From 90051a7ea55acb043434b1c2483b878d602246ba Mon Sep 17 00:00:00 2001 From: Ralph Amissah Date: Fri, 2 Apr 2021 19:37:00 -0400 Subject: org mode (ruby code within) --- org/abstraction.org | 7291 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 7291 insertions(+) create mode 100644 org/abstraction.org (limited to 'org/abstraction.org') diff --git a/org/abstraction.org b/org/abstraction.org new file mode 100644 index 00000000..103c9218 --- /dev/null +++ b/org/abstraction.org @@ -0,0 +1,7291 @@ +-*- mode: org -*- +#+TITLE: sisu abstraction +#+DESCRIPTION: documents - structuring, various output representations & search +#+FILETAGS: :sisu:abstraction: +#+AUTHOR: Ralph Amissah +#+EMAIL: [[mailto:ralph.amissah@gmail.com][ralph.amissah@gmail.com]] +#+COPYRIGHT: Copyright (C) 2015 - 2021 Ralph Amissah +#+LANGUAGE: en +#+STARTUP: content hideblocks hidestars noindent entitiespretty +#+OPTIONS: H:3 num:nil toc:t \n:nil @:t ::t |:t ^:nil _:nil -:t f:t *:t <:t +#+PROPERTY: header-args :exports code +#+PROPERTY: header-args+ :noweb yes +#+PROPERTY: header-args+ :eval no +#+PROPERTY: header-args+ :results no +#+PROPERTY: header-args+ :cache no +#+PROPERTY: header-args+ :padline no + +* ao.rb +** ao.rb + +#+BEGIN_SRC ruby :tangle "../lib/sisu/ao.rb" +# <> +module SiSU_AO + require_relative 'se' # se.rb + include SiSU_Env + require_relative 'dp' # dp.rb + include SiSU_Param + require_relative 'ao_doc_objects' # ao_doc_objects.rb + require_relative 'ao_syntax' # ao_syntax.rb + include SiSU_AO_Syntax + require_relative 'ao_doc_str' # ao_doc_str.rb + require_relative 'ao_appendices' # ao_appendices.rb + require_relative 'ao_idx' # ao_idx.rb + require_relative 'ao_numbering' # ao_numbering.rb + require_relative 'ao_hash_digest' # ao_hash_digest.rb + require_relative 'ao_endnotes' # ao_endnotes.rb + require_relative 'ao_images' # ao_images.rb + require_relative 'ao_metadata' # ao_metadata.rb + require_relative 'ao_character_check' # ao_character_check.rb + require_relative 'ao_misc_arrange' # ao_misc_arrange.rb + require_relative 'ao_expand_insertions' # ao_expand_insertions.rb + require_relative 'ao_persist' # ao_persist.rb + require_relative 'prog_text_translation' # prog_text_translation.rb + require_relative 'shared_sem' # shared_sem.rb + class Instantiate < SiSU_Param::Parameters::Instructions + def initialize + @@flag_vocab=0 + @@line_mode='' + end + end + class Source #{cf.meta}" + ).txt_grey + end + end + ao.each {|s| ao_array << s} + if @opt.act[:maintenance][:set]==:on + ao_array.each do |obj| + if defined? obj.parent + if defined? obj.ln + if defined? obj.node + puts %{#{obj.ln}: #{obj.ocn} : #{obj.parent} : #{obj.node} - #{obj.lc}} + else + puts %{#{obj.ln}: #{obj.ocn} : #{obj.parent}} + end + else + if defined? obj.node + puts %{ #{obj.ocn} : #{obj.parent} : #{obj.node} - #{obj.lc}} + else + puts %{ #{obj.ocn} : #{obj.parent}} + end + end + end + end + end + ao_array + end + def read_fnm + ao=[] + ao=(FileTest.file?(@fnm)) \ + ? (File.open(@fnm,'r:utf-8'){ |f| ao=Marshal.load(f)}) + : SiSU_AO::Source.new(@opt).create_ao + end + def read_fnc + ao=[] + ao=(FileTest.file?(@fnc)) \ + ? (File.open(@fnc,'r:utf-8'){ |f| ao=Marshal.load(f)}) + : SiSU_AO::Source.new(@opt,@fnx,@process).create_ao + end + def read_idx_sst + m=[] + m=(FileTest.file?(@idx_sst)) \ + ? (File.open(@idx_sst,'r:utf-8'){ |f| m=Marshal.load(f)}) + : nil + end + def read_idx_raw + m=[] + m=(FileTest.file?(@idx_raw)) \ + ? (File.open(@idx_raw,'r:utf-8'){ |f| m=Marshal.load(f)}) + : nil + end + def read_idx_html + m=[] + m=(FileTest.file?(@idx_html)) \ + ? (File.open(@idx_html,'r:utf-8'){ |f| m=Marshal.load(f)}) + : nil + end + def read_idx_xhtml + m=[] + m=(FileTest.file?(@idx_xhtml)) \ + ? (File.open(@idx_xhtml,'r:utf-8'){ |f| m=Marshal.load(f)}) + : nil + end + def read_map_nametags + m=[] + m=(FileTest.file?(@map_nametags)) \ + ? (File.open(@map_nametags,'r:utf-8'){ |f| m=Marshal.load(f)}) + : nil + end + def read_map_ocn_htmlseg + m=[] + m=(FileTest.file?(@map_ocn_htmlseg)) \ + ? (File.open(@map_ocn_htmlseg,'r:utf-8'){ |f| m=Marshal.load(f)}) + : nil + end + end + class Output + def initialize(fn,md,data) + @fn,@md,@data=fn,md,data + @cf=SiSU_Env::CreateFile.new(@fn) + @make=SiSU_Env::InfoFile.new(@fn) + @dir=SiSU_Env::InfoEnv.new(@fn) + end + def screen_dump(o) + if defined? o.of + print %{OF: #{o.of}; } + end + if defined? o.is + print %{IS: #{o.is.to_s}; } + end + if defined? o.ocn + print %{OCN: #{o.ocn}; } + end + if defined? o.node + print %{NODE: #{o.node}; } + end + if defined? o.parent + print %{Parent: #{o.parent}; } + end + if defined? o.obj and not o.obj.empty? + puts %{\n#{o.obj}; } + else "\n" + end + end + def screen_print(t_o) + if defined? t_o + print ' ' + t_o.to_s + end + end + def screen_output(data) + data.each do |o| + print o.class + screen_print(o.ocn) + screen_print(o.obj) + puts "\n" + end + end + def hard_output + if @md.opt.act[:maintenance][:set]==:on + filename_meta=@cf.metaverse.file_meta + @data.each {|o| filename_meta.puts o.inspect.sub(/:0x[0-9a-f]{8}\s/,': ')} #to make diffing easier + filename_txt=@cf.metaverse.file_txt + @data.each do |o| + if defined? o.ocn + filename_txt.puts case o.is + when :heading + "[#{o.is.to_s} #{o.lv}~#{o.name} [#{o.ocn}]] #{o.obj}" + else "[#{o.is.to_s} [#{o.ocn}]] #{o.obj}" + end + else + filename_txt.puts case o.is + when :meta + "[m~#{o.tag}] #{o.obj}" + else "[#{o.is.to_s}] #{o.obj}" + end + end + end + filename_debug=@cf.file_debug + @data.each do |o| + if defined? o.ocn + case o.is + when :heading + filename_debug.puts + "#{o.is.to_s} #{o.lv}~#{o.name} odv=#{o.odv} osp=#{o.osp} [#{o.ocn}] -->\n\t#{o.obj}" + end + end + end + else + hard="#{@dir.processing_path.ao}/#{@md.fns}.meta" + File.unlink(hard) if FileTest.file?(hard) + hard="#{@dir.processing_path.ao}/#{@md.fns}.txt" + File.unlink(hard) if FileTest.file?(hard) + hard="#{@dir.processing_path.ao}/#{@md.fns}.debug.txt" + File.unlink(hard) if FileTest.file?(hard) + end + end + def make_marshal_content + marshal_ao=@make.marshal.ao_content + File.open(marshal_ao,'w'){|f| Marshal.dump(@data,f)} if @data.is_a?(Array) + end + def make_marshal_metadata + marshal_ao=@make.marshal.ao_metadata + File.open(marshal_ao,'w'){|f| Marshal.dump(@data,f)} if @data.is_a?(Array) + end + def idx_html_hard_output + if @md.book_idx \ + and @md.opt.act[:maintenance][:set]==:on + filename_meta=@cf.file_meta_idx_html + if @data.is_a?(Array) + @data.each {|s| p s.inspect + "\n" unless s.is_a?(String)} + @data.each {|s| filename_meta.puts s.strip + "\n" unless s.strip.empty?} + end + else + hard_idx_html="#{@dir.processing_path.ao}/#{@md.fns}.idx.html" + File.unlink(hard_idx_html) if FileTest.file?(hard_idx_html) + end + end + def make_marshal_idx_sst_html_seg + marshal_ao=@make.marshal.ao_idx_sst_rel_html_seg + File.open(marshal_ao,'w'){|f| Marshal.dump(@data,f)} \ + if @data.is_a?(Array) + end + def make_marshal_idx_sst_rel + marshal_ao=@make.marshal.ao_idx_sst_rel + File.open(marshal_ao,'w'){|f| Marshal.dump(@data,f)} \ + if @data.is_a?(Array) + end + def make_marshal_idx_html + marshal_ao=@make.marshal.ao_idx_html + File.open(marshal_ao,'w'){|f| Marshal.dump(@data,f)} \ + if @data.is_a?(Array) + end + def make_marshal_idx_xhtml + marshal_ao=@make.marshal.ao_idx_xhtml + File.open(marshal_ao,'w'){|f| Marshal.dump(@data,f)} \ + if @data.is_a?(Array) + end + def make_marshal_map_nametags + marshal_ao=@make.marshal.ao_map_nametags + File.open(marshal_ao,'w'){|f| Marshal.dump(@data,f)} \ + if @data.is_a?(Hash) + end + def make_marshal_map_name_ocn_htmlseg + marshal_ao=@make.marshal.ao_map_ocn_htmlseg + File.open(marshal_ao,'w'){|f| Marshal.dump(@data,f)} \ + if @data.is_a?(Hash) + end + end + class Make + def initialize(fn,md,data,fnx,process) + @fn,@md,@data,@fnx,@process=fn,md,data,fnx,process + @env=SiSU_Env::InfoEnv.new(@md.fns) + end + def reset + @@flag_vocab=0 + @@line_mode='' + end + def song + reset + data_txt=@data + data_txt= + SiSU_AO_Insertions::Insertions.new(@md,data_txt). # ao_expand_insertions.rb + expand_insertions? + data_txt= + SiSU_AO_MiscArrangeText::SI.new(@md,data_txt). # ao_misc_arrange.rb + prepare_text + data_obj, + metadata, + bibliography= + SiSU_AO_DocumentStructureExtract::Build.new(@md,data_txt). # ao_doc_str.rb + identify_parts + data_obj= + SiSU_AO_Syntax::Markup.new(@md,data_obj,bibliography).songsheet # ao_syntax.rb + data_obj, + endnote_array= + SiSU_AO_CharacterCheck::Check.new(data_obj). # ao_character_check.rb + character_check_and_oldstyle_endnote_array + data_obj= + SiSU_AO_Images::Images.new(@md,data_obj).images # ao_images.rb + data_obj, + tags_map, + ocn_html_seg_map= + SiSU_AO_Numbering::Numbering.new(@md,data_obj,@fnx,@process). # ao_numbering.rb + numbering_song + data_obj, + book_index_rel, + book_index_rel_html_seg, + html_idx, + xhtml_idx= + SiSU_AO_BookIndex::BookIndex.new(@md,data_obj,@env). # ao_idx.rb + indexing_song if @md.book_idx + data_obj= + SiSU_AO_Endnotes::Endnotes.new(@md,data_obj,endnote_array). # ao_endnotes.rb + endnotes + outputdata=data_obj + if (@md.opt.act[:ao][:set]==:on \ + || @md.opt.act[:maintenance][:set]==:on) + SiSU_AO::Output.new(@fn,@md,outputdata).hard_output + SiSU_AO::Output.new(@fn,@md,outputdata).make_marshal_content + SiSU_AO::Output.new(@fn,@md,metadata).make_marshal_metadata + SiSU_AO::Output.new(@fn,@md,html_idx).idx_html_hard_output + SiSU_AO::Output.new(@fn,@md,book_index_rel_html_seg).make_marshal_idx_sst_html_seg + SiSU_AO::Output.new(@fn,@md,book_index_rel).make_marshal_idx_sst_rel + SiSU_AO::Output.new(@fn,@md,html_idx).make_marshal_idx_html + SiSU_AO::Output.new(@fn,@md,xhtml_idx).make_marshal_idx_xhtml + SiSU_AO::Output.new(@fn,@md,tags_map).make_marshal_map_nametags + SiSU_AO::Output.new(@fn,@md,ocn_html_seg_map).make_marshal_map_name_ocn_htmlseg + end + reset + outputdata + end + protected + end +end +__END__ +#+END_SRC + +** ao_appendices.rb + +#+BEGIN_SRC ruby :tangle "../lib/sisu/ao_appendices.rb" +# <> +module SiSU_AO_Appendices + class Glossary + def initialize(md,data) + @md,@data=md,data + end + def glossary_extraction + glossary=[] + glossaryflag=false + code_flag=false + flag_code_curly=:not_code_curly + flag_code_tics=:not_code_tics + @data=@data.select do |t_o| + if t_o =~/^code\{/ + flag_code_curly=:code_curly + elsif t_o =~/^\}code/ + flag_code_curly=:not_code_curly + elsif t_o =~/^``` code/ + flag_code_tics=:code_tics + elsif flag_code_tics ==:code_tics \ + and t_o =~/^```/ + flag_code_tics=:not_code_tics + end + code_flag=if flag_code_curly==:code_curly \ + or flag_code_tics==:code_tics + true + else false + end + unless code_flag + if @md.flag_glossary + if t_o =~/^1~!glossary/ + glossaryflag = true + next + elsif t_o =~/^:?[B-D]~/ + next + elsif t_o =~/^:?[B-D1]~/ + glossaryflag = false + t_o + elsif glossaryflag + if t_o !~/\A%+ / + glossary << t_o + next + else + t_o + end + else t_o + end + else t_o + end + else t_o + end + end.compact + [@data,glossary] + end + end + class Bibliography + def initialize(md,data) + @md,@data=md,data + end + def sort_bibliography_array_by_deemed_author_year_title(bib) + if bib + bib.compact.sort_by do |c| + [c[:deemed_author],c[:ymd],c[:title]] + end + end + end + def citation_in_prepared_bibliography(cite) + @cite=cite + def generic + { + is: nil, # :book, :article, :magazine, :newspaper, :blog, :other + author_raw: nil, + author: nil, + author_arr: nil, + editor_raw: nil, + editor: nil, + editor_arr: nil, + title: nil, + subtitle: nil, + fulltitle: nil, + language: nil, + trans: nil, + src: nil, + journal: nil, + in: nil, + volume: nil, + edition: nil, + year: nil, + place: nil, + publisher: nil, + url: nil, + pages: nil, + note: nil, + #format: nil, #consider list of fields arranged with markup + short_name: nil, + id: nil, + } + end + def citation_metadata + type=:generic + if type + citation=generic + citeblock=@cite.split("\n") + citeblock.select do |meta| + case meta + when /^((?:au|author):\s+)\S+/ #req + citation[:author_raw]=/^#{$1}(.+)/.match(meta)[1] + when /^((?:ti|title):\s+)\S+/ #req + citation[:title]=/^#{$1}(.+)/.match(meta)[1] + when /^((?:st|subtitle):\s+)\S+/ + citation[:subtitle]=/^#{$1}(.+)/.match(meta)[1] + when /^((?:lng|language):\s+)\S+/ + citation[:language]=/^#{$1}(.+)/.match(meta)[1] + when /^((?:edr?|editor):\s+)\S+/ + citation[:editor_raw]=/^#{$1}(.+)/.match(meta)[1] + when /^((?:tr|trans(:?lator)?):\s+)\S+/ + citation[:editor_raw]=/^#{$1}(.+)/.match(meta)[1] + when /^((?:pb|publisher):\s+)\S+/ + citation[:publisher]=/^#{$1}(.+)/.match(meta)[1] + when /^((?:edn|edition):\s+)\S+/ + citation[:edition]=/^#{$1}(.+)/.match(meta)[1] + when /^((?:yr|year):\s+)\S+/ #req? + citation[:year]=/^#{$1}(.+)/.match(meta)[1] + when /^((?:pl|publisher_state):\s+)\S+/ + citation[:place]=/^#{$1}(.+)/.match(meta)[1] + when /^((?:jo|journal):\s+)\S+/ #req? + citation[:journal]=/^#{$1}(.+)/.match(meta)[1] + when /^((?:vol?|volume):\s+)\S+/ + citation[:volume]=/^#{$1}(.+)/.match(meta)[1] + when /^((?:in):\s+)\S+/ + citation[:in]=/^#{$1}(.+)/.match(meta)[1] + when /^((?:src):\s+)\S+/ + citation[:src]=/^#{$1}(.+)/.match(meta)[1] + when /^((?:pg|pages?):\s+)\S+/ + citation[:pages]=/^#{$1}(.+)/.match(meta)[1] + when /^(url:\s+)\S+/ + citation[:url]=/^#{$1}(.+)/.match(meta)[1] + when /^(note:\s+)\S+/ + citation[:note]=/^#{$1}(.+)/.match(meta)[1] + when /^((?:sn|shortname):\s+)\S+/ # substitution: (/#{id}/,"#{sn}") + citation[:short_name]=/^#{$1}(.+)/.match(meta)[1] + when /^(id:\s+)\S+/ # substitution: (/#{id}/,"#{sn}") + citation[:id]=/^#{$1}(.+)/.match(meta)[1] + end + end + if citation[:subtitle] + citation[:fulltitle] = citation[:title] \ + + ' - ' \ + + citation[:subtitle] + else + citation[:fulltitle] = citation[:title] + end + if citation[:author_raw] + citation[:author_arr]=citation[:author_raw].split(/;\s*/) + citation[:author]=citation[:author_arr].map do |author| + author.gsub(/(.+?),\s+(.+)/,'\2 \1').strip + end.join(', ').strip + end + if citation[:editor_raw] + citation[:editor_arr]=citation[:editor_raw].split(/;\s*/) + citation[:editor]=citation[:editor_arr].map do |editor| + editor.gsub(/(.+?),\s+(.+)/,'\2 \1').strip + end.join(', ').strip + end + citation[:ymd]=if not citation[:year] =~/^[0-9]{4}/ + '9999' + else citation[:year] + end + citation[:deemed_author]=if not citation[:author_raw] \ + and citation[:editor_raw] + citation[:editor_arr][0] + elsif citation[:author_raw] + citation[:author_arr][0] + else + SiSU_Utils::CodeMarker.new(__LINE__,__FILE__,:fuchsia). + warn('Citation needs an author or editor, title: "' \ + + citation[:title] + '"') + '000' + end + unless citation[:short_name] + citation[:short_name]=%{#{citation[:author]}, "#{citation[:title]}" (#{citation[:date]})} + end + end + citation + end + self + end + def biblio_format + def generic(c) + cite=%{#{c[:author]}. /{"#{c[:fulltitle]}".}/} + cite=(c[:journal]) \ + ? cite + %{ #{c[:journal]},} + : cite + cite=(c[:source]) \ + ? cite + %{ #{c[:source]},} + : cite + cite=(c[:in]) \ + ? cite + %{ in #{c[:in]},} + : cite + cite=(c[:volume]) \ + ? cite + %{ #{c[:volume]},} + : cite + cite=(c[:trans]) \ + ? cite + %{ trans. #{c[:trans]},} + : cite + cite=(c[:editor]) \ + ? cite + %{ ed. #{c[:editor]},} + : cite + cite=(c[:place]) \ + ? cite + %{ #{c[:place]},} + : cite + cite=(c[:publisher]) \ + ? cite + %{ #{c[:publisher]},} + : cite + cite=(c[:year]) \ + ? cite + %{ (#{c[:year]})} + : cite + cite=(c[:pages]) \ + ? cite + %{ #{c[:pages]}} + : cite + cite=(c[:url]) \ + ? cite + %{ #{c[:url]}} + : cite + cite=(c[:note]) \ + ? cite + %{ #{c[:note]}} + : cite + cite + end + def generic_editor(c) + cite=%{#{c[:editor]} ed. /{"#{c[:fulltitle]}".}/} + cite=(c[:journal]) \ + ? cite + %{ #{c[:journal]}, } + : cite + cite=(c[:source]) \ + ? cite + %{ #{c[:source]}, } + : cite + cite=(c[:in]) \ + ? cite + %{ in #{c[:in]},} + : cite + cite=(c[:volume]) \ + ? cite + %{ #{c[:volume]},} + : cite + cite=(c[:trans]) \ + ? cite + %{ trans. #{c[:trans]},} + : cite + cite=(c[:place]) \ + ? cite + %{ #{c[:place]},} + : cite + cite=(c[:publisher]) \ + ? cite + %{ #{c[:publisher]}} + : cite + cite=(c[:year]) \ + ? cite + %{ (#{c[:year]})} + : cite + cite=(c[:pages]) \ + ? cite + %{ #{c[:pages]}} + : cite + cite=(c[:url]) \ + ? cite + %{ #{c[:url]}} + : cite + cite=(c[:note]) \ + ? cite + %{ #{c[:note]}} + : cite + cite + end + self + end + def biblio_make(cite) + if cite[:author] + biblio_format.generic(cite) + elsif cite[:editor] + biblio_format.generic_editor(cite) + else + biblio_format.generic(cite) + end + end + def biblio_extraction + bibliography=[] + biblioflag=false + code_flag=false + flag_code_curly=:not_code_curly + flag_code_tics=:not_code_tics + @data=@data.select do |t_o| + if t_o =~/^code\{/ + flag_code_curly=:code_curly + elsif t_o =~/^\}code/ + flag_code_curly=:not_code_curly + elsif t_o =~/^``` code/ + flag_code_tics=:code_tics + elsif flag_code_tics ==:code_tics \ + and t_o =~/^```/ + flag_code_tics=:not_code_tics + end + code_flag=if flag_code_curly==:code_curly \ + or flag_code_tics==:code_tics + true + else false + end + unless code_flag + if @md.flag_auto_biblio + if t_o =~/^1~!biblio(?:graphy)?/ + biblioflag = true + t_o + elsif t_o =~/^:?[B-D1]~/ + biblioflag = false + t_o + elsif biblioflag + if t_o !~/\A%+ / + bibliography << citation_in_prepared_bibliography(t_o).citation_metadata + next + else + t_o + end + else t_o + end + elsif @md.flag_biblio + if t_o =~/^1~!biblio(?:graphy)?/ + biblioflag = true + next + elsif t_o =~/^:?[B-D]~/ + next + elsif t_o =~/^:?[B-D1]~/ + biblioflag = false + t_o + elsif biblioflag + if t_o !~/\A%+ / + bibliography << t_o + next + else + t_o + end + else t_o + end + else t_o + end + else t_o + end + end.compact + if @md.flag_auto_biblio \ + and bibliography.length > 0 + data_new=[] + bib=sort_bibliography_array_by_deemed_author_year_title(bibliography) + biblio_done=[] + @data.select do |t_o| + if t_o =~/^1~!biblio(?:graphy)?/ + bib.each do |c| + d=c + d.store(:obj, biblio_make(c)) + biblio_done << d + #biblio_done << { obj: biblio_make(c), id: c[:id] } + end + else data_new << t_o + end + end + @data=data_new + end + [@data,biblio_done] + end + end + class Citations + def initialize(md='',data='') + @md,@data=md,data + #@biblio=[] + end + def songsheet + tuned_file,citations=citations_scan(@data) + [tuned_file,citations] + end + def sort_bibliography_array_by_author_year(bib) + bib.sort_by do |c| + [c[:author_raw],c[:year]] + #[c[:author_arr][0],c[:year],c[:title]] + end + end + def citations_regex + def pages_pattern + %r{(?:[,.:]?\s+(?:p{1,2}\.?\s+)?(?:\d+--?\d+)[,.]?\s+)?} + end + def editor_pattern + %r{(?(?:editor|edited by)\s+.+?)} + end + def year_pattern + %r{[(\[]?(?\d{4})[\])]?[.,]?} + end + def authors_year_title_publication_editor_pages + /(?.+?)\s+#{year_pattern}\s+"(?.+?)"\s+(?:#{Mx[:fa_italics_o]}|#{Mx[:srcrgx_italics_o]})(?<publication>.+?)(?:#{Mx[:fa_italics_c]}|#{Mx[:srcrgx_italics_c]})\s+#{editor_pattern}#{pages_pattern}/m # note ed. is usually edition rather than editor + end + def authors_title_publication_year_editor_pages + /(?<authors>.+?)\s+"(?<title>.+?)"\s+(?:#{Mx[:fa_italics_o]}|#{Mx[:srcrgx_italics_o]})(?<publication>.+?)(?:#{Mx[:fa_italics_c]}|#{Mx[:srcrgx_italics_c]})\s+#{year_pattern}\s+#{editor_pattern}#{pages_pattern}/m # note ed. is usually edition rather than editor + end + def authors_title_publication_editor_year_pages ### + /(?<authors>.+?)\s+"(?<title>.+?)"\s+(?:#{Mx[:fa_italics_o]}|#{Mx[:srcrgx_italics_o]})(?<publication>.+?)(?:#{Mx[:fa_italics_c]}|#{Mx[:srcrgx_italics_c]})\s+ed.\s+#{editor_pattern}#{year_pattern}#{pages_pattern}/m + # note ed. is usually edition rather than editor + end + def authors_title_publication_editor_pages_year ### + /(?<authors>.+?)\s+"(?<title>.+?)"\s+(?:#{Mx[:fa_italics_o]}|#{Mx[:srcrgx_italics_o]})(?<publication>.+?)(?:#{Mx[:fa_italics_c]}|#{Mx[:srcrgx_italics_c]})\s+#{editor_pattern}#{pages_pattern}#{year_pattern}/m # note ed. is usually edition rather than editor + end + def authors_year_title_publication_pages + /(?<authors>.+?)\s+#{year_pattern}\s+"(?<title>.+?)"\s+(?:#{Mx[:fa_italics_o]}|#{Mx[:srcrgx_italics_o]})(?<publication>.+?)(?:#{Mx[:fa_italics_c]}|#{Mx[:srcrgx_italics_c]})[,.;]?#{pages_pattern}/m + end + def authors_title_publication_year_pages + /(?<authors>.+?)\s+"(?<title>.+?)"\s+(?:#{Mx[:fa_italics_o]}|#{Mx[:srcrgx_italics_o]})(?<publication>.+?)(?:#{Mx[:fa_italics_c]}|#{Mx[:srcrgx_italics_c]})\s+#{year_pattern}\s+#{pages_pattern}/m + end + def authors_title_publication_pages_year ### + /(?<authors>.+?)\s+"(?<title>.+?)"\s+(?:#{Mx[:fa_italics_o]}|#{Mx[:srcrgx_italics_o]})(?<publication>.+?)(?:#{Mx[:fa_italics_c]}|#{Mx[:srcrgx_italics_c]})#{pages_pattern}#{year_pattern}/m + end + def authors_year_publication_pages + /(?<authors>.+?)\s+#{year_pattern}\s+(?:#{Mx[:fa_italics_o]}|#{Mx[:srcrgx_italics_o]})(?<publication>.+?)(?:#{Mx[:fa_italics_c]}|#{Mx[:srcrgx_italics_c]})#{pages_pattern}/m + end + def authors_publication_year_pages + /(?<authors>.+?)\s+(?:#{Mx[:fa_italics_o]}|#{Mx[:srcrgx_italics_o]})(?<publication>.+?)(?:#{Mx[:fa_italics_c]}|#{Mx[:srcrgx_italics_c]})[,.;]?\s+(?<publisher>.+?)?#{year_pattern}#{pages_pattern}[.;]?/m + end + self + end + def authors?(citations) + citations.each.map do |b| + if b =~ /^.+\s+::.+?:$/ + c=/^(?<citation>.+?)\s+::(?<shortref>.+?):$/.match(b) + { + citation: c[:citation], + shortref: c[:shortref], + c[:shortref].to_s => c[:citation] + } + else { citation: b } + end + end + end + def long_and_short_ref?(citations) #could be useful, keep ... ectract shortref + citations.each.map do |b| + if b =~ /^.+\s+::.+?:$/ + c=/^(?<citation>.+?)\s+::(?<shortref>.+?):$/.match(b) + { + citation: c[:citation], + shortref: c[:shortref], + c[:shortref].to_s => c[:citation] + } + else { citation: b } + end + end + end + def citation_detail(citations) #could be useful, keep ... extract shortref + bibahash=[] + number=0 + missed=0 + citations.select do |b| + z=if b =~citations_regex.authors_year_title_publication_editor_pages + c=citations_regex.authors_year_title_publication_editor_pages.match(b) + { + is: :article, + author_raw: c[:authors], + year: c[:year], + title: c[:title], + publication: c[:publication], + editor: c[:editor], + } + elsif b =~citations_regex.authors_title_publication_year_editor_pages + c=citations_regex.authors_title_publication_year_editor_pages.match(b) + { + is: :article, + author_raw: c[:authors], + year: c[:year], + title: c[:title], + publication: c[:publication], + editor: c[:editor], + } + elsif b =~citations_regex.authors_title_publication_editor_year_pages + c=citations_regex.authors_title_publication_editor_year_pages.match(b) + { + is: :article, + author_raw: c[:authors], + year: c[:year], + title: c[:title], + publication: c[:publication], + editor: c[:editor], + } + elsif b =~citations_regex.authors_title_publication_editor_pages_year + c=citations_regex.authors_title_publication_editor_pages_year.match(b) + { + is: :article, + author_raw: c[:authors], + year: c[:year], + title: c[:title], + publication: c[:publication], + editor: c[:editor], + } + elsif b =~citations_regex.authors_year_title_publication_pages + c=citations_regex.authors_year_title_publication_pages.match(b) + { + is: :article, + author_raw: c[:authors], + year: c[:year], + title: c[:title], + publication: c[:publication], + } + elsif b =~citations_regex.authors_title_publication_year_pages + c=citations_regex.authors_title_publication_year_pages.match(b) + { + is: :article, + author_raw: c[:authors], + year: c[:year], + title: c[:title], + publication: c[:publication], + } + elsif b =~citations_regex.authors_year_publication_pages + c=citations_regex.authors_year_publication_pages.match(b) + { + is: :book, + author_raw: c[:authors], + year: c[:year], + publication: c[:publication], + } + elsif b =~citations_regex.authors_publication_year_pages + c=citations_regex.authors_publication_year_pages.match(b) + { + is: :book, + author_raw: c[:authors], + year: c[:year], + publication: c[:publication], + } + else b + end + if not z.is_a?(NilClass) \ + and z.is_a?(Hash) \ + and z[:author_raw].length > 0 + z[:author_arr]=z[:author_raw].split(/;\s*/) + z[:author]=z[:author_arr].map do |author| + author.gsub(/(.+?),\s+(.+)/,'\2 \1').strip + end.join(', ').strip + if @md.opt.act[:verbose_plus][:set]==:on \ + || @md.opt.act[:maintenance][:set]==:on + number +=1 if z.is_a?(Hash) + missed +=1 if z.is_a?(String) + (z.is_a?(Hash)) \ + ? (p '[' + number.to_s + '] ' + z.to_s) + : (p '<' + missed.to_s + '> ' + z.to_s) + end + end + bibahash << z if z.is_a?(Hash) + end + bibahash=sort_bibliography_array_by_author_year(bibahash.compact) + bibahash + end + def citations_scan(data) + citations=[] + #short_ref=[] + tuned_file = data.compact.select do |dob| + if dob.is !=:meta \ + && dob.is !=:comment \ + && dob.is !=:code \ + && dob.is !=:table + if dob.obj =~/\.:.+?:\./ + citations << dob.obj.scan(/\.:\s*(.+?)\s*:\./m) + #short_ref << dob.obj.scan(/\.:\s+(.+?)\s+::([^:]+)::\./m) #look at later + ##short_ref << dob.obj.scan(/\.:\s+(.+?)\s+::(.+?)::\./m) #look at later + #short_ref << dob.obj.scan(/\.:\s*(.+?)\s*(::(.+?):)?:\./m) #look at later + citations=citations.flatten.compact + dob.obj=dob.obj. #remove citations delimiter & helpers from text + gsub(/\.:|:\./,'') + end + end + dob if dob.is_a?(Object) + end + #bib=long_and_short_ref?(citations) #could be useful, keep ... extract shortref + citations=citation_detail(citations) + [tuned_file,citations] + end + end +end +__END__ +#+END_SRC + +** ao_character_check.rb + +#+BEGIN_SRC ruby :tangle "../lib/sisu/ao_character_check.rb" +# <<sisu_document_header>> +module SiSU_AO_CharacterCheck + class Check + def initialize(data) + @data=data + @comment='%' + @endnote_array=[] + end + def character_check_and_oldstyle_endnote_array + data=@data + @endnote_array=[] + endnote_no=1 + @tuned_file=data.select do |dob| + unless dob.is ==:table + dob.obj=dob.obj.strip. + gsub(/^[{~}]\s*$/,''). + gsub(/~#\s*/,"#{Mx[:pa_non_object_no_heading]}"). + gsub(/-#\s*/,"#{Mx[:pa_non_object_dummy_heading]}"). + gsub(/(#{Mx[:en_a_o]})\s*\s+/,'\1 '). + gsub(/(~\{\s*)\s+/,'\1 '). + gsub(/ \/\//,"#{Mx[:br_line]}"). + gsub(/<br>/,"#{Mx[:br_line]}"). #needed by xml, xhtml etc. + gsub(/\t/,' '). + gsub(/\342\200\231/u,"'"). #if dob =~/’/ #Avoid #‘ ’ #“ ” + gsub(/\\copy(?:right)?\b/,'©'). + gsub(/\\trademark\b|\\tm\b/,'®') + dob.obj=dob.obj + "\n" + unless dob.is ==:code + case dob.obj + when /\^~/ #% Note must do this first (earlier loop) and then enter gathered data into ~^\d+ + sub_dob=dob.obj.dup + @endnote_array << sub_dob.gsub(/\n/,''). + gsub(/\^~\s+(.+)\s*/, + %{#{Mx[:en_a_o]}#{endnote_no} \\1 #{Mx[:en_a_c]}}). + strip + endnote_no+=1 + dob=nil if dob.obj =~/\^~ .+/ #watch, removes 'binary' endnote now in endnote array for later insertion + end + end + end + dob if dob.is_a?(Object) + end.flatten.compact + [@tuned_file,@endnote_array] + end + end +end +#+END_SRC + +** ao_composite.rb + +#+BEGIN_SRC ruby :tangle "../lib/sisu/ao_composite.rb" +# <<sisu_document_header>> +module SiSU_Assemble + require_relative 'se' # se.rb + require_relative 'utils_composite' # utils_composite.rb + class RemoteImage + def initialize + @env=SiSU_Env::InfoEnv.new + end + def image(dir) + images=[] + images[0]=dir + images + end + def download_images(images_info) + path="#{@env.processing_path.processing}/external_document/image" + FileUtils::mkdir_p(path) \ + unless FileTest.directory?(path) + download_from=images_info.shift + images_info.each do |i| + image="#{path}/#{i}" + imagefile=File.new(image,'w+') + open("#{download_from}/#{i}") do |g| + imagefile << g.read + end + imagefile.close + end + output_path="#{@env.path.webserv}/#{@env.path.base_markup_dir_stub}/_sisu/image_external" + FileUtils::mkdir_p(output_path) \ + unless FileTest.directory?(output_path) + SiSU_Env::SystemCall.new("#{path}/*",output_path,'q').rsync + end + end + class Composite + include SiSU_Composite_Doc_Utils # composite doc, .ssm, extract all related insert files, array of filenames test + def initialize(opt) + @opt=opt + @env=SiSU_Env::InfoEnv.new + end + def read + begin + pwd=Dir.pwd + Dir.chdir(@opt.f_pth[:pth]) + if @opt.fno =~/\S+?\.ssm$/ + SiSU_Screen::Ansi.new( + @opt.act[:color_state][:set], + 'Composite Document', + "[#{@opt.f_pth[:lng_is]}] #{@opt.fno}", + ).grey_title_hi unless @opt.act[:quiet][:set]==:on + composite_and_imported_filenames_array(@opt.fno) # composite doc, .ssm, extract all related insert files, array of filenames test + assembled=loadfile(@opt.fno) + write(assembled) + end + Dir.chdir(pwd) + rescue + SiSU_Errors::Rescued.new($!,$@,@opt.selections.str,@opt.fns). + location do + __LINE__.to_s + ':' + __FILE__ + end + ensure + end + end + def insert?(para) + if para =~ /^<<\s+((?:https?|file):\/\/\S+?\.ss[it])$/ # and NetTest + url($1.strip) + elsif para =~/^<<\s+(\S+?\.ss[it])$/ + loadfilename=$1.strip + insert_array=loadfile(loadfilename) + file=insertion(loadfilename,insert_array) + file[:prepared] + else para + end + end + def loadfile(loadfilename) + begin + if FileTest.file?(loadfilename) + insert_array=IO.readlines(loadfilename,'') + if loadfilename =~/\S+?\.ss[itm]$/ + if (@opt.act[:verbose][:set]==:on \ + || @opt.act[:verbose_plus][:set]==:on \ + || @opt.act[:maintenance][:set]==:on) + SiSU_Screen::Ansi.new( + @opt.act[:color_state][:set], + 'loading:', + loadfilename, + ).txt_grey + end + tuned_file=if loadfilename =~/\S+?\.ss[im]$/ + insert_array.each.map do |para| + insert?(para) + end + elsif loadfilename =~/\S+?\.sst$/ + insert_array.each.map do |para| + para + end + end.flatten.compact + end + end + rescue + SiSU_Errors::Rescued.new($!,$@,@opt.selections.str,@opt.fns).location do + __LINE__.to_s + ':' + __FILE__ + end + ensure + end + end + def url(loadfilename) + if loadfilename =~ /((?:https?|file):\/\/\S+?\.ss[it])$/ # and NetTest + loadfilename=$1 + begin + require 'uri' + require 'open-uri' + require 'pp' + rescue LoadError + SiSU_Utils::CodeMarker.new(__LINE__,__FILE__,:fuchsia). + error('uri, open-uri or pp NOT FOUND (LoadError)') + end + insert=open(loadfilename) + insert_array=insert.dup + insert.close + file=insertion(loadfilename,insert_array) + file[:prepared] + end + end + def write(assembled) + assembled_file=File.new("#{@env.processing_path.composite_file}/#{@opt.fnb}.ssm.sst",'w+') + assembled.each {|a| assembled_file << a } + assembled_file.close + end + def download_images(download_from,images_array) + path="#{@env.processing_path.processing}/external_document/image" + FileUtils::mkdir_p(path) unless FileTest.directory?(path) + images_array.each do |i| + image="#{path}/#{i}" + unless FileTest.exists?(image) + imagefile=File.new(image,'w+') + open("#{download_from}/#{i}") do |g| + imagefile << g.read + end + imagefile.close + end + end + end + def insertion(fni,insert_array) + file={ prepared: [], images: [] } + rgx_image=/(?:^|[^_\\])\{\s*(\S+?\.(?:png|jpg|gif))/ + file[:prepared] << "\n% |#{fni}|@|^|>>ok\n\n" + @code_flag=false + insert_array.each do |i| + @code_flag=if i =~/^code\{/ then true + elsif i =~/^\}code/ then false + else @code_flag + end + if not @code_flag \ + and i !~/^%+\s/ + i=i. + gsub(/^([123]|:?[ABCD])~\? /, + '% [conditional heading:] \1~ ') #off conditional heading (consider syntax) + if i =~/^@\S+?:/ + i=i.gsub(/\n/m,"\n% "). + gsub(/\n%\s+$/m,''). + gsub(/^@\S+?:/m,"\n% [imported header:] ") #off imported headers + end + end + file[:prepared] << i + if i !~/^%+\s/ \ + and i =~rgx_image + file[:images] << i.scan(rgx_image).uniq + end + end + file[:prepared] << "\n% end import" << "\n\n" + if file[:images].length > 0 + file[:images]=file[:images].flatten.uniq + file[:images].delete_if {|x| x =~/https?:\/\// } + end + file + end + end + class CompositeFileList + def initialize(opt) + @opt=opt + @env=SiSU_Env::InfoEnv.new + end + def read + begin + @opt.fns=@opt.fns.gsub(/\.ssm\.sst$/,'.ssm') #FIX earlier, hub + fns_array=IO.readlines(@opt.fns,'') + insertions?(fns_array) + rescue + SiSU_Errors::Rescued.new($!,$@,@opt.selections.str,@opt.fns).location do + __LINE__.to_s + ':' + __FILE__ + end + ensure + end + end + def insertions?(fns_array) + tuned_file=[] + SiSU_Screen::Ansi.new( + @opt.act[:color_state][:set], + 'Composite Document', + @opt.fno + ).grey_title_hi unless @opt.act[:quiet][:set]==:on + @ssm=[@opt.fns] + fns_array.each do |para| + if para =~/^<<\s+(\S+?\.ss[it])$/ + loadfilename=$1.strip + if (@opt.act[:verbose][:set]==:on \ + || @opt.act[:verbose_plus][:set]==:on \ + || @opt.act[:maintenance][:set]==:on) + SiSU_Screen::Ansi.new( + @opt.act[:color_state][:set], + 'loading:', + loadfilename, + ).txt_grey + end + tuned_file << if loadfilename =~ /(?:https?|file):\/\/\S+?\.ss[it]$/ + @ssm << loadfilename + elsif loadfilename =~ /\.ss[it]$/ \ + and FileTest.file?(loadfilename) + @ssm << loadfilename + else + STDERR.puts %{SKIPPED processing file: [#{@opt.lng}] "#{@opt.fns}" it requires an invalid or non-existent file: "#{loadfilename}"} + $process_document = :skip; break #remove this line to continue processing documents that have missing include files + para + end + end + end + @ssm + end + end +end +__END__ +#+END_SRC + +** ao_doc_objects.rb + +#+BEGIN_SRC ruby :tangle "../lib/sisu/ao_doc_objects.rb" +# <<sisu_document_header>> +Module SiSU_AO_DocumentStructure + class Extract + def extract(h,o) + h ? h : o + end + end + class ObjectMetadata + attr_accessor :is,:of,:tags,:obj,:digest + def initialize + @tags={} + @is=@tmp=@digest=nil + @of=:meta + end + def metadata(tags) + of = @of #Symbol, classification - group + is = :meta #Symbol, classification - specific type + tags = tags || ((defined? o.tags) ? o.tags : {}) #String, metadata type/tag + obj = nil + @of,@is,@tags,@obj=of,is,tags,obj + self + end + end + class ObjectMeta + attr_accessor :obj,:is,:of,:tag,:digest,:tmp + def initialize + @is=@obj=@tag=@digest=@digest=@tmp=nil + @of=:meta + end + def metadata(h,o=nil) + of = @of #Symbol, classification - group + is = :meta #Symbol, classification - specific type + tag = h[:tag] || ((defined? o.tag) ? o.tag : nil) #String, metadata type/tag + obj = h[:obj] || ((defined? o.obj) ? o.obj : nil) #String, text content + tmp = h[:tmp] || ((defined? o.tmp) ? o.tmp : nil) #available for processing, empty after use + digest = h[:digest] || ((defined? o.digest) ? o.digest : nil) #hash digests, sha512, sha256 or md5 + @of,@is,@tag,@obj,@digest,@tmp=of,is,tag,obj,digest,tmp + self + end + end + class ObjectHeading + attr_accessor :obj,:is,:tags,:of,:lv,:ln,:lc,:use_,:name,:idx,:ocn,:odv,:osp,:node,:parent,:ocn_,:note_,:autonum_,:digest,:tmp + def initialize + @of=:para + @is=@obj=@lv=@ln=@lc=@use_=@name=@idx=@size=@ocn=@odv=@osp=@node=@parent=@ocn_=@note_=@autonum_=@digest=@tmp=nil + @tags=[] + end + def heading_ln(lv) + case lv + when /A/ then 0 + when /B/ then 1 + when /C/ then 2 + when /D/ then 3 + when /1/ then 4 + when /2/ then 5 + when /3/ then 6 + when /4/ then 7 + when /5/ then 8 + when /6/ then 9 + end + end + def heading_lv(ln) + case ln.to_s + when /0/ then 'A' + when /1/ then 'B' + when /2/ then 'C' + when /3/ then 'D' + when /4/ then '1' + when /5/ then '2' + when /6/ then '3' + when /7/ then '4' + when /8/ then '5' + when /9/ then '6' + end + end + def heading(h,o=nil) + if not h[:ln] \ + and (h[:lv] and h[:lv]=~/[1-6A-D]/) + h[:ln]=heading_ln(h[:lv]) + elsif not h[:lv] \ + and (h[:ln] and h[:ln].to_s=~/[0-9]/) + h[:lv]=heading_lv(h[:ln]) + end + of = @of #Symbol, classification - group + is = :heading #Symbol, classification - specific type + name = h[:name] || ((defined? o.name) ? o.name : nil) #String, named object? + tags = h[:tags] || ((defined? o.tags) ? o.tags : []) #Array, associated object tags, names if any + obj = h[:obj] || ((defined? o.obj) ? o.obj : nil) #String, text content + idx = h[:idx] || ((defined? o.idx) ? o.idx : nil) #String, book index provided? + ocn = h[:ocn] || ((defined? o.ocn) ? o.ocn : nil) #Integer, sequential on substantive-content objects + odv = h[:odv] || ((defined? o.odv) ? o.odv : nil) + osp = h[:osp] || ((defined? o.osp) ? o.osp : nil) + node = h[:node] || ((defined? o.node) ? o.node : nil) #[Node relationship doc structure info] + parent = h[:parent] || ((defined? o.parent) ? o.parent : nil) #[Node parent] + lv = h[:lv] || ((defined? o.lv) ? o.lv : nil) #Alpha-numeric, document structure as used in markup, A-D then 1-6 + ln = h[:ln] || ((defined? o.ln) ? o.ln : nil) #Integer, document structure level, for convenience in processing 1-9 + lc = h[:lc] || ((defined? o.lc) ? o.lc : nil) #Integer, document structure collapsed level, convenience (collapse sisu's dual level document structure for markup with simple linear structure) + use_ = if lv \ + and lv == '1' + h[:use_] || ((defined? o.use_) ? o.use_ : :ok) + elsif not lv.empty? \ + and lv =~ /[A-D2-3]/ + :ok + else + h[:use_] || ((defined? o.use_) ? o.use_ : :ok) + end + ocn_ = if h[:ocn_].nil? + ((defined? o.ocn_) ? o.ocn_ : true) #Bool? no ocn, non-substantive content, do not include in toc #consider + else h[:ocn_] + end + autonum_ = if h[:autonum_].nil? + ((defined? o.autonum_) ? o.autonum_ : true) #Bool? auto-numbering if requested default on, false suppresses + else h[:autonum_] + end + note_ = h[:note_] || ((defined? o.note_) ? o.note_ : false) #Bool, endnotes/footnotes? (processing optimization) + digest = h[:digest] || ((defined? o.digest) ? o.digest : nil) #hash digests, sha512, sha256 or md5 + tmp = h[:tmp] || ((defined? o.tmp) ? o.tmp : nil) #available for processing, empty after use + @of,@is,@lv,@ln,@lc,@name,@tags,@obj,@idx,@ocn,@odv,@osp,@node,@parent,@use_,@ocn_,@note_,@autonum_,@digest,@tmp= + of, is, lv, ln, lc, name, tags, obj, idx, ocn, odv, osp, node, parent, use_, ocn_, note_, autonum_, digest, tmp + self + end + def heading_insert(h,o=nil) + heading(h,o=nil) + @is = :heading_insert #String, classification - specific type + self + end + end + class ObjectPara + attr_accessor :obj,:is,:tags,:of,:name,:idx,:quote_,:bullet_,:indent,:hang,:ocn,:odv,:osp,:parent,:note_,:image_,:ocn_,:digest,:tmp + def initialize + @of=:para + @is=@obj=@name=@idx=@quote_=@bullet_=@indent=@hang=@size=@ocn=@odv=@osp=@parent=@note_=@image_=@ocn_=@digest=@tmp=nil + @tags=[] + end + def paragraph(h,o=nil) + of = @of #Symbol, classification - group + is = :para #Symbol, classification - specific type + name = h[:name] || ((defined? o.name) ? o.name : nil) #String, named object? + tags = h[:tags] || ((defined? o.tags) ? o.tags : []) #Array, associated object tags, names if any + obj = h[:obj] || ((defined? o.obj) ? o.obj : nil) #String, text content + idx = h[:idx] || ((defined? o.idx) ? o.idx : nil) #String, book index provided? + ocn = h[:ocn] || ((defined? o.ocn) ? o.ocn : nil) #Integer, sequential on substantive-content objects + odv = h[:odv] || ((defined? o.odv) ? o.odv : nil) + osp = h[:osp] || ((defined? o.osp) ? o.osp : nil) + parent = h[:parent] || ((defined? o.parent) ? o.parent : nil) #[Node parent] + indent = h[:indent].to_s || ((defined? o.indent) ? o.indent.to_s : nil) #Integer, indent level + hang = h[:hang].to_s || ((defined? o.hang) ? o.hang.to_s : nil) #Integer, hanging indent level + bullet_ = h[:bullet_] || ((defined? o.bullet_) ? o.bullet_ : false) #Bool, bulleted? + quote_ = h[:quote_] || ((defined? o.quote_) ? o.quote_ : false) #Bool, quote (blockquote)? + note_ = h[:note_] || ((defined? o.note_) ? o.note_ : false) #Bool, endnotes/footnotes? (processing optimization) + image_ = h[:image_] || ((defined? o.image_) ? o.image_ : false) #Bool, images? (processing optimization) + ocn_ = if h[:ocn_].nil? + ((defined? o.ocn_) ? o.ocn_ : true) #Bool? no ocn, non-substantive content, do not include in toc #consider + else h[:ocn_] + end + digest = h[:digest] || ((defined? o.digest) ? o.digest : nil) #hash digests, sha512, sha256 or md5 + tmp = h[:tmp] || ((defined? o.tmp) ? o.tmp : nil) #available for processing, empty after use + @of,@is,@name,@tags,@obj,@indent,@hang,@bullet_,@quote_,@idx,@ocn,@odv,@osp,@parent,@image_,@note_,@ocn_,@digest,@tmp= + of, is, name, tags, obj, indent, hang, bullet_, quote_, idx, ocn, odv, osp, parent, image_, note_, ocn_, digest, tmp + self + end + def docinfo(h,o=nil) + of = @of #String, classification - group + is = :docinfo #String, classification - specific type + name = h[:name] || ((defined? o.name) ? o.name : nil) #String, named object? + tags = h[:tags] || ((defined? o.tags) ? o.tags : nil) #Array, associated object tags, names if any + obj = h[:obj] || ((defined? o.obj) ? o.obj : nil) #String, text content + idx = nil #String, book index provided? + ocn = nil #Integer, sequential on substantive-content objects + odv = h[:odv] || ((defined? o.odv) ? o.odv : nil) + osp = h[:osp] || ((defined? o.osp) ? o.osp : nil) + parent = h[:parent] || ((defined? o.parent) ? o.parent : nil) #[Node parent] + indent = nil #Integer, indent level + hang = nil #Integer, indent level + bullet_ = false #Bool, bulleted? + note_ = false #Bool, endnotes/footnotes? (processing optimization) + image_ = h[:image_] || ((defined? o.image_) ? o.image_ : false) #Bool, images? (processing optimization) + ocn_ = if h[:ocn_].nil? + ((defined? o.ocn_) ? o.ocn_ : true) #Bool? no ocn, non-substantive content, do not include in toc #consider + else h[:ocn_] + end + digest = h[:digest] || ((defined? o.digest) ? o.digest : nil) #hash digests, sha512, sha256 or md5 + tmp = h[:tmp] || ((defined? o.tmp) ? o.tmp : nil) #available for processing, empty after use + @of,@is,@name,@tags,@obj,@indent,@hang,@bullet_,@idx,@ocn,@odv,@osp,@parent,@image_,@note_,@ocn_,@digest,@tmp= + of, is, name, tags, obj, indent, hang, bullet_, idx, ocn, odv, osp, parent, image_, note_, ocn_, digest, tmp + self + end + end + class ObjectBlockTxt + attr_accessor :obj,:is,:of,:tags,:lngsyn,:idx,:ocn,:odv,:osp,:parent,:note_,:number_,:ocn_,:digest,:tmp + def initialize + @of=:block + @is=@obj=@lngsyn=@idx=@ocn=@odv=@osp=@parent=@note_=@number_=@ocn_=@digest=@tmp=nil + @tags=[] + end + def code(h,o=nil) + of = @of #Symbol, classification - group #alt 'code' + is = :code #Symbol, classification - specific type + tags = h[:tags] || ((defined? o.tags) ? o.tags : []) #Array, associated object tags, names if any + obj = h[:obj] || ((defined? o.obj) ? o.obj : nil) #String, text content + lngsyn = h[:lngsyn] || ((defined? o.lngsyn) ? o.lngsyn : :txt) #symbol, code lngsyn + idx = h[:idx] || ((defined? o.idx) ? o.idx : nil) #String, book index provided? + ocn = h[:ocn] || ((defined? o.ocn) ? o.ocn : nil) #Integer, sequential on substantive-content objects + odv = h[:odv] || ((defined? o.odv) ? o.odv : nil) + osp = h[:osp] || ((defined? o.osp) ? o.osp : nil) + parent = h[:parent] || ((defined? o.parent) ? o.parent : nil) #[Node parent] + number_ = h[:number_] || ((defined? o.number_) ? o.number_ : false) #Bool, numbered or not? + note_ = h[:note_] || ((defined? o.note_) ? o.note_ : false) #Bool, endnotes/footnotes? (processing optimization) + ocn_ = if h[:ocn_].nil? + ((defined? o.ocn_) ? o.ocn_ : true) #Bool? no ocn, non-substantive content, do not include in toc #consider + else h[:ocn_] + end + num = h[:num] || ((defined? o.num) ? o.num : nil) + digest = h[:digest] || ((defined? o.digest) ? o.digest : nil) #hash digests, sha512, sha256 or md5 + tmp = h[:tmp] || ((defined? o.tmp) ? o.tmp : nil) #available for processing, empty after use + @of,@is,@tags,@obj,@lngsyn,@idx,@ocn,@odv,@osp,@parent,@number_,@note_,@ocn_,@num,@digest,@tmp= + of, is, tags, obj, lngsyn, idx, ocn, odv, osp, parent, number_, note_, ocn_, num, digest, tmp + self + end + def box(h,o=nil) + of = @of #Symbol, classification - group + is = :box #Symbol, classification - specific type + tags = h[:tags] || ((defined? o.tags) ? o.tags : []) #Array, associated object tags, names if any + obj = h[:obj] || ((defined? o.obj) ? o.obj : nil) #String, text content + idx = h[:idx] || ((defined? o.idx) ? o.idx : nil) #String, book index provided? + ocn = h[:ocn] || ((defined? o.ocn) ? o.ocn : nil) #Integer, sequential on substantive-content objects + odv = h[:odv] || ((defined? o.odv) ? o.odv : nil) + osp = h[:osp] || ((defined? o.osp) ? o.osp : nil) + parent = h[:parent] || ((defined? o.parent) ? o.parent : nil) #[Node parent] + note_ = h[:note_] || ((defined? o.note_) ? o.note_ : false) #Bool, endnotes/footnotes? (processing optimization) + ocn_ = if h[:ocn_].nil? + ((defined? o.ocn_) ? o.ocn_ : true) #Bool? no ocn, non-substantive content, do not include in toc #consider + else h[:ocn_] + end + num = h[:num] || ((defined? o.num) ? o.num : nil) + digest = h[:digest] || ((defined? o.digest) ? o.digest : nil) #hash digests, sha512, sha256 or md5 + tmp = h[:tmp] || ((defined? o.tmp) ? o.tmp : nil) #available for processing, empty after use + @of,@is,@tags,@obj,@idx,@ocn,@odv,@osp,@parent,@note_,@ocn_,@num,@digest,@tmp= + of, is, tags, obj, idx, ocn, odv, osp, parent, note_, ocn_, num, digest, tmp + self + end + def block(h,o=nil) + of = @of #Symbol, classification - group + is = :block #Symbol, classification - specific type + tags = h[:tags] || ((defined? o.tags) ? o.tags : []) #Array, associated object tags, names if any + obj = h[:obj] || ((defined? o.obj) ? o.obj : nil) #String, text content + idx = h[:idx] || ((defined? o.idx) ? o.idx : nil) #String, book index provided? + ocn = h[:ocn] || ((defined? o.ocn) ? o.ocn : nil) #Integer, sequential on substantive-content objects + odv = h[:odv] || ((defined? o.odv) ? o.odv : nil) + osp = h[:osp] || ((defined? o.osp) ? o.osp : nil) + parent = h[:parent] || ((defined? o.parent) ? o.parent : nil) #[Node parent] + note_ = h[:note_] || ((defined? o.note_) ? o.note_ : false) #Bool, endnotes/footnotes? (processing optimization) + ocn_ = if h[:ocn_].nil? + ((defined? o.ocn_) ? o.ocn_ : true) #Bool? no ocn, non-substantive content, do not include in toc #consider + else h[:ocn_] + end + num = h[:num] || ((defined? o.num) ? o.num : nil) + digest = h[:digest] || ((defined? o.digest) ? o.digest : nil) #hash digests, sha512, sha256 or md5 + tmp = h[:tmp] || ((defined? o.tmp) ? o.tmp : nil) #available for processing, empty after use + @of,@is,@tags,@obj,@idx,@ocn,@odv,@osp,@parent,@note_,@ocn_,@num,@digest,@tmp= + of, is, tags, obj, idx, ocn, odv, osp, parent, note_, ocn_, num, digest, tmp + self + end + def group(h,o=nil) + of = @of #Symbol, classification - group + is = :group #Symbol, classification - specific type + tags = h[:tags] || ((defined? o.tags) ? o.tags : []) #Array, associated object tags, names if any + obj = h[:obj] || ((defined? o.obj) ? o.obj : nil) #String, text content + idx = h[:idx] || ((defined? o.idx) ? o.idx : nil) #String, book index provided? + ocn = h[:ocn] || ((defined? o.ocn) ? o.ocn : nil) #Integer, sequential on substantive-content objects + odv = h[:odv] || ((defined? o.odv) ? o.odv : nil) + osp = h[:osp] || ((defined? o.osp) ? o.osp : nil) + parent = h[:parent] || ((defined? o.parent) ? o.parent : nil) #[Node parent] + note_ = h[:note_] || ((defined? o.note_) ? o.note_ : false) #Bool, endnotes/footnotes? (processing optimization) + ocn_ = if h[:ocn_].nil? + ((defined? o.ocn_) ? o.ocn_ : true) #Bool? no ocn, non-substantive content, do not include in toc #consider + else h[:ocn_] + end + num = h[:num] || ((defined? o.num) ? o.num : nil) + digest = h[:digest] || ((defined? o.digest) ? o.digest : nil) #hash digests, sha512, sha256 or md5 + tmp = h[:tmp] || ((defined? o.tmp) ? o.tmp : nil) #available for processing, empty after use + @of,@is,@tags,@obj,@idx,@ocn,@odv,@osp,@parent,@note_,@ocn_,@num,@digest,@tmp= + of, is, tags, obj, idx, ocn, odv, osp, parent, note_, ocn_, num, digest, tmp + self + end + def alt(h,o=nil) #see block + of = @of #Symbol, classification - group + is = :alt #Symbol, classification - specific type + tags = h[:tags] || ((defined? o.tags) ? o.tags : []) #Array, associated object tags, names if any + obj = h[:obj] || ((defined? o.obj) ? o.obj : nil) #String, text content + idx = h[:idx] || ((defined? o.idx) ? o.idx : nil) #String, book index provided? + ocn = h[:ocn] || ((defined? o.ocn) ? o.ocn : nil) #Integer, sequential on substantive-content objects + odv = h[:odv] || ((defined? o.odv) ? o.odv : nil) + osp = h[:osp] || ((defined? o.osp) ? o.osp : nil) + parent = h[:parent] || ((defined? o.parent) ? o.parent : nil) #[Node parent] + note_ = h[:note_] || ((defined? o.note_) ? o.note_ : false) #Bool, endnotes/footnotes? (processing optimization) + ocn_ = if h[:ocn_].nil? + ((defined? o.ocn_) ? o.ocn_ : true) #Bool? no ocn, non-substantive content, do not include in toc #consider + else h[:ocn_] + end + num = h[:num] || ((defined? o.num) ? o.num : nil) + digest = h[:digest] || ((defined? o.digest) ? o.digest : nil) #hash digests, sha512, sha256 or md5 + tmp = h[:tmp] || ((defined? o.tmp) ? o.tmp : nil) #available for processing, empty after use + @of,@is,@tags,@obj,@idx,@ocn,@odv,@osp,@parent,@note_,@ocn_,@num,@digest,@tmp= + of, is, tags, obj, idx, ocn, odv, osp, parent, note_, ocn_, num, digest, tmp + self + end + def verse(h,o=nil) #part of poem decide how you deal with this + of = @of #Symbol, classification - group + is = :verse #Symbol, classification - specific type + tags = h[:tags] || ((defined? o.tags) ? o.tags : []) #Array, associated object tags, names if any + obj = h[:obj] || ((defined? o.obj) ? o.obj : nil) #String, text content + idx = h[:idx] || ((defined? o.idx) ? o.idx : nil) #String, book index provided? + ocn = h[:ocn] || ((defined? o.ocn) ? o.ocn : nil) #Integer, sequential on substantive-content objects + odv = h[:odv] || ((defined? o.odv) ? o.odv : nil) + osp = h[:osp] || ((defined? o.osp) ? o.osp : nil) + parent = h[:parent] || ((defined? o.parent) ? o.parent : nil) #[Node parent] + ocn_ = if h[:ocn_].nil? + ((defined? o.ocn_) ? o.ocn_ : true) #Bool? no ocn, non-substantive content, do not include in toc #consider + else h[:ocn_] + end + num = h[:num] || ((defined? o.num) ? o.num : nil) + digest = h[:digest] || ((defined? o.digest) ? o.digest : nil) #hash digests, sha512, sha256 or md5 + tmp = h[:tmp] || ((defined? o.tmp) ? o.tmp : nil) #available for processing, empty after use + @of,@is,@tags,@obj,@idx,@ocn,@odv,@osp,@parent,@note_,@ocn_,@num,@digest,@tmp= + of, is, tags, obj, idx, ocn, odv, osp, parent, note_, ocn_, num, digest, tmp + @h=nil + self + end + end + class ObjectTable + attr_accessor :obj,:is,:of,:lv,:tags,:name,:idx,:indent,:hang,:size,:ocn,:num,:head_,:cols,:widths,:odv,:osp,:parent,:note_,:ocn_,:digest,:tmp + def initialize + @of=:block + @is=@obj=@lv=@name=@idx=@indent=@hang=@size=@ocn,@num,@head_,@cols,@widths=@odv=@osp=@parent=@note_=@ocn_=@num=@digest=@tmp=nil + @tags=[] + end + def table(h,o=nil) + of = @of #Symbol, classification - group + is = :table #Symbol, classification - specific type + tags = h[:tags] || ((defined? o.tags) ? o.tags : []) #Array, associated object tags, names if any + cols = h[:cols] || ((defined? o.cols) ? o.cols : nil) + widths = h[:widths] || ((defined? o.widths) ? o.widths : nil) + obj = h[:obj] || ((defined? o.obj) ? o.obj : nil) #String, text content + idx = h[:idx] || ((defined? o.idx) ? o.idx : nil) #String, book index provided? + ocn = h[:ocn] || ((defined? o.ocn) ? o.ocn : nil) #Integer, sequential on substantive-content objects + odv = h[:odv] || ((defined? o.odv) ? o.odv : nil) + osp = h[:osp] || ((defined? o.osp) ? o.osp : nil) + parent = h[:parent] || ((defined? o.parent) ? o.parent : nil) #[Node parent] + head_ = h[:head_] || ((defined? o.head_) ? o.head_ : false) + note_ = h[:note_] || ((defined? o.note_) ? o.note_ : false) #Bool, endnotes/footnotes? (processing optimization) + ocn_ = if h[:ocn_].nil? + ((defined? o.ocn_) ? o.ocn_ : true) #Bool? no ocn, non-substantive content, do not include in toc #consider + else h[:ocn_] + end + num = h[:num] || ((defined? o.num) ? o.num : nil) + digest = h[:digest] || ((defined? o.digest) ? o.digest : nil) #hash digests, sha512, sha256 or md5 + tmp = h[:tmp] || ((defined? o.tmp) ? o.tmp : nil) #available for processing, empty after use + @of,@is,@tags,@cols,@widths,@obj,@idx,@ocn,@odv,@osp,@parent,@head_,@note_,@ocn_,@num,@digest,@tmp= + of, is, tags, cols, widths, obj, idx, ocn, odv, osp, parent, head_, note_, ocn_, num, digest, tmp + self + end + end + class ObjectImage + attr_accessor :obj,:is,:of,:lv,:idx,:size,:ocn,:parent,:note_,:ocn_,:digest,:tmp + def initialize + @of=:image + @is=@obj=@lv=@idx=@size=@ocn=@parent=@note_=@ocn_=@tmp=@digest=nil + @tags=[] + end + def image(h,o=nil) #not yet used, and what of a paragraph containing several images, consider + of= @of #Symbol, classification - group + is= :image #Symbol, classification - specific type + tags= h[:tags] || ((defined? o.tags) ? o.tags : []) #Array, associated object tags, names if any + obj= h[:obj] || ((defined? o.obj) ? o.obj : nil) #String, text content + size= h[:size] || ((defined? o.size) ? o.size : nil) + idx= h[:idx] || ((defined? o.idx) ? o.idx : nil) #String, book index provided? + ocn= h[:ocn] || ((defined? o.ocn) ? o.ocn : nil) #Integer, sequential on substantive-content objects + odv= h[:odv] || ((defined? o.odv) ? o.odv : nil) + osp= h[:osp] || ((defined? o.osp) ? o.osp : nil) + parent= h[:parent] || ((defined? o.parent) ? o.parent : nil) #[Node parent] + note_= h[:note_] || ((defined? o.note_) ? o.note_ : false) #Bool, endnotes/footnotes? (processing optimization) + ocn_=if h[:ocn_].nil? + ((defined? o.ocn_) ? o.ocn_ : true) #Bool? no ocn, non-substantive content, do not include in toc #consider + else h[:ocn_] + end + digest= h[:digest] || ((defined? o.digest) ? o.digest : nil) #hash digests, sha512, sha256 or md5 + tmp= h[:tmp] || ((defined? o.tmp) ? o.tmp : nil) #available for processing, empty after use + @of,@is,@tags,@obj,@size,@idx,@ocn,@odv,@osp,@parent,@note_,@ocn_,@digest,@tmp=of,is,tags,obj,size,idx,ocn,odv,osp,parent,note_,ocn_,digest,tmp + self + end + end + class ObjectStructure + attr_accessor :obj,:tag,:node,:lv,:ln,:lc,:status,:is,:of,:tmp + def initialize + @of=:structure + @is=@obj=@node=@lv=@ln=@lc=@status=@tmp=nil + end + def xml_dom(h,o=nil) + of= @of #Symbol, classification - group + is= :xml_dom #Symbol, classification - specific type + obj= h[:obj] || ((defined? o.obj) ? o.obj : '') #String, text content + lv= h[:lv] || ((defined? o.lv) ? o.lv : nil) #Alpha-numeric, document structure as used in markup, A-D then 1-6 + ln= h[:ln] || ((defined? o.ln) ? o.ln : nil) #Integer, document structure level, for convenience in processing 1-9 + lc= h[:lc] || ((defined? o.lc) ? o.lc : nil) #Integer, document structure collapsed level, convenience (collapse sisu's dual level document structure for markup with simple linear structure) + node= h[:node] || ((defined? o.node) ? o.node : nil) #[Node relationship doc structure info] + status= h[:status] || ((defined? o.status) ? o.status : nil) #tag status Symbol :open or :close + tmp= h[:tmp] || ((defined? o.tmp) ? o.tmp : nil) #available for processing, empty after use + @of,@is,@obj,@status,@node,@lv,@ln,@lc,@tmp=of,is,obj,status,node,lv,ln,lc,tmp + self + end + end + class ObjectFlag + attr_accessor :obj,:is,:of,:flag,:act,:selections,:tmp + def initialize + @of=:flag + @is=@obj=@flag=@act=@selections=@tmp=nil + end + def flag(h,o=nil) + of= @of #Symbol, classification - group + is= :flag #Symbol, classification - specific type + obj= nil #String, text content + flag= h[:flag] || ((defined? o.flag) ? o.flag : nil) #String, text content + act= h[:act] || ((defined? o.act) ? o.act : nil) #String, text content + selections= h[:selections] || ((defined? o.selections) ? o.selections : nil) #String, text content + tmp= h[:flag] || ((defined? o.tmp) ? o.tmp : nil) #available for processing, empty after use + @of, @is,@obj,@flag,@act,@selections,@tmp= + of,is, obj, flag, act, selections, tmp + self + end + def flag_ocn(h,o=nil) + of= @of #Symbol, classification - group + is= :flag_ocn #Symbol, classification - specific type + obj= nil #String, text content + flag= h[:flag] || ((defined? o.flag) ? o.flag : nil) #String, text content + act= h[:act] || ((defined? o.act) ? o.act : nil) #String, text content + selections= h[:selections] || ((defined? o.selections) ? o.selections : nil) #String, text content + tmp= h[:flag] || ((defined? o.tmp) ? o.tmp : nil) #available for processing, empty after use + @of, @is,@obj,@flag,@act,@selections,@tmp= + of,is, obj, flag, act, selections,tmp + self + end + def flag_lng(h,o=nil) + of= @of #Symbol, classification - group + is= :flag_lng + obj= nil #String, text content + flag= h[:flag] || ((defined? o.flag) ? o.flag : nil) #Symbol, :lng_on or :lng_off + act= h[:act] || ((defined? o.act) ? o.act : nil) #Symbol, language set to :en etc. + selections= h[:selections] || ((defined? o.selections) ? o.selections : nil) #String, text content + tmp= h[:act] || ((defined? o.tmp) ? o.tmp : nil) #available for processing, empty after use + @of, @is,@obj,@flag,@act,@selections,@tmp= + of,is, obj, flag, act, selections,tmp + self + end + end + class ObjectLayout + attr_accessor :obj,:sym,:attr,:is,:is_for,:of,:from,:tmp,:num + def initialize + @of=:layout + @is=@is_for=@obj=@from=@tmp=@num=nil + end + def break(h,f=nil) #decide how to deal with + of= @of #Symbol, classification - group + is= :break #Symbol, classification - specific type + obj= h[:obj] #String, text content + from= f + tmp= h[:tmp] #available for processing, empty after use + @of,@is,@obj,@from,@tmp=of,is,obj,from,tmp + self + end + def insert(h,o=nil) #decide how to deal with, could mimic paragraph? + of= @of #Symbol, classification - group + is= :insert #Symbol, classification - specific type + obj= h[:obj] || ((defined? o.obj) ? o.obj : nil) #String, text content + tmp= h[:tmp] || ((defined? o.tmp) ? o.tmp : nil) #available for processing, empty after use + @of,@is,@obj,@tmp=of,is,obj,tmp + self + end + def open_close(h,o=nil) #useful for poem & quote + of= @of #Symbol, classification - group + is= :open_close_tags #Symbol, classification - specific type + is_for= h[:is_for] || ((defined? o.is_for) ? o.is_for : nil) #String, text content + obj= h[:obj] || ((defined? o.obj) ? o.obj : nil) #String, text content + sym= h[:sym] || ((defined? o.sym) ? o.sym : nil) #Symbol tag_open, tag_close + attr= h[:attr] || ((defined? o.attr) ? o.attr : nil) #String, text content + tmp= h[:tmp] || ((defined? o.tmp) ? o.tmp : nil) #available for processing, empty after use + num= h[:num] || ((defined? o.num) ? o.num : nil) + @of,@is,@is_for,@obj,@sym,@attr,@tmp,@num= + of, is, is_for, obj, sym, attr, tmp, num + self + end + end + class ObjectComment + attr_accessor :obj,:is,:of,:tmp + def initialize + @of=:comment + @is=@obj=@tmp=nil + end + def comment(h,o=nil) + of= @of #Symbol, classification - group + is= :comment #Symbol, classification - specific type + obj= h[:obj] || ((defined? o.obj) ? o.obj : nil) #String, text content + tmp= h[:tmp] || ((defined? o.tmp) ? o.tmp : nil) #available for processing, empty after use + @of,@is,@obj,@tmp=of,is,obj,tmp + self + end + end +end +__END__ +# ~# |-# no paragraph number # -# not included in toc +#+END_SRC + +** ao_doc_str.rb + +#+BEGIN_SRC ruby :tangle "../lib/sisu/ao_doc_str.rb" +# <<sisu_document_header>> +module SiSU_AO_DocumentStructureExtract + require_relative 'ao_persist' # ao_persist.rb + class Instantiate < SiSU_Param::Parameters::Instructions + def initialize + @@counter=@@column=@@columns=0 + @@line_mode='' + end + end + class Build + def initialize(md,data) + @md,@data=md,data + SiSU_AO_DocumentStructureExtract::Instantiate.new + @pb=SiSU_AO_DocumentStructure::ObjectLayout.new.break(Hx[:br_page]) + @pbn=SiSU_AO_DocumentStructure::ObjectLayout.new.break(Hx[:br_page_new]) + @pbl=SiSU_AO_DocumentStructure::ObjectLayout.new.break(Hx[:br_page_line]) + @per=SiSU_AO_Persist::PersistDocStructExt.new + @make=SiSU_Env::ProcessingSettings.new(@md) + end + def ln_get(lv) + case lv + when /A/ then 0 + when /B/ then 1 + when /C/ then 2 + when /D/ then 3 + when /1/ then 4 + when /2/ then 5 + when /3/ then 6 + when /4/ then 7 + when /5/ then 8 + when /6/ then 9 + end + end + def image_test(str) + str=~/\{\s*\S+?\.png.+?\}https?:\/\/\S+/ \ + ? true + : false + end + def bullet_test(str) + (str=~/\*/) \ + ? true + : false + end + def quotes? + @per.quote==:open \ + ? true + : false + end + def hang_and_indent_test(str) + hang_indent=if str=~/^_([1-9])[^_]/ + [$1,$1] + elsif str=~/^__([1-9])/ + [0,$1] + elsif str=~/^_([0-9])_([0-9])/ + [$1,$2] + else + [0,0] + end + hang,indent=hang_indent[0],hang_indent[1] + [hang,indent] + end + def hang_and_indent_def_test(str1,str2) + hang_indent=if str1=~/^_([1-9])[^_]/ + [$1,$1] + elsif str1=~/^__([1-9])/ + [0,$1] + elsif str1=~/^_([0-9])_([0-9])/ + [$1,$2] + else + [0,0] + end + obj=if str2 =~/^(.+?)\s+\\\\(?:\s+|\n)/ + str2.gsub(/^(.+?)(\s+\\\\(?:\s+|\n))/, + "#{Mx[:fa_bold_o]}\\1#{Mx[:fa_bold_c]}\\2") + else + str2.gsub(/^(.+?)\n/, + "#{Mx[:fa_bold_o]}\\1#{Mx[:fa_bold_c]}\n") + end + hang,indent=hang_indent[0],hang_indent[1] + [ + hang, + indent, + obj, + ] + end + def endnote_test?(str) + (str=~/~\{.+?\}~|~\[.+?\]~/) \ + ? true + : false + end + def extract_tags(str,nametag=nil) + tags=[] + if str.nil? + else + if str =~/(?:^|[ ])\*~([a-z0-9._-]+)(?=[ #{Mx[:br_nl]}]|$)/ + str=str.gsub(/(^|[ ])\*~([a-z0-9._-]+)(?=[ #{Mx[:br_nl]}]|$)/i, + "\\1#{Mx[:tag_o]}\\2#{Mx[:tag_c]}"). + gsub(/ [ ]+/i,' ') + tags=str.scan(/#{Mx[:tag_o]}(\S+?)#{Mx[:tag_c]}/).flatten.uniq + str=str.gsub(/[ ]?#{Mx[:tag_o]}\S+?#{Mx[:tag_c]}[ ]?/,' ') #may be issues with spaces would leave one, but "code" blocks? + end + tags=nametag ? (tags << nametag) : tags + tags.each do |t| + t.gsub!(/[^a-z0-9._-]/,'') + end + end + [ + str, + tags, + ] + end + def rgx_idx_ocn_seg + @rgx_idx_ocn_seg=/(.+?)\s*[+](\d+)/ + end + def construct_idx_array_and_hash(idxraw) + idx_array_raw=idxraw.scan(/[^;]+/) + idx_hash,idx_array,idx_lst={},[],[] + idx_array_raw.each do |idx| + idx=idx.strip + idx_lst=case idx + when /\S+?\s*:/ + idx_couplet_tmp=[] + idx_couplet=idx.scan(/\s*[^:]+\s*/) + if idx_couplet[1] =~/[|]/ + idx_couplet_tmp << + idx_couplet[0] << + idx_couplet[1].scan(/\s*[^|]+\s*/) + else + idx_couplet_tmp << + idx_couplet[0] << + [idx_couplet[1]] + end + idx_couplet=idx_couplet_tmp + else [idx] + end + term_nodes=[] + idx_lst.each do |term_node| + case term_node + when String + term_node= + term_node[0].chr.capitalize + + term_node[1,term_node.length] + term_node=(term_node =~/.+?[+]\d+/) \ + ? term_node + : (term_node + '+0') + term_nodes << term_node + use,plus=rgx_idx_ocn_seg.match(term_node)[1,2] + @use=use.strip + unless idx_hash[@use] \ + and defined? idx_hash[@use] + idx_hash[@use]= + { sub: [], plus: plus } + end + when Array + subterm_nodes=[] + term_node.each do |subterm_node| + subterm_node=(subterm_node =~/.+?[+]\d+/) \ + ? subterm_node + : (subterm_node + '+0') + subterm_nodes << subterm_node + sub,sub_plus=rgx_idx_ocn_seg.match(subterm_node)[1,2] + unless idx_hash[@use] \ + and defined? idx_hash[@use] + idx_hash[@use]= + { sub: [], plus: 0 } + end + idx_hash[@use][:sub] << + { sub.strip => { plus: sub_plus } } + end + term_nodes << subterm_nodes + end + end + idx_array << term_nodes + end + { + hash: idx_hash, + array: idx_array, + } + end + def extract_structure_loop(data,tuned_file) + data.each do |t_o| + if t_o =~/^--([+~-])[#]$/ + h=case $1 + when /[+]/ + @per.ocn=:on + { + flag: :ocn_on, + } + when /[~]/ + @per.ocn=:ocn_off_headings_keep + { + flag: :ocn_off, + mod: :headings_keep, + } + when /[-]/ #of particular relevance with level 1~ which is required to precede substantive text & used e.g. in html segmented text + @per.ocn=:ocn_off_headings_dummy_lev1 + { + flag: :ocn_off, + mod: :headings_exclude, + } + else + @per.ocn=:on + { + flag: :ocn_on, + } + end + t_o=SiSU_AO_DocumentStructure::ObjectFlag.new.flag_ocn(h) + next + end + if t_o =~/^:[~](#{SiSU_is.language_list_regex?}|-)$/ # work with for identifying language of objects + lng=$1 + h=case lng + when /(?:#{SiSU_is.language_list_regex?})/ + @per.lng=:on + @per.lng_is=lng.to_sym + { + flag: :lng_on, + act: lng.to_sym, + } + else # ^:~- + if @per.lng==:on + @per.lng=:off + @per.lng_is=:doc_default + { + flag: :lng_off, + act: :doc_default, + } + end + end + t_o=SiSU_AO_DocumentStructure::ObjectFlag.new.flag_lng(h) + next + end + t_o=t_o.gsub(/(?:\n\s*\n)+/m,"\n") if @per.code==:off + unless t_o =~/^(?:@\S+?:|%+)\s/ # extract book index for paragraph if any + idx=if t_o=~/^=\{\s*(.+)\s*\}\s*$\Z/m + m=$1 + m=m.split(/[ ]*\n/).join(' '). + gsub(/\s+([|:;])\s+/,'\1'). + gsub(/\s+([+]\d+)\s+/,'\1') + t_o=t_o.gsub(/\n=\{.+?\}\s*$/m,'') + idx_array_and_hash=construct_idx_array_and_hash(m) + idx_array_and_hash[:hash] + else nil + end + end + if (t_o.is_a?(String) \ + && t_o !~/^(?:code(?:\.[a-z][0-9a-z_]+)?(?:\(.+?\))?|box(?:\.[a-z_]+)?|poem|alt|group|block)\{|^\}(?:code|poem|alt|group|block)|^(?:table\(.+?\)\{|\{table\()|^(?:table\{|\{table)[ ~]/ \ + && t_o !~/^```[ ]+(?:code(?:\.[a-z][0-9a-z_]+)?(?:\(.+?\))?|box(?:\.[a-z_]+)?|poem|alt|group|block|table)|^```(?:\s+[~-][#]|\s+\~\{.+?\}\~)?\s*$|^`:quote_(?:open|close)`/ \ + and @per.code==:off \ + and @per.poem==:off \ + and @per.group==:off \ + and @per.block==:off \ + and @per.alt==:off \ + and @per.box==:off \ + and @per.table==:off + ) + t_o=case t_o + when /^#{Mx[:meta_o]}\S+?#{Mx[:meta_c]}/ #metadata, header + if t_o=~/^#{Mx[:meta_o]}(\S+?)#{Mx[:meta_c]}\s*(.+)/m + tag,obj=$1,$2 + @metadata[tag]=obj + end + t_o=nil + when /^%+\s/ #comment + t_o=if t_o=~/^%+\s+(.+)/ + h={ obj: $1 } + SiSU_AO_DocumentStructure::ObjectComment.new.comment(h) + else nil + end + when /^:?([A-D1-6])\~/ #heading / lv + lv=$1 + ln=ln_get(lv) + t_o=if t_o=~/^:?[A-D1-6]\~\s+(.+)/m + obj=$1 + note=endnote_test?(obj) + obj,tags=extract_tags(obj) + if @per.ocn==:ocn_off_headings_dummy_lev1 \ + or @per.ocn==:ocn_off_headings_keep + unless obj =~ /[~-][#]\s*$/ + if @per.ocn==:ocn_off_headings_dummy_lev1 \ + and t_o =~/^1\~\S*\s+/m + obj << ' -#' + elsif @per.ocn==:ocn_off_headings_dummy_lev1 \ + or @per.ocn==:ocn_off_headings_keep + obj << ' ~#' + end + end + end + h={ + lv: lv, + ln: ln, + obj: obj, + idx: idx, + tags: tags, + } + SiSU_AO_DocumentStructure::ObjectHeading.new.heading(h) + elsif t_o=~/^:?[A-D1-6]\~(\S+?)-\s+(.+)/m + name,obj=$1,$2 + note=endnote_test?(obj) + obj,tags=extract_tags(obj) + if @per.ocn==:ocn_off_headings_dummy_lev1 \ + or @per.ocn==:ocn_off_headings_keep + unless obj =~ /[~-][#]\s*$/ + if @per.ocn==:ocn_off_headings_dummy_lev1 \ + and t_o =~/^1\~\S*\s+/m + obj << ' -#' + elsif @per.ocn==:ocn_off_headings_dummy_lev1 \ + or @per.ocn==:ocn_off_headings_keep + obj << ' ~#' + end + end + end + h={ + lv: lv, + name: name, + obj: obj, + idx: idx, + autonum_: false, + tags: tags, + } + SiSU_AO_DocumentStructure::ObjectHeading.new.heading(h) + elsif t_o=~/^:?[A-D1-6]\~(\S+)\s+(.+)/m + name,obj=$1,$2 + note=endnote_test?(obj) + obj,tags=extract_tags(obj,name) + if @per.ocn==:ocn_off_headings_dummy_lev1 \ + or @per.ocn==:ocn_off_headings_keep + unless obj =~ /[~-][#]\s*$/ + if @per.ocn==:ocn_off_headings_dummy_lev1 \ + and t_o =~/^1\~\S*\s+/m + obj << ' -#' + elsif @per.ocn==:ocn_off_headings_dummy_lev1 \ + or @per.ocn==:ocn_off_headings_keep + obj << ' ~#' + end + end + end + h={ + lv: lv, + name: name, + obj: obj, + idx: idx, + tags: tags, + } + SiSU_AO_DocumentStructure::ObjectHeading.new.heading(h) + else nil + end + when /^_(?:[1-9]!?|[1-9]?\*)\s+/ #indented and/or bullet paragraph + t_o=if t_o=~/^(_(?:[1-9]?\*|[1-9]!?)\s+)(.+)/m + tst,obj=$1,$2 + if t_o=~/^_[1-9]!\s+.+/m + hang,indent,obj=hang_and_indent_def_test(tst,obj) + else + hang,indent=hang_and_indent_test(tst) + end + bullet=bullet_test(tst) + image=image_test(obj) + note=endnote_test?(obj) + obj,tags=extract_tags(obj) + unless obj=~/\A\s*\Z/m + if @per.ocn==:ocn_off_headings_dummy_lev1 \ + or @per.ocn==:ocn_off_headings_keep + unless obj =~ /[~-][#]\s*$/ + obj << ' ~#' + end + end + h={ + bullet_: bullet, + hang: hang, + indent: indent, + obj: obj, + idx: idx, + note_: note, + image_: image, + tags: tags, + quote: quotes?, + } + SiSU_AO_DocumentStructure::ObjectPara.new.paragraph(h) + end + else nil + end + when /^_[0-9]?_[0-9]!?\s+/ #hanging indent paragraph + t_o=if t_o=~/^(_[0-9]?_[0-9]!?\s+)(.+)/m + tst,obj=$1,$2 + if t_o=~/^_[0-9]?_[0-9]!\s+.+/m + hang,indent,obj=hang_and_indent_def_test(tst,obj) + else + hang,indent=hang_and_indent_test(tst) + end + image=image_test(obj) + note=endnote_test?(obj) + obj,tags=extract_tags(obj) + unless obj=~/\A\s*\Z/m + if @per.ocn==:ocn_off_headings_dummy_lev1 \ + or @per.ocn==:ocn_off_headings_keep + unless obj =~ /[~-][#]\s*$/ + obj << ' ~#' + end + end + h={ + hang: hang, + indent: indent, + obj: obj, + idx: idx, + note_: note, + image_: image, + tags: tags, + quote: quotes?, + } + SiSU_AO_DocumentStructure::ObjectPara.new.paragraph(h) + end + else nil + end + when /^<(?:br)?:(?:pa?r|o(?:bj|---)?)>\s*$/ #[br:par] #[br:obj] + SiSU_AO_DocumentStructure::ObjectLayout.new.break(Hx[:br_obj]) + when /^(?:-\\\\-|<:pb>)\s*$/ #[br:pg] + SiSU_AO_DocumentStructure::ObjectLayout.new.break(Hx[:br_page],:markup) + when /^(?:=\\\\=|<:pn>)\s*$/ #[br:pgn] + SiSU_AO_DocumentStructure::ObjectLayout.new.break(Hx[:br_page_new],:markup) + when /^-\.\.-\s*$/ #[br:pgl] + SiSU_AO_DocumentStructure::ObjectLayout.new.break(Hx[:br_page_line],:markup) + else #paragraph + image=image_test(t_o) + note=endnote_test?(t_o) + obj,tags=extract_tags(t_o) + if @per.ocn==:ocn_off_headings_dummy_lev1 \ + or @per.ocn==:ocn_off_headings_keep + unless obj =~ /[~-][#]\s*$/ + obj << ' ~#' + end + end + unless obj=~/\A\s*\Z/m + h={ + bullet_: false, + indent: 0, + hang: 0, + obj: obj, + idx: idx, + note_: note, + image_: image, + tags: tags, + quote: quotes?, + } + t_o=SiSU_AO_DocumentStructure::ObjectPara.new.paragraph(h) + end + t_o=SiSU_AO_DocumentStructureExtract::Structure.new(@md).structure_markup(t_o) #must happen earlier, node info etc. require + end + elsif @per.code==:off + if t_o =~/^(?:code(?:\.[a-z][0-9a-z_]+)?(?:\(.+?\))?\{|```[ ]+code(?:\.[a-z][0-9a-z_]+)?(?:\(.+?\))?)/ + @per.code=case t_o + when /^code(?:\.[a-z][0-9a-z_]+)?(?:\(.+?\))?\{/ then :curls + when /^```[ ]+code/ then :tics + else @per.code #error + end + @per.lngsyn=if t_o =~/^(?:code\.[a-z][0-9a-z_]+(?:\(.+?\))?\{|```[ ]+code\.[a-z_]+)/ + case t_o + when /^code\.([a-z][0-9a-z_]+)(?:\(.+?\))?\{/ + :"#{$1}" + when /^```[ ]+code\.([a-z][0-9a-z_]+)/ + :"#{$1}" + else :txt + end + else :txt + end + @@counter=1 + @codeblock_numbered= + (t_o =~/^(?:code(?:\.[a-z][0-9a-z_]+)?\(.*number(?:lines)?.*?\)\{|```[ ]+code(?:\.[a-z][0-9a-z_]+)?\(.*number(?:lines)?.*?\)|code(?:\.[a-z][0-9a-z_]+)?\{#|```[ ]+code(?:\.[a-z][0-9a-z_]+)?\s[#])/) \ + ? true + : false + if (t_o =~/^(?:code(?:\.[a-z][0-9a-z_]+)?\{#|```[ ]+code(?:\.[a-z][0-9a-z_]+)?\s[#])/) + puts "WARNING document using depreciated markup for numbering codeblocks\nuse: code(numberlines){ ... or: ```code(numberlines) ..." + end + @num_id[:code_block] +=1 + h={ + is_for: :code, + obj: '', + sym: :code_block_open, + num: @num_id[:code_block], + syntax: @per.lngsyn, + } + t_o=SiSU_AO_DocumentStructure::ObjectLayout.new.open_close(h) + elsif t_o =~/^(?:poem\{|```[ ]+poem)/ + @per.poem=case t_o + when /^poem\{/ then :curls + when /^```[ ]+poem/ then :tics + else @per.poem #error + end + @num_id[:poem] +=1 + h={ + is_for: :poem, + obj: '', + sym: :poem_open, + num: @num_id[:poem], + } + t_o=SiSU_AO_DocumentStructure::ObjectLayout.new.open_close(h) + tuned_file << t_o + elsif t_o =~/^(?:box(?:\.[a-z_]+)?\{|```[ ]+box(?:\.[a-z_]+)?)/ + @per.box=case t_o + when /^box\{/ then :curls + when /^```[ ]+box/ then :tics + else @per.box #error + end + @num_id[:box] +=1 + h={ + is_for: :box, + obj: '', + sym: :box_open, + num: @num_id[:box], + } + t_o=SiSU_AO_DocumentStructure::ObjectLayout.new.open_close(h) + tuned_file << t_o + elsif t_o =~/^(?:group\{|```[ ]+group)/ + @per.group=case t_o + when /^group\{/ then :curls + when /^```[ ]+group/ then :tics + else @per.group #error + end + @num_id[:group] +=1 + h={ + is_for: :group, + obj: '', + sym: :group_open, + num: @num_id[:group], + } + t_o=SiSU_AO_DocumentStructure::ObjectLayout.new.open_close(h) + tuned_file << t_o + elsif t_o =~/^(?:block\{|```[ ]+block)/ + @per.block=case t_o + when /^block\{/ then :curls + when /^```[ ]+block/ then :tics + else @per.block #error + end + @num_id[:block] +=1 + h={ + is_for: :block, + obj: '', + sym: :block_open, + num: @num_id[:block], + } + t_o=SiSU_AO_DocumentStructure::ObjectLayout.new.open_close(h) + tuned_file << t_o + elsif t_o =~/^(?:alt\{|```[ ]+alt)/ + @per.alt=case t_o + when /^alt\{/ then :curls + when /^```[ ]+alt/ then :tics + else @per.alt #error + end + @num_id[:alt] +=1 + h={ + is_for: :alt, + obj: '', + sym: :alt_open, + num: @num_id[:alt], + } + t_o=SiSU_AO_DocumentStructure::ObjectLayout.new.open_close(h) + tuned_file << t_o + elsif t_o =~/^`:quote_open`/ + @per.quote=:open + @num_id[:quote] +=1 + h={ + is_for: :quote, + obj: '', + sym: :quote_open, + num: @num_id[:quote], + } + t_o=SiSU_AO_DocumentStructure::ObjectLayout.new.open_close(h) + #tuned_file << t_o #% find second source, entered twice, should be once so closed off here + elsif t_o =~/^(?:table\(.+?\)\{|```[ ]+table\(.+?\)|\{table\(.+?\))/ + @num_id[:table] +=1 + h={ + is_for: :table, + obj: '', + sym: :table_open, + num: @num_id[:table], + } + ins_o=SiSU_AO_DocumentStructure::ObjectLayout.new.open_close(h) + tuned_file << ins_o + if t_o=~/^table\((?:.*?\bh;\s+)?.+?\)\{/ + @per.table=:curls + @rows='' + case t_o + when /table\(.*?\bh;\s+c(\d+):\s+(.+?)\)\{/ + cols=$1 + col=$2.scan(/\d+/) + heading=true + when /table\(.*?c(\d+):\s+(.+?)\)\{/ + cols=$1 + col=$2.scan(/\d+/) + heading=false + end + @h={ + head_: heading, + cols: cols, + widths: col, + idx: idx, + } + elsif t_o=~/^```[ ]+table\((?:.*?\bh;)?\s+c\d+:/ + @per.table=:tics + @rows='' + case t_o + when /^```[ ]+table\(.*?\bh;\s+c(\d+):\s+(.+?)\)/ + cols=$1 + col=$2.scan(/\d+/) + heading=true + when /^```[ ]+table\(\s*c(\d+):\s+(.+?)\)/ + cols=$1 + col=$2.scan(/\d+/) + heading=false + end + @h={ + head_: heading, + cols: cols, + widths: col, + idx: idx, + } + elsif t_o=~/^\{table\((?:.*?\bh;\s+)?(?:\s+\d+,?)?\)\s*\}\n.+\Z/m + m1,m2,hd=nil,nil,nil + tbl=/^\{table\((?:.*?\bh;\s+)?(?:\s+\d+,?)*\)\s*\}\n(.+)\Z/m.match(t_o)[1] # fix + hd=((t_o =~/^\{table\(.*?\bh;\s+/) ? true : false) + tbl,tags=extract_tags(tbl) + rws=tbl.split(/\n/) + rows='' + cols=nil + rws.each do |r| + cols=(cols ? cols : (r.scan('|').length) +1) + r=r.gsub(/\s*\|\s*/m,"#{Mx[:tc_p]}") #r.gsub!(/\|/m,"#{Mx[:tc_p]}") + rows += r + Mx[:tc_c] + end + col=[] + if t_o =~/^\{table\((?:.*?\bh;\s+)?\s+c(\d+):.*?\)\s*\}/ #width of col 1 given as %, usually when wider than rest that are even + c1=$1.to_i + width=(100 - c1)/(cols - 1) + col=[ c1 ] + (cols - 1).times { col << width } + else #all columns of equal width + width=100.00/cols + cols.times { col << width } + end + h={ + head_: hd, + cols: cols, + widths: col, + obj: rows, + idx: idx, + tags: tags, + num: @num_id[:table], + } + t_o=SiSU_AO_DocumentStructure::ObjectTable.new.table(h) \ + unless h.nil? + tuned_file << t_o + h={ + is_for: :table, + obj: '', + sym: :table_close, + num: @num_id[:table], + } + t_o=SiSU_AO_DocumentStructure::ObjectLayout.new.open_close(h) + t_o + elsif t_o=~/^```[ ]+table\((?:.*?\bh;)?\s+/ + m1,m2,hd=nil,nil,nil + h=case t_o + when /^```[ ]+table\(.*?\bh;\s+(.+?)\)\n(.+)\Z/m #two table representations should be consolidated as one + m1,tbl,hd=$1,$2,true + when /^```[ ]+table\((.+?)\)\n(.+)\Z/m #two table representations should be consolidated as one + m1,tbl,hd=$1,$2,false + else nil + end + tbl,tags=extract_tags(tbl) + col=m1.scan(/\d+/) + rws=tbl.split(/\n/) + rows='' + rws.each do |r| + r=r.gsub(/\s*\|\s*/m,"#{Mx[:tc_p]}") #r.gsub!(/\|/m,"#{Mx[:tc_p]}") + rows += r + Mx[:tc_c] + end + h={ + head_: hd, + cols: col.length, + widths: col, + obj: rows, + idx: idx, + tags: tags, + num: @num_id[:table], + } + t_o=SiSU_AO_DocumentStructure::ObjectTable.new.table(h) \ + unless h.nil? + tuned_file << t_o + h={ + is_for: :table, + obj: '', + sym: :table_close, + num: @num_id[:table], + } + t_o=SiSU_AO_DocumentStructure::ObjectLayout.new.open_close(h) + t_o + elsif t_o=~/^\{table\((?:.*?\bh;)?/ + m1,m2,hd=nil,nil,nil + h=case t_o + when /\{table\(.*?\bh;\s+(.+?)\)\s*\}\n(.+)\Z/m #two table representations should be consolidated as one + m1,tbl,hd=$1,$2,true + when /\{table\((.+?)\)\s*\}\n(.+)\Z/m #two table representations should be consolidated as one + m1,tbl,hd=$1,$2,false + else nil + end + tbl,tags=extract_tags(tbl) + col=m1.scan(/\d+/) + rws=tbl.split(/\n/) + rows='' + rws.each do |r| + r=r.gsub(/\s*\|\s*/m,"#{Mx[:tc_p]}") #r.gsub!(/\|/m,"#{Mx[:tc_p]}") + rows += r + Mx[:tc_c] + end + h={ + head_: hd, + cols: col.length, + widths: col, + obj: rows, + idx: idx, + tags: tags, + num: @num_id[:table], + } + t_o=SiSU_AO_DocumentStructure::ObjectTable.new.table(h) \ + unless h.nil? + tuned_file << t_o + h={ + is_for: :table, + obj: '', + sym: :table_close, + num: @num_id[:table], + } + t_o=SiSU_AO_DocumentStructure::ObjectLayout.new.open_close(h) + t_o + end +## depreciated markup, code should work for new markup after removal { + elsif t_o =~/^(?:table\{|```[ ]+table|\{table)[ ~]/ + puts "WARNING document using depreciated markup for tables" + puts "use table([table attributes]) instead:" + puts "table(){" + puts "``` table()" + puts "{table()}" + @num_id[:table] +=1 + h={ + is_for: :table, + obj: '', + sym: :table_open, + num: @num_id[:table], + } + ins_o=SiSU_AO_DocumentStructure::ObjectLayout.new.open_close(h) + tuned_file << ins_o + if t_o=~/^table\{(?:~h)?\s+/ + @per.table=:curls + @rows='' + case t_o + when /table\{~h\s+c(\d+);\s+(.+)/ + cols=$1 + col=$2.scan(/\d+/) + heading=true + when /table\{\s+c(\d+);\s+(.+)/ + cols=$1 + col=$2.scan(/\d+/) + heading=false + end + @h={ + head_: heading, + cols: cols, + widths: col, + idx: idx, + } + elsif t_o=~/^```[ ]+table(?:~h)?\s+c\d+/ + @per.table=:tics + @rows='' + case t_o + when /^```[ ]+table~h\s+c(\d+);\s+(.+)/ + cols=$1 + col=$2.scan(/\d+/) + heading=true + when /^```[ ]+table\s+c(\d+);\s+(.+)/ + cols=$1 + col=$2.scan(/\d+/) + heading=false + end + @h={ + head_: heading, + cols: cols, + widths: col, + idx: idx, + } + elsif t_o=~/^\{table(?:~h)?(?:\s+\d+;?)?\}\n.+\Z/m + m1,m2,hd=nil,nil,nil + tbl=/^\{table(?:~h)?(?:\s+\d+;?)?\}\n(.+)\Z/m.match(t_o)[1] + hd=((t_o =~/^\{table~h/) ? true : false) + tbl,tags=extract_tags(tbl) + rws=tbl.split(/\n/) + rows='' + cols=nil + rws.each do |r| + cols=(cols ? cols : (r.scan('|').length) +1) + r=r.gsub(/\s*\|\s*/m,"#{Mx[:tc_p]}") #r.gsub!(/\|/m,"#{Mx[:tc_p]}") + rows += r + Mx[:tc_c] + end + col=[] + if t_o =~/^\{table(?:~h)?\s+(\d+);?\}/ #width of col 1 given as %, usually when wider than rest that are even + c1=$1.to_i + width=(100 - c1)/(cols - 1) + col=[ c1 ] + (cols - 1).times { col << width } + else #all columns of equal width + width=100.00/cols + cols.times { col << width } + end + h={ + head_: hd, + cols: cols, + widths: col, + obj: rows, + idx: idx, + tags: tags, + num: @num_id[:table], + } + t_o=SiSU_AO_DocumentStructure::ObjectTable.new.table(h) \ + unless h.nil? + tuned_file << t_o + h={ + is_for: :table, + obj: '', + sym: :table_close, + num: @num_id[:table], + } + t_o=SiSU_AO_DocumentStructure::ObjectLayout.new.open_close(h) + t_o + elsif t_o=~/^```[ ]+table(?:~h)?\s+/ + m1,m2,hd=nil,nil,nil + h=case t_o + when /^```[ ]+table~h\s+(.+?)\n(.+)\Z/m #two table representations should be consolidated as one + m1,tbl,hd=$1,$2,true + when /^```[ ]+table\s+(.+?)\n(.+)\Z/m #two table representations should be consolidated as one + m1,tbl,hd=$1,$2,false + else nil + end + tbl,tags=extract_tags(tbl) + col=m1.scan(/\d+/) + rws=tbl.split(/\n/) + rows='' + rws.each do |r| + r=r.gsub(/\s*\|\s*/m,"#{Mx[:tc_p]}") #r.gsub!(/\|/m,"#{Mx[:tc_p]}") + rows += r + Mx[:tc_c] + end + h={ + head_: hd, + cols: col.length, + widths: col, + obj: rows, + idx: idx, + tags: tags, + num: @num_id[:table], + } + t_o=SiSU_AO_DocumentStructure::ObjectTable.new.table(h) \ + unless h.nil? + tuned_file << t_o + h={ + is_for: :table, + obj: '', + sym: :table_close, + num: @num_id[:table], + } + t_o=SiSU_AO_DocumentStructure::ObjectLayout.new.open_close(h) + t_o + elsif t_o=~/^\{table(?:~h)?\s+/ + m1,m2,hd=nil,nil,nil + h=case t_o + when /\{table~h\s+(.+?)\}\n(.+)\Z/m #two table representations should be consolidated as one + m1,tbl,hd=$1,$2,true + when /\{table\s+(.+?)\}\n(.+)\Z/m #two table representations should be consolidated as one + m1,tbl,hd=$1,$2,false + else nil + end + tbl,tags=extract_tags(tbl) + col=m1.scan(/\d+/) + rws=tbl.split(/\n/) + rows='' + rws.each do |r| + r=r.gsub(/\s*\|\s*/m,"#{Mx[:tc_p]}") #r.gsub!(/\|/m,"#{Mx[:tc_p]}") + rows += r + Mx[:tc_c] + end + h={ + head_: hd, + cols: col.length, + widths: col, + obj: rows, + idx: idx, + tags: tags, + num: @num_id[:table], + } + t_o=SiSU_AO_DocumentStructure::ObjectTable.new.table(h) \ + unless h.nil? + tuned_file << t_o + h={ + is_for: :table, + obj: '', + sym: :table_close, + num: @num_id[:table], + } + t_o=SiSU_AO_DocumentStructure::ObjectLayout.new.open_close(h) + t_o +## } depreciated markup, code should (continue to) work for new markup after removal, +# when removing depreciated markup check only pass-through for new table attributes format +# table(.+?){ ``` table(.+?) {table(.+?)} formats + end + end + t_o + end + if @per.table==:curls or @per.table==:tics + if (@per.table==:curls \ + and (t_o.is_a?(String) and t_o =~/^\}table/)) \ + or (@per.table==:tics \ + and (t_o.is_a?(String) and t_o =~/^```(?:\s+[~-][#]|\s+\~\{.+?\}\~)?\s*$/)) + @per.table=:off + headings,columns,widths,idx=@h[:head_],@h[:cols],@h[:widths],@h[:idx] + @h={ + head_: headings, + cols: columns, + widths: widths, + idx: idx, + obj: @rows, + } + t_o=SiSU_AO_DocumentStructure::ObjectTable.new.table(@h) + tuned_file << t_o + @h,@rows=nil,'' + h={ + is_for: :table, + obj: '', + sym: :table_close, + num: @num_id[:table], + } + t_o=SiSU_AO_DocumentStructure::ObjectLayout.new.open_close(h) + t_o + else + if t_o.is_a?(String) \ + and t_o !~/^(?:table\{|```[ ]+table)/ + t_o=t_o.gsub(/^\n+/m,''). + gsub(/\n+/m,"#{Mx[:tc_p]}") + @rows += t_o + Mx[:tc_c] + end + t_o=nil + end + end + if @per.code==:curls \ + or @per.code==:tics + if (@per.code==:curls \ + && (t_o.is_a?(String) && t_o =~/^\}code/)) \ + or (@per.code==:tics \ + && (t_o.is_a?(String) && t_o =~/^```(?:\s+[~-][#]|\s+\~\{.+?\}\~)?\s*$/m) \ + ) + @per.code=:off + if @tuned_code[-1] + @tuned_code[-1]. + gsub!(/\s*(?:#{Mx[:br_line]}|#{Mx[:br_nl]})\s*\Z/m,'') + end + obj=@tuned_code.join("\n") + tags=[] + h={ + obj: obj, + idx: idx, + syntax: @per.lngsyn, + tags: tags, + num: @num_id[:code_block], + number_: @codeblock_numbered, + } + @per.lngsyn=:txt + t_o=SiSU_AO_DocumentStructure::ObjectBlockTxt.new.code(h) + @tuned_code=[] + tuned_file << t_o + h={ + is_for: :code, + obj: '', + sym: :code_close, + num: @num_id[:code_block], + } + t_o=SiSU_AO_DocumentStructure::ObjectLayout.new.open_close(h) + end + if (@per.code==:curls \ + || @per.code==:tics) \ + and t_o.is_a?(String) + sub_array=t_o.dup + "#{Mx[:br_nl]}" + @line_mode=[] + sub_array.scan(/.+/) {|w| @line_mode << w if w =~/[\S]+/} + t_o=SiSU_AO_DocumentStructureExtract::Build.new(@md,@line_mode).build_lines(:code).join + @tuned_code << t_o + t_o=nil + end + elsif (@per.poem==:curls \ + || @per.poem==:tics) \ + or (@per.box==:curls \ + || @per.box==:tics) \ + or (@per.group==:curls \ + || @per.group==:tics) \ + or (@per.block==:curls \ + || @per.block==:tics) \ + or (@per.alt==:curls \ + || @per.alt==:tics) \ + or (@per.quote==:open \ + && (t_o.is_a?(String) && t_o =~/`:quote_close`/m)) + if (@per.poem==:curls \ + && (t_o.is_a?(String) && t_o.to_s =~/^\}poem$/m)) \ + or (@per.poem==:tics \ + && (t_o.is_a?(String) && t_o =~/^```(?:\s+[~-][#]|\s+\~\{.+?\}\~)?\s*$/)) + @per.poem=:off + h={ + is_for: :poem, + obj: '', + idx: idx, + sym: :poem_close, + num: @num_id[:poem], + } + t_o=SiSU_AO_DocumentStructure::ObjectLayout.new.open_close(h) + elsif (@per.box==:curls \ + && (t_o.is_a?(String) && t_o =~/^\}box/)) \ + or (@per.box==:tics \ + && (t_o.is_a?(String) && t_o.to_s =~/^```(?:\s+[~-][#]|\s+\~\{.+?\}\~)?\s*$/)) + @per.box=:off + obj,tags=extract_tags(@tuned_block.join("\n")) + h={ + obj: obj, + idx: idx, + tags: tags, + num: @num_id[:box], + } + @tuned_block=[] + t_o=SiSU_AO_DocumentStructure::ObjectBlockTxt.new.box(h) + tuned_file << t_o + h={ + is_for: :box, + obj: '', + idx: idx, + sym: :box_close, + num: @num_id[:box], + } + t_o=SiSU_AO_DocumentStructure::ObjectLayout.new.open_close(h) + elsif (@per.group==:curls \ + && ( t_o.is_a?(String) && t_o.to_s =~/^\}group/)) \ + or (@per.group==:tics \ + && (t_o.is_a?(String) && t_o.to_s =~/^```(?:\s+[~-][#]|\s+\~\{.+?\}\~)?\s*$/)) + @per.group=:off + obj,tags=extract_tags(@tuned_block.join("\n")) + h={ + obj: obj, + idx: idx, + tags: tags, + num: @num_id[:group], + } + @tuned_block=[] + t_o=SiSU_AO_DocumentStructure::ObjectBlockTxt.new.group(h) + tuned_file << t_o + h={ + is_for: :group, + obj: '', + sym: :group_close, + num: @num_id[:group], + } + t_o=SiSU_AO_DocumentStructure::ObjectLayout.new.open_close(h) + elsif (@per.block==:curls \ + && t_o.to_s =~/^\}block/) \ + or (@per.block==:tics \ + && (t_o.is_a?(String) \ + && t_o =~/^```(?:\s+[~-][#]|\s+\~\{.+?\}\~)?\s*$/) \ + ) + @per.block=:off + obj,tags=extract_tags(@tuned_block.join("\n")) + h={ + obj: obj, + idx: idx, + tags: tags, + num: @num_id[:block], + } + @tuned_block=[] + t_o=SiSU_AO_DocumentStructure::ObjectBlockTxt.new.block(h) + tuned_file << t_o + h={ + is_for: :block, + obj: '', + sym: :block_close, + num: @num_id[:block], + } + t_o=SiSU_AO_DocumentStructure::ObjectLayout.new.open_close(h) + elsif (@per.alt==:curls \ + && (t_o.is_a?(String) && t_o =~/^\}alt/)) \ + or (@per.alt==:tics \ + && t_o.is_a?(String) \ + && (t_o =~/^```(?:\s+[~-][#]|\s+\~\{.+?\}\~)?\s*$/) + ) + @per.alt=:off + obj,tags=extract_tags(@tuned_block.join("\n")) + h={ + obj: obj, + idx: idx, + tags: tags, + num: @num_id[:alt], + } + t_o=SiSU_AO_DocumentStructure::ObjectBlockTxt.new.alt(h) + @tuned_block=[] + tuned_file << t_o + h={ + is_for: :alt, + obj: '', + sym: :alt_close, + num: @num_id[:alt], + } + t_o=SiSU_AO_DocumentStructure::ObjectLayout.new.open_close(h) + elsif @per.quote==:open \ + and (t_o.is_a?(String) && t_o =~/`:quote_close`/m) + @per.quote=:off + h={ + is_for: :quote, + idx: idx, + obj: '', + sym: :quote_close, + num: @num_id[:quote], + } + t_o=SiSU_AO_DocumentStructure::ObjectLayout.new.open_close(h) + elsif @per.quote==:open + t_o,tags=extract_tags(t_o) + h={ + indent: 1, + obj: t_o, + idx: idx, + note_: note, + image_: image, + tags: tags, + quote: quotes?, + } + SiSU_AO_DocumentStructure::ObjectPara.new.paragraph(h) + end + if (@per.poem==:curls \ + || @per.poem==:tics) \ + or (@per.group==:curls \ + || @per.group==:tics) \ + or (@per.block==:curls \ + || @per.block==:tics) \ + or (@per.alt==:curls \ + || @per.alt==:tics) \ + and (t_o.is_a?(String) \ + and t_o.to_s =~/\S/ \ + and t_o.to_s !~/^(?:\}(?:verse|code|box|alt|group|block)|(?:verse|code(?:\.[a-z][0-9a-z_]+)?|box(?:\.[a-z_]+)?|alt|group|block)\{)/ \ + and t_o.to_s !~/^```[ ]+(?:code(?:\.[a-z][0-9a-z_]+)?|box(?:\.[a-z_]+)?|poem|alt|group|block)|^```(?:\s+[~-][#]|\s+\~\{.+?\}\~)?\s*$/ + ) + sub_array=t_o.to_s.dup + @line_mode=sub_array.scan(/.+/) + type=if @per.poem==:curls or @per.poem==:tics + t_o=SiSU_AO_DocumentStructureExtract::Build.new(@md,@line_mode).build_lines(type).join + poem=t_o.split(/\n\n/) + poem.each do |v| + v=v.gsub(/\n/m,"#{Mx[:br_nl]}\n") + obj,tags=extract_tags(v) + h={ + obj: obj, + tags: tags, + num: @num_id[:poem], + } + t_o=SiSU_AO_DocumentStructure::ObjectBlockTxt.new.verse(h) + tuned_file << t_o + end + :poem + else :group + end + end + @verse_count+=1 if @per.poem==:curls or @per.poem==:tics + end + if @per.code==:off + if @per.poem==:curls or @per.poem==:tics \ + or @per.box==:curls or @per.box==:tics \ + or @per.group==:curls or @per.group==:tics \ + or @per.block==:curls or @per.block==:tics \ + or @per.alt==:curls or @per.alt==:tics \ + or (@per.quote==:open and t_o =~/`:quote_close`/m) + if t_o.is_a?(String) + t_o=t_o.gsub(/\n/m,"#{Mx[:br_nl]}"). + gsub(/[ ][ ]/m,"#{Mx[:nbsp]*2}"). + gsub(/#{Mx[:nbsp]}\s/,"#{Mx[:nbsp]*2}") + t_o=t_o + Mx[:br_nl] if t_o =~/\S+/ + elsif t_o.is==:group \ + || t_o.is==:block \ + || t_o.is==:alt \ + || t_o.is==:box \ + || t_o.is==:verse + t_o.obj=t_o.obj.gsub(/\n/m,"#{Mx[:br_nl]}"). + gsub(/[ ][ ]/m,"#{Mx[:nbsp]*2}"). + gsub(/#{Mx[:nbsp]}\s/,"#{Mx[:nbsp]*2}") + end + @tuned_block << t_o if t_o.to_s =~/\S+/ + else tuned_file << t_o + end + else tuned_file << t_o + end + end + tuned_file + end + def identify_parts + tuned_file=[] + @tuned_block,@tuned_code=[],[] + @@counter,@verse_count=0,0 + @num_id={ + code_block: 0, + poem: 0, + box: 0, + block: 0, + group: 0, + alt: 0, + quote: 0, + table: 0, + } + @metadata={} + if @md.flag_auto_biblio \ + or @md.flag_biblio + @data,bibliography=SiSU_AO_Appendices::Bibliography.new(@md,@data).biblio_extraction + end + if @md.flag_glossary + @data,glossary=SiSU_AO_Appendices::Glossary.new(@md,@data).glossary_extraction + end + tuned_file=extract_structure_loop(@data,tuned_file) + if @md.flag_endnotes + tuned_file << @pb + h={ + ln: 1, + lc: 1, + obj: 'Endnotes', + autonum_: false, + } + tuned_file << SiSU_AO_DocumentStructure::ObjectHeading.new.heading_insert(h) + h={ + ln: 4, + lc: 2, + obj: 'Endnotes', + name: 'endnotes', + autonum_: false, + } + tuned_file << SiSU_AO_DocumentStructure::ObjectHeading.new.heading_insert(h) + h={ + obj: 'Endnotes' + } + end + if @md.flag_glossary + tuned_file << @pb + h={ + ln: 1, + lc: 1, + obj: 'Glossary', + autonum_: false, + } + tuned_file << SiSU_AO_DocumentStructure::ObjectHeading.new.heading_insert(h) + h={ + ln: 4, + lc: 2, + obj: 'Glossary', + name: 'glossary', + autonum_: false, + } + tuned_file << SiSU_AO_DocumentStructure::ObjectHeading.new.heading_insert(h) + h={ + obj: 'Glossary' + } + if glossary.length > 0 + tuned_file=extract_structure_loop(glossary,tuned_file) + end + end + if @md.flag_auto_biblio + tuned_file << @pb + h={ + ln: 1, + lc: 1, + obj: 'References', + autonum_: false, + } + tuned_file << SiSU_AO_DocumentStructure::ObjectHeading.new.heading_insert(h) + h={ + ln: 4, + lc: 2, + obj: 'Bibliography', + name: 'biblio', + autonum_: false, + } + tuned_file << SiSU_AO_DocumentStructure::ObjectHeading.new.heading_insert(h) + h={ + obj: 'Bibliography' + } + citenumber=0 + bibliography.each do |cite| + citenumber +=1 if cite.is_a?(Hash) + h={ + obj: cite[:obj], + #obj: %{[#{citenumber}] } + cite[:obj], + tags: [cite[:id]], + hang: 0, + indent: 2, + ocn_: false, + } + tuned_file << SiSU_AO_DocumentStructure::ObjectPara.new.paragraph(h) + end + elsif @md.flag_biblio + tuned_file << @pb + h={ + ln: 1, + lc: 1, + obj: 'References', + autonum_: false, + } + tuned_file << SiSU_AO_DocumentStructure::ObjectHeading.new.heading_insert(h) + h={ + ln: 4, + lc: 2, + obj: 'Bibliography', + name: 'biblio', + autonum_: false, + } + tuned_file << SiSU_AO_DocumentStructure::ObjectHeading.new.heading_insert(h) + h={ + obj: 'Bibliography' + } + if not bibliography.nil? \ + and bibliography.length > 0 + tuned_file=extract_structure_loop(bibliography,tuned_file) + else + tuned_file, citations = + SiSU_AO_Appendices::Citations.new(@md,tuned_file).songsheet # ao_appendices.rb + citenumber=0 + citations.compact.each do |c| + citenumber +=1 if c.is_a?(Hash) + if c[:is]==:book + h={ + obj: %{#{c[:author]}. /{#{c[:publication]}}/ (#{c[:year]})}, + #obj: %{[#{citenumber}] *{#{c[:author]}}* /{#{c[:publication]}}/ (#{c[:year]})}, + hang: 0, + indent: 2, + ocn_: false, + } + tuned_file << SiSU_AO_DocumentStructure::ObjectPara.new.paragraph(h) + elsif c[:is]==:article + h={ + obj: %{#{c[:author]}. /{"#{c[:title]}"}/ #{c[:publication]} editor #{c[:editor]} (#{c[:year]})}, + #obj: %{[#{citenumber}] *{#{c[:author]}}* /{"#{c[:title]}"}/ #{c[:publication]} editor #{c[:editor]} (#{c[:year]})}, + hang: 0, + indent: 2, + ocn_: false, + } + tuned_file << SiSU_AO_DocumentStructure::ObjectPara.new.paragraph(h) + end + end + end + end + if @md.book_idx + tuned_file << @pb + h={ + ln: 1, + lc: 1, + obj: 'Index', + autonum_: false, + } + tuned_file << SiSU_AO_DocumentStructure::ObjectHeading.new.heading_insert(h) + h={ + ln: 4, + lc: 2, + obj: 'Index', + name: 'book_index', + autonum_: false, + } + tuned_file << SiSU_AO_DocumentStructure::ObjectHeading.new.heading_insert(h) + h={ + obj: 'Index' + } + end + tuned_file << @pb + if @make.build.metadata? + h={ + ln: 1, + lc: 1, + obj: 'Metadata', + autonum_: false, + ocn_: false, + } + tuned_file << SiSU_AO_DocumentStructure::ObjectHeading.new.heading_insert(h) + h={ + ln: 4, + lc: 2, + obj: 'SiSU Metadata, document information', + name: 'metadata', + autonum_: false, + ocn_: false, + } + tuned_file << SiSU_AO_DocumentStructure::ObjectHeading.new.heading_insert(h) + end + h={ + obj: 'eof', + } + meta=SiSU_AO_DocumentStructure::ObjectMetadata.new.metadata(@metadata) + [tuned_file,meta,bibliography,glossary] + end + def table_rows_and_columns_array(table_str) + table=[] + table_str.split(/#{Mx[:tc_c]}/).each do |table_row| + table_row_with_columns=table_row.split(/#{Mx[:tc_p]}/) + table << table_row_with_columns + end + table + end + def meta_heading(h) + h={ + lv: h[:lv], + ln: h[:ln], + name: h[:name], + obj: h[:obj], + ocn: '0', + } + SiSU_AO_DocumentStructure::ObjectHeading.new.heading(h) + end + def meta_para(str) + h={ + obj: str, + ocn_: false, + } + SiSU_AO_DocumentStructure::ObjectPara.new.paragraph(h) + end + def build_lines(type=:none) + lines=@data + lines.each.map do |line| + line=if line =~/\S/ \ + and line !~/^(?:code(?:\.[a-z][0-9a-z_]+)?\{|\}code)/ \ + and line !~/^(?:```[ ]+code(?:\.[a-z][0-9a-z_]+)?|```(?:\s+[~-][#]|\s+\~\{.+?\}\~)?\s*$)/ \ + and not line.is_a?(Hash) #watch + @@counter+=1 if @per.code==:curls or @per.code==:tics + line=line.gsub(/\s\s/,"#{Mx[:nbsp]*2}"). + gsub(/#{Mx[:nbsp]}\s/,"#{Mx[:nbsp]*2}") + line=line.gsub(/^/,"#{Mx[:gr_o]}codeline#{Mx[:gr_c]}") if type==:code # REMOVE try sort for texpdf special case + line=if line =~/(?:https?|file|ftp):\/\/\S+$/ + line.gsub(/\s*$/," #{Mx[:br_nl]}") + else line.gsub(/\s*$/,"#{Mx[:br_nl]}") #unless type=='code' + end + elsif line =~/^\s*$/ + line.gsub(/\s*$/,"#{Mx[:br_nl]}") + else line + end + line + end + end + end + class Structure # this must happen early + def initialize(md) + @md=md + end + def structure(data) + data.compact.each do |dob| + structure_markup(dob) + end + end + def structure_markup(dob) #build structure where structure provided only in meta header + dob=if dob.is==:para \ + && (((dob.hang !~/[1-9]/) && (dob.indent !~/[1-9]/)) \ + || (dob.hang != dob.indent)) \ + and not dob.bullet_ + dob=case dob.obj + when /^#{@md.lv0}/ + h={ + is: :heading, + lv: 'A', + ln: 0, + } + SiSU_AO_DocumentStructure::ObjectHeading.new.heading(h,dob) + when /^#{@md.lv1}/ + h={ + is: :heading, + lv: 'B', + ln: 1, + } + SiSU_AO_DocumentStructure::ObjectHeading.new.heading(h,dob) + when /^#{@md.lv2}/ + h={ + is: :heading, + lv: 'C', + ln: 2, + } + SiSU_AO_DocumentStructure::ObjectHeading.new.heading(h,dob) + when /^#{@md.lv3}/ + h={ + is: :heading, + lv: 'D', + ln: 3, + } + SiSU_AO_DocumentStructure::ObjectHeading.new.heading(h,dob) + when /^#{@md.lv4}/ + h={ + is: :heading, + lv: '1', + ln: 4, + } + SiSU_AO_DocumentStructure::ObjectHeading.new.heading(h,dob) + when /^#{@md.lv5}/ + h={ + is: :heading, + lv: '2', + ln: 5, + } + SiSU_AO_DocumentStructure::ObjectHeading.new.heading(h,dob) + when /^#{@md.lv6}/ + h={ + is: :heading, + lv: '3', + ln: 6, + } + SiSU_AO_DocumentStructure::ObjectHeading.new.heading(h,dob) + else dob + end + else dob + end + dob + end + end + class OCN + def initialize(md,data,fnx,process) + @md,@data,@fnx,@process=md,data,fnx,process + end + def structure_info + def lv + %w[A~ B~ C~ D~ 1 2 3 4] + end + def possible_parents(child) + case child + when /A~/ then 'none' + when /B~/ then 'A~' + when /C~/ then 'B~' + when /D~/ then 'C~' + when /1/ then 'A~, B~, C~, D~' + when /2/ then '1' + when /3/ then '2' + when /4/ then '3' + end + end + def possible_children(parent) + case parent + when /A~/ then 'B~, 1' + when /B~/ then 'C~, 1' + when /C~/ then 'D~, 1' + when /D~/ then '1' + when /1/ then '2' + when /2/ then '3' + when /3/ then '4' + when /4/ then 'none' + end + end + self + end + def document_structure_check_info(node,node_parent,status=:ok) + node_ln=/^([0-7])/.match(node)[1].to_i + node_parent_ln=/^([0-7])/.match(node_parent)[1].to_i + if status==:error \ + or @md.opt.act[:maintenance][:set]==:on + puts %{node: #{node}, parent node: #{node_parent} #{status.upcase}} + if status==:error + node_ln=/^([0-7])/.match(node)[1].to_i + node_parent_ln=/^([0-7])/.match(node_parent)[1].to_i + STDERR.puts %{current level: #{structure_info.lv[node_ln]} (possible parent levels: #{structure_info.possible_parents(structure_info.lv[node_ln])}) +parent level: #{structure_info.lv[node_parent_ln]} (possible child levels: #{structure_info.possible_children(structure_info.lv[node_parent_ln])}) +SKIPPED processing file: +[#{@md.opt.lng}] "#{@md.fns}"} + if @md.opt.act[:no_stop][:set]==:on + $process_document = :skip + else exit + end + end + end + end + def warning_incorrect_parent_level_or_level(txt) + puts %{ERROR. There is an error in markup of heading levels either here or in the parent heading. +The current header reads: +"#{txt}" +has incorrect level and/or parent level +--} + end + def required_headers_present? + if @process == :complete + unless (defined? @md.title \ + and @md.title.full) + STDERR.puts %{required header missing: + +@title: +SKIPPED processing file: +[#{@md.opt.lng}] "#{@md.fns}" +} + if @md.opt.act[:no_stop][:set]==:on + $process_document = :skip + else exit + end + end + unless (defined? @md.creator.author \ + and @md.creator.author) + STDERR.puts %{required header missing: + +@creator: + :author: anonymous? +SKIPPED processing file: +[#{@md.opt.lng}] "#{@md.fns}" +} + if @md.opt.act[:no_stop][:set]==:on + $process_document = :skip + else exit + end + end + end + end + def ocn #and auto segment numbering increment + required_headers_present? + data=@data + @o_array=[] + node=ocn=ocn_dv=ocn_sp=ocnh=ocnh0=ocnh1=ocnh2=ocnh3=ocnh4=ocnh5=ocnh6=ocnh7=ocno=ocnp=ocnt=ocnc=ocng=ocni=ocnu=0 # h heading, o other, t table, g group, i image + regex_exclude_ocn_and_node = /#{Rx[:meta]}|^@\S+?:\s|^4~endnotes|^#{Mx[:lv_o]}4:endnotes#{Mx[:lv_c]}|^\^~ |<:e[:_]\d+?>|^<:\#|<:- |<[:!]!4|<hr width|#{Mx[:br_endnotes]}|\A\s*\Z/mi #ocn here #  added with Tune.code #¡ + parent=node1=node2=node3=node4=node5=node6=node7=nil + node0='0:0;0' + @collapsed_lv0=0 + @lev_occurences={ a: 0, b: 0, c: 0, d: 0, l1: 0, l2: 0, l3: 0, l4: 0 } + data.each do |dob| + h={} + if (dob.obj !~ regex_exclude_ocn_and_node || dob.is==:code) \ + && (dob.of !=:comment \ + && dob.of !=:layout \ + && dob.of !=:meta) \ + && dob.ocn_ + #dob.ln now is determined, and set earlier, check how best to remove this --> + if dob.is==:heading + @ln=ln=case dob.lv + when 'A' then 0 + when 'B' then 1 + when 'C' then 2 + when 'D' then 3 + when '1' then 4 + when '2' then 5 + when '3' then 6 + when '4' then 7 + when '5' then 8 + when '6' then 9 + end + end + if not dob.obj =~/~#|-#/ + ocn+=1 + end + if @process == :complete \ + or (@fnx == @md.opt.fns \ + && @md.opt.fns =~/.sst$/) + if dob.is==:heading \ + and (ln.to_s =~/^[0-9]/ \ + or ln.to_s =~@md.lv0 \ + or ln.to_s =~@md.lv1 \ + or ln.to_s =~@md.lv2 \ + or ln.to_s =~@md.lv3 \ + or ln.to_s =~@md.lv4 \ + or ln.to_s =~@md.lv5 \ + or ln.to_s =~@md.lv6 \ + or ln.to_s =~@md.lv7) + if not dob.obj =~/~#|-#/ + ocnh+=1 + end + if ln==0 \ + or ln.to_s =~@md.lv0 + @lev_occurences[:a] += 1 + if not dob.obj =~/~#|-#/ + ocn_flag=true + ocnh0+=1 #heading + node0="0:#{ocnh0};#{ocn}" + else + #document_structure_check_info(node0,node0,:error) #fix + ocn_flag=false + node0="0:0;0" + end + document_structure_check_info(node0,node0) + @collapsed_lv0=0 + collapsed_level=@collapsed_lv0 + node,ocn_sp,parent=node0,"h#{ocnh}",'ROOT' + elsif ln==1 \ + or ln.to_s =~@md.lv1 + @lev_occurences[:b] += 1 + if not dob.obj =~/~#|-#/ + ocn_flag=true + ocnh1+=1 #heading + node1="1:#{ocnh1};#{ocn}" + else + #document_structure_check_info(node0,node0,:error) #fix + ocn_flag=false + node1="1:0;0" + end + parent=if node0 + document_structure_check_info(node1,node0) + @collapsed_lv1=@collapsed_lv0+1 + node0 + else + warning_incorrect_parent_level_or_level(dob.obj) + document_structure_check_info(node0,node0,:error) + node0 + end + collapsed_level=@collapsed_lv1 + node,ocn_sp,parent=node1,"h#{ocnh}",node0 #FIX + elsif ln==2 \ + or ln.to_s =~@md.lv2 + @lev_occurences[:c] += 1 + if not dob.obj =~/~#|-#/ + ocn_flag=true + ocnh2+=1 + node2="2:#{ocnh2};#{ocn}" + else + #document_structure_check_info(node0,node0,:error) #fix + ocn_flag=false + node2="2:0;0" + end + parent=if node1 + document_structure_check_info(node2,node1) + @collapsed_lv2=@collapsed_lv1+1 + node1 + else + warning_incorrect_parent_level_or_level(dob.obj) + document_structure_check_info(node2,node0,:error) + node0 + end + collapsed_level=@collapsed_lv2 + node,ocn_sp=node2,"h#{ocnh}" + elsif ln==3 \ + or ln.to_s =~@md.lv3 + @lev_occurences[:d] += 1 + if not dob.obj =~/~#|-#/ + ocn_flag=true + ocnh3+=1 + node3="3:#{ocnh3};#{ocn}" + else + #document_structure_check_info(node0,node0,:error) #fix + ocn_flag=false + node3="3:0;0" + end + parent=if node2 + document_structure_check_info(node3,node2) + @collapsed_lv3=@collapsed_lv2+1 + node2 + elsif node1 + warning_incorrect_parent_level_or_level(dob.obj) + puts %{parent is :A~ & this level #{dob.lv} +either parent should be level :B~ +or this level should be level :B~ rather than #{dob.lv}} + document_structure_check_info(node3,node1,:error) + @collapsed_lv3=@collapsed_lv1+1 + node1 + else + document_structure_check_info(node3,node0,:error) + warning_incorrect_parent_level_or_level(dob.obj) + node0 + end + collapsed_level=@collapsed_lv3 + node,ocn_sp=node3,"h#{ocnh}" + elsif ln==4 \ + or ln.to_s =~@md.lv4 + @lev_occurences[:l1] += 1 + if not dob.obj =~/~#|-#/ + ocn_flag=true + ocnh4+=1 + node4="4:#{ocnh4};#{ocn}" + else + ocn_flag=false + node4="4:0;0" + end + parent=if node3 + document_structure_check_info(node4,node3) + @collapsed_lv4=@collapsed_lv3+1 + node3 + elsif node2 + document_structure_check_info(node4,node2) + @collapsed_lv4=@collapsed_lv2+1 + node2 + elsif node1 + document_structure_check_info(node4,node1) + @collapsed_lv4=@collapsed_lv1+1 + node1 + elsif node0 + document_structure_check_info(node4,node0) + @collapsed_lv4=@collapsed_lv0+1 + node0 + else + warning_incorrect_parent_level_or_level(dob.obj) + document_structure_check_info(node4,node0,:error) + node0 + end + collapsed_level=@collapsed_lv4 + node,ocn_sp=node4,"h#{ocnh}" + elsif ln==5 \ + or ln.to_s =~@md.lv5 + @lev_occurences[:l2] += 1 + if not dob.obj =~/~#|-#/ + ocn_flag=true + ocnh5+=1 + node5="5:#{ocnh5};#{ocn}" + else + ocn_flag=false + node5="5:0;0" + end + parent=if node4 + document_structure_check_info(node5,node4) + @collapsed_lv5=@collapsed_lv4+1 + node4 + elsif node3 + warning_incorrect_parent_level_or_level(dob.obj) + document_structure_check_info(node5,node3,:error) + @collapsed_lv5=@collapsed_lv3+1 + node3 + elsif node2 + warning_incorrect_parent_level_or_level(dob.obj) + document_structure_check_info(node5,node2,:error) + @collapsed_lv5=@collapsed_lv2+1 + node2 + elsif node1 + warning_incorrect_parent_level_or_level(dob.obj) + document_structure_check_info(node5,node1,:error) + @collapsed_lv5=@collapsed_lv1+1 + node1 + else + warning_incorrect_parent_level_or_level(dob.obj) + document_structure_check_info(node5,node0,:error) + node0 + end + collapsed_level=@collapsed_lv5 + node,ocn_sp=node5,"h#{ocnh}" + elsif ln==6 \ + or ln.to_s =~@md.lv6 + @lev_occurences[:l3] += 1 + if not dob.obj =~/~#|-#/ + ocn_flag=true + ocnh6+=1 + node6="6:#{ocnh6};#{ocn}" + else + ocn_flag=false + node6="6:0;0" + end + parent=if node5 + document_structure_check_info(node6,node5) + @collapsed_lv6=@collapsed_lv5+1 + node5 + elsif node4 + warning_incorrect_parent_level_or_level(dob.obj) + puts "parent is level #4 (1~) & this level ##{dob.ln} (#{dob.lv}~) +either parent should be level #5 (2~) +or this level should be #5 (2~) rather ##{dob.ln} (#{dob.lv}~)" + document_structure_check_info(node6,node4,:error) + @collapsed_lv6=@collapsed_lv4+1 + node4 + elsif node3 + warning_incorrect_parent_level_or_level(dob.obj) + document_structure_check_info(node6,node3,:error) + @collapsed_lv6=@collapsed_lv3+1 + node3 + elsif node2 + warning_incorrect_parent_level_or_level(dob.obj) + document_structure_check_info(node6,node2,:error) + @collapsed_lv6=@collapsed_lv2+1 + node2 + elsif node1 + warning_incorrect_parent_level_or_level(dob.obj) + document_structure_check_info(node6,node1,:error) + @collapsed_lv6=@collapsed_lv1+1 + node1 + else + warning_incorrect_parent_level_or_level(dob.obj) + document_structure_check_info(node6,node0,:error) + node0 + end + collapsed_level=@collapsed_lv6 + node,ocn_sp=node6,"h#{ocnh}" + elsif ln==7 \ + or ln.to_s =~@md.lv7 + @lev_occurences[:l4] += 1 + if not dob.obj =~/~#|-#/ + ocn_flag=true + ocnh7+=1 + node7="7:#{ocnh7};#{ocn}" + else + ocn_flag=false + node7="7:0;0" + end + parent=if node6 + document_structure_check_info(node7,node6) + @collapsed_lv7=@collapsed_lv6+1 + node5 + elsif node5 + warning_incorrect_parent_level_or_level(dob.obj) + puts "parent is level #5 (2~) & this level ##{dob.ln} (#{dob.lv}~) +either parent should be level #6 (3~) +or this level should be #6 (3~) rather ##{dob.ln} (#{dob.lv}~)" + document_structure_check_info(node7,node5,:error) + @collapsed_lv6=@collapsed_lv5+1 + node5 + elsif node4 + warning_incorrect_parent_level_or_level(dob.obj) + puts "parent is level #4 (1~) & this level ##{dob.ln} (#{dob.lv}~) +either parent should be level 6~ +or this level should be #6 (3~) rather ##{dob.ln} (#{dob.lv}~)" + document_structure_check_info(node7,node4,:error) + @collapsed_lv6=@collapsed_lv4+1 + node4 + elsif node3 + warning_incorrect_parent_level_or_level(dob.obj) + document_structure_check_info(node7,node3,:error) + @collapsed_lv6=@collapsed_lv3+1 + node3 + elsif node2 + warning_incorrect_parent_level_or_level(dob.obj) + document_structure_check_info(node7,node2,:error) + @collapsed_lv6=@collapsed_lv2+1 + node2 + elsif node1 + warning_incorrect_parent_level_or_level(dob.obj) + document_structure_check_info(node7,node1,:error) + @collapsed_lv6=@collapsed_lv1+1 + node1 + else + warning_incorrect_parent_level_or_level(dob.obj) + document_structure_check_info(node7,node0,:error) + node0 + end + collapsed_level=@collapsed_lv7 + node,ocn_sp=node7,"h#{ocnh}" + end + else + unless @lev_occurences[:l1] > 0 + STDERR.puts %{Substantive text objects must follow a level 1~ heading and there are none at this point in processing: #{@lev_occurences[:l1]} +SKIPPED processing file: +[#{@md.opt.lng}] "#{@md.fns}"} + puts dob.obj #.gsub(/^(.{1,80})/,'"\1"') + exit + end + unless @ln >= 4 + lev=case @ln + when 0 then 'A' + when 1 then 'B' + when 2 then 'C' + when 3 then 'D' + when 4 then '1' + when 5 then '2' + when 6 then '3' + when 7 then '4' + when 8 then '5' + when 9 then '6' + end + STDERR.puts %{Substantive text objects must follow a level 1~ 2~ or 3~ heading: #{lev}~ +SKIPPED processing file: +[#{@md.opt.lng}] "#{@md.fns}"} + puts dob.obj.gsub(/^(.{1,80})/,'"\1"') + if @md.opt.act[:no_stop][:set]==:on + $process_document = :skip + break + else exit + end + end + if not dob.obj =~/~#|-#/ + ocn_flag=true + else + ocn_flag=false + end + ocno+=1 + if dob.is==:table + ocnt+=1 + ocn_sp,parent="t#{ocnt}",node + elsif dob.is==:code + ocnc+=1 + ocn_sp,parent="c#{ocnc}",node + elsif dob.is==:group \ + || dob.is==:box \ + || dob.is==:block \ + || dob.is==:alt \ + || dob.is==:verse + ocng+=1 #group, poem + ocn_sp,parent="g#{ocng}",node + elsif dob.is==:image #check + ocni+=1 + ocn_sp,parent="i#{ocni}",node + else ocnp+=1 #paragraph + ocn_sp,parent="p#{ocnp}",node + end + end + end + if dob.is==:heading + if ocn_flag==true + dob.ln,dob.node,dob.ocn,dob.ocn_,dob.odv,dob.osp,dob.parent,dob.lc= + ln, node, ocn, ocn_flag, ocn_dv,ocn_sp, parent, collapsed_level + else + ocnu+=1 + heading_use=:ok + if dob.obj=~/#{Mx[:pa_non_object_no_heading]}/ + dob.obj=dob.obj.gsub(/#{Mx[:pa_non_object_no_heading]}/,'') + heading_use=:ok + elsif dob.obj=~/#{Mx[:pa_non_object_dummy_heading]}/ + dob.obj=dob.obj.gsub(/#{Mx[:pa_non_object_dummy_heading]}/,'') + heading_use=:dummy + end + dob.ln,dob.node,dob.ocn,dob.ocn_,dob.use_, dob.odv,dob.osp,dob.parent,dob.lc= + ln, node, nil, ocn_flag,heading_use,ocn_dv, ocn_sp, parent, collapsed_level + end + else + if dob.of !=:meta \ + && dob.of !=:comment \ + && dob.of !=:layout + if ocn_flag == true + dob.ocn,dob.ocn_,dob.odv,dob.osp,dob.parent= + ocn, ocn_flag,ocn_dv, ocn_sp, parent + else + ocnu+=1 + dob.obj=dob.obj.gsub(/#{Mx[:fa_o]}[~-]##{Mx[:fa_c]}/,'') if dob.obj + ocn_dv,ocn_sp="u#{ocnu}","u#{ocnu}" + dob.ocn,dob.ocn_,dob.odv,dob.osp,dob.parent= + nil, ocn_flag,ocn_dv, ocn_sp, parent + end + end + end + h + else dob + end + if dob.is==:code \ + || dob.is==:verse \ + || dob.is==:alt \ + || dob.is==:box \ + || dob.is==:group \ + || dob.is==:block + dob.obj=dob.obj.gsub(/\n+/,"\n") #newlines taken out + end + @o_array << dob + end + if @process == :complete \ + or (@fnx == @md.opt.fns \ + && @md.opt.fns =~/.sst$/) + unless @lev_occurences[:a] == 1 + STDERR.puts %{The number of level A~ in this document: #{@lev_occurences[:a]} +There must be one level A~ (no more and no less) +SKIPPED processing file: +[#{@md.opt.lng}] "#{@md.fns}"} + if @md.opt.act[:no_stop][:set]==:on + $process_document = :skip + else exit + end + end + unless @lev_occurences[:l1] > 0 + STDERR.puts %{The number of level 1~ in this document: #{@lev_occurences[:l1]} +There must be at least one level 1~ (and as many as required) +SKIPPED processing file: +[#{@md.opt.lng}] "#{@md.fns}"} + if @md.opt.act[:no_stop][:set]==:on + $process_document = :skip + else exit + end + end + end + @o_array + end + end + class XML + def initialize(md,data) + @data,@md=data,md + end + def dom + @s=[ 'A', 'B', 'C', 'D', '1', '2', '3' ] + tuned_file=structure_build + tuned_file + end + def spaces + Ax[:spaces] + end + def structure_build + data=@data + tuned_file=[] + hs=[0,false,false,false] + t={ + lv: @s[0], + status: :open, + } + tuned_file << tags(t) + if @md.opt.act[:verbose_plus][:set]==:on + puts "\nXML sisu structure outline --->\n" + puts "<#{@s[0]}>" + end + data.each_with_index do |o,i| + if o.is==:heading \ + || o.is==:heading_insert + case o.ln + when 0 + tuned_file << tag_close(o.ln,hs) + tuned_file << tag_open(o,@s) + if @md.opt.act[:verbose_plus][:set]==:on + puts_tag_close(o.ln,hs) + puts_tag_open(o,@s) + end + hs=[0,true,false,false,false] + when 1 + tuned_file << tag_close(o.ln,hs) + tuned_file << tag_open(o,@s) + if @md.opt.act[:verbose_plus][:set]==:on + puts_tag_close(o.ln,hs) + puts_tag_open(o,@s) + end + hs=[1,true,true,false,false] + when 2 + tuned_file << tag_close(o.ln,hs) + tuned_file << tag_open(o,@s) + if @md.opt.act[:verbose_plus][:set]==:on + puts_tag_close(o.ln,hs) + puts_tag_open(o,@s) + end + hs=[2,true,true,true,false] + when 3 + tuned_file << tag_close(o.ln,hs) + tuned_file << tag_open(o,@s) + if @md.opt.act[:verbose_plus][:set]==:on + puts_tag_close(o.ln,hs) + puts_tag_open(o,@s) + end + hs=[3,true,true,true,true] + when 4 + tuned_file << tag_close(o.ln,hs) + tuned_file << tag_open(o,@s) + if @md.opt.act[:verbose_plus][:set]==:on + puts_tag_close(o.ln,hs) + puts_tag_open(o,@s) + end + hs[0]=4 + when 5 + tuned_file << tag_close(o.ln,hs) + tuned_file << tag_open(o,@s) + if @md.opt.act[:verbose_plus][:set]==:on + puts_tag_close(o.ln,hs) + puts_tag_open(o,@s) + end + hs[0]=5 + when 6 + tuned_file << tag_close(o.ln,hs) + tuned_file << tag_open(o,@s) + if @md.opt.act[:verbose_plus][:set]==:on + puts_tag_close(o.ln,hs) + puts_tag_open(o,@s) + end + hs[0]=6 + end + end + tuned_file << o + end + if @md.opt.act[:verbose_plus][:set]==:on + puts_tag_close(0,hs) + end + tuned_file << tag_close(0,hs) + tuned_file=tuned_file.flatten + end + def tags(o) + tag=(o[:status]==:open) \ + ? %{<#{o[:lv]} id="#{o[:node]}">} + : "</#{o[:lv]}>" + ln=case o[:lv] + when 'A' then 0 + when 'B' then 1 + when 'C' then 2 + when 'D' then 3 + when '1' then 4 + when '2' then 5 + when '3' then 6 + when '4' then 7 + when '5' then 8 + when '6' then 9 + end + h={ + tag: tag, + node: o[:node], + lv: o[:lv], + ln: ln, + status: o[:status], + } + SiSU_AO_DocumentStructure::ObjectStructure.new.xml_dom(h) #downstream code utilise else ignore like comments + end + def tag_open(o,tag) + t={ lv: tag[o.ln], node: o.node, status: :open } + t_o=tags(t) + t_o + end + def tag_close(lev,hs) + ary=[] + case hs[0] + when 0 + if (lev <= 0) and hs[0] + t={ + lv: @s[0], + status: :close, + } + ary << tags(t) + end + when 1 + if (lev <= 1) and hs[1] + t={ + lv: @s[1], + status: :close, + } + ary << tags(t) + end + if (lev==0) + t={ + lv: @s[0], + status: :close, + } + ary << tags(t) + end + when 2 + if (lev <= 2) and hs[2] + t={ + lv: @s[2], + status: :close, + } + ary << tags(t) + end + if (lev <= 1) and hs[1] + t={ + lv: @s[1], + status: :close, + } + ary << tags(t) + end + if (lev==0) + t={ + lv: @s[0], + status: :close, + } + ary << tags(t) + end + when 3 + if (lev <= 3) and hs[3] + t={ + lv: @s[3], + status: :close, + } + ary << tags(t) + end + if (lev <= 2) and hs[2] + t={ + lv: @s[2], + status: :close, + } + ary << tags(t) + end + if (lev <= 1) and hs[1] + t={ + lv: @s[1], + status: :close, + } + ary << tags(t) + end + if (lev==0) + t={ + lv: @s[0], + status: :close, + } + ary << tags(t) + end + when 4 + if (lev <= 4) + t={ + lv: @s[4], + status: :close, + } + ary << tags(t) + end + if (lev <= 3) and hs[3] + t={ + lv: @s[3], + status: :close, + } + ary << tags(t) + end + if (lev <= 2) and hs[2] + t={ + lv: @s[2], + status: :close, + } + ary << tags(t) + end + if (lev <= 1) and hs[1] + t={ + lv: @s[1], + status: :close, + } + ary << tags(t) + end + if (lev==0) + t={ + lv: @s[0], + status: :close, + } + ary << tags(t) + end + when 5 + if (lev <= 5) + t={ + lv: @s[5], + status: :close, + } + ary << tags(t) + end + if (lev <= 4) + t={ + lv: @s[4], + status: :close, + } + ary << tags(t) + end + if (lev <= 3) and hs[3] + t={ + lv: @s[3], + status: :close, + } + ary << tags(t) + end + if (lev <= 2) and hs[2] + t={ + lv: @s[2], + status: :close, + } + ary << tags(t) + end + if (lev <= 1) and hs[1] + t={ + lv: @s[1], + status: :close, + } + ary << tags(t) + end + if (lev==0) + t={ + lv: @s[0], + status: :close, + } + ary << tags(t) + end + when 6 + if (lev <= 6) + t={ + lv: @s[6], + status: :close, + } + ary << tags(t) + end + if (lev <= 5) + t={ + lv: @s[5], + status: :close, + } + ary << tags(t) + end + if (lev <= 4) + t={ + lv: @s[4], + status: :close, + } + ary << tags(t) + end + if (lev <= 3) and hs[3] + t={ + lv: @s[3], + status: :close, + } + ary << tags(t) + end + if (lev <= 2) and hs[2] + t={ + lv: @s[2], + status: :close, + } + ary << tags(t) + end + if (lev <= 1) and hs[1] + t={ + lv: @s[1], + status: :close, + } + ary << tags(t) + end + if (lev==0) + t={ + lv: @s[0], + status: :close, + } + ary << tags(t) + end + end + ary + end + def puts_tag_open(o,tag) + puts %{#{spaces*o.ln}<#{tag[o.ln]} id="#{o.node}">} + end + def puts_tag_close(lev,hs) + case hs[0] + when 0 + #puts "#{spaces*0}</#{@s[0]}>" if (lev <= 0) and hs[0] + puts "</#{@s[0]}>" if (lev==0) + when 1 + puts "#{spaces*1}</#{@s[1]}>" if (lev <= 1) and hs[1] + puts "</#{@s[0]}>" if (lev==0) + when 2 + puts "#{spaces*2}</#{@s[2]}>" if (lev <= 2) and hs[2] + puts "#{spaces*1}</#{@s[1]}>" if (lev <= 1) and hs[1] + puts "</#{@s[0]}>" if (lev==0) + when 3 + puts "#{spaces*3}</#{@s[3]}>" if (lev <= 3) and hs[3] + puts "#{spaces*2}</#{@s[2]}>" if (lev <= 2) and hs[2] + puts "#{spaces*1}</#{@s[1]}>" if (lev <= 1) and hs[1] + puts "</#{@s[0]}>" if (lev==0) + when 4 + puts "#{spaces*4}</#{@s[4]}>" if (lev <= 4) + puts "#{spaces*3}</#{@s[3]}>" if (lev <= 3) and hs[3] + puts "#{spaces*2}</#{@s[2]}>" if (lev <= 2) and hs[2] + puts "#{spaces*1}</#{@s[1]}>" if (lev <= 1) and hs[1] + puts "</#{@s[0]}>" if (lev==0) + when 5 + puts "#{spaces*5}</#{@s[5]}>" if (lev <= 5) + puts "#{spaces*4}</#{@s[4]}>" if (lev <= 4) + puts "#{spaces*3}</#{@s[3]}>" if (lev <= 3) and hs[3] + puts "#{spaces*2}</#{@s[2]}>" if (lev <= 2) and hs[2] + puts "#{spaces*1}</#{@s[1]}>" if (lev <= 1) and hs[1] + puts "</#{@s[0]}>" if (lev==0) + when 6 + puts "#{spaces*6}</#{@s[6]}>" if (lev <= 6) + puts "#{spaces*5}</#{@s[5]}>" if (lev <= 5) + puts "#{spaces*4}</#{@s[4]}>" if (lev <= 4) + puts "#{spaces*3}</#{@s[3]}>" if (lev <= 3) and hs[3] + puts "#{spaces*2}</#{@s[2]}>" if (lev <= 2) and hs[2] + puts "#{spaces*1}</#{@s[1]}>" if (lev <= 1) and hs[1] + puts "</#{@s[0]}>" if (lev==0) + end + end + end +end +__END__ +#+END_SRC + +** ao_endnotes.rb + +#+BEGIN_SRC ruby :tangle "../lib/sisu/ao_endnotes.rb_" +# <<sisu_document_header>> +module SiSU_AO_Endnotes + class Endnotes + def initialize(md,data,endnote_array=nil) + @md,@data,@endnote_array= + md, data, endnote_array + @endnote_counter, + @endnote_counter_asterisk, + @endnote_counter_dag= + 1,1,1 + end + def endnotes + data=@data + endnote_ref=1 + @tuned_file=data.each.map do |dob| + # manually numbered endnotes <!e(\d)!> <!e_(\d)!> --> + if @md.opt.selections.str =~/--no-asterisk|--no-annotate/ + dob.obj=dob.obj. + gsub(/#{Mx[:en_b_o]}\s.+?#{Mx[:en_b_c]}/,'') + end + if @md.opt.selections.str =~/--no-dagger|--no-annotate/ + dob.obj=dob.obj. + gsub(/#{Mx[:en_b_o]}[+]\s.+?#{Mx[:en_b_c]}/,'') + end + if (defined? dob.obj) \ + && (defined? dob.is) \ + && dob.is !=:code + case dob.obj # auto-numbered endnotes <!e!> <!e_!> --> + when /#{Mx[:en_a_o]}.+?#{Mx[:en_a_c]}|#{Mx[:en_b_o]}[*+]\s+.+?#{Mx[:en_b_c]}/ + dob.obj=dob.obj. + gsub(/\s*(#{Mx[:en_a_c]}|#{Mx[:en_b_c]})/,'\1') + word_mode=dob.obj.scan(/\S+/m) + word_mode=endnote_call_number(word_mode) + dob.obj=word_mode.join(' ') + endnote_ref+=1 + when /~\^(?:\s|$)/ #%note inserts endnotes previously gathered from /^(<!e[:_]!>|[-~]\{{3})/ (in earlier loop) + word_mode=dob.obj.scan(/\S+/m) + word_mode=endnote_call_number(word_mode) + dob.obj=word_mode.join(' ') + endnote_ref+=1 + end + end + dob + end.flatten + @endnote_counter, + @endnote_counter_asterisk, + @endnote_counter_dag= + 1,1,1 + @tuned_file + end + def endnote_call_number(words) + words.each do |word| + case word + when /#{Mx[:en_a_o]}/ + unless word =~/#{Mx[:en_a_o]}[*+]+/ + word.gsub!(/#{Mx[:en_a_o]}/, + "#{Mx[:en_a_o]}#{@endnote_counter} ") + @endnote_counter+=1 + end + when /#{Mx[:en_b_o]}/ + if word =~/#{Mx[:en_b_o]}[+]/ + word.gsub!(/#{Mx[:en_b_o]}[+]/, + "#{Mx[:en_b_o]}\+#{@endnote_counter_dag} ") + @endnote_counter_dag+=1 + else + word.gsub!(/#{Mx[:en_b_o]}[*]?/, + "#{Mx[:en_b_o]}\*#{@endnote_counter_asterisk} ") + @endnote_counter_asterisk+=1 + end + when /~\^/ + if @endnote_array + word.gsub!(/~\^/, + "#{@endnote_array[@endnote_counter-1]}") + @endnote_counter+=1 + end + end + end + end + end +end +__END__ +#+END_SRC + +** ao_expand_insertions.rb + +#+BEGIN_SRC ruby :tangle "../lib/sisu/ao_expand_insertions.rb" +# <<sisu_document_header>> +module SiSU_AO_Insertions + class Insertions + def initialize(md,data) + @md,@data=md,data + end + def output_filetypes_in_cmd(cmd_shortcut,lnk=nil) #make list of file types in shortcut command (as configured), e.g. when sisu -3 is used + act_defaults=SiSU_Env::InfoProcessingFlag.new + cmd_list=case cmd_shortcut.inspect #check on expectation, string v array + when /0/ then act_defaults.act_0.str + when /1/ then act_defaults.act_1.str + when /2/ then act_defaults.act_2.str + when /3/ then act_defaults.act_3.str + when /4/ then act_defaults.act_4.str + when /5/ then act_defaults.act_5.str + when /6/ then act_defaults.act_6.str + when /7/ then act_defaults.act_7.str + when /8/ then act_defaults.act_8.str + when /9/ then act_defaults.act_9.str + end + file_type_names={} + file_type_names[:gen],file_type_names[:src]=[],[] + file_type_names[:gen] <<= if cmd_list =~ /\b--manifest\b/ + "~^ { document manifest }#{lnk[:manifest]}" + end + file_type_names[:gen] <<= if cmd_list =~ /\b--html\b/ + [ + " { html, segmented text }#{lnk[:html_toc]}", + " { html, scroll, document in one }#{lnk[:html_doc]}", + ] + end + file_type_names[:gen] <<= if cmd_list =~ /\b--epub\b/ + [" { epub }#{lnk[:epub]}"] + end + file_type_names[:gen] <<= if cmd_list =~ /\b--pdf\b/ \ + or cmd_list =~ /--pdf-landscape/ + [ + " { pdf, landscape }#{lnk[:pdf_landscape]}", + ] + end + file_type_names[:gen] <<= if cmd_list =~ /\b--pdf\b/ \ + or cmd_list =~ /--pdf-portrait/ + [ + " { pdf, portrait }#{lnk[:pdf_portrait]}", + ] + end + file_type_names[:gen] <<= if cmd_list =~ /\b(?:--odt|--odf)\b/ + " { odf:odt, open document text }#{lnk[:odt]}" + end + file_type_names[:gen] <<= if cmd_list =~ /\b--xhtml\b/ + " { xhtml scroll }#{lnk[:xhtml]}" + end + file_type_names[:gen] <<= if cmd_list =~ /\b--docbook\b/ + " { docbook }#{lnk[:docbook]}" #CHECK + end + file_type_names[:gen] <<= if cmd_list =~ /\b--xml-sax\b/ + " { xml, sax }#{lnk[:xml_sax]}" + end + file_type_names[:gen] <<= if cmd_list =~ /\b--xml-dom\b/ + " { xml, dom }#{lnk[:xml_dom]}" + end + file_type_names[:gen] <<= if cmd_list =~ /\b(?:--txt|--text|--plaintext)\b/ + " { plain text utf-8 }#{lnk[:txt]}" + end + #file_type_names[:gen] <<= if cmd_list =~ /g/ + # 'wiki.txt' + #end + file_type_names[:gen] <<= if cmd_list =~ /\b--concordance\b/ + " { concordance }#{lnk[:html_concordance]}" + end + file_type_names[:gen] <<= if cmd_list =~ /\b--digest\b/ + " { dcc, document content certificate (digests) }#{lnk[:digest]}" + end + file_type_names[:src] <<= if source and cmd_shortcut =~ /\b--source\b/ + " { markup source text }#{lnk[:source]}" + end + file_type_names[:src] <<= if cmd_shortcut =~ /\b--sisupod\b/ + " { markup source (zipped) pod }#{lnk[:sisupod]}" + end + file_type_names[:gen]=file_type_names[:gen].flatten + file_type_names[:src]=file_type_names[:src].flatten + file_type_names + end + def by_language(linked_doc,lng,src=nil) + @linked_doc,@lng,@src=linked_doc,lng,src + @base_path="#{@md.file.output_path.base.url}/#{lng}" + def fnh + { + fn: @linked_doc, + } + end + def path_and_file(fn,pth) + @base_path + '/' + pth + '/' + fn + end + def manifest + fn=@md.file.base_filename.manifest(fnh) + path_and_file(fn,'manifest') + end + def html_toc + fn=@md.file.base_filename.html_segtoc(fnh) + @base_path + '/html/' + @linked_doc + '/' + fn + end + def html_doc + fn=@md.file.base_filename.html_scroll(fnh) + path_and_file(fn,'html') + end + def html_concordance + fn=@md.file.base_filename.html_concordance + @base_path + '/html/' + @linked_doc + '/' + fn + end + def epub + fn=@md.file.base_filename.epub(fnh) + path_and_file(fn,'epub') + end + def pdf_landscape + fn=@md.file.base_filename.pdf_l_a4(fnh) + path_and_file(fn,'pdf') + end + def pdf_portrait + fn=@md.file.base_filename.pdf_p_a4(fnh) + path_and_file(fn,'pdf') + end + def odt + fn=@md.file.base_filename.odt(fnh) + path_and_file(fn,'odt') + end + def xhtml + fn=@md.file.base_filename.xhtml(fnh) + path_and_file(fn,'xhtml') + end + def docbook + fn=@md.file.base_filename.xml_docbook_book(fnh) + path_and_file(fn,'docbook') + end + def xml_sax + fn=@md.file.base_filename.xml_sax(fnh) + path_and_file(fn,'xml_sax') + end + def xml_dom + fn=@md.file.base_filename.xml_dom(fnh) + path_and_file(fn,'xml_dom') + end + def txt + fn=@md.file.base_filename.txt(fnh) + path_and_file(fn,'txt') + end + def digest + fn=@md.file.base_filename.hash_digest(fnh) + path_and_file(fn,'digest') + end + def source + @base_path + '/src/' + @src + end + def sisupod + @base_path + '/src/' + @src + '.zip' + end + self + end + def by_filetype(linked_doc,lng,src=nil) + @linked_doc,@lng,@src=linked_doc,lng,src + @lc=SiSU_Env::FilenameLanguageCodeInsert.new(@md.opt,lng). + language_code_insert + @base_path="#{@md.file.output_path.base.url}" + def fnh + { + fn: @linked_doc, + lng: @lc, + } + end + def path_and_file(fn,pth) + @base_path + '/' + pth + '/' + fn + end + def manifest + fn=@md.file.base_filename.manifest(fnh) + path_and_file(fn,'manifest') + end + def html_toc + fn=@md.file.base_filename.html_segtoc(fnh) + path_and_file(fn,'html') + end + def html_doc + fn=@md.file.base_filename.html_scroll(fnh) + path_and_file(fn,'html') + end + def html_concordance + fn=@md.file.base_filename.html_concordance + path_and_file(fn,'html') + end + def epub + fn=@md.file.base_filename.epub(fnh) + path_and_file(fn,'epub') + end + def pdf_landscape + fn=@md.file.base_filename.pdf_l_a4(fnh) + path_and_file(fn,'pdf') + end + def pdf_portrait + fn=@md.file.base_filename.pdf_p_a4(fnh) + path_and_file(fn,'pdf') + end + def odt + fn=@md.file.base_filename.odt(fnh) + path_and_file(fn,'odt') + end + def xhtml + fn=@md.file.base_filename.xhtml(fnh) + path_and_file(fn,'xhtml') + end + def docbook + fn=@md.file.base_filename.xml_docbook_book(fnh) + path_and_file(fn,'docbook') + end + def xml_sax + fn=@md.file.base_filename.xml_sax(fnh) + path_and_file(fn,'xml_sax') + end + def xml_dom + fn=@md.file.base_filename.xml_dom(fnh) + path_and_file(fn,'xml_dom') + end + def txt + fn=@md.file.base_filename.txt(fnh) + path_and_file(fn,'txt') + end + def digest + fn=@md.file.base_filename.hash_digest(fnh) + path_and_file(fn,'digest') + end + def source + @base_path + '/src/' + @src + end + def sisupod + @base_path + '/src/' + @src + '.zip' + end + self + end + def by_filename(linked_doc,lng,src=nil) + @linked_doc,@lng,@src=linked_doc,lng,src + @lc=SiSU_Env::FilenameLanguageCodeInsert.new(@md.opt,lng).language_code_insert + @base_path="#{@md.file.output_path.base.url}/#{@linked_doc}" + def fnh + { + fn: @linked_doc, + lng: @lc, + } + end + def path_and_file(fn,pth=nil) + (pth.nil?) \ + ? @base_path + '/' + fn + : @base_path + '/' + pth + '/' + fn + end + def manifest + fn=@md.file.base_filename.manifest(fnh) + path_and_file(fn) + end + def html_toc + fn=@md.file.base_filename.html_segtoc(fnh) + path_and_file(fn) + end + def html_doc + fn=@md.file.base_filename.html_scroll(fnh) + path_and_file(fn) + end + def html_concordance + fn=@md.file.base_filename.html_concordance + path_and_file(fn) + end + def epub + fn=@md.file.base_filename.epub(fnh) + path_and_file(fn,'epub') + end + def pdf_landscape + fn=@md.file.base_filename.pdf_l_a4(fnh) + path_and_file(fn) + end + def pdf_portrait + fn=@md.file.base_filename.pdf_p_a4(fnh) + path_and_file(fn) + end + def odt + fn=@md.file.base_filename.odt(fnh) + path_and_file(fn) + end + def xhtml + fn=@md.file.base_filename.xhtml(fnh) + path_and_file(fn) + end + def docbook + fn=@md.file.base_filename.xml_docbook_book(fnh) + path_and_file(fn) + end + def xml_sax + fn=@md.file.base_filename.xml_sax(fnh) + path_and_file(fn) + end + def xml_dom + fn=@md.file.base_filename.xml_dom(fnh) + path_and_file(fn) + end + def txt + fn=@md.file.base_filename.txt(fnh) + path_and_file(fn) + end + def digest + fn=@md.file.base_filename.hash_digest(fnh) + path_and_file(fn) + end + def source + @base_path + '/' + @src + end + def sisupod + @base_path + '/' + @src + '.zip' + end + self + end + def expand_insertions? + data=@data + tuned_file,tuned_file_tmp=[],[] + codeblock_={ + status: :false, + type: :na, + } + data.each do |para| + codeblock_=if para =~/^code(?:\.[a-z][0-9a-z_]+)?\{/ \ + and codeblock_[:status]==:false + { + status: :true, + type: :curl, + } + elsif para =~/^```[ ]+code(?:\.[a-z][0-9a-z_]+)?/ \ + and codeblock_[:status]==:false + { + status: :true, + type: :tics, + } + elsif codeblock_[:type]==:curl \ + and para =~/^\}code/m + { + status: :false, + type: :na, + } + elsif codeblock_[:type]==:tics \ + and para =~/^```(?:\s|$)/m + { + status: :false, + type: :na, + } + else codeblock_ + end + if para !~/^%+\s/ \ + and codeblock_[:status] != :true \ + and para =~/\{(?:~\^\s+)?(.+?)\s\[(?:\d(?:[sS]*))\]\}(?:\.\.\/\S+?\/|\S+?\.ss[tm]\b)/ + @u=SiSU_Env::InfoEnv.new.url + m_cmd='' + if defined? @u.remote + if /(?<m_pre>.+?)\{(?<m_txt>.+?)\s\[(?<m_cmd>\d[sS]*)\]\}(?<m_source>(?<m_linked_doc>\S+?)\.ss[tm]\b)(?<m_note>.*)/m =~ para + m_pre=m_pre.strip + elsif /\{(?<m_txt>.+?)\s\[(?<m_cmd>\d[sS]*)\]\}(?<m_source>(?<m_linked_doc>\S+?)\.ss[tm]\b)(?<m_note>.*)/m =~ para + end + if m_linked_doc =~ /(\S+?)\/(\S+)/ + m_linked_doc,m_linked_doc_lang=$1,$2 + else + m_linked_doc,m_linked_doc_lang=m_linked_doc,@md.opt.lng_base + end + else + puts "error, does currently support relative paths (reltive paths were removed, as had problems for citation, and was not suited to all output types should possibly reconsider) #{__FILE__} #{__LINE__}" + if /\{(?:~\^\s+)?(?<m_txt>.+?)\s\[(?<m_cmd>\d[sS]*)\]\}\.\.\/(?<m_linked_doc>\S+?)\/(?<m_note>\s+#{Mx[:en_a_o]}.+?#{Mx[:en_a_c]})?/ =~ para + end + end + lnk=case @md.opt.dir_structure_by + when :language + { + manifest: by_language(m_linked_doc,m_linked_doc_lang).manifest, + html_toc: by_language(m_linked_doc,m_linked_doc_lang).html_toc, + html_doc: by_language(m_linked_doc,m_linked_doc_lang).html_doc, + epub: by_language(m_linked_doc,m_linked_doc_lang).epub, + pdf_landscape: by_language(m_linked_doc,m_linked_doc_lang).pdf_landscape, + pdf_portrait: by_language(m_linked_doc,m_linked_doc_lang).pdf_landscape, + odt: by_language(m_linked_doc,m_linked_doc_lang).odt, + xhtml: by_language(m_linked_doc,m_linked_doc_lang).xhtml, + docbook: by_language(m_linked_doc,m_linked_doc_lang).docbook, + xml_sax: by_language(m_linked_doc,m_linked_doc_lang).xml_sax, + xml_dom: by_language(m_linked_doc,m_linked_doc_lang).xml_dom, + txt: by_language(m_linked_doc,m_linked_doc_lang).txt, + html_concordance: by_language(m_linked_doc,m_linked_doc_lang).html_concordance, + digest: by_language(m_linked_doc,m_linked_doc_lang).digest, + sisupod: by_language(m_linked_doc,m_linked_doc_lang,m_source).sisupod, + source: by_language(m_linked_doc,m_linked_doc_lang,m_source).source, + } + when :filetype + { + manifest: by_filetype(m_linked_doc,m_linked_doc_lang).manifest, + html_toc: by_filetype(m_linked_doc,m_linked_doc_lang).html_toc, + html_doc: by_filetype(m_linked_doc,m_linked_doc_lang).html_doc, + epub: by_filetype(m_linked_doc,m_linked_doc_lang).epub, + pdf_landscape: by_filetype(m_linked_doc,m_linked_doc_lang).pdf_landscape, + pdf_portrait: by_filetype(m_linked_doc,m_linked_doc_lang).pdf_landscape, + odt: by_filetype(m_linked_doc,m_linked_doc_lang).odt, + xhtml: by_filetype(m_linked_doc,m_linked_doc_lang).xhtml, + docbook: by_filetype(m_linked_doc,m_linked_doc_lang).docbook, + xml_sax: by_filetype(m_linked_doc,m_linked_doc_lang).xml_sax, + xml_dom: by_filetype(m_linked_doc,m_linked_doc_lang).xml_dom, + txt: by_filetype(m_linked_doc,m_linked_doc_lang).txt, + html_concordance: by_filetype(m_linked_doc,m_linked_doc_lang).html_concordance, + digest: by_filetype(m_linked_doc,m_linked_doc_lang).digest, + sisupod: by_filetype(m_linked_doc,m_linked_doc_lang,m_source).sisupod, + source: by_filetype(m_linked_doc,m_linked_doc_lang,m_source).source, + } + else + { + manifest: by_filename(m_linked_doc,m_linked_doc_lang).manifest, + html_toc: by_filename(m_linked_doc,m_linked_doc_lang).html_toc, + html_doc: by_filename(m_linked_doc,m_linked_doc_lang).html_doc, + epub: by_filename(m_linked_doc,m_linked_doc_lang).epub, + pdf_landscape: by_filename(m_linked_doc,m_linked_doc_lang).pdf_landscape, + pdf_portrait: by_filename(m_linked_doc,m_linked_doc_lang).pdf_landscape, + odt: by_filename(m_linked_doc,m_linked_doc_lang).odt, + xhtml: by_filename(m_linked_doc,m_linked_doc_lang).xhtml, + docbook: by_filename(m_linked_doc,m_linked_doc_lang).docbook, + xml_sax: by_filename(m_linked_doc,m_linked_doc_lang).xml_sax, + xml_dom: by_filename(m_linked_doc,m_linked_doc_lang).xml_dom, + txt: by_filename(m_linked_doc,m_linked_doc_lang).txt, + html_concordance: by_filename(m_linked_doc,m_linked_doc_lang).html_concordance, + digest: by_filename(m_linked_doc,m_linked_doc_lang).digest, + sisupod: by_filename(m_linked_doc,m_linked_doc_lang,m_source).sisupod, + source: by_filename(m_linked_doc,m_linked_doc_lang,m_source).source, + } + end + linked_title="#{m_pre}{#{m_txt} }#{lnk[:manifest]}#{m_note}\n\n" + tuned_file_tmp << linked_title + output_filetypes=output_filetypes_in_cmd(m_cmd,lnk) + output_filetypes[:gen].each do |desc| + if desc + tuned_file_tmp << if @u.remote + "#{Mx[:nbsp]*4} #{desc} " + else # remove ... + "[provide document placement host location]" + end + end + end + output_filetypes[:src].each do |desc| + if desc + tuned_file_tmp << if @u.remote + "#{Mx[:nbsp]*4} #{desc} " + else + "[provide document placement host location]" + end + end + end + tuned_file << 'group{' << tuned_file_tmp.join("\n") << '}group' + tuned_file_tmp=[] + else tuned_file << para + end + end + tuned_file + end + end +end +__END__ +#+END_SRC + +** ao_hash_digest.rb + +#+BEGIN_SRC ruby :tangle "../lib/sisu/ao_hash_digest.rb" +# <<sisu_document_header>> +module SiSU_AO_Hash + require_relative 'shared_markup_alt.rb' #shared_markup_alt.rb + class ObjectDigest + def initialize(md,data,env=nil) + @md,@data,@env=md,data,env + @env ||=SiSU_Env::InfoEnv.new(@md.fns,@md) + end + def object_digest + # 1. clean/stripped text without any markup, paragraph, headings etc. without endnotes + # 2. endnotes clean/stripped text digest only (there may be several endnotes within a paragraph) + # 3. whole object, text with markup and any endnotes, (question: with or without the endnote digests??? presumption better without, [however may be easier to check with?]) + # [digests should not include other digests] + data=@data.compact + @tuned_file=[] + sha_ =@env.digest(@md.opt).type + begin + sha_ ? (require 'digest/sha2') : (require 'digest/md5') + rescue LoadError + SiSU_Utils::CodeMarker.new(__LINE__,__FILE__,:fuchsia).error(sha_ + ' NOT FOUND') + end + data.each do |t_o| + unless t_o.obj.is_a?(Array) + t_o.obj=t_o.obj.strip + end + if (t_o.of !=:structure \ + && t_o.of !=:comment \ + && t_o.of !=:layout) \ + && t_o.ocn.is_a?(Fixnum) + case sha_ + when :sha512 + for hash_class in [ Digest::SHA512 ] + @tuned_file << stamped(t_o,hash_class) + end + when :sha256 + for hash_class in [ Digest::SHA256 ] + @tuned_file << stamped(t_o,hash_class) + end + when :md5 + for hash_class in [ Digest::MD5 ] + @tuned_file << stamped(t_o,hash_class) + end + end + else @tuned_file << t_o unless t_o.nil? + end + end + @tuned_file=@tuned_file.flatten + #use md5 or to create hash of each ao object including ocn, & add into to each ao object + end + def endnote_digest(data) + data.each.map do |en_plus| + case en_plus + when /#{Mx[:en_a_o]}|#{Mx[:en_b_o]}/ + if en_plus =~/#{Mx[:en_a_o]}.+?#{Mx[:en_a_c]}|#{Mx[:en_b_o]}.+?#{Mx[:en_b_c]}/ + t_o_txt,en_open,en_txt,en_close= + /(.*?)(#{Mx[:en_a_o]}|#{Mx[:en_b_o]})(.+?)(#{Mx[:en_a_c]}|#{Mx[:en_b_c]})/m. + match(en_plus)[1..4] + stripped_en=SiSU_TextRepresentation::Alter.new(en_txt).strip_clean_of_markup + digest_en_strip=case @env.digest(@md.opt).type + when :sha512 + Digest::SHA512.hexdigest(stripped_en) + when :sha256 + Digest::SHA256.hexdigest(stripped_en) + when :md5 + Digest::MD5.hexdigest(stripped_en) + else + Digest::SHA256.hexdigest(stripped_en) + end + t_o_txt + + en_open + + en_txt + + Mx[:id_o] + + digest_en_strip + + Mx[:id_c] + + en_close + else STDERR.puts "Error Exception - problem encountered with:\n#{en_plus}" #arbitrary exception, tidy up + end + else en_plus + end + end.join + end + def stamped(t_o,hash_class) #decide what hash information is most useful, is compromise necessary? + t_o.obj=SiSU_TextRepresentation::Alter.new(t_o).strip_clean_of_extra_spaces + #SiSU_TextRepresentation::Alter.new(t_o).strip_clean_of_markup #check + #SiSU_TextRepresentation::Alter.new(t_o).semi_revert_markup #check + #SiSU_TextRepresentation::ModifiedTextPlusHashDigest.new(@md,t_o).composite.dgst #check + unless t_o.is==:code + case t_o.obj + when /#{Mx[:en_a_o]}[\d*+]+\s+.+?#{Mx[:en_a_c]}|#{Mx[:en_b_o]}[*+]\d+\s+.+?#{Mx[:en_b_c]}/m + en_and_t_o_digest=[] + t_o.obj=t_o.obj. + gsub(/\s*(#{Mx[:en_a_c]}|#{Mx[:en_b_c]})/m,' \1') #watch + t_o_plus_en=t_o.obj. + scan(/.*?#{Mx[:en_a_o]}.+?#{Mx[:en_a_c]}|.*?#{Mx[:en_b_o]}.+?#{Mx[:en_b_c]}/m) + t_o_tail=if t_o.obj =~/(?:.*?#{Mx[:en_a_o]}.+?#{Mx[:en_a_c]}|.*?#{Mx[:en_b_o]}.+?#{Mx[:en_b_c]})+([\s\S]+)/m + /(?:.*?#{Mx[:en_a_o]}.+?#{Mx[:en_a_c]}|.*?#{Mx[:en_b_o]}.+?#{Mx[:en_b_c]})+.*/m.match(t_o.obj)[1] + else '' + end + t_o_plus_en << t_o_tail + en_and_t_o_digest << endnote_digest(t_o_plus_en) + en_and_t_o_digest.join(' ') + else #@tuned << t_o + Mx[:id_o] + digest_strip + ':' + digest_all + Mx[:id_c] unless t_o.nil? + end + else #@tuned << t_o + Mx[:id_o] + digest_strip + ':' + digest_all + Mx[:id_c] unless t_o.nil? + end + t_o #KEEP intact + end + def strip_clean_extra_spaces(s) # ao output tuned + s=s.dup + s=s.gsub(/[ ]+([,.;:?](?:$|\s))/,'\1') unless s =~/#{Mx[:en_a_o]}|#{Mx[:en_b_o]}/ + s=s.gsub(/ [ ]+/,' '). + gsub(/^ [ ]+/,''). + gsub(/ [ ]+$/,''). + gsub(/((?:#{Mx[:fa_bold_c]}|#{Mx[:fa_italics_c]})')[ ]+(s )/,'\1\2'). + gsub(/((?:#{Mx[:fa_bold_c]}|#{Mx[:fa_italics_c]})')[ ]+(s )/,'\1\2') + end + end +end +__END__ +#+END_SRC + +** ao_idx.rb + +#+BEGIN_SRC ruby :tangle "../lib/sisu/ao_idx.rb" +# <<sisu_document_header>> +module SiSU_AO_BookIndex + class BookIndex + def initialize(md,data,env=nil) + @md,@data,@env=md,data,env + @rgx_idx=/#{Mx[:idx_o]}(?:.+?)#{Mx[:idx_c]}\s*/ + @rgx_idx_ocn_seg=/(.+?)~(\d+)~(\S+)/ + @rgx_idx_ocn=/(.+?)~(\d+)/ + @env ||=SiSU_Env::InfoEnv.new(@md.fns) + end + def indexing_song + data=@data + data, + sisu_markup_idx_rel, + sisu_markup_idx_rel_html_seg, + html_idx,xhtml_idx= + extract_book_index(data) + data= + clean_and_insert_index( + data, + sisu_markup_idx_rel_html_seg + ) + [ + data, + sisu_markup_idx_rel, + sisu_markup_idx_rel_html_seg, + html_idx, + xhtml_idx, + ] + end + def extract_book_index(data) + tuned_file=[] + idx_array=[] + data.each do |dob| + if (dob.is ==:heading \ + || dob.is ==:heading_insert) \ + && dob.ln==4 + @seg=dob.name + end + if defined? dob.idx \ + and dob.idx.is_a?(Hash) + idx_array << { + idx: dob.idx, + ocn: dob.ocn, + seg: @seg + } + end + tuned_file << dob if dob + end + if idx_array.length > 0 + the_idx=construct_book_index(idx_array) + if @md.book_idx + idx=index(the_idx) + sisu_markup_idx_rel,sisu_markup_idx_rel_html_seg,html_idx, xhtml_idx= + idx[:sst_rel], idx[:sst_rel_html_seg], idx[:html],idx[:xhtml] + else + sisu_markup_idx_rel= + sisu_markup_idx_rel_html_seg= + html_idx= + xhtml_idx= + nil + end + end + [ + tuned_file, + sisu_markup_idx_rel, + sisu_markup_idx_rel_html_seg, + html_idx, + xhtml_idx, + ] + end + def construct_book_index(idx_array) + the_idx={} + idx_array.each do |idx| + idx[:idx].each_pair do |term,term_info| + location=(term_info[:plus].to_i > 0) \ + ? (%{#{idx[:ocn]}-#{idx[:ocn].to_i + term_info[:plus].to_i}}) + : idx[:ocn].to_s + the_idx[term]={} \ + unless the_idx[term] \ + and defined? the_idx[term] + the_idx[term]['node_0_terms']=[] \ + unless the_idx[term]['node_0_terms'] \ + and defined? the_idx[term]['node_0_terms'] + the_idx[term]['node_0_terms'] << { ocn: idx[:ocn], range: location, seg: idx[:seg] } + if term_info[:sub].is_a?(Array) \ + and term_info[:sub].length > 0 + term_info[:sub].each do |y| + y.each_pair do |subterm,subterm_info| + location=(subterm_info[:plus].to_i > 0) \ + ? (%{#{idx[:ocn]}-#{idx[:ocn].to_i + subterm_info[:plus].to_i}}) + : idx[:ocn].to_s + the_idx[term]={} \ + unless the_idx[term] \ + and defined? the_idx[term] + the_idx[term]['node_0_terms']=[] \ + unless the_idx[term]['node_0_terms']\ + and defined? the_idx[term]['node_0_terms'] + the_idx[term]['node_1_subterms']={} \ + unless the_idx[term]['node_1_subterms'] \ + and defined? the_idx[term]['node_1_subterms'] + the_idx[term]['node_1_subterms'][subterm]=[] \ + unless the_idx[term]['node_1_subterms'][subterm] \ + and defined? the_idx[term]['node_1_subterms'][subterm] + the_idx[term]['node_1_subterms'][subterm] << + { ocn: idx[:ocn], range: location, seg: idx[:seg] } + end + end + end + end + end + the_idx=the_idx.sort + the_idx + end + def clean_xml(str) + str=str.gsub(/&/,'&') + str + end + def index(the_idx) + @x=1 + idx={} + idx[:sst_rel_html_seg],idx[:sst_rel],idx[:html],idx[:xhtml]= + [], [], [], [] + h={ + obj: Mx[:br_page] + } + o=SiSU_AO_DocumentStructure::ObjectLayout.new.break(h) + idx[:sst_rel_html_seg] << o + idx[:sst_rel] << o + h={ + lv: '1', + name: 'index', + obj: "Index" + } + o=SiSU_AO_DocumentStructure::ObjectHeading.new.heading(h) + idx[:sst_rel_html_seg] << o + idx[:sst_rel] << o + h={ + lv: '4', + name: 'idx', + obj: " [Index] #{Mx[:pa_non_object_dummy_heading]}" + } + o=SiSU_AO_DocumentStructure::ObjectHeading.new.heading(h) + idx[:sst_rel_html_seg] << o + idx[:sst_rel] << o + alph=%W[9 A B C D E F G H I J K L M N O P Q R S T U V W X Y Z] + idx[:html] << '<p>' + idx[:xhtml] << '<p>' + alph.each do |x| + if x =~/[0-9]/ + idx[:html] << '' + idx[:xhtml] << '' + else + idx[:html] << + %{<a href="##{x}">#{x}</a>,#{$ep[:hsp]}} + idx[:xhtml] << + %{<a href="##{x.downcase}">#{x}</a>,#{$ep[:hsp]}} + end + end + idx[:html] << '</p>' + idx[:xhtml] << '</p>' + letter=alph.shift + idx[:html] << + %{\n<p class="book_index_lev1"><a name="numeral"></a></p>} + idx[:xhtml] << + %{\n<p class="letter" id="numeral">0 - 9</p>} + the_idx.each do |i| + i.each do |x| + if x.is_a?(String) + f=/^(\S)/.match(x)[1] + if letter < f + while letter < f + if alph.length > 0 + letter=alph.shift + idx[:html] << + %{\n<p class="letter"><a name="#{letter}">#{letter}</a></p><p class="book_index_lev1"><a name="#{letter.downcase}"> </a></p>} + idx[:xhtml] << + %{\n<p class="letter" id="#{letter.downcase}">#{letter}</p>} + else break + end + end + end + idx[:sst_rel_html_seg] << + %{\n\n#{Mx[:fa_bold_o]}#{x},#{Mx[:fa_bold_c]} } + idx[:sst_rel] << + %{\n\n#{Mx[:fa_bold_o]}#{x},#{Mx[:fa_bold_c]} } + aname=x.gsub(/\s+/,'_') + idx[:html] << + %{\n<p class="book_index_lev1"><a name="#{aname}"><b>#{x}</b></a>, } + c=clean_xml(x.dup) + idx[:xhtml] << + %{\n<p class="book_index_lev1"><b>#{c}</b>, } + @o=idx[:sst_rel_html_seg].index(idx[:sst_rel_html_seg].last) + @t=idx[:sst_rel].index(idx[:sst_rel].last) + @q=idx[:html].index(idx[:html].last) + @r=idx[:xhtml].index(idx[:xhtml].last) + print "\n" + x + ', ' if @md.opt.act[:verbose_plus][:set]==:on + elsif x.is_a?(Array) + p 'array error? -->' + print x + elsif x.is_a?(Hash) + if x['node_0_terms'].is_a?(Array) + x['node_0_terms'].each do |a| + if a[:range] + idx[:sst_rel_html_seg][@o]= + idx[:sst_rel_html_seg][@o] + + %{#{Mx[:lnk_o]}#{a[:range]}#{Mx[:lnk_c]}#{Mx[:rel_o]}/#{a[:seg]}.html##{a[:ocn]}#{Mx[:rel_c]}, } + idx[:sst_rel][@t]= + idx[:sst_rel][@t] + + %{#{Mx[:lnk_o]}#{a[:range]}#{Mx[:lnk_c]}#{Mx[:rel_o]}#{a[:ocn]}#{Mx[:rel_c]}, } + idx[:html][@q]= + idx[:html][@q] + + %{<a href="#{a[:seg]}.html##{a[:ocn]}">#{a[:range]}</a>, } + idx[:xhtml][@q]= + idx[:xhtml][@q] + + %{<a href="#{a[:seg]}.xhtml#o#{a[:ocn]}">#{a[:range]}</a>, } + print a[:range] + ', ' if @md.opt.act[:verbose_plus][:set]==:on + elsif a[:ocn] + idx[:sst_rel_html_seg][@o]= + idx[:sst_rel_html_seg][@o] + + %{#{Mx[:lnk_o]}#{a[:ocn]}#{Mx[:lnk_c]}#{Mx[:rel_o]}#{a[:seg]}.html##{a[:ocn]}#{Mx[:rel_c]}, } + idx[:sst_rel][@t]= + idx[:sst_rel][@t] + + %{#{Mx[:lnk_o]}#{a[:ocn]}#{Mx[:lnk_c]}#{Mx[:rel_o]}#{a[:ocn]}#{Mx[:rel_c]}, } + idx[:html][@q]= + idx[:html][@q] + + %{<a href="#{a[:seg]}.html##{a[:ocn]}">#{a[:ocn]}</a>, } + idx[:xhtml][@q]= + idx[:xhtml][@q] + + %{<a href="#{a[:seg]}.xhtml#o#{a[:ocn]}">#{a[:ocn]}</a>, } + print a[:ocn] + ', ' if @md.opt.act[:verbose_plus][:set]==:on + else p 'error' + end + end + idx[:html][@q]=idx[:html][@q] + '</p>' + idx[:xhtml][@r]=idx[:xhtml][@r] + '</p>' + end + if x['node_1_subterms'] + x['node_1_subterms'].sort.each do |k,y| + if k !~/node_0_terms/ + idx[:sst_rel_html_seg][@o]= + idx[:sst_rel_html_seg][@o] + + %{#{k}, } + idx[:sst_rel][@t]= + idx[:sst_rel][@t] + + %{#{k}, } + idx[:html][@q]= + idx[:html][@q] + + %{\n<p class="book_index_lev2">#{k}, } + c=clean_xml(k.dup) + idx[:xhtml][@r]= + idx[:xhtml][@r] + + %{\n<p class="book_index_lev2">#{c}, } + print "\n\t" + k + ', ' if @md.opt.act[:verbose_plus][:set]==:on + y.each do |z| + if z[:range] + idx[:sst_rel_html_seg][@o]= + idx[:sst_rel_html_seg][@o] + + %{#{Mx[:lnk_o]}#{z[:range]}#{Mx[:lnk_c]}#{Mx[:rel_o]}#{z[:seg]}.html##{z[:ocn]}#{Mx[:rel_c]}, } + idx[:sst_rel][@t]= + idx[:sst_rel][@t] + + %{#{Mx[:lnk_o]}#{z[:range]}#{Mx[:lnk_c]}#{Mx[:rel_o]}#{z[:ocn]}#{Mx[:rel_c]}, } + idx[:html][@q]= + idx[:html][@q] + + %{<a href="#{z[:seg]}.html##{z[:ocn]}">#{z[:range]}</a>, } + idx[:xhtml][@q]= + idx[:xhtml][@q] + + %{<a href="#{z[:seg]}.xhtml#o#{z[:ocn]}">#{z[:range]}</a>, } + print z[:range] + ', ' if @md.opt.act[:verbose_plus][:set]==:on + elsif z[:ocn] + idx[:sst_rel_html_seg][@o]= + idx[:sst_rel_html_seg][@o] + + %{#{Mx[:lnk_o]}#{z[:ocn]}#{Mx[:lnk_c]}#{Mx[:rel_o]}#{z[:seg]}.html##{z[:ocn]}#{Mx[:rel_c]}, } + idx[:sst_rel][@t]= + idx[:sst_rel][@t] + + %{#{Mx[:lnk_o]}#{z[:ocn]}#{Mx[:lnk_c]}#{Mx[:rel_o]}#{z[:ocn]}#{Mx[:rel_c]}, } + idx[:html][@q]= + idx[:html][@q] + + %{<a href="#{z[:seg]}.html##{z[:ocn]}">#{z[:ocn]}</a>, } + idx[:xhtml][@q]= + idx[:xhtml][@q] + + %{<a href="#{z[:seg]}.xhtml#o#{z[:ocn]}">#{z[:ocn]}</a>, } + print z[:ocn] + ', ' if @md.opt.act[:verbose_plus][:set]==:on + else p 'error' + end + end + idx[:html][@q]=idx[:html][@q] + '</p>' + idx[:xhtml][@r]=idx[:xhtml][@r] + '</p>' + end + end + end + @x +=1 + end + end + end + print "\n" if @md.opt.act[:verbose_plus][:set]==:on + idx + end + def screen_print(the_idx) + the_idx.each do |i| + i.each do |x| + if x.is_a?(String) + print "\n" + x + ', ' + elsif x.is_a?(Array) + p 'array error? -->' + print x + elsif x.is_a?(Hash) + if x['node_0_terms'].is_a?(Array) + x['node_0_terms'].each do |a| + if a[:range] + print a[:range] + ', ' + elsif a[:ocn] + print a[:ocn] + ', ' + else p 'error' + end + end + end + if x['node_1_subterms'] + x['node_1_subterms'].sort.each do |k,y| + if k !~/node_0_terms/ + print "\n\t" + k + ', ' + y.each do |z| + if z[:range] + print z[:range] + ', ' + elsif z[:ocn] + print z[:ocn] + ', ' + else p 'error' + end + end + end + end + end + end + end + end + end + def output_idx(idx) + if @md.book_idx + path="#{@env.path.output}/#{@md.fnb}" + Dir.mkdir(path) unless FileTest.directory?(path) + puts "#{path}/#{@md.fn[:book_idx_html]} #{__FILE__}::#{__LINE__}" + html_index_file=File.new("#{path}/#{@md.fn[:book_idx_html]}",'w') + idx[:html].each {|x| html_index_file << x } + html_index_file.close + end + end + def clean_and_insert_index(data,sisu_markup_idx) + tuned_file=[] + data.each do |dob| + tuned_file << dob + if dob.obj =~/#{Mx[:br_endnotes]}/ \ + and sisu_markup_idx + sisu_markup_idx.each do |idx| + tuned_file << idx + end + end + end + tuned_file + end + def clean_index(data) #check on use of dob + data.each.map do |para| + para.gsub(/\n*#{@rgx_idx}/m,'') + end + end + end +end +__END__ +#+END_SRC + +** ao_images.rb + +#+BEGIN_SRC ruby :tangle "../lib/sisu/ao_images.rb" +# <<sisu_document_header>> +module SiSU_AO_Images + class Images + begin + require 'rmagick' + include Magick + rescue LoadError + #SiSU_Utils::CodeMarker.new(__LINE__,__FILE__,:fuchsia).mark('rmagic NOT FOUND') + end + def initialize(md,data) + @md,@data=md,data + end + def images + data=@data + @rmgk=false + imagemagick_=true #imagemagick_=SiSU_Env::InfoSettings.new.program?('rmagick') + if imagemagick_ + begin + @rmgk=SiSU_Env::Load.new('rmagick').prog + rescue + @rmgk=false + end + else + if (@md.opt.act[:verbose_plus][:set]==:on \ + || @md.opt.act[:maintenance][:set]==:on) + SiSU_Screen::Ansi.new( + @md.opt.act[:color_state][:set], + '*WARN* use of rmagick is not enabled in sisurc.yml' + ).warn + end + end + data.select do |dob| + unless dob.is ==:table + dob.obj=dob.obj.strip + if dob.obj =~/#{Mx[:lnk_o]}\s*\S+\.(?:png|jpg|gif)(?:\s*|\s+.+)?#{Mx[:lnk_c]}(?:#{Mx[:url_o]}\S+?#{Mx[:url_c]}|image)/ + if dob.obj !~/#{Mx[:lnk_o]}\s*\S+\.(?:png|jpg|gif)\s+\d+x\d+/ + m=/#{Mx[:lnk_o]}\s*(\S+\.(?:png|jpg|gif))/ + if imagemagick_ + imgs=dob.obj.scan(m).flatten + img_col=img_row=nil + images=imgs.each do |image| + dir=SiSU_Env::InfoEnv.new(@md.fns) + path_image=[ + dir.path.image_source_include_local, + dir.path.image_source_include_remote, + dir.path.image_source_include + ] + image_path=nil + path_image.each do |img_pth| + image_path=img_pth + break if FileTest.exist?("#{img_pth}/#{image}") + end + if FileTest.exist?("#{image_path}/#{image}") + if @rmgk + img=Magick::ImageList.new("#{image_path}/#{image}") + img_col,img_row=img.columns,img.rows + else + if (@md.opt.act[:verbose_plus][:set]==:on \ + || @md.opt.act[:maintenance][:set]==:on) + SiSU_Screen::Ansi.new( + @md.opt.act[:color_state][:set], + '*WARN* rmagick not present, will attempt to use imagemagick (identify) directly' + ).warn + end + imgk=SiSU_Env::SystemCall.new.imagemagick + gmgk=SiSU_Env::SystemCall.new.graphicsmagick + if imgk or gmgk + if imgk + imgsys=`identify #{image_path}/#{image}`.strip #system call + elsif gmgk + imgsys=`gm identify #{image_path}/#{image}`.strip #system call + end + img_col,img_row=/(\d+)x(\d+)/m.match(imgsys)[1,2] + img_col,img_row=img_col.to_i,img_row.to_i + else + errmsg='imagemagick or graphicsmagick are required to process images' + if @md.opt.act[:no_stop][:set]==:on + SiSU_Utils::CodeMarker.new(__LINE__,__FILE__,:fuchsia). + error("#{errmsg}, proceeding (as requested) without image processing") + break + else + SiSU_Utils::CodeMarker.new(__LINE__,__FILE__,:fuchsia). + error("#{errmsg}, STOPPING") + exit + end + end + end + row=((img && defined? img.rows) ? img.rows : img_row) + col=((img && defined? img.columns) ? img.columns : img_col) + if img_col > img_row #landscape + if img_col> 640 + img_col=640 + img_row=((1.00*img_col/col)*row).round + end + else #portrait + if img_col> 640 + img_col=640 + img_row=((1.00*img_col/col)*row).round + end + if img_row > 640 + img_row=640 + img_col=((1.00*img_row/row)*col).round + end + end + dob.obj=dob.obj.gsub(/(#{image})/,"#{image} #{img_col}x#{img_row}") + else + dob.obj=dob.obj. + gsub(/#{Mx[:lnk_o]}\s*(\S+)\.(png|jpg|gif).+?#{Mx[:lnk_c]}(#{Mx[:url_o]}\S+?#{Mx[:url_c]}|image)/, + '[ \1 (\2 missing) ]') + end + end + else + images=dob.obj.scan(m) do |image| + SiSU_Screen::Ansi.new( + @md.opt.act[:color_state][:set], + '*WARN* where image dimensions have not been provided rmagick or imagemagick is required',image + ).warn unless @md.opt.act[:quiet][:set]==:on + end + end + end + end + if dob.obj =~/#{Mx[:lnk_o]}\s*\S+\.(?:png|jpg|gif).+?#{Mx[:lnk_c]}(?:#{Mx[:url_o]}\S+?#{Mx[:url_c]}|image)/ + dob.obj=dob.obj.gsub(/(#{Mx[:lnk_o]})\s*(\S+\.(?:png|jpg|gif))\s+/i,'\1\2 ') + end + end + dob unless dob.nil? + end + end + end +end +__END__ +imgsys=`identify #{image_path}/#{image}`.strip +#+END_SRC + +** ao_metadata.rb + +#+BEGIN_SRC ruby :tangle "../lib/sisu/ao_metadata.rb" +# <<sisu_document_header>> +module SiSU_AO_Metadata + class Metadata + def initialize(md,metad) + @md,@metadata=md,metad + l=SiSU_Env::StandardiseLanguage.new(@md.opt.lng).language + language=l[:n] + @tr=SiSU_Translate::Source.new(md,language) + end + def make_para(obj,ocn) + h={ + obj: obj, + ocn: 0 + } + SiSU_AO_DocumentStructure::ObjectPara.new.paragraph(h) + end + def make_heading(obj,ocn,name,lv,ln) + h={ + lv: lv, + ln: ln, + name: name, + obj: obj, + ocn: 0 + } + SiSU_AO_DocumentStructure::ObjectHeading.new.heading(h) + end + def metadata + end + end +end +__END__ +#+END_SRC + +** ao_misc_arrange.rb + +#+BEGIN_SRC ruby :tangle "../lib/sisu/ao_misc_arrange.rb" +# <<sisu_document_header>> +module SiSU_AO_MiscArrangeText + class SI + def initialize(md,data) + @md,@data=md,data + end + def conditional_headings(para) + para=para.gsub(/^(:?A~)\s*$/,'\1~ @title @author'). #conditional header + gsub(/^((?:[1-9]|:?[A-D])~\S*)\s*$/, + '\1~ [Note: heading marker::required title missing]~#') #conditional header for incorporated document 2004w12 + if para =~/^@\S+?:/ + para=para.gsub(/^@(\S+?):(\s+|$)/, + "#{Mx[:meta_o]}\\1#{Mx[:meta_c]}\\2"). + gsub(/^@(\S+?):([+-])(\s+|$)/, + "#{Mx[:meta_o]}\\1\\2#{Mx[:meta_c]}\\3") + end + para + end + def markup_blocks(para) + def ticks(para) + block_open,block_close,text=nil,nil,nil + if para =~/\A```[ ]+(?:code(?:\.[a-z][0-9a-z_]+)?|box(?:\.[a-z_]+)?|poem|alt|group|block|table).*?\n.+?\n```(?:\s+[~-][#]|\s+\~\{.+?\}\~)?\s*\Z/m + @flag=:close + block_open,text,block_close= + /\A(```[ ]+(?:code(?:\.[a-z][0-9a-z_]+)?|box(?:\.[a-z_]+)?|poem|alt|group|block|table).*?)\n(.+?)\n(```([ ]+[~-][#]|\s+\~\{.+?\}\~)?)\s*\Z/m. + match(para)[1..3] + ((para=~/^```[ ]+table(?:~h)?\s+/) \ + and (para !~/^```[ ]+table(?:~h)?\s+c\d+/)) \ + ? para + : (para=[]; para << block_open << text << block_close) + elsif para =~/\A```[ ]+(?:code(?:\.[a-z][0-9a-z_]+)?|box(?:\.[a-z_]+)?|poem|alt|group|block|table).*?\n.*?\Z/m #look at, study + @flag=:open + block_open,text=/\A(```(?:[ ]+.+?))\n(.*?)\Z/m.match(para)[1,2] + para=[] + if not text.to_s.empty? + para << block_open << text + else + para << block_open + end + elsif para =~/\A.+?\n```(?:\s+\~\{.+?\}\~)?(?:\s+[~-][#])?(\s*=\{.+?\})?\s*\Z/m \ + and @flag==:open + @flag=:close + text,block_close= + /\A(.+?)\n(```(?:\s+\~\{.+?\}\~)?(?:\s+[~-][#])?(?:\s+=\{.+?\})?)\s*\Z/m.match(para)[1,2] + para=[] + if not text.to_s.empty? + para << text.to_s << block_close + else + para << block_close + end + else para + end + para + end + def ticks_remove(para) + unless @md.opt.act[:quiet][:set] ==:on + SiSU_Utils::CodeMarker.new(__LINE__,__FILE__,:fuchsia). + mark("ticks not recognized, ticks removed from pargraph\n#{para}") + end + para=para.gsub(/```[ ]+\S+[ ]*/m,''). + gsub(/```\s*/m,''). + strip + end + def ticks_quote(para) + @flag=:quote_open + text=para + para=[] + if text =~ /```[ ]+quote/m + para << '`:quote_open`' + text=text.gsub(/```[ ]+quote/m,'') + end + text=if text =~/(?:\n|\A)=\{.+?\}/m #exclude book index from indent markup + txt,bkidx,tail=/(.+?)((?:\n|\A)=\{.+?\}$)(.*)/m.match(text).captures + txt=txt.gsub(/(?:\n|\A)([^`\n]+)/m,'_1 \1') + txt + bkidx + tail + else text.gsub(/(?:\n|\A)([^`\n]+)/m,'_1 \1') + end + para << text.gsub(/```/m,'') + if text =~/```/m + @flag=:quote_close + para << '`:quote_close`' + end + para + end + def curly_braces(para) + block_open,block_close,text=nil,nil,nil + para=if para =~/\A(?:code(?:\.[a-z][0-9a-z_]+)?|box(?:\.[a-z_]+)?|poem|alt|group|block|table)\{ .+?\n.+?\n\}(?:code|box|poem|alt|group|block|table)(?: [~-][#])?\s*\Z/m + block_open,text,block_close= + /\A((?:code(?:\.[a-z][0-9a-z_]+)?|box(?:\.[a-z_]+)?|poem|alt|group|block|table)\{ .+?)\n(.+?)\n(\}(?:code|box|poem|alt|group|block|table)(?: [~-][#])?)\s*\Z/m. + match(para)[1..3] + para=[] + para << block_open << text << block_close + elsif para =~/\A(?:code(?:\.[a-z][0-9a-z_]+)?|box(?:\.[a-z_]+)?|poem|alt|group|block|table)\{ .+?\n.+?\Z/m + block_open,text= + /\A((?:code(?:\.[a-z][0-9a-z_]+)?|box(?:\.[a-z_]+)?|poem|alt|group|block|table)\{ .+?)\n(.+?)\Z/m. + match(para)[1,2] + para=[] + if not text.to_s.empty? + para << block_open << text + else + para << block_open + end + elsif para =~/\A.+?\n\}(?:code|box|poem|alt|group|block|table)(?: [~-][#])?\s*\Z/m + text,block_close= + /\A(.+?)\n(\}(?:code|box|poem|alt|group|block|table)(?: [~-][#])?)\s*\Z/m. + match(para)[1,2] + para=[] + if not text.to_s.empty? + para << text.to_s << block_close + else + para << block_close + end + else para + end + para + end + para=if (para =~/\A```[ ]+quote/m \ + and @flag !=:open) \ + or @flag==:quote_open + ticks_quote(para) + elsif para =~/\A```[ ]+(?:code(?:\.[a-z][0-9a-z_]+)?|box(?:\.[a-z_]+)?|poem|alt|group|block|table).*?\n.*?\Z/m \ + or @flag==:open + ticks(para) + elsif para =~/```/m + ticks_remove(para) + else + para + end + para=if para =~/^(?:code(?:\.[a-z][0-9a-z_]+)?|box(?:\.[a-z_]+)?|poem|alt|group|block|table)\{|^\}(?:code|box|poem|alt|group|block|table)/m + curly_braces(para) + else + para + end + end + def prepare_text + data=@data + if data[0] =~ /^#!\s*(?:\/usr\/bin\/env sisu|\/usr\/bin\/sisu)/ # remove bang from top #! (however file is stripped, so will be removed provided no content precedes it) + data[0]=data[0].gsub(/^#!\s*\/usr\/bin\/sisu/,''). + gsub(/^#!\s*\/usr\/bin\/env sisu/,'') + end + if data[0] =~ /^(SiSU\s+[\d.]*|sisu-[\d.]+)$/ # SiSU identifier + data[0]=data[0].gsub(/^(SiSU\s*[\d.]*)$/,'% \1'). + gsub(/^(sisu-[\d.]+)$/,'% \1') + end + data.each.map do |para| + para=conditional_headings(para) + markup_blocks(para) + end.flatten + end + end +end +__END__ +#+END_SRC + +** ao_numbering.rb + +#+BEGIN_SRC ruby :tangle "../lib/sisu/ao_numbering.rb" +# <<sisu_document_header>> +module SiSU_AO_Numbering + class Numbering + attr_accessor :obj,:osp,:ocn,:lv,:name,:index,:comment + @@segments_count=0 + def initialize(md,data,fnx,process) + @md,@data,@fnx,@process=md,data,fnx,process + @obj=@type=@ocn=@lv=@name=@index=@comment=nil + @chosen_seg_names=[] + end + def chosen_seg_names(chosen,chosen_seg_name,dob,md,type) + @chosen_seg_names=if chosen.compact.uniq.length \ + == chosen.compact.length + chosen + else + if md.opt.act[:maintenance][:set]==:on + SiSU_Utils::CodeMarker.new(__LINE__,__FILE__,:green). + mark( + "duplicated auto segment name: #{type} #{chosen}\n" \ + + "#{chosen}\n" \ + + " manually name level 1 segments '1~given_name'\n" \ + + 'filename: ' + md.fns + "\n" \ + + 'heading text: "' + dob.obj + '"' + "\n" \ + + 'duplication: "' + chosen_seg_name + '" (level: ' + dob.lv + '; numbering type: ' + type.to_s + ')' + ) + end + chosen=chosen[0..-2] + chosen_seg_name=auto_numbering_exceptions(chosen,md,dob) + chosen << chosen_seg_name + end + end + def number_of_segments? + if @@segments_count==0 + @data.each do |dob| + if dob.is == :heading \ + and dob.lv == '1' + @@segments_count += 1 + end + end + @@segments_count + else @@segments_count + end + end + def numbering_song + begin + data=@data + data=number_plaintext_para(data) + data=auto_number_heading_ie_title(data.compact) #tr issue + data=ocn(data.compact) #watch + data=xml(data.compact) + data=minor_numbering(data.compact) + if @process==:complete + data,tags_map,ocn_html_seg_map=name_para_seg_filename(data) + end + data=set_heading_top(data) unless @md.set_heading_top + [data,tags_map,ocn_html_seg_map] + ensure + @@segments_count=0 + end + end + def set_tags(tags,tag) + tags=if not tag.empty? \ + and tag !~/^\d+$/ + tag=tag.gsub(/[^a-z0-9._-]/,'') + [tag,tags].flatten + else tags + end + end + def number_plaintext_para(data) + @tuned_file=[] + data.each do |dob| + if (dob.of !=:block \ + && dob.of !=:comment \ + && dob.of !=:layout) \ + && dob.ocn_ #and dob.obj !~ /#{Mx[:gr_o]}Th|#{Mx[:tc_o]}#{Mx[:tc_p]}#{Mx[:tc_p]}/ #FIX + dob.obj=dob.obj.gsub(/(.+)\n/,'\1 ') #messy, but idea is that tables should retain breaks + end + unless dob.obj.is_a?(Array) + dob.obj=dob.obj.gsub(/^\s+/,''). + gsub(/\s$/,"\n") + end + @tuned_file << dob + end + @tuned_file=@tuned_file.flatten + end + def number_sub_heading(dob,num,title_no) + unless dob.obj =~/\d+\.|(?:chapter|article|section|clause)\s+\d+/i #name selection arbitrary, fix + dob.obj=case dob.name + when /-/ then dob.obj.gsub(/^/,"#{title_no} ") + when /^#/ then dob.obj.gsub(/^/,"#{title_no} ") + when /^[a-z_\.]+/ then dob.obj.gsub(/^/,"#{title_no} ") + else + dob.name=title_no if dob.name=~/^$/ #where title contains title number + dob.obj.gsub(/^/,"#{title_no} ") if title_no =~/\d+/ #main, where title number is to be provided #watch changed placement + end + if @md.toc_lev_limit \ + and @md.toc_lev_limit < num + dob.obj=dob.obj.gsub(/^/,'!_ ') #bold line, watch + end + end + dob + end + def heading_tag_clean(heading_tag) + heading_tag=heading_tag. + gsub(/[ ]+/,'_'). + gsub(/["']/,''). + gsub(/[\/]/,'-'). + gsub(/#{Mx[:fa_bold_o]}|#{Mx[:fa_bold_c]}/,''). + gsub(/#{Mx[:fa_italics_o]}|#{Mx[:fa_italics_c]}/,''). + gsub(/#{Mx[:fa_underscore_o]}|#{Mx[:fa_underscore_c]}/,''). + gsub(/#{Mx[:fa_cite_o]}|#{Mx[:fa_cite_c]}/,''). + gsub(/#{Mx[:fa_insert_o]}|#{Mx[:fa_insert_c]}/,''). + gsub(/#{Mx[:fa_strike_o]}|#{Mx[:fa_strike_c]}/,''). + gsub(/#{Mx[:fa_superscript_o]}|#{Mx[:fa_superscript_c]}/,''). + gsub(/#{Mx[:fa_subscript_o]}|#{Mx[:fa_subscript_c]}/,''). + gsub(/#{Mx[:fa_hilite_o]}|#{Mx[:fa_hilite_c]}/,''). + gsub(/#{Mx[:gl_bullet]}/,'') + end + def auto_number_heading_ie_title(data) #also does some segment naming + if defined? @md.make.num_top \ + and @md.make.num_top \ + and @md.make.num_top !~/^$/ + input||=@md.make.num_top + end + num_top=(input ? input.to_i : nil) + t_no1=t_no2=t_no3=0 + if num_top + no1=num_top; no2=(num_top + 1); no3=(num_top + 2) + end + chapter_number_counter=0 + data=data.compact + @tuned_file=data.each.map do |dob| #@md.seg_names << [additions to segment names] + title_no=nil + if dob.is ==:heading \ + && dob.autonum_ \ + and defined? @md.make.num_top \ + and @md.make.num_top !~/^$/ + if dob.lv=='1' \ + and dob.obj =~/^#\s|\s#(?:\s|$)/ + chapter_number_counter +=1 + dob.obj=dob.obj.gsub(/^#\s/,"#{chapter_number_counter} "). + gsub(/#([:,]?\s|[.]?$)/,"#{chapter_number_counter}\\1") + end + if dob.ln==no1 + @subnumber=1 + @subnumber=0 if dob.ln==no1 + end + if dob.ln.to_s =~/^[0-6]/ \ + and not dob.use_ ==:dummy \ + and dob.obj !~/#{Mx[:fa_o]}(?:~#|-#)#{Mx[:fa_c]}/ # <-- fix + if dob.ln==no1 + t_no1+=1; t_no2=0; t_no3=0 + title_no="#{t_no1}" + if @md.seg_names.is_a?(Array) \ + and not @md.seg_names.include?(title_no) + if dob.ln==no1 + dob.name="#{title_no}" if not dob.name + dob.tags=set_tags(dob.tags,title_no) + tag=dob.obj. + gsub(/(Article|Clause|Section|Chapter)\s+/, + "\\1_#{title_no}"). + downcase + tag=heading_tag_clean(tag) + dob.tags=set_tags(dob.tags,tag) + dob.obj=(dob.obj =~/(Article|Clause|Section)\s+/) \ + ? (dob.obj.gsub(/(Article|Clause|Section)\s+/,"\\1 #{title_no} ")) + : (dob.obj.gsub(/^/,"#{title_no}. ")) #fix stop later + end + if dob.ln !=no1 \ + and dob.obj =~/^[\d.]+\s/ #fix -> if the title starts with a numbering scheme, do not auto-number, review + dob.name ="#{title_no}" if not dob.name + dob.tags=set_tags(dob.tags,title_no) + dob.obj=dob.obj.gsub(/^/,"#{title_no}. ") + end + @md.seg_names << title_no + end + if dob.ln!=no1 \ + and dob.name!~/^[a-z_\.]+$/ \ + and dob.obj !~/[A-Z]\.?\s/ #bug -> tmp fix, excludes A. B. C. lettering, but not roman numerals, is arbitrary, review required # not fixed, work on + dob.tags=set_tags(dob.tags,title_no) + dob.obj=dob.obj.gsub(/^/i,"#{title_no}. ") + end + end + if dob.ln==no1 #watch because here you change dob.name + dob.tags=set_tags(dob.tags,"h#{title_no}") + end + if dob.ln==no2 #watch because here you change dob.name + t_no2+=1; t_no3=0 + title_no="#{t_no1}.#{t_no2}" + dob.tags=set_tags(dob.tags,"h#{title_no}") + dob=number_sub_heading(dob,no2,title_no) + end + if dob.ln==no3 #watch because here you change dob.name + t_no3+=1 + title_no="#{t_no1}.#{t_no2}.#{t_no3}" + dob.tags=set_tags(dob.tags,"h#{title_no}") + dob=number_sub_heading(dob,no3,title_no) + end + elsif dob.ln.to_s =~/^[0-6]/ \ + and dob.name =~ /^[\w-]+-/ # endnotes, watch2005# endnotes, watch2005 + dob.tags=set_tags(dob.tags,dob.name) + dob.name.gsub(/^([a-z_\.]+)-$/,'\1') + end + elsif dob.is ==:heading \ + and dob.autonum_ \ + and @md.markup =~/num_extract/ #AS DANGEROUS force enable with document, note already does this type of numbering for cisg, locate and coordinate logic, is currently misplaced in code, chengwei inspired 2004w23/4 + #here lies a bug, as is nil when run from -Dv --update, FIX + if (dob.name.nil? or dob.name.empty?) \ + and dob.ln.to_s =~/^[0-9]/ \ + and dob.obj =~ /^([\d\.]+)/ #risky (must be unique) consider output to 4~~\d instead of 4~\d + dob.name=$1 + dob.tags=set_tags(dob.tags,dob.name) + end + if @md.toc_lev_limit + end + elsif defined? dob.name \ + and dob.name + dob.tags=set_tags(dob.tags,dob.name) + end + dob.tags=dob.tags.uniq if defined? dob.tags + dob + end.flatten + end + def ocn(data) #and auto segment numbering increment + @tuned_file=SiSU_AO_DocumentStructureExtract::OCN.new(@md,data,@fnx,@process).ocn + @tuned_file + end + def xml(data) + @tuned_file=SiSU_AO_DocumentStructureExtract::XML.new(@md,data).dom + @tuned_file + end + def minor_numbering(data) #and auto segment numbering increment + number_small,letter_small=0,0 + letter=%w( a b c d e f g h i j k l m n o p q r s t u v w x y z ) + @tuned_file=data.each.map do |dob| + if dob.of ==:heading \ + || dob.of ==:heading_insert \ + || dob.of ==:para \ + || dob.of ==:block + if dob.is ==:heading \ + and dob.ln.to_s=~/^[0-9]/ #% sub-number system, (baby numbering) reset with any change of major number (more obviously should be placed in number titles, but that is conditionally executed, check and move later) + number_small,letter_small=0,0 + elsif dob.is ==:para + if dob.obj =~/^#[ 1]/ \ + and dob.obj !~/^#\s+(?:~#)?$/ + letter_small=0 + number_small=0 if dob.obj =~ /^#1/ + number_small+=1 + dob.obj=dob.obj.gsub(/^#[ 1]/,"#{number_small}. ") + end + if dob.obj =~/^_# / + dob.obj=dob.obj.gsub(/^_# /,"#{letter[letter_small]}. ") + dob.indent='1' + letter_small+=1 + end + end + end + dob + end.flatten + end + def leading_zeros_fixed_width_number(possible_seg_name) + if possible_seg_name.to_s =~/^([0-9]+?\.|[0-9]+)$/m #!~/[.,:-]+/ + possible_seg_name=possible_seg_name.to_s. + gsub(/\.$/,'') + nl=possible_seg_name.to_s.length + zero='0' + zeros_fixed_width=number_of_segments?.to_s.length + zero_width=(zeros_fixed_width - nl) + zero_width == 0 \ + ? possible_seg_name.to_s + : zero*zero_width + + possible_seg_name.to_s + end + end + def auto_numbering_exceptions(chosen_seg_names_,md,dob) + number_make=case dob.lv.to_i + when 1 + @num_exc={ + t1: @num_exc[:t1] += 1, + t2: 0, + t3: 0, + t4: 0 + } + Mx[:segname_prefix_auto_num_other] + '_' \ + + @num_exc[:t1].to_s + when 2 + @num_exc={ + t1: @num_exc[:t1], + t2: @num_exc[:t2] += 1, + t3: 0, + t4: 0 + } + Mx[:segname_prefix_auto_num_other] + '_' \ + + @num_exc[:t1].to_s + '_' \ + + @num_exc[:t2].to_s + when 3 + @num_exc={ + t1: @num_exc[:t1], + t2: @num_exc[:t2], + t3: @num_exc[:t3] += 1, + t4: 0 + } + Mx[:segname_prefix_auto_num_other] + '_' \ + + @num_exc[:t1].to_s + '_' \ + + @num_exc[:t2].to_s + '_' \ + + @num_exc[:t3].to_s + when 4 + @num_exc[:t4] += 1 + @num_exc={ + t1: @num_exc[:t1], + t2: @num_exc[:t2], + t3: @num_exc[:t3], + t4: @num_exc[:t4] += 1 + } + Mx[:segname_prefix_auto_num_other] + '_' \ + + @num_exc[:t1].to_s + '_' \ + + @num_exc[:t2].to_s + '_' \ + + @num_exc[:t3].to_s + '_' \ + + @num_exc[:t4].to_s + end + end + def check_that_seg_names_are_unique(chosen_seg_names_,chosen_seg_name,type,md,dob) + begin + chosen_seg_names_ << chosen_seg_name + chosen_seg_names_=chosen_seg_names(chosen_seg_names_,chosen_seg_name,dob,md,type) + if chosen_seg_names_.compact.uniq.length \ + == chosen_seg_names_.compact.length + #check that all auto given seg names are unique + chosen_seg_names_=chosen_seg_names(chosen_seg_names_,chosen_seg_name,dob,md,type) + chosen_seg_name + else + SiSU_Utils::CodeMarker.new(__LINE__,__FILE__,:green). + mark( + "duplicated auto segment name: #{type} #{chosen_seg_name}\n" \ + + "#{chosen_seg_names_}\n" \ + + " manually name level 1 segments '1~given_name'\n" \ + + 'filename: ' + md.fns + "\n" \ + + 'heading text: "' + dob.obj + '"' + "\n" \ + + 'duplication: "' + chosen_seg_name + '" (level: ' + dob.lv + '; numbering type: ' + type.to_s + ')' + ) + chosen_seg_name=auto_numbering_exceptions(chosen_seg_names_,md,dob) + check_that_seg_names_are_unique(chosen_seg_names_,chosen_seg_name,:exception,md,dob) + end + rescue + end + end + def auto_seg_name(possible_seg_name,heading_num_is,dob,type) + prefix=case type + when :auto then Mx[:segname_prefix_auto_num_provide] + when :extract then Mx[:segname_prefix_auto_num_extract] + else '_'*dob.lv.to_i #should not occur + end + if possible_seg_name =~/^[0-9]+?\.$/m #!~/[.,:-]+/ + possible_seg_name=possible_seg_name. + gsub(/\.$/,'') + end + @chosen_seg_name= + if dob.lv=='4' \ + and possible_seg_name.to_s =~/^[0-9]+(?:[.,:-][0-9]){3}/m + possible_seg_name=possible_seg_name.to_s. + gsub(/(?:[:,-]|\W)/,'.'). + gsub(/\.$/,'') + prefix + possible_seg_name + elsif dob.lv=='3' \ + and possible_seg_name.to_s =~/^[0-9]+(?:[.,:-][0-9]){2}/m + possible_seg_name=possible_seg_name.to_s. + gsub(/(?:[:,-]|\W)/,'.'). + gsub(/\.$/,'') + prefix + possible_seg_name + elsif dob.lv=='2' \ + and possible_seg_name.to_s =~/^[0-9]+(?:[.,:-][0-9]){1}/m + possible_seg_name=possible_seg_name.to_s. + gsub(/(?:[:,-]|\W)/,'.'). + gsub(/\.$/,'') + prefix + possible_seg_name + elsif dob.lv=='1' \ + and possible_seg_name.to_s =~/^[0-9]+[:,-]?$/m + if possible_seg_name.to_i <= heading_num_is.to_i + prefix + leading_zeros_fixed_width_number(possible_seg_name) + else + possible_seg_name=possible_seg_name.to_s. + gsub(/(?:[:,-]|\W)/,'.'). + gsub(/\.$/,'') + prefix + possible_seg_name + end + else + @chosen_seg_name=auto_numbering_exceptions(@chosen_seg_names,md,dob) + end + check_that_seg_names_are_unique(@chosen_seg_names,@chosen_seg_name,type,@md,dob) + end + def set_name_and_tags(dob,possible_seg_name) + if @md.seg_names.is_a?(Array) \ + and not @md.seg_names.include?(possible_seg_name) + dob.name=possible_seg_name + dob.tags=set_tags(dob.tags,dob.name) + @md.seg_names << possible_seg_name + elsif (@md.opt.act[:verbose_plus][:set]==:on \ + or @md.opt.act[:maintenance][:set]==:on) + puts 'warn, there may be a conflicting numbering scheme' + end + end + def name_para_seg_filename(data) #segment naming, remaining + # paragraph name/numbering rules + # manual naming overrides, manual naming may be + # alpha-numeric characters mixed, + # numeric only (a number), if + # all segments have been named, + # the numbers used are over 1000 or + # it is not minded that auto-numbering uses a funny scheme for naming segments (not yet implemented) + # [for now a warning is printed for such documents on use of maintenance or very-verbose flag] + # auto-naming takes the form of giving numbers to segments + # the rules for which are as follows + # if the title/heading text starts with a numeric, then that is used (1 3.1 3rd etc.) + # otherwise the level 4 segment number from the embedded document structure info is used + # if there is none a sequential number is designated, preceded by an underscore + @tuned_file,@unique_auto_name=[],[] + tags={} + @art_filename_auto=0 + @counter=1 + if not @md.seg_autoname_safe \ + and (@md.opt.act[:verbose_plus][:set]==:on \ + || @md.opt.act[:maintenance][:set]==:on) + puts 'manual segment names, numbers used as names, risk warning (segmented html)' + end + ocn_html_seg=[] + @num_exc={ t1: 0, t2: 0, t3: 0, t4: 0 } + data.each do |dob| + if dob.is==:heading \ + && dob.ln \ + and dob.ln.to_s =~/^[4-7]/ + heading_num_is=/^\d+:(\d+);\d/m.match(dob.node)[1] + if dob.ln==4 \ + and not dob.name \ + and not @md.set_heading_seg + @md.set_heading_seg=true + end + if dob.name !~/^\S+/ \ + and dob.ln.to_s =~/^[5-7]/ \ + and dob.obj =~/^\s*(?:\S+\s+)?([0-9]+(?:[.,:-][0-9])+)/m + #heading starts with a recognised numeric + #or word followed by a recognised numeric construct, + #use that as name + if dob.ln==7 \ + and dob.obj =~/^\s*(?:\S+\s+)?([0-9]+(?:[.,:-][0-9]){3})/m + possible_seg_name=$1. + gsub(/(?:[:,-]|\W)/,'.'). + gsub(/\.$/,'') + possible_seg_name= + auto_seg_name(possible_seg_name,heading_num_is,dob,:extract) + set_name_and_tags(dob,possible_seg_name) + elsif dob.ln==6 \ + and dob.obj =~/^\s*(?:\S+\s+)?([0-9]+(?:[.,:-][0-9]){2})/m + possible_seg_name=$1. + gsub(/(?:[:,-]|\W)/,'.'). + gsub(/\.$/,'') + possible_seg_name= + auto_seg_name(possible_seg_name,heading_num_is,dob,:extract) + set_name_and_tags(dob,possible_seg_name) + elsif dob.ln==5 \ + and dob.obj =~/^\s*(?:\S+\s+)?([0-9]+(?:[.,:-][0-9]){1})/m + possible_seg_name=$1. + gsub(/(?:[:,-]|\W)/,'.'). + gsub(/\.$/,'') + possible_seg_name= + auto_seg_name(possible_seg_name,heading_num_is,dob,:extract) + set_name_and_tags(dob,possible_seg_name) + end + end + if dob.ln==4 + if dob.name !~/^\S+/ \ + and dob.obj =~/^\s*(?:\S+\s+)?([0-9]+)/m + #heading starts with a recognised numeric + #or word followed by a recognised numeric construct, + #use that as name + possible_seg_name=$1 + possible_seg_name= + auto_seg_name(possible_seg_name,heading_num_is,dob,:extract) + set_name_and_tags(dob,possible_seg_name) + end + if dob.name + #extract segment name from embedded document structure info + if @md.seg_names.is_a?(Array) \ + and not @md.seg_names.include?(dob.name) + dob.tags=set_tags(dob.tags,dob.name) + @md.seg_names << dob.name + end + else + #if no segment name, + #provide a numerical one + @art_filename_auto+=1 + possible_seg_name= + auto_seg_name(@art_filename_auto,heading_num_is,dob,:auto) + if @md.seg_names.is_a?(Array) \ + and not @md.seg_names.include?(possible_seg_name) + dob.name=possible_seg_name + dob.tags=set_tags(dob.tags,dob.name) + @md.seg_names << possible_seg_name + else puts 'segment name (numbering) error' + end + end + if not dob.name #should not occur + puts "e r r o r -\t#{__FILE__}::#{__LINE__}\n#{dob.inspect}" + end + end + end + if (dob.is ==:heading \ + || dob.is ==:heading_insert) \ + && dob.ln==4 + @seg=dob.name + end + @tuned_file << if dob.is==:heading \ + && (@md.pagenew || @md.pagebreak || @md.pageline) + m=dob.ln.to_s + dob_tmp=[] + if @md.pagenew.inspect =~/#{m}/ + dob_tmp << + SiSU_AO_DocumentStructure::ObjectLayout.new.break(Hx[:br_page_new]) << + dob + elsif @md.pagebreak.inspect =~/#{m}/ + dob_tmp << + SiSU_AO_DocumentStructure::ObjectLayout.new.break(Hx[:br_page]) << + dob + elsif @md.pageline.inspect =~/#{m}/ + dob_tmp << + SiSU_AO_DocumentStructure::ObjectLayout.new.break(Hx[:br_page_line]) << + dob + end + unless dob_tmp.length > 0; dob + else dob_tmp + end + else dob + end + if defined? dob.ocn \ + and dob.ocn + @segname=((dob.is==:heading || dob.is==:heading_insert) && dob.ln==4 && (defined? dob.name)) \ + ? (dob.name) + : @segname + tags["#{dob.ocn}"]={ segname: @segname } + ocn_html_seg[dob.ocn]=if (dob.is==:heading || dob.is==:heading_insert) + if dob.ln.to_s =~/[0-3]/ + { + seg: nil, + level: dob.ln, + } + #elsif dob.ln =~/[4-6]/ + else + { + seg: @seg, + level: dob.ln, + } + end + else + { + seg: @seg, + level: nil, + } + end + end + dob.tags=dob.tags.uniq if defined? dob.tags + if defined? dob.tags \ + and dob.tags.length > 0 + #@segname=((dob.is=='heading'|| dob.is=='heading_insert') && dob.ln==4 && (defined? dob.name)) \ + #? (dob.name) \ + #: @segname + dob.tags.each do |y| + tags[y]={ ocn: dob.ocn.to_s, segname: @segname } + end + end + dob + end + ocn_html_seg.each_with_index do |ocn,i| + if ocn \ + and ocn[:level].to_s=~/[1-3]/ + (1..4).each do |x| + if ocn_html_seg[i+x] \ + and ocn_html_seg[i+x][:level]==4 + ocn[:seg]=ocn_html_seg[i+x][:seg] + end + end + end + end + if @md.seg_names.length > 0 + @md.set_heading_seg=true + end + tuned_file=@tuned_file.flatten + [tuned_file,tags,ocn_html_seg] + end + def set_heading_top(data) #% make sure no false positives + unless @md.set_heading_top + if (@md.opt.act[:verbose_plus][:set]==:on \ + or @md.opt.act[:maintenance][:set]==:on) + puts "\tdocument contains no top level heading, (will have to manufacture one)" + end + @tuned_file=[] + data.each do |t_o| + unless @md.set_heading_top + if t_o !~/^(?:#{Rx[:meta]}|@\S+:)\s/m \ + and t_o !~/\A\s*\Z/m + @md.set_heading_top=true + if defined? @md.title \ + and @md.title \ + and defined? @md.title.full \ + and defined? @md.creator \ + and @md.creator + head=@md.title.main \ + ? ([@lv='1',@obj=@md.title.main]) + : ([@lv='1',@obj='[no title provided]']) + @tuned_file << head + end + end + end + @tuned_file << t_o + end + @tuned_file=@tuned_file.flatten + end + end + def set_heading_seg(data) #% make sure no false positives + unless @md.set_heading_seg + if (@md.opt.act[:verbose_plus][:set]==:on \ + or @md.opt.act[:maintenance][:set]==:on) + puts "\tdocument contains no segment level, (will have to manufacture one)" + end + @tuned_file=[] + data.each do |dob| + unless @md.set_heading_seg + if defined? dob.ln and dob.ln.to_s !~/^[0-3]/m \ + and dob.obj !~/\A\s*\Z/m \ + and dob.is !=:layout + @md.set_heading_seg=true + head=@md.title.main \ + ? (dob.ln,dob.name,dob.obj=4,'seg',@md.title.main) + : (dob.ln,dob.name,dob.obj=4,'seg','[segment]') + @tuned_file << head + end + end + @tuned_file << dob + end + @tuned_file=@tuned_file.flatten + end + end + def set_header_title(data) #% make sure no false positives + unless @md.set_header_title + if (@md.opt.act[:verbose_plus][:set]==:on \ + or @md.opt.act[:maintenance][:set]==:on) + puts "\t no document title provided, (will have to manufacture one)" + end + @tuned_file=[] + data.each do |t_o| + unless @md.set_header_title + if t_o !~/^%{1,2}\s/m \ + and t_o !~/\A\s*\Z/m + @tuned_file << + "#{Mx[:meta_o]}title#{Mx[:meta_c]} #{@md.heading_seg_first}" + @md.title.main=@md.heading_seg_first + @md.set_header_title=true + end + end + @tuned_file << t_o + end + @tuned_file=@tuned_file.flatten + end + end + end +end +__END__ +#+END_SRC + +** ao_persist.rb + +#+BEGIN_SRC ruby :tangle "../lib/sisu/ao_persist.rb" +# <<sisu_document_header>> +module SiSU_AO_Persist + class Persist + @@persistance=nil + attr_accessor :fns, :ao_arr, :idx_arr_sst, :idx_arr_tex, :idx_arr_html, :idx_arr_xhtml, :map_arr_nametags, :map_arr_ocn_htmlseg + def initialize(args=nil) + @@persistance=args=(args ? args : (@@persistance || persist_init_hash_values)) + @fns=args[:fns] + @ao_arr=args[:ao_arr] + @idx_arr_sst=args[:idx_arr_sst] + @idx_arr_tex=args[:idx_arr_tex] + @idx_arr_html=args[:idx_arr_html] + @idx_arr_xhtml=args[:idx_arr_xhtml] + @map_arr_nametags=args[:map_arr_nametags] + @map_arr_ocn_htmlseg=args[:map_arr_ocn_htmlseg] + end + def fns + @fns + end + def ao_arr + @ao_arr + end + def idx_arr_sst + @idx_arr_sst + end + def idx_arr_tex + @idx_arr_tex + end + def idx_arr_html + @idx_arr_html + end + def idx_arr_xhtml + @idx_arr_xhtml + end + def map_arr_nametags + @map_arr_nametags + end + def map_arr_ocn_htmlseg + @map_arr_ocn_htmlseg + end + def persist_init_hash_values + { + fns: nil, + ao_arr: [], + idx_arr_sst: [], + idx_arr_tex: [], + idx_arr_html: [], + idx_arr_xhtml: [], + map_arr_nametags: [], + map_arr_ocn_htmlseg: [], + } + end + def persist_init + @@persistance=nil + Persist.new(persist_init_hash_values) + end + end + class PersistDocStructExt + @@persist=nil + attr_accessor :ocn, :lng, :lng_is, :code, :lngsyn, :poem, :block, :box, :group, :alt, :quote, :table, :table_to + def initialize(args=nil) + @@persist=args=(args ? args : (@@persist || persist_init_hash_values)) + @ocn=args[:ocn] + @lng=args[:lng] + @lng_is=args[:lng_is] + @code=args[:code] + @lngsyn=args[:lngsyn] + @poem=args[:poem] + @block=args[:block] + @box=args[:box] + @group=args[:group] + @alt=args[:alt] + @quote=args[:quote] + @table=args[:table] + @table_to=args[:table_to] + end + def ocn + @ocn + end + def lng + @lng + end + def lng_is + @lng_is + end + def code + @code + end + def lngsyn + @lngsyn + end + def poem + @poem + end + def block + @block + end + def box + @box + end + def group + @group + end + def alt + @alt + end + def quote + @quote + end + def table + @table + end + def table_to + @table_to + end + def persist_init_hash_values + { + ocn: :on, + lng: :off, + lng_is: :doc_default, + code: :off, + lngsyn: :txt, + poem: :off, + block: :off, + box: :off, + group: :off, + alt: :off, + quote: :off, + table: :off, + table_to: :off, + } + end + def persist_init + @@persist=nil + PersistDocStructExt.new(persist_init_hash_values) + end + end +end +__END__ +#+END_SRC + +** ao_syntax.rb + +#+BEGIN_SRC ruby :tangle "../lib/sisu/ao_syntax.rb" +# <<sisu_document_header>> +module SiSU_AO_Syntax + class Words + def initialize(line,md,mkp) + @line,@md,@mkp=line,md,mkp + end + end + class Markup + def initialize(md='',data='',biblio=[]) + @md,@data,@bibliography=md,data,biblio + @data_new=[] + url_and_stub=SiSU_Env::InfoEnv.new.url + @output_url="#{url_and_stub.remote}" + @env=SiSU_Env::InfoEnv.new + emph_set=if defined? @md.emphasis_set_to \ + and not @md.emphasis_set_to.nil? + @md.emphasis_set_to + else @env.markup_emphasis + end + @emph=case emph_set + when /bold/ + emph_italics=false + { o: Mx[:fa_bold_o], c: Mx[:fa_bold_c] } + when /italics/ + emph_italics=true + { o: Mx[:fa_italics_o], c: Mx[:fa_italics_c] } + when /underscore/ + emph_italics=false + { o: Mx[:fa_underscore_o], c: Mx[:fa_underscore_c] } + else p __LINE__.to_s + '::' + __FILE__ + end + @http_m=%r{\{.+?\}https?://\S+|https?:\S+|:\S+|\.\.\/\S+|#\S+|\S+?\.png\b|[*]~\S+|^#{Mx[:meta_o]}.+|#{Mx[:gr_o]}(?:code(?:\.[a-z][0-9a-z_]+)?|box(?:\.[a-z_]+)?|block|group|alt|verse)(?:-end)?#{Mx[:gr_c]}|#{Mx[:fa_o]}:br#{Mx[:fa_c]}} + @manmkp_ital=emph_italics \ + ? '[i/*]\\{.+?\\}[i/*]' + : '[i/]\\{.+?\\}[i/]' + tail_m_ital=%q{(?:\s|'s\b|[.,;:?!'")]|~\^|~\\\{\s|$)} + tail_m_bold=%{(?:(?:#{Mx[:fa_italics_c]})?(?:\s|'s\b|[.,;:?!'")]|~\^|~\\\{\s|$))?} + bold_line=%{^!_\s.+?(?:#{Mx[:br_line]}|\n|$)} + #ital_line=%{^/_\s.+?(?:#{Mx[:br_line]}|\n|$)} #not implemented + @line_scan_ital=if defined? @md.italics_match_list[:str] + /#{@http_m}|#{bold_line}|#{@manmkp_ital}#{tail_m_ital}|#{@md.italics_match_list[:str]}#{tail_m_ital}|\S+|\n/i + end + @manmkp_bold=emph_italics \ + ? '^!_\s.+?(?:\n|$)|[!b]\\{.+?\\}[*!b]|[*!][a-zA-Z0-9\-_]+[!]' + : '^!_\s.+?(?:\n|$)|[*!b]\\{.+?\\}[*!b]|[*!][a-zA-Z0-9\-_]+[*!]' + @line_scan_bold=if defined? @md.bold_match_list[:str] \ + and @md.bold_match_list[:str] + /#{@http_m}|#{bold_line}|(?:#{@manmkp_bold}|#{@md.bold_match_list[:str]})#{tail_m_bold}|\S+|\n/i + end + end + def songsheet + @data=@data.compact + @data.each do |dob| + dob=breaks(dob) + dob=if @md.sem_tag then sem(dob) else dob end #revisit + dob=line_actions(dob) + dob=paragraph_set(dob) + dob=substitutions(dob) + dob=wordlist_italics(dob) + dob=wordlist_bold(dob) + dob=bodymarkup(dob) + @data_new << dob unless dob.nil? + end + @data_new + end + def sem(dob) #revisit + dob=SiSU_Sem::Tags.new(dob,@md).rm.all + end + def breaks(dob) + if dob.is !=:meta \ + && dob.is !=:comment \ + && dob.is !=:code \ + && dob.is !=:table + dob.obj=dob.obj. + gsub(/^-\\\\-\s*$/,"#{Mx[:br_page]}"). + gsub(/^=\\\\=\s*$/,"#{Mx[:br_page_new]}"). + gsub(/ \\\\(?: |$)/,"#{Mx[:br_line]}"). + gsub(/(?:<:?pb>)/,"#{Mx[:br_page]}"). # depreciated + gsub(/(?:<:?pn>)/,"#{Mx[:br_page_new]}"). # depreciated + gsub(/(?:<:?br>|<br \/>)/,"#{Mx[:br_line]}"). # depreciated + gsub(/(?:^-\.\.-\s*$)/,"#{Mx[:br_page_line]}") + end + dob + end + def wordlist_italics(dob) + dob=dob.dup + if (defined? @md.italics_match_list[:str] \ + and @md.italics_match_list[:str]) + dob.obj=if dob.is !=:meta \ + && dob.is !=:heading \ + && dob.is !=:heading_insert \ + && dob.is !=:code \ + && dob.is !=:layout \ + && dob.is !=:comment + word=dob.obj.scan(@line_scan_ital) + word=word.flatten.compact + line_array=[] + word.each do |w| + unless /#{@manmkp_ital}|#{@http_m}/.match(w) + if defined? @md.italics_match_list[:regx] \ + and @md.italics_match_list[:regx] + w=w.gsub(@md.italics_match_list[:regx], + "#{Mx[:fa_italics_o]}\\1#{Mx[:fa_italics_c]}") + else w + end + end + line_array << w + end + line_array.join(' ') + else dob.obj + end + end + dob + end + def embolden(given) + given=given. + gsub(/^!_\s+((?:\{|#{Mx[:lnk_o]})(?:~^ )?.+?(?:\}|#{Mx[:lnk_o]})https?:\/\/\S+.*?)([#{Mx[:br_line]}#{Mx[:br_paragraph]}#{Mx[:br_nl]}])/, + "#{Mx[:fa_bold_o]} \\1 #{Mx[:fa_bold_c]}\\2"). + gsub(/^!_\s+((?:\{|#{Mx[:lnk_o]})(?:~^ )?.+?(?:\}|#{Mx[:lnk_o]})https?:\/\/\S+.*)/, + "#{Mx[:fa_bold_o]} \\1 #{Mx[:fa_bold_c]}"). + gsub(/(?:^!_|^#{Mx[:lv_o]}[7-9]:\S*?#{Mx[:lv_c]})\s*(.+?)([#{Mx[:br_line]}#{Mx[:br_paragraph]}#{Mx[:br_nl]}])/, + "#{Mx[:fa_bold_o]}\\1#{Mx[:fa_bold_c]}\\2"). + gsub(/(?:^!_|^#{Mx[:lv_o]}[7-9]:\S*?#{Mx[:lv_c]})\s*(.+?)\s+((?:[*]~\S+\s*)+)/, + "#{Mx[:fa_bold_o]}\\1#{Mx[:fa_bold_c]}\\2"). + gsub(/(?:^!_|^#{Mx[:lv_o]}[7-9]:\S*?#{Mx[:lv_c]})\s*(.+?)\s*([~-]#)$/, + "#{Mx[:fa_bold_o]}\\1#{Mx[:fa_bold_c]}\\2"). + gsub(/(?:^!_\s+|^#{Mx[:lv_o]}[7-9]:\S*?#{Mx[:lv_c]}\s*)(.*)?\s*$/, + "#{Mx[:fa_bold_o]}\\1#{Mx[:fa_bold_c]}") + end + def italicise(given) + given=given. + gsub(/^\/_\s*(.+?)([#{Mx[:br_line]}#{Mx[:br_paragraph]}#{Mx[:br_nl]}])/, + "#{Mx[:fa_italics_o]}\\1#{Mx[:fa_italics_c]}\\2"). + gsub(/^\/_\s*(.+?)\s+((?:[*]~\S+\s*)+)/, + "#{Mx[:fa_italics_o]}\\1#{Mx[:fa_italics_c]}\\2"). + gsub(/^\/_\s*(.+?)\s*([~-]#)$/, + "#{Mx[:fa_italics_o]}\\1#{Mx[:fa_italics_c]}\\2"). + gsub(/^\/_\s+(.*)?\s*$/, + "#{Mx[:fa_italics_o]}\\1#{Mx[:fa_italics_c]}") + end + def line_actions(dob) + dob.obj=if (dob.is !=:heading \ + && dob.is !=:heading_insert \ + && dob.is !=:comment \ + && dob.is !=:meta) \ + and dob.obj =~ /^!_\s+/ + embolden(dob.obj) + elsif dob.obj =~ /^\/_\s+/ + italicise(dob.obj) + else dob.obj + end + dob + end + def paragraph_set(dob) + dob.obj=if dob.is !=:meta \ + && dob.is !=:heading \ + && dob.is !=:heading_insert \ + && dob.is !=:code \ + && dob.is !=:comment \ + && dob.is !=:table + dob.obj.gsub(/\n/m,' '). + gsub(/ \s+/m,' ') + else dob.obj + end + dob + end + def substitutions(dob) + dob=dob.dup + dob=if @md.flag_auto_biblio \ + and @bibliography.length > 0 + dob=if dob.is !=:meta \ + && dob.is !=:heading_insert \ + && dob.is !=:code \ + && dob.is !=:comment \ + && dob.is !=:table + @bibliography.each do |c| + if c[:id] and not c[:id].nil? and not c[:id].empty? + dob.obj=dob.obj.gsub(/#{c[:id]}/mi,c[:short_name]) + end + end + dob + else dob + end + dob + else dob + end + dob=if defined? @md.substitution_match_list[:match_and_replace] \ + and @md.substitution_match_list[:match_and_replace].is_a?(Array) + dob=if dob.is !=:meta \ + && dob.is !=:heading_insert \ + && dob.is !=:code \ + && dob.is !=:comment \ + && dob.is !=:table + if dob.obj =~/#{@md.substitution_match_list[:matches]}/ + @md.substitution_match_list[:match_and_replace].each do |x| + dob.obj=if x[:case_s]==:i + dob.obj.gsub(/#{x[:match]}/mi,x[:replace]) + else + dob.obj.gsub(/#{x[:match]}/m,x[:replace]) + end + end + end + dob + else dob + end + dob + else dob + end + end + def wordlist_bold(dob) + dob=dob.dup + if (defined? @md.bold_match_list[:str] \ + and @md.bold_match_list[:str]) + dob.obj=if dob.is !=:meta \ + && dob.is !=:heading \ + && dob.is !=:heading_insert \ + && dob.is !=:code \ + && dob.is !=:comment \ + && dob.is !=:table + line_array=[] + word=dob.obj.scan(@line_scan_bold) + word=word.flatten.compact + word.each do |w| + unless /#{@manmkp_bold}|#{@http_m}/.match(w) + if defined? @md.bold_match_list[:regx] \ + and @md.bold_match_list[:regx] #document header: @bold: [bold word list] + w=w.gsub(@md.bold_match_list[:regx], + "#{Mx[:fa_bold_o]}\\1#{Mx[:fa_bold_c]}") + end + else + w=if w =~ /(?:^!_|^#{Mx[:lv_o]}[7-9]:\S*?#{Mx[:lv_c]})\s+/ + embolden(w) #bold paragraph/emphasize #may wish to remove think about 7{ 8{ conversion not satisfactory, as information is lost! + elsif w =~/^\/_\s+/ + italicise(w) + else w + end + end + line_array << w + end + line_array.join(' ') + else dob.obj + end + else + dob.obj=if dob.is==:heading \ + and dob.ln.to_s =~/[7-9]/ + embolden(dob.obj) + else dob.obj + end + end + dob + end + def fontface_lines(dob,leader) + while (dob.obj =~/#{Mx[:br_nl]}/ \ + and dob.obj =~/(?:#{leader})([*!\/_#])\{(.+?)\}\1/m) \ + and $2 =~/#{Mx[:br_nl]}/ + dob=if dob.obj =~/#{Mx[:br_nl]}/ \ + and dob.obj =~/(#{leader})([*!\/_#])\{(.+?)\}\2/m + lead,fce,txt=$1,$2,$3 + dob=if txt =~/#{Mx[:br_nl]}/ + lead_break=if dob.obj =~/^#{Mx[:br_nl]}/ + dob.obj=dob.obj.sub(/^#{Mx[:br_nl]}/,'') + Mx[:br_nl] + else '' + end + txt="#{lead_break}#{fce}\{" + txt.split(Mx[:br_nl]).join("\}#{fce}#{Mx[:br_nl]}#{fce}\{") + "\}#{fce}" + dob.obj=dob.obj. + sub(/(?:^|#{Mx[:gl_c]}|\s+|['"]|[#{Mx[:nbsp]}#{Mx[:fa_o_c]}#{Mx[:fa_c]}#{Mx[:lnk_o]}#{Mx[:br_nl]}#{Mx[:br_line]}#{Mx[:br_paragraph]}#{Mx[:tc_c]}#{Mx[:tc_p]}]|[\(\[\{]|\>)([*!\/_#])\{.+?\}\1/m, + "#{lead}#{txt}") + dob + else dob + end + end + dob + end + dob + end + def fontface(dob) + leader=/^|#{Mx[:gl_c]}|\s+|['"]|[#{Mx[:nbsp]}#{Mx[:fa_o_c]}#{Mx[:fa_c]}#{Mx[:lnk_o]}#{Mx[:br_nl]}#{Mx[:br_line]}#{Mx[:br_paragraph]}#{Mx[:tc_c]}#{Mx[:tc_p]}]|[\(\[\{]|[、。「‹«¿¡]|\>/ + dob=fontface_lines(dob,leader) + dob.obj=dob.obj. + gsub(/(#{leader})\*\{(.+?)\}\*/m, + "\\1#{@emph[:o]}\\2#{@emph[:c]}"). #emphasis + gsub(/(#{leader})!\{(.+?)\}!/m, + "\\1#{Mx[:fa_bold_o]}\\2#{Mx[:fa_bold_c]}"). #bold + gsub(/(#{leader})\/\{(.+?)\}\//m, + "\\1#{Mx[:fa_italics_o]}\\2#{Mx[:fa_italics_c]}"). #italics + gsub(/(#{leader})_\{(.+?)\}_/m, + "\\1#{Mx[:fa_underscore_o]}\\2#{Mx[:fa_underscore_c]}"). #underscore + gsub(/(#{leader})#\{(.+?)\}#/m, + "\\1#{Mx[:fa_monospace_o]}\\2#{Mx[:fa_monospace_c]}"). #monospace + gsub(/(^|#{Mx[:gl_c]}|\s+|['"]|[#{Mx[:nbsp]}#{Mx[:fa_o_c]}#{Mx[:fa_c]}]|\(|\>)\"\{(.+?)\}\"/m, + "\\1#{Mx[:fa_cite_o]}\\2#{Mx[:fa_c_o]}cite#{Mx[:fa_c]}"). #cite /blockquote? + gsub(/(^|[^\\])\^\{(.+?)\}\^/m, + "\\1#{Mx[:fa_superscript_o]}\\2#{Mx[:fa_superscript_c]}"). #superscript + gsub(/(^|[^\\]),\{(.+?)\},/m, + "\\1#{Mx[:fa_subscript_o]}\\2#{Mx[:fa_subscript_c]}"). #subscript + gsub(/(^|#{Mx[:gl_c]}|\s+|['"]|#{Mx[:nbsp]}|#{Mx[:fa_o_c]}|#{Mx[:fa_c]}|\(|\>)\+\{(.+?)\}\+/m, + "\\1#{Mx[:fa_insert_o]}\\2#{Mx[:fa_insert_c]}"). #inserted text + gsub(/(^|#{Mx[:gl_c]}|\s+|['"]|#{Mx[:nbsp]}|#{Mx[:fa_o_c]}|#{Mx[:fa_c]}|\(|\>)-\{(.+?)\}-/m, + "\\1#{Mx[:fa_strike_o]}\\2#{Mx[:fa_strike_c]}"). #strikethrough - deleted text + gsub(/(^|#{Mx[:gl_c]}|\s+|['"]|#{Mx[:nbsp]}|#{Mx[:fa_o_c]}|#{Mx[:fa_c]}|\(|\>|\d+)\^(\S+?)\^/, + "\\1#{Mx[:fa_superscript_o]}\\2#{Mx[:fa_superscript_c]}") #superscript single word, watch digit added + dob + end + def bodymarkup(dob) + # << http://www.jus.uio.no/sisu/sisu_markup_table/markup >> + # See: data/sisu/sample/document_samples_sisu_markup/ + ## fontface + # *{emphasis}* e{emphasis}e <strong>emphasis</strong> + # !{bold text}! b{bold}b <b>bold text</b> + # _{underline}_ u{underline}u <u>underline</u> + # /{italics}/ i{italics}i <i>italics</i> + # "{citation}" c{citation}c <cite>citation</cite> #blockquote? + # ^{superscript}^ <sup>superscript</sup> + # ,{subscript}, <sub>subscript</sub> + # +{inserted text}+ <ins>inserted text</ins> + # -{deleted text}- <del>deleted text</del> + # #{monospace text}# + # + # {url address}:url + # {image.png}imageurl + # {image.png}png + # ~{endnote}~ + # !_ #bold/emphasise paragraph + # _" #blockquote paragraph + # _1 <:i1> #indent paragraph 1 step + # _2 <:i2> #indent paragraph 2 steps + # _3 <:i3> #indent paragraph 3 steps + # _4 <:i4> #indent paragraph 4 steps + # _* #bullet (list) ● + # _1* #bullet (list) indented + # _1* #bullet (list) indented + # # #numbered (list) level 1 + # _# #numbered (list) level 2 + dob=dob.dup + if dob.is !=:meta \ + && dob.is !=:comment \ + && dob.is !=:code \ + && dob.is !=:table + line_array=[] + word=dob.obj.scan(/\S+|\n/) #unless line =~/^(?:#{Mx[:meta_o]}|%+\s)/ #visit + if word + word.each do |w| # _ - / # | : ! ^ ~ + unless w =~/~\{|\}~|~\[|\]~|^\^~|~\^|\*~\S+|~#|\{t?~|\{table|https?:\/\/\S+/ # do something earlier about table!! + w=w.gsub(/\\?~/,"#{Mx[:gl_o]}#126#{Mx[:gl_c]}") #escaped special character + end + w=w.gsub(/^\<$/, + "#{Mx[:gl_o]}#lt#{Mx[:gl_c]}").gsub(/^\>$/,"#{Mx[:gl_o]}#gt#{Mx[:gl_c]}") #escaped special character + line_array << w + end + dob.obj=line_array.join(' ') + dob.obj=dob.obj.strip + end + dob.obj=dob.obj. + gsub(/^([*#.-]{1,12})$/,'\1 ~#'). #ocn off for these paragraph separators + gsub(/~\{(.+?)\}~/m,Mx[:en_a_o] + '\1' + Mx[:en_a_c]). + gsub(/~\[([^*+].+?)\]~/m,Mx[:en_b_o] + '* \1' + Mx[:en_b_c]). #default if markup does not specify + gsub(/~\[(.+?)\]~/m,Mx[:en_b_o] + '\1' + Mx[:en_b_c]) + if dob.is ==:heading \ + and dob.ln ==0 + dob.obj=dob.obj.gsub(/\s*@title\b/," #{@md.title.full}") + dob.obj=if defined? @md.creator.author \ + and @md.creator.author + dob.obj.gsub(/\s+(?:@creator|@author)/,",#{Mx[:br_line]}#{@md.creator.author}") + else dob.obj.gsub(/\s+(?:@creator|@author)/,'') + end + end + if defined? @md.title \ + and @md.title \ + and defined? @md.title.full \ + and defined? @md.creator \ + and @md.creator + if dob.is ==:heading + dob.obj=dob.obj.gsub(/^\s*@title\s*$/,@md.title.full) if dob.lv =~/1/ + dob.obj=if dob.lv =~/[23]/ \ + and defined? @md.creator.author \ + and @md.creator.author + dob.obj. + gsub(/^\s*(?:(by\s+)?(?:@creator|@author))\s*$/, + "\\1#{@md.creator.author}") + else dob.obj.gsub(/^\s*(?:(by\s+)?(?:@creator|@author))\s*$/,'\1') + end + end + end + dob.obj=dob.obj.gsub(/<(https?:\/\/\S+?)>/,'< \1 >'). #catch problem markup + gsub(/<:=(\S+?)>/,'{ c_\1.png 14x14 }image'). + gsub(/<!(\S+)!>/,'<:\1>'). #escaped special character + gsub(/ /,"#{Mx[:nbsp]}"). #escaped special character + gsub(/\\~/,"#{Mx[:gl_o]}#126#{Mx[:gl_c]}"). #escaped special character + gsub(/\\\{/,"#{Mx[:gl_o]}#123#{Mx[:gl_c]}"). #escaped special character + gsub(/\\\}/,"#{Mx[:gl_o]}#125#{Mx[:gl_c]}"). #escaped special character + gsub(/\\\<</,"#{Mx[:gl_o]}#lt#{Mx[:gl_c]}#{Mx[:gl_o]}#lt#{Mx[:gl_c]}"). #escaped special character + gsub(/\\\>>/,"#{Mx[:gl_o]}#gt#{Mx[:gl_c]}#{Mx[:gl_o]}#gt#{Mx[:gl_c]}"). #escaped special character + gsub(/\\\</,"#{Mx[:gl_o]}#lt#{Mx[:gl_c]}"). #escaped special character + gsub(/\\\>/,"#{Mx[:gl_o]}#gt#{Mx[:gl_c]}"). #escaped special character + gsub(/\\\_/,"#{Mx[:gl_o]}#095#{Mx[:gl_c]}"). #escaped special character + gsub(/\\\-/,"#{Mx[:gl_o]}#045#{Mx[:gl_c]}"). #escaped special character + gsub(/\\\+/,"#{Mx[:gl_o]}#043#{Mx[:gl_c]}"). #escaped special character + gsub(/\\\//,"#{Mx[:gl_o]}#047#{Mx[:gl_c]}"). #escaped special character + gsub(/\\\#/,"#{Mx[:gl_o]}#035#{Mx[:gl_c]}"). #escaped special character + gsub(/\\\&/,"#{Mx[:gl_o]}#038#{Mx[:gl_c]}"). #& #escaped special character + gsub(/\\\|/,"#{Mx[:gl_o]}#124#{Mx[:gl_c]}"). #not really a sisu special character but made available as possibility + gsub(/\\\:/,"#{Mx[:gl_o]}#058#{Mx[:gl_c]}"). #not really a sisu special character but made available as possibility + gsub(/\\\!/,"#{Mx[:gl_o]}#033#{Mx[:gl_c]}"). #not really a sisu special character but made available as possibility + gsub(/\\\^/,"#{Mx[:gl_o]}#094#{Mx[:gl_c]}"). #not really a sisu special character but made available as possibility + gsub(/\\\,/,"#{Mx[:gl_o]}#044#{Mx[:gl_c]}"). #not really a sisu special character but made available as possibility + gsub(/\\\\/,"#{Mx[:gl_o]}#092#{Mx[:gl_c]}"). #escaped special character + gsub(/\\\*/,"#{Mx[:gl_o]}#042#{Mx[:gl_c]}"). #escaped special character + gsub(/\\\!/,"#{Mx[:gl_o]}#033#{Mx[:gl_c]}") #escaped special character + if dob.obj=~/(?:https?:|ftp:|\{([^{}]+?)\}(?:#|:|[.]{1,2}\/))\S+/m + if dob.obj=~/(?:^|[#{Mx[:gl_c]}#{Mx[:nbsp]} ])\{~\^ (?:.+?)\s*\}(?:(?:https?:|ftp:|:|[.]{1,2}\/)\S+?)\s*#{Mx[:en_a_o]}(.+?)#{Mx[:en_a_c]}/m + dob.obj=dob.obj. + gsub(/(^|[#{Mx[:gl_c]}#{Mx[:nbsp]} ])\{~\^ ([^}]+?)\s*\}((?:https?:|ftp:|:|[.]{1,2}\/)\S+?)\s*#{Mx[:en_a_o]}(.+?)#{Mx[:en_a_c]}/m, + "\\1#{Mx[:lnk_o]}\\2#{Mx[:lnk_c]}\\3 #{Mx[:en_a_o]}\\3 \\4#{Mx[:en_a_c]}") # watch + end + if dob.obj=~/(?:^|[#{Mx[:gl_c]}#{Mx[:nbsp]} ])\{~\^ (?:.+?)\s*\}(?:(?:https?:|ftp:|:|[.]{1,2}\/)\S+?)([;,.]?)(?=\s|[#{Mx[:br_line]}#{Mx[:br_paragraph]}#{Mx[:br_nl]}]|$)/m + dob.obj=dob.obj. + gsub(/(^|[#{Mx[:gl_c]}#{Mx[:nbsp]} ])\{~\^ (.+?)\s*\}((?:https?:|ftp:|:|[.]{1,2}\/)\S+?)([;,.]?)(?=\s|[#{Mx[:br_line]}#{Mx[:br_paragraph]}#{Mx[:br_nl]}]|$)/m, + "\\1#{Mx[:lnk_o]}\\2#{Mx[:lnk_c]}\\3\\4 #{Mx[:en_a_o]}\\3#{Mx[:en_a_c]} ") + end + dob.obj=dob.obj. + gsub(/(^|[^#])\{\s*([^{}]+?)\s*\}((?:https?:|:|[.]{2}\/|#)\S+?)(?=\s|[#{Mx[:br_line]}#{Mx[:br_paragraph]}#{Mx[:br_nl]}#{Mx[:en_a_o]}#{Mx[:en_b_o]}]|$)/, + "\\1#{Mx[:lnk_o]}\\2#{Mx[:lnk_c]}\\3"). #linked (text or image, however text cannot include modified face, e.g. bold, ital, underline) + gsub(/(^|[#{Mx[:gl_c]}#{Mx[:lnk_c]}#{Mx[:en_a_o]}#{Mx[:en_b_o]}(\s])((?:https?|ftp):\/\/\S+?\.[^>< ]+?)([,.;'"]?)(?=[\s#{Mx[:en_a_c]}#{Mx[:en_b_c]}#{Mx[:br_line]}#{Mx[:br_paragraph]}#{Mx[:br_nl]}]|$)/m, + %{\\1#{Mx[:url_o]}\\2#{Mx[:url_c]}\\3}). + gsub(/#{Mx[:lnk_c]}#(\S+?[^>< ]+?)([()\[\]]*[,.;:!?'"]{0,2})(?=[\s#{Mx[:en_a_c]}#{Mx[:en_b_c]}#{Mx[:br_line]}#{Mx[:br_paragraph]}#{Mx[:br_nl]}]|$)/m, + %{#{Mx[:lnk_c]}#{Mx[:rel_o]}\\1#{Mx[:rel_c]}\\2}). + gsub(/#{Mx[:lnk_c]}:(\S+?[^>< ]+?)([()\[\]]*[,.;:!?'"]{0,2})(?=[\s#{Mx[:en_a_c]}#{Mx[:en_b_c]}#{Mx[:br_line]}#{Mx[:br_paragraph]}#{Mx[:br_nl]}]|$)/m, + %{#{Mx[:lnk_c]}#{Mx[:rel_o]}:\\1#{Mx[:rel_c]}\\2}). + gsub(/#{Mx[:lnk_c]}[.]{2}\/(\S+?[^>< ]+?)([()\[\]]*[,.;:!?'"]{0,2})(?=[\s#{Mx[:en_a_c]}#{Mx[:en_b_c]}#{Mx[:br_line]}#{Mx[:br_paragraph]}#{Mx[:br_nl]}]|$)/m, + %{#{Mx[:lnk_c]}#{Mx[:rel_o]}:\\1#{Mx[:rel_c]}\\2}) + end + if dob.obj=~/_(?:https?|ftp):\S+/m # _http://url #CHECK + dob.obj=dob.obj.gsub(/(^|[#{Mx[:gl_c]}#{Mx[:lnk_c]}#{Mx[:en_a_o]}#{Mx[:en_b_o]}(\s])(_(?:https?|ftp):\/\/\S+?\.[^>< ]+?)([,.;'"]?)(?=[\s#{Mx[:en_a_c]}#{Mx[:en_b_c]}#{Mx[:br_line]}#{Mx[:br_paragraph]}#{Mx[:br_nl]}]|$)/m, + %{\\1#{Mx[:url_o]}\\2#{Mx[:url_c]}\\3}) + end + dob=fontface(dob) + dob.obj=dob.obj. + gsub(/<[:e]\s+(.+?)!?>/, + "#{Mx[:en_a_o]}\\1#{Mx[:en_a_c]}"). #not tested + gsub(/(^|#{Mx[:br_nl]})\s*_\*\s*/, + "\\1#{Mx[:gl_bullet]}"). #bullets, shortcut + gsub(/=\{(.+?)\}/, + "#{Mx[:idx_o]}\\1#{Mx[:idx_c]}"). + gsub(/^\s*_([1-9])\*\s*/, + "#{Mx[:pa_o]}:i\\1:\\1#{Mx[:pa_c]}#{Mx[:gl_bullet]}"). #bullets, shortcut + gsub(/^\s*_([1-9])\s+/, + "#{Mx[:pa_o]}:i\\1:\\1#{Mx[:pa_c]}"). #indent + gsub(/^\s*_([1-9])!\s+(.+?)\s*$/, + "#{Mx[:pa_o]}:i\\1:\\1#{Mx[:pa_c]}#{Mx[:fa_bold_o]}\\2#{Mx[:fa_bold_c]} "). #indent bold + gsub(/^\s*__([1-9])\s+/, + "#{Mx[:pa_o]}:i0:\\1#{Mx[:pa_c]}"). #hang + gsub(/^\s*__([1-9])!\s+(.+?)\s*$/, + "#{Mx[:pa_o]}:i0:\\1#{Mx[:pa_c]}#{Mx[:fa_bold_o]}\\2#{Mx[:fa_bold_c]} "). #hangdef + gsub(/^\s*_([0-9])_([0-9])\s+/, + "#{Mx[:pa_o]}:i\\1:\\2#{Mx[:pa_c]}"). #hang + gsub(/^\s*_([0-9])_([0-9])!\s+(.+?)\s*$/, + "#{Mx[:pa_o]}:i\\1:\\2#{Mx[:pa_c]}#{Mx[:fa_bold_o]}\\3#{Mx[:fa_bold_c]} "). #hangdef + gsub(/<:hi>/,"#{Mx[:fa_hilite_o]}"). #'<span style="background-color: rgb(255,240,196)">'). # bright yellow rgb(255,255,0) pale yellow rgb(255,255,200) + gsub(/<:\/hi>/,"#{Mx[:fa_hilite_c]}"). #'</span>'). + gsub(/(#{Mx[:gr_o]}verse#{Mx[:gr_c]}.+)/m,"\\1\n"). + gsub(/[ ]+($)/,'\1'). + gsub(/\{\s*(.+?)\s*\}(https?:\S+?)([;,.]?)(?=\s|[#{Mx[:br_line]}#{Mx[:br_paragraph]}#{Mx[:br_nl]}#{Mx[:en_a_o]}#{Mx[:en_b_o]}]|$)/, + "#{Mx[:lnk_o]}\\1#{Mx[:lnk_c]}#{Mx[:url_o]}\\2#{Mx[:url_c]}\\3"). #any remaining linked text or image + gsub(/\{\s*(.+?)\s*\}(#{Mx[:url_o]}\S+?#{Mx[:url_c]})/, + "#{Mx[:lnk_o]}\\1#{Mx[:lnk_c]}\\2"). #any remaining linked text or image + gsub(/(^|\s)([a-zA-Z0-9._-]+\@\S+?\.[a-zA-Z0-9._-]+)/,"\\1#{Mx[:url_o]}\\2#{Mx[:url_c]}"). + gsub(/(^|[ ])\{\s*(.+?)\s*\}(\S+?)([;,.]?)(?=\s|[#{Mx[:br_line]}#{Mx[:br_paragraph]}#{Mx[:br_nl]}#{Mx[:en_a_o]}#{Mx[:en_b_o]}]|$)/, + "\\1#{Mx[:lnk_o]}\\2#{Mx[:lnk_c]}\\3\\4"). #any remaining linked text or image + gsub(/\{\s*(.+?)\s*\}#([a-zA-Z0-9][a-zA-Z0-9_-]*)([;,.]?)(?=\s|[#{Mx[:br_line]}#{Mx[:br_paragraph]}#{Mx[:br_nl]}#{Mx[:en_a_o]}#{Mx[:en_b_o]}]|$)/, + "#{Mx[:lnk_o]}\\1#{Mx[:lnk_c]}#{Mx[:rel_o]}\\2#{Mx[:rel_c]}\\3"). #any remaining linked text or image, check need + gsub(/\{\s*(.+?)\s*\}(#{Mx[:rel_o]}\S+?#{Mx[:rel_c]})/, + "#{Mx[:lnk_o]}\\1#{Mx[:lnk_c]}\\2"). #any remaining linked text or image, check need + gsub(/\{\s*(.+?)\s*\}(image)/, + "#{Mx[:lnk_o]}\\1#{Mx[:lnk_c]}\\2") #linked image + elsif dob.is==:table + dob=fontface(dob) + elsif dob.is ==:code + dob.obj=dob.obj. + gsub(/#{Mx[:meta_o]}(\S+?)#{Mx[:meta_c]}\s*/,'@\1: '). + gsub(/(^|#{Mx[:gl_c]}|\s)<(?:br(?: \/)?)>([\s,.]|$)/,'\1<br>\2') #convert <br> <br /> back, clumsy + if dob.number_ + codeline=[] + ln=1 + dob.obj.split(/#{Mx[:gr_o]}codeline#{Mx[:gr_c]}|<br(?: \/)?>|\n/).each_with_index do |cl,i| + unless i == 0 + cl=cl.gsub(Mx[:br_nl],'') + w=3-ln.to_s.length + cl = "#{ln}#{Mx[:nbsp]*w}#{Mx[:vline]}#{cl}#{Mx[:br_nl]}" + ln +=1 + end + codeline << cl + end + codeline= codeline.join("") + dob.obj=codeline + else + dob.obj=dob.obj.gsub(/#{Mx[:gr_o]}codeline#{Mx[:gr_c]}/,"\n") + end + dob + else # @\S+?: + end + dob + end + def tech #script markup planned to be more strict for technical documents + # *{emphasis}* e{emphasis}e <strong>emphasis</strong> + # !{bold text}! b{bold}b <b>bold text</b> + # _{underline}_ u{underline}u <u>underline</u> + # /{italics}/ i{italics}i <i>italics</i> + # "{citation}" c{citation}c <cite>citation</cite> + # ^{superscript}^ <sup>superscript</sup> + # ,{subscript}, <sub>subscript</sub> + # +{inserted text}+ <ins>inserted text</ins> + # -{deleted text}- <del>deleted text</del> + # #{monospace text}# + # {url address}:url + # {image.png}imageurl + # {image.png}png + # ~{endnote}~ + # +1 <!i1!> + # +2 <!i2!> + puts 'tech' + @data.each do |line| + line=line. + gsub(/(^|\s+|['"]|#{Mx[:fa_o_c]}|#{Mx[:fa_c]}|[\(\[]|\>)e\{(.+?)\}e/, + "\\1#{@emph[:o]}\\2#{@emph[:c]}"). #emphasis + gsub(/(^|\s+|['"]|#{Mx[:fa_o_c]}|#{Mx[:fa_c]}|[\(\[]|\>)b\{(.+?)\}b/, + "\\1#{Mx[:fa_bold_o]}\\2#{Mx[:fa_bold_c]}"). #bold + gsub(/(^|\s+|['"]|#{Mx[:fa_o_c]}|#{Mx[:fa_c]}|[\(\[]|\>)u\{(.+?)\}u/, + "\\1#{Mx[:fa_underscore_o]}\\2#{Mx[:fa_underscore_c]}"). #underscore + gsub(/(^|\s+|['"]|#{Mx[:fa_o_c]}|#{Mx[:fa_c]}|[\(\[]|\>)c\{(.+?)\}c/, + "\\1#{Mx[:fa_cite_o]}\\2#{Mx[:fa_c_o]}cite#{Mx[:fa_c]}"). #cite + gsub(/(^|\s+|['"]|#{Mx[:fa_o_c]}|#{Mx[:fa_c]}|[\(\[]|\>)i\{(.+?)\}i/, + "\\1#{Mx[:fa_italics_o]}\\2#{Mx[:fa_italics_c]}"). #italics + gsub(/(^|\s+|['"]|#{Mx[:fa_o_c]}|#{Mx[:fa_c]}|[\(\[]|\>)!\{(.+?)\}!/, + "\\1#{Mx[:fa_bold_o]}\\2#{Mx[:fa_bold_c]}"). #bold + gsub(/(^|\s+|['"]|#{Mx[:fa_o_c]}|#{Mx[:fa_c]}|[\(\[]|\>)\*\{(.+?)\}\*/, + "\\1#{@emph[:o]}\\2#{@emph[:c]}"). #emphasis + gsub(/(^|\s+|['"]|#{Mx[:fa_o_c]}|#{Mx[:fa_c]}|[\(\[]|\>)_\{(.+?)\}_/, + "\\1#{Mx[:fa_underscore_o]}\\2#{Mx[:fa_underscore_c]}"). #underscore + gsub(/(^|\s+|['"]|#{Mx[:fa_o_c]}|#{Mx[:fa_c]}|[\(\[]|\(|\>)\/\{(.+?)\}\//, + "\\1#{Mx[:fa_italics_o]}\\2#{Mx[:fa_italics_c]}"). #italics + gsub(/(^|\s+|['"]|#{Mx[:fa_o_c]}|#{Mx[:fa_c]}|\(|\>)\"\{(.+?)\}\"/, + "\\1#{Mx[:fa_cite_o]}\\2#{Mx[:fa_c_o]}cite#{Mx[:fa_c]}"). + gsub(/(^|\s+|['"]|#{Mx[:fa_o_c]}|#{Mx[:fa_c]}|\(|\>)\^\{(.+?)\}\^/, + "\\1#{Mx[:fa_superscript_o]}\\2#{Mx[:fa_superscript_c]}"). + gsub(/(^|\s+|['"]|#{Mx[:fa_o_c]}|#{Mx[:fa_c]}|\(|\>)9\{(.+?)\}9/, + "\\1#{Mx[:fa_superscript_o]}\\2#{Mx[:fa_superscript_c]}"). + gsub(/(^|\s+|['"]|#{Mx[:fa_o_c]}|#{Mx[:fa_c]}|\(|\>),\{(.+?)\},/, + "\\1#{Mx[:fa_subscript_o]}\\2#{Mx[:fa_subscript_c]}"). + gsub(/(^|\s+|['"]|#{Mx[:fa_o_c]}|#{Mx[:fa_c]}|\(|\>)6\{(.+?)\}6/, + "\\1#{Mx[:fa_subscript_o]}\\2#{Mx[:fa_subscript_c]}"). + gsub(/(^|\s+|['"]|#{Mx[:fa_o_c]}|#{Mx[:fa_c]}|\(|\>)\+\{(.+?)\}\+/, + "\\1#{Mx[:fa_insert_o]}\\2#{Mx[:fa_insert_c]}"). + gsub(/(^|\s+|['"]|#{Mx[:fa_o_c]}|#{Mx[:fa_c]}|\(|\>)v\{(.+?)\}v/, + "\\1#{Mx[:fa_insert_o]}\\2#{Mx[:fa_insert_c]}"). + gsub(/(^|\s+|['"]|#{Mx[:fa_o_c]}|#{Mx[:fa_c]}|\(|\>)-\{(.+?)\}-/, + "\\1#{Mx[:fa_strike_o]}\\2#{Mx[:fa_strike_c]}"). + gsub(/(^|\s+|['"]|#{Mx[:fa_o_c]}|#{Mx[:fa_c]}|\(|\>)x\{(.+?)\}x/, + "\\1#{Mx[:fa_strike_o]}\\2#{Mx[:fa_strike_c]}"). + gsub(/(^|\s+|['"]|#{Mx[:fa_o_c]}|#{Mx[:fa_c]}|\(|\>)\*(\S+?)\*/, + "\\1#{@emph[:o]}\\2#{@emph[:c]}"). #emphasise single word, watch + gsub(/(^|\s+|['"]|#{Mx[:fa_o_c]}|#{Mx[:fa_c]}|\(|\>)\!(\S+?)\!/, + "\\1#{Mx[:fa_bold_o]}\\2#{Mx[:fa_bold_c]}"). #bold single word, watch + gsub(/(^|\s+|['"]|#{Mx[:fa_o_c]}|#{Mx[:fa_c]}|\(|\>)\/([\(\)a-zA-Z0-9']+?)\/([ ,.;:'"~$]|[^a-zA-Z0-9])/, + "\\1#{Mx[:fa_italics_o]}\\2#{Mx[:fa_italics_c]}\\3"). #italics single word, watch + gsub(/(^|\s+|['"]|#{Mx[:fa_o_c]}|#{Mx[:fa_c]}|\(|\>)_(\S+?)_/, + "\\1#{Mx[:fa_underscore_o]}\\2#{Mx[:fa_underscore_c]}"). #underscore single word, watch + gsub(/(^|\s+|['"]|#{Mx[:fa_o_c]}|#{Mx[:fa_c]}|\(|\>)\^(\S+?)\^/, + "\\1#{Mx[:fa_superscript_o]}\\2#{Mx[:fa_superscript_c]}"). #check #superscript single word, watch digit added + gsub(/^\s*_\([1-9]\)\(\*\+\)\s*/, + "#{Mx[:pa_o]}:i\\1#{Mx[:pa_c]}#{Mx[:fa_o]}\\2#{Mx[:fa_c_o]}"). #bullets, shortcut + gsub(/^\s*_\([1-9]\)\s+/, + "#{Mx[:pa_o]}:i\\1#{Mx[:pa_c]}"). #watch + gsub(/^\s*__\([1-9]\)\s+/, + "#{Mx[:pa_o]}:h\\1#{Mx[:pa_c]}"). #watch + #line.gsub(/^\s*__\([1-9]\)!\s+/, + # "#{Mx[:pa_o]}:hd\\1#{Mx[:pa_c]}"). #watch + gsub(/#{Mx[:br_line]}\s*_[12]\s+/, + "#{Mx[:br_line]} ") #indent used in endnotes, not implemented, replace when ready with: line.gsub(/(?:<br>|<br \/>)\s*_([12])\s+/,'<br><:i\1> ') + end + @data + end + end +end +__END__ +#+END_SRC + +** ao_endnotes.rb + +#+BEGIN_SRC ruby :tangle "../lib/sisu/ao_endnotes.rb" +# <<sisu_document_header>> +module SiSU_AO_Endnotes + class Endnotes + def initialize(md,data,endnote_array=nil) + @md,@data,@endnote_array= + md, data, endnote_array + @endnote_counter, + @endnote_counter_asterisk, + @endnote_counter_dag= + 1,1,1 + end + def endnotes + data=@data + endnote_ref=1 + @tuned_file=data.each.map do |dob| + # manually numbered endnotes <!e(\d)!> <!e_(\d)!> --> + if @md.opt.selections.str =~/--no-asterisk|--no-annotate/ + dob.obj=dob.obj. + gsub(/#{Mx[:en_b_o]}\s.+?#{Mx[:en_b_c]}/,'') + end + if @md.opt.selections.str =~/--no-dagger|--no-annotate/ + dob.obj=dob.obj. + gsub(/#{Mx[:en_b_o]}[+]\s.+?#{Mx[:en_b_c]}/,'') + end + if (defined? dob.obj) \ + && (defined? dob.is) \ + && dob.is !=:code + case dob.obj # auto-numbered endnotes <!e!> <!e_!> --> + when /#{Mx[:en_a_o]}.+?#{Mx[:en_a_c]}|#{Mx[:en_b_o]}[*+]\s+.+?#{Mx[:en_b_c]}/ + dob.obj=dob.obj. + gsub(/\s*(#{Mx[:en_a_c]}|#{Mx[:en_b_c]})/,'\1') + word_mode=dob.obj.scan(/\S+/m) + word_mode=endnote_call_number(word_mode) + dob.obj=word_mode.join(' ') + endnote_ref+=1 + when /~\^(?:\s|$)/ #%note inserts endnotes previously gathered from /^(<!e[:_]!>|[-~]\{{3})/ (in earlier loop) + word_mode=dob.obj.scan(/\S+/m) + word_mode=endnote_call_number(word_mode) + dob.obj=word_mode.join(' ') + endnote_ref+=1 + end + end + dob + end.flatten + @endnote_counter, + @endnote_counter_asterisk, + @endnote_counter_dag= + 1,1,1 + @tuned_file + end + def endnote_call_number(words) + words.each do |word| + case word + when /#{Mx[:en_a_o]}/ + unless word =~/#{Mx[:en_a_o]}[*+]+/ + word.gsub!(/#{Mx[:en_a_o]}/, + "#{Mx[:en_a_o]}#{@endnote_counter} ") + @endnote_counter+=1 + end + when /#{Mx[:en_b_o]}/ + if word =~/#{Mx[:en_b_o]}[+]/ + word.gsub!(/#{Mx[:en_b_o]}[+]/, + "#{Mx[:en_b_o]}\+#{@endnote_counter_dag} ") + @endnote_counter_dag+=1 + else + word.gsub!(/#{Mx[:en_b_o]}[*]?/, + "#{Mx[:en_b_o]}\*#{@endnote_counter_asterisk} ") + @endnote_counter_asterisk+=1 + end + when /~\^/ + if @endnote_array + word.gsub!(/~\^/, + "#{@endnote_array[@endnote_counter-1]}") + @endnote_counter+=1 + end + end + end + end + end +end +__END__ +#+END_SRC + +* document header + +#+NAME: sisu_document_header +#+BEGIN_SRC text +encoding: utf-8 +- Name: SiSU + + - Description: documents, structuring, processing, publishing, search + abstraction + + - Author: Ralph Amissah + <ralph.amissah@gmail.com> + + - Copyright: (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, + 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2019, + 2020, 2021, Ralph Amissah, + All Rights Reserved. + + - License: GPL 3 or later: + + SiSU, a framework for document structuring, publishing and search + + Copyright (C) Ralph Amissah + + This program is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by the Free + Software Foundation, either version 3 of the License, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. + + You should have received a copy of the GNU General Public License along with + this program. If not, see <http://www.gnu.org/licenses/>. + + If you have Internet connection, the latest version of the GPL should be + available at these locations: + <http://www.fsf.org/licensing/licenses/gpl.html> + <http://www.gnu.org/licenses/gpl.html> + + <http://www.sisudoc.org/sisu/en/manifest/gpl.fsf.html> + + - SiSU uses: + - Standard SiSU markup syntax, + - Standard SiSU meta-markup syntax, and the + - Standard SiSU object citation numbering and system + + - Homepages: + <http://www.sisudoc.org> + + - Git + <https://git.sisudoc.org/projects/> + <https://git.sisudoc.org/projects/?p=software/sisu.git;a=summary> + <https://git.sisudoc.org/projects/?p=markup/sisu-markup-samples.git;a=summary> +#+END_SRC -- cgit v1.2.3