diff --git a/luamml-pdf.sty b/luamml-pdf.sty index d91ef6d..50ba948 100644 --- a/luamml-pdf.sty +++ b/luamml-pdf.sty @@ -51,7 +51,7 @@ % #2 annotation % #3 nodes to be annotated \int_new:N \g__luamml_annotation_id_int -\cs_new_protected:Npn \luamml_pdf_annotate:nnn #1#2#3 { +\cs_new_protected:Npn \luamml_annotate:nen #1#2#3 { \int_gincr:N \g__luamml_annotation_id_int \iow_shipout_x:Nx \l__luamml_pdf_stream { \tl_to_str:e { @@ -71,7 +71,7 @@ % #1 annotation % #2 nodes to be annotated % THIS VERSION IS SIGNIFICANTLY SLOWER -\cs_new_protected:Npn \luamml_pdf_annotate:nn #1#2 { +\cs_new_protected:Npn \luamml_annotate:en #1#2 { \int_gincr:N \g__luamml_annotation_id_int \iow_shipout_x:Nx \l__luamml_pdf_stream { \tl_to_str:e { diff --git a/luamml-tex-annotate.lua b/luamml-tex-annotate.lua new file mode 100644 index 0000000..cb7a8ed --- /dev/null +++ b/luamml-tex-annotate.lua @@ -0,0 +1,100 @@ +local nest = tex.nest + +local properties = node.get_properties_table() + +local mark_environment = {} + +local function annotate() + local annotation, err = load( 'return {' + .. token.scan_argument() + .. '}', nil, 't', mark_environment) + if not annotation then + tex.error('Error while parsing LuaMML annotation', {err}) + return 0 + end + annotation = annotation() + local nesting = nest.top + local props = properties[nesting.head] + local current = props and props.luamml__annotate_context + if current then + current, props.luamml__annotate_context = current.head, current.prev + else + tex.error('Mismatched LuaMML annotation', + {'Something odd happened. Maybe you forgot braces around an annotated symbol in a subscript or superscript?'}) + return 0 + end + local after = nesting.tail + local count, offset = 0, annotation.offset + local marked + if current == after then + tex.error'Empty LuaMML annotation' + else + repeat + current = current.next + count = count + 1 + if count == offset then + marked = current + elseif offset or current ~= after then + local props = properties[current] + if not props then + props = {} + properties[current] = props + end + props.mathml_table, props.mathml_core = nil, false + end + until current == after + if offset and not marked then + tex.error'Invalid offset in LuaMML annotation' + end + marked = marked or current + if annotation.nucleus then + marked = marked.nucleus + end + if marked then + local props = properties[marked] + if not props then + props = {} + properties[marked] = props + end + props.mathml_core = annotation.core + else + tex.error'Unable to annotate nucleus of node without nucleus' + end + end + return count +end + +local funcid = luatexbase.new_luafunction'__luamml_annotate_begin:' +token.set_lua('__luamml_annotate_begin:', funcid, 'protected') +lua.get_functions_table()[funcid] = function() + local top = nest.top + local temp = top.head + local props = properties[temp] + if not props then + props = {} + properties[temp] = props + end + props.luamml__annotate_context = { + prev = props.luamml__annotate_context, + head = top.tail, + } +end + +funcid = luatexbase.new_luafunction'__luamml_annotate_end:we' +token.set_lua('__luamml_annotate_end:we', funcid, 'protected') +lua.get_functions_table()[funcid] = function() + local count = token.scan_int() + local real_count = annotate() + if count ~= real_count then + tex.error('Incorrect count in LuaMML annotation', { + 'A LuaMML annotation was discovered with an explicit count \z + which was not the same as the number of top-level nodes annotated.', + string.format('This can be fixed by changing the supplied count from %i to %i \z + or by omitting the count value entirely.', count, real_count) + }) + end +end + +funcid = luatexbase.new_luafunction'__luamml_annotate_end:e' +token.set_lua('__luamml_annotate_end:e', funcid, 'protected') +lua.get_functions_table()[funcid] = annotate diff --git a/luamml-tex.lua b/luamml-tex.lua index e306879..530c72f 100644 --- a/luamml-tex.lua +++ b/luamml-tex.lua @@ -113,6 +113,8 @@ lua.get_functions_table()[funcid] = function() mlist_result = nil end +require'luamml-tex-annotate' + return { save_result = save_result, } diff --git a/luamml.sty b/luamml.sty index 19edb10..80e6d70 100644 --- a/luamml.sty +++ b/luamml.sty @@ -19,6 +19,20 @@ \tl_set:Nn \l__luamml_filename_tl } + +\cs_new_protected:Npn \luamml_annotate:nen #1#2#3 { + \__luamml_annotate_begin: + #3 + \__luamml_annotate_end:we \tex_numexpr:D #1 \scan_stop: {#2} +} + +\cs_new_protected:Npn \luamml_annotate:en #1#2 { + \__luamml_annotate_begin: + #2 + \__luamml_annotate_end:e {#1} +} + + \cs_new:Npn \__luamml_patch_package:nn #1 #2 { \@ifpackageloaded {#1} {#2} { \hook_gput_code:nnn {package/after/#1} {luamml} {#2} diff --git a/test_pdf.tex b/test_pdf.tex index 5f7d13f..be803a7 100644 --- a/test_pdf.tex +++ b/test_pdf.tex @@ -9,9 +9,9 @@ \cs_set_eq:NN \WriteoutFormula \luamml_pdf_write: \NewDocumentCommand\AnnotateFormula{ o m m }{% \IfValueTF{#1}{% - \luamml_pdf_annotate:nnn{#1}% + \luamml_annotate:nnn{#1}% }{ - \luamml_pdf_annotate:nn + \luamml_annotate:nn }{#2}{#3} } \ExplSyntaxOff