diff options
Diffstat (limited to 'src/sisudoc/spine.d')
| -rwxr-xr-x | src/sisudoc/spine.d | 360 |
1 files changed, 194 insertions, 166 deletions
diff --git a/src/sisudoc/spine.d b/src/sisudoc/spine.d index 59789f6..f53fc09 100755 --- a/src/sisudoc/spine.d +++ b/src/sisudoc/spine.d @@ -54,32 +54,30 @@ description "A SiSU inspired document parser written in D." homepage "https://sisudoc.org" +/ @safe: -import - std.algorithm, - std.datetime, - std.getopt, - std.file, - std.path, - std.process; -import - sisudoc.conf.compile_time_info, - sisudoc.meta, - sisudoc.meta.metadoc, - sisudoc.meta.metadoc_curate, - sisudoc.meta.metadoc_curate_authors, - sisudoc.meta.metadoc_curate_topics, - sisudoc.meta.metadoc_from_src, - sisudoc.meta.conf_make_meta_structs, - sisudoc.meta.conf_make_meta_json, - sisudoc.meta.defaults, - sisudoc.meta.doc_debugs, - sisudoc.meta.rgx, - sisudoc.meta.rgx_yaml, - sisudoc.meta.rgx_files, - sisudoc.io_in.paths_source, - sisudoc.io_in.read_config_files, - sisudoc.io_in.read_source_files, - sisudoc.io_out.hub; +import std.algorithm; +import std.datetime; +import std.getopt; +import std.file; +import std.path; +import std.process; +import sisudoc.conf.compile_time_info; +import sisudoc.meta; +import sisudoc.meta.metadoc; +import sisudoc.meta.metadoc_curate; +import sisudoc.meta.metadoc_curate_authors; +import sisudoc.meta.metadoc_curate_topics; +import sisudoc.meta.metadoc_from_src; +import sisudoc.meta.conf_make_meta_structs; +import sisudoc.meta.conf_make_meta_json; +import sisudoc.meta.defaults; +import sisudoc.meta.doc_debugs; +import sisudoc.meta.rgx; +import sisudoc.meta.rgx_yaml; +import sisudoc.meta.rgx_files; +import sisudoc.io_in.paths_source; +import sisudoc.io_in.read_config_files; +import sisudoc.io_in.read_source_files; +import sisudoc.io_out.hub; mixin(import("version.txt")); mixin(import("configuration.txt")); mixin CompileTimeInfo; @@ -146,6 +144,7 @@ string program_name = "spine"; "html-link-pdf-a4" : false, "html-link-pdf-letter" : false, "html-link-search" : false, + "html-link-text" : false, "html-seg" : false, "html-scroll" : false, "latex" : false, @@ -155,6 +154,7 @@ string program_name = "spine"; "light" : false, "manifest" : false, "hide-ocn" : false, + "no-ocn" : false, "ocn-off" : false, "odf" : false, "odt" : false, @@ -178,6 +178,7 @@ string program_name = "spine"; "show-pod" : false, "show-sqlite" : false, "show-summary" : false, + "skel" : false, "source" : false, "sqlite-discrete" : false, "sqlite-db-create" : false, @@ -187,9 +188,11 @@ string program_name = "spine"; "sqlite-insert" : false, "sqlite-update" : false, "text" : false, - "vox_is0" : false, - "vox_gt1" : false, - "vox_gt2" : false, + "vox_is0" : false, // silent + "vox_is1" : false, // quiet + "vox_is2" : false, // default (unset) + "vox_is3" : false, // verbose + "vox_is4" : false, // very verbose "xhtml" : false, "section_toc" : true, "section_body" : true, @@ -250,6 +253,7 @@ string program_name = "spine"; "html-link-pdf", "provide html link to pdf a4 & letter output", &opts["html-link-pdf"], "html-link-pdf-a4", "provide html link to pdf a4 output", &opts["html-link-pdf-a4"], "html-link-pdf-letter", "provide html link to pdf letter size output", &opts["html-link-pdf-letter"], + "html-link-text", "provide html link to text output", &opts["html-link-text"], "html-link-search", "html embedded search submission", &opts["html-link-search"], "html-seg", "process html output", &opts["html-seg"], "html-scroll", "process html output", &opts["html-scroll"], @@ -260,6 +264,7 @@ string program_name = "spine"; "latex-header-sty", "latex document header sty files", &opts["latex-header-sty"], "light", "default light theme", &opts["light"], "manifest", "process manifest output", &opts["manifest"], + "no-ocn", "object cite numbers", &opts["no-ocn"], "ocn-off", "object cite numbers", &opts["ocn-off"], "odf", "open document format text (--odt)", &opts["odf"], "odt", "open document format text", &opts["odt"], @@ -270,7 +275,7 @@ string program_name = "spine"; "pdf-color-links", "mono or color links for pdfs", &opts["pdf-color-links"], "pdf-init", "initialise latex shared files (see latex-header-sty)", &opts["pdf-init"], "pod", "spine (doc reform) pod source content bundled", &opts["pod"], - "quiet|q", "output to terminal", &opts["vox_is0"], + "quiet|q", "output to terminal", &opts["vox_is1"], "section-backmatter", "document backmatter (default)" , &opts["backmatter"], "section-biblio", "document biblio (default)", &opts["section_biblio"], "section-blurb", "document blurb (default)", &opts["section_blurb"], @@ -295,9 +300,11 @@ string program_name = "spine"; "show-sqlite", "show sqlite", &opts["show-sqlite"], "show-summary", "show summary", &opts["show-summary"], "source", "document markup source", &opts["source"], + "silent", "output to terminal", &opts["vox_is0"], "set-digest", "default hash digest type (e.g. sha256)", &settings["set-digest"], "set-papersize", "default papersize (latex pdf eg. a4 or a5 or b4 or letter)", &settings["set-papersize"], "set-textwrap", "default textwrap (e.g. 80 (characters)", &settings["set-textwrap"], + "skel", "skel (dummy outline)", &opts["skel"], "sqlite-discrete", "process discrete sqlite output", &opts["sqlite-discrete"], "sqlite-db-create", "create db, create tables", &opts["sqlite-db-create"], "sqlite-db-drop", "drop tables & db", &opts["sqlite-db-drop"], @@ -307,16 +314,16 @@ string program_name = "spine"; "sqlite-delete", "sqlite output", &opts["sqlite-delete"], "sqlite-insert", "sqlite output", &opts["sqlite-insert"], "sqlite-update", "sqlite output", &opts["sqlite-update"], + "text", "text output", &opts["text"], + "txt", "text output", &opts["text"], "www-http", "http or https", &settings["www-http"], "www-host", "web server host (domain) name", &settings["www-host"], "www-host-doc-root", "web host host (domain) name with path to doc root", &settings["www-host-doc-root"], "www-url-doc-root", "e.g. http://localhost", &settings["www-url-doc-root"], - "text", "text output", &opts["text"], "theme-dark", "alternative dark theme", &opts["theme-dark"], "theme-light", "default light theme", &opts["theme-light"], - "txt", "text output", &opts["text"], - "verbose|v", "output to terminal", &opts["vox_gt1"], - "very-verbose", "output to terminal", &opts["vox_gt2"], + "verbose|v", "output to terminal", &opts["vox_is3"], + "very-verbose", "output to terminal", &opts["vox_is4"], "workon", "(reserved for some matters under development & testing)", &opts["workon"], "xhtml", "xhtml output", &opts["xhtml"], "config", "=/path/to/config/file/including/filename", &settings["config"], @@ -338,7 +345,7 @@ string program_name = "spine"; if (helpInfo.helpWanted) { defaultGetoptPrinter("Some information about the program.", helpInfo.options); } - enum outTask { source_or_pod, sqlite, sqlite_multi, latex, odt, epub, html_scroll, html_seg, html_stuff } + enum outTask { source_or_pod, sqlite, sqlite_multi, latex, odt, epub, html_scroll, html_seg, html_stuff, text, skel } struct OptActions { @trusted bool allow_downloads() { return opts["allow-downloads"]; @@ -442,6 +449,12 @@ string program_name = "spine"; @trusted bool html_link_pdf_letter() { return (opts["html-link-pdf-letter"]) ? true : false; } + @trusted bool html_link_text() { + return (opts["html-link-text"]) ? true : false; + } + @trusted bool text_link_curate() { + return (opts["text-link-curate"]) ? true : false; + } @trusted bool html_link_search() { return (opts["html-link-search"]) ? true : false; } @@ -476,7 +489,7 @@ string program_name = "spine"; return opts["hide-ocn"]; } @trusted bool ocn_off() { - return opts["ocn-off"]; + return ((opts["ocn-off"]) || (opts["no-ocn"])) ? true : false; } @trusted bool pod() { return opts["pod"]; @@ -488,10 +501,10 @@ string program_name = "spine"; return opts["show-curate"]; } @trusted bool show_curate_authors() { - return (opts["show-curate"] || opts["show-curate-authors"] || opts["vox_gt1"] || opts["vox_gt2"]) ? true : false; + return (opts["show-curate"] || opts["show-curate-authors"] || vox_gt_2) ? true : false; } @trusted bool show_curate_topics() { - return (opts["show-curate"] || opts["show-curate-topics"] || opts["vox_gt2"]) ? true : false; + return (opts["show-curate"] || opts["show-curate-topics"] || vox_gt_3) ? true : false; } @trusted bool show_epub() { return opts["show-epub"]; @@ -515,10 +528,10 @@ string program_name = "spine"; return opts["show-pod"]; } @trusted bool show_sqlite() { - return (opts["show-sqlite"] || opts["vox_gt2"]) ? true : false; + return (opts["show-sqlite"] || vox_gt_3) ? true : false; } @trusted bool show_summary() { - return (opts["show-summary"] || opts["vox_gt1"] || opts["vox_gt2"]) ? true : false; + return (opts["show-summary"] || vox_gt_2) ? true : false; } @trusted bool source() { return opts["source"]; @@ -550,21 +563,48 @@ string program_name = "spine"; || opts["sqlite-update"] ) ? true : false; } - @trusted bool vox_is0() { // --quiet -q + @trusted bool skel() { + return opts["skel"]; + } + @trusted bool text() { + return opts["text"]; + } + @trusted bool vox_0() { // --silent return opts["vox_is0"]; } - @trusted bool vox_gt0() { // normal, minimal, without flag - return (!(opts["vox_is0"]) || opts["vox_gt1"] || opts["vox_gt2"]) ? true : false; + @trusted bool vox_1() { // --quiet -q + return opts["vox_is1"]; } - @trusted bool vox_gt1() { // -- verbose -v - return (opts["vox_gt1"] || opts["vox_gt2"]) ? true : false; + @trusted bool vox_2() { // normal, minimal, without flag + bool _vox_default = true; + if (opts["vox_is0"] || opts["vox_is1"] || opts["vox_is3"] || opts["vox_is4"]) { _vox_default = false; + } else { _vox_default = true; + } + return _vox_default; } - @trusted bool vox_gt2() { // --very-verbose - return opts["vox_gt2"]; + @trusted bool vox_3() { // --verbose -v + return opts["vox_is3"]; } - @trusted bool text() { - return opts["text"]; + @trusted bool vox_4() { // --very-verbose + return opts["vox_is4"]; } + @trusted bool vox_gt_0() { // --quiet -q and above + return ( vox_1 || vox_2 || vox_3 || vox_4) ? true : false; + } + @trusted bool vox_gt_1() { // normal, and above + return (vox_2 || vox_3 || vox_4) ? true : false; + } + @trusted bool vox_gt_2() { // --verbose -v and above + return ( vox_3 || vox_4) ? true : false; + } + @trusted bool vox_gt_3() { // --very-verbose + return (vox_4) ? true : false; + } + @trusted bool vox_silent() { return vox_0; } // --silent + @trusted bool vox_quiet() { return vox_gt_0; } // --quiet -q & above + @trusted bool vox_default() { return vox_gt_1; } // defalt, & above + @trusted bool vox_verbose() { return vox_gt_2; } // --verbose -v & above + @trusted bool vox_very_verbose() { return vox_gt_3; } // --very-verbose @trusted bool xhtml() { return opts["xhtml"]; } @@ -678,6 +718,8 @@ string program_name = "spine"; || latex || manifest || sqlite_discrete + || text + || skel ) { _is = true; } else { _is = false; } @@ -688,30 +730,16 @@ string program_name = "spine"; } auto output_task_scheduler() { int[] schedule; - if (source_or_pod) { - schedule ~= outTask.source_or_pod; - } - if (sqlite_discrete) { - schedule ~= outTask.sqlite; - } - if (epub) { - schedule ~= outTask.epub; - } - if (html_scroll) { - schedule ~= outTask.html_scroll; - } - if (html_seg) { - schedule ~= outTask.html_seg; - } - if (html_stuff) { - schedule ~= outTask.html_stuff; - } - if (odt) { - schedule ~= outTask.odt; - } - if (latex) { - schedule ~= outTask.latex; - } + if (source_or_pod) { schedule ~= outTask.source_or_pod; } + if (sqlite_discrete) { schedule ~= outTask.sqlite; } + if (epub) { schedule ~= outTask.epub; } + if (html_scroll) { schedule ~= outTask.html_scroll; } + if (html_seg) { schedule ~= outTask.html_seg; } + if (html_stuff) { schedule ~= outTask.html_stuff; } + if (odt) { schedule ~= outTask.odt; } + if (latex) { schedule ~= outTask.latex; } + if (text) { schedule ~= outTask.text; } + if (skel) { schedule ~= outTask.skel; } return schedule.sort().uniq; } @trusted bool abstraction() { @@ -728,6 +756,8 @@ string program_name = "spine"; || sqlite_discrete || sqlite_delete || sqlite_update + || text + || skel ) ? true : false; } @trusted bool require_processing_files() { @@ -749,6 +779,7 @@ string program_name = "spine"; || sqlite_update || text || xhtml + || skel ) ? true : false; } @trusted bool meta_processing_general() { @@ -761,6 +792,8 @@ string program_name = "spine"; || latex || sqlite_discrete || sqlite_update + || text + || skel ) ? true :false; } @trusted bool meta_processing_xml_dom() { @@ -884,94 +917,53 @@ string program_name = "spine"; ); if (exists(sisudoc_txt_)) { try { - if (exists(sisudoc_txt_)) { - import dyaml; - try { - Node pod_manifest_yaml; - try { - pod_manifest_yaml = Loader.fromFile(sisudoc_txt_).load(); - } catch (ErrnoException ex) { - } catch (FileException ex) { - writeln("ERROR failed to read config file"); - } catch (Throwable) { - writeln("ERROR failed to read config file content, not parsed as yaml"); - } - if ("doc" in pod_manifest_yaml) { - if (pod_manifest_yaml["doc"].type.mapping - && pod_manifest_yaml["doc"].tag.match(rgx_y.yaml_tag_is_map) - ) { - if ("path" in pod_manifest_yaml["doc"]) { - if (pod_manifest_yaml["doc"]["path"].tag.match(rgx_y.yaml_tag_is_seq)) { - foreach (string _path; pod_manifest_yaml["doc"]["path"]) { - markup_contents_location_ ~= _path ~ "\n"; - pod_manifest_root_content_paths_to_markup_location_raw_ ~= - _path ~ "\n"; - } - } else if ( - pod_manifest_yaml["doc"]["path"].type.string - && pod_manifest_yaml["doc"]["path"].tag.match(rgx_y.yaml_tag_is_str) - ) { - markup_contents_location_ = pod_manifest_yaml["doc"]["path"].get!string; - pod_manifest_root_content_paths_to_markup_location_raw_ = - pod_manifest_yaml["doc"]["path"].get!string; - } + import dyaml; + Node pod_manifest_yaml; + try { + pod_manifest_yaml = Loader.fromFile(sisudoc_txt_).load(); + } catch (ErrnoException ex) { + } catch (FileException ex) { + writeln("ERROR failed to read config file"); + } catch (Throwable) { + writeln("ERROR failed to read config file content, not parsed as yaml"); + } + if ("doc" in pod_manifest_yaml) { + if (pod_manifest_yaml["doc"].type.mapping + && pod_manifest_yaml["doc"].tag.match(rgx_y.yaml_tag_is_map) + ) { + if ("path" in pod_manifest_yaml["doc"]) { + if (pod_manifest_yaml["doc"]["path"].tag.match(rgx_y.yaml_tag_is_seq)) { + foreach (string _path; pod_manifest_yaml["doc"]["path"]) { + markup_contents_location_ ~= _path ~ "\n"; + pod_manifest_root_content_paths_to_markup_location_raw_ ~= + _path ~ "\n"; } - if ("filename" in pod_manifest_yaml["doc"]) { - if (pod_manifest_yaml["doc"]["filename"].tag.match(rgx_y.yaml_tag_is_seq)) { - foreach (string _filename; pod_manifest_yaml["doc"]["filename"]) { - if ("language" in pod_manifest_yaml["doc"]) { - if (pod_manifest_yaml["doc"]["language"].tag.match(rgx_y.yaml_tag_is_seq)) { - foreach (string _lang; pod_manifest_yaml["doc"]["language"]) { - markup_contents_location_ ~= - "media/text/" - ~ _lang ~ "/" - ~ _filename ~ "\n"; - } - } else if (pod_manifest_yaml["doc"]["language"].tag.match(rgx_y.yaml_tag_is_str) - ) { - markup_contents_location_ = - "media/text/" - ~ pod_manifest_yaml["doc"]["language"].get!string - ~ "/" ~ _filename ~ "\n"; - } else { - string _lang_default = "en"; - markup_contents_location_ ~= - "media/text/" - ~ _lang_default ~ "/" - ~ pod_manifest_yaml["doc"]["filename"].get!string ~ "\n"; - } - } else { - string _lang_default = "en"; - markup_contents_location_ ~= - "media/text/" - ~ _lang_default ~ "/" - ~ pod_manifest_yaml["doc"]["filename"].get!string ~ "\n"; - } - } - } else if ( - pod_manifest_yaml["doc"]["filename"].type.string - && pod_manifest_yaml["doc"]["filename"].tag.match(rgx_y.yaml_tag_is_str) - ) { - if ("language" in pod_manifest_yaml["doc"]) { - if (pod_manifest_yaml["doc"]["language"].tag.match(rgx_y.yaml_tag_is_seq)) { - foreach (string _lang; pod_manifest_yaml["doc"]["language"]) { - markup_contents_location_ ~= - "media/text/" - ~ _lang ~ "/" - ~ pod_manifest_yaml["doc"]["filename"].get!string ~ "\n"; - } - } else if (pod_manifest_yaml["doc"]["language"].tag.match(rgx_y.yaml_tag_is_str)) { - markup_contents_location_ = - "media/text/" - ~ pod_manifest_yaml["doc"]["language"].get!string - ~ "/" ~ pod_manifest_yaml["doc"]["filename"].get!string ~ "\n"; - } else { - string _lang_default = "en"; + } else if ( + pod_manifest_yaml["doc"]["path"].type.string + && pod_manifest_yaml["doc"]["path"].tag.match(rgx_y.yaml_tag_is_str) + ) { + markup_contents_location_ = pod_manifest_yaml["doc"]["path"].get!string; + pod_manifest_root_content_paths_to_markup_location_raw_ = + pod_manifest_yaml["doc"]["path"].get!string; + } + } + if ("filename" in pod_manifest_yaml["doc"]) { + if (pod_manifest_yaml["doc"]["filename"].tag.match(rgx_y.yaml_tag_is_seq)) { + foreach (string _filename; pod_manifest_yaml["doc"]["filename"]) { + if ("language" in pod_manifest_yaml["doc"]) { + if (pod_manifest_yaml["doc"]["language"].tag.match(rgx_y.yaml_tag_is_seq)) { + foreach (string _lang; pod_manifest_yaml["doc"]["language"]) { markup_contents_location_ ~= "media/text/" - ~ _lang_default ~ "/" - ~ pod_manifest_yaml["doc"]["filename"].get!string ~ "\n"; + ~ _lang ~ "/" + ~ _filename ~ "\n"; } + } else if (pod_manifest_yaml["doc"]["language"].tag.match(rgx_y.yaml_tag_is_str) + ) { + markup_contents_location_ = + "media/text/" + ~ pod_manifest_yaml["doc"]["language"].get!string + ~ "/" ~ _filename ~ "\n"; } else { string _lang_default = "en"; markup_contents_location_ ~= @@ -979,11 +971,47 @@ string program_name = "spine"; ~ _lang_default ~ "/" ~ pod_manifest_yaml["doc"]["filename"].get!string ~ "\n"; } + } else { + string _lang_default = "en"; + markup_contents_location_ ~= + "media/text/" + ~ _lang_default ~ "/" + ~ pod_manifest_yaml["doc"]["filename"].get!string ~ "\n"; + } + } + } else if ( + pod_manifest_yaml["doc"]["filename"].type.string + && pod_manifest_yaml["doc"]["filename"].tag.match(rgx_y.yaml_tag_is_str) + ) { + if ("language" in pod_manifest_yaml["doc"]) { + if (pod_manifest_yaml["doc"]["language"].tag.match(rgx_y.yaml_tag_is_seq)) { + foreach (string _lang; pod_manifest_yaml["doc"]["language"]) { + markup_contents_location_ ~= + "media/text/" + ~ _lang ~ "/" + ~ pod_manifest_yaml["doc"]["filename"].get!string ~ "\n"; + } + } else if (pod_manifest_yaml["doc"]["language"].tag.match(rgx_y.yaml_tag_is_str)) { + markup_contents_location_ = + "media/text/" + ~ pod_manifest_yaml["doc"]["language"].get!string + ~ "/" ~ pod_manifest_yaml["doc"]["filename"].get!string ~ "\n"; + } else { + string _lang_default = "en"; + markup_contents_location_ ~= + "media/text/" + ~ _lang_default ~ "/" + ~ pod_manifest_yaml["doc"]["filename"].get!string ~ "\n"; } + } else { + string _lang_default = "en"; + markup_contents_location_ ~= + "media/text/" + ~ _lang_default ~ "/" + ~ pod_manifest_yaml["doc"]["filename"].get!string ~ "\n"; } } } - } catch (ErrnoException ex) { } } } catch (ErrnoException ex) { @@ -1036,7 +1064,7 @@ string program_name = "spine"; foreach(manifest; parallel(_manifests[1..$])) { if (!empty(manifest.src.filename)) { scope(success) { - if (_opt_action.vox_gt0) { writeln("-- ~ document complete, ok ~ ------------------------------------"); } + if (_opt_action.vox_gt_1) { writeln("-- ~ document complete, ok ~ ------------------------------------"); } } scope(failure) { debug(checkdoc) { @@ -1094,7 +1122,7 @@ string program_name = "spine"; } else { if ((doc.matters.opt.action.debug_do) || (_opt_action.debug_do_curate) - || (doc.matters.opt.action.vox_gt2) + || (doc.matters.opt.action.vox_gt_3) ) { writeln("WARNING curate: document header yaml does not contain information related to: title or author: ", _hvst.path_html_segtoc); } @@ -1115,7 +1143,7 @@ string program_name = "spine"; } } scope(exit) { - if (_opt_action.vox_gt0) { + if (_opt_action.vox_gt_1) { writefln( "processed file: %s [%s]", manifest.src.filename, @@ -1132,10 +1160,10 @@ string program_name = "spine"; } } else { // note cannot parallelise sqlite shared db foreach(manifest; _manifests[1..$]) { - if (_opt_action.vox_gt2) { writeln("parallelisation off: actions include sqlite shared db"); } + if (_opt_action.vox_gt_3) { writeln("parallelisation off: actions include sqlite shared db"); } if (!empty(manifest.src.filename)) { scope(success) { - if (_opt_action.vox_gt0) { writeln("-- ~ document complete, ok ~ ------------------------------------"); } + if (_opt_action.vox_gt_1) { writeln("-- ~ document complete, ok ~ ------------------------------------"); } } scope(failure) { debug(checkdoc) { @@ -1193,7 +1221,7 @@ string program_name = "spine"; } else { if ((doc.matters.opt.action.debug_do) || (_opt_action.debug_do_curate) - || (doc.matters.opt.action.vox_gt2) + || (doc.matters.opt.action.vox_gt_3) ) { writeln("WARNING curate: document header yaml does not contain information related to: title or author: ", _hvst.path_html_segtoc); } @@ -1214,7 +1242,7 @@ string program_name = "spine"; } } scope(exit) { - if (_opt_action.vox_gt0) { + if (_opt_action.vox_gt_1) { writefln( "processed file: %s [%s]", manifest.src.filename, @@ -1238,7 +1266,7 @@ string program_name = "spine"; if (_opt_action.curate_authors) { spineMetaDocCuratesAuthors!()(hvst.curates, _make_and_meta_struct, _opt_action); } - if (_opt_action.vox_gt0) { + if (_opt_action.vox_gt_1) { import sisudoc.io_out.paths_output; auto out_pth = spinePathsHTML!()(_make_and_meta_struct.conf.output_path, ""); if (_opt_action.curate_authors) { |
