# encoding: utf-8
=begin

 * Name: SiSU

 * Description: a framework for document structuring, publishing and search

 * Author: Ralph Amissah

 * Copyright: (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
   2007, 2008, 2009, 2010, 2011, 2012, 2013 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

 * Hompages:
   <http://www.jus.uio.no/sisu>
   <http://www.sisudoc.org>

 * Download:
   <http://www.sisudoc.org/sisu/en/SiSU/download.html>

 * Git
   <http://sources.sisudoc.org/gitweb/?p=code/sisu.git;a=summary>
   <http://sources.sisudoc.org/?p=code/sisu.git;a=blob;f=lib/sisu/v4/param.rb;hb=HEAD>

 * Ralph Amissah
   <ralph@amissah.com>
   <ralph.amissah@gmail.com>

 ** Description: parameters extracted from input file(s) for program use

=end
module SiSU_Param
  require 'uri'
  require 'pstore'
  require_relative 'sysenv'                             # sysenv.rb
    include SiSU_Env
  require_relative 'param_make'                         # param_make.rb
  require_relative 'param_identify_markup'              # param_identify_markup.rb
  require_relative 'help'                               # help.rb
    include SiSU_Help
  @@date=SiSU_Env::InfoDate.new
  @@proc=@@filename_txt=@@filename_texinfo=@@filename_lout_portrait=@@filename_lout_landscape=@@filename_html_scroll=@@filename_html_index=@@filename_html_segtoc=@@filename_semantic=@@filename_rss=@@newfile=@@drr=nil
  @doc={ initialise: nil, markup: '', lnks: '', stmp: '', req: {} }
  @@yaml=@@yamladdr=nil
  @@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.cmd)
      @cmd,@mod=opt.cmd,opt.mod
      @fns=if @opt.cmd =~/P/ #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.dal}/#{@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])
        p '-- bug alert -- '
        p __FILE__ + ':' + __LINE__.to_s
        p 'f_pth ' + @opt.f_pth[:pth]
        p 'pwd   ' + Dir.pwd
      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.cmd =~/M/ #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)
          @md=SiSU_Param::Parameters::Instructions.new(fns_array,@opt).extract
          @md
        end
        if defined? @md.title.main # on removal check problems with -U
          SiSU_Screen::Ansi.new(@opt.cmd,param_msg,@md.title.main).txt_grey if @opt.cmd =~/[MVv]/
        end
        @@md=@md
      else @@md
      end
      @@md.opt=@opt
      @@md
    end
    class MdDefault
      def rights(author,date)
        @author,@date=author,date
        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
        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.cmd =~/q/
          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 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']
              @h['copyright']
            elsif @h['text']
              @h['text']
            elsif @h['main']
              @h['main']
            else
              SiSU_Screen::Ansi.new(@opt.cmd,'WARNING Document Copyright missing; provide @rights: :copyright:').warn unless @opt.cmd =~/q/
              ''
            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)
          (str =~/https?:\/\/\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.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.cmd,'WARNING Document Rights information missing; provide @rights: :copyright:').warn unless @opt.cmd =~/q/
            else
              l,n=Db[:col_info_note],'rights.all'
              validate_length(s,l,n)
            end
            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,:sisu_version,:ruby_version,:title,:subtitle,:full_title,:html_title,:subtitle_tex,:creator,:classify,:author_home,:author,: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,: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_endnotes,:flag_auto_endnotes,:flag_separate_endnotes,:flag_separate_endnotes_make,:markup,:markup_instruction,:markup_version,:markup_declared,: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_endnotes=@flag_auto_endnotes=@flag_separate_endnotes=@flag_separate_endnotes_make=@sisu=@sisu_version=@ruby_version=@title=@subtitle=@full_title=@html_title=@subtitle_tex=@creator=@classify=@author_home=@author=@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=@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,@markup_declared,@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=if @opt.act[:output_by][:set]==:language
          ''
        elsif @opt.act[:output_by][:set]==:filetype \
        or @opt.act[:output_by][:set]==:filename
          ".#{@opt.lng}"
        elsif @opt.dir_structure_by ==:language
          ''
        else
          ".#{@opt.lng}"
        end
        @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::InfoError.new($!,$@,@opt.cmd,@fns).error 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]
          @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
        @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
        puts 'system locale: ' + @sys.locale if @opt.cmd =~/[MV]/
        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.cmd)
        # programs set here for things that affect output appearance only
        @programs[:pdf]=SiSU_Env::SystemCall.new.program_found?('pdflatex')
        if @opt.cmd =~/P/ #if @env.multilingual?
          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.cmd =~/P/ #watch
          @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
        regx_date=/^\d{4}(?:-(?:[0][0-9]|1[0-2])(-(?:[0-2][0-9]|3[01]))?)?$/
        ver=SiSU_Env::InfoVersion.instance
        @sisu_version=ver.get_version
        @ruby_version=ver.rbversion
        @generated=Time.now
        fns_array=@data.dup
        skip unless fns_array                                                    # consider
        @markup_version=SiSU_MarkupType::MarkupIdentify.new(fns_array,@opt).markup_version?                          #% determine markup version
        if fns_array[0] =~ /^(?:%\s+)?(?:SiSU\s+(?:master\s+)?[\d.]*|sisu-[\d.]+)$/                                    #check markup and markup version
          if fns_array[0] =~ /^(?:%\s+)?(?:SiSU\s+(?:master\s+)?|sisu-)(?:(?:[0-9]+?)(?:\.[0-9]+?)(?:\.[0-9]+))?$/         #check markup and markup version
            @markup_version_declared=fns_array[0].match(/^(?:%\s+)?(?:SiSU\s+(?:master\s+)?|sisu-)([\d.]+)$/)[1]
            sm_a,sm_b,sm_c=fns_array[0].match(/^(?:%\s+)?(?:SiSU\s+(?:master\s+)?|sisu-)([0-9]+)?(?:\.([0-9]+))?(?:\.([0-9]+))?$/)[1..3]
            sm_c ||=0
            sv=(@opt.cmd =~/[VMv]/) ? ("SiSU version (#{@sisu_version[:version]})") : ''
            s_a,s_b,s_c=@sisu_version[:version].match(/^([0-9]+)?(?:\.([0-9]+))?(?:\.([0-9]+))?(?:[~-]\S+)?$/)[1..3]
            tell=(@markup_version_declared.to_f==@markup_version.determined) \
            ? SiSU_Screen::Ansi.new(@opt.cmd,"Markup version (#{@markup_version.series} version #{@markup_version.determined})",sv)
            : SiSU_Screen::Ansi.new(@opt.cmd,"Markup version declared (#{@markup_version_declared}), determined (#{@markup_version.series} version #{@markup_version.determined})",sv)
            ok=if s_a.to_i > sm_a.to_i
              true
            elsif s_a.to_i == sm_a.to_i \
            and s_b.to_i >= sm_b.to_i
              true
            elsif s_a.to_i == sm_a.to_i \
            and s_b.to_i == sm_b.to_i \
            and s_c.to_i >= sm_c.to_i
              true
            else false
            end
            if ok
              tell.txt_green if @opt.cmd =~/[vVM]/
            else
              SiSU_Screen::Ansi.new(@opt.cmd,"WARNING: markup version determined (#{@markup_version.determined}) or markup version declared (#{@markup_version_declared}) is newer than SiSU version (#{@sisu_version[:version]})").warn unless @opt.cmd =~/q/
            end
          else
            SiSU_Screen::Ansi.new(@opt.cmd,'No SiSU markup version provided').warn if @opt.cmd =~/[VM]/
          end
        else
          mv=if @markup_version.determined.is_a?(Float)
            x=@markup_version.determined
            "markup version determined #{x}"
          else ''
          end
          SiSU_Screen::Ansi.new(@opt.cmd,'SiSU filetype indicator not provided',mv).warn unless @opt.cmd =~/q/
        end
        @code_flag=false
        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 #{@sisu_version[:project]} #{@sisu_version[:version]} #{@sisu_version[:date_stamp]} #{@sisu_version[:date]}:\n\t\t#{para}\n\n"
          end
          @code_flag=case para
          when /^code\{\s*$/; true
          when /^\}code\s*$/; false
          else @code_flag
          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; classify=$1                               #% * header metadata - classify
              @classify=SiSU_Param::Parameters::Md.new($1.strip,@opt,@env).classify
            when /^@identifier:(.+)/m; identify=$1                               #% * 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
              @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
            @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~#{l_0}/
              @lvs[1]=1
            when /^:?B~#{l_1}/
              @lvs[2]=1
            when /^:?C~#{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 @markup.nil? \
              or @markup.empty?
                @markup=@markup_version.determined.to_s
              elsif @markup !~/0\.38/ then @markup=@markup.strip + "; #{@markup_version.determined}"
              end
              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
              @html_title=@title.full.gsub(/(<p>|<p \/>|<br>|<br \/>)/,'')
              SiSU_Screen::Ansi.new(@opt.cmd,'Parameters',@html_title).txt_grey if @opt.cmd =~/v/
            end
            if not @book_idx \
            and para =~/^=\{(.+?)\}\s*$/
              @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/; @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.cmd =~/[VM]/
            SiSU_Screen::Ansi.new(@opt.cmd,'@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 =~@rgx_image \
          or @home_button_image =~/\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 |m|
             m[-1]=m[-1].scan(/[^|]+/m) if m[-1] =~/[|]/m
             @topic_register_array << m
           end
           @topic_register_array
        end
        if @i18n
          @i18n=@i18n.uniq
          @i18n << 'en' unless @i18n.find_index("en")
        else
          @i18n=[ 'en' ]
        end
        if @markup_version.determined >= 0.38 #convert values in headers to internal representation
          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}")
        end
        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
          @dgst=[]
          if @env.digest.type =~/sha256/
            dgst=@sys.sha256(@env.source_file_with_path)
            @dgst=dgst[1].length==64 ? dgst : nil
            puts 'check document (sha256) digest' if not @dgst
          else
            dgst=@sys.md5(@env.source_file_with_path)
            @dgst=dgst[1].length==32 ? dgst : nil
            puts 'check document (md5) digest' if not @dgst
          end
        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])
#fix
#       @flv.each do |l|
#         lang=SiSU_Env::StandardiseLanguage.new.file_to_language(l)
#         c={ a: '', b: '', c: '' }
#         if @fnl[:pre] =~/\S/     then c[:a]="#{lang[:c]}."
#         elsif @fnl[:mid] =~/\S/  then c[:b]=".#{lang[:c]}"
#         elsif @fnl[:post] =~/\S/ then c[:c]=".#{lang[:c]}"
#         end
#         @lang << [lang[:n],"#{c[:a]}sisu_manifest#{c[:b]}.html#{c[:c]}"]
#       end if @flv
        @lang=@lang.uniq
        @fn=SiSU_Env::EnvCall.new(@fns).lang(fn_set_lang[:c])
        #if @identifier.is_a?(Array)
        #  @identifier[:sisupod]=sisupod_hash_value
        #else @identifier={ sisupod: sisupod_hash_value }
        #end
        #"#{@env.url.root}/#{@fnb}/#{@fn[:toc]}" #DC note constructed dc identifier
        if @en[:note] > 0 \
        and @en[:sum] > 0
          if @en[:sum] > 0
          else SiSU_Screen::Ansi.new(@opt.cmd,'*WARN* both endnote styles used',"~{ #{@en[:sum]} }~ and ^~ #{@en[:mark]}").warn if @opt.cmd !~/q/
          end
        end
        if @en[:mark] != @en[:note] \
        and @en[:note] > 0
          @en[:mismatch]=@en[:note] - @en[:mark]
          SiSU_Screen::Ansi.new(@opt.cmd,'*WARN* endnote number mismatch',"endnotes: #{@en[:note]} != endnote reference marks: #{@en[:mark]} (difference = #{@en[:mismatch]})").warn if @opt.cmd !~/q/
          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.cmd,'WARNING: Document Title missing','please provide @title:').warn unless @opt.cmd =~/q/
          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.cmd,'WARNING: Document Author missing','please provide @creator: :author:').warn unless @opt.cmd =~/q/
          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
        @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
      end
      private
      class Store
        def initialize(md,env)
          @md,@env=md,env
        end
        def store
          begin
            pstorefile="#{@env.processing_path.dal}/#{@md.fns}.pstore"
            File.unlink(pstorefile) if FileTest.file?(pstorefile)
            SiSU_Screen::Ansi.new(@md.opt.cmd,"PStore -> #{pstorefile}").txt_grey if @md.opt.cmd =~/[MV]/
            store=PStore.new(pstorefile)
            store.transaction do
              store['md']=@md
              store.commit
            end
            @@md=@md=nil
          rescue
            SiSU_Errors::InfoError.new($!,$@,@md.opt.cmd,@md.fns).error do
              __LINE__.to_s + ':' + __FILE__
            end
          ensure
          end
        end
      end
    end
  end
  class Instantiate
    def param_instantiate
      @@date=SiSU_Env::InfoDate.new
      @@proc=@@filename_txt=@@filename_texinfo=@@filename_lout_portrait=@@filename_lout_landscape=@@filename_html_scroll=@@filename_html_index=@@filename_html_segtoc=@@filename_semantic=@@filename_rss=@@newfile=@@drr=nil
      @doc={
       initialise: nil,
       markup: '', lnks: '', stmp: '', prefix_a: '', prefix_b: '',
       req: {}
      }
      @@yaml=@@yamladdr=nil
      @@flag={}
      @@publisher='SiSU scribe'
    end
  end
end
__END__
