diff options
| author | Ralph Amissah <ralph.amissah@gmail.com> | 2026-09-30 14:32:03 -0400 |
|---|---|---|
| committer | Ralph Amissah <ralph.amissah@gmail.com> | 2026-09-30 22:31:56 -0400 |
| commit | 36d0935c9a7521a87929d676a6b657fb033c44eb (patch) | |
| tree | acb1e27aa0a95691419e2b05f5623fbd4f1aac61 /src/sisudoc | |
| parent | unused function removed (diff) | |
notes: editor's notes, ~[* ]~ & ~[+ ]~, as series
The markup documents ~[* note ]~ and ~[+ note ]~ as editor's notes, each
a separately numbered series, and a bare ~[ note ]~ which sisu put in
the asterisk series. They are included as notes. Each series is numbered
through the document, *1, *2 ... and +1, +2 ..., apart from the author's
notes.
(assisted by Claude-Code)
Diffstat (limited to 'src/sisudoc')
| -rw-r--r-- | src/sisudoc/ocda/meta/metadoc_from_src_functions.d | 39 | ||||
| -rw-r--r-- | src/sisudoc/ocda/meta/rgx.d | 11 | ||||
| -rw-r--r-- | src/sisudoc/outputs/io_out/latex.d | 14 | ||||
| -rw-r--r-- | src/sisudoc/outputs/io_out/odt.d | 21 | ||||
| -rw-r--r-- | src/sisudoc/outputs/io_out/rgx.d | 10 | ||||
| -rw-r--r-- | src/sisudoc/outputs/io_out/text.d | 5 |
6 files changed, 84 insertions, 16 deletions
diff --git a/src/sisudoc/ocda/meta/metadoc_from_src_functions.d b/src/sisudoc/ocda/meta/metadoc_from_src_functions.d index c5a63cd..922f389 100644 --- a/src/sisudoc/ocda/meta/metadoc_from_src_functions.d +++ b/src/sisudoc/ocda/meta/metadoc_from_src_functions.d @@ -2340,7 +2340,7 @@ template docAbstractionFunctions() { // ↓ - object inline munge static struct ObjInlineMarkupMunge { string[string] obj_txt; - int n_foot, n_foot_reg, n_foot_sp_asterisk, n_foot_sp_plus; + int n_foot, n_foot_reg, n_foot_sp_asterisk, n_foot_sp_plus, n_foot_ed_asterisk, n_foot_ed_plus; string asterisks_, plus_; string obj_txt_out, tail, note; static auto rgx = RgxI(); @@ -2351,6 +2351,8 @@ template docAbstractionFunctions() { n_foot_reg = 0; n_foot_sp_asterisk = 0; n_foot_sp_plus = 0; + n_foot_ed_asterisk = 0; + n_foot_ed_plus = 0; } static auto images()(string obj_txt_in) { static auto mng = InlineMarkup(); @@ -2381,13 +2383,13 @@ template docAbstractionFunctions() { bool flg_notes_reg = false; bool flg_notes_star = false; bool flg_notes_plus = false; + if (!(stage_reset_note_numbers) && reset_note_numbers) { + stage_reset_note_numbers = true; + } obj_txt_in = obj_txt_in.replaceAll( rgx.inline_notes_curly, (mkup.en_a_o ~ " $1" ~ mkup.en_a_c) ); - if (!(stage_reset_note_numbers) && reset_note_numbers) { - stage_reset_note_numbers = true; - } obj_txt_out = ""; if (obj_txt_in.match(rgx.inline_notes_al_gen)) { string[] _tmp_txt; @@ -2398,6 +2400,8 @@ template docAbstractionFunctions() { n_foot_reg = 0; n_foot_sp_asterisk = 0; n_foot_sp_plus = 0; + n_foot_ed_asterisk = 0; + n_foot_ed_plus = 0; } stage_reset_note_numbers = false; foreach(n; m) { @@ -2439,6 +2443,33 @@ template docAbstractionFunctions() { } else { obj_txt_out = obj_txt_in; } + /+ ↓ editor's notes: ~[* note ]~ and ~[+ note ]~, and a bare ~[ note ]~, + which joins the asterisk series as it did in sisu. Each series is + numbered through the document, apart from the author's notes: + *1, *2 ... and +1, +2 ... + . + Placed after the author's notes rather than before, so that the reset + above, made once per document at its first note, has happened by the + time these are counted. + +/ + if (obj_txt_out.match(rgx.inline_notes_square)) { + if (stage_reset_note_numbers) { + n_foot = 0; + n_foot_reg = 0; + n_foot_sp_asterisk = 0; + n_foot_sp_plus = 0; + n_foot_ed_asterisk = 0; + n_foot_ed_plus = 0; + stage_reset_note_numbers = false; + } + obj_txt_out = replaceAll!((m) { + string _series = (m["series"] == "+") ? "+" : "*"; + int _n = (_series == "+") ? ++n_foot_ed_plus : ++n_foot_ed_asterisk; + if (_series == "+") { flg_notes_plus = true; } + return mkup.en_a_o ~ _series ~ _n.to!string ~ " " ~ m["note"] ~ mkup.en_a_c; + })(obj_txt_out, rgx.inline_notes_square); + flg_notes_star = true; + } ST_txtPlusHasFootnotes ret; { ret.obj_txt = obj_txt_out; diff --git a/src/sisudoc/ocda/meta/rgx.d b/src/sisudoc/ocda/meta/rgx.d index 249fd3d..22828d7 100644 --- a/src/sisudoc/ocda/meta/rgx.d +++ b/src/sisudoc/ocda/meta/rgx.d @@ -151,6 +151,7 @@ static template spineRgxIn() { static inline_notes_curly = ctRegex!(`~\{\s*(.+?)\s*\}~`, "mg"); static inline_notes_curly_sp_asterisk = ctRegex!(`~\{[*]+\s+(.+?)\s*\}~`, "m"); static inline_notes_curly_sp_plus = ctRegex!(`~\{[+]+\s+(.+?)\s*\}~`, "m"); + static inline_notes_square = ctRegex!(`~\[\s*(?P<series>[*+]?)\s*(?P<note>.+?)\s*\]~`, "mg"); // editor's notes, their own numbered series static note_ref = ctRegex!(`^\S+?noteref_(?P<ref>[0-9]+)`, "mg"); // {^{73.}^}#noteref_73 static smid_inline_url_generic = ctRegex!(`(?:^|[}(\[ ])(?:(?:https?|git):\/\/|¤?\.\.\/|¤?\.\/|¤|#)[a-zA-Z0-9_#]`, "mg"); static smid_inline_url = ctRegex!(`((?:(?:https?|git):\/\/|¤?\.\.\/|¤?\.\/|¤|#)[a-zA-Z0-9_]\S*)`, "mg"); @@ -236,17 +237,17 @@ static template spineRgxIn() { +/ static trailing_backslash = ctRegex!(`\s*\\`, "mg"); /+ inline markup footnotes endnotes +/ - static inline_notes_al = ctRegex!(`【(?:[*+]\s+|\s*)(.+?)】`, "mg"); - static inline_notes_al_special = ctRegex!(`【(?:[*+]\s+)(.+?)】`, "mg"); // TODO remove match when special footnotes are implemented + static inline_notes_al = ctRegex!(`【(?:[*+]+[0-9]*\s+|\s*)(.+?)】`, "mg"); + static inline_notes_al_special = ctRegex!(`【(?:[*+]+[0-9]*\s+)(.+?)】`, "mg"); // TODO remove match when special footnotes are implemented static inline_notes_al_gen = ctRegex!(`【.+?】`, "m"); static inline_notes_al_gen_text = ctRegex!(`【(?P<text>.+?)】`, "m"); - static inline_notes_al_all_note = ctRegex!(`【(?P<num>\d+|(?:[*]|[+])+)\s+(?P<note>.+?)\s*】`, "mg"); + static inline_notes_al_all_note = ctRegex!(`【(?P<num>\d+|[*+]+[0-9]*)\s+(?P<note>.+?)\s*】`, "mg"); static inline_notes_al_regular_number_note = ctRegex!(`【(?P<num>\d+)\s+(?P<note>.+?)\s*】`, "mg"); - static inline_notes_al_special_char_note = ctRegex!(`【(?P<char>(?:[*]|[+])+)\s+(?P<note>.+?)】`, "mg"); + static inline_notes_al_special_char_note = ctRegex!(`【(?P<char>[*+]+[0-9]*)\s+(?P<note>.+?)】`, "mg"); static inline_al_delimiter_open_regular = ctRegex!(`【\s`, "m"); static inline_al_delimiter_open_symbol_star = ctRegex!(`【[*]\s`, "m"); static inline_al_delimiter_open_symbol_plus = ctRegex!(`【[+]\s`, "m"); - static inline_text_and_note_al_ = ctRegex!(`(.+?(?:【[*+]*\s+.+?】|.+))`, "mg"); + static inline_text_and_note_al_ = ctRegex!(`(.+?(?:【[*+]*[0-9]*\s+.+?】|.+))`, "mg"); static endnote_section_note = ctRegex!(`┥\s*⑆\^┨(?P<notenumber>\d+)\.┣\^┝┤(?P<link>¤?.+?)├.+`, "mg"); /+ inline markup links +/ static inline_image = ctRegex!(`(?P<pre>┥)☼(?P<imginf>(?P<img>[a-zA-Z0-9._-]+?\.(?:jpg|gif|png)),w(?P<width>\d+)h(?P<height>\d+))\s*(?P<post>.*?┝┤.*?├)`, "mg"); diff --git a/src/sisudoc/outputs/io_out/latex.d b/src/sisudoc/outputs/io_out/latex.d index 8e7b37c..1562fae 100644 --- a/src/sisudoc/outputs/io_out/latex.d +++ b/src/sisudoc/outputs/io_out/latex.d @@ -494,6 +494,20 @@ template outputLaTeX() { "$2".strip ).strip ); + /+ ↓ a note of a special series (*, *1, +1 ...). \footnote[n] takes a + number, so the mark is set as \thefootnote for this one note, + and the counter put back, so that the numbered series does not + move. + +/ + _txt = replaceAll!((m) { + import std.array : replace; + string _mark = m["char"]; + string _name = _mark.replace("*", "a").replace("+", "p"); + return "\\hypertarget{noteref_" ~ _name ~ "}{}" + ~ "{\\renewcommand{\\thefootnote}{" ~ _mark ~ "}" + ~ "\\footnote{\\label{note_" ~ _name ~ "}" ~ m["note"].strip ~ "}" + ~ "\\addtocounter{footnote}{-1}}"; + })(_txt, rgx.inline_notes_al_special_char_note); } return _txt; } diff --git a/src/sisudoc/outputs/io_out/odt.d b/src/sisudoc/outputs/io_out/odt.d index 40d760d..d8f6c2f 100644 --- a/src/sisudoc/outputs/io_out/odt.d +++ b/src/sisudoc/outputs/io_out/odt.d @@ -107,6 +107,8 @@ template formatODT() { return _on; } string _footnotes()(string _txt) { + import std.array : replace; + import std.regex : replaceAll; static auto rgx = RgxO(); static auto rgx_xhtml = RgxXHTML(); _txt = _txt.replaceAll( @@ -124,6 +126,25 @@ template formatODT() { "$1", "$1", "$2", ) ); + /+ ↓ a note of a special series (*, *1, +1 ...): the same footnote, carrying + its mark as the citation's label, since odf numbers a note itself unless + instructed otherwise. The id takes the mark spelled in letters, "*" and + "+" having no place in one. + +/ + _txt = replaceAll!((m) { + string _mark = m["char"]; + string _id = _mark.replace("*", "a").replace("+", "p"); + return format(q"┃<text:note text:id="ftn_%s" text:note-class="footnote"> + <text:note-citation text:label="%s">%s</text:note-citation> + <text:note-body> + <text:p text:style-name="Footnote"> + %s + </text:p> + </text:note-body> + </text:note>┃", + _id, _mark, _mark, m["note"].strip, + ); + })(_txt, rgx.inline_notes_al_special_char_note); return _txt; } string _bullet(O)(const O obj) { diff --git a/src/sisudoc/outputs/io_out/rgx.d b/src/sisudoc/outputs/io_out/rgx.d index 60e169b..d2e842c 100644 --- a/src/sisudoc/outputs/io_out/rgx.d +++ b/src/sisudoc/outputs/io_out/rgx.d @@ -93,17 +93,17 @@ static template spineRgxOut() { /+ quotation marks +/ static quotes_open_and_close = ctRegex!(`[“”]`, "mg"); /+ inline markup footnotes endnotes +/ - static inline_notes_al = ctRegex!(`【(?:[*+]\s+|\s*)(.+?)】`, "mg"); - static inline_notes_al_special = ctRegex!(`【(?:[*+]\s+)(.+?)】`, "mg"); // TODO remove match when special footnotes are implemented + static inline_notes_al = ctRegex!(`【(?:[*+]+[0-9]*\s+|\s*)(.+?)】`, "mg"); + static inline_notes_al_special = ctRegex!(`【(?:[*+]+[0-9]*\s+)(.+?)】`, "mg"); // TODO remove match when special footnotes are implemented static inline_notes_al_gen = ctRegex!(`【.+?】`, "m"); static inline_notes_al_gen_text = ctRegex!(`【(?P<text>.+?)】`, "m"); - static inline_notes_al_all_note = ctRegex!(`【(?P<num>\d+|(?:[*]|[+])+)\s+(?P<note>.+?)\s*】`, "mg"); + static inline_notes_al_all_note = ctRegex!(`【(?P<num>\d+|[*+]+[0-9]*)\s+(?P<note>.+?)\s*】`, "mg"); static inline_notes_al_regular_number_note = ctRegex!(`【(?P<num>\d+)\s+(?P<note>.+?)\s*】`, "mg"); - static inline_notes_al_special_char_note = ctRegex!(`【(?P<char>(?:[*]|[+])+)\s+(?P<note>.+?)】`, "mg"); + static inline_notes_al_special_char_note = ctRegex!(`【(?P<char>[*+]+[0-9]*)\s+(?P<note>.+?)】`, "mg"); static inline_al_delimiter_open_regular = ctRegex!(`【\s`, "m"); static inline_al_delimiter_open_symbol_star = ctRegex!(`【[*]\s`, "m"); static inline_al_delimiter_open_symbol_plus = ctRegex!(`【[+]\s`, "m"); - static inline_text_and_note_al_ = ctRegex!(`(.+?(?:【[*+]*\s+.+?】|.+))`, "mg"); + static inline_text_and_note_al_ = ctRegex!(`(.+?(?:【[*+]*[0-9]*\s+.+?】|.+))`, "mg"); static endnote_section_note = ctRegex!(`┥\s*⑆\^┨(?P<notenumber>\d+)\.┣\^┝┤(?P<link>¤?.+?)├.+`, "mg"); /+ inline markup links +/ static inline_image = ctRegex!(`(?P<pre>┥)☼(?P<imginf>(?P<img>[a-zA-Z0-9._-]+?\.(?:jpg|gif|png)),w(?P<width>\d+)h(?P<height>\d+))\s*(?P<post>.*?┝┤.*?├)`, "mg"); diff --git a/src/sisudoc/outputs/io_out/text.d b/src/sisudoc/outputs/io_out/text.d index 89e85d9..43c7705 100644 --- a/src/sisudoc/outputs/io_out/text.d +++ b/src/sisudoc/outputs/io_out/text.d @@ -110,13 +110,14 @@ template outputText() { string general_munge; _ocn = (obj.metainfo.ocn == 0 || doc_matters.opt.action.ocn_off) ? "" : "「" ~ obj.metainfo.ocn.to!string ~ "」" ~ newline; + /+ ↓ every note, numbered (1, 2 ...) or of a special series (*, *1, +1 ...) +/ if (_txt.matchFirst(rgx.inline_notes_al_gen)) { - foreach (m; _txt.matchAll(rgx.inline_notes_al_regular_number_note)) { + foreach (m; _txt.matchAll(rgx.inline_notes_al_all_note)) { _notes ~= newlines ~ m["num"] ~ ". " ~ special_characters_and_font_face!().general(m["note"].replaceAll(rgx.inline_link, ("$1"))); } } - _txt = _txt.replaceAll(rgx.inline_notes_al_regular_number_note, "[$1]"); + _txt = _txt.replaceAll(rgx.inline_notes_al_all_note, "[$1]"); _txt = (obj.metainfo.is_a == "code") ? special_characters_and_font_face!().code(_txt) : special_characters_and_font_face!().general(_txt); |
