-*- mode: org -*- #+TITLE: sisudoc spine (doc_reform) metadata (multidocument) curates #+DESCRIPTION: documents - structuring, various output representations & search #+FILETAGS: :spine:hub: #+AUTHOR: Ralph Amissah #+EMAIL: [[mailto:ralph.amissah@gmail.com][ralph.amissah@gmail.com]] #+COPYRIGHT: Copyright (C) 2015 - 2024 Ralph Amissah #+LANGUAGE: en #+STARTUP: content hideblocks hidestars noindent entitiespretty #+PROPERTY: header-args :exports code #+PROPERTY: header-args+ :noweb yes #+PROPERTY: header-args+ :results no #+PROPERTY: header-args+ :cache no #+PROPERTY: header-args+ :padline no #+PROPERTY: header-args+ :mkdirp yes #+OPTIONS: H:3 num:nil toc:t \n:t ::t |:t ^:nil -:t f:t *:t - [[./doc-reform.org][doc-reform.org]] [[./][org/]] * document curate _summary_ :module:spine:metadoc_show_summary: - html ~dr/bin/spine-ldc -v --html --html-link-curate --curate \ --output=/var/www/html \ ~grotto/repo/git.repo/code/project-spine/doc-reform-markup/markup_samples/markup/pod/* ** _module template_ metadoc curate #+HEADER: :tangle "../src/sisudoc/meta/metadoc_curate.d" #+HEADER: :noweb yes #+BEGIN_SRC d <> module sisudoc.meta.metadoc_curate; @safe: template spineMetaDocCurate() { auto spineMetaDocCurate(T,H)( T doc_matters, H hvst, ) { <> mixin InternalMarkup; <> <> } } #+END_SRC ** init *** imports #+NAME: metadoc_curate_imports #+BEGIN_SRC d import sisudoc.meta.defaults, sisudoc.meta.rgx; import std.array, std.exception, std.regex, std.stdio, std.string, std.typecons, std.uni, std.utf, std.conv : to; #+END_SRC *** initialize :report: #+NAME: metadoc_curate_initialize #+BEGIN_SRC d static auto mkup = InlineMarkup(); #+END_SRC ** curate summary #+NAME: meta_metadoc_curate_summary #+BEGIN_SRC d auto min_repeat_number = 66; auto char_repeat_number = (doc_matters.conf_make_meta.meta.title_full.length + doc_matters.conf_make_meta.meta.creator_author.length + 4); char_repeat_number = (char_repeat_number > min_repeat_number) ? char_repeat_number : min_repeat_number; writefln( "%s\n\"%s\", %s\n%s\n%s\n%s", mkup.repeat_character_by_number_provided("-", char_repeat_number), doc_matters.conf_make_meta.meta.title_full, doc_matters.conf_make_meta.meta.creator_author, doc_matters.src.filename, doc_matters.conf_make_meta.meta.classify_topic_register_arr, mkup.repeat_character_by_number_provided("-", char_repeat_number), ); #+END_SRC ** return curate #+NAME: meta_metadoc_curate #+BEGIN_SRC d import sisudoc.io_out.paths_output; auto pth_html_abs = spinePathsHTML!()(doc_matters.output_path, doc_matters.src.language); auto pth_html_rel = spineDocRootTreeHTML!()(doc_matters.src.language); hvst.curate.title = doc_matters.conf_make_meta.meta.title_full; hvst.curate.author = doc_matters.conf_make_meta.meta.creator_author; hvst.curate.author_surname = doc_matters.conf_make_meta.meta.creator_author_surname; hvst.curate.author_surname_fn = doc_matters.conf_make_meta.meta.creator_author_surname_fn; hvst.curate.author_arr = doc_matters.conf_make_meta.meta.creator_author_arr; hvst.curate.language_original = doc_matters.conf_make_meta.meta.original_language; hvst.curate.language = doc_matters.src.language; hvst.curate.uid = doc_matters.src.doc_uid; hvst.curate.date_published = doc_matters.conf_make_meta.meta.date_published; hvst.curate.topic_register_arr = doc_matters.conf_make_meta.meta.classify_topic_register_arr; hvst.curate.path_html_metadata = pth_html_rel.fn_metadata(doc_matters.src.filename); hvst.curate.path_html_scroll = pth_html_rel.fn_scroll(doc_matters.src.filename); hvst.curate.path_html_segtoc = pth_html_rel.fn_seg(doc_matters.src.filename, "toc"); hvst.curate.path_abs_html_scroll = pth_html_abs.fn_scroll(doc_matters.src.filename); hvst.curate.path_abs_html_segtoc = pth_html_abs.fn_seg(doc_matters.src.filename, "toc"); return hvst.curate; #+END_SRC ** _module template_ metadoc curate topics *** _module template_ metadoc curate topics template #+HEADER: :tangle "../src/sisudoc/meta/metadoc_curate_topics.d" #+HEADER: :noweb yes #+BEGIN_SRC d <> module sisudoc.meta.metadoc_curate_topics; @safe: import std.algorithm, std.array, std.exception, std.regex, std.stdio, std.string, std.conv : to; import sisudoc.meta.defaults, sisudoc.meta.rgx; mixin spineCurateMetadata; mixin InternalMarkup; template spineMetaDocCuratesTopics() { static auto mkup = InlineMarkup(); void spineMetaDocCuratesTopics(H,M,O)( H hvst, M _make_and_meta_struct, O _opt_action, ) { <> <> <> <> <> <> <> <> <> topics <> <> } } #+END_SRC *** order topic register #+NAME: curated_topics #+BEGIN_SRC d auto min_repeat_number = 42; string[] _document_topic_register; string[] _topic_register; string[] _sub_topic_register; string[] topics = []; string _auth = ""; foreach(k, doc_curate; hvst.curates) { _topic_register = []; foreach(topic; doc_curate.topic_register_arr.sort) { _sub_topic_register = []; string _spaces; string[] subject_tree = topic.split(mkup.sep); switch (subject_tree.length) { case 1: hvst.subject_trees[subject_tree[0]]["_a"]["_a"]["_a"] ~= doc_curate; break; case 2: hvst.subject_trees[subject_tree[0]][subject_tree[1]]["_a"]["_a"] ~= doc_curate; break; case 3: hvst.subject_trees[subject_tree[0]][subject_tree[1]][subject_tree[2]]["_a"] ~= doc_curate; break; case 4: hvst.subject_trees[subject_tree[0]][subject_tree[1]][subject_tree[2]][subject_tree[3]] ~= doc_curate; break; default: break; } _topic_register ~= _sub_topic_register.join("\n"); } auto char_repeat_number = (doc_curate.title.length + doc_curate.author.length + 16); char_repeat_number = (char_repeat_number > min_repeat_number) ? char_repeat_number : min_repeat_number; _document_topic_register ~= format( "\"%s\", %s%s\n%s", doc_curate.title, doc_curate.author, (doc_curate.date_published.length > 0) ? " (" ~ doc_curate.date_published ~ ")" : "", _topic_register.sort!("toUpper(a) < toUpper(b)", SwapStrategy.unstable).release.join("\n"), ); } #+END_SRC *** curated topics html head #+NAME: curated_topics_html_head_1 #+BEGIN_SRC d topics ~= format(q"┃ ⌘ Curated metadata - ⌘ Topics #+END_SRC *** curated topics html head #+NAME: curated_topics_html_head_2 #+BEGIN_SRC d

⌘ Curated metadata - ⌘ Topics (output organised by language & filetype)

ABCDEFGHIJKLMNOPQRSTUVWXYZ


#+END_SRC *** curated topics html head theme insert #+NAME: curated_topics_html_head_theme #+BEGIN_SRC d ┃", _opt_action.css_theme_default ? theme_light_0 : theme_dark_0, _opt_action.css_theme_default ? theme_light_1 : theme_dark_1, inline_search_form(_make_and_meta_struct), ) ~ "\n"; #+END_SRC *** curated topics html #+NAME: curated_topics_html #+BEGIN_SRC d char _prev_k = "_".to!char; int _kn; foreach(k0; hvst.subject_trees.keys .sort!("toUpper(a) < toUpper(b)", SwapStrategy.unstable) ) { if (k0.toUpper.to!(char[])[0] != _prev_k) { topics ~= format(q"┃

%s

┃", k0.toUpper.to!(char[])[0], k0.toUpper.to!(char[])[0], ); _prev_k = k0.toUpper.to!(char[])[0]; } if (k0 != "_a") { topics ~= format(q"┃

%s

┃", k0.translate([' ' : "_"]), k0,) ~ "\n"; if (_opt_action.show_curate_topics) { writeln("", k0); } if ("_a" in hvst.subject_trees[k0]) { foreach (t_a_; hvst.subject_trees[k0]["_a"]["_a"]["_a"] .multiSort!("toUpper(a.title) < toUpper(b.title)", "a.author < b.author", SwapStrategy.unstable) ) { _auth = []; if (t_a_.author_arr.length < 2) { _auth = format(q"┃ %s┃", t_a_.author_surname.translate([' ' : "_"]), t_a_.author, ); } else { foreach (a; t_a_.author_arr) { _auth ~= format(q"┃ %s,┃", t_a_.author_surname.translate([' ' : "_"]), a, ); } } topics ~= format(q"┃

"%s" - %s [ %s ]┃", t_a_.path_html_segtoc, t_a_.title, _auth, t_a_.path_html_metadata, t_a_.language, ) ~ "\n"; if (_opt_action.show_curate_topics) { writeln("- ", t_a_.title, " - ", t_a_.author); } } } foreach(k1; hvst.subject_trees[k0].keys .sort!("toUpper(a) < toUpper(b)", SwapStrategy.unstable) ) { if (k1 != "_a") { topics ~= format(q"┃

%s

┃", k0.translate([' ' : "_"]), k1.translate([' ' : "_"]), k1,) ~ "\n"; if (_opt_action.show_curate_topics) { writeln(" ", k1); } if ("_a" in hvst.subject_trees[k0][k1]) { foreach (t_a_; hvst.subject_trees[k0][k1]["_a"]["_a"] .multiSort!("toUpper(a.title) < toUpper(b.title)", "a.author < b.author", SwapStrategy.unstable) ) { _auth = []; if (t_a_.author_arr.length < 2) { _auth = format(q"┃ %s┃", t_a_.author_surname.translate([' ' : "_"]), t_a_.author, ); } else { foreach (a; t_a_.author_arr) { _auth ~= format(q"┃ %s,┃", t_a_.author_surname.translate([' ' : "_"]), a, ); } } topics ~= format(q"┃

%s - %s [ %s ]┃", t_a_.path_html_segtoc, t_a_.title, _auth, t_a_.path_html_metadata, t_a_.language, ) ~ "\n"; if (_opt_action.show_curate_topics) { writeln(" - ", t_a_.title, " - ", t_a_.author); } } } } foreach(k2; hvst.subject_trees[k0][k1].keys .sort!("toUpper(a) < toUpper(b)", SwapStrategy.unstable) ) { if (k2 != "_a") { topics ~= format(q"┃

%s

┃", k0.translate([' ' : "_"]), k1.translate([' ' : "_"]), k2.translate([' ' : "_"]), k2,) ~ "\n"; if (_opt_action.show_curate_topics) { writeln(" ", k2); } if ("_a" in hvst.subject_trees[k0][k1][k2]) { foreach (t_a_; hvst.subject_trees[k0][k1][k2]["_a"] .multiSort!("toUpper(a.title) < toUpper(b.title)", "a.author < b.author", SwapStrategy.unstable) ) { _auth = []; if (t_a_.author_arr.length < 2) { _auth = format(q"┃ %s┃", t_a_.author_surname.translate([' ' : "_"]), t_a_.author, ); } else { foreach (a; t_a_.author_arr) { _auth ~= format(q"┃ %s,┃", t_a_.author_surname.translate([' ' : "_"]), a, ); } } topics ~= format(q"┃

%s - %s [ %s ]┃", t_a_.path_html_segtoc, t_a_.title, _auth, t_a_.path_html_metadata, t_a_.language, ) ~ "\n"; if (_opt_action.show_curate_topics) { writeln(" - ", t_a_.title, " - ", t_a_.author); } } } } foreach(k3; hvst.subject_trees[k0][k1][k2].keys .sort!("toUpper(a) < toUpper(b)", SwapStrategy.unstable) ) { if (k3 != "_a") { topics ~= format(q"┃

%s

┃", k0.translate([' ' : "_"]), k1.translate([' ' : "_"]), k2.translate([' ' : "_"]), k3.translate([' ' : "_"]), k3,) ~ "\n"; if (_opt_action.show_curate_topics) { writeln(" ", k3); } { foreach (t_a_; hvst.subject_trees[k0][k1][k2][k3] .multiSort!("toUpper(a.title) < toUpper(b.title)", "a.author < b.author", SwapStrategy.unstable) ) { _auth = []; if (t_a_.author_arr.length < 2) { _auth = format(q"┃%s┃", t_a_.author_surname.translate([' ' : "_"]), t_a_.author, ); } else { foreach (a; t_a_.author_arr) { _auth ~= format(q"┃ %s,┃", t_a_.author_surname.translate([' ' : "_"]), a, ); } } topics ~= format(q"┃

%s - %s [ %s ]┃", t_a_.path_html_segtoc, t_a_.title, _auth, t_a_.path_html_metadata, t_a_.language, ) ~ "\n"; if (_opt_action.show_curate_topics) { writeln(" - ", t_a_.title, " - ", t_a_.author); } } } } } } } } } #+END_SRC *** curated topics write #+NAME: curated_topics_html_write #+BEGIN_SRC d import sisudoc.io_out.paths_output; auto out_pth = spinePathsHTML!()(_make_and_meta_struct.conf.output_path, ""); try { auto f = File(out_pth.curate("topics.html"), "w"); foreach (o; topics) { f.writeln(o); } } catch (ErrnoException ex) { // Handle error } #+END_SRC ** _module template_ metadoc curates authors *** _module template_ metadoc curate authors #+HEADER: :tangle "../src/sisudoc/meta/metadoc_curate_authors.d" #+HEADER: :noweb yes #+BEGIN_SRC d <> module sisudoc.meta.metadoc_curate_authors; @safe: import std.algorithm, std.array, std.exception, std.regex, std.stdio, std.string, std.conv : to; import sisudoc.meta.defaults, sisudoc.meta.rgx; mixin spineCurateMetadata; mixin InternalMarkup; template spineMetaDocCuratesAuthors() { static auto mkup = InlineMarkup(); void spineMetaDocCuratesAuthors(H,M,O)( H curates, M _make_and_meta_struct, O _opt_action, ) { <> <> <> <> <> <> <> authors <> <> } } #+END_SRC *** curated authors html head #+NAME: curated_authors_html_head_1 #+BEGIN_SRC d string[] authors = []; authors ~= format(q"┃ ⌘ Curated metadata - 🖋 Authors #+END_SRC *** curated authors html head #+NAME: curated_authors_html_head_2 #+BEGIN_SRC d

⌘ Curated metadata - 🖋 Authors (output organised by language & filetype)


ABCDEFGHIJKLMNOPQRSTUVWXYZ,  #+END_SRC *** curated authors html theme inserts #+NAME: curated_authors_html_head_theme #+BEGIN_SRC d ┃", _opt_action.css_theme_default ? theme_light_0 : theme_dark_0, _opt_action.css_theme_default ? theme_light_1 : theme_dark_1, inline_search_form(_make_and_meta_struct), ) ~ "\n"; string[string] _au; string[] _auth_date_title; string[] _author_date_title; string _prev_auth = ""; char _prev_k = "_".to!char; foreach(doc_curate; curates .multiSort!( "toUpper(a.author_surname_fn) < toUpper(b.author_surname_fn)", "a.date_published < b.date_published", "a.title < b.title", SwapStrategy.unstable ) ) { if (doc_curate.author_surname_fn != _prev_auth) { _au[doc_curate.author_surname_fn] = format(q"┃

%s

%s "%s" [ %s ]

┃", doc_curate.author_surname.translate([' ' : "_"]), doc_curate.author_surname_fn, (doc_curate.date_published.length > 0) ? doc_curate.date_published : "", doc_curate.path_html_segtoc, doc_curate.title, doc_curate.path_html_metadata, doc_curate.language, ); _prev_auth = doc_curate.author_surname_fn; } else { _au[doc_curate.author_surname_fn] ~= format(q"┃

%s "%s" [ %s ]

┃", (doc_curate.date_published.length > 0) ? doc_curate.date_published : "", doc_curate.path_html_segtoc, doc_curate.title, doc_curate.path_html_metadata, doc_curate.language, ); } _author_date_title ~= format(q"┃%s %s "%s" [ %s ]%s┃", doc_curate.author_surname_fn, (doc_curate.date_published.length > 0) ? "(" ~ doc_curate.date_published ~ ")" : "", doc_curate.title, doc_curate.path_html_metadata, doc_curate.language, (_opt_action.show_curate_authors) ? "\n " ~ doc_curate.path_abs_html_scroll : "", ); } foreach (k; _au.keys.sort) { if (k.toUpper.to!(char[])[0] != _prev_k) { authors ~= format(q"┃

%s

┃", k.toUpper.to!(char[])[0], k.toUpper.to!(char[])[0], ); _prev_k = k.toUpper.to!(char[])[0]; } authors ~= _au[k]; } #+END_SRC *** curated authors write #+NAME: curated_authors_html_write #+BEGIN_SRC d import sisudoc.io_out.paths_output; auto out_pth = spinePathsHTML!()(_make_and_meta_struct.conf.output_path, ""); try { auto f = File(out_pth.curate("authors.html"), "w"); foreach (o; authors) { f.writeln(o); } } catch (ErrnoException ex) { // Handle error } if (_opt_action.show_curate_authors) { foreach(_adt; _author_date_title.sort) { writeln(_adt); } } #+END_SRC ** curated authors & topics shared html *** themes **** head #+NAME: curated_html_themes_0 #+BEGIN_SRC d string theme_dark_0 = format(q"┃ body { color : #CCCCCC; background : #000000; background-color : #000000; } a:link { color : #FFFFFF; text-decoration : none; } a:visited { color : #999999; text-decoration : none; } a:hover { color : #000000; background-color : #555555; } a:hover img { background-color : #000000; } a:active { color : #888888; text-decoration : underline; } a.lev0:hover { color : #FFFFFF; background-color : #000000; } a.lev1:hover { color : #FFFFFF; background : #333333; } a.lev2:hover { color : #FFFFFF; background : #555555; } a.lev3:hover { color : #FFFFFF; background : #777777; } a.lnkicon:link { text-decoration : none; } a.lnkicon:visited { text-decoration : none; } a.lnkicon:hover { font-size : 160%%; } a:hover img { background-color : #FFFFFF; } input, select, textarea { font-size : 150%%; } input { color : #FFFFFF; background-color : #777777; } ┃"); string theme_light_0 = format(q"┃ body { color : #000000; background : #FFFFFF; background-color : #FFFFFF; } a:link { color : #003399; text-decoration : none; } a:visited { color : #003399; text-decoration : none; } a:hover { color : #000000; background-color : #f9f9aa; } a:hover img { background-color : #FFFFFF; } a:active { color : #003399; text-decoration : underline; } a.lev0:hover { color : #000000; background-color : #FFFFFF; } a.lev1:hover { color : #FFFFFF; background : #444444; } a.lev2:hover { background : #888888; } a.lev3:hover { background : #BBBBBB; } a.lnkicon:link { text-decoration : none; } a.lnkicon:visited { text-decoration : none; } a.lnkicon:hover { font-size : 160%%; } a:hover img { background-color : #FFFFFF; } input, select, textarea { font-size : 150%%; } input { color : #000000; background-color : #FFFFFF; } ┃"); #+END_SRC **** levels #+NAME: curated_html_themes_1 #+BEGIN_SRC css string theme_dark_1 = format(q"┃ h1 { color : #FFFFFF; background : #000000; } p.letter { color : #FFFFFF; background : #333333; } p.lev0 { color : #FFFFFF; background : #000000; } p.lev1 { color : #FFFFFF; background : #333333; } p.lev2 { background : #555555; } p.lev3 { background : #777777; } p.lev4 { background : #AAAAAA; } p.lev5 { } ┃"); string theme_light_1 = format(q"┃ h1 { color : #FFFFFF; background : #1A3A7A; } p.letter { color : #FFFFFF; background : #1A3A7A; } p.lev0 { color : #FFFFFF; background : #000000; } p.lev1 { color : #FFFFFF; background : #444444; } p.lev2 { background : #888888; } p.lev3 { background : #BBBBBB; } p.lev4 { background : #EEEEEE; } p.lev5 { } ┃"); #+END_SRC *** search form #+NAME: curated_html_search #+BEGIN_SRC d string inline_search_form(M)( M _make_and_meta_truct, ) { string o; string _form; if (_opt_action.html_link_search) { o = format(q"┃
┃", _make_and_meta_struct.conf.w_srv_cgi_action, (_make_and_meta_struct.conf.w_srv_db_sqlite_filename.empty) ? "" : "\n ", ); } else { o = ""; } return o; } #+END_SRC *** curated html head #+NAME: curated_html_head #+BEGIN_SRC d #+END_SRC *** curated html bottom #+NAME: curated_html_bottom #+BEGIN_SRC d ~= format(q"┃
┃") ~ "\n"; #+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__