# 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/sysenv.rb;hb=HEAD>

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

 ** Description: system environment, resource control and configuration details

=end
@@cX=nil
@@current_document=Dir.pwd #nil #''
@@lang_info=nil
module SiSU_Env
  require_relative 'constants'                             # constants.rb
  require_relative 'utils'                                 # utils.rb
  require 'fileutils'
    include FileUtils::Verbose
  require 'singleton'
  @@noyaml=false
  class InfoDate
    require 'date'
    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
  class InfoSystemGen
    require 'rbconfig'
    @@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'],Config::CONFIG['sysconfdir'] + '/sisu',Config::CONFIG['host'],Config::CONFIG['arch'],%x{ruby -v}.strip,Config::CONFIG['archdir'],Config::CONFIG['sitearchdir'],Config::CONFIG['bindir'],%x{locale charmap}.strip,nil,nil,{} # %x{ruby -v}.strip # Config::CONFIG['rb_ver']
    out=Config::CONFIG['localstatedir']
    etc=Config::CONFIG['sysconfdir'] + '/sisu'
    share=Config::CONFIG['datadir'] + '/sisu'
    data=Config::CONFIG['datadir'] + '/doc/sisu'
    m=/.+\/(?:src\/)?(\S+)/m # m=/.+?\/(?:src\/)?([^\/]+)$/im # m=/.+\/(\S+)/m
    @stub_pwd ||=@@pwd[m,1]
    prcss_dir='_sisu_processing_' + '.' + SiSU_version_dir
    prcss_dir_tmp_root="/tmp/#{prcss_dir}"
    prcss_dir_stub="#{prcss_dir}/#{@stub_pwd}"
    if @@user
      tmp_processing="#{prcss_dir_tmp_root}/#{@@user}/#{@stub_pwd}"
      tmp_processing_individual="#{prcss_dir_tmp_root}/#{@@user}/#{@stub_pwd}"
    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_DAL=:processing_dal
    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_DAL =>           'dal',
      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
  class InfoSystem < InfoSystemGen
    include Singleton
    def initialize
      super()
    end
  end
  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
          break
        end
      end
      if load_prog \
      and @prog=~/dbi/
        require 'dbi' #revisit
      end
      if load_prog
        require @prog
      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
  class GetInit < InfoSystemGen
    @@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
      @@tx ||=SiSU_Viz::TeX.new
    end
    def rc_path_options
      [
        "#{$sisu_document_markup_directory_base_fixed_path}/.sisu/#{SiSU_version_dir}",
        "#{$sisu_document_markup_directory_base_fixed_path}/.sisu",
        "#{$sisu_document_markup_directory_base_fixed_path}/_sisu/#{SiSU_version_dir}",
        "#{$sisu_document_markup_directory_base_fixed_path}/_sisu",
        "#{@@home}/.sisu/#{SiSU_version_dir}",
        "#{@@home}/.sisu",
        "#{@@sisu_etc}/#{SiSU_version_dir}",
        "#{@@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)
                require 'yaml'
                @@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)
                  require 'yaml'
                  @@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/#{SiSU_version_dir}/skin/yml",
          "#{$sisu_document_markup_directory_base_fixed_path}/.sisu/skin/yml",
          "#{$sisu_document_markup_directory_base_fixed_path}/_sisu/#{SiSU_version_dir}/skin/yml",
          "#{$sisu_document_markup_directory_base_fixed_path}/_sisu/skin/yml",
          "#{@@home}/.sisu/#{SiSU_version_dir}/skin/yml",
          "#{@@home}/.sisu/skin/yml",
          "#{@@sisu_etc}/#{SiSU_version_dir}/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]
                require 'yaml'
                @@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]
                require 'yaml'
                @@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
  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=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['lingual']
        if (@rc['lingual'].is_a?(String)) \
        && (@rc['lingual'] =~/mono(?:lingual)?/)
          :mono
        elsif  (@rc['lingual'].is_a?(String)) \
        && (@rc['lingual'] =~/multi(?:lingual)?/)
          :multi
        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
  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=InfoSystem.instance
    end
    def program_found?(program)
      found=`which #{program}` #`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,cmd='')                                         #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
        puts encoding if cmd =~/[VM]/
        encoding
      else encoding='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 STDERR.puts "\t*WARN* #{program} is not installed #{program_ref}"               #if @cmd =~/v/
        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 STDERR.puts "\t*WARN* #{program} is not installed #{program_ref}"               #if @cmd =~/v/
        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 STDERR.puts "\t*WARN* #{program} is not installed #{program_ref}"               #if @cmd =~/v/
        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 STDERR.puts "\t*WARN* #{program} is not installed #{program_ref}"               #if @cmd =~/v/
        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 STDERR.puts "\t*WARN* #{program} is not installed #{program_ref}"               #if @cmd =~/v/
        false
      end
    end
    def psql                                                                   #psql
      program='psql'
      program_ref="\n\t\tpsql requested"
      if program_found?(program); true
      else STDERR.puts "\t*WARN* #{program} is not installed #{program_ref}"               #if @cmd =~/v/
        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 graphicksmagick                                                        #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
      prog=['xetex','xelatex','pdflatex','pdfetex','pdftex']
      @pdfetex_flag=false
      @cmd ||=''
      @texpdf=nil
      prog.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=prog.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'
      program_ref="\n\t\tSee http://www.tug.org/applications/pdftex/\n\t\tOn Debian this is is included in tetex-extra"
      texpdf=tex2pdf_engine
      if @pdfetex_flag
        texpdf_cmd=case texpdf
        when /xetex/
          %{#{texpdf} -interaction=#{mode} -fmt=xelatex -papersize="#{papersize}" #{@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: #{program[0]}, #{program[1]}, #{program[2]} is installed. #{program_ref}"
      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='',''
        if not chdir.nil? \
        && chdir != Dir.pwd
          dir_change=Dir.chdir(chdir)
          dir_return=Dir.pwd
        end
        dir_change #check
        system("
          #{rsync_cmd} #{msg} #{amp}
        ")
        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
  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;                    d,c,l=false,lang_lst['am'][:c],    lang_lst['am'][:n]
      when /^bg$|Bulgarian/i;                  d,c,l=false,lang_lst['bg'][:c],    lang_lst['bg'][:n]
      when /^bn$|Bengali/i;                    d,c,l=false,lang_lst['bn'][:c],    lang_lst['bn'][:n]
      when /^br$|Breton/i;                     d,c,l=false,lang_lst['br'][:c],    lang_lst['br'][:n]
      when /^ca$|Catalan/i;                    d,c,l=false,lang_lst['ca'][:c],    lang_lst['ca'][:n]
      when /^cs$|Czech/i;                      d,c,l=false,lang_lst['cs'][:c],    lang_lst['cs'][:n]
      when /^cy$|Welsh/i;                      d,c,l=false,lang_lst['cy'][:c],    lang_lst['cy'][:n]
      when /^da$|Danish|Dansk/i;               d,c,l=false,lang_lst['da'][:c],    lang_lst['da'][:n]
      when /^de$|German/i;                     d,c,l=false,lang_lst['de'][:c],    lang_lst['de'][:n]
      when /^el$|Greek/i;                      d,c,l=false,lang_lst['el'][:c],    lang_lst['el'][:n]
      when /^en$|English/i;                    d,c,l=false,lang_lst['en'][:c],    lang_lst['en'][:n]
      when /^eo$|Esperanto/i;                  d,c,l=false,lang_lst['eo'][:c],    lang_lst['eo'][:n]
      when /^es$|Spanish|Espanol/i;            d,c,l=false,lang_lst['es'][:c],    lang_lst['es'][:n]
      when /^et$|Estonian/i;                   d,c,l=false,lang_lst['et'][:c],    lang_lst['et'][:n]
      when /^eu$|Basque/i;                     d,c,l=false,lang_lst['eu'][:c],    lang_lst['eu'][:n]
      when /^fi$|Finnish|Finsk|Suomi/i;        d,c,l=false,lang_lst['fi'][:c],    lang_lst['fi'][:n]
      when /^fr$|French|Francais/i;            d,c,l=false,lang_lst['fr'][:c],    lang_lst['fr'][:n]
      when /^ga$|Irish/i;                      d,c,l=false,lang_lst['ga'][:c],    lang_lst['ga'][:n]
      when /^gl$|Galician/i;                   d,c,l=false,lang_lst['gl'][:c],    lang_lst['gl'][:n]
      when /^he$|Hebrew/i;                     d,c,l=false,lang_lst['he'][:c],    lang_lst['he'][:n]
      when /^hi$|Hindi/i;                      d,c,l=false,lang_lst['hi'][:c],    lang_lst['hi'][:n]
      when /^hr$|Croatian/i;                   d,c,l=false,lang_lst['hr'][:c],    lang_lst['hr'][:n]
      when /^hy$|Armenian/i;                   d,c,l=false,lang_lst['hy'][:c],    lang_lst['hy'][:n]
      when /^ia$|Interlingua/i;                d,c,l=false,lang_lst['ia'][:c],    lang_lst['ia'][:n]
      when /^is$|Icelandic/i;                  d,c,l=false,lang_lst['is'][:c],    lang_lst['is'][:n]
      when /^it$|Italian/i;                    d,c,l=false,lang_lst['it'][:c],    lang_lst['it'][:n]
      when /^la$|Latin/i;                      d,c,l=false,lang_lst['la'][:c],    lang_lst['la'][:n]
      when /^lo$|Lao/i;                        d,c,l=false,lang_lst['lo'][:c],    lang_lst['lo'][:n]
      when /^lt$|Lithuanian/i;                 d,c,l=false,lang_lst['lt'][:c],    lang_lst['lt'][:n]
      when /^lv$|Latvian/i;                    d,c,l=false,lang_lst['lv'][:c],    lang_lst['lv'][:n]
      when /^ml$|Malayalam/i;                  d,c,l=false,lang_lst['ml'][:c],    lang_lst['ml'][:n]
      when /^mr$|Marathi/i;                    d,c,l=false,lang_lst['mr'][:c],    lang_lst['mr'][:n]
      when /^nl$|Dutch/i;                      d,c,l=false,lang_lst['nl'][:c],    lang_lst['nl'][:n]
      when /^no$|Norwegian|Norsk/i;            d,c,l=false,lang_lst['no'][:c],    lang_lst['no'][:n]
      when /^nn$|Norwegian Nynorsk/i;          d,c,l=false,lang_lst['nn'][:c],    lang_lst['nn'][:n]
      when /^oc$|Occitan/i;                    d,c,l=false,lang_lst['oc'][:c],    lang_lst['oc'][:n]
      when /^pl$|Polish/i;                     d,c,l=false,lang_lst['pl'][:c],    lang_lst['pl'][:n]
      when /^pt$|Portuguese/i;                 d,c,l=false,lang_lst['pt'][:c],    lang_lst['pt'][:n]
      when /^pt_BR$|Portuguese Brazil/i;       d,c,l=false,lang_lst['pt_BR'][:c], lang_lst['pt_BR'][:n]
      when /^ro$|Romanian/i;                   d,c,l=false,lang_lst['ro'][:c],    lang_lst['ro'][:n]
      when /^ru$|Russian/i;                    d,c,l=false,lang_lst['ru'][:c],    lang_lst['ru'][:n]
      when /^sa$|Sanskrit/i;                   d,c,l=false,lang_lst['sa'][:c],    lang_lst['sa'][:n]
      when /^se$|Sami/i;                       d,c,l=false,lang_lst['se'][:c],    lang_lst['se'][:n]
      when /^sk$|Slovak/i;                     d,c,l=false,lang_lst['sk'][:c],    lang_lst['sk'][:n]
      when /^sl$|Slovenian/i;                  d,c,l=false,lang_lst['sl'][:c],    lang_lst['sl'][:n]
      when /^sq$|Albanian/i;                   d,c,l=false,lang_lst['sq'][:c],    lang_lst['sq'][:n]
      when /^sr$|Serbian/i;                    d,c,l=false,lang_lst['sr'][:c],    lang_lst['sr'][:n]
      when /^sv$|Swedish|Svensk/i;             d,c,l=false,lang_lst['sv'][:c],    lang_lst['sv'][:n]
      when /^ta$|Tamil/i;                      d,c,l=false,lang_lst['ta'][:c],    lang_lst['ta'][:n]
      when /^te$|Telugu/i;                     d,c,l=false,lang_lst['te'][:c],    lang_lst['te'][:n]
      when /^th$|Thai/i;                       d,c,l=false,lang_lst['th'][:c],    lang_lst['th'][:n]
      when /^tk$|Turkmen/i;                    d,c,l=false,lang_lst['tk'][:c],    lang_lst['tk'][:n]
      when /^tr$|Turkish/i;                    d,c,l=false,lang_lst['tr'][:c],    lang_lst['tr'][:n]
      when /^uk$|Ukranian/i;                   d,c,l=false,lang_lst['uk'][:c],    lang_lst['uk'][:n]
      when /^ur$|Urdu/i;                       d,c,l=false,lang_lst['ur'][:c],    lang_lst['ur'][:n]
      when /^us|American$|/i;                  d,c,l=false,lang_lst['en'][:c],    lang_lst['en'][:n]
      when /^vi$|Vietnamese/i;                 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
  class InfoEnv < EnvCall
    require 'pathname'
    require 'fileutils'
      include FileUtils
    attr_accessor :filename,:sys,:home,:hostname,:user,:env,:rc,:www,:fnb,:fnn,:fnt,:flv,:webserv_path,:stub_pwd,: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
      @fns,@md=fns,md
      @env=SiSU_Env::EnvCall.new(fns) if fns
      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=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
      m=/.+\/(?:src\/)?(\S+)/m # m=/.+?\/(?:src\/)?([^\/]+)$/im # m=/.+\/(\S+)/m
      @stub_pwd=@@pwd[m,1]
      @stub_txt=     @stub_pwd + '/txt'
      @stub_html=    @stub_pwd + '/html'
      @stub_epub=    @stub_pwd + '/epub'
      @stub_odt=     @stub_pwd + '/odt'
      @stub_pdf=     @stub_pwd + '/pdf'
      @stub_manifest=@stub_pwd + '/manifest'
      @stub_odt=     @stub_pwd + '/odt'
      @stub_src=     @stub_pwd + '/src'
      @stub_pod=     @stub_pwd + '/pod'
      @stub_md=      @stub_pwd + '/sisu_site_metadata'
      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).mark('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 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']==true) \
      ? @rc['odt']['ocn']
      : false
    end
    def plaintext_ocn?
      ((defined? @rc['plaintext']['ocn']) \
      && @rc['plaintext']['ocn']==true) \
      ? @rc['plaintext']['ocn']
      : false
    end
    def widget #needs (md) #move
      @rc=SiSU_Env::GetInit.new.sisu_yaml.rc
      @ad=SiSU_Env::GetInit.new.ads
      @vz=SiSU_Viz::Defaults.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? @vz.widget_promo \
        and not @vz.widget_promo.nil? \
        and @vz.widget_promo.is_a?(Array) \
        and @vz.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? @vz.widget_search \
              and @vz.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? @vz.widget_search \
              and @vz.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
      @vz=SiSU_Viz::Defaults.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? @vz.widget_search \
          and @vz.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? @vz.widget_search \
          and @vz.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 font
      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_font']) \
          && (@rc['default']['texpdf_font']=~/\S{3,}/)  \
          ? @rc['default']['texpdf_font']
          : 'Liberation Sans'
        end
        def sans                                                               # not used
          (defined? @rc['default']['texpdf_font_sans']) \
          && (@rc['default']['texpdf_font_sans']=~/\S{3,}/)  \
          ? @rc['default']['texpdf_font_sans']
          : 'Liberation Sans'
        end
        def serif                                                              # not used
          (defined? @rc['default']['texpdf_font_serif']) \
          && (@rc['default']['texpdf_font_serif']=~/\S{3,}/)  \
          ? @rc['default']['texpdf_font_serif']
          : 'Liberation Serif'
        end
        def mono
          (defined? @rc['default']['texpdf_font_mono']) \
          && (@rc['default']['texpdf_font_mono']=~/\S{3,}/)  \
          ? @rc['default']['texpdf_font_mono']
          : 'Liberation Mono'
        end
        def cjk
          (defined? @rc['default']['texpdf_font_cjk']) \
          && (@rc['default']['texpdf_font_cjk']=~/\S{3,}/)  \
          ? @rc['default']['texpdf_font_cjk']
          : 'IPAGothic' # 'IPAGothic' # 'IPAMincho' # 'TakaoMincho' # 'VL Gothic'
        end
        def cjk_zh
          (defined? @rc['default']['texpdf_font_cjk_zh']) \
          && (@rc['default']['texpdf_font_cjk_zh']=~/\S{3,}/)  \
          ? @rc['default']['texpdf_font_cjk_zh']
          : 'IPAGothic'
        end
        def cjk_ja
          (defined? @rc['default']['texpdf_font_cjk_ja']) \
          && (@rc['default']['texpdf_font_cjk_ja']=~/\S{3,}/)  \
          ? @rc['default']['texpdf_font_cjk_ja']
          : 'IPAGothic'
        end
        def cjk_ko
          (defined? @rc['default']['texpdf_font_cjk_ko']) \
          && (@rc['default']['texpdf_font_cjk_ko']=~/\S{3,}/)  \
          ? @rc['default']['texpdf_font_cjk_ko']
          : 'IPAGothic'
        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
        GetInit.new.sisu_yaml.rc_path
      end
      def pwd
        @sys.pwd
      end
      def stub_pwd
        @stub_pwd
      end
      def stub_txt
        @stub_txt
      end
      def stub_html
        @stub_html
      end
      def stub_epub
        @stub_epub
      end
      def stub_odt
        @stub_odt
      end
      def stub_pdf
        @stub_pdf
      end
      def stub_manifest
        @stub_manifest
      end
      def stub_set_manifest
        @stub_set_manifest
      end
      def stub_src
        @stub_src
      end
      def stub_pod
        @stub_pod
      end
      def stub_md_harvest
        @stub_set_manifest
      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
        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}/#{@stub_pwd}") unless FileTest.directory?("#{path.webserv}/#{@stub_pwd}")
      end
      def webserv_map_pwd #dir
        "#{path.webserv}/#{stub_pwd}"
      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                                                           #image repository source directory
        if defined? @rc['image']['path'] \
        and defined? @rc['image']['public']
          pth="#{@rc['image']['path']}"
          "#{pth}/#{@rc['image']['public']}"
        else
          "#{share}/image"
        end
      end
      def image_source_sisu_includes
        "#{share}/image"
      end
      def image_source_include                                                       #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
          "#{share}/image"
        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/; 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 (dal,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 (dal,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 dal
        pth=if defined? @rc['processing']['dal'] \
          and @rc['processing']['dal'].is_a?(String)
          "#{processing}/#{@rc['processing']['dal']}"
        else "#{processing}/#{defaults[:processing_dal]}"
        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.dal  #"#{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="#{path.share}/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?:\/\//; @rc['webserv']['host']
          when /\S+/; "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=if opt.mod.inspect =~/--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)}"
          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)}"
          else "#{http}#{webserv_host_base}"
          end
        end
        http=http.strip
      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)
          "#{http}#{webserv_host_base}"
        else "#{http}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}/#{@stub_pwd}".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.mod.inspect =~/--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/; url.webserv_base_cgi(opt)
          when /webserv/;     @rc['webserv']['url_root']
          when /https?:\/\//; @rc['webserv_cgi']['file_links']
          when /\S+/;         "http://#{@rc['webserv_cgi']['file_links']}"
          else                webserv_base_cgi(opt)
          end
        end
      end
      def cgi_sample_search_form_name(opt=nil)
        if opt.mod.inspect =~/--(?:cgi-)?search-form-name[=-]["']?(\S+?\.cgi)/
          $1
        elsif not opt.mod.inspect =~/--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.mod.inspect =~/--db[=-]["']?sqlite/) \
          ? "#{Db[:name_prefix_db]}sqlite.cgi" \
          :  "#{Db[:name_prefix_db]}pgsql.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)?/;       url.dir_url
        when /^remote(?:_webserv)?/;       url.remote
        when /^(?:webserv|local_webserv)/; url.local
        when /^local(:\d+)/;               url.hostname + $1 + '/' + stub_pwd
        when /^localhost(:\d+)/;           url.localhost + $1 +  '/' + stub_pwd
        when /^localhost/;                 url.localhost
        when /^webrick/;                   url.webrick
        when /^path/;                      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=@cmd ? @cmd : ''
            SiSU_Screen::Ansi.new(cmd,"WARNING - no local image directory or images:", defaults[:image_local] ).warn unless cmd =~/q/
            @@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 @cmd =~/q/
            @@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.cmd.inspect=~/-F/ \
        and @md.opt.mod.inspect=~/port=(\d+)/
           $1
        else
          if defined? @rc['webserv_cgi']['port']
            if @rc['webserv_cgi']['port'].nil? \
            and (defined? @md.opt.mod \
            and not @md.opt.mod.nil? \
            and @md.opt.mod.inspect=~/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.cmd.inspect=~/-F/ \
        and opt.mod.inspect=~/port=(\d+)/
           $1
        else
          port=if defined? @rc['webserv_cgi']['port']
            if @rc['webserv_cgi']['port'].nil? \
            and (defined? opt.mod \
            and not opt.mod.nil? \
            and opt.mod.inspect=~/webrick/)
              defaults[:webserv_port_cgi]
            elsif not @rc['webserv_cgi']['port'].nil?
              @rc['webserv_cgi']['port']
            else nil
            end
          else
            if (defined? opt.mod \
            and not opt.mod.nil? \
            and opt.mod.inspect=~/webrick/)
              defaults[:webserv_port_cgi]
            else nil
            end
          end
        end
      end
      self
    end
    def digest
      def type
        if defined? @rc['default']['digest'] \
        and @rc['default']['digest'] != nil
          case @rc['default']['digest']
          when /^sha(?:2|256)?$/; 'sha256'
          when /^md5$/;           'md5'
          else                    'sha256'
          end
        else                      'sha256'
        end
      end
      def length
        case digest.type
        when /sha256/; 64
        when /md5/;    32
        else           64
        end
      end
      def pattern
        "[0-9a-f]{#{digest.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 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;                             pwd[m,1]                    #2 directory: by visible directory name
        elsif conf; @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;    @lang[:pre],@lang[:mid],@lang[:post]="#{l}.",'',''
          elsif x==2; @lang[:pre],@lang[:mid],@lang[:post]='',".#{l}",''
          elsif x==3; @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 odf_structure
      FileUtils::rm_rf(processing_path.processing_path.odf_pth)
      FileUtils::mkdir_p(processing_path.processing_path.odf_pth)
      system("unzip -q #{path.share}/#{SiSU_version_dir}/odf/odt.zip -d      #{processing_path.odf_pth}")
    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 @cmd=~/q/
      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 @cmd=~/q/)
      sisupod_processing_path
    end
  end
  class InfoProcessingFlag
    attr_accessor :color,:cf_0,:cf_1,:cf_2,:cf_3,:cf_4,:cf_5
    def initialize
      @rc=GetInit.new.sisu_yaml.rc
    end
    def color                                                                  #processing flag shortcuts
      (defined? @rc['flag']['color']) ? @rc['flag']['color'] : false
    end
    def cf_0                                                                   #processing flag shortcuts
      if defined? @rc['flag']['default'] \
      and @rc['flag']['default'].is_a?(String)
        @rc['flag']['default']
      else                               '-NQhewpotbxXdyYv'
      end
    end
    def cf_1                                                                   #processing flag shortcuts
      if defined? @rc['flag']['i'] \
      and @rc['flag']['i'].is_a?(String)
        @rc['flag']['i']
      else                               '-Qhewpoty'
      end
    end
    def cf_2                                                                   #processing flag shortcuts
      if defined? @rc['flag']['ii'] \
      and @rc['flag']['ii'].is_a?(String)
        @rc['flag']['ii']
      else                               '-NQhewpotbxXdy'
      end
    end
    def cf_3                                                                   #processing flag shortcuts
      if defined? @rc['flag']['iii'] \
      and @rc['flag']['iii'].is_a?(String)
        @rc['flag']['iii']
      else                               '-NQhewpotbxXdyY'
      end
    end
    def cf_4                                                                   #processing flag shortcuts
      if defined? @rc['flag']['iv'] \
      and @rc['flag']['iv'].is_a?(String)
        @rc['flag']['iv']
      else                               '-NQhewpotbxXdDyY --update'
      end
    end
    def cf_5                                                                   #processing flag shortcuts
      if defined? @rc['flag']['v'] \
      and @rc['flag']['v'].is_a?(String)
        @rc['flag']['v']
      else                               '-NQhewpotbxXdDyYv --update'
      end
    end
  end
  class InfoSettings < InfoEnv
    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
  class FileMap < InfoEnv
    attr_accessor :local_sisu_source
    def initialize(opt='') #watch / REVIEW
      super()
      @opt=opt #,opt.fns,opt.cmd
      @env=(@opt.fns && !(@opt.fns.empty?) \
      ? (SiSU_Env::InfoEnv.new(@opt.fns))
      : (SiSU_Env::InfoEnv.new('dummy.sst')))
      ft=[]
      if @opt.act[:dal][: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.cmd =~ /[hH]/
            ft << @md.fn[:html]
          end
          if @md.opt.cmd =~ /w/ \
          and @md.opt.cmd !~ /[hH]/
            ft << @md.fn[:concordance]
          end
          if @md.opt.cmd =~ /y/ \
          and @md.opt.cmd !~ /[hH]/
            ft << @md.fn[:manifest]
          end
          if @md.opt.cmd =~ /[at]/; ft << @md.fn[:plain]
          end
          if @md.opt.cmd =~ /b/; ft << @md.fn[:xhtml]
          end
          if @md.opt.cmd =~ /e/; ft << @md.fn[:epub]
          end
          if @md.opt.cmd =~ /g/; ft << @md.fn[:wiki]
          end
          if @md.opt.cmd =~ /i/; ft << @md.fn[:manpage]
          end
          if @md.opt.cmd =~ /N/; ft << @md.fn[:digest]
          end
          if @md.opt.cmd =~ /o/; ft << @md.fn[:odf]
          end
          if @md.opt.cmd =~ /O/; ft << @md.fn[:oai_pmh]
          end
          if @md.opt.cmd =~ /p/; ft << @md.fn[:pdf_l] << @md.fn[:pdf_p]
          end
          if @md.opt.cmd =~ /s/; ft << @md.fns
          end
          if @md.opt.cmd =~ /S/; ft << @md.fn[:sisupod] << '.kdi'
          end
          if @md.opt.cmd =~ /x/; ft << @md.fn[:sax]
          end
          if @md.opt.cmd =~ /X/; ft << @md.fn[:dom]
          end
          if @md.opt.cmd =~ /G/; ft << @md.fn[:pot]
          end
          @fnb=@md.fnb
        else                                                                     # still needed where/when param is not parsed
          if @opt.cmd =~ /[hH]/; ft << '.html' << '.html.??'
          end
          if @opt.cmd =~ /w/ \
          and @opt.cmd !~ /[hH]/
            ft << 'concordance.html' << '??.concordance.html' << 'concordance.??.html'
          end
          if @opt.cmd =~ /y/ \
          and @opt.cmd !~ /[hH]/
            ft << 'sisu_manifest.html' << '??.sisu_manifest.html' << 'sisu_manifest.??.html'
          end
          if @opt.cmd =~ /a/; ft << 'plain.txt' << '??.plain.txt' << 'plain.??.txt'
          end
          if @opt.cmd =~ /b/; ft << 'scroll.xhtml' << '??.scroll.xhtml' << 'scroll.??.xhtml'
          end
          if @opt.cmd =~ /e/; ft  << @fnb << '.epub'
          end
          if @opt.cmd =~ /g/; ft << 'wiki.txt' << '??.wiki.txt' << 'wiki.??.txt'
          end
          if @opt.cmd =~ /i/; ft << '.1' << '??.man.1' << 'man.??.1'
          end
          if @opt.cmd =~ /N/; ft << 'digest.txt' << '??.digest.txt' << 'digest.??.txt'
          end
          if @opt.cmd =~ /o/; ft << 'opendocument.odt' << '??.opendocument.odt' << 'opendocument.??.odt'
          end
          if @opt.cmd =~ /O/; ft << 'oai_pmh.xml'
          end
          if @opt.cmd =~ /p/; ft << 'landscape.pdf' << 'portrait.pdf' << '.pdf'
          end
          if @opt.cmd =~ /s/; ft << '.sst' << '.ssi' << '.ssm'
          end
          if @opt.cmd =~ /S/; ft << '.zip' << '.kdi'
          end
          if @opt.cmd =~ /x/; ft << 'sax.xml' << '??.sax.xml' << 'sax.??.xml'
          end
          if @opt.cmd =~ /X/; ft << 'dom.xml' << '??.dom.xml' << 'dom.??.xml'
          end
          if @opt.mod.inspect =~ /sxm|sxs|xml/; ft << @fnb << '.sxs.xml'
          end
          if @opt.mod.inspect =~ /sxd/; ft << @fnb << '.sxd.xml'
          end
          if @opt.mod.inspect =~ /sxn/; ft << @fnb << '.sxn.xml'
          end
        end
        ft=ft.uniq
        filetypes=ft.join(',')
        @filetypes=if filetypes !~/..+/;             ''   # -r called alone, copy all
        elsif @opt.cmd =~/u/;                        ''   # -u added, copy all, (used to create remote directory tree see output path), not the usual function of -u
        elsif filetypes =~/\S+?,\S+/;                '*{' + 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
  class CleanOutput
    require 'fileutils'
      include FileUtils::Verbose
    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.dal)
          tell.warn unless @opt.cmd =~/q/
          deletion(m.marshal.dal_content)
          deletion(m.marshal.dal_idx_sst_rel_html_seg)
          deletion(m.dal_idx_sst_rel)
          deletion(m.dal_idx_html)
          deletion(m.dal_idx_xhtml)
          deletion(m.dal_metadata)
          deletion(m.dal_map_nametags)
          deletion(m.dal_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.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
  class InfoRemoteHost
    def initialize
      @rc=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
  class InfoRemote < FileMap
    @@flag_remote=false
    require 'socket'
    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.stub_pwd}/."             #creates remote directory tree, this is not the usual function of u
          when /[abhHNopwxXy]/;    "#{remote_conn[:name]}/#{@env.path.stub_pwd}/#{@fnb}/."
          else                     "#{remote_conn[:name]}/#{@env.path.stub_pwd}/."
          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.stub_pwd}/."
          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.stub_pwd}/."
          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[:dal][: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.stub_pwd}/_sisu/image"
            #local_gen_image_external="#{@env.path.webserv}/#{@env.path.stub_pwd}/_sisu/image_external"
            remote_gen="#{remote_conn[:name]}/#{@env.path.stub_pwd}/."
            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[: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.stub_pwd}"
          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.stub_pwd}"
        image_sys="#{@env.path.webserv}/_sisu/image_sys"
        self.remote_host_base.each do |remote_conn|
          remote="#{remote_conn[:name]}/#{@env.path.stub_pwd}"
          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.stub_pwd}/."
          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.stub_pwd}/."
        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
  class InfoVersion <InfoEnv
    include Singleton
    require 'rbconfig'
    require 'yaml'
    @@lib_path=nil
    def get_version
      @version={}
      @pwd=ENV['PWD']
      yst_ver=SiSU_path_specified_Version_ \
      ? SiSU_path_specified_Version_
      : "#{defaults[:sisu_share]}/#{SiSU_version_dir}/v/version.yml"
      lib_path=@@lib_path ? @@lib_path : `echo $RUBYLIB`.split(':')
      @@lib_path ||=lib_path
      if File.exist?(yst_ver)
        @version=YAML::load(File::open(yst_ver)) #unless @@noyaml
      end
      @version
    end
    def rbversion
      %x{ruby -v}.strip
    end
  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],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
  class InfoFile <InfoEnv                                                  #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)$/ #watch added match for sss
        @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 dal_content
        "#{@env.processing_path.dal}/#{@fns}.content.rbm"
      end
      def dal_idx_sst_rel_html_seg
        "#{@env.processing_path.dal}/#{@fns}.idx_sst.rbm"
      end
      def dal_idx_sst_rel #used by tex & odf
        "#{@env.processing_path.dal}/#{@fns}.idx_raw.rbm"
      end
      def dal_idx_html
        "#{@env.processing_path.dal}/#{@fns}.idx_html.rbm"
      end
      def dal_idx_xhtml
        "#{@env.processing_path.dal}/#{@fns}.idx_xhtml.rbm"
      end
      def dal_metadata
        "#{@env.processing_path.dal}/#{@fns}.metadata.rbm"
      end
      def dal_map_nametags
        "#{@env.processing_path.dal}/#{@fns}.map_name_tags.rbm"
      end
      def dal_map_ocn_htmlseg
        "#{@env.processing_path.dal}/#{@fns}.map_ocn_htmlseg.rbm"
      end
      def html_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 dal
          FileUtils::mkdir_p(@env.processing_path.dal) unless FileTest.directory?(@env.processing_path.dal)
        end
        def tune
          FileUtils::mkdir_p(@env.processing_path.tune) unless FileTest.directory?(@env.processing_path.tune)
        end
        self
      end
    end
  end
  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 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
          true
        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
          true
        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
          true
        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
          true
        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 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
  class InfoDb < InfoEnv
    @@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 ||=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.mod.inspect =~/--db-user[=-]["']?(\S+)["']+/
          $1
        elsif opt \
        and opt.mod =~/--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
        (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
     self
    end
    def mysql
      def db
        #"#{Db[:name_prefix]}#{@pwd_stub}"
      end
      def port
        '**'
      end
      def dbi
        "dbi:Mysql:database=#{mysql.db};port=#{mysql.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
  class DbOp <InfoDb
    def initialize(md)
      begin
        @md=md
      rescue
        SiSU_Screen::Ansi.new(md.opt.cmd,$!,$@).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
        SQLite3::Database.new(sqlite_discrete.sqlite3)
      end
      self
    end
  end
  class FileOp <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.cmd,$!,$@).rescue do
          __LINE__.to_s + ':' + __FILE__
        end
      ensure
      end
    end
    def output_dir_structure
      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.dal) unless FileTest.directory?(@env.processing_path.dal)
      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 html_scroll
        pth=output_path.html.dir
        make_path(pth)
        p_fn=place_file.html_scroll.dir
        @@filename_html_scroll=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
        @@filename_html_index=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
        @@filename_html_index=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 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 pot
        path=output_path.pot.dir
        make_path(path)
        fn=base_filename.pot
        make_file(path,fn)
      end
      def po
        path=output_path.po.dir
        make_path(path)
        fn=base_filename.po
        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 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 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 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=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_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?
          @md.fnb + '.concordance' + 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 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 po #check
        (@fno.empty?) \
        ? (@md.fn[:po])
        : (@fno + '.po')
      end
      def pot
        (@fno.empty?) \
        ? (@md.fn[:pot])
        : (@fno + '.pot')
      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 po
        def dir
          "#{output_path.base.dir}/#{Gt[:src]}/#{@md.opt.fng}/po4a/po/#{@md.opt.lng}"
        end
        def url
          "#{output_path.base.url}/po4a/#{@md.fnb}/po/#{@md.opt.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 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 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 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
  class FilenameLanguageCodeInsert
    def initialize(opt,lng=nil)
      @opt,@lng=opt,lng
      @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
  class CreateFile <InfoEnv                                                  #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='')
      filename="#{@env.path.output}/#{@fnb}/#{output_file}"
      File.new(filename,'w+')
    end
    def file_error
      File.new('/tmp/errorlog.sisu','w+')
    end
    def file_txt
      File.new("#{@env.processing_path.dal}/#{@fns}.txt",'w+')
    end
    def file_debug
      File.new("#{@env.processing_path.dal}/#{@fns}.debug.txt",'w+')
    end
    def metaverse
      def file_meta
        File.new("#{@env.processing_path.dal}/#{@fns}.meta",'w+')
      end
      def file_meta_idx_html
        File.new("#{@env.processing_path.dal}/#{@fns}.idx.html",'w+')
      end
      self
    end
    def file_note
      File.new("#{Dir.pwd}/#{@fns}.fn",'w+')
    end
    def meta
      "#{@env.processing_path.dal}/#{@fns}.meta"
    end
    def file_semantic
      filename_semantic="./semantic.yaml"
      @@filename_semantic=File.new(filename_semantic,'w+')
    end
    def file_rss
      filename_rss="./semantic.xml"
      @@filename_rss=File.new(filename_rss,'w+')
    end
    def epub
      @pth=@env.processing_path.epub
      def xhtml_index
        filename_index="#{@pth}/#{Ep[:d_oebps]}/index.xhtml"
        File.new(filename_index,'w+')
      end
      def xhtml_cover_image
        filename_index="#{@pth}/#{Ep[:d_oebps]}/cover_image.xhtml"
        File.new(filename_index,'w+')
      end
      def xhtml_segtoc
        filename_segtoc="#{@pth}/#{Ep[:d_oebps]}/toc.xhtml"
        File.new(filename_segtoc,'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
        File.new("#{@pth}/#{Ep[:d_oebps]}/#{Ep[:f_opf]}",'w')
      end
      def toc_ncx  #variable toc ~/grotto/theatre/dbld/builds/epub_sample/toc.ncx
        File.new("#{@pth}/#{Ep[:d_oebps]}/#{Ep[:f_ncx]}",'w')
      end
      def metainf_cont #variable content ~/grotto/theatre/dbld/builds/epub_sample/META-INF/container.xml
        File.new("#{@pth}/META-INF/container.xml",'w')
      end
      def xhtml_css #fixed epub xhtml css
        File.new("#{@pth}/#{Ep[:d_oebps]}/css/xhtml.css",'w')
      end
      self
    end
    def file_texinfo
      File.new("#{@env.processing_path.texinfo}/#{@fnb}.texinfo",'w+')
    end
  end
  class Clear <InfoEnv                                                  #todo unify with FileOp
    def initialize(cmd,fns,operation='')
      @cmd=cmd
      begin
        super(fns)
        @env=SiSU_Env::InfoEnv.new(fns)
        InfoVersion.instance
        if operation.class.inspect =~/SiSU_Param/
          @md=operation
        end
        case operation #watch
        when /pdf/; @env_out=''
        when /sql/
        when /xml|plaintext|ascii/; @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_suf='lm'
            @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
      @@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=@@yaml=@@yamladdr=nil
      @@publisher='SiSU scribe'
    end
  end
  class InfoPort < InfoEnv
    def initialize
      @env=SiSU_Env::InfoEnv.new
    end
    def webrick
      @env.port.webrick_port
    end
  end
  class InfoProgram < InfoEnv                                                #revisit
    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
  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 docbook_xml
      'docbook.css'
    end
    def homepage
      'homepage.css'
    end
    def harvest
      'harvest.css'
    end
  end
  class CSS_Select < InfoEnv
    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.stub_pwd}_html.css")
        "#{@env.path.stub_pwd}_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.stub_pwd}_html_tables.css")
        "#{@env.path.stub_pwd}_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.stub_pwd}_xhtml.css")
        "#{@env.path.stub_pwd}_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.stub_pwd}_xml_sax.css")
        "#{@env.path.stub_pwd}_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.stub_pwd}_xml_dom.css")
        "#{@env.path.stub_pwd}_xml_dom.css"
      else SiSU_Env::CSS_Default.new.xml_dom
      end
    end
    def docbook_xml
      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.stub_pwd}_docbook.css")
        "#{@env.path.stub_pwd}_docbook.css"
      else SiSU_Env::CSS_Default.new.docbook_xml
      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.stub_pwd}_homepage.css")
        "#{@env.path.stub_pwd}_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 rel="stylesheet" href="#{stylesheet}" type="text/css" />}
    end
    def html_seg
      stylesheet="#{@file.path_rel_links.html_seg_css}#{@env.path.style}/#{@css.html}"
      %{  <link rel="stylesheet" href="#{stylesheet}" type="text/css" />}
    end
    def html_tables
      stylesheet="#{@file.path_rel_links.html_seg_css}#{@env.path.style}/#{@css.html}"
      %{  <link rel="stylesheet" href="#{stylesheet}" type="text/css" />}
    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
  end
  class CreateSite < InfoEnv
    require_relative 'css'                              # css.rb
      include SiSU_Style
    def initialize(cmd)
      @cmd=cmd
      @env=SiSU_Env::InfoEnv.new
      @init=SiSU_Env::GetInit.new
      @home,@pwd=ENV['HOME'],ENV['PWD'] #@pwd=Dir.pwd
      @rc=GetInit.new.sisu_yaml.rc
      @vz=SiSU_Viz::Defaults.new
      @vz_home=SiSU_Viz::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
        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.stub_pwd}/index.html"
        filename_home_toc="#{@env.path.webserv}/#{@env.path.stub_pwd}/toc.html"
        file_homepage=File.new(filename_homepage,'w')
        file_home_toc=File.new(filename_home_toc,'w')
        file_homepage << @vz_home.homepage
        file_home_toc << @vz_home.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.stub_pwd}") unless FileTest.directory?("#{@env.path.webserv}/#{@env.path.stub_pwd}")
      if home_pages_manually_created.length > 0
        home_pages_manually_created.each do |homepage|
          FileUtils.cp(homepage,"#{@env.path.webserv}/#{@env.path.stub_pwd}")
        end
      else
        create_default_sisu_homepage(:none)
        #create_default_sisu_homepage(: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.stub_pwd}/_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.stub_pwd}/_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.stub_pwd}/_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.stub_pwd}/_sisu/image"
      cp_images(src,dest) if FileTest.directory?(src)
    end
    def cp_base_images #fix images
      src=SiSU_path_base \
      ? SiSU_path_base + '/data/sisu/image'
      : "#{@env.path.share}/image"
      dest_arr=[
        "#{@env.path.webserv}/_sisu/image_sys",
        "#{@env.path.webserv}/#{@env.path.stub_pwd}/_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(@cmd,"*WARN* modify is css set to: #{@rc['permission_set']['css_modify']}").warn if @cmd=~/[MV]/
        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(@cmd,"*WARN* modify css is not set or is set to: false").warn if @cmd=~/[MV]/
      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 @cmd =~/C/ \
      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 @cmd =~/C/ \
      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 @cmd =~/C/ \
      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 @cmd =~/C/ \
      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 @cmd =~/C/ \
      or (@cmd =~/[x]/ \
        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 @cmd =~/C/ \
      or (@cmd =~/[X]/ \
        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 @cmd =~/C/ \
      or (@cmd =~/[b]/ \
        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
module SiSU_Screen
  require_relative 'screen_text_color'                  # screen_text_color.rb
end
module SiSU_Errors
  require_relative 'errors'                             # errors.rb
end
__END__
https? intro check 2007-09-22
