aboutsummaryrefslogtreecommitdiffhomepage
path: root/org/abstraction.org
diff options
context:
space:
mode:
authorRalph Amissah <ralph.amissah@gmail.com>2021-04-02 19:37:00 -0400
committerRalph Amissah <ralph.amissah@gmail.com>2021-04-02 20:03:27 -0400
commit90051a7ea55acb043434b1c2483b878d602246ba (patch)
tree9e803c11a0ac4e37023b3c79f19f5b372d4175ee /org/abstraction.org
parentnix ruby 3.0 (available) (diff)
org mode (ruby code within)
Diffstat (limited to 'org/abstraction.org')
-rw-r--r--org/abstraction.org7291
1 files changed, 7291 insertions, 0 deletions
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"
+# <<sisu_document_header>>
+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 <Instantiate
+ def initialize(opt,fnx=nil,process=:complete)
+ @opt,@fnx,@process=opt,fnx,process
+ @per ||=SiSU_AO_Persist::Persist.new.persist_init
+ @per.fns ||=opt.fns
+ fn_use=if fnx \
+ and fnx =~/\.ss[tmi]$/
+ fnx
+ elsif opt.fns =~/\.ssm$/
+ opt.fns + '.sst'
+ else
+ opt.fns
+ end
+ @make_fns=SiSU_Env::InfoFile.new(fn_use)
+ @fnm=@make_fns.marshal.ao_metadata
+ @fnc=@make_fns.marshal.ao_content
+ @idx_sst=@make_fns.marshal.ao_idx_sst_rel_html_seg
+ @idx_raw=@make_fns.marshal.ao_idx_sst_rel
+ @idx_html=@make_fns.marshal.ao_idx_html
+ @idx_xhtml=@make_fns.marshal.ao_idx_xhtml
+ @map_nametags=@make_fns.marshal.ao_map_nametags
+ @map_ocn_htmlseg=@make_fns.marshal.ao_map_ocn_htmlseg
+ @env=SiSU_Env::InfoEnv.new
+ end
+ def read #creates ao
+ begin
+ @per=SiSU_AO_Persist::Persist.new
+ @per.ao_arr=[]
+ @per.fns=(@fnx && @fnx =~/\.ss[tmi]$/) \
+ ? @fnx
+ : @opt.fns
+ create_ao
+ rescue
+ SiSU_Errors::Rescued.new($!,$@,@opt.selections,@per.fns).location do
+ __LINE__.to_s + ':' + __FILE__
+ end
+ ensure
+ SiSU_AO_Persist::Persist.new.persist_init
+ SiSU_AO::Instantiate.new
+ end
+ end
+ def get #reads ao, unless does not exist then creates first
+ begin
+ ao=[]
+ unless @per.fns==@opt.fns \
+ or @per.fns==@fnx
+ @per.fns=(@fnx && @fnx =~/\.ss[tmi]$/) \
+ ? @fnx
+ : @opt.fns
+ @per.ao_arr=[]
+ end
+ ao=(@per.ao_arr.empty?) \
+ ? read_fnc
+ : @per.ao_arr.dup
+ rescue
+ SiSU_Errors::Rescued.new($!,$@,@opt.selections,@opt.fns).location do
+ __LINE__.to_s + ':' + __FILE__
+ end
+ ensure
+ SiSU_AO::Instantiate.new
+ end
+ end
+ def get_idx_sst #reads ao idx.sst, #unless does not exist then creates first
+ begin
+ ao=[]
+ unless @per.fns==@opt.fns \
+ or @per.fns==@fnx
+ @per.fns=(@fnx && @fnx =~/\.ss[tmi]$/) \
+ ? @fnx
+ : @opt.fns
+ @per.idx_arr_sst=[]
+ end
+ ao=(@per.idx_arr_sst.empty?) \
+ ? read_idx_sst
+ : @per.idx_arr_sst.dup #check
+ rescue
+ SiSU_Errors::Rescued.new($!,$@,@opt.selections,@opt.fns).location do
+ __LINE__.to_s + ':' + __FILE__
+ end
+ ensure
+ SiSU_AO::Instantiate.new
+ end
+ end
+ def get_idx_raw
+ begin
+ ao=[]
+ unless @per.fns==@opt.fns \
+ or @per.fns==@fnx
+ @per.fns=(@fnx && @fnx =~/\.ss[tmi]$/) \
+ ? @fnx
+ : @opt.fns
+ @per.idx_arr_tex=[]
+ end
+ ao=(@per.idx_arr_tex.empty?) \
+ ? read_idx_raw
+ : @per.idx_arr_tex.dup #check
+ rescue
+ SiSU_Errors::Rescued.new($!,$@,@opt.selections,@opt.fns).location do
+ __LINE__.to_s + ':' + __FILE__
+ end
+ ensure
+ SiSU_AO::Instantiate.new
+ end
+ end
+ def get_idx_html #reads ao idx.html, #unless does not exist then creates first
+ begin
+ ao=[]
+ unless @per.fns==@opt.fns \
+ or @per.fns==@fnx
+ @per.fns=(@fnx && @fnx =~/\.ss[tmi]$/) \
+ ? @fnx
+ : @opt.fns
+ @per.idx_arr_html=[]
+ end
+ ao=(@per.idx_arr_html.empty?) \
+ ? read_idx_html
+ : @per.idx_arr_html.dup
+ rescue
+ SiSU_Errors::Rescued.new($!,$@,@opt.selections,@opt.fns).location do
+ __LINE__.to_s + ':' + __FILE__
+ end
+ ensure
+ SiSU_AO::Instantiate.new
+ end
+ end
+ def get_idx_xhtml #reads ao idx.xhtml, #unless does not exist then creates first
+ begin
+ ao=[]
+ unless @per.fns==@opt.fns \
+ or @per.fns==@fnx
+ @per.fns=(@fnx && @fnx =~/\.ss[tmi]$/) \
+ ? @fnx
+ : @opt.fns
+ @per.idx_arr_xhtml=[] #...
+ end
+ ao=(@per.idx_arr_xhtml.empty?) \
+ ? read_idx_xhtml
+ : @per.idx_arr_xhtml.dup
+ rescue
+ SiSU_Errors::Rescued.new($!,$@,@opt.selections,@opt.fns).location do
+ __LINE__.to_s + ':' + __FILE__
+ end
+ ensure
+ SiSU_AO::Instantiate.new
+ end
+ end
+ def get_map_nametags #reads ao map.nametags, #unless does not exist then creates first
+ begin
+ ao=[]
+ unless @per.fns==@opt.fns \
+ or @per.fns==@fnx
+ @per.fns=(@fnx && @fnx =~/\.ss[tmi]$/) \
+ ? @fnx
+ : @opt.fns
+ @per.map_arr_nametags=[]
+ end
+ ao=(@per.map_arr_nametags.empty?) \
+ ? read_map_nametags
+ : @per.map_arr_nametags.dup
+ rescue
+ SiSU_Errors::Rescued.new($!,$@,@opt.selections,@opt.fns).location do
+ __LINE__.to_s + ':' + __FILE__
+ end
+ ensure
+ SiSU_AO::Instantiate.new
+ end
+ end
+ def get_map_ocn_htmlseg #reads ao map.ocn_htmlseg, #unless does not exist then creates first
+ begin
+ ao=[]
+ unless @per.fns==@opt.fns \
+ or @per.fns==@fnx
+ @per.fns=(@fnx && @fnx =~/\.ss[tmi]$/) \
+ ? @fnx
+ : @opt.fns
+ @per.map_arr_ocn_htmlseg=[]
+ end
+ ao=(@per.map_arr_ocn_htmlseg.empty?) \
+ ? read_map_ocn_htmlseg
+ : @per.map_arr_ocn_htmlseg.dup
+ rescue
+ SiSU_Errors::Rescued.new($!,$@,@opt.selections,@opt.fns).location do
+ __LINE__.to_s + ':' + __FILE__
+ end
+ ensure
+ SiSU_AO::Instantiate.new
+ end
+ end
+ protected
+ def create_ao
+ ao_array=[]
+ fnp = @fnx ? "#{@opt.fno} #{@fnx}" : @opt.fno
+ unless @opt.act[:quiet][:set]==:on
+ tell=(@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],
+ 'Document Abstraction'
+ )
+ : SiSU_Screen::Ansi.new(
+ @opt.act[:color_state][:set],
+ 'Document Abstraction',
+ "[#{@opt.f_pth[:lng_is]}] #{fnp}"
+ )
+ tell.blue_title_hi
+ end
+ fn=(@fnx && @fnx =~/\.ss[tmi]$/) \
+ ? @fnx
+ : @opt.fns
+ if @opt.fno =~/\.txz$/
+ Dir.chdir(@opt.f_pth[:pth])
+ end
+ meta=file_array=@env.source_file_processing_array(fn)
+ @md=SiSU_Param::Parameters::Instructions.new(meta,@opt).extract
+ meta=nil
+ ao=SiSU_AO::Make.new(fn,@md,file_array,@fnx,@process).song
+ if (@opt.act[:verbose][:set]==:on \
+ || @opt.act[:verbose_plus][:set]==:on \
+ || @opt.act[:maintenance][:set]==:on)
+ cf=SiSU_Env::CreateFile.new(fn)
+ if (@opt.act[:verbose][:set]==:on \
+ || @opt.act[:verbose_plus][:set]==:on)
+ SiSU_Screen::Ansi.new(
+ @opt.act[:color_state][:set],
+ @opt.fns,
+ "~meta/#{@opt.fns}.meta"
+ ).output
+ elsif @opt.act[:maintenance][:set]==:on
+ SiSU_Screen::Ansi.new(
+ @opt.act[:color_state][:set],
+ "ao -> #{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"
+# <<sisu_document_header>>
+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>(?:editor|edited by)\s+.+?)}
+ end
+ def year_pattern
+ %r{[(\[]?(?<year>\d{4})[\])]?[.,]?}
+ end
+ def authors_year_title_publication_editor_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]})\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 #&lsquo; &rsquo; #&ldquo; &rdquo;
+ gsub(/\\copy(?:right)?\b/,'&#169;').
+ gsub(/\\trademark\b|\\tm\b/,'&#174;')
+ 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 #&nbsp; 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(/&/,'&amp;')
+ 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(/&nbsp;/,"#{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]}"). #&amp; #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)&lt;(?:br(?: \/)?)&gt;([\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