summaryrefslogtreecommitdiff
path: root/support/make4ht/domfilters/make4ht-booktabs.lua
diff options
context:
space:
mode:
authorNorbert Preining <norbert@preining.info>2020-01-24 03:00:54 +0000
committerNorbert Preining <norbert@preining.info>2020-01-24 03:00:54 +0000
commite1192611f0655a1ccaff0dff2f53c7c65fa5db07 (patch)
tree232f5be17a2221a57cc6515bfe8692772b3a3e89 /support/make4ht/domfilters/make4ht-booktabs.lua
parentf7e5d81fe9880913485f7f8c541eeca7adf4c195 (diff)
CTAN sync 202001240300
Diffstat (limited to 'support/make4ht/domfilters/make4ht-booktabs.lua')
-rw-r--r--support/make4ht/domfilters/make4ht-booktabs.lua82
1 files changed, 82 insertions, 0 deletions
diff --git a/support/make4ht/domfilters/make4ht-booktabs.lua b/support/make4ht/domfilters/make4ht-booktabs.lua
new file mode 100644
index 0000000000..edec8adbd8
--- /dev/null
+++ b/support/make4ht/domfilters/make4ht-booktabs.lua
@@ -0,0 +1,82 @@
+
+local function find_cmidrules(current_rows)
+ -- save rows with cmidrules here
+ local matched_rows = {}
+ local continue = false
+ for row_no, row in ipairs(current_rows) do
+ local columnposition = 1
+ local matched_cmidrule = false
+
+ for _, col in ipairs(row:query_selector("td")) do
+ -- keep track of culumns
+ local span = tonumber(col:get_attribute("colspan")) or 1
+ local cmidrule = col:query_selector(".cmidrule")
+ -- column contain cmidrule
+ if #cmidrule > 0 then
+ -- remove any child elements, we don't need them anymore
+ col._children = {}
+ -- only one cmidrule can be on each row, save the position, column span and all attributes
+ matched_rows[row_no] = {attributes = col._attr, column = columnposition, span = span, continue = continue}
+ matched_cmidrule = true
+ end
+ columnposition = columnposition + span
+ end
+ if matched_cmidrule then
+ -- save the row number of the first cmidrule on the current row
+ continue = continue or row_no
+ else
+ continue = false
+ end
+
+ end
+ -- save the table rows count, so we can loop over them sequentially later
+ matched_rows.length = #current_rows
+ return matched_rows
+end
+
+local function update_row(current_rows, match, newspan, i)
+ local row_to_update = current_rows[match.continue]
+ -- insert spanning column if necessary
+ if newspan > 0 then
+ local td = row_to_update:create_element("td", {colspan=tostring(newspan), span="nazdar"})
+ row_to_update:add_child_node(td)
+ end
+ -- insert the rule column
+ local td = row_to_update:create_element("td", match.attributes)
+ row_to_update:add_child_node(td)
+ -- remove unnecessary row
+ current_rows[i]:remove_node()
+end
+
+local function join_rows(matched_rows,current_rows)
+ for i = 1, matched_rows.length do
+ local match = matched_rows[i]
+ if match then
+ -- we only need to process rows that place subsequent cmidrules on the same row
+ local continue = match.continue
+ if continue then
+ local prev_row = matched_rows[continue]
+ -- find column where the previous cmidrule ends
+ local prev_end = prev_row.column + prev_row.span
+ local newspan = match.column - prev_end
+ update_row(current_rows, match, newspan, i)
+ -- update the current row position
+ prev_row.column = match.column
+ prev_row.span = match.span
+ end
+ end
+ end
+end
+
+local function process_booktabs(dom)
+ local tables = dom:query_selector("table")
+ for _, tbl in ipairs(tables) do
+ local current_rows = tbl:query_selector("tr")
+ local matched_rows = find_cmidrules(current_rows)
+ join_rows(matched_rows, current_rows)
+ end
+ return dom
+end
+
+return process_booktabs
+