mirror of
https://github.com/zaphar/sheetsui.git
synced 2025-07-22 04:39: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]]
|
[[package]]
|
||||||
name = "html"
|
name = "htmf"
|
||||||
version = "0.6.3"
|
version = "0.2.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "944d7db81871c611549302f3014418fedbcfbc46902f97e6a1c4f53e785903d2"
|
checksum = "abcb5a4078c86d49875d3079c1b31c3bd5c277ad6adb88800a4d5c6af0fec9b2"
|
||||||
dependencies = [
|
|
||||||
"html-sys",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "html-sys"
|
|
||||||
version = "0.4.3"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "13eca55667a5657dd1b86db77c5fe2d1810e3f9413e9555a2c4c461733dd2573"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "iana-time-zone"
|
name = "iana-time-zone"
|
||||||
@ -1029,7 +1020,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
checksum = "4979f22fdb869068da03c9f7528f8297c6fd2606bc3a4affe42e6a823fdb8da4"
|
checksum = "4979f22fdb869068da03c9f7528f8297c6fd2606bc3a4affe42e6a823fdb8da4"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg-if",
|
"cfg-if",
|
||||||
"windows-targets 0.48.5",
|
"windows-targets 0.52.6",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -1780,7 +1771,7 @@ dependencies = [
|
|||||||
"crossterm",
|
"crossterm",
|
||||||
"csv",
|
"csv",
|
||||||
"futures",
|
"futures",
|
||||||
"html",
|
"htmf",
|
||||||
"ironcalc",
|
"ironcalc",
|
||||||
"pulldown-cmark 0.13.0",
|
"pulldown-cmark 0.13.0",
|
||||||
"ratatui",
|
"ratatui",
|
||||||
|
@ -22,5 +22,5 @@ colorsys = "0.6.7"
|
|||||||
tui-markdown = { version = "0.3.1", features = [] }
|
tui-markdown = { version = "0.3.1", features = [] }
|
||||||
csv = "1.3.1"
|
csv = "1.3.1"
|
||||||
pulldown-cmark = "0.13.0"
|
pulldown-cmark = "0.13.0"
|
||||||
html = "0.6.3"
|
|
||||||
arboard = { version = "3.5.0", features = ["wayland-data-control"] }
|
arboard = { version = "3.5.0", features = ["wayland-data-control"] }
|
||||||
|
htmf = "0.2.0"
|
||||||
|
@ -132,27 +132,19 @@ impl Book {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Construct a payload of (html, csv_text) for the address range.
|
/// Construct a payload of (html, csv_text) for a sheet.
|
||||||
pub fn range_to_clipboard_content(&self, range: AddressRange) -> Result<(String, String), anyhow::Error> {
|
pub fn sheeet_to_clipboard_content(&self, sheet: u32) -> Result<(String, String), anyhow::Error> {
|
||||||
use html::tables;
|
let rows = self.get_export_rows_for_sheet(sheet)?;
|
||||||
let rows = self.get_rows_for_range(&range).unwrap_or_default();
|
rows_to_clipboard_content(rows)
|
||||||
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 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>>> {
|
pub fn get_export_rows(&self) -> Result<Vec<Vec<String>>> {
|
||||||
let sheet = self.location.sheet;
|
let sheet = self.location.sheet;
|
||||||
Ok(self.get_export_rows_for_sheet(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 {
|
fn calculate_area(sheet: u32, start: &Address, end: &Address) -> Area {
|
||||||
let area = Area {
|
let area = Area {
|
||||||
sheet,
|
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