Skip to content

Commit

Permalink
Merge pull request #113 from PgBiel/optimize-map
Browse files Browse the repository at this point in the history
Optimize map parameters
  • Loading branch information
PgBiel authored Jan 7, 2024
2 parents ccc1548 + aedad9a commit d0f2dde
Show file tree
Hide file tree
Showing 3 changed files with 111 additions and 101 deletions.
7 changes: 5 additions & 2 deletions src/grid.typ
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@

// Organize cells in a grid from the given items,
// and also get all given lines
#let generate-grid(items, x-limit: 0, y-limit: 0, map-cells: c => c) = {
#let generate-grid(items, x-limit: 0, y-limit: 0, map-cells: none) = {
// init grid as a matrix
// y-limit x x-limit
let grid = create-grid(x-limit, y-limit)
Expand Down Expand Up @@ -233,7 +233,10 @@

cell.x = this-x
cell.y = this-y
cell = table-item-convert(map-cells(cell))

if type(map-cells) == _function-type {
cell = table-item-convert(map-cells(cell))
}

assert(is-tablex-cell(cell), message: "Tablex error: 'map-cells' returned something that isn't a valid cell.")

Expand Down
195 changes: 101 additions & 94 deletions src/option-parsing.typ
Original file line number Diff line number Diff line change
Expand Up @@ -89,20 +89,13 @@
(col: col-gutter, row: row-gutter)
}

// Accepts a map-X param, and returns its default, or validates
// it.
#let parse-map-func(map-func, uses-second-param: false) = {
if map-func in (none, auto) {
if uses-second-param {
(a, b) => b // identity
} else {
o => o // identity
}
} else if type(map-func) != _function-type {
panic("Map parameters must be functions.")
} else {
map-func
// Accepts a map-X param, and verifies whether it's a function or none/auto.
#let validate-map-func(map-func) = {
if map-func not in (none, auto) and type(map-func) != _function-type {
panic("Tablex error: Map parameters, if specified (not 'none'), must be functions.")
}

map-func
}

#let apply-maps(
Expand All @@ -114,113 +107,127 @@
map-rows: none,
map-cols: none,
) = {
vlines = vlines.map(map-vlines)
if vlines.any(h => not is-tablex-vline(h)) {
panic("'map-vlines' function returned a non-vline.")
if type(map-vlines) == _function-type {
vlines = vlines.map(vline => {
let vline = map-vlines(vline)
if not is-tablex-vline(vline) {
panic("'map-vlines' function returned a non-vline.")
}
vline
})
}

hlines = hlines.map(map-hlines)
if hlines.any(h => not is-tablex-hline(h)) {
panic("'map-hlines' function returned a non-hline.")
if type(map-hlines) == _function-type {
hlines = hlines.map(hline => {
let hline = map-hlines(hline)
if not is-tablex-hline(hline) {
panic("'map-hlines' function returned a non-hline.")
}
hline
})
}

let should-map-rows = type(map-rows) == _function-type
let should-map-cols = type(map-cols) == _function-type

if not should-map-rows and not should-map-cols {
return (grid: grid, hlines: hlines, vlines: vlines)
}

let col-len = grid.width
let row-len = grid-count-rows(grid)

for row in range(row-len) {
let original-cells = grid-get-row(grid, row)
if should-map-rows {
for row in range(row-len) {
let original-cells = grid-get-row(grid, row)

// occupied cells = none for the outer user
let cells = map-rows(row, original-cells.map(c => {
if is-tablex-occupied(c) { none } else { c }
}))
// occupied cells = none for the outer user
let cells = map-rows(row, original-cells.map(c => {
if is-tablex-occupied(c) { none } else { c }
}))

if type(cells) != _array-type {
panic("Tablex error: 'map-rows' returned something that isn't an array.")
}
if type(cells) != _array-type {
panic("Tablex error: 'map-rows' returned something that isn't an array.")
}

// only modify non-occupied cells
let cells = enumerate(cells).filter(i-c => is-tablex-cell(original-cells.at(i-c.at(0))))
if cells.len() != original-cells.len() {
panic("Tablex error: 'map-rows' returned " + str(cells.len()) + " cells, when it should have returned exactly " + str(original-cells.len()) + ".")
}

if cells.any(i-c => not is-tablex-cell(i-c.at(1))) {
panic("Tablex error: 'map-rows' returned a non-cell.")
}

if cells.any(i-c => {
let c = i-c.at(1)
let x = c.x
let y = c.y
type(x) != _int-type or type(y) != _int-type or x < 0 or y < 0 or x >= col-len or y >= row-len
}) {
panic("Tablex error: 'map-rows' returned a cell with invalid coordinates.")
}
for (i, cell) in enumerate(cells) {
let orig-cell = original-cells.at(i)
if not is-tablex-cell(orig-cell) {
// only modify non-occupied cells
continue
}

if cells.any(i-c => i-c.at(1).y != row) {
panic("Tablex error: 'map-rows' returned a cell in a different row (the 'y' must be kept the same).")
}
if not is-tablex-cell(cell) {
panic("Tablex error: 'map-rows' returned a non-cell.")
}

if cells.any(i-c => {
let i = i-c.at(0)
let c = i-c.at(1)
let orig-c = original-cells.at(i)
let x = cell.x
let y = cell.y

c.colspan != orig-c.colspan or c.rowspan != orig-c.rowspan
}) {
panic("Tablex error: Please do not change the colspan or rowspan of a cell in 'map-rows'.")
}
if type(x) != _int-type or type(y) != _int-type or x < 0 or y < 0 or x >= col-len or y >= row-len {
panic("Tablex error: 'map-rows' returned a cell with invalid coordinates.")
}
if y != row {
panic("Tablex error: 'map-rows' returned a cell in a different row (the 'y' must be kept the same).")
}
if cell.colspan != orig-cell.colspan or cell.rowspan != orig-cell.rowspan {
panic("Tablex error: Please do not change the colspan or rowspan of a cell in 'map-rows'.")
}

for i-cell in cells {
let cell = i-cell.at(1)
grid.items.at(grid-index-at(cell.x, cell.y, grid: grid)) = cell
cell.content = [#cell.content]
grid.items.at(grid-index-at(cell.x, cell.y, grid: grid)) = cell
}
}
}

for column in range(col-len) {
let original-cells = grid-get-column(grid, column)
if should-map-cols {
for column in range(col-len) {
let original-cells = grid-get-column(grid, column)

// occupied cells = none for the outer user
let cells = map-cols(column, original-cells.map(c => {
if is-tablex-occupied(c) { none } else { c }
}))
// occupied cells = none for the outer user
let cells = map-cols(column, original-cells.map(c => {
if is-tablex-occupied(c) { none } else { c }
}))

if type(cells) != _array-type {
panic("Tablex error: 'map-cols' returned something that isn't an array.")
}
if type(cells) != _array-type {
panic("Tablex error: 'map-cols' returned something that isn't an array.")
}

// only modify non-occupied cells
let cells = enumerate(cells).filter(i-c => is-tablex-cell(original-cells.at(i-c.at(0))))
if cells.len() != original-cells.len() {
panic("Tablex error: 'map-cols' returned " + str(cells.len()) + " cells, when it should have returned exactly " + str(original-cells.len()) + ".")
}

if cells.any(i-c => not is-tablex-cell(i-c.at(1))) {
panic("Tablex error: 'map-cols' returned a non-cell.")
}

if cells.any(i-c => {
let c = i-c.at(1)
let x = c.x
let y = c.y
type(x) != _int-type or type(y) != _int-type or x < 0 or y < 0 or x >= col-len or y >= row-len
}) {
panic("Tablex error: 'map-cols' returned a cell with invalid coordinates.")
}
for (i, cell) in enumerate(cells) {
let orig-cell = original-cells.at(i)
if not is-tablex-cell(orig-cell) {
// only modify non-occupied cells
continue
}

if cells.any(i-c => i-c.at(1).x != column) {
panic("Tablex error: 'map-cols' returned a cell in a different column (the 'x' must be kept the same).")
}
if not is-tablex-cell(cell) {
panic("Tablex error: 'map-cols' returned a non-cell.")
}

if cells.any(i-c => {
let i = i-c.at(0)
let c = i-c.at(1)
let orig-c = original-cells.at(i)
let x = cell.x
let y = cell.y

c.colspan != orig-c.colspan or c.rowspan != orig-c.rowspan
}) {
panic("Tablex error: Please do not change the colspan or rowspan of a cell in 'map-cols'.")
}
if type(x) != _int-type or type(y) != _int-type or x < 0 or y < 0 or x >= col-len or y >= row-len {
panic("Tablex error: 'map-cols' returned a cell with invalid coordinates.")
}
if x != column {
panic("Tablex error: 'map-cols' returned a cell in a different column (the 'x' must be kept the same).")
}
if cell.colspan != orig-cell.colspan or cell.rowspan != orig-cell.rowspan {
panic("Tablex error: Please do not change the colspan or rowspan of a cell in 'map-cols'.")
}

for i-cell in cells {
let cell = i-cell.at(1)
cell.content = [#cell.content]
grid.items.at(grid-index-at(cell.x, cell.y, grid: grid)) = cell
cell.content = [#cell.content]
grid.items.at(grid-index-at(cell.x, cell.y, grid: grid)) = cell
}
}
}

Expand Down
10 changes: 5 additions & 5 deletions src/tablex.typ
Original file line number Diff line number Diff line change
Expand Up @@ -133,11 +133,11 @@
let header-rows = validate-header-rows(header-rows)
let repeat-header = validate-repeat-header(repeat-header, header-rows: header-rows)
let header-hlines-have-priority = validate-header-hlines-priority(header-hlines-have-priority)
let map-cells = parse-map-func(map-cells)
let map-hlines = parse-map-func(map-hlines)
let map-vlines = parse-map-func(map-vlines)
let map-rows = parse-map-func(map-rows, uses-second-param: true)
let map-cols = parse-map-func(map-cols, uses-second-param: true)
let map-cells = validate-map-func(map-cells)
let map-hlines = validate-map-func(map-hlines)
let map-vlines = validate-map-func(map-vlines)
let map-rows = validate-map-func(map-rows)
let map-cols = validate-map-func(map-cols)
let renderer = validate-renderer(renderer)
let renderer-args = validate-renderer-args(renderer-args, renderer: renderer)

Expand Down

0 comments on commit d0f2dde

Please sign in to comment.