diff options
Diffstat (limited to 'org/ocda_get.org')
| -rw-r--r-- | org/ocda_get.org | 284 |
1 files changed, 0 insertions, 284 deletions
diff --git a/org/ocda_get.org b/org/ocda_get.org deleted file mode 100644 index 40effc5..0000000 --- a/org/ocda_get.org +++ /dev/null @@ -1,284 +0,0 @@ --*- mode: org -*- -#+TITLE: sisudoc spine (doc_reform) object-centric document abstraction -#+DESCRIPTION: documents - structuring, publishing in multiple formats & search -#+FILETAGS: :spine:abstraction: -#+AUTHOR: Ralph Amissah -#+EMAIL: [[mailto:ralph.amissah@gmail.com][ralph.amissah@gmail.com]] -#+COPYRIGHT: Copyright (C) 2015 (continuously updated, current 2026) Ralph Amissah -#+LANGUAGE: en -#+STARTUP: content hideblocks hidestars noindent entitiespretty -#+PROPERTY: header-args+ :eval never-export :exports code -#+PROPERTY: header-args+ :noweb yes :padline no -#+PROPERTY: header-args+ :results silent :cache no -#+PROPERTY: header-args+ :mkdirp yes -#+OPTIONS: H:3 num:nil toc:t \n:t ::t |:t ^:nil -:t f:t *:t -- magic single double-quote → " ← FIX changes hilighting behavior (occuring - after it) in org document. INVESTIGATE (org-mode CONFIG?) FIND & FIX - -- [[./doc-reform.org][doc-reform.org]] [[./][org/]] - -* Get OCD - -get abstracted objects for downstream processing - -** _module template_ - -#+HEADER: :tangle "../src/sisudoc/ocda/abstraction/doc_has.d" -#+HEADER: :noweb yes -#+BEGIN_SRC d -<<doc_header_including_copyright_and_license>> -module sisudoc.ocda.abstraction.doc_has; -@safe: -/+ ↓ ST_DocHas from a loaded abstraction - - the parser builds ST_DocHas as it goes, with the markup in front of it. - A document loaded from a .ssp or a .ocda.db has to arrive at the same - value from what the artefact carries, and this is where that is done. - - Every one of these is an *index over properties the artefact already - holds*, not a re-derivation of something it does not: - - imagelist the .image records' filenames - segnames_lv4 .anchor of each body heading at level 4 - segnames_lv_0_to_4 .segment_epub of each heading at level 4 or less - tag_associations .anchor, .anchor_tag and .segment_* per object - section_keys_sequenced which sections are non-empty, plus the run's - own output flags - - That distinction is the line the .ssp skill draws: assembling an index - is fine and cannot drift, because a wrong index would not survive the - round trip that produced its inputs; recomputing dom_status or ancestors - would be re-derivation and is exactly what ocda exists to remove. If a - value is not in the file and cannot be indexed out of what is, it must - be added to the artefact instead of reconstructed here. - - The counts come from the @doc_has block rather than being recounted, for - the same reason. -+/ -template spineDocHasFromAbstraction() { - import std.algorithm : sort, uniq; - import std.array; - import std.conv : to; - import std.json : JSONValue; - import std.regex; - import sisudoc.ocda.meta.metadoc_object_setter; - import sisudoc.ocda.meta.rgx; - mixin ObjectSetter; - mixin spineRgxIn; - /+ ↓ the sections, in the order a document holds them +/ - enum string[] doc_sections = [ - "head", "toc", "body", "endnotes", - "glossary", "bibliography", "bookindex", "blurb", "tail", - ]; - /+ ↓ the tail sections that become segments of their own, in the order - after_doc_determine_segnames appends them +/ - enum string[] tail_sections = [ - "endnotes", "glossary", "bibliography", "bookindex", "blurb", - ]; - private uint _count(string[string] _doc_has, string _key) { - if (auto _v = _key in _doc_has) { - try { return (*_v).to!uint; } catch (Exception ex) { return 0; } - } - return 0; - } - private bool _has_section(A)(A _abst, string _section) { - if (auto _s = _section in _abst) { return (*_s).length > 1; } - return false; - } - /+ ↓ which document sections each output format walks, and in what order. - - the same rule the parser applies: the three that are always there, - then each tail section that the document actually has, then "tail" - for the formats that close with one. It depends on the run as well as - on the document, since only html and epub take the tail. - +/ - string[][string] sectionKeysSequenced(A,O)(A _abst, O _opt_action) { - string[][string] _keys = [ - "scroll": ["head", "toc", "body",], - "seg": ["head", "toc", "body",], - "sql": ["head", "body",], - "latex": ["head", "toc", "body",], - "text": ["head", "toc", "body",], - ]; - if (_has_section(_abst, "endnotes")) { - _keys["scroll"] ~= "endnotes"; - _keys["seg"] ~= "endnotes"; - _keys["latex"] ~= "endnotes"; - _keys["text"] ~= "endnotes"; - } - if (_has_section(_abst, "glossary")) { - foreach (_k; ["scroll", "seg", "sql", "latex", "text"]) { _keys[_k] ~= "glossary"; } - } - if (_has_section(_abst, "bibliography")) { - foreach (_k; ["scroll", "seg", "sql", "latex", "text"]) { _keys[_k] ~= "bibliography"; } - } - if (_has_section(_abst, "bookindex")) { - foreach (_k; ["scroll", "seg", "sql", "latex", "text"]) { _keys[_k] ~= "bookindex"; } - } - if (_has_section(_abst, "blurb")) { - foreach (_k; ["scroll", "seg", "sql", "latex", "text"]) { _keys[_k] ~= "blurb"; } - } - if (_opt_action.html_scroll || _opt_action.html_seg || _opt_action.epub) { - _keys["scroll"] ~= "tail"; - _keys["seg"] ~= "tail"; - } - return _keys; - } - /+ ↓ the whole of it +/ - ST_DocHas docHasFromAbstraction(A,O)( - A _abst, - string[string] _doc_has_block, - O _opt_action, - ) { - static auto rgx = RgxI(); - ST_DocHas _out; - _out.inline_links = _count(_doc_has_block, "inline_links"); - _out.inline_notes_reg = _count(_doc_has_block, "inline_notes_reg"); - _out.inline_notes_star = _count(_doc_has_block, "inline_notes_star"); - _out.codeblocks = _count(_doc_has_block, "codeblocks"); - _out.tables = _count(_doc_has_block, "tables"); - _out.blocks = _count(_doc_has_block, "blocks"); - _out.groups = _count(_doc_has_block, "groups"); - _out.poems = _count(_doc_has_block, "poems"); - _out.quotes = _count(_doc_has_block, "quotes"); - string[] _images; - string[string][string] _tag_assoc; - /+ ↓ segnames["html"] is seeded with the toc, which is a segment of its - own before any level 4 heading opens one +/ - _out.segnames_lv4 ~= "toc"; - foreach (_section; doc_sections) { - if (_section !in _abst) { continue; } - /+ ↓ head is always walked; every other section only when it holds - more than the placeholder object, which is the guard the parser - puts on each of its section loops - +/ - if (_section != "head" && !_has_section(_abst, _section)) { continue; } - foreach (obj; _abst[_section]) { - /+ ↓ the images this object names, as the abstraction recorded them +/ - foreach (_img; obj.metainfo.sha256.images) { _images ~= _img.fileName; } - /+ ↓ every object: its html anchor is in a segment, and its epub - segment anchor stands for itself +/ - if (obj.tags.anchor_tag_html.length > 0) { - _tag_assoc[obj.tags.anchor_tag_html]["seg_lv4"] = obj.tags.in_segment_html; - } - if (obj.tags.segment_anchor_tag_epub.length > 0) { - _tag_assoc[obj.tags.segment_anchor_tag_epub]["seg_lv1to4"] - = obj.tags.segment_anchor_tag_epub; - } - /+ ↓ a heading's own anchor tags, and the anchors declared inline in - an object's text, both point at the segment the object is in +/ - /+ ↓ a heading above level 4 opens no html segment of its own, so a - cross reference to it has to land on the level 4 segment that - follows it. .segment is exactly that (the segment a heading - opens or falls into), where .segment_html_is is the segment an - object sits in; epub segments go down to level 1, so there - .segment_epub stands for the heading itself - +/ - if (obj.tags.heading_lev_anchor_tag.length > 0 - && obj.tags.in_segment_html.length > 0 - && obj.metainfo.heading_lev_markup >= 4 - ) { - _tag_assoc[obj.tags.heading_lev_anchor_tag]["seg_lv4"] - = obj.tags.in_segment_html; - if (obj.tags.segment_anchor_tag_epub.length > 0) { - _tag_assoc[obj.tags.heading_lev_anchor_tag]["seg_lv1to4"] - = obj.tags.segment_anchor_tag_epub; - } - } - foreach (m; obj.text.matchAll(rgx.inline_link_anchor)) { - string _a = m["anchor"].to!string; - if (_a.length == 0 || _a in _tag_assoc) { continue; } - _tag_assoc[_a]["seg_lv4"] = obj.tags.html_segment_anchor_tag_is; - _tag_assoc[_a]["seg_lv1to4"] = obj.tags.epub_segment_anchor_tag_is; - } - /+ ↓ the segment name lists, in document order +/ - if (obj.metainfo.is_a == "heading") { - if (obj.metainfo.heading_lev_markup <= 4) { - _out.segnames_lv_0_to_4 ~= obj.tags.segment_anchor_tag_epub; - } - if (_section == "body" && obj.metainfo.heading_lev_markup == 4) { - _out.segnames_lv4 ~= obj.tags.anchor_tag_html; - } - /+ ↓ a heading above level 4 opens no html segment of its own, so - a cross reference to it lands on the level 4 segment that - follows. That is .segment_lv4_is, resolved in ocda where the - finished sections are to hand and carried by the artefact, so - there is nothing to work out here - +/ - if (obj.tags.segment_lv4_is.length > 0) { - /+ ↓ seg_lv4 only, and not through heading_lev_anchor_tag: that - names the level 4 heading itself, whose own entry says it - opens that segment rather than merely sits in it. epub - segments go down to level 1, so seg_lv1to4 is untouched - +/ - foreach (_k; [obj.metainfo.identifier, obj.tags.anchor_tag_html]) { - if (_k.length > 0) { _tag_assoc[_k]["seg_lv4"] = obj.tags.segment_lv4_is; } - } - } - } - } - } - foreach (_section; tail_sections) { - if (_has_section(_abst, _section)) { _out.segnames_lv4 ~= _section; } - } - /+ ↓ the body's objects, in a pass of their own after every anchor above - has been recorded, because the parser does it in that order and the - order is what decides two of these entries. - . - each body object's identifier maps to the segment it is in. seg_lv4 - is set only where it is not already, an anchor of the same name - having said it *names* a segment rather than sits in one; seg_lv1to4 - is set always. A heading's own anchor can be a bare number taken - from its text ("2. Shorter Terms" gives the anchor "2"), which then - collides with the ocn of an unrelated object, and this is the order - that resolves the collision the way the parser resolves it: in - free_culture, ocn 2 keeps seg_lv4 "them" from the anchor and takes - seg_lv1to4 "_part_1" from itself. - +/ - if (_has_section(_abst, "body")) { - foreach (obj; _abst["body"]) { - if (obj.metainfo.identifier.length == 0) { continue; } - if (!((obj.metainfo.identifier in _tag_assoc) - && ("seg_lv4" in _tag_assoc[obj.metainfo.identifier])) - ) { - _tag_assoc[obj.metainfo.identifier]["seg_lv4"] - = obj.tags.html_segment_anchor_tag_is; - } - _tag_assoc[obj.metainfo.identifier]["seg_lv1to4"] - = obj.tags.epub_segment_anchor_tag_is; - } - } - _out.imagelist = _images.sort.uniq.array; - _out.tag_associations = _tag_assoc; - _out.section_keys_sequenced = sectionKeysSequenced(_abst, _opt_action); - return _out; - } -} -#+END_SRC - -* org includes -** project version - -#+NAME: spine_version -#+HEADER: :noweb yes -#+BEGIN_SRC emacs-lisp -<<./sisudoc_spine_version_info_and_doc_header_including_copyright_and_license.org:spine_project_version()>> -#+END_SRC - -** year - -#+NAME: year -#+HEADER: :noweb yes -#+BEGIN_SRC emacs-lisp -<<./sisudoc_spine_version_info_and_doc_header_including_copyright_and_license.org:year()>> -#+END_SRC - -** document header including copyright & license - -#+NAME: doc_header_including_copyright_and_license -#+HEADER: :noweb yes -#+BEGIN_SRC emacs-lisp -<<./sisudoc_spine_version_info_and_doc_header_including_copyright_and_license.org:spine_doc_header_including_copyright_and_license()>> -#+END_SRC - -* __END__ |
