From 5be2282e9b33f465fc249a531f61aa1f34d70f9e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcel=20Fabian=20Kr=C3=BCger?= Date: Thu, 3 Jun 2021 17:28:22 +0200 Subject: [PATCH] Implement pdfTeX auto node counting --- luamml-pdf.sty | 26 +++++++++++++++----------- pdfmml-logreader.lua | 13 ++++++++++++- pdfmml-showlists.lua | 32 ++++++++++++++++---------------- pdfmml.lua | 2 +- test_pdf.tex | 2 +- 5 files changed, 45 insertions(+), 30 deletions(-) diff --git a/luamml-pdf.sty b/luamml-pdf.sty index 0e2419d..67bcd15 100644 --- a/luamml-pdf.sty +++ b/luamml-pdf.sty @@ -58,21 +58,25 @@ % THIS VERSION IS SIGNIFICANTLY SLOWER \cs_new_protected:Npn \luamml_pdf_annotate:nn #1#2 { \int_gincr:N \g__luamml_annotation_id_int - \iow_write:Nx \c_log_iow { - LUAMML_COUNT_BEGIN: + \iow_shipout_x:Nx \c_log_iow { + \tl_to_str:e { + LUAMML_MARK: + \int_use:N \g__luamml_annotation_id_int + : + count = data.count[\int_use:N \g__luamml_annotation_id_int], + #1 + } + \exp_not:N \iow_newline: + LUAMML_MARK_END + } + \iow_now:Nx \c_log_iow { + LUAMML_COUNT: \int_use:N \g__luamml_annotation_id_int } \__luamml_pdf_showlists: - \iow_shipout:Nx \c_log_iow { - LUAMML_MARK: - \int_use:N \g__luamml_annotation_id_int - : - #1 - } #2 - \iow_write:Nx \c_log_iow { - LUAMML_COUNT_END: - \int_use:N \g__luamml_annotation_id_int + \iow_now:Nn \c_log_iow { + LUAMML_COUNT_END } \__luamml_pdf_showlists: } diff --git a/pdfmml-logreader.lua b/pdfmml-logreader.lua index 377f92d..4fb7c75 100644 --- a/pdfmml-logreader.lua +++ b/pdfmml-logreader.lua @@ -14,6 +14,16 @@ local luamml_block = l.Cg('LUAMML_FORMULA_BEGIN:' * id * l.P'\n'^1 * l.Ct( local luamml_mark = l.Cg('LUAMML_MARK:' * id * ':' * l.Cs((1 - l.P'\n' + l.Cg('\n' * l.Cc'' - '\nLUAMML_MARK_END\n'))^0) * '\nLUAMML_MARK_END\n' * l.Cc'marks') +local function add(a, b) return a + b end +local count_block = '### ' * line * l.Cf(l.Cc(0) * (('\\' * l.Cc(1))^-1 * line - '### ')^0, add) +local luamml_count = l.Cg('LUAMML_COUNT:' * id * l.P'\n'^1 + * count_block + * (line-'LUAMML_COUNT_END\n')^0 + * 'LUAMML_COUNT_END' * l.P'\n'^1 + * count_block / function(id, first, second) + return id, second - first + end * l.Cc'count') + local luamml_instruction = l.Cg('LUAMML_INSTRUCTION:' * l.Cc(nil) * l.C((1 - l.P'\n')^0) * '\n' * l.Cc'instructions') local function multi_table_set(t, key, value, table) @@ -22,9 +32,10 @@ local function multi_table_set(t, key, value, table) return t end local log_file = l.Cf(l.Ct(l.Cg(l.Ct'', 'groups') + * l.Cg(l.Ct'', 'count') * l.Cg(l.Ct'', 'marks') * l.Cg(l.Ct'', 'instructions')) - * (luamml_block + luamml_mark + luamml_instruction + line)^0, + * (luamml_block + luamml_mark + luamml_instruction + luamml_count + line)^0, multi_table_set) return function(filename) diff --git a/pdfmml-showlists.lua b/pdfmml-showlists.lua index af7f191..b271955 100644 --- a/pdfmml-showlists.lua +++ b/pdfmml-showlists.lua @@ -64,22 +64,22 @@ local fraction_noad = l.Ct('\\fraction, thickness ' local mathchoice_noad = l.Ct('\\mathchoice' * l.Cg(l.Cc'choice', 'id') * -1) -local mark_whatsit = '\\write-{LUAMML_MARK:' * (l.R'09'/tonumber) * ':' +local mark_whatsit = '\\write-{LUAMML_MARK:' * (l.R'09'^1/tonumber) * ':' local parse_list -local function parse_kernel(lines, i, prefix) +local function parse_kernel(lines, i, prefix, parsed) local line = lines[i] if not line or line:sub(1, #prefix) ~= prefix then return nil, i end local result = math_char:match(lines[i], #prefix + 1) if result then return result, i+1 end - result, i = parse_list(lines, i, prefix) + result, i = parse_list(lines, i, prefix, parsed) return {list = result, id = 'sub_mlist'}, i end -function parse_list(lines, i, prefix, marks) +function parse_list(lines, i, prefix, parsed) i = i or 1 prefix = prefix or '' local head, last - local mark_environment = {} + local mark_environment = {data = parsed,} local current_mark, current_count, current_offset while true do local skip @@ -87,9 +87,9 @@ function parse_list(lines, i, prefix, marks) if not line or line:sub(1, #prefix) ~= prefix then break end local simple = simple_noad:match(line, #prefix+1) if simple then - simple.nucleus, i = parse_kernel(lines, i + 1, prefix .. '.') - simple.sup, i = parse_kernel(lines, i, prefix .. '^') - simple.sub, i = parse_kernel(lines, i, prefix .. '_') + simple.nucleus, i = parse_kernel(lines, i + 1, prefix .. '.', parsed) + simple.sup, i = parse_kernel(lines, i, prefix .. '^', parsed) + simple.sub, i = parse_kernel(lines, i, prefix .. '_', parsed) if last then simple.prev, last.next = last, simple end @@ -97,8 +97,8 @@ function parse_list(lines, i, prefix, marks) else local fraction = fraction_noad:match(line, #prefix+1) if fraction then - fraction.num, i = parse_kernel(lines, i + 1, prefix .. '\\') - fraction.denom, i = parse_kernel(lines, i, prefix .. '/') + fraction.num, i = parse_kernel(lines, i + 1, prefix .. '\\', parsed) + fraction.denom, i = parse_kernel(lines, i, prefix .. '/', parsed) if last then fraction.prev, last.next = last, fraction end @@ -106,19 +106,19 @@ function parse_list(lines, i, prefix, marks) else local mathchoice = mathchoice_noad:match(line, #prefix+1) if mathchoice then - mathchoice.display, i = parse_list(lines, i + 1, prefix .. 'D') - mathchoice.text, i = parse_list(lines, i, prefix .. 'T') - mathchoice.script, i = parse_list(lines, i, prefix .. 'S') - mathchoice.scriptscript, i = parse_list(lines, i, prefix .. 's') + mathchoice.display, i = parse_list(lines, i + 1, prefix .. 'D', parsed) + mathchoice.text, i = parse_list(lines, i, prefix .. 'T', parsed) + mathchoice.script, i = parse_list(lines, i, prefix .. 'S', parsed) + mathchoice.scriptscript, i = parse_list(lines, i, prefix .. 's', parsed) if last then mathchoice.prev, last.next = last, mathchoice end last = mathchoice else skip = true - local mark = mark_whatsit:match(line) + local mark = mark_whatsit:match(line, #prefix+1) if mark then - local mark_table = assert(load('return {' .. assert(marks[mark], 'Undefined mark encountered') .. '}', nil, 't', mark_environment))() + local mark_table = assert(load('return {' .. assert(parsed.marks[mark], 'Undefined mark encountered') .. '}', nil, 't', mark_environment))() current_mark, current_count = mark_table, mark_table.count or 1 current_offset = mark_table.offset or current_count i = i + 1 diff --git a/pdfmml.lua b/pdfmml.lua index 2b45dcb..08d5d0b 100755 --- a/pdfmml.lua +++ b/pdfmml.lua @@ -55,7 +55,7 @@ end for i, block in ipairs(parsed.groups) do local stream = out_stream or assert(io.open(out_prefix .. tostring(i) .. out_suffix, 'w')) block = block[1] - local parsed = parse_showlists(block, nil, nil, parsed.marks) + local parsed = parse_showlists(block, nil, nil, parsed) local style = block.display and 0 or 2 stream:write( to_xml(convert.make_root(convert.process(parsed, style), style)), '\n' diff --git a/test_pdf.tex b/test_pdf.tex index 9b459f7..5f7d13f 100644 --- a/test_pdf.tex +++ b/test_pdf.tex @@ -16,7 +16,7 @@ } \ExplSyntaxOff -\protected\edef\models{\AnnotateFormula[3]{% +\protected\edef\models{\AnnotateFormula{% nucleus = true, core = {[0] = 'mi', '\noexpand\string\noexpand\u{22a7}'}, }{\unexpanded\expandafter{\models}}}