Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions R/typst_style.R
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,14 @@ typst_hlines <- function(x, lin) {
tmp <- split(lin, list(lin$i, lin$line, lin$line_color_mapped, lin$line_width))
tmp <- Filter(function(x) nrow(x) > 0, tmp)
tmp <- lapply(tmp, function(k) {
# Drop duplicate cell-level entries. These arise routinely whenever
# theme_tinytable() and a user style_tt() declare the same line (same
# i, j, line, color, width, trim). Without deduplication,
# typst_split_chunks() sees phantom breaks in diff(x) != 1 and emits a
# chain of fragmented table.hline()/table.vline() segments that cover
# the same span as a single line. See test-typst-line-dedup.R.
k <- k[!duplicated(k), , drop = FALSE]

# Split chunks based on consecutive columns AND line_trim boundaries
# line_trim marks group boundaries - split chunks at these points
chunks <- typst_split_chunks(k$j)
Expand Down Expand Up @@ -462,6 +470,8 @@ typst_vlines <- function(x, lin) {
lin <- split(lin, list(lin$j, lin$line, lin$line_color_mapped, lin$line_width))
lin <- Filter(function(x) nrow(x) > 0, lin)
lin <- lapply(lin, function(k) {
# Drop duplicate cell-level entries; see typst_hlines() for rationale.
k <- k[!duplicated(k), , drop = FALSE]
ymin <- typst_split_chunks(k$i)$min
ymax <- typst_split_chunks(k$i)$max
xmin <- k$j[1]
Expand Down
8 changes: 2 additions & 6 deletions inst/tinytest/_tinysnapshot/typst-issue592.typ
Original file line number Diff line number Diff line change
Expand Up @@ -78,11 +78,7 @@ block[ // start block
table.hline(y: 14, start: 1, end: 2, stroke: 0.1em + black), table.hline(y: 14, start: 3, end: 7, stroke: 0.1em + black),
table.hline(y: 15, start: 1, end: 2, stroke: 0.1em + black), table.hline(y: 15, start: 3, end: 7, stroke: 0.1em + black),
table.hline(y: 16, start: 2, end: 3, stroke: 0.1em + black),
table.vline(x: 0, start: 0, end: 1, stroke: 0.1em + black),
table.vline(x: 0, start: 0, end: 2, stroke: 0.1em + black),
table.vline(x: 0, start: 1, end: 7, stroke: 0.1em + black),
table.vline(x: 0, start: 6, end: 12, stroke: 0.1em + black),
table.vline(x: 0, start: 11, end: 16, stroke: 0.1em + black),
table.vline(x: 0, start: 0, end: 16, stroke: 0.1em + black),
table.vline(x: 1, start: 0, end: 16, stroke: 0.1em + black),
table.vline(x: 2, start: 0, end: 1, stroke: 0.1em + black),
table.vline(x: 3, start: 0, end: 1, stroke: 0.1em + black),
Expand Down Expand Up @@ -129,4 +125,4 @@ table.cell(rowspan: 3)[3], [x], [80.9%], [78.4%], [ ], [55.6%],
// tinytable align-figure after

] // end block
) // end figure
) // end figure
33 changes: 33 additions & 0 deletions inst/tinytest/test-bugfix.R
Original file line number Diff line number Diff line change
Expand Up @@ -58,3 +58,36 @@ local({
expect_true(grepl("1,23", typst, fixed = TRUE))
expect_true(grepl("1,23", tabulator, fixed = TRUE))
})


# Regression test: typst_hlines/typst_vlines used to emit fragmented chains of
# table.hline()/table.vline() segments covering the same span whenever
# theme_tinytable() and the user declared the same line (or any line was
# declared twice with identical properties). This produced redundant, ugly
# output and slowed down rendering. The fix deduplicates cell-level entries
# inside the typst line processors.

# Case 1: user re-declares the theme's middle "below colnames" line.
# Before the fix this produced 6 fragmented hline segments at y=1.
tab <- tt(mtcars[1:5, 1:5]) |>
style_tt(i = 0, line = "b", line_color = "black", line_width = 0.05)
out <- save_tt(tab, "typst")
hlines <- strsplit(out, "\n", fixed = TRUE)[[1]]
hlines <- hlines[grepl("table.hline", hlines, fixed = TRUE)]
middle <- hlines[grepl("y: 1,", hlines, fixed = TRUE)]
expect_true(length(middle) >= 1)
# The whole row should contain exactly one table.hline(y: 1, ...) segment
n_middle_segments <- lengths(regmatches(middle, gregexpr("table[.]hline", middle)))
expect_true(n_middle_segments == 1)

# Case 2: user adds the same line twice -> should still produce a single segment
tab <- tt(mtcars[1:5, 1:5]) |>
style_tt(i = 2, line = "b", line_color = "pink") |>
style_tt(i = 2, line = "b", line_color = "pink")
out <- save_tt(tab, "typst")
hlines <- strsplit(out, "\n", fixed = TRUE)[[1]]
hlines <- hlines[grepl("table.hline", hlines, fixed = TRUE)]
dup <- hlines[grepl("y: 3,", hlines, fixed = TRUE)]
expect_true(length(dup) >= 1)
n_dup_segments <- lengths(regmatches(dup, gregexpr("table[.]hline", dup)))
expect_true(n_dup_segments == 1)
Loading