diff options
| author | Ralph Amissah <ralph.amissah@gmail.com> | 2021-04-02 19:37:00 -0400 | 
|---|---|---|
| committer | Ralph Amissah <ralph.amissah@gmail.com> | 2021-04-02 20:03:27 -0400 | 
| commit | 90051a7ea55acb043434b1c2483b878d602246ba (patch) | |
| tree | 9e803c11a0ac4e37023b3c79f19f5b372d4175ee /org | |
| parent | nix ruby 3.0 (available) (diff) | |
org mode (ruby code within)
Diffstat (limited to 'org')
| -rw-r--r-- | org/abstraction.org | 7291 | ||||
| -rw-r--r-- | org/cgi.org | 1459 | ||||
| -rw-r--r-- | org/config.org | 310 | ||||
| -rw-r--r-- | org/css.org | 3508 | ||||
| -rw-r--r-- | org/db.org | 4808 | ||||
| -rw-r--r-- | org/digests.org | 330 | ||||
| -rw-r--r-- | org/env.org | 8610 | ||||
| -rw-r--r-- | org/harvest.org | 1454 | ||||
| -rw-r--r-- | org/html.org | 5971 | ||||
| -rw-r--r-- | org/hub.org | 3163 | ||||
| -rw-r--r-- | org/i18n.org | 2453 | ||||
| -rw-r--r-- | org/json.org | 1620 | ||||
| -rw-r--r-- | org/manpage.org | 436 | ||||
| -rw-r--r-- | org/misc.org | 4107 | ||||
| -rw-r--r-- | org/object_munge.org | 331 | ||||
| -rw-r--r-- | org/param.org | 2363 | ||||
| -rw-r--r-- | org/shared.org | 2297 | ||||
| -rw-r--r-- | org/sisu.org | 128 | ||||
| -rw-r--r-- | org/src.org | 3437 | ||||
| -rw-r--r-- | org/sst.org | 1713 | ||||
| -rw-r--r-- | org/texinfo.org | 946 | ||||
| -rw-r--r-- | org/texpdf.org | 2969 | ||||
| -rw-r--r-- | org/txt.org | 3205 | ||||
| -rw-r--r-- | org/utils.org | 857 | ||||
| -rw-r--r-- | org/xhtml.org | 5080 | ||||
| -rw-r--r-- | org/xml.org | 5583 | 
26 files changed, 74429 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 #‘ ’ #“ ” +            gsub(/\\copy(?:right)?\b/,'©'). +            gsub(/\\trademark\b|\\tm\b/,'®') +          dob.obj=dob.obj + "\n" +          unless dob.is ==:code +            case dob.obj +            when /\^~/                                     #% Note must do this first (earlier loop) and then enter gathered data into ~^\d+ +              sub_dob=dob.obj.dup +              @endnote_array << sub_dob.gsub(/\n/,''). +                gsub(/\^~\s+(.+)\s*/, +                  %{#{Mx[:en_a_o]}#{endnote_no} \\1 #{Mx[:en_a_c]}}). +                  strip +              endnote_no+=1 +              dob=nil if dob.obj =~/\^~ .+/                #watch, removes 'binary' endnote now in endnote array for later insertion +            end +          end +        end +        dob if dob.is_a?(Object) +      end.flatten.compact +      [@tuned_file,@endnote_array] +    end +  end +end +#+END_SRC + +** ao_composite.rb + +#+BEGIN_SRC ruby  :tangle "../lib/sisu/ao_composite.rb" +# <<sisu_document_header>> +module SiSU_Assemble +  require_relative 'se'                                 # se.rb +  require_relative 'utils_composite'                    # utils_composite.rb +  class RemoteImage +    def initialize +      @env=SiSU_Env::InfoEnv.new +    end +    def image(dir) +      images=[] +      images[0]=dir +      images +    end +    def download_images(images_info) +      path="#{@env.processing_path.processing}/external_document/image" +      FileUtils::mkdir_p(path) \ +        unless FileTest.directory?(path) +      download_from=images_info.shift +      images_info.each do |i| +        image="#{path}/#{i}" +        imagefile=File.new(image,'w+') +        open("#{download_from}/#{i}") do |g| +          imagefile << g.read +        end +        imagefile.close +      end +      output_path="#{@env.path.webserv}/#{@env.path.base_markup_dir_stub}/_sisu/image_external" +      FileUtils::mkdir_p(output_path) \ +        unless FileTest.directory?(output_path) +      SiSU_Env::SystemCall.new("#{path}/*",output_path,'q').rsync +    end +  end +  class Composite +    include SiSU_Composite_Doc_Utils # composite doc, .ssm, extract all related insert files, array of filenames test +    def initialize(opt) +      @opt=opt +      @env=SiSU_Env::InfoEnv.new +    end +    def read +      begin +        pwd=Dir.pwd +        Dir.chdir(@opt.f_pth[:pth]) +        if @opt.fno =~/\S+?\.ssm$/ +          SiSU_Screen::Ansi.new( +            @opt.act[:color_state][:set], +            'Composite Document', +            "[#{@opt.f_pth[:lng_is]}] #{@opt.fno}", +          ).grey_title_hi unless @opt.act[:quiet][:set]==:on +          composite_and_imported_filenames_array(@opt.fno) # composite doc, .ssm, extract all related insert files, array of filenames test +          assembled=loadfile(@opt.fno) +          write(assembled) +        end +        Dir.chdir(pwd) +      rescue +        SiSU_Errors::Rescued.new($!,$@,@opt.selections.str,@opt.fns). +          location do +          __LINE__.to_s + ':' + __FILE__ +        end +      ensure +      end +    end +    def insert?(para) +      if para =~ /^<<\s+((?:https?|file):\/\/\S+?\.ss[it])$/ # and NetTest +        url($1.strip) +      elsif para =~/^<<\s+(\S+?\.ss[it])$/ +        loadfilename=$1.strip +        insert_array=loadfile(loadfilename) +        file=insertion(loadfilename,insert_array) +        file[:prepared] +      else para +      end +    end +    def loadfile(loadfilename) +      begin +        if FileTest.file?(loadfilename) +          insert_array=IO.readlines(loadfilename,'') +          if loadfilename =~/\S+?\.ss[itm]$/ +            if (@opt.act[:verbose][:set]==:on \ +            || @opt.act[:verbose_plus][:set]==:on \ +            || @opt.act[:maintenance][:set]==:on) +              SiSU_Screen::Ansi.new( +                @opt.act[:color_state][:set], +                'loading:', +                loadfilename, +              ).txt_grey +            end +            tuned_file=if loadfilename =~/\S+?\.ss[im]$/ +              insert_array.each.map do |para| +                insert?(para) +              end +            elsif loadfilename =~/\S+?\.sst$/ +              insert_array.each.map do |para| +                para +              end +            end.flatten.compact +          end +        end +      rescue +        SiSU_Errors::Rescued.new($!,$@,@opt.selections.str,@opt.fns).location do +          __LINE__.to_s + ':' + __FILE__ +        end +      ensure +      end +    end +    def url(loadfilename) +      if loadfilename =~ /((?:https?|file):\/\/\S+?\.ss[it])$/ # and NetTest +        loadfilename=$1 +        begin +          require 'uri' +          require 'open-uri' +          require 'pp' +        rescue LoadError +          SiSU_Utils::CodeMarker.new(__LINE__,__FILE__,:fuchsia). +            error('uri, open-uri or pp NOT FOUND (LoadError)') +        end +        insert=open(loadfilename) +        insert_array=insert.dup +        insert.close +        file=insertion(loadfilename,insert_array) +        file[:prepared] +      end +    end +    def write(assembled) +      assembled_file=File.new("#{@env.processing_path.composite_file}/#{@opt.fnb}.ssm.sst",'w+') +      assembled.each {|a| assembled_file << a } +      assembled_file.close +    end +    def download_images(download_from,images_array) +      path="#{@env.processing_path.processing}/external_document/image" +      FileUtils::mkdir_p(path) unless FileTest.directory?(path) +      images_array.each do |i| +        image="#{path}/#{i}" +        unless FileTest.exists?(image) +          imagefile=File.new(image,'w+') +          open("#{download_from}/#{i}") do |g| +            imagefile << g.read +          end +          imagefile.close +        end +      end +    end +    def insertion(fni,insert_array) +      file={ prepared: [], images: [] } +      rgx_image=/(?:^|[^_\\])\{\s*(\S+?\.(?:png|jpg|gif))/ +      file[:prepared] << "\n% |#{fni}|@|^|>>ok\n\n" +      @code_flag=false +      insert_array.each do |i| +        @code_flag=if i =~/^code\{/ then true +        elsif i =~/^\}code/         then false +        else @code_flag +        end +        if not @code_flag \ +        and i !~/^%+\s/ +          i=i. +            gsub(/^([123]|:?[ABCD])~\? /, +              '% [conditional heading:] \1~ ')    #off conditional heading (consider syntax) +          if i =~/^@\S+?:/ +            i=i.gsub(/\n/m,"\n%  "). +              gsub(/\n%\s+$/m,''). +              gsub(/^@\S+?:/m,"\n% [imported header:] ")                       #off imported headers +          end +        end +        file[:prepared] << i +        if i !~/^%+\s/ \ +        and i =~rgx_image +          file[:images] << i.scan(rgx_image).uniq +        end +      end +      file[:prepared] << "\n% end import" << "\n\n" +      if file[:images].length > 0 +        file[:images]=file[:images].flatten.uniq +        file[:images].delete_if {|x| x =~/https?:\/\// } +      end +      file +    end +  end +  class CompositeFileList +    def initialize(opt) +      @opt=opt +      @env=SiSU_Env::InfoEnv.new +    end +    def read +      begin +        @opt.fns=@opt.fns.gsub(/\.ssm\.sst$/,'.ssm') #FIX earlier, hub +        fns_array=IO.readlines(@opt.fns,'') +        insertions?(fns_array) +      rescue +        SiSU_Errors::Rescued.new($!,$@,@opt.selections.str,@opt.fns).location do +          __LINE__.to_s + ':' + __FILE__ +        end +      ensure +      end +    end +    def insertions?(fns_array) +      tuned_file=[] +      SiSU_Screen::Ansi.new( +        @opt.act[:color_state][:set], +        'Composite Document', +        @opt.fno +      ).grey_title_hi unless @opt.act[:quiet][:set]==:on +      @ssm=[@opt.fns] +      fns_array.each do |para| +        if para =~/^<<\s+(\S+?\.ss[it])$/ +          loadfilename=$1.strip +          if (@opt.act[:verbose][:set]==:on \ +          || @opt.act[:verbose_plus][:set]==:on \ +          || @opt.act[:maintenance][:set]==:on) +            SiSU_Screen::Ansi.new( +              @opt.act[:color_state][:set], +              'loading:', +              loadfilename, +            ).txt_grey +          end +          tuned_file << if loadfilename =~ /(?:https?|file):\/\/\S+?\.ss[it]$/ +            @ssm << loadfilename +          elsif loadfilename =~ /\.ss[it]$/ \ +          and FileTest.file?(loadfilename) +            @ssm << loadfilename +          else +            STDERR.puts %{SKIPPED processing file: [#{@opt.lng}] "#{@opt.fns}" it requires an invalid or non-existent file: "#{loadfilename}"} +            $process_document = :skip; break #remove this line to continue processing documents that have missing include files +            para +          end +        end +      end +      @ssm +    end +  end +end +__END__ +#+END_SRC + +** ao_doc_objects.rb + +#+BEGIN_SRC ruby  :tangle "../lib/sisu/ao_doc_objects.rb" +# <<sisu_document_header>> +Module SiSU_AO_DocumentStructure +  class Extract +    def extract(h,o) +      h ? h : o +    end +  end +  class ObjectMetadata +    attr_accessor :is,:of,:tags,:obj,:digest +    def initialize +      @tags={} +      @is=@tmp=@digest=nil +      @of=:meta +    end +    def metadata(tags) +      of      = @of                                                                 #Symbol, classification - group +      is      = :meta                                                               #Symbol, classification - specific type +      tags    = tags            || ((defined? o.tags)      ? o.tags        : {})    #String, metadata type/tag +      obj     = nil +      @of,@is,@tags,@obj=of,is,tags,obj +      self +    end +  end +  class ObjectMeta +    attr_accessor :obj,:is,:of,:tag,:digest,:tmp +    def initialize +      @is=@obj=@tag=@digest=@digest=@tmp=nil +      @of=:meta +    end +    def metadata(h,o=nil) +      of      = @of                                                                 #Symbol, classification - group +      is      = :meta                                                               #Symbol, classification - specific type +      tag     = h[:tag]         || ((defined? o.tag)       ? o.tag         : nil)   #String, metadata type/tag +      obj     = h[:obj]         || ((defined? o.obj)       ? o.obj         : nil)   #String, text content +      tmp     = h[:tmp]         || ((defined? o.tmp)       ? o.tmp         : nil)   #available for processing, empty after use +      digest  = h[:digest]      || ((defined? o.digest)    ? o.digest      : nil)   #hash digests, sha512, sha256 or md5 +      @of,@is,@tag,@obj,@digest,@tmp=of,is,tag,obj,digest,tmp +      self +    end +  end +  class ObjectHeading +    attr_accessor :obj,:is,:tags,:of,:lv,:ln,:lc,:use_,:name,:idx,:ocn,:odv,:osp,:node,:parent,:ocn_,:note_,:autonum_,:digest,:tmp +    def initialize +      @of=:para +      @is=@obj=@lv=@ln=@lc=@use_=@name=@idx=@size=@ocn=@odv=@osp=@node=@parent=@ocn_=@note_=@autonum_=@digest=@tmp=nil +      @tags=[] +    end +    def heading_ln(lv) +      case lv +      when /A/ then 0 +      when /B/ then 1 +      when /C/ then 2 +      when /D/ then 3 +      when /1/ then 4 +      when /2/ then 5 +      when /3/ then 6 +      when /4/ then 7 +      when /5/ then 8 +      when /6/ then 9 +      end +    end +    def heading_lv(ln) +      case ln.to_s +      when /0/ then 'A' +      when /1/ then 'B' +      when /2/ then 'C' +      when /3/ then 'D' +      when /4/ then '1' +      when /5/ then '2' +      when /6/ then '3' +      when /7/ then '4' +      when /8/ then '5' +      when /9/ then '6' +      end +    end +    def heading(h,o=nil) +      if not h[:ln] \ +      and (h[:lv] and h[:lv]=~/[1-6A-D]/) +        h[:ln]=heading_ln(h[:lv]) +      elsif not h[:lv] \ +      and (h[:ln] and h[:ln].to_s=~/[0-9]/) +        h[:lv]=heading_lv(h[:ln]) +      end +      of      = @of                                                                 #Symbol, classification - group +      is      = :heading                                                            #Symbol, classification - specific type +      name    = h[:name]        || ((defined? o.name)      ? o.name        : nil)   #String, named object? +      tags    = h[:tags]        || ((defined? o.tags)      ? o.tags        : [])    #Array, associated object tags, names if any +      obj     = h[:obj]         || ((defined? o.obj)       ? o.obj         : nil)   #String, text content +      idx     = h[:idx]         || ((defined? o.idx)       ? o.idx         : nil)   #String, book index provided? +      ocn     = h[:ocn]         || ((defined? o.ocn)       ? o.ocn         : nil)   #Integer, sequential on substantive-content objects +      odv     = h[:odv]         || ((defined? o.odv)       ? o.odv         : nil) +      osp     = h[:osp]         || ((defined? o.osp)       ? o.osp         : nil) +      node    = h[:node]        || ((defined? o.node)      ? o.node        : nil)   #[Node relationship doc structure info] +      parent  = h[:parent]      || ((defined? o.parent)    ? o.parent      : nil)   #[Node parent] +      lv      = h[:lv]          || ((defined? o.lv)        ? o.lv          : nil)   #Alpha-numeric, document structure as used in markup, A-D then 1-6 +      ln      = h[:ln]          || ((defined? o.ln)        ? o.ln          : nil)   #Integer, document structure level, for convenience in processing 1-9 +      lc      = h[:lc]          || ((defined? o.lc)        ? o.lc          : nil)   #Integer, document structure collapsed level, convenience (collapse sisu's dual level document structure for markup with simple linear structure) +      use_    = if lv \ +        and lv == '1' +          h[:use_]              || ((defined? o.use_)      ? o.use_        : :ok) +        elsif not lv.empty? \ +        and lv =~ /[A-D2-3]/ +          :ok +        else +           h[:use_]             || ((defined? o.use_)      ? o.use_        : :ok) +        end +      ocn_    = if h[:ocn_].nil? +                                   ((defined? o.ocn_)      ? o.ocn_        : true)  #Bool? no ocn, non-substantive content, do not include in toc #consider +        else                       h[:ocn_] +        end +      autonum_ = if h[:autonum_].nil? +                                   ((defined? o.autonum_)  ? o.autonum_    : true)  #Bool? auto-numbering if requested default on, false suppresses +        else                       h[:autonum_] +        end +      note_   = h[:note_]       || ((defined? o.note_)     ? o.note_       : false) #Bool, endnotes/footnotes? (processing optimization) +      digest  = h[:digest]      || ((defined? o.digest)    ? o.digest      : nil)   #hash digests, sha512, sha256 or md5 +      tmp     = h[:tmp]         || ((defined? o.tmp)       ? o.tmp         : nil)   #available for processing, empty after use +      @of,@is,@lv,@ln,@lc,@name,@tags,@obj,@idx,@ocn,@odv,@osp,@node,@parent,@use_,@ocn_,@note_,@autonum_,@digest,@tmp= +      of, is, lv, ln, lc, name, tags, obj, idx, ocn, odv, osp, node, parent, use_, ocn_, note_, autonum_, digest, tmp +      self +    end +    def heading_insert(h,o=nil) +      heading(h,o=nil) +      @is     = :heading_insert                                                     #String, classification - specific type +      self +    end +  end +  class ObjectPara +    attr_accessor :obj,:is,:tags,:of,:name,:idx,:quote_,:bullet_,:indent,:hang,:ocn,:odv,:osp,:parent,:note_,:image_,:ocn_,:digest,:tmp +    def initialize +      @of=:para +      @is=@obj=@name=@idx=@quote_=@bullet_=@indent=@hang=@size=@ocn=@odv=@osp=@parent=@note_=@image_=@ocn_=@digest=@tmp=nil +      @tags=[] +    end +    def paragraph(h,o=nil) +      of      = @of                                                                 #Symbol, classification - group +      is      = :para                                                               #Symbol, classification - specific type +      name    = h[:name]        || ((defined? o.name)      ? o.name        : nil)   #String, named object? +      tags    = h[:tags]        || ((defined? o.tags)      ? o.tags        : [])    #Array, associated object tags, names if any +      obj     = h[:obj]         || ((defined? o.obj)       ? o.obj         : nil)   #String, text content +      idx     = h[:idx]         || ((defined? o.idx)       ? o.idx         : nil)   #String, book index provided? +      ocn     = h[:ocn]         || ((defined? o.ocn)       ? o.ocn         : nil)   #Integer, sequential on substantive-content objects +      odv     = h[:odv]         || ((defined? o.odv)       ? o.odv         : nil) +      osp     = h[:osp]         || ((defined? o.osp)       ? o.osp         : nil) +      parent  = h[:parent]      || ((defined? o.parent)    ? o.parent      : nil)   #[Node parent] +      indent  = h[:indent].to_s || ((defined? o.indent)    ? o.indent.to_s : nil)   #Integer, indent level +      hang    = h[:hang].to_s   || ((defined? o.hang)      ? o.hang.to_s   : nil)   #Integer, hanging indent level +      bullet_ = h[:bullet_]     || ((defined? o.bullet_)   ? o.bullet_     : false) #Bool, bulleted? +      quote_  = h[:quote_]      || ((defined? o.quote_)    ? o.quote_      : false) #Bool, quote (blockquote)? +      note_   = h[:note_]       || ((defined? o.note_)     ? o.note_       : false) #Bool, endnotes/footnotes? (processing optimization) +      image_  = h[:image_]      || ((defined? o.image_)    ? o.image_      : false) #Bool, images? (processing optimization) +      ocn_    = if h[:ocn_].nil? +                                   ((defined? o.ocn_)      ? o.ocn_        : true)  #Bool? no ocn, non-substantive content, do not include in toc #consider +      else         h[:ocn_] +      end +      digest  = h[:digest]      || ((defined? o.digest)    ? o.digest      : nil)   #hash digests, sha512, sha256 or md5 +      tmp     = h[:tmp]         || ((defined? o.tmp)       ? o.tmp         : nil)   #available for processing, empty after use +      @of,@is,@name,@tags,@obj,@indent,@hang,@bullet_,@quote_,@idx,@ocn,@odv,@osp,@parent,@image_,@note_,@ocn_,@digest,@tmp= +      of, is, name, tags, obj, indent, hang, bullet_, quote_, idx, ocn, odv, osp, parent, image_, note_, ocn_, digest, tmp +      self +    end +    def docinfo(h,o=nil) +      of      = @of                                                                 #String, classification - group +      is      = :docinfo                                                            #String, classification - specific type +      name    = h[:name]        || ((defined? o.name)      ? o.name        : nil)   #String, named object? +      tags    = h[:tags]        || ((defined? o.tags)      ? o.tags        : nil)   #Array, associated object tags, names if any +      obj     = h[:obj]         || ((defined? o.obj)       ? o.obj         : nil)   #String, text content +      idx     = nil                                                                 #String, book index provided? +      ocn     = nil                                                                 #Integer, sequential on substantive-content objects +      odv     = h[:odv]         || ((defined? o.odv)       ? o.odv         : nil) +      osp     = h[:osp]         || ((defined? o.osp)       ? o.osp         : nil) +      parent  = h[:parent]      || ((defined? o.parent)    ? o.parent      : nil)   #[Node parent] +      indent  = nil                                                                 #Integer, indent level +      hang    = nil                                                                 #Integer, indent level +      bullet_ = false                                                               #Bool, bulleted? +      note_   = false                                                               #Bool, endnotes/footnotes? (processing optimization) +      image_  = h[:image_]      || ((defined? o.image_)    ? o.image_      : false) #Bool, images? (processing optimization) +      ocn_    = if h[:ocn_].nil? +                                   ((defined? o.ocn_)      ? o.ocn_        : true)  #Bool? no ocn, non-substantive content, do not include in toc #consider +      else                         h[:ocn_] +      end +      digest  = h[:digest]      || ((defined? o.digest)    ? o.digest      : nil)   #hash digests, sha512, sha256 or md5 +      tmp     = h[:tmp]         || ((defined? o.tmp)       ? o.tmp         : nil)   #available for processing, empty after use +      @of,@is,@name,@tags,@obj,@indent,@hang,@bullet_,@idx,@ocn,@odv,@osp,@parent,@image_,@note_,@ocn_,@digest,@tmp= +      of, is, name, tags, obj, indent, hang, bullet_, idx, ocn, odv, osp, parent, image_, note_, ocn_, digest, tmp +      self +    end +  end +  class ObjectBlockTxt +    attr_accessor :obj,:is,:of,:tags,:lngsyn,:idx,:ocn,:odv,:osp,:parent,:note_,:number_,:ocn_,:digest,:tmp +    def initialize +      @of=:block +      @is=@obj=@lngsyn=@idx=@ocn=@odv=@osp=@parent=@note_=@number_=@ocn_=@digest=@tmp=nil +      @tags=[] +    end +    def code(h,o=nil) +      of       = @of                                                                #Symbol, classification - group #alt 'code' +      is       = :code                                                              #Symbol, classification - specific type +      tags     = h[:tags]       || ((defined? o.tags)      ? o.tags        : [])    #Array, associated object tags, names if any +      obj      = h[:obj]        || ((defined? o.obj)       ? o.obj         : nil)   #String, text content +      lngsyn   = h[:lngsyn]     || ((defined? o.lngsyn)    ? o.lngsyn      : :txt)  #symbol, code lngsyn +      idx      = h[:idx]        || ((defined? o.idx)       ? o.idx         : nil)   #String, book index provided? +      ocn      = h[:ocn]        || ((defined? o.ocn)       ? o.ocn         : nil)   #Integer, sequential on substantive-content objects +      odv      = h[:odv]        || ((defined? o.odv)       ? o.odv         : nil) +      osp      = h[:osp]        || ((defined? o.osp)       ? o.osp         : nil) +      parent   = h[:parent]     || ((defined? o.parent)    ? o.parent      : nil)   #[Node parent] +      number_  = h[:number_]    || ((defined? o.number_)   ? o.number_     : false) #Bool, numbered or not? +      note_    = h[:note_]      || ((defined? o.note_)     ? o.note_       : false) #Bool, endnotes/footnotes? (processing optimization) +      ocn_     = if h[:ocn_].nil? +                                   ((defined? o.ocn_)      ? o.ocn_        : true)  #Bool? no ocn, non-substantive content, do not include in toc #consider +      else                         h[:ocn_] +      end +      num      = h[:num]        || ((defined? o.num)       ? o.num         : nil) +      digest   = h[:digest]     || ((defined? o.digest)    ? o.digest      : nil)   #hash digests, sha512, sha256 or md5 +      tmp      = h[:tmp]        || ((defined? o.tmp)       ? o.tmp         : nil)   #available for processing, empty after use +      @of,@is,@tags,@obj,@lngsyn,@idx,@ocn,@odv,@osp,@parent,@number_,@note_,@ocn_,@num,@digest,@tmp= +      of, is, tags, obj, lngsyn, idx, ocn, odv, osp, parent, number_, note_, ocn_, num, digest, tmp +      self +    end +    def box(h,o=nil) +      of       = @of                                                                #Symbol, classification - group +      is       = :box                                                               #Symbol, classification - specific type +      tags     = h[:tags]       || ((defined? o.tags)      ? o.tags        : [])    #Array, associated object tags, names if any +      obj      = h[:obj]        || ((defined? o.obj)       ? o.obj         : nil)   #String, text content +      idx      = h[:idx]        || ((defined? o.idx)       ? o.idx         : nil)   #String, book index provided? +      ocn      = h[:ocn]        || ((defined? o.ocn)       ? o.ocn         : nil)   #Integer, sequential on substantive-content objects +      odv      = h[:odv]        || ((defined? o.odv)       ? o.odv         : nil) +      osp      = h[:osp]        || ((defined? o.osp)       ? o.osp         : nil) +      parent   = h[:parent]     || ((defined? o.parent)    ? o.parent      : nil)   #[Node parent] +      note_    = h[:note_]      || ((defined? o.note_)     ? o.note_       : false) #Bool, endnotes/footnotes? (processing optimization) +      ocn_     = if h[:ocn_].nil? +                                   ((defined? o.ocn_)      ? o.ocn_        : true)  #Bool? no ocn, non-substantive content, do not include in toc #consider +      else                         h[:ocn_] +      end +      num      = h[:num]        || ((defined? o.num)       ? o.num         : nil) +      digest   = h[:digest]     || ((defined? o.digest)    ? o.digest      : nil)   #hash digests, sha512, sha256 or md5 +      tmp      = h[:tmp]        || ((defined? o.tmp)       ? o.tmp         : nil)   #available for processing, empty after use +      @of,@is,@tags,@obj,@idx,@ocn,@odv,@osp,@parent,@note_,@ocn_,@num,@digest,@tmp= +      of, is, tags, obj, idx, ocn, odv, osp, parent, note_, ocn_, num, digest, tmp +      self +    end +    def block(h,o=nil) +      of       = @of                                                                #Symbol, classification - group +      is       = :block                                                             #Symbol, classification - specific type +      tags     = h[:tags]       || ((defined? o.tags)      ? o.tags        : [])    #Array, associated object tags, names if any +      obj      = h[:obj]        || ((defined? o.obj)       ? o.obj         : nil)   #String, text content +      idx      = h[:idx]        || ((defined? o.idx)       ? o.idx         : nil)   #String, book index provided? +      ocn      = h[:ocn]        || ((defined? o.ocn)       ? o.ocn         : nil)   #Integer, sequential on substantive-content objects +      odv      = h[:odv]        || ((defined? o.odv)       ? o.odv         : nil) +      osp      = h[:osp]        || ((defined? o.osp)       ? o.osp         : nil) +      parent   = h[:parent]     || ((defined? o.parent)    ? o.parent      : nil)   #[Node parent] +      note_    = h[:note_]      || ((defined? o.note_)     ? o.note_       : false) #Bool, endnotes/footnotes? (processing optimization) +      ocn_     = if h[:ocn_].nil? +                                   ((defined? o.ocn_)      ? o.ocn_        : true)  #Bool? no ocn, non-substantive content, do not include in toc #consider +      else                         h[:ocn_] +      end +      num      = h[:num]        || ((defined? o.num)       ? o.num         : nil) +      digest   = h[:digest]     || ((defined? o.digest)    ? o.digest      : nil)   #hash digests, sha512, sha256 or md5 +      tmp      = h[:tmp]        || ((defined? o.tmp)       ? o.tmp         : nil)   #available for processing, empty after use +      @of,@is,@tags,@obj,@idx,@ocn,@odv,@osp,@parent,@note_,@ocn_,@num,@digest,@tmp= +      of, is, tags, obj, idx, ocn, odv, osp, parent, note_, ocn_, num, digest, tmp +      self +    end +    def group(h,o=nil) +      of       = @of                                                                #Symbol, classification - group +      is       = :group                                                             #Symbol, classification - specific type +      tags     = h[:tags]       || ((defined? o.tags)      ? o.tags        : [])    #Array, associated object tags, names if any +      obj      = h[:obj]        || ((defined? o.obj)       ? o.obj         : nil)   #String, text content +      idx      = h[:idx]        || ((defined? o.idx)       ? o.idx         : nil)   #String, book index provided? +      ocn      = h[:ocn]        || ((defined? o.ocn)       ? o.ocn         : nil)   #Integer, sequential on substantive-content objects +      odv      = h[:odv]        || ((defined? o.odv)       ? o.odv         : nil) +      osp      = h[:osp]        || ((defined? o.osp)       ? o.osp         : nil) +      parent   = h[:parent]     || ((defined? o.parent)    ? o.parent      : nil)   #[Node parent] +      note_    = h[:note_]      || ((defined? o.note_)     ? o.note_       : false) #Bool, endnotes/footnotes? (processing optimization) +      ocn_     = if h[:ocn_].nil? +                                   ((defined? o.ocn_)      ? o.ocn_        : true)  #Bool? no ocn, non-substantive content, do not include in toc #consider +      else          h[:ocn_] +      end +      num      = h[:num]        || ((defined? o.num)       ? o.num         : nil) +      digest   = h[:digest]     || ((defined? o.digest)    ? o.digest      : nil)   #hash digests, sha512, sha256 or md5 +      tmp      = h[:tmp]        || ((defined? o.tmp)       ? o.tmp         : nil)   #available for processing, empty after use +      @of,@is,@tags,@obj,@idx,@ocn,@odv,@osp,@parent,@note_,@ocn_,@num,@digest,@tmp= +      of, is, tags, obj, idx, ocn, odv, osp, parent, note_, ocn_, num, digest, tmp +      self +    end +    def alt(h,o=nil)                                                                #see block +      of       = @of                                                                #Symbol, classification - group +      is       = :alt                                                               #Symbol, classification - specific type +      tags     = h[:tags]       || ((defined? o.tags)      ? o.tags        : [])    #Array, associated object tags, names if any +      obj      = h[:obj]        || ((defined? o.obj)       ? o.obj         : nil)   #String, text content +      idx      = h[:idx]        || ((defined? o.idx)       ? o.idx         : nil)   #String, book index provided? +      ocn      = h[:ocn]        || ((defined? o.ocn)       ? o.ocn         : nil)   #Integer, sequential on substantive-content objects +      odv      = h[:odv]        || ((defined? o.odv)       ? o.odv         : nil) +      osp      = h[:osp]        || ((defined? o.osp)       ? o.osp         : nil) +      parent   = h[:parent]     || ((defined? o.parent)    ? o.parent      : nil)   #[Node parent] +      note_    = h[:note_]      || ((defined? o.note_)     ? o.note_       : false) #Bool, endnotes/footnotes? (processing optimization) +      ocn_     = if h[:ocn_].nil? +                                   ((defined? o.ocn_)      ? o.ocn_        : true)  #Bool? no ocn, non-substantive content, do not include in toc #consider +      else                         h[:ocn_] +      end +      num      = h[:num]        || ((defined? o.num)       ? o.num         : nil) +      digest   = h[:digest]     || ((defined? o.digest)    ? o.digest      : nil)   #hash digests, sha512, sha256 or md5 +      tmp      = h[:tmp]        || ((defined? o.tmp)       ? o.tmp         : nil)   #available for processing, empty after use +      @of,@is,@tags,@obj,@idx,@ocn,@odv,@osp,@parent,@note_,@ocn_,@num,@digest,@tmp= +      of, is, tags, obj, idx, ocn, odv, osp, parent, note_, ocn_, num, digest, tmp +      self +    end +    def verse(h,o=nil)                                                              #part of poem decide how you deal with this +      of       = @of                                                                #Symbol, classification - group +      is       = :verse                                                             #Symbol, classification - specific type +      tags     = h[:tags]       || ((defined? o.tags)      ? o.tags        : [])    #Array, associated object tags, names if any +      obj      = h[:obj]        || ((defined? o.obj)       ? o.obj         : nil)   #String, text content +      idx      = h[:idx]        || ((defined? o.idx)       ? o.idx         : nil)   #String, book index provided? +      ocn      = h[:ocn]        || ((defined? o.ocn)       ? o.ocn         : nil)   #Integer, sequential on substantive-content objects +      odv      = h[:odv]        || ((defined? o.odv)       ? o.odv         : nil) +      osp      = h[:osp]        || ((defined? o.osp)       ? o.osp         : nil) +      parent   = h[:parent]     || ((defined? o.parent)    ? o.parent      : nil)   #[Node parent] +      ocn_     = if h[:ocn_].nil? +                                   ((defined? o.ocn_)      ? o.ocn_        : true)  #Bool? no ocn, non-substantive content, do not include in toc #consider +      else                         h[:ocn_] +      end +      num      = h[:num]        || ((defined? o.num)       ? o.num         : nil) +      digest   = h[:digest]     || ((defined? o.digest)    ? o.digest      : nil)   #hash digests, sha512, sha256 or md5 +      tmp      = h[:tmp]        || ((defined? o.tmp)       ? o.tmp         : nil)   #available for processing, empty after use +      @of,@is,@tags,@obj,@idx,@ocn,@odv,@osp,@parent,@note_,@ocn_,@num,@digest,@tmp= +      of, is, tags, obj, idx, ocn, odv, osp, parent, note_, ocn_, num, digest, tmp +      @h=nil +      self +    end +  end +  class ObjectTable +    attr_accessor :obj,:is,:of,:lv,:tags,:name,:idx,:indent,:hang,:size,:ocn,:num,:head_,:cols,:widths,:odv,:osp,:parent,:note_,:ocn_,:digest,:tmp +    def initialize +      @of=:block +      @is=@obj=@lv=@name=@idx=@indent=@hang=@size=@ocn,@num,@head_,@cols,@widths=@odv=@osp=@parent=@note_=@ocn_=@num=@digest=@tmp=nil +      @tags=[] +    end +    def table(h,o=nil) +      of      = @of                                                                 #Symbol, classification - group +      is      = :table                                                              #Symbol, classification - specific type +      tags    = h[:tags]        || ((defined? o.tags)      ? o.tags        : [])    #Array, associated object tags, names if any +      cols    = h[:cols]        || ((defined? o.cols)      ? o.cols        : nil) +      widths  = h[:widths]      || ((defined? o.widths)    ? o.widths      : nil) +      obj     = h[:obj]         || ((defined? o.obj)       ? o.obj         : nil)   #String, text content +      idx     = h[:idx]         || ((defined? o.idx)       ? o.idx         : nil)   #String, book index provided? +      ocn     = h[:ocn]         || ((defined? o.ocn)       ? o.ocn         : nil)   #Integer, sequential on substantive-content objects +      odv     = h[:odv]         || ((defined? o.odv)       ? o.odv         : nil) +      osp     = h[:osp]         || ((defined? o.osp)       ? o.osp         : nil) +      parent  = h[:parent]      || ((defined? o.parent)    ? o.parent      : nil)   #[Node parent] +      head_   = h[:head_]       || ((defined? o.head_)     ? o.head_       : false) +      note_   = h[:note_]       || ((defined? o.note_)     ? o.note_       : false) #Bool, endnotes/footnotes? (processing optimization) +      ocn_    = if h[:ocn_].nil? +                                   ((defined? o.ocn_)      ? o.ocn_        : true)  #Bool? no ocn, non-substantive content, do not include in toc #consider +      else                         h[:ocn_] +      end +      num     = h[:num]         || ((defined? o.num)       ? o.num         : nil) +      digest  = h[:digest]      || ((defined? o.digest)    ? o.digest      : nil)   #hash digests, sha512, sha256 or md5 +      tmp     = h[:tmp]         || ((defined? o.tmp)       ? o.tmp         : nil)   #available for processing, empty after use +      @of,@is,@tags,@cols,@widths,@obj,@idx,@ocn,@odv,@osp,@parent,@head_,@note_,@ocn_,@num,@digest,@tmp= +      of, is, tags, cols, widths, obj, idx, ocn, odv, osp, parent, head_, note_, ocn_, num, digest, tmp +      self +    end +  end +  class ObjectImage +    attr_accessor :obj,:is,:of,:lv,:idx,:size,:ocn,:parent,:note_,:ocn_,:digest,:tmp +    def initialize +      @of=:image +      @is=@obj=@lv=@idx=@size=@ocn=@parent=@note_=@ocn_=@tmp=@digest=nil +      @tags=[] +    end +    def image(h,o=nil)                                                         #not yet used, and what of a paragraph containing several images, consider +      of=     @of                                                              #Symbol, classification - group +      is=     :image                                                           #Symbol, classification - specific type +      tags=   h[:tags]    || ((defined? o.tags)      ? o.tags    : [])         #Array, associated object tags, names if any +      obj=    h[:obj]     || ((defined? o.obj)       ? o.obj     : nil)        #String, text content +      size=   h[:size]    || ((defined? o.size)      ? o.size    : nil) +      idx=    h[:idx]     || ((defined? o.idx)       ? o.idx     : nil)        #String, book index provided? +      ocn=    h[:ocn]     || ((defined? o.ocn)       ? o.ocn     : nil)        #Integer, sequential on substantive-content objects +      odv=    h[:odv]     || ((defined? o.odv)       ? o.odv     : nil) +      osp=    h[:osp]     || ((defined? o.osp)       ? o.osp     : nil) +      parent= h[:parent]  || ((defined? o.parent)    ? o.parent  : nil)        #[Node parent] +      note_=  h[:note_]   || ((defined? o.note_)     ? o.note_   : false)      #Bool, endnotes/footnotes? (processing optimization) +      ocn_=if h[:ocn_].nil? +                             ((defined? o.ocn_)  ? o.ocn_    : true)           #Bool? no ocn, non-substantive content, do not include in toc #consider +      else                   h[:ocn_] +      end +      digest= h[:digest]  || ((defined? o.digest)    ? o.digest  : nil)        #hash digests, sha512, sha256 or md5 +      tmp=    h[:tmp]     || ((defined? o.tmp)       ? o.tmp     : nil)        #available for processing, empty after use +      @of,@is,@tags,@obj,@size,@idx,@ocn,@odv,@osp,@parent,@note_,@ocn_,@digest,@tmp=of,is,tags,obj,size,idx,ocn,odv,osp,parent,note_,ocn_,digest,tmp +      self +    end +  end +  class ObjectStructure +    attr_accessor :obj,:tag,:node,:lv,:ln,:lc,:status,:is,:of,:tmp +    def initialize +      @of=:structure +      @is=@obj=@node=@lv=@ln=@lc=@status=@tmp=nil +    end +    def xml_dom(h,o=nil) +      of=     @of                                                              #Symbol, classification - group +      is=     :xml_dom                                                         #Symbol, classification - specific type +      obj=    h[:obj]     || ((defined? o.obj)       ? o.obj     : '')         #String, text content +      lv=     h[:lv]      || ((defined? o.lv)        ? o.lv      : nil)        #Alpha-numeric, document structure as used in markup, A-D then 1-6 +      ln=     h[:ln]      || ((defined? o.ln)        ? o.ln      : nil)        #Integer, document structure level, for convenience in processing 1-9 +      lc=     h[:lc]      || ((defined? o.lc)        ? o.lc      : nil)        #Integer, document structure collapsed level, convenience (collapse sisu's dual level document structure for markup with simple linear structure) +      node=   h[:node]    || ((defined? o.node)      ? o.node    : nil)        #[Node relationship doc structure info] +      status= h[:status]  || ((defined? o.status)    ? o.status  : nil)        #tag status Symbol :open or :close +      tmp=    h[:tmp]     || ((defined? o.tmp)       ? o.tmp     : nil)        #available for processing, empty after use +      @of,@is,@obj,@status,@node,@lv,@ln,@lc,@tmp=of,is,obj,status,node,lv,ln,lc,tmp +      self +    end +  end +  class ObjectFlag +    attr_accessor :obj,:is,:of,:flag,:act,:selections,:tmp +    def initialize +      @of=:flag +      @is=@obj=@flag=@act=@selections=@tmp=nil +    end +    def flag(h,o=nil) +      of=     @of                                                              #Symbol, classification - group +      is=     :flag                                                            #Symbol, classification - specific type +      obj=    nil                                                              #String, text content +      flag=   h[:flag]     || ((defined? o.flag)      ? o.flag    : nil)       #String, text content +      act=    h[:act]      || ((defined? o.act)       ? o.act     : nil)       #String, text content +      selections=    h[:selections]      || ((defined? o.selections) ? o.selections : nil)   #String, text content +      tmp=    h[:flag]     || ((defined? o.tmp)       ? o.tmp     : nil)       #available for processing, empty after use +      @of, @is,@obj,@flag,@act,@selections,@tmp= +        of,is, obj, flag, act, selections, tmp +      self +    end +    def flag_ocn(h,o=nil) +      of=     @of                                                              #Symbol, classification - group +      is=     :flag_ocn                                                        #Symbol, classification - specific type +      obj=    nil                                                              #String, text content +      flag=   h[:flag]     || ((defined? o.flag)      ? o.flag    : nil)       #String, text content +      act=    h[:act]      || ((defined? o.act)       ? o.act     : nil)       #String, text content +      selections= h[:selections] || ((defined? o.selections) ? o.selections : nil)   #String, text content +      tmp=    h[:flag]     || ((defined? o.tmp)       ? o.tmp     : nil)       #available for processing, empty after use +      @of, @is,@obj,@flag,@act,@selections,@tmp= +        of,is, obj, flag, act, selections,tmp +      self +    end +    def flag_lng(h,o=nil) +      of=     @of                                                              #Symbol, classification - group +      is=     :flag_lng +      obj=    nil                                                              #String, text content +      flag=   h[:flag]     || ((defined? o.flag)      ? o.flag    : nil)       #Symbol, :lng_on or :lng_off +      act=    h[:act]      || ((defined? o.act)       ? o.act     : nil)       #Symbol, language set to :en etc. +      selections= h[:selections] || ((defined? o.selections) ? o.selections : nil)   #String, text content +      tmp=    h[:act]     || ((defined? o.tmp)       ? o.tmp     : nil)       #available for processing, empty after use +      @of, @is,@obj,@flag,@act,@selections,@tmp= +        of,is, obj, flag, act, selections,tmp +      self +    end +  end +  class ObjectLayout +    attr_accessor :obj,:sym,:attr,:is,:is_for,:of,:from,:tmp,:num +    def initialize +      @of=:layout +      @is=@is_for=@obj=@from=@tmp=@num=nil +    end +    def break(h,f=nil)                                                         #decide how to deal with +      of=     @of                                                              #Symbol, classification - group +      is=     :break                                                           #Symbol, classification - specific type +      obj=    h[:obj]                                                          #String, text content +      from=   f +      tmp=    h[:tmp]                                                          #available for processing, empty after use +      @of,@is,@obj,@from,@tmp=of,is,obj,from,tmp +      self +    end +    def insert(h,o=nil)                                                        #decide how to deal with, could mimic paragraph? +      of=     @of                                                              #Symbol, classification - group +      is=     :insert                                                          #Symbol, classification - specific type +      obj=    h[:obj]     || ((defined? o.obj)       ? o.obj     : nil)        #String, text content +      tmp=    h[:tmp]     || ((defined? o.tmp)       ? o.tmp     : nil)        #available for processing, empty after use +      @of,@is,@obj,@tmp=of,is,obj,tmp +      self +    end +    def open_close(h,o=nil)                                                    #useful for poem & quote +      of=     @of                                                              #Symbol, classification - group +      is=     :open_close_tags                                                 #Symbol, classification - specific type +      is_for= h[:is_for]  || ((defined? o.is_for)    ? o.is_for  : nil)        #String, text content +      obj=    h[:obj]     || ((defined? o.obj)       ? o.obj     : nil)        #String, text content +      sym=    h[:sym]     || ((defined? o.sym)       ? o.sym     : nil)        #Symbol tag_open, tag_close +      attr=   h[:attr]    || ((defined? o.attr)      ? o.attr    : nil)        #String, text content +      tmp=    h[:tmp]     || ((defined? o.tmp)       ? o.tmp     : nil)        #available for processing, empty after use +      num=    h[:num]     || ((defined? o.num)       ? o.num     : nil) +      @of,@is,@is_for,@obj,@sym,@attr,@tmp,@num= +      of, is, is_for, obj, sym, attr, tmp, num +      self +    end +  end +  class ObjectComment +    attr_accessor :obj,:is,:of,:tmp +    def initialize +      @of=:comment +      @is=@obj=@tmp=nil +    end +    def comment(h,o=nil) +      of=     @of                                                              #Symbol, classification - group +      is=     :comment                                                         #Symbol, classification - specific type +      obj=    h[:obj]     || ((defined? o.obj)       ? o.obj     : nil)        #String, text content +      tmp=    h[:tmp]     || ((defined? o.tmp)       ? o.tmp     : nil)        #available for processing, empty after use +      @of,@is,@obj,@tmp=of,is,obj,tmp +      self +    end +  end +end +__END__ +# ~# |-# no paragraph number # -# not included in toc +#+END_SRC + +** ao_doc_str.rb + +#+BEGIN_SRC ruby  :tangle "../lib/sisu/ao_doc_str.rb" +# <<sisu_document_header>> +module SiSU_AO_DocumentStructureExtract +  require_relative 'ao_persist'                     # ao_persist.rb +  class Instantiate < SiSU_Param::Parameters::Instructions +    def initialize +      @@counter=@@column=@@columns=0 +      @@line_mode='' +    end +  end +  class Build +    def initialize(md,data) +      @md,@data=md,data +      SiSU_AO_DocumentStructureExtract::Instantiate.new +      @pb=SiSU_AO_DocumentStructure::ObjectLayout.new.break(Hx[:br_page]) +      @pbn=SiSU_AO_DocumentStructure::ObjectLayout.new.break(Hx[:br_page_new]) +      @pbl=SiSU_AO_DocumentStructure::ObjectLayout.new.break(Hx[:br_page_line]) +      @per=SiSU_AO_Persist::PersistDocStructExt.new +      @make=SiSU_Env::ProcessingSettings.new(@md) +    end +    def ln_get(lv) +      case lv +      when /A/ then 0 +      when /B/ then 1 +      when /C/ then 2 +      when /D/ then 3 +      when /1/ then 4 +      when /2/ then 5 +      when /3/ then 6 +      when /4/ then 7 +      when /5/ then 8 +      when /6/ then 9 +      end +    end +    def image_test(str) +      str=~/\{\s*\S+?\.png.+?\}https?:\/\/\S+/ \ +      ? true +      : false +    end +    def bullet_test(str) +      (str=~/\*/) \ +      ? true +      : false +    end +    def quotes? +      @per.quote==:open \ +      ? true +      : false +    end +    def hang_and_indent_test(str) +      hang_indent=if str=~/^_([1-9])[^_]/ +        [$1,$1] +      elsif str=~/^__([1-9])/ +        [0,$1] +      elsif str=~/^_([0-9])_([0-9])/ +        [$1,$2] +      else +        [0,0] +      end +      hang,indent=hang_indent[0],hang_indent[1] +      [hang,indent] +    end +    def hang_and_indent_def_test(str1,str2) +      hang_indent=if str1=~/^_([1-9])[^_]/ +        [$1,$1] +      elsif str1=~/^__([1-9])/ +        [0,$1] +      elsif str1=~/^_([0-9])_([0-9])/ +        [$1,$2] +      else +        [0,0] +      end +      obj=if str2 =~/^(.+?)\s+\\\\(?:\s+|\n)/ +        str2.gsub(/^(.+?)(\s+\\\\(?:\s+|\n))/, +          "#{Mx[:fa_bold_o]}\\1#{Mx[:fa_bold_c]}\\2") +      else +        str2.gsub(/^(.+?)\n/, +          "#{Mx[:fa_bold_o]}\\1#{Mx[:fa_bold_c]}\n") +      end +      hang,indent=hang_indent[0],hang_indent[1] +      [ +        hang, +        indent, +        obj, +      ] +    end +    def endnote_test?(str) +      (str=~/~\{.+?\}~|~\[.+?\]~/) \ +      ? true +      : false +    end +    def extract_tags(str,nametag=nil) +      tags=[] +      if str.nil? +      else +        if str =~/(?:^|[ ])\*~([a-z0-9._-]+)(?=[ #{Mx[:br_nl]}]|$)/ +          str=str.gsub(/(^|[ ])\*~([a-z0-9._-]+)(?=[ #{Mx[:br_nl]}]|$)/i, +              "\\1#{Mx[:tag_o]}\\2#{Mx[:tag_c]}"). +            gsub(/ [ ]+/i,' ') +          tags=str.scan(/#{Mx[:tag_o]}(\S+?)#{Mx[:tag_c]}/).flatten.uniq +          str=str.gsub(/[ ]?#{Mx[:tag_o]}\S+?#{Mx[:tag_c]}[ ]?/,' ') #may be issues with spaces would leave one, but "code" blocks? +        end +        tags=nametag ? (tags << nametag) : tags +        tags.each do |t| +          t.gsub!(/[^a-z0-9._-]/,'') +        end +      end +      [ +        str, +        tags, +      ] +    end +    def rgx_idx_ocn_seg +      @rgx_idx_ocn_seg=/(.+?)\s*[+](\d+)/ +    end +    def construct_idx_array_and_hash(idxraw) +      idx_array_raw=idxraw.scan(/[^;]+/) +      idx_hash,idx_array,idx_lst={},[],[] +      idx_array_raw.each do |idx| +        idx=idx.strip +        idx_lst=case idx +        when /\S+?\s*:/ +          idx_couplet_tmp=[] +          idx_couplet=idx.scan(/\s*[^:]+\s*/) +          if idx_couplet[1] =~/[|]/ +            idx_couplet_tmp << +              idx_couplet[0] << +              idx_couplet[1].scan(/\s*[^|]+\s*/) +          else +            idx_couplet_tmp << +              idx_couplet[0] << +              [idx_couplet[1]] +          end +          idx_couplet=idx_couplet_tmp +        else [idx] +        end +        term_nodes=[] +        idx_lst.each do |term_node| +          case term_node +          when String +            term_node= +              term_node[0].chr.capitalize + +              term_node[1,term_node.length] +            term_node=(term_node =~/.+?[+]\d+/) \ +            ? term_node +            : (term_node + '+0') +            term_nodes << term_node +            use,plus=rgx_idx_ocn_seg.match(term_node)[1,2] +            @use=use.strip +            unless idx_hash[@use] \ +            and defined? idx_hash[@use] +              idx_hash[@use]= +                { sub: [], plus: plus } +            end +          when Array +            subterm_nodes=[] +            term_node.each do |subterm_node| +              subterm_node=(subterm_node =~/.+?[+]\d+/) \ +              ? subterm_node +              : (subterm_node + '+0') +              subterm_nodes << subterm_node +              sub,sub_plus=rgx_idx_ocn_seg.match(subterm_node)[1,2] +              unless idx_hash[@use] \ +              and defined? idx_hash[@use] +                idx_hash[@use]= +                  { sub: [], plus: 0 } +              end +              idx_hash[@use][:sub] << +                { sub.strip => { plus: sub_plus } } +            end +            term_nodes << subterm_nodes +          end +        end +        idx_array << term_nodes +      end +      { +        hash: idx_hash, +        array: idx_array, +      } +    end +    def extract_structure_loop(data,tuned_file) +      data.each do |t_o| +        if t_o =~/^--([+~-])[#]$/ +          h=case $1 +          when /[+]/ +            @per.ocn=:on +            { +              flag: :ocn_on, +            } +          when /[~]/ +            @per.ocn=:ocn_off_headings_keep +            { +              flag: :ocn_off, +              mod: :headings_keep, +            } +          when /[-]/ #of particular relevance with level 1~ which is required to precede substantive text & used e.g. in html segmented text +            @per.ocn=:ocn_off_headings_dummy_lev1 +            { +              flag: :ocn_off, +              mod: :headings_exclude, +            } +          else +            @per.ocn=:on +            { +              flag: :ocn_on, +            } +          end +          t_o=SiSU_AO_DocumentStructure::ObjectFlag.new.flag_ocn(h) +          next +        end +        if t_o =~/^:[~](#{SiSU_is.language_list_regex?}|-)$/  # work with for identifying language of objects +          lng=$1 +          h=case lng +          when /(?:#{SiSU_is.language_list_regex?})/ +            @per.lng=:on +            @per.lng_is=lng.to_sym +            { +              flag: :lng_on, +              act:  lng.to_sym, +            } +          else # ^:~- +            if @per.lng==:on +              @per.lng=:off +              @per.lng_is=:doc_default +              { +                flag: :lng_off, +                act:  :doc_default, +              } +            end +          end +          t_o=SiSU_AO_DocumentStructure::ObjectFlag.new.flag_lng(h) +          next +        end +        t_o=t_o.gsub(/(?:\n\s*\n)+/m,"\n") if @per.code==:off +        unless t_o =~/^(?:@\S+?:|%+)\s/                  # extract book index for paragraph if any +          idx=if t_o=~/^=\{\s*(.+)\s*\}\s*$\Z/m +            m=$1 +            m=m.split(/[ ]*\n/).join(' '). +              gsub(/\s+([|:;])\s+/,'\1'). +              gsub(/\s+([+]\d+)\s+/,'\1') +            t_o=t_o.gsub(/\n=\{.+?\}\s*$/m,'') +            idx_array_and_hash=construct_idx_array_and_hash(m) +            idx_array_and_hash[:hash] +          else nil +          end +        end +        if (t_o.is_a?(String) \ +          && t_o !~/^(?:code(?:\.[a-z][0-9a-z_]+)?(?:\(.+?\))?|box(?:\.[a-z_]+)?|poem|alt|group|block)\{|^\}(?:code|poem|alt|group|block)|^(?:table\(.+?\)\{|\{table\()|^(?:table\{|\{table)[ ~]/ \ +           && t_o !~/^```[ ]+(?:code(?:\.[a-z][0-9a-z_]+)?(?:\(.+?\))?|box(?:\.[a-z_]+)?|poem|alt|group|block|table)|^```(?:\s+[~-][#]|\s+\~\{.+?\}\~)?\s*$|^`:quote_(?:open|close)`/ \ +          and @per.code==:off \ +          and @per.poem==:off \ +          and @per.group==:off \ +          and @per.block==:off \ +          and @per.alt==:off \ +          and @per.box==:off \ +          and @per.table==:off +        ) +          t_o=case t_o +          when /^#{Mx[:meta_o]}\S+?#{Mx[:meta_c]}/                                 #metadata, header +            if t_o=~/^#{Mx[:meta_o]}(\S+?)#{Mx[:meta_c]}\s*(.+)/m +              tag,obj=$1,$2 +              @metadata[tag]=obj +            end +            t_o=nil +          when /^%+\s/                                     #comment +            t_o=if t_o=~/^%+\s+(.+)/ +              h={ obj: $1 } +              SiSU_AO_DocumentStructure::ObjectComment.new.comment(h) +            else nil +            end +          when /^:?([A-D1-6])\~/                           #heading / lv +            lv=$1 +            ln=ln_get(lv) +            t_o=if t_o=~/^:?[A-D1-6]\~\s+(.+)/m +              obj=$1 +              note=endnote_test?(obj) +              obj,tags=extract_tags(obj) +              if @per.ocn==:ocn_off_headings_dummy_lev1 \ +              or @per.ocn==:ocn_off_headings_keep +                unless obj =~ /[~-][#]\s*$/ +                  if @per.ocn==:ocn_off_headings_dummy_lev1 \ +                  and t_o =~/^1\~\S*\s+/m +                    obj << ' -#' +                  elsif @per.ocn==:ocn_off_headings_dummy_lev1 \ +                  or @per.ocn==:ocn_off_headings_keep +                    obj << ' ~#' +                  end +                end +              end +              h={ +                lv: lv, +                ln: ln, +                obj: obj, +                idx: idx, +                tags: tags, +              } +              SiSU_AO_DocumentStructure::ObjectHeading.new.heading(h) +            elsif t_o=~/^:?[A-D1-6]\~(\S+?)-\s+(.+)/m +              name,obj=$1,$2 +              note=endnote_test?(obj) +              obj,tags=extract_tags(obj) +              if @per.ocn==:ocn_off_headings_dummy_lev1 \ +              or @per.ocn==:ocn_off_headings_keep +                unless obj =~ /[~-][#]\s*$/ +                  if @per.ocn==:ocn_off_headings_dummy_lev1 \ +                  and t_o =~/^1\~\S*\s+/m +                    obj << ' -#' +                  elsif @per.ocn==:ocn_off_headings_dummy_lev1 \ +                  or @per.ocn==:ocn_off_headings_keep +                    obj << ' ~#' +                  end +                end +              end +              h={ +                lv: lv, +                name: name, +                obj: obj, +                idx: idx, +                autonum_: false, +                tags: tags, +              } +              SiSU_AO_DocumentStructure::ObjectHeading.new.heading(h) +            elsif t_o=~/^:?[A-D1-6]\~(\S+)\s+(.+)/m +              name,obj=$1,$2 +              note=endnote_test?(obj) +              obj,tags=extract_tags(obj,name) +              if @per.ocn==:ocn_off_headings_dummy_lev1 \ +              or @per.ocn==:ocn_off_headings_keep +                unless obj =~ /[~-][#]\s*$/ +                  if @per.ocn==:ocn_off_headings_dummy_lev1 \ +                  and t_o =~/^1\~\S*\s+/m +                    obj << ' -#' +                  elsif @per.ocn==:ocn_off_headings_dummy_lev1 \ +                  or @per.ocn==:ocn_off_headings_keep +                    obj << ' ~#' +                  end +                end +              end +              h={ +                lv: lv, +                name: name, +                obj: obj, +                idx: idx, +                tags: tags, +              } +              SiSU_AO_DocumentStructure::ObjectHeading.new.heading(h) +            else nil +            end +          when /^_(?:[1-9]!?|[1-9]?\*)\s+/                  #indented and/or bullet paragraph +            t_o=if t_o=~/^(_(?:[1-9]?\*|[1-9]!?)\s+)(.+)/m +              tst,obj=$1,$2 +              if t_o=~/^_[1-9]!\s+.+/m +                hang,indent,obj=hang_and_indent_def_test(tst,obj) +              else +                hang,indent=hang_and_indent_test(tst) +              end +              bullet=bullet_test(tst) +              image=image_test(obj) +              note=endnote_test?(obj) +              obj,tags=extract_tags(obj) +              unless obj=~/\A\s*\Z/m +                if @per.ocn==:ocn_off_headings_dummy_lev1 \ +                or @per.ocn==:ocn_off_headings_keep +                  unless obj =~ /[~-][#]\s*$/ +                    obj << ' ~#' +                  end +                end +                h={ +                  bullet_: bullet, +                  hang: hang, +                  indent: indent, +                  obj: obj, +                  idx: idx, +                  note_: note, +                  image_: image, +                  tags: tags, +                  quote: quotes?, +                } +                SiSU_AO_DocumentStructure::ObjectPara.new.paragraph(h) +              end +            else nil +            end +          when /^_[0-9]?_[0-9]!?\s+/                  #hanging indent paragraph +            t_o=if t_o=~/^(_[0-9]?_[0-9]!?\s+)(.+)/m +              tst,obj=$1,$2 +              if t_o=~/^_[0-9]?_[0-9]!\s+.+/m +                hang,indent,obj=hang_and_indent_def_test(tst,obj) +              else +                hang,indent=hang_and_indent_test(tst) +              end +              image=image_test(obj) +              note=endnote_test?(obj) +              obj,tags=extract_tags(obj) +              unless obj=~/\A\s*\Z/m +                if @per.ocn==:ocn_off_headings_dummy_lev1 \ +                or @per.ocn==:ocn_off_headings_keep +                  unless obj =~ /[~-][#]\s*$/ +                    obj << ' ~#' +                  end +                end +                h={ +                  hang: hang, +                  indent: indent, +                  obj: obj, +                  idx: idx, +                  note_: note, +                  image_: image, +                  tags: tags, +                  quote: quotes?, +                } +                SiSU_AO_DocumentStructure::ObjectPara.new.paragraph(h) +              end +            else nil +            end +          when /^<(?:br)?:(?:pa?r|o(?:bj|---)?)>\s*$/      #[br:par] #[br:obj] +            SiSU_AO_DocumentStructure::ObjectLayout.new.break(Hx[:br_obj]) +          when /^(?:-\\\\-|<:pb>)\s*$/                                #[br:pg] +            SiSU_AO_DocumentStructure::ObjectLayout.new.break(Hx[:br_page],:markup) +          when /^(?:=\\\\=|<:pn>)\s*$/                                #[br:pgn] +            SiSU_AO_DocumentStructure::ObjectLayout.new.break(Hx[:br_page_new],:markup) +          when /^-\.\.-\s*$/                                          #[br:pgl] +            SiSU_AO_DocumentStructure::ObjectLayout.new.break(Hx[:br_page_line],:markup) +          else                                             #paragraph +            image=image_test(t_o) +            note=endnote_test?(t_o) +            obj,tags=extract_tags(t_o) +            if @per.ocn==:ocn_off_headings_dummy_lev1 \ +            or @per.ocn==:ocn_off_headings_keep +              unless obj =~ /[~-][#]\s*$/ +                obj << ' ~#' +              end +            end +            unless obj=~/\A\s*\Z/m +              h={ +                bullet_: false, +                indent: 0, +                hang: 0, +                obj: obj, +                idx: idx, +                note_: note, +                image_: image, +                tags: tags, +                quote: quotes?, +              } +              t_o=SiSU_AO_DocumentStructure::ObjectPara.new.paragraph(h) +            end +            t_o=SiSU_AO_DocumentStructureExtract::Structure.new(@md).structure_markup(t_o) #must happen earlier, node info etc. require +          end +        elsif @per.code==:off +          if t_o =~/^(?:code(?:\.[a-z][0-9a-z_]+)?(?:\(.+?\))?\{|```[ ]+code(?:\.[a-z][0-9a-z_]+)?(?:\(.+?\))?)/ +            @per.code=case t_o +            when /^code(?:\.[a-z][0-9a-z_]+)?(?:\(.+?\))?\{/ then :curls +            when /^```[ ]+code/                  then :tics +            else                                 @per.code #error +            end +            @per.lngsyn=if t_o =~/^(?:code\.[a-z][0-9a-z_]+(?:\(.+?\))?\{|```[ ]+code\.[a-z_]+)/ +              case t_o +              when /^code\.([a-z][0-9a-z_]+)(?:\(.+?\))?\{/ +                :"#{$1}" +              when /^```[ ]+code\.([a-z][0-9a-z_]+)/ +                :"#{$1}" +              else :txt +              end +            else :txt +            end +            @@counter=1 +            @codeblock_numbered= +              (t_o =~/^(?:code(?:\.[a-z][0-9a-z_]+)?\(.*number(?:lines)?.*?\)\{|```[ ]+code(?:\.[a-z][0-9a-z_]+)?\(.*number(?:lines)?.*?\)|code(?:\.[a-z][0-9a-z_]+)?\{#|```[ ]+code(?:\.[a-z][0-9a-z_]+)?\s[#])/) \ +              ? true +              : false +            if (t_o =~/^(?:code(?:\.[a-z][0-9a-z_]+)?\{#|```[ ]+code(?:\.[a-z][0-9a-z_]+)?\s[#])/) +              puts "WARNING document using depreciated markup for numbering codeblocks\nuse: code(numberlines){ ... or: ```code(numberlines) ..." +            end +            @num_id[:code_block] +=1 +            h={ +              is_for: :code, +              obj: '', +              sym: :code_block_open, +              num: @num_id[:code_block], +              syntax: @per.lngsyn, +            } +            t_o=SiSU_AO_DocumentStructure::ObjectLayout.new.open_close(h) +          elsif t_o =~/^(?:poem\{|```[ ]+poem)/ +            @per.poem=case t_o +            when /^poem\{/        then :curls +            when /^```[ ]+poem/   then :tics +            else                  @per.poem #error +            end +            @num_id[:poem] +=1 +            h={ +              is_for: :poem, +              obj: '', +              sym: :poem_open, +              num: @num_id[:poem], +            } +            t_o=SiSU_AO_DocumentStructure::ObjectLayout.new.open_close(h) +            tuned_file << t_o +          elsif t_o =~/^(?:box(?:\.[a-z_]+)?\{|```[ ]+box(?:\.[a-z_]+)?)/ +            @per.box=case t_o +            when /^box\{/         then :curls +            when /^```[ ]+box/    then :tics +            else                       @per.box #error +            end +            @num_id[:box] +=1 +            h={ +              is_for: :box, +              obj: '', +              sym: :box_open, +              num: @num_id[:box], +            } +            t_o=SiSU_AO_DocumentStructure::ObjectLayout.new.open_close(h) +            tuned_file << t_o +          elsif t_o =~/^(?:group\{|```[ ]+group)/ +            @per.group=case t_o +            when /^group\{/       then :curls +            when /^```[ ]+group/  then :tics +            else                       @per.group #error +            end +            @num_id[:group] +=1 +            h={ +              is_for: :group, +              obj: '', +              sym: :group_open, +              num: @num_id[:group], +            } +            t_o=SiSU_AO_DocumentStructure::ObjectLayout.new.open_close(h) +            tuned_file << t_o +          elsif t_o =~/^(?:block\{|```[ ]+block)/ +            @per.block=case t_o +            when /^block\{/       then :curls +            when /^```[ ]+block/  then :tics +            else                       @per.block #error +            end +            @num_id[:block] +=1 +            h={ +              is_for: :block, +              obj: '', +              sym: :block_open, +              num: @num_id[:block], +            } +            t_o=SiSU_AO_DocumentStructure::ObjectLayout.new.open_close(h) +            tuned_file << t_o +          elsif t_o =~/^(?:alt\{|```[ ]+alt)/ +            @per.alt=case t_o +            when /^alt\{/         then :curls +            when /^```[ ]+alt/    then :tics +            else                       @per.alt #error +            end +            @num_id[:alt] +=1 +            h={ +              is_for: :alt, +              obj: '', +              sym: :alt_open, +              num: @num_id[:alt], +            } +            t_o=SiSU_AO_DocumentStructure::ObjectLayout.new.open_close(h) +            tuned_file << t_o +          elsif t_o =~/^`:quote_open`/ +            @per.quote=:open +            @num_id[:quote] +=1 +            h={ +              is_for: :quote, +              obj: '', +              sym: :quote_open, +              num: @num_id[:quote], +            } +            t_o=SiSU_AO_DocumentStructure::ObjectLayout.new.open_close(h) +            #tuned_file << t_o #% find second source, entered twice, should be once so closed off here +          elsif t_o =~/^(?:table\(.+?\)\{|```[ ]+table\(.+?\)|\{table\(.+?\))/ +            @num_id[:table] +=1 +            h={ +              is_for: :table, +              obj: '', +              sym: :table_open, +              num: @num_id[:table], +            } +            ins_o=SiSU_AO_DocumentStructure::ObjectLayout.new.open_close(h) +            tuned_file << ins_o +            if t_o=~/^table\((?:.*?\bh;\s+)?.+?\)\{/ +              @per.table=:curls +              @rows='' +              case t_o +              when /table\(.*?\bh;\s+c(\d+):\s+(.+?)\)\{/ +                cols=$1 +                col=$2.scan(/\d+/) +                heading=true +              when /table\(.*?c(\d+):\s+(.+?)\)\{/ +                cols=$1 +                col=$2.scan(/\d+/) +                heading=false +              end +              @h={ +                head_: heading, +                cols: cols, +                widths: col, +                idx: idx, +              } +            elsif t_o=~/^```[ ]+table\((?:.*?\bh;)?\s+c\d+:/ +              @per.table=:tics +              @rows='' +              case t_o +              when /^```[ ]+table\(.*?\bh;\s+c(\d+):\s+(.+?)\)/ +                cols=$1 +                col=$2.scan(/\d+/) +                heading=true +              when /^```[ ]+table\(\s*c(\d+):\s+(.+?)\)/ +                cols=$1 +                col=$2.scan(/\d+/) +                heading=false +              end +              @h={ +                head_: heading, +                cols: cols, +                widths: col, +                idx: idx, +              } +            elsif t_o=~/^\{table\((?:.*?\bh;\s+)?(?:\s+\d+,?)?\)\s*\}\n.+\Z/m +              m1,m2,hd=nil,nil,nil +              tbl=/^\{table\((?:.*?\bh;\s+)?(?:\s+\d+,?)*\)\s*\}\n(.+)\Z/m.match(t_o)[1] # fix +              hd=((t_o =~/^\{table\(.*?\bh;\s+/) ? true : false) +              tbl,tags=extract_tags(tbl) +              rws=tbl.split(/\n/) +              rows='' +              cols=nil +              rws.each do |r| +                cols=(cols ? cols : (r.scan('|').length) +1) +                r=r.gsub(/\s*\|\s*/m,"#{Mx[:tc_p]}")       #r.gsub!(/\|/m,"#{Mx[:tc_p]}") +                rows += r + Mx[:tc_c] +              end +              col=[] +              if t_o =~/^\{table\((?:.*?\bh;\s+)?\s+c(\d+):.*?\)\s*\}/       #width of col 1 given as %, usually when wider than rest that are even +                c1=$1.to_i +                width=(100 - c1)/(cols - 1) +                col=[ c1 ] +                (cols - 1).times { col << width } +              else                                         #all columns of equal width +                width=100.00/cols +                cols.times { col << width } +              end +              h={ +                head_: hd, +                cols: cols, +                widths: col, +                obj: rows, +                idx: idx, +                tags: tags, +                num: @num_id[:table], +              } +              t_o=SiSU_AO_DocumentStructure::ObjectTable.new.table(h) \ +                unless h.nil? +              tuned_file << t_o +              h={ +                is_for: :table, +                obj: '', +                sym: :table_close, +                num: @num_id[:table], +              } +              t_o=SiSU_AO_DocumentStructure::ObjectLayout.new.open_close(h) +              t_o +            elsif t_o=~/^```[ ]+table\((?:.*?\bh;)?\s+/ +              m1,m2,hd=nil,nil,nil +              h=case t_o +              when /^```[ ]+table\(.*?\bh;\s+(.+?)\)\n(.+)\Z/m      #two table representations should be consolidated as one +                m1,tbl,hd=$1,$2,true +              when /^```[ ]+table\((.+?)\)\n(.+)\Z/m        #two table representations should be consolidated as one +                m1,tbl,hd=$1,$2,false +              else nil +              end +              tbl,tags=extract_tags(tbl) +              col=m1.scan(/\d+/) +              rws=tbl.split(/\n/) +              rows='' +              rws.each do |r| +                r=r.gsub(/\s*\|\s*/m,"#{Mx[:tc_p]}")       #r.gsub!(/\|/m,"#{Mx[:tc_p]}") +                rows += r + Mx[:tc_c] +              end +              h={ +                head_: hd, +                cols: col.length, +                widths: col, +                obj: rows, +                idx: idx, +                tags: tags, +                num: @num_id[:table], +              } +              t_o=SiSU_AO_DocumentStructure::ObjectTable.new.table(h) \ +                unless h.nil? +              tuned_file << t_o +              h={ +                is_for: :table, +                obj: '', +                sym: :table_close, +                num: @num_id[:table], +                } +              t_o=SiSU_AO_DocumentStructure::ObjectLayout.new.open_close(h) +              t_o +            elsif t_o=~/^\{table\((?:.*?\bh;)?/ +              m1,m2,hd=nil,nil,nil +              h=case t_o +              when /\{table\(.*?\bh;\s+(.+?)\)\s*\}\n(.+)\Z/m          #two table representations should be consolidated as one +                m1,tbl,hd=$1,$2,true +              when /\{table\((.+?)\)\s*\}\n(.+)\Z/m            #two table representations should be consolidated as one +                m1,tbl,hd=$1,$2,false +              else nil +              end +              tbl,tags=extract_tags(tbl) +              col=m1.scan(/\d+/) +              rws=tbl.split(/\n/) +              rows='' +              rws.each do |r| +                r=r.gsub(/\s*\|\s*/m,"#{Mx[:tc_p]}")       #r.gsub!(/\|/m,"#{Mx[:tc_p]}") +                rows += r + Mx[:tc_c] +              end +              h={ +                head_: hd, +                cols: col.length, +                widths: col, +                obj: rows, +                idx: idx, +                tags: tags, +                num: @num_id[:table], +              } +              t_o=SiSU_AO_DocumentStructure::ObjectTable.new.table(h) \ +                unless h.nil? +              tuned_file << t_o +              h={ +                is_for: :table, +                obj: '', +                sym: :table_close, +                num: @num_id[:table], +              } +              t_o=SiSU_AO_DocumentStructure::ObjectLayout.new.open_close(h) +              t_o +            end +## depreciated markup, code should work for new markup after removal { +          elsif t_o =~/^(?:table\{|```[ ]+table|\{table)[ ~]/ +            puts "WARNING document using depreciated markup for tables" +            puts "use table([table attributes]) instead:" +            puts "table(){" +            puts "``` table()" +            puts "{table()}" +            @num_id[:table] +=1 +            h={ +              is_for: :table, +              obj: '', +              sym: :table_open, +              num: @num_id[:table], +            } +            ins_o=SiSU_AO_DocumentStructure::ObjectLayout.new.open_close(h) +            tuned_file << ins_o +            if t_o=~/^table\{(?:~h)?\s+/ +              @per.table=:curls +              @rows='' +              case t_o +              when /table\{~h\s+c(\d+);\s+(.+)/ +                cols=$1 +                col=$2.scan(/\d+/) +                heading=true +              when /table\{\s+c(\d+);\s+(.+)/ +                cols=$1 +                col=$2.scan(/\d+/) +                heading=false +              end +              @h={ +                head_: heading, +                cols: cols, +                widths: col, +                idx: idx, +              } +            elsif t_o=~/^```[ ]+table(?:~h)?\s+c\d+/ +              @per.table=:tics +              @rows='' +              case t_o +              when /^```[ ]+table~h\s+c(\d+);\s+(.+)/ +                cols=$1 +                col=$2.scan(/\d+/) +                heading=true +              when /^```[ ]+table\s+c(\d+);\s+(.+)/ +                cols=$1 +                col=$2.scan(/\d+/) +                heading=false +              end +              @h={ +                head_: heading, +                cols: cols, +                widths: col, +                idx: idx, +              } +            elsif t_o=~/^\{table(?:~h)?(?:\s+\d+;?)?\}\n.+\Z/m +              m1,m2,hd=nil,nil,nil +              tbl=/^\{table(?:~h)?(?:\s+\d+;?)?\}\n(.+)\Z/m.match(t_o)[1] +              hd=((t_o =~/^\{table~h/) ? true : false) +              tbl,tags=extract_tags(tbl) +              rws=tbl.split(/\n/) +              rows='' +              cols=nil +              rws.each do |r| +                cols=(cols ? cols : (r.scan('|').length) +1) +                r=r.gsub(/\s*\|\s*/m,"#{Mx[:tc_p]}")       #r.gsub!(/\|/m,"#{Mx[:tc_p]}") +                rows += r + Mx[:tc_c] +              end +              col=[] +              if t_o =~/^\{table(?:~h)?\s+(\d+);?\}/       #width of col 1 given as %, usually when wider than rest that are even +                c1=$1.to_i +                width=(100 - c1)/(cols - 1) +                col=[ c1 ] +                (cols - 1).times { col << width } +              else                                         #all columns of equal width +                width=100.00/cols +                cols.times { col << width } +              end +              h={ +                head_: hd, +                cols: cols, +                widths: col, +                obj: rows, +                idx: idx, +                tags: tags, +                num: @num_id[:table], +              } +              t_o=SiSU_AO_DocumentStructure::ObjectTable.new.table(h) \ +                unless h.nil? +              tuned_file << t_o +              h={ +                is_for: :table, +                obj: '', +                sym: :table_close, +                num: @num_id[:table], +              } +              t_o=SiSU_AO_DocumentStructure::ObjectLayout.new.open_close(h) +              t_o +            elsif t_o=~/^```[ ]+table(?:~h)?\s+/ +              m1,m2,hd=nil,nil,nil +              h=case t_o +              when /^```[ ]+table~h\s+(.+?)\n(.+)\Z/m      #two table representations should be consolidated as one +                m1,tbl,hd=$1,$2,true +              when /^```[ ]+table\s+(.+?)\n(.+)\Z/m        #two table representations should be consolidated as one +                m1,tbl,hd=$1,$2,false +              else nil +              end +              tbl,tags=extract_tags(tbl) +              col=m1.scan(/\d+/) +              rws=tbl.split(/\n/) +              rows='' +              rws.each do |r| +                r=r.gsub(/\s*\|\s*/m,"#{Mx[:tc_p]}")       #r.gsub!(/\|/m,"#{Mx[:tc_p]}") +                rows += r + Mx[:tc_c] +              end +              h={ +                head_: hd, +                cols: col.length, +                widths: col, +                obj: rows, +                idx: idx, +                tags: tags, +                num: @num_id[:table], +              } +              t_o=SiSU_AO_DocumentStructure::ObjectTable.new.table(h) \ +                unless h.nil? +              tuned_file << t_o +              h={ +                is_for: :table, +                obj: '', +                sym: :table_close, +                num: @num_id[:table], +                } +              t_o=SiSU_AO_DocumentStructure::ObjectLayout.new.open_close(h) +              t_o +            elsif t_o=~/^\{table(?:~h)?\s+/ +              m1,m2,hd=nil,nil,nil +              h=case t_o +              when /\{table~h\s+(.+?)\}\n(.+)\Z/m          #two table representations should be consolidated as one +                m1,tbl,hd=$1,$2,true +              when /\{table\s+(.+?)\}\n(.+)\Z/m            #two table representations should be consolidated as one +                m1,tbl,hd=$1,$2,false +              else nil +              end +              tbl,tags=extract_tags(tbl) +              col=m1.scan(/\d+/) +              rws=tbl.split(/\n/) +              rows='' +              rws.each do |r| +                r=r.gsub(/\s*\|\s*/m,"#{Mx[:tc_p]}")       #r.gsub!(/\|/m,"#{Mx[:tc_p]}") +                rows += r + Mx[:tc_c] +              end +              h={ +                head_: hd, +                cols: col.length, +                widths: col, +                obj: rows, +                idx: idx, +                tags: tags, +                num: @num_id[:table], +              } +              t_o=SiSU_AO_DocumentStructure::ObjectTable.new.table(h) \ +                unless h.nil? +              tuned_file << t_o +              h={ +                is_for: :table, +                obj: '', +                sym: :table_close, +                num: @num_id[:table], +              } +              t_o=SiSU_AO_DocumentStructure::ObjectLayout.new.open_close(h) +              t_o +## } depreciated markup, code should (continue to) work for new markup after removal, +#    when removing depreciated markup check only pass-through for new table attributes format +#    table(.+?){  ``` table(.+?)  {table(.+?)} formats +            end +          end +          t_o +        end +        if @per.table==:curls or @per.table==:tics +          if (@per.table==:curls \ +          and (t_o.is_a?(String) and t_o =~/^\}table/)) \ +          or (@per.table==:tics \ +          and (t_o.is_a?(String) and t_o =~/^```(?:\s+[~-][#]|\s+\~\{.+?\}\~)?\s*$/)) +            @per.table=:off +            headings,columns,widths,idx=@h[:head_],@h[:cols],@h[:widths],@h[:idx] +            @h={ +              head_: headings, +              cols: columns, +              widths: widths, +              idx: idx, +              obj: @rows, +            } +            t_o=SiSU_AO_DocumentStructure::ObjectTable.new.table(@h) +            tuned_file << t_o +            @h,@rows=nil,'' +            h={ +              is_for: :table, +              obj: '', +              sym: :table_close, +              num: @num_id[:table], +            } +            t_o=SiSU_AO_DocumentStructure::ObjectLayout.new.open_close(h) +            t_o +          else +            if t_o.is_a?(String) \ +            and t_o !~/^(?:table\{|```[ ]+table)/ +              t_o=t_o.gsub(/^\n+/m,''). +                gsub(/\n+/m,"#{Mx[:tc_p]}") +              @rows += t_o + Mx[:tc_c] +            end +            t_o=nil +          end +        end +        if @per.code==:curls \ +        or @per.code==:tics +          if (@per.code==:curls \ +          && (t_o.is_a?(String) && t_o =~/^\}code/)) \ +          or (@per.code==:tics \ +          && (t_o.is_a?(String) && t_o =~/^```(?:\s+[~-][#]|\s+\~\{.+?\}\~)?\s*$/m) \ +          ) +            @per.code=:off +            if @tuned_code[-1] +              @tuned_code[-1]. +                gsub!(/\s*(?:#{Mx[:br_line]}|#{Mx[:br_nl]})\s*\Z/m,'') +            end +            obj=@tuned_code.join("\n") +            tags=[] +            h={ +              obj: obj, +              idx: idx, +              syntax: @per.lngsyn, +              tags: tags, +              num: @num_id[:code_block], +              number_: @codeblock_numbered, +            } +            @per.lngsyn=:txt +            t_o=SiSU_AO_DocumentStructure::ObjectBlockTxt.new.code(h) +            @tuned_code=[] +            tuned_file << t_o +            h={ +              is_for: :code, +              obj: '', +              sym: :code_close, +              num: @num_id[:code_block], +            } +            t_o=SiSU_AO_DocumentStructure::ObjectLayout.new.open_close(h) +          end +          if (@per.code==:curls \ +          || @per.code==:tics) \ +          and t_o.is_a?(String) +            sub_array=t_o.dup + "#{Mx[:br_nl]}" +            @line_mode=[] +            sub_array.scan(/.+/) {|w| @line_mode << w if w =~/[\S]+/} +            t_o=SiSU_AO_DocumentStructureExtract::Build.new(@md,@line_mode).build_lines(:code).join +            @tuned_code << t_o +            t_o=nil +          end +        elsif (@per.poem==:curls \ +        || @per.poem==:tics) \ +        or (@per.box==:curls \ +        || @per.box==:tics) \ +        or (@per.group==:curls \ +        || @per.group==:tics) \ +        or (@per.block==:curls \ +        || @per.block==:tics) \ +        or (@per.alt==:curls \ +        || @per.alt==:tics) \ +        or (@per.quote==:open \ +        && (t_o.is_a?(String) && t_o =~/`:quote_close`/m)) +          if (@per.poem==:curls \ +          && (t_o.is_a?(String) && t_o.to_s =~/^\}poem$/m)) \ +          or (@per.poem==:tics \ +          && (t_o.is_a?(String) && t_o =~/^```(?:\s+[~-][#]|\s+\~\{.+?\}\~)?\s*$/)) +            @per.poem=:off +            h={ +              is_for: :poem, +              obj: '', +              idx: idx, +              sym: :poem_close, +              num: @num_id[:poem], +            } +            t_o=SiSU_AO_DocumentStructure::ObjectLayout.new.open_close(h) +          elsif (@per.box==:curls \ +          && (t_o.is_a?(String) && t_o =~/^\}box/)) \ +          or (@per.box==:tics \ +          && (t_o.is_a?(String) && t_o.to_s =~/^```(?:\s+[~-][#]|\s+\~\{.+?\}\~)?\s*$/)) +            @per.box=:off +            obj,tags=extract_tags(@tuned_block.join("\n")) +            h={ +              obj: obj, +              idx: idx, +              tags: tags, +              num: @num_id[:box], +            } +            @tuned_block=[] +            t_o=SiSU_AO_DocumentStructure::ObjectBlockTxt.new.box(h) +            tuned_file << t_o +            h={ +              is_for: :box, +              obj: '', +              idx: idx, +              sym: :box_close, +              num: @num_id[:box], +            } +            t_o=SiSU_AO_DocumentStructure::ObjectLayout.new.open_close(h) +          elsif (@per.group==:curls \ +          && ( t_o.is_a?(String) && t_o.to_s =~/^\}group/)) \ +          or (@per.group==:tics \ +          && (t_o.is_a?(String) && t_o.to_s =~/^```(?:\s+[~-][#]|\s+\~\{.+?\}\~)?\s*$/)) +            @per.group=:off +            obj,tags=extract_tags(@tuned_block.join("\n")) +            h={ +              obj: obj, +              idx: idx, +              tags: tags, +              num: @num_id[:group], +            } +            @tuned_block=[] +            t_o=SiSU_AO_DocumentStructure::ObjectBlockTxt.new.group(h) +            tuned_file << t_o +            h={ +              is_for: :group, +              obj: '', +              sym: :group_close, +              num: @num_id[:group], +            } +            t_o=SiSU_AO_DocumentStructure::ObjectLayout.new.open_close(h) +          elsif (@per.block==:curls \ +          && t_o.to_s =~/^\}block/) \ +          or (@per.block==:tics \ +          && (t_o.is_a?(String) \ +            && t_o =~/^```(?:\s+[~-][#]|\s+\~\{.+?\}\~)?\s*$/) \ +          ) +            @per.block=:off +            obj,tags=extract_tags(@tuned_block.join("\n")) +            h={ +              obj: obj, +              idx: idx, +              tags: tags, +              num: @num_id[:block], +            } +            @tuned_block=[] +            t_o=SiSU_AO_DocumentStructure::ObjectBlockTxt.new.block(h) +            tuned_file << t_o +            h={ +              is_for: :block, +              obj: '', +              sym: :block_close, +              num: @num_id[:block], +            } +            t_o=SiSU_AO_DocumentStructure::ObjectLayout.new.open_close(h) +          elsif (@per.alt==:curls \ +          && (t_o.is_a?(String) && t_o =~/^\}alt/)) \ +          or (@per.alt==:tics \ +          && t_o.is_a?(String) \ +            && (t_o =~/^```(?:\s+[~-][#]|\s+\~\{.+?\}\~)?\s*$/) +          ) +            @per.alt=:off +            obj,tags=extract_tags(@tuned_block.join("\n")) +            h={ +              obj: obj, +              idx: idx, +              tags: tags, +              num: @num_id[:alt], +            } +            t_o=SiSU_AO_DocumentStructure::ObjectBlockTxt.new.alt(h) +            @tuned_block=[] +            tuned_file << t_o +            h={ +              is_for: :alt, +              obj: '', +              sym: :alt_close, +              num: @num_id[:alt], +            } +            t_o=SiSU_AO_DocumentStructure::ObjectLayout.new.open_close(h) +          elsif @per.quote==:open \ +          and (t_o.is_a?(String) &&  t_o =~/`:quote_close`/m) +            @per.quote=:off +            h={ +              is_for: :quote, +              idx: idx, +              obj: '', +              sym: :quote_close, +              num: @num_id[:quote], +            } +            t_o=SiSU_AO_DocumentStructure::ObjectLayout.new.open_close(h) +          elsif @per.quote==:open +            t_o,tags=extract_tags(t_o) +            h={ +              indent: 1, +              obj: t_o, +              idx: idx, +              note_: note, +              image_: image, +              tags: tags, +              quote: quotes?, +            } +            SiSU_AO_DocumentStructure::ObjectPara.new.paragraph(h) +          end +          if (@per.poem==:curls \ +          || @per.poem==:tics) \ +          or (@per.group==:curls \ +          || @per.group==:tics) \ +          or (@per.block==:curls \ +          || @per.block==:tics) \ +          or (@per.alt==:curls \ +          || @per.alt==:tics) \ +          and (t_o.is_a?(String) \ +            and t_o.to_s =~/\S/ \ +            and t_o.to_s !~/^(?:\}(?:verse|code|box|alt|group|block)|(?:verse|code(?:\.[a-z][0-9a-z_]+)?|box(?:\.[a-z_]+)?|alt|group|block)\{)/ \ +            and t_o.to_s !~/^```[ ]+(?:code(?:\.[a-z][0-9a-z_]+)?|box(?:\.[a-z_]+)?|poem|alt|group|block)|^```(?:\s+[~-][#]|\s+\~\{.+?\}\~)?\s*$/ +          ) +            sub_array=t_o.to_s.dup +            @line_mode=sub_array.scan(/.+/) +            type=if @per.poem==:curls or @per.poem==:tics +              t_o=SiSU_AO_DocumentStructureExtract::Build.new(@md,@line_mode).build_lines(type).join +              poem=t_o.split(/\n\n/) +              poem.each do |v| +                v=v.gsub(/\n/m,"#{Mx[:br_nl]}\n") +                obj,tags=extract_tags(v) +                h={ +                  obj: obj, +                  tags: tags, +                  num: @num_id[:poem], +                } +                t_o=SiSU_AO_DocumentStructure::ObjectBlockTxt.new.verse(h) +                tuned_file << t_o +              end +              :poem +            else :group +            end +          end +          @verse_count+=1 if @per.poem==:curls or @per.poem==:tics +        end +        if @per.code==:off +          if @per.poem==:curls or @per.poem==:tics \ +          or @per.box==:curls or @per.box==:tics \ +          or @per.group==:curls or @per.group==:tics \ +          or @per.block==:curls or @per.block==:tics \ +          or @per.alt==:curls or @per.alt==:tics \ +          or (@per.quote==:open and t_o =~/`:quote_close`/m) +            if t_o.is_a?(String) +              t_o=t_o.gsub(/\n/m,"#{Mx[:br_nl]}"). +                gsub(/[ ][ ]/m,"#{Mx[:nbsp]*2}"). +                gsub(/#{Mx[:nbsp]}\s/,"#{Mx[:nbsp]*2}") +              t_o=t_o + Mx[:br_nl] if t_o =~/\S+/ +            elsif t_o.is==:group \ +            || t_o.is==:block \ +            || t_o.is==:alt \ +            || t_o.is==:box \ +            || t_o.is==:verse +              t_o.obj=t_o.obj.gsub(/\n/m,"#{Mx[:br_nl]}"). +                gsub(/[ ][ ]/m,"#{Mx[:nbsp]*2}"). +                gsub(/#{Mx[:nbsp]}\s/,"#{Mx[:nbsp]*2}") +            end +            @tuned_block << t_o if t_o.to_s =~/\S+/ +          else tuned_file << t_o +          end +        else tuned_file << t_o +        end +      end +      tuned_file +    end +    def identify_parts +      tuned_file=[] +      @tuned_block,@tuned_code=[],[] +      @@counter,@verse_count=0,0 +      @num_id={ +        code_block: 0, +        poem:       0, +        box:        0, +        block:      0, +        group:      0, +        alt:        0, +        quote:      0, +        table:      0, +      } +      @metadata={} +      if @md.flag_auto_biblio \ +      or @md.flag_biblio +        @data,bibliography=SiSU_AO_Appendices::Bibliography.new(@md,@data).biblio_extraction +      end +      if @md.flag_glossary +        @data,glossary=SiSU_AO_Appendices::Glossary.new(@md,@data).glossary_extraction +      end +      tuned_file=extract_structure_loop(@data,tuned_file) +      if @md.flag_endnotes +        tuned_file << @pb +        h={ +          ln: 1, +          lc: 1, +          obj: 'Endnotes', +          autonum_: false, +        } +        tuned_file << SiSU_AO_DocumentStructure::ObjectHeading.new.heading_insert(h) +        h={ +          ln: 4, +          lc: 2, +          obj: 'Endnotes', +          name: 'endnotes', +          autonum_: false, +        } +        tuned_file << SiSU_AO_DocumentStructure::ObjectHeading.new.heading_insert(h) +        h={ +          obj: 'Endnotes' +        } +      end +      if @md.flag_glossary +        tuned_file << @pb +        h={ +          ln: 1, +          lc: 1, +          obj: 'Glossary', +          autonum_: false, +        } +        tuned_file << SiSU_AO_DocumentStructure::ObjectHeading.new.heading_insert(h) +        h={ +          ln: 4, +          lc: 2, +          obj: 'Glossary', +          name: 'glossary', +          autonum_: false, +        } +        tuned_file << SiSU_AO_DocumentStructure::ObjectHeading.new.heading_insert(h) +        h={ +          obj: 'Glossary' +        } +        if glossary.length > 0 +          tuned_file=extract_structure_loop(glossary,tuned_file) +        end +      end +      if @md.flag_auto_biblio +        tuned_file << @pb +        h={ +          ln: 1, +          lc: 1, +          obj: 'References', +          autonum_: false, +        } +        tuned_file << SiSU_AO_DocumentStructure::ObjectHeading.new.heading_insert(h) +        h={ +          ln: 4, +          lc: 2, +          obj: 'Bibliography', +          name: 'biblio', +          autonum_: false, +        } +        tuned_file << SiSU_AO_DocumentStructure::ObjectHeading.new.heading_insert(h) +        h={ +          obj: 'Bibliography' +        } +        citenumber=0 +        bibliography.each do |cite| +          citenumber +=1 if cite.is_a?(Hash) +          h={ +            obj: cite[:obj], +            #obj: %{[#{citenumber}] } + cite[:obj], +            tags: [cite[:id]], +            hang: 0, +            indent: 2, +            ocn_: false, +          } +          tuned_file << SiSU_AO_DocumentStructure::ObjectPara.new.paragraph(h) +        end +      elsif @md.flag_biblio +        tuned_file << @pb +        h={ +          ln: 1, +          lc: 1, +          obj: 'References', +          autonum_: false, +        } +        tuned_file << SiSU_AO_DocumentStructure::ObjectHeading.new.heading_insert(h) +        h={ +          ln: 4, +          lc: 2, +          obj: 'Bibliography', +          name: 'biblio', +          autonum_: false, +        } +        tuned_file << SiSU_AO_DocumentStructure::ObjectHeading.new.heading_insert(h) +        h={ +          obj: 'Bibliography' +        } +        if not bibliography.nil? \ +        and bibliography.length > 0 +          tuned_file=extract_structure_loop(bibliography,tuned_file) +        else +          tuned_file, citations = +            SiSU_AO_Appendices::Citations.new(@md,tuned_file).songsheet  # ao_appendices.rb +          citenumber=0 +          citations.compact.each do |c| +            citenumber +=1 if c.is_a?(Hash) +            if c[:is]==:book +              h={ +                obj: %{#{c[:author]}. /{#{c[:publication]}}/ (#{c[:year]})}, +                #obj: %{[#{citenumber}] *{#{c[:author]}}* /{#{c[:publication]}}/ (#{c[:year]})}, +                hang: 0, +                indent: 2, +                ocn_: false, +              } +              tuned_file << SiSU_AO_DocumentStructure::ObjectPara.new.paragraph(h) +            elsif c[:is]==:article +              h={ +                obj: %{#{c[:author]}. /{"#{c[:title]}"}/ #{c[:publication]} editor #{c[:editor]} (#{c[:year]})}, +                #obj: %{[#{citenumber}] *{#{c[:author]}}* /{"#{c[:title]}"}/ #{c[:publication]} editor #{c[:editor]} (#{c[:year]})}, +                hang: 0, +                indent: 2, +                ocn_: false, +              } +              tuned_file << SiSU_AO_DocumentStructure::ObjectPara.new.paragraph(h) +            end +          end +        end +      end +      if @md.book_idx +        tuned_file << @pb +        h={ +          ln: 1, +          lc: 1, +          obj: 'Index', +          autonum_: false, +        } +        tuned_file << SiSU_AO_DocumentStructure::ObjectHeading.new.heading_insert(h) +        h={ +          ln: 4, +          lc: 2, +          obj: 'Index', +          name: 'book_index', +          autonum_: false, +        } +        tuned_file << SiSU_AO_DocumentStructure::ObjectHeading.new.heading_insert(h) +        h={ +          obj: 'Index' +        } +      end +      tuned_file << @pb +      if @make.build.metadata? +        h={ +          ln: 1, +          lc: 1, +          obj: 'Metadata', +          autonum_: false, +          ocn_: false, +        } +        tuned_file << SiSU_AO_DocumentStructure::ObjectHeading.new.heading_insert(h) +        h={ +          ln: 4, +          lc: 2, +          obj: 'SiSU Metadata, document information', +          name: 'metadata', +          autonum_: false, +          ocn_: false, +        } +        tuned_file << SiSU_AO_DocumentStructure::ObjectHeading.new.heading_insert(h) +      end +      h={ +        obj: 'eof', +      } +      meta=SiSU_AO_DocumentStructure::ObjectMetadata.new.metadata(@metadata) +      [tuned_file,meta,bibliography,glossary] +    end +    def table_rows_and_columns_array(table_str) +      table=[] +      table_str.split(/#{Mx[:tc_c]}/).each do |table_row| +        table_row_with_columns=table_row.split(/#{Mx[:tc_p]}/) +        table << table_row_with_columns +      end +      table +    end +    def meta_heading(h) +      h={ +        lv: h[:lv], +        ln: h[:ln], +        name: h[:name], +        obj: h[:obj], +        ocn: '0', +      } +      SiSU_AO_DocumentStructure::ObjectHeading.new.heading(h) +    end +    def meta_para(str) +      h={ +        obj: str, +        ocn_: false, +      } +      SiSU_AO_DocumentStructure::ObjectPara.new.paragraph(h) +    end +    def build_lines(type=:none) +      lines=@data +      lines.each.map do |line| +        line=if line =~/\S/ \ +        and line !~/^(?:code(?:\.[a-z][0-9a-z_]+)?\{|\}code)/ \ +        and line !~/^(?:```[ ]+code(?:\.[a-z][0-9a-z_]+)?|```(?:\s+[~-][#]|\s+\~\{.+?\}\~)?\s*$)/ \ +        and not line.is_a?(Hash) #watch +          @@counter+=1 if @per.code==:curls or @per.code==:tics +          line=line.gsub(/\s\s/,"#{Mx[:nbsp]*2}"). +            gsub(/#{Mx[:nbsp]}\s/,"#{Mx[:nbsp]*2}") +          line=line.gsub(/^/,"#{Mx[:gr_o]}codeline#{Mx[:gr_c]}") if type==:code # REMOVE try sort for texpdf special case +          line=if line =~/(?:https?|file|ftp):\/\/\S+$/ +            line.gsub(/\s*$/," #{Mx[:br_nl]}") +          else line.gsub(/\s*$/,"#{Mx[:br_nl]}")           #unless type=='code' +          end +        elsif line =~/^\s*$/ +          line.gsub(/\s*$/,"#{Mx[:br_nl]}") +        else line +        end +        line +      end +    end +  end +  class Structure                                          # this must happen early +    def initialize(md) +      @md=md +    end +    def structure(data) +      data.compact.each do |dob| +        structure_markup(dob) +      end +    end +    def structure_markup(dob)                                   #build structure where structure provided only in meta header +      dob=if dob.is==:para \ +      && (((dob.hang !~/[1-9]/) && (dob.indent !~/[1-9]/)) \ +      || (dob.hang != dob.indent)) \ +      and not dob.bullet_ +        dob=case dob.obj +        when /^#{@md.lv0}/ +          h={ +            is: :heading, +            lv: 'A', +            ln: 0, +          } +          SiSU_AO_DocumentStructure::ObjectHeading.new.heading(h,dob) +        when /^#{@md.lv1}/ +          h={ +            is: :heading, +            lv: 'B', +            ln: 1, +          } +          SiSU_AO_DocumentStructure::ObjectHeading.new.heading(h,dob) +        when /^#{@md.lv2}/ +          h={ +            is: :heading, +            lv: 'C', +            ln: 2, +          } +          SiSU_AO_DocumentStructure::ObjectHeading.new.heading(h,dob) +        when /^#{@md.lv3}/ +          h={ +            is: :heading, +            lv: 'D', +            ln: 3, +          } +          SiSU_AO_DocumentStructure::ObjectHeading.new.heading(h,dob) +        when /^#{@md.lv4}/ +          h={ +            is: :heading, +            lv: '1', +            ln: 4, +          } +          SiSU_AO_DocumentStructure::ObjectHeading.new.heading(h,dob) +        when /^#{@md.lv5}/ +          h={ +            is: :heading, +            lv: '2', +            ln: 5, +          } +          SiSU_AO_DocumentStructure::ObjectHeading.new.heading(h,dob) +        when /^#{@md.lv6}/ +          h={ +            is: :heading, +            lv: '3', +            ln: 6, +          } +          SiSU_AO_DocumentStructure::ObjectHeading.new.heading(h,dob) +        else dob +        end +      else dob +      end +      dob +    end +  end +  class OCN +    def initialize(md,data,fnx,process) +      @md,@data,@fnx,@process=md,data,fnx,process +    end +    def structure_info +      def lv +        %w[A~ B~ C~ D~ 1 2 3 4] +      end +      def possible_parents(child) +        case child +        when /A~/ then 'none' +        when /B~/ then 'A~' +        when /C~/ then 'B~' +        when /D~/ then 'C~' +        when /1/  then 'A~, B~, C~, D~' +        when /2/  then '1' +        when /3/  then '2' +        when /4/  then '3' +        end +      end +      def possible_children(parent) +        case parent +        when /A~/ then 'B~, 1' +        when /B~/ then 'C~, 1' +        when /C~/ then 'D~, 1' +        when /D~/ then '1' +        when /1/  then '2' +        when /2/  then '3' +        when /3/  then '4' +        when /4/  then 'none' +        end +      end +      self +    end +    def document_structure_check_info(node,node_parent,status=:ok) +      node_ln=/^([0-7])/.match(node)[1].to_i +      node_parent_ln=/^([0-7])/.match(node_parent)[1].to_i +      if status==:error \ +      or @md.opt.act[:maintenance][:set]==:on +        puts %{node: #{node},    parent node: #{node_parent}  #{status.upcase}} +        if status==:error +          node_ln=/^([0-7])/.match(node)[1].to_i +          node_parent_ln=/^([0-7])/.match(node_parent)[1].to_i +          STDERR.puts %{current level: #{structure_info.lv[node_ln]} (possible parent levels: #{structure_info.possible_parents(structure_info.lv[node_ln])}) +parent level:  #{structure_info.lv[node_parent_ln]} (possible child levels: #{structure_info.possible_children(structure_info.lv[node_parent_ln])}) +SKIPPED processing file: +[#{@md.opt.lng}] "#{@md.fns}"} +          if @md.opt.act[:no_stop][:set]==:on +            $process_document = :skip +          else exit +          end +        end +      end +    end +    def warning_incorrect_parent_level_or_level(txt) +      puts %{ERROR. There is an error in markup of heading levels either here or in the parent heading. +The current header reads: +"#{txt}" +has incorrect level and/or parent level +--} +    end +    def required_headers_present? +      if @process == :complete +        unless (defined? @md.title \ +        and @md.title.full) +           STDERR.puts %{required header missing: + +@title: +SKIPPED processing file: +[#{@md.opt.lng}] "#{@md.fns}" +} +          if @md.opt.act[:no_stop][:set]==:on +            $process_document = :skip +          else exit +          end +        end +        unless (defined? @md.creator.author \ +        and @md.creator.author) +           STDERR.puts %{required header missing: + +@creator: + :author: anonymous? +SKIPPED processing file: +[#{@md.opt.lng}] "#{@md.fns}" +} +          if @md.opt.act[:no_stop][:set]==:on +            $process_document = :skip +          else exit +          end +        end +      end +    end +    def ocn                                                                      #and auto segment numbering increment +      required_headers_present? +      data=@data +      @o_array=[] +      node=ocn=ocn_dv=ocn_sp=ocnh=ocnh0=ocnh1=ocnh2=ocnh3=ocnh4=ocnh5=ocnh6=ocnh7=ocno=ocnp=ocnt=ocnc=ocng=ocni=ocnu=0 # h heading, o other, t table, g group, i image +      regex_exclude_ocn_and_node = /#{Rx[:meta]}|^@\S+?:\s|^4~endnotes|^#{Mx[:lv_o]}4:endnotes#{Mx[:lv_c]}|^\^~ |<:e[:_]\d+?>|^<:\#|<:- |<[:!]!4|<hr width|#{Mx[:br_endnotes]}|\A\s*\Z/mi #ocn here #  added with Tune.code #¡ +      parent=node1=node2=node3=node4=node5=node6=node7=nil +      node0='0:0;0' +      @collapsed_lv0=0 +      @lev_occurences={ a: 0, b: 0, c: 0, d: 0, l1: 0, l2: 0, l3: 0, l4: 0 } +      data.each do |dob| +        h={} +        if (dob.obj !~ regex_exclude_ocn_and_node || dob.is==:code) \ +        && (dob.of !=:comment \ +        && dob.of !=:layout \ +        && dob.of !=:meta) \ +        && dob.ocn_ +          #dob.ln now is determined, and set earlier, check how best to remove this --> +          if dob.is==:heading +             @ln=ln=case dob.lv +             when 'A' then 0 +             when 'B' then 1 +             when 'C' then 2 +             when 'D' then 3 +             when '1' then 4 +             when '2' then 5 +             when '3' then 6 +             when '4' then 7 +             when '5' then 8 +             when '6' then 9 +             end +          end +          if not dob.obj =~/~#|-#/ +            ocn+=1 +          end +          if @process == :complete \ +          or (@fnx == @md.opt.fns \ +          && @md.opt.fns =~/.sst$/) +            if dob.is==:heading \ +            and (ln.to_s =~/^[0-9]/ \ +            or ln.to_s =~@md.lv0 \ +            or ln.to_s =~@md.lv1 \ +            or ln.to_s =~@md.lv2 \ +            or ln.to_s =~@md.lv3 \ +            or ln.to_s =~@md.lv4 \ +            or ln.to_s =~@md.lv5 \ +            or ln.to_s =~@md.lv6 \ +            or ln.to_s =~@md.lv7) +              if not dob.obj =~/~#|-#/ +                ocnh+=1 +              end +              if ln==0 \ +              or ln.to_s =~@md.lv0 +                @lev_occurences[:a] += 1 +                if not dob.obj =~/~#|-#/ +                  ocn_flag=true +                  ocnh0+=1                     #heading +                  node0="0:#{ocnh0};#{ocn}" +                else +                  #document_structure_check_info(node0,node0,:error) #fix +                  ocn_flag=false +                  node0="0:0;0" +                end +                document_structure_check_info(node0,node0) +                @collapsed_lv0=0 +                collapsed_level=@collapsed_lv0 +                node,ocn_sp,parent=node0,"h#{ocnh}",'ROOT' +              elsif ln==1 \ +              or ln.to_s =~@md.lv1 +                @lev_occurences[:b] += 1 +                if not dob.obj =~/~#|-#/ +                  ocn_flag=true +                  ocnh1+=1                     #heading +                  node1="1:#{ocnh1};#{ocn}" +                else +                  #document_structure_check_info(node0,node0,:error) #fix +                  ocn_flag=false +                  node1="1:0;0" +                end +                parent=if node0 +                  document_structure_check_info(node1,node0) +                  @collapsed_lv1=@collapsed_lv0+1 +                  node0 +                else +                  warning_incorrect_parent_level_or_level(dob.obj) +                  document_structure_check_info(node0,node0,:error) +                  node0 +                end +                collapsed_level=@collapsed_lv1 +                node,ocn_sp,parent=node1,"h#{ocnh}",node0 #FIX +              elsif ln==2 \ +              or ln.to_s =~@md.lv2 +                @lev_occurences[:c] += 1 +                if not dob.obj =~/~#|-#/ +                  ocn_flag=true +                  ocnh2+=1 +                  node2="2:#{ocnh2};#{ocn}" +                else +                  #document_structure_check_info(node0,node0,:error) #fix +                  ocn_flag=false +                  node2="2:0;0" +                end +                parent=if node1 +                  document_structure_check_info(node2,node1) +                  @collapsed_lv2=@collapsed_lv1+1 +                  node1 +                else +                  warning_incorrect_parent_level_or_level(dob.obj) +                  document_structure_check_info(node2,node0,:error) +                  node0 +                end +                collapsed_level=@collapsed_lv2 +                node,ocn_sp=node2,"h#{ocnh}" +              elsif ln==3 \ +              or ln.to_s =~@md.lv3 +                @lev_occurences[:d] += 1 +                if not dob.obj =~/~#|-#/ +                  ocn_flag=true +                  ocnh3+=1 +                  node3="3:#{ocnh3};#{ocn}" +                else +                  #document_structure_check_info(node0,node0,:error) #fix +                  ocn_flag=false +                  node3="3:0;0" +                end +                parent=if node2 +                  document_structure_check_info(node3,node2) +                  @collapsed_lv3=@collapsed_lv2+1 +                  node2 +                elsif node1 +                  warning_incorrect_parent_level_or_level(dob.obj) +                  puts %{parent is :A~ & this level #{dob.lv} +either parent should be level :B~ +or this level should be level :B~ rather than #{dob.lv}} +                  document_structure_check_info(node3,node1,:error) +                  @collapsed_lv3=@collapsed_lv1+1 +                  node1 +                else +                  document_structure_check_info(node3,node0,:error) +                  warning_incorrect_parent_level_or_level(dob.obj) +                  node0 +                end +                collapsed_level=@collapsed_lv3 +                node,ocn_sp=node3,"h#{ocnh}" +              elsif ln==4 \ +              or ln.to_s =~@md.lv4 +                @lev_occurences[:l1] += 1 +                if not dob.obj =~/~#|-#/ +                  ocn_flag=true +                  ocnh4+=1 +                  node4="4:#{ocnh4};#{ocn}" +                else +                  ocn_flag=false +                  node4="4:0;0" +                end +                parent=if node3 +                  document_structure_check_info(node4,node3) +                  @collapsed_lv4=@collapsed_lv3+1 +                  node3 +                elsif node2 +                  document_structure_check_info(node4,node2) +                  @collapsed_lv4=@collapsed_lv2+1 +                  node2 +                elsif node1 +                  document_structure_check_info(node4,node1) +                  @collapsed_lv4=@collapsed_lv1+1 +                  node1 +                elsif node0 +                  document_structure_check_info(node4,node0) +                  @collapsed_lv4=@collapsed_lv0+1 +                  node0 +                else +                  warning_incorrect_parent_level_or_level(dob.obj) +                  document_structure_check_info(node4,node0,:error) +                  node0 +                end +                collapsed_level=@collapsed_lv4 +                node,ocn_sp=node4,"h#{ocnh}" +              elsif ln==5 \ +              or ln.to_s =~@md.lv5 +                @lev_occurences[:l2] += 1 +                if not dob.obj =~/~#|-#/ +                  ocn_flag=true +                  ocnh5+=1 +                  node5="5:#{ocnh5};#{ocn}" +                else +                  ocn_flag=false +                  node5="5:0;0" +                end +                parent=if node4 +                  document_structure_check_info(node5,node4) +                  @collapsed_lv5=@collapsed_lv4+1 +                  node4 +                elsif node3 +                  warning_incorrect_parent_level_or_level(dob.obj) +                  document_structure_check_info(node5,node3,:error) +                  @collapsed_lv5=@collapsed_lv3+1 +                  node3 +                elsif node2 +                  warning_incorrect_parent_level_or_level(dob.obj) +                  document_structure_check_info(node5,node2,:error) +                  @collapsed_lv5=@collapsed_lv2+1 +                  node2 +                elsif node1 +                  warning_incorrect_parent_level_or_level(dob.obj) +                  document_structure_check_info(node5,node1,:error) +                  @collapsed_lv5=@collapsed_lv1+1 +                  node1 +                else +                  warning_incorrect_parent_level_or_level(dob.obj) +                  document_structure_check_info(node5,node0,:error) +                  node0 +                end +                collapsed_level=@collapsed_lv5 +                node,ocn_sp=node5,"h#{ocnh}" +              elsif ln==6 \ +              or ln.to_s =~@md.lv6 +                @lev_occurences[:l3] += 1 +                if not dob.obj =~/~#|-#/ +                  ocn_flag=true +                  ocnh6+=1 +                  node6="6:#{ocnh6};#{ocn}" +                else +                  ocn_flag=false +                  node6="6:0;0" +                end +                parent=if node5 +                  document_structure_check_info(node6,node5) +                  @collapsed_lv6=@collapsed_lv5+1 +                  node5 +                elsif node4 +                  warning_incorrect_parent_level_or_level(dob.obj) +                  puts "parent is level #4 (1~) & this level ##{dob.ln} (#{dob.lv}~) +either parent should be level #5 (2~) +or this level should be #5 (2~) rather ##{dob.ln} (#{dob.lv}~)" +                  document_structure_check_info(node6,node4,:error) +                  @collapsed_lv6=@collapsed_lv4+1 +                  node4 +                elsif node3 +                  warning_incorrect_parent_level_or_level(dob.obj) +                  document_structure_check_info(node6,node3,:error) +                  @collapsed_lv6=@collapsed_lv3+1 +                  node3 +                elsif node2 +                  warning_incorrect_parent_level_or_level(dob.obj) +                  document_structure_check_info(node6,node2,:error) +                  @collapsed_lv6=@collapsed_lv2+1 +                  node2 +                elsif node1 +                  warning_incorrect_parent_level_or_level(dob.obj) +                  document_structure_check_info(node6,node1,:error) +                  @collapsed_lv6=@collapsed_lv1+1 +                  node1 +                else +                  warning_incorrect_parent_level_or_level(dob.obj) +                  document_structure_check_info(node6,node0,:error) +                  node0 +                end +                collapsed_level=@collapsed_lv6 +                node,ocn_sp=node6,"h#{ocnh}" +              elsif ln==7 \ +              or ln.to_s =~@md.lv7 +                @lev_occurences[:l4] += 1 +                if not dob.obj =~/~#|-#/ +                  ocn_flag=true +                  ocnh7+=1 +                  node7="7:#{ocnh7};#{ocn}" +                else +                  ocn_flag=false +                  node7="7:0;0" +                end +                parent=if node6 +                  document_structure_check_info(node7,node6) +                  @collapsed_lv7=@collapsed_lv6+1 +                  node5 +                elsif node5 +                  warning_incorrect_parent_level_or_level(dob.obj) +                  puts "parent is level #5 (2~) & this level ##{dob.ln} (#{dob.lv}~) +either parent should be level #6 (3~) +or this level should be #6 (3~) rather ##{dob.ln} (#{dob.lv}~)" +                  document_structure_check_info(node7,node5,:error) +                  @collapsed_lv6=@collapsed_lv5+1 +                  node5 +                elsif node4 +                  warning_incorrect_parent_level_or_level(dob.obj) +                  puts "parent is level #4 (1~) & this level ##{dob.ln} (#{dob.lv}~) +either parent should be level 6~ +or this level should be #6 (3~) rather ##{dob.ln} (#{dob.lv}~)" +                  document_structure_check_info(node7,node4,:error) +                  @collapsed_lv6=@collapsed_lv4+1 +                  node4 +                elsif node3 +                  warning_incorrect_parent_level_or_level(dob.obj) +                  document_structure_check_info(node7,node3,:error) +                  @collapsed_lv6=@collapsed_lv3+1 +                  node3 +                elsif node2 +                  warning_incorrect_parent_level_or_level(dob.obj) +                  document_structure_check_info(node7,node2,:error) +                  @collapsed_lv6=@collapsed_lv2+1 +                  node2 +                elsif node1 +                  warning_incorrect_parent_level_or_level(dob.obj) +                  document_structure_check_info(node7,node1,:error) +                  @collapsed_lv6=@collapsed_lv1+1 +                  node1 +                else +                  warning_incorrect_parent_level_or_level(dob.obj) +                  document_structure_check_info(node7,node0,:error) +                  node0 +                end +                collapsed_level=@collapsed_lv7 +                node,ocn_sp=node7,"h#{ocnh}" +              end +            else +              unless @lev_occurences[:l1] > 0 +                STDERR.puts %{Substantive text objects must follow a level 1~ heading and there are none at this point in processing: #{@lev_occurences[:l1]} +SKIPPED processing file: +[#{@md.opt.lng}] "#{@md.fns}"} +                puts dob.obj #.gsub(/^(.{1,80})/,'"\1"') +                exit +              end +              unless @ln >= 4 +                lev=case @ln +                when 0 then 'A' +                when 1 then 'B' +                when 2 then 'C' +                when 3 then 'D' +                when 4 then '1' +                when 5 then '2' +                when 6 then '3' +                when 7 then '4' +                when 8 then '5' +                when 9 then '6' +                end +                STDERR.puts %{Substantive text objects must follow a level 1~ 2~ or 3~ heading: #{lev}~ +SKIPPED processing file: +[#{@md.opt.lng}] "#{@md.fns}"} +                puts dob.obj.gsub(/^(.{1,80})/,'"\1"') +                if @md.opt.act[:no_stop][:set]==:on +                  $process_document = :skip +                  break +                else exit +                end +              end +              if not dob.obj =~/~#|-#/ +                ocn_flag=true +              else +                ocn_flag=false +              end +              ocno+=1 +              if dob.is==:table +                ocnt+=1 +                ocn_sp,parent="t#{ocnt}",node +              elsif dob.is==:code +                ocnc+=1 +                ocn_sp,parent="c#{ocnc}",node +              elsif dob.is==:group \ +              || dob.is==:box \ +              || dob.is==:block \ +              || dob.is==:alt \ +              || dob.is==:verse +                ocng+=1 #group, poem +                ocn_sp,parent="g#{ocng}",node +              elsif dob.is==:image #check +                ocni+=1 +                ocn_sp,parent="i#{ocni}",node +              else ocnp+=1                                 #paragraph +                ocn_sp,parent="p#{ocnp}",node +              end +            end +          end +          if dob.is==:heading +            if ocn_flag==true +              dob.ln,dob.node,dob.ocn,dob.ocn_,dob.odv,dob.osp,dob.parent,dob.lc= +                ln,  node,    ocn,    ocn_flag, ocn_dv,ocn_sp, parent,    collapsed_level +            else +              ocnu+=1 +              heading_use=:ok +              if dob.obj=~/#{Mx[:pa_non_object_no_heading]}/ +                dob.obj=dob.obj.gsub(/#{Mx[:pa_non_object_no_heading]}/,'') +                heading_use=:ok +              elsif dob.obj=~/#{Mx[:pa_non_object_dummy_heading]}/ +                dob.obj=dob.obj.gsub(/#{Mx[:pa_non_object_dummy_heading]}/,'') +                heading_use=:dummy +              end +              dob.ln,dob.node,dob.ocn,dob.ocn_,dob.use_,   dob.odv,dob.osp,dob.parent,dob.lc= +                ln,  node,    nil,    ocn_flag,heading_use,ocn_dv, ocn_sp, parent,    collapsed_level +            end +          else +            if dob.of !=:meta \ +            && dob.of !=:comment \ +            && dob.of !=:layout +              if ocn_flag == true +                dob.ocn,dob.ocn_,dob.odv,dob.osp,dob.parent= +                  ocn,  ocn_flag,ocn_dv, ocn_sp, parent +              else +                ocnu+=1 +                dob.obj=dob.obj.gsub(/#{Mx[:fa_o]}[~-]##{Mx[:fa_c]}/,'') if dob.obj +                ocn_dv,ocn_sp="u#{ocnu}","u#{ocnu}" +                dob.ocn,dob.ocn_,dob.odv,dob.osp,dob.parent= +                  nil,  ocn_flag,ocn_dv, ocn_sp, parent +              end +            end +          end +          h +        else dob +        end +        if dob.is==:code \ +        || dob.is==:verse \ +        || dob.is==:alt \ +        || dob.is==:box \ +        || dob.is==:group \ +        || dob.is==:block +          dob.obj=dob.obj.gsub(/\n+/,"\n") #newlines taken out +        end +        @o_array << dob +      end +      if @process == :complete \ +      or (@fnx == @md.opt.fns \ +      && @md.opt.fns =~/.sst$/) +        unless @lev_occurences[:a] == 1 +          STDERR.puts %{The number of level A~ in this document: #{@lev_occurences[:a]} +There must be one level A~ (no more and no less) +SKIPPED processing file: +[#{@md.opt.lng}] "#{@md.fns}"} +          if @md.opt.act[:no_stop][:set]==:on +            $process_document = :skip +          else exit +          end +        end +        unless @lev_occurences[:l1] > 0 +          STDERR.puts %{The number of level 1~ in this document: #{@lev_occurences[:l1]} +There must be at least one level 1~ (and as many as required) +SKIPPED processing file: +[#{@md.opt.lng}] "#{@md.fns}"} +          if @md.opt.act[:no_stop][:set]==:on +            $process_document = :skip +          else exit +          end +        end +      end +      @o_array +    end +  end +  class XML +    def initialize(md,data) +      @data,@md=data,md +    end +    def dom +      @s=[ 'A', 'B', 'C', 'D', '1', '2', '3' ] +      tuned_file=structure_build +      tuned_file +    end +    def spaces +      Ax[:spaces] +    end +    def structure_build +      data=@data +      tuned_file=[] +      hs=[0,false,false,false] +      t={ +        lv: @s[0], +        status: :open, +      } +      tuned_file << tags(t) +      if @md.opt.act[:verbose_plus][:set]==:on +        puts "\nXML sisu structure outline --->\n" +        puts "<#{@s[0]}>" +      end +      data.each_with_index do |o,i| +        if o.is==:heading \ +        || o.is==:heading_insert +          case o.ln +          when 0 +            tuned_file << tag_close(o.ln,hs) +            tuned_file << tag_open(o,@s) +            if @md.opt.act[:verbose_plus][:set]==:on +              puts_tag_close(o.ln,hs) +              puts_tag_open(o,@s) +            end +            hs=[0,true,false,false,false] +          when 1 +            tuned_file << tag_close(o.ln,hs) +            tuned_file << tag_open(o,@s) +            if @md.opt.act[:verbose_plus][:set]==:on +              puts_tag_close(o.ln,hs) +              puts_tag_open(o,@s) +            end +            hs=[1,true,true,false,false] +          when 2 +            tuned_file << tag_close(o.ln,hs) +            tuned_file << tag_open(o,@s) +            if @md.opt.act[:verbose_plus][:set]==:on +              puts_tag_close(o.ln,hs) +              puts_tag_open(o,@s) +            end +            hs=[2,true,true,true,false] +          when 3 +            tuned_file << tag_close(o.ln,hs) +            tuned_file << tag_open(o,@s) +            if @md.opt.act[:verbose_plus][:set]==:on +              puts_tag_close(o.ln,hs) +              puts_tag_open(o,@s) +            end +            hs=[3,true,true,true,true] +          when 4 +            tuned_file << tag_close(o.ln,hs) +            tuned_file << tag_open(o,@s) +            if @md.opt.act[:verbose_plus][:set]==:on +              puts_tag_close(o.ln,hs) +              puts_tag_open(o,@s) +            end +            hs[0]=4 +          when 5 +            tuned_file << tag_close(o.ln,hs) +            tuned_file << tag_open(o,@s) +            if @md.opt.act[:verbose_plus][:set]==:on +              puts_tag_close(o.ln,hs) +              puts_tag_open(o,@s) +            end +            hs[0]=5 +          when 6 +            tuned_file << tag_close(o.ln,hs) +            tuned_file << tag_open(o,@s) +            if @md.opt.act[:verbose_plus][:set]==:on +              puts_tag_close(o.ln,hs) +              puts_tag_open(o,@s) +            end +            hs[0]=6 +          end +        end +        tuned_file << o +      end +      if @md.opt.act[:verbose_plus][:set]==:on +        puts_tag_close(0,hs) +      end +      tuned_file << tag_close(0,hs) +      tuned_file=tuned_file.flatten +    end +    def tags(o) +      tag=(o[:status]==:open) \ +      ? %{<#{o[:lv]} id="#{o[:node]}">} +      : "</#{o[:lv]}>" +      ln=case o[:lv] +      when 'A' then 0 +      when 'B' then 1 +      when 'C' then 2 +      when 'D' then 3 +      when '1' then 4 +      when '2' then 5 +      when '3' then 6 +      when '4' then 7 +      when '5' then 8 +      when '6' then 9 +      end +      h={ +        tag: tag, +        node: o[:node], +        lv: o[:lv], +        ln: ln, +        status: o[:status], +      } +      SiSU_AO_DocumentStructure::ObjectStructure.new.xml_dom(h) #downstream code utilise else ignore like comments +    end +    def tag_open(o,tag) +      t={ lv: tag[o.ln], node: o.node, status: :open } +      t_o=tags(t) +      t_o +    end +    def tag_close(lev,hs) +      ary=[] +      case hs[0] +      when 0 +        if (lev <= 0) and hs[0] +          t={ +            lv: @s[0], +            status: :close, +          } +          ary << tags(t) +        end +      when 1 +        if (lev <= 1) and hs[1] +          t={ +            lv: @s[1], +            status: :close, +          } +          ary << tags(t) +        end +        if (lev==0) +          t={ +            lv: @s[0], +            status: :close, +          } +          ary << tags(t) +        end +      when 2 +        if (lev <= 2) and hs[2] +          t={ +            lv: @s[2], +            status: :close, +          } +          ary << tags(t) +        end +        if (lev <= 1) and hs[1] +          t={ +            lv: @s[1], +            status: :close, +          } +          ary << tags(t) +        end +        if (lev==0) +          t={ +            lv: @s[0], +            status: :close, +          } +          ary << tags(t) +        end +      when 3 +        if (lev <= 3) and hs[3] +          t={ +            lv: @s[3], +            status: :close, +          } +          ary << tags(t) +        end +        if (lev <= 2) and hs[2] +          t={ +            lv: @s[2], +            status: :close, +          } +          ary << tags(t) +        end +        if (lev <= 1) and hs[1] +          t={ +            lv: @s[1], +            status: :close, +          } +          ary << tags(t) +        end +        if (lev==0) +          t={ +            lv: @s[0], +            status: :close, +          } +          ary << tags(t) +        end +      when 4 +        if (lev <= 4) +          t={ +            lv: @s[4], +            status: :close, +          } +          ary << tags(t) +        end +        if (lev <= 3) and hs[3] +          t={ +            lv: @s[3], +            status: :close, +          } +          ary << tags(t) +        end +        if (lev <= 2) and hs[2] +          t={ +            lv: @s[2], +            status: :close, +          } +          ary << tags(t) +        end +        if (lev <= 1) and hs[1] +          t={ +            lv: @s[1], +            status: :close, +          } +          ary << tags(t) +        end +        if (lev==0) +          t={ +            lv: @s[0], +            status: :close, +          } +          ary << tags(t) +        end +      when 5 +        if (lev <= 5) +          t={ +            lv: @s[5], +            status: :close, +          } +          ary << tags(t) +        end +        if (lev <= 4) +          t={ +            lv: @s[4], +            status: :close, +          } +          ary << tags(t) +        end +        if (lev <= 3) and hs[3] +          t={ +            lv: @s[3], +            status: :close, +          } +          ary << tags(t) +        end +        if (lev <= 2) and hs[2] +          t={ +            lv: @s[2], +            status: :close, +          } +          ary << tags(t) +        end +        if (lev <= 1) and hs[1] +          t={ +            lv: @s[1], +            status: :close, +          } +          ary << tags(t) +        end +        if (lev==0) +          t={ +            lv: @s[0], +            status: :close, +          } +          ary << tags(t) +        end +      when 6 +        if (lev <= 6) +          t={ +            lv: @s[6], +            status: :close, +          } +          ary << tags(t) +        end +        if (lev <= 5) +          t={ +            lv: @s[5], +            status: :close, +          } +          ary << tags(t) +        end +        if (lev <= 4) +          t={ +            lv: @s[4], +            status: :close, +          } +          ary << tags(t) +        end +        if (lev <= 3) and hs[3] +          t={ +            lv: @s[3], +            status: :close, +          } +          ary << tags(t) +        end +        if (lev <= 2) and hs[2] +          t={ +            lv: @s[2], +            status: :close, +          } +          ary << tags(t) +        end +        if (lev <= 1) and hs[1] +          t={ +            lv: @s[1], +            status: :close, +          } +          ary << tags(t) +        end +        if (lev==0) +          t={ +            lv: @s[0], +            status: :close, +          } +          ary << tags(t) +        end +      end +      ary +    end +    def puts_tag_open(o,tag) +      puts %{#{spaces*o.ln}<#{tag[o.ln]} id="#{o.node}">} +    end +    def puts_tag_close(lev,hs) +      case hs[0] +      when 0 +        #puts "#{spaces*0}</#{@s[0]}>" if (lev <= 0) and hs[0] +        puts "</#{@s[0]}>"         if (lev==0) +      when 1 +        puts "#{spaces*1}</#{@s[1]}>" if (lev <= 1) and hs[1] +        puts "</#{@s[0]}>"         if (lev==0) +      when 2 +        puts "#{spaces*2}</#{@s[2]}>" if (lev <= 2) and hs[2] +        puts "#{spaces*1}</#{@s[1]}>" if (lev <= 1) and hs[1] +        puts "</#{@s[0]}>"         if (lev==0) +      when 3 +        puts "#{spaces*3}</#{@s[3]}>" if (lev <= 3) and hs[3] +        puts "#{spaces*2}</#{@s[2]}>" if (lev <= 2) and hs[2] +        puts "#{spaces*1}</#{@s[1]}>" if (lev <= 1) and hs[1] +        puts "</#{@s[0]}>"         if (lev==0) +      when 4 +        puts "#{spaces*4}</#{@s[4]}>" if (lev <= 4) +        puts "#{spaces*3}</#{@s[3]}>" if (lev <= 3) and hs[3] +        puts "#{spaces*2}</#{@s[2]}>" if (lev <= 2) and hs[2] +        puts "#{spaces*1}</#{@s[1]}>" if (lev <= 1) and hs[1] +        puts "</#{@s[0]}>"         if (lev==0) +      when 5 +        puts "#{spaces*5}</#{@s[5]}>" if (lev <= 5) +        puts "#{spaces*4}</#{@s[4]}>" if (lev <= 4) +        puts "#{spaces*3}</#{@s[3]}>" if (lev <= 3) and hs[3] +        puts "#{spaces*2}</#{@s[2]}>" if (lev <= 2) and hs[2] +        puts "#{spaces*1}</#{@s[1]}>" if (lev <= 1) and hs[1] +        puts "</#{@s[0]}>"         if (lev==0) +      when 6 +        puts "#{spaces*6}</#{@s[6]}>" if (lev <= 6) +        puts "#{spaces*5}</#{@s[5]}>" if (lev <= 5) +        puts "#{spaces*4}</#{@s[4]}>" if (lev <= 4) +        puts "#{spaces*3}</#{@s[3]}>" if (lev <= 3) and hs[3] +        puts "#{spaces*2}</#{@s[2]}>" if (lev <= 2) and hs[2] +        puts "#{spaces*1}</#{@s[1]}>" if (lev <= 1) and hs[1] +        puts "</#{@s[0]}>"         if (lev==0) +      end +    end +  end +end +__END__ +#+END_SRC + +** ao_endnotes.rb + +#+BEGIN_SRC ruby  :tangle "../lib/sisu/ao_endnotes.rb_" +# <<sisu_document_header>> +module SiSU_AO_Endnotes +  class Endnotes +    def initialize(md,data,endnote_array=nil) +      @md,@data,@endnote_array= +      md, data, endnote_array +      @endnote_counter, +        @endnote_counter_asterisk, +        @endnote_counter_dag= +        1,1,1 +    end +    def endnotes +      data=@data +      endnote_ref=1 +      @tuned_file=data.each.map do |dob| +                                                                               # manually numbered endnotes <!e(\d)!> <!e_(\d)!> --> +        if @md.opt.selections.str =~/--no-asterisk|--no-annotate/ +          dob.obj=dob.obj. +            gsub(/#{Mx[:en_b_o]}\s.+?#{Mx[:en_b_c]}/,'') +        end +        if @md.opt.selections.str =~/--no-dagger|--no-annotate/ +          dob.obj=dob.obj. +            gsub(/#{Mx[:en_b_o]}[+]\s.+?#{Mx[:en_b_c]}/,'') +        end +        if (defined? dob.obj) \ +        && (defined? dob.is) \ +        && dob.is !=:code +          case dob.obj                                                         # auto-numbered endnotes <!e!> <!e_!> --> +          when /#{Mx[:en_a_o]}.+?#{Mx[:en_a_c]}|#{Mx[:en_b_o]}[*+]\s+.+?#{Mx[:en_b_c]}/ +            dob.obj=dob.obj. +              gsub(/\s*(#{Mx[:en_a_c]}|#{Mx[:en_b_c]})/,'\1') +            word_mode=dob.obj.scan(/\S+/m) +            word_mode=endnote_call_number(word_mode) +            dob.obj=word_mode.join(' ') +            endnote_ref+=1 +          when /~\^(?:\s|$)/                                              #%note inserts endnotes previously gathered from /^(<!e[:_]!>|[-~]\{{3})/ (in earlier loop) +            word_mode=dob.obj.scan(/\S+/m) +            word_mode=endnote_call_number(word_mode) +            dob.obj=word_mode.join(' ') +            endnote_ref+=1 +          end +        end +        dob +      end.flatten +      @endnote_counter, +        @endnote_counter_asterisk, +        @endnote_counter_dag= +        1,1,1 +      @tuned_file +    end +    def endnote_call_number(words) +      words.each do |word| +        case word +        when /#{Mx[:en_a_o]}/ +          unless word =~/#{Mx[:en_a_o]}[*+]+/ +            word.gsub!(/#{Mx[:en_a_o]}/, +              "#{Mx[:en_a_o]}#{@endnote_counter} ") +            @endnote_counter+=1 +          end +        when /#{Mx[:en_b_o]}/ +          if word =~/#{Mx[:en_b_o]}[+]/ +            word.gsub!(/#{Mx[:en_b_o]}[+]/, +              "#{Mx[:en_b_o]}\+#{@endnote_counter_dag} ") +            @endnote_counter_dag+=1 +          else +            word.gsub!(/#{Mx[:en_b_o]}[*]?/, +              "#{Mx[:en_b_o]}\*#{@endnote_counter_asterisk} ") +            @endnote_counter_asterisk+=1 +          end +        when /~\^/ +          if @endnote_array +            word.gsub!(/~\^/, +              "#{@endnote_array[@endnote_counter-1]}") +            @endnote_counter+=1 +          end +        end +      end +    end +  end +end +__END__ +#+END_SRC + +** ao_expand_insertions.rb + +#+BEGIN_SRC ruby  :tangle "../lib/sisu/ao_expand_insertions.rb" +# <<sisu_document_header>> +module SiSU_AO_Insertions +  class Insertions +    def initialize(md,data) +      @md,@data=md,data +    end +    def output_filetypes_in_cmd(cmd_shortcut,lnk=nil) #make list of file types in shortcut command (as configured), e.g. when sisu -3 is used +      act_defaults=SiSU_Env::InfoProcessingFlag.new +      cmd_list=case cmd_shortcut.inspect #check on expectation, string v array +      when /0/ then act_defaults.act_0.str +      when /1/ then act_defaults.act_1.str +      when /2/ then act_defaults.act_2.str +      when /3/ then act_defaults.act_3.str +      when /4/ then act_defaults.act_4.str +      when /5/ then act_defaults.act_5.str +      when /6/ then act_defaults.act_6.str +      when /7/ then act_defaults.act_7.str +      when /8/ then act_defaults.act_8.str +      when /9/ then act_defaults.act_9.str +      end +      file_type_names={} +      file_type_names[:gen],file_type_names[:src]=[],[] +      file_type_names[:gen] <<= if cmd_list =~ /\b--manifest\b/ +        "~^ { document manifest }#{lnk[:manifest]}" +      end +      file_type_names[:gen] <<= if cmd_list =~ /\b--html\b/ +        [ +          " { html, segmented text }#{lnk[:html_toc]}", +          " { html, scroll, document in one }#{lnk[:html_doc]}", +        ] +      end +      file_type_names[:gen] <<= if cmd_list =~ /\b--epub\b/ +        [" { epub }#{lnk[:epub]}"] +      end +      file_type_names[:gen] <<= if cmd_list =~ /\b--pdf\b/ \ +      or cmd_list =~ /--pdf-landscape/ +        [ +          " { pdf, landscape }#{lnk[:pdf_landscape]}", +        ] +      end +      file_type_names[:gen] <<= if cmd_list =~ /\b--pdf\b/ \ +      or cmd_list =~ /--pdf-portrait/ +        [ +          " { pdf, portrait }#{lnk[:pdf_portrait]}", +        ] +      end +      file_type_names[:gen] <<= if cmd_list =~ /\b(?:--odt|--odf)\b/ +        " { odf:odt, open document text }#{lnk[:odt]}" +      end +      file_type_names[:gen] <<= if cmd_list =~ /\b--xhtml\b/ +        " { xhtml scroll }#{lnk[:xhtml]}" +      end +      file_type_names[:gen] <<= if cmd_list =~ /\b--docbook\b/ +        " { docbook }#{lnk[:docbook]}" #CHECK +      end +      file_type_names[:gen] <<= if cmd_list =~ /\b--xml-sax\b/ +        " { xml, sax }#{lnk[:xml_sax]}" +      end +      file_type_names[:gen] <<= if cmd_list =~ /\b--xml-dom\b/ +        " { xml, dom }#{lnk[:xml_dom]}" +      end +      file_type_names[:gen] <<= if cmd_list =~ /\b(?:--txt|--text|--plaintext)\b/ +        " { plain text utf-8 }#{lnk[:txt]}" +      end +      #file_type_names[:gen] <<= if cmd_list =~ /g/ +      #  'wiki.txt' +      #end +      file_type_names[:gen] <<= if cmd_list =~ /\b--concordance\b/ +        " { concordance }#{lnk[:html_concordance]}" +      end +      file_type_names[:gen] <<= if cmd_list =~ /\b--digest\b/ +        " { dcc, document content certificate (digests) }#{lnk[:digest]}" +      end +      file_type_names[:src] <<= if source and cmd_shortcut =~ /\b--source\b/ +        " { markup source text }#{lnk[:source]}" +      end +      file_type_names[:src] <<= if cmd_shortcut =~ /\b--sisupod\b/ +        " { markup source (zipped) pod }#{lnk[:sisupod]}" +      end +      file_type_names[:gen]=file_type_names[:gen].flatten +      file_type_names[:src]=file_type_names[:src].flatten +      file_type_names +    end +    def by_language(linked_doc,lng,src=nil) +      @linked_doc,@lng,@src=linked_doc,lng,src +      @base_path="#{@md.file.output_path.base.url}/#{lng}" +      def fnh +        { +          fn: @linked_doc, +        } +      end +      def path_and_file(fn,pth) +        @base_path + '/' + pth + '/' + fn +      end +      def manifest +        fn=@md.file.base_filename.manifest(fnh) +        path_and_file(fn,'manifest') +      end +      def html_toc +        fn=@md.file.base_filename.html_segtoc(fnh) +        @base_path + '/html/' + @linked_doc + '/' + fn +      end +      def html_doc +        fn=@md.file.base_filename.html_scroll(fnh) +        path_and_file(fn,'html') +      end +      def html_concordance +        fn=@md.file.base_filename.html_concordance +        @base_path + '/html/' + @linked_doc + '/' + fn +      end +      def epub +        fn=@md.file.base_filename.epub(fnh) +        path_and_file(fn,'epub') +      end +      def pdf_landscape +        fn=@md.file.base_filename.pdf_l_a4(fnh) +        path_and_file(fn,'pdf') +      end +      def pdf_portrait +        fn=@md.file.base_filename.pdf_p_a4(fnh) +        path_and_file(fn,'pdf') +      end +      def odt +        fn=@md.file.base_filename.odt(fnh) +        path_and_file(fn,'odt') +      end +      def xhtml +        fn=@md.file.base_filename.xhtml(fnh) +        path_and_file(fn,'xhtml') +      end +      def docbook +        fn=@md.file.base_filename.xml_docbook_book(fnh) +        path_and_file(fn,'docbook') +      end +      def xml_sax +        fn=@md.file.base_filename.xml_sax(fnh) +        path_and_file(fn,'xml_sax') +      end +      def xml_dom +        fn=@md.file.base_filename.xml_dom(fnh) +        path_and_file(fn,'xml_dom') +      end +      def txt +        fn=@md.file.base_filename.txt(fnh) +        path_and_file(fn,'txt') +      end +      def digest +        fn=@md.file.base_filename.hash_digest(fnh) +        path_and_file(fn,'digest') +      end +      def source +        @base_path + '/src/' + @src +      end +      def sisupod +        @base_path + '/src/' + @src + '.zip' +      end +      self +    end +    def by_filetype(linked_doc,lng,src=nil) +      @linked_doc,@lng,@src=linked_doc,lng,src +      @lc=SiSU_Env::FilenameLanguageCodeInsert.new(@md.opt,lng). +        language_code_insert +      @base_path="#{@md.file.output_path.base.url}" +      def fnh +        { +          fn: @linked_doc, +          lng: @lc, +        } +      end +      def path_and_file(fn,pth) +        @base_path + '/' + pth + '/' + fn +      end +      def manifest +        fn=@md.file.base_filename.manifest(fnh) +        path_and_file(fn,'manifest') +      end +      def html_toc +        fn=@md.file.base_filename.html_segtoc(fnh) +        path_and_file(fn,'html') +      end +      def html_doc +        fn=@md.file.base_filename.html_scroll(fnh) +        path_and_file(fn,'html') +      end +      def html_concordance +        fn=@md.file.base_filename.html_concordance +        path_and_file(fn,'html') +      end +      def epub +        fn=@md.file.base_filename.epub(fnh) +        path_and_file(fn,'epub') +      end +      def pdf_landscape +        fn=@md.file.base_filename.pdf_l_a4(fnh) +        path_and_file(fn,'pdf') +      end +      def pdf_portrait +        fn=@md.file.base_filename.pdf_p_a4(fnh) +        path_and_file(fn,'pdf') +      end +      def odt +        fn=@md.file.base_filename.odt(fnh) +        path_and_file(fn,'odt') +      end +      def xhtml +        fn=@md.file.base_filename.xhtml(fnh) +        path_and_file(fn,'xhtml') +      end +      def docbook +        fn=@md.file.base_filename.xml_docbook_book(fnh) +        path_and_file(fn,'docbook') +      end +      def xml_sax +        fn=@md.file.base_filename.xml_sax(fnh) +        path_and_file(fn,'xml_sax') +      end +      def xml_dom +        fn=@md.file.base_filename.xml_dom(fnh) +        path_and_file(fn,'xml_dom') +      end +      def txt +        fn=@md.file.base_filename.txt(fnh) +        path_and_file(fn,'txt') +      end +      def digest +        fn=@md.file.base_filename.hash_digest(fnh) +        path_and_file(fn,'digest') +      end +      def source +        @base_path + '/src/' + @src +      end +      def sisupod +        @base_path + '/src/' + @src + '.zip' +      end +      self +    end +    def by_filename(linked_doc,lng,src=nil) +      @linked_doc,@lng,@src=linked_doc,lng,src +      @lc=SiSU_Env::FilenameLanguageCodeInsert.new(@md.opt,lng).language_code_insert +      @base_path="#{@md.file.output_path.base.url}/#{@linked_doc}" +      def fnh +        { +          fn: @linked_doc, +          lng: @lc, +        } +      end +      def path_and_file(fn,pth=nil) +        (pth.nil?) \ +        ? @base_path + '/' + fn +        : @base_path + '/' + pth + '/' + fn +      end +      def manifest +        fn=@md.file.base_filename.manifest(fnh) +        path_and_file(fn) +      end +      def html_toc +        fn=@md.file.base_filename.html_segtoc(fnh) +        path_and_file(fn) +      end +      def html_doc +        fn=@md.file.base_filename.html_scroll(fnh) +        path_and_file(fn) +      end +      def html_concordance +        fn=@md.file.base_filename.html_concordance +        path_and_file(fn) +      end +      def epub +        fn=@md.file.base_filename.epub(fnh) +        path_and_file(fn,'epub') +      end +      def pdf_landscape +        fn=@md.file.base_filename.pdf_l_a4(fnh) +        path_and_file(fn) +      end +      def pdf_portrait +        fn=@md.file.base_filename.pdf_p_a4(fnh) +        path_and_file(fn) +      end +      def odt +        fn=@md.file.base_filename.odt(fnh) +        path_and_file(fn) +      end +      def xhtml +        fn=@md.file.base_filename.xhtml(fnh) +        path_and_file(fn) +      end +      def docbook +        fn=@md.file.base_filename.xml_docbook_book(fnh) +        path_and_file(fn) +      end +      def xml_sax +        fn=@md.file.base_filename.xml_sax(fnh) +        path_and_file(fn) +      end +      def xml_dom +        fn=@md.file.base_filename.xml_dom(fnh) +        path_and_file(fn) +      end +      def txt +        fn=@md.file.base_filename.txt(fnh) +        path_and_file(fn) +      end +      def digest +        fn=@md.file.base_filename.hash_digest(fnh) +        path_and_file(fn) +      end +      def source +        @base_path + '/' + @src +      end +      def sisupod +        @base_path + '/' + @src + '.zip' +      end +      self +    end +    def expand_insertions? +      data=@data +      tuned_file,tuned_file_tmp=[],[] +      codeblock_={ +        status: :false, +        type:   :na, +      } +      data.each do |para| +        codeblock_=if para =~/^code(?:\.[a-z][0-9a-z_]+)?\{/ \ +        and codeblock_[:status]==:false +          { +            status: :true, +            type:   :curl, +          } +        elsif para =~/^```[ ]+code(?:\.[a-z][0-9a-z_]+)?/ \ +        and codeblock_[:status]==:false +          { +            status: :true, +            type:   :tics, +          } +        elsif codeblock_[:type]==:curl \ +        and para =~/^\}code/m +          { +            status: :false, +            type:   :na, +          } +        elsif codeblock_[:type]==:tics \ +        and para =~/^```(?:\s|$)/m +          { +            status: :false, +            type:   :na, +          } +        else codeblock_ +        end +        if para !~/^%+\s/ \ +        and codeblock_[:status] != :true \ +        and para =~/\{(?:~\^\s+)?(.+?)\s\[(?:\d(?:[sS]*))\]\}(?:\.\.\/\S+?\/|\S+?\.ss[tm]\b)/ +          @u=SiSU_Env::InfoEnv.new.url +          m_cmd='' +          if defined? @u.remote +            if /(?<m_pre>.+?)\{(?<m_txt>.+?)\s\[(?<m_cmd>\d[sS]*)\]\}(?<m_source>(?<m_linked_doc>\S+?)\.ss[tm]\b)(?<m_note>.*)/m =~ para +              m_pre=m_pre.strip +            elsif /\{(?<m_txt>.+?)\s\[(?<m_cmd>\d[sS]*)\]\}(?<m_source>(?<m_linked_doc>\S+?)\.ss[tm]\b)(?<m_note>.*)/m =~ para +            end +            if m_linked_doc =~ /(\S+?)\/(\S+)/ +              m_linked_doc,m_linked_doc_lang=$1,$2 +            else +              m_linked_doc,m_linked_doc_lang=m_linked_doc,@md.opt.lng_base +            end +          else +            puts "error, does currently support relative paths (reltive paths were removed, as had problems for citation, and was not suited to all output types should possibly reconsider) #{__FILE__} #{__LINE__}" +            if /\{(?:~\^\s+)?(?<m_txt>.+?)\s\[(?<m_cmd>\d[sS]*)\]\}\.\.\/(?<m_linked_doc>\S+?)\/(?<m_note>\s+#{Mx[:en_a_o]}.+?#{Mx[:en_a_c]})?/ =~ para +            end +          end +          lnk=case @md.opt.dir_structure_by +          when :language +            { +              manifest:         by_language(m_linked_doc,m_linked_doc_lang).manifest, +              html_toc:         by_language(m_linked_doc,m_linked_doc_lang).html_toc, +              html_doc:         by_language(m_linked_doc,m_linked_doc_lang).html_doc, +              epub:             by_language(m_linked_doc,m_linked_doc_lang).epub, +              pdf_landscape:    by_language(m_linked_doc,m_linked_doc_lang).pdf_landscape, +              pdf_portrait:     by_language(m_linked_doc,m_linked_doc_lang).pdf_landscape, +              odt:              by_language(m_linked_doc,m_linked_doc_lang).odt, +              xhtml:            by_language(m_linked_doc,m_linked_doc_lang).xhtml, +              docbook:          by_language(m_linked_doc,m_linked_doc_lang).docbook, +              xml_sax:          by_language(m_linked_doc,m_linked_doc_lang).xml_sax, +              xml_dom:          by_language(m_linked_doc,m_linked_doc_lang).xml_dom, +              txt:              by_language(m_linked_doc,m_linked_doc_lang).txt, +              html_concordance: by_language(m_linked_doc,m_linked_doc_lang).html_concordance, +              digest:           by_language(m_linked_doc,m_linked_doc_lang).digest, +              sisupod:          by_language(m_linked_doc,m_linked_doc_lang,m_source).sisupod, +              source:           by_language(m_linked_doc,m_linked_doc_lang,m_source).source, +            } +          when :filetype +            { +              manifest:         by_filetype(m_linked_doc,m_linked_doc_lang).manifest, +              html_toc:         by_filetype(m_linked_doc,m_linked_doc_lang).html_toc, +              html_doc:         by_filetype(m_linked_doc,m_linked_doc_lang).html_doc, +              epub:             by_filetype(m_linked_doc,m_linked_doc_lang).epub, +              pdf_landscape:    by_filetype(m_linked_doc,m_linked_doc_lang).pdf_landscape, +              pdf_portrait:     by_filetype(m_linked_doc,m_linked_doc_lang).pdf_landscape, +              odt:              by_filetype(m_linked_doc,m_linked_doc_lang).odt, +              xhtml:            by_filetype(m_linked_doc,m_linked_doc_lang).xhtml, +              docbook:          by_filetype(m_linked_doc,m_linked_doc_lang).docbook, +              xml_sax:          by_filetype(m_linked_doc,m_linked_doc_lang).xml_sax, +              xml_dom:          by_filetype(m_linked_doc,m_linked_doc_lang).xml_dom, +              txt:              by_filetype(m_linked_doc,m_linked_doc_lang).txt, +              html_concordance: by_filetype(m_linked_doc,m_linked_doc_lang).html_concordance, +              digest:           by_filetype(m_linked_doc,m_linked_doc_lang).digest, +              sisupod:          by_filetype(m_linked_doc,m_linked_doc_lang,m_source).sisupod, +              source:           by_filetype(m_linked_doc,m_linked_doc_lang,m_source).source, +            } +          else +            { +              manifest:         by_filename(m_linked_doc,m_linked_doc_lang).manifest, +              html_toc:         by_filename(m_linked_doc,m_linked_doc_lang).html_toc, +              html_doc:         by_filename(m_linked_doc,m_linked_doc_lang).html_doc, +              epub:             by_filename(m_linked_doc,m_linked_doc_lang).epub, +              pdf_landscape:    by_filename(m_linked_doc,m_linked_doc_lang).pdf_landscape, +              pdf_portrait:     by_filename(m_linked_doc,m_linked_doc_lang).pdf_landscape, +              odt:              by_filename(m_linked_doc,m_linked_doc_lang).odt, +              xhtml:            by_filename(m_linked_doc,m_linked_doc_lang).xhtml, +              docbook:          by_filename(m_linked_doc,m_linked_doc_lang).docbook, +              xml_sax:          by_filename(m_linked_doc,m_linked_doc_lang).xml_sax, +              xml_dom:          by_filename(m_linked_doc,m_linked_doc_lang).xml_dom, +              txt:              by_filename(m_linked_doc,m_linked_doc_lang).txt, +              html_concordance: by_filename(m_linked_doc,m_linked_doc_lang).html_concordance, +              digest:           by_filename(m_linked_doc,m_linked_doc_lang).digest, +              sisupod:          by_filename(m_linked_doc,m_linked_doc_lang,m_source).sisupod, +              source:           by_filename(m_linked_doc,m_linked_doc_lang,m_source).source, +            } +          end +          linked_title="#{m_pre}{#{m_txt} }#{lnk[:manifest]}#{m_note}\n\n" +          tuned_file_tmp << linked_title +          output_filetypes=output_filetypes_in_cmd(m_cmd,lnk) +          output_filetypes[:gen].each do |desc| +            if desc +              tuned_file_tmp << if @u.remote +                "#{Mx[:nbsp]*4} #{desc} " +              else # remove ... +                "[provide document placement host location]" +              end +            end +          end +          output_filetypes[:src].each do |desc| +            if desc +              tuned_file_tmp << if @u.remote +                "#{Mx[:nbsp]*4} #{desc} " +              else +                "[provide document placement host location]" +              end +            end +          end +          tuned_file << 'group{' << tuned_file_tmp.join("\n") << '}group' +          tuned_file_tmp=[] +        else tuned_file << para +        end +      end +      tuned_file +    end +  end +end +__END__ +#+END_SRC + +** ao_hash_digest.rb + +#+BEGIN_SRC ruby  :tangle "../lib/sisu/ao_hash_digest.rb" +# <<sisu_document_header>> +module SiSU_AO_Hash +  require_relative 'shared_markup_alt.rb'               #shared_markup_alt.rb +  class ObjectDigest +    def initialize(md,data,env=nil) +      @md,@data,@env=md,data,env +      @env ||=SiSU_Env::InfoEnv.new(@md.fns,@md) +    end +    def object_digest +    # 1. clean/stripped text without any markup, paragraph, headings etc. without endnotes +    # 2. endnotes clean/stripped text digest only (there may be several endnotes within a paragraph) +    # 3. whole object, text with markup and any endnotes, (question: with or without the endnote digests??? presumption better without, [however may be easier to check with?]) +    # [digests should not include other digests] +      data=@data.compact +      @tuned_file=[] +      sha_ =@env.digest(@md.opt).type +      begin +        sha_ ? (require 'digest/sha2') : (require 'digest/md5') +      rescue LoadError +        SiSU_Utils::CodeMarker.new(__LINE__,__FILE__,:fuchsia).error(sha_ + ' NOT FOUND') +      end +      data.each do |t_o| +        unless t_o.obj.is_a?(Array) +          t_o.obj=t_o.obj.strip +        end +        if (t_o.of !=:structure \ +        && t_o.of  !=:comment \ +        && t_o.of  !=:layout) \ +        && t_o.ocn.is_a?(Fixnum) +          case sha_ +          when :sha512 +            for hash_class in [ Digest::SHA512 ] +              @tuned_file << stamped(t_o,hash_class) +            end +          when :sha256 +            for hash_class in [ Digest::SHA256 ] +              @tuned_file << stamped(t_o,hash_class) +            end +          when :md5 +            for hash_class in [ Digest::MD5 ] +              @tuned_file << stamped(t_o,hash_class) +            end +          end +        else @tuned_file << t_o unless t_o.nil? +        end +      end +      @tuned_file=@tuned_file.flatten +      #use md5 or to create hash of each ao object including ocn, & add into to each ao object +    end +    def endnote_digest(data) +      data.each.map do |en_plus| +        case en_plus +        when /#{Mx[:en_a_o]}|#{Mx[:en_b_o]}/ +          if en_plus =~/#{Mx[:en_a_o]}.+?#{Mx[:en_a_c]}|#{Mx[:en_b_o]}.+?#{Mx[:en_b_c]}/ +            t_o_txt,en_open,en_txt,en_close= +              /(.*?)(#{Mx[:en_a_o]}|#{Mx[:en_b_o]})(.+?)(#{Mx[:en_a_c]}|#{Mx[:en_b_c]})/m. +              match(en_plus)[1..4] +            stripped_en=SiSU_TextRepresentation::Alter.new(en_txt).strip_clean_of_markup +            digest_en_strip=case @env.digest(@md.opt).type +            when :sha512 +              Digest::SHA512.hexdigest(stripped_en) +            when :sha256 +              Digest::SHA256.hexdigest(stripped_en) +            when :md5 +              Digest::MD5.hexdigest(stripped_en) +            else +              Digest::SHA256.hexdigest(stripped_en) +            end +            t_o_txt + +              en_open + +              en_txt + +              Mx[:id_o] + +              digest_en_strip + +              Mx[:id_c] + +              en_close +          else STDERR.puts "Error Exception - problem encountered with:\n#{en_plus}" #arbitrary exception, tidy up +          end +        else en_plus +        end +      end.join +    end +    def stamped(t_o,hash_class) #decide what hash information is most useful, is compromise necessary? +      t_o.obj=SiSU_TextRepresentation::Alter.new(t_o).strip_clean_of_extra_spaces +      #SiSU_TextRepresentation::Alter.new(t_o).strip_clean_of_markup                      #check +      #SiSU_TextRepresentation::Alter.new(t_o).semi_revert_markup                         #check +      #SiSU_TextRepresentation::ModifiedTextPlusHashDigest.new(@md,t_o).composite.dgst    #check +      unless t_o.is==:code +        case t_o.obj +        when /#{Mx[:en_a_o]}[\d*+]+\s+.+?#{Mx[:en_a_c]}|#{Mx[:en_b_o]}[*+]\d+\s+.+?#{Mx[:en_b_c]}/m +          en_and_t_o_digest=[] +          t_o.obj=t_o.obj. +            gsub(/\s*(#{Mx[:en_a_c]}|#{Mx[:en_b_c]})/m,' \1') #watch +          t_o_plus_en=t_o.obj. +            scan(/.*?#{Mx[:en_a_o]}.+?#{Mx[:en_a_c]}|.*?#{Mx[:en_b_o]}.+?#{Mx[:en_b_c]}/m) +          t_o_tail=if t_o.obj =~/(?:.*?#{Mx[:en_a_o]}.+?#{Mx[:en_a_c]}|.*?#{Mx[:en_b_o]}.+?#{Mx[:en_b_c]})+([\s\S]+)/m +            /(?:.*?#{Mx[:en_a_o]}.+?#{Mx[:en_a_c]}|.*?#{Mx[:en_b_o]}.+?#{Mx[:en_b_c]})+.*/m.match(t_o.obj)[1] +          else '' +          end +          t_o_plus_en << t_o_tail +          en_and_t_o_digest << endnote_digest(t_o_plus_en) +          en_and_t_o_digest.join(' ') +        else #@tuned << t_o + Mx[:id_o] + digest_strip + ':' + digest_all + Mx[:id_c] unless t_o.nil? +        end +      else #@tuned << t_o + Mx[:id_o] + digest_strip + ':' + digest_all + Mx[:id_c] unless t_o.nil? +      end +      t_o #KEEP intact +    end +    def strip_clean_extra_spaces(s)                                            # ao output tuned +      s=s.dup +      s=s.gsub(/[ ]+([,.;:?](?:$|\s))/,'\1') unless s =~/#{Mx[:en_a_o]}|#{Mx[:en_b_o]}/ +      s=s.gsub(/ [ ]+/,' '). +        gsub(/^ [ ]+/,''). +        gsub(/ [ ]+$/,''). +        gsub(/((?:#{Mx[:fa_bold_c]}|#{Mx[:fa_italics_c]})')[ ]+(s )/,'\1\2'). +        gsub(/((?:#{Mx[:fa_bold_c]}|#{Mx[:fa_italics_c]})')[ ]+(s )/,'\1\2') +    end +  end +end +__END__ +#+END_SRC + +** ao_idx.rb + +#+BEGIN_SRC ruby  :tangle "../lib/sisu/ao_idx.rb" +# <<sisu_document_header>> +module SiSU_AO_BookIndex +  class BookIndex +    def initialize(md,data,env=nil) +      @md,@data,@env=md,data,env +      @rgx_idx=/#{Mx[:idx_o]}(?:.+?)#{Mx[:idx_c]}\s*/ +      @rgx_idx_ocn_seg=/(.+?)~(\d+)~(\S+)/ +      @rgx_idx_ocn=/(.+?)~(\d+)/ +      @env ||=SiSU_Env::InfoEnv.new(@md.fns) +    end +    def indexing_song +      data=@data +      data, +        sisu_markup_idx_rel, +        sisu_markup_idx_rel_html_seg, +        html_idx,xhtml_idx= +          extract_book_index(data) +      data= +        clean_and_insert_index( +          data, +          sisu_markup_idx_rel_html_seg +        ) +      [ +        data, +        sisu_markup_idx_rel, +        sisu_markup_idx_rel_html_seg, +        html_idx, +        xhtml_idx, +      ] +    end +    def extract_book_index(data) +      tuned_file=[] +      idx_array=[] +      data.each do |dob| +        if (dob.is ==:heading \ +        || dob.is ==:heading_insert) \ +        && dob.ln==4 +          @seg=dob.name +        end +        if defined? dob.idx \ +        and dob.idx.is_a?(Hash) +          idx_array << { +            idx: dob.idx, +            ocn: dob.ocn, +            seg: @seg +          } +        end +        tuned_file << dob if dob +      end +      if idx_array.length > 0 +        the_idx=construct_book_index(idx_array) +        if @md.book_idx +          idx=index(the_idx) +          sisu_markup_idx_rel,sisu_markup_idx_rel_html_seg,html_idx,  xhtml_idx= +            idx[:sst_rel],    idx[:sst_rel_html_seg],      idx[:html],idx[:xhtml] +        else +          sisu_markup_idx_rel= +            sisu_markup_idx_rel_html_seg= +            html_idx= +            xhtml_idx= +            nil +        end +      end +      [ +        tuned_file, +        sisu_markup_idx_rel, +        sisu_markup_idx_rel_html_seg, +        html_idx, +        xhtml_idx, +      ] +    end +    def construct_book_index(idx_array) +      the_idx={} +      idx_array.each do |idx| +        idx[:idx].each_pair do |term,term_info| +          location=(term_info[:plus].to_i > 0) \ +          ? (%{#{idx[:ocn]}-#{idx[:ocn].to_i + term_info[:plus].to_i}}) +          : idx[:ocn].to_s +          the_idx[term]={} \ +            unless the_idx[term] \ +            and defined? the_idx[term] +          the_idx[term]['node_0_terms']=[] \ +            unless the_idx[term]['node_0_terms'] \ +            and defined? the_idx[term]['node_0_terms'] +          the_idx[term]['node_0_terms'] << { ocn: idx[:ocn], range: location, seg: idx[:seg] } +          if term_info[:sub].is_a?(Array) \ +          and term_info[:sub].length > 0 +            term_info[:sub].each do |y| +              y.each_pair do |subterm,subterm_info| +                location=(subterm_info[:plus].to_i > 0) \ +                ? (%{#{idx[:ocn]}-#{idx[:ocn].to_i + subterm_info[:plus].to_i}}) +                : idx[:ocn].to_s +                the_idx[term]={} \ +                  unless the_idx[term] \ +                  and defined? the_idx[term] +                the_idx[term]['node_0_terms']=[] \ +                  unless the_idx[term]['node_0_terms']\ +                  and    defined? the_idx[term]['node_0_terms'] +                the_idx[term]['node_1_subterms']={} \ +                  unless the_idx[term]['node_1_subterms'] \ +                  and defined? the_idx[term]['node_1_subterms'] +                the_idx[term]['node_1_subterms'][subterm]=[] \ +                  unless the_idx[term]['node_1_subterms'][subterm] \ +                  and defined? the_idx[term]['node_1_subterms'][subterm] +                the_idx[term]['node_1_subterms'][subterm] << +                  { ocn: idx[:ocn], range: location, seg: idx[:seg] } +              end +            end +          end +        end +      end +      the_idx=the_idx.sort +      the_idx +    end +    def clean_xml(str) +      str=str.gsub(/&/,'&') +      str +    end +    def index(the_idx) +      @x=1 +      idx={} +      idx[:sst_rel_html_seg],idx[:sst_rel],idx[:html],idx[:xhtml]= +        [],                  [],           [],        [] +      h={ +        obj: Mx[:br_page] +      } +      o=SiSU_AO_DocumentStructure::ObjectLayout.new.break(h) +      idx[:sst_rel_html_seg] << o +      idx[:sst_rel] << o +      h={ +        lv: '1', +        name: 'index', +        obj: "Index" +      } +      o=SiSU_AO_DocumentStructure::ObjectHeading.new.heading(h) +      idx[:sst_rel_html_seg] << o +      idx[:sst_rel] << o +      h={ +        lv: '4', +        name: 'idx', +        obj: " [Index] #{Mx[:pa_non_object_dummy_heading]}" +      } +      o=SiSU_AO_DocumentStructure::ObjectHeading.new.heading(h) +      idx[:sst_rel_html_seg] << o +      idx[:sst_rel] << o +      alph=%W[9 A B C D E F G H I J K L M N O P Q R S T U V W X Y Z] +      idx[:html] << '<p>' +      idx[:xhtml] << '<p>' +      alph.each do |x| +        if x =~/[0-9]/ +          idx[:html] << '' +          idx[:xhtml] << '' +        else +          idx[:html] << +            %{<a href="##{x}">#{x}</a>,#{$ep[:hsp]}} +          idx[:xhtml] << +            %{<a href="##{x.downcase}">#{x}</a>,#{$ep[:hsp]}} +        end +      end +      idx[:html] << '</p>' +      idx[:xhtml] << '</p>' +      letter=alph.shift +      idx[:html] << +        %{\n<p class="book_index_lev1"><a name="numeral"></a></p>} +      idx[:xhtml] << +        %{\n<p class="letter" id="numeral">0 - 9</p>} +      the_idx.each do |i| +        i.each do |x| +          if x.is_a?(String) +            f=/^(\S)/.match(x)[1] +            if letter < f +              while letter < f +                if alph.length > 0 +                  letter=alph.shift +                  idx[:html] << +                    %{\n<p class="letter"><a name="#{letter}">#{letter}</a></p><p class="book_index_lev1"><a name="#{letter.downcase}"> </a></p>} +                  idx[:xhtml] << +                    %{\n<p class="letter" id="#{letter.downcase}">#{letter}</p>} +                else break +                end +              end +            end +            idx[:sst_rel_html_seg] << +              %{\n\n#{Mx[:fa_bold_o]}#{x},#{Mx[:fa_bold_c]} } +            idx[:sst_rel] << +              %{\n\n#{Mx[:fa_bold_o]}#{x},#{Mx[:fa_bold_c]} } +            aname=x.gsub(/\s+/,'_') +            idx[:html] << +              %{\n<p class="book_index_lev1"><a name="#{aname}"><b>#{x}</b></a>, } +            c=clean_xml(x.dup) +            idx[:xhtml] << +              %{\n<p class="book_index_lev1"><b>#{c}</b>, } +            @o=idx[:sst_rel_html_seg].index(idx[:sst_rel_html_seg].last) +            @t=idx[:sst_rel].index(idx[:sst_rel].last) +            @q=idx[:html].index(idx[:html].last) +            @r=idx[:xhtml].index(idx[:xhtml].last) +            print "\n" + x + ', ' if @md.opt.act[:verbose_plus][:set]==:on +          elsif x.is_a?(Array) +            p 'array error? -->' +            print x +          elsif x.is_a?(Hash) +            if x['node_0_terms'].is_a?(Array) +              x['node_0_terms'].each do |a| +                if a[:range] +                  idx[:sst_rel_html_seg][@o]= +                    idx[:sst_rel_html_seg][@o] + +                    %{#{Mx[:lnk_o]}#{a[:range]}#{Mx[:lnk_c]}#{Mx[:rel_o]}/#{a[:seg]}.html##{a[:ocn]}#{Mx[:rel_c]}, } +                  idx[:sst_rel][@t]= +                    idx[:sst_rel][@t] + +                    %{#{Mx[:lnk_o]}#{a[:range]}#{Mx[:lnk_c]}#{Mx[:rel_o]}#{a[:ocn]}#{Mx[:rel_c]}, } +                  idx[:html][@q]= +                    idx[:html][@q] + +                    %{<a href="#{a[:seg]}.html##{a[:ocn]}">#{a[:range]}</a>, } +                  idx[:xhtml][@q]= +                    idx[:xhtml][@q] + +                    %{<a href="#{a[:seg]}.xhtml#o#{a[:ocn]}">#{a[:range]}</a>, } +                  print a[:range] + ', ' if @md.opt.act[:verbose_plus][:set]==:on +                elsif a[:ocn] +                  idx[:sst_rel_html_seg][@o]= +                    idx[:sst_rel_html_seg][@o] + +                    %{#{Mx[:lnk_o]}#{a[:ocn]}#{Mx[:lnk_c]}#{Mx[:rel_o]}#{a[:seg]}.html##{a[:ocn]}#{Mx[:rel_c]}, } +                  idx[:sst_rel][@t]= +                    idx[:sst_rel][@t] + +                    %{#{Mx[:lnk_o]}#{a[:ocn]}#{Mx[:lnk_c]}#{Mx[:rel_o]}#{a[:ocn]}#{Mx[:rel_c]}, } +                  idx[:html][@q]= +                    idx[:html][@q] + +                    %{<a href="#{a[:seg]}.html##{a[:ocn]}">#{a[:ocn]}</a>, } +                  idx[:xhtml][@q]= +                    idx[:xhtml][@q] + +                    %{<a href="#{a[:seg]}.xhtml#o#{a[:ocn]}">#{a[:ocn]}</a>, } +                  print a[:ocn] + ', ' if @md.opt.act[:verbose_plus][:set]==:on +                else p 'error' +                end +              end +              idx[:html][@q]=idx[:html][@q] + '</p>' +              idx[:xhtml][@r]=idx[:xhtml][@r] + '</p>' +            end +            if x['node_1_subterms'] +             x['node_1_subterms'].sort.each do |k,y| +                if k !~/node_0_terms/ +                  idx[:sst_rel_html_seg][@o]= +                    idx[:sst_rel_html_seg][@o] + +                    %{#{k}, } +                  idx[:sst_rel][@t]= +                    idx[:sst_rel][@t] + +                    %{#{k}, } +                  idx[:html][@q]= +                    idx[:html][@q] + +                    %{\n<p class="book_index_lev2">#{k}, } +                  c=clean_xml(k.dup) +                  idx[:xhtml][@r]= +                    idx[:xhtml][@r] + +                    %{\n<p class="book_index_lev2">#{c}, } +                  print "\n\t" + k + ', ' if @md.opt.act[:verbose_plus][:set]==:on +                  y.each do |z| +                    if z[:range] +                      idx[:sst_rel_html_seg][@o]= +                        idx[:sst_rel_html_seg][@o] + +                        %{#{Mx[:lnk_o]}#{z[:range]}#{Mx[:lnk_c]}#{Mx[:rel_o]}#{z[:seg]}.html##{z[:ocn]}#{Mx[:rel_c]}, } +                      idx[:sst_rel][@t]= +                        idx[:sst_rel][@t] + +                        %{#{Mx[:lnk_o]}#{z[:range]}#{Mx[:lnk_c]}#{Mx[:rel_o]}#{z[:ocn]}#{Mx[:rel_c]}, } +                      idx[:html][@q]= +                        idx[:html][@q] + +                        %{<a href="#{z[:seg]}.html##{z[:ocn]}">#{z[:range]}</a>, } +                      idx[:xhtml][@q]= +                        idx[:xhtml][@q] + +                        %{<a href="#{z[:seg]}.xhtml#o#{z[:ocn]}">#{z[:range]}</a>, } +                      print z[:range] + ', ' if @md.opt.act[:verbose_plus][:set]==:on +                    elsif z[:ocn] +                      idx[:sst_rel_html_seg][@o]= +                        idx[:sst_rel_html_seg][@o] + +                        %{#{Mx[:lnk_o]}#{z[:ocn]}#{Mx[:lnk_c]}#{Mx[:rel_o]}#{z[:seg]}.html##{z[:ocn]}#{Mx[:rel_c]}, } +                      idx[:sst_rel][@t]= +                        idx[:sst_rel][@t] + +                        %{#{Mx[:lnk_o]}#{z[:ocn]}#{Mx[:lnk_c]}#{Mx[:rel_o]}#{z[:ocn]}#{Mx[:rel_c]}, } +                      idx[:html][@q]= +                        idx[:html][@q] + +                        %{<a href="#{z[:seg]}.html##{z[:ocn]}">#{z[:ocn]}</a>, } +                      idx[:xhtml][@q]= +                        idx[:xhtml][@q] + +                        %{<a href="#{z[:seg]}.xhtml#o#{z[:ocn]}">#{z[:ocn]}</a>, } +                      print z[:ocn] + ', ' if @md.opt.act[:verbose_plus][:set]==:on +                    else p 'error' +                    end +                  end +                  idx[:html][@q]=idx[:html][@q] + '</p>' +                  idx[:xhtml][@r]=idx[:xhtml][@r] + '</p>' +                end +              end +            end +            @x +=1 +          end +        end +      end +      print "\n" if @md.opt.act[:verbose_plus][:set]==:on +      idx +    end +    def screen_print(the_idx) +      the_idx.each do |i| +        i.each do |x| +          if x.is_a?(String) +            print "\n" + x + ', ' +          elsif x.is_a?(Array) +            p 'array error? -->' +            print x +          elsif x.is_a?(Hash) +            if x['node_0_terms'].is_a?(Array) +              x['node_0_terms'].each do |a| +                if a[:range] +                  print a[:range] + ', ' +                elsif a[:ocn] +                  print a[:ocn] + ', ' +                else p 'error' +                end +              end +            end +            if x['node_1_subterms'] +              x['node_1_subterms'].sort.each do |k,y| +                if k !~/node_0_terms/ +                  print "\n\t" + k + ', ' +                  y.each do |z| +                    if z[:range] +                      print z[:range] + ', ' +                    elsif z[:ocn] +                      print z[:ocn] + ', ' +                    else p 'error' +                    end +                  end +                end +              end +            end +          end +        end +      end +    end +    def output_idx(idx) +      if @md.book_idx +        path="#{@env.path.output}/#{@md.fnb}" +        Dir.mkdir(path) unless FileTest.directory?(path) +        puts "#{path}/#{@md.fn[:book_idx_html]} #{__FILE__}::#{__LINE__}" +        html_index_file=File.new("#{path}/#{@md.fn[:book_idx_html]}",'w') +        idx[:html].each {|x| html_index_file << x } +        html_index_file.close +      end +    end +    def clean_and_insert_index(data,sisu_markup_idx) +      tuned_file=[] +      data.each do |dob| +        tuned_file << dob +        if dob.obj =~/#{Mx[:br_endnotes]}/ \ +        and sisu_markup_idx +          sisu_markup_idx.each do |idx| +            tuned_file << idx +          end +        end +      end +      tuned_file +    end +    def clean_index(data)                                  #check on use of dob +      data.each.map do |para| +        para.gsub(/\n*#{@rgx_idx}/m,'') +      end +    end +  end +end +__END__ +#+END_SRC + +** ao_images.rb + +#+BEGIN_SRC ruby  :tangle "../lib/sisu/ao_images.rb" +# <<sisu_document_header>> +module SiSU_AO_Images +  class Images +    begin +      require 'rmagick' +      include Magick +    rescue LoadError +      #SiSU_Utils::CodeMarker.new(__LINE__,__FILE__,:fuchsia).mark('rmagic NOT FOUND') +    end +    def initialize(md,data) +      @md,@data=md,data +    end +    def images +      data=@data +      @rmgk=false +      imagemagick_=true      #imagemagick_=SiSU_Env::InfoSettings.new.program?('rmagick') +      if imagemagick_ +        begin +          @rmgk=SiSU_Env::Load.new('rmagick').prog +        rescue +          @rmgk=false +        end +      else +        if (@md.opt.act[:verbose_plus][:set]==:on \ +        || @md.opt.act[:maintenance][:set]==:on) +          SiSU_Screen::Ansi.new( +            @md.opt.act[:color_state][:set], +            '*WARN* use of rmagick is not enabled in sisurc.yml' +          ).warn +        end +      end +      data.select do |dob| +        unless dob.is ==:table +          dob.obj=dob.obj.strip +          if dob.obj =~/#{Mx[:lnk_o]}\s*\S+\.(?:png|jpg|gif)(?:\s*|\s+.+)?#{Mx[:lnk_c]}(?:#{Mx[:url_o]}\S+?#{Mx[:url_c]}|image)/ +            if dob.obj !~/#{Mx[:lnk_o]}\s*\S+\.(?:png|jpg|gif)\s+\d+x\d+/ +              m=/#{Mx[:lnk_o]}\s*(\S+\.(?:png|jpg|gif))/ +              if imagemagick_ +                imgs=dob.obj.scan(m).flatten +                img_col=img_row=nil +                images=imgs.each do |image| +                  dir=SiSU_Env::InfoEnv.new(@md.fns) +                  path_image=[ +                    dir.path.image_source_include_local, +                    dir.path.image_source_include_remote, +                    dir.path.image_source_include +                  ] +                  image_path=nil +                  path_image.each do |img_pth| +                    image_path=img_pth +                    break if FileTest.exist?("#{img_pth}/#{image}") +                  end +                  if FileTest.exist?("#{image_path}/#{image}") +                    if @rmgk +                      img=Magick::ImageList.new("#{image_path}/#{image}") +                      img_col,img_row=img.columns,img.rows +                    else +                      if (@md.opt.act[:verbose_plus][:set]==:on \ +                      || @md.opt.act[:maintenance][:set]==:on) +                        SiSU_Screen::Ansi.new( +                          @md.opt.act[:color_state][:set], +                          '*WARN* rmagick not present, will attempt to use imagemagick (identify) directly' +                        ).warn +                      end +                      imgk=SiSU_Env::SystemCall.new.imagemagick +                      gmgk=SiSU_Env::SystemCall.new.graphicsmagick +                      if imgk or gmgk +                        if imgk +                          imgsys=`identify #{image_path}/#{image}`.strip                           #system call +                        elsif gmgk +                          imgsys=`gm identify #{image_path}/#{image}`.strip                        #system call +                        end +                        img_col,img_row=/(\d+)x(\d+)/m.match(imgsys)[1,2] +                        img_col,img_row=img_col.to_i,img_row.to_i +                      else +                        errmsg='imagemagick or graphicsmagick are required to process images' +                        if @md.opt.act[:no_stop][:set]==:on +                          SiSU_Utils::CodeMarker.new(__LINE__,__FILE__,:fuchsia). +                            error("#{errmsg}, proceeding (as requested) without image processing") +                          break +                        else +                          SiSU_Utils::CodeMarker.new(__LINE__,__FILE__,:fuchsia). +                            error("#{errmsg}, STOPPING") +                          exit +                        end +                      end +                    end +                    row=((img && defined? img.rows) ? img.rows : img_row) +                    col=((img && defined? img.columns) ? img.columns : img_col) +                    if img_col > img_row                                                           #landscape +                      if img_col> 640 +                        img_col=640 +                        img_row=((1.00*img_col/col)*row).round +                      end +                    else                                                                           #portrait +                      if img_col> 640 +                        img_col=640 +                        img_row=((1.00*img_col/col)*row).round +                      end +                      if img_row > 640 +                        img_row=640 +                        img_col=((1.00*img_row/row)*col).round +                      end +                    end +                    dob.obj=dob.obj.gsub(/(#{image})/,"#{image} #{img_col}x#{img_row}") +                  else +                    dob.obj=dob.obj. +                      gsub(/#{Mx[:lnk_o]}\s*(\S+)\.(png|jpg|gif).+?#{Mx[:lnk_c]}(#{Mx[:url_o]}\S+?#{Mx[:url_c]}|image)/, +                        '[ \1 (\2 missing) ]') +                  end +                end +              else +                images=dob.obj.scan(m) do |image| +                  SiSU_Screen::Ansi.new( +                    @md.opt.act[:color_state][:set], +                    '*WARN* where image dimensions have not been provided rmagick or imagemagick is required',image +                  ).warn unless @md.opt.act[:quiet][:set]==:on +                end +              end +            end +          end +          if dob.obj =~/#{Mx[:lnk_o]}\s*\S+\.(?:png|jpg|gif).+?#{Mx[:lnk_c]}(?:#{Mx[:url_o]}\S+?#{Mx[:url_c]}|image)/ +            dob.obj=dob.obj.gsub(/(#{Mx[:lnk_o]})\s*(\S+\.(?:png|jpg|gif))\s+/i,'\1\2 ') +          end +        end +        dob unless dob.nil? +      end +    end +  end +end +__END__ +imgsys=`identify #{image_path}/#{image}`.strip +#+END_SRC + +** ao_metadata.rb + +#+BEGIN_SRC ruby  :tangle "../lib/sisu/ao_metadata.rb" +# <<sisu_document_header>> +module SiSU_AO_Metadata +  class Metadata +    def initialize(md,metad) +      @md,@metadata=md,metad +      l=SiSU_Env::StandardiseLanguage.new(@md.opt.lng).language +      language=l[:n] +      @tr=SiSU_Translate::Source.new(md,language) +    end +    def make_para(obj,ocn) +      h={ +        obj: obj, +        ocn: 0 +      } +      SiSU_AO_DocumentStructure::ObjectPara.new.paragraph(h) +    end +    def make_heading(obj,ocn,name,lv,ln) +      h={ +        lv: lv, +        ln: ln, +        name: name, +        obj: obj, +        ocn: 0 +      } +      SiSU_AO_DocumentStructure::ObjectHeading.new.heading(h) +    end +    def metadata +    end +  end +end +__END__ +#+END_SRC + +** ao_misc_arrange.rb + +#+BEGIN_SRC ruby  :tangle "../lib/sisu/ao_misc_arrange.rb" +# <<sisu_document_header>> +module SiSU_AO_MiscArrangeText +  class SI +    def initialize(md,data) +      @md,@data=md,data +    end +    def conditional_headings(para) +      para=para.gsub(/^(:?A~)\s*$/,'\1~ @title @author').            #conditional header +        gsub(/^((?:[1-9]|:?[A-D])~\S*)\s*$/, +          '\1~ [Note: heading marker::required title missing]~#')    #conditional header for incorporated document 2004w12 +      if para =~/^@\S+?:/ +        para=para.gsub(/^@(\S+?):(\s+|$)/, +            "#{Mx[:meta_o]}\\1#{Mx[:meta_c]}\\2"). +          gsub(/^@(\S+?):([+-])(\s+|$)/, +            "#{Mx[:meta_o]}\\1\\2#{Mx[:meta_c]}\\3") +      end +      para +    end +    def markup_blocks(para) +      def ticks(para) +        block_open,block_close,text=nil,nil,nil +        if para =~/\A```[ ]+(?:code(?:\.[a-z][0-9a-z_]+)?|box(?:\.[a-z_]+)?|poem|alt|group|block|table).*?\n.+?\n```(?:\s+[~-][#]|\s+\~\{.+?\}\~)?\s*\Z/m +          @flag=:close +          block_open,text,block_close= +            /\A(```[ ]+(?:code(?:\.[a-z][0-9a-z_]+)?|box(?:\.[a-z_]+)?|poem|alt|group|block|table).*?)\n(.+?)\n(```([ ]+[~-][#]|\s+\~\{.+?\}\~)?)\s*\Z/m. +            match(para)[1..3] +          ((para=~/^```[ ]+table(?:~h)?\s+/) \ +          and (para !~/^```[ ]+table(?:~h)?\s+c\d+/)) \ +          ? para +          : (para=[]; para << block_open << text << block_close) +        elsif para =~/\A```[ ]+(?:code(?:\.[a-z][0-9a-z_]+)?|box(?:\.[a-z_]+)?|poem|alt|group|block|table).*?\n.*?\Z/m #look at, study +          @flag=:open +          block_open,text=/\A(```(?:[ ]+.+?))\n(.*?)\Z/m.match(para)[1,2] +          para=[] +          if not text.to_s.empty? +            para << block_open << text +          else +            para << block_open +          end +        elsif para =~/\A.+?\n```(?:\s+\~\{.+?\}\~)?(?:\s+[~-][#])?(\s*=\{.+?\})?\s*\Z/m \ +        and @flag==:open +          @flag=:close +          text,block_close= +            /\A(.+?)\n(```(?:\s+\~\{.+?\}\~)?(?:\s+[~-][#])?(?:\s+=\{.+?\})?)\s*\Z/m.match(para)[1,2] +          para=[] +          if not text.to_s.empty? +            para << text.to_s << block_close +          else +            para << block_close +          end +        else para +        end +        para +      end +      def ticks_remove(para) +        unless @md.opt.act[:quiet][:set] ==:on +          SiSU_Utils::CodeMarker.new(__LINE__,__FILE__,:fuchsia). +           mark("ticks not recognized, ticks removed from pargraph\n#{para}") +        end +        para=para.gsub(/```[ ]+\S+[ ]*/m,''). +          gsub(/```\s*/m,''). +          strip +      end +      def ticks_quote(para) +        @flag=:quote_open +        text=para +        para=[] +        if text =~ /```[ ]+quote/m +          para << '`:quote_open`' +          text=text.gsub(/```[ ]+quote/m,'') +        end +        text=if text =~/(?:\n|\A)=\{.+?\}/m                               #exclude book index from indent markup +          txt,bkidx,tail=/(.+?)((?:\n|\A)=\{.+?\}$)(.*)/m.match(text).captures +          txt=txt.gsub(/(?:\n|\A)([^`\n]+)/m,'_1 \1') +          txt + bkidx + tail +        else text.gsub(/(?:\n|\A)([^`\n]+)/m,'_1 \1') +        end +        para << text.gsub(/```/m,'') +        if text =~/```/m +          @flag=:quote_close +          para << '`:quote_close`' +        end +        para +      end +      def curly_braces(para) +        block_open,block_close,text=nil,nil,nil +        para=if para =~/\A(?:code(?:\.[a-z][0-9a-z_]+)?|box(?:\.[a-z_]+)?|poem|alt|group|block|table)\{ .+?\n.+?\n\}(?:code|box|poem|alt|group|block|table)(?: [~-][#])?\s*\Z/m +          block_open,text,block_close= +            /\A((?:code(?:\.[a-z][0-9a-z_]+)?|box(?:\.[a-z_]+)?|poem|alt|group|block|table)\{ .+?)\n(.+?)\n(\}(?:code|box|poem|alt|group|block|table)(?: [~-][#])?)\s*\Z/m. +            match(para)[1..3] +          para=[] +          para << block_open << text << block_close +        elsif para =~/\A(?:code(?:\.[a-z][0-9a-z_]+)?|box(?:\.[a-z_]+)?|poem|alt|group|block|table)\{ .+?\n.+?\Z/m +          block_open,text= +            /\A((?:code(?:\.[a-z][0-9a-z_]+)?|box(?:\.[a-z_]+)?|poem|alt|group|block|table)\{ .+?)\n(.+?)\Z/m. +            match(para)[1,2] +          para=[] +          if not text.to_s.empty? +            para << block_open << text +          else +            para << block_open +          end +        elsif para =~/\A.+?\n\}(?:code|box|poem|alt|group|block|table)(?: [~-][#])?\s*\Z/m +          text,block_close= +            /\A(.+?)\n(\}(?:code|box|poem|alt|group|block|table)(?: [~-][#])?)\s*\Z/m. +            match(para)[1,2] +          para=[] +          if not text.to_s.empty? +            para << text.to_s << block_close +          else +            para << block_close +          end +        else para +        end +        para +      end +      para=if (para =~/\A```[ ]+quote/m \ +      and @flag !=:open) \ +      or @flag==:quote_open +        ticks_quote(para) +      elsif para =~/\A```[ ]+(?:code(?:\.[a-z][0-9a-z_]+)?|box(?:\.[a-z_]+)?|poem|alt|group|block|table).*?\n.*?\Z/m \ +      or @flag==:open +        ticks(para) +      elsif para =~/```/m +        ticks_remove(para) +      else +        para +      end +      para=if para =~/^(?:code(?:\.[a-z][0-9a-z_]+)?|box(?:\.[a-z_]+)?|poem|alt|group|block|table)\{|^\}(?:code|box|poem|alt|group|block|table)/m +        curly_braces(para) +      else +        para +      end +    end +    def prepare_text +      data=@data +      if data[0] =~ /^#!\s*(?:\/usr\/bin\/env sisu|\/usr\/bin\/sisu)/ # remove bang from top #! (however file is stripped, so will be removed provided no content precedes it) +        data[0]=data[0].gsub(/^#!\s*\/usr\/bin\/sisu/,''). +          gsub(/^#!\s*\/usr\/bin\/env sisu/,'') +      end +      if data[0] =~ /^(SiSU\s+[\d.]*|sisu-[\d.]+)$/ # SiSU identifier +        data[0]=data[0].gsub(/^(SiSU\s*[\d.]*)$/,'% \1'). +          gsub(/^(sisu-[\d.]+)$/,'% \1') +      end +      data.each.map do |para| +        para=conditional_headings(para) +        markup_blocks(para) +      end.flatten +    end +  end +end +__END__ +#+END_SRC + +** ao_numbering.rb + +#+BEGIN_SRC ruby  :tangle "../lib/sisu/ao_numbering.rb" +# <<sisu_document_header>> +module SiSU_AO_Numbering +  class Numbering +    attr_accessor :obj,:osp,:ocn,:lv,:name,:index,:comment +    @@segments_count=0 +    def initialize(md,data,fnx,process) +      @md,@data,@fnx,@process=md,data,fnx,process +      @obj=@type=@ocn=@lv=@name=@index=@comment=nil +      @chosen_seg_names=[] +    end +    def chosen_seg_names(chosen,chosen_seg_name,dob,md,type) +      @chosen_seg_names=if chosen.compact.uniq.length \ +      == chosen.compact.length +        chosen +      else +        if md.opt.act[:maintenance][:set]==:on +          SiSU_Utils::CodeMarker.new(__LINE__,__FILE__,:green). +            mark( +              "duplicated auto segment name: #{type} #{chosen}\n" \ +              + "#{chosen}\n" \ +              + " manually name level 1 segments '1~given_name'\n" \ +              + 'filename: ' + md.fns + "\n" \ +              + 'heading text: "' + dob.obj + '"' + "\n" \ +              + 'duplication: "' + chosen_seg_name + '" (level: ' + dob.lv + '; numbering type: ' + type.to_s + ')' +            ) +        end +        chosen=chosen[0..-2] +        chosen_seg_name=auto_numbering_exceptions(chosen,md,dob) +        chosen << chosen_seg_name +      end +    end +    def number_of_segments? +      if @@segments_count==0 +        @data.each do |dob| +          if dob.is ==  :heading \ +          and dob.lv == '1' +            @@segments_count += 1 +          end +        end +        @@segments_count +      else @@segments_count +      end +    end +    def numbering_song +      begin +        data=@data +        data=number_plaintext_para(data) +        data=auto_number_heading_ie_title(data.compact) #tr issue +        data=ocn(data.compact) #watch +        data=xml(data.compact) +        data=minor_numbering(data.compact) +        if @process==:complete +          data,tags_map,ocn_html_seg_map=name_para_seg_filename(data) +        end +        data=set_heading_top(data) unless @md.set_heading_top +        [data,tags_map,ocn_html_seg_map] +      ensure +        @@segments_count=0 +      end +    end +    def set_tags(tags,tag) +      tags=if not tag.empty? \ +      and tag !~/^\d+$/ +        tag=tag.gsub(/[^a-z0-9._-]/,'') +        [tag,tags].flatten +      else tags +      end +    end +    def number_plaintext_para(data) +      @tuned_file=[] +      data.each do |dob| +        if (dob.of !=:block \ +        && dob.of !=:comment \ +        && dob.of !=:layout) \ +        && dob.ocn_ #and dob.obj !~ /#{Mx[:gr_o]}Th|#{Mx[:tc_o]}#{Mx[:tc_p]}#{Mx[:tc_p]}/ #FIX +          dob.obj=dob.obj.gsub(/(.+)\n/,'\1 ') #messy, but idea is that tables should retain breaks +        end +        unless dob.obj.is_a?(Array) +          dob.obj=dob.obj.gsub(/^\s+/,''). +            gsub(/\s$/,"\n") +        end +        @tuned_file << dob +      end +      @tuned_file=@tuned_file.flatten +    end +    def number_sub_heading(dob,num,title_no) +      unless dob.obj =~/\d+\.|(?:chapter|article|section|clause)\s+\d+/i #name selection arbitrary, fix +        dob.obj=case dob.name +        when /-/          then dob.obj.gsub(/^/,"#{title_no} ") +        when /^#/         then dob.obj.gsub(/^/,"#{title_no} ") +        when /^[a-z_\.]+/ then dob.obj.gsub(/^/,"#{title_no} ") +        else +          dob.name=title_no if dob.name=~/^$/ #where title contains title number +          dob.obj.gsub(/^/,"#{title_no} ") if title_no =~/\d+/ #main, where title number is to be provided #watch changed placement +        end +        if @md.toc_lev_limit \ +        and @md.toc_lev_limit < num +          dob.obj=dob.obj.gsub(/^/,'!_ ') #bold line, watch +        end +      end +      dob +    end +    def heading_tag_clean(heading_tag) +      heading_tag=heading_tag. +        gsub(/[ ]+/,'_'). +        gsub(/["']/,''). +        gsub(/[\/]/,'-'). +        gsub(/#{Mx[:fa_bold_o]}|#{Mx[:fa_bold_c]}/,''). +        gsub(/#{Mx[:fa_italics_o]}|#{Mx[:fa_italics_c]}/,''). +        gsub(/#{Mx[:fa_underscore_o]}|#{Mx[:fa_underscore_c]}/,''). +        gsub(/#{Mx[:fa_cite_o]}|#{Mx[:fa_cite_c]}/,''). +        gsub(/#{Mx[:fa_insert_o]}|#{Mx[:fa_insert_c]}/,''). +        gsub(/#{Mx[:fa_strike_o]}|#{Mx[:fa_strike_c]}/,''). +        gsub(/#{Mx[:fa_superscript_o]}|#{Mx[:fa_superscript_c]}/,''). +        gsub(/#{Mx[:fa_subscript_o]}|#{Mx[:fa_subscript_c]}/,''). +        gsub(/#{Mx[:fa_hilite_o]}|#{Mx[:fa_hilite_c]}/,''). +        gsub(/#{Mx[:gl_bullet]}/,'') +    end +    def auto_number_heading_ie_title(data)                                             #also does some segment naming +      if defined? @md.make.num_top \ +      and @md.make.num_top \ +      and @md.make.num_top !~/^$/ +        input||=@md.make.num_top +      end +      num_top=(input ? input.to_i : nil) +      t_no1=t_no2=t_no3=0 +      if num_top +        no1=num_top; no2=(num_top + 1); no3=(num_top + 2) +      end +      chapter_number_counter=0 +      data=data.compact +      @tuned_file=data.each.map do |dob| #@md.seg_names << [additions to segment names] +        title_no=nil +        if dob.is ==:heading \ +        && dob.autonum_ \ +        and defined? @md.make.num_top \ +        and @md.make.num_top !~/^$/ +          if  dob.lv=='1' \ +          and dob.obj =~/^#\s|\s#(?:\s|$)/ +            chapter_number_counter +=1 +            dob.obj=dob.obj.gsub(/^#\s/,"#{chapter_number_counter} "). +              gsub(/#([:,]?\s|[.]?$)/,"#{chapter_number_counter}\\1") +          end +          if dob.ln==no1 +            @subnumber=1 +            @subnumber=0 if dob.ln==no1 +          end +          if dob.ln.to_s =~/^[0-6]/ \ +          and not dob.use_ ==:dummy \ +          and dob.obj !~/#{Mx[:fa_o]}(?:~#|-#)#{Mx[:fa_c]}/ # <-- fix +            if dob.ln==no1 +              t_no1+=1; t_no2=0; t_no3=0 +              title_no="#{t_no1}" +              if @md.seg_names.is_a?(Array) \ +              and not @md.seg_names.include?(title_no) +                if dob.ln==no1 +                  dob.name="#{title_no}" if not dob.name +                  dob.tags=set_tags(dob.tags,title_no) +                  tag=dob.obj. +                    gsub(/(Article|Clause|Section|Chapter)\s+/, +                      "\\1_#{title_no}"). +                    downcase +                  tag=heading_tag_clean(tag) +                  dob.tags=set_tags(dob.tags,tag) +                  dob.obj=(dob.obj =~/(Article|Clause|Section)\s+/) \ +                  ? (dob.obj.gsub(/(Article|Clause|Section)\s+/,"\\1 #{title_no} ")) +                  : (dob.obj.gsub(/^/,"#{title_no}. ")) #fix stop later +                end +                if dob.ln !=no1 \ +                and dob.obj =~/^[\d.]+\s/ #fix -> if the title starts with a numbering scheme, do not auto-number, review +                  dob.name ="#{title_no}" if not dob.name +                  dob.tags=set_tags(dob.tags,title_no) +                  dob.obj=dob.obj.gsub(/^/,"#{title_no}. ") +                end +                @md.seg_names << title_no +              end +              if dob.ln!=no1 \ +              and dob.name!~/^[a-z_\.]+$/ \ +              and dob.obj !~/[A-Z]\.?\s/ #bug -> tmp fix, excludes A. B. C. lettering, but not roman numerals, is arbitrary, review required # not fixed, work on +                dob.tags=set_tags(dob.tags,title_no) +                dob.obj=dob.obj.gsub(/^/i,"#{title_no}. ") +              end +            end +            if dob.ln==no1         #watch because here you change dob.name +              dob.tags=set_tags(dob.tags,"h#{title_no}") +            end +            if dob.ln==no2         #watch because here you change dob.name +              t_no2+=1; t_no3=0 +              title_no="#{t_no1}.#{t_no2}" +              dob.tags=set_tags(dob.tags,"h#{title_no}") +              dob=number_sub_heading(dob,no2,title_no) +            end +            if dob.ln==no3         #watch because here you change dob.name +              t_no3+=1 +              title_no="#{t_no1}.#{t_no2}.#{t_no3}" +              dob.tags=set_tags(dob.tags,"h#{title_no}") +              dob=number_sub_heading(dob,no3,title_no) +            end +          elsif dob.ln.to_s =~/^[0-6]/ \ +          and dob.name =~ /^[\w-]+-/ # endnotes, watch2005# endnotes, watch2005 +            dob.tags=set_tags(dob.tags,dob.name) +            dob.name.gsub(/^([a-z_\.]+)-$/,'\1') +          end +        elsif dob.is ==:heading \ +        and dob.autonum_ \ +        and @md.markup =~/num_extract/ #AS DANGEROUS force enable with document, note already does this type of numbering for cisg, locate and coordinate logic, is currently misplaced in code, chengwei inspired 2004w23/4 +          #here lies a bug, as is nil when run from -Dv --update, FIX +          if (dob.name.nil? or dob.name.empty?) \ +          and dob.ln.to_s =~/^[0-9]/ \ +          and dob.obj =~ /^([\d\.]+)/ #risky (must be unique) consider output to 4~~\d instead of 4~\d +            dob.name=$1 +            dob.tags=set_tags(dob.tags,dob.name) +          end +          if @md.toc_lev_limit +          end +        elsif defined? dob.name \ +        and  dob.name +          dob.tags=set_tags(dob.tags,dob.name) +        end +        dob.tags=dob.tags.uniq if defined? dob.tags +        dob +      end.flatten +    end +    def ocn(data)                                                                      #and auto segment numbering increment +      @tuned_file=SiSU_AO_DocumentStructureExtract::OCN.new(@md,data,@fnx,@process).ocn +      @tuned_file +    end +    def xml(data) +      @tuned_file=SiSU_AO_DocumentStructureExtract::XML.new(@md,data).dom +      @tuned_file +    end +    def minor_numbering(data)                                                          #and auto segment numbering increment +      number_small,letter_small=0,0 +      letter=%w( a b c d e f g h i j k l m n o p q r s t u v w x y z ) +      @tuned_file=data.each.map do |dob| +        if dob.of ==:heading \ +        || dob.of ==:heading_insert \ +        || dob.of ==:para \ +        || dob.of ==:block +          if dob.is ==:heading \ +          and dob.ln.to_s=~/^[0-9]/                                                    #% sub-number system, (baby numbering) reset with any change of major number (more obviously should be placed in number titles, but that is conditionally executed, check and move later) +            number_small,letter_small=0,0 +          elsif dob.is ==:para +            if dob.obj =~/^#[ 1]/ \ +            and dob.obj !~/^#\s+(?:~#)?$/ +              letter_small=0 +              number_small=0 if dob.obj =~ /^#1/ +              number_small+=1 +              dob.obj=dob.obj.gsub(/^#[ 1]/,"#{number_small}. ") +            end +            if dob.obj =~/^_# / +              dob.obj=dob.obj.gsub(/^_# /,"#{letter[letter_small]}. ") +              dob.indent='1' +              letter_small+=1 +            end +          end +        end +        dob +      end.flatten +    end +    def leading_zeros_fixed_width_number(possible_seg_name) +      if possible_seg_name.to_s =~/^([0-9]+?\.|[0-9]+)$/m       #!~/[.,:-]+/ +        possible_seg_name=possible_seg_name.to_s. +          gsub(/\.$/,'') +        nl=possible_seg_name.to_s.length +        zero='0' +        zeros_fixed_width=number_of_segments?.to_s.length +        zero_width=(zeros_fixed_width - nl) +        zero_width == 0 \ +        ? possible_seg_name.to_s +        : zero*zero_width + +          possible_seg_name.to_s +      end +    end +    def auto_numbering_exceptions(chosen_seg_names_,md,dob) +      number_make=case dob.lv.to_i +      when 1 +        @num_exc={ +          t1: @num_exc[:t1] += 1, +          t2: 0, +          t3: 0, +          t4: 0 +        } +        Mx[:segname_prefix_auto_num_other] + '_' \ +        + @num_exc[:t1].to_s +      when 2 +        @num_exc={ +          t1: @num_exc[:t1], +          t2: @num_exc[:t2] += 1, +          t3: 0, +          t4: 0 +        } +        Mx[:segname_prefix_auto_num_other] + '_' \ +        + @num_exc[:t1].to_s + '_' \ +        + @num_exc[:t2].to_s +      when 3 +        @num_exc={ +          t1: @num_exc[:t1], +          t2: @num_exc[:t2], +          t3: @num_exc[:t3] += 1, +          t4: 0 +        } +        Mx[:segname_prefix_auto_num_other] + '_' \ +        + @num_exc[:t1].to_s + '_' \ +        + @num_exc[:t2].to_s + '_' \ +        + @num_exc[:t3].to_s +      when 4 +        @num_exc[:t4] += 1 +        @num_exc={ +          t1: @num_exc[:t1], +          t2: @num_exc[:t2], +          t3: @num_exc[:t3], +          t4: @num_exc[:t4] += 1 +        } +        Mx[:segname_prefix_auto_num_other] + '_' \ +        + @num_exc[:t1].to_s + '_' \ +        + @num_exc[:t2].to_s + '_' \ +        + @num_exc[:t3].to_s + '_' \ +        + @num_exc[:t4].to_s +      end +    end +    def check_that_seg_names_are_unique(chosen_seg_names_,chosen_seg_name,type,md,dob) +      begin +        chosen_seg_names_ << chosen_seg_name +        chosen_seg_names_=chosen_seg_names(chosen_seg_names_,chosen_seg_name,dob,md,type) +        if chosen_seg_names_.compact.uniq.length \ +        == chosen_seg_names_.compact.length +          #check that all auto given seg names are unique +          chosen_seg_names_=chosen_seg_names(chosen_seg_names_,chosen_seg_name,dob,md,type) +          chosen_seg_name +        else +          SiSU_Utils::CodeMarker.new(__LINE__,__FILE__,:green). +            mark( +              "duplicated auto segment name: #{type} #{chosen_seg_name}\n" \ +              + "#{chosen_seg_names_}\n" \ +              + " manually name level 1 segments '1~given_name'\n" \ +              + 'filename: ' + md.fns + "\n" \ +              + 'heading text: "' + dob.obj + '"' + "\n" \ +              + 'duplication: "' + chosen_seg_name + '" (level: ' + dob.lv + '; numbering type: ' + type.to_s + ')' +            ) +          chosen_seg_name=auto_numbering_exceptions(chosen_seg_names_,md,dob) +          check_that_seg_names_are_unique(chosen_seg_names_,chosen_seg_name,:exception,md,dob) +        end +      rescue +      end +    end +    def auto_seg_name(possible_seg_name,heading_num_is,dob,type) +      prefix=case type +      when :auto    then Mx[:segname_prefix_auto_num_provide] +      when :extract then Mx[:segname_prefix_auto_num_extract] +      else               '_'*dob.lv.to_i #should not occur +      end +      if possible_seg_name =~/^[0-9]+?\.$/m                #!~/[.,:-]+/ +        possible_seg_name=possible_seg_name. +          gsub(/\.$/,'') +      end +      @chosen_seg_name= +      if dob.lv=='4' \ +      and possible_seg_name.to_s =~/^[0-9]+(?:[.,:-][0-9]){3}/m +        possible_seg_name=possible_seg_name.to_s. +          gsub(/(?:[:,-]|\W)/,'.'). +          gsub(/\.$/,'') +        prefix + possible_seg_name +      elsif dob.lv=='3' \ +      and possible_seg_name.to_s =~/^[0-9]+(?:[.,:-][0-9]){2}/m +        possible_seg_name=possible_seg_name.to_s. +          gsub(/(?:[:,-]|\W)/,'.'). +          gsub(/\.$/,'') +        prefix + possible_seg_name +      elsif dob.lv=='2' \ +      and possible_seg_name.to_s =~/^[0-9]+(?:[.,:-][0-9]){1}/m +        possible_seg_name=possible_seg_name.to_s. +          gsub(/(?:[:,-]|\W)/,'.'). +          gsub(/\.$/,'') +        prefix + possible_seg_name +      elsif dob.lv=='1' \ +      and possible_seg_name.to_s =~/^[0-9]+[:,-]?$/m +        if possible_seg_name.to_i <= heading_num_is.to_i +          prefix + leading_zeros_fixed_width_number(possible_seg_name) +        else +          possible_seg_name=possible_seg_name.to_s. +            gsub(/(?:[:,-]|\W)/,'.'). +            gsub(/\.$/,'') +          prefix + possible_seg_name +        end +      else +        @chosen_seg_name=auto_numbering_exceptions(@chosen_seg_names,md,dob) +      end +      check_that_seg_names_are_unique(@chosen_seg_names,@chosen_seg_name,type,@md,dob) +    end +    def set_name_and_tags(dob,possible_seg_name) +      if @md.seg_names.is_a?(Array) \ +      and not @md.seg_names.include?(possible_seg_name) +        dob.name=possible_seg_name +        dob.tags=set_tags(dob.tags,dob.name) +        @md.seg_names << possible_seg_name +      elsif (@md.opt.act[:verbose_plus][:set]==:on \ +      or @md.opt.act[:maintenance][:set]==:on) +        puts 'warn, there may be a conflicting numbering scheme' +      end +    end +    def name_para_seg_filename(data)                                                   #segment naming, remaining +      # paragraph name/numbering rules +      # manual naming overrides, manual naming may be +      #   alpha-numeric characters mixed, +      #   numeric only (a number), if +      #     all segments have been named, +      #     the numbers used are over 1000 or +      #     it is not minded that auto-numbering uses a funny scheme for naming segments (not yet implemented) +      #       [for now a warning is printed for such documents on use of maintenance or very-verbose flag] +      # auto-naming takes the form of giving numbers to segments +      # the rules for which are as follows +      #   if the title/heading text starts with a numeric, then that is used (1 3.1 3rd etc.) +      #   otherwise the level 4 segment number from the embedded document structure info is used +      #   if there is none a sequential number is designated, preceded by an underscore +      @tuned_file,@unique_auto_name=[],[] +      tags={} +      @art_filename_auto=0 +      @counter=1 +      if not @md.seg_autoname_safe \ +      and (@md.opt.act[:verbose_plus][:set]==:on \ +      || @md.opt.act[:maintenance][:set]==:on) +        puts 'manual segment names, numbers used as names, risk warning (segmented html)' +      end +      ocn_html_seg=[] +      @num_exc={ t1: 0, t2: 0, t3: 0, t4: 0 } +      data.each do |dob| +        if dob.is==:heading \ +        && dob.ln \ +        and dob.ln.to_s =~/^[4-7]/ +          heading_num_is=/^\d+:(\d+);\d/m.match(dob.node)[1] +          if dob.ln==4 \ +          and not dob.name \ +          and not @md.set_heading_seg +            @md.set_heading_seg=true +          end +          if dob.name !~/^\S+/ \ +          and dob.ln.to_s =~/^[5-7]/ \ +          and dob.obj =~/^\s*(?:\S+\s+)?([0-9]+(?:[.,:-][0-9])+)/m +            #heading starts with a recognised numeric +            #or word followed by a recognised numeric construct, +            #use that as name +            if dob.ln==7 \ +            and dob.obj =~/^\s*(?:\S+\s+)?([0-9]+(?:[.,:-][0-9]){3})/m +              possible_seg_name=$1. +                gsub(/(?:[:,-]|\W)/,'.'). +                gsub(/\.$/,'') +              possible_seg_name= +                auto_seg_name(possible_seg_name,heading_num_is,dob,:extract) +              set_name_and_tags(dob,possible_seg_name) +            elsif dob.ln==6 \ +            and dob.obj =~/^\s*(?:\S+\s+)?([0-9]+(?:[.,:-][0-9]){2})/m +              possible_seg_name=$1. +                gsub(/(?:[:,-]|\W)/,'.'). +                gsub(/\.$/,'') +              possible_seg_name= +                auto_seg_name(possible_seg_name,heading_num_is,dob,:extract) +              set_name_and_tags(dob,possible_seg_name) +            elsif dob.ln==5 \ +            and dob.obj =~/^\s*(?:\S+\s+)?([0-9]+(?:[.,:-][0-9]){1})/m +              possible_seg_name=$1. +                gsub(/(?:[:,-]|\W)/,'.'). +                gsub(/\.$/,'') +              possible_seg_name= +                auto_seg_name(possible_seg_name,heading_num_is,dob,:extract) +              set_name_and_tags(dob,possible_seg_name) +            end +          end +          if dob.ln==4 +            if dob.name !~/^\S+/ \ +            and dob.obj =~/^\s*(?:\S+\s+)?([0-9]+)/m +              #heading starts with a recognised numeric +              #or word followed by a recognised numeric construct, +              #use that as name +              possible_seg_name=$1 +              possible_seg_name= +                auto_seg_name(possible_seg_name,heading_num_is,dob,:extract) +              set_name_and_tags(dob,possible_seg_name) +            end +            if dob.name +              #extract segment name from embedded document structure info +              if @md.seg_names.is_a?(Array) \ +              and not @md.seg_names.include?(dob.name) +                dob.tags=set_tags(dob.tags,dob.name) +                @md.seg_names << dob.name +              end +            else +              #if no segment name, +              #provide a numerical one +              @art_filename_auto+=1 +              possible_seg_name= +                auto_seg_name(@art_filename_auto,heading_num_is,dob,:auto) +              if @md.seg_names.is_a?(Array) \ +              and not @md.seg_names.include?(possible_seg_name) +               dob.name=possible_seg_name +               dob.tags=set_tags(dob.tags,dob.name) +                @md.seg_names << possible_seg_name +              else puts 'segment name (numbering) error' +              end +            end +            if not dob.name #should not occur +              puts "e r r o r -\t#{__FILE__}::#{__LINE__}\n#{dob.inspect}" +            end +          end +        end +        if (dob.is ==:heading \ +        || dob.is ==:heading_insert) \ +        && dob.ln==4 +          @seg=dob.name +        end +        @tuned_file << if dob.is==:heading \ +        && (@md.pagenew || @md.pagebreak || @md.pageline) +          m=dob.ln.to_s +          dob_tmp=[] +          if @md.pagenew.inspect =~/#{m}/ +            dob_tmp << +              SiSU_AO_DocumentStructure::ObjectLayout.new.break(Hx[:br_page_new]) << +              dob +          elsif @md.pagebreak.inspect =~/#{m}/ +            dob_tmp << +              SiSU_AO_DocumentStructure::ObjectLayout.new.break(Hx[:br_page]) << +              dob +          elsif @md.pageline.inspect =~/#{m}/ +            dob_tmp << +              SiSU_AO_DocumentStructure::ObjectLayout.new.break(Hx[:br_page_line]) << +              dob +          end +          unless dob_tmp.length > 0; dob +          else                       dob_tmp +          end +        else dob +        end +        if defined? dob.ocn \ +        and dob.ocn +          @segname=((dob.is==:heading || dob.is==:heading_insert) && dob.ln==4 && (defined? dob.name)) \ +          ? (dob.name) +          : @segname +          tags["#{dob.ocn}"]={ segname: @segname } +          ocn_html_seg[dob.ocn]=if (dob.is==:heading || dob.is==:heading_insert) +            if dob.ln.to_s =~/[0-3]/ +              { +                seg: nil, +                level: dob.ln, +              } +            #elsif dob.ln =~/[4-6]/ +            else +              { +                seg: @seg, +                level: dob.ln, +              } +            end +          else +            { +              seg: @seg, +              level: nil, +            } +          end +        end +        dob.tags=dob.tags.uniq if defined? dob.tags +        if defined? dob.tags \ +        and dob.tags.length > 0 +          #@segname=((dob.is=='heading'|| dob.is=='heading_insert') && dob.ln==4 && (defined? dob.name)) \ +          #? (dob.name) \ +          #: @segname +          dob.tags.each do |y| +            tags[y]={ ocn: dob.ocn.to_s, segname: @segname } +          end +        end +        dob +      end +      ocn_html_seg.each_with_index do |ocn,i| +        if ocn \ +        and ocn[:level].to_s=~/[1-3]/ +          (1..4).each do |x| +            if ocn_html_seg[i+x] \ +            and ocn_html_seg[i+x][:level]==4 +              ocn[:seg]=ocn_html_seg[i+x][:seg] +            end +          end +        end +      end +      if @md.seg_names.length > 0 +        @md.set_heading_seg=true +      end +      tuned_file=@tuned_file.flatten +      [tuned_file,tags,ocn_html_seg] +    end +    def set_heading_top(data)                                                          #% make sure no false positives +      unless @md.set_heading_top +        if (@md.opt.act[:verbose_plus][:set]==:on \ +        or @md.opt.act[:maintenance][:set]==:on) +          puts "\tdocument contains no top level heading, (will have to manufacture one)" +        end +        @tuned_file=[] +        data.each do |t_o| +          unless @md.set_heading_top +            if t_o !~/^(?:#{Rx[:meta]}|@\S+:)\s/m \ +            and t_o !~/\A\s*\Z/m +              @md.set_heading_top=true +              if defined? @md.title \ +              and @md.title \ +              and defined? @md.title.full \ +              and defined? @md.creator \ +              and @md.creator +                head=@md.title.main \ +                ? ([@lv='1',@obj=@md.title.main]) +                : ([@lv='1',@obj='[no title provided]']) +                @tuned_file << head +              end +            end +          end +          @tuned_file << t_o +        end +        @tuned_file=@tuned_file.flatten +      end +    end +    def set_heading_seg(data)                                                          #% make sure no false positives +      unless @md.set_heading_seg +        if (@md.opt.act[:verbose_plus][:set]==:on \ +        or @md.opt.act[:maintenance][:set]==:on) +          puts "\tdocument contains no segment level, (will have to manufacture one)" +        end +        @tuned_file=[] +        data.each do |dob| +          unless @md.set_heading_seg +            if defined? dob.ln and dob.ln.to_s !~/^[0-3]/m \ +            and dob.obj !~/\A\s*\Z/m \ +            and dob.is !=:layout +              @md.set_heading_seg=true +              head=@md.title.main \ +              ? (dob.ln,dob.name,dob.obj=4,'seg',@md.title.main) +              : (dob.ln,dob.name,dob.obj=4,'seg','[segment]') +              @tuned_file << head +            end +          end +          @tuned_file << dob +        end +        @tuned_file=@tuned_file.flatten +      end +    end +    def set_header_title(data)                                                         #% make sure no false positives +      unless @md.set_header_title +        if (@md.opt.act[:verbose_plus][:set]==:on \ +        or @md.opt.act[:maintenance][:set]==:on) +          puts "\t no document title provided, (will have to manufacture one)" +        end +        @tuned_file=[] +        data.each do |t_o| +          unless @md.set_header_title +            if t_o !~/^%{1,2}\s/m \ +            and t_o !~/\A\s*\Z/m +              @tuned_file << +                "#{Mx[:meta_o]}title#{Mx[:meta_c]} #{@md.heading_seg_first}" +              @md.title.main=@md.heading_seg_first +              @md.set_header_title=true +            end +          end +          @tuned_file << t_o +        end +        @tuned_file=@tuned_file.flatten +      end +    end +  end +end +__END__ +#+END_SRC + +** ao_persist.rb + +#+BEGIN_SRC ruby  :tangle "../lib/sisu/ao_persist.rb" +# <<sisu_document_header>> +module SiSU_AO_Persist +  class Persist +    @@persistance=nil +    attr_accessor :fns, :ao_arr, :idx_arr_sst, :idx_arr_tex, :idx_arr_html, :idx_arr_xhtml, :map_arr_nametags, :map_arr_ocn_htmlseg +    def initialize(args=nil) +      @@persistance=args=(args ? args : (@@persistance || persist_init_hash_values)) +      @fns=args[:fns] +      @ao_arr=args[:ao_arr] +      @idx_arr_sst=args[:idx_arr_sst] +      @idx_arr_tex=args[:idx_arr_tex] +      @idx_arr_html=args[:idx_arr_html] +      @idx_arr_xhtml=args[:idx_arr_xhtml] +      @map_arr_nametags=args[:map_arr_nametags] +      @map_arr_ocn_htmlseg=args[:map_arr_ocn_htmlseg] +    end +    def fns +      @fns +    end +    def ao_arr +      @ao_arr +    end +    def idx_arr_sst +      @idx_arr_sst +    end +    def idx_arr_tex +      @idx_arr_tex +    end +    def idx_arr_html +      @idx_arr_html +    end +    def idx_arr_xhtml +      @idx_arr_xhtml +    end +    def map_arr_nametags +      @map_arr_nametags +    end +    def map_arr_ocn_htmlseg +      @map_arr_ocn_htmlseg +    end +    def persist_init_hash_values +      { +        fns:                 nil, +        ao_arr:              [], +        idx_arr_sst:         [], +        idx_arr_tex:         [], +        idx_arr_html:        [], +        idx_arr_xhtml:       [], +        map_arr_nametags:    [], +        map_arr_ocn_htmlseg: [], +      } +    end +    def persist_init +      @@persistance=nil +      Persist.new(persist_init_hash_values) +    end +  end +  class PersistDocStructExt +    @@persist=nil +    attr_accessor :ocn, :lng, :lng_is, :code, :lngsyn, :poem, :block, :box, :group, :alt, :quote, :table, :table_to +    def initialize(args=nil) +      @@persist=args=(args ? args : (@@persist || persist_init_hash_values)) +      @ocn=args[:ocn] +      @lng=args[:lng] +      @lng_is=args[:lng_is] +      @code=args[:code] +      @lngsyn=args[:lngsyn] +      @poem=args[:poem] +      @block=args[:block] +      @box=args[:box] +      @group=args[:group] +      @alt=args[:alt] +      @quote=args[:quote] +      @table=args[:table] +      @table_to=args[:table_to] +    end +    def ocn +      @ocn +    end +    def lng +      @lng +    end +    def lng_is +      @lng_is +    end +    def code +      @code +    end +    def lngsyn +      @lngsyn +    end +    def poem +      @poem +    end +    def block +      @block +    end +    def box +      @box +    end +    def group +      @group +    end +    def alt +      @alt +    end +    def quote +      @quote +    end +    def table +      @table +    end +    def table_to +      @table_to +    end +    def persist_init_hash_values +      { +        ocn:         :on, +        lng:         :off, +        lng_is:      :doc_default, +        code:        :off, +        lngsyn:      :txt, +        poem:        :off, +        block:       :off, +        box:         :off, +        group:       :off, +        alt:         :off, +        quote:       :off, +        table:       :off, +        table_to:    :off, +      } +    end +    def persist_init +      @@persist=nil +      PersistDocStructExt.new(persist_init_hash_values) +    end +  end +end +__END__ +#+END_SRC + +** ao_syntax.rb + +#+BEGIN_SRC ruby  :tangle "../lib/sisu/ao_syntax.rb" +# <<sisu_document_header>> +module SiSU_AO_Syntax +  class Words +    def initialize(line,md,mkp) +      @line,@md,@mkp=line,md,mkp +    end +  end +  class Markup +    def initialize(md='',data='',biblio=[]) +      @md,@data,@bibliography=md,data,biblio +      @data_new=[] +      url_and_stub=SiSU_Env::InfoEnv.new.url +      @output_url="#{url_and_stub.remote}" +      @env=SiSU_Env::InfoEnv.new +      emph_set=if defined? @md.emphasis_set_to \ +      and not @md.emphasis_set_to.nil? +        @md.emphasis_set_to +      else @env.markup_emphasis +      end +      @emph=case emph_set +      when /bold/ +        emph_italics=false +        { o: Mx[:fa_bold_o], c: Mx[:fa_bold_c] } +      when /italics/ +        emph_italics=true +        { o: Mx[:fa_italics_o], c: Mx[:fa_italics_c] } +      when /underscore/ +        emph_italics=false +        { o: Mx[:fa_underscore_o], c: Mx[:fa_underscore_c] } +      else p __LINE__.to_s + '::' + __FILE__ +      end +      @http_m=%r{\{.+?\}https?://\S+|https?:\S+|:\S+|\.\.\/\S+|#\S+|\S+?\.png\b|[*]~\S+|^#{Mx[:meta_o]}.+|#{Mx[:gr_o]}(?:code(?:\.[a-z][0-9a-z_]+)?|box(?:\.[a-z_]+)?|block|group|alt|verse)(?:-end)?#{Mx[:gr_c]}|#{Mx[:fa_o]}:br#{Mx[:fa_c]}} +      @manmkp_ital=emph_italics \ +      ? '[i/*]\\{.+?\\}[i/*]' +      : '[i/]\\{.+?\\}[i/]' +      tail_m_ital=%q{(?:\s|'s\b|[.,;:?!'")]|~\^|~\\\{\s|$)} +      tail_m_bold=%{(?:(?:#{Mx[:fa_italics_c]})?(?:\s|'s\b|[.,;:?!'")]|~\^|~\\\{\s|$))?} +      bold_line=%{^!_\s.+?(?:#{Mx[:br_line]}|\n|$)} +      #ital_line=%{^/_\s.+?(?:#{Mx[:br_line]}|\n|$)} #not implemented +      @line_scan_ital=if defined? @md.italics_match_list[:str] +        /#{@http_m}|#{bold_line}|#{@manmkp_ital}#{tail_m_ital}|#{@md.italics_match_list[:str]}#{tail_m_ital}|\S+|\n/i +      end +      @manmkp_bold=emph_italics \ +      ? '^!_\s.+?(?:\n|$)|[!b]\\{.+?\\}[*!b]|[*!][a-zA-Z0-9\-_]+[!]' +      : '^!_\s.+?(?:\n|$)|[*!b]\\{.+?\\}[*!b]|[*!][a-zA-Z0-9\-_]+[*!]' +      @line_scan_bold=if defined? @md.bold_match_list[:str] \ +      and @md.bold_match_list[:str] +        /#{@http_m}|#{bold_line}|(?:#{@manmkp_bold}|#{@md.bold_match_list[:str]})#{tail_m_bold}|\S+|\n/i +      end +    end +    def songsheet +      @data=@data.compact +      @data.each do |dob| +        dob=breaks(dob) +        dob=if @md.sem_tag then sem(dob) else dob end #revisit +        dob=line_actions(dob) +        dob=paragraph_set(dob) +        dob=substitutions(dob) +        dob=wordlist_italics(dob) +        dob=wordlist_bold(dob) +        dob=bodymarkup(dob) +        @data_new << dob unless dob.nil? +      end +      @data_new +    end +    def sem(dob) #revisit +      dob=SiSU_Sem::Tags.new(dob,@md).rm.all +    end +    def breaks(dob) +      if dob.is !=:meta \ +      && dob.is !=:comment \ +      && dob.is !=:code \ +      && dob.is !=:table +        dob.obj=dob.obj. +          gsub(/^-\\\\-\s*$/,"#{Mx[:br_page]}"). +          gsub(/^=\\\\=\s*$/,"#{Mx[:br_page_new]}"). +          gsub(/ \\\\(?: |$)/,"#{Mx[:br_line]}"). +          gsub(/(?:<:?pb>)/,"#{Mx[:br_page]}").                         # depreciated +          gsub(/(?:<:?pn>)/,"#{Mx[:br_page_new]}").                     # depreciated +          gsub(/(?:<:?br>|<br \/>)/,"#{Mx[:br_line]}").                 # depreciated +          gsub(/(?:^-\.\.-\s*$)/,"#{Mx[:br_page_line]}") +      end +      dob +    end +    def wordlist_italics(dob) +      dob=dob.dup +      if (defined? @md.italics_match_list[:str] \ +      and @md.italics_match_list[:str]) +        dob.obj=if dob.is !=:meta \ +        && dob.is !=:heading \ +        && dob.is !=:heading_insert \ +        && dob.is !=:code \ +        && dob.is !=:layout \ +        && dob.is !=:comment +          word=dob.obj.scan(@line_scan_ital) +          word=word.flatten.compact +          line_array=[] +          word.each do |w| +            unless /#{@manmkp_ital}|#{@http_m}/.match(w) +              if defined? @md.italics_match_list[:regx] \ +              and @md.italics_match_list[:regx] +                w=w.gsub(@md.italics_match_list[:regx], +                  "#{Mx[:fa_italics_o]}\\1#{Mx[:fa_italics_c]}") +              else w +              end +            end +            line_array << w +          end +          line_array.join(' ') +        else dob.obj +        end +      end +      dob +    end +    def embolden(given) +      given=given. +        gsub(/^!_\s+((?:\{|#{Mx[:lnk_o]})(?:~^ )?.+?(?:\}|#{Mx[:lnk_o]})https?:\/\/\S+.*?)([#{Mx[:br_line]}#{Mx[:br_paragraph]}#{Mx[:br_nl]}])/, +          "#{Mx[:fa_bold_o]} \\1 #{Mx[:fa_bold_c]}\\2"). +        gsub(/^!_\s+((?:\{|#{Mx[:lnk_o]})(?:~^ )?.+?(?:\}|#{Mx[:lnk_o]})https?:\/\/\S+.*)/, +          "#{Mx[:fa_bold_o]} \\1 #{Mx[:fa_bold_c]}"). +        gsub(/(?:^!_|^#{Mx[:lv_o]}[7-9]:\S*?#{Mx[:lv_c]})\s*(.+?)([#{Mx[:br_line]}#{Mx[:br_paragraph]}#{Mx[:br_nl]}])/, +          "#{Mx[:fa_bold_o]}\\1#{Mx[:fa_bold_c]}\\2"). +        gsub(/(?:^!_|^#{Mx[:lv_o]}[7-9]:\S*?#{Mx[:lv_c]})\s*(.+?)\s+((?:[*]~\S+\s*)+)/, +          "#{Mx[:fa_bold_o]}\\1#{Mx[:fa_bold_c]}\\2"). +        gsub(/(?:^!_|^#{Mx[:lv_o]}[7-9]:\S*?#{Mx[:lv_c]})\s*(.+?)\s*([~-]#)$/, +          "#{Mx[:fa_bold_o]}\\1#{Mx[:fa_bold_c]}\\2"). +        gsub(/(?:^!_\s+|^#{Mx[:lv_o]}[7-9]:\S*?#{Mx[:lv_c]}\s*)(.*)?\s*$/, +          "#{Mx[:fa_bold_o]}\\1#{Mx[:fa_bold_c]}") +    end +    def italicise(given) +      given=given. +        gsub(/^\/_\s*(.+?)([#{Mx[:br_line]}#{Mx[:br_paragraph]}#{Mx[:br_nl]}])/, +          "#{Mx[:fa_italics_o]}\\1#{Mx[:fa_italics_c]}\\2"). +        gsub(/^\/_\s*(.+?)\s+((?:[*]~\S+\s*)+)/, +          "#{Mx[:fa_italics_o]}\\1#{Mx[:fa_italics_c]}\\2"). +        gsub(/^\/_\s*(.+?)\s*([~-]#)$/, +          "#{Mx[:fa_italics_o]}\\1#{Mx[:fa_italics_c]}\\2"). +        gsub(/^\/_\s+(.*)?\s*$/, +          "#{Mx[:fa_italics_o]}\\1#{Mx[:fa_italics_c]}") +    end +    def line_actions(dob) +      dob.obj=if (dob.is !=:heading \ +      && dob.is !=:heading_insert \ +      && dob.is !=:comment \ +      && dob.is !=:meta) \ +      and dob.obj =~ /^!_\s+/ +        embolden(dob.obj) +      elsif dob.obj =~ /^\/_\s+/ +        italicise(dob.obj) +      else dob.obj +      end +      dob +    end +    def paragraph_set(dob) +      dob.obj=if dob.is !=:meta \ +      && dob.is !=:heading \ +      && dob.is !=:heading_insert \ +      && dob.is !=:code \ +      && dob.is !=:comment \ +      && dob.is !=:table +        dob.obj.gsub(/\n/m,' '). +          gsub(/ \s+/m,' ') +      else dob.obj +      end +      dob +    end +    def substitutions(dob) +      dob=dob.dup +      dob=if @md.flag_auto_biblio \ +      and @bibliography.length > 0 +        dob=if dob.is !=:meta \ +        && dob.is !=:heading_insert \ +        && dob.is !=:code \ +        && dob.is !=:comment \ +        && dob.is !=:table +          @bibliography.each do |c| +            if c[:id] and not c[:id].nil? and not c[:id].empty? +              dob.obj=dob.obj.gsub(/#{c[:id]}/mi,c[:short_name]) +            end +          end +          dob +        else dob +        end +        dob +      else dob +      end +      dob=if defined? @md.substitution_match_list[:match_and_replace] \ +      and @md.substitution_match_list[:match_and_replace].is_a?(Array) +        dob=if dob.is !=:meta \ +        && dob.is !=:heading_insert \ +        && dob.is !=:code \ +        && dob.is !=:comment \ +        && dob.is !=:table +          if dob.obj =~/#{@md.substitution_match_list[:matches]}/ +            @md.substitution_match_list[:match_and_replace].each do |x| +              dob.obj=if x[:case_s]==:i +                dob.obj.gsub(/#{x[:match]}/mi,x[:replace]) +              else +                dob.obj.gsub(/#{x[:match]}/m,x[:replace]) +              end +            end +          end +          dob +        else dob +        end +        dob +      else dob +      end +    end +    def wordlist_bold(dob) +      dob=dob.dup +      if (defined? @md.bold_match_list[:str] \ +      and @md.bold_match_list[:str]) +        dob.obj=if dob.is !=:meta \ +        && dob.is !=:heading \ +        && dob.is !=:heading_insert \ +        && dob.is !=:code \ +        && dob.is !=:comment \ +        && dob.is !=:table +          line_array=[] +          word=dob.obj.scan(@line_scan_bold) +          word=word.flatten.compact +          word.each do |w| +            unless /#{@manmkp_bold}|#{@http_m}/.match(w) +              if defined? @md.bold_match_list[:regx] \ +              and @md.bold_match_list[:regx]                                             #document header: @bold: [bold word list] +                w=w.gsub(@md.bold_match_list[:regx], +                  "#{Mx[:fa_bold_o]}\\1#{Mx[:fa_bold_c]}") +              end +            else +              w=if w =~ /(?:^!_|^#{Mx[:lv_o]}[7-9]:\S*?#{Mx[:lv_c]})\s+/ +                embolden(w)      #bold paragraph/emphasize #may wish to remove think about 7{ 8{ conversion not satisfactory, as information is lost! +              elsif w =~/^\/_\s+/ +                italicise(w) +              else w +              end +            end +            line_array << w +          end +          line_array.join(' ') +        else dob.obj +        end +      else +        dob.obj=if dob.is==:heading \ +        and dob.ln.to_s =~/[7-9]/ +          embolden(dob.obj) +        else dob.obj +        end +      end +      dob +    end +    def fontface_lines(dob,leader) +      while (dob.obj =~/#{Mx[:br_nl]}/ \ +      and dob.obj =~/(?:#{leader})([*!\/_#])\{(.+?)\}\1/m) \ +      and $2 =~/#{Mx[:br_nl]}/ +        dob=if dob.obj =~/#{Mx[:br_nl]}/ \ +        and dob.obj =~/(#{leader})([*!\/_#])\{(.+?)\}\2/m +          lead,fce,txt=$1,$2,$3 +          dob=if txt =~/#{Mx[:br_nl]}/ +            lead_break=if dob.obj =~/^#{Mx[:br_nl]}/ +              dob.obj=dob.obj.sub(/^#{Mx[:br_nl]}/,'') +              Mx[:br_nl] +            else '' +            end +            txt="#{lead_break}#{fce}\{" + txt.split(Mx[:br_nl]).join("\}#{fce}#{Mx[:br_nl]}#{fce}\{") + "\}#{fce}" +            dob.obj=dob.obj. +              sub(/(?:^|#{Mx[:gl_c]}|\s+|['"]|[#{Mx[:nbsp]}#{Mx[:fa_o_c]}#{Mx[:fa_c]}#{Mx[:lnk_o]}#{Mx[:br_nl]}#{Mx[:br_line]}#{Mx[:br_paragraph]}#{Mx[:tc_c]}#{Mx[:tc_p]}]|[\(\[\{]|\>)([*!\/_#])\{.+?\}\1/m, +                "#{lead}#{txt}") +            dob +          else dob +          end +        end +        dob +      end +      dob +    end +    def fontface(dob) +      leader=/^|#{Mx[:gl_c]}|\s+|['"]|[#{Mx[:nbsp]}#{Mx[:fa_o_c]}#{Mx[:fa_c]}#{Mx[:lnk_o]}#{Mx[:br_nl]}#{Mx[:br_line]}#{Mx[:br_paragraph]}#{Mx[:tc_c]}#{Mx[:tc_p]}]|[\(\[\{]|[、。「‹«¿¡]|\>/ +      dob=fontface_lines(dob,leader) +      dob.obj=dob.obj. +        gsub(/(#{leader})\*\{(.+?)\}\*/m, +          "\\1#{@emph[:o]}\\2#{@emph[:c]}").                                                                                                                             #emphasis +        gsub(/(#{leader})!\{(.+?)\}!/m, +          "\\1#{Mx[:fa_bold_o]}\\2#{Mx[:fa_bold_c]}").                                                                                                                   #bold +        gsub(/(#{leader})\/\{(.+?)\}\//m, +          "\\1#{Mx[:fa_italics_o]}\\2#{Mx[:fa_italics_c]}").                                                                                                             #italics +        gsub(/(#{leader})_\{(.+?)\}_/m, +          "\\1#{Mx[:fa_underscore_o]}\\2#{Mx[:fa_underscore_c]}").                                                                                                       #underscore +        gsub(/(#{leader})#\{(.+?)\}#/m, +          "\\1#{Mx[:fa_monospace_o]}\\2#{Mx[:fa_monospace_c]}").                                                                                                         #monospace +        gsub(/(^|#{Mx[:gl_c]}|\s+|['"]|[#{Mx[:nbsp]}#{Mx[:fa_o_c]}#{Mx[:fa_c]}]|\(|\>)\"\{(.+?)\}\"/m, +          "\\1#{Mx[:fa_cite_o]}\\2#{Mx[:fa_c_o]}cite#{Mx[:fa_c]}").                                                                                                      #cite /blockquote? +        gsub(/(^|[^\\])\^\{(.+?)\}\^/m, +          "\\1#{Mx[:fa_superscript_o]}\\2#{Mx[:fa_superscript_c]}").                                                                                                     #superscript +        gsub(/(^|[^\\]),\{(.+?)\},/m, +          "\\1#{Mx[:fa_subscript_o]}\\2#{Mx[:fa_subscript_c]}").                                                                                                         #subscript +        gsub(/(^|#{Mx[:gl_c]}|\s+|['"]|#{Mx[:nbsp]}|#{Mx[:fa_o_c]}|#{Mx[:fa_c]}|\(|\>)\+\{(.+?)\}\+/m, +          "\\1#{Mx[:fa_insert_o]}\\2#{Mx[:fa_insert_c]}").                                                                                                               #inserted text +        gsub(/(^|#{Mx[:gl_c]}|\s+|['"]|#{Mx[:nbsp]}|#{Mx[:fa_o_c]}|#{Mx[:fa_c]}|\(|\>)-\{(.+?)\}-/m, +          "\\1#{Mx[:fa_strike_o]}\\2#{Mx[:fa_strike_c]}").                                                                                                               #strikethrough - deleted text +        gsub(/(^|#{Mx[:gl_c]}|\s+|['"]|#{Mx[:nbsp]}|#{Mx[:fa_o_c]}|#{Mx[:fa_c]}|\(|\>|\d+)\^(\S+?)\^/, +          "\\1#{Mx[:fa_superscript_o]}\\2#{Mx[:fa_superscript_c]}")                                                                                                      #superscript single word, watch digit added +      dob +    end +    def bodymarkup(dob) +      # << http://www.jus.uio.no/sisu/sisu_markup_table/markup >> +      # See: data/sisu/sample/document_samples_sisu_markup/ +      ## fontface +      # *{emphasis}*        e{emphasis}e       <strong>emphasis</strong> +      # !{bold text}!       b{bold}b           <b>bold text</b> +      # _{underline}_       u{underline}u      <u>underline</u> +      # /{italics}/         i{italics}i        <i>italics</i> +      # "{citation}"        c{citation}c       <cite>citation</cite> #blockquote? +      # ^{superscript}^                        <sup>superscript</sup> +      # ,{subscript},                          <sub>subscript</sub> +      # +{inserted text}+                      <ins>inserted text</ins> +      # -{deleted text}-                       <del>deleted text</del> +      # #{monospace text}# +      # +      # {url address}:url +      # {image.png}imageurl +      # {image.png}png +      # ~{endnote}~ +      # !_                                    #bold/emphasise paragraph +      # _"                                    #blockquote paragraph +      # _1                  <:i1>            #indent paragraph 1 step +      # _2                  <:i2>            #indent paragraph 2 steps +      # _3                  <:i3>            #indent paragraph 3 steps +      # _4                  <:i4>            #indent paragraph 4 steps +      # _*                                    #bullet (list) ● +      # _1*                                   #bullet (list) indented +      # _1*                                   #bullet (list) indented +      # #                                     #numbered (list) level 1 +      # _#                                    #numbered (list) level 2 +      dob=dob.dup +      if dob.is !=:meta \ +      && dob.is !=:comment \ +      && dob.is !=:code \ +      && dob.is !=:table +        line_array=[] +        word=dob.obj.scan(/\S+|\n/) #unless line =~/^(?:#{Mx[:meta_o]}|%+\s)/ #visit +        if word +          word.each do |w| # _ - / # | : ! ^ ~ +            unless w =~/~\{|\}~|~\[|\]~|^\^~|~\^|\*~\S+|~#|\{t?~|\{table|https?:\/\/\S+/           # do something earlier about table!! +              w=w.gsub(/\\?~/,"#{Mx[:gl_o]}#126#{Mx[:gl_c]}")                                      #escaped special character +            end +            w=w.gsub(/^\<$/, +              "#{Mx[:gl_o]}#lt#{Mx[:gl_c]}").gsub(/^\>$/,"#{Mx[:gl_o]}#gt#{Mx[:gl_c]}")            #escaped special character +            line_array << w +          end +          dob.obj=line_array.join(' ') +          dob.obj=dob.obj.strip +        end +        dob.obj=dob.obj. +          gsub(/^([*#.-]{1,12})$/,'\1 ~#').                                                        #ocn off for these paragraph separators +          gsub(/~\{(.+?)\}~/m,Mx[:en_a_o] + '\1' + Mx[:en_a_c]). +          gsub(/~\[([^*+].+?)\]~/m,Mx[:en_b_o] + '* \1' + Mx[:en_b_c]).                            #default if markup does not specify +          gsub(/~\[(.+?)\]~/m,Mx[:en_b_o] + '\1' + Mx[:en_b_c]) +        if dob.is ==:heading \ +        and dob.ln ==0 +          dob.obj=dob.obj.gsub(/\s*@title\b/," #{@md.title.full}") +          dob.obj=if defined? @md.creator.author \ +          and @md.creator.author +            dob.obj.gsub(/\s+(?:@creator|@author)/,",#{Mx[:br_line]}#{@md.creator.author}") +          else dob.obj.gsub(/\s+(?:@creator|@author)/,'') +          end +        end +        if defined? @md.title \ +        and @md.title \ +        and defined? @md.title.full \ +        and defined? @md.creator \ +        and @md.creator +          if dob.is ==:heading +            dob.obj=dob.obj.gsub(/^\s*@title\s*$/,@md.title.full) if dob.lv =~/1/ +            dob.obj=if dob.lv =~/[23]/ \ +            and defined? @md.creator.author \ +            and @md.creator.author +              dob.obj. +                gsub(/^\s*(?:(by\s+)?(?:@creator|@author))\s*$/, +                  "\\1#{@md.creator.author}") +            else dob.obj.gsub(/^\s*(?:(by\s+)?(?:@creator|@author))\s*$/,'\1') +            end +          end +        end +        dob.obj=dob.obj.gsub(/<(https?:\/\/\S+?)>/,'< \1 >').                     #catch problem markup +          gsub(/<:=(\S+?)>/,'{ c_\1.png 14x14 }image'). +          gsub(/<!(\S+)!>/,'<:\1>').                                              #escaped special character +          gsub(/ /,"#{Mx[:nbsp]}").                                          #escaped special character +          gsub(/\\~/,"#{Mx[:gl_o]}#126#{Mx[:gl_c]}").                             #escaped special character +          gsub(/\\\{/,"#{Mx[:gl_o]}#123#{Mx[:gl_c]}").                            #escaped special character +          gsub(/\\\}/,"#{Mx[:gl_o]}#125#{Mx[:gl_c]}").                            #escaped special character +          gsub(/\\\<</,"#{Mx[:gl_o]}#lt#{Mx[:gl_c]}#{Mx[:gl_o]}#lt#{Mx[:gl_c]}"). #escaped special character +          gsub(/\\\>>/,"#{Mx[:gl_o]}#gt#{Mx[:gl_c]}#{Mx[:gl_o]}#gt#{Mx[:gl_c]}"). #escaped special character +          gsub(/\\\</,"#{Mx[:gl_o]}#lt#{Mx[:gl_c]}").                             #escaped special character +          gsub(/\\\>/,"#{Mx[:gl_o]}#gt#{Mx[:gl_c]}").                             #escaped special character +          gsub(/\\\_/,"#{Mx[:gl_o]}#095#{Mx[:gl_c]}").                            #escaped special character +          gsub(/\\\-/,"#{Mx[:gl_o]}#045#{Mx[:gl_c]}").                            #escaped special character +          gsub(/\\\+/,"#{Mx[:gl_o]}#043#{Mx[:gl_c]}").                            #escaped special character +          gsub(/\\\//,"#{Mx[:gl_o]}#047#{Mx[:gl_c]}").                            #escaped special character +          gsub(/\\\#/,"#{Mx[:gl_o]}#035#{Mx[:gl_c]}").                            #escaped special character +          gsub(/\\\&/,"#{Mx[:gl_o]}#038#{Mx[:gl_c]}").                            #& #escaped special character +          gsub(/\\\|/,"#{Mx[:gl_o]}#124#{Mx[:gl_c]}").                            #not really a sisu special character but made available as possibility +          gsub(/\\\:/,"#{Mx[:gl_o]}#058#{Mx[:gl_c]}").                            #not really a sisu special character but made available as possibility +          gsub(/\\\!/,"#{Mx[:gl_o]}#033#{Mx[:gl_c]}").                            #not really a sisu special character but made available as possibility +          gsub(/\\\^/,"#{Mx[:gl_o]}#094#{Mx[:gl_c]}").                            #not really a sisu special character but made available as possibility +          gsub(/\\\,/,"#{Mx[:gl_o]}#044#{Mx[:gl_c]}").                            #not really a sisu special character but made available as possibility +          gsub(/\\\\/,"#{Mx[:gl_o]}#092#{Mx[:gl_c]}").                            #escaped special character +          gsub(/\\\*/,"#{Mx[:gl_o]}#042#{Mx[:gl_c]}").                            #escaped special character +          gsub(/\\\!/,"#{Mx[:gl_o]}#033#{Mx[:gl_c]}")                             #escaped special character +        if dob.obj=~/(?:https?:|ftp:|\{([^{}]+?)\}(?:#|:|[.]{1,2}\/))\S+/m +          if dob.obj=~/(?:^|[#{Mx[:gl_c]}#{Mx[:nbsp]} ])\{~\^ (?:.+?)\s*\}(?:(?:https?:|ftp:|:|[.]{1,2}\/)\S+?)\s*#{Mx[:en_a_o]}(.+?)#{Mx[:en_a_c]}/m +            dob.obj=dob.obj. +              gsub(/(^|[#{Mx[:gl_c]}#{Mx[:nbsp]} ])\{~\^ ([^}]+?)\s*\}((?:https?:|ftp:|:|[.]{1,2}\/)\S+?)\s*#{Mx[:en_a_o]}(.+?)#{Mx[:en_a_c]}/m, +                "\\1#{Mx[:lnk_o]}\\2#{Mx[:lnk_c]}\\3 #{Mx[:en_a_o]}\\3 \\4#{Mx[:en_a_c]}") # watch +          end +          if dob.obj=~/(?:^|[#{Mx[:gl_c]}#{Mx[:nbsp]} ])\{~\^ (?:.+?)\s*\}(?:(?:https?:|ftp:|:|[.]{1,2}\/)\S+?)([;,.]?)(?=\s|[#{Mx[:br_line]}#{Mx[:br_paragraph]}#{Mx[:br_nl]}]|$)/m +            dob.obj=dob.obj. +              gsub(/(^|[#{Mx[:gl_c]}#{Mx[:nbsp]} ])\{~\^ (.+?)\s*\}((?:https?:|ftp:|:|[.]{1,2}\/)\S+?)([;,.]?)(?=\s|[#{Mx[:br_line]}#{Mx[:br_paragraph]}#{Mx[:br_nl]}]|$)/m, +                "\\1#{Mx[:lnk_o]}\\2#{Mx[:lnk_c]}\\3\\4 #{Mx[:en_a_o]}\\3#{Mx[:en_a_c]} ") +          end +          dob.obj=dob.obj. +              gsub(/(^|[^#])\{\s*([^{}]+?)\s*\}((?:https?:|:|[.]{2}\/|#)\S+?)(?=\s|[#{Mx[:br_line]}#{Mx[:br_paragraph]}#{Mx[:br_nl]}#{Mx[:en_a_o]}#{Mx[:en_b_o]}]|$)/, +                "\\1#{Mx[:lnk_o]}\\2#{Mx[:lnk_c]}\\3").                                                                                                                    #linked (text or image, however text cannot include modified face, e.g. bold, ital, underline) +            gsub(/(^|[#{Mx[:gl_c]}#{Mx[:lnk_c]}#{Mx[:en_a_o]}#{Mx[:en_b_o]}(\s])((?:https?|ftp):\/\/\S+?\.[^>< ]+?)([,.;'"]?)(?=[\s#{Mx[:en_a_c]}#{Mx[:en_b_c]}#{Mx[:br_line]}#{Mx[:br_paragraph]}#{Mx[:br_nl]}]|$)/m, +              %{\\1#{Mx[:url_o]}\\2#{Mx[:url_c]}\\3}). +            gsub(/#{Mx[:lnk_c]}#(\S+?[^>< ]+?)([()\[\]]*[,.;:!?'"]{0,2})(?=[\s#{Mx[:en_a_c]}#{Mx[:en_b_c]}#{Mx[:br_line]}#{Mx[:br_paragraph]}#{Mx[:br_nl]}]|$)/m, +              %{#{Mx[:lnk_c]}#{Mx[:rel_o]}\\1#{Mx[:rel_c]}\\2}). +            gsub(/#{Mx[:lnk_c]}:(\S+?[^>< ]+?)([()\[\]]*[,.;:!?'"]{0,2})(?=[\s#{Mx[:en_a_c]}#{Mx[:en_b_c]}#{Mx[:br_line]}#{Mx[:br_paragraph]}#{Mx[:br_nl]}]|$)/m, +              %{#{Mx[:lnk_c]}#{Mx[:rel_o]}:\\1#{Mx[:rel_c]}\\2}). +            gsub(/#{Mx[:lnk_c]}[.]{2}\/(\S+?[^>< ]+?)([()\[\]]*[,.;:!?'"]{0,2})(?=[\s#{Mx[:en_a_c]}#{Mx[:en_b_c]}#{Mx[:br_line]}#{Mx[:br_paragraph]}#{Mx[:br_nl]}]|$)/m, +              %{#{Mx[:lnk_c]}#{Mx[:rel_o]}:\\1#{Mx[:rel_c]}\\2}) +        end +        if dob.obj=~/_(?:https?|ftp):\S+/m           # _http://url #CHECK +          dob.obj=dob.obj.gsub(/(^|[#{Mx[:gl_c]}#{Mx[:lnk_c]}#{Mx[:en_a_o]}#{Mx[:en_b_o]}(\s])(_(?:https?|ftp):\/\/\S+?\.[^>< ]+?)([,.;'"]?)(?=[\s#{Mx[:en_a_c]}#{Mx[:en_b_c]}#{Mx[:br_line]}#{Mx[:br_paragraph]}#{Mx[:br_nl]}]|$)/m, +            %{\\1#{Mx[:url_o]}\\2#{Mx[:url_c]}\\3}) +        end +        dob=fontface(dob) +        dob.obj=dob.obj. +          gsub(/<[:e]\s+(.+?)!?>/, +            "#{Mx[:en_a_o]}\\1#{Mx[:en_a_c]}").                                                                                                                             #not tested +          gsub(/(^|#{Mx[:br_nl]})\s*_\*\s*/, +            "\\1#{Mx[:gl_bullet]}").                                                                                                                                        #bullets, shortcut +          gsub(/=\{(.+?)\}/, +            "#{Mx[:idx_o]}\\1#{Mx[:idx_c]}"). +          gsub(/^\s*_([1-9])\*\s*/, +            "#{Mx[:pa_o]}:i\\1:\\1#{Mx[:pa_c]}#{Mx[:gl_bullet]}").                                                                                                          #bullets, shortcut +          gsub(/^\s*_([1-9])\s+/, +            "#{Mx[:pa_o]}:i\\1:\\1#{Mx[:pa_c]}").                                                                                                                           #indent +          gsub(/^\s*_([1-9])!\s+(.+?)\s*$/, +            "#{Mx[:pa_o]}:i\\1:\\1#{Mx[:pa_c]}#{Mx[:fa_bold_o]}\\2#{Mx[:fa_bold_c]} ").                                                                                     #indent bold +          gsub(/^\s*__([1-9])\s+/, +            "#{Mx[:pa_o]}:i0:\\1#{Mx[:pa_c]}").                                                                                                                             #hang +          gsub(/^\s*__([1-9])!\s+(.+?)\s*$/, +            "#{Mx[:pa_o]}:i0:\\1#{Mx[:pa_c]}#{Mx[:fa_bold_o]}\\2#{Mx[:fa_bold_c]} ").                                                                                       #hangdef +          gsub(/^\s*_([0-9])_([0-9])\s+/, +            "#{Mx[:pa_o]}:i\\1:\\2#{Mx[:pa_c]}").                                                                                                                           #hang +          gsub(/^\s*_([0-9])_([0-9])!\s+(.+?)\s*$/, +            "#{Mx[:pa_o]}:i\\1:\\2#{Mx[:pa_c]}#{Mx[:fa_bold_o]}\\3#{Mx[:fa_bold_c]} ").                                                                                     #hangdef +          gsub(/<:hi>/,"#{Mx[:fa_hilite_o]}").                                                                                                                              #'<span style="background-color: rgb(255,240,196)">'). # bright yellow rgb(255,255,0) pale yellow rgb(255,255,200) +          gsub(/<:\/hi>/,"#{Mx[:fa_hilite_c]}"). #'</span>'). +          gsub(/(#{Mx[:gr_o]}verse#{Mx[:gr_c]}.+)/m,"\\1\n"). +          gsub(/[ ]+($)/,'\1'). +          gsub(/\{\s*(.+?)\s*\}(https?:\S+?)([;,.]?)(?=\s|[#{Mx[:br_line]}#{Mx[:br_paragraph]}#{Mx[:br_nl]}#{Mx[:en_a_o]}#{Mx[:en_b_o]}]|$)/, +            "#{Mx[:lnk_o]}\\1#{Mx[:lnk_c]}#{Mx[:url_o]}\\2#{Mx[:url_c]}\\3").                                                                                               #any remaining linked text or image +          gsub(/\{\s*(.+?)\s*\}(#{Mx[:url_o]}\S+?#{Mx[:url_c]})/, +            "#{Mx[:lnk_o]}\\1#{Mx[:lnk_c]}\\2").                                                                                                                            #any remaining linked text or image +          gsub(/(^|\s)([a-zA-Z0-9._-]+\@\S+?\.[a-zA-Z0-9._-]+)/,"\\1#{Mx[:url_o]}\\2#{Mx[:url_c]}"). +          gsub(/(^|[ ])\{\s*(.+?)\s*\}(\S+?)([;,.]?)(?=\s|[#{Mx[:br_line]}#{Mx[:br_paragraph]}#{Mx[:br_nl]}#{Mx[:en_a_o]}#{Mx[:en_b_o]}]|$)/, +            "\\1#{Mx[:lnk_o]}\\2#{Mx[:lnk_c]}\\3\\4").                                                                                                                      #any remaining linked text or image +          gsub(/\{\s*(.+?)\s*\}#([a-zA-Z0-9][a-zA-Z0-9_-]*)([;,.]?)(?=\s|[#{Mx[:br_line]}#{Mx[:br_paragraph]}#{Mx[:br_nl]}#{Mx[:en_a_o]}#{Mx[:en_b_o]}]|$)/, +            "#{Mx[:lnk_o]}\\1#{Mx[:lnk_c]}#{Mx[:rel_o]}\\2#{Mx[:rel_c]}\\3").                                                                                               #any remaining linked text or image, check need +          gsub(/\{\s*(.+?)\s*\}(#{Mx[:rel_o]}\S+?#{Mx[:rel_c]})/, +            "#{Mx[:lnk_o]}\\1#{Mx[:lnk_c]}\\2").                                                                                                                            #any remaining linked text or image, check need +          gsub(/\{\s*(.+?)\s*\}(image)/, +            "#{Mx[:lnk_o]}\\1#{Mx[:lnk_c]}\\2")                                                                                                                             #linked image +      elsif dob.is==:table +        dob=fontface(dob) +      elsif dob.is ==:code +        dob.obj=dob.obj. +          gsub(/#{Mx[:meta_o]}(\S+?)#{Mx[:meta_c]}\s*/,'@\1: '). +          gsub(/(^|#{Mx[:gl_c]}|\s)<(?:br(?: \/)?)>([\s,.]|$)/,'\1<br>\2') #convert <br> <br /> back, clumsy +        if dob.number_ +          codeline=[] +          ln=1 +          dob.obj.split(/#{Mx[:gr_o]}codeline#{Mx[:gr_c]}|<br(?: \/)?>|\n/).each_with_index do |cl,i| +            unless i == 0 +              cl=cl.gsub(Mx[:br_nl],'') +              w=3-ln.to_s.length +              cl = "#{ln}#{Mx[:nbsp]*w}#{Mx[:vline]}#{cl}#{Mx[:br_nl]}" +              ln +=1 +            end +            codeline << cl +          end +          codeline= codeline.join("") +          dob.obj=codeline +        else +          dob.obj=dob.obj.gsub(/#{Mx[:gr_o]}codeline#{Mx[:gr_c]}/,"\n") +        end +        dob +      else # @\S+?: +      end +      dob +    end +    def tech                                                                       #script markup planned to be more strict for technical documents +      # *{emphasis}*        e{emphasis}e       <strong>emphasis</strong> +      # !{bold text}!       b{bold}b           <b>bold text</b> +      # _{underline}_       u{underline}u      <u>underline</u> +      # /{italics}/         i{italics}i        <i>italics</i> +      # "{citation}"        c{citation}c       <cite>citation</cite> +      # ^{superscript}^                        <sup>superscript</sup> +      # ,{subscript},                          <sub>subscript</sub> +      # +{inserted text}+                      <ins>inserted text</ins> +      # -{deleted text}-                       <del>deleted text</del> +      # #{monospace text}# +      # {url address}:url +      # {image.png}imageurl +      # {image.png}png +      # ~{endnote}~ +      # +1                  <!i1!> +      # +2                  <!i2!> +      puts 'tech' +      @data.each do |line| +        line=line. +          gsub(/(^|\s+|['"]|#{Mx[:fa_o_c]}|#{Mx[:fa_c]}|[\(\[]|\>)e\{(.+?)\}e/, +            "\\1#{@emph[:o]}\\2#{@emph[:c]}").                                                        #emphasis +          gsub(/(^|\s+|['"]|#{Mx[:fa_o_c]}|#{Mx[:fa_c]}|[\(\[]|\>)b\{(.+?)\}b/, +            "\\1#{Mx[:fa_bold_o]}\\2#{Mx[:fa_bold_c]}").                                              #bold +          gsub(/(^|\s+|['"]|#{Mx[:fa_o_c]}|#{Mx[:fa_c]}|[\(\[]|\>)u\{(.+?)\}u/, +            "\\1#{Mx[:fa_underscore_o]}\\2#{Mx[:fa_underscore_c]}").                                  #underscore +          gsub(/(^|\s+|['"]|#{Mx[:fa_o_c]}|#{Mx[:fa_c]}|[\(\[]|\>)c\{(.+?)\}c/, +            "\\1#{Mx[:fa_cite_o]}\\2#{Mx[:fa_c_o]}cite#{Mx[:fa_c]}").                                 #cite +          gsub(/(^|\s+|['"]|#{Mx[:fa_o_c]}|#{Mx[:fa_c]}|[\(\[]|\>)i\{(.+?)\}i/, +            "\\1#{Mx[:fa_italics_o]}\\2#{Mx[:fa_italics_c]}").                                        #italics +          gsub(/(^|\s+|['"]|#{Mx[:fa_o_c]}|#{Mx[:fa_c]}|[\(\[]|\>)!\{(.+?)\}!/, +            "\\1#{Mx[:fa_bold_o]}\\2#{Mx[:fa_bold_c]}").                                              #bold +          gsub(/(^|\s+|['"]|#{Mx[:fa_o_c]}|#{Mx[:fa_c]}|[\(\[]|\>)\*\{(.+?)\}\*/, +            "\\1#{@emph[:o]}\\2#{@emph[:c]}").                                                        #emphasis +          gsub(/(^|\s+|['"]|#{Mx[:fa_o_c]}|#{Mx[:fa_c]}|[\(\[]|\>)_\{(.+?)\}_/, +            "\\1#{Mx[:fa_underscore_o]}\\2#{Mx[:fa_underscore_c]}").                                  #underscore +          gsub(/(^|\s+|['"]|#{Mx[:fa_o_c]}|#{Mx[:fa_c]}|[\(\[]|\(|\>)\/\{(.+?)\}\//, +            "\\1#{Mx[:fa_italics_o]}\\2#{Mx[:fa_italics_c]}").                                        #italics +          gsub(/(^|\s+|['"]|#{Mx[:fa_o_c]}|#{Mx[:fa_c]}|\(|\>)\"\{(.+?)\}\"/, +            "\\1#{Mx[:fa_cite_o]}\\2#{Mx[:fa_c_o]}cite#{Mx[:fa_c]}"). +          gsub(/(^|\s+|['"]|#{Mx[:fa_o_c]}|#{Mx[:fa_c]}|\(|\>)\^\{(.+?)\}\^/, +            "\\1#{Mx[:fa_superscript_o]}\\2#{Mx[:fa_superscript_c]}"). +          gsub(/(^|\s+|['"]|#{Mx[:fa_o_c]}|#{Mx[:fa_c]}|\(|\>)9\{(.+?)\}9/, +            "\\1#{Mx[:fa_superscript_o]}\\2#{Mx[:fa_superscript_c]}"). +          gsub(/(^|\s+|['"]|#{Mx[:fa_o_c]}|#{Mx[:fa_c]}|\(|\>),\{(.+?)\},/, +            "\\1#{Mx[:fa_subscript_o]}\\2#{Mx[:fa_subscript_c]}"). +          gsub(/(^|\s+|['"]|#{Mx[:fa_o_c]}|#{Mx[:fa_c]}|\(|\>)6\{(.+?)\}6/, +            "\\1#{Mx[:fa_subscript_o]}\\2#{Mx[:fa_subscript_c]}"). +          gsub(/(^|\s+|['"]|#{Mx[:fa_o_c]}|#{Mx[:fa_c]}|\(|\>)\+\{(.+?)\}\+/, +            "\\1#{Mx[:fa_insert_o]}\\2#{Mx[:fa_insert_c]}"). +          gsub(/(^|\s+|['"]|#{Mx[:fa_o_c]}|#{Mx[:fa_c]}|\(|\>)v\{(.+?)\}v/, +            "\\1#{Mx[:fa_insert_o]}\\2#{Mx[:fa_insert_c]}"). +          gsub(/(^|\s+|['"]|#{Mx[:fa_o_c]}|#{Mx[:fa_c]}|\(|\>)-\{(.+?)\}-/, +            "\\1#{Mx[:fa_strike_o]}\\2#{Mx[:fa_strike_c]}"). +          gsub(/(^|\s+|['"]|#{Mx[:fa_o_c]}|#{Mx[:fa_c]}|\(|\>)x\{(.+?)\}x/, +            "\\1#{Mx[:fa_strike_o]}\\2#{Mx[:fa_strike_c]}"). +          gsub(/(^|\s+|['"]|#{Mx[:fa_o_c]}|#{Mx[:fa_c]}|\(|\>)\*(\S+?)\*/, +            "\\1#{@emph[:o]}\\2#{@emph[:c]}").                                                        #emphasise single word, watch +          gsub(/(^|\s+|['"]|#{Mx[:fa_o_c]}|#{Mx[:fa_c]}|\(|\>)\!(\S+?)\!/, +            "\\1#{Mx[:fa_bold_o]}\\2#{Mx[:fa_bold_c]}").                                              #bold single word, watch +          gsub(/(^|\s+|['"]|#{Mx[:fa_o_c]}|#{Mx[:fa_c]}|\(|\>)\/([\(\)a-zA-Z0-9']+?)\/([ ,.;:'"~$]|[^a-zA-Z0-9])/, +            "\\1#{Mx[:fa_italics_o]}\\2#{Mx[:fa_italics_c]}\\3").                                     #italics single word, watch +          gsub(/(^|\s+|['"]|#{Mx[:fa_o_c]}|#{Mx[:fa_c]}|\(|\>)_(\S+?)_/, +            "\\1#{Mx[:fa_underscore_o]}\\2#{Mx[:fa_underscore_c]}").                                  #underscore single word, watch +          gsub(/(^|\s+|['"]|#{Mx[:fa_o_c]}|#{Mx[:fa_c]}|\(|\>)\^(\S+?)\^/, +            "\\1#{Mx[:fa_superscript_o]}\\2#{Mx[:fa_superscript_c]}").                                #check  #superscript single word, watch digit added +          gsub(/^\s*_\([1-9]\)\(\*\+\)\s*/, +            "#{Mx[:pa_o]}:i\\1#{Mx[:pa_c]}#{Mx[:fa_o]}\\2#{Mx[:fa_c_o]}").                            #bullets, shortcut +          gsub(/^\s*_\([1-9]\)\s+/, +            "#{Mx[:pa_o]}:i\\1#{Mx[:pa_c]}"). #watch +          gsub(/^\s*__\([1-9]\)\s+/, +            "#{Mx[:pa_o]}:h\\1#{Mx[:pa_c]}"). #watch +          #line.gsub(/^\s*__\([1-9]\)!\s+/, +          #  "#{Mx[:pa_o]}:hd\\1#{Mx[:pa_c]}"). #watch +          gsub(/#{Mx[:br_line]}\s*_[12]\s+/, +            "#{Mx[:br_line]} ")                                                                      #indent used in endnotes, not implemented, replace when ready with: line.gsub(/(?:<br>|<br \/>)\s*_([12])\s+/,'<br><:i\1> ') +      end +      @data +    end +  end +end +__END__ +#+END_SRC + +** ao_endnotes.rb + +#+BEGIN_SRC ruby  :tangle "../lib/sisu/ao_endnotes.rb" +# <<sisu_document_header>> +module SiSU_AO_Endnotes +  class Endnotes +    def initialize(md,data,endnote_array=nil) +      @md,@data,@endnote_array= +      md, data, endnote_array +      @endnote_counter, +        @endnote_counter_asterisk, +        @endnote_counter_dag= +        1,1,1 +    end +    def endnotes +      data=@data +      endnote_ref=1 +      @tuned_file=data.each.map do |dob| +                                                                               # manually numbered endnotes <!e(\d)!> <!e_(\d)!> --> +        if @md.opt.selections.str =~/--no-asterisk|--no-annotate/ +          dob.obj=dob.obj. +            gsub(/#{Mx[:en_b_o]}\s.+?#{Mx[:en_b_c]}/,'') +        end +        if @md.opt.selections.str =~/--no-dagger|--no-annotate/ +          dob.obj=dob.obj. +            gsub(/#{Mx[:en_b_o]}[+]\s.+?#{Mx[:en_b_c]}/,'') +        end +        if (defined? dob.obj) \ +        && (defined? dob.is) \ +        && dob.is !=:code +          case dob.obj                                                         # auto-numbered endnotes <!e!> <!e_!> --> +          when /#{Mx[:en_a_o]}.+?#{Mx[:en_a_c]}|#{Mx[:en_b_o]}[*+]\s+.+?#{Mx[:en_b_c]}/ +            dob.obj=dob.obj. +              gsub(/\s*(#{Mx[:en_a_c]}|#{Mx[:en_b_c]})/,'\1') +            word_mode=dob.obj.scan(/\S+/m) +            word_mode=endnote_call_number(word_mode) +            dob.obj=word_mode.join(' ') +            endnote_ref+=1 +          when /~\^(?:\s|$)/                                              #%note inserts endnotes previously gathered from /^(<!e[:_]!>|[-~]\{{3})/ (in earlier loop) +            word_mode=dob.obj.scan(/\S+/m) +            word_mode=endnote_call_number(word_mode) +            dob.obj=word_mode.join(' ') +            endnote_ref+=1 +          end +        end +        dob +      end.flatten +      @endnote_counter, +        @endnote_counter_asterisk, +        @endnote_counter_dag= +        1,1,1 +      @tuned_file +    end +    def endnote_call_number(words) +      words.each do |word| +        case word +        when /#{Mx[:en_a_o]}/ +          unless word =~/#{Mx[:en_a_o]}[*+]+/ +            word.gsub!(/#{Mx[:en_a_o]}/, +              "#{Mx[:en_a_o]}#{@endnote_counter} ") +            @endnote_counter+=1 +          end +        when /#{Mx[:en_b_o]}/ +          if word =~/#{Mx[:en_b_o]}[+]/ +            word.gsub!(/#{Mx[:en_b_o]}[+]/, +              "#{Mx[:en_b_o]}\+#{@endnote_counter_dag} ") +            @endnote_counter_dag+=1 +          else +            word.gsub!(/#{Mx[:en_b_o]}[*]?/, +              "#{Mx[:en_b_o]}\*#{@endnote_counter_asterisk} ") +            @endnote_counter_asterisk+=1 +          end +        when /~\^/ +          if @endnote_array +            word.gsub!(/~\^/, +              "#{@endnote_array[@endnote_counter-1]}") +            @endnote_counter+=1 +          end +        end +      end +    end +  end +end +__END__ +#+END_SRC + +* document header + +#+NAME: sisu_document_header +#+BEGIN_SRC text +encoding: utf-8 +- Name: SiSU + +  - Description: documents, structuring, processing, publishing, search +    abstraction + +  - Author: Ralph Amissah +    <ralph.amissah@gmail.com> + +  - Copyright: (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, +    2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2019, +    2020, 2021, Ralph Amissah, +    All Rights Reserved. + +  - License: GPL 3 or later: + +    SiSU, a framework for document structuring, publishing and search + +    Copyright (C) Ralph Amissah + +    This program is free software: you can redistribute it and/or modify it +    under the terms of the GNU General Public License as published by the Free +    Software Foundation, either version 3 of the License, or (at your option) +    any later version. + +    This program is distributed in the hope that it will be useful, but WITHOUT +    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +    FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +    more details. + +    You should have received a copy of the GNU General Public License along with +    this program. If not, see <http://www.gnu.org/licenses/>. + +    If you have Internet connection, the latest version of the GPL should be +    available at these locations: +    <http://www.fsf.org/licensing/licenses/gpl.html> +    <http://www.gnu.org/licenses/gpl.html> + +    <http://www.sisudoc.org/sisu/en/manifest/gpl.fsf.html> + +  - SiSU uses: +    - Standard SiSU markup syntax, +    - Standard SiSU meta-markup syntax, and the +    - Standard SiSU object citation numbering and system + +  - Homepages: +    <http://www.sisudoc.org> + +  - Git +    <https://git.sisudoc.org/projects/> +    <https://git.sisudoc.org/projects/?p=software/sisu.git;a=summary> +    <https://git.sisudoc.org/projects/?p=markup/sisu-markup-samples.git;a=summary> +#+END_SRC diff --git a/org/cgi.org b/org/cgi.org new file mode 100644 index 00000000..b127d405 --- /dev/null +++ b/org/cgi.org @@ -0,0 +1,1459 @@ +-*- mode: org -*- +#+TITLE:       sisu cgi +#+DESCRIPTION: documents - structuring, various output representations & search +#+FILETAGS:    :sisu:cgi: +#+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 + +* cgi +** cgi.rb + +#+BEGIN_SRC ruby  :tangle "../lib/sisu/cgi.rb" +# <<sisu_document_header>> +module  SiSU_CGI                                        #% database building documents +  require_relative 'se'                                 # se.rb +  require_relative 'cgi_pgsql'                          # cgi_pgsql.rb +  require_relative 'cgi_sqlite'                         # cgi_sqlite.rb +  class SearchSQL +    def initialize(opt) +      @opt=opt +      @webserv=@opt.files[0].to_s.strip +    end +    def read +      if @opt.act[:sample_search_form][:db]==:pg        # cgi_pgsql.rb +        SiSU_CGI_PgSQL::SearchPgSQL.new(@opt,@webserv).pgsql +      elsif @opt.act[:sample_search_form][:db]==:sqlite # cgi_sqlite.rb +        SiSU_CGI_SQLite::SearchSQLite.new(@opt,@webserv).sqlite +      else +        puts <<-WOK +  please select database type for which sample search form should be built (pgsql or sqlite) +    sisu --sample-search-form --db=sqlite +    sisu --sample-search-form --db=pg +  other options include +     --webserv-cgi='[cgi-server-name]' +     --webserv-output='[sisu-output-server-with-base-path]' +        WOK +      end +    end +  end +end +__END__ +#+END_SRC + +** cgi_sqlite.rb + +#+BEGIN_SRC ruby  :tangle "../lib/sisu/cgi_sqlite.rb" +# <<sisu_document_header>> +module  SiSU_CGI_SQLite                                 #% database building documents +  require_relative 'se'                                 # se.rb +  require_relative 'cgi_sql_common'                     # cgi_sql_common.rb +    include SiSU_CGI_SQL +  class SearchSQLite < CGI_Common +    def initialize(opt,webserv) +      @opt,@webserv=opt,webserv +      @cX=SiSU_Screen::Ansi.new(opt.act[:color_state][:set]).cX +      @env=SiSU_Env::InfoEnv.new('',opt) +      @image_src="#{@env.url.webserv_cgi(opt)}/_sisu/image_sys" +      @name_of={} +      @name_of[:output_dir_structure]=if opt.dir_structure_by.to_s =~/(?:language|filetype|filename)/ +        opt.dir_structure_by.to_s +      else 'language' +      end +      @name_of[:lingual]=if opt.lingual.to_s =~/(?:mono|multi)/ +        opt.lingual.to_s +      else 'multi' +      end +      @name_of[:host_url_cgi]=%q{http://#{ENV['HTTP_HOST']}#{ENV['PATH_INFO']}} +      @name_of[:host_url_docs]=%q{http://#{ENV['HTTP_HOST']}} +      @name_of[:cgi_script]=%q{#{ENV['SCRIPT_NAME']}} +      @image_src=%q{http://#{ENV['HTTP_HOST']}/_sisu/image_sys} +      @common=SiSU_CGI_SQL::CGI_Common.new(@webserv,opt,@image_src,@env) +      @cgi_file_name=@env.url.cgi_sample_search_form_name(opt) +      @name_of_sqlite_db_file='sisu_sqlite.db' +    end +    def sqlite +      serve=[] +      Dir.foreach(@env.path.webserv) do |x| +        if x !~/^\./ \ +        and FileTest.directory?("#{@env.path.webserv}/#{x}") +          if FileTest.file?("#{@env.path.webserv}/#{x}/#{@name_of_sqlite_db_file}") +            serve << x unless x =~/^_\S+/ +          end +        end +      end +      serve=serve.sort +      f1,f2,f3='','','' +      serve.each do |x| +        f1 << %{              <option value="#{Db[:name_prefix]}#{x}">#{x}</option>\n} +      end +      f2 <<  %{          selected_db=case cgi['db']\n} +      serve.each do |x| +        f2 << %{           when /#{Db[:name_prefix]}#{x}/ then '<option value="#{Db[:name_prefix]}#{x}">#{x}</option>'\n} +      end +      f2 << "          end\n" +      f3 << %{          db_name='#{@name_of_sqlite_db_file}'\n} +      f3 << %{          db_sqlite=case cgi['db']\n} +      serve.each do |x| +        f3 << %{          when /#{Db[:name_prefix]}#{x}/ then "#{@env.path.webserv}/#{x}/\#{db_name}"\n} +      end +      f3 << %{           else  "#{@env.path.webserv}/#{serve[0]}/\#{db_name}"\n          end\n} +      if FileTest.writable?('.') +        output=File.open(@cgi_file_name,'w') +        output << header0 << header1 << header_desc << header2 << f1 << buttons1 << buttons2 << search_request << search_statement << search_statement_common << search_query1 << @common.pages << search_query2 << @common.tail << @common.main1 << f2 << f3 << dbi_connect << @common.main2 << @common.dir_structure << @common.main3 +        puts <<-WOK +            generated sample search form: #{@cX.green}#{@cgi_file_name}#{@cX.off} +            default database name:     #{@cX.green}#{Db[:name_prefix]}#{@env.path.base_markup_dir_stub}#{@cX.off} (#{@env.path.base_markup_dir_stub}) +            cgi & db host on:          #{@cX.blue}#{@env.url.webserv_base_cgi(@opt)}#{@cX.off} +              to modify use:           #{@cX.brown}sisu --db-sqlite --webserv-search='#{@env.url.webserv_base_cgi(@opt)}'#{@cX.off} +            sisu output on:            #{@cX.blue}#{@env.url.webserv_files_from_db(@opt)}#{@cX.off} +              to modify use:           #{@cX.brown}sisu --db-sqlite --webserv-output='#{@env.url.webserv_files_from_db(@opt)}'#{@cX.off} +            cgi search form link name: #{@cX.green}#{@env.url.cgi_sample_search_form_name(@opt)}#{@cX.off} +              to modify use:           #{@cX.brown}sisu --db-sqlite --cgi-search-form-name='#{@env.url.cgi_sample_search_form_name(@opt)}'#{@cX.off} +            #{@cX.fuchsia}(settings priority: command line; sisurc.yml; else defaults)#{@cX.off} + +            #{@cX.fuchsia}NOTE it is first necessary to create the database and tables and populate it#{@cX.off} + +            sisu --sqlite --dropall                          # removes existing postgresql db & tables +            sisu --sqlite --createall -v                     # creates postgresql db & tables +            sisu --sqlite --update -v *.sst  *.ssm           # populate the db +            sisu --sample-search-form --sqlite               # creates the postgresql search form +                                                             # this should be done after creating the db +                                                             # to be searched +            sisu --webrick &                                 # starts ruby webrick web server + +            # if necessary make the directory '/usr/lib/cgi-bin' +            # here we copy the postgresql search form to cgi-bin +            # (copy #{@cgi_file_name} to your cgi directory) +            # set file permissions to 755 +        WOK +        a=case @webserv +        when /pwd/ then '' +        else <<-WOK + +              sudo cp -vi #{Dir.pwd}/#{@cgi_file_name} /usr/lib/cgi-bin/.; \\ +              sudo chmod -v 755  /usr/lib/cgi-bin/#{@cgi_file_name} +          WOK +        end +        b='(to create and populate sisu sqlite database see "man sisu" and in particular the -d flag)' +        SiSU_Screen::Ansi.new(@opt.act[:color_state][:set],a,b).warn +        a=<<-WOK + +              #{@env.webserv_base_cgi(@opt)}/cgi-bin/#{@cgi_file_name} + +        WOK +        SiSU_Screen::Ansi.new(@opt.act[:color_state][:set],a).print_blue +      else puts "failed in attempt to write #{@cgi_file_name} to present directory, is directory writable?" +      end +    end +    def header0 +      <<-WOK_SQL +#!/usr/bin/env ruby +=begin +#{about} + * Description: generates naive cgi search form for search of sisu database (sqlite) +#{gpl} +=end +      begin +        require 'cgi' +        require 'fcgi' +        require 'sqlite3' +      rescue LoadError +        puts 'cgi, fcgi or sqlite3 NOT FOUND (LoadError)' +      end +      @stub_default='sisu_sqlite' +      @image_src="#{@image_src}" +      @hosturl_cgi="#{@name_of[:host_url_cgi]}" +      @hosturl_files="#{@name_of[:host_url_docs]}" +      @output_dir_structure_by='#{@name_of[:output_dir_structure]}' +      @lingual='#{@name_of[:lingual]}' +      @db_name_prefix='#{Db[:name_prefix]}' +      @base="#{@name_of[:host_url_cgi]}#{@name_of[:cgi_script]}" +      WOK_SQL +    end +    def search_statement +      <<-'WOK_SQL' +      class DBI_SearchString +        def initialize(l,t,q,cse=false) +          @l,@t,@q=l,t,q +        end +        def string +          search={ search: [], flag: false } +          if @t =~/\S+/ or @q =~/\S+/ +            if @t =~/\S+/    then unescaped_search=CGI.unescape(@t) +            elsif @q =~/\S+/ then unescaped_search=CGI.unescape(@q) +            end +            search_construct=[] +            unescaped_search=unescaped_search.gsub(/\s*(AND|OR)\s*/,"%' \) \\1 #{@l} LIKE \( '%"). +              gsub(/(.+)/,"#{@l} LIKE \( '%\\1%' \)") +            search_construct << unescaped_search +            search_construct=search_construct.join(' ') +            search[:search]                    << search_construct +            search[:flag]=true +            search +          end +          search +        end +      end +      WOK_SQL +    end +    def search_query1 +      <<-'WOK_SQL' +          @search_text='' +          @search_text=search[:text].flatten.join(' AND ') +          @search_text=@search_text.gsub(/(doc_objects\.clean\s+LIKE\s+\(\s*'%[^']+%'\s*\)\s+(?:(?:AND|OR)\s+doc_objects\.clean\s+LIKE\s+\(\s*'%[^']+%'\s*\))+)/,'(\1)') +        end +      WOK_SQL +    end +    def search_query2 +      <<-'WOK_SQL' +        def sql_select_body +          limit ||=@@limit +          offset ||=@@offset +          @sql_statement[:body]=%{SELECT metadata_and_text.title, metadata_and_text.creator_author, metadata_and_text.src_filename, metadata_and_text.language_document_char, metadata_and_text.notes_suffix, doc_objects.body, doc_objects.seg, doc_objects.ocn, metadata_and_text.tid FROM doc_objects, metadata_and_text WHERE #{@search_text} AND doc_objects.metadata_tid = metadata_and_text.tid ORDER BY metadata_and_text.language_document_char, metadata_and_text.title, metadata_and_text.src_filename, doc_objects.ocn} +          @sql_statement[:range]=%{LIMIT #{limit} OFFSET #{offset} ;} +          select=@sql_statement[:body] + ' ' + @sql_statement[:range] +          select +        end +        def sql_select_body_format +          %{<font color="#666666" size="2">#{sql_select_body}</font>} +        end +        def contents +          @conn.execute(sql_select_body) +        end +      end +      WOK_SQL +    end +    def dbi_connect +      <<-'WOK_SQL' +          @conn=SQLite3::Database.new(db_sqlite) +          @conn.results_as_hash=true +      WOK_SQL +    end +  end +end +__END__ +#+END_SRC + +** cgi_pgsql.rb + +#+BEGIN_SRC ruby  :tangle "../lib/sisu/cgi_pgsql.rb" +# <<sisu_document_header>> +module  SiSU_CGI_PgSQL                                  #% database building documents +  require_relative 'se'                                 # se.rb +  require_relative 'cgi_sql_common'                     # cgi_sql_common.rb +    include SiSU_CGI_SQL +  class SearchPgSQL < CGI_Common +    def initialize(opt,webserv) +      @opt,@webserv=opt,webserv +      @cX=SiSU_Screen::Ansi.new(opt.act[:color_state][:set]).cX +      @env=SiSU_Env::InfoEnv.new('',opt) +      @sys=SiSU_Env::SystemCall.new +      @db=SiSU_Env::InfoDb.new +      get_init=SiSU_Env::GetInit.new +      @rc=get_init.sisu_yaml.rc +      @name_of={} +      @name_of[:output_dir_structure]=if opt.dir_structure_by.to_s =~/(?:language|filetype|filename)/ +        opt.dir_structure_by.to_s +      else 'language' +      end +      @name_of[:lingual]=if opt.lingual.to_s =~/(?:mono|multi)/ +        opt.lingual.to_s +      else 'multi' +      end +      @name_of[:db]=if defined? @rc['search'] \ +      and defined? @rc['search']['sisu'] \ +      and defined? @rc['search']['sisu']['action'] \ +      and @rc['search']['sisu']['action'] =~/https?:\/\/\S+?\.cgi/ \ +      and defined? @rc['search']['sisu']['db'] \ +      and @rc['search']['sisu']['db'] =~/\S+/ +        @rc['search']['sisu']['db'] +      else +        @env.path.base_markup_dir_stub #'sisu' #breaks if not present +      end +      @name_of[:host_url_cgi]=%q{http://#{ENV['HTTP_HOST']}#{ENV['PATH_INFO']}} +      @name_of[:host_url_docs]=%q{http://#{ENV['HTTP_HOST']}} +      @name_of[:cgi_script]=%q{#{ENV['SCRIPT_NAME']}} +      @name_of[:user]=@db.psql.user(opt) +      @image_src=%q{http://#{ENV['HTTP_HOST']}/_sisu/image_sys} +      @common=SiSU_CGI_SQL::CGI_Common.new(@webserv,opt,@image_src,@env) +      @cgi_file_name=@env.url.cgi_sample_search_form_name(opt) +    end +    def pgsql +      serve=[] +      if @sys.psql +        available_db_table=`psql --list`                            # system call requires psql +        available_db=available_db_table.scan(/(#{Db[:name_prefix]}\S+)/) if not available_db_table.nil? +        if available_db \ +        and available_db.is_a?(Array) +          available_db.flatten.each do |x| +            serve << x.gsub(/#{Db[:name_prefix]}(\S+)/,'\1') +          end +        else STDERR.puts "WARNING: no postgresql database available, (have you created one?)" +        end +        serve=serve.sort +        f1,f2='','' +        serve.each do |x| +          f1 << %{              <option value="#{Db[:name_prefix]}#{x}">#{x}</option>\n} unless x =~/apache|sisu\/image/ #check +        end +      end +      f2 << %q{          selected_db=%{<option value="#{@db_name_prefix}#{@stub}">#{@stub}</option>}} + "\n" +      if FileTest.writable?('.') +        output=File.open(@cgi_file_name,'w') +        output << header0 << header1 << header_desc << header2 << f1 << buttons1 << buttons1_pgsql << buttons2 << search_request << search_statement << search_statement_common << search_query1 << @common.pages << search_query2 << @common.tail << @common.main1 << f2 << dbi_connect << @common.main2 << @common.dir_structure << @common.main3 +        puts <<-WOK +            generated sample search form: #{@cX.green}#{@cgi_file_name}#{@cX.off} +            default database name:     #{@cX.green}#{Db[:name_prefix]}#{@name_of[:db]}#{@cX.off} (#{@name_of[:db]}) +            db user:                   #{@cX.green}#{@name_of[:user]}#{@cX.off} +              to modify use:           #{@cX.brown}sisu --db-pg --db-user='#{@name_of[:user]}'#{@cX.off} + +            #{@cX.fuchsia}BASED ON ALREADY EXISTING databases#{@cX.off} (default database name: #{@db.psql.db}) +            NOTE it is first necessary to createdb, +            use sisu to create the tables & populate the postgresql db + +            the database to be used for this directory (#{@db.psql.db}) +            will have to be created manually if it does not exist: +            using postgresql tools directly (the following may work): +              (i) if you are not yet a postgresql user, +                #{@cX.brown}sudo su postgres +                  createuser -d -a #{@env.user} +                exit#{@cX.off} +              (ii) create the database: +                #{@cX.brown}createdb #{@db.psql.db}#{@cX.off} +            [for a list of existing databases try 'psql --list']" + +            you can use sisu to create the database tables and populate the database with documents + +            sisu --pg --dropall                              # removes existing postgresql db & tables +            sisu --pg --createall -v                         # creates postgresql db & tables +            sisu --pg --update -v *.sst  *.ssm               # populate the db +            sisu --sample-search-form --db-pg                # creates the postgresql search form +                                                             # this should be done after creating the db +                                                             # to be searched +            sisu --webrick &                                 # starts ruby webrick web server + +            # if necessary make the directory '/usr/lib/cgi-bin' +            # here we copy the postgresql search form to cgi-bin +            # (copy #{@cgi_file_name} to your cgi directory) +            # set file permissions to 755 +        WOK +        a=case @webserv +        when /pwd/ then '' +        else <<-WOK + +              sudo cp -vi #{Dir.pwd}/#{@cgi_file_name} /usr/lib/cgi-bin/.; \\ +              sudo chmod -v 755  /usr/lib/cgi-bin/#{@cgi_file_name} +          WOK +        end +        SiSU_Screen::Ansi.new(@opt.act[:color_state][:set],a).warn +        a=<<-WOK +              #{@env.webserv_base_cgi(@opt)}/cgi-bin/#{@cgi_file_name} +        WOK +        SiSU_Screen::Ansi.new(@opt.act[:color_state][:set],a).print_blue +        a="\n\t(to create and populate postgresql database see 'man sisu' and in particular the --pg option)\n\t[the database to be used for this directory (#{@db.psql.db}) will have to be created manually if it does not exist,\n\tusing postgresql tools directly: 'createdb #{@db.psql.db}' for a list of existing databases try 'psql --list']" +        SiSU_Screen::Ansi.new(@opt.act[:color_state][:set],a).txt_grey +      else puts 'failed in attempt to write #{@cgi_file_name} to present directory,  is directory writable?' +      end +    end +    def header0 +      <<-WOK_SQL +#!/usr/bin/env ruby +=begin +#{about} + * Description: generates naive cgi search form for search of sisu database (pgsql) +#{gpl} +=end +      begin +        require 'cgi' +        require 'fcgi' +        require 'pg' +      rescue LoadError +        puts 'cgi, fcgi or pg NOT FOUND (LoadError)' +      end +      @stub_default='#{@name_of[:db]}' +      @image_src="#{@image_src}" +      @hosturl_cgi="#{@name_of[:host_url_cgi]}" +      @hosturl_files="#{@name_of[:host_url_docs]}" +      @output_dir_structure_by='#{@name_of[:output_dir_structure]}' +      @lingual='#{@name_of[:lingual]}' +      @port='#{@db.psql.port}' +      @db_name_prefix='#{Db[:name_prefix]}' +      @user='#{@name_of[:user]}'  # check user name for access to pg database: e.g. www-data or '#{@env.user}' +      @base="#{@name_of[:host_url_cgi]}#{@name_of[:cgi_script]}" +      WOK_SQL +    end +    def search_statement +      <<-'WOK_SQL' +      class DBI_SearchString +        def initialize(l,t,q,cse=false) +          @l,@t,@q,@c=l,t,q,cse +        end +        def string +          search={ search: [], flag: false } +          if @t =~/\S+/ or @q =~/\S+/ +            if @t =~/\S+/    then unescaped_search=CGI.unescape(@t) +            elsif @q =~/\S+/ then unescaped_search=CGI.unescape(@q) +            end +            search_construct=[] +            unescaped_search=if @c +              unescaped_search.gsub(/\s*(AND|OR)\s*/,"' \) \\1 #{@l}~\( '"). +                gsub(/(.+)/,"#{@l}~\( '\\1' \)") +            else +              unescaped_search.gsub(/\s*(AND|OR)\s*/,"' \) \\1 #{@l}~*\( '"). +                gsub(/(.+)/,"#{@l}~*\( '\\1' \)") +            end +            search_construct << unescaped_search +            search_construct=search_construct.join(' ') +            search[:search]                    << search_construct +            search[:flag]=true +            search +          end +          search +        end +      end +      WOK_SQL +    end +    def search_query1 +      <<-'WOK_SQL' +          @search_text='' +          @search_text=search[:text].flatten.join(' AND ') +          @search_text=@search_text.gsub(/(doc_objects\.clean~[*]?\(\s*'[^']+'\s*\)\s+(?:(?:AND|OR)\s+doc_objects\.clean~[*]?\(\s*'[^']+'\s*\))+)/,'(\1)') +        end +      WOK_SQL +    end +    def search_query2 +      <<-'WOK_SQL' +        def sql_select_body +          limit ||=@@limit +          offset ||=@@offset +          @sql_statement[:body]=%{SELECT metadata_and_text.title, metadata_and_text.creator_author, metadata_and_text.src_filename, metadata_and_text.language_document_char, metadata_and_text.notes_suffix, doc_objects.body, doc_objects.seg, doc_objects.ocn, metadata_and_text.tid FROM doc_objects, metadata_and_text WHERE (#{@search_text}) AND doc_objects.metadata_tid = metadata_and_text.tid ORDER BY metadata_and_text.language_document_char, metadata_and_text.title, metadata_and_text.src_filename, doc_objects.ocn} +          @sql_statement[:range]=%{LIMIT #{limit} OFFSET #{offset} ;} +          select=@sql_statement[:body] + ' ' + @sql_statement[:range] +          select +        end +        def sql_select_body_format +          %{<font color="#666666" size="2">#{sql_select_body}</font>} +        end +        def contents +          @conn.exec(sql_select_body) +        end +      end +      WOK_SQL +    end +    def buttons1_pgsql +      <<-'WOK_SQL' +        <input type="checkbox" name="casesense" #{@checked_case}> case sensitive +      WOK_SQL +    end +    def dbi_connect +      <<-'WOK_SQL' +          @conn=PG::Connection.open(dbname: @db, port: @port, user: @user) +      WOK_SQL +    end +  end +end +__END__ +#+END_SRC + +** cgi_sql_common.rb + +#+BEGIN_SRC ruby  :tangle "../lib/sisu/cgi_sql_common.rb" +# <<sisu_document_header>> +module SiSU_CGI_SQL +  class CGI_Common +    def initialize(webserv,opt,image_src,dir) +      @webserv,@opt,@image_src,@env=webserv,opt,image_src,dir +    end +    def about +      <<-'WOK_SQL' + * Name: SiSU information Structuring Universe + * Author: Ralph Amissah +   * http://www.jus.uio.no/sisu +   * http://www.jus.uio.no/sisu/SiSU/download +      WOK_SQL +    end +    def gpl +      <<-'WOK_SQL' + * Name: SiSU generated sample cgi search form + + * Description: generated sample cgi search form for SiSU +   (SiSU is a framework for document structuring, publishing and search) + + * Author: Ralph Amissah + + * Copyright: (C) 1997 - 2015, 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/licenses/gpl.html> +   [http://www.gnu.org/licenses/gpl.html] +   <http://www.jus.uio.no/sisu/gpl.fsf> + + * SiSU uses: +   * Standard SiSU markup syntax, +   * Standard SiSU meta-markup syntax, and the +   * Standard SiSU object citation numbering and system + + * Homepages: +   [http://www.jus.uio.no/sisu] +   [http://www.sisudoc.org] + + * Ralph Amissah +   [ralph@amissah.com] +   [ralph.amissah@gmail.com] +      WOK_SQL +    end +    def header1 +      <<-'WOK_SQL' +#Common TOP +      @@offset=0 +      @@canned_search_url=@base +      @color_heading='#DDFFAA' +      @color_match='#ffff48' +      class Form +        def initialize(base,search_field,selected_db,result_type,checked_sql_limit,checked_tip,checked_stats,checked_searched,checked_url,checked_case,checked_echo,checked_sql,checked_all,checked_none,checked_selected,checked_default,search_note,the_can='') +          search_note='' if checked_searched !~/\S/ +          the_can='' if checked_url !~/\S/ +          search_field='' if checked_echo !~/\S/ +          @base,@search_field,@selected_db,@result_type,@checked_sql_limit,@checked_tip,@checked_stats,@checked_searched,@checked_url,@checked_case,@checked_echo,@checked_sql,@checked_all,@checked_none,@checked_selected,@checked_default,@search_note,@the_can=base,search_field,selected_db,result_type,checked_sql_limit,checked_tip,checked_stats,checked_searched,checked_url,checked_case,checked_echo,checked_sql,checked_all,checked_none,checked_selected,checked_default,search_note,the_can +          @tip=if checked_tip =~/\S/ +            '<font size="2" color="#666666">text:__; fulltxt:__; keywords:__; title:__; author:__; topic_register:__; subject:__; description:__; publisher:__; editor:__; contributor:__; date:__; type:__; format:__; identifier:__; source:__; language:__; relation:__; coverage:__; rights:__; comment:__; abstract:__; filename:__;</font><br>' +          else '' +          end +        end +        def submission_form +            search_form=<<-WOK +      WOK_SQL +    end +    def header_desc +      <<-WOK_SQL +    <!DOCTYPE html> +    <html> +    <head> +      <title> +      <meta charset="utf-8"> +      <meta name="sourcefile" content="SiSU._sst" /> +      SiSU search form (sample): SiSU information Structuring Universe +      </title> +      <link rel="generator" href="http://www.jus.uio.no/sisu" /> +      <link rel="shortcut icon" href="#{@image_src}/rb7.ico" /> +      <link href="../_sisu/css/html.css" rel="stylesheet"> +    </head> +    <body lang="en" xml:lang="en"> +    <table summary="band" border="0" cellpadding="3" cellspacing="0"> +    <tr><td width="20%"> +     <table summary="home button / home information" border="0" cellpadding="3" cellspacing="0"> +     <tr><td align="left"> +      <br><a href="http://sisudoc.org/" target="_top"> +        <b>SiSU</b> +      </a> +      <br><a href="http://git.sisudoc.org/" target="_top"> +        git +      </a> +     </td></tr> +     </table> +    </td> +    <td> +      <label for="find"><b>#{@env.sample_search_form_title(@opt.dir_structure_by)}</b></label> +    </td></tr> +    </table> +      WOK_SQL +    end +    def header2 +      <<-'WOK_SQL' +    <form action="#{@base}" id="Test Form" method="post"> +      <table cellpadding="2"> +      <tr><td valign=\"top\"> +          <textarea id="find" name="find" type="text" rows="6" cols="40" maxlength="256">#{@search_field}</textarea> +      </td> +      <td valign=\"top\"> +        #{@tip} +        #{@search_note} +        #{@the_can} +      </td></tr></table> +      <td valign=\"top\"><tr><td> +        <!input type="text" id="find" name="find" value="#{@search_field}" /> +        <!input type="text" id="find" name="find" value="" /> +        <font size="2" color="#222222"> +        <b>to search:</b> select which database to search (drop-down menu below); enter your search query (in the form above); and <b>click on the search button</b> (below) +        <br> +        <select name="db" size="1"> +          #{@selected_db} +      WOK_SQL +    end +    def buttons1 +      <<-'WOK_SQL' +        </select> +        <input type="submit" value="SiSU search" /> +        <input type="radio" name="view" value="index" #{@result_type[:index]}> index +        <input type="radio" name="view" value="text" #{@result_type[:text]}> text / grep +      WOK_SQL +    end +    def buttons2 +      <<-'WOK_SQL' +        <br> +          match limit: +          <input type="radio" name="sql_match_limit" value="1000" #{@checked_sql_limit[:l1000]}> 1,000 +          <input type="radio" name="sql_match_limit" value="2500" #{@checked_sql_limit[:l2500]}> 2,500 +        <br> +          <input type="checkbox" name="echo" #{@checked_echo}> echo query +          <input type="checkbox" name="stats" #{@checked_stats}> result stats +          <input type="checkbox" name="url" #{@checked_url}> search url +          <input type="checkbox" name="searched" #{@checked_searched}> searched +          <input type="checkbox" name="tip" #{@checked_tip}> available fields +          <input type="checkbox" name="sql" #{@checked_sql}> sql statement +        <br> +          checks: +          <input type="radio" name="checks" value="check_default" #{@checked_default}> default +          <input type="radio" name="checks" value="check_selected" #{@checked_selected}> selected +          <input type="radio" name="checks" value="check_all" #{@checked_all}> all +          <input type="radio" name="checks" value="check_none" #{@checked_none}> none +          </font> +      </td></tr> +      </table> +    </form> +      WOK +        end +      end +      WOK_SQL +    end +    def search_request +      <<-'WOK_SQL' +      class SearchRequest                                                       #% search_for +        attr_accessor :text1,:fulltext,:keywords,:title,:author,:topic_register,:subject,:description,:publisher,:editor,:contributor,:date,:type,:format,:identifier,:source,:language,:relation,:coverage,:rights,:comment,:abstract,:owner,:date_created,:date_issued,:date_modified,:date_available,:date_valid,:filename +        def initialize(search_field='',q='') +          @search_field,@q=search_field,q +          @text1=@fulltext=@keywords=@title=@author=@topic_register=@subject=@description=@publisher=@editor=@contributor=@date=@type=@format=@identifier=@source=@language=@relation=@coverage=@rights=@comment=@abstract=@owner=@date_created=@date_issued=@date_modified=@date_available=@date_valid=@filename='' +          if @search_field=~/\S/ +            @text1=text_to_match('text:') +            @fulltext=text_to_match('fulltxt:') +            @topic_register=text_to_match('topic_register:') +            @title=text_to_match('title:')                  # DublinCore 1  - title +            @author=text_to_match('(?:author|creator)s?:')  # DublinCore 2  - creator/author +            @subject=text_to_match('subj(?:ect)?:')         # DublinCore 3  - subject +            @description=text_to_match('description:')      # DublinCore 4  - description +            @publisher=text_to_match('pub(?:lisher)?:')     # DublinCore 5  - publisher +            @editor=text_to_match('editor:') +            @contributor=text_to_match('contributor:')      # DublinCore 6  - contributor +            @date=text_to_match('date:')                    # DublinCore 7  - date dd-mm-yy +            @type=text_to_match('type:')                    # DublinCore 8  - type +            @format=text_to_match('format:')                # DublinCore 9  - format +            @identifier=text_to_match('identifier:')        # DublinCore 10 - identifier +            @source=text_to_match('source:')                # DublinCore 11 - source +            @language=text_to_match('language:')            # DublinCore 12 - language +            @relation=text_to_match('relation:')            # DublinCore 13 - relation +            @coverage=text_to_match('coverage:')            # DublinCore 14 - coverage +            @rights=text_to_match('rights:')                # DublinCore 15 - rights +            @keywords=text_to_match('key(?:words?)?:') +            @comment=text_to_match('comment:') +            @abstract=text_to_match('abs(?:tract)?:') +            @owner=text_to_match('owner:') +            @date_created=text_to_match('date_created:') +            @date_issued=text_to_match('date_issued:') +            @date_modified=text_to_match('date_modified:') +            @date_available=text_to_match('date_available:') +            @date_valid=text_to_match('date_valid:') +            @filename=text_to_match('filename:') +            @text1=text_to_match unless @keywords or @author or @title or @text1 or @fulltext or @comment or @abstract or @rights or @subject or @publisher or @date or @filename or @topic_register +          else +            @text1=q['s1'] if q['s1']=~/\S/ +            @fulltext=q['ft'] if q['ft']=~/\S/ +            @keywords=q['key'] if q['key']=~/\S/ +            @title=q['ti'] if q['ti']=~/\S/ +            @author=q['au'] if q['au']=~/\S/ +            @topic_register=q['tr'] if q['tr']=~/\S/ +            @subject=q['sj'] if q['sj']=~/\S/ +            @description=q['dsc'] if q['dsc']=~/\S/ +            @publisher=q['pb'] if q['pb']=~/\S/ +            @editor=q['cntr'] if q['cntr']=~/\S/ +            @contributor=q['cntr'] if q['cntr']=~/\S/ +            @date=q['dt'] if q['dt']=~/\S/ +            @type=q['ty'] if q['ty']=~/\S/ +            @identifier=q['id'] if q['id']=~/\S/ +            @source=q['src'] if q['src']=~/\S/ +            @language=q['lang'] if q['lang']=~/\S/ +            @relation=q['rel'] if q['rel']=~/\S/ +            @coverage=q['cov'] if q['cov']=~/\S/ +            @rights=q['cr'] if q['cr']=~/\S/ +            @comment=q['co'] if q['co']=~/\S/ +            @abstract=q['ab'] if q['ab']=~/\S/ +            @date_created=q['dtc'] if q['dtc']=~/\S/ +            @date_issued=q['dti'] if q['dti']=~/\S/ +            @date_modified=q['dtm'] if q['dtm']=~/\S/ +            @date_available=q['dta'] if q['dta']=~/\S/ +            @date_valid=q['dtv'] if q['dtv']=~/\S/ +            @filename=if q['doc'] and q['search'] !~/search db/ then q['doc'] +            elsif q['fns']=~/\S/                                then q['fns'] +            end +            @@limit=q['ltd'] if q['ltd']=~/\d+/  # 1000 +            @@offset=q['off'] if q['off']=~/\d+/ # 0 +          end +        end +        def text_to_match(identifier='') +          m={ +            string: /#{identifier}\s*(.+?)/, +            string: /#{identifier}\s*(.+?)(?:;|\n|\r|$)/, +            word: /#{identifier}[\s(]*(\S+)/ +          } +          search_string=if @search_field =~m[:word] +            search_string=if @search_field =~m[:braces] then m[:braces].match(@search_field)[1] +            elsif @search_field =~m[:string]            then m[:string].match(@search_field)[1] +            else +              str=m[:word].match(@search_field)[1] +              str=str.gsub(/[()]/,'') +              str +            end +            search_string=search_string.strip.gsub(/\s+/,'+') +          #else +          #  "__" +          end +        end +      end +      WOK_SQL +    end +    def search_statement_common +      <<-'WOK_SQL' +      class DBI_SearchStatement +        attr_reader :text_search_flag,:sql_select_body_format,:sql_offset,:sql_limit +        def initialize(conn,search_for,q,c) +          @conn=conn +          @text_search_flag=false +          @sql_statement={ body: '', endnotes: '', range: '' } +          #@offset||=@@offset +          #@offset+=@@limit +          search={ text: [], endnotes: [] } +          cse=(c =~/\S/) ? true : false +          st=DBI_SearchString.new('doc_objects.clean',search_for.text1,q['s1'],cse).string +          se=DBI_SearchString.new('endnotes.clean',search_for.text1,q['s1'],cse).string +          @text_search_flag=st[:flag] +          if st[:flag] +            search[:text]                    << st[:search] +          end +          st=DBI_SearchString.new('metadata_and_text.fulltext',search_for.fulltext,q['ft'],cse).string +          if st[:flag] +            search[:text]                    << st[:search] +          end +          st=DBI_SearchString.new('metadata_and_text.title',search_for.title,q['ti'],cse).string +          if st[:flag] +            search[:text]                    << st[:search] +          end +          st=DBI_SearchString.new('metadata_and_text.creator_author',search_for.author,q['au'],cse).string +          if st[:flag] +            search[:text]                    << st[:search] +          end +          st=DBI_SearchString.new('metadata_and_text.classify_topic_register',search_for.topic_register,q['tr'],cse).string +          if st[:flag] +            search[:text]                    << st[:search] +          end +          st=DBI_SearchString.new('metadata_and_text.classify_subject',search_for.subject,q['sj'],cse).string +          if st[:flag] +            search[:text]                    << st[:search] +          end +          st=DBI_SearchString.new('metadata_and_text.classify_keywords',search_for.keywords,q['key'],cse).string +          if st[:flag] +            search[:text]                    << st[:search] +          end +          st=DBI_SearchString.new('metadata_and_text.notes_description',search_for.description,q['dsc'],cse).string +          if st[:flag] +            search[:text]                    << st[:search] +          end +          st=DBI_SearchString.new('metadata_and_text.publisher',search_for.publisher,q['pb'],cse).string +          if st[:flag] +            search[:text]                    << st[:search] +          end +          st=DBI_SearchString.new('metadata_and_text.creator_editor',search_for.editor,q['cntr'],cse).string +          if st[:flag] +            search[:text]                    << st[:search] +          end +          st=DBI_SearchString.new('metadata_and_text.creator_contributor',search_for.contributor,q['cntr'],cse).string +          if st[:flag] +            search[:text]                    << st[:search] +          end +          st=DBI_SearchString.new('metadata_and_text.date_published',search_for.date,q['dt'],cse).string +          if st[:flag] +            search[:text]                    << st[:search] +          end +          st=DBI_SearchString.new('metadata_and_text.notes_type',search_for.type,q['ty'],cse).string +          if st[:flag] +            search[:text]                    << st[:search] +          end +          st=DBI_SearchString.new('metadata_and_text.original_source',search_for.source,q['src'],cse).string +          if st[:flag] +            search[:text]                    << st[:search] +          end +          st=DBI_SearchString.new('metadata_and_text.language_document_char',search_for.language,q['lang'],cse).string +          if st[:flag] +            search[:text]                    << st[:search] +          end +          st=DBI_SearchString.new('metadata_and_text.notes_relation',search_for.relation,q['rel'],cse).string +          if st[:flag] +            search[:text]                    << st[:search] +          end +          st=DBI_SearchString.new('metadata_and_text.notes_coverage',search_for.coverage,q['cov'],cse).string +          if st[:flag] +            search[:text]                    << st[:search] +          end +          st=DBI_SearchString.new('metadata_and_text.rights_all',search_for.rights,q['cr'],cse).string +          if st[:flag] +            search[:text]                    << st[:search] +          end +          st=DBI_SearchString.new('metadata_and_text.notes_comment',search_for.comment,q['co'],cse).string +          if st[:flag] +            search[:text]                    << st[:search] +          end +          st=DBI_SearchString.new('metadata_and_text.notes_abstract',search_for.abstract,q['ab'],cse).string +          if st[:flag] +            search[:text]                    << st[:search] +          end +          st=DBI_SearchString.new('metadata_and_text.src_filename',search_for.filename,q['fns'],cse).string +          if st[:flag] +            search[:text]                    << st[:search] +          end +          @@limit=q['ltd'] if q['ltd']=~/\d+/  # 1000 +          @@offset=q['off'] if q['off']=~/\d+/ # 0 +      WOK_SQL +    end +    def pages +      <<-'WOK_SQL' +        def sql_offset +          @@offset +        end +        def sql_match_limit +          @@limit +        end +        def sql_canned_search +          @offset_next=sql_offset.to_i + sql_match_limit.to_i +          @offset_previous=sql_offset.to_i - sql_match_limit.to_i +          def current +            @@canned_search_url.to_s + '<d=' + sql_match_limit.to_s + '&off=' + sql_offset.to_s +          end +          def next +            @@canned_search_url.to_s + '<d=' + sql_match_limit.to_s + '&off=' + @offset_next.to_s +          end +          def previous +            @offset_previous >= 0 \ +            ? (@@canned_search_url.to_s + '<d=' + sql_match_limit.to_s + '&off=' + @offset_previous.to_s) +            : '' +          end +          def start +            @@canned_search_url.to_s + '<d=' + sql_match_limit.to_s + '&off=' + 0.to_s +          end +          self +        end +        def pre_next(beyond_limit,img) +          can=sql_canned_search +          page=(sql_offset.to_i + sql_match_limit.to_i)/sql_match_limit.to_i +          if beyond_limit +            if page.to_s =~ /^1$/ +              %{<br><center> +              pg. #{page.to_s} +              <a href="#{can.next}"> +                <img border="0" width="22" height="22" src="#{img}/arrow_next_red.png" alt=" >>" /> +              </a> +              </center>} +            elsif page.to_s =~ /^2$/ +              %{<br><center> +              <a href="#{can.previous}"> +                <img border="0" width="22" height="22" src="#{img}/arrow_prev_red.png" alt="<< " /> +              </a> +              pg. #{page.to_s} +              <a href="#{can.next}"> +                <img border="0" width="22" height="22" src="#{img}/arrow_next_red.png" alt=" >>" /> +              </a> +              </center>} +            else +              %{<br><center> +              <a href="#{can.start}"> +                <img border="0" width="22" height="22" src="#{img}/arrow_prev_red.png" alt="|< " /> +              </a> +              <a href="#{can.previous}"> +                <img border="0" width="22" height="22" src="#{img}/arrow_prev_red.png" alt="<< " /> +              </a> +              pg. #{page.to_s} +              <a href="#{can.next}"> +                <img border="0" width="22" height="22" src="#{img}/arrow_next_red.png" alt=" >>" /> +              </a> +              </center>} +            end +          else +            if page.to_s =~ /^1$/ then '' +            elsif page.to_s =~ /^2$/ +              %{<br><center> +              <a href="#{can.previous}"> +                <img border="0" width="22" height="22" src="#{img}/arrow_prev_red.png" alt="<< " /> +              </a> +              pg. #{page.to_s} +              </center>} +            else +              %{<br><center> +              <a href="#{can.start}"> +                <img border="0" width="22" height="22" src="#{img}/arrow_prev_red.png" alt="|< " /> +              </a> +              <a href="#{can.previous}"> +                <img border="0" width="22" height="22" src="#{img}/arrow_prev_red.png" alt="<< " /> +              </a> +              pg. #{page.to_s} +              </center>} +            end +          end +        end +      WOK_SQL +    end +    def tail +      v=SiSU_Env::InfoVersion.instance.get_version +      <<-WOK_SQL +      def tail +        <<-'WOK' +    <br><hr /><br> +<table summary="SiSU summary" cellpadding="2" border="0"> +  <!-- widget sisu --> +<tr><td valign="top" width="10%"> + <table summary="home button / home information" border="0" cellpadding="3" cellspacing="0"> + <tr><td align="left"> +  <br><a href="http://sisudoc.org/" target="_top"> +    <b>SiSU</b> +  </a> +  <br><a href="http://git.sisudoc.org/" target="_top"> +    git +  </a> + </td></tr> + </table> +</td> +<td valign="top" width="45%"> +<!-- SiSU Rights --> +  <p class="tiny_left"><font color="#666666" size="2"> +    Generated by +      #{v.project} #{v.version} #{v.date} (#{v.date_stamp}) +    <br> +    <a href="http://www.sisudoc.org" > +    <b>#{v.project}</b></a> <sup>©</sup> Ralph Amissah +    1993, current 2015. +    All Rights Reserved. +    <br> +      #{v.project} is software for document structuring, publishing and search, +    <br> +    <a href="http://www.jus.uio.no/sisu" > +      www.jus.uio.no/sisu +    </a> +    and +    <a href="http://www.sisudoc.org" > +      www.sisudoc.org +    </a> +    sources +    <a href="http://git.sisudoc.org" > +      git.sisudoc.org +    </a> +  <br> +    <i>w3 since October 3 1993</i> +    <a href="mailto:ralph@amissah.com" > +      ralph@amissah.com +    </a> +  <br> +    mailing list subscription +    <a href="http://lists.sisudoc.org/listinfo/sisu" > +      http://lists.sisudoc.org/listinfo/sisu +    </a> +  <br> +    <a href="mailto:sisu@lists.sisudoc.org" > +      sisu@lists.sisudoc.org +    </a> +  </font></p> +</td><td valign="top" width="45%"> +  <p class="tiny_left"><font color="#666666" size="2"> +    #{v.project} using: +    <br>Standard SiSU markup syntax, +    <br>Standard SiSU meta-markup syntax, and the +    <br>Standard SiSU <u>object citation numbering</u> and system, (object/text identifying/locating system) +  <br> +    <sup>©</sup> Ralph Amissah 1997, current 2015. +    All Rights Reserved. +  </font></p> +</td></tr> +  <!-- widget way better --> +<tr><td valign="top" width="10%"> +  <p class="tiny_left"><font color="#666666" size="2"> +    <a href="http://www.gnu.org/licenses/gpl.html"> +      .: +    </a> +  </font></p> +</td><td valign="top" width="45%"> +  <p class="tiny_left"><font color="#666666" size="2"> +    SiSU is released under +    <a href="http://www.gnu.org/licenses/gpl.html">GPL v3</a> +    or later, +    <a href="http://www.gnu.org/licenses/gpl.html"> +      http://www.gnu.org/licenses/gpl.html +    </a> +  </font></p> +</td><td valign="top" width="45%"> +  <p class="tiny_left"><font color="#666666" size="2"> +    #{v.project}, developed using +    <a href="http://www.ruby-lang.org/en/"> +      Ruby +    </a> +    on +    <a href="http://www.debian.org/"> +      Debian/Gnu/Linux +    </a> +    software infrastructure, +    with the usual GPL (or OSS) suspects. +  </font></p> +</td></tr> +</table> +    <a name="bottom" id="bottom"></a><a name="down" id="down"></a><a name="end" id="end"></a><a name="finish" id="finish"></a><a name="stop" id="stop"></a><a name="credits" id="credits"></a> +    </body></html> +    WOK +      end +      WOK_SQL +    end +    def main1 +      <<-'WOK_SQL' +      @tail=tail +      @counter_txt_doc,@counter_txt_ocn,@counter_endn_doc,@counter_endn_ocn=0,0,0,0 +      @counters_txt,@counters_endn,@sql_select_body='','','' +      FCGI.each_cgi do |cgi| +        begin # all code goes in begin section +          @search={ text: [], endnotes: [] } +          q=CGI.new +          @db=if cgi['db'] =~ /#{@db_name_prefix}(\S+)/ +            @stub=$1 +            cgi['db'] +          else +            @stub=@stub_default +            @db_name_prefix + @stub +          end +          checked_url,checked_stats,checked_searched,checked_tip,checked_case,checked_echo,checked_sql,checked_all,checked_none,checked_selected,checked_default,selected_db='','','','','','','','','' +          result_type=(cgi['view']=~/text/) \ +          ? result_type={ index: '', text: 'checked'} +          : result_type={ index: 'checked', text: ''} +          @@limit=if cgi['sql_match_limit'].to_s=~/2500/ +            checked_sql_limit={ l1000: '', l2500: 'checked'} +            '2500' +          else +            checked_sql_limit={ l1000: 'checked', l2500: ''} +            '1000' +          end +          checked_echo='checked' if cgi['echo'] =~/\S/ +          checked_stats='checked' if cgi['stats'] =~/\S/ +          checked_url='checked' if cgi['url'] =~/\S/ or cgi['u'].to_i==1 +          checked_searched='checked' if cgi['searched'] =~/\S/ +          checked_tip='checked' if cgi['tip'] =~/\S/ +          checked_case='checked' if cgi['casesense'] =~/\S/ +          checked_sql='checked' if cgi['sql'] =~/\S/ +          if cgi['checks'] =~/check_all/ or cgi['check_all'] =~/\S/ or cgi['a'].to_i==1 +            checked_all='checked' +            checked_echo=checked_stats=checked_url=checked_searched=checked_tip=checked_sql='checked' +            checked_none='' +          elsif cgi['checks'] =~/check_none/ +            checked_none='checked' +            checked_all=checked_url=checked_stats=checked_searched=checked_tip=checked_echo=checked_sql='' +          elsif cgi['checks'] =~/check_selected/ +            checked_selected='checked' +          elsif cgi['checks'] =~/check_default/ +            checked_default='checked' +            checked_echo=checked_stats=checked_url='checked' +            checked_searched=checked_tip=checked_case=checked_sql='' +          else +            checked_selected='checked' +            checked_echo=checked_stats=checked_url='checked' +            checked_searched=checked_tip=checked_case=checked_sql='' +          end +      WOK_SQL +    end +    def main2 +      <<-'WOK_SQL' +          search_field=cgi['find'] if cgi['find'] # =~/\S+/ +          @search_for=SearchRequest.new(search_field,q) #.analyze               #% search_for +                                                                                 #% searches +          #Canned_search.new(@base,@search_for.text1,cgi) +          if @search_for.text1=~/\S+/ or @search_for.fulltext=~/\S+/ or @search_for.author=~/\S+/ or @search_for.topic_register=~/\S+/  #and search_field =~/\S/ +            s1='s1=' + CGI.escape(@search_for.text1) if @search_for.text1=~/\S/ +            ft='&ft=' + CGI.escape(@search_for.fulltext) if @search_for.fulltext=~/\S/ +            key='key=' + CGI.escape(@search_for.keywords) if @search_for.keywords=~/\S/ +            ti='&ti=' + CGI.escape(@search_for.title) if @search_for.title=~/\S/ +            au='&au=' + CGI.escape(@search_for.author) if @search_for.author=~/\S/ +            tr='&tr=' + CGI.escape(@search_for.topic_register) if @search_for.topic_register=~/\S/ +            sj='&sj=' + CGI.escape(@search_for.subject) if @search_for.subject=~/\S/ +            dsc='&dsc=' + CGI.escape(@search_for.description) if @search_for.description=~/\S/ +            pb='&pb=' + CGI.escape(@search_for.publisher) if @search_for.publisher=~/\S/ +            edt='&edt=' + CGI.escape(@search_for.editor) if @search_for.editor=~/\S/ +            cntr='&cntr=' + CGI.escape(@search_for.contributor) if @search_for.contributor=~/\S/ +            dt='&dt=' + CGI.escape(@search_for.date) if @search_for.date=~/\S/ +            ty='&ty=' + CGI.escape(@search_for.type) if @search_for.type=~/\S/ +            id='&id=' + CGI.escape(@search_for.identifier) if @search_for.identifier=~/\S/ +            src='&src=' + CGI.escape(@search_for.source) if @search_for.source=~/\S/ +            lang='&lang=' + CGI.escape(@search_for.language) if @search_for.language=~/\S/ +            rel='&rel=' + CGI.escape(@search_for.relation) if @search_for.relation=~/\S/ +            cov='&cov=' + CGI.escape(@search_for.coverage) if @search_for.coverage=~/\S/ +            cr='&cr=' + CGI.escape(@search_for.rights) if @search_for.rights=~/\S/ +            co='&co=' + CGI.escape(@search_for.comment) if @search_for.comment=~/\S/ +            ab='&ab=' + CGI.escape(@search_for.abstract) if @search_for.abstract=~/\S/ +            dtc='&dtc=' + CGI.escape(@search_for.date_created) if @search_for.date_created=~/\S/ +            dti='&dti=' + CGI.escape(@search_for.date_issued) if @search_for.date_issued=~/\S/ +            dtm='&dtm=' + CGI.escape(@search_for.date_modified) if @search_for.date_modified=~/\S/ +            dta='&dta=' + CGI.escape(@search_for.date_available) if @search_for.date_available=~/\S/ +            dtv='&dtv=' + CGI.escape(@search_for.date_valid) if @search_for.date_valid=~/\S/ +            fns='&fns=' + CGI.escape(@search_for.filename) if @search_for.filename=~/\S/ +            @@canned_search_url=(checked_all =~/checked/) \ +            ? "#{@base}?#{s1}#{ft}#{key}#{ti}#{au}#{tr}#{sj}#{dsc}#{pb}#{edt}#{cntr}#{dt}#{ty}#{id}#{src}#{lang}#{rel}#{cov}#{cr}#{co}#{ab}#{dtc}#{dti}#{dtm}#{dta}#{dtv}#{fns}&db=#{cgi['db']}&view=#{cgi['view']}&a=1" +            : "#{@base}?#{s1}#{ft}#{key}#{ti}#{au}#{tr}#{sj}#{dsc}#{pb}#{edt}#{cntr}#{dt}#{ty}#{id}#{src}#{lang}#{rel}#{cov}#{cr}#{co}#{ab}#{dtc}#{dti}#{dtm}#{dta}#{dtv}#{fns}&db=#{cgi['db']}&view=#{cgi['view']}" +            mod=ft=~/\S+/ ? (ft.gsub(/ft/,'s1')) : s1 +            @canned_base_url="#{@base}?#{mod}&db=#{cgi['db']}" +            if checked_case=~/\S/ +              @search[:text][1]=%{doc_objects.clean~'#{@search_for.text1}'} #s1 +            else +              @search[:text][1]=%{doc_objects.clean~*'#{@search_for.text1}'} #s1 +            end +            canned_note='search url:' +          else +            @@canned_search_url="#{@base}?db=#{@db}&view=index" +            canned_note='search url example:' +          end +          if search_field =~/\S+/ +            analyze_format=search_field.gsub(/\s*\n/,'; ') +          elsif checked_all =~/checked/ or checked_url =~/checked/ +            canned_search=@@canned_search_url.scan(/(?:s1|ft|au|ti|fns|tr)=[^&]+/) +            af=canned_search.join('; ') +            af=af.gsub(/s1=/,'text: '). +              gsub(/ft=/,'fulltxt: '). +              gsub(/au=/,'author: '). +              gsub(/ti=/,'title: '). +              gsub(/fns=/,'filename: '). +              gsub(/tr=/,'topic_register: '). +              gsub(/%2B/,' ') +            analyze_format=af +            st=af.split(/\s*;\s*/) +            search_field=st.join("\n") +          end +          green=%{<font size="2" color="#004000">} +          canned_search_url_txt=CGI.escapeHTML(@@canned_search_url) +          the_can=%{<font size="2" color="#666666">#{canned_note} <a href="#{@@canned_search_url}">#{canned_search_url_txt}</a></font><br>} +          p_text=p_fulltext=p_keywords=p_title=p_author=p_topic_register=p_subject=p_description=p_publisher=p_editor=p_contributor=p_date=p_type=p_format=p_identifier=p_source=p_language=p_relation=p_coverage=p_rights=p_comment=p_abstract=p_filename='' +          p_filename=%{filename: #{green}#{@search_for.filename}</font><br>} if @search_for.filename =~/\S+/ +          p_text=%{text: #{green}#{@search_for.text1}</font><br>} if @search_for.text1 =~/\S+/ +          p_fulltext=%{fulltxt: #{green}#{@search_for.fulltext}</font><br>} if @search_for.fulltext =~/\S+/ +          p_title=%{title: #{green}#{@search_for.title}</font><br>} if @search_for.title =~/\S+/ +          p_author=%{author: #{green}#{@search_for.author}</font><br>} if @search_for.author =~/\S+/ +          p_editor=%{editor: #{green}#{@search_for.editor}</font><br>} if @search_for.editor=~/\S+/ +          p_contributor=%{contributor: #{green}#{@search_for.contributor}</font><br>} if @search_for.contributor =~/\S+/ +          p_date=%{date: #{green}#{@search_for.date}</font><br>} if @search_for.date =~/\S+/ +          p_rights=%{rights: #{green}#{@search_for.rights}</font><br>} if @search_for.rights =~/\S+/ +          p_topic_register=%{topic_register: #{green}#{@search_for.topic_register}</font><br>} if @search_for.topic_register =~/\S+/ +          p_subject=%{subject: #{green}#{@search_for.subject}</font><br>} if @search_for.subject =~/\S+/ +          p_keywords=%{keywords: #{green}#{@search_for.keywords}</font><br>} if @search_for.keywords =~/\S+/ +          p_identifier=%{identifier: #{green}#{@search_for.identifier}</font><br>} if @search_for.identifier =~/\S+/ +          p_type=%{type: #{green}#{@search_for.type}</font><br>} if @search_for.type =~/\S+/ +          p_format=%{format: #{green}#{@search_for.format}</font><br>} if @search_for.format =~/\S+/ +          p_relation=%{relation: #{green}#{@search_for.relation}</font><br>} if @search_for.relation =~/\S+/ +          p_coverage=%{coverage: #{green}#{@search_for.coverage}</font><br>} if @search_for.coverage =~/\S+/ +          p_description=%{description: #{green}#{@search_for.description}</font><br>} if @search_for.description =~/\S+/ +          p_abstract=%{abstract: #{green}#{@search_for.abstract}</font><br>} if @search_for.abstract =~/\S+/ +          p_comment=%{comment: #{green}#{@search_for.comment}</font><br>} if @search_for.comment =~/\S+/ +          p_publisher=%{publisher: #{green}#{@search_for.publisher}</font><br>} if @search_for.publisher =~/\S+/ +          p_source=%{source: #{green}#{@search_for.source}</font><br>} if @search_for.source =~/\S+/ +          p_language=%{language: #{green}#{@search_for.language}</font><br>} if @search_for.language =~/\S+/ +          search_note=<<-WOK +      <font size="2" color="#666666"> +      <b>database:</b> #{green}#{@db}</font>; <b>selected view:</b> #{green}#{cgi['view']}</font> +      <b>search string:</b> "#{green}#{analyze_format}</font>"<br> +      #{p_text} #{p_fulltext} #{p_keywords} #{p_title} #{p_author} #{p_topic_register} #{p_subject} #{p_description} #{p_publisher} #{p_editor} #{p_contributor} #{p_date} #{p_type} #{p_format} #{p_identifier} #{p_source} #{p_language} #{p_relation} #{p_coverage} #{p_rights} #{p_comment} #{p_abstract} #{p_filename} +      </font> +      WOK +        #eg = %{canned search e.g.:<br> <a href="#{url}">#{url}</a><br>find: #{analyze}<br>database: #{database}} +        #% dbi_canning +        @header=Form.new(@base,search_field,selected_db,result_type,checked_sql_limit,checked_tip,checked_stats,checked_searched,checked_url,checked_case,checked_echo,checked_sql,checked_all,checked_none,checked_selected,checked_default,search_note,the_can).submission_form #% form +        unless q['s1'] =~/\S/ or q['au'] =~/\S/ or @search[:text][1] =~/\S/ +          print "Content-type: text/html\n\n" +          puts (@header+@tail) +        else #% searches +          s1=(@search_for.text1 =~/\S/) \ +          ? @search_for.text1 +          : 'Unavailable' +          if checked_case=~/\S/ +            @search[:text]<<%{doc_objects.clean~'#{CGI.unescape(s1)}'} +          else +            @search[:text]<<%{doc_objects.clean~*'#{CGI.unescape(s1)}'} +          end +          #% dbi_request +          dbi_statement=DBI_SearchStatement.new(@conn,@search_for,q,checked_case) +          @text_search_flag=false +          @text_search_flag=dbi_statement.text_search_flag +          s_contents=dbi_statement.contents +          @body_main='' +          @search_regx=nil +          oldtid=0 +          if @text_search_flag +            if checked_sql =~/\S/ +              sql_select_body=dbi_statement.sql_select_body_format +            else sql_select_body='' +            end +            @body_main << sql_select_body +          else +          end +          @hostpath="#{@hosturl_files}/#{@stub}" +      WOK_SQL +    end +    def dir_structure #@opt.dir_structure_by +      <<-'WOK_SQL' +          def path_manifest(fn,ln=nil) +            case @output_dir_structure_by +            when 'filename' +              @lingual =='mono' \ +              ? "#{@hostpath}/#{fn}/sisu_manifest.html" +              : "#{@hostpath}/#{fn}/sisu_manifest.#{ln}.html" +            when 'filetype' +              @lingual =='mono' \ +              ? "#{@hostpath}/manifest/#{fn}.html" +              : "#{@hostpath}/manifest/#{fn}.#{ln}.html" +            else +              "#{@hostpath}/#{ln}/manifest/#{fn}.html" +            end +          end +          def path_html_seg(fn,ln=nil) +            case @output_dir_structure_by +            when 'filename' +              "#{@hostpath}/#{fn}" +            when 'filetype' +              "#{@hostpath}/html/#{fn}" +            else +              "#{@hostpath}/#{ln}/html/#{fn}" +            end +          end +          def path_toc(fn,ln=nil) +            if @output_dir_structure_by =='filename' \ +            or @output_dir_structure_by =='filetype' +              @lingual =='mono' \ +              ? "#{path_html_seg(fn,ln)}/toc.html" +              : "#{path_html_seg(fn,ln)}/toc.#{ln}.html" +            else +              "#{path_html_seg(fn,ln)}/toc.html" +            end +          end +          def path_filename(fn,seg,ln=nil) +            if @output_dir_structure_by =='filename' \ +            or @output_dir_structure_by =='filetype' +              @lingual =='mono' \ +              ? "#{path_html_seg(fn,ln)}/#{seg}.html" +              : "#{path_html_seg(fn,ln)}/#{seg}.#{ln}.html" +            else +              "#{path_html_seg(fn,ln)}/#{seg}.html" +            end +          end +          def path_html_doc(fn,ln=nil) +            case @output_dir_structure_by +            when 'filename' +              @lingual =='mono' \ +              ? "#{path_html_seg(fn,ln)}/scroll.html" +              : "#{path_html_seg(fn,ln)}/scroll.#{ln}.html" +            when 'filetype' +              @lingual =='mono' \ +              ? "#{@hostpath}/html/#{fn}.html" +              : "#{@hostpath}/html/#{fn}.#{ln}.html" +            else +              "#{@hostpath}/#{ln}/html/#{fn}.html" +            end +          end +      WOK_SQL +    end +    def main3 +      <<-'WOK_SQL' +                    #% text_objects_body +          s_contents.each do |c|                                               #% text body +            location=c['src_filename'][/(.+?)\.(?:ssm\.sst|sst)$/,1] +            file_suffix=c['src_filename'][/.+?\.(ssm\.sst|sst)$/,1] +            lang=if location =~ /\S+?~(\S\S\S?)$/ +              l=location[/\S+?~(\S\S\S?)$/,1] +              location=location.gsub(/(\S+?)~\S\S\S?/,'\1') +              l=".#{l}" +            else '' +            end +          #% metadata_found_body +            if c['tid'].to_i != oldtid.to_i +              ti=c['title'] +              can_txt_srch=(cgi['view']=~/index/) \ +              ? %{<a href="#{@canned_base_url}&fns=#{c['src_filename']}&lang=#{c['language_document_char']}&view=text"><img border="0" width="24" height="16" src="#{@image_src}/b_search.png" alt="search"></a> } +              : %{<a href="#{@canned_base_url}&fns=#{c['src_filename']}&lang=#{c['language_document_char']}&view=index"><img border="0" width="24" height="16" src="#{@image_src}/b_search.png" alt="search"></a> } +              title=%{<span style="background-color: #{@color_heading}"><a href="#{path_toc(location,c['language_document_char'])}"><img border="0" width="15" height="18" src="#{@image_src}/b_toc.png" alt="toc html"> #{ti}</a></span> [#{c['language_document_char']}] by #{c['creator_author']} <a href="#{path_manifest(location,c['language_document_char'])}"><img border="0" width="15" height="15" src="#{@image_src}/b_info.png" alt="manifest"></a> #{can_txt_srch}<br>}  if file_suffix=~/s/ #hmm watch file_suffix +              title=@text_search_flag \ +              ? '<br><hr>'+title +              : '<br>'+title +              @counter_txt_doc+=1 +              oldtid=c['tid'].to_i +            else                    title='' +            end +            if @text_search_flag +              if cgi['view']=~/text/ \ +              or (cgi['view']!~/index/ and cgi['search'] !~/search db/)      #% txt body +                text=if c['suffix'] !~/1/ #seg +                  if @search_for.text1 =~/\S+/ \ +                  or q['s1'] =~/\S+/                         #% only this branch is working !! +                    unescaped_search=if @search_for.text1 =~/\S+/ +                      CGI.unescape(@search_for.text1) +                    elsif q['s1'] =~/\S+/ +                      CGI.unescape(q['s1']) +                    else nil +                    end +                    @search_regx=if unescaped_search                                     #check +                      search_regex=unescaped_search.scan(/\S+/).each.map do |g| +                         (g.to_s =~/(AND|OR)/) \ +                         ? ('|') +                         : (%{#{g.to_s}}) +                      end.join(' ') +                      search_regex=search_regex.gsub(/\s*\|\s*/,'|') +                      Regexp.new(search_regex, Regexp::IGNORECASE) +                    else nil +                    end +                  else nil +                  end +                  matched_para=(@search_regx.to_s.class==String && @search_regx.to_s=~/\S\S+/) \ +                  ? (c['body'].gsub(/(<a\s+href="https?:\/\/[^><\s]+#{@search_regx}[^>]+?>|#{@search_regx})/mi,%{<span style="background-color: #{@color_match}">\\1</span>})) +                  : c['body'] +                  %{<hr><p><font size="2">ocn <b><a href="#{path_filename(location,c['seg'],c['language_document_char'])}##{c['ocn']}">#{c['ocn']}</a></b>:</font></p>#{matched_para}} +                elsif c['suffix'] =~/1/ #doc +                  %{#{title}<hr><p><font size="2">ocn #{c['ocn']}:#{c['body']}} +                end +                @counter_txt_ocn+=1 +                output=title+text +              else #elsif cgi['view']=~/index/                                #% idx body +                if c['suffix'] !~/1/ #seg +                  index=%{<a href="#{path_filename(location,c['seg'],c['language_document_char'])}##{c['ocn']}">#{c['ocn']}</a>, } if @text_search_flag +                elsif c['suffix'] =~/1/ #doc #FIX +                  index=%{<a href="#{path_html_doc(location,c['language_document_char'])}##{c['ocn']}">#{c['ocn']}</a>, } +                end +                if c['seg'] =~/\S+/ +                  if @text_search_flag +                    @counter_txt_ocn+=1 +                    output=title+index +                  end +                else +                  @counter_txt_ocn+=1 +                  output=c['suffix'] !~/1/ \ +                  ? title+index +                  : %{#{title}#{c['ocn'].sort}, } +                end +              end +            else output=title +            end +            @counters_txt=if @counter_txt_doc > 0 +              if checked_stats =~/\S/ +                @@lt_t=(@counter_txt_ocn==dbi_statement.sql_match_limit.to_i) ? true : false +                start=(@@offset.to_i+1).to_s +                range=(@@offset.to_i+@counter_txt_ocn.to_i).to_s +                %{<hr /><font size="2" color="#666666">Found #{@counter_txt_ocn} times in the main body of #{@counter_txt_doc} documents [ matches #{start} to #{range} ]</font><br>} +              else '' +              end +            else '' +            end +            @body_main << output #+ details +          end +          oldtid = 0 +          offset=dbi_statement.sql_offset.to_s +          limit=dbi_statement.sql_match_limit.to_s +          @@lt_t ||=false; @@lt_e ||=false +          canned=(@@lt_t or @@lt_e) \ +          ? dbi_statement.pre_next(true,@image_src).to_s +          : dbi_statement.pre_next(false,@image_src).to_s +          limit=dbi_statement.sql_match_limit.to_s +          cgi.out{@header.force_encoding("UTF-8") + @counters_txt.force_encoding("UTF-8") + @counters_endn.force_encoding("UTF-8") + canned.force_encoding("UTF-8") + @body_main.force_encoding("UTF-8") + canned.force_encoding("UTF-8") + @tail.force_encoding("UTF-8")} #% print cgi_output_header+counters+body +        end +        rescue Exception => e +          s='<pre>' + CGI::escapeHTML(e.backtrace.reverse.join("\n")) +          s << CGI::escapeHTML(e.message) + '</pre>' +          cgi.out{s} +          next +        ensure # eg. disconnect from server +          @conn.disconnect if @conn +        end +      end +      WOK_SQL +    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 +    cgi + +  - 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 diff --git a/org/config.org b/org/config.org new file mode 100644 index 00000000..b44d9792 --- /dev/null +++ b/org/config.org @@ -0,0 +1,310 @@ +-*- mode: org -*- +#+TITLE:       sisu configure site +#+DESCRIPTION: documents - structuring, various output representations & search +#+FILETAGS:    :sisu:config: +#+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 + +* conf.rb + +#+BEGIN_SRC ruby  :tangle "../lib/sisu/conf.rb" +# <<sisu_document_header>> +module SiSU_Initialize +  require_relative 'se'                                 # se.rb +    include SiSU_Env +    include SiSU_Screen +  require_relative 'relaxng'                            # relaxng.rb +    include SiSU_Relaxng +  require_relative 'css'                                # css.rb +    include SiSU_Style +  class Source +    def initialize(opt) +      @opt=opt +    end +    def read +      ConfigSite.new(@opt).make_homepage +      ConfigSite.new(@opt).css +      ConfigSite.new(@opt).dtd +      ConfigSite.new(@opt).cp_local_images +      ConfigSite.new(@opt).cp_external_images +      ConfigSite.new(@opt).cp_webserver_images +    end +  end +  class ConfigSite #config files such as css are not updated if they already exist unless forced using the --init=site modifier +    require_relative 'se'                               # se.rb +    def initialize(opt) +      @opt=opt +      @env=SiSU_Env::InfoEnv.new(@opt.fns) +      @suffix={ +        rnc: 'rnc', +        rng: 'rng', +        xsd: 'xsd', +      } +      @path={ +        xml: @env.path.output + '/_sisu/xml', +        xsd: @env.path.output + '/_sisu/xml/xsd', +        rnc: @env.path.output + '/_sisu/xml/rnc', +        rng: @env.path.output + '/_sisu/xml/rng', +        style: @env.path.output + '/' + @env.path.style, +      } +      @pwd,@home=Dir.pwd,@env.path.home +    end +    def make_homepage +      SiSU_Screen::Ansi.new( +        @opt.act[:color_state][:set], +        'invert', +        'Make homepage', +        '' +      ).colorize unless @opt.act[:quiet][:set]==:on +      SiSU_Env::CreateSite.new(@opt).homepage +    end +    def cp_local_images +      SiSU_Screen::Ansi.new( +        @opt.act[:color_state][:set], +        'invert', +        'Copy images', +        '' +      ).colorize unless @opt.act[:quiet][:set]==:on +      SiSU_Env::CreateSite.new(@opt).cp_local_images +      SiSU_Env::CreateSite.new(@opt).cp_webserver_images_local #this should not have been necessary +      SiSU_Env::CreateSite.new(@opt).cp_base_images #base images (nav etc.) used by all html +    end +    def cp_external_images +      SiSU_Screen::Ansi.new( +        @opt.act[:color_state][:set], +        'invert', +        'Copy external images', +        '' +      ).colorize if @opt.act[:verbose_plus][:set]==:on +      SiSU_Env::CreateSite.new(@opt).cp_external_images +    end +    def cp_webserver_images +      SiSU_Screen::Ansi.new( +        @opt.act[:color_state][:set], +        'invert', +        'Copy webserver/output file images', +        '' +      ).colorize unless @opt.act[:quiet][:set]==:on +      SiSU_Env::CreateSite.new(@opt).cp_webserver_images +    end +    def css +      SiSU_Screen::Ansi.new( +        @opt.act[:color_state][:set], +        'invert', +        'Configuring CSSs', +        '' +      ).colorize unless @opt.act[:quiet][:set]==:on +      SiSU_Env::CreateSite.new(@opt).cp_css +    end +    def dtd +      SiSU_Screen::Ansi.new( +        @opt.act[:color_state][:set], +        'invert', +        'Configuring DTDs', +        '' +      ).colorize unless @opt.act[:quiet][:set]==:on +      @rxng=SiSU_Relaxng::RelaxNG.new +      @path.each { |d| FileUtils::mkdir_p(d[1]) \ +      unless FileTest.directory?(d[1]) } +      #ugly code, sort later +      if @rxng.methods.join =~/[^_]dtd_sax\b/ +        if @rxng.dtd_sax.length > 200 +          dtd=File.new("#{@path[:style]}/#{@rxng.rng_name.output_sax}",'w') +          dtd << @rxng.dtd_sax +          dtd.close +        else trang_rnc_model_output_sax +        end +      else trang_rnc_model_output_sax +      end +      if @rxng.methods.join =~/[^_]dtd_dom\b/ +        if @rxng.dtd_dom.length > 200 +          dtd=File.new("#{@path[:style]}/#{@rxng.rng_name.output_dom}",'w') +          dtd << @rxng.dtd_dom +          dtd.close +        else trang_rnc_model_output_dom +        end +      else trang_rnc_model_output_dom +      end +      if @rxng.methods.join =~/[^_]dtd_node\b/ +        if @rxng.dtd_node.length > 200 +          dtd=File.new("#{@path[:style]}/#{@rxng.rng_name.input_node}",'w') +          dtd << @rxng.dtd_node +          dtd.close +        else trang_rnc_model_input_node +        end +      else trang_rnc_model_input_node +      end +      if @rxng.methods.join =~/[^_]dtd_xhtml\b/ +        if @rxng.dtd_xhtml.length > 200 +          dtd=File.new("#{@path[:style]}/#{@rxng.rng_name.output_xhtml}",'w') +          dtd << @rxng.dtd_xhtml +          dtd.close +        else trang_rnc_model_output_xhtml +        end +      else trang_rnc_model_output_xhtml +      end +    end +    def trang_rnc_model_output_sax +      s=@suffix +      rnc_src=@env.processing_path.ao + '/sax.' + s[:rnc] +      rnc_file=@path[:rnc] + '/' + @rxng.rnc_name.output_sax +      rng_file=@path[:rng] + '/' + @rxng.rng_name.output_sax +      xsd_file=@path[:xsd] + '/' + @rxng.xsd_name.output_sax +      rnc=File.new(rnc_src,'w') +      rnc << @rxng.rnc_model_output_sax +      rnc.close +      #xsd +      schema=SiSU_Env::SystemCall.new(rnc_src,xsd_file) +      schema.relaxng(@opt.selections.str) +      #rng +      schema=SiSU_Env::SystemCall.new(rnc_src,rng_file) +      schema.relaxng(@opt.selections.str) +      #rnc +      if FileTest.file?(rnc_src) +        FileUtils::cp(rnc_src,rnc_file) +        FileUtils::chmod(0644,rnc_file) +      else STDERR.puts %{\t*WARN* did not find rnc - "#{rnc_src}" [#{__FILE__}:#{__LINE__}]} +      end +    end +    def trang_rnc_model_output_dom +      s=@suffix +      rnc_src=@env.processing_path.ao + '/dom.' + s[:rnc] +      rnc_file=@path[:rnc] + '/' + @rxng.rnc_name.output_dom +      rng_file=@path[:rng] + '/' + @rxng.rng_name.output_dom +      xsd_file=@path[:xsd] + '/' + @rxng.xsd_name.output_dom +      rnc=File.new(rnc_src,'w') +      rnc << @rxng.rnc_model_output_dom +      rnc.close +      #xsd +      schema=SiSU_Env::SystemCall.new(rnc_src,xsd_file) +      schema.relaxng(@opt.selections.str) +      #rng +      schema=SiSU_Env::SystemCall.new(rnc_src,rng_file) +      schema.relaxng(@opt.selections.str) +      #rnc +      if FileTest.file?(rnc_src) +        FileUtils::cp(rnc_src,rnc_file) +        FileUtils::chmod(0644,rnc_file) +      else STDERR.puts %{\t*WARN* did not find rnc - "#{rnc_src}" [#{__FILE__}:#{__LINE__}]} +      end +    end +    def trang_rnc_model_output_xhtml +      s=@suffix +      rnc_src=@env.processing_path.ao + '/xhtml.' + s[:rnc] +      rnc_file=@path[:rnc] + '/' + @rxng.rnc_name.output_xhtml +      rng_file=@path[:rng] + '/' + @rxng.rng_name.output_xhtml +      xsd_file=@path[:xsd] + '/' + @rxng.xsd_name.output_xhtml +      rnc=File.new(rnc_src,'w') +      rnc << @rxng.rnc_model_output_xhtml +      rnc.close +      #xsd +      schema=SiSU_Env::SystemCall.new(rnc_src,xsd_file) +      schema.relaxng(@opt.selections.str) +      #rng +      schema=SiSU_Env::SystemCall.new(rnc_src,rng_file) +      schema.relaxng(@opt.selections.str) +      #rnc +      if FileTest.file?(rnc_src) +        FileUtils::cp(rnc_src,rnc_file) +        FileUtils::chmod(0644,rnc_file) +      else STDERR.puts %{\t*WARN* did not find rnc - "#{rnc_src}" [#{__FILE__}:#{__LINE__}]} +      end +    end +    def trang_rnc_model_input_sax +      rnc_file=@env.processing_path.ao + '/sax.rnc' +      dtd_file=@path[:xsd] + '/' + @rxng.rng_name.input_sax +      rnc=File.new(rnc_file,'w') +      rnc << @rxng.rnc_model_output_sax +      rnc.close +      schema=SiSU_Env::SystemCall.new(rnc_file,dtd_file) +      schema.relaxng(@opt.selections.str) +    end +    def trang_rnc_model_input_dom +      rnc_file=@env.processing_path.ao + '/dom.rnc' +      dtd_file=@path[:xsd] + '/' + @rxng.rng_name.input_dom +      rnc=File.new(rnc_file,'w') +      rnc << @rxng.rnc_model_output_dom +      rnc.close +      schema=SiSU_Env::SystemCall.new(rnc_file,dtd_file) +      schema.relaxng(@opt.selections.str) +    end +    def trang_rnc_model_input_node +      rnc_file=@env.processing_path.ao + '/node.rnc' +      dtd_file=@path[:xsd] + '/' + @rxng.rng_name.input_node +      rnc=File.new(rnc_file,'w') +      rnc << @rxng.rnc_model_input_node +      rnc.close +      schema=SiSU_Env::SystemCall.new(rnc_file,dtd_file) +      schema.relaxng(@opt.selections.str) +    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 +    config + +  - 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, + +  - 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 diff --git a/org/css.org b/org/css.org new file mode 100644 index 00000000..266c0051 --- /dev/null +++ b/org/css.org @@ -0,0 +1,3508 @@ +-*- mode: org -*- +#+TITLE:       sisu css +#+DESCRIPTION: documents - structuring, various output representations & search +#+FILETAGS:    :sisu:css: +#+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 + +* css.rb + +#+BEGIN_SRC ruby  :tangle "../lib/sisu/css.rb" +# <<sisu_document_header>> +module SiSU_Style +  require_relative 'se'                                 # se.rb +  require_relative 'html_parts'                         # html_parts.rb +  class CSS_HeadInfo +    def initialize(md,ft='html') +      @md,@ft=md,ft +      @env=SiSU_Env::InfoEnv.new('',md) +      @fn_css ||=SiSU_Env::CSS_Default.new +      @o_str ||=SiSU_Env::ProcessingSettings.new(md).output_dir_structure +      css_copy +    end +    def stylesheet +      def css_path +        SiSU_Env::CSS_Stylesheet.new(@md) +      end +      def css_embed_content +        @css_embed_content ||=SiSU_Style::CSS.new +      end +      def css_embed? +        if @ft=='html' \ +        && @o_str.dump_or_redirect? +          true +        else +          false +        end +      end +      def css_embed(css) +        <<-WOK +          <style TYPE="text/css"> +          #{css} +          </style> +        WOK +      end +      def css_action +        css=case @ft +        when 'html' +          css=css_embed_content.html +          css_embed(css) +        when 'xhtml' +          css_path.xhtml +        when 'xml_sax' +          css_path.xml_sax +        when 'xml_dom' +          css_path.xml_dom +        when 'xml_docbook' +          css_path.xml_docbook +        else +          css_embed_content.html +        end +      end +      def css_head +        (css_embed?) \ +        ? css_action +        : "#{css_path.html}#{css_path.html_seg}" +      end +      def css_head_seg +        (css_embed?) \ +        ? css_action +        : css_path.html_seg +      end +      def css_head_xml +        css_action +      end +      self +    end +    def css_copy +      if @o_str.dump_or_redirect? +        css=SiSU_Style::CSS.new +        if @o_str.dump? +          css_pth="#{@md.opt.opt_act[:dump][:inst]}/#{@env.path.style}" +        elsif @o_str.redirect? +          css_pth="#{@md.opt.opt_act[:redirect][:inst]}/#{@md.fnb}/#{@env.path.style}" +        end +        FileUtils::mkdir_p(css_pth) unless FileTest.directory?(css_pth) +        case @ft +        when 'html' +          style=File.new("#{css_pth}/#{@fn_css.html}",'w') +          style << css.html +          style.close +        when 'xhtml' +          style=File.new("#{css_pth}/#{@fn_css.xhtml}",'w') +          style << css.xhtml +          style.close +        when 'xml_sax' +          style=File.new("#{css_pth}/#{@fn_css.xml_sax}",'w') +          style << css.xml_sax +          style.close +        when 'xml_dom' +          style=File.new("#{css_pth}/#{@fn_css.xml_dom}",'w') +          style << css.xml_dom +          style.close +          css_path.xml_dom +        when 'xml_docbook' +          style=File.new("#{css_pth}/#{@fn_css.xml_docbook}",'w') +          style << css.xml_docbook +          style.close +          css_path.xml_docbook +        end +      end +    end +  end +  class CSS +    include SiSU_Parts_HTML +    def fonts +      the_font.set_fonts +    end +    def html_tables                               #stylesheet for css table_pages +<<WOK +/* SiSU table output stylesheet */ +  body { +    color: black; +    background: #{the_color.white}; +  } +  p { +    display: block; +    line-height: 1.5; +    font-family: #{the_font.set_fonts}; +  } +  a:link { +    color: #{the_color.blue_ink}; +    text-decoration: none; +  } +  a:visited { +    color: #{the_color.blue_ink}; +    text-decoration: none; +    /* background-color: #{the_color.blue_tinge}; */ +  } +  a:hover { +    color: #{the_color.black}; +    text-decoration: underline; +    background-color: #{the_color.yellow_light}; +  } +  a:active { +    color: #{the_color.blue_ink}; +    text-decoration: underline; +  } +WOK +    end +    def harvest +      <<WOK +/* SiSU harvest css default stylesheet */ +  body { +    color: black; +    background: #ffffff; +    background-color: #ffffff; +  } +  a:link { +    color: #003399; +    text-decoration: none; +  } +  a:visited { +    color: #003399; +    text-decoration: none; +  } +  a:hover { +    color: #000000; +    background-color: #f9f9aa; +  } +  a:hover img { +    background-color: #ffffff; +  } +  a:active { +    color: #003399; +    text-decoration: underline; +  } + +  .norm, .bold { +    line-height: 150%; +    margin-left: 1em; +    margin-right: 2em; +    margin-top: 10px; +    margin-bottom: 0px; +    text-indent: 0mm; +  } +  p, h0, h1, h2, h3, h4, h5, h6, h7 { +    display: block; +    font-family: verdana, arial, georgia, tahoma, sans-serif, helvetica, times, roman; +    font-size: 100%; +    font-weight: normal; +    line-height: 150%; +    /* text-align: justify; */ +    margin-left: 1em; +    text-indent: 0mm; +    margin-top: 2px; +    margin-bottom: 2px; +    margin-right: 6px; +    text-align: left; +  } +  h1 { +    font-size: 120%; +    font-weight: bold; +    color: white; +    background: #000088; +    margin-left: 0em; +  } +  p.work { +    font-size: 80%; +    margin-left: 5em; +    margin-top: 0px; +    margin-bottom: 0px; +    margin-right: 6px; +    text-align: left; +  } +  p.author { +    font-size: 100%; +    margin-left: 2em; +    margin-top: 0px; +    margin-bottom: 0px; +    margin-right: 6px; +    text-align: left; +  } +  p.publication { +    font-size: 80%; +    margin-left: 4em; +    margin-top: 0px; +    margin-bottom: 0px; +    margin-right: 6px; +    text-align: left; +  } +  p.letter { +    font-weight: bold; +    font-size: 60%; +    margin-left: 1em; +    margin-top: 0px; +    margin-bottom: 0px; +    margin-right: 6px; +    text-align: left; +    color: white; +    background: #880000; +  } +  p.lev0 { +    font-size: 120%; +    margin-left: 1em; +    color: white; +    background: #000000; +  } + +  p.lev1 { +    font-size: 110%; +    margin-left: 2em; +    color: white; +    background: #444444; +  } + +  p.lev2 { +    font-size: 100%; +    margin-left: 3em; +    background: #888888; +  } + +  p.lev3 { +    font-size: 90%; +    margin-left: 4em; +    background: #bbbbbb; +  } + +  p.lev4 { +    font-size: 80%; +    margin-left: 5em; +    background: #eeeeee; +  } + +  p.lev5 { +    font-size: 80%; +    margin-left: 6em; +  } +WOK +    end +    def html                                      #stylesheet for css html pages== html.css +<<WOK +/* SiSU css default stylesheet */ +  body { +    color: black; +    background: #ffffff; +    background-color: #ffffff; +  } +/* +    table { +      margin-left: 5%; +      display: block; +    } +    tr { +      display: block; +    } +    th,td { +      display: inline; +      vertical-align: top; +    } +,*/ +  a:link { +    color: #003399; +    text-decoration: none; +  } +  a:visited { +    color: #003399; +    text-decoration: none; +  } +  a:hover { +    color: #000000; +    background-color: #f9f9aa; +  } +  a:hover img { +    background-color: #ffffff; +  } +  a:active { +    color: #003399; +    text-decoration: underline; +  } +  a.lnkocn:link { +    color: #777777; +    text-decoration: none; +  } +  a.lnkocn:visited { +    color: #555555; +    text-decoration: none; +  } +  div { +    margin-left: 0; +    margin-right: 0; +  } +  div.p { +    margin-left: 5%; +    margin-right: 1%; +  } + +  #top_band { +    position: absolute; +    top: 0; +    bottom: 80px; +    width: 100%; +  } +  #top_band_search { +    position: absolute; +    top: 0px; +    right: 0px; +    margin-left: 75%; +    width: 20%; +  } +  #column_left { +    position: absolute; +    top: 80px; +    left: 0; +    margin-left: 1%; +    width: 20%; +  } +  #column_center { +    position: absolute; +    top: 80px; +    margin-left: 20%; +    width: 55%; +  } +  #column_right { +    position: absolute; +    top: 80px; +    right: 0px; +    margin-left: 75%; +    width: 25%; +  } +  #pane_major { +    position: absolute; +    top: 0px; +    left: 0; +    margin-left: 0; +    width: 80%; +  } +  #pane_minor { +    position: absolute; +    top: 0px; +    right: 0px; +    margin-left: 75%; +    width: 20%; +    background-color: #aaaaaa; +  } + +  .norm, .bold, .verse, .group, .block, .alt { +    line-height: 133%; +    margin-left: 0em; +    margin-right: 2em; +    margin-top: 12px; +    margin-bottom: 0px; +    padding-left: 0em; +    text-indent: 0em; +  } +  p, h0, h1, h2, h3, h4, h5, h6, h7 { +    display: block; +    font-family: verdana, arial, georgia, tahoma, sans-serif, helvetica, times, roman; +    font-size: 100%; +    font-weight: normal; +    line-height: 133%; +    text-align: justify; +    margin-left: 0em; +    margin-right: 2em; +    text-indent: 0mm; +    margin-top: 0.8em; +    margin-bottom: 0.8em; +  } + +  /* indent */ + +  p.norm { } +  p.i1 {padding-left: 1em;} +  p.i2 {padding-left: 2em;} +  p.i3 {padding-left: 3em;} +  p.i4 {padding-left: 4em;} +  p.i5 {padding-left: 5em;} +  p.i6 {padding-left: 6em;} +  p.i7 {padding-left: 7em;} +  p.i8 {padding-left: 8em;} +  p.i9 {padding-left: 9em;} + +  /* hanging indent */ + +  p.h0i0 { +    padding-left: 0em; +    text-indent:  0em; +  } +  p.h0i1 { +    padding-left: 1em; +    text-indent: -1em; +  } +  p.h0i2 { +    padding-left: 2em; +    text-indent: -2em; +  } +  p.h0i3 { +    padding-left: 3em; +    text-indent: -3em; +  } +  p.h0i4 { +    padding-left: 4em; +    text-indent: -4em; +  } +  p.h0i5 { +    padding-left: 5em; +    text-indent: -5em; +  } +  p.h0i6 { +    padding-left: 6em; +    text-indent: -6em; +  } +  p.h0i7 { +    padding-left: 7em; +    text-indent: -7em; +  } +  p.h0i8 { +    padding-left: 8em; +    text-indent: -8em; +  } +  p.h0i9 { +    padding-left: 9em; +    text-indent: -9em; +  } + +  p.h1i0 { +    padding-left: 0em; +    text-indent:  1em; +  } +  p.h1i1 { +    padding-left: 1em; +    text-indent:  0em; +  } +  p.h1i2 { +    padding-left: 2em; +    text-indent: -1em; +  } +  p.h1i3 { +    padding-left: 3em; +    text-indent: -2em; +  } +  p.h1i4 { +    padding-left: 4em; +    text-indent: -3em; +  } +  p.h1i5 { +    padding-left: 5em; +    text-indent: -4em; +  } +  p.h1i6 { +    padding-left: 6em; +    text-indent: -5em; +  } +  p.h1i7 { +    padding-left: 7em; +    text-indent: -6em; +  } +  p.h1i8 { +    padding-left: 8em; +    text-indent: -7em; +  } +  p.h1i9 { +    padding-left: 9em; +    text-indent: -8em; +  } + +  p.h2i0 { +    padding-left: 0em; +    text-indent:  2em; +  } +  p.h2i1 { +    padding-left: 1em; +    text-indent:  1em; +  } +  p.h2i2 { +    padding-left: 2em; +    text-indent:  0em; +  } +  p.h2i3 { +    padding-left: 3em; +    text-indent: -1em; +  } +  p.h2i4 { +    padding-left: 4em; +    text-indent: -2em; +  } +  p.h2i5 { +    padding-left: 5em; +    text-indent: -3em; +  } +  p.h2i6 { +    padding-left: 6em; +    text-indent: -4em; +  } +  p.h2i7 { +    padding-left: 7em; +    text-indent: -5em; +  } +  p.h2i8 { +    padding-left: 8em; +    text-indent: -6em; +  } +  p.h2i9 { +    padding-left: 9em; +    text-indent: -7em; +  } + +  p.h3i0 { +    padding-left: 0em; +    text-indent:  3em; +  } +  p.h3i1 { +    padding-left: 1em; +    text-indent:  2em; +  } +  p.h3i2 { +    padding-left: 2em; +    text-indent:  1em; +  } +  p.h3i3 { +    padding-left: 3em; +    text-indent:  0em; +  } +  p.h3i4 { +    padding-left: 4em; +    text-indent: -1em; +  } +  p.h3i5 { +    padding-left: 5em; +    text-indent: -2em; +  } +  p.h3i6 { +    padding-left: 6em; +    text-indent: -3em; +  } +  p.h3i7 { +    padding-left: 7em; +    text-indent: -4em; +  } +  p.h3i8 { +    padding-left: 8em; +    text-indent: -5em; +  } +  p.h3i9 { +    padding-left: 9em; +    text-indent: -6em; +  } + +  p.h4i0 { +    padding-left: 0em; +    text-indent:  4em; +  } +  p.h4i1 { +    padding-left: 1em; +    text-indent:  3em; +  } +  p.h4i2 { +    padding-left: 2em; +    text-indent:  2em; +  } +  p.h4i3 { +    padding-left: 3em; +    text-indent:  1em; +  } +  p.h4i4 { +    padding-left: 4em; +    text-indent:  0em; +  } +  p.h4i5 { +    padding-left: 5em; +    text-indent: -1em; +  } +  p.h4i6 { +    padding-left: 6em; +    text-indent: -2em; +  } +  p.h4i7 { +    padding-left: 7em; +    text-indent: -3em; +  } +  p.h4i8 { +    padding-left: 8em; +    text-indent: -4em; +  } +  p.h4i9 { +    padding-left: 9em; +    text-indent: -5em; +  } + +  p.h5i0 { +    padding-left: 0em; +    text-indent:  5em; +  } +  p.h5i1 { +    padding-left: 1em; +    text-indent:  4em; +  } +  p.h5i2 { +    padding-left: 2em; +    text-indent:  3em; +  } +  p.h5i3 { +    padding-left: 3em; +    text-indent:  2em; +  } +  p.h5i4 { +    padding-left: 4em; +    text-indent:  1em; +  } +  p.h5i5 { +    padding-left: 5em; +    text-indent:  0em; +  } +  p.h5i6 { +    padding-left: 6em; +    text-indent: -1em; +  } +  p.h5i7 { +    padding-left: 7em; +    text-indent: -2em; +  } +  p.h5i8 { +    padding-left: 8em; +    text-indent: -3em; +  } +  p.h5i9 { +    padding-left: 9em; +    text-indent: -4em; +  } + +  p.h6i0 { +    padding-left: 0em; +    text-indent:  6em; +  } +  p.h6i1 { +    padding-left: 1em; +    text-indent:  5em; +  } +  p.h6i2 { +    padding-left: 2em; +    text-indent:  4em; +  } +  p.h6i3 { +    padding-left: 3em; +    text-indent:  3em; +  } +  p.h6i4 { +    padding-left: 4em; +    text-indent:  2em; +  } +  p.h6i5 { +    padding-left: 5em; +    text-indent:  1em; +  } +  p.h6i6 { +    padding-left: 6em; +    text-indent:  0em; +  } +  p.h6i7 { +    padding-left: 7em; +    text-indent: -1em; +  } +  p.h6i8 { +    padding-left: 8em; +    text-indent: -2em; +  } +  p.h6i9 { +    padding-left: 9em; +    text-indent: -3em; +  } + +  p.h7i0 { +    padding-left: 0em; +    text-indent:  7em; +  } +  p.h7i1 { +    padding-left: 1em; +    text-indent:  6em; +  } +  p.h7i2 { +    padding-left: 2em; +    text-indent:  5em; +  } +  p.h7i3 { +    padding-left: 3em; +    text-indent:  4em; +  } +  p.h7i4 { +    padding-left: 4em; +    text-indent:  3em; +  } +  p.h7i5 { +    padding-left: 5em; +    text-indent:  2em; +  } +  p.h7i6 { +    padding-left: 6em; +    text-indent:  1em; +  } +  p.h7i7 { +    padding-left: 7em; +    text-indent:  0em; +  } +  p.h7i8 { +    padding-left: 8em; +    text-indent: -1em; +  } +  p.h7i9 { +    padding-left: 9em; +    text-indent: -2em; +  } + +  p.h8i0 { +    padding-left: 0em; +    text-indent:  8em; +  } +  p.h8i1 { +    padding-left: 1em; +    text-indent:  7em; +  } +  p.h8i2 { +    padding-left: 2em; +    text-indent:  6em; +  } +  p.h8i3 { +    padding-left: 3em; +    text-indent:  5em; +  } +  p.h8i4 { +    padding-left: 4em; +    text-indent:  4em; +  } +  p.h8i5 { +    padding-left: 5em; +    text-indent:  3em; +  } +  p.h8i6 { +    padding-left: 6em; +    text-indent:  2em; +  } +  p.h8i7 { +    padding-left: 7em; +    text-indent:  1em; +  } +  p.h8i8 { +    padding-left: 8em; +    text-indent:  0em; +  } +  p.h8i9 { +    padding-left: 9em; +    text-indent: -1em; +  } + +  p.h9i0 { +    padding-left: 0em; +    text-indent:  9em; +  } +  p.h9i1 { +    padding-left: 1em; +    text-indent:  8em; +  } +  p.h9i2 { +    padding-left: 2em; +    text-indent:  7em; +  } +  p.h9i3 { +    padding-left: 3em; +    text-indent:  6em; +  } +  p.h9i4 { +    padding-left: 4em; +    text-indent:  5em; +  } +  p.h9i5 { +    padding-left: 5em; +    text-indent:  4em; +  } +  p.h9i6 { +    padding-left: 6em; +    text-indent:  3em; +  } +  p.h9i7 { +    padding-left: 7em; +    text-indent:  2em; +  } +  p.h9i8 { +    padding-left: 8em; +    text-indent:  1em; +  } +  p.h9i9 { +    padding-left: 9em; +    text-indent:  0em; +  } + +  p.it0 { +    margin-left: 0em; +    margin-top: 6px; +    margin-bottom: 0px; +    line-height: 100%; +  } +  p.it1 { +    margin-left: 1em; +    margin-top: 0px; +    margin-bottom: 0px; +    line-height: 100%; +  } +  p.it2 { +    margin-left: 2em; +    margin-top: 0px; +    margin-bottom: 0px; +    line-height: 100%; +  } +  p.it3 { +    margin-left: 3em; +    margin-top: 0px; +    margin-bottom: 0px; +    line-height: 100%; +  } +  p.it4 { +    margin-left: 4em; +    margin-top: 0px; +    margin-bottom: 0px; +    line-height: 100%; +  } +  p.it5 { +    margin-left: 5em; +    margin-top: 0px; +    margin-bottom: 0px; +    line-height: 100%; +  } +  p.it6 { +    margin-left: 6em; +    margin-top: 0px; +    margin-bottom: 0px; +    line-height: 100%; +  } +  p.it7 { +    margin-left: 7em; +    margin-top: 0px; +    margin-bottom: 0px; +    line-height: 100%; +  } +  p.it8 { +    margin-left: 8em; +    margin-top: 0px; +    margin-bottom: 0px; +    line-height: 100%; +  } +  p.it9 { +    margin-left: 9em; +    margin-bottom: 0px; +    margin-top: 0px; +    line-height: 100%; +  } + +  p.block { } + +  p.group { } + +  p.alt { } + +  p.verse { +    margin-bottom: 6px; +  } + +  p.code { +    font-family: inconsolata, andale mono, courier new, courier, monospace; +    font-size: 90%; +    text-align: left; +    background-color: #eeeeee; +  } + +  p.caption { +    text-align: left; +    font-size: 80%; +    display: inline; +  } + +  p.endnote { +    font-size: 96%; +    line-height: 120%; +    text-align: left; +    margin-right: 15mm; +  } +  p.endnote_indent { +    font-size: 96%; +    line-height: 120%; +    text-align: left; +    margin-left: 2em; +    margin-right: 15mm; +  } + +  p.center { +    text-align: center; +  } +  p.bold { +    font-weight: bold; +  } +  p.bold_left { +    font-weight: bold; +    text-align: left; +  } +  p.centerbold { +    text-align: center; +    font-weight: bold; +  } +  p.em { +    font-weight: bold; +    font-style: normal; +    background: #fff3b6; +  } + +  p.small { +    font-size: 80%; +    margin-top: 0px; +    margin-bottom: 0px; +    margin-right: 6px; +    text-align: left; +  } + +  .tiny, .tiny_left, .tiny_right, .tiny_center { +    font-size: 10px; +    margin-top: 0px; +    margin-bottom: 0px; +    color: #777777; +    margin-right: 6px; +    text-align: left; +  } +  p.tiny { } +  p.tiny_left { +    margin-left: 0px; +    margin-right: 0px; +    text-align: left; +  } +  p.tiny_right { +    margin-right: 1em; +    text-align: right; +  } +  p.tiny_center { +    margin-left: 0px; +    margin-right: 0px; +    text-align: center; +  } + +  p.pane, p.pane_title, p.pane_blurb, p.pane_link, p.pane_indent { +    font-size: 80%; +    margin-top: 0px; +    margin-bottom: 0px; +    margin-left: 2mm; +    margin-right: 4px; +    text-align: left; +  } +  p.pane { } +  p.pane_title { +    font-weight: bold; +    margin-bottom: 0px; +  } +  p.pane_blurb { +    font-size: 10px; +    margin-bottom: 0px; +  } +  p.pane_link { +    font-size: 10px; +    margin-bottom: 0px; +    margin-left: 4mm; +  } +  p.pane_indent { +    font-size: 10px; +    margin-bottom: 0px; +    margin-left: 4mm; +  } + +  p.concordance_word { +    line-height: 150%; +    font-weight: bold; +    display: inline; +    margin-top: 4px; +    margin-bottom: 1px; +  } +  p.concordance_count { +    font-size: 80%; +    color: #777777; +    display: inline; +    margin-left: 0em; +  } +  p.concordance_object { +    font-size: 80%; +    line-height: 120%; +    text-align: left; +    margin-left: 3em; +    margin-top: 1px; +    margin-bottom: 3px; +  } +  p.book_index_lev1 { +    line-height: 100%; +    margin-top: 4px; +    margin-bottom: 1px; +  } +  p.book_index_lev2 { +    line-height: 100%; +    text-align: left; +    margin-left: 3em; +    margin-top: 1px; +    margin-bottom: 3px; +  } + +  p.quickref { +    font-size: 10px; +    font-style: italic; +    margin-top: 0px; +    margin-bottom: 0px; +    color: #777777; +    margin-right: 5px; +    text-align: left; +  } +  p.bigref { +    font-size: 11px; +    font-weight: bold; +    margin-top: 0px; +    margin-bottom: 0px; +    color: #777777; +    margin-right: 5px; +    text-align: center; +  } + +  p.letter { +    font-weight: bold; +    font-size: 80%; +    margin-left: 0em; +    margin-top: 2px; +    margin-bottom: 2px; +    margin-right: 6px; +    text-align: left; +    color: white; +    background: #880000; +  } + +  tt { +    font-family: inconsolata, andale mono, courier new, courier, monospace; +    background-color: #eeeeee; +  } + +  label.ocn { +    width: 2%; +    float: right; +    top: 0; +    font-size: 10px; +    margin-top: 0px; +    margin-bottom: 5px; +    color: #777777; +    margin-right: 5px; +    text-align: right; +    background-color: #ffffff; +  } + +  table { } +  tr { } +  th,td { +    vertical-align: top; +    text-align: left; +  } +  th { +    font-weight: bold; +  } + +  p.left,th.left,td.left { +    text-align: left; +  } +  p.small_left,th.small_left,td.small_left { +    text-align: left; +    font-size: 80%; +  } +  p.right,th.right,td.right { +    text-align: right; +  } + +  #horizontal_links { +    background: #eeeeee; +    margin-left: 5%; +    margin-right: 5%; +  } +  #horizontal { +    margin: 0; +    padding: 0 0 0 10px; +    border-top: 1px solid #000077; +    border-bottom: 1px solid #000077; +  } +  #horizontal li { +    margin: 0 0 0 0; +    padding: 0 16px 0 0; +    display: inline; +    list-style-type: none; +    text-align: left; +    background: none; +  } +  #horizontal a { +    line-height: 12px; +    margin: 0 0 0 0; +    text-decoration: none; +    color: #000077; +  } +  #horizontal a.active, #horizontal a:hover { +    border-bottom: 2px solid #777777; +    padding-bottom: 2px; +    color: #000077; +  } +  #horizontal a:hover { +    color: #000077; +  } + +  #document_versions { +    position: absolute; +    top: 10mm; +    right: 2%; +    width: 12%; +    float: right; +  } + +  #vertical_links { +    position: absolute; +    top: 10mm; +    right: 0px; +    width: 20%; +    background: #dddddd; +    float: right; +  } +  #vertical { +    padding: 0 12px 0px 0px; +    margin-left: 2%; +    margin-right: 2%; +  } +  #vertical li { +    display: block; +    list-style-type: none; +  } +  #vertical a { +    line-height: 12px; +    text-decoration: none; +    color: #000077; +  } +  #vertical a.active, #vertical a:hover { +    border-bottom: 2px solid #777777; +    padding-bottom: 2px; +    color: #000077; +  } + +  ul, li { +    list-style-type: none; +    list-style: none; +    padding-left: 20px; +    display: block; +    font-family: verdana, arial, georgia, tahoma, sans-serif, helvetica, times, roman; +    font-weight: normal; +    line-height: 150%; +    text-align: left; +    text-indent: 0mm; +    margin-left: 1em; +    margin-right: 2em; +    margin-top: 3px; +    margin-bottom: 3px; +  } + +  li { +    background: url(../image_sys/bullet_09.png) no-repeat 0px 6px; +  } + +  ul { +  } +  li.bullet { margin-left: 1em; } +  li.i1 { margin-left: 2em; } +  li.i2 { margin-left: 3em; } +  li.i3 { margin-left: 4em; } +  li.i4 { margin-left: 5em; } +  li.i5 { margin-left: 6em; } +  li.i6 { margin-left: 7em; } +  li.i7 { margin-left: 8em; } +  li.i8 { margin-left: 9em; } +  li.i9 { margin-left: 10em; } + +  li.doc, li.ref, li.refcenter { +    margin-top: 0px; +    margin-bottom: 0px; +    margin-right: 0px; +    font-size: 8px; +    font-style: normal; +    text-align: left; +  } +  li.doc { +    background: url(../image_sys/bullet_09.png) no-repeat 0px 6px; +    padding-left: 16px; +    margin-left: 10px; +    margin-right: 0px; +  } +  li.ref { +    background: none; +    padding-left: 0; +    margin-left: 0; +    color: #777777; +  } +  li.refcenter { +    background: url(../image_sys/bullet_09.png) no-repeat 0px 6px; +    padding-left: 20px; +    margin-left: 10%; +    font-size: 9px; +    color: #777777; +    text-align: center; +  } +  li.refbold { +    list-style-type: none; +    padding-left: 16px; +    margin-left: 0; +    margin-right: 10mm; +    font-weight: bold; +  } + +  h0, h1, h2, h3, h4, h5, h6, h7 { +    font-weight: bold; +    line-height: 120%; +    text-align: left; +    margin-top: 20px; +    margin-bottom: 10px; +  } +  h4.norm, h5.norm, h6.norm, h7.norm { +    margin-top: 10px; +    margin-bottom: 0px; +  } +  h1.center, h2.center, h3.center, h4.center, h5.center, h6.center, h7.center { +    text-align: center; +  } +  h0 { font-size: 125%; } +  h1 { font-size: 120%; } +  h2 { font-size: 115%; } +  h3 { font-size: 110%; } +  h4 { font-size: 105%; } +  h5 { font-size: 100%; } +  h6 { font-size: 100%; } +  h7 { font-size: 100%; } + +  h1.i {margin-left: 2em;} +  h2.i {margin-left: 3em;} +  h3.i {margin-left: 4em;} +  h4.i {margin-left: 5em;} +  h5.i {margin-left: 6em;} +  h6.i {margin-left: 7em;} +  h7.i {margin-left: 8em;} +  h8.i {margin-left: 9em;} +  h9.i {margin-left: 10em;} +  h1.top_band { +    display: inline; +    text-align: left; +    margin-top: 0; +    margin-left: 4mm; +    text-indent: 0mm; +    font-weight: bold; +    font-size: 120%; +  } +  h2.top_band_tiny { +    font-size: 10px; +    font-weight: normal; +    margin-top: 0px; +    margin-left: 4mm; +    text-indent: 0mm; +    margin-bottom: 0px; +    color: #777777; +    margin-left: 140px; +    margin-right: 0px; +    text-align: left; +  } + +  p.top_band { +    display: inline; +    text-align: left; +    margin-top: 0; +    margin-left: 140px; +    text-indent: 0mm; +    font-weight: bold; +    font-size: 120%; +  } +  p.top_band_tiny { +    font-size: 10px; +    margin-top: 0px; +    margin-bottom: 0px; +    color: #777777; +    margin-left: 140px; +    margin-right: 0px; +    text-align: left; +  } +  p.top_band_image { +    float: left; +    display: inline; +    text-align: left; +    margin-top: 0; +    margin-left: 1mm; +    text-indent: 0mm; +    margin-right: 1mm; +  } + +  .banner, .subbanner { +    font-weight: bold; +    text-align: center; +    margin-left: 10mm; +    margin-right: 15mm; +    margin-top: 20px; +    margin-bottom: 10px; +  } + +  h1.banner { +    font-size: 120%; +  } +  h1.subbanner { +    font-size: 115%; +  } +  h2.banner { +    font-size: 110%; +  } +  h3.banner { +    color: #990000; +    font-size: 105%; +  } +  h4.banner { +    color: #ff0000; +    font-size: 100%; +  } +  h5.banner { +  } +  h6.banner { +  } +  h7.banner { +  } + +  .toc { +    font-weight: normal; +    margin-top: 6px; +    margin-bottom: 6px; +  } +  h1.toc { +    margin-left: 1em; +    font-size: 115%; +    line-height: 150%; +  } +  h2.toc { +    margin-left: 2em; +    font-size: 110%; +    line-height: 140%; +  } +  h3.toc { +    margin-left: 3em; +    font-size: 105%; +    line-height: 120%; +  } +  h4.toc { +    margin-left: 4em; +    font-size: 100%; +    line-height: 120%; +  } +  h5.toc { +    margin-left: 5em; +    font-size: 95%; +    line-height: 110%; +  } +  h6.toc { +    margin-left: 6em; +    font-size: 90%; +    line-height: 110%; +  } +  h7.toc { +    margin-left: 7em; +    font-size: 85%; +    line-height: 100%; +  } + +  .microtoc { +    margin-top: 2px; +    margin-bottom: 2px; +  } + +  h1.microtoc { +    margin-left: 0mm; +    font-size: 115%; +  } +  h2.microtoc { +    margin-left: 5mm; +    font-size: 110%; +  } +  h3.microtoc { +    margin-left: 10mm; +    font-size: 105%; +  } +  h4.microtoc { +    margin-left: 15mm; +    font-weight: normal; +    font-size: 100%; +  } +  h5.microtoc { +    margin-left: 20mm; +    font-weight: normal; +    font-size: 95%; +  } +  h6.microtoc { +    margin-left: 25mm; +    font-weight: normal; +    font-size: 90%; +  } +  h7.microtoc { +    margin-left: 30mm; +    font-weight: normal; +    font-size: 85%; +  } + +  .subtoc { +    margin-right: 34%; +    font-weight: normal; +  } +  h5.subtoc { +    margin-left: 2em; +    font-size: 80%; +    margin-top: 2px; +    margin-bottom: 2px; +  } +  h6.subtoc { +    margin-left: 3em; +    font-size: 75%; +    margin-top: 0px; +    margin-bottom: 0px; +  } +  h7.subtoc { +    margin-left: 4em; +    font-size: 70%; +    margin-top: 0px; +    margin-bottom: 0px; +  } + +  div.substance { +    width: 100%; +    background-color: #ffffff; +  } +  div.ocn { +    width: 5%; +    float: right; +    top: 0; +    background-color: #ffffff; +  } +  div.endnote { +    width: 95%; +    background-color: #fffffff; +  } +  div.toc { +    position: absolute; +    float: left; +    margin: 0; +    padding: 0; +    padding-top: 0.5em; +    border: 0; +    width: 13em; +    background-color: #eeeeee; +    margin-right:1em; +  } +  div.summary { +    margin: 0; +    padding: 0; +    border-left: 13em solid #eeeeee; +    padding-left: 1em; +    background-color: #eeeeee; +  } +  div.content, div.main_column { +    margin: 0; +    padding: 0; +    border-left: 13em solid #ffffff; +    padding-left: 1em; +    padding-right: 1em; +  } +  div.content0, div.main_column0 { +    margin: 0; +    padding: 0; +    border-left: 0% solid #ffffff; +    padding-left: 5%; +  } +  div.scroll { +    margin: 0; +    padding: 0; +    padding-left: 1em; +    padding-right: 1em; +  } +  div.content:after { +    content:' '; +    clear:both; +    display:block; +    height:0; +    overflow:hidden +  } +  div.footer { +    clear:left; +    padding: 0.5em; +    font-size: 80%; +    margin: 0; +  } +  div.toc ul { +    list-style: none; +    padding: 0; +    margin: 0; +  } +  div.toc li ul a, li ul span.currentlink +  { +    font-weight: normal; +    font-size: 90%; +    padding-left: 2em; +    background-color: #eeeeee; +  } +  div.toc a, span.currentlink{ +    display:block; +    text-decoration: none; +    padding-left: 0.5em; +    color: #0000aa; +  } +  hr { +    width: 90%; +  } + +  span.currentlink { +    text-decoration: none; +    background-color: #aaaaf9; +  } + +  div.toc a:visited { +    color: #0000aa; +  } +  div.toc a:hover { +    color: #000000; +    background-color: #f9f9aa; +  } + +  .minitoc { +    font-weight: normal; +    margin-top: 2px; +    margin-bottom: 2px; +  } +  h1.minitoc, h2.minitoc, h3.minitoc { +    margin-left: 0em; +    font-weight: bold; +    text-align: left; +    font-size: 90%; +    margin-top: 4px; +    margin-bottom: 4px; +  } +  h4.minitoc { +    margin-left: 0em; +    font-size: 90%; +  } +  h5.minitoc { +    margin-left: 1em; +    font-size: 85%; +  } +  h6.minitoc { +    margin-left: 2em; +    font-size: 85%; +  } +  h7.minitoc { +    margin-left: 3em; +    font-size: 80%; +  } +  h0.minitoc { +    margin-left: 0em; +    font-size: 90%; +  } + +  h1.c, h2.c, h3.c, h4.c, h5.c, h6.c, h7.c, p.c { +    text-align: center +  } +  h1.red, h2.red, h3.red, h4.red, h5.red, h6.red, h7.red { +    text-align: center; +    color: #ff0000; +    margin-left: 5mm; +    text-indent: 5mm; +    margin-top: 30px; +    margin-bottom: 20px; +    margin-right: 15mm; +  } +  h1.ruby, h2.ruby, h3.ruby, h4.ruby, h5.ruby, h6.ruby, h7.ruby { +    text-align: center; +    color: #990000; +    margin-left: 5mm; +    text-indent: 5mm; +    margin-top: 30px; +    margin-bottom: 20px; +    margin-right: 15mm; +  } +WOK +    end +    def homepage                                  #stylesheet for index, home page +<<WOK +  body {color: black; background: #{the_color.white}; margin:10px 10px 0px 10px; padding:0px;} +  p { line-height: 1.5 } +  a:link      {color: #{the_color.blue_ink};   text-decoration: none; } +  a:visited       {color: #{the_color.blue_ink};   text-decoration: none; } +  a:hover {color: #{the_color.black}; text-decoration: underline; background-color: #{the_color.yellow_light};} +  a:active {color: #{the_color.blue_ink}; text-decoration: underline;} +  #banner { +    background:#{the_color.white}; +  } +  #column_left { +    width:25%; +    float:left; +    background:#b9d4dd; +    padding-bottom:10px; +  } +  #column_center { +    width:55%; +    float:left; +    background:#{the_color.white}; +    padding-bottom:10px; +  } +  #column_right { +    width:20%; +    float:left; +    background:#b9d4dd; +    padding-bottom:10px; +  } +  p,h1,pre { +    font-family: #{the_font.set_fonts}; +    margin:0px 10px 10px 10px; +  } +  h1 { +    font-size:14px; +    padding-top:10px; +  } +  #column_right p { font-size:12px} +  #banner h1 { margin:0px; padding:10px} +WOK +    end +    def xhtml                                     #stylesheet for xhtml +<<WOK +/* SiSU css xhtml & sax.xml default style */ +    document { +      display: block; +      margin-left: 0mm; +      margin-right: 0mm; +    } +    head { +      display: block; +      margin-bottom: 20px; +      background-color: #dddddd; +    } +    metadata { +      display: block; +    } +    meta { +      display: inline; +      line-height: 1; +      font-size: 10px; +      color: #990000; +      margin-right: 2mm; +      margin-top: 0px; +      margin-bottom: 0px; + +    } +    data,md { +      display: inline; +      line-height: 1; +      font-size: 10px; +      color: #000099; +      margin-top: 0px; +      margin-bottom: 0px; +    } +    source_control { +      display: block; +    } +    dc { +      display: block; +      font-family: #{the_font.set_fonts}; +      color: blue; +      background-color: #dddddd; +      font-weight: normal; +      text-align: justify; +      font-size: xx-small; +      line-height: 120%; +      margin-left: 5%; +      margin-right: 5mm; +      margin-top: 0px; +      margin-bottom: 0px; +    } +    sc { +      display: inline; +      color: green; +    } +    keywords,copyright { +      display: block; +      font-family: #{the_font.set_fonts}; +      color: red; +      background-color: #dddddd; +      font-weight: normal; +      text-align: justify; +      font-size: xx-small; +      line-height: 120%; +      margin-left: 5%; +      margin-right: 5mm; +      margin-top: 0px; +      margin-bottom: 0px; +    } +    table { +      margin-left: 5%; +      display: block; +    } +    tr { +      display: block; +    } +    th,td { +      display: inline; +    } +    body { +      color: black; +      background: #ffffff; +    } +    a:link { +      color: #003399; +      text-decoration: none; +    } +    a:visited { +      color: #003399; +      text-decoration: none; +      /* background-color: #e3ecef; */ +    } +    a:hover { +      color: #000000; +      text-decoration: underline; +      background-color: #fff3b6; +    } +    a:hover IMG { +      background-color: #ffffff; +    } +    a:active { +      color: #003399; +      text-decoration: underline; +    } +    object { +      display: block; +      margin-left: 2mm; +      margin-right: 2mm; +      margin-top: 4px; +      margin-bottom: 8px; +    } +    text,text[class|="norm"] { +      display: block; +      font-family: #{the_font.set_fonts}; +      text-align: justify; +      font-weight: normal; +      font-size: 100%; +      line-height: 150%; +      margin-left: 5%; +      margin-right: 5%; +      margin-top: 2px; +      margin-bottom: 0px; +    } +    text[class|="h1"] { +      font-size: 120%; +      font-weight: bold; +      text-align: left; +      line-height: 120%; +      margin-top: 20px; +      margin-bottom: 10px; +    } +    text[class|="h2"] { +      font-weight: bold; +      font-size: 110%; +      text-align: left; +      margin-top: 20px; +      margin-bottom: 10px; +    } +    text[class|="h3"] { +      font-size: 110%; +      font-weight: bold; +      text-align: left; +    } +    text[class|="h4"] { +      font-size: 110%; +      font-weight: bold; +      text-align: left; +    } +    text[class|="h5"] { +      font-size: 110%; +      font-weight: bold; +      text-align: left; +    } +    text[class|="h6"] { +      font-size: 110%; +      font-weight: bold; +      text-align: left; +    } +    text[class|="h7"] { +      font-size: 110%; +      font-weight: bold; +      text-align: left; +    } +    text[class|="indent0"] { +      padding-left: 10%; +    } +    text[class|="indent1"] { +      padding-left: 15%; +    } +    text[class|="indent2"] { +      padding-left: 20%; +    } +    text[class|="indent3"] { +      padding-left: 25%; +    } +    text[class|="indent4"] { +      padding-left: 30%; +    } +    text[class|="indent5"] { +      padding-left: 35%; +    } +    text[class|="indent6"] { +      padding-left: 40%; +    } +    text[class|="indent7"] { +      padding-left: 45%; +    } +    text[class|="indent8"] { +      padding-left: 50%; +    } +    text[class|="indent9"] { +      padding-left: 55%; +    } + +    text[class|="hang0_indent0"] { +      padding-left: 10%; +      text-indent:   0%; +    } +    text[class|="hang0_indent1"] { +      padding-left: 15%; +      text-indent:  -5%; +    } +    text[class|="hang0_indent2"] { +      padding-left: 20%; +      text-indent: -10%; +    } +    text[class|="hang0_indent3"] { +      padding-left: 25%; +      text-indent: -15%; +    } +    text[class|="hang0_indent4"] { +      padding-left: 30%; +      text-indent: -20%; +    } +    text[class|="hang0_indent5"] { +      padding-left: 35%; +      text-indent: -25%; +    } +    text[class|="hang0_indent6"] { +      padding-left: 40%; +      text-indent: -30%; +    } +    text[class|="hang0_indent7"] { +      padding-left: 45%; +      text-indent: -35%; +    } +    text[class|="hang0_indent8"] { +      padding-left: 50%; +      text-indent: -40%; +    } +    text[class|="hang0_indent9"] { +      padding-left: 55%; +      text-indent: -45%; +    } + +    text[class|="hang1_indent0"] { +      padding-left: 10%; +      text-indent:   5%; +    } +    text[class|="hang1_indent1"] { +      padding-left: 15%; +      text-indent:   0%; +    } +    text[class|="hang1_indent2"] { +      padding-left: 20%; +      text-indent:  -5%; +    } +    text[class|="hang1_indent3"] { +      padding-left: 25%; +      text-indent: -10%; +    } +    text[class|="hang1_indent4"] { +      padding-left: 30%; +      text-indent: -15%; +    } +    text[class|="hang1_indent5"] { +      padding-left: 35%; +      text-indent: -20%; +    } +    text[class|="hang1_indent6"] { +      padding-left: 40%; +      text-indent: -25%; +    } +    text[class|="hang1_indent7"] { +      padding-left: 45%; +      text-indent: -30%; +    } +    text[class|="hang1_indent8"] { +      padding-left: 50%; +      text-indent: -35%; +    } +    text[class|="hang1_indent9"] { +      padding-left: 55%; +      text-indent: -40%; +    } + +    text[class|="hang2_indent0"] { +      padding-left: 10%; +      text-indent:  10%; +    } +    text[class|="hang2_indent1"] { +      padding-left: 15%; +      text-indent:   5%; +    } +    text[class|="hang2_indent2"] { +      padding-left: 20%; +      text-indent:   0%; +    } +    text[class|="hang2_indent3"] { +      padding-left: 25%; +      text-indent:  -5%; +    } +    text[class|="hang2_indent4"] { +      padding-left: 30%; +      text-indent: -10%; +    } +    text[class|="hang2_indent5"] { +      padding-left: 35%; +      text-indent: -15%; +    } +    text[class|="hang2_indent6"] { +      padding-left: 40%; +      text-indent: -20%; +    } +    text[class|="hang2_indent7"] { +      padding-left: 45%; +      text-indent: -25%; +    } +    text[class|="hang2_indent8"] { +      padding-left: 50%; +      text-indent: -30%; +    } +    text[class|="hang2_indent9"] { +      padding-left: 55%; +      text-indent: -35%; +    } + +    text[class|="hang3_indent0"] { +      padding-left: 10%; +      text-indent:  15%; +    } +    text[class|="hang3_indent1"] { +      padding-left: 15%; +      text-indent:  10%; +    } +    text[class|="hang3_indent2"] { +      padding-left: 20%; +      text-indent:   5%; +    } +    text[class|="hang3_indent3"] { +      padding-left: 25%; +      text-indent:   0%; +    } +    text[class|="hang3_indent4"] { +      padding-left: 30%; +      text-indent:  -5%; +    } +    text[class|="hang3_indent5"] { +      padding-left: 35%; +      text-indent: -10%; +    } +    text[class|="hang3_indent6"] { +      padding-left: 40%; +      text-indent: -15%; +    } +    text[class|="hang3_indent7"] { +      padding-left: 45%; +      text-indent: -20%; +    } +    text[class|="hang3_indent8"] { +      padding-left: 50%; +      text-indent: -25%; +    } +    text[class|="hang3_indent9"] { +      padding-left: 55%; +      text-indent: -30%; +    } + +    text[class|="hang4_indent0"] { +      padding-left: 10%; +      text-indent:  20%; +    } +    text[class|="hang4_indent1"] { +      padding-left: 15%; +      text-indent:  15%; +    } +    text[class|="hang4_indent2"] { +      padding-left: 20%; +      text-indent:  10%; +    } +    text[class|="hang4_indent3"] { +      padding-left: 25%; +      text-indent:   5%; +    } +    text[class|="hang4_indent4"] { +      padding-left: 30%; +      text-indent:   0%; +    } +    text[class|="hang4_indent5"] { +      padding-left: 35%; +      text-indent:  -5%; +    } +    text[class|="hang4_indent6"] { +      padding-left: 40%; +      text-indent: -10%; +    } +    text[class|="hang4_indent7"] { +      padding-left: 45%; +      text-indent: -15%; +    } +    text[class|="hang4_indent8"] { +      padding-left: 50%; +      text-indent: -20%; +    } +    text[class|="hang4_indent9"] { +      padding-left: 55%; +      text-indent: -25%; +    } + +    text[class|="hang5_indent0"] { +      padding-left: 10%; +      text-indent:  25%; +    } +    text[class|="hang5_indent1"] { +      padding-left: 15%; +      text-indent:  20%; +    } +    text[class|="hang5_indent2"] { +      padding-left: 20%; +      text-indent:  15%; +    } +    text[class|="hang5_indent3"] { +      padding-left: 25%; +      text-indent:  10%; +    } +    text[class|="hang5_indent4"] { +      padding-left: 30%; +      text-indent:   5%; +    } +    text[class|="hang5_indent5"] { +      padding-left: 35%; +      text-indent:   0%; +    } +    text[class|="hang5_indent6"] { +      padding-left: 40%; +      text-indent:  -5%; +    } +    text[class|="hang5_indent7"] { +      padding-left: 45%; +      text-indent: -10%; +    } +    text[class|="hang5_indent8"] { +      padding-left: 50%; +      text-indent: -15%; +    } +    text[class|="hang5_indent9"] { +      padding-left: 55%; +      text-indent: -20%; +    } + +    text[class|="hang6_indent0"] { +      padding-left: 10%; +      text-indent:  30%; +    } +    text[class|="hang6_indent1"] { +      padding-left: 15%; +      text-indent:  25%; +    } +    text[class|="hang6_indent2"] { +      padding-left: 20%; +      text-indent:  20%; +    } +    text[class|="hang6_indent3"] { +      padding-left: 25%; +      text-indent:  15%; +    } +    text[class|="hang6_indent4"] { +      padding-left: 30%; +      text-indent:  10%; +    } +    text[class|="hang6_indent5"] { +      padding-left: 35%; +      text-indent:   5%; +    } +    text[class|="hang6_indent6"] { +      padding-left: 40%; +      text-indent:   0%; +    } +    text[class|="hang6_indent7"] { +      padding-left: 45%; +      text-indent:  -5%; +    } +    text[class|="hang6_indent8"] { +      padding-left: 50%; +      text-indent: -10%; +    } +    text[class|="hang6_indent9"] { +      padding-left: 55%; +      text-indent: -15%; +    } + +    text[class|="hang7_indent0"] { +      padding-left: 10%; +      text-indent:  35%; +    } +    text[class|="hang7_indent1"] { +      padding-left: 15%; +      text-indent:  30%; +    } +    text[class|="hang7_indent2"] { +      padding-left: 20%; +      text-indent:  25%; +    } +    text[class|="hang7_indent3"] { +      padding-left: 25%; +      text-indent:  20%; +    } +    text[class|="hang7_indent4"] { +      padding-left: 30%; +      text-indent:  15%; +    } +    text[class|="hang7_indent5"] { +      padding-left: 35%; +      text-indent:  10%; +    } +    text[class|="hang7_indent6"] { +      padding-left: 40%; +      text-indent:   5%; +    } +    text[class|="hang7_indent7"] { +      padding-left: 45%; +      text-indent:   0%; +    } +    text[class|="hang7_indent8"] { +      padding-left: 50%; +      text-indent:  -5%; +    } +    text[class|="hang7_indent9"] { +      padding-left: 55%; +      text-indent: -10%; +    } + +    text[class|="hang8_indent0"] { +      padding-left: 10%; +      text-indent:  40%; +    } +    text[class|="hang8_indent1"] { +      padding-left: 15%; +      text-indent:  35%; +    } +    text[class|="hang8_indent2"] { +      padding-left: 20%; +      text-indent:  30%; +    } +    text[class|="hang8_indent3"] { +      padding-left: 25%; +      text-indent:  25%; +    } +    text[class|="hang8_indent4"] { +      padding-left: 30%; +      text-indent:  20%; +    } +    text[class|="hang8_indent5"] { +      padding-left: 35%; +      text-indent:  15%; +    } +    text[class|="hang8_indent6"] { +      padding-left: 40%; +      text-indent:  10%; +    } +    text[class|="hang8_indent7"] { +      padding-left: 45%; +      text-indent:   5%; +    } +    text[class|="hang8_indent8"] { +      padding-left: 50%; +      text-indent:   0%; +    } +    text[class|="hang8_indent9"] { +      padding-left: 55%; +      text-indent:  -5%; +    } + +    text[class|="hang9_indent0"] { +      padding-left: 10%; +      text-indent:  45%; +    } +    text[class|="hang9_indent1"] { +      padding-left: 15%; +      text-indent:  40%; +    } +    text[class|="hang9_indent2"] { +      padding-left: 20%; +      text-indent:  35%; +    } +    text[class|="hang9_indent3"] { +      padding-left: 25%; +      text-indent:  30%; +    } +    text[class|="hang9_indent4"] { +      padding-left: 30%; +      text-indent:  25%; +    } +    text[class|="hang9_indent5"] { +      padding-left: 35%; +      text-indent:  20%; +    } +    text[class|="hang9_indent6"] { +      padding-left: 40%; +      text-indent:  15%; +    } +    text[class|="hang9_indent7"] { +      padding-left: 45%; +      text-indent:  10%; +    } +    text[class|="hang9_indent8"] { +      padding-left: 50%; +      text-indent:   5%; +    } +    text[class|="hang9_indent9"] { +      padding-left: 55%; +      text-indent:   0%; +    } + +    text[class|="indent_bullet"] { +      text-indent: 0%; +    } +    text[class|="indent_bullet0"] { +      text-indent: 0%; +    } +    text[class|="indent_bullet1"] { +      text-indent: 10%; +    } +    text[class|="indent_bullet2"] { +      text-indent: 15%; +    } +    text[class|="indent_bullet3"] { +      text-indent: 20%; +    } +    text[class|="indent_bullet4"] { +      text-indent: 25%; +    } +    text[class|="indent_bullet5"] { +      text-indent: 30%; +    } +    text[class|="indent_bullet6"] { +      text-indent: 35%; +    } +    text[class|="indent_bullet7"] { +      text-indent: 40%; +    } +    text[class|="indent_bullet8"] { +      text-indent: 45%; +    } +    text[class|="indent_bullet9"] { +      text-indent: 50%; +    } +    text[class|="verse"], text[class|="block"], text[class|="group"], text[class|="code"] { +      text-align: left; +    } +    ocn { +      display: block; +      text-align: right; +      vertical-align: super; +      color: #990000; +      font-size: xx-small; +      margin-right: 0mm; +      margin-top: 0px; +      margin-bottom: 0px; +    } +    named { +      display: block; +      margin-right: 0mm; +      margin-top: 0px; +      margin-bottom: 0px; +    } +    endnote { +      display: block; +      font-size: small; +      font-family: #{the_font.set_fonts}; +      font-weight: normal; +      line-height: 150%; +      text-align: justify; +      margin-left: 10%; +      margin-right: 5%; +      margin-top: 4px; +      margin-bottom: 0px; +    } +    endnote_indent { +      display: block; +      font-size: small; +      font-family: #{the_font.set_fonts}; +      font-weight: normal; +      line-height: 150%; +      text-align: justify; +      margin-left: 15%; +      margin-right: 5%; +      margin-top: 4px; +      margin-bottom: 0px; +    } +    en { +      font-size: xx-small; +      vertical-align: super; +    } +    i { font-style: italic; } +    b { font-style: bold; } +    u { text-decoration: underline; } +    br { display: block; } + +    text[class|="table"] { +      display: table; +      /* display: block; */ +      text-align: left; +    } + +    table { +      margin-left: 0%; +      display: block; +      /* display: table; */ +      width: 100%; +    } +    tr { +      display: block; +      /* display: table-row; */ +    } +    th, td { +      display: table-cell; +      /* display: inline; */ +      vertical-align: top; +    } +    p.left, th.left, td.left { +      text-align: left; +    } +    p.small_left, th.small_left, td.small_left { +      text-align: left; +      font-size: 80%; +    } +    p.right, th.right, td.right { +      text-align: right; +    } + +    .svg_outer { +      display: block; +      margin-bottom: 0; +      margin-left: 0; +      margin-right: 0; +      margin-top: 0; +      padding-bottom: 0; +      padding-left: 0; +      padding-right: 0; +      padding-top: 0; +      text-align: left; +    } +    .svg_inner { +      display: block; +      text-align: center; +    } +WOK +    end +    def xml_sax                                   #stylesheet for xml sax +      xhtml +    end +    def xml_dom                                   #sylesheet for xml dom, work on, starts from copy of css_xhtml +<<WOK +/* SiSU css dom.xml default style */ +    document { +      display: block; +      margin-left: 0mm; +      margin-right: 0mm; +    } +    head { +      display: block; +      margin-bottom: 20px; +      background-color: #dddddd; +    } +    header { +      display: block; +    } +    meta { +      display: inline; +      line-height: 1; +      font-size: 10px; +      color: #990000; +      margin-right: 2mm; +      margin-top: 0px; +      margin-bottom: 0px; + +    } +    md { +      display: inline; +      line-height: 1; +      font-size: 10px; +      color: #000099; +      margin-top: 0px; +      margin-bottom: 0px; +    } +    source_control { +      display: block; +    } +    dc { +      display: block; +      font-family: #{the_font.set_fonts}; +      color: blue; +      background-color: #dddddd; +      font-weight: normal; +      text-align: justify; +      font-size: xx-small; +      line-height: 120%; +      margin-left: 5%; +      margin-right: 5mm; +      margin-top: 0px; +      margin-bottom: 0px; +    } +    sc { +      display: inline; +      color: green; +    } +    keywords,copyright { +      display: block; +      font-family: #{the_font.set_fonts}; +      color: red; +      background-color: #dddddd; +      font-weight: normal; +      text-align: justify; +      font-size: xx-small; +      line-height: 120%; +      margin-left: 5%; +      margin-right: 5mm; +      margin-top: 0px; +      margin-bottom: 0px; +    } +    body { +      color: black; +      background: #ffffff; +    } +    a:link { +      color: #003399; +      text-decoration: none; +    } +    a:visited { +      color: #003399; +      text-decoration: none; +      /* background-color: #e3ecef; */ +    } +    a:hover { +      color: #000000; +      text-decoration: underline; +      background-color: #fff3b6; +    } +    a:hover IMG { +      background-color: #ffffff; +    } +    a:active { +      color: #003399; +      text-decoration: underline; +    } +    object { +      display: block; +      margin-left: 2mm; +      margin-right: 2mm; +      margin-top: 4px; +      margin-bottom: 8px; +    } +    heading { +      font-weight: bold; +    } +    contents { +      font-weight: normal; +    } +    text { +      display: block; +      font-family: #{the_font.set_fonts}; +      text-align: justify; +      font-size: 100%; +      line-height: 150%; +      margin-left: 5%; +      margin-right: 5%; +      margin-top: 2px; +      margin-bottom: 0px; +    } +    text[class|="norm"] { +      font-weight: normal; +    } +    text[class|="h1"] { +      font-size: 120%; +      font-weight: bold; +      text-align: left; +      line-height: 120%; +      margin-top: 20px; +      margin-bottom: 10px; +    } +    text[class|="h2"] { +      font-weight: bold; +      font-size: 110%; +      text-align: left; +      margin-top: 20px; +      margin-bottom: 10px; +    } +    text[class|="h3"] { +      font-size: 110%; +      font-weight: bold; +      text-align: left; +    } +    text[class|="h4"] { +      font-size: 110%; +      font-weight: bold; +      text-align: left; +    } +    text[class|="h5"] { +      font-size: 110%; +      font-weight: bold; +      text-align: left; +    } +    text[class|="h6"] { +      font-size: 110%; +      font-weight: bold; +      text-align: left; +    } +    text[class|="h7"] { +      font-size: 110%; +      font-weight: bold; +      text-align: left; +    } +    text[class|="indent0"] { +      padding-left: 10%; +    } +    text[class|="indent1"] { +      padding-left: 15%; +    } +    text[class|="indent2"] { +      padding-left: 20%; +    } +    text[class|="indent3"] { +      padding-left: 25%; +    } +    text[class|="indent4"] { +      padding-left: 30%; +    } +    text[class|="indent5"] { +      padding-left: 35%; +    } +    text[class|="indent6"] { +      padding-left: 40%; +    } +    text[class|="indent7"] { +      padding-left: 45%; +    } +    text[class|="indent8"] { +      padding-left: 50%; +    } +    text[class|="indent9"] { +      padding-left: 55%; +    } + +    text[class|="hang0_indent0"] { +      padding-left: 10%; +      text-indent:   0%; +    } +    text[class|="hang0_indent1"] { +      padding-left: 15%; +      text-indent:  -5%; +    } +    text[class|="hang0_indent2"] { +      padding-left: 20%; +      text-indent: -10%; +    } +    text[class|="hang0_indent3"] { +      padding-left: 25%; +      text-indent: -15%; +    } +    text[class|="hang0_indent4"] { +      padding-left: 30%; +      text-indent: -20%; +    } +    text[class|="hang0_indent5"] { +      padding-left: 35%; +      text-indent: -25%; +    } +    text[class|="hang0_indent6"] { +      padding-left: 40%; +      text-indent: -30%; +    } +    text[class|="hang0_indent7"] { +      padding-left: 45%; +      text-indent: -35%; +    } +    text[class|="hang0_indent8"] { +      padding-left: 50%; +      text-indent: -40%; +    } +    text[class|="hang0_indent9"] { +      padding-left: 55%; +      text-indent: -45%; +    } + +    text[class|="hang1_indent0"] { +      padding-left: 10%; +      text-indent:   5%; +    } +    text[class|="hang1_indent1"] { +      padding-left: 15%; +      text-indent:   0%; +    } +    text[class|="hang1_indent2"] { +      padding-left: 20%; +      text-indent:  -5%; +    } +    text[class|="hang1_indent3"] { +      padding-left: 25%; +      text-indent: -10%; +    } +    text[class|="hang1_indent4"] { +      padding-left: 30%; +      text-indent: -15%; +    } +    text[class|="hang1_indent5"] { +      padding-left: 35%; +      text-indent: -20%; +    } +    text[class|="hang1_indent6"] { +      padding-left: 40%; +      text-indent: -25%; +    } +    text[class|="hang1_indent7"] { +      padding-left: 45%; +      text-indent: -30%; +    } +    text[class|="hang1_indent8"] { +      padding-left: 50%; +      text-indent: -35%; +    } +    text[class|="hang1_indent9"] { +      padding-left: 55%; +      text-indent: -40%; +    } + +    text[class|="hang2_indent0"] { +      padding-left: 10%; +      text-indent:  10%; +    } +    text[class|="hang2_indent1"] { +      padding-left: 15%; +      text-indent:   5%; +    } +    text[class|="hang2_indent2"] { +      padding-left: 20%; +      text-indent:   0%; +    } +    text[class|="hang2_indent3"] { +      padding-left: 25%; +      text-indent:  -5%; +    } +    text[class|="hang2_indent4"] { +      padding-left: 30%; +      text-indent: -10%; +    } +    text[class|="hang2_indent5"] { +      padding-left: 35%; +      text-indent: -15%; +    } +    text[class|="hang2_indent6"] { +      padding-left: 40%; +      text-indent: -20%; +    } +    text[class|="hang2_indent7"] { +      padding-left: 45%; +      text-indent: -25%; +    } +    text[class|="hang2_indent8"] { +      padding-left: 50%; +      text-indent: -30%; +    } +    text[class|="hang2_indent9"] { +      padding-left: 55%; +      text-indent: -35%; +    } + +    text[class|="hang3_indent0"] { +      padding-left: 10%; +      text-indent:  15%; +    } +    text[class|="hang3_indent1"] { +      padding-left: 15%; +      text-indent:  10%; +    } +    text[class|="hang3_indent2"] { +      padding-left: 20%; +      text-indent:   5%; +    } +    text[class|="hang3_indent3"] { +      padding-left: 25%; +      text-indent:   0%; +    } +    text[class|="hang3_indent4"] { +      padding-left: 30%; +      text-indent:  -5%; +    } +    text[class|="hang3_indent5"] { +      padding-left: 35%; +      text-indent: -10%; +    } +    text[class|="hang3_indent6"] { +      padding-left: 40%; +      text-indent: -15%; +    } +    text[class|="hang3_indent7"] { +      padding-left: 45%; +      text-indent: -20%; +    } +    text[class|="hang3_indent8"] { +      padding-left: 50%; +      text-indent: -25%; +    } +    text[class|="hang3_indent9"] { +      padding-left: 55%; +      text-indent: -30%; +    } + +    text[class|="hang4_indent0"] { +      padding-left: 10%; +      text-indent:  20%; +    } +    text[class|="hang4_indent1"] { +      padding-left: 15%; +      text-indent:  15%; +    } +    text[class|="hang4_indent2"] { +      padding-left: 20%; +      text-indent:  10%; +    } +    text[class|="hang4_indent3"] { +      padding-left: 25%; +      text-indent:   5%; +    } +    text[class|="hang4_indent4"] { +      padding-left: 30%; +      text-indent:   0%; +    } +    text[class|="hang4_indent5"] { +      padding-left: 35%; +      text-indent:  -5%; +    } +    text[class|="hang4_indent6"] { +      padding-left: 40%; +      text-indent: -10%; +    } +    text[class|="hang4_indent7"] { +      padding-left: 45%; +      text-indent: -15%; +    } +    text[class|="hang4_indent8"] { +      padding-left: 50%; +      text-indent: -20%; +    } +    text[class|="hang4_indent9"] { +      padding-left: 55%; +      text-indent: -25%; +    } + +    text[class|="hang5_indent0"] { +      padding-left: 10%; +      text-indent:  25%; +    } +    text[class|="hang5_indent1"] { +      padding-left: 15%; +      text-indent:  20%; +    } +    text[class|="hang5_indent2"] { +      padding-left: 20%; +      text-indent:  15%; +    } +    text[class|="hang5_indent3"] { +      padding-left: 25%; +      text-indent:  10%; +    } +    text[class|="hang5_indent4"] { +      padding-left: 30%; +      text-indent:   5%; +    } +    text[class|="hang5_indent5"] { +      padding-left: 35%; +      text-indent:   0%; +    } +    text[class|="hang5_indent6"] { +      padding-left: 40%; +      text-indent:  -5%; +    } +    text[class|="hang5_indent7"] { +      padding-left: 45%; +      text-indent: -10%; +    } +    text[class|="hang5_indent8"] { +      padding-left: 50%; +      text-indent: -15%; +    } +    text[class|="hang5_indent9"] { +      padding-left: 55%; +      text-indent: -20%; +    } + +    text[class|="hang6_indent0"] { +      padding-left: 10%; +      text-indent:  30%; +    } +    text[class|="hang6_indent1"] { +      padding-left: 15%; +      text-indent:  25%; +    } +    text[class|="hang6_indent2"] { +      padding-left: 20%; +      text-indent:  20%; +    } +    text[class|="hang6_indent3"] { +      padding-left: 25%; +      text-indent:  15%; +    } +    text[class|="hang6_indent4"] { +      padding-left: 30%; +      text-indent:  10%; +    } +    text[class|="hang6_indent5"] { +      padding-left: 35%; +      text-indent:   5%; +    } +    text[class|="hang6_indent6"] { +      padding-left: 40%; +      text-indent:   0%; +    } +    text[class|="hang6_indent7"] { +      padding-left: 45%; +      text-indent:  -5%; +    } +    text[class|="hang6_indent8"] { +      padding-left: 50%; +      text-indent: -10%; +    } +    text[class|="hang6_indent9"] { +      padding-left: 55%; +      text-indent: -15%; +    } + +    text[class|="hang7_indent0"] { +      padding-left: 10%; +      text-indent:  35%; +    } +    text[class|="hang7_indent1"] { +      padding-left: 15%; +      text-indent:  30%; +    } +    text[class|="hang7_indent2"] { +      padding-left: 20%; +      text-indent:  25%; +    } +    text[class|="hang7_indent3"] { +      padding-left: 25%; +      text-indent:  20%; +    } +    text[class|="hang7_indent4"] { +      padding-left: 30%; +      text-indent:  15%; +    } +    text[class|="hang7_indent5"] { +      padding-left: 35%; +      text-indent:  10%; +    } +    text[class|="hang7_indent6"] { +      padding-left: 40%; +      text-indent:   5%; +    } +    text[class|="hang7_indent7"] { +      padding-left: 45%; +      text-indent:   0%; +    } +    text[class|="hang7_indent8"] { +      padding-left: 50%; +      text-indent:  -5%; +    } +    text[class|="hang7_indent9"] { +      padding-left: 55%; +      text-indent: -10%; +    } + +    text[class|="hang8_indent0"] { +      padding-left: 10%; +      text-indent:  40%; +    } +    text[class|="hang8_indent1"] { +      padding-left: 15%; +      text-indent:  35%; +    } +    text[class|="hang8_indent2"] { +      padding-left: 20%; +      text-indent:  30%; +    } +    text[class|="hang8_indent3"] { +      padding-left: 25%; +      text-indent:  25%; +    } +    text[class|="hang8_indent4"] { +      padding-left: 30%; +      text-indent:  20%; +    } +    text[class|="hang8_indent5"] { +      padding-left: 35%; +      text-indent:  15%; +    } +    text[class|="hang8_indent6"] { +      padding-left: 40%; +      text-indent:  10%; +    } +    text[class|="hang8_indent7"] { +      padding-left: 45%; +      text-indent:   5%; +    } +    text[class|="hang8_indent8"] { +      padding-left: 50%; +      text-indent:   0%; +    } +    text[class|="hang8_indent9"] { +      padding-left: 55%; +      text-indent:  -5%; +    } + +    text[class|="hang9_indent0"] { +      padding-left: 10%; +      text-indent:  45%; +    } +    text[class|="hang9_indent1"] { +      padding-left: 15%; +      text-indent:  40%; +    } +    text[class|="hang9_indent2"] { +      padding-left: 20%; +      text-indent:  35%; +    } +    text[class|="hang9_indent3"] { +      padding-left: 25%; +      text-indent:  30%; +    } +    text[class|="hang9_indent4"] { +      padding-left: 30%; +      text-indent:  25%; +    } +    text[class|="hang9_indent5"] { +      padding-left: 35%; +      text-indent:  20%; +    } +    text[class|="hang9_indent6"] { +      padding-left: 40%; +      text-indent:  15%; +    } +    text[class|="hang9_indent7"] { +      padding-left: 45%; +      text-indent:  10%; +    } +    text[class|="hang9_indent8"] { +      padding-left: 50%; +      text-indent:   5%; +    } +    text[class|="hang9_indent9"] { +      padding-left: 55%; +      text-indent:   0%; +    } + +    text[class|="indent_bullet"] { +      text-indent: 0%; +    } +    text[class|="indent_bullet0"] { +      text-indent: 0%; +    } +    text[class|="indent_bullet1"] { +      padding-left: 10%; +    } +    text[class|="indent_bullet2"] { +      padding-left: 15%; +    } +    text[class|="indent_bullet3"] { +      padding-left: 20%; +    } +    text[class|="indent_bullet4"] { +      padding-left: 25%; +    } +    text[class|="indent_bullet5"] { +      padding-left: 30%; +    } +    text[class|="indent_bullet6"] { +      padding-left: 35%; +    } +    text[class|="indent_bullet7"] { +      padding-left: 40%; +    } +    text[class|="indent_bullet8"] { +      padding-left: 45%; +    } +    text[class|="indent_bullet9"] { +      padding-left: 50%; +    } +    text[class|="verse"], text[class|="block"], text[class|="group"], text[class|="code"] { +      text-align: left; +    } +    table { +      margin-left: 5%; +      display: block; +    } +    tr { +      display: block; +    } +    th, td { +      display: inline; +    } +    nametag { +      display: none; +    } +    number { +      padding-right: 4px; +    } +    ocn { +      font-weight: normal; +      display: block; +      text-align: right; +      vertical-align: super; +      color: #990000; +      font-size: xx-small; +      margin-right: 0mm; +      margin-top: 0px; +      margin-bottom: 0px; +    } +    endnote { +      display: block; +      font-size: small; +      font-family: #{the_font.set_fonts}; +      font-weight: normal; +      line-height: 150%; +      text-align: justify; +      margin-left: 10%; +      margin-right: 5%; +      margin-top: 4px; +      margin-bottom: 0px; +    } +    endnote_indent { +      display: block; +      font-size: small; +      font-family: #{the_font.set_fonts}; +      font-weight: normal; +      line-height: 150%; +      text-align: justify; +      margin-left: 15%; +      margin-right: 5%; +      margin-top: 4px; +      margin-bottom: 0px; +    } +    en { +      font-size: xx-small; +      vertical-align: super; +    } +    i { font-style: italic; } +    b { font-style: bold; } +    u { text-decoration: underline; } +    br { display: block; } +WOK +    end +    def xml_docbook                               #stylesheet for docbook +<<WOK +/* SiSU css docbook.xml default style */ +    book { +      display: block; +      margin-left: 0mm; +      margin-right: 0mm; +    } +    bookinfo { +      display: block; +      margin-bottom: 20px; +      background-color: #dddddd; +    } +    source_control { +      display: block; +    } +    dc,sc { +      display: block; +      font-family: #{the_font.set_fonts}; +      color: blue; +      background-color: #dddddd; +      font-weight: normal; +      text-align: justify; +      font-size: xx-small; +      line-height: 120%; +      margin-left: 5%; +      margin-right: 5mm; +      margin-top: 0px; +      margin-bottom: 0px; +    } +    sc { +      color: green; +    } +    keywords,copyright { +      display: block; +      font-family: #{the_font.set_fonts}; +      color: red; +      background-color: #dddddd; +      font-weight: normal; +      text-align: justify; +      font-size: xx-small; +      line-height: 120%; +      margin-left: 5%; +      margin-right: 5mm; +      margin-top: 0px; +      margin-bottom: 0px; +    } +    body { +      color: black; +      background: #ffffff; +    } +    a:link { +      color: #003399; +      text-decoration: none; +    } +    a:visited { +      color: #003399; +      text-decoration: none; +      /* background-color: #e3ecef; */ +    } +    a:hover { +      color: #000000; +      text-decoration: underline; +      background-color: #fff3b6; +    } +    a:hover IMG { +      background-color: #ffffff; +    } +    a:active { +      color: #003399; +      text-decoration: underline; +    } +    object { +      display: block; +      margin-left: 2mm; +      margin-right: 2mm; +      margin-top: 4px; +      margin-bottom: 8px; +    } +    part { +      display: block; +      /* font-weight: bold; */ +    } +    contents { +      font-weight: normal; +    } +    para { +      display: block; +      font-family: #{the_font.set_fonts}; +      /* font-weight: normal; */ +      text-align: justify; +      font-size: 100%; +      line-height: 150%; +      margin-left: 5%; +      margin-right: 5%; +      margin-top: 2px; +      margin-bottom: 0px; +    } +    para.verse, para.block, para.group, para.code { +      text-align: left; +    } +    para.norm { +      font-family: #{the_font.set_fonts}; +      font-weight: normal; +    } +    para.h1, title { +      display: block; +      font-family: #{the_font.set_fonts}; +      font-size: 120%; +      font-weight: bold; +      text-align: left; +      line-height: 120%; +      margin-top: 20px; +      margin-bottom: 10px; +    } +    para.h2 { +      font-weight: bold; +      font-size: 110%; +      text-align: left; +      margin-top: 20px; +      margin-bottom: 10px; +    } +    para.h3 { +      font-size: 110%; +      font-weight: bold; +      text-align: left; +    } +    para.h4 { +      font-size: 110%; +      font-weight: bold; +      text-align: left; +    } +    para.h5 { +      font-size: 110%; +      font-weight: bold; +      text-align: left; +    } +    para.h6 { +      font-size: 110%; +      font-weight: bold; +      text-align: left; +    } +    para.h7 { +      font-size: 110%; +      font-weight: bold; +      text-align: left; +    } +    table { +      margin-left: 5%; +      display: block; +    } +    tr { +      display: block; +    } +    th, td { +      display: inline; +    } +    nametag { +      display: none; +    } +    number { +      padding-right: 4px; +    } +    ocn { +      font-weight: normal; +      display: block; +      text-align: right; +      vertical-align: super; +      color: #990000; +      font-size: xx-small; +      margin-right: 0mm; +      margin-top: 0px; +      margin-bottom: 0px; +    } +    endnote { +      display: block; +      font-size: small; +      font-family: #{the_font.set_fonts}; +      font-weight: normal; +      line-height: 150%; +      text-align: justify; +      margin-left: 10%; +      margin-right: 5%; +      margin-top: 4px; +      margin-bottom: 0px; +    } +    endnote_indent { +      display: block; +      font-size: small; +      font-family: #{the_font.set_fonts}; +      font-weight: normal; +      line-height: 150%; +      text-align: justify; +      margin-left: 15%; +      margin-right: 5%; +      margin-top: 4px; +      margin-bottom: 0px; +    } +    en { +      font-size: xx-small; +      vertical-align: super; +    } +    i { font-style: italic; } +    b { font-style: bold; } +    u { text-decoration: underline; } +    br { display: block; } +WOK +    end +    def css_xhtml_p                               #stylesheet for ... +<<WOK +    body { +      color: black; +      background: #ffffff; +    } +    a:link { +      color: #003399; +      text-decoration: none; +    } +    a:visited { +      color: #003399; +      text-decoration: none; +      /* background-color: #e3ecef; */ +    } +    a:hover { +      color: #000000; +      text-decoration: underline; +      background-color: #fff3b6; +    } +    a:hover IMG { +      background-color: #ffffff; +    } +    a:active { +      color: #003399; +      text-decoration: underline; +    } +    object { +      display: block; +      margin-top: 3px; +      margin-bottom: 3px; +      margin-right: 5mm; +    } +    p { +      display: block; +      font-family: #{the_font.set_fonts}; +      font-size: 100%; +      font-weight: normal; +      line-height: 150%; +      text-align: justify; +      margin-left: 10mm; +      margin-top: 3px; +      margin-bottom: 0px; +      margin-right: 5mm +    } +    p.norm { } +    p.endnote { +      font-size: 100%; +      margin-left: 20%; +      text-indent: 5% +    } +    p.endnote_indent { +      font-size: 100%; +      margin-left: 25%; +      text-indent: 5% +    } +    p.h1 { +      font-family: #{the_font.set_fonts}; +      font-weight: bold; +      line-height: 120%; +      margin-left: 10mm; +      margin-right: 10mm; +      text-align: left; +      margin-top: 20px; +      margin-bottom: 10px; +    } +    p.h2 { +      font-weight: bold; +      font-size: 110%; +      margin-left: 10mm; +      margin-right: 15mm; +      text-align: left; +      margin-top: 20px; +      margin-bottom: 10px; +    } +    p.h3 { +      font-size: 150%; +      font-weight: bold; +      text-align: left; +    } +    p.h4 { +      font-size: 150%; +      font-weight: bold; +      text-align: left; +    } +    p.h5 { +      font-size: 150%; +      font-weight: bold; +      text-align: left; +    } +    p.h6 { +      font-size: 150%; +      font-weight: bold; +      text-align: left; +    } +    p.h7 { +      font-size: 150%; +      font-weight: bold; +      text-align: left; +    } +    ocn { +      display: block; +      text-align: right; +      vertical-align: super; +      color: #990000; +      font-size: xx-small; +      margin-top: 0px; +      margin-bottom: 6px; +    } +    en { +      font-size: xx-small; +      vertical-align: super; +    } +    i { font-style: italic; } +    b { font-style: bold; } +    u { text-decoration: underline; } +    br { display: block; } +WOK +    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 +    css + +  - 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 diff --git a/org/db.org b/org/db.org new file mode 100644 index 00000000..4a2f216b --- /dev/null +++ b/org/db.org @@ -0,0 +1,4808 @@ +-*- mode: org -*- +#+TITLE:       sisu db sql +#+DESCRIPTION: documents - structuring, various output representations & search +#+FILETAGS:    :sisu:db:sql: +#+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 + +* dbi.rb + +#+BEGIN_SRC ruby  :tangle "../lib/sisu/dbi.rb" +# <<sisu_document_header>> +module  SiSU_DBI                                                                 #% database building +  require_relative 'se'                                 # se.rb +    include SiSU_Env; include SiSU_Screen +  require_relative 'dp'                                 # dp.rb +    include SiSU_Param +  require_relative 'db_dbi'                             # db_dbi.rb +    include SiSU_DbDBI +  require_relative 'html_lite_shared'                   # html_lite_shared.rb +    include SiSU_FormatShared +  class SQL +    def initialize(opt) +      @opt=opt +      @db=SiSU_Env::InfoDb.new +      if @opt.act[:psql][:set]==:on \ +      or @opt.act[:sqlite][:set]==:on +        @sql_type=if @opt.act[:psql][:set]==:on +          maintenance_check(@opt,__FILE__,__LINE__) if @opt.act[:maintenance][:set]==:on +          :pg +        elsif @opt.act[:psql][:set]==:on +          maintenance_check(@opt,__FILE__,__LINE__) if @opt.act[:maintenance][:set]==:on +          :pg +        elsif @opt.act[:sqlite][:set]==:on +          maintenance_check(@opt,__FILE__,__LINE__) if @opt.act[:maintenance][:set]==:on +          :sqlite +        elsif @opt.act[:sqlite][:set]==:on +          maintenance_check(@opt,__FILE__,__LINE__) if @opt.act[:maintenance][:set]==:on +          :sqlite +        else +          maintenance_check(@opt,__FILE__,__LINE__) if @opt.act[:maintenance][:set]==:on +          :sqlite +        end +        if    @sql_type==:pg    then SiSU_Env::Load.new('pg',true).prog +        elsif @sql_type==:sqlite then SiSU_Env::Load.new('sqlite3',true).prog +        end +      end +    end +    def maintenance_check(opt,file,line) +      p opt.selections.str +      p "at #{file} #{line}" +    end +    def read_psql +      begin +        begin +          require 'pg' +        rescue LoadError +          SiSU_Utils::CodeMarker.new(__LINE__,__FILE__,:fuchsia). +            error('pg NOT FOUND (LoadError)') +        end +        @conn=@db.psql.conn_pg +      rescue +        if @opt.act[:psql_create][:set]==:on +          cX=SiSU_Screen::Ansi.new(@opt.act[:color_state][:set]).cX +          puts <<-WOK +manually create the database: "#{cX.green}#{@db.db}#{cX.off}" if it does not yet exist +  #{cX.yellow}createdb #{@db.db}#{cX.off} +          WOK +          #sudo su -p postgres;  createdb #{@db.db}; #[createuser?] +        end +      ensure +      end +    end +    def read_sqlite +      begin +        begin +          begin +            require 'sqlite3' +          rescue LoadError +            SiSU_Utils::CodeMarker.new(__LINE__,__FILE__,:fuchsia). +              error('sqlite3 NOT FOUND (LoadError)') +          end +          @conn=@db.sqlite.conn_sqlite3 +        rescue LoadError +          errmsg='sqlite3 NOT FOUND (LoadError)' +          if @opt.act[:no_stop][:set]==:on +            SiSU_Utils::CodeMarker.new(__LINE__,__FILE__,:fuchsia). +              error(errmsg + ', ' + 'attempt to proceed without sqlite output (as requested)') +          else +            SiSU_Utils::CodeMarker.new(__LINE__,__FILE__,:fuchsia). +              error(errmsg + ', ' + 'STOPPING') +            exit +          end +        end +      end +    end +    def connect +      case @sql_type +      when :pg     then read_psql #read_pg +      when :sqlite then read_sqlite +      end +      SiSU_Screen::Ansi.new( +        @opt.act[:color_state][:set], +        "SQL DB #{@sql_type.upcase}", +        @opt.fno +      ).dbi_title unless @opt.act[:quiet][:set]==:on +      begin +        SiSU_DbDBI::Case.new(@opt,@conn,@sql_type).cases +      rescue +        SiSU_Errors::Rescued.new($!,$@,@cf,@opt.fns).location do +          __LINE__.to_s + ':' + __FILE__ +        end +      ensure +      end +      begin +      rescue +        connect +      end +    end +  end +end +__END__ +#+END_SRC + +* dbi_discrete.rb + +#+BEGIN_SRC ruby  :tangle "../lib/sisu/dbi_discrete.rb" +# <<sisu_document_header>> +module  SiSU_DBI_Discrete                               #% database building +  require_relative 'se'                                 # se.rb +    include SiSU_Env; include SiSU_Screen +  require_relative 'dp'                                 # dp.rb +    include SiSU_Param +  require_relative 'db_dbi'                             # db_dbi.rb +    include SiSU_DbDBI +  require_relative 'html_lite_shared'                   # html_lite_shared.rb +    include SiSU_FormatShared +  begin +    require 'fileutils' +      include FileUtils::Verbose +  rescue LoadError +    SiSU_Utils::CodeMarker.new(__LINE__,__FILE__,:fuchsia). +      error('fileutils NOT FOUND (LoadError)') +  end +  class SQL +    def initialize(opt) +      SiSU_Env::Load.new('sqlite3',true).prog +      @opt=opt +      @particulars=SiSU_Particulars::CombinedSingleton.instance.get_all(opt) +      @md=@particulars.md +      if @opt.act[:sqlite][:set]==:on +        @sql_type=:sqlite +        if @opt.act[:maintenance][:set]==:on +          maintenance_check(@opt,__FILE__,__LINE__) +        end +      end +      @output_path=@md.file.output_path.sqlite_discrete.dir +      @filename=@md.file.base_filename.sqlite_discrete +      @file_maint=sql_maintenance_file +      @file="#{@output_path}/#{@filename}" +    end +    def build +      prepare +      create_and_populate +    end +    def maintenance_check(opt,file,line) +      #p opt.selections.str +      p "at #{file} #{line}" +    end +    def prepare +      if not FileTest.directory?(@output_path) +        FileUtils::mkdir_p(@output_path) +      elsif @file +        FileUtils::rm_rf(@file) +      end +    end +    def db_exist?(db,conn) +      msg=%{no connection with sqlite database established, createdb "#{db.sqlite.db}"?} +      if (not (FileTest.file?(db.sqlite.db)) \ +      or FileTest.zero?(db.sqlite.db)) +        puts msg +        exit +      end +      if conn.is_a?(NilClass) +        puts msg +        exit +      end +    end +    def create_and_populate +      db=SiSU_Env::DbOp.new(@md) +      conn=db.sqlite_discrete.conn_sqlite3 +      sdb=SiSU_DbDBI::Create.new(@opt,conn,@file,:sqlite) +      sdb_index=SiSU_DbDBI::Index.new(@opt,conn,@file,:sqlite) +      sdb.output_dir? +      begin +        SiSU_Screen::Ansi.new( +          @opt.act[:color_state][:set], +          'SQLite (discrete)', +          "[#{@opt.f_pth[:lng_is]}] #{@opt.fno}" +        ).green_title_hi unless @opt.act[:quiet][:set]==:on +        sdb.create_db +        sdb.create_table.metadata_and_text +        sdb.create_table.doc_objects +        sdb.create_table.endnotes +        sdb.create_table.endnotes_asterisk +        sdb.create_table.endnotes_plus +        sdb.create_table.urls +        sdb_index.create_indexes +        db_exist?(db,conn) +        sdb_import=SiSU_DbDBI::Import.new(@opt,conn,@file_maint,:sqlite) +        sdb_import.marshal_load +        tell=SiSU_Screen::Ansi.new( +               @opt.act[:color_state][:set], +               "sqlite3 #{db.sqlite.db} database?" +             ) +        tell.puts_grey if @opt.act[:verbose][:set]==:on +      rescue +        SiSU_Errors::Rescued.new($!,$@,'-d').location do +          __LINE__.to_s + ':' + __FILE__ +        end +        sdb.output_dir? +      end +    end +    def read_sqlite +      begin +        begin +          require 'sqlite3' +          @conn=@db.sqlite.conn_sqlite3 +        rescue LoadError +          SiSU_Utils::CodeMarker.new(__LINE__,__FILE__,:fuchsia).error('sqlite3 not available') +        ensure +          Dir.chdir(@opt.f_pth[:pth]) +        end +      end +    end +    def connect +      begin +        SiSU_Screen::Ansi.new( +          @opt.act[:color_state][:set], +          "DBI (#{@sql_type}) #{@opt.selections.str}", +          @opt.fns +        ).dbi_title unless @opt.act[:quiet][:set]==:on +        @db.sqlite_discrete.conn_sqlite3 +      rescue +        SiSU_Errors::Rescued.new($!,$@,@cf,@opt.fns).location do +          __LINE__.to_s + ':' + __FILE__ +        end +      ensure +      end +    end +    def populate +    end +    def sql_maintenance_file +      file=if @opt.act[:maintenance][:set]==:on +        if @opt.fns and not @opt.fns.empty? +          @env=SiSU_Env::InfoEnv.new(@opt.fns) if @opt.fns +          if @sql_type ==:sqlite +            puts "\n#{@env.processing_path.sqlite}/#{@opt.fns}.sql" +          end +          @db=SiSU_Env::InfoDb.new +          @job="sqlite3 #{@db.sqlite.db} < #{@env.processing_path.sqlite}/#{@opt.fns}.sql" +          if @sql_type ==:sqlite +            File.new("#{@env.processing_path.sqlite}/#{@opt.fns}.sql",'w+') +          else +            File.new("#{@env.processing_path.postgresql}/#{@opt.fns}.sql",'w+') +          end +        elsif @opt.fns \ +        and @opt.fns.inspect =~/create/ +          nil #sort variations later +        else nil +        end +      else nil +      end +      file +    end +  end +end +__END__ +#+END_SRC + +* db_dbi.rb + +#+BEGIN_SRC ruby  :tangle "../lib/sisu/db_dbi.rb" +# <<sisu_document_header>> +module  SiSU_DbDBI +  require_relative 'db_columns'                                             # db_columns.rb +  require_relative 'db_tests'                                               # db_tests.rb +  require_relative 'db_create'                                              # db_create.rb +  require_relative 'db_select'                                              # db_select.rb +  require_relative 'db_indexes'                                             # db_indexes.rb +  require_relative 'db_drop'                                                # db_drop.rb +  require_relative 'db_remove'                                              # db_remove.rb +  require_relative 'db_load_tuple'                                          # db_load_tuple.rb +  require_relative 'db_import'                                              # db_import.rb +  class ColumnSize < SiSU_DbColumns::ColumnSize                             # db_columns.rb +  end +  class Test < SiSU_DbTests::Test                                           # db_tests.rb +  end +  class Create <SiSU_DbCreate::Create                                       # db_create.rb +  end +  class Case <SiSU_DbSelect::Case                                           # db_select.rb +  end +  class Index <SiSU_DbIndex::Index                                          # db_indexes.rb +  end +  class Drop <SiSU_DbDrop::Drop                                             # db_drop.rb +  end +  class Remove <SiSU_DbRemove::Remove                                       # db_remove.rb +  end +  class LoadDocuments <SiSU_DbTuple::LoadDocuments                          # db_load_tuple.rb +  end +  class LoadMetadata <SiSU_DbTuple::LoadMetadata                            # db_load_tuple.rb +  end +  class LoadUrls <SiSU_DbTuple::LoadUrls                                    # db_update urls +  end +  class Import <SiSU_DbImport::Import #<SiSU_DB::ColumnSize                 # db_import.rb +  end +end +__END__ +#+END_SRC + +* db_sqltxt.rb + +#+BEGIN_SRC ruby  :tangle "../lib/sisu/db_sqltxt.rb" +# <<sisu_document_header>> +module SiSU_DbText +  class Prepare +    def special_character_escape(str) +      str=str.to_s.gsub(/'/m,"''"). #string.gsub!(/'/,"\047") #string.gsub!(/'/,"\\'") +        gsub(/(\\)/m,'\1\1'). #ok but with warnings, double backslash on sqlite #str.gsub!(/[\\]/m,'\\x5C') #ok but with warnings, but not for sqlite #str.gsub!(/(\\)/m,'\1') #ok for sqlite not for pgsql +        gsub(/#{Mx[:br_line]}|#{Mx[:br_nl]}/m,"<br>\n"). +        gsub(/#{Mx[:tag_o]}\S+?#{Mx[:tag_c]}/m,''). #check +        gsub(/#{Mx[:lnk_o]}\s*(\S+?\.(?:png|jpg))(?:\s+\d+x\d+)?(.+?)#{Mx[:lnk_c]}\S+/m,'[image: \1] \2'). +        gsub(/#{Mx[:lnk_o]}\s*(.+?)\s*#{Mx[:lnk_c]}(?:file|ftp):\/\/\S+?([.,!?]?(?:\s|$))/m,'\1\2'). +        gsub(/#{Mx[:lnk_o]}\s*(.+?)\s*#{Mx[:lnk_c]}#{Mx[:url_o]}\S+?#{Mx[:url_c]}/m,'\1') +    end +    def clean_searchable_text_from_document_objects(arr) +      en=[] +      arr=(arr.is_a?(String)) ? [ arr ] : arr +      txt_arr=arr.each.map do |s| +        s=s.gsub(/#{Mx[:fa_o]}[a-z]{1,4}#{Mx[:fa_o_c]}/m,''). +            gsub(/#{Mx[:fa_c_o]}[a-z]{1,4}#{Mx[:fa_c]}/m,''). +            gsub(/<br>/m,' ') +        en << s.scan(/#{Mx[:en_a_o]}\s*(.+?)\s*#{Mx[:en_a_c]}/m) +        s=s.gsub(/#{Mx[:en_a_o]}.+?#{Mx[:en_a_c]}/m,''). +          gsub(/#{Mx[:en_b_o]}.+?#{Mx[:en_b_c]}/m,''). +          gsub(/ \s+/m,' ') +        #p s if s =~/[^ \nA-Za-z0-9'"`?!#@$%^&*=+,.;:\[\]()<>{}‹›|\\\/~_-]/ +        s +      end +      txt_arr=txt_arr << en +      txt=txt_arr.flatten.join("\n") +      special_character_escape(txt) +    end +    def clean_document_objects_body(arr) +      en=[] +      arr=(arr.is_a?(String)) ? [ arr ] : arr +      txt_arr=arr.each.map do |s| +        en << s.scan(/#{Mx[:en_a_o]}\s*(.+?)\s*#{Mx[:en_a_c]}/m) +        s=s. +          gsub(/#{Mx[:en_a_o]}\s*(\d+).+?#{Mx[:en_a_c]}/m, +            '<sup>\1</sup>'). +          gsub(/#{Mx[:en_b_o]}.+?#{Mx[:en_b_c]}/m,''). +          gsub(/ \s+/m,' ') +        s +      end +      en_arr=en.flatten.each.map do |e| +        e.sub(/^(\d+)\s*/,'<sup>\1</sup> ') +      end +      txt_arr=txt_arr << en_arr +      txt=txt_arr.flatten.join("\n<br>") +      special_character_escape(txt) +    end +    def clean_searchable_text_from_document_source(arr) +      txt_arr,en=[],[] +      arr=(arr.is_a?(String)) ? arr.split(/\n+/m) : arr +      arr.each do |s| +        s=s.gsub(/([*\/_-])\{(.+?)\}\1/m,'\2'). +          gsub(/^(?:block|group|poem|code)\{/m,''). +          gsub(/^\}(?:block|group|poem|code)/m,''). +          gsub(/\A(?:@\S+:\s+.+)\Z/m,'') +        if s =~/^:A~/ +          if defined? @md.creator \ +          and defined? @md.creator.author \ +          and not @md.creator.author.empty? +            s=s.gsub(/@author/,@md.creator.author) +          else +            SiSU_Screen::Ansi.new( +              'v', +              'WARNING Document Author information missing; provide @creator: :author:', +              @md.fnb +            ).warn unless @md.opt.act[:quiet][:set]==:on +          end +          if defined? @md.title \ +          and defined? @md.title.full \ +          and not @md.title.full.empty? +            s=s.gsub(/@title/,@md.title.full) +          else +            SiSU_Screen::Ansi.new( +              'v', +              'WARNING Document Title missing; provide @title:', +              @md.fnb +            ).warn unless @md.opt.act[:quiet][:set]==:on +          end +        end +        s=s.gsub(/^(?:_[1-9]\*?|_\*)\s+/m,''). +          gsub(/^(?:[1-9]\~(\S+)?)\s+/m,''). +          gsub(/^(?::?[A-C]\~(\S+)?)\s+/m,''). +          gsub(/^%{1,3} .+/m,''). #removed even if contained in code block +          gsub(/<br>/m,' ') +        #en << s.scan(/~\{\s*(.+?)\s*\}~/m) +        s=s.gsub(/~\{.+?\}~/m,''). +          gsub(/ \s+/m,' ') +        ##special_character_escape(s) +        #p s if s =~/[^ \nA-Za-z0-9'"`?!#@$%^&*=+,.;:\[\]()<>{}‹›|\\\/~_-]/ +        s +      end +      txt_arr << arr << en +      txt=txt_arr.flatten.join("\n") +      txt=special_character_escape(txt) +      txt +    end +    def strip_markup(str) #define rules, make same as in dal clean +      str=str.gsub(/#{Mx[:fa_superscript_o]}(\d+)#{Mx[:fa_superscript_c]}/,'[\1]'). +        gsub(/(?: \\;|#{Mx[:nbsp]})+/,' '). +        gsub(/#{Mx[:tc_o]}#{Mx[:tc_p]}#{Mx[:tc_p]}\d+(.+)#{Mx[:tc_c]}/u,'\1').         #tables +        gsub(/#{Mx[:tc_p]}#{Mx[:tc_p]}\d+#{Mx[:tc_p]}/u,' ').                          #tables +        gsub(/#{Mx[:tc_p]}/u,' ').                                                     #tables tidy later +        gsub(/<.+?>/,''). +        gsub(/#{Mx[:lnk_o]}.+?\.(?:png|jpg|gif).+?#{Mx[:lnk_c]}(?:file|ftp)\/\/:\S+ /,' [image] '). # else image names found in search +        gsub(/#{Mx[:lnk_o]}.+?\.(?:png|jpg|gif).+?#{Mx[:lnk_c]}#{Mx[:url_o]}\S+?#{Mx[:url_c]}/,' [image]'). # else image names found in search +        gsub(/\s\s+/,' '). +        strip +    end +    def unique_words(str) +      a=str.scan(/[a-zA-Z0-9\\\/_-]{2,}/) #a=str.scan(/\S+{2,}/) +      str=a.uniq.sort.join(' ') +      str +    end +  end +end +__END__ +#+END_SRC + +* create drop import remove +** db_create.rb + +#+BEGIN_SRC ruby  :tangle "../lib/sisu/db_create.rb" +# <<sisu_document_header>> +module SiSU_DbCreate +  require_relative 'db_columns'                         # db_columns.rb +  class Create < SiSU_DbColumns::Columns +    require_relative 'se'                               # se.rb +    @@dl=nil +    def initialize(opt,conn,file,sql_type=:pg) +      @opt,@conn,@file,@sql_type=opt,conn,file,sql_type +      @cX=SiSU_Screen::Ansi.new(@opt.act[:color_state][:set]).cX +      @comment=(@sql_type==:pg) \ +      ? (SiSU_DbCreate::Comment.new(@conn,@sql_type)) +      : nil +      @@dl ||=SiSU_Env::InfoEnv.new.digest.length +    end +    def available +      DBI.available_drivers.each do |driver| +        puts "Driver: #{driver}" +        DBI.data_sources(driver).each do |dsn| +          puts "\tDatasource: #{dsn}" +        end +      end +    end +    def create_db +      @env=SiSU_Env::InfoEnv.new(@opt.fns) +      tell=(@sql_type==:sqlite) \ +      ? SiSU_Screen::Ansi.new( +          @opt.act[:color_state][:set], +          'Create SQLite db tables in:', +          %{"#{@file}"} +        ) +      : SiSU_Screen::Ansi.new( +          @opt.act[:color_state][:set], +          'Create pgSQL db tables in:', +          %{"#{Db[:name_prefix]}#{@env.path.base_markup_dir_stub}"} +        ) +      if (@opt.act[:verbose][:set]==:on \ +      || @opt.act[:verbose_plus][:set]==:on \ +      || @opt.act[:maintenance][:set]==:on) +        tell.dark_grey_title_hi +      end +      SiSU_Env::SystemCall.new.create_pg_db(@env.path.base_markup_dir_stub) if @sql_type==:pg #watch use of path.base_markup_dir_stub instead of stub +    end +    def output_dir? +      dir=SiSU_Env::InfoEnv.new('') +      if @opt.act[:sqlite][:set]==:on +        dir.path.webserv_stub_ensure +      end +    end +    def create_table +      def conn_exec(sql) +        if @sql_type==:pg +          conn_exec_pg(sql) +        elsif @sql_type==:sqlite +          conn_exec_sqlite(sql) +        end +      end +      def conn_exec_pg(sql) +        begin +          @conn.exec_params(sql) +        rescue +          if @conn.is_a?(NilClass) +            errmsg="No pg connection (check pg dependencies)" +            if @opt.act[:no_stop][:set]==:on +              SiSU_Utils::CodeMarker.new(__LINE__,__FILE__,:fuchsia). +                error("#{errmsg}, proceeding without pg output (as requested)") +            else +              SiSU_Utils::CodeMarker.new(__LINE__,__FILE__,:fuchsia). +                error("#{errmsg}, STOPPING") +              exit +            end +          end +        end +      end +      def conn_exec_sqlite(sql) +        begin +          @conn.execute(sql) +        rescue +          if @conn.is_a?(NilClass) +            errmsg="No sqlite3 connection (check sqlite3 dependencies)" +            if @opt.act[:no_stop][:set]==:on +              SiSU_Utils::CodeMarker.new(__LINE__,__FILE__,:fuchsia). +                error("#{errmsg}, proceeding without sqlite output (as requested)") +            else +              SiSU_Utils::CodeMarker.new(__LINE__,__FILE__,:fuchsia). +                error("#{errmsg}, STOPPING") +              exit +            end +          end +        end +      end +      def metadata_and_text +        if (@opt.act[:verbose_plus][:set]==:on \ +        or @opt.act[:maintenance][:set]==:on) +          print %{ +          currently using sisu_dbi module +          to be populated from document files +          create tables metadata_and_text +          data import through ruby transfer +          } +        end +        create_metadata_and_text=%{ +          CREATE TABLE metadata_and_text ( +            tid                  BIGINT PRIMARY KEY, +            /* title */ +            #{column.title.create_column} +            #{column.title_main.create_column} +            #{column.title_sub.create_column} +            #{column.title_short.create_column} +            #{column.title_edition.create_column} +            #{column.title_note.create_column} +            #{column.title_language.create_column} +            #{column.title_language_char.create_column} +            /* creator */ +            #{column.creator_author.create_column} +            #{column.creator_author_honorific.create_column} +            #{column.creator_author_nationality.create_column} +            #{column.creator_editor.create_column} +            #{column.creator_contributor.create_column} +            #{column.creator_illustrator.create_column} +            #{column.creator_photographer.create_column} +            #{column.creator_translator.create_column} +            #{column.creator_prepared_by.create_column} +            #{column.creator_digitized_by.create_column} +            #{column.creator_audio.create_column} +            #{column.creator_video.create_column} +            /* language */ +            #{column.language_document.create_column} +            #{column.language_document_char.create_column} +            #{column.language_original.create_column} +            #{column.language_original_char.create_column} +            /* date */ +            #{column.date_added_to_site.create_column} +            #{column.date_available.create_column} +            #{column.date_created.create_column} +            #{column.date_issued.create_column} +            #{column.date_modified.create_column} +            #{column.date_published.create_column} +            #{column.date_valid.create_column} +            #{column.date_translated.create_column} +            #{column.date_original_publication.create_column} +            #{column.date_generated.create_column} +            /* publisher */ +            #{column.publisher.create_column} +            /* original */ +            #{column.original_publisher.create_column} +            #{column.original_language.create_column} +            #{column.original_language_char.create_column} +            #{column.original_source.create_column} +            #{column.original_institution.create_column} +            #{column.original_nationality.create_column} +            /* rights */ +            #{column.rights_all.create_column} +            #{column.rights_copyright_text.create_column} +            #{column.rights_copyright_translation.create_column} +            #{column.rights_copyright_illustrations.create_column} +            #{column.rights_copyright_photographs.create_column} +            #{column.rights_copyright_preparation.create_column} +            #{column.rights_copyright_digitization.create_column} +            #{column.rights_copyright_audio.create_column} +            #{column.rights_copyright_video.create_column} +            #{column.rights_license.create_column} +            /* classify */ +            #{column.classify_topic_register.create_column} +            #{column.classify_subject.create_column} +            #{column.classify_loc.create_column} +            #{column.classify_dewey.create_column} +            #{column.classify_keywords.create_column} +            /* identifier */ +            #{column.identifier_oclc.create_column} +            #{column.identifier_isbn.create_column} +            /* notes */ +            #{column.notes_abstract.create_column} +            #{column.notes_description.create_column} +            #{column.notes_comment.create_column} +            #{column.notes_history.create_column} +            #{column.notes_coverage.create_column} +            #{column.notes_relation.create_column} +            /* column.notes_source.create_column */ +            #{column.notes_type.create_column} +            #{column.notes_format.create_column} +            #{column.notes_prefix.create_column} +            #{column.notes_prefix_a.create_column} +            #{column.notes_prefix_b.create_column} +            #{column.notes_suffix.create_column} +            /* src */ +            #{column.src_filename.create_column} +            #{column.src_fingerprint.create_column} +            #{column.src_filesize.create_column} +            #{column.src_word_count.create_column} +            #{column.src_txt.create_column} +            /* misc */ +            #{column.fulltext.create_column} +            #{column.links.create_column.gsub(/,$/,'')} +/*          subj                 VARCHAR(64) NULL, */ +/*          contact              VARCHAR(100) NULL, */ +/*          information          VARCHAR(100) NULL, */ +/*          types                CHAR(1) NULL, */ +/*          writing_focus_nationality VARCHAR(100) NULL, */ +          ); +        } +        conn_exec(create_metadata_and_text) +        @comment.psql.metadata_and_text if @comment +      end +      def doc_objects                                                 # create doc_objects base +        if (@opt.act[:verbose_plus][:set]==:on \ +        or @opt.act[:maintenance][:set]==:on) +          print %{ +          to be populated from documents files +          create tables doc_objects +          data import through ruby transfer +          } +        end +        create_doc_objects=%{ +          CREATE TABLE doc_objects ( +            lid             BIGINT PRIMARY KEY, +            metadata_tid    BIGINT REFERENCES metadata_and_text, +            ocn             SMALLINT, +            ocnd            VARCHAR(6), +            ocns            VARCHAR(6), +            clean           TEXT NULL, +            body            TEXT NULL, +            book_idx        TEXT NULL, +            seg             VARCHAR(256) NULL, +            lev_an          VARCHAR(1), +            lev             SMALLINT NULL, +            lev0            SMALLINT, +            lev1            SMALLINT, +            lev2            SMALLINT, +            lev3            SMALLINT, +            lev4            SMALLINT, +            lev5            SMALLINT, +            lev6            SMALLINT, +            lev7            SMALLINT, +            en_a            SMALLINT NULL, +            en_z            SMALLINT NULL, +            en_a_asterisk   SMALLINT NULL, +            en_z_asterisk   SMALLINT NULL, +            en_a_plus       SMALLINT NULL, +            en_z_plus       SMALLINT NULL, +            t_of            VARCHAR(16), +            t_is            VARCHAR(16), +            node            VARCHAR(16) NULL, +            parent          VARCHAR(16) NULL, +            digest_clean    CHAR(#{@@dl}), +            digest_all      CHAR(#{@@dl}), +            types           CHAR(1) NULL +          ); +        } +        conn_exec(create_doc_objects) +        @comment.psql.doc_objects if @comment +      end +      def endnotes +        if (@opt.act[:verbose_plus][:set]==:on \ +        or @opt.act[:maintenance][:set]==:on) +          print %{ +          to be populated from document files +          create tables endnotes +          data import through ruby transfer +          } +        end +        create_endnotes=%{ +          CREATE TABLE endnotes ( +            nid             BIGINT PRIMARY KEY, +            document_lid    BIGINT REFERENCES doc_objects, +            nr              SMALLINT, +            clean           TEXT NULL, +            body            TEXT NULL, +            ocn             SMALLINT, +            ocnd            VARCHAR(6), +            ocns            VARCHAR(6), +            digest_clean    CHAR(#{@@dl}), +            metadata_tid    BIGINT REFERENCES metadata_and_text +          ); +        } +        conn_exec(create_endnotes) +        @comment.psql.endnotes if @comment +      end +      def endnotes_asterisk +        if (@opt.act[:verbose_plus][:set]==:on \ +        or @opt.act[:maintenance][:set]==:on) +          print %{ +          to be populated from document files +          create tables endnotes_asterisk +          data import through ruby transfer +          } +        end +        create_endnotes_asterisk=%{ +          CREATE TABLE endnotes_asterisk ( +            nid             BIGINT PRIMARY KEY, +            document_lid    BIGINT REFERENCES doc_objects, +            nr              SMALLINT, +            clean           TEXT NULL, +            body            TEXT NULL, +            ocn             SMALLINT, +            ocnd            VARCHAR(6), +            ocns            VARCHAR(6), +            digest_clean    CHAR(#{@@dl}), +            metadata_tid    BIGINT REFERENCES metadata_and_text +          ); +        } +        conn_exec(create_endnotes_asterisk) +        @comment.psql.endnotes_asterisk if @comment +      end +      def endnotes_plus +        if (@opt.act[:verbose_plus][:set]==:on \ +        or @opt.act[:maintenance][:set]==:on) +          print %{ +          to be populated from document files +          create tables endnotes_plus +          data import through ruby transfer +          } +        end +        create_endnotes_plus=%{ +          CREATE TABLE endnotes_plus ( +            nid             BIGINT PRIMARY KEY, +            document_lid    BIGINT REFERENCES doc_objects, +            nr              SMALLINT, +            clean           TEXT NULL, +            body            TEXT NULL, +            ocn             SMALLINT, +            ocnd            VARCHAR(6), +            ocns            VARCHAR(6), +            digest_clean    CHAR(#{@@dl}), +            metadata_tid    BIGINT REFERENCES metadata_and_text +          ); +        } +        conn_exec(create_endnotes_plus) +        @comment.psql.endnotes_plus if @comment +      end +      def urls                                                       # create doc_objects file links mapping +        if (@opt.act[:verbose_plus][:set]==:on \ +        or @opt.act[:maintenance][:set]==:on) +          print %{ +          currently using sisu_dbi module +          to be populated from doc_objects files +          create tables urls +          data import through ruby transfer +          } +        end +        create_urls=%{ +          CREATE TABLE urls ( +            metadata_tid    BIGINT REFERENCES metadata_and_text, +            plaintext       varchar(512), +            html_toc        varchar(512), +            html_doc        varchar(512), +            xhtml           varchar(512), +            xml_sax         varchar(512), +            xml_dom         varchar(512), +            odf             varchar(512), +            pdf_p           varchar(512), +            pdf_l           varchar(512), +            concordance     varchar(512), +            latex_p         varchar(512), +            latex_l         varchar(512), +            digest          varchar(512), +            manifest        varchar(512), +            markup          varchar(512), +            sisupod         varchar(512) +          ); +        } +        conn_exec(create_urls) +        @comment.psql.urls if @comment +      end +      self +    end +  end +  class Comment < SiSU_DbColumns::Columns +    def initialize(conn,sql_type=:pg) +      @conn=conn +      if sql_type == :pg then psql +      end +    end +    def psql +      def conn_execute_array(sql_arr) +        @conn.transaction do |conn| +          sql_arr.each do |sql| +            conn.exec_params(sql) +          end +        end +      end +      def metadata_and_text +        sql_arr=[ +          %{COMMENT ON Table metadata_and_text +            IS 'contains SiSU metadata and fulltext for search (including source .sst if shared)';}, +          %{COMMENT ON COLUMN metadata_and_text.tid +            IS 'unique';}, +          %{#{column.title.column_comment}}, +          %{#{column.title_main.column_comment}}, +          %{#{column.title_sub.column_comment}}, +          %{#{column.title_short.column_comment}}, +          %{#{column.title_edition.column_comment}}, +          %{#{column.title_note.column_comment}}, +          %{#{column.title_language.column_comment}}, +          %{#{column.title_language_char.column_comment}}, +          %{#{column.creator_author.column_comment}}, +          %{#{column.creator_author_honorific.column_comment}}, +          %{#{column.creator_author_nationality.column_comment}}, +          %{#{column.creator_editor.column_comment}}, +          %{#{column.creator_contributor.column_comment}}, +          %{#{column.creator_illustrator.column_comment}}, +          %{#{column.creator_photographer.column_comment}}, +          %{#{column.creator_translator.column_comment}}, +          %{#{column.creator_prepared_by.column_comment}}, +          %{#{column.creator_digitized_by.column_comment}}, +          %{#{column.creator_audio.column_comment}}, +          %{#{column.creator_video.column_comment}}, +          %{#{column.language_document.column_comment}}, +          %{#{column.language_document_char.column_comment}}, +          %{#{column.language_original.column_comment}}, +          %{#{column.language_original_char.column_comment}}, +          %{#{column.date_added_to_site.column_comment}}, +          %{#{column.date_available.column_comment}}, +          %{#{column.date_created.column_comment}}, +          %{#{column.date_issued.column_comment}}, +          %{#{column.date_modified.column_comment}}, +          %{#{column.date_published.column_comment}}, +          %{#{column.date_valid.column_comment}}, +          %{#{column.date_translated.column_comment}}, +          %{#{column.date_original_publication.column_comment}}, +          %{#{column.date_generated.column_comment}}, +          %{#{column.publisher.column_comment}}, +          %{#{column.original_publisher.column_comment}}, +          %{#{column.original_language.column_comment}}, +          %{#{column.original_language_char.column_comment}}, +          %{#{column.original_source.column_comment}}, +          %{#{column.original_institution.column_comment}}, +          %{#{column.original_nationality.column_comment}}, +          %{#{column.rights_all.column_comment}}, +          %{#{column.rights_copyright_text.column_comment}}, +          %{#{column.rights_copyright_translation.column_comment}}, +          %{#{column.rights_copyright_illustrations.column_comment}}, +          %{#{column.rights_copyright_photographs.column_comment}}, +          %{#{column.rights_copyright_preparation.column_comment}}, +          %{#{column.rights_copyright_digitization.column_comment}}, +          %{#{column.rights_copyright_audio.column_comment}}, +          %{#{column.rights_copyright_video.column_comment}}, +          %{#{column.rights_license.column_comment}}, +          %{#{column.classify_topic_register.column_comment}}, +          %{#{column.classify_subject.column_comment}}, +          %{#{column.classify_loc.column_comment}}, +          %{#{column.classify_dewey.column_comment}}, +          %{#{column.classify_keywords.column_comment}}, +          %{#{column.identifier_oclc.column_comment}}, +          %{#{column.identifier_isbn.column_comment}}, +          %{#{column.notes_abstract.column_comment}}, +          %{#{column.notes_comment.column_comment}}, +          %{#{column.notes_description.column_comment}}, +          %{#{column.notes_history.column_comment}}, +          %{#{column.notes_coverage.column_comment}}, +          %{#{column.notes_relation.column_comment}}, +          %{#{column.notes_type.column_comment}}, +          %{#{column.notes_format.column_comment}}, +          %{#{column.notes_prefix.column_comment}}, +          %{#{column.notes_prefix_a.column_comment}}, +          %{#{column.notes_prefix_b.column_comment}}, +          %{#{column.notes_suffix.column_comment}}, +          %{#{column.src_filename.column_comment}}, +          %{#{column.src_fingerprint.column_comment}}, +          %{#{column.src_filesize.column_comment}}, +          %{#{column.src_word_count.column_comment}}, +          %{#{column.src_txt.column_comment}}, +          %{#{column.fulltext.column_comment}}, +          %{#{column.links.column_comment}}, +        ] +        conn_execute_array(sql_arr) +      end +      def doc_objects +        sql_arr=[ +          %{COMMENT ON Table doc_objects +            IS 'contains searchable text of SiSU document objects';}, +          %{COMMENT ON COLUMN doc_objects.lid +            IS 'unique';}, +          %{COMMENT ON COLUMN doc_objects.metadata_tid +            IS 'tie to title in metadata_and_text';}, +          %{COMMENT ON COLUMN doc_objects.lev_an +            IS 'doc level A-D 1-4';}, +          %{COMMENT ON COLUMN doc_objects.lev +            IS 'doc level 0-7 \d\~';}, +          %{COMMENT ON COLUMN doc_objects.seg +            IS 'segment name from level number 4 (lv 1)';}, +          %{COMMENT ON COLUMN doc_objects.ocn +            IS 'object citation number';}, +          %{COMMENT ON COLUMN doc_objects.en_a +            IS 'first endnote number in text object (eg. NULL or 34) (used with en_z to create range)';}, +          %{COMMENT ON COLUMN doc_objects.en_z +            IS 'last endnote number within text object (eg. NULL, 34 or say 47) (used with en_a to create range)';}, +          %{COMMENT ON COLUMN doc_objects.en_a_asterisk +            IS 'first endnote number in text object (eg. NULL or 34) (used with en_z_asterisk to create range)';}, +          %{COMMENT ON COLUMN doc_objects.en_z_asterisk +            IS 'last endnote number within text object (eg. NULL, 34 or say 47) (used with en_a_asterisk to create range)';}, +          %{COMMENT ON COLUMN doc_objects.en_a_plus +            IS 'first endnote number in text object (eg. NULL or 34) (used with en_z_plus to create range)';}, +          %{COMMENT ON COLUMN doc_objects.en_z_plus +            IS 'last endnote number within text object (eg. NULL, 34 or say 47) (used with en_a_plus to create range)';}, +          %{COMMENT ON COLUMN doc_objects.types +            IS 'document types seg scroll';}, +          %{COMMENT ON COLUMN doc_objects.clean +            IS 'text object - substantive text: clean, stripped of markup';}, +          %{COMMENT ON COLUMN doc_objects.body +            IS 'text object - substantive text: light html markup';}, +          %{COMMENT ON COLUMN doc_objects.book_idx +            IS 'book index creation information for paragraph, if provided';}, +          %{COMMENT ON COLUMN doc_objects.lev0 +            IS 'document structure, level number 0';}, +          %{COMMENT ON COLUMN doc_objects.lev1 +            IS 'document structure, level number 1';}, +          %{COMMENT ON COLUMN doc_objects.lev2 +            IS 'document structure, level number 2';}, +          %{COMMENT ON COLUMN doc_objects.lev3 +            IS 'document structure, level number 3';}, +          %{COMMENT ON COLUMN doc_objects.lev4 +            IS 'document structure, level number 4';}, +          %{COMMENT ON COLUMN doc_objects.lev5 +            IS 'document structure, level number 5';}, +          %{COMMENT ON COLUMN doc_objects.lev6 +            IS 'document structure, level number 6';}, +          %{COMMENT ON COLUMN doc_objects.lev7 +            IS 'document structure, level number 7';}, +          %{COMMENT ON COLUMN doc_objects.t_of +            IS 'document structure, type of object (object is of)';}, +          %{COMMENT ON COLUMN doc_objects.t_is +            IS 'document structure, object is';}, +          %{COMMENT ON COLUMN doc_objects.node +            IS 'document structure, object node if heading';}, +          %{COMMENT ON COLUMN doc_objects.parent +            IS 'document structure, object parent (is a heading)';} +        ] +        conn_execute_array(sql_arr) +      end +      def endnotes +        sql_arr=[ +          %{COMMENT ON Table endnotes +            IS 'contains searchable text of SiSU documents endnotes';}, +          %{COMMENT ON COLUMN endnotes.nid +            IS 'unique';}, +          %{COMMENT ON COLUMN endnotes.document_lid +            IS 'ties to text block from which referenced';}, +          %{COMMENT ON COLUMN endnotes.nr +            IS 'endnote number <!e_(\d+)!>';}, +          %{COMMENT ON COLUMN endnotes.clean +            IS 'endnote substantive content, stripped of markup';}, +          %{COMMENT ON COLUMN endnotes.body +            IS 'endnote substantive content';}, +          %{COMMENT ON COLUMN endnotes.ocn +            IS 'object citation no# <\~(\d+)> from which endnote is referenced';}, +          %{COMMENT ON COLUMN doc_objects.metadata_tid +            IS 'tie to title in metadata_and_text - unique for each document';} +        ] +        conn_execute_array(sql_arr) +      end +      def endnotes_asterisk +        sql_arr=[ +          %{COMMENT ON Table endnotes_asterisk +            IS 'contains searchable text of SiSU documents endnotes marked with asterisk';}, +          %{COMMENT ON COLUMN endnotes_asterisk.nid +            IS 'unique';}, +          %{COMMENT ON COLUMN endnotes_asterisk.document_lid +            IS 'ties to text block from which referenced';}, +          %{COMMENT ON COLUMN endnotes_asterisk.nr +            IS 'endnote number <!e_(\d+)!>';}, +          %{COMMENT ON COLUMN endnotes_asterisk.clean +            IS 'endnote substantive content, stripped of markup';}, +          %{COMMENT ON COLUMN endnotes_asterisk.body +            IS 'endnote substantive content';}, +          %{COMMENT ON COLUMN endnotes_asterisk.ocn +            IS 'object citation no# <\~(\d+)> from which endnote is referenced';}, +          %{COMMENT ON COLUMN doc_objects.metadata_tid +            IS 'tie to title in metadata_and_text - unique for each document';} +        ] +        conn_execute_array(sql_arr) +      end +      def endnotes_plus +        sql_arr=[ +          %{COMMENT ON Table endnotes_plus +            IS 'contains searchable text of SiSU documents endnotes marked with plus';}, +          %{COMMENT ON COLUMN endnotes_plus.nid +            IS 'unique';}, +          %{COMMENT ON COLUMN endnotes_plus.document_lid +            IS 'ties to text block from which referenced';}, +          %{COMMENT ON COLUMN endnotes_plus.nr +            IS 'endnote number <!e_(\d+)!>';}, +          %{COMMENT ON COLUMN endnotes_plus.clean +            IS 'endnote substantive content, stripped of markup';}, +          %{COMMENT ON COLUMN endnotes_plus.body +            IS 'endnote substantive content';}, +          %{COMMENT ON COLUMN endnotes_plus.ocn +            IS 'object citation no# <\~(\d+)> from which endnote is referenced';}, +          %{COMMENT ON COLUMN doc_objects.metadata_tid +            IS 'tie to title in metadata_and_text - unique for each document';}, +        ] +        conn_execute_array(sql_arr) +      end +      def urls +        sql_arr=[ +          %{COMMENT ON Table urls +            IS 'contains base url links to different SiSU output';}, +          %{COMMENT ON COLUMN doc_objects.metadata_tid +            IS 'tie to title in metadata_and_text - unique for each document, the mapping of rows is one to one';}, +          %{COMMENT ON COLUMN urls.plaintext +            IS 'plaintext utf-8';}, +          %{COMMENT ON COLUMN urls.html_toc +            IS 'table of contents for segmented html document';}, +          %{COMMENT ON COLUMN urls.html_doc +            IS 'html document (scroll)';}, +          %{COMMENT ON COLUMN urls.xhtml +            IS 'xhtml document (scroll)';}, +          %{COMMENT ON COLUMN urls.xml_sax +            IS 'xml sax oriented document (scroll)';}, +          %{COMMENT ON COLUMN urls.xml_dom +            IS 'xml dom oriented document (scroll)';}, +          %{COMMENT ON COLUMN urls.odf +            IS 'opendocument format text';}, +          %{COMMENT ON COLUMN urls.pdf_p +            IS 'pdf portrait';}, +          %{COMMENT ON COLUMN urls.pdf_l +            IS 'pdf landscape';}, +          %{COMMENT ON COLUMN urls.concordance +            IS 'rudimentary document index linked to html';}, +          %{COMMENT ON COLUMN urls.latex_p +            IS 'latex portrait';}, +          %{COMMENT ON COLUMN urls.latex_l +            IS 'latex_landscape';}, +          %{COMMENT ON COLUMN urls.markup +            IS 'markup';}, +          %{COMMENT ON COLUMN urls.sisupod +            IS 'SiSU document format .tgz (all SiSU information on document)';}, +        ] +        conn_execute_array(sql_arr) +      end +      self +    end +  end +end +__END__ +#+END_SRC + +** db_drop.rb + +#+BEGIN_SRC ruby  :tangle "../lib/sisu/db_drop.rb" +# <<sisu_document_header>> +module SiSU_DbDrop +  require_relative 'utils_response'                   # utils_response.rb +  class Drop +    include SiSU_Response +    def initialize(opt,conn,db_info,sql_type) +      @opt,@conn,@db_info,@sql_type=opt,conn,db_info,sql_type +      case @sql_type +      when :sqlite +        cascade='' +      else +        cascade='CASCADE' +      end +      @drop_table=[ +        "DROP TABLE metadata_and_text #{cascade};", +        "DROP TABLE doc_objects #{cascade};", +        "DROP TABLE urls #{cascade};", +        "DROP TABLE endnotes #{cascade};", +        "DROP TABLE endnotes_asterisk #{cascade};", +        "DROP TABLE endnotes_plus #{cascade};", +      ] +    end +    def drop +      def tables                                                              #% drop all tables +        begin +          msg_sqlite="as not all disk space is recovered after dropping the database << #{@db_info.sqlite.db} >>, you may be better off deleting the file, and recreating it as necessary" +          case @sql_type +          when :sqlite +            puts msg_sqlite +            ans=response?('remove sql database?') +            if ans \ +            and File.exist?(@db_info.sqlite.db) +              @conn.close +              File.unlink(@db_info.sqlite.db) +              db=SiSU_Env::InfoDb.new +              conn=db.sqlite.conn_sqlite3 +              sdb=SiSU_DbDBI::Create.new(@opt,conn,@db_info,@sql_type) +              sdb_index=SiSU_DbDBI::Index.new(@opt,conn,@db_info,@sql_type) +              sdb.output_dir? +              begin +                sdb.create_db +                sdb.create_table.metadata_and_text +                sdb.create_table.doc_objects +                sdb.create_table.endnotes +                sdb.create_table.endnotes_asterisk +                sdb.create_table.endnotes_plus +                sdb.create_table.urls +                sdb_index.create_indexes +              rescue +                SiSU_Errors::Rescued.new($!,$@,'-D').location do +                  __LINE__.to_s + ':' + __FILE__ +                end +                sdb.output_dir? +              end +              exit +            else +              @conn.transaction +              @drop_table.each do |d| +                begin +                  @conn.exec_params(d) +                rescue +                  next +                end +                end +              @conn.commit +            end +          when :pg +            @conn.transaction +            @drop_table.each do |d| +              begin +                @conn.exec_params(d) +              rescue +                next +              end +            end +            @conn.commit +          end +        rescue +          case @sql_type +          when :sqlite +            ans=response?('remove sql database?') +            if ans and File.exist?(@db_info.sqlite.db); File.unlink(@db_info.sqlite.db) +            end +          else +            @drop_table.each do |d| +              begin +                @conn.exec_params(d) +              rescue +                next +              end +            end +          end +        ensure +        end +      end +      def indexes +        def conn_execute_array(sql_arr) +          @conn.transaction do |conn| +            sql_arr.each do |sql| +              begin +                conn.exec_params(sql) +              rescue +                next +              end +            end +          end +        end +        def base                                                             #% drop base indexes +          print "\n          drop documents common indexes\n" unless @opt.act[:quiet][:set]==:on +          sql_arr=[ +            %{DROP INDEX idx_title;}, +            %{DROP INDEX idx_author;}, +            %{DROP INDEX idx_filename;}, +            %{DROP INDEX idx_topics;}, +            %{DROP INDEX idx_ocn;}, +            %{DROP INDEX idx_digest_clean;}, +            %{DROP INDEX idx_digest_all;}, +            %{DROP INDEX idx_lev0;}, +            %{DROP INDEX idx_lev1;}, +            %{DROP INDEX idx_lev2;}, +            %{DROP INDEX idx_lev3;}, +            %{DROP INDEX idx_lev4;}, +            %{DROP INDEX idx_lev5;}, +            %{DROP INDEX idx_lev6;}, +            %{DROP INDEX idx_endnote_nr;}, +            %{DROP INDEX idx_digest_en;}, +            %{DROP INDEX idx_endnote_nr_asterisk;}, +            %{DROP INDEX idx_endnote_asterisk;}, +            %{DROP INDEX idx_digest_en_asterisk;}, +            %{DROP INDEX idx_endnote_nr_plus;}, +            %{DROP INDEX idx_endnote_plus;}, +            %{DROP INDEX idx_digest_en_plus}, +          ] +          conn_execute_array(sql_arr) +        end +        def text                                                             #% drop TEXT indexes, sqlite +          print "\n          drop documents TEXT indexes\n" unless @opt.act[:quiet][:set]==:on +          sql_arr=[ +            %{DROP INDEX idx_clean;}, +            %{DROP INDEX idx_endnote}, +          ] +          conn_execute_array(sql_arr) +        end +        self +      end +      indexes.base +      @opt.act[:psql][:set]==:on ? '' : indexes.text +      self +    end +  end +end +__END__ +#+END_SRC + +** db_import.rb + +#+BEGIN_SRC ruby  :tangle "../lib/sisu/db_import.rb" +# <<sisu_document_header>> +module SiSU_DbImport +  require_relative 'db_columns'                         # db_columns.rb +  require_relative 'db_load_tuple'                      # db_load_tuple.rb +  require_relative 'db_sqltxt'                          # db_sqltxt.rb +  require_relative 'html_lite_shared'                   # html_lite_shared.rb +  class Import < SiSU_DbText::Prepare +    include SiSU_Param +    include SiSU_Screen +    include SiSU_DbAction +    @@dl=nil +    @@hname=nil +    attr_accessor :tp +    def initialize(opt,conn,file_maint,sql_type=:pg) +      @opt,@conn,@file_maint,@sql_type=opt,conn,file_maint,sql_type +      @cX=SiSU_Screen::Ansi.new(@opt.act[:color_state][:set]).cX +      @env=SiSU_Env::InfoEnv.new(@opt.fns) +      @dal="#{@env.processing_path.ao}" +      @fnb=if @opt.fns.empty? \ +      or @opt.selections.str.empty? +        '' +      else +        @md=SiSU_Param::Parameters.new(@opt).get +        @md.fnb +      end +      @fnc="#{@dal}/#{@opt.fns}.content.rbm" +      @@seg,@@seg_full='',''                                  #create? consider placing field just before clean text as opposed to seg which contains seg(.html) name info seg_full would contain seg info for levels 5 & 6 where available eg seg_full may be 7.3 (level 5) and 7.3.1 (level 6) where seg  is 7 +      @col=Hash.new('') +      @col[:ocn]='' +      @counter={} +      @db=SiSU_Env::InfoDb.new +      if @sql_type==:sqlite +        @driver_sqlite3= +        (@conn.inspect.match(/^(.{10})/)[1] \ +        == @db.sqlite.conn_sqlite3.inspect.match(/^(.{10})/)[1]) \ +        ? true +        : false +      end +      sql='SELECT MAX(lid) FROM doc_objects' +      begin +        @col[:lid] ||=0 +        @col[:lid]=@driver_sqlite3 \ +        ? @conn.execute( sql ).join.to_i +        : @conn.exec( sql ).getvalue(0,0).to_i +      rescue +        if @opt.act[:maintenance][:set]==:on +          puts "#{__FILE__}:#{__LINE__}" +        end +      end +      @col[:lid]=0 if @col[:lid].nil? or @col[:lid].to_s.empty? +      sql='SELECT MAX(nid) FROM endnotes' +      begin +        @id_n=@driver_sqlite3 \ +        ? @conn.execute( sql ).join.to_i +        : @conn.exec( sql ).getvalue(0,0).to_i +        @id_n ||=0 +      rescue +        if @opt.act[:maintenance][:set]==:on +          puts "#{__FILE__}:#{__LINE__}" +        end +      end +      @id_n =0 if @col[:lid].nil? or @col[:lid].to_s.empty? +      @col[:lv0]=@col[:lv1]=@col[:lv2]=@col[:lv3]=@col[:lv4]=@col[:lv5]=@col[:lv6]=@col[:lv7]=0 +      @db=SiSU_Env::InfoDb.new +      @pdf_fn=SiSU_Env::FileOp.new(@md).base_filename +      @@dl ||=SiSU_Env::InfoEnv.new.digest.length +    end +    def marshal_load +      require_relative 'ao'                               # ao.rb +      @ao_array=SiSU_AO::Source.new(@opt).get             # ao file drawn here +      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], +          "#{@db.psql.db}::#{@opt.fns}" +        ).puts_blue +      end +      SiSU_Screen::Ansi.new( +        @opt.act[:color_state][:set], +        'Marshal Load', +        @fnc +      ).puts_grey if @opt.act[:verbose][:set]==:on +      select_first_match=%{ +        SELECT metadata_and_text.tid +        FROM metadata_and_text +        WHERE metadata_and_text.src_filename = '#{@md.fns}' +        AND metadata_and_text.language_document_char = '#{@opt.lng}' +      ;} # note, for .ssm: @md.fns (is set during runtime & is) != @opt.fns @md.opt.fns +      file_exist=if @sql_type==:sqlite +        begin +          @conn.get_first_value(select_first_match) +        rescue SQLite3::Exception => e +          # not tested +          puts "Exception occurred" +          puts e +          SiSU_Utils::CodeMarker.new(__LINE__,__FILE__,:yellow).mark( +            "\n" \ +            + 'Attempting to initialize db' + "\n" \ +            + 'Creating db tables' +          ) +          sdb={ +            create: SiSU_DbDBI::Create.new(@opt,@conn,@file_maint,@sql_type), +            index: SiSU_DbDBI::Index.new(@opt,@conn,@file_maint,@sql_type), +          } +          db_action(sdb).create +        end +      else +        begin +          @conn.exec(select_first_match).field_values("tid")[0] +        rescue PG::Error => e +          err=[ +            e.result.error_field( PG::Result::PG_DIAG_SEVERITY ), +            e.result.error_field( PG::Result::PG_DIAG_SQLSTATE ), +            e.result.error_field( PG::Result::PG_DIAG_MESSAGE_PRIMARY ), +            e.result.error_field( PG::Result::PG_DIAG_MESSAGE_DETAIL ), +            e.result.error_field( PG::Result::PG_DIAG_MESSAGE_HINT ), +            e.result.error_field( PG::Result::PG_DIAG_STATEMENT_POSITION ), +            e.result.error_field( PG::Result::PG_DIAG_INTERNAL_POSITION ), +            e.result.error_field( PG::Result::PG_DIAG_INTERNAL_QUERY ), +            e.result.error_field( PG::Result::PG_DIAG_CONTEXT ), +            e.result.error_field( PG::Result::PG_DIAG_SOURCE_FILE ), +            e.result.error_field( PG::Result::PG_DIAG_SOURCE_LINE ), +            e.result.error_field( PG::Result::PG_DIAG_SOURCE_FUNCTION ), +          ] +          p err +          if err[2] =~/relation "\S+?" does not exist/ \ +          or err.inspect =~/relation "\S+?" does not exist/ +            SiSU_Utils::CodeMarker.new(__LINE__,__FILE__,:yellow).mark( +              "\n" \ +              + err[2] + "\n" \ +              + 'Attempting to initialize db' + "\n" \ +              + 'Creating db tables' +            ) +            sdb={ +              create: SiSU_DbDBI::Create.new(@opt,@conn,@file_maint,@sql_type), +              index: SiSU_DbDBI::Index.new(@opt,@conn,@file_maint,@sql_type), +            } +            db_action(sdb).create +            retry +          end +        end +      end +      if not file_exist +        t_d=[]                                                              # transaction_data +        t_d << db_import_metadata +        t_d << db_import_documents(@ao_array) +        t_d << db_import_urls(@ao_array,@fnc)                              #import OID on/off +        t_d=t_d.flatten +        if (@opt.act[:verbose_plus][:set]==:on \ +        || @opt.act[:maintenance][:set]==:on) +          puts @conn.class if defined? @conn.class +          puts @conn.driver_name if defined? @conn.driver_name +          puts @conn.driver if defined? @conn.driver +        end +        begin                                                               #% sql +          if @sql_type==:sqlite +            @conn.transaction do |conn| +              t_d.each do |sql| +                conn.execute(sql) +              end +            end +            #also 'execute' works for sqlite +            #@conn.execute("BEGIN") +            #  t_d.each do |sql| +            #    @conn.execute(sql) +            #  end +            #@conn.execute("COMMIT") +          else +            #'do' works for postgresql +            @conn.exec("BEGIN") +              t_d.each do |sql| +                @conn.exec(sql) +              end +            @conn.exec("COMMIT") +          end +        rescue +          SiSU_Errors::Rescued.new($!,$@,@opt.selections.str,@opt.fns).location do +            __LINE__.to_s + ':' + __FILE__ +          end +          sqlfn="#{@env.processing_path.sql}/#{@md.fnb}.sql" +          sql=File.new(sqlfn,'w') +          t_d.each {|i| sql.puts i} +          p sqlfn +          if @opt.act[:maintenance][:set]==:on +            puts sql +            p @conn.methods.sort +            puts "#{__FILE__}:#{__LINE__}" +          end +        ensure +        end +      else +        if file_exist +          @db=SiSU_Env::InfoDb.new +          puts "\nfile #{@opt.fns} in language code #{@opt.lng} already exists in database #{@db.psql.db}, use --update instead?" +        end +      end +    end +    def pf_db_import_transaction_open +    end +    def pf_db_import_transaction_close +    end +    def book_idx_hash_to_str(book_idx) +      book_idx=book_idx ? book_idx : '' +      book_idx_str,book_subidx_part='','' +      if not book_idx.empty? +        book_idx_str='' +        book_idx.each_pair do |k0,v0| +          book_idx_str << %{#{k0}+#{v0[:plus]}} +          book_subidx_part='' +          if v0[:sub].length > 0 +            v0[:sub].each do |subterms| +               subterms.each_pair do |k1,v1| +                 book_subidx_part << %{\n  #{k1}+#{v1[:plus]} | } +               end +            end +            book_idx_str=book_idx_str + ':' + book_subidx_part +          end +        end +      end +      book_idx_str +    end +    def db_import_metadata                                                       #% import documents - populate database +      if (@opt.act[:verbose][:set]==:on \ +      || @opt.act[:verbose_plus][:set]==:on \ +      || @opt.act[:maintenance][:set]==:on) +        print %{ #{@cX.grey}import documents dbi_unit #{@cX.off} } +      end +      @tp={} +      @md=SiSU_Param::Parameters.new(@opt).get +#% sisutxt & fulltxt +      if FileTest.exist?(@md.fns) +        txt_arr=IO.readlines(@md.fns,'') +        src=txt_arr.join("\n") +        src=special_character_escape(src) +        @tp[:sisutxt_f],@tp[:sisutxt_i]='sisutxt, ',"'#{src}', " +        txt=clean_searchable_text_from_document_source(txt_arr) +        #txt=special_character_escape(txt) +        @tp[:fulltxt_f],@tp[:fulltxt_i]='fulltxt, ',"'#{txt}', " +      end +#% title +      if defined? @md.title.full \ +      and @md.title.full=~/\S+/                                              # DublinCore 1 - title +        #@tp[:title]=@md.title.full +        #special_character_escape(@tp[:title]) +        #@tp[:title_f],@tp[:title_i]='title, ',"'#{@tp[:title]}', " +        sql='SELECT MAX(tid) FROM metadata_and_text;' +        begin +          @@id_t ||=0 +          id_t=@driver_sqlite3 \ +          ? @conn.execute( sql ).join.to_i # { |x| id_t=x.join.to_i } +          : @conn.exec( sql ).getvalue(0,0).to_i +          @@id_t=id_t if id_t +        rescue +          if @opt.act[:maintenance][:set]==:on +            puts "#{__FILE__} #{__LINE__}" +          end +        end +        @@id_t+=1 #bug related, needs to be performed once at start of file, but consider moving, as, placed here it means program will fail if document header lacks @title: +        if (@opt.act[:verbose][:set]==:on \ +        || @opt.act[:verbose_plus][:set]==:on \ +        || @opt.act[:maintenance][:set]==:on) +          puts %{\n#{@cX.grey}Processing file number#{@cX.off}: #{@cX.green}#{@@id_t}#{@@cX.off}} +        end +      end +      ################ CLEAR ############## +      SiSU_DbDBI::Test.new(self,@opt).verify                          #% import title names, filenames (tuple) +      t=SiSU_DbTuple::LoadMetadata.new(@conn,@@id_t,@md,@file_maint) +      tuple=t.tuple +      tuple +    end +    def db_import_documents(ao_array)                                     #% import documents - populate main database table, import into substantive database tables (tuple) +      begin +        @col[:tid]=@@id_t +        @en,@en_ast,@en_pls,@tuple_array=[],[],[],[] +        @col[:en_a],@col[:en_z]=nil,nil +        ao_array.each do |data| +          data.obj=data.obj.gsub(/#{Mx[:fa_bold_o]}(.+?)#{Mx[:fa_bold_c]}/,'\1'). +            gsub(/#{Mx[:fa_italics_o]}(.+?)#{Mx[:fa_italics_c]}/,'\1'). +            gsub(/#{Mx[:fa_underscore_o]}(.+?)#{Mx[:fa_underscore_c]}/,'\1'). +            gsub(/#{Mx[:fa_superscript_o]}(.+?)#{Mx[:fa_superscript_c]}/,'\1'). +            gsub(/#{Mx[:fa_subscript_o]}(.+?)#{Mx[:fa_subscript_c]}/,'\1'). +            gsub(/#{Mx[:fa_insert_o]}(.+?)#{Mx[:fa_insert_c]}/,'\1'). +            gsub(/#{Mx[:fa_cite_o]}(.+?)#{Mx[:fa_cite_c]}/,'\1'). +            gsub(/#{Mx[:fa_strike_o]}(.+?)#{Mx[:fa_strike_c]}/,'\1'). +            gsub(/#{Mx[:fa_monospace_o]}(.+?)#{Mx[:fa_monospace_c]}/,'\1'). +            gsub(/#{Mx[:gl_o]}(●)#{Mx[:gl_c]}\s*/,'\1 '). +            gsub(/#{Mx[:tag_o]}\S+?#{Mx[:tag_c]}/,'') #check +          @col[:seg]=@@seg +          if data.of ==:para \ +          || data.of ==:heading \ +          || data.of ==:heading_insert \ +          || data.of ==:block \ +          || data.of ==:group      # regular text what of code-blocks grouped text etc. +            notedata=data.obj.dup +                                                                               #% :headings +            if data.is==:heading \ +            && (data.ln.inspect=~/[0-3]/) +              ( +                @col[:lev], +                txt,@col[:ocn], +                @col[:lev_an], +                @col[:ocnd],@col[:ocns], +                @col[:t_of],@col[:t_is], +                @col[:node],@col[:parent], +                @col[:digest_clean],@col[:digest_all]= +                data.ln, +                data.obj,data.ocn, +                data.lv, +                data.odv,data.osp, +                data.of,data.is, +                data.node,data.parent, +                '','' +              ) +              @col[:lid]+=1 +              txt=endnotes(txt).extract_any +              body=SiSU_FormatShared::CSS_Format.new(@md,data).lev4_minus +              @col[:body]=clean_document_objects_body(body) +              plaintext=@col[:body].dup +              plaintext=strip_markup(plaintext) +              @col[:plaintext]=clean_searchable_text_from_document_objects(plaintext) +              book_idx=book_idx_hash_to_str(data.idx) +              @col[:book_idx]=clean_searchable_text_from_document_objects(book_idx) +              if @en[0] then @en_a,@en_z=@en[0].first,@en[0].last +              end +              if @en_ast[0] then @en_a_asterisk,@en_z_asterisk=@en_ast[0].first,@en_ast[0].last +              end +              if @en_pls[0] then @en_a_plus,@en_z_plus=@en_pls[0].first,@en_pls[0].last +              end +              t=SiSU_DbTuple::LoadDocuments.new(@conn,@col,@opt,@file_maint) +              @tuple_array << t.tuple +              case @col[:lev] +              when /0/ then @col[:lv0]+=1 +              when /1/ then @col[:lv1]+=1 +              when /2/ then @col[:lv2]+=1 +              when /3/ then @col[:lv3]+=1 +              when /4/ then @col[:lv4]+=1 +              end +              @col[:lev]=@col[:plaintext]=@col[:body]='' +            elsif data.is==:heading \ +            && data.ln==4 +              ( +                @@seg,txt, +                @col[:ocn],@col[:lev_an], +                @col[:ocnd],@col[:ocns], +                @col[:t_of],@col[:t_is], +                @col[:node],@col[:parent], +                @col[:digest_clean],@col[:digest_all]= +                data.name,data.obj, +                data.ocn,data.lv, +                data.odv,data.osp, +                data.of,data.is, +                data.node,data.parent, +                '','' +              ) +              @col[:seg]=@@seg +              @col[:lv4]+=1 +              @col[:lid]+=1 +              @col[:lev]=4 +              @hname=if @col[:seg] \ +              and not @col[:seg].to_s.empty? +                @@hname=@col[:seg].to_s +              else @@hname +              end +              @env=SiSU_Env::InfoEnv.new(@md.fns) +              @base_url="#{@env.url.root}/#{@md.fnb}/#{@hname}.html" +              txt=endnotes(txt).extract_any +              body=SiSU_FormatShared::CSS_Format.new(@md,data).lev4_plus +              @col[:body]=clean_document_objects_body(body) +              plaintext=@col[:body].dup +              plaintext=strip_markup(plaintext) +              @col[:plaintext]=clean_searchable_text_from_document_objects(plaintext) +              book_idx=book_idx_hash_to_str(data.idx) +              @col[:book_idx]=clean_searchable_text_from_document_objects(book_idx) +              @en_a,@en_z=@en[0].first,@en[0].last if @en[0] +              @en_a_asterisk,@en_z_asterisk=@en_ast[0].first,@en_ast[0].last if @en_ast[0] +              @en_a_plus,@en_z_plus=@en_pls[0].first,@en_pls[0].last if @en_pls[0] +              t=SiSU_DbTuple::LoadDocuments.new(@conn,@col,@opt,@file_maint) +              @tuple_array << t.tuple +              @col[:lev]=@col[:plaintext]=@col[:body]='' +            elsif data.is==:heading \ +            && data.ln==5 +              ( +                txt, +                @col[:ocn],@col[:lev_an], +                @col[:ocnd],@col[:ocns], +                @col[:t_of],@col[:t_is], +                @col[:node],@col[:parent], +                @col[:digest_clean],@col[:digest_all]= +                data.obj, +                data.ocn,data.lv, +                data.odv,data.osp, +                data.of,data.is, +                data.node,data.parent, +                '','' +              ) +              @@seg_full=data.name if data.is==:heading \ +              && data.ln==5 \ +              && data.name #check data.name +              @@seg ||='' #nil # watch +              @col[:seg]=@@seg +              @col[:lv5]+=1 +              @col[:lid]+=1 +              @col[:lev]=5 +              @hname=if @col[:seg] \ +              and not @col[:seg].to_s.empty? +                @@hname=@col[:seg].to_s +              else @@hname +              end +              @env=SiSU_Env::InfoEnv.new(@md.fns) +              @base_url="#{@env.url.root}/#{@md.fnb}/#{@hname}.html" +              txt=endnotes(txt).extract_any +              body=SiSU_FormatShared::CSS_Format.new(@md,data).lev4_plus +              @col[:body]=clean_document_objects_body(body) +              plaintext=@col[:body].dup +              plaintext=strip_markup(plaintext) +              @col[:plaintext]=clean_searchable_text_from_document_objects(plaintext) +              book_idx=book_idx_hash_to_str(data.idx) +              @col[:book_idx]=clean_searchable_text_from_document_objects(book_idx) +              @en_a,@en_z=@en[0].first,@en[0].last if @en[0] +              @en_a_asterisk,@en_z_asterisk=@en_ast[0].first,@en_ast[0].last if @en_ast[0] +              @en_a_plus,@en_z_plus=@en_pls[0].first,@en_pls[0].last if @en_pls[0] +              t=SiSU_DbTuple::LoadDocuments.new(@conn,@col,@opt,@file_maint) +              @tuple_array << t.tuple +              @col[:lev]=@col[:plaintext]=@col[:body]='' +            elsif data.is==:heading \ +            && data.ln==6 +              txt,       @col[:ocn],@col[:lev_an],@col[:ocnd],@col[:ocns],@col[:t_of],@col[:t_is],@col[:node],@col[:parent],@col[:digest_clean],@col[:digest_all]= +                data.obj,data.ocn,  data.lv,      data.odv,   data.osp,   data.of,    data.is,    data.node,  data.parent,  '',                 '' +              @@seg_full=data.name if data.is==:heading && data.ln==6 && data.name #check data.name +              @@seg ||='' #nil # watch +              @col[:seg]=@@seg +              @col[:lv6]+=1 +              @col[:lid]+=1 +              @col[:lev]=6 +              @hname=if @col[:seg] \ +              and not @col[:seg].to_s.empty? +                @@hname=@col[:seg].to_s +              else @@hname +              end +              @env=SiSU_Env::InfoEnv.new(@md.fns) +              @base_url="#{@env.url.root}/#{@md.fnb}/#{@hname}.html" +              txt=endnotes(txt).extract_any +              body=SiSU_FormatShared::CSS_Format.new(@md,data).lev4_plus +              @col[:body]=clean_document_objects_body(body) +              plaintext=@col[:body].dup +              plaintext=strip_markup(plaintext) +              @col[:plaintext]=clean_searchable_text_from_document_objects(plaintext) +              book_idx=book_idx_hash_to_str(data.idx) +              @col[:book_idx]=clean_searchable_text_from_document_objects(book_idx) +              @en_a,@en_z=@en[0].first,@en[0].last if @en[0] +              @en_a_asterisk,@en_z_asterisk=@en_ast[0].first,@en_ast[0].last if @en_ast[0] +              @en_a_plus,@en_z_plus=@en_pls[0].first,@en_pls[0].last if @en_pls[0] +              t=SiSU_DbTuple::LoadDocuments.new(@conn,@col,@opt,@file_maint) +              @tuple_array << t.tuple +              @col[:lev]=@col[:plaintext]=@col[:body]='' +            elsif data.is==:heading \ +            && data.ln==7 +              txt,       @col[:ocn],@col[:lev_an],@col[:ocnd],@col[:ocns],@col[:t_of],@col[:t_is],@col[:node],@col[:parent],@col[:digest_clean],@col[:digest_all]= +                data.obj,data.ocn,  data.lv,      data.odv,   data.osp,   data.of,    data.is,    data.node,  data.parent,  '',                 '' +              @@seg_full=data.name if data.is==:heading && data.ln==7 && data.name #check data.name +              @@seg ||='' #nil # watch +              @col[:seg]=@@seg +              @col[:lv7]+=1 +              @col[:lid]+=1 +              @col[:lev]=7 +              @hname=if @col[:seg] \ +              and not @col[:seg].to_s.empty? +                @@hname=@col[:seg].to_s +              else @@hname +              end +              @env=SiSU_Env::InfoEnv.new(@md.fns) +              @base_url="#{@env.url.root}/#{@md.fnb}/#{@hname}.html" +              txt=endnotes(txt).extract_any +              body=SiSU_FormatShared::CSS_Format.new(@md,data).lev4_plus +              @col[:body]=clean_document_objects_body(body) +              plaintext=@col[:body].dup +              plaintext=strip_markup(plaintext) +              @col[:plaintext]=clean_searchable_text_from_document_objects(plaintext) +              book_idx=book_idx_hash_to_str(data.idx) +              @col[:book_idx]=clean_searchable_text_from_document_objects(book_idx) +              @en_a,@en_z=@en[0].first,@en[0].last if @en[0] +              @en_a_asterisk,@en_z_asterisk=@en_ast[0].first,@en_ast[0].last if @en_ast[0] +              @en_a_plus,@en_z_plus=@en_pls[0].first,@en_pls[0].last if @en_pls[0] +              t=SiSU_DbTuple::LoadDocuments.new(@conn,@col,@opt,@file_maint) +              @tuple_array << t.tuple +              @col[:lev]=@col[:plaintext]=@col[:body]='' +                                                                               #% :structure :layout :comment +            elsif data.of==:structure \ +            || data.of==:layout \ +            || data.of==:comment +              #added watch +                                                                               #% : +            else                                                               #% regular text +              @col[:lid]+=1 +              ( +                txt='' +                txt,@col[:ocn], +                @col[:ocnd],@col[:ocns], +                @col[:t_of],@col[:t_is], +                @col[:node],@col[:parent], +                @col[:digest_clean],@col[:digest_all], +                @col[:lev]= +                data.obj,data.ocn, +                data.odv,data.osp, +                data.of,data.is, +                '',data.parent, +                '','', +                9 +              ) +              @hname=if @col[:seg] \ +              and not @col[:seg].to_s.empty? +                @@hname=@col[:seg].to_s +              else @@hname +              end +              @env=SiSU_Env::InfoEnv.new(@md.fns) +              @base_url="#{@env.url.root}/#{@md.fnb}/#{@hname}.html" +              txt=endnotes(txt).extract_any +              if @sql_type==:pg \ +              and txt.size > (SiSU_DbColumns::ColumnSize.new.document_clean - 1)             # examine pg build & remove limitation +                puts "\n\nTOO LARGE (TXT - see error log)\n\n" +                open("#{Dir.pwd}/pg_documents_error_log",'a') do |error| +                  error.puts("\n#{@opt.fns}\nTEXT BODY\n#{@col[:body].size} object #{@col[:ocn]} -> #{@col[:body].slice(0..500)}") +                end +                txt=%{\n\nLARGE TEXT BLOCK OMITTED\n\n} +              end +              @en_a,@en_z=@en[0].first,@en[0].last if @en[0] +              @en_a_asterisk,@en_z_asterisk=@en_ast[0].first,@en_ast[0].last if @en_ast[0] +              @en_a_plus,@en_z_plus=@en_pls[0].first,@en_pls[0].last if @en_pls[0] +              body=if data.is==:table +                SiSU_FormatShared::CSS_Format.new(@md,data).html_table +              elsif data.is==:code +                SiSU_FormatShared::CSS_Format.new(@md,data).code +              elsif defined? data.indent \ +              and defined? data.hang \ +              and data.indent =~/[1-9]/ \ +              and data.indent == data.hang +                SiSU_FormatShared::CSS_Format.new(@md,data).indent(data.indent) +              elsif defined? data.indent \ +              and defined? data.hang \ +              and data.hang =~/[0-9]/ \ +              and data.indent != data.hang +                SiSU_FormatShared::CSS_Format.new(@md,data).hang_indent(data.hang,data.indent) +              else +                SiSU_FormatShared::CSS_Format.new(@md,data).norm +              end +              @col[:body]=clean_document_objects_body(body) +              plaintext=@col[:body].dup +              plaintext=strip_markup(plaintext) +              @col[:plaintext]=clean_searchable_text_from_document_objects(plaintext) +              book_idx=book_idx_hash_to_str(data.idx) +              @col[:book_idx]=clean_searchable_text_from_document_objects(book_idx) +              t=SiSU_DbTuple::LoadDocuments.new(@conn,@col,@opt,@file_maint) +              @tuple_array << t.tuple +              @en,@en_ast,@en_pls=[],[],[] +              @col[:en_a]=@col[:en_z]=nil +              @col[:lev]=@col[:plaintext]=@col[:body]=@col[:words]='' +            end +            if notedata =~/#{Mx[:en_a_o]}.+?#{Mx[:en_a_c]}/                                         #% import into database endnotes tables +              endnote_array=notedata.scan(/#{Mx[:en_a_o]}.+?#{Mx[:en_a_c]}/) +              endnote_array.each do |inf| +                if inf[/#{Mx[:en_a_o]}\d+.+?#{Mx[:en_a_c]}/] +                  if inf[/#{Mx[:en_a_o]}(\d+)(.+?)#{Mx[:en_a_c]}/] +                    nr,txt,digest_clean=$1,$2.strip,0 +                  end +                  @id_n ||=0 +                  @id_n+=1 +                  txt=special_character_escape(txt) +                  body=SiSU_FormatShared::CSS_Format.new(@md,data).endnote(nr,txt) +                  txt=strip_markup(txt) +                  if txt.size > (SiSU_DbColumns::ColumnSize.new.endnote_clean - 1) +                    puts "\n\nTOO LARGE (ENDNOTE - see error log)\n\n" +                    open("#{Dir.pwd}/pg_documents_error_log",'a') do |error| +                      error.puts("\n#{@opt.fns}\nENDNOTE\n#{txt.size} object #{@col[:ocn]},#{@col[:ocnd]},#{@col[:ocns]} -> #{txt.slice(0..500)}") +                    end +                    txt=%{\n\nLARGE TEXT BLOCK OMITTED\n\n} +                  end +                  if txt +                    en={ +                      type: 'endnotes', +                      id:      @id_n, +                      lid:     @col[:lid], +                      nr:      nr, +                      txt:     txt, +                      body:    body, +                      ocn:     @col[:ocn], +                      ocnd:    @col[:ocnd], +                      ocns:    @col[:ocns], +                      id_t:    @@id_t, +                      hash:    digest_clean +                    } +                    t=SiSU_DbTuple::LoadEndnotes.new(@conn,en,@opt,@file_maint) +                    @tuple_array << t.tuple +                  end +                end +              end +              word_mode=notedata.scan(/\S+/) +            end +            if notedata =~/#{Mx[:en_b_o]}\*.+?#{Mx[:en_b_c]}/                                      #% import into database endnotes tables +              endnote_array=notedata.scan(/#{Mx[:en_b_o]}\*.+?#{Mx[:en_b_c]}/) +              endnote_array.each do |inf| +                if inf[/#{Mx[:en_b_o]}\*\d+.+?#{Mx[:en_b_c]}/]                    # dal new endnotes 2003w31/1 +                  if inf[/#{Mx[:en_b_o]}[*](\d+)(.+?)#{Mx[:en_b_c]}/]           # dal new endnotes 2003w31/1 +                    nr,txt,digest_clean=$1,$2.strip,0 +                  end +                  @id_n+=1 +                  txt=special_character_escape(txt) +                  body=SiSU_FormatShared::CSS_Format.new(@md,data).endnote(nr,txt) +                  txt=strip_markup(txt) +                  if txt.size > (SiSU_DbColumns::ColumnSize.new.endnote_clean - 1) +                    puts "\n\nTOO LARGE (ENDNOTE - see error log)\n\n" +                    open("#{Dir.pwd}/pg_documents_error_log",'a') do |error| +                      error.puts("\n#{@opt.fns}\nENDNOTE\n#{txt.size} object #{@col[:ocn]},#{@col[:ocnd]},#{@col[:ocns]} -> #{txt.slice(0..500)}") +                    end +                    txt=%{\n\nLARGE TEXT BLOCK OMITTED\n\n} +                  end +                  if txt +                    en={ +                      type: 'endnotes_asterisk', +                      id:      @id_n, +                      lid:     @col[:lid], +                      nr:      nr, +                      txt:     txt, +                      body:    body, +                      ocn:     @col[:ocn], +                      ocnd:    @col[:ocnd], +                      ocns:    @col[:ocns], +                      id_t:    @@id_t, +                      hash:    digest_clean +                    } +                    t=SiSU_DbTuple::LoadEndnotes.new(@conn,en,@opt,@file_maint) +                    @tuple_array << t.tuple +                  end +                end +              end +              word_mode=notedata.scan(/\S+/) +            end +            if notedata =~/#{Mx[:en_b_o]}\+.+?#{Mx[:en_b_c]}/                                           #% import into database endnotes tables +              endnote_array=notedata.scan(/#{Mx[:en_b_o]}\+.+?#{Mx[:en_b_c]}/) +              endnote_array.each do |inf| +                if inf[/#{Mx[:en_b_o]}\+\d+.+?#{Mx[:en_b_c]}/]                        # dal new endnotes 2003w31/1 +                  if inf[/#{Mx[:en_b_o]}[+](\d+)(.+?)#{Mx[:en_b_c]}/]               # dal new endnotes 2003w31/1 +                    nr,txt,digest_clean=$1,$2.strip,0 +                  end +                  @id_n+=1 +                  txt=special_character_escape(txt) +                  body=SiSU_FormatShared::CSS_Format.new(@md,data).endnote(nr,txt) +                  txt=strip_markup(txt) +                  if txt.size > (SiSU_DbColumns::ColumnSize.new.endnote_clean - 1) +                    puts "\n\nTOO LARGE (ENDNOTE - see error log)\n\n" +                    open("#{Dir.pwd}/pg_documents_error_log",'a') do |error| +                      error.puts("\n#{@opt.fns}\nENDNOTE\n#{txt.size} object #{@col[:ocn]},#{@col[:ocnd]},#{@col[:ocns]} -> #{txt.slice(0..500)}") +                    end +                    txt=%{\n\nLARGE TEXT BLOCK OMITTED\n\n} +                  end +                  if txt +                    en={ +                      type: 'endnotes_plus', +                      id:      @id_n, +                      lid:     @col[:lid], +                      nr:      nr, +                      txt:     txt, +                      body:    body, +                      ocn:     @col[:ocn], +                      ocnd:    @col[:ocnd], +                      ocns:    @col[:ocns], +                      id_t:    @@id_t, +                      hash:    digest_clean +                    } +                    t=SiSU_DbTuple::LoadEndnotes.new(@conn,en,@opt,@file_maint) +                    @tuple_array << t.tuple +                  end +                end +              end +              word_mode=notedata.scan(/\S+/) +            end +          end +        end +      rescue +        SiSU_Errors::Rescued.new($!,$@,@opt.selections.str,@opt.fns).location do +          __LINE__.to_s + ':' + __FILE__ +        end +      ensure +      end +      @tuple_array +    end +    def endnotes(txt) +      @txt=txt +      def extract_any +        if @txt =~/(?:#{Mx[:en_a_o]}|#{Mx[:en_b_o]})[*+]?(\d+)\s+.+?(?:#{Mx[:en_a_c]}|#{Mx[:en_b_c]})/ +          endnotes(@txt).range +          @en << endnotes(@txt).standard if @txt =~/#{Mx[:en_a_o]}.+?#{Mx[:en_a_c]}/ +          @en_ast << endnotes(@txt).asterisk if @txt =~/#{Mx[:en_b_o]}\*.+?#{Mx[:en_b_c]}/ +          @en_pls << endnotes(@txt).plus if @txt =~/#{Mx[:en_b_o]}\+.+?#{Mx[:en_b_c]}/ +          @txt=endnotes(@txt).clean_text +        end +        @txt +      end +      def standard +        (@txt =~/#{Mx[:en_a_o]}.+?#{Mx[:en_a_c]}/) \ +        ? @txt.scan(/#{Mx[:en_a_o]}(\d+).+?#{Mx[:en_a_c]}/) +        : nil +      end +      def asterisk +        (@txt =~/#{Mx[:en_b_o]}\*.+?#{Mx[:en_b_c]}/) \ +        ? @txt.scan(/#{Mx[:en_b_o]}[*](\d+).+?#{Mx[:en_b_c]}/) +        : nil +      end +      def plus +        (@txt =~/#{Mx[:en_b_o]}\+.+?#{Mx[:en_b_c]}/) \ +        ? @txt.scan(/#{Mx[:en_b_o]}[+](\d+).+?#{Mx[:en_b_c]}/) +        : nil +      end +      def clean_text(base_url=nil) +        @txt=if base_url +          @txt.gsub(/#{Mx[:en_a_o]}(\d+).+?#{Mx[:en_a_c]}/,%{<sup><a href="#{base_url}#_\\1" name="-\\1">\\1</a></sup>}). +            gsub(/#{Mx[:en_b_o]}([*]\d+).+?#{Mx[:en_b_c]}/,%{<sup><a href="#{base_url}#_\\1" name="-\\1">\\1</a></sup>}). +            gsub(/#{Mx[:en_b_o]}([+]\d+).+?#{Mx[:en_b_c]}/,%{<sup><a href="#{base_url}#_\\1" name="-\\1">\\1</a></sup>}) +        else +          @txt.gsub(/#{Mx[:en_a_o]}(\d+).+?#{Mx[:en_a_c]}/,'<sup>\1</sup>'). +            gsub(/#{Mx[:en_b_o]}([*]\d+).+?#{Mx[:en_b_c]}/,'<sup>\1</sup>'). +            gsub(/#{Mx[:en_b_o]}([+]\d+).+?#{Mx[:en_b_c]}/,'<sup>\1</sup>') +        end +        @txt +      end +      def range +        @col[:en_a]=@col[:en_z]=nil +        if @txt =~/#{Mx[:en_a_o]}.+?#{Mx[:en_a_c]}|#{Mx[:en_b_o]}([*]\d+).+?#{Mx[:en_b_c]}|#{Mx[:en_b_o]}([+]\d+).+?#{Mx[:en_b_c]}/ +          word_array=@txt.scan(/\S+/) +          word_array.each do |w| +            if w[/(?:#{Mx[:en_a_o]}|#{Mx[:en_b_o]})[*+]?(\d+)\s+.+?(?:#{Mx[:en_a_c]}|#{Mx[:en_b_c]})(?:#{Mx[:en_a_c]}|#{Mx[:en_b_c]})/]                                                # not tested since change 2003w31 +              @col[:en_a]=$1 unless @col[:en_a] +              @col[:en_z]=@col[:en_a].dup unless @col[:en_a] +              @col[:en_z]=$1 if @col[:en_a] +            end +          end +        end +        @col +      end +      self +    end +    def db_import_urls(dbi_unit,content)                                           #% import documents OID - populate database +      begin +        @fnc=content +        @env=SiSU_Env::InfoEnv.new(@opt.fns) +        f,u={},{} +        if @fnb.empty? \ +        or @fnb.nil? +          p 'file output path error' #remove +        end +        if FileTest.file?("#{@md.file.output_path.txt.dir}/#{@md.file.base_filename.txt}")==true +          f[:txt],u[:txt]='plaintext,', "'#{@md.file.output_path.txt.url}/#{@md.file.base_filename.txt}'," +        end +        if FileTest.file?("#{@md.file.output_path.html_seg.dir}/#{@md.file.base_filename.html_segtoc}")==true +          f[:html_toc],u[:html_toc]='html_toc,', "'#{@md.file.output_path.html_seg.url}/#{@md.file.base_filename.html_segtoc}'," +        end +        if FileTest.file?("#{@md.file.output_path.html_scroll.dir}/#{@md.file.base_filename.html_scroll}")==true +          f[:html_doc],u[:html_doc]='html_doc,', "'#{@md.file.output_path.html_scroll.url}/#{@md.file.base_filename.html_scroll}'," +        end +        if FileTest.file?("#{@md.file.output_path.xhtml.dir}/#{@md.file.base_filename.xhtml}")==true +          f[:xhtml],u[:xhtml]='xhtml,', "'#{@md.file.output_path.xhtml.url}/#{@md.file.base_filename.xhtml}'," +        end +        if FileTest.file?("#{@md.file.output_path.xml_sax.dir}/#{@md.file.base_filename.xml_sax}")==true +          f[:xml_sax],u[:xml_sax]='xml_sax,', "'#{@md.file.output_path.xml_sax.url}/#{@md.file.base_filename.xml_sax}'," +        end +        if FileTest.file?("#{@md.file.output_path.xml_dom.dir}/#{@md.file.base_filename.xml_dom}")==true +          f[:xml_dom],u[:xml_dom]='xml_dom,', "'#{@md.file.output_path.xml_dom.url}/#{@md.file.base_filename.xml_dom}'," +        end +        if FileTest.file?("#{@md.file.output_path.epub.dir}/#{@md.file.base_filename.epub}")==true +          f[:epub],u[:epub]='epub,', "'#{@md.file.output_path.epub.url}/#{@md.file.base_filename.epub}'," +        end +        if FileTest.file?("#{@md.file.output_path.odt.dir}/#{@md.file.base_filename.odt}")==true +          f[:odf],u[:odf]='odf,', "'#{@md.file.output_path.odt.url}/#{@md.file.base_filename.odt}'," +        end +        if FileTest.file?("#{@md.file.output_path.pdf.dir}/#{@pdf_fn.pdf_p_a4}")==true #\ +        #or FileTest.file?("#{@md.file.output_path.pdf.dir}/#{@pdf_fn.pdf_p_letter}")==true +          f[:pdf_p],u[:pdf_p]='pdf_p,', "'#{@md.file.output_path.pdf.url}/#{@pdf_fn.pdf_p_a4}'," +        end +        if FileTest.file?("#{@md.file.output_path.pdf.dir}/#{@pdf_fn.pdf_l_a4}")==true #\ +        #or FileTest.file?("#{@md.file.output_path.pdf.dir}/#{@pdf_fn.pdf_l_letter}")==true +          f[:pdf_l],u[:pdf_l]='pdf_l,', "'#{@md.file.output_path.pdf.url}/#{@pdf_fn.pdf_l_a4}'," +        end +        if FileTest.file?("#{@md.file.output_path.html_concordance.dir}/#{@md.file.base_filename.html_concordance}")==true +          f[:concordance],u[:concordance]='concordance,', "'#{@md.file.output_path.html_concordance.url}/#{@md.file.base_filename.html_concordance}'," +        end +        #if FileTest.file?("#{@md.file.output_path.x.dir}/#{@md.file.base_filename.x}")==true +        #  f[:latex_p],u[:latex_p]='latex_p,', "'#{@md.file.output_path.x.url}/#{@md.file.base_filename.x}'," +        #end +        ##if FileTest.file?("#{out}/#{@fnb}/#{@opt.fns}.tex")==true +        ##  f[:latex_p],u[:latex_p]='latex_p,', "'#{base}/#{@fnb}/#{@opt.fns}.tex'," +        ##end +        #if FileTest.file?("#{@md.file.output_path.x.dir}/#{@md.file.base_filename.x}")==true +        #  f[:latex_l],u[:latex_l]='latex_l,', "'#{@md.file.output_path.x.url}/#{@md.file.base_filename.x}'," +        #end +        ##if FileTest.file?("#{out}/#{@fnb}/#{@opt.fns}.landscape.tex")==true +        ##  f[:latex_l],u[:latex_l]='latex_l,', "'#{base}/#{@fnb}/#{@opt}.fns}.landscape.tex'," +        ##end +        if FileTest.file?("#{@md.file.output_path.digest.dir}/#{@md.file.base_filename.digest}")==true +          f[:digest],u[:digest]='digest,', "'#{@md.file.output_path.digest.url}/#{@md.file.base_filename.digest}'," +        end +        if FileTest.file?("#{@md.file.output_path.manifest.dir}/#{@md.file.base_filename.manifest}")==true #revisit, was to be text, this is html +          f[:manifest],u[:manifest]='manifest,', "'#{@md.file.output_path.manifest.url}/#{@md.file.base_filename.manifest}'," +        end +        if FileTest.file?("#{@md.file.output_path.src.dir}/#{@md.file.base_filename.src}")==true +          f[:markup],u[:markup]='markup,', "'#{@md.file.output_path.src.url}/#{@md.file.base_filename.src}'," +        end +        if FileTest.file?("#{@md.file.output_path.sisupod.dir}/#{@md.file.base_filename.sisupod}")==true +          f[:sisupod],u[:sisupod]='sisupod,', "'#{@md.file.output_path.sisupod.url}/#{@md.file.base_filename.sisupod}'," +        end +        t=SiSU_DbTuple::LoadUrls.new(@conn,f,u,@@id_t,@opt,@file_maint) +        tuple=t.tuple +      rescue +        SiSU_Errors::Rescued.new($!,$@,@opt.selections.str,@opt.fns).location do +          __LINE__.to_s + ':' + __FILE__ +        end +      ensure +      end +      tuple +    end +  end +end +__END__ +#+END_SRC + +** db_remove.rb + +#+BEGIN_SRC ruby  :tangle "../lib/sisu/db_remove.rb" +# <<sisu_document_header>> +module SiSU_DbRemove +  class Remove +    include SiSU_DbAction +    def initialize(opt,conn,file,sql_type) +      @opt,@conn,@file,@sql_type=opt,conn,file,sql_type +      @md=SiSU_Param::Parameters.new(@opt).get +      @fnb=@md.fnb +      @db=SiSU_Env::InfoDb.new +    end +    def remove +      driver_sqlite3=if @sql_type==:sqlite +        (@conn.inspect.match(/^(.{10})/)[1]==@db.sqlite.conn_sqlite3.inspect.match(/^(.{10})/)[1]) \ +        ? true +        : false +      end +      del_id=if driver_sqlite3 +        begin +          remove_selected=%{ +            SELECT tid +            FROM metadata_and_text +            WHERE src_filename = '#{@md.fns}' +            AND metadata_and_text.language_document_char = '#{@opt.lng}' +          ;} # note, for .ssm: @md.fns (is set during runtime & is) != @opt.fns @md.opt.fns +          @conn.get_first_value(remove_selected).to_i +        rescue SQLite3::Exception => e +          #not tested +          puts "Exception occurred" +          SiSU_Utils::CodeMarker.new(__LINE__,__FILE__,:fuchsia).mark(e.inspect) +          SiSU_Utils::CodeMarker.new(__LINE__,__FILE__,:yellow).mark( +            "\n" \ +            + 'Attempting to initialize db' + "\n" \ +            + 'Creating db tables' +          ) +          sdb={ +            create: SiSU_DbDBI::Create.new(@opt,@conn,@file_maint,@sql_type), +            index: SiSU_DbDBI::Index.new(@opt,@conn,@file_maint,@sql_type), +          } +          db_action(sdb).create +        end +      else +        begin +          remove_selected=%{ +            SELECT metadata_and_text.tid +            FROM metadata_and_text +            WHERE metadata_and_text.src_filename = '#{@md.fns}' +            AND metadata_and_text.language_document_char = '#{@opt.lng}' +          ;} # note, for .ssm: @md.fns (is set during runtime & is) != @opt.fns @md.opt.fns +          x=@conn.exec(remove_selected) +          x.field_values("tid")[0] +        rescue PG::Error => e +          err=[ +            e.result.error_field( PG::Result::PG_DIAG_SEVERITY ), +            e.result.error_field( PG::Result::PG_DIAG_SQLSTATE ), +            e.result.error_field( PG::Result::PG_DIAG_MESSAGE_PRIMARY ), +            e.result.error_field( PG::Result::PG_DIAG_MESSAGE_DETAIL ), +            e.result.error_field( PG::Result::PG_DIAG_MESSAGE_HINT ), +            e.result.error_field( PG::Result::PG_DIAG_STATEMENT_POSITION ), +            e.result.error_field( PG::Result::PG_DIAG_INTERNAL_POSITION ), +            e.result.error_field( PG::Result::PG_DIAG_INTERNAL_QUERY ), +            e.result.error_field( PG::Result::PG_DIAG_CONTEXT ), +            e.result.error_field( PG::Result::PG_DIAG_SOURCE_FILE ), +            e.result.error_field( PG::Result::PG_DIAG_SOURCE_LINE ), +            e.result.error_field( PG::Result::PG_DIAG_SOURCE_FUNCTION ), +          ] +          SiSU_Utils::CodeMarker.new(__LINE__,__FILE__,:fuchsia).mark("\n" + err.inspect) +          if err[2] =~/relation "\S+?" does not exist/ \ +          or err.inspect =~/relation "\S+?" does not exist/ +            SiSU_Utils::CodeMarker.new(__LINE__,__FILE__,:yellow).mark( +              "\n" \ +              + err[2] + "\n" \ +              + 'Attempting to initialize db' + "\n" \ +              + 'Creating db tables' +            ) +            sdb={ +              create: SiSU_DbDBI::Create.new(@opt,@conn,@file_maint,@sql_type), +              index: SiSU_DbDBI::Index.new(@opt,@conn,@file_maint,@sql_type), +            } +            db_action(sdb).create +          end +        end +      end +      if del_id +        sql_entry=[ +          "DELETE FROM endnotes WHERE metadata_tid = '#{del_id}';", +          "DELETE FROM endnotes_asterisk WHERE metadata_tid = '#{del_id}';", +          "DELETE FROM endnotes_plus WHERE metadata_tid = '#{del_id}';", +          "DELETE FROM doc_objects WHERE metadata_tid = '#{del_id}';", +          "DELETE FROM urls WHERE metadata_tid = '#{del_id}';", +          "DELETE FROM metadata_and_text WHERE metadata_and_text.tid = '#{del_id}';", +        ] +        if driver_sqlite3 +          @conn.transaction +          sql_entry.each do |s| +            begin +              @conn.execute(s) +            rescue +              next +            end +          end +          @conn.commit if driver_sqlite3 +        else +          sql_entry.each do |s| +            begin +              @conn.exec_params(s) +            rescue +              next +            end +          end +        end +        if @opt.act[:maintenance][:set]==:on +          @file.puts sql_entry +        end +      else +        if (@opt.act[:verbose][:set]==:on \ +        || @opt.act[:verbose_plus][:set]==:on \ +        || @opt.act[:maintenance][:set]==:on) +          SiSU_Screen::Ansi.new( +            @opt.selections.str, +            "no such file in database #{@db.psql.db}::#{@opt.fns}" +          ).puts_grey +        end +      end +    end +  end +end +__END__ +#+END_SRC + +* db_load_tuple.rb + +#+BEGIN_SRC ruby  :tangle "../lib/sisu/db_load_tuple.rb" +# <<sisu_document_header>> +module SiSU_DbTuple +  require_relative 'db_columns'                         # db_columns.rb +  class LoadDocuments +    require_relative 'dp'                               # dp.rb +      include SiSU_Param +    def initialize(conn,col,opt,file_maint) +      @conn,@col,@opt,@file_maint=conn,col,opt,file_maint +      @col[:lev]=@col[:lev].to_i +      unless @col[:lev].inspect=~/^[0-7]/ \ +      or @col[:lev]==0..7 +        @col[:lev]=9 +      end +      @col[:ocn]=0 unless @col[:ocn].inspect=~/\d+/ +      @cX=SiSU_Screen::Ansi.new(@opt.act[:color_state][:set]).cX +    end +    def tuple                                                                    #% import line +      sql_entry=if @col[:en_a] +        "INSERT INTO doc_objects (lid, metadata_tid, lev, lev_an, clean, body, book_idx, ocn, ocnd, ocns, seg, lev0, lev1, lev2, lev3, lev4, lev5, lev6, lev7, en_a, en_z, t_of, t_is, node, parent, digest_clean, digest_all) " + +        "VALUES (#{@col[:lid]}, #{@col[:tid]}, #{@col[:lev]}, '#{@col[:lev_an]}', '#{@col[:plaintext]}', '#{@col[:body]}', '#{@col[:book_idx]}', '#{@col[:ocn]}', '#{@col[:ocnd]}', '#{@col[:ocns]}', '#{@col[:seg]}', '#{@col[:lv0]}', '#{@col[:lv1]}', '#{@col[:lv2]}', '#{@col[:lv3]}', '#{@col[:lv4]}', '#{@col[:lv5]}', '#{@col[:lv6]}', '#{@col[:lv7]}', '#{@col[:en_a]}', '#{@col[:en_z]}', '#{@col[:t_of]}', '#{@col[:t_is]}', '#{@col[:node]}', '#{@col[:parent]}', '#{@col[:digest_clean]}', '#{@col[:digest_all]}');" +      else +        "INSERT INTO doc_objects (lid, metadata_tid, lev, lev_an, clean, body, book_idx, ocn, ocnd, ocns, seg, lev0, lev1, lev2, lev3, lev4, lev5, lev6, lev7, t_of, t_is, node, parent, digest_clean, digest_all) " + +        "VALUES (#{@col[:lid]}, #{@col[:tid]}, #{@col[:lev]}, '#{@col[:lev_an]}', '#{@col[:plaintext]}', '#{@col[:body]}', '#{@col[:book_idx]}', '#{@col[:ocn]}', '#{@col[:ocnd]}', '#{@col[:ocns]}', '#{@col[:seg]}', '#{@col[:lv0]}', '#{@col[:lv1]}', '#{@col[:lv2]}', '#{@col[:lv3]}', '#{@col[:lv4]}', '#{@col[:lv5]}', '#{@col[:lv6]}', '#{@col[:lv7]}', '#{@col[:t_of]}', '#{@col[:t_is]}', '#{@col[:node]}', '#{@col[:parent]}', '#{@col[:digest_clean]}', '#{@col[:digest_all]}');" +      end +      if @opt.act[:maintenance][:set]==:on +          puts @file_maint.inspect +          puts sql_entry +          @file_maint.puts sql_entry +      elsif @opt.act[:verbose_plus][:set]==:on +          puts sql_entry +      end +      if @opt.act[:verbose][:set]==:on +        if @col[:lev].inspect =~/[0-35-7]/ +          lev=case @col[:lev].inspect +          when /0/ then ':A' +          when /1/ then ':B' +          when /2/ then ':C' +          when /3/ then ':D' +          when /5/ then ' 2' +          when /6/ then ' 3' +          when /7/ then ' 4' +          end +          puts %{#{lev}>\t#{@col[:lv0]}\t#{@col[:lv1]}\t#{@col[:lv2]}\t#{@col[:lv3]}\t#{@col[:lv4]}\t#{@col[:lv5]}\t#{@col[:lv6]}\t#{@col[:lv7]}\t#{@col[:ocn]}\t#{@col[:node]}\t#{@col[:ocns]}} +        elsif @col[:lev].inspect =~/[4]/ +          puts %{ #{@cX.green}1>#{@cX.off}\t#{@col[:lv0]}\t#{@col[:lv1]}\t#{@col[:lv2]}\t#{@col[:lv3]}\t#{@col[:lv4]}\t#{@col[:lv5]}\t#{@col[:lv6]}\t#{@col[:lv7]}\t#{@col[:ocn]}\t#{@col[:node]}\t#{@col[:ocns]}\t#{@col[:seg]}} +        end +      end +      sql_entry +    end +  end +  class LoadMetadata #< SiSU_DbColumns::Columns +    def initialize(conn,id,md,file_maint) +      @conn,@id,@md,@file_maint=conn,id,md,file_maint +      @tp=SiSU_DbColumns::Columns.new(md) +    end +    def tuple +      sql_entry="INSERT INTO metadata_and_text ( +#{@tp.column.title.tuple[0]} +#{@tp.column.title_main.tuple[0]} +#{@tp.column.title_sub.tuple[0]} +#{@tp.column.title_short.tuple[0]} +#{@tp.column.title_edition.tuple[0]} +#{@tp.column.title_note.tuple[0]} +#{@tp.column.title_language.tuple[0]} +#{@tp.column.title_language_char.tuple[0]} +#{@tp.column.creator_author.tuple[0]} +#{@tp.column.creator_author_honorific.tuple[0]} +#{@tp.column.creator_author_nationality.tuple[0]} +#{@tp.column.creator_editor.tuple[0]} +#{@tp.column.creator_contributor.tuple[0]} +#{@tp.column.creator_illustrator.tuple[0]} +#{@tp.column.creator_photographer.tuple[0]} +#{@tp.column.creator_translator.tuple[0]} +#{@tp.column.creator_prepared_by.tuple[0]} +#{@tp.column.creator_digitized_by.tuple[0]} +#{@tp.column.creator_audio.tuple[0]} +#{@tp.column.creator_video.tuple[0]} +#{@tp.column.language_document.tuple[0]} +#{@tp.column.language_document_char.tuple[0]} +#{@tp.column.language_original.tuple[0]} +#{@tp.column.language_original_char.tuple[0]} +#{@tp.column.date_added_to_site.tuple[0]} +#{@tp.column.date_available.tuple[0]} +#{@tp.column.date_created.tuple[0]} +#{@tp.column.date_issued.tuple[0]} +#{@tp.column.date_modified.tuple[0]} +#{@tp.column.date_published.tuple[0]} +#{@tp.column.date_valid.tuple[0]} +#{@tp.column.date_translated.tuple[0]} +#{@tp.column.date_original_publication.tuple[0]} +#{@tp.column.date_generated.tuple[0]} +#{@tp.column.publisher.tuple[0]} +#{@tp.column.original_publisher.tuple[0]} +#{@tp.column.original_language.tuple[0]} +#{@tp.column.original_language_char.tuple[0]} +#{@tp.column.original_source.tuple[0]} +#{@tp.column.original_institution.tuple[0]} +#{@tp.column.original_nationality.tuple[0]} +#{@tp.column.rights_all.tuple[0]} +#{@tp.column.rights_copyright_text.tuple[0]} +#{@tp.column.rights_copyright_translation.tuple[0]} +#{@tp.column.rights_copyright_illustrations.tuple[0]} +#{@tp.column.rights_copyright_photographs.tuple[0]} +#{@tp.column.rights_copyright_preparation.tuple[0]} +#{@tp.column.rights_copyright_digitization.tuple[0]} +#{@tp.column.rights_copyright_audio.tuple[0]} +#{@tp.column.rights_copyright_video.tuple[0]} +#{@tp.column.rights_license.tuple[0]} +#{@tp.column.classify_topic_register.tuple[0]} +#{@tp.column.classify_subject.tuple[0]} +#{@tp.column.classify_loc.tuple[0]} +#{@tp.column.classify_dewey.tuple[0]} +#{@tp.column.classify_keywords.tuple[0]} +#{@tp.column.identifier_oclc.tuple[0]} +#{@tp.column.identifier_isbn.tuple[0]} +#{@tp.column.notes_abstract.tuple[0]} +#{@tp.column.notes_description.tuple[0]} +#{@tp.column.notes_comment.tuple[0]} +#{@tp.column.notes_history.tuple[0]} +#{@tp.column.notes_format.tuple[0]} +#{@tp.column.notes_relation.tuple[0]} +#{@tp.column.notes_coverage.tuple[0]} +#{@tp.column.notes_type.tuple[0]} +#{@tp.column.notes_prefix.tuple[0]} +#{@tp.column.notes_prefix_a.tuple[0]} +#{@tp.column.notes_prefix_b.tuple[0]} +#{@tp.column.notes_suffix.tuple[0]} +#{@tp.column.src_filename.tuple[0]} +#{@tp.column.src_fingerprint.tuple[0]} +#{@tp.column.src_filesize.tuple[0]} +#{@tp.column.src_word_count.tuple[0]} +#{@tp.column.src_txt.tuple[0]} +#{@tp.column.fulltext.tuple[0]} +tid) +" + +       "VALUES ( +#{@tp.column.title.tuple[1]} +#{@tp.column.title_main.tuple[1]} +#{@tp.column.title_sub.tuple[1]} +#{@tp.column.title_short.tuple[1]} +#{@tp.column.title_edition.tuple[1]} +#{@tp.column.title_note.tuple[1]} +#{@tp.column.title_language.tuple[1]} +#{@tp.column.title_language_char.tuple[1]} +#{@tp.column.creator_author.tuple[1]} +#{@tp.column.creator_author_honorific.tuple[1]} +#{@tp.column.creator_author_nationality.tuple[1]} +#{@tp.column.creator_editor.tuple[1]} +#{@tp.column.creator_contributor.tuple[1]} +#{@tp.column.creator_illustrator.tuple[1]} +#{@tp.column.creator_photographer.tuple[1]} +#{@tp.column.creator_translator.tuple[1]} +#{@tp.column.creator_prepared_by.tuple[1]} +#{@tp.column.creator_digitized_by.tuple[1]} +#{@tp.column.creator_audio.tuple[1]} +#{@tp.column.creator_video.tuple[1]} +#{@tp.column.language_document.tuple[1]} +#{@tp.column.language_document_char.tuple[1]} +#{@tp.column.language_original.tuple[1]} +#{@tp.column.language_original_char.tuple[1]} +#{@tp.column.date_added_to_site.tuple[1]} +#{@tp.column.date_available.tuple[1]} +#{@tp.column.date_created.tuple[1]} +#{@tp.column.date_issued.tuple[1]} +#{@tp.column.date_modified.tuple[1]} +#{@tp.column.date_published.tuple[1]} +#{@tp.column.date_valid.tuple[1]} +#{@tp.column.date_translated.tuple[1]} +#{@tp.column.date_original_publication.tuple[1]} +#{@tp.column.date_generated.tuple[1]} +#{@tp.column.publisher.tuple[1]} +#{@tp.column.original_publisher.tuple[1]} +#{@tp.column.original_language.tuple[1]} +#{@tp.column.original_language_char.tuple[1]} +#{@tp.column.original_source.tuple[1]} +#{@tp.column.original_institution.tuple[1]} +#{@tp.column.original_nationality.tuple[1]} +#{@tp.column.rights_all.tuple[1]} +#{@tp.column.rights_copyright_text.tuple[1]} +#{@tp.column.rights_copyright_translation.tuple[1]} +#{@tp.column.rights_copyright_illustrations.tuple[1]} +#{@tp.column.rights_copyright_photographs.tuple[1]} +#{@tp.column.rights_copyright_preparation.tuple[1]} +#{@tp.column.rights_copyright_digitization.tuple[1]} +#{@tp.column.rights_copyright_audio.tuple[1]} +#{@tp.column.rights_copyright_video.tuple[1]} +#{@tp.column.rights_license.tuple[1]} +#{@tp.column.classify_topic_register.tuple[1]} +#{@tp.column.classify_subject.tuple[1]} +#{@tp.column.classify_loc.tuple[1]} +#{@tp.column.classify_dewey.tuple[1]} +#{@tp.column.classify_keywords.tuple[1]} +#{@tp.column.identifier_oclc.tuple[1]} +#{@tp.column.identifier_isbn.tuple[1]} +#{@tp.column.notes_abstract.tuple[1]} +#{@tp.column.notes_comment.tuple[1]} +#{@tp.column.notes_description.tuple[1]} +#{@tp.column.notes_history.tuple[1]} +#{@tp.column.notes_format.tuple[1]} +#{@tp.column.notes_relation.tuple[1]} +#{@tp.column.notes_coverage.tuple[1]} +#{@tp.column.notes_type.tuple[1]} +#{@tp.column.notes_prefix.tuple[1]} +#{@tp.column.notes_prefix_a.tuple[1]} +#{@tp.column.notes_prefix_b.tuple[1]} +#{@tp.column.notes_suffix.tuple[1]} +#{@tp.column.src_filename.tuple[1]} +#{@tp.column.src_fingerprint.tuple[1]} +#{@tp.column.src_filesize.tuple[1]} +#{@tp.column.src_word_count.tuple[1]} +#{@tp.column.src_txt.tuple[1]} +#{@tp.column.fulltext.tuple[1]} +#{@id} +);" +      if @md.opt.act[:maintenance][:set]==:on +        puts "maintenance mode on: creating sql transaction file (for last transaction set (document) only):\n\t#{@file_maint.inspect}" +        @file_maint.puts sql_entry +      end +      sql_entry +    end +  end +  class LoadUrls +    def initialize(conn,f,u,id,opt,file_maint) +      @conn,@f,@u,@id,@opt,@file_maint=conn,f,u,id,opt,file_maint +    end +    def tuple +      sql_entry="INSERT INTO urls (#{@f[:txt]} #{@f[:html_toc]} #{@f[:html_doc]} #{@f[:xhtml]} #{@f[:xml_sax]} #{@f[:xml_dom]} #{@f[:odf]} #{@f[:pdf_p]} #{@f[:pdf_l]} #{@f[:concordance]} #{@f[:latex_p]} #{@f[:latex_l]} #{@f[:manifest]} #{@f[:digest]} #{@f[:markup]} #{@f[:sisupod]} metadata_tid) " + +      "VALUES (#{@u[:txt]} #{@u[:html_toc]} #{@u[:html_doc]} #{@u[:xhtml]} #{@u[:xml_sax]} #{@u[:xml_dom]} #{@u[:odf]} #{@u[:pdf_p]} #{@u[:pdf_l]} #{@u[:concordance]} #{@u[:latex_p]} #{@u[:latex_l]} #{@u[:manifest]} #{@u[:digest]} #{@u[:markup]} #{@u[:sisupod]} #{@id});" +      if @opt.act[:maintenance][:set]==:on +        @file_maint.puts sql_entry +      end +      sql_entry +    end +  end +  class LoadEndnotes +    def initialize(conn,en,opt,file_maint) +      @conn,@en,@opt,@file_maint=conn,en,opt,file_maint +    end +    def tuple +      sql_entry="INSERT INTO #{@en[:type]} (nid, document_lid, nr, clean, body, ocn, ocnd, ocns, metadata_tid, digest_clean) " + +      "VALUES ('#{@en[:id]}', '#{@en[:lid]}', '#{@en[:nr]}', '#{@en[:txt]}', '#{@en[:body]}', '#{@en[:ocn]}', '#{@en[:ocnd]}', '#{@en[:ocns]}', '#{@en[:id_t]}', '#{@en[:hash]}');" +      if @opt.act[:maintenance][:set]==:on +        @file_maint.puts sql_entry +      end +      sql_entry +    end +  end +end +__END__ +#+END_SRC + +* db_select.rb + +#+BEGIN_SRC ruby  :tangle "../lib/sisu/db_select.rb" +# <<sisu_document_header>> +module SiSU_DbAction +  def db_action(sdb) +    @sdb=sdb +    def createdb +      @sdb[:create].output_dir? +      begin +        @sdb[:create].create_db +      rescue +        @sdb[:create].output_dir? +      end +    end +    def drop +      @sdb[:drop].drop.tables +    end +    def create +      @sdb[:create].output_dir? +      begin +        @sdb[:create].create_table.metadata_and_text +        @sdb[:create].create_table.doc_objects +        @sdb[:create].create_table.endnotes +        @sdb[:create].create_table.endnotes_asterisk +        @sdb[:create].create_table.endnotes_plus +        @sdb[:create].create_table.urls +        @sdb[:index].create_indexes +      rescue +        SiSU_Errors::Rescued.new($!,$@,'--sqlite').location +        @sdb[:create].output_dir? do +          __LINE__.to_s + ':' + __FILE__ +        end +      end +    end +    def import +      db_exist? +      @sdb[:import].marshal_load +      tell=case @sql_type +      when :sqlite +        SiSU_Screen::Ansi.new( +          @opt.act[:color_state][:set], +          "sqlite3 #{@db.sqlite.db} database?" +        ) +      when :pg +        SiSU_Screen::Ansi.new( +          @opt.act[:color_state][:set], +          "pgaccess or psql #{@db.psql.db} database?" +        ) +      else '???' +      end +      tell.puts_grey if @opt.act[:verbose][:set]==:on +    end +    def remove +      db_exist? +      @sdb[:remove_doc].remove +    end +    def update +      remove +      import +    end +    self +  end +end +module SiSU_DbSelect +  class Case +    include SiSU_DbAction +    def initialize(opt,conn='',sql_type=:pg) +      @opt,@conn,@sql_type=opt,conn,sql_type +      @db=SiSU_Env::InfoDb.new +      @file_maint=sql_maintenance_file +      @sdb={ +        create: SiSU_DbDBI::Create.new(@opt,@conn,@file_maint,@sql_type), +        index: SiSU_DbDBI::Index.new(@opt,@conn,@file_maint,@sql_type), +        drop: SiSU_DbDBI::Drop.new(@opt,@conn,@db,@sql_type), +      } +      if (@opt.act[:psql_import][:set]==:on \ +      || @opt.act[:psql_update][:set]==:on) \ +      or (@opt.act[:sqlite_import][:set]==:on \ +      || @opt.act[:sqlite_update][:set]==:on) +        @sdb[:import]=SiSU_DbDBI::Import.new(@opt,@conn,@file_maint,@sql_type) +        @sdb[:remove_doc]=SiSU_DbDBI::Remove.new(@opt,@conn,@file_maint,@sql_type) +      elsif (@opt.act[:psql_remove][:set]==:on \ +      or @opt.act[:sqlite_remove][:set]==:on) +        @sdb[:remove_doc]=SiSU_DbDBI::Remove.new(@opt,@conn,@file_maint,@sql_type) +      end +    end +    def db_exist? +      if @sql_type==:sqlite \ +      and (not (FileTest.file?(@db.sqlite.db)) \ +      or FileTest.zero?(@db.sqlite.db)) +        puts %{no connection with sqlite database established, you may need to run:\n} \ +        + %{    sisu --sqlite --createall\n} \ +        + %{  before attempting to populate the database} +        SiSU_Utils::CodeMarker.new(__LINE__,__FILE__,:yellow).mark( +          "\n" \ +          + 'Attempting to initialize db' + "\n" \ +          + 'Creating db tables' +        ) +        db_action(@sdb).create +      end +      if @conn.is_a?(NilClass) +        if @sql_type==:sqlite +          puts %{no connection with sqlite database established, you may need to run:\n} \ +          + %{    sisu --sqlite --createall\n} \ +          + %{  before attempting to populate the database} +          SiSU_Utils::CodeMarker.new(__LINE__,__FILE__,:yellow).mark( +            "\n" \ +            + 'Attempting to initialize db' + "\n" \ +            + 'Creating db tables' +          ) +          db_action(@sdb).create +          @db.sqlite.db +        else +          puts %{no connection with pg database established, you may need to run:\n} \ +          + %{    createdb "#{@db.psql.db}"\n} \ +          + %{  after that don't forget to run:\n} \ +          + %{    sisu --pg --createall\n} \ +          + %{  before attempting to populate the database} +          @db.psql.db +        end +        exit +      end +    end +    def sql_maintenance_file +      file=if @opt.act[:maintenance][:set]==:on +        if @opt.fns and not @opt.fns.empty? +          @env=SiSU_Env::InfoEnv.new(@opt.fns) if @opt.fns +          if @sql_type ==:sqlite +            puts "\n#{@env.processing_path.sqlite}/#{@opt.fns}.sql" +          end +          @db=SiSU_Env::InfoDb.new +          @job="sqlite3 #{@db.sqlite.db} < #{@env.processing_path.sqlite}/#{@opt.fns}.sql" +          if @sql_type ==:sqlite +            File.new("#{@env.processing_path.sqlite}/#{@opt.fns}.sql",'w+') +          else +            File.new("#{@env.processing_path.postgresql}/#{@opt.fns}.sql",'w+') +          end +        elsif @opt.fns \ +        and (@opt.act[:sqlite_create][:set] ==:on \ +        || @opt.act[:psql_create][:set] ==:on) +          nil #sort variations later +        else nil +        end +      else nil +      end +      file +    end +    def cases +      if @opt.act[:psql_drop][:set] ==:on \ +      or @opt.act[:sqlite_drop][:set] ==:on +        db_action(@sdb).drop +      end +      if @opt.act[:psql_createdb][:set] ==:on \ +      or @opt.act[:sqlite_createdb][:set] ==:on +        db_action(@sdb).createdb +      end +      if @opt.act[:psql_create][:set] ==:on \ +      or @opt.act[:sqlite_create][:set] ==:on +        db_action(@sdb).create +      end +      if @opt.act[:psql_update][:set] ==:on \ +      or @opt.act[:sqlite_update][:set] ==:on +        db_action(@sdb).update +      else +        if @opt.act[:psql_remove][:set] ==:on \ +        or @opt.act[:sqlite_remove][:set] ==:on +          db_action(@sdb).remove +        end +        if @opt.act[:psql_import][:set] ==:on \ +        or @opt.act[:sqlite_import][:set] ==:on +          db_action(@sdb).import +        end +      end +    end +  end +end +__END__ +#+END_SRC + +* structure +** db_columns.rb + +#+BEGIN_SRC ruby  :tangle "../lib/sisu/db_columns.rb" +# <<sisu_document_header>> +module SiSU_DbColumns +  require_relative 'se'                                # se.rb +  require_relative 'db_sqltxt'                         # db_sqltxt.rb +  class Columns < SiSU_DbText::Prepare +    def initialize(md=nil) +      @md=md +      @db=SiSU_Env::InfoDb.new #watch +      @lang ||=SiSU_i18n::Languages.new +      if defined? md.opt.act \ +      and ((md.opt.act[:psql_import][:set]==:on \ +      || md.opt.act[:psql_update][:set]==:on) \ +      or (md.opt.act[:sqlite_import][:set]==:on \ +      || md.opt.act[:sqlite_update][:set]==:on)) \ +      and FileTest.exist?(md.fns) +        txt_arr=IO.readlines(md.fns,'') +        src=txt_arr.join("\n") +        if @db.share_source? +          @sisutxt=special_character_escape(src) +        else @sisutxt='' +        end +        @fulltext=clean_searchable_text_from_document_objects(txt_arr) +       else @sisutxt,@fulltext='','' +      end +    end +#% structures +    #def column_define +    #  def varchar(name,size) +    #    "#{name}                VARCHAR(#{size}) NULL," +    #  end +    #end +=begin +#% title +@title: + :subtitle: + :short: + :edition: + :language: + :note: +=end +    def column +      def title                          # DublinCore 1 - title +        def name +          'title' +        end +        def create_column +          "#{name}                VARCHAR(#{Db[:col_title]}) NOT NULL," +        end +        def column_comment +          %{COMMENT ON COLUMN metadata_and_text.#{name} +            IS 'metadata full document title [DC1]';} +        end +        def tuple +          if defined? @md.title.full \ +          and @md.title.full=~/\S+/ +            txt=@md.title.full +            txt=special_character_escape(txt) +            ["#{name}, ","'#{txt}', "] +          else ['',''] +          end +        end +        self +      end +      def title_main +        def name +          'title_main' +        end +        def create_column +          "#{name}                VARCHAR(#{Db[:col_title_part]}) NOT NULL," +        end +        def column_comment +          %{COMMENT ON COLUMN metadata_and_text.#{name} +            IS 'metadata main document title';} +        end +        def tuple +          if defined? @md.title.main \ +          and @md.title.main=~/\S+/ +            txt=@md.title.main +            txt=special_character_escape(txt) +            ["#{name}, ","'#{txt}', "] +          else ['',''] +          end +        end +        self +      end +      def title_sub +        def name +          'title_sub' +        end +        def create_column +          "#{name}                VARCHAR(#{Db[:col_title_part]}) NULL," +        end +        def column_comment +          %{COMMENT ON COLUMN metadata_and_text.#{name} +            IS 'metadata document subtitle';} +        end +        def tuple +          if defined? @md.title.sub \ +          and @md.title.sub=~/\S+/ +            txt=@md.title.sub +            txt=special_character_escape(txt) +            ["#{name}, ","'#{txt}', "] +          else ['',''] +          end +        end +        self +      end +      def title_short +        def name +          'title_short' +        end +        def create_column +          "#{name}                VARCHAR(#{Db[:col_title_part]}) NULL," +        end +        def column_comment +          %{COMMENT ON COLUMN metadata_and_text.#{name} +            IS 'metadata document short title if any';} +        end +        def tuple +          if defined? @md.title.short \ +          and @md.title.short=~/\S+/ +            txt=@md.title.short +            txt=special_character_escape(txt) +            ["#{name}, ","'#{txt}', "] +          else ['',''] +          end +        end +        self +      end +      def title_edition +        def name +          'title_edition' +        end +        def create_column +          "#{name}                VARCHAR(#{Db[:col_title_edition]}) NULL," +        end +        def column_comment +          %{COMMENT ON COLUMN metadata_and_text.#{name} +            IS 'metadata document edition (version)';} +        end +        def tuple +          if defined? @md.title.edition \ +          and @md.title.edition=~/\S+/ +            txt=@md.title.edition +            txt=special_character_escape(txt) +            ["#{name}, ","'#{txt}', "] +          else ['',''] +          end +        end +        self +      end +      def title_note +        def name +          'title_note' +        end +        def create_column +          "#{name}                VARCHAR(#{Db[:col_info_note]}) NULL," +        end +        def column_comment +          %{COMMENT ON COLUMN metadata_and_text.#{name} +            IS 'metadata document notes associated with title';} +        end +        def tuple +          if defined? @md.title.note \ +          and @md.title.note=~/\S+/ +            txt=@md.title.note +            txt=special_character_escape(txt) +            ["#{name}, ","'#{txt}', "] +          else ['',''] +          end +        end +        self +      end +      def title_language +        def name +          'title_language' +        end +        def create_column +          "#{name}                VARCHAR(#{Db[:col_language]}) NULL," +        end +        def column_comment +          %{COMMENT ON COLUMN metadata_and_text.#{name} +            IS 'metadata document language [DC12]';} +        end +        def tuple +          if @lang.list[@md.opt.lng][:n] +            txt=@lang.list[@md.opt.lng][:n] +            txt=special_character_escape(txt) +            ["#{name}, ","'#{txt}', "] +          else ['',''] +          end +        end +        self +      end +      def title_language_char            # consider +        def name +          'title_language_char' +        end +        def create_column +          "#{name}                VARCHAR(#{Db[:col_language_char]}) NULL," +        end +        def column_comment +          %{COMMENT ON COLUMN metadata_and_text.#{name} +            IS 'metadata document language iso code';} +        end +        def tuple +          if defined? @md.opt.lng \ +          and @md.opt.lng=~/\S+/ +            txt=@md.opt.lng +            txt=special_character_escape(txt) +            ["#{name}, ","'#{txt}', "] +          else ['',''] +          end +        end +        self +      end +=begin +#% creator +@creator: + :author: + :editor: + :contributor: + :illustrator: + :photographer: + :translator: + :prepared_by: + :digitized_by: + :audio: + :video: +=end +      def creator_author                 # DublinCore 2 - creator/author (author) +        def name +          'creator_author' +        end +        def create_column +          "#{name}                VARCHAR(#{Db[:col_name]}) NULL," +        end +        def column_comment +          %{COMMENT ON COLUMN metadata_and_text.#{name} +           IS 'metadata document author (creator) [DC2]';} +        end +        def tuple +          if defined? @md.creator.author_detail \ +          and @md.creator.author_detail.is_a?(Array) \ +          and @md.creator.author_detail.length > 0 +            txt='' +            @md.creator.author_detail.each do |h| +              txt=txt + %{#{h[:the]}, #{h[:others]}; } +            end +            txt=txt.gsub(/[;, ]+\s*$/,'') +            txt=special_character_escape(txt) +            ["#{name}, ","'#{txt}', "] +          else ['',''] +          end +        end +        self +      end +      def creator_author_honorific       # consider +        def name +          'creator_author_hon' +        end +        def create_column +          "#{name}                VARCHAR(#{Db[:col_creator_misc_short]}) NULL," +        end +        def column_comment +          %{COMMENT ON COLUMN metadata_and_text.#{name} +           IS 'metadata document author honorific (title e.g, Ms. Dr. Prof.)';} +        end +        def tuple +          if defined? @md.creator.author_hon \ +          and @md.creator.author_hon=~/\S+/ +            txt=@md.creator.author_hon +            txt=special_character_escape(txt) +            ["#{name}, ","'#{txt}', "] +          else ['',''] +          end +        end +        self +      end +      def creator_author_nationality     # consider +        def name +          'creator_author_nationality' +        end +        def create_column +          "#{name}                VARCHAR(#{Db[:col_creator_misc_short]}) NULL," +        end +        def column_comment +          %{COMMENT ON COLUMN metadata_and_text.#{name} +           IS 'metadata nationality of document author (creator)';} +        end +        def tuple +          if defined? @md.creator.author_nationality_detail \ +          and @md.creator.author_nationality=~/\S+/ +            txt=@md.creator.author_nationality_detail +            txt=special_character_escape(txt) +            ["#{name}, ","'#{txt}', "] +          else ['',''] +          end +        end +        self +      end +      def creator_editor +        def name +          'creator_editor' +        end +        def create_column +          "#{name}                VARCHAR(#{Db[:col_name]}) NULL," +        end +        def column_comment +          %{COMMENT ON COLUMN metadata_and_text.#{name} +           IS 'metadata document editor name(s)';} +        end +        def tuple +          if defined? @md.creator.editor_detail \ +          and @md.creator.editor_detail.is_a?(Array) \ +          and @md.creator.editor_detail.length > 0 +            txt='' +            @md.creator.editor_detail.each do |h| +              txt=txt + %{#{h[:the]}, #{h[:others]}; } +            end +            txt=txt.gsub(/[;, ]+\s*$/,'') +            txt=special_character_escape(txt) +            ["#{name}, ","'#{txt}', "] +          else ['',''] +          end +        end +        self +      end +      def creator_contributor            # DublinCore 6 - contributor +        def name +          'creator_contributor' +        end +        def create_column +          "#{name}                VARCHAR(#{Db[:col_name]}) NULL," +        end +        def column_comment +          %{COMMENT ON COLUMN metadata_and_text.#{name} +           IS 'metadata document contributor name(s) [DC6]';} +        end +        def tuple +          if defined? @md.creator.contributor_detail \ +          and @md.creator.contributor_detail.is_a?(Array) \ +          and @md.creator.contributor_detail.length > 0 +            txt='' +            @md.creator.contributor_detail.each do |h| +              txt=txt + %{#{h[:the]}, #{h[:others]}; } +            end +            txt=txt.gsub(/[;, ]+\s*$/,'') +            txt=special_character_escape(txt) +            ["#{name}, ","'#{txt}', "] +          else ['',''] +          end +        end +        self +      end +      def creator_illustrator +        def name +          'creator_illustrator' +        end +        def create_column +          "#{name}                VARCHAR(#{Db[:col_name]}) NULL," +        end +        def column_comment +          %{COMMENT ON COLUMN metadata_and_text.#{name} +           IS 'metadata document illustrator name(s)';} +        end +        def tuple +          if defined? @md.creator.illustrator_detail \ +          and @md.creator.illustrator_detail.is_a?(Array) \ +          and @md.creator.illustrator_detail.length > 0 +            txt='' +            @md.creator.illustrator_detail.each do |h| +              txt=txt + %{#{h[:the]}, #{h[:others]}; } +            end +            txt=txt.gsub(/[;, ]+\s*$/,'') +            txt=special_character_escape(txt) +            ["#{name}, ","'#{txt}', "] +          else ['',''] +          end +        end +        self +      end +      def creator_photographer +        def name +          'creator_photographer' +        end +        def create_column +          "#{name}                VARCHAR(#{Db[:col_name]}) NULL," +        end +        def column_comment +          %{COMMENT ON COLUMN metadata_and_text.#{name} +           IS 'metadata document photographer name(s)';} +        end +        def tuple +          if defined? @md.creator.photographer_detail \ +          and @md.creator.photographer_detail.is_a?(Array) \ +          and @md.creator.photographer_detail.length > 0 +            txt='' +            @md.creator.photographer_detail.each do |h| +              txt=txt + %{#{h[:the]}, #{h[:others]}; } +            end +            txt=txt.gsub(/[;, ]+\s*$/,'') +            txt=special_character_escape(txt) +            ["#{name}, ","'#{txt}', "] +          else ['',''] +          end +        end +        self +      end +      def creator_translator +        def name +          'creator_translator' +        end +        def create_column +          "#{name}                VARCHAR(#{Db[:col_name]}) NULL," +        end +        def column_comment +          %{COMMENT ON COLUMN metadata_and_text.#{name} +           IS 'metadata document translator name(s)';} +        end +        def tuple +          if defined? @md.creator.translator_detail \ +          and @md.creator.translator_detail.is_a?(Array) \ +          and @md.creator.translator_detail.length > 0 +            txt='' +            @md.creator.translator_detail.each do |h| +              txt=txt + %{#{h[:the]}, #{h[:others]}; } +            end +            txt=txt.gsub(/[;, ]+\s*$/,'') +            txt=special_character_escape(txt) +            ["#{name}, ","'#{txt}', "] +          else ['',''] +          end +        end +        self +      end +      def creator_prepared_by +        def name +          'creator_prepared_by' +        end +        def create_column +          "#{name}                VARCHAR(#{Db[:col_name]}) NULL," +        end +        def column_comment +          %{COMMENT ON COLUMN metadata_and_text.#{name} +           IS 'metadata document prepared by name(s)';} +        end +        def tuple +          if defined? @md.creator.prepared_by_detail \ +          and @md.creator.prepared_by_detail.is_a?(Array) \ +          and @md.creator.prepared_by_detail.length > 0 +            txt='' +            @md.creator.prepared_by_detail.each do |h| +              txt=txt + %{#{h[:the]}, #{h[:others]}; } +            end +            txt=txt.gsub(/[;, ]+\s*$/,'') +            txt=special_character_escape(txt) +            ["#{name}, ","'#{txt}', "] +          else ['',''] +          end +        end +        self +      end +      def creator_digitized_by +        def name +          'creator_digitized_by' +        end +        def create_column +          "#{name}                VARCHAR(#{Db[:col_name]}) NULL," +        end +        def column_comment +          %{COMMENT ON COLUMN metadata_and_text.#{name} +           IS 'metadata document digitized by name(s)';} +        end +        def tuple +          if defined? @md.creator.digitized_by_detail \ +          and @md.creator.digitized_by_detail.is_a?(Array) \ +          and @md.creator.digitized_by_detail.length > 0 +            txt='' +            @md.creator.digitized_by_detail.each do |h| +              txt=txt + %{#{h[:the]}, #{h[:others]}; } +            end +            txt=txt.gsub(/[;, ]+\s*$/,'') +            txt=special_character_escape(txt) +            ["#{name}, ","'#{txt}', "] +          else ['',''] +          end +        end +        self +      end +      def creator_audio +        def name +          'creator_audio' +        end +        def create_column +          "#{name}                VARCHAR(#{Db[:col_name]}) NULL," +        end +        def column_comment +          %{COMMENT ON COLUMN metadata_and_text.#{name} +           IS 'metadata document audio by name(s)';} +        end +        def tuple +          if defined? @md.creator.audio_detail \ +          and @md.creator.audio_detail.is_a?(Array) \ +          and @md.creator.audio_detail.length > 0 +            txt='' +            @md.creator.audio_detail.each do |h| +              txt=txt + %{#{h[:the]}, #{h[:others]}; } +            end +            txt=txt.gsub(/[;, ]+\s*$/,'') +            txt=special_character_escape(txt) +            ["#{name}, ","'#{txt}', "] +          else ['',''] +          end +        end +        self +      end +      def creator_video +        def name +          'creator_video' +        end +        def create_column +          "#{name}                VARCHAR(#{Db[:col_name]}) NULL," +        end +        def column_comment +          %{COMMENT ON COLUMN metadata_and_text.#{name} +           IS 'metadata document video by name(s)';} +        end +        def tuple +          if defined? @md.creator.video_detail \ +          and @md.creator.video_detail.is_a?(Array) \ +          and @md.creator.video_detail.length > 0 +            txt='' +            @md.creator.video_detail.each do |h| +              txt=txt + %{#{h[:the]}, #{h[:others]}; } +            end +            txt=txt.gsub(/[;, ]+\s*$/,'') +            txt=special_character_escape(txt) +            ["#{name}, ","'#{txt}', "] +          else ['',''] +          end +        end +        self +      end +=begin +#% language +#taken from other fields +@title: + :language: +@original: + :language: +#not available --> +#@language: +# :document: +# :original: +=end +      def language_document +        def name +          'language_document' +        end +        def create_column +          "#{name}                VARCHAR(#{Db[:col_language]}) NULL," +        end +        def column_comment +          %{COMMENT ON COLUMN metadata_and_text.#{name} +           IS 'metadata document language';} +        end +        def tuple +          if @lang.list[@md.opt.lng][:n] +            txt=@lang.list[@md.opt.lng][:n] +            txt=special_character_escape(txt) +            ["#{name}, ","'#{txt}', "] +          else ['',''] +          end +        end +        self +      end +      def language_document_char +        def name +          'language_document_char' +        end +        def create_column +          "#{name}                VARCHAR(#{Db[:col_language_char]}) NOT NULL," +        end +        def column_comment +          %{COMMENT ON COLUMN metadata_and_text.#{name} +           IS 'metadata document language';} +        end +        def tuple +          #modify check, is now required, SiSUv3d_ +          if defined? @md.opt.lng \ +          and @md.opt.lng=~/\S+/ +            txt=@md.opt.lng +            txt=special_character_escape(txt) +            ["#{name}, ","'#{txt}', "] +          else ['',''] +          end +        end +        self +      end +      def language_original +        def name +          'language_original' +        end +        def create_column +          "#{name}                VARCHAR(#{Db[:col_language]}) NULL," +        end +        def column_comment +          %{COMMENT ON COLUMN metadata_and_text.#{name} +           IS 'metadata original document/text language';} +        end +        def tuple +          if defined? @md.language.original \ +          and @md.language.original=~/\S+/ +            txt=@md.language.original +            txt=special_character_escape(txt) +            ["#{name}, ","'#{txt}', "] +          else ['',''] +          end +        end +        self +      end +      def language_original_char +        def name +          'language_original_char' +        end +        def create_column +          "#{name}                VARCHAR(#{Db[:col_language_char]}) NULL," +        end +        def column_comment +          %{COMMENT ON COLUMN metadata_and_text.#{name} +           IS 'metadata document language';} +        end +        def tuple +          if defined? @md.language.original_char \ +          and @md.language.original_char=~/\S+/ +            txt=@md.language.original_char +            txt=special_character_escape(txt) +            ["#{name}, ","'#{txt}', "] +          else ['',''] +          end +        end +        self +      end +=begin +#% date +@date: + :added_to_site: + :available: + :created: + :issued: + :modified: + :published: + :valid: + :translated: + :original_publication: +=end +      def date_added_to_site +        def name +          'date_added_to_site' +        end +        def create_column +          "#{name}                VARCHAR(#{Db[:col_date_text]}) NULL," +          #"#{name}                DATE," +        end +        def column_comment +          %{COMMENT ON COLUMN metadata_and_text.#{name} +           IS 'metadata date added to site';} +        end +        def tuple +          if defined? @md.date.added_to_site \ +          and @md.date.added_to_site=~/\S+/ +            txt=@md.date.added_to_site +            txt=special_character_escape(txt) +            ["#{name}, ","'#{txt}', "] +          else ['',''] +          end +        end +        self +      end +      def date_available +        def name +          'date_available' +        end +        def create_column +          "#{name}                VARCHAR(#{Db[:col_date_text]}) NULL," +        end +        def column_comment +          %{COMMENT ON COLUMN metadata_and_text.#{name} +           IS 'metadata date added to site [DC]';} +        end +        def tuple +          if defined? @md.date.available \ +          and @md.date.available=~/\S+/ +            txt=@md.date.available +            txt=special_character_escape(txt) +            ["#{name}, ","'#{txt}', "] +          else ['',''] +          end +        end +        self +      end +      def date_created +        def name +          'date_created' +        end +        def create_column +          "#{name}                VARCHAR(#{Db[:col_date_text]}) NULL," +        end +        def column_comment +          %{COMMENT ON COLUMN metadata_and_text.#{name} +           IS 'metadata date created [DC]';} +        end +        def tuple +          if defined? @md.date.created \ +          and @md.date.created=~/\S+/ +            txt=@md.date.created +            txt=special_character_escape(txt) +            ["#{name}, ","'#{txt}', "] +          else ['',''] +          end +        end +        self +      end +      def date_issued +        def name +          'date_issued' +        end +        def create_column +          "#{name}                VARCHAR(#{Db[:col_date_text]}) NULL," +        end +        def column_comment +          %{COMMENT ON COLUMN metadata_and_text.#{name} +           IS 'metadata date issued [DC]';} +        end +        def tuple +          if defined? @md.date.issued \ +          and @md.date.issued=~/\S+/ +            txt=@md.date.issued +            txt=special_character_escape(txt) +            ["#{name}, ","'#{txt}', "] +          else ['',''] +          end +        end +        self +      end +      def date_modified +        def name +          'date_modified' +        end +        def create_column +          "#{name}                VARCHAR(#{Db[:col_date_text]}) NULL," +        end +        def column_comment +          %{COMMENT ON COLUMN metadata_and_text.#{name} +           IS 'metadata date modified [DC]';} +        end +        def tuple +          if defined? @md.date.modified \ +          and @md.date.modified=~/\S+/ +            txt=@md.date.modified +            txt=special_character_escape(txt) +            ["#{name}, ","'#{txt}', "] +          else ['',''] +          end +        end +        self +      end +      def date_published +        def name +          'date_published' +        end +        def create_column +          "#{name}                VARCHAR(#{Db[:col_date_text]}) NULL," +        end +        def column_comment +          %{COMMENT ON COLUMN metadata_and_text.#{name} +           IS 'metadata date published [DC7]';} +        end +        def tuple +          if defined? @md.date.published \ +          and @md.date.published=~/\S+/ +            txt=@md.date.published +            txt=special_character_escape(txt) +            ["#{name}, ","'#{txt}', "] +          else ['',''] +          end +        end +        self +      end +      def date_valid +        def name +          'date_valid' +        end +        def create_column +          "#{name}                VARCHAR(#{Db[:col_date_text]}) NULL," +        end +        def column_comment +          %{COMMENT ON COLUMN metadata_and_text.#{name} +           IS 'metadata date valid [DC]';} +        end +        def tuple +          if defined? @md.date.valid \ +          and @md.date.valid=~/\S+/ +            txt=@md.date.valid +            txt=special_character_escape(txt) +            ["#{name}, ","'#{txt}', "] +          else ['',''] +          end +        end +        self +      end +      def date_translated +        def name +          'date_translated' +        end +        def create_column +          "#{name}                VARCHAR(#{Db[:col_date_text]}) NULL," +        end +        def column_comment +          %{COMMENT ON COLUMN metadata_and_text.#{name} +           IS 'metadata date translated';} +        end +        def tuple +          if defined? @md.date.translated \ +          and @md.date.translated=~/\S+/ +            txt=@md.date.translated +            txt=special_character_escape(txt) +            ["#{name}, ","'#{txt}', "] +          else ['',''] +          end +        end +        self +      end +      def date_original_publication +        def name +          'date_original_publication' +        end +        def create_column +          "#{name}                VARCHAR(#{Db[:col_date_text]}) NULL," +        end +        def column_comment +          %{COMMENT ON COLUMN metadata_and_text.#{name} +           IS 'metadata date of original publication';} +        end +        def tuple +          if defined? @md.date.original_publication \ +          and @md.date.original_publication=~/\S+/ +            txt=@md.date.original_publication +            txt=special_character_escape(txt) +            ["#{name}, ","'#{txt}', "] +          else ['',''] +          end +        end +        self +      end +      def date_generated +        def name +          'date_generated' +        end +        def create_column              #choose other representation of time +          "#{name}                VARCHAR(30) NULL," +          #"#{name}                VARCHAR(10) NULL," +        end +        def column_comment +          %{COMMENT ON COLUMN metadata_and_text.#{name} +           IS 'metadata date of sisu generation of document, automatically populated';} +        end +        def tuple                      #choose other representation of time +          if defined? @md.generated \ +          and @md.generated.to_s=~/\S+/ +            txt=@md.generated.to_s +            txt=special_character_escape(txt) +            ["#{name}, ","'#{txt}', "] +          else ['',''] +          end +        end +        self +      end +=begin +#% publisher +@publisher: +=end +      def publisher +        def name +          'publisher' +        end +        def create_column +          "#{name}                VARCHAR(#{Db[:col_name]}) NULL," +        end +        def column_comment +          %{COMMENT ON COLUMN metadata_and_text.#{name} +           IS 'metadata document publisher [DC5]';} +        end +        def tuple +          if defined? @md.publisher \ +          and @md.publisher=~/\S+/ +            txt=@md.publisher +            txt=special_character_escape(txt) +            ["#{name}, ","'#{txt}', "] +          else ['',''] +          end +        end +        self +      end +##% current +#    def current_publisher +#      def name +#        'current_publisher' +#      end +#      def size +#        10 +#      end +#      def create_column +#        "#{name}                VARCHAR(#{current_publisher.size}) NULL," +#      end +#      def tuple +#        t=if defined? @md.current.publisher \ +#        and @md.current.publisher=~/\S+/ +#          txt=@md.current.publisher +#          txt=special_character_escape(txt) +#          "'#{txt}', " +#        end +#      end +#      self +#    end +=begin +#% original +@original: + :publisher: + #:date:                                #repeated under date + :language: + :institution: + :nationality: + :source: +=end +      def original_publisher +        def name +          'original_publisher' +        end +        def create_column +          "#{name}                VARCHAR(#{Db[:col_name]}) NULL," +        end +        def column_comment +          %{COMMENT ON COLUMN metadata_and_text.#{name} +           IS 'metadata document original publisher [DC5]';} +        end +        def tuple +          if defined? @md.original.publisher \ +          and @md.original.publisher=~/\S+/ +            txt=@md.original.publisher +            txt=special_character_escape(txt) +            ["#{name}, ","'#{txt}', "] +          else ['',''] +          end +        end +        self +      end +      def original_language +        def name +          'original_language' +        end +        def create_column +          "#{name}                VARCHAR(#{Db[:col_language]}) NULL," +        end +        def column_comment +          %{COMMENT ON COLUMN metadata_and_text.#{name} +           IS 'metadata document original language';} +        end +        def tuple +          if defined? @md.original.language \ +          and @md.original.language=~/\S+/ +            txt=@md.original.language +            txt=special_character_escape(txt) +            ["#{name}, ","'#{txt}', "] +          else ['',''] +          end +        end +        self +      end +      def original_language_char         # consider +        def name +          'original_language_char' +        end +        def create_column +          "#{name}                VARCHAR(#{Db[:col_language_char]}) NULL," +        end +        def column_comment +          %{COMMENT ON COLUMN metadata_and_text.#{name} +           IS 'metadata document original language iso character';} +        end +        def tuple +          if defined? @md.original.language_char \ +          and @md.original.language_char=~/\S+/ +            txt=@md.original.language_char +            txt=special_character_escape(txt) +            ["#{name}, ","'#{txt}', "] +          else ['',''] +          end +        end +        self +      end +      def original_source +        def name +          'original_source' +        end +        def create_column +          "#{name}                VARCHAR(#{Db[:col_name]}) NULL," +        end +        def column_comment +          %{COMMENT ON COLUMN metadata_and_text.#{name} +           IS 'metadata document original source [DC11]';} +        end +        def tuple +          if defined? @md.original.source \ +          and @md.original.source=~/\S+/ +            txt=@md.original.source +            txt=special_character_escape(txt) +            ["#{name}, ","'#{txt}', "] +          else ['',''] +          end +        end +        self +      end +      def original_institution +        def name +          'original_institution' +        end +        def create_column +          "#{name}                VARCHAR(#{Db[:col_name]}) NULL," +        end +        def column_comment +          %{COMMENT ON COLUMN metadata_and_text.#{name} +           IS 'metadata document original institution';} +        end +        def tuple +          if defined? @md.original.institution \ +          and @md.original.institution=~/\S+/ +            txt=@md.original.institution +            txt=special_character_escape(txt) +            ["#{name}, ","'#{txt}', "] +          else ['',''] +          end +        end +        self +      end +      def original_nationality +        def name +          'original_nationality' +        end +        def create_column +          "#{name}                VARCHAR(#{Db[:col_language]}) NULL," +        end +        def column_comment +          %{COMMENT ON COLUMN metadata_and_text.#{name} +           IS 'metadata document original nationality';} +        end +        def tuple +          if defined? @md.original.nationality \ +          and @md.original.nationality=~/\S+/ +            txt=@md.original.nationality +            txt=special_character_escape(txt) +            ["#{name}, ","'#{txt}', "] +          else ['',''] +          end +        end +        self +      end +=begin +#% rights +@rights: + #:copyright:                          #mapped to :text: used where no other copyrights and included in :all: + :text: + :translation: + :illustrations: + :photographs: + :preparation: + :digitization: + :audio: + :video: + :license: + :all: +=end +      def rights_all +        def name +          'rights' +        end +        def create_column +          "#{name}                VARCHAR(#{Db[:col_info_note]}) NULL," +        end +        def column_comment +          %{COMMENT ON COLUMN metadata_and_text.#{name} +           IS 'metadata rights associated with document (composite) [DC15]';} +        end +        def tuple +          if defined? @md.rights.all \ +          and @md.rights.all=~/\S+/ +            txt=@md.rights.all +            txt=special_character_escape(txt) +            ["#{name}, ","'#{txt}', "] +          else ['',''] +          end +        end +        self +      end +      def rights_copyright_text +        def name +          'rights_copyright_text' +        end +        def create_column +          "#{name}                VARCHAR(#{Db[:col_info_note]}) NULL," +        end +        def column_comment +          %{COMMENT ON COLUMN metadata_and_text.#{name} +           IS 'metadata copyright associated for document text';} +        end +        def tuple +          if defined? @md.rights.copyright_text \ +          and @md.rights.copyright_text=~/\S+/ +            txt=@md.rights.copyright_text +            txt=special_character_escape(txt) +            ["#{name}, ","'#{txt}', "] +          else ['',''] +          end +        end +        self +      end +      def rights_copyright_translation +        def name +          'rights_copyright_translation' +        end +        def create_column +          "#{name}                VARCHAR(#{Db[:col_info_note]}) NULL," +        end +        def column_comment +          %{COMMENT ON COLUMN metadata_and_text.#{name} +           IS 'metadata copyright associated for document text translation (if any)';} +        end +        def tuple +          if defined? @md.rights.copyright_translation \ +          and @md.rights.copyright_translation=~/\S+/ +            txt=@md.rights.copyright_translation +            txt=special_character_escape(txt) +            ["#{name}, ","'#{txt}', "] +          else ['',''] +          end +        end +        self +      end +      def rights_copyright_illustrations +        def name +          'rights_copyright_illustrations' +        end +        def create_column +          "#{name}                VARCHAR(#{Db[:col_info_note]}) NULL," +        end +        def column_comment +          %{COMMENT ON COLUMN metadata_and_text.#{name} +           IS 'metadata copyright associated for document text illustrations (if any)';} +        end +        def tuple +          if defined? @md.rights.copyright_illustrations \ +          and @md.rights.copyright_illustrations=~/\S+/ +            txt=@md.rights.copyright_illustrations +            txt=special_character_escape(txt) +            ["#{name}, ","'#{txt}', "] +          else ['',''] +          end +        end +        self +      end +      def rights_copyright_photographs +        def name +          'rights_copyright_photographs' +        end +        def create_column +          "#{name}                VARCHAR(#{Db[:col_info_note]}) NULL," +        end +        def column_comment +          %{COMMENT ON COLUMN metadata_and_text.#{name} +           IS 'metadata copyright associated for document text photographs (if any)';} +        end +        def tuple +          if defined? @md.rights.copyright_photographs \ +          and @md.rights.copyright_photographs=~/\S+/ +            txt=@md.rights.copyright_photographs +            txt=special_character_escape(txt) +            ["#{name}, ","'#{txt}', "] +          else ['',''] +          end +        end +        self +      end +      def rights_copyright_preparation +        def name +          'rights_copyright_preparation' +        end +        def create_column +          "#{name}                VARCHAR(#{Db[:col_info_note]}) NULL," +        end +        def column_comment +          %{COMMENT ON COLUMN metadata_and_text.#{name} +           IS 'metadata copyright associated for document text preparation (if any)';} +        end +        def tuple +          if defined? @md.rights.copyright_preparation \ +          and @md.rights.copyright_preparation=~/\S+/ +            txt=@md.rights.copyright_preparation +            txt=special_character_escape(txt) +            ["#{name}, ","'#{txt}', "] +          else ['',''] +          end +        end +        self +      end +      def rights_copyright_digitization +        def name +          'rights_copyright_digitization' +        end +        def create_column +          "#{name}                VARCHAR(#{Db[:col_info_note]}) NULL," +        end +        def column_comment +          %{COMMENT ON COLUMN metadata_and_text.#{name} +           IS 'metadata copyright associated for document text digitization (if any)';} +        end +        def tuple +          if defined? @md.rights.copyright_digitization \ +          and @md.rights.copyright_digitization=~/\S+/ +            txt=@md.rights.copyright_digitization +            txt=special_character_escape(txt) +            ["#{name}, ","'#{txt}', "] +          else ['',''] +          end +        end +        self +      end +      def rights_copyright_audio +        def name +          'rights_copyright_audio' +        end +        def create_column +          "#{name}                VARCHAR(#{Db[:col_info_note]}) NULL," +        end +        def column_comment +          %{COMMENT ON COLUMN metadata_and_text.#{name} +           IS 'metadata copyright associated for document text audio (if any)';} +        end +        def tuple +          if defined? @md.rights.copyright_audio \ +          and @md.rights.copyright_audio=~/\S+/ +            txt=@md.rights.copyright_audio +            txt=special_character_escape(txt) +            ["#{name}, ","'#{txt}', "] +          else ['',''] +          end +        end +        self +      end +      def rights_copyright_video +        def name +          'rights_copyright_video' +        end +        def create_column +          "#{name}                VARCHAR(#{Db[:col_info_note]}) NULL," +        end +        def column_comment +          %{COMMENT ON COLUMN metadata_and_text.#{name} +           IS 'metadata copyright associated for document text video (if any)';} +        end +        def tuple +          if defined? @md.rights.copyright_video \ +          and @md.rights.copyright_video=~/\S+/ +            txt=@md.rights.copyright_video +            txt=special_character_escape(txt) +            ["#{name}, ","'#{txt}', "] +          else ['',''] +          end +        end +        self +      end +      def rights_license +        def name +          'rights_license' +        end +        def create_column +          "#{name}                VARCHAR(#{Db[:col_info_note]}) NULL," +        end +        def column_comment +          %{COMMENT ON COLUMN metadata_and_text.#{name} +           IS 'metadata license granted for use of document if any)';} +        end +        def tuple +          if defined? @md.rights.license \ +          and @md.rights.license=~/\S+/ +            txt=@md.rights.license +            txt=special_character_escape(txt) +            ["#{name}, ","'#{txt}', "] +          else ['',''] +          end +        end +        self +      end +=begin +#% identifier +@identifier: + :oclc: + :isbn: +=end +      def identifier_oclc +        def name +          'identifier_oclc' +        end +        def create_column +          "#{name}                VARCHAR(#{Db[:col_library]}) NULL," +        end +        def column_comment +          %{COMMENT ON COLUMN metadata_and_text.#{name} +           IS 'metadata identifier document Online Computer Library Center number';} +        end +        def tuple +          if defined? @md.identifier.oclc \ +          and @md.identifier.oclc=~/\S+/ +            txt=@md.identifier.oclc +            txt=special_character_escape(txt) +            ["#{name}, ","'#{txt}', "] +          else ['',''] +          end +        end +        self +      end +      def identifier_isbn +        def name +          'identifier_isbn' +        end +        def create_column +          "#{name}                VARCHAR(#{Db[:col_small]}) NULL," +        end +        def column_comment +          %{COMMENT ON COLUMN metadata_and_text.#{name} +           IS 'metadata identifier document isbn (if any)';} +        end +        def tuple +          if defined? @md.identifier.isbn \ +          and @md.identifier.isbn=~/\S+/ +            txt=@md.identifier.isbn +            txt=special_character_escape(txt) +            ["#{name}, ","'#{txt}', "] +          else ['',''] +          end +        end +        self +      end +=begin +#% classify +@classify: + :topic_register: + :subject: + :keywords: + :type: + :loc: + :dewey: +=end +      def classify_topic_register +        def name +          'classify_topic_register' +        end +        def create_column +          "#{name}                VARCHAR(#{Db[:col_info_note]}) NULL," +        end +        def column_comment +          %{COMMENT ON COLUMN metadata_and_text.#{name} +           IS 'metadata classify document topic register (semi-structured document subject information)';} +        end +        def tuple +          if defined? @md.classify.topic_register \ +          and @md.classify.topic_register=~/\S+/ +            txt=@md.classify.topic_register +            txt=special_character_escape(txt) +            ["#{name}, ","'#{txt}', "] +          else ['',''] +          end +        end +        self +      end +      def classify_subject +        def name +          'classify_subject' +        end +        def create_column +          "#{name}                VARCHAR(#{Db[:col_txt_long]}) NULL," +        end +        def column_comment +          %{COMMENT ON COLUMN metadata_and_text.#{name} +           IS 'metadata classify document subject matter [DC3]';} +        end +        def tuple +          if defined? @md.classify.subject \ +          and @md.classify.subject=~/\S+/ +            txt=@md.classify.subject +            txt=special_character_escape(txt) +            ["#{name}, ","'#{txt}', "] +          else ['',''] +          end +        end +        self +      end +      def classify_loc +        def name +          'classify_loc' +        end +        def create_column +          "#{name}                VARCHAR(#{Db[:col_library]}) NULL," +        end +        def column_comment +          %{COMMENT ON COLUMN metadata_and_text.#{name} +           IS 'metadata classify document Library of Congress';} +        end +        def tuple +          if defined? @md.classify.loc \ +          and @md.classify.loc=~/\S+/ +            txt=@md.classify.loc +            txt=special_character_escape(txt) +            ["#{name}, ","'#{txt}', "] +          else ['',''] +          end +        end +        self +      end +      def classify_dewey +        def name +          'classify_dewey' +        end +        def create_column +          "#{name}                VARCHAR(#{Db[:col_library]}) NULL," +        end +        def column_comment +          %{COMMENT ON COLUMN metadata_and_text.#{name} +           IS 'metadata classify document Dewey';} +        end +        def tuple +          if defined? @md.classify.dewey \ +          and @md.classify.dewey=~/\S+/ +            txt=@md.classify.dewey +            txt=special_character_escape(txt) +            ["#{name}, ","'#{txt}', "] +          else ['',''] +          end +        end +        self +      end +      def classify_keywords +        def name +          'classify_keywords' +        end +        def create_column +          "#{name}                VARCHAR(#{Db[:col_txt_long]}) NULL," +        end +        def column_comment +          %{COMMENT ON COLUMN metadata_and_text.#{name} +           IS 'metadata classify document keywords';} +        end +        def tuple +          if defined? @md.classify.keywords \ +          and @md.classify.keywords=~/\S+/ +            txt=@md.classify.keywords +            txt=special_character_escape(txt) +            ["#{name}, ","'#{txt}', "] +          else ['',''] +          end +        end +        self +      end +=begin +#% notes +@notes: + :abstract: + :description: + :comment: + :coverage: + :relation: + :format: + :history: + :prefix: + :prefix_a: + :prefix_b: + :suffix: +=end +      def notes_abstract +        def name +          'notes_abstract' +        end +        def create_column +          "#{name}                     TEXT NULL," +        end +        def column_comment +          %{COMMENT ON COLUMN metadata_and_text.#{name} +           IS 'metadata document notes abstract';} +        end +        def tuple +          if defined? @md.notes.abstract \ +          and @md.notes.abstract=~/\S+/ +            txt=@md.notes.abstract +            txt=special_character_escape(txt) +            ["#{name}, ","'#{txt}', "] +          else ['',''] +          end +        end +        self +      end +      def notes_description +        def name +          'notes_description' +        end +        def create_column +          "#{name}                    TEXT NULL," +        end +        def column_comment +          %{COMMENT ON COLUMN metadata_and_text.#{name} +           IS 'metadata document notes description [DC4]';} +        end +        def tuple +          if defined? @md.notes.description \ +          and @md.notes.description=~/\S+/ +            txt=@md.notes.description +            txt=special_character_escape(txt) +            ["#{name}, ","'#{txt}', "] +          else ['',''] +          end +        end +        self +      end +      def notes_comment +        def name +          'notes_comment' +        end +        def create_column +          "#{name}                       TEXT NULL," +        end +        def column_comment +          %{COMMENT ON COLUMN metadata_and_text.#{name} +           IS 'metadata document notes comment';} +        end +        def tuple +          if defined? @md.notes.comment \ +          and @md.notes.comment=~/\S+/ +            txt=@md.notes.comment +            txt=special_character_escape(txt) +            ["#{name}, ","'#{txt}', "] +          else ['',''] +          end +        end +        self +      end +      def notes_coverage +        def name +          'notes_coverage' +        end +        def create_column +          "#{name}                VARCHAR(#{Db[:col_txt_short]}) NULL," +        end +        def column_comment +          %{COMMENT ON COLUMN metadata_and_text.#{name} +           IS 'metadata classify document coverage [DC14]';} +        end +        def tuple +          if defined? @md.classify.coverage \ +          and @md.classify.coverage=~/\S+/ +            txt=@md.classify.coverage +            txt=special_character_escape(txt) +            ["#{name}, ","'#{txt}', "] +          else ['',''] +          end +        end +        self +      end +      def notes_relation +        def name +          'notes_relation' +        end +        def create_column +          "#{name}                VARCHAR(#{Db[:col_txt_short]}) NULL," +        end +        def column_comment +          %{COMMENT ON COLUMN metadata_and_text.#{name} +           IS 'metadata classify document relation [DC13]';} +        end +        def tuple +          if defined? @md.classify.relation \ +          and @md.classify.relation=~/\S+/ +            txt=@md.classify.relation +            txt=special_character_escape(txt) +            ["#{name}, ","'#{txt}', "] +          else ['',''] +          end +        end +        self +      end +      def notes_history   #check, consider removal +        def name +          'notes_history' +        end +        def create_column +          "#{name}                VARCHAR(#{Db[:col_txt_long]}) NULL," +        end +        def column_comment +          %{COMMENT ON COLUMN metadata_and_text.#{name} +           IS 'metadata document notes history';} +        end +        def tuple +          if defined? @md.notes.history \ +          and @md.notes.history=~/\S+/ +            txt=@md.notes.history +            txt=special_character_escape(txt) +            ["#{name}, ","'#{txt}', "] +          else ['',''] +          end +        end +        self +      end +      def notes_type #check +        def name +          'notes_type' +        end +        def create_column +          "#{name}                VARCHAR(#{Db[:col_txt_long]}) NULL," +        end +        def column_comment +          %{COMMENT ON COLUMN metadata_and_text.#{name} +           IS 'metadata notes document type [DC8]';} +        end +        def tuple +          if defined? @md.notes.type \ +          and @md.notes.type=~/\S+/ +            txt=@md.notes.type +            txt=special_character_escape(txt) +            ["#{name}, ","'#{txt}', "] +          else ['',''] +          end +        end +        self +      end +      def notes_format +        def name +          'notes_format' +        end +        def create_column +          "#{name}                VARCHAR(#{Db[:col_txt_long]}) NULL," +        end +        def column_comment +          %{COMMENT ON COLUMN metadata_and_text.#{name} +           IS 'metadata classify document format [DC9]';} +        end +        def tuple +          if defined? @md.classify.format \ +          and @md.classify.format=~/\S+/ +            txt=@md.classify.format +            txt=special_character_escape(txt) +            ["#{name}, ","'#{txt}', "] +          else ['',''] +          end +        end +        self +      end +      def notes_prefix +        def name +          'notes_prefix' +        end +        def create_column +          "#{name}                TEXT NULL," +        end +        def column_comment +          %{COMMENT ON COLUMN metadata_and_text.#{name} +           IS 'metadata document notes prefix';} +        end +        def tuple +          if defined? @md.notes.prefix \ +          and @md.notes.prefix=~/\S+/ +            txt=@md.notes.prefix +            txt=special_character_escape(txt) +            ["#{name}, ","'#{txt}', "] +          else ['',''] +          end +        end +        self +      end +      def notes_prefix_a +        def name +          'notes_prefix_a' +        end +        def create_column +          "#{name}                TEXT NULL," +        end +        def column_comment +          %{COMMENT ON COLUMN metadata_and_text.#{name} +           IS 'metadata document notes prefix_a';} +        end +        def tuple +          if defined? @md.notes.prefix_a \ +          and @md.notes.prefix_a=~/\S+/ +            txt=@md.notes.prefix_a +            txt=special_character_escape(txt) +            ["#{name}, ","'#{txt}', "] +          else ['',''] +          end +        end +        self +      end +      def notes_prefix_b +        def name +          'notes_prefix_b' +        end +        def create_column +          "#{name}                TEXT NULL," +        end +        def column_comment +          %{COMMENT ON COLUMN metadata_and_text.#{name} +           IS 'metadata document notes prefix_b';} +        end +        def tuple +          if defined? @md.notes.prefix_b \ +          and @md.notes.prefix_b=~/\S+/ +            txt=@md.notes.prefix_b +            txt=special_character_escape(txt) +            ["#{name}, ","'#{txt}', "] +          else ['',''] +          end +        end +        self +      end +      def notes_suffix +        def name +          'notes_suffix' +        end +        def create_column                # keep text +          "#{name}                TEXT NULL," +        end +        def column_comment +          %{COMMENT ON COLUMN metadata_and_text.#{name} +           IS 'metadata document notes suffix';} +        end +        def tuple +          if defined? @md.notes.suffix \ +          and @md.notes.suffix=~/\S+/ +            txt=@md.notes.suffix +            txt=special_character_escape(txt) +            ["#{name}, ","'#{txt}', "] +          else ['',''] +          end +        end +        self +      end +=begin +#% src +=end +      def src_filename +        def name +          'src_filename' +        end +        def create_column +          "#{name}                VARCHAR(#{Db[:col_filename]}) NOT NULL," +        end +        def column_comment +          %{COMMENT ON COLUMN metadata_and_text.#{name} +           IS 'sisu markup source text filename';} +        end +        def tuple +          if defined? @md.fns \ +          and @md.fns=~/\S+/ +            txt=@md.fns +            txt=special_character_escape(txt) +            ["#{name}, ","'#{txt}', "] +          else ['',''] +          end +        end +        self +      end +      def src_fingerprint +        def name +          'src_fingerprint' #hash/digest, sha512, sha256 or md5 +        end +        def create_column +          "#{name}                VARCHAR(#{Db[:col_digest]}) NULL," +          #"#{name}                TEXT NULL," +        end +        def column_comment +          %{COMMENT ON COLUMN metadata_and_text.#{name} +            IS 'sisu markup source text fingerprint, hash digest sha512, sha256 or md5';} +        end +        def tuple +          if defined? @md.dgst \ +          and @md.dgst.is_a?(Array) \ +          and @md.dgst[1]=~/\S+/ +            txt=@md.dgst[1] +            ["#{name}, ","'#{txt}', "] +          else ['',''] +          end +        end +        self +      end +      def src_filesize +        def name +          'src_filesize' +        end +        def create_column +          "#{name}                VARCHAR(#{Db[:col_filesize]}) NULL," +        end +        def column_comment +          %{COMMENT ON COLUMN metadata_and_text.#{name} +            IS 'sisu markup source text file size';} +        end +        def tuple +         if defined? @md.filesize \ +         and @md.filesize=~/\S+/ +           txt=@md.filesize +           txt=special_character_escape(txt) +           ["#{name}, ","'#{txt}', "] +         else ['',''] +         end +        end +        self +      end +      def src_word_count +        def name +          'src_word_count' +        end +        def create_column +          "#{name}                TEXT NULL," +        end +        def column_comment +          %{COMMENT ON COLUMN metadata_and_text.#{name} +            IS 'sisu markup source text word count';} +        end +        def tuple +          if defined? @md.wc_words \ +          and @md.wc_words.to_s=~/\S+/ +            txt=@md.wc_words +            txt=special_character_escape(txt) +            ["#{name}, ","'#{txt}', "] +          else ['',''] +          end +        end +        self +      end +      def src_txt                      # consider naming sisusrc +        def name +          'src_text' +        end +        def create_column +          "#{name}                TEXT NULL," +        end +        def column_comment +          %{COMMENT ON COLUMN metadata_and_text.#{name} +           IS 'sisu markup source text (if shared)';} +        end +        def tuple +          if ((@md.opt.act[:psql_import][:set]==:on \ +          || @md.opt.act[:psql_update][:set]==:on) \ +          or (@md.opt.act[:sqlite_import][:set]==:on \ +          || @md.opt.act[:sqlite_update][:set]==:on)) \ +          and FileTest.exist?(@md.fns) +            ["#{name}, ","'#{@sisutxt}', "] +          else ['',''] +          end +        end +        self +      end +=begin +#% misc +@links: +=end +      def fulltext +        def name +          'fulltext' +        end +        def create_column +          "#{name}                TEXT NULL," +        end +        def column_comment +          %{COMMENT ON COLUMN metadata_and_text.#{name} +            IS 'document full text clean, searchable';} +        end +        def tuple +          if ((@md.opt.act[:psql_import][:set]==:on \ +          || @md.opt.act[:psql_update][:set]==:on) \ +          or (@md.opt.act[:sqlite_import][:set]==:on \ +          || @md.opt.act[:sqlite_update][:set]==:on)) \ +          and  FileTest.exist?(@md.fns) +            ["#{name}, ","'#{@fulltext}', "] +          else ['',''] +          end +        end +        self +      end +      def links +        def name +          'links' +        end +        def create_column +          "#{name}                TEXT NULL," +          #"#{name}                 VARCHAR(#{links.size}) NULL," +        end +        def column_comment +          %{COMMENT ON COLUMN metadata_and_text.#{name} +           IS 'metadata document links';} +        end +        #def tuple +        #  #BUG HERE - links is an array of paired values :say :url +        #  if defined? @md.links \ +        #  and @md.links=~/\S+/ +        #    txt=@md.links +        #    txt=special_character_escape(txt) +        #    ["#{name}, ","'#{txt}', "] +        #  else ['',''] +        #  end +        #end +        self +      end +      self +    end +  end +  class ColumnSize +    def document_clean # restriction not necessary +      60000 +    end +    def document_body +      16000 +    end +    def document_seg +      120 +    end +    def document_seg_full +      120 +    end +    def endnote_clean # restriction not necessary +      60000 +    end +    def endnote_body +      16000 +    end +  end +end +__END__ +#+END_SRC + +** db_indexes.rb + +#+BEGIN_SRC ruby  :tangle "../lib/sisu/db_indexes.rb" +# <<sisu_document_header>> +module SiSU_DbIndex +  class Index                                           # create documents Indexes def initialize(opt,conn='',sql_type) +    def initialize(opt,conn,file,sql_type) +      @opt,@conn,@file,@sql_type=opt,conn,file,sql_type +    end +    def create_indexes                                                           # check added from pg not tested +      def conn_execute_sql_pg(conn,sql) +        conn.exec_params(sql) +      end +      def conn_execute_sql_sqlite(conn,sql) +        conn.execute(sql) +      end +      def conn_execute_sql(conn,sql) +        if @sql_type==:pg +          conn_execute_sql_pg(conn,sql) +        elsif @sql_type==:sqlite +          conn_execute_sql_sqlite(conn,sql) +        else +        end +      end +      def conn_execute_array(sql_arr) +        begin +          @conn.transaction do |conn| +            sql_arr.each do |sql| +              conn_execute_sql(conn,sql) +            end +          end +        rescue +          if @conn.is_a?(NilClass) +            errmsg="No sqlite3 connection (check sqlite3 dependencies)" +            if @opt.act[:no_stop][:set]==:on +              SiSU_Utils::CodeMarker.new(__LINE__,__FILE__,:fuchsia). +                error("#{errmsg}, proceeding without sqlite output (as requested)") +            else +              SiSU_Utils::CodeMarker.new(__LINE__,__FILE__,:fuchsia). +                error("#{errmsg}, STOPPING") +              exit +            end +          end +        end +      end +      def base +        if (@opt.act[:verbose_plus][:set]==:on \ +        || @opt.act[:maintenance][:set]==:on) +          print "\n          create documents common indexes\n" +        end +        sql_arr=[ +          %{CREATE INDEX idx_ocn ON doc_objects(ocn);}, +          %{CREATE INDEX idx_digest_clean ON doc_objects(digest_clean);}, +          %{CREATE INDEX idx_digest_all ON doc_objects(digest_all);}, +          %{CREATE INDEX idx_lev0 ON doc_objects(lev0);}, +          %{CREATE INDEX idx_lev1 ON doc_objects(lev1);}, +          %{CREATE INDEX idx_lev2 ON doc_objects(lev2);}, +          %{CREATE INDEX idx_lev3 ON doc_objects(lev3);}, +          %{CREATE INDEX idx_lev4 ON doc_objects(lev4);}, +          %{CREATE INDEX idx_lev5 ON doc_objects(lev5);}, +          %{CREATE INDEX idx_lev6 ON doc_objects(lev6);}, +          %{CREATE INDEX idx_endnote_nr ON endnotes(nr);}, +          %{CREATE INDEX idx_digest_en ON endnotes(digest_clean);}, +          %{CREATE INDEX idx_endnote_nr_asterisk ON endnotes_asterisk(nr);}, +          %{CREATE INDEX idx_endnote_asterisk ON endnotes_asterisk(clean);}, +          %{CREATE INDEX idx_digest_en_asterisk ON endnotes_asterisk(digest_clean);}, +          %{CREATE INDEX idx_endnote_nr_plus ON endnotes_plus(nr);}, +          %{CREATE INDEX idx_endnote_plus ON endnotes_plus(clean);}, +          %{CREATE INDEX idx_digest_en_plus ON endnotes_plus(digest_clean);}, +          %{CREATE INDEX idx_title ON metadata_and_text(title);}, +          %{CREATE INDEX idx_author ON metadata_and_text(creator_author);}, +          %{CREATE INDEX idx_filename ON metadata_and_text(src_filename);}, +          %{CREATE INDEX idx_language ON metadata_and_text(language_document_char);}, +          %{CREATE INDEX idx_topics ON metadata_and_text(classify_topic_register)}, +        ] +        conn_execute_array(sql_arr) +      end +      def text +        if (@opt.act[:verbose_plus][:set]==:on \ +        || @opt.act[:maintenance][:set]==:on) +          print "\n          create documents TEXT indexes\n" +        end +        sql_arr=[ +          %{CREATE INDEX idx_clean ON doc_objects(clean);}, +          %{CREATE INDEX idx_endnote ON endnotes(clean);} +        ] +        conn_execute_array(sql_arr) +      end +      base +      @opt.act[:psql][:set]==:on ? '' : text +    end +  end +end +__END__ +#+END_SRC + +* db_tests.rb + +#+BEGIN_SRC ruby  :tangle "../lib/sisu/db_tests.rb" +# <<sisu_document_header>> +module SiSU_DbTests +  class Test +    def initialize(info,opt) +      @ck,@opt=info,opt +      unless @opt.act[:quiet][:set]==:on +        puts @ck.tp[:fns]  if @ck.tp[:fns] and not @ck.tp[:fns].empty? +        puts @ck.tp[:title] if @ck.tp[:title] and not @ck.tp[:title].empty? +        puts @ck.tp[:creator] if @ck.tp[:creator] and not @ck.tp[:creator].empty? +      end +    end +    def verify +      unless @opt.act[:quiet][:set]==:on +        puts @ck.tp[:fns].length.to_s                + ' checklength ' + @ck.tp[:fns]                if @ck.tp[:fns]                and @ck.tp[:fns].length                >@ck.lt_filename +        puts @ck.tp[:title].length.to_s              + ' checklength ' + @ck.tp[:title]              if @ck.tp[:title]              and @ck.tp[:title].length              >@ck.lt_title +        puts @ck.tp[:subtitle].length.to_s           + ' checklength ' + @ck.tp[:subtitle]           if @ck.tp[:subtitle]           and @ck.tp[:subtitle].length           >@ck.lt_subtitle +        puts @ck.tp[:creator].length.to_s            + ' checklength ' + @ck.tp[:creator]            if @ck.tp[:creator]            and @ck.tp[:creator].length            >@ck.lt_creator +        puts @ck.tp[:author_title].length.to_s       + ' checklength ' + @ck.tp[:author_title]       if @ck.tp[:author_title]       and @ck.tp[:author_title].length       >@ck.lt_author_title +        puts @ck.tp[:illustrator].length.to_s        + ' checklength ' + @ck.tp[:illustrator]        if @ck.tp[:illustrator]        and @ck.tp[:illustrator].length        >@ck.lt_illustrator +        puts @ck.tp[:translator].length.to_s         + ' checklength ' + @ck.tp[:translator]         if @ck.tp[:translator]         and @ck.tp[:translator].length         >@ck.lt_translator +        puts @ck.tp[:prepared_by].length.to_s        + ' checklength ' + @ck.tp[:prepared_by]        if @ck.tp[:prepared_by]        and @ck.tp[:prepared_by].length        >@ck.lt_prepared_by +        puts @ck.tp[:digitized_by].length.to_s       + ' checklength ' + @ck.tp[:digitized_by]       if @ck.tp[:digitized_by]       and @ck.tp[:digitized_by].length       >@ck.lt_digitized_by +        puts @ck.tp[:subject].length.to_s            + ' checklength ' + @ck.tp[:subject]            if @ck.tp[:subject]            and @ck.tp[:subject].length            >@ck.lt_subject +        puts @ck.tp[:description].length.to_s        + ' checklength ' + @ck.tp[:description]        if @ck.tp[:description]        and @ck.tp[:description].length        >@ck.lt_description +        puts @ck.tp[:publisher].length.to_s          + ' checklength ' + @ck.tp[:publisher]          if @ck.tp[:publisher]          and @ck.tp[:publisher].length          >@ck.lt_publisher +        puts @ck.tp[:contributor].length.to_s        + ' checklength ' + @ck.tp[:contributor]        if @ck.tp[:contributor]        and @ck.tp[:contributor].length        >@ck.lt_contributor +        puts @ck.tp[:date].length.to_s               + ' checklength ' + @ck.tp[:date]               if @ck.tp[:date]               and @ck.tp[:date].length               >@ck.lt_date +        puts @ck.tp[:date_created].length.to_s       + ' checklength ' + @ck.tp[:date_created]       if @ck.tp[:date_created]       and @ck.tp[:date_created].length       >@ck.lt_date +        puts @ck.tp[:date_issued].length.to_s        + ' checklength ' + @ck.tp[:date_issued]        if @ck.tp[:date_issued]        and @ck.tp[:date_issued].length        >@ck.lt_date +        puts @ck.tp[:date_valid].length.to_s         + ' checklength ' + @ck.tp[:date_valid]         if @ck.tp[:date_valid]         and @ck.tp[:date_valid].length         >@ck.lt_date +        puts @ck.tp[:date_available].length.to_s     + ' checklength ' + @ck.tp[:date_available]     if @ck.tp[:date_available]     and @ck.tp[:date_available].length     >@ck.lt_date +        puts @ck.tp[:date_modified].length.to_s      + ' checklength ' + @ck.tp[:date_modified]      if @ck.tp[:date_modified]      and @ck.tp[:date_modified].length      >@ck.lt_date +        puts @ck.tp[:date_translated].length.to_s    + ' checklength ' + @ck.tp[:date_translated]    if @ck.tp[:date_translated]    and @ck.tp[:date_translated].length    >@ck.lt_date +        puts @ck.tp[:date_added_to_site].length.to_s + ' checklength ' + @ck.tp[:date_added_to_site] if @ck.tp[:date_added_to_site] and @ck.tp[:date_added_to_site].length >@ck.lt_date +        puts @ck.tp[:type].length.to_s               + ' checklength ' + @ck.tp[:type]               if @ck.tp[:type]               and @ck.tp[:type].length               >@ck.lt_type +        puts @ck.tp[:format].length.to_s             + ' checklength ' + @ck.tp[:format]             if @ck.tp[:format]             and @ck.tp[:format].length             >@ck.lt_format +        puts @ck.tp[:identifier].length.to_s         + ' checklength ' + @ck.tp[:identifier]         if @ck.tp[:identifier]         and @ck.tp[:identifier].length         >@ck.lt_identifier +        puts @ck.tp[:source].length.to_s             + ' checklength ' + @ck.tp[:source]             if @ck.tp[:source]             and @ck.tp[:source].length             >@ck.lt_source +        puts @ck.tp[:language].length.to_s           + ' checklength ' + @ck.tp[:language]           if @ck.tp[:language]           and @ck.tp[:language].length           >@ck.lt_language +        puts @ck.tp[:language_original].length.to_s  + ' checklength ' + @ck.tp[:language_original]  if @ck.tp[:language_original]  and @ck.tp[:language_original].length  >@ck.lt_language_original +        puts @ck.tp[:relation].length.to_s           + ' checklength ' + @ck.tp[:relation]           if @ck.tp[:relation]           and @ck.tp[:relation].length           >@ck.lt_relation +        puts @ck.tp[:coverage].length.to_s           + ' checklength ' + @ck.tp[:coverage]           if @ck.tp[:coverage]           and @ck.tp[:coverage].length           >@ck.lt_coverage +        puts @ck.tp[:rights].length.to_s             + ' checklength ' + @ck.tp[:rights]             if @ck.tp[:rights]             and @ck.tp[:rights].length             >@ck.lt_rights +        puts @ck.tp[:copyright].length.to_s          + ' checklength ' + @ck.tp[:copyright]          if @ck.tp[:copyright]          and @ck.tp[:copyright].length          >@ck.lt_copyright +        puts @ck.tp[:owner].length.to_s              + ' checklength ' + @ck.tp[:owner]              if @ck.tp[:owner]              and @ck.tp[:owner].length              >@ck.lt_owner +        puts @ck.tp[:keywords].length.to_s           + ' checklength ' + @ck.tp[:keywords]           if @ck.tp[:keywords]           and @ck.tp[:keywords].length           >@ck.lt_keywords +        puts @ck.tp[:abstract].length.to_s           + ' checklength ' + @ck.tp[:abstract]           if @ck.tp[:abstract]           and @ck.tp[:abstract].length           >@ck.lt_abstract +        puts @ck.tp[:comment].length.to_s            + ' checklength ' + @ck.tp[:comment]            if @ck.tp[:comment]            and @ck.tp[:comment].length            >@ck.lt_comment +        puts @ck.tp[:loc].length.to_s                + ' checklength ' + @ck.tp[:loc]                if @ck.tp[:loc]                and @ck.tp[:loc].length                >@ck.lt_loc +        puts @ck.tp[:dewey].length.to_s              + ' checklength ' + @ck.tp[:dewey]              if @ck.tp[:dewey]              and @ck.tp[:dewey].length              >@ck.lt_dewey +        puts @ck.tp[:isbn].length.to_s               + ' checklength ' + @ck.tp[:isbn]               if @ck.tp[:isbn]               and @ck.tp[:isbn].length               >@ck.lt_isbn +        puts @ck.tp[:pg].length.to_s                 + ' checklength ' + @ck.tp[:pg]                 if @ck.tp[:pg]                 and @ck.tp[:pg].length                 >@ck.lt_pg +        puts @ck.tp[:topic_register].length.to_s     + ' checklength ' + @ck.tp[:topic_register]     if @ck.tp[:topic_register]     and @ck.tp[:topci_register].length     >@ck.lt_topic_register +        puts @ck.tp[:date]                                                                           if @ck.tp[:date] and not @ck.tp[:date].empty? and @ck.tp[:date] !~/\d\d-\d\d-\d\d/ +      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 +    db sql + +  - 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 diff --git a/org/digests.org b/org/digests.org new file mode 100644 index 00000000..7107f53f --- /dev/null +++ b/org/digests.org @@ -0,0 +1,330 @@ +-*- mode: org -*- +#+TITLE:       sisu digests +#+DESCRIPTION: documents - structuring, various output representations & search +#+FILETAGS:    :sisu:digests: +#+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 + +* digests.rb + +#+BEGIN_SRC ruby  :tangle "../lib/sisu/digests.rb" +# <<sisu_document_header>> +module SiSU_DigestView +  require_relative 'se_hub_particulars'                 # se_hub_particulars.rb +  require_relative 'prog_text_translation'              # prog_text_translation.rb +  require_relative 'shared_markup_alt.rb'               # shared_markup_alt.rb +  class Source +    @@dg=nil +    def initialize(opt) +      @opt=opt +      @fnb=@opt.fnb +      @@endnotes_para=[] +      @@dg=nil +      @dg=@@dg ||=SiSU_Env::InfoEnv.new.digest(opt).type +      @particulars=SiSU_Particulars::CombinedSingleton.instance.get_all(opt) +    end +    def read +      begin +        @env,@md,@ao_array=@particulars.env,@particulars.md,@particulars.ao_array +        unless @opt.act[:quiet][:set]==:on +          tool=(@opt.act[:verbose][:set]==:on \ +          || @opt.act[:verbose_plus][:set]==:on \ +          || @opt.act[:maintenance][:set]==:on) \ +          ? "#{@env.program.text_editor} file://#{@md.file.output_path.hash_digest.dir}/#{@md.file.base_filename.hash_digest}" +          : "[#{@opt.f_pth[:lng_is]}] #{@opt.fno}" +          (@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 #{@dg} Digests", +              tool +            ).green_hi_blue +          : SiSU_Screen::Ansi.new( +              @opt.act[:color_state][:set], +              "Document #{@dg} Digests", +              tool +            ).green_title_hi +          if @opt.act[:verbose_plus][:set]==:on \ +          or @opt.act[:maintenance][:set]==:on +            SiSU_Screen::Ansi.new( +              @opt.act[:color_state][:set], +              @opt.fns, +              "file://#{@md.file.output_path.hash_digest.dir}/#{@md.file.base_filename.hash_digest}" +            ).flow +          end +        end +        if SiSU_Env::SystemCall.new.openssl +          SiSU_DigestView::Source::Scroll.new(@particulars).songsheet +        else +          SiSU_Utils::CodeMarker.new(__LINE__,__FILE__,:fuchsia).error('*EXITED* hash digests will not run without openssl') +        end +      rescue +        SiSU_Errors::Rescued.new($!,$@,@opt.selections.str,@opt.fns).location do +          __LINE__.to_s + ':' + __FILE__ +        end +      ensure +      end +    end +    private +    class Scroll <Source +      @@dl=nil +      @@ds={ +        digests_clean: [], +        digests_with_markup: [], +        tree: [], +        summary: [], +      } +      @@description,@@sc_info=[],[] +      def initialize(particulars) +        @particulars=particulars +        @data,@env,@md=@particulars.ao_array,@particulars.env,@particulars.md +        SiSU_Env::FileOp.new(@md).mkdir +        @@dg ||=@env.digest(@md.opt).type +        @@dl ||=@env.digest(@md.opt).length +        @dg,@dl=@@dg,@@dl +        l=SiSU_Env::StandardiseLanguage.new(@md.opt.lng).language +        @language=l[:n] +        @tr=SiSU_Translate::Source.new(@md,@language) +        @sp=' ' +      end +      def songsheet +        @@description,@@ds[:digests_clean],@@ds[:digests_with_markup],@@ds[:tree],@@ds[:summary],@@sc_info=[],[],[],[],[],[] +        message_digest +        ao_structure +        supplementary +        output +      end +      def spaces +        Ax[:spaces] +      end +      def description(f,e='') +        puts f + e.to_s if @md.opt.act[:verbose_plus][:set]==:on +        @@description << f << e +      end +      def digests_clean(f,e='') +        puts f if @md.opt.act[:verbose_plus][:set]==:on +        @@ds[:digests_clean] << f + "\n" +      end +      def digests_with_markup(f) +        puts f if @md.opt.act[:verbose_plus][:set]==:on +        @@ds[:digests_with_markup] << f + "\n" +      end +      def ao_structure_tree(f,e='') +        puts f + e.to_s if @md.opt.act[:verbose_plus][:set]==:on +        @@ds[:tree] << f << e +      end +      def ao_structure_summary(f,e='') +        puts f + e.to_s if @md.opt.act[:verbose_plus][:set]==:on +        @@ds[:summary] << f << e +      end +      def rcinfo(f,e='') +        puts f + e.to_s if @md.opt.act[:verbose_plus][:set]==:on +        @@sc_info << f << e +      end +      def output +        file=SiSU_Env::FileOp.new(@md) +        filename_digest=file.write_file.hash_digest +        filename_digest << @@description.join << @@ds[:digests_clean].join << @@ds[:digests_with_markup].join << @@ds[:tree].join << @@ds[:summary].join << @@sc_info.join +      end +      def rgx_txt(txt) +        txt=txt.gsub(/([()])/,"\\\\\\1") +      end +      def message_digest +        @p=[] +        @g,@v,@r='','','' +        manifest="#{@env.url.root}/#{@md.fnb}/sisu_manifest.html" +        description("#{@md.title.full}\n") +        description("#{@md.author}\n") +        description("#{@md.fns}\n") +        description("----------------------------------------------\n") +        description("SiSU Document Content Certificate (Digest/DCC)\n") +        description("----------------------------------------------\n") +        description("                               #{@dg} digests\n") +        description("------------\n") +        description("Sourcefile digest:             #{@md.dgst[1]}\n") +        description("  source filename:             #{@md.fns}\n") +        description("available outputs:             #{manifest}\n") +        description("------------\n") +        description("Document Digests\n") +      end +      def ao_structure +        a=%{\nocn     digests (#{@dg}) clean text (stripped markup)} +        digests_clean(a) +        data=@data +        endnotes=nil +        data.each do |t_o| +          dgst=SiSU_TextRepresentation::ModifiedTextPlusHashDigest.new(@md,t_o).composite.dgst +          if dgst +            if t_o.is==:heading +              digests_clean("#{@sp*0}#{dgst[:ocn]}#{@sp*(8-dgst[:ocn].to_s.length)}#{dgst[:dgst_stripped_txt]} #{dgst[:is]} #{t_o.lv}") +            elsif t_o.is==:heading_insert +              digests_clean("#{@sp*0}[#{dgst[:ocn]}]#{@sp*(6-dgst[:ocn].to_s.length)}#{dgst[:dgst_stripped_txt]} #{dgst[:is]} #{t_o.lv}") +            else +              digests_clean("#{@sp*0}#{dgst[:ocn]}#{@sp*(8-dgst[:ocn].to_s.length)}#{dgst[:dgst_stripped_txt]} #{dgst[:is]}") +              if dgst[:images] +                dgst[:images].each do |img| +                  digests_clean("#{@sp*8}#{img[:img_dgst]}#{@sp*66}#{img[:img_type]} #{img[:img_name]}") +                end +              end +            end +            if dgst[:endnotes] +              dgst[:endnotes].each do |en| +                digests_clean("#{@sp*8}#{en[:note_dgst]} note [#{en[:note_number]}]") +                endnotes=en[:note_number] +              end +            end +          end +        end +        b=%{\nocn     object (#{@dg}) digests (object includes its markup & endnotes (if any))} +        digests_with_markup(b) +        data.each do |t_o| +          dgst=SiSU_TextRepresentation::ModifiedTextPlusHashDigest.new(@md,t_o).composite.dgst +          if dgst +            if t_o.is==:heading +              digests_with_markup("#{@sp*0}#{dgst[:ocn]}#{@sp*(8-dgst[:ocn].to_s.length)}#{dgst[:dgst_markedup_txt]} #{dgst[:is]} #{t_o.lv}") +            elsif t_o.is==:heading_insert +              digests_with_markup("#{@sp*0}[#{dgst[:ocn]}]#{@sp*(6-dgst[:ocn].to_s.length)}#{dgst[:dgst_markedup_txt]} #{dgst[:is]} #{t_o.lv}") +            else +              digests_with_markup("#{@sp*0}#{dgst[:ocn]}#{@sp*(8-dgst[:ocn].to_s.length)}#{dgst[:dgst_markedup_txt]} #{dgst[:is]}") +            end +          end +        end +        l=Hash.new(0) +        ocn=nil +        ao_structure_tree("------------\n") +        ao_structure_tree("document structure[*]\n") +        data.each do |t_o| +          if t_o.is==:heading +            x=case t_o.ln +            when 0 then l[0] +=1 +              spaces*0 << ':A' +            when 1 then l[1] +=1 +              spaces*1 << ':B' +            when 2 then l[2] +=1 +              spaces*2 << ':C' +            when 3 then l[3] +=1 +              spaces*3 << ':D' +            when 4 then l[4] +=1 +              spaces*4 << '1' +            when 5 then l[5] +=1 +              spaces*5 << '2' +            when 6 then l[6] +=1 +              spaces*6 << '3' +            else nil +            end +          end +          ocn=t_o.ocn if defined? t_o.ocn and t_o.is !=:heading_insert +          ao_structure_tree("#{x}\n") if x and not x.empty? +        end +        ao_structure_tree("  [*] heading levels\n") +        ao_structure_summary("------------\n") +        ao_structure_summary("document structure[*]\n") +        [0,1,2,3,4,5,6].each do |y| +          v=case y +          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 ' +          end +          ao_structure_summary("#{v}            = #{l[y]}\n") if l[y] > 0 +        end +        ao_structure_summary("objects (ocn) = #{ocn}\n") +        ao_structure_summary("endnotes      = #{endnotes}\n") +        ao_structure_summary("  [*] number of headers (@) and of each heading level (:A to :D and 1 to 3)\n") +      end +      def supplementary +        if defined? @md.sc_number \ +        and @md.sc_number +          rcinfo("------------\n") +          rcinfo("source control information\n") +          rcinfo("  (the following information while not important for document content certification\n   may help the publisher in locating the version referred to)\n") +          rcinfo("  rcs version number:            #{@md.sc_number}\n") +          if defined? @md.sc_date \ +          and @md.sc_date +            rcinfo("  rcs date:                      #{@md.sc_date}\n") +          end +          if defined? @md.sc_time \ +          and @md.sc_time +            rcinfo("  rcs time:                      #{@md.sc_time}\n") +          end +        end +        rcinfo("------------\n") +        rcinfo("Note: the time generated related fields (text and digests) will vary between otherwise identical document outputs\n") +      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 +    digests + +  - 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 diff --git a/org/env.org b/org/env.org new file mode 100644 index 00000000..fafc90ef --- /dev/null +++ b/org/env.org @@ -0,0 +1,8610 @@ +-*- mode: org -*- +#+TITLE:       sisu environment +#+DESCRIPTION: documents - structuring, various output representations & search +#+FILETAGS:    :sisu:se: +#+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 + +* sisu environment +** se.rb + +#+BEGIN_SRC ruby  :tangle "../lib/sisu/se.rb" +# <<sisu_document_header>> +@@cX=nil +module SiSU_Env +  require_relative 'constants'                         # constants.rb +  require_relative 'utils'                             # utils.rb +  require_relative 'se_date'                           # se_date.rb +  require_relative 'se_info_system'                    # se_info_system.rb +  require_relative 'se_load'                           # se_load.rb +  require_relative 'se_get_init'                       # se_get_init.rb +  require_relative 'se_envcall'                        # se_envcall.rb +  require_relative 'se_programs'                       # se_programs.rb +  require_relative 'se_standardise_lang'               # se_standardise_lang.rb +  require_relative 'se_info_env'                       # se_info_env.rb +  require_relative 'se_processing'                     # se_processing.rb +  require_relative 'se_filemap'                        # se_filemap.rb +  require_relative 'se_file_op'                        # se_file_op.rb +  require_relative 'se_cleanoutput'                    # se_cleanoutput.rb +  require_relative 'se_remotes'                        # se_remotes.rb +  require_relative 'se_version'                        # se_version.rb +  require_relative 'se_db'                             # se_db.rb +  require_relative 'se_css'                            # se_css.rb +  require_relative 'se_clear'                          # se_clear.rb +  require_relative 'se_createsite'                     # se_createsite.rb +  require_relative 'se_info_port'                      # se_info_port.rb +  begin +    require 'singleton' +    require 'fileutils' +      include FileUtils::Verbose +  rescue LoadError +    SiSU_Utils::CodeMarker.new(__LINE__,__FILE__,:fuchsia). +      error('singleton or fileutils NOT FOUND (LoadError)') +  end +  @@noyaml=false +  class InfoDate < SiSU_Info_Date::InfoDate                # se_date.rb +  end +  class InfoSystemGen < SiSU_Info_Sys_Gen::InfoSystemGen   # se_info_system.rb +  end +  class InfoSystem < SiSU_Info_Sys::InfoSystem             # se_info_system.rb +  end +  class Load < SiSU_Load::Load                             # se_load.rb +  end +  class GetInit < SiSU_Get_Init::GetInit                   # se_get_init.rb +  end +  class EnvCall < SiSU_Env_Call::EnvCall                   # se_envcall.rb +  end +  class SystemCall < SiSU_Sys_Call::SystemCall             # se_programs.rb +  end +  class StandardiseLanguage < SiSU_Standardise_Lang::StandardiseLanguage # se_standardise_lang.rb +  end +  class InfoEnv < SiSU_Info_Env::InfoEnv                   # se_info_env.rb +  end +  class InfoProcessingFlag < SiSU_Info_Processing_Flag::InfoProcessingFlag # se_processing.rb +  end +  class InfoSettings < SiSU_Info_Set::InfoSettings         # se_programs.rb +  end +  class FileMap < SiSU_File_Map::FileMap                   # se_filemap.rb +  end +  class CleanOutput < SiSU_Clean_Output::CleanOutput       # se_cleanoutput.rb +  end +  class InfoRemoteHost < SiSU_Info_Remote_Host::InfoRemoteHost # se_remotes.rb +  end +  class InfoRemote < SiSU_Info_Remote::InfoRemote          # se_remotes.rb +  end +  class InfoVersion < SiSU_Info_Version::InfoVersion       # se_version.rb +  end +  class InfoAbout < SiSU_Info_About::InfoAbout             # se_version.rb +  end +  class InfoFile < SiSU_Info_File::InfoFile                # se_file_op.rb +  end +  class ProcessingSettings < SiSU_Processing_Settings::ProcessingSettings # se_processing.rb +  end +  class InfoDb < SiSU_Info_Db::InfoDb                      # se_db.rb +  end +  class DbOp < SiSU_Db_Op::DbOp                            # se_db.rb +  end +  class FileOp < SiSU_File_Op::FileOp                      # se_file_op.rb +  end +  class FilenameLanguageCodeInsert < SiSU_Filename_Lang::FilenameLanguageCodeInsert # se_file_op.rb +  end +  class CreateFile < SiSU_Create_File::CreateFile          # se_file_op.rb +  end +  class Clear < SiSU_Clear::Clear                          # se_clear.rb +  end +  class InfoPort < SiSU_Info_Port::InfoPort                # se_info_port.rb +  end +  class InfoProgram < SiSU_Info_Program::InfoProgram       # se_programs.rb +  end +  class CSS_Default < SiSU_CSS::CSS_Default                # se_css.rb +  end +  class CSS_Select < SiSU_CSS::CSS_Select                  # se_css.rb +  end +  class CSS_Stylesheet < SiSU_CSS::CSS_Stylesheet          # se_css.rb +  end +  class CreateSite < SiSU_Create_Site::CreateSite          # se_createsite.rb +  end +end +module SiSU_Screen +  require_relative 'utils_screen_text_color'               # utils_screen_text_color.rb +end +module SiSU_Errors +  require_relative 'errors'                             # errors.rb +end +__END__ +#+END_SRC + +** se_cleanoutput.rb + +#+BEGIN_SRC ruby  :tangle "../lib/sisu/se_cleanoutput.rb" +# <<sisu_document_header>> +module SiSU_Clean_Output +  require_relative 'constants'                             # constants.rb +  require_relative 'utils'                                 # utils.rb +  class CleanOutput +    begin +      require 'fileutils' +        include FileUtils::Verbose +    rescue LoadError +      SiSU_Utils::CodeMarker.new(__LINE__,__FILE__,:fuchsia). +        error('fileutils NOT FOUND (LoadError)') +    end +    def initialize(opt) +      @opt=opt +      z=SiSU_Env::FileMap.new(opt) +      zap=z.local_sisu_source +      if opt.cmd =~ /h/i +        zap=Dir.glob(zap).join(' ') +        @zap=if opt.cmd !~ /w/ +          zap.gsub(/#{@source_path}\/concordance.html/,'') +        else zap +        end +      end +      @env=SiSU_Env::InfoEnv.new +    end +    def zap +      def deletion(fn) +        if FileTest.file?(fn)==true +          File.delete(fn) +          tell=SiSU_Screen::Ansi.new(@opt.cmd,@opt.fns, 'remove: ' + fn) +          tell.warn unless @opt.cmd =~/q/ +        end +      end +      def remove_output +        if @opt.act[:maintenance][:set] == :on +          m=InfoFile.new(@opt.fnc) +          tell=SiSU_Screen::Ansi.new( +            @opt.cmd,@opt.fns, +            'remove maintenance files from: ' + @env.processing_path.ao +          ) +          tell.warn unless @opt.cmd =~/q/ +          deletion(m.marshal.ao_content) +          deletion(m.marshal.ao_idx_sst_rel_html_seg) +          deletion(m.ao_idx_sst_rel) +          deletion(m.ao_idx_html) +          deletion(m.ao_idx_xhtml) +          deletion(m.ao_metadata) +          deletion(m.ao_map_nametags) +          deletion(m.ao_map_ocn_htmlseg) +          deletion(m.html_tune) +        end +        md=SiSU_Param::Parameters.new(@opt).get +        f=SiSU_Env::FileOp.new(md) +        deletion(f.place_file.html_segtoc.dir) +        deletion(f.place_file.html_scroll.dir) +        deletion(f.place_file.html_book_index.dir) +        deletion(f.place_file.html_concordance.dir) +        deletion(f.place_file.epub.dir) +        deletion("#{f.output_path.pdf.dir}/#{f.base_filename.pdf_p_letter}") +        deletion("#{f.output_path.pdf.dir}/#{f.base_filename.pdf_l_letter}") +        deletion("#{f.output_path.pdf.dir}/#{f.base_filename.pdf_p_a4}") +        deletion("#{f.output_path.pdf.dir}/#{f.base_filename.pdf_l_a4}") +        deletion("#{f.output_path.pdf.dir}/#{f.base_filename.pdf_p_a5}") +        deletion("#{f.output_path.pdf.dir}/#{f.base_filename.pdf_l_a5}") +        deletion("#{f.output_path.pdf.dir}/#{f.base_filename.pdf_p_b5}") +        deletion("#{f.output_path.pdf.dir}/#{f.base_filename.pdf_l_b5}") +        deletion("#{f.output_path.pdf.dir}/#{f.base_filename.pdf_p_legal}") +        deletion("#{f.output_path.pdf.dir}/#{f.base_filename.pdf_p_legal}") +        deletion(f.place_file.odt.dir) +        deletion(f.place_file.xhtml.dir) +        deletion(f.place_file.xml_sax.dir) +        deletion(f.place_file.xml_dom.dir) +        deletion(f.place_file.xml_scaffold_structure_sisu.dir) +        deletion(f.place_file.xml_scaffold_structure_collapse.dir) +        deletion(f.place_file.info.dir) +        deletion(f.place_file.manpage.dir) +        deletion(f.place_file.sqlite_discrete.dir) +        deletion(f.place_file.txt.dir) +        deletion(f.place_file.hash_digest.dir) +        deletion(f.place_file.manifest.dir) +        deletion(f.place_file.qrcode_md.dir) +        deletion(f.place_file.qrcode_title.dir) +        deletion(f.place_file.src.dir) +        deletion(f.place_file.sisupod.dir) +      end +      self +    end +  end +end +__END__ +#+END_SRC + +** se_clear.rb + +#+BEGIN_SRC ruby  :tangle "../lib/sisu/se_clear.rb" +# <<sisu_document_header>> +module SiSU_Clear +  require_relative 'constants'                             # constants.rb +  require_relative 'utils'                                 # utils.rb +  require_relative 'se_info_env'                           # se_info_env.rb +  begin +    require 'singleton' +  rescue LoadError +    SiSU_Utils::CodeMarker.new(__LINE__,__FILE__,:fuchsia). +      error('singleton NOT FOUND (LoadError)') +  end +  class Clear < SiSU_Info_Env::InfoEnv                     # se_info_env.rb +    #todo unify with FileOp +    def initialize(cmd,fns,operation='') +      @cmd=cmd +      begin +        super(fns) +        @env=SiSU_Env::InfoEnv.new(fns) +        SiSU_Env::InfoVersion.instance +        if operation.class.inspect =~/SiSU_Param/ +          @md=operation +        end +        case operation #watch +        when /pdf/                 then @env_out='' +        when /sql/ +        when /xml|plaintext|ascii/ then @env_out=@env.path.output + @fnb #check change of name to plaintext from ascii +        else +          if defined? @md.sfx_src \ +          and @md.sfx_src =~/ss[ftsumc]/ +            @env_out_root=@env.path.output +            @env_out="#{@env.path.output}/#{@fnb}" +            @@publisher='SiSU http://www.jus.uio.no/sisu' +            @env_pdf="#{@env_out_root}/pdf" +          end +        end +      rescue +        SiSU_Screen::Ansi.new(@cmd,$!,$@).rescue do +          __LINE__.to_s + ':' + __FILE__ +        end +      ensure +      end +    end +    def param_instantiate +      @cX||=SiSU_Screen::Ansi.new(@cmd) +      @@date=SiSU_Env::InfoDate.new +      @@publisher='SiSU scribe' +    end +  end +end +__END__ +#+END_SRC + +** se_createsite.rb + +#+BEGIN_SRC ruby  :tangle "../lib/sisu/se_createsite.rb" +# <<sisu_document_header>> +module SiSU_Create_Site +  require_relative 'constants'                             # constants.rb +  require_relative 'html_parts'                            # html_parts.rb +  require_relative 'utils'                                 # utils.rb +  require_relative 'utils_screen_text_color'               # utils_screen_text_color.rb +  require_relative 'se_info_env'                           # se_info_env.rb +  begin +    require 'fileutils' +      include FileUtils::Verbose +  rescue LoadError +    SiSU_Utils::CodeMarker.new(__LINE__,__FILE__,:fuchsia). +      error('fileutils NOT FOUND (LoadError)') +  end +  class CreateSite < SiSU_Info_Env::InfoEnv                # se_info_env.rb +    require_relative 'css'                                 # css.rb +      include SiSU_Style +    def initialize(opt) +      @opt=opt +      @env=SiSU_Env::InfoEnv.new +      @init=SiSU_Env::GetInit.new +      @home,@pwd=ENV['HOME'],ENV['PWD'] #@pwd=Dir.pwd +      @rc=SiSU_Env::GetInit.new.sisu_yaml.rc +      @home_set=SiSU_Proj_HTML::Home.new +    end +    def create_default_sisu_homepage(action=:none) +      if action==:none +        puts %{  place your homepages in directory:\n    "#{@env.path.rc}/home/*.html"\n  (no action taken)} +      else # turned off, unless something other than :none passed +        puts %{  place your homepages in directory:\n    "#{@env.path.rc}/home/*.html"\n  (in order to replace default sisu homepage)} +        filename_homepage= +          @env.path.webserv + '/' \ +          + @env.path.base_markup_dir_stub + '/index.html' +        filename_home_toc= +          @env.path.webserv + '/' \ +          + @env.path.base_markup_dir_stub + '/toc.html' +        file_homepage=File.new(filename_homepage,'w') +        file_home_toc=File.new(filename_home_toc,'w') +        file_homepage << @home_set.homepage +        file_home_toc << @home_set.homepage +        file_homepage.close +        file_home_toc.close +      end +    end +    def homepage +      home_pages_manually_created=Dir.glob("#{@env.path.rc}/home/*.html") +      FileUtils::mkdir_p("#{@env.path.webserv}/#{@env.path.base_markup_dir_stub}") \ +        unless FileTest.directory?("#{@env.path.webserv}/#{@env.path.base_markup_dir_stub}") +      if home_pages_manually_created.length > 0 +        home_pages_manually_created.each do |homepage| +          FileUtils.cp(homepage,"#{@env.path.webserv}/#{@env.path.base_markup_dir_stub}") +        end +      else +        create_default_sisu_homepage(:none) # :default +      end +    end +    def cp_images(src_path,dest_path) +      if FileTest.directory?(src_path) +        FileUtils::cd(src_path) +        source=Dir.glob("*.{png,jpg,gif,ico}") +        FileUtils::mkdir_p(dest_path) unless FileTest.directory?(dest_path) +        FileUtils::chmod(0755,dest_path) +        source.each do |i| +          if FileTest.file?(i) +            FileUtils::cp(i,"#{dest_path}/#{i}") +            FileUtils::chmod(0644,"#{dest_path}/#{i}") +          else STDERR.puts %{\t*WARN* did not find image - "#{i}" [#{__FILE__}:#{__LINE__}]} +          end +        end +        FileUtils::cd(@pwd) +      else STDERR.puts %{\t*WARN* did not find - #{src_path} [#{__FILE__}:#{__LINE__}]} +      end +    end +    def cp_local_images +      src=@pwd + '/_sisu/image' +      dest= +        @env.path.webserv + '/' \ +        + @env.path.base_markup_dir_stub + '/_sisu/image' +      cp_images(src,dest) if FileTest.directory?(src) +    end +    def cp_external_images +      src=@env.processing_path.processing + '/' \ +      + 'external_document/image' +      dest= +        @env.path.webserv + '/' \ +        + @env.path.base_markup_dir_stub + '/' \ +        + '_sisu/image_external' +      if FileTest.directory?(src) +        cp_images(src,dest) if FileTest.directory?(src) +      end +    end +    def cp_webserver_images +      src=@env.path.image_source +      dest_arr=[ +        "#{@env.path.webserv}/_sisu/image", +        "#{@env.path.webserv}/#{@env.path.base_markup_dir_stub}/_sisu/image", +      ] +      dest_arr.each do |dest| +        cp_images(src,dest) if FileTest.directory?(src) +      end +    end +    def cp_webserver_images_local      #this should not have been necessary +      src=@env.path.image_source +      dest= +        @env.path.webserv + '/' \ +        + @env.path.base_markup_dir_stub + '/' \ +        + '_sisu/image' +      cp_images(src,dest) if FileTest.directory?(src) +    end +    def cp_base_images #fix images +      src=SiSU_is.path_base_system_data? + '/image' +      dest_arr=[ +        "#{@env.path.webserv}/_sisu/image_sys", +        "#{@env.path.webserv}/#{@env.path.base_markup_dir_stub}/_sisu/image_sys" +      ] +      dest_arr.each do |dest| +        cp_images(src,dest) if FileTest.directory?(src) +      end +    end +    def cp_css +      FileUtils::mkdir_p("#{@env.path.output}/#{@env.path.style}") \ +        unless FileTest.directory?("#{@env.path.output}/#{@env.path.style}") +      css_path=[ +        '/etc/sisu/css', +        "#{@home}/.sisu/css", +        "#{@pwd}/_sisu/css", +      ] #BROKEN +      if defined? @rc['permission_set']['css_modify'] \ +      and @rc['permission_set']['css_modify'] +        SiSU_Screen::Ansi.new( +          @opt.selections.str, +          "*WARN* modify is css set to: #{@rc['permission_set']['css_modify']}" +        ).warn if @opt.act[:verbose_plus][:set]==:on \ +        or @opt.act[:maintenance][:set]==:on +        css_path.each do |x| +          if FileTest.directory?(x) +            FileUtils::cd(x) +            source=Dir.glob("*.{css}") +            source.each do |i| +              if FileTest.file?(i) +                FileUtils::cp( +                  i, +                  @env.path.output + '/' + @env.path.style +                ) +              else STDERR.puts %{\t*WARN* did not find css - "#{i}" [#{__FILE__}:#{__LINE__}]} +              end +            end +            FileUtils::cd(@pwd) +          end +        end +      else +        SiSU_Screen::Ansi.new( +          @opt.selections.str, +          "*WARN* modify css is not set or is set to: false" +        ).warn if @opt.act[:verbose_plus][:set]==:on \ +        or @opt.act[:maintenance][:set]==:on +      end +      fn_css=SiSU_Env::CSS_Default.new +      css=SiSU_Style::CSS.new +      path_style="#{@env.path.output}/#{@env.path.style}" +      FileUtils::mkdir_p(path_style) \ +        unless FileTest.directory?(path_style) +      if @opt.act[:site_init][:set]==:on \ +      or not FileTest.file?("#{path_style}/#{fn_css.homepage}") +        style=File.new("#{path_style}/#{fn_css.homepage}",'w') +        style << css.homepage +        style.close +      end +      if @opt.act[:site_init][:set]==:on \ +      or not FileTest.file?("#{path_style}/#{fn_css.html_tables}") +        style=File.new("#{path_style}/#{fn_css.html_tables}",'w') +        style << css.html_tables +        style.close +      end +      if @opt.act[:site_init][:set]==:on \ +      or not FileTest.file?("#{path_style}/#{fn_css.html}") +        style=File.new("#{path_style}/#{fn_css.html}",'w') +        style << css.html +        style.close +      end +      if @opt.act[:site_init][:set]==:on \ +      or not FileTest.file?("#{path_style}/#{fn_css.harvest}") +        style=File.new("#{path_style}/#{fn_css.harvest}",'w') +        style << css.harvest +        style.close +      end +      if @opt.act[:site_init][:set]==:on \ +      or (@opt.act[:xml_sax][:set]==:on \ +      and not FileTest.file?("#{path_style}/#{fn_css.xml_sax}")) +        style=File.new("#{path_style}/#{fn_css.xml_sax}",'w') +        style << css.xml_sax +        style.close +      end +      if @opt.act[:site_init][:set]==:on \ +      or (@opt.act[:xml_dom][:set]==:on \ +      and not FileTest.file?("#{path_style}/#{fn_css.xml_dom}")) +        style=File.new("#{path_style}/#{fn_css.xml_dom}",'w') +        style << css.xml_dom +        style.close +      end +      if @opt.act[:site_init][:set]==:on \ +      or (@opt.act[:xml_docbook_book][:set] == :on \ +      and not FileTest.file?("#{path_style}/#{fn_css.xml_docbook}")) +        style=File.new("#{path_style}/#{fn_css.xml_docbook}",'w') +        style << css.xml_docbook +        style.close +      end +      if @opt.act[:site_init][:set]==:on \ +      or (@opt.act[:xhtml][:set] == :on \ +      and not FileTest.file?("#{path_style}/#{fn_css.xhtml}")) +        style=File.new("#{path_style}/#{fn_css.xhtml}",'w') +        style << css.xhtml +        style.close +      end +    end +  end +end +__END__ +#+END_SRC + +** se_css.rb + +#+BEGIN_SRC ruby  :tangle "../lib/sisu/se_css.rb" +# <<sisu_document_header>> +module SiSU_CSS +  require_relative 'constants'                             # constants.rb +  require_relative 'utils'                                 # utils.rb +  require_relative 'se_info_env'                           # se_info_env.rb +  class CSS_Default +    def html +      'html.css' +    end +    def html_tables +      'html_tables.css' +    end +    def xhtml +      'xhtml.css' +    end +    def xml_sax +      'sax.css' +    end +    def xml_dom +      'dom.css' +    end +    def xml_docbook +      'docbook.css' +    end +    def homepage +      'homepage.css' +    end +    def harvest +      'harvest.css' +    end +  end +  class CSS_Select < SiSU_Info_Env::InfoEnv                # se_info_env.rb +    def initialize(md) +      @md=md +      @env=SiSU_Env::InfoEnv.new('',@md) +    end +    def html +      if @md.doc_css \ +      and FileTest.file?("#{@env.path.output}/#{@env.path.style}/#{@md.doc_css}_html.css") +        @md.doc_css + '_html.css' +      elsif FileTest.file?("#{@env.path.output}/#{@env.path.style}/#{@env.path.base_markup_dir_stub}_html.css") +        @env.path.base_markup_dir_stub + '_html.css' +      else +        SiSU_Env::CSS_Default.new.html +      end +    end +    def html_tables +      if @md.doc_css \ +      and FileTest.file?("#{@env.path.output}/#{@env.path.style}/#{@md.doc_css}_html_tables.css") +        @md.doc_css + '_html_tables.css' +      elsif FileTest.file?("#{@env.path.output}/#{@env.path.style}/#{@env.path.base_markup_dir_stub}_html_tables.css") +        @env.path.base_markup_dir_stub + '_html_tables.css' +      else SiSU_Env::CSS_Default.new.html_tables +      end +    end +    def xhtml +      if @md.doc_css \ +      and FileTest.file?("#{@env.path.output}/#{@env.path.style}/#{@md.doc_css}_xhtml.css") +        @md.doc_css + '_xhtml.css' +      elsif FileTest.file?("#{@env.path.output}/#{@env.path.style}/#{@env.path.base_markup_dir_stub}_xhtml.css") +        @env.path.base_markup_dir_stub + '_xhtml.css' +      else SiSU_Env::CSS_Default.new.xhtml +      end +    end +    def xml_sax +      if @md.doc_css \ +      and FileTest.file?("#{@env.path.output}/#{@env.path.style}/#{@md.doc_css}_xml_sax.css") +        @md.doc_css + '_xml_sax.css' +      elsif FileTest.file?("#{@env.path.output}/#{@env.path.style}/#{@env.path.base_markup_dir_stub}_xml_sax.css") +        @env.path.base_markup_dir_stub + '_xml_sax.css' +      else SiSU_Env::CSS_Default.new.xml_sax +      end +    end +    def xml_dom +      if @md.doc_css \ +      and FileTest.file?("#{@env.path.output}/#{@env.path.style}/#{@md.doc_css}_xml_dom.css") +        @md.doc_css + '_xml_dom.css' +      elsif FileTest.file?("#{@env.path.output}/#{@env.path.style}/#{@env.path.base_markup_dir_stub}_xml_dom.css") +        @env.path.base_markup_dir_stub + '_xml_dom.css' +      else SiSU_Env::CSS_Default.new.xml_dom +      end +    end +    def xml_docbook +      if @md.doc_css \ +      and FileTest.file?("#{@env.path.output}/#{@env.path.style}/#{@md.doc_css}_docbook.css") +        @md.doc_css + '_xml_dom.css' +      elsif FileTest.file?("#{@env.path.output}/#{@env.path.style}/#{@env.path.base_markup_dir_stub}_docbook.css") +        @env.path.base_markup_dir_stub + '_docbook.css' +      else SiSU_Env::CSS_Default.new.xml_docbook +      end +    end +    def homepage +      if @md.doc_css \ +      and FileTest.file?("#{@env.path.output}/#{@env.path.style}/#{@md.doc_css}_homepage.css") +        @md.doc_css + '_homepage.css' +      elsif FileTest.file?("#{@env.path.output}/#{@env.path.style}/#{@env.path.base_markup_dir_stub}_homepage.css") +        @env.path.base_markup_dir_stub + '_homepage.css' +      else SiSU_Env::CSS_Default.new.homepage +      end +    end +  end +  class CSS_Stylesheet +    def initialize(md) +      @md=md +      @css=SiSU_Env::CSS_Select.new(@md) +      @env=SiSU_Env::InfoEnv.new('',@md) +      @file=SiSU_Env::FileOp.new(@md) +    end +    def html +      stylesheet= +        @file.path_rel_links.html_scroll_css \ +        + @env.path.style + '/' \ +        + @css.html +      %{  <link href="#{stylesheet}" rel="stylesheet">} +    end +    def html_seg +      stylesheet= +        @file.path_rel_links.html_seg_css \ +        + @env.path.style + '/' \ +        + @css.html +      %{  <link href="#{stylesheet}" rel="stylesheet">} +    end +    def html_tables +      stylesheet= +        @file.path_rel_links.html_seg_css \ +        + @env.path.style + '/' \ +        + @css.html +      %{  <link href="#{stylesheet}" rel="stylesheet">} +    end +    def xhtml_epub +      %{  <link rel="stylesheet" href="css/xhtml.css" type="text/css" />} +    end +    def epub +      xhtml_epub +    end +    def xhtml +      stylesheet= +        @file.path_rel_links.xhtml_css \ +        + @env.path.style + '/' \ +        + @css.xhtml +      %{<?xml-stylesheet type="text/css" href="#{stylesheet}"?>} +    end +    def xml_sax +      stylesheet= +        @file.path_rel_links.xml_css \ +        + @env.path.style + '/' \ +        + @css.xml_sax +      %{<?xml-stylesheet type="text/css" href="#{stylesheet}"?>} +    end +    def xml_dom +      stylesheet= +        @file.path_rel_links.xml_css \ +        + @env.path.style + '/' \ +        + @css.xml_dom +      %{<?xml-stylesheet type="text/css" href="#{stylesheet}"?>} +    end +    def xml_docbook +      stylesheet= +        @file.path_rel_links.xml_css \ +        + @env.path.style + '/' \ +        + @css.xml_docbook +      %{<?xml-stylesheet type="text/css" href="#{stylesheet}"?>} +    end +  end +end +__END__ +#+END_SRC + +** se_date.rb + +#+BEGIN_SRC ruby  :tangle "../lib/sisu/se_date.rb" +# <<sisu_document_header>> +module SiSU_Info_Date +  require_relative 'constants'                             # constants.rb +  require_relative 'utils'                                 # utils.rb +  class InfoDate +    begin +      require 'date' +    rescue LoadError +      SiSU_Utils::CodeMarker.new(__LINE__,__FILE__,:fuchsia). +        error('date NOT FOUND (LoadError)') +    end +    attr_accessor :dt,:t +    def initialize +      @dt,@t=Date.today.to_s,Time.now +    end +    def week +      w=@t.strftime('%W') +      "#{@t.year}w#{w}" +    end +    def month +      "#{@t.year}#{@t.month}" +    end +    def year +      @t.year +    end +    def weekonly +      @t.strftime('%W') +    end +    def monthonly +      @t.month +    end +    def year_static +      YEAR +    end +  end +end +__END__ +#+END_SRC + +** se_db.rb + +#+BEGIN_SRC ruby  :tangle "../lib/sisu/se_db.rb" +# <<sisu_document_header>> +module SiSU_Info_Db +  require_relative 'constants'                             # constants.rb +  require_relative 'utils'                                 # utils.rb +  require_relative 'se_info_env'                           # se_info_env.rb +  class InfoDb < SiSU_Info_Env::InfoEnv                    # se_info_env.rb +    @@rc=nil +    def initialize +      @@pwd=@pwd=SiSU_Utils::Path.new.base_markup +      @env=SiSU_Env::InfoEnv.new +      pt=Pathname.new(@pwd) +      r=Px[:lng_lst_rgx] +      u=/.+?\/([^\/]+)(?:\/(?:#{r})$|$)/ +      @pwd_stub=pt.realpath.to_s[u,1] +      @rc=@@rc ||=SiSU_Env::GetInit.new.sisu_yaml.rc +      @defaults=SiSU_Env::InfoEnv.new.defaults +    end +    def share_source? +      ((defined? @rc['db']['share_source']) \ +      && @rc['db']['share_source']==true) \ +      ? @rc['db']['share_source'] +      : false +    end +    def engine +      def default +        ((defined? @rc['db']['engine']['default']) \ +        && @rc['db']['engine']['default']=~/postgresql|sqlite/) \ +        ? @rc['db']['engine']['default'] +        : 'sqlite' +      end +      self +    end +    def psql +      def user(opt=nil) +        if opt \ +        and opt.selections.str =~/--db-user[=-]["']?(\S+)["']+/ +          $1 +        elsif opt \ +        and opt.selections.str =~/--webserv[=-]webrick/ +          @env.user +        else +          ((defined? @rc['db']['postgresql']['user']) \ +          && @rc['db']['postgresql']['user']=~/\S+/) \ +          ? @rc['db']['postgresql']['user'] +          : @env.user +        end +      end +      def db #db_name +        "#{Db[:name_prefix]}#{@pwd_stub}" +      end +      def port #PGPORT +        ((defined? @rc['db']['postgresql']['port']) \ +        && ( @rc['db']['postgresql']['port'] =~/\d+/ \ +        || @rc['db']['postgresql']['port'].is_a?(Fixnum))) \ +        ? @rc['db']['postgresql']['port'] +        : (@defaults[:postgresql_port]) +      end +      def password +        ((defined? @rc['db']['postgresql']['password']) \ +        && @rc['db']['postgresql']['password']=~/\S+/) \ +        ? @rc['db']['postgresql']['password'] +        : '' +      end +      def host +        ((defined? @rc['db']['postgresql']['host']) \ +        && @rc['db']['postgresql']['host']=~/(?:\S{1,3}\.){3}\S{1,3}|\S+?\.\S+/) \ +        ? @rc['db']['postgresql']['host'] +        : '' +      end +      def dbi +        PG::Connection.open(:dbname =>  psql.db) +      end +      def dbi_ +        (psql.host =~/(?:\S{1,3}\.){3}\S{1,3}|\S+?\.\S+/) \ +        ? "DBI:Pg:database=#{psql.db};host=#{psql.host};port=#{psql.port}" +        : "DBI:Pg:database=#{psql.db};port=#{psql.port}" +      end +      def conn_dbi +        DBI.connect(psql.dbi,psql.user,psql.db) +      end +      def conn_pg +        begin +          require 'pg' +        rescue LoadError +          SiSU_Utils::CodeMarker.new(__LINE__,__FILE__,:fuchsia). +            error('pg NOT FOUND (LoadError)') +        end +        PG::Connection.new(dbname: psql.db, port: psql.port) +      end +     self +    end +    def sqlite +      def db +        "#{@env.path.webserv}/#{@pwd_stub}/sisu_sqlite.db" +      end +      def db_discrete(md) +        # "#{@env.path.webserv}/#{@pwd_stub}/sisu_sqlite.db" +      end +      def dbi +        "DBI:SQLite3:#{sqlite.db}" #sqlite3 ? +      end +      def sqlite3 +        sqlite.db #sqlite3 ? +      end +      def conn_dbi +        DBI.connect(sqlite.dbi) +      end +      def conn_sqlite3 +        SQLite3::Database.new(sqlite.sqlite3) +      end +      self +    end +  end +end +module SiSU_Db_Op +  require_relative 'constants'                             # constants.rb +  require_relative 'utils'                                 # utils.rb +  class DbOp < SiSU_Info_Db::InfoDb +    def initialize(md) +      begin +        @md=md +      rescue +        SiSU_Screen::Ansi.new(md.opt.selections.str,$!,$@).rescue do +          __LINE__.to_s + ':' + __FILE__ +        end +      ensure +      end +    end +    def sqlite_discrete +      def db +        @md.file.output_path.sqlite_discrete.dir \ +        + '/' \ +        + @md.file.base_filename.sqlite_discrete +      end +      def dbi +        "DBI:SQLite3:#{sqlite_discrete.db}" +      end +      def sqlite3 +        sqlite_discrete.db +      end +      def conn_dbi +        DBI.connect(sqlite_discrete.dbi) +      end +      def conn_sqlite3 +        begin +          $sqlite3=:yes +          require 'sqlite3' +          SQLite3::Database.new(sqlite_discrete.sqlite3) +        rescue LoadError +          $sqlite3=:no +          SiSU_Utils::CodeMarker.new(__LINE__,__FILE__,:fuchsia). +            error('sqlite3 NOT FOUND (LoadError)') +        end +      end +      self +    end +  end +end +__END__ +#+END_SRC + +** se_envcall.rb + +#+BEGIN_SRC ruby  :tangle "../lib/sisu/se_envcall.rb" +# <<sisu_document_header>> +module SiSU_Env_Call +  begin +    require 'singleton' +  rescue LoadError +    SiSU_Utils::CodeMarker.new(__LINE__,__FILE__,:fuchsia). +      error('singleton NOT FOUND (LoadError)') +  end +  class EnvCall +    @@rc,@@fns,@@fnn,@@fnb,@@fnt,@@flv,@@fnz=nil,nil,nil,nil,nil,nil,nil +    @@ad={} +    attr_accessor :rc,:fnn,:fnb,:fnt,:fnv,:fnz,:ad +    def initialize(fns='') +      @fns=fns +      @sys=SiSU_Info_Sys::InfoSystem.instance +      get_init=SiSU_Env::GetInit.new +      @rc=get_init.sisu_yaml.rc +      @ad=get_init.ads +      if @fns \ +      and @fns != '' \ +      and @fns !=@@fns +        @@fns,@@fnn,@@fnb,@@fnt,@@flv,@@fnz=@fns,nil,nil,nil,nil,nil +      end +      if @fns \ +      and @fns != '' #watch +        m=/((.+?)(?:\~\w\w(?:_\w\w)?)?)\.((?:-|ssm\.)?sst|ssm|ssi)$/ +        @@fnn ||=@fns[m,1] +        @@fnb ||=@fns[m,2] +        @@fnt ||=@fns[m,3] +        @@flv ||=document_language_versions_found[:f] +        unless @@fns =~/\S+?\.txz/ +          @@fnz ||=if @@fns =~/(?:\~\S{2,3})?\.(?:ssm\.sst|ssm)$/; @@fnb + '.ssm.txz' +          elsif @@fnb; @@fnb + '.sst.txz' +          else '' # e.g. termsheet +          end +        end +      end +      @fnn,@fnb,@fnt,@flv,@fnz=@@fnn,@@fnb,@@fnt,@@flv,@@fnz +    end +    def default_language? +      if @rc \ +      && defined? @rc['language_default'] +        if (@rc['language_default'].is_a?(String)) \ +        && (@rc['language_default'] =~/#{Px[:lng_lst_rgx]}/) +          @rc['language_default'] +        else 'en' +        end +      else 'en' +      end +    end +    def mono_multi_lingual? +      if @rc \ +      && defined? @rc['output_dir_structure_by'] +        if @rc['output_dir_structure_by'] \ +        =~/dump/ +          :mono +        elsif @rc['output_dir_structure_by'] \ +        =~/language|redirect/ +          :multi +        elsif @rc['output_dir_structure_by'] \ +        =~/monolingual|filetype_mono|filenaneme_mono/ +          :mono +        else :multi +        end +      else :multi +      end +    end +    def output_dir_structure +      def by? +        output_structure=:filename #set default output structure +        if @rc \ +        && defined? @rc['output_dir_structure_by'] +          output_structure=if (@rc['output_dir_structure_by'] =~/dump/) \ +          or ((defined? @rc['output_structure']['dump']) \ +          && @rc['output_structure']['dump'] ==true) +            :dump +          elsif (@rc['output_dir_structure_by'] =~/redirect/) \ +          or ((defined? @rc['output_structure']['redirect']) \ +          && @rc['output_structure']['redirect'] ==true) +            :redirect +          elsif (@rc['output_dir_structure_by'] =~/language/) \ +          or ((defined? @rc['output_structure']['by_language']) \ +          && @rc['output_structure']['by_language'] ==true) +            :language +          elsif (@rc['output_dir_structure_by'] =~/filetype/) \ +          or ((defined? @rc['output_structure']['by_filetype']) \ +          && @rc['output_structure']['by_filetype'] ==true) +            :filetype +          elsif (@rc['output_dir_structure_by'] =~/filename/) \ +          or ((defined? @rc['output_structure']['by_filename']) \ +          && @rc['output_structure']['by_filename'] ==true) +            :filename +          else #set default +            :language +          end +        else #set default +          :language +        end +      end +      def dump? +        ((by?) ==:dump) \ +        ? true +        : false +      end +      def redirect? +        ((by?) ==:redirect) \ +        ? true +        : false +      end +      def by_language_code? +        ((by?) ==:language) \ +        ? true +        : false +      end +      def by_filetype? +        ((by?) ==:filetype) \ +        ? true +        : false +      end +      def by_filename? +        ((by?) ==:filename) \ +        ? true +        : false +      end +      def multilingual? +        by_language_code? +      end +      self +    end +    def document_language_versions_found #REVISIT +      @fn={} +      filename=(@fns =~/\.ssm\.sst$/) \ +      ? @fns.gsub(/\.ssm\.sst$/,'.ssm') +      : @fns +      if filename.is_a?(String) \ +      and not filename.empty? +        if output_dir_structure.by_language_code? +          m=/((.+?)(?:\~\w{2,3})?)\.(sst|ssm)$/ +          @fn[:b],@fn[:m],@fn[:t]=filename[m,1],filename[m,2],filename[m,3] +        else m=/(.+?)\.(sst|ssm)$/ +          @fn[:b]=@fn[:m]=filename[m,1] +          @fn[:t]=filename[m,2] +        end +      end +      lng_base=SiSU_Env::InfoEnv.new.language_default_set +      lang=SiSU_Env::StandardiseLanguage.new +      langs=lang.codes +      x=[] +      if FileTest.file?("#{@fn[:m]}.#{@fn[:t]}") +        n=@fn[:m].gsub(/^.+?\//,'') +        n =n + '.' + @fn[:t] +        x << { f: "#{@fn[:m]}.#{@fn[:t]}", l: lng_base, n: n } +      end +      langs.each do |l| +        lng=SiSU_Env::StandardiseLanguage.new(l) +        if FileTest.file?("#{@fn[:m]}~#{lng.code}.#{@fn[:t]}") +          x << { f: "#{@fn[:m]}~#{lng.code}.#{@fn[:t]}", l: lng.code } +        elsif FileTest.file?("#{@fn[:m]}~#{lng.name}.#{@fn[:t]}") +          x << { f: "#{@fn[:m]}~#{lng.name}.#{@fn[:t]}", l: lng.code } +        end +        if FileTest.file?("#{lng.code}/#{@fn[:m]}~#{lng.code}.#{@fn[:t]}") +          if FileTest.file?("#{lng.code}/#{@fn[:m]}~#{lng.code}.#{@fn[:t]}") +            x << { f: "#{lng.code}/#{@fn[:m]}~#{lng.code}.#{@fn[:t]}", l: lng.code } +          elsif FileTest.file?("#{lng.code}/#{@fn[:m]}~#{lng.name}.#{@fn[:t]}") +            x << { f: "#{lng.code}/#{@fn[:m]}~#{lng.name}.#{@fn[:t]}", l: lng.code } +          end +        end +        if FileTest.file?("#{lng.code}/#{@fn[:m]}.#{@fn[:t]}") +          if FileTest.file?("#{lng.code}/#{@fn[:m]}.#{@fn[:t]}") +            x << { f: "#{lng.code}/#{@fn[:m]}.#{@fn[:t]}", l: lng.code } +          elsif FileTest.file?("#{lng.code}/#{@fn[:m]}.#{@fn[:t]}") +            x << { f: "#{lng.code}/#{@fn[:m]}.#{@fn[:t]}", l: lng.code } +          end +        end +      end +      @fn[:f]=x +      @fn +    end +    def published_manifests?(output_base) +      @fn={} +      @m=[] +      unless (@fns.nil? \ +      or @fns.empty?) +        if output_dir_structure.by_language_code? +          m=/((.+?)(?:\~\w{2,3})?)\.((?:-|ssm\.)?sst$)/ +          @fn[:b],@fn[:m],@fn[:t]=@fns[m,1],@fns[m,2],@fns[m,3] +        else m=/(.+?)\.((?:-|ssm\.)?sst$)/ +          @fn[:b]=@fn[:m]=@fns[m,1] +          @fn[:t]=@fns[m,2] +        end +      end +      lang=SiSU_Env::StandardiseLanguage.new +      langs=lang.codes +      x=[] +      if FileTest.file?("#{@fn[:m]}.#{@fn[:t]}"); x << "#{@fn[:m]}.#{@fn[:t]}" +      end +      dir=SiSU_Env::InfoEnv.new(@fns) +      @m << { m: 'sisu_manifest.html', l: 'English' } #fix later, default language +      langs.each do |l| +        lng=SiSU_Env::StandardiseLanguage.new(l) +        fns_c="#{@fn[:m]}~#{lng.code}.#{@fn[:t]}" +        fns_l="#{@fn[:m]}~#{lng.name}.#{@fn[:t]}" +        if FileTest.file?(fns_c) +          fn_set_lang=SiSU_Env::StandardiseLanguage.new. +            file_to_language(fns_c) #reconsider file_to_language +          lng=fn_set_lang[:n] +          fn=SiSU_Env::EnvCall.new(fns_c).lang(fn_set_lang[:c]) +          @m << { m: fn[:manifest], l: lng } +        elsif FileTest.file?(fns_l) +          fn_set_lang=SiSU_Env::StandardiseLanguage.new. +            file_to_language(fns_l) #reconsider file_to_language +          @fnl=dir.i18n.lang_filename(fn_set_lang[:c]) +          fn=SiSU_Env::EnvCall.new(fns_l).lang(fn_set_lang[:c]) +          @m << { m: fn[:manifest], l: lng } +        end +      end +      @m=@m.uniq +    end +    def filename(code,name,suffix) +      "#{name}#{suffix}" +    end +    def lang(code) +      { +        html:            filename(code,'','.html'), +        book_index:      filename(code,'book_index','.html'), +        concordance:     filename(code,'concordance','.html'), +        sax:             filename(code,'sax','.xml'), +        dom:             filename(code,'dom','.xml'), +        docbook:         filename(code,'docbook','.xml'), +        xhtml:           filename(code,'scroll','.xhtml'), +        pdf_l:           filename(code,'','.pdf'), +        pdf_p:           filename(code,'','.pdf'), +        pdf_l_a4:        filename(code,"a4",'.pdf'), +        pdf_p_a4:        filename(code,"a4",'.pdf'), +        pdf_l_a5:        filename(code,"a5",'.pdf'), +        pdf_p_a5:        filename(code,"a5",'.pdf'), +        pdf_l_b5:        filename(code,"b5",'.pdf'), +        pdf_p_b5:        filename(code,"b5",'.pdf'), +        pdf_l_letter:    filename(code,"letter",'.pdf'), +        pdf_p_letter:    filename(code,"letter",'.pdf'), +        pdf_l_legal:     filename(code,"legal",'.pdf'), +        pdf_p_legal:     filename(code,"legal",'.pdf'), +        toc:             filename(code,'toc','.html'), +        doc:             filename(code,fnb,'.html'), +        index:           filename(code,'index','.html'), +        po:              filename(code,@fns,'.po'), +        pot:             filename(code,@fns,'.pot'), +        odf:             filename(code,'','.odt'), +        epub:            filename(code,'','.epub'), +        plain:           filename(code,'','.txt'), +        qrcode:          filename(code,'','.jpg'), +        manpage:         filename(code,'','.1'),          #fix, section number +        wiki:            filename(code,'wiki','.txt'), +        digest:          filename(code,'digest','.txt'), +        metadata:        filename(code,'metadata','.html'), #chk +        manifest:        filename(code,'manifest','.html'), +        oai_pmh:         filename(code,'oai_pmh','.xml'), +        sitemap:         filename(code,'sitemap','.xml'), +        sitemap_touch:   filename(code,"sitemap_#{fnb}",'.xml'), +        sxs:             filename(code,fnb,'.sxs.xml'), +        sxd:             filename(code,fnb,'.sxd.xml'), +        sxn:             filename(code,fnb,'.sxn.xml'), +        sisupod:         filename(nil,@fnz,''), +        book_idx_html:   filename(code,'book_index','.html'), +        book_idx_epub:   filename(code,'book_index','.xhtml'), +        epub_concord:    filename(code,'concordance','.xhtml'), +      } +    end +  end +end +__END__ +#+END_SRC + +** se_filemap.rb + +#+BEGIN_SRC ruby  :tangle "../lib/sisu/se_filemap.rb" +# <<sisu_document_header>> +module SiSU_File_Map +  require_relative 'constants'                             # constants.rb +  require_relative 'utils'                                 # utils.rb +  require_relative 'se_info_env'                           # se_info_env.rb +  class FileMap < SiSU_Info_Env::InfoEnv                   # se_info_env.rb +    attr_accessor :local_sisu_source +    def initialize(opt='') #watch / REVIEW +      super() +      @opt=opt #,opt.fns,opt.selections.str +      @env=(@opt.fns && !(@opt.fns.empty?) \ +      ? (SiSU_Env::InfoEnv.new(@opt.fns)) +      : (SiSU_Env::InfoEnv.new('dummy.sst'))) +      ft=[] +      if @opt.act[:ao][:set]==:on +        @md=SiSU_Param::Parameters.new(@opt).get +        if @md \ +        and defined? @md.fn \ +        and @md.fn        # used for by_language_code? +          if @md.opt.act[:html][:set]==:on                 #% --html, -h -H +            ft << @md.fn[:html] +          end +          if @md.opt.act[:concordance][:set]==:on          #% --concordance, -w +            ft << @md.fn[:concordance] +          end +          if @md.opt.act[:manifest][:set]==:on             #% --manifest, -y +            ft << @md.fn[:manifest] +          end +          if @md.opt.act[:txt][:set]==:on                  #% --txt, -t -a +            ft << @md.fn[:plain] +          end +          if @md.opt.act[:txt_textile][:set]==:on          #% --textile +            ft << @md.fn[:txt_textile] +          end +          if @md.opt.act[:txt_asciidoc][:set]==:on         #% --asciidoc +            ft << @md.fn[:txt_asciidoc] +          end +          if @md.opt.act[:txt_markdown][:set]==:on         #% --markdown +            ft << @md.fn[:txt_markdown] +          end +          if @md.opt.act[:txt_rst][:set]==:on              #% --rst, --rest +            ft << @md.fn[:txt_rst] +          end +          if @md.opt.act[:txt_orgmode][:set]==:on          #% --orgmode +            ft << @md.fn[:txt_orgmode] +          end +          if @md.opt.act[:xhtml][:set]==:on                #% --xhtml, -b xhtml +            ft << @md.fn[:xhtml] +          end +          if @md.opt.act[:epub][:set]==:on                 #% --epub, -e +            ft << @md.fn[:epub] +          end +          if @md.opt.act[:manpage][:set]==:on              #% --manpage, -i +            ft << @md.fn[:manpage] +          end +          if @md.opt.act[:hash_digests][:set]==:on         #% --hash-digests, -N digest tree +            ft << @md.fn[:digest] +          end +          if @md.opt.act[:odt][:set]==:on                  #% --odt, -o opendocument +            ft << @md.fn[:odf] +          end +          if @md.opt.act[:pdf][:set]==:on                  #% --pdf-l --pdf, -p latex/ texpdf +            ft << @md.fn[:pdf_l] << @md.fn[:pdf_p] +          end +          if @md.opt.act[:share_source][:set]==:on +            ft << @md.fns +          end +          if @md.opt.act[:sisupod][:set]==:on              #% --sisupod, -S make sisupod +            ft << @md.fn[:sisupod] +          end +          if @md.opt.act[:xml_sax][:set]==:on              #% --xml-sax, -x xml sax type +            ft << @md.fn[:sax] +          end +          if @md.opt.act[:xml_dom][:set]==:on              #% --xml-dom, -X xml dom type +            ft << @md.fn[:dom] +          end +          if @md.opt.act[:xml_docbook_book][:set]==:on     #% --xml-docbook-book +            ft << @md.fn[:xml_docbook_book] +          end +          if @md.opt.act[:xml_fictionbook][:set]==:on      #% --xml-fictionbook +            ft << @md.fn[:xml_fictionbook] +          end +          if @md.opt.act[:xml_scaffold_structure_sisu][:set]==:on          #% --xml-scaffold --xml-scaffold-sisu +            ft << @md.fn[:xml_scaffold_structure_sisu] +          end +          if @md.opt.act[:xml_scaffold_structure_collapse][:set]==:on      #% --xml-scaffold-collapse +            ft << @md.fn[:xml_scaffold_structure_collapse] +          end +          @fnb=@md.fnb +        else   # still needed where/when dp document param is not parsed +          if @opt.act[:html][:set]==:on                    #% --html, -h -H +            ft << '.html' << '.html.??' +          end +          if @opt.act[:concordance][:set]==:on             #% --concordance, -w +            ft << 'concordance.html' << '??.concordance.html' << 'concordance.??.html' +          end +          if @opt.act[:manifest][:set]==:on                #% --manifest, -y +            ft << 'sisu_manifest.html' << '??.sisu_manifest.html' << 'sisu_manifest.??.html' +          end +          if @opt.act[:txt][:set]==:on                     #% --txt, -t -a +            ft << 'plain.txt' << '??.plain.txt' << 'plain.??.txt' +          end +          if @opt.act[:txt_textile][:set]==:on             #% --textile +            ft << 'plain.txt' << '??.plain.txt' << 'plain.??.txt' +          end +          if @opt.act[:txt_asciidoc][:set]==:on            #% --asciidoc +            ft << 'plain.txt' << '??.plain.txt' << 'plain.??.txt' +          end +          if @opt.act[:txt_markdown][:set]==:on            #% --markdown +            ft << 'plain.txt' << '??.plain.txt' << 'plain.??.txt' +          end +          if @opt.act[:txt_rst][:set]==:on                 #% --rst, --rest +            ft << 'plain.txt' << '??.plain.txt' << 'plain.??.txt' +          end +          if @opt.act[:txt_orgmode][:set]==:on             #% --orgmode +            ft << 'plain.txt' << '??.plain.txt' << 'plain.??.txt' +          end +          if @opt.act[:xhtml][:set]==:on                   #% --xhtml, -b xhtml +            ft << 'scroll.xhtml' << '??.scroll.xhtml' << 'scroll.??.xhtml' +          end +          if @opt.act[:epub][:set]==:on                    #% --epub, -e +            ft  << @fnb << '.epub' +          end +          if @opt.act[:manpage][:set]==:on                 #% --manpage, -i +            ft << '.1' << '??.man.1' << 'man.??.1' +          end +          if @opt.act[:hash_digests][:set]==:on            #% --hash-digests, -N digest tree +            ft << 'digest.txt' << '??.digest.txt' << 'digest.??.txt' +          end +          if @opt.act[:odt][:set]==:on                     #% --odt, -o opendocument +            ft << 'opendocument.odt' << '??.opendocument.odt' << 'opendocument.??.odt' +          end +          if @opt.act[:pdf][:set]==:on                     #% --pdf-l --pdf, -p latex/ texpdf +            ft << 'landscape.pdf' << 'portrait.pdf' << '.pdf' +          end +          if @opt.act[:share_source][:set]==:on +            ft << '.sst' << '.ssi' << '.ssm' +          end +          if @opt.act[:sisupod][:set]==:on                 #% --sisupod, -S make sisupod +            ft << '.zip' +          end +          if @opt.act[:xml_sax][:set]==:on                 #% --xml-sax, -x xml sax type +            ft << 'sax.xml' << '??.sax.xml' << 'sax.??.xml' +          end +          if @opt.act[:xml_dom][:set]==:on                 #% --xml-dom, -X xml dom type +            ft << 'dom.xml' << '??.dom.xml' << 'dom.??.xml' +          end +          if @opt.act[:xml_docbook_book][:set]==:on        #% --xml-docbook-book +            ft << 'docbook.xml' << '??.docbook.xml' << 'docbook.??.xml' +          end +          if @opt.act[:xml_fictionbook][:set]==:on         #% --xml-fictionbook +            ft << 'fictionbook.xml' << '??.fictionbook.xml' << 'fictionbook.??.xml' +          end +          if @opt.act[:xml_scaffold_structure_sisu][:set]==:on          #% --xml-scaffold --xml-scaffold-sisu +            ft << 'scaffold.xml' << '??.scaffold.xml' << 'scaffold.??.xml' +          end +          if @opt.act[:xml_scaffold_structure_collapse][:set]==:on      #% --xml-scaffold-collapse +            ft << 'scaffold.xml' << '??.scaffold.xml' << 'scaffold.??.xml' +          end +        end +        ft=ft.uniq +        filetypes=ft.join(',') +        @filetypes=if filetypes !~/..+/ then ''   # -r called alone, copy all +        elsif @opt.selections.str =~/u/            then ''   # -u added, copy all, (used to create remote directory tree see output path), not the usual function of -u +        elsif filetypes =~/\S+?,\S+/    then '*{' + filetypes + '}' # more than one relevant file type +        else                                 '*' + filetypes # one relevant file type +        end +        @source_path=(@fnb && !(@fnb.empty?) \ +        ? "#{@env.path.output}/#{@fnb}" +        : @env.path.output) +        @source_path_epub=(@fnb && !(@fnb.empty?) \ +        ? "#{@env.path.output}/epub" +        : @env.path.output_epub) +        @source_path_src=(@fnb && !(@fnb.empty?) \ +        ? "#{@env.path.output}/src" +        : @env.path.output_src) +        @source_path_pod=(@fnb && !(@fnb.empty?) \ +        ? "#{@env.path.output}/pod" +        : @env.path.output_pod) +        @source_path_harvest=(@fnb && !(@fnb.empty?) \ +        ? "#{@env.path.output}/manifest" +        : @env.path.output_harvest) +        @local_sisu_source=(@filetypes =~/\S/) \ +        ? "#{@source_path}/#{@filetypes}" +        : @source_path +      end +      if @opt.act[:rsync][:set]==:on +      end +    end +  end +end +__END__ +#+END_SRC + +** se_file_op.rb + +#+BEGIN_SRC ruby  :tangle "../lib/sisu/se_file_op.rb" +# <<sisu_document_header>> +module SiSU_Info_File +  require_relative 'utils'                                 # utils.rb +  require_relative 'se_info_env'                           # se_info_env.rb +  begin +    require 'fileutils' +      include FileUtils::Verbose +  rescue LoadError +    SiSU_Utils::CodeMarker.new(__LINE__,__FILE__,:fuchsia). +      error('fileutils NOT FOUND (LoadError)') +  end +  class InfoFile < SiSU_Info_Env::InfoEnv                  # se_info_env.rb +    #todo unify with FileOp +    def initialize(fns) +      begin +        super(fns) +        @fns=fns +        @env=SiSU_Env::InfoEnv.new(@fns) +        m=/((.+?)(?:\~\w\w(?:_\w\w)?)?)\.((?:-|ssm\.)?sst|ssm)$/ +        @fnn,@fnb,@fnt=@fns[m,1],@fns[m,2],@fns[m,3] +      rescue +        SiSU_Screen::Ansi.new('',$!,$@).rescue do +          __LINE__.to_s + ':' + __FILE__ +        end +      ensure +      end +    end +    def basefilename #Remove if possible +      m=/(.+?)\.(?:(?:-|ssm\.)?sst|ssm)$/m +      @fns[m,1] +    end +    def make_file(path,filename) +      (File.writable?("#{path}/.")) \ +      ? File.new("#{path}/#{filename}",'w+') +      : (SiSU_Screen::Ansi.new( +          '', +          "*WARN* is the file or directory writable?, could not create #{filename}" +        ).warn) +    end +    def touch_file(path,filename) +      if File.writable?("#{path}/."); +        FileUtils::touch("#{path}/#{filename}") +      else +        SiSU_Screen::Ansi.new( +          '', +          "*WARN* is the file or directory writable?, could not create #{filename}" +        ).warn +      end +    end +    def make_path(path) +      FileUtils::mkdir_p(path) unless FileTest.directory?(path) +    end +    def marshal +      def ao_content +        @env.processing_path.ao + '/' \ +          + @fns + '.content.rbm' +      end +      def ao_idx_sst_rel_html_seg +        @env.processing_path.ao + '/' \ +          + @fns + '.idx_sst.rbm' +      end +      def ao_idx_sst_rel #used by tex & odf +        @env.processing_path.ao + '/' \ +          + @fns + '.idx_raw.rbm' +      end +      def ao_idx_html +        @env.processing_path.ao + '/' \ +          + @fns + '.idx_html.rbm' +      end +      def ao_idx_xhtml +        @env.processing_path.ao + '/' \ +          + @fns + '.idx_xhtml.rbm' +      end +      def ao_metadata +        @env.processing_path.ao + '/' \ +          + @fns + '.metadata.rbm' +      end +      def ao_map_nametags +        @env.processing_path.ao + '/' \ +          + @fns + '.map_name_tags.rbm' +      end +      def ao_map_ocn_htmlseg +        @env.processing_path.ao + '/' \ +          + @fns + '.map_ocn_htmlseg.rbm' +      end +      def html_tune +        @env.processing_path.tune + '/' \ +          + @fns + '.marshal_tune' +      end +      def xhtml_tune +        @env.processing_path.tune + '/' \ +          + @fns + '.marshal_tune' +      end +      self +    end +    def write_file_processing +      def html_tune +        File.new("#{@env.processing_path.tune}/#{@fns}.tune",'w+') +      end +      self +    end +    def mkdir #check moved from FileOp, existing mkdir +      def processing +        def ao +          FileUtils::mkdir_p(@env.processing_path.ao) \ +            unless FileTest.directory?(@env.processing_path.ao) +        end +        def tune +          FileUtils::mkdir_p(@env.processing_path.tune) \ +            unless FileTest.directory?(@env.processing_path.tune) +        end +        self +      end +    end +  end +end +module SiSU_File_Op +  require_relative 'constants'                             # constants.rb +  require_relative 'utils'                                 # utils.rb +  begin +    require 'fileutils' +      include FileUtils::Verbose +  rescue LoadError +    SiSU_Utils::CodeMarker.new(__LINE__,__FILE__,:fuchsia). +      error('fileutils NOT FOUND (LoadError)') +  end +  class FileOp < SiSU_Info_File::InfoFile +    #todo unify with CreateFile +    def initialize(md,fno='') +      begin +        @md,@fno=md,fno +        @env=SiSU_Env::InfoEnv.new(@md.fns) +      rescue +        SiSU_Screen::Ansi.new(md.opt.selections.str,$!,$@).rescue do +          __LINE__.to_s + ':' + __FILE__ +        end +      ensure +      end +    end +    def output_dir_structure +      SiSU_Env::ProcessingSettings.new(@md).output_dir_structure +    end +    def mkdir_initialize                # not used but consider using +      FileUtils::mkdir_p(output_path.base.dir) \ +        unless FileTest.directory?(output_path.base.dir) +      FileUtils::mkdir_p("#{output_path.base.dir}/#{@md.fnb}") \ +        unless FileTest.directory?("#{output_path.base.dir}/#{@md.fnb}") +      FileUtils::mkdir_p("#{output_path.base.dir}/#{@env.path.style}") \ +        unless FileTest.directory?("#{output_path.base.dir}/#{@env.path.style}") +      FileUtils::mkdir_p(@env.processing_path.ao) \ +        unless FileTest.directory?(@env.processing_path.ao) +      FileUtils::mkdir_p(@env.processing_path.tune) \ +        unless FileTest.directory?(@env.processing_path.tune) +    end +    def path_rel_links +      def html_scroll_2 +        if output_dir_structure.by_language_code? +          '../../' +        elsif output_dir_structure.by_filetype? +          '../' +        else +          '../' +        end +      end +      def html_seg_2 +        if output_dir_structure.by_language_code? +          '../../../' +        elsif output_dir_structure.by_filetype? +          '../../' +        else +          '../' +        end +      end +      def html_scroll_1 +        if output_dir_structure.by_language_code? +          '../' +        elsif output_dir_structure.by_filetype? +          '../' +        else +          './' +        end +      end +      def html_seg_1 +        if output_dir_structure.by_language_code? +          '../../' +        elsif output_dir_structure.by_filetype? +          '../../' +        else +          './' +        end +      end +      def default_output_css +        if (@md.opt.opt_act[:dump][:bool] \ +        &&  @md.opt.opt_act[:dump][:inst]) \ +        || (@md.opt.opt_act[:redirect][:bool] \ +        &&  @md.opt.opt_act[:redirect][:inst]) +          './' +        elsif output_dir_structure.by_language_code? +          '../../' +        elsif output_dir_structure.by_filetype? +          '../' +        else +          '../' +        end +      end +      def html_scroll_css +        default_output_css +      end +      def xhtml_css +        default_output_css +      end +      def xml_css +        default_output_css +      end +      def html_seg_css +        if output_dir_structure.by_language_code? +          '../../../' +        elsif output_dir_structure.by_filetype? +          '../../' +        else +          '../' +        end +      end +      def manifest_css +        if output_dir_structure.by_language_code? +          '../../_sisu/css' +        elsif output_dir_structure.by_filetype? +          '' +        else +          '../' +        end +      end +      self +    end +    def mkdir +      def output +        def base +          FileUtils::mkdir_p(output_path.base.dir) \ +            unless FileTest.directory?(output_path.base.dir) +        end +        def css +          FileUtils::mkdir_p("#{output_path.base.dir}/#{@env.path.style}") \ +            unless FileTest.directory?("#{output_path.base.dir}/#{@env.path.style}") +        end +        def epub +          path=output_path.epub.dir +          make_path(path) +        end +        self +      end +      self +    end +    def mkfile #consider using more +      path="#{output_path.base.dir}/#{@md.fnb}" +      make_path(path) +      filename=@fno +      make_file(path,filename) +    end +    def mkfile_pwd +      path=Dir.pwd +      filename=@fno +      make_file(path,filename) +    end +    def write_file +      def txt +        path=output_path.txt.dir +        make_path(path) +        fn=base_filename.txt +        make_file(path,fn) +      end +      def textile +        path=output_path.textile.dir +        make_path(path) +        fn=base_filename.textile +        make_file(path,fn) +      end +      def asciidoc +        path=output_path.asciidoc.dir +        make_path(path) +        fn=base_filename.asciidoc +        make_file(path,fn) +      end +      def markdown +        path=output_path.markdown.dir +        make_path(path) +        fn=base_filename.markdown +        make_file(path,fn) +      end +      def rst +        path=output_path.rst.dir +        make_path(path) +        fn=base_filename.rst +        make_file(path,fn) +      end +      def orgmode +        path=output_path.orgmode.dir +        make_path(path) +        fn=base_filename.orgmode +        make_file(path,fn) +      end +      def html_scroll +        pth=output_path.html.dir +        make_path(pth) +        p_fn=place_file.html_scroll.dir +        File.new(p_fn,'w+') +      end +      def html_seg_index +        pth=((output_dir_structure.by_filename?) \ +        || (output_dir_structure.dump?)) \ +        ? "#{output_path.html.dir}" +        : "#{output_path.html.dir}/#{@md.fnb}" +        make_path(pth) +        p_fn=place_file.html_seg_index.dir +        File.new(p_fn,'w+') +      end +      def html_segtoc +        pth=((output_dir_structure.by_filename?) \ +        || (output_dir_structure.dump?) \ +        || (output_dir_structure.redirect?)) \ +        ? "#{output_path.html.dir}" +        : "#{output_path.html.dir}/#{@md.fnb}" +        make_path(pth) +        p_fn=place_file.html_segtoc.dir +        File.new(p_fn,'w+') +      end +      def xhtml +        path=output_path.xhtml.dir +        make_path(path) +        fn=base_filename.xhtml +        make_file(path,fn) +      end +      def xml_sax +        path=output_path.xml.dir +        make_path(path) +        fn=base_filename.xml_sax +        make_file(path,fn) +      end +      def xml_dom +        path=output_path.xml.dir +        make_path(path) +        fn=base_filename.xml_dom +        make_file(path,fn) +      end +      def xml_docbook_book +        path=output_path.xml_docbook_book.dir +        make_path(path) +        fn=base_filename.xml_docbook_book +        make_file(path,fn) +      end +      def xml_fictionbook +        path=output_path.xml_fictionbook.dir +        make_path(path) +        fn=base_filename.xml_fictionbook +        make_file(path,fn) +      end +      def xml_scaffold_structure_sisu +        path=output_path.xml_scaffold_structure_sisu.dir +        make_path(path) +        fn=base_filename.xml_scaffold_structure_sisu +        make_file(path,fn) +      end +      def xml_scaffold_structure_collapse +        path=output_path.xml_scaffold_structure_collapse.dir +        make_path(path) +        fn=base_filename.xml_scaffold_structure_collapse +        make_file(path,fn) +      end +      def json +        path=output_path.json.dir +        make_path(path) +        fn=base_filename.json +        make_file(path,fn) +      end +      def manpage +        path=output_path.manpage.dir +        make_path(path) +        fn=base_filename.manpage +        make_file(path,fn) +      end +      def texinfo +        path=output_path.texinfo.dir +        make_path(path) +        fn=base_filename.texinfo +        make_file(path,fn) +      end +      def info +        path=output_path.texinfo.dir +        make_path(path) +        fn=base_filename.info +        make_file(path,fn) +      end +      def hash_digest +        path=output_path.hash_digest.dir +        make_path(path) +        fn=base_filename.hash_digest +        make_file(path,fn) +      end +      def qrcode +        path=output_path.qrcode.dir +        make_path(path) +        fn=base_filename.qrcode +        make_file(path,fn) +      end +      def manifest +        path=output_path.manifest.dir +        make_path(path) +        fn=base_filename.manifest +        make_file(path,fn) +      end +      def manifest_txt +        path=output_path.manifest.dir +        make_path(path) +        fn=base_filename.manifest_txt +        make_file(path,fn) +      end +      def po4a_cfg +        path=output_path.po4a.dir +        make_path(path) +        fn=base_filename.po4a_cfg +        make_file(path,fn) +      end +      def pot +        path=output_path.pot.dir +        make_path(path) +        fn=base_filename.pot +        make_file(path,fn) +      end +      def po(lng=@md.opt.lng) +        path=output_path.po(lng).dir +        make_path(path) +        fn=base_filename.po +        make_file(path,fn) +      end +      def po4a_sst(lng=@md.opt.lng) +        path=output_path.po4a_sst(lng).dir +        make_path(path) +        fn=base_filename.po4a_sst +        make_file(path,fn) +      end +      self +    end +    def place_file +      def txt +        def dir +          output_path.txt.dir + '/' \ +          + base_filename.txt +        end +        def rel +          output_path.txt.rel + '/' \ +          + base_filename.txt +        end +        self +      end +      def textile +        def dir +          output_path.textile.dir + '/' \ +          + base_filename.textile +        end +        def rel +          output_path.textile.rel + '/' \ +          + base_filename.textile +        end +        self +      end +      def asciidoc +        def dir +          output_path.asciidoc.dir + '/' \ +          + base_filename.asciidoc +        end +        def rel +          output_path.asciidoc.rel + '/' \ +          + base_filename.asciidoc +        end +        self +      end +      def markdown +        def dir +          output_path.markdown.dir + '/' \ +          + base_filename.markdown +        end +        def rel +          output_path.markdown.rel + '/' \ +          + base_filename.markdown +        end +        self +      end +      def rst +        def dir +          output_path.rst.dir + '/' \ +          + base_filename.rst +        end +        def rel +          output_path.rst.rel + '/' \ +          + base_filename.rst +        end +        self +      end +      def orgmode +        def dir +          output_path.orgmode.dir + '/' \ +          + base_filename.orgmode +        end +        def rel +          output_path.orgmode.rel + '/' \ +          + base_filename.orgmode +        end +        self +      end +      def html_scroll +        def dir +          output_path.html_scroll.dir + '/' \ +          + base_filename.html_scroll +        end +        def rel +          output_path.html_scroll.rel + '/' \ +          + base_filename.html_scroll +        end +        self +      end +      def html_seg_index +        def dir +          output_path.html_seg.dir + '/' \ +          + base_filename.html_seg_index +        end +        def rel +          output_path.html_seg.rel + '/' \ +          + base_filename.html_seg_index +        end +        self +      end +      def html_segtoc +        def dir +          output_path.html_seg.dir + '/' \ +          + base_filename.html_segtoc +        end +        def rel +          output_path.html_seg.rel + '/' \ +          + base_filename.html_segtoc +        end +        self +      end +      def html_book_index +        def dir +          output_path.html_seg.dir + '/' \ +          + base_filename.html_book_index +        end +        def rel +          output_path.html_seg.rel + '/' \ +          + base_filename.html_book_index +        end +        self +      end +      def html_concordance +        def dir +          output_path.html_seg.dir + '/' \ +          + base_filename.html_concordance +        end +        def rel +          output_path.html_seg.rel + '/' \ +          + base_filename.html_concordance +        end +        self +      end +      def odt +        def dir +          output_path.odt.dir + '/' \ +          + base_filename.odt +        end +        def rel +          output_path.odt.rel + '/' \ +          + base_filename.odt +        end +        self +      end +      def epub +        def dir +          output_path.epub.dir + '/' \ +          + base_filename.epub +        end +        def rel +          output_path.epub.rel + '/' \ +          + base_filename.epub +        end +        self +      end +      def pdf_p +        STDERR.puts 'ERROR not available due to multiple page format sizes' +      end +      def pdf_l +        STDERR.puts 'ERROR not available due to multiple page format sizes' +      end +      def xhtml +        def dir +          output_path.xhtml.dir + '/' \ +          + base_filename.xhtml +        end +        def rel +          output_path.xhtml.rel + '/' \ +          + base_filename.xhtml +        end +        self +      end +      def xml_sax +        def dir +          output_path.xml.dir + '/' \ +          + base_filename.xml_sax +        end +        def rel +          output_path.xml.rel + '/' \ +          + base_filename.xml_sax +        end +        self +      end +      def xml_dom +        def dir +          output_path.xml.dir + '/' \ +          + base_filename.xml_dom +        end +        def rel +          output_path.xml.rel + '/' \ +          + base_filename.xml_dom +        end +        self +      end +      def xml_docbook_book +        def dir +          output_path.xml_docbook.dir + '/' \ +          + base_filename.xml_docbook_book +        end +        def rel +          output_path.xml_docbook.rel + '/' \ +          + base_filename.xml_docbook_book +        end +        self +      end +      def xml_fictionbook +        def dir +          output_path.xml_fictionbook.dir + '/' \ +          + base_filename.xml_fictionbook +        end +        def rel +          output_path.xml_fictionbook.rel + '/' \ +          + base_filename.xml_fictionbook +        end +        self +      end +      def xml_scaffold_structure_sisu +        def dir +          output_path.xml.dir + '/' \ +          + base_filename.xml_scaffold_structure_sisu +        end +        def rel +          output_path.xml.rel + '/' \ +          + base_filename.xml_scaffold_structure_sisu +        end +        self +      end +      def xml_scaffold_structure_collapse +        def dir +          output_path.xml.dir + '/' \ +          + base_filename.xml_scaffold_structure_collapse +        end +        def rel +          output_path.xml.rel + '/' \ +          + base_filename.xml_scaffold_structure_collapse +        end +        self +      end +      def json +        def dir +          output_path.json.dir + '/' \ +          + base_filename.json +        end +        def rel +          output_path.json.rel + '/' \ +          + base_filename.json +        end +        self +      end +      def sqlite_discrete +        def dir +          output_path.sqlite_discrete.dir + '/' \ +          + base_filename.sqlite_discrete +        end +        def rel +          output_path.sqlite_discrete.rel + '/' \ +          + base_filename.sqlite_discrete +        end +        self +      end +      def hash_digest +        def dir +          output_path.hash_digest.dir + '/' \ +          + base_filename.hash_digest +        end +        def rel +          output_path.hash_digest.rel + '/' \ +          + base_filename.hash_digest +        end +        self +      end +      def src +        def dir +          output_path.src.dir + '/' \ +            + base_filename.src +        end +        def rel +          output_path.src.rel + '/' \ +          + base_filename.src +        end +        self +      end +      def sisupod +        def dir +          output_path.sisupod.dir + '/' \ +          + base_filename.sisupod +        end +        def rel +          output_path.sisupod.rel + '/' \ +          + base_filename.sisupod +        end +        self +      end +      def po +        def dir +          output_path.po.dir + '/' \ +          + base_filename.po +        end +        def rel +          output_path.po.rel + '/' \ +          + base_filename.po +        end +        self +      end +      def pot +        def dir +          output_path.pot.dir + '/' \ +          + base_filename.pot +        end +        def rel +          output_path.pot.rel + '/' \ +          + base_filename.pot +        end +        self +      end +      def po_git +        def dir +          output_path.po_git + '/' \ +          + base_filename.po +        end +        def rel +          #output_path.po_git + '/' + base_filename.po +        end +        self +      end +      def pot_git +        def dir +          output_path.pot_git + '/' \ +          + base_filename.pot +        end +        def rel +          #output_path.pot_git + '/' + base_filename.pot +        end +        self +      end +      def manpage +        def dir +          output_path.manpage.dir + '/' \ +          + base_filename.manpage +        end +        def rel +          output_path.manpage.rel + '/' \ +          + base_filename.manpage +        end +        self +      end +      def texinfo +        def dir +          output_path.texinfo.dir + '/' \ +          + base_filename.texinfo +        end +        def rel +          output_path.texinfo.rel + '/' \ +          + base_filename.texinfo +        end +        self +      end +      def info +        def dir +          output_path.texinfo.dir + '/' \ +          + base_filename.info +        end +        def rel +          output_path.texinfo.rel + '/' \ +          + base_filename.info +        end +        self +      end +      def qrcode_title +        def dir +          output_path.qrcode.dir + '/' \ +          + base_filename.qrcode_title +        end +        def rel +          output_path.qrcode.rel + '/' \ +          + base_filename.qrcode_title +        end +        self +      end +      def qrcode_md +        def dir +          output_path.qrcode.dir + '/' \ +          + base_filename.qrcode_md +        end +        def rel +          output_path.qrcode.rel + '/' \ +          + base_filename.qrcode_md +        end +        self +      end +      def manifest +        def dir +          output_path.manifest.dir + '/' \ +            + base_filename.manifest +        end +        def rel +          output_path.manifest.rel + '/' \ +            + base_filename.manifest +        end +        self +      end +      self +    end +    def base_filename +      def i18n(f) +        f=default_hash.merge(f) +        f[:lng] ||=@md.lang_code_insert +        f[:fn] + f[:lng] + f[:ft] +      end +      def default_hash +        { +          fn: @md.fnb, +          lng: @md.lang_code_insert, +        } +      end +      def default_hash_build(fh,sfx) +        if fh.is_a?(Hash) +          fh[:fn] ||=@md.fnb +          fh[:lng] ||= @md.lang_code_insert +          fh[:ft]=sfx +          fh +        else +          { +            fn: @md.fnb, +            lng: @md.lang_code_insert, +            ft: sfx, +          } +        end +      end +      def lang_code?(lng) +        (output_dir_structure.by_language_code?) \ +        ? '' +        : (lng ||=@md.lang_code_insert) +      end +      def txt(fh=nil) +        fh=default_hash_build(fh,Sfx[:txt]) +        fh[:lng]=lang_code?(fh[:lng]) +        fnh=if output_dir_structure.by_filename? +          { +            fn: 'plain', +            ft: fh[:ft], +            lng: fh[:lng], +           } +         else +          { +            fn: fh[:fn], +            ft: fh[:ft], +            lng: fh[:lng], +          } +        end +        i18n(fnh) +      end +      def textile(fh=nil) +        fh=default_hash_build(fh,Sfx[:txt_textile]) +        fh[:lng]=lang_code?(fh[:lng]) +        fnh=if output_dir_structure.by_filename? +          { +            fn: 'plain', +            ft: fh[:ft], +            lng: fh[:lng], +           } +         else +          { +            fn: fh[:fn], +            ft: fh[:ft], +            lng: fh[:lng], +          } +        end +        i18n(fnh) +      end +      def asciidoc(fh=nil) +        fh=default_hash_build(fh,Sfx[:txt_asciidoc]) +        fh[:lng]=lang_code?(fh[:lng]) +        fnh=if output_dir_structure.by_filename? +          { +            fn: 'plain', +            ft: fh[:ft], +            lng: fh[:lng], +           } +         else +          { +            fn: fh[:fn], +            ft: fh[:ft], +            lng: fh[:lng], +          } +        end +        i18n(fnh) +      end +      def markdown(fh=nil) +        fh=default_hash_build(fh,Sfx[:txt_markdown]) +        fh[:lng]=lang_code?(fh[:lng]) +        fnh=if output_dir_structure.by_filename? +          { +            fn: 'plain', +            ft: fh[:ft], +            lng: fh[:lng], +           } +         else +          { +            fn: fh[:fn], +            ft: fh[:ft], +            lng: fh[:lng], +          } +        end +        i18n(fnh) +      end +      def rst(fh=nil) +        fh=default_hash_build(fh,Sfx[:txt_rst]) +        fh[:lng]=lang_code?(fh[:lng]) +        fnh=if output_dir_structure.by_filename? +          { +            fn: 'plain', +            ft: fh[:ft], +            lng: fh[:lng], +           } +         else +          { +            fn: fh[:fn], +            ft: fh[:ft], +            lng: fh[:lng], +          } +        end +        i18n(fnh) +      end +      def orgmode(fh=nil) +        fh=default_hash_build(fh,Sfx[:txt_orgmode]) +        fh[:lng]=lang_code?(fh[:lng]) +        fnh=if output_dir_structure.by_filename? +          { +            fn: 'plain', +            ft: fh[:ft], +            lng: fh[:lng], +           } +         else +          { +            fn: fh[:fn], +            ft: fh[:ft], +            lng: fh[:lng], +          } +        end +        i18n(fnh) +      end +      def html_scroll(fh=nil) +        fh=default_hash_build(fh,Sfx[:html]) +        fh[:lng]=lang_code?(fh[:lng]) +        fnh=if output_dir_structure.by_filename? +          { +            fn: 'scroll', +            ft: fh[:ft], +            lng: fh[:lng], +          } +        else +          { +            fn: fh[:fn], +            ft: fh[:ft], +            lng: fh[:lng], +          } +        end +        i18n(fnh) +      end +      def html_seg_index(fh=nil) +        fh=default_hash_build(fh,Sfx[:html]) +        fh[:lng]=lang_code?(fh[:lng]) +        fnh={ +          fn: 'index', +          ft: fh[:ft], +          lng: fh[:lng], +        } +        i18n(fnh) +      end +      def html_segtoc(fh=nil) +        fh=default_hash_build(fh,Sfx[:html]) +        fnh=if output_dir_structure.dump_or_redirect? +          { +            fn: fh[:fn] + '.toc', +            ft: fh[:ft], +          } +        else +          { +            fn: 'toc', +            ft: fh[:ft], +            lng: lang_code?(fh[:lng]), +          } +        end +        i18n(fnh) +      end +      def html_seg(fh) +        fh=default_hash_build(fh,Sfx[:html]) +        fh[:lng]=lang_code?(fh[:lng]) +        fnh={ +          fn: fh[:fn], +          ft: fh[:ft], +          lng: fh[:lng], +        } +        i18n(fnh) +      end +      def html_book_index(fh=nil) +        fh=default_hash_build(fh,Sfx[:html]) +        fh[:lng]=lang_code?(fh[:lng]) +        fnh={ +          fn: 'book_index', +          ft: fh[:ft], +          lng: fh[:lng], +        } +        i18n(fnh) +      end +      def html_concordance(fh=nil) +        fh=default_hash_build(fh,Sfx[:html]) +        fh[:lng]=lang_code?(fh[:lng]) +        fnh=if output_dir_structure.dump_or_redirect? +          { +            fn: 'concordance', +            ft: fh[:ft], +          } +        else +          { +            fn: 'concordance', +            ft: fh[:ft], +            lng: fh[:lng], +          } +        end +        i18n(fnh) +      end +      def xhtml(fh=nil) +        fh=default_hash_build(fh,Sfx[:xhtml]) +        fh[:lng]=lang_code?(fh[:lng]) +        fnh=if output_dir_structure.by_filename? +          { +            fn: 'scroll', +            ft: fh[:ft], +            lng: fh[:lng], +          } +        else +          { +            fn: fh[:fn], +            ft: fh[:ft], +            lng: fh[:lng], +          } +        end +        i18n(fnh) +      end +      def epub(fh=nil) +        fh=default_hash_build(fh,Sfx[:epub]) +        fh[:lng]=lang_code?(fh[:lng]) +        fnh={ +          fn: fh[:fn], +          ft: fh[:ft], +          lng: fh[:lng], +        } +        i18n(fnh) +      end +      def odt(fh=nil) +        fh=default_hash_build(fh,Sfx[:odt]) +        fh[:lng]=lang_code?(fh[:lng]) +        fnh=if output_dir_structure.by_filename? +          { +            fn: 'opendocument', +            ft: fh[:ft], +            lng: fh[:lng], +          } +        else +          { +            fn: fh[:fn], +            ft: fh[:ft], +            lng: fh[:lng], +          } +        end +        i18n(fnh) +      end +      def xml_sax(fh=nil) +        fh=default_hash_build(fh,Sfx[:xml_sax]) +        fh[:lng]=lang_code?(fh[:lng]) +        fnh=if output_dir_structure.by_filename? +          { +            fn: 'scroll', +            ft: fh[:ft], +            lng: fh[:lng], +          } +        else +          { +            fn: fh[:fn], +            ft: fh[:ft], +            lng: fh[:lng], +          } +        end +        i18n(fnh) +      end +      def xml_dom(fh=nil) +        fh=default_hash_build(fh,Sfx[:xml_dom]) +        fh[:lng]=lang_code?(fh[:lng]) +        fnh=if output_dir_structure.by_filename? +          { +            fn: 'scroll', +            ft: fh[:ft], +            lng: fh[:lng], +          } +        else +          { +            fn: fh[:fn], +            ft: fh[:ft], +            lng: fh[:lng], +          } +        end +        i18n(fnh) +      end +      def xml_docbook_book(fh=nil) +        fh=default_hash_build(fh,Sfx[:xml_docbook_book]) +        fh[:lng]=lang_code?(fh[:lng]) +        fnh=if output_dir_structure.by_filename? +          { +            fn: 'scroll', +            ft: fh[:ft], +            lng: fh[:lng], +          } +        else +          { +            fn: fh[:fn], +            ft: fh[:ft], +            lng: fh[:lng], +          } +        end +        i18n(fnh) +      end +      def xml_fictionbook(fh=nil) +        fh=default_hash_build(fh,Sfx[:xml_fictionbook]) +        fh[:lng]=lang_code?(fh[:lng]) +        fnh=if output_dir_structure.by_filename? +          { +            fn: 'scroll', +            ft: fh[:ft], +            lng: fh[:lng], +          } +        else +          { +            fn: fh[:fn], +            ft: fh[:ft], +            lng: fh[:lng], +          } +        end +        i18n(fnh) +      end +      def xml_scaffold_structure_sisu(fh=nil) +        fh=default_hash_build(fh,Sfx[:xml_scaffold_structure_sisu]) +        fh[:lng]=lang_code?(fh[:lng]) +        fnh=if output_dir_structure.by_filename? +          { +            fn: 'scroll', +            ft: fh[:ft], +            lng: fh[:lng], +          } +        else +          { +            fn: fh[:fn], +            ft: fh[:ft], +            lng: fh[:lng], +          } +        end +        i18n(fnh) +      end +      def xml_scaffold_structure_collapse(fh=nil) +        fh=default_hash_build(fh,Sfx[:xml_scaffold_structure_collapse]) +        fh[:lng]=lang_code?(fh[:lng]) +        fnh=if output_dir_structure.by_filename? +          { +            fn: 'scroll', +            ft: fh[:ft], +            lng: fh[:lng], +          } +        else +          { +            fn: fh[:fn], +            ft: fh[:ft], +            lng: fh[:lng], +          } +        end +        i18n(fnh) +      end +      def json(fh=nil) +        fh=default_hash_build(fh,Sfx[:json]) +        fh[:lng]=lang_code?(fh[:lng]) +        fnh=if output_dir_structure.by_filename? +          { +            fn: 'scroll', +            ft: fh[:ft], +            lng: fh[:lng], +          } +        else +          { +            fn: fh[:fn], +            ft: fh[:ft], +            lng: fh[:lng], +          } +        end +        i18n(fnh) +      end +      def pdf_p(fh=nil) +        fh=default_hash_build(fh,Sfx[:pdf]) +        fh[:lng]=lang_code?(fh[:lng]) +        if output_dir_structure.by_filename? +          'portrait' + fh[:lng] + '.' +        else +          fh[:fn] + '.portrait' + fh[:lng] + '.' +        end +      end +      def pdf_l(fh=nil) +        fh=default_hash_build(fh,Sfx[:pdf]) +        fh[:lng]=lang_code?(fh[:lng]) +        if output_dir_structure.by_filename? +          'landscape' + fh[:lng] + '.' +        else +          fh[:fn] + '.landscape' + fh[:lng] + '.' +        end +      end +      def pdf_p_a4(fh=nil) +        pdf_p(fh) + @md.fn[:pdf_p_a4] +      end +      def pdf_p_a5(fh=nil) +        pdf_p(fh) + @md.fn[:pdf_p_a5] +      end +      def pdf_p_b5(fh=nil) +        pdf_p(fh) + @md.fn[:pdf_p_b5] +      end +      def pdf_p_letter(fh=nil) +        pdf_p(fh) + @md.fn[:pdf_p_letter] +      end +      def pdf_p_legal(fh=nil) +        pdf_p(fh) + @md.fn[:pdf_p_legal] +      end +      def pdf_l_a4(fh=nil) +        pdf_l(fh) + @md.fn[:pdf_l_a4] +      end +      def pdf_l_a5(fh=nil) +        pdf_l(fh) + @md.fn[:pdf_l_a5] +      end +      def pdf_l_b5(fh=nil) +        pdf_l(fh) + @md.fn[:pdf_l_b5] +      end +      def pdf_l_letter(fh=nil) +        pdf_l(fh) + @md.fn[:pdf_l_letter] +      end +      def pdf_l_legal(fh=nil) +        pdf_l(fh) + @md.fn[:pdf_l_legal] +      end +      def manpage(fh=nil) +        fh=default_hash_build(fh,Sfx[:manpage]) +        fh[:lng]=lang_code?(fh[:lng]) +        fnh={ +          fn: fh[:fn], +          ft: fh[:ft], +          lng: fh[:lng], +        } +        i18n(fnh) +      end +      def info(fh=nil) +        fh=default_hash_build(fh,Sfx[:info]) +        fh[:lng]=lang_code?(fh[:lng]) +        fnh={ +          fn: fh[:fn], +          ft: fh[:ft], +          lng: fh[:lng], +        } +        i18n(fnh) +      end +      def texinfo(fh=nil) +        fh=default_hash_build(fh,Sfx[:texinfo]) +        fh[:lng]=lang_code?(fh[:lng]) +        fnh={ +          fn: fh[:fn], +          ft: fh[:ft], +          lng: fh[:lng], +        } +        i18n(fnh) +      end +      def sqlite_discrete(fh=nil) +        fh=default_hash_build(fh,Sfx[:sql]) +        fh[:lng]=lang_code?(fh[:lng]) +        fnh={ +          fn: fh[:fn], +          ft: fh[:ft], +          lng: fh[:lng], +        } +        i18n(fnh) +      end +      def hash_digest(fh=nil) +        fh=default_hash_build(fh,Sfx[:txt]) +        fh[:lng]=lang_code?(fh[:lng]) +        fnh=if output_dir_structure.by_language_code? +          { +            fn: fh[:fn] + '.hash_digest', +            ft: fh[:ft], +          } +        elsif output_dir_structure.by_filetype? +          { +            fn: fh[:fn], +            ft: fh[:ft], +            lng: fh[:lng], +          } +        else +          { +            fn: 'digest', +            ft: fh[:ft], +            lng: fh[:lng], +          } +        end +        i18n(fnh) +      end +      def sitemap(fh=nil) +        fh=default_hash_build(fh,Sfx[:xml]) +        fh[:lng]=lang_code?(fh[:lng]) +        fnh=if output_dir_structure.by_language_code? +          { +            fn: fh[:fn] + '.sitemap', +            ft: fh[:ft], +          } +        elsif output_dir_structure.by_filetype? +          { +            fn: fh[:fn], +            ft: fh[:ft], +            lng: fh[:lng], +          } +        else +          { +            fn: 'sitemap', +            ft: fh[:ft], +            lng: fh[:lng], +          } +        end +        i18n(fnh) +      end +      def qrcode_title(fh=nil) +        fh=default_hash_build(fh,'.title.png') +        fh[:lng]=lang_code?(fh[:lng]) +        fnh=if output_dir_structure.by_filename? +          { +            fn: 'sisu_manifest', +            ft: fh[:ft], +            lng: fh[:lng], +          } +        else +          { +            fn: fh[:fn], +            ft: fh[:ft], +            lng: fh[:lng], +          } +        end +        i18n(fnh) +      end +      def qrcode_md #check name below +        fh=default_hash_build(fh,'.md.png') +        fh[:lng]=lang_code?(fh[:lng]) +        fnh=if output_dir_structure.by_filename? +          { +            fn: 'sisu_manifest', +            ft: fh[:ft], +            lng: fh[:lng], +          } +        else +          { +            fn: fh[:fn], +            ft: fh[:ft], +            lng: fh[:lng], +          } +        end +        i18n(fnh) +      end +      def manifest_txt(fh=nil) +        fh=default_hash_build(fh,Sfx[:txt]) +        fh[:lng]=lang_code?(fh[:lng]) +        fnh=if output_dir_structure.by_filename? +          { +            fn: 'sisu_manifest', +            ft: fh[:ft], +            lng: fh[:lng], +          } +        else +          { +            fn: fh[:fn], +            ft: fh[:ft], +            lng: fh[:lng], +          } +        end +        i18n(fnh) +      end +      def manifest(fh=nil) +        fh=default_hash_build(fh,Sfx[:html]) +        fh[:lng]=lang_code?(fh[:lng]) +        fnh=if output_dir_structure.dump_or_redirect? +          { +            fn: fh[:fn] + '.manifest', +            ft: fh[:ft], +            lng: fh[:lng], +          } +        elsif output_dir_structure.by_filename? +          { +            fn: 'sisu_manifest', +            ft: fh[:ft], +            lng: fh[:lng], +          } +        else +          { +            fn: fh[:fn], +            ft: fh[:ft], +            lng: fh[:lng], +          } +        end +        i18n(fnh) +      end +      def src +        @md.fno +      end +      def po4a_cfg +        'po4a.cfg' +      end +      def po #check +        (@fno.empty?) \ +        ? (@md.fn[:po]) +        : (@fno + '.po') +      end +      def pot +        (@fno.empty?) \ +        ? (@md.fn[:pot]) +        : (@fno + '.pot') +      end +      def po4a_sst #check +        @fno +      end +      def sisupod +        (@md.fns =~/\.ssm\.sst$/) \ +        ? @md.fns.gsub(/(?:\~\S{2,3})?\.ssm\.sst$/,'.ssm.txz') +        : @md.fns.gsub(/(?:\~\S{2,3})?(\.sst)$/,'\1.txz') +      end +      self +    end +    def set_path(ft) +      @ft=ft +      def dir +        def abc +          if output_dir_structure.redirect? +            @md.opt.opt_act[:redirect][:inst] + '/' + @md.fnb +          elsif output_dir_structure.dump? +            @md.opt.opt_act[:dump][:inst] +          elsif output_dir_structure.by_language_code? +            output_path.base.dir + '/' + @md.opt.lng + '/' + @ft +          elsif output_dir_structure.by_filetype? +            output_path.base.dir + '/' + @ft +          else +            output_path.base.dir + '/' + @md.fnb +          end +        end +        def ab +          if output_dir_structure.redirect? +            @md.opt.opt_act[:redirect][:inst] + '/' + @md.fnb +          elsif output_dir_structure.dump? +            @md.opt.opt_act[:dump][:inst] +          elsif output_dir_structure.by_language_code? +            output_path.base.dir + '/' + @md.opt.lng + '/' + @ft +          else +            output_path.base.dir + '/' + @ft +          end +        end +        def ab_src +          if output_dir_structure.redirect? +            @md.opt.opt_act[:redirect][:inst] + '/' + @md.fnb +          elsif output_dir_structure.dump? +            @md.opt.opt_act[:dump][:inst] +          else +            output_path.base.dir + '/' \ +              + @ft + '/' \ +              + @md.opt.fng + '/' \ +              + Gt[:sisupod] + '/' \ +              + Gt[:doc] + '/' \ +              + @md.opt.lng +          end +        end +        def ab_pod +          if output_dir_structure.redirect? +            @md.opt.opt_act[:redirect][:inst] + '/' + @md.fnb +          elsif output_dir_structure.dump? +            @md.opt.opt_act[:dump][:inst] +          else +            output_path.base.dir + '/' + @ft +          end +        end +        self +      end +      def url +        def abc +          if output_dir_structure.by_language_code? +            output_path.base.url + '/' + @md.opt.lng + '/' + @ft +          elsif output_dir_structure.by_filetype? +            output_path.base.url + '/' + @ft +          else +            output_path.base.url + '/' + @md.fnb +          end +        end +        def ab +          if output_dir_structure.by_language_code? +            output_path.base.url + '/' + @md.opt.lng + '/' + @ft +          else +            output_path.base.url + '/' + @ft +          end +        end +        def ab_src +          output_path.base.url + '/' \ +            + @ft + '/' \ +            + @md.opt.fng + '/' \ +            + Gt[:sisupod] + '/' \ +            + Gt[:doc] + '/' \ +            + @md.opt.lng +        end +        def ab_pod +          output_path.base.url + '/' + @ft +        end +        self +      end +      def rel +        def abc +          if output_dir_structure.by_language_code? +            @md.opt.lng + '/' + @ft +          elsif output_dir_structure.by_filetype? +            @ft +          else +            @md.fnb +          end +        end +        def ab +          if output_dir_structure.by_language_code? +            @md.opt.lng + '/' + @ft +          else +            @ft +          end +        end +        def ab_src +          @ft +        end +        def ab_pod +          @ft +        end +        self +      end +      def rel_sm +        def abc +          if output_dir_structure.by_language_code? +            @md.opt.lng + '/' + @ft +          elsif output_dir_structure.by_filetype? +            @ft +          else +            @md.fnb +          end +        end +        def ab +          if output_dir_structure.dump_or_redirect? +            '.' +          elsif output_dir_structure.by_language_code? \ +          or output_dir_structure.by_filetype? +            '../' + @ft +          else '.' +          end +        end +        def ab_src +          locate="#{@ft}/#{@md.opt.fng}/#{Gt[:sisupod]}/#{Gt[:doc]}/#{@md.opt.lng}" +          if output_dir_structure.dump_or_redirect? +            '.' +          elsif output_dir_structure.by_language_code? +            '../../' + locate +          else +            '../' + locate +          end +        end +        def ab_pod +          if output_dir_structure.dump_or_redirect? +            '.' +          elsif output_dir_structure.by_language_code? +            '../../' + @ft +          else +            '../' + @ft +          end +        end +        self +      end +      def rcp +        def abc +          if output_dir_structure.by_language_code? +            output_path.stub.rcp + '/' + @md.opt.lng + '/' + @ft +          elsif output_dir_structure.by_filetype? +            output_path.stub.rcp + '/' + @ft +          else +            output_path.stub.rcp + '/' + @md.fnb +          end +        end +        def ab +          if output_dir_structure.by_language_code? +            output_path.stub.rcp + '/' + @md.opt.lng + '/' + @ft +          else +            output_path.stub.rcp + '/' + @ft +          end +        end +        self +      end +      self +    end +    def output_path +      def web_base +        def dir +          @env.path.webserv +        end +        def url +          #"#{@env.url.root}" +        end +        def rel +          '.' +        end +        def rcp +          '.' +        end +        self +      end +      def stub +        def dir +          @md.opt.f_pth[:pth_stub] +        end +        #def url +        #  "#{@env.url.root}" +        #end +        def rel +          './' + @md.opt.f_pth[:pth_stub] +        end +        def rcp +          @md.opt.f_pth[:pth_stub] +        end +        self +      end +      def webserver_path +        if output_dir_structure.dump? +          @md.opt.opt_act[:dump][:inst] +        elsif output_dir_structure.redirect? +          @md.opt.opt_act[:redirect][:inst] +        else +          @env.path.webserv +        end +      end +      def base +        def dir +          webserver_path + '/' + @md.opt.f_pth[:pth_stub] +        end +        def url +          @env.url.webserv + '/' + @md.opt.f_pth[:pth_stub] +        end +        def rel +          './' + @md.opt.f_pth[:pth_stub] +        end +        def rcp +          './' + @md.opt.f_pth[:pth_stub] +        end +        self +      end +      def sisugit +        def dir +          output_path.base.dir + '/git' +        end +        def url +          output_path.base.url + '/git' +        end +        def rel +          output_path.base.rel + '/git' +        end +        def rcp +          output_path.base.rcp + '/git' +        end +        self +      end +      #def pod +      #  ft='pod' +      #  path=set_path(ft).dir.ab +      #end +      def src +        def ft +          Gt[:src] +        end +        def dir +          set_path(ft).dir.ab_src +        end +        def url +          set_path(ft).url.ab_src +        end +        def rel +          set_path(ft).rel.ab_src +        end +        def rcp +          set_path(ft).rcp.ab_src +        end +        def rel_sm +          set_path(ft).rel_sm.ab_src +        end +        self +      end +      def sisupod +        def ft +          Gt[:src] +        end +        def dir +          set_path(ft).dir.ab_pod +        end +        def url +          set_path(ft).url.ab_pod +        end +        def rel +          set_path(ft).rel.ab_pod +        end +        def rcp +          set_path(ft).rcp.ab_pod +        end +        def rel_sm +          set_path(ft).rel_sm.ab_pod +        end +        self +      end +      def po4a +        def dir +         output_path.base.dir + '/' \ +           + Gt[:src] + '/' \ +           + @md.opt.fng + '/po4a' +        end +        def url +          output_path.base.url + '/po4a/' \ +            + @md.fnb +        end +        def rcp +          #p "#{output_path.base.dir}/po4a/#{@md.fnb}" +        end +        self +      end +      def po(lng=@md.opt.lng) +        @lng=lng +        def dir +          output_path.base.dir + '/' \ +            + Gt[:src] + '/' \ +            + @md.opt.fng + '/po4a/po/' \ +            + @lng +        end +        def url +          output_path.base.url + '/po4a/' \ +            + @md.fnb + '/po/' \ +            + @lng +        end +        self +      end +      def pot +        def dir +         output_path.base.dir + '/' \ +           + Gt[:src] + '/' \ +           + @md.opt.fng + '/po4a/pot' +        end +        def url +          output_path.base.url + '/po4a/' \ +            + @md.fnb + '/pot' +        end +        def rcp +          #p "#{output_path.base.dir}/po4a/#{@md.fnb}/pot" +        end +        self +      end +      def po_git # consider !!! +        def ft +          Gt[:po] +        end +        def dir +          pth=@env.processing_path.git + '/' \ +            + @md.fnb + '/' \ +            + ft + '/' \ +            + @md.opt.lng +          FileUtils::mkdir_p(pth) unless FileTest.directory?(pth) +          pth +        end +        self +      end +      def pot_git # consider !!! +        def ft +          Gt[:pot] +        end +        def dir +          @env.processing_path.git + '/' \ +            + @md.fnb + '/' \ +            + ft +        end +        self +      end +      def po4a_sst(lng=@md.opt.lng) +        @lng=lng +        def dir +          output_path.base.dir + '/' \ +            + Gt[:src] + '/' \ +            + @md.opt.fng + '/po4a/' \ +            + @lng +        end +        def url +          output_path.base.url + '/po4a/' \ +            + @md.fnb \ +            + @lng +        end +        self +      end +      def md_harvest +        manifest +        self +      end +      def txt +        def ft +          'txt' +        end +        def dir +          set_path(ft).dir.abc +        end +        def url +          set_path(ft).url.abc +        end +        def rel +          set_path(ft).rel.abc +        end +        def rcp +          set_path(ft).rcp.abc +        end +        def rel_sm +          set_path(ft).rel_sm.ab +        end +        self +      end +      def textile +        def ft +          'textile' \ +            + DEVELOPER[:under_construction] +        end +        def dir +          set_path(ft).dir.abc +        end +        def url +          set_path(ft).url.abc +        end +        def rel +          set_path(ft).rel.abc +        end +        def rcp +          set_path(ft).rcp.abc +        end +        def rel_sm +          set_path(ft).rel_sm.ab +        end +        self +      end +      def asciidoc +        def ft +          'asciidoc' \ +            + DEVELOPER[:under_construction] +        end +        def dir +          set_path(ft).dir.abc +        end +        def url +          set_path(ft).url.abc +        end +        def rel +          set_path(ft).rel.abc +        end +        def rcp +          set_path(ft).rcp.abc +        end +        def rel_sm +          set_path(ft).rel_sm.ab +        end +        self +      end +      def markdown +        def ft +          'markdown' \ +            + DEVELOPER[:under_construction] +        end +        def dir +          set_path(ft).dir.abc +        end +        def url +          set_path(ft).url.abc +        end +        def rel +          set_path(ft).rel.abc +        end +        def rcp +          set_path(ft).rcp.abc +        end +        def rel_sm +          set_path(ft).rel_sm.ab +        end +        self +      end +      def rst +        def ft +          'rst' \ +            + DEVELOPER[:under_construction] +        end +        def dir +          set_path(ft).dir.abc +        end +        def url +          set_path(ft).url.abc +        end +        def rel +          set_path(ft).rel.abc +        end +        def rcp +          set_path(ft).rcp.abc +        end +        def rel_sm +          set_path(ft).rel_sm.ab +        end +        self +      end +      def orgmode +        def ft +          'orgmode' \ +            + DEVELOPER[:under_construction] +        end +        def dir +          set_path(ft).dir.abc +        end +        def url +          set_path(ft).url.abc +        end +        def rel +          set_path(ft).rel.abc +        end +        def rcp +          set_path(ft).rcp.abc +        end +        def rel_sm +          set_path(ft).rel_sm.ab +        end +        self +      end +      def html_scroll +        def ft +          'html' +        end +        def dir +          set_path(ft).dir.abc +        end +        def url +          set_path(ft).url.abc +        end +        def rel +          set_path(ft).rel.abc +        end +        def rcp +          set_path(ft).rcp.abc +        end +        def rel_sm +          set_path(ft).rel_sm.ab +        end +        def rel_image +          if output_dir_structure.dump_or_redirect? +            './image' +          elsif output_dir_structure.by_language_code? +            '../../_sisu/image' +          elsif output_dir_structure.by_filetype? +            '../_sisu/image' +          else +            '../_sisu/image' +          end +        end +        self +      end +      def html_seg +        def ft +          'html/' + @md.fnb +        end +        def dir +          set_path(ft).dir.abc +        end +        def url +          set_path(ft).url.abc +        end +        def rel +          set_path(ft).rel.abc +        end +        def rcp +          set_path(ft).rcp.abc +        end +        def rel_sm +          set_path(ft).rel_sm.ab +        end +        def rel_image +          if output_dir_structure.dump_or_redirect? +            './image' +          elsif output_dir_structure.by_language_code? +            '../../../_sisu/image' +          elsif output_dir_structure.by_filetype? +            '../../_sisu/image' +          else +            '../_sisu/image' +          end +        end +        self +      end +      def html_concordance +        html_seg +        self +      end +      def html +        def ft +          'html' +        end +        def dir +          set_path(ft).dir.abc +        end +        def url +          set_path(ft).url.abc +        end +        def rel +          set_path(ft).url.abc +        end +        def rcp +          set_path(ft).rcp.abc +        end +        def rel_sm +          set_path(ft).rel_sm.ab +        end +        def rel_image +          if output_dir_structure.by_language_code? +            '../../_sisu/image' +          elsif output_dir_structure.by_filetype? +            '../_sisu/image' +          else +            '../_sisu/image' +          end +        end +        self +      end +      def xhtml +        def ft +          'xhtml' +        end +        def dir +          set_path(ft).dir.abc +        end +        def url +          set_path(ft).url.abc +        end +        def rel +          set_path(ft).rel.abc +        end +        def rcp +          set_path(ft).rcp.abc +        end +        def rel_sm +          set_path(ft).rel_sm.ab +        end +        def rel_image +          '../../_sisu/image' +        end +        self +      end +      def epub +        def ft +          'epub' +        end +        def dir +          set_path(ft).dir.ab +        end +        def url +          set_path(ft).url.ab +        end +        def rel +          set_path(ft).rel.ab +        end +        def rcp +          set_path(ft).rcp.ab +        end +        def rel_sm +          set_path(ft).rel_sm.ab +        end +        def rel_image +          './image' +        end +        self +      end +      def odt +        def ft +          'odt' +        end +        def dir +          set_path(ft).dir.abc +        end +        def url +          set_path(ft).url.abc +        end +        def rel +          set_path(ft).rel.abc +        end +        def rcp +          set_path(ft).rcp.abc +        end +        def rel_sm +          set_path(ft).rel_sm.ab +        end +        self +      end +      def xml +        def ft +          'xml' +        end +        def dir +          set_path(ft).dir.abc +        end +        def url +          set_path(ft).url.abc +        end +        def rel +          set_path(ft).rel.abc +        end +        def rcp +          set_path(ft).rcp.abc +        end +        def rel_sm +          set_path(ft).rel_sm.ab +        end +        def rel_image +          '../../_sisu/image' +        end +        self +      end +      def xml_sax +        xml +        self +      end +      def xml_dom +        xml +        self +      end +      def xml_docbook +        def ft +          'docbook' +        end +        def dir +          set_path(ft).dir.abc +        end +        def url +          set_path(ft).url.abc +        end +        def rel +          set_path(ft).rel.abc +        end +        def rcp +          set_path(ft).rcp.abc +        end +        def rel_sm +          set_path(ft).rel_sm.ab +        end +        def rel_image +          '../../_sisu/image' +        end +        self +      end +      def xml_docbook_article +        def ft +          'docbook' \ +            + DEVELOPER[:under_construction] +        end +        def dir +          set_path(ft).dir.abc +        end +        def url +          set_path(ft).url.abc +        end +        def rel +          set_path(ft).rel.abc +        end +        def rcp +          set_path(ft).rcp.abc +        end +        def rel_sm +          set_path(ft).rel_sm.ab +        end +        def rel_image +          '../../_sisu/image' +        end +        self +      end +      def xml_docbook_book +        def ft +          'docbook' +        end +        def dir +          set_path(ft).dir.abc +        end +        def url +          set_path(ft).url.abc +        end +        def rel +          set_path(ft).rel.abc +        end +        def rcp +          set_path(ft).rcp.abc +        end +        def rel_sm +          set_path(ft).rel_sm.ab +        end +        def rel_image +          '../../_sisu/image' +        end +        self +      end +      def xml_fictionbook +        def ft +          'fictionbook' \ +            + DEVELOPER[:under_construction] +        end +        def dir +          set_path(ft).dir.abc +        end +        def url +          set_path(ft).url.abc +        end +        def rel +          set_path(ft).rel.abc +        end +        def rcp +          set_path(ft).rcp.abc +        end +        def rel_sm +          set_path(ft).rel_sm.ab +        end +        def rel_image +          '../../_sisu/image' +        end +        self +      end +      def xml_scaffold_structure_sisu +        def ft +          'sisu.scaffold.xml' +          #'xml' +        end +        def dir +          set_path(ft).dir.abc +        end +        def url +          set_path(ft).url.abc +        end +        def rel +          set_path(ft).rel.abc +        end +        def rcp +          set_path(ft).rcp.abc +        end +        def rel_sm +          set_path(ft).rel_sm.ab +        end +        def rel_image +          '../../_sisu/image' +        end +        self +      end +      def xml_scaffold_structure_collapse +        def ft +          'collapsed.scaffold.xml' +          #'xml' +        end +        def dir +          set_path(ft).dir.abc +        end +        def url +          set_path(ft).url.abc +        end +        def rel +          set_path(ft).rel.abc +        end +        def rcp +          set_path(ft).rcp.abc +        end +        def rel_sm +          set_path(ft).rel_sm.ab +        end +        def rel_image +          '../../_sisu/image' +        end +        self +      end +      def json +        def ft +          'json' +        end +        def dir +          set_path(ft).dir.abc +        end +        def url +          set_path(ft).url.abc +        end +        def rel +          set_path(ft).rel.abc +        end +        def rcp +          set_path(ft).rcp.abc +        end +        def rel_sm +          set_path(ft).rel_sm.ab +        end +        def rel_image +          '../../_sisu/image' +        end +        self +      end +      def pdf +        def ft +          'pdf' +        end +        def dir +          set_path(ft).dir.abc +        end +        def url +          set_path(ft).url.abc +        end +        def rel +          set_path(ft).rel.abc +        end +        def rcp +          set_path(ft).rcp.abc +        end +        def rel_sm +          set_path(ft).rel_sm.ab +        end +        self +      end +      def sqlite_discrete +        def ft +          'sql' +        end +        def dir +          set_path(ft).dir.ab +        end +        def url +          set_path(ft).url.ab +        end +        def rel +          set_path(ft).rel.ab +        end +        def rcp +          set_path(ft).rcp.ab +        end +        def rel_sm +          set_path(ft).rel_sm.ab +        end +        self +      end +      def hash_digest +        def ft +          'hashes' +        end +        def dir +          set_path(ft).dir.abc +        end +        def url +          set_path(ft).url.abc +        end +        def rel +          set_path(ft).rel.abc +        end +        def rcp +          set_path(ft).rcp.abc +        end +        def rel_sm +          set_path(ft).rel_sm.ab +        end +        self +      end +      def manifest +        def ft +          'manifest' +        end +        def dir +          set_path(ft).dir.abc +        end +        def url +          set_path(ft).url.abc +        end +        def rel +          set_path(ft).rel.abc +        end +        def rel_image +          if output_dir_structure.dump_or_redirect? +            './image' +          elsif output_dir_structure.by_language_code? +            '../../_sisu/image' +          elsif output_dir_structure.by_filetype? +            '../_sisu/image' +          else +            '../_sisu/image' +          end +        end +        def rcp +          set_path(ft).rcp.abc +        end +        self +      end +      def qrcode +        def ft +          'manifest/qrcode' +        end +        def dir +          set_path(ft).dir.abc +        end +        def url +          set_path(ft).url.abc +        end +        def rel +          set_path(ft).rel.abc +        end +        def rcp +          set_path(ft).rcp.abc +        end +        def rel_sm +          set_path(ft).rel_sm.ab +        end +        self +      end +      def harvest +        def ft +          'site_metadata' +        end +        def dir +          set_path(ft).dir.ab +        end +        def url +          set_path(ft).url.ab +        end +        def rel +          set_path(ft).rel.ab +        end +        def rcp +          set_path(ft).rcp.ab +        end +        def rel_sm +          if output_dir_structure.by_language_code? +            '' +          elsif output_dir_structure.by_filetype? +            '' +          else +            '' +          end +        end +        self +      end +      def manpage +        def ft +          'man' +        end +        def dir +          set_path(ft).dir.ab +        end +        def url +          set_path(ft).url.ab +        end +        def rel +          set_path(ft).rel.ab +        end +        def rcp +          set_path(ft).rcp.ab +        end +        def rel_sm +          set_path(ft).rel_sm.ab +        end +        self +      end +      def texinfo +        def ft +          'texinfo' +        end +        def dir +          set_path(ft).dir.ab +        end +        def url +          set_path(ft).url.ab +        end +        def rel +          set_path(ft).rel.ab +        end +        def rcp +          set_path(ft).rcp.ab +        end +        def rel_sm +          set_path(ft).rel_sm.ab +        end +        self +      end +      def sitemaps +        def ft +          'sitemaps' +        end +        def dir +          set_path(ft).dir.ab +        end +        def url +          set_path(ft).url.ab +        end +        def rel +          set_path(ft).rel.ab +        end +        def rcp +          set_path(ft).rcp.ab +        end +        self +      end +      def sqlite #check url +        def dir +          output_path.base.dir +        end +        def url +          output_path.base.url +        end +        def rel +          output_path.base.rel +        end +        def rcp +          output_path.base.rcp +        end +        self +      end +      #def cgi +      #end +      def css +        @d='_sisu/css' +        def dir +          output_path.base.dir + '/' + @d +        end +        def url +          output_path.base.url + '/' + @d +        end +        def rel +          @d +          #output_path.base.rel + '/' + @d +        end +        def rcp +          output_path.stub.rcp + '/' + @d +        end +        self +      end +      def images +        @d='_sisu/image' +        def dir +          output_path.base.dir + '/' + @d +        end +        def url +          output_path.base.url + '/' + @d +        end +        def rel +          @d +          #output_path.base.rel + '/' + @d +        end +        def rcp +          output_path.stub.rcp + '/' + @d +        end +        self +      end +      def images_external +        @d='_sisu/image_external' +        def dir +          output_path.base.dir + '/' + @d +        end +        def url +          output_path.base.url + '/' + @d +        end +        def rel +          output_path.base.rel + '/' + @d +        end +        def rcp +          output_path.base.rcp + '/' + @d +        end +        self +      end +      #def css +      #  #"#{@env.path.output}/#{@env.path.style}" +      #end +      self +    end +  end +end +module SiSU_Create_File +  require_relative 'constants'                             # constants.rb +  require_relative 'utils'                                 # utils.rb +  require_relative 'se_info_env'                           # se_info_env.rb +  class CreateFile < SiSU_Info_Env::InfoEnv                # se_info_env.rb +    #todo unify with FileOp +    def initialize(fns) +      begin +        super(fns) +        @env=SiSU_Env::InfoEnv.new(fns) +      rescue +        SiSU_Screen::Ansi.new('',$!,$@).rescue do +          __LINE__.to_s + ':' + __FILE__ +        end +      ensure +      end +    end +    def html_root +      #@env.path.output +    end +    def mkdir_pdf +      Dir.mkdir(@env.processing_path.tex) \ +        unless FileTest.directory?(@env.processing_path.tex) +    end +    def file_generic(output_file='') +      fn=@env.path.output + '/' \ +      + @fnb + '/' \ +      + output_file +      File.new(fn,'w+') +    end +    def file_error +      fn='/tmp/errorlog.sisu' +      File.new(fn,'w+') +    end +    def file_txt +      fn=@env.processing_path.ao + '/' \ +      + @fns + '.txt' +      File.new(fn,'w+') +    end +    def file_debug +      fn=@env.processing_path.ao + '/' \ +      + @fns + '.debug.txt' +      File.new(fn,'w+') +    end +    def metaverse +      def file_meta +        fn=@env.processing_path.ao + '/' \ +        + @fns + '.meta' +        File.new(fn,'w+') +      end +      def file_meta_idx_html +        fn=@env.processing_path.ao + '/' \ +        + @fns + '.idx.html' +        File.new(fn,'w+') +      end +      self +    end +    def file_note +      fn=Dir.pwd + '/' \ +      + @fns + '.fn' +      File.new(fn,'w+') +    end +    def meta +      @env.processing_path.ao + '/' \ +      + @fns + '.meta' +    end +    def file_semantic +      fn='./semantic.yaml' +      File.new(fn,'w+') +    end +    def file_rss +      fn='./semantic.xml' +      File.new(fn,'w+') +    end +    def epub +      @pth=@env.processing_path.epub +      def xhtml_index +        fn=@pth + '/' \ +        + Ep[:d_oebps] + '/index.xhtml' +        File.new(fn,'w+') +      end +      def xhtml_cover_image +        fn=@pth + '/' \ +        + Ep[:d_oebps] + '/cover_image.xhtml' +        File.new(fn,'w+') +      end +      def xhtml_segtoc +        fn=@pth + '/' \ +        + Ep[:d_oebps] + '/toc.xhtml' +        File.new(fn,'w+') +      end +      def mimetype  #fixed application/epub+zip ~/grotto/theatre/dbld/builds/epub_sample/mimetype +        File.new("#{@pth}/mimetype",'w') +      end +      def metadata #variable matadata ~/grotto/theatre/dbld/builds/epub_sample/metadata.opf +        fn=@pth + '/' \ +        + Ep[:d_oebps] + '/' \ +        + Ep[:f_opf] +        File.new(fn,'w') +      end +      def toc_ncx  #variable toc ~/grotto/theatre/dbld/builds/epub_sample/toc.ncx +        fn=@pth + '/' \ +        + Ep[:d_oebps] + '/' \ +        + Ep[:f_ncx] +        File.new(fn,'w') +      end +      def metainf_cont #variable content ~/grotto/theatre/dbld/builds/epub_sample/META-INF/container.xml +        fn=@pth + '/META-INF/container.xml' +        File.new(fn,'w') +      end +      def xhtml_css #fixed epub xhtml css +        fn=@pth + '/' \ +        + Ep[:d_oebps] + '/css/xhtml.css' +        File.new(fn,'w') +      end +      self +    end +    def file_texinfo +      fn=@env.processing_path.texinfo + '/' \ +      + @fnb + '.texinfo' +      File.new(fn,'w+') +    end +  end +end +module SiSU_Filename_Lang +  require_relative 'constants'                             # constants.rb +  require_relative 'utils'                                 # utils.rb +  class FilenameLanguageCodeInsert +    def initialize(opt,lng=nil) +      @opt=opt +      @lng=lng ||=opt.lng +    end +    def language_code_insert +      if @opt.dir_structure_by ==:language \ +      or ((@opt.dir_structure_by ==:filetype \ +      || @opt.dir_structure_by ==:filename) \ +      and (@opt.lingual ==:mono \ +      && @lng == @opt.act[:default_language][:code])) +        '' +      elsif (@opt.dir_structure_by ==:filetype \ +      || @opt.dir_structure_by ==:filename) \ +      and not @opt.lingual ==:mono +        '.' + @lng +      else +        '.' + @lng +      end +    end +  end +end +__END__ +#+END_SRC + +** se_get_init.rb + +#+BEGIN_SRC ruby  :tangle "../lib/sisu/se_get_init.rb" +# <<sisu_document_header>> +module SiSU_Get_Init +  require_relative 'constants'                             # constants.rb +  require_relative 'utils'                                 # utils.rb +  require_relative 'se_info_system'                        # se_info_system.rb +  @@noyaml=false +  class GetInit < SiSU_Info_Sys_Gen::InfoSystemGen         # se_info_system.rb +    @@noyaml=false +    @@rc,@@sisu_doc_makefile,@@sisurc_path,@@tx=nil,nil,nil,nil +    @@ad={ promo: nil, promo_list: nil, flag_promo: false } +    @@sdmd=nil +    attr_accessor :yaml +    def initialize +      super() +        @markup_dir_changed_=if @@sdmd==$sisu_document_markup_directory +          false +        else +          @@sdmd=$sisu_document_markup_directory +          true +        end +    end +    def tex +      require_relative 'texpdf_parts'                        # texpdf_parts.rb +      @@tx ||=SiSU_Parts_TeXpdf::TeX.new +    end +    def rc_path_options +      v=SiSU_Env::InfoVersion.instance.get_version +      [ +        $sisu_document_markup_directory_base_fixed_path \ +        + '/.sisu/v' \ +        + v.version_major, +        $sisu_document_markup_directory_base_fixed_path \ +        + '/.sisu', +        $sisu_document_markup_directory_base_fixed_path \ +        + '/_sisu/v' \ +        + v.version_major, +        $sisu_document_markup_directory_base_fixed_path \ +        + '/_sisu', +        @@home \ +        + '/.sisu/v' \ +        + v.version_major, +        @@home \ +        + '/.sisu', \ +        @@sisu_etc \ +        + '/v' \ +        + v.version_major, +        @@sisu_etc, +      ] +    end +    def sisu_document_make +      def makefile_name +        S_CONF[:header_make] +      end +      def makefile +        rc_path_options.each do |v| +          if FileTest.exist?("#{v}/#{makefile_name}") +            @sisu_make_path=v +            break +          end +        end +        @sisu_make_file_path=@sisu_make_path \ +        ? "#{@sisu_make_path}/#{makefile_name}" +        : nil +      end +      def makefile_read +        if makefile +          sisu_doc_makefile=IO.read(makefile, mode: 'r:utf-8') +          @sisu_doc_makefile=sisu_doc_makefile.split(/\s*\n\s*\n/m) +        end +        @sisu_doc_makefile +      end +      self +    end +    def sisu_yaml +      def rc +        if @markup_dir_changed_ +          rc_path_options.each do |v| +            if @@noyaml \ +            or FileTest.exist?("#{v}/noyaml") +              STDERR.puts "WARNING - YAML loading switched off, to enable delete the file:\n\t#{v}/noyaml\n\n" unless @@noyaml +              @@noyaml=true +              break +            else +              f=S_CONF[:rc_yml] +              p_f="#{v}/#{f}" +              if FileTest.exist?(p_f) +                begin +                  require 'yaml' +                rescue LoadError +                  SiSU_Utils::CodeMarker.new(__LINE__,__FILE__,:fuchsia). +                    error('yaml NOT FOUND (LoadError)') +                end +                @@sisurc_path=v +                @@rc=YAML::load(File::open(p_f)) +                break +              end +              unless @@rc +                f='sisurc.yaml' +                p_f="#{v}/#{f}" +                if FileTest.exist?(p_f) +                  begin +                    require 'yaml' +                  rescue LoadError +                    SiSU_Utils::CodeMarker.new(__LINE__,__FILE__,:fuchsia). +                      error('yaml NOT FOUND (LoadError)') +                  end +                  @@sisurc_path=v +                  @@rc=YAML::load(File::open(p_f)) +                  break +                end +              end +            end +          end +        end +        @@rc +      end +      def rc_path +        rc +        @@sisurc_path +      end +      self +    end +    def ads #WORK AREA +      tell_no_yaml='WARNING - YAML loading switched off, to enable delete the file:' +      if @markup_dir_changed_ +        @ad_path=[ +          "#{$sisu_document_markup_directory_base_fixed_path}/.sisu/skin/yml", +          "#{$sisu_document_markup_directory_base_fixed_path}/_sisu/skin/yml", +          "#{@@home}/.sisu/skin/yml", +          "#{@@sisu_etc}/skin/yml", +        ] +        @ad_path.each do |v| +          if @@noyaml \ +          or FileTest.exist?("#{v}/noyaml") +            puts tell_no_yaml + "\n\t#{v}/noyaml\n" unless @@noyaml +            @@noyaml=true +            break +          else +            if FileTest.exist?("#{v}/list.yml") +              unless @@ad[:promo_list] +                begin +                  require 'yaml' +                rescue LoadError +                  SiSU_Utils::CodeMarker.new(__LINE__,__FILE__,:fuchsia). +                    error('yaml NOT FOUND (LoadError)') +                end +                @@ad[:promo_list] ||= YAML::load(File::open("#{v}/list.yml")) +              end +              @@ad[:flag_promo]=true +              break +            end +            @@ad[:flag_promo]=false +          end +        end +        @ad_path.each do |v| +          if @@noyaml \ +          or FileTest.exist?("#{v}/noyaml") +            puts tell_no_yaml + "\n\t#{v}/noyaml\n" unless @@noyaml +            @@noyaml=true +            break +          else +            if FileTest.exist?("#{v}/promo.yml") +              unless @@ad[:promo] +                begin +                  require 'yaml' +                rescue LoadError +                  SiSU_Utils::CodeMarker.new(__LINE__,__FILE__,:fuchsia). +                    error('yaml NOT FOUND (LoadError)') +                end +                @@ad[:promo] ||= YAML::load(File::open("#{v}/promo.yml")) +              end +              @@ad[:flag_promo]=true +              break +            end +            @@ad[:flag_promo]=false +          end +        end +      end +      @@ad +    end +  end +end +__END__ +#+END_SRC + +** se_hub_particulars.rb + +#+BEGIN_SRC ruby  :tangle "../lib/sisu/se_hub_particulars.rb" +# <<sisu_document_header>> +module SiSU_Particulars +  begin +    require 'singleton' +  rescue LoadError +    SiSU_Utils::CodeMarker.new(__LINE__,__FILE__,:fuchsia). +      error('singleton NOT FOUND (LoadError)') +  end +  require_relative 'se'                                 # se.rb +    include SiSU_Env +  require_relative 'dp'                                 # dp.rb +    include SiSU_Param +  require_relative 'ao'                                 # ao.rb +  class CombinedSingleton +    include Singleton +    def get_all(opt) +      set_env(opt) +      set_file(opt) +      set_md(opt) +      set_ao(opt)                #needs @md +    end +    def get_env(opt) +      set_env(opt) +    end +    def get_file(opt) +      set_file(opt) +    end +    def get_md(opt) +      set_md(opt) +    end +    def get_ao_array(opt) +      set_ao(opt)                #needs @md +    end +    def get_env_md(opt) +      set_env(opt) +      set_md(opt) +    end +    def get_idx_sst(opt) +      set_sst_idx(opt) +    end +    def get_idx_raw(opt) +      set_raw_idx(opt) +    end +    def get_idx_html(opt) +      set_html_idx(opt) +    end +    def get_idx_xhtml(opt) +      set_xhtml_idx(opt) +    end +    def get_name_tags(opt) +      set_name_tags(opt) +    end +    def get_maps(opt) +      set_nametags_map(opt) +      set_ocn_htmlseg_map(opt) +    end +    def get_map_nametags(opt) +      set_nametags_map(opt) +    end +    def get_map_ocn_htmlseg(opt) +      set_ocn_htmlseg_map(opt) +    end +    attr_accessor :opt,:md,:sst_idx,:raw_idx,:html_idx,:xhtml_idx +    def set_md(opt) +      begin +        @md=SiSU_Param::Parameters.new(opt).get +        self +      rescue +        SiSU_Errors::Rescued.new($!,$@,opt.selections.str,opt.fnl).location do +          __LINE__.to_s + ':' + __FILE__ +        end +      end +    end +    attr_accessor :opt,:env,:file +    def set_env(opt) +      begin +        @env=SiSU_Env::InfoEnv.new(opt.fns) +        self +      rescue +        SiSU_Errors::Rescued.new($!,$@,opt.selections.str,opt.fnl).location do +          __LINE__.to_s + ':' + __FILE__ +        end +      end +    end +    def set_file(opt) +      begin +        set_md(opt) unless @md +        @file=SiSU_Env::FileOp.new(@md) +        self +      rescue +        SiSU_Errors::Rescued.new($!,$@,opt.selections.str,opt.fnl).location do +          __LINE__.to_s + ':' + __FILE__ +        end +      end +    end +    attr_accessor :opt,:ao_array +    def set_ao(opt) +      begin +        @ao_array=SiSU_AO::Source.new(opt).get +        self +      rescue +        SiSU_Errors::Rescued.new($!,$@,opt.selections.str,opt.fnl).location do +          __LINE__.to_s + ':' + __FILE__ +        end +      end +    end +    def set_sst_idx(opt) +      begin +        @sst_idx=SiSU_AO::Source.new(opt).get_idx_sst +        self +      rescue +        SiSU_Errors::Rescued.new($!,$@,opt.selections.str,opt.fnl).location do +          __LINE__.to_s + ':' + __FILE__ +        end +      end +    end +    def set_raw_idx(opt) +      begin +        @raw_idx=SiSU_AO::Source.new(opt).get_idx_raw +        self +      rescue +        SiSU_Errors::Rescued.new($!,$@,opt.selections.str,opt.fnl).location do +          __LINE__.to_s + ':' + __FILE__ +        end +      end +    end +    def set_html_idx(opt) +      begin +        @html_idx=SiSU_AO::Source.new(opt).get_idx_html +        self +      rescue +        SiSU_Errors::Rescued.new($!,$@,opt.selections.str,opt.fnl).location do +          __LINE__.to_s + ':' + __FILE__ +        end +      end +    end +    def set_xhtml_idx(opt) +      begin +        @xhtml_idx=SiSU_AO::Source.new(opt).get_idx_xhtml +        self +      rescue +        SiSU_Errors::Rescued.new($!,$@,opt.selections.str,opt.fnl).location do +          __LINE__.to_s + ':' + __FILE__ +        end +      end +    end +    attr_accessor :nametags_map +    def set_nametags_map(opt) +      begin +        opt=@md ? @md : opt +        @nametags_map=SiSU_AO::Source.new(opt).get_map_nametags +        self +      rescue +        if @md +          SiSU_Errors::Rescued.new($!,$@,@md.opt.selections.str,@md.opt.fnl).location do +            __LINE__.to_s + ':' + __FILE__ +          end +        else +          SiSU_Errors::Rescued.new($!,$@,opt.selections.str,opt.fnl).location do +            __LINE__.to_s + ':' + __FILE__ +          end +        end +      end +    end +    attr_accessor :ocn_htmlseg_map +    def set_ocn_htmlseg_map(opt) +      begin +        @ocn_htmlseg_map=SiSU_AO::Source.new(@md).get_map_ocn_htmlseg +        self +      rescue +        SiSU_Errors::Rescued.new($!,$@,opt.selections.str,opt.fnl).location do +          __LINE__.to_s + ':' + __FILE__ +        end +      end +    end +  end +end +__END__ +consider running as separate objects +#+END_SRC + +** se_info_env.rb + +#+BEGIN_SRC ruby  :tangle "../lib/sisu/se_info_env.rb" +# <<sisu_document_header>> +@@current_document=Dir.pwd #nil #'' +module SiSU_Info_Env +  require_relative 'se_envcall'                            # se_envcall.rb +  require_relative 'html_parts'                            # html_parts.rb +  begin +    require 'singleton' +    require 'fileutils' +      include FileUtils::Verbose +  rescue LoadError +    SiSU_Utils::CodeMarker.new(__LINE__,__FILE__,:fuchsia). +      error('singleton or fileutils NOT FOUND (LoadError)') +  end +  class InfoEnv < SiSU_Env_Call::EnvCall                   # se_envcall.rb +    begin +      require 'pathname' +      require 'fileutils' +        include FileUtils +    rescue LoadError +      SiSU_Utils::CodeMarker.new(__LINE__,__FILE__,:fuchsia). +        error('pathname or fileutils NOT FOUND (LoadError)') +    end +    attr_accessor :filename,:sys,:home,:hostname,:user,:env,:rc,:www,:fnb,:fnn,:fnt,:flv,:webserv_path,:stub_pwd,:base_markup_dir_stub,:stub_src,:webserv_host_cgi,:webserv_port_cgi,:processing,:processing_git,:etc,:yamlrc_dir +    @@image_flag,@@local_image=true,true   #warning on @@image_flag +    @@fb,@@man_path=nil,nil +    def initialize(fns='',md=nil) +      super() #you may not want to re-execute this static info so frequently! +      @init=SiSU_Env::GetInit.new #SiSU_Get_Init::GetInit +      @fns,@md=fns,md +      @env=SiSU_Env::EnvCall.new(fns) if fns #SiSU_Env_Call::EnvCall +      fnb=if @md \ +      and defined? @md.fnb +        @md.fnb +      elsif defined? @env.fnb \ +      and @env.fnb +        @env.fnb +      elsif @fns.is_a?(String) \ +      and not @fns.empty? +        m=/(.+)?\.(?:(?:-|ssm\.)?sst|ssm)$/m +        @fns[m,1] if not @fns.empty? +      end +      if fnb; @@fb ||=fnb +      end +      @sys=SiSU_Info_Sys::InfoSystem.instance +      @fnb ||=@@fb #clean up this... used primarily for zap which is not passed normal parameters +      @fixed_websev_root='' # @home +      @pwd=@@pwd=Dir.pwd +      @base_markup_dir_stub=SiSU_Utils::Path.new.base_markup_stub +      @stub_src=     @base_markup_dir_stub + '/src' +      @stub_pod=     @base_markup_dir_stub + '/pod' +      @stub_epub=    @base_markup_dir_stub + '/epub' +      m=/.+\/(?:src\/)?(\S+)/m # m=/.+?\/(?:src\/)?([^\/]+)$/im # m=/.+\/(\S+)/m +      @stub_pwd=@@pwd[m,1] || '' #; p __LINE__; #p @pwd; #p m; #p @stub_pwd +      pt=Pathname.new(Dir.pwd) +      stub=if output_dir_structure.by_language_code? +        r=Px[:lng_lst_rgx] +        stub=if Dir.pwd =~/.+?\/([^\/]+)(?:\/(#{r})$)/ +          lng=pt.split[-1].to_s +          lng_part='/' + lng +          base=pt.split[0].split[-1].to_s +        else +          lng_part='/' + language_default_set +          base=pt.split[-1].to_s +        end +        base + lng_part +      elsif output_dir_structure.by_filetype? +        pt.split[-1].to_s +      elsif  output_dir_structure.by_filename? +        '' +      else +        SiSU_Utils::CodeMarker.new(__LINE__,__FILE__,:fuchsia). +          warn('set output type, by: language, filetype or filename') +      end +      @stub_set_manifest=stub + '/manifest' +    end +    def user +      @sys.user +    end +    def hostname +      @sys.hostname +    end +    def host +      @sys.host +    end +    def arch +      @sys.arch +    end +    def rbver +      @sys.rbver +    end +    def locale +      @sys.locale +    end +    def concord_max +      ((defined? @rc['processing']['concord_max']) \ +      && @rc['processing']['concord_max']) \ +      ? @rc['processing']['concord_max'] +      : (defaults[:concord_max]) +    end +    def language_default_set           #set directory (default) language +      ((defined? @rc['default']['language']) \ +      && @rc['default']['language'] =~/\S+/) \ +      ? @rc['default']['language'] +      : 'en' +    end +    def markup_emphasis +      if defined? @rc['default']['emphasis'] \ +      and @rc['default']['emphasis'] \ +      and @rc['default']['emphasis']=~/bold/ +        'bold' +      elsif defined? @rc['default']['emphasis'] \ +      and @rc['default']['emphasis'] \ +      and @rc['default']['emphasis']=~/italic/ +        'italics' +      elsif defined? @rc['default']['emphasis'] \ +      and @rc['default']['emphasis'] \ +      and @rc['default']['emphasis']=~/underscore/ +        'underscore' +      else 'bold' +      end +    end +    def plaintext_wrap +      ((defined? @rc['default']['text_wrap']) \ +      && (@rc['default']['text_wrap']) \ +      && (@rc['default']['text_wrap'].to_s=~/\d\d+/) \ +      && (@rc['default']['text_wrap'].to_i > 19) \ +      && (@rc['default']['text_wrap'].to_i < 201)) \ +      ? @rc['default']['text_wrap'].to_i +      : 78 +    end +    def current_document +      @@current_document||=Dir.pwd +      @@current_document +    end +    def stub_pwd                       #200412 +      @stub_pwd +    end +    def base_markup_dir_stub +      @base_markup_dir_stub +    end +    def stub_md_harvest                #watch +      @stub_set_manifest +    end +    def stub_src +      @stub_src +    end +    def stub_pod +      @stub_pod +    end +    def sisupod_v4(opt) +      #processing_path.processing +      #  sisupod +      #    doc/ +      #      manifest.txt +      #      en/content.sst                [file content] +      #      fr/content.sst +      #      _sisu +      #        sisu_document_make +      #        image@ (ln -s ../../image) +      #        audio@ (ln -s ../../audio) +      #        video@ (ln -s ../../video) +      #    image/                          [all images for specific document gathered here] +      #    audio/ +      #    video/ +      spp="#{processing_path.processing}/#{Gt[:sisupod]}" +      sppc="#{spp}/doc/_sisu" +      lng_dirs=[] +      if FileTest.directory?(spp) \ +      or FileTest.file?(spp) +        FileUtils::rm_rf(spp) +      end +      paths=[] +      flv=SiSU_Env::EnvCall.new(opt.fns). +        document_language_versions_found +      flv[:f].each {|l| lng_dirs << l[:l] } +      lng_dirs.uniq.each do |lng| +        paths << "#{spp}/doc/#{lng}" +      end +      paths \ +      << "#{spp}/image" +     #<< "#{spp}/audio" \ +     #<< "#{spp}/video" \ +      paths.each do |x| +        unless FileTest.directory?(x) +          FileUtils::mkdir_p(x) +        end +      end +      if FileTest.directory?(sppc) +        pwd=Dir.pwd +        Dir.chdir(sppc) +        FileUtils::ln_s('../../image', 'image') +       #FileUtils::ln_s('../../audio', 'audio') +       #FileUtils::ln_s('../../video', 'video') +        Dir.chdir(pwd) +      end +    end +    def sisupod_v3(opt) +      #processing_path.processing +      #  sisupod +      #    doc/ +      #      manifest.txt +      #      en/content.sst                [file content] +      #      fr/content.sst +      #      _sisu +      #        skin/ +      #          doc                       [relevant skin if any other than default] +      #        image@ (ln -s ../../image) +      #        audio@ (ln -s ../../audio) +      #        video@ (ln -s ../../video) +      #    image/                          [all images for specific document gathered here] +      #    audio/ +      #    video/ +      spp="#{processing_path.processing}/#{Gt[:sisupod]}" +      sppc="#{spp}/doc/_sisu" +      lng_dirs=[] +      if FileTest.directory?(spp) \ +      or FileTest.file?(spp) +        FileUtils::rm_rf(spp) +      end +      paths=[] +      flv=SiSU_Env::EnvCall.new(opt.fns). +        document_language_versions_found +      flv[:f].each {|l| lng_dirs << l[:l] } +      lng_dirs.uniq.each do |lng| +        paths << "#{spp}/doc/#{lng}" +      end +      paths \ +      << "#{spp}/image" \ +      << "#{sppc}/skin/doc" \ +      << "#{sppc}/skin/dir" \ +      << "#{sppc}/skin/site" +     #<< "#{spp}/audio" \ +     #<< "#{spp}/video" \ +      paths.each do |x| +        unless FileTest.directory?(x) +          FileUtils::mkdir_p(x) +        end +      end +      if FileTest.directory?(sppc) +        pwd=Dir.pwd +        Dir.chdir(sppc) +        FileUtils::ln_s('../../image', 'image') +       #FileUtils::ln_s('../../audio', 'audio') +       #FileUtils::ln_s('../../video', 'video') +        Dir.chdir(pwd) +      end +    end +    def sisupod_v2 +      #processing_path.processing +      #  sisupod +      #    content.sst              [file content] +      #    filename.sst             [link to content.sst] +      #    _sisu +      #      skin/ +      #        doc                  [relevant skin if any other than default] +      #      image                  [all images for specific document gathered here] +      sisupod_processing_path="#{processing_path.processing}/#{Gt[:sisupod]}" +      if FileTest.directory?(sisupod_processing_path) \ +      or FileTest.file?(sisupod_processing_path) +        FileUtils::rm_rf(sisupod_processing_path) +      end +      paths=[] +      paths=[ +        "#{processing_path.processing}/#{Gt[:sisupod]}/_sisu/skin/doc", +        "#{processing_path.processing}/#{Gt[:sisupod]}/_sisu/skin/dir", +        "#{processing_path.processing}/#{Gt[:sisupod]}/_sisu/skin/site", +        "#{processing_path.processing}/#{Gt[:sisupod]}/_sisu/image" +      ] +      paths.each {|x| FileUtils::mkdir_p(x) unless FileTest.directory?(x) } +    end +    def defaults                       #multiple default directories +      @default_dir ||=@sys.default_dir #DEFAULT_DIR +    end +    def html_seg_title_banner? +      ((defined? @rc['html']['seg_title_banner']) \ +      && @rc['html']['seg_title_banner']==true) \ +      ? @rc['html']['seg_title_banner'] +      : false +    end +    def html_quick_ref? +      ((defined? @rc['html']['quick_ref']) \ +      && @rc['html']['quick_ref']==true) \ +      ? @rc['html']['quick_ref'] +      : false +    end +    def html_minitoc? +      if defined? @rc['html']['minitoc'] \ +      and @rc['html']['minitoc'].is_a?(String) +        @rc['html']['minitoc'] +      else false +      end +    end +    def manifest_minitoc? +      if defined? @rc['manifest']['minitoc'] \ +      and @rc['manifest']['minitoc'].is_a?(String) +        @rc['manifest']['minitoc'] +      else false +      end +    end +    def build +      def omit_list +        @off_list ||=if defined? @rc['omit_list'] \ +        and @rc['omit_list'].is_a?(String) +          @rc['omit_list'] +        elsif defined? @rc['omit']['list'] \ +        and @rc['omit']['list'].is_a?(String) +          @rc['omit']['list'] +        else +          nil +        end +      end +      def listed?(test) #fix +        listed=if omit_list +          x=(omit_list.scan(/\b#{test}\b/)).join +          test==x \ +          ? true +          : false +        else +          false +        end +        listed +      end +      def ocn? +        if (defined? @rc['omit']['ocn'] \ +        and not @rc['omit']['ocn'].nil?) \ +        or listed?('ocn') +          :off +        else +          :na +        end +      end +      def toc? +        if (defined? @rc['omit']['toc'] \ +        and not @rc['omit']['toc'].nil?) \ +        or listed?('toc') +          :off +        else +          :na +        end +      end +      def manifest? +        if (defined? @rc['omit']['manifest'] \ +        and not @rc['omit']['manifest'].nil?) \ +        or listed?('manifest') +          :off +        else +          :na +        end +      end +      def links_to_manifest? +        if (defined? @rc['omit']['links_to_manifest'] \ +        and not @rc['omit']['links_to_manifest'].nil?) \ +        or (listed?('links_to_manifest') \ +        ||  listed?('manifest_links')) +          :off +        else +          :na +        end +      end +      def metadata? +        if (defined? @rc['omit']['metadata'] \ +        and not @rc['omit']['metadata'].nil?) \ +        or listed?('metadata') +          :off +        else +          :na +        end +      end +      def minitoc? +        if (defined? @rc['omit']['minitoc'] \ +        and not @rc['omit']['minitoc'].nil?) \ +        or (listed?('minitoc')) +          :off +        else +          :na +        end +      end +      def manifest_minitoc? +        if (defined? @rc['omit']['manifest_minitoc'] \ +        and not @rc['omit']['manifest_minitoc'].nil?) \ +        or listed?('manifest_minitoc') +          :off +        else +          :na +        end +      end +      def html_minitoc? +        if (defined? @rc['omit']['html_minitoc'] \ +        and not @rc['omit']['html_minitoc'].nil?) \ +        or (listed?('html_minitoc') \ +        || listed?('minitoc')) +          :off +        else +          :na +        end +      end +      def html_navigation? +        if (defined? @rc['omit']['html_navigation'] \ +        and not @rc['omit']['html_navigation'].nil?) \ +        or listed?('html_navigation') +          :off +        else +          :na +        end +      end +      def html_navigation_bar? +        if (defined? @rc['omit']['html_navigation_bar'] \ +        and not @rc['omit']['html_navigation_bar'].nil?) \ +        or listed?('html_navigation_bar') +          :off +        else +          :na +        end +      end +      def segsubtoc? +        if (defined? @rc['omit']['segsubtoc'] \ +        and not @rc['omit']['segsubtoc'].nil?) \ +        or listed?('segsubtoc') +          :off +        else +          :na +        end +      end +      def html_right_pane? +        if (defined? @rc['omit']['html_right_pane'] \ +        and not @rc['omit']['html_right_pane'].nil?) \ +        or listed?('html_right_pane') +          :off +        else +          :na +        end +      end +      def html_top_band? +        if (defined? @rc['omit']['html_top_band'] \ +        and not @rc['omit']['html_top_band'].nil?) \ +        or listed?('html_top_band') +          :off +        else +          :na +        end +      end +      def search_form? #decide later, as is configured here (in sisurc) and can be turned off on command line +        if (defined? @rc['omit']['search_form'] \ +        and not @rc['omit']['search_form'].nil?) \ +        or listed?('search_form') +          :off +        else +          :na +        end +      end +      def html_search_form? #decide later, as is configured here (in sisurc) and can be turned off on command line +        if (defined? @rc['omit']['html_search_form'] \ +        and not @rc['omit']['html_search_form'].nil?) \ +        or listed?('html_search_form') +          :off +        else +          :na +        end +      end +      self +    end +    def odt_ocn? +      ((defined? @rc['odt']['ocn']) \ +      && @rc['odt']['ocn']==false) \ +      ? @rc['odt']['ocn'] +      : true +    end +    def xml_docbook_ocn? +      ((defined? @rc['xml_docbook']['ocn']) \ +      && @rc['xml_docbook']['ocn']==false) \ +      ? @rc['xml_docbook']['ocn'] +      : true +    end +    def xml_fictionbook_ocn? +      ((defined? @rc['xml_fictionbook']['ocn']) \ +      && @rc['xml_fictionbook']['ocn']==false) \ +      ? @rc['xml_fictionbook']['ocn'] +      : true +    end +    def xml_scaffold_ocn? +      ((defined? @rc['xml_scaffold']['ocn']) \ +      && @rc['xml_scaffold']['ocn']==false) \ +      ? @rc['xml_scaffold']['ocn'] +      : true +    end +    def plaintext_ocn? +      ((defined? @rc['plaintext']['ocn']) \ +      && @rc['plaintext']['ocn']==false) \ +      ? @rc['plaintext']['ocn'] +      : true +    end +    def textile_ocn? +      ((defined? @rc['textile']['ocn']) \ +      && @rc['textile']['ocn']==true) \ +      ? @rc['textile']['ocn'] +      : false +    end +    def asciidoc_ocn? +      ((defined? @rc['asciidoc']['ocn']) \ +      && @rc['asciidoc']['ocn']==true) \ +      ? @rc['asciidoc']['ocn'] +      : false +    end +    def markdown_ocn? +      ((defined? @rc['markdown']['ocn']) \ +      && @rc['markdown']['ocn']==true) \ +      ? @rc['markdown']['ocn'] +      : false +    end +    def rst_ocn? +      ((defined? @rc['rst']['ocn']) \ +      && @rc['rst']['ocn']==true) \ +      ? @rc['rst']['ocn'] +      : false +    end +    def orgmode_ocn? +      ((defined? @rc['orgmode']['ocn']) \ +      && @rc['orgmode']['ocn']==true) \ +      ? @rc['orgmode']['ocn'] +      : false +    end +    def widget #needs (md) #move +      @rc=SiSU_Env::GetInit.new.sisu_yaml.rc +      @ad=SiSU_Env::GetInit.new.ads +      @html_bits=SiSU_Proj_HTML::Bits.new +      @flag={ +        ad: false, +        md: false, +        sk: false, +        rc: false +      } +      def promo? +        @flag[:ad]=if @md.flag_promo \ +        && @ad[:flag_promo] +          @flag[:md]=true +          true +        elsif defined? @html_bits.widget_promo \ +        and not @html_bits.widget_promo.nil? \ +        and @html_bits.widget_promo.is_a?(Array) \ +        and @html_bits.widget_promo.length > 0 +          @flag[:sk]=true +          true +        elsif defined? @rc['html']['promo'] \ +        and not @rc['html']['promo'].nil? \ +        and @rc['html']['promo'].length > 0 +          @flag[:rc]=true +          true +        else false +        end +        @flag +      end +      def search? +        searches=['sisu'] +        flag=false +        if defined? @rc['search'] +          searches.each do |type| +            flag=if defined? @rc['search'][type] \ +            and defined? @rc['search'][type]['action'] \ +            and @rc['search'][type]['flag']==true \ +            and @rc['search'][type]['action'] =~/https?:\/\// +              flag=if promo?[:ad] +                false +              elsif defined? @html_bits.widget_search \ +              and @html_bits.widget_search==true +                true +              elsif defined? @rc['search'][type]['flag'] \ +              and @rc['search'][type]['flag']==true +                true +              else false +              end +            else false +            end +          end +        else false +        end +        flag +      end +      def search_fixed? +        searches=['sisu','hyperestraier'] +        flag=if defined? @rc['search'] +          searches.each do |type| +            if defined? @rc['search'][type] \ +            and defined? @rc['search'][type]['action'] \ +            and @rc['search'][type]['action'] =~/https?:\/\// \ +            and defined? @rc['search'][type]['db'] \ +            and @rc['search'][type]['db'] =~/\S+/ +              flag=if promo?[:ad] +                false +              elsif defined? @html_bits.widget_search \ +              and @html_bits.widget_search==true +                true +              elsif defined? @rc['search'][type]['flag'] \ +              and @rc['search'][type]['flag']==true +                true +              else false +              end +            else false +            end +          end +        else false +        end +      end +      def search_form(type='sisusearch',action=nil,db=nil,table=false) +        rc=SiSU_Env::GetInit.new.sisu_yaml.rc +        create_form_sisu=if action \ +        and db \ +        and action =~/https?:\/\// \ +        and db =~/\S+/ +          true +        elsif widget.search? +          db=if rc['search']['sisu']['flag']==true \ +          and rc['search']['sisu']['db']=~/\S+/ +            (rc['search']['sisu']['db']=~/^#{Db[:name_prefix]}\S+/) \ +            ? rc['search']['sisu']['db'] +            : "#{Db[:name_prefix]}#{rc['search']['sisu']['db']}" +          else nil +          end +          action=rc['search']['sisu']['action'] +          true +        elsif defined? rc['search']['sisu']['flag'] \ +        and defined? rc['search']['sisu']['action'] \ +        and rc['search']['sisu']['flag']==true \ +        and rc['search']['sisu']['action'] =~/https?:\/\// +          true +        else false +        end +        if table +          table_open='<td align="center" bgcolor="#ffffff">' +          table_close='</td>' +        else +          table_open='' +          table_close='<br />' +        end +        form=if create_form_sisu \ +        and type=~/sisusearch/ \ +        and defined? rc['search']['sisu'] \ +        and defined? rc['search']['sisu']['action'] +          <<WOK +<!-- SiSU Search --> +#{table_open} +<a name="search"></a> +<form method="get" action="#{rc['search']['sisu']['action']}" target="_top"> +<font size="2"> +<input type="text" name="s1" size="24" maxlength="255" /> +<input type="hidden" name="db" value="#{db}" /> +<input type="hidden" name="ltd" value="1000" /> +<input type="hidden" name="off" value="0" /> +<input type="hidden" name="doc" value="#{@md.fnb}" /><br /> +<input type="submit" name="search" value="search doc" /> +<input type="submit" name="search" value="search db" /> +</font></form> +#{table_close} +<!-- SiSU Search --> +WOK +        else '' +        end +        form +      end +      def search_form_static(action=nil,db=nil) +        rc=SiSU_Env::GetInit.new.sisu_yaml.rc +        create_form=if rc['search']['sisu']['flag']==true \ +        and action \ +        and db \ +        and action =~/https?:\/\// \ +        and db =~/\S+/ +          true +        elsif widget.search_fixed? +          db=if rc['search']['sisu']['flag']==true \ +          and rc['search']['sisu']['db']=~/\S+/ +            (rc['search']['sisu']['db']=~/^#{Db[:name_prefix]}\S+/) \ +            ? rc['search']['sisu']['db'] +            : "#{Db[:name_prefix]}#{rc['search']['sisu']['db']}" +          else nil +          end +          action=rc['search']['sisu']['action'] +          true +        else false +        end +        if create_form +          %{<td align="center" bgcolor="#ffffff"> +<!-- SiSU Search --> +<a name="search"></a> +<form method="get" action="#{rc['search']['sisu']['action']}" target="_top"> +<font size="2"> +<input type="text" name="s1" size="24" maxlength="255" /> +<br /> +<input type="hidden" name="db" value="#{db}" /> +<input type="hidden" name="ltd" value="1000" /> +<input type="hidden" name="off" value="0" /> +<input type="hidden" name="doc" value="#{@md.fnb}" /> +<input type="submit" name="search" value="search doc" /> +<input type="submit" name="search" value="search db" /> +</font> +</form> +<!-- SiSU Search --> +</td> } +        else '' +        end +      end +      def search_action #check +        if search? +        else '' +        end +      end +      self +    end +    def widget_static +      @rc=SiSU_Env::GetInit.new.sisu_yaml.rc +      @html_bits=SiSU_Proj_HTML::Bits.new +      @flag={ ad: false, md: false, sk: false, rc: false } +      def search? +        flag=if defined? @rc['search'] \ +        and defined? @rc['search']['sisu'] \ +        and defined? @rc['search']['sisu']['action'] \ +        and @rc['search']['sisu']['action'] =~/https?:\/\// \ +        and defined? @rc['search']['sisu']['db'] \ +        and @rc['search']['sisu']['db'] =~/\S+/ +          flag=if defined? @html_bits.widget_search \ +          and @html_bits.widget_search==true +            true +          elsif defined? @rc['search']['sisu']['flag'] \ +          and @rc['search']['sisu']['flag']==true +            true +          else +            false +          end +        else +          false +        end +      end +      def search_fixed? +        flag=if defined? @rc['search'] \ +        and defined? @rc['search']['sisu'] \ +        and defined? @rc['search']['sisu']['action'] \ +        and @rc['search']['sisu']['action'] =~/https?:\/\// \ +        and defined? @rc['search']['sisu']['db'] \ +        and @rc['search']['sisu']['db'] =~/\S+/ \ +        and defined? @rc['search']['sisu']['db'] \ +        and @rc['search']['sisu']['db'] =~/\S+/ +          flag=if defined? @html_bits.widget_search \ +          and @html_bits.widget_search==true +            true +          elsif defined? @rc['search']['sisu']['flag'] \ +          and @rc['search']['sisu']['flag']==true +            true +          else +            false +          end +        else +          false +        end +      end +      def search_form(action=nil,db=nil) +        rc=SiSU_Env::GetInit.new.sisu_yaml.rc +        create_form=if defined? rc['search']['sisu']['flag'] \ +        and rc['search']['sisu']['flag']==true \ +        and action \ +        and db \ +        and action =~/https?:\/\// \ +        and db =~/\S+/ +          true +        elsif widget_static.search? \ +        and rc['search']['sisu']['flag']==true +          db=if rc['search']['sisu']['db']=~/\S+/ +            (rc['search']['sisu']['db']=~/^#{Db[:name_prefix]}\S+/) \ +            ? rc['search']['sisu']['db'] +            : "#{Db[:name_prefix]}#{rc['search']['sisu']['db']}" +          else nil +          end +          action=rc['search']['sisu']['action'] +          true +        else false +        end +        if create_form \ +        and @fnb \ +        and @fnb=~/\S+/ +          %{<!-- SiSU Search --> +<a name="search"></a> +<form method="get" action="#{rc['search']['sisu']['action']}" target="_top"> +<font size="2"> +<input type="text" name="s1" size="24" maxlength="255" /> +<br /> +<input type="hidden" name="db" value="#{db}" /> +<input type="hidden" name="doc" value="#{@fnb}" /> +<input type="submit" name="search" value="search doc" /> +<input type="submit" name="search" value="search db" /> +</font> +</form> +<!-- SiSU Search --> } +        elsif create_form +          %{<!-- SiSU Search --> +<a name="search"></a> +<form method="get" action="#{rc['search']['sisu']['action']}" target="_top"> +<font size="2"> +<input type="text" name="s1" size="24" maxlength="255" /> +<br /> +<input type="hidden" name="db" value="#{db}" /> +<input type="submit" name="search" value="search db" /> +</font> +</form> +<!-- SiSU Search --> } +        else '' +        end +      end +      def search_action #check +        if search? +        else '' +        end +      end +      self +    end +    def source_file_path +      file=@fns.gsub(/\.ssm(?:\.sst)?/,'.ssm.sst') +      unless file =~/\.ssm\.sst$/; "#{Dir.pwd}" +      else "#{processing_path.composite_file}" +      end +    end +    def source_file_with_path +      file=@fns.gsub(/\.ssm(?:\.sst)?/,'.ssm.sst') +      "#{source_file_path}/#{file}" +    end +    def texpdf_hyperlinks(cli) +      @cli=cli +      @hyplnks=if cli != :na +        cli +      elsif (defined? @rc['default']['pdf_hyperlinks']) \ +      && (@rc['default']['pdf_hyperlinks']=~/color/) +        :color +      elsif (defined? @rc['default']['pdf_hyperlinks']) \ +      && (@rc['default']['pdf_hyperlinks'] \ +      =~/(?:no-color|color-off|mono(?:chrome)?)/) +        :mono +      else :na +      end +      def landscape +        if @cli != :na +          @cli +        elsif (defined? @rc['default']['pdf_hyperlinks_landscape']) \ +        && (@rc['default']['pdf_hyperlinks_landscape']=~/color/) +          :color +        elsif (defined? @rc['default']['pdf_hyperlinks_landscape']) \ +        && (@rc['default']['pdf_hyperlinks_landscape'] \ +        =~/(?:no-color|color-off|mono(?:chrome)?)/) +          :mono +        elsif @hyplnks != :na +          @hyplnks +        else :na +        end +      end +      def portrait +        if @cli != :na +          @cli +        elsif (defined? @rc['default']['pdf_hyperlinks_portrait']) \ +        && (@rc['default']['pdf_hyperlinks_portrait']=~/color/) +          :color +        elsif (defined? @rc['default']['pdf_hyperlinks_portrait']) \ +        && (@rc['default']['pdf_hyperlinks_portrait'] \ +        =~/(?:no-color|color-off|mono(?:chrome)?)/) +          :mono +        elsif @hyplnks != :na +          @hyprlnks +        else :na +        end +      end +      self +    end +    def font +      def size(pt=nil) +        if pt && pt != :na +          pt +        elsif defined? @rc['default']['fontsize'] \ +        && @rc['default']['fontsize']=~/\d{1,2}/ +          @rc['default']['fontsize'] +        else :na +        end +      end +      def texpdf +        # you may wish to check selected font against available fonts: +        # fc-list :outline -f "%{family}\n" +        # fc-list :lang=ja +        def main +          (defined? @rc['default']['texpdf_fontface']) \ +          && (@rc['default']['texpdf_fontface']=~/\S{3,}/)  \ +          ? @rc['default']['texpdf_fontface'] +          : 'Liberation Sans' +        end +        def sans                       # not used +          (defined? @rc['default']['texpdf_fontface_sans']) \ +          && (@rc['default']['texpdf_fontface_sans']=~/\S{3,}/)  \ +          ? @rc['default']['texpdf_fontface_sans'] +          : 'Liberation Sans' +        end +        def serif                      # not used +          (defined? @rc['default']['texpdf_fontface_serif']) \ +          && (@rc['default']['texpdf_font_serif']=~/\S{3,}/)  \ +          ? @rc['default']['texpdf_fontface_serif'] +          : 'Liberation Serif' +        end +        def mono +          (defined? @rc['default']['texpdf_fontface_mono']) \ +          && (@rc['default']['texpdf_fontface_mono']=~/\S{3,}/)  \ +          ? @rc['default']['texpdf_fontface_mono'] +          : 'Liberation Mono' +        end +        def cjk +          (defined? @rc['default']['texpdf_fontface_cjk']) \ +          && (@rc['default']['texpdf_fontface_cjk']=~/\S{3,}/)  \ +          ? @rc['default']['texpdf_fontface_cjk'] +          : 'IPAGothic' # 'IPAGothic' # 'IPAMincho' # 'TakaoMincho' # 'VL Gothic' +        end +        def cjk_zh +          (defined? @rc['default']['texpdf_fontface_cjk_zh']) \ +          && (@rc['default']['texpdf_fontface_cjk_zh']=~/\S{3,}/)  \ +          ? @rc['default']['texpdf_fontface_cjk_zh'] +          : 'IPAGothic' +        end +        def cjk_ja +          (defined? @rc['default']['texpdf_fontface_cjk_ja']) \ +          && (@rc['default']['texpdf_fontface_cjk_ja']=~/\S{3,}/)  \ +          ? @rc['default']['texpdf_fontface_cjk_ja'] +          : 'IPAGothic' +        end +        def cjk_ko +          (defined? @rc['default']['texpdf_fontface_cjk_ko']) \ +          && (@rc['default']['texpdf_fontface_cjk_ko']=~/\S{3,}/)  \ +          ? @rc['default']['texpdf_fontface_cjk_ko'] +          : 'IPAGothic' +        end +        def size(pt=nil) +          if pt && pt != :na +            pt +          elsif (defined? @rc['default']['texpdf_fontsize']) \ +          && (@rc['default']['texpdf_fontsize']=~/\d{1,2}/) +            @rc['default']['texpdf_fontsize'] +          elsif (defined? @rc['default']['fontsize']) \ +          && (@rc['default']['fontsize']=~/\d{1,2}/) +            @rc['default']['fontsize'] +          else +            :na +          end +        end +        self +      end +      self +    end +    def path_rel_links +      def html_scroll_2 +        if @env.output_dir_structure.by_language_code? +          '../../' +        elsif @env.output_dir_structure.by_filetype? +          '../' +        else +          '../' +        end +      end +      def html_seg_2 +        if @env.output_dir_structure.by_language_code? +          '../../../' +        elsif @env.output_dir_structure.by_filetype? +          '../../' +        else +          '../' +        end +      end +      def html_scroll_1 +        if @env.output_dir_structure.by_language_code? +          '../' +        elsif @env.output_dir_structure.by_filetype? +          '../' +        else +          './' +        end +      end +      def html_seg_1 +        if @env.output_dir_structure.by_language_code? +          '../../' +        elsif @env.output_dir_structure.by_filetype? +          '../../' +        else +          './' +        end +      end +      self +    end +    def read_source_file_array(fns) +      (fns !~/\.ssm.sst$/) \ +      ? (IO.readlines(fns, mode: 'r:utf-8', cr_newline: true)) +      : (IO.readlines( +           "#{processing_path.composite_file}/#{fns}", +           mode: 'r:utf-8', +           cr_newline: true +        )) +    end +    def read_source_file(fns) +      read_source_file_array(fns) +    end +    def read_source_file_string(fns) +      (fns !~/\.ssm.sst$/) \ +      ? (IO.read(fns, mode: 'r:utf-8', cr_newline: true)) +      : (IO.read( +           "#{processing_path.composite_file}/#{fns}", +           mode: 'r:utf-8', +           cr_newline: true +        )) +    end +    def source_file_processing_array(fns) +      read_source_file_string(fns).split(/\s*\n\s*\n/m) +    end +    def path                           #dir +      def home +        @sys.home +      end +      def sisurc_path +        SiSU_Get_Init::GetInit.new.sisu_yaml.rc_path +      end +      def pwd +        @sys.pwd +      end +      def stub_pwd +        @stub_pwd +      end +      def base_markup_dir_stub +        @base_markup_dir_stub +      end +      def stub_epub +        @stub_epub +      end +      def stub_src +        @stub_src +      end +      def stub_pod +        @stub_pod +      end +      def etc +        defaults[:sisu_etc]            #live/dynamic +      end +      def arch +        @sys.dir_arch +      end +      def sitearch +        @sys.dir_sitearch +      end +      def bin +        @sys.dir_bin +      end +      def share                        #shared data repository source directory +        #SiSU_Utils::CodeMarker.new(__LINE__,__FILE__,:green). +        #  mark(defaults[:sisu_share]) +        defaults[:sisu_share] +      end +      def style +        if @md \ +        && ((@md.opt.opt_act[:dump][:bool] \ +        &&   @md.opt.opt_act[:dump][:inst]) \ +        ||  (@md.opt.opt_act[:redirect][:bool] \ +        &&   @md.opt.opt_act[:redirect][:inst])) +          'css' +        else +         defaults[:stylesheet_stub] +        end +      end +      def sample_data                  #sample data repository source directory +        defaults[:sample_data_path] +      end +      def rc +        @init.rc_path +      end +      def yamlrc +        GetInit.new.sisu_yaml.rc_path +      end +      def man #check use +        (defined? @rc['webserv']['man']) \ +        ? "#{webserv}/#{@rc['webserv']['man']}" +        : defaults[:webserv_man] +      end +      def webserv_path #testing, check need, remove +        webserv +      end +      def webserv                      #separation required for webrick which cannot use path.output (different requirements as no file is passed) +        man_path=if @@man_path.nil? +          man_path=if defined? @rc['webserv']['path'] \ +          and @rc['webserv']['path'] =~/\S\S+/ +            pwd=Dir.pwd +            Dir.chdir(SiSU_Utils::Path.new.base_markup) +            man_path=@@man_path=File.expand_path(@rc['webserv']['path']) +            Dir.chdir(pwd) +            man_path +          else defaults[:webserv_path] +          end +        else @@man_path +        end +        man_path_head=man_path.gsub(/(\S+)\/[^\/\s]+$/,'\1') +        unless FileTest.directory?(man_path) +          FileUtils::mkdir_p(man_path) if File.writable?("#{man_path_head}/.") +        end +        @webserv_path=if defined? man_path \ +        and File.writable?("#{man_path}/.") +          man_path #web server path as configured in rc file +        elsif FileTest.directory?(defaults[:webserv_path]) \ +        and File.writable?("#{defaults[:webserv_path]}/.") #web server path default +          defaults[:webserv_path] +        else #create default directory under home and place output there +          unless FileTest.directory?(defaults[:output_local]) +            FileUtils::mkdir_p(defaults[:output_local]) +          end +          defaults[:output_local] +        end +      end +      def webserv_stub_ensure +        FileUtils::mkdir_p(path.webserv) unless FileTest.directory?(path.webserv) +        FileUtils::mkdir_p("#{path.webserv}/#{@base_markup_dir_stub}") \ +          unless FileTest.directory?("#{path.webserv}/#{@base_markup_dir_stub}") +      end +      def webserv_map_pwd #dir +        "#{path.webserv}/#{base_markup_dir_stub}" +      end +      def webserv_dir                  #fixed/hard path to /www web/presentation directory, on Debian /var/www subdirectories are created within it, depending on markup directory stub-name (last segment of markup directory name) +        defaults[:webserv_dir] +      end +      def webserv_image                #web/presentation directory, subdirectories are created within it, depending on markup directory stub-name (last segment of markup directory name) +        images=if defined? @rc['webserv']['images'] +          @rc['webserv']['images'] +        else defaults[:images] +        end +        "#{path.webserv}/#{images}" +      end +      def output                       #web/webserv output directory... subdirectory into which further subdirectories are made based on file names +        r=Px[:lng_lst_rgx] +        u=/.+?\/([^\/]+)(?:\/(?:#{r})$|$)/ +        base_stub=@sys.pwd.gsub(u,'\1') +        if Dir.pwd =~/\/#{Gt[:sisupod]}\/[^\/]+\/#{Gt[:pod]}\/#{Gt[:doc]}/ +          "#{path.webserv}/#{Gt[:doc]}" +        else +          "#{path.webserv}/#{base_stub}" +        end +      end +      def feed +        (defined? @rc['webserv']['feed']) \ +        ? ("#{public_output}/#{@rc['webserv']['feed']}") +        : (defaults[:webserv_feed]) +      end +      def feed_home +        "#{public_output}/#{@rc['webserv']['feed_home']}" +      end +      def scripts                      #used previously only to include tla version info +        if defined? @rc['project']['path'] +          "#{home}/#{@rc['project']['path']}" +        end +      end +      def cgi +        (defined? @rc['webserv']['cgi']) \ +        ? "#{@rc['webserv']['cgi']}" +        : (defaults[:webserv_cgi]) +      end +      def php +        (defined? @rc['webserv']['php']) \ +        ? "#{public_output}/#{@rc['webserv']['php']}" +        : (defaults[:webserv_php]) +      end +      #% programs +      def output_tell +        url.webserv_map_pwd +      end +      def image_source_sisu_includes(md=nil) +        if md \ +        and (md.opt.sisu_install_type? == \ +        :full_path_to_sisu_bin_in_sisu_dir_tree) \ +        and FileTest.directory?( +          "#{md.opt.sisu_data_dir?}/image" +        )==true +          "#{md.opt.sisu_data_dir?}/image" +        else +          "#{share}/image" +        end +      end +      def image_source(md=nil)                 #image repository source directory +        if defined? @rc['image']['path'] \ +        and defined? @rc['image']['public'] +          pth="#{@rc['image']['path']}" +          "#{pth}/#{@rc['image']['public']}" +        else +          image_source_sisu_includes(md) +        end +      end +      def image_source_include(md=nil)         #image repository source directory +        if defined? @rc['image']['path'] \ +        and defined? @rc['image']['public'] \ +        and FileTest.directory?( +          "#{@rc['image']['path']}/#{@rc['image']['public']}" +        )==true +          "#{@rc['image']['path']}/#{@rc['image']['public']}" +        elsif FileTest.directory?("#{@@pwd}/#{defaults[:image_stub]}")==true +          "#{@@pwd}/#{defaults[:image_stub]}" +        elsif FileTest.directory?( +          "#{SiSU_Utils::Path.new.base_markup}/#{defaults[:image_stub]}" +        )==true +          "#{SiSU_Utils::Path.new.base_markup}/#{defaults[:image_stub]}" +        else +          image_source_sisu_includes(md) +        end +      end +      def image_external +        "#{processing}/external_document/image" +      end +      def image_source_include_local +        if FileTest.directory?(defaults[:image_local]) +          defaults[:image_local] +        end +      end +      def image_source_include_remote +        if FileTest.directory?(image_external) +          image_external +        end +      end +      self +    end +    def processing_path +      def encoding +        pth="#{processing}/#{defaults[:processing_encoding]}" +        FileUtils::mkdir_p(pth) unless FileTest.directory?(pth) +        pth +      end +      def processing_base_tmp +        defaults[:processing_path_tmp_base] +      end +      def tmp_root_dir +        defaults[:processing_dir_tmp_root] +      end +      def root_dir +        proposed_path_base=if defined? @rc['processing']['path'] \ +        and not @rc['processing']['path'].nil? \ +        and not @rc['processing']['path'].empty? +          x=if @rc['processing']['path'] =~/^(?:~|home)$/ +            home #fix +          else @rc['processing']['path'] +          end +        else nil +        end +        proposed_dir=if defined? @rc['processing']['dir'] \ +        and not @rc['processing']['dir'].nil? \ +        and not @rc['processing']['dir'].empty? +          @rc['processing']['dir'] +        else defaults[:processing_dir] +        end +        v=SiSU_Env::InfoVersion.instance.get_version +        v_dev=(DEVELOPER[:maintenance]==:true) \ +        ? "_#{v.version}" +        : '' +        path=if proposed_path_base \ +        and FileTest.directory?(proposed_path_base) \ +        and File.writable?("#{proposed_path_base}/.") +          x=proposed_dir \ +          ? "#{proposed_path_base}/#{proposed_dir}" +          : "#{proposed_path_base}/#{defaults[:processing_dir]}" +        else defaults[:processing_dir_tmp_root] +        end +        path = path + v_dev +      end +      def usr_dir? +        case root_dir +        when /^\/home/ then false +        else                true +        end +      end +      def stub_dir +        (usr_dir?) \ +        ? ("#{root_dir}/#{user}/#{stub_pwd}") +        : ("#{root_dir}/#{stub_pwd}") # see defaults[:processing_path] +      end +      def stub_dir_orig # ends up with lang, if lang dir +        (usr_dir?) \ +        ? ("#{root_dir}/#{user}/#{stub_pwd}") +        : ("#{root_dir}/#{stub_pwd}") # see defaults[:processing_path] +      end +      def processing_sisupod(opt=nil)  #processing directory, used/needed for sisu work files, has sub-directories (ao,tex etc) +        @opt=opt +        def paths +          processing_path_usr="#{root_dir}/#{user}" +          processing_path_fnb=processing_path_usr \ +            + '/' + Gt[:pods] \ +            + '/' + @opt.fng +          processing_path_sisupod=processing_path_fnb \ +            + '/' + Gt[:sisupod] +          { +            fnb: processing_path_fnb, +            sisupod: processing_path_sisupod, +          } +        end +        def make +          unless FileTest.directory?(root_dir) +            FileUtils::mkdir_p(root_dir) +            File.chmod(0777,root_dir) +          end +          if usr_dir? +            processing_path_usr="#{root_dir}/#{user}" +            FileUtils::mkdir_p(processing_path_usr) \ +              unless FileTest.directory?(processing_path_usr) +            File.chmod(0700,processing_path_usr) +          end +          sisupod_processing_path=paths[:sisupod] +          FileUtils::mkdir_p(sisupod_processing_path) \ +            unless FileTest.directory?(sisupod_processing_path) +          sisupod_processing_path_lng=if defined? @opt.lng +            sisupod_processing_path \ +              + '/' + Gt[:doc] \ +              + '/' + @opt.lng +          else +            sisupod_processing_path \ +              + '/' + Gt[:doc] +          end +          unless FileTest.directory?(sisupod_processing_path_lng) +            #puts "a processing directory (#{sisupod_processing_path_lng}) is being created for use by sisu" +            FileUtils::mkdir_p(sisupod_processing_path_lng) +            File.chmod(0700,sisupod_processing_path_lng) +          end +          sisupod_processing_path +        end +        self +      end +      def processing                   #processing directory, used/needed for sisu work files, has sub-directories (ao,tex etc) +        unless FileTest.directory?(root_dir) +          FileUtils::mkdir_p(root_dir) +          File.chmod(0777,root_dir) +        end +        if usr_dir? +          processing_path_usr="#{root_dir}/#{user}" +          FileUtils::mkdir_p(processing_path_usr) \ +            unless FileTest.directory?(processing_path_usr) +          File.chmod(0700,processing_path_usr) +        end +        FileUtils::mkdir_p(stub_dir) \ +          unless FileTest.directory?(stub_dir) +        File.chmod(0700,stub_dir) +        path_processing=[ +          stub_dir, +          defaults[:processing_path], +          defaults[:processing_path_home] +        ] +        processing=nil +        path_processing.each do |v|                                              # +          processing=v +          unless FileTest.directory?(processing) +            FileUtils::mkdir_p(processing) +            File.chmod(0700,processing) +          end +          break +        end +        processing +      end +      def ao +        pth=if defined? @rc['processing']['dal'] \ +          and @rc['processing']['dal'].is_a?(String) +          "#{processing}/#{@rc['processing']['dal']}" +        else "#{processing}/#{defaults[:processing_ao]}" +        end +        FileUtils::mkdir_p(pth) unless FileTest.directory?(pth) +        pth +      end +      def tune +        pth=if defined? @rc['processing']['tune'] \ +          and @rc['processing']['tune'].is_a?(String) +          "#{processing}/#{@rc['processing']['tune']}" +        else "#{processing}/#{defaults[:processing_tune]}" +        end +        FileUtils::mkdir_p(pth) unless FileTest.directory?(pth) +        pth +      end +      def composite_file +        pth=processing_path.ao  #"#{processing}/composite" +        FileUtils::mkdir_p(pth) unless FileTest.directory?(pth) +        pth +      end +      def git +        pth=if defined? @rc['git']['dir'] \ +        and @rc['git']['dir'].is_a?(String) +          (@rc['git']['dir'] =~/^(?:~|home)$/) \ +          ? home + '/' + Gt[:git] +          : @rc['git']['dir'] + '/' + Gt[:git] +        else defaults[:processing_git] +        end +        unless FileTest.directory?(pth) +          FileUtils::mkdir_p(pth) +          File.chmod(0700,pth) +        end +        pth +      end +      def odf_pth +        pth="#{processing}/odf/#{@fns}" +        pth +      end +      def odf +        odt +      end +      def odt +        pth=odf_pth + '/odt' +        FileUtils::mkdir_p(pth) unless FileTest.directory?(pth) +        pth +      end +      def odf +        pth="#{processing}/odf" +        FileUtils::mkdir_p(pth) unless FileTest.directory?(pth) +        pth +      end +      def odt_bld +        FileUtils::rm_rf(processing_path.odt) +        FileUtils::mkdir_p(processing_path.odt) \ +          unless FileTest.directory?(processing_path.odt) +        FileUtils::mkdir_p("#{processing_path.odt}/Configurations2") \ +          unless FileTest.directory?("#{processing_path.odt}/Configurations2") +        FileUtils::mkdir_p("#{processing_path.odt}/META-INF") \ +          unless FileTest.directory?("#{processing_path.odt}/META-INF") +        FileUtils::mkdir_p("#{processing_path.odt}/Pictures") \ +          unless FileTest.directory?("#{processing_path.odt}/Pictures") +        FileUtils::mkdir_p("#{processing_path.odt}/Thumbnails") \ +          unless FileTest.directory?("#{processing_path.odt}/Thumbnails") +        processing_path.odt +      end +      def epub +        "#{processing}/epub/#{@fnb}" +      end +      def epub_bld #(md) +        FileUtils::rm_rf(processing_path.epub) \ +          if FileTest.directory?(processing_path.epub) +        FileUtils::mkdir_p(processing_path.epub) \ +          unless FileTest.directory?(processing_path.epub) +        FileUtils::mkdir_p("#{processing_path.epub}/META-INF") \ +          unless FileTest.directory?("#{processing_path.epub}/META-INF") +        FileUtils::mkdir_p("#{processing_path.epub}/#{Ep[:d_oebps]}/image") \ +          unless FileTest.directory?("#{processing_path.epub}/#{Ep[:d_oebps]}/image") +        FileUtils::mkdir_p("#{processing_path.epub}/#{Ep[:d_oebps]}/css") \ +          unless FileTest.directory?("#{processing_path.epub}/#{Ep[:d_oebps]}/css") +        processing_path.epub +      end +      def epub_cp_images(md) +        pth="#{processing_path.epub}/#{Ep[:d_oebps]}/image" +        FileUtils::mkdir_p(pth) unless FileTest.directory?(pth) +        src=(md.opt.sisu_install_type? == :full_path_to_sisu_bin_in_sisu_dir_tree) \ +        ? "#{md.opt.sisu_data_dir?}/image" +        : "#{md.opt.sisu_data_dir?}/sisu/image" +        images=%W[bullet_09.png arrow_next_red.png arrow_prev_red.png arrow_up_red.png] +        images.each do |i| #move to avoid repeated tests +          if FileTest.file?("#{src}/#{i}") +            FileUtils::cp("#{src}/#{i}","#{pth}/#{i}") \ +              unless FileTest.file?("#{pth}/#{i}") +          else STDERR.puts %{\t*WARN* did not find image - "#{i}" [#{__FILE__}:#{__LINE__}]} +          end +        end +        pth +      end +      def tex +        pth=if defined? @rc['processing']['latex'] \ +        and @rc['processing']['latex'].is_a?(String) +          "#{processing}/#{@rc['processing']['latex']}" +        else "#{processing}/#{defaults[:processing_latex]}" +        end +        FileUtils::mkdir_p(pth) unless FileTest.directory?(pth) +        pth +      end +      def texi +        pth=if defined? @rc['processing']['texinfo'] \ +        and @rc['processing']['texinfo'].is_a?(String) +          "#{processing}/#{@rc['processing']['texinfo']}" +        else "#{processing}/#{defaults[:processing_texinfo]}" +        end +        FileUtils::mkdir_p(pth) unless FileTest.directory?(pth) +        pth +      end +      def texinfo                      #texinfo webserv, check +        "#{processing}/#{defaults[:processing_texinfo]}" +      end +      def manpage +        "#{path.output}/man" +      end +      def lout +        pth=if defined? @rc['processing']['lout'] \ +        and @rc['processing']['lout'].is_a?(String) +          "#{processing}/#{@rc['processing']['lout']}" +        else "#{processing}/#{defaults[:processing_lout]}" +        end +        FileUtils::mkdir_p(pth) unless FileTest.directory?(pth) +        pth +      end +      def sql +        pth="#{processing}/sql" +        FileUtils::mkdir_p(pth) unless FileTest.directory?(pth) +        pth +      end +      def sqlite +        pth=if defined? @rc['processing']['sqlite'] \ +        and @rc['processing']['sqlite'].is_a?(String) +          "#{processing}/#{@rc['processing']['sqlite']}" +        else "#{processing}/#{defaults[:processing_sqlite]}" +        end +        FileUtils::mkdir_p(pth) unless FileTest.directory?(pth) +        pth +      end +      def postgresql +        pth=if defined? @rc['processing']['postgresql'] \ +        and @rc['processing']['postgresql'].is_a?(String) +          "#{processing}/#{@rc['processing']['postgresql']}" +        else "#{processing}/#{defaults[:processing_postgresql]}" +        end +        FileUtils::mkdir_p(pth) unless FileTest.directory?(pth) +        pth +      end +      self +    end +    def url +      def hostname +        "http://#{@sys.hostname}" +      end +      def dir_url +        "file://#{path.webserv}/#{stub_pwd}" +      end +      def localhost +        "http://localhost/#{stub_pwd}" +      end +      def local +        "http://#{hostname}/#{@stub_pwd}" +      end +      def root +        if defined? @rc['webserv']['url_root'] \ +        and @rc['webserv']['url_root'] =~/https?:\/\// +          "#{@rc['webserv']['url_root']}/#{@stub_pwd}" +        elsif defined? @rc['webserv']['url_root'] \ +        and @rc['webserv']['url_root'] =~/localhost/ +          "http://localhost/#{@stub_pwd}" +        else "file://#{path.output}" +        end +      end +      def remote +        root +      end +      def txt +        "#{root}/txt" +      end +      def html +        "#{root}/html" +      end +      def epub +        "#{root}/epub" +      end +      def odt +        "#{root}/odt" +      end +      def pdf +        "#{root}/pdf" +      end +      def src_txt +        "#{root}/src" +      end +      def src_pod +        "#{root}/pod" +      end +      def pot +        "#{root}/po4a/pot" +      end +      def po +        "#{root}/po4a/po" +      end +      def webserv_host_base(opt=nil) +        if defined? @rc['webserv']['host'] +          case  @rc['webserv']['host'] +          when /https?:\/\// then @rc['webserv']['host'] +          when /\S+/         then "http://#{@rc['webserv']['host']}" +          else                    defaults[:webserv_host_cgi] +          end +        else                      defaults[:webserv_host_cgi] +        end +      end +      def webserv_cgi(opt=nil)         #web url for local webserv (localhost, or hostname) +        http=if defined? @rc['webserv_cgi']['host'] \ +        and @rc['webserv_cgi']['host'].is_a?(String) +          http=((@rc['webserv_cgi']['host'] =~ /https?:\/\//) ? '' : 'http://') #check https? missing +          if port.webserv_port_cgi +            http + @rc['webserv_cgi']['host'] + ':' \ +            + port.webserv_port_cgi + '/' \ +            + @stub_pwd +          else +            http + @rc['webserv_cgi']['host'] + '/' \ +            + @stub_pwd +          end +        else +          http=((webserv_host_base=~/https?:\/\//) ? '' : 'http://') +          if port.webserv_port_cgi(opt) +            http + webserv_host_base + ':' \ +            + port.webserv_port_cgi(opt) + '/'\ +            + @stub_pwd +          else +            http + webserv_host_base + '/' \ +            + @stub_pwd +          end +        end +        http=http.strip +      end +      def webserv_base_cgi(opt=nil)    #web url for local webserv (localhost, or hostname) +        http_cgi=if opt.selections.str =~/--webserv-(?:cgi|db|search)[=-]["']?(\S+)["']+/ +          m=$1 +          (m=~/http\/\/:/) ? m : %{http://#{m}} +        elsif defined? @rc['webserv_cgi']['host'] \ +        and @rc['webserv_cgi']['host'].is_a?(String) +          http=((@rc['webserv_cgi']['host'] =~ /https?:\/\//) ? '' : 'http://') +          if port.webserv_port_cgi(opt) +            http + @rc['webserv_cgi']['host'] + ':' \ +            + port.webserv_port_cgi(opt).to_s +          else +            http + @rc['webserv_cgi']['host'] +          end +        else +          http=((webserv_host_base=~/https?:\/\//) ? '' : 'http://') +          if port.webserv_port_cgi(opt) +            http + webserv_host_base + ':' \ +            + port.webserv_port_cgi(opt).to_s +          else http + webserv_host_base +          end +        end +        http_cgi=http_cgi.strip +        #%q{http://#{ENV['HTTP_HOST']}} +      end +      def webrick #must have a port    #REMOVE +        if defined? @rc['webserv_cgi']['host'] \ +        and @rc['webserv_cgi']['host'].is_a?(String) +          http=if @rc['webserv_cgi']['host'] =~/http:\/\// +            'http://' +          elsif @rc['webserv_cgi']['host'] =~/https:\/\// +            'https://' +          else defaults +          end +          http + @rc['webserv_cgi']['host'] +        elsif webserv_host_base \ +        and webserv_host_base.is_a?(String) +          webserv_host_base +        else +          #http + 'localhost' +          'localhost' +        end +      end +      def webserv                      #web url for local webserv (localhost, or hostname) +        if defined? @rc['webserv']['url_root'] \ +        and @rc['webserv']['url_root'] =~/http/ +          # needed for alternative output dir structures, fixes manifest url links, check may cause problems elsewhere +          @rc['webserv']['url_root'] +        elsif path.webserv_dir \ +        and path.webserv =~ /#{path.webserv_dir}/ #revisit +          path.webserv + '/' \ +            + @base_markup_dir_stub. +              gsub(/#{path.webserv_dir}/, +                "#{url.hostname}/#{@stub_pwd}") +        elsif defined? @rc['webserv']['webrick_url'] \ +        and @rc['webserv']['webrick_url']==false +          'file://' + path.webserv +        elsif port.webserv_port_cgi =~/\S+/ +          url.hostname + ':' + port.webserv_port_cgi +        else +          url.hostname +        end +      end +      def webserv_base                 #web url for local webserv (localhost, or hostname) +        if path.webserv_dir \ +        and path.webserv =~ /#{path.webserv_dir}/ #revisit +          path.webserv + '/' \ +          + @stub_pwd. +            gsub(/#{path.webserv_dir}/, +              "#{url.hostname}") +        elsif defined? @rc['webserv']['webrick_url'] \ +        and @rc['webserv']['webrick_url']==false +          "file://#{path.webserv}" +        else "#{url.webrick_base}" +        end +      end +      def webserv_files_from_db(opt=nil) #sort this out, messy +        if opt.selections.str =~/--webserv-output[=-]["']?(\S+)["']+/ +          m=$1 +          (m=~/(?:http|file\/)\/\/:/) ? m : %{http://#{m}} +        else +          show_output_on=if defined? @rc['webserv_cgi']['show_output_on'] +            @rc['webserv_cgi']['show_output_on'] +          elsif  defined? @rc['webserv_cgi']['file_links'] +            @rc['webserv_cgi']['file_links'] +          else '' +          end +          m=case show_output_on +          when /webserv_cgi/ then url.webserv_base_cgi(opt) +          when /webserv/     then @rc['webserv']['url_root'] +          when /https?:\/\// then @rc['webserv_cgi']['file_links'] +          when /\S+/         then 'http://' + @rc['webserv_cgi']['file_links'] +          else                     webserv_base_cgi(opt) +          end +        end +        #%q{http://#{ENV['HTTP_HOST']}/cgi-bin} +      end +      def cgi_sample_search_form_name(opt=nil) +        if opt.selections.str \ +        =~/--(?:cgi-)?search-form-name[=-]["']?(\S+?\.cgi)/ +          $1 +        elsif not opt.selections.str =~/--db[=-]["']?sqlite/ \ +        and defined? @rc['search'] \ +        and defined? @rc['search']['sisu'] \ +        and defined? @rc['search']['sisu']['action'] \ +        and @rc['search']['sisu']['action'] =~/https?:\/\/\S+?\.cgi/ +          /(?:https?:\/\/\S+?)\/([^\/]+?\.cgi)$/. +            match(@rc['search']['sisu']['action'])[1] +        else +          (opt.selections.str =~/--db[=-]["']?sqlite/) \ +          ? "#{Db[:name_prefix_db]}sqlite.cgi" \ +          :  "#{Db[:name_prefix_db]}pg.cgi" +        end +      end +      def sample_search_form_title(organised_by=:language) +        title=if defined? @rc['search']['sisu']['title'] \ +        and @rc['search']['sisu']['title'] =~/\S+/ +          @rc['search']['sisu']['title'] +        else %{SiSU (generated sample) search form} +        end +        title=title + " (content organised by #{organised_by})" +      end +      def output_tell                  #BROKEN Revisit 2011-02 +        output_type=if defined? @rc['show_output_on'] \ +        and @rc['show_output_on'] \ +        =~/^(?:filesystem|webserv|(?:local|remote)(?:_webserv)?|webrick)/ +          @rc['show_output_on'] +        else 'filesystem' +        end +        case output_type +        when /^filesystem(?:_url)?/       then url.dir_url +        when /^remote(?:_webserv)?/       then url.remote +        when /^(?:webserv|local_webserv)/ then url.local +        when /^local(:\d+)/               then url.hostname + $1 + '/' + stub_pwd +        when /^localhost(:\d+)/           then url.localhost + $1 +  '/' + stub_pwd +        when /^localhost/                 then url.localhost +        when /^webrick/                   then url.webrick +        when /^path/                      then url.webserv_map_pwd +        else                                   url.webserv_map_pwd +        end +      end +      def images +        "#{Xx[:html_relative2]}/_sisu/image" +      end +      #def images +      #  '../_sisu/image' +      #end +      def images_local +        if FileTest.directory?(path.image_source_include) +          path.image_source_include +        else +          if @@local_image==true +            cmd=@md.opt.selections.str ? @md.opt.selections.str : '' +            SiSU_Screen::Ansi.new( +              cmd, +              "WARNING - no local image directory or images:", +              defaults[:image_local] +            ).warn unless @md.opt.act[:quiet][:set]==:on +            @@local_image=false +          end +          url.images +        end +      end +      def images_external +        if FileTest.directory?(image_external) +          if @@image_flag +            images=Dir.glob("#{image_external}/*.{png,jpg,gif}") +            pth=path.webserv + '/' \ +            + @stub_pwd +            FileUtils::mkdir_p("#{pth}/_sisu/image_external") \ +              unless FileTest.directory?("#{pth}/_sisu/image_external") +            images.each { |i| File.install(i,"#{pth}/#{i}") } \ +              unless images.length > 0 +            @@image_flag=false +          end +          "#{Xx[:html_relative2]}/_sisu/image_external" +        else +          if @@local_image==true +            SiSU_Screen::Ansi.new( +              @cmd, +              'WARNING - image directory for external images or no such images:', +              :image_external +            ).warn unless @md.opt.act[:quiet][:set]==:on +            @@local_image=false +          end +          url.images_external +        end +      end +      def images_epub +        './image' +      end +      self +    end +    def port +      def webrick_port +        if @md \ +        and @md.opt.act[:sample_search_form][:set]==:on \ +        and @md.opt.selections.str=~/port=(\d+)/ +           $1 +        else +          if defined? @rc['webserv_cgi']['port'] +            if @rc['webserv_cgi']['port'].nil? \ +            and (defined? @md.opt.selections \ +            and @md.opt.selections.str=~/webrick/) +              defaults[:webserv_port_cgi] +            elsif not @rc['webserv_cgi']['port'].nil? +              @rc['webserv_cgi']['port'] +            else defaults[:webserv_port_cgi] +            end +          else   defaults[:webserv_port_cgi] +          end +        end +      end +      def webserv_port_cgi(opt=nil) +        port=if opt \ +        and opt.act[:sample_search_form][:set]==:on \ +        and opt.selections.str=~/port[=-](\d+)/ +           $1 +        else +          port=if defined? @rc['webserv_cgi']['port'] +            if @rc['webserv_cgi']['port'].nil? \ +            and (defined? opt.selections \ +            and opt.selections.str=~/webrick/) +              defaults[:webserv_port_cgi] +            elsif not @rc['webserv_cgi']['port'].nil? +              @rc['webserv_cgi']['port'] +            else nil +            end +          else +            if (defined? opt.selections \ +            and opt.selections.str=~/webrick/) +              defaults[:webserv_port_cgi] +            else nil +            end +          end +        end +        port.to_s +      end +      self +    end +    def digest_conf? +      if defined? @rc['default']['digest'] \ +      and @rc['default']['digest'] != nil +        case @rc['default']['digest'] +        when /^sha(?:5|512)?$/ then :sha512 +        when /^sha(?:2|256)?$/ then :sha256 +        when /^md5$/           then :md5 +        else                        :sha256 +        end +      else                          :sha256 +      end +    end +    def digest(opt=nil) +      @opt=opt +      def type +        if @opt +          case @opt.act[:hash_digest_algo] +          when :sha512 then :sha512 +          when :sha256 then :sha256 +          when :md5    then :md5 +          else              digest_conf? +          end +        else                digest_conf? +        end +      end +      def length +        case digest(@opt).type +        when :sha512 then 128 +        when :sha256 then  64 +        when :md5    then  32 +        else               64 +        end +      end +      def pattern +        "[0-9a-f]{#{digest(@opt).length}}" #/[0-9a-f]{#{digest.length}}/ +      end +      self +    end +    def program +      def text_editor +        if defined? @rc['program_select']['editor'] \ +        and @rc['program_select']['editor'] =~/\S\S+/ +          @rc['program_select']['editor'] +        elsif defined? @rc['program_select']['text_editor'] \ +        and @rc['program_select']['text_editor'] =~/\S\S+/ +          @rc['program_select']['text_editor'] +        else 'editor'                                                            #'gvim -c :R -c :S' +        end +      end +      def pdf_viewer +        ((defined? @rc['program_select']['pdf_viewer']) \ +        && @rc['program_select']['pdf_viewer'] =~/\S\S+/) \ +        ? @rc['program_select']['pdf_viewer'] +        : 'pdf-viewer'                                                        #'evince' +      end +      def web_browser +        if defined? @rc['program_select']['www_browser'] \ +        and @rc['program_select']['www_browser'] =~/\S\S+/ +          @rc['program_select']['www_browser'] +        elsif defined? @rc['program_select']['web_browser'] \ +        and @rc['program_select']['web_browser'] =~/\S\S+/ +          @rc['program_select']['web_browser'] +        else 'x-www-browser'                                                      #'firefox' 'iceweasel' 'kazehakase' 'galeon' +        end +      end +      def www_browser +        web_browser +      end +      def console_web_browser +        if defined? @rc['program_select']['console_www_browser'] \ +        and @rc['program_select']['console_www_browser'] =~/\S\S+/ +          @rc['program_select']['console_www_browser'] +        elsif defined? @rc['program_select']['console_web_browser'] \ +        and @rc['program_select']['console_web_browser'] =~/\S\S+/ +          @rc['program_select']['console_web_browser'] +        else 'console-www-browser'                                             #'lynx' 'links' 'links2' 'elinks' 'w3m' +        end +      end +      def console_www_browser +        web_browser +      end +      def epub_viewer +        ((defined? @rc['program_select']['epub_viewer']) \ +        && @rc['program_select']['epub_viewer'] =~/\S\S+/) \ +        ? @rc['program_select']['epub_viewer'] +        : 'ebook-viewer'                                                    #'calibre' 'fbreader' +      end +      def xml_viewer +        ((defined? @rc['program_select']['xml_viewer']) \ +        && @rc['program_select']['xml_viewer'] =~/\S\S+/) \ +        ? @rc['program_select']['xml_viewer'] +        : text_editor +      end +      def docbook_viewer +        ((defined? @rc['program_select']['xml_viewer']) \ +        && @rc['program_select']['xml_viewer'] =~/\S\S+/) \ +        ? @rc['program_select']['xml_viewer'] +        : text_editor +      end +      def fictionbook_viewer +        ((defined? @rc['program_select']['xml_viewer']) \ +        && @rc['program_select']['xml_viewer'] =~/\S\S+/) \ +        ? @rc['program_select']['xml_viewer'] +        : text_editor +      end +      def xml_editor +        xml_viewer +      end +      def odf_viewer +        ((defined? @rc['program_select']['odf_viewer']) \ +        && @rc['program_select']['odf_viewer'] =~/\S\S+/) \ +        ? @rc['program_select']['odf_viewer'] +        : 'lowriter'                                                           #'odf-viewer','oowriter' +      end +      def manpage_viewer +        'man' +      end +      def manpage_generator +        ((defined? @rc['program_select']['man']) \ +        && @rc['program_select']['man'] =~/\S\S+/) \ +        ? @rc['program_select']['man'] +        : 'nroff -man'                                                        #'nroff -man' #'groff -man -Tascii' +      end +      def texinfo +        ((defined? @rc['program_select']['info_viewer']) \ +        && @rc['program_select']['info_viewer'] =~/\S\S+/) \ +        ? @rc['program_select']['info_viewer'] +        : 'pinfo -f'                                                          #'pinfo -f' 'info' 'tkinfo' +      end +      def file_encoding +        is=(defined? @rc['program_set']['file_encoding']) \ +        ? @rc['program_set']['encoding'] : '' +        (is.nil? || is==true) ? 'encoding' : is +      end +      def wc #wordcount +        is=(defined? @rc['program_set']['wc']) \ +          ? @rc['program_set']['wc'] : '' +        (is.nil? || is==true) ? 'wc' : is +      end +      def tidy +        is=(defined? @rc['program_set']['tidy']) \ +          ? @rc['program_set']['tidy'] : nil +        (is.nil? || is==true) ? 'tidy' : is +      end +      def rmagick +        is=(defined? @rc['program_set']['rmagick']) \ +          ? @rc['program_set']['rmagick'] : nil +        (is.nil? || is==true) ? 'rmagick' : is +      end +      def rexml                        #should be part of ruby 1.8 but apparently not always +        is=(defined? @rc['program_set']['rexml']) ? \ +          @rc['program_set']['rexml'] : '' +        (is.nil? || is==true) ? 'rexml' : is +      end +      def pdflatex +        is=(defined? @rc['program_set']['pdflatex']) ? \ +          @rc['program_set']['pdflatex'] : '' +        (is.nil? || is==true) ? 'pdflatex' : is +      end +      def postgresql +        is=(defined? @rc['program_set']['postgresql']) ? \ +          @rc['program_set']['postgresql'] : '' +        (is.nil? || is==true) ? 'postgresql' : is +      end +      def sqlite +        is=(defined? @rc['program_set']['sqlite']) ? \ +          @rc['program_set']['sqlite'] : '' +        (is.nil? || is==true) ? 'sqlite' : is +      end +      self +    end +    def i18n +      def language                     # language settings +        m=/.+\/\S+?\~(\S+)/ +        pwd=Dir.pwd +        conf=(defined? @rc['default']['language']) \ +        ? @rc['default']['language'] : nil +        l=if pwd=~ m    then pwd[m,1]                                        #2 directory: by visible directory name +        elsif conf      then @rc['default']['language']                      #3 config: from sisurc.yaml +        else            defaults[:language]                                  #4 sisu: program default +        end                                                                  #1 document: param gets +        SiSU_Env::StandardiseLanguage.new(l) +      end +      #def multilingual +      #  x=(defined? @rc['output_structure']['multilingual'] \ +      #  && @rc['output_structure']['multilingual'] ==true) \ +      #  ? true : false +      #end +      #def bundle +      #  x=(defined? @rc['output_structure']['bundle'] \ +      #  && @rc['output_structure']['bundle'] ==true) \ +      #  ? true : false +      #end +      def lang_filename(l) +        @lang={} +        x=if output_dir_structure.by_language_code? +          (( defined? @rc['default']['language_file']) \ +          && @rc['default']['language_file'] != nil) \ +          ? @rc['default']['language_file'] +          : 1 +        else 0 +        end +        if (l != defaults[:language_code]) \ +        or (language.code != defaults[:language_code]) #watch +          if x==1    then @lang[:pre],@lang[:mid],@lang[:post]="#{l}.",'','' +          elsif x==2 then @lang[:pre],@lang[:mid],@lang[:post]='',".#{l}",'' +          elsif x==3 then @lang[:pre],@lang[:mid],@lang[:post]='','',".#{l}" +          else            @lang[:pre],@lang[:mid],@lang[:post]='','','' +          end +        else              @lang[:pre],@lang[:mid],@lang[:post]='','','' +        end +        @lang +      end +      self +    end +    def file_encoding +      is='' +      if defined? @rc['program_set']['file_encoding'] +        is=@rc['program_set']['encoding'] +      end +      if is.nil? \ +      or is==true +        is='encoding' +      end +      is +    end +    def papersize                      # paper settings, default overidden in param if set within document +      (defined? @rc['default']['papersize']) \ +      ? @rc['default']['papersize'].downcase +      : (defaults[:papersize].downcase) +    end +    def sisupod_gen(fns_pod) +      sisupod_gen_v3(fns_pod) +    end +    def sisupod_gen_v3(fns_pod) +      pwd=Dir.pwd +      sisupod_processing_path= +        processing_path.processing + '/' + Gt[:sisupod] +      if FileTest.directory?(sisupod_processing_path) \ +      or FileTest.file?(sisupod_processing_path) +        FileUtils::rm_rf(sisupod_processing_path) +      end +      unless FileTest.directory?(sisupod_processing_path) +        FileUtils::mkdir_p(sisupod_processing_path) +      end +      f_pod=if FileTest.file?("#{Dir.pwd}/#{fns_pod}") +        "#{Dir.pwd}/#{fns_pod}" +      elsif FileTest.file?(fns_pod) +        fns_pod +      end +      if f_pod \ +      && FileTest.file?(f_pod) +        (SiSU_Env::SystemCall.new.program_found?('tree')) \ +        ? 'tree ' + processing_path.processing + '/' + Gt[:sisupod] +        : '' +        if FileTest.directory?(processing_path.processing) +          Dir.chdir(processing_path.processing) +          system(%{tar xJf #{f_pod}}) +          Dir.chdir(pwd) +        end +        #system(tree)                                                          #enable if (/[vVM]/) +      else +        SiSU_Screen::Ansi.new( +          '', +          '*WARN* file not found: ' + fns_pod +        ).warn unless @md.opt.act[:quiet][:set]==:on +      end +      sisupod_processing_path +    end +    def sisupod_gen_v2(fns_pod) +      sisupod_processing_path= +        processing_path.processing + '/' + Gt[:sisupod] +      if FileTest.directory?(sisupod_processing_path) \ +      or FileTest.file?(sisupod_processing_path) +        FileUtils::rm_rf(sisupod_processing_path) +      end +      unless FileTest.directory?(sisupod_processing_path) +        FileUtils::mkdir_p(sisupod_processing_path) +      end +      (FileTest.file?(fns_pod)) \ +      ? system("unzip -q #{fns_pod} -d #{processing_path.processing}") +      : (SiSU_Screen::Ansi.new( +          '', +          "*WARN* file not found: #{fns_pod}" +        ).warn unless @md.opt.act[:quiet][:set]==:on) +      sisupod_processing_path +    end +  end +end +__END__ +#+END_SRC + +** se_info_port.rb + +#+BEGIN_SRC ruby  :tangle "../lib/sisu/se_info_port.rb" +# <<sisu_document_header>> +module SiSU_Info_Port +  require_relative 'constants'                             # constants.rb +  require_relative 'utils'                                 # utils.rb +  require_relative 'se_info_env'                           # se_info_env.rb +  class InfoPort < SiSU_Info_Env::InfoEnv                  # se_info_env.rb +    def initialize +      @env=SiSU_Env::InfoEnv.new +    end +    def webrick +      @env.port.webrick_port +    end +  end +end +__END__ +#+END_SRC + +** se_info_system.rb + +#+BEGIN_SRC ruby  :tangle "../lib/sisu/se_info_system.rb" +# <<sisu_document_header>> +module SiSU_Info_Sys_Gen +  require_relative 'constants'                             # constants.rb +  require_relative 'utils'                                 # utils.rb +  class InfoSystemGen +    begin +      require 'rbconfig' +    rescue LoadError +      SiSU_Utils::CodeMarker.new(__LINE__,__FILE__,:fuchsia). +        error('rbconfig NOT FOUND (LoadError)') +    end +    @@user,       @@home,     @@hostname,     @@pwd,     @@sisu_etc,                            @@host,                @@arch,                @@rbver,          @@dir_arch,               @@dir_sitearch,               @@dir_bin,               @@locale,                @@rc,@@sisurc_path,@@ad= +      ENV['USER'],ENV['HOME'],ENV['HOSTNAME'],ENV['PWD'],RbConfig::CONFIG['sysconfdir'] + '/sisu',RbConfig::CONFIG['host'],RbConfig::CONFIG['arch'],%x{ruby -v}.strip,RbConfig::CONFIG['archdir'],RbConfig::CONFIG['sitearchdir'],RbConfig::CONFIG['bindir'],%x{locale charmap}.strip,nil, nil,          {} # %x{ruby -v}.strip # RbConfig::CONFIG['rb_ver'] +    out=RbConfig::CONFIG['localstatedir'] +    etc=RbConfig::CONFIG['sysconfdir'] + '/sisu' +    share=RbConfig::CONFIG['datadir']  + '/sisu' +    data=RbConfig::CONFIG['datadir']   + '/doc/sisu' +    m=/.+\/(?:src\/)?(\S+)/m # m=/.+?\/(?:src\/)?([^\/]+)$/im # m=/.+\/(\S+)/m +    @stub_pwd ||=@@pwd[m,1] +    @base_markup_dir_stub=SiSU_Utils::Path.new.base_markup_stub +    prcss_dir='_sisu_processing_' +    prcss_dir_tmp_root="/tmp/#{prcss_dir}" +    prcss_dir_stub="#{prcss_dir}/#{@stub_pwd}" +    if @@user +      tmp_processing="#{prcss_dir_tmp_root}/#{@@user}/#{@base_markup_dir_stub}" +      tmp_processing_individual="#{prcss_dir_tmp_root}/#{@@user}/#{@base_markup_dir_stub}" +    else #error +      tmp_processing=tmp_processing_individual="/tmp/#{prcss_dir_stub}" +    end +    processing_pth=tmp_processing_individual +    processing_dir=prcss_dir +    processing_git="#{Dir.pwd}/#{Gt[:grotto]}" +    #user=ENV['USER'] +    port_pgsql=if defined? ENV['PGPORT'] \ +    and not (ENV['PGPORT'].nil? \ +    || ENV['PGPORT'].empty?) \ +    and ENV['PGPORT']=~/^\d+$/ +      ENV['PGPORT'] +    else '5432' +    end +    IMAGES=:images +    SISU_ETC=:sisu_etc +    SISU_SHARE=:sisu_share +    SAMPLE_DATA_PATH=:sample_data_path +    IMAGE_STUB=:image_stub +    STYLESHEET_STUB=:stylesheet_stub +    IMAGE_LOCAL=:image_local +    WEBSERV_PATH=:webserv_path +    WEBSERV_MAN=:webserv_man +    WEBSERV_PHP=:webserv_php +    WEBSERV_CGI=:webserv_cgi +    WEBSERV_RSS=:webserv_rss +    WEBSERV_SQLITE=:webserv_sqlite +    OUTPUT_LOCAL=:output_local +    PROCESSING_DIR=:processing_dir +    PROCESSING_PATH=:processing_path +    PROCESSING_DIR_TMP_ROOT=:processing_dir_tmp_root +    PROCESSING_PATH_TMP_BASE=:processing_path_tmp_base +    PROCESSING_AO=:processing_ao +    PROCESSING_TUNE=:processing_tune +    PROCESSING_LATEX=:processing_latex +    PROCESSING_TEXINFO=:processing_texinfo +    PROCESSING_LOUT=:processing_lout +    PROCESSING_SQLITE=:processing_sqlite +    PROCESSING_POSTGRESQL=:processing_postgresql +    PROCESSING_ENCODING=:processing_encoding +    PROCESSING_GIT=:processing_git +    PAPERSIZE=:papersize +    #LANGUAGE=:language +    #LANGUAGE_CODE=:language_code +    MULTILINGUAL=:multilingual +    BUNDLE=:bundle +    CONCORD_MAX=:concord_max +    DIGEST=:digest +    WEBSERV_HOST_CGI=:webserv_host_cgi +    WEBSERV_PORT_CGI=:webserv_port_cgi +    POSTGRESQL_USER=:postgresql_user +    POSTGRESQL_PORT=:postgresql_port +    SQLITE_USER=:sqlite_user +    SQLITE_PATH=:sqlite_path +    SQLITE_PORT=:sqlite_port +    DEFAULT_DIR={ +      IMAGES =>                   '_sisu/image', +      SISU_ETC =>                 etc, +      SISU_SHARE =>               share, +      SAMPLE_DATA_PATH =>         data, +      IMAGE_STUB =>               '_sisu/image', +      STYLESHEET_STUB =>          '_sisu/css', +      IMAGE_LOCAL =>              @@pwd + '/_sisu/image', +      WEBSERV_PATH =>             out + '/www', +      #WEBSERV_DIR =>             www, # uncomment for urls... +      #WEBSERV_IMAGE =>            out + '/www/_sisu/image', +      WEBSERV_MAN =>              out + '/www/man', #alter +      WEBSERV_PHP =>              out + '/www/php', +      WEBSERV_CGI =>              '/usr/lib/cgi-bin', +      WEBSERV_RSS =>              out + '/www/feed', +      WEBSERV_SQLITE =>           out + '/www/sqlite', +      OUTPUT_LOCAL =>             @@home + '/sisu_www', +      PROCESSING_DIR =>           processing_dir, +      PROCESSING_PATH =>          processing_pth, +      PROCESSING_DIR_TMP_ROOT  => prcss_dir_tmp_root, +      PROCESSING_PATH_TMP_BASE => processing_pth, +      PROCESSING_AO =>            'ao', +      PROCESSING_TUNE =>          'tune', +      PROCESSING_LATEX =>         'tex', +      PROCESSING_TEXINFO =>       'texinfo', +      PROCESSING_SQLITE =>        'sqlite', +      PROCESSING_POSTGRESQL=>     'postgresql', +      PROCESSING_ENCODING =>      'encoding', +      PROCESSING_GIT =>           processing_git, +      #TEXINFO_STUB =>             'texinfo', +      PAPERSIZE =>                'A4', #A4, US_letter, book_b5, book_a5, US_legal +      #LANGUAGE =>                 'English', +      #LANGUAGE_CODE =>            'en', #change, unecessary duplication though currently used +      MULTILINGUAL =>             false, +      BUNDLE =>                   false, +      CONCORD_MAX =>              260000, +      DIGEST =>                   :sha256, +      WEBSERV_HOST_CGI =>         'http://localhost', +      WEBSERV_PORT_CGI =>         8081, #8111,8123,8081 +      POSTGRESQL_USER =>          @@user, #'ralph', # change user !!! +      POSTGRESQL_PORT =>          port_pgsql, +      #POSGRESQL_LINKS_PATH =>    '', +      SQLITE_USER =>              @@user, +      SQLITE_PATH =>              @@user, #?? +      SQLITE_PORT =>              '**', +    } +    @@default_dir=DEFAULT_DIR +    m=/.+\/(?:src\/)?(\S+)/m # m=/.+?\/(?:src\/)?([^\/]+)$/im # m=/.+\/(\S+)/m +    @@pwd=@pwd=SiSU_Utils::Path.new.base_markup +    attr_accessor :user,:home,:hostname,:pwd,:host,:arch,:rbver,:dir_arch,:dir_sitearch,:dir_bin,:locale,:webserv_path,:webserv_host_cgi,:webserv_port_cgi,:default_dir,:rc_path,:ad_path +    def initialize +      @user,   @home, @hostname, @pwd, @sisu_etc, @host, @arch, @rbver, @dir_arch, @dir_sitearch, @dir_bin, @locale, @default_dir= +        @@user,@@home,@@hostname,@@pwd,@@sisu_etc,@@host,@@arch,@@rbver,@@dir_arch,@@dir_sitearch,@@dir_bin,@@locale,@@default_dir +      #note rbver is duplicated in InfoVersion +    end +  end +end +module SiSU_Info_Sys +  class InfoSystem < SiSU_Info_Sys_Gen::InfoSystemGen +    include Singleton +    def initialize +      super() +    end +  end +end +__END__ +#+END_SRC + +** se_load.rb + +#+BEGIN_SRC ruby  :tangle "../lib/sisu/se_load.rb" +# <<sisu_document_header>> +module SiSU_Load +  require_relative 'constants'                             # constants.rb +  require_relative 'utils'                                 # utils.rb +  class Load +    def initialize(prog,mandatory=false) +      @prog,@mandatory=prog,mandatory +    end +    def prog +      load_prog=false +      $:.each do |reqpath| +        if FileTest.exist?("#{reqpath}/#{@prog}.rb") +          load_prog=true +          #SiSU_Utils::CodeMarker.new(__LINE__,__FILE__,:fuchsia).ok("#{reqpath}/#{@prog}.rb loaded") +          break +        #else SiSU_Utils::CodeMarker.new(__LINE__,__FILE__,:fuchsia).warn("#{reqpath}/#{@prog}.rb not found") +        end +      end +      if load_prog \ +      and @prog=~/dbi/ +        begin +          require 'dbi' +        rescue LoadError +          SiSU_Utils::CodeMarker.new(__LINE__,__FILE__,:fuchsia). +            error('dbi NOT FOUND (LoadError)') +        end +      end +      if load_prog +        begin +          require @prog +        rescue LoadError +          SiSU_Utils::CodeMarker.new(__LINE__,__FILE__,:fuchsia). +            error("#{@prog} NOT FOUND (LoadError)") +        end +      else +        @mandatory \ +        ? (SiSU_Screen::Ansi.new(@prog,"*WARN* module required: #{@prog}").warn) +        : '' #(SiSU_Screen::Ansi.new(@prog,"*WARN* #{@prog} load requested").warn) +      end +      load_prog +    end +    def prog? +      load_prog=false +      $:.each do |reqpath| +        if FileTest.exist?("#{reqpath}/#{@prog}.rb"); load_prog=true +          break +        end +      end +      load_prog +    end +  end +end +__END__ +#+END_SRC + +** se_processing.rb + +#+BEGIN_SRC ruby  :tangle "../lib/sisu/se_processing.rb" +# <<sisu_document_header>> +module SiSU_Processing_Settings +  require_relative 'constants'                             # constants.rb +  require_relative 'utils'                                 # utils.rb +  class ProcessingSettings +    def initialize(md) +      @md=md +    end +    def cnf_rc #sisurc.yml +      @rc=SiSU_Env::GetInit.new.sisu_yaml.rc +    end +    def env_rc #env rc (including sisurc.yml) +      @env_rc ||=SiSU_Env::InfoEnv.new(@md.fns) +    end +    def doc_rc #document rc, make instructions +      (defined? @md.make) \ +      ? @md.make +      : nil +    end +    def cmd_rc_act #command-line rc +      @cmd_rc_act=@md.opt.opt_act +    end +    def build +      def ocn? +        if cmd_rc_act[:ocn][:set]==:on +          true +        elsif cmd_rc_act[:ocn][:set]==:off +          false +        elsif doc_rc.is_a?(Method) \ +        and defined? doc_rc.ocn? \ +        and doc_rc.toc? ==:off +          false +        elsif env_rc.build.ocn? ==:off +          false +        else +          true +        end +      end +      def plaintext_ocn? +        if cmd_rc_act[:txt_ocn][:set]==:on \ +        or cmd_rc_act[:ocn][:set]==:on +          true +        elsif cmd_rc_act[:txt_ocn][:set]==:off \ +        or cmd_rc_act[:ocn][:set]==:off +          false +        elsif doc_rc.is_a?(Method) \ +        and defined? doc_rc.ocn? \ +        and doc_rc.toc? ==:off +          false +        elsif env_rc.build.ocn? ==:off +          false +        else +          true +        end +      end +      def odt_ocn? +        if cmd_rc_act[:odt_ocn][:set]==:on \ +        or cmd_rc_act[:ocn][:set]==:on +          true +        elsif cmd_rc_act[:odt_ocn][:set]==:off \ +        or cmd_rc_act[:ocn][:set]==:off +          false +        elsif doc_rc.is_a?(Method) \ +        and defined? doc_rc.ocn? \ +        and doc_rc.toc? ==:off +          false +        elsif env_rc.build.ocn? ==:off +          false +        else +          true +        end +      end +      def html_strict? +        if cmd_rc_act[:html_strict][:set]==:on +          true +        elsif cmd_rc_act[:html_strict][:set]==:off +          false +        elsif doc_rc.is_a?(Method) \ +        and defined? doc_rc.html_strict? \ +        and doc_rc.html_strict? ==:on +          true +        else +          false +        end +      end +      def toc? +        if cmd_rc_act[:toc][:set]==:on +          true +        elsif cmd_rc_act[:toc][:set]==:off +          false +        elsif doc_rc.is_a?(Method) \ +        and defined? doc_rc.toc? \ +        and doc_rc.toc? ==:off +          false +        elsif env_rc.build.toc? ==:off +          false +        else +          true +        end +      end +      def manifest? +        if cmd_rc_act[:manifest][:set]==:on +          true +        elsif cmd_rc_act[:manifest][:set]==:off +          false +        elsif doc_rc.is_a?(Method) \ +        and defined? doc_rc.manifest? \ +        and doc_rc.manifest? ==:off +          false +        elsif env_rc.build.manifest? ==:off +          false +        else +          true +        end +      end +      def links_to_manifest? +        if cmd_rc_act[:links_to_manifest][:set]==:on +          true +        elsif cmd_rc_act[:links_to_manifest][:set]==:off +          false +        elsif doc_rc.is_a?(Method) \ +        and defined? doc_rc.links_to_manifest? \ +        and doc_rc.links_to_manifest? ==:off +          false +        elsif env_rc.build.links_to_manifest? ==:off +          false +        else +          true +        end +      end +      def metadata? +        if cmd_rc_act[:metadata][:set]==:on +          true +        elsif cmd_rc_act[:metadata][:set]==:off +          false +        elsif doc_rc.is_a?(Method) \ +        and defined? doc_rc.metadata? \ +        and doc_rc.metadata? ==:off +          false +        elsif env_rc.build.metadata? ==:off +          false +        else +          true +        end +      end +      def minitoc? +        if html_top_band? == false #one form of navigation necessary +          true +        elsif cmd_rc_act[:minitoc][:set]==:on +          true +        elsif cmd_rc_act[:minitoc][:set]==:off +          false +        elsif doc_rc.is_a?(Method) \ +        and defined? doc_rc.minitoc? \ +        and doc_rc.minitoc? ==:off +          false +        elsif env_rc.build.minitoc? ==:off +          false +        else +          false +        end +      end +      def manifest_minitoc? +        if html_top_band? == false #one form of navigation necessary +          true +        elsif cmd_rc_act[:manifest_minitoc][:set]==:on \ +        || cmd_rc_act[:minitoc][:set]==:on +          true +        elsif cmd_rc_act[:manifest_minitoc][:set]==:off \ +        || cmd_rc_act[:minitoc][:set]==:off +          false +        elsif doc_rc.is_a?(Method) \ +        and defined? doc_rc.manifest_minitoc? \ +        and (doc_rc.manifest_minitoc? ==:off \ +        || doc_rc.minitoc? ==:off) +          false +        elsif env_rc.build.manifest_minitoc? ==:off \ +        || env_rc.build.minitoc? ==:off +          false +        elsif minitoc? == false +          false +        else +          false +        end +      end +      def html_minitoc? +        if html_top_band? == false #one form of navigation necessary +          true +        elsif cmd_rc_act[:html_minitoc][:set]==:on \ +        || cmd_rc_act[:minitoc][:set]==:on +          true +        elsif cmd_rc_act[:html_minitoc][:set]==:off \ +        || cmd_rc_act[:minitoc][:set]==:off +          false +        elsif doc_rc.is_a?(Method) \ +        and defined? doc_rc.html_minitoc? \ +        and (doc_rc.html_minitoc? ==:off \ +        || doc_rc.minitoc? ==:off) +          false +        elsif env_rc.build.html_minitoc? ==:off \ +        || env_rc.build.minitoc? ==:off +          false +        elsif minitoc? == false +          false +        else +          false +        end +      end +      def html_top_band? +        if cmd_rc_act[:html_top_band][:set]==:on +          true +        elsif cmd_rc_act[:html_top_band][:set]==:off +          false +        elsif doc_rc.is_a?(Method) \ +        and defined? doc_rc.html_top_band? \ +        and doc_rc.html_top_band? ==:off +          false +        elsif env_rc.build.html_top_band? ==:off +          false +        else +          true +        end +      end +      def html_navigation? +        if cmd_rc_act[:html_navigation][:set]==:on +          true +        elsif cmd_rc_act[:html_navigation][:set]==:off +          false +        elsif doc_rc.is_a?(Method) \ +        and defined? doc_rc.html_navigation? \ +        and doc_rc.html_navigation? ==:off +          false +        elsif env_rc.build.html_navigation? ==:off +          false +        else +          true +        end +      end +      def html_navigation_bar? +        if cmd_rc_act[:html_navigation_bar][:set]==:on +          true +        elsif cmd_rc_act[:html_navigation_bar][:set]==:off +          false +        elsif doc_rc.is_a?(Method) \ +        and defined? doc_rc.html_navigation_bar? \ +        and doc_rc.html_navigation_bar? ==:off +          false +        elsif env_rc.build.html_navigation_bar? ==:off +          false +        else +          false +        end +      end +      def search_form? +        if cmd_rc_act[:search_form][:set]==:on +          true +        elsif cmd_rc_act[:search_form][:set]==:off +          false +        elsif doc_rc.is_a?(Method) \ +        and defined? doc_rc.html_search_form? \ +        and doc_rc.search_form? ==:off +          false +        elsif env_rc.build.search_form? ==:off +          false +        else +          true +        end +      end +      def html_search_form? +        if cmd_rc_act[:html_search_form][:set]==:on \ +        || cmd_rc_act[:search_form][:set]==:on +          true +        elsif cmd_rc_act[:html_search_form][:set]==:off \ +        || cmd_rc_act[:search_form][:set]==:off +          false +        elsif doc_rc.is_a?(Method) \ +        and defined? doc_rc.html_search_form? \ +        and (doc_rc.html_search_form? ==:off \ +        || doc_rc.search_form? ==:off) +          false +        elsif env_rc.build.html_search_form? ==:off \ +        || env_rc.build.search_form? ==:off +          false +        elsif search_form? == false +          false +        else +          true +        end +      end +      def html_right_pane? +        if cmd_rc_act[:html_right_pane][:set]==:on +          true +        elsif cmd_rc_act[:html_right_pane][:set]==:off +          false +        elsif doc_rc.is_a?(Method) \ +        and defined? doc_rc.html_right_pane? \ +        and doc_rc.html_right_pane? ==:off +          false +        elsif env_rc.build.html_right_pane? ==:off +          false +        else +          true +        end +      end +      def segsubtoc? +        if cmd_rc_act[:segsubtoc][:set]==:on +          true +        elsif cmd_rc_act[:segsubtoc][:set]==:off +          false +        elsif doc_rc.is_a?(Method) \ +        and defined? doc_rc.segsubtoc? \ +        and doc_rc.segsubtoc? ==:off +          false +        elsif env_rc.build.segsubtoc? ==:off +          false +        else +          true +        end +      end +      self +    end +    def ocn_html_identifier +      (build.html_strict?) \ +      ? Mx[:ocn_id_char] +      : '' +    end +    def output_dir_structure +      def by_language_code? +        if cmd_rc_act[:output_by][:set] == :language +          true +        elsif cmd_rc_act[:output_by][:set] == :filetype \ +        or cmd_rc_act[:output_by][:set] == :filename +          false +        elsif cmd_rc_act[:output_by][:set] == :language +          true +        else +          env_rc.output_dir_structure.by_language_code? +        end +      end +      def by_filetype? +        if cmd_rc_act[:output_by][:set] == :filetype +          true +        elsif cmd_rc_act[:output_by][:set] == :language \ +        or cmd_rc_act[:output_by][:set] == :filename +          false +        elsif cmd_rc_act[:output_by][:set] == :filetype +          true +        else +          env_rc.output_dir_structure.by_filetype? +        end +      end +      def by_filename? +        if cmd_rc_act[:output_by][:set] == :filename +          true +        elsif cmd_rc_act[:output_by][:set] == :language \ +        or cmd_rc_act[:output_by][:set] == :filetype +          false +        elsif cmd_rc_act[:output_by][:set] == :filename +          true +        else +          env_rc.output_dir_structure.by_filename? +        end +      end +      def multilingual? +        by_language_code? +      end +      def dump? +        ((cmd_rc_act[:dump][:bool] \ +        &&  cmd_rc_act[:dump][:inst]) \ +        || (env_rc.output_dir_structure.dump?)) \ +        ? true +        : false +      end +      def redirect? +        ((cmd_rc_act[:redirect][:bool] \ +        &&  cmd_rc_act[:redirect][:inst]) \ +        || (env_rc.output_dir_structure.redirect?)) \ +        ? true +        : false +      end +      def dump_or_redirect? +        ((dump?) || (redirect?)) \ +        ? true +        : false +      end +      def by? +        if dump? +          :dump +        elsif redirect? +          :redirect +        elsif by_language_code? +          :language +        elsif by_filetype? +          :filetype +        elsif by_filename? +          :filename +        else #recheck current default +          :language +        end +      end +      self +    end +  end +end +module SiSU_Info_Processing_Flag +  class InfoProcessingFlag +    attr_accessor :color,:act_0,:act_1,:act_2,:act_3,:act_4,:act_5,:act_6,:act_7,:act_8,:act_9 +    def initialize +      @rc=SiSU_Get_Init::GetInit.new.sisu_yaml.rc +    end +    def color                          #configurable processing flag shortcuts +      (defined? @rc['flag']['color']) \ +      ? @rc['flag']['color'] +      : false +    end +    def act_0                           #configurable processing flag shortcuts +      def default +        '--manifest --digest --qrcode --text --html --epub --concordance --pdf --odf --docbook --xhtml --xml-sax --xml-dom --sqlite --verbose' +      end +      def str +        if defined? @rc['flag']['act0'] \ +        and @rc['flag']['act0'].is_a?(String) +          @rc['flag']['act0'] +        elsif defined? @rc['flag']['default'] \ +        and @rc['flag']['default'].is_a?(String) +          @rc['flag']['default'] +        else default +        end +      end +      def arr +        str.scan(/\S+/) +      end +      self +    end +    def act_1                           #configurable processing flag shortcuts +      def default +        '--manifest --text --html' +      end +      def str +        if defined? @rc['flag']['act1'] \ +        and @rc['flag']['act1'].is_a?(String) +          @rc['flag']['act1'] +        elsif defined? @rc['flag']['i'] \ +        and @rc['flag']['i'].is_a?(String) +          @rc['flag']['i'] +        else default +        end +      end +      def arr +        str.scan(/\S+/) +      end +      self +    end +    def act_2                           #configurable processing flag shortcuts +      def default +        '--manifest --text --html --epub --pdf' +      end +      def str +        if defined? @rc['flag']['act2'] \ +        and @rc['flag']['act2'].is_a?(String) +          @rc['flag']['act2'] +        elsif defined? @rc['flag']['ii'] \ +        and @rc['flag']['ii'].is_a?(String) +          @rc['flag']['ii'] +        else default +        end +      end +      def arr +        str.scan(/\S+/) +      end +      self +    end +    def act_3                           #configurable processing flag shortcuts +      def default +        '--manifest --text --html --epub --pdf --concordance --qrcode' +      end +      def str +        if defined? @rc['flag']['act3'] \ +        and @rc['flag']['act3'].is_a?(String) +          @rc['flag']['act3'] +        elsif defined? @rc['flag']['iii'] \ +        and @rc['flag']['iii'].is_a?(String) +          @rc['flag']['iii'] +        else default +        end +      end +      def arr +        str.scan(/\S+/) +      end +      self +    end +    def act_4                           #configurable processing flag shortcuts +      def default +        '--manifest --text --html --epub --pdf --concordance --qrcode --digest --odf --docbook' +      end +      def str +        if defined? @rc['flag']['act4'] \ +        and @rc['flag']['act4'].is_a?(String) +          @rc['flag']['act4'] +        elsif defined? @rc['flag']['iv'] \ +        and @rc['flag']['iv'].is_a?(String) +          @rc['flag']['iv'] +        else default +        end +      end +      def arr +        str.scan(/\S+/) +      end +      self +    end +    def act_5                           #configurable processing flag shortcuts +      def default +        '--manifest --text --html --epub --pdf --concordance --qrcode --digest --odf --docbook --sqlite' +      end +      def str +        if defined? @rc['flag']['act5'] \ +        and @rc['flag']['act5'].is_a?(String) +          @rc['flag']['act5'] +        elsif defined? @rc['flag']['v'] \ +        and @rc['flag']['v'].is_a?(String) +          @rc['flag']['v'] +        else default +        end +      end +      def arr +        str.scan(/\S+/) +      end +      self +    end +    def act_6                           #configurable processing flag shortcuts +      def default +        '--manifest --text --html --epub --pdf --concordance --qrcode --digest --odf --docbook --sqlite --xhtml --xml-sax --xml-dom' +      end +      def str +        if defined? @rc['flag']['act6'] \ +        and @rc['flag']['act6'].is_a?(String) +          @rc['flag']['act6'] +        else default +        end +      end +      def arr +        str.scan(/\S+/) +      end +      self +    end +    def act_7                           #configurable processing flag shortcuts +      def default +        '--manifest --text --html --epub --pdf --concordance --qrcode --digest --odf --docbook --sqlite --xhtml --xml-sax --xml-dom --source --sisupod' +      end +      def str +        if defined? @rc['flag']['act7'] \ +        and @rc['flag']['act7'].is_a?(String) +          @rc['flag']['act7'] +        else default +        end +      end +      def arr +        str.scan(/\S+/) +      end +      self +    end +    def act_8                           #configurable processing flag shortcuts +      def default +        '--manifest --text --html --epub --pdf --concordance --qrcode --digest --odf --docbook --xhtml --xml-sax --xml-dom --pg --update' +      end +      def str +        if defined? @rc['flag']['act8'] \ +        and @rc['flag']['act8'].is_a?(String) +          @rc['flag']['act8'] +        else default +        end +      end +      def arr +        str.scan(/\S+/) +      end +      self +    end +    def act_9                           #configurable processing flag shortcuts +      def default +        '--manifest --text --html --epub --pdf --concordance --qrcode --digest --odf --docbook --xhtml --xml-sax --xml-dom --pg --update --source --sisupod' +      end +      def str +        if defined? @rc['flag']['act9'] \ +        and @rc['flag']['act9'].is_a?(String) +          @rc['flag']['act9'] +        else default +        end +      end +      def arr +        str.scan(/\S+/) +      end +      self +    end +    def act_info +      puts 'current "act" settings:' +      acts=%w[ act_0 act_1 act_2 act_3 act_4 act_5 act_6 act_7 act_8 act_9 ] +      acts.each_with_index do |m,i| +        puts '--act-' + i.to_s + ' == ' \ +        + send(m).str +      end +    end +  end +end +__END__ +#+END_SRC + +** se_programs.rb + +#+BEGIN_SRC ruby  :tangle "../lib/sisu/se_programs.rb" +# <<sisu_document_header>> +module SiSU_Sys_Call +  begin +    require 'singleton' +  rescue LoadError +    SiSU_Utils::CodeMarker.new(__LINE__,__FILE__,:fuchsia). +      error('singleton NOT FOUND (LoadError)') +  end +  class SystemCall +    @@locale_flag=false +    def initialize(input='',output='',opt_or_cmd='') +      @input,@output=input,output +      (opt_or_cmd.is_a?(SiSU_Commandline::Options)) \ +      ? (@cmd,@opt=opt_or_cmd.cmd,opt_or_cmd) +      : (@cmd,@opt=opt_or_cmd,nil) #cmd.is_a?(String) +      @prog=SiSU_Env::InfoProgram.new +      @sys=SiSU_Info_Sys::InfoSystem.instance +    end +    def program_found?(program) +      found=`which #{program} 2>&1` #`whereis #{program}` +      (found =~/bin\/#{program}\b/) ? true : false +    end +    def locale                         #locales utf8 or other +      unless @@locale_flag +        @@locale_flag=true +      end +      @sys.locale +    end +    def file_encoding(filename,act='') #file encoding +      program='file' +      fnsp=SiSU_Env::InfoEnv.new(filename).source_file_with_path +      if program_found?(program) +        encoding=%x{file -L #{fnsp}}.strip +        encoding=encoding.gsub(/#{fnsp}:(\s+|$)/,'') +        encoding=if encoding \ +        and not encoding.empty? +          encoding +        else 'UTF-8 assumed, encoding undetermined' +        end +        if act[:verbose_plus][:set] ==:on \ +        or  act[:maintenance][:set] ==:on +          puts encoding +        end +        encoding +      else +        'UTF-8 assumed, file encoding check program unavailable' +      end +    end +    def wc                             #word count +      program='wc' +      if program_found?(program) \ +      and locale !~/utf-?8/i +        true +      else +        program_ref="(not available)" \ +          unless program_found?(program) +        program_ref="(UTF-8)" \ +          if locale =~/utf-?8/i +        false +      end +    end +    def rcs                            #rcs for document markup data +      program='rcs' +      program_ref="\n\t\tdocument version information requested" +      if program_found?(program); true +      else +        SiSU_Utils::CodeMarker.new(__LINE__,__FILE__,:fuchsia). +          warn("#{program} is not installed #{program_ref}") +        false +      end +    end +    def cvs                            #cvs for document markup data +      program='cvs' +      program_ref="\n\t\tdocument version information requested" +      if program_found?(program); true +      else +        SiSU_Utils::CodeMarker.new(__LINE__,__FILE__,:fuchsia). +          warn("#{program} is not installed #{program_ref}") +        false +      end +    end +    def po4a                           #po4a +      program='po4a' +      program_ref="\n\t\tpo4a" +      if program_found?(program); true +      else +        SiSU_Utils::CodeMarker.new(__LINE__,__FILE__,:fuchsia). +          warn("#{program} is not installed #{program_ref}") +        false +      end +    end +    def zip                            #zip +      program='zip' +      program_ref="\n\t\tused to in the making of number of file formats, odf, epub" +      if program_found?(program); true +      else +        SiSU_Utils::CodeMarker.new(__LINE__,__FILE__,:fuchsia). +          mark("*WARN* #{program} is not installed #{program_ref}") +        false +      end +    end +    def openssl                        #openssl for digests +      program='openssl' +      program_ref="\n\t\tused to generate requested source document identification digest" +      if program_found?(program); true +      else +        SiSU_Utils::CodeMarker.new(__LINE__,__FILE__,:fuchsia). +          warn("#{program} is not installed #{program_ref}") +        false +      end +    end +    def md5(filename)                  #md5 dgst +      program='openssl' +      program_ref="\n\t\tmd5 digest requested" +      if program_found?(program) +        pwd=Dir.pwd +        Dir.chdir(File.dirname(filename)) +        dgst=%x{openssl dgst -md5 #{File.basename(filename)}}.strip #use file name without file path +        Dir.chdir(pwd) +        dgst.scan(/\S+/) +      else +        SiSU_Utils::CodeMarker.new(__LINE__,__FILE__,:fuchsia). +          warn("#{program} is not installed #{program_ref}") +        false +      end +    end +    def sha256(filename)               #sha dgst +      program='openssl' +      program_ref="\n\t\tsha digest requested" +      if program_found?(program) +        pwd=Dir.pwd +        Dir.chdir(File.dirname(filename)) +        dgst=%x{openssl dgst -sha256 #{File.basename(filename)}}.strip #use file name without file path +        Dir.chdir(pwd) +        dgst.scan(/\S+/) +      else +        SiSU_Utils::CodeMarker.new(__LINE__,__FILE__,:fuchsia). +          warn("#{program} is not installed #{program_ref}") +        false +      end +    end +    def sha512(filename)               #sha dgst +      program='openssl' +      program_ref="\n\t\tsha digest requested" +      if program_found?(program) +        pwd=Dir.pwd +        Dir.chdir(File.dirname(filename)) +        dgst=%x{openssl dgst -sha512 #{File.basename(filename)}}.strip #use file name without file path +        Dir.chdir(pwd) +        dgst.scan(/\S+/) +      else +        SiSU_Utils::CodeMarker.new(__LINE__,__FILE__,:fuchsia). +          warn("#{program} is not installed #{program_ref}") +        false +      end +    end +    def psql                           #psql +      program='psql' +      program_ref="\n\t\tpsql requested" +      if program_found?(program); true +      else +        SiSU_Utils::CodeMarker.new(__LINE__,__FILE__,:fuchsia). +          warn("#{program} is not installed #{program_ref}") +        false +      end +    end +    def create_pg_db(dbname_stub=nil)  #createdb +      unless dbname_stub +        @pwd ||=Dir.pwd +        m=/.+\/(?:src\/)?(\S+)/im # m=/.+?\/(?:src\/)?([^\/]+)$/im # m=/.+\/(\S+)/m +        dbname_stub=@pwd[m,1] +      end +      program='createdb' +      db_name="#{Db[:name_prefix]}#{dbname_stub}" +      program_ref="\n\t\tcreatedb dbname #{db_name} #for postgresql database creation" +      (program_found?(program)) \ +      ? system("#{program} #{dbname_name}") +      : (STDERR.puts "\t*WARN* #{program} is not available #{program_ref}") +    end +    def relaxng(cmd='')                #trang - convert between different schema languages for XML +      program='trang' +      program_ref="\n\t\tsee <http://www.thaiopensource.com/relaxng/trang.html>" +      (program_found?(program)) \ +      ? system("#{program} #{@input} #{@output}") +      : (STDERR.puts "\t*WARN* #{program} is not installed #{program_ref}" if cmd =~/V/) +    end +    def qrencode                       #qrcode - for generating QR code +      program='qrencode' +      program_ref="\n\t\tsee <http://megaui.net/fukuchi/works/qrencode/index.en.html>" +      found=(program_found?(program)) ? true : false +      found \ +      ? (system(%{ +          echo "#{@input}" | #{program} -s 3 -o #{@output} +        })) +      : (STDERR.puts "\t*WARN* #{program} is not installed #{program_ref}" if @cmd =~/V/) +      #found +    end +    def imagemagick                    #imagemagick is a image manipulation program +      program='identify' +      #program_ref="\n\t\tsee <http://www.imagemagick.org/>" +      found=(program_found?(program)) ? true : false +      #STDERR.puts "\t*WARN* #{program} is not installed #{program_ref}" unless found +      found +    end +    def graphicsmagick                #graphicsmagick is a image manipulation program +      program='gm' +      #program_ref="\n\t\tsee <http://www.graphicsmagick.org/>" +      found=(program_found?(program)) ? true : false +      #STDERR.puts "\t*WARN* #{program} is not installed #{program_ref}" unless found +      found +    end +    def well_formed?                   #tidy - check for well formed xml xhtml etc. +      program=@prog.tidy +      program_ref="\n\t\tsee <http://tidy.sourceforge.net/>" +      (program_found?(program)) \ +      ? system("#{@prog.tidy} -xml #{@input} > #{@output}") +      : (STDERR.puts "\t*WARN* #{program} is not installed #{program_ref}") +    end +    def tex2pdf_engine +      progs=['xetex','xelatex','pdflatex','pdfetex','pdftex'] +      @pdfetex_flag=false +      @cmd ||='' +      @texpdf=nil +      progs.each do |program| +        if program_found?(program) +          @texpdf=program if program =~/xetex|xelatex|pdftex|pdflatex/ +          @pdfetex_flag=true +          break +        end +      end +      if @pdfetex_flag==false +        @texpdf=progs.join(', ') +      end +      @texpdf +    end +    def latex2pdf(md,papersize='a4')   #convert from latex to pdf +      tell=if @cmd =~/[MV]/ +        '' +      elsif @cmd =~/[v]/ +        %q{2>&1 | grep -v ' WARNING '} +      else %q{2>&1 | grep -v '$'} +      end +      mode='batchmode' #mode='nonstopmode' +      texpdf=tex2pdf_engine +      if @pdfetex_flag +        texpdf_cmd=case texpdf +        when /xetex/ +          %{#{texpdf} -interaction=#{mode} -fmt=xelatex #{@input} #{tell}\n} +        when /xelatex/ +          %{#{texpdf} -interaction=#{mode} -papersize="#{papersize}" #{@input} #{tell}\n} +        when /pdftex/ +          "#{texpdf} -interaction=#{mode} -fmt=pdflatex #{@input} #{tell}\n" +        when /pdflatex/ +          "#{texpdf} -interaction=#{mode} #{@input} #{tell}\n" +        end +        system(texpdf_cmd) +      else STDERR.puts "\t*WARN* none of the following programs are installed: #{@texpdf}" +      end +    end +    def makeinfo                       #texinfo +      program='makeinfo' +      options='' #'--force' #'' +      program_ref="\n\t\tsee http://www.gnu.org/software/texinfo/" +      (program_found?(program)) \ +      ? system("#{program} #{options} #{@input}\n") +      : (STDERR.puts "\t*WARN* #{program} is not installed #{program_ref}") +    end +    def scp +      puts "scp -Cr #{@input} #{@output}" if @cmd =~/[vVM]/ +      puts "scp disabled" +    end +    def rsync(action='',chdir=nil) +      program='rsync' +      if program_found?(program) +        vb=if @cmd =~/q/; 'q' +        elsif @cmd =~/v/; 'v' +        else              '' +        end +        cX=SiSU_Screen::Ansi.new(@cmd).cX +        msg=(@cmd =~/q/) ? '' : %{ && echo " #{cX.grey}OK: #{@input} -> #{@output}#{cX.off}"} +        amp=(@opt \ +        && @opt.files.length > 1) \ +        ? '' +        : ((@cmd =~/[vVM]/) ? '' : '&') +        rsync_cmd="rsync -az#{vb} #{action} #{@input} #{@output}" +        puts rsync_cmd if @cmd =~/[vVM]/ +        dir_change=dir_return=nil +        if not chdir.nil? \ +        && chdir != Dir.pwd +          dir_change=Dir.chdir(chdir) +          dir_return=Dir.pwd +        end +        dir_change if dir_change +        system(" +          #{rsync_cmd} #{msg} #{amp} +        ") +        dir_return if dir_return +      else STDERR.puts "\t*WARN* #{program} not found" +      end +    end +    def rm +      if @cmd =~/^-Z[mMvVq]*$/;      FileUtils::rm_rf(@input) +      elsif @cmd =~/V/;              FileUtils::rm(@input) +      elsif @cmd !~/q/;              FileUtils::rm(@input) +      elsif @cmd =~/q/;              FileUtils::rm(@input) +      else                           STDERR.puts "\t*WARN* operation ignored" +      end +    end +  end +end +module SiSU_Info_Program +  require_relative 'constants'                             # constants.rb +  require_relative 'utils'                                 # utils.rb +  require_relative 'se_info_env'                           # se_info_env.rb +  class InfoProgram < SiSU_Info_Env::InfoEnv               # se_info_env.rb +    attr_accessor :editor,:wc,:tidy,:rexml,:pdflatex,:postgresql,:sqlite +    def initialize +      prog=SiSU_Env::InfoEnv.new.program +      @editor,           @wc,    @tidy,    @rexml,    @pdflatex,    @postgresql,    @sqlite= +        prog.text_editor,prog.wc,prog.tidy,prog.rexml,prog.pdflatex,prog.postgresql,prog.sqlite +    end +  end +end +module SiSU_Info_Set +  require_relative 'se_info_env'                           # se_info_env.rb +  class InfoSettings < SiSU_Info_Env::InfoEnv              # se_info_env.rb +    def permission?(prog)                                  # program defaults +      (defined? @rc['permission_set'][prog]) \ +      ? @rc['permission_set'][prog] +      : false +    end +    def program?(prog)                                     # program defaults +      (defined? @rc['program_set'][prog]) \ +      ? @rc['program_set'][prog] +      : false +    end +  end +end +__END__ +#+END_SRC + +** se_remotes.rb + +#+BEGIN_SRC ruby  :tangle "../lib/sisu/se_remotes.rb" +# <<sisu_document_header>> +module SiSU_Info_Remote_Host +  require_relative 'constants'                             # constants.rb +  require_relative 'utils'                                 # utils.rb +  class InfoRemoteHost +    def initialize +      @rc=SiSU_Env::GetInit.new.sisu_yaml.rc +    end +    def remote_host #see InfoRemote remote_host_base_general +      r=[] +      r=if (defined? @rc['remote'] \ +      and @rc['remote'].is_a?(Array)) +        r_array=@rc['remote'] +        r_array.each_with_index do |renv,i| +          r[i]={} +          if defined? renv['user'] \ +          and defined? renv['host'] +          end +          r[i][:user]=renv['user'] +          r[i][:host]=renv['host'] +          r[i][:path]=if defined? renv['path'] +            renv['path'] +          else '' +          end +          r[i][:name]="#{r[i][:user]}@#{r[i][:host]}:#{r[i][:path]}" +        end +        r +      elsif (defined? @rc['remote'] \ +      and @rc['remote'].is_a?(Hash) \ +      and defined? @rc['remote']['user'] \ +      and defined? @rc['remote']['host']) +        r[0]={} +        r[0][:user]=@rc['remote']['user'] +        r[0][:host]=@rc['remote']['host'] +        r[0][:path]=if defined? @rc['remote']['path'] +          @rc['remote']['path'] +        else '' +        end +        r[0][:name]="#{r[0][:user]}@#{r[0][:host]}:#{r[0][:path]}" +        r +      else +        r[0]={} +        r[0][:name]='.' +        r[0][:user]='' +        r[0][:host]='' +        r[0][:path]='' +        #puts "no remote host or user" +        r +      end +    end +    def rhost +      def r1 +        (defined? SiSU_Env::InfoRemoteHost.new.remote_host[0][:name]) \ +        ? (SiSU_Env::InfoRemoteHost.new.remote_host[0][:name]) +        : nil +      end +      def r2 +        (defined? SiSU_Env::InfoRemoteHost.new.remote_host[1][:name]) \ +        ? (SiSU_Env::InfoRemoteHost.new.remote_host[1][:name]) +        : nil +      end +      def r3 +        (defined? SiSU_Env::InfoRemoteHost.new.remote_host[2][:name]) \ +        ? (SiSU_Env::InfoRemoteHost.new.remote_host[2][:name]) +        : nil +      end +      def r4 +        (defined? SiSU_Env::InfoRemoteHost.new.remote_host[3][:name]) \ +        ? (SiSU_Env::InfoRemoteHost.new.remote_host[3][:name]) +        : nil +      end +      def r5 +        (defined? SiSU_Env::InfoRemoteHost.new.remote_host[4][:name]) \ +        ? (SiSU_Env::InfoRemoteHost.new.remote_host[4][:name]) +        : nil +      end +      def r6 +        (defined? SiSU_Env::InfoRemoteHost.new.remote_host[5][:name]) \ +        ? (@ls + SiSU_Env::InfoRemoteHost.new.remote_host[5][:name]) +         : nil +      end +      self +    end +  end +end +module SiSU_Info_Remote +  require_relative 'constants'                             # constants.rb +  require_relative 'utils'                                 # utils.rb +  require_relative 'se_filemap'                            # se_filemap.rb +  begin +    require 'fileutils' +      include FileUtils::Verbose +  rescue LoadError +    SiSU_Utils::CodeMarker.new(__LINE__,__FILE__,:fuchsia). +      error('fileutils NOT FOUND (LoadError)') +  end +  class InfoRemote < SiSU_File_Map::FileMap                # se_filemap.rb +    @@flag_remote=false +    begin +      require 'socket' +    rescue LoadError +      SiSU_Utils::CodeMarker.new(__LINE__,__FILE__,:fuchsia). +        error('socket NOT FOUND (LoadError)') +    end +    def initialize(opt) +      super(opt) # +      @opt=opt +      @rc=GetInit.new.sisu_yaml.rc +    end +    def remote_host_base_general +      SiSU_Env::InfoRemoteHost.new.remote_host +    end +    def remote_host_base +      remote_host_base_general.each do |remote_conn| +        @@flag_remote=true if remote_conn[:name] =~/\S+?@\S+/ +      end +      remote_host_base_general +    end +    def scp                            #sort out later using ruby libraries #not ideal, first time each file is sent, -r must be called separately for subdir to be built +      def document +        self.remote_host_base.each do |remote_conn| +          local_gen=@source_path +          remote_gen=case @opt.cmd +          when /u/ +            remote_conn[:name] + '/' \ +              + @env.path.base_markup_dir_stub + '/.'             #creates remote directory tree, this is not the usual function of u +          when /[abhHNopwxXy]/ +            remote_conn[:name] + '/' \ +              + @env.path.base_markup_dir_stub + '/' \ +              + @fnb + '/.' +          else +            remote_conn[:name] + '/' \ +              + @env.path.base_markup_dir_stub \ +              + '/.' +          end +          local_epub=@source_path_epub +          local_src=@source_path_src +          local_pod=@source_path_pod +          remote_epub= +            remote_conn[:name] + '/' + @env.path.stub_epub + '/.' +          remote_src= +            remote_conn[:name] + '/' + @env.path.stub_src + '/.' +          remote_pod= +            remote_conn[:name] + '/' + @env.path.stub_pod + '/.' +          src_txt=@opt.fnc +          src_pod=@opt.fncb.gsub(/(\.ss[mt])(?:\.sst)?$/,'\1.txz') +          if (local_gen =~/\S/ \ +          and local_gen !~/\/\//) \ +          and (remote_gen =~/\S/ \ +          and remote_gen !~/\/\//) \ +          and @@flag_remote==true \ +          and @opt.cmd !~/U/ +            SiSU_Env::SystemCall.new(local_gen,remote_gen).scp +            if FileTest.file?("#{local_src}/#{src_txt}") +              SiSU_Env::SystemCall.new("#{local_src}/#{src_txt}",remote_src).scp +            end +            if FileTest.file?("#{local_pod}/#{src_pod}") +              SiSU_Env::SystemCall.new("#{local_src}/#{src_pod}",remote_pod).scp +            end +            if FileTest.file?("#{local_epub}/#{@opt.fnb}.epub") +              SiSU_Env::SystemCall.new( +                "#{local_epub}/#{@opt.fnb}.epub", +                remote_epub,@opt.cmd +              ).scp +            end +          elsif  @opt.cmd =~/U/ +            puts "#{__FILE__} #{__LINE__}" if @opt.cmd =~/M/ +            puts "#{local_gen} -> #{remote_gen}" +            if FileTest.file?("#{local_src}/#{src_doc}") +              puts "#{local_src}/#{src_doc}* -> #{remote_src}" +            end +            if FileTest.file?("#{local_pod}/#{src_doc}.txz") +              puts "#{local_pod}/#{src_doc}* -> #{remote_pod}" +            end +          else +            puts 'suspect scp request, ignored' +            puts "#{local_gen} -> #{remote_gen} remote flag: #{@@flag_remote}" +            puts "permission not granted #{__FILE__} #{__LINE__}" if @opt.cmd =~/M/ +          end +        end +      end +      def site_base                    #base site +        self.remote_host_base.each do |remote_conn| +          local=@source_path +          remote="#{remote_conn[:name]}/#{@env.path.base_markup_dir_stub}/." +          if defined? @rc['permission_set']['remote_base_site'] \ +          and @rc['permission_set']['remote_base_site'] \ +          and @@flag_remote==true \ +          and @opt.cmd !~/U/ +            puts "begin scp_base: #{local} -> #{remote}" +            SiSU_Env::SystemCall.new("#{local}/#{@env.path.style}/",remote).scp +          elsif @opt.cmd =~/U/ +            puts "#{__FILE__} #{__LINE__}" if @opt.cmd =~/M/ +            puts "begin scp_base: #{local} -> #{remote}" +            puts "#{local}/#{@env.path.style}/ -> #{remote}" +          else  puts "permission not granted #{__FILE__} #{__LINE__}" if @opt.cmd =~/M/ +          end +        end +      end +      def site_base_all                #base site +        self.remote_host_base.each do |remote_conn| +          local=@source_path +          remote= +            remote_conn[:name] + '/' \ +              + @env.path.base_markup_dir_stub + '/.' +          if defined? @rc['permission_set']['remote_base_site'] \ +          and @rc['permission_set']['remote_base_site'] \ +          and @@flag_remote==true \ +          and @opt.cmd !~/U/ +            puts "begin scp_base_all: #{local} -> #{remote}" +            SiSU_Env::SystemCall.new("#{local}/_sisu/image_sys/",remote).scp +            SiSU_Env::SystemCall.new("#{local}/_sisu/image/",remote).scp +            SiSU_Env::SystemCall.new("#{local}/#{@env.path.style}/",remote).scp +          elsif @opt.cmd =~/U/ +            puts "#{__FILE__} #{__LINE__}" if @opt.cmd =~/M/ +            puts "scp_base_all: #{local} -> #{remote}" +            puts "#{local}/_sisu/image_sys/ -> #{remote}" +            puts "#{local}/_sisu/image/ -> #{remote}" +            puts "#{local}/#{@env.path.style}/ -> #{remote}" +          else +            puts "permission not granted #{__FILE__} #{__LINE__}" \ +              if @opt.cmd =~/M/ +          end +        end +      end +      self +    end +    def rsync +      def document +        f=(@opt.act[:ao][:set]==:on) \ +        ? SiSU_Env::FileOp.new(@md) +        : nil +        if f +          self.remote_host_base.each do |remote_conn| +            local_gen=@source_path +            #local_gen_image="#{@env.path.webserv}/#{@env.path.base_markup_dir_stub}/_sisu/image" +            #local_gen_image_external="#{@env.path.webserv}/#{@env.path.base_markup_dir_stub}/_sisu/image_external" +            remote_gen= +              remote_conn[:name] + '/' \ +                + @env.path.base_markup_dir_stub + '/.' +            remote_rel= +              remote_conn[:name] + '/' \ +                + f.output_path.stub.rcp +            @opt.fnc +            if (local_gen =~/\S/ \ +            and local_gen !~/\/\//) \ +            and (remote_gen =~/\S/ \ +            and remote_gen !~/\/\//) \ +            and @@flag_remote==true \ +            and @opt.cmd !~/U/ +#             SiSU_Env::SystemCall.new("#{local_src}/#{src_txt}",remote_src,@opt.cmd).rsync +              #delete_extra_files='--delete' # '--delete-after' +              inp=[] +              if (@opt.act[:html][:set]==:on \ +              || @opt.cmd =~/^-[mqvVM]*R[mqvVM]*$/) \ +              && FileTest.file?(f.place_file.html_scroll.dir) +                inp \ +                  << f.output_path.html_seg.rel \ +                  << f.place_file.html_scroll.rel +              end +              if (@opt.act[:concordance][:set]==:on \ +              || @opt.cmd =~/^-[mqvVM]*R[mqvVM]*$/) \ +              && FileTest.file?(f.place_file.html_concordance.dir) +                inp << f.place_file.html_concordance.rel +              end +              if (@opt.act[:epub][:set]==:on \ +              || @opt.cmd =~/^-R[mqvVM]*$/) \ +              && FileTest.file?(f.place_file.epub.dir) +                inp << f.place_file.epub.rel +              end +              if (@opt.act[:odt][:set]==:on \ +              || @opt.cmd =~/^-[mqvVM]*R[mqvVM]*$/) \ +              && FileTest.file?(f.place_file.odt.dir) +                inp << f.place_file.odt.rel +              end +              if (@opt.act[:xhtml][:set]==:on \ +              || @opt.cmd =~/^-[mqvVM]*R[mqvVM]*$/) \ +              && FileTest.file?(f.place_file.xhtml.dir) +                inp << f.place_file.xhtml.rel +              end +              if (@opt.act[:xml_sax][:set]==:on \ +              || @opt.cmd =~/^-[mqvVM]*R[mqvVM]*$/) \ +              && FileTest.file?(f.place_file.xml_sax.dir) +                inp << f.place_file.xml_sax.rel +              end +              if (@opt.act[:xml_dom][:set]==:on \ +              || @opt.cmd =~/^-[mqvVM]*R[mqvVM]*$/) \ +              && FileTest.file?(f.place_file.xml_dom.dir) +                inp << f.place_file.xml_dom.rel +              end +              if (@opt.act[:xml_scaffold_structure_sisu][:set]==:on \ +              || @opt.cmd =~/^-[mqvVM]*R[mqvVM]*$/) \ +              && FileTest.file?(f.place_file.xml_scaffold_structure_sisu.dir) +                inp << f.place_file.xml_scaffold_structure_sisu.rel +              end +              if (@opt.act[:xml_scaffold_structure_collapse][:set]==:on \ +              || @opt.cmd =~/^-[mqvVM]*R[mqvVM]*$/) \ +              && FileTest.file?(f.place_file.xml_scaffold_structure_collapse.dir) +                inp << f.place_file.xml_scaffold_structure_collapse.rel +              end +              if (@opt.act[:txt][:set]==:on \ +              || @opt.cmd =~/^-[mqvVM]*R[mqvVM]*$/) \ +              && FileTest.file?(f.place_file.txt.dir) +                inp << f.place_file.txt.rel +              end +              if (@opt.act[:manpage][:set]==:on \ +              || @opt.cmd =~/^-[mqvVM]*i[mqvVM]*$/) \ +              && FileTest.file?(f.place_file.manpage.dir) +                inp << f.place_file.manpage.rel +              end +              if (@opt.act[:texinfo][:set]==:on \ +              || @opt.cmd =~/^-[mqvVM]*I[mqvVM]*$/) \ +              && FileTest.file?(f.place_file.info.dir) +                inp << f.place_file.info.rel +              end +              if (@opt.act[:hash_digests][:set]==:on \ +              || @opt.cmd =~/^-[mqvVM]*R[mqvVM]*$/) \ +              && FileTest.file?(f.place_file.hash_digest.dir) +                inp << f.place_file.hash_digest.rel +              end +              if (@opt.act[:share_source][:set]==:on \ +              || @opt.cmd =~/^-[mqvVM]*R[mqvVM]*$/) \ +              && FileTest.file?(f.place_file.src.dir) +                inp << f.place_file.src.rel +              end +              if (@opt.act[:sisupod][:set]==:on \ +              || @opt.cmd =~/^-[mqvVM]*R[mqvVM]*$/) \ +              && FileTest.file?(f.place_file.sisupod.dir) +                inp << f.place_file.sisupod.rel +              end +              if (@opt.act[:pdf][:set]==:on \ +              || @opt.cmd =~/^-[mqvVM]*R[mqvVM]*$/) +                inp <<=(@opt.dir_structure_by == :filename) \ +                ? (f.output_path.pdf.rel + '/*.pdf') +                : (f.output_path.pdf.rel + '/' + @opt.fnb + '*.pdf') +              end +              if (@opt.act[:sqlite_discrete][:set]==:on \ +              || @opt.cmd =~/^-[mqvVM]*R[mqvVM]*$/) \ +              && FileTest.file?(f.place_file.sqlite_discrete.dir) +                inp << f.place_file.sqlite_discrete.rel +              end +              if (@opt.act[:qrcode][:set]==:on \ +              || @opt.cmd =~/^-[mqvVM]*R[mqvVM]*$/) \ +              && FileTest.file?(f.place_file.qrcode_md.dir) +                inp \ +                  << f.place_file.qrcode_md.rel \ +                  << f.place_file.qrcode_title.rel +              end +              if (@opt.act[:manifest][:set]==:on \ +              || @opt.cmd =~/^-[mqvVM]*R[mqvVM]*$/) \ +              && FileTest.file?(f.place_file.manifest.dir) +                inp << f.place_file.manifest.rel +              end +              local_gen=if inp.length > 0 +                inp.join(' ') +              else '' +              end +              local_css,images,images_system='','','' +              images=images_skin=images_system=local_css='' +              if @opt.cmd =~/[hwbxX]/ \ +              && (defined? @md.ec[:image]) \ +              && (@md.ec[:image].length > 0) +                images= +                  f.place_file.images.rel + '/' \ +                    + @md.ec[:image].join(" #{f.output_path.images.rel}/") +              end +              if @opt.cmd =~/[yhwbxX]/ \ +              && (defined? @md.ec[:image]) \ +              && (@md.ec[:image].length > 0) +                local_css=f.output_path.css.rel +                images_system='_sisu/image_sys' +              end +              begin +                ##create file structure without copying files?: +                ##rsync -av -f"+ */" -f"- *" f.output_path.base.dir remote:./path/. +                #local_dirs=%{-f"+ */" -f"- *" #{f.output_path.base.dir}/*} +                #SiSU_Env::SystemCall.new(local_dirs,remote_gen,@opt.cmd).rsync +                local=local_gen + ' ' + images + ' ' + images_skin + ' ' + images_system + ' ' + local_css +                SiSU_Env::SystemCall.new(local,remote_rel,@opt.cmd). +                  rsync('--relative',f.output_path.base.dir) +              rescue +                p __LINE__.to_s + ':' + __FILE__ +                local_dirs=%{--include='*/' --exclude='*' #{f.output_path.base.dir}} +                SiSU_Env::SystemCall.new(local_dirs,remote_gen,@opt.cmd).rsync +              end +            elsif @opt.cmd =~/U/ +              puts "#{__FILE__} #{__LINE__}" if @opt.cmd =~/M/ +              puts "#{local_gen} -> #{remote_gen}" +              if FileTest.file?("#{local_src}/#{src_doc}") \ +              or FileTest.file?("#{local_src}/#{src_doc}.txz") +                puts "#{local_src}/#{src_doc}* -> #{remote_src}" +              end +            else +              puts 'suspect rsync request, ignored' +              puts "#{local_gen} -> #{remote_gen} remote flag: #{@@flag_remote}" +              puts "permission not granted #{__FILE__} #{__LINE__}" \ +                if @opt.cmd =~/M/ +            end +          end +        end +      end +      def site_harvest +        self.remote_host_base.each do |remote_conn| +          local=@source_path_harvest +          l_rel="#{@env.path.webserv}/#{@env.path.base_markup_dir_stub}" +          lng='en' +          if @env.output_dir_structure.by? == :language +            ldest=lng + '/manifest' +            files= +              ldest + '/authors.html' + ' ' \ +                + ldest + '/topics.html' +          elsif @env.output_dir_structure.by? == :filetype +            ldest="manifest" +            files= +              ldest + '/authors.' + lng + '.html' + ' ' \ +                + ldest + '/topics.' + lng + '.html' +          elsif @env.output_dir_structure.by? == :filename +            files= +              l_rel + '/authors.' + lng + '.html' + ' ' \ +                + l_rel + '/topics.' + lng + '.html' +          end +          remote="#{remote_conn[:name]}/#{@opt.base_stub}" +          if @opt.act[:harvest][:set] \ +          && @opt.act[:rsync][:set] +            (@env.output_dir_structure.by? == :filename) \ +            ? (SiSU_Env::SystemCall.new(files,remote).rsync) +            : (SiSU_Env::SystemCall.new(ldest,remote). +                rsync('--relative',l_rel)) +          elsif @opt.cmd =~/U/ +            puts "#{__FILE__} #{__LINE__}" if @opt.cmd =~/M/ +            puts "rsync_harvest: #{local} -> #{remote}" +          else +            puts "permission not granted #{__FILE__} #{__LINE__}" \ +              if @opt.cmd =~/M/ +          end +        end +      end +      def site_base                    #base site +        ldest='_sisu/*' +        l_rel="#{@env.path.webserv}/#{@env.path.base_markup_dir_stub}" +        image_sys="#{@env.path.webserv}/_sisu/image_sys" +        self.remote_host_base.each do |remote_conn| +          remote="#{remote_conn[:name]}/#{@env.path.base_markup_dir_stub}" +          remote_conf="#{remote_conn[:name]}/_sisu" +            SiSU_Env::SystemCall.new(image_sys,remote_conf).rsync +            SiSU_Env::SystemCall.new(ldest,remote).rsync('--relative',l_rel) +        end +      end +      def site_base_sync +        self.remote_host_base.each do |remote_conn| +          local=@source_path +          remote="#{remote_conn[:name]}/#{@env.path.base_markup_dir_stub}/." +          if defined? @rc['permission_set']['remote_base_site'] \ +          and @rc['permission_set']['remote_base_site'] \ +          and @@flag_remote==true \ +          and @opt.cmd !~/U/ +            delete_extra_files='--delete' # '--delete-after' +            puts "begin rsync_base_sync: #{local} -> #{remote}" +            SiSU_Env::SystemCall.new("#{local}/_sisu/image_sys/",remote). +              rsync(delete_extra_files) +            SiSU_Env::SystemCall.new("#{local}/_sisu/image/",remote). +              rsync(delete_extra_files) +            SiSU_Env::SystemCall.new("#{local}/#{@env.path.style}/",remote). +              rsync(delete_extra_files) +          elsif @opt.cmd =~/U/ +            puts "#{__FILE__} #{__LINE__}" if @opt.cmd =~/M/ +            puts "rsync_base_sync: #{local} -> #{remote}" +            puts "#{local}/_sisu/image_sys/ -> #{remote}" +            puts "#{local}/_sisu/image/ -> #{remote}" +            puts "#{local}/#{@env.path.style}/ -> #{remote}" +          else +            puts "permission not granted #{__FILE__} #{__LINE__}" \ +              if @opt.cmd =~/M/ +          end +        end +      end +      self +    end +    def rsync_sitemaps                 #sitemap directory +      self.remote_host_base.each do |remote_conn| +        local= +          @source_path + '/sitemapindex.xml' +        remote="#{remote_conn[:name]}/#{@env.path.base_markup_dir_stub}/." +        if @@flag_remote +          delete_extra_files='--delete' # '--delete-after' +          SiSU_Env::SystemCall.new(local,remote).rsync(delete_extra_files) +        elsif @opt.cmd =~/U/ +          puts "#{__FILE__} #{__LINE__}" if @opt.cmd =~/M/ +          puts "rsync_sitemaps: #{local} -> #{remote}" +        else +          puts "permission not granted #{__FILE__} #{__LINE__}" \ +            if @opt.cmd =~/M/ +        end +      end +    end +  end +end +__END__ +#+END_SRC + +** se_standardise_lang.rb + +#+BEGIN_SRC ruby  :tangle "../lib/sisu/se_standardise_lang.rb" +# <<sisu_document_header>> +@@lang_info=nil +module SiSU_Standardise_Lang +  class StandardiseLanguage +    require_relative 'i18n'                  # i18n.rb +    def initialize(l='') +      @language=(l.nil? || l.empty?) \ +      ? SiSU_Env::InfoEnv.new.language_default_set +      : l +      @r=%{(?:#{Px[:lng_lst_rgx]})} +      @lang_info=SiSU_i18n::Languages.new +    end +    def lang_lst                       # from i18n +      @@lang_info ||=@lang_info.language.list +    end +    def lang(l='')                     # from i18n +      if l =~/^#{@r}$/ +        @lang_info.language.list[l] +      elsif @language =~/^#{@r}$/ +        @lang_info.language.list[@language] +      else nil +      end +    end +    def language +      lng={} +      case @language +      when /^am$|Amharic/i                    then d,c,l=false,lang_lst['am'][:c],    lang_lst['am'][:n] +      when /^bg$|Bulgarian/i                  then d,c,l=false,lang_lst['bg'][:c],    lang_lst['bg'][:n] +      when /^bn$|Bengali/i                    then d,c,l=false,lang_lst['bn'][:c],    lang_lst['bn'][:n] +      when /^br$|Breton/i                     then d,c,l=false,lang_lst['br'][:c],    lang_lst['br'][:n] +      when /^ca$|Catalan/i                    then d,c,l=false,lang_lst['ca'][:c],    lang_lst['ca'][:n] +      when /^cs$|Czech/i                      then d,c,l=false,lang_lst['cs'][:c],    lang_lst['cs'][:n] +      when /^cy$|Welsh/i                      then d,c,l=false,lang_lst['cy'][:c],    lang_lst['cy'][:n] +      when /^da$|Danish|Dansk/i               then d,c,l=false,lang_lst['da'][:c],    lang_lst['da'][:n] +      when /^de$|German/i                     then d,c,l=false,lang_lst['de'][:c],    lang_lst['de'][:n] +      when /^el$|Greek/i                      then d,c,l=false,lang_lst['el'][:c],    lang_lst['el'][:n] +      when /^en$|English/i                    then d,c,l=false,lang_lst['en'][:c],    lang_lst['en'][:n] +      when /^eo$|Esperanto/i                  then d,c,l=false,lang_lst['eo'][:c],    lang_lst['eo'][:n] +      when /^es$|Spanish|Espanol/i            then d,c,l=false,lang_lst['es'][:c],    lang_lst['es'][:n] +      when /^et$|Estonian/i                   then d,c,l=false,lang_lst['et'][:c],    lang_lst['et'][:n] +      when /^eu$|Basque/i                     then d,c,l=false,lang_lst['eu'][:c],    lang_lst['eu'][:n] +      when /^fi$|Finnish|Finsk|Suomi/i        then d,c,l=false,lang_lst['fi'][:c],    lang_lst['fi'][:n] +      when /^fr$|French|Francais/i            then d,c,l=false,lang_lst['fr'][:c],    lang_lst['fr'][:n] +      when /^ga$|Irish/i                      then d,c,l=false,lang_lst['ga'][:c],    lang_lst['ga'][:n] +      when /^gl$|Galician/i                   then d,c,l=false,lang_lst['gl'][:c],    lang_lst['gl'][:n] +      when /^he$|Hebrew/i                     then d,c,l=false,lang_lst['he'][:c],    lang_lst['he'][:n] +      when /^hi$|Hindi/i                      then d,c,l=false,lang_lst['hi'][:c],    lang_lst['hi'][:n] +      when /^hr$|Croatian/i                   then d,c,l=false,lang_lst['hr'][:c],    lang_lst['hr'][:n] +      when /^hy$|Armenian/i                   then d,c,l=false,lang_lst['hy'][:c],    lang_lst['hy'][:n] +      when /^ia$|Interlingua/i                then d,c,l=false,lang_lst['ia'][:c],    lang_lst['ia'][:n] +      when /^is$|Icelandic/i                  then d,c,l=false,lang_lst['is'][:c],    lang_lst['is'][:n] +      when /^it$|Italian/i                    then d,c,l=false,lang_lst['it'][:c],    lang_lst['it'][:n] +      when /^la$|Latin/i                      then d,c,l=false,lang_lst['la'][:c],    lang_lst['la'][:n] +      when /^lo$|Lao/i                        then d,c,l=false,lang_lst['lo'][:c],    lang_lst['lo'][:n] +      when /^lt$|Lithuanian/i                 then d,c,l=false,lang_lst['lt'][:c],    lang_lst['lt'][:n] +      when /^lv$|Latvian/i                    then d,c,l=false,lang_lst['lv'][:c],    lang_lst['lv'][:n] +      when /^ml$|Malayalam/i                  then d,c,l=false,lang_lst['ml'][:c],    lang_lst['ml'][:n] +      when /^mr$|Marathi/i                    then d,c,l=false,lang_lst['mr'][:c],    lang_lst['mr'][:n] +      when /^nl$|Dutch/i                      then d,c,l=false,lang_lst['nl'][:c],    lang_lst['nl'][:n] +      when /^no$|Norwegian|Norsk/i            then d,c,l=false,lang_lst['no'][:c],    lang_lst['no'][:n] +      when /^nn$|Norwegian Nynorsk/i          then d,c,l=false,lang_lst['nn'][:c],    lang_lst['nn'][:n] +      when /^oc$|Occitan/i                    then d,c,l=false,lang_lst['oc'][:c],    lang_lst['oc'][:n] +      when /^pl$|Polish/i                     then d,c,l=false,lang_lst['pl'][:c],    lang_lst['pl'][:n] +      when /^pt$|Portuguese/i                 then d,c,l=false,lang_lst['pt'][:c],    lang_lst['pt'][:n] +      when /^pt_BR$|Portuguese Brazil/i       then d,c,l=false,lang_lst['pt_BR'][:c], lang_lst['pt_BR'][:n] +      when /^ro$|Romanian/i                   then d,c,l=false,lang_lst['ro'][:c],    lang_lst['ro'][:n] +      when /^ru$|Russian/i                    then d,c,l=false,lang_lst['ru'][:c],    lang_lst['ru'][:n] +      when /^sa$|Sanskrit/i                   then d,c,l=false,lang_lst['sa'][:c],    lang_lst['sa'][:n] +      when /^se$|Sami/i                       then d,c,l=false,lang_lst['se'][:c],    lang_lst['se'][:n] +      when /^sk$|Slovak/i                     then d,c,l=false,lang_lst['sk'][:c],    lang_lst['sk'][:n] +      when /^sl$|Slovenian/i                  then d,c,l=false,lang_lst['sl'][:c],    lang_lst['sl'][:n] +      when /^sq$|Albanian/i                   then d,c,l=false,lang_lst['sq'][:c],    lang_lst['sq'][:n] +      when /^sr$|Serbian/i                    then d,c,l=false,lang_lst['sr'][:c],    lang_lst['sr'][:n] +      when /^sv$|Swedish|Svensk/i             then d,c,l=false,lang_lst['sv'][:c],    lang_lst['sv'][:n] +      when /^ta$|Tamil/i                      then d,c,l=false,lang_lst['ta'][:c],    lang_lst['ta'][:n] +      when /^te$|Telugu/i                     then d,c,l=false,lang_lst['te'][:c],    lang_lst['te'][:n] +      when /^th$|Thai/i                       then d,c,l=false,lang_lst['th'][:c],    lang_lst['th'][:n] +      when /^tk$|Turkmen/i                    then d,c,l=false,lang_lst['tk'][:c],    lang_lst['tk'][:n] +      when /^tr$|Turkish/i                    then d,c,l=false,lang_lst['tr'][:c],    lang_lst['tr'][:n] +      when /^uk$|Ukranian/i                   then d,c,l=false,lang_lst['uk'][:c],    lang_lst['uk'][:n] +      when /^ur$|Urdu/i                       then d,c,l=false,lang_lst['ur'][:c],    lang_lst['ur'][:n] +      when /^us|American$|/i                  then d,c,l=false,lang_lst['en'][:c],    lang_lst['en'][:n] +      when /^vi$|Vietnamese/i                 then d,c,l=false,lang_lst['vi'][:c],    lang_lst['vi'][:n] +      else                                     d,c,l=true, lang_lst['en'][:c],    lang_lst['en'][:n] #default +      end +      lng[:d],lng[:c],lng[:n]=d,c,l +      lng +    end +    def name +      language[:n].downcase +    end +    def title +      language[:n] +    end +    def code +      language[:c] +    end +    def tex_name +      language[:xlp] +    end +    def file_to_language(file)         # used, fix and remove +      m=/.+?\~(\w{2,3})\.(?:-|ssm\.)?sst$/ +      @language=if file =~m ; file[m,1] +      else '' +      end +      language +    end +    def codes +      # Language List po4a +      #   <http://www.debian.org/international/l10n/po/> +      #   Px[:lng_lst] see constants.rb +      # see polyglossia for subset +      #   <http://mirrors.ctan.org/macros/xetex/latex/polyglossia/polyglossia.pdf> +      # also note ISO_639-2 +      #   <http://en.wikipedia.org/wiki/ISO_639-2> +      #   <http://en.wikipedia.org/wiki/List_of_ISO_639-2_codes> +      Px[:lng_lst] # constants.rb +    end +  end +end +__END__ +#+END_SRC + +** se_version.rb + +#+BEGIN_SRC ruby  :tangle "../lib/sisu/se_version.rb" +# <<sisu_document_header>> +module SiSU_Info_Version +  require_relative 'constants'                             # constants.rb +  require_relative 'utils'                                 # utils.rb +  require_relative 'se_info_env'                           # se_info_env.rb +  begin +    require 'singleton' +  rescue LoadError +    SiSU_Utils::CodeMarker.new(__LINE__,__FILE__,:fuchsia). +      error('singleton NOT FOUND (LoadError)') +  end +  class InfoVersion < SiSU_Info_Env::InfoEnv               # se_info_env.rb +    include Singleton +    begin +      require 'rbconfig' +      require 'yaml' +    rescue LoadError +      SiSU_Utils::CodeMarker.new(__LINE__,__FILE__,:fuchsia). +        error('rbconfig or yaml NOT FOUND (LoadError)') +    end +    @@lib_path=nil +    def get_version +      version={} +      @pwd=ENV['PWD'] +      lib_path= +        @@lib_path \ +        ? @@lib_path +        : `echo $RUBYLIB`.split(':') +      @@lib_path ||=lib_path +      if File.exist?(SiSU_is.version_info_path?) +        version=YAML::load(File::open(SiSU_is.version_info_path?)) +      end +      version[:install_method]=if SiSU_is.runtime_type? ==:gem_install +        spec = Gem::Specification.find_by_name("sisu") +        gem_root = spec.gem_dir +        (File.dirname(__FILE__.gsub(/\/lib\/sisu}/,'')) == gem_root) \ +        ? ' (ruby gem install)' : '' +      else '' +      end +      @version=version +      def version_details_hash +        @version +      end +      def project +        version_details_hash[:project] +      end +      def date +        version_details_hash[:date] +      end +      def date_stamp +        version_details_hash[:date_stamp] +      end +      def version +        version_details_hash[:version] +      end +      def version_major +        @version_major=version_details_hash[:version].gsub(/([0-9]+)\.[0-9]+\.[0-9]+/,'\1') +      end +      def install_method +        version_details_hash[:install_method] +      end +      self +    end +    def rbversion +      %x{ruby -v}.strip +    end +  end +end +module SiSU_Info_About +  require_relative 'constants'                             # constants.rb +  require_relative 'utils'                                 # utils.rb +  begin +    require 'singleton' +  rescue LoadError +    SiSU_Utils::CodeMarker.new(__LINE__,__FILE__,:fuchsia). +      error('singleton NOT FOUND (LoadError)') +  end +  class InfoAbout +    def initialize(color='') +      @color=color +    end +    def sisu_version +      version=SiSU_Env::InfoVersion.instance.get_version +      rb_ver=SiSU_Env::InfoVersion.instance.rbversion +      if version.version +        opt_cmd=if defined? @color.cmd \ +        and @color.cmd =~/[ck]/ +          @color.cmd +        else '-v' +        end +        SiSU_Screen::Ansi.new( +          opt_cmd, +          version.project, +          version.version, +          version.date_stamp, +          version.date, +          version.install_method, +          rb_ver +        ).version +      else puts 'SiSU (version information not available)' +      end +    end +    def sisu_about +      puts <<-WOK +     sisu: documents; markup, structuring, publishing in multiple standard formats, & search +     most (not all) useful commands (are made in a directory containing a sisu markup file &) take the form: +       sisu [action(s)] [filename(s)] +     where filename refers to a valid sisu marked up file, e.g.: +       cd /usr/share/doc/sisu/markup-samples/sisu_manual +       sisu --html --verbose sisu_commands.sst +       sisu --txt --html --epub --odt --pdf --sqlite --manpage --texinfo --concordance --qrcode --verbose sisu.ssm +       cd - +     See output produced, or see man pages: man sisu +     <http://www.sisudoc.org/> <http://www.jus.uio.no/sisu/> +        WOK +    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 +    se + +  - 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 diff --git a/org/harvest.org b/org/harvest.org new file mode 100644 index 00000000..ccc55123 --- /dev/null +++ b/org/harvest.org @@ -0,0 +1,1454 @@ +-*- mode: org -*- +#+TITLE:       sisu harvest +#+DESCRIPTION: documents - structuring, various output representations & search +#+FILETAGS:    :sisu:harvest: +#+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 + +* harvest +** html_harvest.rb + +#+BEGIN_SRC ruby  :tangle "../lib/sisu/html_harvest.rb" +# <<sisu_document_header>> +module SiSU_Harvest +  @@the_idx_topics,@@the_idx_authors={},{} +  class Source +    require_relative 'hub_options'                          # hub_options.rb +    require_relative 'html_harvest_topics'                  # html_harvest_topics.rb +    require_relative 'html_harvest_authors'                 # html_harvest_authors.rb +    require_relative 'se'                                   # se.rb +      include SiSU_Env +    def initialize(opt) +      @opt=opt +      @env=SiSU_Env::InfoEnv.new +    end +    def read +      begin +        harvest_pth=@env.path.webserv + '/' + @opt.base_stub +        FileUtils::mkdir_p(harvest_pth) unless FileTest.directory?(harvest_pth) +        cases(@opt,@env) +      rescue +      ensure +        SiSU_Env::CreateSite.new(@opt).cp_css +      end +    end +    def help +      puts <<WOK +      harvest --harvest   extracts document index metadata + +WOK +    end +    def css(opt) +      require_relative 'css'                                # css.rb +      css=SiSU_Style::CSS.new +      fn_css=SiSU_Env::CSS_Default.new +      style=File.new("#{@env.path.pwd}/#{fn_css.harvest}",'w') +      style << css.harvest +      style.close +    end +    def cases(opt,env) +      case opt.selections.str.inspect +      when/--harvest/i +        css(opt) if @opt.act[:maintenance][:set]==:on +        SiSU_HarvestAuthors::Songsheet.new(opt,env).songsheet +        SiSU_HarvestTopics::Songsheet.new(opt,env).songsheet +        if @opt.act[:rsync][:set]==:on +          require_relative 'remote'                         # remote.rb +          SiSU_Remote::Put.new(opt).rsync_harvest +        end +      else +        help +      end +    end +  end +end +#+END_SRC + +** topics +*** html_harvest_topics.rb + +#+BEGIN_SRC ruby  :tangle "../lib/sisu/html_harvest_topics.rb" +# <<sisu_document_header>> +module SiSU_HarvestTopics +  require_relative 'html_harvest_author_format'          # html_harvest_author_format.rb +  require_relative 'html_parts'                          # html_parts.rb +  class Songsheet +    @@the_idx_topics={} +    def initialize(opt,env) +      @opt,@env=opt,env +      @file_list=opt.files +    end +    def songsheet +      idx_array={} +      @opt.f_pths.each do |y| +        lang_hash_file_array={} +        name=y[:f] +        filename=y[:pth] + '/' + y[:f] +        File.open(filename,'r') do |file| +          file.each_line("\n\n") do |line| +            if line =~/^@(?:title|creator|classify):(?:\s|$)/m +              lang_hash_file_array[y[:lng_is]] ||= [] +              lang_hash_file_array[y[:lng_is]] << line +            elsif line =~/^@\S+?:(?:\s|$)/m \ +            or line =~/^(?:\s*\n|\s*$|%+ )/ +            else break +            end +          end +        end +        lang_hash_file_array.each_pair do |lang,a| +          idx_array[lang] ||=[] +          idx_array=SiSU_HarvestTopics::Harvest.new( +            @opt, +            @env, +            a, +            filename, +            name, +            idx_array, +            lang +          ).extract_harvest +        end +      end +      the_hash=SiSU_HarvestTopics::Index.new( +        @opt, +        @env, +        idx_array, +        @@the_idx_topics +      ).song +      SiSU_HarvestTopics::OutputIndex.new( +        @opt, +        the_hash +      ).html_print.html_songsheet +    end +  end +  class Mix +    def spaces +      Ax[:spaces] +    end +  end +  class Harvest +    def initialize(opt,env,data,filename,name,idx_array,lang) +      @opt, @env,@data,@filename,@name,@idx_array,@lang= +        opt,env, data, filename, name, idx_array, lang +    end +    def extract_harvest +      data,   filename, name, idx_array, lang= +        @data,@filename,@name,@idx_array,@lang +      @idx_lst=@title=@subtitle=@fulltitle=@author=@author_format=nil +      rgx={} +      rgx[:author]=/^@creator:(?:[ ]+|.+?:author:[ ]+)(.+?)(?:\||\n)/m +      rgx[:title]=/^@title:[ ]+(.+)/ +      rgx[:subtitle]=/^@title:.+?:subtitle:[ ]+(.+?)\n/m +      rgx[:idx]=/^@classify:.+?:topic_register:[ ]+(.+?)(?:\n\n|\n\s+:\S|\n%)/m +      data.each do |para| +        if para=~ rgx[:idx] +          @idx_list=(rgx[:idx].match(para)[1]).split(/\s*\n\s*/).join +        end +        if para=~ rgx[:title] +          @title=rgx[:title].match(para)[1] +        end +        if para=~ rgx[:subtitle] +          @subtitle=rgx[:subtitle].match(para)[1] +        end +        if para=~ rgx[:author] +          @author_format=rgx[:author].match(para)[1] +        end +        break if @title && @subtitle && @author && @idx_lst +      end +      @fulltitle=@subtitle ? (@title + ' - ' + @subtitle) : @title +      if @title \ +      and @author_format \ +      and @idx_list +        creator=SiSU_FormatAuthor::Author.new(@author_format.strip).author_details +        @authors,@authorship=creator[:authors],creator[:authorship] +        file=if name=~/~[a-z]{2,3}\.ss[mt]$/ +          name.sub(/~[a-z]{2,3}\.ss[mt]$/,'') +        else +          name.sub(/\.ss[mt]$/,'') +        end +        page=if @env.output_dir_structure.by? == :language +          "#{lang}/sisu_manifest.html" +        else +          "sisu_manifest.#{lang}.html" +        end +        idx_array[lang] <<=if @idx_list =~/;/ +          g=@idx_list.scan(/[^;]+/) +          g.each.map do |i| +            i=i.strip +            { +              filename: filename, +              file: file, +              rough_idx: i, +              title: @fulltitle, +              author: creator, +              page: page, +              lang: lang +            } +          end +        else { +            filename: filename, +            file: file, +            rough_idx: @idx_list, +            title: @fulltitle, +            author: creator, +            page: page, +            lang: lang, +          } +        end +      else +        if (@opt.act[:verbose_plus][:set]==:on \ +        || @opt.act[:maintenance][:set]==:on) +          p "missing required field in #{@filename} - [title]: <#{@title}>; [author]: <#{@author_format}>; [idx]: <#{@idx_list}>" +        end +      end +      idx_array[lang]=idx_array[lang].flatten +      idx_array +    end +  end +  class Index < Mix +    def initialize(opt,env,idx_array,the_idx) +      @opt, @env,@idx_array,@the_idx= +        opt,env, idx_array, the_idx +      @@the_idx_topics=@the_idx +    end +    def song +      the_idx=construct_book_topic_keys +      construct_book_topic_hash(the_idx) +    end +    def capital(txt) +      txt_a=txt.scan(/\S+/) +      tx='' +      txt_a.each do |t| +        tx += t[0].chr.capitalize + t[1,txt.length] + ' ' +      end +      tx.strip +    end +    def capital_(txt) +      txt[0].chr.capitalize + txt[1,txt.length] +    end +    def contents(idx,lang) +      names='' +      idx[:author][:last_first_format_a].each do |n| +        s=n.sub(/(.+?)(?:,.+|$)/,'\1').gsub(/\s+/,'_') +        names=if @env.output_dir_structure.by? == :language +          names += %{<a href="authors.html##{s}">#{n}</a>, } +        else +          names += %{<a href="authors.#{lang}.html##{s}">#{n}</a>, } +        end +      end +      { +        filename: idx[:filename], +        file: idx[:file], +        author: names, +        title: idx[:title], +        page: idx[:page] +      } +    end +    def capital_(txt) +      txt[0].chr.capitalize + txt[1,txt.length] +    end +    def key_create(c,alt) +      x=nil +      x=if c.length==6 +        c[0].to_s + '|' + +          capital(c[1][0].to_s) + '|' + +          capital(c[2][0].to_s) + '|' + +          capital(c[3][0].to_s) + '|' + +          capital(alt.to_s) +      elsif c.length==5 +        c[0].to_s + '|' + +          capital(c[1][0].to_s) + '|' + +          capital(c[2][0].to_s) + '|' + +          capital(alt.to_s) +      elsif c.length==4 +        c[0].to_s + '|' + +          capital(c[1][0].to_s) + '|' + +          capital(alt.to_s) +      elsif c.length==3 +        c[0].to_s + '|' + +          capital(alt.to_s) +      end +    end +    def construct_book_topic_keys +      idx_array=@idx_array +      @idx_a=[] +      @the_a=[] +      idx_array.each_pair do |lang,idx_arr| +        @@the_idx_topics[lang] ||= {} +        idx_arr.each do |idx| +          if idx[:rough_idx] +            idx_lst=idx[:rough_idx].scan(/[^:]+/) +          else +            puts "no topic register in: << #{idx[:filename]} >>" +            next +          end +          idx_a=[] +          idx_lst.each do |c| +            idx_a << c.scan(/[^|\n]+/m) +          end +          idx_a << contents(idx,lang) +          @idx_a << [lang] + idx_a +        end +      end +      @idx_a.each do |c| +        if c.length > 1 \ +        and c.is_a?(Array) +          if c[2].is_a?(Hash) +            c[1].each do |alt| +              v=key_create(c,alt) +              @the_a << [v, c[2]] if v +            end +          end +        end +        if c.length > 2 \ +        and c.is_a?(Array) +          if c[3].is_a?(Hash) +            c[2].each do |alt| +              v=key_create(c,alt) +              @the_a << [v, c[3]] if v +            end +          end +        end +        if c.length > 3 \ +        and c.is_a?(Array) +          if c[4].is_a?(Hash) +            c[3].each do |alt| +              v=key_create(c,alt) +              @the_a << [v, c[4]] if v +            end +          end +        end +        if c.length > 4 \ +        and c.is_a?(Array) +          if c[5].is_a?(Hash) +            c[4].each do |alt| +              v=key_create(c,alt) +              @the_a << [v, c[5]] if v +            end +          end +        end +        if c.length > 5 \ +        and c.is_a?(Array) +          if c[6].is_a?(Hash) +            c[5].each do |alt| +              v=key_create(c,alt) +              @the_a << [v, c[6]] if v +            end +          end +        end +      end +      @the_a.sort_by { |x| x[0] } #; y.each {|z| puts z} +    end +    def construct_book_topic_hash(t) +      @the_h={} +      t.each do |z| +        x=z[0].scan(/[^|]+/) +        depth=x.length +        extract=(depth-1) +        k=case extract +        when 4 +          { x[0] => { x[1] => { x[2] => { x[3] => { x[4] => z[1] } } } } } +        when 3 +          { x[0] => { x[1] => { x[2] => { x[3] => z[1] } } } } +        when 2 +          { x[0] => { x[1] => { x[2] => z[1] } } } +        when 1 +          { x[0] => { x[1] => z[1] } } +        when 0 +          { x[0] => z[1] } +        end +        if extract >= 0 +          k.each_pair do |x0,y0| +            if extract == 0 +              @the_h[x0] ||={ md: [] } +              @the_h[x0][:md] << y0 +            else +              @the_h[x0] ||={} +            end +            #puts spaces*0 + x0 +            if extract >= 1 +              y0.each_pair do |x1,y1| +                if extract == 1 +                  @the_h[x0][x1] ||={ md: [] } +                  @the_h[x0][x1][:md] << y1 +                else +                  @the_h[x0][x1] ||={} +                end +                #puts spaces*1 + x1 +                if extract >= 2 +                  y1.each_pair do |x2,y2| +                    if extract == 2 +                      @the_h[x0][x1][x2] ||={ md: [] } +                      @the_h[x0][x1][x2][:md] << y2 +                    else +                      @the_h[x0][x1][x2] ||={} +                    end +                    #puts spaces*2 + x2 +                    if extract >= 3 +                      y2.each_pair do |x3,y3| +                        if extract == 3 +                          @the_h[x0][x1][x2][x3] ||={ md: [] } +                          @the_h[x0][x1][x2][x3][:md] << y3 +                        else +                          @the_h[x0][x1][x2][x3] ||={} +                        end +                        #puts spaces*3 + x3 +                        if extract == 4 +                          y3.each_pair do |x4,y4| +                            if extract == 4 +                              @the_h[x0][x1][x2][x3][x4] ||={ md: [] } +                              @the_h[x0][x1][x2][x3][x4][:md] << y4 +                            else +                              @the_h[x0][x1][x2][x3][x4] ||={} +                            end +                            #puts spaces*4 + x4 +                            if extract == 5 +                              y4.each_pair do |x5,y5| +                                if extract == 5 +                                  @the_h[x0][x1][x2][x3][x4][x5] ||={ md: [] } +                                  @the_h[x0][x1][x2][x3][x4][x5][:md] << y5 +                                end +                                #puts spaces*5 + x5 +                              end +                            end +                          end +                        end +                      end +                    end +                  end +                end +              end +            end +          end +        end +      end +      #@the_h.each_pair { |x,y| p x; p y } +      @the_h +    end +    def traverse_base +      @the_h.each_pair do |x0,y0| +        puts spaces*0 + x0 if x0.is_a?(String) +        if y0.is_a?(Hash) +          y0.each_pair do |x1,y1| +            puts spaces*1 + x1 if x1.is_a?(String) +            if y1.is_a?(Hash) +              y1.each_pair do |x2,y2| +                puts spaces*2 + x2 if x2.is_a?(String) +                if y2.is_a?(Hash) +                  y2.each_pair do |x3,y3| +                    puts spaces*3 + x3 if x3.is_a?(String) +                    if y3.is_a?(Hash) +                      y3.each_pair do |x4,y4| +                        puts spaces*4 + x4 if x4.is_a?(String) +                        if y4.is_a?(Hash) +                          y4.each_pair do |x5,y5| +                            puts spaces*5 + x5 if x5.is_a?(String) +                          end +                        end +                      end +                    end +                  end +                end +              end +            end +          end +        end +      end +    end +    def traverse +      @the_h.each_pair do |x0,y0| +        puts spaces*0 + x0 if x0.is_a?(String) +        if y0.is_a?(Hash) +          if y0.has_key?(:md) +            y0[:md].each { |x| puts spaces*5 + x[:title] } +          end +          y0.each_pair do |x1,y1| +            puts spaces*1 + x1 if x1.is_a?(String) +            if y1.is_a?(Hash) +              if y1.has_key?(:md) +                y1[:md].each { |x| puts spaces*5 + x[:title] } +              end +              y1.each_pair do |x2,y2| +                puts spaces*2 + x2 if x2.is_a?(String) +                if y2.is_a?(Hash) +                  if y2.has_key?(:md) +                    y2[:md].each { |x| puts spaces*5 + x[:title] } +                  end +                  y2.each_pair do |x3,y3| +                    puts spaces*3 + x3 if x3.is_a?(String) +                    if y3.is_a?(Hash) +                      if y3.has_key?(:md) +                        y3[:md].each { |x| puts spaces*5 + x[:title] } +                      end +                      y3.each_pair do |x4,y4| +                        puts spaces*4 + x4 if x4.is_a?(String) +                        if y4.is_a?(Hash) +                          if y4.has_key?(:md) +                            y4[:md].each { |x| puts spaces*5 + x[:title] } +                          end +                          y4.each_pair do |x5,y5| +                            puts spaces*5 + x4 if x4.is_a?(String) +                          end +                        end +                      end +                    end +                  end +                end +              end +            end +          end +        end +      end +    end +  end +  class OutputIndex < Mix +    require_relative 'i18n'                               # i18n.rb +    def initialize(opt,the_idx) +      @opt,@the_idx=opt,the_idx +      @env=SiSU_Env::InfoEnv.new +      @rc=SiSU_Env::GetInit.new.sisu_yaml.rc +      @alphabet_list=%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] +      @alph=@alphabet_list.dup +      @letter=@alph.shift +    end +    def html_file_open +      @the_idx.keys.each do |lng| +        @output ||={} +        @output[lng] ||={} +        harvest_pth,file='','' +        if @env.output_dir_structure.by? == :language +          harvest_pth=@env.path.webserv + '/' \ +          + @opt.base_stub + '/' \ +          + lng + '/' \ +          + 'manifest' +          file=harvest_pth + '/' + 'topics.html' +        elsif @env.output_dir_structure.by? == :filetype +          harvest_pth=@env.path.webserv + '/' \ +          + @opt.base_stub + '/' \ +          + 'manifest' +          file=harvest_pth + '/' + 'topics.' + lng + '.html' +        elsif @env.output_dir_structure.by? == :filename +          harvest_pth=@env.path.webserv + '/' \ +          + @opt.base_stub +          file=harvest_pth + '/' + 'topics.' + lng + '.html' +        end +        FileUtils::mkdir_p(harvest_pth) \ +          unless FileTest.directory?(harvest_pth) +        fileinfo=(@opt.act[:verbose][:set]==:on \ +        || @opt.act[:verbose_plus][:set]==:on \ +        || @opt.act[:urls_selected][:set]==:on \ +        || @opt.act[:maintenance][:set]==:on) \ +        ? ("file://#{file}") +        : '' +        SiSU_Screen::Ansi.new( +          @opt.act[:color_state][:set], +          "harvest topics(#{@opt.files.length} files)", +          fileinfo +        ).dark_grey_title_hi unless @opt.act[:quiet][:set]==:on +        @output[lng][:html]=File.new(file,'w') +        if @opt.act[:maintenance][:set]==:on +          @output[lng][:html_mnt]=File.new("#{@env.path.pwd}/topics.html",'w') +        end +      end +    end +    def html_file_close +      @the_idx.keys.each do |lng| +        @output[lng][:html].close +        @output[lng][:html_mnt].close if @output[lng][:html_mnt].is_a?(File) +      end +    end +    def html_print +      def html_songsheet +        #traverse +        html_file_open +        html_head +        html_alph +        html_body_traverse +        html_tail +        html_file_close +      end +      def html_body_traverse +        @the_idx.each_pair do |x0,y0| +          lng=x0 +          if x0.is_a?(String) +            #do_string_name(lng,'lev0',x0) +            #puts spaces*0 + x0 +          end +          if y0.is_a?(Hash) +            if y0.has_key?(:md) +              y0[:md].each do |x| +                #do_hash(lng,attrib,x) #lv==0 ? +                #puts spaces*5 + x[:title] +              end +            end +            y0.each_pair do |x1,y1| +              if x1.is_a?(String) +                do_string_name(lng,'lev0',x1) +                #puts spaces*1 + x1 +              end +              if y1.is_a?(Hash) +                if y1.has_key?(:md) +                  y1[:md].each do |x| +                    do_hash(lng,0,x) +                    #puts spaces*5 + x[:title] +                  end +                end +                y1.each_pair do |x2,y2| +                  if x2.is_a?(String) +                    do_string(lng,'lev1',x2) +                    #puts spaces*2 + x2 +                  end +                  if y2.is_a?(Hash) +                    if y2.has_key?(:md) +                      y2[:md].each do |x| +                        do_hash(lng,1,x) +                        #puts spaces*5 + x[:title] +                      end +                    end +                    y2.each_pair do |x3,y3| +                      if x3.is_a?(String) +                        do_string(lng,'lev2',x3) +                        #puts spaces*3 + x3 +                      end +                      if y3.is_a?(Hash) +                        if y3.has_key?(:md) +                          y3[:md].each do |x| +                            do_hash(lng,2,x) +                            #puts spaces*5 + x[:title] +                          end +                        end +                        y3.each_pair do |x4,y4| +                          if x4.is_a?(String) +                            do_string(lng,'lev3',x4) +                            #puts spaces*4 + x4 +                          end +                          if y4.is_a?(Hash) +                            if y4.has_key?(:md) +                              y4[:md].each do |x| +                                do_hash(lng,3,x) +                                #puts spaces*5 + x[:title] +                              end +                            end +                            y4.each_pair do |x5,y5| +                              if x5.is_a?(String) +                                do_string(lng,'lev4',x5) +                                #puts spaces*5 + x5 +                              end +                            end +                          end +                        end +                      end +                    end +                  end +                end +              end +            end +          end +        end +      end +      def html_head_adjust(lng,type='') +        css_path,authors='','' +        if @env.output_dir_structure.by? == :language +          css_path=(type !~/maintenance/) \ +          ? '../../_sisu/css/harvest.css' +          : 'harvest.css' +          authors='authors.html' +        elsif @env.output_dir_structure.by? == :filetype +          css_path=(type !~/maintenance/) \ +          ? '../_sisu/css/harvest.css' +          : 'harvest.css' +          authors="authors.#{lng}.html" +        elsif @env.output_dir_structure.by? == :filename +          css_path=(type !~/maintenance/) \ +          ? './_sisu/css/harvest.css' +          : 'harvest.css' +          authors="authors.#{lng}.html" +        end +        ln=SiSU_i18n::Languages.new.language.list +        harvest_languages='' +        @the_idx.keys.each do |lg| +          if @env.output_dir_structure.by? == :language +            harvest_pth="../../#{lg}/manifest" +            file=harvest_pth + '/' + 'topics.html' +          elsif @env.output_dir_structure.by? == :filetype +            harvest_pth='.' +            file=harvest_pth + '/' + 'topics.' + lg + '.html' +          elsif @env.output_dir_structure.by? == :filename +            harvest_pth='.' +            file=harvest_pth + '/topics.' + lg + '.html' +          end +          l=ln[lg][:t] +          harvest_languages += +            %{<a href="#{file}">#{l}</a>   } +        end +        sv=SiSU_Env::InfoVersion.instance.get_version +        if @env.output_dir_structure.by? == :language +          home_pth='../..' +          output_structure_by='(output organised by language & filetype)' +        elsif @env.output_dir_structure.by? == :filetype +          home_pth='..' +          output_structure_by='(output organised by filetype)' +        elsif @env.output_dir_structure.by? == :filename +          home_pth='.' +          output_structure_by='(output organised by filename)' +        else +          home_pth='.' +          output_structure_by='(output organised by ?)' +        end +        <<WOK +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>SiSU Metadata Harvest - Topics</title> +<meta http-equiv="Content-Type" content="text/html;charset=utf-8" /> +<meta name="dc.title" content= "SiSU metadata harvest, Topics - SiSU information Structuring Universe, Structured information Serialised Units" /> +<meta name="dc.subject" content= "document structuring, ebook, publishing, PDF, LaTeX, XML, ODF, SQL, postgresql, sqlite, electronic book, electronic publishing, electronic document, electronic citation, data structure, citation systems, granular search, digital library" /> +<meta name="generator" content="#{sv.project} #{sv.version} of #{sv.date_stamp} (n*x and Ruby!)" /> +<link rel="generator" href="http://www.jus.uio.no/sisu/SiSU" /> +<link href="#{css_path}" rel="stylesheet"> +<link rel="shortcut icon" href="../_sisu/image/rb7.ico" /> +</head> +<body lang="en" xml:lang="en"> +<a name="top" id="top"></a> +<a name="up" id="up"></a> +<a name="start" id="start"></a> +<h1>SiSU Metadata Harvest - Topics #{output_structure_by}</h1> +<p>[<a href="#{home_pth}/index.html"> HOME </a>] also see <a href="#{authors}">SiSU Metadata Harvest - Authors</a></p> +<p>#{@env.widget_static.search_form}</p> +<hr /> +<p class="tiny">#{harvest_languages}</p> +<hr /> +WOK +      end +      def html_head +        @the_idx.keys.each do |lng| +          @output[lng][:html_mnt] \ +          << html_head_adjust(lng,'maintenance') \ +            if @opt.act[:maintenance][:set]==:on +          @output[lng][:html] << html_head_adjust(lng) +        end +      end +      def html_alph +        a=[] +        a << '<p>' +        @alph.each do |x| +          a << ((x =~/[0-9]/) \ +          ? '' +          : %{<a href="##{x}">#{x}</a>, }) +        end +        a=a.join +        @the_idx.keys.each do |lng| +          @output[lng][:html_mnt] << a \ +            if @opt.act[:maintenance][:set]==:on +          @output[lng][:html] << a +        end +      end +      def html_tail +        a =<<WOK +<hr /> +<a name="bottom" id="bottom"></a> +<a name="down" id="down"></a> +<a name="end" id="end"></a> +<a name="finish" id="finish"></a> +<a name="stop" id="stop"></a> +<a name="credits"></a> +#{SiSU_Proj_HTML::Bits.new.credits_sisu} +</body> +</html> +WOK +        @the_idx.keys.each do |lng| +          @output[lng][:html_mnt] << a \ +            if @output[lng][:html_mnt].is_a?(File) +          @output[lng][:html] << a +        end +      end +      def do_html(lng,html) +        @output[lng][:html] << html +      end +      def do_html_maintenance(lng,html) +        @output[lng][:html_mnt] << html \ +          if @output[lng][:html_mnt].is_a?(File) +      end +      def do_string(lng,attrib,string) +        html=%{<p class="#{attrib}">#{string}</p>} +        do_html(lng,html) +        do_html_maintenance(lng,html) \ +          if @output[lng][:html_mnt].is_a?(File) +      end +      def do_string_default(lng,attrib,string) +        html=%{<p class="#{attrib}">#{string}</p>} +        do_html(lng,html) +      end +      def do_string_maintenance(lng,attrib,string) +        html=%{<p class="#{attrib}">#{string}</p>} +        do_html_maintenance(lng,html) \ +          if @output[lng][:html_mnt].is_a?(File) +      end +      def do_string_name(lng,attrib,string) +        f=/^(\S)/.match(string)[1] +        if @lng != lng +          @alph=@alphabet_list.dup +          @letter=@alph.shift +          @lng = lng +        end +        if @letter < f +          while @letter < f +            if @alph.length > 0 +              @letter=@alph.shift +              if @output[lng][:html_mnt].is_a?(File) +                @output[lng][:html_mnt] \ +                << %{\n<p class="letter"><a name="#{@letter}">#{@letter}</a></p><p class="book_index_lev1"><a name="#{@letter.downcase}"></a></p>} +              end +              @output[lng][:html] \ +              << %{\n<p class="letter"><a name="#{@letter}">#{@letter}</a></p><p class="book_index_lev1"><a name="#{@letter.downcase}"></a></p>} +            else break +            end +          end +        end +        name=string.strip.gsub(/\s+/,'_') +        html=%{<p class="#{attrib}"><a name="#{name}">#{string}</a></p>} +        do_html(lng,html) +        do_html_maintenance(lng,html) \ +          if @output[lng][:html_mnt].is_a?(File) +      end +      def do_array(lng,lv,array) +        lv+=1 +        array.each do |b| +          do_case(lng,lv,b) +        end +      end +      def do_hash_md(lng,attrib,hash) +        lang_code_insert=SiSU_Env::FilenameLanguageCodeInsert.new(@opt,lng).language_code_insert +        manifest_at=if @env.output_dir_structure.by? == :language +          hash[:file] + Sfx[:html] +        elsif @env.output_dir_structure.by? == :filetype +          hash[:file] + lang_code_insert +  Sfx[:html] +        elsif @env.output_dir_structure.by? == :filename +          "./#{hash[:file]}/#{hash[:page]}" +        else '' #error +        end +        html=%{<a href="#{manifest_at}">#{hash[:title]}</a> - #{hash[:author]}} +        do_string_default(lng,attrib,html) +      end +      def do_hash_md_maintenance(lng,attrib,hash) +        if @output[lng][:html_mnt].is_a?(File) #should not be run for presentation output +          html=%{[<a href="#{hash[:file]}.sst">src</a>]  <a href="file://#{@env.path.output}/#{hash[:file]}/#{hash[:page]}">#{hash[:title]}</a> - #{hash[:author]}} +          do_string_maintenance(lng,attrib,html) +        end +      end +      def do_hash(lng,lv,hash) +        lv+=1 +        key=[] +        hash.each_key do |m| +          if m == :md +            do_case(lng,lv,hash[m]) +          elsif m != :title \ +          and m != :author \ +          and m != :filename \ +          and m != :file \ +          and m != :rough_idx \ +          and m != :page +            key << m +          elsif m == :title +            do_hash_md(lng,'work',hash) +            do_hash_md_maintenance(lng,'work',hash) +          end +        end +        if key.length > 0 +          key.sort.each do |m| +            attrib="lev#{lv}" +            lv==0 ? do_string_name(lng,attrib,m) : do_string(lng,attrib,m) +            do_case(lng,lv,hash[m]) +          end +        end +      end +      def do_case(lng,lv,a) +        case a +        when String +          attrib="lev#{lv}" +          if a=~/S/ +            lv==0 ? do_string_name(lng,attrib,a) : do_string(lng,attrib,a) +          end +        when Array +          do_array(lng,lv,a) +        when Hash +          do_hash(lng,lv,a) +        end +      end +      #def html_body +      #  the_idx=@the_idx +      #  the_idx.each_pair do |lng,lng_array| +      #    lng_array.sort.each do |a| +      #      do_case(lng,-1,a) +      #    end +      #  end +      #end +      self +    end +  end +end +__END__ +terms -|_  t{tl1} -|_ {fa}[fa]{filenames and other details} +       |           |_ {tl2} -|_ {fa}[fa]{filenames and other details} +       |           |         |_{tl3} -|_ {fa}[fa]{filenames and other details} +       |           |         |        |_{tl4} - {fa}[fa]{filenames and other details} +       |           |         |        | +       |           |         |        |_{tl4a} - {fa}[fa]{filenames and other details} +       |           |         |        | +       |           |         |        |_{tl4b} - {fa}[fa]{filenames and other details} +       |           |         |        | +       |           |         |        |_ ... +       |           |         | +       |           |         |_{tl3a} - {fa}[fa]{filenames and other details} +       |           | +       |           |_{tl2a} - {fa}[fa]{filenames and other details} +       | +       |_ t{tl1a} -|_ {fa}[fa]{filenames and other details} +                   |_ ... +#+END_SRC + +** authors +*** html_harvest_authors.rb + +#+BEGIN_SRC ruby  :tangle "../lib/sisu/html_harvest_authors.rb" +# <<sisu_document_header>> +module SiSU_HarvestAuthors +  require_relative 'html_harvest_author_format'          # html_harvest_author_format.rb +  require_relative 'html_parts'                          # html_parts.rb +  class Songsheet +    @@the_idx_authors={} +    def initialize(opt,env) +      @opt,@env=opt,env +      @file_list=opt.files +    end +    def songsheet +      idx_array={} +      @opt.f_pths.each do |y| +        lang_hash_file_array={} +        name=y[:f] +        filename=y[:pth] + '/' + y[:f] +        File.open(filename,'r') do |file| +          file.each_line("\n\n") do |line| +            if line =~/^@(?:title|creator|date):(?:\s|$)/m +              lang_hash_file_array[y[:lng_is]] ||= [] +              lang_hash_file_array[y[:lng_is]] << line +            elsif line =~/^@\S+?:(?:\s|$)/m \ +            or line =~/^(?:\s*\n|%+ )/ +            else break +            end +          end +        end +        lang_hash_file_array.each_pair do |lang,a| +          idx_array[lang] ||= [] +          idx_array=SiSU_HarvestAuthors::Harvest.new( +            @opt, +            @env, +            a, +            filename, +            name, +            idx_array, +            lang +          ).extract_harvest +        end +      end +      the_idx=SiSU_HarvestAuthors::Index.new( +        idx_array, +        @@the_idx_authors +      ).construct_book_author_index +      SiSU_HarvestAuthors::OutputIndex.new( +        @opt, +        the_idx +      ).html_print.html_songsheet +    end +  end +  class Harvest +    def initialize(opt,env,data,filename,name,idx_array,lang) +      @opt, @env,@data,@filename,@name,@idx_array,@lang= +        opt,env, data, filename, name, idx_array, lang +    end +    def extract_harvest +      data,   filename, name, idx_array, lang = +        @data,@filename,@name,@idx_array,@lang +      @title=@subtitle=@fulltitle=@author=@author_format=@date=nil +      @authors=[] +      rgx={} +      rgx[:author]=/^@creator:(?:[ ]+|.+?:author:[ ]+)(.+?)(?:\||\n)/m +      rgx[:title]=/^@title:[ ]+(.+)/ +      rgx[:subtitle]=/^@title:.+?:subtitle:[ ]+(.+?)\n/m +      rgx[:date]=/^@date:(?:[ ]+|.+?:published:[ ]+)(\d{4})/m +      data.each do |para| +        if para=~ rgx[:title] +          @title=rgx[:title].match(para)[1] +        end +        if para=~ rgx[:subtitle] +          @subtitle=rgx[:subtitle].match(para)[1] +        end +        if para=~ rgx[:author] +          @author_format=rgx[:author].match(para)[1] +        end +        if para=~ rgx[:date] +          @date=rgx[:date].match(para)[1] +        end +        break if @title && @subtitle && @author && @date +      end +      @fulltitle=@subtitle \ +      ? (@title + ' - ' + @subtitle) +      : @title +      if @title \ +      and @author_format +        creator=SiSU_FormatAuthor::Author.new(@author_format.strip).author_details +        @authors,@authorship=creator[:authors],creator[:authorship] +        file=if name=~/~[a-z]{2,3}\.ss[mt]$/ +          name.sub(/~[a-z]{2,3}\.ss[mt]$/,'') +        else +          name.sub(/\.ss[mt]$/,'') +        end +        page=if @env.output_dir_structure.by? == :language +          "#{lang}/sisu_manifest.html" +        else +          "sisu_manifest.#{lang}.html" +        end +        idx_array[lang] <<= { +          filename: filename, +          file: file, +          date: @date, +          title: @fulltitle, +          author: creator, +          page: page, +          lang: lang +        } +      else +        #p "missing author field: #{@filename} title: #{@title}; author: #{@author_format}" +      end +      idx_array[lang]=idx_array[lang].flatten +      idx_array +    end +  end +  class Index +    def initialize(idx_array,the_idx) +      @idx_array,@the_idx=idx_array,the_idx +      @@the_idx_authors=@the_idx +    end +    def capital(txt) +      txt[0].chr.capitalize + txt[1,txt.length] +    end +    def construct_book_author_index +      idx_array=@idx_array +      idx_array.each_pair do |lang,idx_arr| +        @@the_idx_authors[lang] ||= {} +        idx_arr.each do |idx| +          idx[:author][:last_first_format_a].each do |author| +            author=author.strip +            if @@the_idx_authors[lang][author].is_a?(NilClass) +              @@the_idx_authors[lang][author]={ md: [] } +            end +            @@the_idx_authors[lang][author][:md] << { +              filename: idx[:filename], +              file: idx[:file], +              author: idx[:author], +              title: idx[:title], +              date: idx[:date], +              page: idx[:page], +              lang: idx[:lang] +            } +          end +        end +      end +      @the_idx=@@the_idx_authors +    end +  end +  class OutputIndex +    require_relative 'i18n'                               # i18n.rb +    def initialize(opt,the_idx) +      @opt,@the_idx=opt,the_idx +      @env=SiSU_Env::InfoEnv.new +      @rc=SiSU_Env::GetInit.new.sisu_yaml.rc +      @alphabet_list=%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] +      @alph=@alphabet_list.dup +      @letter=@alph.shift +    end +    def html_file_open +      @the_idx.keys.each do |lng| +        @output ||={} +        @output[lng] ||={} +        harvest_pth,file='','' +        if @env.output_dir_structure.by? == :language +          harvest_pth=@env.path.webserv + '/' \ +          + @opt.base_stub + '/' \ +          + lng + '/' \ +          + 'manifest' +          file="#{harvest_pth}/authors.html" +        elsif @env.output_dir_structure.by? == :filetype +          harvest_pth=@env.path.webserv + '/' \ +          + @opt.base_stub + '/' \ +          + 'manifest' +          file="#{harvest_pth}/authors.#{lng}.html" +        elsif @env.output_dir_structure.by? == :filename +          harvest_pth=@env.path.webserv + '/' \ +          + @opt.base_stub +          file="#{harvest_pth}/authors.#{lng}.html" +        end +        FileUtils::mkdir_p(harvest_pth) \ +          unless FileTest.directory?(harvest_pth) +        fileinfo=(@opt.act[:verbose][:set]==:on \ +        || @opt.act[:verbose_plus][:set]==:on \ +        || @opt.act[:urls_selected][:set]==:on \ +        || @opt.act[:maintenance][:set]==:on) \ +        ? ("file://#{file}") : '' +        SiSU_Screen::Ansi.new( +          @opt.act[:color_state][:set], +          "harvest authors (#{@opt.files.length} files)", +          fileinfo +        ).dark_grey_title_hi unless @opt.act[:quiet][:set]==:on +        @output[lng][:html]=File.new(file,'w') +      end +    end +    def html_file_close +      @the_idx.keys.each do |lng| +        @output[lng][:html].close +        @output[lng][:html_mnt].close \ +          if @output[lng][:html_mnt].is_a?(File) +      end +    end +    def html_print +      def html_songsheet +        html_file_open +        html_head +        html_alph +        html_body +        html_tail +        html_file_close +      end +      def html_head_adjust(lng,type='') +        css_path,topics='','' +        if @env.output_dir_structure.by? == :language +          css_path=(type !~/maintenance/) \ +          ? '../../_sisu/css/harvest.css' +          : 'harvest.css' +          topics='topics.html' +        elsif @env.output_dir_structure.by? == :filetype +          css_path=(type !~/maintenance/) \ +          ? '../_sisu/css/harvest.css' +          : 'harvest.css' +          topics="topics.#{lng}.html" +        elsif @env.output_dir_structure.by? == :filename +          css_path=(type !~/maintenance/) \ +          ? './_sisu/css/harvest.css' +          : 'harvest.css' +          topics="topics.#{lng}.html" +        end +        ln=SiSU_i18n::Languages.new.language.list +        harvest_languages='' +        @the_idx.keys.each do |lg| +          if @env.output_dir_structure.by? == :language +            harvest_pth="../../#{lg}/manifest" +            file="#{harvest_pth}/authors.html" +          elsif @env.output_dir_structure.by? == :filetype +            harvest_pth='.' +            file="#{harvest_pth}/authors.#{lg}.html" +          elsif @env.output_dir_structure.by? == :filename +            harvest_pth='.' +            file="#{harvest_pth}/authors.#{lg}.html" +          end +          l=ln[lg][:t] +          harvest_languages += +            %{<a href="#{file}">#{l}</a>   } +        end +        sv=SiSU_Env::InfoVersion.instance.get_version +        if @env.output_dir_structure.by? == :language +          home_pth='../..' +          output_structure_by= +            '(output organised by language & filetype)' +        elsif @env.output_dir_structure.by? == :filetype +          home_pth='..' +          output_structure_by= +            '(output organised by filetype)' +        elsif @env.output_dir_structure.by? == :filename +          home_pth='.' +          output_structure_by= +            '(output organised by filename)' +        else +          home_pth='.' +          output_structure_by='(output organised by ?)' +        end +        <<WOK +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>SiSU Metadata Harvest - Authors</title> +<meta http-equiv="Content-Type" content="text/html;charset=utf-8" /> +<meta name="dc.title" content= "SiSU metadata harvest, Authors - SiSU information Structuring Universe, Structured information Serialised Units" /> +<meta name="dc.subject" content= "document structuring, ebook, publishing, PDF, LaTeX, XML, ODF, SQL, postgresql, sqlite, electronic book, electronic publishing, electronic document, electronic citation, data structure, citation systems, granular search, digital library" /> +<meta name="generator" content="#{sv.project} #{sv.version} of #{sv.date_stamp} (n*x and Ruby!)" /> +<link rel="generator" href="http://www.jus.uio.no/sisu/SiSU" /> +<link href="#{css_path}" rel="stylesheet" > +<link rel="shortcut icon" href="../_sisu/image/rb7.ico" /> +</head> +<body lang="en" xml:lang="en"> +<a name="top" id="top"></a> +<a name="up" id="up"></a> +<a name="start" id="start"></a> +<h1>SiSU Metadata Harvest - Authors #{output_structure_by}</h1> +<p>[<a href="#{home_pth}/index.html"> HOME </a>] also see <a href="#{topics}">SiSU Metadata Harvest - Topics</a></p> +<p>#{@env.widget_static.search_form}</p> +<hr /> +<p class="tiny">#{harvest_languages}</p> +<hr /> +WOK +      end +      def html_head +        @the_idx.keys.each do |lng| +          @output[lng][:html_mnt] \ +          << html_head_adjust(lng,'maintenance') \ +            if @opt.act[:maintenance][:set]==:on +          @output[lng][:html] \ +          << html_head_adjust(lng) +        end +      end +      def html_alph +        a=[] +        a << '<p>' +        @alph.each do |x| +          a << ((x =~/[0-9]/) \ +          ? '' +          : %{<a href="##{x}">#{x}</a>, }) +        end +        a=a.join +        @the_idx.keys.each do |lng| +          @output[lng][:html_mnt] << a \ +            if @opt.act[:maintenance][:set]==:on +          @output[lng][:html] << a +        end +      end +      def html_tail +        a =<<WOK +<hr /> +<a name="bottom" id="bottom"></a> +<a name="down" id="down"></a> +<a name="end" id="end"></a> +<a name="finish" id="finish"></a> +<a name="stop" id="stop"></a> +<a name="credits"></a> +#{SiSU_Proj_HTML::Bits.new.credits_sisu} +</body> +</html> +WOK +        @the_idx.keys.each do |lng| +          @output[lng][:html_mnt] << a \ +            if @output[lng][:html_mnt].is_a?(File) +          @output[lng][:html] << a +        end +      end +      def do_html(lng,html) +        @output[lng][:html_mnt] << html \ +          if @output[lng][:html_mnt].is_a?(File) +        @output[lng][:html] << html +      end +      def do_string_name(lng,attrib,string) +        f=/^(\S)/.match(string[0])[1] +        if @lng != lng +          @alph=@alphabet_list.dup +          @letter=@alph.shift +          @lng = lng +        end +        if @letter < f +          while @letter < f +            if @alph.length > 0 +              @letter=@alph.shift +              if @output[lng][:html_mnt].is_a?(File) +                @output[lng][:html_mnt] \ +                << %{\n<p class="letter"><a name="#{@letter}"></p>#{@letter}</a><p class="book_index_lev1"><a name="#{@letter.downcase}"></a></p>} +              end +              @output[lng][:html] \ +              << %{\n<p class="letter"><a name="#{@letter}">#{@letter}</a></p><p class="book_index_lev1"><a name="#{@letter.downcase}"></a></p>} +            else break +            end +          end +        end +      end +      def html_body +        the_idx=@the_idx +        the_idx.each_pair do |lng,lng_array| +          lng_array.sort.each do |a| +            do_string_name(lng,'',a) +            name=a[0].sub(/(.+?)(?:,.+|$)/,'\1').gsub(/\s+/,'_') +            x = %{<p class="author"><a name="#{name}">#{a[0]}</a></p>} +            if @output[lng][:html_mnt].is_a?(File) +              @output[lng][:html_mnt] << x +            end +            @output[lng][:html] << x +            lang_code_insert=SiSU_Env::FilenameLanguageCodeInsert.new(@opt,lng).language_code_insert +            works=[] +            a[1][:md].each do |i| +              manifest_at=if @env.output_dir_structure.by? == :language +                i[:file] + Sfx[:html] +              elsif @env.output_dir_structure.by? == :filetype +                i[:file] + lang_code_insert + Sfx[:html] +              elsif @env.output_dir_structure.by? == :filename +                './' + i[:file] + '/' + i[:page] +              else '' #error +              end +              work=[ +                "#{i[:date]} #{i[:title]}", +                %{<p class="publication">#{i[:date]} <a href="#{manifest_at}">#{i[:title]}</a>, #{i[:author][:authors_s]}</p>} +              ] +              works<<=(@output[lng][:html_mnt].is_a?(File)) \ +              ? (work.concat([%{<p class="publication">[<a href="#{i[:file]}.sst">src</a>]  #{i[:date]} <a href="file://#{manifest_at}">#{i[:title]}</a>, #{i[:author][:authors_s]} -- [<a href="#{i[:file]}.sst">#{i[:file]}.sst</a>]</p>}])) +              : work +            end +            works.sort_by {|y| y[0]}.each do |z| +              @output[lng][:html] << z[1] +              @output[lng][:html_mnt] << z[2] \ +                if @output[lng][:html_mnt].is_a?(File) +            end +          end +        end +      end +      self +    end +    def screen_print +      def cycle +        the_idx=@the_idx +        the_idx.sort.each do |a| +          puts a[0] +          a[1][:md].each do |x| +            puts "\t" + x[:file] +          end +        end +      end +      self +    end +  end +end +__END__ +#+END_SRC + +*** html_harvest_author_format.rb + +#+BEGIN_SRC ruby  :tangle "../lib/sisu/html_harvest_author_format.rb" +# <<sisu_document_header>> +module SiSU_FormatAuthor +  class Author +    def initialize(author_param) +      @author_param=author_param +    end +    def author_details +      @authors,@author_array=[],[] +      authors=@author_param.scan(/[^;]+/) +      authors.each do |a| +        a=a.strip +        if a =~/"(.+?)"/ +          @authors << { the: $1 } +          @author_array << $1.upcase +        else #if a =~/,/ +          x=a.scan(/[^,]+/) +          x[0]=x[0].strip +          x[1]=x[1].strip if x[1] +          if x.length==1 +            @authors << { the: x[0] } +            @author_array << x[0].upcase +          elsif x.length==2 +            @authors << { the: x[0], others: x[1] } +            @author_array << "#{x[0].upcase}, #{x[1]}" +          else #p x.length +          end +        end +      end +      l = @authors.length +      authors_string='' +      @authors.each_with_index do |a,i| +        authors_string += if a[:others] +          if (l - i) > 1 +            "#{a[:others]} #{a[:the]}, " +          else +            "#{a[:others]} #{a[:the]}" +          end +        else +          if (l - i) > 2 +            "#{a[:the]}, " +          else +            "#{a[:the]}" +          end +        end +      end +      { +        last_first_a: authors, +        last_first_format_a: @author_array, +        authors_h: @authors, +        authors_s: authors_string, +        authors_param: @author_param +      } +    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 +    harvest + +  - 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 diff --git a/org/html.org b/org/html.org new file mode 100644 index 00000000..1454226d --- /dev/null +++ b/org/html.org @@ -0,0 +1,5971 @@ +-*- mode: org -*- +#+TITLE:       sisu html +#+DESCRIPTION: documents - structuring, various output representations & search +#+FILETAGS:    :sisu:html: +#+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 + +* html +** part +*** html.rb + +#+BEGIN_SRC ruby  :tangle "../lib/sisu/html.rb" +# <<sisu_document_header>> +module SiSU_HTML +  begin +    require 'pstore' +  rescue LoadError +    SiSU_Utils::CodeMarker.new(__LINE__,__FILE__,:fuchsia). +      error('pstore NOT FOUND (LoadError)') +  end +  require_relative 'se_hub_particulars'                 # se_hub_particulars.rb +    include SiSU_Particulars +  require_relative 'html_table'                         # html_table.rb +  require_relative 'html_parts'                         # html_parts.rb +  require_relative 'html_format'                        # html_format.rb +    include SiSU_HTML_Format +  require_relative 'html_segments'                      # html_segments.rb +    include SiSU_HTML_Seg +  require_relative 'html_scroll'                        # html_scroll.rb +  require_relative 'html_promo'                         # html_promo.rb +    include SiSU_HTML_Promo +  require_relative 'html_tune'                          # html_tune.rb +    include SiSU_HTML_Tune +  class Source +    def initialize(opt) +      @opt=opt +      @particulars=SiSU_Particulars::CombinedSingleton.instance.get_all(opt) +    end +    def read +      begin +        songsheet +      ensure +        SiSU_Env::CreateSite.new(@opt).cp_css +        SiSU_Env::CreateSite.new(@opt).cp_base_images +        Dir.chdir(@opt.f_pth[:pth]) +      end +    end +    def songsheet +      begin +        @md=@particulars.md +        @fnb=@md.fnb +        @env=@particulars.env +        primary_output_file=(@opt.act[:html_seg][:set]==:on) \ +        ? (@md.file.output_path.html_seg.dir + '/' + @md.file.base_filename.html_segtoc) +        : (@md.file.output_path.html_scroll.dir + '/' + @md.file.base_filename.html_scroll) +        unless @opt.act[:quiet][:set]==:on +          tool=(@opt.act[:verbose][:set]==:on \ +          || @opt.act[:verbose_plus][:set]==:on \ +          || @opt.act[:maintenance][:set]==:on) \ +          ? ("#{@env.program.web_browser} file://#{primary_output_file}") +          : ("[#{@opt.f_pth[:lng_is]}] #{@opt.fno}") +          (@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], +              'HTML', +              tool +            ).green_hi_blue +          : SiSU_Screen::Ansi.new( +              @opt.act[:color_state][:set], +              'HTML', +              tool +            ).green_title_hi +          if (@opt.act[:verbose_plus][:set]==:on \ +          || @opt.act[:maintenance][:set]==:on) +            SiSU_Screen::Ansi.new( +              @opt.act[:color_state][:set], +              @opt.fns, +              "file://#{primary_output_file}" +            ).flow +          end +        end +        data=nil +        tuned_file_array=SiSU_HTML::Source::HTML_Environment.new(@particulars).tuned_file_instructions +        data=tuned_file_array +        if @opt.act[:html_scroll][:set]==:on +          scr_endnotes=SiSU_HTML::Source::Endnotes.new(data,@md).scroll +        end +        toc=SiSU_HTML::Source::Toc.new(@md,data).songsheet +        links_guide=SiSU_HTML::Source::LinksGuide.new(data,@md).toc +        data=tuned_file_array +        scr_toc=SiSU_HTML::Source::ScrollHeadAndSegToc.new(@md,toc,links_guide).in_common #watch +        if @opt.act[:html_seg][:set]==:on +          SiSU_HTML::Source::Seg.new(@md,data).songsheet +        end +        data=tuned_file_array +        if @opt.act[:html_scroll][:set]==:on +          scr=SiSU_HTML::Source::Scroll.new(@md,data,scr_endnotes).songsheet +          scroll=SiSU_HTML::Source::ScrollOutput.new( +            scr_toc, +            scr[:body], +            scr[:metadata], +            scr[:owner_details], +            scr[:tails], +            @md +          ).publish +          SiSU_HTML::Source::Output.new(scroll,@md).scroll +        end +      rescue +        SiSU_Errors::Rescued.new($!,$@,@opt.selections.str,@opt.fns).location do +          __LINE__.to_s + ':' + __FILE__ +        end +      ensure +        unless (@opt.act[:verbose_plus][:set]==:on \ +        || @opt.act[:maintenance][:set]==:on) +          texfiles=Dir["#{@env.processing_path.tune}/#{@opt.fns}*"] +          texfiles.each do |f| +            if FileTest.file?(f) +              File.unlink(f) +            end +          end +        end +        SiSU_Env::Clear.new(@opt.selections.str,@opt.fns,@md).param_instantiate +        @@flag,@@scr,@@seg,@@seg_endnotes,@@seg_subtoc={},{},{},{},{} +        @@tracker=0 +        @@seg_name,@@seg_name_x,@@seg_subtoc_array,@@seg_endnotes_array,@@tablefoot=Array.new(5){[]} +        @@filename_seg,@@seg_url,@@to_lev4,@@get_hash_to,@@get_hash_fn='','','','','' +      end +    end +    private +    class HTML_Environment +      def initialize(particulars) +        @particulars=particulars +        @md,@env=particulars.md,particulars.env +        @env,@css=particulars.env,SiSU_Style::CSS.new +      end +      def tuned_file_instructions +        @tell=SiSU_Screen::Ansi.new(@md.opt.act[:color_state][:set]) +        ao_array=@particulars.ao_array # ao file drawn here +        tuned_file_array=SiSU_HTML_Tune::Tune.new(ao_array,@md).songsheet +        tuned_file_array +      end +    end +    class LinksGuide +      @links_guide_toc=[] +      def initialize(data,md) +        @data,@md=data,md +        @links_guide_=SiSU_Env::CreateSite.new(@md.opt).html_quick_ref? +      end +      def toc +        @links_guide_toc=[] +        if @links_guide_ +          format_head_toc=SiSU_HTML_Format::HeadToc.new(@md) +          guide_type='horzontal' #values: horizontal or vertical +          @links_guide_toc << format_head_toc.links_guide_open(guide_type) +          if defined? @md.lnk \ +          and @md.lnk +            @md.lnk.each do |l| +              if defined? l[:say] +                target=(l[:url] !~/^\.(\.)?\//) \ +                ? 'external' +                : '_top' +                s_lnk_url,s_lnk_lnk=l[:url],l[:say] +                txt_obj={ +                  lnk_url: s_lnk_url, +                  lnk_txt: s_lnk_lnk, +                  target: target, +                } +                lev_dob_ocn=SiSU_HTML_Format::FormatToc.new(@md,txt_obj) +                @links_guide_toc << lev_dob_ocn.links_guide if s_lnk_lnk +              end +            end +          end +          format_head_toc=SiSU_HTML_Format::HeadToc.new(@md) +          @links_guide_toc << format_head_toc.links_guide_close #(guide_type) +          @links_guide_toc +        else '' +        end +      end +    end +    class Endnotes +      include SiSU_HTML_Format +      def initialize(data,md) +        @data,@md=data,md +      end +      def scroll +        @scr_endnotes=[] +        SiSU_HTML_Format::HeadScroll.new(@md) +        @data.each do |dob| +          pg=dob.dup +          unless pg.is ==:code +            if pg.obj =~/(?:#{Mx[:en_a_o]}|#{Mx[:en_b_o]})[\d*+]+ / +              endnote_array=[] +              if pg.obj=~/#{Mx[:en_a_o]}[\d*+].+?#{Mx[:en_a_c]}/m +                endnote_array = pg.obj.scan(/#{Mx[:en_a_o]}[\d*+]+(.+?)#{Mx[:en_a_c]}/m) +              end +              if pg.obj=~/#{Mx[:en_b_o]}[\d*]+\s.+?#{Mx[:en_b_c]}/m +                endnote_array = pg.obj.scan(/#{Mx[:en_b_o]}[\d*]+(.+?)#{Mx[:en_b_c]}/m) +              end +              if pg.obj=~/#{Mx[:en_b_o]}[\d+]+\s.+?#{Mx[:en_b_c]}/m +                endnote_array = pg.obj.scan(/#{Mx[:en_b_o]}[\d+]+(.+?)#{Mx[:en_b_c]}/m) +              end +              endnote_array.flatten.each do |note| +                txt_obj={ txt: note } +                format_scroll=SiSU_HTML_Format::FormatScroll.new(@md,txt_obj) +                @scr_endnotes << format_scroll.endnote_body +              end +            end +          end +        end +        @scr_endnotes +      end +    end +    class Toc <LinksGuide +      @@toc={ seg: [], seg_mini: [], scr: [] } +      @@seg_url='' +      @@firstseg=nil +      def initialize(md=nil,data='') +        @data,@md=data,md +        @tell=SiSU_Screen::Ansi.new(@md.opt.act[:color_state][:set]) if @md +      end +      def songsheet #extracts toc for scroll & seg +        if (@md.opt.act[:verbose][:set]==:on \ +        || @md.opt.act[:verbose_plus][:set]==:on \ +        || @md.opt.act[:maintenance][:set]==:on) +          SiSU_Screen::Ansi.new( +            @md.opt.act[:color_state][:set], +            'Toc' +          ).txt_grey +        end +        toc=nil +        @@firstseg=nil +        @@toc={ seg: [], seg_mini: [], scr: [] } +        @data.each do |dob| +          if dob.is==:heading \ +          || dob.is==:heading_insert +            dob_toc=dob.dup +            toc=if dob_toc.is ==:heading \ +            || dob.is==:heading_insert +              toc=case dob_toc.ln +              when 0 then SiSU_HTML::Source::Toc.new(@md,dob_toc).level_0 +              when 1 then SiSU_HTML::Source::Toc.new(@md,dob_toc).level_1 +              when 2 then SiSU_HTML::Source::Toc.new(@md,dob_toc).level_2 +              when 3 then SiSU_HTML::Source::Toc.new(@md,dob_toc).level_3 +              when 4 then SiSU_HTML::Source::Toc.new(@md,dob_toc).level_4 +              when 5 then SiSU_HTML::Source::Toc.new(@md,dob_toc).level_5 +              when 6 then SiSU_HTML::Source::Toc.new(@md,dob_toc).level_6 +              else nil +              end +            end +            toc.each do |k,d| +              d.gsub!(/(?:#{Mx[:en_a_o]}.+?#{Mx[:en_a_c]}|#{Mx[:en_b_o]}.+?#{Mx[:en_b_c]})\s*/m,' ') +            end if toc +            if @@firstseg.nil? \ +            and dob.ln==4 \ +            and dob.name =~/\S+/ +              @@firstseg=dob.name +            end +            if toc +              begin +                @@toc[:seg] << toc[:seg] if toc[:seg] +                @@toc[:seg_mini] << toc[:seg_mini] if toc[:seg_mini] +                @@toc[:scr] << toc[:scr] if toc[:scr] +              rescue +                SiSU_Errors::Rescued.new($!,$@,@md.opt.selections.str,@md.fns).location do +                  __LINE__.to_s + ':' + __FILE__ +                end +              end +            end +          end +        end +        @md.firstseg=@@firstseg +        @@toc +      end +      def minitoc +        minitoc=@@toc[:seg_mini].join("\n") +        '<div class="toc">' + minitoc + '</div>' +      end +    protected +      def rss #sort all wrong, disabled but kept +        @@toc[:seg] <<<<WOK +<center> +<table><tr><td> +<p><font color="#222222" #{the_font.set_face} size="2"> +(relatively static) RSS feeds for DOCUMENTS:<br> +<a href="../rssfeed/documents.xml"><img border="0" height="14" width="36" src="../_sisu/image/rss.png" alt="RSS feed"></a> http://www.jus.uio.no/lm/rssfeed/documents.xml<br> +<a href="../rssfeed/tradelaw.xml"><img border="0" height="14" width="36" src="../_sisu/image/rss.png" alt="RSS feed"></a> http://www.jus.uio.no/lm/rssfeed/tradelaw.xml<br> +<a href="../rssfeed/environmental.xml"><img border="0" height="14" width="36" src="../_sisu/image/rss.png" alt="RSS feed"></a> http://www.jus.uio.no/lm/rssfeed/environmental.xml<br> +<center><a href="mailto:info@address.com" target="_top">info@address.com</a></center> +</font></p> +</td></tr></table> +WOK +      end +#not used --> +      def level_endnotes +        if @md.flag_endnotes +          format_head_scroll=SiSU_HTML_Format::HeadScroll.new(@md) +          @@toc[:scr] << format_head_scroll.toc_endnote +        end +      end +      def level_concordance +        format_head_toc=SiSU_HTML_Format::HeadToc.new(@md) +        @@toc[:seg_mini] << format_head_toc.mini_seg_concordance +      end +      def level_metadata +        format_head_toc=SiSU_HTML_Format::HeadToc.new(@md) +        @@toc[:scr] << format_head_toc.metadata +        @@toc[:seg] << format_head_toc.seg_metadata +        @@toc[:seg_mini] << format_head_toc.mini_seg_metadata +      end +      def level_word_index +        format_head_toc=SiSU_HTML_Format::HeadToc.new(@d0c) +        @@toc[:scr] << format_head_toc.concordance +        @@toc[:seg] << format_head_toc.concordance +        @@toc[:seg_mini] << format_head_toc.mini_concordance +      end +# <-- not used +      def level_0 +        dob=@data +        linkname,link=dob.obj.strip,dob.ocn +        if link \ +        and link.to_s !~/#/ #% keep eye on link +          SiSU_HTML_Format::ParagraphNumber.new(@md,link) +        end +        title=linkname +        toc={} +        txt_obj={ txt: title } +        format_toc=SiSU_HTML_Format::FormatToc.new(@md,txt_obj) +        toc[:seg]=format_toc.lev0 +        toc[:seg_mini]=format_toc.mini_lev0 +        title=if dob.ocn ==0 then linkname +        else +          @@toc[:scr] <<  '<br>' +          %{<b><a href="##{dob.ocn}">#{linkname}</a></b>} +        end +        txt_obj={ txt: title } +        format_toc=SiSU_HTML_Format::FormatToc.new(@md,txt_obj) +        toc[:scr]=format_toc.lev0 +        toc +      end +      def level_1 +        dob=@data +        linkname,link=dob.obj.strip,dob.ocn +        if link \ +        and link.to_s !~/#/ #% keep eye on link +          SiSU_HTML_Format::ParagraphNumber.new(@md,link) +        end +        title=if dob.obj !~/^Metadata$/ then linkname +        else +          link='metadata' +          %{<b><a href="#{link}#{@md.lang_code_insert}#{Sfx[:html]}">#{linkname}</a></b>} +        end +        toc={} +        txt_obj={ txt: title } +        format_toc=SiSU_HTML_Format::FormatToc.new(@md,txt_obj) +        toc[:seg]=if dob.name =~/^meta/ \ +        and dob.obj =~/Document Information/ +          format_toc.lev0 +        else format_toc.lev1 +        end +        toc[:seg_mini]=if dob.name =~/^meta/ \ +        and dob.obj =~/Document Information/ +          @md.concord_make \ +          ? format_toc.mini_concord_tail +          : format_toc.mini_tail +        else format_toc.mini_lev1 +        end +        title=if dob.ocn ==0 +          if dob.name =~/^meta/ \ +          and dob.obj =~/Document Information/ +            %{<a href="#docinfo">#{linkname}</a>} +          else linkname +          end +        else +          @@toc[:scr] <<  '<br>' +          %{<b><a href="##{dob.ocn}">#{linkname}</a></b>} +        end +        txt_obj={ txt: title } +        format_toc=SiSU_HTML_Format::FormatToc.new(@md,txt_obj) +        toc[:scr]=if dob.obj =~/^Metadata$/ then '' +        elsif txt_obj[:txt] =~/<a href="#">/ +          format_toc.lev1.gsub(/<a href="#">|<\/a>/,'') +        else format_toc.lev1 +        end +        toc +      end +      def level_2 +        dob=@data +        linkname,ocn=dob.obj.strip,dob.ocn +        p_num=if ocn \ +        and ocn.to_s !~/#/ +          SiSU_HTML_Format::ParagraphNumber.new(@md,ocn) +        else nil +        end +        txt_obj={ txt: linkname } +        format_toc=SiSU_HTML_Format::FormatToc.new(@md,txt_obj) +        toc={} +        toc[:seg]=format_toc.lev2 +        toc[:seg_mini]=format_toc.mini_lev2 +        if p_num +          title=%{#{p_num.goto}#{linkname}</a>} +          txt_obj={ txt: title } +          format_toc=SiSU_HTML_Format::FormatToc.new(@md,txt_obj) +          toc[:scr]=if txt_obj[:txt] =~/<a href="#">/ +            format_toc.lev2.gsub(/<a href="#">|<\/a>/,'') +          else format_toc.lev2 +          end +        end +        toc +      end +      def level_3 +        dob=@data +        linkname,ocn=dob.obj.strip,dob.ocn +        p_num=if ocn \ +        and ocn.to_s !~/#/ +          SiSU_HTML_Format::ParagraphNumber.new(@md,ocn) +        else nil +        end +        txt_obj={ txt: linkname } +        format_toc=SiSU_HTML_Format::FormatToc.new(@md,txt_obj) +        toc={} +        toc[:seg]=format_toc.lev3 +        toc[:seg_mini]=format_toc.mini_lev3 +        if p_num +          title=%{#{p_num.goto}#{linkname}</a>} +          txt_obj={ txt: title } +          format_toc=SiSU_HTML_Format::FormatToc.new(@md,txt_obj) +          toc[:scr]=if txt_obj[:txt] =~/<a href="#">/ +            format_toc.lev3.gsub(/<a href="#">|<\/a>/,'') +          else format_toc.lev3 +          end +        end +        toc +      end +      def level_4 +        dob=@data +        linkname,ocn=dob.obj.strip,dob.ocn +        p_num=SiSU_HTML_Format::ParagraphNumber.new(@md,ocn) if ocn +        if dob.ln ==4 +          fnh={ +            fn: dob.name, +          } +          f=@md.file.base_filename.html_seg(fnh) +          seg_link=%{  <a href="#{f}" target="_top"> +    #{dob.obj} +  </a> } +          @@seg_url=dob.name +        elsif dob.obj =~/\d+.\d+.\d+.\d+|\d+.\d+.\d+|\d+.\d+|\d+/ +          fn,hd=/^(\d+.\d+.\d+.\d+|\d+.\d+.\d+|\d+.\d+|\d+)(.*)/.match(dob.obj)[1,2] +          fnh={ +            fn: fn, +          } +          f=@md.file.base_filename.html_seg(fnh) +          seg_link=%{<a href="#{f}" target="_top">#{fn} #{hd}</a> } +        end +        p_num=SiSU_HTML_Format::ParagraphNumber.new(@md,ocn) if ocn +        @file=SiSU_Env::FileOp.new(@md) if @md +        txt_obj=if seg_link=~/sisu_manifest\.html/ +          man_link=if @file.output_dir_structure.by_language_code? \ +          or @file.output_dir_structure.by_filetype? +            seg_link.gsub(/sisu_manifest\.html/,"../../manifest/#{@file.base_filename.manifest}") +          else seg_link +          end +          { txt: man_link } +        else { txt: seg_link } +        end +        format_toc=SiSU_HTML_Format::FormatToc.new(@md,txt_obj) +        toc={} +        toc[:seg]=format_toc.lev4 +        toc[:seg_mini]=format_toc.mini_lev4 +        title=%{#{p_num.goto}#{linkname}</a>} if p_num +        txt_obj=if title=~/sisu_manifest.html/ +          man_link=title.gsub(/sisu_manifest.html/,"../manifest/#{@file.base_filename.manifest}") +          { txt: man_link } +        else { txt: title } +        end +        format_toc=SiSU_HTML_Format::FormatToc.new(@md,txt_obj) +        toc[:scr]=format_toc.lev4 +        toc +       #end +      end +      def level_5 +        dob=@data +        linkname,ocn=dob.obj.strip,dob.ocn +        toc={} +        if ocn \ +        and ocn.to_s !~/#/ +          fnh={ +            fn: @@seg_url, +          } +          f=@md.file.base_filename.html_seg(fnh) +          p_num=SiSU_HTML_Format::ParagraphNumber.new(@md,ocn) +          lnk_n_txt=%{  <a href="#{f}##{ocn}"> +    #{linkname} +  </a>} +          txt_obj={ txt: lnk_n_txt } +          format_toc=SiSU_HTML_Format::FormatToc.new(@md,txt_obj) +          toc[:seg]=format_toc.lev5 +          toc[:seg_mini]=format_toc.mini_lev5 +          title=%{#{p_num.goto}#{linkname}</a>} +          txt_obj={ txt: title } +          format_toc=SiSU_HTML_Format::FormatToc.new(@md,txt_obj) +          toc[:scr]=format_toc.lev5 +        end +        toc +      end +      def level_6 +        dob=@data +        linkname,ocn=dob.obj.strip,dob.ocn +        toc={} +        if ocn \ +        and ocn.to_s !~/#/ +          fnh={ +            fn: @@seg_url, +          } +          f=@md.file.base_filename.html_seg(fnh) +          p_num=SiSU_HTML_Format::ParagraphNumber.new(@md,ocn) +          lnk_n_txt=%{  <a href="#{f}##{ocn}"> +  #{linkname} +</a>} +          txt_obj={ txt: lnk_n_txt } +          format_toc=SiSU_HTML_Format::FormatToc.new(@md,txt_obj) +          toc[:seg]=format_toc.lev6 +          toc[:seg_mini]=format_toc.mini_lev6 +          title=%{#{p_num.goto}#{linkname}</a>} +          txt_obj={ txt: title } +          format_toc=SiSU_HTML_Format::FormatToc.new(@md,txt_obj) +          toc[:scr]=format_toc.lev6 +        end +        toc +      end +      def level_crosslink +        dob=@data +        dob=if dob !~/^4~!/ +          dob.gsub(/^4~!\s+(\S+)\s+(.+)/, +            %{<table><tr><td width =\"80\"></td> +  <td><a href="http://\\1" target="_top"> +    #{@png.crosslink_ext} +        \\2 +    <\/a> +  </td></tr></table> +}) +        else +          dob.gsub(/^4~!\s+(\S+)\s+(.+)/, +            %{<table><tr><td width ="80"> +  </td><td> +    <a href="\\1" target="_top"> +      #{@png.crosslink} +          \\2 +    <\/a> +  </td></tr></table> +}) +        end +      end +    end +    class ScrollHeadAndSegToc < Toc +      include SiSU_Parts_HTML +      def initialize(md='',toc='',links_guide_toc='') +        @md,@toc,@links_guide_toc=md,toc,links_guide_toc +        @make=SiSU_Env::ProcessingSettings.new(@md) +      end +      def in_common +        toc_shared=[] +        @segtoc=[] +        if (@md.opt.act[:verbose][:set]==:on \ +        || @md.opt.act[:verbose_plus][:set]==:on \ +        || @md.opt.act[:maintenance][:set]==:on) +          SiSU_Screen::Ansi.new( +            @md.opt.act[:color_state][:set], +            'Scroll & Segtoc' +          ).txt_grey +        end +        format_head_toc=SiSU_HTML_Format::HeadToc.new(@md) +        dochead=format_head_toc.head +        dochead=dochead.gsub(/toc\.(html)/,'doc.\1') #kludge +        toc_shared << dochead +        @segtoc << format_head_toc.head +        if @make.build.html_top_band? +          toc_shared << format_head_toc.scroll_head_navigation_band +        end +        if defined? @md.rights.all +          rights=format_head_toc.rights.all +          rights=SiSU_HTML_Tune::CleanHTML.new(rights).clean +        end +        if @md.prefix_b +          prefix_b=format_head_toc.notes.prefix_b +          prefix_b=SiSU_HTML_Tune::CleanHTML.new(prefix_b).clean +        end +        if @make.build.html_top_band? +          @segtoc << format_head_toc.seg_head_navigation_band +        end +        toc_shared << format_head_toc.scroll_head_title_banner_open +        @segtoc << format_head_toc.seg_head_title_banner_open +        tmp_head=nil +        doc_title_endnote=@md.title.full.gsub(/(\*+)/, +          '<sup><a href="#endnotes">\1</a></sup>') +        tmp_head=doc_title_endnote + "\n" +        txt_obj={ txt: tmp_head } +        format_txt_obj=SiSU_HTML_Format::FormatTextObject.new(@md,txt_obj) +        toc_shared << format_txt_obj.center_bold +        @segtoc << format_txt_obj.center_bold +        if defined? @md.creator.author +          creator=SiSU_HTML_Tune::CleanHTML.new(@md.creator.author).clean_for_html +          creator_endnote=creator.gsub(/(\*+)/, +            %{ <sup><a href="#notes">\\1</a></sup>}) +          tmp_head=creator_endnote + "\n" +          txt_obj={ txt: tmp_head } +          format_txt_obj=SiSU_HTML_Format::FormatTextObject.new(@md,txt_obj) +          toc_shared << format_txt_obj.center_bold +          @segtoc << format_txt_obj.center_bold +        end +        toc_shared << "#{the_table_close*1}\n" +        @segtoc << "#{the_table_close*1}\n" +        tmp_head=nil +        if @md.prefix_a +          tmp_head ||= %{<p>#{@md.prefix_a}\n} +          toc_shared << tmp_head.dup +          @segtoc << tmp_head.dup +        end +        tmp_head=nil +        toc_shared << @links_guide_toc +        if defined? @md.rights.all #and ? @md.rights.all +          toc_shared << rights +        end +        if defined? @md.prefix_b +          toc_shared << prefix_b +        end +        if @make.build.toc? #Table of Contents added/appended here +          toc_shared << @toc[:scr] +        end +        @segtoc << @links_guide_toc +        @segtoc << @toc[:seg] +        if defined? @md.rights.all \ +        and not @md.rights.all.empty? +          @segtoc << rights +        end +        @segtoc << prefix_b if @md.prefix_b +        #Segtoc tail added here +        @segtoc << "</p>\n" #bugfix sort later DEBUGNOW +        @segtoc << @seg_toc_band_bottom +        @segtoc << format_head_toc.seg_navigation_tail << format_head_toc.html_close +        @segtoc=@segtoc.flatten.compact #watch +        if @md.opt.act[:html_seg][:set]==:on +          SiSU_HTML::Source::Output.new(@segtoc,@md).segtoc +        end +        @segtoc=[] +        @toc[:scr],@toc[:seg]=[],[] +        toc_shared +      end +    end +    class Table < SiSU_HTML_Table::TableHTML +    end +    class Scroll < SiSU_HTML_Scroll::Scroll +    end +    class ScrollOutput +      def initialize(scr_toc,scr_body,scr_metadata,scr_owner_details,scr_tails,md) +        @scr_toc,@scr_body,@scr_metadata,@scr_owner_details,@scr_tails,@md=scr_toc,scr_body,scr_metadata,scr_owner_details,scr_tails,md +      end +      def publish +        scroll=[] +        scroll << @scr_toc << '<div class="scroll">' << @scr_body << @scr_endnotes << @scr_owner_details << '</div>' << @scr_tails +        scroll=scroll.flatten.compact #watch +      end +    end +    class Seg < SiSU_HTML_Seg::Seg +    end +    class Output +      def initialize(data='',md='') +        @data,@md=data,md +        @file=SiSU_Env::FileOp.new(md) +        @o_str ||=SiSU_Env::ProcessingSettings.new(md).output_dir_structure +      end +      def scroll +        if @md.opt.act[:html_scroll][:set]==:on +          begin +            @filename_html_scroll=@file.write_file.html_scroll +            @data.each do |para| +              para=para.strip. +                gsub(/<:.+?>/,''). +                gsub(Xx[:html_relative2],@file.path_rel_links.html_scroll_2). +                gsub(Xx[:html_relative1],@file.path_rel_links.html_scroll_1). +               #gsub(/#{Xx[:html_relative]}/,@file.path_rel_links.html_scroll). +                gsub(/#{Rx[:mx_fa_clean]}/,'') +              unless para =~/\A\s*\Z/ +                @filename_html_scroll.puts para,"\n" +              end +            end +          rescue +            SiSU_Errors::Rescued.new($!,$@,@md.opt.selections.str,@md.fns).location do +              __LINE__.to_s + ':' + __FILE__ +            end +          ensure +            @filename_html_scroll.close +          end +        end +      end +      def segtoc +        if @md.opt.act[:html_seg][:set]==:on +          begin +            @filename_html_segtoc=@file.write_file.html_segtoc +            @data.each do |para| +              para=para.strip. +                gsub(/<!.+?!>/,''). +                gsub(Xx[:html_relative2],@file.path_rel_links.html_seg_2). +                gsub(Xx[:html_relative1],@file.path_rel_links.html_seg_1) +              unless para =~/\A\s*\Z/ +                @filename_html_segtoc.puts para,"\n" +              end +            end +          rescue +            SiSU_Errors::Rescued.new($!,$@,@md.opt.selections.str,@md.fns).location do +              __LINE__.to_s + ':' + __FILE__ +            end +          ensure +            @filename_html_segtoc.close +            pwd_set=Dir.pwd +            idx_lnk=(@o_str.dump_or_redirect?) \ +            ? @file.base_filename.manifest +            : @file.base_filename.html_segtoc +            mlnk=@file.base_filename.html_seg_index +            Dir.chdir(@file.output_path.html_seg.dir) +            FileUtils::rm_f(mlnk) +            FileUtils::ln_s(idx_lnk,mlnk) +            Dir.chdir(pwd_set) +          end +        end +      end +    end +  end +end +__END__ +#+END_SRC + +*** html_parts.rb + +#+BEGIN_SRC ruby  :tangle "../lib/sisu/html_parts.rb" +# <<sisu_document_header>> +module SiSU_Parts_HTML +  require_relative 'generic_parts'                       # generic_parts.rb +  include SiSU_Parts_Generic +  def the_line_break +    '<br>' +  end +  def the_table_close +    '</td></tr> +</table>' +  end +  def the_table_cellpad_box +    '"20"' +  end +  def the_color +    def white +      '#ffffff' +    end +    def black +      '#000000' +    end +    def grey_pale +      '#eeeeee' +    end +    def grey_medium +      '#cccccc' +    end +    def grey +      '#999999' +    end +    def blue_ink +      '#003399' +    end +    def blue_tinge +      '#e3ecef' +    end +    def yellow_light +      '#fff3b6' +    end +    def table1 +      'ffffcc' +    end +    def table2 +      'c0d0f0' +    end +    def band1 +      %{"#{white}"} +    end +    def band2 +      %{"#{white}"} +    end +    self +  end +  def the_url_decoration +    #def tex_open                     #'{\UseTextSymbol{OML}{<}}' +    #  Dx[:url_o] +    #end +    #def tex_close                    #'{\UseTextSymbol{OML}{>}}' +    #  Dx[:url_c] +    #end +    def xml_open                     #'<' +      Dx[:url_o] +    end +    def xml_close                    #'>' +      Dx[:url_c] +    end +    def txt_open +      '<' +    end +    def txt_close +      '>' +    end +    self +  end +  def the_width +    def table1 +      '"100%"' +    end +    def table2 +      '"99%"' +    end +    def table_txt +      '"94%"' +    end +    def table_txt_r +      '"96%"' +    end +    self +  end +  def the_png +    def _url_path_image_base #used for html image display +      "#{Xx[:html_relative2]}_sisu/image" +    end +    def ico +      %{  <link rel="shortcut icon" href="../_sisu/image/#{the_icon.i_ico}" />} +    end +    def png_home +      %{<img border="0" src="#{_url_path_image_base}/#{the_icon.home_button}" alt="#{the_text.home} -->" />} +    end +    def png_home_button +      rel=@dir.path_rel_links.html_scroll_2 +      %{<img border="0" src="#{rel}/#{the_icon.home_button}" alt="#{the_text.home} -->" />} +    end +    self +  end +  def the_font +    def set_fonts +      'verdana, arial, georgia, tahoma, sans-serif, helvetica, times, roman' +     #'verdana, arial, georgia, tahoma, sans-serif, helvetica, "times new roman", times, roman' +    end +    def set_face +      %{face="#{set_fonts}"} +    end +    def set_color +      'color="#000000"' +    end +    def set_size_endnote +      'size="3"' +    end +    def set_small +      'size="3"' +    end +    def set_tiny +      'size="2"' +    end +    def paragraph_font_tiny +      %{<font #{set_tiny} #{set_face}>} +    end +    def paragraph_font_small +      %{<font #{set_small} #{set_face}>} +    end +    self +  end +  def the_nav +    def txt_homepage +      %{  <font face="#{the_font.set_fonts}" size="2"> +     home  +  </font> } +    end +    def txt_toc_link +      %{  <font face="#{the_font.set_fonts}" size="2"> +      toc  +  </font> } +    end +    def txt_doc_link +      %{  <font face="#{the_font.set_fonts}" size="2"> +     scroll  +  </font> } +    end +    def txt_manifest +      #{png_manifest} document manifest +      %{  <font face="#{the_font.set_fonts}" size="2"> +    [ document manifest ] +  </font> } +    end +    def txt_concordance +      %{  <font face="#{the_font.set_fonts}" size="2"> +      A-Z  +  </font> } +    end +    self +  end +  def the_banner +    def home_button_only +      %{<a href="#{url.site}/"> +  #{the_png.png_home_button} +  </a>} +    end +    def banner_band +      %{<table summary="home button" width="100%" border="0" cellpadding="3" align="center"> +<tr><td align="left" valign="middle"> +  <a href="#{url.site}/" target="_top"> +    #{the_png.png_home} +  </a> +</td> +<td width="90%"> +#{the_table_close}} +    end +    def instrument_cover_band_scr +      '<table summary="scroll instrument cover band" width="100%" border="0" cellpadding="8" align="center"> +<tr><td align="center">' +    end +    def instrument_cover_band_seg +      '<table summary="segment instrument cover band, title, author, location" width="100%" border="0" cellpadding="8" align="center"> +<tr><td align="center">' +    end +    self +  end +  def the_margin +    def txt_0 +      %{<table summary="" width=#{the_width.table_txt} border="0" cellpadding="2" align="center"> +<tr><td width=#{indent_level_0} align="right"> +</td><td valign="top" align="justify">} +    end +    def txt_1 +      %{<table summary="" width=#{the_width.table_txt} border="0" cellpadding="2" align="center"> +<tr><td width=#{indent_level_1} align="right"></td><td valign="top" align="justify">} +    end +    def txt_2 +      %{<table summary="" width=#{the_width.table_txt} border="0" cellpadding="2" align="center"> +<tr><td width=#{indent_level_2} align="right"> +</td> +<td valign="top" align="justify">} +    end +    def txt_3 +      %{<table summary="" width=#{the_width.table_txt} border="0" cellpadding="2" align="center"> +<tr><td width=#{indent_level_3} align="right"> +</td> +<td valign="top" align="justify">} +    end +    def css +      '<table summary="normal text css" width="100%" border="0" cellpadding="2" align="center"> +<tr><td valign="top" align="justify"> ' +    end +    def num +      '</p> </td><td width="4%" align="right" valign="top">' +    end +    def numless +      '</td><td width="4%" align="right" valign="top">' +    end +    def num_css +      '</td> +<td width="2%" align="right" valign="top">  ' +    end +    self +  end +end +module SiSU_Proj_HTML +  require_relative 'se'                                 # se.rb +  include SiSU_Env +  #require_relative 'css'                                # css.rb +  #  include SiSU_Style +  class Bits +    include SiSU_Parts_HTML +    def initialize +      @v=SiSU_Env::InfoVersion.instance.get_version +      #@dir=SiSU_Env::InfoEnv.new +      #@date=SiSU_Env::InfoDate.new #{@date.year} +    end +    def txt_generator +      %{  <meta name="generator" content="#{@v.project} #{@v.version} of #{@v.date_stamp} (#{@v.date}) (n*x and Ruby!)" /> +    <link rel="generator" href="http://www.sisudoc.org/" />} +    end +    def widget_sisu_text +<<WOK +  <p class="tiny"><font color="#666666" size="2"> +    Output generated by +    <a href="#{the_url.sisu}"> +      #{@v.project} +    </a> +    #{@v.version} #{@v.date} (#{@v.date_stamp}) +  </font></p> +WOK +    end +    def credits_sisu_manifest +      widget_sisu_text +    end +    def widget_sisu +<<WOK +<!-- widget sisu --> +<tr><td valign="top" width="100%"> +<!-- SiSU Rights --> +#{widget_sisu_text} +</td></tr> +WOK +    end +    def credits_sisu +      %{<div class="substance"> +<table summary="SiSU summary" cellpadding="4" border="0"> +<tr><td> +  #{widget_sisu} +</table></div>} +      '' +    end +    def widget_promo # Array used to build promo from list.yml and promo.yml +    #  ['sisu_icon','sisu','sisu_search_libre','open_society','fsf','ruby'] +    end +  end +  class Home +    def initialize +      @v=SiSU_Env::InfoVersion.instance.get_version +      @dir=SiSU_Env::InfoEnv.new +      @date=SiSU_Env::InfoDate.new #{@date.year} +    end +    def redirect +      <<WOK +<html><head> +<title>SiSU</title> +<meta http-equiv="refresh" content="0, url=http://www.sisudoc.org/sisu/SiSU/"> +</head> +<body> +SiSU informtion provided at <a href="http://www.sisudoc.org/sisu/SiSU/">www.sisudoc.org/sisu/SiSU</a><p /> +If your browser supports redirection, you will be escorted there shortly. +</body> +</html> +WOK +    end +    def homepage +      <<WOK +<html xmlns="http://www.w3.org/1999/xhtml"> +<head> +<meta http-equiv="Content-Type" content="text/html;charset=utf-8" /> +<title>SiSU information Structuring Universe - Structured information, Serialized Units - software for electronic texts, documents, books, digital libraries in plaintext, HTML, EPUB, XHTML, XML, ODF (OpenDocument), LaTeX, PDF, SQL (PostgreSQL and SQLite), and for search</title> +<meta name="dc.title" content="SiSU - SiSU information Structuring Universe, Structured information Serialised Units, #{@date.year_static}" /> +<meta name="dc.creator" content="Ralph Amissah" /> +<meta name="dc.subject" content= "document structuring, ebook, publishing, PDF, LaTeX, XML, ODF, EPUB, SQL, postgresql, sqlite, electronic book, electronic publishing, electronic document, electronic citation, data structure, citation systems, granular search, digital library" /> +<meta name="dc.publisher" content= "SiSU http://www.sisudoc.org/" /> +<meta name="dc.language" content="en" /> +<meta name="dc.rights" content="Copyright Ralph Amissah" /> +<meta name="generator" content="#{@v.project} #{@v.version} of #{@v.date_stamp} (#{@v.date}) (n*x and Ruby!)" /> +<link rel="generator" href="http://www.sisudoc.org/" /> +<link rel="stylesheet" href="./#{@dir.path.style}/harvest.css" type="text/css" /> +<link rel="shortcut icon" href="./_sisu/image/rb7.ico" /> +</head> + +<body lang="en" xml:lang="en"> +<a name="top" id="top"></a> +<a name="up" id="up"></a> +<a name="start" id="start"></a> + +<h1>SiSU</h1> +<p> +[<a href="http://sisudoc.org/sisu_manual/en/html/sisu/toc.html">Manual</a>] +</p> +<p> +[<a href="http://git.sisudoc.org/gitweb/?p=code/sisu.git;a=summary">Source</a>] +[<a href="http://lists.sisudoc.org/listinfo/sisu">List Info (sisu@lists.sisudoc.org)</a>] +</p> + +<h1>SiSU Markup Samples</h1> +<p> +[<a href="http://git.sisudoc.org/gitweb/?p=doc/sisu-markup-samples.git;a=summary">Source</a>] +[<a href="http://sisudoc.org/sisu_markup_samples.html">Output</a>] +</p> + +<hr /> + +<h2 class="top_band_tiny"> +  Structured information, Serialized Units +     +  <a href="http://www.sisudoc.org" target="_top"> +    <www.sisudoc.org> +  </a> +    or   +  <a href="http://www.jus.uio.no/sisu/" target="_top"> +    <www.jus.uio.no/sisu/> +  </a> +software for electronic texts, document collections, books, digital libraries & search, with "atomic search" & text locating system (shared object citation numbering: "<i>ocn</i>"). +Outputs include: plaintext, HTML, EPUB, ODT (OpenDocumentText), (XHTML, XML,) LaTeX, PDF, SQL (PostgreSQL and SQLite). +</h2> +<p class="small"> +<a href="mailto:sisu@lists.sisudoc.org"> +<sisu@lists.sisudoc.org> +</a> +<a href="http://lists.sisudoc.org/listinfo/sisu"> +<http://lists.sisudoc.org/listinfo/sisu> +</a> +</p> +<p class="small"> +<a href="mailto:ralph@amissah.com"> +<ralph@amissah.com> +</a> +<a href="mailto:ralph.amissah@gmail.com"> +<ralph.amissah@gmail.com> +</a> +</p> +<p class="tiny"> +#{@v.project} #{@v.version} of #{@v.date_stamp} (#{@v.date}) (n*x and Ruby!), #{@date.year_static}. +</p> +<p class="tiny"> +w3 since October 3 1993. +</p> +</body> +</html> +WOK +    end +    def home_toc +      ' ' +    end +  end +end +__END__ +#+END_SRC + +*** html_tune.rb + +#+BEGIN_SRC ruby  :tangle "../lib/sisu/html_tune.rb" +# <<sisu_document_header>> +require_relative 'dp'                                   # dp.rb +module SiSU_HTML_Tune +  require_relative 'se'                                 # se.rb +    include SiSU_Env; include SiSU_Screen +  require_relative 'html_parts'                         # html_parts.rb +  require_relative 'html_format'                        # html_format.rb #watch +  @@line_mode='' +  @@endnote_array=[] +  @@endnote_call_counter=1 +  @@table_align='<table summary='' width="96%" border="0" cellpadding="0" col="3"> +<tr ...><td width="2%" align="right"> + \;</td> +<td width="94%" valign="top" align="justify">' +  @@table_align_close='</td> +<td width="4%" align="right" valign="top"> +<font size="1" color="#777777"> +   </font> </td></tr></table>' +  @@counter,@@column,@columns=0,0,0 +  class Output +    def initialize(data,md) +      @data,@md=data,md +      @file=SiSU_Env::InfoFile.new(@md.fns) +      @cX=SiSU_Screen::Ansi.new(@md.opt.act[:color_state][:set]).cX +    end +    def hard_output +      @filename_tune=@file.write_file_processing.html_tune +      data=[] +      @data.each do |x| +        unless x.obj.empty? +          x.obj=x.obj.strip +          data << x +        end +      end +      data.each do |dob| +        @filename_tune.puts dob, "\n" +      end +    end +    def marshal +      File.open(@file.marshal.html_tune,'w') {|f| Marshal.dump(@data.to_a,f)} +    end +  end +  class CleanHTML +    def initialize(html='') +      @html=html +    end +    def clean_for_html +      html=@html +      str=if html.is_a?(String) +        html +      else html.obj +      end +      str=str.gsub(/#{Mx[:gl_o]}(#[0-9]{3})#{Mx[:gl_c]}/u,'&\1;'). +        gsub(/#{Mx[:gl_o]}#([a-z]{2,4})#{Mx[:gl_c]}/u,'&\1;'). +        gsub(/[<]/m,'<').gsub(/[>]/m,'>') +    end +    def clean +      html=@html +      str=if html.is_a?(String) +        html +      else html.obj +      end +      str=str.gsub(/#{Mx[:gl_o]}(#[0-9]{3})#{Mx[:gl_c]}/u,'&\1;'). +        gsub(/#{Mx[:gl_o]}#([a-z]{2,4})#{Mx[:gl_c]}/u,'&\1;'). +        gsub(/[\\]{2}/m,'<br>') +    end +  end +  class Tune +    include SiSU_Parts_HTML +    def initialize(data,md) +      @data,@md=data,md +      @sys=SiSU_Env::SystemCall.new +      @env=SiSU_Env::InfoEnv.new(@md.fns,@md) +    end +    def songsheet +      begin +        @cX=SiSU_Screen::Ansi.new(@md.opt.act[:color_state][:set]).cX +        if (@md.opt.act[:verbose][:set]==:on \ +        || @md.opt.act[:verbose_plus][:set]==:on \ +        || @md.opt.act[:maintenance][:set]==:on) +          SiSU_Screen::Ansi.new(@md.opt.act[:color_state][:set],'Tune').txt_grey +        end +        songsheet_array(@data) +        #data=songsheet_array(@data) +        if @md.opt.act[:maintenance][:set]==:on #Hard Output Tune Optional on/off here +          SiSU_HTML_Tune::Output.new(@data,@md).hard_output +          SiSU_HTML_Tune::Output.new(@data,@md).marshal +        end +        SiSU_HTML_Tune::Tune.new(@data,@md).output +      rescue +        SiSU_Errors::Rescued.new($!,$@,@md.opt.selections.str,@md.fns).location do +          __LINE__.to_s + ':' + __FILE__ +        end +      ensure +      end +    end +    def songsheet_array(data) +      data_tuned=[] +      data.each do |dob| +        dob=amp_angle_brackets(dob) +        dob=endnotes_html(dob) +        dob=url_markup(dob) +        dob=markup(dob) +        data_tuned << dob +      end +      data_tuned +    end +    def urls(data) +      @words=data.each.map do |word| +        if word=~/#{Mx[:lnk_o]}(.+?)#{Mx[:lnk_c]}(?:#{Mx[:url_o]}\S+?#{Mx[:url_c]}|#{Mx[:rel_o]}\S+?#{Mx[:rel_c]}|image)/ +          http_=true +          if word =~/#{Mx[:lnk_o]}.+?#{Mx[:lnk_c]}#{Mx[:url_o]}\S+?#{Mx[:url_c]}/ +            m,u=/#{Mx[:lnk_o]}(.+?)#{Mx[:lnk_c]}#{Mx[:url_o]}(\S+?)#{Mx[:url_c]}/.match(word).captures +          elsif word =~/#{Mx[:lnk_o]}.+?#{Mx[:lnk_c]}#{Mx[:rel_o]}:\S+?#{Mx[:rel_c]}/ +            #http_=false +            m,u=/#{Mx[:lnk_o]}(.+?)#{Mx[:lnk_c]}#{Mx[:rel_o]}:(\S+?)#{Mx[:rel_c]}/.match(word).captures +            u="#{Xx[:html_relative2]}/" + u +          elsif word =~/#{Mx[:lnk_o]}.+?#{Mx[:lnk_c]}#{Mx[:rel_o]}\S+?#{Mx[:rel_c]}/ +            http_=false +            m,u=/#{Mx[:lnk_o]}(.+?)#{Mx[:lnk_c]}#{Mx[:rel_o]}(\S+?)#{Mx[:rel_c]}/.match(word).captures +          elsif word =~/#{Mx[:lnk_o]}.+?#{Mx[:lnk_c]}image/ +            m,u=/#{Mx[:lnk_o]}(.+?)#{Mx[:lnk_c]}(image)/.match(word).captures +          end +          case m +          when /\.png|\.jpg|\.gif|c=|\s\d+x\d+/ +            w,h=/\s(\d+)x(\d+)/.match(m).captures if m =~/\s\d+x\d+/ +            w=%{width="#{w}"} if w +            h=%{height="#{h}"} if h +            c=m[/"(.+?)"/m,1] +            caption=%{<br><p class="caption">#{c}</p>} if c +            png=m.scan(/\S+/)[0] +            image_path=@md.file.output_path.html_seg.rel_image +            #image_path=(@md.fns =~/\.-ss[tm]$/) \ +            #? @env.url.images_external +            #: @env.url.images_local +            ins=if u \ +            and u.strip !~/^image$/ +              %{<a href="#{u}"><img src="#{image_path}/#{png}" #{w} #{h} naturalsizeflag="0" align="bottom" border="0"></a>#{caption}} +            else %{<img src="#{image_path}/#{png}" #{w} #{h} naturalsizeflag="0" align="bottom" border="0">#{caption}} +            end +            word=word.gsub(/#{Mx[:lnk_o]}.+?#{Mx[:lnk_c]}(?:#{Mx[:url_o]}\S+?#{Mx[:url_c]}|image)/,ins) +          else +            link=m[/(.+)/m] +            png=m.scan(/\S+/)[0].strip +            link=link.strip +            u=u.gsub(/(\S+)/,"#{Xx[:segment]}#\\1") if u !~/\// unless http_ #marker: in scroll remove; in seg replace +            ins=%{<a href="#{u}">#{link}</a>} +            word=word.gsub(/#{Mx[:lnk_o]}.+?#{Mx[:lnk_c]}#{Mx[:url_o]}\S+?#{Mx[:url_c]}/,ins). +              gsub(/#{Mx[:lnk_o]}.+?#{Mx[:lnk_c]}#{Mx[:rel_o]}\S+?#{Mx[:rel_c]}/,ins) +          end +          word +        else word +        end +      end.join(' ') +    end +    def url_markup(dob) +      unless dob.is==:code +        if dob.obj =~/#{Mx[:lnk_o]}.+?#{Mx[:lnk_c]}(?:#{Mx[:url_o]}\S+?#{Mx[:url_c]}|#{Mx[:rel_o]}\S+?#{Mx[:rel_c]}|image)/ +          @word_mode=dob.obj.scan(/#{Mx[:lnk_o]}.+?#{Mx[:lnk_c]}(?:#{Mx[:url_o]}\S+?#{Mx[:url_c]}|#{Mx[:rel_o]}\S+?#{Mx[:rel_c]}|image)[()\[\]]*[,.;:!?'"]{0,2}|(?:#{Mx[:gl_o]}\S+?#{Mx[:gl_c]})+|[^#{Mx[:lnk_o]}#{Mx[:lnk_c]}]+/mu) +          words=urls(@word_mode) +          dob.obj=dob.obj.gsub(/.+/m,words) +        end #consider change, do a while loop +        dob.obj=dob.obj.gsub(/\\copyright/i,%{<sup>©</sup>}) +        if (dob.obj !~/\<:ad\s+\.\.\//) +          dob.obj=dob.obj.gsub(/\<:ad\s+(\S+)?\s+(\S+\.png)\s+(.+)?\;\s+(.+)?\;\s*!\>/, +            %{\n<center><a href="http:\/\/\\1" target="external"><img src="#{@env.url.images_local}/\\2" alt="\\3"></a></center>\n}) +        else +          dob.obj=dob.obj.gsub(/\<:ad\s+(\S+)?\s+(\S+\.png)\s+(.+)?\;\s+(.+)?\;\s*\>/, +            %{\n<center><a href="\\1" target="_top"><img src="#{@env.url.images_local}/\\2" alt="\\3"></a></center>\n}) +        end +        dob.obj=dob.obj.gsub(/!pick/,%{<img border="0" height="15" width="15" src="#{@env.url.images}/#{the_icon.i_choice}" alt="stellar">}). +          gsub(/!new/,%{ <img border="0" height="15" width="15" src="#{@env.url.images}/#{the_icon.i_new}" alt="new">}). +          gsub(/<:h(.{1,7}?)>/,'<a href="#h\1">\1</a>'). +          gsub(/<:to(\d{1,7}?)>/,'<a href="#to\1">to { \1 }</a> '). +          gsub(/#{Mx[:url_o]}_(\S+?)#{Mx[:url_c]}/,'<a href="\1" target="_top">\1</a>'). #http ftp matches escaped, no decoration +          gsub(/#{Mx[:url_o]}([a-zA-Z0-9._-]+\@\S+?\.[a-zA-Z0-9._-]+)#{Mx[:url_c]}/,%{#{the_url_decoration.xml_open}<a href="mailto:\\1">\\1</a>#{the_url_decoration.xml_close}}). +          gsub(/#{Mx[:url_o]}(\S+?)#{Mx[:url_c]}/,%{#{the_url_decoration.xml_open}<a href="\\1" target="_top">\\1</a>#{the_url_decoration.xml_close}}) #http ftp matches with decoration +        if dob.obj =~/#{Xx[:html_relative2]}\/\S+/ \ +        and dob.obj !~/(\"#{Xx[:html_relative2]}\/\S+?\"|>\s*#{Xx[:html_relative2]}\/\S+<)/ +          dob.obj=dob.obj.gsub(/(#{Xx[:html_relative2]}\/\S+)/,'<a href="\1">\1</a>') +        end +        if dob.obj =~/..\/\S+/ \ +        and dob.obj !~/(\"..\/\S+?\"|>\s*..\/\S+<)/ +          dob.obj=dob.obj.gsub(/\.\.(\/\S+)/,%{<a href="#{Xx[:html_relative2]}\1">\1</a>}) +        end +        dob.obj=dob.obj.gsub(/<a href=":/,%{<a href="#{the_url.site}/}). +          gsub(/<a href="\.\.\//,%{<a href="#{the_url.site}/}). +          gsub(/<a href="#{Xx[:html_relative2]}\//,%{<a href="#{the_url.site}/}) +      else +        dob.obj=dob.obj.gsub(/</m,'<').gsub(/>/m,'>') +      end +      dob +    end +    def amp_angle_brackets(dob) +      dob.obj=dob.obj. +        gsub(/&/u,'&'). +        gsub(/<([a-z:\/]+)>/,"#{Dx[:lt_xml]}\\1#{Dx[:gt_xml]}"). +        gsub(/</u,'<').gsub(/>/u,'>') +      dob +    end +    def endnotes_html(dob) +      unless dob.is ==:code +        dob.obj=dob.obj.gsub(/(#{Mx[:en_a_o]}|#{Mx[:en_b_o]})(\d+)\s+(.+?)(#{Mx[:en_a_c]}|#{Mx[:en_b_c]})/, +            %{ <a href="##{Mx[:note]}\\2"><note id="#{Mx[:note_ref]}\\2"> <sup>\\2</sup> </note></a> } + +            %{\\1\\2 <a href="##{Mx[:note_ref]}\\2"><note id="#{Mx[:note]}\\2"> <sup>\\2.</sup></note></a> \\3 \\4}). +          gsub(/(#{Mx[:en_b_o]})([*+]\d+)\s+(.+?)(#{Mx[:en_b_c]})/, +            %{ <a href="##{Mx[:note]}\\2"><note id="#{Mx[:note_ref]}\\2"> <sup>\\2</sup> </note></a> } + +            %{\\1\\2 <a href="##{Mx[:note_ref]}\\2"><note id="#{Mx[:note]}\\2"> <sup>\\2.</sup></note></a> \\3 \\4}). +          gsub(/(#{Mx[:en_a_o]})([*+]+)\s+(.+?)(#{Mx[:en_a_c]})/, +            %{ <a href="##{Mx[:note]}\\2"><note id="#{Mx[:note_ref]}\\2"> <sup>\\2</sup> </note></a> } + +            %{\\1\\2 <a href="##{Mx[:note_ref]}\\2"><note id="#{Mx[:note]}\\2"> <sup>\\2</sup></note></a> \\3 \\4}) +      end +      dob +    end +    def markup(dob) +      dob.obj=dob.obj.gsub(/#{Mx[:mk_o]}#([a-zA-Z]+)#{Mx[:mk_c]}/,'&\1;'). +        gsub(/#{Mx[:mk_o]}(#[0-9]+)#{Mx[:mk_c]}/,'&\1;') +      dob.obj=dob.obj.gsub(/#{Mx[:br_line]}|#{Mx[:br_nl]}/,'<br>') unless dob.is==:table +      dob.obj=dob.obj.gsub(/#{Mx[:fa_bold_o]}(.+?)#{Mx[:fa_bold_c]}/,'<b>\1</b>'). +        gsub(/#{Mx[:fa_italics_o]}(.+?)#{Mx[:fa_italics_c]}/,'<i>\1</i>'). +        gsub(/#{Mx[:fa_underscore_o]}(.+?)#{Mx[:fa_underscore_c]}/,'<u>\1</u>'). +        gsub(/#{Mx[:fa_superscript_o]}(.+?)#{Mx[:fa_superscript_c]}/,'<sup>\1</sup>'). +        gsub(/#{Mx[:fa_subscript_o]}(.+?)#{Mx[:fa_subscript_c]}/,'<sub>\1</sub>'). +        gsub(/#{Mx[:fa_insert_o]}(.+?)#{Mx[:fa_insert_c]}/,'<ins>\1</ins>'). +        gsub(/#{Mx[:fa_cite_o]}(.+?)#{Mx[:fa_cite_c]}/,'<cite>\1</cite>'). +        gsub(/#{Mx[:fa_strike_o]}(.+?)#{Mx[:fa_strike_c]}/,'<del>\1</del>'). +        gsub(/#{Mx[:fa_monospace_o]}(.+?)#{Mx[:fa_monospace_c]}/,'<tt>\1</tt>'). # tt, kbd +        gsub(/#{Mx[:mk_o]}:name#(\S+?)#{Mx[:mk_c]}/,'<a name="\1"></a>'). +        gsub(/#{Mx[:gl_bullet]}/m,'●  '). +        gsub(/#{Mx[:nbsp]}/,' '). +        gsub(/<(p|br) \/>/,'<\1>') +      dob=SiSU_HTML_Tune::CleanHTML.new(dob).clean +      dob +    end +    def output +      data=@data +      @tuned_file=data.each.map do |dob| +        dob.obj=dob.obj.strip.chomp +        dob +      end +      @tuned_file << "\n<EOF>" if (@md.fns =~/\.sst0/) #remove +      @tuned_file +    end +  end +end +__END__ +#+END_SRC + +*** html_scroll.rb + +#+BEGIN_SRC ruby  :tangle "../lib/sisu/html_scroll.rb" +# <<sisu_document_header>> +module SiSU_HTML_Scroll +  require_relative 'html_shared'                        # html_shared.rb +  require_relative 'html'                               # html.rb +  require_relative 'shared_metadata'                    # shared_metadata.rb +  require_relative 'html_promo'                         # html_promo.rb +  class Scroll +    def initialize(md='',data='',endnotes='') +      @md,@data,@endnotes=md,data,endnotes +    end +    def songsheet +      begin +        scr=SiSU_HTML_Scroll::Scroll.new(@md,@data,@endnotes).markup +        scr[:tails]=SiSU_HTML_Scroll::Scroll.new(@md).tails +        scr +      rescue +        SiSU_Errors::Rescued.new($!,$@,@md.opt.selections.str,@md.fns).location do +          __LINE__.to_s + ':' + __FILE__ +        end +      ensure +      end +    end +  protected +    def markup +      data=@data +      @rcdc=false +      @scr={ body: [], metadata: [], owner_details: [] } +      data.each do |dob| +        dob.obj=dob.obj.gsub(/#{@md.file.output_path.html_seg.rel_image}/m, +          @md.file.output_path.html_scroll.rel_image) +        if defined? dob.name and dob.name =~/^meta/ \ +        and dob.obj =~/Document Information/ +          dob.obj=dob.obj. +            gsub(/(Document Information(?: \(metadata\))?)/, +              '\1<a name="docinfo"></a>') +        end +        if dob.obj =~/^Metadata$/ \ +        and dob.lv =='B' +          dob.obj=dob.obj.gsub(/Metadata/,'') #dob.obj='' +        end +        if defined? dob.name \ +        and dob.name =~/^metadata/ \ +        and dob.lv =='1' \ +        and dob.obj =~/SiSU Metadata, document information/ +          @rcdc=true +        end +        dob.obj=dob.obj.gsub(/href="[a-z0-9._-]+(#\S+?")/m,'href="\1'). # internal document links +          gsub(/href="#{Xx[:segment]}/m,'href="') +        if dob.obj !~/(^#{Rx[:meta]}|#{Mx[:br_eof]})/ +          unless dob.is ==:code +            dob.obj=dob.obj. +              gsub(/(?:#{Mx[:en_a_o]}.+?#{Mx[:en_a_c]}|#{Mx[:en_b_o]}.+?#{Mx[:en_b_c]})\s*/m,' ') +          end +          if defined? dob.ocn +            @p_num=SiSU_HTML_Format::ParagraphNumber.new(@md,dob.ocn) +          end +          sto=SiSU_HTML_Format::FormatTextObject.new(@md,dob) +          para_html=if dob.is==:heading +            x=if dob.ln==0 +              sto.heading_body0 +            elsif dob.ln==1 +              sto.heading_body1 +            elsif dob.ln==2 +              sto.heading_body2 +            elsif dob.ln==3 +              sto.heading_body3 +            elsif dob.ln==4 +              sto.heading_body4 +            elsif dob.ln==5 +              sto.heading_body5 +            elsif dob.ln==6 +              sto.heading_body6 +            elsif dob.ln==7 +              sto.heading_body7 +            end +          elsif dob.is==:break \ +          and dob.from==:markup +            '<br><hr width=90% /><br>' +          elsif dob.is==:heading_insert +            x=if dob.ln==0 +              unless dob.obj.empty? +                sto.heading_body0 +              end +            elsif dob.ln==1 +              unless dob.obj.empty? +                sto.heading_body1 +              end +            elsif dob.ln==2 +              unless dob.obj.empty? +                sto.heading_body2 +              end +            elsif dob.ln==3 +              unless dob.obj.empty? +                sto.heading_body3 +              end +            elsif dob.ln==4 \ +            and dob.obj !~/^(?:Endnotes|Index|Metadata|Manifest)$/ +              unless dob.obj.empty? +                sto.heading_body4 +              end +            elsif dob.ln==4 \ +            and dob.obj=='Endnotes' +              sto.heading_body4 +              @endnotes.join("\n") +            elsif dob.ln==4 \ +            and dob.obj=='Index' +              sto.heading_body4 +              book_idx=SiSU_Particulars::CombinedSingleton. +                instance.get_idx_html(@md.opt).html_idx +              book_idx.each do |y| #takes book index prepared for segments & strips segment identifying info +                y.gsub!(/<a href="\S+?\.html#(\d+)">(\1(?:-\d+)?)<\/a>/, +                  '<a href="#\1">\2</a>') +              end +              book_idx.join("\n") +            elsif dob.ln==5 +              unless dob.obj.empty? +                sto.heading_body5 +              end +            elsif dob.ln==6 +              unless dob.obj.empty? +                sto.heading_body6 +              end +            elsif dob.ln==7 +              unless dob.obj.empty? +                sto.heading_body7 +              end +            end +          elsif dob.is==:para +            if dob.indent \ +            and dob.hang \ +            and dob.indent =~/[0-9]/ \ +            and dob.hang =~/[0-9]/ +              if dob.bullet_ +                (dob.indent =~/[1-9]/) \ +                ? sto.format('li',"i#{dob.indent}") +                : sto.format('li','bullet') +              elsif dob.indent == dob.hang +                sto.format('p',"i#{dob.indent}") +              elsif dob.indent != dob.hang +                sto.format('p',"h#{dob.hang}i#{dob.indent}") +              else sto.para +              end +            else sto.para +            end +          elsif dob.is==:block +            sto.block +          elsif dob.is==:group +            sto.group +          elsif dob.is==:alt +            sto.alt +          elsif dob.is==:verse +            sto.verse +          elsif dob.is==:code +            sto.code +          elsif dob.is==:table +            sto.table +          elsif dob.is==:break +          end +          if dob.obj =~/<a name="n\d+">/ \ +          and dob.obj =~/^(?:\^~\d+\s|<!e[:_]\d+!>)/ # hmmm re-adjusted 200507, for alt endnote which should again be matched ^~ ... not in response to problem though +            dob.obj='' +          end +          unless @rcdc +            @scr[:body] << para_html unless para_html =~/\A\s*\Z/ +          end +        end +      end +      @scr +    end +    def tails +      scr_tail=[] +      format_head_scroll=SiSU_HTML_Format::HeadToc.new(@md) +      scr_tail \ +      << format_head_scroll.scroll_tail \ +      << format_head_scroll.html_close +      scr_tail +    end +  end +end +__END__ +#+END_SRC + +*** html_segments.rb + +#+BEGIN_SRC ruby  :tangle "../lib/sisu/html_segments.rb" +# <<sisu_document_header>> +module SiSU_HTML_Seg +  require_relative 'html_shared'                        # html_shared.rb +  require_relative 'html'                               # html.rb +  require_relative 'html_persist'                       # html_persist.rb +  require_relative 'html_promo'                         # html_promo.rb +  require_relative 'shared_metadata'                    # shared_metadata.rb +  class Output +    def initialize(md,outputfile,per,minitoc,type='') +      @md, @output_seg_file,@per,@minitoc,@type= +        md,outputfile,      per,minitoc,  type +      @title_banner_=SiSU_Env::CreateSite.new(@md.opt).html_seg_title_banner? +      @file=SiSU_Env::FileOp.new(@md) +      @make=SiSU_Env::ProcessingSettings.new(@md) +      @cl=(@make.build.html_minitoc?) \ +      ? 'content' +      : 'content0' +    end +    def output +      if @per.title =~/\S/ +        filename_seg=[] +        if @make.build.html_top_band? +          filename_seg \ +          << @per.title \ +          << @per.tocband_banner +        else +          filename_seg \ +          << @per.title +        end +        if @type=='endnotes' +          @per.headings=[] +          format_head_seg=SiSU_HTML_Format::HeadSeg.new(@md) +          if @title_banner_ +            @per.headings \ +            << format_head_seg. +              title_banner(@md.title.main,@md.title.sub,@author) +          end +          txt_obj={ txt: 'Endnotes', ocn_display: '' } +          format_seg=SiSU_HTML_Format::FormatSeg.new(@md,txt_obj) +          @per.headings \ +          << format_seg.title_heading1 +          filename_seg \ +          << @per.heading_endnotes \ +          << @minitoc << @per.headings \ +          << %{\n<div class="#{@cl}">\n} \ +          << @per.endnote_all \ +          << '</div>' # << '</div>' +        elsif @type=='idx' +          @per.headings=[] +          format_head_seg=SiSU_HTML_Format::HeadSeg.new(@md) +          if @title_banner_ +            @per.headings \ +            << format_head_seg. +              title_banner(@md.title.main,@md.title.sub,@author) +          end +          txt_obj={ txt: 'Index', ocn_display: '' } +          format_seg=SiSU_HTML_Format::FormatSeg.new(@md,txt_obj) +          @per.headings << format_seg.title_heading1 +          filename_seg \ +          << @per.heading_idx \ +          << @minitoc << @per.headings \ +          << %{\n<div class="#{@cl}">\n} \ +          << @per.idx \ +          << '</div>' # << '</div>' +        elsif @type=='metadata' +          metadata=SiSU_Metadata::Summary.new(@md).html_display.metadata +          @per.headings=[] +          format_head_seg=SiSU_HTML_Format::HeadSeg.new(@md) +          if @title_banner_ +            @per.headings \ +            << format_head_seg. +              title_banner(@md.title.main,@md.title.sub,@author) +          end +          txt_obj={ txt: 'Metadata', ocn_display: '' } +          format_seg=SiSU_HTML_Format::FormatSeg.new(@md,txt_obj) +          @per.headings \ +          << format_seg.title_heading1 +          filename_seg \ +          << @per.heading_idx \ +          << @minitoc \ +          << @per.headings \ +          << %{\n<div class="#{@cl}">\n} \ +          << metadata \ +          << '</div>' # << '</div>' +        else +          if @make.build.html_top_band? +            filename_seg \ +            << @minitoc \ +            << @per.headings \ +            << @per.main \ +            << "\n</div>\n" +          else +            filename_seg \ +            << @minitoc \ +            << @per.main \ +            << "\n</div>\n" +          end +        end +        filename_seg <<=if @make.build.html_top_band? +          @per.tail \ +          << @per.tocband_bannerless \ +          << @per.credits +        else +          @per.tail \ +          << @per.credits +        end +        filename_seg=filename_seg.flatten.compact #watch +        filename_seg.each do |str| +          unless str =~/\A\s*\Z/ +            str=str.strip. +              gsub(Xx[:html_relative2], +                @file.path_rel_links.html_seg_2). +              gsub(Xx[:html_relative1], +                @file.path_rel_links.html_seg_1) +            @output_seg_file << str +          end +        end +        @output_seg_file.close +      end +    end +  end +  class Seg +    @@seg_url='' +    @@tracker=0 +    @@seg_name=[] +    attr_reader :seg_name_x,:seg_name_x_tracker +    def initialize(md=nil,data='') +      @md,@data=md,data +      @per=SiSU_HTML_Persist::Persist.new +      @seg_name_x=@per.seg_name_x=(@@seg_name || []) +      @seg_name_x_tracker=@per.seg_name_x_tracker=(@@tracker || 0) +      @env=SiSU_Env::InfoEnv.new(@md.fns) if @md +      if @md +        @make=SiSU_Env::ProcessingSettings.new(@md) +        @cl=(@make.build.html_minitoc?) \ +        ? 'content' +        : 'content0' +      else @cl='content' +      end +      if @md +        @title_banner_=SiSU_Env::CreateSite.new(@md.opt).html_seg_title_banner? +      end +    end +    def songsheet +      begin +        @minitoc=SiSU_HTML::Source::Toc.new(@md,@data).minitoc +        @per=SiSU_HTML_Persist::Persist.new +        data=get_subtoc_endnotes(@data,@per) +        data=articles(data,@per) +        cleanup(@md,@per) # (((( added )))) +        #### (((( END )))) #### +      rescue +        SiSU_Errors::Rescued.new($!,$@,@md.opt.selections.str,@md.fns).location do +          __LINE__.to_s + ':' + __FILE__ +        end +      ensure +        SiSU_HTML_Persist::Persist.new.persist_init +        @@seg_name=@per.seg_name=[] +      end +    end +  protected +    def articles(data,per) +      @per=per +      tracking,newfile=0,0 +      printed_endnote_seg='n' +      idx_html=nil +      if @md.book_idx +        #my_make_source_file=SiSU_Env::CreateFile.new(@md.fns) +        idx_html=SiSU_Particulars::CombinedSingleton. +          instance.get_idx_html(@md.opt).html_idx +        idx_html.each do |x| +          @per.idx << x +        end +        @per.heading_idx='' +      end +      data.each do |dob| +        if (dob.is == :heading \ +        || dob.is == :heading_insert) \ +        && dob.ln == 4 +          @@seg_name << dob.name +          @per.seg_name = @@seg_name +          dob.name +        end +      end +      @per.seg_name_x=@per.seg_name +      @per.seg_name.length +      testforartnum=@per.seg_name_x +      if (@md.opt.act[:verbose][:set]==:on \ +      || @md.opt.act[:verbose_plus][:set]==:on \ +      || @md.opt.act[:maintenance][:set]==:on) +        SiSU_Screen::Ansi.new( +          @md.opt.act[:color_state][:set], +          @per.seg_name.length +        ).segmented +      end +      map_nametags=SiSU_Particulars::CombinedSingleton. +        instance.get_map_nametags(@md).nametags_map #p map_nametags +      data.each do |dob| +        if defined? dob.obj \ +        and dob.obj =~/href="#{Xx[:segment]}#+\S+?"/ +          while dob.obj =~/href="#{Xx[:segment]}#+(\S+?)"/ +            m=$1 +            if map_nametags[m] \ +            and map_nametags[m][:segname] +              inf=SiSU_Env::FileOp.new(@md) if @md +              lng=(inf.output_dir_structure.by_language_code?) \ +              ? '' +              : '.' + @md.opt.lng +              dob.obj.sub!(/href="#{Xx[:segment]}#+(\S+?)"/, +                %{href="#{map_nametags[m][:segname]}#{lng}#{Sfx[:html]}#\\1"}) +            else +              p "NOT FOUND name_tags: #{m}" +              dob.obj.sub!(/href="#{Xx[:segment]}#+(\S+?)"/, +                %{href="#\\1"}) # not satisfactory +            end +          end +        end +        if (dob.is==:heading \ +        || dob.is==:heading_insert) \ +        && dob.ln==4 +          @per.heading4=dob.obj +          @per.is4=newfile=1 +        end +        if (dob.is==:heading \ +        || dob.is==:heading_insert) \ +        && dob.ln==3 +          @per.heading3=dob.obj +          @per.is4,@per.is3=0,1 +        end +        if (dob.is==:heading \ +        || dob.is==:heading_insert) \ +        && dob.ln==2 +          @per.heading2=dob.obj +          @per.is4,@per.is3,@per.is2=0,0,1 +        end +        if (dob.is==:heading \ +        || dob.is==:heading_insert) \ +        && dob.ln==1 +          @per.heading1=dob.obj +          @per.is4,@per.is3,@per.is2,@per.is1=0,0,0,1 +        end +        if (dob.is==:heading \ +        || dob.is==:heading_insert) \ +        && dob.ln==0 +          @per.heading0=dob.obj +          @per.is4,@per.is3,@per.is2,@per.is1,@per.is0=0,0,0,0,1 +        end +        if (@per.is1 && !@per.is2 && !@per.is3 && !@per.is4) +          if not (dob.is==:heading \ +          || dob.is==:heading_insert) \ +          && dob.ln==0 +            $_ #; check +          end +        end +        if @per.is4==1 +          if newfile==1 \ +          or dob.obj =~/^#{Mx[:br_endnotes]}|^#{Mx[:br_eof]}/ +            newfile=0 +            if (dob.is==:heading \ +            || dob.is==:heading_insert) \ +            && dob.ln==4 +              if tracking != 0 +                @file=SiSU_Env::FileOp.new(@md) +                unless FileTest.directory?(@file.output_path.html_seg.dir) +                  FileUtils::mkdir_p(@file.output_path.html_seg.dir) \ +                    if File.writable?("#{@file.output_path.base.dir}/.") +                end +                tail(@md,@per) +                #SiSU_HTML_Seg::Seg.new(@md,@per).tail +                fnh={ +                  fn: @per.seg_name_x[tracking-1], +                } +                fn=@md.file.base_filename.html_seg(fnh) +                segfilename="#{@file.output_path.html_seg.dir}/#{fn}" +                output_seg_file=File.new(segfilename,'w') if @per.seg_name_x[tracking-1] +                minitoc=(@make.build.html_minitoc?) ? @minitoc : '' +                if dob.is==:heading \ +                || (@per.seg_name_x[tracking-1] !~/endnotes|book_index|metadata/) +                  SiSU_HTML_Seg::Output.new(@md,output_seg_file,@per,minitoc).output +                elsif dob.is==:heading_insert +                  if @per.seg_name_x[tracking-1]=='endnotes' +                    SiSU_HTML_Seg::Output.new(@md,output_seg_file,@per,minitoc,'endnotes').output +                  elsif @per.seg_name_x[tracking-1]=='book_index' +                    SiSU_HTML_Seg::Output.new(@md,output_seg_file,@per,minitoc,'idx').output +                    @per.idx=[] +                  elsif @per.seg_name_x[tracking-1]=='metadata' +                    SiSU_HTML_Seg::Output.new(@md,output_seg_file,@per,minitoc,'metadata').output +                  else puts "#{__FILE__}::#{__LINE__}" +                  end +                else puts "#{__FILE__}::#{__LINE__}" +                end +                SiSU_HTML_Seg::Seg.new.reinitialise(per) +                #per=persist_init +                heading_art(dob) +                head(dob) +               #keep use for last segment, eg if metadata is last segment +                if @per.seg_name_x[tracking] =='metadata' # this is for metadata +                  fnh={ +                    fn: @per.seg_name_x[tracking], +                  } +                  fn=@md.file.base_filename.html_seg(fnh) +                  segfilename="#{@file.output_path.html_seg.dir}/#{fn}" +                  output_seg_file=File.new(segfilename,'w') +                  SiSU_HTML_Seg::Output.new(@md,output_seg_file,@per,minitoc,'metadata').output +                  #per=persist_init +                  Seg.new.reinitialise(per) +                end +              end +              if tracking==0 +                heading_art(dob) +                head(dob) +              end +            end +            tracking=tracking+1 +          end +          if (dob.is==:heading \ +          || dob.is==:heading_insert) \ +          && dob.ln==4 \ +          && dob.name +            @per.get_hash_to=dob.name +            @per.get_hash_fn=dob.name +          end +          if dob.obj.is_a?(String) +            markup(dob) +          elsif dob.obj.is_a?(Array) +            dob.obj.each do |pg| +              markup(pg) +            end +          end +          if testforartnum[tracking-1] =~/endnote/ +            if printed_endnote_seg=='n' +              printed_endnote_seg='y' +            end +          end +        end +      end +      data +    end +    def heading_art(dob) +      format_head_seg=SiSU_HTML_Format::HeadSeg.new(@md) +      @per.dot_nav=if (@make.build.html_navigation?) \ +      && (@make.build.html_navigation_bar?) +        x=if (dob.is==:heading \ +        || dob.is==:heading_insert) \ +        && (dob.ln.to_s =~/^[0-7]/) +          x=if @@tracker < @per.seg_name.length-1 +            format_head_seg.dot_control_pre_next +          else +            format_head_seg.dot_control_pre +          end +        else @per.dot_nav +        end +      else @per.dot_nav='' +      end +      ads=SiSU_HTML_Promo::Ad.new(@md) +      @per.title=format_head_seg.head_seg << ads.div.major +    end +    def head(dob) +      clean=/<!.*?!>|<:.*?>/ +      format_head_seg=SiSU_HTML_Format::HeadSeg.new(@md) +      if @make.build.html_navigation? +        if @@tracker < @per.seg_name.length-1 +          @per.segtocband=if @@tracker==0 +            format_head_seg.toc_next2 +          else +            format_head_seg.toc_pre_next2 +          end +        else @per.segtocband=format_head_seg.toc_pre2 +        end +      else @per.segtocband='' +      end +      @p_num ||= '' +      if @per.is0==1 +        @author=%{<b>#{@md.author}</b>\n} if @md.author.to_s =~/\S/ +        @per.tocband_banner \ +        << format_head_seg.navigation_band(@per.segtocband,@per.dot_nav) +        @per.tocband_bannerless \ +        << '<br>' \ +        << format_head_seg.navigation_band_bottom(@per.segtocband,@per.dot_nav) +        if @title_banner_ +          @per.headings \ +          << format_head_seg.title_banner(@md.title.main,@md.title.sub,@author).gsub(clean,'') +        end +        ocn=(@per.heading0[/.+?#{Mx[:id_o]}~(\d+);(?:[oh]|[0-6]:)\d+;\w\d+#{Mx[:id_c]}#{Mx[:id_o]}#{@dp}:#{@dp}#{Mx[:id_c]}$/]) \ +        ? $1 +        : '' +        @p_num=SiSU_HTML_Format::ParagraphNumber.new(@md,ocn) +        txt_obj={ txt: @per.heading0, ocn_display: @p_num.ocn_display } +        format_seg=SiSU_HTML_Format::FormatSeg.new(@md,txt_obj) +        @per.headings \ +        << format_seg.title_heading0.gsub(clean,'') +        @per.heading0=@per.heading0. +          gsub(/ <a name="-[\d*+]+" href="#_[\d*+]+"> <sup>[\d*+]+<\/sup> <\/a>/,'') +      end +      if @per.is1==1 +        heading1=@per.heading1 +        ocn=(heading1[/.+?#{Mx[:id_o]}~(\d+);(?:[oh]|[0-6]:)\d+;\w\d+#{Mx[:id_c]}#{Mx[:id_o]}#{@dp}:#{@dp}#{Mx[:id_c]}$/]) \ +        ? $1 +        : '' +        @p_num=SiSU_HTML_Format::ParagraphNumber.new(@md,ocn) +        txt_obj={ txt: heading1, ocn_display: @p_num.ocn_display } +        format_seg=SiSU_HTML_Format::FormatSeg.new(@md,txt_obj) +        @per.headings \ +        << format_seg.title_heading1.gsub(clean,'') +        @per.heading1=@per.heading1. +          gsub(/ <a name="-[\d*+]+" href="#_[\d*+]+"> <sup>[\d*+]+<\/sup> <\/a>/,'') +      end +      if @per.is2==1 +        heading2=@per.heading2 +        ocn=(heading2[/.+?#{Mx[:id_o]}~(\d+);(?:[oh]|[0-6]:)\d+;\w\d+#{Mx[:id_c]}#{Mx[:id_o]}#{@dp}:#{@dp}#{Mx[:id_c]}$/]) \ +        ? $1 +        : '' +        @p_num=SiSU_HTML_Format::ParagraphNumber.new(@md,ocn) +        txt_obj={ txt: heading2, ocn_display: @p_num.ocn_display } +        format_seg=SiSU_HTML_Format::FormatSeg.new(@md,txt_obj) +        @per.headings \ +        << format_seg.title_heading2.gsub(clean,'') +        @per.heading2=@per.heading2. +          gsub(/ <a name="-[\d*+]+" href="#_[\d*+]+"> <sup>[\d*+]+<\/sup> <\/a>/,'') +      end +      if @per.is3==1 +        heading3=@per.heading3 +        ocn=(heading3[/.+?#{Mx[:id_o]}~(\d+);(?:[oh]|[0-6]:)\d+;\w\d+#{Mx[:id_c]}#{Mx[:id_o]}#{@dp}:#{@dp}#{Mx[:id_c]}$/]) \ +        ? $1 +        : '' +        @p_num=SiSU_HTML_Format::ParagraphNumber.new(@md,ocn) +        txt_obj={ txt: heading3, ocn_display: @p_num.ocn_display } +        format_seg=SiSU_HTML_Format::FormatSeg.new(@md,txt_obj) +        @per.headings \ +        << format_seg.title_heading3.gsub(clean,'') +        @per.heading3=@per.heading3. +          gsub(/ <a name="-[\d*+]+" href="#_[\d*+]+"> <sup>[\d*+]+<\/sup> <\/a>/,'') +      end +      if @per.is4==1 +        heading4=@per.heading4 +        ocn=(heading4[/.+?#{Mx[:id_o]}~(\d+);(?:[oh]|[0-6]:)\d+;\w\d+#{Mx[:id_c]}#{Mx[:id_o]}#{@dp}:#{@dp}#{Mx[:id_c]}$/]) \ +        ? $1 +        : '' +        @p_num=SiSU_HTML_Format::ParagraphNumber.new(@md,ocn) +        txt_obj={ txt: heading4, ocn_display: @p_num.ocn_display } +        format_seg=SiSU_HTML_Format::FormatSeg.new(@md,txt_obj) +        @per.headings \ +        << format_seg.title_heading4.gsub(clean,'') +      end +      @@tracker=@@tracker+1 +    end +    def markup(dob) +      @debug=[] +      SiSU_HTML_Format::HeadSeg.new(@md) +      if dob.is !=:meta +        if dob.is==:heading \ +        || dob.is==:heading_insert \ +        || dob.is == :para +          @p_num=SiSU_HTML_Format::ParagraphNumber.new(@md,dob.ocn) +        end +        sto=SiSU_HTML_Format::FormatTextObject.new(@md,dob) +        dob_html=if dob.is == :heading \ +        || dob.is==:heading_insert \ +        || dob.is==:para +          dob_html=if dob.is==:heading \ +          || dob.is==:heading_insert +            if dob.ln==4 +              sto.seg_heading4 +            elsif dob.ln==5 +              sto.seg_heading5 +            elsif dob.ln==6 +              sto.seg_heading6 +            elsif dob.ln==7 +              sto.seg_heading6 +            end +          elsif dob.is==:para +            if dob.indent \ +            and dob.hang \ +            and dob.indent =~/[0-9]/ \ +            and dob.hang =~/[0-9]/ +              if dob.bullet_ +                if dob.indent =~/[1-9]/ +                  sto.format('li',"i#{dob.indent}") +                else +                  sto.format('li','bullet') +                end +              elsif dob.indent == dob.hang +                sto.format('p',"i#{dob.indent}") +              elsif dob.indent != dob.hang +                sto.format('p',"h#{dob.hang}i#{dob.indent}") +              else sto.para +              end +            else sto.para +            end +          end +        elsif dob.is==:block +          sto.block +        elsif dob.is==:group +          sto.group +        elsif dob.is==:alt +          sto.alt +        elsif dob.is==:verse +          sto.verse +        elsif dob.is==:code +          sto.code +        elsif dob.is==:table +          sto.table +        elsif dob.is==:break \ +        and dob.from==:markup +          '<br><hr width=90% /><br>' +        end +        if @md.flag_separate_endnotes +          dob.obj=dob.obj.gsub(/"\s+href="#(#{Mx[:note]}\d+)">/,%{" href=\"endnotes#{Sfx[:html]}#\\1">})       #endnote- twice #removed file type +        end +        if (dob.is==:heading \ +        || dob.is==:heading_insert \ +        || dob.is==:para) \ +        && (not dob.ocn \ +        || (dob.ocn.to_s.empty?)) +          format_seg=SiSU_HTML_Format::FormatSeg.new(@md,dob) +        end +        dob.obj=dob.obj.gsub(/\s*(-\{{2}~\d+|<:e[:_]\d+>).*/,'')                   #potentially dagerous - removes all paragraphs with <!e_!> #?? workpoint +        if dob.obj =~/<a name="_\d+" href="#-\d+"> <sup>/                #endnote- note- +          format_seg=SiSU_HTML_Format::FormatSeg.new(@md,dob) +          dob=format_seg.no_paranum +        end +        if (dob.is==:heading \ +        || dob.is==:heading_insert) \ +        && dob.ln==4 +          @per.main << %{\n<div class="#{@cl}">\n} +          @per.main << dob_html +          if @make.build.segsubtoc? +            @per.main << @per.seg_subtoc[@per.get_hash_fn]                       #% insertion of sub-toc +          end +        else +          @per.main << dob_html #unless @@flag_alt==true +        end +      end +    end +    def tail(md,per) +      @md,@per=md,per +      format_head_seg=SiSU_HTML_Format::HeadSeg.new(@md) +      if @md.flag_auto_endnotes \ +      and @per.seg_endnotes[@per.get_hash_fn] +        @per.tail <<  %{\n<div class="#{@cl}">\n<div class="endnote">\n} +        if @per.seg_endnotes[@per.get_hash_fn].flatten.length > 0 +          @per.tail << format_head_seg.endnote_mark +          @per.tail << @per.seg_endnotes[@per.get_hash_fn].flatten #endnotes deposited at end of individual segments ||@|EXTRACTION OF ENDNOTES| +        end +        @per.tail << '</div>' +        @per.tail << '</div>' #this div closes div class content +      end +      ads=SiSU_HTML_Promo::Ad.new(@md) +      @per.credits \ +      << format_head_seg.credit \ +      << ads.div.close \ +      << ads.display \ +      << format_head_seg.html_close +    end +    def reinitialise(per) +      per.title,per.dot_nav,per.tocband_banner,per.tocband_bannerless,per.headings,per.main,per.tail,per.credits=Array.new(8){[]} +      @per.segtocband=nil +    end +    def cleanup(md,per) +      #per=persist_init +      reinitialise(per) +      @@tracker=0 +      @per.seg_endnotes,@per.seg_subtoc={},{} +      @per.seg_endnotes_array,@per.seg_subtoc_array=[],[] +      per.endnote_all=[] +    end +    def get_subtoc_endnotes(data,per) #get endnotes & sub-table of contents subtoc +      @per=per +      data.each do |dob| +        dob.obj=dob.obj.gsub(/<a name=\"h\d.*?\">(.+?)<\/a>/mi,'\1') +        if @md.flag_auto_endnotes +          if (dob.is==:heading \ +          || dob.is==:heading_insert) \ +          && (dob.ln.to_s =~/^[0-4]/) \ +          and not @per.fn.to_s.empty? +            @per.seg_endnotes[@per.fn]=[] +            @per.seg_endnotes[@per.fn] << @per.seg_endnotes_array +            @per.seg_endnotes_array=[] if dob.ln==4 +          end +          if (dob.is==:heading \ +          || dob.is==:heading_insert) \ +          && dob.ln==4                                              #%  EXTRACTION OF SUB-TOCs & SEGMENT NAME, after EXTRACTION OF ENDNOTES & SUB-TOCs +            @per.seg_subtoc[@per.fn]=@per.seg_subtoc_array +            @per.seg_subtoc_array=[] +            if dob.name \ +            and dob.obj +              @per.fn=dob.name +            else +              if dob.name =~/\S+/ +                @per.fn=dob.name +              else @per.fn='' +              end +            end +          end +        end +        if dob.is==:heading \ +        && (dob.ln.to_s =~/^[5-7]/) +          case dob.ln +          when 5 +            txt_obj={ txt: dob.obj.strip, ocn: dob.ocn } +            format_seg=SiSU_HTML_Format::FormatSeg.new(@md,txt_obj) +            subtoc=format_seg.subtoc_lev5 #keep and make available, this is the subtoc +          when 6 +            txt_obj={ txt: dob.obj.strip, ocn: dob.ocn } +            format_seg=SiSU_HTML_Format::FormatSeg.new(@md,txt_obj) +            subtoc=format_seg.subtoc_lev6 #keep and make available, this is the subtoc +          when 7 +            txt_obj={ txt: dob.obj.strip, ocn: dob.ocn } +            format_seg=SiSU_HTML_Format::FormatSeg.new(@md,txt_obj) +            subtoc=format_seg.subtoc_lev7 #keep and make available, this is the subtoc +          end +          @per.seg_subtoc_array << subtoc +        end +        if @md.flag_auto_endnotes +          if (dob.obj =~/(?:#{Mx[:en_a_o]}|#{Mx[:en_b_o]})[\d*+]+\s*<a href="##{Mx[:note_ref]}[\d*+]+"/) \ +          && dob.is !=:code # endnote- +            endnote_array=[] +            if dob.obj=~/#{Mx[:en_a_o]}.+?#{Mx[:en_a_c]}/m +              endnote_array << dob.obj.scan(/#{Mx[:en_a_o]}.+?#{Mx[:en_a_c]}/m) +            end +            if dob.obj=~/#{Mx[:en_b_o]}[*]\d+\s.+?#{Mx[:en_b_c]}/m +              endnote_array \ +              << dob.obj.scan(/#{Mx[:en_b_o]}[*]\d+\s.+?#{Mx[:en_b_c]}/m) +            end +            if dob.obj=~/#{Mx[:en_b_o]}[+]\d+\s.+?#{Mx[:en_b_c]}/m +              endnote_array \ +              << dob.obj.scan(/#{Mx[:en_b_o]}[+]\d+\s.+?#{Mx[:en_b_c]}/m) +            end +            endnote_array=endnote_array.flatten.compact #watch, check compacting +            endnote_array.each do |note| +              note_match=note.dup +              note_match_seg=note.dup +              e_n=note_match_seg[/(?:#{Mx[:en_a_o]}[\d*+]+|#{Mx[:en_b_o]}[*+]\d+)\s+(.+?)(?:#{Mx[:en_a_c]}|#{Mx[:en_b_c]})/m,1] +              try=e_n.split(/<br(?: \/)?>/) +              try.each do |e| +                txt_obj={ txt: e } +                format_seg=SiSU_HTML_Format::FormatSeg.new(@md,txt_obj) +                note_match=if e =~/#{Mx[:pa_o]}i[1-9]#{Mx[:pa_c]}/ +                  format_seg.endnote_body_indent +                else format_seg.endnote_body +                end +                @per.seg_endnotes_array << note_match +              end +              try.join('<br>') +              #% creation of separate end segment/page of all endnotes referenced back to reference segment +              m=/(?:#{Mx[:en_a_o]}[\d*+]+|#{Mx[:en_b_o]}[*+]\d+)\s+(.+?href=")(##{Mx[:note_ref]}[\d*+]+".+)(?:#{Mx[:en_a_c]}|#{Mx[:en_b_c]})/mi +              endnote_part_a=note_match_seg[m,1] +              endnote_part_b=note_match_seg[m,2] +              txt_obj={ endnote_part_a: endnote_part_a, endnote_part_b: endnote_part_b } +              format_seg=SiSU_HTML_Format::FormatSeg.new(@md,txt_obj) +              note_match_all_seg=format_seg.endnote_seg_body(@per.fn) #BUG WATCH 200408 +              @per.endnote_all << note_match_all_seg +            end +            dob.obj=dob.obj.gsub(/(?:#{Mx[:en_a_o]}.+?#{Mx[:en_a_c]}|#{Mx[:en_b_o]}.+?#{Mx[:en_b_c]})\s*/m,' ') +          end +        end +      end +    end +  end +end +__END__ +#+END_SRC + +*** html_format.rb + +#+BEGIN_SRC ruby  :tangle "../lib/sisu/html_format.rb" +# <<sisu_document_header>> +module SiSU_HTML_Format +  require_relative 'html_parts'                         # html_parts.rb +  class ParagraphNumber +    def initialize(md,ocn) +      @md,@ocn=md,ocn.to_s +      @ocn ||='' +      @make=SiSU_Env::ProcessingSettings.new(@md) +    end +    def ocn_display +      if @make.build.ocn? +        if @ocn.to_i==0 \ +        or @ocn.empty? +          '' +        else +          %{<label class="ocn"><a href="##{@ocn}" class="lnkocn">#{@ocn}</a></label>} +        end +      else +        '' +      end +    end +    def name +      if @make.build.html_strict? \ +      or @ocn==(nil || @ocn.empty?) +        '' +      else +        %{<a name="#{@ocn}"></a>} +      end +    end +    def id #w3c? "tidy" complains about numbers as identifiers ! annoying +      (@ocn==nil || @ocn.empty?) \ +      ? '' : %{id="#{Mx[:ocn_id_char]}#{@ocn}"} +    end +    def goto +      (@ocn==nil || @ocn.empty?) \ +      ? '' : %{<a href="##{@ocn}">} +    end +  end +  class HeadInformation +    require_relative 'css'                              # css.rb +    include SiSU_Parts_HTML +    require_relative 'xml_shared'                       # xml_shared.rb +    attr_reader :md,:rdf +    def initialize(md) +      @md=md +      # DublinCore 1 - title +      @bits=SiSU_Proj_HTML::Bits.new +      @per=SiSU_HTML_Persist::Persist.new +      @per.seg_name_x=SiSU_HTML::Seg.new.seg_name_x +      @per.seg_name_x_tracker=SiSU_HTML::Seg.new.seg_name_x_tracker +      @tocband_scroll,@tocband_segtoc=nil,nil +      @stylesheet=SiSU_Style::CSS_HeadInfo.new(md).stylesheet +      @o_str ||=SiSU_Env::ProcessingSettings.new(md).output_dir_structure +      @index,@metalink='index','#metadata' +      @toc=@md.file.base_filename.html_segtoc +    end +    def url_path_image_sys +      (@o_str.dump_or_redirect?) \ +      ? './image' +      : "#{Xx[:html_relative2]}_sisu/image_sys" +    end +    def icon +      def up +        'arrow_up_red.png' +      end +      def next +        'arrow_next_red.png' +      end +      def previous +        'arrow_prev_red.png' +      end +      def dot_clear +        'dot_clear.png' +      end +      def dot_white +        'dot_white.png' +      end +      def dot +        dot_white +      end +      self +    end +    def png_nav +      def toc +        %{<img border="0" width="22" height="22" src="#{url_path_image_sys}/#{icon.up}" alt="toc" />} +      end +      def pre +        %{<img border="0" width="22" height="22" src="#{url_path_image_sys}/#{icon.previous}" alt="<< previous" />} +      end +      def nxt +        %{<img border="0" width="22" height="22" src="#{url_path_image_sys}/#{icon.next}" alt="next >>" />} +      end +      def dot_toc +        %{<img border="0" width="100%" height="20" src="#{url_path_image_sys}/#{icon.dot}" alt="^" />} +      end +      def dot_pre +        %{<img border="0" width="100%" height="20" src="#{url_path_image_sys}/#{icon.dot}" alt="<" />} +      end +      def dot_nxt +        %{<img border="0" width="100%" height="20" src="#{url_path_image_sys}/#{icon.dot}" alt=">" />} +      end +      self +    end +    def doc_types(page=:seg) #used in toc & seg_nav_band +      wgt=SiSU_HTML_Format::Widget.new(@md) +      %{ +<table summary="segment navigation available documents types: toc,doc,pdf,concordance" border="0" cellpadding="3" cellspacing="0"> +<tr> +<td align="center" bgcolor=#{the_color.band2}> +  #{wgt.manifest(page)} +  #{wgt.search} +</tr></table>} +    end +    def rdf +      SiSU_XML_Tags::RDF.new(md) +    end +    def button_home(page=:seg) +      button=%{ <table summary="home button / home information" border="0" cellpadding="3" cellspacing="0">\n <tr><td align="left" bgcolor="#ffffff">\n} +      if @md.make.home_button_image.is_a?(Hash) +        image_path=if page==:manifest +          @md.file.output_path.manifest.rel_image +        elsif  page==:scroll +          @md.file.output_path.html_scroll.rel_image +        else +          @md.file.output_path.html_seg.rel_image +        end +        SiSU_Env::FileOp.new(@md) +        button +=%{   <p class="tiny_left"><a href="#{@md.make.home_button_image[:link]}" target="_top"><img border="0" src="#{image_path}/#{@md.make.home_button_image[:home_button]}"  width="#{@md.make.home_button_image[:w]}" height="#{@md.make.home_button_image[:h]}" alt="home icon -->" /></a></p>\n} +      elsif @md.home_button_links.is_a?(Array) +        @md.home_button_links.each do |links| +          button +=%{  <p class="tiny_left"><a href="#{links[:url]}" target="_top">\n    #{links[:say]}\n  </a></p>\n} +        end +      end +      button +=%{ </td></tr>\n </table>} +      button +    end +    def html_close #moved +    %{</body> +</html>} +    end +  end +  class Widget < HeadInformation +    include SiSU_Parts_HTML +    def initialize(md) +      super(md) +      @md=md +      @cf_defaults=SiSU_Env::InfoProcessingFlag.new +      @env=SiSU_Env::InfoEnv.new(md.fns) +      @file=SiSU_Env::FileOp.new(md) +      @o_str ||=SiSU_Env::ProcessingSettings.new(md).output_dir_structure +      @make=SiSU_Env::ProcessingSettings.new(md) +    end +    def home +      %{<td align="center" bgcolor=#{the_color.band2}> +  <a href="../index.html" target="_top"> +  #{the_nav.txt_homepage}</a> +</td> +} +    end +    def scroll(text) +      if @md.fns =~ /\.(?:-|ssm\.)?sst$/ +        %{<td align="center" bgcolor=#{the_color.band2}> +  <a href="#{Xx[:html_relative1]}html/#{@file.base_filename.html_scroll}" target="_top"> +    #{text} +  </a> +</td> +} +      end +    end +    def seg(text) +      %{<td align="center" bgcolor="#99CC66"> +  <a href="#{@md.file.base_filename.html_segtoc}" target="_top"> +    #{text} +  </a> +</td> +} +    end +    def search +      if @make.build.html_search_form? +        env=SiSU_Env::InfoEnv.new(@md.fns,@md) +        env.widget.search_form('sisusearch',nil,nil,true) +      else '' +      end +    end +    def manifest(page=:seg) +      if @make.build.links_to_manifest? \ +      and not @o_str.dump_or_redirect? +        manifest_lnk=if @file.output_dir_structure.by_language_code? \ +        or @file.output_dir_structure.by_filetype? +          "#{Xx[:html_relative1]}manifest/#{@file.base_filename.manifest}" +        else @file.base_filename.manifest +        end +        if page==:manifest +          manifest_lnk="#{@md.file.output_path.manifest.url}/#{@file.base_filename.manifest}" +          %{<td align="center" bgcolor=#{the_color.band2}> +  <font face="#{the_font.set_fonts}" size="2"> +  #{the_url_decoration.xml_open}<a href="#{manifest_lnk}" target="_top">#{@md.file.output_path.manifest.url}/#{@file.base_filename.manifest}</a>#{the_url_decoration.xml_close} +  </font> +</td>} +        else +          %{<td align="center" bgcolor=#{the_color.band2}> +  <a href="#{manifest_lnk}" target="_top"> +    #{the_nav.txt_manifest} +  </a> +</td>} +        end +      else '' +      end +    end +  end +  class XML +  end +  class HeadToc < HeadInformation +    def initialize(md) +      super(md) +      @md=md +      @o_str ||=SiSU_Env::ProcessingSettings.new(md).output_dir_structure +      @make=SiSU_Env::ProcessingSettings.new(@md) +      @file=SiSU_Env::FileOp.new(@md) +    end +    def scroll_head_navigation_band +      if @make.build.html_top_band? +        <<WOK +<td align="center" width="60%"> +  #{make_scroll_search_form_and_manifest_link} +</td> +WOK +        %{<table summary="table of contents scroll navigation band" id="toc" width="100%" bgcolor=#{the_color.band1}> +<tr><td width="20%"> +  #{button_home(:scroll)} +</td> +<td width="75%" align="center"> +  #{doc_types} +</td> +<td width="20%"> +    +#{the_table_close} +<p>} +      else '' +      end +    end +    def concordance_navigation_band +      up_button=if @make.build.html_navigation? +        %{</td> +<td width="5%" align="right"> +   <a href="toc.html" target="_top" alt="->"> +      #{png_nav.toc} +    </a>  +} +      else '' +      end +      if @make.build.html_top_band? +        %{<table summary="concordance navigation band" id="toc" width="100%" bgcolor=#{the_color.band1}> +<tr><td width="20%"> +  #{button_home} +</td> +<td width="75%" align="center"> +  #{doc_types} +#{up_button} +#{the_table_close} +<p>} +      else '' +      end +    end +    def seg_head_navigation_band(page=:seg) +      if @make.build.html_navigation? +        if page==:manifest +          nxt=(@file.output_dir_structure.by_language_code? \ +          || @file.output_dir_structure.by_filetype?) \ +          ? "../html/#{@md.fnb}/toc#{@md.lang_code_insert}#{Sfx[:html]}" +          : "toc#{@md.lang_code_insert}#{Sfx[:html]}" +          firstseg=%{<a href="#{nxt}" target="_top" alt="->"> +          #{png_nav.nxt}</a>} +        elsif @md.firstseg =~/\S+/ +          firstseg=%{<a href="#{@md.firstseg}#{@md.lang_code_insert}#{Sfx[:html]}" target="_top" alt="->"> +        #{png_nav.nxt}</a>} +        end +      else '' +      end +      if @make.build.html_top_band? +        %{<table summary="table of contents segment navigation band" id="toc" width="100%" bgcolor=#{the_color.band1}> +<tr><td width="20%"> +#{button_home(page)} +</td> +<td width="75%" align="center"> +  #{doc_types(page)} +</td> +<td width="5%" align="right"> +   #{firstseg}  +#{the_table_close} +<p>} +      else '' +      end +    end +    def manifest_link(text) +#     @file=SiSU_Env::FileOp.new(@md) if @md +  %{<font size=2> +    <a href="#{@md.file.base_filename.manifest}" target="_top">#{text}</a> +  </font>} +    end +    def concordance_link(text) +      if @md.concord_make +  %{<font size=2> +    <a href="#{@md.file.base_filename.html_concordance}" target="_top"> +      #{text} +    </a> +  </font>} +      else '' +      end +    end +    def make_scroll_search_form_and_manifest_link +      wgt=SiSU_HTML_Format::Widget.new(@md) +      %{<td align="center" bgcolor=#{the_color.band2}> +  #{the_nav.txt_doc_link} +</td> +} +      %{<table summary="toc segment and scroll with pdf" border="0" cellpadding="3" cellspacing="0"> +<tr> +  #{wgt.manifest} +  #{wgt.search} +</tr></table>} +    end +    def make_scroll_seg_pdf +      seg='' +      wgt=SiSU_HTML_Format::Widget.new(@md) +      seg=%{<td align="center" bgcolor=#{the_color.band2}> +  #{the_nav.txt_toc_link} +</td> +} +      %{<table summary="toc scroll and segment with pdf" border="0" cellpadding="3" cellspacing="0"> +<tr> +<td align="center" bgcolor=#{the_color.band2}> +  #{wgt.manifest} +  #{wgt.search} +</tr></table>} +    end +    def make_concordance +      wgt=SiSU_HTML_Format::Widget.new(@md) +      %{<table summary="toc scroll and segment with pdf" border="0" cellpadding="3" cellspacing="0"> +<tr> +<td align="center" bgcolor=#{the_color.band2}> +  #{wgt.manifest} +  #{wgt.search} +</tr></table>} +    end +    def head +      rdf=SiSU_XML_Tags::RDF.new(@md) +      %{<!DOCTYPE html> +<html> +<head> +  <meta charset="utf-8"> +  <title> +    #{@md.title.full} +  </title> +<meta http-equiv="Content-Type" content="text/html;charset=utf-8" /> +#{rdf.metatag_html} +#{@stylesheet.css_head} +</head> +<body lang="#{@md.opt.lng}"> +<a name="top" id="top"></a>} +    end +    def concordance +      if @md.concord_make +      %{#{the_margin.css} +  <h4 class="toc"> +    <a href="./#{@md.file.base_filename.html_concordance}"> +      <i>Concordance</i> +    </a> +  </h4> +#{table_close}} +      else +      %{#{the_margin.css} +#{table_close}} +      end +    end +    def links_guide_vertical_open +#     @file=SiSU_Env::FileOp.new(@md) if @md +      %{ +<div id="vertical_links"> +  <ul id="vertical"> +  <li class="refbold"> +    <a href="#{the_url.home}"> +      #{the_text.txt_hp} +    </a> +  </li> +  <li class="ref"> +     Quick Ref.: +  </li> +  <li class="ref"> +    <a href="#{@md.file.base_filename.manifest}" alt="Document Manifest" target="_top"> +      Manifest +    </a> +  </li> +<!- quick ref -!>} +    end +    def links_guide_horizontal_open +#     @file=SiSU_Env::FileOp.new(@md) if @md +      %{ +<div id="horizontal_links"> +  <ul id="horizontal"> +  <li class="refbold"> +    <a href="#{the_url.home}"> +      #{the_text.txt_hp} +    </a> +  </li> +  <li class="ref"> +     Quick Ref.: +  </li> +  <li class="ref"> +    <a href="#{@md.file.base_filename.manifest}" alt="Document Manifest" target="_top"> +      Manifest +    </a> +  </li> +<!- quick ref -!>} +    end +    def links_guide_open(type='horizontal') +      (type=='vertical') \ +      ? links_guide_vertical_open +      : links_guide_horizontal_open +    end +    def links_guide_close +      insert='' +      insert=if @md.sfx_src =~/s?/ +        link='http://sisudoc.org'                          #get from defaults +        url='sisudoc.org' +        name='SiSU electronic documents'                   #get from defaults +        insert= %{ +  <li class="ref"> +    <a href="#{link}" alt="#{name}" target="_top"> +      #{url} +    </a> +  </li> +  </ul> +</div> +} +      end +      %{ #{insert} +<!- quick ref -!>} +    end +    def prefix_a +    end +    def rights +      def all +        rights=SiSU_HTML_Tune::CleanHTML.new(@md.rights.all).clean_for_html +        rights=rights.gsub(/^\s*Copyright\s+\(C\)/,'Copyright <sup>©</sup> ') +        %{<p class="small_left">Rights: #{rights}</p> +<p>} +      end +      self +    end +    def prefix_b +      %{<p class="small_left">Prefix: #{@md.prefix_b}<p />} +    end +    def scroll_head_title_banner_open +      icon=@md.icon ? %{<center>\n#{@md.icon}\n</center>} : '' +      %{#{icon} +#{the_banner.instrument_cover_band_scr}} +    end +    def seg_head_title_banner_open +      icon=@md.icon ? %{<center>\n#{@md.icon}\n</center>} : '' +      %{#{icon} +#{the_banner.instrument_cover_band_seg}} +    end +    def make_scroll +      concord=concordance_link(the_nav.txt_concordance) +      %{<table summary="toc scroll" border="0" cellpadding="3" cellspacing="0"> +<tr><td align="center" bgcolor="white" border="0"> +  #{the_nav.txt_doc_link} +</td> +<td align="center" bgcolor="white"> +   #{concord} +#{the_table_close}} +    end +    def make_seg +      concord=concordance_link(the_nav.txt_concordance) +      %{<table summary="toc segment" border="0" cellpadding="3" cellspacing="0"> +<tr><td align="center" bgcolor="white"> +  #{the_nav.txt_toc_link} +</td> +<td align="center" bgcolor="white"> +  <font size=2> +   #{concord} +#{the_table_close}} +    end +    def manifest #check structure +      if not @o_str.dump_or_redirect? +        manifest=manifest_link(the_nav.txt_manifest) +        %{#{the_margin.txt_3} +  #{the_font.paragraph_font_small} +   #{manifest} +    </font> +#{the_table_close}} +      else '' +      end +    end +    def concordance #check structure +      concord=concordance_link(the_nav.txt_concordance) +      %{#{the_margin.txt_3} +  #{the_font.paragraph_font_small} +   #{concord} +    </font> +#{the_table_close}} +    end +    def metadata +      %{#{the_margin.css} +  <h4 class="toc"> +    <a href="#{@metalink}"> +      <i>MetaData</i> +    </a> +  </h4> +#{the_table_close}} +    end +    def seg_tail +      %{ +<div class="main_column"> +<p> <p> +<table summary="toc segment tail" bgcolor=#{the_color.band1}> +<tr><td width="20%"> +  #{the_banner.banner_band} +</td> +<td width="60%"> +  <center> +    #{@tocband_segtoc} +  </center> +</td></tr> +</table> +<p> </p> +#{@bits.credits_sisu} +<a name="bottom" id="bottom"></a> +<a name="end" id="end"></a> +</div> +</div> +</div> +} +    end +    def scroll_tail #debug +      nav=scroll_head_navigation_band +      %{ +<div class="main_column"> +#{nav} +#{@bits.credits_sisu} +<a name="bottom" id="bottom"></a> +<a name="end" id="end"></a> +</div> +} +    end +    def seg_navigation_tail #this is a bug area, look up and "tidy" +      %{ +<div class="main_column"> +<p> </p> +#{@bits.credits_sisu} +<a name="bottom" id="bottom"></a> +<a name="end" id="end"></a> +</div> +</div> +</div> +} +    end +  end +  class HeadSeg < HeadInformation +    def initialize(md) +      super(md) +    end +    def dot_control_pre_next +      pre="#{@per.seg_name_x[@per.seg_name_x_tracker-1]}#{@md.lang_code_insert}#{Sfx[:html]}" +      up=@toc +      nxt="#{@per.seg_name_x[@per.seg_name_x_tracker+1]}#{@md.lang_code_insert}#{Sfx[:html]}" +      if nxt=~/sisu_manifest\.html/ +        @file=SiSU_Env::FileOp.new(@md) if @md +        if @file.output_dir_structure.by_language_code? \ +        or @file.output_dir_structure.by_filetype? +          nxt=nxt.gsub(/sisu_manifest\.html/,"../../manifest/#{@file.base_filename.manifest}") +        end +      end +      %{<table summary="segment hidden control pre and next" width="100%" border="0" cellpadding="0" bgcolor=#{the_color.grey_pale} align="center"> +<tr><td align="left"> +  <a href="#{pre}" target="_top"> +    #{png_nav.dot_pre} +  </a> +</td> +<td align="center"> +  <a href="#{up}" target="_top"> +    #{png_nav.dot_toc} +  </a> +</td> +<td align="right"> +  <a href="#{nxt}" target="_top"> +    #{png_nav.dot_nxt} +  </a> +#{the_table_close}} +    end +    def dot_control_pre +      pre="#{@per.seg_name_x[@per.seg_name_x_tracker-2]}#{@md.lang_code_insert}#{Sfx[:html]}" +      up=@toc +      nxt="#{@md.file.base_filename.html_segtoc}" +      %{<table summary="segment hidden control pre" width="100%" border="0" cellpadding="0" bgcolor=#{the_color.grey_pale} align="center"> +<tr><td align="left"> +  <a href="#{pre}" target="_top"> +    #{png_nav.dot_pre} +  </a> +</td> +<td align="center"> +  <a href="#{up}" target="_top"> +    #{png_nav.dot_toc} +  </a> +</td> +<td align="right"> +  <a href="#{nxt}" target="_top"> +    #{png_nav.dot_nxt} +  </a> +#{the_table_close}} +    end +    def toc_nav(f_pre=false,f_nxt=false,use=1) +      pre=nxt='' +      toc=%{<td align="center" bgcolor=#{the_color.band1}> +  <a href="#{@toc}" target="_top"> +    #{png_nav.toc} +  </a> +</td>} +      pre=%{<td align="center" bgcolor=#{the_color.band1}> +  <a href="#{@per.seg_name_x[@per.seg_name_x_tracker-use]}#{@md.lang_code_insert}#{Sfx[:html]}" target="_top"> +    #{png_nav.pre} +  </a> +</td>} if f_pre==true +      nxt=%{<td align="center" bgcolor=#{the_color.band1}> +  <a href="#{@per.seg_name_x[@per.seg_name_x_tracker+1]}#{@md.lang_code_insert}#{Sfx[:html]}" target="_top"> +    #{png_nav.nxt} +  </a> +</td>} if f_nxt==true +      if nxt =~/sisu_manifest.html/ +        @file=SiSU_Env::FileOp.new(@md) if @md +        if @file.output_dir_structure.by_language_code? \ +        or @file.output_dir_structure.by_filetype? +          nxt=nxt.gsub(/sisu_manifest\.html/,"../../manifest/#{@file.base_filename.manifest}") +        end +      end +      %{<table summary="segment navigation pre/next" border="0" cellpadding="3" cellspacing="0"> +<tr> +#{pre} +#{toc} +#{nxt} +<td> +#{the_table_close}} +    end +    def toc_next2 +      toc_nav(false,true).dup +    end +    def toc_pre_next2 +      toc_nav(true,true).dup +    end +    def toc_pre2 +      toc_nav(true,false,2).dup +    end +    def manifest_link(text) +  %{<font size=2> +    <a href="#{@md.file.base_filename.manifest}" target="_top"> +      #{text} +    </a> +  </font>} +    end +    def concordance_link(text) +      if @md.concord_make +  %{<font size=2> +    <a href="#{@md.file.base_filename.html_concordance}" target="_top"> +      #{text} +    </a> +  </font>} +      else '' +      end +    end +    def credit +      %{ +<div class="main_column"> +#{@bits.credits_sisu} +<a name="bottom" id="bottom"></a> +<a name="end" id="end"></a> +</div></div> +} +    end +    def navigation_band(segtocband,seg_table_top_control) #change name to navigation_band_banner +      %{<table summary="segment navigation band with banner" bgcolor=#{the_color.band1} width="100%"><tr> +<td width="20%" align="left"> +#{button_home} +</td> +<td width="75%" align="center"> +  #{doc_types} +</td> +<td width="5%" align="right"> +  #{segtocband} +</td></tr> +</table> +#{seg_table_top_control}} +    end +    def navigation_band_bottom(segtocband,seg_table_top_control) #change name to navigation_band_bannerless +      %{ +<div class="main_column"> +  <table summary="segment navigation band" bgcolor=#{the_color.band1} width="100%"><tr> +  <td width="70%" align="center"> +    #{doc_types} +  </td> +  <td width="5%" align="right"> +    #{segtocband} +  </td></tr> +  </table> +  #{seg_table_top_control} +</div> +} +    end +    def endnote_mark +%{ +<p class="center" id="endnotes"> +  <hr class="endnote" /> +</p>} +    end +    def endnote_section_open +%{ +<div class="endnote"> +} +    end +    def endnote_section_close +%{ +</div> +} #revisit +    end +    def head_seg +      rdf=SiSU_XML_Tags::RDF.new(@md) +      %{<!DOCTYPE html> +<html> +<head> +  <meta charset="utf-8"> +  <title> +    #{@per.seg_name_x[@per.seg_name_x_tracker]} - +    #{@md.title.main} +  </title> +<meta http-equiv="Content-Type" content="text/html;charset=utf-8"> +#{rdf.metatag_html} +#{@stylesheet.css_head_seg} +</head> +<body lang="#{@md.opt.lng}"> +<a name="top" id="top"></a>} +    end +    def title_banner(title,subtitle,creator) +      %{ +<div class="summary"> +  <p class="tiny"> +    #{title} +  </p> +  <p class="tiny"> +    #{subtitle} +  </p> +  <p class="tiny"> +    #{creator} +  </p> +  <p class="tiny"> +    copy @ +    <a href="#{the_url.home}"> +      #{the_text.txt_home} +    </a> +  </p> +</div> +} +    end +  end +  class HeadScroll < HeadToc +    def initialize(md) +      super(md) +    end +    def toc_owner_details +      %{#{the_margin.txt_3} +#{the_font.paragraph_font_small} +  <a href="#owner.details"> +    Owner Details +    <font size="1" color="#777777"> +          +    </font> +  </a> +  </font> +#{the_table_close}} +    end +  end +  class FormatTextObject +    include SiSU_Parts_HTML +    attr_accessor :md,:t_o,:txt,:ocn,:format,:table,:link,:linkname,:paranum,:p_num,:headname,:banner,:url +    def initialize(md,t_o) +      @md,@t_o=md,t_o +      @make=SiSU_Env::ProcessingSettings.new(@md) +      if t_o.is_a?(Hash) +        @txt            =t_o[:txt]            || nil +        @ocn            =t_o[:ocn]            || nil +        @ocn_display    =t_o[:ocn_display]    || nil +        @headname       =t_o[:headname]       || nil +        @trailer        =t_o[:trailer]        || nil +        @endnote_part_a =t_o[:endnote_part_a] || nil +        @endnote_part_b =t_o[:endnote_part_b] || nil +        @lnk_url        =t_o[:lnk_url]        || nil +        @lnk_txt        =t_o[:lnk_txt]        || nil +        @format         =t_o[:format]         || nil +      elsif t_o.class.inspect =~/^(?:#<)?SiSU_AO_DocumentStructure/ +        @dob=t_o if defined? t_o.is +        @named=nametags_seg(@dob) +        @txt=((defined? t_o.obj) ? t_o.obj : nil) +        @ocn=((defined? t_o.ocn) ? t_o.ocn.to_s : nil) +        @headname=((t_o.is==:heading and defined? t_o.name) ? t_o.name : nil) +      else +        if @md.opt.act[:maintenance][:set]==:on +          p t_o.class +          p caller +        end +      end +      @headnamed=(@headname ? %{<a id="h#{@headname}"></a>} : nil) +      if @txt and not @txt.empty? +        @txt=@txt.gsub(/#{Mx[:mk_o]}[-~]##{Mx[:mk_c]}/,'') +      end +      @p_num=ParagraphNumber.new(@md,@ocn) +    end +    def nametags_scroll(dob) +      tags='' +      if defined? dob.tags \ +      and dob.tags.length > 0 # insert tags "hypertargets" +        dob.tags.each do |t| +          t=t.gsub(/[^a-z0-9._-]/,'') #use for all html tags? consider limiting to strict? or implementing earlier +          tags=tags << %{<named id="#{t}" />} +        end +      end +      tags +    end +    def nametags_seg(dob) #FIX +      tags='' +      if defined? dob.tags \ +      and dob.tags.length > 0 # insert tags "hypertargets" +        dob.tags.compact.each do |t| # .compact hides a problem, nil should not occur fix (upstream) +          t=t.gsub(/[^a-z0-9._-]/,'') #use for all html tags? consider limiting to strict? or implementing earlier +          tags=(t =~/^[0-9.]+$/) \ +          ? tags             #check what can be sorted in ao +          : (tags << %{<a name="#{t}" ></a>}) +        end +      end +      tags +    end +    def headname #check whether used +      hn=if @t_o.is ==:heading \ +      and not @t_o.name.empty? #determine use +        hn=(@t_o.is ==:heading) \ +        ? (%{<a id="h#{@t_o.name}"></a>}) +        : (%{<a id="#{@t_o.name}"></a>}) +      else nil +      end +      hn +    end +    def endnote_body +      %{ +<p class="endnote"> +  #{@txt} +</p> +} +    end +    def endnote_body_indent +      %{ +  <p class="endnote_indent"> +    #{@txt} +  </p> +} +    end +    def no_paranum +      %{ +<div class="substance"> +  <label class="ocn"> </label> +  <p class="norm"> +    #{@txt} +  </p> +</div> +} +    end +    def para_form_css(tag,attrib)                                                    # regular paragraphs shaped here +      ul=ulc='' +      if tag =~/li/ +        ul,ulc="<ul>\n  ","\n  </ul>" +      end +      %{ +<div class="substance"> +  #{@p_num.ocn_display} +  #{ul}<#{tag} class="#{attrib}" #{@p_num.id}> +    #{@named}#{@txt} +  </#{tag}>#{ulc} +</div> +} +    end +    def para +      para_form_css('p','norm') +    end +    def block +      para_form_css('p','block') +    end +    def group +      para_form_css('p','group') +    end +    def alt +      para_form_css('p','alt') +    end +    def verse +      para_form_css('p','verse') +    end +    def code +      para_form_css('p','code') +    end +    def center +      para_form_css('p','center') +    end +    def bold +      para_form_css('p','bold') +    end +    def bullet +      para_form_css('li','bullet') +    end +    def table +      @txt=if @t_o.obj !~/^<table\s/ +        table=SiSU_HTML_Shared::TableHTML.new(@t_o) #move, make happen earlier +        @txt=table.table.obj +      else @txt +      end +      para_form_css('p','norm') +    end +    def format(tag,attrib) +      para_form_css(tag,attrib) +    end +    def heading_normal(tag,attrib) +      section_break=(tag=~/h[1-5]/) \ +      ? '<br><hr width=90% /><br>' +      : '' +      %{#{section_break} +<div class="substance"> +  #{@p_num.ocn_display} +  <#{tag} class="#{attrib}" #{@p_num.id}>#{@p_num.name} +    #{@named}#{@txt} +  </#{tag}> +</div> +} +    end +    def heading_body +      heading_normal('p','norm') +    end +    def heading_body0 +      heading_normal('h1','norm') +    end +    def heading_body1 +      heading_normal('h1','norm') +    end +    def heading_body2 +      heading_normal('h2','norm') +    end +    def heading_body3 +      heading_normal('h3','norm') +    end +    def heading_body4 +      heading_normal('h4','norm') +    end +    def heading_body5 +      heading_normal('h5','norm') +    end +    def heading_body6 +      heading_normal('h6','norm') +    end +    def heading_body7 +      heading_normal('h7','norm') +    end +    def title_heading(tag,attrib) +      cl=(@make.build.html_minitoc?) \ +      ? 'content' +      : 'content0' +      %{ +<div class="#{cl}"> +<#{tag} class="#{attrib}"> +    #{@named}#{@txt} +  </#{tag}> +</div> +} +    end +    def title_heading0 +      title_heading('h1','tiny') +    end +    def title_heading1 +      title_heading('h1','tiny') +    end +    def title_heading2 +      title_heading('h2','tiny') +    end +    def title_heading3 +      title_heading('h3','tiny') +    end +    def title_heading4 +      '' +    end +    def seg_heading_sub(tag,attrib) +      @txt=@txt.gsub(/(?:#{Mx[:en_a_o]}.+?#{Mx[:en_a_c]}|#{Mx[:en_b_o]}.+?#{Mx[:en_b_c]})\s*/m,' ') +      %{ +<div class="substance"> +  #{@p_num.ocn_display} +  <#{tag} class="#{attrib}" #{@p_num.id}>#{@p_num.name} #{@headnamed} +    #{@named}#{@txt} +  </#{tag}> +</div> +} +    end +    def seg_heading4 +      %{ +<div class="substance"> +  #{@p_num.ocn_display} +  <h1 class="norm" #{@p_num.id}>#{@p_num.name} +    #{@txt} +  </h1> +</div> +} +    end +    def seg_heading5 +      seg_heading_sub('p','bold') +    end +    def seg_heading6 +      seg_heading_sub('p','bold') +    end +    def dl #check :trailer +      "<dl><b>#{@txt}</b> #{@trailer}</dl>" +    end +    def table_css_end +      '</table> +    </p> +  </div>' +    end +    def gsub_body #fix +      @txt=case @txt +      when /^\((i+|iv|v|vi+|ix|x|xi+)\)/ +        @txt.gsub(/^\((i+|iv|v|vi+|ix|x|xi+)\)/,'<b>(\1)</b>') +      when /^\(?(\d|[a-z])+\)/ +        @txt.gsub(/^\((\d+|[a-z])+\)/,'<b>(\1)</b>') +      when /^\s*\d{1,3}\.\s/ +        @txt.gsub(/^\s*(\d+\.)/,'<b>\1</b>') +      when /^\s*[A-Z]\.\s/ +        @txt.gsub(/^\s*([A-Z]\.)/,'<b>\1</b>') +      else @txt +      end +    end +    def bold_para +      %{#{the_margin.txt_0} +  <p class="bold"> +    #{@txt} +  </p> +#{the_margin.num_css} +      +#{the_table_close}} +    end +    def bold_heading +      %{<p class="bold"> +    #{@txt} +  </p> +#{the_margin.num_css} +      +#{the_table_close}} +    end +    def toc_head_copy_at +      %{<p class="center">#{@txt}</p>\n} +    end +    def center +      %{<p class="center">#{@txt}</p>\n} +    end +    def bold +      %{<p class="bold">#{@txt}</p>\n} +    end +    def center_bold +      %{<p class="centerbold">#{@txt}</p>\n} +    end +  end +  class FormatScroll < FormatTextObject +    def initialize(md,txt) +      super(md,txt) +    end +  end +  class FormatSeg < FormatTextObject +    def initialize(md,txt) +      super(md,txt) +    end +    def endnote_seg_body(fn='') +      fn="../#{@md.fnb}" if fn.to_s.empty? +      %{ +  <p class="endnote"> +    #{@endnote_part_a}#{fn}#{@md.lang_code_insert}#{Sfx[:html]}#{@endnote_part_b} +  </p> +} +    end +    def clean(txt) +      txt=txt.gsub(/#{Mx[:en_a_o]}.+?#{Mx[:en_a_c]}/,''). +        gsub(/#{Mx[:en_b_o]}.+?#{Mx[:en_b_c]}/,'') +    end +    def subtoc_lev(tag,attrib) +      @txt=clean(@txt) +      txt=if @txt \ +      and @txt =~/<\/?i>|<a\s+name="\S+?">/mi +        @txt.gsub(/<\/?i>|<a\s+name="\S+?">/mi,'') #removes name markers from subtoc, go directly to substantive text +      else @txt +      end +      note='' +      if txt =~/(#{Mx[:en_a_o]}.+?#{Mx[:en_a_c]}|#{Mx[:en_b_o]}.+?#{Mx[:en_b_c]})/m # had \s* at end +        note=$1 +        note=note.gsub(/[\s]+/m,' ') +        txt=txt.gsub(/(?:#{Mx[:en_a_o]}.+?#{Mx[:en_a_c]}|#{Mx[:en_b_o]}.+?#{Mx[:en_b_c]})\s*/m,' '). +          gsub(/<a[\s]+name="-\d+"[\s]+href="#_\d+"> <sup>\d+<\/sup> /m,'') +      end +      %{<#{tag} class="#{attrib}"> +    <a href="##{@ocn}"><i>#{txt}</i></a> #{note} +  </#{tag}>} +    end +    def subtoc_lev5 +      subtoc_lev('h5','subtoc') if @txt +    end +    def subtoc_lev6 +      subtoc_lev('h6','subtoc') if @txt +    end +    def subtoc_lev7 +      subtoc_lev('h7','subtoc') if @txt +    end +    def heading_sub(tag,attrib) +      @txt=@txt.gsub(/(?:#{Mx[:en_a_o]}.+?#{Mx[:en_a_c]}|#{Mx[:en_b_o]}.+?#{Mx[:en_b_c]})\s*/m,' ') +      %{ +<div class="substance"> +  #{@p_num.ocn_display} +  <#{tag} class="#{attrib}" #{@p_num.id}>#{@p_num.name} #{@headnamed} +    #{@txt} +  </#{tag}> +</div> +} +    end +    def heading5 +      heading_sub('p','bold') +    end +    def heading6 +      heading_sub('p','bold') +    end +    def heading4 +      %{ +<div class="substance"> +  #{@p_num.ocn_display} +  <h1 class="norm" #{@p_num.id}>#{@p_num.name} +    #{@t_o[:format]} +    #{@txt} +  </h1> +</div> +} +    end +    def navigation_heading4 +      %{<table summary="navigation segment heading 4" width=100% bgcolor="#08163f" border="0"> +<tr><td align="center"> +<p class="bold"> +  #{@txt} +</p> +#{the_table_close}} +    end +    def navigation_heading5 +      %{<p class="bold"> +  #{@txt} +</p>} +    end +    def navigation_heading6 +      %{<p class="bold"> +  #{@txt} +</p>} +    end +    def navigation_center +      "<center>#{@txt}</center>" +    end +  end +  class FormatToc < FormatTextObject +    def initialize(md,txt) +      super(md,txt) +    end +    def links_guide +      %{  <li class="doc"> +    <a href="#{@lnk_url}" target="_top"> +      #{@lnk_txt} +    </a> +  </li> +} +    end +    def lev(tag,attrib) +      if @txt +        %{<#{tag} class="#{attrib}"> +    #{@txt} +  </#{tag}> +} +      else '' +      end +    end +    def lev0 #docinfo +      lev('h1','toc') +    end +    def lev1 +      lev('h1','toc') +    end +    def lev2 +      lev('h2','toc') +    end +    def lev3 +      lev('h3','toc') +    end +    def lev4 +      lev('h4','toc') +    end +    def lev5 +      lev('h5','toc') +    end +    def lev6 +      lev('h6','toc') +    end +    def lev7 +      lev('h7','toc') +    end +    def strip_endnotes(txt) +      txt=txt.gsub(/(?:#{Mx[:en_a_o]}.+?#{Mx[:en_a_c]}|#{Mx[:en_b_o]}.+?#{Mx[:en_b_c]})\s*/m,' ') +      txt +    end +    def mini_lev0 +      @txt=strip_endnotes(@txt) +      lev('h1','minitoc') +    end +    def mini_lev1 +      @txt=strip_endnotes(@txt) +      lev('h1','minitoc') +    end +    def mini_lev2 +      @txt=strip_endnotes(@txt) +      lev('h2','minitoc') +    end +    def mini_lev3 +      @txt=strip_endnotes(@txt) +      lev('h3','minitoc') +    end +    def mini_lev4 +      @txt=strip_endnotes(@txt) +      lev('h4','minitoc') +    end +    def mini_lev5 +      @txt=strip_endnotes(@txt) +      lev('h5','minitoc') +    end +    def mini_lev6 +      @txt=strip_endnotes(@txt) +      lev('h6','minitoc') +    end +    def mini_lev7 +      @txt=strip_endnotes(@txt) +      lev('h7','minitoc') +    end +    def mini_lev0 #docinfo +      lev('h1','minitoc') +    end +    def mini_tail +  %{ +  <h4 class="minitoc"> +    <a href="sisu_manifest.html">Manifest (alternative outputs)</a> +  </h4> +} +    end +    def mini_concord_tail +  %{ +  <h4 class="minitoc"> +    <a href="concordance.html">Concordance (wordlist)</a> +  </h4> +  <h4 class="minitoc"> +    <a href="sisu_manifest.html">Manifest (alternative outputs)</a> +  </h4> +} +    end +  end +  class FormatStr +    def initialize(md,str) +      @str=str +    end +    def center +      %{<p class="center">#{@str}</p>\n} +    end +    def bold +      %{<p class="bold">#{@str}</p>\n} +    end +    def center_bold +      %{<p class="centerbold">#{@str}</p>\n} +    end +    def endnote_body +      %{ +<p class="endnote"> +  #{@str} +</p> +} +    end +  end +end +__END__ +#+END_SRC + +** shared +*** html_shared.rb + +#+BEGIN_SRC ruby  :tangle "../lib/sisu/html_shared.rb" +# <<sisu_document_header>> +module SiSU_HTML_Shared +  require_relative 'html_table'                         # html_table.rb +  class TableHTML < SiSU_HTML_Table::TableHTML +  end +end +__END__ +#+END_SRC + +*** html_lite_shared.rb + +#+BEGIN_SRC ruby  :tangle "../lib/sisu/html_lite_shared.rb" +# <<sisu_document_header>> +module SiSU_FormatShared +  require_relative 'html_parts'                         # html_parts.rb +  class CSS_Format +    require_relative 'se_hub_particulars'               # se_hub_particulars.rb +    include SiSU_Parts_HTML +    @@fns=nil +    def initialize(md,t_o) +      @md,@t_o=md,t_o +      @txt=@t_o.obj +      @id=@ocn=@t_o.ocn if defined? @t_o.ocn +      @lv=@t_o.lv.to_s if @t_o.is==:heading +      if @md.fns != @@fns +        @@fns,@@hname=@md.fns,'' +      end +      @hname=if defined? @t_o.name \ +      and not @t_o.name.to_s.empty? +        @@hname=@t_o.name +      else @@hname +      end +      @tab="\t" +      @@tablehead,@@tablefoot=[],[] +      @env=SiSU_Env::InfoEnv.new(@md.fns) +      @base_url="#{@env.url.root}/#{@md.fnb}/#{@hname}.html" +    end +    def urls(data) +      @words=[] +      map_nametags=SiSU_Particulars::CombinedSingleton.instance.get_map_nametags(@md).nametags_map +      data.each do |word| +        @words << if word=~/#{Mx[:lnk_o]}(.+?)#{Mx[:lnk_c]}(#{Mx[:url_o]}\S+?#{Mx[:url_c]}|#{Mx[:rel_o]}\S+?#{Mx[:rel_c]}|image)/ +          if word =~/#{Mx[:lnk_o]}.+?#{Mx[:lnk_c]}#{Mx[:url_o]}\S+?#{Mx[:url_c]}/ +            m,u=/#{Mx[:lnk_o]}(.+?)#{Mx[:lnk_c]}#{Mx[:url_o]}(\S+?)#{Mx[:url_c]}/.match(word).captures +          elsif word =~/#{Mx[:lnk_o]}.+?#{Mx[:lnk_c]}#{Mx[:rel_o]}\S+?#{Mx[:rel_c]}/ +            m,u=/#{Mx[:lnk_o]}(.+?)#{Mx[:lnk_c]}#{Mx[:rel_o]}(\S+?)#{Mx[:rel_c]}/.match(word).captures +          elsif word =~/#{Mx[:lnk_o]}.+?#{Mx[:lnk_c]}image/ +            m,u=/#{Mx[:lnk_o]}(.+?)#{Mx[:lnk_c]}(image)/.match(word).captures +          end +          word=case m +          when /\.png|\.jpg|\.gif|c=|\d+x\d+/ +            w,h=/(\d+)x(\d+)/.match(m).captures if m =~/\d+x\d+/ +            w=%{width="#{w}"} if w +            h=%{height="#{h}"} if h +            c=m[/"(.+?)"/m,1] +            caption=%{<br><p class="caption">#{c}</p>} if c +            png=m.scan(/\S+/)[0] +            ins=if u \ +            and u.strip !~/^image$/ +              %{<a href="#{u}">[#{png}]</a>#{caption}} +            else %{[#{png}] #{caption}} +            end +            word=word.gsub(/#{Mx[:lnk_o]}.+?#{Mx[:lnk_c]}(#{Mx[:url_o]}\S+?#{Mx[:url_c]}|image)/,ins) +          else +            u=case u +            when /^https?:\/\// +              u +            when /^:/ +              u=u.gsub(/^:/,'') +              "#{@env.url.root}/#{u}" +            when /^\.\.\// # can remove +              u=u.gsub(/^\.\.\//,'') +              "#{@env.url.root}/#{u}" +            else +              if not map_nametags[u].nil? +                @env.url.root + '/' \ +                + @md.fnb + '/' \ +                + map_nametags[u][:segname] \ +                + Sfx[:html] \ +                + '#' + u +              else '' +              end +            end +            link=m[/(.+)/m] +            png=m.scan(/\S+/)[0].strip +            link=link.strip +            ins=%{<a href="#{u}">#{link}</a>} +            word=word.gsub(/#{Mx[:lnk_o]}.+?#{Mx[:lnk_c]}#{Mx[:url_o]}\S+?#{Mx[:url_c]}/,ins). +              gsub(/#{Mx[:lnk_o]}.+?#{Mx[:lnk_c]}#{Mx[:rel_o]}\S+?#{Mx[:rel_c]}/,ins) +            word +          end +          word +        else word +        end +        word +      end +      @words=@words.join(' ') +    end +    def markup_generic(s) +      s=s.gsub(/#{Mx[:fa_bold_o]}(.+?)#{Mx[:fa_bold_c]}/,'<b>\1</b>'). +        gsub(/#{Mx[:fa_italics_o]}(.+?)#{Mx[:fa_italics_c]}/,'<i>\1</i>'). +        gsub(/#{Mx[:fa_underscore_o]}(.+?)#{Mx[:fa_underscore_c]}/,'<u>\1</u>'). +        gsub(/#{Mx[:fa_cite_o]}(.+?)#{Mx[:fa_cite_c]}/,'"\1"'). +        gsub(/#{Mx[:fa_insert_o]}(.+?)#{Mx[:fa_insert_c]}/,'+{\1}+'). +        gsub(/#{Mx[:fa_strike_o]}(.+?)#{Mx[:fa_strke_c]}/,'-{\1}-'). +        gsub(/#{Mx[:fa_superscript_o]}(.+?)#{Mx[:fa_superscript_c]}/,'<sup>\1</sup>'). +        gsub(/#{Mx[:fa_subscript_o]}(.+?)#{Mx[:fa_subscript_c]}/,'<sub>\1</sub>'). +        gsub(/#{Mx[:fa_monospace_o]}(.+?)#{Mx[:fa_monospace_c]}/,'<tt>\1</tt>'). # tt, kbd +        gsub(/#{Mx[:gl_o]}#(?:126|152)#{Mx[:gl_c]}/i,'~') +    end +    def markup_object(t_o) +      s=t_o.obj +      s=if t_o.is !=:code +        s=markup_generic(s) +        if s =~/#{Mx[:lnk_o]}.+?#{Mx[:lnk_c]}(?:#{Mx[:url_o]}\S+?#{Mx[:url_c]}|#{Mx[:rel_o]}\S+?#{Mx[:rel_c]}|image)/ +          wm=s.scan(/#{Mx[:lnk_o]}.+?#{Mx[:lnk_c]}(?:#{Mx[:url_o]}\S+?#{Mx[:url_c]}|#{Mx[:rel_o]}\S+?#{Mx[:rel_c]}|image)|\S+/) +          words=urls(wm) +          s=s.gsub(/.+/m,words) +        end +        s.gsub(/#{Mx[:gl_o]}(#[0-9]{3})#{Mx[:gl_c]}/u,'&\1;'). +          gsub(/#{Mx[:gl_o]}#([a-z]{2,4})#{Mx[:gl_c]}/u,'&\1;'). +          gsub(/#{Mx[:url_o]}[_\\](\S+?)#{Mx[:url_c]}/,'<a href="\1" target="_top">\1</a>'). #http ftp matches escaped, no decoration +          gsub(/(#{Mx[:lnk_c]})#{Mx[:url_o]}(\S+?)#{Mx[:url_c]}/,'\1<a href="\2" target="_top">\2</a>'). #special case \{ e.g. \}http://url +          gsub(/(^|#{Mx[:gl_c]}|\s)#{Mx[:url_o]}(\S+?)#{Mx[:url_c]}/,%{\\1#{the_url_decoration.xml_open}<a href="\\2" target="_top">\\2</a>#{the_url_decoration.xml_close}\\3}) #http ftp matches with decoration +      else +        s.gsub(/</m,'<'). +          gsub(/>/m,'>') +      end +      s +    end +    def markup_note(s) +      s=markup_generic(s) +      if s =~/#{Mx[:lnk_o]}.+?#{Mx[:lnk_c]}(#{Mx[:url_o]}\S+?#{Mx[:url_c]}|#{Mx[:rel_o]}\S+?#{Mx[:rel_c]}|image)/ +        wm=s.scan(/#{Mx[:lnk_o]}.+?#{Mx[:lnk_c]}(?:#{Mx[:url_o]}\S+?#{Mx[:url_c]}|#{Mx[:rel_o]}\S+?#{Mx[:rel_c]}|image)|\S+/) +        words=urls(wm) +        s=s.gsub(/.+/m,words) +      end +      s=s.gsub(/#{Mx[:gl_o]}(#[0-9]{3})#{Mx[:gl_c]}/u,'&\1;'). +        gsub(/#{Mx[:gl_o]}#([a-z]{2,4})#{Mx[:gl_c]}/u,'&\1;'). +        gsub(/#{Mx[:url_o]}_(\S+?)#{Mx[:url_c]}/,'<a href="\1" target="_top">\1</a>\2'). #http ftp matches escaped, no decoration +        gsub(/(#{Mx[:lnk_c]})#{Mx[:url_o]}(\S+?)#{Mx[:url_c]}/,'\1<a href="\2" target="_top">\2</a>'). #special case \{ e.g. \}http://url +        gsub(/#{Mx[:url_o]}(\S+?)#{Mx[:url_c]}/,%{#{the_url_decoration.xml_open}<a href="\\1" target="_top">\\1</a>#{the_url_decoration.xml_close}}) #http ftp matches with decoration +    end +    def paragraph +      %{<p class="h#{@lv}" type="substantive" header="#{@hname}">#{@txt}</p>\n} # << "\n" +    end +    def endnote(nr,en) #used only by db +      txt=markup_note(en) +      <<GSUB +<p class="endnote" name="note_#{nr}" from="#{@t_o.ocn}"> +<a href="#{@base_url}#-#{nr}" name="_#{nr}">#{nr}.</a> <note>#{txt}</note> +</p> +GSUB +    end +    def tag_header(h) +      %{<p class="#{h[:class]}" type="#{h[:type]}" header="#{h[:header]}">#{h[:txt]}</a></p>\n} # << "\n" +    end +    def tag_para(h) +      %{<p class="#{h[:class]}" type="#{h[:type]}">#{h[:txt]}</a></p>\n}  << "\n" +    end +    def lev_toc_hname +      %{<p class="toc#{@lv}" header="#{@hname}"><a href="##{@ocn}">#{@txt}</a></p>\n}  #<< "\n" +    end +    def lev_toc +      h={ txt: txt, class: "toc#{@lv}", type: 'toc' } +      tag_para(h) +    end +    def lev4_plus +      txt=markup_object(@t_o) +      h={ txt: txt, class: "h#{@lv}", type: 'substantive', id: @ocn, header: @hname } +      tag_header(h) +    end +    def lev4_minus +      txt=markup_object(@t_o) +      h={ txt: txt, class: "h#{@t_o.ln}", type: 'substantive', id: @ocn } +      tag_para(h) +    end +    def norm_comment +      h={ txt: @t_o.obj, class: 'norm', type: 'comment' } +      tag_para(h) +    end +    def norm +      txt=markup_object(@t_o) +      h={ txt: txt, class: 'norm', type: 'substantive', id: @ocn } +      tag_para(h) +    end +    def code +      txt=markup_object(@t_o) +      h={ txt: "<tt>#{txt}</tt>", class: 'code', type: 'substantive', id: @ocn } +      tag_para(h) +    end +    def indent(t) +      txt=markup_object(@t_o) +      h={ txt: txt, class: "indent#{t}", type: 'substantive', id: @ocn } +      tag_para(h) +    end +    def hang_indent(f,t) +      txt=markup_object(@t_o) +      h={ txt: txt, class: "hang#{f}indent#{t}", type: 'substantive', id: @ocn } +      #h={ txt: txt, class: "h#{f}i#{t}", type: 'substantive', id: @ocn } +      tag_para(h) +    end +    def para_table +      %{<p class="norm" align="left"><font #{the_font.set_small} #{the_font.set_color} #{the_font.set_face}>} +    end +    def ocn +      %{<label class="ocn">#{@ocn}</label>} << "\n" +    end +    def html_table # get rid of use html_table +      @new_content=[] +      @txt.split(/\n/).each do |parablock| +        m=parablock[/<!f(.+?)!>/,1] +        @@tablefoot << m if m +        parablock=parablock.gsub(/<!f.+?!>/,'') +        @@tablehead=1 if parablock =~/#{Mx[:gr_o]}Th#{Mx[:tc_p]}/u +        parablock=parablock.gsub(/#{Mx[:gr_o]}Th?#{Mx[:tc_p]}.+?#{Mx[:tc_p]}~(\d+)#{Mx[:gr_c]}/, +          %{<table summary="normal text css" width="100%" border="0" cellpadding="2" align="center">}) +        if parablock =~/#{Mx[:gr_o]}TZ#{Mx[:gr_c]}/ +          tablefoot=[] +          @@tablefoot.each {|x| tablefoot << %{<p align="center"><font size=2><i>#{x}</i></font></p>\n}} +          @@tablefoot=[] +          parablock=parablock.gsub(/#{Mx[:gr_o]}TZ#{Mx[:gr_c]}/, +            %{#{the_table_close}\n}) # + +        end +        if @@tablehead==1 +          if parablock =~/#{Mx[:tc_p]}#{Mx[:tc_p]}/u +            parablock=parablock.gsub(/#{Mx[:tc_o]}#{Mx[:tc_p]}#{Mx[:tc_p]}(\d+?)#{Mx[:tc_p]}/u, +                %{\n<tr>} + +                %{\n<td width="\\1%" valign="top">} + +                %{#{para_table}<b>}). +              gsub(/#{Mx[:tc_p]}#{Mx[:tc_p]}(\d+?)#{Mx[:tc_p]}/u, +                %{</b></td><td width="\\1%" valign="top">} + +                %{#{para_table}<b>}). +              gsub(/#{Mx[:tc_c]}/, '</b></td></tr>') +            @@tablehead=0 +          end +          parablock +        else +          parablock=parablock.gsub(/#{Mx[:tc_o]}#{Mx[:tc_p]}#{Mx[:tc_p]}(\d+?)#{Mx[:tc_p]}/u, +              %{\n<tr>} + +              %{\n<td width="\\1%" valign="top">} + +              %{#{para_table}}). +            gsub(/#{Mx[:tc_p]}#{Mx[:tc_p]}(\d+?)#{Mx[:tc_p]}/u, +              %{</td><td width="\\1%" valign="top">} + +              %{#{para_table}}). +            gsub(/#{Mx[:tc_c]}/, '</td></tr>') +          parablock +        end +        @new_content << parablock +      end +      @new_content.join +    end +  end +  class CSS_FormatGeneric #does CSS_Format in one definition, needs to be told about attrib, despite brevity of generic, easier to see structure with CSS_Format +    def initialize(attrib='',txt='',id=nil,ocnd=nil,ocns=nil,lv='',hname=nil) +      @tab="\t" +      @attrib=attrib +      @txt=txt +      @lv=lv.to_s +      @hname=hname.to_s +      @id=@ocn=id +    end +    def paragraph +      attrib=%{class="#{@attrib}" } +      if @ocn +        id=%{id="#{Mx[:ocn_id_char]}#{@ocn}" } +        type=%{type="substantive" } +      else +        id='' +        type=%{type="comment" } +      end +      header=%{header="#{@hname}" } if @hname +      %{<p #{attrib}#{type}#{header}>#{@txt}</p>\n} #<< "\n" +    end +    def para +      paragraph +    end +  end +end +__END__ +#+END_SRC + +*** html_table.rb + +#+BEGIN_SRC ruby  :tangle "../lib/sisu/html_table.rb" +# <<sisu_document_header>> +module SiSU_HTML_Table +  require_relative 'xhtml_table'                         # xhtml_table.rb +  require_relative 'html_parts'                          # html_parts.rb +  class TableHTML < SiSU_XHTML_Table::TableXHTML +    include SiSU_Parts_HTML +  end +end +__END__ +#+END_SRC + +#+RESULTS: + +** misc +*** html_minitoc.rb + +#+BEGIN_SRC ruby  :tangle "../lib/sisu/html_minitoc.rb" +# <<sisu_document_header>> +module SiSU_HTML_MiniToc +  require_relative 'html_tune'                        # html_tune.rb +    include SiSU_HTML_Tune +  class TocMini +    @@seg_mini=nil +    @@seg_url='' +    @@firstseg=nil +    def initialize(md,data) +      @md,@data=md,data +      @pat_strip_heading_name=/<a name="h?\d.*?">(.+?)<\/a>/ +      @tell=SiSU_Screen::Ansi.new(@md.opt.act[:color_state][:set]) if @md +    end +    def songsheet +      if (@md.opt.act[:verbose][:set]==:on \ +      || @md.opt.act[:verbose_plus][:set]==:on \ +      || @md.opt.act[:maintenance][:set]==:on) +        SiSU_Screen::Ansi.new(@md.opt.act[:color_state][:set],'Toc').txt_grey +      end +      toc=nil +      @toc=[] +      @data.each do |txt| +        if txt.is ==:heading \ +        || txt.is ==:heading_insert +          txt.obj=txt.obj.gsub(/(?:#{Mx[:en_a_o]}|#{Mx[:en_b_o]}).+?(?:#{Mx[:en_a_c]}|#{Mx[:en_b_c]})/m,''). #remove endnotes from toc +            gsub(/<a name="-\d+" href="#_\d+"> <sup>\d+<\/sup> <\/a>/,''). +            gsub(@pat_strip_heading_name,'\1') +            #gsub(/(.*?)<a name="(\d+)"><\/a>(.*)/,'\1') #2002w42 altered gsub - problematic? - suspect +          toc=case txt.ln +          when 0 then SiSU_HTML_MiniToc::TocMini.new(@md,txt).level_0 +          when 1 then SiSU_HTML_MiniToc::TocMini.new(@md,txt).level_1 +          when 2 then SiSU_HTML_MiniToc::TocMini.new(@md,txt).level_2 +          when 3 then SiSU_HTML_MiniToc::TocMini.new(@md,txt).level_3 +          when 4 then SiSU_HTML_MiniToc::TocMini.new(@md,txt).level_4 +          when 5 then SiSU_HTML_MiniToc::TocMini.new(@md,txt).level_5 +          when 6 then SiSU_HTML_MiniToc::TocMini.new(@md,txt).level_6 +          else +          end +          @toc << toc +        end +      end +      @toc +    end +  protected +    def level_concordance +      format_head_toc=SiSU_HTML_Format::HeadToc.new(@md) +      @@seg_mini << format_head_toc.mini_seg_concordance +    end +    def level_metadata +      format_head_toc=SiSU_HTML_Format::HeadToc.new(@md) +      @@seg_mini << format_head_toc.mini_seg_metadata +    end +    def level_word_index +      format_head_toc=SiSU_HTML_Format::HeadToc.new(@d0c) +      @@seg_mini << format_head_toc.mini_concordance +    end +    def level_0 +      txt=@data +      if (txt.is ==:heading \ +      || txt.is ==:heading_insert) \ +      && txt.ocn !=0 +        txt.obj=txt.obj.gsub(@pat_strip_heading_name,'\1') +      end +      txt_obj={ txt: txt.obj } +      format_toc=SiSU_HTML_Format::FormatToc.new(@md,txt_obj) +      toc_mini=format_toc.mini_lev0 +      toc_mini +    end +    def level_1 +      txt=@data +      if (txt.is ==:heading \ +      || txt.is ==:heading_insert) \ +      && txt.ocn !=0 +        txt.obj=txt.obj.gsub(@pat_strip_heading_name,'\1') +      end +      title=unless txt.obj =~/Document Information/ then txt.obj +      else +        link='metadata' +        %{<b><a href="#{link}#{@md.lang_code_insert}#{Sfx[:html]}">#{txt.obj}</a></b>} +      end +      txt_obj={ txt: title } +      format_toc=SiSU_HTML_Format::FormatToc.new(@md,txt_obj) +      toc_mini=if txt.name =~/^meta/ \ +      and txt.obj=~/Document Information/ +        format_toc.mini_tail +      else format_toc.mini_lev1 +      end +      toc_mini +    end +    def level_2 +      txt=@data +      if (txt.is ==:heading \ +      || txt.is ==:heading_insert) \ +      && txt.ocn !=0 +        txt.obj=txt.obj.gsub(@pat_strip_heading_name,'\1') +      end +      txt_obj={ txt: txt.obj } +      format_toc=SiSU_HTML_Format::FormatToc.new(@md,txt_obj) +      toc_mini=format_toc.mini_lev2 +      toc_mini +    end +    def level_3 +      txt=@data +      txt_obj={ txt: txt.obj } +      format_toc=SiSU_HTML_Format::FormatToc.new(@md,txt_obj) +      toc_mini=format_toc.mini_lev3 +      toc_mini +    end +    def level_4 +      txt=@data +      unless txt.obj =~/~metadata/ +        if txt.ln ==4 +          fnh={ +            fn: txt.name, +          } +          f=@md.file.base_filename.html_seg(fnh) +          seg_link=%{  <a href="#{f}" target="_top"> +    #{txt.obj} +  </a> } +          @@seg_url=txt.name +        elsif txt.obj =~/\d+.\d+.\d+.\d+|\d+.\d+.\d+|\d+.\d+|\d+/ +          fn,hd=/^(\d+.\d+.\d+.\d+|\d+.\d+.\d+|\d+.\d+|\d+)(.*)/.match(dob.obj)[1,2] +          fnh={ +            fn: fn, +          } +          f=@md.file.base_filename.html_seg(fnh) +          seg_link=%{<a href="#{f}" target="_top">#{fn} #{hd}</a> } +        end +        txt_obj={ txt: seg_link } +        format_toc=SiSU_HTML_Format::FormatToc.new(@md,txt_obj) +        toc_mini=format_toc.mini_lev4 +        toc_mini +      end +    end +    def level_5 +      txt=@data +      if (txt.is ==:heading \ +      || txt.is ==:heading_insert) \ +      && txt.ocn !=0 +        txt.obj=txt.obj.gsub(@pat_strip_heading_name,'\1') +      end +      fnh={ +        fn: @@seg_url, +      } +      f=@md.file.base_filename.html_seg(fnh) +      lnk_n_txt=%{  <a href="#{f}##{txt.ocn}"> +    #{txt.obj} +  </a>} +        txt_obj={ txt: lnk_n_txt } +        format_toc=SiSU_HTML_Format::FormatToc.new(@md,txt_obj) +        toc_mini=format_toc.mini_lev5 +      toc_mini +    end +    def level_6 +      txt=@data +      if (txt.is ==:heading \ +      || txt.is ==:heading_insert) \ +      && txt.ocn !=0 +        txt.obj=txt.obj.gsub(@pat_strip_heading_name,'\1') +      end +      fnh={ +        fn: @@seg_url, +      } +      f=@md.file.base_filename.html_seg(fnh) +      lnk_n_txt=%{  <a href="#{f}##{txt.ocn}"> +    #{txt.obj} +  </a>} +        txt_obj={ txt: lnk_n_txt } +        format_toc=SiSU_HTML_Format::FormatToc.new(@md,txt_obj) +        toc_mini=format_toc.mini_lev6 +      toc_mini +    end +  end +end +__END__ +#+END_SRC + +*** html_concordance.rb + +#+BEGIN_SRC ruby  :tangle "../lib/sisu/html_concordance.rb" +# <<sisu_document_header>> +module SiSU_Concordance +  require_relative 'se_hub_particulars'                 # se_hub_particulars.rb +    include SiSU_Particulars +  require_relative 'se'                                 # se.rb +    include SiSU_Env +  require_relative 'html_format'                        # html_format.rb +    include SiSU_HTML_Format +  require_relative 'html_minitoc'                       # html_minitoc.rb +  class Source +    def initialize(opt) +      @opt=opt +      @particulars=SiSU_Particulars::CombinedSingleton.instance.get_all(opt) +    end +    def read +      begin +        @env,@md=@particulars.env,@particulars.md +        @env.url.output_tell +        unless @md.opt.act[:quiet][:set]==:on +          tool=(@md.opt.act[:verbose][:set]==:on \ +          || @md.opt.act[:verbose_plus][:set]==:on \ +          || @md.opt.act[:maintenance][:set]==:on) \ +          ? "#{@env.program.web_browser} #{@md.file.output_path.html_concordance.dir}/#{@md.file.base_filename.html_concordance}" +          : "[#{@opt.f_pth[:lng_is]}] #{@opt.fno}" +          (@md.opt.act[:verbose][:set]==:on \ +          || @md.opt.act[:verbose_plus][:set]==:on \ +          || @md.opt.act[:maintenance][:set]==:on) \ +          ? SiSU_Screen::Ansi.new( +              @opt.act[:color_state][:set], +              "Concordance", +              tool +            ).green_hi_blue +          : SiSU_Screen::Ansi.new( +              @opt.act[:color_state][:set], +              'Concordance', +              tool +            ).green_title_hi +        end +        wordmax=@env.concord_max +        unless @md.wc_words.nil? +          if @md.wc_words < wordmax +            SiSU_Concordance::Source::Words.new(@particulars).songsheet +          else +            SiSU_Screen::Ansi.new( +              @md.opt.act[:color_state][:set], +              "concordance skipped, large document has over #{wordmax} words (#{@md.wc_words})" +            ).warn unless @md.opt.act[:quiet][:set]==:on +          end +        else +          SiSU_Screen::Ansi.new( +            @md.opt.act[:color_state][:set], +            "wc (word count) is off, concordance will be processed for all files including those over the max set size of: #{wordmax} words" +          ).warn unless @md.opt.act[:quiet][:set]==:on +          SiSU_Concordance::Source::Words.new(@particulars).songsheet +        end +      rescue +        SiSU_Errors::Rescued.new($!,$@,@md.opt.selections.str,@md.fns).location do +          __LINE__.to_s + ':' + __FILE__ +        end +      ensure +        SiSU_Env::CreateSite.new(@opt).cp_css +        Dir.chdir(@opt.f_pth[:pth]) +      end +    end +    private +    class DocTitle +      #revisit, both requires (html & xml_shared) needed for stand alone operation (sisu -w [filename]) +      require_relative 'xml_shared'                     # xml_shared.rb +      require_relative 'html'                           # html.rb +      def initialize(particulars) +        @particulars,@md=particulars,particulars.md +        @data=SiSU_HTML::Source::HTML_Environment.new(particulars).tuned_file_instructions +        @file=SiSU_Env::FileOp.new(@md) +        @fnb=@md.fnb +        @lex_button=%{<a href="http://www.jus.uio.no/sisu/" target="_top"><img border="0" height="44" width="144" valign="center" src="#{@file.path_rel_links.html_seg_2}_sisu/image/sisu.png" alt="SiSU home -->"></a>} +        @doc_details =<<WOK +<table summary="links to text related to this rudimentary index" width="96%" border="0" cellpadding="0" align="center"><tr><td width="2%" align="right"> </td><td width="94%" valign="top" align="justify"><h1 class="small"><a href="#{@md.file.base_filename.html_segtoc}"><b>#{@md.title.full}</b></a></h1><p class="bold">#{@md.author}</p></td></tr></table> +WOK +        @make=SiSU_Env::ProcessingSettings.new(@md) +      end +      def create +        head_banner=SiSU_HTML_Format::HeadToc.new(@md) +        minitoc=SiSU_HTML_MiniToc::TocMini.new(@md,@data).songsheet.join("\n") +        stylesheet=SiSU_Style::CSS_HeadInfo.new(@md).stylesheet +        if @make.build.manifest_minitoc? +          toc='<div class="toc">' + minitoc + '</div>' +          div_class='content' +        else +          toc='' +          div_class='content0' +        end +        top_band=if @make.build.html_top_band? +          head_banner.concordance_navigation_band +        else '' +        end +        <<WOK +<!DOCTYPE html> +<html> +<head> +  <meta charset="utf-8"> +  <title> +    SiSU created WordIndex for: #{@md.title.full} +  </title> +  <meta http-equiv="Content-Type" content="text/html;charset=utf-8" /> +  <meta name="Description" content=" SiSU created"> +  <meta name="keywords" content="word index for #{@md.title.full}"> +  <meta name="generator" content="SiSU (Linux & Ruby!)"> +  <link rel="generator" href="http://www.jus.uio.no/sisu" /> +  <link rel="shortcut icon" href="../_sisu/image/rb7.ico" /> +  #{stylesheet.css_head_seg} +</head> +<body> +  #{top_band} +  #{toc} +<div class="#{div_class}"> + #{@doc_details} +<p>Word index links are to html versions of the text the segmented version followed by the scroll (single document) version.<br>[For segmented text references [T1], [T2] or [T3] appearing without a link, indicates that the word appears in a title (or subtitle) of the text (that is identifiable by the appended object citation number).]</p> +<p>(The word listing/index is Case sensitive: Capitalized words appear before lower case)</p> +  <p> +    <b>word</b> (number of occurences)<br>linked references to word within document <br> +    [if number of occurences exceed number of references - word occurs more than once in at least one reference. Footnote/endnotes are either assigned to the paragraph from which they are referenced or ignored, so it is relevant to check the footnotes referenced from within a paragraph as well.] +  </p> +  <p> +    (After the page is fully loaded) you can jump directly to a word by appending a hash (#) and the word to the url for this text, (do not forget that words are case sensitive, and may be listed twice (starting with and without an upper case letter)), #your_word # [ http://[web host]/#{@fnb}/concordance.html#your_word ] +  </p> +WOK +      end +    end +    class Word +      @@word_previous='' +      def initialize(word,freq) +        @word,@freq=word,freq +      end +      def html +        w=if @word.capitalize==@@word_previous +          %{\n<p class="concordance_word">#{@word}</p><p class="concordance_count">(#{@freq})</p>\n\t<p class="concordance_object"> } +        else n=@word.strip.gsub(/\s+/,'_') #also need to convert extended character set to html +          %{\n<p class="concordance_word"><a name="#{n}">#{@word}</a></p><p class="concordance_count">(#{@freq})</p>\n\t<p class="concordance_object"> } +        end +        @@word_previous=@word.capitalize +        w +      end +    end +    class Words +      require_relative 'i18n'                           # i18n.rb +        include SiSU_i18n +      require_relative 'html_format'                    # html_format.rb +        include SiSU_HTML_Format +      require_relative 'se'                             # se.rb +        include SiSU_Screen +      @@dp=nil +      def initialize(particulars) +        @particulars=particulars +        begin +          @env,@md,@ao_array=particulars.env,particulars.md,particulars.ao_array +          @file=SiSU_Env::FileOp.new(@md) +          @freq=Hash.new(0) +          @dp=@@dp ||=SiSU_Env::InfoEnv.new.digest.pattern +          @rxp_lv1=/^#{Mx[:lv_o]}1:/ #fix @rxp_lv #  Mx[:lv_o] +          @rxp_lv2=/^#{Mx[:lv_o]}2:/ #fix @rxp_lv #  Mx[:lv_o] +          @rxp_lv3=/^#{Mx[:lv_o]}3:/ #fix @rxp_lv #  Mx[:lv_o] +          @rxp_title=Regexp.new("^#{Mx[:meta_o]}title#{Mx[:meta_c]}\s*(.+?)\s*$") +          @rxp_t1=Regexp.new('^T1') +          @rxp_t2=Regexp.new('^T2') +          @rxp_t3=Regexp.new('^T3') +          @rxp_excluded1=/#{Mx[:url_o]}\S+?#{Mx[:url_c]}|#{Mx[:rel_o]}\S+?#{Mx[:rel_c]}/ +          @rxp_excluded0=/^(?:#{Mx[:fa_bold_o]}|#{Mx[:fa_italics_o]})?(?:to\d+|\d+| |#{Mx[:br_endnotes]}|EOF|#{Mx[:br_eof]}|thumb_\S+|snap_\S+|_+|-+|[(]?(?:ii+|iv|vi+|ix|xi+|xiv|xv|xvi+|xix|xx)[).]?|\S+?_\S+|[\d_]+\w\S+|[\w\d]{1,2}|\d{1,3}\w?|#{@dp}|[0-9a-f]{16,64}|\d{2,3}x\d{2,3}|\S{0,2}sha\d|\S{0,3}\d{4}w\d\d|\b\w\d+|\d_all\b|e\.?g\.?)(?:#{Mx[:fa_bold_c]}|#{Mx[:fa_italics_c]})?$/mi #this regex causes and cures a stack dump in ruby 1.9 !!! +          @rgx_splitlist=%r{[—.,;:#{Mx[:nbsp]}-]}mi +          @alph=SiSU_i18n::Alphabet.new(@md.opt.lng).hash_arrays +          @alphlst=SiSU_i18n::Alphabet.new(@md.opt.lng).hash_strings +          @rgx_scanlist=%r{#{Mx[:fa_italics_o]}[#{@alphlst[:l]}#{@alphlst[:u]}0-9"\s]{2,12}#{Mx[:fa_italics_c]}|#{Mx[:fa_bold_o]}[#{@alphlst[:l]}#{@alphlst[:u]}0-9"\s]{2,12}#{Mx[:fa_bold_c]}|(?:https?|file)://\S+|<\S+?>|[#{@alphlst[:l]}#{@alphlst[:u]}]+|\w+}mi +        rescue +          SiSU_Errors::Rescued.new($!,$@,@md.opt.selections.str,@md.fns).location do +            __LINE__.to_s + ':' + __FILE__ +          end +        end +      end +      def songsheet +        begin +          FileUtils::mkdir_p(@file.output_path.html_concordance.dir) \ +            unless FileTest.directory?(@file.output_path.html_concordance.dir) +          @file_concordance=File.open(@file.place_file.html_concordance.dir,'w') +          map_para +        rescue +          SiSU_Errors::Rescued.new($!,$@,@md.opt.selections.str,@md.fns).location do +            __LINE__.to_s + ':' + __FILE__ +          end +        ensure +          @file_concordance.close +        end +      end +    protected +      def location_scroll(wordlocation,show)                    # not used +        %{<a href="doc#{@md.lang_code_insert}#{Sfx[:html]}\##{Mx[:ocn_id_char]}#{wordlocation}">#{wordlocation}</a>;  } +      end +      def location_seg(wordlocation,show) +        unless wordlocation.nil? +          wl=wordlocation.gsub(/(.+?)\#(\d+)/, +            "\\1#{@md.lang_code_insert}#{Sfx[:html]}##{Mx[:ocn_id_char]}\\2")     # id="o\d+" always available; a name="\d+" not available if html strict used +          case wordlocation +          when /#{@rxp_t1}|@rxp_t2}|#{@rxp_t3}/ +            %{[<a href="doc#{@md.lang_code_insert}#{Sfx[:html]}##{show}">H</a>]#{show},  } +          when /(.+?)\#(\d+)/ +             %{<a href="#{wl}">#{show}</a>,  } +          end +        end +      end +      def map_para +        @seg,ocn=nil,nil +        @word_map={} +        @ao_array.each do |line| +          if defined? line.ocn \ +          and line.ocn.to_s =~/\d/ +            if (line.is ==:heading \ +            || line.is ==:heading_insert) \ +            && line.ln==4 +              @seg=line.name +            end +            ocn=line.ocn.to_s +            if ocn =~/\d+/ \ +            and ocn !~/^0$/ +              line.obj=line.obj.gsub(/#{@rxp_excluded1}/,' ') +              line.obj=line.obj.split(@rgx_splitlist).join(' ') #%take in word or other match +              for word in line.obj.scan(@rgx_scanlist) #%take in word or other match +                if word =~ /^([#{@alphlst[:l]}])/ +                  firstletter=$1 +                  flu=firstletter.tr(@alphlst[:l],@alphlst[:u]) +                  word=word.gsub(/^#{firstletter}/,flu ) +                end +                word=word.gsub(/#{Mx[:lnk_o]}|#{Mx[:lnk_c]}|#{Mx[:url_o]}|#{Mx[:url_c]}/,''). +                  gsub(/#{Mx[:fa_o]}\S+?#{Mx[:fa_o_c]}/,''). +                  gsub(/#{Mx[:fa_c_o]}\S+?#{Mx[:fa_c]}/,''). +                  gsub(/#{Mx[:gl_o]}#[a-z]+#{Mx[:gl_c]}/,''). +                  gsub(/#{Mx[:gl_o]}#[0-9]+#{Mx[:gl_c]}/,'') +                word=word.gsub(/[0-9a-f]{10,}/,' ') if word =~/[0-9]/ +                word=word.gsub(/#{Mx[:br_line]}/,' '). +                  gsub(/^ +/,''). +                  gsub(/^\S$/,'') +                word=nil if word.empty? +                word=nil if word =~@rxp_excluded0 #watch +                word=nil if word =~/^\S$/ +                if word +                  word=word.gsub(/#{Mx[:br_nl]}|#{Mx[:br_line]}/,' '). +                    gsub(/#{Mx[:fa_o]}[a-z]{1,7}#{Mx[:fa_o_c]}|#{Mx[:fa_c_o]}[a-z]{1,7}#{Mx[:fa_c]}/,''). +                    gsub(/#{Mx[:en_a_o]}(?:\d|[*+])*|#{Mx[:en_b_o]}(?:\d|[*+])*|#{Mx[:en_a_c]}|#{Mx[:en_b_c]}/mi,''). +                    gsub(/#{Mx[:fa_o]}\S+?#{Mx[:fa_o_c]}/,''). +                    gsub(/#{Mx[:fa_c_o]}\S+?#{Mx[:fa_c]}/,''). +                    gsub(/<\/?\S+?>/,''). +                    gsub(/^\@+/,''). +                    strip. +                    gsub(/#{Mx[:tc_p]}.+/,''). +                    gsub(/[\.,;:"]$/,''). +                    gsub(/["]/,''). +                    gsub(/^\s*[\(]/,''). +                    gsub(/[\(]\s*$/,''). +                    gsub(/^(?:See|e\.?g\.?).+/,''). +                    gsub(/^\s*[.,;:]\s*/,''). +                    strip. +                    gsub(/^\(?[a-zA-Z]\)$/,''). +                    gsub(/^\d+(st|nd|rd|th)$/,''). +                    gsub(/^(\d+\.?)+$/, ''). +                    gsub(/#{Mx[:mk_o]}|#{Mx[:mk_c]}/,''). +                    gsub(/:name#\S+/,''). +                    gsub(/^\S$/,'') +                  word=nil if word =~/^\S$/ +                  word=nil if word =~/^\s*$/ #watch +                  if word +                    unless word =~/[A-Z][A-Z]/ \ +                    or word =~/\w+\s\w+/ +                      word=word.capitalize +                    end +                    @freq[word] +=1 +                    @word_map[word] ||= [] +                    if line !~ /#{@rxp_lv1}|#{@rxp_lv2}|#{@rxp_lv3}/ +                      loc_=%{#{location_seg("#{@seg}\##{ocn}",ocn).to_s}} +                      unless loc_.empty? +                        @word_map[word] << loc_ +                      end +                    else +                      @word_map[word] << case line +                      when @rxp_lv1 then location_seg('T1',ocn) #fix @rxp_lv #  Mx[:lv_o] +                      when @rxp_lv2 then location_seg('T2',ocn) #fix @rxp_lv #  Mx[:lv_o] +                      when @rxp_lv3 then location_seg('T3',ocn) #fix @rxp_lv #  Mx[:lv_o] +                      end +                    end +                  end +                end +              end +            end +          end +        end +        seg='' +        head=SiSU_Concordance::Source::DocTitle.new(@particulars).create +        head=head.gsub(/#{Xx[:html_relative2]}/m,@file.path_rel_links.html_seg_2). +          gsub(/#{Xx[:html_relative1]}/m,@file.path_rel_links.html_seg_1) +        @file_concordance << head +        @file_concordance << '<p>' +        alph=@alph[:u] +        alph.each {|x| @file_concordance << %{<a href="##{x}">#{x}</a>, }} +        @file_concordance << '</p>' +        letter=alph.shift +        @file_concordance << %{\n<p class="letter"><a name="A">A</a></p>} +        for word in @freq.keys.sort! {|a,b| a.downcase<=>b.downcase} +          f=/^(\S)/.match(word)[1] +          if letter < f.upcase +            while letter < f.upcase +              if alph.length > 0 +                letter=alph.shift +                @file_concordance << %{\n<p class="letter"><a name="#{letter}">#{letter}</a></p>} +              else break +              end +            end +          end +          keyword=SiSU_Concordance::Source::Word.new(word,@freq[word]).html +          if keyword !~ @rxp_excluded0 +            if @word_map[word][0] =~ /\d+/ +              @file_concordance << %{#{keyword}#{seg}#{@word_map[word].uniq.compact.join}} +            end +            @file_concordance << '</p>' +          end +          # special cases endnotes and header levels 1 - 3 +        end +        @file_concordance << %{</div></body>\n</html>} # footer +        if @md.opt.act[:verbose_plus][:set]==:on \ +        || @md.opt.act[:maintenance][:set]==:on +          SiSU_Screen::Ansi.new( +            @md.opt.act[:color_state][:set], +            @md.fns, +            "#{@md.file.output_path.html_concordance.dir}/#{@md.file.base_filename.html_concordance}" +          ).flow +        end +      end +    end +  end +end +__END__ +#+END_SRC + +*** html_manifest.rb + +#+BEGIN_SRC ruby  :tangle "../lib/sisu/html_manifest.rb" +# <<sisu_document_header>> +module SiSU_Manifest +  require_relative 'se'                                 # se.rb +    include SiSU_Env +  require_relative 'prog_text_translation'              # prog_text_translation.rb +  require_relative 'se_hub_particulars'                 # se_hub_particulars.rb +    include SiSU_Particulars +  require_relative 'html_parts'                         # html_parts.rb +  require_relative 'html_minitoc'                       # html_minitoc.rb +  require_relative 'html'                               # html.rb +    include SiSU_HTML_Format +  require_relative 'dp'                                 # dp.rb +    include SiSU_Param +  require_relative 'i18n'                               # i18n.rb +  class Source +    def initialize(opt) +      @opt=opt +      @particulars=SiSU_Particulars::CombinedSingleton.instance.get_all(opt) +      l=SiSU_Env::StandardiseLanguage.new(opt.lng).language +      @doc_language=l[:n] +    end +    def read +      begin +        @env=SiSU_Env::InfoEnv.new(@opt.fns) +        @md=SiSU_Param::Parameters.new(@opt).get +        xbrowser=@env.program.web_browser +        browser=@env.program.console_web_browser +#       webserv_url=@env.path.url.output_tell #fix in sysenv +        unless @opt.act[:quiet][:set]==:on +          url_html='file://' \ +          + @md.file.output_path.manifest.dir + '/' \ +          + @md.file.base_filename.manifest +          (@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], +              'Manifest', +              "#{xbrowser} #{url_html}" +            ).green_hi_blue +          : SiSU_Screen::Ansi.new( +              @opt.act[:color_state][:set], +              'Manifest', +              "[#{@opt.f_pth[:lng_is]}]", +              "#{url_html}" +            ).grey_title_grey_blue +          if (@md.opt.act[:verbose][:set]==:on \ +          || @md.opt.act[:verbose_plus][:set]==:on) +            SiSU_Screen::Ansi.new( +              @opt.act[:color_state][:set], +              "#{browser} #{url_html}" +            ).grey_tab +          end +        end +        data=SiSU_HTML::Source::HTML_Environment.new(@particulars).tuned_file_instructions +        SiSU_Manifest::Source::Output.new(@md).check_output(data) +      rescue +        SiSU_Errors::Rescued.new($!,$@,@opt.selections.str,@opt.fns).location do +          __LINE__.to_s + ':' + __FILE__ +        end +      ensure +        SiSU_Env::CreateSite.new(@opt).cp_css +        Dir.chdir(@opt.f_pth[:pth]) +      end +    end +    private +    class Output <Source +      include SiSU_Parts_HTML +      def initialize(md) +        @manifest={ txt: [], html: [] } +        @md,@fns=md,md.fns +        @env=SiSU_Env::InfoEnv.new(md.fns) +        @f=SiSU_Env::FileOp.new(md) +        @fnb=md.fnb +        @base_url="#{@env.url.root}/#{@fnb}" +        @o_str=SiSU_Env::FileOp.new(md).output_dir_structure +        @image_path=(@o_str.dump_or_redirect?) \ +        ? './image' +        : %{#{@f.path_rel_links.html_scroll_2}_sisu/image_sys} +        @base_path=@f.output_path.manifest.dir +        @@dg ||=SiSU_Env::InfoEnv.new(md.fns,md).digest(md.opt).type +        @dg=@@dg +        l=SiSU_Env::StandardiseLanguage.new(md.opt.lng).language +        @language=l[:n] +        @translate=SiSU_Translate::Source.new(md,@language) +        @stylesheet=SiSU_Style::CSS_HeadInfo.new(md).stylesheet +        @fn_lng=(@f.output_dir_structure.by_language_code?) \ +        ? '' +        : ('.' + md.opt.lng) +      end +      def output +        manifest=@f.write_file.manifest +        @manifest[:html].each do |x| +          x=x.gsub(Xx[:html_relative2],@f.path_rel_links.html_scroll_2). +            gsub(Xx[:html_relative1],@f.path_rel_links.html_scroll_1) +          manifest << x +        end +      end +      def url_make(url,file,src=nil) +        if @o_str.dump_or_redirect? +          '' +        elsif src==:src #check +          %{<br>#{the_url_decoration.xml_open}<a href="#{url}/#{file}">#{url}/#{file}</a>#{the_url_decoration.xml_close}} +        else +          %{<p class="tiny">#{the_url_decoration.xml_open}<a href="#{url}/#{file}">#{url}/#{file}</a>#{the_url_decoration.xml_close}</p>} +        end +      end +      def summarize(desc,id,file,pth='',rel='',url='',img='● ') +        size=(File.size("#{pth}/#{file}")/1024.00).to_s +        kb=/([0-9]+\.[0-9]{0,1})/m.match(size)[1] +        @manifest[:txt] << "#{file} #{desc} #{kb}\n" +        @manifest[:html] << %{<tr><th class="left"><p class="norm"><a href="#{rel}/#{file}">#{img}#{desc}</a></p></th><td><p class="small"><a href="#{rel}/#{file}">#{file}</a></p>#{url_make(url,file)}</td><td class="right"><p class="right">#{kb}</p></td></tr>\n} +      end +      def summarize_html_seg(desc,id,file,pth='',rel='',url='',img='● ') +        size=(File.size("#{pth}/#{file}")/1024.00).to_s +        kb=/([0-9]+\.[0-9]{0,1})/m.match(size)[1] +        @manifest[:txt] << "#{file} #{desc} #{kb}\n" +        @manifest[:html] << %{<tr><th class="left"><p class="norm"><a href="#{rel}/#{file}">#{img}#{desc}</a></p></th><td><p class="small"><a href="#{rel}/#{file}">#{file}</a></p>#{url_make(url,file)}</td><td class="right"><p class="right">#{kb}</p></td></tr>\n} +      end +      def summarize_sources(desc,id,file,pth,rel,url) +        sys=SiSU_Env::SystemCall.new +        dgst=case @dg +        when :sha512 +          sys.sha512("#{pth}/#{file}") +        when :sha256 +          sys.sha256("#{pth}/#{file}") +        when :md5 +          sys.md5("#{pth}/#{file}") +        else +        end +        dgst=dgst ? dgst : [ '', 'n/a' ] +        if (@md.opt.act[:verbose][:set]==:on \ +        || @md.opt.act[:verbose_plus][:set]==:on \ +        || @md.opt.act[:maintenance][:set]==:on) +          SiSU_Screen::Ansi.new( +            @md.opt.act[:color_state][:set], +            "#{dgst[1]} #{file}" +          ).warn +        end +        size=(File.size("#{pth}/#{file}")/1024.00).to_s +        kb=/([0-9]+\.[0-9]{0,1})/m.match(size)[1] +        @manifest[:txt] << "#{file} #{desc} #{kb}\n" +        @manifest[:html] << %{<tr>} \ +        + %{<th class="left"><p class="norm" id="#{id}"><a href="#{rel}/#{file}">#{desc}</a></p></th>} \ +        + %{<td class="right"><p class="tiny"><a href="#{rel}/#{file}">#{file}</a>   #{dgst[1]}#{url_make(url,file,:src)}</p></td>} \ +        + %{<td class="right"><p class="right">#{kb}</p></td>} \ +        + %{</tr>\n} \ +          if kb and kb =~/\d+/ +      end +      def published_manifests? +        @f=SiSU_Env::FileOp.new(@md) #.base_filename +        @m=[] +        url=@f.output_path.base.url +        manifests={} +        mp,mn,mt,mr=nil,nil,nil,nil +        ln=SiSU_i18n::Languages.new.language.list +        Px[:lng_lst].each do |lc| +          lngc=SiSU_Env::FilenameLanguageCodeInsert.new(@md.opt,lc).language_code_insert +          fnh={ +             fn: @md.fnb, +             lng: lngc, +          } +          mn=@f.base_filename.manifest(fnh) +          if @o_str.dump_or_redirect? #does not work for --redirect or --dump +            mp="#{@f.output_path.base.dir}" +            mt="#{mp}/#{mn}" +            mr="../../#{lc}/manifest/#{mn}" +            mu="#{url}/#{mn}" +          elsif @f.output_dir_structure.by_language_code? +            mp="#{@f.output_path.base.dir}/#{lc}/manifest" +            mt="#{mp}/#{mn}" +            mr="../../#{lc}/manifest/#{mn}" +            mu="#{url}/#{lc}/manifest/#{mn}" +          elsif @f.output_dir_structure.by_filetype? +            mp="#{@f.output_path.base.dir}/manifest" +            mt="#{mp}/#{mn}" +            mr=mn +            mu="#{url}/manifest/#{mn}" +          else +            mp="#{@f.output_path.base.dir}/#{@md.fnb}" +            mt="#{mp}/#{mn}" +            mr=mn +            mu="#{url}/#{mn}" +          end +          if FileTest.directory?(mp) \ +          &&  FileTest.file?(mt) +            lng=ln[lc][:t] +            manifests[lc]={ ln: lng, fn: mn, rel: mr } +            @m << { mu: mu, l: lng, rel: mr } +          end +        end +        @m=@m.uniq +      end +      def languages(desc,file) +        @manifest[:html] << %{<tr><th class="left"><div id="horizontal_links"><ul id="horizontal">\n} +        published_manifests?.each do |l| +          SiSU_Translate::Source.new(@md,@language,l[:n]).language_list +          @manifest[:txt] << "#{l[:mu]} #{l[:l]}\n" +          @manifest[:html] << %{<li class="norm"><a href="#{l[:rel]}">#{l[:l]}</a>   </li>} +        end +        @manifest[:html] << %{</ul></div></th></tr>\n} +      end +      def published_languages(desc) +        published_manifests?.each do |l| +          @manifest[:txt] << "#{l[:mu]} #{l[:l]}\n" +          @manifest[:html] << %{<tr><th class="left"><p class="bold"><a href="#{l[:mu]}">#{l[:l]}</a></p></th><td><p class="norm">#{l[:l]}</p><p class="tiny">#{the_url_decoration.xml_open}<a href="#{l[:mu]}">#{l[:mu]}</a>#{the_url_decoration.xml_close}</p></td><td class="right"><p class="right"> </p></td></tr>\n} +        end +      end +      def metadata(desc,id,info) +        info=info.to_s.gsub(/(?:#{Mx[:br_line]}|\\)+/,'<br>') +        @manifest[:html] << %{<tr><th class="left"><p class="bold_left" id="#{id}">#{desc}:</p></th><td><p class="left">#{info}</p></td></tr>\n} +      end +      def links(url,lnk,target) +        static=if url =~/^\.\// then url.gsub(/^\.(\.)?/,@base_url) +        elsif url =~/^\.\.\//   then url.gsub(/^\.(\.)?/,@env.url.root) +        else                         url +        end +        @manifest[:html] << %{<tr><th class="right" width=5%><p class="norm">●</p></th><td class="left"><p class="norm"><a href="#{url}">#{lnk}</a></p><p class="tiny">  #{the_url_decoration.xml_open}<a href="#{static}">#{static}</a>#{the_url_decoration.xml_close}</p></td></tr>\n} +      end +      def output_tests +        if FileTest.file?(@f.place_file.html_segtoc.dir)==true +          img=%{<img border="0" height="18" width="15" src="#{@image_path}/b_toc.png" alt="TOC linked" /> } +          pth=@f.output_path.html_seg.dir +          rel=@f.output_path.html_seg.rel_sm +          url=@f.output_path.html_seg.url +          desc,id,file='HTML, table of contents (for segmented text)','html',@f.base_filename.html_segtoc +          summarize_html_seg(desc,id,file,pth,rel,url,img) +        end +        if FileTest.file?(@f.place_file.html_scroll.dir)==true +          img=%{<img border="0" height="15" width="15" src="#{@image_path}/b_doc.png" alt="Full Text" /> } +          pth=@f.output_path.html_scroll.dir +          rel=@f.output_path.html_scroll.rel_sm +          url=@f.output_path.html_scroll.url +          desc,id,file='HTML, full length document','html_scroll',@f.base_filename.html_scroll +          summarize(desc,id,file,pth,rel,url,img) +        end +        if FileTest.file?(@f.place_file.html_book_index.dir)==true +          pth=@f.output_path.html_seg.dir +          rel=@f.output_path.html_seg.rel_sm +          url=@f.output_path.html_seg.url +          desc,id,file='HTML, (book type) index','html_book',@f.base_filename.html_book_index +          summarize(desc,id,file,pth,rel,url) +        end +        if FileTest.file?(@f.place_file.html_concordance.dir)==true +          pth=@f.output_path.html_seg.dir +          rel=@f.output_path.html_seg.rel_sm +          url=@f.output_path.html_seg.url +          desc,id,file='HTML, concordance file','concordance',@f.base_filename.html_concordance +          summarize(desc,id,file,pth,rel,url) +        end +        if FileTest.file?(@f.place_file.epub.dir)==true +          img=%{<img border="0" height="18" width="18" src="#{@image_path}/b_epub.png" alt="EPUB" /> } +          desc,id,file='EPUB (Electronic Publication, e-book standard)','epub',@f.base_filename.epub +          pth=@f.output_path.epub.dir +          rel=@f.output_path.epub.rel_sm +          url=@f.output_path.epub.url +          summarize(desc,id,file,pth,rel,url,img) +        end +        if FileTest.file?("#{@f.output_path.pdf.dir}/#{@f.base_filename.pdf_p_letter}")==true +          img=%{<img border="0" height="18" width="15" src="#{@image_path}/b_pdf.png" alt="PDF portrait" /> } +          pth=@f.output_path.pdf.dir +          rel=@f.output_path.pdf.rel_sm +          url=@f.output_path.pdf.url +          desc,id,file="PDF, U.S. letter size, portrait/vertical document (recommended for printing)",'pdf_letter',"#{@f.base_filename.pdf_p_letter}" +          summarize(desc,id,file,pth,rel,url,img) +        end +        if FileTest.file?("#{@f.output_path.pdf.dir}/#{@f.base_filename.pdf_l_letter}")==true +          img=%{<img border="0" height="15" width="18" src="#{@image_path}/b_pdf.png" alt="PDF landscape" /> } +          pth=@f.output_path.pdf.dir +          rel=@f.output_path.pdf.rel_sm +          url=@f.output_path.pdf.url +          desc,id,file="PDF, U.S. letter size, landscape/horizontal document (recommended for screen viewing)",'pdf_letter_landscape',"#{@f.base_filename.pdf_l_letter}" +          summarize(desc,id,file,pth,rel,url,img) +        end +        if FileTest.file?("#{@f.output_path.pdf.dir}/#{@f.base_filename.pdf_p_a4}")==true +          img=%{<img border="0" height="18" width="15" src="#{@image_path}/b_pdf.png" alt="PDF portrait" /> } +          pth=@f.output_path.pdf.dir +          rel=@f.output_path.pdf.rel_sm +          url=@f.output_path.pdf.url +          desc,id,file="PDF, A4 size, portrait/vertical document (recommended for printing)",'pdf_a4',"#{@f.base_filename.pdf_p_a4}" +          summarize(desc,id,file,pth,rel,url,img) +        end +        if FileTest.file?("#{@f.output_path.pdf.dir}/#{@f.base_filename.pdf_l_a4}")==true +          img=%{<img border="0" height="15" width="18" src="#{@image_path}/b_pdf.png" alt="PDF landscape" /> } +          pth=@f.output_path.pdf.dir +          rel=@f.output_path.pdf.rel_sm +          url=@f.output_path.pdf.url +          desc,id,file="PDF, A4 size, landscape/horizontal document (recommended for screen viewing)",'pdf_a4_landscape',"#{@f.base_filename.pdf_l_a4}" +          summarize(desc,id,file,pth,rel,url,img) +        end +        if FileTest.file?("#{@f.output_path.pdf.dir}/#{@f.base_filename.pdf_p_a5}")==true +          img=%{<img border="0" height="18" width="15" src="#{@image_path}/b_pdf.png" alt="PDF portrait" /> } +          pth=@f.output_path.pdf.dir +          rel=@f.output_path.pdf.rel_sm +          url=@f.output_path.pdf.url +          desc,id,file="PDF, A5 (book) size, portrait/vertical document (recommended for printing)",'pdf_a5',"#{@f.base_filename.pdf_p_a5}" +          summarize(desc,id,file,pth,rel,url,img) +        end +        if FileTest.file?("#{@f.output_path.pdf.dir}/#{@f.base_filename.pdf_l_a5}")==true +          img=%{<img border="0" height="15" width="18" src="#{@image_path}/b_pdf.png" alt="PDF landscape" /> } +          pth=@f.output_path.pdf.dir +          rel=@f.output_path.pdf.rel_sm +          url=@f.output_path.pdf.url +          desc,id,file="PDF, A5 (book) size, landscape/horizontal document (recommended for screen viewing)",'pdf_a5_landscape',"#{@f.base_filename.pdf_l_a5}" +          summarize(desc,id,file,pth,rel,url,img) +        end +        if FileTest.file?("#{@f.output_path.pdf.dir}/#{@f.base_filename.pdf_p_b5}")==true +          img=%{<img border="0" height="18" width="15" src="#{@image_path}/b_pdf.png" alt="PDF portrait" /> } +          pth=@f.output_path.pdf.dir +          rel=@f.output_path.pdf.rel_sm +          url=@f.output_path.pdf.url +          desc,id,file="PDF, B5 (book) size, portrait/vertical document (recommended for printing)",'pdf_b5',"#{@f.base_filename.pdf_p_b5}" +          summarize(desc,id,file,pth,rel,url,img) +        end +        if FileTest.file?("#{@f.output_path.pdf.dir}/#{@f.base_filename.pdf_l_b5}")==true +          img=%{<img border="0" height="15" width="18" src="#{@image_path}/b_pdf.png" alt="PDF landscape" /> } +          pth=@f.output_path.pdf.dir +          rel=@f.output_path.pdf.rel_sm +          url=@f.output_path.pdf.url +          desc,id,file="PDF, B5 (book) size, landscape/horizontal document (recommended for screen viewing)",'pdf_a5_landscape',"#{@f.base_filename.pdf_l_b5}" +          summarize(desc,id,file,pth,rel,url,img) +        end +        if FileTest.file?("#{@f.output_path.pdf.dir}/#{@f.base_filename.pdf_p_legal}")==true +          img=%{<img border="0" height="18" width="15" src="#{@image_path}/b_pdf.png" alt="PDF portrait" /> } +          pth=@f.output_path.pdf.dir +          rel=@f.output_path.pdf.rel_sm +          url=@f.output_path.pdf.url +          desc,id,file="PDF, U.S. legal size, portrait/vertical document (recommended for printing)",'pdf_legal',"#{@f.base_filename.pdf_p_legal}" +          summarize(desc,id,file,pth,rel,url,img) +        end +        if FileTest.file?("#{@f.output_path.pdf.dir}/#{@f.base_filename.pdf_l_legal}")==true +          img=%{<img border="0" height="15" width="18" src="#{@image_path}/b_pdf.png" alt="PDF landscape" /> } +          pth=@f.output_path.pdf.dir +          rel=@f.output_path.pdf.rel_sm +          url=@f.output_path.pdf.url +          desc,id,file="PDF, U.S. legal size, landscape/horizontal document (recommended for screen viewing)",'pdf_legal_landscape',"#{@f.base_filename.pdf_l_legal}" +          summarize(desc,id,file,pth,rel,url,img) +        end +        if FileTest.file?(@f.place_file.odt.dir)==true +          img=%{<img border="0" height="18" width="18" src="#{@image_path}/b_odf.png" alt="ODF/ODT" /> } +          pth=@f.output_path.odt.dir +          rel=@f.output_path.odt.rel_sm +          url=@f.output_path.odt.url +          desc,id,file='ODF:ODT (Open Document Format)','odt',@f.base_filename.odt +          summarize(desc,id,file,pth,rel,url,img) +        end +        if FileTest.file?(@f.place_file.xhtml.dir)==true +          pth=@f.output_path.xhtml.dir +          rel=@f.output_path.xhtml.rel_sm +          url=@f.output_path.xhtml.url +          desc,id,file='XHTML','xhtml',@f.base_filename.xhtml +          summarize(desc,id,file,pth,rel,url) +        end +        if FileTest.file?(@f.place_file.xml_sax.dir)==true +          pth=@f.output_path.xml_sax.dir +          rel=@f.output_path.xml_sax.rel_sm +          url=@f.output_path.xml_sax.url +          desc,id,file='XML SAX','xml_sax',@f.base_filename.xml_sax +          summarize(desc,id,file,pth,rel,url) +        end +        if FileTest.file?(@f.place_file.xml_dom.dir)==true +          pth=@f.output_path.xml_dom.dir +          rel=@f.output_path.xml_dom.rel_sm +          url=@f.output_path.xml_dom.url +          desc,id,file='XML DOM','xml_dom',@f.base_filename.xml_dom +          summarize(desc,id,file,pth,rel,url) +        end +        if FileTest.file?(@f.place_file.xml_docbook_article.dir)==true +          pth=@f.output_path.xml_docbook_article.dir +          rel=@f.output_path.xml_docbook_article.rel_sm +          url=@f.output_path.xml_docbook_article.url +          desc,id,file='XML Docbook Article','docbook_article',@f.base_filename.xml_docbook_article +          summarize(desc,id,file,pth,rel,url) +        end +        if FileTest.file?(@f.place_file.xml_docbook_book.dir)==true +          pth=@f.output_path.xml_docbook_book.dir +          rel=@f.output_path.xml_docbook_book.rel_sm +          url=@f.output_path.xml_docbook_book.url +          desc,id,file='XML Docbook Book','docbook',@f.base_filename.xml_docbook_book +          summarize(desc,id,file,pth,rel,url) +        end +        if FileTest.file?(@f.place_file.xml_fictionbook.dir)==true +          pth=@f.output_path.xml_fictionbook.dir +          rel=@f.output_path.xml_fictionbook.rel_sm +          url=@f.output_path.xml_fictionbook.url +          desc,id,file='XML Fictionbook','fictionbook',@f.base_filename.xml_fictionbook +          summarize(desc,id,file,pth,rel,url) +        end +        if FileTest.file?(@f.place_file.xml_scaffold_structure_sisu.dir)==true +          pth=@f.output_path.xml_scaffold_structure_sisu.dir +          rel=@f.output_path.xml_scaffold_structure_sisu.rel_sm +          url=@f.output_path.xml_scaffold_structure_sisu.url +          desc,id,file='XML Scaffold sisu structure','xml_scaffold',@f.base_filename.xml_scaffold_structure_sisu +          summarize(desc,id,file,pth,rel,url) +        end +        if FileTest.file?(@f.place_file.xml_scaffold_structure_collapse.dir)==true +          pth=@f.output_path.xml_scaffold_structure_collapse.dir +          rel=@f.output_path.xml_scaffold_structure_collapse.rel_sm +          url=@f.output_path.xml_scaffold_structure_collapse.url +          desc,id,file='XML Scaffold collapsed structure','xml_collapsed',@f.base_filename.xml_scaffold_structure_collapse +          summarize(desc,id,file,pth,rel,url) +        end +        if FileTest.file?(@f.place_file.info.dir)==true +          pth=@f.output_path.texinfo.dir +          rel=@f.output_path.texinfo.rel_sm +          url=@f.output_path.texinfo.url +          desc,id,file='Info file','info',@f.base_filename.info +          summarize(desc,id,file,pth,rel,url) +        end +        if FileTest.file?(@f.place_file.manpage.dir)==true +          pth=@f.output_path.manpage.dir +          rel=@f.output_path.manpage.rel_sm +          url=@f.output_path.manpage.url +          desc,id,file='Manpage','manpage',@f.base_filename.manpage +          summarize(desc,id,file,pth,rel,url) +        end +        if FileTest.file?(@f.place_file.sqlite_discrete.dir)==true +          desc,id,file='SQLite3 file','sqlite',@f.base_filename.sqlite_discrete +          pth=@f.output_path.sqlite_discrete.dir +          rel=@f.output_path.sqlite_discrete.rel_sm +          url=@f.output_path.sqlite_discrete.url +          summarize(desc,id,file,pth,rel,url) +        end +        if FileTest.file?(@f.place_file.txt.dir)==true +          desc,id='Plaintext (UTF-8)','text' +          pth=@f.output_path.txt.dir +          rel=@f.output_path.txt.rel_sm +          url=@f.output_path.txt.url +          file=@f.base_filename.txt +          summarize(desc,id,file,pth,rel,url) +        end +        if FileTest.file?(@f.place_file.textile.dir)==true +          desc,id='Textile text (UTF-8)','textile' +          pth=@f.output_path.textile.dir +          rel=@f.output_path.textile.rel_sm +          url=@f.output_path.textile.url +          file=@f.base_filename.textile +          summarize(desc,id,file,pth,rel,url) +        end +        if FileTest.file?(@f.place_file.asciidoc.dir)==true +          desc,id='AsciiDoc text (UTF-8)','asciidoc' +          pth=@f.output_path.asciidoc.dir +          rel=@f.output_path.asciidoc.rel_sm +          url=@f.output_path.asciidoc.url +          file=@f.base_filename.asciidoc +          summarize(desc,id,file,pth,rel,url) +        end +        if FileTest.file?(@f.place_file.markdown.dir)==true +          desc,id='Markdown text (UTF-8)','markdown' +          pth=@f.output_path.markdown.dir +          rel=@f.output_path.markdown.rel_sm +          url=@f.output_path.markdown.url +          file=@f.base_filename.markdown +          summarize(desc,id,file,pth,rel,url) +        end +        if FileTest.file?(@f.place_file.rst.dir)==true +          desc,id='rST text (UTF-8)','rst' +          pth=@f.output_path.rst.dir +          rel=@f.output_path.rst.rel_sm +          url=@f.output_path.rst.url +          file=@f.base_filename.rst +          summarize(desc,id,file,pth,rel,url) +        end +        if FileTest.file?(@f.place_file.orgmode.dir)==true +          desc,id='OrgMode structure text (UTF-8)','org' +          pth=@f.output_path.orgmode.dir +          rel=@f.output_path.orgmode.rel_sm +          url=@f.output_path.orgmode.url +          file=@f.base_filename.orgmode +          summarize(desc,id,file,pth,rel,url) +        end +        if FileTest.file?("#{@base_path}/#{@md.fns}.tex")==true +          desc,id,file='LaTeX (portrait)','latex',"#{@md.fns}.tex" +          pth,rel,url='','','' +          summarize(desc,id,file,pth,rel,url) +        end +        if FileTest.file?("#{@base_path}/#{@md.fns}.tex")==true +          desc,id,file='LaTeX (landscape)','latex_landscape',"#{@md.fns}.landscape.tex" +          pth,rel,url='','','' +          summarize(desc,id,file,pth,rel,url) +        end +        if FileTest.file?(@f.place_file.hash_digest.dir)==true +          pth=@f.output_path.hash_digest.dir +          rel=@f.output_path.hash_digest.rel_sm +          url=@f.output_path.hash_digest.url +          desc,id,file="Digest/DCC - Document Content Certificate (#{@dg})",'digests',@f.base_filename.hash_digest +          summarize(desc,id,file,pth,rel,url) +        end +      end +      def published_versions +        desc,file='Markup (SiSU source)','source',@md.fns +        languages(desc,file) +      end +      def language_versions +        if FileTest.file?(@f.place_file.manifest.dir)==true +          desc='Markup (SiSU source)' +          published_languages(desc) +        end +      end +      def qrc_image +        fn=(@f.output_dir_structure.by_filename?) \ +        ? 'sisu_manifest' +        : @md.fnb +        pth=((@o_str.dump_or_redirect?) \ +        || (@f.output_dir_structure.by_filename?)) \ +        ? '.' +        : 'qrcode' +        img_md="#{pth}/#{fn}#{@fn_lng}.md.png" +        img_title="#{pth}/#{fn}#{@fn_lng}.title.png" +        if FileTest.file?(@f.place_file.qrcode_md.dir)==true +          @manifest[:html] <<<<WOK +<tr><td class="left"> +  <p class="tiny">QR code SiSU document metadata:</p> +  <p class="tiny"> +    <img border="0" src="#{img_md}" alt="qrcode metadata" /> +  </p> +</td></tr> +WOK +        end +        if FileTest.file?(@f.place_file.qrcode_title.dir)==true +          @manifest[:html] <<<<WOK +<tr><td class="left"> +  <p class="tiny">QR code document title info:</p> +  <p class="tiny"> +    <img border="0" src="#{img_title}" alt="qrcode title" /> +  </p> +</td></tr> +WOK +        end +      end +      def source_tests +        if @md.fno =~/\.ssm$/                                                  #% decide whether to extract and include requested/required documents +          if FileTest.file?(@f.place_file.src.dir)==true +            pth=@f.output_path.src.dir +            rel=@f.output_path.src.rel_sm +            url=@f.output_path.src.url +            desc,id,file='Markup Composite File (SiSU source)','source',@f.base_filename.src +            summarize_sources(desc,id,file,pth,rel,url) +          end +        else +          if FileTest.file?(@f.place_file.src.dir)==true +            pth=@f.output_path.src.dir +            rel=@f.output_path.src.rel_sm +            url=@f.output_path.src.url +            desc,id,file='Markup (SiSU source)','composite',@f.base_filename.src +            summarize_sources(desc,id,file,pth,rel,url) +          end +        end +        if FileTest.file?(@f.place_file.sisupod.dir)==true +          pth=@f.output_path.sisupod.dir +          rel=@f.output_path.sisupod.rel_sm +          url=@f.output_path.sisupod.url +          desc,id,file='SiSUdoc pod (tar.xz)','sisupod',@f.base_filename.sisupod +          summarize_sources(desc,id,file,pth,rel,url) +        end +        if FileTest.file?(@f.place_file.pot.dir)==true +          pth=@f.output_path.pot.dir +          rel=@f.output_path.pot.rel_sm +          url=@f.output_path.pot.url +          desc,id,file='SiSU pot','pot',@f.base_filename.pot +          summarize_sources(desc,id,file,pth,rel,url) +        end +      end +      def metadata_tests +        if defined? @md.title                                                   #% +          if defined? @md.title.full \ +          and @md.title.full=~/\S+/ +            desc,id,info=@translate.full_title,'title',@md.title.full +            metadata(desc,id,info) +          end +        end +        if defined? @md.creator                                                 #% +          if defined? @md.creator.author \ +          and @md.creator.author=~/\S+/ +            desc,id,info=@translate.author,'author',@md.creator.author +            metadata(desc,id,info) +          end +          if defined? @md.creator.editor \ +          and @md.creator.editor=~/\S+/ +            desc,id,info=@translate.editor,'editor',@md.creator.editor +            metadata(desc,id,info) +          end +          if defined? @md.creator.contributor \ +          and @md.creator.contributor=~/\S+/ +            desc,id,info=@translate.contributor,'contributor',@md.creator.contributor +            metadata(desc,id,info) +          end +          if defined? @md.creator.translator \ +          and @md.creator.translator=~/\S+/ +            desc,id,info=@translate.translator,'creator',@md.creator.translator +            metadata(desc,id,info) +          end +          if defined? @md.creator.illustrator \ +          and @md.creator.illustrator=~/\S+/ +            desc,id,info=@translate.illustrator,'illustrator',@md.creator.illustrator +            metadata(desc,id,info) +          end +          if defined? @md.creator.prepared_by \ +          and @md.creator.prepared_by=~/\S+/ +            desc,id,info=@translate.prepared_by,'prepared_by',@md.creator.prepared_by +            metadata(desc,id,info) +          end +          if defined? @md.creator.digitized_by \ +          and @md.creator.digitized_by=~/\S+/ +            desc,id,info=@translate.digitized_by,'designed_by',@md.creator.digitized_by +            metadata(desc,id,info) +          end +        end +        if defined? @md.rights +          if defined? @md.rights.all \ +          and @md.rights.all=~/\S+/ #dc +            desc,id,info=@translate.rights,'rights',@md.rights.all +            metadata(desc,id,info) +          end +        end +        if defined? @md.date                                                    #% +          if defined? @md.date.published \ +          and @md.date.published=~/\S+/ #dc +            desc,id,info=@translate.date,'date',@md.date.published +            metadata(desc,id,info) +          end +          if defined? @md.date.created \ +          and @md.date.created=~/\S+/ #dc +            desc,id,info=@translate.date_created,'date_created',@md.date.created +            metadata(desc,id,info) +          end +          if defined? @md.date.issued \ +          and @md.date.issued=~/\S+/ #dc +            desc,id,info=@translate.date_issued,'date_issued',@md.date.issued +            metadata(desc,id,info) +          end +          if defined? @md.date.available \ +          and @md.date.available=~/\S+/ #dc +            desc,id,info=@translate.date_available,'date_available',@md.date.available +            metadata(desc,id,info) +          end +          if defined? @md.date.modified \ +          and @md.date.modified=~/\S+/ #dc +            desc,id,info=@translate.date_modified,'date_modified',@md.date.modified +            metadata(desc,id,info) +          end +          if defined? @md.date.valid \ +          and @md.date.valid=~/\S+/ #dc +            desc,id,info=@translate.date_valid,'date_valid',@md.date.valid +            metadata(desc,id,info) +          end +        end +        if defined? @md.publisher \ +        and @md.publisher=~/\S+/ #dc +          desc,id,info=@translate.publisher,'publisher',@md.publisher +          metadata(desc,id,info) +        end +        if defined? @md.notes                                                   #% +          if defined? @md.notes.description \ +          and @md.notes.description=~/\S+/ +            desc,id,info=@translate.description,'description',@md.notes.description +            metadata(desc,id,info) +          end +          if defined? @md.notes.abstract \ +          and @md.notes.abstract=~/\S+/ +            desc,id,info=@translate.abstract,'abstract',@md.notes.abstract +            metadata(desc,id,info) +          end +          if defined? @md.notes.comment \ +          and @md.notes.comment=~/\S+/ +            desc,id,info=@translate.comments,'comment',@md.notes.comment +            metadata(desc,id,info) +          end +          if defined? @md.notes.prefix_a \ +          and @md.notes.prefix_a=~/\S+/ +            desc,id,info=@translate.prefix_a,'prefix',@md.notes.prefix_a +            metadata(desc,id,info) +          end +          if defined? @md.notes.prefix_b \ +          and @md.notes.prefix_b=~/\S+/ +            desc,id,info=@translate.prefix_b,'prefix_b',@md.notes.prefix_b +            metadata(desc,id,info) +          end +        end +        if defined? @md.title                                                   #% +          if defined? @md.title.language \ +          and @md.title.language=~/\S+/ +            desc,id,info=@translate.language,'language',@md.title.language +            metadata(desc,id,info) +          end +          if defined? @md.original.language \ +          and @md.original.language=~/\S+/ +            desc,id,info=@translate.language_original,'language_original',@md.original.language +            metadata(desc,id,info) +          end +        end +        if defined? @md.classify                                                #% +          if defined? @md.topic_register_array \ +          and @md.topic_register_array.length > 0 +            @manifest[:html] << %{<tr><th class="left"><p class="bold_left" id="topics">#{@translate.topic_register}:</p></th><td>\n} +            @md.topic_register_array.each do |t| +              t.each_with_index do |st,i| +                if st.is_a?(Array) +                  st.each do |v| +                    if v.is_a?(Array) +                      v.each do |w| +                        @manifest[:html] << %{<p class="it#{i}">#{w}</p>\n} +                      end +                    else +                      @manifest[:html] << %{<p class="it#{i}">#{v}</p>\n} +                    end +                  end +                else @manifest[:html] << %{<p class="it#{i}">#{st}</p>\n} +                end +              end +            end +            @manifest[:html] << %{</td></tr>\n} +          end +          if defined? @md.classify.subject \ +          and @md.classify.subject=~/\S+/ +            desc,id,info=@translate.subject,'subject',@md.classify.subject +            metadata(desc,id,info) +          end +          if defined? @md.classify.keywords \ +          and @md.classify.keywords=~/\S+/ +            desc,id,info=@translate.keywords,'keywords',@md.classify.keywords +            metadata(desc,id,info) +          end +          if defined? @md.classify.loc \ +          and @md.classify.loc=~/\S+/ +            desc,id,info=@translate.cls_loc,'loc',@md.classify.loc +            metadata(desc,id,info) +          end +          if defined? @md.classify.dewey \ +          and @md.classify.dewey=~/\S+/ +            desc,id,info=@translate.cls_dewey,'dewey',@md.classify.dewey +            metadata(desc,id,info) +          end +          if defined? @md.notes.coverage \ +          and @md.notes.coverage=~/\S+/ +            desc,id,info=@translate.coverage,'coverage',@md.notes.coverage +            metadata(desc,id,info) +          end +          if defined? @md.notes.relation \ +          and @md.notes.relation=~/\S+/ +            desc,id,info=@translate.relation,'relation',@md.notes.relation +            metadata(desc,id,info) +          end +          if defined? @md.notes.type \ +          and @md.notes.type=~/\S+/ #dc +            desc,id,info=@translate.type,'type',@md.notes.type +            metadata(desc,id,info) +          end +          if defined? @md.notes.format \ +          and @md.notes.format=~/\S+/ +            desc,id,info=@transate.format,'format',@md.notes.format +            metadata(desc,id,info) +          end +        end +        if defined? @md.identifier                                              #% +          if defined? @md.identifier.oclc \ +          and @md.identifier.oclc=~/\S+/ +            desc,id,info=@translate.cls_oclc,'',@md.identifier.oclc +            @manifest[:html] << %{<tr><th class="left"><p class="bold_left">#{desc}:</p></th><td>\n} +            @manifest[:html] << %{<p class="left"><a href="http://worldcat.org/oclc/#{info}">#{info}</a></p>\n} +            @manifest[:html] << %{</td></tr>\n} +          end +          if defined? @md.identifier.pg \ +          and @md.identifier.pg=~/\S+/ +            desc,id,info=@translate.cls_gutenberg,'ocalc',@md.identifier.pg +            metadata(desc,id,info) +          end +          if defined? @md.identifier.isbn \ +          and @md.identifier.isbn=~/\S+/ +            desc,id,info=@translate.cls_isbn,'isbn',@md.identifier.isbn +            metadata(desc,id,info) +          end +        end +        if defined? @md.original.source \ +        and @md.original.source=~/\S+/ +          desc,id,info=@translate.source,'source_original',@md.original.source +          metadata(desc,id,info) +        end +        if @md.fns +          desc,id,info=@translate.sourcefile,'source_filename',@md.fns +          metadata(desc,id,info) +        end +        if @md.en[:mismatch] > 0 +          desc,id,info='WARNING document error in endnote markup, number mismatch','',"endnotes: #{@md.en[:note]} != endnote reference marks: #{@md.en[:mark]} (difference = #{@md.en[:mismatch]})" +          metadata(desc,id,info) +        end +        if @md.wc_words +          desc,id,info=@translate.word_count,'wordcount',@md.wc_words +          metadata(desc,id,info) +        end +        if @md.dgst +          desc,id,info="#{@translate.sourcefile_digest} (#{@dg})",'digests',@md.dgst[1] +          metadata(desc,id,info) +        end +        if @md.sc_number +          desc,id,info=@translate.sc_number,'sc_number',@md.sc_number +          metadata(desc,id,info) +        end +        if @md.sc_date +          desc,id,info=@translate.sc_date,'sc_date',"#{@md.sc_date} at #{@md.sc_time}" +          metadata(desc,id,info) +        end +        if @md.generated +          desc,id,info=@translate.last_generated,'generated',@md.generated +          metadata(desc,id,info) +        end +        if @md.project_details +          desc,id,info=@translate.sisu_version,'project',"#{@md.project_details.project} #{@md.project_details.version} #{@md.project_details.date_stamp} (#{@md.project_details.date})#{@md.project_details.install_method}" +          metadata(desc,id,info) +        end +        if @md.ruby_version +          desc,id,info=@translate.ruby_version,'ruby',@md.ruby_version +          metadata(desc,id,info) +        end +      end +      def links_tests +        if defined? @md.lnk \ +        and @md.lnk +          @md.lnk.each do |l| +            if defined? l[:say] +              target=(l[:url] !~/^\.(\.)?\//) \ +              ? 'external' +              : '_top' +              url,lnk=l[:url],l[:say] +              unless url.nil? \ +              or url.empty? +                links(url,lnk,target) +              end +            end +          end +        end +      end +      def check_output(data) +        begin +          make=SiSU_Env::ProcessingSettings.new(@md) +          minitoc=SiSU_HTML_MiniToc::TocMini.new(@md,data).songsheet.join("\n") +          format_head_toc=SiSU_HTML_Format::HeadToc.new(@md) +          @manifest[:html] <<<<WOK +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title> +SiSU manifest: #{@md.title.full} +</title> +<meta http-equiv="Content-Type" content="text/html;charset=utf-8" /> +<meta name="sourcefile" content="#{@md.fns}" /> +<link rel="generator" href="http://www.jus.uio.no/sisu" /> +<link rel="shortcut icon" href="#{@f.path_rel_links.html_scroll_css}_sisu/image_sys/rb7.ico" /> +#{@stylesheet.css_head} +</head> +<body lang="#{@md.opt.lng}"> +#{format_head_toc.seg_head_navigation_band(:manifest)} +WOK +          if make.build.manifest_minitoc? +            if @o_str.dump_or_redirect? +            elsif @f.output_dir_structure.by_language_code? \ +            or @f.output_dir_structure.by_filetype? +              minitoc=minitoc.gsub(/<a href="(\S+?)"/m,%{<a href="../html/#{@md.fnb}/\\1"}). +                gsub(/<a href="\.\.\/html\/#{@md.fnb}\/(?:sisu_manifest\.html|#{@f.base_filename.manifest})"/m, +              %{<a href="#{@f.base_filename.manifest}"}) +            end +            @manifest[:html] <<<<WOK +<div class="toc"> +#{minitoc.to_s} +</div> +<div class="content"> +WOK +          else +            @manifest[:html] <<<<WOK +<div> +WOK +          end +          if @o_str.dump_or_redirect? +          elsif @f.output_dir_structure.by_language_code? \ +          or @f.output_dir_structure.by_filetype? +            pth_local=@f.output_path.manifest.dir +            pth_rel='.' +          else +            pth_local=@f.output_path.base.dir +            pth_rel='..' +          end +          pth_rel_home=if @env.output_dir_structure.by? == :language +            '../..' +          elsif @env.output_dir_structure.by? == :filetype +            '..' +          elsif @env.output_dir_structure.by? == :filename +            '..' +          else '..' +          end +          output_organised_by="(output organised by #{@env.output_dir_structure.by?})" +          harvest=(FileTest.file?("#{pth_local}/authors#{@fn_lng}.html") \ +          && FileTest.file?("#{pth_local}/topics#{@fn_lng}.html")) \ +          ? %{<p class="small"><a href="#{pth_rel_home}/index.html">.:</a> other document manifests: [<a href="#{pth_rel}/authors#{@fn_lng}.html">authors</a>] [<a href="#{pth_rel}/topics#{@fn_lng}.html">topics</a>] #{output_organised_by}</p>} +          : %{<p class="small"><a href="#{pth_rel_home}">#{output_organised_by}</a></p>} +          manifest_title=%{<p class="bold">#{@translate.manifest_description}</p>#{harvest}} +          @manifest[:html] <<<<WOK +<div id="horizontal_links"> +#{manifest_title} +</div> +<h1 class="small">#{@md.title.full}</h1> +<p class="bold">#{@md.author}</p> +<div id="horizontal_links"><p class="bold"> +<p class="small"> +  <a href="#output">Document, Available Filetypes</a> +</p> +<p class="small"> +  <a href="#metadata">Document Metadata</a> +</p> +<p class="tiny"> +      <a href="#links">metadata suggested links (if any)</a> +</p> +</div> +<table summary="normal text css" width="100%" border="0" cellpadding="2" align="center"> +WOK +          published_versions +          @manifest[:html] << '</table>' +          @manifest[:html] <<<<WOK +<h2 class="small"><a name="output">#{@translate.manifest_description_output}</a></h2> +<table summary="available output/filetypes" width="100%" border="0" cellpadding="2" align="center"> +<tr> <th class="left"><p class="bold">#{@translate.filetype_description}</p></th><th class="left"><p class="bold">#{@translate.filename}</p></th><th class="right"><p class="right"><b>#{@translate.file_size}</b></p><p class="tiny_right">(kB)</p></th></tr> + +WOK +          output_tests +          @manifest[:html] << '</table>' +          @manifest[:html] <<<<WOK +<table summary="normal text css" width="100%" border="0" cellpadding="2" align="center"> +WOK +          source_tests +          @manifest[:html] << '</table>' +          @manifest[:html] <<<<WOK +<h2 class="small"><a name="metadata">#{@translate.manifest_description_metadata}</a></h2> +<table summary="document metadata" width="100%" border="0" cellpadding="2" align="center"> +<tr> <th class="left"><p class="bold" id="metadata">#{@translate.metadata}</p></th><th class="left"><p class="bold">#{@translate.description}</p></th></tr> +WOK +          metadata_tests +          @manifest[:html] <<<<WOK +</table> +WOK +          @manifest[:html] <<<<WOK +<p class="bold"><a name="links">#{@translate.suggested_links}:</a></p> +<table summary="suggested links" width="100%" border="0" cellpadding="2" align="center"> +WOK +          links_tests +          @manifest[:html] <<<<WOK +</table> +WOK +          @manifest[:html] <<<<WOK +<h2 class="small"><a name="languages">#{@translate.language_version_list}</a></h2> +<table summary="language versions" width="100%" border="0" cellpadding="2" align="center"> +<tr> <th class="left"><p class="bold">#{@translate.filename}</p></th><th class="left"><p class="bold">#{@translate.description}</p></th><th class="right"><p class="right"> </p></th></tr> + +WOK +          language_versions +          qrc_image +          @manifest[:html] <<<<WOK +</table> +</div> +<div> +<br> +#{SiSU_Proj_HTML::Bits.new.credits_sisu_manifest} +</div> +</body> +</html> +WOK +          output +        rescue +          SiSU_Errors::Rescued.new($!,$@,@md.opt.selections.str,@md.fns).location do +            __LINE__.to_s + ':' + __FILE__ +          end +        ensure +        end +      end +    end +  end +end +__END__ +#+END_SRC + +*** html_persist.rb + +#+BEGIN_SRC ruby  :tangle "../lib/sisu/html_persist.rb" +# <<sisu_document_header>> +Module SiSU_HTML_Persist +  class Persist +    @@persist=nil +    attr_accessor :is0,:is1,:is2,:is3,:is4,:heading0,:heading1,:heading2,:heading3,:heading4, :title, :dot_nav, :tocband_banner, :tocband_bannerless, :headings, :heading_endnotes, :main, :endnote_all, :tail, :credits, :heading_idx, :idx, :seg_endnotes, :seg_endnotes_array, :segtocband, :get_hash_fn, :get_hash_to, :seg_subtoc, :seg_subtoc_array, :fn, :seg_name ,:seg_name_x,:seg_name_x_tracker +    def initialize(args=nil) +      @@persist=args=(args ? args : (@@persist || persist_init_hash_values)) +      @is0=args[:is0] +      @is1=args[:is1] +      @is2=args[:is2] +      @is3=args[:is3] +      @is4=args[:is4] +      @heading0=args[:heading0] +      @heading1=args[:heading1] +      @heading2=args[:heading2] +      @heading3=args[:heading3] +      @heading4=args[:heading4] +      @title=args[:title] +      @dot_nav=args[:dot_nav] +      @tocband_banner=args[:tocband_banner] +      @tocband_bannerless=args[:tocband_bannerless] +      @headings=args[:headings] +      @heading_endnotes=args[:heading_endnotes] +      @main=args[:main] +      @endnote_all=args[:endnote_all] +      @tail=args[:tail] +      @credits=args[:credits] +      @heading_idx=args[:heading_idx] +      @idx=args[:idx] +      @seg_endnotes=args[:seg_endnotes] +      @seg_endnotes_array=args[:seg_endnotes_array] +      @get_hash_to=args[:get_hash_to] +      @get_hash_fn=args[:get_hash_fn] +      @seg_subtoc=args[:seg_subtoc] +      @seg_subtoc_array=args[:seg_subtoc_array] +      @segtocband=args[:fn] +      @fn=args[:fn] +      @seg_name=args[:seg_name] +      @seg_name_x=args[:seg_name_x] +      @seg_name_x_tracker=args[:seg_name_x_tracker] +    end +    def is0 +      @is0 +    end +    def is1 +      @is1 +    end +    def is2 +      @is2 +    end +    def is3 +      @is3 +    end +    def is4 +      @is4 +    end +    def heading0 +      @heading0 +    end +    def heading1 +      @heading1 +    end +    def heading2 +      @heading2 +    end +    def heading3 +      @heading3 +    end +    def heading4 +      @heading4 +    end +    def title +      @title +    end +    def dot_nav +      @dot_nav +    end +    def tocband_banner +      @tocband_banner +    end +    def tocband_bannerless +      @tocband_bannerless +    end +    def headings +      @headings +    end +    def heading_endnotes +      @heading_endnotes +    end +    def main +      @main +    end +    def endnote_all +      @endnote_all +    end +    def tail +      @tail +    end +    def credits +      @credits +    end +    def heading_idx +      @heading_idx +    end +    def idx +      @idx +    end +    def seg_endnotes +      @seg_endnotes +    end +    def seg_endnotes_array +      @seg_endnotes_array +    end +    def get_hash_to +      @get_hash_to +    end +    def get_hash_fn +      @get_hash_fn +    end +    def seg_subtoc +      @seg_subtoc +    end +    def seg_subtoc_array +      @seg_subtoc_array +    end +    def segtocband +      @segtocband +    end +    def fn +      @fn +    end +    def seg_name +      @seg_name +    end +    def seg_name_x +      @seg_name_x +    end +    def seg_name_x_tracker +      @seg_name_x_tracker +    end +    def persist_init_hash_values +      { +        is0: 0, +        is1: 0, +        is2: 0, +        is3: 0, +        is4: 0, +        heading0: '', +        heading1: '', +        heading2: '', +        heading3: '', +        heading4: '', +        tocband_banner: [], +        tocband_bannerless: [], +        title: [], +        headings: [], +        main: [], +        idx: [], +        tail: [], +        credits: [], +        endnote_all: [], +        heading_endnotes: '', +        seg_endnotes: {}, +        seg_endnotes_array: [], +        get_hash_fn: '', +        get_hash_to: '', +        seg_subtoc: {}, +        seg_subtoc_array: [], +        segtocband: '', +        fn: '', +        seg_name: [], +        seg_name_x: [], +        seg_name_x_tracker: 0, +      } +    end +    def persist_init +      @@persist=nil +      Persist.new(persist_init_hash_values) +    end +  end +end +__END__ +#+END_SRC + +*** html_promo.rb + +#+BEGIN_SRC ruby  :tangle "../lib/sisu/html_promo.rb" +# <<sisu_document_header>> +module SiSU_HTML_Promo +  require_relative 'se'                                 # se.rb +    include SiSU_Env +  class Ad +    def initialize(md) +      @md=md +      @env=SiSU_Env::InfoEnv.new(@md.fns,@md) +      @rc=SiSU_Env::GetInit.new.sisu_yaml.rc +      @ad=SiSU_Env::GetInit.new.ads +      @flag=@env.widget.promo? +      @make=SiSU_Env::ProcessingSettings.new(@md) +    end +    def div +      def major +        (@make.build.html_right_pane? \ +         && @flag[:ad]) \ +        ? '<div id="pane_major">' +        : '' +      end +      def minor +        (@make.build.html_right_pane? \ +         && @flag[:ad]) \ +        ? '<div id="pane_minor">' +        : '' +      end +      def close +        (@make.build.html_right_pane? \ +         && @flag[:ad]) \ +        ? '</div>' +        : '' +      end +      self +    end +    def display +      ads_array,promo_array=[],[] +      if @make.build.html_right_pane? \ +      && @flag[:ad] +        ads=if @md.promo && @md.promo.length > 0           #promo set in document +          promo_array=@md.promo +        elsif @flag[:rc]                                   #promo set in rc file +          promo_array=if @rc['html']['promo'].is_a?(String) +            @rc['html']['promo'].split(/[,;]\s*/) +          else @rc['html']['promo'] +          end +        else advert_extract_all +        end +        ads=if promo_array.length > 0 +          promo_array.each do |x| +            ads_array << advert_extract_subject(x) +          end +          ads_array +        end +        adverts(ads.join) +      end +    end +    def cell(prod,id) +      @prod,@id=prod,id +      def title +        @prod['title'] ? %{<b>#{@prod['title']}</b>} : '' +      end +      def subtitle +        @prod['subtitle'] ? %{ - #{@prod['subtitle']}} : '' +      end +      def author +        @prod['author'] ? %{<p class="pane">#{@prod['author']}</p>} : '' +      end +      def editor +        @prod['editor'] ? %{<p class="pane">#{@prod['editor']}</p>} : '' +      end +      def year +        @prod['year'] ? %{<p class="pane">#{@prod['year']}</p>} : '' +      end +      def date +        @prod['date'] ? %{<p class="pane">On: #{@prod['date']}</p>} : '' +      end +      def location +        @prod['at'] ? %{<p class="pane">At: #{@prod['at']}</p>} : '' +      end +      def pages +        @prod['pages'] ? %{<p class="pane">Pages: #{@prod['pages']} pages</p>} : '' +      end +      def form +        @prod['form'] ? %{<p class="pane">#{@prod['form']}</p>} : '' +      end +      def nick +        @prod['nick'] ? %{(#{@prod['nick']})<br>} : '' +      end +      def update +        @prod['update'] ? %{<p class="pane">Updated: #{@prod['update']}</p>} : '' +      end +      def issn +        @prod['issn'] ? %{<p class="pane">issn: #{@prod['issn']}</p>} : '' +      end +      def blurb +        @prod['blurb'] ? %{<p class="pane_blurb">#{@prod['blurb']}</p>} : '' +      end +      def search_form_sisu(table=true) +        db=if @prod['db']=~/\S+/ +          (@prod['db']=~/^#{Db[:name_prefix]}\S+/) ? @prod['db'] : "#{Db[:name_prefix]}#{@prod['db']}" +        elsif defined? @rc['search']['sisu']['db'] \ +        and @rc['search']['sisu']['db'] =~/\S+/ +          (@rc['search']['sisu']['db']=~/^#{Db[:name_prefix]}\S+/) \ +          ? @prod['search']['sisu']['db'] +          : "#{Db[:name_prefix]}#{@prod['db']}" +        else nil +        end +        action=if @prod['action']=~/^https?:\/\// +          @prod['action'] +        elsif defined? @rc['search']['sisu']['action'] \ +        and @rc['search']['sisu']['action'] =~/^https?:\/\// +          @rc['search']['sisu']['action'] +        else nil +        end +        if action \ +        and db +          @env.widget.search_form('sisusearch',action,db,table) +        else '' +        end +      end +      def search_form_hyperestraier(table=true) +        action=if defined? @rc['search']['hyperestraier']['action'] \ +        and @rc['search']['hyperestraier']['action'] =~/^https?:\/\// +          @rc['search']['hyperestraier']['action'] +        else nil +        end +        form=if action +          '<br>' + @env.widget.search_form('hyperestraier',action,'',table) +        else '' +        end +        form +      end +      def links +        if @prod['links'] #and @prod['links']==Array +          links_a=[] +          @prod['links'].each do |x| +            if x \ +            and x['url'] \ +            and x['title'] +              subtitle=x['subtitle'] ? %{ - #{x['subtitle']}} : '' +              url_=(x['url'] =~/https?:/) ? x['url'] : "../#{x['url']}" +              links_a << %{<p class="pane_link"><a href="#{url_}">#{x['title']}#{subtitle}</a></p>\n} +            end +          end +          links_a.join +        else '' +        end +      end +      def image +        @prod['image'] ? %{<img border="0" src="../_sisu/image/#{@prod['image']}" /><br>} : '' +      end +      def url_link +        @url_=if @prod['url'] =~/https?:/ +          "#{@prod['url']}" +        else "../#{@prod['url']}" # "#{@env.url.root}/#{@prod['url']}" +        end +        def show +          @prod['url'] ? %{<p class="pane_link"><a href="#{@url_}">#{@url_}</a></p>} : '' +        end +        def url +          @prod['url'] ? %{<a href="#{@url_}">} : '' +        end +        def url_relative +          @prod['url'] ? %{<a href="../#{@prod['url']}/toc.html">} : '' +        end +        self +      end +      def flyer +        if @prod['flyer'] +          %{<p class="pane"><a href="../man/pdf/#{@id}.pdf"><img border="0" height="18" width="15" src="../_sisu/image/b_pdf.png"> PDF flyer</a></p>} +        else '' +        end +      end +      def price +        def gbp +          if defined? @prod['price']['gbp'] \ +          and @prod['price']['gbp'] +            "  £ #{@prod['price']['gbp']} (GBP) " +          else '' +          end +        end +        def euro +          if defined? @prod['price']['euro'] \ +          and @prod['price']['euro'] +            "  € #{@prod['price']['euro']} (Euro) " +          else '' +          end +        end +        def usd +          if defined? @prod['price']['usd'] \ +          and @prod['price']['usd'] +            "  $ #{@prod['price']['usd']} (USD) " +          else '' +          end +        end +        %{<p class="pane">Price:#{gbp}#{euro}#{usd}</p>} +      end +      def adsense #draw content from a configuration file +        def column_right +          if defined? @ad[:promo]['ad']['adsense']['column_right'] +            @ad[:promo]['ad']['adsense']['column_right'].join("\n") +          else '' +          end +        end +        def line_single +          if defined? @ad[:promo]['ad']['adsense']['line_single'] +            @ad[:promo]['ad']['adsense']['line_single'].join("\n") +          else '' +          end +        end +        self +      end +      def site_link #Work area +        if url_link.url +           <<-WOK +<p class="pane"> +#{url_link.url} +#{image} +#{title} +#{subtitle} +</a>#{nick}</p> +          WOK +        else +         <<-WOK +<p class="pane"> +#{image} +#{title} +#{subtitle} +</p> +          WOK +        end +      end +      self +    end +    def output_form_sponsor(type,id) +      cell=cell(@ad[:promo][type][id],prod_id) +      <<-WOK +<br> +#{cell.site_link} +#{cell.blurb} +#{cell.links} +      WOK +    end +    def output_form_link(type,id) +      prod_id=id.gsub(/id_/,'') +      cell=cell(@ad[:promo][type][id],prod_id) +       <<WOK +<br> +#{cell.site_link} +#{cell.author} +#{cell.year} +#{cell.blurb} +#{cell.links} +WOK +    end +    def output_form_search_sisu(type,id) +      prod_id=id.gsub(/id_/,'') +      cell=cell(@ad[:promo][type][id],prod_id) +      cell.search_form_sisu(false) +    end +    def output_form_search_hyperestraier(type,id) +      prod_id=id.gsub(/id_/,'') +      cell=cell(@ad[:promo][type][id],prod_id) +      cell.search_form_hyperestraier(false) +    end +    def output_form_book(type,id) +      prod_id=id.gsub(/id_/,'') +      cell=cell(@ad[:promo][type][id],prod_id) +      prod_type=((id=~/id_(?:[0-9x]){10,13}/i) ? 'isbn' : 'id') +      id_detail=%{<p class="pane">#{prod_type}: #{prod_id}</p>} +       <<WOK +<br> +#{cell.site_link} +#{cell.author} +#{cell.year} +#{id_detail} +#{cell.pages}#{cell.form} +#{cell.price} +#{cell.flyer} +#{cell.blurb} +#{cell.links} +WOK +    end +    def output_form_journal(type,id) +      prod_id=id.gsub(/id_/,'') +      cell=cell(@ad[:promo][type][id],prod_id) +       <<WOK +<br> +#{cell.site_link} +#{cell.editor} +#{cell.issn} +#{cell.update} +#{cell.form} +#{cell.price.gsub(/Price:/,'Subscription:')} +#{cell.flyer} +#{cell.blurb} +#{cell.links} +WOK +    end +    def output_form_conference(type,id) +      prod_id=id.gsub(/id_/,'') +      cell=cell(@ad[:promo][type][id],prod_id) +#translate date (dd month yyyy) from 2007-03-04 and ruby conversion +       <<WOK +<br> +#{cell.site_link} +#{cell.date} +#{cell.location} +#{cell.price} +#{cell.flyer} +#{cell.blurb} +#{cell.links} +WOK +    end +    def output_form_select(type,id) +      case type +      when /site/ +        output_form_link(type,id) +      when /sponsor/ +        output_form_sponsor(type,id) +      when /search/ +        if id=~/hyperestraier/ +          output_form_search_hyperestraier(type,id) +        else output_form_search_sisu(type,id) +        end +      when /book/ +        output_form_book(type,id) +      when /journal/ +        output_form_journal(type,id) +      when /conference/ +        output_form_conference(type,id) +      end +    end +    def advert_extract_subject(category) #extracts products from category/subject list +      adverts=[] +      if defined? @ad[:promo_list][category] \ +      and @ad[:promo_list][category] +        @ad[:promo_list][category].keys.each do |type| +          @ad[:promo_list][category][type].each do |i| +            if i +              id=((i.inspect =~/^\d/) ? "id_#{i.to_s.strip}" : i.to_s.strip) #watch remove .to_s ? +              if defined? @ad[:promo][type][id] \ +              and not @ad[:promo][type][id].nil? +                adverts << output_form_select(type,id) +              else +                if defined? @ad[:promo][category][type][id] \ +                and @ad[:promo][category][type][id].is_a?(Array) \ +                and @ad[:promo][category][type][id].length > 0 +                  adverts << @ad[:promo][category][type][id].join("\n") +                end +              end +            end +          end +        end +      else +        SiSU_Screen::Ansi.new( +          @md.opt.act[:color_state][:set], +          "*WARN* category not found: #{category}" +        ).warn unless @md.opt.act[:quiet][:set]==:on +      end +      adverts.join +    end +    def advert_extract_all #extracts all products from list (which is broken down into categories) +      adverts=[] +      @ad[:promo_list].keys.each do |category| +        adverts << advert_extract_subject(category) +      end +      adverts.flatten +    end +    def adverts(ads) +      <<WOK +#{div.minor} +#{ads} +#{div.close} +WOK +    end +    def no_adverts +      <<WOK +#{div.minor} +#{div.close} +WOK +    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 +    html + +  - 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 diff --git a/org/hub.org b/org/hub.org new file mode 100644 index 00000000..3199aa35 --- /dev/null +++ b/org/hub.org @@ -0,0 +1,3163 @@ +-*- mode: org -*- +#+TITLE:       sisu hub +#+DESCRIPTION: documents - structuring, various output representations & search +#+FILETAGS:    :sisu:hub: +#+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 + +* hub +** hub.rb + +#+BEGIN_SRC ruby  :tangle "../lib/sisu/hub.rb" +# <<sisu_document_header>> +module SiSU +  require_relative 'constants'                         # constants.rb +  require_relative 'se'                                # se.rb +    include SiSU_Env +    include SiSU_Screen +  require_relative 'hub_actions'                       # hub_actions.rb +  require_relative 'hub_loop_markup_files'             # hub_loop_markup_files.rb +  require_relative 'hub_options'                       # hub_options.rb +  require_relative 'dp'                                # dp.rb +    include SiSU_Param +  require_relative 'utils'                             # utils.rb +  begin +    require 'uri' +  rescue LoadError +    SiSU_Utils::CodeMarker.new(__LINE__,__FILE__,:fuchsia). +      error('uri NOT FOUND (LoadError)') +  end +  class HubMaster +    def initialize(argv,sisu_runtime) +      begin +        opt=SiSU_Commandline::Options.new(argv,sisu_runtime) +        SiSU::Processing.new(opt).actions_without_files +        SiSU::Processing.new(opt).actions_on_files +        SiSU::Processing.new(opt).actions_without_files_post +      rescue +        selection=(opt ? opt.selections.src : argv) +        SiSU_Screen::Ansi.new(selection,$!,$@).rescue do +          __LINE__.to_s + ':' + __FILE__ +        end +      ensure +        Dir.chdir(sisu_runtime[:call_path]) +      end +    end +  end +  class Processing +    begin +      require 'fileutils' +        include FileUtils +    rescue LoadError +      SiSU_Utils::CodeMarker.new(__LINE__,__FILE__,:fuchsia). +        error('fileutils NOT FOUND (LoadError)') +    end +    @@env=nil +    attr_accessor :op +    def initialize(opt) +      @opt=opt +      @@env=@env=SiSU_Env::InfoEnv.new +      @msg,@msgs='',nil +      @tell=lambda { +        SiSU_Screen::Ansi.new( +          @opt.selections.str, +          @msg, +          "#{@msgs.inspect if @msgs}" +        ) +      } +    end +    def remove_skipped_files_if_any_from_processing_files_array +      if @remove_faulty_markup_files_array.length > 0 +        @opt.files = (@opt.files - @remove_faulty_markup_files_array) +      end +    end +    def print_error_message_if_files_skipped +      if @remove_faulty_markup_files_array.length > 0 +        puts '---' +        STDERR.puts 'ERROR with file(s), did not process: ' + +          @remove_faulty_markup_files_array.join(',') +      end +    end +    def do_each_file_loop_check_and_perform_selected_actions(opt) +      actions=SiSU_Hub_Actions::HubActions.new(opt) +      actions.outputs.each_file.abstract_objects? +      actions.outputs.each_file.qrcode? +      actions.outputs.each_file.hash_digests? +      actions.outputs.each_file.text? +      actions.outputs.each_file.html? +      actions.outputs.each_file.xhtml? +      actions.outputs.each_file.xml? +      actions.outputs.each_file.json? +      actions.outputs.each_file.pdf? +      actions.outputs.each_file.man_or_info? +      actions.outputs.each_file.po4a_make? +      actions.outputs.each_file.sqlite_discrete? +      actions.outputs.each_file.manifest? +    end +    def do_each_file_loop_options +      if @opt.files.length > 0 +        @opt.files.each_with_index do |fno,i| +          @opt.fno=fno +          @opt.fns=fno. +            gsub(/(?:https?|file):\/\/\S+\/(\S+)\.sst$/,'\1.-sst'). +            gsub(/\.ssm$/,'.ssm.sst') +          @opt.f_pth=@opt.f_pths[i] +          if @opt.fns !~/\.-sst$/ +            @opt.pth=@opt.f_pths[i][:pth] +            @opt.lng=@opt.f_pths[i][:lng] +          else +            @opt.pth=Dir.pwd +            @opt.lng='en' +          end +          unless @opt.pth.nil? +            @@pwd=@opt.pth +            Dir.chdir(@opt.pth) #watch +          end +          #@env=SiSU_Env::InfoEnv.new(@opt.fns) +          do_each_file_loop_check_and_perform_selected_actions(@opt) +        end +      else +        do_each_file_loop_check_and_perform_selected_actions(@opt) +      end +    end +    def do_loop_files_on_given_option_pre +      begin +        if @opt.act[:zap][:set]==:on                   #% --zap, -Z +          SiSU_Hub_Loops::OptionLoopFiles.new(@opt).loop_files_on_given_option do +            require_relative 'zap' +            SiSU_Zap::Source.new(@opt).read            # -Z     zap.rb +          end +        end +      ensure +      end +    end +    def do_loop_files_on_given_option_post +      actions=SiSU_Hub_Actions::HubActions.new(@opt) +      if defined? actions.outputs.loop_files.share_source? +        actions.outputs.loop_files.share_source? +      end +      if defined? actions.outputs.loop_files.run_termsheet? +        actions.outputs.loop_files.run_termsheet? +      end +      if defined? actions.outputs.loop_files.po4a_setup? +        actions.outputs.loop_files.po4a_setup? +      end +      if defined? actions.outputs.loop_files.sql? +        actions.outputs.loop_files.sql? +      end +      SiSU_Hub_Actions::Operations.new.counter +      if defined? actions.outputs.loop_files.manifest? +        actions.outputs.loop_files.manifest? +      end +      if defined? actions.outputs.loop_files.sitemaps? +        actions.outputs.loop_files.sitemaps? +      end +      if defined? actions.outputs.loop_files.urls? +        actions.outputs.loop_files.urls? +      end +    end +    def actions_without_files +      actions=SiSU_Hub_Actions::HubActions.new(@opt) +      actions.report.version_info? +      actions.report.version_info_extra? +      actions.prepare.site? +      actions.prepare.sql? +    end +    def actions_without_files_post +      actions=SiSU_Hub_Actions::HubActions.new(@opt) +      actions.prepare.remote_site? +      actions.prepare.search_form? +      actions.prepare.webrick? +    end +    def actions_on_files +      if @opt.act[:profile][:set]==:on +        begin +          require 'profile' +        rescue LoadError +          SiSU_Utils::CodeMarker.new(__LINE__,__FILE__,:fuchsia). +            error('profile NOT FOUND (LoadError)') +        end +      end +      actions=SiSU_Hub_Actions::HubActions.new(@opt) +      actions.outputs.each_file.harvest? +      actions.outputs.init? +      do_loop_files_on_given_option_pre +      do_each_file_loop_options +      #remove_skipped_files_if_any_from_processing_files_array # NEEDS WORK +      do_loop_files_on_given_option_post +      #print_error_message_if_files_skipped +      if (@opt.act[:verbose][:set]==:on \ +      || @opt.act[:verbose_plus][:set]==:on \ +      || @opt.act[:maintenance][:set]==:on) +        @msg,@msgs="\tsisu -W [to start ruby web-server on output directory]\n",nil +      end +      if (@opt.act[:verbose][:set]==:on \ +      || @opt.act[:verbose_plus][:set]==:on \ +      || @opt.act[:maintenance][:set]==:on \ +      || @opt.act[:urls_selected][:set]==:on \ +      || @opt.act[:urls_all][:set]==:on) +        @tell.call.print_brown unless @opt.files.join.empty? +      end +      if defined? @@env.processing_path.processing \ +      and @@env.user \ +      and FileTest.directory?(@@env.processing_path.processing) \ +      and @@env.processing_path.processing =~/#{@@env.user}$/ +        #clean tmp processing dir of content as is located in public area +        if @@env.processing_path.processing_base_tmp =~/^\/tmp\/\S+/ +          FileUtils::cd(@@env.processing_path.processing_base_tmp) do +            FileUtils::rm_rf('.') unless @opt.act[:maintenance][:set] ==:on +          end +        end +      end +    end +  end +  class HubClose +    def initialize(call_path,argv) +      begin +        env=SiSU_Env::InfoEnv.new +      rescue +      ensure +        if FileTest.directory?(env.processing_path.processing) \ +        and FileTest.directory?(env.processing_path.processing_base_tmp) \ +        and env.processing_path.processing_base_tmp =~ /#{env.processing_path.processing}/ \ +        and env.processing_path.processing_base_tmp =~/^\/tmp\/\S+/ \ +        and not argv.inspect =~/"--maintenance"|"-M"/ +          FileUtils::cd(env.processing_path.processing_base_tmp) do +            FileUtils::rm_rf('.') +          end +        end +        Dir.chdir(call_path) +      end +    end +  end +end +__END__ +#+END_SRC + +** hub_options.rb + +#+BEGIN_SRC ruby  :tangle "../lib/sisu/hub_options.rb" +# <<sisu_document_header>> +module SiSU_Commandline +  begin +    require 'pathname' +  rescue LoadError +    SiSU_Utils::CodeMarker.new(__LINE__,__FILE__,:fuchsia). +      error('pathname NOT FOUND (LoadError)') +  end +  require_relative 'se'                                 # se.rb +  require_relative 'dp_make'                            # dp_make.rb +  class HeaderCommon +    def sisu_document_make_instructions(make_instruct_array=:nil) +      @pagenew= +        @pagebreak= +        @pageline= +        @toc= +        @lv1=@lv2=@lv3=@lv4=@lv5=@lv6= +        @num_top= +        @i18n= +        @man_section= +        @emphasis_set_to= +        @bold_match_list= +        @italics_match_list= +        @substitution_match_list= +        @footer_links= +        @home_button_links= +        @links= +        nil +      make_instruct_array=make_instruct_array==:nil \ +      ? SiSU_Env::GetInit.new.sisu_document_make.makefile_read +      : make_instruct_array +      @makeset=false +      if make_instruct_array +        make_instruct_array.each do |para|                                     #% scan document +          if para =~/^(?:@make:|@links:)[+-]?\s/ +            case para +            when /^@make:(.+)/m                                                #% header processing - make +              @env=SiSU_Env::InfoEnv.new +              @make=SiSU_Param_Make::MdMake.new($1.strip,@opt,@env).make +              makes=SiSU_Param_Make::MakeHead.new(@make).make_instruct +              @makeset=true +              @pagenew=makes[:pagenew] +              @pagebreak=makes[:pagenew] +              @pageline=makes[:pageline] +              @toc=makes[:toc] +              @lv1=makes[:lv1] +              @lv2=makes[:lv2] +              @lv3=makes[:lv3] +              @lv4=makes[:lv4] +              @lv5=makes[:lv5] +              @lv6=makes[:lv6] +              @num_top=makes[:num_top] +              @i18n=makes[:i18n] +              @man_section=makes[:man_section] +              @emphasis_set_to=makes[:emphasis_set_to] +              @bold_match_list=makes[:bold_match_list] +              @italics_match_list=makes[:italics_match_list] +              @substitution_match_list=makes[:substitution_match_list] +              @footer_links=makes[:footer_links] +              @home_button_links=makes[:home_button_links] +              @home_button_image=makes[:home_button_image] +              @cover_image=makes[:cover_image] +            when /^@links:(.+)/m                                                #% header processing - make +              make_links=SiSU_Param::Parameters::MdMake.new($1.strip,@opt,@env).make_links +              @links,@links_append=make_links.links,make_links.append? +            end +          end +        end                                                                    #% here endeth the common header loop +      end +      { makeset: @makeset, +        pagenew: @pagenew, +        pagebreak: @pagebreak, +        pageline: @pageline, +        toc: @toc, +        lv1: @lv1, +        lv2: @lv2, +        lv3: @lv3, +        lv4: @lv4, +        lv5: @lv5, +        lv6: @lv6, +        num_top: @num_top, +        i18n: @i18n, +        man_section: @man_section, +        emphasis_set_to: @emphasis_set_to, +        bold_match_list: @bold_match_list, +        italics_match_list: @italics_match_list, +        substitution_match_list: @substitution_match_list, +        footer_links: @footer_links, +        home_button_links: @home_button_links, +        home_button_image: @home_button_image, +        cover_image: @cover_image, +        links: @links, +        links_append: @links_append +      } +    end +  end +  class Options +    attr_accessor :selections,:opt_ch,:act,:dir_structure_by,:lingual,:f_pths,:files,:files_mod,:call_path,:base_path,:base_stub,:sub_location,:image_src_path,:paths,:lngs,:f_pth,:pth,:fno,:fns,:fnb,:fnc,:fng,:fncb,:lng,:lng_base,:what,:make_instructions,:make_instructions_pod,:sisu_run_path,:sisu_install_type +    @@act=nil +    def initialize(a,sisu_runtime) +      @opt_ch=@f_pth=@pth=@fno=@fns=@fnb=@fnc=@fng=@fncb=@what=@lng=@lng_base=@call_path=@base_path=@base_stub=@image_src_path=@sub_location='' +      @f_pths,@files,@files_mod,@paths,@select_arr,@act=Array.new(5){[]} +      @select_str=nil +      @env=SiSU_Env::InfoEnv.new +      @lng_base=@env.language_default_set +      @dir_structure_by=SiSU_Env::EnvCall.new.output_dir_structure.by? +      @lingual=SiSU_Env::EnvCall.new.mono_multi_lingual? +      @sisu_run_from=sisu_runtime[:runtime_path] +      @sisu_install_type=sisu_runtime[:runtime_type] +      @call_path=sisu_runtime[:call_path] +      pth=SiSU_Utils::Path.new(call_path) +      @base_path=pth.base_markup +      @base_stub=pth.base_markup_stub +      @image_src_path=pth.image_src +      @a=sisu_glob_rules(a) +      @a.freeze +      @make_instructions=HeaderCommon.new.sisu_document_make_instructions +      @make_instructions_pod=nil +      init +    end +    def sisu_called_from? +      @call_path +    end +    def sisu_bin_filepath? +      @sisu_run_from +    end +    def sisu_install_type? +      @sisu_install_type +    end +    def sisu_lib_dir? +      File.dirname(__FILE__) +    end +    def sisu_data_dir? +      env=RbConfig::CONFIG +      if sisu_install_type? ==:full_path_to_sisu_bin_in_sisu_dir_tree +        sisu_bin_filepath?.gsub(/\/bin\/sisu\S*/,'/data/sisu') +        #sisu_lib_dir?.gsub(/\/lib\/sisu\/(?:current|develop)\S*/,'/data/sisu') +      elsif sisu_install_type? ==:gem_install +        #sisu_run_from?.gsub(/\/bin\/.+/,'/data/sisu') +        env['datadir'] +      elsif sisu_install_type? ==:system_install +        #SiSU_Info_Env::InfoEnv.new.path.share +        env['datadir'] +      else +        env['datadir'] +      end +    end +    def find_all(find_flag,opt) +      if find_flag +        x=Dir.glob('*.ss[tm]') +        Px[:lng_lst].each do |d| +          if FileTest.directory?(d) +            x << Dir.glob("#{d}/*.ss[tm]") +          end +        end +        x=x.flatten +        opt + x +      end +    end +    def find_select(find_flag,opt) +      if find_flag +        x=[] +        if opt.inspect =~/"[a-zA-Z][a-zA-Z0-9._-]+?"/ +          opt.each do |g| +            x <<=if g =~/.ss[tm]/ +              Dir.glob("*#{g}") +            else +              Dir.glob("*#{g}*.ss[tm]") +            end +            Px[:lng_lst].each do |d| +              if FileTest.directory?(d) +                x <<=if g =~/.ss[tm]/ +                  Dir.glob("#{d}/*#{g}") +                else +                  Dir.glob("#{d}/*#{g}*.ss[tm]") +                end +              end +            end +          end +        end +        x.flatten +      end +    end +    def sisu_glob_rules(a) +      a=if a.inspect =~/"-[A-Za-z0-9]*[fG]/ \ +      or a.inspect =~/"--find"|"--glob"/ +        b,f=[],[] +        find_flag=false +        a.each do |y| +          if y =~ /^-/ +            if y =~/^-/ \ +            && y =~/[fG]|--find|--glob/ +              find_flag=true +            end +            b << y +          end +          if find_flag \ +          && y !~ /^-/ \ +          && y =~ /\S+/ +            if y !~/\// +              f << y +            else +              find_flag=false +              puts %{sub-directories "#{y}" cannot be provided for --find or --glob at this time} +            end +          end +        end +        r=Px[:lng_lst_rgx].gsub(/\|#{lng_base}\|/,'|') +        @lang_regx=%r{(?:#{r})} +        if find_flag +          (f.length > 0) \ +          ? (b + find_select(find_flag,f)) +          : find_all(find_flag,b) +        elsif a.inspect =~/"(?:-\S+?|--\S+?)"/ \ +        && a.inspect =~/"#{@lang_regx}\/?"/ \ +        && a.inspect =~/"#{lng_base}\/\S+?\.ss[tm]"/ +          init_selected_lang_dirs(a) +        else b +        end +      else a +      end +    end +    def init_selected_lang_dirs(a) +      @z=a.each.map do |y| +        if y =~/^#{lng_base}\/(\S+?\.ss[tm])$/ +          @fn=$1 +          y +        elsif y =~/^#{@lang_regx}\/?$/ +          "#{y}/#{@fn}" +        else y +        end +      end +    end +    def init +      a=@a +      s=expand_numeric_shortcuts(a) +      q=set_files_and_paths_and_general_extract(s) +      files=(q[:files].length > 0) ? :true : :false +      @select_arr=opt_cmd_and_mod_adjust(q[:opt_ch],q[:selections],files) +      if a.length > 0 +        @what=q[:what] unless q[:what].empty? +        @paths = q[:paths] +        @files = q[:files] +        @f_pths = q[:f_pths] +        @lngs = q[:lngs] +        if @files.length > 0 \ +        and @opt_ch.empty? \ +        and @select_arr.length==0 #% if no other action called on filename given, default is sisu --v5 -0 [filename(s)] configured as flag default +          shortcut=SiSU_Env::InfoProcessingFlag.new +          @select_arr=['--v5'] +          @select_arr << shortcut.act_0.arr #+ ' --dal' +        end +        if @select_arr.inspect =~/--verbose/ \ +        && @opt_ch !~/-[ku]*v[ku]*$/ +          SiSU_Screen::Ansi.new( +            @opt_ch, +            "\tsisu " + @opt_ch +  ' ' + @select_arr.join(' ') + ' ' + @files.join(' ') + "\n" +          ).print_brown +        end +      end +      @@act ? @act=@@act : @@act=@act=opt_act +      self +    end +    def sisu_document_make_pod +      def makefile_name +        SiSU_Env::GetInit.new.sisu_document_make.makefile_name +      end +      def makefile(pod_make_path) +        "#{pod_make_path}/#{makefile_name}" +      end +      def makefile_read(pod_make_path) +        if FileTest.file?(makefile(pod_make_path)) +          sisu_doc_makefile=IO.read(makefile(pod_make_path), mode: 'r:utf-8') +          sisu_doc_makefile.split(/\s*\n\s*\n/m) +        else nil +        end +      end +      self +    end +    def set_files_and_paths_and_general_extract(s) +      c,w='','' +      m,f,pth,lng,lngs=[],[],[],[],[] +      lng_is='' +      a=(s.nil?) \ +      ? ['-v'] +      : s.split(/\s+/) +      r_l=Px[:lng_lst].join('|') +      a.uniq.each do |x| +        if x =~/^-[a-z0-5]+/i \ +        or x =~/^--\S+/ +          if x =~/^-([a-z0-5]+)/i +            c << $1 +          end +          if x =~/^--\S+/ +            m << x +          end +        elsif x =~ /(?:\.(?:(?:-|ssm\.)?sst(?:\.xml)?|ssm|ssi|sx[sdn]\.xml|s[1-3]|kdi|ssp)|\S+?\.ss[mt]\.(?:txz|zip)|sisupod\.(?:txz|zip))$/ +          if x =~/\S+?\.ss[mt]\.(?:txz|zip)|sisupod\.(?:txz|zip)/ +            if x =~/^(?:https?|file):\/\/\S+/ #\ +            end +            pwd=Dir.pwd +            fn_pod=x.gsub(/([^\/]+)\.txz$/,'\1') +            fullname=@env.processing_path.processing + '/sisupod/' + fn_pod +            pt=Pathname.new(fullname) +            FileUtils::mkdir_p(pt.to_s) +            pod_make_path=fullname + '/sisupod/doc/_sisu' +            make_instruct_array=sisu_document_make_pod.makefile_read(pod_make_path) +            @make_instructions_pod= +              HeaderCommon.new.sisu_document_make_instructions(make_instruct_array) +            Dir.chdir(pt.realpath) +            system(" +              chdir #{fullname} +              tar xaf #{pwd}/#{x} +              chdir #{pwd} +            ") +            Dir.chdir(pt.realpath.to_s + '/sisupod/doc') +            r=Px[:lng_lst_rgx] +            Dir.entries("#{fullname}/sisupod/doc").each do |d_lng| +              if d_lng =~/^(?:#{r})$/ +                Dir.chdir(pt.realpath.to_s + "/sisupod/doc/#{d_lng}") +                filenames=Dir.glob("*.ss[mt]") +                filenames.each do |fn| +                  f_pths << { +                    pth: "#{fullname}/sisupod/doc/#{d_lng}", +                    f: "#{fn}", +                    pth_stub: 'doc', +                    lng: d_lng, +                    lng_is: d_lng, +                    url_base: '', +                    url: '' +                  } +                  Dir.chdir(pwd) +                  f << fn +                end +              end +            end +          elsif x =~/^(?:https?|file):\/\/\S+/ \ +          and x =~/\S+?\.ss[mt]$/ +            r_url=/(http:\/\/\S+?\/\S+?\/src(?:\/(?:#{r_l}))?)\// +            url_base = (x[r_url,1]) +            url = x +            y=x.gsub(/http:\/\/\S+?\/\S+?\/src\//,'') +            t=/(#{r_l})\/[^\/]+?\.ss[tm]$/ +            l_p = (y[t,1]) \ +              ? y[t,1] +              : nil +            lng << l_p +            lngs << if l_p +              l_p +            elsif x =~/~(#{r_l})\.ss[tm]/ +              $1 +            else lng_base +            end +            r_f=/(?:#{r_l})\/([^\/]+?\.ss[tm])$/ +            fn = (y[r_f,1]) \ +              ? y[r_f,1] +              : y +            fn=fn.gsub(/\.((?:ssm\.)?sst)/,'.-\1') +            fullname=Dir.pwd + '/' + fn +            pt=Pathname.new(fullname) +            pth << Dir.pwd +            r_u=/.+?\/([^\/]+)(?:\/(?:#{r_l})$|$)/ +            lng_is =if l_p +              l_p +            elsif x =~/~(#{r_l})\.ss[tm]/ +              $1 +            else lng_base +            end +            f_pths << { +              pth: pt.split[0].realpath.to_s, +              f: pt.split[1].to_s, +              pth_stub: pt.split[0].realpath.to_s[r_u,1], +              lng: (pt.split[0].realpath.to_s[t,1]) \ +                ? pt.split[0].realpath.to_s[t,1] +                : nil, +              lng_is: lng_is, +              url_base: url_base, +              url: url +            } +            f << fn +          elsif FileTest.file?(x) +            pt=Pathname.new(x) +            pth << pt.split[0].realpath.to_s     #remove? +            f << pt.split[1].to_s                #remove? +            r_u=/.+?\/([^\/]+)(?:\/(?:#{r_l})$|$)/ +            t=/.+\/(#{r_l})$/ +            l_p = (pt.split[0].realpath.to_s[t,1]) \ +              ? pt.split[0].realpath.to_s[t,1] +              : nil +            lngs << lng_is = if l_p +              l_p +            elsif x =~/~(#{r_l})\.ss[tm]/ +              $1 +            else lng_base +            end +            f_pths << { +              pth: pt.split[0].realpath.to_s, +              f: pt.split[1].to_s, +              pth_stub: pt.split[0].realpath.to_s[r_u,1], +              lng: lng_is, +              lng_is: lng_is, +              url_base: nil, +              url: nil, +            } +          else  puts "file not found: #{x}" +          end +        elsif x =~ /\.termsheet\.rb$/ +          (FileTest.file?(x)) \ +          ? (f << x) +          : (puts "file not found: #{x}") +        else w=x +          puts "#{x} in #{a.join(' ')}?" +        end +      end +      { +        opt_ch: c, +        selections: m, +        what: w, +        paths: pth, +        files: f, +        f_pths: f_pths, +        lng: lng_is, +        lngs: lngs, +      } +    end +    def expand_numeric_shortcuts(a) +      s='' +      a.each do |x| +        y=case x +        when /0/ +          (x=~/^-0\S+/) \ +          ? x.gsub(/^-0(\S+)/,'--act0' + ' -\1') +          : x.gsub(/^-0/,'--act0' + ' ') +        when /1/ +          (x=~/^-1\S+/) \ +          ? x.gsub(/^-1(\S+)/,'--act1' + ' -\1') +          : x.gsub(/^-1/,'--act1' + ' ') +        when /2/ +          (x=~/^-2\S+/) \ +          ? x.gsub(/^-2(\S+)/,'--act2' + ' -\1') +          : x.gsub(/^-2/,'--act2' + ' ') +        when /3/ +          (x=~/^-3\S+/) \ +          ? x.gsub(/^-3(\S+)/,'--act3' + ' -\1') +          : x.gsub(/^-3/,'--act3' + ' ') +        when /4/ +          (x=~/^-4\S+/) \ +          ? x.gsub(/^-4(\S+)/,'--act4' + ' -\1') +          : x.gsub(/^-4/,'--act4' + ' ') +        when /5/ +          (x=~/^-5\S+/) \ +          ? x.gsub(/^-5(\S+)/,'--act5' + ' -\1') +          : x.gsub(/^-5/,'--act5' + ' ') +        when /6/ +          (x=~/^-6\S+/) \ +          ? x.gsub(/^-6(\S+)/,'--act6' + ' -\1') +          : x.gsub(/^-6/,'--act6' + ' ') +        when /7/ +          (x=~/^-7\S+/) \ +          ? x.gsub(/^-7(\S+)/,'--act7' + ' -\1') +          : x.gsub(/^-7/,'--act7' + ' ') +        when /8/ +          (x=~/^-8\S+/) \ +          ? x.gsub(/^-8(\S+)/,'--act8' + ' -\1') +          : x.gsub(/^-8/,'--act8' + ' ') +        when /9/ +          (x=~/^-9\S+/) \ +          ? x.gsub(/^-9(\S+)/,'--act9' + ' -\1') +          : x.gsub(/^-9/,'--act9' + ' ') +        else x +        end +        s << " #{y}" unless y.empty? +      end +      s.strip! +    end +    def opt_cmd_and_mod_adjust(ch,select_arr,files) +      select_arr=select_arr.flatten +      sel_init=select_arr.flatten +      shortcut=SiSU_Env::InfoProcessingFlag.new +      if files ==:true +        if not sel_init.empty? \ +        and sel_init.inspect =~/"--act[s0-9]?/ +          sel_init.each do |s| +            select_arr <<=case s +            when /--act0/ then shortcut.act_0.arr +            when /--act1/ then shortcut.act_1.arr +            when /--act2/ then shortcut.act_2.arr +            when /--act3/ then shortcut.act_3.arr +            when /--act4/ then shortcut.act_4.arr +            when /--act5/ then shortcut.act_5.arr +            when /--act6/ then shortcut.act_6.arr +            when /--act7/ then shortcut.act_7.arr +            when /--act8/ then shortcut.act_8.arr +            when /--act9/ then shortcut.act_9.arr +            when /--act/  then shortcut.act_info +            end +          end +        end +        if not sel_init.empty? \ +        and sel_init.inspect =~/"--pdf-/ +          select_arr << '--pdf' +          sel_init.each do |s| +            if s =~ /^--pdf-(?:(?:l|landscape)(?:-(?:a4|letter|a5|b5|legal))?|(?:a4|letter|a5|b5|legal)-(?:l|landscape))$/ +              select_arr << '--landscape' +            end +            if s =~ /^--pdf-(?:(?:p|portrait)(?:-(?:a4|letter|a5|b5|legal))?|(?:a4|letter|a5|b5|legal)-(?:p|portrait))$/ +              select_arr << '--portrait' +            end +            if s =~ /^--pdf(?:-(?:a4|letter|a5|b5|legal)(?:-(?:[lp]|landscape|portrait))?|(?:-(?:[lp]|landscape|portrait))(?:-(?:a4|letter|a5|b5|legal)))$/ +              if s =~ /^--pdf(?:-a4(?:-(?:[lp]|landscape|portrait))?|(?:-(?:[lp]|landscape|portrait))-a4)$/ +                select_arr << '--papersize-a4' +              end +              if s =~ /^--pdf(?:-a5(?:-(?:[lp]|landscape|portrait))?|(?:-(?:[lp]|landscape|portrait))-a5)$/ +                select_arr << '--papersize-a5' +              end +              if s =~ /^--pdf(?:-b5(?:-(?:[lp]|landscape|portrait))?|(?:-(?:[lp]|landscape|portrait))-b5)$/ +                select_arr << '--papersize-b5' +              end +              if s =~ /^--pdf(?:-letter(?:-(?:[lp]|landscape|portrait))?|(?:-(?:[lp]|landscape|portrait))-letter)$/ +                select_arr << '--papersize-letter' +              end +              if s =~ /^--pdf(?:-legal(?:-(?:[lp]|landscape|portrait))?|(?:-(?:[lp]|landscape|portrait))-legal)$/ +                select_arr << '--papersize-legal' +              end +            end +          end +          select_arr=select_arr.uniq +        end +        if ch.empty? \ +        and sel_init.length == 0 +          select_arr << shortcut.act_0.arr ################ & --flag empty +        elsif not ch.empty? +          if ch =~/c/ then select_arr << '--color-toggle' +            ch=ch.gsub(/[c]/,'') +          end +          if ch =~/k/ then select_arr << '--color-off' +            ch=ch.gsub(/[k]/,'') +          end +          if ch =~/C/ then select_arr << '--config' +            ch=ch.gsub(/[C]+/,'') +          end +          if ch =~/m/ then select_arr << '--dal' +            ch=ch.gsub(/[m]/,'') +          end +          if ch =~/t/ then select_arr << '--txt' +            ch=ch.gsub(/[t]/,'') +          end +          if ch =~/h/ then select_arr << '--html' +            ch=ch.gsub(/[h]/,'') +          end +          if ch =~/e/ then select_arr << '--epub' +            ch=ch.gsub(/[e]/,'') +          end +          if ch =~/o/ then select_arr << '--odt' +            ch=ch.gsub(/[o]/,'') +          end +          if ch =~/d/ then select_arr << '--docbook' +            ch=ch.gsub(/[d]/,'') +          end +          if ch =~/p/ then select_arr << '--pdf' +            ch=ch.gsub(/[p]/,'') +          end +          if ch =~/w/ then select_arr << '--concordance' +            ch=ch.gsub(/[w]/,'') +          end +          if ch =~/i/ then select_arr << '--manpage' +            ch=ch.gsub(/[i]/,'') +          end +          if ch =~/I/ then select_arr << '--texinfo' +            ch=ch.gsub(/[I]/,'') +          end +          if ch =~/b/ then select_arr << '--xhtml' +            ch=ch.gsub(/[b]/,'') +          end +          if ch =~/x/ then select_arr << '--xml-sax' +            ch=ch.gsub(/[x]/,'') +          end +          if ch =~/X/ then select_arr << '--xml-dom' +            ch=ch.gsub(/[X]/,'') +          end +          if ch =~/j/ then select_arr << '--images' +            ch=ch.gsub(/[j]/,'') +          end +          if ch =~/J/ then select_arr << '--json' +            ch=ch.gsub(/[J]/,'') +          end +          if ch =~/N/ then select_arr << '--digests' +            ch=ch.gsub(/[N]/,'') +          end +          if ch =~/P/ then select_arr << '--po4a-sst' +            ch=ch.gsub(/[P]/,'') +          end +          if ch =~/d/ then select_arr << '--sqlite' +            ch=ch.gsub(/[d]/,'') +          end +          if ch =~/D/ then select_arr << '--pg' +            ch=ch.gsub(/[D]/,'') +          end +          if ch =~/Q/ then select_arr << '--qrcode' +            ch=ch.gsub(/[Q]/,'') +          end +          if ch =~/s/ then select_arr << '--source' +            ch=ch.gsub(/[s]/,'') +          end +          if ch =~/S/ then select_arr << '--sisupod' +            ch=ch.gsub(/[S]/,'') +          end +          if ch =~/m/ then select_arr << '--manifest' +            ch=ch.gsub(/[m]/,'') +          end +          if ch =~/R/ then select_arr << '--rsync' +            ch=ch.gsub(/[R]/,'') +          end +          if ch =~/r/ then select_arr << '--scp' +            ch=ch.gsub(/[r]/,'') +          end +          if ch =~/g/ then select_arr << '--git' +            ch=ch.gsub(/[g]/,'') +          end +          if ch =~/U/ then select_arr << '--urls' +            ch=ch.gsub(/[u]/,'') +          end +          if ch =~/Z/ then select_arr << '--zap' +            ch=ch.gsub(/[Z]/,'') +          end +          if ch =~/F/ then select_arr << '--sample-search-form' +            ch=ch.gsub(/[F]/,'') +          end +          if ch =~/W/ then select_arr << '--webrick' +            ch=ch.gsub(/[w]/,'') +          end +          if ch =~/M/ then select_arr << '--maintenance' +            ch=ch.gsub(/[M]/,'') +          end +          if ch =~/V/ then select_arr << '--very-verbose' +            ch=ch.gsub(/[V]/,'') +          end +          if ch =~/v/ then select_arr << '--verbose' +            ch=ch.gsub(/[v]/,'') +          end +          if ch =~/q/ then select_arr << '--quiet' +            ch=ch.gsub(/[q]/,'') +          end +          if select_arr.inspect !~/--urls/ \ +          and select_arr.inspect \ +          !~/"--harvest/ +            select_arr << '--urls' +          end +          if select_arr.inspect !~/--dal/ \ +          and select_arr.inspect =~/txt|text|html|odt|epub|docbook|xml|pdf|manpage|texinfo|concordance|qrcode|source|sisupod|pg|sqlite|zap/ +            select_arr << '--dal' +          end +          if select_arr.inspect !~/--manifest/ \ +          and select_arr.inspect =~/txt|text|html|odt|epub|docbook|xml|pdf|manpage|texinfo|concordance|qrcode|source|sisupod|pg|sqlite|zap/ +            select_arr << '--manifest' +          end +          if select_arr.inspect !~/--images/ \ +          and select_arr.inspect =~/html|odt|docbook|xml|qrcode/ +            select_arr << '--images' +          end +        end +      else +        if not sel_init.empty? \ +        and sel_init.inspect =~/"--acts?/ +          shortcut.act_info +          exit +        end +        if ch =~/c/ then select_arr << '--color-toggle' +          ch=ch.gsub(/[c]/,'') +        end +        if ch =~/k/ then select_arr << '--color-off' +          ch=ch.gsub(/[k]/,'') +        end +        if ch =~/C/ then select_arr << '--config' +          ch=ch.gsub(/[C]+/,'') +        end +        if sel_init.inspect =~/"--createdb"|"--create(?:all)?"|"--dropall"|"--recreate(?:all)?"/ +          if ch =~/d/ then select_arr << '--sqlite' +            ch=ch.gsub(/[d]/,'') +          end +          if ch =~/D/ then select_arr << '--pg' +            ch=ch.gsub(/[D]/,'') +          end +        end +        if ch =~/W/ then select_arr << '--webrick' +          ch=ch.gsub(/[w]/,'') +        end +        if ch =~/v/ then select_arr << '--version' +          ch=ch.gsub(/[v]/,'') +        end +        if ch =~/M/ then select_arr << '--maintenance' +          ch=ch.gsub(/[M]/,'') +        end +        if ch =~/V/ then select_arr << '--very-verbose' +          ch=ch.gsub(/[V]/,'') +        end +        if ch =~/q/ then select_arr << '--quiet' +          ch=ch.gsub(/[q]/,'') +        end +      end +      select_arr=select_arr.flatten.compact.uniq.sort +    end +    def opt_act +      select_arr=@select_arr +      @@act=if @@act +        @act=@@act +      else +        act={} +        act[:no_stop]=if select_arr.inspect \ +        =~/"--no-stop"|"--errors-as-warnings"/ +          { bool: true, set: :on } +        else +          { bool: false, set: :na } +        end +        act[:license]=(select_arr.inspect \ +        =~/"--license/) \ +        ? { bool: true, set: :on } +        : { bool: false, set: :na } +        act[:site_init]=(select_arr.inspect \ +        =~/"--init"|"--initialize"|"--init-site"|"--conf"|"--config"|"--configure"/) \ +        ? { bool: true, set: :on  } +        : { bool: false, set: :na } +        act[:rc]=if select_arr.inspect \ +        =~/"--rc=/ +          x=Dir.pwd + '/' + select_arr.join.gsub(/--rc=/,'') +          { bool: true, set: :on, inst: x } +        else +          { bool: false, set: :na, inst: '' } +        end +        act[:processing_path]=if select_arr.inspect \ +        =~/"--processing-path=/ +          base_pth=select_arr.join(';').gsub(/^.*--processing-path=['"]?(.+?)(?:['"]?;.+)?$/,'\1') +          { bool: true, set: :on, inst: base_pth } +        elsif select_arr.inspect \ +        =~/"--processing-path/ +          { bool: true, set: :on, inst: @base_path } +        else +          { bool: false, set: :na, inst: nil } +        end +        act[:dump]=if select_arr.inspect \ +        =~/"--dump=/ +          base_pth=select_arr.join(';'). +            gsub(/^.*--dump=['"]?(.+?)(?:['"]?;.+)?$/,'\1') +          { bool: true, set: :on, inst: base_pth } +        elsif select_arr.inspect =~/"--dump/ +          { bool: true, set: :on, inst: @base_path } +        else +          { bool: false, set: :na, inst: nil } +        end +        act[:redirect]=if select_arr.inspect \ +        =~/"--redirect=/ +          base_pth=select_arr.join(';'). +            gsub(/^.*--redirect=['"]?(.+?)(?:['"]?;.+)?$/,'\1') +          { bool: true, set: :on, inst: base_pth } +        elsif select_arr.inspect \ +        =~/"--redirect/ +          { bool: true, set: :on, inst: @base_path } +        else +          { bool: false, set: :na, inst: nil } +        end +        act[:switch]=if select_arr.inspect \ +        =~/"--switch-off=/ +          off_list=select_arr.join(';'). +            gsub(/^.*--switch-off=['"]?(.+?)(?:['"];.+)?$/,'\1') +          off_list=off_list.scan(/[^,;\s]+/) +          { bool: false, set: :off, off: off_list} +        else { bool: true, set: :na, off: [] } +        end +        act[:default_language]=if select_arr.inspect \ +        =~/"--(?:default-)?language[-=](\S{2})"/ +          { set: :on, code: $1 } +        elsif lng_base +          { set: :on, code: lng_base } +        else { set: :na, code: 'en' } +        end +        act[:i18n]=if select_arr.inspect \ +        =~/"(?:--monolingual|--i18n-mono(?:lingual)?)"/ #if monolingual possible outputs output_by :filename & :filetype only, without language code in default language name; give warning of conflict settings if monolingual & :language selected +          @lingual=:mono +          { set: :mono } +        elsif select_arr.inspect \ +        =~/"(?:--multilingual|--i18n-multi(?:lingual)?)"/ +          @lingual=:multi +          { set: :multi } +        else { set: :na } +        end +        act[:output_by]=if select_arr.inspect \ +        =~/"--(?:output-)?by-language"/ +          @dir_structure_by=:language +          { set: :language } +        elsif select_arr.inspect \ +        =~/"--(?:output-)?by-filename"/ +          @dir_structure_by=:filename +          { set: :filename } +        elsif select_arr.inspect \ +        =~/"--(?:output-)?by-filetype"/ +          @dir_structure_by=:filetype +          { set: :filetype } +        else { set: :na } +        end +        act[:ocn]=if select_arr.inspect \ +        =~/"--ocn"|"--inc-ocn"|"--numbering"|"--inc-numbering"/ +          { bool: true, set: :on } +        elsif select_arr.inspect \ +        =~/"--no-ocn"|"--exc-ocn"|"--no-numbering"|"--exc-numbering"/ \ +        || act[:switch][:off].inspect =~/"ocn"|"--numbering"/ +          { bool: false, set: :off } +        else { bool: true, set: :na } +        end +        act[:toc]=if select_arr.inspect \ +        =~/"--inc-toc"/ +          { bool: true, set: :on } +        elsif select_arr.inspect \ +        =~/"--(?:exc|no)-toc"/ \ +        || act[:switch][:off].inspect =~/"toc"/ +          { bool: false, set: :off } +        else { bool: true, set: :na } +        end +        act[:minitoc]=if select_arr.inspect \ +        =~/"--minitoc"|"--inc-minitoc"/ +          { bool: true, set: :on } +        elsif select_arr.inspect \ +        =~/"--(?:exc|no)-minitoc"/ \ +        || act[:switch][:off].inspect =~/"minitoc"/ +          { bool: false, set: :off } +        else { bool: false, set: :na } +        end +        act[:links_to_manifest]=if select_arr.inspect \ +        =~/"--inc-links-to-manifest"|"--inc-manifest-links"/ +          { bool: true, set: :on } +        elsif select_arr.inspect \ +        =~/"--(?:exc|no)-manifest"/ \ +        || act[:switch][:off].inspect =~/"manifest"/ #place lower +          { bool: false, set: :off } +        elsif select_arr.inspect \ +        =~/"--(?:exc|no)-links-to-manifest"|"--(?:exc|no)-manifest-links"/ \ +        || act[:switch][:off].inspect \ +        =~/"links_to_manifest"|"manifest_links"|"--(?:exc|no)-manifest"/ \ +        || select_arr.inspect \ +        =~/"--(?:redirect|dump)/ +          { bool: false, set: :off } +        else { bool: true, set: :na } +        end +        act[:manifest_minitoc]=if select_arr.inspect \ +        =~/"--inc-manifest-minitoc"|"--inc-minitoc"/ +          { bool: true, set: :on } +        elsif select_arr.inspect \ +        =~/"--(?:exc|no)-manifest-minitoc"|"--(?:exc|no)-minitoc"/ \ +        || act[:switch][:off].inspect =~/"manifest_minitoc"|"minitoc"/ +          { bool: false, set: :off } +        else { bool: false, set: :na } +        end +        act[:metadata]=if select_arr.inspect \ +        =~/"--metadata"|"--inc-metadata"/ +          { bool: true, set: :on } +        elsif select_arr.inspect \ +        =~/"--(?:exc|no)-metadata"/ \ +        || act[:switch][:off].inspect =~/"metadata"/ +          { bool: false, set: :off } +        else { bool: true, set: :na } +        end +        act[:html_minitoc]=if select_arr.inspect \ +        =~/"--inc-html-minitoc"|"--inc-minitoc"/ +          { bool: true, set: :on } +        elsif select_arr.inspect \ +        =~/"--(?:exc|no)-html-minitoc"|"--(?:exc|no)-minitoc"/ \ +        || act[:switch][:off].inspect =~/"html_minitoc"|"minitoc"/ +          { bool: false, set: :off } +        else { bool: false, set: :na } +        end +        act[:html_navigation]=if select_arr.inspect \ +        =~/"--inc-html-navigation"|"--inc-navigation"/ +          { bool: true, set: :on } +        elsif select_arr.inspect \ +        =~/"--(?:exc|no)-html-navigation"|"--(?:exc|no)-navigation"/ \ +        || act[:switch][:off].inspect =~/"html_navigation"|"nav"/ +          { bool: false, set: :off } +        else { bool: true, set: :na } +        end +        act[:html_navigation_bar]=if select_arr.inspect \ +        =~/"--inc-html-navigation-bar"|"--inc-navigation-bar"/ +          { bool: true, set: :on } +        elsif select_arr.inspect \ +        =~/"--(?:exc|no)-html-navigation-bar"|"--(?:exc|no)-navigation-bar"/ \ +        || act[:switch][:off].inspect =~/"html_navigation_bar"|"navbar"/ +          { bool: false, set: :off } +        else { bool: false, set: :na } +        end +        act[:segsubtoc]=if select_arr.inspect \ +        =~/"--inc-segsubtoc"/ +          { bool: true, set: :on } +        elsif select_arr.inspect \ +        =~/"--(?:exc|no)-segsubtoc"/ \ +        || act[:switch][:off].inspect =~/"segsubtoc"/ +          { bool: false, set: :off } +        else { bool: true, set: :na } +        end +        act[:search_form]=if select_arr.inspect \ +        =~/"--inc-search-form"/ +          { bool: true, set: :on } +        elsif select_arr.inspect \ +        =~/"--(?:exc|no)-search-form"/ \ +        || act[:switch][:off].inspect =~/"search_form"|"search"/ +          { bool: false, set: :off } +        else { bool: true, set: :na } +        end +        act[:html_search_form]=if select_arr.inspect \ +        =~/"--inc-html-search-form"|"--inc-search-form"/ +          { bool: true, set: :on } +        elsif select_arr.inspect \ +        =~/"--(?:exc|no)-html-search-form"|"--(?:exc|no)-search-form"/ \ +        || act[:switch][:off].inspect \ +        =~/"html_search_form"|"search_form"|"search"/ +          { bool: false, set: :off } +        else { bool: true, set: :na } +        end +        act[:html_right_pane]=if select_arr.inspect \ +        =~/"--inc-html-right-pane"|"--inc-right-pane"|"--inc-html-right-column"|"--inc-right-column"/ +          { bool: true, set: :on } +        elsif select_arr.inspect \ +        =~/"--(?:exc|no)-html-right-pane"|"--(?:exc|no)-right-pane"|"--(?:exc|no)-html-right-column"|"--(?:exc|no)-right-column"/ \ +        || act[:switch][:off].inspect =~/"html_right_pane"|"html_right_column"|"promo"/ +          { bool: false, set: :off } +        else { bool: true, set: :na } +        end +        act[:html_top_band]=if select_arr.inspect \ +        =~/"--inc-html-top-band"|"--inc-top-band"/ +          { bool: true, set: :on } +        elsif select_arr.inspect \ +        =~/"--(?:exc|no)-html-top-band"|"--(?:exc|no)-top-band"/ \ +        || act[:switch][:off].inspect =~/"html-top-band"|"top-band"/ +          { bool: false, set: :off } +        else { bool: true, set: :na } +        end +        act[:html]=if select_arr.inspect \ +        =~/"--html-strict"/ \ +        or ((select_arr.inspect \ +        =~/"--html"/) \ +        && select_arr.inspect \ +        =~/"--strict"/) +          act[:html_strict]={ bool: true, set: :on } +          act[:html_scroll]={ bool: true, set: :on } +          act[:html_seg]={ bool: true, set: :on } +          { bool: true, set: :on } +        elsif (select_arr.inspect \ +        =~/"--html"/) +          act[:html_strict]={ bool: false, set: :off } +          act[:html_scroll]={ bool: true, set: :on } +          act[:html_seg]={ bool: true, set: :on } +          { bool: true, set: :on } +        else +          act[:html_strict]=(select_arr.inspect \ +          =~/"--strict"/) \ +          ? { bool: true, set: :on } +          : { bool: false, set: :na } +          act[:html_scroll]=(select_arr.inspect \ +          =~/"--html-scroll"/) \ +          ? { bool: true, set: :on } +          : { bool: false, set: :na } +          act[:html_seg]=(select_arr.inspect \ +          =~/"--html-seg"/) \ +          ? { bool: true, set: :on } +          : { bool: false, set: :na } +          { bool: false, set: :na } +        end +        act[:concordance]=(select_arr.inspect \ +        =~/"--concordance"/) \ +        ? { bool: true, set: :on } +        : { bool: false, set: :na } +        act[:images]=(select_arr.inspect \ +        =~/"--images"/) \ +        ? { bool: true, set: :on } +        : { bool: false, set: :na } +        act[:json]=(select_arr.inspect \ +        =~/"--json"/) \ +        ? { bool: true, set: :on } +        : { bool: false, set: :na } +        if select_arr.inspect \ +        =~/"--pdf"/ +          if select_arr.inspect \ +          =~/"--portrait"/ +            act[:pdf]=  { bool: false, set: :na } +            act[:pdf_l]={ bool: false, set: :na } +            act[:pdf_p]={ bool: true, set: :on } +          elsif select_arr.inspect \ +          =~/"--landscape"/ +            act[:pdf]=  { bool: false, set: :na } +            act[:pdf_l]={ bool: true, set: :on } +            act[:pdf_p]={ bool: false, set: :na } +          else +            act[:pdf]=  { bool: true, set: :on } +            act[:pdf_l]={ bool: true, set: :on } +            act[:pdf_p]={ bool: true, set: :on } +          end +        else +          act[:pdf]=       { bool: false, set: :na } +          act[:pdf_p]=     { bool: false, set: :na } +          act[:pdf_l]=     { bool: false, set: :na } +          act[:pdf_a4]=    { bool: false, set: :na } +          act[:pdf_a5]=    { bool: false, set: :na } +          act[:pdf_b5]=    { bool: false, set: :na } +          act[:pdf_letter]={ bool: false, set: :na } +          act[:pdf_legal]= { bool: false, set: :na } +        end +        if act[:pdf][:set]==:on \ +        or act[:pdf_p][:set]==:on \ +        or act[:pdf_l][:set]==:on +          act[:pdf_a4]=if select_arr.inspect \ +          =~/"--a4"|--papersize-a4"/ \ +          or select_arr.inspect \ +          =~/"--papersize=\S*a4\b\S*"/ #--papersize=a4,a5 +            { bool: true, set: :on } +          else +            { bool: false, set: :na } +          end +          act[:pdf_a5]=if select_arr.inspect \ +          =~/"--a5"|"--papersize-a5"/ \ +          or select_arr.inspect \ +          =~/"--papersize=\S*a5\b\S*"/ #--papersize=a4,a5 +            { bool: true, set: :on } +          else +            { bool: false, set: :na } +          end +          act[:pdf_b5]=if select_arr.inspect \ +          =~/"--b5"|"--papersize-b5"/ \ +          or select_arr.inspect \ +          =~/"--papersize=\S*b5\b\S*"/ +            { bool: true, set: :on } +          else +            { bool: false, set: :na } +          end +          act[:pdf_letter]=if select_arr.inspect \ +          =~/"--letter"|"--papersize-letter"/ \ +          or select_arr.inspect \ +          =~/"--papersize=\S*letter\b\S*"/ +            { bool: true, set: :on } +          else +            { bool: false, set: :na } +          end +          act[:pdf_legal]=if select_arr.inspect \ +          =~/"--legal"|"--papersize-legal"/ \ +          or select_arr.inspect \ +          =~/"--papersize=\S*legal\b\S*"/ +            { bool: true, set: :on } +          else +            { bool: false, set: :na } +          end +        end +        act[:epub]=(select_arr.inspect \ +        =~/"--epub"/) \ +        ? { bool: true, set: :on } +        : { bool: false, set: :na } +        act[:odt]=if select_arr.inspect \ +        =~/"--odt"|"--odf"|"--odt-(?:ocn|numbering)"|"--odf-(?:ocn|numbering)"/ +          act[:odt_ocn]=if (select_arr.inspect \ +          =~/"--odt-(?:ocn|numbering)"|"--odf-(?:ocn|numbering)"/ \ +          or select_arr.inspect \ +          =~/"--ocn"|"--inc-ocn"|"--numbering"|"--inc-numbering"/) +            { bool: true, set: :on } +          elsif select_arr.inspect \ +          =~/"--no-ocn"|"--exc-ocn"|"--no-numbering"|"--exc-numbering"/ +            { bool: false, set: :off } +          else +            { bool: false, set: :na } +          end +          { bool: true, set: :on } +        else +          { bool: false, set: :na } +        end +        act[:xml_sax]=(select_arr.inspect \ +        =~/"--xml-sax"|"--sax"/) \ +        ? { bool: true, set: :on } +        : { bool: false, set: :na } +        act[:xml_dom]=(select_arr.inspect \ +        =~/"--xml-dom"|"--dom"/) \ +        ? { bool: true, set: :on } +        : { bool: false, set: :na } +        act[:xml_docbook_book]=(select_arr.inspect \ +        =~/"--docbook"|"--docbook-book"|"--xml-docbook"|"--xml-docbook_book"/) \ +        ? { bool: true, set: :on } +        : { bool: false, set: :na } +        act[:xml_fictionbook]=(select_arr.inspect \ +        =~/"--fictionbook"|"--xml-fictionbook"/) \ +        ? { bool: true, set: :on } +        : { bool: false, set: :na } +        act[:xml_scaffold_structure_sisu]=select_arr.inspect \ +        =~/"--xml-scaffold"|"--xml-scaffold-sisu"/ \ +        ? { bool: true, set: :on } +        : { bool: false, set: :na } +        act[:xml_scaffold_structure_collapse]=select_arr.inspect \ +        =~/"--xml-scaffold-collapse"/ \ +        ? { bool: true, set: :on } +        : { bool: false, set: :na } +        act[:xhtml]=(select_arr.inspect \ +        =~/"--xhtml"/) \ +        ? { bool: true, set: :on } +        : { bool: false, set: :na } +        act[:txt]=if select_arr.inspect \ +        =~/"--txt"|"--text"|"--plaintext"|"--txt-(?:ocn|numbering)"|"--text-(?:ocn|numbering)"|"--plaintext-(?:ocn|numbering)"/ +          act[:txt_ocn]=if (select_arr.inspect \ +          =~/"--txt-(?:ocn|numbering)"|"--text-(?:ocn|numbering)"|"--plaintext-(?:ocn|numbering)"/ \ +          or select_arr.inspect \ +          =~/"--ocn"|"--inc-ocn"|"--numbering"|"--inc-numbering"/) +            { bool: true, set: :on } +          elsif select_arr.inspect \ +          =~/"--no-ocn"|"--exc-ocn"|"--no-numbering"|"--exc-numbering"/ +            { bool: false, set: :off } +          else +            { bool: false, set: :na } +          end +          { bool: true, set: :on } +        else +          { bool: false, set: :na } +        end +        act[:txt_textile]=(select_arr.inspect \ +        =~/"--textile"/) \ +        ? { bool: true, set: :on } +        : { bool: false, set: :na } +        act[:txt_asciidoc]=(select_arr.inspect \ +        =~/"--asciidoc"/) \ +        ? { bool: true, set: :on } +        : { bool: false, set: :na } +        act[:txt_markdown]=(select_arr.inspect \ +        =~/"--markdown"/) \ +        ? { bool: true, set: :on } +        : { bool: false, set: :na } +        act[:txt_rst]=(select_arr.inspect \ +        =~/"--rst"|"--rest"|"--restructuredtext"/) \ +        ? { bool: true, set: :on } +        : { bool: false, set: :na } +        act[:txt_orgmode]=(select_arr.inspect \ +        =~/"--org"|"--orgmode"/) \ +        ? { bool: true, set: :on } +        : { bool: false, set: :na } +        act[:manpage]=(select_arr.inspect \ +        =~/"--manpage"|"--man"/) \ +        ? { bool: true, set: :on } +        : { bool: false, set: :na } +        act[:texinfo]=(select_arr.inspect \ +        =~/"--texinfo"/) \ +        ? { bool: true, set: :on } +        : { bool: false, set: :na } +        act[:psql]=if select_arr.inspect \ +        =~/"--pg-\S+"/ \ +        or ((select_arr.inspect =~/"--pg"/) \ +        && (select_arr.inspect \ +        =~/"--createdb"|"--create(?:all)?"|"--dropall"|"--recreate(?:all)?"|"--import"|"--update"|"--remove"/)) +          act[:psql_createdb]=if select_arr.inspect \ +          =~/"--pg-createdb"|"--createdb"/ +            { bool: true, set: :on } +          else +            { bool: false, set: :na } +          end +          if select_arr.inspect \ +          =~/"--pg-recreate(?:all)?"|"--recreate(?:all)?"/ +            act[:psql_drop]={ bool: true, set: :on } +            act[:psql_create]={ bool: true, set: :on } +          else +            act[:psql_drop]=if select_arr.inspect \ +            =~/"--pg-dropall"|"--dropall"/ +              { bool: true, set: :on } +            else +              { bool: false, set: :na } +            end +            act[:psql_create]=if select_arr.inspect \ +            =~/"--pg-create(?:all)?"|"--create(?:all)?"/ +              { bool: true, set: :on } +            else +              { bool: false, set: :na } +            end +          end +          act[:psql_import]=if select_arr.inspect \ +          =~/"--pg-import"|"--import"/ +            { bool: true, set: :on } +          else +            { bool: false, set: :na } +          end +          act[:psql_update]=if select_arr.inspect \ +          =~/"--pg-update"|"--update"/ +            act[:psql_remove]={ bool: true, set: :on } +            { bool: true, set: :on } +          else +            act[:psql_remove]=if select_arr.inspect \ +            =~/"--pg-remove"|"--remove"/ +              { bool: true, set: :on } +            else +              { bool: false, set: :na } +            end +            { bool: false, set: :na } +          end +          { bool: true, set: :on } +        else +          act[:psql_createdb]= +            { bool: false, set: :na } +          act[:psql_drop]= +            { bool: false, set: :na } +          act[:psql_create]= +            { bool: false, set: :na } +          act[:psql_import]= +            { bool: false, set: :na } +          act[:psql_update]= +            { bool: false, set: :na } +          act[:psql_remove]= +            { bool: false, set: :na } +          { bool: false, set: :na } +        end +        act[:sqlite]=if select_arr.inspect \ +        =~/"--sqlite-\S+"/ \ +        or (select_arr.inspect \ +        =~/"--sqlite"/ \ +        && select_arr.inspect \ +        =~/"--createdb"|"--create(?:all)?"|"--dropall"|"--recreate(?:all)?"|"--import"|"--update"|"--remove"/) +          act[:sqlite_createdb]=if select_arr.inspect \ +          =~/"--sqlite-createdb"|"--createdb"/ +            { bool: true, set: :on } +          else +            { bool: false, set: :na } +          end +          if select_arr.inspect \ +          =~/"--sqlite-recreate(?:all)?"|"--recreate(?:all)?"/ +            act[:sqlite_drop]={ bool: true, set: :on } +            act[:sqlite_create]={ bool: true, set: :on } +          else +            act[:sqlite_create]=if select_arr.inspect \ +            =~/"--sqlite-create(?:all)?"|"--create(?:all)?"/ +              { bool: true, set: :on } +            else +              { bool: false, set: :na } +            end +            act[:sqlite_drop]=if select_arr.inspect \ +            =~/"--sqlite-dropall"|"--dropall"/ +              { bool: true, set: :on } +            else +              { bool: false, set: :na } +            end +          end +          act[:sqlite_import]=if select_arr.inspect \ +          =~/"--sqlite-import"|"--import"/ +            { bool: true, set: :on } +          else +            { bool: false, set: :na } +          end +          act[:sqlite_update]=if select_arr.inspect \ +          =~/"--sqlite-update"|"--update"/ +            act[:sqlite_remove]={ bool: true, set: :on } +            { bool: true, set: :on } +          else +            act[:sqlite_remove]=if select_arr.inspect \ +            =~/"--sqlite-remove"|"--sqlite-remove"/ +              { bool: true, set: :on } +            else +              { bool: false, set: :na } +            end +            { bool: false, set: :na } +          end +          { bool: true, set: :on } +        else +          act[:sqlite_createdb]= +            { bool: false, set: :na } +          act[:sqlite_drop]= +            { bool: false, set: :na } +          act[:sqlite_create]= +            { bool: false, set: :na } +          act[:sqlite_import]= +            { bool: false, set: :na } +          act[:sqlite_update]= +            { bool: false, set: :na } +          act[:sqlite_remove]= +            { bool: false, set: :na } +          { bool: false, set: :na } +        end +        act[:sqlite_discrete]=select_arr.inspect \ +        =~/"--sql"|"--sqlite"/ \ +        && (select_arr.inspect \ +        !~/"--createdb"|"--create(?:all)?"|"--dropall"|"--recreate(?:all)?"|"--import"|"--update"|"--remove"/) \ +        ? { bool: true, set: :on } +        : { bool: false, set: :na } +        act[:harvest]=(select_arr.inspect \ +        =~/"--harvest"/) \ +        ? { bool: true, set: :on } +        : { bool: false, set: :na } +        act[:po4a_sstm]=(select_arr.inspect \ +        =~/"--po4a-ss[tm]"/) \ +        ? { bool: true, set: :on } +        : { bool: false, set: :na } +        act[:po4a_sst_ao_sst]=(select_arr.inspect \ +        =~/"--po4a-ao(?:-ss[tm])?"/) \ +        ? { bool: true, set: :on } +        : { bool: false, set: :na } +        act[:po4a_shelf]=(select_arr.inspect \ +        =~/"--po4a-shelf"|"--pot?-shelf"/) \ +        ? { bool: true, set: :on } +        : { bool: false, set: :na } +        if act[:po4a_shelf][:set]==:on \ +        or act[:po4a_sst_ao_sst][:set]==:on \ +        or act[:po4a_sstm][:set]==:on +          act[:po4a_lang]=if select_arr.inspect \ +          =~/"--(?:trans|init)-([a-z]{2}):((?:(?:[a-z]{2}\b),?)+)/ +            lng_src,lng_trn=$1,$2.split(',') +            { bool: true, set: :on, src: lng_src, trn: lng_trn } +          elsif select_arr.inspect \ +          =~/"--trans"/ +            { bool: true, set: :on } +            { bool: true, set: :on, src: 'en', trn: [] } +          else +            { bool: false, set: :na } +          end +          act[:po4a_lang_trans]=if select_arr.inspect \ +          =~/"--trans-([a-z]{2}):((?:(?:[a-z]{2}\b),?)+)/ +            lng_src,lng_trn=$1,$2.split(',') +            { bool: true, set: :on, src: lng_src, trn: lng_trn } +          elsif select_arr.inspect \ +          =~/"--trans"/ +            { bool: true, set: :on } +            { bool: true, set: :on, src: 'en', trn: [] } +          else +            { bool: false, set: :na } +          end +          act[:po4a_lang_init]=if select_arr.inspect \ +          =~/"--init-([a-z]{2}):((?:(?:[a-z]{2}\b),?)+)/ +            lng_src,lng_trn=$1,$2.split(',') +            { bool: true, set: :on, src: lng_src, trn: lng_trn } +          else +            { bool: false, set: :na } +          end +        else +          act[:po4a_lang_trans]= \ +          { bool: false, set: :na } +          act[:po4a_lang_init]= \ +          { bool: false, set: :na } +        end +        act[:git]=(select_arr.inspect \ +        =~/"--git"/) \ +        ? { bool: true, set: :on } +        : { bool: false, set: :na } +        act[:hash_digests]=(select_arr.inspect \ +        =~/"--digests?"|"--hash-digests"/) \ +        ? { bool: true, set: :on } +        : { bool: false, set: :na } +        act[:pdf_font_size]=if select_arr.inspect \ +        =~/"--(?:pdf-)?font-?size[=-](\d{1,2})(?:pt)?"/ +          $1 +        else :na +        end +        act[:pdf_hyperlink_colors]=if select_arr.inspect \ +        =~/"--pdf-hyperlinks-(?:mono(?:chrome)?|no-color)"/ +          :mono +        elsif select_arr.inspect \ +        =~/"--pdf-hyperlinks-color"/ +          :color +        else :na +        end +        act[:hash_digest_algo]=if select_arr.inspect \ +        =~/"--hash-(?:sha)?512"/ +          :sha512 +        elsif select_arr.inspect \ +        =~/"--hash-(?:sha)?256"/ +          :sha256 +        elsif select_arr.inspect \ +        =~/"--hash-md5"/ +          :md5 +        else :na +        end +        act[:sample_search_form]=if select_arr.inspect \ +        =~/"--sample-search-form"/ +          if select_arr.inspect \ +          =~/"--db[-=]pg"/ +            { bool: true, set: :on, db: :pg } +          elsif select_arr.inspect \ +          =~/"--db[-=]sqlite"/ +            { bool: true, set: :on, db: :sqlite } +          else +            { bool: true, set: :on, db: :na } +          end +        else +          { bool: false, set: :na, db: :na } +        end +        act[:webrick]=select_arr.inspect \ +        =~/"--webrick"/ \ +        ? { bool: true, set: :on } +        : { bool: false, set: :na } +        act[:share_source]=select_arr.inspect \ +        =~/"--source"/ \ +        ? { bool: true, set: :on } +        : { bool: false, set: :na } +        act[:sisupod]=select_arr.inspect \ +        =~/"--sisupod"/ \ +        ? { bool: true, set: :on } +        : { bool: false, set: :na } +        act[:scp]=select_arr.inspect \ +        =~/"--scp"/ \ +        ? { bool: true, set: :on } +        : { bool: false, set: :na } +        act[:rsync]=select_arr.inspect \ +        =~/"--rsync"|"--remote"/ \ +        ? { bool: true, set: :on } +        : { bool: false, set: :na } +        act[:zap]=select_arr.inspect \ +        =~/"--zap"|"--delete"/ \ +        ? { bool: true, set: :on } +        : { bool: false, set: :na } +        act[:urls_all]=select_arr.inspect \ +        =~/"--urls-all"/ \ +        ? { bool: true, set: :on } +        : { bool: false, set: :na } +        act[:urls_selected]=if select_arr.inspect \ +        =~/"--urls"/ +          { bool: true, set: :on } +        elsif select_arr.inspect \ +        =~/"--harvest/ +          { bool: false, set: :off } +        elsif select_arr.inspect \ +        =~/"--verbose"|"--maintenance"/ +          { bool: true, set: :on } +        else +          { bool: false, set: :na } +        end +        act[:sitemap]=select_arr.inspect \ +        =~/"--sitemap"/ \ +        ? { bool: true, set: :on } +        : { bool: false, set: :na } +        act[:qrcode]=select_arr.inspect \ +        =~/"--qrcode"/ \ +        ? { bool: true, set: :on } +        : { bool: false, set: :na } +        act[:help]=select_arr.inspect \ +        =~/"--help/ \ +        ? { bool: true, set: :on } +        : { bool: false, set: :na } +        act[:ao]=if select_arr.inspect \ +        =~/"--ao"|"--dal"/ +          { bool: true, set: :on } +        elsif (act[:txt][:set]==:on \ +        || act[:txt_textile][:set]==:on \ +        || act[:txt_asciidoc][:set]==:on \ +        || act[:txt_markdown][:set]==:on \ +        || act[:txt_rst][:set]==:on \ +        || act[:txt_orgmode][:set]==:on \ +        || act[:xhtml][:set]==:on \ +        || act[:epub][:set]==:on \ +        || act[:html][:set]==:on \ +        || act[:html_seg][:set]==:on \ +        || act[:html_scroll][:set]==:on \ +        || act[:json][:set]==:on \ +        || act[:texinfo][:set]==:on \ +        || act[:manpage][:set]==:on \ +        || act[:hash_digests][:set]==:on \ +        || act[:odt][:set]==:on \ +        || act[:pdf][:set]==:on \ +        || act[:pdf_p][:set]==:on \ +        || act[:pdf_l][:set]==:on \ +        || act[:qrcode][:set]==:on \ +        || act[:sisupod][:set]==:on \ +        || act[:share_source][:set]==:on \ +        || act[:po4a_sstm][:set]==:on \ +        || act[:concordance][:set]==:on \ +        || act[:sqlite_discrete][:set]==:on \ +        || act[:sqlite_import][:set]==:on \ +        || act[:sqlite_update][:set]==:on \ +        || act[:sqlite_remove][:set]==:on \ +        || act[:psql_import][:set]==:on \ +        || act[:psql_update][:set]==:on \ +        || act[:psql_remove][:set]==:on \ +        || act[:xml_dom][:set]==:on \ +        || act[:xml_sax][:set]==:on \ +        || act[:xml_docbook_book][:set]==:on \ +        || act[:xml_fictionbook][:set]==:on \ +        || act[:xml_scaffold_structure_sisu][:set]==:on \ +        || act[:xml_scaffold_structure_collapse][:set]==:on ) +          { bool: true, set: :on } +        else +          { bool: false, set: :na } +        end +        act[:manifest]=if select_arr.inspect \ +        =~/"--inc-manifest"/ +          { bool: true, set: :on } +        elsif select_arr.inspect \ +        =~/"--(?:exc|no)-manifest"/ \ +        || act[:switch][:off].inspect =~/"manifest"/ +          { bool: false, set: :off } +        elsif select_arr.inspect \ +        =~/"--manifest"/ +          { bool: true, set: :on } +        elsif (act[:txt][:set]==:on \ +        || act[:txt_textile][:set]==:on \ +        || act[:txt_asciidoc][:set]==:on \ +        || act[:txt_markdown][:set]==:on \ +        || act[:txt_rst][:set]==:on \ +        || act[:txt_orgmode][:set]==:on \ +        || act[:xhtml][:set]==:on \ +        || act[:epub][:set]==:on \ +        || act[:html][:set]==:on \ +        || act[:html_seg][:set]==:on \ +        || act[:html_scroll][:set]==:on \ +        || act[:json][:set]==:on \ +        || act[:texinfo][:set]==:on \ +        || act[:manpage][:set]==:on \ +        || act[:hash_digests][:set]==:on \ +        || act[:odt][:set]==:on \ +        || act[:pdf][:set]==:on \ +        || act[:pdf_p][:set]==:on \ +        || act[:pdf_l][:set]==:on \ +        || act[:qrcode][:set]==:on \ +        || act[:sisupod][:set]==:on \ +        || act[:share_source][:set]==:on \ +        || act[:po4a_sstm][:set]==:on \ +        || act[:concordance][:set]==:on \ +        || act[:xml_dom][:set]==:on \ +        || act[:xml_sax][:set]==:on \ +        || act[:xml_docbook_book][:set]==:on \ +        || act[:xml_fictionbook][:set]==:on \ +        || act[:xml_scaffold_structure_sisu][:set]==:on \ +        || act[:xml_scaffold_structure_collapse][:set]==:on ) +          { bool: true, set: :on } +        else { bool: true, set: :na } +        end +        act[:console_messages] = '' +        act[:verbose]=if select_arr.inspect \ +        =~/"--verbose"/ +          act[:console_messages] << ' --verbose ' +          { bool: true, set: :on } +        else +          { bool: false, set: :na } +        end +        act[:verbose_plus]=if select_arr.inspect \ +        =~/"--very-verbose"|"--verbose-very"/ +          act[:console_messages] << ' --very-verbose ' +          { bool: true, set: :on } +        else +          { bool: false, set: :na } +        end +        act[:version_info]=if select_arr.inspect \ +        =~/"--version"|"--verbose"|"--maintenance"/ +          act[:console_messages] << ' --maintenance ' +          { bool: true, set: :on } +        else +          { bool: false, set: :na } +        end +        act[:quiet]=if (select_arr.inspect =~/"--quiet"/) +          act[:console_messages] << ' --quiet ' +          { bool: true, set: :on } +        else +          { bool: false, set: :na } +        end +        act[:color_state]=if select_arr.inspect =~/"--color-on"|"--color"/ +          act[:console_messages] << ' --color-on ' +          { bool: true, set: :on } +        elsif (select_arr.inspect =~/"--color-off"/) +          act[:console_messages] << ' --color-off ' +          { bool: false, set: :off } +        else { bool: true, set: :na } #fix default color +        end +#       act[:color_toggle]=if select_arr.inspect =~/"--color-toggle"/ +#         true +#       else false +#       end +        act[:maintenance]=if (select_arr.inspect =~/"--maintenance|--keep-processing-files"/) +          act[:console_messages] << ' --maintenance ' +          { bool: true, set: :on } +        else +          { bool: false, set: :na } +        end +        act[:profile]=if (select_arr.inspect =~/"--profile"/) +          act[:console_messages] << ' --color-off ' +          { bool: true, set: :on } +        else +          { bool: false, set: :na } +        end +        @act=act +      end +    end +    def opt_ch +      @opt_ch +    end +    def selections +      def arr +        @select_arr.sort +      end +      def str +        @select_str ||= arr.join(' ') +      end +      self +    end +    def act +      @@act +    end +    def files_mod +      files_mod=files +      @files_mod=files_mod +    end +    def files +      @files +    end +    def f_pth +      @f_pth +    end +    def pth +      @pth +    end +    def sub_location +      pth.gsub(/#{base_path}/,'') +    end +    def lng +      @lng +    end +    def lng_base +      @lng_base +    end +    def fno +      @fno=(fns.nil? || fns.empty?) \ +      ? '' \ +      : (fns[/(.+?(?:sst|ssm))(?:\.sst)?/,1]) +    end +    def fng +      @fng=(fno.nil? || fno.empty?) \ +      ? '' \ +      : (fno.gsub(/(?:~(?:#{Px[:lng_lst_rgx]}))?(\.ss[tm])$/,'\1')) +    end +    def fns +      @fns +    end +    def fnl +      @fns.gsub(/(\S+?)((?:\.ssm)?\.sst)/,"\\1.#{lng}\\2") +    end +    def what +      @what +    end +    def fnb +      (fns.nil? || fns.empty?) \ +      ? '' \ +      : (fns[/(.+?)\.(?:(?:-|ssm\.)?sst|ssm)$/,1]) +    end +    def fnc +      @fnc=(@fns =~/\.(?:ssm\.sst|ssm)$/) \ +      ? fnb + '.ssm.sst' +      : @fns +    end +    def fncb +      @fncb=(@fns =~/(?:\~\S{2,3})?\.(?:ssm\.sst|ssm)$/) \ +      ? fnb + '.ssm.sst' +      : @fns.gsub(/(?:\~\S{2,3})?(\.sst)$/,'\1') +    end +  end +end +__END__ +note usually named @opt is carried in dp document parameters (usually as @md.opt), @opt is a +subset of @md where @md is passed, contents of @opt are available as @md.opt +passing @opt as well is duplication check for fns & fnb +#+END_SRC + +** hub_actions.rb + +#+BEGIN_SRC ruby  :tangle "../lib/sisu/hub_actions.rb" +# <<sisu_document_header>> +module SiSU_Hub_Actions +  class HubActions +    require_relative 'utils_composite'                    # utils_composite.rb +    include SiSU_Composite_Doc_Utils                      # composite doc, .ssm, extract all related insert files, array of filenames test +    def initialize(opt) +      @opt=opt +    end +    def report +      def version_info? +        if @opt.act[:version_info][:set]==:on +          SiSU_Env::InfoAbout.new(@opt).sisu_version +        end +      end +      def version_number_git? +        if @opt.act[:version_info][:set]==:on \ +        || @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], +            ' ' + SiSU_is.git_version_info? +          ).grey +        end +      end +      def version_dir? +        if @opt.act[:version_info][:set]==:on \ +        || @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], +            ' ' + File.dirname(__FILE__) +          ).grey +        end +      end +      def version_info_extra? +        if @opt.act[:version_info][:set]==:on \ +        || @opt.act[:verbose][:set]==:on \ +        || @opt.act[:verbose_plus][:set]==:on \ +        || @opt.act[:maintenance][:set]==:on +          if SiSU_is.git_version_info? +            SiSU_Screen::Ansi.new( +              @opt.act[:color_state][:set], +              ' ' + File.dirname(__FILE__) + \ +              '  vcr: ' + SiSU_is.git_version_info? +            ).grey +          else +            SiSU_Screen::Ansi.new( +              @opt.act[:color_state][:set], +              ' ' + File.dirname(__FILE__) +            ).grey +          end +        end +      end +      self +    end +    def prepare +      def site? +        if @opt.act[:site_init][:set]==:on               #% --init-site, -C initialize/configure +          require_relative 'conf'                        #% --init-site, -C initialize/configure +          SiSU_Initialize::Source.new(@opt).read +          if @opt.act[:rsync][:set]==:on +            if @opt.selections.str =~/--init(?:ialize)?=site/ \ +            and @opt.selections.str =~/RZ/ +              SiSU_Hub_Actions::Operations.new(@opt).remote_put_base_site_rsync_match +            else SiSU_Hub_Actions::Operations.new(@opt).remote_put_base_site_rsync +            end +          elsif @opt.act[:scp][:set]==:on +            if @opt.selections.str =~/--init(?:ialize)?=site/ \ +            and @opt.selections.str =~/CCr/ +              SiSU_Hub_Actions::Operations.new(@opt).remote_put_base_site_all +            else SiSU_Hub_Actions::Operations.new(@opt).remote_put_base_site +            end +          end +        end +      end +      def remote_site? +        if @opt.act[:site_init][:set]==:on +          if @opt.act[:site_init][:set]==:on               #% --init-site, -C initialize/configure +            #require_relative 'conf'                        #% --init-site, -C initialize/configure +            #SiSU_Initialize::Source.new(@opt).read +            #if @opt.act[:rsync][:set]==:on +            #  if @opt.selections.str =~/--init(?:ialize)?=site/ \ +            #  and @opt.selection =~/RZ/ +            #    SiSU_Hub_Actions::Operations.new(@opt).remote_put_base_site_rsync_match +            #  else SiSU_Hub_Actions::Operations.new(@opt).remote_put_base_site_rsync +            #  end +            #elsif @opt.act[:scp][:set]==:on +            #  if @opt.selections.str =~/--init(?:ialize)?=site/ \ +            #  and @opt.selection =~/CCr/ +            #    SiSU_Hub_Actions::Operations.new(@opt).remote_put_base_site_all +            #  else SiSU_Hub_Actions::Operations.new(@opt).remote_put_base_site +            #  end +            #end +          end +        end +      end +      def sql? +        if @opt.act[:psql_createdb][:set]==:on \ +        or @opt.act[:psql_create][:set]==:on \ +        or @opt.act[:psql_drop][:set]==:on +          done=:ok +          if @opt.act[:psql][:set]==:on +            require_relative 'dbi' +            SiSU_DBI::SQL.new(@opt).connect +          end +        end +        if @opt.act[:sqlite_createdb][:set]==:on \ +        or @opt.act[:sqlite_create][:set]==:on \ +        or @opt.act[:sqlite_drop][:set]==:on +          done=:ok +          if @opt.act[:sqlite][:set]==:on +            require_relative 'dbi' +            SiSU_DBI::SQL.new(@opt).connect +          end +        end +      end +      def search_form? +        if @opt.act[:sample_search_form][:set]==:on      #% --sample-search-form, -F cgi sample search form +          SiSU_Hub_Actions::Operations.new(@opt).cgi +        end +      end +      def webrick? +        if @opt.act[:webrick][:set]==:on                 #% --webrick, -W webrick +          SiSU_Hub_Actions::Operations.new(@opt).webrick +        end +      end +      self +    end +    def outputs +      def each_file +        def abstract_objects? +          if @opt.act[:ao][:set]==:on                    #% --ao --dal, -m +            if @opt.f_pths.length > 0 +              unless @opt.act[:po4a_shelf][:set]==:on    # --po4a-shelf +                if @opt.fno =~ /\.ssm$/ +                  require_relative 'ao_composite'        # ao_composite.rb #pre-processing +                  SiSU_Assemble::Composite.new(@opt).read +                end +                require_relative 'ao'                    # ao.rb +                SiSU_AO::Source.new(@opt).read +              end +            else +              msg='document abstraction request requires sisu markup files' +              if (@opt.act[:verbose_plus][:set]==:on \ +              || @opt.act[:maintenance][:set]==:on) +                SiSU_Utils::CodeMarker.new(__LINE__,__FILE__,:yellow). +                  mark(msg) +              else puts msg +              end +            end +          end +        end +        def qrcode? +          if @opt.act[:qrcode][:set]==:on                #% --qrcode, -Q +            if @opt.f_pths.length > 0 +              require_relative 'qrcode'                  # qrcode.rb +              SiSU_QRcode::Source.new(@opt).read +            else +              msg='qrcode request requires sisu markup files' +              if (@opt.act[:verbose_plus][:set]==:on \ +              || @opt.act[:maintenance][:set]==:on) +                SiSU_Utils::CodeMarker.new(__LINE__,__FILE__,:yellow). +                  mark(msg) +              else puts msg +              end +            end +          end +        end +        def hash_digests? +          if @opt.act[:hash_digests][:set]==:on          #% --hash-digests, -N digest tree +            if @opt.f_pths.length > 0 +              require_relative 'digests'                 # digests.rb +              SiSU_DigestView::Source.new(@opt).read +            else +              msg='hash digest request requires sisu markup files' +              if (@opt.act[:verbose_plus][:set]==:on \ +              || @opt.act[:maintenance][:set]==:on) +                SiSU_Utils::CodeMarker.new(__LINE__,__FILE__,:yellow). +                  mark(msg) +              else puts msg +              end +            end +          end +        end +        def text? +          if @opt.act[:txt][:set]==:on                   #% --txt, -t -a +            if @opt.f_pths.length > 0 +              require_relative 'txt_plain'               #  txt_plain.rb +              SiSU_Txt_Plain::Source.new(@opt).read +            else +              msg='text request requires sisu markup files' +              if (@opt.act[:verbose_plus][:set]==:on \ +              || @opt.act[:maintenance][:set]==:on) +                SiSU_Utils::CodeMarker.new(__LINE__,__FILE__,:yellow). +                  mark(msg) +              else puts msg +              end +            end +          end +          if @opt.act[:txt_textile][:set]==:on           #% --textile +            if @opt.f_pths.length > 0 +              require_relative 'txt_textile'             #txt_textile.rb +              SiSU_Txt_Textile::Source.new(@opt).read +            else +              msg='textile request requires sisu markup files' +              if (@opt.act[:verbose_plus][:set]==:on \ +              || @opt.act[:maintenance][:set]==:on) +                SiSU_Utils::CodeMarker.new(__LINE__,__FILE__,:yellow). +                  mark(msg) +              else puts msg +              end +            end +          end +          if @opt.act[:txt_asciidoc][:set]==:on          #% --asciidoc +            if @opt.f_pths.length > 0 +              require_relative 'txt_asciidoc'            # txt_asciidoc.rb +              SiSU_Txt_AsciiDoc::Source.new(@opt).read +            else +              msg='asciidoc request requires sisu markup files' +              if (@opt.act[:verbose_plus][:set]==:on \ +              || @opt.act[:maintenance][:set]==:on) +                SiSU_Utils::CodeMarker.new(__LINE__,__FILE__,:yellow). +                  mark(msg) +              else puts msg +              end +            end +          end +          if @opt.act[:txt_markdown][:set]==:on          #% --markdown +            if @opt.f_pths.length > 0 +              require_relative 'txt_markdown'            # txt_markdown.rb +              SiSU_Txt_Markdown::Source.new(@opt).read +            else +              msg='markdown request requires sisu markup files' +              if (@opt.act[:verbose_plus][:set]==:on \ +              || @opt.act[:maintenance][:set]==:on) +                SiSU_Utils::CodeMarker.new(__LINE__,__FILE__,:yellow). +                  mark(msg) +              else puts msg +              end +            end +          end +          if @opt.act[:txt_rst][:set]==:on               #% --rst, --rest +            if @opt.f_pths.length > 0 +              require_relative 'txt_rst'                 # txt_rst.rb +              SiSU_Txt_rST::Source.new(@opt).read +            else +              msg='rst request requires sisu markup files' +              if (@opt.act[:verbose_plus][:set]==:on \ +              || @opt.act[:maintenance][:set]==:on) +                SiSU_Utils::CodeMarker.new(__LINE__,__FILE__,:yellow). +                  mark(msg) +              else puts msg +              end +            end +          end +          if @opt.act[:txt_orgmode][:set]==:on          #% --orgmode +            if @opt.f_pths.length > 0 +              require_relative 'txt_orgmode'            # txt_orgmode.rb +              SiSU_Txt_OrgMode::Source.new(@opt).read +            else +              msg='orgmode request requires sisu markup files' +              if (@opt.act[:verbose_plus][:set]==:on \ +              || @opt.act[:maintenance][:set]==:on) +                SiSU_Utils::CodeMarker.new(__LINE__,__FILE__,:yellow). +                  mark(msg) +              else puts msg +              end +            end +          end +        end +        def html? +          if @opt.act[:html][:set]==:on                  #% --html, -h +            if @opt.f_pths.length > 0 +              require_relative 'html'                    # html.rb +              SiSU_HTML::Source.new(@opt).read +            else +              msg='html request requires sisu markup files' +              if (@opt.act[:verbose_plus][:set]==:on \ +              || @opt.act[:maintenance][:set]==:on) +                SiSU_Utils::CodeMarker.new(__LINE__,__FILE__,:yellow). +                  mark(msg) +              else puts msg +              end +            end +          else +            if @opt.act[:html_seg][:set]==:on            #% --html-seg +              if @opt.f_pths.length > 0 +                require_relative 'html'                  # html.rb +                SiSU_HTML::Source.new(@opt).read +              else +                msg='html seg request requires sisu markup files' +                if (@opt.act[:verbose_plus][:set]==:on \ +                || @opt.act[:maintenance][:set]==:on) +                  SiSU_Utils::CodeMarker.new(__LINE__,__FILE__,:yellow). +                    mark(msg) +                else puts msg +                end +              end +            end +            if @opt.act[:html_scroll][:set]==:on         #% --html-scroll +              if @opt.f_pths.length > 0 +                require_relative 'html'                  # html.rb +                SiSU_HTML::Source.new(@opt).read +              else +                msg='html scroll request requires sisu markup files' +                if (@opt.act[:verbose_plus][:set]==:on \ +                || @opt.act[:maintenance][:set]==:on) +                  SiSU_Utils::CodeMarker.new(__LINE__,__FILE__,:yellow). +                    mark(msg) +                else puts msg +                end +              end +            end +          end +          if @opt.act[:concordance][:set]==:on           #% --concordance, -w +            if @opt.f_pths.length > 0 +              require_relative 'html_concordance'        # html_concordance.rb +              SiSU_Concordance::Source.new(@opt).read +            else +              msg='concordance request requires sisu markup files' +              if (@opt.act[:verbose_plus][:set]==:on \ +              || @opt.act[:maintenance][:set]==:on) +                SiSU_Utils::CodeMarker.new(__LINE__,__FILE__,:yellow). +                  mark(msg) +              else puts msg +              end +            end +          end +        end +        def json? +          if @opt.act[:json][:set]==:on                 #% --js, -J +            if @opt.f_pths.length > 0 +              require_relative 'json'                   # json.rb +              SiSU_JSON::Source.new(@opt).read +            else +              msg='json request requires sisu markup files' +              if (@opt.act[:verbose_plus][:set]==:on \ +              || @opt.act[:maintenance][:set]==:on) +                SiSU_Utils::CodeMarker.new(__LINE__,__FILE__,:yellow). +                  mark(msg) +              else puts msg +              end +            end +          end +        end +        def xhtml? +          if @opt.act[:xhtml][:set]==:on                 #% --xhtml, -b +            if @opt.f_pths.length > 0 +              require_relative 'xhtml'                   # xhtml.rb +              SiSU_XHTML::Source.new(@opt).read +            else +              msg='xhtml request requires sisu markup files' +              if (@opt.act[:verbose_plus][:set]==:on \ +              || @opt.act[:maintenance][:set]==:on) +                SiSU_Utils::CodeMarker.new(__LINE__,__FILE__,:yellow). +                  mark(msg) +              else puts msg +              end +            end +          end +          if @opt.act[:epub][:set]==:on                  #% --epub, -e +            if @opt.f_pths.length > 0 +              require_relative 'xhtml_epub2'             # xhtml_epub2.rb +              SiSU_XHTML_EPUB2::Source.new(@opt).read +            else +              msg='epub request requires sisu markup files' +              if (@opt.act[:verbose_plus][:set]==:on \ +              || @opt.act[:maintenance][:set]==:on) +                SiSU_Utils::CodeMarker.new(__LINE__,__FILE__,:yellow). +                  mark(msg) +              else puts msg +              end +            end +          end +        end +        def xml? +          if @opt.act[:odt][:set]==:on                   #% --odt, -o +            if @opt.f_pths.length > 0 +              require_relative 'xml_odf_odt'             # xml_odf_odt.rb +              SiSU_XML_ODF_ODT::Source.new(@opt).read +            else +              msg='odt request requires sisu markup files' +              if (@opt.act[:verbose_plus][:set]==:on \ +              || @opt.act[:maintenance][:set]==:on) +                SiSU_Utils::CodeMarker.new(__LINE__,__FILE__,:yellow). +                  mark(msg) +              else puts msg +              end +            end +          end +          if @opt.act[:xml_scaffold_structure_sisu][:set]==:on #% --xml-scaffold --xml-scaffold-sisu +            if @opt.f_pths.length > 0 +              require_relative 'xml_scaffold_structure_sisu'   #  xml_scaffold_structure_sisu.rb +              SiSU_XML_Scaffold_Structure_Sisu::Source.new(@opt).read +            else +              msg='xml scaffold request requires sisu markup files' +              if (@opt.act[:verbose_plus][:set]==:on \ +              || @opt.act[:maintenance][:set]==:on) +                SiSU_Utils::CodeMarker.new(__LINE__,__FILE__,:yellow). +                  mark(msg) +              else puts msg +              end +            end +          end +          if @opt.act[:xml_scaffold_structure_collapse][:set]==:on #% --xml-scaffold-collapse +            if @opt.f_pths.length > 0 +              require_relative 'xml_scaffold_structure_collapsed'  # xml_scaffold_structure_collapsed.rb +              SiSU_XML_Scaffold_Structure_Collapse::Source.new(@opt).read +            else +              msg='xml scaffold request requires sisu markup files' +              if (@opt.act[:verbose_plus][:set]==:on \ +              || @opt.act[:maintenance][:set]==:on) +                SiSU_Utils::CodeMarker.new(__LINE__,__FILE__,:yellow). +                  mark(msg) +              else puts msg +              end +            end +          end +          if @opt.act[:xml_docbook_book][:set]==:on      #% --xml-docbook +            if @opt.f_pths.length > 0 +              require_relative 'xml_docbook5'            # xml_docbook5.rb +              SiSU_XML_Docbook_Book::Source.new(@opt).read +            else +              msg='docbook request requires sisu markup files' +              if (@opt.act[:verbose_plus][:set]==:on \ +              || @opt.act[:maintenance][:set]==:on) +                SiSU_Utils::CodeMarker.new(__LINE__,__FILE__,:yellow). +                  mark(msg) +              else puts msg +              end +            end +          end +          if @opt.act[:xml_fictionbook][:set]==:on       #% --xml-fictionbook +            if @opt.f_pths.length > 0 +              require_relative 'xml_fictionbook2'        # xml_fictionbook2.rb +              SiSU_XML_Fictionbook::Source.new(@opt).read +            else +              msg='fictionbook request requires sisu markup files' +              if (@opt.act[:verbose_plus][:set]==:on \ +              || @opt.act[:maintenance][:set]==:on) +                SiSU_Utils::CodeMarker.new(__LINE__,__FILE__,:yellow). +                  mark(msg) +              else puts msg +              end +            end +          end +          if @opt.act[:xml_sax][:set]==:on               #% --xml-sax, -x +            if @opt.f_pths.length > 0 +              require_relative 'xml_sax'                 # xml_sax.rb +              SiSU_XML_SAX::Source.new(@opt).read +            else +              msg='xml sax request requires sisu markup files' +              if (@opt.act[:verbose_plus][:set]==:on \ +              || @opt.act[:maintenance][:set]==:on) +                SiSU_Utils::CodeMarker.new(__LINE__,__FILE__,:yellow). +                  mark(msg) +              else puts msg +              end +            end +          end +          if @opt.act[:xml_dom][:set]==:on               #% --xml-dom, -X +            if @opt.f_pths.length > 0 +              require_relative 'xml_dom'                 # xml_dom.rb +              SiSU_XML_DOM::Source.new(@opt).read +            else +              msg='xml dom request requires sisu markup files' +              if (@opt.act[:verbose_plus][:set]==:on \ +              || @opt.act[:maintenance][:set]==:on) +                SiSU_Utils::CodeMarker.new(__LINE__,__FILE__,:yellow). +                  mark(msg) +              else puts msg +              end +            end +          end +        end +        def pdf? +          if @opt.act[:pdf][:set]==:on \ +          or @opt.act[:pdf_p][:set]==:on \ +          or @opt.act[:pdf_l][:set]==:on                 #% --pdf-l --pdf, -p +            if @opt.f_pths.length > 0 +              require_relative 'texpdf'                  # texpdf.rb +              SiSU_TeX::Source.new(@opt).read +            else +              msg='pdf request requires sisu markup files' +              if (@opt.act[:verbose_plus][:set]==:on \ +              || @opt.act[:maintenance][:set]==:on) +                SiSU_Utils::CodeMarker.new(__LINE__,__FILE__,:yellow). +                  mark(msg) +              else puts msg +              end +            end +          end +        end +        def man_or_info? +          if @opt.act[:manpage][:set]==:on               #% --manpage, -i +            if @opt.f_pths.length > 0 +              require_relative 'manpage'                 # manpage.rb +              SiSU_Manpage::Source.new(@opt).read +            else +              msg='manpage request requires sisu markup files' +              if (@opt.act[:verbose_plus][:set]==:on \ +              || @opt.act[:maintenance][:set]==:on) +                SiSU_Utils::CodeMarker.new(__LINE__,__FILE__,:yellow). +                  mark(msg) +              else puts msg +              end +            end +          end +          if @opt.act[:texinfo][:set]==:on               #% --texinfo, -I +            if @opt.f_pths.length > 0 +              require_relative 'texinfo'                 # texinfo.rb +              SiSU_TexInfo::Source.new(@opt).read +            else +              msg='texinfo request requires sisu markup files' +              if (@opt.act[:verbose_plus][:set]==:on \ +              || @opt.act[:maintenance][:set]==:on) +                SiSU_Utils::CodeMarker.new(__LINE__,__FILE__,:yellow). +                  mark(msg) +              else puts msg +              end +            end +          end +        end +        def sqlite_discrete? +          if @opt.act[:sqlite_discrete][:set]==:on       #% --sqlite, -d +            if @opt.f_pths.length > 0 +              require_relative 'dbi_discrete'            # dbi_discrete.rb +              SiSU_DBI_Discrete::SQL.new(@opt).build +            else +              msg='sqlite (discrete) request requires sisu markup files' +              if (@opt.act[:verbose_plus][:set]==:on \ +              || @opt.act[:maintenance][:set]==:on) +                SiSU_Utils::CodeMarker.new(__LINE__,__FILE__,:yellow). +                  mark(msg) +              else puts msg +              end +            end +          end +        end +        def po4a_make? +          if @opt.act[:po4a_sst_ao_sst][:set]==:on               #% --po4a-ao +            if @opt.f_pths.length > 0 +              require_relative 'src_po4a_sst_ao_sst' +              SiSU_SStm_AO_SStm::Source.new(@opt).read_process_src_files # src_po4a_sst_ao_sst.rb +            else +              msg='sst request requires sisu markup files' +              if (@opt.act[:verbose_plus][:set]==:on \ +              || @opt.act[:maintenance][:set]==:on) +                SiSU_Utils::CodeMarker.new(__LINE__,__FILE__,:cyan). +                  mark(msg) +              else puts msg +              end +            end +          end +        end +        def elasticsearch? +          if @opt.act[:elasticsearch][:set]==:on         #% --elastic, -x +            if @opt.f_pths.length > 0 +              require_relative 'json_elastic'            # json_elastic.rb +              SiSU_Elastic::Source.new(@opt).read +            else +              msg='easticsearch request requires sisu markup files' +              if (@opt.act[:verbose_plus][:set]==:on \ +              || @opt.act[:maintenance][:set]==:on) +                SiSU_Utils::CodeMarker.new(__LINE__,__FILE__,:yellow). +                  mark(msg) +              else puts msg +              end +            end +          end +        end +        def manifest? +          if @opt.act[:manifest][:set]==:on              #% --manifest, -y +            if @opt.f_pths.length > 0 +              begin +                require_relative 'html_manifest'           # html_manifest.rb +                ((@opt.act[:sisupod][:set]==:on \ +                || @opt.act[:share_source][:set]==:on \ +                || @opt.act[:po4a_sstm][:set]==:on) \ +                && @opt.f_pths.length < 2 ) \ +                ? nil +                : SiSU_Manifest::Source.new(@opt).read +              rescue +              end +            else +              msg='manifest request requires sisu markup files' +              if (@opt.act[:verbose_plus][:set]==:on \ +              || @opt.act[:maintenance][:set]==:on) +                SiSU_Utils::CodeMarker.new(__LINE__,__FILE__,:yellow). +                  mark(msg) +              else puts msg +              end +            end +          end +        end +        def harvest? +          if @opt.act[:harvest][:set]==:on               #% --harvest +            if @opt.f_pths.length > 0 +              require_relative 'html_harvest'            # html_harvest.rb +              SiSU_Harvest::Source.new(@opt).read +            else +              msg='harvest request requires sisu markup files' +              if (@opt.act[:verbose_plus][:set]==:on \ +              || @opt.act[:maintenance][:set]==:on) +                SiSU_Utils::CodeMarker.new(__LINE__,__FILE__,:yellow). +                  mark(msg) +              else puts msg +              end +            end +          end +        end +        self +      end +      def loop_files +        def share_source? +          if @opt.act[:sisupod][:set]==:on \ +          or @opt.act[:share_source][:set]==:on \ +          or @opt.act[:po4a_sstm][:set]==:on \ +          or @opt.act[:git][:set]==:on +            begin +              if @opt.f_pths.length > 0 +                require_relative 'src_shared' +                SiSU_Hub_Loops::OptionLoopFiles.new(@opt). +                loop_files_on_given_option do +                  SiSU_Source::SiSUpodSource.new(@opt).read +                end +              else +                msg='share markup source request requires sisu markup files' +                if (@opt.act[:verbose_plus][:set]==:on \ +                || @opt.act[:maintenance][:set]==:on) +                  SiSU_Utils::CodeMarker.new(__LINE__,__FILE__,:cyan). +                    mark(msg) +                else puts msg +                end +              end +              if @opt.act[:sisupod][:set]==:on           #% --sisupod, -S +                if @opt.f_pths.length > 0 +                  require_relative 'src_sisupod_make'    # src_sisupod_make.rb +                  begin +                    SiSU_Hub_Loops::OptionLoopFiles.new(@opt). +                    loop_files_on_given_option_bundle do +                      SiSU_Doc::Source.new(@opt).sisupod_tar_xz +                    end +                  ensure +                  end +                else +                  msg='sisupod (share markup source) request requires sisu markup files' +                  if (@opt.act[:verbose_plus][:set]==:on \ +                  || @opt.act[:maintenance][:set]==:on) +                    SiSU_Utils::CodeMarker.new(__LINE__,__FILE__,:cyan). +                      mark(msg) +                  else puts msg +                  end +                end +              end +              if @opt.act[:git][:set]==:on               #% --git, -g +                if @opt.f_pths.length > 0 +                  require_relative 'git'                 # git.rb +                  begin +                    SiSU_Hub_Loops::OptionLoopFiles.new(@opt). +                    loop_files_on_given_option do +                      SiSU_Git::Source.new(@opt).read +                    end +                  ensure +                    SiSU_Hub_Loops::OptionLoopFiles.new(@opt). +                    loop_files_on_given_option_bundle do +                      SiSU_Git::Source.new(@opt).git_commit +                    end +                  end +                else +                  msg='git request requires sisu markup files' +                  if (@opt.act[:verbose_plus][:set]==:on \ +                  || @opt.act[:maintenance][:set]==:on) +                    SiSU_Utils::CodeMarker.new(__LINE__,__FILE__,:cyan). +                      mark(msg) +                  else puts msg +                  end +                end +              end +              if (@opt.act[:sisupod][:set]==:on \ +              || @opt.act[:share_source][:set]==:on \ +              || @opt.act[:po4a_sstm][:set]==:on) \ +              and @opt.act[:manifest][:set]==:on         #% --manifest, -y +                if @opt.f_pths.length > 0 +                  require_relative 'html_manifest'            # html_manifest.rb +                  begin +                  ensure +                    SiSU_Hub_Loops::OptionLoopFiles.new(@opt). +                    loop_files_on_given_option_bundle do +                      SiSU_Manifest::Source.new(@opt).read +                    end +                  end +                else +                  msg='manifest request requires sisu markup files' +                  if (@opt.act[:verbose_plus][:set]==:on \ +                  || @opt.act[:maintenance][:set]==:on) +                    SiSU_Utils::CodeMarker.new(__LINE__,__FILE__,:cyan). +                      mark(msg) +                  else puts msg +                  end +                end +              end +            ensure +              if @opt.f_pths.length > 0 +                env=SiSU_Env::InfoEnv.new(@opt.fns) +                path_pod=env.processing_path.processing_sisupod(@opt).paths +                unless @opt.act[:maintenance][:set]==:on +                  FileUtils::rm_rf("#{path_pod[:sisupod]}/*") \ +                    if FileTest.directory?(path_pod[:sisupod]) +                end +              else +                #SiSU_Utils::CodeMarker.new(__LINE__,__FILE__,:cyan). +                #  mark('*** request requires sisu markup files') +              end +            end +          end +          if @opt.act[:share_source][:set]==:on +            if @opt.f_pths.length > 0 +              require_relative 'src_sisupod_sstm'           # src_sisupod_sstm.rb +              begin +              ensure +                SiSU_Hub_Loops::OptionLoopFiles.new(@opt). +                loop_files_on_given_option_bundle do +                  SiSU_Markup::Source_Sisupod.new(@opt).read +                end +              end +            else +              msg='share markup source request requires sisu markup files' +              if (@opt.act[:verbose_plus][:set]==:on \ +              || @opt.act[:maintenance][:set]==:on) +                SiSU_Utils::CodeMarker.new(__LINE__,__FILE__,:cyan). +                  mark(msg) +              else puts msg +              end +            end +          end +          if @opt.act[:po4a_sstm][:set]==:on                    #% --po4a-sst +            if @opt.f_pths.length > 0 +              require_relative 'src_po4a_sstm' +              begin +                SiSU_Hub_Loops::OptionLoopFiles.new(@opt). +                loop_files_on_given_option do +                  SiSU_Markup::Source_Po4a.new(@opt).read       # src_po4a_sstm.rb +                end +              ensure +              end +            else +              msg='sst request requires sisu markup files' +              if (@opt.act[:verbose_plus][:set]==:on \ +              || @opt.act[:maintenance][:set]==:on) +                SiSU_Utils::CodeMarker.new(__LINE__,__FILE__,:cyan). +                  mark(msg) +              else puts msg +              end +            end +          end +          if @opt.act[:po4a_sst_ao_sst][:set]==:on               #% --po4a-ao +            if @opt.f_pths.length > 0 +              require_relative 'src_po4a_sst_ao_sst' +              begin +                SiSU_Hub_Loops::OptionLoopFiles.new(@opt). +                loop_files_on_given_option do +                  SiSU_SStm_AO_SStm::Source.new(@opt).read_setup # src_po4a_sst_ao_sst.rb +                end +              ensure +              end +            else +              msg='sst request requires sisu markup files' +              if (@opt.act[:verbose_plus][:set]==:on \ +              || @opt.act[:maintenance][:set]==:on) +                SiSU_Utils::CodeMarker.new(__LINE__,__FILE__,:cyan). +                  mark(msg) +              else puts msg +              end +            end +          end +          if @opt.act[:po4a_shelf][:set]==:on            #% --po4a-shelf +            if @opt.f_pths.length > 0 +              require_relative 'src_po4a_shelf' +              begin +                SiSU_Hub_Loops::OptionLoopFiles.new(@opt). +                loop_files_on_given_option do +                  SiSU_Po4a::Source.new(@opt).read       # src_po4a_shelf.rb +                end +              ensure +              end +            else +              msg='src_po4a_shelf request requires sisu markup files' +              if (@opt.act[:verbose_plus][:set]==:on \ +              || @opt.act[:maintenance][:set]==:on) +                SiSU_Utils::CodeMarker.new(__LINE__,__FILE__,:cyan). +                  mark(msg) +              else puts msg +              end +            end +          end +          if @opt.act[:images][:set]==:on                #% --images, -j +            if @opt.f_pths.length > 0 +              require_relative 'shared_images' +              SiSU_Hub_Loops::OptionLoopFiles.new(@opt). +              loop_files_on_given_option do +                SiSU_Images::Source.new(@opt).read       # shared_images.rb +              end +            else +              msg='place images request requires sisu markup files' +              if (@opt.act[:verbose_plus][:set]==:on \ +              || @opt.act[:maintenance][:set]==:on) +                SiSU_Utils::CodeMarker.new(__LINE__,__FILE__,:cyan). +                  mark(msg) +              else puts msg +              end +            end +          end +        end +        def run_termsheet? #broken, revisit later +          if @opt.selections.str =~/--termsheet/         #% -T termsheet/standard form #fix later +            if @opt.f_pths.length > 0 +              @opt.files.each do |fns| +                if FileTest.file?(fns) +                  @opt.fns=fns +                  case @opt.fns +                  when /\.(termsheet.rb)$/ +                    SiSU_Hub_Actions::Operations.new(@opt).termsheet +                  else                                   #print "not processed --> ", fns, "\n" +                  end +                else SiSU_Hub_Actions::Operations.new(@opt).not_found +                end +              end +            else +              msg='process termsheet request requires sisu markup files' +              if (@opt.act[:verbose_plus][:set]==:on \ +              || @opt.act[:maintenance][:set]==:on) +                SiSU_Utils::CodeMarker.new(__LINE__,__FILE__,:cyan). +                  mark(msg) +              else puts msg +              end +            end +          end +        end +        def sql? +          if @opt.act[:psql][:set]==:on                  #% --pg, -D +            if @opt.f_pths.length > 0 +              require_relative 'dbi' +              SiSU_Hub_Loops::OptionLoopFiles.new(@opt). +              loop_files_on_given_option do +                SiSU_DBI::SQL.new(@opt).connect          # dbi.rb +              end +            else +              msg='pgsql request requires sisu markup files' +              if (@opt.act[:verbose_plus][:set]==:on \ +              || @opt.act[:maintenance][:set]==:on) +                SiSU_Utils::CodeMarker.new(__LINE__,__FILE__,:cyan). +                  mark(msg) +              else puts msg +              end +            end +          end +          if @opt.act[:sqlite][:set]==:on                #% --sqlite, -d +            if @opt.f_pths.length > 0 +              require_relative 'dbi' +              SiSU_Hub_Loops::OptionLoopFiles.new(@opt). +              loop_files_on_given_option do +                SiSU_DBI::SQL.new(@opt).connect          # dbi.rb +              end +            else +              msg='sqlite request requires sisu markup files' +              if (@opt.act[:verbose_plus][:set]==:on \ +              || @opt.act[:maintenance][:set]==:on) +                SiSU_Utils::CodeMarker.new(__LINE__,__FILE__,:cyan). +                  mark(msg) +              else puts msg +              end +            end +          end +        end +        def manifest? +          if @opt.act[:manifest][:set]==:on              #% --manifest, -y +            if @opt.f_pths.length > 1 +              require_relative 'html_manifest' +              SiSU_Hub_Loops::OptionLoopFiles.new(@opt).manifest_on_files_translated do +                SiSU_Manifest::Source.new(@opt).read     # html_manifest.rb +              end +            end +          end +        end +        def sitemaps? +          if @opt.act[:sitemap][:set]==:on               #% --sitemap, -Y +            if @opt.f_pths.length > 0 +              require_relative 'sitemaps' +              SiSU_Hub_Loops::OptionLoopFiles.new(@opt). +              loop_files_on_given_option do +                SiSU_Sitemaps::Source.new(@opt).read     # sitemaps.rb +              end +            end +          end +        end +        def remote_placement? +          if @opt.act[:harvest][:set] !=:on +            if @opt.act[:scp][:set]==:on                 #% -r copy to remote server +              if @opt.f_pths.length > 0 +                require_relative 'remote'                # remote.rb +                SiSU_Hub_Loops::OptionLoopFiles.new(@opt). +                loop_files_on_given_option do +                  SiSU_Remote::Put.new(@opt).scp +                end +              end +            end +            if @opt.act[:rsync][:set]==:on               #% -R copy to remote server +              if @opt.f_pths.length > 0 +                require_relative 'remote'                # remote.rb +                SiSU_Hub_Loops::OptionLoopFiles.new(@opt). +                loop_files_on_given_option do +                  SiSU_Remote::Put.new(@opt).rsync +                end +              end +            end +          else +          end +        end +        def urls? +          if @opt.act[:urls_selected][:set]==:on         #% --urls +            if @opt.f_pths.length > 0 +              require_relative 'urls' +              SiSU_Hub_Loops::OptionLoopFiles.new(@opt). +              loop_files_on_given_option do +                SiSU_Urls::Source.new(@opt).read         #% urls.rb +              end +            else +              msg='urls request requires sisu markup files' +              if (@opt.act[:verbose_plus][:set]==:on \ +              || @opt.act[:maintenance][:set]==:on) +                SiSU_Utils::CodeMarker.new(__LINE__,__FILE__,:cyan). +                  mark(msg) +              else puts msg +              end +            end +          end +        end +        self +      end +      def init? +        SiSU_Env::InfoProcessingFlag.new +        if @opt.act[:ao][:set]==:on \ +        or @opt.act[:maintenance][:set]==:on             #% --maintenance, -M +          env=SiSU_Env::InfoEnv.new(@opt.fns) +          path={} +          path[:css]=env.path.output + '/_sisu/css' +          path[:xml]=env.path.output + '/_sisu/xml' +          path[:xsd]=path[:xml] + '/xsd' +          path[:xsd]=path[:xml] + '/rnc' +          path[:xsd]=path[:xml] + '/rng' +          re_p3=/(sisupod(?:\.txz)?|\S+?\.ss[mt]\.txz|[^\/]+?\.ssp)$/ +          unless @opt.files.join(',') =~ re_p3 #do not mix pods with source markup files in command line +            if @opt.act[:maintenance][:set] ==:on +              $VERBOSE=false                             #debug $VERBOSE=true +            end +          end +          re_p2=/(sisupod(?:\.zip)?|\S+?\.ss[mt]\.zip)$/ +          unless @opt.files.join(',') =~ re_p2 #do not mix pods with source markup files in command line +            if @opt.act[:maintenance][:set] ==:on +              $VERBOSE=false                             #debug $VERBOSE=true +            end +          end +        end +        if @opt.act[:ao][:set]==:on +          @retry_count= -1 +          begin +            @get_s,@get_p,@get_pl=[],[],[] +            re_s=/(\S+?\.-sst)$/ +            re_p3=/((?:https?|file):\/\/\S+?(?:\/\S+?\.ss[mt]\.txz|sisupod(?:\.txz)?|\.ssp))/ +            re_pl3=/^(\/\S+?\.ss[mt]\.txz)/ +            @opt.files.each do |fns| +              if fns =~re_s +                @get_s << @opt.f_pths[0][:url] +              end +              if fns =~re_p3 +                @get_p << re_p3.match(fns)[1] if re_p3 +              end +              if fns =~re_pl3 +                @get_pl << re_pl3.match(fns)[1] if re_p3 +              end +            end +            if @get_s.length > 0                         #% remote markup file .sst +              require_relative 'remote'                  # remote.rb +              SiSU_Remote::Get.new(@opt,@get_s).fns +              SiSU_Hub_Actions::Operations.new.counter +            end +            if @get_p.length > 0                         #% remote sisupod +              require_relative 'remote'                  # remote.rb +              SiSU_Remote::Get.new(@opt,@get_p).sisupod +            end +          rescue +            SiSU_Errors::Rescued.new($!,$@,@opt,@fns).location do +              __LINE__.to_s + ':' + __FILE__ +            end +            @retry_count +=1 +            retry unless @retry_count > 1 +          ensure +          end +        end +      end +      self +    end +  end +  class Operations +    @@n_do=0 +    def initialize(opt='') +      @opt=opt +      @cX=SiSU_Screen::Ansi.new(@opt).cX +    end +    def counter +      @@n_do=0 +    end +    def remote_put_base_site_rsync                       # -CR +      SiSU_Utils::CodeMarker.new(__LINE__,__FILE__).mark(:cyan) \ +        if @opt.act[:maintenance][:set] ==:on +      require_relative 'remote'                          # remote.rb +      SiSU_Remote::Put.new(@opt).rsync_base +    end +    def remote_put_base_site_rsync_match                 # -CCRZ +      SiSU_Utils::CodeMarker.new(__LINE__,__FILE__).mark(:cyan) \ +        if @opt.act[:maintenance][:set] ==:on +      require_relative 'remote'                          # remote.rb +      SiSU_Remote::Put.new(@opt).rsync_base_sync +    end +    def remote_put_base_site                             # -Cr +      SiSU_Utils::CodeMarker.new(__LINE__,__FILE__).mark(:cyan) \ +        if @opt.act[:maintenance][:set] ==:on +      require_relative 'remote'                          # remote.rb +      SiSU_Remote::Put.new(@opt).scp_base +    end +    def remote_put_base_site_all                         # -CCr +      SiSU_Utils::CodeMarker.new(__LINE__,__FILE__).mark(:cyan) \ +        if @opt.act[:maintenance][:set] ==:on +      require_relative 'remote'                          # remote.rb +      SiSU_Remote::Put.new(@opt).scp_base_all +    end +    def cgi                                              # -F +      require_relative 'cgi'                             # cgi.rb +      SiSU_CGI::SearchSQL.new(@opt).read +    end +    def termsheet                                        # -t +      system("sisu_termsheet #{@opt.selections.str} #{@opt.fns}\n") +      @@n_do=@@n_do+1 +      SiSU_Screen::Ansi.new( +        @opt.selections.str,@@n_do, +        'Termsheet(s) processed' +      ).term_sheet_title unless @opt.act[:quiet][:set] ==:on +    end +    def webrick                                          # -W +      prt=SiSU_Env::InfoEnv.new(@fns).port.webrick_port +      puts %{#{@cX.blue}[#{@cX.off}#{@cX.green}Start Webrick web server on port: #{prt}#{@cX.off}#{@cX.blue}] #{@cX.off*2} } +      require_relative 'webrick' +      SiSU_Webserv::WebrickStart.new +    end +    def not_found +      puts "\n#{@cX.fuchsia}FILE NOT FOUND:#{@cX.off} [ #{@opt.fns} ] - requested #{@opt.selections.str} processing skipped\n" +    end +    def convert_name_message(fns,type,i,o,rune) +      %{\nIn filename: "#{@cX.fuchsia}#{fns}#{@cX.off}" [ #{type} ] #{@cX.fuchsia}is apre 0.36 markup filename.#{@cX.off} #{@cX.brown}Please rename your file.#{@cX.off}\n\tAs of sisu-0.37, SiSU markup files with #{@cX.brown}the extensions #{i} should be re-named #{o}#{@cX.off}\n\tif you have the program called 'rename' installed, the following rune should do the trick:\n\t\t#{rune}\n\talternatively try:\n\t\tsisu --convert --36to37 #{fns}\n\trequested #{@opt.selections.str} processing skipped\n} +    end +    def not_recognised +      case @opt.fns +      when /(\.s[123])$/ +        type=@opt.fns.gsub(/\S+?(#{$1})/,'\1') +        rune=%q{rename 's/\.s[123]$/\.sst/' *.s{1,2,3}} +        puts convert_name_message(@opt.fns,type,'.s1 .s2 and .s3','.sst',rune) +      when /(\.r[123])$/ +        type=@opt.fns.gsub(/\S+?(#{$1})/,'\1') +        rune=%q{rename 's/\.r[123]$/\.ssm/' *.r{1,2,3}} +        puts convert_name_message(@opt.fns,type,'.r1 .r2 and .r3','.sst',rune) +        puts %{\n\tNote also that you will need to change the names of the files called/required\n\twithin the document text to build the composite document\n\t\t.s1 .s2 .s3 should be .sst \n\t\t.si should be .ssi\n\trequested #{@opt.selections.str} processing skipped\n} +      when /(\.ssi)$/ +        puts "\n#{@cX.fuchsia}component filetype:#{@cX.off} [ #{@opt.fns} ] - is not a processed filetype, (it may be used as a component of a .ssm markup file)\n\trequested #{@opt.selections.str} processing skipped\n" +      else +        puts "\n#{@cX.fuchsia}FILETYPE NOT RECOGNISED:#{@cX.off} [ #{@opt.fns} ] - is not a recognized filetype,\n\trequested #{@opt.selections.str} processing skipped\n" +      end +    end +  end +end +__END__ +#+END_SRC + +** hub_loop_markup_files.rb + +#+BEGIN_SRC ruby  :tangle "../lib/sisu/hub_loop_markup_files.rb" +# <<sisu_document_header>> +module SiSU_Hub_Loops +  require_relative 'constants'                         # constants.rb +  require_relative 'se'                                # se.rb +    include SiSU_Env +    include SiSU_Screen +  require_relative 'hub_actions'                       # hub_actions.rb +  require_relative 'hub_options'                       # hub_options.rb +  require_relative 'dp'                                # dp.rb +    include SiSU_Param +  require_relative 'utils'                             # utils.rb +  begin +    require 'uri' +  rescue LoadError +    SiSU_Utils::CodeMarker.new(__LINE__,__FILE__,:fuchsia). +      error('uri NOT FOUND (LoadError)') +  end +  class OptionLoopFiles +    attr_reader :opt +    def initialize(opt) +      @opt=opt +      @r=Px[:lng_lst_rgx] +    end +    def loop_files_on_given_option +      @opt.files.each_with_index do |fno,i| +        @opt.fno,@opt.fns=fno,fno +        @opt.f_pth=@opt.f_pths[i] +        if fno !~/\.-sst$/ +          @opt.pth=@opt.paths[i] +          @opt.lng=@opt.lngs[i] +        end +        @@pwd=@opt.pth +        @opt.pth=@opt.f_pths[i][:pth] +        @opt.lng=@opt.f_pths[i][:lng] +        Dir.chdir(@opt.f_pth[:pth]) #watch +        SiSU_Env::FilenameLanguageCodeInsert.new(@opt,@opt.lng).language_code_insert # ... track +        @env=SiSU_Env::InfoEnv.new(fno) +        yield +      end +    end +    def loop_files_on_given_option_bundle +      @files_bundle={} +      @opt.files.each_with_index do |fno,i| +        fn_base_bundle=fno.gsub(/(?:~(?:#{@r}))?\.ss[tm]$/,'') +        unless @files_bundle[fn_base_bundle] +          @files_bundle[fn_base_bundle]={ status: :todo } +        end +      end +      @opt.files.each_with_index do |fno,i| +        fn_base_bundle=fno.gsub(/(?:~(?:#{@r}))?\.ss[tm]$/,'') +        unless @files_bundle[fn_base_bundle][:status] == :done +          @files_bundle[fn_base_bundle][:status] = :done +          @opt.fns=fno +          @opt.fno=fno +          @opt.f_pth=@opt.f_pths[i] +          if fno !~/\.-sst$/ +            @opt.pth=@opt.paths[i] +            @opt.lng=@opt.lngs[i] +          end +          @@pwd=@opt.pth +          @opt.pth=@opt.f_pths[i][:pth] +          @opt.lng=@opt.f_pths[i][:lng] +          Dir.chdir(@opt.f_pth[:pth]) #watch +          @env=SiSU_Env::InfoEnv.new(fno) +          yield +        else next +        end +      end +    end +    def manifest_on_files_translated +      number_of_files={} +      @opt.files.each_with_index do |fns,i| +        fn=fns.gsub(/(?:~(?:#{@r}))?\.ss[tm]$/,'') +        (number_of_files[fn].is_a?(Array)) \ +        ? (number_of_files[fn] << i) +        : (number_of_files.store(fn,[i])) +      end +      files_translated_idx=[] +      number_of_files.each do |x| +        if x[1].length > 1 +          files_translated_idx << x[1] +        end +      end +      #files_translated_idx=number_of_files.select do |x| +      #  x[1] if x[1].length > 1 +      #end +      if files_translated_idx.flatten.length > 1 +        SiSU_Screen::Ansi.new( +          @opt.act[:color_state][:set], +          'Manifest re-run on (currently generated) translated files', +          '' +        ).grey_title_hi unless @opt.act[:quiet][:set] ==:on +        files_translated_idx.flatten.each do |i| +          @opt.fns=@opt.files[i] +          @opt.f_pth=@opt.f_pths[i] +          if @opt.fns =~/\.-sst$/ +            @opt.pth=Dir.pwd +            @opt.lng='en' +          elsif @opt.fno =~/\.txz$/ +            @opt.pth=@opt.f_pths[i][:pth] +            @opt.lng=@opt.f_pths[i][:lng] +          else +            @opt.pth=@opt.f_pths[i][:pth] +            @opt.lng=@opt.f_pths[i][:lng] +          end +          @@pwd=@opt.pth +          Dir.chdir(@opt.pth) #watch +          @env=SiSU_Env::InfoEnv.new(@opt.fns) +          yield +        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 +    hub + +  - 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 diff --git a/org/i18n.org b/org/i18n.org new file mode 100644 index 00000000..0aea09d6 --- /dev/null +++ b/org/i18n.org @@ -0,0 +1,2453 @@ +-*- mode: org -*- +#+TITLE:       sisu i18n +#+DESCRIPTION: documents - structuring, various output representations & search +#+FILETAGS:    :sisu:i18n: +#+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 + +* i18n +** i18n.rb + +#+BEGIN_SRC ruby  :tangle "../lib/sisu/i18n.rb" +# <<sisu_document_header>> +module SiSU_i18n +  @@language_table,@@language_list=nil,nil +  class Languages +    def language +      def table +        @@language_table ||= { +          am:    { c: 'am',    n: 'Amharic',           t: 'Amharic',                     xlp: 'amharic'          }, +          bg:    { c: 'bg',    n: 'Bulgarian',         t: 'Български (Bəlgarski)',       xlp: 'bulgarian'        }, +          bn:    { c: 'bn',    n: 'Bengali',           t: 'Bengali',                     xlp: 'bengali'          }, +          br:    { c: 'br',    n: 'Breton',            t: 'Breton',                      xlp: 'breton'           }, +          ca:    { c: 'ca',    n: 'Catalan',           t: 'catalan',                     xlp: 'catalan'          }, +          cs:    { c: 'cs',    n: 'Czech',             t: 'česky',                       xlp: 'czech'            }, +          cy:    { c: 'cy',    n: 'Welsh',             t: 'Welsh',                       xlp: 'welsh'            }, +          da:    { c: 'da',    n: 'Danish',            t: 'dansk',                       xlp: 'danish'           }, +          de:    { c: 'de',    n: 'German',            t: 'Deutsch',                     xlp: 'german'           }, +          el:    { c: 'el',    n: 'Greek',             t: 'Ελληνικά (Ellinika)',         xlp: 'greek'            }, +          en:    { c: 'en',    n: 'English',           t: 'English',                     xlp: 'english'          }, +          eo:    { c: 'eo',    n: 'Esperanto',         t: 'Esperanto',                   xlp: 'esperanto'        }, +          es:    { c: 'es',    n: 'Spanish',           t: 'español',                     xlp: 'spanish'          }, +          et:    { c: 'et',    n: 'Estonian',          t: 'Estonian',                    xlp: 'estonian'         }, +          eu:    { c: 'eu',    n: 'Basque',            t: 'basque',                      xlp: 'basque'           }, +          fi:    { c: 'fi',    n: 'Finnish',           t: 'suomi',                       xlp: 'finnish'          }, +          fr:    { c: 'fr',    n: 'French',            t: 'français',                    xlp: 'french'           }, +          ga:    { c: 'ga',    n: 'Irish',             t: 'Irish',                       xlp: 'irish'            }, +          gl:    { c: 'gl',    n: 'Galician',          t: 'Galician',                    xlp: 'galician'         }, +          he:    { c: 'he',    n: 'Hebrew',            t: 'Hebrew',                      xlp: 'hebrew'           }, +          hi:    { c: 'hi',    n: 'Hindi',             t: 'Hindi',                       xlp: 'hindi'            }, +          hr:    { c: 'hr',    n: 'Croatian',          t: 'Croatian',                    xlp: 'croatian'         }, +          hy:    { c: 'hy',    n: 'Armenian',          t: 'Armenian',                    xlp: 'armenian'         }, +          ia:    { c: 'ia',    n: 'Interlingua',       t: 'Interlingua',                 xlp: 'interlingua'      }, +          is:    { c: 'is',    n: 'Icelandic',         t: 'Icelandic',                   xlp: 'icelandic'        }, +          it:    { c: 'it',    n: 'Italian',           t: 'Italiano',                    xlp: 'italian'          }, +          ja:    { c: 'ja',    n: 'Japanese',          t: '日本語 (Nihongo)',            xlp: 'japanese'         }, +          ko:    { c: 'ko',    n: 'Korean',            t: 'Korean',                      xlp: 'korean'           }, +          la:    { c: 'la',    n: 'Latin',             t: 'Latin',                       xlp: 'latin'            }, +          lo:    { c: 'lo',    n: 'Lao',               t: 'Lao',                         xlp: 'lao'              }, +          lt:    { c: 'lt',    n: 'Lithuanian',        t: 'Lithuanian',                  xlp: 'lithuanian'       }, +          lv:    { c: 'lv',    n: 'Latvian',           t: 'Latvian',                     xlp: 'latvian'          }, +          ml:    { c: 'ml',    n: 'Malayalam',         t: 'Malayalam',                   xlp: 'malayalam'        }, +          mr:    { c: 'mr',    n: 'Marathi',           t: 'Marathi',                     xlp: 'marathi'          }, +          nl:    { c: 'nl',    n: 'Dutch',             t: 'Nederlands',                  xlp: 'dutch'            }, +          no:    { c: 'no',    n: 'Norwegian',         t: 'norsk',                       xlp: 'norsk'            }, +          nn:    { c: 'nn',    n: 'Norwegian Nynorsk', t: 'nynorsk',                     xlp: 'nynorsk'          }, +          oc:    { c: 'oc',    n: 'Occitan',           t: 'Occitan',                     xlp: 'occitan'          }, +          pl:    { c: 'pl',    n: 'Polish',            t: 'polski',                      xlp: 'polish'           }, +          pt:    { c: 'pt',    n: 'Portuguese',        t: 'Português',                   xlp: 'portuges'         }, +          pt_BR: { c: 'pt_BR', n: 'Portuguese Brazil', t: 'Brazilian Português',         xlp: 'brazilian'        }, +          ro:    { c: 'ro',    n: 'Romanian',          t: 'română',                      xlp: 'romanian'         }, +          ru:    { c: 'ru',    n: 'Russian',           t: 'Русский (Russkij)',           xlp: 'russian'          }, +          sa:    { c: 'sa',    n: 'Sanskrit',          t: 'Sanskrit',                    xlp: 'sanskrit'         }, +          se:    { c: 'se',    n: 'Sami',              t: 'Samin',                       xlp: 'samin'            }, +          sk:    { c: 'sk',    n: 'Slovak',            t: 'slovensky',                   xlp: 'slovak'           }, +          sl:    { c: 'sl',    n: 'Slovenian',         t: 'Slovenian',                   xlp: 'slovenian'        }, +          sq:    { c: 'sq',    n: 'Albanian',          t: 'Albanian',                    xlp: 'albanian'         }, +          sr:    { c: 'sr',    n: 'Serbian',           t: 'Serbian',                     xlp: 'serbian'          }, +          sv:    { c: 'sv',    n: 'Swedish',           t: 'svenska',                     xlp: 'swedish'          }, +          ta:    { c: 'ta',    n: 'Tamil',             t: 'Tamil',                       xlp: 'tamil'            }, +          te:    { c: 'te',    n: 'Telugu',            t: 'Telugu',                      xlp: 'telugu'           }, +          th:    { c: 'th',    n: 'Thai',              t: 'Thai',                        xlp: 'thai'             }, +          tk:    { c: 'tk',    n: 'Turkmen',           t: 'Turkmen',                     xlp: 'turkmen'          }, +          tr:    { c: 'tr',    n: 'Turkish',           t: 'Türkçe',                      xlp: 'turkish'          }, +          uk:    { c: 'uk',    n: 'Ukranian',          t: 'українська (ukrajins\'ka)',   xlp: 'ukrainian'        }, +          ur:    { c: 'ur',    n: 'Urdu',              t: 'Urdu',                        xlp: 'urdu'             }, +          us:    { c: 'en',    n: 'English (American)',t: 'English',                     xlp: 'english'          }, +          vi:    { c: 'vi',    n: 'Vietnamese',        t: 'Vietnamese',                  xlp: 'vietnamese'       }, +          zh:    { c: 'zh',    n: 'Chinese',           t: '中文',                        xlp: 'chinese'          }, +          en:    { c: 'en',    n: 'English',           t: 'English',                     xlp: 'english'          }, +          xx:    { c: 'xx',    n: 'Default',           t: 'English',                     xlp: 'english'          }, +        } +      end +      def list +        @@language_list ||= { +          'am'    => table[:am], +          'bg'    => table[:bg], +          'bn'    => table[:bn], +          'br'    => table[:br], +          'ca'    => table[:ca], +          'cs'    => table[:cs], +          'cy'    => table[:cy], +          'da'    => table[:da], +          'de'    => table[:de], +          'el'    => table[:el], +          'en'    => table[:en], +          'eo'    => table[:eo], +          'es'    => table[:es], +          'et'    => table[:et], +          'eu'    => table[:eu], +          'fi'    => table[:fi], +          'fr'    => table[:fr], +          'ga'    => table[:ga], +          'gl'    => table[:gl], +          'he'    => table[:he], +          'hi'    => table[:hi], +          'hr'    => table[:hr], +          'hy'    => table[:hy], +          'ia'    => table[:ia], +          'is'    => table[:is], +          'it'    => table[:it], +          'ja'    => table[:ja], +          'ko'    => table[:ko], +          'la'    => table[:la], +          'lo'    => table[:lo], +          'lt'    => table[:lt], +          'lv'    => table[:lv], +          'ml'    => table[:ml], +          'mr'    => table[:mr], +          'nl'    => table[:nl], +          'no'    => table[:no], +          'nn'    => table[:nn], +          'oc'    => table[:oc], +          'pl'    => table[:pl], +          'pt'    => table[:pt], +          'pt_BR' => table[:pt_BR], +          'ro'    => table[:ro], +          'ru'    => table[:ru], +          'sa'    => table[:sa], +          'se'    => table[:se], +          'sk'    => table[:sk], +          'sl'    => table[:sl], +          'sq'    => table[:sq], +          'sr'    => table[:sr], +          'sv'    => table[:sv], +          'ta'    => table[:ta], +          'te'    => table[:te], +          'th'    => table[:th], +          'tk'    => table[:tk], +          'tr'    => table[:tr], +          'uk'    => table[:uk], +          'ur'    => table[:ur], +          'us'    => table[:en], +          'vi'    => table[:vi], +          'zh'    => table[:zh], +          'en'    => table[:en], +          'xx'    => table[:en] +        } +      end +      self +    end +  end +  class Alphabet +    def initialize(lng_code) +      @lng_code=lng_code +    end +    def hash_arrays +      @alph=case @lng_code +      when /en/                                                              #english +        { +          u: %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], +          l: %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] +        } +      when /da|no|nn/                                                        #danish, norwegian +        { +          u: %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 Å Æ Ø], +          l: %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 å æ ø] +          #u: %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 Æ Ø Å], +          #l: %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 æ ø å] +        } +      when /sv/                                                              #swedish +        { +          u: %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 Å Ä Ö], +          l: %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 å ä ö] +        } +      else                                                                   #english default +        { +          u: %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], +          l: %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] +        } +      end +    end +    def hash_strings +      { u: hash_arrays[:u].join, l: hash_arrays[:l].join } +    end +  end +end +__END__ +Language Lists +,* po4a c: +  <http://www.debian.org/international/l10n/po/> +  Px[:lng_lst] see constants.rb +,* polyglossia xlp: +  <http://mirrors.ctan.org/macros/xetex/latex/polyglossia/polyglossia.pdf> +  missing from (:c) list: +    arabic asturian bahasai bahasam coptic divehi farsi lsorbian magyar scottish syriac usorbian +note ISO_639-1 +  <http://en.wikipedia.org/wiki/ISO_639-1> +  <http://en.wikipedia.org/wiki/List_of_ISO_639-1_codes> +also note ISO_639-2 +  <http://en.wikipedia.org/wiki/ISO_639-2> +  <http://en.wikipedia.org/wiki/List_of_ISO_639-2_codes> + +Px[:lng_lst] # constants.rb + +module SiSU_TextTranslation +  class Language +    def initialize(md) +      @md=md +    end +    def tex_name(char) +      @lang=if char +        case char +        when 'sq'    then 'albanian' +        when 'am'    then 'amharic' +       #when 'ar'    then 'arabic'         # see polyglossia +        when 'hy'    then 'armenian' +       #when ''      then 'asturian'       # polyglossia +       #when ''      then 'bahasai'        # polyglossia +       #when ''      then 'bahasam'        # polyglossia +        when 'eu'    then 'basque' +        when 'bn'    then 'bengali' +        when 'pt_BR' then 'brazilian' +        when 'br'    then 'breton' +        when 'bg'    then 'bulgarian' +        when 'ca'    then 'catalan'        # see polyglossia +       #when ''      then 'coptic'         # polyglossia +        when 'hr'    then 'croatian' +        when 'cs'    then 'czech' +        when 'da'    then 'danish' +       #when ''      then 'divehi'         # polyglossia +        when 'nl'    then 'dutch'          # see polyglossia +        when 'en'    then 'english'        # see polyglossia +        when 'eo'    then 'esperanto'      # see polyglossia +        when 'et'    then 'estonian' +        when 'gl'    then 'galician' +        when 'de'    then 'german' +        when 'el'    then 'greek'          #gl ? +        when 'he'    then 'hebrew' +        when 'hi'    then 'hindi' +        when 'is'    then 'icelandic' +        when 'ia'    then 'interlingua' +        when 'ga'    then 'irish' +        when 'it'    then 'italian' +       #when ''      then 'farsi'          # polyglossia +        when 'fi'    then 'finnish' +        when 'fr'    then 'french' +        when 'lo'    then 'lao' +        when 'la'    then 'latin' +        when 'lv'    then 'latvian' +        when 'lt'    then 'lithuanian' +       #when ''      then 'lsorbian'       # polyglossia +       #when ''      then 'magyar'         # polyglossia +        when 'ml'    then 'malayalam' +        when 'mr'    then 'marathi' +       #when 'hu'    then 'magyar' +        when 'no'    then 'norske' +        when 'nn'    then 'nynorsk' +        when 'oc'    then 'occitan' +        when 'pl'    then 'polish' +        when 'pt'    then 'portuges' +        when 'ro'    then 'romanian' +        when 'ru'    then 'russian' +        when 'se'    then 'samin'          #(check sami?) +        when 'sa'    then 'sanskrit' +        when 'sr'    then 'serbian' +       #when ''      then 'scottish'       # polyglossia  (gd (Gaelic (Scots))) +        when 'sk'    then 'slovak' +        when 'sl'    then 'slovenian' +        when 'es'    then 'spanish' +        when 'sv'    then 'swedish' +        when 'ta'    then 'tamil' +        when 'te'    then 'telugu' +        when 'th'    then 'thai' +        when 'tr'    then 'turkish' +        when 'tk'    then 'turkmen' +        when 'uk'    then 'ukrainian' +        when 'ur'    then 'urdu' +       #when ''      then 'usorbian'       # polyglossia +        when 'vi'    then 'vietnamese' +        when 'cy'    then 'welsh' +        when 'us'    then 'USenglish'      # depreciated, see iso-639-2 +        else         then 'english' +        end +      else            'english' +      end +    end +  end +end +__END__ +#+END_SRC + +* prog_text_translation.rb + +#+BEGIN_SRC ruby  :tangle "../lib/sisu/prog_text_translation.rb" +# <<sisu_document_header>> +module SiSU_Translate +  require_relative 'se'                                 # se.rb +    include SiSU_Env; include SiSU_Param +  class Source +    def initialize(md,doc_lang,trans_str='') +      @md,@doc_lang,@trans_str=md,doc_lang,trans_str +      @lang_class=case @doc_lang +      when /American/i       then English.new(md,doc_lang,trans_str)    # tag depreciated, see iso 639-2 +      when /English/i        then English.new(md,doc_lang,trans_str) +      when /French/i         then French.new(md,doc_lang,trans_str) +      when /German/i         then German.new(md,doc_lang,trans_str) +      when /Italian/i        then Italian.new(md,doc_lang,trans_str) +      when /Spanish/i        then Spanish.new(md,doc_lang,trans_str) +      when /Portuguese Brazil|Brazilian(?: Portuguese)?/i +                                  Portuguese.new(md,doc_lang,trans_str) # tag depreciated, see iso 639-2 +      when /Portuguese/i     then Portuguese.new(md,doc_lang,trans_str) +      when /Swedish/i        then Swedish.new(md,doc_lang,trans_str) +      when /Danish/i         then Danish.new(md,doc_lang,trans_str) +      when /Finnish/i        then Finnish.new(md,doc_lang,trans_str) +      when /Norwegian/i      then Norwegian.new(md,doc_lang,trans_str) +      when /Icelandic/i      then Icelandic.new(md,doc_lang,trans_str) +      when /Dutch/i          then Dutch.new(md,doc_lang,trans_str) +      when /Estonian/i       then Estonian.new(md,doc_lang,trans_str) +      when /Hungarian/i      then Hungarian.new(md,doc_lang,trans_str) +      when /Polish/i         then Polish.new(md,doc_lang,trans_str) +      when /Romanian/i       then Romanian.new(md,doc_lang,trans_str) +      when /Russian/i        then Russian.new(md,doc_lang,trans_str) +      when /Greek/i          then Greek.new(md,doc_lang,trans_str) +      when /Ukranian/i       then Ukranian.new(md,doc_lang,trans_str) +      when /Turkish/i        then Turkish.new(md,doc_lang,trans_str) +      when /Slovenian/i      then Slovenian.new(md,doc_lang,trans_str) +      when /Croatian/i       then Croatian.new(md,doc_lang,trans_str) +      when /Slovak(?:ian)?/i then Slovak.new(md,doc_lang,trans_str) +      when /Czech/i          then Czech.new(md,doc_lang,trans_str) +      when /Bulgarian/i      then Bulgarian.new(md,doc_lang,trans_str) +      else                        English.new(md,doc_lang,trans_str) +      end +    end +    def filename +      @lang_class.filename +    end +    def metadata +      @lang_class.metadata +    end +    def filetype_description +      @lang_class.filetype_description +    end +    def file_size +      @lang_class.file_size +    end +    def sourcefile +      @lang_class.sourcefile +    end +    def sourcefile_digest +      @lang_class.sourcefile_digest +    end +    def full_title #dc +      @lang_class.full_title +    end +    def title +      @lang_class.title +    end +    def subtitle +      @lang_class.subtitle +    end +    def author +      @lang_class.author +    end +    def contributor +      @lang_class.contributor +    end +    def translator +      @lang_class.translator +    end +    def illustrator +      @lang_class.illustrator +    end +    def publisher +      @lang_class.publisher +    end +    def prepared_by +      @lang_class.prepared_by +    end +    def digitized_by +      @lang_class.digitized_by +    end +    def contents +      @lang_class.contents +    end +    def subject +      @lang_class.subject +    end +    def description #dc (watch) +      @lang_class.description +    end +    def abstract +      @lang_class.abstract +    end +    def type +      @lang_class.type +    end +    def rights +      @lang_class.rights +    end +    def date +      @lang_class.date +    end +    def date_created +      @lang_class.date_created +    end +    def date_available +      @lang_class.date_available +    end +    def date_valid +      @lang_class.date_valid +    end +    def date_modified +      @lang_class.date_modified +    end +    def date_issued +      @lang_class.date_issued +    end +    def language +      @lang_class.language +    end +    def language_original +      @lang_class.language_original +    end +    def format +      @lang_class.format +    end +    def identifier +      @lang_class.identifier +    end +    def source +      @lang_class.source +    end +    def relation +      @lang_class.relation +    end +    def coverage +      @lang_class.coverage +    end +    def keywords +      @lang_class.keywords +    end +    def comments +      @lang_class.comments +    end +    def cls_loc +      @lang_class.cls_loc +    end +    def cls_dewey +      @lang_class.cls_dewey +    end +    def cls_oclc +      @lang_class.cls_oclc +    end +    def cls_gutenberg +      @lang_class.cls_gutenberg +    end +    def cls_isbn +      @lang_class.cls_isbn +    end +    def prefix_a +      @lang_class.prefix_a +    end +    def prefix_b +      @lang_class.prefix_b +    end +    def topic_register +      @lang_class.topic_register +    end +    def fns +      @lang_class.fns +    end +    def word_count +      @lang_class.word_count +    end +    def dgst +      @lang_class.dgst +    end +    def sc_number +      @lang_class.sc_number +    end +    def sc_date +      @lang_class.sc_date +    end +    def last_generated +      @lang_class.last_generated +    end +    def sisu_version +      @lang_class.sisu_version +    end +    def ruby_version +      @lang_class.ruby_version +    end +    def suggested_links +      @lang_class.suggested_links +    end +    def language_version_list +      @lang_class.language_version_list +    end +    def language +      @lang_class.language +    end +    def manifest_description +      @lang_class.manifest_description +    end +    def manifest_description_output +      @lang_class.manifest_description_output +    end +    def manifest_description_metadata +      @lang_class.manifest_description_metadata +    end +    def language_list_translated +      @lang_class.language_list +    end +    def language_list +      case @trans_str +      when /American/i       then 'American English'                    # tag depreciated, see iso 639-2 +      when /English/i        then 'English' +      when /French/i         then 'français' +      when /German/i         then 'Deutsch' +      when /Italian/i        then 'Italiano' +      when /Spanish/i        then 'español' +      when /Portuguese Brazil|Brazilian(?: Portuguese)?/i +                                  'Brazilian Português'                 # tag depreciated, see iso 639-2 +      when /Portuguese/i     then 'Português' +      when /Swedish/i        then 'svenska' +      when /Danish/i         then 'dansk' +      when /Finnish/i        then 'suomi' +      when /Norwegian/i      then 'norsk' +      when /Icelandic/i      then 'Icelandic' +      when /Dutch/i          then 'Nederlands' +      when /Estonian/i       then 'Estonian' +      when /Hungarian/i      then 'Hungarian' +      when /Polish/i         then 'polski' +      when /Romanian/i       then 'română' +      when /Russian/i        then 'Русский (Russkij)' +      when /Greek/i          then 'Ελληνικά (Ellinika)' +      when /Ukranian/i       then 'українська (ukrajins\'ka)' +      when /Turkish/i        then 'Türkçe' +      when /Slovenian/i      then 'Slovenian' +      when /Croatian/i       then 'Croatian' +      when /Slovak(?:ian)?/i then 'slovensky'            #slovensky ? +      when /Czech/i          then 'česky' +      when /Bulgarian/i      then 'Български (Bəlgarski)' +      when /Japanese/i       then '日本語 (Nihongo)' +      when /Korean/i         then '한국어 (Hangul)' +     #when /Catalan/i        then 'català' +      else                         'English' +      end +      #check on 中文  and عربي +    end +  end +  <<language_english>> +  <<language_french>> +  <<language_german>> +  <<language_spanish>> +  <<language_italian>> +  <<language_finnish>> +  <<language_protuguese>> +  <<language_swedish>> +  <<language_remaining>> +end +__END__ +#+END_SRC + +* translations +** English + +#+NAME: language_english +#+BEGIN_SRC  ruby +class English +  def initialize(md,doc_lang,trans_str) +    @md,@doc_lang,@trans_str=md,doc_lang,trans_str +  end +  def filename +    'filename' +  end +  def filetype_description +    'filetype description' +  end +  def metadata +    'metadata' +  end +  def file_size +    'file size' +  end +  def full_title #dc +    'Title' +  end +  def title +    'Title' +  end +  def subtitle +    'Subtitle' +  end +  def author +    'Author' +  end +  def creator #dc +    'Creator' +  end +  def contributor #dc +    'Contributor' +  end +  def translator +    'Translator' +  end +  def illustrator +    'Illustrator' +  end +  def publisher #dc +    'Publisher' +  end +  def prepared_by +    'Prepared by' +  end +  def digitized_by +    'Digitized by' +  end +  def contents +    'Contents' +  end +  def subject #dc +    'Subject' +  end +  def description #dc (watch) +    'Description' +  end +  def abstract #dc +    'Abstract' +  end +  def type #dc +    'Type' +  end +  def rights #dc +    'Rights' +  end +  def date #dc +    'Date' +  end +  def date_created #dc +    'Date created' +  end +  def date_issued #dc +    'Date issued' +  end +  def date_available #dc +    'Date available' +  end +  def date_modified #dc +    'Date modified' +  end +  def date_valid #dc +    'Date valid' +  end +  def language #dc +    'Language' +  end +  def language_original +    'Original Language' +  end +  def format #dc +    'Format' +  end +  def identifier #dc +    'Identifier' +  end +  def source #dc +    'Source' +  end +  def relation #dc +    'Relation' +  end +  def coverage #dc +    'Coverage' +  end +  def keywords +    'Keywords' +  end +  def comments +    'Comments' +  end +  def cls_loc +    'Classify Library of Congress' +  end +  def cls_dewey +    'Classify Dewey' +  end +  def cls_oclc +    'Classify OCLC number' +  end +  def cls_gutenberg +    'Classify Project Gutenberg' +  end +  def cls_isbn +    'Classify ISBN' +  end +  def prefix_a +    'Prefix (a)' +  end +  def prefix_b +    'Prefix (b)' +  end +  def topic_register +    'Topics Registered' +  end +  def sourcefile +    'Sourcefile' +  end +  def word_count +    'Word Count approximate' +  end +  def sourcefile_digest +    'Sourcefile Digest' +  end +  def digest_md5 +    'Sourcefile Digest (md5)' +  end +  def digest_sha256 +    'Sourcefile Digest (sha256)' +  end +  def sc_number +    'Document (RCS/CVS) number' +  end +  def sc_date +    'Document (RCS/CVS) number' +  end +  def last_generated +    'Document (ao) last generated' +  end +  def sisu_version +    'Generated by' +  end +  def ruby_version +    'Ruby version' +  end +  def suggested_links +    'metadata suggested links' +  end +  def language_version_list +    'Document Language Versions, manifests' +  end +  def manifest_description +    'SiSU manifest of document filetypes and metadata' +  end +  def manifest_description_output +    'Available document filetypes' +  end +  def manifest_description_metadata +    'Document Metadata' +  end +  def language_list_translated +    case @trans_str +    when /American/i       then 'American English'                    # tag depreciated, see iso 639-2 +    when /English/i        then 'English' +    when /French/i         then 'French' +    when /German/i         then 'German' +    when /Italian/i        then 'Italian' +    when /Spanish/i        then 'Spanish' +    when /Portuguese Brazil|Brazilian(?: Portuguese)?/i +                                'Brazilian Portuguese'                # tag depreciated, see iso 639-2 +    when /Portuguese/i     then 'Portuguese' +    when /Swedish/i        then 'Swedish' +    when /Danish/i         then 'Danish' +    when /Finnish/i        then 'Finnish' +    when /Norwegian/i      then 'Norwegian' +    when /Icelandic/i      then 'Icelandic' +    when /Dutch/i          then 'Dutch' +    when /Estonian/i       then 'Estonian' +    when /Hungarian/i      then 'Hungarian' +    when /Polish/i         then 'Polish' +    when /Romanian/i       then 'Romanian' +    when /Russian/i        then 'Russian' +    when /Greek/i          then 'Greek' +    when /Ukranian/i       then 'Ukranian' +    when /Turkish/i        then 'Turkish' +    when /Slovenian/i      then 'Slovenian' +    when /Croatian/i       then 'Croatian' +    when /Slovak(?:ian)?/i then 'Slovakian' +    when /Czech/i          then 'Czech' +    when /Bulgarian/i      then 'Bulgarian' +    else @trans_str +    end +  end +end +#+END_SRC + +** French + +#+NAME: language_french +#+BEGIN_SRC text +class French +  def initialize(md,doc_lang,trans_str) +    @md,@doc_lang,@trans_str=md,doc_lang,trans_str +  end +  def filename +    'nom de fichier' +  end +  def filetype_description +    description +  end +  def metadata +    'metadonnées' +  end +  def file_size +    'taille' +  end +  def full_title #dc +    'Titre' +  end +  def title +    'Titre' +  end +  def subtitle +    'Sous titre' +  end +  def author +    'Auteur' +  end +  def author #dc +    'Auteur' +  end +  def contributor #dc +    'Contributeur' +  end +  def translator +    'Traducteur' +  end +  def illustrator +    'Illustrateur' +  end +  def publisher #dc +    'Éditeur' +  end +  def prepared_by +    'Préparé par' +  end +  def digitized_by +    'Numérisé par' +  end +  def contents +    'Contents' #translate +  end +  def subject #dc +    'Sujet' +  end +  def description #dc (watch) +    'Description' +  end +  def abstract #dc +    'Résumé' +  end +  def type #dc +    'Type' +  end +  def rights #dc +    'Droits relatifs à la ressource' +  end +  def date #dc +    'Date' +  end +  def date_created #dc +    'Date de création' +  end +  def date_issued #dc +    'Date de publication' +  end +  def date_available #dc +    'Date de mise à disposition' +  end +  def date_modified #dc +    'Date de modification' +  end +  def date_valid #dc +    'Date de validité' +  end +  def language #dc +    'Langue' +  end +  def language_original +    'Langue originale' +  end +  def format #dc +    'Format' +  end +  def identifier #dc +    'Identifiant' +  end +  def source #dc +    'Source' +  end +  def relation #dc +    'Lien' +  end +  def coverage #dc +    'Portée du document' +  end +  def keywords +    'Mots clef' +  end +  def comments +    'Commentaires' +  end +  def cls_loc +    'Classification de la bibliothèque du congres' +  end +  def cls_dewey +    'Classification Dewey' +  end +  def cls_oclc # fix +    'Classify OCLC number' +  end +  def cls_gutenberg +    'Classification du project Gutenberg' +  end +  def cls_isbn +    'Classification ISBN' +  end +  def prefix_a +    'Préfixe (a)' +  end +  def prefix_b +    'Préfixe (b)' +  end +  def topic_register +    'Topics Registered' +  end +  def sourcefile +    'Fichier source' +  end +  def word_count +    'Nombre approximatif de mots' +  end +  def sourcefile_digest +    'Condensé du fichier source' +  end +  def digest_md5 +    'Condensé du fichier source (md5)' +  end +  def digest_sha256 +    'Condensé du fichier source (sha256)' +  end +  def sc_number +    'Numéro (RCS/CVS) du document' +  end +  def sc_date +    'Numéro (RCS/CVS) du document' +  end +  def last_generated +    'Dernière production du document (metaverse)' +  end +  def sisu_version +    'Généré par' +  end +  def ruby_version +    'Version de Ruby' +  end +  def suggested_links +    'Liens suggérés' +  end +  def language_version_list +    'Versions des langues du document, manifestes' +  end +  def manifest_description +    'SiSU manifest of document filetypes and metadata' +  end +  def manifest_description_output +    'Manifeste SiSU du document généré' +  end +  def manifest_description_metadata +    'Manifeste SiSU des métadonnées du document' +  end +  def language_list_translated +    case @trans_str +    when /American/i       then 'Anglais americain'                   # tag depreciated, see iso 639-2 +    when /English/i        then 'Anglais' +    when /French/i         then 'Français' +    when /German/i         then 'Allemand' +    when /Italian/i        then 'Italien' +    when /Spanish/i        then 'Espagnol' +    when /Portuguese Brazil|Brazilian(?: Portuguese)?/i +                                'Portugais brésilien'                 # tag depreciated, see iso 639-2 +    when /Portuguese/i     then 'Portugais' +    when /Swedish/i        then 'Suédois' +    when /Danish/i         then 'Danois' +    when /Finnish/i        then 'Finnois' +    when /Norwegian/i      then 'Norvégien' +    when /Icelandic/i      then 'Islandais' +    when /Dutch/i          then 'Néerlandais' +    when /Estonian/i       then 'Estonien' +    when /Hungarian/i      then 'Hongrois' +    when /Polish/i         then 'Polonais' +    when /Romanian/i       then 'Roumain' +    when /Russian/i        then 'Russe' +    when /Greek/i          then 'Grec' +    when /Ukranian/i       then 'Ukrainien' +    when /Turkish/i        then 'Turc' +    when /Slovenian/i      then 'Slovène' +    when /Croatian/i       then 'Croate' +    when /Slovak(?:ian)?/i then 'Slovaque' +    when /Czech/i          then 'Tcheque' +    when /Bulgarian/i      then 'Bulgare' +    else @trans_str +    end +  end +end +#+END_SRC + +** German + +#+NAME: language_german +#+BEGIN_SRC text +class German +  def initialize(md,doc_lang,trans_str) +    @md,@doc_lang,@trans_str=md,doc_lang,trans_str +  end +  def filename +    'Dateiname' +  end +  def filetype_description +    description +  end +  def metadata +    'Metadata' +  end +  def file_size +    'Dateigrösse' +  end +  def full_title #dc +    'Titel' +  end +  def title +    'Titel' +  end +  def subtitle +    'Untertitel' +  end +  def author +    'Autor' +  end +  def contributor #dc +    'Mitautor' +  end +  def translator +    'Übersetzung' +  end +  def illustrator +    'Illustrator' +  end +  def publisher +    'Herausgeber' +  end +  def prepared_by +    'gesetzt von' +  end +  def digitized_by +    'digitalisiert von' +  end +  def contents +    'Contents' #translate +  end +  def subject +    'Titel' +  end +  def description #dc (watch) +    'Beschreibung' +  end +  def abstract #dc +    'Abstract' +  end +  def type +    'Typ' +  end +  def rights +    'Rechte' +  end +  def date +    'Datum' +  end +  def date_created +    'Erstellung' +  end +  def date_issued +    'Herausgabe' +  end +  def date_available +    'Veröffentlichung' +  end +  def date_modified +    'Modifikation' +  end +  def date_valid +    'Gültigkeit' +  end +  def language +    'Sprache' +  end +  def language_original +    'Ursprungssprache' +  end +  def format #dc +    'Format' +  end +  def identifier #dc +    'Bezeichnung' +  end +  def source #dc +    'Quelle' +  end +  def relation #dc +    'Beziehung' +  end +  def coverage #dc +    'Eingrenzung' +  end +  def keywords +    'Schlüsselwörter' +  end +  def comments +    'Kommentare' +  end +  def cls_loc +    'Klassifikation nach Library of Congress' +  end +  def cls_dewey +    'Klassifikation nach Dewey' +  end +  def cls_oclc # fix +    'Classify OCLC number' +  end +  def cls_gutenberg +    'Klassifikation nach Projekt Gutenberg' +  end +  def cls_isbn +    'Klassifikation nach ISBN' +  end +  def prefix_a +    'Präfix (a)' +  end +  def prefix_b +    'Präfix (b)' +  end +  def topic_register +    'Topics Registered' +  end +  def sourcefile +    'Quelldatei' +  end +  def word_count +    'Anzahl Wörter' +  end +  def sourcefile_digest +    'Quelldatei Digest' +  end +  def digest_md5 +    'Prüfsumme der Quelldatei (MD5)' +  end +  def digest_sha256 +    'Prüfsumme der Quelldatei (SHA256)' +  end +  def sc_number +    'Dokumentversion (RCS/CVS)' +  end +  def sc_date +    'Dokumentdatum (RCS/CVS)' +  end +  def last_generated +    'Letzte Erstellung (metaverse)' +  end +  def sisu_version +    'erstellt bei' +  end +  def ruby_version +    'Ruby Version' +  end +  def suggested_links +    'empfohlene Links' +  end +  def language_version_list +    'verfügbare Sprachen' +  end +  def manifest_description +    'SiSU manifest of document filetypes and metadata' +  end +  def manifest_description_output +    'SiSU Zusammenfassung des Dokumentes' +  end +  def manifest_description_metadata +    'SiSU Zusammenfassung der Metadaten' +  end +  def language_list_translated +    case @trans_str +    when /American/i       then 'Amerikanisch-Englisch'               # tag depreciated, see iso 639-2 +    when /English/i        then 'Englisch' +    when /French/i         then 'Französisch' +    when /German/i         then 'Deutsch' +    when /Italian/i        then 'Italienisch' +    when /Spanish/i        then 'Spanisch' +    when /Portuguese Brazil|Brazilian(?: Portuguese)?/i +                                'Brasilianisch-Portugiesisch'         # tag depreciated, see iso 639-2 +    when /Portuguese/i     then 'Portugiesisch' +    when /Swedish/i        then 'Schwedisch' +    when /Danish/i         then 'Dänisch' +    when /Finnish/i        then 'Finnisch' +    when /Norwegian/i      then 'Norwegisch' +    when /Icelandic/i      then 'Isländisch' +    when /Dutch/i          then 'Niederländisch' +    when /Estonian/i       then 'Estnisch' +    when /Hungarian/i      then 'Ungarisch' +    when /Polish/i         then 'Polnisch' +    when /Romanian/i       then 'Rumänisch' +    when /Russian/i        then 'Russisch' +    when /Greek/i          then 'Griechisch' +    when /Ukranian/i       then 'Ukrainisch' +    when /Turkish/i        then 'Türkisch' +    when /Slovenian/i      then 'Slovenisch' +    when /Croatian/i       then 'Kroatisch' +    when /Slovak(?:ian)?/i then 'Slovakisch' +    when /Czech/i          then 'Tschechisch' +    when /Bulgarian/i      then 'Bulgarisch' +    else @trans_str +    end +  end +end +#+END_SRC + +** Spanish + +#+NAME: language_spanish +#+BEGIN_SRC text +class Spanish +  def initialize(md,doc_lang,trans_str) +    @md,@doc_lang,@trans_str=md,doc_lang,trans_str +  end +  def filename +   'nombre del fichero' +  end +  def filetype_description +    description +  end +  def metadata +    'metadatos' +  end +  def file_size +    'tamaño del fichero' +  end +  def full_title #dc +    'Título' +  end +  def title +    'Título' +  end +  def subtitle +    'Subtítulo' +  end +  def author #dc +    'Creador' +  end +  def contributor #dc +    'Contribuidor' +  end +  def translator +    'Traductor' +  end +  def illustrator +    'Ilustrador' +  end +  def publisher #dc +    'Editor' +  end +  def prepared_by +    'Preparado por' +  end +  def digitized_by +    'Digitalizado por' +  end +  def contents +    'Contents' #translate +  end +  def subject #dc +    'Asunto' +  end +  def description #dc (watch) +    'Descripción' +  end +  def abstract #dc +    'Resumen' +  end +  def type #dc +    'Tipo' +  end +  def rights #dc +    'Derechos' +  end +  def date #dc +    'Fecha' +  end +  def date_created #dc +    'Fecha de creación' +  end +  def date_issued #dc +    'Fecha de publicación' +  end +  def date_available #dc +    'Fecha de disponibilidad' +  end +  def date_modified #dc +    'Fecha de modificación' +  end +  def date_valid #dc +    'Fecha de valided' +  end +  def language #dc +    'Idioma' +  end +  def language_original +    'Lenguaje original' +  end +  def format #dc +    'Formato' +  end +  def identifier #dc +    'Identificador' +  end +  def source #dc +    'Fuente' +  end +  def relation #dc +    'Relación' +  end +  def coverage #dc +    'Cobertura' +  end +  def keywords +    'Palabras claves' +  end +  def comments +    'Comentarios' +  end +  def cls_loc +    'Clasificación Biblioteca del Congreso' +  end +  def cls_dewey +    'Clasificación Dewey' +  end +   def cls_oclc # fix +     'Classify OCLC number' +   end +  def cls_gutenberg +    'Clasificación Proyecto Gutenberg' +  end +  def cls_isbn +    'Clasificación ISBN' +  end +  def prefix_a +    'Prefijo (a)' +  end +  def prefix_b +    'Prefijo (b)' +  end +   def topic_register +     'Topics Registered' +   end +  def sourcefile +    'Fichero fuente' +  end +  def word_count +    'Número de palabras apróximado' +  end +  def sourcefile_digest +    'Resumen del fichero fuente' +  end +  def digest_md5 +    'Resumen del fichero fuente (md5)' +  end +  def digest_sha256 +    'Resumen del fichero fuente (sha256)' +  end +  def sc_number +    'Versión (RCS/CVS) del documento' +  end +  def sc_date +    'Versión (RCS/CVS) del documento' +  end +  def last_generated +    'Última generación (metaverse) del documento' +  end +  def sisu_version +    'Generado por' +  end +  def ruby_version +    'Versión de Ruby' +  end +  def suggested_links +    'enlaces sugeridos de metadatos' +  end +  def language_version_list +    'Document Language Versions, manifests' +  end +   def manifest_description +     'SiSU manifest of document filetypes and metadata' +   end +  def manifest_description_output +    'Manifiesto SiSU de salida generada' +  end +  def manifest_description_metadata +    'Manifiesto SiSU de metadatos de documento' +  end +  def language_list_translated +    case @trans_str +    when /American/i       then 'Inglés Americano'                     # tag depreciated, see iso 639-2 +    when /English/i        then 'Inglés' +    when /French/i         then 'Francés' +    when /German/i         then 'Alemán' +    when /Italian/i        then 'Italiano' +    when /Spanish/i        then 'Español' +    when /Portuguese Brazil|Brazilian(?: Portuguese)?/i +                                'Portugués de Brasil'                  # tag depreciated, see iso 639-2 +    when /Portuguese/i     then 'Portugués' +    when /Swedish/i        then 'Sueco' +    when /Danish/i         then 'Danés' +    when /Finnish/i        then 'Finés' +    when /Norwegian/i      then 'Noruego' +    when /Icelandic/i      then 'Islandés' +    when /Dutch/i          then 'Holandés' +    when /Estonian/i       then 'Estonio' +    when /Hungarian/i      then 'Húngaro' +    when /Polish/i         then 'Polaco' +    when /Romanian/i       then 'Rumano' +    when /Russian/i        then 'Ruso' +    when /Greek/i          then 'Griego' +    when /Ukranian/i       then 'Ucraniano' +    when /Turkish/i        then 'Turco' +    when /Slovenian/i      then 'Eslovaco' +    when /Croatian/i       then 'Croata' +    when /Slovak(?:ian)?/i then 'Eslovaco' +    when /Czech/i          then 'Checo' +    when /Bulgarian/i      then 'Búlgaro' +    else @trans_str +    end +  end +end +#+END_SRC + +** Italian + +#+NAME: language_italian +#+BEGIN_SRC text +class Italian +  def initialize(md,doc_lang,trans_str) +    @md,@doc_lang,@trans_str=md,doc_lang,trans_str +  end +  def filename +    'nome del file' +  end +  def filetype_description +    description +  end +  def metadata +    'metadati' +  end +  def file_size +    'dimensione' +  end +  def full_title #dc +    'Titolo' +  end +  def title +    'Titolo' +  end +  def subtitle +    'Sottotitolo' +  end +  def author #dc +    'Autore' +  end +  def contributor #dc +    'Contributore' +  end +  def translator +    'Traduttore' +  end +  def illustrator +    'Illustratore' +  end +  def publisher #dc +    'Casa editrice' +  end +  def prepared_by +    'Preparato da' +  end +  def digitized_by +    'Convertito in digitale da' +  end +  def contents +    'Contents' #translate +  end +  def subject #dc +    'Oggetto' +  end +  def description #dc (watch) +    'Descrizione' +  end +  def abstract #dc +    'Abstract' +  end +  def type #dc +    'Tipo' +  end +  def rights #dc +    'Diritti del lettore' +  end +  def date #dc +    'Data' +  end +  def date_created #dc +    'Data di creazione' +  end +  def date_issued #dc +    'Data di pubblicazione' +  end +  def date_available #dc +    'Data di effettiva disponibilità' +  end +  def date_modified #dc +    'Data di ultima modifica' +  end +  def date_valid #dc +    'Data di inizo validità' +  end +  def language #dc +    'Lingua' +  end +  def language_original +    'Lingua originale' +  end +  def format #dc +    'Formato' +  end +  def identifier #dc +    'Indentificatore' +  end +  def source #dc +    'Fonte' +  end +  def relation #dc +    'Collegamento' +  end +  def coverage #dc +    'Ambito' +  end +  def keywords +    'Parole chiave' +  end +  def comments +    'Commenti' +  end +  def cls_loc +    'Classificazione della Library of Congress' +  end +  def cls_dewey +    'Classificazione Dewey' +  end +  def cls_oclc # fix +    'Classify OCLC number' +  end +  def cls_gutenberg +    'Classificazione del Progetto Gutenberg' +  end +  def cls_isbn +    'Numero ISBN' +  end +  def prefix_a +    'Premessa (a)' +  end +  def prefix_b +    'Premessa (b)' +  end +  def topic_register +    'Topics Registered' +  end +  def sourcefile +    'Sorgente' +  end +  def word_count +    'Numero approssimativo di parole' +  end +  def sourcefile_digest +    'Checksum file sorgente' +  end +  def digest_md5 +    'Checksum file sorgente (md5)' +  end +  def digest_sha256 +    'Checksum file sorgente (sha256)' +  end +  def sc_number +    'Numero di revisione (RCS/CVS)' +  end +  def sc_date +    'Numero di revisione (RCS/CVS)' +  end +  def last_generated +    'Data di ultima generazione (ao metaverse)' +  end +  def sisu_version +    'Generato da' +  end +  def ruby_version +    'Ruby versione' +  end +  def suggested_links +    'Link suggeriti' +  end +  def language_version_list +    'Traduzioni disponibili' +  end +  def manifest_description +    'SiSU manifest of document filetypes and metadata' +  end +  def manifest_description_output +    'Inventario SiSU dell\'output generato' +  end +  def manifest_description_metadata +    'Inventario SiSU dei metadati' +  end +  def language_list_translated +    case @trans_str +    when /American/i       then 'Inglese USA'                         # tag depreciated, see iso 639-2 +    when /English/i        then 'Inglese' +    when /French/i         then 'Francese' +    when /German/i         then 'Tedesco' +    when /Italian/i        then 'Italiano' +    when /Spanish/i        then 'Spagnolo' +    when /Portuguese Brazil|Brazilian(?: Portuguese)?/i +                                'Portoguese (Brasile)'                # tag depreciated, see iso 639-2 +    when /Portuguese/i     then 'Portoguese' +    when /Swedish/i        then 'Svedese' +    when /Danish/i         then 'Danese' +    when /Finnish/i        then 'Finlandese' +    when /Norwegian/i      then 'Norvegese' +    when /Icelandic/i      then 'Islandese' +    when /Dutch/i          then 'Olandese' +    when /Estonian/i       then 'Estone' +    when /Hungarian/i      then 'Ungherese' +    when /Polish/i         then 'Polacco' +    when /Romanian/i       then 'Romeno' +    when /Russian/i        then 'Russo' +    when /Greek/i          then 'Greco' +    when /Ukranian/i       then 'Ucraino' +    when /Turkish/i        then 'Turco' +    when /Slovenian/i      then 'Sloveno' +    when /Croatian/i       then 'Croato' +    when /Slovak(?:ian)?/i then 'Slovacco' +    when /Czech/i          then 'Ceco' +    when /Bulgarian/i      then 'Bulgaro' +    else @trans_str +    end +  end +end +#+END_SRC + +** Finnish + +#+NAME: language_finnish +#+BEGIN_SRC text +class Finnish +  def initialize(md,doc_lang,trans_str) +    @md,@doc_lang,@trans_str=md,doc_lang,trans_str +  end +  def filename +   'tiedostonimi' +  end +  def filetype_description +    description +  end +  def metadata +    'metadata' +  end +  def file_size +    'tiedoston koko' +  end +  def full_title #dc +    'otsikko' +  end +  def title +    'Otsikko' +  end +  def subtitle +    'Alaotsikko' +  end +  def author #dc +    'tekijä' +  end +  def contributor #dc +    'osallistuja' +  end +  def translator +    'Kääntäjä' +  end +  def illustrator +    'Kuvittaja' +  end +  def publisher #dc +    'julkaisija' +  end +  def prepared_by +    'Valmistaja' +  end +  def digitized_by +    'Digitalisoinut' +  end +  def contents +    'Contents' #translate +  end +  def subject #dc +    'aihe' +  end +  def description #dc (watch) +    'kuvaus' +  end +  def abstract #dc +    'tiivistelmä' +  end +  def type #dc +    'tyyppi' +  end +  def rights #dc +    'oikeudet' +  end +  def date #dc +    'päiväys' +  end +  def date_created #dc +    'luontipäivä' +  end +  def date_issued #dc +    'julkaisupäivä' +  end +  def date_available #dc +    'saantipäivä' +  end +  def date_modified #dc +    'muokkauspäivä' +  end +  def date_valid #dc +    'kelpoisuuspäivä' +  end +  def language #dc +    'kieli' +  end +  def language_original +    'Alkuperäiskieli' +  end +  def format #dc +    'muoto' +  end +  def identifier #dc +    'tunnus' +  end +  def source #dc +    'lähde' +  end +  def relation #dc +    'suhde' +  end +  def coverage #dc +    'kattavuus' +  end +  def keywords +    'Avainsanat' +  end +  def comments +    'Kommentit' +  end +  def cls_loc +    'Classify Library of Congress' +  end +  def cls_dewey +    'Classify Dewey' +  end +  def cls_oclc # fix +    'Classify OCLC number' +  end +  def cls_gutenberg +    'Classify Project Gutenberg' +  end +  def cls_isbn +    'Classify ISBN' +  end +  def prefix_a +    'Prefix (a)' +  end +  def prefix_b +    'Prefix (b)' +  end +  def topic_register +    'Topics Registered' +  end +  def sourcefile +    'Lähdetiedosto' +  end +  def word_count +    'Arvioitu sanamäärä' +  end +  def sourcefile_digest +    'Lähdetiedoston tiiviste' +  end +  def digest_md5 +    'Lähdetiedoston tiiviste (md5)' +  end +  def digest_sha256 +    'Lähdetiedoston tiiviste (sha256)' +  end +  def sc_number +    'Dokumentin RCS/CVS-numero' +  end +  def sc_date +    'Dokumentin RCS/CVS-päiväys' +  end +  def last_generated +    'Viimeksi tuotettu dokumentti (metaverse)' +  end +  def sisu_version +    'Generoinut' +  end +  def ruby_version +    'Ruby-versio' +  end +  def suggested_links +    'metadatan ehdottamat linkit' +  end +  def language_version_list +    'Dokumentin kieliversiot, manifestit' +  end +  def manifest_description +    'SiSU manifest of document filetypes and metadata' +  end +  def manifest_description_output +    'Tuotetun tuloksen SISU-manifesti' +  end +  def manifest_description_metadata +    'Dokumenttimetadatan SISU-manifesti' +  end +  def language_list_translated +    case @trans_str +    when /American/i       then 'Amerikanenglanti'                    # tag depreciated, see iso 639-2 +    when /English/i        then 'Englanti' +    when /French/i         then 'Ranska' +    when /German/i         then 'Saksa' +    when /Italian/i        then 'Italia' +    when /Spanish/i        then 'Espanja' +    when /Portuguese Brazil|Brazilian(?: Portuguese)?/i +                                'Brasilian portugali'                 # tag depreciated, see iso 639-2 +    when /Portuguese/i     then 'Portugali' +    when /Swedish/i        then 'Ruotsi' +    when /Danish/i         then 'Tanska' +    when /Finnish/i        then 'Suomi' +    when /Norwegian/i      then 'Norja' +    when /Icelandic/i      then 'Islanti' +    when /Dutch/i          then 'Hollanti' +    when /Estonian/i       then 'Viro' +    when /Hungarian/i      then 'Unkari' +    when /Polish/i         then 'Puola' +    when /Romanian/i       then 'Romania' +    when /Russian/i        then 'Venäjä' +    when /Greek/i          then 'Kreikka' +    when /Ukranian/i       then 'Ukraina' +    when /Turkish/i        then 'Turkki' +    when /Slovenian/i      then 'Slovenia' +    when /Croatian/i       then 'Kroatia' +    when /Slovak(?:ian)?/i then 'Slovakki' +    when /Czech/i          then 'Tsekki' +    when /Bulgarian/i      then 'Bulgaria' +    else @trans_str +    end +  end +end +#+END_SRC + +** Portuguese + +#+NAME: language_protuguese +#+BEGIN_SRC text +class Portuguese            < English +end +#+END_SRC + +** Swedish + +#+NAME: language_swedish +#+BEGIN_SRC text +class Swedish               < English +  def contents +    'Innehåll' +  end +end +#+END_SRC + +** remaining + +#+NAME: language_remaining +#+BEGIN_SRC text +class Danish                < English +end +class Norwegian             < English +end +class Icelandic             < English +end +class Dutch                 < English +end +class Estonian              < English +end +class Hungarian             < English +end +class Polish                < English +end +class Romanian              < English +end +class Russian               < English +end +class Greek                 < English +end +class Ukranian              < English +end +class Turkish               < English +end +class Croatian              < English +end +class Slovakian             < English +end +class Czech                 < English +end +class Bulgarian             < English +end +#+END_SRC + +* document header + +#+NAME: sisu_document_header +#+BEGIN_SRC text +encoding: utf-8 +- Name: SiSU + +  - Description: documents, structuring, processing, publishing, search +    i18n + +  - 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 +* NOTES +** language list po4a + +#+BEGIN_SRC text +#% Language List po4a +http://www.debian.org/international/l10n/po/ +see polyglossia for subset +- CSB (Unknown language) +- KAB (Unknown language) +- TLH (Unknown language) +- aa (Afar) +- ab (Abkhazian) +- af (Afrikaans) +- af_ZA (Afrikaans, as spoken in South Africa) +- am (Amharic) +- an (Unknown language) +- ang (Unknown language) +- ar (Arabic) +- ar_AR (Arabic, as spoken in Argentina) +- ar_EG (Arabic, as spoken in Egypt) +- ar_OM (Arabic, as spoken in Oman) +- ar_PS (Arabic, as spoken in Palestinian Territory, Occupied) +- ar_SA (Arabic, as spoken in Saudi Arabia) +- ar_SY (Arabic, as spoken in Syrian Arab Republic) +- as (Assamese) +- ast (Unknown language) +- ay (Aymara) +- az (Azerbaijani) +- az_IR (Azerbaijani, as spoken in Iran) +- be (Belarusian) +- be@latin (Unknown language) +- be@tarask (Unknown language) +- bem (Unknown language) +- bg (Bulgarian) +- bg_BG (Bulgarian, as spoken in Bulgaria) +- bi (Bislama) +- bn (Bengali) +- bn_BD (Bengali, as spoken in Bangladesh) +- bn_IN (Bengali, as spoken in India) +- bo (Tibetan) +- br (Breton) +- bs (Bosnian) +- bs_BA (Bosnian, as spoken in Bosnia and Herzegovina) +- bs_BS (Bosnian, as spoken in Bahamas) +- byn (Unknown language) +- ca (Catalan) +- ca@valencia (Unknown language) +- ca_AD (Catalan, as spoken in Andorra) +- ca_ES (Catalan, as spoken in Spain) +- ca_ES@valencia (Unknown language) +- ca_FR (Catalan, as spoken in France) +- ca_IT (Catalan, as spoken in Italy) +- co (Corsican) +- crh (Unknown language) +- cs (Czech) +- cs_CZ (Czech, as spoken in Czech Republic) +- csb (Unknown language) +- cy (Welsh) +- cy_GB (Welsh, as spoken in Great Britain) +- cz (Unknown language) +- da (Danish) +- da_DK (Danish, as spoken in Denmark) +- de (German) +- de_AT (German, as spoken in Austria) +- de_CH (German, as spoken in Switzerland) +- de_DE (German, as spoken in Germany) +- dk (Unknown language) +- dz (Dzongkha) +- el (Greek) +- el_GR (Greek, as spoken in Greece) +- en (English) +- en@boldquot (Unknown language) +- en@quot (Unknown language) +- en@shaw (Unknown language) +- en_AU (English, as spoken in Australia) +- en_CA (English, as spoken in Canada) +- en_GB (English, as spoken in Great Britain) +- en_NZ (English, as spoken in New Zealand) +- en_US (English, as spoken in United States) +- en_US@piglatin (Unknown language) +- en_ZA (English, as spoken in South Africa) +- eo (Esperanto) +- es (Spanish) +- es_AR (Spanish, as spoken in Argentina) +- es_CL (Spanish, as spoken in Chile) +- es_CO (Spanish, as spoken in Colombia) +- es_CR (Spanish, as spoken in Costa Rica) +- es_DO (Spanish, as spoken in Dominican Republic) +- es_EC (Spanish, as spoken in Ecuador) +- es_ES (Spanish, as spoken in Spain) +- es_GA (Spanish, as spoken in Gabon) +- es_GT (Spanish, as spoken in Guatemala) +- es_HN (Spanish, as spoken in Honduras) +- es_LA (Spanish, as spoken in Lao People''s Democratic Republic) +- es_MX (Spanish, as spoken in Mexico) +- es_NI (Spanish, as spoken in Nicaragua) +- es_PA (Spanish, as spoken in Panama) +- es_PE (Spanish, as spoken in Peru) +- es_PR (Spanish, as spoken in Puerto Rico) +- es_SV (Spanish, as spoken in El Salvador) +- es_UY (Spanish, as spoken in Uruguay) +- es_VE (Spanish, as spoken in Venezuela) +- et (Estonian) +- et_EE (Estonian, as spoken in Estonia) +- eu (Basque) +- eu_ES (Basque, as spoken in Spain) +- fa (Persian) +- fa_AF (Persian, as spoken in Afghanistan) +- fa_IR (Persian, as spoken in Iran) +- fi (Finnish) +- fi_FI (Finnish, as spoken in Finland) +- fil (Unknown language) +- fo (Faeroese) +- fo_FO (Faeroese, as spoken in Faroe Islands) +- fr (French) +- fr_BE (French, as spoken in Belgium) +- fr_CA (French, as spoken in Canada) +- fr_CH (French, as spoken in Switzerland) +- fr_FR (French, as spoken in France) +- fr_FX (French, as spoken in France, Metropolitan) +- fr_LU (French, as spoken in Luxembourg) +- frp (Unknown language) +- fur (Unknown language) +- fy (Frisian) +- fy_NL (Frisian, as spoken in Netherlands) +- ga (Irish) +- gd (Gaelic (Scots)) +- gez (Unknown language) +- gl (Galician) +- gl_ES (Galician, as spoken in Spain) +- gn (Guarani) +- gu (Gujarati) +- gv (Manx) +- ha (Hausa) +- he (Hebrew) +- he_IL (Hebrew, as spoken in Israel) +- hi (Hindi) +- hne (Unknown language) +- hr (Croatian) +- hr_HR (Croatian, as spoken in Croatia) +- ht (Unknown language) +- hu (Hungarian) +- hu_HU (Hungarian, as spoken in Hungary) +- hy (Armenian) +- ia (Interlingua) +- id (Indonesian) +- id_ID (Indonesian, as spoken in Indonesia) +- ig (Unknown language) +- io (Unknown language) +- is (Icelandic) +- is_IS (Icelandic, as spoken in Iceland) +- it (Italian) +- it_CH (Italian, as spoken in Switzerland) +- it_IT (Italian, as spoken in Italy) +- iu (Inuktitut) +- ja (Japanese) +- ja_JP (Japanese, as spoken in Japan) +- jv (Unknown language) +- jv_ID (Unknown language) +- ka (Georgian) +- kab (Unknown language) +- kk (Kazakh) +- kl (Kalaallisut) +- km (Khmer) +- km_KH (Khmer, as spoken in Cambodia) +- kn (Kannada) +- ko (Korean) +- ko_KR (Korean, as spoken in Korea) +- ks (Kashmiri) +- ku (Kurdish) +- kw (Cornish) +- ky (Kirghiz) +- la (Latin) +- lb (Letzeburgesch) +- lg (Unknown language) +- li (Unknown language) +- ln (Lingala) +- lo (Lao) +- lt (Lithuanian) +- lt_LT (Lithuanian, as spoken in Lithuania) +- lv (Latvian) +- lv_LV (Latvian, as spoken in Latvia) +- mai (Unknown language) +- mal (Unknown language) +- mg (Malagasy) +- mi (Maori) +- mk (Macedonian) +- mk_MK (Macedonian, as spoken in Macedonia, the Former Yugoslav Republic of) +- ml (Malayalam) +- ml_IN (Malayalam, as spoken in India) +- ml_ML (Malayalam, as spoken in Mali) +- mn (Mongolian) +- mr (Marathi) +- ms (Malay) +- ms_MY (Malay, as spoken in Malaysia) +- mt (Maltese) +- my (Burmese) +- my_MM (Burmese, as spoken in Myanmar) +- na (Nauru) +- nb (Norwegian Bokmål) +- nb_NO (Norwegian Bokmål, as spoken in Norway) +- nds (Unknown language) +- ne (Nepali) +- new (Unknown language) +- nl (Dutch) +- nl_BE (Dutch, as spoken in Belgium) +- nl_NL (Dutch, as spoken in Netherlands) +- nn (Norwegian Nynorsk) +- nn_NO (Norwegian Nynorsk, as spoken in Norway) +- no (Norwegian) +- no_NO (Norwegian, as spoken in Norway) +- nr (Ndebele, South) +- nso (Unknown language) +- oc (Occitan (post 1500)) +- oc_FR (Occitan (post 1500), as spoken in France) +- om (Oromo) +- or (Oriya) +- pa (Panjabi) +- pl (Polish) +- pl_PL (Polish, as spoken in Poland) +- pms (Unknown language) +- ps (Pushto) +- pt (Portuguese) +- pt_BR (Portuguese, as spoken in Brazil) +- pt_PT (Portuguese, as spoken in Portugal) +- qu (Quechua) +- rm (Rhaeto-Romance) +- ro (Romanian) +- ro_RO (Romanian, as spoken in Romania) +- ru (Russian) +- ru_RU (Russian, as spoken in Russia) +- rw (Kinyarwanda) +- sa (Sanskrit) +- sc (Sardinian) +- sd (Sindhi) +- se (Sami) +- se_NO (Sami, as spoken in Norway) +- si (Sinhalese) +- si_LK (Sinhalese, as spoken in Sri Lanka) +- si_SI (Sinhalese, as spoken in Slovenia) +- sk (Slovak) +- sk_SK (Slovak, as spoken in Slovakia) +- sl (Slovenian) +- sl_SI (Slovenian, as spoken in Slovenia) +- sl_SL (Slovenian, as spoken in Sierra Leone) +- so (Somali) +- sp (Unknown language) +- sq (Albanian) +- sq_AL (Albanian, as spoken in Albania) +- sr (Serbian) +- sr@Latn (Unknown language) +- sr@ije (Unknown language) +- sr@ijekavian (Unknown language) +- sr@ijekavianlatin (Unknown language) +- sr@latin (Unknown language) +- sr_SR (Serbian, as spoken in Suriname) +- sr_YU (Serbian, as spoken in Yugoslavia) +- st (Sotho) +- su (Sundanese) +- su_ID (Sundanese, as spoken in Indonesia) +- sv (Swedish) +- sv_SE (Swedish, as spoken in Sweden) +- sw (Swahili) +- ta (Tamil) +- ta_LK (Tamil, as spoken in Sri Lanka) +- te (Telugu) +- tg (Tajik) +- th (Thai) +- th_TH (Thai, as spoken in Thailand) +- ti (Tigrinya) +- tig (Unknown language) +- tk (Turkmen) +- tl (Tagalog) +- tlh (Unknown language) +- to (Tonga) +- tr (Turkish) +- tr_TR (Turkish, as spoken in Turkey) +- tt (Tatar) +- ug (Uighur) +- ug_CN (Uighur, as spoken in China) +- uk (Ukrainian) +- uk_UA (Ukrainian, as spoken in Ukraine) +- ur (Urdu) +- ur_PK (Urdu, as spoken in Pakistan) +- uz (Uzbek) +- uz@cyrillic (Unknown language) +- ve (Unknown language) +- vi (Vietnamese) +- vi_AR (Vietnamese, as spoken in Argentina) +- vi_DE (Vietnamese, as spoken in Germany) +- vi_PL (Vietnamese, as spoken in Poland) +- vi_TR (Vietnamese, as spoken in Turkey) +- vi_VN (Vietnamese, as spoken in Vietnam) +- wa (Unknown language) +- wal (Unknown language) +- wo (Wolof) +- xh (Xhosa) +- yi (Yiddish) +- yo (Yoruba) +- zh (Chinese) +- zh_CN (Chinese, as spoken in China) +- zh_HK (Chinese, as spoken in Hong Kong) +- zh_TW (Chinese, as spoken in Taiwan) +- zu (Zulu) + + 'sq';    'albanian' + 'am';    'amharic' +#'ar';    'arabic'         # see polyglossia + 'hy';    'armenian' +#'';      'asturian'       # polyglossia +#'';      'bahasai'        # polyglossia +#'';      'bahasam'        # polyglossia + 'eu';    'basque' + 'bn';    'bengali' + 'pt_BR'; 'brazilian' + 'br';    'breton' + 'bg';    'bulgarian' + 'ca';    'catalan'        # see polyglossia +#'';      'coptic'         # polyglossia + 'hr';    'croatian' + 'cs';    'czech' + 'da';    'danish' +#'';      'divehi'         # polyglossia + 'nl';    'dutch'          # see polyglossia + 'en';    'english'        # see polyglossia + 'eo';    'esperanto'      # see polyglossia + 'et';    'estonian' + 'gl';    'galician' + 'de';    'german' + 'el';    'greek'          #gl ? + 'he';    'hebrew' + 'hi';    'hindi' + 'is';    'icelandic' + 'ia';    'interlingua' + 'ga';    'irish' + 'it';    'italian' +#'';      'farsi'          # polyglossia + 'fi';    'finnish' + 'fr';    'french' + 'lo';    'lao' + 'la';    'latin' + 'lv';    'latvian' + 'lt';    'lithuanian' +#'';      'lsorbian'       # polyglossia +#'';      'magyar'         # polyglossia + 'ml';    'malayalam' + 'mr';    'marathi' +#'hu';    'magyar' + 'no';    'norske' + 'nn';    'nynorsk' + 'oc';    'occitan' + 'pl';    'polish' + 'pt';    'portuges' + 'ro';    'romanian' + 'ru';    'russian' + 'se';    'samin'          #(check sami?) + 'sa';    'sanskrit' + 'sr';    'serbian' +#'';      'scottish'       # polyglossia  (gd (Gaelic (Scots))) + 'sk';    'slovak' + 'sl';    'slovenian' + 'es';    'spanish' + 'sv';    'swedish' + 'ta';    'tamil' + 'te';    'telugu' + 'th';    'thai' + 'tr';    'turkish' + 'tk';    'turkmen' + 'uk';    'ukrainian' + 'ur';    'urdu' +#'';      'usorbian'       # polyglossia + 'vi';    'vietnamese' + 'cy';    'welsh' + 'us';    'USenglish'      # depreciated, see iso-639-2 +#+END_SRC +** language list po4a + +#+BEGIN_SRC text +http://www.debian.org/international/l10n/po/ +http://en.wikipedia.org/wiki/List_of_ISO_639-1_codes +http://www.loc.gov/standards/iso639-2/php/code_list.php +albanian           sq +amharic            am +arabic             ar +armenian           hy +asturian +bahasai +bahasam +basque             eu +bengali            bn +brazil[ian]        pt_BR +breton             br +bulgarian          bg +catalan            ca +coptic +croatian           hr +czech              cs +danish             da +divehi +dutch              nl +english            en +esperanto          eo +estonian           et +galician           gl +german             de +greek              el +hebrew             he +hindi              hi +icelandic          is +interlingua        ia +irish              ga +italian            it +farsi +finnish            fi +french             fr +lao                lo +latin              la +latvian            lv +lithuanian         lt +lsorbian +magyar +malayalam          ml +marathi            mr +norsk              no +nynorsk            nn +occitan            oc +polish             pl +portuges           pt +romanian           ro +russian            ru +samin              se (check sami?) +sanskrit           sa +scottish            #  (gd (Gaelic (Scots))) +serbian            sr +slovak             sk +slovenian          sl +spanish            es +swedish            sv +syriac             #  (ar_SY (Arabic, as spoken in Syrian Arab Republic)) +tamil              ta +telugu             te +thai               th +turkish            tr +turkmen            tk +ukrainian          uk +urdu               ur +usorbian +vietnamese         vi +welsh              cy +#+END_SRC diff --git a/org/json.org b/org/json.org new file mode 100644 index 00000000..c2c04a7c --- /dev/null +++ b/org/json.org @@ -0,0 +1,1620 @@ +-*- mode: org -*- +#+TITLE:       sisu json +#+DESCRIPTION: documents - structuring, various output representations & search +#+FILETAGS:    :sisu:json: +#+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 + +* json.rb + +#+BEGIN_SRC ruby  :tangle "../lib/sisu/json.rb" +# <<sisu_document_header>> +module SiSU_JSON +  require_relative 'se_hub_particulars'                 # se_hub_particulars.rb +    include SiSU_Particulars +  require_relative 'se'                                 # se.rb +    include SiSU_Env +  require_relative 'json_shared'                        # json_shared.rb +    include SiSU_JSON_Munge +  require_relative 'json_format'                        # json_format.rb +    include SiSU_JSON_Format +  require_relative 'json_persist'                       # json_persist.rb +  require_relative 'shared_metadata'                    # shared_metadata.rb +  @@alt_id_count=0 +  @@tablefoot='' +  class Source +    def initialize(opt) +      @opt=opt +      @particulars=SiSU_Particulars::CombinedSingleton.instance.get_all(opt) +    end +    def read +      begin +        @env,@md,@ao_array=@particulars.env,@particulars.md,@particulars.ao_array +        unless @opt.act[:quiet][:set]==:on +          tool=if (@opt.act[:verbose_plus][:set]==:on \ +          || @opt.act[:maintenance][:set]==:on) +            @env.program.web_browser + +            ' file://' + +            @md.file.output_path.json.dir + '/' + +            @md.file.base_filename.json +          elsif @opt.act[:verbose][:set]==:on +            @env.program.web_browser + +            ' file://' + +            @md.file.output_path.json.dir + '/' + +            @md.file.base_filename.json +          else "[#{@opt.f_pth[:lng_is]}] #{@opt.fno}" +          end +          (@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], +              'JSON', +              tool +            ).green_hi_blue +          : SiSU_Screen::Ansi.new( +              @opt.act[:color_state][:set], +              'JSON', +              tool +            ).green_title_hi +          if (@opt.act[:verbose_plus][:set]==:on \ +          || @opt.act[:maintenance][:set]==:on) +            SiSU_Screen::Ansi.new( +              @opt.act[:color_state][:set], +              @opt.fns, +                '/' + @md.file.output_path.json.dir + +                '/' + @md.file.base_filename.json +            ).flow +          end +        end +        SiSU_JSON::Source::Songsheet.new(@particulars).song +      rescue +        SiSU_Errors::Rescued.new($!,$@,@opt.selections.str,@opt.fns).location do +          __LINE__.to_s + ':' + __FILE__ +        end +      ensure +        SiSU_Env::CreateSite.new(@opt).cp_css +        Dir.chdir(@opt.f_pth[:pth]) +      end +    end +    private +    class Songsheet +      def initialize(particulars) +        @env,@md,@ao_array,@particulars= +          particulars.env,particulars.md,particulars.ao_array,particulars +        @file=SiSU_Env::FileOp.new(@md) +      end +      def song +        begin +          SiSU_JSON::Source::Scroll.new(@particulars).songsheet +        rescue +          SiSU_Errors::Rescued.new($!,$@,@md.opt.selections.str,@md.fns).location do +            __LINE__.to_s + ':' + __FILE__ +          end +        ensure +        end +      end +    end +    class Scroll +      require_relative 'json_shared'                   # json_shared.rb #check already called +      require_relative 'txt_shared'                     # txt_shared.rb +        include SiSU_TextUtils +      require_relative 'css'                            # css.rb +      def initialize(particulars) +        @env,@md,@ao_array=particulars.env,particulars.md,particulars.ao_array +        @tab="\t" +        @trans=SiSU_JSON_Munge::Trans.new(@md) +        @sys=SiSU_Env::SystemCall.new +        @per=SiSU_JSON_Persist::Persist.new +      end +      def songsheet +        begin +          pre +          @data=markup(@ao_array) +          post +          publish +        ensure +          SiSU_JSON_Persist::Persist.new.persist_init +        end +      end +    protected +      def embedded_endnotes(dob='') +        dob.obj=dob.obj.gsub(/#{Mx[:en_a_o]}(\d+)\s+(.+?)#{Mx[:en_a_c]}/, +            '<endnote><number>\1</number><note>\2</note></endnote> '). +          gsub(/#{Mx[:en_b_o]}([*+]\d+)\s+(.+?)#{Mx[:en_b_c]}/, +            '<endnote><symbol>\1</symbol><note>\2</note></endnote> '). +          gsub(/#{Mx[:en_a_o]}([*+]+)\s+(.+?)#{Mx[:en_a_c]}/, +            '<endnote><symbol>\1</symbol><note>\2</note></endnote> ') +      end +      def extract_endnotes(dob='') +        notes=dob.obj.scan(/(?:#{Mx[:en_a_o]}|#{Mx[:en_b_o]})([\d*+]+\s+.+?)(?:#{Mx[:en_a_c]}|#{Mx[:en_b_c]})/) +        notes.flatten.each do |e| +          s=e.to_s +          util=SiSU_JSONutils::Clean.new(s) +          wrap=util.line_json_clean +          wrap=wrap.gsub(/^(\d+)\s+(.+?)\s*\Z/m, <<-WOK +\\n[\\1.] \\2 +              WOK +            ). +            gsub(/^([*+]\d+)\s+(.+?)\s*\Z/m, <<-WOK +\\n[\\1.] \\2 +              WOK +            ). +            gsub(/^([*+]+)\s+(.+?)\s*\Z/m, <<-WOK +\\n[\\1.] \\2 +              WOK +            ).strip +#KEEP alternative presentation of endnotes +#        wrap=wrap.gsub(/^(\d+)\s+(.+?)\s*\Z/m, <<WOK +##{Ax[:tab]*1}<p class="endnote" notenumber="\\1"> +##{Ax[:tab]*2}\\1. \\2 +##{Ax[:tab]*1}</p> +#WOK +#) +          @endnotes << wrap +        end +      end +      def json_head +        #metadata=SiSU_Metadata::Summary.new(@md).json.metadata +        #@per.head << metadata +      end +      def name_tags(dob) +        tags='' +        if defined? dob.tags \ +        and dob.tags.length > 0 # insert tags "hypertargets" +          dob.tags.each do |t| +            tags=tags << %{<named id="#{t}" />} +          end +        end +        tags +      end +      def json_structure(dob,attrib=nil) +        if dob.is ==:para \ +        || dob.is ==:heading +          if dob.is==:heading +            lv=dob.ln +            dob.ln + 2 +          else lv=nil +          end +          extract_endnotes(dob) +          dob.obj=dob.obj. +            gsub(/#{Mx[:en_a_o]}([\d*+]+)\s+(?:.+?)#{Mx[:en_a_c]}/,'<en>\1</en>'). #footnote/endnote clean +            gsub(/#{Mx[:en_b_o]}([\d*+]+)\s+(?:.+?)#{Mx[:en_b_c]}/,'<en>\1</en>') +          util=SiSU_JSONutils::Clean.new(dob.obj) +          wrapped=util.line_json_clean +          @per.body << Ax[:tab]*1 + '{' +          if defined? dob.ocn and dob.ocn +            @per.body << Ax[:tab]*2 + '"ocn": ' + dob.ocn.to_s + '",' +          end +          if lv                                                                 # main text, contents, body KEEP +            @per.body << +              Ax[:tab]*2 + %{"object": "<h#{lv}>} + wrapped + %{</h#{lv}>} + +              ((@endnotes.length > 0) ? '",' : '"') +          else +            @per.body << +              Ax[:tab]*2 + '"object": "' + wrapped + +              ((@endnotes.length > 0) ? '",' : '"') +          end +          if @endnotes.length > 0                                               # main text, endnotes KEEP +            @per.body << +              Ax[:tab]*2 + '"endnotes": "' + +              @endnotes.compact.join.strip + '"' +          end +          @per.body << Ax[:tab]*1 + '},' # unless is last object then '}' +          @endnotes=[] +        end +      end +      def block_structure(dob) +        dob=@trans.markup_block(dob) +        dob.obj=dob.obj.strip. +          gsub(/#{Mx[:en_a_o]}([\d*+]+)\s+(?:.+?)#{Mx[:en_a_c]}/,'<en>\1</en>'). #footnote/endnote clean +          gsub(/#{Mx[:en_b_o]}([\d*+]+)\s+(?:.+?)#{Mx[:en_b_c]}/,'<en>\1</en>') #footnote/endnote clean +        @per.body << Ax[:tab]*1 + '{' +        if defined? dob.ocn and dob.ocn +          @per.body << Ax[:tab]*2 + '"ocn": ' + dob.ocn.to_s + '",' +        end +        @per.body << +          Ax[:tab]*2 + '"object": "' + dob.obj + '"' +          #((@endnotes.length > 0) ? '",' : '"') +        @per.body << Ax[:tab]*1 + '},' # unless is last object then '}' +      end +      def group_structure(dob) +        dob=@trans.markup_group(dob) +        dob.obj=dob.obj.strip. +          gsub(/#{Mx[:en_a_o]}([\d*+]+)\s+(?:.+?)#{Mx[:en_a_c]}/,'<en>\1</en>'). #footnote/endnote clean +          gsub(/#{Mx[:en_b_o]}([\d*+]+)\s+(?:.+?)#{Mx[:en_b_c]}/,'<en>\1</en>') #footnote/endnote clean +        @per.body << Ax[:tab]*1 + '{' +        if defined? dob.ocn and dob.ocn +          @per.body << Ax[:tab]*2 + '"ocn": ' + dob.ocn.to_s + '",' +        end +        @per.body << +          Ax[:tab]*2 + '"object": "' + dob.obj + '"' +          #((@endnotes.length > 0) ? '",' : '"') +        @per.body << Ax[:tab]*1 + '},' # unless is last object then '}' +      end +      def poem_structure(dob) +        dob=@trans.markup_group(dob) +        dob.obj=dob.obj.strip +        @per.body << Ax[:tab]*1 + '{' +        if defined? dob.ocn and dob.ocn +          @per.body << Ax[:tab]*2 + '"ocn": ' + dob.ocn.to_s + '",' +        end +        @per.body << +          Ax[:tab]*2 + '"object": "' + dob.obj + '"' +          #((@endnotes.length > 0) ? '",' : '"') +        @per.body << Ax[:tab]*1 + '},' # unless is last object then '}' +      end +      def code_structure(dob) +        dob=@trans.markup_group(dob) +        dob.obj=dob.obj.gsub(/\s\s/,'  ').strip +        @per.body << Ax[:tab]*1 + '{' +        if defined? dob.ocn and dob.ocn +          @per.body << Ax[:tab]*2 + '"ocn": ' + dob.ocn.to_s + '",' +        end +        @per.body << +          Ax[:tab]*2 + '"object": "' + dob.obj + '"' +          #((@endnotes.length > 0) ? '",' : '"') +        @per.body << Ax[:tab]*1 + '},' # unless is last object then '}' +      end +      def table_structure(dob) +        table=SiSU_JSON_Shared::TableJSON.new(dob) +        @per.body << Ax[:tab]*1 + '{' +        if defined? dob.ocn and dob.ocn +          @per.body << Ax[:tab]*2 + '"ocn": ' + dob.ocn.to_s + '",' +        end +        @per.body << +          Ax[:tab]*2 + '"object": "' + table.table.obj + '"' +        #((@endnotes.length > 0) ? '",' : '"') +        @per.body << Ax[:tab]*1 + '},' # unless is last object then '}' +      end +      def markup(data) +        @endnotes=[] +        @rcdc=false +        @level,@cont,@copen,@json_contents_close=[],[],[],[] +        json_head +        (0..7).each { |x| @cont[x]=@level[x]=false } +        (4..7).each { |x| @json_contents_close[x]='' } +        data.each_with_index do |dob,i| +          dob=@trans.char_enc.utf8(dob) if @sys.locale =~/utf-?8/i #% utf8 +          dob=@trans.markup(dob) +          if @rcdc==false \ +          and (dob.obj =~/~meta/ \ +          and dob.obj =~/Document Information/) +            @rcdc=true +          end +          if dob.obj !~/(^#{Rx[:meta]}|#{Mx[:br_eof]}|#{Mx[:br_endnotes]})/ +            if not @rcdc +              x=SiSU_JSON_Format::FormatTextObject.new(@md,dob) +              if dob.is==:heading +                json_structure(dob) +                dob.obj=case dob.ln +                when 0 then x.heading_body0 +                when 1 then x.heading_body1 +                when 2 then x.heading_body2 +                when 3 then x.heading_body3 +                when 4 then x.heading_body4 +                when 5 then x.heading_body5 +                when 6 then x.heading_body6 +                when 7 then x.heading_body7 +                end +              else +                if dob.is ==:verse +                  poem_structure(dob) +                elsif dob.is ==:group +                  group_structure(dob) +                elsif dob.is ==:block +                  block_structure(dob) +                elsif dob.is ==:code +                  code_structure(dob) +                elsif dob.is ==:table +                  table_structure(dob) +                elsif dob.is ==:para \ +                and dob.indent.to_s =~/[1-9]/ \ +                and dob.bullet_==true +                  json_structure(dob,"indent_bullet#{dob.indent}") +                elsif dob.is ==:para \ +                and dob.indent.to_s =~/[1-9]/ \ +                and dob.indent == dob.hang +                  json_structure(dob,"indent#{dob.indent}") +                elsif dob.is==:para \ +                and dob.hang.to_s =~/[0-9]/ \ +                and dob.indent != dob.hang +                  json_structure(dob,"hang#{dob.hang.to_s}_indent#{dob.indent.to_s}") +                else json_structure(dob) +                end +              end +            end +            dob.obj=dob.obj.gsub(/#{Mx[:pa_o]}:\S+#{Mx[:pa_c]}/,'') if dob.obj +          end +        end +        6.downto(4) do |x| +          y=x - 1; v=x - 3 +          @per.body << "#{Ax[:tab]*5}</content>\n#{Ax[:tab]*y}</contents#{v}>" if @level[x]==true +        end +        3.downto(1) do |x| +          y=x - 1 +          @per.body << "#{Ax[:tab]*y}</heading#{x}>" if @level[x]==true +        end +      end +      def pre +        @per.head,@per.body=[],[] +        @per.open = '{' +      end +      def post +        @per.close = '}' +      end +      def publish +        content=[] +        @per.body[-1] = @per.body[-1].gsub(/,$/, '') #= Ax[:tab]*1 + '}' +        content << @per.open << @per.head << @per.body << @per.metadata +        content << @per.tail << @per.close +        content=content.flatten.compact +        Output.new(content,@md).json +      end +    end +    class Output +      def initialize(data,md) +        @data,@md=data,md +        @file=SiSU_Env::FileOp.new(@md) +      end +      def json +        SiSU_Env::FileOp.new(@md).mkdir +        filename_json=@file.write_file.json +        @data.each do |str| +          str=str.gsub(/\A\s+\Z/m,'') #str.gsub(/^\s+$/,'') +          filename_json.puts str unless str.empty? +        end +        filename_json.close +      end +    end +  end +end +__END__ +#+END_SRC + +* json_parts.rb + +#+BEGIN_SRC ruby  :tangle "../lib/sisu/json_parts.rb" +# <<sisu_document_header>> +module SiSU_Parts_JSON +  require_relative 'generic_parts'                       # generic_parts.rb +  include SiSU_Parts_Generic +  def the_line_break +    '<br>' +  end +  def the_table_close +    '</td></tr> +</table>' +  end +  def the_url_decoration +    def xml_open                     #'<' +      Dx[:url_o] +    end +    def xml_close                    #'>' +      Dx[:url_c] +    end +    def txt_open +      '[' +    end +    def txt_close +      ']' +    end +    self +  end +end +module SiSU_Proj_XML +  require_relative 'html_parts'                         # html_parts.rb +  require_relative 'se'                                 # se.rb +  include SiSU_Env +  class Bits < SiSU_Proj_HTML::Bits +  end +end +__END__ +#+END_SRC + +* json_shared.rb + +#+BEGIN_SRC ruby  :tangle "../lib/sisu/json_shared.rb" +# <<sisu_document_header>> +module SiSU_JSONutils +  require_relative 'generic_parts'                      # generic_parts.rb +  class Clean +    def initialize(para='') +      @para=para +      #@para,@n_char_max,@n_indent,@post,=para,n_char_max,n_indent,post +      #@n_char_max_extend = n_char_max +      #@n_hang=n_hang ? n_hang : @n_indent +    end +    def line_json_clean +      @para=@para.gsub(/<br>/,' \\ '). +        gsub(/#{Mx[:br_nl]}/,"\n\n"). +        gsub(/"/,'\"'). +        gsub(/'/,"\\\\'") +      @para +    end +  end +end +module SiSU_JSON_Munge +  require_relative 'json_parts'                         # json_parts.rb +  class Trans +    include SiSU_Parts_JSON +    def initialize(md) +      @md=md +      @sys=SiSU_Env::SystemCall.new +      @dir=SiSU_Env::InfoEnv.new(@md.fns) +      if @md.sem_tag +        @ab ||=semantic_tags.default +      end +    end +    def semantic_tags +      def default +        { +          pub:   'publication', +          conv:  'convention', +          vol:   'volume', +          pg:    'page', +          cty:   'city', +          org:   'organization', +          uni:   'university', +          dept:  'department', +          fac:   'faculty', +          inst:  'institute', +          co:    'company', +          com:   'company', +          conv:  'convention', +          dt:    'date', +          y:     'year', +          m:     'month', +          d:     'day', +          ti:    'title', +          au:    'author', +          ed:    'editor', #editor? +          v:     'version', #edition +          n:     'name', +          fn:    'firstname', +          mn:    'middlename', +          ln:    'lastname', +          in:    'initials', +          qt:    'quote', +          ct:    'cite', +          ref:   'reference', +          ab:    'abreviation', +          def:   'define', +          desc:  'description', +          trans: 'translate', +        } +      end +      self +    end +    def char_enc #character encode +      def utf8(dob='') +        if @sys.locale =~/utf-?8/i # instead ucs for utf8 # String#encode Iñtërnâtiônàlizætiøn +          str=if defined? dob.obj then dob.obj +          elsif dob.is_a?(String) then dob +          end +          if str +            #¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÞßàáâãäåæçèéêëìíîïðñòóôõöøùúûü +            #¢£¥§©ª«®°±²³µ¶¹º»¼½¾×÷ +            str=str.gsub(/</um,'<').    # '<'     # < +              gsub(/>/um,'>').    # '>'     # > +              gsub(/¢/um,'¢').   # '¢'   # ¢ +              gsub(/£/um,'£').   # '£'  # £ +              gsub(/¥/um,'¥').   # '¥'    # ¥ +              gsub(/§/um,'§').   # '§'   # § +              gsub(/©/um,'©').   # '©'   # © +              gsub(/ª/um,'ª').   # 'ª'   # ª +              gsub(/«/um,'«').   # '«'  # « +              gsub(/®/um,'®').   # '®'    # ® +              gsub(/°/um,'°').   # '°'    # ° +              gsub(/±/um,'±').   # '±' # ± +              gsub(/²/um,'²').   # '²'   # ² +              gsub(/³/um,'³').   # '³'   # ³ +              gsub(/µ/um,'µ').   # 'µ'  # µ +              gsub(/¶/um,'¶').   # '¶'   # ¶ +              gsub(/¹/um,'¹').   # '¹'   # ¹ +              gsub(/º/um,'º').   # 'º'   # º +              gsub(/»/um,'»').   # '»'  # » +              gsub(/¼/um,'¼').   # '¼' # ¼ +              gsub(/½/um,'½').   # '½' # ½ +              gsub(/¾/um,'¾').   # '¾' # ¾ +              gsub(/×/um,'×').   # '×'  # × +              gsub(/÷/um,'÷').   # '÷' # ÷ +              gsub(/¿/um,'¿').   # '¿' # ¿ +              gsub(/À/um,'À').   # 'À' # À +              gsub(/Á/um,'Á').   # 'Á' # Á +              gsub(/Â/um,'Â').   # 'Â'  #  +              gsub(/Ã/um,'Ã').   # 'Ã' # à +              gsub(/Ä/um,'Ä').   # 'Ä'   # Ä +              gsub(/Å/um,'Å').   # 'Å'  # Å +              gsub(/Æ/um,'Æ').   # 'Æ'  # Æ +              gsub(/Ç/um,'Ç').   # 'Ç' # Ç +              gsub(/È/um,'È').   # 'È' # È +              gsub(/É/um,'É').   # 'É' # É +              gsub(/Ê/um,'Ê').   # 'Ê'  # Ê +              gsub(/Ë/um,'Ë').   # 'Ë'   # Ë +              gsub(/Ì/um,'Ì').   # 'Ì' # Ì +              gsub(/Í/um,'Í').   # 'Í' # Í +              gsub(/Î/um,'Î').   # 'Î'  # Î +              gsub(/Ï/um,'Ï').   # 'Ï'   # Ï +              gsub(/Ð/um,'Ð').   # 'Ð'    # Ð +              gsub(/Ñ/um,'Ñ').   # 'Ñ' # Ñ +              gsub(/Ò/um,'Ò').   # 'Ò' # Ò +              gsub(/Ó/um,'Ó').   # 'Ó' # Ó +              gsub(/Ô/um,'Ô').   # 'Ô'  # Ô +              gsub(/Õ/um,'Õ').   # 'Õ' # Õ +              gsub(/Ö/um,'Ö').   # 'Ö'   # Ö +              gsub(/Ø/um,'Ø').   # 'Ø' # Ø +              gsub(/Ù/um,'Ù').   # 'Ù' # Ù +              gsub(/Ú/um,'Ú').   # 'Ú' # Ú +              gsub(/Û/um,'Û').   # 'Û'  # Û +              gsub(/Ü/um,'Ü').   # 'Ü'   # Ü +              gsub(/Ý/um,'Ý').   # 'Ý' # Ý +              gsub(/Þ/um,'Þ').   # 'Þ'  # Þ +              gsub(/ß/um,'ß').   # 'ß'  # ß +              gsub(/à/um,'à').   # 'à' # à +              gsub(/á/um,'á').   # 'á' # á +              gsub(/â/um,'â').   # 'â'  # â +              gsub(/ã/um,'ã').   # 'ã' # ã +              gsub(/ä/um,'ä').   # 'ä'   # ä +              gsub(/å/um,'å').   # 'å'  # å +              gsub(/æ/um,'æ').   # 'æ'  # æ +              gsub(/ç/um,'ç').   # 'ç' # ç +              gsub(/è/um,'è').   # 'è' # è +              gsub(/é/um,'é').   # '´'  # é +              gsub(/ê/um,'ê').   # 'ˆ'   # ê +              gsub(/ë/um,'ë').   # 'ë'   # ë +              gsub(/ì/um,'ì').   # 'ì' # ì +              gsub(/í/um,'í').   # '´'  # í +              gsub(/î/um,'î').   # 'î'  # î +              gsub(/ï/um,'ï').   # 'ï'   # ï +              gsub(/ð/um,'ð').   # 'ð'    # ð +              gsub(/ñ/um,'ñ').   # 'ñ' # ñ +              gsub(/ò/um,'ò').   # 'ò' # ò +              gsub(/ó/um,'ó').   # 'ó' # ó +              gsub(/ô/um,'ô').   # 'ô'  # ô +              gsub(/õ/um,'õ').   # 'õ' # õ +              gsub(/ö/um,'ö').   # 'ö'   # ö +              gsub(/ø/um,'ø').   # 'ø' # ø +              gsub(/ù/um,'ú').   # 'ù' # ú +              gsub(/ú/um,'û').   # 'ú' # û +              gsub(/û/um,'ü').   # 'û'  # ü +              gsub(/ü/um,'ý').   # 'ü'   # ý +              gsub(/þ/um,'þ').   # 'þ'  # þ +              gsub(/ÿ/um,'ÿ').   # 'ÿ'   # ÿ +              gsub(/‘/um,'‘').  # '‘'  # ‘ +              gsub(/’/um,'’').  # '’'  # ’ +              gsub(/“/um,'“').  # “    # “ +              gsub(/”/um,'”').  # ”    # ” +              gsub(/–/um,'–').  # –    # – +              gsub(/—/um,'—').  # —    # — +              gsub(/∝/um,'∝').  # ∝     # ∝ +              gsub(/∞/um,'∞').  # ∞    # ∞ +              gsub(/™/um,'™').  # ™    # ™ +              gsub(/✠/um,'✠'). # ✗    # ✠ +              gsub(/ /um,' ').       # space identify +              gsub(/ /um,' ')       # space identify +          end +          dob=if defined? dob.obj +            dob.obj=str +            dob +          elsif dob.is_a?(String) +            str +          end +          dob +        end +      end +      def html(dob='') +        if @sys.locale =~/utf-?8/i # instead ucs for utf8 # String#encode Iñtërnâtiônàlizætiøn +          dob.obj=dob.obj.gsub(/ /u,' ').           # space identify +            gsub(/ /u,' ')           # space identify +        end +      end +      self +    end +    def tidywords(wordlist) +      wordlist_new=[] +      wordlist.each do |x| +        #imperfect solution will not catch all possible cases +        x=x.gsub(/&/,'&') unless x =~/&\S+;/ +        x=x.gsub(/&([A-Z])/,'&\1') +        wordlist_new << x +      end +      wordlist_new +    end +    def markup(dob='') +      wordlist=dob.obj.scan(/&[#0-9a-z]+;|\S+|\n/) #\n needed for tables, check though added 2005w17 +      dob.obj=tidywords(wordlist).join(' ').strip +      unless dob.is==:table +        dob.obj=dob.obj.gsub(/#{Mx[:br_line]}/u,'<br>'). +          gsub(/#{Mx[:br_paragraph]}/u,'<br>'). +          gsub(/#{Mx[:br_line]}|#{Mx[:br_nl]}/,'<br>') +      end +      dob.obj=dob.obj.gsub(/#{Mx[:mk_o]}:name#\S+?#{Mx[:mk_c]}/,''). +        gsub(/#{Mx[:mk_o]}#([a-zA-Z]+)#{Mx[:mk_c]}/,'&\1;'). +        gsub(/#{Mx[:mk_o]}(#[0-9]+)#{Mx[:mk_c]}/,'&\1;'). +        gsub(/(^|#{Mx[:gl_c]}|\s+)<\s+/,'\1< ').gsub(/\s+>(\s+|$)/,' >\1'). +        #gsub(/#{Mx[:fa_emphasis_o]}(.+?)#{Mx[:fa_emphasis_c]}/,'<em>\1</em>'). #reinstate +        gsub(/#{Mx[:fa_bold_o]}(.+?)#{Mx[:fa_bold_c]}/m,'<b>\1</b>'). +        gsub(/#{Mx[:fa_italics_o]}(.+?)#{Mx[:fa_italics_c]}/m,'<i>\1</i>'). +        gsub(/#{Mx[:fa_underscore_o]}(.+?)#{Mx[:fa_underscore_c]}/,'<u>\1</u>'). +        gsub(/#{Mx[:fa_superscript_o]}(.+?)#{Mx[:fa_superscript_c]}/,'<sup>\1</sup>'). +        gsub(/#{Mx[:fa_subscript_o]}(.+?)#{Mx[:fa_subscript_c]}/,'<sub>\1</sub>'). +        gsub(/#{Mx[:fa_insert_o]}(.+?)#{Mx[:fa_insert_c]}/,'<ins>\1</ins>'). +        gsub(/#{Mx[:fa_cite_o]}(.+?)#{Mx[:fa_cite_c]}/,'<cite>\1</cite>'). +        gsub(/#{Mx[:fa_strike_o]}(.+?)#{Mx[:fa_strike_c]}/,'<del>\1</del>'). +        gsub(/#{Mx[:fa_monospace_o]}(.+?)#{Mx[:fa_monospace_c]}/,'<tt>\1</tt>'). +        gsub(/<:pb>\s*/,''). #Fix +        gsub(/<+[-~]#>+/,'') +      if dob.is !=:code +        #embeds a red-bullet image --> +        dob.obj=dob.obj.gsub(/#{Mx[:fa_bold_o]}(.+?)#{Mx[:fa_bold_c]}/,'<b>\1</b>'). +          gsub(/#{Mx[:fa_italics_o]}(.+?)#{Mx[:fa_italics_c]}/,'<i>\1</i>'). +          gsub(/#{Mx[:fa_underscore_o]}(.+?)#{Mx[:fa_underscore_c]}/,'<u>\1</u>'). +          gsub(/#{Mx[:fa_strike_o]}(.+?)#{Mx[:fa_strike_c]}/,'<del>\1</del>') +        dob.obj=dob.obj.gsub(/#{Mx[:br_line]}|#{Mx[:br_nl]}/,'<br>') unless dob.is==:table +        dob.obj=dob.obj.gsub(/#{Mx[:br_page]}\s*/,''). +          gsub(/#{Mx[:br_page_new]}\s*/,''). +          gsub(/#{Mx[:br_page_line]}\s*/,''). +          gsub(/#{Mx[:pa_non_object_no_heading]}|#{Mx[:pa_non_object_dummy_heading]}/,''). +          gsub(/<[-~]#>/,''). +          gsub(/href="#{Xx[:segment]}/m,'href="'). +          gsub(/#{Mx[:lnk_o]}([^#{Mx[:lnk_o]}#{Mx[:lnk_c]}#{Mx[:rel_o]}#{Mx[:rel_c]}]+?)#{Mx[:lnk_c]}#{Mx[:rel_o]}(\.\.\/\S+?)#{Mx[:rel_c]}/, +            '<link xmlns:xl="http://www.w3.org/1999/xlink" xl:type="simple" xl:href="\2">\1</link>'). +          gsub(/#{Mx[:lnk_o]}([^#{Mx[:lnk_o]}#{Mx[:lnk_c]}#{Mx[:rel_o]}#{Mx[:rel_c]}]+?)#{Mx[:lnk_c]}#{Mx[:rel_o]}:(\S+?)#{Mx[:rel_c]}/, +            '<link xmlns:xl="http://www.w3.org/1999/xlink" xl:type="simple" xl:href="../\2">\1</link>'). +          gsub(/#{Mx[:lnk_o]}(.+?)#{Mx[:lnk_c]}#{Mx[:rel_o]}(\S+?)#{Mx[:rel_c]}/, +            '<link xmlns:xl="http://www.w3.org/1999/xlink" xl:type="simple" xl:href="#\2">\1</link>'). +          gsub(/(?:^|[^_\\])#{Mx[:lnk_o]}[ ]*(\S+?\.(?:jpg|png|gif))[ ]+(\d+)x(\d+)(\s+[^}]+)?#{Mx[:lnk_c]}#{Mx[:url_o]}(\S+?)#{Mx[:url_c]}/, +            %{<image xmlns:xl="http://www.w3.org/1999/xlink" xl:type="simple" xl:actuate="onLoad" xl:show="embed" xl:href="#{@md.file.output_path.xml.rel_image}/\\1" width="\\2" height="\\3" />[\\1] \\4}). +          gsub(/(?:^|[^_\\])#{Mx[:lnk_o]}[ ]*(\S+?\.(?:jpg|png|gif))([ ]+[^}]+)?#{Mx[:lnk_c]}#{Mx[:url_o]}(\S+?)#{Mx[:url_c]}/, +            %{<image xmlns:xl="http://www.w3.org/1999/xlink" xl:type="simple" xl:actuate="onLoad" xl:show="embed" xl:href="#{@md.file.output_path.xml.rel_image}/\\1"/>\\1}). +          gsub(/(?:^|[^_\\])#{Mx[:lnk_o]}[ ]*(\S+?\.(?:jpg|png|gif))[ ]+(\d+)x(\d+)(\s+[^}]+)?#{Mx[:lnk_c]}image/, +            %{<image xmlns:xl="http://www.w3.org/1999/xlink" xl:type="simple" xl:actuate="onLoad" xl:show="embed" xl:href="#{@md.file.output_path.xml.rel_image}/\\1" width="\\2" height="\\3" />[\\1] \\4}). +          gsub(/(?:^|[^_\\])#{Mx[:lnk_o]}[ ]*(\S+?\.(?:jpg|png|gif))([ ]+[^}]+)?#{Mx[:lnk_c]}image/, +            %{<image xmlns:xl="http://www.w3.org/1999/xlink" xl:type="simple" xl:actuate="onLoad" xl:show="embed" xl:href="#{@md.file.output_path.xml.rel_image}/\\1"/>\\1}). +          gsub(/#{Mx[:lnk_o]}(.+?)#{Mx[:lnk_c]}#{Mx[:url_o]}(\S+?)#{Mx[:url_c]}/, +            '<link xmlns:xl="http://www.w3.org/1999/xlink" xl:type="simple" xl:href="\2">\1</link>'). #watch, compare html_tune +          gsub(/#{Mx[:url_o]}(\S+?)#{Mx[:url_c]}/, +            %{#{the_url_decoration.xml_open}<link xmlns:xl="http://www.w3.org/1999/xlink" xl:type="simple" xl:href="\\1">\\1</link>#{the_url_decoration.xml_close}}). +          gsub(/#{Mx[:url_o]}_(\S+?)#{Mx[:url_c]}/, +            '<link xmlns:xl="http://www.w3.org/1999/xlink" xl:type="simple" xl:href="\1">\1</link>') #escaped urls not linked, deal with later +      else +        dob.obj=dob.obj.gsub(/</m,'<').gsub(/>/m,'>') +      end +      if dob.of==:block +        dob.obj=dob.obj.gsub(/#{Mx[:gl_bullet]}/,'● ') +      end +      dob.obj=dob.obj.gsub(/#{Mx[:url_o]}([a-zA-Z0-9._-]+\@\S+?\.[a-zA-Z0-9._-]+)#{Mx[:url_c]}/, +          %{#{the_url_decoration.xml_open}\\1#{the_url_decoration.xml_close}}). +        gsub(/#{Dx[:url_o]}/,"#{Dx[:url_o_xml]}"). +        gsub(/#{Dx[:url_c]}/,"#{Dx[:url_c_xml]}"). +        gsub(/ |#{Mx[:nbsp]}/m,' '). +        gsub(/;&([^#]|(?:[^gl][^t]|[^a][^m][^p]|[^n][^b][^s][^p])[^;])/,';&\1') # pattern not to match +      dob +    end +    def markup_light(dob='') +      dob.obj=dob.obj.gsub(/\/\{(.+?)\}\//,'<i>\1</i>'). +        gsub(/[*!]\{(.+?)\}[*!]/,'<b>\1</b>'). +        gsub(/_\{(.+?)\}_/,'<u>\1</u>'). +        gsub(/-\{(.+?)\}-/,'<del>\1</del>'). +        gsub(/<br(\s*\/)?>/,'<br>'). +        gsub(/<:pb>\s*/,''). +        gsub(/<[-~]#>/,''). +        gsub(/(^|#{Mx[:gl_c]}|\s)&\s+/,'\1& '). #sort +        gsub(/&([^;]{1,5})/,'&\1'). #sort, rough estimate, revisit #WATCH found in node not sax +        gsub(/(?:^|[^_\\])#{Mx[:lnk_o]}(\S+?\.(?:png|jpg|gif))[ ]+.+?#{Mx[:lnk_c]}(?:#{Mx[:url_o]}\S+?#{Mx[:url_c]}|image)/, +          "<image.path>#{@md.file.output_path.xml.rel_image}\/\\1</image.path>"). +        gsub(/ |#{Mx[:nbsp]}/,' '). +        gsub(/;&([^#]|(?:[^gl][^t]|[^a][^m][^p]|[^n][^b][^s][^p])[^;])/,';&\1') # pattern not to match +      wordlist=dob.obj.scan(/&[#0-9a-z]+;|\S+|\n/) #\n needed for tables, check though added 2005w17 +      dob.obj=tidywords(wordlist).join(' ').strip +      dob +    end +    def clean(str) +      str=str.gsub(/#{Mx[:gl_o]}(#[0-9]{3})#{Mx[:gl_c]}/u,'&\1;'). +        gsub(/#{Mx[:gl_o]}#([a-z]{2,4})#{Mx[:gl_c]}/u,'&\1;') +    end +    def markup_fictionbook(str='',is='') +      str=str.gsub(/#{Mx[:en_a_o]}([\d+*]+).+?#{Mx[:en_a_c]}/m,'<a xl:href="#footnote\1" type="note">[\1]</a>'). +        gsub(/&/,'&'). #sort +        gsub(/#{Mx[:mk_o]}#([a-zA-Z]+)#{Mx[:mk_c]}/,'&\1;'). +        gsub(/(^|#{Mx[:gl_c]}|\s)&\s+/,'\1& '). #sort +        gsub(/#{Mx[:mk_o]}(#[0-9]+)#{Mx[:mk_c]}/,'&\1;') +      str=str.gsub(/#{Mx[:br_line]}|#{Mx[:br_nl]}/,'<br>') unless is==:table +      str=str.gsub(/#{Mx[:fa_bold_o]}(.+?)#{Mx[:fa_bold_c]}/,'<b>\1</b>'). +        gsub(/#{Mx[:fa_italics_o]}(.+?)#{Mx[:fa_italics_c]}/,'<i>\1</i>'). +        gsub(/#{Mx[:fa_underscore_o]}(.+?)#{Mx[:fa_underscore_c]}/,'<u>\1</u>'). +        gsub(/#{Mx[:fa_superscript_o]}(.+?)#{Mx[:fa_superscript_c]}/,'<sup>\1</sup>'). +        gsub(/#{Mx[:fa_subscript_o]}(.+?)#{Mx[:fa_subscript_c]}/,'<sub>\1</sub>'). +        gsub(/#{Mx[:fa_insert_o]}(.+?)#{Mx[:fa_insert_c]}/,'<ins>\1</ins>'). +        gsub(/#{Mx[:fa_cite_o]}(.+?)#{Mx[:fa_cite_c]}/,'<cite>\1</cite>'). +        gsub(/#{Mx[:fa_strike_o]}(.+?)#{Mx[:fa_strike_c]}/,'<del>\1</del>'). +        gsub(/#{Mx[:fa_monospace_o]}(.+?)#{Mx[:fa_monospace_c]}/,'<tt>\1</tt>'). # tt, kbd +        gsub(/#{Mx[:lnk_o]}\s*(\S+?\.(?:png|jpg|gif)).+?#{Mx[:lnk_c]}(?:#{Mx[:url_o]}\S+?#{Mx[:url_c]}|#{Mx[:rel_o]}\S+?#{Mx[:rel_c]}|image)/m,'<image xl:href="#\1" />'). +        gsub(/#{Mx[:url_o]}(.+?)#{Mx[:url_c]}/,"#{Dx[:url_o]}\\1#{Dx[:url_c]}"). +        gsub(/#{Mx[:mk_o]}:name#(\S+?)#{Mx[:mk_c]}/,'<a name="\1"></a>'). +        gsub(/#{Mx[:gl_bullet]}/m,'● '). #  not available +        gsub(/#{Mx[:nbsp]}/,' '). #  not available +        gsub(/<(p|br)>/,'<\1 />') +      clean(str) +    end +    def markup_docbook(dob='')                                  # work on, initially a copy of fictionbook! +      if dob.is !=:code +        dob.obj=dob.obj.gsub(/#{Mx[:en_a_o]}(\d+)\s*(.+?)#{Mx[:en_a_c]}/m,'<footnote><para><!-- fn\1 -->\2</para></footnote>'). +          gsub(/\\\\/,'</para><para>'). +          gsub(/&/,'&'). #sort +          gsub(/#{Mx[:mk_o]}#([a-zA-Z]+)#{Mx[:mk_c]}/,'&\1;'). +          gsub(/(^|#{Mx[:gl_c]}|\s)&\s+/,'\1& '). #sort +          gsub(/#{Mx[:mk_o]}(#[0-9]+)#{Mx[:mk_c]}/,'&\1;') +        dob.obj=dob.obj.gsub(/#{Mx[:br_line]}|#{Mx[:br_nl]}/,'<br>') unless dob.is==:table +        dob.obj=dob.obj.gsub(/#{Mx[:fa_bold_o]}(.+?)#{Mx[:fa_bold_c]}/,'<b>\1</b>'). +          gsub(/#{Mx[:fa_italics_o]}(.+?)#{Mx[:fa_italics_c]}/,'<i>\1</i>'). +          gsub(/#{Mx[:fa_underscore_o]}(.+?)#{Mx[:fa_underscore_c]}/,'<u>\1</u>'). +          gsub(/#{Mx[:fa_superscript_o]}(.+?)#{Mx[:fa_superscript_c]}/,'<sup>\1</sup>'). +          gsub(/#{Mx[:fa_subscript_o]}(.+?)#{Mx[:fa_subscript_c]}/,'<sub>\1</sub>'). +          gsub(/#{Mx[:fa_insert_o]}(.+?)#{Mx[:fa_insert_c]}/,'<ins>\1</ins>'). +          gsub(/#{Mx[:fa_cite_o]}(.+?)#{Mx[:fa_cite_c]}/,'<cite>\1</cite>'). +          gsub(/#{Mx[:fa_strike_o]}(.+?)#{Mx[:fa_strike_c]}/,'<del>\1</del>'). +          gsub(/#{Mx[:fa_monospace_o]}(.+?)#{Mx[:fa_monospace_c]}/,'<tt>\1</tt>'). # tt, kbd +          gsub(/#{Mx[:lnk_o]}\s*(\S+?)\.(png|jpg|gif).+?#{Mx[:lnk_c]}(?:#{Mx[:url_o]}\S+?#{Mx[:url_c]}|#{Mx[:rel_o]}\S+?#{Mx[:rel_c]}|image)/m, +            %{#{Xx[:split]}:spaces0:<figure id="fig-\\1">\n:spaces1:<title></title>\n:spaces1:<graphic fileref="../../_sisu/image/\\1.\\2" align="center" width="50%"></graphic>\n:spaces0:</figure>#{Xx[:split]}}). # common image location, else use ./images +          gsub(/#{Mx[:lnk_o]}(.+?)#{Mx[:lnk_c]}#{Mx[:url_o]}(.+?)#{Mx[:url_c]}/, +            '<ulink url="\2">\1</ulink>'). +          gsub(/#{Mx[:url_o]}(.+?)#{Mx[:url_c]}/, +            '<ulink url="\1">\1</ulink>'). +          gsub(/#{Mx[:mk_o]}:name#(\S+?)#{Mx[:mk_c]}/,'<a name="\1"></a>'). +          gsub(/#{Mx[:gl_bullet]}/m,'● '). #  not available +          gsub(/#{Mx[:nbsp]}/,' '). #  not available +          gsub(/<(p|br)>/,'<\1 />') +        dob.obj=clean(dob.obj) +      elsif dob.is == :code +        dob.obj=dob.obj.gsub(/&/m,'&'). #sort +          gsub(/</,'<').gsub(/>/,'>') +      else # p dob.is ?? +      end +      dob +    end +    def markup_group(dob='') +      dob.obj=dob.obj.gsub(/</,'<').gsub(/>/,'>'). +        gsub(/<:?br(?:\s+\/)?>/,'<br>'). +        gsub(/<(link xmlns:xl=".+?")>/,'<\1>'). +        gsub(/<(\/link)>/,'<\1>'). +        gsub(/<(\/?en)>/,'<\1>') +      dob +    end +    def markup_block(dob='') +      dob.obj=dob.obj.gsub(/</,'<').gsub(/>/,'>'). +        gsub(/<:?br(?:\s+\/)?>/,'<br>'). +        gsub(/<(link xmlns:xl=".+?")>/,'<\1>'). +        gsub(/<(\/link)>/,'<\1>'). +        gsub(/<(\/?en)>/,'<\1>') +      dob +    end +    def xml_sem_block_paired(matched) # colon depth: many, recurs +      matched=matched.gsub(/\b(au):\{(.+?)\}:\1\b/m,  %{<sem:#{@ab[:au]} depth="many">\\2</sem:#{@ab[:au]}>}). +        gsub(/\b(vol):\{(.+?)\}:\1\b/m, %{<sem:#{@ab[:vol]} depth="many">\\2</sem:#{@ab[:vol]}>}). +        gsub(/\b(pub):\{(.+?)\}:\1\b/m, %{<sem:#{@ab[:pub]} depth="many">\\2</sem:#{@ab[:pub]}>}). +        gsub(/\b(ref):\{(.+?)\}:\1\b/m, %{<sem:#{@ab[:ref]} depth="many">\\2</sem:#{@ab[:ref]}>}). +        gsub(/\b(desc):\{(.+?)\}:\1\b/m,%{<sem:#{@ab[:desc]} depth="many">\\2</sem:#{@ab[:desc]}>}). +        gsub(/\b(conv):\{(.+?)\}:\1\b/m,%{<sem:#{@ab[:conv]} depth="many">\\2</sem:#{@ab[:conv]}>}). +        gsub(/\b(ct):\{(.+?)\}:\1\b/m,  %{<sem:#{@ab[:ct]} depth="many">\\2</sem:#{@ab[:ct]}>}). +        gsub(/\b(cty):\{(.+?)\}:\1\b/m, %{<sem:#{@ab[:cty]} depth="many">\\2</sem:#{@ab[:cty]}>}). +        gsub(/\b(org):\{(.+?)\}:\1\b/m, %{<sem:#{@ab[:org]} depth="many">\\2</sem:#{@ab[:org]}>}). +        gsub(/\b(dt):\{(.+?)\}:\1\b/m,  %{<sem:#{@ab[:dt]} depth="many">\\2</sem:#{@ab[:dt]}>}). +        gsub(/\b(n):\{(.+?)\}:\1\b/m,   %{<sem:#{@ab[:n]} depth="many">\\2</sem:#{@ab[:n]}>}). +        gsub(/([a-z]+(?:[_:.][a-z]+)*)(?::\{(.+?)\}:\1)/m,'<sem:\1 depth="many">\2</sem:\1>') +    end +    def xml_semantic_tags(dob) +      if @md.sem_tag +        dob.obj.gsub!(/([a-z]+(?:[_:.][a-z]+)*)(?::\{(.+?)\}:\1)/m) {|c| xml_sem_block_paired(c) } +        dob.obj.gsub!(/([a-z]+(?:[_:.][a-z]+)*)(?::\{(.+?)\}:\1)/m) {|c| xml_sem_block_paired(c) } +        dob.obj.gsub!(/([a-z]+(?:[_:.][a-z]+)*)(?::\{(.+?)\}:\1)/m) {|c| xml_sem_block_paired(c) } +        dob.obj=dob.obj.gsub(/:\{(.+?)\}:au\b/m,             %{<sem:#{@ab[:au]} depth="one">\\1</sem:#{@ab[:au]}>}). +          gsub(/:\{(.+?)\}:n\b/m,              %{<sem:#{@ab[:n]} depth="one">\\1</sem:#{@ab[:n]}>}). +          gsub(/:\{(.+?)\}:ti\b/m,             %{<sem:#{@ab[:ti]} depth="one">\\1</sem:#{@ab[:ti]}>}). +          gsub(/:\{(.+?)\}:ref\b/m,            %{<sem:#{@ab[:ref]} depth="one">\\1</sem:#{@ab[:ref]}>}). +          gsub(/:\{(.+?)\}:desc\b/m,           %{<sem:#{@ab[:desc]} depth="one">\\1</sem:#{@ab[:desc]}>}). +          gsub(/:\{(.+?)\}:cty\b/m,            %{<sem:#{@ab[:cty]} depth="one">\\1</sem:#{@ab[:cty]}>}). +          gsub(/:\{(.+?)\}:org\b/m,            %{<sem:#{@ab[:org]} depth="one">\\1</sem:#{@ab[:org]}>}). +          gsub(/:\{(.+?)\}:([a-z]+(?:[_:.][a-z]+)*)/m,'<sem:\2 depth="one">\1</sem:\2>'). +          gsub(/;\{([^}]+(?![;]))\};ti\b/m,    %{<sem:#{@ab[:ti]} depth="zero">\\1</sem:#{@ab[:ti]}>}). +          gsub(/;\{([^}]+(?![;]))\};qt\b/m,    %{<sem:#{@ab[:qt]} depth="zero">\\1</sem:#{@ab[:qt]}>}). +          gsub(/;\{([^}]+(?![;]))\};ref\b/m,   %{<sem:#{@ab[:ref]} depth="zero">\\1</sem:#{@ab[:ref]}>}). +          gsub(/;\{([^}]+(?![;]))\};ed\b/m,    %{<sem:#{@ab[:ed]} depth="zero">\\1</sem:#{@ab[:ed]}>}). +          gsub(/;\{([^}]+(?![;]))\};v\b/m,     %{<sem:#{@ab[:v]} depth="zero">\\1</sem:#{@ab[:v]}>}). +          gsub(/;\{([^}]+(?![;]))\};desc\b/m,  %{<sem:#{@ab[:desc]} depth="zero">\\1</sem:#{@ab[:desc]}>}). +          gsub(/;\{([^}]+(?![;]))\};def\b/m,   %{<sem:#{@ab[:def]} depth="zero">\\1</sem:#{@ab[:def]}>}). +          gsub(/;\{([^}]+(?![;]))\};trans\b/m, %{<sem:#{@ab[:trans]} depth="zero">\\1</sem:#{@ab[:trans]}>}). +          gsub(/;\{([^}]+(?![;]))\};y\b/m,     %{<sem:#{@ab[:y]} depth="zero">\\1</sem:#{@ab[:y]}>}). +          gsub(/;\{([^}]+(?![;]))\};ab\b/m,    %{<sem:#{@ab[:ab]} depth="zero">\\1</sem:#{@ab[:ab]}>}). +          gsub(/;\{([^}]+(?![;]))\};pg\b/m,    %{<sem:#{@ab[:pg]} depth="zero">\\1</sem:#{@ab[:pg]}>}). +          gsub(/;\{([^}]+(?![;]))\};fn?\b/m,   %{<sem:#{@ab[:fn]} depth="zero">\\1</sem:#{@ab[:fn]}>}). +          gsub(/;\{([^}]+(?![;]))\};mn?\b/m,   %{<sem:#{@ab[:mn]} depth="zero">\\1</sem:#{@ab[:mn]}>}). +          gsub(/;\{([^}]+(?![;]))\};ln?\b/m,   %{<sem:#{@ab[:ln]} depth="zero">\\1</sem:#{@ab[:ln]}>}). +          gsub(/;\{([^}]+(?![;]))\};in\b/m,    %{<sem:#{@ab[:in]} depth="zero">\\1</sem:#{@ab[:in]}>}). +          gsub(/;\{([^}]+(?![;]))\};uni\b/m,   %{<sem:#{@ab[:uni]} depth="zero">\\1</sem:#{@ab[:uni]}>}). +          gsub(/;\{([^}]+(?![;]))\};fac\b/m,   %{<sem:#{@ab[:fac]} depth="zero">\\1</sem:#{@ab[:fac]}>}). +          gsub(/;\{([^}]+(?![;]))\};inst\b/m,  %{<sem:#{@ab[:inst]} depth="zero">\\1</sem:#{@ab[:inst]}>}). +          gsub(/;\{([^}]+(?![;]))\};dept\b/m,  %{<sem:#{@ab[:dpt]} depth="zero">\\1</sem:#{@ab[:dept]}>}). +          gsub(/;\{([^}]+(?![;]))\};org\b/m,   %{<sem:#{@ab[:org]} depth="zero">\\1</sem:#{@ab[:org]}>}). +          gsub(/;\{([^}]+(?![;]))\};com?\b/m,  %{<sem:#{@ab[:com]} depth="zero">\\1</sem:#{@ab[:com]}>}). +          gsub(/;\{([^}]+(?![;]))\};cty\b/m,   %{<sem:#{@ab[:cty]} depth="zero">\\1</sem:#{@ab[:cty]}>}). +          gsub(/;\{([^}]+(?![;]))\};([a-z]+(?:[_:.][a-z]+)*)/m,'<sem:\2 depth="zero">\1</sem:\2>') +      end +      dob +    end +  end +end +module SiSU_XML_Tags #Format +  require_relative 'dp'                                 # dp.rb +    include SiSU_Param +  class RDF +    include SiSU_Parts_JSON +    def initialize(md='',seg_name=[],tracker=0) +      @full_title=@subtitle=@author=@subject=@description=@publisher=@contributor=@date=@date_created=@date_issued=@date_available=@date_valid=@date_modified=@type=@format=@identifier=@source=@language=@relation=@coverage=@rights=@copyright=@owner=@keywords='' +      @md=md +      @rdfurl=%{  rdf:about="http://www.jus.uio.no/lm/toc"\n} +      if defined? @md.title.full \ +      and @md.title.full                          # DublinCore 1 - title +        @rdf_title=%{    dc.title="#{seg_name}#{@md.title.full}"\n} +        @full_title=%{  <meta name="dc.title" content="#{@md.title.full}" />\n} +      end +      if defined? @md.creator.author \ +      and @md.creator.author=~/\S+/                                            # DublinCore 2 - creator/author (author) +        @rdf_author=%{    dc.author="#{@md.creator.author}"\n} +        content=meta_content_clean(@md.creator.author) +        @author=%{  <meta name="dc.author" content="#{content}" />\n} +      end +      if defined? @md.publisher \ +      and @md.publisher                                                        # DublinCore 5 - publisher (current copy published by) +        @rdf_publisher=%{    dc.publisher="#{@md.publisher}"\n} +        content=meta_content_clean(@md.publisher) +        @publisher=%{  <meta name="dc.publisher" content="#{content}" />\n} +      end +      if defined? @md.creator.contributor \ +      and @md.creator.contributor=~/\S+/                                      # DublinCore 6 - contributor +        @rdf_contributor=%{    dc.contributor="#{@md.creator.contributor}"\n} +        content=meta_content_clean(@md.creator.contributor) +        @contributor=%{  <meta name="dc.contributor" content="#{content}" />\n} +      end +      if defined? @md.date.published \ +      and @md.date.published=~/\S+/                                           # DublinCore 7 - date year-mm-dd +        @rdf_date=%{    dc.date="#{@md.date.published}"\n} +        @date=%{  <meta name="dc.date" content="#{@md.date.published}" #{@md.date_scheme} />\n} # fix @md.date_scheme +      end +      if defined? @md.date.created \ +      and @md.date.created=~/\S+/                                             # DublinCore 7 - date.created year-mm-dd +        @rdf_date_created=%{    dc.date.created="#{@md.date.created}"\n} +        @date_created=%{  <meta name="dc.date.created" content="#{@md.date.created}" #{@md.date_scheme} />\n} +      end +      if defined? @md.date.issued \ +      and @md.date.issued=~/\S+/                                              # DublinCore 7 - date.issued year-mm-dd +        @rdf_date_issued=%{    dc.date.issued="#{@md.date.issued}"\n} +        @date_issued=%{  <meta name="dc.date.issued" content="#{@md.date.issued}" #{@md.date_scheme} />\n} +      end +      if defined? @md.date.available \ +      and @md.date.available=~/\S+/                                           # DublinCore 7 - date.available year-mm-dd +        @rdf_date_available=%{    dc.date.available="#{@md.date.available}"\n} +        @date_available=%{  <meta name="dc.date.available" content="#{@md.date.available}" #{@md.date_scheme} />\n} +      end +      if defined? @md.date.valid \ +      and @md.date.valid=~/\S+/                                               # DublinCore 7 - date.valid year-mm-dd +        @rdf_date_valid=%{    dc.date.valid="#{@md.date.valid}"\n} +        @date_valid=%{  <meta name="dc.date.valid" content="#{@md.date.valid}" #{@md.date_scheme} />\n} +      end +      if defined? @md.date.modified \ +      and @md.date.modified=~/\S+/                                            # DublinCore 7 - date.modified year-mm-dd +        @rdf_date_modified=%{    dc.date.modified="#{@md.date.modified}"\n} +        @date_modified=%{  <meta name="dc.date.modified" content="#{@md.date.modified}" #{@md.date_scheme} />\n} +      end +      if defined? @md.rights.all \ +      and @md.rights.all                                                      # DublinCore 15 - rights +        @rdf_rights=%{    dc.rights="#{@md.rights.all}"\n} +        content=meta_content_clean(@md.rights.all) +        @rights=%{  <meta name="dc.rights" content="#{content}" />\n} +      end +      if defined? @md.classify.subject \ +      and @md.classify.subject=~/\S+/                                          # DublinCore 3 - subject (us library of congress, eric or udc, or schema???) +        @rdf_subject=%{    dc.subject="#{@md.classify.subject}"\n} +        content=meta_content_clean(@md.classify.subject) +        @subject=%{  <meta name="dc.subject" content="#{content}" />\n} +      end +      if defined? @md.notes.description \ +      and @md.notes.description=~/\S+/                                         # DublinCore 4 - description +        @rdf_description=%{    dc.description="#{@md.notes.description}"\n} +        content=meta_content_clean(@md.notes.description) +        @description=%{  <meta name="dc.description" content="#{content}" />\n} +      end +      if defined? @md.notes.coverage \ +      and @md.notes.coverage=~/\S+/                                            # DublinCore 14 - coverage +        @rdf_coverage=%{    dc.coverage="#{@md.notes.coverage}"\n} +        content=meta_content_clean(@md.notes.coverage) +        @coverage=%{  <meta name="dc.coverage" content="#{content}" />\n} +      end +      if defined? @md.notes.relation \ +      and @md.notes.relation=~/\S+/                                            # DublinCore 13 - relation +        @rdf_relation=%{    dc.relation="#{@md.notes.relation}"\n} +        content=meta_content_clean(@md.notes.relation) +        @relation=%{  <meta name="dc.relation" content="#{content}" />\n} +      end +      if defined? @md.notes.type \ +      and @md.notes.type                                                       # DublinCore 8 - type (genre eg. report, convention etc) +        @rdf_type=%{    dc.type="#{@md.notes.type}"\n} +        content=meta_content_clean(@md.notes.type) +        @type=%{  <meta name="dc.type" content="#{content}" />\n} +      end +      if defined? @md.notes.format \ +      and @md.notes.format=~/\S+/                                              # DublinCore 9 - format (use your mime type) +        @rdf_format=%{    dc.format="#{@md.notes.format}"\n} +        content=meta_content_clean(@md.notes.format) +        @format=%{  <meta name="dc.format" content="#{content}" />\n} +      end +      #if defined? @md.identifier.sisupod \ +      #and @md.identifier.sisupod=~/\S+/                                       # DublinCore 10 - identifier (your identifier, could use urn which is free) +      #  @rdf_identifier=%{    dc.identifier="#{@md.identifier.sisupod}"\n} +      #  content=meta_content_clean(@md.identifier.sisupod) +      #  @identifier=%{  <meta name="dc.identifier" content="#{content}" />\n} +      #end +      if defined? @md.original.source \ +      and @md.original.source=~/\S+/                                           # DublinCore 11 - source (document source) +        @rdf_source=%{    dc.source="#{@md.original.source}"\n} +        content=meta_content_clean(@md.original.source) +        @source=%{  <meta name="dc.source" content="#{content}" />\n} +      end +      if defined? @md.title.language \ +      and @md.title.language=~/\S+/                                            # DublinCore 12 - language (English) +        @rdf_language=%{    dc.language="#{@md.title.language}"\n} +        @language=%{  <meta name="dc.language" content="#{@md.title.language}" />\n} +      end +      if defined? @md.original.language \ +      and @md.original.language=~/\S+/ +        @rdf_language_original=%{    dc.language="#{@md.original.language}"\n} +        @language_original=%{  <meta name="dc.language" content="#{@md.original.language}" />\n} +      end +      content=meta_content_clean(@md.keywords) +      @keywords=%{  <meta name="keywords" content="#{content}" />\n} if @md.keywords +    end +    def meta_content_clean(content='') +      content=if not content.nil? +        content=content.tr('"',"'"). +           gsub(/&/,'&') +        content=SiSU_XML_Munge::Trans.new(@md).char_enc.utf8(content) +      else content +      end +    end +    def rdfseg #segHead +      rdftoc +    end +    def comment_xml(extra='') +      generator="Generated by: #{@md.project_details.project} #{@md.project_details.version} of #{@md.project_details.date_stamp} (#{@md.project_details.date})"  if @md.project_details.version +      lastdone="Last Generated on: #{Time.now}" +      rubyv="Ruby version: #{@md.ruby_version}" +      sc=if @md.sc_info +        "Source file: #{@md.sc_filename} version: #{@md.sc_number} of: #{@md.sc_date}" +      else '' +      end +      if extra.empty? +<<WOK +<!-- Document processing information: +     * #{generator} +     * #{rubyv} +     * #{sc} +     * #{lastdone} +     * SiSU http://www.jus.uio.no/sisu +--> +WOK +     else +<<WOK +<!-- Document processing information: +     * #{extra} +     * #{generator} +     * #{rubyv} +     * #{sc} +     * #{lastdone} +     * SiSU http://www.jus.uio.no/sisu +--> +WOK +      end +    end +    def comment_xml_sax +      desc='SiSU XML, SAX type representation' +      comment_xml(desc) +    end +    def comment_xml_node +      desc='SiSU XML, Node type representation' +      comment_xml(desc) +    end +    def comment_xml_dom +      desc='SiSU XML, DOM type representation' +      comment_xml(desc) +    end +    def metatag_html #values strung together, because some empty, and resulting output (line breaks) is much better +<<WOK +#{@full_title}#{@subtitle}#{@author}#{@subject}#{@description}#{@publisher}#{@contributor}#{@date}#{@date_created}#{@date_issued}#{@date_available}#{@date_valid}#{@date_modified}#{@type}#{@format}#{@identifier}#{@source}#{@language}#{@relation}#{@coverage}#{@rights}#{@copyright}#{@owner} +#{SiSU_Proj_XML::Bits.new.txt_generator} +#{the_png.ico} +WOK +    end +  end +end +module SiSU_JSON_Shared +  require_relative 'xhtml_table'                        # xhtml_table.rb +  class TableJSON < SiSU_XHTML_Table::TableXHTML +  end +end +__END__ +#+END_SRC + +* json_format.rb + +#+BEGIN_SRC ruby  :tangle "../lib/sisu/json_format.rb" +# <<sisu_document_header>> +module SiSU_JSON_Format +  require_relative 'dp'                                 # dp.rb +  require_relative 'json_parts'                         # json_parts.rb +  include SiSU_Param +  class ParagraphNumber +    def initialize(md,paranum) +      @md=md +      @paranum=(paranum \ +      ? (/(\d+)/m.match(paranum)[1]) +      : nil) +    end +    def display +      p_num_display=if @paranum +        @paranum.gsub(/(\d+)/, +        '<font size="1" color="#777777">' + +        '  \1</font>') +      else '' +      end +      p_num_display +    end +    def name +      p_num_name=@paranum.gsub(/(\d+)/,'<a name="\1"></a>') +      p_num_name +    end +    def goto +      p_num_goto=@paranum.gsub(/(\d+)/,'<a href="#\1">') +      p_num_goto +    end +  end +  class HeadInformation +    include SiSU_Parts_JSON +    def initialize #dc rdf +      @full_title=@subtitle=@author=@subject=@description=@publisher=@contributor=@date=@type=@format=@identifier=@source=@language=@relation=@coverage=@rights=@copyright=@owner=@keywords='' +      @md=@@md +      # DublinCore 1 - title +      @rdfurl=%{  rdf:about="http://www.jus.uio.no/lm/toc"\n} +      if defined? @md.title.full \ +      and @md.title.full                                                      # DublinCore 1 - title +        @rdf_title=%{    dc.title="#{seg_name}#{@md.title.full}"\n} +        @full_title=%{<meta name="dc.title" content="#{seg_name}#{@md.title.full}" />\n} +      end +      if defined? @md.creator.author \ +      and @md.creator.author                                                  # DublinCore 2 - creator/author (author) +        @rdf_author=%{    dc.author="#{@md.creator.author}"\n} +        @author=%{<meta name="dc.author" content="#{@md.creator.author}" />\n} +      end +      if defined? @md.classify.subject \ +      and @md.classify.subject=~/\S+/                                          # DublinCore 3 - subject (us library of congress, eric or udc, or schema???) +        @rdf_subject=%{    dc.subject="#{@md.classify.subject}"\n} +        @subject=%{<meta name="dc.subject" content="#{@md.classify.subject}" />\n} +      end +      if defined? @md.notes.description \ +      and @md.notes.description=~/\S+/                                        # DublinCore 4 - description +        @rdf_description=%{    dc.description="#{@md.notes.description}"\n} +        @description=%{<meta name="dc.description" content="#{@md.notes.description}" />\n} +      end +      if defined? @md.publisher \ +      and @md.publisher=~/\S+/                                                # DublinCore 5 - publisher (current copy published by) +        @rdf_publisher=%{    dc.publisher="#{@md.publisher}"\n} +        @publisher=%{<meta name="dc.publisher" content="#{@md.publisher}" />\n} +      end +      if defined? @md.creator.contributor \ +      and @md.creator.contributor=~/\S+/                                      # DublinCore 6 - contributor +        @rdf_contributor=%{    dc.contributor="#{@md.creator.contributor}"\n} +        @contributor=%{<meta name="dc.contributor" content="#{@md.creator.contributor}" />\n} +      end +      if defined? @md.date.published \ +      and @md.date.published                                                  # DublinCore 7 - date year-mm-dd +        @rdf_date=%{    dc.date="#{@md.date.published}"\n} +        @date=%{<meta name="dc.date" content="#{@md.date.published}" #{@md.date_scheme} />\n} +      end +      if defined? @md.date.created \ +      and @md.date.created                                                    # DublinCore 7 - date.created year-mm-dd +        @rdf_date_created=%{    dc.date.created="#{@md.date.created}"\n} +        @date_created=%{<meta name="dc.date.created" content="#{@md.date.created}" #{@md.date_created_scheme} />\n} +      end +      if defined? @md.date.issued \ +      and @md.date.issued                                                      # DublinCore 7 - date.issued year-mm-dd +        @rdf_date_issued=%{    dc.date.issued="#{@md.date.issued}"\n} +        @date_issued=%{<meta name="dc.date.issued" content="#{@md.date.issued}" #{@md.date_issued_scheme} />\n} +      end +      if defined? @md.date.available \ +      and @md.date.available                                                  # DublinCore 7 - date.available year-mm-dd +        @rdf_date_available=%{    dc.date.available="#{@md.date.available}"\n} +        @date_available=%{<meta name="dc.date.available" content="#{@md.date.available}" #{@md.date_available_scheme} />\n} +      end +      if defined? @md.date.valid \ +      and @md.date.valid                                                      # DublinCore 7 - date.valid year-mm-dd +        @rdf_date_valid=%{    dc.date.valid="#{@md.date.valid}"\n} +        @date_valid=%{<meta name="dc.date.valid" content="#{@md.date.valid}" #{@md.date_valid_scheme} />\n} +      end +      if defined? @md.date.modified \ +      and @md.date.modified                                                   # DublinCore 7 - date.modified year-mm-dd +        @rdf_date_modified=%{    dc.date.modified="#{@md.date.modified}"\n} +        @date_modified=%{<meta name="dc.date.modified" content="#{@md.date.modified}" #{@md.date_modified_scheme} />\n} +      end +      if defined? @md.notes.coverage \ +      and @md.notes.coverage=~/\S+/                                        # DublinCore 14 - coverage +        @rdf_coverage=%{    dc.coverage="#{@md.notes.coverage}"\n} +        @coverage=%{<meta name="dc.coverage" content="#{@md.notes.coverage}" />\n} +      end +      if defined? @md.notes.relation \ +      and @md.notes.relation=~/\S+/                                         # DublinCore 13 - relation +        @rdf_relation=%{    dc.relation="#{@md.notes.relation}"\n} +        @relation=%{<meta name="dc.relation" content="#{@md.notes.relation}" />\n} +      end +      if defined? @md.notes.type \ +      and @md.notes.type                                                            # DublinCore 8 - type (genre eg. report, convention etc) +        @rdf_type=%{    dc.type="#{@md.notes.type}"\n} +        @type=%{<meta name="dc.type" content="#{@md.notes.type}" />\n} +      end +      if defined? @md.notes.format \ +      and @md.notes.format=~/\S+/                                              # DublinCore 9 - format (use your mime type) +        @rdf_format=%{    dc.format="#{@md.notes.format}"\n} +        @format=%{<meta name="dc.format" content="#{@md.notes.format}" />\n} +      end +      #if defined? @md.identifier.sisupod \ +      #and @md.identifier.sisupod=~/\S+/                                       # DublinCore 10 - identifier (your identifier, could use urn which is free) +      #  @rdf_identifier=%{    dc.identifier="#{@md.identifier.sisupod}"\n} +      #  @identifier=%{<meta name="dc.identifier" content="#{@md.identifier.sisupod}" />\n} +      #end +      if defined? @md.original.source \ +      and @md.original.source=~/\S+/                                           # DublinCore 11 - source (document source) +        @rdf_source=%{    dc.source="#{@md.original.source}"\n} +        @source=%{<meta name="dc.source" content="#{@md.source}" />\n} +      end +      if defined? @md.original.language \ +      and @md.original.language=~/\S+/                                         # DublinCore 12 - language (English) +        @rdf_language=%{    dc.language="#{@md.original.title}"\n} +        @language=%{<meta name="dc.language" content="#{@md.language[:name]}" />\n} +      end +      if defined? @md.rights.all \ +      and @md.rights.all=~/\S+/                                               # DublinCore 15 - rights +        rights=meta_content_clean(@md.rights.all) +        copyright=meta_content_clean(@md.rights.copyright.all) +        @rdf_rights=%{    dc.rights="#{rights}"\n} +        @rights=%{<meta name="dc.rights" content="#{rights}" />\n} +      end +      @copyright=%{<meta name="copyright" content="#{copyright}" />\n} \ +        if @md.rights.copyright.all # possibly redundant see dc.rights +      @owner=%{<meta name="owner" content="#{@md.owner}" />\n} if @md.owner +      @keywords=%{<meta name="keywords" content="#{@md.keywords}" />\n} if @md.keywords +      @index='index' +    end +    def meta_content_clean(content='') +      content=if not content.nil? +        content=content.tr('"',"'"). +           gsub(/&/,'&') +        content=SiSU_XML_Munge::Trans.new(@md).char_enc.utf8(content) +      else content +      end +    end +    def table_close +      '</font> </td></tr></table>' +    end +    def toc_head +      <<WOK +<html> +<head> +<title>#{@md.html_title}</title> +<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" +         xmlns:dc="http://purl.org/dc/elements/1.1/"> + <rdf:Description +#{@rdfurl} +#{@rdf_title} +#{@rdf_subtitle} +#{@rdf_author} +#{@rdf_subject} +#{@rdf_description} +#{@rdf_publisher} +#{@rdf_contributor} +#{@rdf_date} +#{@rdf_date_created} +#{@rdf_date_issued} +#{@rdf_date_available} +#{@rdf_date_valid} +#{@rdf_date_modified} +#{@rdf_type} +#{@rdf_format} +#{@rdf_identifier} +#{@rdf_source} +#{@rdf_language} +#{@rdf_relation} +#{@rdf_coverage} +#{@rdf_rights} +  /> +</rdf:RDF> +#{@full_title} +#{@author} +#{@subject} +#{@description} +#{@publisher} +#{@contributor} +#{@date} +#{@date_created} +#{@date_issued} +#{@date_available} +#{@date_valid} +#{@date_modified} +#{@type} +#{@format} +#{@identifier} +#{@source} +#{@language} +#{@relation} +#{@coverage} +#{@rights} +#{@copyright} +#{@owner} +#{@png.ico} +#{@txt.generator} +#{@js.head} +\n</head> +#{@color.body} +#{@font.css_table_file} +<a name="top"></a> +<a name="up"></a> +<a name="start"></a> +#{@js.top} +WOK +    end +  end +  class ParagraphNumber +    def initialize(md,ocn) +      @md,@ocn=md,ocn.to_s +      @ocn ||='' +    end +    def ocn_display +      @make=SiSU_Env::ProcessingSettings.new(@md) +      if @make.build.ocn? +        ocn_class='ocn' +        if @ocn.to_i==0 +          @ocn.gsub(/^(\d+|)$/, +            %{<label class="#{ocn_class}"><a name="#{@ocn}"> </a></label>}) +        else +          @ocn.gsub(/^(\d+|)$/, +            %{<label class="#{ocn_class}"><a name="#{@ocn}">\\1</a></label>}) +        end +      else +        ocn_class='ocn_off' +        @ocn.gsub(/^(\d+|)$/, +          %{<label class="#{ocn_class}"> </label>}) +      end +    end +    def name +      %{<a name="#{@ocn}"></a>} +    end +    def id #w3c? "tidy" complains about numbers as identifiers ! annoying +      %{id="o#{@ocn}"} +    end +    def goto +      %{<a href="##{@ocn}">} +    end +  end +  class FormatTextObject +    include SiSU_Parts_JSON +    attr_accessor :md,:dob,:txt,:ocn,:format,:table,:link,:linkname,:paranum,:p_num,:headname,:banner,:url +    def initialize(md,t_o) +      @md,@t_o=md,t_o +      if t_o.class.inspect =~/Object/ +        @txt=if defined? t_o.obj; t_o.obj +        else nil +        end +        @ocn=if defined? t_o.ocn; t_o.ocn.to_s +        else nil +        end +        @headname=if t_o.is==:heading and defined? t_o.name; t_o.name +        else nil +        end +      else +        if @md.opt.act[:maintenance][:set]==:on +          p __FILE__ << ':' << __LINE__.to_s +          p t_o.class +          p caller +        end +      end +      if defined? @t_o.ocn +        ocn=((@t_o.ocn.to_s =~/\d+/) ? @t_o.ocn : nil) +        @p_num=ParagraphNumber.new(@md,ocn) +      end +      if @format and not @format.empty? +        if @format=~/^\d:(\S+)/ #need more reliable marker #if @format =~ /#{Rx[:lv]}/ +          headname=$1 #format[/\d~(\S+)/m,1] +          @headname=if headname =~/^[a-zA-Z]/; %{<a name="#{headname}" id="#{headname}"></a>} #consider: h_#{headname} +          else %{<a name="h#{headname}" id="h#{headname}"></a>} +          end +        end +      end +      @dob=t_o if defined? t_o.is +    end +    def para +      para_form_css('p','norm') +    end +    def code +      para_form_css('p','code') +    end +    def center +      para_form_css('p','center') +    end +    def bold +      para_form_css('p','bold') +    end +    def bullet +      para_form_css('li','bullet') +    end +    def format(tag,attrib) +      para_form_css(tag,attrib) +    end +    def heading_normal(tag,attrib) +      %{ +<div class="substance"> +  #{@p_num.ocn_display} +  <#{tag} class="#{attrib}" #{@p_num.id}>#{@p_num.name} +    #{@headname}#{@txt} +  </#{tag}> +</div> +} +    end +    def heading_body +      heading_normal('p','norm') +    end +    def heading_body0 +      heading_normal('h1','norm') +    end +    def heading_body1 +      heading_normal('h1','norm') +    end +    def heading_body2 +      heading_normal('h2','norm') +    end +    def heading_body3 +      heading_normal('h3','norm') +    end +    def heading_body4 +      heading_normal('h4','norm') +    end +    def heading_body5 +      heading_normal('h5','norm') +    end +    def heading_body6 +      heading_normal('h6','norm') +    end +    def heading_body7 +      heading_normal('h7','norm') +    end +    def title_header(tag,attrib) +      %{ +<div class="content"> +<#{tag} class="#{attrib}"> +    #{@txt} +  </#{tag}> +</div> +} +    end +    def title_header1 +      title_header('h1','tiny') +    end +    def title_header2 +      title_header('h2','tiny') +    end +    def title_header3 +      title_header('h3','tiny') +    end +    def title_header4 +      '' +    end +    def dl #check :trailer +      "<dl><b>#{@txt}</b> #{@trailer}</dl>" +    end +    def table_css_end      #<!TZ!> +      '</table> +    </p> +  </div>' +    end +    def gsub_body +#fix +      @txt=case @txt +      when /^\s*\((i+|iv|v|vi+|ix|x|xi+)\)/ +        @txt.gsub(/^\((i+|iv|v|vi+|ix|x|xi+)\)/,'<b>(\1)</b>'). +          gsub(/^(#{Mx[:pa_o]}i[1-9]#{Mx[:pa_c]})\s*\((i+|iv|v|vi+|ix|x|xi+)\)/,'\1<b>(\2)</b>') +      when /^\s*\(?(\d|[a-z])+\)/ +        @txt.gsub(/^\((\d+|[a-z])+\)/,'<b>(\1)</b>'). +          gsub(/^(#{Mx[:pa_o]}i[1-9]#{Mx[:pa_c]})\s*\((\d+|[a-z])+\)/,'\1<b>(\2)</b>') +      when /^\s*\d{1,3}\.\s/ +        @txt.gsub(/^\s*(\d+\.)/,'<b>\1</b>') +      when /^\s*[A-Z]\.\s/ +        @txt.gsub(/^\s*([A-Z]\.)/,'<b>\1</b>') +      else @txt +      end +    end +    def bold_para +      %{#{the_margin.txt_0} +  <p class="bold"> +    #{@txt} +  </p> +#{the_margin.num_css} +      +#{the_table_close}} +    end +    def bold_header +      @txt=@txt.gsub(/[1-9]~(\S+)/,'<a name="\1"></a>'). +        gsub(/[1-9]~/,'') +      %{<p class="bold"> +    #{@txt} +  </p> +#{the_margin.num_css} +      +#{the_table_close}} +    end +    def toc_head_copy_at +      %{<p class="center">#{@txt}</p>\n} +    end +    def center +      %{<p class="center">#{@txt}</p>\n} +    end +    def bold +      %{<p class="bold">#{@txt}</p>\n} +    end +    def center_bold +      %{<p class="centerbold">#{@txt}</p>\n} +    end +  end +end +__END__ +#+END_SRC + +* json_persist.rb + +#+BEGIN_SRC ruby  :tangle "../lib/sisu/json_persist.rb" +# <<sisu_document_header>> +module SiSU_JSON_Persist +  class Persist +    @@persist=nil +    attr_accessor :head,:toc,:body,:tail,:open,:close,:sc,:endnotes,:book_idx,:metadata +    #attr_accessor :head,:body,:tail,:open,:close,:sc +#@@odf={ body: [], head: [], toc: [],  metadata: [], tail: [], book_idx: [], endnotes: [] } +    def initialize(args=nil) +      @@persist=args=(args ? args : (@@persist || persist_init_hash_values)) +      @head=args[:head] +      @toc=args[:toc] +      @body=args[:body] +      @tail=args[:tail] +      @open=args[:open] +      @close=args[:close] +      @sc=args[:sc] +      @endnotes=args[:endnotes] +      @book_idx=args[:book_idx] +      @metadata=args[:metadata] +    end +    def head +      @head +    end +    def toc +      @toc +    end +    def body +      @body +    end +    def tail +      @tail +    end +    def open +      @open +    end +    def close +      @close +    end +    def sc +      @sc +    end +    def endnotes +      @endnotes +    end +    def book_idx +      @book_idx +    end +    def metadata +      @metadata +    end +    def persist_init_hash_values +      { +        head: [], +        toc: [], +        body: [], +        tail: [], +        open: [], +        close: [], +        sc: [], +        endnotes: [], +        book_idx: [], +        metadata: [], +      } +    end +    def persist_init +      @@persist=nil +      Persist.new(persist_init_hash_values) +    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 +    json + +  - 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 diff --git a/org/manpage.org b/org/manpage.org new file mode 100644 index 00000000..67c3efc9 --- /dev/null +++ b/org/manpage.org @@ -0,0 +1,436 @@ +-*- mode: org -*- +#+TITLE:       sisu manpage +#+DESCRIPTION: documents - structuring, various output representations & search +#+FILETAGS:    :sisu:manpage: +#+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 + +* manpage.rb + +#+BEGIN_SRC ruby  :tangle "../lib/sisu/manpage.rb" +# <<sisu_document_header>> +module SiSU_Manpage +  require_relative 'ao'                                 # ao.rb +  require_relative 'se'                                 # se.rb +    include SiSU_Env +  include SiSU_Param +  require_relative 'manpage_format'                     # manpage_format.rb +    include SiSU_ManpageFormat +  require_relative 'shared_metadata'                    # shared_metadata.rb +  require_relative 'generic_parts'                      # generic_parts.rb +  require_relative 'txt_read'                           # txt_read.rb +  require_relative 'txt_output'                         # txt_output.rb +  require_relative 'txt_shared'                         # txt_shared.rb +  @@alt_id_count,@@alt_id_count=0,0 +  @@tablefoot='' +  class Source +    include SiSU_Txt_Read +    def initialize(opt) +      @opt=opt +      if @opt.fns =~/(.+?)\.(?:-|ssm\.)?sst$/ +        @@notes=:end +      else +        puts "#{sf} not a processed file type" +      end +    end +    def read +      begin +        md=SiSU_Param::Parameters.new(@opt).get +        specific={ +          description:     'Manpage', +          output_path:     md.file.output_path.manpage.dir, +          output_file:     md.file.base_filename.manpage, +        } +        read_generic(@opt,specific) +        SiSU_Manpage::Source::Scroll.new(md,@ao_array,@wrap_width).songsheet +      rescue +        SiSU_Errors::Rescued.new($!,$@,@opt.selections.str,@opt.fns).location do +          __LINE__.to_s + ':' + __FILE__ +        end +      ensure +        Dir.chdir(@opt.f_pth[:pth]) +      end +    end +    private +    class Scroll <Source +      include SiSU_Parts_Generic +      include SiSU_TextUtils +      @@endnotes={ para: [], end: [] } +      def initialize(md,data,wrap_width) +        @md,@data,@wrap_width=md,data,wrap_width +        @tab="\t" +        @@notes=:end +        @manpage={ body: [], open: [], close: [], head: [], metadata: [], tail: [], endnotes: [] } +      end +      def songsheet +        manpage=markup(@data) +        publish(manpage) +      end +      def break_line +        "\n" +      end +      # Used for extraction of endnotes from paragraphs +      def extract_endnotes(dob='') +        para=dob.obj.gsub(/#{Mx[:br_line]}/,"\n") +        notes=para.scan(/(?:#{Mx[:en_a_o]}|#{Mx[:en_b_o]})([\d*+]+(?:\s|\n)+.+?)(?:#{Mx[:en_a_c]}|#{Mx[:en_b_c]})/m) +        @n=[] +        notes.flatten.each do |n| #high cost to deal with <br> appropriately within manpage, consider +          n=n.dup.to_s +          if n =~/#{Mx[:br_line]}|#{Mx[:br_nl]}/ +            fix = n.split(/#{Mx[:br_line]}|#{Mx[:br_nl]}/) #watch #added +            fix.each do |x| +              unless x.empty?; @n << x +              end +            end +          else                 @n << n +          end +        end +        notes=@n.flatten +        notes.each do |e| +          util=(e.to_s =~/^\[[\d*+]+\]:/) \ +          ? (SiSU_TextUtils::Wrap.new(e.to_s,@wrap_width,4,1)) +          : (SiSU_TextUtils::Wrap.new(e.to_s,@wrap_width,0,1)) +          wrap=util.line_wrap +          wrap=if wrap =~ /^\s*[\d*+]+\s+.+?\s*\Z/m +            wrap.gsub(/(^| |#{Mx[:nbsp]}|\s|\*)\\\*/,'\1\\\\\*'). #man page requires +              gsub(/\s(.[BI])\s/,' '). +              gsub(/\s\.(\S+)/,' \\.\1'). +              gsub(/^\s*([\d*+]+)\s+(.+?)\s*\Z/m, <<GSUB +.TP +.BI \\1. +\\2 +GSUB +                      ) +          else +            wrap.gsub(/^\s*(.+)\Z/m, <<GSUB +\\1 +GSUB +                      ) +          end +          @@endnotes[:para] << wrap +          @@endnotes[:end] << wrap << "\n.BR" +          @@endnotes +        end +      end +      def manpage_metadata +        @manpage[:metadata]=SiSU_Metadata::Summary.new(@md).manpage.metadata +      end +      def manpage_tail +        @manpage[:tail] <<<<WOK +#{break_line} +.TP +.SH SEE ALSO +       sisu(1), +       sisu-epub(1), +       sisu-harvest(1), +       sisu-html(1), +       sisu-odf(1), +       sisu-pdf(1), +       sisu-pg(1), +       sisu-sqlite(1), +       sisu-txt(1). +       sisu_vim(7) +.TP +.SH HOMEPAGE +       More information about SiSU can be found at <http://www.sisudoc.org/> or <http://www.jus.uio.no/sisu/> +.TP +.SH SOURCE +       <http://git.sisudoc.org/> +.TP +.SH AUTHOR +       SiSU is written by Ralph Amissah [ralph@amissah.com] +WOK +      end +      def manpage_structure(dob='',hname='') #% Used to extract the structure of a document +        if dob.is==:heading +          lv=dob.ln +          dob.ln + 2 +        else lv=nil +        end +        wrapped=if dob.is==:para \ +        || dob.is==:heading +          paragraph=dob.obj +          if dob.is==:para +            if dob.indent =~/[1-9]/ \ +            and dob.indent == dob.hang +              util=if dob.bullet_ +                SiSU_TextUtils::Wrap.new("* #{paragraph}",@wrap_width,dob.indent.to_i*2) +              else SiSU_TextUtils::Wrap.new(paragraph,@wrap_width,dob.indent.to_i*2) +              end +            elsif dob.hang =~/[0-9]/ \ +            and dob.indent != dob.hang                     # NOT yet implemented +              util=SiSU_TextUtils::Wrap.new(paragraph,@wrap_width,dob.indent.to_i*2) +            else +              util=if dob.bullet_ +                SiSU_TextUtils::Wrap.new("* #{paragraph}",@wrap_width,0) +              else SiSU_TextUtils::Wrap.new(paragraph,@wrap_width,0) +              end +            end +          else util=SiSU_TextUtils::Wrap.new(paragraph,@wrap_width,0) +          end +          w=util.line_wrap +          w=w.gsub(/^(\\\.)/,' \1') +          w +        end +        if lv +          times=wrapped.length +          times=@wrap_width if times > @wrap_width +          @manpage[:body] << case lv +          when 0    then '.SH ' << wrapped.upcase << break_line << break_line +          when 1..3 then '.SH ' << wrapped.upcase << break_line << break_line +          when 4    then '.SH ' << wrapped.upcase << break_line << break_line +          when 5..6 then '.SH ' << wrapped.upcase << break_line << break_line +          end +        else +          @manpage[:body] << if  wrapped =~/^\.BI\s/ # main text, contents, body KEEP +            '.TP' << break_line << wrapped.gsub(/(^\.B)I\s/,'\1 ') # sleight ... simpler output (check gsub!) +          else +            break_line + '.BR' + break_line << wrapped +          end +        end +        if @@endnotes[:para] \ +        and @@notes==:foot #edit out to switch off endnotes following paragraph to which they belong +          @@endnotes[:para].each { |e| @manpage[:body] << e << break_line } +        elsif @@endnotes[:para] \ +        and @@notes==:end +        end +        @@endnotes[:para]=[] +      end +      def markup(data)                                                       # Used for major markup instructions +        SiSU_Env::InfoEnv.new(@md.fns) +        @data_mod,@endnotes,@level,@cont,@copen,@manpage_contents_close=Array.new(6){[]} +        (0..6).each { |x| @cont[x]=@level[x]=false } +        (4..6).each { |x| @manpage_contents_close[x]='' } +        #manpage_tail # stop call +        table_message='[table omitted, see other document formats]' +        #manpage_metadata +        data.each do |dob| +          if dob.is==:comment \ +          || dob.is==:heading_insert +            dob.obj='' +          end +          dob.obj=dob.obj.gsub(/.+?<-#>/,'').                                           # remove dummy headings (used by html) #check +            gsub(/#{Mx[:fa_superscript_o]}(.+?)#{Mx[:fa_superscript_c]}/,'^\1^'). +            gsub(/#{Mx[:fa_subscript_o]}(.+?)#{Mx[:fa_subscript_c]}/,'[\1]'). +            gsub(/#{Mx[:fa_insert_o]}(.+?)#{Mx[:fa_insert_c]}/,'++\1++'). +            gsub(/#{Mx[:fa_strike_o]}(.+?)#{Mx[:fa_strike_c]}/,'--\1--'). +            gsub(/#{Mx[:fa_cite_o]}(.+?)#{Mx[:fa_cite_c]}/,'"\1"'). +            gsub(/#{Mx[:fa_monospace_o]}(.+?)#{Mx[:fa_monospace_c]}/,'\1'). +            gsub(/\A\s*#{Mx[:fa_italics_o]}(.+?)#{Mx[:fa_italics_c]}#{Mx[:br_line]}([,.:!?](?: |$))?/m, +              "#{Mx[:br_line]}.I \\1\\2#{Mx[:br_line]}"). +            gsub(/\s*#{Mx[:fa_italics_o]}(.+?)#{Mx[:fa_italics_c]}([,.:!?](?: |$))?/m, +              "#{Mx[:br_line]}.I \\1\\2#{Mx[:br_line]}"). +            gsub(/\A\s*#{Mx[:fa_bold_o]}(.+?)#{Mx[:fa_bold_c]}([,.:!?](?: |$))?#{Mx[:br_line]}/m, +              "\n.BI \\1\\2#{Mx[:br_line]}"). +            gsub(/\s*#{Mx[:fa_bold_o]}(.+?)#{Mx[:fa_bold_c]}([,.:!?](?: |$))?/m, +              "#{Mx[:br_line]}.B \\1\\2#{Mx[:br_line]}"). +            gsub(/\s*#{Mx[:fa_underscore_o]}(.+?)#{Mx[:fa_underscore_c]}([,.:!?](?: |$))?/, +              "\n.I \\1\\2#{Mx[:br_line]}") +          unless dob.is==:code +            dob.obj=dob.obj.gsub(/(?:^|\s)#{Mx[:lnk_o]}(.+?)#{Mx[:lnk_c]}#{Mx[:url_o]}(\S+?)#{Mx[:url_c]}([,.:!?](?: |$))?/, +                "\\1 #{the_text.url_open}\\2#{the_text.url_close}\\3"). +              gsub(/(^|#{Mx[:gl_c]}|\s)#{Mx[:url_o]}(\S+?)#{Mx[:url_c]}([,.:!?](?: |$))?/, +                "\\1#{the_text.url_open}\\2#{the_text.url_close}\\3") +            @manpage[:endnotes]=extract_endnotes(dob) +            dob.obj=dob.obj.gsub(/#{Mx[:en_a_o]}([\d*+]+)\s*(?:.+?)#{Mx[:en_a_c]}/m,'[^\1]'). # endnote marker marked up +              gsub(/#{Mx[:en_b_o]}([\d*+]+)\s*(?:.+?)#{Mx[:en_b_c]}/m,'[^\1]'). # endnote marker marked up +              gsub(/#{Mx[:gl_o]}#amp#{Mx[:gl_c]}/,'&'). ##{Mx[:gl_o]}#095#{Mx[:gl_c]} +              gsub(/#{Mx[:gl_o]}#033#{Mx[:gl_c]}/,'!'). +              gsub(/#{Mx[:gl_o]}#035#{Mx[:gl_c]}/,'#'). +              gsub(/#{Mx[:gl_o]}#042#{Mx[:gl_c]}/,'*'). +              gsub(/#{Mx[:gl_o]}#045#{Mx[:gl_c]}/,'-'). +              gsub(/#{Mx[:gl_o]}#092#{Mx[:gl_c]}/,'\e'). +              gsub(/#{Mx[:gl_o]}#047#{Mx[:gl_c]}/,'/'). +              gsub(/#{Mx[:gl_o]}#095#{Mx[:gl_c]}/,'_'). +              gsub(/#{Mx[:gl_o]}#123#{Mx[:gl_c]}/,'{'). +              gsub(/#{Mx[:gl_o]}#125#{Mx[:gl_c]}/,'}'). +              gsub(/#{Mx[:gl_o]}#126#{Mx[:gl_c]}/,'~'). +              gsub(/#{Mx[:gl_o]}#169#{Mx[:gl_c]}/,'©') +          else +            dob.obj=dob.obj.gsub(/\\/,'\e'). +              gsub(/(?:#{Mx[:br_line]}|#{Mx[:br_nl]})\s*/,"\n")                          # watch +          end +          dob.obj=dob.obj.gsub(/(^| |#{Mx[:nbsp]}|\s|\*)\\\*/,'\1\\\\\*').          #man page requires +            gsub(/┆/,'|'). +            gsub(/^(\.\S{3,})/m,' \1')                                                   # ^\. used by interpreter, disable when use not intended +          dob.obj=dob.obj.gsub(/~/,'~') if dob.obj #manpages use this +          if dob.is ==:code +            dob.obj=dob.obj.gsub(/(^|[^}])_([<>])/m,'\1\2'). # _> _< +              gsub(/(^|[^}])_([<>])/m,'\1\2'). # _<_< +              gsub(/(?:#{Mx[:br_line]}|#{Mx[:br_nl]})+(\s*)/m,"\n\\1").                  # watch +              gsub(/\A(.+?)\s*\Z/m,".nf\n\\1\n.fi") +          end +          dob.obj=dob.obj.gsub(/(?:#{Mx[:br_line]}|#{Mx[:br_nl]})+\s*/m,"\n\n")          # watch +          dob.obj=dob.obj.gsub(/#{Mx[:gl_o]}:name#\S+?#{Mx[:gl_c]}/mi,'').               #added +            gsub(/#{Mx[:br_page]}\s*|#{Mx[:br_page_new]}|#{Mx[:br_page_line]}/,'').      # remove page breaks, you may wish to have a line across the page break instead +            gsub(/(^|#{Mx[:gl_c]}|\s)#{Mx[:url_o]}_(\S+?)#{Mx[:url_c]}/,'\1\2'). +            gsub(/<a href=".+?">(.+?)<\/a>/m,'\1'). +            gsub(/#{Mx[:mk_o]}name#\S+?#{Mx[:mk_c]}/,'').                                # remove name links +            gsub(/ |#{Mx[:nbsp]}/,' ').                                             # decide on +            gsub(/(?:^|[^_\\])#{Mx[:lnk_o]}\s*(\S+?\.(?:png|jpg|gif)) .+?#{Mx[:lnk_c]}#{Mx[:url_o]}\S+?#{Mx[:url_c]}/,'    [ \1 ]'). #"[ #{dir.url.images_local}\/\\1 ]") +            gsub(/(?:^|[^_\\])#{Mx[:lnk_o]}\s*(\S+?\.(?:png|jpg|gif)) .+?#{Mx[:lnk_c]}image/,'    [ \1 ]'). #"[ #{dir.url.images_local}\/\\1 ]") +            gsub(/^(?:^|[^_\\])#{Mx[:lnk_o]}\s*\S+?\.(?:png|jpg|gif)\s+.+?"(.*?)"\s*#{Mx[:lnk_c]}\S+/,'[image: "\1"]') +          if dob.obj !~/(^#{Rx[:meta]}|#{Mx[:br_eof]}|#{Mx[:br_endnotes]})/ +            if dob.obj =~@regx #/.+?<~\d+;\w\d+;\w\d+>.*/ #watch change +              paranum=dob.obj[@regx,3] +              @p_num=SiSU_ManpageFormat::ParagraphNumber.new(paranum) +            end +            SiSU_ManpageFormat::FormatTextObject.new(@md,dob) #check +            if dob.is==:heading +              manpage_structure(dob) +            elsif dob.is==:para +              manpage_structure(dob) +            else +              if dob.obj =~/#{table_message}/ +                @manpage[:body] << dob.obj << break_line +              end +            end +            if (dob.obj =~/<a name="n\d+">/ \ +            and dob.obj =~/^(-\{{2}~\d+|<!e[:_]\d+!>)/) # -endnote +              dob.obj='' +            end +            if dob.obj +              dob.obj=dob.obj.gsub(/(?:#{Mx[:br_line]}|#{Mx[:br_nl]})\s*/,"\n\n").                                   # watch +                gsub(/#{Mx[:gl_o]}#126#{Mx[:gl_c]}/,'~'). +                gsub(/#{Mx[:gl_o]}#123#{Mx[:gl_c]}/,'{'). +                gsub(/#{Mx[:pa_o]}\S+#{Mx[:pa_c]}/,' ') +              unless dob.is ==:code +                dob.obj=dob.obj.gsub(/<!.+!>/,' '). +                  gsub(/<:\S+>/,' ') +              end +            end +            dob +          end +        end +        @manpage +      end +      def publish(manpage) +        content=[] +        date=if defined? @md.date.modified \ +        and @md.date.modified +          @md.date.modified +        elsif defined? @md.date.published \ +        and @md.date.published +          @md.date.published +        else SiSU_Env::InfoDate.new.year #date missing decide on action +        end +        proj=SiSU_Env::InfoVersion.instance.get_version +        manpage[:open] = %{.TH "#{@md.fnb}" "#{@md.make.manpage['section']}" "#{date}" "#{proj.version}" "#{@md.title.main}"#{@md.make.manpage['name']}#{@md.make.manpage['synopsis']}} +        content << manpage[:open] +        content << manpage[:head] +        content << manpage[:body] +        content << @@endnotes[:end] if @@notes==:end +        content << manpage[:metadata] +        content << manpage[:tail] +        outputfile=SiSU_Env::FileOp.new(@md).write_file.manpage +        Txt_Output::Output.new.document(content,outputfile) +        @@endnotes={ para: [], end: [] } +      end +    end +  end +end +__END__ +#+END_SRC + +* manpage_format.rb + +#+BEGIN_SRC ruby  :tangle "../lib/sisu/manpage_format.rb" +# <<sisu_document_header>> +module SiSU_ManpageFormat +  require_relative 'dp'                                 # dp.rb +    include SiSU_Param +  class ParagraphNumber +    def initialize(paranum) +      @paranum=/(\d+)/m.match(paranum)[1] +    end +    def display +      @paranum.gsub(/(\d+)/,'<font size="1" color="#777777">  \1</font>') +    end +    def name +      @paranum.gsub(/(\d+)/,'<a name="\1"></a>') +    end +    def goto +      @paranum.gsub(/(\d+)/,'<a href="#\1">') +    end +  end +  class FormatTextObject +    def initialize(md,dob) +      @md,@dob=md,dob +      rgx=/#{Mx[:en_a_o]}[\d*+]+\s+(.+?)#{Mx[:en_a_c]}/ +      @dob.obj.gsub!(rgx,'\1') if @dob.obj =~rgx +    end +    def scr_endnote_body +      "<endnote>#{@dob.obj}</endnote> " +    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 +    manpage + +  - 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 diff --git a/org/misc.org b/org/misc.org new file mode 100644 index 00000000..fb212b61 --- /dev/null +++ b/org/misc.org @@ -0,0 +1,4107 @@ +-*- mode: org -*- +#+TITLE:       sisu misc +#+DESCRIPTION: documents - structuring, various output representations & search +#+FILETAGS:    :sisu:misc: +#+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 + +* misc sort +** air.rb + +#+BEGIN_SRC ruby  :tangle "../lib/sisu/air.rb" +# <<sisu_document_header>> +module SiSU_Air +  require_relative 'se_hub_particulars'                 # se_hub_particulars.rb +  class Source +    @@ao_array=[] +    @@fns=nil +    def initialize(opt) +      @opt=opt +      @@fns||@opt.fns +      @particulars=SiSU_Particulars::Combined.new(opt) +      #@env=@particulars.env +      #@md=@particulars.md +      #@ao_array=@particulars.ao_array +    end +    def read +    end +  protected +    def print +      puts @particulars.md.inspect +      puts @particulars.env.inspect +      puts @particulars.ao_array +    end +  end +end +__END__ +#+END_SRC + +** embedded.rb + +#+BEGIN_SRC ruby  :tangle "../lib/sisu/embedded.rb" +# <<sisu_document_header>> +module SiSU_Embedded +  require_relative 'dp'                                 # dp.rb +    include SiSU_Param +  require_relative 'se'                                 # se.rb +    include SiSU_Env +  class Source +    def initialize(opt) +      @opt=opt +      @md=SiSU_Param::Parameters.new(@opt).get +      @env=SiSU_Env::InfoEnv.new(@md.fns) +      @rhost=SiSU_Env::InfoRemote.new(@opt).remote_host_base +      @base_src_dir=@opt.f_pth[:pth].sub(/\/#{@opt.f_pth[:lng]}$/,'') +      @f=SiSU_Env::FileOp.new(@md) +    end +    def read +      songsheet +    end +    def songsheet +      images +      audio +      multimedia +      begin +      rescue +        SiSU_Errors::Rescued.new($!,$@,@opt.selections.str,@opt.fns).location do +          __LINE__.to_s + ':' + __FILE__ +        end +      ensure +      end +    end +    def images +      src="#{@base_src_dir}/_sisu/image" +      ldest=@env.path.output +      img_dir="#{@env.path.output}/_sisu/image" +      @rhost.each do |remote_conn| +        if (@md.opt.act[:verbose][:set]==:on \ +        || @md.opt.act[:verbose_plus][:set]==:on \ +        || @md.opt.act[:maintenance][:set]==:on \ +        || @md.opt.act[:rsync][:set]==:on) \ +        and FileTest.directory?(src) +          FileUtils::mkdir_p(img_dir) unless FileTest.directory?(img_dir) +          src_ec=@f.place_file.images.rel + '/' + @md.ec[:image].join(" #{@f.output_path.images.rel}/") +          unless @opt.fns =~/\.-sst$/ +            SiSU_Env::SystemCall.new(src_ec,ldest,'q').rsync('--relative',@opt.base_path) +            #if @md.opt.selections.str.inspect =~/R/ #rsync to remote image directory +            #  SiSU_Env::SystemCall.new(src_ec,remote_rel,'q').rsync('--relative') +            #end +          end +        end +      end +    end +    def audio +      #p @md.ec[:audio] +      src="#{@base_src_dir}/_sisu/mm/audio" +      ldest="#{@env.path.webserv}/#{@env.path.base_markup_dir_stub}/_sisu/mm/audio" +      @rhost.each do |remote_conn| +        rdest="#{remote_conn[:name]}/#{@env.path.base_markup_dir_stub}/_sisu/mm/audio" +        if (@md.opt.act[:verbose][:set]==:on \ +        || @md.opt.act[:verbose_plus][:set]==:on \ +        || @md.opt.act[:maintenance][:set]==:on \ +        || @md.opt.act[:rsync][:set]==:on) \ +        and FileTest.directory?(src) +          FileUtils::mkdir_p(ldest) unless FileTest.directory?(ldest) +          src_ec="#{src}/" + @md.ec[:audio].join(" #{src}/") +          SiSU_Env::SystemCall.new(src_ec,"#{ldest}/.",'q').rsync +          if @md.opt.act[:rsync][:set]==:on #rsync to remote audio directory +            SiSU_Env::SystemCall.new(src_ec,"#{rdest}/.",'q').rsync +          end +        end +      end +    end +    def multimedia +      #p @md.ec[:multimedia] +      src="#{@base_src_dir}/_sisu/mm/video" +      ldest="#{@env.path.webserv}/#{@env.path.base_markup_dir_stub}/_sisu/mm/video" +      @rhost.each do |remote_conn| +        rdest="#{remote_conn[:name]}/#{@env.path.base_markup_dir_stub}/_sisu/mm/video" +        if (@md.opt.act[:verbose][:set]==:on \ +        || @md.opt.act[:verbose_plus][:set]==:on \ +        || @md.opt.act[:maintenance][:set]==:on \ +        || @md.opt.act[:rsync][:set]==:on) \ +        and FileTest.directory?(src) +          FileUtils::mkdir_p(ldest) unless FileTest.directory?(ldest) +          src_ec="#{src}/" + @md.ec[:multimedia].join(" #{src}/") +          SiSU_Env::SystemCall.new(src_ec,"#{ldest}/.",'q').rsync +          if @md.opt.act[:rsync][:set]==:on #rsync to remote video directory +            SiSU_Env::SystemCall.new(src_ec,"#{rdest}/.",'q').rsync +          end +        end +      end +    end +  end +end +__END__ +#+END_SRC + +** errors.rb + +#+BEGIN_SRC ruby  :tangle "../lib/sisu/errors.rb" +# <<sisu_document_header>> +module SiSU_Errors +  require_relative 'se'                                 # se.rb +    include SiSU_Env; include SiSU_Screen +  class Rescued <CreateFile +    def initialize(error,errorlist,cmd,fns='') +      @fns,@cmd,@error,@errorlist=fns,cmd,error,errorlist +      @cmd=(cmd \ +      && (cmd =~/c/)) \ +      ?  'Vc' +      : 'V' +    end +    def location +      file=@fns \ +      ? (SiSU_Env::CreateFile.new(@fns).file_error) +      : (File.new('/tmp/errorlog.sisu','w+')) +      file << @fns << "\n" << @error << "\n" << @errorlist +      file.close +      if @cmd=~/[vVM]/ +        SiSU_Screen::Ansi.new('',$!,$@).rescue do +          (block_given?) ? yield : __LINE__.to_s + ':' + __FILE__ +        end +      else +        SiSU_Screen::Ansi.new('',"rescued, exception raised, silenced").puts_grey +      end +    end +  end +end +__END__ +#+END_SRC + +** git.rb + +#+BEGIN_SRC ruby  :tangle "../lib/sisu/git.rb" +# <<sisu_document_header>> +module SiSU_Git +  require_relative 'dp'                                 # dp.rb +  require_relative 'se'                                 # se.rb +  require_relative 'ao'                                 # ao.rb +  class Source +    def initialize(opt,process=:complete) +      @opt,@process=opt,process +      @env=SiSU_Env::InfoEnv.new +      @md=SiSU_Param::Parameters.new(@opt).get +      @file=SiSU_Env::FileOp.new(@md) +      l=SiSU_Env::StandardiseLanguage.new(@md.opt.lng).language +      unless @opt.lng==l[:c] # @md.i18n[0]==l[:c] +        p "using: #{@opt.lng} (@make: :language:); filename #{@md.fns} filename language: #{l[:c]}, mismatch" +      end +      if @env.output_dir_structure.multilingual? +        m=/((.+?)(?:\~\w{2,3})?)\.((?:-|ssm\.)?sst|ssm)$/ #watch added match for sss +        fnb,fnt=@opt.fns[m,2],@opt.fns[m,3] +      else m=/(.+?)\.((?:-|ssm\.)?sst|ssm)$/ +        fnb=@fnn=@opt.fns[m,1] +        fnt=@opt.fns[m,2] +      end +      git_path_fnb=@env.processing_path.git + '/' + fnb +      lng=(@md.opt.lng) ? (@md.opt.lng) : (@md.i18n[0]) +      @git_path={ +        fnb:       git_path_fnb, +        doc:       git_path_fnb + '/' + Gt[:sisupod] + '/' + Gt[:doc] + '/' + lng, +        po:        git_path_fnb + '/' + Gt[:po] + '/' + lng, +        pot:       git_path_fnb + '/' + Gt[:pot], +        conf:      git_path_fnb + '/' + Gt[:sisupod] + '/' + Gt[:conf], +        image:     git_path_fnb + '/' + Gt[:sisupod] + '/' + Gt[:image], +        audio:     git_path_fnb + '/' + Gt[:sisupod] + '/' + Gt[:audio], +        video:     git_path_fnb + '/' + Gt[:sisupod] + '/' + Gt[:video], +        conf:      git_path_fnb + '/' + Gt[:sisupod] + '/' + Gt[:conf] +      } +      SiSU_AO::Source.new(@opt,nil,@process).read                            # -m +    end +    def create_file_structure_git +      make_dir_fnb +      if program_found? +        git_init +      end +    end +    def read +      create_file_structure_git +      populate.sisusrc_files +      #if program_found? +      #  git_commit +      #end +      unless @opt.act[:quiet][:set]==:on +        (@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], +            'Git path', +            @git_path[:fnb] +          ).green_hi_blue +        : SiSU_Screen::Ansi.new( +            @opt.act[:color_state][:set], +            'Git path', +            @git_path[:fnb] +          ).green_title_hi +        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], +            "Git path", +            "#{@opt.fns} -> #{@git_path[:fnb]}" +          ).warn +        end +      end +    end +    def program_found? +      found=`whereis git` +      (found =~/bin\/git\b/) ? true : false +    end +    def make_dir_fnb +      FileUtils::mkdir_p(@git_path[:fnb]) \ +        unless FileTest.directory?(@git_path[:fnb]) +      FileUtils::mkdir_p(@git_path[:doc]) \ +        unless FileTest.directory?(@git_path[:doc]) +      FileUtils::mkdir_p(@git_path[:po]) \ +        unless FileTest.directory?(@git_path[:po]) +      FileUtils::mkdir_p(@git_path[:pot]) \ +        unless FileTest.directory?(@git_path[:pot]) +      FileUtils::mkdir_p(@git_path[:conf]) \ +        unless FileTest.directory?(@git_path[:conf]) +      FileUtils::mkdir_p(@git_path[:image]) \ +        unless FileTest.directory?(@git_path[:image]) +      #FileUtils::mkdir_p(@git_path[:audio]) \ +      #  unless FileTest.directory?(@git_path[:audio]) +      #FileUtils::mkdir_p(@git_path[:video]) \ +      #  unless FileTest.directory?(@git_path[:video]) +    end +    def git_init +      unless FileTest.directory?("#{@git_path[:fnb]}/.git") +        pwd=Dir.pwd +        Dir.chdir(@git_path[:fnb]) +        system("git init ") +        Dir.chdir(pwd) +      end +    end +    def git_commit +      if program_found? +        if FileTest.directory?("#{@git_path[:fnb]}") +          pwd=Dir.pwd +          Dir.chdir(@git_path[:fnb]) +          system(" +            git add . \ +            && git commit -a +          ") +          Dir.chdir(pwd) +        end +      end +    end +    def populate +      def identify_language_versions +        print __FILE__ + ':' +        p __LINE__ +      end +      def copy_src_head +        if @opt.f_pth[:lng] \ +        and File.exist?("#{@env.path.pwd}/#{@opt.f_pth[:lng]}/#{@opt.fns}") +          FileUtils::cp_r( +            "#{@env.path.pwd}/#{@opt.f_pth[:lng]}/#{@opt.fns}", +            @git_path[:doc] +          ) +        elsif @opt.fns =~/\.ssm\.sst/ +          ssm=@opt.fns.gsub(/\.ssm\.sst/,'.ssm') +          FileUtils::cp_r( +            "#{@env.path.pwd}/#{ssm}", +            @git_path[:doc] +          ) +        elsif File.exist?("#{@env.path.pwd}/#{@opt.fns}") +          FileUtils::cp_r( +            "#{@env.path.pwd}/#{@opt.fns}", +            @git_path[:doc] +          ) +        end +      end +      def copy_related_sst_ssi +        doc_import=[] +        @rgx_doc_import=/^<<\s(\S+?\.ss[ti])/ +        file_array=IO.readlines(@opt.fns,'') +        file_array.each do |f| +          if f =~@rgx_doc_import +            doc_import = doc_import \ +            + f.scan(@rgx_doc_import).uniq.flatten +          end +        end +        doc_import.each do |f| +          if @opt.f_pth[:lng] +            FileUtils::cp_r( +              "#{@env.path.pwd}/#{@opt.f_pth[:lng]}/#{f}", +              @git_path[:doc] +            ) +          else +            FileUtils::cp_r( +              "#{@env.path.pwd}/#{f}", +              @git_path[:doc] +            ) +          end +        end +      end +      def locate_parse_file +        composite_src=@opt.fns=~/\.ssm$/ ? true : false +        if composite_src \ +        and not @opt.act[:ao][:set]==:on +          ##SiSU_Assemble::Composite.new(@opt).read +          #SiSU_AO::Source.new(@opt).read                                         # -m +          @env.processing_path.composite_file \ +          + '/' \ +          + @opt.fnb \ +          + '.ssm.sst' +        elsif composite_src +          @env.processing_path.composite_file \ +          + '/' \ +          + @opt.fnb \ +          + '.ssm.sst' +        else +          @env.path.pwd +          + '/' \ +          + @opt.fns +        end +      end +      def read_composite +        #print __FILE__ + ':' +        #p __LINE__ +      end +      def sisuyaml_rc +        sisurc=@env.path.sisurc_path +        if FileTest.file?(sisurc) +          FileUtils::cp_r(sisurc,@git_path[:conf]) +        end +      end +      def read_src +        print __FILE__ + ':' +        p __LINE__ +      end +      def composite_src? +        @opt.fns=~/\.ssm$/ ? true : false +      end +      def sisusrc_files +        populate.copy_src_head +        if composite_src? +          populate.copy_related_sst_ssi +        end +        #parse_file_name=locate_parse_file +        #parse_file=IO.readlines(parse_file_name,'') +        populate.sisuyaml_rc #(parse_file) +        #populate.extract_composite_source +        #populate.read_composite # or read_each_composite +        populate.identify_language_versions +      end +      self +    end +  end +end +__END__ +@file.output_path.sisugit +#+END_SRC + +** qrcode.rb + +#+BEGIN_SRC ruby  :tangle "../lib/sisu/qrcode.rb" +# <<sisu_document_header>> +module SiSU_QRcode +  require_relative 'se'                                 # se.rb +    include SiSU_Env +  require_relative 'prog_text_translation'              # prog_text_translation.rb +  require_relative 'se_hub_particulars'                 # se_hub_particulars.rb +    include SiSU_Particulars +  require_relative 'html'                               # html.rb +  require_relative 'dp'                                 # dp.rb +    include SiSU_Param +  require_relative 'generic_parts'                      # generic_parts.rb +  require_relative 'i18n'                               # i18n.rb +  class Source +    def initialize(opt) +      @opt=opt +      @particulars=SiSU_Particulars::CombinedSingleton.instance.get_all(opt) +      l=SiSU_Env::StandardiseLanguage.new(@opt.lng).language +      @doc_language=l[:n] +    end +    def read +      begin +        @env=SiSU_Env::InfoEnv.new(@opt.fns,@opt) +        @md=SiSU_Param::Parameters.new(@opt).get +        xbrowser=@env.program.web_browser +        browser=@env.program.console_web_browser +        unless @opt.act[:quiet][:set]==:on +          url_html="file://#{@md.file.output_path.manifest.dir}/#{@md.file.base_filename.manifest}" +          (@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], +              'QR code', +              "#{xbrowser} #{url_html}" +            ).green_hi_blue +          : SiSU_Screen::Ansi.new( +              @opt.act[:color_state][:set], +              'QR code', +              "[#{@opt.f_pth[:lng_is]}] #{@opt.fns}" +            ).green_title_hi +          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], +              "#{browser} #{url_html}" +            ).grey_tab +          end +        end +        data=SiSU_HTML::Source::HTML_Environment.new(@particulars).tuned_file_instructions +        OutputInfo.new(@md).check_output(data) +      rescue +        SiSU_Errors::Rescued.new($!,$@,@opt.selections.str,@opt.fns).location do +          __LINE__.to_s + ':' + __FILE__ +        end +      ensure +      end +    end +    private +    class OutputInfo <Source +      include SiSU_Parts_Generic +      def initialize(md) +        @manifest={ txt: [], txt_title: [] } +        @md,@fns=md,md.fns +        @env=SiSU_Env::InfoEnv.new(@md.fns,@md.opt) +        @fnb=@md.fnb +        @base_url="#{@env.url.root}/#{@fnb}" +        @f=SiSU_Env::FileOp.new(@md) +        @base_path=@f.output_path.manifest.dir +        @@dg ||=SiSU_Env::InfoEnv.new.digest(@md.opt).type +        @dg=@@dg +        l=SiSU_Env::StandardiseLanguage.new(@md.opt.lng).language +        @language=l[:n] +        @translate=SiSU_Translate::Source.new(@md,@language) +        @f.make_path(@f.output_path.qrcode.dir) +      end +      def spaces +        Ax[:spaces] +      end +      def output_metadata +        fn=@f.base_filename.manifest_txt +        mn='' +        if @md.opt.act[:maintenance][:set]==:on +          fn=@f.base_filename.manifest_txt +          manifest=@f.write_file.manifest_txt +        end +        @manifest[:txt].each do |x| +          x=x.gsub(/\\\\/m,"\n") +          puts x if @md.opt.act[:verbose_plus][:set]==:on +          manifest << x if @md.opt.act[:maintenance][:set]==:on +          mn += x +        end +        manifest.close if @md.opt.act[:maintenance][:set]==:on +        cmd=SiSU_Env::SystemCall.new(mn,@f.place_file.qrcode_md.dir,@md.opt.selections.str) +        cmd.qrencode +      end +      def output_metadata_short +        mn='' +        @manifest[:txt_title].each do |x| +          mn += x +        end +        cmd=SiSU_Env::SystemCall.new(mn,@f.place_file.qrcode_title.dir,@md.opt.selections.str) +        cmd.qrencode +      end +      def summarize(id,file,pth='',rel='',url='',img='● ') +        size=(File.size("#{pth}/#{file}")/1024.00).to_s +        kb=/([0-9]+\.[0-9]{0,1})/m.match(size)[1] +        @manifest[:txt] <<<<WOK +#{id} #{kb} +  #{the_text.url_open}#{url}/#{file}#{the_text.url_close} +WOK +      end +      def summarize_html_seg(id,file,pth='',rel='',url='',img='● ') +        size=(File.size("#{pth}/#{file}")/1024.00).to_s +        kb=/([0-9]+\.[0-9]{0,1})/m.match(size)[1] +        @manifest[:txt] <<<<WOK +#{id} #{kb} +  #{the_text.url_open}#{url}/#{file}#{the_text.url_close} +WOK +      end +      def summarize_sources(id,file,pth,rel,url) +        sys=SiSU_Env::SystemCall.new +        dgst=case @dg +        when :sha512 +          (sys.sha512("#{pth}/#{file}")) #check +        when :md5 +          (sys.md5("#{pth}/#{file}")) +        else +          (sys.sha256("#{pth}/#{file}")) +        end +        dgst=dgst ? dgst : [ '', 'n/a' ] +        if (@md.opt.act[:verbose][:set]==:on \ +        || @md.opt.act[:verbose_plus][:set]==:on \ +        || @md.opt.act[:maintenance][:set]==:on) +          SiSU_Screen::Ansi.new( +            @md.opt.selections.str, +            "#{dgst[1]} #{file}" +          ).warn +        end +        size=(File.size("#{pth}/#{file}")/1024.00).to_s +        kb=/([0-9]+\.[0-9]{0,1})/m.match(size)[1] +        @manifest[:txt] <<<<WOK +#{id} #{dgst[1]} #{kb} +  #{the_text.url_open}#{url}/#{file}#{the_text.url_close} +WOK +      end +      def published_manifests? +        @f=SiSU_Env::FileOp.new(@md) #.base_filename +        @m=[] +        url=@f.output_path.base.url +        manifests={} +        mp,mn,mt=nil,nil,nil +        ln=SiSU_i18n::Languages.new.language.list +        Px[:lng_lst].each do |lc| +          if @env.output_dir_structure.by_language_code? +            mp="#{@f.output_path.base.dir}/#{lc}/manifest" +            mn="#{@md.fnb}.html" +            mt="#{mp}/#{mn}" +            mu="#{url}/#{lc}/manifest/#{mn}" +          elsif @env.output_dir_structure.by_filetype? +            mp="#{@f.output_path.base.dir}/manifest" +            mn="#{@md.fnb}.#{lc}.html" +            mt="#{mp}/#{mn}" +            mu="#{url}/manifest/#{mn}" +          else +            mp="#{@f.output_path.base.dir}/#{@md.fnb}" +            mn="sisu_manifest.#{lc}.html" +            mt="#{mp}/#{mn}" +            mu="#{url}/#{mn}" +          end +          if FileTest.directory?(mp) \ +          &&  FileTest.file?(mt) +            lng=ln[lc][:t] +            manifests[lc]={ ln: lng, fn: mn } +            @m << { mu: mu, l: lng } +          end +        end +        #manifests +        @m=@m.uniq +        @m +      end +      def languages(id,file) +        flv=published_manifests? +        flv.each do |l| +          SiSU_Translate::Source.new(@md,@language,l[:n]).language_list +          @manifest[:txt] << "#{l[:mu]} #{l[:l]}\n" +        end +      end +      def published_languages(id,file) +        flv=published_manifests? +        flv.each do |l| +          @manifest[:txt] << "#{l[:l]}  #{the_text.url_open}#{l[:mu]}#{the_text.url_close}\n" +        end +      end +      def metadata(id,info) +        info=info.to_s.gsub(/#{Mx[:br_line]}/,"\n") +        @manifest[:txt] << %{#{id}: #{info}\n} +      end +      def md_title_info(id,info) +        info=info.to_s.gsub(/#{Mx[:br_line]}/,"\n") +        @manifest[:txt_title] << %{#{info}\n} +      end +      def links(url,lnk,target) +        static=if url =~/^\.\// then url.gsub(/^\.(\.)?/,@base_url) +        elsif url =~/^\.\.\//   then url.gsub(/^\.(\.)?/,@env.url.root) +        else                         url +        end +        @manifest[:txt] << %{#{url} #{lnk} #{the_text.url_open}#{static}#{the_text.url_close}\n} +      end +      def output_tests +        if FileTest.file?(@f.place_file.html_segtoc.dir)==true +          pth=@f.output_path.html_seg.dir +          rel=@f.output_path.html_seg.rel_sm +          url=@f.output_path.html_seg.url +          id,file='HTML, table of contents (for segmented text)',@f.base_filename.html_segtoc +          summarize_html_seg(id,file,pth,rel,url) +        end +        if FileTest.file?(@f.place_file.html_scroll.dir)==true +          pth=@f.output_path.html_scroll.dir +          rel=@f.output_path.html_scroll.rel_sm +          url=@f.output_path.html_scroll.url +          id,file='HTML, full length document',@f.base_filename.html_scroll +          summarize(id,file,pth,rel,url) +        end +        if FileTest.file?(@f.place_file.html_book_index.dir)==true +          pth=@f.output_path.html_seg.dir +          rel=@f.output_path.html_seg.rel_sm +          url=@f.output_path.html_seg.url +          id,file='HTML, (book type) index',@f.base_filename.html_book_index +          summarize(id,file,pth,rel,url) +        end +        if FileTest.file?(@f.place_file.html_concordance.dir)==true +          pth=@f.output_path.html_seg.dir +          rel=@f.output_path.html_seg.rel_sm +          url=@f.output_path.html_seg.url +          id,file='HTML, concordance file',@f.base_filename.html_concordance +          summarize(id,file,pth,rel,url) +        end +        if FileTest.file?(@f.place_file.epub.dir)==true +          id,file='EPUB (Electronic Publication, e-book standard)',@f.base_filename.epub +          pth=@f.output_path.epub.dir +          rel=@f.output_path.epub.rel_sm +          url=@f.output_path.epub.url +          summarize(id,file,pth,rel,url) +        end +        if FileTest.file?("#{@f.output_path.pdf.dir}/#{@f.base_filename.pdf_p_letter}")==true +          pth=@f.output_path.pdf.dir +          rel=@f.output_path.pdf.rel_sm +          url=@f.output_path.pdf.url +          id,file="PDF, U.S. letter size, portrait/vertical","#{@f.base_filename.pdf_p_letter}" +          summarize(id,file,pth,rel,url) +        end +        if FileTest.file?("#{@f.output_path.pdf.dir}/#{@f.base_filename.pdf_l_letter}")==true +          pth=@f.output_path.pdf.dir +          rel=@f.output_path.pdf.rel_sm +          url=@f.output_path.pdf.url +          id,file="PDF, U.S. letter size, landscape/horizontal","#{@f.base_filename.pdf_l_letter}" +          summarize(id,file,pth,rel,url) +        end +        if FileTest.file?("#{@f.output_path.pdf.dir}/#{@f.base_filename.pdf_p_a4}")==true +          pth=@f.output_path.pdf.dir +          rel=@f.output_path.pdf.rel_sm +          url=@f.output_path.pdf.url +          id,file="PDF, A4 size, portrait/vertical","#{@f.base_filename.pdf_p_a4}" +          summarize(id,file,pth,rel,url) +        end +        if FileTest.file?("#{@f.output_path.pdf.dir}/#{@f.base_filename.pdf_l_a4}")==true +          pth=@f.output_path.pdf.dir +          rel=@f.output_path.pdf.rel_sm +          url=@f.output_path.pdf.url +          id,file="PDF, A4 size, landscape/horizontal","#{@f.base_filename.pdf_l_a4}" +          summarize(id,file,pth,rel,url) +        end +        if FileTest.file?("#{@f.output_path.pdf.dir}/#{@f.base_filename.pdf_p_a5}")==true +          pth=@f.output_path.pdf.dir +          rel=@f.output_path.pdf.rel_sm +          url=@f.output_path.pdf.url +          id,file="PDF, A5 (book) size, portrait/vertical","#{@f.base_filename.pdf_p_a5}" +          summarize(id,file,pth,rel,url) +        end +        if FileTest.file?("#{@f.output_path.pdf.dir}/#{@f.base_filename.pdf_l_a5}")==true +          pth=@f.output_path.pdf.dir +          rel=@f.output_path.pdf.rel_sm +          url=@f.output_path.pdf.url +          id,file="PDF, A5 (book) size, landscape/horizontal","#{@f.base_filename.pdf_l_a5}" +          summarize(id,file,pth,rel,url) +        end +        if FileTest.file?("#{@f.output_path.pdf.dir}/#{@f.base_filename.pdf_p_b5}")==true +          pth=@f.output_path.pdf.dir +          rel=@f.output_path.pdf.rel_sm +          url=@f.output_path.pdf.url +          id,file="PDF, B5 (book) size, portrait/vertical","#{@f.base_filename.pdf_p_b5}" +          summarize(id,file,pth,rel,url) +        end +        if FileTest.file?("#{@f.output_path.pdf.dir}/#{@f.base_filename.pdf_l_b5}")==true +          pth=@f.output_path.pdf.dir +          rel=@f.output_path.pdf.rel_sm +          url=@f.output_path.pdf.url +          id,file="PDF, B5 (book) size, landscape/horizontal","#{@f.base_filename.pdf_l_b5}" +          summarize(id,file,pth,rel,url) +        end +        if FileTest.file?("#{@f.output_path.pdf.dir}/#{@f.base_filename.pdf_p_legal}")==true +          pth=@f.output_path.pdf.dir +          rel=@f.output_path.pdf.rel_sm +          url=@f.output_path.pdf.url +          id,file="PDF, U.S. legal size, portrait/vertical","#{@f.base_filename.pdf_p_legal}" +          summarize(id,file,pth,rel,url) +        end +        if FileTest.file?("#{@f.output_path.pdf.dir}/#{@f.base_filename.pdf_l_legal}")==true +          pth=@f.output_path.pdf.dir +          rel=@f.output_path.pdf.rel_sm +          url=@f.output_path.pdf.url +          id,file="PDF, U.S. legal size, landscape/horizontal","#{@f.base_filename.pdf_l_legal}" +          summarize(id,file,pth,rel,url) +        end +        if FileTest.file?(@f.place_file.odt.dir)==true +          pth=@f.output_path.odt.dir +          rel=@f.output_path.odt.rel_sm +          url=@f.output_path.odf.url +          id,file='ODF:ODT (Open Document Format)',@f.base_filename.odt +          summarize(id,file,pth,rel,url) +        end +        if FileTest.file?(@f.place_file.xhtml.dir)==true +          pth=@f.output_path.xhtml.dir +          rel=@f.output_path.xhtml.rel_sm +          url=@f.output_path.xhtml.url +          id,file='ODF:ODT (Open Document Format)',@f.base_filename.odt +          id,file='XHTML',@f.base_filename.xhtml +          summarize(id,file,pth,rel,url) +        end +        if FileTest.file?(@f.place_file.xml_sax.dir)==true +          pth=@f.output_path.xml_sax.dir +          rel=@f.output_path.xml_sax.rel_sm +          url=@f.output_path.xml_sax.url +          id,file='XML SAX',@f.base_filename.xml_sax +          summarize(id,file,pth,rel,url) +        end +        if FileTest.file?(@f.place_file.xml_dom.dir)==true +          pth=@f.output_path.xml_dom.dir +          rel=@f.output_path.xml_dom.rel_sm +          url=@f.output_path.xml_dom.url +          id,file='XML DOM',@f.base_filename.xml_dom +          summarize(id,file,pth,rel,url) +        end +        if FileTest.file?(@f.place_file.txt.dir)==true +          id='Plaintext (UTF-8)' +          #id=if @md.opt.selections.str =~/a/ then 'Plaintext (Unix (UTF-8) with footnotes)' +          #elsif @md.opt.selections.str =~/e/ then 'Plaintext (Unix (UTF-8) with endnotes)' +          #elsif @md.opt.selections.str =~/A/ then 'Plaintext (dos (UTF-8) with footnotes)' +          #elsif @md.opt.selections.str =~/E/ then 'Plaintext (dos (UTF-8) with endnotes)' +          #else                         'Plaintext (UTF-8)' +          #end +          pth=@f.output_path.txt.dir +          rel=@f.output_path.txt.rel_sm +          url=@f.output_path.txt.url +          file=@f.base_filename.txt +          summarize(id,file,pth,rel,url) +        end +        if FileTest.file?("#{@base_path}/#{@md.fns}.tex")==true +          id,file='LaTeX (portrait)',"#{@md.fns}.tex" +          pth,rel,url='','','' +          summarize(id,file,pth,rel,url) +        end +        if FileTest.file?("#{@base_path}/#{@md.fns}.tex")==true +          id,file='LaTeX (landscape)',"#{@md.fns}.landscape.tex" +          pth,rel,url='','','' +          summarize(id,file,pth,rel,url) +        end +        if FileTest.file?(@f.place_file.manpage.dir)==true +          pth=@f.output_path.manpage.dir +          rel=@f.output_path.manpage.rel_sm +          url=@f.output_path.manpage.url +          id,file='Manpage',@f.base_filename.manpage +          summarize(id,file,pth,rel,url) +        end +        if FileTest.file?(@f.place_file.texinfo.dir)==true +          pth=@f.output_path.texinfo.dir +          rel=@f.output_path.texinfo.rel_sm +          url=@f.output_path.texinfo.url +          id,file='Texinfo',@f.base_filename.texinfo +          summarize(id,file,pth,rel,url) +        end +        if FileTest.file?(@f.place_file.hash_digest.dir)==true +          pth=@f.output_path.hash_digest.dir +          rel=@f.output_path.hash_digest.rel_sm +          url=@f.output_path.hash_digest.url +          id,file="Digest/DCC - Document Content Certificate (#{@dg})",@f.base_filename.hash_digest +          summarize(id,file,pth,rel,url) +        end +      end +      def published_versions +        id,file='Markup (SiSU source)',@md.fns +        #languages(id,file) +        published_languages(id,file) +      end +      def language_versions +        if FileTest.file?(@f.place_file.manifest.dir)==true +          id,file='Markup (SiSU source)',@md.fns +          published_languages(id,file) +        end +      end +      def source_tests +        if @md.fns =~/\.ssm\.sst$/                                                  #% decide whether to extract and include requested/required documents +          if FileTest.file?(@f.place_file.src.dir)==true +            pth=@f.output_path.src.dir +            rel=@f.output_path.src.rel +            url=@f.output_path.src.url +            id,file='Markup Composite File (SiSU source)',@f.base_filename.src +            summarize_sources(id,file,pth,rel,url) +          end +        else +          if FileTest.file?(@f.place_file.src.dir)==true +            pth=@f.output_path.src.dir +            rel=@f.output_path.src.rel +            url=@f.output_path.src.url +            id,file='Markup (SiSU source)',@f.base_filename.src +            summarize_sources(id,file,pth,rel,url) +          end +        end +        if FileTest.file?(@f.place_file.sisupod.dir)==true +          pth=@f.output_path.sisupod.dir +          rel=@f.output_path.sisupod.rel +          url=@f.output_path.sisupod.url +          id,file='SiSU doc (zip)',@f.base_filename.sisupod +          summarize_sources(id,file,pth,rel,url) +        end +        if FileTest.file?(@f.place_file.pot.dir)==true +          pth=@f.output_path.pot.dir +          rel=@f.output_path.pot.rel_sm +          url=@f.output_path.pot.url +          id,file='SiSU pot',@f.base_filename.pot +          summarize_sources(id,file,pth,rel,url) +        end +      end +      def metadata_tests +        if defined? @md.title.full \ +        and @md.title.full=~/\S+/ +          id,info=@translate.full_title,@md.title.full +          #id,info=@translate.full_title,%{"#{@md.title.full}"} +          metadata(id,info) +          md_title_info(id,info) +        end +        if defined? @md.creator.author \ +        and @md.creator.author=~/\S+/ +          id,info=@translate.author,@md.creator.author +          metadata(id,info) +          md_title_info(id,info) +        end +        if defined? @md.creator.editor \ +        and @md.creator.editor=~/\S+/ +          id,info=@translate.editor,@md.creator.editor +          metadata(id,info) +        end +        if defined? @md.creator.contributor \ +        and @md.creator.contributor=~/\S+/ +          id,info=@translate.contributor,@md.creator.contributor +          metadata(id,info) +        end +        if defined? @md.creator.translator \ +        and @md.creator.translator=~/\S+/ +          id,info=@translate.translator,%{(#{@md.creator.translator})} +          metadata(id,info) +          md_title_info(id,info) +        end +        if defined? @md.creator.illustrator \ +        and @md.creator.illustrator=~/\S+/ +          id,info=@translate.illustrator,@md.creator.illustrator +          metadata(id,info) +        end +        if defined? @md.publisher \ +        and @md.publisher=~/\S+/ #dc +          id,info=@translate.publisher,@md.publisher +          metadata(id,info) +        end +        if defined? @md.creator.prepared_by \ +        and @md.creator.prepared_by=~/\S+/ +          id,info=@translate.prepared_by,@md.creator.prepared_by +          metadata(id,info) +        end +        if defined? @md.creator.digitized_by \ +        and @md.creator.digitized_by=~/\S+/ +          id,info=@translate.digitized_by,@md.creator.digitized_by +          metadata(id,info) +        end +        if defined? @md.rights.all \ +        and @md.rights.all=~/\S+/ #dc +          id,info=@translate.rights,@md.rights.all +          metadata(id,info) +        end +        if defined? @md.date.published +          if defined? @md.date.published \ +          and @md.date.published=~/\S+/ #dc +            id,info=@translate.date,@md.date.published +            metadata(id,info) +            md_title_info(id,info) +          end +          if defined? @md.date.created \ +          and @md.date.created=~/\S+/ #dc +            id,info=@translate.date_created,@md.date.created +            metadata(id,info) +          end +          if defined? @md.date.issued \ +          and @md.date.issued=~/\S+/ #dc +            id,info=@translate.date_issued,@md.date.issued +            metadata(id,info) +          end +          if defined? @md.date.available \ +          and @md.date.available=~/\S+/ #dc +            id,info=@translate.date_available,@md.date.available +            metadata(id,info) +          end +          if defined? @md.date.modified \ +          and @md.date.modified=~/\S+/ #dc +            id,info=@translate.date_modified,@md.date.modified +            metadata(id,info) +          end +          if defined? @md.date.valid \ +          and @md.date.valid=~/\S+/ #dc +            id,info=@translate.date_valid,@md.date.valid +            metadata(id,info) +          end +        end +        if defined? @md.title.language \ +        and @md.title.language=~/\S+/ +          id,info=@translate.language,@md.title.language +          metadata(id,info) +        end +        if defined? @md.original.language \ +        and @md.original.language=~/\S+/ +          id,info=@translate.language_original,@md.original.language +          metadata(id,info) +        end +        if defined? @md.classify.subject \ +        and @md.classify.subject=~/\S+/ +          id,info=@translate.subject,@md.classify.subject +          metadata(id,info) +        end +        if defined? @md.classify.keywords \ +        and @md.classify.keywords=~/\S+/ +          id,info=@translate.keywords,@md.classify.keywords +          metadata(id,info) +        end +        if defined? @md.classify.loc \ +        and @md.classify.loc=~/\S+/ +          id,info=@translate.cls_loc,@md.classify.loc +          metadata(id,info) +        end +        if defined? @md.classify.dewey \ +        and @md.classify.dewey=~/\S+/ +          id,info=@translate.cls_dewey,@md.classify.dewey +          metadata(id,info) +        end +        if defined? @md.notes.description \ +        and @md.notes.description=~/\S+/ +          id,info=@translate.description,@md.notes.description +          metadata(id,info) +        end +        if defined? @md.notes.abstract \ +        and @md.notes.abstract=~/\S+/ +          id,info=@translate.abstract,@md.notes.abstract +          metadata(id,info) +        end +        if defined? @md.notes.comment \ +        and @md.notes.comment=~/\S+/ +          id,info=@translate.comments,@md.notes.comment +          metadata(id,info) +        end +        if defined? @md.notes.coverage \ +        and @md.notes.coverage=~/\S+/ +          id,info=@translate.coverage,@md.notes.coverage +          metadata(id,info) +        end +        if defined? @md.notes.relation \ +        and @md.notes.relation=~/\S+/ +          id,info=@translate.relation,@md.notes.relation +          metadata(id,info) +        end +        #if defined? @md.notes.source \ +        #and @md.notes.source=~/\S+/ +        #  id,info=@translate.source,@md.notes.source +        #  metadata(id,info) +        #end +        #if defined? @md.notes.history \ +        #and @md.notes.history=~/\S+/ +        #  id,info=@translate.history,@md.notes.history +        #  metadata(id,info) +        #end +        if defined? @md.notes.type \ +        and @md.notes.type=~/\S+/ #dc +          id,info=@translate.type,@md.type +          metadata(id,info) +        end +        if defined? @md.notes.format \ +        and @md.notes.format=~/\S+/ +          id,info=@transate.format,@md.notes.format +          metadata(id,info) +        end +        if defined? @md.notes.prefix_a \ +        and @md.notes.prefix_a=~/\S+/ +          id,info=@translate.prefix_a,@md.notes.prefix_a +          metadata(id,info) +        end +        if defined? @md.notes.prefix_b \ +        and @md.notes.prefix_b=~/\S+/ +          id,info=@translate.prefix_b,@md.notes.prefix_b +          metadata(id,info) +        end +        if defined? @md.original.source \ +        and @md.original.source=~/\S+/ +          id,info=@translate.source,@md.original.source +          metadata(id,info) +        end +        if defined? @md.identifier.oclc \ +        and @md.identifier.oclc=~/\S+/ +          id,info=@translate.cls_oclc,@md.identifier.oclc +          @manifest[:txt] << %{#{id}:\n} +          @manifest[:txt] << %{#{info}\n} +        end +        if defined? @md.identifier.isbn \ +        and @md.identifier.isbn=~/\S+/ +          id,info=@translate.cls_isbn,@md.identifier.isbn +          metadata(id,info) +        end +        if defined? @md.topic_register_array \ +        and @md.topic_register_array.length > 0 +          @manifest[:txt] << %{#{@translate.topic_register}:\n} +          @md.topic_register_array.each do |t| +            t.each_with_index do |st,i| +              if st.is_a?(Array) +                st.each do |v| +                  @manifest[:txt] << %{#{spaces*i}#{v}\n} +                end +              else @manifest[:txt] << %{#{spaces*i}#{st}\n} +              end +            end +          end +        end +        if @md.fns +          id,info=@translate.sourcefile,@md.fns +          metadata(id,info) +        end +        if @md.en[:mismatch] > 0 +          id,info='WARNING document error in endnote markup, number mismatch',"endnotes: #{@md.en[:note]} != endnote reference marks: #{@md.en[:mark]} (difference = #{@md.en[:mismatch]})" +          metadata(id,info) +        end +        if @md.wc_words +          id,info=@translate.word_count,@md.wc_words +          metadata(id,info) +        end +        if @md.dgst +          id,info="#{@translate.sourcefile_digest} (#{@dg})",@md.dgst[1] +          metadata(id,info) +        end +        if @md.sc_number +          id,info=@translate.sc_number,@md.sc_number +          metadata(id,info) +        end +        if @md.sc_date +          id,info=@translate.sc_date,"#{@md.sc_date} at #{@md.sc_time}" +          metadata(id,info) +        end +      end +      def check_output(data) +        begin +          @f=SiSU_Env::FileOp.new(@md) #.base_filename +          url=@f.output_path.base.url +          @en_manifest=if @env.output_dir_structure.by_language_code? +            "#{url}/en/manifest/#{@md.fnb}.html" +          elsif @env.output_dir_structure.by_filetype? +            "#{url}/manifest/#{@md.fnb}.#{@md.opt.lng}.html" +          else +            "#{url}/sisu_manifest.#{@md.opt.lng}.html" +          end +          @manifest[:txt] <<<<WOK +#{@translate.manifest_description_metadata} +  #{the_text.url_open}#{@en_manifest}#{the_text.url_close} +WOK +          metadata_tests +          @manifest[:txt_title] <<<<WOK +  #{the_text.url_open}#{@en_manifest}#{the_text.url_close} +WOK +          source_tests +          @manifest[:txt] <<<<WOK +#{@translate.language_version_list} +WOK +          language_versions +          output_metadata +          output_metadata_short +        rescue +          SiSU_Errors::Rescued.new($!,$@,@md.opt.selections.str,@md.fns).location do +            __LINE__.to_s + ':' + __FILE__ +          end +        ensure +        end +      end +    end +  end +end +__END__ +#+END_SRC + +** relaxng.rb + +#+BEGIN_SRC ruby  :tangle "../lib/sisu/relaxng.rb" +# <<sisu_document_header>> +module SiSU_Relaxng +  require_relative 'se'                                 # se.rb +  class RelaxNG +    def gpl3_or_later +      @gpl3_or_later =<<RELAXNG +=begin + + * Name: SiSU generated relaxng + + * Description: generated relaxng for SiSU +   (SiSU is a framework for document structuring, publishing and search) + + * Author: Ralph Amissah + + * Copyright: (C) 1997 - 2013 Ralph Amissah All Rights Reserved. + + * License: GPL 3 or later: + +   SiSU, a framework for document structuring, publishing and search + +   Copyright: (C) 1997 - 2013 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/licenses/gpl.html> +   [http://www.gnu.org/licenses/gpl.html] +   <http://www.jus.uio.no/sisu/gpl.fsf> + + * SiSU uses: +   * Standard SiSU markup syntax, +   * Standard SiSU meta-markup syntax, and the +   * Standard SiSU object citation numbering and system + + * Homepages: +   [http://www.jus.uio.no/sisu] +   [http://www.sisudoc.org] + + * Ralph Amissah +   [ralph@amissah.com] +   [ralph.amissah@gmail.com] + +=end +RELAXNG +    end +    def rnc_name +      def output_sax +        'sisu_sax.rnc' +      end +      def output_dom +        'sisu_dom.rnc' +      end +      def output_xhtml +        'sisu_xhtml.rnc' +      end +      def input_sax +        'sisu_sax.rnc' +      end +      def input_dom +        'sisu_dom.rnc' +      end +      def input_node +        'sisu_node.rnc' +      end +      self +    end +    def rng_name +      def output_sax +        'sisu_sax.rng' +      end +      def output_dom +        'sisu_dom.rng' +      end +      def output_xhtml +        'sisu_xhtml.rng' +      end +      def input_sax +        'sisu_sax.rng' +      end +      def input_dom +        'sisu_dom.rng' +      end +      def input_node +        'sisu_node.rng' +      end +      self +    end +    def xsd_name +      def output_sax +        'sisu_sax.xsd' +      end +      def output_dom +        'sisu_dom.xsd' +      end +      def output_xhtml +        'sisu_xhtml.xsd' +      end +      def input_sax +        'sisu_sax.xsd' +      end +      def input_dom +        'sisu_dom.xsd' +      end +      def input_node +        'sisu_node.xsd' +      end +      self +    end +    def rnc_sisu_object_input +      @relaxng =<<RELAXNG +#%% sisu object model: input +#{gpl3_or_later} +#%% definitions +# dublin core: +element-semantic = +  element semantic { +  # dublin core: +  element title { text } +  & element creator { text }? +  & element subject { text }? +  & element description { text }? +  & element publisher { text }? +  & element contributor { text }? +  & element date { text }? +  & element date.created { text }? +  & element date.issued { text }? +  & element date.available { text }? +  & element date.valid { text }? +  & element date.modified { text }? +  & element type { text }? +  & element format { text }? +  & element identifier { text }? +  & element source { text }? +  & element relation { text }? +  & element coverage { text }? +  & element rights { text }? +  & element keywords { text }? +  # extended semantic metadata: +  & attribute subtitle { text }? +  & attribute illustrator { text }? +  & attribute translator { text }? +  & attribute prepared_by { text }? +  & attribute digitized_by { text }? +  & attribute language { text }? +  & attribute language.original { text }? +  & attribute classify.pg { text }? +  & attribute classify.isbn { text }? +  & attribute classify.dewey { text }? +  & attribute classify.loc { text }? +  & attribute prefix.a { text }? +  & attribute prefix.b { text }? +  & attribute suffix { text }? +  & attribute comments { text }? +  & attribute abstract { text }? +  # & attribute information { text }? +  & attribute contact { text }? +  & attribute links { text }? +  } +element-processing = +  element processing { +  attribute structure { text }? +  & attribute level { text }? +  & attribute markup { text }? +  & attribute bold { text }? +  & attribute italics { text }? +  & attribute papersize { text }? +  & attribute vocabulary { text }? +  & element date_scheme { text }? +  & element date.issued.scheme { text }? +  & element date.available.scheme { text }? +  & element date.valid.scheme { text }? +  & element date.modified.scheme { text }? +  }? +element-head = +  element head { +    # processing instructions, and semantic data, distinguish?: +    element metadata { +      element title { text }, +      element file { text }, +      element generator { text }, +      element-semantic, +      element-processing +    }+ +  } +# body text/contents +# includes <b> <i> <u> <del> <ins> <indent1> <bullet> etc. +element-txt = +  element txt { +    text* +    & element b { text }* +    & element i { text }* +    & element u { text }* +    & element ins { text }* +    & element del { text }* +  } +element-endnote = +  element endnote { +    element number { text }, +    element note { element-txt }+ +  }+ +element-para = +  element para { +    # attribute paragraph_format { text }, +    element-txt+ +    & element-endnote? +  } +element-external_space = +  element external_space { +    # ignored by sisu, provide program needs +    element program { +      # e.g. kdissert +      element name { text }, +      element xpos { text }, +      element ypos { text }, +      element font { text }, +      element outline_color { text }, +      element text_color { text }, +      element comment { text } +    }* +  }*, +#%% structure +  element document { +    # document head: +    element-head, +    # document body: +    element body { +      # object, a unit of text, usually a paragraph with any associated endnotes +      element node { +        element structure { +          # structure document using either node:heading levels or node:heading relationships: +          # (i) sisu default uses node:heading levels (1-6 or A-C,1-3) to build document structure +          element level { text }?, +          # (ii) sisu alternatively could use node:heading relationship information to build document structure +          element node.id { text }, +          element node.parent { text }, +          element node.child { text }* +        }, +        element node.objects { +          element object.heading { +            # nametag used only in headings, especially important for segmented html +            element nametag { text }, +            element-para +          }, +          element object.para { +            element-para +          }* +        }+, +        element-external_space +      }+ +    } +  } +RELAXNG +    end +    def rnc_sisu_object_ao +      @relaxng =<<RELAXNG +#%% sisu object model: ao +#{gpl3_or_later} +#%% definitions +# dublin core: +element-semantic = +  element semantic { +  # dublin core: +  element title { text } +  & element creator { text }? +  & element subject { text }? +  & element description { text }? +  & element publisher { text }? +  & element contributor { text }? +  & element date { text }? +  & element date.created { text }? +  & element date.issued { text }? +  & element date.available { text }? +  & element date.valid { text }? +  & element date.modified { text }? +  & element type { text }? +  & element format { text }? +  & element identifier { text }? +  & element source { text }? +  & element relation { text }? +  & element coverage { text }? +  & element rights { text }? +  & element keywords { text }? +  # extended semantic metadata: +  & attribute subtitle { text }? +  & attribute illustrator { text }? +  & attribute translator { text }? +  & attribute prepared_by { text }? +  & attribute digitized_by { text }? +  & attribute language { text }? +  & attribute language.original { text }? +  & attribute classify.pg { text }? +  & attribute classify.isbn { text }? +  & attribute classify.dewey { text }? +  & attribute classify.loc { text }? +  & attribute prefix.a { text }? +  & attribute prefix.b { text }? +  & attribute suffix { text }? +  & attribute comments { text }? +  & attribute abstract { text }? +  # & attribute information { text }? +  & attribute contact { text }? +  & attribute links { text }? +  } +element-processing = +  element processing { +  attribute structure { text }? +  & attribute level { text }? +  & attribute markup { text }? +  & attribute bold { text }? +  & attribute italics { text }? +  & attribute papersize { text }? +  & attribute vocabulary { text }? +  & element date_scheme { text }? +  & element date.issued.scheme { text }? +  & element date.available.scheme { text }? +  & element date.valid.scheme { text }? +  & element date.modified.scheme { text }? +  }? +element-head = +  element head { +    # processing instructions, and semantic data, distinguish?: +    element metadata { +      element title { text }, +      element file { text }, +      element generator { text }, +      element-semantic, +      element-processing +    }+ +  } +# body text/contents +# includes <b> <i> <u> <del> <ins> <indent1> <bullet> etc. +element-txt = +  element txt { +    text* +    & element b { text }* +    & element i { text }* +    & element u { text }* +    & element ins { text }* +    & element del { text }* +  } +element-checksum.endnote = element checksum.clean { text } +element-endnote = +  element endnote { +    element number { text }, +    element note { element-txt }+, +    element-checksum.endnote +  }+ +element-checksum.para = +  element checksum.para { +    element checksum.clean { text }, +    element checksum.marked { text } +  } +element-para = +  element para { +    # attribute paragraph_format { text }, +    element-txt+ +    & element-endnote? +  } +element-object = +  element object { +    element-para, +    element-checksum.para +  } +# object citation number, unique sequential number for objects: +element-ocn = element ocn { text } +element-object_structure_summary = +  element-ocn, +  # type: heading level value 1 -6, or normal text +  element type { text }, +  # type number: sequential number for designated type +  element type_number { text }, +  # type category: sequential number for designated category, e.g. sequentially counting all headers +  element category_number { text } +element-external_space = +  element external_space { +    # ignored by sisu, provide program needs +    element program { +      # e.g. kdissert +      element name { text }, +      element xpos { text }, +      element ypos { text }, +      element font { text }, +      element outline_color { text }, +      element text_color { text }, +      element comment { text } +    }* +  }*, +#%% structure +  element document { +    # document head: +    element-head, +    # document body: +    element body { +      # object, a unit of text, usually a paragraph with any associated endnotes +      element node { +        element structure { +          # structure document using either node:heading levels or node:heading relationships: +          # (i) sisu default uses node:heading levels (1-6 or A-C,1-3) to build document structure +          element level { text }?, +          # (ii) sisu alternatively could use node:heading relationship information to build document structure +          element node.id { text }, +          element node.parent { text }, +          element node.child { text }* +        }, +        element node.objects { +          element object.heading { +            element-object_structure_summary, +            # nametag used only in headings, especially important for segmented html +            element nametag { text }, +            element-object +          }, +          element object.para { +            element-object_structure_summary, +            element-object +          }* +        }+, +        element-external_space +      }+ +    } +  } +RELAXNG +    end +    def rnc_model_output_sax +      @relaxng =<<RELAXNG +#% sax output model, part of SiSU and distributed under the same license +default namespace = "" +namespace xl = "http://www.w3.org/1999/xlink" +start = +  element document { +    element head { +      (br +       | meta +       | element creator { +           attribute class { xsd:NCName }, +           (text +            | element link { +                attribute xl:href { xsd:anyURI }, +                attribute xl:type { xsd:NCName }, +                xsd:anyURI +              })+ +         } +       | element date { +           attribute class { xsd:NCName }, +           xsd:NMTOKEN +         } +       | element date_available { +           attribute class { xsd:NCName }, +           xsd:NMTOKEN +         } +       | element date_created { +           attribute class { xsd:NCName }, +           xsd:NMTOKEN +         } +       | element date_issued { +           attribute class { xsd:NCName }, +           xsd:NMTOKEN +         } +       | element date_modified { +           attribute class { xsd:NCName }, +           xsd:NMTOKEN +         } +       | element date_valid { +           attribute class { xsd:NCName }, +           xsd:NMTOKEN +         } +       | element keywords { +           attribute class { xsd:NCName }, +           text +         } +       | element language { +           attribute class { xsd:NCName }, +           xsd:NCName +         } +       | element meta { xsd:NMTOKEN } +       | element rights { +           attribute class { xsd:NCName }, +           (text | link)+ +         } +       | element source { +           attribute class { xsd:NCName }, +           text +         } +       | element structure { +           attribute class { xsd:NCName }, +           text +         } +       | element subject { +           attribute class { xsd:NCName }, +           text +         } +       | element title { +           attribute class { xsd:NCName }, +           text +         } +       | element type { +           attribute class { xsd:NCName }, +           text +         } +       | element source_control { +           (br +            | meta +            | element sc { +                attribute class { xsd:NCName }, +                text +              })+ +         })+ +    }, +    element body { +      element object { +        attribute id { text }, +        element ocn { +          text +        }, +        element text { +          attribute class { xsd:NCName }, +          (text +           | b +           | br +           | del +           | en +           | i +           | link +           | sub +           | sup +           | u +           | element image { +               attribute alt { text }?, +               attribute height { xsd:integer }?, +               attribute width { xsd:integer }?, +               attribute xl:actuate { xsd:NCName }, +               attribute xl:href { text }, +               attribute xl:show { xsd:NCName }, +               attribute xl:type { xsd:NCName } +             })+ +        }?, +        element table { +          attribute align { xsd:NCName }, +          attribute bgcolor { xsd:NCName }, +          attribute border { xsd:integer }, +          attribute cellpadding { xsd:integer }, +          attribute summary { text }, +          attribute width { text }, +          element tr { +            element td { +              attribute valign { xsd:NCName }, +              attribute width { text }, +              (text | b | i)+ +            }+ +          }+ +        }?, +        element endnote { +          attribute notenumber { xsd:integer }?, +          attribute symbol { text }?, +          (element number { xsd:integer } +           | element symbol { text }), +          element note { +            (text +             | b +             | br +             | del +             | i +             | link +             | sup +             | u +             | element em { xsd:NCName } +             | element sub { xsd:NCName })+ +          } +        }* +      }+ +    } +  } +meta = element meta { text } +br = element br { empty } +b = element b { (text | en | i | link | sup)+ } +i = element i { (text | b | br | sup)+ } +en = element en { text } +sub = element sub { xsd:NCName } +sup = element sup { xsd:NCName } +link = +  element link { +    attribute xl:href { xsd:anyURI }, +    attribute xl:type { xsd:NCName }, +    (xsd:anyURI | text | b | i | sup)+ +  } +u = element u { (text | b | i)+ } +del = element del { (text | b | i | link)+ } +RELAXNG +    end +    def rnc_model_output_dom +      @relaxng =<<RELAXNG +#% dom output model, part of SiSU and distributed under the same license +default namespace = "" +namespace xl = "http://www.w3.org/1999/xlink" +start = +  element document { +    element head { +      element header { +        meta, +        (element creator { text } +         | element date { xsd:NMTOKEN } +         | element date_available { xsd:NMTOKEN } +         | element date_created { xsd:NMTOKEN } +         | element date_issued { xsd:NMTOKEN } +         | element date_modified { xsd:NMTOKEN } +         | element date_valid { xsd:NMTOKEN } +         | element keywords { text } +         | element language { xsd:NCName } +         | element rights { (text | link)+ } +         | element source { text } +         | element structure { text } +         | element subject { text } +         | element title { text } +         | element type { text } +         | element source_control { +             (br +              | meta +              | element sc { +                  attribute class { xsd:NCName }, +                  text +                })+ +           }) +      }+ +    }, +    element body { +      element heading1 { +        heading, +        contents1*, +        element heading2 { +          heading, +          contents1*, +          element heading3 { +            heading, +            element contents1 { +              heading, +              content, +              element contents2 { +                heading, +                content, +                element contents3 { heading, content }* +              }* +            }+ +          }* +        }* +      }+ +    } +  } +meta = element meta { text } +br = element br { empty } +heading = element heading { object } +contents1 = +  element contents1 { +    heading, +    content, +    element contents2 { +      heading, +      content, +      element contents3 { heading, content }* +    }* +  } +content = element content { object* } +object = +  element object { +    attribute id { xsd:integer }, +    element ocn { text }, +    element nametag { text }?, +    (element table { +       attribute align { xsd:NCName }, +       attribute bgcolor { xsd:NCName }, +       attribute border { xsd:integer }, +       attribute cellpadding { xsd:integer }, +       attribute summary { text }, +       attribute width { text }, +       element tr { +         element td { +           attribute valign { xsd:NCName }, +           attribute width { text }, +           (text | b | i)+ +         }+ +       }+ +     } +     | element text { +         attribute class { xsd:NCName }?, +         (text +          | b +          | del +          | endnote +          | i +          | link +          | element br { empty } +          | element endnote { +              element number { xsd:integer }, +              element note { (text | i | link)+ } +            } +          | element image { +              attribute height { xsd:integer }, +              attribute width { xsd:integer }, +              attribute xl:actuate { xsd:NCName }, +              attribute xl:href { text }, +              attribute xl:show { xsd:NCName }, +              attribute xl:type { xsd:NCName } +            } +          | element sub { text })+ +       }) +  } +i = element i { text } +b = element i { text } +u = element u { (text | b | i)+ } +sub = element sub { xsd:NCName } +sup = element sup { xsd:NCName } +del = element del { (text | b | i | link)+ } +link = +  element link { +    attribute xl:href { xsd:anyURI }, +    attribute xl:type { xsd:NCName }, +    xsd:anyURI +  } +endnote = +  element endnote { +    (element number { xsd:integer } +     | element symbol { text }), +    element note { +      (text +       | b +       | br +       | del +       | i +       | link +       | sub +       | sup +       | u +       | element em { xsd:NCName } +       | element sub { xsd:NCName })+ +    } +  } +RELAXNG +    end +    def rnc_model_output_xhtml #not done +      @relaxng =<<RELAXNG +#% xhtml output model, part of SiSU and distributed under the same license +default namespace = "" +namespace xl = "http://www.w3.org/1999/xlink" +start = +  element document { +    element head { +      (br +       | element creator { +           attribute class { xsd:NCName }, +           (text +            | element link { +                attribute xl:href { xsd:anyURI }, +                attribute xl:type { xsd:NCName }, +                xsd:anyURI +              })+ +         } +       | element date { +           attribute class { xsd:NCName }, +           xsd:NMTOKEN +         } +       | element date_available { +           attribute class { xsd:NCName }, +           xsd:NMTOKEN +         } +       | element date_created { +           attribute class { xsd:NCName }, +           xsd:NMTOKEN +         } +       | element date_issued { +           attribute class { xsd:NCName }, +           xsd:NMTOKEN +         } +       | element date_modified { +           attribute class { xsd:NCName }, +           xsd:NMTOKEN +         } +       | element date_valid { +           attribute class { xsd:NCName }, +           xsd:NMTOKEN +         } +       | element language { +           attribute class { xsd:NCName }, +           xsd:NCName +         } +       | element keywords { +           attribute class { xsd:NCName }, +           text +         } +       | element meta { +           attribute content { text }?, +           attribute http-equiv { xsd:NCName }?, +           text +         } +       | element rights { +           attribute class { xsd:NCName }, +           (text | link)+ +         } +       | element source { +           attribute class { xsd:NCName }, +           text +         } +       | element structure { +           attribute class { xsd:NCName }, +           text +         } +       | element subject { +           attribute class { xsd:NCName }, +           text +         } +       | element title { +           attribute class { xsd:NCName }, +           text +         } +       | element type { +           attribute class { xsd:NCName }, +           xsd:NCName +         })+ +    }, +    element body { +      element object { +        attribute id { xsd:integer }, +        (element endnote { +           attribute notenumber { xsd:integer }?, +           attribute symbol { text }?, +           (text +            | b +            | br +            | del +            | i +            | link +            | sup +            | u +            | element em { xsd:NCName } +            | element sub { xsd:NCName })+ +         } +         | element ocn { text } +         | element text { +             attribute class { xsd:NCName }, +             (text +              | b +              | br +              | del +              | en +              | i +              | link +              | sup +              | u +              | element image { +                  attribute alt { text }?, +                  attribute height { xsd:integer }?, +                  attribute width { xsd:integer }?, +                  attribute xl:actuate { xsd:NCName }, +                  attribute xl:href { text }, +                  attribute xl:show { xsd:NCName }, +                  attribute xl:type { xsd:NCName } +                } +              | element sub { text })+ +           })+, +        element table { +          attribute align { xsd:NCName }, +          attribute bgcolor { xsd:NCName }, +          attribute border { xsd:integer }, +          attribute cellpadding { xsd:integer }, +          attribute summary { text }, +          attribute width { text }, +          element tr { +            element td { +              attribute valign { xsd:NCName }, +              attribute width { text }, +              (text | b | i)+ +            }+ +          }+ +        }? +      }+ +    } +  } +br = element br { empty } +en = element en { text } +sup = element sup { xsd:NCName } +i = element i { (text | b | br | sup)+ } +link = +  element link { +    attribute xl:href { xsd:anyURI }, +    attribute xl:type { xsd:NCName }, +    (text | b | i | sup)+ +  } +b = element b { (text | en | i | link | sup)+ } +u = element u { (text | b | i)+ } +del = element del { (text | b | i | link)+ } +RELAXNG +    end +    def rnc_model_input_sax +      @relaxng =<<RELAXNG +#% sax input model, part of SiSU and distributed under the same license +default namespace = "" +start = +  element document { +    element head { +      element header { +        attribute class { xsd:NCName }, +        (element creator { text } +         | element date { xsd:NMTOKEN } +         | element date.available { xsd:NMTOKEN } +         | element date.created { xsd:NMTOKEN } +         | element date.issued { xsd:NMTOKEN } +         | element date.modified { xsd:NMTOKEN } +         | element date.valid { xsd:NMTOKEN } +         | element italicize { text } +         | element language { xsd:NCName } +         | element links { text } +         | element markup { text } +         | element rights { text } +         | element subject { text } +         | element title { text } +         | element type { xsd:NCName } +         | element vocabulary { xsd:NCName }) +      }+ +    }, +    element body { +      element object { +        element text { +          attribute class { xsd:NCName }, +          (text +           | b +           | i +           | element endnote { +               attribute symbol { xsd:NCName }, +               (text +                | i +                | element br { empty })+ +             } +           | element u { i } +           | element image.path { text })+ +        }? +      }+ +    } +  } +i = element i { text } +b = element b { text } +RELAXNG +    end +    def rnc_model_input_dom +      @relaxng =<<RELAXNG +#% dom input model, part of SiSU and distributed under the same license +default namespace = "" +start = +  element document { +    element head { +      element header { +        attribute class { xsd:NCName }, +        (element creator { text } +         | element date { xsd:NMTOKEN } +         | element date.available { xsd:NMTOKEN } +         | element date.created { xsd:NMTOKEN } +         | element date.issued { xsd:NMTOKEN } +         | element date.modified { xsd:NMTOKEN } +         | element date.valid { xsd:NMTOKEN } +         | element italicize { text } +         | element language { xsd:NCName } +         | element links { text } +         | element markup { text } +         | element rights { text } +         | element subject { text } +         | element title { text } +         | element type { xsd:NCName } +         | element vocabulary { xsd:NCName }) +      }+ +    }, +    element body { +      element heading1 { +        heading, +        element heading2 { +          heading, +          contents1+, +          element heading3 { heading, contents1+ }+ +        } +      } +    } +  } +heading = element heading { object } +contents1 = +  element contents1 { +    heading, +    content, +    element contents2 { +      heading, +      content, +      element contents3 { heading, content }* +    }* +  } +object = +  element object { +    element text { +      (text +       | italic +       | element bold { xsd:NMTOKEN } +       | element endnote { +           element symbol { text }?, +           element note { +             (text +              | italic +              | element br { empty })+ +           } +         } +       | element underscore { italic } +       | element image.path { text } +       | element italic { text })+ +    } +  } +italic = element italic { text } +content = element content { object+ } +RELAXNG +    end +    def rnc_model_input_node +      @relaxng =<<RELAXNG +#% node input model, part of SiSU and distributed under the same license +default namespace = "" +start = +  element document { +    element head { +      element header { +        attribute class { xsd:NCName }, +        (element creator { text } +         | element date { xsd:NMTOKEN } +         | element date.available { xsd:NMTOKEN } +         | element date.created { xsd:NMTOKEN } +         | element date.issued { xsd:NMTOKEN } +         | element date.modified { xsd:NMTOKEN } +         | element date.valid { xsd:NMTOKEN } +         | element italicize { (text | i)+ } +         | element language { xsd:NCName } +         | element links { text } +         | element markup { text } +         | element rights { text } +         | element subject { text } +         | element title { text } +         | element type { xsd:NCName } +         | element vocabulary { xsd:NCName }) +      }+ +    }, +    element body { +      element object { +        (element text { +           attribute class { xsd:NCName }, +           (text +            | b +            | i +            | element br { empty } +            | element endnote { +                attribute symbol { xsd:NCName }, +                (text | i)+ +              } +            | element image.path { text } +            | element sub { text })+ +         } +         | (element ocn { empty }, +            element table { +              attribute align { xsd:NCName }, +              attribute bgcolor { xsd:NCName }, +              attribute border { xsd:integer }, +              attribute cellpadding { xsd:integer }, +              attribute summary { text }, +              attribute width { text }, +              element tr { +                element td { +                  attribute valign { xsd:NCName }, +                  attribute width { text }, +                  (text | b)+ +                }+ +              }+ +            })), +        element node { +          element id { xsd:integer }, +          element parent { xsd:integer }, +          element offspring { text }? +        } +      }+ +    } +  } +b = element b { text } +i = element i { text } +RELAXNG +    end +  end +end +__END__ +needs updating +#+END_SRC + +** remote.rb + +#+BEGIN_SRC ruby  :tangle "../lib/sisu/remote.rb" +# <<sisu_document_header>> +module SiSU_Remote +  require_relative 'se'                                 # se.rb +    include SiSU_Env +  class Put +    def initialize(opt) +      @opt=opt +      @dir=SiSU_Env::InfoEnv.new(@opt.fns) +      @put=(@opt.fns =~/\.ssm\.sst$/) \ +      ? opt.fns.gsub(/(.+)?\.ssm\.sst$/,'\1.ssm') +      : opt.fns +      @remote=SiSU_Env::InfoRemote.new(opt) +    end +    def rsync +      SiSU_Screen::Ansi.new( +        @opt.act[:color_state][:set], +        'Remote placement ->', +        @put +      ).dark_grey_title_hi unless @opt.act[:quiet][:set]==:on +      @remote.rsync.document +    end +    def rsync_base +      SiSU_Screen::Ansi.new( +        @opt.act[:color_state][:set], +        'Remote placement ->', +        'rsync' +      ).dark_grey_title_hi unless @opt.act[:quiet][:set]==:on +      @remote.rsync.site_base +    end +    def rsync_base_sync +      SiSU_Screen::Ansi.new( +        @opt.act[:color_state][:set], +        'Remote placement ->', +        'rsync and sync' +      ).dark_grey_title_hi unless @opt.act[:quiet][:set]==:on +      @remote.rsync.site_base_sync +    end +    def rsync_sitemaps +      SiSU_Screen::Ansi.new( +        @opt.act[:color_state][:set], +        'Remote placement sitemaps ->', +        'rsync' +      ).dark_grey_title_hi unless @opt.act[:quiet][:set]==:on +      @remote.rsync_sitemaps +    end +    def rsync_harvest +      SiSU_Screen::Ansi.new( +        @opt.act[:color_state][:set], +        'Remote placement metadata harvest ->', +        'rsync_harvest' +      ).dark_grey_title_hi unless @opt.act[:quiet][:set]==:on +      @remote.rsync.site_harvest +    end +    def scp +      SiSU_Screen::Ansi.new( +        @opt.act[:color_state][:set], +        'Remote placement ->', +        @put +      ).dark_grey_title_hi unless @opt.act[:quiet][:set]==:on +      @remote.scp.document +    end +    def scp_base +      SiSU_Screen::Ansi.new( +        @opt.act[:color_state][:set], +        'Remote placement of base site ->', +        'excluding images' +      ).dark_grey_title_hi unless @opt.act[:quiet][:set]==:on +      @remote.scp.site_base +    end +    def scp_base_all +      SiSU_Screen::Ansi.new( +        @opt.act[:color_state][:set], +        'Remote placement ->', +        'complete' +      ).dark_grey_title_hi unless @opt.act[:quiet][:set]==:on +      @remote.scp.site_base_all +    end +  end +  class Get +    def initialize(opt,get_s) +      @opt,@get_s=opt,get_s +      @msg,@msgs='',nil +      @tell=lambda { +        SiSU_Screen::Ansi.new(@opt.act[:color_state][:set], +        @msg, +        "#{@msgs.inspect if @msgs}") +      } +    end +    def fns +      begin +        require 'open-uri' +        require 'pp' +      rescue LoadError +        SiSU_Utils::CodeMarker.new(__LINE__,__FILE__,:fuchsia). +          error('open-uri or pp NOT FOUND (LoadError)') +      end +      require_relative 'ao_composite'                   # ao_composite.rb +      @rgx_image=/(?:^|[^_\\])\{\s*(\S+?\.(?:png|jpg|gif))/ +      threads=[] +      for requested_page in @get_s +        re_fnb=/((?:https?|file):\/\/[^\/ ]+?\/[^\/ ]+?)\/\S+?\/([^\/]+?)\.ss(t)/ #revisit and remove DO +        threads << Thread.new(requested_page) do |url| +          open(url) do |f| +            raise "#{url} not found" unless f +            base_uri,fnb=re_fnb.match(url)[1..2] if re_fnb +            imagedir=base_uri + '/_sisu/image' #check on +            downloaded_file=File.new("#{fnb}.-sst",'w+') +            image_download_url=SiSU_Assemble::RemoteImage.new.image(imagedir) +            images=[] +            f.collect.each do |r|                            # work area +              unless r =~/^%+\s/ +                if r !~/^%+\s/ \ +                and r =~@rgx_image +                  images << r.scan(@rgx_image).uniq +                end +              end +              downloaded_file << r +            end +            if images \ +            and images.length > 1 +              images=images.flatten.uniq +              images.delete_if {|x| x =~/https?:\/\// } +              images=images.sort +              @msg,@msgs='downloading images:', [ images.join(',') ] +              @tell.call.warn unless @opt.act[:quiet][:set]==:on +              image_info=image_download_url + images +              SiSU_Assemble::RemoteImage.new.download_images(image_info) +              #SiSU_Assemble::RemoteImage.new.download_images(image_download_url,images) +              @msg,@msgs='downloading done',nil +              @tell.call.warn unless @opt.act[:quiet][:set]==:on +            end +            downloaded_file.close +          end +        end +      end +      threads.each {|thr| thr.join} if threads #and threads.length > 0 +    end +    def sisupod +      get_p=@get_s +      if get_p.length > 0                                     #% remote sisupod +        begin +          require 'net/http' +        rescue LoadError +          SiSU_Utils::CodeMarker.new(__LINE__,__FILE__,:fuchsia). +            error('net/http NOT FOUND (LoadError)') +        end +        for requested_pod in get_p +          pod_info=RemoteDownload.new(requested_pod) +          Net::HTTP.start(pod_info.pod.site) do |http| +            resp=http.get("#{pod_info.pod.path}/#{pod_info.pod.name_source}") +            open(pod_info.pod.name,'wb') do |file| +              file.write(resp.body) +             end +          end +        end +      end +    end +  end +  class RemoteDownload +    def initialize(requested_file) +      @requested_file=requested_file +    end +    def pod +      re_p_div=/https?:\/\/([^\/]+)(\/\S+)\/(sisupod\.(?:txz|zip)|\S+?(?:\.ss[mt]\.(?:txz|zip))?|[^\/]+?\.ssp)$/ +      re_p=/(sisupod\.(?:txz|zip)|\S+?\.ss[mt]\.(?:txz|zip)?|[^\/]+?\.ssp)$/ +      if @requested_file =~ re_p_div +        @site,@pth,@pod= re_p_div.match(@requested_file).captures +      elsif @requested_file =~ re_p +        @pod=re_p.match(@requested_file).captures.join +      end +      def site +        @site +      end +      def path +        @pth +      end +      def dir_stub +        re_p_stub=/.+?([^\/]+)$/ +        re_p_stub.match(path).captures.join if path +      end +      def name_source +        @pod +      end +      def name +        name_source +      end +      self +    end +  end +end +__END__ +#+END_SRC + +** rexml.rb + +#+BEGIN_SRC ruby  :tangle "../lib/sisu/rexml.rb" +# <<sisu_document_header>> +module SiSU_Rexml +  # load XML file for REXML parsing +  begin +    require 'rexml/document' \ +      if FileTest.directory?("#{RbConfig::CONFIG['rubylibdir']}/rexml") #RbConfig::CONFIG['sitedir'] +  rescue LoadError +    SiSU_Utils::CodeMarker.new(__LINE__,__FILE__,:fuchsia). +      error('rexml/document NOT FOUND (LoadError)') +  end +  require_relative 'dp'                                 # dp.rb +    include SiSU_Param +  require_relative 'se'                                 # se.rb +    include SiSU_Env +  class Rexml +    begin +      require 'rexml/document' \ +        if FileTest.directory?("#{RbConfig::CONFIG['rubylibdir']}/rexml") #RbConfig::CONFIG['sitedir'] +    rescue LoadError +      SiSU_Utils::CodeMarker.new(__LINE__,__FILE__,:fuchsia). +        error('rexml/document NOT FOUND (LoadError)') +    end +    def initialize(md,fno) +      @md,@fno=md,fno +      @env=SiSU_Env::InfoEnv.new(@md.fns) +      @prog=SiSU_Env::InfoProgram.new #(md.fns) #if md +      if File.file?(@fno) +        @fnap=@fno #index.xml causes problems with index.html in server config +      end +      @e_head='/document/head' +      @e_title='/document/head/title' +      @e_object='/document/body/object' +      @e_ocn='/document/body/object/ocn' +      @e_text='/document/body/object/text' +      @e_endnote='/document/body/object/endnote' +    end +    def xml +      begin +        if FileTest.file?(@fnap) +          if @prog.rexml !=false \ +          and FileTest.directory?('/usr/lib/ruby/1.8/rexml/') #note values can be other than true +            xmlfile=IO.readlines(@fnap,'').join +            begin +              @xmldoc=REXML::Document.new xmlfile +              SiSU_Screen::Ansi.new( +                @md.opt.act[:color_state][:set], +                'invert', +                'REXML', +                "XML document #{@fnap} loaded" +              ).colorize unless @md.opt.act[:quiet][:set]==:on +              if (@opt.act[:verbose][:set]==:on \ +              || @opt.act[:verbose_plus][:set]==:on) +                @xmldoc.elements.each(@e_head) do |e| +                  SiSU_Screen::Ansi.new( +                    @md.opt.act[:color_state][:set], +                    'brown', +                    e +                  ).colorize unless @md.opt.act[:quiet][:set]==:on +                end +              end +            rescue REXML::ParseException +              puts 'broken XML' +            end +          end +        else +          SiSU_Screen::Ansi.new( +            @md.opt.act[:color_state][:set], +            'fuchsia', +            "File Not Found #{xmlfile}", +            'requested XML processing skipped' +          ).colorize unless @md.opt.act[:quiet][:set]==:on +          exit +        end +      rescue +        SiSU_Errors::Rescued.new($!,$@,@md.opt.selections.str,@md.fns).location do +          __LINE__.to_s + ':' + __FILE__ +        end +      ensure +      end +    end +  end +end +__END__ + misc +e.each do |element| +  element.each do |child| +    if child.is_a?(REXML::Text) +      puts "Text: #{child.to_s.inspect}" +    else +      puts "SubElement: #{child.name}" +    end +  end +end +#+END_SRC + +** sitemaps.rb + +#+BEGIN_SRC ruby  :tangle "../lib/sisu/sitemaps.rb" +# <<sisu_document_header>> +module SiSU_Sitemaps +  require_relative 'dp'                                 # dp.rb +    include SiSU_Param +  require_relative 'se'                                 # se.rb +    include SiSU_Env +  require_relative 'xml_shared'                         # xml_shared.rb +    include SiSU_XML_Munge +  class Source +    def initialize(opt) +      @opt=opt +    end +    def read +      songsheet +    end +    def songsheet +      begin +        @sys=SiSU_Env::SystemCall.new +        fn_set_lang=SiSU_Env::StandardiseLanguage.new(@opt.lng).language +        @fn=SiSU_Env::EnvCall.new(@opt.fns).lang(fn_set_lang[:c]) +        if @opt.act[:sitemap][:set]==:on +          @md=SiSU_Param::Parameters.new(@opt).get +          @trans=SiSU_XML_Munge::Trans.new(@md) #check @md is required +          @env=SiSU_Env::InfoEnv.new(@md.fns) +#         @file=SiSU_Env::FileOp.new(@md) +          @rdf=SiSU_XML_Tags::RDF.new(@md) +          @fnb_utf8_xml=@md.fnb.dup +          @trans.char_enc.utf8(@fnb_utf8_xml) \ +            if @sys.locale =~/utf-?8/i +          output_map(sitemap) +        elsif @opt.selections.str =~/--sitemaps/ +          @sitemap_idx_fn='sitemapindex.xml' +          @env=SiSU_Env::InfoEnv.new +          output_idx(sitemap_index) +          SiSU_Screen::Ansi.new( +            @opt.act[:color_state][:set], +            'sitemap index:', +            "#{@env.path.output}/#{@sitemap_idx_fn}" +          ).result unless @opt.act[:quiet][:set]==:on +        end +      rescue +        SiSU_Errors::Rescued.new($!,$@,@opt.cmd,@opt.fns).location do +          __LINE__.to_s + ':' + __FILE__ +        end +      ensure +      end +    end +    def make_file(path,filename) +      (File.writable?("#{path}/.")) \ +      ? (File.new("#{path}/#{filename}",'w+')) +      : (SiSU_Screen::Ansi.new( +           '', +           "is the file or directory writable?, could not create #{filename}" +         ).warn) +    end +    def output_map(sitemap) +      path=@md.file.output_path.sitemaps.dir +      filename=@fn[:sitemap] +      touch_path=@md.file.output_path.sitemaps.dir +      touch_filename=@fn[:sitemap_touch] +      SiSU_Env::FileOp.new(@md).make_path(path) +      file=SiSU_Env::FileOp.new(@md).make_file(path,filename) +      file << sitemap +      if FileTest.file?("#{touch_path}/#{touch_filename}") +        FileUtils::rm("#{touch_path}/#{touch_filename}") +      end +    end +    def output_idx(sitemap) +      path=@env.path.output +      filename=@sitemap_idx_fn +      make_path(path) +      file=make_file(path,filename) +      file << sitemap +    end +    def sitemap_index +      sitemap_files=Dir.glob("#{@env.path.sitemaps}/sitemap_*.xml") +      sitemap_idx=[] +      sitemap_idx << <<WOK +<?xml version="1.0" encoding="UTF-8"?> +<sitemapindex xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" +   xsi:schemaLocation="http://www.sitemaps.org/schemas/sitemaps/0.9 +   http://www.sitemaps.org/schemas/sitemaps/sitemap.xsd" +     xmlns="http://www.sitemaps.org/schemas/sitemapindex/0.9"> +WOK +      sitemap_files.each do |s| +        f=s.gsub(/.+?\/sitemap_([^\/]+?)\.xml$/,'\1') +        @trans.char_enc.utf8(f) \ +          if @sys.locale =~/utf-?8/i +sitemap_idx << <<WOK +  <sitemap> +    <loc>#{@env.path.url.remote}/#{f}/sitemap.xml</loc> +  </sitemap> +WOK +      end +      sitemap_idx << <<WOK +</sitemapindex> +WOK +      sitemap_idx.join +    end +    def sitemap +      if defined? @md.date.modified \ +      and @md.date.modified=~/\d{4}-\d{2}-\d{2}/ +        sitemap_date_modified +      else sitemap_no_date +      end +    end +    def sitemap_date_modified +<<WOK +<?xml version='1.0' encoding='UTF-8'?> +<urlset xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" +  xsi:schemaLocation="http://www.sitemaps.org/schemas/sitemaps/0.9 +  http://www.sitemaps.org/schemas/sitemaps/sitemap.xsd" +  xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"> +#{@rdf.comment_xml} +  <url> +    <loc>#{@env.path.url.remote}/#{@fnb_utf8_xml}/#{@fn[:toc]}</loc> +    <lastmod>#{@md.date.modified}</lastmod> +    <changefreq>monthly</changefreq> +    <priority>0.7</priority> +  </url> +  <url> +    <loc>#{@env.path.url.remote}/#{@fnb_utf8_xml}/#{@fn[:doc]}</loc> +    <lastmod>#{@md.date.modified}</lastmod> +    <priority>0.5</priority> +  </url> +  <url> +    <loc>#{@env.path.url.remote}/#{@fnb_utf8_xml}/#{@fn[:manifest]}</loc> +    <lastmod>#{@md.date.modified}</lastmod> +    <priority>0.5</priority> +  </url> +</urlset> +WOK +    end +    def sitemap_no_date +<<WOK +<?xml version="1.0" encoding="UTF-8"?> +<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"> +#{@rdf.comment_xml} +  <url> +    <loc>#{@env.path.url.remote}/#{@fnb_utf8_xml}/#{@fn[:toc]}</loc> +    <changefreq>monthly</changefreq> +    <priority>0.7</priority> +  </url> +  <url> +    <loc>#{@env.path.url.remote}/#{@fnb_utf8_xml}/#{@fn[:doc]}</loc> +    <priority>0.5</priority> +  </url> +  <url> +    <loc>#{@env.path.url.remote}/#{@fnb_utf8_xml}/#{@fn[:manifest]}</loc> +    <priority>0.5</priority> +  </url> +</urlset> +WOK +    end +  end +end +__END__ +,* sanitize xml, pass through filter to ensure is valid - done but needs testing +,* remote placement of sitemaps --sitemaps -R (probably makes more sense than doing against -Y [filename/wildcard]) - done but needs testing +,* gzip sitemaps - not before testing / after testing +,* issue with master documnts, naming and mapping, check multilingual + +<!-- Document processing information: +     * Generated by: SiSU 0.48.6 of 2006w45/6 (20061111) +     * Ruby version: ruby 1.8.5 (2006-08-25) [i486-linux] +     * +     * Last Generated on: Sat Nov 18 15:28:08 +0000 2006 +     * SiSU http://www.jus.uio.no/sisu +--> +#+END_SRC + +** termsheet.rb + +#+BEGIN_SRC ruby  :tangle "../lib/sisu/termsheet.rb" +# <<sisu_document_header>> +require_relative 'se'                                   # se.rb +require_relative 'dp'                                   # dp.rb +  include SiSU_Param +@do,@done,@used,@html_output,@txt_input,@txt_output,@@report=Array.new(7){[]} +@@info=nil +@c=0 +@cX=SiSU_Screen::Ansi.new('yes').cX +@done << "\n#{@cX.blue_hi}#{@cX.black}Summary#{@cX.off*2}" +def talent(termsheet,flag) +  @@info=nil +  @@info=termsheet.gsub(/(.+?)\.termsheet\.rb/,'../facility_data/\1.html') +  @env=SiSU_Env::InfoEnv.new +  @dir_fd="#{@env.path.output}/facility_data" +  FileUtils::mkdir_p(@dir_fd) unless FileTest.directory?(@dir_fd)==true +  html_output=[] +  case termsheet +  when /.+?\.(termsheet)\.rb$/ +    @basename=termsheet[/(.+?)\.termsheet\.rb/, 1] +    @standard_form={} +    require termsheet +    include Termsheet +    @standard_form=Termsheet::StandardForms.new.standardforms +    puts %{\n#{@@cX.yellow_hi}#{@@cX.black}From#{@@cX.off*2}: #{@@cX.grey_hi}#{@@cX.black}#{@basename}.termsheet.rb#{@@cX.off*3}\n\n} +    @standard_form.each do |k,v| +      @c+=1 +      require v +      puts %{\n#{@@cX.blue_hi}#{@@cX.black}Producing the following#{@@cX.off*2}: #{@@cX.green}#{@basename}.#{k}#{@@cX.off}\n\n} +      @done << %{\n\t#{@@cX.grey}Documents generated#{@@cX.off}: #{@@cX.cyan}#{@basename}.#{k}#{@@cX.off}\n} +      @used << %{\n\t#{@@cX.grey}Using#{@@cX.off}: #{@@cX.ruby}#{v}#{@@cX.off}\n} +      html_output=<<WOK +<br /><a href="../#{@basename}.#{k}/landscape.pdf"> +<img border="0" width="18" height="15" src="../_sisu/image/b_pdf.png" alt="pdf landscape"></a>  +<a href="../#{@basename}.#{k}/portrait.pdf"> +<img border="0" width="15" height="18" src="../_sisu/image/b_pdf.png" alt="pdf portrait"></a>  +<a href="../#{@basename}.#{k}/sisu_manifest.html">#{@basename}.#{k}.sisu_manifest.html</a> +WOK +      @html_output << html_output +      @txt_input << %{\n\tForm #{@c}: <url:#{Dir.pwd}/#{v}>\n\t        |#{Dir.pwd}/#{v}|@|^|\n} +      @txt_output << %{\n\t#{k}: |../#{@basename}.#{k}/sisu_manifest.html|@|^|\n} +      @report_file_i=File.new("#{@dir_fd}/#{@basename}.txt",'w+') +      @report_file_o=File.new("#{@dir_fd}/#{@basename}.html",'w+') +      @filename_new=File.new("#{@basename}.#{k}.sst",'w+') +      @do << %{#{k}} +      @filename_new << @document +        # "require v" pulls in the composite @document +        # "termsheet" having all the variables required to complete the standard form @document +      @filename_new.close +    end +    @do.each do |x| +      system %{sisu -Nhwpo #{@basename}.#{x}.sst\n} +    end +  else print "not processed --> ", termsheet, "\n" +  end +  @done << %{\n\t#{@@cX.green}Summary:#{@@cX.off} #{@@cX.blue}#{@env.path.output}/facility_data/#{@basename}.html#{@@cX.off}\n} +  @done << %{\n\t#{@@cX.grey}From details provided in#{@@cX.off}: #{@@cX.green}#{termsheet}#{@@cX.off}\n} +  terms=%{\nTermsheet: <url:#{Dir.pwd}/#{termsheet}>\n           |#{Dir.pwd}/#{termsheet}|@|^|\n} +  @report_file_i << "<url:all.txt>\n|all.txt|@|^|\n" << terms << "\nForms:\n" << @txt_input  << "\nOutput Files\n" << @txt_output +  @report_file_o << %{<a href="toc.html">^</a><br />\n} << @html_output +  @@report << @done << @used << "\n" +  @done,@used=[],[] +end +require_relative 'dp'                                   # dp.rb +@argv=$* +@proc="#{@argv[0].to_s}" +if @proc =~  /^-?[wft]/ +  @argv.shift +  @argv.each do |termsheet| +    talent(termsheet,@proc) +  end +end +@env=SiSU_Env::InfoEnv.new +@dir_fd="#{@env.path.output}/facility_data" +@url="#{@env.url.webserv}/facility_data" +@@report << %{\n#{@@cX.grey}See#{@@cX.off}: #{@@cX.blue}#{@dir_fd}/all.txt\t#{@dir_fd}/toc.html\t#{@dir_fd}/#{@@cX.off}\n\n#{@@cX.grey}See#{@@cX.off}: #{@@cX.blue}#{@url}/all.txt\t#{@url}/toc.html\t#{@url}/#{@@cX.off}\n\n} +puts @@report +File.unlink("#{@dir_fd}/all.txt") if FileTest.file?("#{@dir_fd}/all.txt") +File.unlink("#{@dir_fd}/toc.html") if FileTest.file?("#{@dir_fd}/toc.html") +summary_file=File.new("#{@dir_fd}/all.txt",'w+') +summary_html=File.new("#{@dir_fd}/toc.html",'w+') +ls_txt=%x{ls #{@dir_fd}/*.txt} +report_thlnk=[] +ls_txt.scan(/.+/) +ls_txt.each {|x| report_thlnk << x.gsub!(/#{@dir_fd}\/(.+)/,"<url:\\1>\n|\\1|@|^|")} +report_thlnk.join("\n") +ls_html=%x{ls #{@dir_fd}/*.html} +report_html=[] +ls_html.split(/.+/) +ls_html.each {|x| report_html << x.gsub!(/#{@dir_fd}\/(.+)/,'<a href="\1">\1</a><br />')} +report_html.join("\n") +summary_file << "#{report_thlnk}" +summary_html << "#{report_html}" +__END__ +,** NOTE wrapper makes little sense without additional components, additional +   sample files must be provided - (saved till later as may confuse) +,*** bits +sisu -t x_bank.and.* +e.g. sisu -t x_bank.and.*.termsheet.rb +e.g. sisu_termsheet.rb -t x_bank.and.c*.termsheet.rb +program calls upon termsheet file with extension termsheet.rb +termsheet.rb calls upon relevant standard form files (to be used) with extension .sForm.rb +there is also a standard_terms.rb file - with terms/details that are  constant +the file produced is named after the termsheet.rb with that extension replaced with .er30 +from there scribbler.rb is called upon its usual metaVerse html and pdf  creation +! :-) +to test run +termsheet.rb -f dev.export.import.trade.facility.termsheet.rb +the term sheet calls the standard form or template that is to be run against it. +#+END_SRC + +** update.rb + +#+BEGIN_SRC ruby  :tangle "../lib/sisu/update.rb" +# <<sisu_document_header>> +module SiSU_UpdateControlFlag +  require_relative 'se'                                 # se.rb +    include SiSU_Env +  include SiSU_Param +  class Check +    def initialize(opt) +      @opt=opt +      @md=SiSU_Param::Parameters.new(@opt).get +    end +    def read +      begin +        @env=SiSU_Env::InfoEnv.new(@md.fns) +        out=@env.path.output +        base_path="#{out}/#{@md.fnb}" +        SiSU_Screen::Ansi.new( +          @md.opt.act[:color_state][:set], +          'Checking previous output', +          base_path +        ).green_hi_blue unless @md.opt.act[:quiet][:set]==:on +        SetCF.new(@md).set_flags +      rescue +        SiSU_Errors::Rescued.new($!,$@,@md.opt.selections.str,@md.fns).location do +          __LINE__.to_s + ':' + __FILE__ +        end +      ensure +      end +    end +    private +    class SetCF +      def initialize(md) +        @md=md +        @env=SiSU_Env::InfoEnv.new(@md.fns) +        out=@env.path.output +        @base_path="#{out}/#{@md.fnb}" +        @pdf_fn=SiSU_Env::FileOp.new(@md).base_filename +      end +      def set_flags #-mNhwpoabxXyv +        flag='-v' +        if FileTest.file?("#{@md.file.output_path.txt.dir}/#{@md.file.base_filename.txt}")==true +          flag=flag + 'a' +        end +        if FileTest.file?("#{@md.file.output_path.html_seg.dir}/#{@md.file.base_filename.html_seg}")==true \ +        or FileTest.file?("#{@md.file.output_path.html_scroll.dir}/#{@md.file.base_filename.html_scroll}")==true +          flag=flag + 'h' +        end +        if FileTest.file?("#{@md.file.output_path.xhtml.dir}/#{@md.file.base_filename.xhtml}")==true +          flag=flag + 'b' +        end +        if FileTest.file?("#{@md.file.output_path.xml_sax.dir}/#{@md.file.base_filename.xml_sax}")==true +          flag=flag + 'x' +        end +        if FileTest.file?("#{@md.file.output_path.xml_dom.dir}/#{@md.file.base_filename.xml_dom}")==true +          flag=flag + 'X' +        end +        if FileTest.file?("#{@md.file.output_path.epub.dir}/#{@md.file.base_filename.epub}")==true +          flag=flag + 'e' +        end +        if FileTest.file?("#{@md.file.output_path.odt.dir}/#{@md.file.base_filename.odt}")==true +          flag=flag + 'o' +        end +        if FileTest.file?("#{@md.file.output_path.pdf.dir}/#{@pdf_fn.pdf_p_a4}")==true \ +        or FileTest.file?("#{@md.file.output_path.pdf.dir}/#{@pdf_fn.pdf_l_a4}")==true \ +        or FileTest.file?("#{@md.file.output_path.pdf.dir}/#{@pdf_fn.pdf_p_letter}")==true \ +        or FileTest.file?("#{@md.file.output_path.pdf.dir}/#{@pdf_fn.pdf_l_letter}")==true +          flag=flag + 'p' +        end +        if FileTest.file?("#{@md.file.output_path.html_concordance.dir}/#{@md.file.base_filename.html_concordance}")==true +          flag=flag + 'w' +        end +        if FileTest.file?("#{@md.file.output_path.digest.dir}/#{@md.file.base_filename.digest}")==true +          flag=flag + 'N' +        end +        if FileTest.file?("#{@md.file.output_path.src.dir}/#{@md.file.base_filename.src}")==true +          flag=flag + 's' +        end +        if FileTest.file?("#{@md.file.output_path.sisupod.dir}/#{@md.file.base_filename.sisupod}")==true +          flag=flag + 'S' +        end +        puts flag +        flag +      end +    end +  end +end +__END__ +#+END_SRC + +** urls.rb + +#+BEGIN_SRC ruby  :tangle "../lib/sisu/urls.rb" +# <<sisu_document_header>> +module SiSU_Urls +  require_relative 'se_hub_particulars'                 # se_hub_particulars.rb +    include SiSU_Particulars +  require_relative 'se'                                 # se.rb +    include SiSU_Env; include SiSU_Screen +  class Source +    attr_reader :opt +    def initialize(opt) +      @opt=opt +    end +    def read +      begin +        SiSU_Urls::OutputUrls.new(@opt).songsheet if @opt.fnb +      rescue +        SiSU_Errors::Rescued.new($!,$@,@opt.selections.str).location do +          __LINE__.to_s + ':' + __FILE__ +        end +      ensure +      end +    end +  end +  class OutputUrls +    attr_reader :fns,:fnb,:act,:dir,:m_regular,:u +    def initialize(opt) +      @opt=opt +      @particulars=SiSU_Particulars::CombinedSingleton.instance.get_env_md(opt) +      if @particulars.is_a?(NilClass) +        if @opt.act[:verbose_plus][:set]==:on \ +        or @opt.act[:maintenance][:set]==:on +          SiSU_Utils::CodeMarker.new(__LINE__,__FILE__,:fuchsia). +            mark("@particulars is NilClass, acceptable e.g. for --harvest") +        end +        exit +      end +      @selections=@opt.selections.str +      @act=@opt.act +      @md=@particulars.md +      @env=@particulars.env +      @fnb=@env.fnb +      fn_set_lang=SiSU_Env::StandardiseLanguage.new(@opt.lng).language +      @fnl=@env.i18n.lang_filename(fn_set_lang[:c]) +      @fn=SiSU_Env::EnvCall.new(@opt.fns).lang(fn_set_lang[:c]) +      @m_regular=/(.+?)\.(?:(?:-|ssm\.)?sst|ssm)$/ +      @prog=@env.program +    end +    def songsheet +      begin +        (@opt.act[:urls_all][:set]==:on) \ +        ? urls_all \ +        : (urls_select unless @opt.act[:quiet][:set]==:on) +      rescue +        SiSU_Errors::Rescued.new($!,$@,@opt.selections.str,@opt.fns).location do +          __LINE__.to_s + ':' + __FILE__ +        end +      ensure +      end +    end +    def show +      def report(x) +        SiSU_Screen::Ansi.new( +          @opt.act[:color_state][:set], +          "[#{@opt.f_pth[:lng_is]}]", +          x[:cmd], +          x[:viewer] + ' ' \ +          + x[:f_pth] +        ).result +      end +      def maintenance(x) +        if @opt.act[:maintenance][:set]==:on +          SiSU_Screen::Ansi.new( +            @opt.act[:color_state][:set], +            "[#{@opt.f_pth[:lng_is]}]", +            x[:cmd], +            x[:p_pth] +          ).maintenance +        end +      end +      self +    end +    def report_info +      def dal +        { +          cmd: '--ao', +          p_pth: @env.processing_path.ao + '/' \ +          + @opt.fns + '.meta', +          fn: 'ao', +         } +      end +      def hash_digests +        { +          cmd: '--hash-digests (sha512/sha256/md5)', +          viewer: @prog.web_browser, +          f_pth: @md.file.output_path.hash_digest.dir + '/' \ +          + @md.file.base_filename.hash_digest, +          fn: @fn[:digest], +         } +      end +      def text +        def txt +          { +            cmd: '--txt', +            viewer: @prog.web_browser, +            f_pth: @md.file.output_path.txt.dir + '/' \ +            + @md.file.base_filename.txt, +            fn: @fn[:plain], +           } +        end +        def asciidoc +          { +            cmd: '--asciidoc', +            viewer: @prog.web_browser, +            f_pth: @md.file.output_path.asciidoc.dir + '/' \ +            + @md.file.base_filename.asciidoc, +            fn: @fn[:txt_asciidoc], +           } +        end +        def markdown +          { +            cmd: '--markdown', +            viewer: @prog.web_browser, +            f_pth: @md.file.output_path.markdown.dir + '/' \ +            + @md.file.base_filename.markdown, +            fn: @fn[:txt_markdown], +           } +        end +        def rst +          { +            cmd: '--rst', +            viewer: @prog.web_browser, +            f_pth: @md.file.output_path.rst.dir + '/' \ +            + @md.file.base_filename.rst, +            fn: @fn[:txt_rst], +           } +        end +        def textile +          { +            cmd: '--textile', +            viewer: @prog.web_browser, +            f_pth: @md.file.output_path.textile.dir + '/' \ +            + @md.file.base_filename.textile, +            fn: @fn[:txt_textile], +           } +        end +        def orgmode +          { +            cmd: '--orgmode', +            viewer: @prog.web_browser, +            f_pth: @md.file.output_path.orgmode.dir + '/' \ +            + @md.file.base_filename.orgmode, +            fn: @fn[:txt_orgmode], +           } +        end +        self +      end +      def html +        def seg +          { +            cmd: '--html-seg', +            viewer: @prog.web_browser, +            f_pth: @md.file.output_path.html_seg.dir + '/' \ +            + @md.file.base_filename.html_segtoc, +            p_pth: @env.processing_path.tune + '/' \ +            + @md.fns + '.tune', +            fn: @fn[:toc], +           } +        end +        def scroll +          { +            cmd: '--html-scroll', +            viewer: @prog.web_browser, +            f_pth: @md.file.output_path.html_scroll.dir + '/' \ +            + @md.file.base_filename.html_scroll, +            p_pth: @env.processing_path.tune + '/' \ +            + @md.fns + '.tune', +            fn: @fn[:doc], +           } +        end +        def concordance +          { +            cmd: '--concordance', +            viewer: @prog.web_browser, +            f_pth: @md.file.output_path.html_concordance.dir + '/' \ +            + @md.file.base_filename.html_concordance, +            fn: @fn[:concordance], +           } +        end +        self +      end +      def xhtml +        def xhtml +          { +            cmd: '--xhtml', +            viewer: @prog.web_browser, +            f_pth: @md.file.output_path.xhtml.dir + '/' \ +            + @md.file.base_filename.xhtml, +            p_pth: @env.processing_path.tune + '/' \ +            + @md.fns + '.tune', +            fn: @fn[:xhtml], +           } +        end +        def epub +          { +            cmd: '--epub', +            viewer: @prog.epub_viewer, +            f_pth: @md.file.output_path.epub.dir + '/' \ +            + @md.file.base_filename.epub, +            p_pth: @env.processing_path.epub + '/' \ +            + Ep[:d_oebps] + '/' \ +            + 'index.xhtml', +            fn: @fn[:epub], +           } +        end +        self +      end +      def xml +        def odt +          { +            cmd: '--odt (ODF:ODT)', +            viewer: @prog.odf_viewer, +            f_pth: @md.file.output_path.odt.dir + '/' \ +            + @md.file.base_filename.odt, +            p_pth: @env.processing_path.odf + '/' \ +            + @opt.fns + '/' \ +            + 'odt/content.xml', +            fn: @fn[:odf], +           } +        end +        def docbook +          { +            cmd: '--docbook', +            viewer: @prog.web_browser, +            f_pth: @md.file.output_path.xml_docbook_book.dir + '/' \ +            + @md.file.base_filename.xml_docbook_book, +            fn: @fn[:xml_docbook_book], +           } +        end +        def fictionbook +          { +            cmd: '--fictionbook', +            viewer: @prog.web_browser, +            f_pth: @md.file.output_path.xml_fictionbook.dir + '/' \ +            + @md.file.base_filename.xml_fictionbook, +            fn: @fn[:xml_fictionbook], +           } +        end +        def sax +          { +            cmd: '--xml-sax', +            viewer: @prog.web_browser, +            f_pth: @md.file.output_path.xml_sax.dir + '/' \ +            + @md.file.base_filename.xml_sax, +            fn: @fn[:sax], +           } +        end +        def dom +          { +            cmd: '--xml-dom', +            viewer: @prog.web_browser, +            f_pth: @md.file.output_path.xml_dom.dir + '/' \ +            + @md.file.base_filename.xml_dom, +            fn: @fn[:dom], +           } +        end +        def scaffold_sisu +          { +            cmd: '--xml-scaffold-sisu', +            viewer: @prog.web_browser, +            f_pth: @md.file.output_path.xml_scaffold_structure_sisu.dir + '/' \ +            + @md.file.base_filename.xml_scaffold_structure_sisu, +            fn: @fn[:xml_scaffold_structure_sisu], +           } +        end +        def scaffold_collapse +          { +            cmd: '--xml-scaffold-collapse', +            viewer: @prog.web_browser, +            f_pth: @md.file.output_path.xml_scaffold_structure_collapse.dir + '/' \ +            + @md.file.base_filename.xml_scaffold_structure_collapse, +            fn: @fn[:xml_scaffold_structure_collapse], +           } +        end +        self +      end +      def json +        { +          cmd: '--js (json)', +          viewer: @prog.web_browser, +          f_pth: @md.file.output_path.json.dir + '/' \ +          + @md.file.base_filename.json, +          fn: @fn[:json], +        } +      end +      def pdf +        def landscape +          { +            cmd: '--pdf (landscape)', +            viewer: @prog.pdf_viewer, +            f_pth: @md.file.output_path.pdf.dir + '/' \ +            + @md.file.base_filename.pdf_l \ +            + @md.papersize_array[0] + '.pdf', +            p_pth: @env.processing_path.tex + '/' \ +            + @opt.fns.gsub(/~/,'-') + '.' \ +            + @md.papersize_array[0] \ +            + '.landscape.tex', +            fn: @fn[:pdf_l], +           } +        end +        def portrait +          { +            cmd: '--pdf (portrait)', +            viewer: @prog.pdf_viewer, +            f_pth: @md.file.output_path.pdf.dir + '/' \ +            + @md.file.base_filename.pdf_p \ +            + @md.papersize_array[0] + '.pdf', +            p_pth: @env.processing_path.tex + '/' \ +            + @opt.fns.gsub(/~/,'-') + '.' \ +            + @md.papersize_array[0] \ +            + '.tex', +            fn: @fn[:pdf_p], +           } +        end +        self +      end +      def manpage +        { +          cmd: '--manpage', +          viewer: @prog.manpage_viewer, +          f_pth: @md.file.output_path.manpage.dir + '/' \ +          + @md.file.base_filename.manpage, +          fn: 'manpage', +         } +      end +      def texinfo +        { +          cmd: '--texinfo', +          viewer: '', +          f_pth: 'cd ' \ +          + @md.file.output_path.texinfo.dir + ' && ' \ +          + @env.program.texinfo + ' ' \ +          + @md.file.base_filename.info \ +          + '; cd -', +          fn: 'info', +         } +      end +      def db +        def psql +          { +            cmd: '--psql --update/--import', +            viewer: '', +            f_pth: @pwd_stub + '::' \ +            + @opt.fns \ +            + 'dbi psql', +            p_pth: @env.processing_path.postgresql + '/' \ +            + @md.fns \ +            + '.sql', +            fn: 'dbi psql', +           } +        end +        def sqlite +          { +            cmd: '--sqlite --update/--import', +            viewer: 'sqlite3 ', +            f_pth: @env.path.webserv + '/' \ +            + @md.opt.f_pth[:pth_stub] + '/' \ +            + 'sisu_sqlite.db', +            p_pth: @env.processing_path.sqlite + '/' \ +            + @md.fns \ +            + '.sql', +            fn: 'dbi sqlite3', +           } +        end +        def sqlite_discrete +          { +            cmd: '--sqlite', +            viewer: 'sqlite3 ', +            f_pth: @md.file.output_path.sqlite_discrete.dir + '/' \ +            + @md.file.base_filename.sqlite_discrete, +            p_pth: @env.processing_path.sqlite + '/' \ +            + @md.fns \ +            + '.sql', +            fn: 'dbi sqlite3', +           } +        end +        self +      end +      def po4a +        def po +          { +            cmd: '--po4a/--pot', +            viewer: @prog.web_browser, +            f_pth: @prog.text_editor + ' ' \ +            + @md.file.output_path.po.dir \ +            + '/' + y, +            fn: @fn[:pot], +           } +        end +        def pot +          { +            cmd: '--po4a/--pot', +            viewer: @prog.web_browser, +            f_pth: @prog.text_editor + ' ' \ +            + @md.file.output_path.pot.dir \ +            + '/' + y, +            fn: @fn[:pot], +           } +        end +        self +      end +      def source +        { +          cmd: '--source (sisu markup)', +          viewer: @prog.text_editor, +          f_pth: @md.file.output_path.src.dir + '/' \ +          + @opt.fno, +          p_pth: @md.file.output_path.src.dir + '/' \ +          + @opt.fno, +          fn: @opt.fno, +         } +      end +      def sisupod +        { +          cmd: '--sisupod', +          viewer: '', +          f_pth: @md.file.output_path.sisupod.dir + '/' \ +          + @opt.fno \ +          + '.txz', +          p_pth: @md.file.output_path.sisupod.dir + '/' \ +          + @opt.fno + '/' \ +          + 'sisupod/', +          fn: @fn[:sisupod], +         } +      end +      def ruby_profile +        { +          cmd: '--profile (ruby profiler)', +          fn: 'profile', +         } +      end +      def qrcode +        { +          cmd: '--qrcode', +          viewer: @prog.web_browser, +          f_pth: @md.file.output_path.manifest.dir + '/' \ +          + @md.file.base_filename.manifest, +          fn: @fn[:qrcode], +         } +      end +      def manifest +        { +          cmd: '--manifest', +          viewer: @prog.web_browser, +          f_pth: @md.file.output_path.manifest.dir + '/' \ +          + @md.file.base_filename.manifest, +          fn: @fn[:manifest], +         } +      end +      def sitemap +        { +          cmd: '--sitemap', +          viewer: @prog.web_browser, +          f_pth: @md.file.output_path.sitemaps.dir + '/' \ +          + @md.file.base_filename.sitemap, +          fn: @fn[:sitemap], +         } +      end +      self +    end +    def urls_select +      unless @opt.act[:quiet][:set]==:on +        i1='[' + @opt.f_pth[:lng_is] + ']' +        i2='file://' \ +        + @md.file.output_path.manifest.dir + '/' \ +        + @md.file.base_filename.manifest +        (@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], +            'URLs' +          ).green_title_hi +        : SiSU_Screen::Ansi.new( +            @opt.act[:color_state][:set], +            'URL (output manifest)', +            i1, i2 +          ).grey_title_grey_blue +        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], +            i1, i2, +          ).flow +        end +      end +      m=/.+\/(?:src\/)?(\S+)/im +      @pwd_stub="#{@env.url.output_tell}"[m,1] +      unless @opt.act[:quiet][:set]==:on +        if @opt.fns =~ @m_regular +          if (@opt.act[:verbose][:set]==:on \ +          || @opt.act[:verbose_plus][:set]==:on \ +          || @opt.act[:maintenance][:set]==:on) +            if @opt.act[:txt][:set]==:on +              show.report(report_info.text.txt) +              #show.maintenance(report_info.text.txt) +            end +            if @opt.act[:txt_textile][:set]==:on +              show.report(report_info.text.textile) +              #show.maintenance(report_info.text.textile) +            end +            if @opt.act[:txt_asciidoc][:set]==:on +              show.report(report_info.text.asciidoc) +              #show.maintenance(report_info.text.asciidoc) +            end +            if @opt.act[:txt_markdown][:set]==:on +              show.report(report_info.text.markdown) +              #show.maintenance(report_info.text.markdown) +            end +            if @opt.act[:txt_rst][:set]==:on +              show.report(report_info.text.rst) +              #show.maintenance(report_info.text.rst) +            end +            if @opt.act[:txt_orgmode][:set]==:on +              show.report(report_info.text.orgmode) +              #show.maintenance(report_info.text.orgmode) +            end +            if (@opt.act[:html][:set]==:on \ +            or @opt.act[:html_scroll][:set]==:on \ +            or @opt.act[:html_seg][:set]==:on) +              if @opt.act[:html_scroll][:set]==:on +                show.report(report_info.html.scroll) +                show.maintenance(report_info.html.scroll) +              end +              if @opt.act[:html_seg][:set]==:on +                show.report(report_info.html.seg) +                show.maintenance(report_info.html.seg) +              end +            end +            if @opt.act[:concordance][:set]==:on +              show.report(report_info.html.concordance) +              #show.maintenance(report_info.html.concordance) +            end +            if @opt.act[:xhtml][:set]==:on +              show.report(report_info.xhtml.xhtml) +              show.maintenance(report_info.xhtml.xhtml) +            end +            if @opt.act[:epub][:set]==:on +              show.report(report_info.xhtml.epub) +              show.maintenance(report_info.xhtml.epub) +            end +            if @opt.act[:odt][:set]==:on +              show.report(report_info.xml.odt) +              show.maintenance(report_info.xml.odt) +            end +            if @opt.act[:xml_dom][:set]==:on +              show.report(report_info.xml.dom) +              #show.maintenance(report_info.xml.dom) +            end +            if @opt.act[:xml_sax][:set]==:on +              show.report(report_info.xml.sax) +              #show.maintenance(report_info.xml.sax) +            end +            if @opt.act[:xml_docbook_book][:set]==:on +              show.report(report_info.xml.docbook) +              #show.maintenance(report_info.xml.docbook) +            end +            if @opt.act[:xml_fictionbook][:set]==:on +              show.report(report_info.xml.fictionbook) +              #show.maintenance(report_info.xml.fictionbook) +            end +            if @opt.act[:xml_scaffold_structure_sisu][:set]==:on +              show.report(report_info.xml.scaffold_structure_sisu) +              #show.maintenance(report_info.xml.scaffold_structure_sisu) +            end +            if @opt.act[:xml_scaffold_structure_collapse][:set]==:on +              show.report(report_info.xml.scaffold_collapse) +              #show.maintenance(report_info.xml.scaffold_collapse) +            end +            if @opt.act[:json][:set]==:on +              show.report(report_info.json) +              #show.maintenance(report_info.json) +            end +            if (@opt.act[:pdf][:set]==:on \ +            or @opt.act[:pdf_p][:set]==:on \ +            or @opt.act[:pdf_l][:set]==:on) +              if @opt.act[:pdf_p][:set]==:on +                show.report(report_info.pdf.portrait) +                show.maintenance(report_info.pdf.portrait) +              end +              if @opt.act[:pdf_l][:set]==:on +                show.report(report_info.pdf.landscape) +                show.maintenance(report_info.pdf.landscape) +              end +            end +            if @opt.act[:psql][:set]==:on +              show.report(report_info.db.psql) +              show.maintenance(report_info.db.psql) +            end +            if @opt.act[:sqlite_discrete][:set]==:on +              show.report(report_info.db.sqlite_discrete) +              show.maintenance(report_info.db.sqlite_discrete) +            end +            if @opt.act[:sqlite][:set]==:on +              show.report(report_info.db.sqlite) +              show.maintenance(report_info.db.sqlite) +            end +            if @opt.act[:texinfo][:set]==:on +              show.report(report_info.texinfo) +              #show.maintenance(report_info.texinfo) +            end +            if @opt.act[:manpage][:set]==:on +              show.report(report_info.manpage) +              #show.maintenance(report_info.manpage) +            end +            if @opt.act[:hash_digests][:set]==:on +              show.report(report_info.hash_digests) +              #show.maintenance(report_info.hash_digests) +            end +            if @opt.act[:po4a_shelf][:set]==:on +              #if @opt.fns =~/\S+?~\S{2}(?:_\S{2})?\.ss[mt]/ +              #else +              #end +            end +            if @opt.act[:share_source][:set]==:on +              show.report(report_info.source) +              show.maintenance(report_info.source) +            end +            if @opt.act[:sisupod][:set]==:on +              show.report(report_info.sisupod) +              show.maintenance(report_info.sisupod) +            end +            if @opt.act[:qrcode][:set]==:on +              show.report(report_info.qrcode) +              #show.maintenance(report_info.qrcode) +            end +            if @opt.act[:manifest][:set]==:on +              show.report(report_info.manifest) +              show.maintenance(report_info.manifest) +            end +          end +        end +      end +    end +    def urls_all +      i="(output manifest) [#{@opt.f_pth[:lng_is]}] #{@env.url.output_tell}/#{@fnb}/sisu_manifest.html" +      SiSU_Screen::Ansi.new( +        @opt.act[:color_state][:set], +        'URLs', +        i +      ).grey_title_hi +    end +  end +end +__END__ +#+END_SRC + +** webrick.rb + +#+BEGIN_SRC ruby  :tangle "../lib/sisu/webrick.rb" +# <<sisu_document_header>> +module SiSU_Webserv +  class WebrickStart +    begin +      require 'time' +      require 'webrick' +        include WEBrick +    rescue LoadError +      SiSU_Utils::CodeMarker.new(__LINE__,__FILE__,:fuchsia). +        error('time or webrick NOT FOUND (LoadError)') +    end +    require_relative 'se'                                 # se.rb +      include SiSU_Env +      include SiSU_Screen +    def initialize +      @cX=SiSU_Screen::Ansi.new('yes').cX +      @env=SiSU_Env::InfoEnv.new +      port=SiSU_Env::InfoPort.new +      @host=@env.url.webrick +      @port=port.webrick +      @serve=[] +      Dir.foreach(@env.path.webserv) do |x| +        if x !~/^\./ \ +        and FileTest.directory?("#{@env.path.webserv}/#{x}") +          @serve << x +        end +      end +      @mount=[] +      @serve.each {|x| @mount << ["/#{x}", "#{@env.path.webserv}/#{x}"]} +      @pwd=Dir.pwd +      @week=Time.now.strftime(%{%Yw%W}) +      puts "\n" +      @mount.each { |x,y| +        puts "  * #{@cX.blue}#{@host}:#{@port}#{x}/#{@cX.off}" +      } +      get=Dir.pwd +      brick(@port,get) +    end +    def brick(port,get='') +      cgidir=if get=~/pwd/ then Dir.pwd +      else                      '/usr/lib/cgi-bin' +      end +      port=SiSU_Env::InfoPort.new.webrick +      begin +        s=HTTPServer.new( +          Port:         port, +          DocumentRoot: Dir::pwd + '/htdocs', +          CGIPathEnv:   ENV['PATH'] +        ) +        cgi_dir=File.expand_path(cgidir) +        @mount.each { |x,y|                                                        # mount subdirectories +          s.mount(x, HTTPServlet::FileHandler, y, true) +        } +        s.mount('/cgi-bin', HTTPServlet::FileHandler, cgi_dir, { FancyIndexing: true }) +        trap("INT"){ s.shutdown } +        s.start +      rescue +        SiSU_Errors::Rescued.new($!,$@,'-W',nil).location do #fix +          __LINE__.to_s + ':' + __FILE__ +        end +      ensure +      end +    end +    def wb_cgi +      begin                                                                          #% +        wb_s2='' +                                                                 #% writes file wb.cgi to shared directories ... +                                                                 #% wb_top +        wb_top=%q(#!/usr/bin/env ruby +        # * arch-tag: webrick info on environment, mounted directories, and contents of pwd +        begin +          require 'time' +          require 'cgi' +          require 'fcgi' +        rescue LoadError +          puts 'time, cgi or fcgi NOT FOUND (LoadError)' +        end +        ls=Dir.entries('./') +        dir_contents=[] +        ls.each { |x| dir_contents << "<a href=\"./#{x}/\">#{x}</a><br>" unless x =~/^(\.)+$/ } +        dir_contents=dir_contents.sort.join(' ') +        #host=ENV['HOSTNAME'] +        #host=%x{echo $HOSTNAME} +        ) +        wb_s1=<<-WOK + +  page=CGI.new "html3" +  page.out { +    page.html { +      page.head { page.title {"#{@host} Webrick Report"} } + +      page.body { +        page.h1 {"Webrick #{@host}"} + +        page.p {"Webrick is Ruby's built in webserver."} + +        page.center {"Host name: " + page.b{"#{@host} "} + "(#{@host})  port: " + page.b{"#{@port}"}} + +        page.center {"#{Time.now}"} + +        page.center {"#{Time.now.strftime(%{%Yw%W})}"} + +        page.p {''} + +        page.p {''} + +        page.p {page.b{"Webrick Served Directories: "}} + +        WOK +                                                               #% wb_s2 (mounts) +        @mount.each do |x,y| wb_s2 += <<-WOK +          page.p {%{<a href="#{@host}:#{@port}#{x}/">#{x}</a> } + +            %{<a href="#{@host}:#{@port}#{x}/">#{@host}:#{@port}#{x}</a> (mounts: #{y}/)   <a href="#{@host}:#{@port}#{x}/wb.cgi">info (wb.cgi)</a>}} + +          WOK +        end +                                                               #% wb_end +        wb_end=<<-WOK +        page.p {page.b{"Contents of PWD (see URL): "}} + +        page.p {"#\{dir_contents}"} +      } +    } +  } +        WOK +        @mount.each { |x,y|                                      #% wb puts +          puts y +            filename=File.new("#{y}/wb.cgi",'w') +            filename << wb_top +            filename << wb_s1 +            filename << wb_s2 +            filename << wb_end +            filename.close +            FileUtils::chmod(0755,"#{y}/wb.cgi &") if FileTest.file?("#{y}/wb.cgi &") +        } +      rescue +        SiSU_Errors::Rescued.new($!,$@,'-W',nil).location do #fix +          __LINE__.to_s + ':' + __FILE__ +        end +      ensure +      end +    end +  end +ensure +end +__END__ +#+END_SRC + +** wikispeak.rb + +#+BEGIN_SRC ruby  :tangle "../lib/sisu/wikispeak.rb" +# <<sisu_document_header>> +module SiSU_Wikispeak +  require_relative 'ao'                                 # ao.rb +  require_relative 'se'                                 # se.rb +    include SiSU_Env +  include SiSU_Param +  require_relative 'plaintext_format'                   # plaintext_format.rb +    include Format +  require_relative 'html_parts'                         # html_parts.rb +  require_relative 'txt_shared' +  @@alt_id_count,@@alt_id_count=0,0 +  @@tablefoot='' +  class Source +    def initialize(opt) +      @opt=opt +      @@dostype='msdos footnotes' +    end +    def read +      begin +        @md=SiSU_Param::Parameters.new(@opt).get +        @env=SiSU_Env::InfoEnv.new(@opt.fns) +        path=@env.path.output_tell +        tool=(@opt.act[:verbose][:set]==:on \ +        || @opt.act[:verbose_plus][:set]==:on \ +        || @opt.act[:maintenance][:set]==:on) \ +        ? "#{@env.program.text_editor} #{path}/#{@md.fnb}/#{@md.fn[:wiki]}" +        : '' +        SiSU_Screen::Ansi.new( +          @opt.act[:color_state][:set], +          'Wikispeak', +          tool +        ).green_hi_blue unless @opt.act[:quiet][:set]==:on +        if (@opt.act[:verbose_plus][:set]==:on \ +        || @opt.act[:maintenance][:set]==:on) +          SiSU_Screen::Ansi.new( +            @opt.act[:color_state][:set], +            @opt.fns, +            "#{@env.path.output_tell}/#{@md.fnb}/#{@md.fn[:wiki]}" +          ).flow +        end +        @ao_array=SiSU_AO::Source.new(@opt).get # ao file drawn here +        SiSU_Wikispeak::Source::Scroll.new(@ao_array,@md).songsheet +      rescue +        SiSU_Errors::Rescued.new($!,$@,@opt.selections.str,@opt.fns).location do +          __LINE__.to_s + ':' + __FILE__ +        end +      ensure +      end +    end +    private +    class SplitTextObject <Source +      require_relative 'plaintext_format'               # plaintext_format.rb +        include Format +      @@alt_id_count=0 +      @@dp=nil +      attr_reader :format,:lev,:text,:ocn,:lev_para_ocn +      def initialize(para) +        @para=para +        @format,@ocn='ordinary','ordinary' +        @dp=@@dp ||=SiSU_Env::InfoEnv.new.digest.pattern +      end +      def lev_segname_para_ocn +        @text=nil +        if @para =~/^(\d~|<:.+?>).+?#{Mx[:id_o]}~(\d+);(?:\w|[0-6]:)\d+;\w\d+#{Mx[:id_c]}#{Mx[:id_o]}#{@dp}:#{@dp}#{Mx[:id_c]}$/ +          if /^(([1-6])~(\S+))\s+(\S.+?)#{Mx[:id_o]}~(\d+);(?:\w|[0-6]:)\d+;\w\d+#{Mx[:id_c]}#{Mx[:id_o]}#{@dp}:#{@dp}#{Mx[:id_c]}$/m.match(@para) +            @format,@lev,segname,@text,@ocn=$1,$2,$3,$4,$5 +          elsif  /^(([1-6])~)\s+(\S.+?)#{Mx[:id_o]}~(\d+);(?:\w|[0-6]:)\d+;\w\d+#{Mx[:id_c]}#{Mx[:id_o]}#{@dp}:#{@dp}#{Mx[:id_c]}$/m.match(@para) +            @format,@lev,@text,@ocn=$1,$2,$3,$4 +          elsif /<:(.+?)>\s*(\S.+?)#{Mx[:id_o]}~(\d+);(?:\w|[0-6]:)\d+;\w\d+#{Mx[:id_c]}#{Mx[:id_o]}#{@dp}:#{@dp}#{Mx[:id_c]}$/m.match(@para) +            @format,@text,@ocn=$1,$2,$3 +          elsif /^(([1-6])~(\S+))\s+(\S.+?)#{Mx[:id_o]}~(\d+);(?:\w|[0-6]:)\d+;[um]\d+#{Mx[:id_c]}#{Mx[:id_o]}#{@dp}:#{@dp}#{Mx[:id_c]}$/m.match(@para) +            @@alt_id_count+=1 +            @format,@lev,segname,@text,@ocn=$1,$2,$3,$4,"x#{@@alt_id_count}" +          elsif  /^(([1-6])~)\s+(\S.+?)#{Mx[:id_o]}~(\d+);[um]\d+;\w\d+#{Mx[:id_c]}#{Mx[:id_o]}#{@dp}:#{@dp}#{Mx[:id_c]}$/m.match(@para) +            @@alt_id_count+=1 +            @format,@lev,@text,@ocn=$1,$2,$3,"x#{@@alt_id_count}" +          end +        else +          if /(.+?)#{Mx[:id_o]}~(\d+);(?:\w|[0-6]:)\d+;\w\d+#{Mx[:id_c]}#{Mx[:id_o]}#{@dp}:#{@dp}#{Mx[:id_c]}$/m.match(@para) +            @text,@ocn=$1,$2 +          end +          if @para !~/#{Mx[:id_o]}~(\d+);(?:\w|[0-6]:)\d+;\w\d+#{Mx[:id_c]}#{Mx[:id_o]}#{@dp}:#{@dp}#{Mx[:id_c]}$|^$/ #added 2002w06 +            @text=/(.+?)/m.match(@para)[1] +          end +          if /^((\d)~(?:~\S+)?)\s+(.+)/m.match(@para) +            @format,@lev,@text=$1,$2,$3 +          end +        end +        format=@format.dup +        @lev_para_ocn=if @para =~/.+#{Mx[:id_o]}~\d+;(?:\w|[0-6]:)\d+;\w\d+#{Mx[:id_c]}#{Mx[:id_o]}#{@dp}:#{@dp}#{Mx[:id_c]}$/ +          Format::FormatTextObject.new(format,@text,@ocn) +        else +          Format::FormatTextObject.new(format,@text,"#{Mx[:id_o]}~(\d+);[um]\d+;\w\d+#{Mx[:id_c]}#{Mx[:id_o]}#{@dp}:#{@dp}#{Mx[:id_c]}") +        end +        self +      end +    end +    class Scroll <Source +      include SiSU_TextUtils +      include SiSU_Parts_HTML +      @@endnotes_para=[] +      @@wiki={ body: [], open: [], close: [], head: [], metadata: [], tail: [], endnotes: [] } +      @@dp=nil +      def initialize(data,md) +        @data,@md=data,md +        @dp=@@dp ||=SiSU_Env::InfoEnv.new.digest.pattern +        @regx=/^(?:(?:#{Mx[:br_line]}\s*|#{Mx[:br_nl]}\s*)?#{Mx[:lv_o]}\d:(\S*?)#{Mx[:lv_c]}\s*)?(.+)/ #fix Mx[:lv_o] #m # 2004w18 pb pn removal added +        @tab="\t" +        @@dostype='unix footnotes' +        @br="\n" +      end +      def songsheet +        markup +        publish +      end +      # Used for extraction of endnotes from paragraphs +      def extract_endnotes(para='') #check +        para.scan(/(?:#{Mx[:en_a_o]}|#{Mx[:en_b_o]})([\d*+]+\s+.+?)\s*#{Mx[:id_o]}#{@dp}#{Mx[:id_c]}(?:#{Mx[:en_a_c]}|#{Mx[:en_b_c]})/) +      end +      def wiki_metadata(meta) +        util=SiSU_TextUtils::Wrap.new(meta.text,70,15,1) +        txt=util.line_wrap +        @@wiki[:metadata] <<= if meta.type=='meta' +          <<WOK + +#{@tab}#{meta.el}: #{txt} +WOK +        else '' +        end +      end +      def wiki_tail +        generator="Generated by: #{@md.project_details.project} #{@md.project_details.version} of #{@md.project_details.date_stamp} (#{@md.project_details.date})"  if @md.project_details.version +        lastdone="Last Generated on: #{Time.now}" +        rubyv="Ruby version: #{@md.ruby_version}" +        sc=if @md.sc_info +          "Source file:    #{@md.sc_filename}#{@br}Version number: #{@md.sc_number}#{@br}Version date:   #{@md.sc_date}#{@br}" +        else '' +        end +        @@wiki[:tail] <<<<WOK +#{@br} +Other versions of this document: #{@br} +manifest: +   #{vz.url_root_http}/#{@md.fnb}/#{@md.fn[:manifest]}#{@br} +html: +   #{vz.url_root_http}/#{@md.fnb}/#{@md.fn[:toc]}#{@br} +pdf: +   #{vz.url_root_http}/#{@md.fnb}/#{@md.fn[:pdf_p]} +   #{vz.url_root_http}/#{@md.fnb}/#{@md.fn[:pdf_l]}#{@br} +plaintext (plain text): +   #{vz.url_root_http}/#{@md.fnb}/#{@md.fn[:plain]}#{@br} +at: +   #{vz.url_site}#{@br} + +#{sc} +,* #{generator} +,* #{rubyv} +,* #{lastdone} +,* SiSU #{vz.url_sisu} +WOK +      end +      def wiki_structure(para='',lv='',ocn='',hname='') #% Used to extract the structure of a document +        lv=lv.to_i +        lv=nil if lv==0 +        extract_endnotes(para) +        para.gsub!(/(?:#{Mx[:en_a_o]}|#{Mx[:en_b_o]})(?:[\d*+]+)\s+(.+?)#{Mx[:id_o]}#{@dp}#{Mx[:id_c]}(?:#{Mx[:en_a_c]}|#{Mx[:en_b_c]})/,'<ref>\1</ref>') # endnote marker marked up +        para.gsub!(/^#{Rx[:lv]}\S*\s+/,'') # endnote marker marked up +        para.gsub!(/<\S+?>#{Mx[:id_o]}#{@dp}:#{@dp}#{Mx[:id_c]}/,'') # endnote marker marked up +        if lv +          @@wiki[:body] << case lv +          when 1    then '='*2 << para.strip << @br*2 +          when 2..3 then '='*2 << para.strip << @br*2 +          when 4    then '='*4 << para.strip << @br*2 +          when 5..6 then '='*4 << para.strip << @br*2 +          end +        else @@wiki[:body] << para << @br*2 # main text, contents, body KEEP +        end +      end +      def markup                                                               # Used for major markup instructions +        data=@data +        SiSU_Env::InfoEnv.new(@md.fns) +        @data_mod,@endnotes,@level,@cont,@copen,@wiki_contents_close=Array.new(6){[]} +        (0..6).each { |x| @cont[x]=@level[x]=false } +        (4..6).each { |x| @wiki_contents_close[x]='' } +        wiki_tail +        table_message='[table omitted, see other document formats]' +        data.each do |para| +          para.gsub!(/#{Mx[:gr_o]}Th?#{Mx[:tc_p]}.+/um,"#{@br}#{table_message}") #fix +          para.gsub!(/.+?<-#>/,'')                                           # remove dummy headings (used by html) #check +          para.gsub!(/_\*\s+/,'* ')                                           # bullet markup, marked down +          para.gsub!(/©/,'©')                                           # bullet markup, marked down +          para.gsub!(/&/,'&')                                           # bullet markup, marked down +          para.gsub!(/<sup>(.+?)<\/sup>/,'^\1^') +          para.gsub!(/<sub>(.+?)<\/sub>/,'[\1]') +          para.gsub!(/<i>(.+?)<\/i>/,"''\\1''") +          para.gsub!(/<b>(.+?)<\/b>/,"'''\\1'''") +          para.gsub!(/<u>(.+?)<\/u>/,'_\1_') +          para.gsub!(/#{Mx[:lnk_o]}(.+?)#{Mx[:lnk_c]}#{Mx[:url_o]}(\S+?)#{Mx[:url_c]}/,'[\2 \1]') +          para.gsub!(/#{Mx[:url_o]}(\S+?)#{Mx[:url_c]}/,'[\1]') +          para.gsub!(/<:(?:block|group|verse|alt|code)(?:-end)?>(?:\s+#{Mx[:id_o]}~(\d+);(?:\w|[0-6]:)\d+;\w\d+#{Mx[:id_c]}#{Mx[:id_o]}#{@dp}:#{@dp}#{Mx[:id_c]})?/,'') +          para.gsub!(/<:p[bn]>/,'')                                         # remove page breaks +          para.gsub!(/^\s*#{Mx[:id_o]}~\d+;(?:\w|[0-6]:)\d+;\w\d+#{Mx[:id_c]}#{Mx[:id_o]}#{@dp}:#{@dp}#{Mx[:id_c]}$/,'') # remove empty lines - check +          para.gsub!(/<a href=".+?">(.+?)<\/a>/m,'\1') +          para.gsub!(/<:name#\S+?>/,'')                                       # remove name links +          para.gsub!(/ |#{Mx[:nbsp]}/,' ')                               # decide on +          para.gsub!(/(?:^|[^_\\])#{Mx[:lnk_o]}(\S+?\.(?:png|jpg|gif)) .+?#{Mx[:lnk_c]}(?:#{Mx[:url_o]}\S+?#{Mx[:url_c]}|image)/,'    [ \1 ]') #"[ #{dir.url.images_local}\/\\1 ]") +          para.gsub!(/(?:^|[^_\\])#{Mx[:lnk_o]}\s*\S+?\.(?:png|jpg|gif)\s+.+?"(.*?)"\s*#{Mx[:lnk_c]}\S+/,'[image: "\1"]') +          if para =~/^@(\S+?):\s+(.+?)\Z/m # for headers +            d_meta=SiSU_TextUtils::HeaderScan.new(@md,para).meta +            if d_meta; wiki_metadata(d_meta) +            end +          end +          if para !~/(^@\S+?:|#{Mx[:br_endnotes]}|#{Mx[:br_eof]})/ +            if para =~@regx #/.+?<~\d+;\w\d+;\w\d+>.*/ #watch change +              paranum=para[@regx,3] +              @p_num=Format::ParagraphNumber.new(paranum) +            end +            @sto=SplitTextObject.new(para).lev_segname_para_ocn +            ### problem in scroll, it appears tables are getting paragraph numbers +            m=/#{Mx[:id_o]}~(\d+);(?:\w|[0-6]:)\d+;\w\d+#{Mx[:id_c]}#{Mx[:id_o]}#{@dp}:#{@dp}#{Mx[:id_c]}$/ +            if para =~m \ +            and para=~/\S+/ +              para=case @sto.format +              when /^(1)~(?:(\S+))?/ +                wiki_structure(para,$1,@sto.ocn,$2) +                @sto.lev_para_ocn.heading_body1 +              when /^(2)~(?:(\S+))?/ +                wiki_structure(para,$1,@sto.ocn,$2) +                @sto.lev_para_ocn.heading_body2 +              when /^(3)~(?:(\S+))?/ +                wiki_structure(para,$1,@sto.ocn,$2) +                @sto.lev_para_ocn.heading_body3 +              when /^(4)~(\S+)/ # work on see SiSU_text_parts::SplitTextObject +                wiki_structure(para,$1,@sto.ocn,$2) +                @sto.lev_para_ocn.heading_body4 +              when /^(5)~(?:(\S+))?/ +                wiki_structure(para,$1,@sto.ocn,$2) +                @sto.lev_para_ocn.heading_body5 +              when /^(6)~(?:(\S+))?/ +                wiki_structure(para,$1,@sto.ocn,$2) +                @sto.lev_para_ocn.heading_body6 +              else +                wiki_structure(para,nil,nil,nil) #watch may be problematic +                para +              end +            elsif para =~/#{table_message}/ +              @@wiki[:body] << para << @br +            elsif para =~/(Note|Endnotes?)/ \ +            and para !~/#{Mx[:id_o]}~\d+;(?:\w|[0-6]:)\d+;\w\d+#{Mx[:id_c]}#{Mx[:id_o]}#{@dp}:#{@dp}#{Mx[:id_c]}$/ +            elsif para =~/(MetaData)/ \ +            and para =~/#{Mx[:id_o]}~(\d+);[um]\d+;\w\d+#{Mx[:id_c]}#{Mx[:id_o]}#{@dp}:#{@dp}#{Mx[:id_c]}$/ #debug 2003w46 add rc info ####suspect visit +            elsif para.include? 'Owner Details' \ +            and para !~/#{Mx[:id_o]}~(\d+);(?:[oh]|[0-6]:)\d+;\w\d+#{Mx[:id_c]}#{Mx[:id_o]}#{@dp}:#{@dp}#{Mx[:id_c]}$/ +            elsif para =~/(#{Mx[:tc_p]}|#{Mx[:gr_o]}Th?)/u #tables ! #fix +            elsif para =~/(.*)<!#!>(.*)/ +              one,two=$1,$2 +              format_text=FormatTextObject.new(one,two) +              para=format_text.seg_no_paranum +            end +            if (para =~/<a name="n\d+">/ \ +            and para =~/^(-\{{2}~\d+|<!e[:_]\d+!>)/) # -endnote +              para='' +            end +            case para +            when /<:i1>/ +              if para =~/.*<:#>.*$/ +                format_text=FormatTextObject.new(para,'') +                para=format_text.scr_indent_one_no_paranum +              end +            when /<:i2>/ +              if para =~/.*<:#>.*$/ +                format_text=FormatTextObject.new(para,'') +                para=format_text.scr_indent_one_no_paranum +              end +            end +            if para !~/#{the_margin.txt_0}|#{the_margin.txt_1}|#{the_margin.txt_2}/ +              # i don't get the condition for no paranum +            end +            if para =~/<:center>/ +              one,two=/(.*)<:center>(.*)/.match(para)[1,2] +              format_text=FormatTextObject.new(one,two) +              para=format_text.center +            end +            para.gsub!(/<!.+!>/,' ') if para ## Clean Prepared Text +            para.gsub!(/<:\S+>/,' ') if para ## Clean Prepared Text +          end +        end +      end +      def publish +        content=[] +        content << @@wiki[:open] +        content << @@wiki[:head] +        content << @@wiki[:body] +        Output.new(content.join,@md).wiki +        @@wiki[:head],@@wiki[:body],@@wiki[:tail],@@wiki[:metadata]=[],[],[],[] +      end +    end +    class Output <Source +      include SiSU_Param +      include SiSU_Env +      def initialize(content,md) +        @content,@md=content,md +      end +      def wiki                                                            #%wiki output +        SiSU_Env::FileOp.new(@md).mkdir +        filename_wiki=SiSU_Env::FileOp.new(@md,@md.fn[:wiki]).mkfile +        @sisu=[] +        @content.each do |para|                                                # this is a hack +          if para =~/^\S/ +            if para !~/^([*=-]|\.){5}/; filename_wiki.puts para           #unix wiki +            else                        filename_wiki.puts para           #unix wiki +            end +          else filename_wiki.puts para # if para =~/^\s/ +          end +        end +      end +    end +  end +end +__END__ +#+END_SRC + +** zap.rb + +#+BEGIN_SRC ruby  :tangle "../lib/sisu/zap.rb" +# <<sisu_document_header>> +module SiSU_Zap +  require_relative 'se'                                 # se.rb +    include SiSU_Env +  class Source +    def initialize(opt) +      @opt=opt +      @env=SiSU_Env::InfoEnv.new(opt.fns) +    end +    def read +      zap_path="#{@env.path.output}/#{@env.fnb}" +      z=SiSU_Env::CleanOutput.new(@opt) +      if SiSU_Env::InfoSettings.new.permission?('zap') +        unless @opt.act[:quiet][:set]==:on +          tell=SiSU_Screen::Ansi.new( +            @opt.act[:color_state][:set], +            "Clean files related to processing #{@opt.selections.str} ->", +            "#{@opt.fns} -> #{zap_path}" +          ) +          tell.warn +        end +        z.zap.remove_output +      else +        unless @opt.act[:quiet][:set]==:on +          tell=SiSU_Screen::Ansi.new( +            @opt.act[:color_state][:set], +            'use of -Z (zap) has not enabled in sisurc.yml' +          ) +          tell.warn +        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 +    misc + +  - 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 diff --git a/org/object_munge.org b/org/object_munge.org new file mode 100644 index 00000000..7e3f95e5 --- /dev/null +++ b/org/object_munge.org @@ -0,0 +1,331 @@ +-*- mode: org -*- +#+TITLE:       sisu object munge +#+DESCRIPTION: documents - structuring, various output representations & search +#+FILETAGS:    :sisu:munge:objects: +#+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 + +* object_munge.rb + +#+BEGIN_SRC ruby  :tangle "../lib/sisu/object_munge.rb" +# <<sisu_document_header>> +module SiSU_Object_Munge +  def i_src_o_strip_markup(txtobj) +    txtobj=txtobj. +      gsub(/#{Mx[:srcrgx_bold_o]}(.+?)#{Mx[:srcrgx_bold_c]}/m,'\1'). +      gsub(/#{Mx[:srcrgx_italics_o]}(.+?)#{Mx[:srcrgx_italics_c]}/m,'\1'). +      gsub(/#{Mx[:srcrgx_underscore_o]}(.+?)#{Mx[:srcrgx_underscore_c]}/m,'\1'). +      gsub(/#{Mx[:srcrgx_cite_o]}(.+?)#{Mx[:srcrgx_cite_c]}/m,'\1'). +      gsub(/#{Mx[:srcrgx_insert_o]}(.+?)#{Mx[:srcrgx_insert_c]}/m,'\1'). +      gsub(/#{Mx[:srcrgx_strike_o]}(.+?)#{Mx[:srcrgx_strike_c]}/m,'\1'). +      gsub(/#{Mx[:srcrgx_superscript_o]}(\d+)#{Mx[:srcrgx_superscript_c]}/m,'[\1]'). +      gsub(/#{Mx[:srcrgx_superscript_o]}(.+?)#{Mx[:srcrgx_superscript_c]}/m,'\1'). +      gsub(/#{Mx[:srcrgx_subscript_o]}(.+?)#{Mx[:srcrgx_subscript_c]}/m,'\1'). +      gsub(/#{Mx[:srcrgx_hilite_o]}(.+?)#{Mx[:srcrgx_hilite_c]}/m,'\1'). +      gsub(/#{Mx[:gl_o]}#(?:126|152)#{Mx[:gl_c]}/i,'~'). +      gsub(/#{Mx[:en_a_o]}([\d*+]+)\s+(?:.+?)#{Mx[:en_a_c]}/m,''). # endnote removed +      gsub(/#{Mx[:en_b_o]}([\d*+]+)\s+(?:.+?)#{Mx[:en_b_c]}/m,''). # endnote removed +      gsub(/(?:#{Mx[:nbsp]})+/,' '). +      gsub(/(?:#{Mx[:br_nl]})+/,"\n"). +      gsub(/(?:#{Mx[:br_paragraph]})+/,"\n"). +      gsub(/(?:#{Mx[:br_line]})+/,"\n"). +      gsub(/#{Mx[:gl_o]}(?:#lt|#060)#{Mx[:gl_c]}/,'<'). +      gsub(/#{Mx[:gl_o]}(?:#gt|#062)#{Mx[:gl_c]}/,'>'). +      gsub(/#{Mx[:gl_o]}#(?:038|amp)#{Mx[:gl_c]}/,'&'). +      gsub(/#{Mx[:gl_o]}#033#{Mx[:gl_c]}/,'!'). +      gsub(/#{Mx[:gl_o]}#035#{Mx[:gl_c]}/,'#'). +      gsub(/#{Mx[:gl_o]}#042#{Mx[:gl_c]}/,'*'). +      gsub(/#{Mx[:gl_o]}#045#{Mx[:gl_c]}/,'-'). +      gsub(/#{Mx[:gl_o]}#047#{Mx[:gl_c]}/,'/'). +      gsub(/#{Mx[:gl_o]}#095#{Mx[:gl_c]}/,'_'). +      gsub(/#{Mx[:gl_o]}#123#{Mx[:gl_c]}/,'{'). +      gsub(/#{Mx[:gl_o]}#125#{Mx[:gl_c]}/,'}'). +      gsub(/#{Mx[:gl_o]}#126#{Mx[:gl_c]}/,'~'). +      gsub(/#{Mx[:gl_o]}#169#{Mx[:gl_c]}/,'©'). +      gsub(/[ ][ ]s+/,' '). +      strip +if txtobj =~/Reading this/ +  puts txtobj +  if txtobj =~ /#{Mx[:srcrgx_italics_o]}(.+?)#{Mx[:srcrgx_italics_c]}/ +    puts __LINE__ +    puts Mx[:srcrgx_italics_o] +    puts txtobj +  end +end +; txtobj +  end +  def i_ao_o_strip_markup(txtobj) +    txtobj=txtobj.gsub(/#{Mx[:fa_bold_o]}(.+?)#{Mx[:fa_bold_c]}/,'\1'). +      gsub(/#{Mx[:fa_italics_o]}(.+?)#{Mx[:fa_italics_c]}/,'\1'). +      gsub(/#{Mx[:fa_underscore_o]}(.+?)#{Mx[:fa_underscore_c]}/,'\1'). +      gsub(/#{Mx[:fa_cite_o]}(.+?)#{Mx[:fa_cite_c]}/,'\1'). +      gsub(/#{Mx[:fa_insert_o]}(.+?)#{Mx[:fa_insert_c]}/,'\1'). +      gsub(/#{Mx[:fa_strike_o]}(.+?)#{Mx[:fa_strike_c]}/,'\1'). +      gsub(/#{Mx[:fa_superscript_o]}(\d+)#{Mx[:fa_superscript_c]}/,'[\1]'). +      gsub(/#{Mx[:fa_superscript_o]}(.+?)#{Mx[:fa_superscript_c]}/,'\1'). +      gsub(/#{Mx[:fa_subscript_o]}(.+?)#{Mx[:fa_subscript_c]}/,'\1'). +      gsub(/#{Mx[:fa_hilite_o]}(.+?)#{Mx[:fa_hilite_c]}/,'\1'). +      gsub(/#{Mx[:gl_o]}#(?:126|152)#{Mx[:gl_c]}/i,'~'). +      gsub(/#{Mx[:en_a_o]}([\d*+]+)\s+(?:.+?)#{Mx[:en_a_c]}/,''). # endnote removed +      gsub(/#{Mx[:en_b_o]}([\d*+]+)\s+(?:.+?)#{Mx[:en_b_c]}/,''). # endnote removed +      gsub(/(?:#{Mx[:nbsp]})+/,' '). +      gsub(/(?:#{Mx[:br_nl]})+/,"\n"). +      gsub(/(?:#{Mx[:br_paragraph]})+/,"\n"). +      gsub(/(?:#{Mx[:br_line]})+/,"\n"). +      gsub(/#{Mx[:gl_o]}(?:#lt|#060)#{Mx[:gl_c]}/,'<'). +      gsub(/#{Mx[:gl_o]}(?:#gt|#062)#{Mx[:gl_c]}/,'>'). +      gsub(/#{Mx[:gl_o]}#(?:038|amp)#{Mx[:gl_c]}/,'&'). +      gsub(/#{Mx[:gl_o]}#033#{Mx[:gl_c]}/,'!'). +      gsub(/#{Mx[:gl_o]}#035#{Mx[:gl_c]}/,'#'). +      gsub(/#{Mx[:gl_o]}#042#{Mx[:gl_c]}/,'*'). +      gsub(/#{Mx[:gl_o]}#045#{Mx[:gl_c]}/,'-'). +      gsub(/#{Mx[:gl_o]}#047#{Mx[:gl_c]}/,'/'). +      gsub(/#{Mx[:gl_o]}#095#{Mx[:gl_c]}/,'_'). +      gsub(/#{Mx[:gl_o]}#123#{Mx[:gl_c]}/,'{'). +      gsub(/#{Mx[:gl_o]}#125#{Mx[:gl_c]}/,'}'). +      gsub(/#{Mx[:gl_o]}#126#{Mx[:gl_c]}/,'~'). +      gsub(/#{Mx[:gl_o]}#169#{Mx[:gl_c]}/,'©'). +      gsub(/[ ][ ]s+/,' '). +      strip +  end +  def i_ao_o_src_markup_restore(txtobj) +    @txtobj=txtobj +    def textface_marks +      @txtobj.gsub(/#{Mx[:fa_bold_o]}(.+?)#{Mx[:fa_bold_c]}/,'*{\1}*'). +        gsub(/#{Mx[:fa_italics_o]}(.+?)#{Mx[:fa_italics_c]}/,'/{\1}/'). +        gsub(/#{Mx[:fa_underscore_o]}(.+?)#{Mx[:fa_underscore_c]}/,'_{\1}_'). +        gsub(/#{Mx[:fa_cite_o]}(.+?)#{Mx[:fa_cite_c]}/,'"{\1}"'). +        gsub(/#{Mx[:fa_insert_o]}(.+?)#{Mx[:fa_insert_c]}/,'+{\1}+'). +        gsub(/#{Mx[:fa_strike_o]}(.+?)#{Mx[:fa_strike_c]}/,'-{\1}-'). +        gsub(/#{Mx[:fa_superscript_o]}(\d+)#{Mx[:fa_superscript_c]}/,'^{[\1]}^'). +        gsub(/#{Mx[:fa_superscript_o]}(.+?)#{Mx[:fa_superscript_c]}/,'^{\1}^'). +        gsub(/#{Mx[:fa_subscript_o]}(.+?)#{Mx[:fa_subscript_c]}/,',{\1},'). +        gsub(/#{Mx[:fa_hilite_o]}(.+?)#{Mx[:fa_hilite_c]}/,'\1'). +        gsub(/#{Mx[:gl_o]}#(?:126|152)#{Mx[:gl_c]}/i,'~'). +        gsub(/#{Mx[:en_a_o]}([\d*+]+)\s+(?:.+?)#{Mx[:en_a_c]}/,'~{\1 \2}~'). +        gsub(/#{Mx[:en_b_o]}([\d*+]+)\s+(?:.+?)#{Mx[:en_b_c]}/,''). # endnote removed +        gsub(/(?:#{Mx[:nbsp]})+/,' '). +        gsub(/(?:#{Mx[:br_nl]})+/,"\n"). +        gsub(/(?:#{Mx[:br_paragraph]})+/,"\n"). +        gsub(/(?:#{Mx[:br_line]})+/,"\n"). +        gsub(/#{Mx[:gl_o]}(?:#lt|#060)#{Mx[:gl_c]}/,'<'). +        gsub(/#{Mx[:gl_o]}(?:#gt|#062)#{Mx[:gl_c]}/,'>'). +        gsub(/#{Mx[:gl_o]}#(?:038|amp)#{Mx[:gl_c]}/,'&'). +        gsub(/#{Mx[:gl_o]}#033#{Mx[:gl_c]}/,'!'). +        gsub(/#{Mx[:gl_o]}#035#{Mx[:gl_c]}/,'#'). +        gsub(/#{Mx[:gl_o]}#042#{Mx[:gl_c]}/,'*'). +        gsub(/#{Mx[:gl_o]}#045#{Mx[:gl_c]}/,'-'). +        gsub(/#{Mx[:gl_o]}#047#{Mx[:gl_c]}/,'/'). +        gsub(/#{Mx[:gl_o]}#095#{Mx[:gl_c]}/,'_'). +        gsub(/#{Mx[:gl_o]}#123#{Mx[:gl_c]}/,'{'). +        gsub(/#{Mx[:gl_o]}#125#{Mx[:gl_c]}/,'}'). +        gsub(/#{Mx[:gl_o]}#126#{Mx[:gl_c]}/,'~'). +        gsub(/#{Mx[:gl_o]}#169#{Mx[:gl_c]}/,'©'). +        gsub(/[ ][ ]s+/,' '). +        strip +    end +    def object_marks +      @txtobj +    end +    self +  end +  def clean_text(txtobj,markup=:ao) +    if txtobj.class==String +      txtobj=if markup ==:ao +        i_ao_o_strip_markup(txtobj) +      elsif markup ==:src +        i_src_o_strip_markup(txtobj) +      else p __FILE__; p __LINE__ +      end +    elsif txtobj.class.inspect=~/^SiSU_AO_DocumentStructure::/ +      txtobj.obj=i_ao_o_strip_markup(txtobj.obj) +    else p 'error' +    end +    txtobj +  end +  def footnotes_inline(txtobj) +  end +  def footnotes_ref_and_note(txtobj) +  end +  def src_markup(txtobj) +    txtobj +  end +  def extract_endnotes(doc_obj_txt,endnotes_)               #% used for extraction of endnotes from paragraphs +    if endnotes_ ==:separate +      notes_a=doc_obj_txt.scan(/#{Mx[:en_a_o]}([\d]+\s+.+?)#{Mx[:en_a_c]}/) +      ##notes_a=doc_obj_txt.scan(/#{Mx[:en_a_o]}([\d*+]+\s+.+?)#{Mx[:en_a_c]}/) +      #notes_b=doc_obj_txt.scan(/#{Mx[:en_b_o]}([\d*+]+\s+.+?)#{Mx[:en_b_c]}/) +      n=[] +      notes_a.flatten.each do |note| #high cost to deal with <br> appropriately within plaintext, consider +        note=note.dup.to_s +        note=note.gsub(/^([\d]+)\s+/,'^~\1 '). +          gsub(/#{Mx[:br_line]}|#{Mx[:br_nl]}/, +            ' \\\\\\ ') +        n << note +      end +      notes_a=n.flatten +      doc_obj_txt=doc_obj_txt. +        gsub(/#{Mx[:en_a_o]}([\d]+)\s+(?:.+?)#{Mx[:en_a_c]}/,'~^')   # endnote marker marked up +    else +      doc_obj_txt=doc_obj_txt. +        gsub(/#{Mx[:en_b_o]}[\d]+\s+(.+?)#{Mx[:en_b_c]}/, +          '~[ \1 ]~').     # inline endnote with marker marked up +        gsub(/#{Mx[:en_a_o]}([*+]+)\s+(.+?)#{Mx[:en_a_c]}/, +          '~{\1 \2 }~'). # inline endnote with marker marked up +        gsub(/#{Mx[:en_b_o]}([*+]+)\s+(.+?)#{Mx[:en_b_c]}/, +          '~[\1 \2 ]~') # inline endnote with marker marked up +    end +    [doc_obj_txt,notes_a] +  end +  def objects #def i_ao_o_src_markup_restore(txtobj) +    def code_(dob) +      if dob.is==:code +        dob.obj=dob.obj.gsub(/(^|[^}])_([<>])/m,'\1\2'). # _> _< +          gsub(/(^|[^}])_([<>])/m,'\1\2') # _<_< +      end +      dob +    end +    def block_(dob) +      dob.obj=if dob.of==:block                                   # watch +        dob.obj.gsub(/#{Mx[:gl_o]}●#{Mx[:gl_c]}/,"* "). +          gsub(/#{Mx[:br_line]}|#{Mx[:br_nl]}/,"\n") +      else dob.obj.gsub(/#{Mx[:br_line]}|#{Mx[:br_nl]}/,"\n\n") +      end +      dob +    end +    def textface_marks_po4a(dob,endnotes_=:inline) +      notes='' +      dob.obj=dob.obj. +        gsub(/#{Mx[:fa_bold_o]}(.+?)#{Mx[:fa_bold_c]}/, +          Mx[:src_bold_o] + '\1' + Mx[:src_bold_c]). +        gsub(/#{Mx[:fa_italics_o]}(.+?)#{Mx[:fa_italics_c]}/, +          Mx[:src_italics_o] + '\1' + Mx[:src_italics_c]). +        gsub(/#{Mx[:fa_underscore_o]}(.+?)#{Mx[:fa_underscore_c]}/, +          Mx[:src_underscore_o] + '\1' + Mx[:src_underscore_c]). +        gsub(/#{Mx[:fa_subscript_o]}(.+?)#{Mx[:fa_subscript_c]}/, +          Mx[:src_subscript_o] + '\1' + Mx[:src_subscript_c]). +        gsub(/#{Mx[:fa_superscript_o]}(.+?)#{Mx[:fa_superscript_c]}/, +          Mx[:src_superscript_o] + '\1' + Mx[:src_superscript_c]). +        gsub(/#{Mx[:fa_insert_o]}(.+?)#{Mx[:fa_insert_c]}/, +          Mx[:src_insert_o] + '\1' + Mx[:src_insert_c]). +        gsub(/#{Mx[:fa_cite_o]}(.+?)#{Mx[:fa_cite_c]}/, +          Mx[:src_cite_o] + '\1' + Mx[:src_cite_c]). +        gsub(/#{Mx[:fa_strike_o]}(.+?)#{Mx[:fa_strike_c]}/, +          Mx[:src_strike_o] + '\1' + Mx[:src_strike_c]). +        gsub(/#{Mx[:fa_monospace_o]}(.+?)#{Mx[:fa_monospace_c]}/, +          Mx[:src_monospace_o] + '\1' + Mx[:src_monospace_c]) +      unless dob.is==:code +        dob.obj=dob.obj. +          gsub(/#{Mx[:lnk_o]}(.+?)#{Mx[:lnk_c]}#{Mx[:rel_o]}\S+?#{Mx[:rel_c]}/,'\1'). +          gsub(/#{Mx[:url_o]}_(\S+?)#{Mx[:url_c]}/,'\1'). +          gsub(/#{Mx[:lnk_o]}(.+?)#{Mx[:lnk_c]}#{Mx[:url_o]}(\S+?)#{Mx[:url_c]}/, +            '\1 [link: <\2>]'). +          gsub(/#{Mx[:lnk_o]}(.+?)#{Mx[:lnk_c]}image/, +            '\1 [link: local image]'). +          gsub(/#{Mx[:url_o]}(\S+?)#{Mx[:url_c]}/,'\1') +        dob.obj,notes=extract_endnotes(dob.obj,endnotes_) +        dob.obj=dob.obj. +          gsub(/#{Mx[:gl_o]}(?:#lt|#060)#{Mx[:gl_c]}/,'<'). +          gsub(/#{Mx[:gl_o]}(?:#gt|#062)#{Mx[:gl_c]}/,'>'). +          gsub(/#{Mx[:gl_o]}#(?:038|amp)#{Mx[:gl_c]}/,'&'). +          gsub(/#{Mx[:gl_o]}#033#{Mx[:gl_c]}/,'!'). +          gsub(/#{Mx[:gl_o]}#035#{Mx[:gl_c]}/,'#'). +          gsub(/#{Mx[:gl_o]}#042#{Mx[:gl_c]}/,'*'). +          gsub(/#{Mx[:gl_o]}#045#{Mx[:gl_c]}/,'-'). +          gsub(/#{Mx[:gl_o]}#047#{Mx[:gl_c]}/,'/'). +          gsub(/#{Mx[:gl_o]}#095#{Mx[:gl_c]}/,'_'). +          gsub(/#{Mx[:gl_o]}#123#{Mx[:gl_c]}/,'{'). +          gsub(/#{Mx[:gl_o]}#125#{Mx[:gl_c]}/,'}'). +          gsub(/#{Mx[:gl_o]}#126#{Mx[:gl_c]}/,'~'). +          gsub(/#{Mx[:gl_o]}#169#{Mx[:gl_c]}/,'©') +      end +      dob=block_(dob) +      dob=code_(dob) +      dob.obj=dob.obj.gsub(/#{Mx[:br_page]}\s*|#{Mx[:br_page_new]}/,''). # remove page breaks +        gsub(/#{Mx[:url_o]}_(\S+?)#{Mx[:url_c]}/,'\1'). +        gsub(/#{Mx[:mk_o]}:name#(\S+?)#{Mx[:mk_c]}/,'').                 # remove name links +        gsub(/ |#{Mx[:nbsp]}/,' ').                                 # decide on +        gsub(/(?:^|[^_\\])#{Mx[:lnk_o]}(\S+?\.(?:png|jpg|gif)) .+?#{Mx[:lnk_c]}#{Mx[:url_o]}\S+?#{Mx[:url_c]}/, +          '    [ \1 ]'). #"[ #{dir.url.images_local}\/\\1 ]") +        gsub(/(?:^|[^_\\])#{Mx[:lnk_o]}(\S+?\.(?:png|jpg|gif)) .+?#{Mx[:lnk_c]}image/, +          '    [ \1 ]'). #"[ #{dir.url.images_local}\/\\1 ]") +        gsub(/(?:^|[^_\\])\{\s*\S+?\.(?:png|jpg|gif)\s+.+?"(.*?)"\s*\}\S+/, +          '[image: "\1"]') +      [dob,notes] +    end +    def object_marks +      @txtobj +    end +    self +  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 +    object_munge + +  - 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 diff --git a/org/param.org b/org/param.org new file mode 100644 index 00000000..20dbdf49 --- /dev/null +++ b/org/param.org @@ -0,0 +1,2363 @@ +-*- mode: org -*- +#+TITLE:       sisu param +#+DESCRIPTION: documents - structuring, various output representations & search +#+FILETAGS:    :sisu:param: +#+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 + +* dp.rb + +#+BEGIN_SRC ruby  :tangle "../lib/sisu/dp.rb" +# <<sisu_document_header>> +module SiSU_Param +  begin +    require 'uri' +    require 'pstore' +  rescue LoadError +    SiSU_Utils::CodeMarker.new(__LINE__,__FILE__,:fuchsia). +      error('uri or pstore NOT FOUND (LoadError)') +  end +  require_relative 'se'                                 # se.rb +    include SiSU_Env +  require_relative 'dp_make'                            # dp_make.rb +  require_relative 'dp_identify_markup'                 # dp_identify_markup.rb +  @@date=SiSU_Env::InfoDate.new +  @doc={ +    initialise: nil, +    markup: '', +    lnks: '', +    stmp: '', +    req: {}, +  } +  @@trigger=nil +  @@lv,@@flag={},{} +  @@tex_backslash="\\\\" +  class Parameters +    @@publisher='SiSU scribe' +    @@md=@@fns=@@pth=nil +    def initialize(opt) +      @opt=opt +      @cX||=SiSU_Screen::Ansi.new(@opt.act[:color_state][:set]) +      @fns=if @opt.act[:psql][:set] == [:on] #revisit CHECK +        opt.fns +      else opt.fns.gsub(/\.ssm$/,'.ssm.sst') +      end +      SiSU_Param::Instantiate.new.param_instantiate +      @env=SiSU_Env::InfoEnv.new(@fns) +      @pstorefile="#{@env.processing_path.ao}/#{@fns}.pstore" +    end +    def get +      if @opt.f_pth \ +      and @opt.f_pth[:pth] != Dir.pwd #BUG check +        # you may need to change Dir.pwd to @opt.f_pth[:pth] where the latter +        # has a path value that is different, however, f_pth is not always set! +        Dir.chdir(@opt.f_pth[:pth]) +      end +      if @@fns !=@fns \ +      or @@pth !=Dir.pwd               #@opt.f_pth[:pth] +        @@fns,@@pth=@fns,Dir.pwd       #@opt.f_pth[:pth] +        @@md=nil +      end +      if @@md.nil? \ +      or @opt.act[:maintenance][:set]==:on #not particularly helpful, as current cycle is through output types, with files changing, only helpful if deal with a file all output types before going to next file +        if File.exist?(@pstorefile) +          param_msg='Parameters from pstore' +          store=PStore.new(@pstorefile) +          store.transaction do +            @md=store['md'] +          end +          @md +        else +          param_msg='Parameters extracted' +          fns_array=@env.read_source_file(@opt.fns) +          @md=SiSU_Param::Parameters::Instructions.new(fns_array,@opt).extract +          @md +        end +        if defined? @md.title.main # on removal check problems with -U +          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], +              param_msg, +              @md.title.main +            ).txt_grey +          end +        end +        @@md=@md +      else @@md +      end +      begin +        @@md.opt=@opt +        @@md +      rescue +        SiSU_Utils::CodeMarker.new(__LINE__,__FILE__,:fuchsia). +          mark('has an existing option been selected?') +        exit +      end +    end +    class MdDefault +      def rights(author,date) +        @author,@date=author,date +        def assignment(author) +          'copyright not explicitly stated, ' \ +          + 'program "assigning" copyright to author: ' \ +          + author +        end +        def all +          s=nil +          if @author +            #puts assignment(@author) +            s ||=((@date =~/((?:1[4-9]|2[01])\d{2})/ ) \ +            ? ("Copyright (C) #{$1} #{@author}") +            : ('Copyright (C)' + @author))                     #matches years 1400 through 21\d\d +          end +          s +        end +        def copyright_and_license +          s=nil +          if @author +            #puts assignment(@author) +            s ||=((@date =~/((?:1[4-9]|2[01])\d{2})/ ) \ +            ? ("Copyright (C) #{$1} #{@author}") +            : ('Copyright (C)' + @author))                     #matches years 1400 through 21\d\d +          end +          s +        end +        def text +          all +        end +        def copyright +          def all +            s=nil +            if @author +              s ||=((@date =~/((?:1[4-9]|2[01])\d{2})/ ) \ +              ? ("Copyright (C) #{$1} #{@author}") +              : ('Copyright (C)' + @author))                     #matches years 1400 through 21\d\d +            end +            s +          end +          def text +            all +          end +          self +        end +        self +      end +    end +    class MdMake < SiSU_Param_Make::MdMake +    end +    class Md +      def initialize(str,opt,env) +        @s,@opt,@env=str,opt,env +      end +      def validate_length(s,l,n) +        #s=(s.length <= l) ? s : nil +        s=if s.is_a?(String) \ +        and s.length <= l +          s +        elsif s.is_a?(NilClass) +          nil +        elsif s.class !=String +          STDERR.puts "#{n} is #{s.class}: programming error, String expected #{__FILE__}:#{__LINE__}" +          s +        else +          SiSU_Screen::Ansi.new( +            'v', +            "*WARN* #{n} length #{s.length} exceeds set db field length #{l}, metadata dropped", +            @opt.fns +          ).warn unless @opt.act[:quiet][:set]==:on +          nil +        end +      end +      def name_format(name) +        if name +          name=name.strip +          @name_a_h=[] +          authors=name.scan(/[^;]+/) +          authors.each_with_index do |a,i| +            b=((a =~/\s*\|\s*/) ? (a.split(/\|/)) : [a]) +            if b[0] =~/"(.+?)"/ +              @name_a_h << { the: $1 } +            else +              x=b[0].scan(/[^,]+/) +              if x.length==1 +                @name_a_h << { the: x[0].strip } +              elsif x.length==2 +                @name_a_h << { the: x[0].strip, others: x[1].strip } +              else #p x.length +              end +            end +            b.delete_at(0) +            b.each do |d| +              k,c=nil +              k,c=/^(\S+)\s+(.*)/.match(d)[1,2] if d +              @name_a_h[i][:hon]=c.strip if k=='hon' +              @name_a_h[i][:affiliation]=c.strip if k=='affiliation' +              @name_a_h[i][:nationality]=c.strip if k=='nationality' +            end +          end +          l=@name_a_h.length +          name_str='' +          @name_a_h.each_with_index do |a,i| +            name_str += if a[:others] +              z=(((l - i) > 1) ? ', ' : '') +              "#{a[:others].strip} #{a[:the].strip}" + z +            else +              z=(((l - i) > 2) ? ', ' : '') +              "#{a[:the].strip}" + z +            end +          end +          { name_a_h: @name_a_h, name_str: name_str } +        else nil +        end +      end +      def build_hash(arr) +        @h={} +        arr.each_with_index do |x,i| +          a,b=nil,nil +          if x =~/^%\s/ #ignore comment +          elsif x =~/:(\S+?):\s+(.+)/ +            a,b=/:(\S+?):\s+(.+)\Z/m.match(x)[1,2] +            b=b.gsub(/\s*<br(?: \/)?>\s*/,' \\\\\\ ') +            b=if b =~/\n/m +              (b =~/;\n/m) \ +              ? (b.split(/;\s*\n\s*/).join(';')) +              : (b.split(/\s*\n\s*/).join(' ')) +            else +              b +            end +          elsif i == 0 +            a='main' +            b=x +          else +          end +          @h[a]=b +        end +        @h +      end +      def title +        a=@s.split(/\n%\s.+?$|[ ]*\n[ ]*/m) +        @h=build_hash(a) +        def main +          s=@h['main'] +          l,n=Db[:col_title_part],'title.main' +          validate_length(s,l,n) +        end +        def sub +          s=@h['subtitle'] +          l,n=Db[:col_title_part],'title.subtitle' +          validate_length(s,l,n) +        end +        def edition +          s=@h['edition'] +          l,n=Db[:col_title_edition],'title.edition' +          validate_length(s,l,n) +        end +        def note +          s=@h['note'] +          l,n=Db[:col_info_note],'title.note' +          validate_length(s,l,n) +        end +        def short +          s=@h['short'] \ +          ? @h['short'] +          : @h['main'] +          l,n=Db[:col_title_part],'title.short' +          validate_length(s,l,n) +        end +        def full +          s=@h['subtitle'] \ +          ? (@h['main'] + ' - ' + @h['subtitle']) +          : @h['main'] +          l,n=Db[:col_title],'title.full' +          validate_length(s,l,n) +        end +        def language +          s=@h['language'] +          l,n=Db[:col_language],'title.language' +          validate_length(s,l,n) +        end +        def language_char # look into, this must be set, from 1 directory stub (.fi), 2 filename (~fi), [3 (not used) document header (@title:\n  :language_char: fi)] +          s=@h['language_char'] +          l,n=Db[:col_language_char],'title.language_char' +          validate_length(s,l,n) +        end +        self +      end +      def creator #there are sub categories that need to be catered for and sometimes more than one author etc.; implement array.to_s.length validation test later, current test on string approximate as string is not used +        a=@s.split(/\n%\s.+?$|[ ]*\n[ ]*/m) +        @h=build_hash(a) +        def author +          @h['author']=(@h['author'] \ +          ? @h['author'] +          : @h['main']) +          names=name_format(@h['author']) +          s=names[:name_str] +          l,n=Db[:col_name],'creator.author' +          validate_length(s,l,n) +        end +        def author_detail +          s=@h['author'] \ +          ? @h['author'] +          : @h['main'] +          names=name_format(s) +          names[:name_a_h] +        end +        def email #revisit +          s=@h['email'] +        end +        def editor +          names=@h['editor'] \ +          ? name_format(@h['editor']) +          : nil +          s=(names.is_a?(Hash)) \ +          ? names[:name_str] +          : nil +          s=if s +            l,n=Db[:col_name],'creator.editor' +            validate_length(s,l,n) +          else nil +          end +        end +        def editor_detail +          names=@h['editor'] \ +          ? name_format(@h['editor']) +          : nil +          (names.is_a?(Hash)) \ +          ? names[:name_a_h] +          : nil +        end +        def contributor +          names=@h['contributor'] \ +          ? name_format(@h['contributor']) +          : nil +          s=(names.is_a?(Hash)) \ +          ? names[:name_str] +          : nil +          s=if s +            l,n=Db[:col_name],'creator.author' +            validate_length(s,l,n) +          else nil +          end +        end +        def contributor_detail +          names=@h['contributor'] \ +          ? name_format(@h['contributor']) +          : nil +          (names.is_a?(Hash)) \ +          ? names[:name_a_h] +          : nil +        end +        def illustrator +          names=@h['illustrator'] \ +          ? name_format(@h['illustrator']) +          : nil +          s=(names.is_a?(Hash)) \ +          ? names[:name_str] +          : nil +          s=if s +            l,n=Db[:col_name],'creator.illustrator' +            validate_length(s,l,n) +          else nil +          end +        end +        def illustrator_detail +          names=@h['illustrator'] \ +          ? name_format(@h['illustrator']) +          : nil +          (names.is_a?(Hash)) \ +          ? names[:name_a_h] +          : nil +        end +        def photographer +          names=@h['photographer'] \ +          ? name_format(@h['photographer']) +          : nil +          s=(names.is_a?(Hash)) \ +          ? names[:name_str] +          : nil +          s=if s +            l,n=Db[:col_name],'creator.photographer' +            validate_length(s,l,n) +          else nil +          end +        end +        def photographer_detail +          names=@h['photographer'] \ +          ? name_format(@h['photographer']) +          : nil +          (names.is_a?(Hash)) \ +          ? names[:name_a_h] +          : nil +        end +        def translator +          names=@h['translator'] \ +          ? name_format(@h['translator']) +          : nil +          s=(names.is_a?(Hash)) \ +          ? names[:name_str] +          : nil +          s=if s +            l,n=Db[:col_name],'creator.translator' +            validate_length(s,l,n) +          else nil +          end +        end +        def translator_detail +          names=@h['translator'] \ +          ? name_format(@h['translator']) +          : nil +          (names.is_a?(Hash)) \ +          ? names[:name_a_h] +          : nil +        end +        def audio +          names=@h['audio'] \ +          ? name_format(@h['audio']) +          : nil +          s=(names.is_a?(Hash)) \ +          ? names[:name_str] +          : nil +          s=if s +            l,n=Db[:col_name],'creator.audio' +            validate_length(s,l,n) +          else nil +          end +        end +        def audio_detail +          names=@h['audio'] \ +          ? name_format(@h['audio']) +          : nil +          (names.is_a?(Hash)) \ +          ? names[:name_a_h] +          : nil +        end +        def digitized_by +          names=@h['digitized_by'] \ +          ? name_format(@h['digitized_by']) +          : nil +          s=(names.is_a?(Hash)) \ +          ? names[:name_str] +          : nil +          s=if s +            l,n=Db[:col_name],'creator.digitized_by' +            validate_length(s,l,n) +          else nil +          end +        end +        def digitized_by_detail +          names=@h['digitized_by'] \ +          ? name_format(@h['digitized_by']) +          : nil +          (names.is_a?(Hash)) \ +          ? names[:name_a_h] +          : nil +        end +        def prepared_by +          names=@h['prepared_by'] \ +          ? name_format(@h['prepared_by']) +          : nil +          s=(names.is_a?(Hash)) \ +          ? names[:name_str] +          : nil +          s=if s +            l,n=Db[:col_name],'creator.prepared_by' +            validate_length(s,l,n) +          else nil +          end +        end +        def prepared_by_detail +          names=@h['prepared_by'] \ +          ? name_format(@h['prepared_by']) +          : nil +          names=name_format(@h['prepared_by']) +          (names.is_a?(Hash)) \ +          ? names[:name_a_h] +          : nil +        end +        self +      end +      def rights +        a=@s.split(/\n%\s.+?$|[ ]*\n[ ]*/m) +        @h=build_hash(a) +        def copyright +          def text #you may wish to expand to take from all +            s=if @h['copyright'] then @h['copyright'] +            elsif @h['text']     then @h['text'] +            elsif @h['main']     then @h['main'] +            else +              SiSU_Screen::Ansi.new( +                @opt.act[:color_state][:set], +                'WARNING Document Copyright missing; provide @rights: :copyright:' +              ).warn if (@opt.act[:verbose][:set]==:on \ +                || @opt.act[:verbose_plus][:set]==:on \ +                || @opt.act[:maintenance][:set]==:on) +              '' +            end +            l,n=Db[:col_info_note],'rights.copyright.text' +            validate_length(s,l,n) +          end +          def translation +            s=@h['translation'] \ +            ? @h['translation'] +            : nil +            l,n=Db[:col_info_note],'rights.copyright.translation' +            validate_length(s,l,n) +          end +          def illustrations +            s=@h['illustrations'] \ +            ? @h['illustrations'] +            : nil +            l,n=Db[:col_info_note],'rights.copyright.illustrations' +            validate_length(s,l,n) +          end +          def photographs +            s=@h['photographs'] \ +            ? @h['photographs'] +            : nil +            l,n=Db[:col_info_note],'rights.copyright.photographs' +            validate_length(s,l,n) +          end +          def digitization +            s=@h['digitization'] \ +            ? @h['digitization'] +            : nil +            l,n=Db[:col_info_note],'rights.copyright.digitization' +            validate_length(s,l,n) +          end +          def audio +            s=@h['audio'] \ +            ? @h['audio'] +            : nil +            l,n=Db[:col_info_note],'rights.copyright.audio' +            validate_length(s,l,n) +          end +          self +        end +        def license +          s=@h['license'] \ +          ? @h['license'] +          : nil +          l,n=Db[:col_info_note],'rights.license' +          validate_length(s,l,n) +        end +        def sep(str) +          ' \\\\ ' +        end +        def copyright_and_license +          s=if @h['copyright_and_license'] then @h['copyright_and_license'] +          else +            s='' +            if defined? copyright.text \ +            and copyright.text \ +            and not copyright.text.empty? +              v=sep(copyright.text) +              s +=copyright.text + v +            end +            if defined? copyright.license \ +            and copyright.license \ +            and not copyright.license.empty? +              s +=copyright.license +            end +            if s.empty? +              SiSU_Screen::Ansi.new( +                @opt.act[:color_state][:set], +                'WARNING Document Rights information missing; provide @rights: :copyright:' +              ).warn if (@opt.act[:verbose][:set]==:on \ +                || @opt.act[:verbose_plus][:set]==:on \ +                || @opt.act[:maintenance][:set]==:on) +            else +              l,n=Db[:col_info_note],'rights.all' +              validate_length(s,l,n) +            end +            s=s.gsub(/ [\\]+\s+$/,'') +          end +          s +        end +        def all +          s=if @h['all'] then @h['all'] +          else +            s='' +            if defined? copyright.text \ +            and copyright.text \ +            and not copyright.text.empty? +              v=sep(copyright.text) +              s +='Copyright: ' + copyright.text + v +            end +            if defined? copyright.translation \ +            and copyright.translation \ +            and not copyright.translation.empty? +              v=sep(copyright.translation) +              s +='translation: ' + copyright.translation + v +            end +            if defined? copyright.illustrations \ +            and copyright.illustrations \ +            and not copyright.illustrations.empty? +              v=sep(copyright.illustrations) +              s +='illustrations: ' + copyright.illustrations + v +            end +            if defined? copyright.photographs \ +            and copyright.photographs \ +            and not copyright.photographs.empty? +              v=sep(copyright.photographs) +              s +='photographs: ' + copyright.photographs + v +            end +            if defined? copyright.digitization \ +            and copyright.digitization \ +            and not copyright.digitization.empty? +              v=sep(copyright.digitization) +              s +='digitization: ' + copyright.digitization + v +            end +            if defined? copyright.audio \ +            and copyright.audio \ +            and not copyright.audio.empty? +              v=sep(copyright.audio) +              s +='audio: ' + copyright.audio + v +            end +            if defined? copyright.license \ +            and copyright.license \ +            and not copyright.license.empty? +              s +='License: ' + copyright.license +            end +            if s.empty? +              SiSU_Screen::Ansi.new( +                @opt.act[:color_state][:set], +                'WARNING Document Rights information missing; provide @rights: :copyright:' +              ).warn if (@opt.act[:verbose][:set]==:on \ +                || @opt.act[:verbose_plus][:set]==:on \ +                || @opt.act[:maintenance][:set]==:on) +            else +              l,n=Db[:col_info_note],'rights.all' +              validate_length(s,l,n) +            end +            s=s.gsub(/ [\\]+\s+$/,'') +          end +          s +        end +        self +      end +      def identifier +        a=@s.split(/\n%\s.+?$|[ ]*\n[ ]*/m) +        @h=build_hash(a) +        def oclc +          s=@h['oclc'] +          l,n=Db[:col_library],'identifier.oclc' +          validate_length(s,l,n) +        end +        def isbn +          s=@h['isbn'] +          l,n=Db[:col_small],'identifier.isbn' +          validate_length(s,l,n) +        end +        def pg +          s=@h['pg'] +          l,n=Db[:col_small],'identifier.pg' +          validate_length(s,l,n) +        end +        self +      end +      def classify +        a=@s.split(/(\n%\s.+?$|[ ]*)(?:\n[ ]*(?=:)|\Z)/m) +        @h=build_hash(a) +        def topic_register +          s=@h['topic_register'] +          l,n=Db[:col_info_note],'classify.topic_register' +          validate_length(s,l,n) +        end +        def subject +          s=@h['subject'] +          l,n=Db[:col_txt_long],'classify.subject' +          validate_length(s,l,n) +        end +        def keywords +          s=@h['keywords'] +          l,n=Db[:col_txt_long],'classify.keywords' +          validate_length(s,l,n) +        end +        def loc +          s=@h['loc'] +          l,n=Db[:col_library],'classify.loc' +          validate_length(s,l,n) +        end +        def dewey +          s=@h['dewey'] +          l,n=Db[:col_library],'classify.dewey' +          validate_length(s,l,n) +        end +        self +      end +      def publisher +        a=@s.split(/\n%\s.+?$|[ ]*\n[ ]*/m) +        @h=build_hash(a) +        s=@h['main'] +        l,n=Db[:col_name],'publisher' +        validate_length(s,l,n) +      end +      def date +        a=@s.split(/\n%\s.+?$|[ ]*\n[ ]*/m) +        @h=build_hash(a) +        def added_to_site +          s=@h['added_to_site'] +          l,n=Db[:col_date_text],'date.added_to_site' +          validate_length(s,l,n) +        end +        def available +          s=@h['available'] +          l,n=Db[:col_date_text],'date.available' +          validate_length(s,l,n) +        end +        def created +          s=@h['created'] +          l,n=Db[:col_date_text],'date.created' +          validate_length(s,l,n) +        end +        def issued +          s=@h['issued'] +          l,n=Db[:col_date_text],'date.issued' +          validate_length(s,l,n) +        end +        def modified +          s=@h['modified'] +          l,n=Db[:col_date_text],'date.modified' +          validate_length(s,l,n) +        end +        def published +          s=@h['published']=(@h['published'] ? @h['published'] : @h['main']) +          l,n=Db[:col_date_text],'date.published' +          validate_length(s,l,n) +        end +        def valid +          s=@h['valid'] +          l,n=Db[:col_date_text],'date.valid' +          validate_length(s,l,n) +        end +        self +      end +      #def language                     # as things stand this should really be populated from title.language and original.language, resolve +      #  a=@s.split(/\n%\s.+?$|[ ]*\n[ ]*/m) +      #  @h=build_hash(a) +      #  def document +      #    s=@h['document']=(@h['document'] ? @h['document'] : @h['main']) +      #    l,n=Db[:col_language],'language.document' +      #    validate_length(s,l,n) +      #  end +      #  def document_char +      #    s=@h['document_char']=(@h['document_char'] ? @h['document_char'] : nil) +      #    l,n=Db[:col_language_char],'language.document_char' +      #    validate_length(s,l,n) +      #  end +      #  def original +      #    s=@h['original'] +      #    l,n=Db[:col_language],'language.original' +      #    validate_length(s,l,n) +      #  end +      #  def original_char +      #    s=@h['original_char'] +      #    l,n=Db[:col_language_char],'language.original_char' +      #    validate_length(s,l,n) +      #  end +      #  self +      #end +      def current_publisher +        @s +      end +      def original +        a=@s.split(/\n%\s.+?$|[ ]*\n[ ]*/m) +        @h=build_hash(a) +        def publisher +          s=@h['publisher'] +          l,n=Db[:col_name],'original.publisher' +          validate_length(s,l,n) +        end +        def language +          s=@h['language'] +          l,n=Db[:col_language],'original.language' +          validate_length(s,l,n) +        end +        def language_char +          s=@h['language_char'] +          l,n=Db[:col_language_char],'original.language_char' +          validate_length(s,l,n) +        end +        def source +          s=@h['source'] +          l,n=Db[:col_name],'original.source' +          validate_length(s,l,n) +        end +        def institution +          s=@h['institution'] +          l,n=Db[:col_name],'original.institution' +          validate_length(s,l,n) +        end +        def nationality +          s=@h['nationality'] +          l,n=Db[:col_language],'original.nationality' +          validate_length(s,l,n) +        end +        self +      end +      def notes +        a=@s.split(/\n%\s.+?$|[ ]*\n[ ]*/m) +        @h=build_hash(a) +        def description +          s=@h['description'] +          l,n=Db[:col_info_note],'notes.description' +          validate_length(s,l,n) +        end +        def abstract +          s=@h['abstract'] +          l,n=Db[:col_info_note],'notes.abstract' +          validate_length(s,l,n) +        end +        def comment +          s=@h['comment'] +          l,n=Db[:col_info_note],'notes.comment' +          validate_length(s,l,n) +        end +        def coverage +          s=@h['coverage'] +          l,n=Db[:col_info_note],'notes.coverage' +          validate_length(s,l,n) +        end +        def relation +          s=@h['relation'] +          l,n=Db[:col_info_note],'notes.relation' +          validate_length(s,l,n) +        end +        def source +          s=@h['source'] +          l,n=Db[:col_txt_long],'notes.source' +          validate_length(s,l,n) +        end +        def history +          s=@h['history'] +          l,n=Db[:col_txt_long],'notes.history' +          validate_length(s,l,n) +        end +        def type +          s=@h['type'] +          l,n=Db[:col_txt_long],'notes.relation' +          validate_length(s,l,n) +        end +        def format +          s=@h['format'] +          l,n=Db[:col_txt_short],'notes.format' +          validate_length(s,l,n) +        end +        def prefix +          @h['prefix'] +        end +        self +      end +    end +    class Instructions +      @doc={ lv: [] } +      @doc[:fns],@doc[:fnb],@doc[:scr_suffix]='','','' +      @@publisher='SiSU scribe' +      attr_accessor :make,:env,:path,:file,:fn,:fns,:fno,:fnb,:fnn,:fnt,:fnl,:flv,:fnz,:fnstex,:ocn,:sfx_src,:pdf,:file_type,:dir_out,:dir_tex,:dir_lout,:txt_path,:sisu,:project_details,:ruby_version,:title,:subtitle,:full_title,:html_title,:subtitle_tex,:creator,:classify,:author_home,:author,:email,:author_title,:author_nationality,:authors,:authorship,:translator,:illustrator,:prepared_by,:digitized_by,:subject,:description,:publisher,:current_publisher,:contributor,:date,:date_created,:date_issued,:date_available,:date_valid,:date_modified,:date_translated,:date_added_to_site,:date_scheme,:date_created_scheme,:date_issued_scheme,:date_available_scheme,:date_valid_scheme,:date_modified_scheme,:type,:format,:identifier,:source,:language,:language_original,:relation,:coverage,:rights,:keywords,:comments,:abstract,:cls_loc,:cls_dewey,:cls_pg,:cls_isbn,:papersize,:papersize_array,:toc,:lv0,:lv1,:lv2,:lv3,:lv4,:lv5,:lv6,:lvs,:pagenew,:pagebreak,:pageline,:num_top,:bold_match_list,:italics_match_list,:substitution_match_list,:emphasis_set_to,:toc_lev_limit,:flag_biblio,:flag_auto_biblio,:flag_endnotes,:flag_auto_endnotes,:flag_glossary,:flag_separate_endnotes,:flag_separate_endnotes_make,:markup,:markup_instruction,:flag_tables,:vocabulary,:doc_css,:yaml,:lnk,:links,:prefix_a,:prefix_b,:suffix,:information,:contact,:icon,:image,:ad_url,:ad_png,:ad_alt,:ad_began,:flag_promo,:promo,:ad_home,:stmp,:stmpd,:sc_filename,:sc_number,:sc_date,:sc_time,:sc_info,:yamladdr,:locale,:wc_lines,:wc_words,:wc_bytes,:file_encoding,:filesize,:user,:home,:hostname,:pwd,:firstseg,:programs,:author_copymark,:i18n,:lang,:lang_code_insert,:en,:notes,:dgst,:generated,:tags,:tag_array,:concord_make,:seg_names,:seg_autoname_safe,:set_header_title,:set_heading_top,:set_heading_seg,:heading_seg_first,:heading_seg_first_flag,:base_program,:ec,:opt,:sem_tag,:book_idx,:topic_register,:topic_register_array,:original,:writing_focus,:audio,:daisy,:home_button_image,:home_button_links,:footer_links,:cover_image,:man_section +      def initialize(fns_array,opt) +        @env=@path,@file=@fn=@fns=@fno=@fnb=@fnn=@fnt=@fnl=@flv=@fnz=@fnstex=@ocn=@sfx_src=@pdf=@file_type=@dir_out=@dir_tex=@dir_lout=@txt_path=@make=@flag_biblio=@flag_auto_biblio=@flag_endnotes=@flag_auto_endnotes=@flag_glossary=@flag_separate_endnotes=@flag_separate_endnotes_make=@sisu=@project_details=@ruby_version=@title=@subtitle=@full_title=@html_title=@subtitle_tex=@creator=@classify=@author_home=@author=@email=@author_title=@author_nationality=@translator=@illustrator=@prepared_by=@digitized_by=@subject=@description=@publisher=@current_publisher=@contributor=@date=@date_created=@date_issued=@date_available=@date_valid=@date_modified=@date_translated=@date_added_to_site=@date_scheme=@date_created_scheme=@date_issued_scheme=@date_available_scheme=@date_valid_scheme=@date_modified_scheme=@type=@format=@identifier=@source=@language=@language_original=@relation=@coverage=@rights=@keywords=@comments=@abstract=@cls_loc=@cls_dewey=@cls_pg=@cls_isbn=@papersize=@toc=@lv0=@lv1=@lv2=@lv3=@lv4=@lv5=@lv6=@pagenew=@pagebreak=@pageline=@num_top=@bold_match_list=@italics_match_list=@substitution_match_list=@emphasis_set_to=@toc_lev_limit=@flag_tables=@vocabulary=@doc_css=@yaml=@lnk=@links=@prefix_a=@prefix_b=@suffix=@information=@contact=@icon=@ad_url=@ad_png=@ad_alt=@ad_began=@promo=@ad_home=@stmp=@stmpd=@sc_filename=@sc_number=@sc_date=@sc_time=@sc_info=@yamladdr=@locale=@wc_lines=@wc_words=@wc_bytes=@file_encoding=@filesize=@firstseg=@programs=@author_copymark=@i18n=@lang=@lang_code_insert=@en=@notes=@dgst=@generated=@heading_seg_first=@base_program=@topic_register=@original=@writing_focus=@audio=@home_button_image=@home_button_links=@cover_image=@man_section=nil +        @data,      @path,  @fns,   @fno,   @opt= +          fns_array,opt.pth,opt.fns,opt.fno,opt #@data used as data +        @flag_tables,@set_header_title,@set_heading_top,@set_heading_seg,@heading_seg_first_flag,@flag_promo,@book_idx= +          false,     false,            false,           false,           false,                  false,      false +        @seg_autoname_safe=true +        @daisy,@sem_tag=false,false +        @authorship,@markup_instruction,@image='','','','' #check which other values should be set to empty rather than nil +        @markup=@markup_instruction #use @markup_instruction +        @doc,@fn,@make_italic,@tag_hash,@ec={},{},{},{},{},{} +        @flv,@lang,@seg_names,@tags,@tag_array,@tag_a,@ec[:image],@ec[:audio],@ec[:multimedia]=Array.new(9){[]} +        @authors,@topic_register_array,@papersize_array=[],[],[] +        @lvs=[nil,0,0,0,0,0,0] +        @emphasis_set_to='bold' +        @lang_code_insert=SiSU_Env::FilenameLanguageCodeInsert.new(@opt).language_code_insert +        @footer_links= { left: { say: '', url: '' }, center: { say: '', url: '' } } +        @rgx_image=/(?:^|[^_\\])\{(?:\s*|\~\^\s+)(\S+?\.(?:png|jpg|gif)\b)/m +        @rgx_audio=/\{\s*(\S+?\.(?:mp3|ogg))/ +        @rgx_mm=/\{\s*(\S+?\.(?:ogg|mpeg))/ #expand and distinguish ogg +        Dir.chdir(@opt.f_pth[:pth]) +        begin +        rescue +          SiSU_Errors::Rescued.new($!,$@,@opt.selections.str,@fns).location do +            __LINE__.to_s + ':' + __FILE__ +          end +        ensure +        end +        @header_make_links_append=:no +        common_makes=(defined? @opt.make_instructions_pod) \ +        && @opt.make_instructions_pod !=nil \ +        && @opt.make_instructions_pod[:makeset]==true \ +        ? @opt.make_instructions_pod +        : @opt.make_instructions +        if common_makes[:makeset] +          @pagenew=common_makes[:pagenew] +          @pagebreak=common_makes[:pagebreak] +          @pageline=common_makes[:pageline] +          @toc=common_makes[:toc] +          @lv0=common_makes[:lv0] +          @lv1=common_makes[:lv1] +          @lv2=common_makes[:lv2] +          @lv3=common_makes[:lv3] +          @lv4=common_makes[:lv4] +          @lv5=common_makes[:lv5] +          @lv6=common_makes[:lv6] +          @num_top=common_makes[:num_top] +          @i18n=common_makes[:i18n] +          @man_section=common_makes[:man_section] +          @emphasis_set_to=common_makes[:emphasis_set_to] +          @bold_match_list=common_makes[:bold_match_list] +          @italics_match_list=common_makes[:italics_match_list] +          @substitution_match_list=common_makes[:substitution_match_list] +          @footer_links=common_makes[:footer_links] +          @home_button_links=common_makes[:home_button_links] +          @home_button_image=common_makes[:home_button_image] +          @cover_image=common_makes[:cover_image] +          @lnk=@links=common_makes[:links] +          @header_make_links_append=common_makes[:links_append] +        end +      end +      #protected +      def extract +        begin +          @user,@home,@hostname,@pwd=ENV['USER'],ENV['HOME'],ENV['HOSTNAME'],ENV['PWD'] +          @programs,@wc,@language,@language_original={},{},{},{} +          @en={ sum: 0, mark: 0, note: 0, mismatch: 0 } +          @prog=SiSU_Env::InfoSettings.new +          @sys=SiSU_Env::SystemCall.new +          @env=SiSU_Env::InfoEnv.new(@fns) #watch +          if (@opt.act[:verbose_plus][:set]==:on \ +          || @opt.act[:maintenance][:set]==:on) +            puts 'system locale: ' + @sys.locale +          end +          if @prog.wc \ +          and @sys.wc +            wc=%x{wc #{fns}} +            wca=wc.scan(/\d+/) +            @wc_lines,@wc_words,@wc_bytes=wca[0].to_i,wca[1].to_i,wca[2].to_i +          else +            fns_a=@data.dup +            tmp=fns_a.join +            fns_a=tmp.scan(/\S+/) +            @wc_words=fns_a.length +            fns_a=tmp=nil +          end +          @concord_make=(@wc_words > @env.concord_max) ? false : true +          @locale=@sys.locale +          @file_encoding=@sys.file_encoding(fns,@opt.act) +          # programs set here for things that affect output appearance only +          @programs[:pdf]=SiSU_Env::SystemCall.new.program_found?('pdflatex') +          if @opt.act[:psql][:set] == [:ok] +            m=/((.+?)(?:\~\w\w(?:_\w\w)?)?)\.((?:-|ssm\.)?sst|ssm|ssi)$/ #watch added match for sss +            @fnn,@fnb,@fnt=@fns[m,1],@fns[m,2],@fns[m,3] +            @flv=@env.document_language_versions_found[:f] +          else +            m=/((.+?)(?:\~\w\w(?:_\w\w)?)?)\.((?:-|ssm\.)?sst|ssm)$/ #watch added match for sss +            @fnn,@fnb,@fnt=@fns[m,1],@fns[m,2],@fns[m,3] +            @flv=@env.document_language_versions_found[:f] +            @fnz=(@fns =~/\.(?:ssm\.sst|ssm)$/) ? (@fnn + '.ssm.txz') : (@fnn + '.sst.txz') +          end +          @papersize=@env.papersize #'A4' #default size #get first from SiSU_Env:: # @env is probably no longer most appropriate name! as default info is more general +          @sfx_src=@fns[m,2] +          if @fns =~ /(?:-|ssm\.)?sst$/ \ +          and not @opt.act[:psql][:set] == [:ok] +            @env_out_root=@env.path.output +            @dir_out="#{@env.path.output}/#{@fnb}" +            @dir_tex=@env.processing_path.tex +            @dir_lout=@env.processing_path.lout +            @@publisher='SiSU http://www.jus.uio.no/sisu' +          end +          @txt_path=@txt_path ||= @env.path.output +          @stmp=%{#{@fns}}[/^(.+?)\..*/m,1] +          @fnstex=@fns.gsub(/_/,'\_\-').gsub(/\./,'.\-') +          @flag_endnotes,@flag_auto_endnotes,@flag_separate_endnotes=false,false,false +          @flag_separate_endnotes_make=true +          @flag_glossary=false +          @flag_biblio,@flag_auto_biblio=false,false +          ver=SiSU_Env::InfoVersion.instance +          @project_details=ver.get_version +          @ruby_version=ver.rbversion +          @generated=Time.now +          fns_array=@data.dup +          skip unless fns_array                                                    # consider +          @code_flag=false +          flag_code_curly=:not_code_curly +          flag_code_tics=:not_code_tics +          fns_array.each do |para|                                               #% scan document +            if para !~/^%+\s/ \ +            and para =~/<![abcdeghijklmnopqrstuvwxyz]/i # <!f not included +              raise "Old markup style in file #{@fns}, current version #{@project_details.project} #{@project_details.version} #{@project_details.date_stamp} #{@project_details.date}:\n\t\t#{para}\n\n" +            end +            if para =~/^code\{/ +              flag_code_curly=:code_curly +            elsif para =~/^\}code/ +              flag_code_curly=:not_code_curly +            elsif para =~/^``` code/ +              flag_code_tics=:code_tics +            elsif flag_code_tics ==:code_tics \ +            and para =~/^```/ +              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 +            regx_header=/^@\S+?:[+-]?\s/ +            if para =~regx_header \ +            and not @code_flag #or para=~/^(?:1|:?A)~/ +              case para +              when /^@title:(.+)/m                                               #% * header metadata - title +                @title=SiSU_Param::Parameters::Md.new($1.strip,@opt,@env).title +              when /^@creator:(.+)/m                                             #% * header metadata - creator +                @creator=SiSU_Param::Parameters::Md.new($1.strip,@opt,@env).creator +                @authorship=@author=@creator.author +                @authors=@creator.author_detail +              when /^@date:(.+)/m                                                #% * header metadata - date +                @date=SiSU_Param::Parameters::Md.new($1.strip,@opt,@env).date +              when /^@publisher:\s+(.+)/m                                        #% * header metadata - publisher +                @publisher=SiSU_Param::Parameters::Md.new($1.strip,@opt,@env).current_publisher +                @current_publisher=@publisher +              when /^@rights:(.+)/m                                              #% * header metadata - rights +                @rights=SiSU_Param::Parameters::Md.new($1.strip,@opt,@env).rights +              when /^@classify:(.+)/m                                            #% * header metadata - classify +                @classify=SiSU_Param::Parameters::Md.new($1.strip,@opt,@env).classify +              when /^@identifier:(.+)/m                                          #% * header metadata - identifier +                @identifier=SiSU_Param::Parameters::Md.new($1.strip,@opt,@env).identifier +              when /^@original:(.+)/m                                            #% * header metadata - original (document) +                @original=SiSU_Param::Parameters::Md.new($1.strip,@opt,@env).original +                @source=@original.source +              when /^@notes?:\s(.+)\Z/m                                          #% * header metadata - notes +                @notes=SiSU_Param::Parameters::Md.new($1.strip,@opt,@env).notes +              when /^@links:\s+(.+?)\Z/m                                         #% * header metadata - links +                links=SiSU_Param::Parameters::MdMake.new($1.strip,@opt,@env).make_links.links +                @lnk=@links=if @header_make_links_append == :yes +                  (links) \ +                    ? (links + @links) +                    : @links +                else +                  (links) \ +                    ? (links) +                    : @links +                end +              when /^@make:(.+)/m                                                #% * header processing - make +                @make=SiSU_Param::Parameters::MdMake.new($1.strip,@opt,@env).make +                makes=SiSU_Param_Make::MakeHead.new(@make).make_instruct +                @pagenew=(makes[:pagenew]) \ +                  ? (makes[:pagenew]) \ +                  : @pagenew +                @pagebreak=(makes[:pagebreak]) \ +                  ? (makes[:pagebreak]) \ +                  : @pagebreak +                @pageline=(makes[:pageline]) \ +                  ? (makes[:pageline]) \ +                  : @pageline +                @toc=(makes[:toc]) ? (makes[:toc]) : @toc +                @lv0=(makes[:lv0]) ? (makes[:lv0]) : @lv0 +                @lv1=(makes[:lv1]) ? (makes[:lv1]) : @lv1 +                @lv2=(makes[:lv2]) ? (makes[:lv2]) : @lv2 +                @lv3=(makes[:lv3]) ? (makes[:lv3]) : @lv3 +                @lv4=(makes[:lv4]) ? (makes[:lv4]) : @lv4 +                @lv5=(makes[:lv5]) ? (makes[:lv5]) : @lv5 +                @lv6=(makes[:lv6]) ? (makes[:lv6]) : @lv6 +                @num_top= +                  (makes[:num_top]) \ +                  ? (makes[:num_top]) \ +                  : @num_top +                @substitution_match_list= +                  (makes[:substitution_match_list]) \ +                  ? (makes[:substitution_match_list]) \ +                  : @substitution_match_list +                @bold_match_list= +                  (makes[:bold_match_list]) \ +                  ? (makes[:bold_match_list]) \ +                  : @bold_match_list +                @italics_match_list= +                  (makes[:italics_match_list]) \ +                  ? (makes[:italics_match_list]) \ +                  : @italics_match_list +                @emphasis_set_to= +                  (makes[:emphasis_set_to]) \ +                  ? (makes[:emphasis_set_to]) \ +                  : @emphasis_set_to +                @i18n= +                  (makes[:i18n]) \ +                  ? (makes[:i18n]) \ +                  : @i18n +                @man_section= +                  (makes[:man_section]) \ +                  ? (makes[:man_section]) \ +                  : @man_section +                @footer_links= +                  (makes[:footer_links]) \ +                  ? (makes[:footer_links]) \ +                  : @footer_links +                @home_button_links= +                  (makes[:home_button_links]) \ +                  ? (makes[:home_button_links]) \ +                  : @home_button_links +                @home_button_image= +                  (makes[:home_button_image]) \ +                  ? (makes[:home_button_image]) \ +                  : @home_button_image +                @cover_image= +                  (makes[:cover_image]) \ +                  ? (makes[:cover_image]) \ +                  : @cover_image +              end +              @lv0 ||=/^0~/ +              @lv1 ||=/^1~/ +              @lv2 ||=/^2~/ +              @lv3 ||=/^3~/ +              @lv4 ||=/^4~/ +              @lv5 ||=/^5~/ +              @lv6 ||=/^6~/ +            else                                                                 #% * +              l_0=l_1=l_2=l_3=l_4=l_5='' +              if defined? @make.headings[0] +                l_0=if defined? @make.headings[0][0] \ +                and @make.headings[0][0] =~/\S+/ +                  "|^#{@make.headings[0][0]}" +                end +                l_1=if defined? @make.headings[0][1] \ +                and @make.headings[0][1] =~/\S+/ +                  "|^#{@make.headings[0][1]}" +                end +                l_2=if defined? @make.headings[0][2] \ +                and @make.headings[0][2] =~/\S+/ +                  "|^#{@make.headings[0][2]}" +                end +                l_3=if defined? @make.headings[0][3] \ +                and @make.headings[0][3] =~/\S+/ +                  "|^#{@make.headings[0][3]}" +                end +                l_4=if defined? @make.headings[0][4] \ +                and @make.headings[0][4] =~/\S+/ +                  "|^#{@make.headings[0][4]}" +                end +                l_5=if defined? @make.headings[0][5] \ +                and @make.headings[0][5] =~/\S+/ +                  "|^#{@make.headings[0][5]}" +                end +              end +              case para +              #when /^:?A~/ +              when /^:?B~#{l_0}/ +                @lvs[1]=1 +              when /^:?C~#{l_1}/ +                @lvs[2]=1 +              when /^:?D~#{l_2}/ +                @lvs[3]=1 +              when /^1~#{l_3}/ +                @lvs[4]=1 +              when /^2~#{l_4}/ +                @lvs[5]=1 +              when /^3~#{l_5}/ +                @lvs[6]=1 +              end +              if para =~ /^:?A~/                                                  #% processing +                if not defined? @title.full.nil? +                  tf=para[/^:A~\S*(.+)$/m,1] +                  tf="@title: #{tf}" +                  @title=SiSU_Param::Parameters::Md.new(tf.strip,@opt,@env).title +                end +                creator=(@creator.is_a?(SiSU_Param::Parameters::Md) \ +                && defined? @creator.author \ +                && @creator.author.is_a?(String)) \ +                ? " #{@creator.author}" +                : '' +                title=@title.full.gsub(/\s*(?:<p>|<p \/>|<br>|<br \/>)\s*/,' '). +                  gsub(/~\{.+?\}~/,'') +                SiSU_Screen::Ansi.new( +                  @opt.act[:color_state][:set], +                  'Document Parameters', +                  %{#{title}#{creator}} +                ).txt_grey if @opt.act[:verbose][:set]==:on +              end +              unless @code_flag +                if para =~/^1~!biblio(?:graphy)?/ +                  @flag_auto_biblio,@flag_biblio=false,true +                  #@flag_biblio=true +                elsif @flag_biblio ==true \ +                and @flag_auto_biblio ==false \ +                and para =~/^(?:au|author):/m +                  @flag_auto_biblio =true +                end +                if para =~/^1~!glossary/ +                  @flag_glossary=true +                end +              end +              if not @book_idx \ +              and para =~/^=\{(.+?)\}[\s`]*\Z/m +                @book_idx=true +              end +              unless @code_flag +                case para +                when /~\{\s+.+?\}~/m                                             #% processing +                  en=para.scan(/~\{.+?\}~/m) +                  en.each { |e| @en[:sum] +=1 } +                when /~\^(?:\s|$)/m                                              #% processing +                  mk=para.scan(/~\^(?:\s|$)/) +                  mk.each { |e| @en[:mark] +=1 } +                when /^\^~\s+\S/ then @en[:note] +=1                             #% processing +                end +              end +              if para =~/~\{|\^~ |~\^|\{.+?\[[1-6]\]\}\S+?\.ss[tm]/m +                @flag_auto_endnotes,@flag_endnotes=true,true +              end +              if para =~/^(?:table\{|\{table)/i +                @flag_tables=true +              end +            end +            if para =~/^:?A~/ +              @set_heading_top=true +            end +            if para =~/^1~/ +              m=nil +              if para =~/^1~(\S+)\s+(.+)$/ +                m,t=$1,$2 +              elsif para =~/^1~\s+(.+)$/ +                t=$1 +              end +              unless @heading_seg_first_flag                                     # extract first segment name +                @heading_seg_first=t +                @heading_seg_first_flag=true +              end +              if m                                                               # list all segment names +                @seg_names << m +                @set_heading_seg=true +                if m=~/^\d{1,3}/ \ +                and m !~/^0/ +                  @seg_autoname_safe=false +                end +              end +            end +            para=para.gsub(/<:=(\S+?)>/,'{ c_\1.png 14x14 }image')               # embedded symbol (image) +            if para !~/^%+\s/ \ +            and para =~@rgx_image +              @ec[:image] << para.scan(@rgx_image).uniq +            end +            @ec[:audio] << para.scan(@rgx_audio).uniq if para =~@rgx_audio #embedded content +            @ec[:multimedia] << para.scan(@rgx_mm).uniq if para =~@rgx_mm #embedded content +            unless @sem_tag +              @sem_tag=true if para=~/[:;]\{.+?\}[:;][a-z+]/ #refix later +            end +          end                                                                    #% here endeth the document loop +          unless @make +            if (@opt.act[:verbose_plus][:set]==:on \ +            || @opt.act[:maintenance][:set]==:on) +              SiSU_Screen::Ansi.new( +                @opt.act[:color_state][:set], +                '@make:', +                'header absent' +              ).warn +            end +            @make=SiSU_Param::Parameters::MdMake.new('@make: ',@opt,@env).make +          end +          if @cover_image \ +          and @cover_image.is_a?(Hash) \ +          and (@cover_image[:cover] =~@rgx_image \ +            or @cover_image[:cover] =~/\S+?.(?:jpg|png|gif)/) +            @ec[:image] << @cover_image[:cover] +          end +          if @home_button_image \ +          and @home_button_image.is_a?(Hash) \ +          and (@home_button_image[:home] =~@rgx_image \ +            or @home_button_image[:home] =~/\S+?\.(?:jpg|png|gif)/) +            @ec[:image] << @home_button_image +          end +          if @ec[:image].length > 0 +            @ec[:image]=@ec[:image].flatten.uniq +            @ec[:image].delete_if {|x| x =~/https?:\/\// } +            @ec[:image]=@ec[:image].sort +          end +          @ec[:audio]=@ec[:audio].uniq.flatten.sort +          @ec[:multimedia]=@ec[:multimedia].uniq.flatten.sort +          unless @rights +            if defined? @creator.author \ +            and @creator.author.is_a?(String) \ +            and defined? @date.published \ +            and @date.published.is_a?(String) +              @rights=SiSU_Param::Parameters::MdDefault.new.rights(@creator.author,@date.published) +            elsif defined? @creator.author \ +            and @creator.author.is_a?(String) +              @rights=SiSU_Param::Parameters::MdDefault.new.rights("[#{@creator.author}]",'') +            end +          end +          if defined? @classify.topic_register \ +          and @classify.topic_register.is_a?(String) \ +          and @classify.topic_register.length >3 +             topic_register=@classify.topic_register +             u=topic_register.scan(/[^;]+/m).sort +             v=[] +             u.each do |l| +               v << l.scan(/[^:]+/m) +             end +             v.each do |s| +               s[-1]=s[-1].scan(/[^|]+/m) if s[-1] =~/[|]/m +               @topic_register_array << s +             end +             @topic_register_array +          end +          if @i18n +            @i18n=@i18n.uniq +            @i18n << 'en' unless @i18n.find_index("en") +          else +            @i18n=[ 'en' ] +          end +          translated=[] +          translate_list=[@pagenew,@pagebreak,@pageline,@num_top,@toc_lev_limit] +          translate_list.each do |t| +            translate=t.to_s if t +            translated << if translate +              translate.gsub!(/3/,'6') +              translate.gsub!(/2/,'5') +              translate.gsub!(/1/,'4') +              translate.gsub!(/:?C/,'3') +              translate.gsub!(/:?B/,'2') +              translate.gsub!(/:?A/,'1') +              # looks like an ok substituion for the above but is not, causes problems, check why +              #translate=translate.gsub(/3/,'6'). +              #  gsub(/2/,'5'). +              #  gsub(/1/,'4'). +              #  gsub(/:?C/,'3'). +              #  gsub(/:?B/,'2'). +              #  gsub(/:?A/,'1') +              translate=(translate =~/^\d+$/) \ +              ? translate.to_i +              : translate +            else nil +            end +          end +          @pagenew,@pagebreak,@pageline,@num_top,@toc_lev_limit=translated +          @markup=@markup.gsub(/page_new\s*=\s*([\dA-C])/,"page_new=#{@pagenew}"). +            gsub(/page_break\s*=\s*([\dA-C])/,"page_break=#{@pagebreak}"). +            gsub(/page_line\s*=\s*([\dA-C])/,"page_line=#{@pageline}"). +            gsub(/num_top\s*=\s*([\dA-C])/,"num_top=#{@num_top}"). +            gsub(/toc_lev_limit\s*=\s*([\dA-C])/,"toc_lev_limit=#{@toc_lev_limit}") +          papersize_array_rc=@papersize.downcase.scan(/(?:a4|letter|legal|book|a5|b5)/) +          papersize_array_opt=[ +            ((@opt.act[:pdf_a4][:set]==:on)     ? 'a4'     : ''), +            ((@opt.act[:pdf_a5][:set]==:on)     ? 'a5'     : ''), +            ((@opt.act[:pdf_b5][:set]==:on)     ? 'b5'     : ''), +            ((@opt.act[:pdf_letter][:set]==:on) ? 'letter' : ''), +            ((@opt.act[:pdf_legal][:set]==:on)  ? 'legal'  : ''), +          ] - [""] +          @papersize_array=(papersize_array_opt.length > 0) \ +          ? papersize_array_opt +          : papersize_array_rc +          fn=@opt.fno #decide what to do a filesize on .ssm tells very little about actual document size +          @filesize=(File.size(fn)).to_s +          if @sys.openssl !=false \ +          and FileTest.file?(@env.source_file_with_path) +            @dgst=[] +            case @env.digest(@opt).type +            when :sha512 +              dgst=@sys.sha512(@env.source_file_with_path) +              @dgst=dgst[1].length==128 ? dgst : nil +              puts 'check document (sha512) digest' if not @dgst +            when :sha256 +              dgst=@sys.sha256(@env.source_file_with_path) +              @dgst=dgst[1].length==64 ? dgst : nil +              puts 'check document (sha256) digest' if not @dgst +            when :md5 +              dgst=@sys.md5(@env.source_file_with_path) +              @dgst=dgst[1].length==32 ? dgst : nil +              puts 'check document (md5) digest' if not @dgst +            else +              dgst=@sys.sha256(@env.source_file_with_path) +              @dgst=dgst[1].length==64 ? dgst : nil +              puts 'check document (sha256) digest' if not @dgst +            end +          elsif not FileTest.file?(@env.source_file_with_path) +            #puts SiSU_Utils::CodeMarker.new(__LINE__,__FILE__).set(:fuchsia) +          end +          @publisher ||= "#{@@publisher} (this copy)" +          fn_set_lang=SiSU_Env::StandardiseLanguage.new(@opt.lng).language +          unless @language[:code] \ +          and @language[:name] +            lang=@env.i18n.language #default language settings for directory by name, or in sysrc.yml +            @language[:code] ||= lang.code +            @language[:name] ||= lang.title +          end +          unless fn_set_lang[:d]==true #decide, naming convention overrides other settings, within document, etc. +            @language[:code]=fn_set_lang[:c] +            @language[:name]=fn_set_lang[:n] +          end +          @fnl=@env.i18n.lang_filename(fn_set_lang[:c]) +          @lang=@lang.uniq +          @fn=SiSU_Env::EnvCall.new(@fns).lang(fn_set_lang[:c]) +          if @en[:note] > 0 \ +          and @en[:sum] > 0 +            if @en[:sum] > 0 +            else +              SiSU_Screen::Ansi.new( +                @opt.act[:color_state][:set], +                '*WARN* both endnote styles used', +                "~{ #{@en[:sum]} }~ and ^~ #{@en[:mark]}" +              ).warn unless @opt.act[:quiet][:set]==:on +            end +          end +          if @en[:mark] != @en[:note] \ +          and @en[:note] > 0 +            @en[:mismatch]=@en[:note] - @en[:mark] +            SiSU_Screen::Ansi.new( +              @opt.act[:color_state][:set], +              '*WARN* endnote number mismatch', +              "endnotes: #{@en[:note]} != endnote reference marks: #{@en[:mark]} " \ +              + "(difference = #{@en[:mismatch]})" +            ).warn unless @opt.act[:quiet][:set]==:on +            footnote_conversion_errors=File.new("#{Dir.pwd}/footnote_conversion_errors.txt",'a') +            footnote_conversion_errors << +              "#{@fns}:\n\tendnotes: #{@en[:note]} != endnote reference marks: #{@en[:mark]} " \ +              + "(difference = #{@en[:mismatch]})\n" +          end +          if not @title \ +          or not defined? @title.main \ +          or @title.main !~/[\S]/ +            if @fns =~/\.ssm$/ \ +            and  @opt.inspect =~/P/ +              #@title=Md.new('Text Insert',@opt,@env).title +            else +              SiSU_Screen::Ansi.new( +                @opt.act[:color_state][:set], +                'WARNING: Document Title missing', +                'please provide @title:' +              ).warn if (@opt.act[:verbose][:set]==:on \ +                || @opt.act[:verbose_plus][:set]==:on \ +                || @opt.act[:maintenance][:set]==:on) +            end +          end +          if @author !~/[\S]/ +            if @fns =~/\.ssm$/ \ +            and  @opt.inspect =~/P/ +              #@creator=SiSU_Param::Md.new('Text Insert',@opt,@env).creator +            else +              SiSU_Screen::Ansi.new( +                @opt.act[:color_state][:set], +                'WARNING: Document Author missing', +                'please provide @creator: :author:' +              ).warn if (@opt.act[:verbose][:set]==:on \ +                || @opt.act[:verbose_plus][:set]==:on \ +                || @opt.act[:maintenance][:set]==:on) +            end +          end +          @struct={} +          doc_struct=Hash.new(0) +          if @lv1.nil? +            fns_array.each do |para| +              if para =~/^(Part|Chapter|Section|Article)\b/i +                case para +                when /^(Part|PART)\b/ +                  @struct[:part]=doc_struct[:part] +                  doc_struct[:part]=doc_struct[:part] + 1 +                when /^(Chapter|CHAPTER)\b/ +                  @struct[:chapter]=doc_struct[:chapter] +                  doc_struct[:chapter]=doc_struct[:chapter] + 1 +                when /^(Section|SECTION)\b/ +                  @struct[:section]=doc_struct[:section] +                  doc_struct[:section]=doc_struct[:section] + 1 +                when /^(Article|ARTICLE)\b/ +                  @struct[:article]=doc_struct[:article] +                  doc_struct[:article]=doc_struct[:article] + 1 +                when /^(Clause|CLAUSE)\b/ +                  @struct[:clause]=doc_struct[:clause] +                  doc_struct[:clause]=doc_struct[:clause] + 1 +                when /^\d\..*[^\.]$/ +                  @struct[:number]=doc_struct[:number] +                  doc_struct[:number]=doc_struct[:number] + 1 +                end +              end +            end +            if doc_struct[:article] > 2                                            #%~level 4 +              @lv4=/^(?:Article|ARTICLE)\b/ +            elsif doc_struct[:chapter] > 2 \ +            and doc_struct[:article] \ +            and doc_struct[:article] < 3 +              @lv4=/^(?:Chapter|CHAPTER)\b/ +            elsif doc_struct[:clause] > 2 +              @lv4=/^(?:Clause|CLAUSE)\b/ +            elsif doc_struct[:number] > 2 +              @lv4="^\d\..*[^\.]$" +            end +            if doc_struct[:section] > 2                                           #%~level 3 +              @lv3=/^(?:Section|SECTION)\b/ +            end +            if doc_struct[:chapter] > 2 \ +            and doc_struct[:article] \ +            and doc_struct[:article] > 2 +              @lv2=/^(?:Chapter|CHAPTER)\b/ +            end +            if doc_struct[:part] > 2 \ +            and @lv[2].nil? +              @lv2=/^(?:Part|PART)\b/ +            end +            if doc_struct[:part] > 2 \ +            and @lv[2].inspect !~/Part/ \ +            and @lv[1].nil? +              @lv1=/^(Part|PART)\b/ +            end +          end +          @lnk=@lnk.compact if @lnk +          @lv0 ||=/^0~/ +          @lv1 ||=/^1~/ +          @lv2 ||=/^2~/ +          @lv3 ||=/^3~/ +          @lv4 ||=/^4~/ +          @lv5 ||=/^5~/ +          @lv6 ||=/^6~/ +          @data=nil #else whole file's contents are stored in md pstore & is not required to be... big waste actually +          @file=SiSU_Env::FileOp.new(self) #watch +          Store.new(self,@env).store                                             #% pstore +          self +        rescue +          if @opt.act[:harvest][:set]==:on +            exit +          end +        end +      end +      private +      class Store +        def initialize(md,env) +          @md,@env=md,env +        end +        def store +          begin +            pstorefile="#{@env.processing_path.ao}/#{@md.fns}.pstore" +            File.unlink(pstorefile) if FileTest.file?(pstorefile) +            if (@md.opt.act[:verbose_plus][:set]==:on \ +            || @md.opt.act[:maintenance][:set]==:on) +              SiSU_Screen::Ansi.new( +                @md.opt.act[:color_state][:set], +                "PStore -> #{pstorefile}" +              ).txt_grey +            end +            store=PStore.new(pstorefile) +            store.transaction do +              store['md']=@md +              store.commit +            end +            @@md=@md=nil +          rescue +            SiSU_Errors::Rescued.new($!,$@,@md.opt.selections.str,@md.fns).location do +              __LINE__.to_s + ':' + __FILE__ +            end +          ensure +          end +        end +      end +    end +  end +  class Instantiate +    def param_instantiate +      @@date=SiSU_Env::InfoDate.new +      @doc={ +       initialise: nil, +       markup: '', +       lnks: '', +       stmp: '', +       prefix_a: '', +       prefix_b: '', +       req: {} +      } +      @@flag={} +      @@publisher='SiSU scribe' +    end +  end +end +__END__ +#+END_SRC + +* dp_make.rb + +#+BEGIN_SRC ruby  :tangle "../lib/sisu/dp_make.rb" +# <<sisu_document_header>> +module SiSU_Param_Make +  class MdMake +    def initialize(str,opt,env) +      @s,@opt,@env=str,opt,env +    end +    def validate_length(s,l,n) +      #s=(s.length <= l) ? s : nil +      s=if s.is_a?(String) \ +      and s.length <= l +        s +      elsif s.is_a?(NilClass) +        nil +      elsif s.class !=String +        STDERR.puts "#{n} is #{s.class}: programming error, String expected #{__FILE__}:#{__LINE__}" +        s +      else +        SiSU_Screen::Ansi.new( +          'v', +          "*WARN* #{n} length #{s.length} exceeds set db field length #{l}, metadata dropped", +          @opt.fns +        ).warn unless @opt.act[:quiet][:set]==:on +        nil +      end +    end +    def name_format(name) +      if name +        name=name.strip +        @name_a_h=[] +        authors=name.scan(/[^;]+/) +        authors.each_with_index do |a,i| +          b=((a =~/\s*\|\s*/) ? (a.split(/\|/)) : [a]) +          if b[0] =~/"(.+?)"/ +            @name_a_h << { the: $1 } +          else +            x=b[0].scan(/[^,]+/) +            if x.length==1 +              @name_a_h << { the: x[0].strip } +            elsif x.length==2 +              @name_a_h << { the: x[0].strip, others: x[1].strip } +            else #p x.length +            end +          end +          b.delete_at(0) +          b.each do |d| +            k,c=nil +            k,c=/^(\S+)\s+(.*)/.match(d)[1,2] if d +            @name_a_h[i][:hon]=c.strip if k=='hon' +            @name_a_h[i][:affiliation]=c.strip if k=='affiliation' +            @name_a_h[i][:nationality]=c.strip if k=='nationality' +          end +        end +        l=@name_a_h.length +        name_str='' +        @name_a_h.each_with_index do |a,i| +          name_str += if a[:others] +            z=(((l - i) > 1) ? ', ' : '') +            "#{a[:others].strip} #{a[:the].strip}" + z +          else +            z=(((l - i) > 2) ? ', ' : '') +            "#{a[:the].strip}" + z +          end +        end +        { name_a_h: @name_a_h, name_str: name_str } +      else nil +      end +    end +    def build_hash(arr) +      @h={} +      arr.each_with_index do |x,i| +        a,b=nil,nil +        if x =~/^%[:\s]/ #ignore comment +        elsif x =~/:(\S+?):\s+(.+)/ +          a,b=/:(\S+?):\s+(.+)\Z/m.match(x)[1,2] +        elsif i == 0 +          a='main' +          b=x +        else +        end +        @h[a]=b +      end +      @h +    end +    def make +      a=@s.split(/\n%\s.+?$|[ ]*\n[ ]*/m) +      @h=build_hash(a) +      def headings +        lv=[] +        x=@h['headings'] +        x=((x =~/;/) ? (x.split(/;\s*/)) : [ x ]) +        lv[0]=x +        lv0 ||='A~ '             #root level, single document apex, document title +        lv1=x[0] ||='B~ ' +        lv[1]=/^#{lv1}/ +        lv2=x[1] ||='C~ ' +        lv[2]=/^#{lv2}/ +        lv3=x[2] ||='D~ ' +        lv[3]=/^#{lv3}/ +        lv4=x[3] ||='1~ ' +        lv[4]=/^#{lv4}/ +        lv5=x[4] ||='2~ ' +        lv[5]=/^#{lv5}/ +        lv6=x[5] ||='3~ ' +        lv[6]=/^#{lv6}/ +        lv +      end +      def num_top +        @h['num_top'] +      end +      def breaks +        pagebreaks=((@h['breaks'] =~/;/) \ +        ? (@h['breaks'].split(/;\s*/)) +        : [ @h['breaks'] ]) +        page_new,page_break,page_line=nil,nil,nil +        pagebreaks.each do |x| +          page_new=x[/(:?[\dA-C],?)+/] if x=~/new|clear/ +          page_break=x[/(:?[\dA-C],?)+/] if x =~/break/ +          page_line=x[/(:?[\dA-C],?)+/] if x =~/line/ +        end +        { page_new: page_new, page_break: page_break, page_line: page_line } +      end +      def language +        if @h['language'] && (@h['language']=~/\S{2,}/) +          ((@h['language'] =~/,/) \ +          ? (@h['language'].split(/,\s*/)) +          : [ @h['language'] ]) +        else [ 'en' ] +        end +      end +      def bold +        m=@h['bold'] +        i=(m=~/\/i$/)? 'i' : '' +        if m +          x=m.gsub(/^\/(.+?)\/i?/,'\1'). +            gsub(/\((?:\?:)?/,'(?:')                                         # avoid need to escape use of brackets within regex provided +          rgx='\b(' + x + ')\b' +          y=((i =~/i/) ? (/#{rgx}/i) : (/#{rgx}/)) +          { str: '\b(?:' + x + ')\b', regx: y, i: i } +        else nil +        end +      end +      def italics +        m=@h['italics'] +        i=((m=~/\/i$/) ? 'i' : '') +        if m +          x=m.gsub(/^\/(.+?)\/i?/,'\1'). +            gsub(/\((?:\?:)?/,'(?:')                                         # avoid need to escape use of brackets within regex provided +          rgx='\b(' + x + ')\b' +          y=((i =~/i/) ? (/#{rgx}/i) : (/#{rgx}/)) +          { str: '\b(?:' + x + ')\b', regx: y, i: i } +        else nil +        end +      end +      def emphasis +        if @h['emphasis'] =~/bold/                   then 'bold' +        elsif @h['emphasis'] =~/italics?/            then 'italics' +        elsif @h['emphasis'] =~/under(?:line|score)/ then 'underscore' +        else nil +        end +      end +      def substitute +        m=@h['substitute'] +        if m +          w=m.scan(/\/(.+?)\/(i?,)\s*'(.+?)'(?:\s+|\s*;\s*|$)/) +          arr_hash=[] +          matches='' +          w.each do |x| +            c=(x[1] =~/[i],/) ? :i : :s +            matches=matches + x[0].gsub(/([${}])/,'\\\\\1') + '|' +            arr_hash << { +              match: x[0].gsub(/([${}])/,'\\\\\1'), +              replace: x[2], +              case_s: c +            } +          end +          matches.chop! +          { match_and_replace: arr_hash, matches: matches } +        else nil +        end +      end +      def plaintext_wrap +        if @h['plaintext_wrap'].to_s =~/\d\d+/ \ +        and @h['plaintext_wrap'].to_i > 19 \ +        and @h['plaintext_wrap'].to_i < 201 +          @h['plaintext_wrap'].to_i +        else nil +        end +      end +      def omit +        m=@h['omit'] +        @m=m ? (m.split(/,\s+/)) : nil +        def list +          @m +        end +        self +      end +      def ocn? +        (omit.list.inspect =~/"ocn"/) \ +        ? :off +        : :na +      end +      def toc? +        (omit.list.inspect =~/"toc"/) \ +        ? :off +        : :na +      end +      def manifest? +        (omit.list.inspect =~/"manifest"/) \ +        ? :off +        : :na +      end +      def links_to_manifest? +        (omit.list.inspect =~/"manifest_links"|"links_to_manifest"/) \ +        ? :off +        : :na +      end +      def metadata? +        (omit.list.inspect =~/"metadata"/) \ +        ? :off +        : :na +      end +      def minitoc? +        (omit.list.inspect =~/"minitoc"/) \ +        ? :off +        : :na +      end +      def html_minitoc? +        (omit.list.inspect =~/"html_minitoc"/) \ +        ? :off +        : :na +      end +      def html_top_band? +        (omit.list.inspect =~/"html_top_band"/) \ +        ? :off +        : :na +      end +      def html_navigation? +        (omit.list.inspect =~/"html_navigation"/) \ +        ? :off +        : :na +      end +      def html_navigation_bar? +        (omit.list.inspect =~/"html_navigation_bar"/) \ +        ? :off +        : :na +      end +      def segsubtoc? +        (omit.list.inspect =~/"segsubtoc"/) \ +        ? :off +        : :na +      end +      def search_form? +        (omit.list.inspect =~/"search_form"/) \ +        ? :off +        : :na +      end +      def html_search_form? +        (omit.list.inspect =~/"html_search_form"/) \ +        ? :off +        : :na +      end +      def html_right_pane? +        (omit.list.inspect =~/"html_right_column"|"html_right_pane"/) \ +        ? :off +        : :na +      end +      def manifest_minitoc? +        (omit.list.inspect =~/"manifest_minitoc"/) \ +        ? :off +        : :na +      end +      def cover_image? +        (omit.list.inspect =~/"cover_image"/) \ +        ? :off +        : :na +      end +      def home_button_image? +        (omit.list.inspect =~/"home_button_image"/) \ +        ? :off +        : :na +      end +      def texpdf_font +        def main +          @h['texpdf_font'] \ +          && (@h['texpdf_font']=~/\S{3,}/) \ +          ? @h['texpdf_font'] +          : @env.font.texpdf.main +        end +        def sans                                                             # not used +          @h['texpdf_font_sans'] \ +          && (@h['texpdf_font_sans']=~/\S{3,}/) \ +          ? @h['texpdf_font_sans'] +          : @env.font.texpdf.sans +        end +        def serif                                                            # not used +          @h['texpdf_font_serif'] \ +          && (@h['texpdf_font_serif']=~/\S{3,}/) \ +          ? @h['texpdf_font_serif'] +          : @env.font.texpdf.serif +        end +        def mono +          @h['texpdf_font_mono'] \ +          && (@h['texpdf_font_mono']=~/\S{3,}/) \ +          ? @h['texpdf_font_mono'] +          : @env.font.texpdf.mono +        end +        def cjk +          @h['texpdf_font_cjk'] \ +          && (@h['texpdf_font_cjk']=~/\S{3,}/) \ +          ? @h['texpdf_font_cjk'] +          : @env.font.texpdf.cjk +        end +        def cjk_zh +          @h['texpdf_font_cjk_zh'] \ +          && (@h['texpdf_font_cjk_zh']=~/\S{3,}/) \ +          ? @h['texpdf_font_cjk_zh'] +          : @env.font.texpdf.cjk_zh +        end +        def cjk_ja +          @h['texpdf_font_cjk_ja'] \ +          && (@h['texpdf_font_cjk_ja']=~/\S{3,}/) \ +          ? @h['texpdf_font_cjk_ja'] +          : @env.font.texpdf.cjk_ja +        end +        def cjk_ko +          @h['texpdf_font_cjk_ko'] \ +          && (@h['texpdf_font_cjk_ko']=~/\S{3,}/) \ +          ? @h['texpdf_font_cjk_ko'] +          : @env.font.texpdf.cjk_ko +        end +        self +      end +      def promo +        @h['promo'] +      end +      def ad +        @h['ad'] +      end +      def manpage +        manpage={} +        if @h['manpage'] +          if @h['manpage'] =~/;/m +            man=@h['manpage'].split(/;/m) +            man.each do |x| +              m=(x=~/=/m) ? x.split(/=/m) : nil +              if m +                manpage[m[0].strip] = m[1].split(/ \. /) +              end +            end +          end +        end +        if manpage['name'] +          manpage['name']=manpage['name'].join("\n.br\n"). +            gsub(/(-)/m,"\\\\\\1"). +            gsub(/\A/,"\n.br\n.SH NAME\n.br\n") +        else +          manpage['name']='man page "name/whatis" information not provided, set in header @man: name=[whatis information]' +        end +        if manpage['synopsis'] +          manpage['synopsis']=manpage['synopsis'].join("\n\n.br\n"). +            gsub(/(-)/m,"\\\\\\1"). +            gsub(/\A/,"\n.br\n.SH SYNOPSIS\n.br\n") +        else +          manpage['synopsis']='' +        end +        unless manpage['section'] +          manpage['section']=1 +        end +        manpage +      end +      def get_image_dimensions(img) +        imgk=SiSU_Env::SystemCall.new.imagemagick +        gmgk=SiSU_Env::SystemCall.new.graphicsmagick +        img_pth={ +          sst: @env.path.image_source_include, +          pod: File.expand_path("../../../sisupod/image" ) +        } +        path_img=if FileTest.file?("#{img_pth[:pod]}/#{img}") +          "#{img_pth[:pod]}/#{img}" +        elsif FileTest.file?("#{img_pth[:sst]}/#{img}") +          "#{img_pth[:sst]}/#{img}" +        else nil +        end +        if path_img +          if imgk or gmgk +            if imgk +              imgsys=`identify #{path_img}`.strip                           #system call +            elsif gmgk +              imgsys=`gm identify #{path_img}`.strip                        #system call +            end +            w,h=/(\d+)x(\d+)/m.match(imgsys)[1,2] +          else +            w,h='600','800' +          end +        else +          w,h=nil,nil +        end +        {w: w, h: h} +      end +      def home_button_text +        if @h['home_button_text'] +          @h['home_button_text'].split(/\s*;\s*/) +        else nil +        end +      end +      def home_button_image +        s=nil +        s=if @h['home_button_image'] +          s=@h['home_button_image'].split(/\s*;\s*/) +          s0=s[0] #if +          image={} +          s=if s0 =~/{(\S+\.(?:jpg|png|gif))(?:\s+(\d+x\d+))?\s*}(?:(http:\/\/\S+)|image)/ +            image[:home_button]=$1 +            if $2 +              image[:dimensions]=$2 +              image[:w],image[:h]=/(\d+)x(\d+)/m.match(image[:dimensions])[1,2] +            else +              d=get_image_dimensions(image[:home_button]) +              image[:w],image[:h]=d[:w],d[:h] +              image[:dimensions]="#{d[:w]}x#{d[:h]}" +            end +            image[:link]=$3 +            image +          end +        else nil +        end +      end +      def cover_image +        s=nil +        if @h['cover_image'] +          s=@h['cover_image'].split(/\s*;\s*/) +          s=s[0] #if +          image={} +          if s =~/{\s*(\S+\.(?:jpg|png|gif))(?:\s+(\d+x\d+))?(?:\s+"(.+?)")?\s*}image/ +            image[:cover]=$1 +            if $2 +              image[:dimensions]=$2 +              image[:w],image[:h]=/(\d+)x(\d+)/m.match(image[:dimensions])[1,2] +            else +              d=get_image_dimensions(image[:cover]) +              image[:w],image[:h]=d[:w],d[:h] +              image[:dimensions]="#{d[:w]}x#{d[:h]}" +            end +            image[:note]=$3 +          elsif s =~/(\S+\.(?:jpg|png|gif))/ +            image[:cover]=$1 +            d=get_image_dimensions(image[:cover]) +            image[:w],image[:h]=d[:w],d[:h] +            image[:dimensions]="#{d[:w]}x#{d[:h]}" +            image[:note]=nil +          end +          image +        else nil +        end +      end +      def footer +        if @h['footer'] +          @h['footer'].split(/\s*;\s*/) +        else nil +        end +      end +      self +    end +    def make_links +      @doc_links=@s.split(/\n%\s.+?$|[ ]*\n[ ]*/m) +      def links +        lnks,a_idx=[],0 +        @doc_links.each do |doc_link| +          if doc_link=~/\{.+?\}(?:(?:https?|file|ftp):\/|\.\.)\/\S+(?:\s|$)/ +            say,url=/\{\s*(.+?)\s*\}((?:(?:https?|file|ftp):\/|\.\.)\/\S+)/im.match(doc_link)[1,2] +            lnks[a_idx]={ say: say, url: url  } +            a_idx +=1 +          end +        end +        lnks +      end +      def append? +        (@doc_links[0]=='+') \ +          ? :yes +          : :no +      end +      self +    end +  end +  class MakeHead +    attr_accessor :pagenew,:pagebreak,:pageline,:toc,:lv1,:lv2,:lv3,:lv4,:lv5,:lv6,:num_top,:i18n,:man_section,:substitution_match_list,:bold_match_list,:italics_match_list,:emphasis_set_to,:footer_links,:home_button_links,:home_button_image,:cover_image +    def initialize(make) +      @make=make +    end +    def clear +      @pagenew=@pagebreak=@pageline=@toc=@lv1=@lv2=@lv3=@lv4=@lv5=@lv6=@num_top=@i18n=@man_section=@footer_links=@substitution_match_list=@bold_match_list=@italics_match_list=@emphasis_set_to=@home_button_links=@home_button_image=@cover_image=nil +    end +    def make_instruct +      clear +      if defined? @make.breaks \ +      and @make.breaks[:page_new]                  #clearpage +        @pagenew=@make.breaks[:page_new] +      end +      if defined? @make.breaks \ +      and @make.breaks[:page_break]                #newpage +        @pagebreak=@make.breaks[:page_break] +      end +      if defined? @make.breaks \ +      and @make.breaks[:page_line]                 #page line across +        @pagebreak=@make.breaks[:page_line] +      end +      if defined? @make.headings \ +      and @make.headings +        @toc=@make.headings[0] +        @lv1=@make.headings[1] +        @lv2=@make.headings[2] +        @lv3=@make.headings[3] +        @lv4=@make.headings[4] +        @lv5=@make.headings[5] +        @lv6=@make.headings[6] +      end +      if defined? @make.num_top \ +      and @make.num_top +        @num_top=@make.num_top # remove @num_top +      end +      if defined? @make.language \ +      and @make.language[0] +        @i18n=@make.language +      end +      if defined? @make.manpage \ +      and @make.manpage +        @man_section=(defined? @make.manpage.section) \ +        ? @make.manpage.section +        : 1 +      end +      if defined? @make.substitute \ +      and @make.substitute +        @substitution_match_list=@make.substitute +      end +      if defined? @make.bold \ +      and @make.bold +        @bold_match_list=@make.bold +      end +      if defined? @make.italics \ +      and @make.italics +        @italics_match_list=@make.italics +      end +      if defined? @make.emphasis \ +      and @make.emphasis +        @emphasis_set_to=@make.emphasis +      end +      if defined? @make.footer \ +      and @make.footer.is_a?(Array) +        @footer_links= { left: { say: '', url: '' }, center: { say: '', url: '' } } #already set +        @footer_links[:left]=if @make.footer[0]=~/\{.+?\}(?:(?:https?|file|ftp):\/|\.\.)\/\S+(?:\s|$)/ +          say,url=/\{\s*(.+?)\s*\}((?:(?:https?|file|ftp):\/|\.\.)\/\S+)/im.match(@make.footer[0])[1,2] +          { say: say, url: url } +        else +          { say: '', url: '' } +        end +        @footer_links[:center]=if @make.footer[1]=~/\{.+?\}(?:(?:https?|file|ftp):\/|\.\.)\/\S+(?:\s|$)/ +          say,url=/\{\s*(.+?)\s*\}((?:(?:https?|file|ftp):\/|\.\.)\/\S+)/im.match(@make.footer[1])[1,2] +          { say: say, url: url } +        else +          { say: '', url: '' } +        end +        @footer_links +      else #already set +        @footer_links= { left: { say: '', url: '' }, center: { say: '', url: '' } } +      end +      if defined? @make.home_button_text \ +      and @make.home_button_text.is_a?(Array) +        a_idx=0 +        @home_button_links=[] +        @make.home_button_text.each do |doc_link| +          if doc_link=~/\{.+?\}(?:(?:https?|file|ftp):\/|\.\.)\/\S+(?:\s|$)/ +            say,url=/\{\s*(.+?)\s*\}((?:(?:https?|file|ftp):\/|\.\.)\/\S+)/im.match(doc_link)[1,2] +            @home_button_links[a_idx]= { say: say, url: url } +            a_idx +=1 +          end +        end +        @home_button_links +      end +      if defined? @make.home_button_image \ +      and @make.home_button_image.is_a?(Hash) +        @home_button_image=@make.home_button_image +      end +      if defined? @make.cover_image \ +      and @make.cover_image.is_a?(Hash) +        @cover_image=@make.cover_image +      end +      { pagenew: @pagenew, +        pagebreak: @pagebreak, +        pageline: @pageline, +        toc: @toc, +        lv1: @lv1, +        lv2: @lv2, +        lv3: @lv3, +        lv4: @lv4, +        lv5: @lv5, +        lv6: @lv6, +        num_top: @num_top, +        i18n: @i18n, +        emphasis_set_to: @emphasis_set_to, +        bold_match_list: @bold_match_list, +        italics_match_list: @italics_match_list, +        substitution_match_list: @substitution_match_list, +        man_section: @man_section, +        footer_links: @footer_links, +        home_button_links: @home_button_links, +        home_button_image: @home_button_image, +        cover_image: @cover_image, +      } +    end +  end +end +__END__ +#+END_SRC + +* dp_identify_markup.rb + +#+BEGIN_SRC ruby  :tangle "../lib/sisu/dp_identify_markup.rb" +# <<sisu_document_header>> +module SiSU_MarkupType +  class MarkupIdentify +    @@version={} +    @@fns,@@version[:determined],@@version[:declared],@@declared_doc_type='','','','[text?]' +    attr_accessor :version,:declared_doc_type +    def initialize(content,opt) +      @cont,@opt=content,opt +    end +    def identify +      @version,@declared_doc_type=@@version,@@declared_doc_type +      if @opt.fns != @@fns +        if @cont[0] =~ /^(?:%\s+)?SiSU\s+(text|master|insert)\s+([0-9](?:\.[0-9]+){1,2})/ \ +        or @cont[0] =~ /^(?:%\s+)?sisu-([0-9](?:\.[0-9]+){1,2})/ +          @declared_doc_type,@version[:declared]=$1,$2 +        elsif @cont[0] =~ /^(?:%\s+)?SiSU\s+([0-9](?:\.[0-9]+){1,2})/ \ +        or @cont[0] =~ /^(?:%\s+)?sisu-([0-9](?:\.[0-9]+){1,2})/ +          @version[:declared]=$1 +        end +        @flag_2_0,@flag_66,@flag_57,@flag_38=false,false,false,false +        @cont.each_with_index do |y,i| +          if y =~/^@make:|^@classify|^\s\s?:\S+?:\s+\S/ +            version=2.0.to_f +            @version[:determined]=version +            @flag_2_0=true +            break +          end +          unless @flag_38 +            if y =~/^:?A~/ +              version=0.38.to_f +              @version[:determined]=version +              @flag_38=true +            end +          end +          if @flag_38 +            if @flag_69 \ +            or y =~/^=\{.+?\}\s*$/ +              version=0.69.to_f +              @flag_69=true +              @version[:determined]=version +              break +            end +            if @flag_66 \ +            or y =~/[:;]\{.+?\}[:;][a-z+]/ +              version=0.66.to_f +              @flag_66=true +              @version[:determined]=version +              break +            end +          end +        end +        @flag_57,@flag_38=false,false +        unless @flag_2_0 \ +        or @flag_66 \ +        or @flag_69 +          @cont.each_with_index do |y,i| +            if @flag_57 \ +            or y =~/^:?A~\?? @title/ +              @version[:determined]=0.57.to_f +              @flag_57=true +              break +            end +            if @flag_38 \ +            or y =~/^:?A~/ +              @version[:determined]=0.38.to_f +              @flag_38=true +              break if i >= 200 +              if y =~ /(?:~{\*+|~\[\*|~\[\+)\s/ +                @version[:determined]=0.42 #0.38 can safely be treated as 0.42 +                break +              end +            end +            if y =~/^0~/ \ +            and not @flag_38 +              @version[:determined]=0.16.to_f +              break +            end +          end +        end +        @@fns=@opt.fns +        @@version,@@declared_doc_type=@version,@declared_doc_type +      end +      self +    end +    def markup_version? +      def determined +        identify.version[:determined].to_f +      end +      def series +        s=case identify.version[:determined].to_s +        when /^[01]\./ then '1.0' +        when /^[2]\./  then '2.0' +        else '2.0' +        end +        "series #{s}" +      end +      def declared +        identify.version[:declared].to_f +      end +      self +    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 +    param + +  - 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 diff --git a/org/shared.org b/org/shared.org new file mode 100644 index 00000000..66df485d --- /dev/null +++ b/org/shared.org @@ -0,0 +1,2297 @@ +-*- mode: org -*- +#+TITLE:       sisu shared +#+DESCRIPTION: documents - structuring, various output representations & search +#+FILETAGS:    :sisu:shared: +#+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 + +* shared +** shared_sem.rb + +#+BEGIN_SRC ruby  :tangle "../lib/sisu/shared_sem.rb" +# <<sisu_document_header>> +module SiSU_Sem +  require_relative 'dp'                                 # dp.rb +  class Tags +    def initialize(para,md) +      @para,@md=para,md +    end +    def rgx +      def exclude +        /^(?:<:code>|%+ )/ +      end +      def each_csc +        /(?:;|(?:[a-z]+(?:[_:.][a-z]+)+|[a-z]*):)\{|\}[:;][a-z]+(?:[_:.][a-z]+)*/m +      end +      def each_c +        /(?:[a-z]+(?:[_:.][a-z]+)+|[a-z]*):\{|\}:[a-z]+(?:[_:.][a-z]+)*/m +      end +      def each_sc +        /(?:[a-z]+(?:[_:.][a-z]+)+|[a-z]*);\{|\};[a-z]+(?:[_:.][a-z]+)*/m +      end +      def pair_csc +        /(([a-z]+(?:[_:.][a-z]+)+|[a-z]+)(?::\{(.+?)\}:\2)|([:;])\{(.+?)\}\4[a-z]+(?:[_:.][a-z]+)*)/m +      end +      def pair_c +        /(([a-z]+(?:[_:.][a-z]+)*)(?::\{(.+?)\}:\2)|:\{(.+?)\}:[a-z]+(?:[_:.][a-z]+)*)/m +      end +      def pair_sc +        /(;\{.+?\};[a-z]+(?:[_:.][a-z]+)*)/m +      end +      def whole_csc_ae +        /(([a-z]+(?:[_.][a-z]+)+|[a-z]*)(?::\[(.+?)\]:\2)|;\{(.+?)\};(?:[a-z]+(?:[_:.][a-z]+)+|[a-z]+)\b)/m +      end +      def each_csc_ae +        /(?:;|(?:[a-z]+(?:[_:.][a-z]+)+)*:|[a-z]*:)\[|\][:;](?:[a-z]+(?:[_:.][a-z]+)+|[a-z]+)/m +      end +      self +    end +    def print +      def scan_pair_c +        if @para =~ rgx.pair_c +          matched=@para.scan(rgx.pair_c).flatten +          puts matched[0] unless matched[0].nil? +        end +      end +      def scan_pair_sc +        matched=@para.scan(rgx.pair_sc).flatten +        puts matched[0] unless matched[0].nil? +      end +      def if_pair_c +        if @para=~/([a-z](?:[a-z_:.]+?[a-z])?)+(?::\{(.+?)\}:\1)/m +          puts "#{$1}:{ #{$2} }:#{$1}" +        end +      end +      def if_pair_sc +        if @para=~/;\{\s*(.+?)\s*\};([a-z]+(?:[_:.][a-z]+)*)/ +          puts ";{ #{$1} };#{$2}" +        end +      end +      def match_pair_c +        matched=[] +        matched=rgx.pair_c.match(@para)[1] if @para =~ rgx.pair_c +        puts matched unless matched.nil? +      end +      def match_pair_sc +        matched=[] +        matched=rgx.pair_sc.match(@para)[1] if @para =~ rgx.pair_sc +        puts matched unless matched.nil? +      end +      def matching +        scan_pair_c +      end +      self +    end +    def rm +      def sem_marker_parts +        unless @para =~ rgx.exclude +          @para.gsub!(rgx.each_csc,'') +        end +        @para +      end +      def sem_marker_added_extra_parts +        unless @para =~ rgx.exclude +          @para.gsub!(rgx.whole_csc_ae,'') +          if @para =~rgx.each_csc_ae +            STDERR.puts "WARNING semantic tagging error: #{@para}" +          end +        end +        @para +      end +      def all +        if @md.sem_tag +          sem_marker_parts +          sem_marker_added_extra_parts +        end +        @para +      end +      self +    end +  end +end +__END__ +#+END_SRC + +** shared_images.rb + +#+BEGIN_SRC ruby  :tangle "../lib/sisu/shared_images.rb" +# <<sisu_document_header>> +module SiSU_Images +  require_relative 'se_hub_particulars'                 # se_hub_particulars.rb +  class Source +    def initialize(opt) +      @particulars=SiSU_Particulars::CombinedSingleton.instance.get_all(opt) +    end +    def read +      SiSU_Images::Source::Place.new(@particulars).songsheet +    end +    class Place +      def initialize(particulars) +        @particulars=particulars +        @md=@particulars.md +        @env=@particulars.env +        @o_str ||=SiSU_Env::ProcessingSettings.new(@md).output_dir_structure +      end +      def songsheet +        images_set.select_sisu_base +        images_set.select_with_document +      end +      def images_set +        @pwd=(/(\S+?)(?:\/(?:#{Px[:lng_lst_rgx]}))?$/).match(Dir.pwd)[1] +        def copy(src_path,dest_path,images=nil) +          if FileTest.directory?(src_path) +            FileUtils::cd(src_path) +            unless images +              images=Dir.glob("*.{png,jpg,gif,ico}") +            end +            unless FileTest.directory?(dest_path) \ +            or FileTest.symlink?(dest_path) +              FileUtils::mkdir_p(dest_path) +              FileUtils::chmod(0755,dest_path) +            end +            if images.length > 0 +              images.each do |i| +                if FileTest.file?(i) +                  FileUtils::cp_r(i,"#{dest_path}/#{i}") +                  FileUtils::chmod(0644,"#{dest_path}/#{i}") +                else STDERR.puts %{\t*WARN* did not find image - "#{i}" [#{__FILE__}:#{__LINE__}]} +                end +              end +            end +            FileUtils::cd(@pwd) +          else STDERR.puts %{\t*WARN* did not find - "#{src_path}" [#{__FILE__}:#{__LINE__}]} +          end +        end +        def dest_path(image_type) +          pth=if image_type==:image_sys +            pth=(@o_str.dump_or_redirect?) \ +            ? "#{@md.file.output_path.html.dir}/image" +            : "#{@md.file.output_path.base.dir}/_sisu/image_sys" +          elsif image_type==:image +            pth=(@o_str.dump_or_redirect?) \ +            ? "#{@md.file.output_path.html.dir}/image" +            : "#{@md.file.output_path.base.dir}/_sisu/image" +          end +          pth +        end +        def select_with_document +          images=@md.ec[:image] +          src_path=unless @md.opt.f_pth[:pth] =~/\/\S+?\/sisupod\/\S+?\/sisupod\/doc/ +            "#{@pwd}/_sisu/image" +          else #sisupod +            pt=/(\/\S+?\/sisupod\/\S+?\/sisupod)\/doc/.match(@md.opt.f_pth[:pth])[1] +            pt + '/image' +          end +          dest=dest_path(:image) +          copy(src_path,dest,images) +        end +        def select_sisu_base +          images=%w[arrow_next_red.png arrow_prev_red.png arrow_up_red.png dot_clear.png dot_white.png b_doc.png b_epub.png b_odf.png b_pdf.png b_toc.png] +          src_path="#{SiSU_is.path_base_system_data?}/image" +          dest=dest_path(:image_sys) +          copy(src_path,dest,images) +        end +        self +      end +    end +  end +end +__END__ +#+END_SRC + +** shared_markup_alt.rb + +#+BEGIN_SRC ruby  :tangle "../lib/sisu/shared_markup_alt.rb" +# <<sisu_document_header>> +module SiSU_TextRepresentation +  class Alter +    def initialize(x) +      if x.is_a?(String) +        @t_o,@s=nil,x +      else +        @t_o,@s=x,x.obj.dup +      end +    end +    def strip_clean_of_extra_spaces                                              # dal 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 +    def strip_clean_of_markup                                                  # text form used in sql db search, used for digest, define rules, make same as in db clean +      @s=@s.dup                                                                  #% same as db clean --> +      @s=@s.gsub(/#{Mx[:fa_bold_o]}(.+?)#{Mx[:fa_bold_c]}/,'\1'). +        gsub(/#{Mx[:fa_italics_o]}(.+?)#{Mx[:fa_italics_c]}/,'\1'). +        gsub(/#{Mx[:fa_underscore_o]}(.+?)#{Mx[:fa_underscore_c]}/,'\1'). +        gsub(/#{Mx[:fa_cite_o]}(.+?)#{Mx[:fa_cite_c]}/,'\1'). +        gsub(/#{Mx[:fa_insert_o]}(.+?)#{Mx[:fa_insert_c]}/,'\1'). +        gsub(/#{Mx[:fa_strike_o]}(.+?)#{Mx[:fa_strike_c]}/,'\1'). +        gsub(/#{Mx[:fa_superscript_o]}(\d+)#{Mx[:fa_superscript_c]}/,'[\1]'). +        gsub(/#{Mx[:fa_subscript_o]}(.+?)#{Mx[:fa_subscript_c]}/,'\1'). +        gsub(/#{Mx[:fa_hilite_o]}(.+?)#{Mx[:fa_hilite_c]}/,'\1'). +        gsub(/#{Mx[:gl_o]}#(?:126|152)#{Mx[:gl_c]}/i,'~'). +        gsub(/#{Mx[:en_a_o]}([\d*+]+)\s+(?:.+?)#{Mx[:en_a_c]}/,''). # endnote removed +        gsub(/#{Mx[:en_b_o]}([\d*+]+)\s+(?:.+?)#{Mx[:en_b_c]}/,''). # endnote removed +        gsub(/(?:#{Mx[:nbsp]})+/,' '). +        gsub(/(?:#{Mx[:br_nl]})+/,"\n"). +        gsub(/(?:#{Mx[:br_paragraph]})+/,"\n"). +        gsub(/(?:#{Mx[:br_line]})+/,"\n"). +        gsub(/#{Mx[:gl_o]}(?:#lt|#060)#{Mx[:gl_c]}/,'<'). +        gsub(/#{Mx[:gl_o]}(?:#gt|#062)#{Mx[:gl_c]}/,'>'). +        gsub(/#{Mx[:gl_o]}#(?:038|amp)#{Mx[:gl_c]}/,'&'). +        gsub(/#{Mx[:gl_o]}#033#{Mx[:gl_c]}/,'!'). +        gsub(/#{Mx[:gl_o]}#035#{Mx[:gl_c]}/,'#'). +        gsub(/#{Mx[:gl_o]}#042#{Mx[:gl_c]}/,'*'). +        gsub(/#{Mx[:gl_o]}#045#{Mx[:gl_c]}/,'-'). +        gsub(/#{Mx[:gl_o]}#047#{Mx[:gl_c]}/,'/'). +        gsub(/#{Mx[:gl_o]}#095#{Mx[:gl_c]}/,'_'). +        gsub(/#{Mx[:gl_o]}#123#{Mx[:gl_c]}/,'{'). +        gsub(/#{Mx[:gl_o]}#125#{Mx[:gl_c]}/,'}'). +        gsub(/#{Mx[:gl_o]}#126#{Mx[:gl_c]}/,'~'). +        gsub(/#{Mx[:gl_o]}#169#{Mx[:gl_c]}/,'©'). +        gsub(/\s\s+/,' '). +        gsub(/\s\s+/,' '). +        strip +    end +    def semi_revert_markup                                             # used for digest, define rules, make same as in db clean +      if @t_o +        @s=@s.gsub(/#{Mx[:fa_bold_o]}(.+?)#{Mx[:fa_bold_c]}/,'*{\1}*'). +          gsub(/#{Mx[:fa_italics_o]}(.+?)#{Mx[:fa_italics_c]}/,'/{\1}/'). +          gsub(/#{Mx[:fa_underscore_o]}(.+?)#{Mx[:fa_underscore_c]}/,'_{\1}_'). +          gsub(/#{Mx[:fa_cite_o]}(.+?)#{Mx[:fa_cite_c]}/,'"{\1}"'). +          gsub(/#{Mx[:fa_insert_o]}(.+?)#{Mx[:fa_insert_c]}/,'+{\1}+'). +          gsub(/#{Mx[:fa_strike_o]}(.+?)#{Mx[:fa_strke_c]}/,'-{\1}-'). +          gsub(/#{Mx[:fa_superscript_o]}(.+?)#{Mx[:fa_superscript_c]}/,'^{\1}^'). +          gsub(/#{Mx[:fa_subscript_o]}(.+?)#{Mx[:fa_subscript_c]}/,',{\1},'). +          gsub(/#{Mx[:gl_o]}#(?:126|152)#{Mx[:gl_c]}/i,'~'). +          gsub(/#{Mx[:en_a_o]}([\d*+]+\s+.+?)#{Mx[:en_a_c]}/,'~{\1}~'). # endnote marker marked up +          gsub(/#{Mx[:en_b_o]}([\d*+]+\s+.+?)#{Mx[:en_b_c]}/,'~[\1]~') # endnote marker marked up +        if @t_o.is==:heading \ +        || @t_o.is==:para +          @s=@s.gsub(/ [ ]+/,' ') +          @s=@s.gsub(/(?:#{Mx[:nbsp]})+/,' ') +          if @t_o.is==:heading +            @s=@t_o.lv + '~ ' + @s +          end +          if @t_o.is==:para +            if @t_o.bullet_ +              @s='_* ' + @s +            end +            if @t_o.indent.to_i > 0 +              @s="_#{@t_o.indent} " + @s +              @s=@s.gsub(/^(_[1-9])\s_\*\s/,'\1* ') +            end +          end +        end +        if @t_o.is==:block \ +        || @t_o.is==:group \ +        || @t_o.is==:code +          @s=@s.gsub(/#{Mx[:nbsp]}/,' ') +          @s="#{@t_o.is.to_s}{\n\n#{@s}\n\n}#{@t_o.is.to_s}" +          @s=@s.gsub(/(?:#{Mx[:br_nl]}|\n)+/m,"\n\n") +        end +        #dealing with poem and verse calls for change in dal, where start and end verse of poem are marked as such +        @s=@s.strip +      end +      @s +    end +    def html_lite #test whether eventually can be used in db_import replacing shared_html_lite (search for SiSU_FormatShared) +      if @t_o +        @s=@s.gsub(/#{Mx[:fa_bold_o]}(.+?)#{Mx[:fa_bold_c]}/,'<b>\1</b>'). +          gsub(/#{Mx[:fa_italics_o]}(.+?)#{Mx[:fa_italics_c]}/,'<i>\1</i>'). +          gsub(/#{Mx[:fa_underscore_o]}(.+?)#{Mx[:fa_underscore_c]}/,'<u>\1</u>'). +          gsub(/#{Mx[:fa_cite_o]}(.+?)#{Mx[:fa_cite_c]}/,'"\1"'). +          gsub(/#{Mx[:fa_insert_o]}(.+?)#{Mx[:fa_insert_c]}/,'+{\1}+'). +          gsub(/#{Mx[:fa_strike_o]}(.+?)#{Mx[:fa_strke_c]}/,'-{\1}-'). +          gsub(/#{Mx[:fa_superscript_o]}(.+?)#{Mx[:fa_superscript_c]}/,'<sup>\1</sup>'). +          gsub(/#{Mx[:fa_subscript_o]}(.+?)#{Mx[:fa_subscript_c]}/,'<sub>\1</sub>'). +          gsub(/#{Mx[:gl_o]}#(?:126|152)#{Mx[:gl_c]}/i,'~') +        if @t_o.is !=:code +          if @s =~/#{Mx[:lnk_o]}.+?#{Mx[:lnk_c]}(?:#{Mx[:url_o]}\S+?#{Mx[:url_c]}|image)/ +            wm=@s.scan(/#{Mx[:lnk_o]}.+?#{Mx[:lnk_c]}(?:#{Mx[:url_o]}\S+?#{Mx[:url_c]}|image)|\S+/) +            words=urls(wm) +            @s=@s.gsub(/.+/m,words) +          end +          @s=@s.gsub(/#{Mx[:gl_o]}(#[0-9]{3})#{Mx[:gl_c]}/u,'&\1;'). +            gsub(/#{Mx[:gl_o]}#([a-z]{2,4})#{Mx[:gl_c]}/u,'&\1;'). +            gsub(/#{Mx[:url_o]}_(\S+?)#{Mx[:url_c]}/,'<a href="\1" target="_top">\1</a>'). #http ftp matches escaped, no decoration +            gsub(/(#{Mx[:lnk_c]})#{Mx[:url_o]}(\S+?)#{Mx[:url_c]}/,'\1<a href="\2" target="_top">\2</a>\3'). #special case \{ e.g. \}http://url +            gsub(/#{Mx[:url_o]}(\S+?)#{Mx[:url_c]}/,%{#{@url_brace.xml_open}<a href="\\1" target="_top">\\1</a>#{@url_brace.xml_close}}) #http ftp matches with decoration +        else +          @s=@s.gsub(/</m,'<').gsub(/>/m,'>') +        end +        if @t_o.is==:paragraph +          if @t_o.bullet_ +            @s=@s +          end +          if @t_o.indent > 0 +            @s=@s +          end +        end +        if @t_o.is==:heading +          @s=@s +        end +      else +        p __FILE__ << ':' << __LINE__.to_s +      end +      @s +    end +  end +  class ModifiedTextPlusHashDigest +    def initialize(md,x) +      @md=md +      if x.is_a?(String) +        @t_o,@s=nil,x +      else +        @t_o,@s=x,x.obj.dup +      end +      @env ||=SiSU_Env::InfoEnv.new(@md.fns) +      @sha_ = @env.digest(@md.opt).type +      begin +        case @sha_ +        when :sha512 +          require 'digest/sha2' +        when :sha256 +          require 'digest/sha2' +        when :md5 +          require 'digest/md5' +        end +      rescue LoadError +        SiSU_Utils::CodeMarker.new(__LINE__,__FILE__,:fuchsia).error((@sha_ ? 'digest/sha2' : 'digest/md5') + ' NOT FOUND') +      end +    end +    def digest(txt) +      d=nil +      case @sha_ +      when :sha512 +        for hash_class in [ Digest::SHA512 ] +          d=hash_class.hexdigest(txt) +        end +      when :sha256 +        for hash_class in [ Digest::SHA256 ] +          d=hash_class.hexdigest(txt) +        end +      when :md5 +        for hash_class in [ Digest::MD5 ] +          d=hash_class.hexdigest(txt) +        end +      end +      d +    end +    def strip_clean_of_markup +      def txt +        SiSU_TextRepresentation::Alter.new(@s).strip_clean_of_markup +      end +      def dgst +        txt_dgst=digest(txt) +        { txt: txt, dgst_txt: txt_dgst } +      end +      self +    end +    def semi_revert_markup +      def txt +        SiSU_TextRepresentation::Alter.new(@s).semi_revert_markup +      end +      def dgst +        txt_dgst=digest(txt) +        { txt: txt, dgst_txt: txt_dgst } +      end +      self +    end +    def composite +      def stripped_clean(txt) +        SiSU_TextRepresentation::Alter.new(txt).strip_clean_of_markup +      end +      def markup_reverted(txt) +        SiSU_TextRepresentation::Alter.new(txt).semi_revert_markup +      end +      def images(imgs) +        sys=SiSU_Env::SystemCall.new +        line_image=[] +        if imgs and imgs.length > 0 +           @image_name,@image_dgst,@img=[],[],[] +           imgs.each do |i| +             image_source=if FileTest.file?("#{@env.path.image_source_include_local}/#{i}") +               @env.path.image_source_include_local +             elsif FileTest.file?("#{@env.path.image_source_include_remote}/#{i}") +               @env.path.image_source_include_remote +             elsif FileTest.file?("#{@env.path.image_source_include}/#{i}") +               @env.path.image_source_include +             else +               SiSU_Screen::Ansi.new( +                 @md.opt.act[:color_state][:set], +                 "ERROR - image:", +                 %{"#{i}" missing}, +                 "search locations: #{@env.path.image_source_include_local}, #{@env.path.image_source_include_remote} and #{@env.path.image_source_include}" +               ).error2 unless @md.opt.act[:quiet][:set]==:on +               nil +             end +             img_type = /\S+\.(png|jpg|gif)/.match(i)[1] +             if image_source +               para_image = image_source + '/' + i +               image_name = i +               image_dgst =(@sha_ ? sys.sha256(para_image) : sys.md5(para_image)) +             else +               image_name = i + ' [image missing]' +               image_dgst = '' +             end +             line_image << { img_dgst: image_dgst[1], img_name: image_name, img_type: img_type } +           end +        end +        line_image +      end +      def endnotes(en) +        en_dgst=[] +        if en and en.length > 0 +          en.flatten.each do |e| +             note_no=e.gsub(/^([\d*+]+)\s+.+/,'\1') +             e=digest(stripped_clean(e)) +             note_dgst=digest(e) +             en_dgst << { note_number: note_no, note_dgst: note_dgst } +          end +        end +        en_dgst +      end +      def dgst +        if @t_o.of !=:comment \ +        && @t_o.of !=:structure \ +        && @t_o.of !=:layout +          txt_stripped_dgst=digest(stripped_clean(@t_o)) +          txt_markup_reverted_dgst=digest(markup_reverted(@t_o)) +          endnotes_dgst=[] +          rgx_notes=/(?:#{Mx[:en_a_o]}|#{Mx[:en_b_o]})([\d*+]+\s+.+?)(?:#{Mx[:en_a_c]}|#{Mx[:en_b_c]})/ +          notes=@t_o.obj.scan(rgx_notes) +          endnotes_dgst=endnotes(notes) +          rgx_image=/#{Mx[:lnk_o]}(\S+\.(?:png|jpg|gif))\s.+?#{Mx[:lnk_c]}(?:#{Mx[:url_o]}\S+?#{Mx[:url_c]}|image)/ +          imgs=if (@t_o.is==:para \ +          || @t_o.is==:image) \ +          and @t_o.obj =~rgx_image +            imgs=@t_o.obj.scan(rgx_image).flatten +            line_image=images(imgs) +          end +          dgst={ is: @t_o.is, ocn: @t_o.ocn, dgst_stripped_txt: txt_stripped_dgst, dgst_markedup_txt: txt_markup_reverted_dgst } +          dgst[:endnotes]=endnotes_dgst if endnotes_dgst and endnotes_dgst.length > 0 +          dgst[:images]=line_image if line_image and line_image.length > 0 +        end +        dgst +      end +      self +    end +  end +end +__END__ +#+END_SRC + +** shared_metadata.rb + +#+BEGIN_SRC ruby  :tangle "../lib/sisu/shared_metadata.rb" +# <<sisu_document_header>> +module SiSU_Metadata +  require_relative 'xml_parts'                          # xml_parts.rb +  require_relative 'xml_shared'                         # xml_shared.rb +  class Summary +    include SiSU_Parts_XML +    attr_accessor :tag,:inf,:class,:attrib +    def initialize(md,display_heading=false) +      @md,@display_heading=md,display_heading +      @tag,@inf,@class,@attrib=nil +    end +    def metadata_base +      meta=[] +      l=SiSU_Env::StandardiseLanguage.new(@md.opt.lng).language +      language=l[:n] +      tr=SiSU_Translate::Source.new(@md,language) +      @attrib='md' +      def meta_content_clean(content='') +        content=if not content.nil? +          content=content.tr('"',"'"). +            gsub(/&/,'&') +        else content +        end +      end +      if @display_heading +        @tag,@inf=%{<b><u>Document Metadata</u></b>},'' +        meta << self.meta_para +      end +      if defined? @md.title.full \ +      and @md.title.full=~/\S+/ +        @tag,@inf,@class=tr.full_title,@md.title.full,'dc' #1 +        meta << self.meta_para +      end +      if defined? @md.creator.author \ +      and @md.creator.author=~/\S+/ +        @tag,@inf,@class=tr.author,@md.creator.author,'dc' #2 +        meta << self.meta_para +      end +      if defined? @md.creator.translator \ +      and @md.creator.translator=~/\S+/ +        @tag,@inf,@class=tr.translator,@md.creator.translator,'ext' +        meta << self.meta_para +      end +      if defined? @md.creator.illustrator \ +      and @md.creator.illustrator=~/\S+/ +        @tag,@inf,@class=tr.illustrator,@md.creator.illustrator,'ext' +        meta << self.meta_para +      end +      if defined? @md.creator.prepared_by \ +      and @md.creator.prepared_by=~/\S+/ +        @tag,@inf,@class=tr.prepared_by,@md.creator.prepared_by,'ext' +        meta << self.meta_para +      end +      if defined? @md.creator.digitized_by \ +      and @md.creator.digitized_by=~/\S+/ +        @tag,@inf,@class=tr.digitized_by,@md.creator.digitized_by,'ext' +        meta << self.meta_para +      end +      if defined? @md.creator.contributor \ +      and @md.creator.contributor=~/\S+/ +        @tag,@inf,@class=tr.contributor,@md.creator.contributor,'dc' #6 +        meta << self.meta_para +      end +      if defined? @md.rights.all \ +      and @md.rights.all=~/\S+/ +        @tag,@inf,@class=tr.rights,meta_content_clean(@md.rights.all),'dc' #15 +        meta << self.meta_para +      end +      if defined? @md.classify.subject \ +      and @md.classify.subject=~/\S+/ +        @tag,@inf,@class=tr.subject,@md.classify.subject,'dc' #3 +        meta << self.meta_para +      end +      if defined? @md.classify.keywords \ +      and @md.classify.keywords=~/\S+/ +        @tag,@inf,@class=tr.keywords,@md.classify.keywords,'ext' +        meta << self.meta_para +      end +      if defined? @md.classify.loc \ +      and @md.classify.loc=~/\S+/ +        @tag,@inf,@class=tr.cls_loc,@md.classify.loc,'id' +        meta << self.meta_para +      end +      if defined? @md.classify.dewey \ +      and @md.classify.dewey=~/\S+/ +        @tag,@inf,@class=tr.cls_dewey,@md.classify.dewey,'id' +        meta << self.meta_para +      end +      if defined? @md.publisher \ +      and @md.publisher=~/\S+/ +        @tag,@inf,@class=tr.publisher,@md.publisher,'dc' #5 +        meta << self.meta_para +      end +      if defined? @md.date.created \ +      and @md.date.created=~/\S+/ +        @tag,@inf,@class=tr.date_created,@md.date.created,'dc' #7 +        meta << self.meta_para +      end +      if defined? @md.date.issued \ +      and @md.date.issued=~/\S+/ +        @tag,@inf,@class=tr.date_issued,@md.date.issued,'dc' #7 +        meta << self.meta_para +      end +      if defined? @md.date.available \ +      and @md.date.available=~/\S+/ +        @tag,@inf,@class=tr.date_available,@md.date.available,'dc' #7 +        meta << self.meta_para +      end +      if defined? @md.date.modified \ +      and @md.date.modified=~/\S+/ +        @tag,@inf,@class=tr.date_modified,@md.date.modified,'dc' #7 +        meta << self.meta_para +      end +      if defined? @md.date.valid \ +      and @md.date.valid=~/\S+/ +        @tag,@inf,@class=tr.date_valid,@md.date.valid,'dc' #7 +        meta << self.meta_para +      end +      if defined? @md.date.published \ +      and @md.date.published=~/\S+/ +        @tag,@inf,@class=tr.date,@md.date.published,'dc' #7 +        meta << self.meta_para +      end +      if defined? @md.identifier.isbn \ +      and @md.identifier.isbn=~/\S+/ +        @tag,@inf,@class=tr.cls_isbn,@md.identifier.isbn,'id' +        meta << self.meta_para +      end +      if defined? @md.identifier.oclc \ +      and @md.identifier.oclc=~/\S+/ +        @tag,@inf,@class=tr.cls_oclc,@md.identifier.oclc,'id' +        meta << self.meta_para +      end +      if defined? @md.notes.description \ +      and @md.notes.description=~/\S+/ +        @tag,@inf,@class=tr.description,@md.notes.description,'dc' #4 +        meta << self.meta_para +      end +      if defined? @md.notes.abstract \ +      and @md.notes.abstract=~/\S+/ +        @tag,@inf,@class=tr.abstract,@md.notes.abstract,'ext' +        meta << self.meta_para +      end +      if defined? @md.notes.comment \ +      and @md.notes.comment=~/\S+/ +        @tag,@inf,@class=tr.comments,@md.notes.comment,'ext' +        meta << self.meta_para +      end +      if defined? @md.notes.coverage \ +      and @md.notes.coverage=~/\S+/ +        @tag,@inf,@class=tr.coverage,@md.notes.coverage,'dc' #14 +        meta << self.meta_para +      end +      if defined? @md.notes.relation \ +      and @md.notes.relation=~/\S+/ +        @tag,@inf,@class=tr.relation,@md.notes.relation,'dc' #13 +        meta << self.meta_para +      end +      #if defined? @md.notes.source \ +      #and @md.notes.source=~/\S+/ +      #  @tag,@inf,@class=tr.source,@md.notes.source,'dc' #11 +      #  meta << self.meta_para +      #end +      if defined? @md.notes.history \ +      and @md.notes.history=~/\S+/ +        @tag,@inf,@class=tr.type,@md.notes.history,'dc' #8 +        meta << self.meta_para +      end +      if defined? @md.notes.type \ +      and @md.notes.type=~/\S+/ +        @tag,@inf,@class=tr.type,@md.notes.type,'dc' #8 +        meta << self.meta_para +      end +      if defined? @md.notes.format \ +      and @md.notes.format=~/\S+/ +        @tag,@inf,@class=tr.format,@md.notes.format,'dc' #9 +        meta << self.meta_para +      end +      if defined? @md.notes.prefix_a \ +      and @md.notes.prefix_a=~/\S+/ +        @tag,@inf,@class=tr.prefix_a,@md.notes.prefix_a,'inf' +        meta << self.meta_para +      end +      if defined? @md.notes.prefix_b \ +      and @md.notes.prefix_b=~/\S+/ +        @tag,@inf,@class=tr.prefix_b,@md.notes.prefix_b,'inf' +        meta << self.meta_para +      end +      if defined? @md.original.source \ +      and @md.original.source=~/\S+/ +        @tag,@inf,@class=tr.source,@md.original.source,'dc' #11 +        meta << self.meta_para +      end +      if defined? @md.title.language \ +      and @md.title.language=~/\S+/ +        @tag,@inf,@class=tr.language,@md.title.language,'dc' #12 +        meta << self.meta_para +      end +      if defined? @md.original.language \ +      and @md.original.language=~/\S+/ +        @tag,@inf,@class=tr.language_original,@md.original.language,'ext' +        meta << self.meta_para +      end +      if @display_heading +        @tag,@inf=%{<b><u>Version Information</u></b>},'' +        meta << self.meta_para +      end +      if defined? @md.fns \ +      and @md.fns=~/\S+/ +        @tag,@inf,@class=tr.sourcefile,@md.fns,'src' +        meta << self.meta_para +      end +      if defined? @md.file_encoding \ +      and @md.file_encoding=~/\S+/ +        @tag,@inf,@class='Filetype',@md.file_encoding,'src' +        meta << self.meta_para +      end +      if defined? @md.dgst \ +      and @md.dgst.is_a?(Array) +        @tag,@inf,@class='Source Digest',"#{@md.dgst[0]} #{@md.dgst[1]}",'src' +        meta << self.meta_para +      end +      if @display_heading +        @tag,@inf=%{<b><u>Generated</u></b>},'' +        meta << self.meta_para +      end +      if defined? @md.project_details \ +      and @md.project_details.version=~/\S+/ +        v="#{tr.sisu_version}: " + +          "#{@md.project_details.project} " + +          "#{@md.project_details.version} " + +          "of #{@md.project_details.date_stamp} " + +          "(#{@md.project_details.date})" +        @tag,@inf,@class='Generated by',v,'ver' +        meta << self.meta_para +      end +      if defined? @md.ruby_version \ +      and @md.ruby_version=~/\S+/ +        @tag,@inf,@class=tr.ruby_version,@md.ruby_version,'ver' +        meta << self.meta_para +      end +      if defined? @md.generated \ +      and @md.generated.is_a?(Time) +        @tag,@inf,@class=tr.last_generated,@md.generated,'date' +        meta << self.meta_para +      end +      meta +    end +    def metadata_alt +      meta=[] +      if @display_heading +        @tag,@inf=%{<b><u>Document Metadata</u></b>},'' +        meta << self.meta_para +      end +      if defined? @md.title.main \ +      and @md.title.main=~/\S+/ +        @tag='title' +        @inf=@md.title.main +        meta << self.meta_para +      end +      if defined? @md.title.sub \ +      and @md.title.sub=~/\S+/ +        @tag='subtitle' +        @inf=@md.title.sub +        meta << self.meta_para +      end +      if defined? @md.creator.author \ +      and @md.creator.author=~/\S+/ +        @tag='author' +        @inf=@md.creator.author +        meta << self.meta_para +      end +      if defined? @md.creator.translator \ +      and @md.creator.translator=~/\S+/ +        @tag='translator' +        @inf=@md.creator.translator +        meta << self.meta_para +      end +      if defined? @md.creator.illustrator \ +      and @md.creator.illustrator=~/\S+/ +        @tag='illustrator' +        @inf=@md.creator.illustrator +        meta << self.meta_para +      end +      if defined? @md.rights.copyright.text \ +      and @md.rights.copyright.text=~/\S+/ +        @tag='copyright' +        @inf=@md.rights.copyright.text # year & holder +        @inf=@inf.gsub(/(?:Copyright|\(C\))+\s*/,'') +        meta << self.meta_para +      end +      if defined? @md.rights.license \ +      and @md.rights.license=~/\S+/ +        @tag='license' +        @inf=@md.rights.license +        meta << self.meta_para +      end +      meta +    end +    def processing_tags +      def make +        def language +          if defined? @md.make.language \ +          and @md.make.language +            ' :language: ' + @md.make.language.join(', ') +          else nil +          end +        end +        def headings +          if defined? @md.make.headings \ +          and @md.make.headings +            ' :headings: ' + @md.make.headings[0].join('; ') +          else nil +          end +        end +        def num_top +          if defined? @md.make.num_top \ +          and @md.make.num_top +            ' :num_top: ' + @md.make.num_top +          else nil +          end +        end +        def breaks +          x=if defined? @md.make.breaks \ +            and @md.make.breaks +            x=' :breaks:' +            if @md.make.breaks[:page_break] +              x +=' break=' + @md.make.breaks[:page_break] + ';' +            end +            if @md.make.breaks[:page_new] +              x +=' new=' + @md.make.breaks[:page_new] + ';' +            end +          else nil +          end +        end +        def emphasis +          if defined? @md.make.emphasis \ +          and @md.make.emphasis +            ' :emphasis: ' + @md.make.emphasis[:regx].inspect +          else nil +          end +        end +        def bold +          if defined? @md.make.bold \ +          and @md.make.bold +            ' :bold: ' + @md.make.bold[:regx].inspect +          else nil +          end +        end +        def italics +          if defined? @md.make.italics \ +          and  @md.make.italics +            ' :italics: ' + @md.make.italics[:regx].inspect +          else nil +          end +        end +        def texpdf_font +          if defined? @md.make.texpdf_font \ +          and @md.make.texpdf_font +            ' :texpdf_font: ' + @md.make.texpdf_font.main +          else nil +          end +        end +        self +      end +      self +    end +    def metadata_tags +      def title +        def main +          if defined? @md.title.main \ +          and @md.title.main +            '@title: ' + @md.title.main +          else '@title:' +          end +        end +        def sub +          if defined? @md.title.sub \ +          and @md.title.sub +            ' :subtitle: ' + @md.title.sub +          else nil +          end +        end +        def edition +          if defined? @md.title.edition \ +          and @md.title.edition +            ' :edition: ' + @md.title.edition +          else nil +          end +        end +        def note +          if defined? @md.title.note \ +          and @md.title.note +            ' :note: ' + @md.title.note +          else nil +          end +        end +        def short +          if defined? @md.title.short \ +          and @md.title.short +            ' :short: ' + @md.title.short +          else nil +          end +        end +        def language +          if defined? @md.title.language \ +          and @md.title.language +            ' :language: ' + @md.title.language +          else nil +          end +        end +        def language_char +          if defined? @md.title.language_char \ +          and @md.title.language_char +            ' :language_char: ' + @md.title.language_char +          else nil +          end +        end +        self +      end +      def creator +        def head +          '@creator:' +        end +        def author +          x=if defined? @md.creator.author_detail \ +            and @md.creator.author_detail +            x='' +            @md.creator.author_detail.each do |n| +              x += "#{n[:the]}, #{n[:others]}; " +            end +            x=x.gsub(/;\s*$/,'') +            ' :author: ' + x +          else nil +          end +        end +        def contributor +          x=if defined? @md.creator.contributor_detail \ +            and @md.creator.contributor_detail +            x='' +            @md.creator.contributor_detail.each do |n| +              x += "#{n[:the]}, #{n[:others]}; " +            end +            x=x.gsub(/;\s*$/,'') +            ' :contributor: ' + x +          else nil +          end +        end +        def illustrator +          x=if defined? @md.creator.illustrator_detail \ +            and @md.creator.illustrator_detail +            x='' +            @md.creator.illustrator_detail.each do |n| +              x += "#{n[:the]}, #{n[:others]}; " +            end +            x=x.gsub(/;\s*$/,'') +            ' :illustrator: ' + x +          else nil +          end +        end +        def photographer +          x=if defined? @md.creator.photographer_detail \ +            and @md.creator.photographer_detail +            x='' +            @md.creator.photographer_detail.each do |n| +              x += "#{n[:the]}, #{n[:others]}; " +            end +            x=x.gsub(/;\s*$/,'') +            ' :photographer: ' + x +          else nil +          end +        end +        def translator +          x=if defined? @md.creator.translator_detail \ +            and @md.creator.translator_detail +            x='' +            @md.creator.translator_detail.each do |n| +              x += "#{n[:the]}, #{n[:others]}; " +            end +            x=x.gsub(/;\s*$/,'') +            ' :translator: ' + x +          else nil +          end +        end +        def audio +          x=if defined? @md.creator.audio_detail \ +            and @md.creator.audio_detail +            x='' +            @md.creator.audio_detail.each do |n| +              x += "#{n[:the]}, #{n[:others]}; " +            end +            x=x.gsub(/;\s*$/,'') +            ' :audio: ' + x +          else nil +          end +        end +        def digitized_by +          x=if defined? @md.creator.digitized_by_detail \ +            and @md.creator.digitized_by_detail +            x='' +            @md.creator.digitized_by_detail.each do |n| +              x += "#{n[:the]}, #{n[:others]}; " +            end +            x=x.gsub(/;\s*$/,'') +            ' :digitized_by: ' + x +          else nil +          end +        end +        def prepared_by +          x=if defined? @md.creator.prepared_by_detail \ +            and @md.creator.prepared_by_detail +            x='' +            @md.creator.prepared_by_detail.each do |n| +              x += "#{n[:the]}, #{n[:others]}; " +            end +            x=x.gsub(/;\s*$/,'') +            ' :prepared_by: ' + x +          else nil +          end +        end +        self +      end +      def rights +        def head +          '@rights:' +        end +        def copyright +          def text +            if defined? @md.rights.copyright.text \ +            and @md.rights.copyright.text +              ' :copyright: ' + @md.rights.copyright.text +            else nil +            end +          end +          def translation +            if defined? @md.rights.copyright.translation \ +            and @md.rights.copyright.translation +              ' :translation: ' + @md.rights.copyright.translation +            else nil +            end +          end +          def illustrations +            if defined? @md.rights.copyright.illustrations \ +            and @md.rights.copyright.illustrations +              ' :illustrations: ' + @md.rights.copyright.illustrations +            else nil +            end +          end +          def photographs +            if defined? @md.rights.copyright.photographs \ +            and @md.rights.copyright.photographs +              ' :photographs: ' + @md.rights.copyright.photographs +            else nil +            end +          end +          def digitization +            if defined? @md.rights.copyright.digitization \ +            and @md.rights.copyright.digitization +              ' :digitization: ' + @md.rights.copyright.digitization +            else nil +            end +          end +          def audio +            if defined? @md.rights.copyright.audio \ +            and @md.rights.copyright.audio +              ' :audio: ' + @md.rights.copyright.audio +            else nil +            end +          end +          self +        end +        def license +          if defined? @md.rights.license \ +          and @md.rights.license +            ' :license: ' + @md.rights.license +          else nil +          end +        end +        self +      end +      def classify +        def head +          '@classify:' +        end +        def coverage +          if defined? @md.classify.coverage \ +          and @md.classify.coverage +            ' :coverage: ' + @md.classify.coverage +          else nil +          end +        end +        def relation +          if defined? @md.classify.relation \ +          and @md.classify.relation +            ' :relation: ' + @md.classify.relation +          else nil +          end +        end +        def subject +          if defined? @md.classify.subject \ +          and @md.classify.subject +            ' :subject: ' + @md.classify.subject +          else nil +          end +        end +        def topic_register +          if defined? @md.classify.topic_register \ +          and @md.classify.topic_register +            ' :topic_register: ' + @md.classify.topic_register +          else nil +          end +        end +        def type +#         if defined? @md.classify.type \ +#         and @md.classify.type +#           ' :type: ' + @md.classify.type +#         else nil +#         end +          nil +        end +        #def identifier +        #  if defined? @md.classify.identifier \ +        #  and @md.classify.identifier +        #    ' :identifier: ' + @md.classify.identifier +        #  else nil +        #  end +        #end +        def loc +          if defined? @md.classify.loc \ +          and @md.classify.loc +            ' :loc: ' + @md.classify.loc +          else nil +          end +        end +        def dewey +          if defined? @md.classify.dewey \ +          and @md.classify.dewey +            ' :dewey: ' + @md.classify.dewey +          else nil +          end +        end +        def oclc +          if defined? @md.classify.oclc \ +          and @md.classify.oclc +            ' :oclc: ' + @md.classify.oclc +          else nil +          end +        end +        def pg +          if defined? @md.classify.pg \ +          and @md.classify.pg +            ' :pg: ' + @md.classify.pg +          else nil +          end +        end +        def isbn +          if defined? @md.classify.isbn \ +          and @md.classify.isbn +            ' :isbn: ' + @md.classify.isbn +          else nil +          end +        end +        self +      end +      def date +        def head +          '@date:' +        end +        def added_to_site +          if defined? @md.date.added_to_site \ +          and @md.date.added_to_site +            ' :added_to_site: ' + @md.date.added_to_site +          else nil +          end +        end +        def available +          if defined? @md.date.available \ +          and @md.date.available +            ' :available: ' + @md.date.available +          else nil +          end +        end +        def created +          if defined? @md.date.created \ +          and @md.date.created +            ' :created: ' + @md.date.created +          else nil +          end +        end +        def issued +          if defined? @md.date.issued \ +          and @md.date.issued +            ' :issued: ' + @md.date.issued +          else nil +          end +        end +        def modified +          if defined? @md.date.modified \ +          and @md.date.modified +            ' :modified: ' + @md.date.modified +          else nil +          end +        end +        def published +          if defined? @md.date.published \ +          and @md.date.published +            ' :published: ' + @md.date.published +          else nil +          end +        end +        def valid +          if defined? @md.date.valid \ +          and @md.date.valid +            ' :valid: ' + @md.date.valid +          else nil +          end +        end +        self +      end +      #def make +      #  def headings +      #    @md.make.headings \ +      #    ? (' :headings: ' + @md.make.headings) \ +      #    : nil +      #  end +      #end +      self +    end +    def char_enc(str) +      @s=str +      def amp +        if @s \ +        and @s.is_a?(String) +          @s=@s.gsub(/&/u,'&') +        end +        @s +      end +      def br +        if @s \ +        and @s.is_a?(String) +          @s=@s.gsub(/(?:#{Mx[:br_line]}|\\\\)+/,'<br />') +        end +        @s +      end +      def utf8 +        if @s \ +        and @s.is_a?(String) +          @s=@s.gsub(/<br(?: \/)?>/u,Mx[:br_paragraph]). +            gsub(/</um,'<').gsub(/>/um,'>'). +            #gsub(/</um,'<').gsub(/>/um,'>'). +            gsub(/ /um,' ').       # space identify +            gsub(/ /um,' ').       # space identify +            gsub(/#{Mx[:br_paragraph]}/u,'<br />') +        end +        @s +      end +      self +    end +    def xml_docbook +      def meta_para +        inf_xml=char_enc(@inf).amp +        inf_xml=char_enc(inf_xml).br +        <<WOK +#{Ax[:tab]}<#{@tag}> +#{Ax[:tab]*2}#{inf_xml} +#{Ax[:tab]}</#{@tag}> +WOK +      end +      def metadata +        SiSU_Metadata::Summary.new(@md).metadata_alt +      end +      self +    end +    def html_display +      def meta_para +        inf_xml=char_enc(@inf).amp +        inf_xml=char_enc(inf_xml).br +        %{<p class="norm"> +  <b>#{@tag}</b>: #{inf_xml} +</p>} +      end +      def metadata +        SiSU_Metadata::Summary.new(@md,true).metadata_base +      end +      self +    end +    def xml_sax +      def meta_para +        inf_xml=char_enc(inf_xml).br +        <<WOK +<metadata> +#{Ax[:tab]}<meta>#{@tag.capitalize}:</meta> +#{Ax[:tab]}<data class="#{@attrib}"> +#{Ax[:tab]*2}#{inf_xml} +#{Ax[:tab]}</data> +</metadata> +WOK +      end +      def metadata +        SiSU_Metadata::Summary.new(@md).metadata_base +      end +      self +    end +    def xml_dom +      def meta_para +        inf_xml=char_enc(inf_xml).amp +        inf_xml=char_enc(inf_xml).br +        <<WOK +#{Ax[:tab]}<header> +#{Ax[:tab]*2}<meta>#{@tag.capitalize}:</meta> +#{Ax[:tab]*2}<#{@attrib}> +#{Ax[:tab]*3}#{inf_xml} +#{Ax[:tab]*2}</#{@attrib}> +#{Ax[:tab]}</header> +WOK +      end +      def metadata +        SiSU_Metadata::Summary.new(@md).metadata_base +      end +      self +    end +    def xhtml_scroll +      def meta_para +        inf_xml=char_enc(inf_xml).amp +        inf_xml=char_enc(inf_xml).br +        <<WOK +#{Ax[:tab]}<metadata> +#{Ax[:tab]}<meta>#{@tag.capitalize}:</meta> +#{Ax[:tab]}<#{@attrib} class="#{@class}"> +#{Ax[:tab]*2}#{inf_xml} +#{Ax[:tab]}</#{@attrib}> +#{Ax[:tab]}</metadata> +	<br /> +WOK +      end +      def metadata +        SiSU_Metadata::Summary.new(@md).metadata_base +      end +      self +    end +    def xhtml_display +      def meta_para +        inf_xml=char_enc(@inf).amp +        inf_xml=char_enc(inf_xml).br +        %{<p class="norm"> +  <b>#{@tag}</b>: #{inf_xml} +</p>} +      end +      def metadata +        SiSU_Metadata::Summary.new(@md,true).metadata_base +      end +      self +    end +    def odf +      def meta_para +        if @inf.is_a?(String) +          @inf=@inf.gsub(/</,'<').gsub(/>/,'>'). +            gsub(/<br(?: \/)?>/,'<br />') +          if @inf =~/&/ +            inf_array=[] +            word=@inf.scan(/\S+|\n/) +            word.each do |w| # _ - / # | : ! ^ ~ +              w=w.gsub(/ /,' ') +              if w !~/&\S{2,7}?;/ +                w=w.gsub(/&/,'&') +              end +              inf_array << w +            end +            @inf=inf_array.join(' ') +          end +          @inf=@inf.gsub(/#{Mx[:url_o]}_(\S+?)#{Mx[:url_c]}/, +              '<text:a xl:type="simple" xl:href="\1">\1</text:a>'). #http ftp matches escaped, no decoration +            gsub(/(#{Mx[:lnk_c]})#{Mx[:url_o]}(\S+?)#{Mx[:url_c]}/, +              '\1<text:a xl:type="simple" xl:href="\2">\2</text:a>') #special case \{ e.g. \}http://url +          @inf=if @inf =~/#{Mx[:url_o]}(\S+?)#{Mx[:url_c]}/ +            @inf.gsub(/#{Mx[:url_o]}(\S+?)#{Mx[:url_c]}/, +              %{#{the_url_decoration.xml_open}<text:a xl:type="simple" xl:href="\\1">\\1</text:a>#{the_url_decoration.xml_close}}) #http ftp matches with decoration +          else +            @inf.gsub(/(https?:\/\/[^<>()'"\s]+)/, +              %{#{the_url_decoration.xml_open}<text:a xl:type="simple" xl:href="\\1">\\1</text:a>#{the_url_decoration.xml_close}}) #http ftp matches with decoration +          end +          @inf=@inf.gsub(/([a-zA-Z0-9._-]+@[a-zA-Z0-9._-]+)/, +            %{#{the_url_decoration.xml_open}<text:a xl:type="simple" xl:href="mailto:\\1">\\1</text:a>#{the_url_decoration.xml_close}}) if @inf !~/http:\/\// # improve upon, document crash where url contains '@' symbol +        end +        <<WOK +<text:p text:style-name="P1">#{@tag.capitalize}: #{@inf}</text:p> +WOK +      end +      def metadata +        SiSU_Metadata::Summary.new(@md).metadata_base +      end +      self +    end +    def json +      def meta_para +        <<WOK + +#{@tag.capitalize}: #{@inf} +WOK +      end +      def metadata +        SiSU_Metadata::Summary.new(@md).metadata_base +      end +      self +    end +    def plaintext +      def meta_para +        <<WOK + +#{@tag.capitalize}: #{@inf} +WOK +      end +      def metadata +        SiSU_Metadata::Summary.new(@md).metadata_base +      end +      self +    end +    def manpage +      def meta_para +        <<WOK + +.TP +#{@tag.capitalize}: +.I #{@inf} +WOK +      end +      def metadata +        SiSU_Metadata::Summary.new(@md).metadata_base +      end +      self +    end +  end +  class TeX_Metadata +    def initialize(md) +      @md=md +      @br="\\\\\n" +      @make=SiSU_Env::ProcessingSettings.new(md) +      @o_str ||=SiSU_Env::ProcessingSettings.new(md).output_dir_structure +    end +    def meta_para(tag,inf,sc=true) +      inf=((inf.is_a?(String) && sc) ? spec_char(inf) : inf) +      %{\\begin\{bfseries\}#{tag}:\\end\{bfseries\} #{inf} +} +    end +    def spec_char(inf) +      SiSU_TeX_Pdf::SpecialCharacters.new(@md,inf).special_characters +    end +    def word_break_points(inf) +      SiSU_TeX_Pdf::SpecialCharacters.new(@md,inf).special_word_break_points +    end +    def number_break_points(inf) +      SiSU_TeX_Pdf::SpecialCharacters.new(@md,inf).special_number_break_points +    end +    def metadata_tex +      meta=[] +      l=SiSU_Env::StandardiseLanguage.new(@md.opt.lng).language +      language=l[:n] +      tr=SiSU_Translate::Source.new(@md,language) +      if @make.build.links_to_manifest? \ +      and not @o_str.dump_or_redirect? +        tag="Document Manifest @" +        inf="#{@br}#{@md.file.output_path.manifest.url}/#{@md.file.base_filename.manifest}" +        meta << meta_para(tag,inf) +      end +      if defined? @md.title.full \ +      and @md.title.full=~/\S+/ +        tag,inf=tr.full_title,@md.title.full +        meta << meta_para(tag,inf) +      end +      if defined? @md.creator.author \ +      and @md.creator.author=~/\S+/ +        tag,inf=tr.author,@md.creator.author +        meta << meta_para(tag,inf) +      end +      if defined? @md.creator.translator \ +      and @md.creator.translator=~/\S+/ +        tag,inf=tr.translator,@md.creator.translator +        meta << meta_para(tag,inf) +      end +      if defined? @md.creator.illustrator \ +      and @md.creator.illustrator=~/\S+/ +        tag,inf=tr.illustrator,@md.creator.illustrator +        meta << meta_para(tag,inf) +      end +      if defined? @md.creator.prepared_by \ +      and @md.creator.prepared_by=~/\S+/ +        tag,inf=tr.prepared_by,@md.creator.prepared_by +        meta << meta_para(tag,inf) +      end +      if defined? @md.creator.digitized_by \ +      and @md.creator.digitized_by=~/\S+/ +        tag,inf=tr.digitized_by,@md.creator.digitized_by +        meta << meta_para(tag,inf) +      end +      if defined? @md.rights.all \ +      and @md.rights.all=~/\S+/ +        tag,inf=tr.rights,@md.rights.all +        meta << meta_para(tag,inf) +      end +      if defined? @md.notes.description \ +      and @md.notes.description=~/\S+/ +        tag,inf=tr.description,@md.notes.description +        meta << meta_para(tag,inf) +      end +      if defined? @md.classify.subject \ +      and @md.classify.subject=~/\S+/ +        tag,inf=tr.subject,@md.classify.subject +        meta << meta_para(tag,inf) +      end +      if defined? @md.publisher \ +      and @md.publisher=~/\S+/ +        tag,inf=tr.publisher,@md.publisher +        meta << meta_para(tag,inf) +      end +      if defined? @md.creator.contributor \ +      and @md.creator.contributor=~/\S+/ +        tag,inf=tr.contributor,@md.creator.contributor +        meta << meta_para(tag,inf) +      end +      if defined? @md.notes.abstract \ +      and @md.notes.abstract=~/\S+/ +        tag,inf=tr.abstract,@md.notes.abstract +        meta << meta_para(tag,inf) +      end +      if defined? @md.date.created \ +      and @md.date.created=~/\S+/ +        tag,inf=tr.date_created,@md.date.created +        meta << meta_para(tag,inf) +      end +      if defined? @md.date.issued \ +      and @md.date.issued=~/\S+/ +        tag,inf=tr.date_issued,@md.date.issued +        meta << meta_para(tag,inf) +      end +      if defined? @md.date.available \ +      and @md.date.available=~/\S+/ +        tag,inf=tr.date_available,@md.date.available +        meta << meta_para(tag,inf) +      end +      if defined? @md.date.modified \ +      and @md.date.modified=~/\S+/ +        tag,inf=tr.date_modified,@md.date.modified +        meta << meta_para(tag,inf) +      end +      if defined? @md.date.valid \ +      and @md.date.valid=~/\S+/ +        tag,inf=tr.date_valid,@md.date.valid +        meta << meta_para(tag,inf) +      end +      if defined? @md.date.published \ +      and @md.date.published=~/\S+/ +        tag,inf=tr.date,@md.date.published +        meta << meta_para(tag,inf) +      end +      if defined? @md.classify.topic_register \ +      and @md.classify.topic_register=~/\S+/ +        tag,inf=tr.topic_register,@md.classify.topic_register +        inf=word_break_points(inf) +        meta << meta_para(tag,inf) +      end +      if defined? @md.classify.loc \ +      and @md.classify.loc=~/\S+/ +        tag,inf=tr.cls_loc,@md.classify.loc +        meta << meta_para(tag,inf) +      end +      if defined? @md.classify.dewey \ +      and @md.classify.dewey=~/\S+/ +        tag,inf=tr.cls_dewey,@md.classify.dewey +        meta << meta_para(tag,inf) +      end +      if defined? @md.classify.oclc \ +      and @md.classify.oclc=~/\S+/ +        tag,inf=tr.cls_oclc,@md.classify.oclc +        meta << meta_para(tag,inf) +      end +      if defined? @md.classify.pg \ +      and @md.classify.pg=~/\S+/ +        tag,inf=tr.cls_gutenberg,@md.classify.pg +        meta << meta_para(tag,inf) +      end +      if defined? @md.classify.isbn \ +      and @md.classify.isbn=~/\S+/ +        tag,inf=tr.cls_isbn,@md.classify.isbn +        meta << meta_para(tag,inf) +      end +      if defined? @md.notes.comment \ +      and @md.notes.comment=~/\S+/ +        tag,inf=tr.comments,@md.notes.comment +        meta << meta_para(tag,inf) +      end +      if defined? @md.notes.prefix_a \ +      and @md.notes.prefix_a=~/\S+/ +        tag,inf=tr.prefix_a,@md.notes.prefix_a +        meta << meta_para(tag,inf) +      end +      if defined? @md.notes.prefix_b \ +      and @md.notes.prefix_b=~/\S+/ +        tag,inf=tr.prefix_b,@md.notes.prefix_b +        meta << meta_para(tag,inf) +      end +      if defined? @md.identifier.isbn \ +      and @md.identifier.isbn=~/\S+/ +        tag,inf=tr.cls_isbn,@md.identifier.isbn +        meta << meta_para(tag,inf) +      end +      if defined? @md.identifier.oclc \ +      and @md.identifier.oclc=~/\S+/ +        tag,inf=tr.cls_oclc,@md.identifier.oclc +        meta << meta_para(tag,inf) +      end +      if defined? @md.original.source \ +      and @md.original.source=~/\S+/ +        tag,inf=tr.source,@md.original.source +        meta << meta_para(tag,inf) +      end +      if defined? @md.title.language \ +      and @md.title.language=~/\S+/ +        tag,inf=tr.language,@md.title.language +        meta << meta_para(tag,inf) +      end +      if defined? @md.original.language \ +      and @md.original.language=~/\S+/ +        tag,inf=tr.language_original,@md.original.language +        meta << meta_para(tag,inf) +      end +      if defined? @md.classify.format \ +      and @md.classify.format=~/\S+/ +        tag,inf=tr.format,@md.classify.format +        meta << meta_para(tag,inf) +      end +      if defined? @md.classify.relation \ +      and @md.classify.relation=~/\S+/ +        tag,inf=tr.relation,@md.classify.relation +        meta << meta_para(tag,inf) +      end +      if defined? @md.classify.coverage \ +      and @md.classify.coverage=~/\S+/ +        tag,inf=tr.coverage,@md.classify.coverage +        meta << meta_para(tag,inf) +      end +      if defined? @md.classify.keywords \ +      and @md.classify.keywords=~/\S+/ +        tag,inf=tr.keywords,@md.classify.keywords +        meta << meta_para(tag,inf) +      end +      meta << %{#{@br}\\begin\{bfseries\}Version Information \\end\{bfseries\}} +      if defined? @md.fns \ +      and @md.fns=~/\S+/ +        fn=spec_char(@md.fns) +        fn=word_break_points(fn) +        fn="\\begin\{footnotesize\}#{fn}\\end\{footnotesize\}" +        tag,inf=tr.sourcefile,fn +        meta << meta_para(tag,inf,false) +      end +      if defined? @md.file_encoding \ +      and @md.file_encoding=~/\S+/ +        tag,inf='Filetype',@md.file_encoding +        meta << meta_para(tag,inf) +      end +      if defined? @md.dgst \ +      and @md.dgst.is_a?(Array) +        hash_of=spec_char(@md.dgst[0]) +        hash_of=word_break_points(hash_of) +        dgst=number_break_points(@md.dgst[1]) +        tag,inf='Source Digest',"\\begin\{footnotesize\}#{hash_of}\\end\{footnotesize\}\\-\\begin\{scriptsize\}#{dgst}\\end\{scriptsize\}" +        meta << meta_para(tag,inf,false) +      end +      meta << %{#{@br}\\begin\{bfseries\}Generated \\end\{bfseries\}} +      if defined? @md.generated \ +      and @md.generated.is_a?(Time) +        tag,inf=tr.last_generated,@md.generated +        meta << meta_para(tag,inf) +      end +      if defined? @md.project_details \ +      and @md.project_details.version=~/\S+/ +        tag=tr.sisu_version +        inf="#{@md.project_details.project} " + +          "#{@md.project_details.version} " + +          "of #{@md.project_details.date_stamp} " + +          "(#{@md.project_details.date})" +        meta << meta_para(tag,inf) +      end +      if defined? @md.ruby_version \ +      and @md.ruby_version=~/\S+/ +        tag,inf=tr.ruby_version,@md.ruby_version +        meta << meta_para(tag,inf) +      end +      meta +    end +  end +end +__END__ +if @md.title +  x=[ +    @md.title.main, +    @md.title.sub, +    @md.title.edition, +    @md.title.note, +    @md.title.short, +    @md.title.full, +    @md.title.language, +    @md.title.language_char +  ] +  x.each {|y| p y if y} +end +if @md.creator +  x=[ +    @md.creator.author, +    @md.creator.author_detail, +    @md.creator.contributor, +    @md.creator.contributor_detail, +    @md.creator.illustrator, +    @md.creator.illustrator_detail, +    @md.creator.photographer, +    @md.creator.photographer_detail, +    @md.creator.translator, +    @md.creator.translator_detail, +    @md.creator.audio, +    @md.creator.audio_detail, +    @md.creator.digitized_by, +    @md.creator.digitized_by_detail, +    @md.creator.prepared_by, +    @md.creator.prepared_by_detail +  ] +  x.each {|y| p y if y} +end +if @md.rights +  x=[ +    @md.rights.copyright.text, +    @md.rights.copyright.translation, +    @md.rights.copyright.illustrations, +    @md.rights.copyright.photographs, +    @md.rights.copyright.digitization, +    @md.rights.copyright.audio, +    @md.rights.license, +    @md.rights.all +  ] +  x.each {|y| p y if y} +end +if @md.classify +  x=[ +    @md.classify.coverage, +    @md.classify.relation, +    @md.classify.subject, +    @md.classify.topic_register, +    @md.classify.type, +    @md.classify.identifier, +    @md.classify.loc, +    @md.classify.dewey, +    @md.classify.oclc, +    @md.classify.pg, +    @md.classify.isbn, +  ] +  x.each {|y| p y if y} +end +if @md.date +  x=[ +    @md.date.added_to_site, +    @md.date.available, +    @md.date.created, +    @md.date.issued, +    @md.date.modified, +    @md.date.published, +    @md.date.valid +  ] +  x.each {|y| p y if y} +end +#if @md.language +#  p @md.language.document +#  p @md.language.document_char +#  p @md.language.original +#  p @md.language.original_char +#end +if @md.make +  x=[ +    @md.make.headings, +    @md.make.num_top, +    @md.make.breaks, +    @md.make.bold, +    @md.make.italics, +    @md.make.emphasis, +    @md.make.plaintext_wrap, +    @md.make.texpdf_font, +    @md.make.promo, +    @md.make.ad, +    @md.make.manpage +  ] +  x.each {|y| p y if y} +end +if @md.current_publisher # @md.publisher +  x=[ +    @md.current_publisher +  ] +  x.each {|y| p y if y} +end +if @md.original +  x=[ +    @md.original.publisher, +    @md.original.language, +    @md.original.language_char, +    @md.original.source, +    @md.original.institution, +    @md.original.nationality +  ] +  x.each {|y| p y if y} +end +if @md.notes +  x=[ +    @md.notes.abstract, +    @md.notes.comment, +    @md.notes.description, +    @md.notes.history, +    @md.notes.prefix +  ] +  x.each {|y| p y if y} +end +__END__ +#+END_SRC + +* constants +** constants.rb + +#+BEGIN_SRC ruby  :tangle "../lib/sisu/constants.rb" +# <<sisu_document_header>> +YEAR='2021' +Sfx={ +  txt:                       '.txt', +  txt_textile:               '.textile', +  txt_asciidoc:              '.ad', +  txt_markdown:              '.md', +  txt_rst:                   '.rst', +  txt_orgmode:               '.org', +  html:                      '.html', +  xhtml:                     '.xhtml', +  xml:                       '.xml', +  xml_sax:                   '.sax.xml', +  xml_dom:                   '.dom.xml', +  xml_scaffold:              '.scaffold.xml', +  xml_scaffold_structure_sisu:     '.scaffold.sisu.xml', +  xml_scaffold_structure_collapse: '.scaffold.collapse.xml', +  xml_docbook:               '.docbook.xml', +  xml_docbook_article:       '.article.docbook.xml', +  xml_docbook_book:          '.book.docbook.xml', +  xml_fictionbook:           '.fb2', +  epub:                      '.epub', +  epub_xhtml:                '.xhtml', +  odt:                       '.odt', +  json:                      '.json', +  pdf:                       '.pdf', +  manpage:                   '.1', +  info:                      '.info', +  texinfo:                   '.texinfo', +  sql:                       '.sql.db', +} +Ax={ +  tab:                       "\t", +  comment:                   '%', +  spaces:                    '  ', +} +Xx={ +  protect:                   '☞', +  split:                     '✠', +  segment:                   'Ф', +  relative_path:             '☼', +  html_relative2:            '※※', +  html_relative1:            '※', +} +Mx={ +  segname_prefix_auto_num_extract: 'c', +  segname_prefix_auto_num_provide: 's', +  segname_prefix_auto_num_other:   'x', +  ocn_id_char:               '',                                              #'o', now as before; remove for html5 +  note:                      'note_', +  note_ref:                  'noteref_', +  note_astx:                 'note_astx_', +  note_ref_astx:             'noteref_astx_', +  note_plus:                 'note_plus_', +  note_ref_plus:             'noteref_plus_', +  meta_o:                    '〔@',   meta_c: '〕', +  lv_o_0:                    0, +  lv_o_1:                    1, +  lv_o_2:                    2, +  lv_o_3:                    3, +  lv_o_4:                    4, +  lv_o_5:                    5, +  lv_o_6:                    6, +  lv_o_7:                    7, +  lv_o_8:                    8, +  lv_o_9:                    9, +  lv_o:                      '〔',         lv_c:                '〕', +  en_a_o:                    '【',         en_a_c:              '】',          #endnote Mx[:en_a_o]='~{'; Mx[:en_a_c]='}~' +  en_b_o:                    '〖',         en_b_c:              '〗',          #endnote Mx[:en_b_o]='~['; Mx[:en_b_c]=']~' +  bl_o:                      '〔',         bl_c:                '〕',          #block text mark +  gr_o:                      '〔',         gr_c:                '〕',          #group text mark #REPLACE & RETIRE +  id_o:                      '〔',         id_c:                '〕',          #object id mark +  tc_o:                      '『',         tc_c:                "』",          #table row mark #Mx[:tc_c]="』\n" +  tc_p:                      '┆',                                              #table col/misc mark +  pa_o:                      '〔',         pa_c:                '〕',          #affects paragraph mark +  mk_o:                      '〔',         mk_c:                '〕',          #generic mark +  gl_o:                      '〔',         gl_c:                '〕',          #glyph +  fa_o: '〔', fa_o_c: '¤', fa_c_o: '¤', fa_c: '〕', +  idx_o:                     '▩',         idx_c:               '▩', +  nbsp:                      '░',                                              #'▭ ' +  br_line:                   '╱',                                              #lB ▌  9612 ┘ ¶ +  br_nl:                     '╲',                                              #lB ▌ 』  ┘ +  br_paragraph:              '█',                                              #FB █  9608 # PP ∥  8741 #▐  #'┘' #'¶' #FB █  9608  lB ▌  9612   RB ▐  9616 +  br_obj:                    'break_obj', +  br_page_line:              '▭', +  br_page:                   '┼', +  br_page_new:               '╋', +  lnk_o:                     '⌠',          lnk_c:               '⌡',           #'⌈' '⌋' '⌠' '⌡' #Mx[:lnk_o: '◁'; Mx[:lnk_c: '▷' #‹ › +  url_o:                     '◘',          url_c:               '◙', +  rel_o:                     '⌈',          rel_c:               '⌋', +  tag_o:                     '⌊',          tag_c:               '⌉', +  sm_set_o:                  '◢',          sm_set_c:            '◣', +  sm_subset_o:               '◢',          sm_subset_c:         '◣', +  vline:                     '┆',                                              #  ¦ | +  src_bold_o:                '!{',    src_bold_c:               '}!', +  src_italics_o:             '/{',    src_italics_c:            '}/', +  src_underscore_o:          '_{',    src_underscore_c:         '}_', +  src_cite_o:                '"{',    src_cite_c:               '}"', +  src_insert_o:              '+{',    src_insert_c:             '}+', +  src_strike_o:              '-{',    src_strike_c:             '}-', +  src_superscript_o:         '^{',    src_superscript_c:        '}^', +  src_subscript_o:           ',{',    src_subscript_c:          '}', +  src_hilite_o:              '*{',    src_hilite_c:             '}*', +  src_monospace_o:           '#{',    src_monospace_c:          '}#', +  srcrgx_bold_o:             '\!\{',   srcrgx_bold_c:           '\}\!', +  srcrgx_italics_o:          '\/\{',   srcrgx_italics_c:        '\}\/', +  srcrgx_underscore_o:       '_\{',    srcrgx_underscore_c:     '\}_', +  srcrgx_cite_o:             '"\{',    srcrgx_cite_c:           '\}"', +  srcrgx_insert_o:           '\+\{',   srcrgx_insert_c:         '\}\+', +  srcrgx_strike_o:           '\-\{',   srcrgx_strike_c:         '\}\-', +  srcrgx_superscript_o:      '\^\{',   srcrgx_superscript_c:    '\}\^', +  srcrgx_subscript_o:        ',\{',    srcrgx_subscript_c:      '\},', +  srcrgx_hilite_o:           '\*\{',   srcrgx_hilite_c:         '\}\*', +  srcrgx_monospace_o:        '\#\{',   srcrgx_monospace_c:      '\}\#', +} +Mx[:fa_bold_o]=              "#{Mx[:fa_o]}b#{Mx[:fa_o_c]}" +Mx[:fa_bold_c]=              "#{Mx[:fa_c_o]}b#{Mx[:fa_c]}" +Mx[:fa_italics_o]=           "#{Mx[:fa_o]}i#{Mx[:fa_o_c]}" +Mx[:fa_italics_c]=           "#{Mx[:fa_c_o]}i#{Mx[:fa_c]}" +Mx[:fa_underscore_o]=        "#{Mx[:fa_o]}u#{Mx[:fa_o_c]}" +Mx[:fa_underscore_c]=        "#{Mx[:fa_c_o]}u#{Mx[:fa_c]}" +Mx[:fa_cite_o]=              "#{Mx[:fa_o]}cite#{Mx[:fa_o_c]}" +Mx[:fa_cite_c]=              "#{Mx[:fa_c_o]}cite#{Mx[:fa_c]}" +Mx[:fa_insert_o]=            "#{Mx[:fa_o]}ins#{Mx[:fa_o_c]}" +Mx[:fa_insert_c]=            "#{Mx[:fa_c_o]}ins#{Mx[:fa_c]}" +Mx[:fa_strike_o]=            "#{Mx[:fa_o]}del#{Mx[:fa_o_c]}" +Mx[:fa_strike_c]=            "#{Mx[:fa_c_o]}del#{Mx[:fa_c]}" +Mx[:fa_superscript_o]=       "#{Mx[:fa_o]}sup#{Mx[:fa_o_c]}" +Mx[:fa_superscript_c]=       "#{Mx[:fa_c_o]}sup#{Mx[:fa_c]}" +Mx[:fa_subscript_o]=         "#{Mx[:fa_o]}sub#{Mx[:fa_o_c]}" +Mx[:fa_subscript_c]=         "#{Mx[:fa_c_o]}sub#{Mx[:fa_c]}" +Mx[:fa_hilite_o]=            "#{Mx[:fa_o]}hi#{Mx[:fa_o_c]}" +Mx[:fa_hilite_c]=            "#{Mx[:fa_c_o]}hi#{Mx[:fa_c]}" +Mx[:fa_monospace_o]=         "#{Mx[:fa_o]}mono#{Mx[:fa_o_c]}" +Mx[:fa_monospace_c]=         "#{Mx[:fa_c_o]}mono#{Mx[:fa_c]}" +Mx[:gl_bullet]=              "#{Mx[:gl_o]}●#{Mx[:gl_c]}" +Mx[:br_endnotes]=            "#{Mx[:mk_o]}ENDNOTES#{Mx[:mk_c]}" +Mx[:br_eof]=                 "#{Mx[:mk_o]}EOF#{Mx[:mk_c]}" +Mx[:pa_non_object_dummy_heading]="#{Mx[:pa_o]}-##{Mx[:pa_c]}"                  #unnumbered paragraph, delete when not required [used in dummy headings, eg. for segmented html] (place marker at end of paragraph) +Mx[:pa_non_object_no_heading]="#{Mx[:pa_o]}~##{Mx[:pa_c]}"                     #unnumbered paragraph (place marker at end of paragraph) +Hx={ +  br_obj:                    { obj: Mx[:br_obj] },                             # line sep +  br_page_line:              { obj: Mx[:br_page_line] },                       # line across page +  br_page:                   { obj: Mx[:br_page] },                            # newpage +  br_page_new:               { obj: Mx[:br_page_new] },                        # clearpage +} +#Mx[:sm_set_o]='∈ '; Mx[:sm_set_c]='∋ ' +#Mx[:sm_subset_o]='∈ '; Mx[:sm_subset_c]='∋ ' +Rx={ +  mx_fa_clean:               /#{Mx[:fa_o]}.+?#{Mx[:fa_c]}|#{Mx[:pa_o]}.+?#{Mx[:pa_c]}|#{Mx[:mk_o]}.+?#{Mx[:mk_c]}/, +  lv:                        /〔([0-9]):(\S*?)〕/, +  lv_0:                      /#{Mx[:lv_o_0]}(\S*?)#{Mx[:lv_c]}/, +  lv_1:                      /#{Mx[:lv_o_1]}(\S*?)#{Mx[:lv_c]}/, +  lv_2:                      /#{Mx[:lv_o_2]}(\S*?)#{Mx[:lv_c]}/, +  lv_3:                      /#{Mx[:lv_o_3]}(\S*?)#{Mx[:lv_c]}/, +  lv_4:                      /#{Mx[:lv_o_4]}(\S*?)#{Mx[:lv_c]}/, +  lv_5:                      /#{Mx[:lv_o_5]}(\S*?)#{Mx[:lv_c]}/, +  lv_6:                      /#{Mx[:lv_o_6]}(\S*?)#{Mx[:lv_c]}/, +  lv_7:                      /#{Mx[:lv_o_7]}(\S*?)#{Mx[:lv_c]}/, +  lv_8:                      /#{Mx[:lv_o_8]}(\S*?)#{Mx[:lv_c]}/, +  lv_9:                      /#{Mx[:lv_o_9]}(\S*?)#{Mx[:lv_c]}/, +  meta:                      /#{Mx[:meta_o]}(\S+?)#{Mx[:meta_c]}/, +} +Dx={ +  ocn_o:                     '「',         ocn_c:                   '」', +  url_o:                     '‹',          url_c:                   '›', +  url_o_xml:                 '<',       url_c_xml:               '>', +  rel_o:                     '‹',          rel_c:                   '›', +  lt_xml:                    '<',       gt_xml:                  '>', +} +Tex={ +  backslash:                 "\\\\", +  backslash:                 "\\\\", +  tilde:                     '\\\\\\~', +} +Px={ +  bold_o:                    '*',          bold_c:                   '*', +  italics_o:                 '/',          italics_c:                '/', +  underscore_o:              '_',          underscore_c:             '_', + #emphasis_o:                '*',          emphasis_c:               '*', + #bold_o:                    '!',          bold_c:                   '!', +  cite_o:                    '"',          cite_c:                   '"', +  insert_o:                  '+',          insert_c:                 '+', +  strike_o:                  '-',          strike_c:                 '-', +  superscript_o:             '^',          superscript_c:            '^', +  subscript_o:               '[',          subscript_c:              ']', +  hilite_o:                  '*',          hilite_c:                 '*', +  monospace_o:               '',           monospace_c:              '', +  lng_lst:                   SiSU_is.language_list?, +  lng_lst_rgx:               SiSU_is.language_list_regex?, +  lv1:                       '*', +  lv2:                       '=', +  lv3:                       '=', +  lv4:                       '-', +  lv5:                       '.', +  lv6:                       '.', +} +Px[:lng_lst_rgx]=Px[:lng_lst].join('|') +Ep={ +  alt:                       :on, +  d_oebps:                   'OEBPS', +  d_image:                   'OEBPS/image', +  d_css:                     'OEBPS/css', +  f_ncx:                     'toc.ncx', +  f_opf:                     'content.opf', +} +$ep=if Ep[:alt]==:on +  { +    o:   'opf:', +    hsp: ' ', +  } +else +  { +    o:   '', +    hsp: ' ', +  } +end +Db={ +  name_prefix:               "SiSU.#{SiSU_is.version_major?}a.", +  name_prefix_db:            "sisu_#{SiSU_is.version_major?}a_", +  col_title:                  800, +  col_title_part:             400, +  col_title_edition:           10, +  col_name:                   600, +  col_creator_misc_short:     100, +  col_language:               100, +  col_language_char:            6, +  col_date_text:               10, +  col_txt_long:               600, +  col_txt_short:              200, +  col_identify_hash:          256, +  col_library:                 30, +  col_small:                   16, +  col_filename:               256, +  col_digest:                 128, +  col_filesize:                10, +  col_info_note:             2500, +} +Gt={ +  grotto:                    'sisu_src', +  git:                       'sisu:', +  src:                       'src', +  pods:                      'pods', +  sisupod:                   'sisupod', +  pod:                       'pod', +  files:                     'files', +  doc:                       'doc', +  po:                        'po4a/po', +  pot:                       'po4a/pot', +  image:                     'image', +  audio:                     'audio', +  video:                     'video', +  conf:                      'doc/_sisu', +} +S_CONF={ +  header_make: 'sisu_document_make', +  rc_yml: 'sisurc.yml', +} +ANSI_C={ +  red:                       "\033[#{31}m", +  green:                     "\033[#{32}m", +  yellow:                    "\033[#{33}m", +  blue:                      "\033[#{34}m", +  fuchsia:                   "\033[#{35}m", +  cyan:                      "\033[#{36}m", +  inv_red:                   "\033[#{41}m", +  inv_green:                 "\033[#{42}m", +  inv_yellow:                "\033[#{43}m", +  inv_blue:                  "\033[#{44}m", +  inv_fuchsia:               "\033[#{45}m", +  inv_cyan:                  "\033[#{46}m", +  b_red:                     "\033[#{91}m", +  b_green:                   "\033[#{92}m", +  b_yellow:                  "\033[#{93}m", +  b_blue:                    "\033[#{94}m", +  b_fuchsia:                 "\033[#{95}m", +  b_cyan:                    "\033[#{96}m", +  off:                       "\033[m" +} +DISABLE={ +  epub: { +    internal_navigation:     true, +    per_section_title:       true, +    ncx_navpoint_unique_id:  true, +  }, +} +DEVELOPER={ +  maintenance:               :false, +  under_construction:        '_CONSTRUCTION_ZONE', +} +__END__ +utils.rb +consider: +  〔comment〕 +  〔links?????〕 +   import document? +check: +  bold line + +┆┆⋮┇┊┋ +『』 +「」 +〔〕 +【】 + +· +¤ + #˝ " λ Ω  β α π Ѫ Ж Я Ѳ ѳ Ф ✠ ㈣ + Ѳ  ѳ   Ф + ♩ ♭   ✠   ▭  ▬  ▪ +【】〖〗◢ ◣ ◀ ▶ ◘ ◙ « ▲ » +《》「」 + ‹ › ∗  ∴ ∷ +'〔lv1〕','〔lv2〕','〔lv3〕','〔lv4〕','〔lv5〕','〔lv6〕','〔lv7〕','〔lv8〕','〔lv9〕' +'〔 Ѳ1〕','〔 Ѳ2〕','〔 Ѳ3〕','〔 Ѳ4〕','〔 Ѳ5〕','〔Ѳ6〕','〔Ѳ7〕','〔Ѳ8〕','〔Ѳ9〕' +◁▷ +◀this is text or an image▶ http:// +p __FILE__ +':'+ __LINE__.to_s +p __FILE__ + ' ' + __LINE__.to_s + ' ' + html +puts "#{__FILE__} #{__LINE__} #{o.inspect}" +puts __FILE__ + ' ' + __LINE__.to_s + '-->  ' + o.inspect +puts %{-\t#{__FILE__}::#{__LINE__}::#{caller}:\n"#{name}"} +p "\t" + txt.obj + " << #{__FILE__} #{__LINE__} >>" +p (__FILE__ + ' ' + __LINE__.to_s + '--> ' + dob.inspect) if dob.is==:heading +data.each {|o| p (__FILE__ + ' ' + __LINE__.to_s + '--> ' + o.inspect) if o.is==:heading} +puts "#{__FILE__} #{__LINE__} #{para}" if @opt.act[:maintenance][:set]==:on +puts "#{__FILE__} #{__LINE__} #{t_o}" if @opt.act[:maintenance][:set]==:on + dr ┌  9484   dR ┍  9485   Dr ┎  9486   DR ┏  9487   dl ┐  9488   dL ┑  9489   Dl ┒  9490   LD ┓  9491  ur └  9492   uR ┕  9493   Ur ┖  9494   UR ┗  9495   ul ┘  9496   uL ┙  9497   Ul ┚  9498   UL ┛  9499   vr ├ + dr ┌  9484   dR ┍  9485   Dr ┎  9486   DR ┏  9487   dl ┐  9488   dL ┑  9489   Dl ┒  9490   LD ┓  9491  ur └  9492   uR ┕  9493   Ur ┖  9494   UR ┗  9495   ul ┘  9496   uL ┙  9497   Ul ┚  9498   UL ┛  9499   vr ├ + └  ┘ +Iu ⌠  8992   Il ⌡ <7 ⌈  8968   >7 ⌉  8969   7< ⌊  8970   7> ⌋  8971 +<" 『 12302  >" 』 12303 +<' 「 12300  >' 」 12301 +#+END_SRC + +* generic +** generic_parts.rb + +#+BEGIN_SRC ruby  :tangle "../lib/sisu/generic_parts.rb" +# <<sisu_document_header>> +module SiSU_Parts_Generic +  def the_url +    def urify(uri) +      URI.parse(uri) +    end +    def sisu +      'http://www.sisudoc.org/' +    end +    def sisudoc +      'http://www.sisudoc.org' +    end +    def footer_signature +      'http://www.sisudoc.org/' +    end +    def rl_root +      '/sisu' #watch +    end +    def root_http +      'http://www.sisudoc.org/' #watch +    end +    def home +      'http://www.sisudoc.org/' # used in pdf header +    end +    def site #used as stub... where there are subdirectories and is different from home +      home +    end +    def home_txt +      'www.sisudoc.org' +    end +    def sisu_txt +      'www.sisudoc.org' +    end +    self +  end +  def the_text +    def home +      'SiSU' +    end +    def txt_hp +      ' SiSU' +    end +    def txt_hp_alias +      'SiSU' +    end +    def txt_home +      'SiSU' +    end +    def txt_signature # used in latex/pdf footer +      'SiSU' +    end +    def url_open +      '<' +    end +    def url_close +      '>' +    end +    self +  end +  def the_icon +    def i_ico +      'rb7.ico' +    end +    def i_home_button +      'sisu.png' +    end +    def i_choice +      'b_choice.png' +    end +    def i_new +      'b_new.png' +    end +    self +  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 +    shared + +  - 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 diff --git a/org/sisu.org b/org/sisu.org new file mode 100644 index 00000000..10b7f3e9 --- /dev/null +++ b/org/sisu.org @@ -0,0 +1,128 @@ +-*- mode: org -*- +#+TITLE:       sisu +#+DESCRIPTION: documents - structuring, various output representations & search +#+FILETAGS:    :sisu: +#+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 + +[[./sisu_info.org][sisu_info.org]]  [[./][org/]] +[[./sisu_build.org][make/build]] VERSION + +* version.txt (set version) :version: +** set program tangle + +#+BEGIN_SRC txt  :NO-tangle "../views/version.txt" +<<sisu_version_current_set>> +#+END_SRC + +* sisu.rb + +#+BEGIN_SRC ruby  :tangle "../lib/sisu.rb" +# <<sisu_document_header>> +module SiSU_libs +  require_relative 'sisu/hub'                               # sisu/hub.rb +  require_relative 'sisu/se'                                # sisu/se.rb +  require_relative 'sisu/utils'                             # sisu/utils.rb +  class CallHubMaster +    def initialize(argv,sisu_runtime) +      begin +        SiSU::HubMaster.new(argv,sisu_runtime) +      rescue +        SiSU_Screen::Ansi.new(argv).rescue do +          __LINE__.to_s + ':' + __FILE__ +        end +      ensure +        Dir.chdir(sisu_runtime[:call_path]) +      end +    end +  end +  class HubClose +    def initialize(argv,call_path) +      begin +        env=SiSU_Env::InfoEnv.new +      rescue +      ensure +        if FileTest.directory?(env.processing_path.processing) \ +        and FileTest.directory?(env.processing_path.processing_base_tmp) \ +        and env.processing_path.processing_base_tmp =~/#{env.processing_path.processing}/ \ +        and env.processing_path.processing_base_tmp =~/^\/tmp\/\S+/ \ +        and not argv.inspect =~/"--maintenance"|"-M"/ +          FileUtils::cd(env.processing_path.processing_base_tmp) do +            FileUtils::rm_rf('.') +          end +        end +        Dir.chdir(call_path) +      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 +    sisu + +  - 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 diff --git a/org/src.org b/org/src.org new file mode 100644 index 00000000..cb74f8bb --- /dev/null +++ b/org/src.org @@ -0,0 +1,3437 @@ +-*- mode: org -*- +#+TITLE:       sisu src +#+DESCRIPTION: documents - structuring, various output representations & search +#+FILETAGS:    :sisu:src: +#+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 + +* src_sisupod_make.rb + +#+BEGIN_SRC ruby  :tangle "../lib/sisu/src_sisupod_make.rb" +# <<sisu_document_header>> +module SiSU_Doc +  require_relative 'src_shared'                         # scr_shared.rb +    include SiSU_Source +  require_relative 'se'                                 # se.rb +    include SiSU_Env +  class Source < SiSU_Source::SiSUpodSource +    require_relative 'utils_response'                   # utils_response.rb +    def initialize(opt,build=nil,place=nil) +      super(opt,build,place) +      @zipfile=@opt.fno.gsub(/(?:\~\S{2,3})?(\.ss[tm])$/,'\1') +      unless @opt.act[:quiet][:set]==:on +        pthinfo="#{@file.output_path.sisupod.dir}/#{@zipfile}.txz" +        (@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], +            'Assemble source for sisu document', +            "#{@opt.fns} -> file://#{pthinfo}" +          ).cyan_hi_blue +        : SiSU_Screen::Ansi.new( +            @opt.act[:color_state][:set], +            'Assemble source for sisu document', +            pthinfo +          ).cyan_title_hi +      end +    end +    def sisupod_tar_xz +      begin +        FileUtils::mkdir_p(@file.output_path.sisupod.dir) \ +          unless FileTest.directory?(@file.output_path.sisupod.dir) +        tree=((@opt.act[:verbose][:set]==:on \ +        || @opt.act[:verbose_plus][:set]==:on \ +        || @opt.act[:maintenance][:set]==:on) \ +        && SiSU_Env::SystemCall.new.program_found?('tree')) \ +        ? 'tree sisupod' +        : '' +        if FileTest.directory?(@path_pod[:fnb]) +          Dir.chdir(@path_pod[:fnb]) +          system(%{ +            #{tree} +            tar -cJf #{@zipfile}.txz sisupod +            #echo "#{@file.place_file.sisupod.dir}" +          }) +          FileUtils::mv("#{@zipfile}.txz",@file.place_file.sisupod.dir) +          Dir.chdir(@env.path.pwd) +          if (@opt.act[:verbose][:set]==:on \ +          || @opt.act[:verbose_plus][:set]==:on \ +          || @opt.act[:maintenance][:set]==:on) +            SiSU_Screen::Ansi.new('',"#{@opt.fns}.txz").blue_tab +          end +        else +          if (@opt.act[:verbose][:set]==:on \ +          || @opt.act[:verbose_plus][:set]==:on \ +          || @opt.act[:maintenance][:set]==:on) +            SiSU_Screen::Ansi.new('',"#{@opt.fns}.txz not built").blue_tab +          end +        end +      rescue +      ensure +      end +    end +  end +end +__END__ +question?:                   should you permit the packing of multiple documents in single .xz ? + +  open @opt.fns, parse file +    extract from file content: +      images and copy each image from whatever image source to _sisu/sisupod/sisu/_sisu/image + +   remove previously existing contents of _/sisu/sisupod & +   make directory structure: + +v3 --> +   _sisu +     sisupod +       doc +         manifest.txt +         en/content.sst                [file content] +         fr/content.sst +         _sisu +           conf +           image (ln -s ../../image) +           audio (ln -s ../../audio) +           video (ln -s ../../video) +       image                           [all images for specific document gathered here] +       audio +       video + +v2 --> +   _sisu +     sisupod +       content.sst                     [file content] +       filename.sst                    [link to content.sst] +       _sisu/ +         image/                        [all images for specific document gathered here] + +sisu +  _sisu +    sisurc.yml +    convert/ +    standard_terms/ +    image +    processing +      ao/ +      tex/ +      texinfo/ +      tune/ +    sisupod + +special case + +composite file (master), e.g. +SiSU.ssm +#+END_SRC + +* src_sisupod_sstm.rb + +#+BEGIN_SRC ruby  :tangle "../lib/sisu/src_sisupod_sstm.rb" +# <<sisu_document_header>> +module SiSU_Markup +  require_relative 'src_shared'                         # src_shared.rb +    include SiSU_Source +  require_relative 'se'                                 # se.rb +    include SiSU_Env +  class Source_Sisupod < SiSU_Source::SiSUpodSource +    def initialize(opt,build=nil,place=nil) +      super(opt,build,place) +      @opt=opt +    end +    def read +      unless @opt.act[:quiet][:set]==:on +        (@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], +            'Share document markup text source', +            @opt.fns +          ).cyan_hi_blue +        : SiSU_Screen::Ansi.new( +            @opt.act[:color_state][:set], +            'Share document markup text source', +            @opt.fns +          ).cyan_title_hi +      end +      if FileTest.directory?(@path_pod[:fnb]) +        FileUtils::mkdir_p(@file.output_path.src.dir) \ +          unless FileTest.directory?(@file.output_path.src.dir) +        v=(@opt.act[:maintenance][:set]==:on) \ +        ? 'v' : '' +        system(%{ +          rsync -a#{v} #{@path_pod[:fnb]} #{@file.output_path.sisupod.dir} +          chbk=`pwd` +          cd #{@file.output_path.sisupod.dir} +          for I in `find -type d` ; do chmod 755 $I ; done +          for I in `find -type f` ; do chmod 644 $I ; done +          cd ${chbk} +        }) +      else +        if (@opt.act[:verbose][:set]==:on \ +        || @opt.act[:verbose_plus][:set]==:on \ +        || @opt.act[:maintenance][:set]==:on) +          SiSU_Screen::Ansi.new( +            '', +            "#{@opt.fno} not available" +          ).blue_tab +        end +      end +    end +  end +end +__END__ +#+END_SRC + +* src_kdissert_share.rb + +#+BEGIN_SRC ruby  :tangle "../lib/sisu/src_kdissert_share.rb" +# <<sisu_document_header>> +module SiSU_KdiSource +  require_relative 'se'                                 # se.rb +    include SiSU_Env +  class Source +    begin +      require 'fileutils' +        include FileUtils +    rescue LoadError +      SiSU_Utils::CodeMarker.new(__LINE__,__FILE__,:fuchsia). +        error('fileutils NOT FOUND (LoadError)') +    end +    def initialize(opt) +      @opt=opt +      @env=SiSU_Env::InfoEnv.new(@opt.fns) +      @output_path="#{@env.path.output}/#{@opt.fnb}" +    end +    def read +      SiSU_Screen::Ansi.new( +        @opt.act[:color_state][:set], +        'Share Kdissert Source Document!', +        @opt.fnb +      ).green_hi_blue unless @opt.act[:quiet][:set]==:on +      SiSU_Screen::Ansi.new( +        @opt.act[:color_state][:set], +        "Copy kdissert file to output directory", +        "#{@opt.fnb} -> #{@output_path}" +      ).warn unless @opt.act[:quiet][:set]==:on +      FileUtils::mkdir_p(@env.path.output) unless FileTest.directory?(@env.path.output) +      FileUtils::mkdir_p(@output_path) unless FileTest.directory?(@output_path) +      if FileTest.directory?(@output_path) +        if @opt.fns =~/\.kdi\._sst$/ \ +        and FileTest.file?(@opt.fnb) +          FileUtils::cp(@opt.fnb,@output_path) +        end +      else +        SiSU_Screen::Ansi.new( +          @opt.act[:color_state][:set], +          "Output directory does not exist", +          "#{@opt.fnb} -> #{@output_path}" +        ).warn unless @opt.act[:quiet][:set]==:on +        exit +      end +    end +  end +end +__END__ +#+END_SRC + +* src_po4a_share.rb + +#+BEGIN_SRC ruby  :tangle "../lib/sisu/src_po4a_share.rb" +# <<sisu_document_header>> +module SiSU_Languages_Selected +  require_relative 'utils_response'                   # utils_response.rb +  def language +    def sisu_languages_available +      Px[:lng_lst] +    end +    def source_language_selected_str +      @opt.act[:po4a_lang][:src] \ +      ? @opt.act[:po4a_lang][:src] +      : 'en' +    end +    def translation_languages_selected +      @opt.act[:po4a_lang][:trn] \ +      ? @opt.act[:po4a_lang][:trn] +      : [] +    end +    def translation_languages_available +      sisu_languages_available - [source_language_selected_str] +    end +    def translation_languages_selected_that_are_available +      translation_languages_selected & sisu_languages_available +    end +    def translation_languages_selected_that_are_available_str +      translation_languages_selected_that_are_available.join(' ') +    end +    def translation_languages_selected_str +      @opt.act[:po4a_lang][:trn].join(' ') +    end +    self +  end +end +module SiSU_Po4a_Project +  class Po4aCfg +    include SiSU_Composite_Doc_Utils                    # composite doc, .ssm, extract all related insert files, array of filenames test +    include SiSU_Response +    include SiSU_Languages_Selected +    def initialize(opt,file) +      @opt,@file=opt,file +    end +    def song +      if @opt.lng==language.source_language_selected_str +        ans=response?('po4a config file') +        if ans +          po4a_cfg +        end +      end +    end +    def po4a_cfg_filename +      'po4a.cfg' +    end +    def dir +      def pwd +        Dir.pwd +      end +      def po4a_ +        'po4a/' # '' +      end +      def pot +        #po4a_ + 'pot' +        'pot' +      end +      def po +        #po4a_ + 'po' +        'po' +      end +      self +    end +    def po4a_cfg_file +      File.open("#{Dir.pwd}/#{po4a_cfg_filename}",'w') +    end +    def po4a_cfg +      lng=language.source_language_selected_str +      doc_import_list=composite_and_imported_filenames_array(@opt.fno) +      po4a_cfg_arr=[] +      po4a_cfg_arr \ +        << "[po4a_langs] #{language.translation_languages_selected_that_are_available_str}" +      po4a_cfg_arr \ +        << "[po4a_paths] #{dir.pot}/$master.pot $lang:#{dir.po}/$lang/$master.po" +      doc_import_list.each do |file_src| +        file_src_fn= +          file_src.gsub(/#{language.source_language_selected_str}\//,'') +        po4a_cfg_arr \ +          << "[type: text] #{lng}/#{file_src} $lang:$lang/#{file_src_fn}" +      end +      file=@file.write_file.po4a_cfg +      po4a_cfg_arr.each do |txt| +      puts txt +        file << txt << "\n" +      end +      file.close +    end +  end +  class Po4aProject +    include SiSU_Languages_Selected +    include SiSU_Response +    def initialize(opt,file) +      @opt,@file=opt,file +    end +    def song +      make_paths +      if FileTest.directory?(@file.output_path.po4a.dir) +        Dir.chdir(@file.output_path.po4a.dir) +        dirs=Dir['*/'] +        dirs_language=[] +        dirs.each do |x| +          dirs_language << x.gsub(/\/$/,'') +        end +        dirs_translation = \ +          (language.translation_languages_available & dirs_language) +      end +      if (language.translation_languages_available & [@opt.lng]).length == 1 +        puts %{gettext for: #{dirs_translation} +in #{Dir.pwd}} +        ans=response?('gettext?') +        if ans +          gettext_if_any_build_src_trans_po +        end +      end +      ans=response?('build project?') +      if ans +        build_src_master_to_pot_and_po_and_srcs +      end +    end +    def flags +      def debug +        '-d -v' +      end +      def normal +        '' +      end +      def quiet +        '-q' +      end +      self +    end +    def build_src_master_to_pot_and_po_and_srcs +      if SiSU_Sys_Call::SystemCall.new.po4a +        pwd=Dir.pwd +        #cmd='po4a --keep 0 -M UTF-8 --no-backups ' \ +        #+ '--package-name ' \ +        #+ 'sisu-manual' + ' ' \ +        #+ flags.normal + ' ' \ +        #+ filename.po4a_cfg +        cmd='po4a --keep 0 -M UTF-8' \ +        + flags.normal + ' ' \ +        + @file.base_filename.po4a_cfg +        Dir.chdir(@file.output_path.po4a.dir) +        system(" +          cd #{@file.output_path.po4a.dir} +          #{cmd} +          cd - +        "); puts cmd +        Dir.chdir(pwd) +      end +    end +    def gettext_if_any_build_src_trans_po +        Dir.chdir(@file.output_path.po4a.dir) +        dirs=Dir['*/'] +        dirs_language=[] +        dirs.each do |x| +          dirs_language << x.gsub(/\/$/,'') +        end +        dirs_translation = \ +          (language.translation_languages_available & dirs_language) +        files_src=Dir.glob("./#{source_language_selected_str}/*.ss[tmi]") +        dirs_translation.each do |lng| +          files_src.each do |file| +            fn=file.gsub(/\.\/#{source_language_selected_str}\//,'') +            system(" +              po4a-gettextize -f text -M utf-8 \ +              -m ./#{source_language_selected_str}/#{fn} \ +              -l ./#{lng}/#{fn} \ +              -p ./po/#{lng}/#{fn}.po +            ") +            puts fn +          end +        end +    end +    def dir_mk(dir) +      unless FileTest.directory?(dir) +        FileUtils::mkdir_p(dir) +      end +    end +    def make_paths +      dir_mk(@file.output_path.pot.dir) +      dir_mk(@file.output_path.po.dir) +    end +    def clean +      #rm -f po/*/*.po~ +      #rm -rf ../build +      FileUtils.rm_f Dir.glob("./#{dir.po}/*/*.po~") +    end +    def distclean +      #rm -f po4a.cfg +      #rm -rf $(LANGUAGES) +      FileUtils::rm_f(filename.po4a_cfg) +      FileUtils::rm_r(language.possible_translations,:force => true) +      #FileUtils::rm_r(language.translation_languages_selected_that_are_available,:force => true) +    end +  end +  class Po4aDistClean +    include SiSU_Languages_Selected +    include SiSU_Response +    def initialize(opt,file) +      @opt,@file=opt,file +    end +    def song +      pwd=Dir.pwd +      if FileTest.directory?(@file.output_path.po4a.dir) +        Dir.chdir(@file.output_path.po4a.dir) +        dirs=Dir['*/'] +        dirs_language=[] +        dirs.each do |x| +          dirs_language << x.gsub(/\/$/,'') +        end +        dirs_translation = \ +          (language.translation_languages_available & dirs_language) +        if dirs_translation.length > 0 +          puts %{remove language translation directorie(s): #{dirs_translation} +in #{Dir  .pwd}} +          ans=response?('disclean?') +          if ans +            FileUtils::rm_f(@file.base_filename.po4a_cfg) +            FileUtils::rm_r(dirs_translation,:force => true) +            #FileUtils::rm_r(language.translation_languages_available,:force => true) +          end +        end +        Dir.chdir(pwd) +      end +    end +  end +end +#end +__END__ +REMOVE +!\|#\|&*\|-\|/\|_\|{\|}\|~\|&# + +tables are problematic, difficult to reconstitute instruction, check + +metadata, move to top? and work on + +footnotes, different types, asterisk, also do you want to have separate +paragraphs, or breaks within one block? + +where no ocn appropriately use ~# or -# or indeed 1~name- + +comments in document, what to do about them, not sure they are currently +retained in dal, could be quite valuable to keep + +Translate Shell +http://www.soimort.org/translate-shell/ +translate.google.com +#+END_SRC + +* src_po4a_shelf.rb + +#+BEGIN_SRC ruby  :tangle "../lib/sisu/src_po4a_shelf.rb" +# <<sisu_document_header>> +module SiSU_Po4a +  require_relative 'ao'                                 # ao.rb +  require_relative 'se'                                 # se.rb +    include SiSU_Env +  require_relative 'ao_composite'                       # ao_composite.rb +  require_relative 'shared_metadata'                    # shared_metadata.rb +  require_relative 'src_po4a_shelf_set'                 # src_po4a_shelf_set.rb +  include SiSU_Param +  require_relative 'object_munge'                       # object_munge.rb +  require_relative 'utils_composite'                    # utils_composite.rb +  class Source +    include SiSU_Object_Munge +    @@opt_src,@@opt_trn,@@opt_src_,@@opt_trn_,@@md_src,@@md_trn= +          nil,      nil,       nil,       nil,     nil,     nil +    @@auto_translation_ = :go +    def initialize(opt,fn=nil) +      @opt,@fn=opt,fn +      #unless @opt.fns =~/(.+?\.(?:-|ssm\.)?sst)$/ +      #  puts "#{@opt.fns} not a processed file type" +      #end +      file_arr=SiSU_Info_Env::InfoEnv.new.source_file_processing_array(@opt.fns) +      SiSU_Param::Parameters::Instructions.new(file_arr,@opt).extract +      r=Px[:lng_lst_rgx].gsub(/\|en\|/,'|') +      @lang_regx=%r{(?:#{r})} +      if opt.fns =~/\S+?~#{@lang_regx}\.ss[mti]/ \ +      and opt.f_pth[:lng]!=@opt.lng_base +        @@opt_src_=false +        @@opt_trn=opt +        @@md_trn=SiSU_Param::Parameters.new(opt).get +      else +        @@opt_src_=true +        @@opt_src=opt +        @@md_src=SiSU_Param::Parameters.new(opt).get +      end +    end +    def wrap_width_set(md,env) +      if defined? md.make.plaintext_wrap \ +      and md.make.plaintext_wrap +        md.make.plaintext_wrap +      elsif defined? env.plaintext_wrap \ +      and env.plaintext_wrap +        env.plaintext_wrap +      else 78 +      end +    end +    def process_file(md,env,file,wrap_width,fn) +      unless @opt.act[:quiet][:set]==:on +        tool=(@opt.act[:verbose][:set]==:on \ +        || @opt.act[:verbose_plus][:set]==:on \ +        || @opt.act[:maintenance][:set]==:on) \ +        ? "#{env.program.text_editor} #{file.output_path.pot.dir}/" +        : @opt.fns +        (@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], +            'Pot po4a', +            tool +          ).green_hi_blue +        : SiSU_Screen::Ansi.new( +            @opt.act[:color_state][:set], +            'Pot po4a', +            tool +          ).green_title_hi +        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], +            @opt.fns, +            file.output_path.pot.dir +          ).flow +        end +      end +      if @opt.fns =~/\S+?~#{@lang_regx}\.ss[mti]/ \ +      or @opt.f_pth[:lng] !=@opt.lng_base +        opt_lang_trn_fn=fn +        @ao_arr_lang_trans= +          SiSU_AO::Source.new(@opt,opt_lang_trn_fn,:po4a).get # ao file drawn here +        opt_lang_src_fn=(fn =~/\S+?~\S{2}(?:_\S{2})?\.ss[mti]/) \ +        ? (fn.gsub(/(\S+?)~\S{2}(?:_\S{2})?(\.ss[mti])/,'\1\2')) #check i +        : fn +        transdir,srcdir=Dir.pwd,Dir.pwd +        if Dir.pwd.to_s =~/\/#{@lang_regx}$/ +          transdir=Dir.pwd +          srcdir=transdir. +            gsub(/\/#{@lang_regx}$/, +              "/#{@opt.lng_base}") +          if FileTest.directory?(srcdir) +            Dir.chdir(srcdir) +          end +        else nil +        end +        if FileTest.file?("#{srcdir}/#{opt_lang_src_fn}") +          @ao_arr_lang_src= +            SiSU_AO::Source.new( +              @@opt_src, +              opt_lang_src_fn, +              :po4a +            ).get # ao file drawn here +        else +          puts "no identified source document" +          exit +        end +        Dir.chdir(transdir) if transdir +      else +        @ao_arr_lang_src= +          SiSU_AO::Source.new( +            @opt, +            fn, +            :po4a +          ).get # ao file drawn here +        @ao_arr_lang_trans=nil +      end +      SiSU_Po4a::Source::Scroll.new( +        fn, +        @ao_arr_lang_src, +        @ao_arr_lang_trans, +        @@md_src, +        @@md_trn, +        wrap_width +      ).songsheet +    end +    def read +      begin +        src={} +        src[:pth]=@opt.f_pth[:pth] +        src[:files]=if @opt.fns =~ /\.(?:(?:-|ssm\.)sst|ssm)$/ +          @opt.fns=@opt.fns.gsub(/\.ssm\.sst$/,'.ssm') +          SiSU_Assemble::CompositeFileList.new(@opt).read +        else +          [@opt.fns] +        end +        md=SiSU_Param::Parameters.new(@opt).get +        env=SiSU_Env::InfoEnv.new(@opt.fns) +        file=SiSU_Env::FileOp.new(md) +        Po4aCfg.new(@opt,file).po4a_cfg +        wrap_width=wrap_width_set(md,env) +        src[:files].each do |fn| +          process_file(md,env,file,wrap_width,fn) +        end +      rescue +        SiSU_Errors::Rescued.new($!,$@,@opt.selections.str,@opt.fns).location do +          __LINE__.to_s + ':' + __FILE__ +        end +      ensure +      end +    end +    private +    class Scroll <Source +      include SiSU_Po4aUtils +      @@endnotes={ para: [], end: [] } +      def initialize(fn,data_src,data_trn,md_src,md_trn,wrap_width) +        @fn,@data_src,@data_trn,@md_src,@md_trn,@wrap_width= +         fn, data_src, data_trn, md_src, md_trn, wrap_width +        @md=(md_trn.nil?) \ +        ? md_src +        : md_trn +        @tab="\t" +        @@endnotes_=(@md.opt.selections.str =~/--endnote/) \ +        ? true +        : false    # --footnote +        @pot={ +          body: [], +          open: [], +          close: [], +          head: [], +          metadata: [], +          tail: [] +        } +      end +      def br +        (@md.opt.selections.str =~/--dos/) ? "\r\n" : "\n"  # --unix +      end +      def songsheet +        fn=@fn +        pot=pot_markup(@data_src,@data_trn) +        publish(fn,pot) +      end +      def pot_structure_wrap(desc,orig,trans,indent=0,hang=0) +        SiSU_Po4aUtils::Wrap.new( +          @md, +          orig, +          trans, +          desc, +          @wrap_width, +          indent, +          hang +        ) +      end +      def wrap_endnotes(orig_notes='',trn_notes='') +        nt=@@endnotes_ ? 'endnote' : 'footnote' +        @fn=0 +        a_l=orig_notes.length +        0.upto(a_l-1) do |i| +          @fn=if orig_notes[i].to_s =~/^\^~([\d*+]+)/ # provides endnote number within paragraph +            @fn += 1 +          else @fn +          end +          d="#{nt} #{@fn}" +          mark="^~ " +          instruct=s_mark='' +          if @md.opt.act[:maintenance][:set]==:on +            instruct=%{\n# footnotes, the preferred sisu markup for a footnote is~{this is a footnote}~ } \ +            + %{however, for translation a footnote reference marker in the text~^ } \ +            + %{with a set of notes following the paragraph starting on a newline with "^~ this is a footnote", } \ +            + %{is easier to deal with, if possible these should be converted back to~{inline notes}~} +            s_mark="\n# " + %{"\\n\\n#{mark}...\\n\\n"} +          end +          desc="#{d}#{s_mark}#{instruct}" +          orig=(orig_notes[i].to_s =~/^\^~[\d*+]+/) \ +          ? (orig_notes[i].to_s.gsub(/^\^~[\d*+]+/,'^~')) +          : orig_notes[i].to_s +          trans=if trn_notes.is_a?(Array) \ +          and trn_notes.length==orig_notes.length +            (trn_notes[i].to_s =~/^\^~[\d*+]+/) \ +            ? (trn_notes[i].to_s.gsub(/^\^~[\d*+]+/,'^~')) +            : trn_notes[i].to_s +          else '' +          end +          util=pot_structure_wrap(desc,orig,trans) +          wrap=util.line_wrap +          wrap=if wrap =~ /^\s*\^~[\d*+]+\s+.+?\s*\Z/m +            wrap.gsub(/^\s*(\^~[\d*+]+)\s+(.+?)\s*\Z/m, <<GSUB +\\1 \\2 +GSUB +                      ) +          else +            wrap.gsub(/^(.+)\Z/m, <<GSUB +\\1 +GSUB +                      ) +          end +          @@endnotes[:para] << wrap +          @@endnotes[:end] << '' << wrap +        end +        @@endnotes[:para].each {|e| @pot[:body] << e << br} +        @@endnotes[:para]=[] +        @@endnotes +      end +      def pot_metadata_src +        @po4a_identify_type='type: SiSU doc' #'type: Plain text' +        meta_src=SiSU_Metadata::Summary.new(@md_src) +        w=[] +        w << [ +          "#. #{@po4a_identify_type} - metadata: title", +          "#: en/#{@md.fns}:#{SiSU_Po4aUtils::PotNumber.new.num}", +          'msgid ""', +          meta_src.metadata_tags.title.main, +          meta_src.metadata_tags.title.sub, +          meta_src.metadata_tags.title.edition, +          meta_src.metadata_tags.title.note, +          meta_src.metadata_tags.title.short, +          meta_src.metadata_tags.title.language, +          meta_src.metadata_tags.title.language_char, +          'msgstr ""', +        ] +        w << [ +          "#. #{@po4a_identify_type} - metadata: creator", +          "#: en/#{@md.fns}:#{SiSU_Po4aUtils::PotNumber.new.num}", +          'msgid ""', +          meta_src.metadata_tags.creator.head, +          meta_src.metadata_tags.creator.author, +          meta_src.metadata_tags.creator.contributor, +          meta_src.metadata_tags.creator.illustrator, +          meta_src.metadata_tags.creator.photographer, +          meta_src.metadata_tags.creator.translator, +          meta_src.metadata_tags.creator.audio, +          meta_src.metadata_tags.creator.digitized_by, +          meta_src.metadata_tags.creator.prepared_by, +          'msgstr ""', +        ] +        w << [ +          "#. #{@po4a_identify_type} - metadata: rights", +          "#: en/#{@md.fns}:#{SiSU_Po4aUtils::PotNumber.new.num}", +          'msgid ""', +          meta_src.metadata_tags.rights.head, +          meta_src.metadata_tags.rights.copyright.text, +          meta_src.metadata_tags.rights.copyright.translation, +          meta_src.metadata_tags.rights.copyright.illustrations, +          meta_src.metadata_tags.rights.copyright.photographs, +          meta_src.metadata_tags.rights.copyright.digitization, +          meta_src.metadata_tags.rights.copyright.audio, +          meta_src.metadata_tags.rights.license, +          'msgstr ""', +        ] +        w << [ +          "#. #{@po4a_identify_type} - metadata: classify", +          "#: en/#{@md.fns}:#{SiSU_Po4aUtils::PotNumber.new.num}", +          'msgid ""', +          meta_src.metadata_tags.classify.head, +          meta_src.metadata_tags.classify.subject, +          meta_src.metadata_tags.classify.topic_register, +          meta_src.metadata_tags.classify.loc, +          meta_src.metadata_tags.classify.dewey, +          #meta_src.metadata_tags.notes.relation, +          #meta_src.metadata_tags.notes.type, +          #meta_src.metadata_tags.identifier.oclc, +          #meta_src.metadata_tags.identifier.isbn, +          'msgstr ""', +        ] +        w << [ +          "#. #{@po4a_identify_type} - metadata: date", +          "#: en/#{@md.fns}:#{SiSU_Po4aUtils::PotNumber.new.num}", +          'msgid ""', +          meta_src.metadata_tags.date.head, +          meta_src.metadata_tags.date.added_to_site, +          meta_src.metadata_tags.date.available, +          meta_src.metadata_tags.date.created, +          meta_src.metadata_tags.date.issued, +          meta_src.metadata_tags.date.modified, +          meta_src.metadata_tags.date.published, +          meta_src.metadata_tags.date.valid, +          'msgstr ""', +        ] +        w << [ +          "#. #{@po4a_identify_type} - processing, make instruction", +          "#: en/#{@md.fns}:#{SiSU_Po4aUtils::PotNumber.new.num}", +          'msgid ""', +          meta_src.processing_tags.make.language, +          meta_src.processing_tags.make.headings, +          meta_src.processing_tags.make.num_top, +          meta_src.processing_tags.make.breaks, +          meta_src.processing_tags.make.emphasis, +          meta_src.processing_tags.make.bold, +          meta_src.processing_tags.make.italics, +          meta_src.processing_tags.make.texpdf_font, +          'msgstr ""', +        ] +        w.each do |y| +          z='' +          y.each do |x| +            if x +              z += x + "\n" if x =~/^#|^msg(?:id|str)/ +              z += %{"#{x}"\n} if x =~/^@\S+?:(?: |$)/ +              z += %{"#{x}"\n} if x =~/^\s+:\S+?: / +            end +          end +          @pot[:metadata] << z << br +          #puts z unless z.empty? +        end +      end +      def pot_metadata_src_trn +        @po4a_identify_type='type: SiSU doc' +        #@po4a_identify_type='type: Plain text' +        meta_src=SiSU_Metadata::Summary.new(@md_src) +        meta_trn=SiSU_Metadata::Summary.new(@md_trn) +        w=[] +        w << [ +          "#. #{@po4a_identify_type} - metadata: title", +          "#: en/#{@md.fns}:#{SiSU_Po4aUtils::PotNumber.new.num}", +          'msgid ""', +          meta_src.metadata_tags.title.main, +          meta_src.metadata_tags.title.sub, +          meta_src.metadata_tags.title.edition, +          meta_src.metadata_tags.title.note, +          meta_src.metadata_tags.title.short, +          meta_src.metadata_tags.title.language, +          meta_src.metadata_tags.title.language_char, +          'msgstr ""', +          meta_trn.metadata_tags.title.main, +          meta_trn.metadata_tags.title.sub, +          meta_trn.metadata_tags.title.edition, +          meta_trn.metadata_tags.title.note, +          meta_trn.metadata_tags.title.short, +          meta_trn.metadata_tags.title.language, +          meta_trn.metadata_tags.title.language_char, +        ] +        w << [ +          "#. #{@po4a_identify_type} - metadata: creator", +          "#: en/#{@md.fns}:#{SiSU_Po4aUtils::PotNumber.new.num}", +          'msgid ""', +          meta_src.metadata_tags.creator.head, +          meta_src.metadata_tags.creator.author, +          meta_src.metadata_tags.creator.contributor, +          meta_src.metadata_tags.creator.illustrator, +          meta_src.metadata_tags.creator.photographer, +          meta_src.metadata_tags.creator.translator, +          meta_src.metadata_tags.creator.audio, +          meta_src.metadata_tags.creator.digitized_by, +          meta_src.metadata_tags.creator.prepared_by, +          'msgstr ""', +          meta_trn.metadata_tags.creator.head, +          meta_trn.metadata_tags.creator.author, +          meta_trn.metadata_tags.creator.contributor, +          meta_trn.metadata_tags.creator.illustrator, +          meta_trn.metadata_tags.creator.photographer, +          meta_trn.metadata_tags.creator.translator, +          meta_trn.metadata_tags.creator.audio, +          meta_trn.metadata_tags.creator.digitized_by, +          meta_trn.metadata_tags.creator.prepared_by, +        ] +        w << [ +          "#. #{@po4a_identify_type} - metadata: rights", +          "#: en/#{@md.fns}:#{SiSU_Po4aUtils::PotNumber.new.num}", +          'msgid ""', +          meta_src.metadata_tags.rights.head, +          meta_src.metadata_tags.rights.copyright.text, +          meta_src.metadata_tags.rights.copyright.translation, +          meta_src.metadata_tags.rights.copyright.illustrations, +          meta_src.metadata_tags.rights.copyright.photographs, +          meta_src.metadata_tags.rights.copyright.digitization, +          meta_src.metadata_tags.rights.copyright.audio, +          meta_src.metadata_tags.rights.license, +          'msgstr ""', +          meta_trn.metadata_tags.rights.head, +          meta_trn.metadata_tags.rights.copyright.text, +          meta_trn.metadata_tags.rights.copyright.translation, +          meta_trn.metadata_tags.rights.copyright.illustrations, +          meta_trn.metadata_tags.rights.copyright.photographs, +          meta_trn.metadata_tags.rights.copyright.digitization, +          meta_trn.metadata_tags.rights.copyright.audio, +          meta_trn.metadata_tags.rights.license, +        ] +        w << [ +          "#. #{@po4a_identify_type} - metadata: classify", +          "#: en/#{@md.fns}:#{SiSU_Po4aUtils::PotNumber.new.num}", +          'msgid ""', +          meta_src.metadata_tags.classify.head, +          meta_src.metadata_tags.classify.subject, +          meta_src.metadata_tags.classify.topic_register, +          meta_src.metadata_tags.classify.loc, +          meta_src.metadata_tags.classify.dewey, +          #meta_src.metadata_tags.notes.relation, +          #meta_src.metadata_tags.notes.type, +          #meta_src.metadata_tags.identifier.oclc, +          #meta_src.metadata_tags.identifier.isbn, +          'msgstr ""', +          meta_trn.metadata_tags.classify.head, +          meta_trn.metadata_tags.classify.subject, +          meta_trn.metadata_tags.classify.topic_register, +          meta_trn.metadata_tags.classify.loc, +          meta_trn.metadata_tags.classify.dewey, +          #meta_trn.metadata_tags.notes.relation, +          #meta_trn.metadata_tags.notes.type, +          #meta_trn.metadata_tags.identifier.oclc, +          #meta_trn.metadata_tags.identifier.isbn, +        ] +        w << [ +          "#. #{@po4a_identify_type} - metadata: date", +          "#: en/#{@md.fns}:#{SiSU_Po4aUtils::PotNumber.new.num}", +          'msgid ""', +          meta_src.metadata_tags.date.head, +          meta_src.metadata_tags.date.added_to_site, +          meta_src.metadata_tags.date.available, +          meta_src.metadata_tags.date.created, +          meta_src.metadata_tags.date.issued, +          meta_src.metadata_tags.date.modified, +          meta_src.metadata_tags.date.published, +          meta_src.metadata_tags.date.valid, +          'msgstr ""', +          meta_trn.metadata_tags.date.head, +          meta_trn.metadata_tags.date.added_to_site, +          meta_trn.metadata_tags.date.available, +          meta_trn.metadata_tags.date.created, +          meta_trn.metadata_tags.date.issued, +          meta_trn.metadata_tags.date.modified, +          meta_trn.metadata_tags.date.published, +          meta_trn.metadata_tags.date.valid, +        ] +        w << [ +          "#. #{@po4a_identify_type} - processing, make instruction", +          "#: en/#{@md.fns}:#{SiSU_Po4aUtils::PotNumber.new.num}", +          'msgid ""', +          meta_src.processing_tags.make.language, +          meta_src.processing_tags.make.headings, +          meta_src.processing_tags.make.num_top, +          meta_src.processing_tags.make.breaks, +          meta_src.processing_tags.make.emphasis, +          meta_src.processing_tags.make.bold, +          meta_src.processing_tags.make.italics, +          meta_src.processing_tags.make.texpdf_font, +          'msgstr ""', +          meta_trn.processing_tags.make.language, +          meta_trn.processing_tags.make.headings, +          meta_trn.processing_tags.make.num_top, +          meta_trn.processing_tags.make.breaks, +          meta_trn.processing_tags.make.emphasis, +          meta_trn.processing_tags.make.bold, +          meta_trn.processing_tags.make.italics, +          meta_trn.processing_tags.make.texpdf_font, +        ] +        w.each do |y| +          z='' +          y.each do |x| +            if x +              z += x + "\n" if x =~/^#|^msg(?:id|str)/ +              z += %{"#{x}"\n} if x =~/^@\S+?:(?: |$)/ +              z += %{"#{x}"\n} if x =~/^\s+:\S+?: / +            end +          end +          @pot[:metadata] << z << br +          #puts z unless z.empty? +        end +      end +      def auto_translate?(set_to=nil) +        @@auto_translation_= +        if @md.opt.act[:po4a_lang_trans][:set]==:on +          set_to \ +          ? set_to +          : @@auto_translation_ +        else :skip +        end +      end +      def auto_translation(src_txt,markup=:src) # check for an appropriate request flag +        auto_translate?(:skip) +        begin +          src_txt_clean=clean_text(src_txt,markup) +          src_txt_clean=src_txt_clean. +            gsub(/\n/,' '). +            gsub(/"/,'\"'). +            gsub(/([()])/,'\\\\\1') +          trans='' +          unless auto_translate? == :skip +            require 'timeout' +            Timeout::timeout(60) { +              trans=`trans -b -no-ansi en:#{@md.opt.f_pth[:lng_is]} #{src_txt_clean}`.strip +              unless trans.empty? +                trans + ' {[G.Tr]}http://translate.google.com' +              end +            } +          end +          trans +        rescue +          auto_translate?(:skip) +          p 'timeout issues with translation, skip remaining' +        end +      end +      def pot_structure +        def heading(dob_src='',notes_s='',dob_trn='',notes_t='')   #% used to extract the structure of a document +          lv=n=n3=nil +          lv=dob_src.ln +          n=lv - 1 +          n3=lv + 2 +          util=nil +          fn=(dob_src.name=~/[a-z\d]/i) ? dob_src.name : '' +          mark="#{dob_src.lv}~#{fn} " +          d="#{dob_src.is.to_s} (level #{dob_src.lv})" +          instruct=s_mark='' +          if @md.opt.act[:maintenance][:set]==:on +            instruct=%{\n# markup for headings is marker at the start of the line/object, } \ +            + %{indicating the heading level, and if provided an associated name tag, } \ +            + %{this heading is "#{mark}"} +            s_mark="\n# " + %{"\\n\\n#{mark}...\\n\\n"} +          end +          desc="#{d}#{s_mark}#{instruct}" +          orig="#{s_mark}#{dob_src.obj}" +          trans=((dob_trn=='') \ +          || (dob_src.obj == dob_trn.obj)) \ +          ? '' +          : "#{s_mark}#{dob_trn.obj}" +          if @md.opt.f_pth[:lng_is] !=@md.opt.lng_base \ +          and trans.empty? \ +          and auto_translate? +            trans=auto_translation(dob_src.obj,:src) +          end +          util=pot_structure_wrap(desc,orig,trans) +          wrapped=util.line_wrap +          @pot[:body] << wrapped << br # main text, contents, body KEEP +          if @@endnotes[:para] \ +          and notes_s.length > 0 \ +          and not @@endnotes_ +            @pot[:body] << br +            wrap_endnotes(notes_s,notes_t) +          elsif @@endnotes[:para] \ +          and @@endnotes_ +            @pot[:body] << br*2 +          end +        end +        def para(dob_src='',notes_s='',dob_trn='',notes_t='')      #% used to extract the structure of a document +          util=nil +          wrapped=if dob_src.indent =~/[1-9]/ \ +          and dob_src.indent == dob_src.hang +            s_mark=desc=orig=trans='' +            if dob_src.bullet_ +              mark="_#{dob_src.indent}* " +              d="#{dob_src.is.to_s}: indent #{dob_src.indent}, bullet" +              instruct=s_mark='' +              if @md.opt.act[:maintenance][:set]==:on +                instruct=%{\n# markup for indented bullet text is at the start of the line/object, } \ +                + %{an underscore followed by the indent level and an asterisk "#{mark}"} +                s_mark="\n# " + %{"\\n\\n#{mark}...\\n\\n"} +              end +              desc="#{d}#{s_mark}#{instruct}" +            else +              mark="_#{dob_src.indent} " +              d="#{dob_src.is.to_s}: indent #{dob_src.indent}" +              instruct=s_mark='' +              if @md.opt.act[:maintenance][:set]==:on +                instruct=%{\n# markup for indented text is at the start of the line/object, } \ +                + %{an underscore followed by the indent level "#{mark}"} +                s_mark="\n# " + %{"\\n\\n#{mark}...\\n\\n"} +              end +              desc="#{d}#{s_mark}#{instruct}" +            end +            orig="#{s_mark}#{dob_src.obj}" +            trans=((dob_trn=='') \ +            || (dob_src.obj == dob_trn.obj)) \ +            ? '' +            : "#{s_mark}#{dob_trn.obj}" +            if @md.opt.f_pth[:lng_is] !=@md.opt.lng_base \ +            and trans.empty? \ +            and auto_translate? +              trans=auto_translation(dob_src.obj,:src) +            end +            util=pot_structure_wrap(desc,orig,trans) +          elsif dob_src.hang =~/[0-9]/ \ +          and dob_src.indent != dob_src.hang +            s_mark=desc=orig=trans='' +            mark="_#{dob_src.hang}_#{dob_src.indent} " +            d="#{dob_src.is.to_s}: hang #{dob_src.hang} indent #{dob_src.indent}" +            instruct=s_mark='' +            if @md.opt.act[:maintenance][:set]==:on +              instruct=%{\n# markup for indented text with a first line indented } \ +              + %{to a different level from the rest of the paragraph, } \ +              + %{is at the start of the line/object, } \ +              + %{an underscore and the first indent level } \ +              + %{a second underscore and the indent level for the rest of the paragraph, "#{mark1}"} +              s_mark="\n# " + %{"\\n\\n#{mark}...\\n\\n"} +            end +            desc="#{d}#{s_mark}#{instruct}" +            orig="#{s_mark}#{dob_src.obj}" +            trans=((dob_trn=='') \ +            || (dob_src.obj == dob_trn.obj)) \ +            ? '' +            : "#{s_mark}#{dob_trn.obj}" +            if @md.opt.f_pth[:lng_is] !=@md.opt.lng_base \ +            and trans.empty? \ +            and auto_translate? +              trans=auto_translation(dob_src.obj,:src) +            end +            util=pot_structure_wrap(desc,orig,trans) +          else +            s_mark=desc=orig=trans='' +            if dob_src.bullet_ +              mark='_* ' +              d="#{dob_src.is.to_s}: bullet" +              instruct=s_mark='' +              if @md.opt.act[:maintenance][:set]==:on +                instruct=%{\n# markup for indented text is at the start of the line/object, } \ +                + %{an underscore followed by an asterisk "#{mark}"} +                s_mark="\n# " + %{"\\n\\n#{mark}...\\n\\n"} +              end +              desc="#{d}#{s_mark}#{instruct}" +              orig="#{s_mark}#{dob_src.obj}" +              trans=((dob_trn=='') \ +              || (dob_src.obj == dob_trn.obj)) \ +              ? '' +              : "#{s_mark}#{dob_trn.obj}" +              if @md.opt.f_pth[:lng_is] !=@md.opt.lng_base \ +              and trans.empty? \ +              and auto_translate? +                trans=auto_translation(dob_src.obj,:src) +              end +            else +              mark='' +              d=dob_src.is.to_s +              instruct=%{\n# regular paragraph, no special markup} +              if @md.opt.act[:maintenance][:set]==:on +                instruct="\n# " +                s_mark="\n# " + %{"\\n\\n#{mark}...\\n\\n"} +              end +              desc="#{d}#{s_mark}#{instruct}" +              orig=dob_src.obj +              trans=((dob_trn=='') \ +              || (dob_src.obj == dob_trn.obj)) \ +              ? '' +              : "#{s_mark}#{dob_trn.obj}" +              if @md.opt.f_pth[:lng_is] !=@md.opt.lng_base \ +              and trans.empty? \ +              and auto_translate? +                trans=auto_translation(dob_src.obj,:src) +              end +            end +            util=pot_structure_wrap(desc,orig,trans) +          end +          wrapped=util.line_wrap +          @pot[:body] << wrapped << br # main text, contents, body KEEP +          if @@endnotes[:para] \ +          and notes_s.length > 0 \ +          and not @@endnotes_ +            @pot[:body] << br +            wrap_endnotes(notes_s,notes_t) +          elsif @@endnotes[:para] \ +          and @@endnotes_ +            @pot[:body] << br*2 +          end +        end +        def block(dob_src='',notes_s='',dob_trn='',notes_t='')     #% used to extract the structure of a document +          mark="block{\\n\\n...\\n\\n}block" +          d=dob_src.is.to_s +          instruct=s_mark='' +          if @md.opt.act[:maintenance][:set]==:on +            instruct=%{\n# block text is a text block with an opening and closing marker, } \ +            + %{the content of which may be wrapped} +            s_mark="\n# " + %{"\\n\\n#{mark}\\n\\n"} +          end +          desc="#{d}#{s_mark}#{instruct}" +          orig=dob_src.obj +          trans=((dob_trn=='') \ +          || (dob_src.obj == dob_trn.obj)) \ +          ? '' +          : "#{s_mark}#{dob_trn.obj}" +          if @md.opt.f_pth[:lng_is] !=@md.opt.lng_base \ +          and trans.empty? \ +          and auto_translate? +            trans=auto_translation(dob_src.obj,:src) +          end +          util=pot_structure_wrap(desc,orig,trans) +          unwrapped=util.no_line_wrap_block +          @pot[:body] << unwrapped << br +        end +        def group(dob_src='',notes_s='',dob_trn='',notes_t='')     #% used to extract the structure of a document +          mark="group{\\n\\n...\\n\\n}group" +          d=dob_src.is.to_s +          instruct=s_mark='' +          if @md.opt.act[:maintenance][:set]==:on +            instruct=%{\n# group text is a text block with an opening and closing marker, } \ +            + %{the content of which may be wrapped} +            s_mark="\n# " + %{"\\n\\n#{mark}\\n\\n"} +          end +          desc="#{d}#{s_mark}#{instruct}" +          orig=dob_src.obj +          trans=((dob_trn=='') \ +          || (dob_src.obj == dob_trn.obj)) \ +          ? '' +          : "#{s_mark}#{dob_trn.obj}" +          if @md.opt.f_pth[:lng_is] !=@md.opt.lng_base \ +          and trans.empty? \ +          and auto_translate? +            trans=auto_translation(dob_src.obj,:src) +          end +          util=pot_structure_wrap(desc,orig,trans) +          unwrapped=util.no_line_wrap_block +          @pot[:body] << unwrapped << br +        end +        def verse(dob_src='',notes_s='',dob_trn='',notes_t='')     #% used to extract the structure of a document +          mark="poem{\n\nverse\n\nverse\n\n...\n\n}poem" +          d=dob_src.is.to_s +          instruct=s_mark='' +          if @md.opt.act[:maintenance][:set]==:on +            instruct=%{\n# verse are part of the text block described as a poem, } \ +            + %{the first verse is preceeded by an opening marker, } \ +            + %{and the last verse by a closing marker, } \ +            + %{the content of which should remain unwrapped} +            s_mark="\n# " + %{"\\n\\n#{mark}\\n\\n"} +          end +          desc="#{d}#{s_mark}#{instruct}" +          orig=dob_src.obj +          trans=(dob_trn=='') ? '' : dob_trn.obj +          util=pot_structure_wrap(desc,orig,trans) +          unwrapped=util.no_line_wrap_block +          @pot[:body] << unwrapped << br +        end +        def code(dob_src='',notes_s='',dob_trn='',notes_t='')      #% used to extract the structure of a document +          mark="code{\\n\\n...\\n\\n}code" +          d=dob_src.is.to_s +          instruct=s_mark='' +          if @md.opt.act[:maintenance][:set]==:on +            instruct=%{\n# codeblocks are a text block with an opening and closing marker, } \ +            + %{the content of which should remain unwrapped} +            s_mark="\n# " + %{"\\n\\n#{mark}\\n\\n"} +          end +          desc="#{d}#{s_mark}#{instruct}" +          orig=dob_src.obj +          trans=(dob_trn=='') ? '' : dob_trn.obj +          util=pot_structure_wrap(desc,orig,trans) +          unwrapped=util.no_line_wrap_block +          @pot[:body] << unwrapped << br +        end +        def table(dob_src='',notes_s='',dob_trn='',notes_t='')     #% used to extract the structure of a document +          mark="table{\\n\\n...\\n\\n}table" +          d=dob_src.is.to_s +          instruct=s_mark='' +          if @md.opt.act[:maintenance][:set]==:on +            instruct=%{\n# tables are a text block with an opening and closing marker, } \ +            + %{the content of which should remain unwrapped} +            s_mark="\n# " + %{"\\n\\n#{mark}\\n\\n"} +          end +          desc="#{d}#{s_mark}#{instruct}" +          orig=dob_src.obj +          orig=orig.gsub(/#{Mx[:tc_c]}/,"\n") +          trans=(dob_trn=='') ? '' : dob_trn.obj +          trans=trans.gsub(/#{Mx[:tc_c]}/,"\n") +          util=pot_structure_wrap(desc,orig,trans) +          unwrapped=util.no_line_wrap_block +          @pot[:body] << unwrapped << br +        end +        def idx_markup(idx) +          struct=['={'] +          idx.sort.each do |x| +            x.each_with_index do |y,i0| +              case y +              when String +                struct << ';' unless struct[-1] =~/=\{/ +                struct << y +                if x[i0+1].class == Hash \ +                and x[i0+1][:sub].length > 0 +                  struct << ':' +                end +              when Hash +                if y[:plus].to_i > 0 +                  struct << '+' + y[:plus].to_s +                end +                if y[:sub].length > 0 +                  y[:sub].each_with_index do |z,i1| +                    z.each_with_index do |a,i2| +                      #p a +                      if z.length > 0 +                        struct << a[0] +                        if a[1][:plus].to_i > 0 +                          struct << '+' + a[1][:plus].to_s +                        end +                        if (i1 + 1) < y[:sub].length +                          struct << '|' +                        end +                      end +                    end +                  end +                end +              end +            end +          end +          struct << '}' +          #puts struct.join +          struct.join +        end +        def idx(dob_src='',dob_trn='')                             #% used for book index but broken as original markup lost, already abstracted, fix +          mark="={ ... }" +          instruct=s_mark='' +          if @md.opt.act[:maintenance][:set]==:on +            instruct=%{\n# the book index should be attached unwrapped to the preceding text block } \ +            + %{(there should be a new line, but no empty line)} +            s_mark="\n# " + %{"\\n#{mark}\\n\\n"} +          end +          d='book-idx' +          desc="#{d}#{s_mark}#{instruct}" +          orig=pot_structure.idx_markup(dob_src.idx) #'={' + dob_src.idx + '}' +          trans=if defined? dob_trn.idx \ +          and not dob_trn.idx.nil? \ +          and not dob_trn.idx.empty? +            pot_structure.idx_markup(dob_trn.idx) #'={' + dob_trn.idx + '}' +          else '' +          end +          util=pot_structure_wrap(desc,orig,trans) +          unwrapped=util.no_line_wrap_block +          @pot[:body] << unwrapped << br +        end +        self +      end +      def pot_markup(data_src,data_trn) +        #@endnotes,@copen,@pot_contents_close=Array.new(3){[]} +        a_l=if data_trn +        a_l=(data_src.length >= data_trn.length) \ +        ? data_src.length +        : data_trn.length +        else +          data_src.length +        end +        s,t=0,0 +        if @md.fns =~ /\.(?:(?:-|ssm\.)?sst|ssm)$/ +          (data_trn.nil?) \ +          ? pot_metadata_src +          : pot_metadata_src_trn +        end +        0.upto(a_l-1) do |i| +          if data_trn +            unless data_src[s] \ +            and data_trn[t] +              break +            end +            if data_src[s].of == :comment \ +            and data_trn[t].of == :comment \ +            and (data_src[s].is == data_trn[t].is) +              s+=1;t+=1 +              next +            end +            if ((data_src[s].is == :comment) \ +            || (data_trn[t].is == :comment)) \ +            and (data_src[s].is != data_trn[t].is) +              if data_src[s].is == :comment +                if @md.opt.act[:maintenance][:set]==:on +                  puts "src (comment):\n\t" \ +                  + data_src[s].obj +                end +                s+=1 +                #next if data_src[s].is == :comment +              elsif data_trn[t].is == :comment +                if @md.opt.act[:maintenance][:set]==:on +                  puts "trans (comment):\n\t" \ +                  + data_trn[t].obj +                end +                t+=1 +                #next if data_trn[t].is == :comment +              end +            end +            if ((defined? data_src[s].ocn) \ +            && (data_src[s].ocn.is_a?(Fixnum))) \ +            and ((defined? data_trn[t].ocn) \ +            && (data_trn[t].ocn.is_a?(Fixnum))) \ +            and (data_src[s].ocn == data_trn[t].ocn) +              @m_s,@m_t=s,t +            elsif ((defined? data_src[s].ocn) \ +            && (data_src[s].ocn.is_a?(Fixnum))) \ +            and ((defined? data_trn[t].ocn) \ +            && (data_trn[t].ocn.is_a?(Fixnum))) \ +            and (data_src[s].ocn != data_trn[t].ocn) +              p '--- OCN ---' +              p 'mis-match' +              p data_src[s].ocn +              p data_src[s].obj +              p data_trn[t].ocn +              p data_trn[t].obj +              p '---' +              p 'previous match' +              p data_src[@m_s].ocn +              p data_src[@m_s].obj +              p data_trn[@m_t].ocn +              p data_trn[@m_t].obj +              exit +            elsif (((defined? data_src[s].ocn) \ +            && (defined? data_trn[t].ocn)) \ +            and data_src[s].ocn.class != data_trn[t].ocn.class) +              p '--- OCN class ---' +              p 'mis-match' +              p data_src[s].ocn if defined? data_src[s].ocn +              p data_src[s].obj +              p data_trn[t].ocn if defined? data_trn[t].ocn +              p data_trn[t].obj +              #p '---' +              #p 'previous match' +              #p data_src[@m_s].ocn +              #p data_src[@m_s].obj +              #p data_trn[@m_t].ocn +              #p data_trn[@m_t].obj +            #elsif (defined? data_src[s].ocn != defined? data_trn[t].ocn) \ +            #and (data_src[s].ocn.nil? != data_trn[t].ocn.nil?) +            #  p '--- missing OCN? ---' +            #  p 'mis-match' +            #  p data_src[s].ocn if defined? data_src[s].ocn +            #  p data_src[s].obj +            #  p data_trn[t].ocn if defined? data_trn[t].ocn +            #  p data_trn[t].obj +            else +            end +          end +          notes_s,notes_t='','' +          data_src[s],notes_s=markup(data_src[s]) +          if data_trn +            data_trn[t],notes_t=markup(data_trn[t]) +            #data_src[s],data_trn[t]=pot_data(data_src[s],notes_s,data_trn[t],notes_t) +            pot_data(data_src[s],notes_s,data_trn[t],notes_t) +          else +            #data_src[s],nul=pot_data(data_src[s],notes_s) +            pot_data(data_src[s],notes_s) +          end +          s+=1;t+=1 +        end +        @pot #watch +      end +      def pot_data(dob_src='',notes_s='',dob_trn='',notes_t='') +        if dob_src.obj !~/(^#{Rx[:meta]}|#{Mx[:br_eof]}|#{Mx[:br_endnotes]})/ +          if defined? dob_src.ocn \ +          and dob_src.ocn.to_s =~/\d+/ +            paranum=dob_src.ocn.to_s +            @p_num=SiSU_Po4aUtils::ParagraphNumber.new(paranum) +          end +          case dob_src.is +          when :heading +            pot_structure.heading(dob_src,notes_s,dob_trn,notes_t) +          when :para +            pot_structure.para(dob_src,notes_s,dob_trn,notes_t) +          when :group +            pot_structure.group(dob_src,notes_s,dob_trn,notes_t) +          when :block +            pot_structure.block(dob_src,notes_s,dob_trn,notes_t) +          when :verse +            pot_structure.verse(dob_src,notes_s,dob_trn,notes_t) +          when :code +            pot_structure.code(dob_src,notes_s,dob_trn,notes_t) +          when :table +            pot_structure.table(dob_src,notes_s,dob_trn,notes_t) +          end +          if defined? dob_src.idx \ +          and not dob_src.idx.nil? \ +          and not dob_src.idx.empty? +            pot_structure.idx(dob_src,dob_trn) +          end +          dob_src='' if (dob_src.obj =~/<a name="n\d+">/ \ +          and dob_src.obj =~/^(-\{{2}~\d+|<!e[:_]\d+!>)/) # -endnote +          if dob_src ## Clean Prepared Text +            dob_src.obj=dob_src.obj.gsub(/<!.+!>/,' '). +              gsub(/<:\S+>/,' ') if dob_src ## Clean Prepared Text +          end +        end +        #[dob_src,dob_trn] +      end +      def markup(dob) +        dob,notes=objects.textface_marks_po4a(dob,:separate) +        [dob,notes] +      end +      def publish(fn,pot) +        content=[] +        content << pot[:open] +        content << pot[:head] +        content << pot[:metadata] +        content << pot[:body] +        content << @@endnotes[:end] if @@endnotes_ +        Output.new(fn,content,@md,@process).po4a +        @@endnotes={ para: [], end: [] } +      end +    end +    class Po4aCfg +      include SiSU_Composite_Doc_Utils                    # composite doc, .ssm, extract all related insert files, array of filenames test +      def initialize(opt,file) +        @opt,@file=opt,file +      end +      def po4a_cfg_filename +        'po4a.cfg' +      end +      def dir +        def pwd +          Dir.pwd +        end +        def po4a_ +          'po4a/' # '' +        end +        def pot +          po4a_ + 'pot' +        end +        def po +          po4a_ + 'po' +        end +        self +      end +      def po4a_cfg_file +        File.open("#{Dir.pwd}/#{po4a_cfg_filename}",'w') +      end +      def language +        def sisu_languages_available +          Px[:lng_lst] +        end +        def translation_languages_selected +          @opt.act[:po4a_lang_trans][:trn] \ +          ? @opt.act[:po4a_lang_trans][:trn] +          : [] +        end +        def translation_languages_selected_that_are_available +          translation_languages_selected & sisu_languages_available +        end +        def source_language_selected_str +          @opt.act[:po4a_lang_trans][:src] \ +          ? @opt.act[:po4a_lang_trans][:src] +          : 'en' +        end +        def translation_languages_selected_that_are_available_str +          translation_languages_selected_that_are_available.join(' ') +        end +        def translation_languages_selected_str +          @opt.act[:po4a_lang_trans][:trn].join(' ') +        end +        self +      end +      def po4a_cfg +        doc_import_list=composite_and_imported_filenames_array(@opt.fno) +        po4a_cfg_arr=[] +        po4a_cfg_arr \ +          << "[po4a_langs] #{language.translation_languages_selected_that_are_available_str}" +        po4a_cfg_arr \ +          << "[po4a_paths] #{dir.pot}/$master.pot $lang:#{dir.po}/$lang/$master.po" +        doc_import_list.each do |file_src| +          file_src_fn= +            file_src.gsub(/#{language.source_language_selected_str}\//,'') +          po4a_cfg_arr \ +            << "[type: text] #{file_src} $lang:$lang/#{file_src_fn}" +        end +        file=@file.write_file.po4a_cfg +        po4a_cfg_arr.each do |txt| +        puts txt +          file << txt << "\n" +        end +        file.close +      end +    end +    class Output <Source +      include SiSU_Param +      include SiSU_Env +      def initialize(fn,content,md,process=:complete) +        @fn,@content,@md,@process=fn,content,md,process +        @file=SiSU_Env::FileOp.new(md,fn) +      end +      def po4a                                                                 #%pot output +        file_pot=(@md.opt.f_pth[:lng] == @md.opt.lng_base) \ +        ? @file.write_file.pot +        : @file.write_file.po +        @sisu=[] +        emptyline=0 +        @content.each do |para|                                                # this is a hack +          if para.is_a?(Array) \ +          and para.length > 0 +            para.each do |line| +              if line +                line=line.gsub(/\s+$/m,''). +                  gsub(/^\A[ ]*\Z/m,'') +                if line=~/^\A[ ]*\Z/m +                  emptyline+=1 +                else emptyline=0 +                end +                file_pot.puts line if emptyline < 2                     #remove extra line spaces (fix upstream) +              end +            end +          else file_pot.puts para          #unix plaintext # /^([*=-]|\.){5}/ +          end +        end +        file_pot.close +        SiSU_Po4aUtils::PotNumber.new.reset +        po4a_git +      end +      def po4a_git +        unless @md.opt.act[:maintenance][:set]==:on +          require_relative 'git'                           # git.rb +          git=SiSU_Git::Source.new(@md.opt,@process) +          unless FileTest.directory?(@file.output_path.pot_git.dir) +            git.create_file_structure_git +          end +          if @md.opt.f_pth[:lng] == @md.opt.lng_base +            FileUtils::cp( +              @file.place_file.pot.dir, +              @file.output_path.pot_git.dir +            ) +          else # naive, work on --> +            FileUtils::cp( +              @file.place_file.po.dir, +              @file.output_path.po_git.dir +            ) #unless FileTest.file?(@file.place_file.po_git.dir) +          end +          git.read +        end +      end +    end +  end +end +__END__ +!\|#\|&*\|-\|/\|_\|{\|}\|~\|&# + +tables are problematic, difficult to reconstitute instruction, check + +metadata, move to top? and work on + +footnotes, different types, asterisk, also do you want to have separate +paragraphs, or breaks within one block? + +where no ocn appropriately use ~# or -# or indeed 1~name- + +comments in document, what to do about them, not sure they are currently +retained in dal, could be quite valuable to keep + +Translate Shell +http://www.soimort.org/translate-shell/ +translate.google.com +#+END_SRC + +* src_po4a_shelf_set.rb + +#+BEGIN_SRC ruby  :tangle "../lib/sisu/src_po4a_shelf_set.rb" +# <<sisu_document_header>> +module SiSU_Po4aUtils +  class Wrap +    def initialize(md,orig='',trans='',is_desc='',n_char_max=76,n_indent=0,n_hang=nil) +      @md,@orig,@trans,@is_desc,@n_char_max,@n_indent= +       md, orig, trans, is_desc, n_char_max, n_indent +      @n_char_max_extend = n_char_max +      @br="\n" +      @n_hang=n_hang ? n_hang : @n_indent +      @po4a_identify_type='type: SiSU doc' +      #@po4a_identify_type='type: Plain text' +    end +    def line_wrap +      space=' ' +      spaces_indent,spaces_hang= +        "#{@br}#{space*@n_indent}",space*@n_hang +      pot,i=[],0 +      pot_array=(@trans.empty?) ? [@orig] : [@orig,@trans] +      pot_array.each do |pa| +        line=0 +        out=[] +        out[line]='' +        @oldword='' #REMOVE @oldword +        pa=pa.gsub(/<br>/,' <br> '). +          gsub(/#{Mx[:br_nl]}/,"\n\n") +        words=pa.scan(/\n\n|\\\\\\|<br>|\S+/m) +        while words != '' +          word=words.shift +          if not word +            out[line] unless out[line].empty? #check +            break +          elsif word =~/\n\n/ +            word="\n" +            @n_char_max_extend = @n_char_max + out[line].length +            line=line +          elsif (out[line].length + word.length) > (@n_char_max_extend - @n_indent) \ +          and out[line] =~/\S+/ +            @n_char_max_extend = @n_char_max +            out[line].squeeze!(' ') +            line += 1 +          end +          if word +            out[line]=if out[line] \ +            and out[line] !~/\S+$/m +              "#{out[line]}#{word}" +            elsif out[line] \ +            and out[line] =~/\S+/ +              "#{out[line]} #{word}" +            else "#{word.strip}" +            end +          end +          @oldword=word if word =~/\S+/ +        end +        x=out.join(spaces_indent).gsub(/\A\n+/m,'').insert(0,spaces_hang) +        z=[] +        x.split(/\n/).each do |y| +          y=y.gsub(/"/,'\"') +          y=%{"#{y}"} +          z << y +        end +        pot[i]=z.join("\n") +        i +=1 +        pot +      end +      trans=(pot.length == 2) ? pot[1] : '' +      po_str=<<WOK +#. #{@po4a_identify_type} - #{@is_desc} +#: en/#{@md.fns}:#{PotNumber.new.num} +msgid "" +#{pot[0]} +msgstr "" +#{trans} +WOK +      po_str +    end +    def no_line_wrap_block +      pot,i=[],0 +      pot_array=(@trans.empty?) ? [@orig] : [@orig,@trans] +      pot_array.each do |pa| +        z=[] +        pa.split(/\n\n/).each do |y| +          y=y.gsub(/"/,'\"') +          y=%{"#{y}"} +          z << y if not y.empty? +        end +        pot[i]=z.join("\n") +        i +=1 +        pot +      end +      trans=(pot.length == 2) ? pot[1] : '' +      po_str=<<WOK +#. #{@po4a_identify_type} - #{@is_desc} +#: en/#{@md.fns}:#{PotNumber.new.num} +#, no-wrap +msgid "" +#{pot[0]} +msgstr "" +#{trans} +WOK +      po_str +    end +    def line_wrap_indent1 +      @n_indent,@n_hang=2,2 +      line_wrap +    end +    def line_wrap_endnote +      @n_indent,@n_hang=4,2 +      line_wrap +    end +    def array_wrap +      if @orig.is_a?(Array) +        @arr=[] +        @orig.each do |line| +          @arr << SiSU_TextUtils::Wrap.new(line,@n_char_max,@n_indent,@n_hang).line_wrap +        end +      end +      @arr +    end +  end +  class HeaderScan +    def initialize(md,para) +      @md,@p=md,para +    end +    def extract(tag,tag_content,type,attrib) +      if dc_tag \ +      and dc_content +        [dc_tag,dc_content,{dc_tag=>dc_content}] +      else nil +      end +    end +    def header(tag,tag_content,type='',attrib='') #this will break stuff and must be tested thoroughly 20060825 +      @tag,@tag_content,@type,@attrib=tag,tag_content,type,attrib +      def label #element +        @tag +      end +      def type +        @type +      end +      def text +        @tag_content +      end +      def info  #element text +        @tag_content +      end +      def attribute +        @attrib +      end +      def element +        @tag +      end +      def attrib +        @attrib +      end +      def el +        @tag +      end +      self +    end +    def start_is_match +      case @p +      when /^#{Mx[:meta_o]}(title)#{Mx[:meta_c]}\s*(.+?)$/                      then header($1,@md.title.full,'meta','dc') #dc 1 +      when /^#{Mx[:meta_o]}(creator|author)#{Mx[:meta_c]}\s*(.+?)$/             then header('creator',$2,'meta','dc')    #dc 2 +      when /^#{Mx[:meta_o]}(subject)#{Mx[:meta_c]}\s*(.+?)$/                    then header($1,$2,'meta','dc')           #dc 3 +      when /^#{Mx[:meta_o]}(description)#{Mx[:meta_c]}\s*(.+?)$/                then header($1,$2,'meta','dc')           #dc 4 +      when /^#{Mx[:meta_o]}(publisher)#{Mx[:meta_c]}\s*(.+?)$/                  then header($1,$2,'meta','dc')           #dc 5 +      when /^#{Mx[:meta_o]}(contributor)#{Mx[:meta_c]}\s*(.+?)$/                then header($1,$2,'meta','dc')           #dc 6 +      when /^#{Mx[:meta_o]}(date)#{Mx[:meta_c]}\s*(.+?)$/                       then header($1,$2,'meta','dc')           #dc 7 +      when /^#{Mx[:meta_o]}(date\.created)#{Mx[:meta_c]}\s*(.+?)$/              then header($1,$2,'meta','extra') +      when /^#{Mx[:meta_o]}(date\.issued)#{Mx[:meta_c]}\s*(.+?)$/               then header($1,$2,'meta','extra') +      when /^#{Mx[:meta_o]}(date\.available)#{Mx[:meta_c]}\s*(.+?)$/            then header($1,$2,'meta','extra') +      when /^#{Mx[:meta_o]}(date\.valid)#{Mx[:meta_c]}\s*(.+?)$/                then header($1,$2,'meta','extra') +      when /^#{Mx[:meta_o]}(date\.modified)#{Mx[:meta_c]}\s*(.+?)$/             then header($1,$2,'meta','extra') +      when /^#{Mx[:meta_o]}(type)#{Mx[:meta_c]}\s*(.+?)$/                       then header($1,$2,'meta','dc')           #dc 8 +      when /^#{Mx[:meta_o]}(format)#{Mx[:meta_c]}\s*(.+?)$/                     then header($1,$2,'meta','dc')           #dc 9 +      when /^#{Mx[:meta_o]}(identifier)#{Mx[:meta_c]}\s*(.+?)$/                 then header($1,$2,'meta','dc')           #dc 10 +      when /^#{Mx[:meta_o]}(source)#{Mx[:meta_c]}\s*(.+?)$/                     then header($1,$2,'meta','dc')           #dc 11 +      when /^#{Mx[:meta_o]}(language)#{Mx[:meta_c]}\s*(.+?)$/                   then header($1,$2,'meta','dc')           #dc 12 +      when /^#{Mx[:meta_o]}(relation)#{Mx[:meta_c]}\s*(.+?)$/                   then header($1,$2,'meta','dc')           #dc 13 +      when /^#{Mx[:meta_o]}(coverage)#{Mx[:meta_c]}\s*(.+?)$/                   then header($1,$2,'meta','dc')           #dc 14 +      when /^#{Mx[:meta_o]}(rights)#{Mx[:meta_c]}\s*(.+?)$/                     then header($1,$2,'meta','dc')           #dc 15 +      when /^#{Mx[:meta_o]}(keywords)#{Mx[:meta_c]}\s*(.+?)$/                   then header($1,$2,'meta','extra') +      when /^#{Mx[:meta_o]}(copyright)#{Mx[:meta_c]}\s*(.+?)$/                  then header($1,$2,'meta','extra') +      when /^#{Mx[:meta_o]}(translator|translated_by)#{Mx[:meta_c]}\s*(.+?)$/   then header('translator',$2) +      when /^#{Mx[:meta_o]}(illustrator|illustrated_by)#{Mx[:meta_c]}\s*(.+?)$/ then header('illustrator',$2) +      when /^#{Mx[:meta_o]}(prepared_by)#{Mx[:meta_c]}\s*(.+?)$/                then header($1,$2,'meta','extra') +      when /^#{Mx[:meta_o]}(digitized_by)#{Mx[:meta_c]}\s*(.+?)$/               then header($1,$2,'meta','extra') +      when /^#{Mx[:meta_o]}(comments?)#{Mx[:meta_c]}\s*(.+?)$/                  then header($1,$2,'meta','extra') +      when /^#{Mx[:meta_o]}(abstract)#{Mx[:meta_c]}\s*(.+?)$/                   then header($1,$2,'meta','extra') +      when /^#{Mx[:meta_o]}(tags?)#{Mx[:meta_c]}\s*(.+?)$/                      then header($1,$2,'meta','extra') +      when /^#{Mx[:meta_o]}(catalogue)#{Mx[:meta_c]}\s*(.+?)$/                  then header($1,$2,'meta','extra') +      when /^#{Mx[:meta_o]}(class(?:ify)?_loc)#{Mx[:meta_c]}\s*(.+?)$/          then header('classify_loc',$2,'meta','extra') +      when /^#{Mx[:meta_o]}(class(?:ify)?_dewey)#{Mx[:meta_c]}\s*(.+?)$/        then header('classify_dewey',$2,'meta','extra') +      when /^#{Mx[:meta_o]}(class(?:ify)?_pg)#{Mx[:meta_c]}\s*(.+?)$/           then header('classify_pg',$2,'meta','extra') +      when /^#{Mx[:meta_o]}(class(?:ify)?_isbn)#{Mx[:meta_c]}\s*(.+?)$/         then header('classify_isbn',$2,'meta','extra') +      when /^#{Mx[:meta_o]}(toc|structure)#{Mx[:meta_c]}\s*(.+?)$/              then header('structure',$2,'process','instruct') +      when /^#{Mx[:meta_o]}(level|page|markup)#{Mx[:meta_c]}\s*(.+?)$/          then header('markup',$2,'process','instruct') +      when /^#{Mx[:meta_o]}(bold)#{Mx[:meta_c]}\s*(.+?)$/                       then header($1,$2,'process','instruct') +      when /^#{Mx[:meta_o]}(italics|itali[sz]e)#{Mx[:meta_c]}\s*(.+?)$/         then header('italicize',$2,'process','instruct') +      when /^#{Mx[:meta_o]}(vocabulary|wordlist)#{Mx[:meta_c]}\s*(.+?)$/        then header('vocabulary',$2,'process','instruct') +      when /^#{Mx[:meta_o]}(css|stylesheet)#{Mx[:meta_c]}\s*(.+?)$/             then header('css',$2,'process','instruct') +      when /^#{Mx[:meta_o]}(links)#{Mx[:meta_c]}\s*(.+?)$/                      then header($1,$2,'process','instruct') +      when /^#{Mx[:meta_o]}(prefix)#{Mx[:meta_c]}\s*(.+?)$/                     then header($1,$2,'process','instruct') #add a & b +      when /^#{Mx[:meta_o]}(suffix)#{Mx[:meta_c]}\s*(.+?)$/                     then header($1,$2,'process','instruct') +      when /^#{Mx[:meta_o]}(information)#{Mx[:meta_c]}\s*(.+?)$/                then header($1,$2,'process','instruct') +      when /^#{Mx[:meta_o]}(contact)#{Mx[:meta_c]}\s*(.+?)$/                    then header($1,$2,'process','instruct') +      when /^#{Mx[:meta_o]}(rcs|cvs)#{Mx[:meta_c]}\s*(.+?)$/                    then header('version',$2,'process','instruct') +      else nil +      end +    end +    def dublin +      (@p =~/^#{Mx[:meta_o]}\S+?#{Mx[:meta_c]}/) \ +      ? start_is_match +      : nil +    end +    def meta +      (@p =~/^#{Mx[:meta_o]}\S+?#{Mx[:meta_c]}/) \ +      ? start_is_match +      : nil +    end +  end +  class ParagraphNumber +    def initialize(paranum) +      @paranum=/(\d+)/m.match(paranum)[1] +    end +    def display +      @paranum.gsub(/(\d+)/,'#\1') +    end +  end +  class PotNumber +    @@n=0 +    def initialize +      @@n +=2 +    end +    def num +      @@n +    end +    def reset +      @@n=0 +    end +  end +end +__END__ +#+END_SRC + +* src_po4a_sst_ao_sst.rb + +#+BEGIN_SRC ruby  :tangle "../lib/sisu/src_po4a_sst_ao_sst.rb" +# <<sisu_document_header>> +module SiSU_SStm_AO_SStm +  require_relative 'ao'                                 # ao.rb +  require_relative 'se'                                 # se.rb +    include SiSU_Env +  require_relative 'ao_composite'                       # ao_composite.rb +  require_relative 'shared_metadata'                    # shared_metadata.rb +  require_relative 'src_po4a_share'                     # src_po4a_share.rb +  require_relative 'src_po4a_sst_ao_sst_set'            # src_po4a_sst_ao_sst_set.rb +  include SiSU_Param +  require_relative 'object_munge'                       # object_munge.rb +  require_relative 'utils_composite'                    # utils_composite.rb +  require_relative 'utils_response'                     # utils_response.rb +  class Source +    include SiSU_Object_Munge +    include SiSU_Languages_Selected +    include SiSU_Response +    @@md_src,@@md_master= +          nil,      nil +    @@auto_translation_ = :go +    def initialize(opt,fn=nil) +      @opt,@fn=opt,fn +      #unless @opt.fns =~/(.+?\.(?:-|ssm\.)?sst)$/ +      #  puts "#{@opt.fns} not a processed file type" +      #end +      file_arr=SiSU_Info_Env::InfoEnv.new. +        source_file_processing_array(@opt.fno) +      SiSU_Param::Parameters::Instructions.new(file_arr,@opt).extract +      r=Px[:lng_lst_rgx].gsub(/\|#{language.source_language_selected_str}\|/,'|') +      @lang_regx=%r{(?:#{r})} +      @@todo=if source_language_selected_str == opt.f_pth[:lng] +        :same_file +      else :compare +      end +      if opt.f_pth[:lng]==@opt.lng_base \ +      and opt.f_pth[:lng]==source_language_selected_str +        @@md_master=SiSU_Param::Parameters.new(opt).get +      end +    end +    def wrap_width_set(md,env) +      if defined? md.make.plaintext_wrap \ +      and md.make.plaintext_wrap +        md.make.plaintext_wrap +      elsif defined? env.plaintext_wrap \ +      and env.plaintext_wrap +        #env.plaintext_wrap # 78 use 75 +        75 +      else 75 #78 +      end +    end +    def process_file(md,env,file,wrap_width,fn) +      if source_language_selected_str == @opt.f_pth[:lng] +        @@ao_arr_lang_trans= +          SiSU_AO::Source.new( +            @opt, +            fn, +            :po4a +          ).get # ao file drawn here +      end +      @ao_arr_lang_src= +        SiSU_AO::Source.new( +          @opt, +          fn, +          :po4a +        ).get # ao file drawn here +      SiSU_SStm_AO_SStm::Source::Scroll.new( +        fn, +        @ao_arr_lang_src, +        @@ao_arr_lang_trans, +        @@md_src, +        @@md_master, +        wrap_width +      ).songsheet +    end +    def read_process_src_files +      begin +        src={} +        src[:pth]=@opt.f_pth[:pth] +        src[:files]=if @opt.fns =~ /\.(?:(?:-|ssm\.)sst|ssm)$/ +          @opt.fns=@opt.fns.gsub(/\.ssm\.sst$/,'.ssm') +          SiSU_Assemble::CompositeFileList.new(@opt).read +        else +          [@opt.fns] +        end +        md=SiSU_Param::Parameters.new(@opt).get +        env=SiSU_Env::InfoEnv.new(@opt.fns) +        file=SiSU_Env::FileOp.new(md) +        lng=/\/([^\/]+)$/.match(src[:pth])[1] +        if language.source_language_selected_str == lng +          SiSU_Po4a_Project::Po4aDistClean.new(@opt,file).song +        end +        wrap_width=wrap_width_set(md,env) +        lng = /\/([^\/]+)$/.match(src[:pth])[1] +        ans=response?('process files?') +        if ans +          src[:files].each do |fn| +            puts "[#{lng}] #{fn}" +            process_file(md,env,file,wrap_width,fn) +          end +        end +      rescue +        SiSU_Errors::Rescued.new($!,$@,@opt.selections.str,@opt.fns).location do +          __LINE__.to_s + ':' + __FILE__ +        end +      ensure +      end +    end +    def read_setup +      begin +        md=SiSU_Param::Parameters.new(@opt).get +        file=SiSU_Env::FileOp.new(md) +        SiSU_Po4a_Project::Po4aCfg.new(@opt,file).song +        SiSU_Po4a_Project::Po4aProject.new(@opt,file).song +      rescue +        SiSU_Errors::Rescued.new($!,$@,@opt.selections.str,@opt.fns).location do +          __LINE__.to_s + ':' + __FILE__ +        end +      ensure +      end +    end +    private +    class Scroll <Source +      include SiSU_Po4aUtils +      @@endnotes={ para: [], end: [] } +      def initialize(fn,data_src,data_master,md_src,md_master,wrap_width) +        @fn,@data_src,@data_master,@md_src,@md_master,@wrap_width= +         fn, data_src, data_master, md_src, md_master, wrap_width +        @md=md_src +        @tab="\t" +        @@endnotes_=(@md.opt.selections.str =~/--endnote/) \ +        ? true +        : false    # --footnote +        @pot={ +          body: [], +          open: [], +          close: [], +          head: [], +          metadata: [], +          tail: [] +        } +      end +      def br +        (@md.opt.selections.str =~/--dos/) ? "\r\n" : "\n"  # --unix +      end +      def songsheet +        fn=@fn +        pot=compare_structure_src_trn(@data_src,@data_master,@@todo) +        publish(fn,pot) +      end +      def pot_structure_wrap(orig,trans,indent=0,hang=0) +        SiSU_Po4aUtils::Wrap.new( +          @md, +          orig, +          trans, +          @wrap_width, +          indent, +          hang +        ) +      end +      def wrap_endnotes(orig_notes='',trn_notes='') +        #nt=@@endnotes_ ? 'endnote' : 'footnote' +        @fn=0 +        a_l=orig_notes.length +        0.upto(a_l-1) do |i| +          @fn=if orig_notes[i].to_s =~/^\^~([\d*+]+)/ # provides endnote number within paragraph +            @fn += 1 +          else @fn +          end +          #mark="^~ " +          orig=(orig_notes[i].to_s =~/^\^~[\d*+]+/) \ +          ? (orig_notes[i].to_s.gsub(/^\^~[\d*+]+/,'^~')) +          : orig_notes[i].to_s +          trans=if trn_notes.is_a?(Array) \ +          and trn_notes.length==orig_notes.length +            (trn_notes[i].to_s =~/^\^~[\d*+]+/) \ +            ? (trn_notes[i].to_s.gsub(/^\^~[\d*+]+/,'^~')) +            : trn_notes[i].to_s +          else '' +          end +          util=pot_structure_wrap(orig,trans) +          wrap=util.line_wrap +          wrap=if wrap =~ /^\s*\^~[\d*+]+\s+.+?\s*\Z/m +            wrap.gsub(/^\s*(\^~[\d*+]+)\s+(.+?)\s*\Z/m, <<GSUB +\\1 \\2 +GSUB +                      ) +          else +            wrap.gsub(/^(.+)\Z/m, <<GSUB +\\1 +GSUB +                      ) +          end +          @@endnotes[:para] << wrap +          @@endnotes[:end] << '' << wrap +        end +        @@endnotes[:para].each {|e| @pot[:body] << e << br} +        @@endnotes[:para]=[] +        @@endnotes +      end +      def pot_metadata_src +        @po4a_identify_type='type: SiSU doc' #'type: Plain text' +        meta_src=SiSU_Metadata::Summary.new(@md_src) +        w=[] +        w << [ +          meta_src.metadata_tags.title.main, +          meta_src.metadata_tags.title.sub, +          meta_src.metadata_tags.title.edition, +          meta_src.metadata_tags.title.note, +          meta_src.metadata_tags.title.short, +          meta_src.metadata_tags.title.language, +          meta_src.metadata_tags.title.language_char, +        ] +        w << [ +          meta_src.metadata_tags.creator.head, +          meta_src.metadata_tags.creator.author, +          meta_src.metadata_tags.creator.contributor, +          meta_src.metadata_tags.creator.illustrator, +          meta_src.metadata_tags.creator.photographer, +          meta_src.metadata_tags.creator.translator, +          meta_src.metadata_tags.creator.audio, +          meta_src.metadata_tags.creator.digitized_by, +          meta_src.metadata_tags.creator.prepared_by, +        ] +        w << [ +          meta_src.metadata_tags.rights.head, +          meta_src.metadata_tags.rights.copyright.text, +          meta_src.metadata_tags.rights.copyright.translation, +          meta_src.metadata_tags.rights.copyright.illustrations, +          meta_src.metadata_tags.rights.copyright.photographs, +          meta_src.metadata_tags.rights.copyright.digitization, +          meta_src.metadata_tags.rights.copyright.audio, +          meta_src.metadata_tags.rights.license, +        ] +        w << [ +          meta_src.metadata_tags.classify.head, +          meta_src.metadata_tags.classify.subject, +          meta_src.metadata_tags.classify.topic_register, +          meta_src.metadata_tags.classify.loc, +          meta_src.metadata_tags.classify.dewey, +        ] +        w << [ +          meta_src.metadata_tags.date.head, +          meta_src.metadata_tags.date.added_to_site, +          meta_src.metadata_tags.date.available, +          meta_src.metadata_tags.date.created, +          meta_src.metadata_tags.date.issued, +          meta_src.metadata_tags.date.modified, +          meta_src.metadata_tags.date.published, +          meta_src.metadata_tags.date.valid, +        ] +        w << [ +          meta_src.processing_tags.make.language, +          meta_src.processing_tags.make.headings, +          meta_src.processing_tags.make.num_top, +          meta_src.processing_tags.make.breaks, +          meta_src.processing_tags.make.emphasis, +          meta_src.processing_tags.make.bold, +          meta_src.processing_tags.make.italics, +          meta_src.processing_tags.make.texpdf_font, +        ] +        w.each do |y| +          z='' +          y.each do |x| +            if x +              z += x + "\n" if x =~/^#|^msg(?:id|str)/ +              z += %{#{x}\n} if x =~/^@\S+?:(?: |$)/ +              z += %{#{x}\n} if x =~/^\s+:\S+?: / +            end +          end +          @pot[:metadata] << z << br +          #puts z unless z.empty? +        end +      end +      def pot_metadata_src_trn +        #@po4a_identify_type='type: Plain text' +        meta_src=SiSU_Metadata::Summary.new(@md_src) +        w=[] +        w << [ +          meta_src.metadata_tags.title.main, +          meta_src.metadata_tags.title.sub, +          meta_src.metadata_tags.title.edition, +          meta_src.metadata_tags.title.note, +          meta_src.metadata_tags.title.short, +          meta_src.metadata_tags.title.language, +          meta_src.metadata_tags.title.language_char, +        ] +        w << [ +          meta_src.metadata_tags.creator.head, +          meta_src.metadata_tags.creator.author, +          meta_src.metadata_tags.creator.contributor, +          meta_src.metadata_tags.creator.illustrator, +          meta_src.metadata_tags.creator.photographer, +          meta_src.metadata_tags.creator.translator, +          meta_src.metadata_tags.creator.audio, +          meta_src.metadata_tags.creator.digitized_by, +          meta_src.metadata_tags.creator.prepared_by, +        ] +        w << [ +          meta_src.metadata_tags.rights.head, +          meta_src.metadata_tags.rights.copyright.text, +          meta_src.metadata_tags.rights.copyright.translation, +          meta_src.metadata_tags.rights.copyright.illustrations, +          meta_src.metadata_tags.rights.copyright.photographs, +          meta_src.metadata_tags.rights.copyright.digitization, +          meta_src.metadata_tags.rights.copyright.audio, +          meta_src.metadata_tags.rights.license, +        ] +        w << [ +          meta_src.metadata_tags.classify.head, +          meta_src.metadata_tags.classify.subject, +          meta_src.metadata_tags.classify.topic_register, +          meta_src.metadata_tags.classify.loc, +          meta_src.metadata_tags.classify.dewey, +        ] +        w << [ +          meta_src.metadata_tags.date.head, +          meta_src.metadata_tags.date.added_to_site, +          meta_src.metadata_tags.date.available, +          meta_src.metadata_tags.date.created, +          meta_src.metadata_tags.date.issued, +          meta_src.metadata_tags.date.modified, +          meta_src.metadata_tags.date.published, +          meta_src.metadata_tags.date.valid, +        ] +        w << [ +          meta_src.processing_tags.make.language, +          meta_src.processing_tags.make.headings, +          meta_src.processing_tags.make.num_top, +          meta_src.processing_tags.make.breaks, +          meta_src.processing_tags.make.emphasis, +          meta_src.processing_tags.make.bold, +          meta_src.processing_tags.make.italics, +          meta_src.processing_tags.make.texpdf_font, +        ] +        w.each do |y| +          z='' +          y.each do |x| +            if x +              z += x + "\n" if x =~/^#|^msg(?:id|str)/ +              z += %{#{x}\n} if x =~/^@\S+?:(?: |$)/ +              z += %{#{x}\n} if x =~/^\s+:\S+?: / +            end +          end +          @pot[:metadata] << z << br +          #puts z unless z.empty? +        end +      end +      def auto_translate?(set_to=nil) +        @@auto_translation_= +        if @md.opt.act[:po4a_lang_trans][:set]==:on +          set_to \ +          ? set_to +          : @@auto_translation_ +        else :skip +        end +      end +      def auto_translation(src_txt,markup=:src) # check for an appropriate request flag +        auto_translate?(:skip) +        begin +          src_txt_clean=clean_text(src_txt,markup) +          src_txt_clean=src_txt_clean. +            gsub(/\n/,' '). +            gsub(/"/,'\"'). +            gsub(/([()])/,'\\\\\1') +          trans='' +          unless auto_translate? == :skip +            require 'timeout' +            Timeout::timeout(60) { +              trans=`trans -b -no-ansi en:#{@md.opt.f_pth[:lng_is]} #{src_txt_clean}`.strip +              unless trans.empty? +                trans + ' {[G.Tr]}http://translate.google.com' +              end +            } +          end +          trans +        rescue +          auto_translate?(:skip) +          p 'timeout issues with translation, skip remaining' +        end +      end +      def pot_structure +        def heading(dob_src='',notes_s='',dob_trn='',notes_t='')   #% used to extract the structure of a document +          lv=n=n3=nil +          lv=dob_src.ln +          n=lv - 1 +          n3=lv + 2 +          util=nil +          fn=(dob_src.name=~/[a-z\d]/i) ? dob_src.name : '' +          mark="#{dob_src.lv}~#{fn} " +          orig="#{mark}#{dob_src.obj}" +          trans=((dob_trn=='') \ +          || (dob_src.obj == dob_trn.obj)) \ +          ? '' +          : "#{mark}#{dob_trn.obj}" +          if @md.opt.f_pth[:lng_is] !=@md.opt.lng_base \ +          and trans.empty? \ +          and auto_translate? +            trans=auto_translation(dob_src.obj,:src) +          end +          util=pot_structure_wrap(orig,trans) +          wrapped=util.line_wrap +          @pot[:body] << wrapped << br # main text, contents, body KEEP +          if @@endnotes[:para] \ +          and notes_s.length > 0 \ +          and not @@endnotes_ +            @pot[:body] << br +            wrap_endnotes(notes_s,notes_t) +          elsif @@endnotes[:para] \ +          and @@endnotes_ +            @pot[:body] << br*2 +          end +        end +        def para(dob_src='',notes_s='',dob_trn='',notes_t='')      #% used to extract the structure of a document +          util=nil +          wrapped=if dob_src.indent =~/[1-9]/ \ +          and dob_src.indent == dob_src.hang +            s_mark=desc=orig=trans='' +            mark=if dob_src.bullet_ +              "_#{dob_src.indent}* " +            else +              "_#{dob_src.indent} " +            end +            orig="#{mark}#{dob_src.obj}" +            trans=((dob_trn=='') \ +            || (dob_src.obj == dob_trn.obj)) \ +            ? '' +            : "#{mark}#{dob_trn.obj}" +            if @md.opt.f_pth[:lng_is] !=@md.opt.lng_base \ +            and trans.empty? \ +            and auto_translate? +              trans=auto_translation(dob_src.obj,:src) +            end +            util=pot_structure_wrap(orig,trans) +          elsif dob_src.hang =~/[0-9]/ \ +          and dob_src.indent != dob_src.hang +            s_mark=desc=orig=trans='' +            mark="_#{dob_src.hang}_#{dob_src.indent} " +            orig="#{mark}#{dob_src.obj}" +            trans=((dob_trn=='') \ +            || (dob_src.obj == dob_trn.obj)) \ +            ? '' +            : "#{mark}#{dob_trn.obj}" +            if @md.opt.f_pth[:lng_is] !=@md.opt.lng_base \ +            and trans.empty? \ +            and auto_translate? +              trans=auto_translation(dob_src.obj,:src) +            end +            util=pot_structure_wrap(orig,trans) +          else +            s_mark=desc=orig=trans='' +            if dob_src.bullet_ +              mark='_* ' +              orig="#{mark}#{dob_src.obj}" +              trans=((dob_trn=='') \ +              || (dob_src.obj == dob_trn.obj)) \ +              ? '' +              : "#{mark}#{dob_trn.obj}" +              if @md.opt.f_pth[:lng_is] !=@md.opt.lng_base \ +              and trans.empty? \ +              and auto_translate? +                trans=auto_translation(dob_src.obj,:src) +              end +            else +              mark='' +              orig=dob_src.obj +              trans=((dob_trn=='') \ +              || (dob_src.obj == dob_trn.obj)) \ +              ? '' +              : "#{mark}#{dob_trn.obj}" +              if @md.opt.f_pth[:lng_is] !=@md.opt.lng_base \ +              and trans.empty? \ +              and auto_translate? +                trans=auto_translation(dob_src.obj,:src) +              end +            end +            util=pot_structure_wrap(orig,trans) +          end +          wrapped=util.line_wrap +          @pot[:body] << wrapped << br # main text, contents, body KEEP +          if @@endnotes[:para] \ +          and notes_s.length > 0 \ +          and not @@endnotes_ +            @pot[:body] << br +            wrap_endnotes(notes_s,notes_t) +          elsif @@endnotes[:para] \ +          and @@endnotes_ +            @pot[:body] << br*2 +          end +        end +        def block(dob_src='',notes_s='',dob_trn='',notes_t='')     #% used to extract the structure of a document +          mark_o ="block{\n\n" +          mark_c ="\n\n}block" +          orig="#{mark_o}#{dob_src.obj}#{mark_c}" +          trans=((dob_trn=='') \ +          || (dob_src.obj == dob_trn.obj)) \ +          ? '' +          : "#{mark_o}#{dob_trn.obj}#{mark_c}" +          if @md.opt.f_pth[:lng_is] !=@md.opt.lng_base \ +          and trans.empty? \ +          and auto_translate? +            trans=auto_translation(dob_src.obj,:src) +          end +          util=pot_structure_wrap(orig,trans) +          unwrapped=util.no_line_wrap_block +          @pot[:body] << unwrapped << br +        end +        def group(dob_src='',notes_s='',dob_trn='',notes_t='')     #% used to extract the structure of a document +          mark_o ="group{\n\n" +          mark_c ="\n\n}group" +          orig="#{mark_o}#{dob_src.obj}#{mark_c}" +          trans=((dob_trn=='') \ +          || (dob_src.obj == dob_trn.obj)) \ +          ? '' +          : "#{mark_o}#{dob_trn.obj}#{mark_c}" +          if @md.opt.f_pth[:lng_is] !=@md.opt.lng_base \ +          and trans.empty? \ +          and auto_translate? +            trans=auto_translation(dob_src.obj,:src) +          end +          util=pot_structure_wrap(orig,trans) +          unwrapped=util.no_line_wrap_block +          @pot[:body] << unwrapped << br +        end +        def verse(dob_src='',notes_s='',dob_trn='',notes_t='')     #% used to extract the structure of a document +          mark="poem{\n\nverse\n\nverse\n\n...\n\n}poem" +          instruct=s_mark='' +          if @md.opt.act[:maintenance][:set]==:on +            instruct=%{\n# verse are part of the text block described as a poem, } \ +            + %{the first verse is preceeded by an opening marker, } \ +            + %{and the last verse by a closing marker, } \ +            + %{the content of which should remain unwrapped} +            s_mark="\n# " + %{"\\n\\n#{mark}\\n\\n"} +          end +          orig=dob_src.obj +          trans=(dob_trn=='') \ +          ? '' +          : dob_trn.obj +          util=pot_structure_wrap(orig,trans) +          unwrapped=util.no_line_wrap_block +          @pot[:body] << unwrapped << br +        end +        def code(dob_src='',notes_s='',dob_trn='',notes_t='')      #% used to extract the structure of a document +          mark_o ="code{\n\n" +          mark_c ="\n\n}code" +          orig="#{mark_o}#{dob_src.obj}#{mark_c}" +          trans=(dob_trn=='') \ +          ? '' +          : "#{mark_o}#{dob_trn.obj}#{mark_c}" +          util=pot_structure_wrap(orig,trans) +          unwrapped=util.no_line_wrap_block +          @pot[:body] << unwrapped << br +        end +        def table(dob_src='',notes_s='',dob_trn='',notes_t='')     #% used to extract the structure of a document +          mark_o ="table{\n\n" +          mark_c ="\n\n}table" +          orig="#{mark_o}#{dob_src.obj}#{mark_c}" +          orig=orig.gsub(/#{Mx[:tc_c]}/m,"\n") +          trans=(dob_trn=='') \ +          ? '' +          : "#{mark_o}#{dob_trn.obj}#{mark_c}" +          trans=trans.gsub(/#{Mx[:tc_c]}/m,"\n") +          util=pot_structure_wrap(orig,trans) +          unwrapped=util.no_line_wrap_block +          @pot[:body] << unwrapped << br +        end +        def idx_markup(idx) +          struct=['={' + "\n  "] +          idx.sort.each do |x| +            x.each_with_index do |y,i0| +              case y +              when String +                unless struct[-1] =~/=\{/ +                  struct << ' ;' + "\n  " +                end +                struct << y +                if x[i0+1].class == Hash \ +                and x[i0+1][:sub].length > 0 +                  struct << ' :' + "\n    " +                end +              when Hash +                if y[:plus].to_i > 0 +                  struct << '+' + y[:plus].to_s +                end +                if y[:sub].length > 0 +                  y[:sub].each_with_index do |z,i1| +                    z.each_with_index do |a,i2| +                      if z.length > 0 +                        struct << a[0] +                        if a[1][:plus].to_i > 0 +                          struct << '+' + a[1][:plus].to_s +                        end +                        if (i1 + 1) < y[:sub].length +                          struct << '|' +                        end +                      end +                    end +                  end +                end +              end +            end +          end +          struct << "\n" + '}' +          #puts struct.join +          struct.join +        end +        def idx(dob_src='') #% used for book index but broken as original markup lost, already abstracted, fix +          orig=pot_structure.idx_markup(dob_src.idx) #'={' + dob_src.idx + '}' +          util=pot_structure_wrap(orig,'') +          unwrapped=util.no_line_wrap_block +          if @pot[:body][-1] == "\n" +            @pot[:body][-1] = unwrapped #<< br +            @pot[:body] << br +          else # expect to catch all above, problem if wraps, must =~/^=\{/ +            @pot[:body] << unwrapped << br # places idx in separate object +          end +        end +        self +      end +      def compare_structure_src_trn(data_src,data_trn,todo) +        #@endnotes,@copen,@pot_contents_close=Array.new(3){[]} +        a_l= data_src.length +        s,t=0,0 +        0.upto(a_l-1) do |i| +          if todo==:compare +            unless data_src[s] \ +            and data_trn[t] +              break +            end +            if data_src[s].of == :comment \ +            and data_trn[t].of == :comment \ +            and (data_src[s].is == data_trn[t].is) +              s+=1;t+=1 +              next +            end +            if ((data_src[s].is == :comment) \ +            || (data_trn[t].is == :comment)) \ +            and (data_src[s].is != data_trn[t].is) +              if data_src[s].is == :comment +                if @md.opt.act[:maintenance][:set]==:on +                  puts "src (comment):\n\t" \ +                  + data_src[s].obj +                end +                s+=1 +                #next if data_src[s].is == :comment +              elsif data_trn[t].is == :comment +                if @md.opt.act[:maintenance][:set]==:on +                  puts "trans (comment):\n\t" \ +                  + data_trn[t].obj +                end +                t+=1 +                #next if data_trn[t].is == :comment +              end +            end +            if ((defined? data_src[s].ocn) \ +            && (data_src[s].ocn.is_a?(Fixnum))) \ +            and ((defined? data_trn[t].ocn) \ +            && (data_trn[t].ocn.is_a?(Fixnum))) \ +            and (data_src[s].ocn == data_trn[t].ocn) +              @m_s,@m_t=s,t +            elsif ((defined? data_src[s].ocn) \ +            && (data_src[s].ocn.is_a?(Fixnum))) \ +            and ((defined? data_trn[t].ocn) \ +            && (data_trn[t].ocn.is_a?(Fixnum))) \ +            and (data_src[s].ocn != data_trn[t].ocn) +              p '--- OCN ---' +              p 'mis-match' +              p data_src[s].ocn if defined? data_src[s].ocn +              p data_src[s].obj if defined? data_src[s].obj +              p data_trn[t].ocn if defined? data_trn[t].ocn +              p data_trn[t].obj if defined? data_trn[t].obj +              p '---' +              p 'previous match' +              p data_src[@m_s].ocn if defined? data_src[@m_s].ocn +              p data_src[@m_s].obj if defined? data_src[@m_s].obj +              p data_trn[@m_t].ocn if defined? data_trn[@m_t].ocn +              p data_trn[@m_t].obj if defined? data_trn[@m_s].obj +              exit +            elsif (((defined? data_src[s].ocn) \ +            && (defined? data_trn[t].ocn)) \ +            and data_src[s].ocn.class != data_trn[t].ocn.class) +              p '--- OCN class ---' +              p 'mis-match' +              p data_src[s].ocn if defined? data_src[s].ocn +              p data_src[s].obj if defined? data_src[s].obj +              p data_trn[t].ocn if defined? data_trn[t].ocn +              p data_trn[t].obj if defined? data_trn[t].obj +              #p '---' +              #p 'previous match' +              #p data_src[@m_s].ocn +              #p data_src[@m_s].obj +              #p data_trn[@m_t].ocn +              #p data_trn[@m_t].obj +            #elsif (defined? data_src[s].ocn != defined? data_trn[t].ocn) \ +            #and (data_src[s].ocn.nil? != data_trn[t].ocn.nil?) +            #  p '--- missing OCN? ---' +            #  p 'mis-match' +            #  p data_src[s].ocn if defined? data_src[s].ocn +            #  p data_src[s].obj +            #  p data_trn[t].ocn if defined? data_trn[t].ocn +            #  p data_trn[t].obj +            else +            end +          end +          notes_s='' +          data_src[s],notes_s=markup(data_src[s]) +          data_src[s],nul=pot_data(data_src[s],notes_s) +          s+=1;t+=1 +        end +        @pot #watch +      end +      def pot_data(dob_src='',notes_s) +        if dob_src.obj !~/(^#{Rx[:meta]}|#{Mx[:br_eof]}|#{Mx[:br_endnotes]})/ +          if defined? dob_src.ocn \ +          and dob_src.ocn.to_s =~/\d+/ +            paranum=dob_src.ocn.to_s +            @p_num=SiSU_Po4aUtils::ParagraphNumber.new(paranum) +          end +          case dob_src.is +          when :heading +            pot_structure.heading(dob_src,notes_s) +          when :para +            pot_structure.para(dob_src,notes_s) +          when :group +            pot_structure.group(dob_src,notes_s) +          when :block +            pot_structure.block(dob_src,notes_s) +          when :verse +            pot_structure.verse(dob_src,notes_s) +          when :code +            pot_structure.code(dob_src,notes_s) +          when :table +            pot_structure.table(dob_src,notes_s) +          end +          if defined? dob_src.idx \ +          and not dob_src.idx.nil? \ +          and not dob_src.idx.empty? +            pot_structure.idx(dob_src) +          end +          #if dob_src ## Clean Prepared Text +          #  dob_src.obj=dob_src.obj.gsub(/<!.+!>/,' '). +          #    gsub(/<:\S+>/,' ') if dob_src ## Clean Prepared Text +          #end +        end +        #[dob_src,dob_trn] +      end +      def markup(dob) +        dob,notes=objects.textface_marks_po4a(dob,:separate) +        [dob,notes] +      end +      def publish(fn,pot) +        content=[] +        content << pot[:open] +        content << pot[:head] +        content << pot[:metadata] +        content << pot[:body] +        content << @@endnotes[:end] if @@endnotes_ +        Output.new(fn,content,@md,@process).po4a +        @@endnotes={ para: [], end: [] } +      end +    end +    class Output <Source +      include SiSU_Param +      include SiSU_Env +      def initialize(fn,content,md,process=:complete) +        @fn,@content,@md,@process=fn,content,md,process +        @file=SiSU_Env::FileOp.new(md,fn) +      end +      def po4a                                                                 #%pot output +        file_pot=@file.write_file.po4a_sst +        #file_pot=(@md.opt.f_pth[:lng] == @md.opt.lng_base) \ +        #? @file.write_file.pot +        #: @file.write_file.po +        @sisu=[] +        emptyline=0 +        @content.each do |para|                                                # this is a hack +          if para.is_a?(Array) \ +          and para.length > 0 +            para.each do |line| +              if line +                line=line.gsub(/\s+$/m,''). +                  gsub(/^\A[ ]*\Z/m,'') +                if line=~/^\A[ ]*\Z/m +                  emptyline+=1 +                else emptyline=0 +                end +                file_pot.puts line if emptyline < 2                     #remove extra line spaces (fix upstream) +              end +            end +          else file_pot.puts para          #unix plaintext # /^([*=-]|\.){5}/ +          end +        end +        file_pot.close +        SiSU_Po4aUtils::PotNumber.new.reset +        #po4a_git +      end +      def po4a_git +        unless @md.opt.act[:maintenance][:set]==:on +          require_relative 'git'                           # git.rb +          git=SiSU_Git::Source.new(@md.opt,@process) +          unless FileTest.directory?(@file.output_path.pot_git.dir) +            git.create_file_structure_git +          end +          if @md.opt.f_pth[:lng] == @md.opt.lng_base +            FileUtils::cp( +              @file.place_file.pot.dir, +              @file.output_path.pot_git.dir +            ) +          else # naive, work on --> +            FileUtils::cp( +              @file.place_file.po.dir, +              @file.output_path.po_git.dir +            ) #unless FileTest.file?(@file.place_file.po_git.dir) +          end +          git.read +        end +      end +    end +  end +end +__END__ +REMOVE +!\|#\|&*\|-\|/\|_\|{\|}\|~\|&# + +tables are problematic, difficult to reconstitute instruction, check + +metadata, move to top? and work on + +footnotes, different types, asterisk, also do you want to have separate +paragraphs, or breaks within one block? + +where no ocn appropriately use ~# or -# or indeed 1~name- + +comments in document, what to do about them, not sure they are currently +retained in dal, could be quite valuable to keep + +Translate Shell +http://www.soimort.org/translate-shell/ +translate.google.com +#+END_SRC + +* src_po4a_sst_ao_sst_set.rb + +#+BEGIN_SRC ruby  :tangle "../lib/sisu/src_po4a_sst_ao_sst_set.rb" +# <<sisu_document_header>> +module SiSU_Po4aUtils +  class Wrap +    def initialize(md,orig='',trans='',n_char_max=76,n_indent=0,n_hang=nil) +      @md,@orig,@trans,@n_char_max,@n_indent= +       md, orig, trans, n_char_max, n_indent +      @n_char_max_extend = n_char_max +      @br="\n" +      @n_hang=n_hang ? n_hang : @n_indent +      @po4a_identify_type='type: SiSU doc' +      #@po4a_identify_type='type: Plain text' +    end +    def line_wrap +      space=' ' +      spaces_indent,spaces_hang= +        "#{@br}#{space*@n_indent}",space*@n_hang +      pot,i=[],0 +      pot_array=(@trans.empty?) ? [@orig] : [@orig,@trans] +      pot_array.each do |pa| +        line=0 +        out=[] +        out[line]='' +        @oldword='' #REMOVE @oldword +        pa=pa.gsub(/<br>/,' <br> '). +          gsub(/#{Mx[:br_nl]}/,"\n\n") +        words=pa.scan(/\n\n|\\\\\\|<br>|\S+/m) +        while words != '' +          word=words.shift +          if not word +            out[line] unless out[line].empty? #check +            break +          elsif word =~/\n\n/ +            word="\n" +            @n_char_max_extend = @n_char_max + out[line].length +            line=line +          elsif (out[line].length + word.length) > (@n_char_max_extend - @n_indent) \ +          and out[line] =~/\S+/ +            @n_char_max_extend = @n_char_max +            out[line].squeeze!(' ') +            line += 1 +          end +          if word +            out[line]=if out[line] \ +            and out[line] !~/\S+$/m +              "#{out[line]}#{word}" +            elsif out[line] \ +            and out[line] =~/\S+/ +              "#{out[line]} #{word}" +            else "#{word.strip}" +            end +          end +          @oldword=word if word =~/\S+/ +        end +        x=out.join(spaces_indent).gsub(/\A\n+/m,'').insert(0,spaces_hang) +        z=[] +        x.split(/\n/).each do |y| +          z << y +        end +        pot[i]=z.join("\n") +        i +=1 +        pot +      end +      trans=(pot.length == 2) ? pot[1] : '' +      po_str=<<WOK +#{pot[0]} +WOK +#{trans} +      po_str +    end +    def no_line_wrap_block +      pot,i=[],0 +      pot_array=(@trans.empty?) ? [@orig] : [@orig,@trans] +      pot_array.each do |pa| +        z=[] +        pa.split(/\n\n/).each do |y| +          z << y if not y.empty? +        end +        pot[i]=z.join("\n") +        i +=1 +        pot +      end +      trans=(pot.length == 2) ? pot[1] : '' +      po_str=<<WOK +#{pot[0]} +WOK +#{trans} +      po_str +    end +    def line_wrap_indent1 +      @n_indent,@n_hang=2,2 +      line_wrap +    end +    def line_wrap_endnote +      @n_indent,@n_hang=4,2 +      line_wrap +    end +    def array_wrap +      if @orig.is_a?(Array) +        @arr=[] +        @orig.each do |line| +          @arr << SiSU_TextUtils::Wrap.new(line,@n_char_max,@n_indent,@n_hang).line_wrap +        end +      end +      @arr +    end +  end +  class HeaderScan +    def initialize(md,para) +      @md,@p=md,para +    end +    def extract(tag,tag_content,type,attrib) +      if dc_tag \ +      and dc_content +        [dc_tag,dc_content,{dc_tag=>dc_content}] +      else nil +      end +    end +    def header(tag,tag_content,type='',attrib='') #this will break stuff and must be tested thoroughly 20060825 +      @tag,@tag_content,@type,@attrib=tag,tag_content,type,attrib +      def label #element +        @tag +      end +      def type +        @type +      end +      def text +        @tag_content +      end +      def info  #element text +        @tag_content +      end +      def attribute +        @attrib +      end +      def element +        @tag +      end +      def attrib +        @attrib +      end +      def el +        @tag +      end +      self +    end +    def start_is_match +      case @p +      when /^#{Mx[:meta_o]}(title)#{Mx[:meta_c]}\s*(.+?)$/                      then header($1,@md.title.full,'meta','dc') #dc 1 +      when /^#{Mx[:meta_o]}(creator|author)#{Mx[:meta_c]}\s*(.+?)$/             then header('creator',$2,'meta','dc')    #dc 2 +      when /^#{Mx[:meta_o]}(subject)#{Mx[:meta_c]}\s*(.+?)$/                    then header($1,$2,'meta','dc')           #dc 3 +      when /^#{Mx[:meta_o]}(description)#{Mx[:meta_c]}\s*(.+?)$/                then header($1,$2,'meta','dc')           #dc 4 +      when /^#{Mx[:meta_o]}(publisher)#{Mx[:meta_c]}\s*(.+?)$/                  then header($1,$2,'meta','dc')           #dc 5 +      when /^#{Mx[:meta_o]}(contributor)#{Mx[:meta_c]}\s*(.+?)$/                then header($1,$2,'meta','dc')           #dc 6 +      when /^#{Mx[:meta_o]}(date)#{Mx[:meta_c]}\s*(.+?)$/                       then header($1,$2,'meta','dc')           #dc 7 +      when /^#{Mx[:meta_o]}(date\.created)#{Mx[:meta_c]}\s*(.+?)$/              then header($1,$2,'meta','extra') +      when /^#{Mx[:meta_o]}(date\.issued)#{Mx[:meta_c]}\s*(.+?)$/               then header($1,$2,'meta','extra') +      when /^#{Mx[:meta_o]}(date\.available)#{Mx[:meta_c]}\s*(.+?)$/            then header($1,$2,'meta','extra') +      when /^#{Mx[:meta_o]}(date\.valid)#{Mx[:meta_c]}\s*(.+?)$/                then header($1,$2,'meta','extra') +      when /^#{Mx[:meta_o]}(date\.modified)#{Mx[:meta_c]}\s*(.+?)$/             then header($1,$2,'meta','extra') +      when /^#{Mx[:meta_o]}(type)#{Mx[:meta_c]}\s*(.+?)$/                       then header($1,$2,'meta','dc')           #dc 8 +      when /^#{Mx[:meta_o]}(format)#{Mx[:meta_c]}\s*(.+?)$/                     then header($1,$2,'meta','dc')           #dc 9 +      when /^#{Mx[:meta_o]}(identifier)#{Mx[:meta_c]}\s*(.+?)$/                 then header($1,$2,'meta','dc')           #dc 10 +      when /^#{Mx[:meta_o]}(source)#{Mx[:meta_c]}\s*(.+?)$/                     then header($1,$2,'meta','dc')           #dc 11 +      when /^#{Mx[:meta_o]}(language)#{Mx[:meta_c]}\s*(.+?)$/                   then header($1,$2,'meta','dc')           #dc 12 +      when /^#{Mx[:meta_o]}(relation)#{Mx[:meta_c]}\s*(.+?)$/                   then header($1,$2,'meta','dc')           #dc 13 +      when /^#{Mx[:meta_o]}(coverage)#{Mx[:meta_c]}\s*(.+?)$/                   then header($1,$2,'meta','dc')           #dc 14 +      when /^#{Mx[:meta_o]}(rights)#{Mx[:meta_c]}\s*(.+?)$/                     then header($1,$2,'meta','dc')           #dc 15 +      when /^#{Mx[:meta_o]}(keywords)#{Mx[:meta_c]}\s*(.+?)$/                   then header($1,$2,'meta','extra') +      when /^#{Mx[:meta_o]}(copyright)#{Mx[:meta_c]}\s*(.+?)$/                  then header($1,$2,'meta','extra') +      when /^#{Mx[:meta_o]}(translator|translated_by)#{Mx[:meta_c]}\s*(.+?)$/   then header('translator',$2) +      when /^#{Mx[:meta_o]}(illustrator|illustrated_by)#{Mx[:meta_c]}\s*(.+?)$/ then header('illustrator',$2) +      when /^#{Mx[:meta_o]}(prepared_by)#{Mx[:meta_c]}\s*(.+?)$/                then header($1,$2,'meta','extra') +      when /^#{Mx[:meta_o]}(digitized_by)#{Mx[:meta_c]}\s*(.+?)$/               then header($1,$2,'meta','extra') +      when /^#{Mx[:meta_o]}(comments?)#{Mx[:meta_c]}\s*(.+?)$/                  then header($1,$2,'meta','extra') +      when /^#{Mx[:meta_o]}(abstract)#{Mx[:meta_c]}\s*(.+?)$/                   then header($1,$2,'meta','extra') +      when /^#{Mx[:meta_o]}(tags?)#{Mx[:meta_c]}\s*(.+?)$/                      then header($1,$2,'meta','extra') +      when /^#{Mx[:meta_o]}(catalogue)#{Mx[:meta_c]}\s*(.+?)$/                  then header($1,$2,'meta','extra') +      when /^#{Mx[:meta_o]}(class(?:ify)?_loc)#{Mx[:meta_c]}\s*(.+?)$/          then header('classify_loc',$2,'meta','extra') +      when /^#{Mx[:meta_o]}(class(?:ify)?_dewey)#{Mx[:meta_c]}\s*(.+?)$/        then header('classify_dewey',$2,'meta','extra') +      when /^#{Mx[:meta_o]}(class(?:ify)?_pg)#{Mx[:meta_c]}\s*(.+?)$/           then header('classify_pg',$2,'meta','extra') +      when /^#{Mx[:meta_o]}(class(?:ify)?_isbn)#{Mx[:meta_c]}\s*(.+?)$/         then header('classify_isbn',$2,'meta','extra') +      when /^#{Mx[:meta_o]}(toc|structure)#{Mx[:meta_c]}\s*(.+?)$/              then header('structure',$2,'process','instruct') +      when /^#{Mx[:meta_o]}(level|page|markup)#{Mx[:meta_c]}\s*(.+?)$/          then header('markup',$2,'process','instruct') +      when /^#{Mx[:meta_o]}(bold)#{Mx[:meta_c]}\s*(.+?)$/                       then header($1,$2,'process','instruct') +      when /^#{Mx[:meta_o]}(italics|itali[sz]e)#{Mx[:meta_c]}\s*(.+?)$/         then header('italicize',$2,'process','instruct') +      when /^#{Mx[:meta_o]}(vocabulary|wordlist)#{Mx[:meta_c]}\s*(.+?)$/        then header('vocabulary',$2,'process','instruct') +      when /^#{Mx[:meta_o]}(css|stylesheet)#{Mx[:meta_c]}\s*(.+?)$/             then header('css',$2,'process','instruct') +      when /^#{Mx[:meta_o]}(links)#{Mx[:meta_c]}\s*(.+?)$/                      then header($1,$2,'process','instruct') +      when /^#{Mx[:meta_o]}(prefix)#{Mx[:meta_c]}\s*(.+?)$/                     then header($1,$2,'process','instruct') #add a & b +      when /^#{Mx[:meta_o]}(suffix)#{Mx[:meta_c]}\s*(.+?)$/                     then header($1,$2,'process','instruct') +      when /^#{Mx[:meta_o]}(information)#{Mx[:meta_c]}\s*(.+?)$/                then header($1,$2,'process','instruct') +      when /^#{Mx[:meta_o]}(contact)#{Mx[:meta_c]}\s*(.+?)$/                    then header($1,$2,'process','instruct') +      when /^#{Mx[:meta_o]}(rcs|cvs)#{Mx[:meta_c]}\s*(.+?)$/                    then header('version',$2,'process','instruct') +      else nil +      end +    end +    def dublin +      (@p =~/^#{Mx[:meta_o]}\S+?#{Mx[:meta_c]}/) \ +      ? start_is_match +      : nil +    end +    def meta +      (@p =~/^#{Mx[:meta_o]}\S+?#{Mx[:meta_c]}/) \ +      ? start_is_match +      : nil +    end +  end +  class ParagraphNumber +    def initialize(paranum) +      @paranum=/(\d+)/m.match(paranum)[1] +    end +    def display +      @paranum.gsub(/(\d+)/,'#\1') +    end +  end +  class PotNumber +    @@n=0 +    def initialize +      @@n +=2 +    end +    def num +      @@n +    end +    def reset +      @@n=0 +    end +  end +end +__END__ +#+END_SRC + +* src_po4a_sstm.rb + +#+BEGIN_SRC ruby  :tangle "../lib/sisu/src_po4a_sstm.rb" +# <<sisu_document_header>> +module SiSU_Markup +  require_relative 'src_shared'                         # src_shared.rb +    include SiSU_Source +  require_relative 'src_po4a_share'                     # src_po4a_share.rb +  require_relative 'se'                                 # se.rb +    include SiSU_Env +  class Source_Po4a < SiSU_Source::SiSUpodSource +    def initialize(opt,build=nil,place=nil) +      super(opt,build,place) +      @opt=opt +      md=SiSU_Param::Parameters.new(opt).get +      @file=SiSU_Env::FileOp.new(md,opt.fno) +    end +    def dir_mk(dir) +      unless FileTest.directory?(dir) +        FileUtils::mkdir_p(dir) +      end +    end +    def make_paths +      dir_mk(@file.output_path.pot.dir) +      dir_mk(@file.output_path.po.dir) +    end +    def language +      def source_language_selected_str +        @opt.act[:po4a_lang][:src] \ +        ? @opt.act[:po4a_lang][:src] +        : 'en' +      end +      self +    end +    def read +      unless @opt.act[:quiet][:set]==:on +        (@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], +            'Share document markup text source', +            @opt.fns +          ).cyan_hi_blue +        : SiSU_Screen::Ansi.new( +            @opt.act[:color_state][:set], +            'Share document markup text source', +            @opt.fns +          ).cyan_title_hi +      end +      make_paths +      if FileTest.directory?(@path_pod[:fnb]) +        FileUtils::mkdir_p(@file.output_path.src.dir) \ +          unless FileTest.directory?(@file.output_path.src.dir) +        v=(@opt.act[:maintenance][:set]==:on) \ +        ? 'v' : '' +        system(%{ +          #rsync -a#{v} #{@path_pod[:fnb]}/sisupod/doc/* #{@file.output_path.po4a.dir} +          rsync -a#{v} #{@path_pod[:fnb]}/sisupod/doc/#{language.source_language_selected_str}* #{@file.output_path.po4a.dir} +          chbk=`pwd` +          cd #{@file.output_path.sisupod.dir} +          for I in `find -type d` ; do chmod 755 $I ; done +          for I in `find -type f` ; do chmod 644 $I ; done +          cd ${chbk} +        }) +        md=SiSU_Param::Parameters.new(@opt).get +        file=SiSU_Env::FileOp.new(md) +        SiSU_Po4a_Project::Po4aCfg.new(@opt,file).song +        SiSU_Po4a_Project::Po4aProject.new(@opt,file).song +      else +        if (@opt.act[:verbose][:set]==:on \ +        || @opt.act[:verbose_plus][:set]==:on \ +        || @opt.act[:maintenance][:set]==:on) +          SiSU_Screen::Ansi.new( +            '', +            "#{@opt.fno} not available" +          ).blue_tab +        end +      end +    end +  end +end +__END__ +#+END_SRC + +* src_shared.rb + +#+BEGIN_SRC ruby  :tangle "../lib/sisu/src_shared.rb" +# <<sisu_document_header>> +module SiSU_Source +  include SiSU_Env +  class SiSUpodSource +    require_relative 'se'                               # se.rb +    require_relative 'se_hub_particulars'               # se_hub_particulars.rb +    require_relative 'utils_composite'                  # utils_composite.rb +    include SiSU_Composite_Doc_Utils                    # composite doc, .ssm, extract all related insert files, array of filenames test +    def initialize(opt,build=nil,place=nil) +      @opt=opt +      @date=SiSU_Env::InfoDate.new.dt +      @env=SiSU_Env::InfoEnv.new(opt.fns) +      #@ver=SiSU_Env::InfoVersion.instance.get_version +      @v=(@opt.act[:verbose_plus][:set]==:on \ +      || @opt.act[:maintenance][:set]==:on) \ +      ? 'v' : '' +      @particulars=SiSU_Particulars::CombinedSingleton.instance.get_all(opt) +      @file=@particulars.file +      @local_path="#{@file.output_path.sisupod.dir}" +      processing_sisupod=@env.processing_path.processing_sisupod(opt) +      processing_sisupod.make +      path_pod=processing_sisupod.paths[:sisupod] +      path_pod_fnb=processing_sisupod.paths[:fnb] +      FileUtils::mkdir_p(path_pod) unless FileTest.directory?(path_pod) +      @path_pod={ +        fnb:       path_pod_fnb, +        pod:       path_pod, +        doc:       path_pod + '/' + Gt[:doc] + '/' + opt.lng, +        po:        path_pod + '/' + Gt[:po]  + '/' + opt.lng, +        pot:       path_pod + '/' + Gt[:pot], +        conf:      path_pod + '/' + Gt[:conf], +        image:     path_pod + '/' + Gt[:image], +        audio:     path_pod + '/' + Gt[:audio], +        video:     path_pod + '/' + Gt[:video], +      } +    end +    def read +      unless @opt.act[:quiet][:set]==:on +        (@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], +          'Assemble SiSU source', +          "[#{@opt.f_pth[:lng_is]}] #{@opt.fno}"). +          green_hi_blue +        : '' +      end +      unless @opt.fns.empty? +        directories +        doc_import_list=composite_and_imported_filenames_array(@opt.fno) +        doc_import_list=[@opt.fno, doc_import_list].flatten +        image_extraction(doc_import_list) +        language_versions +      end +    end +    def images_extract(f,images)                                                # consider using param info +      rgx_image=/(?:^|[^_\\])\{(?:\s*|\~\^\s+)(\S+?\.(?:png|jpg|gif)\b)/m +      if f !~/^%+\s/ \ +      and f =~rgx_image +        images << f.scan(rgx_image).uniq +      end +      images.flatten +    end +    def image_extraction(doc_import_list) +      @rgx_rb_image=/["']\S*?([a-zA-Z0-9_-]+?\.(?:png|jpg|gif))["']/ +      @rgx_image=/(?:^|[^_\\])\{\s*(\S+?\.(?:png|jpg|gif))/ +      doc_import_dir=@opt.sub_location +      images=[] +      if doc_import_list.length > 0 +        doc_import_list=doc_import_list.uniq.flatten +        doc_import_list.each do |fn| +          file_array=IO.readlines(fn,'') +          file_array.each do |f|                                               #% work area +            f=f.gsub(/<:=(\S+?)>/,'{ c_\1.png 14x14 }image')                   # embedded symbol (image) +            if f !~/^%+\s/ \ +            and f =~@rgx_image +              images=images_extract(f,images) +            end +          end +        end +      end +      gi=SiSU_Env::GetInit.new +      unless FileTest.file?("#{@path_pod[:conf]}/#{gi.makefile_name}") +        if gi.makefile \ +        && FileTest.file?(gi.makefile) +          FileUtils::mkdir_p(@path_pod[:conf]) \ +            unless FileTest.directory?(@path_pod[:conf]) +          FileUtils::cp(gi.makefile,"#{@path_pod[:conf]}/#{gi.makefile_name}") +        end +        #get images from makefile, consider placing in param +      end +      if images \ +      and images.length > 1 +        images=images.flatten.uniq +        images.delete_if {|x| x =~/https?:\/\// } +        #images=images.sort +        FileUtils::mkdir_p(@path_pod[:image]) +        images_pwd=@opt.image_src_path +        ##sequence copies base images, defaults used in all html outputs +          #image_source_base='/usr/share/sisu/image' +          #dir_pwd=Dir.pwd +          #Dir.chdir(image_source_base) +          #base_images=Dir.glob('*') +          #base_images.each do |i| +          #  FileUtils::cp_r(i,"#{images_path_pod}/#{i}") +          #end +          #Dir.chdir(dir_pwd) +        if FileTest.directory?(images_pwd) +          images=images.uniq +          images.each do |i| +            if FileTest.file?("#{images_pwd}/#{i}") +              FileUtils::cp( +                "#{images_pwd}/#{i}", +                "#{@path_pod[:image]}/#{i}" +              ) +            else +              STDERR.puts \ +                %{\t*WARN* did not find image - } \ +                + %{"#{images_pwd}/#{i}" } \ +                + %{[#{__FILE__}:#{__LINE__}]} +            end +          end +        else +          STDERR.puts \ +            %{\t*WARN* did not find - } \ +            + %{#{images_pwd} #{@path_pod[:image]} } \ +            + %{[#{__FILE__}:#{__LINE__}]} +        end +      end +      if doc_import_list.length > 0 \ +      and @opt.fno =~/\.ssm$/ +        doc_import_list.each do |f| +          if FileTest.file?("#{@opt.base_path}#{doc_import_dir}/#{f}") +            FileUtils::cp( +              "#{@opt.base_path}#{doc_import_dir}/#{f}", +              "#{@path_pod[:doc]}/#{f}" +            ) +          else +            STDERR.puts \ +              %{\t*WARN* did not find image - } \ +              + %{"#{@opt.base_path}#{doc_import_dir}/#{f}" } \ +              + %{[#{__FILE__}:#{__LINE__}]} +          end +        end +      end +    end +    def language_versions +      x=@env.document_language_versions_found                                  #check multiple document language versions (param not used) +      doc_import_dir=@opt.sub_location +      if x[:f] \ +      and x[:f].length > 0                                                     #store multiple document language versions, sisupod +        x[:f].each do |f| +          FileUtils::mkdir_p(@path_pod[:doc]) \ +            unless FileTest.directory?(@path_pod[:doc]) +          if f[:f] =~/\~(\S{2,3})\.ss[tm]$/ +            lng_f=$1 +            if @opt.lng == lng_f +              if @opt.fno =~/\.ssm$/ +                if FileTest.file?("#{@opt.base_path}#{doc_import_dir}/#{f[:f]}") +                  FileUtils::cp( +                    "#{@opt.base_path}#{doc_import_dir}/#{f[:f]}", +                    "#{@path_pod[:doc]}/#{f[:n]}" +                  ) +                else +                  STDERR.puts \ +                    %{\t*WARN* did not find - } \ +                    + %{"#{@opt.base_path}#{doc_import_dir}/#{f[:f]}" } \ +                    + %{[#{__FILE__}:#{__LINE__}]} +                end +              else +                if FileTest.file?("#{@opt.base_path}/#{f[:f]}") +                  cpy= :no +                  cpy=if f[:f] =~ /^#{@opt.f_pth[:lng_is]}\// \ +                  or f[:f] =~ /~#{@opt.f_pth[:lng_is]}\.sst/ +                    :yes +                  elsif f[:f] !~ /^(?:#{Px[:lng_lst_rgx]})\/|~(?:#{Px[:lng_lst_rgx]})\.sst/ \ +                  and @opt.f_pth[:lng_is] == 'en' +                    :yes +                  else :no +                  end +                  if cpy == :yes +                    FileUtils::cp( +                      "#{@opt.base_path}/#{f[:f]}", +                      "#{@path_pod[:doc]}/#{f[:n]}" +                    ) +                  end +                else +                  STDERR.puts \ +                    %{\t*WARN* did not find - } \ +                    + %{"#{@opt.base_path}/#{f[:f]}" } \ +                    + %{[#{__FILE__}:#{__LINE__}]} +                end +              end +            end +          else +            if @opt.fno =~/\.ssm$/ +              if FileTest.file?("#{@opt.base_path}#{doc_import_dir}/#{f[:f]}") +                FileUtils::cp_r( +                  "#{@opt.base_path}#{doc_import_dir}/#{f[:f]}", +                  "#{@path_pod[:doc]}/#{f[:n]}" +                ) +              else +                STDERR.puts \ +                  %{\t*WARN* did not find - } \ +                  + %{"#{@opt.base_path}#{doc_import_dir}/#{f[:f]}" } \ +                  + %{[#{__FILE__}:#{__LINE__}]} +              end +            else +              if FileTest.file?("#{@opt.base_path}#{doc_import_dir}/#{f[:f]}") +                cpy= :no +                cpy=if f[:f] =~ /^#{@opt.f_pth[:lng_is]}\// \ +                or f[:f] =~ /~#{@opt.f_pth[:lng_is]}\.sst/ +                  :yes +                elsif f[:f] !~ /^(?:#{Px[:lng_lst_rgx]})\/|~(?:#{Px[:lng_lst_rgx]})\.sst/ \ +                and @opt.f_pth[:lng_is] == 'en' +                  :yes +                else :no +                end +                if cpy == :yes +                  FileUtils::cp( +                    "#{@opt.base_path}#{doc_import_dir}/#{f[:f]}", +                    "#{@path_pod[:doc]}/#{f[:n]}" +                  ) +                end +              else +                STDERR.puts \ +                  %{\t*WARN* did not find - } \ +                  + %{"#{@opt.base_path}#{doc_import_dir}/#{f[:f]}" } \ +                  + %{[#{__FILE__}:#{__LINE__}]} +              end +            end +          end +        end +      end #NB not all possibilies met, revisit, also in case of composite file may wish to add README +    end +    def directories +      SiSU_Env::InfoEnv.new.sisupod_v4(@opt) +    end +  end +end +__END__ +question?:                   should you permit the packing of multiple documents in single .xz ? + +  open @opt.fns, parse file +    extract from file content: +      images and copy each image from whatever image source to _sisu/sisupod/sisu/_sisu/image + +   remove previously existing contents of _/sisu/sisupod & +   make directory structure: + +v3 --> +   _sisu +     sisupod +       doc +         manifest.txt +         en/content.sst                [file content] +         fr/content.sst +         _sisu +           conf +           image (ln -s ../../image) +           audio (ln -s ../../audio) +           video (ln -s ../../video) +       image                           [all images for specific document gathered here] +       audio +       video + +v2 --> +   _sisu +     sisupod +       content.sst                     [file content] +       filename.sst                    [link to content.sst] +       _sisu/ +         image/                        [all images for specific document gathered here] + +sisu +  _sisu +    sisurc.yml +    convert/ +    standard_terms/ +    image +    processing +      ao/ +      tex/ +      texinfo/ +      tune/ +    sisupod + +special case + +composite file (master), e.g. +SiSU.ssm +#+END_SRC + +* document header + +#+NAME: sisu_document_header +#+BEGIN_SRC text +encoding: utf-8 +- Name: SiSU + +  - Description: documents, structuring, processing, publishing, search +    src + +  - 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 diff --git a/org/sst.org b/org/sst.org new file mode 100644 index 00000000..5cfe98d6 --- /dev/null +++ b/org/sst.org @@ -0,0 +1,1713 @@ +-*- mode: org -*- +#+TITLE:       sisu sst +#+DESCRIPTION: documents - structuring, various output representations & search +#+FILETAGS:    :sisu:sst: +#+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 + +* sst_from_xml.rb + +#+BEGIN_SRC ruby  :tangle "../lib/sisu/sst_from_xml.rb" +# <<sisu_document_header>> +module SiSU_sstFromXML +  require_relative 'se'                                 # se.rb +  class Convert +    begin +      require 'rexml/document' +        include REXML +    rescue LoadError +      SiSU_Utils::CodeMarker.new(__LINE__,__FILE__,:fuchsia). +        error('rexml/document NOT FOUND (LoadError)') +    end +    def initialize(opt) +      @opt=opt +      @sisu,@sisu_base=[],[] +      @ver=SiSU_Env::InfoVersion.instance.get_version +    end +    def tell(filename,type) +      SiSU_Screen::Ansi.new( +        @opt.act[:color_state][:set], +        "XML #{type} to SiSU sst", +        "#{filename} --> #{filename}.sst" +      ).green_hi_blue +    end +    def read +      xml_to_sisu +    end +    def markup_head(text) +      text.strip! +      text.gsub!(/(?:\s*\n|\s\s+)/,' ') +      text.gsub!(/<header class=['"]\S+?['"]>(.+?)<\/header>/,'\1') +      text.gsub!(/<(\w+)>(.+?)<\/\w+>/,'@\1: \2') +      text.gsub!(/<header class=['"]\S+?['"]><(\w+)>(.+?)<\/\w+><\/header>/,'@\1: \2') +      text.gsub!(/\s +/,' ') +      text.strip! +      text + "\n\n" +    end +    def markup(text) +      text.strip! +      text.gsub!(/(?:\s*\n|\s\s+)/,' ') +      text.gsub!(/<text class='h1'>(.+?)<\/text>/,':A~ \1') +      text.gsub!(/<text class='h2'>(.+?)<\/text>/,':B~ \1') +      text.gsub!(/<text class='h3'>(.+?)<\/text>/,':C~ \1') +      text.gsub!(/<text class='h4'>(.+?)<\/text>/,'1~ \1') +      text.gsub!(/<text class='h5'>(.+?)<\/text>/,'2~ \1') +      text.gsub!(/<text class='h6'>(.+?)<\/text>/,'3~ \1') +      text.gsub!(/<text class='norm'>(.+?)<\/text>/,'\1') +      text.gsub!(/<endnote symbol='norm'>(.+?)<\/endnote>/,'~{ \1 }~') +      text.gsub!(/<br ?\/>/,'<br>') +      text.gsub!(/<i>(.+?)<\/i>/,'/{\1}/') +      text.gsub!(/<b>(.+?)<\/b>/,'*{\1}*') +      text.gsub!(/<u>(.+?)<\/u>/,'_{\1}_') +      text.gsub!(/<sem:([a-z_]+)\s+depth=['"]zero['"]>(\s*.+?\s*)<\/sem:\1>/,';{ \2 };\1') +      text.gsub!(/<sem:([a-z_]+)\s+depth=['"]one['"]>(\s*.+?\s*)<\/sem:\1>/,':{ \2 }:\1') +      text.gsub!(/<sem:([a-z_]+)\s+depth=['"]many['"]>(\s*.+?\s*)<\/sem:\1>/,'\1:{ \2 }:\1') +      text.gsub!(/<sem:([a-z_]+)>(\s*.+?\s*)<\/sem:\1>/,'\1:{ \2 }:\1') +      text.gsub!(/\s +/,' ') +      text.strip! +      text + "\n\n" +    end +    def sax +      out_file=File.new(@output_file_name,'w') +      head=@doc.root.get_elements('//head/header') +      body=@doc.root.get_elements('//object/text') +      out_file.puts "% SiSU text #{@ver.version} (generated from a SiSU XML markup representation)\n\n" +      head.each do |x| +        if x.name=='header' +          head=markup_head(x.to_s) +          out_file.puts head +        end +      end +      body.each do |x| +        if x.name=='text' +          body=markup(x.to_s) +          out_file.puts body +        end +      end +    end +    def node +      sax +    end +    def dom +      raise "#{__FILE__}::#{__LINE__} xml dom representation to sst not yet implemented (experimental simple xml representations sax and node to sst are in place)." +    end +    def xml_to_sisu +      unless @opt.files.empty? +        @opt.files.each do |xml| +          @sisu_base=[] +          if xml =~/\.sx[sdn]\.xml$/ +            begin +              @doc_str=IO.readlines(xml,'').join("\n") +              @output=File.new("#{xml}.sst",'w') +              @doc=REXML::Document.new(@doc_str) +              @output_file_name="#{Dir.pwd}/#{xml}.sst" +              @el=[] +            rescue REXML::ParseException +            end +          end +          if xml =~/\.sxs\.xml$/ +            unless @opt.act[:quiet][:set]==:on +              tell(xml,'sax') +            end +            sax +          elsif xml =~/\.sxd\.xml$/ +            unless @opt.act[:quiet][:set]==:on +              tell(xml,'dom') +            end +            dom +          elsif xml =~/\.sxn\.xml$/ +            unless @opt.act[:quiet][:set]==:on +              tell(xml,'node') +            end +            node +          else puts "filename not recognised: << #{xml} >>" +          end +          @output << @sisu_base +        end +      else puts '.xml file for conversion to sisu expected' +      end +      puts @opt.files.inspect +    end +  end +end +__END__ +#+END_SRC + +* sst_to_s_xml_sax.rb + +#+BEGIN_SRC ruby  :tangle "../lib/sisu/sst_to_s_xml_sax.rb" +# <<sisu_document_header>> +module SiSU_SimpleXML_ModelSax +  require_relative 'se_hub_particulars'                 # se_hub_particulars.rb +    include SiSU_Particulars +  require_relative 'dp'                                 # dp.rb +    include SiSU_Param +  require_relative 'se'                                 # se.rb +    include SiSU_Env +  require_relative 'ao_doc_str'                         # ao_doc_str.rb +  require_relative 'xml_shared'                         # xml_shared.rb +    include SiSU_XML_Munge +  require_relative 'shared_sem'                         # shared_sem.rb +  require_relative 'xml_format'                         # xml_format.rb +    include SiSU_XML_Format +  require_relative 'rexml'                              # rexml.rb +    include SiSU_Rexml +  @@alt_id_count=0 +  @@tablefoot='' +  class Convert +    @@fns=nil +    def initialize(opt) +      @opt=opt +      @particulars=SiSU_Particulars::CombinedSingleton.instance.get_env_md(opt) +    end +    def read +      begin +        @md=@particulars.md #bug, relies on info persistence, assumes -m has previously been run +        @env=@particulars.env +        SiSU_Screen::Ansi.new( +          @opt.act[:color_state][:set], +          'invert', +          'XML SAX', +          "#{@md.fns} -> #{@md.fn[:sxs]}" +        ).colorize unless @opt.act[:quiet][:set]==:on +        if (@opt.act[:verbose_plus][:set]==:on \ +        || @opt.act[:maintenance][:set]==:on) +          SiSU_Screen::Ansi.new( +            @opt.act[:color_state][:set], +            @opt.fns, +            "#{Dir.pwd}/#{@md.fn[:sxs]}" +          ).flow +        end +        unless @@fns==@opt.fns +          @@fns=@opt.fns +          @@fns_array=[] +        end +        @fns_array=if @@fns_array.empty?; read_fnm +        else @@fns_array.dup #check +        end +        SiSU_SimpleXML_ModelSax::Convert::Songsheet.new(@fns_array,@particulars).songsheet +      rescue +        SiSU_Errors::Rescued.new($!,$@,@opt.cmd,@opt.fns).location do +          __LINE__.to_s + ':' + __FILE__ +        end +      ensure #file closed in songsheet +      end +    end +    def read_fnm +      ao=[] +      if FileTest.file?("#{Dir.pwd}/#{@opt.fns}") +        ao=IO.readlines("#{Dir.pwd}/#{@opt.fns}","\n\n") +      else STDERR.puts 'Error' +      end +    end +    private +    class Songsheet +      def initialize(data,particulars) +        @data,@particulars,@env,@md=data,particulars,particulars.env,particulars.md +      end +      def songsheet +        begin +          SiSU_SimpleXML_ModelSax::Convert::Scroll.new(@data,@particulars).songsheet +          if (@md.opt.act[:verbose][:set]==:on \ +          || @md.opt.act[:verbose_plus][:set]==:on \ +          || @md.opt.act[:maintenance][:set]==:on) +            SiSU_SimpleXML_ModelSax::Convert::Tidy.new(@md,@env).xml # test wellformedness, comment out when not in use +          end +          SiSU_Rexml::Rexml.new(@md,@md.fn[:sxs]).xml if @md.opt.act[:maintenance][:set]==:on # test rexml parsing, comment out when not in use #debug +        rescue +          SiSU_Errors::Rescued.new($!,$@,@md.opt.cmd,@md.fns).location do +            __LINE__.to_s + ':' + __FILE__ +          end +        ensure +        end +      end +    end +    class Scroll +      require_relative 'txt_shared'                     # txt_shared.rb +      require_relative 'css'                            # css.rb +        include SiSU_TextUtils +      @@xml={ body: [], open: [], close: [], head: [] } +      def initialize(data='',particulars='') +        @data,@env,@md=data,particulars.env,particulars.md +        @regx=/^(?:#{Mx[:mk_o]}:p[bn]#{Mx[:mk_c]}\s*)?(?:#{Mx[:lv_o]}[1-9]:(\S*)#{Mx[:lv_c]})?(.+)/ +        @tab="\t" +        if @md +          @trans=SiSU_XML_Munge::Trans.new(@md) +        end +        @sys=SiSU_Env::SystemCall.new +      end +      def songsheet +        pre +        markup +        post +        publish +      end +    protected +      def embedded_endnotes(para='') +        para.gsub!(/~\{(.+?)\}~/,'<endnote symbol="norm">\1</endnote> ') +        para.gsub!(/~\[([*+])\s+(.+?)\]~/,'<endnote symbol="\1">\2</endnote> ') +      end +      def xml_head(meta) +        txt=meta.text +        txt.gsub!(/\/{(.+?)}\//,'<i>\1</i>') +        txt.gsub!(/[*!]{(.+?)}[*!]/,'<b>\1</b>') +        txt.gsub!(/_{(.+?)}_/,'<u>\1</u>') +        txt.gsub!(/-{(.+?)}-/,'<del>\1</del>') +        txt.gsub!(/<br(?: \/)?>/,'<br />') +        txt.gsub!(/ & /,' and ') +        @@xml[:head] <<<<WOK +#{@tab}<header class="#{meta.attrib}"> +#{@tab*2}<#{meta.el}> +#{@tab*3}#{txt} +#{@tab*2}</#{meta.el}> +#{@tab}</header> +WOK +      end +      def xml_sc(md='') +        sc=if @md.sc_info +          <<WOK +    <source_control> +      <sc class="sourcefile"> +        #{@md.sc_filename} +      </sc> +      <sc class="number"> +        #{@md.sc_number} +      </sc> +      <sc class="date"> +        #{@md.sc_date} +      </sc> +    </source_control> +WOK +        else '' +        end +        @@xml[:sc]=sc +      end +      def xml_structure(para='',lv='',hname='') #extracted endnotes +        lv=lv.to_i +        lv=nil if lv==0 +        embedded_endnotes(para) +        if para[@regx] +          paragraph="#{para[@regx,2]}" +          util=SiSU_TextUtils::Wrap.new(paragraph,70) +          wrapped=util.line_wrap +        end +        @@xml[:body] << "#{@tab*0}<object>" if para[@regx] +        @@xml[:body] << "#{@tab*1}" << "\n" if para[@regx] +        @@xml[:body] << if lv; %{#{@tab*1}<text class="h#{lv}">\n#{@tab*2}#{wrapped}\n#{@tab*1}</text>\n} << "\n" +        elsif wrapped =~/\A%%?\s+/; %{<!--\n#{@tab*1}<text class="comment">\n#{@tab*2}#{wrapped}\n#{@tab*1}</text>\n-->\n} # comments +        else                        %{#{@tab*1}<text class="norm">\n#{@tab*2}#{wrapped}\n#{@tab*1}</text>\n} # main text, contents, body KEEP +        end +        @@xml[:body] << "#{@endnotes}" if @endnotes # main text, endnotes KEEP +        @@xml[:body] << "#{@tab*0}</object>" << "\n" if para[@regx] +        @endnotes=[] +      end +      def block_structure(para='') +        para.gsub!(/<:block(?:-end)?>/,'') +        para.strip! +        @@xml[:body] << %{#{@tab*0}<object>} +        @@xml[:body] << %{#{@tab*1}<text class="block">#{@tab*1}\n} +        @@xml[:body] << %{#{@tab*2}#{para}#{@tab*1}\n} +        @@xml[:body] << %{#{@tab*1}</text>\n} +        @@xml[:body] << "#{@tab*0}</object>" +      end +      def group_structure(para='') +        para.gsub!(/<:group(?:-end)?>/,'') +        para.strip! +        @@xml[:body] << %{#{@tab*0}<object>} +        @@xml[:body] << %{#{@tab*1}<text class="group">#{@tab*1}\n} +        @@xml[:body] << %{#{@tab*2}#{para}#{@tab*1}\n} +        @@xml[:body] << %{#{@tab*1}</text>\n} +        @@xml[:body] << "#{@tab*0}</object>" +      end +      def poem_structure(para='') +        para.gsub!(/<:verse(?:-end)?>/,'') +        para.strip! +        @@xml[:body] << %{#{@tab*0}<object>} +        @@xml[:body] << %{#{@tab*1}<text class="verse">#{@tab*1}\n} +        @@xml[:body] << %{#{@tab*2}#{para}#{@tab*1}\n} +        @@xml[:body] << %{#{@tab*1}</text>\n} +        @@xml[:body] << "#{@tab*0}</object>" << "\n" +      end +      def code_structure(para='') +        para.gsub!(/<:code(?:-end)?>/,'') +        para.strip! +        @@xml[:body] << %{#{@tab*0}<object>} +        @@xml[:body] << %{#{@tab*1}<text class="code">#{@tab*1}\n} +        @@xml[:body] << %{#{@tab*2}#{para}#{@tab*1}\n} +        @@xml[:body] << %{#{@tab*1}</text>\n} +        @@xml[:body] << "#{@tab*0}</object>" << "\n" +      end +      def table_structure(table='') #tables +        @@xml[:body] << %{#{@tab*0}<object>} +        @@xml[:body] << %{#{@tab*1}#{table}\n#{@tab*1}\n} # unless lv  # main text, contents, body KEEP +        @@xml[:body] << "#{@tab*0}</object>" << "\n" #if para[@regx] +        @endnotes=[] +      end +      def tidywords(wordlist) +        wordlist.each do |x| +          x.gsub!(/&/,'&') unless x =~/&\S+;/ +        end +      end +      def xml_clean(para) +        para.gsub!(/#{Mx[:gl_o]}[1-9]:\S*?#{Mx[:gl_c]}/,'') #Danger, watch +        para +      end +      def markup +        data=[] +        xml_sc(@md) +        @endnotes,@level,@cont,@copen,@xml_contents_close=[],[],[],[],[] +        @rcdc=false +        (0..6).each { |x| @cont[x]=@level[x]=false } +        (4..6).each { |x| @xml_contents_close[x]='' } +        @data.each do |para| +          data << SiSU_AO_DocumentStructureExtract::Structure.new(@md,para).structure #takes on Mx marks +        end +        data.each do |para| +          if para !~/^\s*(?:%+ |<:code>)/ +            if @md.sem_tag and para =~/[:;]\{|\}[:;]/ +              para=@trans.xml_semantic_tags(para) +            end +            if para =~/[:;]\{|\}[:;]/ +              para=SiSU_Sem::Tags.new(para,@md).rm.all +            end +          end +          para=@trans.markup_light(para) +          @trans.char_enc.utf8(para) if @sys.locale =~/utf-?8/i #% utf8 +          para.gsub!(/^@(\S+?):/,"#{Mx[:lv_o]}@\\1#{Mx[:lv_c]}") +          if para =~/\A#{Mx[:lv_o]}@(\S+?)#{Mx[:lv_c]}\s*(.+?)\Z/m # for headers +            d_meta=SiSU_TextUtils::HeaderScan.new(@md,para).meta +            if d_meta; xml_head(d_meta) +            end +          end +          para='' if para=~/#{Mx[:lv_o]}@\S+?#{Mx[:lv_c]}/ +          if @rcdc==false \ +          and (para =~/~metadata/ or para =~/^1~meta\s+Document Information/) +            @rcdc=true +          end +          if para !~/(^@\S+?:|^\s*$|<ENDNOTES>|<EOF>)/ +            @sto=SiSU_text_parts::SplitTextObject.new(@md,para).lev_segname_para +            unless @rcdc +              SiSU_XML_Format::FormatScroll.new(@md,@sto.text) if @sto.format =~/i[1-9]|ordinary/ +              case @sto.format +              when /^(1):(\S*)/ +                xml_clean(para) +                xml_structure(para,$1,$2) +                para=@sto.lev_para_ocn.heading_body1 +              when /^(2):(\S*)/ +                xml_clean(para) +                xml_structure(para,$1,$2) +                para=@sto.lev_para_ocn.heading_body2 +              when /^(3):(\S*)/ +                xml_clean(para) +                xml_structure(para,$1,$2) +                para=@sto.lev_para_ocn.heading_body3 +              when /^(4):(\S*)/ # work on see SplitTextObject +                xml_clean(para) +                xml_structure(para,$1,$2) +                para=@sto.lev_para_ocn.heading_body4 +              when /^(5):(\S*)/ +                xml_clean(para) +                xml_structure(para,$1,$2) +                para=@sto.lev_para_ocn.heading_body5 +              when /^(6):(\S*)/ +                xml_clean(para) +                xml_structure(para,$1,$2) +                para=@sto.lev_para_ocn.heading_body6 +              else +                if para =~ /<:verse>/ +                  para=poem_structure(para) +                elsif para =~ /<:group>/ +                  para=group_structure(para) +                elsif para =~ /<:code>/ +                  para.gsub!(/</,'<') +                  para.gsub!(/>/,'>') +                  para=code_structure(para) +                elsif para =~/<!Th?.+/ # tables come as single block #work area 2005w13 +                  table=SiSU_Tables::TableXML.new(para) +                  para=table.table_split +                  para=table_structure(para) +                else xml_structure(para,nil,nil) +                end +              end +              if para =~/<a name="n\d+">/ \ +              and para =~/^(-\{{2}~\d+|<!e[:_]\d+!>)/ # -endnote +                para='' +              end +              if para =~/.*<:#>.*$/ +                para=case para +                when /<:i1>/ +                  format_text=FormatTextObject.new(para,'') +                  format_text.scr_inden_ocn_e_no_paranum +                when /<:i2>/ +                  format_text=FormatTextObject.new(para,'') +                  format_text.scr_inden_ocn_e_no_paranum +                end +              end +              if para =~/<:center>/ +                one,two=/(.*)<:center>(.*)/.match(para)[1,2] +                format_text=FormatTextObject.new(one,two) +                para=format_text.center +              end +            end +            para.gsub!(/<:\S+?>/,'') +            para.gsub!(/<!.+!>/,'') ## Clean Prepared Text #bugwatch reinstate +            para +          end +          para +        end +        6.downto(4) do |x| +          y=x - 1; v=x - 3 +          @@xml[:body] << "#{@tab*5}</content>\n#{@tab*y}</contents#{v}>\n" if @level[x]==true +        end +        3.downto(1) do |x| +          y=x - 1 +          @@xml[:body] << "#{@tab*y}</heading#{x}>\n" if @level[x]==true +        end +      end +      def pre +        rdf=SiSU_XML_Tags::RDF.new(@md) +        dir=SiSU_Env::InfoEnv.new +        @@xml[:head],@@xml[:body]=[],[] +        css=SiSU_Env::CSS_Select.new(@md).xml_sax +        encoding=if @sys.locale =~/utf-?8/i then '<?xml version="1.0" encoding="UTF-8" standalone="no"?>' +        else                                     '<?xml version="1.0" encoding="ISO-8859-1" standalone="no"?>' +        end +        @@xml[:open] =<<WOK +#{encoding} +<?xml-stylesheet type="text/css" href="../#{dir.path.style}/#{css}"?> +#{rdf.comment_xml_sax} +<document> +WOK +        @@xml[:head] << "<head>\n" +        @@xml[:body] << "<body>\n" +      end +      def post +        @@xml[:head] << @@xml[:sc] +        @@xml[:head] << "</head>\n" +        @@xml[:body] << "</body>\n" +        @@xml[:close] = "</document>\n" +      end +      def publish +        content=[] +        content << @@xml[:open] << @@xml[:head] << @@xml[:body] << @@xml[:metadata] +        content << @@xml[:owner_details] if @md.stmp =~/\w\w/ +        content << @@xml[:tail] << @@xml[:close] +        Output.new(content.join,@md).xml +        @@xml={} +      end +    end +    class Output +      def initialize(data,md) +        @data,@md=data,md +      end +      def xml +        @sisu=[] +        @data.each do |para| +          para.gsub!(/<:\S+?>/,'') +          para.gsub!(/<!.+?!>/,'') +          para="#{para}\n" unless para.empty? +          @sisu << para +        end +        new_file_data=@sisu.join +        @sisu=new_file_data.scan(/.+/) +        SiSU_Env::FileOp.new(@md).mkdir +        filename_sxm=SiSU_Env::FileOp.new(@md,@md.fn[:sxs]).mkfile_pwd +        if filename_sxm.is_a?(File) +          @sisu.each {|para| filename_sxm.puts para} +          filename_sxm.close +        else puts 'file not created, is directory writable?' +        end +      end +    end +    class Tidy +      def initialize(md,dir) +        @md,@env=md,dir +        @prog=SiSU_Env::InfoProgram.new +      end +      def xml +        if @prog.tidy !=false #note values can be other than true +          if (@md.opt.act[:verbose_plus][:set]==:on \ +          || @md.opt.act[:maintenance][:set]==:on) +            SiSU_Screen::Ansi.new( +              @md.opt.act[:color_state][:set], +              'invert', +              'Using XML Tidy', +              'check document structure' +            ).colorize unless @md.opt.act[:quiet][:set]==:on +            SiSU_Screen::Ansi.new( +              @md.opt.act[:color_state][:set], +              '', +              '', +              'check document structure' +            ) +            tell.grey_open unless @md.opt.act[:quiet][:set]==:on +            tidyfile='/dev/null' #don't want one or screen output, check for alternative flags +            tidy =SiSU_Env::SystemCall.new("#{Dir.pwd}/#{@md.fn[:sxs]}",tidyfile) +            tidy.well_formed? +            tell.p_off unless @md.opt.act[:quiet][:set]==:on +          end +        end +      end +    end +  end +end +__END__ +#+END_SRC + +* sst_identify_markup.rb + +#+BEGIN_SRC ruby  :tangle "../lib/sisu/sst_identify_markup.rb" +# <<sisu_document_header>> +module SiSU_Markup +  class MarkupInform +    attr_accessor :version +    def initialize(version,message,declared_markup='',declared_type='') +      @version,@message,@declared_markup,@declared_type=version,message,declared_markup,declared_type +    end +    def version +      @version +    end +    def message +      @message +    end +    def declared_version +      @declared_markup +    end +    def declared_type +      @declared_type +    end +    def history +      MarkupHistory.new(@version).query +    end +  end +  class MarkupIdentify +    def initialize(opt) +      @opt=opt +      @description='This is a script attempts to identify the version of markup used in SiSU (and provides information on changes in markup)' +    end +    def help +    print <<WOK + +#{@description} + +WOK +      exit +    end +    def identify +      f=@opt.fns +      if f =~/(?:\.sst|\.ssm|\.ssi|\.s[123])$/ \ +      and File.exist?(f) +        file=File.open(f,'r') +        cont=file.readlines +        file.close +        links,oldlinks='','' +        markup=nil +        @declared_type,@declared_markup='[text?]','' +        if cont[0] =~ /^(?:%\s+)?SiSU\s+(text|master|insert)\s+([0-9](?:\.[0-9]+){1,2})/ \ +        or cont[0] =~ /^(?:%\s+)?sisu-([0-9](?:\.[0-9]+){1,2})/ +          @declared_type,@declared_markup=$1,$2 +        elsif cont[0] =~ /^(?:%\s+)?SiSU\s+([0-9](?:\.[0-9]+){1,2})/ \ +        or cont[0] =~ /^(?:%\s+)?sisu-([0-9](?:\.[0-9]+){1,2})/ +          @declared_markup=$1 +        end +        @flag_2_0,@flag_1_0,@flag_69,@flag_66,@flag_57,@flag_38=false,false,false,false,false,false +        cont.each_with_index do |y,i| +          if y =~/^(?:0\{?~links?|@links?:)\s/ \ +          and f =~/(?:\.sst|\.ssm|\.ssi|\.s[123])/ +            links=unless y =~/\{.+?\}\S+/; oldlinks=' (pre 0.20.4 header links)' +            else ' (post 0.20.4 header links)' +            end +          end +          if @flag_2_0 \ +          or y =~/^@make:|^@classify|^\s\s?:[a-z_-]+?:\s+\S/ +            version=2.0.to_f +            markup=MarkupInform.new(version,'2.0' + oldlinks,@declared_markup,@declared_type) +            @flag_2_0=true +            break +          end +          unless @flag_38 +            if (y =~/^:?A~/ and f =~/(?:\.sst|\.ssm|\.ssi)/) +              version='0.38' +              markup=MarkupInform.new(version,'0.38' + oldlinks,@declared_markup,@declared_type) +              @flag_38=true +            end +          end +          if @flag_38 +            if @flag_1_0 \ +            or y =~/^=\{.+?\}\s*$/ +              version='0.69' +              markup=MarkupInform.new(version,'0.69' + oldlinks,@declared_markup,@declared_type) +              @flag_1_0=true +              break +            end +            if @flag_66 \ +            or y =~/[a-z+][:;]\{.+?\}[:;][a-z+]/ +              version='0.66' +              markup=MarkupInform.new(version,'0.66' + oldlinks,@declared_markup,@declared_type) +              @flag_66=true +              break +            end +          end +        end +        unless @flag_2_0 \ +        or @flag_1_0 \ +        or @flag_66 +          cont.each_with_index do |y,i| +            if y =~/^(?:0\{?~links?|@links?:)\s/ \ +            and f =~/(?:\.sst|\.ssm|\.ssi|\.s[123])/ +              links=unless y =~/\{.+?\}\S+/; oldlinks=' (pre 0.20.4 header links)' +              else ' (post 0.20.4 header links)' +              end +            end +            if @flag_57 \ +            or (y =~/^:?A~\?? @title/ and f =~/(?:\.sst|\.ssm|\.ssi)/) +              version='0.57' +              markup=MarkupInform.new(version,'0.57' + oldlinks,@declared_markup,@declared_type) +              @flag_57=true +              break +            end +            if @flag_38 \ +            or (y =~/^:?A~/ and f =~/(?:\.sst|\.ssm|\.ssi)/) +              version='0.38' +              markup=MarkupInform.new(version,'0.38' + oldlinks,@declared_markup,@declared_type) +              @flag_38=true +              break if i >= 200 +              if y =~ /(?:~{\*+|~\[\*|~\[\+)\s/ +                version='0.42' +                markup=MarkupInform.new(version,'0.42' + oldlinks,@declared_markup,@declared_type) +                break +              end +            end +            if (y =~/^1~/ and f =~/(?:\.sst|\.ssm|\.ssi)/) \ +            and not @flag_38 +              version='0.37' +              markup=MarkupInform.new(version,'0.37 is substantially 0.16 - 0.36 markup with new file-extension' + oldlinks,@declared_markup,@declared_type) +              break +            end +            if y =~/^1~/ \ +            and f =~/\.([rs])([123])/ \ +            and not @flag_38 +              t,n=$1,$2 +              version='0.16' +              instruct=if t =~/r/ +                " (change file extension from .#{t}#{n} to .ssm)" +              else " (change file extension from .#{t}#{n} to .sst)" +              end +              markup=MarkupInform.new(version,'0.16 - 0.36' + instruct + links,@declared_markup,@declared_type) +              break +            end +            if y =~/^0\{~/ \ +            and not @flag_38 +              version='0.1' +              markup=MarkupInform.new(version,'0.1 - 0.15',@declared_markup,@declared_type) +              break +            end +            if y =~/^0\{{3}/ \ +            and not @flag_38 +              markup=MarkupInform.new('circa. 1997','old, check date',@declared_markup,@declared_type) +              break +            end +            markup='Not a recognised file type ' +          end +        end +        markup +      else MarkupHistory.new(@opt).help_query +      end +    end +    def determine_markup_version +      if @opt.fns.nil? \ +      or @opt.fns.empty? +        MarkupHistory.new(@opt).help_identify +      end +      if File.exist?(@opt.fns) +        if @opt.fns =~/\.(?:sst|ssm|ssi|s[123i]|r[123])/ +          markup=identify #(@opt.fns) +          if defined? markup.version +            unless @opt.act[:quiet][:set]==:on +              message=unless markup.declared_version.empty? +                "#{@opt.fns}\n  markup Type Declared as SiSU #{markup.declared_version} #{markup.declared_type}\n  appears to be SiSU #{markup.version}" +              else +                "Markup Type Appears to be SiSU #{markup.version}\n  in file #{@opt.fns}" +              end +              puts message +              puts %{"sisu --query-#{markup.version}" for a brief description of markup type} +            end +          end +        else puts 'file-type not recognised: ' + @opt.fns +        end +      else puts 'file not found: ' + @opt.fns +      end +      (defined? markup.version) \ +      ? markup.version +      : 'markup type/version not determined' +    end +    def markup_version? +      if @opt.fns.empty? +        @opt.files.each do |fns| +          @opt.fns=fns +          determine_markup_version +        end +      else determine_markup_version +      end +    end +  end +  class MarkupHistory +    def initialize(opt) +      @opt=opt +    end +    def sisu_3_0 +      <<WOK +  SiSU 3.0 same as 2.0, apart from change to headers + +    see document markup samples, and sisu --help headers + +WOK +    end +    def sisu_2_0 +      <<WOK +  SiSU 2.0 same as 1.0, apart from the changing of headers and the addition of a monospace tag +    related headers now grouped, e.g. + +    @title: +     :subtitle: + +    @creator: +     :author: +     :translator: +     :illustrator: + +    see document markup samples, and sisu --help headers + +    the monospace tag takes the form of a has '#' \#{ this enclosed text would be monospaced }# + +WOK +    end +    def sisu_1_0 +      <<WOK +  SiSU 1.0 same as 0.69 + +WOK +    end +    def sisu_0_69 +      <<WOK +  SiSU 0.69 (same as 1.0) as previous (0.57) with the addition of book index tags +    /^=\{.+?\}$/ +    e.g. appended to a paragraph, on a new-line (without a blank line in between) +    logical structure produced assuming this is the first text "object" +    ={GNU/Linux community distribution:Debian+2|Fedora|Gentoo;Free Software Foundation+5} + +   Free Software Foundation, 1-6 +   GNU/Linux community distribution, 1 +       Debian, 1-3 +       Fedora, 1 +       Gentoo, + +WOK +    end +    def sisu_0_66 +      <<WOK +  SiSU 0.66 same as previous, adds semantic tags +    /[:;]\{.+?\}[:;][a-z+]/ +    e.g. :{ Ralph last;{Amissah};last }:author + +WOK +    end +    def sisu_0_65 +      <<WOK +  SiSU 0.65 same as previous, adds semantic tags +    /[a-z+][:;]\{.+?\}[:;][a-z+]/ +    e.g. author:{ Ralph last;{Amissah};last }:author + +WOK +    end +    def sisu_0_57 +      <<WOK + +  SiSU 0.57 (a subset of 1.0) is the same as 0.42 with the introduction of some +  a shortcut to use the headers @title and @creator in the first heading +  [expanded using the contents of the headers @title: and @author:] + +  :A~ @title by @author + +WOK +    end +    def sisu_0_42 +      <<WOK +  SiSU 0.42 (a subset of 1.0) is the same as 0.38 with the introduction of some additional endnote types, + +  Introduces some varations on endnotes, in particular the use of the asterisk +  ~{* for example for describing an author }~ and ~{** for describing a second author }~ + +  * for example for describing an author + +  ** for describing a second author + +  and ~[* my note ]~ or ~[+ another note ]~ which numerically increments an +  asterisk and plus respectively + +  *1 my note +  +1 another note + +WOK +    end +    def sisu_0_38 +      <<WOK + +  SiSU 0.38 (a subset of 1.0) introduced alternative experimental header and heading/structure markers, + +  @headername: and headers :A~ :B~ :C~ 1~ 2~ 3~ + +  as the equivalent of (the superceded) + +  0~headername and headers 1~ 2~ 3~ 4~ 5~ 6~ + +  The internal document markup of SiSU 0.16 remains valid and standard +  Though note that SiSU 0.37 introduced a new file naming convention + +  SiSU has in effect two sets of levels to be considered, using 0.38 notation +  A-C headings/levels, pre-ordinary paragraphs /pre-substantive text, and +  1-3 headings/levels, levels which are followed by ordinary text. +    This may be conceptualised as levels A,B,C, 1,2,3, and using such letter +    number notation, in effect: +      A must exist, optional B and C may follow in sequence (not strict) +      1 must exist, optional 2 and 3 may follow in sequence +    i.e. there are two independent heading level sequences A,B,C and 1,2,3 +      (using the 0.16 standard notation 1,2,3 and 4,5,6) +    on the positive side: +      * the 0.38 A,B,C,1,2,3 alternative makes explicit an aspect of structuring +        documents in SiSU that is not otherwise obvious to the newcomer (though +        it appears more complicated, is more in your face and likely to be +        understood fairly quickly) +      * the substantive text follows levels 1,2,3 and it is 'nice' to do +        most work in those levels +WOK +    end +    def sisu_0_37 +      <<WOK + +  SiSU 0.37 introduced the file naming convention, that remains in use in SiSU +  v1 and v2, using the file extensions .sst .ssm and .ssi +  to replace .s1 .s2 .s3 .r1 .r2 .r3  and .si + +  this is captured by the following file 'rename' instruction: + +  rename 's/\.s[123]$/\.sst/' *.s{1,2,3} +  rename 's/\.r[123]$/\.ssm/' *.r{1,2,3} +  rename 's/\.si$/\.ssi/' *.si + +  The internal document markup remains unchanged, from SiSU 0.16 +WOK +    end +    def sisu_0_16 +      <<WOK + +  SiSU 0.16 (0.15 development branch) introduced the use of + +  the header 0~ and headings/structure 1~ 2~ 3~ 4~ 5~ 6~ + +  in place of the 0.1 header, heading/structure notation +WOK +    end +    def sisu_0_1 +      <<WOK + +  SiSU 0.1 headers and headings structure represented by +  header 0{~ and headings/structure  1{ 2{ 3{ 4{~ 5{ 6{ +WOK +    end +    def help_query +      <<WOK + +  sisu --query=[sisu version [0.38] or 'history] +  provides a short history of changes to SiSU markup + +WOK +    end +    def help_identify +      <<WOK + +  sisu --identify [filename] +  attempts to identify the SiSU markup used in a file + +WOK +    end +    def query +      tell=if @opt.selections.str =~/--query/ +        tell=case @opt.selections.str +        when /history/ +          "#{sisu_3_0}#{sisu_2_0}#{sisu_1_0}#{sisu_0_69}#{sisu_0_66}#{sisu_0_57}#{sisu_0_42}#{sisu_0_38}\n#{sisu_0_37}\n#{sisu_0_16}\n#{sisu_0_1}" +        when /3.0/ +          "#{sisu_3_0}#{sisu_2_0}#{sisu_1_0}#{sisu_0_69}#{sisu_0_66}#{sisu_0_57}#{sisu_0_42}#{sisu_0_38}#{sisu_0_16}" +        when /2.0/ +          "#{sisu_2_0}#{sisu_1_0}#{sisu_0_69}#{sisu_0_66}#{sisu_0_57}#{sisu_0_42}#{sisu_0_38}#{sisu_0_16}" +        when /1.0/ +          "#{sisu_1_0}#{sisu_0_69}#{sisu_0_66}#{sisu_0_57}#{sisu_0_42}#{sisu_0_38}#{sisu_0_16}" +        when /0.69/ +          "#{sisu_0_69}#{sisu_0_66}#{sisu_0_57}#{sisu_0_42}#{sisu_0_38}#{sisu_0_16}" +        when /0.66/ +          "#{sisu_0_66}#{sisu_0_57}#{sisu_0_42}#{sisu_0_38}#{sisu_0_16}" +        when /0.65/ +          "#{sisu_0_65}#{sisu_0_57}#{sisu_0_42}#{sisu_0_38}#{sisu_0_16}" +        when /0.57/ +          "#{sisu_0_57}#{sisu_0_42}#{sisu_0_38}#{sisu_0_16}" +        when /0.42/ +          "#{sisu_0_42}#{sisu_0_38}#{sisu_0_16}" +        when /0.38/ +          "#{sisu_0_38}#{sisu_0_16}" +        when /0.37/ +          "#{sisu_0_37}\n#{sisu_0_16}" +        when /0.1[6-9]|0.2[0-9]|0.3[0-6]/ +          "#{sisu_0_16}\n#{sisu_0_1}" +        when /0.[1-9]|0.1[1-4]/ +          sisu_0_1 +        else puts "NOT RECOGNISED: #{@opt.selections.str}" +          help_query +        end +        tell +      else help_query +      end +    end +  end +end +__END__ +#%% to use as independent program -------------------------> +f=$* +cf=f[0].to_s +f.shift +match_and_replace=[] +unless f.length > 0; f=Dir.glob("[a-z]*.ss?")  #restricted to sisu type files, it need not be +end +puts "SiSU files:" +puts f +f.each do |x| +  SiSU_Markup::MarkupIdentify.new(x).markup_version? +end +#+END_SRC + +* sst_do_inline_footnotes.rb + +#+BEGIN_SRC ruby  :tangle "../lib/sisu/sst_do_inline_footnotes.rb" +# <<sisu_document_header>> +module SiSU_ConvertFootnotes +  require_relative 'se'                                 # se.rb +    include SiSU_Env +  require_relative 'dp'                                 # dp.rb +    include SiSU_Param +  require_relative 'ao_syntax'                          # ao_syntax.rb +    include SiSU_AO_Syntax +  require_relative 'i18n'                               # i18n.rb +  class Instantiate < SiSU_Param::Parameters::Instructions +     @@flag={} #Beware!! +    def initialize +      @@flag['table_to']=false +      @@counter=@@column=@@columns=@@flag_vocab=0 +      @@endnote={} +      @@endnote_array=@@word_mode=[] +      @@endnote_call_counter=1 +      @@line_mode='' +    end +  end +  class Source <Instantiate +    @@ao_array=[] +    @@fns=nil +    def initialize(opt) +      @opt=opt +      @@fns||@opt.fns +      @my_make=SiSU_Env::CreateFile.new(@opt.fns) +      @fnm=SiSU_Env::InfoFile.new(@opt.fns).marshal.ao_content +    end +    def read                                                                     #creates ao +      begin +        @@ao_array=[] +        @@fns=@opt.fns +        create_ao +      rescue +        SiSU_Errors::Rescued.new($!,$@,@opt.cmd,@opt.fns).location do +          __LINE__.to_s + ':' + __FILE__ +        end +      ensure +        Instantiate.new +      end +    end +    def get                                                                      #reads ao, unless does not exist then creates first +      begin +        ao=[] +        unless @@fns==@opt.fns +          @@fns=@opt.fns +          @@ao_array=[] +        end +        ao=(@@ao_array.empty?) \ +        ? read_fnm +        : @@ao_array.dup #check +      rescue +        SiSU_Errors::Rescued.new($!,$@,@opt.cmd,@opt.fns).location do +          __LINE__.to_s + ':' + __FILE__ +        end +      ensure +        Instantiate.new +      end +    end +  protected +    def create_ao +      ao_array=[] +      SiSU_Screen::Ansi.new( +        @opt.act[:color_state][:set], +        'convert footnotes' +      ).green_title_hi unless @opt.act[:quiet][:set]==:on +      file_array=IO.readlines(@opt.fns,'') +      file_array.each do |l| +        if l =~/\r\n/ then l.gsub!(/\r\n/,"\n") +        end +      end +      meta=file_array.dup +      meta=meta.join.split("\n\n") #check whether can be eliminated, some of these are large objects to have twice +      @md=SiSU_Param::Parameters::Instructions.new(meta,@opt).extract +      if @md.en[:mismatch]==0 \ +      or @md.opt.selections.str =~/=footnotes-force/ +        meta=nil +        ao=SiSU_ConvertFootnotes::Make.new(@md,file_array).song +        SiSU_Screen::Ansi.new( +          @opt.act[:color_state][:set], +          @opt.fns, +          "#{@md.fns}.fn" +        ).output if @md.opt.act[:verbose][:set]==:on +        SiSU_Screen::Ansi.new( +          @opt.act[:color_state][:set], +          "#{@md.fns}.fn -> #{@md.fns}.fn" +        ).txt_red unless @md.opt.act[:quiet][:set]==:on +        ao.each {|s| ao_array << "#{s.strip}\n\n" unless s.strip.empty?} +        ao_array +      else +        SiSU_Screen::Ansi.new( +          @md.opt.act[:color_state][:set], +          '*WARN* no footnote conversion done, problem with source file', +          'to override use --convert=footnote-force (this is not advised)' +        ).warn unless @md.opt.act[:quiet][:set]==:on +        '' +      end +    end +    def read_fnm +      ao=[] +      ao=(FileTest.file?(@fnm)) \ +      ? (File.open(@fnm){ |f| ao=Marshal.load(f)}) +      : (SiSU_ConvertFootnotes::Source.new(@opt).create_ao) #watch +    end +  end +  class Output +    def initialize(md,data) +      @md,@data=md,data +      @my_make=SiSU_Env::CreateFile.new(@md.fns) +      SiSU_Env::InfoEnv.new(@md.fns) +      @hard="#{Dir.pwd}/#{@md.fns}.fn" +    end +    def hard_output +      filename_note=@my_make.file_note +      @data.each {|s| filename_note.puts s.strip + "\n\n" unless s.strip.empty?} +    end +  end +  class Make +    @@endnote={} +    @@endnote_array=@@word_mode=[] +    @@endnote_call_counter=1 +    @@comment='%' +    @@flag={ ['table_to']=>false } +    def initialize(md,data) +      @md,@data=md,data +      @@word_mode=[] +      @env=SiSU_Env::InfoEnv.new(@md.fns) +      l=SiSU_Env::StandardiseLanguage.new(@md.opt.lng).language +      @language=l[:n] +      @translate=SiSU_Translate::Source.new(@md,@language) +    end +    def reset +      @@counter=@@column=@@columns=@@flag_vocab=0 +      @@endnote={} +      @@endnote_array=@@word_mode=[] +      @@endnote_call_counter=1 +      @@line_mode='' +    end +    def song +      reset +      data=@data +      @metafile="#{@env.processing_path.ao}/#{@md.fns}.meta" +      SiSU_Env::CreateFile.new(@md.fns) +      data=data.join.split("\n\n") +      data_new=[] +      data.each do |x| +        data_new << (x =~ /\n\n/m) \ +        ? (x.split(/\n\n+/)) +        : x +      end +      data=data_new.flatten +      data=SiSU_ConvertFootnotes::Make.new(@md,data).character_check +      data=SiSU_ConvertFootnotes::Make.new(@md,data).endnotes +      SiSU_ConvertFootnotes::Output.new(@md,data).hard_output +      reset +      data +    end +  protected +    def vocabulary +      data=@data +      tuned_file,vocab_insert=[],[] +      data.each do |para| +        if para =~/^1~/ \ +        and @@flag_vocab==0 +          vocab_insert << '@vocabulary: lex' << "\n\n" << para +          tuned_file << vocab_insert unless para.nil? +          @@flag_vocab=1 +        else tuned_file << para unless para.nil? +        end +      end +      tuned_file +    end +    def character_check +      reset +      data=@data +      @tuned_file=[] +      endnote_no=1 +      data.each do |para| +        para.strip! +        para.gsub!(/^[{~}]\s*$/,'') +        para.gsub!(/^#{@@comment}.*/,'')                                       #remove comment and divider #% +        para.gsub!(/<~#>|~#\s*/,'~#') +        para.gsub!(/-#\s*/,'-#') +        para.gsub!(/(~\{ )\s+/,'\1') +        para.gsub!(/ \/\//,'<br />')                                           #added 2004w29 +        para.gsub!(/<br>/,'<br />')                                            #needed by xml, xhtml etc. +        para.gsub!(/`/,"'") +        para.gsub!(/\342\200\231/,"'") #if para =~/’/  #Avoid #‘ ’ #“ ” +        para.gsub!(/\t/,' ') +        para.gsub!(/�/,' ') #watch, replace with char code +        para.gsub!(/[“”]/,'""') +        para.gsub!(/[–—]/,'-')   #— – chk +        para.gsub!(/·/,'*') +        para.gsub!(/\\copy(?:right)?\b/,'©') +        para.gsub!(/\\trademark\b|\\tm\b/,'®') +        para.gsub!(/\44/,'$') #$ watch +        para=para + "\n" +        case para +        when /\^~/                                                             # endnotes +                                                                               #% Note must do this first (earlier loop) and then enter gathered data into ~^\d+ +          sub_para=para.dup +          @@endnote_array << sub_para.gsub!(/\n/,'').gsub!(/\^~\s+(.+)\s*/,'~{ \1 }~').strip +           endnote_no+=1 +          para=nil if para =~/\^~ .+/ #removes 'binary' endnote now in endnote array for later insertion +        end +        @tuned_file << para unless para.nil? +      end +      @tuned_file +    end +    def name_endnote_seg +      data=@data +      @tuned_file=[] +      data.each do |para| +        para.gsub!(/<:3>\s*<:ee>/, +          "#{@@endnote['special_align']} <p /><br />\r " + +          "#{@@endnote['seg_name_3']} <p /> " + +          "#{@@endnote['special_align_close']}") +        para.gsub!(/<:2>\s*<:ee>/, +          "#{@@endnote['special_align']} <p /><br />\r " + +          "#{@@endnote['seg_name_2']} <p />" + +          "#{@@endnote['special_align_close']}") +        para.gsub!(/<:1>\s*<:ee>/, +          "#{@@endnote['special_align']} <p /><br />\r " + +          "#{@@endnote['seg_name_1']} <p /> " + +          "#{@@endnote['special_align_close']}") +        @tuned_file << para +      end +      if @md.flag_auto_endnotes \ +      and @md.flag_separate_endnotes_make +        @tuned_file << "\n1~endnotes Endnotes" #prob numbering, revisit +      end +      @tuned_file << "\n<ENDNOTES>" +      @tuned_file +    end +    def owner_details_seg +      data << '1~owner.details Owner Details' +    end +    def number_sub_heading(para,num,title_no) +      case para +      when /#{num}~- /    then para.gsub!(/#{num}~- /,"#{title_no} ") +      when /^#{num}~#\s*/ then para.gsub!(/^#{num}~#\s*/,"#{title_no} ") +      when /^#{num}~[a-z_\.]+ / +        para.gsub!(/^#{num}~([a-z_\.]+)\s+(.+)/i,%{#{num}~\\1 #{title_no} \\2  <:name##{title_no}>}) +      else para.gsub!(/^#{num}~ /,"#{num}~#{title_no} #{title_no} ") #main +      end +      if @md.toc_lev_limit \ +      and @md.toc_lev_limit < num +        para.gsub!(/^[2-6]~(?:~\S+)?\s*/,'!_ ') +      end +      para +    end +    def set_heading_top                                                        #% make sure no false positives +      unless @md.set_heading_top +        if (@md.opt.act[:verbose_plus][:set]==:on \ +        || @md.opt.act[:maintenance][:set]==:on) +          puts "\tdocument contains no top level heading, (will have to manufacture one)" +        end +        data=@data +        @tuned_file=[] +        data.each do |para| +          unless @md.set_heading_top +            if para !~/^(?:@\S+:|0~\S+)\s/m \ +            and para !~/\A\s*\Z/m +              @md.set_heading_top=true +              head=(@md.title.full) \ +              ? (":A~ #{@md.title.full}") +              : (':A~ [no title provided]') +              @tuned_file << head +            end +          end +          @tuned_file << para +        end +        @tuned_file +      end +    end +    def set_heading_seg                                                        #% make sure no false positives +      unless @md.set_heading_seg +        if (@md.opt.act[:verbose_plus][:set]==:on \ +        || @md.opt.act[:maintenance][:set]==:on) +          puts "\tdocument contains no segment level, (will have to manufacture one)" +        end +        data=@data +        @tuned_file=[] +        data.each do |para| +          unless @md.set_heading_seg +            if para !~/^(?:@\S+:|0~\S+|:[ABC]~)/m \ +            and para !~/\A\s*\Z/m \ +            and para !~/<:p[bn]>/ +              @md.set_heading_seg=true +              head=(@md.title.full) \ +              ? ("1~seg [#{@md.title.full}]") +              : ('1~seg [segment]') +              @tuned_file << head +            end +          end +          @tuned_file << para +        end +        @tuned_file +      end +    end +    def set_header_title                                                       #% make sure no false positives +      unless @md.set_header_title +        if (@md.opt.act[:verbose_plus][:set]==:on \ +        || @md.opt.act[:maintenance][:set]==:on) +          puts "\t no document title provided, (will have to manufacture one)" +        end +        data=@data +        @tuned_file=[] +        data.each do |para| +          unless @md.set_header_title +            if para !~/^%{1,2}\s/m \ +            and para !~/\A\s*\Z/m +              @tuned_file << "0~title #{@md.heading_seg_first}" +              @md.title.full=@md.heading_seg_first +              @md.set_header_title=true +            end +          end +          @tuned_file << para +        end +        @tuned_file +      end +    end +    def endnotes                                                                         #% endnote work zone +      data=@data +      @tuned_file=[] +      endnote_ref=1 +      data.each do |para| +        case para                                                                               # manually numbered endnotes <!e(\d)!> <!e_(\d)!> --> +        when /~\{\s+.+?\}~/                                                                               # auto-numbered endnotes <!e!> <!e_!> --> +          para.gsub!(/\s*\}~/,' }~')                                           # required 2003w31 +          @word_mode=para.scan(/\S+/) +          word_mode=SiSU_ConvertFootnotes::Make.new(@md,@word_mode).endnote_call_number +          para=word_mode.join(' ') +          endnote_ref+=1 +        when /~\^(?:\s|$)|<:e>/                                                #%Note inserts endnotes previously gathered from /^(<!e[:_]!>|[-~]\{{3})/ (in earlier loop) +          word_mode=para.scan(/\S+/) +          word_mode=SiSU_ConvertFootnotes::Make.new(@md,word_mode).endnote_call_number +          para=word_mode.join(' ') +          endnote_ref+=1 +        end +        @tuned_file << para +      end +      @tuned_file +    end +    def endnote_call_number +      data=@data +      data.each do |word| +        case word +        when /~\{/ +          unless word =~/~\{\*+/ +            @@endnote_call_counter+=1 +          end +        when /~\^|<:e>/ +          word.gsub!(/~\^|<:e>/,"#{@@endnote_array[@@endnote_call_counter-1]}") +          @@endnote_call_counter+=1 +        end +      end +    end +    def strip_clean_extra_spaces(s)                                            # ao output tuned +      s=s.dup +      s=s.gsub(/[ ]+([,.;:?](?:$|\s))/,'\1') +      s=s.gsub(/ [ ]+/,' ') +      s=s.gsub(/^ [ ]+/,'') +      s=s.gsub(/ [ ]+$/,'') +      s=s.gsub(/(<\/[bi]>')[ ]+(s )/,'\1\2') +    end +    def strip_clean_of_markup(s)                                               # used for digest, define rules, make same as in db clean +      s=s.dup +      s=s.gsub(/(?:<\/?[ib]>|^:[A-C]~\S+|^[1-6]~\S+|~\{\d+\s.+?\}~)/,'') # markup and endnotes removed +                                                                               #% same as db clean --> +      s=s.gsub(/<del>(.+?)<\/del>/,'DELETED(\1)')                           # deletions +      s=s.gsub(/<sup>(\d+)<\/sup>/,'[\1]') +      s=s.gsub(/(?: \\;|#{Mx[:nbsp]})+/,' ')  #checking source Mx not necessary +      s=s.gsub(/\{.+?\.(?:png|jpg|gif).+?\}(?:https?|file|ftp)\\\:\S+ /,' [image] ')             # else image names found in search +      s=s.gsub(/#{Mx[:lnk_o]}.+?\.(?:png|jpg|gif).+?#{Mx[:lnk_c]}#{Mx[:url_o]}\S+?#{Mx[:url_c]}/,' [image] ')             # else image names found in search, re-check +      s=s.gsub(/\s\s+/,' ') +      s=s.strip +    end +  end +end +__END__ +@particulars=SiSU_Particulars::CombinedSingleton.instance.get_all(opt) +ao_array=@particulars.ao_array # ao file drawn here +#+END_SRC + +* sst_convert_markup.rb + +#+BEGIN_SRC ruby  :tangle "../lib/sisu/sst_convert_markup.rb" +# <<sisu_document_header>> +module SiSU_Modify +  require_relative 'sst_identify_markup'                # sst_identify_markup.rb +  require_relative 'sst_from_xml'                       # sst_from_xml.rb +  require_relative 'utils_response'                     # utils_response.rb +  class ConvertMarkup +    include SiSU_Response +    def initialize(opt) +      @opt=opt +      @description='This is a script that contains canned text conversions for reuse' +      @warn='WARNING, PROCEED AT YOUR OWN RISK, will make file changes.' +    end +    def current_match_and_replace +      convert_37_to_38 +    end +    def message(text) +      response='' +      unless @opt.cmd=~/QQ/ \ +      or @opt.act[:quiet][:set]==:on +        response=response?(%{#{  text}\nProceed? }) +      end +    end +    def help +    print <<WOK + +#{@description} + +sisu --convert --to38 [filename/wildcard] +  converts pre 0.37 sisu markup to 0.38 experimental +  [--37to38] + +sisu --convert --to37 [filename/wildcard] +  converts pre 0.37 sisu markup to 0.38 experimental +  [--38to37] + +sisu --convert --36to37 [filename/wildcard] +  converts pre 0.36 file-name, to 0.37 file-name +  [--36to37] + +sisu --identify [filename] +  attempts to identify markup version used in file + +sisu --query [version number] +  gives short summary of distinguishing characteristic +  of that version of markup + +WOK +      exit +    end +    #%% substitutions to be made +    def convert_37_to_38 +      message("#{@warn}\nConvert sisu markup from 0.37 to 0.38") +      [ +        [/^0~(\S+?)([+-])\s+/,    '@\1:\2 ',               //], +        [/^0~(\S+)\s+/,           '@\1: ',                 //], +        [/^@toc:\s+/,             '@structure: ',          //], +        [/^1~/,                   ':A~',                   //], +        [/^2~/,                   ':B~',                   //], +        [/^3~/,                   ':C~',                   //], +        [/^4~/,                   '1~',                    //], +        [/^5~/,                   '2~',                    //], +        [/^6~/,                   '3~',                    //], +        [/^7~/,                   '4~',                    //], +        [/^8~/,                   '5~',                    //], +        [/^9~/,                   '6~',                    //], +        [/1/,                     ':A',                    /^@(?:level|markup):\s/], +        [/2/,                     ':B',                    /^@(?:level|markup):\s/], +        [/3/,                     ':C',                    /^@(?:level|markup):\s/], +        [/4/,                     '1',                     /^@(?:level|markup):\s/], +        [/5/,                     '2',                     /^@(?:level|markup):\s/], +        [/6/,                     '3',                     /^@(?:level|markup):\s/] +      ] +    end +    def convert_38_to_37 +      message("#{@warn}\nConvert sisu markup from 0.38 to 0.37") +      [ +        [/^@(\S+?):([+-])\s+/,    '0~\1\2 ',               //], +        [/^@(\S+?):\s+/,          '0~\1 ',                 //], +        [/^0~structure\s+/,       '0~toc ',                //], +        [/^1~/,                   '4~',                    //], +        [/^2~/,                   '5~',                    //], +        [/^3~/,                   '6~',                    //], +        [/^4~/,                   '7~',                    //], +        [/^5~/,                   '8~',                    //], +        [/^6~/,                   '9~',                    //], +        [/^:?A~/,                 '1~',                    //], +        [/^:?B~/,                 '2~',                    //], +        [/^:?C~/,                 '3~',                    //], +        [/1/,                     '4',                     /^0~(?:level|markup)\s/], +        [/2/,                     '5',                     /^0~(?:level|markup)\s/], +        [/3/,                     '6',                     /^0~(?:level|markup)\s/], +        [/:?A/,                   '1',                     /^0~(?:level|markup)\s/], +        [/:?B/,                   '2',                     /^0~(?:level|markup)\s/], +        [/:?C/,                   '3',                     /^0~(?:level|markup)\s/] +      ] +    end +    def convert_filename_36_to_37 +      @opt.files.each do |f| +        s=case f +        when /(\.s[1-3])$/ then f.sub($1,'.sst') +        when /(\.r[1-3])$/ then f.sub($1,'.ssm') +        when /(\.ri)$/     then f.sub($1,'.ssi') +        else f +        end +        pwd=Dir.pwd +        unless f==s +          unless File.exist?("#{pwd}/#{s}") +            puts "./#{f} -> ./#{s}" +            FileUtils::cp("#{pwd}/#{f}","#{pwd}/#{s}") +          else "File already exists, < #{s} >  will not overwrite" +          end +        end +      end +    end +    def convert_to_simple_xml_model_sax +      SiSU_SimpleXML_ModelSax::Convert.new(@opt).read +    end +    def convert_to_simple_xml_model_dom +      SiSU_simple_xml_model_dom::Convert.new(@opt).read +    end +    def convert_to_simple_xml_model_node +      SiSU_simple_xml_model_node::Convert.new(@opt).read +    end +    def convert_kdi_to_sst +      SiSU_Kdissert::Convert.new(@opt).read +    end +    def convert_s_xml_to_sst +      SiSU_sstFromXML::Convert.new(@opt).read +    end +    def convert_footnotes +      require_relative 'sst_do_inline_footnotes' +      SiSU_ConvertFootnotes::Source.new(@opt).read +    end +    def conversion +      #%% do it                                   --------------------------> +      if @opt.files \ +      and @opt.files.length > 0 +        mr=nil +        #%% changes to make m match, r replace      --------------------------> +        if @opt.selections.str =~/--help/ then help +        elsif @opt.selections.str =~/(?:convert|to)[=-](?:xml |sxs|sax|sxd|dom|sxn|node)/ +          ext=case @opt.selections.str +          when /(?:convert|to)[=-](?:xml|sxs|sax)/ then '.sxs.xml' +          when /(?:convert|to)[=-](?:sxd|dom)/     then '.sxd.xml' +          when /(?:convert|to)[=-](?:sxn|node)/    then '.sxn.xml' +          end +          message("#{@opt.files.inspect}\n\nWARNING, PROCEED AT YOUR OWN RISK,\noverwriting any equivalent file with the extension #{ext}") +          mr=case @opt.selections.str +          when /(?:convert|to)[=-](?:sxs|sax|xml )/ then convert_to_simple_xml_model_sax +          when /(?:convert|to)[=-](?:sxd|dom)/      then convert_to_simple_xml_model_dom +          when /(?:convert|to)[=-](?:sxn|node)/     then convert_to_simple_xml_model_node +          else help +          end +        else +          mr=case @opt.selections.str +          when /(?:(?:37)?to-?38|--(?:convert|to)[=-](?:current|0.38))/           then convert_37_to_38 +          when /(?:(?:38)?to-?37|--(?:convert|to)[=-](?:0.37))/                   then convert_38_to_37 +          when /(?:36to37)/                                                       then convert_filename_36_to_37 +          when /(?:convert|from)[=-]kdi/                                          then convert_kdi_to_sst +          when /(?:(?:convert|from)[=-])?(?:xml_to_sst|xml2sst|sxml|sxs|sxd|sxd)/ then convert_s_xml_to_sst +          when /(?:convert|to)[=-]footnotes/                                      then convert_footnotes +          when /convert|default/                                                  then current_match_and_replace +          else help +          end +        end +        unless @opt.selections.str =~/kdi/ +          match_and_replace=mr +          #start_processing =/not used in this example/i +          end_processing =/END\s+OF\s+FILE/ +          i=@opt.fns +          if i =~/(?:\.sst|\.ssm|\.ssi)$/ +            @new,@matched,@flag_start,@flag_end,@empty1,@empty2=true,false,false,false,false,false +            o="#{i}.bk" #o is for old +            markup_version=SiSU_Markup::MarkupIdentify.new(@opt).markup_version? +            if (@opt.selections.str=~/37/ and markup_version=~/0.38/) \ +            or (@opt.selections.str=~/current|38/ and markup_version=~/0.37/) +              puts "#{i} #{markup_version}" +              file=File.open(i,'r') +              cont=file.readlines +              file.close +              cont.each do |y| +                match_and_replace.each do |m,r,w| +                  if y =~m \ +                  and y =~w +                    if @new +                      @new=false +                      File.unlink(o) if File.exist?(o) +                      File.rename(i,o) +                      File.unlink(i) if File.exist?(i) +                      @file=File.new(i,'w') +                      @matched=true +                      break +                    end +                  end +                end +              end +              if @matched +                puts "conversion match in #{i}" unless @opt.act[:quiet][:set]==:on +                @flag_start=true +                cont.each do |y| +                  if y =~end_processing +                    @flag_end=true +                  end +                  if @flag_start \ +                  and not @flag_end +                    match_and_replace.each do |m,r,w| +                      if y =~m \ +                      and y =~w +                        puts m.inspect + ' -> ' + r unless @opt.act[:quiet][:set]==:on +                        if (@opt.act[:verbose][:set]==:on \ +                        || @opt.act[:verbose_plus][:set]==:on \ +                        || @opt.act[:maintenance][:set]==:on) +                          puts "in:  #{y}" +                        end +                        y.gsub!(m,r) if m and r +                        if (@opt.act[:verbose][:set]==:on \ +                        || @opt.act[:verbose_plus][:set]==:on \ +                        || @opt.act[:maintenance][:set]==:on) +                          puts "out: #{y}" +                        end +                      end +                    end +                  end +                  @empty1=(y=~/^\s*$/) \ +                  ? true +                  : false +                  @file.puts y unless (@empty1==true and @empty2==true) +                  @empty2=(y=~/^\s*$/) \ +                  ? true +                  : false +                end +                @file.close +              else puts "NO conversion match in #{i}" unless @opt.act[:quiet][:set]==:on +              end +            else +              if (@opt.act[:verbose][:set]==:on \ +              || @opt.act[:verbose_plus][:set]==:on \ +              || @opt.act[:maintenance][:set]==:on) +                puts "Requested conversion #{@opt.selections.str} markup #{markup_version} identified in #{i}" +              end +            end +          end +        end +      else puts 'this routine makes permanent changes to the contents of the files matched, as instructed within [no matches]' +      end +    end +  end +end +#%% files to match for this conversion set  -------------------------> +require_relative 'hub_options'                          # hub_options.rb +argv=$* +base_path=Dir.pwd +@opt=SiSU_Commandline::Options.new(argv,base_path) +case @opt.selections.str +when /=kdi/ +  SiSU_Modify::ConvertMarkup.new(@opt).conversion +when /(?:36|37|38)?to-?(?:37|38)|--convert|--to|--from|default/ +@opt.files.each do |fns| +  @opt.fns=fns +  SiSU_Modify::ConvertMarkup.new(@opt).conversion +end +else +  @opt.selections.str='--help' + SiSU_Modify::ConvertMarkup.new(@opt).help +end +__END__ +#+END_SRC + +* document header + +#+NAME: sisu_document_header +#+BEGIN_SRC text +encoding: utf-8 +- Name: SiSU + +  - Description: documents, structuring, processing, publishing, search +    sst + +  - 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 diff --git a/org/texinfo.org b/org/texinfo.org new file mode 100644 index 00000000..3046df51 --- /dev/null +++ b/org/texinfo.org @@ -0,0 +1,946 @@ +-*- mode: org -*- +#+TITLE:       sisu texinfo +#+DESCRIPTION: documents - structuring, various output representations & search +#+FILETAGS:    :sisu:texinfo: +:wqa +#+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 + +* texinfo.rb + +#+BEGIN_SRC ruby  :tangle "../lib/sisu/texinfo.rb" +# <<sisu_document_header>> +module SiSU_TexInfo +  require_relative 'html'                               # html.rb +  require_relative 'dp'                                 # dp.rb +    include SiSU_Param +  #include Stamp ... needed removed arbitrarily 2005w05/1 (warnings about undefined flags) +  require_relative 'texinfo_format'                     # texinfo_format.rb +  include SiSU_TexInfoFormat +  @tex_file=[] +  @@tabular="{tabular}" +  @@table_pagebreak_counter,@@tex_endnote_call_counter,@@tex_table_flag,@@tex_counter,@@tex_column,@@tex_columns,@@counting=0,0,0,0,0,0,0 +  @@column_instruct,@@tex_line_mode,@@tex_word_mode,@@start_table,@@line_mode='','','','','' +  @@n,@@copyright,@@tableheader=nil,nil,nil +  @@tex_col_w=[] +  @@tex_pattern_margin_number="\\\\marginpar.+?\s+" +  class Source +    include SiSU_Param +    include SiSU_TexInfo +    def initialize(opt) +      @opt=opt +      @md=SiSU_Param::Parameters.new(@opt).get +      @env=SiSU_Env::InfoEnv.new(@opt.fns) +    end +    def directories +      begin +        case @opt.fns +        when /\.(?:-|ssm\.)?sst$/ +          Dir.mkdir(@env.path.output) unless FileTest.directory?("#{@env.path.output}") +          Dir.mkdir(@env.processing_path.texi) unless FileTest.directory?(@env.processing_path.texi) +        end +      rescue +        SiSU_Screen::Ansi.new(opt,$!,$@).rescue do +          __LINE__.to_s + ':' + __FILE__ +        end +      ensure +      end +    end +    def read +      begin +        song +      ensure +        Dir.chdir(@opt.f_pth[:pth]) +      end +    end +    def song +      begin +        tool=(@opt.act[:verbose][:set]==:on \ +        || @opt.act[:verbose_plus][:set]==:on \ +        || @opt.act[:maintenance][:set]==:on) \ +        ? "cd #{@md.file.output_path.texinfo.dir} && #{@env.program.texinfo} #{@md.file.base_filename.info}; cd -" +        : "[#{@opt.f_pth[:lng_is]}] #{@opt.fno}" +        (@opt.act[:verbose][:set]==:on \ +        || @opt.act[:verbose_plus][:set]==:on \ +        || @opt.act[:maintenance][:set]==:on) \ +        && ! @opt.act[:quiet][:set]==:on \ +        ? SiSU_Screen::Ansi.new( +            @opt.act[:color_state][:set], +            'TexInfo', +            tool +          ).green_hi_blue +        : SiSU_Screen::Ansi.new( +            @opt.act[:color_state][:set], +            'TexInfo', +            tool +          ).green_title_hi +        @md=SiSU_Param::Parameters.new(@opt).get +        directories +        @marshalfile=SiSU_Env::InfoFile.new(@opt.fns).marshal.ao_content +        if FileTest.file?(@marshalfile)==true +          File.open(@marshalfile) { |f| @@tuned_file=Marshal.load(f)} +          #tell.meta_verse_skipped if @opt.selections.str =~/[vVM]/ +        else +          tex_array=IO.readlines(@opt.fns,'') +          SiSU_Metaverse.songsheet(tex_array) +        end +        tex_array=@@tuned_file +        TeXinfoMake.new(@md,tex_array).songsheet +        tex_array='' +      rescue; STDERR.puts SiSU_Screen::Ansi.new(@opt.act[:color_state][:set],$!,$@).rescue +      ensure +      end +    end +  end +  class TeXinfoMake +    include SiSU_Param +    include SiSU_TexInfoFormat +    @@tex_1='(?:.+?)+~' #?? debug +    @@tabular="{tabular}" +    @@tex_pattern_margin_number="\\\\marginpar.+?\s+" +    def initialize(md,data) +      @md,@data=md,data +      @env=SiSU_Env::InfoEnv.new(@md.fns) +      @f=SiSU_Env::FileOp.new(@md) +    end +    def songsheet +      begin +        data=@data +        data=pre(data) +        data=endnote(data) +        data,head=markup(data) +        objs_txt=tail(data) +        doc_txt=[head,objs_txt] +        output(doc_txt) +        makeinfo #KEEP reinstate when fixed #% +        place_info +      rescue; STDERR.puts SiSU_Screen::Ansi.new(@md.opt.act[:color_state][:set],$!,$@).rescue +      ensure +      end +    end +    def pre(data) +      data_new=[] +      data.each do |dob| +        # DEBUG 2003w16 this is a kludge, because i could not get parameters +        # from param, Sort out ... revert to more elegant solution +        if dob.is =='table' +          @@flag['tables']='y' # KLUDGE get from param +        end +        dob.obj=dob.obj.gsub(/<:p[bn]>/,''). +          gsub(/#{Mx[:lnk_o]}(.+?)#{Mx[:lnk_c]}#{Mx[:url_o]}(\S+?)#{Mx[:url_c]}/,'\1(\2 [linked to:] \3)'). +          gsub(/(^|#{Mx[:gl_c]}|\s)\{(.+?)\}((?:https?|file):\/\/\S+)/,'\1(\2 [linked to:] \3)') +        do_mono=SiSU_TexInfoFormat::Texinfo.new(@md,dob) +        dob.obj=do_mono.spec_char(dob.obj) +        data_new << dob +      end +      data_new +    end +    def endnote(data) +      data_new=[] +      data.each do |dob| +        if dob.of==:para \ +        || dob.of==:block +          dob.obj=dob.obj.gsub(/\s*#{Mx[:en_a_o]}(?:\d+)\s+(.+?)#{Mx[:en_a_c]}/m,' @footnote{ \1} '). +            gsub(/\s*#{Mx[:en_a_o]}(\*+)\s+(.+?)#{Mx[:en_a_c]}/m,' @footnote{ \1} ') +        end +        data_new << dob +      end +      data_new +    end +    def poem +      data,data_new=@data,[] +      @tex_file=[] +      @@counting=0 +      data.each do |dob| +        if dob.is ==:code +          @@flag['code']=true +          @@counting=1 +        end +        if dob.is ==:verse +          @@flag['poem']=1 +        end +        if @@flag['code'] +          if @@flag['code'] \ +          && (dob.obj =~ /#{Mx[:gr_o]}code[-_](?:end|close)#{Mx[:gr_c]}/) #watch change not tested 200501 #fix +            @@flag['code']=false +          end +          if @@flag['code'] \ +          && (dob.obj =~ /\S/) +            sub_array=dob.obj.dup +            @@line_mode=sub_array.scan(/.+/) +            Tune.code_lines(@@line_mode) +            dob.obj=@@line_mode.join +          end +        elsif @@flag['poem']==1 +          if @@flag['poem']==1 \ +          && (dob.obj =~ /#{Mx[:gr_o]}verse[-_](?:end|close)#{Mx[:gr_c]}/) #watch change not tested 200501 #fix +            @@flag['poem']=0 +          end +          if @@flag['poem']==1 \ +          && (dob.obj =~ /\S/) +            sub_array=dob.obj.dup +            @@line_mode=sub_array.scan(/.+/) +            Tune.code_lines(@@line_mode) +            dob.obj=@@line_mode.join +          end +        end +        @tex_file << dob.obj +        data_new << dob +      end +      data_new +    end +    def code_lines +      data,data_new=@data,[] +      data.each do |line| +        if (line =~ /\S/) \ +        && (line !~ /#{Mx[:gr_o]}(code|verse).+/) #fix +          line=if @@flag['code'] +            line.gsub(/^\s*(.+)/m,"\\noindent \\marginpar\[left-text\]{\\begin{tiny}#{@@counting}\\end{tiny}}\\1\\") +            @@counting+=1 if @@flag['code'] +          else line.gsub(/(.+)/m,'\noindent\1') +          end +        end +        data_new << line +      end +    end +    def tables +      data,data_new=@data,[] +      @tex_file=[] +      @@tableheader=0 +      data.each do |dob| +        if dob.obj =~ /#{Mx[:tc_p]}|#{Mx[:gr_o]}T/ui #fix +          do_mono=SiSU_TexInfoFormat::Texinfo.new(@md,dob) +          dob.obj=do_mono.longtable # using longtable latex package +        end +        @tex_file << dob.obj +        data_new << dob +      end +      data_new +    end +    def markup(data) +      data_new=[] +      @tex_file=[] +      @row_break='\\\\\\' +      @break_page="#{@row_break}\n#{@row_break} \n" +      @tex_file << SiSU_TexInfoFormat::Texinfo.new(@md).head +      mono=SiSU_TexInfoFormat::Texinfo.new(@md) +      @tex_file << mono.topnode(@md.title.full) +      texinfo_menu=[] +      n_menu,n_submenu=0,0 +      @submenu,@subsubmenu={},{} +      data.each do |dob| +        if dob.is ==:heading \ +        && (dob.ln.to_s =~ /^[0-3]$/) +          toc=SiSU_TexInfoFormat::Texinfo.new(@md,dob) +          texinfo_menu << toc.menu +        elsif dob.is ==:heading \ +        && (dob.ln.to_s =~ /^[4-6]$/) +          toc=SiSU_TexInfoFormat::Texinfo.new(@md,dob) +          texinfo_menu << toc.menu +          case dob.ln +          when 4 +            n_menu+=1 +            @submenu[n_menu]=[] +          when 5 +            n_submenu+=1 +            @subsubmenu[n_menu]=[] +            @submenu[n_menu] << toc.menu +          when 6 +            n_submenu+=1 +            @subsubmenu[n_submenu]=[] +            @subsubmenu[n_submenu] << toc.menu +          end +        else +          dob.obj=dob.obj.gsub(/\s*(?:<:?br>|<br \/>)\s*/,"\n\n") +        end +        data_new << dob +      end +      data=data_new +      texinfo_menu=texinfo_menu.compact +      texinfo_menu << "* Dublin Core::" +      @tex_file << texinfo_menu +      @tex_file << "* Index::\n" + +        "@end menu\n\n" + +        "@c %% 5\n\n" +      n_menu,n_submenu=0,0 +      @@do_submenu,@@do_subsubmenu=1,1 +      data_new=[] +      data.each do |dob| +        unless defined? dob.ln and dob.ln == (5..6) +          mono=SiSU_TexInfoFormat::Texinfo.new(@md,dob) +        end +        if dob.is==:heading +          case dob.ln +          when 0 then dob=mono.level0 +          when 1 then dob=mono.level1 +          when 2 then dob=mono.level2 +          when 3 then dob=mono.level3 +          when 4; +            @@n4_txt=dob.obj +            dob=mono.level4 +            n_menu+=1 +            @@do_submenu,@@do_subsubmenu=1,1 +          when 5; +            n_submenu+=1 +            @@do_subsubmenu=1 +            @@n5_txt=dob.obj +            if @@do_submenu==1 +              menu=SiSU_TexInfoFormat::TeXinfoTxt.new(@md,dob,@submenu[n_menu]) +              dob.obj="#{menu.submenu}#{SiSU_TexInfoFormat::Texinfo.new(@md,dob,@@n4_txt).level5.obj}" +              @@do_submenu=0 +            else dob.obj="#{SiSU_TexInfoFormat::Texinfo.new(@md,dob,@@n4_txt).level5.obj}" +            end +          when 6; +            if @@do_submenu==1 +              menu=SiSU_TexInfoFormat::TeXinfoTxt.new(@md,dob,@submenu[n_menu]) +              dob.obj="#{menu.submenu}#{SiSU_TexInfoFormat::Texinfo.new(@md,dob,@@n5_txt).level6.obj}" +              dob.obj="#{menu.subsubmenu}#{mono.level6.obj}" +              @@do_subsubmenu=0 +            else dob.obj="#{SiSU_TexInfoFormat::Texinfo.new(@md,dob,@@n5_txt).level6.obj}" +            end +          end +        else +          if dob.obj !~/\S/ +            dob.obj=nil +          else +            if dob.is==:para \ +            && (dob.obj !~/#{Dx[:ocn_o]}#{dob.ocn}#{Dx[:ocn_c]}/) +              dob.obj=dob.ocn.is_a?(Fixnum) \ +              ? "#{dob.obj} #{Dx[:ocn_o]}#{dob.ocn}#{Dx[:ocn_c]}\n\n" : "#{dob.obj}\n\n" +            end +          end +        end +        #%case with endnotes +        dob.obj=dob.obj.gsub(/\s*[0-8]\\+(\S+)?\s+/,' ') if dob.obj +        data_new << dob +      end +      [data_new, @tex_file] +    end +    def number_titles +      data,data_new=@data,[] +      @tex_file=[] +      data.each do |dob| +        if (@md.markup =~ /num_top/i) \ +        && (dob.obj !~ /#{Rx[:meta]}/) +          if (dob.obj =~ /^[1-6]\\+(?:~\S+)?\s*<!h-.+?-!>/) \ +          && (dob.obj !~ /<:\d-endnotes>/) +            header=dob.obj[/<!h-(.+?)-!>/m, 1].gsub(/-/m,'.') +            dob.obj=dob.obj.gsub(/^(?:[1-6]\\+(?:~\S+)|<:([12356]|4-.+?-)>)\s*<!h-.+?-!>/, +              "\\1 #{header} ") +          end +        elsif dob.obj=~ /<!h!>|<!h\d!>|<!h.+?!>|<!!h.+?!>/ +          if dob.obj=~ /<!h-.+?-!>/ +            dob.obj=dob.obj.gsub(/<!h-(.+?)-!>/,'\1 ') +          end +        end +        @tex_file << dob.obj +      end +      data_new << dob +    end +    def tail(data) +      tex=SiSU_TexInfoFormat::Texinfo.new(@md) +      objs_txt=[] +      data.each do |dob| +        if dob.obj \ +        && (dob.is !=:structure \ +        && dob.is !=:comment) +           objs_txt << dob.obj if dob.obj +        end +      end +      objs_txt << tex.dublincore << tex.tail +      objs_txt +    end +    def output(data) +      filename_texinfo=%{#{@env.processing_path.texi}/#{@md.fnb}.texinfo} +      file_texinfo=File.new(filename_texinfo,'w+') +      puts filename_texinfo if @md.opt.act[:maintenance][:set]==:on +      data.each {|s| (file_texinfo.puts s,"\n") if s} +      file_texinfo.close +    end +    def makeinfo +      if @md.fns =~/\.(?:-|ssm\.)?sst$/ +        m=/(.+?)\.((?:-|ssm\.)?sst)$/.match(@md.fns) +        fnb,sfx=m[1],m[2] +        pwd=Dir.pwd +        case sfx +        when /(?:-|ssm\.)?sst$/ +          @env=SiSU_Env::InfoEnv.new(@md.fns,@md.opt.selections.str) +          Dir.chdir(@env.processing_path.texi) +          texinfo=SiSU_Env::SystemCall.new("#{fnb}.texinfo") +          texinfo.makeinfo +        end +        Dir.chdir(pwd) +      end +      def place_info +        unless FileTest.directory?(@f.output_path.texinfo.dir) +          FileUtils::mkdir_p(@f.output_path.texinfo.dir) +        end +        info_src=%{#{@env.processing_path.texi}/#{@md.fnb}.info} +        Dir.glob("#{info_src}*").sort.each do |f| +          FileUtils::cp(f, File.dirname(@f.place_file.info.dir)) # bug should provide dir without need to extract it! +        end +      end +    end +  end +end +__END__ +#+END_SRC + +* texinfo_format.rb + +#+BEGIN_SRC ruby  :tangle "../lib/sisu/texinfo_format.rb" +# <<sisu_document_header>> +module SiSU_TexInfoFormat +  @@table_pg_break_counter=1 +  require_relative 'dp'                                 # dp.rb +    include SiSU_Param +  class Texinfo +    @@tex_1='\\\\~' #?? debug +    @@tabular="{tabular}" +    @@tex_pattern_margin_number="\\\\marginpar.+?\s+" +    def initialize(md,dob=nil,up='') +      @md,@dob,@up=md,dob,up +      if dob.is_a?(Hash) +        p dob.class +        p caller +      elsif dob.is_a?(String) +        p dob.class +        p caller +      end +    end +    def head +      t=Time.now +      year=t.year +      title=spec_char(@md.title.full) +      title=title.gsub(/<(br|p|i)>|<\/\s*(br|p|i)>|<(br|p)\s*\/>/," #{Tex[:backslash]*2} "). +        gsub(/\$/,"\\$"). +        gsub(/[,]\s*/,' - ') +      if @md.title.sub +        subtitle=spec_char(@md.title.sub) +        subtitle=subtitle.gsub(/<(br|p|i)>|<\/\s*(br|p|i)>|<(br|p)\s*\/>/," #{Tex[:backslash]*2} "). +          gsub(/\$/,"\\$"). +          gsub(/[,]\s*/,' - ') +        subtitle="\n@subtitle #{subtitle}\n" +      end +      subtitle ||='' +      author=@md.author if @md.author +      author ||='' +      author=author.gsub(/[\*]/,'') #if author +      #SiSU_Env::InfoVersion.instance.get_version +      head =<<WOK +\\input texinfo   @c -*-texinfo-*- +@comment %**start of header +@setfilename #{@md.fnb}.info +@settitle #{title} +@syncodeindex pg cp +@comment %**end of header +@c %% 2 +@copying +SiSU texinfo of #{title} + +Copyright @copyright{} #{year} #{author}. + +@quotation +Copyright #{author}, generated by ``SiSU'' +@end quotation +@end copying + +@dircategory SiSU Texinfo +@direntry +,* sisu: SiSU texinfo file. +@end direntry +WOK +      if @md.title.sub +        titlepage=<<WOK +@c %% 3 +@titlepage +@title #{title} #{subtitle} +@author #{author} +@page +@vskip 0pt plus 1filll +@insertcopying +@end titlepage +@contents +WOK +      else +        titlepage=<<WOK +@c %% 3 +@titlepage +@title #{title} +@author #{author} +@page +@vskip 0pt plus 1filll +@insertcopying +@end titlepage + +@contents +WOK +      end +      "#{head}#{titlepage}" +    end +    def topnode(txt) +      txt=spec_char(txt) +      txt=txt.gsub(/<(br|p|i)>|<\/\s*(br|p|i)>|<(br|p)\s*\/>/," #{Tex[:backslash]*2} "). +        gsub(/\$/,"\\$"). +        gsub(/[,]\s*/,' - ') +      "@c %% 4\n" + +        "@ifnottex\n" + +        "@node Top\n" + +        "@top #{txt}\n\n" + +        "@insertcopying\n" + +        "@end ifnottex\n\n" + +        "@menu\n" +    end +    def dublincore +      if defined? @md.title.full \ +      and @md.title.full=~/\S+/ +        full_title=spec_char(@md.title.full) +      end +      if defined? @md.creator.author \ +      and @md.creator.author=~/\S+/ +        author=spec_char(@md.creator.author) +      end +      if defined? @md.publisher \ +      and @md.publisher=~/\S+/ +        publisher=spec_char(@md.publisher) +      end +      if defined? @md.creator.contributor \ +      and @md.creator.contributor=~/\S+/ +        contributor=spec_char(@md.contributor) +      end +      if defined? @md.date.published \ +      and @md.date.published=~/\S+/ +        date=spec_char(@md.date.published) +      end +      if defined? @md.date.created \ +      and @md.date.created=~/\S+/ +        date_created=spec_char(@md.date.created) +      end +      if defined? @md.date.issued \ +      and @md.date.issued=~/\S+/ +        date_issued=spec_char(@md.date.issued) +      end +      if defined? @md.date.available \ +      and @md.date.available=~/\S+/ +        date_available=spec_char(@md.date.available) +      end +      if defined? @md.date.valid \ +      and @md.date.valid=~/\S+/ +        date_valid=spec_char(@md.date.valid) +      end +      if defined? @md.date.modified \ +      and @md.date.modified=~/\S+/ +        date_modified=spec_char(@md.date.modified) +      end +      if defined? @md.classify.subject \ +      and @md.classify.subject=~/\S+/ +        subject=spec_char(@md.classify.subject) +      end +      if defined? @md.notes.description \ +      and @md.notes.description=~/\S+/ +        description=spec_char(@md.description) +      end +      if defined? @md.notes.coverage \ +      and @md.notes.coverage=~/\S+/ +        coverage=spec_char(@md.notes.coverage) +      end +      if defined? @md.notes.relation \ +      and @md.notes.relation=~/\S+/ +        relation=spec_char(@md.notes.relation) +      end +      #type=spec_char(@md.type) if @md.type                                   #dc +      if defined? @md.notes.format \ +      and @md.notes.format=~/\S+/ +        format=spec_char(@md.notes.format) +      end +      #if defined? @md.identifier.sisupod \ +      #and @md.identifier.sisupod=~/\S+/ +      #  identifier=spec_char(@md.identifier.sisupod) +      #end +      if defined? @md.original.source \ +      and @md.original.source=~/\S+/ +        source=spec_char(@md.original.source) +      end +      if defined? @md.title.language \ +      and @md.title.language=~/\S+/ +        language=spec_char(@md.title.language) +      end +      if defined? @md.rights.all \ +      and @md.rights.all=~/\S+/ +        rights=spec_char(@md.rights.all) +      end +      rights=spec_char(@md.rights.all) +      full_title="Title: #{full_title}\n\n" if full_title                           #dc +      author="Author: #{author}\n\n" if author                                      #dc +      subject="Subject: #{subject}\n\n" if subject                                  #dc +      description="Description: #{description}\n\n" if description                  #dc +      publisher="Publisher: #{publisher}\n\n" if publisher                          #dc +      contributor="Contributor: #{contributor}\n\n" if contributor                  #dc +      date="Date: #{date}\n\n" if date                                              #dc +      date_created="Date Created: #{date_created}\n\n" if date_created              #dc +      date_issued="Date Issued: #{date_issued}\n\n" if date_issued                  #dc +      date_available="Date Available: #{date_available}\n\n" if date_available      #dc +      date_valid="Date Valid: #{date_valid}\n\n" if date_valid                      #dc +      date_modified="Date Modified: #{date_modified}\n\n" if date_modified          #dc +      format="Format: #{format}\n\n" if format                                      #dc +      identifier="Identifier: #{identifier}\n\n" if identifier #watch               #dc +      source="Source: #{source}\n\n" if source                                      #dc +      language="Language: #{language}\n\n" if language                              #dc +      relation="Relation: #{relation}\n\n" if relation                              #dc +      coverage="Coverage: #{coverage}\n\n" if coverage                              #dc +      rights="Rights: #{rights}\n\n" if rights                                      #dc +      <<WOK +@node Dublin Core +@unnumbered Dublin Core +@cindex chapter, Dublin Core + +#{full_title}#{author}#{subject}#{description}#{publisher}#{contributor}#{date}#{date_created}#{date_issued}#{date_available}#{date_valid}#{date_modified}#{format}#{identifier}#{source}#{language}#{relation}#{coverage}#{rights} + +WOK +    end +    def tail +      <<WOK +@c %% 6 +@node Index +@unnumbered Index +@printindex cp + +@bye +WOK +    end +    def clean(dob) +      if dob.is==:heading \ +      and dob.obj !~/#{Dx[:ocn_o]}#{dob.ocn}#{Dx[:ocn_c]}/ +        dob.obj=dob.ocn.is_a?(Fixnum) \ +        ? "#{dob.obj} #{Dx[:ocn_o]}#{dob.ocn}#{Dx[:ocn_c]}" : dob.obj +      end +      dob.obj=dob.obj.gsub(/\n/m,' '). +        gsub(/,\s+/,' - '). +        strip +      dob +    end +    def menu +      dob=clean(@dob) +      m=dob.obj.gsub(/[:,]\s*/,' - '). +        gsub(/@footnote\{.+?\}\s+/,'') +      m="* #{m}::" +    end +    def level_common +      dob=clean(@dob) +      nd=dob.obj.gsub(/@footnote\{.+?\}\s+/,''). +        gsub(/: \s*/,' - ') +      dob.obj="@node #{nd}\n@unnumbered #{nd}\n@cindex chapter, #{nd}\n\n" +      dob +    end +    def level_sub(up) +      dob=clean(@dob) +      nd=dob.obj.gsub(/@footnote\{.+?\}\s+/,''). +        gsub(/: \s*/,' - ') +      dob.obj="@node #{nd}, #{up}\n@comment node-name, up\n@unnumbered #{nd}\n@cindex chapter, #{nd}\n\n" +      dob +    end +    def level0 +      level_common +    end +    def level1 +      level_common +    end +    def level2 +      level_common +    end +    def level3 +      level_common +    end +    def level4 +      level_common +    end +    def level5 +      level_sub(@up) +    end +    def level6 +      level_sub(@up) +    end +    def spec_char(txt) # special characters +      txt=txt.gsub(/#{Mx[:br_eof]}/i,''). +        gsub(/#{Mx[:gl_o]}#169#{Mx[:gl_c]}/,'(c)'). +        gsub(/#{Mx[:gl_o]}#(?:lt|060)#{Mx[:gl_c]}/,'<').gsub(/#{Mx[:gl_o]}(gt|#062)#{Mx[:gl_c]}/,'>'). +        gsub(/#{Mx[:gl_o]}#123#{Mx[:gl_c]}/,'{').gsub(/#{Mx[:gl_o]}#125#{Mx[:gl_c]}/,'}'). +        gsub(/#{Mx[:gl_o]}#(?:126|152)#{Mx[:gl_c]}/i,'~'). +        gsub(/#{Mx[:gl_o]}#033#{Mx[:gl_c]}/,'!'). +        gsub(/#{Mx[:gl_o]}#035#{Mx[:gl_c]}/,'#'). +        gsub(/#{Mx[:gl_o]}#042#{Mx[:gl_c]}/,'*'). +        gsub(/#{Mx[:gl_o]}#047#{Mx[:gl_c]}/,'/'). +        gsub(/#{Mx[:gl_o]}#095#{Mx[:gl_c]}/,'_'). +        gsub(/#{Mx[:gl_o]}#092#{Mx[:gl_c]}/,'\\'). +        gsub(/(?:#{Mx[:br_line]}|#{Mx[:br_nl]})\s*/,"\n\n").                                   # watch +        gsub(/<sup><font face=symbol>&atild;<\/font><\/sup>/,' '). +        #gsub(/\\/,'\\backslash '). +        gsub(/<:pb>/,'\\newpage'). +        gsub(/\\backslash copyright/,'\\copyright '). +        gsub(/\^/,'\\wedge '). +        gsub(/(\$)/,"\\$"). +        gsub(/\~/,'\\~'). +        gsub(/#{Mx[:url_o]}(https?:\S+?)#{Mx[:url_c]}/,'<\1>'). +        gsub(/#{Mx[:url_o]}_(https?:\S+?)#{Mx[:url_c]}/,'\1'). +        gsub(/§/i,'\S'). +        gsub(/£/i,'\pounds'). +        gsub(/å/,'\aa').gsub(/Å/,'\AA'). +        gsub(/æ/,'\ae').gsub(/Æ/,'\AE'). +        gsub(/ø/,'\o').gsub(/Ø/,'\O'). +        gsub(/<a href=".+?">/i,' '). +        gsub(/<\/a>/i,' '). +        gsub(/<!>/i,' '). +        gsub(/#{Mx[:br_paragrph]}/i,''). #watch +        gsub(/#{Mx[:fa_bold_o]}(.+?)#{Mx[:fa_bold_c]}/,'*\1*'). +        gsub(/#{Mx[:fa_italics_o]}(.+?)#{Mx[:fa_italics_c]}/,'/\1/'). +        gsub(/#{Mx[:fa_underscore_o]}(.+?)#{Mx[:fa_underscore_c]}/,'_\1_'). +        gsub(/#{Mx[:fa_subscript_o]}(.+?)#{Mx[:fa_subscript_c]}/,'[\1]'). +        gsub(/#{Mx[:fa_superscript_o]}(.+?)#{Mx[:fa_superscript_c]}/,'^\1^'). +        gsub(/#{Mx[:fa_insert_o]}(.+?)#{Mx[:fa_insert_c]}/,'+\1+'). +        gsub(/#{Mx[:fa_cite_o]}(.+?)#{Mx[:fa_cite_c]}/,'"\1"'). +        gsub(/#{Mx[:fa_strike_o]}(.+?)#{Mx[:fa_strike_c]}/,'-\1-'). +        gsub(/@/i,'@@'). +        gsub(/\{/,'@{').gsub(/\}/,'@}'). +        gsub(/(?: |#{Mx[:nbsp]})+/,' ').        # ~ character for hardspace +        gsub(/&(\S+?);/,' '). +        gsub(/&/,'<=and>'). +        gsub(/(\s+&\s+)/,' and '). +        gsub(/(\&)/,"\\&"). +        gsub(/"(.+?)"/,"`\\1'").                                        # open & close " +        gsub(/\s+"/," `").                                              # open " +        gsub(/^([1-6-]\\+(?:~\S+)?|<.+?>)?\s*"/,'\1`').       # open " +        gsub(/"(\s|\.|,|:|;)/,"'\\1").                                  # close " +        gsub(/"([1-6-]\\+(?:~\S+)?|<.+?>)?\s*$/,"'\\1").       # close " +        gsub(/"(\.|,)/,"'").                                            # close " +        gsub(/\s+'/," `").                                              # open ' +        gsub(/^([1-6-]\\+(?:~\S+)?|<.+?>)?\s*'/,'\1`').       # open ' +        gsub(/(<font.*?>|<\/font>)/,'') +    end +    def longtable +      @end_table="\\end{longtable}" +      @row_break='\\\\\\' +      if @dob[/#{Mx[:gr_o]}Th?#{Mx[:tc_p]}\s+c(\d+);(.+?)#{Mx[:gr_c]}/ui] #CHECK !> closure #fix +        no_of_cols,cols_width=$1,$2 +        @@tableheader=1 if @dob =~ /#{Mx[:gr_o]}Th/i #fix +        @w=cols_width.split(/;\s+/) +        @@number_of_cols=no_of_cols +        @colW=[] +        @colW << '{' +        @w.each  do |x| +          col_w=x.gsub(/.+/,'l\|') #unless x.nil? +          @colW << "#{col_w}" if col_w +        end +        @colW << '}' +        @colW=@colW.join +        @@start_table="\\setlength{\\LTleft}{0pt}\n\\setlength{\\LTright}{\\fill}\n" + +          "\\begin{longtable}[hb]#{@colW}\n" +        @dob.obj=@dob.obj.gsub(/#{Mx[:gr_o]}Th?#{Mx[:tc_p]}\s+c\d+?;.+#{Mx[:gr_c]}/u,"#{@@start_table}") #fix +      end +      if @dob =~/#{Mx[:gr_o]}TZ#{Mx[:gr_c]}/ #fix +        @dob.obj=@dob.obj.gsub(/#{Mx[:gr_o]}TZ#{Mx[:gr_c]}/," #{@end_table}") #fix +      end +      @dob.obj=@dob.obj.gsub(/#{Mx[:tc_o]}#{Mx[:tc_p]}/u,'') +      if @@tableheader==1 +        if @dob =~/#{Mx[:tc_p]}\d+?#{Mx[:tc_p]}(.+?)(?:#{Mx[:tc_p]}|!)/u +          tablefoot=para[/\<!f(.+?)!\>/,1] +          @dob.obj=@dob.obj.gsub(/\<!f(.+?)!\>/,''). +            gsub(/#{Mx[:tc_p]}\d+?#{Mx[:tc_p]}(.+?)(?:#{Mx[:tc_p]}|!)/u, +              "{\\begin{tiny} {\\bfseries \\1}\\end{tiny}}&"). +            gsub(/&>\s*$/, +              " #{@row_break} \\hline\\endhead #{@row_break}") +          @dob="#{@dob} \\multicolumn{#{@@number_of_cols}}{l}{\\tiny #{tablefoot}} \\\\ \\hline\n\\endfoot\n\\hline\n" if tablefoot +          @@tableheader=0 +          @@number_of_cols=0 +        end +      else +        if @dob =~/#{Mx[:tc_p]}\d+?#{Mx[:tc_p]}(.+?)(?:#{Mx[:tc_p]}|!)/u +          @dob.obj=@dob.obj.gsub(/#{Mx[:tc_p]}\d+?#{Mx[:tc_p]}(.+?)(?:#{Mx[:tc_p]}|!)/u,"\\begin{tiny}\\1\\end{tiny}&"). +            gsub(/&>\s*$/," #{@row_break}") +        end +      end +      @dob +    end +    def scopedtable +      # some features related to headers have been incorporated in longtable +      # that are not included yet here, so until synced is broken on some +      # input files, work needs to be done if is to work as before +      @end_table="\\end{tabular}" +      @row_break='\\\\\\\\' +      @break_page="#{@row_break}\n#{@row_break} \n" +      if @dob[/#{Mx[:gr_o]}Th?#{Mx[:tc_p]}\s+c(\d+);(.+?)#{Mx[:gr_c]}/ui] #fix +        cols_width=$2 +        @w=cols_width.split(/;\s+/) +        @colW=[] +        @w.each  do |x| +          col_w=((x.to_i*12)/100.00).to_s #unless x.nil? +          @colW << "p{#{col_w}cm}" if col_w +        end +        @@start_table="\\begin{tabular}{#{@colW}}\n" +        @dob.obj=@dob.obj.gsub(/#{Mx[:gr_o]}Th?#{Mx[:tc_p]}\s+c\d+?;.+#{Mx[:gr_c]}/u,"#{@@start_table}") #fix +      end +      if @dob =~/#{Mx[:gr_o]}TZ#{Mx[:gr_c]}/ #fix +        @dob.obj=@dob.obj.gsub(/#{Mx[:gr_o]}TZ#{Mx[:gr_c]}/,"#{@end_table}") #fix +        @@table_pg_break_counter=1 +      end +      if @dob =~/#{Mx[:tc_o]}#{Mx[:tc_p]}/u +        if @@table_pg_break_counter==28 # taken from 34 ideal for portrait to 28 which suits landscape +          @dob = +            "\n\n#{@end_table} \n" + +            "#{@break_page}" + +            "#{@@start_table}\n" +          @@table_pg_break_counter=1 +        else +          @dob.obj=@dob.obj.gsub(/#{Mx[:tc_o]}#{Mx[:tc_p]}/u,'') +          @@table_pg_break_counter+=1 +          @dob.obj=@dob.obj.gsub(/\<!f(.+?)!\>/,'') +        end +      end +      if @dob =~/#{Mx[:tc_p]}\d+?#{Mx[:tc_p]}(.+?)(?:#{Mx[:tc_p]}|!)/u +        @dob.obj=@dob.obj.gsub(/#{Mx[:tc_p]}\d+?#{Mx[:tc_p]}(.+?)(?:#{Mx[:tc_p]}|!)/u,"\\begin{tiny}\\1\\end{tiny}&"). +          gsub(/&>\s*$/,"#{@row_break}") +      end +      @dob +    end +    def graphics +      dir=SiSU_Env::InfoEnv.new(@md.fns) +      @dob.obj=@dob.obj.gsub(/<::\s+(\S+?)\s+>/i, #watch +        "\\includegraphics*[width=11pt]{#{dir.path.image_source_include}/c_\\1.png}") +    end +    def image +      dir=SiSU_Env::InfoEnv.new(@md.fns) +      width="100" +      width=@dob[/<:image.+?width=``(\d+)''.+?>/im,1] +      width=width.to_i*0.4 +      @dob.obj=@dob.obj.gsub(/<:image\s+((?:https?|file|ftp)\S+)\s+(\S+)\s+.+\s+?>/i, +          "\\href{\\1}{\\includegraphics*[width=#{width}pt]{#{dir.path.image_source_include}/\\2}}"). +        gsub(/<:image\s+(\S+)\s+.+\s+?>/i, +          "\\includegraphics*[width=#{width}pt]{#{dir.path.image_source_include}/\\1}") +    end +    def png +      # very messy clean up ! - work area, testing +      z=@dob[/\\\{(.+?)\}(?:image|png)/,1] # match operator for z \\ fragile ! +      image=z.scan(/\S+/)[0] #image,w,x,y=z.scan(/\S+/) +      image=image.gsub(/\\/,'') +      @dob.obj=@dob.obj.gsub(/\\\{\S+\.(png|jpg|gif).+?\}(image|png)/,"<image #{image} not available>")  # fragile match operator\\ fragile ! +    end +    def http +      # very messy clean up ! - work area, testing +      z=@dob[/#{Mx[:lnk_o]}(.+?)#{Mx[:lnk_c]}#{Mx[:url_o]}\S+?#{Mx[:url_c]}/,1] # match operator for z \\ fragile ! +      url=@dob[/((?:https?|file|ftp):\S+)/im,1] +      if @dob =~/\.(png|jpg|gif)/ +        image=z.scan(/\S+/)[0] #image,w,x,y=z.scan(/\S+/) +        image=image.gsub(/\\/,'') +        width=200 +        width=z[/w=(\d+)/im,1] if z =~/w=(\d+)/ +        width=width.to_i*0.8 +        width=400 if width > 400 +        c=z[/``(.+?)''/im,1] +        caption="{\\\\\\\ \n\\begin{scriptsize}#{c}\\end{scriptsize}&}" if c +      end +      if image +        dir=SiSU_Env::InfoEnv.new(@md.fns) +        @dob.obj=@dob.obj.gsub(/#{Mx[:lnk_o]}\S+\.(png|jpg|gif).+?#{Mx[:lnk_c]}#{Mx[:url_o]}\S+?#{Mx[:url_c]}/, # fragile match operator\\ fragile ! +          "\n\\href{#{url}}{\\includegraphics*[width=#{width}pt]{#{dir.path.image_source_include}/#{image}}}#{caption}") +      else +        link=z[/(.+?)\\/im,1] +        @dob.obj=@dob.obj.gsub(/#{Mx[:lnk_o]}.+?#{Mx[:lnk_c]}#{Mx[:url_o]}\S+#{Mx[:url_c]}/,"\n\\noindent\\href{#{url}}{#{link}}")  # fragile match operator\\ fragile ! +      end +    end +  end +  class TeXinfoTxt +    def initialize(md,dob,txt) +      @md,@dob,@txt=md,dob,txt +    end +    def clean(dob,txt) +      if dob.is==:heading \ +      and txt !~/#{Dx[:ocn_o]}#{dob.ocn}#{Dx[:ocn_c]}/ +        txt=dob.ocn.is_a?(Fixnum) \ +        ? "#{dob.obj} #{Dx[:ocn_o]}#{dob.ocn}#{Dx[:ocn_c]}" : dob.obj +      end +      txt.strip +    end +    def submenu +      txt=@txt.join("\n") +      txt=clean(@dob,txt) +      txt="@menu\n#{txt}\n@end menu\n\n" +      txt=txt.gsub(/.+/m,"#{txt}") +    end +    def subsubmenu +      txt=@txt.join("\n") +      txt=clean(@dob,txt) +      txt="@menu\n#{txt}\n@end menu\n\n" +      txt=txt.gsub(/.+/m,"#{txt}") +    end +  end +end +__END__ +watch title, might need full_title +#+END_SRC + +* document header + +#+NAME: sisu_document_header +#+BEGIN_SRC text +encoding: utf-8 +- Name: SiSU + +  - Description: documents, structuring, processing, publishing, search +    texinfo + +  - 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 diff --git a/org/texpdf.org b/org/texpdf.org new file mode 100644 index 00000000..3aa25fcd --- /dev/null +++ b/org/texpdf.org @@ -0,0 +1,2969 @@ +-*- mode: org -*- +#+TITLE:       sisu tex pdf +#+DESCRIPTION: documents - structuring, various output representations & search +#+FILETAGS:    :sisu:texpdf: +#+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 + +* texpdf +** texpdf.rb + +#+BEGIN_SRC ruby  :tangle "../lib/sisu/texpdf.rb" +# <<sisu_document_header>> +module SiSU_TeX +  begin +    require 'pstore' +  rescue LoadError +    SiSU_Utils::CodeMarker.new(__LINE__,__FILE__,:fuchsia). +      error('pstore NOT FOUND (LoadError)') +  end +  require_relative 'texpdf_parts'                        # texpdf_parts.rb +  require_relative 'se_hub_particulars'                 # se_hub_particulars.rb +    include SiSU_Particulars +  require_relative 'texpdf_format'                      # texpdf_format.rb +    include SiSU_TeX_Pdf +  require_relative 'shared_metadata'                    # shared_metadata.rb +  require_relative 'prog_text_translation'              # prog_text_translation.rb +  @tex_file=@@tex_footnote_array=@@tex_col_w=[] +  @@tabular="{tabular}" +  @@column_instruct=@@squigle_close=@@tex_line_mode=@@tex_word_mode=@@line_mode='' +  @@tex_debug_counter=@@table_pagebreak_counter=@@tex_footnote_call_counter=@@tex_table_flag=@@tex_counter=@@tex_column=@@tex_columns=@@tex_columns=@@counting=0 +  @@tex_pattern_margin_number=/\\\\begin\\\{tiny\\\}\\\\hspace\\\{0mm\\\}\\\\end\\\{tiny\\\}\\\{\\\\marginpar.+?\s+/ +  @@n=@@tableheader=@@rights=nil +  @@date ||=SiSU_Env::InfoDate.new +  class Source +    begin +      require 'pstore' +    rescue LoadError +      SiSU_Utils::CodeMarker.new(__LINE__,__FILE__,:fuchsia). +        error('pstore NOT FOUND (LoadError)') +    end +    require_relative 'se'                               # se.rb +      include SiSU_Env +    require_relative 'ao'                               # ao.rb +      include SiSU_AO +    include SiSU_TeX +    def initialize(opt) +      @opt=opt +      @particulars=SiSU_Particulars::CombinedSingleton.instance.get_all(opt) +      @md=@particulars.md +      @env=SiSU_Env::InfoEnv.new(@md.fns) #@env=@particulars.env +    end +    def directories +      begin +        case @opt.fns +        when /\.(?:-|ssm\.)?sst$/ +          SiSU_Env::FileOp.new(@md).mkdir +          Dir.mkdir(@env.processing_path.tex) unless FileTest.directory?(@env.processing_path.tex) +        end +      rescue +        SiSU_Errors::Rescued.new($!,$@,@opt.selections.str,@opt.fns).location do +          __LINE__.to_s + ':' + __FILE__ +        end +      ensure +      end +    end +    def read +      begin +        song +      ensure +        Dir.chdir(@opt.f_pth[:pth]) +      end +    end +    def song +      begin +        @md=@particulars.md +        SiSU_Screen::Ansi.new( +          @opt.act[:color_state][:set], +          'LaTeX/PDF', +          "[#{@opt.f_pth[:lng_is]}] #{@opt.fno}" +        ).green_title_hi unless @opt.act[:quiet][:set]==:on +        if (@opt.act[:verbose][:set]==:on \ +        || @opt.act[:verbose_plus][:set]==:on \ +        || @opt.act[:maintenance][:set]==:on) +          @env.url.output_tell +          if @md.opt.act[:pdf_l][:set]==:on +            SiSU_Screen::Ansi.new( +              @opt.act[:color_state][:set], +              @opt.fns, +              "#{@env.program.pdf_viewer} #{@md.file.output_path.pdf.dir}/#{@md.file.base_filename.pdf_l}#{@md.papersize_array[0]}.pdf" +            ).flow +          end +          if @md.opt.act[:pdf_p][:set]==:on +            SiSU_Screen::Ansi.new( +              @opt.act[:color_state][:set], +              @opt.fns, +              "#{@opt.fns} #{@env.program.pdf_viewer} #{@md.file.output_path.pdf.dir}/#{@md.file.base_filename.pdf_p}#{@md.papersize_array[0]}.pdf" +            ).flow +          end +        end +        @md=@particulars.md +        $flag=@md.opt.selections.str                                                          #introduced to pass 0 for no object citation numbers... to texpdf_format +        directories +                                                                               #% needed needs to be reprogrammed !!! +        ao_array=SiSU_AO::Source.new(@opt).get # ao file drawn here +        SiSU_TeX::Source::LaTeXcreate.new(@particulars).songsheet +        ao_array='' +        pwd=Dir.pwd +        SiSU_TeX::Source::LaTeXtoPdf.new(@md,@particulars.env).latexrun_selective +        Dir.chdir(pwd) +      rescue +        SiSU_Errors::Rescued.new($!,$@,@opt.selections.str,@opt.fns).location do +          __LINE__.to_s + ':' + __FILE__ +        end +      ensure +        unless (@opt.act[:verbose_plus][:set]==:on \ +        || @opt.act[:maintenance][:set]==:on) +          texfiles=Dir["#{@env.processing_path.tex}/#{@opt.fns}*"] +          texfiles.each do |f| +            if FileTest.file?(f) +              File.unlink(f) +            end +          end +        end +        @tex_file=@@tex_footnote_array=[] +        @@column_instruct='' +        @@squigle_close=@@tex_line_mode=@@tex_word_mode=@@line_mode='' +        @@tex_debug_counter=@@table_pagebreak_counter=@@tex_footnote_call_counter=@@tex_table_flag=@@tex_counter=@@tex_column=@@tex_columns=@@tex_columns=@@counting=0 +        @@tex_col_w=[] +        @@n=@@tableheader=@@rights=nil +        @@date=SiSU_Env::InfoDate.new +        @@flag={} +        $flag=1 #remove at some stage +        SiSU_Env::Clear.new(@opt.selections.str,@opt.fns).param_instantiate +      end +    end +    private +    class LaTeXtoPdf +      @@n_lpdf||=0 #change +      def initialize(md,env) +        @md,@env=md,env +        @f=SiSU_Env::FileOp.new(@md).base_filename +      end +      def latex_do(texfilename,papersize) +        @texfilename=texfilename +        @@n_lpdf=@@n_lpdf+1 +        tex_fn_base=@texfilename.gsub(/\.tex$/,'') +        tell=SiSU_Screen::Ansi.new(@md.opt.selections.str) +        if @md.opt.act[:pdf_p][:set]==:on +          if (@md.opt.act[:verbose][:set]==:on \ +          || @md.opt.act[:verbose_plus][:set]==:on \ +          || @md.opt.act[:maintenance][:set]==:on) +            SiSU_Screen::Ansi.new( +              @md.opt.act[:color_state][:set], +              "#{papersize} portrait ->" +            ).dark_grey_title_hi +          end +          cmd=SiSU_Env::SystemCall.new("#{tex_fn_base}.tex",'',@md.opt.selections.str) +          if @md.opt.act[:verbose][:set]==:on \ +          || @md.opt.act[:verbose_plus][:set]==:on \ +          || @md.opt.act[:maintenance][:set]==:on +            tell.grey_open +          end +          if "#{tex_fn_base}" =~/\w+/ \ +          and "#{papersize}" =~/\w+/ +            2.times { |i| cmd.latex2pdf(@md,papersize) } #comment out to skip processing of latex portrait +          end +          if @md.opt.act[:verbose][:set]==:on \ +          || @md.opt.act[:verbose_plus][:set]==:on \ +          || @md.opt.act[:maintenance][:set]==:on +            tell.p_off +          end +        end +        if @md.opt.act[:pdf_l][:set]==:on +          if (@md.opt.act[:verbose][:set]==:on \ +          || @md.opt.act[:verbose_plus][:set]==:on \ +          || @md.opt.act[:maintenance][:set]==:on) +            SiSU_Screen::Ansi.new( +              @md.opt.act[:color_state][:set], +              "#{papersize} landscape ->" +            ).dark_grey_title_hi +          end +          cmd=SiSU_Env::SystemCall.new("#{tex_fn_base}.landscape.tex",'',@md.opt.selections.str) +          if (@md.opt.act[:verbose][:set]==:on \ +          || @md.opt.act[:verbose_plus][:set]==:on \ +          || @md.opt.act[:maintenance][:set]==:on) +            tell.grey_open +          end +          if "#{tex_fn_base}" =~/\w+/ \ +          and "#{papersize}" =~/\w+/ +            2.times { |i| cmd.latex2pdf(@md,papersize) } #comment out to skip processing of latex landscape +          end +          if (@md.opt.act[:verbose][:set]==:on \ +          || @md.opt.act[:verbose_plus][:set]==:on \ +          || @md.opt.act[:maintenance][:set]==:on) +            tell.p_off +          end +        end +        pwd=Dir.pwd +        if @md.opt.act[:pdf_p][:set]==:on +          portrait_pdf="#{pwd}/#{tex_fn_base}.pdf" +        end +        if @md.opt.act[:pdf_l][:set]==:on +          landscape_pdf="#{pwd}/#{tex_fn_base}.landscape.pdf" +        end +        case papersize +        when /a4/     then pdf_p=@f.pdf_p_a4;     pdf_l=@f.pdf_l_a4 +        when /a5/     then pdf_p=@f.pdf_p_a5;     pdf_l=@f.pdf_l_a5 +        when /b5/     then pdf_p=@f.pdf_p_b5;     pdf_l=@f.pdf_l_b5 +        when /letter/ then pdf_p=@f.pdf_p_letter; pdf_l=@f.pdf_l_letter +        when /legal/  then pdf_p=@f.pdf_p_legal;  pdf_l=@f.pdf_l_legal +        else               pdf_p=@f.pdf_p_a4;     pdf_l=@f.pdf_l_a4 +        end +        FileUtils::mkdir_p(@md.file.output_path.pdf.dir) unless FileTest.directory?(@md.file.output_path.pdf.dir) +        cX=SiSU_Screen::Ansi.new(@md.opt.act[:color_state][:set]).cX +        if @md.opt.act[:pdf_p][:set]==:on +          if FileTest.file?(portrait_pdf) +            FileUtils::cp(portrait_pdf,"#{@md.file.output_path.pdf.dir}/#{pdf_p}") +            FileUtils::rm(portrait_pdf) +          else +            STDERR.puts "#{__FILE__}:#{__LINE__} NOT FOUND: #{portrait_pdf}" if @md.opt.act[:maintenance][:set]==:on +            errmsg="pdf file not generated #{portrait_pdf.gsub(/.+?([^\/]+?\.pdf)$/,'\1')} (check texlive dependencies)" +            if @md.opt.act[:no_stop][:set]==:on +              SiSU_Utils::CodeMarker.new(__LINE__,__FILE__,:fuchsia). +                error("#{errmsg}, proceeding without pdf output (as requested)") +            else +              SiSU_Utils::CodeMarker.new(__LINE__,__FILE__,:fuchsia). +                error("#{errmsg}, STOPPING") +              exit +            end +          end +        end +        if @md.opt.act[:pdf_l][:set]==:on +          if FileTest.file?(landscape_pdf) +            FileUtils::cp(landscape_pdf,"#{@md.file.output_path.pdf.dir}/#{pdf_l}") +            FileUtils::rm(landscape_pdf) +          else +            STDERR.puts "#{__FILE__}:#{__LINE__} NOT FOUND: #{landscape_pdf}" if @md.opt.act[:maintenance][:set]==:on +            errmsg="pdf file not generated #{landscape_pdf.gsub(/.+?([^\/]+?\.pdf)$/,'\1')} (check texlive dependencies)" +            if @md.opt.act[:no_stop][:set]==:on +              SiSU_Utils::CodeMarker.new(__LINE__,__FILE__,:fuchsia). +                error("#{errmsg}, proceeding without pdf output (as requested)") +            else +              SiSU_Utils::CodeMarker.new(__LINE__,__FILE__,:fuchsia). +                error("#{errmsg}, STOPPING") +              exit +            end +          end +        end +        if (@md.opt.act[:verbose][:set]==:on \ +        || @md.opt.act[:verbose_plus][:set]==:on \ +        || @md.opt.act[:maintenance][:set]==:on) +          SiSU_Screen::Ansi.new( +            @md.opt.act[:color_state][:set], +            @@n_lpdf, +            'processed (SiSU LaTeX to pdf - using pdfetex aka. pdftex or pdflatex)' +          ).generic_number +        end +      end +      def latexrun_selective +        begin +          pwd=Dir.pwd +          Dir.chdir(pwd) #watch +          @tex_f_no=0 +          if FileTest.file?(@env.source_file_with_path) +            @md.papersize_array.each do |ps| +              if @md.fns =~/\.(?:-|ssm\.)?sst$/ +                case @md.fns +                when /\.(?:-|ssm\.)?sst$/ +                  if FileTest.directory?(@env.processing_path.tex)==true +                    Dir.chdir(@env.processing_path.tex) +                    texfile=@md.fns.gsub(/$/,".#{ps}.tex"). +                      gsub(/~/,'-') +                    if @md.opt.act[:pdf_p][:set]==:on \ +                    or @md.opt.act[:pdf_l][:set]==:on +                      latex_do(texfile,ps) +                      if @md.opt.act[:pdf_p][:set]==:on +                        if File.exist?(texfile) \ +                        and File.size(texfile) > 0 +                          #@tex_f_no+=1 +                        else +                          errmsg="zero file size #{@env.processing_path.tex}/#{texfile}" +                          if @md.opt.act[:no_stop][:set]==:on +                            SiSU_Utils::CodeMarker.new(__LINE__,__FILE__,:fuchsia). +                              error("#{errmsg}, proceeding without pdf output (as requested)") +                          else +                            SiSU_Utils::CodeMarker.new(__LINE__,__FILE__,:fuchsia). +                              error("#{errmsg}, STOPPING") +                            exit +                          end +                        end +                      end +                    end +                  end +                end +              end +            end +            case @md.papersize_array[0] #default pdf +            when /a4/     then pdf_p=@f.pdf_p_a4;     pdf_l=@f.pdf_l_a4 +            when /a5/     then pdf_p=@f.pdf_p_a5;     pdf_l=@f.pdf_l_a5 +            when /b5/     then pdf_p=@f.pdf_p_b5;     pdf_l=@f.pdf_l_b5 +            when /letter/ then pdf_p=@f.pdf_p_letter; pdf_l=@f.pdf_l_letter +            when /legal/  then pdf_p=@f.pdf_p_legal;  pdf_l=@f.pdf_l_legal +            else               pdf_p=@f.pdf_p_a4;     pdf_l=@f.pdf_l_a4 +            end +            if @md.opt.act[:pdf_p][:set]==:on +              if FileTest.file?("#{@md.file.output_path.pdf.dir}/#{pdf_p}") +                mklnk=((@md.file.output_dir_structure.by_language_code?) \ +                || (@md.file.output_dir_structure.by_filetype?)) \ +                ? "#{@md.fnb}.portrait.pdf" +                : 'portrait.pdf' +                if FileTest.directory?(@md.file.output_path.pdf.dir) +                  pwd=Dir.pwd +                  Dir.chdir(@md.file.output_path.pdf.dir) +                  FileUtils::rm_f(mklnk) +                  FileUtils::ln_s(pdf_p, mklnk) +                  Dir.chdir(pwd) +                end +              end +            end +            if @md.opt.act[:pdf_l][:set]==:on +              if FileTest.file?("#{@md.file.output_path.pdf.dir}/#{pdf_l}") +                mklnk=((@md.file.output_dir_structure.by_language_code?) \ +                || (@md.file.output_dir_structure.by_filetype?)) \ +                ? "#{@md.fnb}.landscape.pdf" +                : 'landscape.pdf' +                pwd_set=Dir.pwd +                Dir.chdir(@md.file.output_path.pdf.dir) +                FileUtils::rm_f(mklnk) +                FileUtils::ln_s(pdf_l, mklnk) +                Dir.chdir(pwd_set) +              end +            end +          else +            SiSU_Screen::Ansi.new( +              @md.opt.act[:color_state][:set], +              "*WARN* FILE NOT FOUND: << #{@md.fns} >> - requested latex system processing skipped" +            ).warn +          end +          lst=Dir["*.{aux,log,out}"] +          lst.each {|file| File.unlink(file)} if lst +        rescue +          SiSU_Errors::Rescued.new($!,$@,@md.opt.selections.str,@md.fns).location do +            __LINE__.to_s + ':' + __FILE__ +          end +        end +      end +    end +    class LaTeXcreate +      include SiSU_Parts_TeXpdf +      @@tex_head={ +        'a4'=>    { p: nil, l: nil }, +        'a5'=>    { p: nil, l: nil }, +        'b5'=>    { p: nil, l: nil }, +        'letter'=>{ p: nil, l: nil }, +        'legal'=> { p: nil, l: nil }, +        'book'=>  { p: nil, l: nil } +      } +      @@prefix_b=nil +      def initialize(particulars) +        @particulars=particulars +        @md=@particulars.md +        @env=SiSU_Env::InfoEnv.new(@md.fns) #@env=@particulars.env +        @data=@particulars.ao_array # ao file drawn here +        @st={ tex: {} } +        @tex_ml=SiSU_TeX_Pdf::UseTeX.new(@md) +        @dp=@@dp ||=SiSU_Env::InfoEnv.new.digest.pattern +        l=SiSU_Env::StandardiseLanguage.new(@md.opt.lng).language +        @language=l[:n] +        @translate=SiSU_Translate::Source.new(@md,@language) +        @codeblock_box='listings' #alternative 'boites' +        @make ||=SiSU_Env::ProcessingSettings.new(@md) +      end +      def songsheet +        begin +          data=@data +          @@tex_footnote_array=[] +          @@rights=nil +          txt_gen=if @md.opt.act[:pdf_l][:set]==:on \ +          and @md.opt.act[:pdf_p][:set]==:on +            'pdfTex portrait & landscape' +          elsif @md.opt.act[:pdf_l][:set]==:on +            'pdfTex landscape' +          elsif @md.opt.act[:pdf_p][:set]==:on +            'pdfTex portrait' +          else +            SiSU_Utils::CodeMarker.new(__LINE__,__FILE__,:fuchsia).error('error: neither landscape nor portrait') +          end +          if (@md.opt.act[:verbose][:set]==:on \ +          || @md.opt.act[:verbose_plus][:set]==:on \ +          || @md.opt.act[:maintenance][:set]==:on) +            SiSU_Screen::Ansi.new( +              @md.opt.act[:color_state][:set], +              txt_gen +            ).txt_grey +          end +          if defined? @md.rights.all \ +          and not @md.rights.all.empty? +            sp_char=SiSU_TeX_Pdf::SpecialCharacters.new(@md,@md.rights.copyright.copyright_and_license.dup) +            copymark='Copyright {\begin{small}{\copyright\end{small}} ' +           #copymark='Copyright {\begin{small}^{\copyright\end{small}} ' +            copyright=sp_char.special_characters_safe.gsub(/\s*Copyright \(C\)/, copymark) +            @@rights||="\n #{Tex[:backslash]*2}[3]\\ \\linebreak #{copyright}" +          end +          if defined? @md.notes.prefix_b \ +          and not @md.notes.prefix_b.empty? +            sp_char=SiSU_TeX_Pdf::SpecialCharacters.new(@md,@md.notes.prefix_b) +            prefix_b=sp_char.special_characters_safe +            @@prefix_b="\n #{Tex[:backslash]*2}[3]\\ \\linebreak \\ #{prefix_b}\n" unless @@prefix_b +          end +          data=pre(data) +          data=footnote(data) +          if @md.flag_tables #WORK ON 2009 +            data=tables(data) #uncomment to start experimenting with tables +          end +          data=number_paras(data) +          data=markup(data) +          output(data) +        rescue +          SiSU_Errors::Rescued.new($!,$@,@md.opt.selections.str,@md.fns).location do +            __LINE__.to_s + ':' + __FILE__ +          end +        ensure +        end +      end +    protected +      def pre(data) +        @tex_file=[] +        data.each do |dob| +          # DEBUG 2003w16 this is a kludge, because i could not get parameters +          # from param, Sort out ... revert to more elegant solution +          # even more of a kludge as had to insert newlines where code is used not satisfactory, think about +          dob.tmp=dob.obj #.dup +          if dob.is==:para \ +          || dob.is==:heading +            dob.tmp=dob.tmp.gsub(/#{Mx[:mk_o]}:name#\S+?#{Mx[:mk_c]}/,'') +            dob.tmp=SiSU_TeX_Pdf::SpecialCharacters.new(@md,dob.tmp).special_characters +            if dob.tmp =~/#{Mx[:lnk_o]}.+?#{Mx[:lnk_c]}#{Mx[:rel_o]}\S+?#{Mx[:rel_c]}/ +              dob.tmp=SiSU_TeX_Pdf::FormatTextObject.new(@md,dob.tmp).url_str_internal(dob.tmp) +            end +          elsif dob.is ==:code +            dob.tmp=if @codeblock_box=='listings' +              dob.tmp +            else +              SiSU_TeX_Pdf::SpecialCharacters.new(@md,dob.tmp).special_characters_code +            end +          elsif dob.is ==:break +            if dob.obj==Mx[:br_page]; dob.tmp='\newpage' +            elsif dob.obj==Mx[:br_page_new]; dob.tmp='\clearpage' +            elsif dob.obj==Mx[:br_page_line]; dob.tmp=' \\ \hline \\ ' +            elsif dob.obj==Mx[:br_obj]; dob.tmp='\parasep' +            end +          elsif dob.is==:comment \ +          || dob.is==:meta +            dob.tmp='' #dob.tmp=nil +          end +        end +        data +      end +      def footnote(data) +        data.each do |dob| +          # EMBEDDED FOOTNOTES / ENDNOTES should be straightforward but not quite a synch. +          if dob.tmp =~/#{Mx[:en_a_o]}[\d*+]+\s|#{Mx[:en_b_o]}([*+]\d+)\s/ +            dob.tmp=dob.tmp.gsub(/#{Mx[:en_a_o]}(\d+)\s+(.+?)#{Mx[:en_a_c]}/m,"\\footnote[\\1]{%\n \\2} "). +              gsub(/#{Mx[:en_b_o]}([*+]\d+)\s+(.+?)#{Mx[:en_b_c]}/m,"\\FootnoteA{\\1}{%\n \\2} "). +              gsub(/#{Mx[:en_a_o]}([*+]+)\s+(.+?)#{Mx[:en_a_c]}/m,"\\FootnoteA{\\1}{%\n \\2} ") +          end +        end +        data +      end +      def tables_hash(md,dob) +        @block={} +        @dob=dob +        @md.papersize_array.each do |ps| +          @@tableheader={ ps => { p: 0, l: 0 } } +          dob.tmp={ tmp: dob.tmp, paper_size: ps } +          format_l=SiSU_TeX_Pdf::FormatTextObject.new(md,dob) +          dob.tmp={ tmp: dob.tmp, paper_size: ps } +          format_p=SiSU_TeX_Pdf::FormatTextObject.new(md,dob) +          @block[ps]={ +            l: format_l.longtable_landscape, +            p: format_p.longtable_portrait +          } +        end +        @dob.tmp=@block +        @dob +      end +      def tables(data) +        @tex_file=[] +        data.each do |dob| +          @tex_file << if dob.is_a?(String) \ +          or dob.is_a?(Hash) +            dob +          elsif dob.is==:table +            tables_hash(@md,dob) #Hash result +          else dob +          end +        end +        @tex_file +      end +      def enclose(dob) +        dob +      end +      def box_boites(dob,ocn) +        sp_char=SiSU_TeX_Pdf::SpecialCharacters.new(@md,dob.tmp,dob.is) +        dob.tmp=sp_char.special_characters_safe +        dob.tmp=dob.tmp.gsub(/(#{Mx[:nbsp]})/m,'{\color{mywhite}\1}'). +        #dob.tmp.gsub(/#{Mx[:nbsp]}/m,'{~}') # dob.tmp.gsub(/#{Mx[:nbsp]}\s*/m,'{~}') +          gsub(/#{Mx[:vline]}/m,'\vline'). +          gsub(/ \\( |#{Mx[:br_nl]})/,' {\textbackslash}\1'). +          gsub(/#{Mx[:br_nl]}\s*\Z/m,''). +          gsub(/#{Mx[:br_nl]}{2}/,'\newline \\\\\\ '). +          gsub(/#{Mx[:br_nl]}/,' \\\\\\ '). +          gsub(/\n\n\n/m," \\newline\n\n") +        ocn=SiSU_TeX_Pdf::FormatTextObject.new(@md).ocn_display(dob) +        dob.tmp = ocn \ +        + @tex_ml.paraskip_small \ +        + '\begin{Codeblock}' \ +        + '\begin{codeblockboitebox} \hardspace \newline ' \ +        + dob.tmp \ +        + '\end{codeblockboitebox}' \ +        + '\end{Codeblock}' \ +        + "\n" \ +        + @tex_ml.paraskip_normal +        dob +      end +      def box_listings(dob,ocn) +        sp_char=SiSU_TeX_Pdf::SpecialCharacters.new(@md,dob.tmp,dob.is) +        dob.tmp=sp_char.characters_code_listings +        dob.tmp=dob.tmp.gsub(/^\s+/m,''). #bug, fix earlier, should be made unecessary +          gsub(/#{Mx[:nbsp]}/m,' '). +          gsub(/#{Mx[:vline]}/m,'|'). +          gsub(/#{Mx[:br_nl]}(?:\s?\n)?/m,"\n"). +          gsub(/\n\n\n/m," \n\n") +        ocn=SiSU_TeX_Pdf::FormatTextObject.new(@md).ocn_display(dob) +        dob.tmp = ocn \ +        + @tex_ml.paraskip_small \ +        + '\begin{Codeblock}' \ +        + "\n" \ +        + '\begin{lstlisting} ' \ +        + "\n" \ +        + dob.tmp \ +        + "\n" \ +        + '\end{lstlisting} ' \ +        + "\n" \ +        + '\end{Codeblock}' \ +        + "\n" \ +        + @tex_ml.paraskip_normal +        dob +      end +      def markup_common(dob) +        if dob.of==:block +          @lineone=if dob.is==:block \ +          || dob.is==:group \ +          || dob.is==:alt \ +          || dob.is==:verse +            dob.tmp=dob.tmp.gsub(/#{Mx[:nbsp]}/m,' \hardspace '). +              gsub(/#{Mx[:gl_bullet]}/m,'\txtbullet \hardspace '). #Bullet environment not used for grouped text, no hanging indent here +              gsub(/#{Mx[:br_nl]}+/m,"\n\n") #match not ideal, but currently not inserting extra newlines anyway +            ocn=SiSU_TeX_Pdf::FormatTextObject.new(@md).ocn_display(dob) +            dob.tmp=if dob.is==:group \ +            || dob.is==:block \ +            || dob.is==:alt +              dob.tmp=SiSU_TeX_Pdf::SpecialCharacters.new(@md,dob.tmp).special_characters_safe +              ocn \ +              + @tex_ml.paraskip_small \ +              + "\n" \ +              + ' \\begin{footnotesize}' \ +              + "\n\n" \ +              + dob.tmp \ +              + '\\end{footnotesize}' \ +              + "\n" \ +              + @tex_ml.paraskip_normal +            elsif dob.is==:verse +              dob.tmp=dob.tmp.gsub(/#{Mx[:fa_bold_o]}(.+?)#{Mx[:fa_bold_c]}/m,'\begin{bfseries}\1 \end{bfseries}'). +                gsub(/#{Mx[:fa_italics_o]}(.+?)#{Mx[:fa_italics_c]}/m,'\emph{\1}'). +                gsub(/#{Mx[:fa_underscore_o]}(.+?)#{Mx[:fa_underscore_c]}/m,'\uline{\1}') +              ocn \ +              + @tex_ml.paraskip_tiny \ +              + "\n" \ +              + ' \\begin{footnotesize}' \ +              + "\n\n" \ +              + dob.tmp \ +              + '\\end{footnotesize}' \ +              + "\n" \ +              + @tex_ml.paraskip_normal \ +              + "\n\\linebreak\n" +            end +            dob +          elsif dob.is ==:code +            dob=if @codeblock_box == 'listings' +              box_listings(dob,ocn) +            elsif @codeblock_box == 'boites' +              box_boites(dob,ocn) +            else +              box_boites(dob,ocn) +            end +            dob +          else 'error' #should never occur +          end +          dob=enclose(dob) unless (dob.tmp.is_a?(String) && dob.tmp =~/^$/) +          dob +        else +          tst=SiSU_TeX_Pdf::FormatTextObject.new(@md,dob) +          case dob.is +          when :heading +            case dob.ln +            when 0 +              tst.title_level_A +            when 1 +              tst.section_heading_level_B +            when 2 +              tst.section_heading_level_C +            when 3 +              tst.section_heading_level_D +            when 4 +              tst.heading_level_1 +            when 5 +              tst.heading_level_2 +            when 6 +              tst.heading_level_3 +            when 7 +              tst.heading_level_4 +            else dob +            end +          when :heading_insert +            br="\n\\\\\n" +            if dob.name=='book_index' +              h=tst.section_heading_level_B +              heading="\\clearpage\n" + h.tmp +              idx_arr=[] +              idx=SiSU_Particulars::CombinedSingleton.instance.get_idx_raw(@md.opt).raw_idx +              idx.each do |x| +                x=if x.is_a?(String) +                  x=SiSU_TeX_Pdf::SpecialCharacters.new(@md,x).special_characters +                  x=SiSU_TeX_Pdf::FormatTextObject.new(@md,x).url_str_internal(x,true) +                else x=nil +                end +                idx_arr << x.sub(/,$/,'') if x.is_a?(String) +              end +              idx_str=idx_arr.join(br) +              l=heading + br + idx_str +              p=heading + br + +                '\begin{multicols}{2}' + br + +                idx_str + br + +                '\end{multicols}' +              dob.tmp={ l: l, p: p } +            elsif dob.ln==2 \ +            and dob.obj=~/Metadata\b/ +              tst.section_heading_level_B +            elsif dob.ln==4 \ +            and dob.obj=~/Metadata\b/ +              h=tst.heading_level_1 +              metadata=SiSU_Metadata::TeX_Metadata.new(@md).metadata_tex +              dob.tmp=h.tmp + ' ' + '\begin{scriptsize}' + metadata.join(br) + '\end{scriptsize}' +            else dob.tmp='' # dob.tmp={ l: '', p: '' } +            end +          when :para +            if dob.bullet_ +              dob.tmp=tst.bullet +            elsif dob.indent \ +            and dob.hang \ +            and dob.indent =~/[1-9]/ \ +            and dob.indent == dob.hang +              dob.tmp=tst.indent +            elsif dob.hang \ +            and dob.hang =~/[0-9]/ \ +            and (dob.indent != dob.hang or dob.indent =~/[1-9]/) +              dob.tmp=tst.hang +            else +              dob.tmp=dob.tmp.strip +              dob=enclose(dob) unless (dob.tmp.is_a?(String) && dob.tmp =~/^$/) +            end +          else +            dob.tmp=dob.tmp.strip unless dob.is==:code +            dob=enclose(dob) unless (dob.tmp.is_a?(String) && dob.tmp =~/^$/) +          end +          if dob.is_a?(String) +            dob.tmp=dob.tmp.gsub(/\s*(?:#{Mx[:br_line]}|#{Mx[:br_nl]})\s*/,' \newline ').   #% tread with care +              gsub(/(\.#{Tex[:tilde]}\S*\s*|<:\S+>|#{Mx[:fa_o]}.*?#{Mx[:fa_c]}|#{Mx[:gr_o]}.*?#{Mx[:gr_c]}|<!.*?!>|<!>)/,' ')   #% tread with care +          end +          dob +        end +        if (dob.tmp.is_a?(String) and dob.tmp =~/(?:#{Mx[:url_o]}\S+?#{Mx[:url_c]}|image\b)/m) \ +        && dob.is !=:code +          dob=SiSU_TeX_Pdf::BareUrls.new(@md,dob).bare_urls +          tst=SiSU_TeX_Pdf::FormatTextObject.new(@md,dob) +          dob=tst.urls_txt_and_images +          dob +        elsif (dob.tmp.is_a?(String) and dob.tmp  =~/https?:\/\/\S+\b/m) \ +        && dob.is ==:code \ +        && @codeblock_box !='listings' +          dob=SiSU_TeX_Pdf::BareUrls.new(@md,dob).bare_urls_in_code +          dob +        end +        if dob.class !=Hash \ +        && (dob.tmp.is_a?(String) and dob.tmp =~/#{Mx[:lnk_o]}.+?#{Mx[:lnk_c]}image\b/) \ +        && dob.is !=:code +          tst=SiSU_TeX_Pdf::FormatTextObject.new(@md,dob) +        end +        dob +      end +      def tex_box_listings +        <<-WOK +\\definecolor{listinggray}{gray}{0.9} +\\definecolor{lbcolor}{rgb}{0.9,0.9,0.9} +\\lstset{ +	backgroundcolor=\\color{lbcolor}, +	tabsize=4, +	rulecolor=, +	language=, +  basicstyle=\\scriptsize, +  upquote=true, +  aboveskip={1.5\\baselineskip}, +  columns=fixed, +  showstringspaces=false, +  extendedchars=true, +  breaklines=true, +  prebreak = \\raisebox{0ex}[0ex][0ex]{\\ensuremath{\\hookleftarrow}}, +  frame=single, +  showtabs=false, +  showspaces=false, +  showstringspaces=false, +  identifierstyle=\\ttfamily, +  keywordstyle=\\color[rgb]{0,0,1}, +  commentstyle=\\color[rgb]{0.133,0.545,0.133}, +  stringstyle=\\color[rgb]{0.627,0.126,0.941}, +} +        WOK +      end +      def tex_box_boites +        <<-WOK +\\def\\codeblockboitebox{% +  \\def\\bkvz@before@breakbox{\\ifhmode\\par\\fi\\vskip\\breakboxskip\\relax}% +  \\def\\bkvz@set@linewidth{\\advance\\linewidth -2\\fboxrule +    \\advance\\linewidth -2\\fboxsep} % +  \\def\\bk@line{\\hbox to \\linewidth{% +      \\ifbkcount\\smash{\\llap{\\the\\bk@lcnt\\ }}\\fi +      \\psframebox*[framesep=0pt,linewidth=0pt]{% +        \\vrule\\@width\\fboxrule \\hskip\\fboxsep +        \\box\\bk@bxa +        \\hskip\\fboxsep \\vrule\\@width\\fboxrule +        }% +      }}% +  %\\def\\bkvz@top{\\hrule\\@height\\fboxrule} +  \\def\\bkvz@top{\\hrule height .6pt}% +  \\def\\bkvz@bottom{\\hrule\\@height\\fboxrule}% +  \\breakbox} +\\def\\endcodeblockboitebox{\\endbreakbox} +        WOK +      end +      def tex_codeblock +        codeblock_box=if @codeblock_box=='listings' +          tex_box_listings +        elsif @codeblock_box=='boites' +          tex_box_boites +        else +          tex_box_boites +        end +        codeblock_box +      end +      def markup(data) +        @tex_file=[] +        home=the_text.txt_home.gsub(/#{Mx[:br_line]}|#{Mx[:br_nl]}|#{Mx[:br_paragraph]}|\\\\/,' - ') #no line splitting in heading neither html nor latex +        title=@md.title.full.gsub(/#{Mx[:br_line]}|#{Mx[:br_nl]}|#{Mx[:br_paragraph]}|\\\\/,' - ') #no line splitting in heading neither html nor latex +        @md.papersize_array.each do |ps| +          if @md.opt.act[:pdf_p][:set]==:on +            txt_obj={ txt: "#{home}: - #{title}", paper_size: ps, orientation: :portrait } +            orient_portrait=SiSU_TeX_Pdf::FormatHead.new(@md,txt_obj) +            @@tex_head[ps][:p]=orient_portrait.document_head_with_orientation(@codeblock_box) +          end +          if @md.opt.act[:pdf_l][:set]==:on +            txt_obj={ txt: "#{home}: - #{title}", paper_size: ps, orientation: :landscape } +            orient_landscape=SiSU_TeX_Pdf::FormatHead.new(@md,txt_obj) +            @@tex_head[ps][:l]=orient_landscape.document_head_with_orientation(@codeblock_box) +          end +        end +        @tex_file << <<-WOK +#{@tex_ml.header}#{@tex_ml.footer} +\\tolerance=300 +\\clubpenalty=300 +\\widowpenalty=300 +\\makeatother +\\makeatother +\\chardef\\txtbullet="2022 +\\chardef\\tilde="7E +%\\chardef\\asterisk="2A +\\def\\asterisk{{\\rm \\char42} } +\\definecolor{Light}{gray}{.92} +\\newcommand{\\Codeblock}[1]{\\normaltext\\raggedright\\small\\ttfamily\\texbackslash#1} +\\newcommand{\\monosp}[1]{\\normaltext\\ttfamily\\texbackslash#1} +\\newcommand{\\parasep}{\\\\ \\begin{center}*\\hspace{2em}*\\hspace{2em}*\\end{center} \\\\} +\\newcommand{\\hardspace}{{~}} +%\\newcommand{\\hardspace}{\\hspace{.5em}} +\\newcommand{\\caret}{{\\^{~}}} +\\newcommand{\\pipe}{{\\textbar}} +\\newcommand{\\curlyopen}{\{} +\\newcommand{\\curlyclose}{\}} +\\newcommand{\\lt}{{\UseTextSymbol{OML}{<}}} +\\newcommand{\\gt}{{\UseTextSymbol{OML}{>}}} +\\newcommand{\\slash}{{/}} +\\newcommand{\\underscore}{\\_} +\\newcommand{\\exclaim}{\\Verbatim{!}} +#{tex_codeblock} +% (tilde hash amp affected by http) +% \\sloppy +\\begin{document} +        WOK +        @copymark='' #check and remove as now is superflous +        x={} +        txt_obj={ title: @md.title.full } +        if @md.opt.act[:pdf_l][:set]==:on +          x[:l]=SiSU_TeX_Pdf::FormatTextObject.new(@md,txt_obj).title_landscape +        end +        if @md.opt.act[:pdf_p][:set]==:on +          x[:p]=SiSU_TeX_Pdf::FormatTextObject.new(@md,txt_obj).title_portrait +        end +        @tex_file << x +        x=nil +        if defined? @md.creator.author \ +        and @md.creator.author +          sp_char=SiSU_TeX_Pdf::SpecialCharacters.new(@md,@md.creator.author) +          author=sp_char.special_characters +          @tex_file << if @md.author_home +            <<-WOK + +\\author{\\href{#{@md.author_home}}{#{@copymark} \\textnormal{#{author}}}} +            WOK +          else "\n\\author{#{@copymark} \\textnormal{#{author}}}" +          end +        end +        if defined? @md.make.cover_image \ +        and not @md.make.cover_image.nil? \ +        and @md.make.cover_image[:cover] =~/\S+/ +          x={} +          dir=SiSU_Env::InfoEnv.new(@md.fns) +          x[:l] =<<-WOK +\\titlepic{\\includegraphics[width=0.3\\textwidth]{#{dir.path.image_source_include}/#{@md.make.cover_image[:cover]}}} +          WOK +          x[:p] =<<-WOK +\\titlepic{\\includegraphics[width=0.6\\textwidth]{#{dir.path.image_source_include}/#{@md.make.cover_image[:cover]}}} +          WOK +          @tex_file << x +          x=nil +        end +        @tex_file << unless @md.fnb =~/^mail\s*$/ then @tex_ml.site +        else                                           '\date' +        end +        @tex_file << <<-WOK +\\pagenumbering{roman}\\maketitle +\\pagestyle{fancy} +        WOK +        if defined? @md.rights.all \ +        and @md.rights.all +          @tex_file << "\\newpage\n" +          @tex_file << @@rights +          @tex_file << @@prefix_b if defined? @md.creator.prefix_b and @md.creator.prefix_b +        end +        x={} +        if (@make.build.toc?) +          toc=<<-WOK +\\renewcommand{\\contentsname}{#{@translate.contents}} +\\tableofcontents +          WOK +          toc_pb={ l: @tex_ml.newpage(:landscape), p: @tex_ml.newpage(:portrait) } +        else +          toc='' +          toc_pb={ l: '', p: '' } +        end +        if @md.opt.act[:pdf_l][:set]==:on +          x[:l] =<<-WOK +#{@tex_ml.newpage(:landscape)} +\\pagestyle{fancy} +#{toc}#{toc_pb[:l]} +\\pagenumbering{arabic} +#{@tex_ml.paraskip_normal} +#{@tex_ml.newpage(:landscape)} +          WOK +        end +        if @md.opt.act[:pdf_p][:set]==:on +          x[:p] =<<-WOK +#{@tex_ml.newpage(:portrait)} +\\pagestyle{fancy} +#{toc}#{toc_pb[:p]} +#{@tex_ml.newpage(:portrait)} +\\pagenumbering{arabic} +#{@tex_ml.paraskip_normal} +#{@tex_ml.newpage(:portrait)} +          WOK +        end +        @tex_file << x +        x=nil +        data.each do |dob|                                                      #% case follows with levels 1-6 indents & graphics +          if dob.is_a?(Hash) +          elsif dob.of==:para \ +          || dob.of==:block #GATEWAY FIX FIX stuff +            dob=markup_common(dob) +          elsif dob.is==:table +            if ( dob.tmp['a4'] \ +            or dob.tmp['a5'] \ +            or dob.tmp['b5'] \ +            or dob.tmp['letter'] \ +            or dob.tmp['legal']) +              @md.papersize_array.each do |ps| +                if dob.tmp[ps] +                  if (dob.tmp[ps][:p] and dob.tmp[ps][:l]) +                    dob.tmp[ps]={ +                      p: markup_common(dob.tmp[ps][:p]), +                      l: markup_common(dob.tmp[ps][:l]) +                    } +                  else p "#{__FILE__}:#{__LINE__}" if @md.opt.act[:maintenance][:set]==:on +                  end +                end +              end +            elsif dob.tmp.is_a?(Hash) \ +            and (dob.tmp[:p] and dob.tmp[:l]) +              dob = { +                p: markup_common(dob.tmp[:p]), +                l: markup_common(dob.tmp[:l]) +              } +            else p "#{__FILE__}:#{__LINE__}" if @md.opt.act[:maintenance][:set]==:on +            end +          end +          @tex_file << dob +        end +        @st[:tex][:stmp]||=@md.stmpd +        stamp=@st[:tex][:stmp] if @st[:tex][:stmp] +        if stamp +          use=stamp.gsub(/\n/,"#{Tex[:backslash]*2}\n") +          @tex_file << "\n\\newpage\n" +          @tex_file << "\\section*" + +            "{#{@tex_ml.owner_chapter}}\n" + +            "\\addcontentsline{toc}" + +            "{section}{#{@tex_ml.owner_chapter}}\n" +          @tex_file << "#{use}\n" +          @tex_file << @@rights if @@rights +        end +        @tex_file << "\n\\end{document}" +      end +      def number_paras_numbering(dob) # need tables and other types of object +        if dob.of ==:para +          paranum=dob.ocn ? dob.ocn : '' +          paranum = '' if paranum.to_i==0 +          paranumber_display=if @make.build.ocn? +            tags='' +            #[keep] code that follows inserts "name tags" as hypertargets, currently using ocn (converting nametags to ocn) for internal linking, related code: |texpdf_format.rb|@|uses nametags directly| +            #if dob.tags.length > 0 # insert tags "hypertargets" +            #  dob.tags.each do |t| +            #    tags=tags +"\\hspace{0mm}\\hypertarget{#{t}}{\\hspace{0mm}}" +            #  end +            #end +            "\\begin{tiny}\\hspace{0mm}\\end{tiny}{\\marginpar{\\begin{tiny}\\hspace{0mm}\\hypertarget{#{dob.ocn}}{#{dob.ocn}}#{tags}\\end{tiny}}}" #ocn object citation numbering +          else '' +          end +          dob.tmp = paranumber_display + dob.tmp +        end +        dob +      end +      def number_paras(data) +        data.each do |dob| +          dob=if dob.is_a?(Hash) +            if ( dob['a4'] \ +            or dob['a5'] \ +            or dob['b5'] \ +            or dob['letter'] \ +            or dob['legal']) +              para_hash={} +              @md.papersize_array.each do |ps| +                if defined? dob.tmp and dob.tmp[ps] +                  if (dob.tmp[ps][:p] and dob.tmp[ps][:l]) +                    para_hash[ps]={ +                      p: number_paras_numbering(dob.tmp[ps][:p]), +                      l: number_paras_numbering(dob.tmp[ps][:l]) +                    } +                    dob.tmp=para_hash +                  else p "#{__FILE__}:#{__LINE__}" if @md.opt.act[:maintenance][:set]==:on +                  end +                end +              end +            elsif (dob.tmp[:p] and dob.tmp[:l]) +              dob.tmp = { +                p: number_paras_numbering(dob.tmp[:p]), +                l: number_paras_numbering(dob.tmp[:l]) +              } +            else p "#{__FILE__}:#{__LINE__}" if @md.opt.act[:maintenance][:set]==:on +            end +          else +            dob=if dob.of !=:comment \ +            || dob.of !=:meta \ +            || dob.of !=:layout +              number_paras_numbering(dob) +            else dob +            end +          end +        end +        data +      end +      def output_morph_hash(o) +        ps,h,fn=o[:ps],o[:h],o[:filename] +        if h[ps] \ +        and (h[ps][:p] or h[ps][:l]) +          if @md.opt.act[:pdf_p][:set]==:on +            if h[ps][:p] +              h[ps][:p]=h[ps][:p].gsub(/[ ]+$/m,''). +                gsub(/\n\n\n+/m,"\n\n") +            end +            if h[ps][:p] !~/\A\s*\Z/ +              fn[:portrait].puts h[ps][:p],"\n" +            end +          end +          if @md.opt.act[:pdf_l][:set]==:on +            if h[ps][:l] +              h[ps][:l]=h[ps][:l].gsub(/[ ]+$/m,''). +                gsub(/\n\n\n+/m,"\n\n") +            end +            if h[ps][:l] !~/\A\s*\Z/ +              fn[:landscape].puts h[ps][:l],"\n" +            end +          end +        elsif (h[:p] or h[:l]) +          if @md.opt.act[:pdf_p][:set]==:on +            if h[:p] +              h[:p]=h[:p].gsub(/[ ]+$/m,''). +                gsub(/\n\n\n+/m,"\n\n") +            end +            if h[:p] !~/\A\s*\Z/ +              fn[:portrait].puts h[:p],"\n" +            end +          end +          if @md.opt.act[:pdf_l][:set]==:on +            if h[:l] +              h[:l]=h[:l].gsub(/[ ]+$/m,''). +                gsub(/\n\n\n+/m,"\n\n") +            end +            if h[:l] !~/\A\s*\Z/ +              fn[:landscape].puts h[:l],"\n" +            end +          end +        else p "#{__FILE__}:#{__LINE__}" if @md.opt.act[:maintenance][:set]==:on +        end +      end +      def output(array) +        @array=array=array.flatten.compact +        fns=@md.fns.gsub(/~/,'-') #this is a sorry fix, but necessary as it appears latex programs like not ~ +        @md.papersize_array.each do |ps| +          texfile_landscape=(@md.opt.act[:pdf_l][:set]==:on) \ +          ? (File.new("#{@env.processing_path.tex}/#{fns}.#{ps}.landscape.tex",'w+')) +          : nil +          texfile_portrait=(@md.opt.act[:pdf_p][:set]==:on) \ +          ? (File.new("#{@env.processing_path.tex}/#{fns}.#{ps}.tex",'w+')) +          : nil +          file={ +            landscape: texfile_landscape, +            portrait:  texfile_portrait +          } +          if @md.opt.act[:pdf_p][:set]==:on +            file[:portrait] << @@tex_head[ps][:p] +          end +          if @md.opt.act[:pdf_l][:set]==:on +            file[:landscape] << @@tex_head[ps][:l] +          end +          array.each do |morph| +            if morph.is_a?(String) +              #morph.gsub!(/^\s+/,'') +              if morph !~/\A\s*\Z/ +                if @md.opt.act[:pdf_p][:set]==:on +                  file[:portrait].puts morph,"\n" +                end +                if @md.opt.act[:pdf_l][:set]==:on +                  file[:landscape].puts morph,"\n" +                end +              end +            elsif morph.class.inspect =~ /SiSU_AO_DocumentStructure/ \ +            and morph.tmp \ +            and morph.tmp.is_a?(String) +              if morph.is !=:code \ +              && morph.of !=:block +                morph.tmp=morph.tmp.gsub(/^\s+/,'') +              else morph.tmp +              end +              if (morph.tmp !~/\A\s*\Z/) \ +              || morph.is==:code +                if @md.opt.act[:pdf_p][:set]==:on +                  file[:portrait].puts morph.tmp,"\n" +                end +                if @md.opt.act[:pdf_l][:set]==:on +                  file[:landscape].puts morph.tmp,"\n" +                end +              end +            elsif morph.is_a?(Hash)            #inserted headers and the like, only +              h={ ps: ps, h: morph, filename: file } +              output_morph_hash(h) +            elsif morph.tmp.is_a?(Hash)       #tables & images? +              h={ ps: ps, h: morph.tmp, filename: file } +              output_morph_hash(h) +            end +          end +          array=@array +          if @md.opt.act[:pdf_p][:set]==:on +            file[:portrait].close +          end +          if @md.opt.act[:pdf_l][:set]==:on +            file[:landscape].close +          end +        end +        @@tex_head={ +          'a4'=>    { p: nil, l: nil }, +          'a5'=>    { p: nil, l: nil }, +          'b5'=>    { p: nil, l: nil }, +          'letter'=>{ p: nil, l: nil }, +          'legal'=> { p: nil, l: nil }, +          'book'=>  { p: nil, l: nil } +        } +        array=[] +      end +    end +  end +end +__END__ +#+END_SRC + +** texpdf_parts.rb + +#+BEGIN_SRC ruby  :tangle "../lib/sisu/texpdf_parts.rb" +# <<sisu_document_header>> +module SiSU_Parts_TeXpdf +  require_relative 'generic_parts'                       # generic_parts.rb +  include SiSU_Parts_Generic +  def the_line_break +    ' \\ ' +  end +  def url_decoration +    def tex_open                     #'{\UseTextSymbol{OML}{<}}' +      Dx[:url_o] +    end +    def tex_close                    #'{\UseTextSymbol{OML}{>}}' +      Dx[:url_c] +    end +    def txt_open +      '<' +    end +    def txt_close +      '>' +    end +    self +  end +  def the_font +    def set_fonts +      'verdana, arial, georgia, tahoma, sans-serif, helvetica, times, roman' +    end +    self +  end +  class TeX +    def initialize(papersize='') +      @papersize=papersize +    end +    def a4 +      def portrait +        def w +          160 +        end +        def h +          228 +        end +        def img_px +          450 +        end +        self +      end +      def landscape +        def w +          238 +        end +        def h +          160 +        end +        def img_px +          300 +        end +        self +      end +      self +    end +    def letter +      def portrait +        def w +          166 +        end +        def h +          212 +        end +        def img_px +          468 +        end +        self +      end +      def landscape +        def w +          226 +        end +        def h +          166 +        end +        def img_px +          290 +        end +        self +      end +      self +    end +    def legal +      def portrait +        def w +          168 +        end +        def h +          286 +        end +        def img_px +          474 +        end +        self +      end +      def landscape +        def w +          296 +        end +        def h +          166 +        end +        def img_px +          420 +        end +        self +      end +      self +    end +    def b5 +      def portrait +        def w +          140 +        end +        def h +          204 +        end +        def img_px +          356 +        end +        self +      end +      def landscape +        def w +          200 +        end +        def h +          130 +        end +        def img_px +          260 +        end +        self +      end +      self +    end +    def a5 +      def portrait +        def w +          112 +        end +        def h +          162 +        end +        def img_px +          280 +        end +        self +      end +      def landscape +        def w +          152 +        end +        def h +          100 +        end +        def img_px +          190 +        end +        self +      end +      self +    end +    def dimensions +      case @papersize +      when /a4/     then a4 +      when /letter/ then letter +      when /legal/  then legal +      when /b5/     then b5 +      when /a5/     then a5 +      else               a4 +      end +    end +  end +end +__END__ +#+END_SRC + +** texpdf_format.rb + +#+BEGIN_SRC ruby  :tangle "../lib/sisu/texpdf_format.rb" +# <<sisu_document_header>> +module SiSU_TeX_Pdf +  require_relative 'texpdf_parts'                        # texpdf_parts.rb +  @@table_pg_break_counter=1 +  class BareUrls +    include SiSU_Parts_TeXpdf +    def initialize(md,dob=nil) +      @md,@dob=md,dob +    end +    def bare_urls +      @dob.obj=@dob.obj.gsub(/#{Mx[:url_o]}([a-zA-Z0-9._-]+\@[a-zA-Z0-9_-]+?\.[a-zA-Z0-9._-]+)#{Mx[:url_c]}/, +         "#{url_decoration.tex_open}\\begin{scriptsize}\\email{\\1}#{url_decoration.tex_close}") +      @dob.tmp=@dob.tmp.gsub(/(^|[^\\])_/m,'\1\_'). #watch may not work +        gsub(/(^|[^#{Mx[:lnk_c]}])#{Mx[:url_o]}_?(?:\\?_)?(\S+?)#{Mx[:url_c]}/m, +          "\\1#{url_decoration.tex_open}\\begin{scriptsize}\\url{\\2}\\end{scriptsize}#{url_decoration.tex_close}") +      @dob +    end +    def bare_urls_in_code +      @dob.tmp=@dob.tmp.gsub(/(^|[^\\])_/m,'\1\_'). #watch may not work +        gsub(/(https?:\/\/\S+?)([{]|[.,;)\]]?(?: |$))/m, +          '\begin{scriptsize}\url{\1}\end{scriptsize}\2') +      @dob +    end +  end +  class FormatTextObject +    include SiSU_Parts_TeXpdf +    attr_accessor :string,:string1,:orientation,:url,:dir,:tex +    @@sys=SiSU_Env::SystemCall.new +    @@tex_pattern_margin_number=/\\begin\{tiny\}\\hspace\{0mm\}\\end\{tiny\}\{\\marginpar.+?\}\}\}/ +    @@tableheader={ +      'a4' => { p: 0, l: 0 }, +      'a5' => { p: 0, l: 0 }, +      'b5' => { p: 0, l: 0 }, +      'letter' => { p: 0, l: 0 }, +      'legal' => { p: 0, l: 0 } +    } +    @@sys=SiSU_Env::SystemCall.new +    def initialize(md,dob=nil) +      @md,@dob=md,dob +      if defined? @md.image \ +      and @md.image =~/center/ +        @center_begin,@center_end='\begin{center}','\end{center}' +      else @center_begin,@center_end='','' +      end +      @start_table='' +      @tx=SiSU_Env::GetInit.new.tex +      @env ||=SiSU_Env::InfoEnv.new(@md.fns) +      @tex2pdf=@@tex3pdf ||=SiSU_Env::SystemCall.new.tex2pdf_engine +      @make ||=SiSU_Env::ProcessingSettings.new(@md) +    end +    def ocn_display(dob) +      show_ocn=(@make.build.ocn?) \ +      ? dob.ocn +      : '' +      "\\begin{tiny}\\hspace{0mm}\\end{tiny}{\\marginpar{\\begin{tiny}\\hspace{0mm}\\hypertarget{#{dob.ocn}}{#{show_ocn}}\\end{tiny}}}" #ocn object citation numbering +    end +    def table_special_characters(r) +      r=r.gsub(/#{Mx[:tc_p]}/mu,'&'). +        gsub(/#{Mx[:tc_c]}/m,'\\\\\\'). +        gsub(/%/,'\%'). +        gsub(/#{Mx[:fa_bold_o]}(.+?)#{Mx[:fa_bold_c]}/,'\begin{bfseries}\1 \end{bfseries}'). +        gsub(/#{Mx[:fa_italics_o]}(.+?)#{Mx[:fa_italics_c]}/,'\emph{\1}'). +        gsub(/#{Mx[:fa_underscore_o]}(.+?)#{Mx[:fa_underscore_c]}/,'\uline{\1}'). # ulem +        gsub(/#{Mx[:fa_cite_o]}(.+?)#{Mx[:fa_cite_c]}/,"``\\1''"). # quote #CHECK +        gsub(/#{Mx[:fa_insert_o]}(.+?)#{Mx[:fa_insert_c]}/,'\uline{\1}'). # ulem +        gsub(/#{Mx[:fa_strike_o]}(.+?)#{Mx[:fa_strike_c]}/,'\sout{\1}'). # ulem +        gsub(/#{Mx[:fa_superscript_o]}(.+?)#{Mx[:fa_superscript_c]}/,"\$^{\\textrm{\\1}}\$"). +        gsub(/#{Mx[:fa_subscript_o]}(.+?)#{Mx[:fa_subscript_c]}/,"\$_{\\textrm{\\1}}\$") +    end +    def longtable_landscape +      end_table='\end{longtable}' +      row_break='\\\\\\' +      if @dob.is==:table +        tw=case @dob.tmp[:paper_size] +        when /a4/i      then @tx.a4.landscape.w     #European default, SiSU default +        when /letter/i  then @tx.letter.landscape.w #U.S. default +        when /legal/i   then @tx.legal.landscape.w  #U.S. alternative +        when /book|b5/i then @tx.b5.landscape.w     #book default - larger +        when /a5/i      then @tx.a5.landscape.w +        else             @tx.a4.landscape.w     #default currently A4 +        end +        textwidth=(tw.to_i/2) - 24 +        colW=[] +        colW << '{' +        @dob.widths.each  do |x| +          x=(x.to_i * textwidth)/100 +          col_w=x.to_s # x.gsub(/.+/,'l\|') #unless x.nil? +          colW << "p{#{col_w}mm}" if col_w +        end +        colW << '}' +        colW=colW.join +        start_table="\n\\setlength{\\LTleft}{0pt}\n\\setlength{\\LTright}{\\fill}\n" + +          "\\begin{tiny}\n\\begin{longtable}#{colW}\n" +        rows=@dob.obj.split(/#{Mx[:br_nl]}/) +        if @dob.head_ #result imperfect, check on +          rows[0]=rows[0].gsub(/(^|.+?)(?:#{Mx[:tc_p]}|$)/u,'\bfseries \1&'). +            gsub(/&\s*$/," #{row_break} \\hline\\endhead #{row_break}") +        end +        rows_new=[] +        rows.each do |r| +          r=table_special_characters(r) +          r=r.gsub(/$/," #{row_break}\n") unless r =~/#{row_break*2}$/ +          if r=~/\<!f(.+?)!\>/ # not tested table footer if any +            tablefoot=$1 +            r=r.gsub(/\<!f(.+?)!\>/,'') +            r="#{r} \\multicolumn{#{@dob.cols}}{l}{\\tiny #{tablefoot}} \\\\ \\hline\n\\endfoot\n\\hline\n" +          end +          rows_new << r +        end +        table=rows_new.join #@dob[:ao].obj=rows.join +        ocn_display(@dob) + start_table + table + " #{end_table}\n\\end{tiny}" +      else '' +      end +    end +    def longtable_portrait +      end_table='\end{longtable}' +      row_break='\\\\\\' +      if @dob.is==:table +        tw=case @dob.tmp[:paper_size] +        when /a4/i      then @tx.a4.portrait.w     #European default, SiSU default +        when /letter/i  then @tx.letter.portrait.w #U.S. default +        when /legal/i   then @tx.legal.portrait.w  #U.S. alternative +        when /book|b5/i then @tx.b5.portrait.w     #book default - larger +        when /a5/i      then @tx.a5.portrait.w +        else             @tx.a4.portrait.w         #default currently A4 +        end +        textwidth=tw.to_i - 20 +        colW=[] +        colW << '{' +        @dob.widths.each do |x| +          x=(x.to_i * textwidth)/100 #x=(x.to_i/100.0 * 160) +          col_w=x.to_s # x.gsub(/.+/,'l\|') #unless x.nil? +          colW << "p{#{col_w}mm}" if col_w +        end +        colW << '}' +        colW=colW.join +        start_table="\n\\setlength{\\LTleft}{0pt}\n\\setlength{\\LTright}{\\fill}\n" + +          "\\begin{tiny}\n\\begin{longtable}#{colW}\n" +        rows=@dob.obj.split(/#{Mx[:br_nl]}/) +        if @dob.head_ +          rows[0]=rows[0].gsub(/(^|.+?)(?:#{Mx[:tc_p]}|$)/u,'\bfseries \1&'). +            gsub(/&\s*$/," #{row_break} \\hline\\endhead #{row_break}") +        end +        rows_new=[] +        rows.each do |r| +          r=table_special_characters(r) +          r=r.gsub(/$/," #{row_break}\n") unless r =~/#{row_break*2}$/ +          if r=~/\<!f(.+?)!\>/ # not tested table footer if any +            tablefoot=$1 +            r=r.gsub(/\<!f(.+?)!\>/,'') +            r="#{r} \\multicolumn{#{@dob.cols}}{l}{\\tiny #{tablefoot}} \\\\ \\hline\n\\endfoot\n\\hline\n" +          end +          rows_new << r +        end +        table=rows_new.join #@dob[:ao].obj=rows.join +        ocn_display(@dob) + start_table + table + " #{end_table}\n\\end{tiny}" +      else '' +      end +    end +    def remove_footnotes(cont_ln) +      cont_ln=if cont_ln =~/\\[Ff]ootnote/m +        cont_ln.gsub(/\s*\\[Ff]ootnote\[\d+\]\{%\s+.+?\}\s*/m,' '). +          gsub(/\s*\\[Ff]ootnote[A]\{[*+]+\d*\}\{%\S+.+?\}\s*/m,' ') +      else cont_ln +      end +    end +    def title_level_A +      dob=@dob +      dob.tmp=dob.tmp.strip if dob.tmp +      dob.tmp=dob.tmp.gsub(/\\begin\{(bfseries|itshape)\}(.+?)\\end\{\1\}/m,'\2'). +        gsub(/#{Mx[:url_o]}|#{Mx[:url_c]}/,'') +      cont_ln=dob.tmp.dup +      cont_ln=cont_ln.gsub(/\\begin\{(monosp)\}(.+?)\\end\{\1\}/m,'\2'). +        gsub(@@tex_pattern_margin_number,'') +      cont_ln=remove_footnotes(cont_ln) +      cont_ln=cont_ln.gsub(/\{[\\]+(&)\}/,'\\1') +      titleset='' +      dob.tmp=dob.tmp.gsub(/^(.*)\n?$/m, +        "#{titleset}\\part*{\\1} +\\markboth{#{@md.title.full}}\n") +      dob +    end +    def section_heading_level(dob) +      dob.tmp=dob.tmp.strip if dob.tmp +      dob.tmp=dob.tmp.gsub(/\\begin\{(bfseries|itshape)\}(.+?)\\end\{\1\}/m,'\2'). +        gsub(/#{Mx[:url_o]}|#{Mx[:url_c]}/,'') +      cont_ln=dob.tmp.dup +      cont_ln=cont_ln.gsub(/\\begin\{(monosp)\}(.+?)\\end\{\1\}/m,'\2'). +        gsub(@@tex_pattern_margin_number,'') +      cont_ln=remove_footnotes(cont_ln) +      cont_ln=cont_ln.gsub(/\{[\\]+(&)\}/,'\\1') +      dob.tmp=dob.tmp.gsub(/^(.*)\n?$/m, +        "\\clearpage +\\part*{\\1} +\\addcontentsline{toc}{part}{#{cont_ln}} +\\markboth{#{@md.title.full}}\n") +      dob +    end +    def heading_dev_null(dob) +      dob.tmp,dob.obj='','' +      dob +    end +    def heading_sublevels(dob) +      if dob.lv=='1' +        sect='section' +        tocadd=%{\\addcontentsline{toc}{section}} +        pre='' +        post='' +        headadd=%{\n\\markright{#{@md.title.full}}} +      elsif dob.lv=='2' +        sect='subsection' +        tocadd=%{\\addcontentsline{toc}{subsection}} +        pre='' +        post=" \\\\\n" +        headadd='' +      elsif dob.lv=='3' +        sect='subsubsection' +        tocadd=%{\\addcontentsline{toc}{subsubsection}} +        pre='' #pre='~~~~' +        post=" \\\\\n" +        headadd='' +      end +      dob.tmp=dob.tmp.strip if dob.tmp +      dob.tmp=dob.tmp.gsub(/\\begin\{(bfseries|itshape)\}(.+?)\\end\{\1\}/m,'\2'). +        gsub(/#{Mx[:url_o]}|#{Mx[:url_c]}/,'') +      cont_ln=dob.tmp.dup +      cont_ln=cont_ln.gsub(/\\begin\{(monosp)\}(.+?)\\end\{\1\}/m,'\2'). +        gsub(@@tex_pattern_margin_number,''). +        gsub(/#{Tex[:backslash]*2}/,"#{Tex[:backslash]*4}"). # added w42 +        gsub(/\\footnote\[\d+\]\{%.+?\\end\{scriptsize\}\s*\}/m,''). #arbitrary bugfix, revisit should not be necessary, eg. wta.1994 2004w22 +        gsub(/\\Footnote[A]\{[*+]+\d*\}\{%.+?\\end\{scriptsize\}\s*\}/m,'') #arbitrary bugfix, revisit should not be necessary, eg. wta.1994 2004w22 +      if dob.name =~/endnotes/ +        dob.tmp=dob.tmp.gsub(/.+/m,'') +      end +      cont_ln=remove_footnotes(cont_ln) +      cont_ln=cont_ln.gsub(/\{[\\]+(&)\}/,'\\1') +      dob.tmp=dob.tmp.gsub(/^(.*)?\n?$/m, +        "\\#{sect}*{\\1} +#{tocadd}{#{pre}#{cont_ln}#{post}}#{headadd}") +      dob +    end +    def section_heading_level_B +      section_heading_level(@dob) +    end +    def section_heading_level_C +      section_heading_level(@dob) +    end +    def section_heading_level_D +      section_heading_level(@dob) +    end +    def heading_level_1 +      if not @dob.use_ == :dummy +        heading_sublevels(@dob) +      else +        heading_dev_null(@dob) +      end +    end +    def heading_level_2 +      heading_sublevels(@dob) +    end +    def heading_level_3 +      heading_sublevels(@dob) +    end +    def heading_level_4 +      heading_sublevels(@dob) +    end +    def hang +      _idt=10 +      indent = "#{_idt*(@dob.indent.to_i-1)}mm" +      hang =  "#{_idt*(@dob.hang.to_i - @dob.indent.to_i)}mm" +      "\\begin{ParagraphHang}{#{indent}}{#{hang}}#{@dob.tmp} \\end{ParagraphHang}}" +    end +    def indent +      indent=case @dob.indent +      when /1/ then '0mm' +      when /2/ then '10mm' +      when /3/ then '20mm' +      when /4/ then '30mm' +      when /5/ then '40mm' +      when /6/ then '50mm' +      when /7/ then '60mm' +      when /8/ then '70mm' +      when /9/ then '80mm' +      end +      "\\begin{ParagraphIndent}{#{indent}}#{@dob.tmp} \\end{ParagraphIndent}}" +    end +    def bullet +      blt=if @dob.indent +        indent=case @dob.indent +        when /1/ then '0em' +        when /2/ then '1.0em' +        when /3/ then '2.0em' +        when /4/ then '3.0em' +        when /5/ then '4.0em' +        when /6/ then '5.0em' +        when /7/ then '6.0em' +        when /8/ then '7.0em' +        when /9/ then '8.0em' +        else      '-1.0em' +        end +        "\\begin{Bullet}{#{indent}}$\\txtbullet$\\hspace{\\enspace}#{@dob.tmp}\\end{Bullet}" +      else +        "\\begin{Bullet}{-5mm}$\\txtbullet$\\hspace{\\enspace}#{@dob.tmp}\\end{Bullet}" +      end +      blt +    end +    def symbol_graphic +      dir=SiSU_Env::InfoEnv.new(@md.fns) +      image='c_' + /<:=\s*(\S+?)\s*>/m.match(@txt).captures.join + '.png' #watch +      if FileTest.file?("#{dir.path.image_source_include}/#{image}") +        @txt.gsub!(/<:=\s*(\S+?)\s*>/, +          "\\includegraphics*[width=11pt]{#{dir.path.image_source_include}/c_\\1.png}") +      else +        SiSU_Screen::Ansi.new( +          @md.opt.act[:color_state][:set], +          "ERROR - image:", +          %{"#{image}" missing}, +          "search path: #{dir.path.image_source_include}" +        ).error2 unless @md.opt.act[:quiet][:set]==:on +        @txt.gsub!(/#{Mx[:lnk_o]}\S+\.(png|jpg|gif).+?#{Mx[:lnk_c]}#{Mx[:url_o]}\S+?#{Mx[:url_c]}/,'') # fragile match operator\\ fragile ! +      end +    end +    def url_str_internal(str,idx=nil) +      map_nametags=SiSU_Particulars::CombinedSingleton.instance.get_map_nametags(@md).nametags_map #p map_nametags +      rgx_url_internal=/#{Mx[:lnk_o]}.+?#{Mx[:lnk_c]}#{Mx[:rel_o]}#?\S+?#{Mx[:rel_c]}/m +      while str =~/#{Mx[:lnk_o]}([^#{Mx[:lnk_o]}#{Mx[:lnk_c]}]+)#{Mx[:lnk_c]}#{Mx[:rel_o]}:(\S+?)#{Mx[:rel_c]}/m +        link,url=$1,$2 +        link,url=link.strip,url.strip +        link.gsub!(/&/,"#{Xx[:protect]}&") +        url="#{@env.url.root}/" + url +        str.sub!(/#{Mx[:lnk_o]}[^#{Mx[:lnk_o]}#{Mx[:lnk_c]}]+#{Mx[:lnk_c]}#{Mx[:rel_o]}:\S+?#{Mx[:rel_c]}/m, +          "#{url_decoration.tex_open}\\href{#{url}}{#{link}}#{url_decoration.tex_close}") +      end +      while str =~/#{Mx[:lnk_o]}([^#{Mx[:lnk_o]}#{Mx[:lnk_c]}]+)#{Mx[:lnk_c]}#{Mx[:rel_o]}#?(\S+?)#{Mx[:rel_c]}/m +        link,url=$1,$2 +        link,url=link.strip,url.strip +        link.gsub!(/&/,"#{Xx[:protect]}&") +        url.gsub!(/\\_/,'_') +        ocn_lnk=if map_nametags[url] \ +        and map_nametags[url][:ocn] +          map_nametags[url][:ocn] +        else nil +        end +        ocn_lnk=(url=~/^\d+$/ ? url : ocn_lnk) +        if ocn_lnk and not ocn_lnk.empty? +          idx \ +          ? (str.sub!(rgx_url_internal,"\\hyperlink{#{ocn_lnk}}{#{link}}")) +          : (str.sub!(rgx_url_internal,"#{url_decoration.tex_open}\\hyperlink{#{ocn_lnk}}{#{link}}#{url_decoration.tex_close}")) +        else +          puts %{name tag: "#{url}" not found} +          str.sub!(rgx_url_internal,"#{link}") +        end +        #[keep] code that follows uses nametags directly, currently nametags converted to their ocn, related code: |texpdf.rb|@|hypertargets| +        #idx \ +        #? (str.sub!(rgx_url_internal,"\\hyperlink{#{url}}{#{link}}")) \ +        #: (str.sub!(rgx_url_internal,"#{url_decoration.tex_open}\\hyperlink{#{url}}{#{link}}#{url_decoration.tex_close}")) +      end +      str=str.gsub(/#{Xx[:protect]}/,'') +    end +    def url_str(str) +      rgx_url_generic=/#{Mx[:lnk_o]}.+?#{Mx[:lnk_c]}#{Mx[:url_o]}\S+?#{Mx[:url_c]}/m +      while str =~rgx_url_generic +        if str=~rgx_url_generic +          regx_url=%r/#{Mx[:lnk_o]}(.+?)#{Mx[:lnk_c]}#{Mx[:url_o]}(\S+?)#{Mx[:url_c]}/m +          z,url=regx_url.match(str).captures if str =~regx_url +          url=url.strip +          link=z.strip +          link.gsub!(/&/,"#{Xx[:protect]}&") +          str.sub!(rgx_url_generic,"#{url_decoration.tex_open}\\href{#{url}}{#{link}}#{url_decoration.tex_close}") +          str=str.gsub(/#{Xx[:protect]}/,'') +          str +        else str +        end +        str +      end +      str +    end +    def url_with_txt(dob) +      rgx_url_generic=/#{Mx[:lnk_o]}.+?#{Mx[:lnk_c]}#{Mx[:url_o]}\S+?#{Mx[:url_c]}/m +      while dob.tmp =~rgx_url_generic +        if dob.tmp=~rgx_url_generic +          if dob.tmp =~/#{Mx[:lnk_o]}(?:.+?)#{Mx[:lnk_c]}#{Mx[:url_o]}\S+?#{Mx[:url_c]}/m +            regx_url=%r/#{Mx[:lnk_o]}(.+?)#{Mx[:lnk_c]}#{Mx[:url_o]}(\S+?)#{Mx[:url_c]}/m +            punctuate=/#{Mx[:lnk_o]}.+?#{Mx[:lnk_c]}#{Mx[:url_o]}\S+?#{Mx[:url_c]}/m.match(dob.tmp).captures.join +          else +            regx_url=%r/#{Mx[:lnk_o]}(.+?)#{Mx[:lnk_c]}#{Mx[:url_o]}(\S+?)#{Mx[:url_c]}/m +            punctuate='' +          end +          z,url=regx_url.match(dob.tmp).captures if dob.tmp =~regx_url +          url=url.strip +          link=z.strip +          link.gsub!(/&/,"#{Xx[:protect]}&") +          dob.tmp.sub!(rgx_url_generic,"#{url_decoration.tex_open}\\href{#{url}}{#{link}}#{url_decoration.tex_close}#{punctuate}") +          dob.tmp.gsub!(/#{Xx[:protect]}/,'') +          #dob.tmp=dob.tmp.sub(rgx_url_generic,"#{url_decoration.tex_open}\\href{#{url}}{#{link}}#{url_decoration.tex_close}#{punctuate}"). +          #  gsub(/#{Xx[:protect]}/,'') +          dob +        else dob +        end +        dob +      end +      dob +    end +    def urls_txt_and_images +      dob=@dob +      dir=SiSU_Env::InfoEnv.new(@md.fns) +      @dm={ +        'a4'=>     @tx.a4.landscape.img_px, +        'letter'=> @tx.letter.landscape.img_px, +        'legal'=>  @tx.legal.landscape.img_px, +        'b5'=>     @tx.b5.landscape.img_px, +        'a5'=>     @tx.a5.landscape.img_px +      } +      images_hash={ } +      generic_rgx=/#{Mx[:lnk_o]}.+?#{Mx[:lnk_c]}(?:#{Mx[:url_o]}\S+?#{Mx[:url_c]}|image\b)/m +      rgx_url_generic=/#{Mx[:lnk_o]}.+?#{Mx[:lnk_c]}#{Mx[:url_o]}\S+?#{Mx[:url_c]}/m +      #url_bare_rgx=/#{Mx[:url_o]}\S+?#{Mx[:url_c]}/m +      url_image_rgx=/#{Mx[:lnk_o]}[a-zA-Z0-9_\\-]+\.(?:png|jpg|gif).+?#{Mx[:lnk_c]}#{Mx[:url_o]}\S+?#{Mx[:url_c]}/m +      image_rgx=/#{Mx[:lnk_o]}[a-zA-Z0-9_\\-]+\.(?:png|jpg|gif).+?#{Mx[:lnk_c]}image/m +      @md.papersize_array.each do |ps| +        images_hash[ps] = dob.tmp +        while images_hash[ps] =~generic_rgx +          if dob.tmp =~rgx_url_generic \ +          and dob.tmp !~/\.(?:png|jpg|gif)|#{Mx[:lnk_c]}image\b/m +            dob=url_with_txt(dob) +          elsif images_hash[ps]=~generic_rgx +            if dob.tmp=~rgx_url_generic +              if images_hash[ps] =~/#{Mx[:lnk_o]}(?:.+?)#{Mx[:lnk_c]}#{Mx[:url_o]}\S+?#{Mx[:url_c]}/m +                regx_url=%r/#{Mx[:lnk_o]}(.+?)#{Mx[:lnk_c]}#{Mx[:url_o]}(\S+?)#{Mx[:url_c]}/m +                punctuate=/#{Mx[:lnk_o]}.+?#{Mx[:lnk_c]}#{Mx[:url_o]}\S+?#{Mx[:url_c]}/m.match(images_hash[ps]).captures.join +              else +                regx_url=%r/#{Mx[:lnk_o]}(.+?)#{Mx[:lnk_c]}#{Mx[:url_o]}(\S+?)#{Mx[:url_c]}/m +                punctuate='' +              end +              z,url=regx_url.match(images_hash[ps]).captures if images_hash[ps] =~regx_url +              url=url.strip +            else +              if images_hash[ps] =~/#{Mx[:lnk_o]}(?:.+?)#{Mx[:lnk_c]}image\.[^'"\s]+?(?:[;.,]?(?:\s|$)|(?:\s|$))/m +                regx_url=%r/#{Mx[:lnk_o]}(.+?)#{Mx[:lnk_c]}image\.[^'"\s]+?(?:[;.,]?(?:\s|$)|(?:\s|$))/m +                punctuate=/#{Mx[:lnk_o]}.+?#{Mx[:lnk_c]}image\.[^'"\s]+?([;.,]?(?:\s|$))/m.match(images_hash[ps]).captures.join +              else +                regx_url=%r/#{Mx[:lnk_o]}(.+?)#{Mx[:lnk_c]}image/m +                punctuate='' +              end +              z=regx_url.match(images_hash[ps])[1] if images_hash[ps] =~regx_url +              url='' +            end +            if images_hash[ps] =~/#{Mx[:lnk_o]}\s*\S+\.?(?:png|jpg|gif)/m \ +            and images_hash[ps]=~/\s+\d+x\d+(\s+|\s*#{Mx[:lnk_c]})/m +              image=z.scan(/\S+/)[0] #image,x,y=z.scan(/\S+/) +              image.gsub!(/\\/,'') +              w=((z =~/\s(\d+)x\d*/) ? z[/\s(\d+)x\d*/,1] : 200) +              width={} +              width['a4'] =     ((w.to_i > @dm['a4'])     ? @dm['a4'] :     w) +              width['letter'] = ((w.to_i > @dm['letter']) ? @dm['letter'] : w) +              width['legal'] =  ((w.to_i > @dm['legal'])  ? @dm['legal'] :  w) +              width['a5'] =     ((w.to_i > @dm['a5'])     ? @dm['a5'] :     w) +              width['b5'] =     ((w.to_i > @dm['b5'])     ? @dm['b5'] :     w) +              c=z[/``(.+?)''/m,1] +              hsp="\n{\\color{mywhite} .}&~\n" # ~ character for hardspace +              caption=(c ?  "{\\\\\ \n\\begin{scriptsize}#{hsp*3}#{c}\\end{scriptsize}&}" : '') +            elsif images_hash[ps] =~/#{Mx[:lnk_o]}\s*(\S+\.?\.(?:png|jpg|gif))/m +              SiSU_Screen::Ansi.new( +                @md.opt.act[:color_state][:set], +                %{document built without image: "#{$1}" as image dimensions not provided (either image not found or neither imagemagick nor graphicsmagick is installed)?\n} +              ).print_grey #unless @md.opt.act[:quiet][:set]==:on +              images_hash[ps].gsub!(/#{Mx[:lnk_o]}\s*(\S+\.?\.(?:png|jpg|gif))/,'[image]') +            end +            if image #most images fc etc. #% clean up ! +              if FileTest.file?("#{dir.path.image_source_include}/#{image}") +                case images_hash[ps] +                when url_image_rgx +                  images_hash[ps].sub!(url_image_rgx, +                    "#{@center_begin}\\\n\\href{#{url}}\n{\\includegraphics*[width=#{width[ps]}pt]{#{dir.path.image_source_include}/#{image}}}#{caption}#{@center_end}") +                when image_rgx +                  images_hash[ps].sub!(image_rgx, +                    "#{@center_begin}\\\n\\includegraphics*[width=#{width[ps]}pt]{#{dir.path.image_source_include}/#{image}}#{caption}#{@center_end}") +                end +                images_hash[ps] +              elsif @md.opt.f_pth[:pth] =~/\/\S+?\/sisupod\/\S+?\/sisupod\/doc/ +                pt=/(\/\S+?\/sisupod\/\S+?\/sisupod)\/doc/.match(@md.opt.f_pth[:pth])[1] +                img_src=pt + '/image' +                if FileTest.file?("#{img_src}/#{image}") +                  case images_hash[ps] +                  when url_image_rgx +                    images_hash[ps].sub!(url_image_rgx, +                      "#{@center_begin}\\\n\\href{#{url}}{\\includegraphics*[width=#{width[ps]}pt]{#{img_src}/#{image}}}#{caption} #{@center_end}") +                  when image_rgx +                    images_hash[ps].sub!(image_rgx, +                      "#{@center_begin}\\\n\\includegraphics*[width=#{width[ps]}pt]{#{img_src}/#{image}}#{caption} #{@center_end}") +                  end +                  images_hash[ps] +                end + +              elsif @md.fns =~/\.(?:ssm\.)?sst$/ \ +              and FileTest.file?("#{dir.path.image_source_include_local}/#{image}") +                case images_hash[ps] +                when url_image_rgx +                  images_hash[ps].sub!(url_image_rgx, +                    "#{@center_begin}\\\n\\href{#{url}}{\\includegraphics*[width=#{width[ps]}pt]{#{dir.path.image_source_include_local}/#{image}}}#{caption} #{@center_end}") +                when image_rgx +                  images_hash[ps].sub!(image_rgx, +                    "#{@center_begin}\\\n\\includegraphics*[width=#{width[ps]}pt]{#{dir.path.image_source_include_local}/#{image}}#{caption} #{@center_end}") +                end +                images_hash[ps] +              elsif @md.fns =~/\.-ss[tm]$/ \ +              and FileTest.file?("#{dir.path.image_source_include_remote}/#{image}") +                case images_hash[ps] +                when url_image_rgx +                  images_hash[ps].sub!(url_image_rgx, +                    "#{@center_begin}\\\n\\href{#{url}}{\\includegraphics*[width=#{width[ps]}pt]{#{dir.path.image_source_include_remote}/#{image}}}#{caption}#{@center_end}") +                when image_rgx +                  images_hash[ps].sub!(image_rgx, +                    "#{@center_begin}\\\n\\includegraphics*[width=#{width[ps]}pt]{#{dir.path.image_source_include_remote}/#{image}}#{caption}#{@center_end}") +                end +                images_hash[ps] +              else +                SiSU_Screen::Ansi.new( +                  @md.opt.act[:color_state][:set], +                  "ERROR - image:", +                  %{"#{image}" missing}, +                  "search locations: #{dir.path.image_source_include_local}, #{dir.path.image_source_include_remote} and #{dir.path.image_source_include}" +                ).error2 unless @md.opt.act[:quiet][:set]==:on +                if images_hash[ps] =~url_image_rgx \ +                or images_hash[ps] =~image_rgx +                  images_hash[ps]='' +                end +                images_hash[ps] +              end +            else +              link=z.strip #[/(.+?)\\/m,1] +              images_hash[ps]="\\href{#{url}}{#{link}}#{punctuate}" if images_hash[ps] =~/#{Mx[:lnk_o]}.+?#{Mx[:lnk_c]}#{Mx[:url_o]}\S+?#{Mx[:url_c]}/ +              images_hash[ps] +            end +          else images_hash[ps] +          end +          images_hash[ps] #=ocn_display(dob) + images_hash[ps] +        end #while loop +        images_hash +      end +      use_images_hash={} +      images_hash.each do |k,t| +        use_images_hash[k]={ l: t, p: t} +      end +      dob.tmp=use_images_hash +      dob +    end +    def title +      title=SiSU_TeX_Pdf::SpecialCharacters.new(@md,@md.title.full).special_characters_safe +      "\n\\title{#{title}}" +    end +    def title_landscape +      title +    end +    def title_portrait +      title +    end +  end +  class FormatHead +    require_relative 'prog_text_translation'        # prog_text_translation.rb +    def initialize(md,t_o) +      @md,@t_o=md,t_o +      @env=SiSU_Env::InfoEnv.new(@md.fns) +      if t_o.is_a?(Hash) +        @txt =t_o[:txt]            || nil +        @subtitle=t_o[:subtitle]   || nil +        @ps=t_o[:paper_size]       || nil +        @ocn=t_o[:ocn]             || nil +        @layout=t_o[:orientation]  || nil +      else +        p t_o.class +        p caller +      end +      @tx=SiSU_Env::GetInit.new.tex +      @tex2pdf=@@tex3pdf ||=SiSU_Env::SystemCall.new.tex2pdf_engine +      @ps=@txt if @txt=~/(?:a4|letter|legal|book|a5|b5)/i +      @lang ||=SiSU_i18n::Languages.new #.list[@md.opt.lng][:xlp] +      @author=if defined? @md.creator.author \ +      and @md.creator.author=~/\S+/ +        SiSU_TeX_Pdf::SpecialCharacters.new(@md,@md.creator.author).special_characters_safe +      else '' +      end +      @subject=if defined? @md.classify.subject \ +      and @md.classify.subject=~/\S+/ +        SiSU_TeX_Pdf::SpecialCharacters.new(@md,@md.classify.subject).special_characters_safe +      else '' +      end +      @keywords=if defined? @md.classify.keywords \ +      and @md.classify.keywords=~/\S+/ +        SiSU_TeX_Pdf::SpecialCharacters.new(@md,@md.classify.keywords).special_characters_safe +      else '' +      end +    end +    def tex_head_lang #babel 18n +      lang_char_arr=@md.i18n +      mainlang_char=if @md.i18n == Array \ +      and @md.i18n.length > 0 +        lang_char_arr.slice(0) +      else @md.opt.lng +      end +      mainlang=@lang.list[mainlang_char][:xlp] +      otherlang=if mainlang != 'english' +        [ @lang.list['en'][:xlp] ] +      else [] +      end +      if lang_char_arr.length > 0 +        lang_char_arr.slice(1..9).each { |ch| otherlang << @lang.list[ch][:xlp] } +        otherlang=otherlang.uniq +      end +      otherlang=otherlang.join(',') +      { mainlang: mainlang, otherlang: otherlang } +    end +    def tex_head_encode +      texpdf_fontface=if defined? @md.make.texpdf_fontface.main \ +      and not @md.make.texpdf_fontface.main.nil? \ +      and @md.make.texpdf_fontface.main=~/\S{3,}/ +        @md.make.texpdf_fontface.main +      else @env.font.texpdf.main +      end +      texpdf_fontface_sans=if defined? @md.make.texpdf_fontface.sans \ +      and not @md.make.texpdf_fontface.sans.nil? \ +      and @md.make.texpdf_fontface.sans=~/\S{3,}/                                  # not used +        @md.make.texpdf_fontface.sans +      else @env.font.texpdf.sans +      end +      texpdf_fontface_serif=if defined? @md.make.texpdf_fontface.serif \ +      and not @md.make.texpdf_fontface.serif.nil? \ +      and @md.make.texpdf_fontface.serif=~/\S{3,}/                                 # not used +        @md.make.texpdf_fontface.serif +      else @env.font.texpdf.serif +      end +      texpdf_fontface_mono=if defined? @md.make.texpdf_fontface.mono \ +      and not @md.make.texpdf_fontface.mono.nil? \ +      and @md.make.texpdf_fontface.mono=~/\S{3,}/ +        @md.make.texpdf_fontface.mono +      else @env.font.texpdf.mono +      end +      texpdf_fontface_cjk=if @md.opt.lng =~/zh/ \ +      and defined? @md.make.texpdf_fontface.cjk_zh \ +      and not @md.make.texpdf_fontface.cjk_zh.nil? \ +      and @md.make.texpdf_fontface.cjk_zh=~/\S{3,}/ +        @md.make.texpdf_fontface.cjk_zh +      elsif @md.opt.lng =~/ja/ \ +      and defined? @md.make.texpdf_fontface.cjk_ja \ +      and not @md.make.texpdf_fontface.cjk_ja.nil? \ +      and @md.make.texpdf_fontface.cjk_ja=~/\S{3,}/ +        @md.make.texpdf_fontface.cjk_ja +      elsif @md.opt.lng =~/ko/ \ +      and defined? @md.make.texpdf_fontface.cjk_ko \ +      and not @md.make.texpdf_fontface.cjk_ko.nil? \ +      and @md.make.texpdf_fontface.cjk_ko=~/\S{3,}/ +        @md.make.texpdf_fontface.cjk_ko +      elsif @md.opt.lng =~/(?:zh|ja|ko)/ \ +      and defined? @md.make.texpdf_fontface.cjk \ +      and not @md.make.texpdf_fontface.cjk.nil? \ +      and @md.make.texpdf_fontface.cjk=~/\S{3,}/ +        @md.make.texpdf_fontface.cjk +      else +        case @md.opt.lng +        when /zh/ then @env.font.texpdf.cjk_zh +        when /ja/ then @env.font.texpdf.cjk_ja +        when /ko/ then @env.font.texpdf.cjk_ko +        else @env.font.texpdf.cjk +        end +      end +      # you may wish to check selected font against available fonts: +      # fc-list :outline -f "%{family}\n" +      # fc-list :lang=ja +      case @tex2pdf +      when /xe/ +        if @md.opt.lng =~/(?:zh|ja|ko)/ +          <<-WOK +\\usepackage{ucs, fontspec, xltxtra, xunicode, xeCJK} +\\setmainCJKlanguage{#{tex_head_lang[:mainlang]}} +\\setCJKmainfont{#{texpdf_fontface_cjk}} +\\XeTeXlinebreaklocale "#{tex_head_lang[:mainlang]}" +\\XeTeXlinebreakskip = 0pt plus 1pt +\\setotherlanguage{#{tex_head_lang[:otherlang]}} +\\setmainfont{#{texpdf_fontface}} +\\setmonofont[Scale=0.85]{#{texpdf_fontface_mono}} +          WOK +        elsif (tex_head_lang[:mainlang] == "english" \ +        && (tex_head_lang[:otherlang] == "english" \ +          || tex_head_lang[:otherlang] == "" \ +          || tex_head_lang[:otherlang].length == 0)) +          <<-WOK +\\usepackage{polyglossia, ucs, fontspec, xltxtra, xunicode} +\\setmainlanguage{#{tex_head_lang[:mainlang]}} +\\setmainfont{#{texpdf_fontface}} +\\setmonofont[Scale=0.85]{#{texpdf_fontface_mono}} +% \\setsansfont{#{texpdf_fontface_sans}} +% \\setromanfont{#{texpdf_fontface_serif}} +          WOK +        else +          <<-WOK +\\usepackage{polyglossia, ucs, fontspec, xltxtra, xunicode} +\\setmainlanguage{#{tex_head_lang[:mainlang]}} +\\setotherlanguage{english} +\\setmainfont{#{texpdf_fontface}} +\\setmonofont[Scale=0.85]{#{texpdf_fontface_mono}} +% \\setsansfont{#{texpdf_fontface_sans}} +% \\setromanfont{#{texpdf_fontface_serif}} +          WOK +        end +      when /pdf/ +        if @md.file_encoding =~ /iso-?8859/i                                   #% iso8859 +          <<-WOK +% \\usepackage[latin1]{inputenc} +\\usepackage{fontspec} +          WOK +        else                                                                   #% utf-8 assumed +        <<-WOK +\\usepackage{babel} +\\usepackage{ucs} +\\usepackage[utf8x]{inputenc} +          WOK +        end +      end +    end +    def tex_head_info +      generator="Generated by: #{@md.project_details.project} #{@md.project_details.version} of #{@md.project_details.date_stamp} (#{@md.project_details.date})" if @md.project_details.version +      lastdone="Last Generated on: #{Time.now}" +      rubyv="Ruby version: #{@md.ruby_version}" +      <<-WOK +%% SiSU (Linux & Ruby - \"better ways\") LaTeX output +%% #{generator} +%% #{rubyv} +%% LaTeX output +%% #{lastdone} +%% SiSU http://www.jus.uio.no/sisu +      WOK +    end +    def tex_head_paper_portrait(d) +      multicol=(@md.book_idx ? '\usepackage{multicol}' : '') +      <<-WOK +#{tex_head_info} +\\usepackage{geometry} +\\documentclass[#{d[:fontsize]},#{d[:papertype]},titlepage]{scrartcl}        %with titlepage +\\setlength{\\textheight}{#{d[:textheight]}mm} \\setlength{\\textwidth}{#{d[:textwidth]}mm} +\\setlength{\\oddsidemargin}{#{d[:oddsidemargin]}} \\setlength{\\evensidemargin}{#{d[:evensidemargin]}} +\\setlength{\\topmargin}{#{d[:topmargin]}} \\setlength{\\headheight}{#{d[:headheight]}} +\\setlength{\\headsep}{#{d[:headsep]}} +\\setlength{\\marginparsep}{#{d[:marginparsep]}} +\\setlength{\\marginparwidth}{#{d[:marginparwidth]}} +#{multicol} +      WOK +    end +    def tex_head_paper_landscape(d) +      <<-WOK +#{tex_head_info} +\\usepackage{geometry} +\\documentclass[#{d[:fontsize]},#{d[:papertype]},landscape,titlepage,twocolumn]{scrartcl}        %with titlepage +\\setlength{\\textheight}{#{d[:textheight]}mm} \\setlength{\\textwidth}{#{d[:textwidth]}mm} +\\setlength{\\oddsidemargin}{#{d[:oddsidemargin]}} \\setlength{\\evensidemargin}{#{d[:evensidemargin]}} +\\setlength{\\topmargin}{#{d[:topmargin]}} \\setlength{\\headheight}{#{d[:headheight]}} +\\setlength{\\headsep}{#{d[:headsep]}} +\\setlength{\\columnsep}{#{d[:columnsep]}} +\\setlength{\\marginparsep}{#{d[:marginparsep]}} +\\setlength{\\marginparwidth}{#{d[:marginparwidth]}} +      WOK +    end +    def tex_head_paper_portrait_dvi(d) +      <<-WOK +#{tex_head_info} +\\documentclass[#{d[:fontsize]},#{d[:papertype]},titlepage]{scrartcl}      %with titlepage +\\setlength{\\textheight}{#{d[:textheight]}mm} \\setlength{\\textwidth}{#{d[:textwidth]}mm} +\\setlength{\\oddsidemargin}{#{d[:oddsidemargin]}} \\setlength{\\evensidemargin}{#{d[:evensidemargin]}} +\\setlength{\\topmargin}{#{d[:topmargin]}} \\setlength{\\headheight}{#{d[:headheight]}} +\\setlength{\\headsep}{#{d[:headsep]}} +\\setlength{\\marginparsep}{#{d[:marginparsep]}} +\\setlength{\\marginparwidth}{#{d[:marginparwidth]}} +      WOK +    end +    def tex_head_paper_dimensions +      d={} +      fontsize_set=if defined? @env.font.texpdf.size(@md.opt.act[:pdf_font_size]) \ +      and not @env.font.texpdf.size(@md.opt.act[:pdf_font_size]).nil? +        @env.font.texpdf.size(@md.opt.act[:pdf_font_size]) +      else :na +      end +      case @layout +      when :portrait +        fontsize=(fontsize_set==:na) ? '11pt' : (fontsize_set + 'pt') +        d[:papertype],d[:fontsize]='a4paper',fontsize +        d[:oddsidemargin],d[:evensidemargin],d[:topmargin]='0mm','0mm','-12pt' +        d[:headheight],d[:headsep],d[:columnsep]='12pt','35pt','' +        d[:marginparsep],d[:marginparwidth]='4mm','8mm' +        case @ps #@md.papersize +        when /a4/i           #European default, SiSU default +          fontsize=(fontsize_set==:na) ? '12pt' : (fontsize_set + 'pt') +          d[:papertype],d[:fontsize]='a4paper',fontsize +          d[:textheight],d[:textwidth]=@tx.a4.portrait.h,@tx.a4.portrait.w +        when /letter/i   #U.S. default +          fontsize=(fontsize_set==:na) ? '12pt' : (fontsize_set + 'pt') +          d[:papertype],d[:fontsize]='letterpaper',fontsize +          d[:textheight],d[:textwidth]=@tx.letter.portrait.h,@tx.letter.portrait.w +        when /legal/i     #U.S. alternative +          fontsize=(fontsize_set==:na) ? '12pt' : (fontsize_set + 'pt') +          d[:papertype],d[:fontsize]='legalpaper',fontsize +          d[:textheight],d[:textwidth]=@tx.legal.portrait.h,@tx.legal.portrait.w +        when /book|b5/i   #book default - larger +          fontsize=(fontsize_set==:na) ? '11pt' : (fontsize_set + 'pt') +          d[:papertype],d[:fontsize]='b5paper',fontsize +          d[:oddsidemargin],d[:evensidemargin],d[:topmargin]='-4mm','-4mm','-36pt' +          d[:headheight],d[:headsep],d[:columnsep]='12pt','20pt','' +          d[:textheight],d[:textwidth]=@tx.b5.portrait.h,@tx.b5.portrait.w +        when /a5/i +          fontsize=(fontsize_set==:na) ? '11pt' : (fontsize_set + 'pt') +          d[:papertype],d[:fontsize]='a5paper',fontsize +          d[:oddsidemargin],d[:evensidemargin],d[:topmargin]='-4mm','-4mm','-36pt' +          d[:headheight],d[:headsep],d[:columnsep]='11pt','12pt','' +          d[:marginparsep],d[:marginparwidth]='4mm','6mm' +          d[:textheight],d[:textwidth]=@tx.a5.portrait.h,@tx.a5.portrait.w +        else           #default currently A4 +          fontsize=(fontsize_set==:na) ? '12pt' : (fontsize_set + 'pt') +          d[:papertype],d[:fontsize]='a4paper',fontsize +          d[:textheight],d[:textwidth]=@tx.a4.portrait.h,@tx.a4.portrait.w +        end +      when :landscape +        fontsize=(fontsize_set==:na) ? '11pt' : (fontsize_set + 'pt') +        d[:papertype],d[:fontsize]='a4paper',fontsize +        d[:oddsidemargin],d[:evensidemargin],d[:topmargin]='6mm','6mm','-12mm' +        d[:headheight],d[:headsep],d[:columnsep]='12pt','20pt','40pt' +        d[:marginparsep],d[:marginparwidth]='4mm','8mm' +        case @ps #@md.papersize +        when /a4/i                            #European default, SiSU default +          fontsize=(fontsize_set==:na) ? '11pt' : (fontsize_set + 'pt') +          d[:papertype],d[:fontsize]='a4paper',fontsize +          d[:textheight],d[:textwidth]=@tx.a4.landscape.h,@tx.a4.landscape.w +        when /letter/i                    #U.S. default +          fontsize=(fontsize_set==:na) ? '11pt' : (fontsize_set + 'pt') +          d[:papertype],d[:fontsize]='letterpaper',fontsize +          d[:textheight],d[:textwidth]=@tx.letter.landscape.h,@tx.letter.landscape.w +        when /legal/i #U.S. alternative +          fontsize=(fontsize_set==:na) ? '11pt' : (fontsize_set + 'pt') +          d[:papertype],d[:fontsize],d[:columnsep]='legalpaper',fontsize,'48pt' +          d[:textheight],d[:textwidth]=@tx.legal.landscape.h,@tx.legal.landscape.w +        when /book|b5/i       #book default - larger +          fontsize=(fontsize_set==:na) ? '11pt' : (fontsize_set + 'pt') +          d[:papertype],d[:fontsize],d[:columnsep]='b5paper',fontsize,'35pt' +          d[:textheight],d[:textwidth]=@tx.b5.landscape.h,@tx.b5.landscape.w +        when /a5/i +          fontsize=(fontsize_set==:na) ? '10pt' : (fontsize_set + 'pt') +          d[:papertype],d[:fontsize],d[:columnsep]='a5paper',fontsize,'32pt' +          d[:textheight],d[:textwidth]=@tx.a5.landscape.h,@tx.a5.landscape.w +        else                            #default currently A4 +          fontsize=(fontsize_set==:na) ? '12pt' : (fontsize_set + 'pt') +          d[:papertype],d[:fontsize]='a4paper',fontsize +          d[:textheight],d[:textwidth]=@tx.a4.landscape.h,@tx.a4.landscape.w +        end +      end +      d +    end +    def tex_head_paper +      case @layout +      when :portrait +        tex_head_paper_portrait(tex_head_paper_dimensions) +      when :landscape +        tex_head_paper_landscape(tex_head_paper_dimensions) +      end +    end +    def hyperlinks_monochrome +      <<-WOK +  colorlinks=true, +  urlcolor=myblack, +  filecolor=myblack, +  linkcolor=myblack, +      WOK +    end +    def hyperlinks_colored +      <<-WOK +  colorlinks=true, +  urlcolor=myblue,    % \\href{...}{...}   external url +  filecolor=mygreen,  % \\href{...}        local file +  linkcolor=myred,    % \\href{...} and \\pageref{...} +      WOK +    end +    def hyperlinks_color? +      case @layout +      when :portrait  then hyperlinks_monochrome +        if @env.texpdf_hyperlinks(@md.opt.act[:pdf_hyperlink_colors]).portrait != :na +          case @env.texpdf_hyperlinks(@md.opt.act[:pdf_hyperlink_colors]).portrait +          when :color then hyperlinks_colored +          when :mono  then hyperlinks_monochrome +          else p __LINE__.to_s + ':error' +          end +        else               hyperlinks_monochrome +        end +      when :landscape +        if @env.texpdf_hyperlinks(@md.opt.act[:pdf_hyperlink_colors]).landscape != :na +          case @env.texpdf_hyperlinks(@md.opt.act[:pdf_hyperlink_colors]).landscape +          when :color then hyperlinks_colored +          when :mono  then hyperlinks_monochrome +          else p __LINE__.to_s + ':error' +          end +        else               hyperlinks_colored +        end +      end +    end +    def tex_head_pdftex +      author=if defined? @md.creator.author \ +      and @md.creator.author=~/\S+/ +        SiSU_TeX_Pdf::SpecialCharacters.new(@md,@md.creator.author).special_characters_safe_no_urls +      else '' +      end +      <<-WOK +\\usepackage{alltt} +\\usepackage{thumbpdf} +\\usepackage[#{@tex2pdf}, +  #{hyperlinks_color?.strip} +  pdftitle={#{@txt}}, +  pdfauthor={#{author}}, +  pdfsubject={#{@subject}}, +  pdfkeywords={#{@keywords}}, +  pageanchor=true, +  plainpages=true, +  pdfpagelabels=true, +  pagebackref, +  bookmarks=true, +  bookmarksopen=true, +  pdfmenubar=true, +  pdfpagemode=UseOutline, +  pdffitwindow=true, +  pdfwindowui=true, +  plainpages=false, +%  pdfusetitle=true, +%  pdfpagelayout=SinglePage, +%  pdfpagelayout=TwoColumnRight, +%  pdfpagelayout=TwoColumnLeft, +%  pdfstartpage=3, +  pdfstartview=FitH +] +{hyperref} +%% trace lost characters +% \\tracinglostchars = 1 +% \\tracingonline = 1 +\\usepackage[usenames]{color} +\\definecolor{myblack}{rgb}{0,0,0} +\\definecolor{myred}{rgb}{0.75,0,0} +\\definecolor{mygreen}{rgb}{0,0.5,0} +\\definecolor{myblue}{rgb}{0,0,0.5} +\\definecolor{mywhite}{rgb}{1,1,1} +\\usepackage{url} +\\urlstyle{sf} +%\\usepackage{breakurl} +        WOK +    end +    def tex_head_codeblock(codeblock_box_type) +      codeblock_box=if codeblock_box_type=='listings' +        <<-WOK +\\usepackage{listings} +\\usepackage{color} +\\usepackage{textcomp} +        WOK +      elsif codeblock_box_type=='boites' +        "\\usepackage{boites}" +      else +        "\\usepackage{boites}" +      end +      codeblock_box +    end +    def tex_head_misc +      <<-WOK +\\usepackage{textcomp} +\\usepackage[parfill]{parskip} +\\usepackage[normalem]{ulem} +\\usepackage{soul} +\\usepackage{longtable} +\\usepackage[tc]{titlepic} +\\usepackage{graphicx} +\\makeatletter +\\parindent0pt +%\\usepackage{mathptmx} +\\usepackage{amssymb} +% amssymb used for backslash +      WOK +    end +    def document_head_with_orientation(codeblock_box_type) +      endnotes=("\\usepackage{endnotes}" if @txt =~/endnotes?/) || '' #not implemented see also def endnotes +      @lang.list[@md.i18n[0]][:xlp] +      <<-WOK +#{tex_head_paper} +#{tex_head_encode} +#{tex_head_pdftex} +#{tex_head_misc} +#{tex_head_codeblock(codeblock_box_type)} +\\setcounter{secnumdepth}{2} +\\setcounter{tocdepth}{4} +\\makeatletter +#{endnotes} +\\usepackage[multiple,ragged]{footmisc} +\\setlength\\footnotemargin{12pt} +\\usepackage[para]{manyfoot} +\\DeclareNewFootnote{A} +%\\DeclareNewFootnote[para]{A} +\\newenvironment{ParagraphIndent}[1]% +{ +\\begin{list}{}{% +\\setlength\\topsep{0pt}% +\\addtolength{\\leftmargin}{#1} +\\setlength\\parsep{0pt plus 1pt}% +} +\\item[] +} +{\\end{list}} + +\\newenvironment{ParagraphHang}[2]% +{ +\\begin{list}{}{% +\\setlength\\topsep{0pt}% +\\addtolength{\\leftmargin}{#1} +\\itemindent=#2 +\\setlength\\parsep{0pt plus 1pt}% +} +\\item[] +} +{\\end{list}} + +\\newenvironment{Bullet}[1]% +{ +\\begin{list}{}{% +\\setlength\\topsep{0pt}% +\\addtolength{\\leftmargin}{#1} +\\itemindent=-1em +\\setlength\\parsep{0pt plus 1pt}% +} +\\item[] +} +{\\end{list}} +\\usepackage{fancyhdr} +\\lhead{} +\\renewcommand{\\part}{\\\@startsection +  {part}{1}{-2mm}% +  {-\\baselineskip}{0.5\\baselineskip}% +  {\\bfseries\\large\\upshape\\raggedright}} +\\renewcommand{\\section}{\\\@startsection +  {section}{2}{-2mm}% +  {-\\baselineskip}{0.5\\baselineskip}% +  {\\bfseries\\large\\upshape\\raggedright}} +\\renewcommand{\\subsection}{\\\@startsection +  {subsection}{3}{-2mm}% +  {-\\baselineskip}{0.5\\baselineskip}% +  {\\bfseries\\large\\upshape\\raggedright}} +\\renewcommand{\\subsubsection}{\\\@startsection +  {subsubsection}{4}{-2mm}% +  {-\\baselineskip}{0.5\\baselineskip}% +  {\\normalfont\\normalsize\\bfseries\\raggedright}} +\\renewcommand{\\paragraph}{\\\@startsection +  {paragraph}{5}{-2mm}% +  {-\\baselineskip}{0.5\\baselineskip}% +  {\\normalfont\\normalsize\\itshape\\raggedright}} +\\renewcommand{\\subparagraph}{\\\@startsection +  {subparagraph}%{6}%{-2mm}% +  {-\\baselineskip}{0.5\\baselineskip}% +  {\\normalfont\\normalsize\\itshape\\raggedright}} +% \\makeatother +\\selectlanguage{#{@lang.list[@md.i18n[0]][:xlp]}} +      WOK +    end +    def a4generic +    end +  end +  class SpecialCharacters +    include SiSU_Parts_TeXpdf +    def initialize(md,str,is=:default) +      @md,@txt,@is=md,str,is +      @tex2pdf=@@tex3pdf ||=SiSU_Env::SystemCall.new.tex2pdf_engine +    end +    def xetex_code_listings(str,is=:default)                                 # ~ ^ $ & % _ { }  #LaTeX special characters - KEEP list +      word=str.scan(/\S+|\n/) #unless line =~/^(?:@\S|%+\s)/ +      para_array=[] +      str=if word +        word.each do |w| # _ - / # | : ! ^ ~ +          w=w.gsub(/#{Mx[:gl_o]}#lt#{Mx[:gl_c]}/,'<').gsub(/#{Mx[:gl_o]}#gt#{Mx[:gl_c]}/,'>'). +            gsub(/[\\]?~/,'~'). +            gsub(/[#{Mx[:br_line]}#{Mx[:br_paragraph]}]/,"\n").              #watch +            gsub(/#{Mx[:gl_o]}#(?:126|152)#{Mx[:gl_c]}/,'~').                #126 usual +            gsub(/\\?\||#{Mx[:gl_o]}#124#{Mx[:gl_c]}/,'|')                   #unless is=='code' #unless w=~/<~\d+;(?:[ohmu]|[0-6]:)\d+;\w\d+>/ # | SiSU not really special sisu character but done, also LaTeX +          para_array << w +        end +        str=para_array.join(' ') +        str=str.strip unless is==:code +        str +      else '' +      end +      str=str.gsub(/\s*#{Mx[:mk_o]}:name#\S+?#{Mx[:mk_c]}\s*/,' '). +        gsub(/.+?<-#>/,''). +        gsub(/#{Mx[:br_eof]}/,''). +        gsub(/#{Mx[:br_endnotes]}/,''). +      #problem sequence -> +        gsub(/&(?:lt|#060);/,'<').                                           # < SiSU special character also LaTeX +        gsub(/#{Mx[:gl_o]}#(?:gt|062)#{Mx[:gl_c]}/,'>').                     # > SiSU special character also LaTeX +        gsub(/#{Mx[:gl_o]}#123#{Mx[:gl_c]}/,'{').                            # { SiSU special character also LaTeX +        gsub(/#{Mx[:gl_o]}#125#{Mx[:gl_c]}/,'}').                            # } SiSU special character also LaTeX +        gsub(/#{Mx[:gl_o]}#(?:126|152)#{Mx[:gl_c]}/,'~').                    # ~ SiSU special character also LaTeX +        gsub(/#{Mx[:gl_o]}#035#{Mx[:gl_c]}/,'#').                            # SiSU special character also LaTeX +        gsub(/#{Mx[:gl_o]}#033#{Mx[:gl_c]}/,'!').                            # ! SiSU not really special sisu character but done, also LaTeX +       #gsub(/(^|\s)\*\s/,'\1\asterisk ').                                   # * should you wish to escape astrisk e.g. describing \*{bold}* +        gsub(/#{Mx[:gl_o]}#042#{Mx[:gl_c]}/,'*').                            # * should you wish to escape astrisk e.g. describing \*{bold}* +        gsub(/#{Mx[:gl_o]}#045#{Mx[:gl_c]}/,'-').                            # - SiSU special character also LaTeX +        gsub(/#{Mx[:gl_o]}#043#{Mx[:gl_c]}/,'+').                            # + SiSU special character also LaTeX +        gsub(/#{Mx[:gl_o]}#044#{Mx[:gl_c]}/,',').                            # + SiSU special character also LaTeX +        gsub(/#{Mx[:gl_o]}#038#{Mx[:gl_c]}/,'&').                            #unless @txt=~/<:code>/  # / SiSU special character also LaTeX +        gsub(/#{Mx[:gl_o]}#047#{Mx[:gl_c]}/,'/').                            # / SiSU special character also LaTeX +        gsub(/#{Mx[:gl_o]}#092#{Mx[:gl_c]}/,'\\').                           # \ SiSU special character also LaTeX +        gsub(/#{Mx[:gl_o]}#095#{Mx[:gl_c]}/,'_').                            # _ SiSU special character also LaTeX +        gsub(/#{Mx[:gl_o]}#124#{Mx[:gl_c]}/,'|').                            # | SiSU not really special sisu character but done, also LaTeX +        gsub(/#{Mx[:gl_o]}#058#{Mx[:gl_c]}/,':').                            # : SiSU not really special sisu character but done, also LaTeX +        gsub(/#{Mx[:gl_o]}#094#{Mx[:gl_c]}|\^/,'^').                         # ^ SiSU not really special sisu character but done, also LaTeX +      ##watch placement, problem sequence ^ +        gsub(/<sup><font face=symbol>&atild;<\/font><\/sup>/,' '). +        gsub(/\\copy(right|mark)?/,'<=copymark>')                            # ok problem with superscript +    end +    def xetex_special_characters_1(str,is=:default)                          # ~ ^ $ & % _ { }  #LaTeX special characters - KEEP list +      word=str.scan(/\S+|\n/) #unless line =~/^(?:@\S|%+\s)/ +      para_array=[] +      str=if word +        word.each do |w| # _ - / # | : ! ^ ~ +          if w !~/https?:/ \ +          and w=~/\/\S+?\// \ +          and w.length > 6 +            w=w.gsub(/([_.\/])/,'\1\-') +          end +          w=w.gsub(/#{Mx[:gl_o]}#lt#{Mx[:gl_c]}/,'<').gsub(/#{Mx[:gl_o]}#gt#{Mx[:gl_c]}/,'>'). +            gsub(/[\\]?~/,'<=tilde>'). +            gsub(/[#{Mx[:br_line]}#{Mx[:br_paragraph]}]/,' \newline ').      #watch +            gsub(/#{Mx[:gl_o]}#(?:126|152)#{Mx[:gl_c]}/,'<=tilde>').         #126 usual +            gsub(/\\?\||#{Mx[:gl_o]}#124#{Mx[:gl_c]}/,'\pipe')               #unless is=='code' #unless w=~/<~\d+;(?:[ohmu]|[0-6]:)\d+;\w\d+>/ # | SiSU not really special sisu character but done, also LaTeX +          if w !~/#{Mx[:rel_o]}/ \ +          and w !~/#{Mx[:gl_o]}#/ +            w=w.gsub(/\#/,'<=hash>') +          end +          para_array << w +        end +        str=para_array.join(' ') +        str=str.strip unless is==:code +        str +      else '' +      end +      str=str.gsub(/\s*#{Mx[:mk_o]}:name#\S+?#{Mx[:mk_c]}\s*/,' '). +        gsub(/.+?<-#>/,''). +        gsub(/#{Mx[:br_eof]}/,''). +        gsub(/#{Mx[:br_endnotes]}/,'') +      #problem sequence -> +      str=str.gsub(/&(?:nbsp);|#{Mx[:nbsp]}/,'\hardspace') unless is==:code  # < SiSU special character also LaTeX +      str=str.gsub(/&(?:lt|#060);/,'\lt').                                   # < SiSU special character also LaTeX +        gsub(/#{Mx[:gl_o]}#(?:gt|062)#{Mx[:gl_c]}/,'\gt').                   # > SiSU special character also LaTeX +        gsub(/#{Mx[:gl_o]}#123#{Mx[:gl_c]}/,'\curlyopen').                   # { SiSU special character also LaTeX +        gsub(/#{Mx[:gl_o]}#125#{Mx[:gl_c]}/,'\curlyclose').                  # } SiSU special character also LaTeX +        gsub(/#{Mx[:gl_o]}#(?:126|152)#{Mx[:gl_c]}/,'<=tilde>').             # ~ SiSU special character also LaTeX +        gsub(/#{Mx[:gl_o]}#035#{Mx[:gl_c]}/,'\#').                           # # SiSU special character also LaTeX +        gsub(/#{Mx[:gl_o]}#033#{Mx[:gl_c]}/,'!').                            # ! SiSU not really special sisu character but done, also LaTeX +        gsub(/(^|\s)\*\s/,'\1\asterisk ').                                   # * should you wish to escape astrisk e.g. describing \*{bold}* +        gsub(/#{Mx[:gl_o]}#042#{Mx[:gl_c]}/,'\*').                           # * should you wish to escape astrisk e.g. describing \*{bold}* +        gsub(/#{Mx[:gl_o]}#045#{Mx[:gl_c]}/,'-').                            # - SiSU special character also LaTeX +        gsub(/#{Mx[:gl_o]}#043#{Mx[:gl_c]}/,'+').                            # + SiSU special character also LaTeX +        gsub(/#{Mx[:gl_o]}#044#{Mx[:gl_c]}/,',').                            # + SiSU special character also LaTeX +        gsub(/#{Mx[:gl_o]}#038#{Mx[:gl_c]}/,'<=amp>'). #unless @txt=~/<:code>/  # / SiSU special character also LaTeX +        gsub(/#{Mx[:gl_o]}#047#{Mx[:gl_c]}/,'\slash').                       # / SiSU special character also LaTeX +        gsub(/#{Mx[:gl_o]}#092#{Mx[:gl_c]}/,'\textbackslash').               # \ SiSU special character also LaTeX +        gsub(/#{Mx[:gl_o]}#095#{Mx[:gl_c]}/,'<=underscore>').                # _ SiSU special character also LaTeX +        gsub(/#{Mx[:gl_o]}#124#{Mx[:gl_c]}/,'|').                            # | SiSU not really special sisu character but done, also LaTeX +        gsub(/#{Mx[:gl_o]}#058#{Mx[:gl_c]}/,':').                            # : SiSU not really special sisu character but done, also LaTeX +        gsub(/#{Mx[:gl_o]}#094#{Mx[:gl_c]}|\^/,'\caret').                    # ^ SiSU not really special sisu character but done, also LaTeX +      ##watch placement, problem sequence ^ +        gsub(/<sup><font face=symbol>&atild;<\/font><\/sup>/,' '). +        gsub(/\\copy(right|mark)?/,'<=copymark>') # ok problem with superscript +    end +    def xetex_special_characters_2(str,is=:default) +      str=str.gsub(/#{Mx[:gl_o]}#156#{Mx[:gl_c]}/,'\oe '). +        gsub(/\$/,'\$'). +        gsub(/\#/,'\#'). +        gsub(/\%/,'\%'). +        gsub(/\~/,'\~') #revist, should not be necessary to mark remaining tildes +      if str !~/^\s*#{Mx[:lnk_o]}.+?#{Mx[:lnk_c]}image\s/ +        str=str.gsub(/_/,'\_') +      end +      str=str.gsub(/\{/,'\{'). +        gsub(/\}/,'\}') +      str=if is==:code +        str.gsub(/&/,'{\\\&}'). +          gsub(/\\~(\\\{)/,'{$\tilde$}\1'). +          gsub(/(\\\})\\~/,'\1{$\tilde$}'). +          gsub(/\\~(\[)/,'{$\tilde$}\1'). +          gsub(/(\])\\~/,'\1{$\tilde$}'). +          gsub(/<=tilde>/,'{$\tilde$}'). +          gsub(/<=hash>/,'{\#}') +      else +        str.gsub(/ |#{Mx[:nbsp]}/,'~'). # ~ character for hardspace +          gsub(/&/,'<=amp>') +      end +      str=str.gsub(/&\S+?;/,' '). +        gsub(/§/u,'\S'). #latex: space between next character not preserved? #str.gsub(/§ /,'\S ') +        gsub(/£/u,'\pounds'). +        gsub(/<a href=".+?">/,' '). +        gsub(/<\/a>/,' ') +      unless is==:no_urls +        str=str.gsub(/((?:^|\s)#{Mx[:lnk_c]})#{Mx[:url_o]}(\S+?)#{Mx[:url_c]}/, +            '\1\begin{scriptsize}\url{\2}\end{scriptsize}\3'). #special case \{ e.g. \}http://url +          gsub(/#{Mx[:url_o]}\\_(\S+?)#{Mx[:url_c]}/, +            '\begin{scriptsize}\url{\1}\end{scriptsize}'). #special case \{ e.g. \}http://url +          gsub(/#{Mx[:url_o]}_(\S+?)#{Mx[:url_c]}/, +            '\begin{scriptsize}\\url{\1}\end{scriptsize}') #specially escaped url no decoration +      end +      if is !=:code \ +      and is !=:no_urls +        str=str.gsub(/(^|#{Mx[:gl_c]}|\s)((?:https?|file|ftp):\/\/\S+?\.[^'"\s]+?)([;.,]?(?=\s|$))/, +          "\\1#{url_decoration.tex_open}\\begin{scriptsize}\\url{\\2}\\end{scriptsize}#{url_decoration.tex_close}\\3") #url matching with decoration <url> positive lookahead, sequence issue with { linked }http://url cannot use \b at start +      end +      str=str.gsub(/<:ee>/,''). +        gsub(/<!>/,' ').  #proposed change, insert, but may be redundant +        gsub(/<(br|p)>|<\/\s*(br|p)>|<(br|p)\s*\/>/," #{Tex[:backslash]*2} "). # Work Area +        gsub(/#{Mx[:fa_bold_o]}(.+?)#{Mx[:fa_bold_c]}/,'\begin{bfseries}\1 \end{bfseries}'). +        gsub(/<h\d+>(.+?)<\/h\d+>/,'\begin{bfseries}\1 \end{bfseries}'). +        gsub(/#{Mx[:fa_italics_o]}(.+?)#{Mx[:fa_italics_c]}/,'\emph{\1}'). +        gsub(/#{Mx[:fa_underscore_o]}(.+?)#{Mx[:fa_underscore_c]}/,'\uline{\1}'). # ulem +        gsub(/#{Mx[:fa_cite_o]}(.+?)#{Mx[:fa_cite_c]}/,"``\\1''"). # quote #CHECK +        gsub(/#{Mx[:fa_insert_o]}(.+?)#{Mx[:fa_insert_c]}/,'\uline{\1}'). # ulem +        gsub(/#{Mx[:fa_strike_o]}(.+?)#{Mx[:fa_strike_c]}/,'\sout{\1}'). # ulem +        gsub(/#{Mx[:fa_superscript_o]}(.+?)#{Mx[:fa_superscript_c]}/,"\$^{\\textrm{\\1}}\$"). +        gsub(/#{Mx[:fa_subscript_o]}(.+?)#{Mx[:fa_subscript_c]}/,"\$_{\\textrm{\\1}}\$"). +        gsub(/#{Mx[:fa_monospace_o]}(.+?)#{Mx[:fa_monospace_c]}/,'\begin{monosp}\1\end{monosp}') +      unless is==:code +        str=str.gsub(/"(.+?)"/,'“\1”').  # quote marks / quotations open & close " need condition exclude for code +          gsub(/\s+"/,' “').                                # open " +          gsub(/^(#{Mx[:lv_o]}[1-6-]:\S*?#{Mx[:lv_c]}|<.+?>)?\s*"/,'\1“'). #fix Mx[:lv_o] # open " +          gsub(/"(\s|\.|,|:|;)/,'”\1').                     # close " +          gsub(/"(#{Mx[:lv_o]}[1-6-]:\S*?#{Mx[:lv_c]}|<.+?>)?\s*$/,'”\1'). #fix Mx[:lv_o] # close " +          gsub(/"(\.|,)/,'”').                              # close " +          gsub(/\s+'/,' `').                                # open ' +          gsub(/^(#{Mx[:lv_o]}[1-6-]:\S*?#{Mx[:lv_c]}|<.+?>)?\s*'/,'\1`') #fix Mx[:lv_o] # open ' +      end +      str=str.gsub(/(<font.*?>|<\/font>)/,''). +        gsub(/\s*#{Mx[:fa_superscript_o]}(\S+?)#{Mx[:fa_superscript_c]}/,'^\1') +      str +    end +    def xetex_special_characters_3(str) +      str=str.gsub(/<br(\s*[^\/][^>])/,'\1'). # clean up, incredibly messy :-( footnote indents, problems if match exists in ordinary paragraphs? check! Work Area 200501 a bit tricky as must be able to match multiple times, and to clean remainder +        gsub(/([^<][^b][^r]\s+)\/>/,'\1') # clean up, incredibly messy :-( footnote indents, problems if match exists in ordinary paragraphs? check! Work Area 200501 a bit tricky as must be able to match multiple times, and to clean remainder +      while str =~/(https?:\/\/\S+?)(?:<=tilde>\S+)+/ #tilde in urls \href treated differently from text #FIX +        str=str.gsub(/(https?:\/\/\S+?)(?:<=tilde>(\S+))+/,'\1~\2') +      end +      str=str.gsub(/<=tilde>/,'{$\tilde$}'). +        gsub(/(https?:\/\/\S+?)(?:(?:<=hash>)(\S+))+/,'\1#\2'). #hash in urls \href treated differently from text #FIX +        gsub(/<=hash>/,'{\#}') +      while str =~/(https?:\/\/\S+?)(?:<=amp>\S+)+/ #amp in urls \href treated differently from text #FIX +        str=str.gsub(/(https?:\/\/\S+?)(?:<=amp>(\S+))+/,'\1&\2') +      end +      str=str.gsub(/<=amp>/,'{\\\&}'). #changed ... 2005 +        gsub(/<=copymark>\s*(.+)/, +          '^\copyright \textnormal{\1} \2') # watch likely to be problematic +      str +    end +    def special_characters_safe_close(str) +      str=str.gsub(/<=tilde>/,'{$\tilde$}'). +        gsub(/<=hash>/,'{\#}'). +        gsub(/<=amp>/,'{\\\&}'). #changed ... 2005 +        gsub(/<=copymark>\s*(.+)/, +          '^\copyright \textnormal{\1} \2') # watch likely to be problematic +    end +    def special_characters_code_fix(str) +      str=str.gsub(/<=tilde>/,'{$\tilde$}') +      str +    end +    def special_characters_unsafe_1(str) #depreciated, make obsolete +      # some substitutions are sequence sensitive, rearrange with care. +      str=str.gsub(/\\textbackslash (copyright|clearpage|newpage)/,"\\\\\\1")  #kludge bad solution, find out where tail is sent through specChar ! +      str +    end +    def special_characters                                                   # special characters - some substitutions are sequence sensitive, rearrange with care +      str,is=@txt,@is +      str=xetex_special_characters_1(str,is) unless str.nil? +      str=special_characters_unsafe_1(str) unless str.nil? #xetex_special_characters_unsafe_1(@txt) +      str=xetex_special_characters_2(str,is) unless str.nil? #issues with xetex +      str=xetex_special_characters_3(str) unless str.nil? +      @txt=str +    end +    def special_word_break_points +      str=@txt +      str=str.gsub(/([_,.;:\/|=])/,'\1\-'). +        gsub(/(--)(\S{4,})/,'\1\-\2') +      @txt=str +    end +    def special_number_break_points +      str=@txt +      str=str.gsub(/([0-9a-f]{8})/i,'\1\-') +      @txt=str +    end +    def special_characters_safe                                              # special characters - some substitutions are sequence sensitive, rearrange with care +      str,is=@txt,@is +      str=xetex_special_characters_1(str,is) unless str.nil? +      str=xetex_special_characters_2(str,is) unless str.nil?                 # remove this to start with, causes issues +      str=special_characters_safe_close(str) unless str.nil? +      @txt=str +    end +    def special_characters_safe_no_urls +      str,is=@txt,:no_urls +      str=xetex_special_characters_1(str,is) unless str.nil? +      str=xetex_special_characters_2(str,is) unless str.nil? # remove this to start with, causes issues +      str=special_characters_safe_close(str) unless str.nil? +      @txt=str +    end +    def characters_code_listings                                             # special characters - some substitutions are sequence sensitive, rearrange with care +      str,is=@txt,@is +      str=xetex_code_listings(str,is) unless str.nil? +      @txt=str +    end +    def special_characters_code +      str=@txt +      str=str.gsub(/ \\\\([ #{Mx[:br_nl]}]+|$)/,' \textbackslash\textbackslash\hardspace\1') +      str +    end +  end +  class UseTeX +    include SiSU_Parts_TeXpdf +    attr_accessor :url,:txt,:date +    def initialize(md) +      @md=md +      @date=SiSU_Env::InfoDate.new # #{@date.year} +      @copymark='{\\begin{footnotesize}\\raisebox{1ex}{\\copyright}\\end{footnotesize}}' +    end +    def skip +      "\n\\vspace*{\\smallskipamount} \n" +    end +    def paraskip_normal +      '\setlength{\parskip}{1ex plus0.5ex minus0.2ex}' +    end +    def paraskip_small +      '\setlength{\parskip}{0.5ex plus0.2ex minus0.1ex}' +    end +    def paraskip_tiny +      '\setlength{\parskip}{0.1ex plus0.1ex minus0.1ex}' +    end +    def skip_small +      "\\smallskip{}" +    end +    def skip_small_vspace +      "\n\\vspace*{\\smallskipamount} \n" +    end +    def skip_small_footnote +    end +    def skip_medium +      "\n\\medskip{}\n\n" +    end +    def skip_dummy +      "\n" +    end +    def header +      "\\lhead[ ]{ }\n" + +      "\\chead[ \\fancyplain{} \\bfseries \\footnotesize \\leftmark ]{ \\fancyplain{} \\bfseries \\footnotesize \\rightmark }\n" + +      "\\rhead[ ]{ }\n" +    end +    def footer +      "\\lfoot[\\textrm{\\thepage}]{\\tiny \\href{#{@md.footer_links[:left][:url]}}{#{@md.footer_links[:left][:say]}}}\n" + +      "\\cfoot{\\href{#{@md.footer_links[:center][:url]}}{#{@md.footer_links[:center][:say]}}}\n" + +      "\\rfoot[\\tiny \\href{}{}]{\\textrm{\\thepage}}\n" +    end +    def site +      if not the_url.home.empty? \ +      and not the_url.home_txt.empty? +        "\n\\date{\\begin{tiny} \\end{tiny}}" +      else '' +      end +    end +    def owner_chapter +      "Contact Details for Original Promulgating Authority" +    end +    #BOOK standard dimensions - 229x156 +    def newpage(orientation) +      case orientation +      when :landscape # using longtable latex package +        <<-WOK +\\clearpage +        WOK +      when :portrait +        <<-WOK +\\newpage +        WOK +      end +    end +    def sisu_rights +      v=SiSU_Env::InfoVersion.instance.get_version +      base_prog_txt=if @md.base_program +        case @md.base_program +        when /kdissert/i then "\n\\\\ This document prepared using \\href{http://freehackers.org/~tnagy/kdissert/}{Kdissert \\ http://freehackers.org/~tnagy/kdissert/ } \\\\ Kdissert is Document Mapping software by Thomas Nagy" +        else '' +        end +      else '' +      end +      <<-WOK +\\\\ ~ +{\\begin{footnotesize}#{base_prog_txt} +\\\\ Generated by \\href{http://www.jus.uio.no/sisu}{SiSU} \\begin{tiny}[ #{v.project} #{v.version} of #{v.date_stamp} ]\\end{tiny} \\href{http://www.jus.uio.no/sisu}{www.jus.uio.no/sisu} +\\\\ Copyright #{@copymark} 1997, current #{@date.year_static} Ralph Amissah, All Rights Reserved. +\\\\ SiSU is software for document structuring, publishing and search (with object citation numbering), \\href{http://www.sisudoc.org}{www.sisudoc.org} +\\\\ SiSU is released under \\href{http://www.fsf.org/licenses/gpl.html}{GPL 3 } or later, #{url_brace.tex_open}\\href{http://www.fsf.org/licenses/gpl.html}{http://www.fsf.org/licenses/gpl.html}#{url_brace.tex_close}. +{\\end{footnotesize} +\\\\ +      WOK +    end +    def doc_sc_info_footnote_full +      <<-WOK +\\footnote{%\nGenerated by \\href{http://www.jus.uio.no/sisu}{SiSU \\ www.jus.uio.no/sisu }\\ \\newline \\scriptsize{Document version information: \\emph{sourcefile} \\uline{#{@md.fnstex}}; \\emph{version} \\uline{#{@md.sc_number}}; \\emph{date} \\uline{#{@md.sc_date}}; \\emph{time} \\uline{#{@md.sc_time}}}} +      WOK +    end +    def doc_sc_info_footnote_brief +      " \\footnote{%\nGenerated by \\href{http://www.jus.uio.no/sisu}{SiSU} \\ \\href{http://www.jus.uio.no/sisu}{www.jus.uio.no/sisu} \\newline \\href{http://www.sisudoc.org}{www.sisudoc.org} \\\n}" +    end +    def doc_sc_info +      v=SiSU_Env::InfoVersion.instance.get_version +      <<-WOK +\\\\ +{\\begin{footnotesize} +Document version information: \\\\ +\\emph{sourcefile} \\uline{#{@md.fnstex}}; \\emph{version} \\uline{#{@md.sc_number}}; \\emph{date} \\uline{#{@md.sc_date}}; \\emph{time} \\uline{#{@md.sc_time}} \\\\ +Generated by \\href{http://www.jus.uio.no/sisu}{SiSU www.jus.uio.no/sisu }\\- version information: \\\\ +\\uline{ #{v.project} #{v.version} of #{v.date_stamp}} +\\end{footnotesize}}& +      WOK +    end +    def doc_no_sc_info +      v=SiSU_Env::InfoVersion.instance.get_version +      <<-WOK +\\\\ +{\\begin{small} +Document information: \\\\ +\\emph{sourcefile} \\uline{#{@md.fnstex}} \\\\ +Generated by \\href{http://www.jus.uio.no/sisu}{SiSU www.jus.uio.no/sisu } \\\\ version information: \\ +\\uline{ #{v.project} #{v.version} of #{v.date_stamp}} + +\\end{small}}& +      WOK +    end +    def endnotes #not used should be inserted before MetaData section which preceeds doc_tail, but is "part of document" +      <<-WOK +\\subsection*{Endnotes} +\\addcontentsline{toc}{section}{Endnotes} +\\ +\\listofendnotes +      WOK +    end +  end +end +__END__ +ag usepackage texpdf* +ag usepackage texpdf* | ag '\{.+?\}' +# texpdf_format.rb +ag usepackage texpdf* | ag --only-matching '\{.+?\}' + +,* sort & make unique +@tex2pdf +alltt.sty +amssymb.sty +babel.sty +boites.sty +breakurl.sty +color.sty +endnotes.sty +fancyhdr.sty +fontspec.sty +footmisc.sty +graphicx.sty +inputenc.sty +listings.sty +longtable.sty +manyfoot.sty +mathptmx.sty +multicol.sty +parskip.sty +polyglossia.sty +soul.sty +textcomp.sty +thumbpdf.sty +titlepic.sty +ucs.sty +ulem.sty +url.sty +xeCJK.sty +xltxtra.sty +xunicode.sty + +,* debian related +,** found in + +alltt.sty +  texlive-latex-base: /usr/share/texlive/texmf-dist/tex/latex/base/alltt.sty +amssymb.sty +  texlive-base: /usr/share/texlive/texmf-dist/tex/latex/amsfonts/amssymb.sty +babel.sty +  texlive-latex-base: /usr/share/texlive/texmf-dist/tex/generic/babel/babel.sty +boites.sty +  texlive-latex-extra: /usr/share/texlive/texmf-dist/tex/latex/boites/boites.sty +breakurl.sty +  texlive-latex-extra: /usr/share/texlive/texmf-dist/tex/latex/breakurl/breakurl.sty +color.sty +  texlive-latex-base: /usr/share/texlive/texmf-dist/tex/latex/graphics/color.sty +endnotes.sty +  texlive-latex-extra: /usr/share/texlive/texmf-dist/tex/latex/endnotes/endnotes.sty +fancyhdr.sty +  texlive-latex-base: /usr/share/texlive/texmf-dist/tex/latex/fancyhdr/fancyhdr.sty +fontspec.sty +  texlive-latex-recommended: /usr/share/texlive/texmf-dist/tex/latex/fontspec/fontspec.sty +footmisc.sty +  texlive-latex-extra: /usr/share/texlive/texmf-dist/tex/latex/footmisc/footmisc.sty +graphicx.sty +  texlive-latex-base: /usr/share/texlive/texmf-dist/tex/latex/graphics/graphicx.sty +inputenc.sty +  texlive-latex-base: /usr/share/texlive/texmf-dist/tex/latex/base/inputenc.sty +listings.sty +  texlive-latex-recommended: /usr/share/texlive/texmf-dist/tex/latex/listings/listings.sty +longtable.sty +  texlive-latex-base: /usr/share/texlive/texmf-dist/tex/latex/tools/longtable.sty +manyfoot.sty +  texlive-latex-extra: /usr/share/texlive/texmf-dist/tex/latex/ncctools/manyfoot.sty +mathptmx.sty +  texlive-font-utils: /usr/share/doc/texlive-doc/fonts/fontinst/examples/mathptmx/mathptmx.sty +  texlive-latex-base: /usr/share/texlive/texmf-dist/tex/latex/psnfss/mathptmx.sty +multicol.sty +  ptex-jtex: /usr/share/texmf/ajtex/multicol.sty +  texlive-latex-base: /usr/share/texlive/texmf-dist/tex/latex/tools/multicol.sty +parskip.sty +  texlive-latex-recommended: /usr/share/texlive/texmf-dist/tex/latex/parskip/parskip.sty +polyglossia.sty +  texlive-latex-recommended: /usr/share/texlive/texmf-dist/tex/latex/polyglossia/polyglossia.sty +soul.sty +  texlive-latex-extra: /usr/share/texlive/texmf-dist/tex/latex/soul/soul.sty +textcomp.sty +  texlive-latex-base: /usr/share/texlive/texmf-dist/tex/latex/base/textcomp.sty +thumbpdf.sty +  texlive-latex-recommended: /usr/share/texlive/texmf-dist/tex/generic/thumbpdf/thumbpdf.sty +titlepic.sty +  texlive-latex-extra: /usr/share/texlive/texmf-dist/tex/latex/titlepic/titlepic.sty +ucs.sty +  texlive-latex-extra: /usr/share/texlive/texmf-dist/tex/latex/ucs/ucs.sty +ulem.sty +  texlive-plain-generic: /usr/share/texlive/texmf-dist/tex/generic/ulem/ulem.sty +url.sty +  texlive-latex-base: /usr/share/texlive/texmf-dist/tex/latex/url/url.sty +xeCJK.sty +  texlive-xetex: /usr/share/texlive/texmf-dist/tex/xelatex/xecjk/xeCJK.sty +xltxtra.sty +  texlive-latex-recommended: /usr/share/texlive/texmf-dist/tex/latex/xltxtra/xltxtra.sty +xunicode.sty +  texlive-latex-recommended: /usr/share/texlive/texmf-dist/tex/xelatex/xunicode/xunicode.sty + +,** belongs to + +texlive-base: +  amssymb.sty +texlive-latex-base: +  alltt.sty +  babel.sty +  color.sty +  fancyhdr.sty +  graphicx.sty +  inputenc.sty +  longtable.sty +  mathptmx.sty +  multicol.sty +  textcomp.sty +  url.sty +texlive-latex-extra: +  boites.sty +  breakurl.sty +  endnotes.sty +  footmisc.sty +  manyfoot.sty +  soul.sty +  titlepic.sty +  ucs.sty +texlive-latex-recommended: +  fontspec.sty +  listings.sty +  parskip.sty +  polyglossia.sty +  thumbpdf.sty +  xltxtra.sty +  xunicode.sty +texlive-plain-generic: +  ulem.sty +texlive-xetex: +  xeCJK.sty + +,** all texlive packages used + +texlive-base +texlive-latex-base +texlive-latex-extra +texlive-latex-recommended +texlive-plain-generic +texlive-xetex + +#+END_SRC + +* document header + +#+NAME: sisu_document_header +#+BEGIN_SRC text +encoding: utf-8 +- Name: SiSU + +  - Description: documents, structuring, processing, publishing, search +    texpdf + +  - 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 diff --git a/org/txt.org b/org/txt.org new file mode 100644 index 00000000..e7fb6a7c --- /dev/null +++ b/org/txt.org @@ -0,0 +1,3205 @@ +-*- mode: org -*- +#+TITLE:       sisu txt +#+DESCRIPTION: documents - structuring, various output representations & search +#+FILETAGS:    :sisu:txt: +#+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 + +* types +** asciidoc +*** txt_asciidoc.rb + +#+BEGIN_SRC ruby  :tangle "../lib/sisu/txt_asciidoc.rb" +# <<sisu_document_header>> +module SiSU_Txt_AsciiDoc +  require_relative 'ao'                                 # ao.rb +  require_relative 'se'                                 # se.rb +    include SiSU_Env +  require_relative 'shared_metadata'                    # shared_metadata.rb +  require_relative 'generic_parts'                      # generic_parts.rb +  require_relative 'txt_read'                           # txt_read.rb +  require_relative 'txt_shared'                         # txt_shared.rb +  require_relative 'txt_asciidoc_decorate'              # txt_decorate.rb +  require_relative 'txt_output'                         # txt_output.rb +  include SiSU_Param +  @@alt_id_count,@@alt_id_count=0,0 +  @@tablefoot='' +  class Source +    include SiSU_Txt_Read +    def initialize(opt) +      @opt=opt +      unless @opt.fns =~/(.+?)\.(?:-|ssm\.)?sst$/ +        puts "#{sf} not a processed file type" +      end +    end +    def read +      begin +        md=SiSU_Param::Parameters.new(@opt).get +        specific={ +          description:     'AsciiDoc (plaintext utf-8)', +          output_path:     md.file.output_path.asciidoc.dir, +          output_file:     md.file.base_filename.asciidoc, +        } +        read_generic(@opt,specific) +        SiSU_Txt_AsciiDoc::Source::Scroll.new(md,@ao_array,@wrap_width).songsheet +      rescue +        SiSU_Errors::Rescued.new($!,$@,@opt.selections.str,@opt.fns).location do +          __LINE__.to_s + ':' + __FILE__ +        end +      ensure +      end +    end +    private +    class Scroll <Source +      include SiSU_Parts_Generic +      include SiSU_TextUtils +      include SiSU_Decorate_Txt_AsciiDoc +      @@endnotes={ para: [], end: [] } +      def initialize(md,data,wrap_width) +        @md,@data,@wrap_width=md,data,wrap_width +        @env=SiSU_Env::InfoEnv.new(@md.fns) +        @tab="\t" +        @@endnotes_=case md.opt.selections.str +        when /--footnote/ then false +        when /--endnote/  then true +        else                   true +        end +        @plaintext={ body: [], open: [], close: [], head: [], metadata: [], tail: [] } +      end +      def songsheet +        plaintext=markup(@data) +        publish(plaintext) +      end +      def break_line +        "\n" +      end +      # Used for extraction of endnotes from paragraphs +      def plaintext_metadata +        array=SiSU_Metadata::Summary.new(@md).plaintext.metadata +        array.each do |meta| +          tag,inf=meta.scan(/^.+?:\s|.+/) +          if tag and inf +            util=SiSU_TextUtils::Wrap.new(inf,@wrap_width,15,1) +            txt=util.line_wrap +            @plaintext[:metadata] <<<<WOK + +#{@tab}#{tag}#{txt} +WOK +          end +        end +      end +      def plaintext_tail +#       env=SiSU_Env::InfoEnv.new(@md.fns) +        generator="Generated by: #{@md.project_details.project} #{@md.project_details.version} of #{@md.project_details.date_stamp} (#{@md.project_details.date})"  if @md.project_details.version +        lastdone="Last Generated on: #{Time.now}" +        rubyv="Ruby version: #{@md.ruby_version}" +        sc=if @md.sc_info +          "Source file:    #{@md.sc_filename}#{break_line}Version number: #{@md.sc_number}#{break_line}Version date:   #{@md.sc_date}#{break_line}" +        else '' +        end +        @plaintext[:tail] <<<<WOK +#{break_line} +plaintext (plain text): +   #{@md.file.output_path.asciidoc.url}/#{@md.file.base_filename.asciidoc}#{break_line} +Other versions of this document: #{break_line} +manifest: +   #{@md.file.output_path.manifest.url}/#{@md.file.base_filename.manifest}#{break_line} +at: +   #{@md.file.output_path.base.url}#{break_line} + +#{sc} +,* #{generator} +,* #{rubyv} +,* #{lastdone} +,* SiSU #{the_url.sisu_txt} +WOK +      end +      def heading_decorated_inline(dob) +        if dob.is==:heading +          heading_inline = case dob.lc +          when 0 then decorate.heading.inline.l0 +          when 1 then decorate.heading.inline.l1 +          when 2 then decorate.heading.inline.l2 +          when 3 then decorate.heading.inline.l3 +          when 4 then decorate.heading.inline.l4 +          when 5 then decorate.heading.inline.l5 +          when 6 then decorate.heading.inline.l6 +          end +          heading_inline + ' ' +  dob.obj + ' ' + heading_inline +        end +      end +      def heading_decorated_underscore(dob,times,p_num) +        if dob.is==:heading +          #times=@wrap_width if times > @wrap_width +          case dob.lc +          when 0 then decorate.heading.underscore.l0*times + p_num << break_line*2 +          when 1 then decorate.heading.underscore.l1*times + p_num << break_line*2 +          when 2 then decorate.heading.underscore.l2*times + p_num << break_line*2 +          when 3 then decorate.heading.underscore.l3*times + p_num << break_line*2 +          when 4 then decorate.heading.underscore.l4*times + p_num << break_line*2 +          when 5 then decorate.heading.underscore.l5*times + p_num << break_line*2 +          when 6 then decorate.heading.underscore.l6*times + p_num << break_line*2 +          end +        end +      end +      def plaintext_structure(dob='',p_num='') #% Used to extract the structure of a document +        heading_decoration=:inline #(:inline|:underscore) #switch heading decoration between inline & underscore options +        util=nil +        wrapped=if dob.is==:para \ +        || dob.is==:heading +          if dob.is==:heading +            util=(heading_decoration== :inline) \ +            ? (SiSU_TextUtils::Wrap.new(heading_decorated_inline(dob),@wrap_width,0)) +            : (SiSU_TextUtils::Wrap.new(dob.obj,@wrap_width,0)) +          elsif dob.is==:para +            if dob.hang \ +            and dob.hang =~/[0-9]/ \ +            and dob.indent != dob.hang +              util=SiSU_TextUtils::Wrap.new(dob.obj,@wrap_width,dob.indent.to_i*2,dob.hang.to_i*2) +              #util=SiSU_TextUtils::Wrap.new(dob.obj,@wrap_width,dob.hang.to_i*2,0) +            elsif dob.indent =~/[1-9]/ +              util=if dob.bullet_ +                SiSU_TextUtils::Wrap.new("* #{dob.obj}",@wrap_width,dob.indent.to_i*2) +              else SiSU_TextUtils::Wrap.new(dob.obj,@wrap_width,dob.indent.to_i*2) +              end +            else +              util=if dob.bullet_ +                SiSU_TextUtils::Wrap.new("* #{dob.obj}",@wrap_width,0) +              else SiSU_TextUtils::Wrap.new(dob.obj,@wrap_width,0) +              end +            end +          else util=SiSU_TextUtils::Wrap.new(dob.obj,@wrap_width,0) +          end +          dob.is==:heading ? util.no_wrap_no_breaks : util.line_wrap +        end +        if heading_decoration== :underscore \ +        and dob.is==:heading +          @plaintext[:body] << wrapped + p_num # main text, contents, body KEEP +          @plaintext[:body] << heading_decorated_underscore(dob,wrapped.length,p_num) +        else +          @plaintext[:body] << wrapped + p_num << break_line # main text, contents, body KEEP +        end +        if @@endnotes[:para] \ +        and not @@endnotes_ +          @@endnotes[:para].each {|e| @plaintext[:body] << e << break_line} +        elsif @@endnotes[:para] \ +        and @@endnotes_ +        end +        @@endnotes[:para]=[] +      end +      def markup(data)                                                       # Used for major markup instructions +        SiSU_Env::InfoEnv.new(@md.fns) +        @data_mod,@endnotes,@level,@cont,@copen,@plaintext_contents_close=Array.new(6){[]} +        (0..6).each { |x| @cont[x]=@level[x]=false } +        (4..6).each { |x| @plaintext_contents_close[x]='' } +        plaintext_tail #($1,$2) +        plaintext_metadata +        table_message='[table conversion awaited, see other document formats]' +        data.each do |dob| +          dob.obj=dob.obj.gsub(/#{Mx[:gr_o]}Th?#{Mx[:tc_p]}.+/um,"#{break_line}#{table_message}"). #fix +            gsub(/.+?#{Mx[:gl_o]}-##{Mx[:gl_c]}/,'').                              # remove dummy headings (used by html) #check also [~-]# +            gsub(/#{Mx[:fa_bold_o]}(.+?)#{Mx[:fa_bold_c]}/, +              "#{decorate.bold.open}\\1#{decorate.bold.close}"). +            gsub(/#{Mx[:fa_italics_o]}(.+?)#{Mx[:fa_italics_c]}/, +              "#{decorate.italics.open}\\1#{decorate.italics.close}"). +            gsub(/#{Mx[:fa_underscore_o]}(.+?)#{Mx[:fa_underscore_c]}/, +              "#{decorate.underscore.open}\\1#{decorate.underscore.close}"). +            gsub(/#{Mx[:fa_subscript_o]}(.+?)#{Mx[:fa_subscript_c]}/, +              "#{decorate.subscript.open}\\1#{decorate.subscript.close}"). +            gsub(/#{Mx[:fa_superscript_o]}(.+?)#{Mx[:fa_superscript_c]}/, +              "#{decorate.superscript.open}\\1#{decorate.superscript.close}"). +            gsub(/#{Mx[:fa_insert_o]}(.+?)#{Mx[:fa_insert_c]}/, +              "#{decorate.insert.open}\\1#{decorate.insert.close}"). +            gsub(/#{Mx[:fa_cite_o]}(.+?)#{Mx[:fa_cite_c]}/, +              "#{decorate.cite.open}\\1#{decorate.cite.close}"). +            gsub(/#{Mx[:fa_strike_o]}(.+?)#{Mx[:fa_strike_c]}/, +              "#{decorate.strike.open}\\1#{decorate.strike.close}"). +            gsub(/#{Mx[:fa_monospace_o]}(.+?)#{Mx[:fa_monospace_c]}/, +              "#{decorate.monospace.open}\\1#{decorate.monospace.close}") +          unless dob.is==:code +            dob.obj=dob.obj.gsub(/#{Mx[:lnk_o]}(.+?)#{Mx[:lnk_c]}#{Mx[:rel_o]}\S+?#{Mx[:rel_c]}/,'\1'). +              gsub(/#{Mx[:url_o]}_(\S+?)#{Mx[:url_c]}/,'\1'). +              gsub(/#{Mx[:lnk_o]}(.+?)#{Mx[:lnk_c]}#{Mx[:url_o]}(\S+?)#{Mx[:url_c]}/,'\1 [link: <\2>]'). +              gsub(/#{Mx[:lnk_o]}(.+?)#{Mx[:lnk_c]}image/,'\1 [link: local image]'). +              gsub(/#{Mx[:url_o]}(\S+?)#{Mx[:url_c]}/,"#{the_text.url_open}\\1#{the_text.url_close}") +            dob.obj=dob.obj.gsub(/\s*#{Mx[:en_a_o]}([\d*+]+)\s+(.+?)#{Mx[:en_a_c]}/,' footnote:[note\1,\2]'). +              gsub(/\s*#{Mx[:en_b_o]}([\d*+]+\s+.+?)#{Mx[:en_b_c]}/,' footnote:[\1]') +            dob.obj=dob.obj.gsub(/#{Mx[:en_a_o]}([\d*+]+)\s+(?:.+?)#{Mx[:en_a_c]}/,'[^\1]'). # endnote marker marked up +              gsub(/#{Mx[:en_b_o]}([\d*+]+)\s+(?:.+?)#{Mx[:en_b_c]}/,'[^\1]'). # endnote marker marked up +              gsub(/#{Mx[:gl_o]}(?:#lt|#060)#{Mx[:gl_c]}/,'<'). +              gsub(/#{Mx[:gl_o]}(?:#gt|#062)#{Mx[:gl_c]}/,'>'). +              gsub(/#{Mx[:gl_o]}#(?:038|amp)#{Mx[:gl_c]}/,'&'). +              gsub(/#{Mx[:gl_o]}#033#{Mx[:gl_c]}/,'!'). +              gsub(/#{Mx[:gl_o]}#035#{Mx[:gl_c]}/,'#'). +              gsub(/#{Mx[:gl_o]}#042#{Mx[:gl_c]}/,'*'). +              gsub(/#{Mx[:gl_o]}#045#{Mx[:gl_c]}/,'-'). +              gsub(/#{Mx[:gl_o]}#047#{Mx[:gl_c]}/,'/'). +              gsub(/#{Mx[:gl_o]}#095#{Mx[:gl_c]}/,'_'). +              gsub(/#{Mx[:gl_o]}#123#{Mx[:gl_c]}/,'{'). +              gsub(/#{Mx[:gl_o]}#125#{Mx[:gl_c]}/,'}'). +              gsub(/#{Mx[:gl_o]}#126#{Mx[:gl_c]}/,'~'). +              gsub(/#{Mx[:gl_o]}#169#{Mx[:gl_c]}/,'©'). +              gsub(/#{Mx[:gl_o]}#092#{Mx[:gl_c]}/,'\\') +          end +          dob.obj=if dob.of==:block                                   # watch +            dob.obj.gsub(/#{Mx[:gl_o]}●#{Mx[:gl_c]}/m,"* "). +              gsub(/\n?#{Mx[:br_line]}\n?|\n?#{Mx[:br_nl]}\n?/m,break_line) +          else dob.obj.gsub(/\n?#{Mx[:br_line]}\n?|\n?#{Mx[:br_nl]}\n?/m,break_line*2) +          end +          if dob.is==:code +            dob.obj=dob.obj.gsub(/(^|[^}])_([<>])/m,'\1\2'). # _> _< +              gsub(/(^|[^}])_([<>])/m,'\1\2') # _<_< +          end +          dob.obj=dob.obj.gsub(/#{Mx[:url_o]}_(\S+?)#{Mx[:url_c]}/,'\1'). +            gsub(/<a href=".+?">(.+?)<\/a>/m,'\1'). +            gsub(/#{Mx[:mk_o]}:name#(\S+?)#{Mx[:mk_c]}/,'').                       # remove name links +            gsub(/ |#{Mx[:nbsp]}/,' ').                                       # decide on +            gsub(/(?:^|[^_\\])#{Mx[:lnk_o]}(\S+?\.(?:png|jpg|gif)) .+?#{Mx[:lnk_c]}#{Mx[:url_o]}\S+?#{Mx[:url_c]}/,'    [ \1 ]'). #"[ #{dir.url.images_local}\/\\1 ]") +            gsub(/(?:^|[^_\\])#{Mx[:lnk_o]}(\S+?\.(?:png|jpg|gif)) .+?#{Mx[:lnk_c]}image/,'    [ \1 ]'). +            gsub(/(?:^|[^_\\])\{\s*\S+?\.(?:png|jpg|gif)\s+.+?"(.*?)"\s*\}\S+/,'[image: "\1"]') +          if dob.obj !~/(^#{Rx[:meta]}|#{Mx[:br_eof]}|#{Mx[:br_endnotes]})/ +            p_num='' +            #ocn +            if dob.is==:heading \ +            or dob.is==:para +              plaintext_structure(dob,p_num) +            elsif dob.is==:group \ +            or dob.is==:block \ +            or dob.is==:verse \ +            or dob.is==:code \ +            or dob.is==:table +              @plaintext[:body] << dob.obj + p_num << break_line +            elsif dob.is==:break +              sp=' ' +              ln='<' #ln='-' +              @plaintext[:body] <<=if dob.obj==Mx[:br_page] \ +              or dob.obj==Mx[:br_page_new] \ +              or dob.obj==Mx[:br_page_line] +                "#{break_line}#{ln*40}#{break_line*2}" +              elsif dob.obj ==Mx[:br_obj] +                "#{break_line}#{sp*20}*  *  *#{break_line*2}" +              end # following empty line (break_line) missing, fix +            end +            dob='' if (dob.obj =~/<a name="n\d+">/ \ +              and dob.obj =~/^(-\{{2}~\d+|<!e[:_]\d+!>)/) # -endnote +            if dob ## Clean Prepared Text +              dob.obj=dob.obj.gsub(/<!.+!>/,' '). +                gsub(/<:\S+>/,' ') +            end +          end +        end +        @plaintext +      end +      def publish(plaintext) +        divider='=' +        content=[] +        content << plaintext[:open] +        content << plaintext[:head] +        content << plaintext[:body] +        content << @@endnotes[:end] if @@endnotes_ +        content << "#{break_line}#{divider*@wrap_width}#{break_line}" +        content << plaintext[:metadata] +        content << "#{break_line}#{divider*@wrap_width}#{break_line}" if @md.stmp =~/\w+/ #not used? +        content << plaintext[:tail] +        outputfile=SiSU_Env::FileOp.new(@md).write_file.asciidoc +        Txt_Output::Output.new.document(content,outputfile) +        @@endnotes={ para: [], end: [] } +      end +    end +  end +end +__END__ +#+END_SRC + +*** txt_asciidoc_decorate.rb + +#+BEGIN_SRC ruby  :tangle "../lib/sisu/txt_asciidoc_decorate.rb" +# <<sisu_document_header>> +module SiSU_Decorate_Txt_AsciiDoc +  def decorate +    def heading +      def inline +        def l0 +          '=' +        end +        def l1 +          '==' +        end +        def l2 +          '===' +        end +        def l3 +          '====' +        end +        def l4 +          '=====' +        end +        def l5 +          '' #'======' #logical +        end +        self +      end +      def underscore +        def l0 +          '=' +        end +        def l1 +          '-' +        end +        def l2 +          '~' +        end +        def l3 +          '^' +        end +        def l4 +          '+' +        end +        def l5 +          '.' #'.' #proposed +        end +        self +      end +      self +    end +    def bold +      def open +        '*' +      end +      def close +        '*' +      end +      self +    end +    def italics +      def open +        '_' +      end +      def close +        '_' +      end +      self +    end +    def underscore +      def open +        '' +      end +      def close +        '' +      end +      self +    end +   #def emphasis +   #  def open +   #    '' +   #  end +   #  def close +   #    '' +   #  end +   #  self +   #end +    def cite +      def open +        '"' +      end +      def close +        '"' +      end +      self +    end +    def insert +      def open +        '' +      end +      def close +        '' +      end +      self +    end +    def strike +      def open +        '-' +      end +      def close +        '-' +      end +      self +    end +    def superscript +      def open +        '^' +      end +      def close +        '^' +      end +      self +    end +    def subscript +      def open +        '~' +      end +      def close +        '~' +      end +      self +    end +    def hilite #bold +      def open +        '*' +      end +      def close +        '*' +      end +      self +    end +    def monospace +      def open +        '+' +      end +      def close +        '+' +      end +      self +    end +    self +  end +end +__END__ +#+END_SRC + +** markdown +*** txt_markdown.rb + +#+BEGIN_SRC ruby  :tangle "../lib/sisu/txt_markdown.rb" +# <<sisu_document_header>> +module SiSU_Txt_Markdown +  require_relative 'ao'                                 # ao.rb +  require_relative 'se'                                 # se.rb +    include SiSU_Env +  require_relative 'shared_metadata'                    # shared_metadata.rb +  require_relative 'generic_parts'                      # generic_parts.rb +  require_relative 'txt_read'                           # txt_read.rb +  require_relative 'txt_shared'                         # txt_shared.rb +  require_relative 'txt_markdown_decorate'              # txt_markdown_decorate.rb +  require_relative 'txt_output'                         # txt_output.rb +  include SiSU_Param +  @@alt_id_count,@@alt_id_count=0,0 +  @@tablefoot='' +  class Source +    include SiSU_Txt_Read +    def initialize(opt) +      @opt=opt +      unless @opt.fns =~/(.+?)\.(?:-|ssm\.)?sst$/ +        puts "#{sf} not a processed file type" +      end +    end +    def read +      begin +        md=SiSU_Param::Parameters.new(@opt).get +        specific={ +          description:     'Markdown (plaintext utf-8)', +          output_path:     md.file.output_path.markdown.dir, +          output_file:     md.file.base_filename.markdown, +        } +        read_generic(@opt,specific) +        SiSU_Txt_Markdown::Source::Scroll.new(md,@ao_array,@wrap_width).songsheet +      rescue +        SiSU_Errors::Rescued.new($!,$@,@opt.selections.str,@opt.fns).location do +          __LINE__.to_s + ':' + __FILE__ +        end +      ensure +      end +    end +    private +    class Scroll <Source +      include SiSU_Parts_Generic +      include SiSU_TextUtils +      include SiSU_Decorate_Txt_Markdown +      @@endnotes={ para: [], end: [] } +      def initialize(md,data,wrap_width) +        @md,@data,@wrap_width=md,data,wrap_width +        @env=SiSU_Env::InfoEnv.new(@md.fns) +        @tab="\t" +        @@endnotes_=case md.opt.selections.str +        when /--footnote/ then false +        when /--endnote/  then true +        else                   true +        end +        @plaintext={ body: [], open: [], close: [], head: [], metadata: [], tail: [] } +      end +      def songsheet +        plaintext=markup(@data) +        publish(plaintext) +      end +      def break_line +        "\n" +      end +      # Used for extraction of endnotes from paragraphs +      def extract_endnotes(dob='') +        notes=dob.obj.scan(/(?:#{Mx[:en_a_o]}|#{Mx[:en_b_o]})([\d*+]+\s+.+?)(?:#{Mx[:en_a_c]}|#{Mx[:en_b_c]})/) +        @n=[] +        notes.flatten.each do |n| #high cost to deal with <br> appropriately within plaintext, consider +          n=n.dup.to_s +          if n =~/#{Mx[:br_line]}|#{Mx[:br_nl]}/ +            fix = n.split(/#{Mx[:br_line]}|#{Mx[:br_nl]}/) #watch #added +            fix.each do |x| +              unless x.empty? then @n << x +              end +            end +          else                     @n << n +          end +        end +        notes=@n.flatten +        notes.each do |e| +          util=(e.to_s =~/^\[[\d*+]+\]:/) \ +          ? (SiSU_TextUtils::Wrap.new(e.to_s,@wrap_width,4,1)) +          : (SiSU_TextUtils::Wrap.new(e.to_s,@wrap_width,1,1)) +          wrap=util.line_wrap +          wrap=if wrap =~ /^\s*[\d*+]+\s+.+?\s*\Z/m +            wrap.gsub(/^(\s*)([\d*+]+)\s+(.+?)\s*\Z/m, <<-GSUB +\\1[\\2]: \\3 +              GSUB +            ) +          else +            wrap.gsub(/^(.+)\Z/m, <<-GSUB +\\1 +              GSUB +            ) +          end +          @@endnotes[:para] << "-#{wrap}" +          @@endnotes[:end] << '' << wrap +        end +        @@endnotes +      end +      def plaintext_metadata +        array=SiSU_Metadata::Summary.new(@md).plaintext.metadata +        array.each do |meta| +          tag,inf=meta.scan(/^.+?:\s|.+/) +          if tag and inf +            util=SiSU_TextUtils::Wrap.new(inf,@wrap_width,15,1) +            txt=util.line_wrap +            @plaintext[:metadata] <<<<WOK + +#{@tab}#{tag}#{txt} +WOK +          end +        end +      end +      def plaintext_tail +#       env=SiSU_Env::InfoEnv.new(@md.fns) +        generator="Generated by: #{@md.project_details.project} #{@md.project_details.version} of #{@md.project_details.date_stamp} (#{@md.project_details.date})"  if @md.project_details.version +        lastdone="Last Generated on: #{Time.now}" +        rubyv="Ruby version: #{@md.ruby_version}" +        sc=if @md.sc_info +          "Source file:    #{@md.sc_filename}#{break_line}Version number: #{@md.sc_number}#{break_line}Version date:   #{@md.sc_date}#{break_line}" +        else '' +        end +        @plaintext[:tail] <<<<WOK +#{break_line} +plaintext (plain text): +   #{@md.file.output_path.markdown.url}/#{@md.file.base_filename.markdown}#{break_line} +Other versions of this document: #{break_line} +manifest: +   #{@md.file.output_path.manifest.url}/#{@md.file.base_filename.manifest}#{break_line} +at: +   #{@md.file.output_path.base.url}#{break_line} + +#{sc} +,* #{generator} +,* #{rubyv} +,* #{lastdone} +,* SiSU #{the_url.sisu_txt} +WOK +      end +      def heading_decorated_inline(dob) +        if dob.is==:heading +          heading_inline = case dob.lc +          when 0 then decorate.heading.inline.l0 +          when 1 then decorate.heading.inline.l1 +          when 2 then decorate.heading.inline.l2 +          when 3 then decorate.heading.inline.l3 +          when 4 then decorate.heading.inline.l4 +          when 5 then decorate.heading.inline.l5 +          when 6 then decorate.heading.inline.l6 +          end +          heading_inline + ' ' +  dob.obj + ' ' + heading_inline +        end +      end +      def heading_decorated_underscore(dob,times,p_num) +        if dob.is==:heading +          #times=@wrap_width if times > @wrap_width +          case dob.lc +          when 0 then decorate.heading.underscore.l0*times + p_num << break_line*2 +          when 1 then decorate.heading.underscore.l1*times + p_num << break_line*2 +          when 2 then decorate.heading.underscore.l2*times + p_num << break_line*2 +          when 3 then decorate.heading.underscore.l3*times + p_num << break_line*2 +          when 4 then decorate.heading.underscore.l4*times + p_num << break_line*2 +          when 5 then decorate.heading.underscore.l5*times + p_num << break_line*2 +          when 6 then decorate.heading.underscore.l6*times + p_num << break_line*2 +          end +        end +      end +      def plaintext_structure(dob='',p_num='') #% Used to extract the structure of a document +        heading_decoration=:inline #(:inline|:underscore) #switch heading decoration between inline & underscore options +        util=nil +        wrapped=if dob.is==:para \ +        || dob.is==:heading +          if dob.is==:heading +            util=(heading_decoration== :inline) \ +            ? (SiSU_TextUtils::Wrap.new(heading_decorated_inline(dob),@wrap_width,0)) +            : (SiSU_TextUtils::Wrap.new(dob.obj,@wrap_width,0)) +          elsif dob.is==:para +            if dob.hang \ +            and dob.hang =~/[0-9]/ \ +            and dob.indent != dob.hang +              util=SiSU_TextUtils::Wrap.new(dob.obj,@wrap_width,dob.indent.to_i*2,dob.hang.to_i*2) +              #util=SiSU_TextUtils::Wrap.new(dob.obj,@wrap_width,dob.hang.to_i*2,0) +            elsif dob.indent =~/[1-9]/ +              util=if dob.bullet_ +                SiSU_TextUtils::Wrap.new("* #{dob.obj}",@wrap_width,dob.indent.to_i*2) +              else SiSU_TextUtils::Wrap.new(dob.obj,@wrap_width,dob.indent.to_i*2) +              end +            else +              util=if dob.bullet_ +                SiSU_TextUtils::Wrap.new("* #{dob.obj}",@wrap_width,0) +              else SiSU_TextUtils::Wrap.new(dob.obj,@wrap_width,0) +              end +            end +          else util=SiSU_TextUtils::Wrap.new(dob.obj,@wrap_width,0) +          end +          dob.is==:heading ? util.no_wrap_no_breaks : util.line_wrap +        end +        if heading_decoration== :underscore \ +        and dob.is==:heading +          @plaintext[:body] << wrapped + p_num # main text, contents, body KEEP +          @plaintext[:body] << heading_decorated_underscore(dob,wrapped.length,p_num) +        else +          @plaintext[:body] << wrapped + p_num << break_line # main text, contents, body KEEP +        end +        if @@endnotes[:para] \ +        and not @@endnotes_ +          @@endnotes[:para].each {|e| @plaintext[:body] << e << break_line} +        elsif @@endnotes[:para] \ +        and @@endnotes_ +        end +        @@endnotes[:para]=[] +      end +      def markup(data)                                                       # Used for major markup instructions +        SiSU_Env::InfoEnv.new(@md.fns) +        @data_mod,@endnotes,@level,@cont,@copen,@plaintext_contents_close=Array.new(6){[]} +        (0..6).each { |x| @cont[x]=@level[x]=false } +        (4..6).each { |x| @plaintext_contents_close[x]='' } +        plaintext_tail #($1,$2) +        plaintext_metadata +        table_message='[table conversion awaited, see other document formats]' +        data.each do |dob| +          dob.obj=dob.obj.gsub(/#{Mx[:gr_o]}Th?#{Mx[:tc_p]}.+/um,"#{break_line}#{table_message}"). #fix +            gsub(/.+?#{Mx[:gl_o]}-##{Mx[:gl_c]}/,'').                              # remove dummy headings (used by html) #check also [~-]# +            gsub(/#{Mx[:fa_bold_o]}(.+?)#{Mx[:fa_bold_c]}/, +              "#{decorate.bold.open}\\1#{decorate.bold.close}"). +            gsub(/#{Mx[:fa_italics_o]}(.+?)#{Mx[:fa_italics_c]}/, +              "#{decorate.italics.open}\\1#{decorate.italics.close}"). +            gsub(/#{Mx[:fa_underscore_o]}(.+?)#{Mx[:fa_underscore_c]}/, +              "#{decorate.underscore.open}\\1#{decorate.underscore.close}"). +            gsub(/#{Mx[:fa_subscript_o]}(.+?)#{Mx[:fa_subscript_c]}/, +              "#{decorate.subscript.open}\\1#{decorate.subscript.close}"). +            gsub(/#{Mx[:fa_superscript_o]}(.+?)#{Mx[:fa_superscript_c]}/, +              "#{decorate.superscript.open}\\1#{decorate.superscript.close}"). +            gsub(/#{Mx[:fa_insert_o]}(.+?)#{Mx[:fa_insert_c]}/, +              "#{decorate.insert.open}\\1#{decorate.insert.close}"). +            gsub(/#{Mx[:fa_cite_o]}(.+?)#{Mx[:fa_cite_c]}/, +              "#{decorate.cite.open}\\1#{decorate.cite.close}"). +            gsub(/#{Mx[:fa_strike_o]}(.+?)#{Mx[:fa_strike_c]}/, +              "#{decorate.strike.open}\\1#{decorate.strike.close}"). +            gsub(/#{Mx[:fa_monospace_o]}(.+?)#{Mx[:fa_monospace_c]}/, +              "#{decorate.monospace.open}\\1#{decorate.monospace.close}") +          unless dob.is==:code +            dob.obj=dob.obj.gsub(/#{Mx[:lnk_o]}(.+?)#{Mx[:lnk_c]}#{Mx[:rel_o]}\S+?#{Mx[:rel_c]}/,'\1'). +              gsub(/#{Mx[:url_o]}_(\S+?)#{Mx[:url_c]}/,'\1'). +              gsub(/#{Mx[:lnk_o]}(.+?)#{Mx[:lnk_c]}#{Mx[:url_o]}(\S+?)#{Mx[:url_c]}/,'\1 [link: <\2>]'). +              gsub(/#{Mx[:lnk_o]}(.+?)#{Mx[:lnk_c]}image/,'\1 [link: local image]'). +              gsub(/#{Mx[:url_o]}(\S+?)#{Mx[:url_c]}/,"#{the_text.url_open}\\1#{the_text.url_close}") +            extract_endnotes(dob) +            dob.obj=dob.obj.gsub(/#{Mx[:en_a_o]}([\d*+]+)\s+(?:.+?)#{Mx[:en_a_c]}/,'[^\1]'). # endnote marker marked up +              gsub(/#{Mx[:en_b_o]}([\d*+]+)\s+(?:.+?)#{Mx[:en_b_c]}/,'[^\1]'). # endnote marker marked up +              gsub(/#{Mx[:gl_o]}(?:#lt|#060)#{Mx[:gl_c]}/,'<'). +              gsub(/#{Mx[:gl_o]}(?:#gt|#062)#{Mx[:gl_c]}/,'>'). +              gsub(/#{Mx[:gl_o]}#(?:038|amp)#{Mx[:gl_c]}/,'&'). +              gsub(/#{Mx[:gl_o]}#033#{Mx[:gl_c]}/,'!'). +              gsub(/#{Mx[:gl_o]}#035#{Mx[:gl_c]}/,'#'). +              gsub(/#{Mx[:gl_o]}#042#{Mx[:gl_c]}/,'*'). +              gsub(/#{Mx[:gl_o]}#045#{Mx[:gl_c]}/,'-'). +              gsub(/#{Mx[:gl_o]}#047#{Mx[:gl_c]}/,'/'). +              gsub(/#{Mx[:gl_o]}#095#{Mx[:gl_c]}/,'_'). +              gsub(/#{Mx[:gl_o]}#123#{Mx[:gl_c]}/,'{'). +              gsub(/#{Mx[:gl_o]}#125#{Mx[:gl_c]}/,'}'). +              gsub(/#{Mx[:gl_o]}#126#{Mx[:gl_c]}/,'~'). +              gsub(/#{Mx[:gl_o]}#169#{Mx[:gl_c]}/,'©'). +              gsub(/#{Mx[:gl_o]}#092#{Mx[:gl_c]}/,'\\') +          end +          dob.obj=if dob.of==:block                                   # watch +            dob.obj.gsub(/#{Mx[:gl_o]}●#{Mx[:gl_c]}/m,"* "). +              gsub(/\n?#{Mx[:br_line]}\n?|\n?#{Mx[:br_nl]}\n?/m,break_line) +          else dob.obj.gsub(/\n?#{Mx[:br_line]}\n?|\n?#{Mx[:br_nl]}\n?/m,break_line*2) +          end +          if dob.is==:code +            dob.obj=dob.obj.gsub(/(^|[^}])_([<>])/m,'\1\2'). # _> _< +              gsub(/(^|[^}])_([<>])/m,'\1\2') # _<_< +          end +          dob.obj=dob.obj.gsub(/#{Mx[:url_o]}_(\S+?)#{Mx[:url_c]}/,'\1'). +            gsub(/<a href=".+?">(.+?)<\/a>/m,'\1'). +            gsub(/#{Mx[:mk_o]}:name#(\S+?)#{Mx[:mk_c]}/,'').                       # remove name links +            gsub(/ |#{Mx[:nbsp]}/,' ').                                       # decide on +            gsub(/(?:^|[^_\\])#{Mx[:lnk_o]}(\S+?\.(?:png|jpg|gif)) .+?#{Mx[:lnk_c]}#{Mx[:url_o]}\S+?#{Mx[:url_c]}/,'    [ \1 ]'). #"[ #{dir.url.images_local}\/\\1 ]") +            gsub(/(?:^|[^_\\])#{Mx[:lnk_o]}(\S+?\.(?:png|jpg|gif)) .+?#{Mx[:lnk_c]}image/,'    [ \1 ]'). +            gsub(/(?:^|[^_\\])\{\s*\S+?\.(?:png|jpg|gif)\s+.+?"(.*?)"\s*\}\S+/,'[image: "\1"]') +          if dob.obj !~/(^#{Rx[:meta]}|#{Mx[:br_eof]}|#{Mx[:br_endnotes]})/ +            p_num='' +            #ocn +            if dob.is==:heading \ +            or dob.is==:para +              plaintext_structure(dob,p_num) +            elsif dob.is==:group \ +            or dob.is==:block \ +            or dob.is==:verse \ +            or dob.is==:code \ +            or dob.is==:table +              @plaintext[:body] << dob.obj + p_num << break_line +            elsif dob.is==:break +              sp=' ' +              ln='-' +              @plaintext[:body] <<=if dob.obj==Mx[:br_page] \ +              or dob.obj==Mx[:br_page_new] \ +              or dob.obj==Mx[:br_page_line] +                "#{break_line}#{ln*40}#{break_line*2}" +              elsif dob.obj ==Mx[:br_obj] +                "#{break_line}#{sp*20}*  *  *#{break_line*2}" +              end # following empty line (break_line) missing, fix +            end +            dob='' if (dob.obj =~/<a name="n\d+">/ \ +              and dob.obj =~/^(-\{{2}~\d+|<!e[:_]\d+!>)/) # -endnote +            if dob ## Clean Prepared Text +              dob.obj=dob.obj.gsub(/<!.+!>/,' '). +                gsub(/<:\S+>/,' ') +            end +          end +        end +        @plaintext +      end +      def publish(plaintext) +        divider='=' +        content=[] +        content << plaintext[:open] +        content << plaintext[:head] +        content << plaintext[:body] +        content << @@endnotes[:end] if @@endnotes_ +        content << "#{break_line}#{divider*@wrap_width}#{break_line}" +        content << plaintext[:metadata] +        content << "#{break_line}#{divider*@wrap_width}#{break_line}" if @md.stmp =~/\w+/ #not used? +        content << plaintext[:tail] +        outputfile=SiSU_Env::FileOp.new(@md).write_file.markdown +        Txt_Output::Output.new.document(content,outputfile) +        @@endnotes={ para: [], end: [] } +      end +    end +  end +end +__END__ +#+END_SRC + +*** txt_markdown_decorate.rb + +#+BEGIN_SRC ruby  :tangle "../lib/sisu/txt_markdown_decorate.rb" +# <<sisu_document_header>> +module SiSU_Decorate_Txt_Markdown +  def decorate +    def heading +      def inline                   #atx +        def l0 +          '#' +        end +        def l1 +          '##' +        end +        def l2 +          '###' +        end +        def l3 +          '####' +        end +        def l4 +          '#####' +        end +        def l5 +          '######' +        end +        self +      end +      def underscore               #Setext +        def l1 +          '=' +        end +        def l2 +          '-' +        end +        def l3 +          '' +        end +        def l4 +          '' +        end +        def l5 +          '' +        end +        def l6 +          '' +        end +        self +      end +      self +    end +    def bold +      def open +        '**' +      end +      def close +        '**' +      end +      self +    end +    def italics +      def open +        '*' +      end +      def close +        '*' +      end +      self +    end +    def underscore +      def open +        '_' +      end +      def close +        '_' +      end +      self +    end +   #def emphasis +   #  def open +   #    '' +   #  end +   #  def close +   #    '' +   #  end +   #  self +   #end +    def cite +      def open +        '"' +      end +      def close +        '"' +      end +      self +    end +    def insert +      def open +        '+' +      end +      def close +        '+' +      end +      self +    end +    def strike +      def open +        '-' +      end +      def close +        '-' +      end +      self +    end +    def superscript +      def open +        '^' +      end +      def close +        '^' +      end +      self +    end +    def subscript +      def open +        '[' +      end +      def close +        ']' +      end +      self +    end +    def hilite +      def open +        '**' +      end +      def close +        '**' +      end +      self +    end +    def monospace +      def open +        '`' +      end +      def close +        '`' +      end +      self +    end +    self +  end +end +__END__ +#+END_SRC + +** orgmode +*** txt_orgmode.rb + +#+BEGIN_SRC ruby  :tangle "../lib/sisu/txt_orgmode.rb" +# <<sisu_document_header>> +module SiSU_Txt_OrgMode +  require_relative 'ao'                                 # ao.rb +  require_relative 'se'                                 # se.rb +    include SiSU_Env +  require_relative 'shared_metadata'                    # shared_metadata.rb +  require_relative 'generic_parts'                      # generic_parts.rb +  require_relative 'txt_read'                           # txt_read.rb +  require_relative 'txt_shared'                         # txt_shared.rb +  require_relative 'txt_orgmode_decorate'               # txt_orgmode_decorate.rb +  require_relative 'txt_output'                         # txt_output.rb +  include SiSU_Param +  @@alt_id_count,@@alt_id_count=0,0 +  @@tablefoot='' +  class Source +    include SiSU_Txt_Read +    def initialize(opt) +      @opt=opt +      unless @opt.fns =~/(.+?)\.(?:-|ssm\.)?sst$/ +        puts "#{sf} not a processed file type" +      end +    end +    def read +      begin +        md=SiSU_Param::Parameters.new(@opt).get +        specific={ +          description:     'OrgMode (plaintext utf-8)', +          output_path:     md.file.output_path.orgmode.dir, +          output_file:     md.file.base_filename.orgmode, +        } +        read_generic(@opt,specific) +        SiSU_Txt_OrgMode::Source::Scroll.new(md,@ao_array,@wrap_width).songsheet +      rescue +        SiSU_Errors::Rescued.new($!,$@,@opt.selections.str,@opt.fns).location do +          __LINE__.to_s + ':' + __FILE__ +        end +      ensure +      end +    end +    private +    class Scroll <Source +      include SiSU_Parts_Generic +      include SiSU_TextUtils +      include SiSU_Decorate_Txt_OrgMode +      @@endnotes={ para: [], end: [] } +      def initialize(md,data,wrap_width) +        @md,@data,@wrap_width=md,data,wrap_width +        @env=SiSU_Env::InfoEnv.new(@md.fns) +        @tab="\t" +        @@endnotes_=case md.opt.selections.str +        when /--footnote/ then false +        when /--endnote/  then true +        else                   true +        end +        @plaintext={ body: [], open: [], close: [], head: [], endnotes: [], metadata: [], tail: [] } +        @plaintext[:head]= <<-WOK +#+TITLE: #{@md.title.short} +#+AUTHOR: #{@md.creator.author} +#+EMAIL: #{@md.creator.email} +#+STARTUP: indent content +#+LANGUAGE: #{@md.opt.lng} +#+OPTIONS: H:3 num:nil toc:t \\n:nil @:t ::t |:t ^:nil _:nil -:t f:t *:t <:t +#+OPTIONS: TeX:t LaTeX:t skip:nil d:nil todo:t pri:nil tags:not-in-toc +#+OPTIONS: author:nil email:nil creator:nil timestamp:nil +#+EXPORT_SELECT_TAGS: export +#+EXPORT_EXCLUDE_TAGS: noexport + +        WOK +      end +      def songsheet +        plaintext=markup(@data) +        publish(plaintext) +      end +      def break_line +        "\n" +      end +      def extract_endnotes(dob='') +        notes=dob.obj. +          scan(/(?:#{Mx[:en_a_o]}|#{Mx[:en_b_o]})([\d*+]+\s+.+?)(?:#{Mx[:en_a_c]}|#{Mx[:en_b_c]})/) +        @n=[] +        notes.flatten.each do |n| #high cost to deal with <br> appropriately within plaintext, consider +          n=n.dup.to_s +          if n =~/#{Mx[:br_line]}|#{Mx[:br_nl]}/ +            fix = n.split(/#{Mx[:br_line]}|#{Mx[:br_nl]}/) #watch #added +            fix.each do |x| +              unless x.empty? then @n << x +              end +            end +          else                     @n << n +          end +        end +        notes=@n.flatten +        notes.each do |e| +          util=(e.to_s =~/^\[[\d*+]+\]:/) \ +          ? (SiSU_TextUtils::Wrap.new(e.to_s,@wrap_width,4,1)) +          : (SiSU_TextUtils::Wrap.new(e.to_s,@wrap_width,1,1)) +          wrap=util.line_wrap +          wrap=if wrap =~ /^\s*[\d*+]+\s+.+?\s*\Z/m +            wrap.gsub(/^(\s*)([\d*+]+)\s+(.+?)\s*\Z/m, <<-GSUB +\\1[fn:\\2] \\3 +              GSUB +            ) +          else +            wrap.gsub(/^(.+)\Z/m, <<-GSUB +\\1 +              GSUB +            ) +          end +          @@endnotes[:para] << "-#{wrap}" +          @@endnotes[:end] << '' << wrap.strip +        end +        @@endnotes +      end +      # Used for extraction of endnotes from paragraphs +      def plaintext_metadata +        array=SiSU_Metadata::Summary.new(@md).plaintext.metadata +        array.each do |meta| +          tag,inf=meta.scan(/^.+?:\s|.+/) +          if tag and inf +            util=SiSU_TextUtils::Wrap.new(inf,@wrap_width,15,1) +            txt=util.line_wrap +            @plaintext[:metadata] <<<<WOK + +#{@tab}#{tag}#{txt} +WOK +          end +        end +      end +      def plaintext_tail +#       env=SiSU_Env::InfoEnv.new(@md.fns) +        generator="Generated by: #{@md.project_details.project} #{@md.project_details.version} of #{@md.project_details.date_stamp} (#{@md.project_details.date})"  if @md.project_details.version +        lastdone="Last Generated on: #{Time.now}" +        rubyv="Ruby version: #{@md.ruby_version}" +        sc=if @md.sc_info +          "Source file:    #{@md.sc_filename}#{break_line}Version number: #{@md.sc_number}#{break_line}Version date:   #{@md.sc_date}#{break_line}" +        else '' +        end +        @plaintext[:tail] <<<<WOK +,** Metadata +#{break_line} +plaintext (plain text): +   #{@md.file.output_path.orgmode.url}/#{@md.file.base_filename.orgmode}#{break_line} +Other versions of this document: #{break_line} +manifest: +   #{@md.file.output_path.manifest.url}/#{@md.file.base_filename.manifest}#{break_line} +at: +   #{@md.file.output_path.base.url}#{break_line} + +  #{sc} +  * #{generator} +  * #{rubyv} +  * #{lastdone} +  * SiSU #{the_url.sisu_txt} +WOK +      end +      def heading_decorated_inline(dob) +        if dob.is==:heading +          heading_inline = case dob.lc +          when 0 then decorate.heading.inline.l0 +          when 1 then decorate.heading.inline.l1 +          when 2 then decorate.heading.inline.l2 +          when 3 then decorate.heading.inline.l3 +          when 4 then decorate.heading.inline.l4 +          when 5 then decorate.heading.inline.l5 +          when 6 then decorate.heading.inline.l6 +          end +          heading_inline + ' ' +  dob.obj +        end +      end +      def plaintext_structure(dob='',p_num='') #% Used to extract the structure of a document +        heading_decoration=:inline #(:inline|:underscore) #switch heading decoration between inline & underscore options +        util=nil +        wrapped=if dob.is==:para \ +        || dob.is==:heading +          if dob.is==:heading +            util=(heading_decoration== :inline) \ +            ? (SiSU_TextUtils::Wrap.new(heading_decorated_inline(dob),@wrap_width,0)) +            : (SiSU_TextUtils::Wrap.new(dob.obj,@wrap_width,0)) +          elsif dob.is==:para +            if dob.hang \ +            and dob.hang =~/[0-9]/ \ +            and dob.indent != dob.hang +              util=SiSU_TextUtils::Wrap.new(dob.obj,@wrap_width,dob.indent.to_i*2,dob.hang.to_i*2) +              #util=SiSU_TextUtils::Wrap.new(dob.obj,@wrap_width,dob.hang.to_i*2,0) +            elsif dob.indent =~/[1-9]/ +              util=if dob.bullet_ +                SiSU_TextUtils::Wrap.new("* #{dob.obj}",@wrap_width,dob.indent.to_i*2) +              else SiSU_TextUtils::Wrap.new(dob.obj,@wrap_width,dob.indent.to_i*2) +              end +            else +              util=if dob.bullet_ +                SiSU_TextUtils::Wrap.new("* #{dob.obj}",@wrap_width,0) +              else SiSU_TextUtils::Wrap.new(dob.obj,@wrap_width,0) +              end +            end +          else util=SiSU_TextUtils::Wrap.new(dob.obj,@wrap_width,0) +          end +          dob.is==:heading ? util.no_wrap_no_breaks : util.line_wrap +        end +        if dob.is==:para \ +        || dob.is==:heading +          @plaintext[:body] << wrapped + p_num << break_line # main text, contents, body KEEP +        end +# remove ... +        if @@endnotes[:para] \ +        and not @@endnotes_ +          @@endnotes[:para].each {|e| @plaintext[:body] << e << break_line} +        elsif @@endnotes[:para] \ +        and @@endnotes_ +          @@endnotes[:para].each {|e| @plaintext[:endnotes] << e << break_line} +        end +        @@endnotes[:para]=[] +      end +      def markup(data)                                                       # Used for major markup instructions +        SiSU_Env::InfoEnv.new(@md.fns) +        @data_mod,@endnotes,@level,@cont,@copen,@plaintext_contents_close=Array.new(6){[]} +        (0..6).each { |x| @cont[x]=@level[x]=false } +        (4..6).each { |x| @plaintext_contents_close[x]='' } +        plaintext_tail #($1,$2) +        plaintext_metadata +        table_message='[table conversion awaited, see other document formats]' +        data.each do |dob| +          dob.obj=dob.obj.gsub(/#{Mx[:gr_o]}Th?#{Mx[:tc_p]}.+/um,"#{break_line}#{table_message}"). #fix +            gsub(/.+?#{Mx[:gl_o]}-##{Mx[:gl_c]}/,'').                              # remove dummy headings (used by html) #check also [~-]# +            gsub(/#{Mx[:fa_bold_o]}(.+?)#{Mx[:fa_bold_c]}/, +              "#{decorate.bold.open}\\1#{decorate.bold.close}"). +            gsub(/#{Mx[:fa_italics_o]}(.+?)#{Mx[:fa_italics_c]}/, +              "#{decorate.italics.open}\\1#{decorate.italics.close}"). +            gsub(/#{Mx[:fa_underscore_o]}(.+?)#{Mx[:fa_underscore_c]}/, +              "#{decorate.underscore.open}\\1#{decorate.underscore.close}"). +            gsub(/#{Mx[:fa_subscript_o]}(.+?)#{Mx[:fa_subscript_c]}/, +              "#{decorate.subscript.open}\\1#{decorate.subscript.close}"). +            gsub(/#{Mx[:fa_superscript_o]}(.+?)#{Mx[:fa_superscript_c]}/, +              "#{decorate.superscript.open}\\1#{decorate.superscript.close}"). +            gsub(/#{Mx[:fa_insert_o]}(.+?)#{Mx[:fa_insert_c]}/, +              "#{decorate.insert.open}\\1#{decorate.insert.close}"). +            gsub(/#{Mx[:fa_cite_o]}(.+?)#{Mx[:fa_cite_c]}/, +              "#{decorate.cite.open}\\1#{decorate.cite.close}"). +            gsub(/#{Mx[:fa_strike_o]}(.+?)#{Mx[:fa_strike_c]}/, +              "#{decorate.strike.open}\\1#{decorate.strike.close}"). +            gsub(/#{Mx[:fa_monospace_o]}(.+?)#{Mx[:fa_monospace_c]}/, +              "#{decorate.monospace.open}\\1#{decorate.monospace.close}") +          unless dob.is==:code +            dob.obj=dob.obj.gsub(/#{Mx[:lnk_o]}(.+?)#{Mx[:lnk_c]}#{Mx[:rel_o]}\S+?#{Mx[:rel_c]}/,'\1'). +              gsub(/#{Mx[:url_o]}_(\S+?)#{Mx[:url_c]}/,'[[\1]]'). +              gsub(/#{Mx[:lnk_o]}(.+?)#{Mx[:lnk_c]}#{Mx[:url_o]}(\S+?)#{Mx[:url_c]}/,'[[\2][\1]]'). +              gsub(/#{Mx[:lnk_o]}(.+?)#{Mx[:lnk_c]}image/,'[[\1]] [link: local image]'). +              gsub(/#{Mx[:url_o]}(\S+?)#{Mx[:url_c]}/,'[[\1]]') #urls +            extract_endnotes(dob) +            dob.obj=dob.obj.gsub(/#{Mx[:en_a_o]}([\d*+]+)\s+(?:.+?)#{Mx[:en_a_c]}/,'[fn:\1]'). # endnote marker marked up +              gsub(/#{Mx[:en_b_o]}([\d*+]+)\s+(?:.+?)#{Mx[:en_b_c]}/,'[fn:\1]'). # endnote marker marked up +              gsub(/#{Mx[:gl_o]}(?:#lt|#060)#{Mx[:gl_c]}/,'<'). +              gsub(/#{Mx[:gl_o]}(?:#gt|#062)#{Mx[:gl_c]}/,'>'). +              gsub(/#{Mx[:gl_o]}#(?:038|amp)#{Mx[:gl_c]}/,'&'). +              gsub(/#{Mx[:gl_o]}#033#{Mx[:gl_c]}/,'!'). +              gsub(/#{Mx[:gl_o]}#035#{Mx[:gl_c]}/,'#'). +              gsub(/#{Mx[:gl_o]}#042#{Mx[:gl_c]}/,'*'). +              gsub(/#{Mx[:gl_o]}#045#{Mx[:gl_c]}/,'-'). +              gsub(/#{Mx[:gl_o]}#047#{Mx[:gl_c]}/,'/'). +              gsub(/#{Mx[:gl_o]}#095#{Mx[:gl_c]}/,'_'). +              gsub(/#{Mx[:gl_o]}#123#{Mx[:gl_c]}/,'{'). +              gsub(/#{Mx[:gl_o]}#125#{Mx[:gl_c]}/,'}'). +              gsub(/#{Mx[:gl_o]}#126#{Mx[:gl_c]}/,'~'). +              gsub(/#{Mx[:gl_o]}#169#{Mx[:gl_c]}/,'©'). +              gsub(/#{Mx[:gl_o]}#092#{Mx[:gl_c]}/,'\\') +          end +          dob.obj=if dob.of==:block                                   # watch +            dob.obj.gsub(/#{Mx[:gl_o]}●#{Mx[:gl_c]}/m,"* "). +              gsub(/\n?#{Mx[:br_line]}\n?|\n?#{Mx[:br_nl]}\n?/m,break_line) +          else dob.obj.gsub(/\n?#{Mx[:br_line]}\n?|\n?#{Mx[:br_nl]}\n?/m,break_line*2) +          end +          if dob.is==:code +            dob.obj=dob.obj.gsub(/(^|[^}])_([<>])/m,'\1\2'). # _> _< +              gsub(/(^|[^}])_([<>])/m,'\1\2'). # _<_< +              gsub(/^\*/m,',*') +            dob.obj = '#+BEGIN_SRC sh :tangle no :padline no :exports none   :noweb yes' + "\n" + dob.obj + '#+END_SRC' +          end +          dob.obj=dob.obj.gsub(/#{Mx[:url_o]}_(\S+?)#{Mx[:url_c]}/,'\1'). +            gsub(/<a href=".+?">(.+?)<\/a>/m,'\1'). +            gsub(/#{Mx[:mk_o]}:name#(\S+?)#{Mx[:mk_c]}/,'').                       # remove name links +            gsub(/ |#{Mx[:nbsp]}/,' ').                                       # decide on +            gsub(/(?:^|[^_\\])#{Mx[:lnk_o]}(\S+?\.(?:png|jpg|gif)) .+?#{Mx[:lnk_c]}#{Mx[:url_o]}\S+?#{Mx[:url_c]}/,'    [ \1 ]'). #"[ #{dir.url.images_local}\/\\1 ]") +            gsub(/(?:^|[^_\\])#{Mx[:lnk_o]}(\S+?\.(?:png|jpg|gif)) .+?#{Mx[:lnk_c]}image/,'    [ \1 ]'). +            gsub(/(?:^|[^_\\])\{\s*\S+?\.(?:png|jpg|gif)\s+.+?"(.*?)"\s*\}\S+/,'[image: "\1"]') +          if dob.obj !~/(^#{Rx[:meta]}|#{Mx[:br_eof]}|#{Mx[:br_endnotes]})/ +            p_num='' +            #ocn +            if dob.is==:heading \ +            or dob.is==:para +              plaintext_structure(dob,p_num) +            elsif dob.is==:group \ +            or dob.is==:block \ +            or dob.is==:verse \ +            or dob.is==:code \ +            or dob.is==:table +              @plaintext[:body] << dob.obj + p_num << break_line +            elsif dob.is==:break +              sp=' ' +              ln='<' #ln='-' +              @plaintext[:body] <<=if dob.obj==Mx[:br_page] \ +              or dob.obj==Mx[:br_page_new] \ +              or dob.obj==Mx[:br_page_line] +                "#{break_line}#{ln*40}#{break_line*2}" +              elsif dob.obj ==Mx[:br_obj] +                "#{break_line}#{sp*20}*  *  *#{break_line*2}" +              end # following empty line (break_line) missing, fix +            end +            dob='' if (dob.obj =~/<a name="n\d+">/ \ +              and dob.obj =~/^(-\{{2}~\d+|<!e[:_]\d+!>)/) # -endnote +            if dob ## Clean Prepared Text +              dob.obj=dob.obj.gsub(/<!.+!>/,' '). +                gsub(/<:\S+>/,' ') +            end +          end +        end +        @plaintext +      end +      def publish(plaintext) +        divider='=' +        content=[] +        content << plaintext[:open] +        content << plaintext[:head] +        content << plaintext[:body] +        if @@endnotes_ +          content << '** Endnotes' <<  @@endnotes[:end] +        end +        content << plaintext[:metadata] +        content << "#{break_line}#{divider*@wrap_width}#{break_line}" if @md.stmp =~/\w+/ #not used? +        content << plaintext[:tail] +        outputfile=SiSU_Env::FileOp.new(@md).write_file.orgmode +        Txt_Output::Output.new.document(content,outputfile) +        @@endnotes={ para: [], end: [] } +      end +    end +  end +end +__END__ +#+END_SRC + +*** txt_orgmode_decorate.rb + +#+BEGIN_SRC ruby  :tangle "../lib/sisu/txt_orgmode_decorate.rb" +# <<sisu_document_header>> +module SiSU_Decorate_Txt_OrgMode +  def decorate +    def heading +      def inline +        def l0 +          '*' +        end +        def l1 +          '**' +        end +        def l2 +          '***' +        end +        def l3 +          '****' +        end +        def l4 +          '*****' +        end +        def l5 +          '******' +        end +        self +      end +      self +    end +    def bold +      def open +        '*' +      end +      def close +        '*' +      end +      self +    end +    def italics +      def open +        '/' +      end +      def close +        '/' +      end +      self +    end +    def underscore +      def open +        '' +      end +      def close +        '' +      end +      self +    end +   #def emphasis +   #  def open +   #    '' +   #  end +   #  def close +   #    '' +   #  end +   #  self +   #end +    def cite +      def open +        '"' +      end +      def close +        '"' +      end +      self +    end +    def insert +      def open +        '' +      end +      def close +        '' +      end +      self +    end +    def strike +      def open +        '+' +      end +      def close +        '+' +      end +      self +    end +    def superscript +      def open +        '^' +      end +      def close +        '^' +      end +      self +    end +    def subscript +      def open +        '~' +      end +      def close +        '~' +      end +      self +    end +    def hilite #bold +      def open +        '*' +      end +      def close +        '*' +      end +      self +    end +    def monospace +      def open +        '~' +      end +      def close +        '~' +      end +      self +    end +    self +  end +end +__END__ +#+END_SRC + +** plain +*** txt_plain.rb + +#+BEGIN_SRC ruby  :tangle "../lib/sisu/txt_plain.rb" +# <<sisu_document_header>> +module SiSU_Txt_Plain +  require_relative 'ao'                                 # ao.rb +  require_relative 'se'                                 # se.rb +    include SiSU_Env +  require_relative 'shared_metadata'                    # shared_metadata.rb +  require_relative 'generic_parts'                      # generic_parts.rb +  require_relative 'txt_read'                           # txt_read.rb +  require_relative 'txt_shared'                         # txt_shared.rb +  require_relative 'txt_plain_decorate'                 # txt_plain_decorate.rb +  require_relative 'txt_output'                         # txt_output.rb +  include SiSU_Param +  @@alt_id_count,@@alt_id_count=0,0 +  @@tablefoot='' +  class Source +    include SiSU_Txt_Read +    def initialize(opt) +      @opt=opt +      unless @opt.fns =~/(.+?)\.(?:-|ssm\.)?sst$/ +        puts "#{sf} not a processed file type" +      end +    end +    def read +      begin +        md=SiSU_Param::Parameters.new(@opt).get +        specific={ +          description:     'Plaintext (utf-8)', +          output_path:     md.file.output_path.txt.dir, +          output_file:     md.file.base_filename.txt, +        } +        read_generic(@opt,specific) +        SiSU_Txt_Plain::Source::Scroll.new(md,@ao_array,@wrap_width).songsheet +      rescue +        SiSU_Errors::Rescued.new($!,$@,@opt.selections.str,@opt.fns).location do +          __LINE__.to_s + ':' + __FILE__ +        end +      ensure +      end +    end +    private +    class Scroll <Source +      include SiSU_Parts_Generic +      include SiSU_TextUtils +      include SiSU_Decorate_Txt_Plain +      @@endnotes={ para: [], end: [] } +      def initialize(md,data,wrap_width) +        @md,@data,@wrap_width=md,data,wrap_width +        @env=SiSU_Env::InfoEnv.new(@md.fns) +        @tab="\t" +        @@endnotes_=case md.opt.selections.str +        when /--footnote/ then false +        when /--endnote/  then true +        else                   true +        end +        @plaintext={ body: [], open: [], close: [], head: [], metadata: [], tail: [] } +      end +      def songsheet +        plaintext=markup(@data) +        publish(plaintext) +      end +      def break_line +        "\n" +      end +      # Used for extraction of endnotes from paragraphs +      def extract_endnotes(dob='') +        notes=dob.obj.scan(/(?:#{Mx[:en_a_o]}|#{Mx[:en_b_o]})([\d*+]+\s+.+?)(?:#{Mx[:en_a_c]}|#{Mx[:en_b_c]})/) +        @n=[] +        notes.flatten.each do |n| #high cost to deal with <br> appropriately within plaintext, consider +          n=n.dup.to_s +          if n =~/#{Mx[:br_line]}|#{Mx[:br_nl]}/ +            fix = n.split(/#{Mx[:br_line]}|#{Mx[:br_nl]}/) #watch #added +            fix.each do |x| +              unless x.empty?; @n << x +              end +            end +          else                 @n << n +          end +        end +        notes=@n.flatten +        notes.each do |e| +          util=(e.to_s =~/^\[[\d*+]+\]:/) \ +          ? (SiSU_TextUtils::Wrap.new(e.to_s,@wrap_width,4,1)) +          : (SiSU_TextUtils::Wrap.new(e.to_s,@wrap_width,1,1)) +          wrap=util.line_wrap +          wrap=if wrap =~ /^\s*[\d*+]+\s+.+?\s*\Z/m +            wrap.gsub(/^(\s*)([\d*+]+)\s+(.+?)\s*\Z/m, <<-GSUB +\\1[\\2]: \\3 +              GSUB +            ) +          else +            wrap.gsub(/^(.+)\Z/m, <<-GSUB +\\1 +              GSUB +            ) +          end +          @@endnotes[:para] << "-#{wrap}" +          @@endnotes[:end] << '' << wrap +        end +        @@endnotes +      end +      def plaintext_metadata +        array=SiSU_Metadata::Summary.new(@md).plaintext.metadata +        array.each do |meta| +          tag,inf=meta.scan(/^.+?:\s|.+/) +          if tag and inf +            util=SiSU_TextUtils::Wrap.new(inf,@wrap_width,15,1) +            txt=util.line_wrap +            @plaintext[:metadata] <<<<WOK + +#{@tab}#{tag}#{txt} +WOK +          end +        end +      end +      def plaintext_tail +#       env=SiSU_Env::InfoEnv.new(@md.fns) +        generator="Generated by: #{@md.project_details.project} #{@md.project_details.version} of #{@md.project_details.date_stamp} (#{@md.project_details.date})"  if @md.project_details.version +        lastdone="Last Generated on: #{Time.now}" +        rubyv="Ruby version: #{@md.ruby_version}" +        sc=if @md.sc_info +          "Source file:    #{@md.sc_filename}#{break_line}Version number: #{@md.sc_number}#{break_line}Version date:   #{@md.sc_date}#{break_line}" +        else '' +        end +        @plaintext[:tail] <<<<WOK +#{break_line} +plaintext (plain text): +   #{@md.file.output_path.txt.url}/#{@md.file.base_filename.txt}#{break_line} +Other versions of this document: #{break_line} +manifest: +   #{@md.file.output_path.manifest.url}/#{@md.file.base_filename.manifest}#{break_line} +at: +   #{@md.file.output_path.base.url}#{break_line} + +#{sc} +,* #{generator} +,* #{rubyv} +,* #{lastdone} +,* SiSU #{the_url.sisu_txt} +WOK +      end +      def plaintext_structure(dob='',p_num='') #% Used to extract the structure of a document +        lv=n=n3=nil +        if dob.is==:heading +          lv=dob.ln +          n=lv - 1 +          n3=lv + 2 +        end +        util=nil +        wrapped=if dob.is==:para \ +        || dob.is==:heading +          if dob.is==:para +            if dob.hang \ +            and dob.hang =~/[0-9]/ \ +            and dob.indent != dob.hang +              util=SiSU_TextUtils::Wrap.new(dob.obj,@wrap_width,dob.indent.to_i*2,dob.hang.to_i*2) +              #util=SiSU_TextUtils::Wrap.new(dob.obj,@wrap_width,dob.hang.to_i*2,0) +            elsif dob.indent =~/[1-9]/ +              util=if dob.bullet_ +                SiSU_TextUtils::Wrap.new("* #{dob.obj}",@wrap_width,dob.indent.to_i*2) +              else SiSU_TextUtils::Wrap.new(dob.obj,@wrap_width,dob.indent.to_i*2) +              end +            else +              util=if dob.bullet_ +                SiSU_TextUtils::Wrap.new("* #{dob.obj}",@wrap_width,0) +              else SiSU_TextUtils::Wrap.new(dob.obj,@wrap_width,0) +              end +            end +          else util=SiSU_TextUtils::Wrap.new(dob.obj,@wrap_width,0) +          end +          util.line_wrap +        end +        if lv +          times=wrapped.length +          times=@wrap_width if times > @wrap_width +          @plaintext[:body] << case lv +          when 0 then wrapped.upcase << break_line << decorate.heading_underscore.l0*times + p_num << break_line*2 +          when 1 then wrapped.upcase << break_line << decorate.heading_underscore.l1*times + p_num << break_line*2 +          when 2 then wrapped.upcase << break_line << decorate.heading_underscore.l2*times + p_num << break_line*2 +          when 3 then wrapped.upcase << break_line << decorate.heading_underscore.l3*times + p_num << break_line*2 +          when 4 +            unless dob.use_ == :dummy +              wrapped.upcase << break_line << decorate.heading_underscore.l4*times + p_num << break_line*2 +            end +          when 5 then wrapped.upcase << break_line << decorate.heading_underscore.l5*times + p_num << break_line*2 +          when 6 then wrapped.upcase << break_line << decorate.heading_underscore.l6*times + p_num << break_line*2 +          when 7 +            wrapped.upcase << break_line << decorate.heading_underscore.l7*times + p_num << break_line*2 +          #when 7 then wrapped.upcase << break_line << decorate.heading_underscore.l7*times + p_num << break_line*2 +          end +        else +          @plaintext[:body] << wrapped + p_num << break_line # main text, contents, body KEEP +        end +        if @@endnotes[:para] \ +        and not @@endnotes_ +          @@endnotes[:para].each {|e| @plaintext[:body] << e << break_line} +        elsif @@endnotes[:para] \ +        and @@endnotes_ +        end +        @@endnotes[:para]=[] +      end +      def ocn_display(dob) +        make=SiSU_Env::ProcessingSettings.new(@md) +        if make.build.plaintext_ocn? +          if defined? dob.ocn \ +          and dob.ocn.is_a?(Fixnum) +            (defined? dob.ocn) \ +            ? "\n#{Dx[:ocn_o]}#{dob.ocn}#{Dx[:ocn_c]}" \ +            : '' +          else '' +          end +        else '' +        end +      end +      def markup(data)                                                       # Used for major markup instructions +        SiSU_Env::InfoEnv.new(@md.fns) +        @data_mod,@endnotes,@level,@cont,@copen,@plaintext_contents_close=Array.new(6){[]} +        (0..7).each { |x| @cont[x]=@level[x]=false } +        (4..7).each { |x| @plaintext_contents_close[x]='' } +        plaintext_tail #($1,$2) +        plaintext_metadata +        table_message='[table omitted, see other document formats]' +        data.each do |dob| +          dob.obj=dob.obj.gsub(/#{Mx[:gr_o]}Th?#{Mx[:tc_p]}.+/um,"#{break_line}#{table_message}"). #fix +            gsub(/.+?#{Mx[:gl_o]}-##{Mx[:gl_c]}/,'').                              # remove dummy headings (used by html) #check also [~-]# +            gsub(/#{Mx[:fa_bold_o]}(.+?)#{Mx[:fa_bold_c]}/, +              "#{decorate.bold.open}\\1#{decorate.bold.close}"). +            gsub(/#{Mx[:fa_italics_o]}(.+?)#{Mx[:fa_italics_c]}/, +              "#{decorate.italics.open}\\1#{decorate.italics.close}"). +            gsub(/#{Mx[:fa_underscore_o]}(.+?)#{Mx[:fa_underscore_c]}/, +              "#{decorate.underscore.open}\\1#{decorate.underscore.close}"). +            gsub(/#{Mx[:fa_subscript_o]}(.+?)#{Mx[:fa_subscript_c]}/, +              "#{decorate.subscript.open}\\1#{decorate.subscript.close}"). +            gsub(/#{Mx[:fa_superscript_o]}(.+?)#{Mx[:fa_superscript_c]}/, +              "#{decorate.superscript.open}\\1#{decorate.superscript.close}"). +            gsub(/#{Mx[:fa_insert_o]}(.+?)#{Mx[:fa_insert_c]}/, +              "#{decorate.insert.open}\\1#{decorate.insert.close}"). +            gsub(/#{Mx[:fa_cite_o]}(.+?)#{Mx[:fa_cite_c]}/, +              "#{decorate.cite.open}\\1#{decorate.cite.close}"). +            gsub(/#{Mx[:fa_strike_o]}(.+?)#{Mx[:fa_strike_c]}/, +              "#{decorate.strike.open}\\1#{decorate.strike.close}"). +            gsub(/#{Mx[:fa_monospace_o]}(.+?)#{Mx[:fa_monospace_c]}/, +              "#{decorate.monospace.open}\\1#{decorate.monospace.close}") +          unless dob.is==:code +            dob.obj=dob.obj.gsub(/#{Mx[:lnk_o]}(.+?)#{Mx[:lnk_c]}#{Mx[:rel_o]}\S+?#{Mx[:rel_c]}/,'\1'). +              gsub(/#{Mx[:url_o]}_(\S+?)#{Mx[:url_c]}/,'\1'). +              gsub(/#{Mx[:lnk_o]}(.+?)#{Mx[:lnk_c]}#{Mx[:url_o]}(\S+?)#{Mx[:url_c]}/,'\1 [link: <\2>]'). +              gsub(/#{Mx[:lnk_o]}(.+?)#{Mx[:lnk_c]}image/,'\1 [link: local image]'). +              gsub(/#{Mx[:url_o]}(\S+?)#{Mx[:url_c]}/,"#{the_text.url_open}\\1#{the_text.url_close}") +            extract_endnotes(dob) +            dob.obj=dob.obj.gsub(/#{Mx[:en_a_o]}([\d*+]+)\s+(?:.+?)#{Mx[:en_a_c]}/,'[^\1]'). # endnote marker marked up +              gsub(/#{Mx[:en_b_o]}([\d*+]+)\s+(?:.+?)#{Mx[:en_b_c]}/,'[^\1]'). # endnote marker marked up +              gsub(/#{Mx[:gl_o]}(?:#lt|#060)#{Mx[:gl_c]}/,'<'). +              gsub(/#{Mx[:gl_o]}(?:#gt|#062)#{Mx[:gl_c]}/,'>'). +              gsub(/#{Mx[:gl_o]}#(?:038|amp)#{Mx[:gl_c]}/,'&'). +              gsub(/#{Mx[:gl_o]}#033#{Mx[:gl_c]}/,'!'). +              gsub(/#{Mx[:gl_o]}#035#{Mx[:gl_c]}/,'#'). +              gsub(/#{Mx[:gl_o]}#042#{Mx[:gl_c]}/,'*'). +              gsub(/#{Mx[:gl_o]}#045#{Mx[:gl_c]}/,'-'). +              gsub(/#{Mx[:gl_o]}#047#{Mx[:gl_c]}/,'/'). +              gsub(/#{Mx[:gl_o]}#095#{Mx[:gl_c]}/,'_'). +              gsub(/#{Mx[:gl_o]}#123#{Mx[:gl_c]}/,'{'). +              gsub(/#{Mx[:gl_o]}#125#{Mx[:gl_c]}/,'}'). +              gsub(/#{Mx[:gl_o]}#126#{Mx[:gl_c]}/,'~'). +              gsub(/#{Mx[:gl_o]}#169#{Mx[:gl_c]}/,'©'). +              gsub(/#{Mx[:gl_o]}#092#{Mx[:gl_c]}/,'\\') +          end +          dob.obj=if dob.of==:block                                   # watch +            dob.obj.gsub(/#{Mx[:gl_o]}●#{Mx[:gl_c]}/m,"* "). +              gsub(/\n?#{Mx[:br_line]}\n?|\n?#{Mx[:br_nl]}\n?/m,break_line) +          else dob.obj.gsub(/\n?#{Mx[:br_line]}\n?|\n?#{Mx[:br_nl]}\n?/m,break_line*2) +          end +          if dob.is==:code +            dob.obj=dob.obj.gsub(/(^|[^}])_([<>])/m,'\1\2'). # _> _< +              gsub(/(^|[^}])_([<>])/m,'\1\2') # _<_< +          end +          dob.obj=dob.obj.gsub(/#{Mx[:url_o]}_(\S+?)#{Mx[:url_c]}/,'\1'). +            gsub(/<a href=".+?">(.+?)<\/a>/m,'\1'). +            gsub(/#{Mx[:mk_o]}:name#(\S+?)#{Mx[:mk_c]}/,'').                       # remove name links +            gsub(/ |#{Mx[:nbsp]}/,' ').                                       # decide on +            gsub(/(?:^|[^_\\])#{Mx[:lnk_o]}(\S+?\.(?:png|jpg|gif)) .+?#{Mx[:lnk_c]}#{Mx[:url_o]}\S+?#{Mx[:url_c]}/,'    [ \1 ]'). #"[ #{dir.url.images_local}\/\\1 ]") +            gsub(/(?:^|[^_\\])#{Mx[:lnk_o]}(\S+?\.(?:png|jpg|gif)) .+?#{Mx[:lnk_c]}image/,'    [ \1 ]'). +            gsub(/(?:^|[^_\\])\{\s*\S+?\.(?:png|jpg|gif)\s+.+?"(.*?)"\s*\}\S+/,'[image: "\1"]') +          if dob.obj !~/(^#{Rx[:meta]}|#{Mx[:br_eof]}|#{Mx[:br_endnotes]})/ +            p_num=ocn_display(dob) +            if dob.is==:heading \ +            or dob.is==:para +              plaintext_structure(dob,p_num) +            elsif dob.is==:group \ +            or dob.is==:block \ +            or dob.is==:verse \ +            or dob.is==:code \ +            or dob.is==:table +              @plaintext[:body] << dob.obj + p_num << break_line +            elsif dob.is==:break +              sp=' ' +              ln='-' +              @plaintext[:body] <<=if dob.obj==Mx[:br_page] \ +              or dob.obj==Mx[:br_page_new] \ +              or dob.obj==Mx[:br_page_line] +                "#{break_line}#{ln*40}#{break_line*2}" +              elsif dob.obj ==Mx[:br_obj] +                "#{break_line}#{sp*20}*  *  *#{break_line*2}" +              end # following empty line (break_line) missing, fix +            end +            dob='' if (dob.obj =~/<a name="n\d+">/ \ +              and dob.obj =~/^(-\{{2}~\d+|<!e[:_]\d+!>)/) # -endnote +            if dob ## Clean Prepared Text +              dob.obj=dob.obj.gsub(/<!.+!>/,' '). +                gsub(/<:\S+>/,' ') +            end +          end +        end +        @plaintext +      end +      def publish(plaintext) +        divider='=' +        content=[] +        content << plaintext[:open] +        content << plaintext[:head] +        content << plaintext[:body] +        content << @@endnotes[:end] if @@endnotes_ +        content << "#{break_line}#{divider*@wrap_width}#{break_line}" +        content << plaintext[:metadata] +        content << "#{break_line}#{divider*@wrap_width}#{break_line}" if @md.stmp =~/\w+/ #not used? +        content << plaintext[:tail] +        outputfile=SiSU_Env::FileOp.new(@md).write_file.txt +        Txt_Output::Output.new.document(content,outputfile) +        @@endnotes={ para: [], end: [] } +      end +    end +  end +end +__END__ +  bold_o:                    '*',          bold_c:                   '*', + #bold_o:                    '!',          bold_c:                   '!', + #emphasis_o:                '*',          emphasis_c:               '*', +  italics_o:                 '/',          italics_c:                '/', +  underscore_o:              '_',          underscore_c:             '_', +  cite_o:                    '"',          cite_c:                   '"', +  insert_o:                  '+',          insert_c:                 '+', +  strike_o:                  '-',          strike_c:                 '-', +  superscript_o:             '^',          superscript_c:            '^', +  subscript_o:               '[',          subscript_c:              ']', +  hilite_o:                  '*',          hilite_c:                 '*', +  monospace_o:               '',           monospace_c:              '', +  p_bold_o:                  '!{',         p_bold_c:                 '}!', +  p_italics_o:               '/{',         p_italics_c:              '}/', +  p_underscore_o:            '_{',         p_underscore_c:           '}_', +  p_cite_o:                  '"{',         p_cite_c:                 '}"', +  p_insert_o:                '+{',         p_insert_c:               '}+', +  p_strike_o:                '-{',         p_strike_c:               '}-', +  p_superscript_o:           '^{',         p_superscript_c:          '}^', +  p_subscript_o:             ',{',         p_subscript_c:            '},', +  p_hilite_o:                '*{',         p_hilite_c:               '}*', +  p_monospace_o:             '#{',         p_monospace_c:            '}#', +#+END_SRC + +*** txt_plain_decorate.rb + +#+BEGIN_SRC ruby  :tangle "../lib/sisu/txt_plain_decorate.rb" +# <<sisu_document_header>> +module SiSU_Decorate_Txt_Plain +  def decorate +    def heading_underscore +      def l0 +        '=' +      end +      def l1 +        '*' +      end +      def l2 +        '+' +      end +      def l3 +        '~' +      end +      def l4 +        '-' +      end +      def l5 +        '.' +      end +      def l6 +        '.' +      end +      def l7 +        '.' +      end +      self +    end +    def bold +      def open +        '*' +      end +      def close +        '*' +      end +      self +    end +    def italics +      def open +        '/' +      end +      def close +        '/' +      end +      self +    end +    def underscore +      def open +        '_' +      end +      def close +        '_' +      end +      self +    end +   #def emphasis +   #  def open +   #    '' +   #  end +   #  def close +   #    '' +   #  end +   #  self +   #end +    def cite +      def open +        '"' +      end +      def close +        '"' +      end +      self +    end +    def insert +      def open +        '+' +      end +      def close +        '+' +      end +      self +    end +    def strike +      def open +        '-' +      end +      def close +        '-' +      end +      self +    end +    def superscript +      def open +        '^' +      end +      def close +        '^' +      end +      self +    end +    def subscript +      def open +        '[' +      end +      def close +        ']' +      end +      self +    end +    def hilite +      def open +        '*' +      end +      def close +        '*' +      end +      self +    end +    def monospace +      def open +        '#' +      end +      def close +        '#' +      end +      self +    end +    self +  end +end +__END__ +#+END_SRC + +** rst +*** txt_rst.rb + +#+BEGIN_SRC ruby  :tangle "../lib/sisu/txt_rst.rb" +# <<sisu_document_header>> +module SiSU_Txt_rST +  require_relative 'ao'                                 # ao.rb +  require_relative 'se'                                 # se.rb +    include SiSU_Env +  require_relative 'shared_metadata'                    # shared_metadata.rb +  require_relative 'generic_parts'                      # generic_parts.rb +  require_relative 'txt_read'                           # txt_read.rb +  require_relative 'txt_shared'                         # txt_shared.rb +  require_relative 'txt_rst_decorate'                   # txt_rst_decorate.rb +  require_relative 'txt_output'                         # txt_output.rb +  include SiSU_Param +  @@alt_id_count,@@alt_id_count=0,0 +  @@tablefoot='' +  class Source +    include SiSU_Txt_Read +    def initialize(opt) +      @opt=opt +      unless @opt.fns =~/(.+?)\.(?:-|ssm\.)?sst$/ +        puts "#{sf} not a processed file type" +      end +    end +    def read +      begin +        md=SiSU_Param::Parameters.new(@opt).get +        specific={ +          description:     'rST (plaintext utf-8)', +          output_path:     md.file.output_path.rst.dir, +          output_file:     md.file.base_filename.rst, +        } +        read_generic(@opt,specific) +        SiSU_Txt_rST::Source::Scroll.new(md,@ao_array,@wrap_width).songsheet +      rescue +        SiSU_Errors::Rescued.new($!,$@,@opt.selections.str,@opt.fns).location do +          __LINE__.to_s + ':' + __FILE__ +        end +      ensure +      end +    end +    private +    class Scroll <Source +      include SiSU_Parts_Generic +      include SiSU_TextUtils +      include SiSU_Decorate_Txt_rST +      @@endnotes={ para: [], end: [] } +      def initialize(md,data,wrap_width) +        @md,@data,@wrap_width=md,data,wrap_width +        @env=SiSU_Env::InfoEnv.new(@md.fns) +        @tab="\t" +        @@endnotes_=case md.opt.selections.str +        when /--footnote/ then false +        when /--endnote/  then true +        else                   true +        end +        @plaintext={ body: [], open: [], close: [], head: [], metadata: [], tail: [] } +      end +      def songsheet +        plaintext=markup(@data) +        publish(plaintext) +      end +      def break_line +        "\n" +      end +      # Used for extraction of endnotes from paragraphs +      def extract_endnotes(dob='') +        notes=dob.obj.scan(/(?:#{Mx[:en_a_o]}|#{Mx[:en_b_o]})([\d*+]+\s+.+?)(?:#{Mx[:en_a_c]}|#{Mx[:en_b_c]})/) +        @n=[] +        notes.flatten.each do |n| #high cost to deal with <br> appropriately within plaintext, consider +          n=n.dup.to_s +          if n =~/#{Mx[:br_line]}|#{Mx[:br_nl]}/ +            fix = n.split(/#{Mx[:br_line]}|#{Mx[:br_nl]}/) #watch #added +            fix.each do |x| +              unless x.empty?; @n << x +              end +            end +          else                 @n << n +          end +        end +        notes=@n.flatten +        notes.each do |e| +          util=(e.to_s =~/^\[[\d*+]+\]:/) \ +          ? (SiSU_TextUtils::Wrap.new(e.to_s,@wrap_width,4,1)) +          : (SiSU_TextUtils::Wrap.new(e.to_s,@wrap_width,1,1)) +          wrap=util.line_wrap +          wrap=if wrap =~ /^\s*[\d*+]+\s+.+?\s*\Z/m +            wrap.gsub(/^(\s*)([\d*+]+)\s+(.+?)\s*\Z/m, <<-GSUB +\\1[\\2]: \\3 +              GSUB +            ) +          else +            wrap.gsub(/^(.+)\Z/m, <<-GSUB +\\1 +              GSUB +            ) +          end +          @@endnotes[:para] << "-#{wrap}" +          @@endnotes[:end] << '' << wrap +        end +        @@endnotes +      end +      def plaintext_metadata +        array=SiSU_Metadata::Summary.new(@md).plaintext.metadata +        array.each do |meta| +          tag,inf=meta.scan(/^.+?:\s|.+/) +          if tag and inf +            util=SiSU_TextUtils::Wrap.new(inf,@wrap_width,15,1) +            txt=util.line_wrap +            @plaintext[:metadata] <<<<WOK + +#{@tab}#{tag}#{txt} +WOK +          end +        end +      end +      def plaintext_tail +#       env=SiSU_Env::InfoEnv.new(@md.fns) +        generator="Generated by: #{@md.project_details.project} #{@md.project_details.version} of #{@md.project_details.date_stamp} (#{@md.project_details.date})"  if @md.project_details.version +        lastdone="Last Generated on: #{Time.now}" +        rubyv="Ruby version: #{@md.ruby_version}" +        sc=if @md.sc_info +          "Source file:    #{@md.sc_filename}#{break_line}Version number: #{@md.sc_number}#{break_line}Version date:   #{@md.sc_date}#{break_line}" +        else '' +        end +        @plaintext[:tail] <<<<WOK +#{break_line} +plaintext (plain text): +   #{@md.file.output_path.rst.url}/#{@md.file.base_filename.rst}#{break_line} +Other versions of this document: #{break_line} +manifest: +   #{@md.file.output_path.manifest.url}/#{@md.file.base_filename.manifest}#{break_line} +at: +   #{@md.file.output_path.base.url}#{break_line} + +#{sc} +,* #{generator} +,* #{rubyv} +,* #{lastdone} +,* SiSU #{the_url.sisu_txt} +WOK +      end +      def heading_decorated_underscore(dob,times,p_num) +        if dob.is==:heading +          #times=@wrap_width if times > @wrap_width +          case dob.lc +          when 0 then decorate.heading.underscore.l0*times + p_num << break_line*2 +          when 1 then decorate.heading.underscore.l1*times + p_num << break_line*2 +          when 2 then decorate.heading.underscore.l2*times + p_num << break_line*2 +          when 3 then decorate.heading.underscore.l3*times + p_num << break_line*2 +          when 4 then decorate.heading.underscore.l4*times + p_num << break_line*2 +          when 5 then decorate.heading.underscore.l5*times + p_num << break_line*2 +          when 6 then decorate.heading.underscore.l6*times + p_num << break_line*2 +          end +        end +      end +      def plaintext_structure(dob='',p_num='') #% Used to extract the structure of a document +        util=nil +        wrapped=if dob.is==:para \ +        || dob.is==:heading +          if dob.is==:heading +            util=SiSU_TextUtils::Wrap.new(dob.obj,@wrap_width,0) +          elsif dob.is==:para +            if dob.hang \ +            and dob.hang =~/[0-9]/ \ +            and dob.indent != dob.hang +              util=SiSU_TextUtils::Wrap.new(dob.obj,@wrap_width,dob.indent.to_i*2,dob.hang.to_i*2) +              #util=SiSU_TextUtils::Wrap.new(dob.obj,@wrap_width,dob.hang.to_i*2,0) +            elsif dob.indent =~/[1-9]/ +              util=if dob.bullet_ +                SiSU_TextUtils::Wrap.new("* #{dob.obj}",@wrap_width,dob.indent.to_i*2) +              else SiSU_TextUtils::Wrap.new(dob.obj,@wrap_width,dob.indent.to_i*2) +              end +            else +              util=if dob.bullet_ +                SiSU_TextUtils::Wrap.new("* #{dob.obj}",@wrap_width,0) +              else SiSU_TextUtils::Wrap.new(dob.obj,@wrap_width,0) +              end +            end +          else util=SiSU_TextUtils::Wrap.new(dob.obj,@wrap_width,0) +          end +          dob.is==:heading ? util.no_wrap_no_breaks : util.line_wrap +        end +        if dob.is==:heading +          @plaintext[:body] << wrapped + p_num # main text, contents, body KEEP +          @plaintext[:body] << heading_decorated_underscore(dob,wrapped.length,p_num) +        else +          @plaintext[:body] << wrapped + p_num << break_line # main text, contents, body KEEP +        end +        if @@endnotes[:para] \ +        and not @@endnotes_ +          @@endnotes[:para].each {|e| @plaintext[:body] << e << break_line} +        elsif @@endnotes[:para] \ +        and @@endnotes_ +        end +        @@endnotes[:para]=[] +      end +      def markup(data)                                                       # Used for major markup instructions +        SiSU_Env::InfoEnv.new(@md.fns) +        @data_mod,@endnotes,@level,@cont,@copen,@plaintext_contents_close=Array.new(6){[]} +        (0..6).each { |x| @cont[x]=@level[x]=false } +        (4..6).each { |x| @plaintext_contents_close[x]='' } +        plaintext_tail #($1,$2) +        plaintext_metadata +        table_message='[table conversion awaited, see other document formats]' +        data.each do |dob| +          dob.obj=dob.obj.gsub(/#{Mx[:gr_o]}Th?#{Mx[:tc_p]}.+/um,"#{break_line}#{table_message}"). #fix +            gsub(/.+?#{Mx[:gl_o]}-##{Mx[:gl_c]}/,'').                              # remove dummy headings (used by html) #check also [~-]# +            gsub(/#{Mx[:fa_bold_o]}(.+?)#{Mx[:fa_bold_c]}/, +              "#{decorate.bold.open}\\1#{decorate.bold.close}"). +            gsub(/#{Mx[:fa_italics_o]}(.+?)#{Mx[:fa_italics_c]}/, +              "#{decorate.italics.open}\\1#{decorate.italics.close}"). +            gsub(/#{Mx[:fa_underscore_o]}(.+?)#{Mx[:fa_underscore_c]}/, +              "#{decorate.underscore.open}\\1#{decorate.underscore.close}"). +            gsub(/#{Mx[:fa_subscript_o]}(.+?)#{Mx[:fa_subscript_c]}/, +              "#{decorate.subscript.open}\\1#{decorate.subscript.close}"). +            gsub(/#{Mx[:fa_superscript_o]}(.+?)#{Mx[:fa_superscript_c]}/, +              "#{decorate.superscript.open}\\1#{decorate.superscript.close}"). +            gsub(/#{Mx[:fa_insert_o]}(.+?)#{Mx[:fa_insert_c]}/, +              "#{decorate.insert.open}\\1#{decorate.insert.close}"). +            gsub(/#{Mx[:fa_cite_o]}(.+?)#{Mx[:fa_cite_c]}/, +              "#{decorate.cite.open}\\1#{decorate.cite.close}"). +            gsub(/#{Mx[:fa_strike_o]}(.+?)#{Mx[:fa_strike_c]}/, +              "#{decorate.strike.open}\\1#{decorate.strike.close}"). +            gsub(/#{Mx[:fa_monospace_o]}(.+?)#{Mx[:fa_monospace_c]}/, +              "#{decorate.monospace.open}\\1#{decorate.monospace.close}") +          unless dob.is==:code +            dob.obj=dob.obj.gsub(/#{Mx[:lnk_o]}(.+?)#{Mx[:lnk_c]}#{Mx[:rel_o]}\S+?#{Mx[:rel_c]}/,'\1'). +              gsub(/#{Mx[:url_o]}_(\S+?)#{Mx[:url_c]}/,'\1'). +              gsub(/#{Mx[:lnk_o]}(.+?)#{Mx[:lnk_c]}#{Mx[:url_o]}(\S+?)#{Mx[:url_c]}/,'\1 [link: <\2>]'). +              gsub(/#{Mx[:lnk_o]}(.+?)#{Mx[:lnk_c]}image/,'\1 [link: local image]'). +              gsub(/#{Mx[:url_o]}(\S+?)#{Mx[:url_c]}/,"#{the_text.url_open}\\1#{the_text.url_close}") +            extract_endnotes(dob) +            dob.obj=dob.obj.gsub(/#{Mx[:en_a_o]}([\d*+]+)\s+(?:.+?)#{Mx[:en_a_c]}/,'[^\1]'). # endnote marker marked up +              gsub(/#{Mx[:en_b_o]}([\d*+]+)\s+(?:.+?)#{Mx[:en_b_c]}/,'[^\1]'). # endnote marker marked up +              gsub(/#{Mx[:gl_o]}(?:#lt|#060)#{Mx[:gl_c]}/,'<'). +              gsub(/#{Mx[:gl_o]}(?:#gt|#062)#{Mx[:gl_c]}/,'>'). +              gsub(/#{Mx[:gl_o]}#(?:038|amp)#{Mx[:gl_c]}/,'&'). +              gsub(/#{Mx[:gl_o]}#033#{Mx[:gl_c]}/,'!'). +              gsub(/#{Mx[:gl_o]}#035#{Mx[:gl_c]}/,'#'). +              gsub(/#{Mx[:gl_o]}#042#{Mx[:gl_c]}/,'*'). +              gsub(/#{Mx[:gl_o]}#045#{Mx[:gl_c]}/,'-'). +              gsub(/#{Mx[:gl_o]}#047#{Mx[:gl_c]}/,'/'). +              gsub(/#{Mx[:gl_o]}#095#{Mx[:gl_c]}/,'_'). +              gsub(/#{Mx[:gl_o]}#123#{Mx[:gl_c]}/,'{'). +              gsub(/#{Mx[:gl_o]}#125#{Mx[:gl_c]}/,'}'). +              gsub(/#{Mx[:gl_o]}#126#{Mx[:gl_c]}/,'~'). +              gsub(/#{Mx[:gl_o]}#169#{Mx[:gl_c]}/,'©'). +              gsub(/#{Mx[:gl_o]}#092#{Mx[:gl_c]}/,'\\') +          end +          dob.obj=if dob.of==:block                                   # watch +            dob.obj.gsub(/#{Mx[:gl_o]}●#{Mx[:gl_c]}/m,"* "). +              gsub(/\n?#{Mx[:br_line]}\n?|\n?#{Mx[:br_nl]}\n?/m,break_line) +          else dob.obj.gsub(/\n?#{Mx[:br_line]}\n?|\n?#{Mx[:br_nl]}\n?/m,break_line*2) +          end +          if dob.is==:code +            dob.obj=dob.obj.gsub(/(^|[^}])_([<>])/m,'\1\2'). # _> _< +              gsub(/(^|[^}])_([<>])/m,'\1\2') # _<_< +          end +          dob.obj=dob.obj.gsub(/#{Mx[:url_o]}_(\S+?)#{Mx[:url_c]}/,'\1'). +            gsub(/<a href=".+?">(.+?)<\/a>/m,'\1'). +            gsub(/#{Mx[:mk_o]}:name#(\S+?)#{Mx[:mk_c]}/,'').                       # remove name links +            gsub(/ |#{Mx[:nbsp]}/,' ').                                       # decide on +            gsub(/(?:^|[^_\\])#{Mx[:lnk_o]}(\S+?\.(?:png|jpg|gif)) .+?#{Mx[:lnk_c]}#{Mx[:url_o]}\S+?#{Mx[:url_c]}/,'    [ \1 ]'). #"[ #{dir.url.images_local}\/\\1 ]") +            gsub(/(?:^|[^_\\])#{Mx[:lnk_o]}(\S+?\.(?:png|jpg|gif)) .+?#{Mx[:lnk_c]}image/,'    [ \1 ]'). +            gsub(/(?:^|[^_\\])\{\s*\S+?\.(?:png|jpg|gif)\s+.+?"(.*?)"\s*\}\S+/,'[image: "\1"]') +          if dob.obj !~/(^#{Rx[:meta]}|#{Mx[:br_eof]}|#{Mx[:br_endnotes]})/ +            p_num='' +            #ocn +            if dob.is==:heading \ +            or dob.is==:para +              plaintext_structure(dob,p_num) +            elsif dob.is==:group \ +            or dob.is==:block \ +            or dob.is==:verse \ +            or dob.is==:code \ +            or dob.is==:table +              @plaintext[:body] << dob.obj + p_num << break_line +            elsif dob.is==:break +              sp=' ' +              ln='-' +              @plaintext[:body] <<=if dob.obj==Mx[:br_page] \ +              or dob.obj==Mx[:br_page_new] \ +              or dob.obj==Mx[:br_page_line] +                "#{break_line}#{ln*40}#{break_line*2}" +              elsif dob.obj ==Mx[:br_obj] +                "#{break_line}#{sp*20}*  *  *#{break_line*2}" +              end # following empty line (break_line) missing, fix +            end +            dob='' if (dob.obj =~/<a name="n\d+">/ \ +              and dob.obj =~/^(-\{{2}~\d+|<!e[:_]\d+!>)/) # -endnote +            if dob ## Clean Prepared Text +              dob.obj=dob.obj.gsub(/<!.+!>/,' '). +                gsub(/<:\S+>/,' ') +            end +          end +        end +        @plaintext +      end +      def publish(plaintext) +        divider='=' +        content=[] +        content << plaintext[:open] +        content << plaintext[:head] +        content << plaintext[:body] +        content << @@endnotes[:end] if @@endnotes_ +        content << "#{break_line}#{divider*@wrap_width}#{break_line}" +        content << plaintext[:metadata] +        content << "#{break_line}#{divider*@wrap_width}#{break_line}" if @md.stmp =~/\w+/ #not used? +        content << plaintext[:tail] +        outputfile=SiSU_Env::FileOp.new(@md).write_file.rst +        Txt_Output::Output.new.document(content,outputfile) +        @@endnotes={ para: [], end: [] } +      end +    end +  end +end +__END__ +#+END_SRC + +*** txt_rst_decorate.rb + +#+BEGIN_SRC ruby  :tangle "../lib/sisu/txt_rst_decorate.rb" +# <<sisu_document_header>> +module SiSU_Decorate_Txt_rST +  def decorate +    def heading +      def underscore +        def l0 +          '=' +        end +        def l1 +          '-' +        end +        def l2 +          '`' +        end +        def l3 +          ':' +        end +        def l4 +          "'" +        end +        def l5 +          '"' +        end +        self +      end +      self +    end +    def bold +      def open +        '*' +      end +      def close +        '*' +      end +      self +    end +    def italics +      def open +        '/' +      end +      def close +        '/' +      end +      self +    end +    def underscore +      def open +        '_' +      end +      def close +        '_' +      end +      self +    end +   #def emphasis +   #  def open +   #    '' +   #  end +   #  def close +   #    '' +   #  end +   #  self +   #end +    def cite +      def open +        '"' +      end +      def close +        '"' +      end +      self +    end +    def insert +      def open +        '+' +      end +      def close +        '+' +      end +      self +    end +    def strike +      def open +        '-' +      end +      def close +        '-' +      end +      self +    end +    def superscript +      def open +        '^' +      end +      def close +        '^' +      end +      self +    end +    def subscript +      def open +        '[' +      end +      def close +        ']' +      end +      self +    end +    def hilite +      def open +        '*' +      end +      def close +        '*' +      end +      self +    end +    def monospace +      def open +        '#' +      end +      def close +        '#' +      end +      self +    end +    self +  end +end +__END__ +#+END_SRC + +** textile +*** txt_textile.rb + +#+BEGIN_SRC ruby  :tangle "../lib/sisu/txt_textile.rb" +# <<sisu_document_header>> +module SiSU_Txt_Textile +  require_relative 'ao'                                 # ao.rb +  require_relative 'se'                                 # se.rb +    include SiSU_Env +  require_relative 'shared_metadata'                    # shared_metadata.rb +  require_relative 'generic_parts'                      # generic_parts.rb +  require_relative 'txt_read'                           # txt_read.rb +  require_relative 'txt_shared'                         # txt_shared.rb +  require_relative 'txt_textile_decorate'               # txt_textile_decorate.rb +  require_relative 'txt_output'                         # txt_output.rb +  include SiSU_Param +  @@alt_id_count,@@alt_id_count=0,0 +  @@tablefoot='' +  class Source +    include SiSU_Txt_Read +    #include SiSU_Parts_Generic +    def initialize(opt) +      @opt=opt +      unless @opt.fns =~/(.+?)\.(?:-|ssm\.)?sst$/ +        puts "#{sf} not a processed file type" +      end +    end +    def read +      begin +        md=SiSU_Param::Parameters.new(@opt).get +        specific={ +          description:     'Textile (plaintext utf-8)', +          output_path:     md.file.output_path.textile.dir, +          output_file:     md.file.base_filename.textile, +        } +        read_generic(@opt,specific) +        SiSU_Txt_Textile::Source::Scroll.new(md,@ao_array,@wrap_width).songsheet +      rescue +        SiSU_Errors::Rescued.new($!,$@,@opt.selections.str,@opt.fns).location do +          __LINE__.to_s + ':' + __FILE__ +        end +      ensure +      end +    end +    private +    class Scroll <Source +      include SiSU_Parts_Generic +      include SiSU_TextUtils +      include SiSU_Decorate_Txt_Textile +      @@endnotes={ para: [], end: [] } +      def initialize(md,data,wrap_width) +        @md,@data,@wrap_width=md,data,wrap_width +        @env=SiSU_Env::InfoEnv.new(@md.fns) +        @tab="\t" +        @@endnotes_=case md.opt.selections.str +        when /--footnote/ then false +        when /--endnote/  then true +        else                   true +        end +        @plaintext={ body: [], open: [], close: [], head: [], metadata: [], tail: [] } +      end +      def songsheet +        plaintext=markup(@data) +        publish(plaintext) +      end +      def break_line +        "\n" +      end +      # Used for extraction of endnotes from paragraphs +      def extract_endnotes(dob='') +        notes=dob.obj.scan(/(?:#{Mx[:en_a_o]}|#{Mx[:en_b_o]})([\d*+]+\s+.+?)(?:#{Mx[:en_a_c]}|#{Mx[:en_b_c]})/) +        @n=[] +        notes.flatten.each do |n| #high cost to deal with <br> appropriately within plaintext, consider +          n=n.dup.to_s +          if n =~/#{Mx[:br_line]}|#{Mx[:br_nl]}/ +            fix = n.split(/#{Mx[:br_line]}|#{Mx[:br_nl]}/) #watch #added +            fix.each do |x| +              unless x.empty?; @n << x +              end +            end +          else                 @n << n +          end +        end +        notes=@n.flatten +        notes.each do |e| +          util=(e.to_s =~/^\[[\d*+]+\]:/) \ +          ? (SiSU_TextUtils::Wrap.new(e.to_s,@wrap_width,4,1)) +          : (SiSU_TextUtils::Wrap.new(e.to_s,@wrap_width,1,1)) +          wrap=util.line_wrap +          wrap=if wrap =~ /^\s*[\d*+]+\s+.+?\s*\Z/m +            wrap.gsub(/^(\s*)([\d*+]+)\s+(.+?)\s*\Z/m, <<-GSUB +\\1[\\2]: \\3 +              GSUB +            ) +          else +            wrap.gsub(/^(.+)\Z/m, <<-GSUB +\\1 +              GSUB +            ) +          end +          @@endnotes[:para] << "-#{wrap}" +          @@endnotes[:end] << '' << wrap +        end +        @@endnotes +      end +      def plaintext_metadata +        array=SiSU_Metadata::Summary.new(@md).plaintext.metadata +        array.each do |meta| +          tag,inf=meta.scan(/^.+?:\s|.+/) +          if tag and inf +            util=SiSU_TextUtils::Wrap.new(inf,@wrap_width,15,1) +            txt=util.line_wrap +            @plaintext[:metadata] <<<<WOK + +#{@tab}#{tag}#{txt} +WOK +          end +        end +      end +      def plaintext_tail +#       env=SiSU_Env::InfoEnv.new(@md.fns) +        generator="Generated by: #{@md.project_details.project} #{@md.project_details.version} of #{@md.project_details.date_stamp} (#{@md.project_details.date})"  if @md.project_details.version +        lastdone="Last Generated on: #{Time.now}" +        rubyv="Ruby version: #{@md.ruby_version}" +        sc=if @md.sc_info +          "Source file:    #{@md.sc_filename}#{break_line}Version number: #{@md.sc_number}#{break_line}Version date:   #{@md.sc_date}#{break_line}" +        else '' +        end +        @plaintext[:tail] <<<<WOK +#{break_line} +plaintext (plain text): +   #{@md.file.output_path.textile.url}/#{@md.file.base_filename.textile}#{break_line} +Other versions of this document: #{break_line} +manifest: +   #{@md.file.output_path.manifest.url}/#{@md.file.base_filename.manifest}#{break_line} +at: +   #{@md.file.output_path.base.url}#{break_line} + +#{sc} +,* #{generator} +,* #{rubyv} +,* #{lastdone} +,* SiSU #{the_url.sisu_txt} +WOK +      end +      def heading_decorated_inline(dob) +        if dob.is==:heading +          heading_inline = case dob.lc +          when 0 then decorate.heading.inline.l0 +          when 1 then decorate.heading.inline.l1 +          when 2 then decorate.heading.inline.l2 +          when 3 then decorate.heading.inline.l3 +          when 4 then decorate.heading.inline.l4 +          when 5 then decorate.heading.inline.l5 +          when 6 then decorate.heading.inline.l6 +          end +          heading_inline + ' ' +  dob.obj +        end +      end +      def plaintext_structure(dob='',p_num='') #% Used to extract the structure of a document +        util=nil +        wrapped=if dob.is==:para \ +        || dob.is==:heading +          if dob.is==:heading +            util=SiSU_TextUtils::Wrap.new(heading_decorated_inline(dob),@wrap_width,0,0) +          elsif dob.is==:para +            if dob.hang \ +            and dob.hang =~/[0-9]/ \ +            and dob.indent != dob.hang +              util=SiSU_TextUtils::Wrap.new(dob.obj,@wrap_width,dob.indent.to_i*2,dob.hang.to_i*2) +              #util=SiSU_TextUtils::Wrap.new(dob.obj,@wrap_width,dob.hang.to_i*2,0) +            elsif dob.indent =~/[1-9]/ +              util=if dob.bullet_ +                SiSU_TextUtils::Wrap.new("* #{dob.obj}",@wrap_width,dob.indent.to_i*2) +              else SiSU_TextUtils::Wrap.new(dob.obj,@wrap_width,dob.indent.to_i*2) +              end +            else +              util=if dob.bullet_ +                SiSU_TextUtils::Wrap.new("* #{dob.obj}",@wrap_width,0) +              else SiSU_TextUtils::Wrap.new(dob.obj,@wrap_width,0) +              end +            end +          else util=SiSU_TextUtils::Wrap.new(dob.obj,@wrap_width,0) +          end +          dob.is==:heading ? util.no_wrap_no_breaks : util.line_wrap +        end +        @plaintext[:body] << wrapped + p_num << break_line # main text, contents, body KEEP +        if @@endnotes[:para] \ +        and not @@endnotes_ +          @@endnotes[:para].each {|e| @plaintext[:body] << e << break_line} +        elsif @@endnotes[:para] \ +        and @@endnotes_ +        end +        @@endnotes[:para]=[] +      end +      def markup(data)                                                       # Used for major markup instructions +        SiSU_Env::InfoEnv.new(@md.fns) +        @data_mod,@endnotes,@level,@cont,@copen,@plaintext_contents_close=Array.new(6){[]} +        (0..6).each { |x| @cont[x]=@level[x]=false } +        (4..6).each { |x| @plaintext_contents_close[x]='' } +        plaintext_tail #($1,$2) +        plaintext_metadata +        table_message='[table conversion awaited, see other document formats]' +        data.each do |dob| +          dob.obj=dob.obj.gsub(/#{Mx[:gr_o]}Th?#{Mx[:tc_p]}.+/um,"#{break_line}#{table_message}"). #fix +            gsub(/.+?#{Mx[:gl_o]}-##{Mx[:gl_c]}/,'').                              # remove dummy headings (used by html) #check also [~-]# +            gsub(/#{Mx[:fa_bold_o]}(.+?)#{Mx[:fa_bold_c]}/, +              "#{decorate.bold.open}\\1#{decorate.bold.close}"). +            gsub(/#{Mx[:fa_italics_o]}(.+?)#{Mx[:fa_italics_c]}/, +              "#{decorate.italics.open}\\1#{decorate.italics.close}"). +            gsub(/#{Mx[:fa_underscore_o]}(.+?)#{Mx[:fa_underscore_c]}/, +              "#{decorate.underscore.open}\\1#{decorate.underscore.close}"). +            gsub(/#{Mx[:fa_subscript_o]}(.+?)#{Mx[:fa_subscript_c]}/, +              "#{decorate.subscript.open}\\1#{decorate.subscript.close}"). +            gsub(/#{Mx[:fa_superscript_o]}(.+?)#{Mx[:fa_superscript_c]}/, +              "#{decorate.superscript.open}\\1#{decorate.superscript.close}"). +            gsub(/#{Mx[:fa_insert_o]}(.+?)#{Mx[:fa_insert_c]}/, +              "#{decorate.insert.open}\\1#{decorate.insert.close}"). +            gsub(/#{Mx[:fa_cite_o]}(.+?)#{Mx[:fa_cite_c]}/, +              "#{decorate.cite.open}\\1#{decorate.cite.close}"). +            gsub(/#{Mx[:fa_strike_o]}(.+?)#{Mx[:fa_strike_c]}/, +              "#{decorate.strike.open}\\1#{decorate.strike.close}"). +            gsub(/#{Mx[:fa_monospace_o]}(.+?)#{Mx[:fa_monospace_c]}/, +              "#{decorate.monospace.open}\\1#{decorate.monospace.close}") +          unless dob.is==:code +            dob.obj=dob.obj.gsub(/#{Mx[:lnk_o]}(.+?)#{Mx[:lnk_c]}#{Mx[:rel_o]}\S+?#{Mx[:rel_c]}/,'\1'). +              gsub(/#{Mx[:url_o]}_(\S+?)#{Mx[:url_c]}/,'\1'). +              gsub(/#{Mx[:lnk_o]}(.+?)#{Mx[:lnk_c]}#{Mx[:url_o]}(\S+?)#{Mx[:url_c]}/,'\1 [link: <\2>]'). +              gsub(/#{Mx[:lnk_o]}(.+?)#{Mx[:lnk_c]}image/,'\1 [link: local image]'). +              gsub(/#{Mx[:url_o]}(\S+?)#{Mx[:url_c]}/,"#{the_text.url_open}\\1#{the_text.url_close}") +            extract_endnotes(dob) +            dob.obj=dob.obj.gsub(/#{Mx[:en_a_o]}([\d*+]+)\s+(?:.+?)#{Mx[:en_a_c]}/,'[^\1]'). # endnote marker marked up +              gsub(/#{Mx[:en_b_o]}([\d*+]+)\s+(?:.+?)#{Mx[:en_b_c]}/,'[^\1]'). # endnote marker marked up +              gsub(/#{Mx[:gl_o]}(?:#lt|#060)#{Mx[:gl_c]}/,'<'). +              gsub(/#{Mx[:gl_o]}(?:#gt|#062)#{Mx[:gl_c]}/,'>'). +              gsub(/#{Mx[:gl_o]}#(?:038|amp)#{Mx[:gl_c]}/,'&'). +              gsub(/#{Mx[:gl_o]}#033#{Mx[:gl_c]}/,'!'). +              gsub(/#{Mx[:gl_o]}#035#{Mx[:gl_c]}/,'#'). +              gsub(/#{Mx[:gl_o]}#042#{Mx[:gl_c]}/,'*'). +              gsub(/#{Mx[:gl_o]}#045#{Mx[:gl_c]}/,'-'). +              gsub(/#{Mx[:gl_o]}#047#{Mx[:gl_c]}/,'/'). +              gsub(/#{Mx[:gl_o]}#095#{Mx[:gl_c]}/,'_'). +              gsub(/#{Mx[:gl_o]}#123#{Mx[:gl_c]}/,'{'). +              gsub(/#{Mx[:gl_o]}#125#{Mx[:gl_c]}/,'}'). +              gsub(/#{Mx[:gl_o]}#126#{Mx[:gl_c]}/,'~'). +              gsub(/#{Mx[:gl_o]}#169#{Mx[:gl_c]}/,'©'). +              gsub(/#{Mx[:gl_o]}#092#{Mx[:gl_c]}/,'\\') +          end +          dob.obj=if dob.of==:block                                   # watch +            dob.obj.gsub(/#{Mx[:gl_o]}●#{Mx[:gl_c]}/m,"* "). +              gsub(/\n?#{Mx[:br_line]}\n?|\n?#{Mx[:br_nl]}\n?/m,break_line) +          else dob.obj.gsub(/\n?#{Mx[:br_line]}\n?|\n?#{Mx[:br_nl]}\n?/m,break_line*2) +          end +          if dob.is==:code +            dob.obj=dob.obj.gsub(/(^|[^}])_([<>])/m,'\1\2'). # _> _< +              gsub(/(^|[^}])_([<>])/m,'\1\2') # _<_< +          end +          dob.obj=dob.obj.gsub(/#{Mx[:url_o]}_(\S+?)#{Mx[:url_c]}/,'\1'). +            gsub(/<a href=".+?">(.+?)<\/a>/m,'\1'). +            gsub(/#{Mx[:mk_o]}:name#(\S+?)#{Mx[:mk_c]}/,'').                       # remove name links +            gsub(/ |#{Mx[:nbsp]}/,' ').                                       # decide on +            gsub(/(?:^|[^_\\])#{Mx[:lnk_o]}(\S+?\.(?:png|jpg|gif)) .+?#{Mx[:lnk_c]}#{Mx[:url_o]}\S+?#{Mx[:url_c]}/,'    [ \1 ]'). #"[ #{dir.url.images_local}\/\\1 ]") +            gsub(/(?:^|[^_\\])#{Mx[:lnk_o]}(\S+?\.(?:png|jpg|gif)) .+?#{Mx[:lnk_c]}image/,'    [ \1 ]'). +            gsub(/(?:^|[^_\\])\{\s*\S+?\.(?:png|jpg|gif)\s+.+?"(.*?)"\s*\}\S+/,'[image: "\1"]') +          if dob.obj !~/(^#{Rx[:meta]}|#{Mx[:br_eof]}|#{Mx[:br_endnotes]})/ +            p_num='' +            #ocn +            if dob.is==:heading \ +            or dob.is==:para +              plaintext_structure(dob,p_num) +            elsif dob.is==:group \ +            or dob.is==:block \ +            or dob.is==:verse \ +            or dob.is==:code \ +            or dob.is==:table +              @plaintext[:body] << dob.obj + p_num << break_line +            elsif dob.is==:break +              sp=' ' +              ln='-' +              @plaintext[:body] <<=if dob.obj==Mx[:br_page] \ +              or dob.obj==Mx[:br_page_new] \ +              or dob.obj==Mx[:br_page_line] +                "#{break_line}#{ln*40}#{break_line*2}" +              elsif dob.obj ==Mx[:br_obj] +                "#{break_line}#{sp*20}*  *  *#{break_line*2}" +              end # following empty line (break_line) missing, fix +            end +            dob='' if (dob.obj =~/<a name="n\d+">/ \ +              and dob.obj =~/^(-\{{2}~\d+|<!e[:_]\d+!>)/) # -endnote +            if dob ## Clean Prepared Text +              dob.obj=dob.obj.gsub(/<!.+!>/,' '). +                gsub(/<:\S+>/,' ') +            end +          end +        end +        @plaintext +      end +      def publish(plaintext) +        divider='=' +        content=[] +        content << plaintext[:open] +        content << plaintext[:head] +        content << plaintext[:body] +        content << @@endnotes[:end] if @@endnotes_ +        content << "#{break_line}#{divider*@wrap_width}#{break_line}" +        content << plaintext[:metadata] +        content << "#{break_line}#{divider*@wrap_width}#{break_line}" if @md.stmp =~/\w+/ #not used? +        content << plaintext[:tail] +        outputfile=SiSU_Env::FileOp.new(@md).write_file.textile +        Txt_Output::Output.new.document(content,outputfile) +        @@endnotes={ para: [], end: [] } +      end +    end +  end +end +__END__ +#+END_SRC + +*** txt_textile_decorate.rb + +#+BEGIN_SRC ruby  :tangle "../lib/sisu/txt_textile_decorate.rb" +# <<sisu_document_header>> +module SiSU_Decorate_Txt_Textile +  def decorate +    def heading +      def inline +        def l0 +          'h1. ' +        end +        def l1 +          'h2. ' +        end +        def l2 +          'h3. ' +        end +        def l3 +          'h4. ' +        end +        def l4 +          'h5. ' +        end +        def l5 +          'h6. ' +        end +        self +      end +      self +    end +    def bold +      def open +        '*' +      end +      def close +        '*' +      end +      self +    end +    def italics +      def open +        '_' +      end +      def close +        '_' +      end +      self +    end +    def underscore +      def open +        '+' +      end +      def close +        '+' +      end +      self +    end +   #def emphasis +   #  def open +   #    '' +   #  end +   #  def close +   #    '' +   #  end +   #  self +   #end +    def cite +      def open +        '"' +      end +      def close +        '"' +      end +      self +    end +    def insert +      def open +        '' +      end +      def close +        '' +      end +      self +    end +    def strike +      def open +        '-' +      end +      def close +        '-' +      end +      self +    end +    def superscript +      def open +        '^' +      end +      def close +        '^' +      end +      self +    end +    def subscript +      def open +        '~' +      end +      def close +        '~' +      end +      self +    end +    def hilite +      def open +        '*' +      end +      def close +        '*' +      end +      self +    end +    def monospace +      def open +        '' +      end +      def close +        '' +      end +      self +    end +    self +  end +end +__END__ +#+END_SRC + +* txt_output.rb + +#+BEGIN_SRC ruby  :tangle "../lib/sisu/txt_output.rb" +# <<sisu_document_header>> +module Txt_Output +  class Output +    include SiSU_Param +    include SiSU_Env +    def document(content,outputfile) +      emptyline=0 +      content.each do |para|           # this is a hack +        if para.is_a?(Array) \ +        and para.length > 0 +          para.each do |line| +            if line +              line=line.gsub(/[ \t]+$/m,''). +                gsub(/^\A[ ]*\Z/m,'') +              (line=~/^\A\Z/) \ +              ? (emptyline+=1) +              : emptyline=0 +              if emptyline < 2         #remove additional empty lines +                outputfile.puts line +              end +            end +          end +        else outputfile.puts para      #unix plaintext # /^([*=-]|\.){5}/ +        end +      end +      outputfile.close +    end +  end +end +__END__ + +#+END_SRC + +* txt_read.rb + +#+BEGIN_SRC ruby  :tangle "../lib/sisu/txt_read.rb" +# <<sisu_document_header>> +module SiSU_Txt_Read +  require_relative 'se'                                 # se.rb +    include SiSU_Env +  def read_generic(opt,specific) +    begin +      env=SiSU_Env::InfoEnv.new(opt.fns) +      unless opt.act[:quiet][:set]==:on +        tool=(opt.act[:verbose][:set]==:on \ +        || opt.act[:verbose_plus][:set]==:on \ +        || opt.act[:maintenance][:set]==:on) \ +        ? "#{env.program.text_editor} #{specific[:output_path]}/#{specific[:output_file]}" +        : "[#{opt.f_pth[:lng_is]}] #{opt.fno}" +        (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], +            specific[:description], +            tool +          ).green_hi_blue +        : SiSU_Screen::Ansi.new( +            opt.act[:color_state][:set], +            specific[:description], +            tool +          ).green_title_hi +        if (opt.act[:verbose_plus][:set]==:on \ +        || opt.act[:maintenance][:set]==:on) +          SiSU_Screen::Ansi.new( +            opt.act[:color_state][:set], +            opt.fns, +            "#{specific[:output_path]}/#{specific[:output_file]}" +          ).flow +        end +      end +      @ao_array=SiSU_AO::Source.new(opt).get # ao file drawn here +      @wrap_width=if defined? md.make.plaintext_wrap \ +      and md.make.plaintext_wrap +        md.make.plaintext_wrap +      elsif defined? env.plaintext_wrap \ +      and env.plaintext_wrap +        env.plaintext_wrap +      else 78 +      end +      #wrap_width=(defined? md.make.plaintext_wrap) ? md.make.plaintext_wrap : 78 +    rescue +      SiSU_Errors::Rescued.new($!,$@,opt.selections.str,opt.fns).location do +        __LINE__.to_s + ':' + __FILE__ +      end +    ensure +    end +  end +end +__END__ +#+END_SRC + +* txt_shared.rb + +#+BEGIN_SRC ruby  :tangle "../lib/sisu/txt_shared.rb" +# <<sisu_document_header>> +module SiSU_TextUtils +  require_relative 'generic_parts'                      # generic_parts.rb +  class Wrap +    def initialize(para='',n_char_max=76,n_indent=0,n_hang=nil,post='') +      @para,@n_char_max,@n_indent,@post,=para,n_char_max,n_indent,post +      @n_char_max_extend = n_char_max +      @n_hang=n_hang ? n_hang : @n_indent +    end +    def break_line +      "\n" +    end +    def line_wrap +      space=' ' +      spaces_indent,spaces_hang="#{break_line}#{space*@n_indent}",space*@n_hang +      line=0 +      out=[] +      out[line]='' +      @para=@para.gsub(/<br>/,' \\ '). +        gsub(/#{Mx[:br_nl]}/,"\n\n") +      words=@para.scan(/\n\n|\s+\\\s+|<br>|\S+/m) +      while words != '' +        word=words.shift +        if not word +          out[line] unless out[line].empty? #check +          break +        elsif word =~/<br>/ +          word=nil +          out[line]=out[line].gsub(/<br>/,'') +          line=line +        elsif word =~/\n\n/ +          word="\n" +          @n_char_max_extend = @n_char_max +          line += 1 +        elsif (out[line].length + word.length) > (@n_char_max_extend - @n_indent) \ +        and out[line] =~/\S+/ +          @n_char_max_extend = @n_char_max +          out[line].squeeze!(' ') +          line += 1 +        end +        if word +          out[line]=if out[line] \ +          and out[line] !~/\S+$/m +            "#{out[line]}#{word}" +          elsif out[line] \ +          and out[line] =~/\S+/ +            "#{out[line]} #{word}" +          else "#{word.strip}" +          end +        end +        @oldword=word if word =~/\S+/ +      end +      post=(@post.empty?) \ +      ? '' +      : "\n" + (' '*@n_indent) +@post +      spaces_hang + out.join(spaces_indent) + post +    end +    def line_wrap_indent1 +      @n_indent,@n_hang=2,2 +      line_wrap +    end +    def line_wrap_endnote +      @n_indent,@n_hang=4,2 +      line_wrap +    end +    def array_wrap +      if @para.is_a?(Array) +        @arr=[] +        @para.each do |line| +          @arr << SiSU_TextUtils::Wrap.new(line,@n_char_max,@n_indent,@n_hang).line_wrap +        end +      end +      @arr +    end +    def no_wrap +      @para +    end +    def no_wrap_no_breaks +      @para.gsub(/\n/m,' ').gsub(/\s\s+/,' ') +    end +  end +  class HeaderScan +    def initialize(md,para) +      @md,@p=md,para +    end +    def extract(tag,tag_content,type,attrib) +      if dc_tag \ +      and dc_content +        [dc_tag,dc_content,{dc_tag=>dc_content}] +      else nil +      end +    end +    def header(tag,tag_content,type='',attrib='') #this will break stuff and must be tested thoroughly 20060825 +      @tag,@tag_content,@type,@attrib=tag,tag_content,type,attrib +      def label #element +        @tag +      end +      def type +        @type +      end +      def text +        @tag_content +      end +      def info  #element text +        @tag_content +      end +      def attribute +        @attrib +      end +      def element +        @tag +      end +      def attrib +        @attrib +      end +      def el +        @tag +      end +      self +    end +    def start_is_match +      case @p +      when /^#{Mx[:meta_o]}(title)#{Mx[:meta_c]}\s*(.+?)$/               then header($1,@md.title.full,'meta','dc') #dc 1 +      when /^#{Mx[:meta_o]}(creator|author)#{Mx[:meta_c]}\s*(.+?)$/      then header('creator',$2,'meta','dc')    #dc 2 +      when /^#{Mx[:meta_o]}(subject)#{Mx[:meta_c]}\s*(.+?)$/             then header($1,$2,'meta','dc')           #dc 3 +      when /^#{Mx[:meta_o]}(description)#{Mx[:meta_c]}\s*(.+?)$/         then header($1,$2,'meta','dc')           #dc 4 +      when /^#{Mx[:meta_o]}(publisher)#{Mx[:meta_c]}\s*(.+?)$/           then header($1,$2,'meta','dc')           #dc 5 +      when /^#{Mx[:meta_o]}(contributor)#{Mx[:meta_c]}\s*(.+?)$/         then header($1,$2,'meta','dc')           #dc 6 +      when /^#{Mx[:meta_o]}(date)#{Mx[:meta_c]}\s*(.+?)$/                then header($1,$2,'meta','dc')           #dc 7 +      when /^#{Mx[:meta_o]}(date\.created)#{Mx[:meta_c]}\s*(.+?)$/       then header($1,$2,'meta','extra') +      when /^#{Mx[:meta_o]}(date\.issued)#{Mx[:meta_c]}\s*(.+?)$/        then header($1,$2,'meta','extra') +      when /^#{Mx[:meta_o]}(date\.available)#{Mx[:meta_c]}\s*(.+?)$/     then header($1,$2,'meta','extra') +      when /^#{Mx[:meta_o]}(date\.valid)#{Mx[:meta_c]}\s*(.+?)$/         then header($1,$2,'meta','extra') +      when /^#{Mx[:meta_o]}(date\.modified)#{Mx[:meta_c]}\s*(.+?)$/      then header($1,$2,'meta','extra') +      when /^#{Mx[:meta_o]}(type)#{Mx[:meta_c]}\s*(.+?)$/                then header($1,$2,'meta','dc')           #dc 8 +      when /^#{Mx[:meta_o]}(format)#{Mx[:meta_c]}\s*(.+?)$/              then header($1,$2,'meta','dc')           #dc 9 +      when /^#{Mx[:meta_o]}(identifier)#{Mx[:meta_c]}\s*(.+?)$/          then header($1,$2,'meta','dc')           #dc 10 +      when /^#{Mx[:meta_o]}(source)#{Mx[:meta_c]}\s*(.+?)$/              then header($1,$2,'meta','dc')           #dc 11 +      when /^#{Mx[:meta_o]}(language)#{Mx[:meta_c]}\s*(.+?)$/            then header($1,$2,'meta','dc')           #dc 12 +      when /^#{Mx[:meta_o]}(relation)#{Mx[:meta_c]}\s*(.+?)$/            then header($1,$2,'meta','dc')           #dc 13 +      when /^#{Mx[:meta_o]}(coverage)#{Mx[:meta_c]}\s*(.+?)$/            then header($1,$2,'meta','dc')           #dc 14 +      when /^#{Mx[:meta_o]}(rights)#{Mx[:meta_c]}\s*(.+?)$/              then header($1,$2,'meta','dc')           #dc 15 +      when /^#{Mx[:meta_o]}(keywords)#{Mx[:meta_c]}\s*(.+?)$/            then header($1,$2,'meta','extra') +      when /^#{Mx[:meta_o]}(copyright)#{Mx[:meta_c]}\s*(.+?)$/           then header($1,$2,'meta','extra') +      when /^#{Mx[:meta_o]}(translator|translated_by)#{Mx[:meta_c]}\s*(.+?)$/   then header('translator',$2) +      when /^#{Mx[:meta_o]}(illustrator|illustrated_by)#{Mx[:meta_c]}\s*(.+?)$/ then header('illustrator',$2) +      when /^#{Mx[:meta_o]}(prepared_by)#{Mx[:meta_c]}\s*(.+?)$/         then header($1,$2,'meta','extra') +      when /^#{Mx[:meta_o]}(digitized_by)#{Mx[:meta_c]}\s*(.+?)$/        then header($1,$2,'meta','extra') +      when /^#{Mx[:meta_o]}(comments?)#{Mx[:meta_c]}\s*(.+?)$/           then header($1,$2,'meta','extra') +      when /^#{Mx[:meta_o]}(abstract)#{Mx[:meta_c]}\s*(.+?)$/            then header($1,$2,'meta','extra') +      when /^#{Mx[:meta_o]}(tags?)#{Mx[:meta_c]}\s*(.+?)$/               then header($1,$2,'meta','extra') +      when /^#{Mx[:meta_o]}(catalogue)#{Mx[:meta_c]}\s*(.+?)$/           then header($1,$2,'meta','extra') +      when /^#{Mx[:meta_o]}(class(?:ify)?_loc)#{Mx[:meta_c]}\s*(.+?)$/   then header('classify_loc',$2,'meta','extra') +      when /^#{Mx[:meta_o]}(class(?:ify)?_dewey)#{Mx[:meta_c]}\s*(.+?)$/ then header('classify_dewey',$2,'meta','extra') +      when /^#{Mx[:meta_o]}(class(?:ify)?_pg)#{Mx[:meta_c]}\s*(.+?)$/    then header('classify_pg',$2,'meta','extra') +      when /^#{Mx[:meta_o]}(class(?:ify)?_isbn)#{Mx[:meta_c]}\s*(.+?)$/  then header('classify_isbn',$2,'meta','extra') +      when /^#{Mx[:meta_o]}(toc|structure)#{Mx[:meta_c]}\s*(.+?)$/       then header('structure',$2,'process','instruct') +      when /^#{Mx[:meta_o]}(level|page|markup)#{Mx[:meta_c]}\s*(.+?)$/   then header('markup',$2,'process','instruct') +      when /^#{Mx[:meta_o]}(bold)#{Mx[:meta_c]}\s*(.+?)$/                then header($1,$2,'process','instruct') +      when /^#{Mx[:meta_o]}(italics|itali[sz]e)#{Mx[:meta_c]}\s*(.+?)$/  then header('italicize',$2,'process','instruct') +      when /^#{Mx[:meta_o]}(vocabulary|wordlist)#{Mx[:meta_c]}\s*(.+?)$/ then header('vocabulary',$2,'process','instruct') +      when /^#{Mx[:meta_o]}(css|stylesheet)#{Mx[:meta_c]}\s*(.+?)$/      then header('css',$2,'process','instruct') +      when /^#{Mx[:meta_o]}(links)#{Mx[:meta_c]}\s*(.+?)$/               then header($1,$2,'process','instruct') +      when /^#{Mx[:meta_o]}(prefix)#{Mx[:meta_c]}\s*(.+?)$/              then header($1,$2,'process','instruct') #add a & b +      when /^#{Mx[:meta_o]}(suffix)#{Mx[:meta_c]}\s*(.+?)$/              then header($1,$2,'process','instruct') +      when /^#{Mx[:meta_o]}(information)#{Mx[:meta_c]}\s*(.+?)$/         then header($1,$2,'process','instruct') +      when /^#{Mx[:meta_o]}(contact)#{Mx[:meta_c]}\s*(.+?)$/             then header($1,$2,'process','instruct') +      when /^#{Mx[:meta_o]}(rcs|cvs)#{Mx[:meta_c]}\s*(.+?)$/             then header('version',$2,'process','instruct') +      else nil +      end +    end +    def dublin +      if @p =~/^#{Mx[:meta_o]}\S+?#{Mx[:meta_c]}/ +        start_is_match +      else nil +      end +    end +    def meta +      if @p =~/^#{Mx[:meta_o]}\S+?#{Mx[:meta_c]}/ +        start_is_match +      else nil +      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 +    txt + +  - 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 diff --git a/org/utils.org b/org/utils.org new file mode 100644 index 00000000..e709bcfe --- /dev/null +++ b/org/utils.org @@ -0,0 +1,857 @@ +-*- mode: org -*- +#+TITLE:       sisu utils +#+DESCRIPTION: documents - structuring, various output representations & search +#+FILETAGS:    :sisu:utils: +#+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 + +* utils +** utils.rb + +#+BEGIN_SRC ruby  :tangle "../lib/sisu/utils.rb" +# <<sisu_document_header>> +module SiSU_Utils +  class CodeMarker +    def initialize(line,file,color=:red) +      @line,@file,@color=line.to_s,file,color +    end +    def ansi(color=nil) +      @color=color ? color : @color +      c={} +      c[:on]=case @color +      when :red         then ANSI_C[:red] +      when :green       then ANSI_C[:green] +      when :yellow      then ANSI_C[:yellow] +      when :blue        then ANSI_C[:blue] +      when :fuchsia     then ANSI_C[:fuchsia] +      when :cyan        then ANSI_C[:cyan] +      when :inv_red     then ANSI_C[:inv_red] +      when :inv_green   then ANSI_C[:inv_green] +      when :inv_yellow  then ANSI_C[:inv_yellow] +      when :inv_blue    then ANSI_C[:inv_blue] +      when :inv_fuchsia then ANSI_C[:inv_fuchsia] +      when :inv_cyan    then ANSI_C[:inv_cyan] +      when :b_red       then ANSI_C[:b_red] +      when :b_green     then ANSI_C[:b_green] +      when :b_yellow    then ANSI_C[:b_yellow] +      when :b_blue      then ANSI_C[:b_blue] +      when :b_fuchsia   then ANSI_C[:b_fuchsia] +      when :b_cyan      then ANSI_C[:b_cyan] +      else                   ANSI_C[:red] +      end +      c[:off]= ANSI_C[:off] +      #ansi_color + @line.to_s + ansi_color_off + ' ' + @file.gsub(/([^\/]+$)/,"#{ansi_color}\\1#{ansi_color_off}") +      c +    end +    def var(v,x) +      h={ c: nil, m: '' } +      if v.is_a?(Hash) +        h[:c] = (defined? v[:c]) ? v[:c] : '' +        h[:m] = (defined? v[:m]) ? v[:m] : '' +      elsif (v.is_a?(Symbol) \ +      and x.is_a?(String)) +        if v.is_a?(Symbol) +          h[:c]=v +        elsif v.is_a?(String) +          h[:m]=v +        end +        if x.is_a?(String) +          h[:m]=x +        end +      elsif (v.is_a?(Symbol) \ +      or v.is_a?(String)) +        if v.is_a?(Symbol) +          h[:c]=v +        elsif v.is_a?(String) +          h[:m]=v +        end +      end +      h[:c] = (defined? h[:c]) ? h[:c] : '' +      h[:m] = (defined? h[:m]) ? h[:m] : '' +      h[:c]=ansi(h[:c]) +      h[:m]=message(h[:m]) +      h +    end +    def message(msg='') +      @message=(msg.nil? || msg.empty?) \ +      ? '' +      : ' ' + msg +    end +    def set(v=nil,x=nil) +      v=var(v,x) +      file,path=File.basename(@file),File.dirname(@file) +      v[:c][:on] + @line + v[:c][:off] + ' ' \ +      + path + '/' \ +      + "#{v[:c][:on]}#{file}#{v[:c][:off]}" \ +      + v[:m] +    end +    def mark(v=nil,x=nil) +      puts set(v,x) +    end +    def tell(v=nil,x=nil) +      puts set(v,x) +    end +    def report(v=nil,x=nil) +      puts set(v,x) +    end +    def ok(v=nil,x=nil) +      if (v.is_a?(Symbol) \ +      and x.is_a?(String)) +        x= '*OK* ' + x +      elsif v.is_a?(String) +        v='*OK* ' + v +        x=nil +      else +        v,x='*OK*',nil +      end +      puts set(v,x) +    end +    def warn(v=nil,x=nil) +      if (v.is_a?(Symbol) \ +      and x.is_a?(String)) +        x="\n  " + '*WARN* ' + x +      elsif v.is_a?(String) +        v="\n  " + '*WARN* ' + v +        x=nil +      else +        v,x='*WARN*',nil +      end +      puts set(v,x) +    end +    def error(v=nil,x=nil) +      if (v.is_a?(Symbol) \ +      and x.is_a?(String)) +        x="\n  " + '*ERROR* ' + x +      elsif v.is_a?(String) +        v="\n  " + '*ERROR* ' + v +        x=nil +      else +        v,x='*ERROR*',nil +      end +      STDERR.puts set(v,x) +    end +  end +  class Path +    def initialize(dir=Dir.pwd) +      @dir=dir +    end +    def base_markup(call_path=nil) +      call_path = call_path \ +      ? call_path \ +      : Dir.pwd +      (/(\S+?)(?:\/(?:#{Px[:lng_lst_rgx]}))?$/).match(call_path)[1] +    end +    def base_markup_stub +      m=/.+\/(?:src\/)?(\S+)/im +      base_markup[m,1] +    end +    def image_src +      if base_markup =~/sisupod\/doc[\/]?$/ +        base_markup.gsub(/\/doc[\/]?$/,'/image') +      elsif FileTest.directory?("#{base_markup}/_sisu/image") +        "#{base_markup}/_sisu/image" +      end +    end +    def bmd +      base_markup +    end +  end +end +__END__ +SiSU_Utils::CodeMarker.new(__LINE__,__FILE__,:green).mark({ m: %{ +  code: #{@@flag[:code]}, <-- close "#{t_o}" +}}) +SiSU_Utils::CodeMarker.new(__LINE__,__FILE__).mark({ m: %{ +  code: #{@@flag['code']}, <-- close "#{t_o}" +}, c: :green}) +SiSU_Utils::CodeMarker.new(__LINE__,__FILE__,:green).mark({ m: %{ +  code: #{@@flag['code']}, open --> "#{t_o}" +}}) if t_o=~/^```/m +SiSU_Utils::CodeMarker.new(__LINE__,__FILE__,:green).mark(%{ code: #{@@flag['code']}, open --> "#{t_o}" }) \ +if t_o=~/^```/m +SiSU_Utils::CodeMarker.new(__LINE__,__FILE__,:green).mark("open -->") +SiSU_Utils::CodeMarker.new(__LINE__,__FILE__,:fuchsia).mark("open -->") +SiSU_Utils::CodeMarker.new(__LINE__,__FILE__).mark("open -->",:green) +SiSU_Utils::CodeMarker.new(__LINE__,__FILE__).mark(:green,"open -->") +SiSU_Utils::CodeMarker.new(__LINE__,__FILE__).mark("open -->") +SiSU_Utils::CodeMarker.new(__LINE__,__FILE__).mark(:green) +SiSU_Utils::CodeMarker.new(__LINE__,__FILE__,:green).mark +SiSU_Utils::CodeMarker.new(__LINE__,__FILE__,:green).mark("open -->") +SiSU_Utils::CodeMarker.new(__LINE__,__FILE__).mark('open -->',:green) +SiSU_Utils::CodeMarker.new(__LINE__,__FILE__,:red).mark +puts SiSU_Utils::CodeMarker.new(__LINE__,__FILE__,:red).set +puts SiSU_Utils::CodeMarker.new(__LINE__,__FILE__).set('',:green) +puts SiSU_Utils::CodeMarker.new(__LINE__,__FILE__).set('',:fuchsia) +puts ANSI_C[:red] + __LINE__.to_s + ANSI_C[:off] + ' ' + __FILE__ +puts "#{ANSI_C[:red]} #{__LINE__.to_s} #{ANSI_C[:off]} #{__FILE__}" +puts ANSI_C[:fuchsia] + __LINE__.to_s + ANSI_C[:off] + ' ' + __FILE__.gsub(/([^\/]+$)/,"#{ANSI_C[:fuchsia]}\\1#{ANSI_C[:off]}") +puts ANSI_C[:red] + __LINE__.to_s + ANSI_C[:off] + ' ' + __FILE__.gsub(/([^\/]+$)/,"#{ANSI_C[:red]}\\1#{ANSI_C[:off]}") +#+END_SRC + +** utils_spell.rb + +#+BEGIN_SRC ruby  :tangle "../lib/sisu/utils_spell.rb" +# <<sisu_document_header>> +module SiSU_SpellUtility +  class Spell +    def initialize(input,filesrc,flg) +      @flg=flg +      @filename, @filetype = /(.+?)(\.\w\w\w0$)/.match(filesrc)[1,2] #.gsub(/\.\w\w\w0$/, "") +      @input=input +      @allwords=[] +      puts @filename +      @speller='aspell' # 'ispell' +      @dictionary='british' +      @lang='en_GB' +    end +    def check +      @input.each do |data| +        data=data.gsub(/(https?|www|ftp|gopher|png|jpg|gif|html|htm)\S+/i,' '). +          gsub(/( |#{Mx[:nbsp]})/i,' '). +          gsub(/<\/?(table|tr|td|b|p|href).*?>/i,' '). +          gsub(/(<==.+|<:\S+>|<!.+?!>|^@\S+?:.+|\{\{\{|~)/,' '). +          gsub(/(["|<>)(\n'`.;&_-]|\=)/,' '). +          gsub(/\b(altExternal| +            target|externalimg| +            srcimagebext| +            img|src|toc|pdf| +            cd|org| +            helvetica|roman +            )\b/i,' '). +          gsub(/EOF/,'') +        @words=data.scan(/\S+/) +        @words.each { |y| @allwords << y } +      end +      @allwords=@allwords.uniq +      if @flg =~ /S/ +        File.open('/home/ralph/spell_error','a+') do |file| #fix +          file.puts %{\n\n[ #{@filename} ]} +        end +        @allwords.each { |y| puts y.inspect; system(%{cat #{y} | /usr/bin/#{@speller} -l -d #{@dictionary} >> ~/spell_error })} +      else +        @allwords.each { |y| sp=%x{echo #{y}|#{@speller} -l }; puts sp unless sp.empty?} +      end +    end +  end +end +__END__ +#+END_SRC + +** utils_response.rb + +#+BEGIN_SRC ruby  :tangle "../lib/sisu/utils_response.rb" +# <<sisu_document_header>> +module SiSU_Response +  def available_selections_ +    %{'yes', 'no', 'quit' or 'exit'; [ynqx]} +  end +  def response?(ask) +    response='redo' +    print ask + %{ [#{available_selections_}]: } +    response=File.new('/dev/tty').gets.strip +    case response +    when /^(?:y|yes)$/          then true +    when /^(?:n|no)$/           then false +    when /^(?:[qx]|quit|exit)$/ then exit +    else puts %{[please type: #{available_selections_}]} +      response?(ask) +    end +  end +  def query +    def selections_available_(selections=:strict) +      short_options=(selections == :strict) ? '' : '; [ynqx]' +      %{'yes', 'no', 'quit' or 'exit'#{short_options}} +    end +    def selection_options +      def response_strict(resp) +        case resp +        when /^(?:yes)$/          then true +        when /^(?:no)$/           then false +        when /^(?:quit|exit)$/    then exit +        else +          puts %{response was: #{resp}} +          puts %{[please type to select: #{selections_available_(:strict)}]} +          answer?('',:strict) +        end +      end +      def response_short(resp) +        case resp +        when /^(?:y|yes)$/          then true +        when /^(?:n|no)$/           then false +        when /^(?:[qx]|quit|exit)$/ then exit +        else +          puts %{response was: #{resp}} +          puts %{[please type to select: #{selections_available_(:short)}]} +          answer?('',:short) +        end +      end +      self +    end +    def answer?(ask,selections=:strict) +      resp='redo' +      print ask + %{PROCEED? [#{selections_available_(selections)}]: } +      resp=File.new('/dev/tty').gets.strip +      (selections==:strict) \ +      ? selection_options.response_strict(resp) +      : selection_options.response_short(resp) +    end +    self +  end +end +__END__ +#+END_SRC + +** utils_composite.rb + +#+BEGIN_SRC ruby  :tangle "../lib/sisu/utils_composite.rb" +# <<sisu_document_header>> +module SiSU_Composite_Doc_Utils +  def inserts_array(loadfilename) +    IO.readlines(loadfilename,'') +  end +  def insert_filename?(para) +    if para =~ /^<<\s+((?:https?|file):\/\/\S+?\.ss[it])$/ # and NetTest +      url($1.strip) +    elsif para =~/^<<\s*(\S+?\.ss[it])$/ +      $1.strip +    end +  end +  def extract_filenames(loadfilename,file_names_arr) +    file_names_arr << loadfilename +    ssi_files=[] +    if loadfilename =~/\S+?\.ss[im]$/ +      inserts_array(loadfilename).each do |para| +        filen=insert_filename?(para) +        file_names_arr << filen +        if filen =~/\S+?\.ssi$/ +          ssi_files << filen +        end +      end +    end +    ssi_files.each do |fn| +      extract_filenames(fn,file_names_arr) +    end +    file_names_arr.flatten.compact.uniq.sort +  end +  def composite_and_imported_filenames_array(loadfilename) +    file_names_arr=[] +    begin +      if FileTest.file?(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 +          file_names_arr=extract_filenames(loadfilename,file_names_arr) +        end +      end +      if (@opt.act[:verbose_plus][:set]==:on \ +      || @opt.act[:maintenance][:set]==:on) +        p file_names_arr ;p file_names_arr.length +      end +      file_names_arr +    rescue +      SiSU_Errors::Rescued.new($!,$@,@opt.selections.str,@opt.fns).location do +        __LINE__.to_s + ':' + __FILE__ +      end +    ensure +    end +  end +end +__END__ +#+END_SRC + +** utils_screen_text_color.rb + +#+BEGIN_SRC ruby  :tangle "../lib/sisu/utils_screen_text_color.rb" +# <<sisu_document_header>> +module SiSU_Screen +  class Color +    attr_accessor :off,:marker,:bold,:underline,:invert,:darkgrey_hi,:grey_hi,:pink_hi,:fuchsia_hi,:red_hi,:orange_hi,:yellow_hi,:brown_hi,:lightgreen_hi,:green_hi,:cyan_hi,:blue_hi,:navy_hi,:white,:white_bold,:grey,:pink,:fuchsia,:ruby,:red,:orange,:yellow,:brown,:green,:darkgreen,:cyan,:blue,:navy,:black +    def initialize(&block) +      instance_eval &block +    end +  end +  class Ansi < Color +    attr_reader :cX +    def initialize(color_state,*txt) +      @color_state,@txt=color_state,txt +      @color_instruct=txt[0] +      @cX=@@cX=if color_state==:on +        Color.new do +          self.off=self.white=self.white_bold=self.marker=self.bold=self.underline=self.invert=self.darkgrey_hi=self.grey_hi=self.pink_hi=self.fuchsia_hi=self.red_hi=self.orange_hi=self.yellow_hi=self.brown_hi=self.lightgreen_hi=self.green_hi=self.cyan_hi=self.blue_hi=self.navy_hi=self.grey=self.pink=self.fuchsia=self.ruby=self.red=self.orange=self.yellow=self.brown=self.green=self.darkgreen=self.cyan=self.blue=self.navy=self.black='' +        end +      else                                                                       #default set to colors on +        Color.new do +          self.off           = "\033[0m" +          self.white         = "\033[37m" +          self.white_bold    = "\033[1m" +          self.marker        = "\033[42m" +          self.bold          = "\033[1m" +          self.underline     = "\033[4m" +          self.invert        = "\033[7m" +          self.darkgrey_hi   = "\033[100m" +          self.grey_hi       = "\033[47m" +          self.pink_hi       = "\033[105m" +          self.fuchsia_hi    = "\033[45m" +          self.red_hi        = "\033[41m" +          self.orange_hi     = "\033[101m" +          self.yellow_hi     = "\033[103m" +          self.brown_hi      = "\033[43m" +          self.lightgreen_hi = "\033[102m" +          self.green_hi      = "\033[42m" +          self.cyan_hi       = "\033[106m" +          self.blue_hi       = "\033[104m" +          self.navy_hi       = "\033[44m" +          self.grey          = "\033[90m" +          self.pink          = "\033[95m" +          self.fuchsia       = "\033[35m" +          self.ruby          = "\033[31m" +          self.red           = "\033[91m" #check +          self.orange        = "\033[91m" +          self.yellow        = "\033[93m" +          self.brown         = "\033[33m" +          self.green         = "\033[92m" +          self.darkgreen     = "\033[32m" +          self.cyan          = "\033[36m" +          self.blue          = "\033[94m" +          self.navy          = "\033[34m" +          self.black         = "\033[30m" +        end +      end +    end +    def colors +      0.upto(109) {|i| print "\033[#{i}m 33[#{i}m \033[m"} +      puts '' +    end +    def color +      case @color_instruct +      when /invert/        then @cX.invert +      when /darkgrey_hi/   then @cX.darkgrey_hi +      when /grey_hi/       then @cX.grey_hi +      when /pink_hi/       then @cX.pink_hi +      when /fuchsia_hi/    then @cX.fuchsia_hi +      when /red_hi/        then @cX.red_hi +      when /orange_hi/     then @cX.orange_hi +      when /yellow_hi/     then @cX.yellow_hi +      when /brown_hi/      then @cX.brown_hi +      when /lightgreen_hi/ then @cX.lightgreen_hi +      when /green_hi/      then @cX.green_hi +      when /cyan_hi/       then @cX.cyan_hi +      when /blue_hi/       then @cX.blue_hi +      when /navy_hi/       then @cX.navy_hi +      when /white/         then @cX.white +      when /grey/          then @cX.grey +      when /pink/          then @cX.pink +      when /fuchsia/       then @cX.fuchsia +      when /ruby/          then @cX.ruby +      when /red/           then @cX.red +      when /orange/        then @cX.orange +      when /yellow/        then @cX.yellow +      when /brown/         then @cX.brown +      when /green/         then @cX.green +      when /darkgreen/     then @cX.darkgreen +      when /cyan/          then @cX.cyan +      when /blue/          then @cX.blue +      when /navy/          then @cX.navy +      when /close/         then @cX.off +      when /off/           then @cX.off +      end +    end +    def colorize +      case @color_instruct +      when /invert/        then puts "#{@cX.invert}#{@txt[1]}#{@cX.off} #{@cX.blue}#{@txt[2]}#{@cX.off} #{@cX.grey}#{@txt[3]}#{@cX.off}" +      when /darkgrey_hi/   then puts "#{@cX.darkgrey_hi}#{@txt[1]}#{@cX.off} #{@cX.blue}#{@txt[2]}#{@cX.off} #{@cX.grey}#{@txt[3]}#{@cX.off}" +      when /grey_hi/       then puts "#{@cX.grey_hi}#{@txt[1]}#{@cX.off} #{@cX.blue}#{@txt[2]}#{@cX.off} #{@cX.grey}#{@txt[3]}#{@cX.off}" +      when /pink_hi/       then puts "#{@cX.pink_hi}#{@txt[1]}#{@cX.off} #{@cX.blue}#{@txt[2]}#{@cX.off} #{@cX.grey}#{@txt[3]}#{@cX.off}" +      when /fuchsia_hi/    then puts "#{@cX.fuchsia_hi}#{@txt[1]}#{@cX.off} #{@cX.blue}#{@txt[2]}#{@cX.off} #{@cX.grey}#{@txt[3]}#{@cX.off}" +      when /red_hi/        then puts "#{@cX.red_hi}#{@txt[1]}#{@cX.off} #{@cX.blue}#{@txt[2]}#{@cX.off} #{@cX.grey}#{@txt[3]}#{@cX.off}" +      when /orange_hi/     then puts "#{@cX.orange_hi}#{@txt[1]}#{@cX.off} #{@cX.blue}#{@txt[2]}#{@cX.off} #{@cX.grey}#{@txt[3]}#{@cX.off}" +      when /yellow_hi/     then puts "#{@cX.yellow_hi}#{@txt[1]}#{@cX.off} #{@cX.blue}#{@txt[2]}#{@cX.off} #{@cX.grey}#{@txt[3]}#{@cX.off}" +      when /brown_hi/      then puts "#{@cX.brown_hi}#{@txt[1]}#{@cX.off} #{@cX.blue}#{@txt[2]}#{@cX.off} #{@cX.grey}#{@txt[3]}#{@cX.off}" +      when /lightgreen_hi/ then puts "#{@cX.lightgreen_hi}#{@txt[1]}#{@cX.off} #{@cX.blue}#{@txt[2]}#{@cX.off} #{@cX.grey}#{@txt[3]}#{@cX.off}" +      when /green_hi/      then puts "#{@cX.green_hi}#{@txt[1]}#{@cX.off} #{@cX.blue}#{@txt[2]}#{@cX.off} #{@cX.grey}#{@txt[3]}#{@cX.off}" +      when /cyan_hi/       then puts "#{@cX.cyan_hi}#{@txt[1]}#{@cX.off} #{@cX.blue}#{@txt[2]}#{@cX.off} #{@cX.grey}#{@txt[3]}#{@cX.off}" +      when /blue_hi/       then puts "#{@cX.blue_hi}#{@txt[1]}#{@cX.off} #{@cX.blue}#{@txt[2]}#{@cX.off} #{@cX.grey}#{@txt[3]}#{@cX.off}" +      when /navy_hi/       then puts "#{@cX.navy_hi}#{@txt[1]}#{@cX.off} #{@cX.blue}#{@txt[2]}#{@cX.off} #{@cX.grey}#{@txt[3]}#{@cX.off}" +      when /bold/          then puts "#{@cX.bold}#{@txt[1]}#{@cX.off} #{@cX.grey}#{@txt[2]}#{@cX.off}" +      when /white/         then puts "#{@cX.off}#{@txt[1]} #{@txt[2]}" +      when /grey/          then puts "#{@cX.grey}#{@txt[1]}#{@cX.off} #{@cX.grey}#{@txt[2]}#{@cX.off}" +      when /pink/          then puts "#{@cX.pink}#{@txt[1]}#{@cX.off} #{@cX.grey}#{@txt[2]}#{@cX.off}" +      when /fuchsia/       then puts "#{@cX.fuchsia}#{@txt[1]}#{@cX.off} #{@cX.grey}#{@txt[2]}#{@cX.off}" +      when /ruby/          then puts "#{@cX.ruby}#{@txt[1]}#{@cX.off} #{@cX.grey}#{@txt[2]}#{@cX.off}" +      when /red/           then puts "#{@cX.red}#{@txt[1]}#{@cX.off} #{@cX.grey}#{@txt[2]}#{@cX.off}" +      when /orange/        then puts "#{@cX.orange}#{@txt[1]}#{@cX.off} #{@cX.grey}#{@txt[2]}#{@cX.off}" +      when /yellow/        then puts "#{@cX.yellow}#{@txt[1]}#{@cX.off} #{@cX.grey}#{@txt[2]}#{@cX.off}" +      when /brown/         then puts "#{@cX.brown}#{@txt[1]}#{@cX.off} #{@cX.grey}#{@txt[2]}#{@cX.off}" +      when /green/         then puts "#{@cX.green}#{@txt[1]}#{@cX.off} #{@cX.grey}#{@txt[2]}#{@cX.off}" +      when /darkgreen/     then puts "#{@cX.darkgreen}#{@txt[1]}#{@cX.off} #{@cX.grey}#{@txt[2]}#{@cX.off}" +      when /cyan/          then puts "#{@cX.cyan}#{@txt[1]}#{@cX.off} #{@cX.grey}#{@txt[2]}#{@cX.off}" +      when /blue/          then puts "#{@cX.blue}#{@txt[1]}#{@cX.off} #{@cX.grey}#{@txt[2]}#{@cX.off}" +      when /navy/          then puts "#{@cX.navy}#{@txt[1]}#{@cX.off} #{@cX.grey}#{@txt[2]}#{@cX.off}" +      end +    end +    def sourcename(sourcefilename) +      @sourcefilename=sourcefilename +    end +    def basename(sourcefilename) +      @basename=sourcefilename.sub(/\.(?:(?:-|ssm\.)?sst|ssm)$/,'') +    end +    def sisu +    end +    def rescue +      STDERR.puts %{\t   #{@cX.orange}Rescued#{@cX.off} #{@cX.grey}#{yield if block_given?}\n\t   An#{@cX.off} #{@cX.fuchsia}ERROR#{@cX.off} #{@cX.grey}occurred, message:#{@cX.off} #{@cX.fuchsia}#{@txt[0]}#{@cX.off} #{@cX.grey}#{@txt[1]}#{@cX.off} #{@cX.brown}#{@txt[2]}#{@cX.off}} +    end +    def warn +      STDERR.puts "\t  #{@cX.brown}#{@txt[0]}#{@cX.off} #{@cX.grey}#{@txt[1]}#{@cX.off}" +    end +    def error +      STDERR.puts "\t  #{@cX.fuchsia}#{@txt[0]}#{@cX.off} #{@cX.brown}#{@txt[1]}#{@cX.off}" +    end +    def error2 +      STDERR.puts "\t  #{@cX.grey}#{@txt[0]}#{@cX.off} #{@cX.fuchsia}#{@txt[1]}#{@cX.off} #{@cX.grey}#{@txt[2]}#{@cX.off}" +    end +    def version +      puts "#{@cX.blue_hi}#{@txt[0]} #{@txt[1]}#{@cX.off} #{@cX.grey} (#{@txt[3]} [#{@txt[2]}])#{@txt[4]} &#{@cX.off} #{@cX.ruby}Ruby#{@cX.off} #{@cX.grey}(#{@txt[5]})#{@cX.off}\n" +    end +    def html3numbers +      puts %{\t#{@cX.green}#{@txt[0]}#{@cX.off} #{@cX.cyan}files processed#{@cX.off}. } + +        %{#{@cX.grey}} + +        %{scroll only: #{@txt[1]}, seg only: #{@txt[2]},} + +        %{#{@cX.off} } + +        %{#{@cX.cyan}joint scroll & seg: #{@txt[3]},#{@cX.off}} + +        %{#{@cX.grey} } + +        %{nav only: #{@txt[4]}} + +        %{#{@cX.off}} +    end +    def html2numbers +      puts %{\t#{@cX.green}#{@txt[0]}#{@cX.off} #{@cX.cyan}files processed#{@cX.off}. } + +        %{#{@cX.grey}} + +        %{scroll only: #{@txt[1]},} + +        %{#{@cX.off} } + +        %{#{@cX.cyan}seg only: #{@txt[2]},#{@cX.off}} + +        %{#{@cX.grey} } + +        %{joint scroll & seg: #{@txt[3]}, nav only: #{@n_files_nav}} + +        %{#{@cX.off}} +    end +    def html1numbers +      puts %{\t#{@cX.green}#{@txt[0]}#{@cX.off} #{@cX.cyan}files processed#{@cX.off}. } + +        %{#{@cX.cyan}scroll only: #{@txt[1]},#{@cX.off}} + +        %{#{@cX.grey} } + +        %{seg only: #{@txt[2]}, } + +        %{joint scroll & seg: #{@txt[3]}, nav only: #{@n_files_nav}} + +        %{#{@cX.off}} +    end +    def html0_numbers +      puts %{\t#{@cX.ruby}#{@txt[0]} files processed#{@cX.off}. } + +        %{#{@cX.grey}} + +        %{scroll only: #{@txt[1]}, seg only: #{@txt[2]}, joint scroll & seg: #{@txt[3]},} + +        %{#{@cX.off} } + +        %{#{@cX.cyan}nav only: #{@txt[4]}#{@cX.off}.} +    end +    def grey +      puts "#{@cX.grey}#{@txt[0]}#{@cX.off} #{@cX.cyan}#{@txt[1]}#{@cX.off}" +    end +    def txt_white +      puts "\t#{@cX.white}#{@txt[0]}#{@cX.off} #{@cX.white}#{@txt[1]}#{@cX.off}" +    end +    def txt_grey +      puts "\t#{@cX.grey}#{@txt[0]}#{@cX.off} #{@cX.cyan}#{@txt[1]}#{@cX.off}" +    end +    def txt_cyan +      puts "\t#{@cX.cyan}#{@txt[0]}#{@cX.off} #{@cX.grey}#{@txt[1]}#{@cX.off}" +    end +    def txt_blue +      puts "\t#{@cX.blue}#{@txt[0]}#{@cX.off} #{@cX.grey}#{@txt[1]}#{@cX.off}" +    end +    def txt_red +      puts "\t#{@cX.red}#{@txt[0]}#{@cX.off} #{@cX.cyan}#{@txt[1]}#{@cX.off}" +    end +    def txt_green +      puts "\t#{@cX.green}#{@txt[0]}#{@cX.off} #{@cX.grey}#{@txt[1]}#{@cX.off}" +    end +    def url #clean +      blue +    end +    def result +      puts "\t#{@cX.grey}#{@txt[0]}#{@cX.off} #{@cX.green}#{@txt[1]}#{@cX.off} #{@cX.blue}#{@txt[2]}#{@cX.off}" +    end +    def maintenance +      puts "\t#{@cX.grey}#{@txt[0]}#{@cX.off} #{@cX.brown}#{@txt[1]}#{@cX.off} #{@cX.grey}#{@txt[2]}#{@cX.off}" +    end +    def instruct +      puts %{\t  #{@cX.grey}#{@txt[0]}#{@cX.off} #{@cX.cyan}#{@txt[1]}#{@cX.off} #{@cX.grey}#{@txt[2]}#{@cX.off} #{@cX.cyan}#{@txt[3]}#{@cX.off} #{@cX.grey}#{@txt[4]}#{@cX.off} "#{@cX.brown}#{@f}#{@cX.off}"} +    end +    def grey_open +      print @cX.grey +    end +    def p_off +      print @cX.off +    end +    def p_close +      print @cX.off +    end +    def flow +      puts %{\t#{@cX.grey}#{@txt[0]}#{@cX.off} #{@cX.ruby}->#{@cX.off}\n\t  #{@cX.blue}#{@txt[1]}#{@cX.off}} +    end +    def output +      puts %{\t#{@cX.grey}#{@txt[0]}#{@cX.off} #{@cX.ruby}->#{@cX.off}\n\t  #{@cX.blue}#{@txt[1]}#{@cX.off}} +    end +    def generic +      puts %{\t#{@cX.navy}#{@txt[0]} #{@txt[1]}#{@cX.off}. } +    end +    def files_processed +      puts %{\t#{@cX.green}#{@txt[0]}#{@cX.off} #{@cX.grey}#{@txt[1]}#{@cX.off}} +    end +    def print_blue +      print "#{@cX.blue}#{@txt[0]} #{@txt[1]}#{@cX.off}" +    end +    def puts_blue +      puts "#{@cX.blue}#{@txt[0]} #{@txt[1]}#{@cX.off}" +    end +    def print_brown +      print "#{@cX.brown}#{@txt[0]}#{@cX.off}" +    end +    def blue_tab +      print  "\t#{@cX.blue}#{@txt[0]}#{@cX.off}\n" +    end +    def print_grey +      print "#{@cX.grey}#{@txt[0]} #{@txt[1]}#{@cX.off}" +    end +    def puts_grey +      puts "#{@cX.grey}#{@txt[0]} #{@txt[1]}#{@cX.off}" +    end +    def puts_brown +      puts "#{@cX.brown}#{@txt[0]} #{@txt[1]}#{@cX.off}" +    end +    def grey_tab +      print "\t#{@cX.grey}#{@txt[0]}#{@cX.off}\n" +    end +    def green_title +      puts %{#{@cX.green}#{@txt[0]}#{@cX.off} #{@cX.grey}#{@txt[1]}#{@cX.off}} +    end +    def green_title_hi +      puts %{#{@cX.green_hi}#{@cX.black}#{@txt[0]}#{@cX.off*2} #{@cX.grey}#{@txt[1]}#{@cX.off}} +    end +    def green_hi_blue +      puts %{#{@cX.green_hi}#{@cX.black}#{@txt[0]}#{@cX.off*2} #{@cX.blue}#{@txt[1]}#{@cX.off}} +    end +    def blue_title_hi +      puts %{#{@cX.blue_hi}#{@txt[0]}#{@cX.off*2} #{@cX.blue}#{@txt[1]}#{@cX.off}} +    end +    def grey_title_hi +      puts %{#{@cX.grey_hi}#{@cX.black}#{@txt[0]}#{@cX.off*2} #{@cX.blue}#{@txt[1]}#{@cX.off}} +    end +    def grey_title_grey_blue +      puts %{#{@cX.grey_hi}#{@cX.black}#{@txt[0]}#{@cX.off*2} #{@cX.grey}#{@txt[1]}#{@cX.off} #{@cX.blue}#{@txt[2]}#{@cX.off}} +    end +    def dark_grey_title_hi +      puts %{#{@cX.darkgrey_hi}#{@cX.black}#{@txt[0]}#{@cX.off*2} #{@cX.blue}#{@txt[1]}#{@cX.off}} +    end +    def cyan_title_hi +      puts %{#{@cX.cyan_hi}#{@cX.black}#{@txt[0]}#{@cX.off*2} #{@cX.blue}#{@txt[1]}#{@cX.off}} +    end +    def cyan_hi_blue +      puts %{#{@cX.cyan_hi}#{@cX.black}#{@txt[0]}#{@cX.off*2} #{@cX.blue}#{@txt[1]}#{@cX.off}} +    end +    def dbi_title +      puts %{#{@cX.blue_hi}#{@cX.black}#{@txt[0]}#{@cX.off*2} #{@cX.cyan}#{@cX.grey}#{@txt[1]}#{@cX.off*2} #{@cX.green}#{@txt[2]}#{@cX.off}} +    end +    def yellow_title_hi +      puts %{#{@cX.yellow_hi}#{@cX.black}#{@txt[0]}#{@cX.off*2} #{@cX.blue}#{@txt[1]}#{@cX.off}} +    end +    def term_sheet_title +      puts %{\t#{@cX.green}#{@txt[0]}#{@cX.off} #{@cX.red_hi}#{@cX.black}#{@txt[1]}.#{@cX.off*2} } +    end +    def generic_number +      puts "#{@cX.green}#{@txt[0]}#{@cX.off} #{@cX.grey}#{@txt[1]}#{@cX.off}" +    end +    def tex_numbers +      puts %{  #{@cX.green}#{@txt[0]}#{@cX.off} #{@cX.cyan}tex/pdf files processed#{@cX.off}.} +    end +    def tex_info_numbers +      puts %{  #{@cX.green}#{@txt[0]}#{@cX.off} #{@cX.cyan}texinfo files processed#{@cX.off}.} +    end +    def lout_numbers +      puts %{  #{@cX.green}#{@n_lout}#{@cX.off} #{@cX.cyan}lout/pdf files processed#{@cX.off}.} +    end +    def parameters +    end +    def reserved +      puts %{ #{@cX.grey_hi}#{@cX.black}reserved#{@cX.off*2}} +    end +    def meta_verse_title +      puts %{#{@cX.green_hi}#{@cX.black}MetaVerse#{@cX.off*2} } +    end +    def meta_verse_title_v +      b=sourcename(@txt[0]) +      puts %{#{@cX.green_hi}#{@cX.black}MetaVerse#{@cX.off*2} } + +        %{#{@cX.grey}#{@txt[0]}#{@cX.off} #{@cX.ruby}->#{@cX.off}\n\t  #{@cX.blue}~meta/#{b}.meta#{@cX.off}} +    end +    def meta_verse +      puts "\t#{@cX.grey}MetaVerse#{@cX.off}" +    end +    def meta_verse_skipped +      puts %{\t#{@cX.grey}MetaVerse: MarshalLoad (creation of metaVerse skipped)#{@cX.off}} +    end +    def meta_verse_load +      puts %{\t[ MetaVerse: MarshalLoad ]} +    end +    def html_title +      puts %{#{@cX.green_hi}#{@cX.black}HTML#{@cX.off*2}} +    end +    def html_output +      puts %{\t#{@cX.grey}#{@txt[0]}#{@cX.off} #{@cX.ruby}->#{@cX.off}\n\t  #{@cX.blue}#{@txt[1]}#{@cX.off}} +    end +    def segmented +      puts "\t#{@cX.grey}Seg#{@cX.off} #{@cX.green}#{@txt[0]}#{@cX.off} #{@cX.grey}segments#{@cX.off}" +    end +  end +end +__END__ +        Color.new do +          self.off           = "\033[0m" +          self.white         = "\033[37m" +          self.white_bold    = "\033[1m" +          self.marker        = "\033[42m" +          self.bold          = "\033[1m" +          self.underline     = "\033[4m" +          self.invert        = "\033[7m" +          self.darkgrey_hi   = "\033[100m" +          self.grey_hi       = "\033[47m" +          self.pink_hi       = "\033[105m" +          self.fuchsia_hi    = "\033[45m" +          self.red_hi        = "\033[41m" +          self.orange_hi     = "\033[101m" +          self.yellow_hi     = "\033[103m" +          self.brown_hi      = "\033[43m" +          self.lightgreen_hi = "\033[102m" +          self.green_hi      = "\033[42m" +          self.cyan_hi       = "\033[106m" +          self.blue_hi       = "\033[104m" +          self.navy_hi       = "\033[44m" +          self.grey          = "\033[90m" +          self.pink          = "\033[95m" +          self.fuchsia       = "\033[35m" +          self.ruby          = "\033[31m" +          self.red           = "\033[91m" #check +          self.orange        = "\033[91m" +          self.yellow        = "\033[93m" +          self.brown         = "\033[33m" +          self.green         = "\033[92m" +          self.darkgreen     = "\033[32m" +          self.cyan          = "\033[36m" +          self.blue          = "\033[94m" +          self.navy          = "\033[34m" +          self.black         = "\033[30m" +        end +# fewer colors +        Color.new do +          self.off           = "\033[0m" +          self.white         = "\033[0m" +          self.marker        = "\033[42m" +          self.bold          = "\033[1m" +          self.underline     = "\033[4m" +          self.invert        = "\033[7m" +          self.darkgrey_hi   = "\033[100m" +          self.grey_hi       = "\033[47m" +          self.pink_hi       = "\033[105m" +          self.fuchsia_hi    = "\033[45m" +          self.red_hi        = "\033[41m" +          self.orange_hi     = "\033[101m" +          self.yellow_hi     = "\033[103m" +          self.brown_hi      = "\033[43m" +          self.lightgreen_hi = "\033[102m" +          self.green_hi      = "\033[42m" +          self.cyan_hi       = "\033[106m" +          self.blue_hi       = "\033[104m" +          self.navy_hi       = "\033[44m" +          self.grey          = "\033[90m" +          self.pink          = "\033[95m" +          self.fuchsia       = "\033[35m" +          self.ruby          = "\033[31m" +          self.red           = "\033[31m" #check +          self.orange        = "\033[91m" +          self.yellow        = "\033[33m" +          self.brown         = "\033[33m" +          self.green         = "\033[32m" +          self.darkgreen     = "\033[32m" +          self.cyan          = "\033[36m" +          self.blue          = "\033[34m" +          self.navy          = "\033[34m" +          self.black         = "\033[30m" +        end +#+END_SRC + +* document header + +#+NAME: sisu_document_header +#+BEGIN_SRC text +encoding: utf-8 +- Name: SiSU + +  - Description: documents, structuring, processing, publishing, search +    utils + +  - 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 diff --git a/org/xhtml.org b/org/xhtml.org new file mode 100644 index 00000000..3fc576e9 --- /dev/null +++ b/org/xhtml.org @@ -0,0 +1,5080 @@ +-*- mode: org -*- +#+TITLE:       sisu xhtml including epub +#+DESCRIPTION: documents - structuring, various output representations & search +#+FILETAGS:    :sisu:xhtml: +#+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 + +* xhtml.rb + +#+BEGIN_SRC ruby  :tangle "../lib/sisu/xhtml.rb" +# <<sisu_document_header>> +module SiSU_XHTML +  require_relative 'se_hub_particulars'                 # se_hub_particulars.rb +    include SiSU_Particulars +  require_relative 'se'                                 # se.rb +    include SiSU_Env +  require_relative 'xml_shared'                         # xml_shared.rb +    include SiSU_XML_Munge +  require_relative 'xml_format'                         # xml_format.rb +    include SiSU_XML_Format +  require_relative 'xml_persist'                        # xml_persist.rb +  require_relative 'rexml'                              # rexml.rb +    include SiSU_Rexml +  require_relative 'shared_metadata'                    # shared_metadata.rb +  @@alt_id_count=0 +  @@tablefoot='' +  class Source +    def initialize(opt) +      @opt=opt +      @particulars=SiSU_Particulars::CombinedSingleton.instance.get_all(opt) +    end +    def read +      begin +        @env,@md,@ao_array=@particulars.env,@particulars.md,@particulars.ao_array +        unless @opt.act[:quiet][:set]==:on +          tool=if (@opt.act[:verbose_plus][:set]==:on \ +          || @opt.act[:maintenance][:set]==:on) +            "#{@env.program.web_browser} file://#{@md.file.output_path.xhtml.dir}/#{@md.file.base_filename.xhtml}" +          elsif @opt.act[:verbose][:set]==:on +            "#{@env.program.web_browser} file://#{@md.file.output_path.xhtml.dir}/#{@md.file.base_filename.xhtml}" +          else "[#{@opt.f_pth[:lng_is]}] #{@opt.fno}" +          end +          (@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], +              'XHTML', +              tool +            ).green_hi_blue +          : SiSU_Screen::Ansi.new( +              @opt.act[:color_state][:set], +              'XHTML', +              tool +            ).green_title_hi +          if (@opt.act[:verbose_plus][:set]==:on \ +          || @opt.act[:maintenance][:set]==:on) +            SiSU_Screen::Ansi.new( +              @opt.act[:color_state][:set], +              @opt.fns, +              "/#{@md.file.output_path.xhtml.dir}/#{@md.file.base_filename.xhtml}" +            ).flow +          end +        end +        SiSU_XHTML::Source::Songsheet.new(@particulars).song +      rescue +        SiSU_Errors::Rescued.new($!,$@,@opt.selections.str,@opt.fns).location do +          __LINE__.to_s + ':' + __FILE__ +        end +      ensure +        SiSU_Env::CreateSite.new(@opt).cp_css +        Dir.chdir(@opt.f_pth[:pth]) +      end +    end +    private +    class Songsheet +      def initialize(particulars) +        @env,@md,@ao_array,@particulars=particulars.env,particulars.md,particulars.ao_array,particulars +        @file=SiSU_Env::FileOp.new(@md) +      end +      def song +        begin +          SiSU_XHTML::Source::Scroll.new(@particulars).songsheet +          if (@md.opt.act[:verbose][:set]==:on \ +          || @md.opt.act[:verbose_plus][:set]==:on \ +          || @md.opt.act[:maintenance][:set]==:on) +            SiSU_XHTML::Source::Tidy.new(@md,@file.place_file.xhtml.dir).xml # test wellformedness, comment out when not in use +          end +          SiSU_Rexml::Rexml.new(@md,@file.place_file.xhtml.dir).xml if @md.opt.act[:maintenance][:set]==:on # test rexml parsing, comment out when not in use #debug +        rescue +          SiSU_Errors::Rescued.new($!,$@,@md.opt.selections.str,@md.fns).location do +            __LINE__.to_s + ':' + __FILE__ +          end +        ensure +        end +      end +    end +    class Scroll +      require_relative 'xhtml_shared'                   # xhtml_shared.rb #check already called +      require_relative 'txt_shared'                     # txt_shared.rb +        include SiSU_TextUtils +      require_relative 'css'                            # css.rb +      def initialize(particulars) +        @env,@md,@ao_array=particulars.env,particulars.md,particulars.ao_array +        @tab="\t" +        @trans=SiSU_XML_Munge::Trans.new(@md) +        @sys=SiSU_Env::SystemCall.new +        @per=SiSU_XML_Persist::Persist.new +      end +      def songsheet +        begin +          pre +          @data=markup(@ao_array) +          post +          publish +        ensure +          SiSU_XML_Persist::Persist.new.persist_init +        end +      end +    protected +      def embedded_endnotes(dob='') +        dob.obj=dob.obj.gsub(/#{Mx[:en_a_o]}(\d+)\s+(.+?)#{Mx[:en_a_c]}/, +            '<endnote><number>\1</number><note>\2</note></endnote> '). +          gsub(/#{Mx[:en_b_o]}([*+]\d+)\s+(.+?)#{Mx[:en_b_c]}/, +            '<endnote><symbol>\1</symbol><note>\2</note></endnote> '). +          gsub(/#{Mx[:en_a_o]}([*+]+)\s+(.+?)#{Mx[:en_a_c]}/, +            '<endnote><symbol>\1</symbol><note>\2</note></endnote> ') +      end +      def extract_endnotes(dob='') +        notes=dob.obj.scan(/(?:#{Mx[:en_a_o]}|#{Mx[:en_b_o]})([\d*+]+\s+.+?)(?:#{Mx[:en_a_c]}|#{Mx[:en_b_c]})/) +        notes.flatten.each do |e| +          s=e.to_s +          util=SiSU_TextUtils::Wrap.new(s,70) +          wrap=util.line_wrap +          wrap=wrap.gsub(/^(\d+)\s+(.+?)\s*\Z/m, <<WOK +#{Ax[:tab]*1}<endnote notenumber="\\1"> +#{Ax[:tab]*2}\\1. \\2 +#{Ax[:tab]*1}</endnote> +WOK +). +            gsub(/^([*+]\d+)\s+(.+?)\s*\Z/m, <<WOK +#{Ax[:tab]*1}<endnote symbol="\\1"> +#{Ax[:tab]*2}\\1 \\2 +#{Ax[:tab]*1}</endnote> +WOK +). +            gsub(/^([*+]+)\s+(.+?)\s*\Z/m, <<WOK +#{Ax[:tab]*1}<endnote symbol="\\1.length"> +#{Ax[:tab]*2}\\1 \\2 +#{Ax[:tab]*1}</endnote> +WOK +) +#KEEP alternative presentation of endnotes +#        wrap=wrap.gsub(/^(\d+)\s+(.+?)\s*\Z/m, <<WOK +##{Ax[:tab]*1}<p class="endnote" notenumber="\\1"> +##{Ax[:tab]*2}\\1. \\2 +##{Ax[:tab]*1}</p> +#WOK +#) +          @endnotes << wrap +        end +      end +      def xml_head +        metadata=SiSU_Metadata::Summary.new(@md).xhtml_scroll.metadata +        @per.head << metadata +      end +      def name_tags(dob) +        tags='' +        if defined? dob.tags \ +        and dob.tags.length > 0 # insert tags "hypertargets" +          dob.tags.each do |t| +            tags=tags << %{<named id="#{t}" />} +          end +        end +        tags +      end +      def xml_structure(dob,type='norm') +        if dob.is ==:para \ +        || dob.is ==:heading +          named=name_tags(dob) +          if dob.is==:heading +            lv=dob.ln +            dob.ln + 2 +          else lv=nil +          end +          extract_endnotes(dob) +          dob.obj=dob.obj.gsub(/#{Mx[:en_a_o]}([\d*+]+)\s+(?:.+?)#{Mx[:en_a_c]}/,'<en>\1</en>'). #footnote/endnote clean +            gsub(/#{Mx[:en_b_o]}([\d*+]+)\s+(?:.+?)#{Mx[:en_b_c]}/,'<en>\1</en>') +          util=SiSU_TextUtils::Wrap.new(dob.obj,70) +          wrapped=util.line_wrap +          @per.body << if defined? dob.ocn +            %{#{Ax[:tab]*0}<object id="#{dob.ocn}">} +          else                        "#{Ax[:tab]*0}<object>" +          end +          @per.body << %{#{Ax[:tab]*1}<text class="#{type}">#{named}\n#{Ax[:tab]*2}#{wrapped}\n#{Ax[:tab]*1}</text>} unless lv  # main text, contents, body KEEP +          @per.body << %{#{Ax[:tab]*1}<text class="h#{lv}">#{named}\n#{Ax[:tab]*2}#{wrapped}\n#{Ax[:tab]*1}</text>} if lv # main text, contents, body KEEP +          @per.body << @endnotes.compact.join if @endnotes.length > 0 # main text, endnotes KEEP +          @per.body << "#{Ax[:tab]*1}<ocn>#{dob.ocn}</ocn>" if defined? dob.ocn +          @per.body << "#{Ax[:tab]*0}</object>" +          @endnotes=[] +        end +      end +      def block_structure(dob) +        named=name_tags(dob) +        dob=@trans.markup_block(dob) +        dob.obj=dob.obj.strip. +          gsub(/#{Mx[:en_a_o]}([\d*+]+)\s+(?:.+?)#{Mx[:en_a_c]}/,'<en>\1</en>'). #footnote/endnote clean +          gsub(/#{Mx[:en_b_o]}([\d*+]+)\s+(?:.+?)#{Mx[:en_b_c]}/,'<en>\1</en>') #footnote/endnote clean +        @per.body << %{#{Ax[:tab]*0}<object id="#{dob.ocn}">} +        @per.body << %{#{Ax[:tab]*1}<ocn>#{dob.ocn}</ocn>} +        @per.body << %{#{Ax[:tab]*1}<text class="block">#{named}#{Ax[:tab]*1}} +        @per.body << %{#{Ax[:tab]*2}#{dob.obj}#{Ax[:tab]*1}} +        @per.body << %{#{Ax[:tab]*1}</text>} +        @per.body << "#{Ax[:tab]*0}</object>" +      end +      def group_structure(dob) +        named=name_tags(dob) +        dob=@trans.markup_group(dob) +        dob.obj=dob.obj.strip. +          gsub(/#{Mx[:en_a_o]}([\d*+]+)\s+(?:.+?)#{Mx[:en_a_c]}/,'<en>\1</en>'). #footnote/endnote clean +          gsub(/#{Mx[:en_b_o]}([\d*+]+)\s+(?:.+?)#{Mx[:en_b_c]}/,'<en>\1</en>') #footnote/endnote clean +        @per.body << %{#{Ax[:tab]*0}<object id="#{dob.ocn}">} +        @per.body << %{#{Ax[:tab]*1}<ocn>#{dob.ocn}</ocn>} +        @per.body << %{#{Ax[:tab]*1}<text class="group">#{named}#{Ax[:tab]*1}} +        @per.body << %{#{Ax[:tab]*2}#{dob.obj}#{Ax[:tab]*1}} +        @per.body << %{#{Ax[:tab]*1}</text>} +        @per.body << "#{Ax[:tab]*0}</object>" +      end +      def poem_structure(dob) +        named=name_tags(dob) +        dob=@trans.markup_group(dob) +        dob.obj=dob.obj.strip +        @per.body << %{#{Ax[:tab]*0}<object id="#{dob.ocn}">} +        @per.body << %{#{Ax[:tab]*1}<ocn>#{dob.ocn}</ocn>} +        @per.body << %{#{Ax[:tab]*1}<text class="verse">#{named}#{Ax[:tab]*1}} +        @per.body << %{#{Ax[:tab]*2}#{dob.obj}#{Ax[:tab]*1}} +        @per.body << %{#{Ax[:tab]*1}</text>} +        @per.body << "#{Ax[:tab]*0}</object>" +      end +      def code_structure(dob) +        named=name_tags(dob) +        dob=@trans.markup_group(dob) +        dob.obj=dob.obj.gsub(/\s\s/,'  ').strip +        @per.body << %{#{Ax[:tab]*0}<object id="#{dob.ocn}">} +        @per.body << %{#{Ax[:tab]*1}<ocn>#{dob.ocn}</ocn>} +        @per.body << %{#{Ax[:tab]*1}<text class="code">#{named}#{Ax[:tab]*1}} +        @per.body << %{#{Ax[:tab]*2}#{dob.obj}#{Ax[:tab]*1}} +        @per.body << %{#{Ax[:tab]*1}</text>} +        @per.body << "#{Ax[:tab]*0}</object>" +      end +      def table_structure(dob) +        named=name_tags(dob) +        table=SiSU_XHTML_Shared::TableXHTML.new(dob) +        @per.body << %{#{Ax[:tab]*0}<object id="#{dob.ocn}">} +        @per.body << %{#{Ax[:tab]*1}<ocn>#{dob.ocn}</ocn>} +        @per.body << %{#{Ax[:tab]*2}#{named}#{table.table.obj}} +        @per.body << "#{Ax[:tab]*0}</object>" +      end +      def markup(data) +        @endnotes=[] +        @rcdc=false +        @level,@cont,@copen,@xml_contents_close=[],[],[],[] +        xml_head +        (0..7).each { |x| @cont[x]=@level[x]=false } +        (4..7).each { |x| @xml_contents_close[x]='' } +        data.each do |dob| +          dob=@trans.markup(dob) +          if @rcdc==false \ +          and (dob.obj =~/~meta/ \ +          and dob.obj =~/Document Information/) +            @rcdc=true +          end +          if dob.obj !~/(^#{Rx[:meta]}|#{Mx[:br_eof]}|#{Mx[:br_endnotes]})/ +            if defined? dob.ocn #look to move to format section +              ocn=(dob.ocn.to_s =~/\d+/) ? dob.ocn : nil +              @p_num=SiSU_XML_Format::ParagraphNumber.new(@md,ocn) +            end +            if not @rcdc +              x=SiSU_XML_Format::FormatSeg.new(@md,dob) +              if dob.is==:heading +                xml_structure(dob) +                dob.obj=case dob.ln +                when 0 then x.heading_body0 +                when 1 then x.heading_body1 +                when 2 then x.heading_body2 +                when 3 then x.heading_body3 +                when 4 then x.heading_body4 +                when 5 then x.heading_body5 +                when 6 then x.heading_body6 +                when 7 then x.heading_body7 +                end +              else +                if dob.is ==:verse +                  poem_structure(dob) +                elsif dob.is ==:group +                  group_structure(dob) +                elsif dob.is ==:block +                  block_structure(dob) +                elsif dob.is ==:code +                  code_structure(dob) +                elsif dob.is ==:table +                  table_structure(dob) +                elsif dob.is ==:para \ +                and dob.indent.to_s =~/[1-9]/ \ +                and dob.bullet_==true +                  xml_structure(dob,"indent_bullet#{dob.indent}") +                elsif dob.is ==:para \ +                and dob.indent.to_s =~/[1-9]/ \ +                and dob.indent == dob.hang +                  xml_structure(dob,"indent#{dob.indent}") +                elsif dob.is==:para \ +                and dob.hang.to_s =~/[0-9]/ \ +                and dob.indent != dob.hang +                  xml_structure(dob,"hang#{dob.hang.to_s}_indent#{dob.indent.to_s}") +                else xml_structure(dob) +                end +              end +              if dob.obj =~/.*<:#>.*$/ #investigate removal +                dob.obj=if dob.obj =~ /#{Mx[:pa_o]}:i[1-9]#{Mx[:pa_c]}/ +                  txt_obj={ txt: dob } +                  format_text=FormatTextObject.new(@md,txt_obj) +                  format_text.scr_inden_ocn_e_no_paranum +                end +              end +            else # +            end +            dob.obj=dob.obj.gsub(/#{Mx[:pa_o]}:\S+#{Mx[:pa_c]}/,'') if dob.obj +          end +        end +        6.downto(4) do |x| +          y=x - 1; v=x - 3 +          @per.body << "#{Ax[:tab]*5}</content>\n#{Ax[:tab]*y}</contents#{v}>" if @level[x]==true +        end +        3.downto(1) do |x| +          y=x - 1 +          @per.body << "#{Ax[:tab]*y}</heading#{x}>" if @level[x]==true +        end +      end +      def pre +        rdf=SiSU_XML_Tags::RDF.new(@md) +        @per.head,@per.body=[],[] +        stylesheet=SiSU_Style::CSS_HeadInfo.new(@md,'xhtml').stylesheet +        encoding=(@sys.locale =~/utf-?8/i) \ +        ? '<?xml version="1.0" encoding="UTF-8" standalone="no"?>' +        : '<?xml version="1.0" encoding="ISO-8859-1" standalone="no"?>' +        @per.open =<<WOK +#{encoding} +#{stylesheet.css_head_xml} +#{rdf.comment_xml} +<document> +WOK +        @per.head << %{<head>\n\t<meta http-equiv="Content-Type" content="text/html;charset=utf-8" />} +        @per.body << '<body>' +      end +      def post +        @per.head << '</head>' +        @per.body << '</body>' +        @per.close = '</document>' +      end +      def publish +        content=[] +        content << @per.open << @per.head << @per.body << @per.metadata +        content << @per.tail << @per.close +        content=content.flatten.compact +        Output.new(content,@md).xhtml +        @@xml={} +      end +    end +    class Output +      def initialize(data,md) +        @data,@md=data,md +        @file=SiSU_Env::FileOp.new(@md) +      end +      def xhtml +        SiSU_Env::FileOp.new(@md).mkdir +        filename_xml=@file.write_file.xhtml +        @data.each do |str| +          str=str.gsub(/\A\s+\Z/m,'') #str.gsub(/^\s+$/,'') +          filename_xml.puts str unless str.empty? +        end +        filename_xml.close +      end +    end +    class Tidy +      def initialize(md,file) +        @md,@file=md,file +        @prog=SiSU_Env::InfoProgram.new +      end +      def xml +        if @prog.tidy !=false +          if (@md.opt.act[:verbose_plus][:set]==:on \ +          || @md.opt.act[:maintenance][:set]==:on) +            unless @md.opt.act[:quiet][:set]==:on +              SiSU_Screen::Ansi.new( +                @md.opt.act[:color_state][:set], +                'invert', +                'Using XML Tidy', +                'check document structure' +              ).colorize +              tell=SiSU_Screen::Ansi.new( +                @md.opt.act[:color_state][:set], +                'invert', +                '', +                '' +              ) +              tell.grey_open +            end +            tidyfile='/dev/null' #don't want one or screen output, check for alternative flags +            tidy=SiSU_Env::SystemCall.new(@file,tidyfile) +            tidy.well_formed? +            tell.p_off unless @md.opt.act[:quiet][:set]==:on +          end +        end +      end +    end +  end +end +__END__ +,** Notes: +tidy -xml scroll.xhtml >> index.tidy +<?xml version="1.0"?> +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<?xml version="1.0" encoding="ISO-8859-1" standalone="no"?> +<?xml version="1.0" encoding="ISO-8859-1" standalone="yes"?> +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<?xml version="1.0" encoding="UTF-16" standalone="no"?> +#+END_SRC + +* epub2.rb +** xhtml_epub2.rb + +#+BEGIN_SRC ruby  :tangle "../lib/sisu/xhtml_epub2.rb" +# <<sisu_document_header>> +module SiSU_XHTML_EPUB2 +  begin +    require 'pstore' +  rescue LoadError +    SiSU_Utils::CodeMarker.new(__LINE__,__FILE__,:fuchsia). +      error('pstore NOT FOUND (LoadError)') +  end +  require_relative 'se_hub_particulars'                 # se_hub_particulars.rb +    include SiSU_Particulars +  require_relative 'xml_shared'                         # xml_shared.rb +    include SiSU_XML_Munge +  require_relative 'xhtml_table'                        # xhtml_table.rb +  require_relative 'xhtml_epub2_format'                 # xhtml_epub2_format.rb +    include SiSU_XHTML_EPUB2_Format +  require_relative 'xhtml_epub2_segments'               # xhtml_epub2_segments.rb +    include SiSU_XHTML_EPUB2_Seg +  require_relative 'xhtml_epub2_tune'                   # xhtml_epub2_tune.rb +    include SiSU_XHTML_EPUB2_Tune +  require_relative 'xhtml_epub2_concordance'            # xhtml_epub2_concordance.rb +  require_relative 'xhtml_epub2_persist'                # xhtml_epub2_persist.rb +  class Source +    def initialize(opt) +      @opt=opt +      @particulars=SiSU_Particulars::CombinedSingleton.instance.get_all(opt) +    end +    def read +      begin +        songsheet +      ensure +        Dir.chdir(@opt.f_pth[:pth]) +      end +    end +    def songsheet +      begin +        @md=@particulars.md +        @fnb=@md.fnb +        @env=@particulars.env +        unless @opt.act[:quiet][:set]==:on +          tool=(@opt.act[:verbose][:set]==:on \ +          || @opt.act[:verbose_plus][:set]==:on \ +          || @opt.act[:maintenance][:set]==:on) \ +          ? "#{@env.program.epub_viewer} #{@md.file.output_path.epub.dir}/#{@md.file.base_filename.epub}" +          : "[#{@opt.f_pth[:lng_is]}] #{@opt.fno}" +          (@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], +              'EPUB', +              tool +            ).green_hi_blue +          : SiSU_Screen::Ansi.new( +              @opt.act[:color_state][:set], +              'EPUB', +              tool +            ).green_title_hi +          if (@opt.act[:verbose_plus][:set]==:on \ +          || @opt.act[:maintenance][:set]==:on) +            SiSU_Screen::Ansi.new( +              @opt.act[:color_state][:set], +              @opt.fns, +              "#{@md.file.output_path.epub.dir}/#{@md.file.base_filename.epub}" +            ).flow +          end +        end +        @env.processing_path.epub_bld #(@md) +        @env.processing_path.epub_cp_images(@md) +        data=nil +        SiSU_Env::FileOp.new(@md).mkdir.output.epub +        @tuned_file_array=SiSU_XHTML_EPUB2::Source::XHTML_Environment.new(@particulars).tuned_file_instructions +        data=@tuned_file_array +        per=SiSU_XHTML_EPUB2::Source::Toc.new(@md,data).songsheet +        data=@tuned_file_array +        SiSU_XHTML_EPUB2::Source::ScrollHeadAndSegToc.new(@md,per).in_common #watch +        SiSU_XHTML_EPUB2::Source::Seg.new(@md,data).songsheet +        SiSU_XHTML_EPUB2::Source::Output.new(@md).songsheet +      rescue +        SiSU_Errors::Rescued.new($!,$@,@opt.selections.str,@opt.fns).location do +          __LINE__.to_s + ':' + __FILE__ +        end +      ensure +        unless (@opt.act[:verbose_plus][:set]==:on \ +        || @opt.act[:maintenance][:set]==:on) +          texfiles=Dir["#{@env.processing_path.tune}/#{@opt.fns}*"] +          texfiles.each do |f| +            if FileTest.file?(f) +              File.unlink(f) +            end +          end +        end +        SiSU_Env::Clear.new(@opt.selections.str,@opt.fns).param_instantiate +        @@flag,@@scr,@@seg,@@seg_endnotes,@@seg_subtoc={},{},{},{},{} +        @@tracker=0 +        @@seg_name,@@seg_name_html,@@seg_subtoc_array,@@seg_endnotes_array,@@tablefoot=Array.new(5){[]} +        @@filename_seg,@@seg_url,@@to_lev4,@@get_hash_to,@@get_hash_fn='','','','','' +      end +    end +    private +    class XHTML_Environment +      def initialize(particulars) +        @particulars=particulars +        @md,@env=particulars.md,particulars.env +        @env,@css=particulars.env,SiSU_Style::CSS.new +      end +      def directories +        SiSU_Env::FileOp.new(@md).mkdir.output.epub +      end +      def tuned_file_instructions +        @tell=SiSU_Screen::Ansi.new(@md.opt.act[:color_state][:set]) +        directories +        ao_array=@particulars.ao_array # ao file drawn here +        @tuned_file_array=SiSU_XHTML_EPUB2_Tune::Tune.new(ao_array,@md).songsheet +        @tuned_file_array +      end +    end +    class Endnotes +      include SiSU_XHTML_EPUB2_Format +      def initialize(md,data) +        @md,@data=md,data +      end +      def scroll +        @scr_endnotes=[] +        @data.each do |dob| +          pg=dob.dup +          unless pg.is ==:code +            if pg.obj =~/(?:#{Mx[:en_a_o]}|#{Mx[:en_b_o]})[\d*+]+ / +              endnote_array=[] +              if pg.obj=~/#{Mx[:en_a_o]}[\d*+].+?#{Mx[:en_a_c]}/m +                endnote_array = pg.obj.scan(/#{Mx[:en_a_o]}[\d*+]+(.+?)#{Mx[:en_a_c]}/m) +              end +              if pg.obj=~/#{Mx[:en_b_o]}[\d*]+\s.+?#{Mx[:en_b_c]}/m +                endnote_array = pg.obj.scan(/#{Mx[:en_b_o]}[\d*]+(.+?)#{Mx[:en_b_c]}/m) +              end +              if pg.obj=~/#{Mx[:en_b_o]}[\d+]+\s.+?#{Mx[:en_b_c]}/m +                endnote_array = pg.obj.scan(/#{Mx[:en_b_o]}[\d+]+(.+?)#{Mx[:en_b_c]}/m) +              end +              endnote_array.flatten.each do |note| +                txt_obj={ txt: note } +                format_scroll=SiSU_XHTML_EPUB2_Format::FormatScroll.new(@md,txt_obj) +                @scr_endnotes << format_scroll.endnote_body +              end +            end +          end +        end +        @scr_endnotes +      end +    end +    class Toc +      @@seg_url='' +      @@firstseg=nil +      def initialize(md=nil,data='') +        @md,@data=md,data +        @epub=SiSU_XHTML_EPUB2_Format::HeadInformation.new(@md) +        @tell=SiSU_Screen::Ansi.new(@md.opt.act[:color_state][:set]) if @md +        @make=SiSU_Env::ProcessingSettings.new(@md) +        @per=SiSU_XHTML_EPUB2_Persist::PersistTOC.new +      end +      def songsheet #extracts toc for scroll & seg +        begin +          if (@md.opt.act[:verbose][:set]==:on \ +          || @md.opt.act[:verbose_plus][:set]==:on \ +          || @md.opt.act[:maintenance][:set]==:on) +            SiSU_Screen::Ansi.new( +              @md.opt.act[:color_state][:set], +              'Toc' +            ).txt_grey +          end +          toc=nil +          @@firstseg=nil +          SiSU_XHTML_EPUB2_Persist::PersistTOC.new.persist_init +          md_opf_a_content,md_opf_a_spine,md_opf_a_guide=[],[],[] +          @nav_no=0 +          @s_a_no,@s_b_no,@s_c_no,@s_d_no,@lv5_no,@lv6_no=0,0,0,0,0,0 +          @per.ncx << @epub.toc_ncx.open #epub ncx navmap +          @per.ncx << @epub.toc_ncx.head_open << @epub.toc_ncx.head << @epub.toc_ncx.head_close +          @per.ncx << @epub.toc_ncx.doc_title << @epub.toc_ncx.doc_author +          @per.ncx << @epub.toc_ncx.navmap_open +          @per.opf << @epub.metadata_opf.package_open +          @per.opf << @epub.metadata_opf.metadata +          @per.opf << @epub.metadata_opf.manifest_open +          @per.seg << %{<div class="content">\n<div class="substance">} +          @per.scr << %{<div class="content">\n<div class="substance">} +          if defined? @md.make.cover_image \ +          and @md.make.cover_image.is_a?(Hash) \ +          and @md.make.cover_image[:cover] =~/\S+/ +            md_opf_a_content << @epub.metadata_opf.manifest_cover_image_information(@md) +            md_opf_a_spine << @epub.metadata_opf.spine_cover_image +            md_opf_a_guide << @epub.metadata_opf.guide_cover_image +          end +          md_opf_a_content << @epub.metadata_opf.manifest_content_sisu_toc +          if @make.build.toc? +            md_opf_a_spine << @epub.metadata_opf.spine_sisu_toc +            md_opf_a_guide << @epub.metadata_opf.guide_sisu_toc +          end +          @ncxo=[false,false,false,false,false,false,false] +          @dob_toc2,@dob_toc3=nil,nil +          @ncx_cls=[] +          @level_a_first_occurrence=true +          @data.each do |dob| +            if dob.is==:heading \ +            || dob.is==:heading_insert +              dob_toc=dob.dup +              toc=case dob_toc.ln +              when 0 +                @s_a_no +=1 +                lv_name='section_a' + @s_a_no.to_s +                @nav_no+=1 +                @nav_no2=@nav_no +                @per.ncx << @epub.toc_ncx.navpoint_close if @ncxo[7] +                @per.ncx << @epub.toc_ncx.navpoint_close if @ncxo[6] +                @per.ncx << @epub.toc_ncx.navpoint_close if @ncxo[5] +                @per.ncx << @epub.toc_ncx.navpoint_close if @ncxo[4] +                @per.ncx << @epub.toc_ncx.navpoint_close if @ncxo[3] +                @per.ncx << @epub.toc_ncx.navpoint_close if @ncxo[2] +                @per.ncx << @epub.toc_ncx.navpoint_close if @ncxo[1] +                @per.ncx << @epub.toc_ncx.navpoint_close if @ncxo[0] +                @ncxo[0],@ncxo[1],@ncxo[2],@ncxo[3],@ncxo[4],@ncxo[5],@ncxo[6],@ncxo[7]= +                  true,  false,   false,   false,   false,   false,   false,   false +                @epub.sections(dob_toc,lv_name) +                if @level_a_first_occurrence \ +                && @make.build.toc? +                  @per.ncx << @epub.toc_ncx.navmap_sisu_toc(@nav_no) #epub ncx navmap, toc +                  @nav_no+=1 +                  @level_a_first_occurrence=false +                end +                @per.ncx << @epub.toc_ncx.navpoint(dob_toc,@nav_no,lv_name) if dob_toc +                md_opf_a_content << @epub.metadata_opf.manifest_content(dob_toc,lv_name) +                md_opf_a_spine << @epub.metadata_opf.spine(dob_toc,lv_name) +                md_opf_a_guide << @epub.metadata_opf.guide(dob_toc,lv_name) +                SiSU_XHTML_EPUB2::Source::Toc.new(@md,dob_toc).level_0 +              when 1 +                @s_b_no +=1 +                lv_name='section_b' + @s_b_no.to_s +                @nav_no+=1 +                @nav_no2=@nav_no +                @per.ncx << @epub.toc_ncx.navpoint_close if @ncxo[7] +                @per.ncx << @epub.toc_ncx.navpoint_close if @ncxo[6] +                @per.ncx << @epub.toc_ncx.navpoint_close if @ncxo[5] +                @per.ncx << @epub.toc_ncx.navpoint_close if @ncxo[4] +                @per.ncx << @epub.toc_ncx.navpoint_close if @ncxo[3] +                @per.ncx << @epub.toc_ncx.navpoint_close if @ncxo[2] +                @per.ncx << @epub.toc_ncx.navpoint_close if @ncxo[1] +                @ncxo[1],@ncxo[2],@ncxo[3],@ncxo[4],@ncxo[5],@ncxo[6],@ncxo[7]= +                  true,  false,   false,   false,   false,   false,   false +                @epub.sections(dob_toc,lv_name) +                @per.ncx << @epub.toc_ncx.navpoint(dob_toc,@nav_no,lv_name) if dob_toc +                md_opf_a_content << @epub.metadata_opf.manifest_content(dob_toc,lv_name) +                md_opf_a_spine << @epub.metadata_opf.spine(dob_toc,lv_name) +                md_opf_a_guide << @epub.metadata_opf.guide(dob_toc,lv_name) +                SiSU_XHTML_EPUB2::Source::Toc.new(@md,dob_toc).level_1 +              when 2 +                @s_c_no +=1 +                lv_name='section_c' + @s_c_no.to_s +                @nav_no+=1 +                @nav_no2=@nav_no +                @per.ncx << @epub.toc_ncx.navpoint_close if @ncxo[7] +                @per.ncx << @epub.toc_ncx.navpoint_close if @ncxo[6] +                @per.ncx << @epub.toc_ncx.navpoint_close if @ncxo[5] +                @per.ncx << @epub.toc_ncx.navpoint_close if @ncxo[4] +                @per.ncx << @epub.toc_ncx.navpoint_close if @ncxo[3] +                @per.ncx << @epub.toc_ncx.navpoint_close if @ncxo[2] +                @ncxo[2],@ncxo[3],@ncxo[4],@ncxo[5],@ncxo[6],@ncxo[7]= +                  true,  false,   false,   false,   false,   false +                @epub.sections(dob_toc,lv_name) +                @per.ncx << @epub.toc_ncx.navpoint(dob_toc,@nav_no,lv_name) if dob_toc +                md_opf_a_content << @epub.metadata_opf.manifest_content(dob_toc,lv_name) +                md_opf_a_spine << @epub.metadata_opf.spine(dob_toc,lv_name) +                md_opf_a_guide << @epub.metadata_opf.guide(dob_toc,lv_name) +                SiSU_XHTML_EPUB2::Source::Toc.new(@md,dob_toc).level_2 +              when 3 +                @s_d_no +=1 +                lv_name='section_d' + @s_d_no.to_s +                @nav_no+=1 +                @nav_no3=@nav_no +                @per.ncx << @epub.toc_ncx.navpoint_close if @ncxo[7] +                @per.ncx << @epub.toc_ncx.navpoint_close if @ncxo[6] +                @per.ncx << @epub.toc_ncx.navpoint_close if @ncxo[5] +                @per.ncx << @epub.toc_ncx.navpoint_close if @ncxo[4] +                @per.ncx << @epub.toc_ncx.navpoint_close if @ncxo[3] +                @ncxo[3],@ncxo[4],@ncxo[5],@ncxo[6],@ncxo[7]= +                  true,  false,   false,   false,   false +                @epub.sections(dob_toc,lv_name) +                @per.ncx << @epub.toc_ncx.navpoint(dob_toc,@nav_no,lv_name) if dob_toc +                md_opf_a_content << @epub.metadata_opf.manifest_content(dob_toc,lv_name) +                md_opf_a_spine << @epub.metadata_opf.spine(dob_toc,lv_name) +                md_opf_a_guide << @epub.metadata_opf.guide(dob_toc,lv_name) +                SiSU_XHTML_EPUB2::Source::Toc.new(@md,dob_toc).level_3 +              when 4 +                @ncx_cls=[] +                lv_name=dob_toc.name +                @nav_no+=1 +                @dob_name=dob.name +                @per.ncx << @epub.toc_ncx.navpoint_close if @ncxo[7] +                @per.ncx << @epub.toc_ncx.navpoint_close if @ncxo[6] +                @per.ncx << @epub.toc_ncx.navpoint_close if @ncxo[5] +                @per.ncx << @epub.toc_ncx.navpoint_close if @ncxo[4] +                @ncxo[4],@ncxo[5],@ncxo[6],@ncxo[7]= +                  true,  false,   false,   false +                @per.ncx << @epub.toc_ncx.navpoint(dob_toc,@nav_no,lv_name) if dob_toc +                md_opf_a_content << @epub.metadata_opf.manifest_content(dob_toc,lv_name) +                md_opf_a_spine << @epub.metadata_opf.spine(dob_toc,lv_name) +                md_opf_a_guide << @epub.metadata_opf.guide(dob_toc,lv_name) +                SiSU_XHTML_EPUB2::Source::Toc.new(@md,dob_toc).level_4 +              when 5 +                @ncx_cls=[] +                hashtag='#o' + dob_toc.ocn.to_s +                lv_name=@dob_name +                @nav_no+=1 +                @per.ncx << @epub.toc_ncx.navpoint_close if @ncxo[7] +                @per.ncx << @epub.toc_ncx.navpoint_close if @ncxo[6] +                @per.ncx << @epub.toc_ncx.navpoint_close if @ncxo[5] +                @ncxo[5],@ncxo[6],@ncxo[7]= +                  true,  false, false +                @per.ncx << @epub.toc_ncx.navpoint(dob_toc,@nav_no,lv_name,hashtag) if dob_toc +                md_opf_a_content << @epub.metadata_opf.manifest_content(dob_toc,lv_name,hashtag) +                md_opf_a_spine << @epub.metadata_opf.spine(dob_toc,lv_name,hashtag) +                md_opf_a_guide << @epub.metadata_opf.guide(dob_toc,lv_name,hashtag) +                SiSU_XHTML_EPUB2::Source::Toc.new(@md,dob_toc).level_5 +              when 6 +                @ncx_cls=[] +                hashtag='#o' + dob_toc.ocn.to_s +                lv_name=@dob_name +                @nav_no+=1 +                @per.ncx << @epub.toc_ncx.navpoint_close if @ncxo[7] +                @per.ncx << @epub.toc_ncx.navpoint_close if @ncxo[6] +                @ncxo[6],@ncxo[7]= +                  true,  false +                @per.ncx << @epub.toc_ncx.navpoint(dob_toc,@nav_no,lv_name,hashtag) if dob_toc +                md_opf_a_content << @epub.metadata_opf.manifest_content(dob_toc,lv_name,hashtag) +                md_opf_a_spine << @epub.metadata_opf.spine(dob_toc,lv_name,hashtag) +                md_opf_a_guide << @epub.metadata_opf.guide(dob_toc,lv_name,hashtag) +                SiSU_XHTML_EPUB2::Source::Toc.new(@md,dob_toc).level_6 +              when 7 +                @ncx_cls=[] +                hashtag='#o' + dob_toc.ocn.to_s +                lv_name=@dob_name +                @nav_no+=1 +                @per.ncx << @epub.toc_ncx.navpoint_close if @ncxo[7] +                @ncxo[7]=true +                @per.ncx << @epub.toc_ncx.navpoint(dob_toc,@nav_no,lv_name,hashtag) if dob_toc +                md_opf_a_content << @epub.metadata_opf.manifest_content(dob_toc,lv_name,hashtag) +                md_opf_a_spine << @epub.metadata_opf.spine(dob_toc,lv_name,hashtag) +                md_opf_a_guide << @epub.metadata_opf.guide(dob_toc,lv_name,hashtag) +                SiSU_XHTML_EPUB2::Source::Toc.new(@md,dob_toc).level_7 +              else nil +              end +              toc.each do |k,d| +                d.gsub!(/(?:#{Mx[:en_a_o]}.+?#{Mx[:en_a_c]}|#{Mx[:en_b_o]}.+?#{Mx[:en_b_c]})\s*/m,' ') +              end if toc +              if @@firstseg.nil? \ +              and dob.ln==4 \ +              and dob.name =~/\S+/ +                @@firstseg=dob.name +              end +              if toc +                begin +                  @per.seg << toc[:seg] +                  @per.scr << toc[:seg] +                rescue +                  SiSU_Errors::Rescued.new($!,$@,@md.opt.selections.str,@md.fns).location do +                    __LINE__.to_s + ':' + __FILE__ +                  end +                end +              end +            end +          end +          @per.ncx << @epub.toc_ncx.navpoint_close if @ncxo[6] +          @per.ncx << @epub.toc_ncx.navpoint_close if @ncxo[5] +          @per.ncx << @epub.toc_ncx.navpoint_close if @ncxo[4] +          @per.ncx << @epub.toc_ncx.navpoint_close if @ncxo[3] +          @per.ncx << @epub.toc_ncx.navpoint_close if @ncxo[2] +          @per.ncx << @epub.toc_ncx.navpoint_close if @ncxo[1] +          @per.ncx << @epub.toc_ncx.navpoint_close if @ncxo[0] +          @ncxo[0],@ncxo[1],@ncxo[2],@ncxo[3],@ncxo[4],@ncxo[5],@ncxo[6]=false,false,false,false,false,false,false +          md_opf_a_content << @epub.metadata_opf.manifest_images(@md.ec[:image]) +          @per.seg << "</div>\n</div>" +          @per.scr << "</div>\n</div>" +          @per.ncx << @epub.toc_ncx.navmap_close +          @per.ncx << @epub.toc_ncx.close +          @per.opf << md_opf_a_content << @epub.metadata_opf.manifest_close +          @per.opf << @epub.metadata_opf.spine_open << md_opf_a_spine << @epub.metadata_opf.spine_close +          @per.opf << @epub.metadata_opf.guide_open << md_opf_a_guide << @epub.metadata_opf.guide_close +          @per.opf << @epub.metadata_opf.package_close +          @per.opf=@per.opf.flatten +          SiSU_XHTML_EPUB2::Source::Output.new(@md,@per.opf).epub_metadata_opf +          SiSU_XHTML_EPUB2::Source::Output.new(@md,@per.ncx).epub_toc_ncx +          @md.firstseg=@@firstseg +          @per +        ensure +          SiSU_XHTML_EPUB2_Persist::Persist.new.persist_init +        end +      end +    protected +      def level_0 +        dob=@data +        linkname=dob.obj.gsub(/#{Mx[:en_a_o]}.+?#{Mx[:en_a_c]}|#{Mx[:en_b_o]}.+?#{Mx[:en_b_c]}/,'').strip +        link=dob.ocn +        title=linkname +        toc={} +        txt_obj={ txt: title } +        format_toc=SiSU_XHTML_EPUB2_Format::FormatToc.new(@md,txt_obj) +        toc[:seg]=format_toc.lev1 +        title=if dob.ocn ==0 then linkname +        else +          @per.scr <<  '<br />' +          link=(dob.ln) \ +          ? dob.ln +          : '' +          %{<b><a href="##{link}">#{linkname}</a></b>} +        end +        txt_obj={ txt: title } +        format_toc=SiSU_XHTML_EPUB2_Format::FormatToc.new(@md,txt_obj) +        toc[:scr]=format_toc.lev1 +        toc +      end +      def level_1 +        dob=@data +        linkname=dob.obj.gsub(/#{Mx[:en_a_o]}.+?#{Mx[:en_a_c]}|#{Mx[:en_b_o]}.+?#{Mx[:en_b_c]}/,'').strip +        link=dob.ocn +        title=if dob.obj !~/Document Information/ +          linkname +        else +          link='metadata' +          %{<b><a href="#{link}#{Sfx[:epub_xhtml]}">#{linkname}</a></b>} +        end +        toc={} +        txt_obj={ txt: title } +        format_toc=SiSU_XHTML_EPUB2_Format::FormatToc.new(@md,txt_obj) +        toc[:seg]=if dob.name =~/^meta/ \ +        and dob.obj =~/Document Information/ #check +          format_toc.lev0 +        else format_toc.lev1 +        end +        title=if dob.ocn ==0 +          if dob.name =~/^meta/ \ +          and dob.obj =~/Document Information/ +            %{<a href="#docinfo">#{linkname}</a>} +          else linkname +          end +        else +          @per.scr <<  '<br />' +          link=(dob.ln) \ +          ? dob.ln +          : '' +          %{<b><a href="##{link}">#{linkname}</a></b>} +        end +        txt_obj={ txt: title } +        format_toc=SiSU_XHTML_EPUB2_Format::FormatToc.new(@md,txt_obj) +        toc[:scr]=if dob.name =~/^meta/ \ +        and dob.obj =~/Document Information/ +          format_toc.lev0 +        else format_toc.lev1 +        end +        toc +      end +      def level_2 +        dob=@data +        linkname=dob.obj.gsub(/#{Mx[:en_a_o]}.+?#{Mx[:en_a_c]}|#{Mx[:en_b_o]}.+?#{Mx[:en_b_c]}/,'').strip +        ocn=dob.ocn +        if ocn \ +        and ocn !~/#/ +          p_num=SiSU_XHTML_EPUB2_Format::ParagraphNumber.new(@md,ocn) +        end +        txt_obj={ txt: linkname } +        format_toc=SiSU_XHTML_EPUB2_Format::FormatToc.new(@md,txt_obj) +        toc={} +        toc[:seg]=format_toc.lev2 +        if p_num +          title=%{#{p_num.goto}#{linkname}</a>} +          txt_obj={ txt: title } +          format_toc=SiSU_XHTML_EPUB2_Format::FormatToc.new(@md,txt_obj) +          toc[:scr]=format_toc.lev2 +        end +        toc +      end +      def level_3 +        dob=@data +        linkname=dob.obj.gsub(/#{Mx[:en_a_o]}.+?#{Mx[:en_a_c]}|#{Mx[:en_b_o]}.+?#{Mx[:en_b_c]}/,'').strip +        ocn=dob.ocn +        if ocn \ +        and ocn !~/#/ +          p_num=SiSU_XHTML_EPUB2_Format::ParagraphNumber.new(@md,ocn) +        end +        txt_obj={ txt: linkname } +        format_toc=SiSU_XHTML_EPUB2_Format::FormatToc.new(@md,txt_obj) +        toc={} +        toc[:seg]=format_toc.lev3 +        if p_num +          title=%{#{p_num.goto}#{linkname}</a>} +          txt_obj={ txt: title } +          format_toc=SiSU_XHTML_EPUB2_Format::FormatToc.new(@md,txt_obj) +          toc[:scr]=format_toc.lev3 +        end +        toc +      end +      def level_4 +        dob=@data +        linkname=dob.obj.gsub(/#{Mx[:en_a_o]}.+?#{Mx[:en_a_c]}|#{Mx[:en_b_o]}.+?#{Mx[:en_b_c]}/,'').strip +        ocn=dob.ocn +        p_num=SiSU_XHTML_EPUB2_Format::ParagraphNumber.new(@md,ocn) if ocn +        if dob.ln==4 +          seg_link=%{  <a href="#{dob.name}#{Sfx[:epub_xhtml]}"> +    #{dob.obj} +  </a> } +          @@seg_url=dob.name +        elsif dob.obj =~/\d+.\d+.\d+.\d+|\d+.\d+.\d+|\d+.\d+|\d+/ +          seg_link=dob.obj.gsub(/^(\d+.\d+.\d+.\d+|\d+.\d+.\d+|\d+.\d+|\d+)(.*)/, +            %{<a href="\\1#{Sfx[:epub_xhtml]}">} + +            %{\\1 \\2</a> }) +        end +        p_num=SiSU_XHTML_EPUB2_Format::ParagraphNumber.new(@md,ocn) if ocn +        txt_obj={ txt: seg_link } +        format_toc=SiSU_XHTML_EPUB2_Format::FormatToc.new(@md,txt_obj) +        toc={} +        toc[:seg]=format_toc.lev4 +        title=%{#{p_num.goto}#{linkname}</a>} if p_num +        txt_obj={ txt: title } +        format_toc=SiSU_XHTML_EPUB2_Format::FormatToc.new(@md,txt_obj) +        toc[:scr]=format_toc.lev4 +        toc +      end +      def level_5 +        dob=@data +        linkname=dob.obj.gsub(/#{Mx[:en_a_o]}.+?#{Mx[:en_a_c]}|#{Mx[:en_b_o]}.+?#{Mx[:en_b_c]}/,'').strip +        ocn=dob.ocn +        toc={} +        if ocn \ +        and ocn.to_s !~/#/ +          p_num=SiSU_XHTML_EPUB2_Format::ParagraphNumber.new(@md,ocn) +          lnk_n_txt=%{  <a href="#{@@seg_url}#{Sfx[:epub_xhtml]}#o#{ocn}"> +    #{linkname} +  </a>} +          txt_obj={ txt: lnk_n_txt } +          format_toc=SiSU_XHTML_EPUB2_Format::FormatToc.new(@md,txt_obj) +          toc[:seg]=format_toc.lev5 +          title=%{#{p_num.goto}#{linkname}</a>} +          txt_obj={ txt: title } +          format_toc=SiSU_XHTML_EPUB2_Format::FormatToc.new(@md,txt_obj) +          toc[:scr]=format_toc.lev5 +        end +        toc +      end +      def level_6 +        dob=@data +        linkname=dob.obj.gsub(/#{Mx[:en_a_o]}.+?#{Mx[:en_a_c]}|#{Mx[:en_b_o]}.+?#{Mx[:en_b_c]}/,'').strip +        ocn=dob.ocn +        toc={} +        if ocn \ +        and ocn.to_s !~/#/ +          p_num=SiSU_XHTML_EPUB2_Format::ParagraphNumber.new(@md,ocn) +          lnk_n_txt=%{  <a href="#{@@seg_url}#{Sfx[:epub_xhtml]}#o#{ocn}"> +  #{linkname} +</a>} +          txt_obj={ txt: lnk_n_txt } +          format_toc=SiSU_XHTML_EPUB2_Format::FormatToc.new(@md,txt_obj) +          toc[:seg]=format_toc.lev6 +          title=%{#{p_num.goto}#{linkname}</a>} +          txt_obj={ txt: title } +          format_toc=SiSU_XHTML_EPUB2_Format::FormatToc.new(@md,txt_obj) +          toc[:scr]=format_toc.lev6 +        end +        toc +      end +      def level_7 +        dob=@data +        linkname=dob.obj.gsub(/#{Mx[:en_a_o]}.+?#{Mx[:en_a_c]}|#{Mx[:en_b_o]}.+?#{Mx[:en_b_c]}/,'').strip +        ocn=dob.ocn +        toc={} +        if ocn \ +        and ocn.to_s !~/#/ +          p_num=SiSU_XHTML_EPUB2_Format::ParagraphNumber.new(@md,ocn) +          lnk_n_txt=%{  <a href="#{@@seg_url}#{Sfx[:epub_xhtml]}#o#{ocn}"> +  #{linkname} +</a>} +          txt_obj={ txt: lnk_n_txt } +          format_toc=SiSU_XHTML_EPUB2_Format::FormatToc.new(@md,txt_obj) +          toc[:seg]=format_toc.lev7 +          title=%{#{p_num.goto}#{linkname}</a>} +          txt_obj={ txt: title } +          format_toc=SiSU_XHTML_EPUB2_Format::FormatToc.new(@md,txt_obj) +          toc[:scr]=format_toc.lev7 +        end +        toc +      end +    end +    class ScrollHeadAndSegToc < Toc +      def initialize(md='',per='',links_guide_toc='') +        @md,@per,@links_guide_toc=md,per,links_guide_toc +      end +      def in_common +        toc_shared=[] +        segtoc=[] +        if (@md.opt.act[:verbose][:set]==:on \ +        || @md.opt.act[:verbose_plus][:set]==:on \ +        || @md.opt.act[:maintenance][:set]==:on) +          SiSU_Screen::Ansi.new( +            @md.opt.act[:color_state][:set], +            'Scroll & Segtoc' +          ).txt_grey +        end +        format_head_toc=SiSU_XHTML_EPUB2_Format::HeadToc.new(@md) +        dochead=format_head_toc.head +        dochead=dochead.gsub(/toc\.(html)/,'doc.\1') #kludge +        toc_shared << dochead #<< ads.div.major +        segtoc << format_head_toc.head #<< ads.div.major +        if defined? @md.rights.all \ +        and @md.rights.all +          rights=format_head_toc.rights.all +          rights=SiSU_XHTML_EPUB2_Tune::CleanXHTML.new(rights).clean +        end +        if defined? @md.notes.prefix_b \ +        and @md.notes.prefix_b +          prefix_b=format_head_toc.prefix_b +          prefix_b=SiSU_XHTML_EPUB2_Tune::CleanXHTML.new(prefix_b).clean +        end +        tmp_head=nil +        doc_title_endnote=@md.title.full.gsub(/(\*+)/,'<sup><a href="#endnotes">\1</a></sup>') +        tmp_head=doc_title_endnote + "\n" +        txt_obj={ txt: tmp_head } +        format_txt_obj=SiSU_XHTML_EPUB2_Format::FormatTextObject.new(@md,txt_obj) +        toc_shared << format_txt_obj.center_bold +        segtoc << format_txt_obj.center_bold +        if defined? @md.creator.author \ +        and @md.creator.author +          creator_endnote=@md.creator.author.gsub(/(\*+)/,%{#{$ep[:hsp]}<sup><a href="#notes">\\1</a></sup>}) +          tmp_head=creator_endnote + "\n" +          txt_obj={ txt: tmp_head } +          format_txt_obj=SiSU_XHTML_EPUB2_Format::FormatTextObject.new(@md,txt_obj) +          toc_shared << format_txt_obj.center_bold +          segtoc << format_txt_obj.center_bold +        end +        tmp_head=nil +        if defined? @md.prefix_a \ +        and @md.prefix_a +          tmp_head ||= %{#{@md.prefix_a}\n} +          toc_shared << tmp_head.dup +          segtoc << tmp_head.dup +        end +        tmp_head=nil +        toc_shared << @links_guide_toc +        if defined? @md.rights.all \ +        and @md.rights.all +          toc_shared << rights +        end +        if defined? @md.prefix_b \ +        and @md.prefix_b +          toc_shared << prefix_b +        end +        #Table of Contents added/appended here +        toc_shared << @per.scr +        segtoc << @links_guide_toc +        segtoc << @per.seg +        if defined? @md.rights.all \ +        and @md.rights.all +          segtoc << rights +        end +        if defined? @md.prefix_b \ +        and @md.prefix_b +          segtoc << prefix_b +        end +        #Segtoc tail added here +        segtoc << format_head_toc.xhtml_close +        segtoc=segtoc.flatten.compact #watch +        SiSU_XHTML_EPUB2::Source::Output.new(@md).make_cover_image +        SiSU_XHTML_EPUB2::Source::Output.new(@md,segtoc).make_segtoc +        segtoc=[] +        @per.scr,@per.seg=[],[] +        toc_shared +      end +    end +    class Table < SiSU_XHTML_Table::TableXHTML +    end +    class Seg < SiSU_XHTML_EPUB2_Seg::Seg +    end +    class Output +      def initialize(md,output='') +        @md,@output=md,output +        @epub_doc="#{@md.fnb}.epub" +        @epub_header=SiSU_XHTML_EPUB2_Format::HeadInformation.new(@md) +        @make=SiSU_Env::ProcessingSettings.new(@md) +        @make_file=SiSU_Env::CreateFile.new(@md.fns) +      end +      def songsheet +        mimetype +        metainf_container +        css +        images if @md.ec[:image] +       #concordance #uncomment to enable inclusion of concordance file +        output_zip +      end +      def mimetype +        out=@make_file.epub.mimetype +        out<<@epub_header.mimetype +        out.close +      end +      def metainf_container #container.xml file in META-INF directory +        out=@make_file.epub.metainf_cont +        out<<@epub_header.metainf_container +        out.close +      end +      def css +        out=@make_file.epub.xhtml_css +        out << SiSU_XHTML_EPUB2_Format::CSS.new.css_epub_xhtml +        out.close +      end +      def epub_toc_ncx +        begin +          out=@make_file.epub.toc_ncx +          @output.each do |para| +            unless para =~/\A\s*\Z/ +              out.puts para +            end +          end +          out.close +        rescue +          SiSU_Errors::Rescued.new($!,$@,@md.opt.selections.str,@md.fns).location do +            __LINE__.to_s + ':' + __FILE__ +          end +        end +      end +      def epub_metadata_opf +        begin +          out=@make_file.epub.metadata +          @output.each do |para| +            unless para =~/\A\s*\Z/ +              out.puts para +            end +          end +          out.close +        rescue +          SiSU_Errors::Rescued.new($!,$@,@md.opt.selections.str,@md.fns).location do +            __LINE__.to_s + ':' + __FILE__ +          end +        end +      end +      def images +        img_pth=@md.env.path.image_source_include +        img_src_pth=unless @md.opt.f_pth[:pth] =~/\/\S+?\/sisupod\/\S+?\/sisupod\/doc/ +          @md.file.output_path.epub.rel_image +        else +          pt=/(\/\S+?\/sisupod\/\S+?\/sisupod)\/doc/.match(@md.opt.f_pth[:pth])[1] +          pt + '/image' +        end +        @md.ec[:image].each do |x| +          if FileTest.directory?("#{@md.env.processing_path.epub}/#{Ep[:d_oebps]}/image") \ +          && FileTest.file?("#{img_src_pth}/#{x}") +            FileUtils::cp("#{img_src_pth}/#{x}","#{@md.env.processing_path.epub}/#{Ep[:d_oebps]}/image") +          elsif FileTest.directory?("#{@md.env.processing_path.epub}/#{Ep[:d_oebps]}/image") \ +          && FileTest.file?("#{img_pth}/#{x}") +            FileUtils::cp("#{img_pth}/#{x}","#{@md.env.processing_path.epub}/#{Ep[:d_oebps]}/image") +          else STDERR.puts %{\t*WARN* did not find image - "#{x}" in #{img_src_pth} or #{img_pth} [#{__FILE__}:#{__LINE__}]} +          end +        end +      end +      def concordance +        SiSU_XHTML_EPUB2_Concordance::Source.new(@md.opt).read +      end +      def output_zip +        FileUtils::mkdir_p(@md.file.output_path.epub.dir) unless FileTest.directory?(@md.file.output_path.epub.dir) +        if FileTest.directory?(@md.env.processing_path.epub) \ +        and SiSU_Env::SystemCall.new.zip +          pwd=Dir.pwd +          Dir.chdir(@md.env.processing_path.epub) +          system(" +            zip -qXr9D #{@epub_doc} * +          ") +          FileUtils::mv(@epub_doc, @md.file.place_file.epub.dir) +          Dir.chdir(pwd) +          unless @md.opt.act[:maintenance][:set]==:on +            FileUtils::rm_r(@md.env.processing_path.epub) +          end +        else +          SiSU_Utils::CodeMarker.new(__LINE__,__FILE__,:fuchsia).mark('*EXITED epub* zip program not found') unless SiSU_Env::SystemCall.new.zip +        end +      end +      def make_cover_image +        begin +          if @md.make.cover_image? \ +          and @md.make.cover_image.is_a?(Hash) \ +          and @md.make.cover_image[:cover] =~/\S+/ +            filename_xhtml=@make_file.epub.xhtml_cover_image +            cover_image=<<WOK +<?xml version='1.0' encoding='utf-8'?> +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" +   "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml"> +  <head> +    <title>Cover</title> +    <meta http-equiv="Content-Type" content='text/html; charset=utf-8' /> +    <link rel="stylesheet" href="css/xhtml.css" type="text/css" /> +    <style type="text/css"> img { max-width: 100%; } </style> +  </head> +  <body xml:lang="en"> +    <div class="svg_outer"> +      <div class="svg_inner"> +        <svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xl="http://www.w3.org/1999/xlink" width="100%" height="100%" viewBox="0 0 #{@md.make.cover_image[:w]} #{@md.make.cover_image[:h]}" preserveAspectRatio="xMidYMid meet"> +        <image width="#{@md.make.cover_image[:w]}" height="#{@md.make.cover_image[:h]}" xl:href="image/#{@md.make.cover_image[:cover]}" /> +        </svg> +      </div> +    </div> +  </body> +</html> +WOK +            filename_xhtml.puts cover_image,"\n" +            filename_xhtml.close +          end +        rescue +          SiSU_Errors::Rescued.new($!,$@,@md.opt.selections.str,@md.fns).location do +            __LINE__.to_s + ':' + __FILE__ +          end +        end +      end +      def make_segtoc +        begin +          if @make.build.toc? +            filename_xhtml=@make_file.epub.xhtml_index +            @output.each do |para| +              para=para.strip +              unless para =~/\A\s*\Z/ +                filename_xhtml.puts para,"\n" +              end +            end +            filename_xhtml.close +          end +        rescue +          SiSU_Errors::Rescued.new($!,$@,@md.opt.selections.str,@md.fns).location do +            __LINE__.to_s + ':' + __FILE__ +          end +        end +      end +    end +  end +end +__END__ +#+END_SRC + +** xhtml_epub2_concordance.rb + +#+BEGIN_SRC ruby  :tangle "../lib/sisu/xhtml_epub2_concordance.rb" +# <<sisu_document_header>> +module SiSU_XHTML_EPUB2_Concordance +  require_relative 'se_hub_particulars'                 # se_hub_particulars.rb +    include SiSU_Particulars +  require_relative 'se'                                 # se.rb +    include SiSU_Env +  require_relative 'xhtml_parts'                        # xhtml_parts.rb +  require_relative 'xhtml_epub2_format'                 # xhtml_epub2_format.rb +    include SiSU_XHTML_EPUB2_Format +  class Source +    def initialize(opt) +      @opt=opt +      @particulars=SiSU_Particulars::CombinedSingleton.instance.get_all(opt) +    end +    def read +      begin +        @env,@md=@particulars.env,@particulars.md +        wordmax=@env.concord_max +        unless @md.wc_words.nil? +          if @md.wc_words < wordmax +            SiSU_XHTML_EPUB2_Concordance::Source::Words.new(@particulars).songsheet +          else +            SiSU_Screen::Ansi.new( +              @md.opt.act[:color_state][:set], +              "*WARN* concordance skipped, large document has over #{wordmax} words (#{@md.wc_words})" +            ).warn unless @md.opt.act[:quiet][:set]==:on +          end +        else +          SiSU_Screen::Ansi.new( +            @md.opt.act[:color_state][:set], +            "*WARN* wc (word count) is off, concordance will be processed for all files including those over the max set size of: #{wordmax} words" +          ).warn unless @md.opt.act[:quiet][:set]==:on +          SiSU_XHTML_EPUB2_Concordance::Source::Words.new(@particulars).songsheet +        end +      rescue +        SiSU_Errors::Rescued.new($!,$@,@md.opt.selections.str,@md.fns).location do +          __LINE__.to_s + ':' + __FILE__ +        end +      ensure +      end +    end +    private +    class DocTitle +      #revisit, both requires (html & xml_shared) needed for stand alone operation (sisu -w [filename]) +      require_relative 'xhtml_epub2'                    # xhtml_epub2.rb +      def initialize(particulars) +        @particulars,@md=particulars,particulars.md +        @data=SiSU_XHTML_EPUB2::Source::XHTML_Environment.new(particulars).tuned_file_instructions +        @fnb=@md.fnb +        @lex_button=%{<a href="http://www.jus.uio.no/sisu/" target="_top"><img border="0" height="44" width="144" valign="center" src="../_sisu/image/sisu.png" alt="SiSU home"></a>} +        @doc_details =<<WOK +<table summary="links to text related to this rudimentary index" width="96%" border="0" bgcolor="white" cellpadding="0" align="center"><tr><td width="2%" align="right">#{$ep[:hsp]}</td><td width="94%" valign="top" align="justify"><h1 class="small"><a href="#{@md.file.base_filename.epub}"><b>#{@md.title.full}</b></a></h1><p class="bold">#{@md.creator.author}</p></td></tr></table> +WOK +      end +      def create +        @css=SiSU_Env::CSS_Stylesheet.new(@particulars.md) +        format_head_toc=SiSU_XHTML_EPUB2_Format::HeadToc.new(@md) +        dochead=format_head_toc.head +        <<WOK +#{dochead} +<div class="content"> + #{@doc_details} +<p>Word index links are to html versions of the text the segmented version followed by the scroll (single document) version.<br />[For segmented text references [T1], [T2] or [T3] appearing without a link, indicates that the word appears in a title (or subtitle) of the text (that is identifiable by the appended object citation number).]</p> +<p>(The word listing/index is Case sensitive: Capitalized words appear before lower case)</p> +  <p> +    <b>word</b> (number of occurences)<br />linked references to word within document <br /> +    [if number of occurences exceed number of references - word occurs more than once in at least one reference. Footnote/endnotes are either assigned to the paragraph from which they are referenced or ignored, so it is relevant to check the footnotes referenced from within a paragraph as well.] +  </p> +  <p> +    (After the page is fully loaded) you can jump directly to a word by appending a hash (#) and the word to the url for this text, (do not forget that words are case sensitive, and may be listed twice (starting with and without an upper case letter)), #your_word # [#{$ep[:hsp]}http://[web host]/#{@fnb}/concordance.html#your_word#{$ep[:hsp]}] +  </p> +WOK +      end +    end +    class Word +      @@word_previous='' +      def initialize(word,freq) +        @word,@freq=word,freq +      end +      def html +        w=if @word.capitalize==@@word_previous +          %{\n<p class="concordance_word">#{@word}</p><p class="concordance_count">(#{@freq})</p>\n\t<p class="concordance_object"> } +        else n=@word.strip.gsub(/\s+/,'_') #also need to convert extended character set to html +          %{\n<p class="concordance_word"><a name="#{n}">#{@word}</a></p><p class="concordance_count">(#{@freq})</p>\n\t<p class="concordance_object"> } +        end +        @@word_previous=@word.capitalize +        w +      end +    end +    class Words +      require_relative 'xhtml_epub2_format'             # xhtml_epub2_format.rb +        include SiSU_XHTML_EPUB2_Format +      require_relative 'se'                             # se.rb +        include SiSU_Screen +      def initialize(particulars) +        @particulars=particulars +        begin +          @env,@md,@ao_array=particulars.env,particulars.md,particulars.ao_array +          @path="#{@env.processing_path.epub}" +          @freq=Hash.new(0) +          @rxp_lv0=/^#{Mx[:lv_o]}0:/ +          @rxp_lv1=/^#{Mx[:lv_o]}1:/ +          @rxp_lv2=/^#{Mx[:lv_o]}2:/ +          @rxp_lv3=/^#{Mx[:lv_o]}3:/ +          @rxp_seg=/^#{Mx[:lv_o]}4:(\S+?)#{Mx[:lv_c]}/ +          @rxp_title=Regexp.new("^#{Mx[:meta_o]}title#{Mx[:meta_c]}\s*(.+?)\s*$") +          @rxp_t0=Regexp.new('^T0') +          @rxp_t1=Regexp.new('^T1') +          @rxp_t2=Regexp.new('^T2') +          @rxp_t3=Regexp.new('^T3') +          @rxp_excluded1=/(?:https?|file|ftp):\/\/\S+/ +          @rxp_excluded0=/^(?:#{Mx[:fa_bold_o]}|#{Mx[:fa_italics_o]})?(?:to\d+|\d+| |#{Mx[:br_endnotes]}|EOF|#{Mx[:br_eof]}|thumb_\S+|snap_\S+|_+|-+|[(]?(?:ii+|iv|vi+|ix|xi+|xiv|xv|xvi+|xix|xx)[).]?|\S+?_\S+|[\d_]+\w\S+|[\w\d]{1,2}|\d{1,3}\w?|[0-9a-f]{16,64}|\d{2,3}x\d{2,3}|\S{0,2}sha\d|\S{0,3}\d{4}w\d\d|\b\w\d+|\d_all\b|e\.?g\.?)(?:#{Mx[:fa_bold_c]}|#{Mx[:fa_italics_c]})?$/mi #this regex causes and cures a stack dump in ruby 1.9 !!! +          @rgx_splitlist=%r{[—.,;:-]+|#{Mx[:nbsp]}+}mi +          @rgx_scanlist=%r{#{Mx[:fa_italics_o]}[a-zA-Z0-9"\s]{2,12}#{Mx[:fa_italics_c]}|#{Mx[:fa_bold_o]}[a-zA-Z0-9"\s]{2,12}#{Mx[:fa_bold_c]}|#{Mx[:url_o]}https?://\S+?#{Mx[:url_c]}|file://\S+|<\S+?>|\w+|[a-zA-Z]+}mi +        rescue +          SiSU_Errors::Rescued.new($!,$@,@md.opt.selections.str,@md.fns).location do +            __LINE__.to_s + ':' + __FILE__ +          end +        end +      end +      def songsheet +        begin +          #fix to use +          p __LINE__.to_s + ':' + __FILE__ +          p "#{@path}/content/#{@md.fn[:epub_concord]}" +          p "#{@md.file.output_path.epub.dir}/#{@md.file.base_filename.epub}" +          @file_concordance=File.open("#{@path}/content/#{@md.fn[:epub_concord]}",'w') +          map_para +        rescue +          SiSU_Errors::Rescued.new($!,$@,@md.opt.selections.str,@md.fns).location do +            __LINE__.to_s + ':' + __FILE__ +          end +        ensure +          @file_concordance.close +        end +      end +    protected +      def location_scroll(wordlocation,show) +        @wordlocation=wordlocation +        %{<a href="doc#{Sfx[:epub_xhtml]}\##{@wordlocation}">#{@wordlocation}</a>;  } +      end +      def location_seg(wordlocation,show) +        @wordlocation,@show=wordlocation,show +        @word_location_seg=wordlocation.gsub(/(.+?)\#(\d+)/,"\\1#{Sfx[:epub_xhtml]}#o\\2") unless wordlocation.nil? +        case @wordlocation +        when @rxp_t1 +          %{[<a href="doc#{Sfx[:epub_xhtml]}##{@show}">H</a>]#{@show},  } +        when @rxp_t2 +          %{[<a href="doc#{Sfx[:epub_xhtml]}##{@show}">H</a>]#{@show},  } +        when @rxp_t3 +          %{[<a href="doc#{Sfx[:epub_xhtml]}##{@show}">H</a>]#{@show},  } +        else %{<a href="#{@word_location_seg}">#{@show}</a>,  } +        end +      end +      def map_para +        @seg,toy=nil,nil +        @word_map={} +        @ao_array.each do |line| +          if defined? line.ocn +            if (line.is ==:heading \ +            || line.is ==:heading_insert) \ +            && line.ln==4 +              @seg=line.name +            end +            if line.ocn.to_s =~/\d+/ then toy=line.ocn.to_s +            end +            if toy =~/\d+/ \ +            and toy !~/^0$/ +              line.obj=line.obj.split(@rgx_splitlist).join(' ') #%take in word or other match +              for word in line.obj.scan(@rgx_scanlist) #%take in word or other match +                word=word.gsub(/#{Mx[:lnk_o]}|#{Mx[:lnk_c]}|#{Mx[:url_o]}|#{Mx[:url_c]}/,''). +                  gsub(/#{Mx[:fa_o]}\S+?#{Mx[:fa_o_c]}/,''). +                  gsub(/#{Mx[:fa_c_o]}\S+?#{Mx[:fa_c]}/,''). +                  gsub(/#{Mx[:gl_o]}#[a-z]+#{Mx[:gl_c]}/,''). +                  gsub(/#{Mx[:gl_o]}#[0-9]+#{Mx[:gl_c]}/,''). +                  gsub(/^\S$/,'') +                word=nil if word.empty? +                word=nil if word =~@rxp_excluded0 #watch +                word=nil if word =~@rxp_excluded1 #watch +                word=nil if word =~/^\S$/ +                if word +                  word=word.gsub(/#{Mx[:br_nl]}|#{Mx[:br_line]}/,' '). +                    gsub(/#{Mx[:fa_o]}[a-z]{1,7}#{Mx[:fa_o_c]}|#{Mx[:fa_c_o]}[a-z]{1,7}#{Mx[:fa_c]}/,''). +                    gsub(/#{Mx[:mk_o]}(?:[0-9a-f]{32}:[0-9a-f]{32}|[0-9a-f]{64}:[0-9a-f]{64})#{Mx[:mk_c]}/,''). +                    gsub(/#{Mx[:mk_o]}(?:[0-9a-f]{32}|[0-9a-f]{64})#{Mx[:mk_c]}/,''). +                    gsub(/#{Mx[:en_a_o]}(?:\d|[*+])*|#{Mx[:en_b_o]}(?:\d|[*+])*|#{Mx[:en_a_c]}|#{Mx[:en_b_c]}/mi,''). +                    gsub(/#{Mx[:fa_o]}\S+?#{Mx[:fa_o_c]}/,'').gsub(/#{Mx[:fa_c_o]}\S+?#{Mx[:fa_c]}/,''). +                    gsub(/<\/?\S+?>/,''). +                    gsub(/^\@+/,''). +                    strip. +                    gsub(/#{Mx[:tc_p]}.+/,''). +                    gsub(/[\.,;:"]$/,''). +                    gsub(/["]/,''). +                    gsub(/^\s*[\(]/,''). +                    gsub(/[\(]\s*$/,''). +                    gsub(/^(?:See|e\.?g\.?).+/,''). +                    gsub(/^\s*[.,;:]\s*/,''). +                    strip. +                    gsub(/^\(?[a-zA-Z]\)$/,''). +                    gsub(/^\d+(st|nd|rd|th)$/,''). +                    gsub(/^(\d+\.?)+$/, ''). +                    gsub(/#{Mx[:mk_o]}|#{Mx[:mk_c]}/,''). +                    gsub(/:name#\S+/,''). +                    gsub(/^\S$/,'') +                  word=nil if word =~/^\S$/ +                  word=nil if word =~/^\s*$/ #watch +                  if word +                    unless word =~/[A-Z][A-Z]/ \ +                    or word =~/\w+\s\w+/ +                      word=word.capitalize +                    end +                    @freq[word] +=1 +                    @word_map[word] ||= [] +                    if line !~@rxp_lv0 \ +                    and line !~@rxp_lv1 \ +                    and line !~@rxp_lv2 \ +                    and line !~@rxp_lv3 +                      @word_map[word] << location_seg("#{@seg}\##{toy}",toy) +                    else +                      @word_map[word] << case line +                      when @rxp_lv0 then location_seg('T0',toy) +                      when @rxp_lv1 then location_seg('T1',toy) +                      when @rxp_lv2 then location_seg('T2',toy) +                      when @rxp_lv3 then location_seg('T3',toy) +                      end +                    end +                  end +                end +              end +            end +          end +        end +        seg='' +        @file_concordance << SiSU_XHTML_EPUB2_Concordance::Source::DocTitle.new(@particulars).create +        alph=%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] +        @file_concordance << '<p>' +        alph.each {|x| @file_concordance << %{<a href="##{x}">#{x}</a>,#{$ep[:hsp]}}} +        @file_concordance << '</p>' +        letter=alph.shift +        @file_concordance << %{\n<p class="letter"><a name="A">A</a></p>} +        for word in @freq.keys.sort! {|a,b| a.downcase<=>b.downcase} +          f=/^(\S)/.match(word)[1] +          if letter < f.upcase +            while letter < f.upcase +              if alph.length > 0 +                letter=alph.shift +                @file_concordance << %{\n<p class="letter"><a name="#{letter}">#{letter}</a></p>} +              else break +              end +            end +          end +          keyword=SiSU_XHTML_EPUB2_Concordance::Source::Word.new(word,@freq[word]).html +          if keyword !~ @rxp_excluded0 +            if @word_map[word][0] =~ /\d+/ +              @file_concordance << %{#{keyword}#{seg}#{@word_map[word].uniq.compact.join}} +            end +            @file_concordance << '</p>' +          end +          # special cases endnotes and header levels 1 - 3 +        end +        credits=SiSU_Proj_XHTML::Bits.new.credits_sisu_epub +        @file_concordance << %{</div>#{credits}</body>\n</html>} # footer +      end +    end +  end +end +__END__ +#+END_SRC + +** xhtml_epub2_format.rb + +#+BEGIN_SRC ruby  :tangle "../lib/sisu/xhtml_epub2_format.rb" +# <<sisu_document_header>> +module SiSU_XHTML_EPUB2_Format +  class ParagraphNumber +    def initialize(md,ocn) +      @md,@ocn=md,ocn.to_s +      @ocn ||='' +    end +    def ocn_display +      make=SiSU_Env::ProcessingSettings.new(@md) +      if make.build.ocn? +        ocn_class='ocn' +        if @ocn==nil \ +        or @ocn.to_i==0 \ +        or @ocn.empty? +          %{<label class="ocn_off"></label>} +        else +          @ocn.gsub(/^(\d+|)$/, +            %{<label class="#{ocn_class}"><a href="#o\\1" class="lnk#{ocn_class}">\\1</a></label>}) +        end +      else +        %{<label class="ocn_off"></label>} +      end +    end +    def name +      (@ocn==nil || @ocn.empty?) ? '' : %{<a name="#{@ocn}"></a>} +    end +    def id #w3c? "tidy" complains about numbers as identifiers ! annoying +      (@ocn==nil || @ocn.empty?) ? '' : %{id="o#{@ocn}"} +    end +    def goto +      (@ocn==nil || @ocn.empty?) ? '' : %{<a href="##{@ocn}">} +    end +  end +  class CSS +    def css_epub_xhtml +      <<-WOK +/* SiSU epub css default stylesheet */ +  body { +    color: black; +    background: #ffffff; +    background-color: #ffffff; +  } +/* +    table { +      margin-left: 5%; +      display: block; +    } +    tr { +      display: block; +    } +    th,td { +      display: inline; +      vertical-align: top; +    } +*/ +  a:link { +    color: #003399; +    text-decoration: none; +  } +  a:visited { +    color: #003399; +    text-decoration: none; +  } +  a:hover { +    color: #000000; +    background-color: #f9f9aa; +  } +/* +  a:hover { +    border-bottom: 2px solid #777777; +    background-color: #fff3b6; +  } +*/ +  a:hover img { +    background-color: #ffffff; +  } +  a:active { +    color: #003399; +    text-decoration: underline; +  } +  a.lnkocn:link { +    color: #777777; +    text-decoration: none; +  } +  div { +    margin-left: 0; +    margin-right: 0; +  } +  div.p { +    margin-left: 5%; +    margin-right: 1%; +  } + +  .norm, .bold, .verse, .group, .block, .alt { +    line-height: 133%; +    margin-left: 0em; +    margin-right: 2em; +    margin-top: 12px; +    margin-bottom: 0px; +    padding-left: 0em; +    text-indent: 0mm; +  } +  p, h0, h1, h2, h3, h4, h5, h6, h7 { +    display: block; +    font-family: verdana, arial, georgia, tahoma, sans-serif, helvetica, times, roman; +    font-size: 100%; +    font-weight: normal; +    line-height: 133%; +    text-align: justify; +    margin-left: 0em; +    margin-right: 2em; +    text-indent: 0mm; +    margin-top: 0.8em; +    margin-bottom: 0.8em; +  } +  p.norm { } +  p.i1 {padding-left: 1em;} +  p.i2 {padding-left: 2em;} +  p.i3 {padding-left: 3em;} +  p.i4 {padding-left: 4em;} +  p.i5 {padding-left: 5em;} +  p.i6 {padding-left: 6em;} +  p.i7 {padding-left: 7em;} +  p.i8 {padding-left: 8em;} +  p.i9 {padding-left: 9em;} + +  p.h0i0 { +    padding-left: 0em; +    text-indent:  0em; +  } +  p.h0i1 { +    padding-left: 1em; +    text-indent: -1em; +  } +  p.h0i2 { +    padding-left: 2em; +    text-indent: -2em; +  } +  p.h0i3 { +    padding-left: 3em; +    text-indent: -3em; +  } +  p.h0i4 { +    padding-left: 4em; +    text-indent: -4em; +  } +  p.h0i5 { +    padding-left: 5em; +    text-indent: -5em; +  } +  p.h0i6 { +    padding-left: 6em; +    text-indent: -6em; +  } +  p.h0i7 { +    padding-left: 7em; +    text-indent: -7em; +  } +  p.h0i8 { +    padding-left: 8em; +    text-indent: -8em; +  } +  p.h0i9 { +    padding-left: 9em; +    text-indent: -9em; +  } + +  p.h1i0 { +    padding-left: 0em; +    text-indent:  1em; +  } +  p.h1i1 { +    padding-left: 1em; +    text-indent:  0em; +  } +  p.h1i2 { +    padding-left: 2em; +    text-indent: -1em; +  } +  p.h1i3 { +    padding-left: 3em; +    text-indent: -2em; +  } +  p.h1i4 { +    padding-left: 4em; +    text-indent: -3em; +  } +  p.h1i5 { +    padding-left: 5em; +    text-indent: -4em; +  } +  p.h1i6 { +    padding-left: 6em; +    text-indent: -5em; +  } +  p.h1i7 { +    padding-left: 7em; +    text-indent: -6em; +  } +  p.h1i8 { +    padding-left: 8em; +    text-indent: -7em; +  } +  p.h1i9 { +    padding-left: 9em; +    text-indent: -8em; +  } + +  p.h2i0 { +    padding-left: 0em; +    text-indent:  2em; +  } +  p.h2i1 { +    padding-left: 1em; +    text-indent:  1em; +  } +  p.h2i2 { +    padding-left: 2em; +    text-indent:  0em; +  } +  p.h2i3 { +    padding-left: 3em; +    text-indent: -1em; +  } +  p.h2i4 { +    padding-left: 4em; +    text-indent: -2em; +  } +  p.h2i5 { +    padding-left: 5em; +    text-indent: -3em; +  } +  p.h2i6 { +    padding-left: 6em; +    text-indent: -4em; +  } +  p.h2i7 { +    padding-left: 7em; +    text-indent: -5em; +  } +  p.h2i8 { +    padding-left: 8em; +    text-indent: -6em; +  } +  p.h2i9 { +    padding-left: 9em; +    text-indent: -7em; +  } + +  p.h3i0 { +    padding-left: 0em; +    text-indent:  3em; +  } +  p.h3i1 { +    padding-left: 1em; +    text-indent:  2em; +  } +  p.h3i2 { +    padding-left: 2em; +    text-indent:  1em; +  } +  p.h3i3 { +    padding-left: 3em; +    text-indent:  0em; +  } +  p.h3i4 { +    padding-left: 4em; +    text-indent: -1em; +  } +  p.h3i5 { +    padding-left: 5em; +    text-indent: -2em; +  } +  p.h3i6 { +    padding-left: 6em; +    text-indent: -3em; +  } +  p.h3i7 { +    padding-left: 7em; +    text-indent: -4em; +  } +  p.h3i8 { +    padding-left: 8em; +    text-indent: -5em; +  } +  p.h3i9 { +    padding-left: 9em; +    text-indent: -6em; +  } + +  p.h4i0 { +    padding-left: 0em; +    text-indent:  4em; +  } +  p.h4i1 { +    padding-left: 1em; +    text-indent:  3em; +  } +  p.h4i2 { +    padding-left: 2em; +    text-indent:  2em; +  } +  p.h4i3 { +    padding-left: 3em; +    text-indent:  1em; +  } +  p.h4i4 { +    padding-left: 4em; +    text-indent:  0em; +  } +  p.h4i5 { +    padding-left: 5em; +    text-indent: -1em; +  } +  p.h4i6 { +    padding-left: 6em; +    text-indent: -2em; +  } +  p.h4i7 { +    padding-left: 7em; +    text-indent: -3em; +  } +  p.h4i8 { +    padding-left: 8em; +    text-indent: -4em; +  } +  p.h4i9 { +    padding-left: 9em; +    text-indent: -5em; +  } + +  p.h5i0 { +    padding-left: 0em; +    text-indent:  5em; +  } +  p.h5i1 { +    padding-left: 1em; +    text-indent:  4em; +  } +  p.h5i2 { +    padding-left: 2em; +    text-indent:  3em; +  } +  p.h5i3 { +    padding-left: 3em; +    text-indent:  2em; +  } +  p.h5i4 { +    padding-left: 4em; +    text-indent:  1em; +  } +  p.h5i5 { +    padding-left: 5em; +    text-indent:  0em; +  } +  p.h5i6 { +    padding-left: 6em; +    text-indent: -1em; +  } +  p.h5i7 { +    padding-left: 7em; +    text-indent: -2em; +  } +  p.h5i8 { +    padding-left: 8em; +    text-indent: -3em; +  } +  p.h5i9 { +    padding-left: 9em; +    text-indent: -4em; +  } + +  p.h6i0 { +    padding-left: 0em; +    text-indent:  6em; +  } +  p.h6i1 { +    padding-left: 1em; +    text-indent:  5em; +  } +  p.h6i2 { +    padding-left: 2em; +    text-indent:  4em; +  } +  p.h6i3 { +    padding-left: 3em; +    text-indent:  3em; +  } +  p.h6i4 { +    padding-left: 4em; +    text-indent:  2em; +  } +  p.h6i5 { +    padding-left: 5em; +    text-indent:  1em; +  } +  p.h6i6 { +    padding-left: 6em; +    text-indent:  0em; +  } +  p.h6i7 { +    padding-left: 7em; +    text-indent: -1em; +  } +  p.h6i8 { +    padding-left: 8em; +    text-indent: -2em; +  } +  p.h6i9 { +    padding-left: 9em; +    text-indent: -3em; +  } + +  p.h7i0 { +    padding-left: 0em; +    text-indent:  7em; +  } +  p.h7i1 { +    padding-left: 1em; +    text-indent:  6em; +  } +  p.h7i2 { +    padding-left: 2em; +    text-indent:  5em; +  } +  p.h7i3 { +    padding-left: 3em; +    text-indent:  4em; +  } +  p.h7i4 { +    padding-left: 4em; +    text-indent:  3em; +  } +  p.h7i5 { +    padding-left: 5em; +    text-indent:  2em; +  } +  p.h7i6 { +    padding-left: 6em; +    text-indent:  1em; +  } +  p.h7i7 { +    padding-left: 7em; +    text-indent:  0em; +  } +  p.h7i8 { +    padding-left: 8em; +    text-indent: -1em; +  } +  p.h7i9 { +    padding-left: 9em; +    text-indent: -2em; +  } + +  p.h8i0 { +    padding-left: 0em; +    text-indent:  8em; +  } +  p.h8i1 { +    padding-left: 1em; +    text-indent:  7em; +  } +  p.h8i2 { +    padding-left: 2em; +    text-indent:  6em; +  } +  p.h8i3 { +    padding-left: 3em; +    text-indent:  5em; +  } +  p.h8i4 { +    padding-left: 4em; +    text-indent:  4em; +  } +  p.h8i5 { +    padding-left: 5em; +    text-indent:  3em; +  } +  p.h8i6 { +    padding-left: 6em; +    text-indent:  2em; +  } +  p.h8i7 { +    padding-left: 7em; +    text-indent:  1em; +  } +  p.h8i8 { +    padding-left: 8em; +    text-indent:  0em; +  } +  p.h8i9 { +    padding-left: 9em; +    text-indent: -1em; +  } + +  p.h9i0 { +    padding-left: 0em; +    text-indent:  9em; +  } +  p.h9i1 { +    padding-left: 1em; +    text-indent:  8em; +  } +  p.h9i2 { +    padding-left: 2em; +    text-indent:  7em; +  } +  p.h9i3 { +    padding-left: 3em; +    text-indent:  6em; +  } +  p.h9i4 { +    padding-left: 4em; +    text-indent:  5em; +  } +  p.h9i5 { +    padding-left: 5em; +    text-indent:  4em; +  } +  p.h9i6 { +    padding-left: 6em; +    text-indent:  3em; +  } +  p.h9i7 { +    padding-left: 7em; +    text-indent:  2em; +  } +  p.h9i8 { +    padding-left: 8em; +    text-indent:  1em; +  } +  p.h9i9 { +    padding-left: 9em; +    text-indent:  0em; +  } + +  p.it0 { +    margin-left: 0em; +    margin-top: 6px; +    margin-bottom: 0px; +    line-height: 100%; +  } +  p.it1 { +    margin-left: 1em; +    margin-top: 0px; +    margin-bottom: 0px; +    line-height: 100%; +  } +  p.it2 { +    margin-left: 2em; +    margin-top: 0px; +    margin-bottom: 0px; +    line-height: 100%; +  } +  p.it3 { +    margin-left: 3em; +    margin-top: 0px; +    margin-bottom: 0px; +    line-height: 100%; +  } +  p.it4 { +    margin-left: 4em; +    margin-top: 0px; +    margin-bottom: 0px; +    line-height: 100%; +  } +  p.it5 { +    margin-left: 5em; +    margin-top: 0px; +    margin-bottom: 0px; +    line-height: 100%; +  } +  p.it6 { +    margin-left: 6em; +    margin-top: 0px; +    margin-bottom: 0px; +    line-height: 100%; +  } +  p.it7 { +    margin-left: 7em; +    margin-top: 0px; +    margin-bottom: 0px; +    line-height: 100%; +  } +  p.it8 { +    margin-left: 8em; +    margin-top: 0px; +    margin-bottom: 0px; +    line-height: 100%; +  } +  p.it9 { +    margin-left: 9em; +    margin-bottom: 0px; +    margin-top: 0px; +    line-height: 100%; +  } + +  p.group { } + +  p.block { } + +  p.alt { } + +  p.verse { +    margin-bottom: 6px; +  } + +  p.code { +    font-family: inconsolata, andale mono, courier new, courier, monospace; +    font-size: 90%; +    text-align: left; +    background-color: #eeeeee; +  } + +  p.caption { +    text-align: left; +    font-size: 80%; +    display: inline; +  } + +  p.endnote { +    font-size: 96%; +    line-height: 120%; +    text-align: left; +    margin-right: 2em; +  } +  p.endnote_indent { +    font-size: 96%; +    line-height: 120%; +    text-align: left; +    margin-left: 2em; +    margin-right: 2em; +  } + +  p.center { +    text-align: center; +  } +  p.align_right { +    text-align: right; +  } +  p.bold { +    font-weight: bold; +  } +  p.bold_left { +    font-weight: bold; +    text-align: left; +  } +  p.centerbold { +    text-align: center; +    font-weight: bold; +  } +  p.em { +    font-weight: bold; +    font-style: normal; +    background: #fff3b6; +  } + +  p.small { +    font-size: 80%; +    margin-top: 0px; +    margin-bottom: 0px; +    margin-right: 6px; +    text-align: left; +  } + +  .tiny, .tiny_left, .tiny_right, .tiny_center { +    font-size: 10px; +    margin-top: 0px; +    margin-bottom: 0px; +    color: #777777; +    margin-right: 6px; +    text-align: left; +  } +  p.tiny { } +  p.tiny_left { +    margin-left: 0px; +    margin-right: 0px; +    text-align: left; +  } +  p.tiny_right { +    margin-right: 1em; +    text-align: right; +  } +  p.tiny_center { +    margin-left: 0px; +    margin-right: 0px; +    text-align: center; +  } + +  p.concordance_word { +    line-height: 150%; +    font-weight: bold; +    display: inline; +    margin-top: 4px; +    margin-bottom: 1px; +  } +  p.concordance_count { +    font-size: 80%; +    color: #777777; +    display: inline; +    margin-left: 0em; +  } +  p.concordance_object { +    font-size: 80%; +    line-height: 120%; +    text-align: left; +    margin-left: 3em; +    margin-top: 1px; +    margin-bottom: 3px; +  } +  p.book_index_lev1 { +    line-height: 100%; +    margin-top: 4px; +    margin-bottom: 1px; +  } +  p.book_index_lev2 { +    line-height: 100%; +    text-align: left; +    margin-left: 3em; +    margin-top: 1px; +    margin-bottom: 3px; +  } + +  p.quickref { +    font-size: 10px; +    font-style: italic; +    margin-top: 0px; +    margin-bottom: 0px; +    color: #777777; +    margin-right: 5px; +    text-align: left; +  } +  p.bigref { +    font-size: 11px; +    font-weight: bold; +    margin-top: 0px; +    margin-bottom: 0px; +    color: #777777; +    margin-right: 5px; +    text-align: center; +  } + +  p.letter { +    font-weight: bold; +    font-size: 80%; +    margin-left: 0em; +    margin-top: 2px; +    margin-bottom: 2px; +    margin-right: 6px; +    text-align: left; +    color: white; +    background: #880000; +  } + +  tt { +    font-family: inconsolata, andale mono, courier new, courier, monospace; +    background-color: #eeeeee; +  } + +  label.ocn { +    width: 2%; +    float: right; +    top: 0; +    font-size: 10px; +    margin-top: 0px; +    margin-bottom: 5px; +    color: #777777; +    margin-right: 5px; +    text-align: right; +    background-color: #ffffff; +  } + +  table { } +  tr { } +  th,td { +    vertical-align: top; +    text-align: left; +  } +  th { +    font-weight: bold; +  } + +  p.left, th.left, td.left { +    text-align: left; +  } +  p.small_left, th.small_left, td.small_left { +    text-align: left; +    font-size: 80%; +  } +  p.right, th.right, td.right { +    text-align: right; +  } + +  #horizontal_links { +    background: #eeeeee; +    margin-left: 5%; +    margin-right: 5%; +  } +  #horizontal { +    margin: 0; +    padding: 0 0 0 10px; +    border-top: 1px solid #000077; +    border-bottom: 1px solid #000077; +  } +  #horizontal li { +    margin: 0 0 0 0; +    padding: 0 16px 0 0; +    display: inline; +    list-style-type: none; +    text-align: left; +    background: none; +  } +  #horizontal a { +    line-height: 12px; +    margin: 0 0 0 0; +    text-decoration: none; +    color: #000077; +  } +  #horizontal a.active, #horizontal a:hover { +    border-bottom: 2px solid #777777; +    padding-bottom: 2px; +    color: #000077; +  } +  #horizontal a:hover { +    color: #000077; +  } + +  #document_versions { +    position: absolute; +    top: 10mm; +    right: 2%; +    width: 12%; +    float: right; +  } + +  #vertical_links { +    position: absolute; +    top: 10mm; +    right: 0px; +    width: 20%; +    background: #dddddd; +    float: right; +  } +  #vertical { +    padding: 0 12px 0px 0px; +    margin-left: 2%; +    margin-right: 2%; +  } +  #vertical li { +    display: block; +    list-style-type: none; +  } +  #vertical a { +    line-height: 12px; +    text-decoration: none; +    color: #000077; +  } +  #vertical a.active, #vertical a:hover { +    border-bottom: 2px solid #777777; +    padding-bottom: 2px; +    color: #000077; +  } + +  ul, li { +    list-style-type: none; +    list-style: none; +    padding-left: 20px; +    display: block; +    font-family: verdana, arial, georgia, tahoma, sans-serif, helvetica, times, roman; +    font-weight: normal; +    line-height: 150%; +    text-align: justify; +    text-indent: 0mm; +    margin-left: 1em; +    margin-right: 2em; +    margin-top: 3px; +    margin-bottom: 3px; +  } + +  li { +    background: url(../image/bullet_09.png) no-repeat 0px 6px; +  } + +  ul { +  } +  li.bullet { margin-left: 0em; } +  li.i1 { margin-left: 1em; } +  li.i2 { margin-left: 2em; } +  li.i3 { margin-left: 3em; } +  li.i4 { margin-left: 4em; } +  li.i5 { margin-left: 5em; } +  li.i6 { margin-left: 6em; } +  li.i7 { margin-left: 7em; } +  li.i8 { margin-left: 8em; } +  li.i9 { margin-left: 9em; } + +  li.doc, li.ref, li.refcenter { +    margin-top: 0px; +    margin-bottom: 0px; +    margin-right: 0px; +    font-size: 8px; +    font-style: normal; +    text-align: left; +  } +  li.doc { +    background: url(../image/bullet_09.png) no-repeat 0px 6px; +    padding-left: 16px; +    margin-left: 10px; +    margin-right: 0px; +  } +  li.ref { +    background: none; +    padding-left: 0; +    margin-left: 0; +    color: #777777; +  } +  li.refcenter { +    background: url(../image/bullet_09.png) no-repeat 0px 6px; +    padding-left: 20px; +    margin-left: 10%; +    font-size: 9px; +    color: #777777; +    text-align: center; +  } +  li.refbold { +    list-style-type: none; +    padding-left: 16px; +    margin-left: 0; +    margin-right: 10mm; +    font-weight: bold; +  } + +  h0, h1, h2, h3, h4, h5, h6, h7 { +    font-weight: bold; +    line-height: 120%; +    text-align: left; +    margin-top: 20px; +    margin-bottom: 10px; +  } +  h4.norm, h5.norm, h6.norm, h7.norm { +    margin-top: 10px; +    margin-bottom: 0px; +  } +  h1.center, h2.center, h3.center, h4.center, h5.center, h6.center, h7.center { +    text-align: center; +  } +  h1 { font-size: 120%; } +  h2 { font-size: 115%; } +  h3 { font-size: 110%; } +  h4 { font-size: 105%; } +  h5 { font-size: 100%; } +  h6 { font-size: 100%; } +  h7 { font-size: 100%; } +  h0 { font-size: 80%; } + +  h1.i {margin-left: 2em;} +  h2.i {margin-left: 3em;} +  h3.i {margin-left: 4em;} +  h4.i {margin-left: 5em;} +  h5.i {margin-left: 6em;} +  h6.i {margin-left: 7em;} +  h7.i {margin-left: 8em;} +  h8.i {margin-left: 9em;} +  h9.i {margin-left: 10em;} + +  .toc { +    font-weight: normal; +    margin-top: 6px; +    margin-bottom: 6px; +  } +  h1.toc { +    margin-left: 1em; +    font-size: 115%; +    line-height: 150%; +  } +  h2.toc { +    margin-left: 2em; +    font-size: 110%; +    line-height: 140%; +  } +  h3.toc { +    margin-left: 3em; +    font-size: 105%; +    line-height: 120%; +  } +  h4.toc { +    margin-left: 4em; +    font-size: 100%; +    line-height: 120%; +  } +  h5.toc { +    margin-left: 5em; +    font-size: 95%; +    line-height: 110%; +  } +  h6.toc { +    margin-left: 6em; +    font-size: 90%; +    line-height: 110%; +  } +  h7.toc { +    margin-left: 7em; +    font-size: 90%; +    line-height: 105%; +  } + +  .microtoc { +    margin-top: 2px; +    margin-bottom: 2px; +  } + +  h1.microtoc { +    margin-left: 0mm; +    font-size: 115%; +  } +  h2.microtoc { +    margin-left: 5mm; +    font-size: 110%; +  } +  h3.microtoc { +    margin-left: 10mm; +    font-size: 105%; +  } +  h4.microtoc { +    margin-left: 15mm; +    font-weight: normal; +    font-size: 100%; +  } +  h5.microtoc { +    margin-left: 20mm; +    font-weight: normal; +    font-size: 95%; +  } +  h6.microtoc { +    margin-left: 25mm; +    font-weight: normal; +    font-size: 90%; +  } +  h7.microtoc { +    margin-left: 30mm; +    font-weight: normal; +    font-size: 85%; +  } + +  .subtoc { +    margin-right: 34%; +    font-weight: normal; +  } +  h5.subtoc { +    margin-left: 2em; +    font-size: 80%; +    margin-top: 2px; +    margin-bottom: 2px; +  } +  h6.subtoc { +    margin-left: 3em; +    font-size: 75%; +    margin-top: 0px; +    margin-bottom: 0px; +  } +  h7.subtoc { +    margin-left: 4em; +    font-size: 70%; +    margin-top: 0px; +    margin-bottom: 0px; +  } + +  div.substance { +    width: 100%; +    background-color: #ffffff; +  } +  div.ocn { +    width: 5%; +    float: right; +    top: 0; +    background-color: #ffffff; +  } +  div.endnote { +    width: 100%; +    background-color: #fffffff; +  } +  div.toc { +    position: absolute; +    float: left; +    margin: 0; +    padding: 0; +    padding-top: 0.5em; +    border: 0; +    width: 5%; +    background-color: #eeeeee; +    margin-right:1em; +  } +  div.summary { +    margin: 0; +    padding: 0; +    border-left: 2em solid #eeeeee; +    padding-left: 0em; +    background-color: #eeeeee; +  } +  div.content, div.main_column { +    margin: 0; +    padding: 0; +    border-left: 0% solid #ffffff; +    padding-left: 5%; +  } +  div.content:after { +    content:' '; +    clear:both; +    display:block; +    height:0; +    overflow:hidden +  } +  div.footer { +    clear:left; +    padding: 0.5em; +    font-size: 80%; +    margin: 0; +  } +  div.toc ul { +    list-style: none; +    padding: 0; +    margin: 0; +  } +  div.toc li ul a, li ul span.currentlink +  { +    font-weight: normal; +    font-size: 90%; +    padding-left: 2em; +    background-color: #eeeeee; +  } +  div.toc a, span.currentlink{ +    display:block; +    text-decoration: none; +    padding-left: 0.5em; +    color: #0000aa; +  } +  hr { +    width: 90%; +  } + +  span.currentlink { +    text-decoration: none; +    background-color: #aaaaf9; +  } + +  div.toc a:visited { +    color: #0000aa; +  } +  div.toc a:hover { +    color: #000000; +    background-color: #f9f9aa; +  } + +  h1.c, h2.c, h3.c, h4.c, h5.c, h6.c, h7.c, p.c { +    text-align: center +  } +  h1.red, h2.red, h3.red, h4.red, h5.red, h6.red, h7.red { +    text-align: center; +    color: #ff0000; +    margin-left: 5mm; +    text-indent: 5mm; +    margin-top: 30px; +    margin-bottom: 20px; +    margin-right: 15mm; +  } +  h1.ruby, h2.ruby, h3.ruby, h4.ruby, h5.ruby, h6.ruby, h7.ruby { +    text-align: center; +    color: #990000; +    margin-left: 5mm; +    text-indent: 5mm; +    margin-top: 30px; +    margin-bottom: 20px; +    margin-right: 15mm; +  } +      WOK +    end +  end +  module SanitizeXML +    require_relative 'xhtml_parts'                        # xhtml_parts.rb +    def self.xml(x) +      if x.is_a?(String) +        x=x.gsub(/ /,' ') if Ep[:alt]==:on +        x.gsub(/&/,'&'). +          gsub(/</,"<").gsub(/>/,">"). +          gsub(/#{Dx[:url_o]}/,Dx[:url_o_xml]).gsub(/#{Dx[:url_c]}/,Dx[:url_c_xml]). +          #gsub(/</,'<').gsub(/>/,'>'). +          gsub(/\\\\/,'<br />'). +          gsub(/<br(?: \/)?>/,'<br />') +      else x +      end +    end +  end +  class HeadInformation +    attr_reader :md,:rdf +    def initialize(md) +      @md=md +      # DublinCore 1 - title +      @css=SiSU_Env::CSS_Stylesheet.new(md) +      @per=SiSU_XHTML_EPUB2_Persist::Persist.new +      @per.seg_name_x=SiSU_XHTML_EPUB2::Seg.new.seg_name_x +      @per.seg_name_x_tracker=SiSU_XHTML_EPUB2::Seg.new.seg_name_x_tracker +      @tocband_scroll,@tocband_segtoc=nil,nil +      @index,@metalink='index','#metadata' +    end +    def doc_type_xhtml +      <<-WOK +<?xml version='1.0' encoding='utf-8'?> +<html xmlns="http://www.w3.org/1999/xhtml"> +      WOK +    end +=begin +~/epub +  |-- META-INF +  |   `-- container.xml                # simple, make sure full-path of rootfile points to metadata.opf +  |-- content +  |   |-- 1.xhtml +  |   |-- 2.xhtml +  |   |-- 3.xhtml +  |   |-- ... .xhtml +  |   |-- concordance.xhtml +  |   |-- css +  |   |   `-- xhtml.css +  |   |-- endnotes.xhtml +  |   |-- image +  |   |   |-- arrow_next_red.png +  |   |   |-- arrow_prev_red.png +  |   |   |-- arrow_up_red.png +  |   |   `-- bullet_09.png +  |   |-- index.xhtml +  |   |-- meta.xhtml +  |   |-- metadata.xhtml +  |   `-- toc.xhtml +  |-- metadata.opf                     #(i) metadata dc; (ii) manifest (contents); (iii) spine (mimetypes) +  |-- mimetype                         # application/epub+zip +  `-- toc.ncx                          #(i) head (ii) doc title (iii) navmap, list of navigation points (like chapters) +=end +    def doc_type +      doc_type_xhtml +    end +    def mimetype +      <<-WOK +application/epub+zip +      WOK +    end +    def metainf_container #container.xml file in META-INF directory +      #simple, make sure full-path of rootfile points to metadata.opf +      #epub_metadata.opf content.opf +      <<-WOK +<?xml version='1.0' encoding='utf-8'?> +<container version="1.0" +  xmlns="urn:oasis:names:tc:opendocument:xmlns:container"> +  <rootfiles> +    <rootfile full-path="#{Ep[:d_oebps]}/#{Ep[:f_opf]}" +      media-type="application/oebps-package+xml" /> +  </rootfiles> +</container> +      WOK +    end +    def sections(dob,fn_base) +      name=fn_base + Sfx[:epub_xhtml] +      dir_epub_cont=@md.env.processing_path.epub + '/' + Ep[:d_oebps] +      segfilename=dir_epub_cont + '/' + name +      output_epub_cont_seg=File.new(segfilename,'w') +      txt=dob.obj.gsub(/#{Mx[:en_a_o]}.+?#{Mx[:en_a_c]}|#{Mx[:en_b_o]}.+?#{Mx[:en_b_c]}/,'') +      output_epub_cont_seg << %{#{doc_type} +  <head> +    <title> +      #{dob.obj} - +      #{@md.html_title} +    </title> +    <meta http-equiv='Content-Type' content='text/html; charset=utf-8' /> +    #{@css.xhtml_epub} +  </head> +    <body lang="#{@md.opt.lng}"> +    <div class="content"> +      <div class="substance"> +        <label class="ocn"><a href="#o#{dob.ocn}" class="lnkocn">#{dob.ocn}</a></label> +        <h1 class="norm" id="o#{dob.ocn}"> +          #{txt} +        </h1> +      </div> +    </div> +    </body> +  </html>} +output_epub_cont_seg.close +    end +    def toc_ncx #list of navigation points (like chapters), table of contents, listing each navigation point (chapters and such) under the navigation map +      def structure +        open +        head_open +        head +        head_close +        doc_title +        doc_author +        navmap_open +       #navmap ... +        navmap_close +        close +      end +      def open +        <<-WOK +<?xml version='1.0' encoding='utf-8'?> +<ncx xmlns="http://www.daisy.org/z3986/2005/ncx/" version="2005-1"> +        WOK +      end +      def close +        <<-WOK +</ncx> +        WOK +      end +      def head_open +        <<-WOK +  <head> +        WOK +      end +      def head +        depth=@md.lvs[1] + @md.lvs[2] + @md.lvs[3] + @md.lvs[4] +        title=SanitizeXML.xml(@md.title.full) +        author=SanitizeXML.xml(@md.author) +        dgst=(@md.dgst.is_a?(Array) and @md.dgst.length > 1) ? @md.dgst[1] : 'na' +        <<-WOK +    <!-- four required metadata items (for all NCX documents, +      (including the relaxed constraints of OPS 2.0) --> +    <title>#{title} by #{author}</title> +    <link href="css/xhtml.css" rel="stylesheet" type="text/css" id="main-css" /> +    <meta name="dtb:uid" content="urn:uuid:#{dgst}" /> +    <!-- <meta name="epub-creator" content="#{@md.publisher}" /> --> +    <meta name="dtb:depth" content="#{depth}" /> +    <meta name="dtb:totalPageCount" content="0" /> +    <meta name="dtb:maxPageNumber" content="0" /> +        WOK +      end +      def head_close +        <<-WOK +  </head> +        WOK +      end +      def doc_title +        txt=SanitizeXML.xml(@md.title.full) +        <<-WOK +  <docTitle> +    <text>#{txt}</text> +  </docTitle> +        WOK +      end +      def doc_author +        txt=SanitizeXML.xml(@md.author) +        <<-WOK +  <docAuthor> +    <text>#{txt}</text> +  </docAuthor> +        WOK +      end +      def navmap_open +        <<-WOK +  <navMap> +        WOK +      end +      def navmap_sisu_toc(no) +        id_u=DISABLE[:epub][:ncx_navpoint_unique_id] \ +        ? '' +        : "-#{no}" +        <<-WOK +      <navPoint id="navpoint#{id_u}" playOrder="#{no}"> +        <navLabel> +          <text>Table of Contents</text> +        </navLabel> +        <content src="index#{Sfx[:epub_xhtml]}" /> +      </navPoint> +        WOK +      end +      def navpoint(dob,no,fn_base,hashtag=nil) +        fn=fn_base + Sfx[:epub_xhtml] +        name=hashtag ? fn + hashtag : fn +        id_u=DISABLE[:epub][:ncx_navpoint_unique_id] \ +        ? '' +        : "-#{no}" +        txt=dob.obj.gsub(/#{Mx[:en_a_o]}.+?#{Mx[:en_a_c]}|#{Mx[:en_b_o]}.+?#{Mx[:en_b_c]}/,'') +        <<-WOK +      <navPoint class="chapter" id="navpoint#{id_u}" playOrder="#{no}"> +        <navLabel> +          <text>#{txt}</text> +        </navLabel> +        <content src="#{name}" /> +        WOK +      end +      def navpoint_close +        <<-WOK +      </navPoint> +        WOK +      end +      def navmap_close +        <<-WOK +  </navMap> +        WOK +      end +      self +    end +    def metadata_opf #(i) metadata dc; (ii) manifest (contents); (iii) spine (mimetypes) +      def structure +        package_open +        metadata_open +        metadata_close +        manifest_open +        manifest_close +        spine_open +        spine_close +        guide_open +        guide_close +        package_close +      end +      def package_open +        <<-WOK +<?xml version='1.0' encoding='utf-8'?> +<package xmlns="http://www.idpf.org/2007/opf" version="2.0" unique-identifier="EPB-UUID"> +        WOK +      end +      def package_close +        <<-WOK +</package> +        WOK +      end +      def metadata #metadata dc +        cover_image=if defined? @md.make.cover_image \ +        and @md.make.cover_image.is_a?(Hash) \ +        and @md.make.cover_image[:cover] =~/\S+/ +          %{\n    <#{$ep[:o]}meta name="cover" content="cover_image" />} +        else '' +        end +        author=if defined? @md.creator.author \ +        and @md.creator.author =~/\S+/ +          m='' +          @md.creator.author_detail.each do |i| +            surname=i[:the] \ +            ? i[:the] +            : '' +            other_names=i[:others] \ +            ? ', ' + i[:others] +            : '' +            m=(m.empty?) \ +            ? (surname + other_names) +            : (m + '; ' + surname + ', ' + other_names) +            m=SanitizeXML.xml(m) +          end +          x=@md.creator.author.dup +          x=SanitizeXML.xml(x) +          %{\n    <dc:creator opf:file-as="#{m}" opf:role="aut">#{x}</dc:creator>} +        else '' +        end +        editor=if defined? @md.creator.editor \ +        and @md.creator.editor =~/\S+/ +          m='' +          @md.creator.editor_detail.each do |i| +            surname=i[:the] \ +            ? i[:the] +            : '' +            other_names=i[:others] \ +            ? ', ' + i[:others] +            : '' +            m=(m.empty?) \ +            ? (surname + other_names) +            : (m + '; ' + surname + ', ' + other_names) +            m=SanitizeXML.xml(m) +          end +          x=@md.creator.editor.dup +          x=SanitizeXML.xml(x) +          %{\n    <dc:creator opf:file-as="#{m}" opf:role="edt">#{x}</dc:creator>} +        else '' +        end +        translator=if defined? @md.creator.translator \ +        and @md.creator.translator =~/\S+/ +          m='' +          @md.creator.translator_detail.each do |i| +            surname=i[:the] \ +            ? i[:the] +            : '' +            other_names=i[:others] \ +            ? ', ' + i[:others] +            : '' +            m=(m.empty?) \ +            ? (surname + other_names) +            : (m + '; ' + surname + ', ' + other_names) +            m=SanitizeXML.xml(m) +          end +          x=@md.creator.translator.dup +          x=SanitizeXML.xml(x) +          %{\n    <dc:creator opf:file-as="#{m}" opf:role="trl">#{x}</dc:creator>} +        else '' +        end +        illustrator=if defined? @md.creator.illustrator \ +        and @md.creator.illustrator =~/\S+/ +          m='' +          @md.creator.illustrator_detail.each do |i| +            surname=i[:the] \ +            ? i[:the] +            : '' +            other_names=i[:others] \ +            ? ', ' + i[:others] +            : '' +            m=(m.empty?) \ +            ? (surname + other_names) +            : (m + '; ' + surname + ', ' + other_names) +            m=SanitizeXML.xml(m) +          end +          x=@md.creator.illustrator.dup +          x=SanitizeXML.xml(x) +          %{\n    <dc:creator opf:file-as="#{m}" opf:role="ill">#{x}</dc:creator>} +        else '' +        end +        date_published=if defined? @md.date.published \ +        and @md.date.published =~/\S+/ +          x=@md.date.published.dup +          x=SanitizeXML.xml(x) +          %{\n    <dc:date opf:event="published">#{x}</dc:date>} +        else '' +        end +        subject=if defined? @md.classify.subject \ +        and @md.classify.subject =~/\S+/ +          x=@md.classify.subject.dup +          x=SanitizeXML.xml(x) +          %{\n    <dc:subject>#{x}</dc:subject>} +        else '' +        end +        language=if defined? @md.opt.lng \ +        and @md.opt.lng =~/\S+/ +          language=@md.opt.lng.gsub(/<br>/,'<br />') +          %{\n    <dc:language>#{language}</dc:language>} +        else '' +        end +        rights=if defined? @md.rights.all \ +        and @md.rights.all =~/\S+/ +          rights=SanitizeXML.xml(@md.rights.all) +          rights=rights.gsub(/<br\s*\/?>/,' ') +          %{\n    <dc:rights>#{rights}</dc:rights>} +        else '' +        end +        f=SiSU_Env::FileOp.new(@md) +        dgst=(@md.dgst.is_a?(Array) and @md.dgst.length > 1) ? @md.dgst[1] : 'na' +        <<-WOK +  <#{$ep[:o]}metadata +    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" +    xmlns:opf="http://www.idpf.org/2007/opf" +    xmlns:dcterms="http://purl.org/dc/terms/" +    xmlns:dc="http://purl.org/dc/elements/1.1/" +    unique-identifier="urn:uuid:#{dgst}" version="2.0"> +    <dc:title>#{@md.title.full}</dc:title> +    #{cover_image}#{author}#{editor}#{translator}#{illustrator}#{language}#{date_published}#{subject}#{rights} +    <dc:identifier opf:scheme="URI">#{f.output_path.epub.url.gsub(/http:\/\//,'')}/#{f.base_filename.epub}</dc:identifier> +    <dc:identifier id="bookid">urn:uuid:#{dgst}</dc:identifier> +    <!-- <dc:identifier id="EPB-UUID">urn:uuid:#{dgst}</dc:identifier> --> +  </#{$ep[:o]}metadata> +        WOK +      end +      def manifest_open +        <<-WOK +  <manifest> +    <!-- NCX --> +    <item id="ncx" href="#{Ep[:f_ncx]}" media-type="application/x-dtbncx+xml" /> +    <!-- CSS Style Sheets --> +    <item id="main-css" href="css/xhtml.css" media-type="text/css" /> +    <!-- Content Documents --> +        WOK +      end +      def manifest_content_sisu_toc +        <<-WOK +    <item id="index#{Sfx[:epub_xhtml]}" href="index#{Sfx[:epub_xhtml]}" media-type="application/xhtml+xml" /> +        WOK +      end +      def manifest_cover_image_information(md) +        if defined? md.make.cover_image \ +        and @md.make.cover_image.is_a?(Hash) \ +        and md.make.cover_image[:cover] =~/\S+/ +          <<-WOK +    <item id="cover_image#{Sfx[:epub_xhtml]}" href="cover_image#{Sfx[:epub_xhtml]}" media-type="application/xhtml+xml" /> +          WOK +        else '' +        end +      end +      def manifest_content(dob,fn_base,hashtag=nil) +         fn=fn_base + Sfx[:epub_xhtml] +         name=hashtag ? fn + hashtag : fn +        <<-WOK +    <item id="#{name}" href="#{name}" media-type="application/xhtml+xml" /> +        WOK +      end +      def manifest_images(imgs) +        imgs=imgs + ['arrow_next_red.png','arrow_prev_red.png','arrow_up_red.png','bullet_09.png'] +        images=["    <!-- Images -->\n"] +        imgs.each do |i| +          image,type=/(\S+?)\.(png|jpg|gif)/.match(i)[1,2] +          type=type.sub(/jpg/,'jpeg') +          images<<<<-WOK +    <item id="#{image}" href="image/#{image}.#{type}" media-type="image/#{type}" /> +          WOK +        end +        images=images.join('') +        images +      end +      def manifest_close +        <<-WOK +  </manifest> +        WOK +      end +      def spine_open +        #spine: reading order of XHTML files from manifest, idref attribute refers back to id in manifest (exclude images, CSS etc.). +        <<-WOK +  <spine toc="ncx"> +        WOK +      end +      def spine_cover_image +        <<-WOK +    <itemref idref="cover_image#{Sfx[:epub_xhtml]}" /> +        WOK +      end +      def spine_sisu_toc +        <<-WOK +    <itemref idref="index#{Sfx[:epub_xhtml]}" linear="yes" /> +        WOK +      end +      def spine(dob,fn_base,hashtag=nil) +         fn=fn_base + Sfx[:epub_xhtml] +         name=hashtag ? fn + hashtag : fn +        <<-WOK +    <itemref idref="#{name}" linear="yes" /> +        WOK +      end +      def spine_close +        <<-WOK +  </spine> +        WOK +      end +      def guide_open +        #guide: presentation order of XHTML files by reader). +        <<-WOK +  <guide> +        WOK +      end +      def guide_cover_image +        <<-WOK +    <reference type="cover" title="Cover of #{SanitizeXML.xml(@md.title.full)}" href="cover_image#{Sfx[:epub_xhtml]}" /> +        WOK +      end +      def guide_sisu_toc +        <<-WOK +    <reference type="index#{Sfx[:epub_xhtml]}" href="index#{Sfx[:epub_xhtml]}" /> +        WOK +      end +      def guide(dob,fn_base,hashtag=nil) +         fn=fn_base + Sfx[:epub_xhtml] +         name=hashtag ? fn + hashtag : fn +        name=name ? name : dob.name +        guide_name=(name =~/#{Sfx[:epub_xhtml]}/) ? name : (name + Sfx[:epub_xhtml]) +        <<-WOK +    <reference type="text" href="#{guide_name}" /> +        WOK +      end +      def guide_close +        <<-WOK +  </guide> +        WOK +      end +      self +    end +    def table_close +      %{  </font> +#{the_table_close}} +    end +    def xhtml_close +    %{#{SiSU_Proj_XHTML::Bits.new.credits_sisu_epub} +  </body> +</html>} +    end +  end +  class HeadToc < HeadInformation +    include SiSU_Parts_XHTML +    def initialize(md) +      super(md) +      @md=md +      @tocband_segtoc=make_seg +    end +    def manifest_link(text) +  %{ <a href="#{@md.file.output_path.manifest.url}/#{@md.file.base_filename.manifest}" target="_top">#{text}</a>} +    end +    def concordance_link(text) +      if @md.concord_make +  %{<a href="#{@md.file.base_filename.html_concordance}" target="_top"> +      #{text} +    </a>} +      else '' +      end +    end +    def head +      %{#{doc_type} +  <head> +    <meta http-equiv='Content-Type' content='text/html; charset=utf-8' /> +    #{@css.xhtml_epub} +  </head> +    <body lang="#{@md.opt.lng}">} +    end +    def concordance +      if @md.concord_make +      %{#{the_margin.css} +      <h4 class="toc"> +        <a href="./#{@md.file.base_filename.html_concordance}"> +          <i>Concordance</i> +        </a> +      </h4> +#{the_table_close}} +      else +      %{#{the_margin.css} +#{the_table_close}} +      end +    end +    def links_guide_open(type='horizontal') +      (type=='vertical') \ +      ? links_guide_vertical_open +      : links_guide_horizontal_open +    end +    def prefix_a +    end +    def rights +      def all +        rights=SanitizeXML.xml(@md.rights.all) +        %{<p class="small_left">Rights: #{rights}</p>} +      end +      self +    end +    def prefix_b +      %{<p class="small_left">Prefix: #{@md.prefix_b}} +    end +    def make_seg +      concord=concordance_link(the_nav.txt_concordance) +      %{<table summary="toc segment" border="0" cellpadding="3" cellspacing="0"> +<tr><td align="center" bgcolor="white"> +  #{the_nav.txt_toc_link} +</td> +<td align="center" bgcolor="white"> +  <font size=2> +   #{concord} +#{the_table_close}} +    end +    def manifest #check structure +      manifest=manifest_link(the_nav.txt_manifest) +      %{#{the_margin.txt_3} +  #{the_font.paragraph_font_small} +   #{manifest} +    </font> +#{the_table_close}} +    end +    def concordance #check structure +      concord=concordance_link(the_nav.txt_concordance) +      %{#{the_margin.txt_3} +  #{the_font.paragraph_font_small} +   #{concord} +    </font> +#{the_table_close}} +    end +    def metadata +      %{#{the_margin.css} +  <h4 class="toc"> +    <a href="#{@metalink}"> +      <i>MetaData</i> +    </a> +  </h4> +#{the_table_close}} +    end +  end +  class HeadSeg < HeadInformation +    def initialize(md) +      super(md) +    end +    def head +      %{#{doc_type} +  <head> +    <title> +      #{@per.seg_name_x[@per.seg_name_x_tracker]} - +      #{@md.html_title} +    </title> +    <meta http-equiv='Content-Type' content='text/html; charset=utf-8' /> +    #{@css.xhtml_epub} +  </head> +    <body lang="#{@md.opt.lng}">} +    end +    def endnote_mark +%{ +  <hr class="endnote" /> +} +    end +  end +  class HeadScroll < HeadToc +    def initialize(md) +      super(md) +    end +    def toc_owner_details +      %{#{the_margin.txt_3} +#{the_font.paragraph_font_small} +  <a href="#owner.details"> +    Owner Details +    <font size="1" color="#777777"> +      #{$ep[:hsp]*3} +    </font> +  </a> +  </font> +#{the_table_close}} +    end +  end +  class FormatTextObject +    include SiSU_Parts_XHTML +    attr_accessor :md,:t_o,:txt,:ocn,:format,:table,:link,:linkname,:paranum,:p_num,:headname,:banner,:url +    def initialize(md,t_o) +      @md,@t_o=md,t_o +      if t_o.is_a?(Hash) +        @txt            =t_o[:txt]            || nil +        @ocn            =t_o[:ocn]            || nil +        @ocn_display    =t_o[:ocn_display]    || nil +        @headname       =t_o[:headname]       || nil +        @trailer        =t_o[:trailer]        || nil +        @endnote_part_a =t_o[:endnote_part_a] || nil +        @endnote_part_b =t_o[:endnote_part_b] || nil +        @lnk_url        =t_o[:lnk_url]        || nil +        @lnk_txt        =t_o[:lnk_txt]        || nil +        @format         =t_o[:format]         || nil +        @target         =t_o[:target]         || nil #occasionally passed but not used +        if @format and not @format.empty? +          if @format=~/^\d:(\S+)/ #need more reliable marker #if @format =~ /#{Rx[:lv]}/ +            headname=$1 #format[/\d~(\S+)/m,1] +            @headname=(headname =~/^[a-zA-Z]/) \ +            ? %{<id="#{headname}">} +            : %{<id="h#{headname}"></a>} +            @headname=(headname =~/^[a-zA-Z]/) \ +            ? %{<a name="#{headname}" id="#{headname}"></a>} +            : %{<a name="h#{headname}" id="h#{headname}"></a>} +          end +        end +      elsif t_o.class.inspect =~/Object/ +        @dob=t_o if defined? t_o.is +        @named=nametags_seg(@dob) +        @txt=((defined? t_o.obj) ? t_o.obj : nil) +        @ocn=((defined? t_o.ocn) ? t_o.ocn.to_s : nil) +        @headname=((t_o.is==:heading and defined? t_o.name) ? t_o.name : nil) +      else +        if @md.opt.act[:maintenance][:set]==:on +          p __FILE__ << ':' << __LINE__.to_s +          p t_o.class +          p caller +        end +      end +      if @txt and not @txt.empty? +        @txt=@txt.gsub(/#{Mx[:mk_o]}[-~]##{Mx[:mk_c]}/,'') +      end +      @p_num=ParagraphNumber.new(@md,@ocn) +    end +    def nametags_seg(dob) #FIX +      tags='' +      if defined? dob.tags \ +      and dob.tags.length > 0 # insert tags "hypertargets" +        dob.tags.each do |t| +          tags=tags << %{<a name="#{t}" />} +        end +      end +      tags +    end +    def endnote_body +      %{ +<p class="endnote"> +  #{@txt} +</p> +} +    end +    def endnote_body_indent +      %{ +  <p class="endnote_indent"> +    #{@txt} +  </p> +} +    end +    def no_paranum +      %{ +<div class="substance"> +  <label class="ocn">#{$ep[:hsp]}</label> +  <p class="norm"> +    #{@txt} +  </p> +</div> +} +    end +    def para_form_css(tag,attrib,txt)                                                    # regular paragraphs shaped here +      ul=ulc='' +      ul,ulc="<ul>\n  ","\n  </ul>" if @tag =~/li/ +      %{ +<div class="substance"> +  #{@p_num.ocn_display} +  #{ul}<#{tag} class="#{attrib}" #{@p_num.id}> +    #{@named}#{txt} +  </#{tag}>#{ulc} +</div> +} +    end +    def para +      para_form_css('p','norm',@txt) +    end +    def group +      para_form_css('p','group',@txt) +    end +    def block +      para_form_css('p','block',@txt) +    end +    def alt +      para_form_css('p','alt',@txt) +    end +    def verse +      para_form_css('p','verse',@txt) +    end +    def code +      para_form_css('p','code',@txt) +    end +    def center +      para_form_css('p','center',@txt) +    end +    def bold +      para_form_css('p','bold',@txt) +    end +    def bullet +      para_form_css('li','bullet',@txt) +    end +    def table +      @txt=if @t_o.obj !~/^<table\s/ +        table=SiSU_XHTML_Shared::TableXHTML.new(@t_o) #move, make happen earlier +        table.table.obj +      else @txt +      end +      para_form_css('p','norm',@txt) +    end +    def break +      @txt=@txt.gsub(/#{Mx[:br_page_new]}|#{Mx[:br_page]}|#{Mx[:br_page_line]}/,'<hr /><br />'). +        gsub(/#{Mx[:br_obj]}/,'<hr style="width:30%" /><br />') +      para_form_css('p','norm',@txt) +    end +    def format(tag,attrib) +      para_form_css(tag,attrib,@txt) +    end +    def title_heading(tag,attrib) +      %{ +<div class="content"> +<#{tag} class="#{attrib}"> +    #{@named}#{@txt} +  </#{tag}> +</div> +} +    end +    def title_heading0 +      DISABLE[:epub][:per_section_title] \ +      ? '' +      : title_heading('h1','tiny') +    end +    def title_heading1 +      DISABLE[:epub][:per_section_title] \ +      ? '' +      : title_heading('h1','tiny') +    end +    def title_heading2 +      DISABLE[:epub][:per_section_title] \ +      ? '' +      : title_heading('h2','tiny') +    end +    def title_heading3 +      DISABLE[:epub][:per_section_title] \ +      ? '' +      : title_heading('h3','tiny') +    end +    def title_heading4 +      '' +    end +    def seg_heading_sub(tag,attrib,txt) +      txt=txt.gsub(/(?:#{Mx[:en_a_o]}.+?#{Mx[:en_a_c]}|#{Mx[:en_b_o]}.+?#{Mx[:en_b_c]})\s*/m,' ') +      %{ +<div class="substance"> +  #{@p_num.ocn_display} +  <#{tag} class="#{attrib}" #{@p_num.id}>#{@p_num.name} +    #{@named}#{@txt} +  </#{tag}> +</div> +} +    end +    def seg_heading4 +      %{ +<div class="substance"> +  #{@p_num.ocn_display} +  <h1 class="norm" #{@p_num.id}> +    #{@txt} +  </h1> +</div> +} +    end +    def seg_heading5 +      seg_heading_sub('p','bold',@txt) +    end +    def seg_heading6 +      seg_heading_sub('p','bold',@txt) +    end +    def seg_heading7 +      seg_heading_sub('p','bold',@txt) +    end +    def dl #check :trailer +      "<dl><b>#{@txt}</b> #{@trailer}</dl>" +    end +    def table_css_end +      '</table> +    </p> +  </div>' +    end +    def gsub_body #unused +      @txt=case @txt +      when /^(?:#{Mx[:pa_o]}i[1-9]#{Mx[:pa_c]}\s*)?\((i+|iv|v|vi+|ix|x|xi+)\)/ +        @txt.gsub(/^\((i+|iv|v|vi+|ix|x|xi+)\)/,'<b>(\1)</b>'). +          gsub(/^(#{Mx[:pa_o]}i[1-9]#{Mx[:pa_c]})\s*\((i+|iv|v|vi+|ix|x|xi+)\)/,'\1<b>(\2)</b>') +      when /^(?:#{Mx[:pa_o]}i[1-9]#{Mx[:pa_c]}\s*)?\(?(\d|[a-z])+\)/ +        @txt.gsub(/^\((\d+|[a-z])+\)/,'<b>(\1)</b>'). +          gsub(/^(#{Mx[:pa_o]}i[1-9]#{Mx[:pa_c]})\s*\((\d+|[a-z])+\)/,'\1<b>(\2)</b>') +      when /^\s*\d{1,3}\.\s/ +        @txt.gsub(/^\s*(\d+\.)/,'<b>\1</b>') +      when /^\s*[A-Z]\.\s/ +        @txt.gsub(/^\s*([A-Z]\.)/,'<b>\1</b>') +      else @txt +      end +    end +    def bold_para +      %{#{the_margin.txt_0} +  <p class="bold"> +    #{@txt} +  </p> +#{the_margin.num_css} +  #{$ep[:hsp]*3} +#{the_table_close}} +    end +    def bold_heading #unused +      @txt=@txt.gsub(/[1-9]~\S+/,''). +        gsub(/[1-9]~/,'') +      %{<p class="bold"> +    #{@txt} +  </p> +#{the_margin.num_css} +  #{$ep[:hsp]*3} +#{the_table_close}} +    end +    def toc_head_copy_at +      @txt=SanitizeXML.xml(@txt) +      %{<p class="center">#{@txt}</p>\n} +    end +    def center +      @txt=SanitizeXML.xml(@txt) +      %{<p class="center">#{@txt}</p>\n} +    end +    def bold +      @txt=SanitizeXML.xml(@txt) +      %{<p class="bold">#{@txt}</p>\n} +    end +    def center_bold +      @txt=SanitizeXML.xml(@txt) +      %{<p class="centerbold">#{@txt}</p>\n} +    end +  end +  class FormatScroll < FormatTextObject +    def initialize(md,txt) +      super(md,txt) +    end +  end +  class FormatSeg < FormatTextObject +    def initialize(md,txt) +      super(md,txt) +    end +    def endnote_seg_body(fn='')  #FIX                                                #url construction keep within single line... BUG WATCH 200408 +      fn='doc' if fn.to_s.empty? #you may wish to reconsider, sends to 'doc' where no segment info +      %{ +  <p class="endnote"> +    #{@endnote_part_a}#{fn}#{Sfx[:epub_xhtml]}#{@endnote_part_b} +  </p> +} +    end +    def clean(txt) +      txt=txt.gsub(/#{Mx[:en_a_o]}.+?#{Mx[:en_a_c]}/,''). +        gsub(/#{Mx[:en_b_o]}.+?#{Mx[:en_b_c]}/,'') +    end +    def subtoc_lev(tag,attrib) +      @txt=clean(@txt) +      txt=if @txt \ +      and @txt =~/<\/?i>|<a\s+name="\S+?">/mi +        @txt.gsub(/<\/?i>|<a\s+name="\S+?">/mi,'') #removes name markers from subtoc, go directly to substantive text +      else @txt +      end +      note='' +      if txt =~/(#{Mx[:en_a_o]}.+?#{Mx[:en_a_c]}|#{Mx[:en_b_o]}.+?#{Mx[:en_b_c]})/m # had \s* at end +        note=$1 +        note=note.gsub(/[\s]+/m,' ') +        txt=txt.gsub(/(?:#{Mx[:en_a_o]}.+?#{Mx[:en_a_c]}|#{Mx[:en_b_o]}.+?#{Mx[:en_b_c]})\s*/m,' '). +          gsub(/<a[\n\s]+"[\n\s]+href="##{Mx[:note_ref]}\d+">#{$ep[:hsp]}<sup id="#{Mx[:note]}\d+">\d+<\/sup>#{$ep[:hsp]}/m,''). +          gsub(/<a[\n\s]+"[\n\s]+href="##{Mx[:note_ref]}\d+">#{$ep[:hsp]}<sup id="#{Mx[:note]}\d+">\d+<\/sup>#{$ep[:hsp]}/m,'') #remove +      end +      %{<#{tag} class="#{attrib}"> +    <a href="#o#{@ocn}"><i>#{txt}</i></a> #{note} +  </#{tag}>} +    end +    def subtoc_lev5 +      subtoc_lev('h5','subtoc') if @txt +    end +    def subtoc_lev6 +      subtoc_lev('h6','subtoc') if @txt +    end +    def subtoc_lev7 +      subtoc_lev('h7','subtoc') if @txt +    end +    def heading_sub(tag,attrib,txt) +      txt=txt.gsub(/(?:#{Mx[:en_a_o]}.+?#{Mx[:en_a_c]}|#{Mx[:en_b_o]}.+?#{Mx[:en_b_c]})\s*/m,' ') +      %{ +<div class="substance"> +  #{@p_num.ocn_display} +  <#{tag} class="#{attrib}" #{@p_num.id}> #{@headname} +    #{@txt} +  </#{tag}> +</div> +} +    end +    def heading4 +      %{ +<div class="substance"> +  #{@p_num.ocn_display} +  <h1 class="norm" #{@p_num.id}> +    #{@t_o[:format]} +    #{@txt} +  </h1> +</div> +} +    end +    def heading5 +      heading_sub('p','bold',@txt) +    end +    def heading6 +      heading_sub('p','bold',@txt) +    end +    def heading7 +      heading_sub('h7','bold',@txt) +    end +    def navigation_heading4 +      %{<table summary="navigation segment heading 4" width=100% bgcolor="#08163f" border="0"> +<tr><td align="center"> +<p class="bold"> +  #{@txt} +</p> +#{the_table_close}} +    end +    def navigation_heading5 +      %{<p class="bold"> +  #{@txt} +</p>} +    end +    def navigation_heading6 +      %{<p class="bold"> +  #{@txt} +</p>} +    end +    def navigation_heading7 +      %{<p class="bold"> +  #{@txt} +</p>} +    end +    def navigation_center +      %{<p class="centerbold">#{@txt}</p>} +    end +  end +  class FormatToc < FormatTextObject +    def initialize(md,txt) +      super(md,txt) +    end +    def links_guide +      %{  <li class="doc"> +    <a href="#{@lnk_url}" target="_top"> +      #{@lnk_txt} +    </a> +  </li> +} +    end +    def lev(tag,attrib) +      if @txt +        %{<#{tag} class="#{attrib}"> +    #{@txt} +  </#{tag}> +} +      else '' +      end +    end +    def lev1 +      lev('h1','toc') +    end +    def lev2 +      lev('h2','toc') +    end +    def lev3 +      lev('h3','toc') +    end +    def lev4 +      lev('h4','toc') +    end +    def lev5 +      lev('h5','toc') +    end +    def lev6 +      lev('h6','toc') +    end +    def lev7 +      lev('h7','toc') +    end +    def lev0 #docinfo +      lev('h0','toc') +    end +  end +end +__END__ +#+END_SRC + +** xhtml_epub2_persist.rb + +#+BEGIN_SRC ruby  :tangle "../lib/sisu/xhtml_epub2_persist.rb" +# <<sisu_document_header>> +module SiSU_XHTML_EPUB2_Persist +  class Persist +    @@persist=nil +    attr_accessor :is0,:is1,:is2,:is3,:is4,:heading0,:heading1,:heading2,:heading3,:heading4, :title, :nav, :tocband_banner, :tocband_bannerless, :headings, :heading_endnotes, :main, :endnote_all, :tail, :credits, :heading_idx, :idx, :seg_endnotes, :seg_endnotes_array, :closed, :get_hash_fn, :get_hash_to, :seg_subtoc, :seg_subtoc_array, :fn, :seg_name ,:seg_name_x,:seg_name_x_tracker +    def initialize(args=nil) +      @@persist=args=(args ? args : (@@persist || persist_init_hash_values)) +      @is0=args[:is0] +      @is1=args[:is1] +      @is2=args[:is2] +      @is3=args[:is3] +      @is4=args[:is4] +      @heading0=args[:heading0] +      @heading1=args[:heading1] +      @heading2=args[:heading2] +      @heading3=args[:heading3] +      @heading4=args[:heading4] +      @title=args[:title] +      @nav=args[:nav] +      @tocband_banner=args[:tocband_banner] +      @tocband_bannerless=args[:tocband_bannerless] +      @headings=args[:headings] +      @heading_endnotes=args[:heading_endnotes] +      @main=args[:main] +      @endnote_all=args[:endnote_all] +      @tail=args[:tail] +      @credits=args[:credits] +      #@heading_idx=args[:heading_idx] +      @idx=args[:idx] +      @seg_endnotes=args[:seg_endnotes] +      @seg_endnotes_array=args[:seg_endnotes_array] +      @closed=args[:closed] +      @get_hash_to=args[:get_hash_to] +      @get_hash_fn=args[:get_hash_fn] +      @seg_subtoc=args[:seg_subtoc] +      @seg_subtoc_array=args[:seg_subtoc_array] +      @fn=args[:fn] +      @seg_name=args[:seg_name] +      @seg_name_x=args[:seg_name_x] +      @seg_name_x_tracker=args[:seg_name_x_tracker] +    end +    def is0 +      @is0 +    end +    def is1 +      @is1 +    end +    def is2 +      @is2 +    end +    def is3 +      @is3 +    end +    def is4 +      @is4 +    end +    def heading0 +      @heading0 +    end +    def heading1 +      @heading1 +    end +    def heading2 +      @heading2 +    end +    def heading3 +      @heading3 +    end +    def heading4 +      @heading4 +    end +    def title +      @title +    end +    def nav +      @nav +    end +    def tocband_banner +      @tocband_banner +    end +    def tocband_bannerless +      @tocband_bannerless +    end +    def headings +      @headings +    end +    def heading_endnotes +      @heading_endnotes +    end +    def main +      @main +    end +    def endnote_all +      @endnote_all +    end +    def tail +      @tail +    end +    def credits +      @credits +    end +    def heading_idx +      @heading_idx +    end +    def idx +      @idx +    end +    def seg_endnotes +      @seg_endnotes +    end +    def seg_endnotes_array +      @seg_endnotes_array +    end +    def closed +      @closed +    end +    def get_hash_to +      @get_hash_to +    end +    def get_hash_fn +      @get_hash_fn +    end +    def seg_subtoc +      @seg_subtoc +    end +    def seg_subtoc_array +      @seg_subtoc_array +    end +    def fn +      @fn +    end +    def seg_name +      @seg_name +    end +    def seg_name_x +      @seg_name_x +    end +    def seg_name_x_tracker +      @seg_name_x_tracker +    end +    def persist_init_hash_values +      { +        is0: 0, +        is1: 0, +        is2: 0, +        is3: 0, +        is4: 0, +        heading0: '', +        heading1: '', +        heading2: '', +        heading3: '', +        heading4: '', +        tocband_banner: [], +        tocband_bannerless: [], +        title: [], +        nav: [], +        headings: [], +        main: [], +        idx: [], +        tail: [], +        credits: [], +        endnote_all: [], +        heading_endnotes: '', +        seg_endnotes: {}, +        seg_endnotes_array: [], +        closed: [], +        get_hash_fn: '', +        get_hash_to: '', +        seg_subtoc: {}, +        seg_subtoc_array: [], +        fn: '', +        seg_name: [], +        seg_name_x: [], +        seg_name_x_tracker: 0, +      } +    end +    def persist_init +      @@persist=nil +      Persist.new(persist_init_hash_values) +    end +  end +  class PersistTOC +    @@persist=nil +    attr_accessor :seg,:seg_mini,:scr,:ncx,:opf +    def initialize(args=nil) +      @@persist=args=(args ? args : (@@persist || persist_init_hash_values)) +      @seg=args[:seg] +      @seg_mini=args[:seg_mini] +      @scr=args[:scr] +      @ncx=args[:ncx] +      @opf=args[:opf] +    end +    def seg +      @seg +    end +    def seg_mini +      @seg_mini +    end +    def scr +      @scr +    end +    def ncx +      @ncx +    end +    def opf +      @opf +    end +    def persist_init_hash_values +      { +        seg: [], +        seg_mini: [], +        scr: [], +        ncx: [], +        opf: [], +      } +    end +    def persist_init +      @@persist=nil +      PersistTOC.new(persist_init_hash_values) +    end +  end +end +__END__ +#+END_SRC + +** xhtml_epub2_segments.rb + +#+BEGIN_SRC ruby  :tangle "../lib/sisu/xhtml_epub2_segments.rb" +# <<sisu_document_header>> +module SiSU_XHTML_EPUB2_Seg +  require_relative 'xhtml_shared'                       # xhtml_shared.rb +  require_relative 'xhtml_epub2'                        # xhtml_epub2.rb +  require_relative 'xhtml_epub2_persist'                # xhtml_epub2_persist.rb +  require_relative 'shared_metadata'                    # shared_metadata.rb +  class Output +    def initialize(md,outputfile,per,type='') +      @md, @output_epub_cont_seg,@per,@type= +        md,outputfile,           per, type +    end +    def output +      if @per.title =~/\S/ +        filename_seg=[] +        filename_seg \ +        << @per.title \ +        << @per.nav +        if @type=='endnotes' +          @per.headings=[] #watch +          txt_obj={ txt: 'Endnotes', ocn_display: ''} +          format_seg=SiSU_XHTML_EPUB2_Format::FormatSeg.new(@md,txt_obj) +          @per.headings \ +          << format_seg.title_heading1 +          filename_seg \ +          << @per.heading_endnotes \ +          << @per.headings \ +          << %{\n<div class="content">\n} \ +          << @per.endnote_all \ +          << '</div>' +        elsif @type=='idx' +          @per.headings=[] +          txt_obj={ txt: 'Index', ocn_display: ''} +          format_seg=SiSU_XHTML_EPUB2_Format::FormatSeg.new(@md,txt_obj) +          @per.headings << format_seg.title_heading1 +          filename_seg \ +          << @per.heading_idx \ +          << @per.headings \ +          << %{\n<div class="content">\n} \ +          << @per.idx \ +          << '</div>' +        elsif @type=='metadata' +          metadata=SiSU_Metadata::Summary.new(@md).xhtml_display.metadata +          @per.headings=[] +          txt_obj={ txt: 'Metadata', ocn_display: ''} +          format_seg=SiSU_XHTML_EPUB2_Format::FormatSeg.new(@md,txt_obj) +          @per.headings \ +          << format_seg.title_heading1 +          filename_seg \ +          << @per.heading_idx \ +          << @per.headings \ +          << %{\n<div class="content">\n} \ +          << metadata \ +          << '</div>' +        elsif @type=='sisu_manifest' +          env=SiSU_Env::InfoEnv.new(@md.fns) +          path_and_name,url_and_name= \ +            "#{env.path.output}/#{@md.fnb}/sisu_manifest.html", +            "#{env.url.root}/#{@md.fnb}/sisu_manifest.html" +          manifest=if FileTest.file?("#{path_and_name}")==true +            <<WOK +<p>A list of available output types may be available at the following url:</p> +<p><a href="#{url_and_name}">#{url_and_name}</a></p> +WOK +          else '' +          end +          @per.headings=[] +          txt_obj={ txt: 'Manifest', ocn_display: ''} +          format_seg=SiSU_XHTML_EPUB2_Format::FormatSeg.new(@md,txt_obj) +          @per.headings \ +          << format_seg.title_heading1 +          filename_seg \ +          << @per.heading_idx \ +          << @per.headings \ +          << %{\n<div class="content">\n} \ +          << manifest \ +          << '</div>' +        else +          filename_seg \ +          << @per.headings \ +          << @per.main \ +          << "\n</div>\n" +        end +        filename_seg \ +        << @per.tail \ +        << @per.nav \ +        << @per.closed +        filename_seg=filename_seg.flatten.compact #watch +        filename_seg.each do |str| +          unless str =~/\A\s*\Z/ +            @output_epub_cont_seg \ +            << str.strip +          end +        end +        @output_epub_cont_seg.close +      end +    end +  end +  class Seg +    @@seg_name=[] +    @@seg_url='' +    @@tracker=0 +    attr_reader :seg_name_x,:seg_name_x_tracker +    def initialize(md='',data='') +      @md,@data=md,data +      @per=SiSU_XHTML_EPUB2_Persist::Persist.new +      @seg_name_x=@per.seg_name_x=(@@seg_name || []) +      @seg_name_x_tracker=@per.seg_name_x_tracker=(@@tracker || 0) +      @make=SiSU_Env::ProcessingSettings.new(@md) if @md +    end +    def songsheet +      begin +        data=get_subtoc_endnotes(@data,@per) +        data=articles(data,@per) +        SiSU_XHTML_EPUB2_Seg::Seg.new.cleanup(@md,@per) # (((( added )))) +        #### (((( END )))) #### +      rescue +        SiSU_Errors::Rescued.new($!,$@,@md.opt.selections.str,@md.fns).location do +          __LINE__.to_s + ':' + __FILE__ +        end +      ensure +        SiSU_XHTML_EPUB2_Persist::Persist.new.persist_init +        @@seg_name=@per.seg_name=[] +      end +    end +  protected +    def articles(data,per) +      @per=per +      tracking,newfile=0,0 +      printed_endnote_seg='n' +      idx_xhtml=nil +      if @md.book_idx +        idx_xhtml=SiSU_Particulars::CombinedSingleton. +          instance.get_idx_xhtml(@md).xhtml_idx +        idx_xhtml.each do |x| +          @per.idx << x +        end +        @per.heading_idx='' +      end +      data.each do |dob| +        if (dob.is == :heading \ +        || dob.is == :heading_insert) \ +        && dob.ln == 4 +          @@seg_name << dob.name +          @per.seg_name = @@seg_name +          dob.name +        end +      end +      @per.seg_name_x=@per.seg_name +      @per.seg_name.length +      testforartnum=@per.seg_name_x +      if (@md.opt.act[:verbose][:set]==:on \ +      || @md.opt.act[:verbose_plus][:set]==:on \ +      || @md.opt.act[:maintenance][:set]==:on) +        SiSU_Screen::Ansi.new( +          @md.opt.act[:color_state][:set], +          @per.seg_name.length +        ) +      end +      SiSU_Particulars::CombinedSingleton. +        instance.get_map_nametags(@md).nametags_map #p map_nametags +      data.each do |dob| +        #if defined? dob.obj \ +        #and dob.obj =~/href="#{Xx[:segment]}#+\S+?"/ +        #  ##Consider: remove, reinstate earlier? +        #  #while dob.obj =~/href="#{Xx[:segment]}#+(\S+?)"/ +        #  #  m=$1 +        #  #  if map_nametags[m][:segname] +        #  #    dob.obj=dob.obj.sub(/href="#{Xx[:segment]}#+(\S+?)"/,%{href="#{map_nametags[m][:segname]}#{Sfx[:html]}#\\1"}) +        #  #  else +        #  #    p "NOT FOUND name_tags: #{m}" +        #  #    dob.obj=dob.obj.sub(/href="#{Xx[:segment]}#+(\S+?)"/,%{href="#\\1"}) # not satisfactory +        #  #  end +        #  #end +        #end +        if (dob.is==:heading \ +        || dob.is==:heading_insert) \ +        && dob.ln==4 +          @per.heading4=dob.obj +          @per.is4=newfile=1 +        end +        if (dob.is==:heading \ +        || dob.is==:heading_insert) \ +        && dob.ln==3 +          @per.heading3=dob.obj +          @per.is4,@per.is3=0,1 +        end +        if (dob.is==:heading \ +        || dob.is==:heading_insert) \ +        && dob.ln==2 +          @per.heading2=dob.obj +          @per.is4,@per.is3,@per.is2=0,0,1 +        end +        if (dob.is==:heading \ +        || dob.is==:heading_insert) \ +        && dob.ln==1 +          @per.heading1=dob.obj +          @per.is4,@per.is3,@per.is2,@per.is1=0,0,0,1 +        end +        if (dob.is==:heading \ +        || dob.is==:heading_insert) \ +        && dob.ln==0 +          @per.heading0=dob.obj +          @per.is4,@per.is3,@per.is2,@per.is1,@per.is0=0,0,0,0,1 +        end +        if (@per.is0 && !@per.is1 && !@per.is2 && !@per.is3 && !@per.is4) +          if not (dob.is==:heading \ +          || dob.is==:heading_insert) \ +          && dob.ln==0 +            $_ #; check +          end +        end +        if @per.is4==1 +          dir_epub_cont="#{@md.env.processing_path.epub}/#{Ep[:d_oebps]}" +          if newfile==1 \ +          or dob.obj =~/^#{Mx[:br_endnotes]}|^#{Mx[:br_eof]}/ +            newfile=0 +            if (dob.is==:heading \ +            || dob.is==:heading_insert) \ +            && dob.ln==4 +              if tracking != 0 +                tail(@md,@per) +                #SiSU_XHTML_EPUB2_Seg::Seg.new(@md,@per).tail +                segfilename="#{dir_epub_cont}/#{@per.seg_name_x[tracking-1]}#{Sfx[:epub_xhtml]}" +                output_epub_cont_seg=File.new(segfilename,'w') if @per.seg_name_x[tracking-1] +                if dob.is==:heading \ +                or @per.seg_name_x[tracking-1] !~/endnotes|book_index|metadata/ +                  SiSU_XHTML_EPUB2_Seg::Output.new(@md,output_epub_cont_seg,@per).output +                elsif dob.is==:heading_insert +                  if @per.seg_name_x[tracking-1]=='endnotes' +                    SiSU_XHTML_EPUB2_Seg::Output.new(@md,output_epub_cont_seg,@per,'endnotes').output +                  elsif @per.seg_name_x[tracking-1]=='book_index' +                    SiSU_XHTML_EPUB2_Seg::Output.new(@md,output_epub_cont_seg,@per,'idx').output +                    @per.idx=[] +                  elsif @per.seg_name_x[tracking-1]=='metadata' # navigation bug FIX +                    SiSU_XHTML_EPUB2_Seg::Output.new(@md,output_epub_cont_seg,@per,'metadata').output +                  else puts "#{__FILE__}::#{__LINE__}" +                  end +                else puts "#{__FILE__}::#{__LINE__}" +                end +                SiSU_XHTML_EPUB2_Seg::Seg.new.reinitialise(per) +                heading_art(dob) +                head(dob) +                if @per.seg_name_x[tracking] =='metadata' +                  segfilename="#{dir_epub_cont}/#{@per.seg_name_x[tracking]}#{Sfx[:epub_xhtml]}" +                  output_epub_cont_seg=File.new(segfilename,'w') +                  SiSU_XHTML_EPUB2_Seg::Output.new(@md,output_epub_cont_seg,@per,'metadata').output +                  SiSU_XHTML_EPUB2_Seg::Seg.new.reinitialise(per) +                  #BUG navigation bug with items following metadata, and occurring before manifest, this becomes a bug ... work area for book index, FIX +                end +               #@output_epub_cont_seg.closed                                         #%(((( EOF )))) --> +              end +              if tracking==0 +                heading_art(dob) +                head(dob) +              end +            end +            tracking=tracking+1 +          end +          if (dob.is==:heading \ +          || dob.is==:heading_insert) \ +          && dob.ln==4 \ +          && dob.name +            @per.get_hash_to=dob.name +            @per.get_hash_fn=dob.name +          end +          if dob.obj.is_a?(String) +            markup(dob) +          elsif dob.obj.is_a?(Array) +            dob.obj.each do |pg| +              markup(pg) +            end +          end +          if testforartnum[tracking-1] =~/endnote/ +            if printed_endnote_seg=='n' +              printed_endnote_seg='y' +            end +          end +        end +      end +      data +    end +    def heading_art(dob) +      @per.title=SiSU_XHTML_EPUB2_Format::HeadSeg.new(@md).head +    end +    def head(dob) +      clean=/<!.*?!>|<:.*?>$/ +      @p_num ||= '' +      if @per.is0==1 +        if defined? @md.creator.author \ +        and @md.creator.author +          @author=%{<b>#{@md.creator.author}</b>\n} +        end +        @p_num=SiSU_XHTML_EPUB2_Format::ParagraphNumber.new(@md,dob.ocn) +        txt_obj={ txt: @per.heading0, ocn_display: @p_num.ocn_display } +        format_seg=SiSU_XHTML_EPUB2_Format::FormatSeg.new(@md,txt_obj) +        @per.headings << format_seg.title_heading0.gsub(clean,'') +        @per.heading0=@per.heading0. +          gsub(/#{$ep[:hsp]}<a name="-[\d*+]+" href="#_[\d*+]+">#{$ep[:hsp]}<sup>[\d*+]+<\/sup>#{$ep[:hsp]}<\/a>/,'') +      end +      if @per.is1==1 +        @p_num=SiSU_XHTML_EPUB2_Format::ParagraphNumber.new(@md,dob.ocn) +        txt_obj={ txt: @per.heading1, ocn_display: @p_num.ocn_display } +        format_seg=SiSU_XHTML_EPUB2_Format::FormatSeg.new(@md,txt_obj) +        @per.headings << format_seg.title_heading1.gsub(clean,'') +        @per.heading1=@per.heading1. +          gsub(/#{$ep[:hsp]}<a name="-[\d*+]+" href="#_[\d*+]+">#{$ep[:hsp]}<sup>[\d*+]+<\/sup>#{$ep[:hsp]}<\/a>/,'') +      end +      if @per.is2==1 +        heading2=@per.heading2 +        @p_num=SiSU_XHTML_EPUB2_Format::ParagraphNumber.new(@md,dob.ocn) +        txt_obj={ txt: heading2, ocn_display: @p_num.ocn_display } +        format_seg=SiSU_XHTML_EPUB2_Format::FormatSeg.new(@md,txt_obj) +        @per.headings << format_seg.title_heading2.gsub(clean,'') +        @per.heading2=@per.heading2. +          gsub(/#{$ep[:hsp]}<a name="-[\d*+]+" href="#_[\d*+]+">#{$ep[:hsp]}<sup>[\d*+]+<\/sup>#{$ep[:hsp]}<\/a>/,'') +      end +      if @per.is3==1 +        heading3=@per.heading3 +        @p_num=SiSU_XHTML_EPUB2_Format::ParagraphNumber.new(@md,dob.ocn) +        txt_obj={ txt: heading3, ocn_display: @p_num.ocn_display } +        format_seg=SiSU_XHTML_EPUB2_Format::FormatSeg.new(@md,txt_obj) +        @per.headings << format_seg.title_heading3.gsub(clean,'') +        @per.heading3=@per.heading3. +          gsub(/#{$ep[:hsp]}<a name="-[\d*+]+" href="#_[\d*+]+">#{$ep[:hsp]}<sup>[\d*+]+<\/sup>#{$ep[:hsp]}<\/a>/,'') +      end +      if @per.is4==1 +        heading4=@per.heading4 +        @p_num=SiSU_XHTML_EPUB2_Format::ParagraphNumber.new(@md,dob.ocn) +        txt_obj={ txt: heading4, ocn_display: @p_num.ocn_display } +        format_seg=SiSU_XHTML_EPUB2_Format::FormatSeg.new(@md,txt_obj) +        @per.headings \ +        << format_seg.title_heading4.gsub(clean,'') +      end +      @@tracker=@@tracker+1 +    end +    def markup(dob) +      @debug=[] +      if dob.is ==:heading \ +      || dob.is ==:heading_insert \ +      || dob.is ==:para +        #extend as necessary FIX +        @p_num=SiSU_XHTML_EPUB2_Format::ParagraphNumber.new(@md,dob.ocn) +      end +      sto=SiSU_XHTML_EPUB2_Format::FormatTextObject.new(@md,dob) +      dob_xhtml=if dob.is==:heading \ +      || dob.is==:heading_insert \ +      || dob.is==:para +        dob_xhtml=if dob.is==:heading \ +        or dob.is==:heading_insert +          if dob.ln==4 +            sto.seg_heading4 # work on see SplitTextObject +          elsif dob.ln==5 +            sto.seg_heading5 +          elsif dob.ln==6 +            sto.seg_heading6 +          elsif dob.ln==7 +            sto.seg_heading7 +          end +        elsif dob.is==:para +          if dob.indent \ +          and dob.hang \ +          and dob.indent =~/[0-9]/ \ +          and dob.hang =~/[0-9]/ +            if dob.bullet_ +              (dob.indent =~/[1-9]/) \ +              ? sto.format('li',"i#{dob.indent}") +              : sto.format('li','bullet') +            elsif dob.indent == dob.hang +              sto.format('p',"i#{dob.indent}") +            elsif dob.indent != dob.hang +              sto.format('p',"h#{dob.hang}i#{dob.indent}") +            else sto.para +            end +          else sto.para +          end +        end +      elsif dob.is ==:block \ +      || dob.is ==:group \ +      || dob.is ==:alt +        sto.para #fix this should be block type specific #FIX +      elsif dob.is==:verse +        sto.verse +      elsif dob.is==:code +        sto.code +      elsif dob.is==:table +        sto.table +      elsif dob.is==:break +        sto.break +      end +      if @md.flag_separate_endnotes # may need to revisit, check +        dob.obj=dob.obj.gsub(/"\s+href="##{Mx[:note_ref]}(\d+)">/, +          %{" href=\"endnotes#{Sfx[:epub_xhtml]}##{Mx[:note_ref]}\\1">}) +          #endnote- twice #removed file type +      end +      if (dob.is ==:heading \ +      || dob.is==:heading_insert \ +      || dob.is==:para) \ +      && (not dob.ocn or dob.ocn.to_s.empty?) +        format_seg=SiSU_XHTML_EPUB2_Format::FormatSeg.new(@md,dob) +      end +      if (dob.is==:heading \ +      || dob.is==:heading_insert \ +      || dob.is==:para) \ +      and dob.note_ +        #dob.obj =~/<a href="#note_ref\d+"> <sup id=/       #endnote- note- +        format_seg=SiSU_XHTML_EPUB2_Format::FormatSeg.new(@md,dob) +        dob.obj=format_seg.no_paranum +      end +      if (dob.is==:heading \ +      || dob.is==:heading_insert) \ +      and dob.ln==4 +        @per.main <<  %{\n<div class="content">\n} +        @per.main << dob_xhtml +        if @make.build.segsubtoc? +          @per.main << @per.seg_subtoc[@per.get_hash_fn] +          #% insertion of sub-toc +        end +      else +        @per.main << dob_xhtml +      end +    end +    def tail(md,per) +      @md,@per=md,per +      format_head_seg=SiSU_XHTML_EPUB2_Format::HeadSeg.new(@md) +      if @md.flag_auto_endnotes \ +      and @per.seg_endnotes[@per.get_hash_fn] +        @per.tail <<  %{\n<div class="content">\n<div class="endnote">\n} +        if @per.seg_endnotes[@per.get_hash_fn].flatten.length > 0 +          @per.tail << format_head_seg.endnote_mark +          @per.tail << @per.seg_endnotes[@per.get_hash_fn].flatten +          #endnotes deposited at end of individual segments ||@|EXTRACTION OF ENDNOTES| +        end +        @per.tail << '</div>' +        @per.tail << '</div>' #this div closes div class content +      end +      @per.closed=[] +      @per.closed << format_head_seg.xhtml_close +    end +    def reinitialise(per) +      per.headings,per.main,per.tail,per.credits=Array.new(4){[]} +    end +    def cleanup(md,per) +      reinitialise(per) +      @@tracker=0 +      @per.seg_endnotes,@per.seg_subtoc={},{} +      @per.seg_endnotes_array,@per.seg_subtoc_array=[],[] +      per.endnote_all=[] +    end +    def get_subtoc_endnotes(data,per) #get endnotes & sub-table of contents subtoc +      @per=per +      data.each do |dob| +        dob.obj=dob.obj.gsub(/<a name=\"h\d.*?\">(.+?)<\/a>/mi,'\1') +        if @md.flag_auto_endnotes +          if (dob.is==:heading \ +          || dob.is==:heading_insert) \ +          && dob.ln.to_s =~/^[1-4]/ \ +          and not @per.fn.to_s.empty? +            @per.seg_endnotes[@per.fn]=[] +            @per.seg_endnotes[@per.fn] << @per.seg_endnotes_array +            @per.seg_endnotes_array=[] if dob.ln==4 +          end +          if (dob.is==:heading \ +          || dob.is==:heading_insert) \ +          && dob.ln==4 +            #%  EXTRACTION OF SUB-TOCs & SEGMENT NAME, after EXTRACTION OF ENDNOTES & SUB-TOCs +            @per.seg_subtoc[@per.fn]=@per.seg_subtoc_array +            @per.seg_subtoc_array=[] +            if dob.name \ +            and dob.obj +              @per.fn=dob.name +            else +              @per.fn=(dob.name =~/\S+/) \ +              ? dob.name +              : '' +            end +          end +        end +        if dob.is==:heading \ +        && dob.ln.to_s =~/^[5-7]/ +          case dob.ln +          when 5 +            format_seg=SiSU_XHTML_EPUB2_Format::FormatSeg.new(@md,dob) +            subtoc=format_seg.subtoc_lev5 #keep and make available, this is the subtoc +          when 6 +            format_seg=SiSU_XHTML_EPUB2_Format::FormatSeg.new(@md,dob) +            subtoc=format_seg.subtoc_lev6 #keep and make available, this is the subtoc +          when 7 +            format_seg=SiSU_XHTML_EPUB2_Format::FormatSeg.new(@md,dob) +            subtoc=format_seg.subtoc_lev7 #keep and make available, this is the subtoc +          end +          @per.seg_subtoc_array << subtoc +        end +        if @md.flag_auto_endnotes +          ast,pls='*','+' +          if dob.obj =~/(?:#{Mx[:en_a_o]}|#{Mx[:en_b_o]})(?:\d|#{ast}|#{pls})+ / \ +          and dob.is !=:code # endnote- +            endnote_array=[] +            if dob.obj=~/#{Mx[:en_a_o]}.+?#{Mx[:en_a_c]}/m +              endnote_array << dob.obj.scan(/#{Mx[:en_a_o]}.+?#{Mx[:en_a_c]}/m) +            end +            if dob.obj=~/#{Mx[:en_b_o]}#{ast}\d+\s.+?#{Mx[:en_b_c]}/m +              endnote_array \ +              << dob.obj.scan(/#{Mx[:en_b_o]}#{ast}\d+\s.+?#{Mx[:en_b_c]}/m) +            end +            if dob.obj=~/#{Mx[:en_b_o]}#{pls}\d+\s.+?#{Mx[:en_b_c]}/m +              endnote_array \ +              << dob.obj.scan(/#{Mx[:en_b_o]}#{pls}\d+\s.+?#{Mx[:en_b_c]}/m) +            end +            endnote_array=endnote_array.flatten #.compact #check compacting +            endnote_array.each do |note| +              note_match=note.dup +              note_match_seg=note.dup +              e_n=note_match_seg[/(?:#{Mx[:en_a_o]}(?:\d|#{ast}|#{pls})+|#{Mx[:en_b_o]}(?:#{ast}|#{pls})\d+)\s+(.+?)(?:#{Mx[:en_a_c]}|#{Mx[:en_b_c]})/m,1] +              try=e_n.split(/<br(?: \/)?>/) +              try.each do |e| +                txt_obj={ txt: e } +                format_seg=SiSU_XHTML_EPUB2_Format::FormatSeg.new(@md,txt_obj) +                note_match=if e =~/#{Mx[:pa_o]}i[1-9]#{Mx[:pa_c]}/ +                  format_seg.endnote_body_indent +                else format_seg.endnote_body +                end +                @per.seg_endnotes_array << note_match +              end +              try.join('<br \/>') +              #% creation of separate end segment/page of all endnotes referenced back to reference segment +              m=/(?:#{Mx[:en_a_o]}(?:\d|#{ast}|#{pls})+|#{Mx[:en_b_o]}(?:#{ast}|#{pls})\d+)\s+(.+?href=")(##{Mx[:note_ref]}(?:\d|_a|_b)+".+)(?:#{Mx[:en_a_c]}|#{Mx[:en_b_c]})/mi +              endnote_part_a=note_match_seg[m,1] +              endnote_part_b=note_match_seg[m,2] +              txt_obj={ +                endnote_part_a: endnote_part_a, +                endnote_part_b: endnote_part_b +              } +              format_seg=SiSU_XHTML_EPUB2_Format::FormatSeg.new(@md,txt_obj) +              note_match_all_seg=format_seg.endnote_seg_body(@per.fn) #BUG WATCH 200408 +              @per.endnote_all << note_match_all_seg +            end +            dob.obj=dob.obj.gsub(/(?:#{Mx[:en_a_o]}.+?#{Mx[:en_a_c]}|#{Mx[:en_b_o]}.+?#{Mx[:en_b_c]})\s*/m,' ') +          end +        end +      end +    end +  end +end +__END__ +#+END_SRC + +** xhtml_epub2_tune.rb + +#+BEGIN_SRC ruby  :tangle "../lib/sisu/xhtml_epub2_tune.rb" +# <<sisu_document_header>> +require_relative 'dp'                                   # dp.rb +module SiSU_XHTML_EPUB2_Tune +  require_relative 'se'                                 # se.rb +    include SiSU_Env; include SiSU_Screen +  require_relative 'xhtml_parts'                        # xhtml_parts.rb +  require_relative 'xhtml_epub2_format'                 # xhtml_epub2_format.rb #watch +  @@line_mode='' +  @@endnote_array=[] +  @@endnote_call_counter=1 +  @@table_align='<table summary='' width="96%" border="0" bgcolor="white" cellpadding="0" col="3"> +<tr ...><td width="2%" align="right"> + \;</td> +<td width="94%" valign="top" align="justify">' +  @@table_align_close='</td> +<td width="4%" align="right" valign="top"> +<font size="1" color="#777777"> +   </font> </td></tr></table>' +  @@counter,@@column,@columns=0,0,0 +  class Output +    def initialize(data,md) +      @data,@md=data,md +      @file=SiSU_Env::InfoFile.new(@md.fns) +      @cX=SiSU_Screen::Ansi.new(@md.opt.act[:color_state][:set]).cX +    end +    def hard_output +      @filename_tune=@file.write_file_processing.html_tune +      data=[] +      @data.each {|x| x.obj.strip; data << x if not x.obj.empty?} #1.9 array? +      data.each do |dob| +        @filename_tune.puts dob, "\n" #check +      end +    end +    def marshal +      File.open(@file.marshal.xhtml_tune,'w') {|f| Marshal.dump(@data.to_a,f)} +    end +  end +  class CleanXHTML +    def initialize(html='') +      @html=html +    end +    def clean +      html=@html +      str=if html.is_a?(String) +        html +      else html.obj +      end +      str=str.gsub(/#{Mx[:gl_o]}(#[0-9]{3})#{Mx[:gl_c]}/u,'&\1;'). +        gsub(/#{Mx[:gl_o]}#([a-z]{2,4})#{Mx[:gl_c]}/u,'&\1;'). +        gsub(/<br>/u,'<br />'). +        gsub(/#{Mx[:nbsp]}/u,$ep[:hsp]) +    end +  end +  class Tune +    include SiSU_Parts_XHTML +    def initialize(data,md) +      @data,@md=data,md +      @sys=SiSU_Env::SystemCall.new +      @env=SiSU_Env::InfoEnv.new(@md.fns) +    end +    def songsheet +      begin +        @cX=SiSU_Screen::Ansi.new(@md.opt.act[:color_state][:set]).cX +        if (@md.opt.act[:verbose][:set]==:on \ +        || @md.opt.act[:verbose_plus][:set]==:on \ +        || @md.opt.act[:maintenance][:set]==:on) +          SiSU_Screen::Ansi.new( +            @md.opt.act[:color_state][:set], +            'Tune' +          ).txt_grey +        end +        data=SiSU_XHTML_EPUB2_Tune::Tune.new(@data,@md).amp_angle_brackets +        data=SiSU_XHTML_EPUB2_Tune::Tune.new(data,@md).endnotes_html +        data=SiSU_XHTML_EPUB2_Tune::Tune.new(data,@md).url_markup +        data=SiSU_XHTML_EPUB2_Tune::Tune.new(data,@md).markup +        if @md.opt.act[:maintenance][:set]==:on #Hard Output Tune Optional on/off here +          data=SiSU_XHTML_EPUB2_Tune::Output.new(data,@md).hard_output +          SiSU_XHTML_EPUB2_Tune::Output.new(data,@md).marshal +        end +        SiSU_XHTML_EPUB2_Tune::Tune.new(@data,@md).output +      rescue +        SiSU_Errors::Rescued.new($!,$@,@md.opt.selections.str,@md.fns).location do +          __LINE__.to_s + ':' + __FILE__ +        end +      ensure +      end +    end +    def markup +      @tuned_file=[] +      @data.each do |dob| +        dob.obj=dob.obj.gsub(/#{Mx[:mk_o]}#([a-zA-Z]+)#{Mx[:mk_c]}/,'&\1;'). +          gsub(/#{Mx[:mk_o]}(#[0-9]+)#{Mx[:mk_c]}/,'&\1;') +        dob.obj=dob.obj.gsub(/#{Mx[:br_line]}|#{Mx[:br_nl]}/,'<br />') unless dob.is==:table +        dob.obj=dob.obj.gsub(/#{Mx[:fa_bold_o]}(.+?)#{Mx[:fa_bold_c]}/,'<b>\1</b>'). +          gsub(/#{Mx[:fa_italics_o]}(.+?)#{Mx[:fa_italics_c]}/,'<i>\1</i>'). +          gsub(/#{Mx[:fa_underscore_o]}(.+?)#{Mx[:fa_underscore_c]}/,'<u>\1</u>'). +          gsub(/#{Mx[:fa_superscript_o]}(.+?)#{Mx[:fa_superscript_c]}/,'<sup>\1</sup>'). +          gsub(/#{Mx[:fa_subscript_o]}(.+?)#{Mx[:fa_subscript_c]}/,'<sub>\1</sub>'). +          gsub(/#{Mx[:fa_insert_o]}(.+?)#{Mx[:fa_insert_c]}/,'<ins>\1</ins>'). +          gsub(/#{Mx[:fa_cite_o]}(.+?)#{Mx[:fa_cite_c]}/,'<cite>\1</cite>'). +          gsub(/#{Mx[:fa_strike_o]}(.+?)#{Mx[:fa_strike_c]}/,'<del>\1</del>'). +          gsub(/#{Mx[:fa_monospace_o]}(.+?)#{Mx[:fa_monospace_c]}/,'<tt>\1</tt>'). # tt, kbd +          gsub(/#{Mx[:mk_o]}:name#(\S+?)#{Mx[:mk_c]}/,''). +          gsub(/#{Mx[:gl_bullet]}/m,"●#{$ep[:hsp]*2}"). +          gsub(/#{Dx[:url_o]}/,Dx[:url_o_xml]).gsub(/#{Dx[:url_c]}/,Dx[:url_c_xml]). +          gsub(/#{Mx[:nbsp]}/,$ep[:hsp]). +          gsub(/<(p|br)>/,'<\1 />') +        dob.obj=SiSU_XHTML_EPUB2_Tune::CleanXHTML.new(dob.obj).clean +        @tuned_file << dob +      end +    end +    def urls(data) +      @words=[] +      map_nametags=SiSU_Particulars::CombinedSingleton.instance.get_map_nametags(@md).nametags_map #p map_nametags +      data.each do |word| +        @words << if word=~/#{Mx[:lnk_o]}(.+?)#{Mx[:lnk_c]}(?:#{Mx[:url_o]}\S+?#{Mx[:url_c]}|#{Mx[:rel_o]}\S+?#{Mx[:rel_c]}|image)/ +          http_=true +          if word =~/#{Mx[:lnk_o]}.+?#{Mx[:lnk_c]}#{Mx[:url_o]}\S+?#{Mx[:url_c]}/ +            m,u=/#{Mx[:lnk_o]}(.+?)#{Mx[:lnk_c]}#{Mx[:url_o]}(\S+?)#{Mx[:url_c]}/.match(word).captures +          elsif word =~/#{Mx[:lnk_o]}.+?#{Mx[:lnk_c]}#{Mx[:rel_o]}\S+?#{Mx[:rel_c]}/ +            http_=false +            m,u=/#{Mx[:lnk_o]}(.+?)#{Mx[:lnk_c]}#{Mx[:rel_o]}(\S+?)#{Mx[:rel_c]}/.match(word).captures +          elsif word =~/#{Mx[:lnk_o]}.+?#{Mx[:lnk_c]}image/ +            m,u=/#{Mx[:lnk_o]}(.+?)#{Mx[:lnk_c]}(image)/.match(word).captures +          end +          case m +          when /\.png|\.jpg|\.gif|c=|\s\d+x\d+/ +            w,h=/\s(\d+)x(\d+)/.match(m).captures if m =~/\s\d+x\d+/ +            w=%{width="#{w}"} if w +            h=%{height="#{h}"} if h +            c=m[/"(.+?)"/m,1] +            caption=%{<br /><p class="caption">#{c}</p>} if c +            png=m.scan(/\S+/)[0] +            image_path=@md.file.output_path.epub.rel_image #image_path=@env.url.images_epub +            ins=if u \ +            and u.strip !~/^image$/ +              %{<a href="#{u}"><img src="#{image_path}/#{png}" #{w} #{h} naturalsizeflag="0" align="bottom" border="0" /></a>#{caption}} +            else %{<img src="#{image_path}/#{png}" #{w} #{h} naturalsizeflag="0" align="bottom" border="0" />#{caption}} +            end +            word=word.gsub(/#{Mx[:lnk_o]}.+?#{Mx[:lnk_c]}(?:#{Mx[:url_o]}\S+?#{Mx[:url_c]}|image)/,ins) +          else +            link=m[/(.+)/m] +            png=m.scan(/\S+/)[0].strip +            link=link.strip +            u=u.sub(/^#*/,'') #make neater +            if map_nametags[u] \ +            and map_nametags[u][:segname] +              u=unless http_ +                u=if u=~/^\d+$/ +                  u.gsub(/^(\d+)$/,"#{map_nametags[u][:segname]}#{Sfx[:xhtml]}#o\\1") if u !~/\// +                else +                  u.gsub(/(\S+)/,"#{map_nametags[u][:segname]}#{Sfx[:xhtml]}#\\1") if u !~/\// +                end +              else u +              end +            elsif u =~/^:/ +              u=u.gsub(/^:/,"#{@env.url.root}/") +            elsif u =~/^\.\.\// +              u=u.gsub(/^\.\.\//,"#{@env.url.root}/") +            elsif u =~/https?:\/\// +            else p "NOT FOUND name_tags: #{u}" +            end +            ins=%{<a href="#{u}">#{link}</a>} +            word=word.gsub(/#{Mx[:lnk_o]}.+?#{Mx[:lnk_c]}#{Mx[:url_o]}\S+?#{Mx[:url_c]}/,ins). +              gsub(/#{Mx[:lnk_o]}.+?#{Mx[:lnk_c]}#{Mx[:rel_o]}\S+?#{Mx[:rel_c]}/,ins) +          end +          word +        else word +        end +        word +      end +      @words=@words.join(' ') +    end +    def url_markup +      data=@data +      @tuned_file=[] +      data.each do |dob| +        unless dob.is==:code +          if dob.obj =~/<::\s+/ #watch +            dob.obj=dob.obj.gsub(/<::\s+(\S+?)\s+!>/, +              %{<img src="#{@env.url.images_epub}/c_\\1.png" alt="\\1" width="14" height="14" align="bottom" border="0" />}) +          end +          if dob.obj =~/<:image\s+/ +            dob.obj=dob.obj.gsub(/<:image\s+(http\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+>/, +                %{<a href="\\1"><img src="#{@env.url.images_epub}/\\2" \\3 \\4 naturalsizeflag="0" align="bottom" border="0" /></a>}). +              gsub(/<:image\s+(http\S+)\s+(\S+)\s+>/, +                %{<a href="\\1"><img src="#{@env.url.images_epub}/\\2" naturalsizeflag="0" align="bottom" border="0" /></a>}). +              gsub(/<:image\s+(\S+)\s+(\S+)\s+(\S+)\s+>/, +                %{<img src="#{@env.url.images_epub}/\\1" \\2 \\3 naturalsizeflag="0" align="bottom" border="0" />}). +              gsub(/<:image\s+(\S+)\s+>/, +                %{<img src="#{@env.url.images_epub}/\\1" naturalsizeflag="0" align="bottom" border="0" />}) +          end +          if dob.obj =~/#{Mx[:lnk_o]}.+?#{Mx[:lnk_c]}(?:#{Mx[:url_o]}\S+?#{Mx[:url_c]}|#{Mx[:rel_o]}\S+?#{Mx[:rel_c]}|image)/ +            @word_mode=dob.obj.scan(/#{Mx[:lnk_o]}.+?#{Mx[:lnk_c]}(?:#{Mx[:url_o]}\S+?#{Mx[:url_c]}|#{Mx[:rel_o]}\S+?#{Mx[:rel_c]}|image)[()\[\]]*[,.;:!?'"]{0,2}|(?:#{Mx[:gl_o]}\S+?#{Mx[:gl_c]})+|[^#{Mx[:lnk_o]}#{Mx[:lnk_c]}]+/mu) +            words=urls(@word_mode) +            dob.obj=dob.obj.gsub(/.+/m,words) +          end +          dob.obj=dob.obj.gsub(/\\copyright/i,%{<sup>©</sup>}) +          dob.obj=if (dob.obj !~/\<:ad\s+\.\.\//) +            dob.obj.gsub(/\<:ad\s+(\S+)?\s+(\S+\.png)\s+(.+)?\;\s+(.+)?\;\s*!\>/, +              %{\n<center><a href="http:\/\/\\1" target="external"><img src="#{@env.url.images_epub}/\\2" alt="\\3" /></a></center>\n}) +          else +            dob.obj.gsub(/\<:ad\s+(\S+)?\s+(\S+\.png)\s+(.+)?\;\s+(.+)?\;\s*\>/, +              %{\n<center><a href="\\1" target="_top"><img src="#{@env.url.images_epub}/\\2" alt="\\3" /></a></center>\n}) +          end +          dob.obj=dob.obj.gsub(/!pick/,%{<img border="0" height="15" width="15" src="#{@env.url.images_epub}/#{the_icon.i_choice}" alt="stellar" />}). +            gsub(/!new/,%{#{$ep[:hsp]}<img border="0" height="15" width="15" src="#{@env.url.images_epub}/#{the_icon.i_new}" alt="new" />}). +            gsub(/<:h(.{1,7}?)>/,'<a href="#h\1">\1</a>'). +            gsub(/<:to(\d{1,7}?)>/,%{<a href="#to\\1">to#{$ep[:hsp]}\{#{$ep[:hsp]}\\1#{$ep[:hsp]}\}</a> }). +            gsub(/#{Mx[:url_o]}_(\S+?)#{Mx[:url_c]}/,'<a href="\1" target="_top">\1</a>'). #http ftp matches escaped, no decoration +            gsub(/#{Mx[:url_o]}([a-zA-Z0-9._-]+\@\S+?\.[a-zA-Z0-9._-]+)#{Mx[:url_c]}/,%{#{the_url_decoration.xml_open}<a href="mailto:\\1">\\1</a>#{the_url_decoration.xml_close}}). +            gsub(/#{Mx[:url_o]}(\S+?)#{Mx[:url_c]}/,%{#{the_url_decoration.xml_open}<a href="\\1" target="_top">\\1</a>#{the_url_decoration.xml_close}}) #http ftp matches with decoration +          if dob.obj =~/..\/\S+/ \ +          and dob.obj !~/(\"..\/\S+?\"|>\s*..\/\S+<)/ +            dob.obj=dob.obj.gsub(/(\.\.\/\S+)/,'<a href="\1">\1</a>') +          end +          dob.obj=dob.obj.gsub(/<a href="\.\.\//,%{<a href="#{the_url.site}/}) +        else +          dob.obj=dob.obj.gsub(/</m,'<').gsub(/>/m,'>') +        end +        @tuned_file << dob +      end +    end +    def amp_angle_brackets +      data,data_new=@data,[] +      data.each do |dob| +        dob.obj=dob.obj. +          gsub(/&/u,'&'). +          gsub(/</u,'<').gsub(/>/u,'>') +        data_new << dob +      end +      data_new +    end +    def endnotes_html +      data=@data +      @tuned_file=[] +      a,s='_a','_s' +      ast,pls='*','+' +      data.each do |dob| +        unless dob.is ==:code +          dob.obj=dob.obj.gsub(/(#{Mx[:en_a_o]}|#{Mx[:en_b_o]})(\d+)\s+(.+?)(#{Mx[:en_a_c]}|#{Mx[:en_b_c]})/, +              %{#{Mx[:nbsp]}<a href="##{Mx[:note]}\\2">#{Mx[:nbsp]}<sup id="#{Mx[:note_ref]}\\2">\\2</sup>#{Mx[:nbsp]}</a> } +  #note- endnote- +              %{\\1\\2 <a href="##{Mx[:note_ref]}\\2">#{Mx[:nbsp]}<sup id="#{Mx[:note]}\\2">\\2.</sup></a> \\3 \\4}). #endnote- note- (careful may have switched) +            gsub(/(#{Mx[:en_b_o]})[*](\d+)\s+(.+?)(#{Mx[:en_b_c]})/, +              %{#{Mx[:nbsp]}<a href="##{Mx[:note_astx]}\\2">#{Mx[:nbsp]}<sup id="#{Mx[:note_ref_astx]}\\2">#{ast}\\2</sup>#{Mx[:nbsp]}</a> } +  #note- endnote- +              %{\\1#{ast}\\2 <a href="##{Mx[:note_ref_astx]}\\2">#{Mx[:nbsp]}<sup id="#{Mx[:note_astx]}\\2">#{ast}\\2.</sup></a> \\3 \\4}). #endnote- note- (careful may have switched) +            gsub(/(#{Mx[:en_b_o]})[+](\d+)\s+(.+?)(#{Mx[:en_b_c]})/, +              %{#{Mx[:nbsp]}<a href="##{Mx[:note_plus]}\\2">#{Mx[:nbsp]}<sup id="#{Mx[:note_ref_plus]}\\2">#{pls}\\2</sup>#{Mx[:nbsp]}</a> } +  #note- endnote- +              %{\\1#{pls}\\2 <a href="##{Mx[:note_ref_plus]}\\2">#{Mx[:nbsp]}<sup id="#{Mx[:note_plus]}\\2">#{pls}\\2.</sup></a> \\3 \\4}) #endnote- note- (careful may have switched) # double-check there may here be a bug +          if dob.obj =~/#{Mx[:en_a_o]}([*+]+)\s+.+?#{Mx[:en_a_c]}/ +            m=$1.length.to_i +            dob.obj=dob.obj.gsub(/(#{Mx[:en_a_o]})[*]+\s+(.+?)(#{Mx[:en_a_c]})/, +                %{#{Mx[:nbsp]}<a href="##{Mx[:note]}#{a*m}">#{Mx[:nbsp]}<sup id="#{Mx[:note_ref]}#{a*m}">#{ast*m}</sup>#{Mx[:nbsp]}</a> } +  #note- endnote- +                %{\\1#{ast*m} <a href="##{Mx[:note_ref]}#{a*m}">#{Mx[:nbsp]}<sup id="#{Mx[:note]}#{a*m}">#{ast*m}</sup></a> \\2 \\3}). #endnote- note- (careful may have switched) +              gsub(/(#{Mx[:en_a_o]})([+]+)\s+(.+?)(#{Mx[:en_a_c]})/, +                %{#{Mx[:nbsp]}<a href="##{Mx[:note]}#{s*m}">#{Mx[:nbsp]}<sup id="#{Mx[:note_ref]}#{s*m}">#{pls*m}</sup>#{Mx[:nbsp]}</a> } +  #note- endnote- +                %{\\1#{pls*m} <a href="##{Mx[:note_ref]}#{s*m}">#{Mx[:nbsp]}<sup id="#{Mx[:note]}#{s*m}">#{pls*m}</sup></a> \\2 \\3}) #endnote- note- (careful may have switched) +          end +        end +        @tuned_file << dob +      end +    end +    def output +      data=@data +      @tuned_file=[] +      data.each do |dob| +        dob.obj=dob.obj.strip.chomp +        @tuned_file << dob +      end +      @tuned_file << "\n<EOF>" if (@md.fns =~/\.sst0/) #remove +      @tuned_file +    end +  end +end +__END__ +#+END_SRC + +* xhtml shared +** xhtml_parts.rb + +#+BEGIN_SRC ruby  :tangle "../lib/sisu/xhtml_parts.rb" +# <<sisu_document_header>> +module SiSU_Parts_XHTML +  require_relative 'generic_parts'                       # generic_parts.rb +  include SiSU_Parts_Generic +  def the_line_break +    '<br />' +  end +  def the_table_close +    '</td></tr> +</table>' +  end +  def the_url +    def home +      'http://www.sisudoc.org/' # used in pdf header +    end +    def site #used as stub... where there are subdirectories and is different from home +      home +    end +    self +  end +  def the_url_decoration +    def xml_open                     #'<' +      Dx[:url_o] +    end +    def xml_close                    #'>' +      Dx[:url_c] +    end +    def txt_open +      '<' +    end +    def txt_close +      '>' +    end +    self +  end +  def the_margin +    def txt_0 +      %{<table summary="" width=#{the_width.table_txt} border="0" cellpadding="2" align="center"> +<tr><td width=#{indent_level_0} align="right"> +</td><td valign="top" align="justify">} +    end +    def txt_1 +      %{<table summary="" width=#{the_width.table_txt} border="0" cellpadding="2" align="center"> +<tr><td width=#{indent_level_1} align="right"></td><td valign="top" align="justify">} +    end +    def txt_2 +      %{<table summary="" width=#{the_width.table_txt} border="0" cellpadding="2" align="center"> +<tr><td width=#{indent_level_2} align="right"> +</td> +<td valign="top" align="justify">} +    end +    def txt_3 +      %{<table summary="" width=#{the_width.table_txt} border="0" cellpadding="2" align="center"> +<tr><td width=#{indent_level_3} align="right"> +</td> +<td valign="top" align="justify">} +    end +    def css +      '<table summary="normal text css" width="100%" border="0" cellpadding="2" align="center"> +<tr><td valign="top" align="justify"> ' +    end +    def num_css +      '</td> +<td width="2%" align="right" valign="top">  ' +    end +    self +  end +  def the_font +    def set_fonts +      'verdana, arial, georgia, tahoma, sans-serif, helvetica, times, roman' +     #'verdana, arial, georgia, tahoma, sans-serif, helvetica, "times new roman", times, roman' +    end +    def set_small +      'size="3"' +    end +    def set_tiny +      'size="2"' +    end +    def paragraph_font_tiny +      %{<font #{set_tiny} #{set_face}>} +    end +    def paragraph_font_small +      %{<font #{set_small} #{set_face}>} +    end +    self +  end +  def the_nav +    def txt_concordance +      %{  <font face="#{the_font.set_fonts}" size="2"> +      A-Z  +  </font> } +    end +    def txt_toc_link +      %{  <font face="#{the_font.set_fonts}" size="2"> +      toc  +  </font> } +    end +    def txt_manifest +      #{png_manifest} document manifest +      %{  <font face="#{the_font.set_fonts}" size="2"> +    [ document manifest ] +  </font> } +    end +    def txt_concordance +      %{  <font face="#{the_font.set_fonts}" size="2"> +      A-Z  +  </font> } +    end +    self +  end +end +module SiSU_Proj_XHTML +  require_relative 'se'                                 # se.rb +    include SiSU_Env +  class Bits +    include SiSU_Parts_HTML +    def initialize +      @v=SiSU_Env::InfoVersion.instance.get_version +    end +    def credits_sisu_epub +      %{<div class="substance"> +<p class="center"><a href="http://www.openebook.org"><b>EPUB</b></a> generated by <a href="http://www.sisudoc.org"><b>#{@v.project}</b></a> v#{@v.version}, GPL3</p> +</div>} +      '' +    end +  end +end +__END__ +#+END_SRC + +** xhtml_shared.rb + +#+BEGIN_SRC ruby  :tangle "../lib/sisu/xhtml_shared.rb" +# <<sisu_document_header>> +module SiSU_XHTML_Shared +  require_relative 'xhtml_table'                        # xhtml_table.rb +  class TableXHTML < SiSU_XHTML_Table::TableXHTML +  end +end +__END__ +#+END_SRC + +** xhtml_table.rb + +#+BEGIN_SRC ruby  :tangle "../lib/sisu/xhtml_table.rb" +# <<sisu_document_header>> +module SiSU_XHTML_Table +  require_relative 'xhtml_parts'                         # xhtml_parts.rb +  class TableXHTML +    include SiSU_Parts_XHTML +    @@tablefoot=[] #watch +    def initialize(table) +      @table_obj=table +    end +    def table +      table_obj=@table_obj +      if table_obj.obj !~/^<table\s/m +        table_obj=table_rows_and_columns_array(table_obj) +      else p __LINE__; p caller +      end +      table_obj +    end +    def table_rows_and_columns_array(table_obj) # provides basic (x)html table +      table_rows,nr=[],0 +      table_obj.obj.split(Mx[:tc_c]).each do |table_row| +        table_row_with_columns=table_row.split(Mx[:tc_p]) +        trc,nc=[],0 +        table_row_with_columns.each do |c| +          c=c.gsub(/^~$/,''). # tilde / empty cell +            gsub(/<:br>/,the_line_break) +          trc <<= if table_obj.head_ and nr==0; %{<th width="#{table_obj.widths[nc]}%">#{c}</th>} +          else %{<td width="#{table_obj.widths[nc]}%">#{c}</td>} +          end +          nc+=1 +        end +        trc=(trc.is_a?(Array)) ? trc.flatten.join : trc +        trc="      <tr>#{trc}</tr>\n" +        nr+=1 +        table_rows << trc +      end +      table_rows=table_rows.flatten.join +      table_obj.obj=%{<table summary="normal text css" width="100%" border="0" bgcolor="white" cellpadding="2" align="center">\n#{table_rows}    </table>} +      table_obj +    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 +    xhtml + +  - 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 diff --git a/org/xml.org b/org/xml.org new file mode 100644 index 00000000..68452bfa --- /dev/null +++ b/org/xml.org @@ -0,0 +1,5583 @@ +-*- mode: org -*- +#+TITLE:       sisu xml including odf +#+DESCRIPTION: documents - structuring, various output representations & search +#+FILETAGS:    :sisu:xml: +#+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 + +* xml native +** xml_sax.rb + +#+BEGIN_SRC ruby  :tangle "../lib/sisu/xml_sax.rb" +# <<sisu_document_header>> +module SiSU_XML_SAX +  require_relative 'se_hub_particulars'                 # se_hub_particulars.rb +    include SiSU_Particulars +  require_relative 'se'                                 # se.rb +    include SiSU_Env +  require_relative 'xml_shared'                         # xml_shared.rb +    include SiSU_XML_Munge +  require_relative 'xml_format'                         # xml_format.rb +    include SiSU_XML_Format +  require_relative 'xml_persist'                        # xml_persist.rb +  require_relative 'rexml'                              # rexml.rb +    include SiSU_Rexml +  require_relative 'shared_metadata'                    # shared_metadata.rb +  @@alt_id_count=0 +  @@tablefoot='' +  class Source +    def initialize(opt) +      @opt=opt +      @particulars=SiSU_Particulars::CombinedSingleton.instance.get_all(opt) +    end +    def read +      begin +        @env,              @md,            @ao_arr= +          @particulars.env,@particulars.md,@particulars.ao_array +        unless @opt.act[:quiet][:set]==:on +          tool=if (@opt.act[:verbose_plus][:set]==:on \ +          || @opt.act[:maintenance][:set]==:on) +            @env.program.web_browser \ +            + ' file://' \ +            + @md.file.output_path.xml_sax.dir + '/' \ +            + @md.file.base_filename.xml_sax + "\n\t" \ +            + @env.program.xml_viewer \ +            + ' file://' \ +            + @md.file.output_path.xml_sax.dir + '/' \ +            + @md.file.base_filename.xml_sax +          elsif @opt.act[:verbose][:set]==:on +            @env.program.web_browser \ +            + ' file://' \ +            + @md.file.output_path.xml_sax.dir + '/' \ +            + @md.file.base_filename.xml_sax +          else "[#{@opt.f_pth[:lng_is]}] #{@opt.fno}" +          end +          (@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], +              'XML SAX', +              tool +            ).green_hi_blue +          : SiSU_Screen::Ansi.new( +              @opt.act[:color_state][:set], +              'XML SAX', +              tool +            ).green_title_hi +          if (@opt.act[:verbose_plus][:set]==:on \ +          || @opt.act[:maintenance][:set]==:on) +            SiSU_Screen::Ansi.new( +              @opt.act[:color_state][:set], +              @opt.fns, +              'file://' \ +              + @md.file.output_path.xml_sax.dir + '/' \ +              + @md.file.base_filename.xml_sax +            ).flow +          end +        end +        SiSU_XML_SAX::Source::Songsheet.new(@particulars).song +      rescue +        SiSU_Errors::Rescued.new($!,$@,@opt.selections.str,@opt.fns).location do +          __LINE__.to_s + ':' + __FILE__ +        end +      ensure +        #file closed in songsheet +        SiSU_Env::CreateSite.new(@opt).cp_css +        Dir.chdir(@opt.f_pth[:pth]) +      end +    end +    private +    class Songsheet +      def initialize(particulars) +        @env,             @md,           @ao_arr,             @particulars= +          particulars.env,particulars.md,particulars.ao_array,particulars +        @file=SiSU_Env::FileOp.new(@md) +      end +      def song +        begin +          SiSU_XML_SAX::Source::Scroll.new(@particulars).songsheet +          if (@md.opt.act[:verbose][:set]==:on \ +          || @md.opt.act[:verbose_plus][:set]==:on \ +          || @md.opt.act[:maintenance][:set]==:on) +            SiSU_XML_SAX::Source::Tidy.new(@md,@file.place_file.xml_sax.dir).xml # test wellformedness, comment out when not in use +          end +          SiSU_Rexml::Rexml.new(@md,@file.place_file.xml_sax.dir).xml if @md.opt.act[:maintenance][:set]==:on # test rexml parsing, comment out when not in use #debug +        rescue +          SiSU_Errors::Rescued.new($!,$@,@md.opt.selections.str,@md.fns).location do +            __LINE__.to_s + ':' + __FILE__ +          end +        ensure +        end +      end +    end +    class Scroll +      require_relative 'txt_shared'                     # txt_shared.rb +        include SiSU_TextUtils +      require_relative 'css'                            # css.rb +      require_relative 'xhtml_shared'                   # decide use, whether xml rather than xhtml +      def initialize(particulars) +        @env,             @md,           @ao_arr= +          particulars.env,particulars.md,particulars.ao_array +        @trans=SiSU_XML_Munge::Trans.new(@md) +        @sys=SiSU_Env::SystemCall.new +        @per=SiSU_XML_Persist::Persist.new +      end +      def songsheet +        begin +          pre +          @data=markup(@ao_arr) +          post +          publish +        ensure +          SiSU_XML_Persist::Persist.new.persist_init +        end +      end +    protected +      def embedded_endnotes(dob='') +        dob.obj=dob.obj.gsub(/#{Mx[:en_a_o]}(\d+)\s+(.+?)#{Mx[:en_a_c]}/, +            '<endnote><number>\1</number><note>\2</note></endnote> '). +          gsub(/#{Mx[:en_b_o]}([*+]\d+)\s+(.+?)#{Mx[:en_b_c]}/, +            '<endnote><symbol>\1</symbol><note>\2</note></endnote> '). +          gsub(/#{Mx[:en_a_o]}([*+]+)\s+(.+?)#{Mx[:en_a_c]}/, +            '<endnote><symbol>\1</symbol><note>\2</note></endnote> ') +      end +      def extract_endnotes(dob='') +        notes=dob.obj.scan(/(?:#{Mx[:en_a_o]}|#{Mx[:en_b_o]})([\d*+]+\s+.+?)(?:#{Mx[:en_a_c]}|#{Mx[:en_b_c]})/) +        notes.flatten.each do |e| +          s=e.to_s +          util=SiSU_TextUtils::Wrap.new(s,70) +          wrap=util.line_wrap +          wrap=wrap.gsub(/^(\d+)\s+(.+?)\s*\Z/m, <<WOK +#{Ax[:tab]*1}<endnote notenumber="\\1"> +#{Ax[:tab]*2}<number>\\1</number> +#{Ax[:tab]*2}<note> +#{Ax[:tab]*3}\\2 +#{Ax[:tab]*2}</note> +#{Ax[:tab]*1}</endnote> +WOK +). +            gsub(/^([*+]\d+)\s+(.+?)\s*\Z/m, <<WOK +#{Ax[:tab]*1}<endnote symbol="\\1"> +#{Ax[:tab]*2}<symbol>\\1</symbol> +#{Ax[:tab]*2}<note> +#{Ax[:tab]*3}\\2 +#{Ax[:tab]*2}</note> +#{Ax[:tab]*1}</endnote> +WOK +). +            gsub(/^([*+]+)\s+(.+?)\s*\Z/m, <<WOK +#{Ax[:tab]*1}<endnote symbol="\\1.length"> +#{Ax[:tab]*2}<symbol>\\1</symbol> +#{Ax[:tab]*2}<note> +#{Ax[:tab]*3}\\2 +#{Ax[:tab]*2}</note> +#{Ax[:tab]*1}</endnote> +WOK +) +          @endnotes << wrap +        end +      end +      def xml_head +        metadata=SiSU_Metadata::Summary.new(@md).xml_sax.metadata +        @per.head << metadata +      end +      def xml_sc(md='') +        sc=if @md.sc_info +          <<WOK +    <source_control> +      <meta>filename:</meta> +      <sc class="sourcefile"> +        #{@md.sc_filename} +      </sc><br /> +      <meta>version number:</meta> +      <sc class="number"> +        #{@md.sc_number} +      </sc><br /> +      <meta>version date:</meta> +      <sc class="date"> +        #{@md.sc_date} +      </sc><br /> +    </source_control> +WOK +        else '' +        end +        @per.sc=sc +      end +      def xml_structure(dob,type='norm') +        if dob.is==:heading +          lv=dob.ln +          dob.ln + 2 +        else lv=nil +        end +        extract_endnotes(dob) +        dob.obj=dob.obj.gsub(/#{Mx[:en_a_o]}([\d*+]+)\s+(?:.+?)#{Mx[:en_a_c]}/,'<en>\1</en>'). #footnote/endnote clean +          gsub(/#{Mx[:en_b_o]}([\d*+]+)\s+(?:.+?)#{Mx[:en_b_c]}/,'<en>\1</en>') #footnote/endnote clean +        #if defined? dob.obj +        #t_ograph="#{dob.obj}" +        util=SiSU_TextUtils::Wrap.new(dob.obj,70) +        wrapped=util.line_wrap +        #end +        @per.body << if defined? dob.ocn; %{#{Ax[:tab]*0}<object id="#{dob.ocn}">} +        else                              "#{Ax[:tab]*0}<object>" +        end +        @per.body << "#{Ax[:tab]*1}<ocn>#{dob.ocn}</ocn>" if defined? dob.ocn +        @per.body << if lv; %{#{Ax[:tab]*1}<text class="h#{lv}">\n#{Ax[:tab]*2}#{wrapped}\n#{Ax[:tab]*1}</text>} +        else                   %{#{Ax[:tab]*1}<text class="#{type}">\n#{Ax[:tab]*2}#{wrapped}\n#{Ax[:tab]*1}</text>} # main text, contents, body KEEP +        end +        @per.body << @endnotes if @endnotes +        ##@per.body << "#{Ax[:tab]*1}<text>#{dob[@regx,2]}</text>" if dob[@regx,2] # old unwrapped main text, contents, body KEEP +        @per.body << "#{Ax[:tab]*0}</object>" +        @endnotes=[] +      end +      def block_structure(dob='') +        extract_endnotes(dob) +        dob.obj=dob.obj.gsub(/#{Mx[:en_a_o]}([\d*+]+)\s+(?:.+?)#{Mx[:en_a_c]}/,'<en>\1</en>'). #footnote/endnote clean +          gsub(/#{Mx[:en_b_o]}([\d*+]+)\s+(?:.+?)#{Mx[:en_b_c]}/,'<en>\1</en>') #footnote/endnote clean +        dob=@trans.markup_block(dob) +        dob.obj=dob.obj.strip +        @per.body << %{#{Ax[:tab]*0}<object id="#{dob.ocn}">} +        @per.body << %{#{Ax[:tab]*1}<ocn>#{dob.ocn}</ocn>} +        @per.body << %{#{Ax[:tab]*1}<text class="block">#{Ax[:tab]*1}} +        @per.body << %{#{Ax[:tab]*2}#{dob.obj}#{Ax[:tab]*1}} +        @per.body << %{#{Ax[:tab]*1}</text>} +        @per.body << "#{Ax[:tab]*0}</object>" +        @per.body << @endnotes if @endnotes +        @endnotes=[] +      end +      def group_structure(dob='') +        extract_endnotes(dob) +        dob.obj=dob.obj.gsub(/#{Mx[:en_a_o]}([\d*+]+)\s+(?:.+?)#{Mx[:en_a_c]}/,'<en>\1</en>'). #footnote/endnote clean +          gsub(/#{Mx[:en_b_o]}([\d*+]+)\s+(?:.+?)#{Mx[:en_b_c]}/,'<en>\1</en>') #footnote/endnote clean +        dob=@trans.markup_group(dob) +        dob.obj=dob.obj.strip +        @per.body << %{#{Ax[:tab]*0}<object id="#{dob.ocn}">} +        @per.body << %{#{Ax[:tab]*1}<ocn>#{dob.ocn}</ocn>} +        @per.body << %{#{Ax[:tab]*1}<text class="group">#{Ax[:tab]*1}} +        @per.body << %{#{Ax[:tab]*2}#{dob.obj}#{Ax[:tab]*1}} +        @per.body << %{#{Ax[:tab]*1}</text>} +        @per.body << "#{Ax[:tab]*0}</object>" +        @per.body << @endnotes if @endnotes +        @endnotes=[] +      end +      def poem_structure(dob='') +        dob=@trans.markup_group(dob) +        #dob.obj.gsub(/\s\s/,'  ') +        dob.obj=dob.obj.strip +        @per.body << %{#{Ax[:tab]*0}<object id="#{dob.ocn}">} +        @per.body << %{#{Ax[:tab]*1}<ocn>#{dob.ocn}</ocn>} +        @per.body << %{#{Ax[:tab]*1}<text class="verse">#{Ax[:tab]*1}} +        @per.body << %{#{Ax[:tab]*2}#{dob.obj}#{Ax[:tab]*1}} +        @per.body << %{#{Ax[:tab]*1}</text>} +        @per.body << %{#{Ax[:tab]*0}</object>} +      end +      def code_structure(dob='') +        dob=@trans.markup_group(dob) +        dob.obj=dob.obj.gsub(/\s\s/,'  ').strip +        @per.body << %{#{Ax[:tab]*0}<object id="#{dob.ocn}">} +        @per.body << %{#{Ax[:tab]*1}<ocn>#{dob.ocn}</ocn>} +        @per.body << %{#{Ax[:tab]*1}<text class="code">#{Ax[:tab]*1}} +        @per.body << %{#{Ax[:tab]*2}#{dob.obj}#{Ax[:tab]*1}} +        @per.body << %{#{Ax[:tab]*1}</text>} +        @per.body << "#{Ax[:tab]*0}</object>" +      end +      def table_structure(dob) +        table=SiSU_XHTML_Shared::TableXHTML.new(dob) +        @per.body << %{#{Ax[:tab]*0}<object id="#{dob.ocn}">} +        @per.body << %{#{Ax[:tab]*1}<ocn>#{dob.ocn}</ocn>} +        @per.body << %{#{Ax[:tab]*1}<text class="table">#{Ax[:tab]*1}} +        @per.body << %{#{Ax[:tab]*2}#{table.table.obj}} +        @per.body << %{#{Ax[:tab]*1}</text>} +        #@per.body << %{#{tab*1}</text>} +        @per.body << "#{Ax[:tab]*0}</object>" +       #@per.body << %{#{Ax[:tab]*0}<object id="#{ocn}">} +       #@per.body << %{#{Ax[:tab]*1}#{table}\n#{Ax[:tab]*1}} # unless lv  # main text, contents, body KEEP +       #@per.body << "#{Ax[:tab]*0}</object>" +       #@endnotes=[] +      end +      def markup(data) +        xml_sc(@md) +        @endnotes,@level,@cont,@copen,@xml_contents_close=[],[],[],[],[] +        @rcdc=false +        xml_head +        (0..7).each { |x| @cont[x]=@level[x]=false } +        (4..7).each { |x| @xml_contents_close[x]='' } +        data.each do |dob| +          @trans.char_enc.utf8(dob) if @sys.locale =~/utf-?8/i #% utf8 +          dob=@trans.markup(dob) +          if @rcdc==false \ +          and (dob.is ==:meta \ +          and dob.obj =~/Document Information/) +            @rcdc=true +          end +          if dob.obj !~/(^#{Rx[:meta]}|#{Mx[:br_eof]}|#{Mx[:br_endnotes]})/ +            if defined? dob.ocn #look to move to format section +              ocn=((dob.ocn.to_s =~/\d+/) ? dob.ocn : nil) +              @p_num=SiSU_XML_Format::ParagraphNumber.new(@md,ocn) +            end +            if not @rcdc +              if defined? dob.ocn \ +              and dob.ocn.to_s =~/\d+/ +                x=SiSU_XML_Format::FormatSeg.new(@md,dob) +                if dob.is==:heading +                  xml_structure(dob) +                  dob.obj=case dob.ln +                  when 1 then x.heading_body1 +                  when 2 then x.heading_body2 +                  when 3 then x.heading_body3 +                  when 4 then x.heading_body4 +                  when 5 then x.heading_body5 +                  when 6 then x.heading_body6 +                  when 7 then x.heading_body7 +                  end +                else +                  if dob.is==:verse +                    poem_structure(dob) +                  elsif dob.is==:group +                    group_structure(dob) +                  elsif dob.is==:block +                    block_structure(dob) +                  elsif dob.is==:code +                    code_structure(dob) +                  elsif dob.is==:table # FIX, check css, will need to modify +                    table_structure(dob) +                  elsif dob.is ==:para \ +                  and dob.indent.to_s =~/[1-9]/ \ +                  and dob.bullet_==true +                    xml_structure(dob,"indent_bullet#{dob.indent}") +                  elsif dob.is ==:para \ +                  and dob.indent.to_s =~/[1-9]/ \ +                  and dob.indent == dob.hang +                    xml_structure(dob,"indent#{dob.indent}") +                  elsif dob.is ==:para \ +                  and dob.hang.to_s =~/[0-9]/ \ +                  and dob.indent != dob.hang +                    xml_structure(dob,"hang#{dob.hang.to_s}_indent#{dob.indent.to_s}") +                  else xml_structure(dob) +                  end +                end +              elsif dob.obj =~/(#{Mx[:br_eof]}|#{Mx[:br_endnotes]})/ +              elsif dob.obj =~/MetaData/ +                txt_obj={ txt: '<br /><a name="metadata">MetaData</a>' } +                format_scroll=FormatScroll.new(@md,txt_obj) +                dob.obj=format_scroll.bold_para +              elsif dob.obj =~/(Owner Details)/ +#               txt_obj={ txt: '<br /><a name="owner.details">Owner Details</a>' } +#               format_scroll=FormatScroll.new(@md,txt_obj) +#               @per.owner_details=format_scroll.bold_para +                dob.obj='' +              end +              if dob.obj =~/<a name="n\d+">/ \ +              and dob.obj =~/^(-\{{2}~\d+|<!e[:_]\d+!>)/ # -endnote +                dob.obj='' +              end +              if dob.obj =~/.*<:#>.*$/ #investigate removal +                dob.obj=if dob.obj =~ /#{Mx[:pa_o]}:i[1-9]#{Mx[:pa_c]}/ +                  txt_obj={ txt: dob } +                  format_text=FormatTextObject.new(@md,txt_obj) +                  format_text.scr_inden_ocn_e_no_paranum +                end +              end +            else # +            end +            dob.obj=dob.obj.gsub(/#{Mx[:pa_o]}:\S+#{Mx[:pa_c]}/,'') if dob.obj +          end +        end +        7.downto(4) do |x| +          y=x - 1; v=x - 3 +          @per.body << "#{Ax[:tab]*5}</content>\n#{Ax[:tab]*y}</contents#{v}>" if @level[x]==true +        end +        3.downto(1) do |x| +          y=x - 1 +          @per.body << "#{Ax[:tab]*y}</heading#{x}>" if @level[x]==true +        end +        #7.downto(1) { |x| y=x - 1; @per.body << "#{Ax[:tab]*y}</level #{x}>" if @level[x]==true } +      end +      def pre +        rdf=SiSU_XML_Tags::RDF.new(@md) +        @per.head,@per.body=[],[] +        stylesheet=SiSU_Style::CSS_HeadInfo.new(@md,'xml_sax').stylesheet +        encoding=if @sys.locale =~/utf-?8/i then '<?xml version="1.0" encoding="UTF-8" standalone="no"?>' +        else                                     '<?xml version="1.0" encoding="ISO-8859-1" standalone="no"?>' +        end +        @per.open =<<WOK +#{encoding} +#{stylesheet.css_head_xml} +#{rdf.comment_xml} +<document> +WOK +        @per.head << '<head>' +        @per.body << '<body>' +      end +      def post +        @per.head << @per.sc +        @per.head << '</head>' +        @per.body << '</body>' +        @per.close = '</document>' +      end +      def publish +        content=[] +        content << @per.open << @per.head << @per.body #<< @per.metadata +        #content << @per.owner_details if @md.stmp =~/\w\w/ +        content << @per.tail << @per.close +        content=content.flatten.compact +        Output.new(content,@md).xml +        @@xml={} +      end +    end +    class Output +      def initialize(data,md) +        @data,@md=data,md +        @file=SiSU_Env::FileOp.new(@md) +      end +      def xml +        SiSU_Env::FileOp.new(@md).mkdir +        filename_xml=@file.write_file.xml_sax +        @data.each do |str| +          str=str.gsub(/\A\s+\Z/m,'') +          filename_xml.puts str unless str.empty? +        end +        filename_xml.close +      end +    end +    class Tidy +      def initialize(md,file) +        @md,@file=md,file +        @prog=SiSU_Env::InfoProgram.new +      end +      def xml +        if @prog.tidy !=false #note values can be other than true +          if (@md.opt.act[:verbose_plus][:set]==:on \ +          || @md.opt.act[:maintenance][:set]==:on) +            unless @md.opt.act[:quiet][:set]==:on +              SiSU_Screen::Ansi.new( +                @md.opt.act[:color_state][:set], +                'invert', +                'Using XML Tidy', +                'check document structure' +              ).colorize +              tell=SiSU_Screen::Ansi.new( +                @md.opt.act[:color_state][:set], +                'invert', +                '', +                '' +              ) +              tell.grey_open +            end +            tidyfile='/dev/null' #don't want one or screen output, check for alternative flags +            tidy=SiSU_Env::SystemCall.new(@file,tidyfile) +            tidy.well_formed? +            tell.p_off unless @md.opt.act[:quiet][:set]==:on +          end +        end +      end +    end +  end +end +__END__ +#+END_SRC + +** xml_dom.rb + +#+BEGIN_SRC ruby  :tangle "../lib/sisu/xml_dom.rb" +# <<sisu_document_header>> +module SiSU_XML_DOM +  require_relative 'se_hub_particulars'                 # se_hub_particulars.rb +    include SiSU_Particulars +  require_relative 'se'                                 # se.rb +    include SiSU_Env +  require_relative 'ao'                                 # ao.rb +  require_relative 'xml_shared'                         # xml_shared.rb +    include SiSU_XML_Munge +  require_relative 'xml_format'                         # xml_format.rb +    include SiSU_XML_Format +  require_relative 'xml_persist'                        # xml_persist.rb +  require_relative 'rexml'                              # rexml.rb +    include SiSU_Rexml +  require_relative 'shared_metadata'                    # shared_metadata.rb +  @@alt_id_count=0 +  @@tablefoot='' +  class Source +    def initialize(opt) +      @opt=opt +      @particulars=SiSU_Particulars::CombinedSingleton.instance.get_all(opt) +    end +    def read +      begin +        @env,              @md,            @ao_arr= +          @particulars.env,@particulars.md,@particulars.ao_array +        unless @opt.act[:quiet][:set]==:on +          tool=if (@opt.act[:verbose_plus][:set]==:on \ +          || @opt.act[:maintenance][:set]==:on) +            @env.program.web_browser \ +            + ' file://' \ +            + @md.file.output_path.xml_dom.dir + '/' \ +            + @md.file.base_filename.xml_dom + "\n\t" \ +            + @env.program.xml_viewer \ +            + ' file://' \ +            + @md.file.output_path.xml_dom.dir + '/' \ +            + @md.file.base_filename.xml_dom +          elsif @opt.act[:verbose][:set]==:on +            @env.program.web_browser \ +            + ' file://' \ +            + @md.file.output_path.xml_dom.dir + '/' \ +            + @md.file.base_filename.xml_dom +          else "[#{@opt.f_pth[:lng_is]}] #{@opt.fno}" +          end +          (@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], +              'XML DOM', +              tool +            ).green_hi_blue +          : SiSU_Screen::Ansi.new( +              @opt.act[:color_state][:set], +              'XML DOM', +              tool +            ).green_title_hi +          if (@opt.act[:verbose_plus][:set]==:on \ +          || @opt.act[:maintenance][:set]==:on) +            SiSU_Screen::Ansi.new( +              @opt.act[:color_state][:set], +              @opt.fns, +              'file://' \ +              + @md.file.output_path.xml_dom.dir + '/' \ +              + @md.file.base_filename.xml_dom +            ).flow +          end +        end +        SiSU_XML_DOM::Source::Songsheet.new(@particulars).songsheet +      rescue +        SiSU_Errors::Rescued.new($!,$@,@opt.selections.str,@opt.fns).location do +          __LINE__.to_s + ':' + __FILE__ +        end +      ensure +        SiSU_Env::CreateSite.new(@opt).cp_css +        Dir.chdir(@opt.f_pth[:pth]) +      end +    end +    private +    class Songsheet +      def initialize(particulars) +        @env,             @md,           @ao_arr,             @particulars= +          particulars.env,particulars.md,particulars.ao_array,particulars +        @file=SiSU_Env::FileOp.new(@md) +      end +      def songsheet +        begin +          SiSU_XML_DOM::Source::Scroll.new(@particulars).songsheet +          if (@md.opt.act[:verbose][:set]==:on \ +          || @md.opt.act[:verbose_plus][:set]==:on \ +          || @md.opt.act[:maintenance][:set]==:on) +            SiSU_XML_DOM::Source::Tidy.new(@md,@file.place_file.xml_dom.dir).xml # test wellformedness, comment out when not in use +          end +          SiSU_Rexml::Rexml.new(@md,@file.place_file.xml_dom.dir).xml if @md.opt.act[:maintenance][:set]==:on # test rexml parsing, comment out when not in use #debug +        rescue +          SiSU_Errors::Rescued.new($!,$@,@md.opt.selections.str,@md.fns).location do +            __LINE__.to_s + ':' + __FILE__ +          end +        ensure +        end +      end +    end +    class Scroll +      require_relative 'txt_shared'                     # txt_shared.rb +        include SiSU_TextUtils +      require_relative 'xhtml_shared'                   # decide use, whether xml rather than xhtml +      def initialize(particulars) +        @env,             @md,           @ao_arr= +          particulars.env,particulars.md,particulars.ao_array +        @trans=SiSU_XML_Munge::Trans.new(@md) +        @sys=SiSU_Env::SystemCall.new +        @per=SiSU_XML_Persist::Persist.new +      end +      def songsheet +        begin +          pre +          @data=markup(@ao_arr) +          post +          publish +        ensure +          SiSU_XML_Persist::Persist.new.persist_init +        end +      end +    protected +      def xml_markup(dob='') +        dob.obj=dob.obj.gsub(/#{Mx[:en_a_o]}(\d+)\s+(.+?)#{Mx[:en_a_c]}/, +            '<endnote><number>\1</number><note>\2</note></endnote> '). +          gsub(/#{Mx[:en_b_o]}([*+]\d+)\s+(.+?)#{Mx[:en_b_c]}/, +            '<endnote><symbol>\1</symbol><note>\2</note></endnote> '). +          gsub(/#{Mx[:en_a_o]}([*+]+)\s+(.+?)#{Mx[:en_a_c]}/, +            '<endnote><symbol>\1</symbol><note>\2</note></endnote> ') +      end +      def xml_head +        metadata=SiSU_Metadata::Summary.new(@md).xml_dom.metadata +        @per.head << metadata +      end +      def xml_sc(md='') +        sc=if @md.sc_info +          <<WOK +    <source_control> +      <meta>filename:</meta> +      <sc class="sourcefile"> +        #{@md.sc_filename} +      </sc><br /> +      <meta>version number:</meta> +      <sc class="number"> +        #{@md.sc_number} +      </sc><br /> +      <meta>version date:</meta> +      <sc class="date"> +        #{@md.sc_date} +      </sc><br /> +    </source_control> +WOK +        else '' +        end +        @per.sc=sc +      end +      def xml_element(dob,xml_el='',xml_content='',type='norm') +        n=n1=n2=n3=0 +        if dob.is==:heading +          lv=dob.ln +          n=dob.ln +          n1=dob.ln +          n2=dob.ln + 2 +          n3=dob.ln + 3 +        else lv=nil +        end +        tag=if defined? dob.name and dob.name=~/\S+/ +          "\n#{Ax[:tab]*n3}<nametag>#{dob.name}</nametag>" +        else '' +        end +        xml_el ||='' +        @per.body <<<<WOK +#{Ax[:tab]*n}#{xml_el} +#{Ax[:tab]*n1}<heading> +#{Ax[:tab]*n2}<object id="#{dob.ocn}"> +#{Ax[:tab]*n3}<ocn>#{dob.ocn}</ocn>#{tag} +#{Ax[:tab]*n3}<text class="#{type}">#{dob.obj}</text> +#{Ax[:tab]*n2}</object> +#{Ax[:tab]*n1}</heading>#{xml_content} +WOK +        if lv==4 +          @copen[1]=true +          @copen[2]=@copen[3]=@copen[4]=false +        elsif lv==5 +          @copen[2]=true +          @copen[3]=@copen[4]=false +        elsif lv==6 +          @copen[3]=true +          @copen[4]=false +        elsif lv==7 +          @copen[4]=true +        end +      end +      def xml_structure(dob,type='norm') +        n=n1=n2=n3=0 +        if dob.is==:heading +          lv=dob.ln +          n=dob.ln - 1 +          n1=dob.ln +          n2=dob.ln + 1 +          n3=dob.ln + 2 +          dob.ln - 3 +        else lv=nil +        end +        case lv +        when 1..3 +          xml_el="<heading#{lv}>" +          3.downto(lv) do |x| +            y=x - 1 +            if @cont[1] \ +            or @cont[2] \ +            or @cont[3] +              @per.body << "#{Ax[:tab]*5}</content>" +            end +            @cont[1]=false if @cont[1] +            @cont[2]=false if @cont[2] +            @cont[3]=false if @cont[3] +            ####### attempt to close contents +            if @copen[4] # 4~ +              [4,3,2,1].each { |v| @per.body << "#{Ax[:tab]*n}</contents#{v}>" } +              @copen[1]=@copen[2]=@copen[3]=@copen[4]=false +            elsif @copen[3] # 3~ +              [3,2,1].each { |v| @per.body << "#{Ax[:tab]*n}</contents#{v}>" } +              @copen[1]=@copen[2]=@copen[3]=false +            elsif @copen[2] # 2~ +              [2,1].each { |v| @per.body << "#{Ax[:tab]*n}</contents#{v}>" } +              @copen[1]=@copen[2]=@copen[3]=false +            elsif @copen[1] # 1~ +              [1].each { |v| @per.body << "#{Ax[:tab]*n}</contents#{v}>" } +              @copen[1]=@copen[2]=@copen[3]=false +            end +            @per.body << "#{Ax[:tab]*y}</heading#{x}>" if @level[x] +            @level[x]=false +          end +        when 4..7 +          7.downto(lv) do |x| +            if @level[x]==true +              @xml_contents_close[x]='' +            end +          end +          cv=lv - 3 +          xml_el="<contents#{cv}>" +          xml_content="\n#{Ax[:tab]*5}<content>" +          case lv +          when 4 +            @per.body << "#{Ax[:tab]*5}</content>" if @cont[1] +            if @copen[4]==true # 4~ +              [4,3,2,1].each { |v| @per.body << "#{Ax[:tab]*n}</contents#{v}>" } +            elsif @copen[3]==true # 3~ +              [3,2,1].each { |v| @per.body << "#{Ax[:tab]*n}</contents#{v}>" } +            elsif @copen[2]==true # 2~ +              [2,1].each { |v| @per.body << "#{Ax[:tab]*n}</contents#{v}>" } +            elsif @copen[1]==true # 1~ +              [1].each { |v| @per.body << "#{Ax[:tab]*n}</contents#{v}>" } +            end +            @cont[1]=true +          when 5 +            if @cont[3] \ +            or @cont[2] \ +            or @cont[1] +              @per.body << "#{Ax[:tab]*5}</content>" +            end +            if @copen[4]==true  #4~ +              [4,3,2].each { |v| @per.body << "#{Ax[:tab]*n}</contents#{v}>" } +            elsif @copen[3]==true  #3~ +              [3,2].each { |v| @per.body << "#{Ax[:tab]*n}</contents#{v}>" } +            elsif @copen[2]==true #2~ +              [2].each { |v| @per.body << "#{Ax[:tab]*n}</contents#{v}>" } +            end +            @cont[2]=true +          when 6 +            if @cont[4] \ +            or @cont[3] \ +            or @cont[2] \ +            or @cont[1] +              @per.body << "#{Ax[:tab]*5}</content>" +            end +            if @copen[4] #4~ +              [4,3].each { |v| @per.body << "#{Ax[:tab]*n}</contents#{v}>" } +            elsif @copen[3] #3~ +              [3].each { |v| @per.body << "#{Ax[:tab]*n}</contents#{v}>" } +            end +            @cont[3]=true +          when 7 +            if @cont[4] \ +            or @cont[3] \ +            or @cont[2] \ +            or @cont[1] +              @per.body << "#{Ax[:tab]*5}</content>" +            end +            if @copen[4] #4~ +              [4].each { |v| @per.body << "#{Ax[:tab]*n}</contents#{v}>" } +            end +            @cont[4]=true +          end +        end +        xml_el ||='' +        xml_element(dob,xml_el,xml_content,type) +        if lv +          @level[lv]=true +          ((lv+1)..7).each { |x| @level[x]=false } +        end +      end +      def add_to_body(dob,type='norm') +        if defined? dob.obj # main text, contents, body KEEP +          if defined? dob.ocn \ +          and dob.ocn +            @per.body << %{#{Ax[:tab]*6}<object id="#{dob.ocn}">} +            @per.body << %{#{Ax[:tab]*7}<ocn>#{dob.ocn}</ocn>} if defined? dob.ocn +          end +          #@per.body << %{#{Ax[:tab]*7}<text class="#{type}">#{dob.obj}</text>} +          #@per.body << %{#{Ax[:tab]*7}<text class="#{dob.is}">#{Ax[:tab]*1}} +          @per.body << %{#{Ax[:tab]*7}<text class="#{type}">#{Ax[:tab]*1}} +          @per.body << %{#{Ax[:tab]*8}#{dob.obj}#{Ax[:tab]*1}} +          @per.body << %{#{Ax[:tab]*7}</text>} +          @per.body << %{#{Ax[:tab]*6}</object>} +        end +      end +      def block_structure(dob) +        dob=@trans.markup_block(dob) #decide check & FIX +        dob.obj=dob.obj.gsub(/#{Mx[:en_a_o]}(\d+)\s+(.+?)#{Mx[:en_a_c]}/m, +          '<endnote><number>\1</number><note>\2</note></endnote> ').strip +        dob +      end +      def group_structure(dob) +        dob=@trans.markup_group(dob) #decide check & FIX +        dob.obj=dob.obj.gsub(/#{Mx[:en_a_o]}(\d+)\s+(.+?)#{Mx[:en_a_c]}/m, +          '<endnote><number>\1</number><note>\2</note></endnote> ').strip +        dob +      end +      def poem_structure(dob) +        dob=@trans.markup_group(dob) #decide check & FIX +        dob.obj=dob.obj.strip +        dob +      end +      def code_structure(dob) +        dob=@trans.markup_group(dob) #decide check & FIX +        dob.obj=dob.obj.gsub(/\s\s/,'  ').strip +        dob +      end +      def table_structure(dob) #tables +        SiSU_XHTML_Shared::TableXHTML.new(dob) +      end +      def markup(data) +        xml_sc(@md) +        @level,@cont,@copen,@xml_contents_close=[],[],[],[] +        @rcdc=false +        type='norm' +        (0..7).each { |x| @cont[x]=@level[x]=false } +        (4..7).each { |x| @xml_contents_close[x]='' } +        xml_head +        data.each do |dob| +          @trans.char_enc.utf8(dob) if @sys.locale =~/utf-?8/i #% utf8 +          dob=@trans.markup(dob) +          if @rcdc==false \ +          and (dob.is ==:meta \ +          and dob.obj =~/Document Information/) +            @rcdc=true +          end +          if dob !~/(^#{Rx[:meta]}|#{Mx[:br_eof]}|#{Mx[:br_endnotes]})/ +            @p_num=SiSU_XML_Format::ParagraphNumber.new(@md,dob.ocn) if defined? dob.ocn +            if not @rcdc +              if defined? dob.ocn \ +              and dob.ocn.to_s =~/\d+/ +                format_scroll=SiSU_XML_Format::FormatScroll.new(@md,dob) if dob.is==:para and dob.indent ##FIX +                x=SiSU_XML_Format::FormatSeg.new(@md,dob) +                if dob.is==:heading +                  if dob.ln==0 +                    type="heading_section_#{dob.ln.to_s}" +                    xml_markup(dob) +                    xml_structure(dob,type) +                    dob.obj=x.heading_body0 +                  elsif dob.ln==1 +                    type="heading_section_#{dob.ln.to_s}" +                    xml_markup(dob) +                    xml_structure(dob,type) +                    dob.obj=x.heading_body1 +                  elsif dob.ln==2 +                    type="heading_section_#{dob.ln.to_s}" +                    xml_markup(dob) +                    xml_structure(dob,type) +                    dob.obj=x.heading_body2 +                  elsif dob.ln==3 +                    type="heading_section_#{dob.ln.to_s}" +                    xml_markup(dob) +                    xml_structure(dob,type) +                    dob.obj=x.heading_body3 +                  elsif dob.ln==4 +                    type="heading_content_#{dob.lv}" +                    xml_markup(dob) +                    xml_structure(dob,type) +                    dob.obj=x.heading_body4 +                  elsif dob.ln==5 +                    type="heading_content_#{dob.lv}" +                    xml_markup(dob) +                    xml_structure(dob,type) +                    dob.obj=x.heading_body5 +                  elsif dob.ln==6 +                    type="heading_content_#{dob.lv}" +                    xml_structure(dob,type) +                    dob.obj=x.heading_body6 +                  elsif dob.ln==7 +                    type="heading_content_#{dob.lv}" +                    xml_structure(dob,type) +                    dob.obj=x.heading_body7 +                  end +                else +                  dob.ocn +                  if dob.is==:verse +                    type='verse' +                    poem_structure(dob) #redo +                  elsif dob.is==:group +                    type='group' +                    group_structure(dob) #redo +                  elsif dob.is==:block +                    type='block' +                    block_structure(dob) #redo +                  elsif dob.is==:code +                    type='code' +                    code_structure(dob) #redo +                  elsif dob.is==:table # tables come as single block #work area 2005w13 +                    type='table' +                    table_structure(dob) +                  elsif dob.is==:para \ +                  and dob.indent.to_s =~/[1-9]/ \ +                  and dob.bullet_ +                    type="indent_bullet#{dob.indent.to_s}" +                    xml_markup(dob) +                  elsif dob.is==:para \ +                  and dob.indent.to_s =~/[1-9]/ \ +                  and dob.indent == dob.hang +                    type="indent#{dob.indent.to_s}" +                    xml_markup(dob) +                  elsif dob.is==:para \ +                  and dob.hang.to_s =~/[0-9]/ \ +                  and dob.indent != dob.hang +                    type="hang#{dob.hang.to_s}_indent#{dob.indent.to_s}" +                    xml_markup(dob) +                  else +                    type='norm' +                    xml_markup(dob) +                  end +                  add_to_body(dob,type) +                end +              elsif dob.obj =~/(#{Mx[:br_eof]}|#{Mx[:br_endnotes]})/ +              elsif dob.obj =~/(MetaData)/ +                txt_obj={ txt: '<br /><a name="metadata">MetaData</a>' } +                format_scroll=FormatScroll.new(@md,txt_obj) +                dob.obj=format_scroll.bold_para +              elsif dob.obj =~/(Owner Details)/ +                dob.obj='' +              end +              if dob.obj =~/<a name="n\d+">/ \ +              and dob.obj =~/^(-\{{2}~\d+|<!e[:_]\d+!>)/ # -endnote +                dob.obj='' +              end +              if dob.obj =~/.*<:#>.*$/ +                dob.obj=if dob.obj =~ /#{Mx[:pa_o]}:i[1-9]#{Mx[:pa_c]}/ +                  txt_obj={ txt: dob.obj } +                  format_text=FormatTextObject.new(@md,txt_obj) +                  format_text.scr_inden_ocn_e_no_paranum +                end +              end +            else # +            end +            dob.obj=dob.obj.gsub(/#{Mx[:pa_o]}:\S+#{Mx[:pa_c]}/,'') if dob.obj +          end +        end +        @content_flag=true +        7.downto(4) do |x| +          y=x - 1; v=x - 3 +          if @level[x]==true #2004w36 bug fix? watch/test previous logic broke on free.for.all @coontent_flag introduced +            if @content_flag==true +              @per.body << "#{Ax[:tab]*5}</content>\n#{Ax[:tab]*y}</contents#{v}>" +              @content_flag=false +            else +              @per.body << "\n#{Ax[:tab]*y}</contents#{v}>" +            end +          end +        end +        3.downto(1) do |x| +          y=x - 1 +          @per.body << "#{Ax[:tab]*y}</heading#{x}>" if @level[x]==true +        end +      end +      def pre +        rdf=SiSU_XML_Tags::RDF.new(@md) +        stylesheet=SiSU_Style::CSS_HeadInfo.new(@md,'xml_dom').stylesheet +        encoding=if @sys.locale =~/utf-?8/i then '<?xml version="1.0" encoding="UTF-8" standalone="no"?>' +        else                                     '<?xml version="1.0" encoding="ISO-8859-1" standalone="no"?>' +        end +        @per.open =<<WOK +#{encoding} +#{stylesheet.css_head_xml} +#{rdf.comment_xml} +<document> +WOK +        @per.head << '<head>' +        @per.body << '<body>' +      end +      def post +        @per.head << @per.sc +        @per.head << '</head>' +        @per.body << '</body>' +        @per.close << '</document>' +      end +      def publish +        content=[] +        content << @per.open << @per.head << @per.body # << @per.metadata +        content << @per.tail << @per.close +        content=content.flatten.compact +        Output.new(content,@md).xml +        @per.head,@per.body,@per.tail=[],[],[] # check whether should be nil +      end +    end +    class Output +      include SiSU_Param +      def initialize(data,md) +        @data,@md=data,md +        @file=SiSU_Env::FileOp.new(@md) +      end +      def xml +        SiSU_Env::FileOp.new(@md).mkdir +        filename_xml=@file.write_file.xml_dom +        @data.each do |str| +          str=str.gsub(/#{Mx[:pa_o]}:\S+#{Mx[:pa_c]}/,'') +          filename_xml.puts str unless str.empty? +        end +        filename_xml.close +      end +    end +    class Tidy +      def initialize(md,file) +        @md,@file=md,file +        @prog=SiSU_Env::InfoProgram.new +      end +      def xml +        if @prog.tidy !=false +          if (@md.opt.act[:verbose_plus][:set]==:on \ +          || @md.opt.act[:maintenance][:set]==:on) +            unless @md.opt.act[:quiet][:set]==:on +              SiSU_Screen::Ansi.new( +                @md.opt.act[:color_state][:set], +                'invert', +                'Using XML Tidy', +                'check document structure' +              ).colorize +              tell=SiSU_Screen::Ansi.new( +                @md.opt.act[:color_state][:set], +                'invert', +                '', +                '' +              ) +              tell.grey_open +            end +            tidyfile='/dev/null' #don't want one or screen output, check for alternative flags +            tidy=SiSU_Env::SystemCall.new(@file,tidyfile) +            tidy.well_formed? +            tell.p_off unless @md.opt.act[:quiet][:set]==:on +          end +        end +      end +    end +  end +end +__END__ +,** Notes: tidy -xml dom.xml >> index.tidy +#+END_SRC + +#+END_SRC + +* xml shared +** xml_shared.rb + +#+BEGIN_SRC ruby  :tangle "../lib/sisu/xml_shared.rb" +# <<sisu_document_header>> +module SiSU_XML_Munge +  require_relative 'xml_parts'                          # xml_parts.rb +  class Trans +    include SiSU_Parts_XML +    def initialize(md) +      @md=md +      @sys=SiSU_Env::SystemCall.new +      @dir=SiSU_Env::InfoEnv.new(@md.fns) +      if @md.sem_tag +        @ab ||=semantic_tags.default +      end +    end +    def semantic_tags +      def default +        { +          pub:   'publication', +          conv:  'convention', +          vol:   'volume', +          pg:    'page', +          cty:   'city', +          org:   'organization', +          uni:   'university', +          dept:  'department', +          fac:   'faculty', +          inst:  'institute', +          co:    'company', +          com:   'company', +          dt:    'date', +          y:     'year', +          m:     'month', +          d:     'day', +          ti:    'title', +          au:    'author', +          ed:    'editor', #editor? +          v:     'version', #edition +          n:     'name', +          fn:    'firstname', +          mn:    'middlename', +          ln:    'lastname', +          in:    'initials', +          qt:    'quote', +          ct:    'cite', +          ref:   'reference', +          ab:    'abreviation', +          def:   'define', +          desc:  'description', +          trans: 'translate', +        } +      end +      self +    end +    def char_enc #character encode +      def utf8(dob='') +        if @sys.locale =~/utf-?8/i # instead ucs for utf8 # String#encode Iñtërnâtiônàlizætiøn +          str=if defined? dob.obj then dob.obj +          elsif dob.is_a?(String) then dob +          end +          if str +            #¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÞßàáâãäåæçèéêëìíîïðñòóôõöøùúûü +            #¢£¥§©ª«®°±²³µ¶¹º»¼½¾×÷ +            str=str.gsub(/</um,'<').    # '<'     # < +              gsub(/>/um,'>').    # '>'     # > +              gsub(/¢/um,'¢').   # '¢'   # ¢ +              gsub(/£/um,'£').   # '£'  # £ +              gsub(/¥/um,'¥').   # '¥'    # ¥ +              gsub(/§/um,'§').   # '§'   # § +              gsub(/©/um,'©').   # '©'   # © +              gsub(/ª/um,'ª').   # 'ª'   # ª +              gsub(/«/um,'«').   # '«'  # « +              gsub(/®/um,'®').   # '®'    # ® +              gsub(/°/um,'°').   # '°'    # ° +              gsub(/±/um,'±').   # '±' # ± +              gsub(/²/um,'²').   # '²'   # ² +              gsub(/³/um,'³').   # '³'   # ³ +              gsub(/µ/um,'µ').   # 'µ'  # µ +              gsub(/¶/um,'¶').   # '¶'   # ¶ +              gsub(/¹/um,'¹').   # '¹'   # ¹ +              gsub(/º/um,'º').   # 'º'   # º +              gsub(/»/um,'»').   # '»'  # » +              gsub(/¼/um,'¼').   # '¼' # ¼ +              gsub(/½/um,'½').   # '½' # ½ +              gsub(/¾/um,'¾').   # '¾' # ¾ +              gsub(/×/um,'×').   # '×'  # × +              gsub(/÷/um,'÷').   # '÷' # ÷ +              gsub(/¿/um,'¿').   # '¿' # ¿ +              gsub(/À/um,'À').   # 'À' # À +              gsub(/Á/um,'Á').   # 'Á' # Á +              gsub(/Â/um,'Â').   # 'Â'  #  +              gsub(/Ã/um,'Ã').   # 'Ã' # à +              gsub(/Ä/um,'Ä').   # 'Ä'   # Ä +              gsub(/Å/um,'Å').   # 'Å'  # Å +              gsub(/Æ/um,'Æ').   # 'Æ'  # Æ +              gsub(/Ç/um,'Ç').   # 'Ç' # Ç +              gsub(/È/um,'È').   # 'È' # È +              gsub(/É/um,'É').   # 'É' # É +              gsub(/Ê/um,'Ê').   # 'Ê'  # Ê +              gsub(/Ë/um,'Ë').   # 'Ë'   # Ë +              gsub(/Ì/um,'Ì').   # 'Ì' # Ì +              gsub(/Í/um,'Í').   # 'Í' # Í +              gsub(/Î/um,'Î').   # 'Î'  # Î +              gsub(/Ï/um,'Ï').   # 'Ï'   # Ï +              gsub(/Ð/um,'Ð').   # 'Ð'    # Ð +              gsub(/Ñ/um,'Ñ').   # 'Ñ' # Ñ +              gsub(/Ò/um,'Ò').   # 'Ò' # Ò +              gsub(/Ó/um,'Ó').   # 'Ó' # Ó +              gsub(/Ô/um,'Ô').   # 'Ô'  # Ô +              gsub(/Õ/um,'Õ').   # 'Õ' # Õ +              gsub(/Ö/um,'Ö').   # 'Ö'   # Ö +              gsub(/Ø/um,'Ø').   # 'Ø' # Ø +              gsub(/Ù/um,'Ù').   # 'Ù' # Ù +              gsub(/Ú/um,'Ú').   # 'Ú' # Ú +              gsub(/Û/um,'Û').   # 'Û'  # Û +              gsub(/Ü/um,'Ü').   # 'Ü'   # Ü +              gsub(/Ý/um,'Ý').   # 'Ý' # Ý +              gsub(/Þ/um,'Þ').   # 'Þ'  # Þ +              gsub(/ß/um,'ß').   # 'ß'  # ß +              gsub(/à/um,'à').   # 'à' # à +              gsub(/á/um,'á').   # 'á' # á +              gsub(/â/um,'â').   # 'â'  # â +              gsub(/ã/um,'ã').   # 'ã' # ã +              gsub(/ä/um,'ä').   # 'ä'   # ä +              gsub(/å/um,'å').   # 'å'  # å +              gsub(/æ/um,'æ').   # 'æ'  # æ +              gsub(/ç/um,'ç').   # 'ç' # ç +              gsub(/è/um,'è').   # 'è' # è +              gsub(/é/um,'é').   # '´'  # é +              gsub(/ê/um,'ê').   # 'ˆ'   # ê +              gsub(/ë/um,'ë').   # 'ë'   # ë +              gsub(/ì/um,'ì').   # 'ì' # ì +              gsub(/í/um,'í').   # '´'  # í +              gsub(/î/um,'î').   # 'î'  # î +              gsub(/ï/um,'ï').   # 'ï'   # ï +              gsub(/ð/um,'ð').   # 'ð'    # ð +              gsub(/ñ/um,'ñ').   # 'ñ' # ñ +              gsub(/ò/um,'ò').   # 'ò' # ò +              gsub(/ó/um,'ó').   # 'ó' # ó +              gsub(/ô/um,'ô').   # 'ô'  # ô +              gsub(/õ/um,'õ').   # 'õ' # õ +              gsub(/ö/um,'ö').   # 'ö'   # ö +              gsub(/ø/um,'ø').   # 'ø' # ø +              gsub(/ù/um,'ú').   # 'ù' # ú +              gsub(/ú/um,'û').   # 'ú' # û +              gsub(/û/um,'ü').   # 'û'  # ü +              gsub(/ü/um,'ý').   # 'ü'   # ý +              gsub(/þ/um,'þ').   # 'þ'  # þ +              gsub(/ÿ/um,'ÿ').   # 'ÿ'   # ÿ +              gsub(/‘/um,'‘').  # '‘'  # ‘ +              gsub(/’/um,'’').  # '’'  # ’ +              gsub(/“/um,'“').  # “    # “ +              gsub(/”/um,'”').  # ”    # ” +              gsub(/–/um,'–').  # –    # – +              gsub(/—/um,'—').  # —    # — +              gsub(/∝/um,'∝').  # ∝     # ∝ +              gsub(/∞/um,'∞').  # ∞    # ∞ +              gsub(/™/um,'™').  # ™    # ™ +              gsub(/✠/um,'✠'). # ✗    # ✠ +              gsub(/ /um,' ').       # space identify +              gsub(/ /um,' ')       # space identify +          end +          dob=if defined? dob.obj +            dob.obj=str +            dob +          elsif dob.is_a?(String) +            str +          end +          dob +        end +      end +      def html(dob='') +        if @sys.locale =~/utf-?8/i # instead ucs for utf8 # String#encode Iñtërnâtiônàlizætiøn +          dob.obj=dob.obj.gsub(/ /u,' ').           # space identify +            gsub(/ /u,' ')           # space identify +        end +      end +      self +    end +    def tidywords(wordlist) +      wordlist_new=[] +      wordlist.each do |x| +        #imperfect solution will not catch all possible cases +        x=x.gsub(/&/,'&') unless x =~/&\S+;/ +        x=x.gsub(/&([A-Z])/,'&\1') +        wordlist_new << x +      end +      wordlist_new +    end +    def markup(dob='') +      wordlist=dob.obj.scan(/&[#0-9a-z]+;|\S+|\n/) #\n needed for tables, check though added 2005w17 +      dob.obj=tidywords(wordlist).join(' ').strip +      unless dob.is==:table +        dob.obj=dob.obj.gsub(/#{Mx[:br_line]}/u,'<br />'). +          gsub(/#{Mx[:br_paragraph]}/u,'<br />'). +          gsub(/#{Mx[:br_line]}|#{Mx[:br_nl]}/,'<br />') +      end +      dob.obj=dob.obj.gsub(/#{Mx[:mk_o]}:name#\S+?#{Mx[:mk_c]}/,''). +        gsub(/#{Mx[:mk_o]}#([a-zA-Z]+)#{Mx[:mk_c]}/,'&\1;'). +        gsub(/#{Mx[:mk_o]}(#[0-9]+)#{Mx[:mk_c]}/,'&\1;'). +        gsub(/(^|#{Mx[:gl_c]}|\s+)<\s+/,'\1< ').gsub(/\s+>(\s+|$)/,' >\1'). +        #gsub(/#{Mx[:fa_emphasis_o]}(.+?)#{Mx[:fa_emphasis_c]}/,'<em>\1</em>'). #reinstate +        gsub(/#{Mx[:fa_bold_o]}(.+?)#{Mx[:fa_bold_c]}/m,'<b>\1</b>'). +        gsub(/#{Mx[:fa_italics_o]}(.+?)#{Mx[:fa_italics_c]}/m,'<i>\1</i>'). +        gsub(/#{Mx[:fa_underscore_o]}(.+?)#{Mx[:fa_underscore_c]}/,'<u>\1</u>'). +        gsub(/#{Mx[:fa_superscript_o]}(.+?)#{Mx[:fa_superscript_c]}/,'<sup>\1</sup>'). +        gsub(/#{Mx[:fa_subscript_o]}(.+?)#{Mx[:fa_subscript_c]}/,'<sub>\1</sub>'). +        gsub(/#{Mx[:fa_insert_o]}(.+?)#{Mx[:fa_insert_c]}/,'<ins>\1</ins>'). +        gsub(/#{Mx[:fa_cite_o]}(.+?)#{Mx[:fa_cite_c]}/,'<cite>\1</cite>'). +        gsub(/#{Mx[:fa_strike_o]}(.+?)#{Mx[:fa_strike_c]}/,'<del>\1</del>'). +        gsub(/#{Mx[:fa_monospace_o]}(.+?)#{Mx[:fa_monospace_c]}/,'<tt>\1</tt>'). +        gsub(/<:pb>\s*/,''). #Fix +        gsub(/<+[-~]#>+/,'') +      if dob.is !=:code +        #embeds a red-bullet image --> +        dob.obj=dob.obj.gsub(/#{Mx[:fa_bold_o]}(.+?)#{Mx[:fa_bold_c]}/,'<b>\1</b>'). +          gsub(/#{Mx[:fa_italics_o]}(.+?)#{Mx[:fa_italics_c]}/,'<i>\1</i>'). +          gsub(/#{Mx[:fa_underscore_o]}(.+?)#{Mx[:fa_underscore_c]}/,'<u>\1</u>'). +          gsub(/#{Mx[:fa_strike_o]}(.+?)#{Mx[:fa_strike_c]}/,'<del>\1</del>') +        dob.obj=dob.obj.gsub(/#{Mx[:br_line]}|#{Mx[:br_nl]}/,'<br />') unless dob.is==:table +        dob.obj=dob.obj.gsub(/#{Mx[:br_page]}\s*/,''). +          gsub(/#{Mx[:br_page_new]}\s*/,''). +          gsub(/#{Mx[:br_page_line]}\s*/,''). +          gsub(/#{Mx[:pa_non_object_no_heading]}|#{Mx[:pa_non_object_dummy_heading]}/,''). +          gsub(/<[-~]#>/,''). +          gsub(/href="#{Xx[:segment]}/m,'href="'). +          gsub(/#{Mx[:lnk_o]}([^#{Mx[:lnk_o]}#{Mx[:lnk_c]}#{Mx[:rel_o]}#{Mx[:rel_c]}]+?)#{Mx[:lnk_c]}#{Mx[:rel_o]}(\.\.\/\S+?)#{Mx[:rel_c]}/, +            '<link xmlns:xl="http://www.w3.org/1999/xlink" xl:type="simple" xl:href="\2">\1</link>'). +          gsub(/#{Mx[:lnk_o]}([^#{Mx[:lnk_o]}#{Mx[:lnk_c]}#{Mx[:rel_o]}#{Mx[:rel_c]}]+?)#{Mx[:lnk_c]}#{Mx[:rel_o]}:(\S+?)#{Mx[:rel_c]}/, +            '<link xmlns:xl="http://www.w3.org/1999/xlink" xl:type="simple" xl:href="../\2">\1</link>'). +          gsub(/#{Mx[:lnk_o]}(.+?)#{Mx[:lnk_c]}#{Mx[:rel_o]}(\S+?)#{Mx[:rel_c]}/, +            '<link xmlns:xl="http://www.w3.org/1999/xlink" xl:type="simple" xl:href="#\2">\1</link>'). +          gsub(/(?:^|[^_\\])#{Mx[:lnk_o]}[ ]*(\S+?\.(?:jpg|png|gif))[ ]+(\d+)x(\d+)(\s+[^}]+)?#{Mx[:lnk_c]}#{Mx[:url_o]}(\S+?)#{Mx[:url_c]}/, +            %{<image xmlns:xl="http://www.w3.org/1999/xlink" xl:type="simple" xl:actuate="onLoad" xl:show="embed" xl:href="#{@md.file.output_path.xml.rel_image}/\\1" width="\\2" height="\\3" />[\\1] \\4}). +          gsub(/(?:^|[^_\\])#{Mx[:lnk_o]}[ ]*(\S+?\.(?:jpg|png|gif))([ ]+[^}]+)?#{Mx[:lnk_c]}#{Mx[:url_o]}(\S+?)#{Mx[:url_c]}/, +            %{<image xmlns:xl="http://www.w3.org/1999/xlink" xl:type="simple" xl:actuate="onLoad" xl:show="embed" xl:href="#{@md.file.output_path.xml.rel_image}/\\1"/>\\1}). +          gsub(/(?:^|[^_\\])#{Mx[:lnk_o]}[ ]*(\S+?\.(?:jpg|png|gif))[ ]+(\d+)x(\d+)(\s+[^}]+)?#{Mx[:lnk_c]}image/, +            %{<image xmlns:xl="http://www.w3.org/1999/xlink" xl:type="simple" xl:actuate="onLoad" xl:show="embed" xl:href="#{@md.file.output_path.xml.rel_image}/\\1" width="\\2" height="\\3" />[\\1] \\4}). +          gsub(/(?:^|[^_\\])#{Mx[:lnk_o]}[ ]*(\S+?\.(?:jpg|png|gif))([ ]+[^}]+)?#{Mx[:lnk_c]}image/, +            %{<image xmlns:xl="http://www.w3.org/1999/xlink" xl:type="simple" xl:actuate="onLoad" xl:show="embed" xl:href="#{@md.file.output_path.xml.rel_image}/\\1"/>\\1}). +          gsub(/#{Mx[:lnk_o]}(.+?)#{Mx[:lnk_c]}#{Mx[:url_o]}(\S+?)#{Mx[:url_c]}/, +            '<link xmlns:xl="http://www.w3.org/1999/xlink" xl:type="simple" xl:href="\2">\1</link>'). #watch, compare html_tune +          gsub(/#{Mx[:url_o]}(\S+?)#{Mx[:url_c]}/, +            %{#{the_url_decoration.xml_open}<link xmlns:xl="http://www.w3.org/1999/xlink" xl:type="simple" xl:href="\\1">\\1</link>#{the_url_decoration.xml_close}}). +          gsub(/#{Mx[:url_o]}_(\S+?)#{Mx[:url_c]}/, +            '<link xmlns:xl="http://www.w3.org/1999/xlink" xl:type="simple" xl:href="\1">\1</link>') #escaped urls not linked, deal with later +      else +        dob.obj=dob.obj.gsub(/</m,'<').gsub(/>/m,'>') +      end +      if dob.of==:block +        dob.obj=dob.obj.gsub(/#{Mx[:gl_bullet]}/,'● ') +      end +      dob.obj=dob.obj.gsub(/#{Mx[:url_o]}([a-zA-Z0-9._-]+\@\S+?\.[a-zA-Z0-9._-]+)#{Mx[:url_c]}/, +          %{#{the_url_decoration.xml_open}\\1#{the_url_decoration.xml_close}}). +        gsub(/#{Dx[:url_o]}/,"#{Dx[:url_o_xml]}"). +        gsub(/#{Dx[:url_c]}/,"#{Dx[:url_c_xml]}"). +        gsub(/ |#{Mx[:nbsp]}/m,' '). +        gsub(/;&([^#]|(?:[^gl][^t]|[^a][^m][^p]|[^n][^b][^s][^p])[^;])/,';&\1') # pattern not to match +      dob +    end +    def markup_light(dob='') +      dob.obj=dob.obj.gsub(/\/\{(.+?)\}\//,'<i>\1</i>'). +        gsub(/[*!]\{(.+?)\}[*!]/,'<b>\1</b>'). +        gsub(/_\{(.+?)\}_/,'<u>\1</u>'). +        gsub(/-\{(.+?)\}-/,'<del>\1</del>'). +        gsub(/<br(\s*\/)?>/,'<br />'). +        gsub(/<:pb>\s*/,''). +        gsub(/<[-~]#>/,''). +        gsub(/(^|#{Mx[:gl_c]}|\s)&\s+/,'\1& '). #sort +        gsub(/&([^;]{1,5})/,'&\1'). #sort, rough estimate, revisit #WATCH found in node not sax +        gsub(/(?:^|[^_\\])#{Mx[:lnk_o]}(\S+?\.(?:png|jpg|gif))[ ]+.+?#{Mx[:lnk_c]}(?:#{Mx[:url_o]}\S+?#{Mx[:url_c]}|image)/, +          "<image.path>#{@md.file.output_path.xml.rel_image}\/\\1</image.path>"). +        gsub(/ |#{Mx[:nbsp]}/,' '). +        gsub(/;&([^#]|(?:[^gl][^t]|[^a][^m][^p]|[^n][^b][^s][^p])[^;])/,';&\1') # pattern not to match +      wordlist=dob.obj.scan(/&[#0-9a-z]+;|\S+|\n/) #\n needed for tables, check though added 2005w17 +      dob.obj=tidywords(wordlist).join(' ').strip +      dob +    end +    def clean(str) +      str=str.gsub(/#{Mx[:gl_o]}(#[0-9]{3})#{Mx[:gl_c]}/u,'&\1;'). +        gsub(/#{Mx[:gl_o]}#([a-z]{2,4})#{Mx[:gl_c]}/u,'&\1;') +    end +    def markup_fictionbook(str='',is='') +      str=str.gsub(/#{Mx[:en_a_o]}([\d+*]+).+?#{Mx[:en_a_c]}/m,'<a xl:href="#footnote\1" type="note">[\1]</a>'). +        gsub(/&/,'&'). #sort +        gsub(/#{Mx[:mk_o]}#([a-zA-Z]+)#{Mx[:mk_c]}/,'&\1;'). +        gsub(/(^|#{Mx[:gl_c]}|\s)&\s+/,'\1& '). #sort +        gsub(/#{Mx[:mk_o]}(#[0-9]+)#{Mx[:mk_c]}/,'&\1;') +      str=str.gsub(/#{Mx[:br_line]}|#{Mx[:br_nl]}/,'<br />') unless is==:table +      str=str.gsub(/#{Mx[:fa_bold_o]}(.+?)#{Mx[:fa_bold_c]}/,'<b>\1</b>'). +        gsub(/#{Mx[:fa_italics_o]}(.+?)#{Mx[:fa_italics_c]}/,'<i>\1</i>'). +        gsub(/#{Mx[:fa_underscore_o]}(.+?)#{Mx[:fa_underscore_c]}/,'<u>\1</u>'). +        gsub(/#{Mx[:fa_superscript_o]}(.+?)#{Mx[:fa_superscript_c]}/,'<sup>\1</sup>'). +        gsub(/#{Mx[:fa_subscript_o]}(.+?)#{Mx[:fa_subscript_c]}/,'<sub>\1</sub>'). +        gsub(/#{Mx[:fa_insert_o]}(.+?)#{Mx[:fa_insert_c]}/,'<ins>\1</ins>'). +        gsub(/#{Mx[:fa_cite_o]}(.+?)#{Mx[:fa_cite_c]}/,'<cite>\1</cite>'). +        gsub(/#{Mx[:fa_strike_o]}(.+?)#{Mx[:fa_strike_c]}/,'<del>\1</del>'). +        gsub(/#{Mx[:fa_monospace_o]}(.+?)#{Mx[:fa_monospace_c]}/,'<tt>\1</tt>'). # tt, kbd +        gsub(/#{Mx[:lnk_o]}\s*(\S+?\.(?:png|jpg|gif)).+?#{Mx[:lnk_c]}(?:#{Mx[:url_o]}\S+?#{Mx[:url_c]}|#{Mx[:rel_o]}\S+?#{Mx[:rel_c]}|image)/m,'<image xl:href="#\1" />'). +        gsub(/#{Mx[:url_o]}(.+?)#{Mx[:url_c]}/,"#{Dx[:url_o]}\\1#{Dx[:url_c]}"). +        gsub(/#{Mx[:mk_o]}:name#(\S+?)#{Mx[:mk_c]}/,'<a name="\1"></a>'). +        gsub(/#{Mx[:gl_bullet]}/m,'● '). #  not available +        gsub(/#{Mx[:nbsp]}/,' '). #  not available +        gsub(/<(p|br)>/,'<\1 />') +      clean(str) +    end +    def markup_docbook(dob='')                                  # work on, initially a copy of fictionbook! +      if dob.is !=:code +        dob.obj=dob.obj.gsub(/#{Mx[:en_a_o]}(\d+)\s*(.+?)#{Mx[:en_a_c]}/m,'<footnote><para><!-- fn\1 -->\2</para></footnote>'). +          gsub(/\\\\/,'</para><para>'). +          gsub(/&/,'&'). #sort +          gsub(/#{Mx[:mk_o]}#([a-zA-Z]+)#{Mx[:mk_c]}/,'&\1;'). +          gsub(/(^|#{Mx[:gl_c]}|\s)&\s+/,'\1& '). #sort +          gsub(/#{Mx[:mk_o]}(#[0-9]+)#{Mx[:mk_c]}/,'&\1;') +        dob.obj=dob.obj.gsub(/#{Mx[:br_line]}|#{Mx[:br_nl]}/,'<br />') unless dob.is==:table +        dob.obj=dob.obj.gsub(/#{Mx[:fa_bold_o]}(.+?)#{Mx[:fa_bold_c]}/,'<b>\1</b>'). +          gsub(/#{Mx[:fa_italics_o]}(.+?)#{Mx[:fa_italics_c]}/,'<i>\1</i>'). +          gsub(/#{Mx[:fa_underscore_o]}(.+?)#{Mx[:fa_underscore_c]}/,'<u>\1</u>'). +          gsub(/#{Mx[:fa_superscript_o]}(.+?)#{Mx[:fa_superscript_c]}/,'<sup>\1</sup>'). +          gsub(/#{Mx[:fa_subscript_o]}(.+?)#{Mx[:fa_subscript_c]}/,'<sub>\1</sub>'). +          gsub(/#{Mx[:fa_insert_o]}(.+?)#{Mx[:fa_insert_c]}/,'<ins>\1</ins>'). +          gsub(/#{Mx[:fa_cite_o]}(.+?)#{Mx[:fa_cite_c]}/,'<cite>\1</cite>'). +          gsub(/#{Mx[:fa_strike_o]}(.+?)#{Mx[:fa_strike_c]}/,'<del>\1</del>'). +          gsub(/#{Mx[:fa_monospace_o]}(.+?)#{Mx[:fa_monospace_c]}/,'<tt>\1</tt>'). # tt, kbd +          gsub(/#{Mx[:lnk_o]}\s*(\S+?)\.(png|jpg|gif).+?#{Mx[:lnk_c]}(?:#{Mx[:url_o]}\S+?#{Mx[:url_c]}|#{Mx[:rel_o]}\S+?#{Mx[:rel_c]}|image)/m, +            %{#{Xx[:split]}:spaces0:<figure id="fig-\\1">\n:spaces1:<title></title>\n:spaces1:<graphic fileref="../../_sisu/image/\\1.\\2" align="center" width="50%"></graphic>\n:spaces0:</figure>#{Xx[:split]}}). # common image location, else use ./images +          gsub(/#{Mx[:lnk_o]}(.+?)#{Mx[:lnk_c]}#{Mx[:url_o]}(.+?)#{Mx[:url_c]}/, +            '<ulink url="\2">\1</ulink>'). +          gsub(/#{Mx[:url_o]}(.+?)#{Mx[:url_c]}/, +            '<ulink url="\1">\1</ulink>'). +          gsub(/#{Mx[:mk_o]}:name#(\S+?)#{Mx[:mk_c]}/,'<a name="\1"></a>'). +          gsub(/#{Mx[:gl_bullet]}/m,'● '). #  not available +          gsub(/#{Mx[:nbsp]}/,' '). #  not available +          gsub(/<(p|br)>/,'<\1 />') +        dob.obj=clean(dob.obj) +      elsif dob.is == :code +        dob.obj=dob.obj.gsub(/&/m,'&'). #sort +          gsub(/</,'<').gsub(/>/,'>') +      else # p dob.is ?? +      end +      dob +    end +    def markup_group(dob='') +      dob.obj=dob.obj.gsub(/</,'<').gsub(/>/,'>'). +        gsub(/<:?br(?:\s+\/)?>/,'<br />'). +        gsub(/<(link xmlns:xl=".+?")>/,'<\1>'). +        gsub(/<(\/link)>/,'<\1>'). +        gsub(/<(\/?en)>/,'<\1>') +      dob +    end +    def markup_block(dob='') +      dob.obj=dob.obj.gsub(/</,'<').gsub(/>/,'>'). +        gsub(/<:?br(?:\s+\/)?>/,'<br />'). +        gsub(/<(link xmlns:xl=".+?")>/,'<\1>'). +        gsub(/<(\/link)>/,'<\1>'). +        gsub(/<(\/?en)>/,'<\1>') +      dob +    end +    def xml_sem_block_paired(matched) # colon depth: many, recurs +      matched=matched.gsub(/\b(au):\{(.+?)\}:\1\b/m,  %{<sem:#{@ab[:au]} depth="many">\\2</sem:#{@ab[:au]}>}). +        gsub(/\b(vol):\{(.+?)\}:\1\b/m, %{<sem:#{@ab[:vol]} depth="many">\\2</sem:#{@ab[:vol]}>}). +        gsub(/\b(pub):\{(.+?)\}:\1\b/m, %{<sem:#{@ab[:pub]} depth="many">\\2</sem:#{@ab[:pub]}>}). +        gsub(/\b(ref):\{(.+?)\}:\1\b/m, %{<sem:#{@ab[:ref]} depth="many">\\2</sem:#{@ab[:ref]}>}). +        gsub(/\b(desc):\{(.+?)\}:\1\b/m,%{<sem:#{@ab[:desc]} depth="many">\\2</sem:#{@ab[:desc]}>}). +        gsub(/\b(conv):\{(.+?)\}:\1\b/m,%{<sem:#{@ab[:conv]} depth="many">\\2</sem:#{@ab[:conv]}>}). +        gsub(/\b(ct):\{(.+?)\}:\1\b/m,  %{<sem:#{@ab[:ct]} depth="many">\\2</sem:#{@ab[:ct]}>}). +        gsub(/\b(cty):\{(.+?)\}:\1\b/m, %{<sem:#{@ab[:cty]} depth="many">\\2</sem:#{@ab[:cty]}>}). +        gsub(/\b(org):\{(.+?)\}:\1\b/m, %{<sem:#{@ab[:org]} depth="many">\\2</sem:#{@ab[:org]}>}). +        gsub(/\b(dt):\{(.+?)\}:\1\b/m,  %{<sem:#{@ab[:dt]} depth="many">\\2</sem:#{@ab[:dt]}>}). +        gsub(/\b(n):\{(.+?)\}:\1\b/m,   %{<sem:#{@ab[:n]} depth="many">\\2</sem:#{@ab[:n]}>}). +        gsub(/([a-z]+(?:[_:.][a-z]+)*)(?::\{(.+?)\}:\1)/m,'<sem:\1 depth="many">\2</sem:\1>') +    end +    def xml_semantic_tags(dob) +      if @md.sem_tag +        dob.obj.gsub!(/([a-z]+(?:[_:.][a-z]+)*)(?::\{(.+?)\}:\1)/m) {|c| xml_sem_block_paired(c) } +        dob.obj.gsub!(/([a-z]+(?:[_:.][a-z]+)*)(?::\{(.+?)\}:\1)/m) {|c| xml_sem_block_paired(c) } +        dob.obj.gsub!(/([a-z]+(?:[_:.][a-z]+)*)(?::\{(.+?)\}:\1)/m) {|c| xml_sem_block_paired(c) } +        dob.obj=dob.obj.gsub(/:\{(.+?)\}:au\b/m,             %{<sem:#{@ab[:au]} depth="one">\\1</sem:#{@ab[:au]}>}). +          gsub(/:\{(.+?)\}:n\b/m,              %{<sem:#{@ab[:n]} depth="one">\\1</sem:#{@ab[:n]}>}). +          gsub(/:\{(.+?)\}:ti\b/m,             %{<sem:#{@ab[:ti]} depth="one">\\1</sem:#{@ab[:ti]}>}). +          gsub(/:\{(.+?)\}:ref\b/m,            %{<sem:#{@ab[:ref]} depth="one">\\1</sem:#{@ab[:ref]}>}). +          gsub(/:\{(.+?)\}:desc\b/m,           %{<sem:#{@ab[:desc]} depth="one">\\1</sem:#{@ab[:desc]}>}). +          gsub(/:\{(.+?)\}:cty\b/m,            %{<sem:#{@ab[:cty]} depth="one">\\1</sem:#{@ab[:cty]}>}). +          gsub(/:\{(.+?)\}:org\b/m,            %{<sem:#{@ab[:org]} depth="one">\\1</sem:#{@ab[:org]}>}). +          gsub(/:\{(.+?)\}:([a-z]+(?:[_:.][a-z]+)*)/m,'<sem:\2 depth="one">\1</sem:\2>'). +          gsub(/;\{([^}]+(?![;]))\};ti\b/m,    %{<sem:#{@ab[:ti]} depth="zero">\\1</sem:#{@ab[:ti]}>}). +          gsub(/;\{([^}]+(?![;]))\};qt\b/m,    %{<sem:#{@ab[:qt]} depth="zero">\\1</sem:#{@ab[:qt]}>}). +          gsub(/;\{([^}]+(?![;]))\};ref\b/m,   %{<sem:#{@ab[:ref]} depth="zero">\\1</sem:#{@ab[:ref]}>}). +          gsub(/;\{([^}]+(?![;]))\};ed\b/m,    %{<sem:#{@ab[:ed]} depth="zero">\\1</sem:#{@ab[:ed]}>}). +          gsub(/;\{([^}]+(?![;]))\};v\b/m,     %{<sem:#{@ab[:v]} depth="zero">\\1</sem:#{@ab[:v]}>}). +          gsub(/;\{([^}]+(?![;]))\};desc\b/m,  %{<sem:#{@ab[:desc]} depth="zero">\\1</sem:#{@ab[:desc]}>}). +          gsub(/;\{([^}]+(?![;]))\};def\b/m,   %{<sem:#{@ab[:def]} depth="zero">\\1</sem:#{@ab[:def]}>}). +          gsub(/;\{([^}]+(?![;]))\};trans\b/m, %{<sem:#{@ab[:trans]} depth="zero">\\1</sem:#{@ab[:trans]}>}). +          gsub(/;\{([^}]+(?![;]))\};y\b/m,     %{<sem:#{@ab[:y]} depth="zero">\\1</sem:#{@ab[:y]}>}). +          gsub(/;\{([^}]+(?![;]))\};ab\b/m,    %{<sem:#{@ab[:ab]} depth="zero">\\1</sem:#{@ab[:ab]}>}). +          gsub(/;\{([^}]+(?![;]))\};pg\b/m,    %{<sem:#{@ab[:pg]} depth="zero">\\1</sem:#{@ab[:pg]}>}). +          gsub(/;\{([^}]+(?![;]))\};fn?\b/m,   %{<sem:#{@ab[:fn]} depth="zero">\\1</sem:#{@ab[:fn]}>}). +          gsub(/;\{([^}]+(?![;]))\};mn?\b/m,   %{<sem:#{@ab[:mn]} depth="zero">\\1</sem:#{@ab[:mn]}>}). +          gsub(/;\{([^}]+(?![;]))\};ln?\b/m,   %{<sem:#{@ab[:ln]} depth="zero">\\1</sem:#{@ab[:ln]}>}). +          gsub(/;\{([^}]+(?![;]))\};in\b/m,    %{<sem:#{@ab[:in]} depth="zero">\\1</sem:#{@ab[:in]}>}). +          gsub(/;\{([^}]+(?![;]))\};uni\b/m,   %{<sem:#{@ab[:uni]} depth="zero">\\1</sem:#{@ab[:uni]}>}). +          gsub(/;\{([^}]+(?![;]))\};fac\b/m,   %{<sem:#{@ab[:fac]} depth="zero">\\1</sem:#{@ab[:fac]}>}). +          gsub(/;\{([^}]+(?![;]))\};inst\b/m,  %{<sem:#{@ab[:inst]} depth="zero">\\1</sem:#{@ab[:inst]}>}). +          gsub(/;\{([^}]+(?![;]))\};dept\b/m,  %{<sem:#{@ab[:dpt]} depth="zero">\\1</sem:#{@ab[:dept]}>}). +          gsub(/;\{([^}]+(?![;]))\};org\b/m,   %{<sem:#{@ab[:org]} depth="zero">\\1</sem:#{@ab[:org]}>}). +          gsub(/;\{([^}]+(?![;]))\};com?\b/m,  %{<sem:#{@ab[:com]} depth="zero">\\1</sem:#{@ab[:com]}>}). +          gsub(/;\{([^}]+(?![;]))\};cty\b/m,   %{<sem:#{@ab[:cty]} depth="zero">\\1</sem:#{@ab[:cty]}>}). +          gsub(/;\{([^}]+(?![;]))\};([a-z]+(?:[_:.][a-z]+)*)/m,'<sem:\2 depth="zero">\1</sem:\2>') +      end +      dob +    end +  end +end +module SiSU_XML_Tags #Format +  require_relative 'dp'                                 # dp.rb +    include SiSU_Param +  class RDF +    include SiSU_Parts_XML +    def initialize(md='',seg_name=[],tracker=0) +      @full_title=@subtitle=@author=@subject=@description=@publisher=@contributor=@date=@date_created=@date_issued=@date_available=@date_valid=@date_modified=@type=@format=@identifier=@source=@language=@relation=@coverage=@rights=@copyright=@owner=@keywords='' +      @md=md +      @rdfurl=%{  rdf:about="http://www.jus.uio.no/lm/toc"\n} +      if defined? @md.title.full \ +      and @md.title.full                          # DublinCore 1 - title +        @rdf_title=%{    dc.title="#{seg_name}#{@md.title.full}"\n} +        @full_title=%{  <meta name="dc.title" content="#{@md.title.full}" />\n} +      end +      if defined? @md.creator.author \ +      and @md.creator.author=~/\S+/                                            # DublinCore 2 - creator/author (author) +        @rdf_author=%{    dc.author="#{@md.creator.author}"\n} +        content=meta_content_clean(@md.creator.author) +        @author=%{  <meta name="dc.author" content="#{content}" />\n} +      end +      if defined? @md.publisher \ +      and @md.publisher                                                        # DublinCore 5 - publisher (current copy published by) +        @rdf_publisher=%{    dc.publisher="#{@md.publisher}"\n} +        content=meta_content_clean(@md.publisher) +        @publisher=%{  <meta name="dc.publisher" content="#{content}" />\n} +      end +      if defined? @md.creator.contributor \ +      and @md.creator.contributor=~/\S+/                                      # DublinCore 6 - contributor +        @rdf_contributor=%{    dc.contributor="#{@md.creator.contributor}"\n} +        content=meta_content_clean(@md.creator.contributor) +        @contributor=%{  <meta name="dc.contributor" content="#{content}" />\n} +      end +      if defined? @md.date.published \ +      and @md.date.published=~/\S+/                                           # DublinCore 7 - date year-mm-dd +        @rdf_date=%{    dc.date="#{@md.date.published}"\n} +        @date=%{  <meta name="dc.date" content="#{@md.date.published}" #{@md.date_scheme} />\n} # fix @md.date_scheme +      end +      if defined? @md.date.created \ +      and @md.date.created=~/\S+/                                             # DublinCore 7 - date.created year-mm-dd +        @rdf_date_created=%{    dc.date.created="#{@md.date.created}"\n} +        @date_created=%{  <meta name="dc.date.created" content="#{@md.date.created}" #{@md.date_scheme} />\n} +      end +      if defined? @md.date.issued \ +      and @md.date.issued=~/\S+/                                              # DublinCore 7 - date.issued year-mm-dd +        @rdf_date_issued=%{    dc.date.issued="#{@md.date.issued}"\n} +        @date_issued=%{  <meta name="dc.date.issued" content="#{@md.date.issued}" #{@md.date_scheme} />\n} +      end +      if defined? @md.date.available \ +      and @md.date.available=~/\S+/                                           # DublinCore 7 - date.available year-mm-dd +        @rdf_date_available=%{    dc.date.available="#{@md.date.available}"\n} +        @date_available=%{  <meta name="dc.date.available" content="#{@md.date.available}" #{@md.date_scheme} />\n} +      end +      if defined? @md.date.valid \ +      and @md.date.valid=~/\S+/                                               # DublinCore 7 - date.valid year-mm-dd +        @rdf_date_valid=%{    dc.date.valid="#{@md.date.valid}"\n} +        @date_valid=%{  <meta name="dc.date.valid" content="#{@md.date.valid}" #{@md.date_scheme} />\n} +      end +      if defined? @md.date.modified \ +      and @md.date.modified=~/\S+/                                            # DublinCore 7 - date.modified year-mm-dd +        @rdf_date_modified=%{    dc.date.modified="#{@md.date.modified}"\n} +        @date_modified=%{  <meta name="dc.date.modified" content="#{@md.date.modified}" #{@md.date_scheme} />\n} +      end +      if defined? @md.rights.all \ +      and @md.rights.all                                                      # DublinCore 15 - rights +        @rdf_rights=%{    dc.rights="#{@md.rights.all}"\n} +        content=meta_content_clean(@md.rights.all) +        @rights=%{  <meta name="dc.rights" content="#{content}" />\n} +      end +      if defined? @md.classify.subject \ +      and @md.classify.subject=~/\S+/                                          # DublinCore 3 - subject (us library of congress, eric or udc, or schema???) +        @rdf_subject=%{    dc.subject="#{@md.classify.subject}"\n} +        content=meta_content_clean(@md.classify.subject) +        @subject=%{  <meta name="dc.subject" content="#{content}" />\n} +      end +      if defined? @md.notes.description \ +      and @md.notes.description=~/\S+/                                         # DublinCore 4 - description +        @rdf_description=%{    dc.description="#{@md.notes.description}"\n} +        content=meta_content_clean(@md.notes.description) +        @description=%{  <meta name="dc.description" content="#{content}" />\n} +      end +      if defined? @md.notes.coverage \ +      and @md.notes.coverage=~/\S+/                                            # DublinCore 14 - coverage +        @rdf_coverage=%{    dc.coverage="#{@md.notes.coverage}"\n} +        content=meta_content_clean(@md.notes.coverage) +        @coverage=%{  <meta name="dc.coverage" content="#{content}" />\n} +      end +      if defined? @md.notes.relation \ +      and @md.notes.relation=~/\S+/                                            # DublinCore 13 - relation +        @rdf_relation=%{    dc.relation="#{@md.notes.relation}"\n} +        content=meta_content_clean(@md.notes.relation) +        @relation=%{  <meta name="dc.relation" content="#{content}" />\n} +      end +      if defined? @md.notes.type \ +      and @md.notes.type                                                       # DublinCore 8 - type (genre eg. report, convention etc) +        @rdf_type=%{    dc.type="#{@md.notes.type}"\n} +        content=meta_content_clean(@md.notes.type) +        @type=%{  <meta name="dc.type" content="#{content}" />\n} +      end +      if defined? @md.notes.format \ +      and @md.notes.format=~/\S+/                                              # DublinCore 9 - format (use your mime type) +        @rdf_format=%{    dc.format="#{@md.notes.format}"\n} +        content=meta_content_clean(@md.notes.format) +        @format=%{  <meta name="dc.format" content="#{content}" />\n} +      end +      #if defined? @md.identifier.sisupod \ +      #and @md.identifier.sisupod=~/\S+/                                       # DublinCore 10 - identifier (your identifier, could use urn which is free) +      #  @rdf_identifier=%{    dc.identifier="#{@md.identifier.sisupod}"\n} +      #  content=meta_content_clean(@md.identifier.sisupod) +      #  @identifier=%{  <meta name="dc.identifier" content="#{content}" />\n} +      #end +      if defined? @md.original.source \ +      and @md.original.source=~/\S+/                                           # DublinCore 11 - source (document source) +        @rdf_source=%{    dc.source="#{@md.original.source}"\n} +        content=meta_content_clean(@md.original.source) +        @source=%{  <meta name="dc.source" content="#{content}" />\n} +      end +      if defined? @md.title.language \ +      and @md.title.language=~/\S+/                                            # DublinCore 12 - language (English) +        @rdf_language=%{    dc.language="#{@md.title.language}"\n} +        @language=%{  <meta name="dc.language" content="#{@md.title.language}" />\n} +      end +      if defined? @md.original.language \ +      and @md.original.language=~/\S+/ +        @rdf_language_original=%{    dc.language="#{@md.original.language}"\n} +        @language_original=%{  <meta name="dc.language" content="#{@md.original.language}" />\n} +      end +      content=meta_content_clean(@md.keywords) +      @keywords=%{  <meta name="keywords" content="#{content}" />\n} if @md.keywords +    end +    def meta_content_clean(content='') +      content=if not content.nil? +        content=content.tr('"',"'"). +           gsub(/&/,'&') +      else content +      end +    end +    def rdfseg #segHead +      rdftoc +    end +    def comment_xml(extra='') +      generator="Generated by: #{@md.project_details.project} #{@md.project_details.version} of #{@md.project_details.date_stamp} (#{@md.project_details.date})"  if @md.project_details.version +      lastdone="Last Generated on: #{Time.now}" +      rubyv="Ruby version: #{@md.ruby_version}" +      sc=if @md.sc_info +        "Source file: #{@md.sc_filename} version: #{@md.sc_number} of: #{@md.sc_date}" +      else '' +      end +      if extra.empty? +<<WOK +<!-- Document processing information: +     ,* #{generator} +     ,* #{rubyv} +     ,* #{sc} +     ,* #{lastdone} +     ,* SiSU http://www.jus.uio.no/sisu +--> +WOK +     else +<<WOK +<!-- Document processing information: +     ,* #{extra} +     ,* #{generator} +     ,* #{rubyv} +     ,* #{sc} +     ,* #{lastdone} +     ,* SiSU http://www.jus.uio.no/sisu +--> +WOK +      end +    end +    def comment_xml_sax +      desc='SiSU XML, SAX type representation' +      comment_xml(desc) +    end +    def comment_xml_node +      desc='SiSU XML, Node type representation' +      comment_xml(desc) +    end +    def comment_xml_dom +      desc='SiSU XML, DOM type representation' +      comment_xml(desc) +    end +    def metatag_html #values strung together, because some empty, and resulting output (line breaks) is much better +<<WOK +#{@full_title}#{@subtitle}#{@author}#{@subject}#{@description}#{@publisher}#{@contributor}#{@date}#{@date_created}#{@date_issued}#{@date_available}#{@date_valid}#{@date_modified}#{@type}#{@format}#{@identifier}#{@source}#{@language}#{@relation}#{@coverage}#{@rights}#{@copyright}#{@owner} +#{SiSU_Proj_XML::Bits.new.txt_generator} +#{the_png.ico} +WOK +    end +  end +end +module SiSU_Tables +  require_relative 'xml_tables'                         # xml_tables.rb +end +__END__ +#+END_SRC + +** xml_tables.rb + +#+BEGIN_SRC ruby  :tangle "../lib/sisu/xml_tables.rb" +# <<sisu_document_header>> +module SiSU_Tables +  class Table #_xml +    @@tablehead=0 +    @@tablefoot=[] #watch #bug??? #check was @@tablefoot +    def initialize(one,ocn='') +      @one,@parablock,@ocn=one,one,ocn +    end +    def table_split                                                            #% used but, no longer operational, revisit +      @new_content=[] +      @one.split(/\n/).each do |parablock| +        table=TableXML.new("#{parablock}\n") +        @new_content << table.table +      end +      @new_content.join +    end +  end +  class TableXML <Table +    @@tablehead=0 +    @@tablefoot=[] +    def initialize(one,ocn='') +      @one,@parablock,@ocn=one,one,ocn +    end +    def table +      m=@parablock[/<!f(.+?)!>/,1] +      @@tablefoot << m if m +      @parablock=@parablock.gsub(/<!f.+?!>/,'') +      @@tablehead=1 if @parablock =~/#{Mx[:gr_o]}Th#{Mx[:tc_p]}/u +      if @parablock =~/#{Mx[:gr_o]}Th?#{Mx[:tc_p]}/u +        @parablock=@parablock.gsub(/#{Mx[:gr_o]}Th?#{Mx[:tc_p]}.+?#{Mx[:tc_p]}~(\d+);\w\d+;\w\d+#{Mx[:gr_c]}/u, +          %{\n<ocn>#{@ocn}</ocn><table summary="normal text css" width="100%" border="0" bgcolor="white" cellpadding="2" align="center">}) +      end +      if @parablock =~/#{Mx[:gr_o]}TZ#{Mx[:gr_c]}/ +        tablefoot=[] +        @@tablefoot.each {|x| tablefoot << ''} +        @@tablefoot=[] +      end +      if @@tablehead==1 +        if @parablock =~/#{Mx[:tc_p]}#{Mx[:tc_p]}/u +          @parablock=@parablock.gsub(/#{Mx[:tc_o]}#{Mx[:tc_p]}#{Mx[:tc_p]}(\d+?)#{Mx[:tc_p]}/u, +            %{<tr> +  <td width="\\1%" valign="top"><b>}). +            gsub(/#{Mx[:tc_p]}#{Mx[:tc_p]}(\d+?)#{Mx[:tc_p]}/u, +              %{</b></td><td width="\\1%" valign="top"><b>}). +            gsub(/#{Mx[:tc_c]}/,"</b>\n</td>\n</tr>") +          @@tablehead=0 +        end +        @parablock +      else +        @parablock=@parablock.gsub(/#{Mx[:tc_o]}#{Mx[:tc_p]}#{Mx[:tc_p]}(\d+?)#{Mx[:tc_p]}/u, +          %{<tr> +  <td width="\\1%" valign="top">}). +          gsub(/#{Mx[:tc_p]}#{Mx[:tc_p]}(\d+?)#{Mx[:tc_p]}/u, +            %{ +  </td> +  <td width="\\1%" valign="top">}). +          gsub(/#{Mx[:tc_c]}/,"\n</td>\n</tr>\n") +      end +      @parablock +    end +  end +  class TableXMLdocbook +    @@tablehead=0 +    @@tablefoot=[] #watch +    def initialize(table,id='') +      @table_obj,@id=table,id +    end +    def spaces +      Ax[:spaces] +    end +    def table +      table_obj=@table_obj +      if table_obj.obj !~/^<table\s/m +        table_obj=table_rows_and_columns_array(table_obj) +      else p __LINE__; p caller +      end +      table_obj +    end +    def table_rows_and_columns_array(table_obj) # provides basic (x)html table +      table_rows,nr=[],0 +      table_obj.obj.split(Mx[:tc_c]).each do |table_row| +        table_row_with_columns=table_row.split(Mx[:tc_p]) +        trc,nc=[],0 +        table_row_with_columns.each do |c| +          c=c.gsub(/^(?:~| )$/,''). # tilde / empty cell +            gsub(/ /,' '). +            gsub(/<:br>/,'<br />') +          trc <<= if table_obj.head_ and nr==0 +            %{#{spaces*6}<entry>#{c}</entry>\n} +          else %{#{spaces*6}<entry>#{c}</entry>\n} +          end +          nc+=1 +        end +        trc=(trc.is_a?(Array)) ? trc.flatten.join : trc +        trc = if table_obj.head_ and nr==0 +          "#{spaces*4}<thead>\n#{spaces*5}<row>\n#{trc}#{spaces*5}</row>\n#{spaces*4}</thead>\n#{spaces*4}<tbody>\n" +        else +          "#{spaces*5}<row>\n#{trc}#{spaces*5}</row>\n" +        end +        nr+=1 +        table_rows << trc +      end +      tbody_close=if table_obj.head_ +        "#{spaces*4}</tbody>" +      else '' +      end +      table_rows=table_rows.flatten.join +      # include table_id <table id=''> +      table_obj.obj=%{#{spaces*3}<para #{@id}> +#{spaces*4}<table> +#{spaces*4}<tgroup cols="#{table_obj.cols}" align="char"> +#{table_rows}#{tbody_close} +#{spaces*4}</tgroup> +#{spaces*4}</table> +#{spaces*3}</para>} +      table_obj +    end +  end +  class TableXMLexp <Table +    @@tablehead=0 +    @@tablefoot=[] +    def initialize(one) +      @one,@parablock=one,one +    end +    def table_close +      '</td></tr> +</table>' +    end +    def margin_numless +      '</td><td width="4%" align="right" valign="top">' +    end +    def table_head(inf) +      %{<table summary="normal text css" width="100%" border="0" bgcolor="white" cellpadding="2" align="center"> +  <tr> +    <td valign="top" align="justify"> +      <a name="#{inf}"></a> +    </td> +    <td> +<table summary="normal text css" width="100%" border="0" bgcolor="white" cellpadding="2" align="center">} +    end +    def table_end(tablefoot='') +      %{</table>#{the_margin_numless}#{the_margin_numless} #{the_table_close} +#{tablefoot}} +    end +    def table_row(inf,h=false) +      bold=h ? '<b>' : '' +      %{ +<tr> +  <td width="#{inf}%" valign="top">#{bold}} +    end +    def table_cell(inf,h=false) +      if h; %{</b></td><td width="#{inf}%" valign="top"><b>} +      else  %{</td><td width="#{inf}%" valign="top">} +      end +    end +    def table_row_close(h=false) +      bold_close=h ? '<b>' : '' +      "#{bold_close}</td></tr>" +    end +    def table +      m=@parablock[/<!f(.+?)!>/,1] +      @@tablefoot << m if m +      @parablock=@parablock.gsub(/<!f.+?!>/,'') +      @@tablehead=1 if @parablock =~/#{Mx[:gr_o]}Th#{Mx[:tc_p]}/u +      if @parablock =~/#{Mx[:gr_o]}Th?#{Mx[:tc_p]}.+?#{Mx[:tc_p]}~(\d+);\w\d+;\w\d+#{Mx[:gr_c]}/u +        @parablock=table_head($1) +      end +      if @parablock =~/#{Mx[:gr_o]}TZ#{Mx[:gr_c]}/ +        tablefoot=[] +        @@tablefoot.each {|x| tablefoot << ''} +        @@tablefoot=[] +        if @parablock =~/#{Mx[:gr_o]}TZ#{Mx[:gr_c]}/ +          @parablock=table_end +        end +      end +      if @@tablehead==1 +        if @parablock =~/#{Mx[:tc_p]}#{Mx[:tc_p]}/u +          if @parablock =~/#{Mx[:tc_o]}#{Mx[:tc_p]}#{Mx[:tc_p]}(\d+?)#{Mx[:tc_p]}/u +            @parablock=@parablock.gsub(/#{Mx[:tc_o]}#{Mx[:tc_p]}#{Mx[:tc_p]}(\d+?)#{Mx[:tc_p]}/u,table_row($1,true)) +          end +          if @parablock =~/#{Mx[:tc_p]}#{Mx[:tc_p]}(\d+?)#{Mx[:tc_p]}/u +            @parablock=@parablock.gsub(/#{Mx[:tc_p]}#{Mx[:tc_p]}(\d+?)#{Mx[:tc_p]}/u,table_cell($1,true)) +          end +          if @parablock =~/#{Mx[:tc_c]}/ +            @parablock=@parablock.gsub(/#{Mx[:tc_c]}/,table_row_close(true)) +          end +          @@tablehead=0 +        end +        @parablock +      else +        if @parablock =~/^#{Mx[:tc_p]}#{Mx[:tc_p]}(\d+?)#{Mx[:tc_p]}/u +          @parablock=@parablock.gsub(/^#{Mx[:tc_p]}#{Mx[:tc_p]}(\d+?)#{Mx[:tc_p]}/u,table_row($1)) +        end +        if @parablock =~/#{Mx[:tc_p]}#{Mx[:tc_p]}(\d+?)#{Mx[:tc_p]}/u +          @parablock=@parablock.gsub(/#{Mx[:tc_p]}#{Mx[:tc_p]}(\d+?)#{Mx[:tc_p]}/u,table_cell($1)) +        end +        if @parablock =~/#{Mx[:tc_c]}/ +          @parablock=@parablock.gsub(/#{Mx[:tc_c]}/,table_row_close) +        end +        @parablock +      end +      @parablock +    end +  end +end +__END__ +#+END_SRC + +** xml_format.rb + +#+BEGIN_SRC ruby  :tangle "../lib/sisu/xml_format.rb" +# <<sisu_document_header>> +module SiSU_XML_Format +  require_relative 'dp'                                 # dp.rb +  require_relative 'xml_parts'                          # xml_parts.rb +  include SiSU_Param +  class ParagraphNumber +    def initialize(md,paranum) +      @md=md +      @paranum=(paranum ? (/(\d+)/m.match(paranum)[1]) : nil) +    end +    def display +      p_num_display=if @paranum +        @paranum.gsub(/(\d+)/, +        '<font size="1" color="#777777">' + +        '  \1</font>') +      else '' +      end +      p_num_display +    end +    def name +      p_num_name=@paranum.gsub(/(\d+)/,'<a name="\1"></a>') +      p_num_name +    end +    def goto +      p_num_goto=@paranum.gsub(/(\d+)/,'<a href="#\1">') +      p_num_goto +    end +  end +  class HeadInformation +    include SiSU_Parts_XML +    def initialize #dc rdf +      @full_title=@subtitle=@author=@subject=@description=@publisher=@contributor=@date=@type=@format=@identifier=@source=@language=@relation=@coverage=@rights=@copyright=@owner=@keywords='' +      @md=@@md +      # DublinCore 1 - title +      @rdfurl=%{  rdf:about="http://www.jus.uio.no/lm/toc"\n} +      if defined? @md.title.full \ +      and @md.title.full                          # DublinCore 1 - title +        @rdf_title=%{    dc.title="#{seg_name}#{@md.title.full}"\n} +        @full_title=%{<meta name="dc.title" content="#{seg_name}#{@md.title.full}" />\n} +      end +      if defined? @md.creator.author \ +      and @md.creator.author                                                  # DublinCore 2 - creator/author (author) +        @rdf_author=%{    dc.author="#{@md.creator.author}"\n} +        @author=%{<meta name="dc.author" content="#{@md.creator.author}" />\n} +      end +      if defined? @md.classify.subject \ +      and @md.classify.subject=~/\S+/                                          # DublinCore 3 - subject (us library of congress, eric or udc, or schema???) +        @rdf_subject=%{    dc.subject="#{@md.classify.subject}"\n} +        @subject=%{<meta name="dc.subject" content="#{@md.classify.subject}" />\n} +      end +      if defined? @md.notes.description \ +      and @md.notes.description=~/\S+/                                        # DublinCore 4 - description +        @rdf_description=%{    dc.description="#{@md.notes.description}"\n} +        @description=%{<meta name="dc.description" content="#{@md.notes.description}" />\n} +      end +      if defined? @md.publisher \ +      and @md.publisher=~/\S+/                                                # DublinCore 5 - publisher (current copy published by) +        @rdf_publisher=%{    dc.publisher="#{@md.publisher}"\n} +        @publisher=%{<meta name="dc.publisher" content="#{@md.publisher}" />\n} +      end +      if defined? @md.creator.contributor \ +      and @md.creator.contributor=~/\S+/                                      # DublinCore 6 - contributor +        @rdf_contributor=%{    dc.contributor="#{@md.creator.contributor}"\n} +        @contributor=%{<meta name="dc.contributor" content="#{@md.creator.contributor}" />\n} +      end +      if defined? @md.date.published \ +      and @md.date.published                                                  # DublinCore 7 - date year-mm-dd +        @rdf_date=%{    dc.date="#{@md.date.published}"\n} +        @date=%{<meta name="dc.date" content="#{@md.date.published}" #{@md.date_scheme} />\n} +      end +      if defined? @md.date.created \ +      and @md.date.created                                                    # DublinCore 7 - date.created year-mm-dd +        @rdf_date_created=%{    dc.date.created="#{@md.date.created}"\n} +        @date_created=%{<meta name="dc.date.created" content="#{@md.date.created}" #{@md.date_created_scheme} />\n} +      end +      if defined? @md.date.issued \ +      and @md.date.issued                                                      # DublinCore 7 - date.issued year-mm-dd +        @rdf_date_issued=%{    dc.date.issued="#{@md.date.issued}"\n} +        @date_issued=%{<meta name="dc.date.issued" content="#{@md.date.issued}" #{@md.date_issued_scheme} />\n} +      end +      if defined? @md.date.available \ +      and @md.date.available                                                  # DublinCore 7 - date.available year-mm-dd +        @rdf_date_available=%{    dc.date.available="#{@md.date.available}"\n} +        @date_available=%{<meta name="dc.date.available" content="#{@md.date.available}" #{@md.date_available_scheme} />\n} +      end +      if defined? @md.date.valid \ +      and @md.date.valid                                                      # DublinCore 7 - date.valid year-mm-dd +        @rdf_date_valid=%{    dc.date.valid="#{@md.date.valid}"\n} +        @date_valid=%{<meta name="dc.date.valid" content="#{@md.date.valid}" #{@md.date_valid_scheme} />\n} +      end +      if defined? @md.date.modified \ +      and @md.date.modified                                                   # DublinCore 7 - date.modified year-mm-dd +        @rdf_date_modified=%{    dc.date.modified="#{@md.date.modified}"\n} +        @date_modified=%{<meta name="dc.date.modified" content="#{@md.date.modified}" #{@md.date_modified_scheme} />\n} +      end +      if defined? @md.notes.coverage \ +      and @md.notes.coverage=~/\S+/                                        # DublinCore 14 - coverage +        @rdf_coverage=%{    dc.coverage="#{@md.notes.coverage}"\n} +        @coverage=%{<meta name="dc.coverage" content="#{@md.notes.coverage}" />\n} +      end +      if defined? @md.notes.relation \ +      and @md.notes.relation=~/\S+/                                         # DublinCore 13 - relation +        @rdf_relation=%{    dc.relation="#{@md.notes.relation}"\n} +        @relation=%{<meta name="dc.relation" content="#{@md.notes.relation}" />\n} +      end +      if defined? @md.notes.type \ +      and @md.notes.type                                                            # DublinCore 8 - type (genre eg. report, convention etc) +        @rdf_type=%{    dc.type="#{@md.notes.type}"\n} +        @type=%{<meta name="dc.type" content="#{@md.notes.type}" />\n} +      end +      if defined? @md.notes.format \ +      and @md.notes.format=~/\S+/                                              # DublinCore 9 - format (use your mime type) +        @rdf_format=%{    dc.format="#{@md.notes.format}"\n} +        @format=%{<meta name="dc.format" content="#{@md.notes.format}" />\n} +      end +      #if defined? @md.identifier.sisupod \ +      #and @md.identifier.sisupod=~/\S+/                                       # DublinCore 10 - identifier (your identifier, could use urn which is free) +      #  @rdf_identifier=%{    dc.identifier="#{@md.identifier.sisupod}"\n} +      #  @identifier=%{<meta name="dc.identifier" content="#{@md.identifier.sisupod}" />\n} +      #end +      if defined? @md.original.source \ +      and @md.original.source=~/\S+/                                           # DublinCore 11 - source (document source) +        @rdf_source=%{    dc.source="#{@md.original.source}"\n} +        @source=%{<meta name="dc.source" content="#{@md.source}" />\n} +      end +      if defined? @md.original.language \ +      and @md.original.language=~/\S+/                                         # DublinCore 12 - language (English) +        @rdf_language=%{    dc.language="#{@md.original.title}"\n} +        @language=%{<meta name="dc.language" content="#{@md.language[:name]}" />\n} +      end +      if defined? @md.rights.all \ +      and @md.rights.all=~/\S+/                                               # DublinCore 15 - rights +        rights=meta_content_clean(@md.rights.all) +        copyright=meta_content_clean(@md.rights.copyright.all) +        @rdf_rights=%{    dc.rights="#{rights}"\n} +        @rights=%{<meta name="dc.rights" content="#{rights}" />\n} +      end +      @copyright=%{<meta name="copyright" content="#{copyright}" />\n} \ +        if @md.rights.copyright.all # possibly redundant see dc.rights +      @owner=%{<meta name="owner" content="#{@md.owner}" />\n} if @md.owner +      @keywords=%{<meta name="keywords" content="#{@md.keywords}" />\n} if @md.keywords +      @index='index' +    end +    def meta_content_clean(content='') +      content=if not content.nil? +        content=content.tr('"',"'"). +           gsub(/&/,'&') +        content=SiSU_XML_Munge::Trans.new(@md).char_enc.utf8(content) +      else content +      end +    end +    def table_close +      '</font> </td></tr></table>' +    end +    def toc_head +      <<WOK +<html> +<head> +<title>#{@md.html_title}</title> +<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" +         xmlns:dc="http://purl.org/dc/elements/1.1/"> + <rdf:Description +#{@rdfurl} +#{@rdf_title} +#{@rdf_subtitle} +#{@rdf_author} +#{@rdf_subject} +#{@rdf_description} +#{@rdf_publisher} +#{@rdf_contributor} +#{@rdf_date} +#{@rdf_date_created} +#{@rdf_date_issued} +#{@rdf_date_available} +#{@rdf_date_valid} +#{@rdf_date_modified} +#{@rdf_type} +#{@rdf_format} +#{@rdf_identifier} +#{@rdf_source} +#{@rdf_language} +#{@rdf_relation} +#{@rdf_coverage} +#{@rdf_rights} +  /> +</rdf:RDF> +#{@full_title} +#{@author} +#{@subject} +#{@description} +#{@publisher} +#{@contributor} +#{@date} +#{@date_created} +#{@date_issued} +#{@date_available} +#{@date_valid} +#{@date_modified} +#{@type} +#{@format} +#{@identifier} +#{@source} +#{@language} +#{@relation} +#{@coverage} +#{@rights} +#{@copyright} +#{@owner} +#{@png.ico} +#{@txt.generator} +#{@js.head} +\n</head> +#{@color.body} +#{@font.css_table_file} +<a name="top"></a> +<a name="up"></a> +<a name="start"></a> +#{@js.top} +WOK +    end +  end +  class FormatTextObject +    include SiSU_Parts_XML +    attr_accessor :md,:txt,:format,:paranum,:p_num,:para_id,:headname,:font +    def initialize(md,dob) +      @md,@dob=md,dob +      if @dob[:ocn]=~/\d+/ +        @paranum=/(\d+)/m.match(@dob[:ocn])[1] +        @headname='' +        @headname=%{<a name="h#{dob.name}"></a>} if defined? dob.name +        @p_num=SiSU_XML_Format::ParagraphNumber.new(@md,dob.ocn) +      end +      rgx=/^[1-6-]~{1,2}/ #watch +      @lnk_url=@lnk_url.gsub(rgx,'') if @lnk_url =~rgx +      rgx=/~\{\d+\s+(.+?)\}~/ +      @lnk_url=@lnk_url.gsub(rgx,'\1') if @lnk_url =~rgx +    end +    def scr_endnote_body +      "<endnote>#{@txt}</endnote> " +    end +  end +  class FormatScroll < FormatTextObject +    def initialize(md,dob) +      super(md,dob) +    end +    def heading_body +      %{<p class="norm">#{@p_num.name}#{@headname}#{@dob.obj} </p>} + +      %{<p class="paranum"><font size="1" color="#777777">  #{@dob.ocn}</font></p>\n} +    end +    def heading_body0 +      %{<h1 class="norm">#{@p_num.name}#{@headname}#{@dob.obj}</h1>} + +      %{<p class="paranum"><font size="1" color="#777777">  #{@dob.ocn}</font></p>\n} +    end +    def heading_body1 +      %{<h2 class="norm">#{@p_num.name}#{@headname}#{@dob.obj}</h2>} + +      %{<p class="paranum"><font size="1" color="#777777">  #{@dob.ocn}</font></p>\n} +    end +    def heading_body2 +      %{<h3 class="norm">#{@p_num.name}#{@headname}#{@dob.obj}</h3>} + +      %{<p class="paranum"><font size="1" color="#777777">  #{@dob.ocn}</font></p>\n} +    end +    def heading_body3 +      %{<h4 class="norm">#{@p_num.name}#{@headname}#{@dob.obj}</h4>} + +      %{<p class="paranum"><font size="1" color="#777777">  #{@dob.ocn}</font></p>\n} +    end +    def heading_body4 +      %{<h5 class="norm">#{@p_num.name}#{@headname}#{@dob.obj}</h5>} + +      %{<p class="paranum"><font size="1" color="#777777">  #{@dob.ocn}</font></p>\n} +    end +    def heading_body5 +      %{<h6 class="norm">#{@p_num.name}#{@headname}#{@dob.obj}</h6>} + +      %{<p class="paranum"><font size="1" color="#777777">  #{@dob.ocn}</font></p>\n} +    end +    def heading_body6 +      %{<h7 class="norm">#{@p_num.name}#{@headname}#{@dob.obj}</h7>} + +      %{<p class="paranum"><font size="1" color="#777777">  #{@dob.ocn}</font></p>\n} +    end +  end +  class ParagraphNumber +    def initialize(md,ocn) +      @md,@ocn=md,ocn.to_s +      @ocn ||='' +    end +    def ocn_display +      @make=SiSU_Env::ProcessingSettings.new(@md) +      if @make.build.ocn? +        ocn_class='ocn' +        if @ocn.to_i==0 +          @ocn.gsub(/^(\d+|)$/, +            %{<label class="#{ocn_class}"><a name="#{@ocn}"> </a></label>}) +        else +          @ocn.gsub(/^(\d+|)$/, +            %{<label class="#{ocn_class}"><a name="#{@ocn}">\\1</a></label>}) +        end +      else +        ocn_class='ocn_off' +        @ocn.gsub(/^(\d+|)$/, +          %{<label class="#{ocn_class}"> </label>}) +      end +    end +    def name +      %{<a name="#{@ocn}"></a>} +    end +    def id #w3c? "tidy" complains about numbers as identifiers ! annoying +      %{id="o#{@ocn}"} +    end +    def goto +      %{<a href="##{@ocn}">} +    end +  end +  class HeadInformation +    include SiSU_Parts_XML +    attr_reader :md,:sfx,:pdf,:rdf,:vz +    def initialize(md) +      @md=md +      @rdf=SiSU_XML_Tags::RDF.new(md) +      # DublinCore 1 - title +      @stylesheet=SiSU_Style::CSS_HeadInfo.new(md).stylesheet +      @seg_name_html=(SiSU_HTML::Source::Seg.new.seg_name_html || []) +      @seg_name_html_tracker=(SiSU_HTML::Source::Seg.new.seg_name_html_tracker || []) +      @index='index' +      @metalink='#metadata' +      @tocband_scroll,@tocband_segtoc=nil,nil +    end +    def doc_type +      %{<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" +"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml">\n} +    end +    def table_close +      %{  </font> +#{the_table_close}} +    end +    def html_close #moved +    %{</body> +</html>} +    end +  end +  class XML +  end +  class FormatTextObject +    include SiSU_Parts_XML +    attr_accessor :md,:dob,:txt,:ocn,:format,:table,:link,:linkname,:paranum,:p_num,:headname,:banner,:url +    def initialize(md,t_o) +      @md,@t_o=md,t_o +      if t_o.is_a?(Hash) +        @txt            =t_o[:txt]            || nil +        @ocn            =t_o[:ocn]            || nil +        @ocn_display    =t_o[:ocn_display]    || nil +        @headname       =t_o[:headname]       || nil +        @trailer        =t_o[:trailer]        || nil +        @endnote_part_a =t_o[:endnote_part_a] || nil +        @endnote_part_b =t_o[:endnote_part_b] || nil +        @lnk_url        =t_o[:lnk_url]        || nil +        @lnk_txt        =t_o[:lnk_txt]        || nil +        @format         =t_o[:format]         || nil +        @target         =t_o[:target]         || nil #occasionally passed but not used +      elsif t_o.class.inspect =~/Object/ +        @txt=if defined? t_o.obj; t_o.obj +        else nil +        end +        @ocn=if defined? t_o.ocn; t_o.ocn.to_s +        else nil +        end +        @headname=if t_o.is==:heading and defined? t_o.name; t_o.name +        else nil +        end +      else +        if @md.opt.act[:maintenance][:set]==:on +          p __FILE__ << ':' << __LINE__.to_s +          p t_o.class +          p caller +        end +      end +      if defined? @t_o.ocn +        ocn=((@t_o.ocn.to_s =~/\d+/) ? @t_o.ocn : nil) +        @p_num=ParagraphNumber.new(@md,ocn) +      end +      if @format and not @format.empty? +        if @format=~/^\d:(\S+)/ #need more reliable marker #if @format =~ /#{Rx[:lv]}/ +          headname=$1 #format[/\d~(\S+)/m,1] +          @headname=if headname =~/^[a-zA-Z]/; %{<a name="#{headname}" id="#{headname}"></a>} #consider: h_#{headname} +          else %{<a name="h#{headname}" id="h#{headname}"></a>} +          end +        end +      end +      @dob=t_o if defined? t_o.is +    end +    def endnote_body +      %{ +<p class="endnote"> +  #{@txt} +</p> +} +    end +    def endnote_body_indent +      %{ +  <p class="endnote_indent"> +    #{@txt} +  </p> +} +    end +    def no_paranum +      %{ +<div class="substance"> +  <label class="ocn"> </label> +  <p class="norm"> +    #{@txt} +  </p> +</div> +} +    end +    def para_form_css(tag,attrib)                                                    # regular paragraphs shaped here +      ul=ulc='' +      ul,ulc="<ul>\n  ","\n  </ul>" if @tag =~/li/ +      %{ +<div class="substance"> +  #{@p_num.ocn_display} +  #{ul}<#{tag} class="#{attrib}" #{@p_num.id}> +    #{@txt} +  </#{tag}>#{ulc} +</div> +} +    end +    def para +      para_form_css('p','norm') +    end +    def code +      para_form_css('p','code') +    end +    def center +      para_form_css('p','center') +    end +    def bold +      para_form_css('p','bold') +    end +    def bullet +      para_form_css('li','bullet') +    end +    def format(tag,attrib) +      para_form_css(tag,attrib) +    end +    def heading_normal(tag,attrib) +      %{ +<div class="substance"> +  #{@p_num.ocn_display} +  <#{tag} class="#{attrib}" #{@p_num.id}>#{@p_num.name} +    #{@headname}#{@txt} +  </#{tag}> +</div> +} +    end +    def heading_body +      heading_normal('p','norm') +    end +    def heading_body0 +      heading_normal('h1','norm') +    end +    def heading_body1 +      heading_normal('h1','norm') +    end +    def heading_body2 +      heading_normal('h2','norm') +    end +    def heading_body3 +      heading_normal('h3','norm') +    end +    def heading_body4 +      heading_normal('h4','norm') +    end +    def heading_body5 +      heading_normal('h5','norm') +    end +    def heading_body6 +      heading_normal('h6','norm') +    end +    def heading_body7 +      heading_normal('h7','norm') +    end +    def title_header(tag,attrib) +      %{ +<div class="content"> +<#{tag} class="#{attrib}"> +    #{@txt} +  </#{tag}> +</div> +} +    end +    def title_header1 +      title_header('h1','tiny') +    end +    def title_header2 +      title_header('h2','tiny') +    end +    def title_header3 +      title_header('h3','tiny') +    end +    def title_header4 +      '' +    end +    def title_header4_old +      %{ +<div class="substance"> +  <label class="ocn"> </label> +  <h4 class="banner"> +    #{@txt} +  </h4> +</div> +} +    end +    def dl #check :trailer +      "<dl><b>#{@txt}</b> #{@trailer}</dl>" +    end +    def table_css_end      #<!TZ!> +      '</table> +    </p> +  </div>' +    end +    def gsub_body +#fix +      @txt=case @txt +      when /^\s*\((i+|iv|v|vi+|ix|x|xi+)\)/ +        @txt.gsub(/^\((i+|iv|v|vi+|ix|x|xi+)\)/,'<b>(\1)</b>'). +          gsub(/^(#{Mx[:pa_o]}i[1-9]#{Mx[:pa_c]})\s*\((i+|iv|v|vi+|ix|x|xi+)\)/,'\1<b>(\2)</b>') +      when /^\s*\(?(\d|[a-z])+\)/ +        @txt.gsub(/^\((\d+|[a-z])+\)/,'<b>(\1)</b>'). +          gsub(/^(#{Mx[:pa_o]}i[1-9]#{Mx[:pa_c]})\s*\((\d+|[a-z])+\)/,'\1<b>(\2)</b>') +      when /^\s*\d{1,3}\.\s/ +        @txt.gsub(/^\s*(\d+\.)/,'<b>\1</b>') +      when /^\s*[A-Z]\.\s/ +        @txt.gsub(/^\s*([A-Z]\.)/,'<b>\1</b>') +      else @txt +      end +    end +    def bold_para +      %{#{the_margin.txt_0} +  <p class="bold"> +    #{@txt} +  </p> +#{the_margin.num_css} +      +#{the_table_close}} +    end +    def bold_header +      @txt=@txt.gsub(/[1-9]~(\S+)/,'<a name="\1"></a>'). +        gsub(/[1-9]~/,'') +      %{<p class="bold"> +    #{@txt} +  </p> +#{the_margin.num_css} +      +#{the_table_close}} +    end +    def toc_head_copy_at +      %{<p class="center">#{@txt}</p>\n} +    end +    def center +      %{<p class="center">#{@txt}</p>\n} +    end +    def bold +      %{<p class="bold">#{@txt}</p>\n} +    end +    def center_bold +      %{<p class="centerbold">#{@txt}</p>\n} +    end +  end +  class FormatScroll < FormatTextObject +    include SiSU_Parts_XML +    def initialize(md,txt) +      super(md,txt) +    end +  end +  class FormatSeg < FormatTextObject +    def initialize(md,txt) +      super(md,txt) +    end +    def navigation_toc_lev1_advert +      %{#{@banner.home_button}\n +<center> +#{@txt} +#{@two} +</a></center><p />} +    end +    def navigation_toc_lev1 +      %{#{@banner.nav_toc}} +    end +    def navigation_toc_lev2                                                      #change bold use css +      %{<p /> +<table summary="navigation segment level 2"> +<tr><td width ="20"> +</td> +<td> +  <font size="3" #{the_font.set_face}> +    <b>#{@txt}</b> +  </font> +  </p> +#{the_table_close}} +    end +    def navigation_toc_lev3                                                      #change bold use css +      %{<p /> +<table summary="navigation segment level 3"> +<tr><td width ="20"> +</td> +<td> +  <font size="3" #{the_font.set_face}> +    <b>#{@txt}</b> +  </font> +  </p> +#{the_table_close}} +    end +    def navigation_toc_lev4 +      %{<table summary="navigation segment level 4"> +<tr><td width ="80"> +</td> +<td> +<p> +  #{@txt} +</p> +#{the_table_close}} +    end +    def navigation_toc_lev5 +    end +    def navigation_toc_lev6 +    end +    def endnote_seg_body(fn='')  #FIX                                                #url construction keep within single line... BUG WATCH 200408 +      fn='doc' if fn.empty? #you may wish to reconsider, sends to 'doc' where no segment info # Sfx[:html] or Sfx[:xhtml] ? +      %{ +  <p class="endnote"> +    #{@endnote_part_a}#{fn}#{@md.lang_code_insert}#{Sfx[:html]}#{@endnote_part_b} +  </p> +} +    end +    def subtoc_lev(tag,attrib) +      txt=if @txt \ +      and @txt =~/<\/?i>|<a\s+name="\S+?">/mi +        @txt.gsub(/<\/?i>|<a\s+name="\S+?">/mi,'') #removes name markers from subtoc, go directly to substantive text +      else @txt +      end +      note='' +      if txt =~/(#{Mx[:en_a_o]}.+?#{Mx[:en_a_c]}|#{Mx[:en_b_o]}.+?#{Mx[:en_b_c]}\s*)/m +        note=$1 +        note=note.gsub(/[\n\s]+/m,' ') +        txt=txt.gsub(/(?:#{Mx[:en_a_o]}.+?#{Mx[:en_a_c]}|#{Mx[:en_b_o]}.+?#{Mx[:en_b_c]})\s*/m,' '). +          gsub(/<a[\n\s]+name="-\d+"[\n\s]+href="#_\d+"> <sup>\d+<\/sup> /m,'') +      end +      %{<#{tag} class="#{attrib}"> +    <a href="##{@ocn}"><i>#{txt}</i></a> #{note} +  </#{tag}>} +    end +    def subtoc_lev5 +      subtoc_lev('h5','subtoc') if @txt +    end +    def subtoc_lev6 +      subtoc_lev('h6','subtoc') if @txt +    end +    def subtoc_lev7 +      subtoc_lev('h7','subtoc') if @txt +    end +    #% para sisu +    def header_sub(tag,attrib) +      @txt=@txt.gsub(/(?:#{Mx[:en_a_o]}.+?#{Mx[:en_a_c]}|#{Mx[:en_b_o]}.+?#{Mx[:en_b_c]})\s*/m,' ') +      %{ +<div class="substance"> +  #{@p_num.ocn_display} +  <#{tag} class="#{attrib}" #{@p_num.id}>#{@p_num.name} #{@headname} +    #{@txt} +  </#{tag}> +</div> +} +    end +    def header4 +      %{ +<div class="substance"> +  #{@p_num.ocn_display} +  <h1 class="norm" #{@p_num.id}>#{@p_num.name} +    #{@t_o[:format]} +    #{@txt} +  </h1> +</div> +} +    end +    def header5 +      header_sub('p','bold') +    end +    def header6 +      header_sub('p','bold') +    end +    def header7 +      header_sub('p','bold') +    end +    def navigation_header4 +      %{<table summary="navigation segment header 4" width=100% bgcolor="#08163f" border="0"> +<tr><td align="center"> +<p class="bold"> +  #{@txt} +</p> +#{the_table_close}} +    end +    def navigation_header5 +      %{<p class="bold"> +  #{@txt} +</p>} +    end +    def navigation_header6 +      %{<p class="bold"> +  #{@txt} +</p>} +    end +    def navigation_header7 +      %{<p class="bold"> +  #{@txt} +</p>} +    end +    def navigation_center +      "<center>#{@txt}</center>" +    end +  end +  class FormatToc < FormatTextObject +    def initialize(md,txt) +      super(md,txt) +    end +    def links_guide +      %{  <li class="doc"> +    <a href="#{@lnk_url}" target="_top"> +      #{@lnk_txt} +    </a> +  </li> +} +    end +    def lev(tag,attrib) +      if @txt +        %{<#{tag} class="#{attrib}"> +    #{@txt} +  </#{tag}> +} +      else '' +      end +    end +    def lev1 +      lev('h1','toc') +    end +    def lev2 +      lev('h2','toc') +    end +    def lev3 +      lev('h3','toc') +    end +    def lev4 +      lev('h4','toc') +    end +    def lev5 +      lev('h5','toc') +    end +    def lev6 +      lev('h6','toc') +    end +    def lev7 +      lev('h7','toc') +      #lev('b','toc') +    end +    def lev0 #docinfo +      lev('h0','toc') +    end +    def mini_lev1 +      lev('h1','minitoc') +    end +    def mini_lev2 +      lev('h2','minitoc') +    end +    def mini_lev3 +      lev('h3','minitoc') +    end +    def mini_lev4 +      lev('h4','minitoc') +    end +    def mini_lev5 +      lev('h5','minitoc') +    end +    def mini_lev6 +      lev('h6','minitoc') +    end +    def mini_lev7 +      lev('h7','minitoc') +    end +    def mini_lev0 #docinfo +      lev('h0','minitoc') +    end +    def mini_tail +  %{ +  <h4 class="minitoc"> +    <a href="sisu_manifest.html">Manifest (alternative outputs)</a> +  </h4> +} +    end +    def mini_concord_tail +  %{ +  <h4 class="minitoc"> +    <a href="concordance.html">Concordance (wordlist)</a> +  </h4> +  <h4 class="minitoc"> +    <a href="sisu_manifest.html">Manifest (alternative outputs)</a> +  </h4> +} +    end +  end +  class XML +  end +end +__END__ +,** Notes: tidy -xml index.xml >> index.tidy +#+END_SRC + +** xml_md_oai_pmh_dc.rb + +#+BEGIN_SRC ruby  :tangle "../lib/sisu/xml_md_oai_pmh_dc.rb" +# <<sisu_document_header>> +module SiSU_XML_Metadata +  require_relative 'se'                                 # se.rb +    include SiSU_Env +  require_relative 'dp'                                 # dp.rb +    include SiSU_Param +  class OAI_PMH +    def initialize(opt) +      @md=SiSU_Param::Parameters.new(opt).get +      @oai_pmh=[] +    end +    def read +      output +    end +    def pre +<<WOK +<?xml version="1.0" encoding="UTF-8"?> +<oai_dc:dc +  xmlns:oai_dc="http://www.openarchives.org/OAI/2.0/oai_dc/" +  xmlns:dc="http://purl.org/dc/elements/1.1/" +  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" +  xsi:schemaLocation="http://www.openarchives.org/OAI/2.0/oai_dc/ +  http://www.openarchives.org/OAI/2.0/oai_dc.xsd"> +WOK +    end +    def body +      if defined? @md.title.full \ +      and @md.title.full=~/\S+/                                               # DublinCore 1 - title +        @oai_pmh << %{  <dc:title xml:lang="en">#{@md.title.full}</dc:title>\n} +      end +      if defined? @md.creator.author \ +      and @md.creator.author=~/\S+/                                           # DublinCore 2 - creator/author (author) +        txt=meta_content_clean(@md.creator.author) +        @oai_pmh << %{  <dc:author>#{txt}</dc:author>\n} +      end +      if defined? @md.classify.subject \ +      and @md.classify.subject=~/\S+/                                          # DublinCore 3 - subject (us library of congress, eric or udc, or schema???) +        txt=meta_content_clean(@md.classify.subject) +        @oai_pmh << %{  <dc:subject>#{txt}</dc:subject>\n} +      end +      if defined? @md.classify.keywords \ +      and @md.classify.keywords=~/\S+/ +        txt=meta_content_clean(@md.classify.keywords) +        @oai_pmh << %{  <dc:keywords>#{txt}</dc:keywords>\n} +      end +      if @md.publisher                                                         # DublinCore 5 - publisher (current copy published by) +        txt=meta_content_clean(@md.publisher) +        @oai_pmh << %{  <dc:publisher>#{txt}</dc:publisher>\n} +      end +      if defined? @md.creator.contributor \ +      and @md.creator.contributor=~/\S+/                                       # DublinCore 6 - contributor +        txt=meta_content_clean(@md.creator.contributor) +        @oai_pmh << %{  <dc:contributor>#{txt}</dc:contributor>\n} +      end +      if defined? @md.date.published \ +      and @md.date.published=~/\S+/                                            # DublinCore 7 - date year-mm-dd +        @oai_pmh << %{  <dc:date>#{@md.date.published}</dc:date>\n} +      end +      if defined? @md.date.created \ +      and @md.date.created=~/\S+/                                              # DublinCore 7 - date.created +        @oai_pmh << %{  <dc:date_created>#{@md.date.created}</dc:date_created>\n} +      end +      if defined? @md.date.issued \ +      and @md.date.issued=~/\S+/                                               # DublinCore 7 - date.issued +        @oai_pmh << %{  <dc:date_issued>#{@md.date.issued}</dc:date_issued>\n} +      end +      if defined? @md.date.available \ +      and @md.date.available=~/\S+/                                            # DublinCore 7 - date.available +        @oai_pmh << %{  <dc:date_available>#{@md.date.available}</dc:date_available>\n} +      end +      if defined? @md.date.valid \ +      and @md.date.valid=~/\S+/                                                # DublinCore 7 - date.valid +        @oai_pmh << %{  <dc:date_valid>#{@md.date.valid}</dc:date_valid>\n} +      end +      if defined? @md.date.modified \ +      and @md.date.modified=~/\S+/                                             # DublinCore 7 - date.modified +        @oai_pmh <<  %{  <dc:date_modified>#{@md.date.modified}</dc:date_modified>\n} +      end +      if defined? @md.notes.description \ +      and @md.notes.description=~/\S+/                                         # DublinCore 4 - description +        txt=meta_content_clean(@md.notes.description) +        @oai_pmh << %{  <dc:description>#{txt}</dc:description>\n} +      end +      if defined? @md.notes.coverage \ +      and @md.notes.coverage=~/\S+/                                            # DublinCore 14 - coverage +        txt=meta_content_clean(@md.notes.coverage) +        @oai_pmh << %{  <dc:coverage>#{txt}</dc:coverage>\n} +      end +      if defined? @md.notes.relation \ +      and @md.notes.relation=~/\S+/                                            # DublinCore 13 - relation +        txt=meta_content_clean(@md.notes.relation) +        @oai_pmh << %{  <dc:relation>#{txt}</dc:relation>\n} +      end +      if defined? @md.notes.type \ +      and @md.notes.type=~/\S+/                                                # DublinCore 8 - type +        txt=meta_content_clean(@md.notes.type) +        @oai_pmh << %{  <dc:type>#{txt}</dc:type>\n} +      end +      if defined? @md.notes.format \ +      and @md.notes.format=~/\S+/                                              # DublinCore 9 - format +        txt=meta_content_clean(@md.notes.format) +        @oai_pmh << %{  <dc:format>#{txt}</dc:format>\n} +      end +      #if defined? @md.identifier.sisupod \ +      #and @md.identifier.sisupod=~/\S+/                                       # DublinCore 10 - identifier +      #  txt=meta_content_clean(@md.identifier.sisupod) +      #  @oai_pmh << %{  <dc:identifier>#{txt}</dc:identifier>\n} +      #end +      if defined? @md.original.source \ +      and @md.original.source=~/\S+/                                           # DublinCore 11 - source +        txt=meta_content_clean(@md.original.source) +        @oai_pmh << %{  <dc:source>#{txt}</dc:source>\n} +      end +      if defined? @md.title.language \ +      and @md.title.language=~/\S+/                                            # DublinCore 12 - language (English) +        @oai_pmh << %{  <dc:language>#{@md.title.language}</dc:language>\n} +      end +      if defined? @md.original.language \ +      and @md.original.language=~/\S+/ +        @oai_pmh << %{  <dc:language>#{@md.original.language}</dc:language>\n} +      end +      if defined? @md.rights.all \ +      and @md.rights.all=~/\S+/                                                # DublinCore 15 - rights +        txt=meta_content_clean(@md.rights.all) +        @oai_pmh << %{  <dc:rights>#{txt}</dc:rights>\n} +      end +      @oai_pmh +    end +    def meta_content_clean(content='') +      unless content.nil? +        content=content.tr('"',"'") +      end +      content +    end +    def post +      '</oai_dc:dc>' +    end +    def output +      SiSU_Env::FileOp.new(@md).mkdir +      oai_pmh=SiSU_Env::FileOp.new(@md,@md.fn[:oai_pmh]).mkfile #implement in param +      oai_pmh << pre +      body.each do |x| +        oai_pmh << x +      end +      oai_pmh << post +    end +  end +end +__END__ +http://www.openarchives.org/pmh/ +http://www.openarchives.org/OAI/2.0/openarchivesprotocol.htm#dublincore +http://es.dublincore.org/documents/usageguide/elements.shtml +http://dublincore.org/documents/dces/ +see also http://dublincore.org/documents/dcmes-xml/ +#http://www.openarchives.org/OAI/2.0/openarchivesprotocol.htm#dublincore +#sample implementation, e.g. 2 +<?xml version="1.0" encoding="UTF-8"?> +<oai_dc:dc +    xmlns:oai_dc="http://www.openarchives.org/OAI/2.0/oai_dc/" +    xmlns:dc="http://purl.org/dc/elements/1.1/" +    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" +    xsi:schemaLocation="http://www.openarchives.org/OAI/2.0/oai_dc/ +    http://www.openarchives.org/OAI/2.0/oai_dc.xsd"> +  <dc:title xml:lang="en">Grassmann's space analysis</dc:title> +  <dc:author>Hyde, E. W. (Edward Wyllys)</dc:author> +  <dc:subject>LCSH:Ausdehnungslehre; LCCN QA205.H99</dc:subject> +  <dc:publisher>J. Wiley & Sons</dc:publisher> +  <dc:date>Created: 1906; Available: 1991</dc:date> +  <dc:type>text</dc:type> +  <dc:identifier>http://resolver.library.cornell.edu/math/1796949 +     </dc:identifier> +  <dc:language>english</dc:language> +  <dc:rights xml:lang="en">Public Domain</dc:rights> +</oai_dc:dc> +#+END_SRC + +** xml_parts.rb + +#+BEGIN_SRC ruby  :tangle "../lib/sisu/xml_parts.rb" +# <<sisu_document_header>> +module SiSU_Parts_XML +  require_relative 'generic_parts'                       # generic_parts.rb +  include SiSU_Parts_Generic +  def the_line_break +    '<br />' +  end +  def the_table_close +    '</td></tr> +</table>' +  end +  def the_url_decoration +    def xml_open                     #'<' +      Dx[:url_o] +    end +    def xml_close                    #'>' +      Dx[:url_c] +    end +    def txt_open +      '<' +    end +    def txt_close +      '>' +    end +    self +  end +  def the_color +    def white +      '#ffffff' +    end +    def black +      '#000000' +    end +    def grey_pale +      '#eeeeee' +    end +    def grey_medium +      '#cccccc' +    end +    def grey +      '#999999' +    end +    def blue_ink +      '#003399' +    end +    def blue_tinge +      '#e3ecef' +    end +    def yellow_light +      '#fff3b6' +    end +    def table1 +      'ffffcc' +    end +    def table2 +      'c0d0f0' +    end +    def band1 +      %{"#{white}"} +    end +    def band2 +      %{"#{white}"} +    end +    self +  end +  def the_png +    def _url_path_image_base #used for html image display +      "#{Xx[:html_relative2]}_sisu/image" +    end +    def ico +      %{  <link rel="shortcut icon" href="../_sisu/image/#{the_icon.i_ico}" />} +    end +    def png_home +      %{<img border="0" src="#{_url_path_image_base}/#{the_icon.home_button}" alt="#{the_text.home} -->" />} +    end +    def png_home_button +      rel=@dir.path_rel_links.html_scroll_2 +      %{<img border="0" src="#{rel}/#{the_icon.home_button}" alt="#{the_text.home} -->" />} +    end +    self +  end +  def the_font +    def set_fonts +      'verdana, arial, georgia, tahoma, sans-serif, helvetica, times, roman' +     #'verdana, arial, georgia, tahoma, sans-serif, helvetica, "times new roman", times, roman' +    end +    def set_face +      %{face="#{set_fonts}"} +    end +    #def set_color +    #  'color="#000000"' +    #end +    #def set_size_endnote +    #  'size="3"' +    #end +    #def set_small +    #  'size="3"' +    #end +    #def set_tiny +    #  'size="2"' +    #end +    #def paragraph_font_tiny +    #  %{<font #{set_tiny} #{set_face}>} +    #end +    #def paragraph_font_small +    #  %{<font #{set_small} #{set_face}>} +    #end +    self +  end +  def the_banner +    def home_button_only +      %{<a href="#{url.site}/"> +  #{the_png.png_home_button} +  </a>} +    end +    def banner_band +      %{<table summary="home button" width="100%" border="0" cellpadding="3" align="center"> +<tr><td align="left" valign="middle"> +  <a href="#{url.site}/" target="_top"> +    #{the_png.png_home} +  </a> +</td> +<td width="90%"> +#{the_table_close}} +    end +    self +  end +end +module SiSU_Proj_XML +  require_relative 'html_parts'                         # html_parts.rb +  require_relative 'se'                                 # se.rb +  include SiSU_Env +  class Bits < SiSU_Proj_HTML::Bits +  end +end +__END__ +#+END_SRC + +** xml_persist.rb + +#+BEGIN_SRC ruby  :tangle "../lib/sisu/xml_persist.rb" +# <<sisu_document_header>> +module SiSU_XML_Persist +  class Persist +    @@persist=nil +    attr_accessor :head,:toc,:body,:tail,:open,:close,:sc,:endnotes,:book_idx,:metadata +    #attr_accessor :head,:body,:tail,:open,:close,:sc +#@@odf={ body: [], head: [], toc: [],  metadata: [], tail: [], book_idx: [], endnotes: [] } +    def initialize(args=nil) +      @@persist=args=(args ? args : (@@persist || persist_init_hash_values)) +      @head=args[:head] +      @toc=args[:toc] +      @body=args[:body] +      @tail=args[:tail] +      @open=args[:open] +      @close=args[:close] +      @sc=args[:sc] +      @endnotes=args[:endnotes] +      @book_idx=args[:book_idx] +      @metadata=args[:metadata] +    end +    def head +      @head +    end +    def toc +      @toc +    end +    def body +      @body +    end +    def tail +      @tail +    end +    def open +      @open +    end +    def close +      @close +    end +    def sc +      @sc +    end +    def endnotes +      @endnotes +    end +    def book_idx +      @book_idx +    end +    def metadata +      @metadata +    end +    def persist_init_hash_values +      { +        head: [], +        toc: [], +        body: [], +        tail: [], +        open: [], +        close: [], +        sc: [], +        endnotes: [], +        book_idx: [], +        metadata: [], +      } +    end +    def persist_init +      @@persist=nil +      Persist.new(persist_init_hash_values) +    end +  end +end +__END__ +#+END_SRC + +** xml_scaffold_structure_collapsed.rb + +#+BEGIN_SRC ruby  :tangle "../lib/sisu/xml_scaffold_structure_collapsed.rb" +# <<sisu_document_header>> +module SiSU_XML_Scaffold_Structure_Collapse +  require_relative 'se_hub_particulars'                 # se_hub_particulars.rb +    include SiSU_Particulars +  require_relative 'ao'                                 # ao.rb +  require_relative 'se'                                 # se.rb +    include SiSU_Env +  class Source +    def initialize(opt) +      @opt=opt +      @particulars=SiSU_Particulars::CombinedSingleton.instance.get_all(opt) +    end +    def spaces +      Ax[:spaces] +    end +    def read +      begin +        @md,@ao_array=@particulars.md,@particulars.ao_array +        SiSU_XML_Scaffold_Structure_Collapse::Source::Scroll.new(@ao_array,@md).songsheet +      rescue +        SiSU_Errors::Rescued.new($!,$@,@opt.selections.str,@opt.fns).location do +          __LINE__.to_s + ':' + __FILE__ +        end +      ensure +      end +    end +    private +    class Scroll <Source +      def initialize(data='',md='') +        @data,@md=data,md +      end +      def songsheet +        @t='sisu' +        data=@data +        if @md.opt.act[:verbose_plus][:set]==:on +          structure_collapsed(data) +        end +        structure_build_collapsed(data) +      end +      def tags +        # collapsed --> +        def collapsed +          [ '0', +            '1', +            '2', +            '3', +            '4', +            '5', +            '6' +          ] +        end +        def docbook +        end +        def fictionbook +        end +        self +      end +      def output(o,lev=nil,comment='') +         puts lev == (0..6) \ +         ? "#{spaces*lev}<#{lev}>[#{o.ocn}] #{o.ln} #{o.obj}</#{lev}>#{comment}" +         : "<#{lev}>[#{o.ocn}] #{o.ln} #{o.obj}</#{lev}>#{comment}" +      end +      def structure_collapsed(data) +        puts "\ncollapsed structure, heading outline --->\n\n" +        data.each_with_index do |o,i| +          if  (o.is ==:heading || o.is ==:heading_insert) +            output(o,o.lc) +          end +        end +      end +      def structure_build_collapsed(data) +        @s=tags.collapsed +        puts "\nXML [#{@t} type] structure outline --->\n\n" +        h=[0,false,false,false] +        puts "<#{@s[0]}>" +        data.each_with_index do |o,i| +          if  (o.is ==:heading || o.is ==:heading_insert) +            lev=o.lc +            structure_build_tag_close(lev,h) +            puts "#{spaces*lev}<#{@s[lev]}>\n#{spaces*lev}  [#{o.ocn}] #{lev} {#{o.node}}" +            h[0]=lev +          end +        end +        structure_build_tag_close(0,h) +      end +      def structure_build_tag_close(lev,h) +        case h[0] +        when 1 +          puts "#{spaces*1}</#{@s[1]}>" if (lev <= 1) +          puts "</#{@s[0]}>"         if (lev==0) +        when 2 +          puts "#{spaces*2}</#{@s[2]}>" if (lev <= 2) +          puts "#{spaces*1}</#{@s[1]}>" if (lev <= 1) +          puts "</#{@s[0]}>"         if (lev==0) +        when 3 +          puts "#{spaces*3}</#{@s[3]}>" if (lev <= 3) +          puts "#{spaces*2}</#{@s[2]}>" if (lev <= 2) +          puts "#{spaces*1}</#{@s[1]}>" if (lev <= 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) +          puts "#{spaces*2}</#{@s[2]}>" if (lev <= 2) +          puts "#{spaces*1}</#{@s[1]}>" if (lev <= 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) +          puts "#{spaces*2}</#{@s[2]}>" if (lev <= 2) +          puts "#{spaces*1}</#{@s[1]}>" if (lev <= 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) +          puts "#{spaces*2}</#{@s[2]}>" if (lev <= 2) +          puts "#{spaces*1}</#{@s[1]}>" if (lev <= 1) +          puts "</#{@s[0]}>"         if (lev==0) +        end +      end +    end +  end +end +__END__ +@s=['0', +  'A', +  'B', +  'C', +  '1', +  '2', +  '3' +] +#@t='docbook'         #@t='fictionbook' +#@s=['book',          #@s=['body', +#  'part',            #  'section', +#  'subpart N/A',     #  'section', +#  'sub-subpart N/A', #  'section', +#  'chapter',         #  'section', +#  'sect1',           #  'section', +#  'sect2'            #  'section' +#]                    #] +#+END_SRC + +** xml_scaffold_structure_sisu.rb + +#+BEGIN_SRC ruby  :tangle "../lib/sisu/xml_scaffold_structure_sisu.rb" +# <<sisu_document_header>> +module SiSU_XML_Scaffold_Structure_Sisu +  require_relative 'se_hub_particulars'                 # se_hub_particulars.rb +    include SiSU_Particulars +  require_relative 'ao'                                 # ao.rb +  require_relative 'se'                                 # se.rb +    include SiSU_Env +  class Source +    def initialize(opt) +      @opt=opt +      @particulars=SiSU_Particulars::CombinedSingleton.instance.get_all(opt) +    end +    def spaces +      Ax[:spaces] +    end +    def read +      begin +        @md,@ao_array=@particulars.md,@particulars.ao_array +        SiSU_XML_Scaffold_Structure_Sisu::Source::Scroll.new(@ao_array,@md).songsheet +      rescue +        SiSU_Errors::Rescued.new($!,$@,@opt.selections.str,@opt.fns).location do +          __LINE__.to_s + ':' + __FILE__ +        end +      ensure +      end +    end +    private +    class Scroll <Source +      def initialize(data='',md='') +        @data,@md=data,md +      end +      def songsheet +        @t='sisu' +        data=@data +        if @md.opt.act[:verbose_plus][:set]==:on +          structure_sisu_simple(data) +        end +        structure_build_sisu(data) +      end +      def tags +        def sisu +          [ '0', +            'A', +            'B', +            'C', +            '1', +            '2', +            '3' +          ] +        end +        self +      end +      def structure_sisu_simple(data) +        puts "\nsisu structure, heading outline --->\n\n" +        data.each_with_index do |o,i| +          if  (o.is ==:heading || o.is ==:heading_insert) +            puts "#{spaces*o.ln}<#{tags.sisu[o.ln]}>[#{o.ocn}] #{o.ln} #{o.obj}</#{tags.sisu[o.ln]}>" +          end +        end +      end +      def output(o,lev=nil,comment='') +         puts lev == (0..6) \ +         ? "#{spaces*lev}<#{lev}>[#{o.ocn}] #{o.ln} #{o.obj}</#{lev}>#{comment}" +         : "<#{lev}>[#{o.ocn}] #{o.ln} #{o.obj}</#{lev}>#{comment}" +      end +      def structure_build_sisu(data) +        @s=tags.sisu +        puts "\nXML [#{@t} type] structure outline --->\n\n" +        h=[0,false,false,false] +        puts "<#{@s[0]}>" +        data.each_with_index do |o,i| +          if  (o.is ==:heading || o.is ==:heading_insert) +            structure_build_tag_close(o.ln,h) +            puts "#{spaces*o.ln}<#{@s[o.ln]}>\n#{spaces*o.ln}  [#{o.ocn}] #{o.ln} {#{o.node}}" +            case o.ln +            when 1 +              h=[o.ln,true,false,false] +            when 2 +              h=[o.ln,true,true,false] +            when 3 +              h=[o.ln,true,true,true] +            when 4..6 +              h[0]=o.ln +            end +          end +        end +        structure_build_tag_close(0,h) +      end +      def structure_build_tag_close(lev,h) +        case h[0] +        when 1 +          puts "#{spaces*1}</#{@s[1]}>" if (lev <= 1) && h[1] +          puts "</#{@s[0]}>"         if (lev==0) +        when 2 +          puts "#{spaces*2}</#{@s[2]}>" if (lev <= 2) && h[2] +          puts "#{spaces*1}</#{@s[1]}>" if (lev <= 1) && h[1] +          puts "</#{@s[0]}>"         if (lev==0) +        when 3 +          puts "#{spaces*3}</#{@s[3]}>" if (lev <= 3) && h[3] +          puts "#{spaces*2}</#{@s[2]}>" if (lev <= 2) && h[2] +          puts "#{spaces*1}</#{@s[1]}>" if (lev <= 1) && h[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) && h[3] +          puts "#{spaces*2}</#{@s[2]}>" if (lev <= 2) && h[2] +          puts "#{spaces*1}</#{@s[1]}>" if (lev <= 1) && h[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) && h[3] +          puts "#{spaces*2}</#{@s[2]}>" if (lev <= 2) && h[2] +          puts "#{spaces*1}</#{@s[1]}>" if (lev <= 1) && h[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) && h[3] +          puts "#{spaces*2}</#{@s[2]}>" if (lev <= 2) && h[2] +          puts "#{spaces*1}</#{@s[1]}>" if (lev <= 1) && h[1] +          puts "</#{@s[0]}>"         if (lev==0) +        end +      end +    end +  end +end +__END__ +@s=['0', +  'A', +  'B', +  'C', +  '1', +  '2', +  '3' +] +#@t='docbook'         #@t='fictionbook' +#@s=['book',          #@s=['body', +#  'part',            #  'section', +#  'subpart N/A',     #  'section', +#  'sub-subpart N/A', #  'section', +#  'chapter',         #  'section', +#  'sect1',           #  'section', +#  'sect2'            #  'section' +#]                    #] +#+END_SRC + +* odf +** xml_odf_odt.rb + +#+BEGIN_SRC ruby  :tangle "../lib/sisu/xml_odf_odt.rb" +# <<sisu_document_header>> +module SiSU_XML_ODF_ODT +  require_relative 'se_hub_particulars'                 # se_hub_particulars.rb +    include SiSU_Particulars +  require_relative 'ao'                                 # ao.rb +  require_relative 'se'                                 # se.rb +    include SiSU_Env +  require_relative 'xml_parts'                          # xml_parts.rb +  require_relative 'xml_odf_odt_format'                 # xml_odf_odt_format.rb +    include SiSU_XML_ODF_ODT_Format +  require_relative 'shared_metadata'                    # shared_metadata.rb +  require_relative 'txt_shared'                         # txt_shared.rb +  require_relative 'xml_shared'                         # xml_shared.rb +    include SiSU_XML_Munge +  require_relative 'xml_persist'                        # xml_persist.rb +  @@alt_id_count,@@alt_id_count=0,0 +  class Source +    begin +      require 'zlib' +      require 'find' +    rescue LoadError +      SiSU_Utils::CodeMarker.new(__LINE__,__FILE__,:fuchsia). +        error('zlib or find NOT FOUND (LoadError)') +    end +    def initialize(opt) +      @opt=opt +      @particulars=SiSU_Particulars::CombinedSingleton.instance.get_all(opt) +      @@endnotes_para=[] +    end +    def read +      begin +        @md,@env,@ao_array=@particulars.md,@particulars.env,@particulars.ao_array +        unless  @opt.act[:quiet][:set]==:on +          tool=(@opt.act[:verbose][:set]==:on \ +          || @opt.act[:verbose_plus][:set]==:on \ +          || @opt.act[:maintenance][:set]==:on) \ +          ? "#{@env.program.odf_viewer} file://#{@md.file.output_path.odt.dir}/#{@md.file.base_filename.odt}" +          : "[#{@opt.f_pth[:lng_is]}] #{@opt.fno}" +          (@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], +              'Opendocument (ODF:ODT)', +              tool +            ).green_hi_blue +          : SiSU_Screen::Ansi.new( +              @opt.act[:color_state][:set], +              'Opendocument (ODF:ODT)', +              tool +            ).green_title_hi +          if (@opt.act[:verbose_plus][:set]==:on \ +          || @opt.act[:maintenance][:set]==:on) +            SiSU_Screen::Ansi.new( +              @opt.act[:color_state][:set], +              @opt.fns, +              'file://' \ +              + @md.file.output_path.odt.dir + '/' \ +              + @md.file.base_filename.odt +            ).flow +          end +        end +        SiSU_XML_ODF_ODT::Source::Scroll.new(@particulars).songsheet +      rescue +        SiSU_Errors::Rescued.new($!,$@,@opt.selections.str,@opt.fns).location do +          __LINE__.to_s + ':' + __FILE__ +        end +      ensure +        Dir.chdir(@opt.f_pth[:pth]) +      end +    end +    private +    class Scroll <Source +      require_relative 'txt_shared'                     # txt_shared.rb +      include SiSU_Parts_XML +      @@img_count=0 +      @@docstart=true +      @@fns=nil +      def initialize(particulars) +        @md,@env,@ao_array=particulars.md,particulars.env,particulars.ao_array +        @make=SiSU_Env::ProcessingSettings.new(@md) +        @tab="\t" +        @br=(@md.opt.act[:maintenance][:set]==:on) \ +        ? '' : '' +      end +      def songsheet +        begin +          @per=SiSU_XML_Persist::Persist.new +          pre +          @data=markup(@ao_array) +          publish +        ensure +          SiSU_XML_Persist::Persist.new.persist_init +          unless (@md.opt.act[:verbose_plus][:set]==:on \ +          || @md.opt.act[:maintenance][:set]==:on) +            if @env.processing_path.odt =~/od[ft]/ +              #p "rm -r #{@env.processing_path.odt}" if @md.opt.selections.str =~/v/ +              FileUtils::rm_r(@env.processing_path.odf_pth) +              #system("rm -r #{@env.processing_path.odt}") +            end +          end +        end +      end +      def break_line +        (@md.opt.act[:maintenance][:set]==:on) \ +        ? "\n" : '' +      end +      # Used for extraction of endnotes from paragraphs +      def extract_endnotes(dob='') +        notes=dob.obj.scan(/#{Mx[:en_a_o]}(\d+\s+.+?)#{Mx[:en_a_c]}/)[1] #FIX +        @n=[] +        notes.each do |n| #high cost to deal with <br> appropriately within odf, consider +          n=n.dup.to_s +          if n =~/#{Mx[:br_line]}/ +            fix=n.split(/#{Mx[:br_line]}/) #watch #added +            fix.each do |x| +              if x =~/\S+/ then @n << x +              end +            end +          else                  @n << n +          end +        end +      end +      def odf_book_idx +      if @md.book_idx +        idx_arr=[] +        idx_raw=SiSU_Particulars::CombinedSingleton. +          instance.get_idx_raw(@md.opt).raw_idx +        idx_raw.each do |x| +          x=if x.is_a?(String) +            SiSU_XML_ODF_ODT_Format::FormatBookIndex.new(x). +              book_idx_bookmark +          else nil +          end +          idx_arr << x.strip if x.is_a?(String) +        end +        @per.book_idx=idx_arr.join +      end +      end +      def odf_metadata +        @per.metadata=SiSU_Metadata::Summary.new(@md). +          odf.metadata +      end +      def odf_tail +        manifest="#{@md.file.output_path.manifest.url}/#{@md.file.base_filename.manifest}" +        @per.tail << %{<text:p text:style-name="P_normal">Available document outputs: <br /> <<text:a xl:type="simple" xl:href="#{manifest}">#{manifest}</text:a>></text:p>} +        @per.tail << %{\n<text:p text:style-name="P_normal">SiSU: <<text:a xl:type="simple" xl:href="http://www.jus.uio.no/lm">www.jus.uio.no/sisu</text:a>> and <<text:a xl:type="simple" xl:href="http://www.sisudoc.org">www.sisudoc.org</text:a>></text:p>} +        @per.tail << "\n</office:text></office:body></office:document-content>" +      end +      def set_bookmark_tag(dob) +        SiSU_XML_ODF_ODT_Format::Tags.new.set_bookmark_tag(dob) +      end +      def heading(dob,p_num) +        dob=footnote(dob) +        m=/#{$1}/ +        breakpage='' +        if @md.fns \ +        and @md.fns != '' \ +        and @md.fns !=@@fns +          @@docstart=true +          @@fns=@md.fns +        end +        unless @@docstart +          breakpage=if (@md.pagenew || @md.pagebreak) \ +          and (@md.pagenew.to_s =~m \ +            or @md.pagebreak.to_s =~m) +            '<text:p text:style-name="P_normal_page_new"> </text:p>' +          elsif @md.pageline \ +          and @md.pageline =~m #fix +          else '' +          end +        end +        @@docstart=false +        if dob.use_ != :dummy +          dob.tmp=dob.obj +          dob.obj=%{#{breakpage}<text:h text:style-name="H_#{dob.ln}" text:outline-level="#{dob.ln}">} \ +          + %{#{p_num[:set_ref]}#{set_bookmark_tag(dob)}#{dob.obj}#{p_num[:display]}</text:h>} +        else dob.tmp,dob.obj='','' +        end +        dob +      end +      def toc(dob,p_num) +        hardspace=(dob.lv =~/[A-D]/i) \ +        ? '<text:p text:style-name="Standard"/>' +        : '' +        toc_heading=dob.ocn \ +        ? (%{<text:bookmark-ref text:reference-format="text" text:ref-name="#{dob.ocn}">} \ +          + %{#{dob.tmp}</text:bookmark-ref>}) +        : dob.tmp +        dob.obj=%{<text:h text:style-name="H_#{dob.ln}" text:outline-level="#{dob.ln}">} \ +        + %{#{toc_heading}</text:h>#{hardspace}} +        dob +      end +      def image_src(i) +        if @md.fns =~/\.ss[tm]$/ \ +        and FileTest.file?("#{@env.path.image_source_include(@md)}/#{i}") #review +          @env.path.image_source_include(@md) +        elsif @md.opt.f_pth[:pth] =~/\/\S+?\/sisupod\/\S+?\/sisupod\/doc/ +          pt=/(\/\S+?\/sisupod\/\S+?\/sisupod)\/doc/.match(@md.opt.f_pth[:pth])[1] +          img_src=pt + '/image' +          if FileTest.file?("#{img_src}/#{i}") +            img_src +          else +            SiSU_Screen::Ansi.new( +              @md.opt.act[:color_state][:set], +              "ERROR - image:", +              %{"#{i}" missing}, +              "search locations: #{@env.path.image_source_include_local}," \ +              + "#{@env.path.image_source_include_remote} and" \ +              + "#{@env.path.image_source_include}" +            ).error2 unless @md.opt.act[:quiet][:set]==:on +            nil +          end +        elsif @md.fns =~/\.ss[tm]$/ \ +        and FileTest.file?("#{@env.path.image_source_include_local}/#{i}") #review +          @env.path.image_source_include_local +        elsif @md.fns =~/\.ss[tm]$/ \ +        and FileTest.file?("#{@env.path.image_source_sisu_includes(@md)}/#{i}") +          @env.path.image_source_sisu_includes(@md) +        elsif @md.fns =~/\.-ss[tm]$/ \ +        and FileTest.file?("#{@env.path.image_source_include_remote}/#{i}") +          @env.path.image_source_include_remote +        else +          SiSU_Screen::Ansi.new( +            @md.opt.act[:color_state][:set], +            "ERROR - image:", +              %{"#{i}" missing}, +              "search locations: " \ +              + @env.path.image_source_include_local + ',' \ +              + @env.path.image_source_include_remote + 'and' \ +              + @env.path.image_source_include \ +              + @md.opt.sisu_data_dir? +          ).error2 unless @md.opt.act[:quiet][:set]==:on +          nil +        end +      end +      def image_odf(img) +        # copy image to od image directory (unless exists) +        # divide pixel dimension by 37.79485 and retain 3 decimal places +        m=img[1] +        i=/^(\S+?\.(?:png|jpg|gif))/.match(m).captures.join \ +          if m =~/^(\S+?\.(?:png|jpg|gif))/ +        c=/^\S+?\.(?:png|jpg|gif)\s+.+?"(.*?)"/.match(m).captures.join \ +          if m =~/^\S+?\.(?:png|jpg|gif)\s+.+?"(.*?)"/ +        w,h=/\s(\d+)x(\d+)/.match(m).captures if m =~/\s\d+x\d+/ +        w=(w.to_i/37.79485).to_s +        h=(h.to_i/37.79485).to_s +        h=/([0-9]+\.\d{0,3})/.match(h).captures.join +        w=/([0-9]+\.\d{0,3})/.match(w).captures.join +        image_source=image_src(i) +        if image_source +          if FileTest.file?("#{image_source}/#{i}") +            FileUtils::cp( +              "#{image_source}/#{i}", +              "#{@env.processing_path.odt}/Pictures/#{i}" +            ) +          else STDERR.puts %{\t*WARN* did not find image - "#{image_source}/#{i}" [#{__FILE__}:#{__LINE__}]} +          end +        end +        img=if i.to_s =~/jpg|png|gif/ \ +        and h.to_s =~/\d/ \ +        and w.to_s =~/\d/ +          @@img_count +=1 +          %{<draw:frame draw:style-name="fr1" draw:name="graphics#{@@img_count}" text:anchor-type="as-char" svg:width="#{w}cm" svg:height="#{h}cm" draw:z-index="2"><draw:image xl:href="Pictures/#{i}" xl:type="simple" xl:show="embed" xl:actuate="onLoad"/></draw:frame>#{c}} #anchor-type: as-char or paragraph or char or ... +        else %{<text:p text:style-name="P_normal">[image omitted]</text:p>} +        end +      end +      def image(dob) +        m=if dob.obj =~/#{Mx[:lnk_o]}[ ]*(.+?)[ ]*#{Mx[:lnk_c]}#{Mx[:url_o]}\S+?#{Mx[:url_c]}/ +          dob.obj.scan(/(#{Mx[:lnk_o]}[ ]*(.+?)[ ]*#{Mx[:lnk_c]}#{Mx[:url_o]}(\S+?)#{Mx[:url_c]})/) +        elsif dob.obj =~/#{Mx[:lnk_o]}[ ]*(.+?)[ ]*#{Mx[:lnk_c]}image/ +          dob.obj.scan(/(#{Mx[:lnk_o]}[ ]*(.+?)[ ]*#{Mx[:lnk_c]}(image))/) +        else nil +        end +        if m then m.each do |i| +            cont,url=i[1],i[2] +            cont=cont.gsub(/([)(\]\[])/,"\\\\\\1"). +              gsub(/([+?])/,"\\\\\\1") # incorrect handling of + +            url=url.gsub(/([+?])/,"\\\\\\1") +            dob.obj=dob.obj.sub(/#{Mx[:lnk_o]}[ ]*#{cont}[ ]*#{Mx[:lnk_c]}image/m,image_odf(i)). +              sub(/#{Mx[:lnk_o]}[ ]*#{cont}[ ]*#{Mx[:lnk_c]}#{Mx[:url_o]}#{url}#{Mx[:url_c]}/m,image_odf(i)). +              sub(/\\([)(\]\[?])/,'\1') #clumsy fix +          end +          m=nil +        end +        dob +      end +      def text_link_odf(txt,url,trail) +        txt=txt.gsub(/(\\\+)/,'+') #this is convoluted, and risky :-( +        url=url.gsub(/(\\\+)/,'+') #this is convoluted, and risky :-( +        map_nametags=SiSU_Particulars::CombinedSingleton. +          instance.get_map_nametags(@md).nametags_map +        t=case url +        when /^https?:/ +          %{<text:a xl:type="simple" xl:href="#{url}">#{txt.strip}</text:a>#{trail}} +        when /^:/                 # site same document collection html link +          url=url.gsub(/^:/,"#{@env.url.root}/") +          %{<text:a xl:type="simple" xl:href="#{url}">#{txt.strip}</text:a>#{trail}} +        when /^\.\.\//                 # site same document collection html link +          url=url.gsub(/^\.\.\//,"#{@env.url.root}/") +          %{<text:a xl:type="simple" xl:href="#{url}">#{txt.strip}</text:a>#{trail}} +        else                           # document internal link +          if map_nametags[url] \ +          and map_nametags[url][:segname] +          else p "NOT FOUND name_tags: #{url}" +          end +          t=map_nametags[url] \ +          && map_nametags[url][:segname] \ +          ? (%{<text:a xl:type="simple" xl:href="#{@env.url.root}/#{@md.fnb}/#{map_nametags[url][:segname]}#{Sfx[:html]}##{url}">} \ +            + %{#{txt.strip}</text:a>#{trail}}) +          : %{#{txt.strip}#{trail}} +        end +        t +      end +      def text_link_odf_bookmark(txt,url,trail) +        SiSU_Particulars::CombinedSingleton.instance.get_map_nametags(@md).nametags_map +        %{<text:bookmark-ref text:reference-format="text" text:ref-name="#{url}">#{txt.strip}</text:bookmark-ref>#{trail}} +      end +      def text_link(dob) +        m=dob.obj.scan(/(#{Mx[:lnk_o]}(.+?)#{Mx[:lnk_c]}#{Mx[:url_o]}(\S+?)#{Mx[:url_c]})/) #sort +        if m +          m.each do |i| +            txt,url,trail=i[1],i[2] +            txt=txt.gsub(/([)(\]\[])/,"\\\\\\1"). +              gsub(/([+?*])/,"\\\\\\1") # problems with + +            url=url.gsub(/([+?])/,"\\\\\\1") # problems with + +            dob.obj=dob.obj.gsub(/#{Mx[:lnk_o]}[ ]*#{txt}#{Mx[:lnk_c]}#{Mx[:url_o]}#{url}#{Mx[:url_c]}/m, +                text_link_odf(txt,url,trail)). #make sure trailing ']' are not caught in url +              gsub(/\\([)(\]\[?])/,'\1') #clumsy fix +          end +          m=nil +        end +        dob +      end +      def text_link_relative(dob) +        m=dob.obj.scan(/(#{Mx[:lnk_o]}(.+?)#{Mx[:lnk_c]}#{Mx[:rel_o]}(\S+?)#{Mx[:rel_c]})/) #sort +        if m +          m.each do |i| +            txt,url,trail=i[1],i[2] +            txt=txt.gsub(/([)(\]\[])/,"\\\\\\1"). +              gsub(/([+?*])/,"\\\\\\1") # problems with + +            url=url.gsub(/([+?])/,"\\\\\\1") # problems with + +            dob.obj=dob.obj.gsub(/#{Mx[:lnk_o]}[ ]*#{txt}#{Mx[:lnk_c]}#{Mx[:rel_o]}#{url}#{Mx[:rel_c]}/m, +                text_link_odf_bookmark(txt,url,trail)). #make sure trailing ']' are not caught in url +              gsub(/\\([)(\]\[?])/,'\1') #clumsy fix +          end +          m=nil +        end +        dob +      end +      def text_link_relative_(dob) +        m=dob.obj.scan(/(#{Mx[:lnk_o]}(.+?)#{Mx[:lnk_c]}#{Mx[:rel_o]}(\S+?)#{Mx[:rel_c]})/) #sort +        if m +          m.each do |i| +            txt,url,trail=i[1],i[2] +            txt=txt.gsub(/([)(\]\[])/,"\\\\\\1") +            dob.obj=dob.obj.gsub(/#{Mx[:lnk_o]}[ ]*#{txt}#{Mx[:lnk_c]}#{Mx[:rel_o]}#{url}#{Mx[:rel_c]}/m, +                text_link_odf(txt,url,trail)). #make sure trailing ']' are not caught in url +              gsub(/\\([)(\]\[?])/,'\1') #clumsy fix +          end +          m=nil +        end +        dob +      end +      def normal(dob,p_num)                                                           #P1 - P3 +        dob=footnote(dob) +        dob.obj=dob.obj.gsub(/#{Mx[:url_o]}_(\S+?)#{Mx[:url_c]}/, +            '<text:a xl:type="simple" xl:href="\1">\1</text:a>'). #http ftp matches escaped, no decoration +          gsub(/#{Mx[:url_o]}([a-zA-Z0-9._-]+\@\S+?\.[a-zA-Z0-9._-]+)#{Mx[:url_c]}/, +            %{#{the_url_decoration.xml_open}<text:a xl:type="simple" xl:href="mailto:\\1">\\1</text:a>#{the_url_decoration.xml_close}}). +          gsub(/#{Mx[:url_o]}(\S+?)#{Mx[:url_c]}/, +            %{#{the_url_decoration.xml_open}<text:a xl:type="simple" xl:href="\\1">\\1</text:a>#{the_url_decoration.xml_close}}) #http ftp matches with decoration +        dob.obj= if dob.is==:para \ +        and dob.indent.to_s =~/[0-9]/ \ +        and dob.indent == dob.hang +          %{<text:p text:style-name="P_indent_#{dob.indent}">#{p_num[:set_ref]}#{set_bookmark_tag(dob)}#{dob.obj}#{p_num[:display]}</text:p>} +        elsif dob.is==:para \ +        and dob.hang.to_s =~/[0-9]/ \ +        and dob.indent != dob.hang +          %{<text:p text:style-name="P_h#{dob.hang}_i#{dob.indent}">#{p_num[:set_ref]}#{set_bookmark_tag(dob)}#{dob.obj}#{p_num[:display]}</text:p>} +        else %{<text:p text:style-name="P_normal">#{p_num[:set_ref]}#{set_bookmark_tag(dob)}#{dob.obj}#{p_num[:display]}</text:p>} +        end +        dob +      end +      def fontface(dob) +      end +      def footnote_urls(str) +        str=str.gsub(/#{Mx[:url_o]}(\S+?)#{Mx[:url_c]}/, +          %{#{the_url_decoration.xml_open}<text:a xl:type="simple" xl:href="\\1">\\1</text:a>#{the_url_decoration.xml_close}}) +        str=text_link(str) if str =~/#{Mx[:lnk_o]}.+?#{Mx[:lnk_c]}#{Mx[:url_o]}\S+?#{Mx[:url_c]}/ +        str=text_link_relative(str) if str =~/#{Mx[:lnk_o]}.+?#{Mx[:lnk_c]}#{Mx[:rel_o]}\S+?#{Mx[:rel_c]}/ +        str +      end +      def footnote(t_o) +        str=if defined? t_o.obj then t_o.obj +        elsif t_o.is_a?(String) then t_o +        end +        if str +          @astx||=10000 +          @astxs||=20000 +          if str =~/#{Mx[:en_a_o]}\d+\s+/ +            str=str.gsub(/#{Mx[:en_a_o]}(\d+)\s+(.+?)#{Mx[:en_a_c]}/, +              '<text:note text:id="ftn\1" text:note-class="footnote"><text:note-citation>\1</text:note-citation><text:note-body><text:p text:style-name="Footnote"> \2</text:p><text:p text:style-name="Footnote"/></text:note-body></text:note>') +          end +          if str =~/#{Mx[:en_a_o]}([*]+)\s+/ +            a=$1.gsub(/([*])/,"\\\\\\1") +              str=str.gsub(/#{Mx[:en_a_o]}([*]+)\s+(.+?)#{Mx[:en_a_c]}/, +                %{<text:note text:id="ftn#{@astx.to_s}" text:note-class="footnote"><text:note-citation text:label="\\1">\\1</text:note-citation><text:note-body><text:p text:style-name="Footnote"> \\2</text:p><text:p text:style-name="Footnote"/></text:note-body></text:note>}) +              @astxs+=1 +          end +          if str=~/#{Mx[:en_a_o]}[*+]+\s/ +            asterisk=str.scan(/#{Mx[:en_a_o]}([*+]+)\s+(.+?)#{Mx[:en_a_c]}/) +            asterisk.each do |x| +              a=x[0].gsub(/([*+])/,"\\\\\\1") +              str=group_clean(str) +              str=footnote_urls(str) +              str=str.gsub(/#{Mx[:en_a_o]}(#{a})\s+(.+?)#{Mx[:en_a_c]}/, +                %{<text:note text:id="ftn#{@astx.to_s}" text:note-class="footnote"><text:note-citation text:label="\\1">\\1</text:note-citation><text:note-body><text:p text:style-name="Footnote"> \\2</text:p><text:p text:style-name="Footnote"/></text:note-body></text:note>}) +              @astx+=1 +            end +          end +          if str=~/#{Mx[:en_b_o]}[*+]\d+\s/ +            asterisk=str.scan(/#{Mx[:en_b_o]}([*+]\d+)\s+(.+?)#{Mx[:en_b_c]}/) +            asterisk.each do |x| +              a=x[0].gsub(/([*+])/,"\\\\\\1") +              str=group_clean(str) +              str=footnote_urls(str) +              str=str.gsub(/#{Mx[:en_b_o]}(#{a})\s+(.+?)#{Mx[:en_b_c]}/, +                %{<text:note text:id="ftn#{@astx.to_s}" text:note-class="footnote"><text:note-citation text:label="\\1">\\1</text:note-citation><text:note-body><text:p text:style-name="Footnote"> \\2</text:p><text:p text:style-name="Footnote"/></text:note-body></text:note>}) +              @astx+=1 +            end +          end +        end +        if defined? t_o.obj     then t_o.obj=str +        elsif t_o.is_a?(String) then t_o=str +        end +        t_o +      end +      def group_clean(str) +        str=str.gsub(/&nbsp;| |#{Mx[:nbsp]}/,' '). +          gsub(/</,'<').gsub(/>/,'>'). +          gsub(/<(text:span text:style-name="Span_\S+?"|\/text:span)>/,'<\1>'). #works, not ideal +          gsub(/#{Mx[:br_line]}/,'<br />'). +          gsub(/<br(?:\s+\/)?>/,'<br />') +      end +      def poem(dob,p_num)                                                             #P4 #same as group +        parray=[] +        dob.obj.split(/#{Mx[:br_line]}|#{Mx[:br_nl]}/).each_with_index do |parablock,i| +          set_ref=(i==0) ? "#{p_num[:set_ref]}#{set_bookmark_tag(dob)}" : '' +          parablock=group_clean(parablock) +          parablock=footnote(parablock) +          parray << %{<text:p text:style-name="P_group">#{set_ref}#{parablock}</text:p>} if parablock =~/\S+/ +        end +        dob.obj=parray.join \ +        + %{<text:p text:style-name="P_group">#{p_num[:display]}</text:p>} \ +        + '<text:p text:style-name="Standard"/>' +        dob +      end +      def group(dob,p_num)                                                            #P4 #same as verse +        parray=[] +        dob.obj=dob.obj.gsub(/#{Mx[:url_o]}_(\S+?)#{Mx[:url_c]}/, +            '<text:a xl:type="simple" xl:href="\1">\1</text:a>'). #http ftp matches escaped, no decoration +          gsub(/#{Mx[:url_o]}([a-zA-Z0-9._-]+\@\S+?\.[a-zA-Z0-9._-]+)#{Mx[:url_c]}/, +            %{#{the_url_decoration.xml_open}<text:a xl:type="simple" xl:href="mailto:\\1">\\1</text:a>#{the_url_decoration.xml_close}}). +          gsub(/#{Mx[:url_o]}(\S+?)#{Mx[:url_c]}/, +            %{#{the_url_decoration.xml_open}<text:a xl:type="simple" xl:href="\\1">\\1</text:a>#{the_url_decoration.xml_close}}) #http ftp matches with decoration +        dob.obj.split(/#{Mx[:br_line]}|#{Mx[:br_nl]}/).each_with_index do |parablock,i| +          set_ref=(i==0) ? "#{p_num[:set_ref]}#{set_bookmark_tag(dob)}" : '' +          parablock=group_clean(parablock) +          parablock=parablock.gsub(/<text:a xl:type="simple" xl:href="(.+?)">/m, +              '<text:a xl:type="simple" xl:href="\1">'). +            gsub(/<(\/text:a)>/,'<\1>'). +            gsub(/<(text:note text:id=.+?)>/,'<\1>'). +            gsub(/<(text:p text:style-name="Footnote")>/,'<\1>'). +            gsub(/<(\/?text:(?:note-citation|note-body|note|p))>/,'<\1>') +          parablock=footnote(parablock) +          parray << %{<text:p text:style-name="P_group">#{set_ref}#{parablock}</text:p>} if parablock =~/\S+/ +        end +        dob.obj=parray.join \ +        + %{<text:p text:style-name="P_group">#{p_num[:display]}</text:p>} \ +        + '<text:p text:style-name="Standard"/>' +        dob +      end +      def block(dob,p_num)                                                            #P4 #same as verse +        parray=[] +        dob.obj=dob.obj.gsub(/#{Mx[:url_o]}_(\S+?)#{Mx[:url_c]}/, +            '<text:a xl:type="simple" xl:href="\1">\1</text:a>'). #http ftp matches escaped, no decoration +          gsub(/#{Mx[:url_o]}([a-zA-Z0-9._-]+\@\S+?\.[a-zA-Z0-9._-]+)#{Mx[:url_c]}/, +            %{#{the_url_decoration.xml_open}<text:a xl:type="simple" xl:href="mailto:\\1">\\1</text:a>#{the_url_decoration.xml_close}}). +          gsub(/#{Mx[:url_o]}(\S+?)#{Mx[:url_c]}/, +            %{#{the_url_decoration.xml_open}<text:a xl:type="simple" xl:href="\\1">\\1</text:a>#{the_url_decoration.xml_close}}) #http ftp matches with decoration +        dob.obj.split(/#{Mx[:br_line]}|#{Mx[:br_nl]}/).each_with_index do |parablock,i| +          set_ref=(i==0) ? "#{p_num[:set_ref]}#{set_bookmark_tag(dob)}" : '' +          parablock=group_clean(parablock) +          parablock=parablock.gsub(/<text:a xl:type="simple" xl:href="(.+?)">/m, +              '<text:a xl:type="simple" xl:href="\1">'). +            gsub(/<(\/text:a)>/,'<\1>'). +            gsub(/<(text:note text:id=.+?)>/,'<\1>'). +            gsub(/<(text:p text:style-name="Footnote")>/,'<\1>'). +            gsub(/<(\/?text:(?:note-citation|note-body|note|p))>/,'<\1>') +          parablock=footnote(parablock) +          parray << %{<text:p text:style-name="P_group">#{set_ref}#{parablock}</text:p>} \ +            if parablock =~/\S+/ +        end +        dob.obj=parray.join \ +        + %{<text:p text:style-name="P_group">#{p_num[:display]}</text:p>} \ +        + '<text:p text:style-name="Standard"/>' +        dob +      end +      def code(dob,p_num)                                                             #P5 +        if dob.is==:code +          dob.obj=dob.obj.gsub(/\s\s/,'  ') +          parray=[] +          dob.obj.split(/#{Mx[:br_line]}|#{Mx[:br_nl]}/).each_with_index do |parablock,i| +            set_ref=(i==0) ? "#{p_num[:set_ref]}#{set_bookmark_tag(dob)}" : '' +            parablock=group_clean(parablock) +            parablock=parablock.gsub(/^\s*$/,'<br />'). +              gsub(/#{Mx[:url_o]}_(\S+?)#{Mx[:url_c]}/, +                '<text:a xl:type="simple" xl:href="\1">\1</text:a>') #http ftp matches escaped, no decoration +            parray << %{<text:p text:style-name="P_code">#{set_ref}#{parablock}</text:p>} if parablock =~/\S+/ +          end +          dob.obj=parray.join \ +          + %{<text:p text:style-name="P_group">#{p_num[:display]}</text:p>} \ +          + '<text:p text:style-name="Standard"/>' +        end +        dob +      end +      def table(dob,p_num)                                                            # +        if dob.is ==:table +          dob=footnote(dob) #check +          table=SiSU_XML_ODF_ODT_Format::Table.new(@md,dob,p_num) +          dob=table.table +        end +        dob +      end +      def obj_break(dob) +        if dob.is ==:break +          br=SiSU_XML_ODF_ODT_Format::FormatObjBreak.new(@md,dob) +          if dob.obj==Mx[:br_page] \ +          or dob.obj==Mx[:br_page_new] +            dob=br.br_page +          elsif dob.obj==Mx[:br_page_line] +            dob=br.br_page_line +          elsif dob.obj==Mx[:br_obj] +            dob=br.obj_sep +          end +        end +        dob +      end +      def odf_structure(md,dob) +        @md,@dob=md,dob +        dob=if dob.is !=:code +          dob=image(dob) if dob.obj =~/#{Mx[:lnk_o]}[ ]*\S+?\.(?:png|jpg|gif)\s.+?#{Mx[:lnk_c]}(?:#{Mx[:url_o]}\S+?#{Mx[:url_c]}|image)/ +          dob=text_link(dob) if dob.obj =~/#{Mx[:lnk_o]}.+?#{Mx[:lnk_c]}#{Mx[:url_o]}\S+?#{Mx[:url_c]}/ +          dob=text_link_relative(dob) if dob.obj =~/#{Mx[:lnk_o]}.+?#{Mx[:lnk_c]}#{Mx[:rel_o]}\S+?#{Mx[:rel_c]}/ +          dob +        else dob +        end +        p_num={ display: '', set_ref: '' } +        if dob.is !~/(^#{Rx[:meta]}|#{Mx[:br_eof]}|#{Mx[:br_endnotes]})/ +          if @make.build.odt_ocn? +            if defined? dob.ocn \ +            and dob.ocn.is_a?(Integer) +              p_num=SiSU_XML_ODF_ODT_Format::ParagraphNumber.new(@make,dob.ocn).set_bookmark_and_display +            end +          end +        end +        if dob.is==:heading +          @per.body << heading(dob,p_num).obj << break_line*2 +          if SiSU_Env::ProcessingSettings.new(md).build.toc? +            if dob.lv =~/[A-D1]/i +              @per.toc << toc(dob,p_num).obj +            end +          end +        elsif dob.is ==:verse +          @per.body << poem(dob,p_num).obj << break_line*2 +        elsif dob.is==:group +          @per.body << group(dob,p_num).obj << break_line*2 +        elsif dob.is==:block +          @per.body << block(dob,p_num).obj << break_line*2 +        elsif dob.is==:code +          @per.body << code(dob,p_num).obj << break_line*2 +        elsif dob.is==:table #elsif dob.obj =~ /<!Th?¡/u +          @per.body << table(dob,p_num).obj << break_line*2 +        elsif dob.is==:break +          @per.body << obj_break(dob).obj << break_line*2 +        else +          @per.body << normal(dob,p_num).obj << break_line*2 # main text, contents, body KEEP +        end +        @@endnotes_para=[] +      end +      def tidywords(wordlist) +        wordlist +      end +      def markup(data)                                                                 # Used for major markup instructions +        #safe_characters=/[^a-zA-Z0-9}{\/?,."';:)(><\-_&!@%~#\]\[*=$| \n+`#{Mx[:tc_p]}]/u +        dir=SiSU_Env::InfoEnv.new(@md.fns) +        dir.path.odt_bld +        @data_mod,@endnotes,@level,@cont,@copen,@odf_contents_close=Array.new(6){[]} +        @rcdc=false +        (0..7).each { |x| @cont[x]=@level[x]=false } +        (4..7).each { |x| @odf_contents_close[x]='' } +        odf_tail #($1,$2) +        bullet=image_src('bullet_09.png') +        if bullet +          if FileTest.file?("#{bullet}/bullet_09.png") +            FileUtils::cp("#{bullet}/bullet_09.png","#{@env.processing_path.odt}/Pictures/.") +          else STDERR.puts %{\t*WARN* did not find image - "#{bullet}/bullet_09.png" [#{__FILE__}:#{__LINE__}]} +          end +        end +        odf_book_idx +        odf_metadata +        data.each do |dob| +          #p dob.obj if dob.obj =~safe_characters and @md.opt.selections.str =~/V/ #KEEP +          dob.obj='' if dob.obj =~/#{Mx[:lv_o]}\d+:.*?#{Mx[:lv_c]}.+?#{Mx[:pa_non_object_dummy_heading]}/ #fix Mx[:lv_o] +          para_array=[] +          dob.obj=dob.obj.gsub(/</,'<').gsub(/>/,'>') +          word=dob.obj.scan(/\S+|\n/) +          if word +            word.each do |w| # _ - / # | : ! ^ ~ +              unless dob.obj =~/^(?:#{Rx[:meta]}|%+ )/m +                w=w.gsub(/&#(?:126|152);/,'~'). #126 usual +                  gsub(/ /,' ') +                if w !~/(?:&\S{2,7}?;)+/ +                  w=w.gsub(/&/,'&') +                end +                if w !~/&\S{1,7}?;(?:&\S{1,7}?;)+/    #imperfect +                  w=w.gsub(/(&\S{1,7};)+&/,'\1&') +                end +              end +              para_array << w +            end +            dob.obj=para_array.join(' ') +            dob.obj=dob.obj.strip +          end +          if dob.is==:code #{Mx[:gr_o]}code#{Mx[:gr_c]}/ #fix #code-block: angle brackets special characters #fix +            dob.obj=dob.obj.gsub(/(^|[^}])_(?:<|<)/m,'\1<').gsub(/(^|[^}])_(?:>|>)/m,'\1>'). +              gsub(/(^|[^}])_(?:<|<)/m,'\1<').gsub(/(^|[^}])_(?:>|>)/m,'\1>') +          end +          if dob.of==:block +            dob.obj=dob.obj.gsub(/#{Mx[:gl_bullet]}/,'● ') +          end +          dob.obj=dob.obj.gsub(/#{Mx[:fa_strike_o]}(.+?)#{Mx[:fa_strike_c]}/,'<del>\1</del>'). +            gsub(/#{Mx[:fa_insert_o]}(.+?)#{Mx[:fa_insert_c]}/,'<ins>\1</ins>'). +            gsub(/#{Mx[:fa_cite_o]}(.+?)#{Mx[:fa_cite_c]}/,'<cite>\1</cite>'). +            gsub(/#{Mx[:tag_o]}\S+?#{Mx[:tag_c]}/, +              '<text:bookmark-start text:name="\1"/><text:bookmark-end text:name="\1"/>'). #check +            gsub(/#{Mx[:mk_o]}#([a-zA-Z]+)#{Mx[:mk_c]}/,'&\1;'). +            gsub(/#{Mx[:mk_o]}(#[0-9]+)#{Mx[:mk_c]}/,'&\1;'). +            gsub(/#{Mx[:mk_o]}[~-]##{Mx[:mk_c]}/,'') +          if dob.is==:para \ +          and dob.bullet_ +            dob.obj='<draw:frame draw:style-name="gr1" text:anchor-type="as-char" svg:width="0.22cm" svg:height="0.22cm" draw:z-index="2"><draw:image xl:href="Pictures/bullet_09.png" xl:type="simple" xl:show="embed" xl:actuate="onLoad"/></draw:frame> ' + +              dob.obj +          end +          dob.obj=dob.obj.gsub(/#{Mx[:br_line]}/,'<br />'). +            gsub(/©/,'©'). #too arbitrary +            gsub(/.+?<-#>/,'').                                           # remove dummy headings (used by html) #check +            gsub(/#{Mx[:fa_bold_o]}(.+?)#{Mx[:fa_bold_c]}/, +              '<text:span text:style-name="Span_bold">\1</text:span>'). +            gsub(/#{Mx[:fa_italics_o]}(.+?)#{Mx[:fa_italics_c]}/, +              '<text:span text:style-name="Span_italic">\1</text:span>'). +            gsub(/#{Mx[:fa_underscore_o]}(.+?)#{Mx[:fa_underscore_c]}/, +              '<text:span text:style-name="Span_underscore">\1</text:span>'). +            gsub(/#{Mx[:fa_superscript_o]}(.+?)#{Mx[:fa_superscript_c]}/, +              '<text:span text:style-name="Span_superscript">\1</text:span>'). +            gsub(/#{Mx[:fa_subscript_o]}(.+?)#{Mx[:fa_subscript_c]}/, +              '<text:span text:style-name="Span_subscript">\1</text:span>'). +            gsub(/#{Mx[:fa_monospace_o]}(.+?)#{Mx[:fa_monospace_c]}/, +              '<text:span text:style-name="Span_monospace">\1</text:span>'). +            gsub(//u,'-'). +            gsub(/ /u, ' ').       # space identify +            gsub(/ /u, ' ').       # space identify +            gsub(/·/u,'*'). +            gsub(/[–—]/u,'-').   #— – chk +            gsub(/ < /i,'<'). +            gsub(/\\copy(?:right)?\b/,'©'). +            gsub(/\\trademark\b|\\tm\b/,'®'). +            gsub(/\44/,'$'). #$ watch +            gsub(/<a href=".+?">(.+?)<\/a>/,'\1'). +            gsub(/#{Mx[:mk_o]}name#\S+?#{Mx[:mk_c]}/,'')                                       # remove name links +          wordlist=dob.obj.scan(/\S+/) +          dob.obj=tidywords(wordlist).join(' ').strip +          @rcdc=true if @rcdc==false \ +          and (dob.obj =~/~metadata/ \ +          or dob.obj =~/#{Mx[:lv_o]}1:meta#{Mx[:lv_x]}\s*Document Information/) #fix Mx[:lv_o] +          if dob.is !~/(^#{Rx[:meta]}|#{Mx[:br_eof]}|#{Mx[:br_endnotes]})/ #check +            if defined? dob.ocn and dob.ocn.to_s =~/\d+/ +              @p_num=SiSU_XML_ODF_ODT_Format::ParagraphNumber.new(@make,dob.ocn) +            end +            if dob.is ==:heading \ +            || dob.is ==:para \ +            || dob.is ==:group \ +            || dob.is ==:verse \ +            || dob.is ==:code \ +            || dob.is ==:table \ +            || dob.is ==:break +              odf_structure(@md,dob) +            end +            if dob.obj ## Clean Prepared Text +              dob.obj=dob.obj.gsub(/<!.+!>/,' '). +                gsub(/#{Mx[:tc_o]}.+?#{Mx[:tc_c]}/,' '). +                gsub(/<:\S+>/,' ') +            end +          end +        end +      end +      def pre +        table=if @md.flag_tables +          x=<<WOK +  <style:style style:name="Table1" style:family="table"><style:table-properties style:width="16.999cm" table:align="margins"/></style:style> +  <style:style style:name="Table1.A" style:family="table-column"><style:table-column-properties style:column-width="16.999cm" style:rel-column-width="65535*"/></style:style> +  <style:style style:name="Table1.B" style:family="table-column"><style:table-column-properties style:column-width="8.499cm" style:rel-column-width="32767*"/></style:style> +  <style:style style:name="Table1.C" style:family="table-column"><style:table-column-properties style:column-width="5.666cm" style:rel-column-width="21845*"/></style:style> +  <style:style style:name="Table1.D" style:family="table-column"><style:table-column-properties style:column-width="4.349cm" style:rel-column-width="16383*"/></style:style> +  <style:style style:name="Table1.E" style:family="table-column"><style:table-column-properties style:column-width="3.399cm" style:rel-column-width="13107*"/></style:style> +  <style:style style:name="Table1.F" style:family="table-column"><style:table-column-properties style:column-width="2.833cm" style:rel-column-width="10922*"/></style:style> +  <style:style style:name="Table1.G" style:family="table-column"><style:table-column-properties style:column-width="2.428cm" style:rel-column-width="9362*"/></style:style> +  <style:style style:name="Table1.H" style:family="table-column"><style:table-column-properties style:column-width="2.124cm" style:rel-column-width="8191*"/></style:style> +  <style:style style:name="Table2" style:family="table"><style:table-properties style:width="16.999cm" table:align="margins"/></style:style> +  <style:style style:name="Table2.A" style:family="table-column"><style:table-column-properties style:column-width="16.999cm" style:rel-column-width="65535*"/></style:style> +  <style:style style:name="Table2.B" style:family="table-column"><style:table-column-properties style:column-width="8.499cm" style:rel-column-width="32767*"/></style:style> +  <style:style style:name="Table2.C" style:family="table-column"><style:table-column-properties style:column-width="5.666cm" style:rel-column-width="21845*"/></style:style> +  <style:style style:name="Table2.D" style:family="table-column"><style:table-column-properties style:column-width="4.349cm" style:rel-column-width="16383*"/></style:style> +  <style:style style:name="Table2.E" style:family="table-column"><style:table-column-properties style:column-width="3.999cm" style:rel-column-width="13107*"/></style:style> +  <style:style style:name="Table2.F" style:family="table-column"><style:table-column-properties style:column-width="2.833cm" style:rel-column-width="10922*"/></style:style> +  <style:style style:name="Table2.G" style:family="table-column"><style:table-column-properties style:column-width="2.428cm" style:rel-column-width="9362*"/></style:style> +  <style:style style:name="Table2.H" style:family="table-column"><style:table-column-properties style:column-width="2.124cm" style:rel-column-width="8191*"/></style:style> +  <style:style style:name="Table2.I" style:family="table-column"><style:table-column-properties style:column-width="1.8887cm" style:rel-column-width="7281*"/></style:style> +  <style:style style:name="Table2.J" style:family="table-column"><style:table-column-properties style:column-width="1.6999cm" style:rel-column-width="6553*"/></style:style> +  <style:style style:name="Table2.K" style:family="table-column"><style:table-column-properties style:column-width="1.5453cm" style:rel-column-width="5957*"/></style:style> +  <style:style style:name="Table2.L" style:family="table-column"><style:table-column-properties style:column-width="1.416cm" style:rel-column-width="5461*"/></style:style> +  <style:style style:name="Table2.M" style:family="table-column"><style:table-column-properties style:column-width="1.307" style:rel-column-width="5041*"/></style:style> +  <style:style style:name="Table2.N" style:family="table-column"><style:table-column-properties style:column-width="1.214cm" style:rel-column-width="4681*"/></style:style> +WOK +          x=x.strip +          x=x.gsub(/\n+/m,'') unless @md.opt.act[:maintenance][:set]==:on +          x +        else '' +        end +        x=<<WOK +<?xml version="1.0" encoding="UTF-8"?> +<office:document-content xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0" xmlns:style="urn:oasis:names:tc:opendocument:xmlns:style:1.0" xmlns:text="urn:oasis:names:tc:opendocument:xmlns:text:1.0" xmlns:table="urn:oasis:names:tc:opendocument:xmlns:table:1.0" xmlns:draw="urn:oasis:names:tc:opendocument:xmlns:drawing:1.0" xmlns:fo="urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0" xmlns:xl="http://www.w3.org/1999/xlink" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:meta="urn:oasis:names:tc:opendocument:xmlns:meta:1.0" xmlns:number="urn:oasis:names:tc:opendocument:xmlns:datastyle:1.0" xmlns:svg="urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0" xmlns:chart="urn:oasis:names:tc:opendocument:xmlns:chart:1.0" xmlns:dr3d="urn:oasis:names:tc:opendocument:xmlns:dr3d:1.0" xmlns:math="http://www.w3.org/1998/Math/MathML" xmlns:form="urn:oasis:names:tc:opendocument:xmlns:form:1.0" xmlns:script="urn:oasis:names:tc:opendocument:xmlns:script:1.0" xmlns:ooo="http://openoffice.org/2004/office" xmlns:ooow="http://openoffice.org/2004/writer" xmlns:oooc="http://openoffice.org/2004/calc" xmlns:dom="http://www.w3.org/2001/xml-events" xmlns:xforms="http://www.w3.org/2002/xforms" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:rpt="http://openoffice.org/2005/report" xmlns:of="urn:oasis:names:tc:opendocument:xmlns:of:1.2" xmlns:xhtml="http://www.w3.org/1999/xhtml" xmlns:grddl="http://www.w3.org/2003/g/data-view#" xmlns:tableooo="http://openoffice.org/2009/table" xmlns:field="urn:openoffice:names:experimental:ooo-ms-interop:xmlns:field:1.0" xmlns:formx="urn:openoffice:names:experimental:ooxml-odf-interop:xmlns:form:1.0" xmlns:css3t="http://www.w3.org/TR/css3-text/" office:version="1.2"><office:scripts/> +<office:font-face-decls><style:font-face style:name="DejaVu Sans Mono" svg:font-family="'DejaVu Sans Mono'" style:font-adornments="Book" style:font-family-generic="modern" style:font-pitch="fixed"/><style:font-face style:name="Inconsolata" svg:font-family="Inconsolata" style:font-adornments="Regular" style:font-pitch="fixed"/><style:font-face style:name="Liberation Mono" svg:font-family="'Liberation Mono'" style:font-adornments="Regular" style:font-family-generic="modern" style:font-pitch="fixed"/><style:font-face style:name="DejaVu Sans" svg:font-family="'DejaVu Sans'" style:font-adornments="ExtraLight" style:font-family-generic="swiss" style:font-pitch="variable"/><style:font-face style:name="Nimbus Sans L" svg:font-family="'Nimbus Sans L'" style:font-pitch="variable"/><style:font-face style:name="Tahoma" svg:font-family="Tahoma, Lucidasans, 'Lucida Sans', 'Arial Unicode MS'" style:font-pitch="variable"/><style:font-face style:name="Nimbus Roman No9 L" svg:font-family="'Nimbus Roman No9 L'" style:font-family-generic="roman" style:font-pitch="variable"/><style:font-face style:name="Bitstream Vera Sans" svg:font-family="'Bitstream Vera Sans'" style:font-family-generic="swiss" style:font-pitch="variable"/></office:font-face-decls> +<office:automatic-styles> +#{table} +  <style:style style:name="P_table_cell" style:family="paragraph" style:parent-style-name="Table_Contents"><style:paragraph-properties fo:text-align="justify" style:justify-single-word="false"/></style:style> +</office:automatic-styles> +<office:body> +  <office:text text:use-soft-page-breaks="true"> +    <office:forms form:automatic-focus="false" form:apply-design-mode="false"/> +    <text:sequence-decls><text:sequence-decl text:display-outline-level="0" text:name="Illustration"/><text:sequence-decl text:display-outline-level="0" text:name="Table"/><text:sequence-decl text:display-outline-level="0" text:name="Text"/><text:sequence-decl text:display-outline-level="0" text:name="Drawing"/></text:sequence-decls> +WOK +        x=x.strip +        x=x.gsub(/\n+/m,'') unless @md.opt.act[:maintenance][:set]==:on +        @per.head << x +      end +      def publish +        content=[] +        br_pg='<text:p text:style-name="P_normal_page_new"> </text:p>' +        content << +          @per.head << +          @per.toc << +          br_pg << +          @per.body << +          @per.book_idx << +          br_pg << +          @per.metadata << +          @per.tail +        SiSU_XML_ODF_ODT::Source::Output.new(content,@md,@env).odf +        @@odf={ head: [], toc: [], body: [], tail: [], book_idx: [], metadata: [] } +      end +    end +    class Output <Source +      def initialize(content,md,env) +        @content,@md,@env=content,md,env +      end +      def odf                                                           #%odf output +        env=SiSU_Env::FileOp.new(@md) +        env.mkdir +        header=SiSU_XML_ODF_ODT_Format::ODT_Head_1_2.new(@md) +        filename="#{@env.processing_path.odt}/manifest.rdf" +        od=File.new(filename,'w+') +        od << header.manifest_rdf +        od.close +        filename="#{@env.processing_path.odt}/META-INF/manifest.xml" +        od=File.new(filename,'w+') +        od << header.meta_inf_manifest_xml(@md) +        od.close +        filename="#{@env.processing_path.odt}/meta.xml" +        od=File.new(filename,'w+') +        od << header.meta_xml +        od.close +        filename="#{@env.processing_path.odt}/settings.xml" +        od=File.new(filename,'w+') +        od << header.settings_xml +        od.close +        filename="#{@env.processing_path.odt}/styles.xml" +        od=File.new(filename,'w+') +        od << header.styles_xml +        od.close +        filename="#{@env.processing_path.odt}/mimetype" +        od=File.new(filename,'w+') +        od << header.mimetype +        od.close +        env.make_path(@env.processing_path.odt) +        env.make_path(@md.file.output_path.odt.dir) +        filename="#{@env.processing_path.odt}/content.xml" +        od=File.new(filename,'w+') +        @content.flatten.compact.each do |para|             # this is a hack, check change does not alter behavior +          od.puts para unless para =~/\A\s*\Z/ +        end +        od.close +        opendoc=@md.file.base_filename.odt #watch where output by language +        FileUtils::mkdir_p(@md.file.output_path.odt.dir) \ +          unless FileTest.directory?(@md.file.output_path.odt.dir) +        if FileTest.directory?(@env.processing_path.odt) \ +        and SiSU_Env::SystemCall.new.zip +          pwd=Dir.pwd +          Dir.chdir(@env.processing_path.odt) +          system(" +            zip -qr #{opendoc} * +          ") +          FileUtils::mv(opendoc, @md.file.place_file.odt.dir) +          Dir.chdir(pwd) +        else +          SiSU_Utils::CodeMarker.new(__LINE__,__FILE__,:fuchsia).mark('*EXITED odf* zip program not found') unless SiSU_Env::SystemCall.new.zip +        end +      end +    end +  end +end +__END__ +#+END_SRC + +** xml_odf_odt_format.rb + +#+BEGIN_SRC ruby  :tangle "../lib/sisu/xml_odf_odt_format.rb" +# <<sisu_document_header>> +module SiSU_XML_ODF_ODT_Format +  require_relative 'dp'                                 # dp.rb +    include SiSU_Param +  class ParagraphNumber +    def initialize(make,paranum) +      @make=make +      @paranum=/(\d+)/m.match(paranum.to_s)[1] +    end +    def set_ref_and_display +      set_ref=@paranum.gsub(/(\d+)/, +        ' <text:span text:style-name="Span_subscript"><text:reference-mark-start text:name="\1"/><text:reference-mark-end text:name="\1"/></text:span>') +      disp=@paranum.gsub(/(\d+)/, +        (@make.build.odt_ocn?) \ +        ? %{ <text:span text:style-name="Span_subscript">#{Dx[:ocn_o]}\\1#{Dx[:ocn_c]}</text:span>} +        : '') +      { display: disp, set_ref: set_ref } +    end +    def set_bookmark_and_display +      set_ref=@paranum.gsub(/(\d+)/, +        ' <text:span text:style-name="Span_subscript"><text:bookmark-start text:name="\1"/><text:bookmark-end text:name="\1"/></text:span>') +      disp=@paranum.gsub(/(\d+)/, +        (@make.build.odt_ocn?) \ +        ? %{ <text:span text:style-name="Span_subscript">#{Dx[:ocn_o]}\\1#{Dx[:ocn_c]}</text:span>} +        : '') +      { display: disp, set_ref: set_ref } +    end +    def name +      @paranum.gsub(/(\d+)/,'<a name="\1"></a>') +    end +    def goto +      @paranum.gsub(/(\d+)/,'<a href="#\1">') +    end +  end +  class FormatBookIndex +    def initialize(idx_str) +      @idx_str=idx_str +    end +    def book_idx_bookmark +      map_nametags=SiSU_Particulars::CombinedSingleton.instance.get_map_nametags(@md).nametags_map #p map_nametags +      rgx_bookmark=/#{Mx[:lnk_o]}.+?#{Mx[:lnk_c]}#{Mx[:rel_o]}#?\S+?#{Mx[:rel_c]}/m +      while @idx_str =~/#{Mx[:lnk_o]}([^#{Mx[:lnk_o]}#{Mx[:lnk_c]}]+)#{Mx[:lnk_c]}#{Mx[:rel_o]}#?(\S+?)#{Mx[:rel_c]}/m +        link,url=$1,$2 +        link,url=link.strip,url.strip +        @idx_str=@idx_str.gsub(/&/m,"&") +        ocn_lnk=if map_nametags[url] \ +        and map_nametags[url][:ocn] +          map_nametags[url][:ocn] +        else nil +        end +        ocn_lnk=(url=~/^\d+$/ ? url : ocn_lnk) +        if ocn_lnk and not ocn_lnk.empty? +          @idx_str=@idx_str.sub(/#{Mx[:fa_bold_o]}(.+?)#{Mx[:fa_bold_c]}/, +              '<text:span text:style-name="Span_bold">\1</text:span>'). +            sub(rgx_bookmark, +              %{<text:bookmark-ref text:reference-format="text" text:ref-name="#{url}">#{link.strip}</text:bookmark-ref>}) +        else +          puts %{name tag: "#{url}" not found} +          @idx_str.sub!(rgx_bookmark,"#{link}") +        end +      end +      @idx_str=@idx_str.gsub(/#{Xx[:protect]}/m,''). +        sub(/,\s*$/m,''). +        gsub(/\n/,'') +      @idx_str='<text:p text:style-name="P_normal">' + @idx_str + '</text:p>' +    end +  end +  class Tags +    def set_bookmark_tag(dob) +      tags='' +      if dob.tags.length > 0 +        dob.tags.each do |tag| +          tags +=%{ <text:span text:style-name="Span_subscript"><text:bookmark-start text:name="#{tag}"/><text:bookmark-end text:name="#{tag}"/></text:span>} +        end +      end +      tags +    end +  end +  class FormatTextObject +    def initialize(md,t_o) +      @md,@t_o=md,t_o +      if t_o.is_a?(Hash) +        @txt =t_o[:txt]            || nil +      else +        p t_o.class +        p caller +      end +      rgx=/#{Mx[:en_a_o]}\d+\s+(.+?)#{Mx[:en_a_c]}/ +      @txt=@txt.gsub(rgx,'\1') if @txt =~rgx +    end +    def scr_endnote_body +      "<endnote>#{@txt}</endnote> " +    end +    def heading_body1 +    end +    def heading_body2 +    end +    def heading_body3 +    end +    def heading_body4 +    end +    def heading_body5 +    end +    def heading_body6 +    end +    def heading_body7 +    end +  end +  class Table +    @@table_counter=0 +    @@tablefoot=[] #watch +    @@fns='' +    def initialize(md,dob,p_num) +      @md,@dob,@p_num=md,dob,p_num +      @txt=dob.obj +      if @md.fns != @@fns +        @@table_counter=0 +        @@fns=@md.fns +      end +    end +    def break_line +      (@md.opt.act[:maintenance][:set]==:on) \ +      ? "\n" : '' +    end +    def table_head_open(count) +      type=(@dob.head_) \ +      ? 1 +      : 2 +      alpha=case @dob.cols +      when  1 then 'A' +      when  2 then 'B' +      when  3 then 'C' +      when  4 then 'D' +      when  5 then 'E' +      when  6 then 'F' +      when  7 then 'G' +      when  8 then 'H' +      when  9 then 'I' +      when 10 then 'J' +      when 11 then 'K' +      when 12 then 'L' +      when 13 then 'M' +      when 14 then 'N' +      else         'D' +      end +      tag=SiSU_XML_ODF_ODT_Format::Tags.new.set_bookmark_tag(@dob) +      %{<table:table table:name="Table#{count}" table:style-name="Table#{type}">#{@p_num[:set_ref]}#{tag}#{break_line}} + +      %{<table:table-column table:style-name="Table#{type}.#{alpha}" table:number-columns-repeated="#{@dob.cols}"/>#{break_line}} +    end +    def table_close(tablefoot='') +      '</table:table>' \ +      + %{<text:p text:style-name="P_group">#{@p_num[:display]}</text:p>} +    end +    def table_tag_cell(str,i) +      txt_name_cell=if i==0 \ +      and @dob.head_ +        'Table_Heading' +      else 'P_table_cell' +      end +      str=str.gsub(/^~$/,'') # tilde / empty cell +      %{<table:table-cell office:value-type="string">#{break_line}} + +      %{<text:p text:style-name="#{txt_name_cell}">#{break_line}} + +      %{#{str}} + +      %{</text:p>#{break_line}} + +      %{</table:table-cell>#{break_line}} +    end +    def table_tag_row(str,i) +      %{<table:table-row>#{break_line}} + +      %{#{str}} + +      %{</table:table-row>#{break_line}} +    end +    def table_tag_row_dump(str,i) +      txt_name_row=if i==0 \ +      and @dob.head_ +        'Table_Heading' +      else 'P_table_cell' +      end +      %{<table:table-row>#{break_line}} + +      %{<table:table-cell office:value-type="string">#{break_line}} + +      %{<text:p text:style-name="#{txt_name_row}">#{break_line}} + +      %{#{str}} + +      %{</text:p>#{break_line}} + +      %{</table:table-cell>#{break_line}} + +      %{</table:table-row>#{break_line}} +    end +    def table_row(row,i) +      row='' if row =~/^<!$/ +      m=row[/<!f(.+?)!>/,1] +      @@tablefoot << m if m +      row=row.gsub(/<!f.+?!>/,'') +      @cells=[] +      row.split(/\s*#{Mx[:tc_p]}/).each do |cell| +        @cells << table_tag_cell(cell,i) +      end +      row=@cells.join +      row=table_tag_row(row,i) +      row +    end +    def table +      @@table_counter+=1 +      table_head_open(@@table_counter) +      @table=[] +      @dob.obj.split(/\s*#{Mx[:tc_c]}/).each_with_index do |r,i| +        @table << table_row(r,i) +      end +      @dob.obj= table_head_open(@@table_counter) + @table.join + table_close +      @dob +    end +  end +  class ODT_Head_1_2 +    def initialize(md) +      @md=md +      @generator="#{@md.project_details.project} #{@md.project_details.version} #{@md.project_details.date_stamp} (#{@md.project_details.date})" +    end +    def manifest_rdf +      x=<<WOK +<?xml version="1.0" encoding="utf-8"?> +<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"> +  <rdf:Description rdf:about="styles.xml"> +    <rdf:type rdf:resource="http://docs.oasis-open.org/ns/office/1.2/meta/odf#StylesFile"/> +  </rdf:Description> +  <rdf:Description rdf:about=""> +    <ns0:hasPart xmlns:ns0="http://docs.oasis-open.org/ns/office/1.2/meta/pkg#" rdf:resource="styles.xml"/> +  </rdf:Description> +  <rdf:Description rdf:about="content.xml"> +    <rdf:type rdf:resource="http://docs.oasis-open.org/ns/office/1.2/meta/odf#ContentFile"/> +  </rdf:Description> +  <rdf:Description rdf:about=""> +    <ns0:hasPart xmlns:ns0="http://docs.oasis-open.org/ns/office/1.2/meta/pkg#" rdf:resource="content.xml"/> +  </rdf:Description> +  <rdf:Description rdf:about=""> +    <rdf:type rdf:resource="http://docs.oasis-open.org/ns/office/1.2/meta/pkg#Document"/> +  </rdf:Description> +</rdf:RDF> +WOK +      x=x.strip +      x=x.gsub(/\n+/m,'') unless @md.opt.act[:maintenance][:set]==:on +      x +    end +    def meta_inf_manifest_xml(md) +      images=['  <manifest:file-entry manifest:media-type="" manifest:full-path="Pictures/bullet_09.png"/>'] +      if md.ec[:image].length > 0 +        md.ec[:image].each do |i| +          images<<<<WOK +  <manifest:file-entry manifest:media-type="" manifest:full-path="Pictures/#{i}"/> +WOK +        end +      end +      images=images.join('') +      x=<<WOK +<?xml version="1.0" encoding="UTF-8"?> +<manifest:manifest xmlns:manifest="urn:oasis:names:tc:opendocument:xmlns:manifest:1.0" manifest:version="1.2"> +  <manifest:file-entry manifest:media-type="application/vnd.oasis.opendocument.text" manifest:version="1.2" manifest:full-path="/"/> +  <manifest:file-entry manifest:media-type="text/xml" manifest:full-path="styles.xml"/> +  <manifest:file-entry manifest:media-type="text/xml" manifest:full-path="content.xml"/> +  #{images} +  <manifest:file-entry manifest:media-type="text/xml" manifest:full-path="meta.xml"/> +  <manifest:file-entry manifest:media-type="application/rdf+xml" manifest:full-path="manifest.rdf"/> +  <manifest:file-entry manifest:media-type="image/png" manifest:full-path="Thumbnails/thumbnail.png"/> +  <manifest:file-entry manifest:media-type="application/binary" manifest:full-path="layout-cache"/> +  <manifest:file-entry manifest:media-type="text/xml" manifest:full-path="settings.xml"/> +  <manifest:file-entry manifest:media-type="" manifest:full-path="Configurations2/accelerator/current.xml"/> +  <manifest:file-entry manifest:media-type="application/vnd.sun.xml.ui.configuration" manifest:full-path="Configurations2/"/> +</manifest:manifest> +WOK +      x=x.strip +      x=x.gsub(/\n+/m,'') unless @md.opt.act[:maintenance][:set]==:on +      x +    end +    def meta_xml +      x=<<WOK +<?xml version="1.0" encoding="UTF-8"?> +<office:document-meta xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0" xmlns:xl="http://www.w3.org/1999/xlink" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:meta="urn:oasis:names:tc:opendocument:xmlns:meta:1.0" xmlns:ooo="http://openoffice.org/2004/office" xmlns:grddl="http://www.w3.org/2003/g/data-view#" office:version="1.2"> +  <office:meta> +    <meta:generator>#{@generator}</meta:generator> +    <meta:creation-date>#{@md.generated}</meta:creation-date> +    <dc:date>#{@md.generated}</dc:date> +    <dc:language>en-US</dc:language> +  </office:meta> +</office:document-meta> +WOK +      x=x.strip +      x=x.gsub(/\n+/m,'') unless @md.opt.act[:maintenance][:set]==:on +      x +    end +    def settings_xml +      x=<<WOK +<?xml version="1.0" encoding="UTF-8"?> +<office:document-settings xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0" xmlns:xl="http://www.w3.org/1999/xlink" xmlns:config="urn:oasis:names:tc:opendocument:xmlns:config:1.0" xmlns:ooo="http://openoffice.org/2004/office" office:version="1.2"> +  <office:settings> +    <config:config-item-set config:name="ooo:view-settings"> +      <config:config-item config:name="ViewAreaTop" config:type="int">0</config:config-item> +      <config:config-item config:name="ViewAreaLeft" config:type="int">0</config:config-item> +      <config:config-item config:name="ViewAreaWidth" config:type="int">0</config:config-item> +      <config:config-item config:name="ViewAreaHeight" config:type="int">0</config:config-item> +      <config:config-item config:name="ShowRedlineChanges" config:type="boolean">true</config:config-item> +      <config:config-item config:name="InBrowseMode" config:type="boolean">false</config:config-item> +      <config:config-item-map-indexed config:name="Views"> +        <config:config-item-map-entry> +          <config:config-item config:name="ViewId" config:type="string">view2</config:config-item> +          <config:config-item config:name="ViewLeft" config:type="int">0</config:config-item> +          <config:config-item config:name="ViewTop" config:type="int">0</config:config-item> +          <config:config-item config:name="VisibleLeft" config:type="int">0</config:config-item> +          <config:config-item config:name="VisibleTop" config:type="int">0</config:config-item> +          <config:config-item config:name="VisibleRight" config:type="int">0</config:config-item> +          <config:config-item config:name="VisibleBottom" config:type="int">0</config:config-item> +          <config:config-item config:name="ZoomType" config:type="short">0</config:config-item> +          <config:config-item config:name="ViewLayoutColumns" config:type="short">2</config:config-item> +          <config:config-item config:name="ViewLayoutBookMode" config:type="boolean">true</config:config-item> +          <config:config-item config:name="ZoomFactor" config:type="short">100</config:config-item> +          <config:config-item config:name="IsSelectedFrame" config:type="boolean">false</config:config-item> +        </config:config-item-map-entry> +      </config:config-item-map-indexed> +    </config:config-item-set> +    <config:config-item-set config:name="ooo:configuration-settings"> +      <config:config-item config:name="ChartAutoUpdate" config:type="boolean">true</config:config-item> +      <config:config-item config:name="IsLabelDocument" config:type="boolean">false</config:config-item> +      <config:config-item config:name="MathBaselineAlignment" config:type="boolean">false</config:config-item> +      <config:config-item config:name="OutlineLevelYieldsNumbering" config:type="boolean">true</config:config-item> +      <config:config-item config:name="PrintLeftPages" config:type="boolean">true</config:config-item> +      <config:config-item config:name="DoNotJustifyLinesWithManualBreak" config:type="boolean">false</config:config-item> +      <config:config-item config:name="AlignTabStopPosition" config:type="boolean">true</config:config-item> +      <config:config-item config:name="PrintTextPlaceholder" config:type="boolean">false</config:config-item> +      <config:config-item config:name="UseOldNumbering" config:type="boolean">false</config:config-item> +      <config:config-item config:name="CurrentDatabaseCommand" config:type="string"/> +      <config:config-item config:name="ProtectForm" config:type="boolean">false</config:config-item> +      <config:config-item config:name="PrintBlackFonts" config:type="boolean">false</config:config-item> +      <config:config-item config:name="PrintProspectRTL" config:type="boolean">false</config:config-item> +      <config:config-item config:name="SmallCapsPercentage66" config:type="boolean">true</config:config-item> +      <config:config-item config:name="PrintControls" config:type="boolean">true</config:config-item> +      <config:config-item config:name="CharacterCompressionType" config:type="short">0</config:config-item> +      <config:config-item config:name="PrintHiddenText" config:type="boolean">false</config:config-item> +      <config:config-item config:name="UseFormerTextWrapping" config:type="boolean">false</config:config-item> +      <config:config-item config:name="IsKernAsianPunctuation" config:type="boolean">false</config:config-item> +      <config:config-item config:name="PrintProspect" config:type="boolean">false</config:config-item> +      <config:config-item config:name="PrintEmptyPages" config:type="boolean">true</config:config-item> +      <config:config-item config:name="UseFormerObjectPositioning" config:type="boolean">false</config:config-item> +      <config:config-item config:name="ConsiderTextWrapOnObjPos" config:type="boolean">false</config:config-item> +      <config:config-item config:name="TableRowKeep" config:type="boolean">false</config:config-item> +      <config:config-item config:name="PrintReversed" config:type="boolean">false</config:config-item> +      <config:config-item config:name="TabsRelativeToIndent" config:type="boolean">true</config:config-item> +      <config:config-item config:name="PrintRightPages" config:type="boolean">true</config:config-item> +      <config:config-item config:name="PrintPaperFromSetup" config:type="boolean">false</config:config-item> +      <config:config-item config:name="AddFrameOffsets" config:type="boolean">false</config:config-item> +      <config:config-item config:name="AddParaSpacingToTableCells" config:type="boolean">true</config:config-item> +      <config:config-item config:name="UpdateFromTemplate" config:type="boolean">false</config:config-item> +      <config:config-item config:name="AddExternalLeading" config:type="boolean">true</config:config-item> +      <config:config-item config:name="PrintSingleJobs" config:type="boolean">false</config:config-item> +      <config:config-item config:name="PrinterIndependentLayout" config:type="string">high-resolution</config:config-item> +      <config:config-item config:name="LinkUpdateMode" config:type="short">1</config:config-item> +      <config:config-item config:name="PrintAnnotationMode" config:type="short">0</config:config-item> +      <config:config-item config:name="UseOldPrinterMetrics" config:type="boolean">true</config:config-item> +      <config:config-item config:name="RedlineProtectionKey" config:type="base64Binary"/> +      <config:config-item config:name="PrinterSetup" config:type="base64Binary"/> +      <config:config-item config:name="IgnoreFirstLineIndentInNumbering" config:type="boolean">false</config:config-item> +      <config:config-item config:name="CollapseEmptyCellPara" config:type="boolean">true</config:config-item> +      <config:config-item config:name="PrinterName" config:type="string"/> +      <config:config-item config:name="InvertBorderSpacing" config:type="boolean">false</config:config-item> +      <config:config-item config:name="PrintPageBackground" config:type="boolean">true</config:config-item> +      <config:config-item config:name="DoNotCaptureDrawObjsOnPage" config:type="boolean">false</config:config-item> +      <config:config-item config:name="ApplyUserData" config:type="boolean">true</config:config-item> +      <config:config-item config:name="TabAtLeftIndentForParagraphsInList" config:type="boolean">false</config:config-item> +      <config:config-item config:name="UnxForceZeroExtLeading" config:type="boolean">true</config:config-item> +      <config:config-item config:name="SaveVersionOnClose" config:type="boolean">false</config:config-item> +      <config:config-item config:name="PrintFaxName" config:type="string"/> +      <config:config-item config:name="AddParaTableSpacing" config:type="boolean">true</config:config-item> +      <config:config-item config:name="PrintDrawings" config:type="boolean">true</config:config-item> +      <config:config-item config:name="LoadReadonly" config:type="boolean">false</config:config-item> +      <config:config-item config:name="PrintGraphics" config:type="boolean">true</config:config-item> +      <config:config-item config:name="FieldAutoUpdate" config:type="boolean">true</config:config-item> +      <config:config-item config:name="AllowPrintJobCancel" config:type="boolean">true</config:config-item> +      <config:config-item config:name="UseFormerLineSpacing" config:type="boolean">false</config:config-item> +      <config:config-item config:name="SaveGlobalDocumentLinks" config:type="boolean">false</config:config-item> +      <config:config-item config:name="CurrentDatabaseDataSource" config:type="string"/> +      <config:config-item config:name="IgnoreTabsAndBlanksForLineCalculation" config:type="boolean">false</config:config-item> +      <config:config-item config:name="CurrentDatabaseCommandType" config:type="int">0</config:config-item> +      <config:config-item config:name="DoNotResetParaAttrsForNumFont" config:type="boolean">false</config:config-item> +      <config:config-item config:name="ClipAsCharacterAnchoredWriterFlyFrames" config:type="boolean">false</config:config-item> +      <config:config-item config:name="PrintTables" config:type="boolean">true</config:config-item> +      <config:config-item config:name="AddParaTableSpacingAtStart" config:type="boolean">true</config:config-item> +    </config:config-item-set> +  </office:settings> +</office:document-settings> +WOK +      x=x.strip +      x=x.gsub(/\n+/m,'') unless @md.opt.act[:maintenance][:set]==:on +      x +    end +    def styles_xml +      x=<<WOK +<?xml version="1.0" encoding="UTF-8"?> +<office:document-styles xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0" xmlns:style="urn:oasis:names:tc:opendocument:xmlns:style:1.0" xmlns:text="urn:oasis:names:tc:opendocument:xmlns:text:1.0" xmlns:table="urn:oasis:names:tc:opendocument:xmlns:table:1.0" xmlns:draw="urn:oasis:names:tc:opendocument:xmlns:drawing:1.0" xmlns:fo="urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0" xmlns:xl="http://www.w3.org/1999/xlink" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:meta="urn:oasis:names:tc:opendocument:xmlns:meta:1.0" xmlns:number="urn:oasis:names:tc:opendocument:xmlns:datastyle:1.0" xmlns:svg="urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0" xmlns:chart="urn:oasis:names:tc:opendocument:xmlns:chart:1.0" xmlns:dr3d="urn:oasis:names:tc:opendocument:xmlns:dr3d:1.0" xmlns:math="http://www.w3.org/1998/Math/MathML" xmlns:form="urn:oasis:names:tc:opendocument:xmlns:form:1.0" xmlns:script="urn:oasis:names:tc:opendocument:xmlns:script:1.0" xmlns:ooo="http://openoffice.org/2004/office" xmlns:ooow="http://openoffice.org/2004/writer" xmlns:oooc="http://openoffice.org/2004/calc" xmlns:dom="http://www.w3.org/2001/xml-events" xmlns:rpt="http://openoffice.org/2005/report" xmlns:of="urn:oasis:names:tc:opendocument:xmlns:of:1.2" xmlns:xhtml="http://www.w3.org/1999/xhtml" xmlns:grddl="http://www.w3.org/2003/g/data-view#" xmlns:tableooo="http://openoffice.org/2009/table" xmlns:css3t="http://www.w3.org/TR/css3-text/" office:version="1.2"> +  <office:font-face-decls> +    <style:font-face style:name="DejaVu Sans Mono" svg:font-family="'DejaVu Sans Mono'" style:font-adornments="Book" style:font-family-generic="modern" style:font-pitch="fixed"/> +    <style:font-face style:name="Nimbus Sans L" svg:font-family="'Nimbus Sans L'" style:font-pitch="variable"/> +    <style:font-face style:name="Tahoma" svg:font-family="Tahoma, Lucidasans, 'Lucida Sans', 'Arial Unicode MS'" style:font-pitch="variable"/> +    <style:font-face style:name="Nimbus Roman No9 L" svg:font-family="'Nimbus Roman No9 L'" style:font-family-generic="roman" style:font-pitch="variable"/> +    <style:font-face style:name="Bitstream Vera Sans" svg:font-family="'Bitstream Vera Sans'" style:font-family-generic="swiss" style:font-pitch="variable"/> +  </office:font-face-decls> +  <office:styles> +    <style:default-style style:family="graphic"> +      <style:graphic-properties fo:wrap-option="wrap" draw:shadow-offset-x="0.3cm" draw:shadow-offset-y="0.3cm" draw:start-line-spacing-horizontal="0.283cm" draw:start-line-spacing-vertical="0.283cm" draw:end-line-spacing-horizontal="0.283cm" draw:end-line-spacing-vertical="0.283cm" style:flow-with-text="false"/> +      <style:paragraph-properties style:text-autospace="ideograph-alpha" style:line-break="strict" style:writing-mode="lr-tb" style:font-independent-line-spacing="false"> +        <style:tab-stops/> +      </style:paragraph-properties> +      <style:text-properties style:use-window-font-color="true" fo:font-size="12pt" fo:language="en" fo:country="US" style:font-size-asian="12pt" style:language-asian="zxx" style:country-asian="none" style:font-size-complex="12pt" style:language-complex="zxx" style:country-complex="none"/> +    </style:default-style> +    <style:default-style style:family="paragraph"> +      <style:paragraph-properties fo:hyphenation-ladder-count="no-limit" style:text-autospace="ideograph-alpha" style:punctuation-wrap="hanging" style:line-break="strict" style:tab-stop-distance="1.251cm" style:writing-mode="page"/> +      <style:text-properties style:use-window-font-color="true" style:font-name="Nimbus Roman No9 L" fo:font-size="12pt" fo:language="en" fo:country="US" style:font-name-asian="Nimbus Sans L" style:font-size-asian="12pt" style:language-asian="zxx" style:country-asian="none" style:font-name-complex="Nimbus Sans L" style:font-size-complex="12pt" style:language-complex="zxx" style:country-complex="none" fo:hyphenate="false" fo:hyphenation-remain-char-count="2" fo:hyphenation-push-char-count="2"/> +    </style:default-style> +    <style:default-style style:family="table"> +      <style:table-properties table:border-model="collapsing"/> +    </style:default-style> +    <style:default-style style:family="table-row"> +      <style:table-row-properties fo:keep-together="auto"/> +    </style:default-style> +    <style:style style:name="Standard" style:family="paragraph" style:class="text"/> +    <style:style style:name="Text_body" style:display-name="Text body" style:family="paragraph" style:class="text"><style:paragraph-properties fo:margin-top="0cm" fo:margin-bottom="0.212cm"/></style:style> +    <style:style style:name="P_page_break" style:family="paragraph" style:parent-style-name="Standard"><style:paragraph-properties fo:break-before="page"/></style:style> +    <style:style style:name="P_normal" style:family="paragraph" style:parent-style-name="Standard"><style:paragraph-properties  fo:margin-top="0.199cm" fo:margin-bottom="0.199cm" fo:line-height="150%" fo:text-align="justify" style:justify-single-word="false"/></style:style> +    <style:style style:name="P_normal_page_new" style:family="paragraph" style:parent-style-name="Standard"><style:paragraph-properties fo:break-after="page"/></style:style> +    <style:style style:name="P_indent_0" style:display-name="Paragraph indent 0" style:family="paragraph" style:parent-style-name="Standard"><style:paragraph-properties  fo:margin-top="0.199cm" fo:margin-bottom="0.199cm" fo:line-height="150%" fo:text-align="justify" style:justify-single-word="false"/></style:style> +    <style:style style:name="P_indent_1" style:display-name="Paragraph indent 1" style:family="paragraph" style:parent-style-name="Standard"><style:paragraph-properties  fo:margin-top="0.199cm" fo:margin-bottom="0.199cm" fo:line-height="150%" fo:margin-left="1cm" fo:margin-right="0cm" fo:text-align="justify" style:justify-single-word="false" fo:text-indent="0cm" style:auto-text-indent="false"/></style:style> +    <style:style style:name="P_indent_2" style:display-name="Paragraph indent 2" style:family="paragraph" style:parent-style-name="Standard"><style:paragraph-properties  fo:margin-top="0.199cm" fo:margin-bottom="0.199cm" fo:line-height="150%" fo:margin-left="2cm" fo:margin-right="0cm" fo:text-align="justify" style:justify-single-word="false" fo:text-indent="0cm" style:auto-text-indent="false"/></style:style> +    <style:style style:name="P_indent_3" style:display-name="Paragraph indent 3" style:family="paragraph" style:parent-style-name="Standard"><style:paragraph-properties  fo:margin-top="0.199cm" fo:margin-bottom="0.199cm" fo:line-height="150%" fo:margin-left="3cm" fo:margin-right="0cm" fo:text-align="justify" style:justify-single-word="false" fo:text-indent="0cm" style:auto-text-indent="false"/></style:style> +    <style:style style:name="P_indent_4" style:display-name="Paragraph indent 4" style:family="paragraph" style:parent-style-name="Standard"><style:paragraph-properties  fo:margin-top="0.199cm" fo:margin-bottom="0.199cm" fo:line-height="150%" fo:margin-left="4cm" fo:margin-right="0cm" fo:text-align="justify" style:justify-single-word="false" fo:text-indent="0cm" style:auto-text-indent="false"/></style:style> +    <style:style style:name="P_indent_5" style:display-name="Paragraph indent 5" style:family="paragraph" style:parent-style-name="Standard"><style:paragraph-properties  fo:margin-top="0.199cm" fo:margin-bottom="0.199cm" fo:line-height="150%" fo:margin-left="5cm" fo:margin-right="0cm" fo:text-align="justify" style:justify-single-word="false" fo:text-indent="0cm" style:auto-text-indent="false"/></style:style> +    <style:style style:name="P_indent_6" style:display-name="Paragraph indent 6" style:family="paragraph" style:parent-style-name="Standard"><style:paragraph-properties  fo:margin-top="0.199cm" fo:margin-bottom="0.199cm" fo:line-height="150%" fo:margin-left="6cm" fo:margin-right="0cm" fo:text-align="justify" style:justify-single-word="false" fo:text-indent="0cm" style:auto-text-indent="false"/></style:style> +    <style:style style:name="P_indent_7" style:display-name="Paragraph indent 7" style:family="paragraph" style:parent-style-name="Standard"><style:paragraph-properties  fo:margin-top="0.199cm" fo:margin-bottom="0.199cm" fo:line-height="150%" fo:margin-left="7cm" fo:margin-right="0cm" fo:text-align="justify" style:justify-single-word="false" fo:text-indent="0cm" style:auto-text-indent="false"/></style:style> +    <style:style style:name="P_indent_8" style:display-name="Paragraph indent 8" style:family="paragraph" style:parent-style-name="Standard"><style:paragraph-properties  fo:margin-top="0.199cm" fo:margin-bottom="0.199cm" fo:line-height="150%" fo:margin-left="8cm" fo:margin-right="0cm" fo:text-align="justify" style:justify-single-word="false" fo:text-indent="0cm" style:auto-text-indent="false"/></style:style> +    <style:style style:name="P_indent_9" style:display-name="Paragraph indent 9" style:family="paragraph" style:parent-style-name="Standard"><style:paragraph-properties  fo:margin-top="0.199cm" fo:margin-bottom="0.199cm" fo:line-height="150%" fo:margin-left="9cm" fo:margin-right="0cm" fo:text-align="justify" style:justify-single-word="false" fo:text-indent="0cm" style:auto-text-indent="false"/></style:style> +    <style:style style:name="P_h0_i0" style:display-name="Hang 0 Indent 0" style:family="paragraph" style:parent-style-name="Text_body" style:class="text"><style:paragraph-properties fo:margin-left="0cm" fo:margin-right="0cm" fo:text-indent="0cm" style:auto-text-indent="false"><style:tab-stops><style:tab-stop style:position="0cm"/></style:tab-stops></style:paragraph-properties></style:style> +    <style:style style:name="P_h0_i1" style:display-name="Hang 0 Indent 1" style:family="paragraph" style:parent-style-name="Text_body" style:class="text"><style:paragraph-properties fo:margin-left="1cm" fo:margin-right="0cm" fo:text-indent="-1cm" style:auto-text-indent="false"><style:tab-stops><style:tab-stop style:position="0cm"/></style:tab-stops></style:paragraph-properties></style:style> +    <style:style style:name="P_h0_i2" style:display-name="Hang 0 Indent 2" style:family="paragraph" style:parent-style-name="Text_body" style:class="text"><style:paragraph-properties fo:margin-left="2cm" fo:margin-right="0cm" fo:text-indent="-2cm" style:auto-text-indent="false"><style:tab-stops><style:tab-stop style:position="0cm"/></style:tab-stops></style:paragraph-properties></style:style> +    <style:style style:name="P_h0_i3" style:display-name="Hang 0 Indent 3" style:family="paragraph" style:parent-style-name="Text_body" style:class="text"><style:paragraph-properties fo:margin-left="3cm" fo:margin-right="0cm" fo:text-indent="-3cm" style:auto-text-indent="false"><style:tab-stops><style:tab-stop style:position="0cm"/></style:tab-stops></style:paragraph-properties></style:style> +    <style:style style:name="P_h0_i4" style:display-name="Hang 0 Indent 4" style:family="paragraph" style:parent-style-name="Text_body" style:class="text"><style:paragraph-properties fo:margin-left="4cm" fo:margin-right="0cm" fo:text-indent="-4cm" style:auto-text-indent="false"><style:tab-stops><style:tab-stop style:position="0cm"/></style:tab-stops></style:paragraph-properties></style:style> +    <style:style style:name="P_h0_i5" style:display-name="Hang 0 Indent 5" style:family="paragraph" style:parent-style-name="Text_body" style:class="text"><style:paragraph-properties fo:margin-left="5cm" fo:margin-right="0cm" fo:text-indent="-5cm" style:auto-text-indent="false"><style:tab-stops><style:tab-stop style:position="0cm"/></style:tab-stops></style:paragraph-properties></style:style> +    <style:style style:name="P_h0_i6" style:display-name="Hang 0 Indent 6" style:family="paragraph" style:parent-style-name="Text_body" style:class="text"><style:paragraph-properties fo:margin-left="6cm" fo:margin-right="0cm" fo:text-indent="-6cm" style:auto-text-indent="false"><style:tab-stops><style:tab-stop style:position="0cm"/></style:tab-stops></style:paragraph-properties></style:style> +    <style:style style:name="P_h0_i7" style:display-name="Hang 0 Indent 7" style:family="paragraph" style:parent-style-name="Text_body" style:class="text"><style:paragraph-properties fo:margin-left="7cm" fo:margin-right="0cm" fo:text-indent="-7cm" style:auto-text-indent="false"><style:tab-stops><style:tab-stop style:position="0cm"/></style:tab-stops></style:paragraph-properties></style:style> +    <style:style style:name="P_h0_i8" style:display-name="Hang 0 Indent 8" style:family="paragraph" style:parent-style-name="Text_body" style:class="text"><style:paragraph-properties fo:margin-left="8cm" fo:margin-right="0cm" fo:text-indent="-8cm" style:auto-text-indent="false"><style:tab-stops><style:tab-stop style:position="0cm"/></style:tab-stops></style:paragraph-properties></style:style> +    <style:style style:name="P_h0_i9" style:display-name="Hang 0 Indent 9" style:family="paragraph" style:parent-style-name="Text_body" style:class="text"><style:paragraph-properties fo:margin-left="9cm" fo:margin-right="0cm" fo:text-indent="-9cm" style:auto-text-indent="false"><style:tab-stops><style:tab-stop style:position="0cm"/></style:tab-stops></style:paragraph-properties></style:style> +    <style:style style:name="P_h1_i0" style:display-name="Hang 1 Indent 0" style:family="paragraph" style:parent-style-name="Text_body" style:class="text"><style:paragraph-properties fo:margin-left="0cm" fo:margin-right="0cm" fo:text-indent="1cm" style:auto-text-indent="false"><style:tab-stops><style:tab-stop style:position="0cm"/></style:tab-stops></style:paragraph-properties></style:style> +    <style:style style:name="P_h1_i1" style:display-name="Hang 1 Indent 1" style:family="paragraph" style:parent-style-name="Text_body" style:class="text"><style:paragraph-properties fo:margin-left="1cm" fo:margin-right="0cm" fo:text-indent="0cm" style:auto-text-indent="false"><style:tab-stops><style:tab-stop style:position="0cm"/></style:tab-stops></style:paragraph-properties></style:style> +    <style:style style:name="P_h1_i2" style:display-name="Hang 1 Indent 2" style:family="paragraph" style:parent-style-name="Text_body" style:class="text"><style:paragraph-properties fo:margin-left="2cm" fo:margin-right="0cm" fo:text-indent="-1cm" style:auto-text-indent="false"><style:tab-stops><style:tab-stop style:position="0cm"/></style:tab-stops></style:paragraph-properties></style:style> +    <style:style style:name="P_h1_i3" style:display-name="Hang 1 Indent 3" style:family="paragraph" style:parent-style-name="Text_body" style:class="text"><style:paragraph-properties fo:margin-left="3cm" fo:margin-right="0cm" fo:text-indent="-2cm" style:auto-text-indent="false"><style:tab-stops><style:tab-stop style:position="0cm"/></style:tab-stops></style:paragraph-properties></style:style> +    <style:style style:name="P_h1_i4" style:display-name="Hang 1 Indent 4" style:family="paragraph" style:parent-style-name="Text_body" style:class="text"><style:paragraph-properties fo:margin-left="4cm" fo:margin-right="0cm" fo:text-indent="-3cm" style:auto-text-indent="false"><style:tab-stops><style:tab-stop style:position="0cm"/></style:tab-stops></style:paragraph-properties></style:style> +    <style:style style:name="P_h1_i5" style:display-name="Hang 1 Indent 5" style:family="paragraph" style:parent-style-name="Text_body" style:class="text"><style:paragraph-properties fo:margin-left="5cm" fo:margin-right="0cm" fo:text-indent="-4cm" style:auto-text-indent="false"><style:tab-stops><style:tab-stop style:position="0cm"/></style:tab-stops></style:paragraph-properties></style:style> +    <style:style style:name="P_h1_i6" style:display-name="Hang 1 Indent 6" style:family="paragraph" style:parent-style-name="Text_body" style:class="text"><style:paragraph-properties fo:margin-left="6cm" fo:margin-right="0cm" fo:text-indent="-5cm" style:auto-text-indent="false"><style:tab-stops><style:tab-stop style:position="0cm"/></style:tab-stops></style:paragraph-properties></style:style> +    <style:style style:name="P_h1_i7" style:display-name="Hang 1 Indent 7" style:family="paragraph" style:parent-style-name="Text_body" style:class="text"><style:paragraph-properties fo:margin-left="7cm" fo:margin-right="0cm" fo:text-indent="-6cm" style:auto-text-indent="false"><style:tab-stops><style:tab-stop style:position="0cm"/></style:tab-stops></style:paragraph-properties></style:style> +    <style:style style:name="P_h1_i8" style:display-name="Hang 1 Indent 8" style:family="paragraph" style:parent-style-name="Text_body" style:class="text"><style:paragraph-properties fo:margin-left="8cm" fo:margin-right="0cm" fo:text-indent="-7cm" style:auto-text-indent="false"><style:tab-stops><style:tab-stop style:position="0cm"/></style:tab-stops></style:paragraph-properties></style:style> +    <style:style style:name="P_h1_i9" style:display-name="Hang 1 Indent 9" style:family="paragraph" style:parent-style-name="Text_body" style:class="text"><style:paragraph-properties fo:margin-left="9cm" fo:margin-right="0cm" fo:text-indent="-8cm" style:auto-text-indent="false"><style:tab-stops><style:tab-stop style:position="0cm"/></style:tab-stops></style:paragraph-properties></style:style> +    <style:style style:name="P_h2_i0" style:display-name="Hang 2 Indent 0" style:family="paragraph" style:parent-style-name="Text_body" style:class="text"><style:paragraph-properties fo:margin-left="0cm" fo:margin-right="0cm" fo:text-indent="2cm" style:auto-text-indent="false"><style:tab-stops><style:tab-stop style:position="0cm"/></style:tab-stops></style:paragraph-properties></style:style> +    <style:style style:name="P_h2_i1" style:display-name="Hang 2 Indent 1" style:family="paragraph" style:parent-style-name="Text_body" style:class="text"><style:paragraph-properties fo:margin-left="1cm" fo:margin-right="0cm" fo:text-indent="1cm" style:auto-text-indent="false"><style:tab-stops><style:tab-stop style:position="0cm"/></style:tab-stops></style:paragraph-properties></style:style> +    <style:style style:name="P_h2_i2" style:display-name="Hang 2 Indent 2" style:family="paragraph" style:parent-style-name="Text_body" style:class="text"><style:paragraph-properties fo:margin-left="2cm" fo:margin-right="0cm" fo:text-indent="0cm" style:auto-text-indent="false"><style:tab-stops><style:tab-stop style:position="0cm"/></style:tab-stops></style:paragraph-properties></style:style> +    <style:style style:name="P_h2_i3" style:display-name="Hang 2 Indent 3" style:family="paragraph" style:parent-style-name="Text_body" style:class="text"><style:paragraph-properties fo:margin-left="3cm" fo:margin-right="0cm" fo:text-indent="-1cm" style:auto-text-indent="false"><style:tab-stops><style:tab-stop style:position="0cm"/></style:tab-stops></style:paragraph-properties></style:style> +    <style:style style:name="P_h2_i4" style:display-name="Hang 2 Indent 4" style:family="paragraph" style:parent-style-name="Text_body" style:class="text"><style:paragraph-properties fo:margin-left="4cm" fo:margin-right="0cm" fo:text-indent="-2cm" style:auto-text-indent="false"><style:tab-stops><style:tab-stop style:position="0cm"/></style:tab-stops></style:paragraph-properties></style:style> +    <style:style style:name="P_h2_i5" style:display-name="Hang 2 Indent 5" style:family="paragraph" style:parent-style-name="Text_body" style:class="text"><style:paragraph-properties fo:margin-left="5cm" fo:margin-right="0cm" fo:text-indent="-3cm" style:auto-text-indent="false"><style:tab-stops><style:tab-stop style:position="0cm"/></style:tab-stops></style:paragraph-properties></style:style> +    <style:style style:name="P_h2_i6" style:display-name="Hang 2 Indent 6" style:family="paragraph" style:parent-style-name="Text_body" style:class="text"><style:paragraph-properties fo:margin-left="6cm" fo:margin-right="0cm" fo:text-indent="-4cm" style:auto-text-indent="false"><style:tab-stops><style:tab-stop style:position="0cm"/></style:tab-stops></style:paragraph-properties></style:style> +    <style:style style:name="P_h2_i7" style:display-name="Hang 2 Indent 7" style:family="paragraph" style:parent-style-name="Text_body" style:class="text"><style:paragraph-properties fo:margin-left="7cm" fo:margin-right="0cm" fo:text-indent="-5cm" style:auto-text-indent="false"><style:tab-stops><style:tab-stop style:position="0cm"/></style:tab-stops></style:paragraph-properties></style:style> +    <style:style style:name="P_h2_i8" style:display-name="Hang 2 Indent 8" style:family="paragraph" style:parent-style-name="Text_body" style:class="text"><style:paragraph-properties fo:margin-left="8cm" fo:margin-right="0cm" fo:text-indent="-6cm" style:auto-text-indent="false"><style:tab-stops><style:tab-stop style:position="0cm"/></style:tab-stops></style:paragraph-properties></style:style> +    <style:style style:name="P_h2_i9" style:display-name="Hang 2 Indent 9" style:family="paragraph" style:parent-style-name="Text_body" style:class="text"><style:paragraph-properties fo:margin-left="9cm" fo:margin-right="0cm" fo:text-indent="-7cm" style:auto-text-indent="false"><style:tab-stops><style:tab-stop style:position="0cm"/></style:tab-stops></style:paragraph-properties></style:style> +    <style:style style:name="P_h3_i0" style:display-name="Hang 3 Indent 0" style:family="paragraph" style:parent-style-name="Text_body" style:class="text"><style:paragraph-properties fo:margin-left="0cm" fo:margin-right="0cm" fo:text-indent="3cm" style:auto-text-indent="false"><style:tab-stops><style:tab-stop style:position="0cm"/></style:tab-stops></style:paragraph-properties></style:style> +    <style:style style:name="P_h3_i1" style:display-name="Hang 3 Indent 1" style:family="paragraph" style:parent-style-name="Text_body" style:class="text"><style:paragraph-properties fo:margin-left="1cm" fo:margin-right="0cm" fo:text-indent="2cm" style:auto-text-indent="false"><style:tab-stops><style:tab-stop style:position="0cm"/></style:tab-stops></style:paragraph-properties></style:style> +    <style:style style:name="P_h3_i2" style:display-name="Hang 3 Indent 2" style:family="paragraph" style:parent-style-name="Text_body" style:class="text"><style:paragraph-properties fo:margin-left="2cm" fo:margin-right="0cm" fo:text-indent="1cm" style:auto-text-indent="false"><style:tab-stops><style:tab-stop style:position="0cm"/></style:tab-stops></style:paragraph-properties></style:style> +    <style:style style:name="P_h3_i3" style:display-name="Hang 3 Indent 3" style:family="paragraph" style:parent-style-name="Text_body" style:class="text"><style:paragraph-properties fo:margin-left="3cm" fo:margin-right="0cm" fo:text-indent="0cm" style:auto-text-indent="false"><style:tab-stops><style:tab-stop style:position="0cm"/></style:tab-stops></style:paragraph-properties></style:style> +    <style:style style:name="P_h3_i4" style:display-name="Hang 3 Indent 4" style:family="paragraph" style:parent-style-name="Text_body" style:class="text"><style:paragraph-properties fo:margin-left="4cm" fo:margin-right="0cm" fo:text-indent="-1cm" style:auto-text-indent="false"><style:tab-stops><style:tab-stop style:position="0cm"/></style:tab-stops></style:paragraph-properties></style:style> +    <style:style style:name="P_h3_i5" style:display-name="Hang 3 Indent 5" style:family="paragraph" style:parent-style-name="Text_body" style:class="text"><style:paragraph-properties fo:margin-left="5cm" fo:margin-right="0cm" fo:text-indent="-2cm" style:auto-text-indent="false"><style:tab-stops><style:tab-stop style:position="0cm"/></style:tab-stops></style:paragraph-properties></style:style> +    <style:style style:name="P_h3_i6" style:display-name="Hang 3 Indent 6" style:family="paragraph" style:parent-style-name="Text_body" style:class="text"><style:paragraph-properties fo:margin-left="6cm" fo:margin-right="0cm" fo:text-indent="-3cm" style:auto-text-indent="false"><style:tab-stops><style:tab-stop style:position="0cm"/></style:tab-stops></style:paragraph-properties></style:style> +    <style:style style:name="P_h3_i7" style:display-name="Hang 3 Indent 7" style:family="paragraph" style:parent-style-name="Text_body" style:class="text"><style:paragraph-properties fo:margin-left="7cm" fo:margin-right="0cm" fo:text-indent="-4cm" style:auto-text-indent="false"><style:tab-stops><style:tab-stop style:position="0cm"/></style:tab-stops></style:paragraph-properties></style:style> +    <style:style style:name="P_h3_i8" style:display-name="Hang 3 Indent 8" style:family="paragraph" style:parent-style-name="Text_body" style:class="text"><style:paragraph-properties fo:margin-left="8cm" fo:margin-right="0cm" fo:text-indent="-5cm" style:auto-text-indent="false"><style:tab-stops><style:tab-stop style:position="0cm"/></style:tab-stops></style:paragraph-properties></style:style> +    <style:style style:name="P_h3_i9" style:display-name="Hang 3 Indent 9" style:family="paragraph" style:parent-style-name="Text_body" style:class="text"><style:paragraph-properties fo:margin-left="9cm" fo:margin-right="0cm" fo:text-indent="-6cm" style:auto-text-indent="false"><style:tab-stops><style:tab-stop style:position="0cm"/></style:tab-stops></style:paragraph-properties></style:style> +    <style:style style:name="P_h4_i0" style:display-name="Hang 4 Indent 0" style:family="paragraph" style:parent-style-name="Text_body" style:class="text"><style:paragraph-properties fo:margin-left="0cm" fo:margin-right="0cm" fo:text-indent="4cm" style:auto-text-indent="false"><style:tab-stops><style:tab-stop style:position="0cm"/></style:tab-stops></style:paragraph-properties></style:style> +    <style:style style:name="P_h4_i1" style:display-name="Hang 4 Indent 1" style:family="paragraph" style:parent-style-name="Text_body" style:class="text"><style:paragraph-properties fo:margin-left="1cm" fo:margin-right="0cm" fo:text-indent="3cm" style:auto-text-indent="false"><style:tab-stops><style:tab-stop style:position="0cm"/></style:tab-stops></style:paragraph-properties></style:style> +    <style:style style:name="P_h4_i2" style:display-name="Hang 4 Indent 2" style:family="paragraph" style:parent-style-name="Text_body" style:class="text"><style:paragraph-properties fo:margin-left="2cm" fo:margin-right="0cm" fo:text-indent="2cm" style:auto-text-indent="false"><style:tab-stops><style:tab-stop style:position="0cm"/></style:tab-stops></style:paragraph-properties></style:style> +    <style:style style:name="P_h4_i3" style:display-name="Hang 4 Indent 3" style:family="paragraph" style:parent-style-name="Text_body" style:class="text"><style:paragraph-properties fo:margin-left="3cm" fo:margin-right="0cm" fo:text-indent="1cm" style:auto-text-indent="false"><style:tab-stops><style:tab-stop style:position="0cm"/></style:tab-stops></style:paragraph-properties></style:style> +    <style:style style:name="P_h4_i4" style:display-name="Hang 4 Indent 4" style:family="paragraph" style:parent-style-name="Text_body" style:class="text"><style:paragraph-properties fo:margin-left="4cm" fo:margin-right="0cm" fo:text-indent="0cm" style:auto-text-indent="false"><style:tab-stops><style:tab-stop style:position="0cm"/></style:tab-stops></style:paragraph-properties></style:style> +    <style:style style:name="P_h4_i5" style:display-name="Hang 4 Indent 5" style:family="paragraph" style:parent-style-name="Text_body" style:class="text"><style:paragraph-properties fo:margin-left="5cm" fo:margin-right="0cm" fo:text-indent="-1cm" style:auto-text-indent="false"><style:tab-stops><style:tab-stop style:position="0cm"/></style:tab-stops></style:paragraph-properties></style:style> +    <style:style style:name="P_h4_i6" style:display-name="Hang 4 Indent 6" style:family="paragraph" style:parent-style-name="Text_body" style:class="text"><style:paragraph-properties fo:margin-left="6cm" fo:margin-right="0cm" fo:text-indent="-2cm" style:auto-text-indent="false"><style:tab-stops><style:tab-stop style:position="0cm"/></style:tab-stops></style:paragraph-properties></style:style> +    <style:style style:name="P_h4_i7" style:display-name="Hang 4 Indent 7" style:family="paragraph" style:parent-style-name="Text_body" style:class="text"><style:paragraph-properties fo:margin-left="7cm" fo:margin-right="0cm" fo:text-indent="-3cm" style:auto-text-indent="false"><style:tab-stops><style:tab-stop style:position="0cm"/></style:tab-stops></style:paragraph-properties></style:style> +    <style:style style:name="P_h4_i8" style:display-name="Hang 4 Indent 8" style:family="paragraph" style:parent-style-name="Text_body" style:class="text"><style:paragraph-properties fo:margin-left="8cm" fo:margin-right="0cm" fo:text-indent="-4cm" style:auto-text-indent="false"><style:tab-stops><style:tab-stop style:position="0cm"/></style:tab-stops></style:paragraph-properties></style:style> +    <style:style style:name="P_h4_i9" style:display-name="Hang 4 Indent 9" style:family="paragraph" style:parent-style-name="Text_body" style:class="text"><style:paragraph-properties fo:margin-left="9cm" fo:margin-right="0cm" fo:text-indent="-5cm" style:auto-text-indent="false"><style:tab-stops><style:tab-stop style:position="0cm"/></style:tab-stops></style:paragraph-properties></style:style> +    <style:style style:name="P_h5_i0" style:display-name="Hang 5 Indent 0" style:family="paragraph" style:parent-style-name="Text_body" style:class="text"><style:paragraph-properties fo:margin-left="0cm" fo:margin-right="0cm" fo:text-indent="5cm" style:auto-text-indent="false"><style:tab-stops><style:tab-stop style:position="0cm"/></style:tab-stops></style:paragraph-properties></style:style> +    <style:style style:name="P_h5_i1" style:display-name="Hang 5 Indent 1" style:family="paragraph" style:parent-style-name="Text_body" style:class="text"><style:paragraph-properties fo:margin-left="1cm" fo:margin-right="0cm" fo:text-indent="4cm" style:auto-text-indent="false"><style:tab-stops><style:tab-stop style:position="0cm"/></style:tab-stops></style:paragraph-properties></style:style> +    <style:style style:name="P_h5_i2" style:display-name="Hang 5 Indent 2" style:family="paragraph" style:parent-style-name="Text_body" style:class="text"><style:paragraph-properties fo:margin-left="2cm" fo:margin-right="0cm" fo:text-indent="3cm" style:auto-text-indent="false"><style:tab-stops><style:tab-stop style:position="0cm"/></style:tab-stops></style:paragraph-properties></style:style> +    <style:style style:name="P_h5_i3" style:display-name="Hang 5 Indent 3" style:family="paragraph" style:parent-style-name="Text_body" style:class="text"><style:paragraph-properties fo:margin-left="3cm" fo:margin-right="0cm" fo:text-indent="2cm" style:auto-text-indent="false"><style:tab-stops><style:tab-stop style:position="0cm"/></style:tab-stops></style:paragraph-properties></style:style> +    <style:style style:name="P_h5_i4" style:display-name="Hang 5 Indent 4" style:family="paragraph" style:parent-style-name="Text_body" style:class="text"><style:paragraph-properties fo:margin-left="4cm" fo:margin-right="0cm" fo:text-indent="1cm" style:auto-text-indent="false"><style:tab-stops><style:tab-stop style:position="0cm"/></style:tab-stops></style:paragraph-properties></style:style> +    <style:style style:name="P_h5_i5" style:display-name="Hang 5 Indent 5" style:family="paragraph" style:parent-style-name="Text_body" style:class="text"><style:paragraph-properties fo:margin-left="5cm" fo:margin-right="0cm" fo:text-indent="0cm" style:auto-text-indent="false"><style:tab-stops><style:tab-stop style:position="0cm"/></style:tab-stops></style:paragraph-properties></style:style> +    <style:style style:name="P_h5_i6" style:display-name="Hang 5 Indent 6" style:family="paragraph" style:parent-style-name="Text_body" style:class="text"><style:paragraph-properties fo:margin-left="6cm" fo:margin-right="0cm" fo:text-indent="-1cm" style:auto-text-indent="false"><style:tab-stops><style:tab-stop style:position="0cm"/></style:tab-stops></style:paragraph-properties></style:style> +    <style:style style:name="P_h5_i7" style:display-name="Hang 5 Indent 7" style:family="paragraph" style:parent-style-name="Text_body" style:class="text"><style:paragraph-properties fo:margin-left="7cm" fo:margin-right="0cm" fo:text-indent="-2cm" style:auto-text-indent="false"><style:tab-stops><style:tab-stop style:position="0cm"/></style:tab-stops></style:paragraph-properties></style:style> +    <style:style style:name="P_h5_i8" style:display-name="Hang 5 Indent 8" style:family="paragraph" style:parent-style-name="Text_body" style:class="text"><style:paragraph-properties fo:margin-left="8cm" fo:margin-right="0cm" fo:text-indent="-3cm" style:auto-text-indent="false"><style:tab-stops><style:tab-stop style:position="0cm"/></style:tab-stops></style:paragraph-properties></style:style> +    <style:style style:name="P_h5_i9" style:display-name="Hang 5 Indent 9" style:family="paragraph" style:parent-style-name="Text_body" style:class="text"><style:paragraph-properties fo:margin-left="9cm" fo:margin-right="0cm" fo:text-indent="-4cm" style:auto-text-indent="false"><style:tab-stops><style:tab-stop style:position="0cm"/></style:tab-stops></style:paragraph-properties></style:style> +    <style:style style:name="P_h6_i0" style:display-name="Hang 6 Indent 0" style:family="paragraph" style:parent-style-name="Text_body" style:class="text"><style:paragraph-properties fo:margin-left="0cm" fo:margin-right="0cm" fo:text-indent="6cm" style:auto-text-indent="false"><style:tab-stops><style:tab-stop style:position="0cm"/></style:tab-stops></style:paragraph-properties></style:style> +    <style:style style:name="P_h6_i1" style:display-name="Hang 6 Indent 1" style:family="paragraph" style:parent-style-name="Text_body" style:class="text"><style:paragraph-properties fo:margin-left="1cm" fo:margin-right="0cm" fo:text-indent="5cm" style:auto-text-indent="false"><style:tab-stops><style:tab-stop style:position="0cm"/></style:tab-stops></style:paragraph-properties></style:style> +    <style:style style:name="P_h6_i2" style:display-name="Hang 6 Indent 2" style:family="paragraph" style:parent-style-name="Text_body" style:class="text"><style:paragraph-properties fo:margin-left="2cm" fo:margin-right="0cm" fo:text-indent="4cm" style:auto-text-indent="false"><style:tab-stops><style:tab-stop style:position="0cm"/></style:tab-stops></style:paragraph-properties></style:style> +    <style:style style:name="P_h6_i3" style:display-name="Hang 6 Indent 3" style:family="paragraph" style:parent-style-name="Text_body" style:class="text"><style:paragraph-properties fo:margin-left="3cm" fo:margin-right="0cm" fo:text-indent="3cm" style:auto-text-indent="false"><style:tab-stops><style:tab-stop style:position="0cm"/></style:tab-stops></style:paragraph-properties></style:style> +    <style:style style:name="P_h6_i4" style:display-name="Hang 6 Indent 4" style:family="paragraph" style:parent-style-name="Text_body" style:class="text"><style:paragraph-properties fo:margin-left="4cm" fo:margin-right="0cm" fo:text-indent="2cm" style:auto-text-indent="false"><style:tab-stops><style:tab-stop style:position="0cm"/></style:tab-stops></style:paragraph-properties></style:style> +    <style:style style:name="P_h6_i5" style:display-name="Hang 6 Indent 5" style:family="paragraph" style:parent-style-name="Text_body" style:class="text"><style:paragraph-properties fo:margin-left="5cm" fo:margin-right="0cm" fo:text-indent="1cm" style:auto-text-indent="false"><style:tab-stops><style:tab-stop style:position="0cm"/></style:tab-stops></style:paragraph-properties></style:style> +    <style:style style:name="P_h6_i6" style:display-name="Hang 6 Indent 6" style:family="paragraph" style:parent-style-name="Text_body" style:class="text"><style:paragraph-properties fo:margin-left="6cm" fo:margin-right="0cm" fo:text-indent="0cm" style:auto-text-indent="false"><style:tab-stops><style:tab-stop style:position="0cm"/></style:tab-stops></style:paragraph-properties></style:style> +    <style:style style:name="P_h6_i7" style:display-name="Hang 6 Indent 7" style:family="paragraph" style:parent-style-name="Text_body" style:class="text"><style:paragraph-properties fo:margin-left="7cm" fo:margin-right="0cm" fo:text-indent="-1cm" style:auto-text-indent="false"><style:tab-stops><style:tab-stop style:position="0cm"/></style:tab-stops></style:paragraph-properties></style:style> +    <style:style style:name="P_h6_i8" style:display-name="Hang 6 Indent 8" style:family="paragraph" style:parent-style-name="Text_body" style:class="text"><style:paragraph-properties fo:margin-left="8cm" fo:margin-right="0cm" fo:text-indent="-2cm" style:auto-text-indent="false"><style:tab-stops><style:tab-stop style:position="0cm"/></style:tab-stops></style:paragraph-properties></style:style> +    <style:style style:name="P_h6_i9" style:display-name="Hang 6 Indent 9" style:family="paragraph" style:parent-style-name="Text_body" style:class="text"><style:paragraph-properties fo:margin-left="9cm" fo:margin-right="0cm" fo:text-indent="-3cm" style:auto-text-indent="false"><style:tab-stops><style:tab-stop style:position="0cm"/></style:tab-stops></style:paragraph-properties></style:style> +    <style:style style:name="P_h7_i0" style:display-name="Hang 7 Indent 0" style:family="paragraph" style:parent-style-name="Text_body" style:class="text"><style:paragraph-properties fo:margin-left="0cm" fo:margin-right="0cm" fo:text-indent="7cm" style:auto-text-indent="false"><style:tab-stops><style:tab-stop style:position="0cm"/></style:tab-stops></style:paragraph-properties></style:style> +    <style:style style:name="P_h7_i1" style:display-name="Hang 7 Indent 1" style:family="paragraph" style:parent-style-name="Text_body" style:class="text"><style:paragraph-properties fo:margin-left="1cm" fo:margin-right="0cm" fo:text-indent="6cm" style:auto-text-indent="false"><style:tab-stops><style:tab-stop style:position="0cm"/></style:tab-stops></style:paragraph-properties></style:style> +    <style:style style:name="P_h7_i2" style:display-name="Hang 7 Indent 2" style:family="paragraph" style:parent-style-name="Text_body" style:class="text"><style:paragraph-properties fo:margin-left="2cm" fo:margin-right="0cm" fo:text-indent="5cm" style:auto-text-indent="false"><style:tab-stops><style:tab-stop style:position="0cm"/></style:tab-stops></style:paragraph-properties></style:style> +    <style:style style:name="P_h7_i3" style:display-name="Hang 7 Indent 3" style:family="paragraph" style:parent-style-name="Text_body" style:class="text"><style:paragraph-properties fo:margin-left="3cm" fo:margin-right="0cm" fo:text-indent="4cm" style:auto-text-indent="false"><style:tab-stops><style:tab-stop style:position="0cm"/></style:tab-stops></style:paragraph-properties></style:style> +    <style:style style:name="P_h7_i4" style:display-name="Hang 7 Indent 4" style:family="paragraph" style:parent-style-name="Text_body" style:class="text"><style:paragraph-properties fo:margin-left="4cm" fo:margin-right="0cm" fo:text-indent="3cm" style:auto-text-indent="false"><style:tab-stops><style:tab-stop style:position="0cm"/></style:tab-stops></style:paragraph-properties></style:style> +    <style:style style:name="P_h7_i5" style:display-name="Hang 7 Indent 5" style:family="paragraph" style:parent-style-name="Text_body" style:class="text"><style:paragraph-properties fo:margin-left="5cm" fo:margin-right="0cm" fo:text-indent="2cm" style:auto-text-indent="false"><style:tab-stops><style:tab-stop style:position="0cm"/></style:tab-stops></style:paragraph-properties></style:style> +    <style:style style:name="P_h7_i6" style:display-name="Hang 7 Indent 6" style:family="paragraph" style:parent-style-name="Text_body" style:class="text"><style:paragraph-properties fo:margin-left="6cm" fo:margin-right="0cm" fo:text-indent="1cm" style:auto-text-indent="false"><style:tab-stops><style:tab-stop style:position="0cm"/></style:tab-stops></style:paragraph-properties></style:style> +    <style:style style:name="P_h7_i7" style:display-name="Hang 7 Indent 7" style:family="paragraph" style:parent-style-name="Text_body" style:class="text"><style:paragraph-properties fo:margin-left="7cm" fo:margin-right="0cm" fo:text-indent="0cm" style:auto-text-indent="false"><style:tab-stops><style:tab-stop style:position="0cm"/></style:tab-stops></style:paragraph-properties></style:style> +    <style:style style:name="P_h7_i8" style:display-name="Hang 7 Indent 8" style:family="paragraph" style:parent-style-name="Text_body" style:class="text"><style:paragraph-properties fo:margin-left="8cm" fo:margin-right="0cm" fo:text-indent="-1cm" style:auto-text-indent="false"><style:tab-stops><style:tab-stop style:position="0cm"/></style:tab-stops></style:paragraph-properties></style:style> +    <style:style style:name="P_h7_i9" style:display-name="Hang 7 Indent 9" style:family="paragraph" style:parent-style-name="Text_body" style:class="text"><style:paragraph-properties fo:margin-left="9cm" fo:margin-right="0cm" fo:text-indent="-2cm" style:auto-text-indent="false"><style:tab-stops><style:tab-stop style:position="0cm"/></style:tab-stops></style:paragraph-properties></style:style> +    <style:style style:name="P_h8_i0" style:display-name="Hang 8 Indent 0" style:family="paragraph" style:parent-style-name="Text_body" style:class="text"><style:paragraph-properties fo:margin-left="0cm" fo:margin-right="0cm" fo:text-indent="8cm" style:auto-text-indent="false"><style:tab-stops><style:tab-stop style:position="0cm"/></style:tab-stops></style:paragraph-properties></style:style> +    <style:style style:name="P_h8_i1" style:display-name="Hang 8 Indent 1" style:family="paragraph" style:parent-style-name="Text_body" style:class="text"><style:paragraph-properties fo:margin-left="1cm" fo:margin-right="0cm" fo:text-indent="7cm" style:auto-text-indent="false"><style:tab-stops><style:tab-stop style:position="0cm"/></style:tab-stops></style:paragraph-properties></style:style> +    <style:style style:name="P_h8_i2" style:display-name="Hang 8 Indent 2" style:family="paragraph" style:parent-style-name="Text_body" style:class="text"><style:paragraph-properties fo:margin-left="2cm" fo:margin-right="0cm" fo:text-indent="6cm" style:auto-text-indent="false"><style:tab-stops><style:tab-stop style:position="0cm"/></style:tab-stops></style:paragraph-properties></style:style> +    <style:style style:name="P_h8_i3" style:display-name="Hang 8 Indent 3" style:family="paragraph" style:parent-style-name="Text_body" style:class="text"><style:paragraph-properties fo:margin-left="3cm" fo:margin-right="0cm" fo:text-indent="5cm" style:auto-text-indent="false"><style:tab-stops><style:tab-stop style:position="0cm"/></style:tab-stops></style:paragraph-properties></style:style> +    <style:style style:name="P_h8_i4" style:display-name="Hang 8 Indent 4" style:family="paragraph" style:parent-style-name="Text_body" style:class="text"><style:paragraph-properties fo:margin-left="4cm" fo:margin-right="0cm" fo:text-indent="4cm" style:auto-text-indent="false"><style:tab-stops><style:tab-stop style:position="0cm"/></style:tab-stops></style:paragraph-properties></style:style> +    <style:style style:name="P_h8_i5" style:display-name="Hang 8 Indent 5" style:family="paragraph" style:parent-style-name="Text_body" style:class="text"><style:paragraph-properties fo:margin-left="5cm" fo:margin-right="0cm" fo:text-indent="3cm" style:auto-text-indent="false"><style:tab-stops><style:tab-stop style:position="0cm"/></style:tab-stops></style:paragraph-properties></style:style> +    <style:style style:name="P_h8_i6" style:display-name="Hang 8 Indent 6" style:family="paragraph" style:parent-style-name="Text_body" style:class="text"><style:paragraph-properties fo:margin-left="6cm" fo:margin-right="0cm" fo:text-indent="2cm" style:auto-text-indent="false"><style:tab-stops><style:tab-stop style:position="0cm"/></style:tab-stops></style:paragraph-properties></style:style> +    <style:style style:name="P_h8_i7" style:display-name="Hang 8 Indent 7" style:family="paragraph" style:parent-style-name="Text_body" style:class="text"><style:paragraph-properties fo:margin-left="7cm" fo:margin-right="0cm" fo:text-indent="1cm" style:auto-text-indent="false"><style:tab-stops><style:tab-stop style:position="0cm"/></style:tab-stops></style:paragraph-properties></style:style> +    <style:style style:name="P_h8_i8" style:display-name="Hang 8 Indent 8" style:family="paragraph" style:parent-style-name="Text_body" style:class="text"><style:paragraph-properties fo:margin-left="8cm" fo:margin-right="0cm" fo:text-indent="0cm" style:auto-text-indent="false"><style:tab-stops><style:tab-stop style:position="0cm"/></style:tab-stops></style:paragraph-properties></style:style> +    <style:style style:name="P_h8_i9" style:display-name="Hang 8 Indent 9" style:family="paragraph" style:parent-style-name="Text_body" style:class="text"><style:paragraph-properties fo:margin-left="9cm" fo:margin-right="0cm" fo:text-indent="-1cm" style:auto-text-indent="false"><style:tab-stops><style:tab-stop style:position="0cm"/></style:tab-stops></style:paragraph-properties></style:style> +    <style:style style:name="P_h9_i0" style:display-name="Hang 9 Indent 0" style:family="paragraph" style:parent-style-name="Text_body" style:class="text"><style:paragraph-properties fo:margin-left="0cm" fo:margin-right="0cm" fo:text-indent="9cm" style:auto-text-indent="false"><style:tab-stops><style:tab-stop style:position="0cm"/></style:tab-stops></style:paragraph-properties></style:style> +    <style:style style:name="P_h9_i1" style:display-name="Hang 9 Indent 1" style:family="paragraph" style:parent-style-name="Text_body" style:class="text"><style:paragraph-properties fo:margin-left="1cm" fo:margin-right="0cm" fo:text-indent="8cm" style:auto-text-indent="false"><style:tab-stops><style:tab-stop style:position="0cm"/></style:tab-stops></style:paragraph-properties></style:style> +    <style:style style:name="P_h9_i2" style:display-name="Hang 9 Indent 2" style:family="paragraph" style:parent-style-name="Text_body" style:class="text"><style:paragraph-properties fo:margin-left="2cm" fo:margin-right="0cm" fo:text-indent="7cm" style:auto-text-indent="false"><style:tab-stops><style:tab-stop style:position="0cm"/></style:tab-stops></style:paragraph-properties></style:style> +    <style:style style:name="P_h9_i3" style:display-name="Hang 9 Indent 3" style:family="paragraph" style:parent-style-name="Text_body" style:class="text"><style:paragraph-properties fo:margin-left="3cm" fo:margin-right="0cm" fo:text-indent="6cm" style:auto-text-indent="false"><style:tab-stops><style:tab-stop style:position="0cm"/></style:tab-stops></style:paragraph-properties></style:style> +    <style:style style:name="P_h9_i4" style:display-name="Hang 9 Indent 4" style:family="paragraph" style:parent-style-name="Text_body" style:class="text"><style:paragraph-properties fo:margin-left="4cm" fo:margin-right="0cm" fo:text-indent="5cm" style:auto-text-indent="false"><style:tab-stops><style:tab-stop style:position="0cm"/></style:tab-stops></style:paragraph-properties></style:style> +    <style:style style:name="P_h9_i5" style:display-name="Hang 9 Indent 5" style:family="paragraph" style:parent-style-name="Text_body" style:class="text"><style:paragraph-properties fo:margin-left="5cm" fo:margin-right="0cm" fo:text-indent="4cm" style:auto-text-indent="false"><style:tab-stops><style:tab-stop style:position="0cm"/></style:tab-stops></style:paragraph-properties></style:style> +    <style:style style:name="P_h9_i6" style:display-name="Hang 9 Indent 6" style:family="paragraph" style:parent-style-name="Text_body" style:class="text"><style:paragraph-properties fo:margin-left="6cm" fo:margin-right="0cm" fo:text-indent="3cm" style:auto-text-indent="false"><style:tab-stops><style:tab-stop style:position="0cm"/></style:tab-stops></style:paragraph-properties></style:style> +    <style:style style:name="P_h9_i7" style:display-name="Hang 9 Indent 7" style:family="paragraph" style:parent-style-name="Text_body" style:class="text"><style:paragraph-properties fo:margin-left="7cm" fo:margin-right="0cm" fo:text-indent="2cm" style:auto-text-indent="false"><style:tab-stops><style:tab-stop style:position="0cm"/></style:tab-stops></style:paragraph-properties></style:style> +    <style:style style:name="P_h9_i8" style:display-name="Hang 9 Indent 8" style:family="paragraph" style:parent-style-name="Text_body" style:class="text"><style:paragraph-properties fo:margin-left="8cm" fo:margin-right="0cm" fo:text-indent="1cm" style:auto-text-indent="false"><style:tab-stops><style:tab-stop style:position="0cm"/></style:tab-stops></style:paragraph-properties></style:style> +    <style:style style:name="P_h9_i9" style:display-name="Hang 9 Indent 9" style:family="paragraph" style:parent-style-name="Text_body" style:class="text"><style:paragraph-properties fo:margin-left="9cm" fo:margin-right="0cm" fo:text-indent="0cm" style:auto-text-indent="false"><style:tab-stops><style:tab-stop style:position="0cm"/></style:tab-stops></style:paragraph-properties></style:style> +    <style:style style:name="Span_bold" style:family="text"><style:text-properties fo:font-weight="bold" style:font-weight-asian="bold" style:font-weight-complex="bold"/></style:style> +    <style:style style:name="Span_italic" style:family="text"><style:text-properties fo:font-style="italic" style:font-style-asian="italic" style:font-style-complex="italic"/></style:style> +    <style:style style:name="Span_underscore" style:family="text"><style:text-properties style:text-underline-style="solid" style:text-underline-width="auto" style:text-underline-color="font-color"/></style:style> +    <style:style style:name="Span_superscript" style:family="text"><style:text-properties style:text-position="super 58%"/></style:style> +    <style:style style:name="Span_subscript" style:family="text"><style:text-properties style:text-position="sub 58%"/></style:style> +    <style:style style:name="Span_monospace" style:family="text"><style:text-properties style:font-name="DejaVu Sans Mono" fo:font-size="10pt" fo:font-weight="normal" fo:background-color="#e6e6e6"/></style:style> +    <style:style style:name="Heading" style:family="paragraph" style:next-style-name="Text_body" style:class="text"> <style:paragraph-properties fo:margin-top="0.423cm" fo:margin-bottom="0.212cm" fo:keep-with-next="always"/><style:text-properties style:font-name="Bitstream Vera Sans" fo:font-size="14pt" style:font-size-asian="14pt" style:font-name-complex="Tahoma" style:font-size-complex="14pt"/></style:style> +    <style:style style:name="H_1" style:display-name="Heading 1" style:family="paragraph" style:next-style-name="Text_body" style:default-outline-level="1" style:class="text"><style:text-properties fo:font-size="120%" fo:font-weight="bold" style:font-size-asian="120%" style:font-weight-asian="bold" style:font-size-complex="115%" style:font-weight-complex="bold"/></style:style> +    <style:style style:name="H_2" style:display-name="Heading 2" style:family="paragraph" style:next-style-name="Text_body" style:default-outline-level="2" style:class="text"><style:text-properties fo:font-size="115%" fo:font-weight="bold" style:font-size-asian="115%" style:font-weight-asian="bold" style:font-size-complex="115%" style:font-weight-complex="bold"/></style:style> +    <style:style style:name="H_3" style:display-name="Heading 3" style:family="paragraph" style:next-style-name="Text_body" style:default-outline-level="3" style:class="text"><style:text-properties fo:font-size="110%" fo:font-weight="bold" style:font-size-asian="110%" style:font-weight-asian="bold" style:font-size-complex="115%" style:font-weight-complex="bold"/></style:style> +    <style:style style:name="H_4" style:display-name="Heading 4" style:family="paragraph" style:next-style-name="Text_body" style:default-outline-level="4" style:class="text"><style:text-properties fo:font-size="12pt" fo:font-style="italic" fo:font-weight="bold" style:font-size-asian="12pt" style:font-style-asian="italic" style:font-weight-asian="bold" style:font-size-complex="12pt" style:font-style-complex="italic" style:font-weight-complex="bold"/></style:style> +    <style:style style:name="H_5" style:display-name="Heading 5" style:family="paragraph" style:next-style-name="Text_body" style:default-outline-level="5" style:class="text"><style:text-properties fo:font-size="90%" fo:font-style="italic" fo:font-weight="bold" style:font-size-asian="90%" style:font-style-asian="italic" style:font-weight-asian="bold" style:font-size-complex="90%" style:font-style-complex="italic" style:font-weight-complex="bold"/></style:style> +    <style:style style:name="H_6" style:display-name="Heading 6" style:family="paragraph" style:next-style-name="Text_body" style:default-outline-level="6" style:class="text"><style:text-properties fo:font-size="80%" fo:font-style="italic" fo:font-weight="bold" style:font-size-asian="80%" style:font-style-asian="italic" style:font-weight-asian="bold" style:font-size-complex="80%" style:font-style-complex="italic" style:font-weight-complex="bold"/></style:style> +    <style:style style:name="P_group" style:family="paragraph" style:parent-style-name="Standard"><style:paragraph-properties fo:margin-top="0cm" fo:margin-bottom="0cm" fo:line-height="100%" fo:text-align="justify" style:justify-single-word="false"/></style:style> +    <style:style style:name="P_code" style:family="paragraph" style:parent-style-name="Standard"><style:paragraph-properties fo:margin-top="0cm" fo:margin-bottom="0cm" fo:line-height="100%" fo:text-align="start" style:justify-single-word="false"/><style:text-properties style:font-name="DejaVu Sans Mono" fo:font-size="9pt" fo:font-weight="normal" fo:background-color="#e6e6e6"/></style:style> +    <style:style style:name="Footnote" style:family="paragraph" style:class="extra"><style:paragraph-properties fo:margin-left="0.499cm" fo:margin-right="0cm" fo:text-indent="-0.499cm" style:auto-text-indent="false" text:number-lines="false" text:line-number="0"/> <style:text-properties fo:font-size="10pt" style:font-size-asian="10pt" style:font-size-complex="10pt"/></style:style> +    <style:style style:name="Table_Contents" style:display-name="Table Contents" style:family="paragraph" style:parent-style-name="Standard" style:class="extra"><style:paragraph-properties text:number-lines="false" text:line-number="0"/></style:style> +    <style:style style:name="Footnote_symbol" style:display-name="Footnote Symbol" style:family="text"/> +    <style:style style:name="Footnote_anchor" style:display-name="Footnote Anchor" style:family="text"><style:text-properties style:text-position="super 58%"/></style:style> +    <style:style style:name="Internet_link" style:display-name="Internet link" style:family="text"><style:text-properties fo:color="#000080" fo:language="zxx" fo:country="none" style:text-underline-style="solid" style:text-underline-width="auto" style:text-underline-color="font-color" style:language-asian="zxx" style:country-asian="none" style:language-complex="zxx" style:country-complex="none"/></style:style> +    <style:style style:name="Graphics" style:family="graphic"><style:graphic-properties text:anchor-type="paragraph" svg:x="0cm" svg:y="0cm" style:wrap="dynamic" style:number-wrapped-paragraphs="no-limit" style:wrap-contour="false" style:vertical-pos="top" style:vertical-rel="paragraph" style:horizontal-pos="center" style:horizontal-rel="paragraph"/></style:style> +    <text:outline-style style:name="Outline"><text:outline-level-style text:level="1" style:num-format=""><style:list-level-properties text:min-label-distance="0.381cm"/></text:outline-level-style> +      <text:outline-level-style text:level="2" style:num-format=""><style:list-level-properties text:min-label-distance="0.381cm"/></text:outline-level-style> +      <text:outline-level-style text:level="3" style:num-format=""><style:list-level-properties text:min-label-distance="0.381cm"/></text:outline-level-style> +      <text:outline-level-style text:level="4" style:num-format=""><style:list-level-properties text:min-label-distance="0.381cm"/></text:outline-level-style> +      <text:outline-level-style text:level="5" style:num-format=""><style:list-level-properties text:min-label-distance="0.381cm"/></text:outline-level-style> +      <text:outline-level-style text:level="6" style:num-format=""><style:list-level-properties text:min-label-distance="0.381cm"/></text:outline-level-style> +      <text:outline-level-style text:level="7" style:num-format=""><style:list-level-properties text:min-label-distance="0.381cm"/></text:outline-level-style> +      <text:outline-level-style text:level="8" style:num-format=""><style:list-level-properties text:min-label-distance="0.381cm"/></text:outline-level-style> +      <text:outline-level-style text:level="9" style:num-format=""><style:list-level-properties text:min-label-distance="0.381cm"/></text:outline-level-style> +      <text:outline-level-style text:level="10" style:num-format=""><style:list-level-properties text:min-label-distance="0.381cm"/></text:outline-level-style> +    </text:outline-style> +    <text:notes-configuration text:note-class="footnote" text:citation-style-name="Footnote_symbol" text:citation-body-style-name="Footnote_anchor" style:num-format="1" text:start-value="0" text:footnotes-position="page" text:start-numbering-at="document"/> +    <text:notes-configuration text:note-class="endnote" style:num-format="i" text:start-value="0"/> +    <text:linenumbering-configuration text:number-lines="false" text:offset="0.499cm" style:num-format="1" text:number-position="left" text:increment="5"/> +    <style:style style:name="fr1" style:family="graphic" style:parent-style-name="Graphics"><style:graphic-properties style:wrap="none" style:horizontal-pos="left" style:horizontal-rel="paragraph" style:mirror="none" fo:clip="rect(0cm 0cm 0cm 0cm)" draw:luminance="0%" draw:contrast="0%" draw:red="0%" draw:green="0%" draw:blue="0%" draw:gamma="100%" draw:color-inversion="false" draw:image-opacity="100%" draw:color-mode="standard"/></style:style> +    <style:style style:name="gr1" style:family="graphic"><style:graphic-properties draw:stroke="none" draw:fill="none" draw:textarea-horizontal-align="center" draw:textarea-vertical-align="middle" draw:color-mode="standard" draw:luminance="0%" draw:contrast="0%" draw:gamma="100%" draw:red="0%" draw:green="0%" draw:blue="0%" fo:clip="rect(0cm 0cm 0cm 0cm)" draw:image-opacity="100%" style:mirror="none" style:run-through="background" style:wrap="none" style:vertical-pos="top" style:vertical-rel="baseline" style:horizontal-pos="left" style:horizontal-rel="paragraph" draw:wrap-influence-on-position="once-concurrent" style:flow-with-text="false"/></style:style> +    <style:style style:name="gr2" style:family="graphic"><style:graphic-properties draw:stroke="none" draw:fill="none" draw:textarea-horizontal-align="center" draw:textarea-vertical-align="middle" draw:color-mode="standard" draw:luminance="0%" draw:contrast="0%" draw:gamma="100%" draw:red="0%" draw:green="0%" draw:blue="0%" fo:clip="rect(0cm 0cm 0cm 0cm)" draw:image-opacity="100%" style:mirror="none" style:run-through="background" style:wrap="none" style:vertical-pos="middle" style:vertical-rel="baseline" style:horizontal-pos="left" style:horizontal-rel="paragraph" draw:wrap-influence-on-position="once-concurrent" style:flow-with-text="false"/></style:style> +  </office:styles> +  <office:automatic-styles> +    <style:page-layout style:name="Mpm1"> +      <style:page-layout-properties fo:page-width="20.999cm" fo:page-height="29.699cm" style:num-format="1" style:print-orientation="portrait" fo:margin-top="2cm" fo:margin-bottom="2cm" fo:margin-left="2cm" fo:margin-right="2cm" style:writing-mode="lr-tb" style:footnote-max-height="0cm"> +        <style:footnote-sep style:width="0.018cm" style:distance-before-sep="0.101cm" style:distance-after-sep="0.101cm" style:line-style="none" style:adjustment="left" style:rel-width="25%" style:color="#000000"/> +      </style:page-layout-properties> +      <style:header-style/> +      <style:footer-style/> +    </style:page-layout> +  </office:automatic-styles> +  <office:master-styles> +    <style:master-page style:name="Standard" style:page-layout-name="Mpm1"/> +  </office:master-styles> +</office:document-styles> +WOK +      x=x.strip +      x=x.gsub(/\n+/m,'') unless @md.opt.act[:maintenance][:set]==:on +      x +    end +    def mimetype +      x=<<WOK +application/vnd.oasis.opendocument.text +WOK +      x=x.strip +    end +  end +  class FormatObjBreak +    def initialize(md,t_o) +      @md,@t_o=md,t_o +    end +    def br_page +      @t_o.obj='<text:p text:style-name="P_page_break"> </text:p>' +      @t_o +    end +    def br_page_line +      sep='_' +      @t_o.obj=%{<text:p text:style-name="P_normal">#{sep*60}</text:p>} +      @t_o +    end +    def obj_sep #center later +      sep='--- ' +      @t_o.obj=%{<text:p text:style-name="P_normal">#{sep*20}</text:p>} +      @t_o +    end +  end +  class XML +  end +end +__END__ +#+END_SRC + +* docbook5rb + +#+BEGIN_SRC ruby  :tangle "../lib/sisu/xml_docbook5.rb" +# <<sisu_document_header>> +module SiSU_XML_Docbook_Book +  require_relative 'se_hub_particulars'                 # se_hub_particulars.rb +    include SiSU_Particulars +  require_relative 'ao'                                 # ao.rb +  require_relative 'se'                                 # se.rb +    include SiSU_Env +  require_relative 'txt_shared'                         # txt_shared.rb +    include SiSU_TextUtils +  require_relative 'xml_shared'                         # xml_shared.rb +    include SiSU_XML_Munge +  require_relative 'shared_metadata'                    # shared_metadata.rb +  class Source +    def initialize(opt) +      @opt=opt +      @particulars=SiSU_Particulars::CombinedSingleton.instance.get_all(opt) +    end +    def read +      begin +        @md,@ao_array=@particulars.md,@particulars.ao_array +        @env=@particulars.env +        report +        SiSU_XML_Docbook_Book::Source::Scroll.new(@ao_array,@md).songsheet +      rescue +        SiSU_Errors::Rescued.new($!,$@,@opt.selections.str,@opt.fns).location do +          __LINE__.to_s + ':' + __FILE__ +        end +      ensure +        #SiSU_Env::CreateSite.new(@opt.selections.str).cp_css +        #SiSU_Env::CreateSite.new(@opt.selections.str).cp_base_images +        Dir.chdir(@opt.f_pth[:pth]) +      end +    end +    private +    def report +      unless @opt.act[:quiet][:set]==:on +        tool=(@opt.act[:verbose][:set]==:on \ +        || @opt.act[:verbose_plus][:set]==:on \ +        || @opt.act[:maintenance][:set]==:on) \ +        ? "#{@env.program.docbook_viewer} #{@md.file.output_path.xml_docbook_book.dir}/#{@md.file.base_filename.xml_docbook_book}" +        : "[#{@opt.f_pth[:lng_is]}] #{@opt.fno}" +        (@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], +            'DocBook', +            tool +          ).green_hi_blue +        : SiSU_Screen::Ansi.new( +            @opt.act[:color_state][:set], +            'DocBook', +            tool +          ).green_title_hi +        if (@opt.act[:verbose_plus][:set]==:on \ +        || @opt.act[:maintenance][:set]==:on) +          SiSU_Screen::Ansi.new( +            @opt.act[:color_state][:set], +            @opt.fns, +            "#{@md.file.output_path.xml_docbook_book.dir}/#{@md.file.base_filename.xml_docbook_book}" +          ).flow +        end +      end +    end +    class Scroll <Source +      def initialize(data='',md='') +        @data,@md=data,md +        @trans=SiSU_XML_Munge::Trans.new(md) +        @particulars=SiSU_Particulars::CombinedSingleton.instance.get_all(md.opt) +        @env=@particulars.env +        @make ||=SiSU_Env::ProcessingSettings.new(md) +      end +      def songsheet +        @t='sisu' +        data=@data +        if @md.opt.act[:verbose_plus][:set]==:on +          structure_collapsed(data) +        end +        #head +        #extract_endnotes +        data=markup_text(data) +        structure_build_collapsed(data) +        document_images if @md.ec[:image] and @md.ec[:image].length > 0 +        #tail +      end +      def document_images +        img_pth={ +          src:  @md.opt.image_src_path, +          dest: @md.env.path.webserv + '/_sisu/image', +        } +        unless FileTest.directory?(img_pth[:dest]) +          #mkdir? +        end +        if FileTest.directory?(img_pth[:dest]) +          @md.ec[:image].each do |x| +            img={ +              src:  "#{img_pth[:src]}/#{x}", +              dest: "#{img_pth[:dest]}/#{x}", +            } +            if FileTest.file?(img[:src]) +              FileUtils::cp(img[:src],img[:dest]) +            else p "Not Found: #{img[:src]}/#{x}" +            end +          end +        end +      end +      def spaces +        Ax[:spaces] +      end +      def tags +        # collapsed --> +        def collapsed +          %w[ 0 1 2 3 4 5 ] +        end +        def docbook_tag(lc,chlv='') +          case lc +          when 0 then 'book' +          when 1 then lc==chlv ? 'chapter' : 'section' +          when 2 then lc==chlv ? 'chapter' : 'section' +          when 3 then lc==chlv ? 'chapter' : 'section' +          when 4 then 'section' +          when 5 then 'section' +          when 6 then 'section' +          end +        end +        self +      end +      def put(line) +        #@file_docbook.puts line                           #look into and use perhaps +        puts line if @md.opt.act[:verbose_plus][:set]==:on +      end +      def head +        rdf=SiSU_XML_Tags::RDF.new(@md) +        stylesheet=SiSU_Style::CSS_HeadInfo.new(@md,'xml_docbook').stylesheet +        <<-WOK +<?xml version="1.0" encoding="utf-8"?> +#{stylesheet.css_head_xml} +#{rdf.comment_xml} +<book xmlns="http://docbook.org/ns/docbook" +  xmlns:xl="http://www.w3.org/1999/xlink" +  version="5.0"> +        WOK +      end +      def markup_text(data) +        data.each_with_index do |o,i| +          if o.is ==:heading \ +          || o.is ==:para \ +          || o.of ==:block \ +          || o.is ==:open_close_tags +            o=@trans.markup_docbook(o) #unless o.obj==nil +          end +        end +        data +      end +      def tail +        tail=<<-WOK +</book> +        WOK +        put(tail) +      end +      def output(o,comment='') +         puts o.lc == (0..6) \ +         ? "#{spaces*o.lc}<#{o.lc}>[#{o.ocn}] #{o.ln} #{o.obj}</#{o.lc}>#{comment}" +         : "<#{o.lc}>[#{o.ocn}] #{o.ln} #{o.obj}</#{o.lc}>#{comment}" +      end +      def structure_collapsed(data) +        puts "\ncollapsed structure, heading outline --->\n\n" +        data.each_with_index do |o,i| +          if  (o.is ==:heading || o.is ==:heading_insert) +            output(o) +          end +        end +      end +      #def chapterlevel +      #end +      def xml_head +        [ +          '<docinfo>', +          SiSU_Metadata::Summary.new(@md).xml_docbook.metadata, +          '</docinfo>' +        ].flatten +      end +      def code_output(o,ocn,filename_docbook) +        filename_docbook.puts o.obj.gsub(/\n?(?:#{Mx[:br_line]}|#{Mx[:br_nl]})\n?/m,"\n") +      end +      def adjust_output(o,ocn,filename_docbook,splv) +        if o.obj =~/#{Xx[:split]}/ +          outs=o.obj.split(/#{Xx[:split]}/) +          outs.each do |out| +            if out =~/<figure id=/m +              out=out.gsub(/:spaces0:/m, +                  %{#{spaces*(splv)}#{spaces}}). +                gsub(/:spaces1:/m, +                  %{#{spaces*(splv)}#{spaces*2}}) +              filename_docbook.puts out +              filename_docbook.puts "#{spaces*3}#{ocn}" +            else +              unless out.empty? +                filename_docbook.puts SiSU_TextUtils::Wrap.new(out,80,(splv*2+2),nil).line_wrap +                filename_docbook.puts "#{spaces*3}#{ocn}" +              end +            end +          end +        else +          filename_docbook.puts SiSU_TextUtils::Wrap.new(o.obj,80,(splv*2+2),nil,ocn).line_wrap +        end +      end +      def structure_build_collapsed(data) +        #output_file=@md.file.output_path.xml_docbook_book.dir + '/' + @md.file.base_filename.xml_docbook_book +        file=SiSU_Env::FileOp.new(@md) +        filename_docbook=file.write_file.xml_docbook_book +        h=0 +        @chlv=chlv=0 +        doc_position=:head +        filename_docbook.puts head +        filename_docbook.puts xml_head +        data.each_with_index do |o,i| +          if (defined? o.ocn and not o.ocn.nil?) +            ocn=(@make.build.ocn?) \ +            ? "<!-- o#{o.ocn} -->" +            : '' +            id=%{ id="o#{o.ocn}" } +          else +            ocn,id='','' +          end +          if  (o.is ==:heading || o.is ==:heading_insert) +            chlv=(o.lv.to_i == 1) \ +            ? @chlv=o.lc.to_i +            : 0 +            @splv=o.lc +            tag_id=o.tags[0] ? %{ id="#{o.tags[0]}" } : '' +            if doc_position ==:head +               filename_docbook.puts  %{#{spaces*o.lc}<title#{id}>} +              doc_position=:body_and_tail +            else +              filename_docbook.puts structure_build_tag_close(o.lc,h) +              filename_docbook.puts  %{#{spaces*(o.lc)}<#{tags.docbook_tag(o.lc,chlv)}#{tag_id}> +#{spaces*o.lc}<title#{id}> +} +            end +            adjust_output(o,ocn,filename_docbook,@splv) +            filename_docbook.puts %{#{spaces*o.lc}</title>} +            h=o.lc +          elsif o.of ==:layout \ +          and o.is ==:open_close_tags +            xml_tag=case o.sym +            when :quote_open then '<blockquote>' +            when :quote_close then '</blockquote>' +            else '' +            end +            unless xml_tag.empty? +              filename_docbook.puts "#{spaces*(@splv)}#{xml_tag}" +            end +          elsif o.of ==:block +            if o.is ==:table +              filename_docbook.puts SiSU_Tables::TableXMLdocbook.new(o,id).table.obj +            elsif o.is ==:code +              filename_docbook.puts "#{spaces*(@splv)}<para#{id}>" +              filename_docbook.puts "#{spaces*(@splv+1)}<programlisting>" +              code_output(o,ocn,filename_docbook) +              filename_docbook.puts "#{spaces*(@splv+1)}</programlisting>" +              filename_docbook.puts "#{spaces*(@splv)}</para>" +            else +              filename_docbook.puts "#{spaces*(@splv)}<para#{id}>" +              adjust_output(o,ocn,filename_docbook,@splv) +              filename_docbook.puts "#{spaces*(@splv)}</para>" +            end +          elsif o.of ==:para +            filename_docbook.puts "#{spaces*(@splv)}<para#{id}>" +            adjust_output(o,ocn,filename_docbook,@splv) +            filename_docbook.puts "#{spaces*(@splv)}</para>" +          end +        end +        filename_docbook.puts structure_build_tag_close(0,h) +        filename_docbook.close +      end +      def structure_build_tag_close(lc,h) +        x=[] +        case h +        when 0 +          x << "#{spaces*0}</#{tags.docbook_tag(0)}>"       if (lc <= 0) +        when 1 +          x << "#{spaces*1}</#{tags.docbook_tag(1,@chlv)}>" if (lc <= 1) +          x << "#{spaces*0}</#{tags.docbook_tag(0)}>"       if (lc <= 0) +        when 2 +          x << "#{spaces*2}</#{tags.docbook_tag(2,@chlv)}>" if (lc <= 2) +          x << "#{spaces*1}</#{tags.docbook_tag(1,@chlv)}>" if (lc <= 1) +          x << "#{spaces*0}</#{tags.docbook_tag(0)}>"       if (lc <= 0) +        when 3 +          x << "#{spaces*3}</#{tags.docbook_tag(3,@chlv)}>" if (lc <= 3) +          x << "#{spaces*2}</#{tags.docbook_tag(2,@chlv)}>" if (lc <= 2) +          x << "#{spaces*1}</#{tags.docbook_tag(1,@chlv)}>" if (lc <= 1) +          x << "#{spaces*0}</#{tags.docbook_tag(0)}>"       if (lc <= 0) +        when 4 +          x << "#{spaces*4}</#{tags.docbook_tag(4,@chlv)}>" if (lc <= 4) +          x << "#{spaces*3}</#{tags.docbook_tag(3,@chlv)}>" if (lc <= 3) +          x << "#{spaces*2}</#{tags.docbook_tag(2,@chlv)}>" if (lc <= 2) +          x << "#{spaces*1}</#{tags.docbook_tag(1,@chlv)}>" if (lc <= 1) +          x << "#{spaces*0}</#{tags.docbook_tag(0)}>"       if (lc <= 0) +        when 5 +          x << "#{spaces*5}</#{tags.docbook_tag(5)}>"       if (lc <= 5) +          x << "#{spaces*4}</#{tags.docbook_tag(4,@chlv)}>" if (lc <= 4) +          x << "#{spaces*5}</#{tags.docbook_tag(3,@chlv)}>" if (lc <= 3) +          x << "#{spaces*2}</#{tags.docbook_tag(2,@chlv)}>" if (lc <= 2) +          x << "#{spaces*1}</#{tags.docbook_tag(1,@chlv)}>" if (lc <= 1) +          x << "#{spaces*0}</#{tags.docbook_tag(0)}>"       if (lc <= 0) +        when 6 +          x << "#{spaces*6}</#{tags.docbook_tag(6)}>"       if (lc <= 6) +          x << "#{spaces*5}</#{tags.docbook_tag(5)}>"       if (lc <= 5) +          x << "#{spaces*4}</#{tags.docbook_tag(4,@chlv)}>" if (lc <= 4) +          x << "#{spaces*3}</#{tags.docbook_tag(3,@chlv)}>" if (lc <= 3) +          x << "#{spaces*2}</#{tags.docbook_tag(2,@chlv)}>" if (lc <= 2) +          x << "#{spaces*1}</#{tags.docbook_tag(1,@chlv)}>" if (lc <= 1) +          x << "#{spaces*0}</#{tags.docbook_tag(0)}>"       if (lc <= 0) +        end +        x.join("\n") +      end +    end +  end +end +__END__ +#+END_SRC + +* fictionbook2.rb + +#+BEGIN_SRC ruby  :tangle "../lib/sisu/xml_fictionbook2.rb" +# <<sisu_document_header>> +module SiSU_XML_Fictionbook +  require_relative 'se_hub_particulars'                 # se_hub_particulars.rb +    include SiSU_Particulars +  require_relative 'ao'                                 # ao.rb +  require_relative 'se'                                 # se.rb +    include SiSU_Env +  require_relative 'txt_shared'                         # txt_shared.rb +    include SiSU_TextUtils +  require_relative 'xml_shared'                         # xml_shared.rb +    include SiSU_XML_Munge +  class Source +    def initialize(opt) +      @opt=opt +      @particulars=SiSU_Particulars::CombinedSingleton.instance.get_all(opt) +    end +    def read +      begin +        @md,@ao_array=@particulars.md,@particulars.ao_array +        @env=@particulars.env +        report +        SiSU_XML_Fictionbook::Source::Scroll.new(@ao_array,@md).songsheet +      rescue +        SiSU_Errors::Rescued.new($!,$@,@opt.selections.str,@opt.fns).location do +          __LINE__.to_s + ':' + __FILE__ +        end +      ensure +        Dir.chdir(@opt.f_pth[:pth]) +      end +    end +    private +    def report +      unless @opt.act[:quiet][:set]==:on +        tool=(@opt.act[:verbose][:set]==:on \ +        || @opt.act[:verbose_plus][:set]==:on \ +        || @opt.act[:maintenance][:set]==:on) \ +        ? "#{@env.program.fictionbook_viewer} #{@md.file.output_path.xml_fictionbook.dir}/#{@md.file.base_filename.xml_fictionbook}" +        : "[#{@opt.f_pth[:lng_is]}] #{@opt.fno}" +        (@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], +            'Fictionbook', +            tool +          ).green_hi_blue +        : SiSU_Screen::Ansi.new( +            @opt.act[:color_state][:set], +            'Fictionbook', +            tool +          ).green_title_hi +        if (@opt.act[:verbose_plus][:set]==:on \ +        || @opt.act[:maintenance][:set]==:on) +          SiSU_Screen::Ansi.new( +            @opt.act[:color_state][:set], +            @opt.fns, +            "#{@md.file.output_path.xml_fictionbook.dir}/#{@md.file.base_filename.xml_fictionbook}" +          ).flow +        end +      end +    end +    class Scroll <Source +      def initialize(data='',md='') +        @data,@md=data,md +        @trans=SiSU_XML_Munge::Trans.new(@md) +        @particulars=SiSU_Particulars::CombinedSingleton.instance.get_all(md.opt) +        @env=@particulars.env +      end +      def songsheet +        @t='sisu' +        data=@data +        if @md.opt.act[:verbose_plus][:set]==:on +          structure_collapsed(data) +        end +        head +        endnotes=extract_endnotes +        images_base64=extract_images +        data=markup_text(data) +        structure_build_collapsed(data,endnotes,images_base64) +      end +      def spaces +        Ax[:spaces] +      end +      def tags +        # collapsed --> +        def collapsed +          %w[ 0 1 2 3 4 5 ] +        end +        def fictionbook +          [ +            'section', +            'section', +            'section', +            'section', +            'section', +            'section', +            'section' +          ] +        end +        self +      end +      def put(line) +        puts line if @md.opt.act[:verbose_plus][:set]==:on +      end +      def head +        version=SiSU_Env::InfoVersion.instance.get_version +        rb_ver=SiSU_Env::InfoVersion.instance.rbversion +        date_available=if defined? @md.date.available; "\n     <p>#{@md.date.available} Initial version</p>" +        else '' +        end +        date_modified=if defined? @md.date.modified; "\n      <p>#{@md.date.modified} Last Modified</p>" +        else '' +        end +        coverpageimage=if defined? @md.make.cover_image[:cover] +          %{\n    <coverpage><image href="##{@md.make.cover_image[:cover]}" /></coverpage>} +        else '' +        end +        if defined? @md.authors \ +        and @md.authors.length > 0 +          authors=[] +          @md.authors.each do |author| +            authors << '    <author>' +            if not author[:others].empty? +              authors << %{      <first-name>#{author[:others]}</first-name>} +            end +            if not author[:the].empty? +              authors << %{      <last-name>#{author[:the]}</last-name>} +            end +            authors << '    </author>' +          end +          authors=authors.join("\n") +        end +        <<-WOK +<?xml version="1.0" encoding="UTF-8"?> +<FictionBook xmlns:xl="http://www.w3.org/1999/xlink" + xmlns="http://www.gribuser.ru/xml/fictionbook/2.0"> +<description> +  <title-info> +    <genre match="100">***</genre> +#{authors} +    <book-title>#{@md.title.full}</book-title>#{coverpageimage} +    <annotation> +    </annotation> +    <date value="#{@md.date.published}">#{@md.date.published}</date> +  </title-info> +     <document-info> +    <author> +      <first-name/> +      <last-name/> +      <nickname/> +    </author> +    <program-used>#{version.project} #{version.version} and #{rb_ver}</program-used> +    <date value="#{version.date}">#{version.date}</date> +    <src-url>#{@md.file.output_path.manifest.url}/#{@md.file.base_filename.manifest}</src-url> +    <id></id> +    <version>1.0</version> +    <history>#{date_available}#{date_modified} +    </history> +  </document-info> +</description> +<body> +        WOK +      end +      def extract_endnotes                                #work on +        endnotes,endnotes_raw,endnotes_b=[],[],[] +        @data.each do |para| +          endnotes_raw << para.obj.scan(/#{Mx[:en_a_o]}(.+?)#{Mx[:en_a_c]}/m) +          endnotes_b << para.obj.scan(/#{Mx[:en_b_o]}(.+?)#{Mx[:en_b_c]}/m) +        end +        endnotes_raw.flatten.each do |en| +          en=@trans.markup_fictionbook(en) +          endnotes << en.gsub(/([\d+*]+)\s+(.+)/m, +            %{<section id="footnote\\1">\n +<title><p>\\1.</p></title>\n +<p>\\2</p>\n +</section>}) +        end +        endnotes_raw=[] +        endnotes +      end +      def extract_images                                #work on +        begin +          require 'base64' +        rescue LoadError +          SiSU_Utils::CodeMarker.new(__LINE__,__FILE__,:fuchsia). +            error('base64 NOT FOUND (LoadError)') +        end +        images_raw,images_base64_fb2=[],[] +        images_base64={} +        if defined? @md.make.cover_image[:cover] +          images_raw << @md.make.cover_image[:cover] +        end +        @data.each do |para| +          images_raw << para.obj.scan(/#{Mx[:lnk_o]}\s*(\S+?\.(?:png|jpg|gif)).+?#{Mx[:lnk_c]}(?:#{Mx[:url_o]}\S+?#{Mx[:url_c]}|#{Mx[:rel_o]}\S+?#{Mx[:rel_c]}|image)/m) +        end +        images_raw.flatten.sort.each do |img| +          imgpth=@env.url.images_local + '/' + img +          open(imgpth) +          if FileTest.file?(imgpth) +            images_base64[img]=Base64.encode64(File.read(imgpth)) +          end +        end +        images_raw=[] +        images_base64.each_key do |k| +          imgtype=case k +          when /\.jpg/ then 'jpeg' +          when /\.png/ then 'png' +          when /\.gif/ then 'gif' +          else              'jpeg' +          end +          images_base64_fb2 << %{<binary content-type="image/#{imgtype}" id="#{k}">#{images_base64[k]} +</binary> +} +        end +        images_base64_fb2.join("\n") +      end +      def markup_text(data) +        data.each_with_index do |o,i| +          if o.is ==:heading || o.is ==:para +            o.obj=@trans.markup_fictionbook(o.obj,o.is) #unless o.obj==nil +          end +        end +        data +      end +      def tail(images_base64_fb2) +        <<-WOK +</body> +#{images_base64_fb2} +</FictionBook> +        WOK +      end +      def output(o,comment='') +         puts o.lc == (0..6) \ +         ? "#{spaces*o.lc}<#{o.lc}>[#{o.ocn}] #{o.ln} #{o.obj}</#{o.lc}>#{comment}" +         : "<#{o.lc}>[#{o.ocn}] #{o.ln} #{o.obj}</#{o.lc}>#{comment}" +      end +      def structure_collapsed(data) +        puts "\ncollapsed structure, heading outline --->\n\n" +        data.each_with_index do |o,i| +          if  (o.is ==:heading || o.is ==:heading_insert) +            output(o) +          end +        end +      end +      def endnotes_build(endnotes,filename_fictionbook) +        if endnotes.length > 0 +          filename_fictionbook.puts %{</body><body name="notes">} +          endnotes.each do |en| +            filename_fictionbook.puts SiSU_TextUtils::Wrap.new(en,80,6).line_wrap +          end +        end +      end +      def structure_build_collapsed(data,endnotes,images_base64) +        file=SiSU_Env::FileOp.new(@md) +        filename_fictionbook=file.write_file.xml_fictionbook +        h=0 +        doc_position=:head +        filename_fictionbook.puts head +        data.each_with_index do |o,i| +          ocn=if @make.build.ocn? +            (defined? o.ocn and not o.ocn.nil?) \ +            ? "\n#{Dx[:ocn_o]}#{o.ocn}#{Dx[:ocn_c]}" +            : '' +          else '' +          end +          if  o.is ==:heading +            unless doc_position==:head +              filename_fictionbook.puts structure_build_tag_close(o.lc,h) +            end +            doc_position=:body_and_tail +            filename_fictionbook.puts %{#{spaces*o.lc}<#{tags.fictionbook[o.lc]}> +#{spaces*o.lc}<title> +} +            filename_fictionbook.puts SiSU_TextUtils::Wrap.new("<p>#{o.obj}#{ocn}</p>",80,(o.lc*2+2)).line_wrap +            filename_fictionbook.puts %{#{spaces*o.lc}</title>} +            h=o.lc +          elsif  o.is ==:heading_insert \ +          and o.obj =~/Endnotes/ \ +          and o.ln == 1 +            break +          elsif (o.of ==:para or o.of ==:block) +            filename_fictionbook.puts SiSU_TextUtils::Wrap.new("<p>#{o.obj}#{ocn}</p>",80,6).line_wrap +          end +        end +        filename_fictionbook.puts structure_build_tag_close(0,h) +        endnotes_build(endnotes,filename_fictionbook) +        filename_fictionbook.puts tail(images_base64) +        filename_fictionbook.close +      end +      def structure_build_tag_close(lc,h) +        x=[] +        case h +        when 0 +          x << "#{spaces*0}</#{tags.fictionbook[0]}>" if (lc <= 0) +        when 1 +          x << "#{spaces*1}</#{tags.fictionbook[1]}>" if (lc <= 1) +          x << "#{spaces*0}</#{tags.fictionbook[0]}>" if (lc <= 0) +        when 2 +          x << "#{spaces*2}</#{tags.fictionbook[2]}>" if (lc <= 2) +          x << "#{spaces*1}</#{tags.fictionbook[1]}>" if (lc <= 1) +          x << "#{spaces*0}</#{tags.fictionbook[0]}>" if (lc <= 0) +        when 3 +          x << "#{spaces*3}</#{tags.fictionbook[3]}>" if (lc <= 3) +          x << "#{spaces*2}</#{tags.fictionbook[2]}>" if (lc <= 2) +          x << "#{spaces*1}</#{tags.fictionbook[1]}>" if (lc <= 1) +          x << "#{spaces*0}</#{tags.fictionbook[0]}>" if (lc <= 0) +        when 4 +          x << "#{spaces*4}</#{tags.fictionbook[4]}>" if (lc <= 4) +          x << "#{spaces*3}</#{tags.fictionbook[3]}>" if (lc <= 3) +          x << "#{spaces*2}</#{tags.fictionbook[2]}>" if (lc <= 2) +          x << "#{spaces*1}</#{tags.fictionbook[1]}>" if (lc <= 1) +          x << "#{spaces*0}</#{tags.fictionbook[0]}>" if (lc <= 0) +        when 5 +          x << "#{spaces*5}</#{tags.fictionbook[5]}>" if (lc <= 5) +          x << "#{spaces*4}</#{tags.fictionbook[4]}>" if (lc <= 4) +          x << "#{spaces*3}</#{tags.fictionbook[3]}>" if (lc <= 3) +          x << "#{spaces*2}</#{tags.fictionbook[2]}>" if (lc <= 2) +          x << "#{spaces*1}</#{tags.fictionbook[1]}>" if (lc <= 1) +          x << "#{spaces*0}</#{tags.fictionbook[0]}>" if (lc <= 0) +        when 6 +          x << "#{spaces*6}</#{tags.fictionbook[6]}>" if (lc <= 6) +          x << "#{spaces*5}</#{tags.fictionbook[5]}>" if (lc <= 5) +          x << "#{spaces*4}</#{tags.fictionbook[4]}>" if (lc <= 4) +          x << "#{spaces*3}</#{tags.fictionbook[3]}>" if (lc <= 3) +          x << "#{spaces*2}</#{tags.fictionbook[2]}>" if (lc <= 2) +          x << "#{spaces*1}</#{tags.fictionbook[1]}>" if (lc <= 1) +          x << "#{spaces*0}</#{tags.fictionbook[0]}>" if (lc <= 0) +        end +        x.join("\n") +      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 +    xml + +  - 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  | 
