mirror of
https://github.com/zaphar/sheetsui.git
synced 2025-07-21 12:29:48 -04:00
wip: convert a sheet into clipboard format
This commit is contained in:
parent
6a044f174a
commit
fbbdcb983f
19
Cargo.lock
generated
19
Cargo.lock
generated
@ -844,19 +844,10 @@ dependencies = [
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "html"
|
||||
version = "0.6.3"
|
||||
name = "htmf"
|
||||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "944d7db81871c611549302f3014418fedbcfbc46902f97e6a1c4f53e785903d2"
|
||||
dependencies = [
|
||||
"html-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "html-sys"
|
||||
version = "0.4.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "13eca55667a5657dd1b86db77c5fe2d1810e3f9413e9555a2c4c461733dd2573"
|
||||
checksum = "abcb5a4078c86d49875d3079c1b31c3bd5c277ad6adb88800a4d5c6af0fec9b2"
|
||||
|
||||
[[package]]
|
||||
name = "iana-time-zone"
|
||||
@ -1029,7 +1020,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4979f22fdb869068da03c9f7528f8297c6fd2606bc3a4affe42e6a823fdb8da4"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"windows-targets 0.48.5",
|
||||
"windows-targets 0.52.6",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -1780,7 +1771,7 @@ dependencies = [
|
||||
"crossterm",
|
||||
"csv",
|
||||
"futures",
|
||||
"html",
|
||||
"htmf",
|
||||
"ironcalc",
|
||||
"pulldown-cmark 0.13.0",
|
||||
"ratatui",
|
||||
|
@ -22,5 +22,5 @@ colorsys = "0.6.7"
|
||||
tui-markdown = { version = "0.3.1", features = [] }
|
||||
csv = "1.3.1"
|
||||
pulldown-cmark = "0.13.0"
|
||||
html = "0.6.3"
|
||||
arboard = { version = "3.5.0", features = ["wayland-data-control"] }
|
||||
htmf = "0.2.0"
|
||||
|
@ -132,27 +132,19 @@ impl Book {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Construct a payload of (html, csv_text) for the address range.
|
||||
pub fn range_to_clipboard_content(&self, range: AddressRange) -> Result<(String, String), anyhow::Error> {
|
||||
use html::tables;
|
||||
let rows = self.get_rows_for_range(&range).unwrap_or_default();
|
||||
let mut html = tables::Table::builder();
|
||||
let mut writer = csv::Writer::from_writer(vec![]);
|
||||
for row in rows {
|
||||
let mut html_row = tables::TableRow::builder();
|
||||
writer.write_record(&row)?;
|
||||
for cell in row {
|
||||
let mut html_cell = tables::TableCell::builder();
|
||||
html_cell.text(cell);
|
||||
html_row.push(html_cell.build());
|
||||
}
|
||||
html.push(html_row.build());
|
||||
}
|
||||
|
||||
let csv_content = writer.into_inner().expect("Failed to get the csv content");
|
||||
Ok((html.build().to_string(), String::from_utf8_lossy(&csv_content).to_string()))
|
||||
/// Construct a payload of (html, csv_text) for a sheet.
|
||||
pub fn sheeet_to_clipboard_content(&self, sheet: u32) -> Result<(String, String), anyhow::Error> {
|
||||
let rows = self.get_export_rows_for_sheet(sheet)?;
|
||||
rows_to_clipboard_content(rows)
|
||||
}
|
||||
|
||||
/// Construct a payload of (html, csv_text) for the address range.
|
||||
pub fn range_to_clipboard_content(&self, range: AddressRange) -> Result<(String, String), anyhow::Error> {
|
||||
let rows = self.get_rows_for_range(&range).unwrap_or_default();
|
||||
rows_to_clipboard_content(rows)
|
||||
}
|
||||
|
||||
/// Get rows for current sheet to export.
|
||||
pub fn get_export_rows(&self) -> Result<Vec<Vec<String>>> {
|
||||
let sheet = self.location.sheet;
|
||||
Ok(self.get_export_rows_for_sheet(sheet)?)
|
||||
@ -730,6 +722,25 @@ impl Book {
|
||||
}
|
||||
}
|
||||
|
||||
fn rows_to_clipboard_content(rows: Vec<Vec<String>>) -> std::result::Result<(String, String), anyhow::Error> {
|
||||
use htmf::prelude::*;
|
||||
let table = table([]);
|
||||
let mut writer = csv::Writer::from_writer(vec![]);
|
||||
let mut table_rows = vec![];
|
||||
for row in rows {
|
||||
let table_row = tr([]);
|
||||
writer.write_record(&row)?;
|
||||
let mut row_cells = vec![];
|
||||
for cell in row {
|
||||
row_cells.push(td([]).with(text(cell)));
|
||||
}
|
||||
table_rows.push(table_row.with(row_cells));
|
||||
}
|
||||
|
||||
let csv_content = writer.into_inner().expect("Failed to get the csv content");
|
||||
Ok((table.with(table_rows).to_html(), String::from_utf8_lossy(&csv_content).to_string()))
|
||||
}
|
||||
|
||||
fn calculate_area(sheet: u32, start: &Address, end: &Address) -> Area {
|
||||
let area = Area {
|
||||
sheet,
|
||||
|
116
src/book/test.rs
116
src/book/test.rs
@ -200,3 +200,119 @@ fn test_book_get_exportable_rows() {
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_sheet_to_clipboard_content() {
|
||||
let mut book = Book::default();
|
||||
book.update_cell(
|
||||
&Address {
|
||||
sheet: 0,
|
||||
row: 1,
|
||||
col: 1,
|
||||
},
|
||||
"A1",
|
||||
)
|
||||
.expect("failed to edit cell");
|
||||
book.update_cell(
|
||||
&Address {
|
||||
sheet: 0,
|
||||
row: 1,
|
||||
col: 2,
|
||||
},
|
||||
"B1",
|
||||
)
|
||||
.expect("failed to edit cell");
|
||||
book.update_cell(
|
||||
&Address {
|
||||
sheet: 0,
|
||||
row: 2,
|
||||
col: 1,
|
||||
},
|
||||
"A2",
|
||||
)
|
||||
.expect("failed to edit cell");
|
||||
book.update_cell(
|
||||
&Address {
|
||||
sheet: 0,
|
||||
row: 2,
|
||||
col: 2,
|
||||
},
|
||||
"B2",
|
||||
)
|
||||
.expect("failed to edit cell");
|
||||
|
||||
let (html, csv) = dbg!(book.sheeet_to_clipboard_content(0).expect("Failed to get clipboard content"));
|
||||
|
||||
// Check that HTML contains table elements and our data
|
||||
assert!(html.contains("<table>"));
|
||||
assert!(html.contains("<tr>"));
|
||||
assert!(html.contains("<td>"));
|
||||
assert!(html.contains("A1"));
|
||||
assert!(html.contains("B1"));
|
||||
assert!(html.contains("A2"));
|
||||
assert!(html.contains("B2"));
|
||||
|
||||
// Check CSV content
|
||||
let expected_csv = ",,\n,A1,B1\n,A2,B2\n";
|
||||
assert_eq!(csv, expected_csv);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_range_to_clipboard_content() {
|
||||
let mut book = Book::default();
|
||||
book.update_cell(
|
||||
&Address {
|
||||
sheet: 0,
|
||||
row: 1,
|
||||
col: 1,
|
||||
},
|
||||
"A1",
|
||||
)
|
||||
.expect("failed to edit cell");
|
||||
book.update_cell(
|
||||
&Address {
|
||||
sheet: 0,
|
||||
row: 1,
|
||||
col: 2,
|
||||
},
|
||||
"B1",
|
||||
)
|
||||
.expect("failed to edit cell");
|
||||
book.update_cell(
|
||||
&Address {
|
||||
sheet: 0,
|
||||
row: 2,
|
||||
col: 1,
|
||||
},
|
||||
"A2",
|
||||
)
|
||||
.expect("failed to edit cell");
|
||||
book.update_cell(
|
||||
&Address {
|
||||
sheet: 0,
|
||||
row: 2,
|
||||
col: 2,
|
||||
},
|
||||
"B2",
|
||||
)
|
||||
.expect("failed to edit cell");
|
||||
|
||||
let start = Address { sheet: 0, row: 1, col: 1 };
|
||||
let end = Address { sheet: 0, row: 2, col: 2 };
|
||||
let range = super::AddressRange { start: &start, end: &end };
|
||||
|
||||
let (html, csv) = book.range_to_clipboard_content(range).expect("Failed to get clipboard content");
|
||||
|
||||
// Check that HTML contains table elements and our data
|
||||
assert!(html.contains("<table>"));
|
||||
assert!(html.contains("<tr>"));
|
||||
assert!(html.contains("<td>"));
|
||||
assert!(html.contains("A1"));
|
||||
assert!(html.contains("B1"));
|
||||
assert!(html.contains("A2"));
|
||||
assert!(html.contains("B2"));
|
||||
|
||||
// Check CSV content
|
||||
let expected_csv = "A1,B1\nA2,B2\n";
|
||||
assert_eq!(csv, expected_csv);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user