# coding: utf-8
=begin

 * Name: SiSU

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

 * Author: Ralph Amissah

 * Copyright: (C) 1997 - 2011, 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.jus.uio.no/sisu/gpl.fsf/toc.html>
   <http://www.jus.uio.no/sisu/gpl.fsf/doc.html>
   <http://www.jus.uio.no/sisu/gpl.fsf/plain.txt>

 * 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.jus.uio.no/sisu/SiSU/download.html>

 * 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 #''
module SiSU_Env
  require "#{SiSU_lib}/constants"                             # constants.rb
  require 'fileutils'
    include FileUtils::Verbose
  require 'singleton'
  @@noyaml=false
  class Info_date
    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
      '2010'
    end
  end
  class Info_system
    require 'rbconfig'
      include Singleton
    @@user,@@home,@@hostname,@@pwd,@@sisu_etc,@@host,@@arch,@@rbver,@@dir_arch,@@dir_sitearch,@@dir_bin,@@locale,@@rc,@@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,{} # %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_'
    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
    tmp_processing_home=if @@home \
    and File.writable?("#{@@home}/.")
      "#{@@home}/#{prcss_dir_stub}"
    else prcss_dir_stub
    end
    processing_path=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? \
    or 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
    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_path,
      PROCESSING_DIR_TMP_ROOT  => prcss_dir_tmp_root,
      PROCESSING_PATH_TMP_BASE => processing_path,
      PROCESSING_DAL =>           'dal',
      PROCESSING_TUNE =>          'tune',
      PROCESSING_LATEX =>         'tex',
      PROCESSING_TEXINFO =>       'texinfo',
      PROCESSING_LOUT =>          'lout',
      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 =>             true,
      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
    stub_pwd=@@pwd[m,1]
    @@rc_path=["#{@@pwd}/_sisu/#{SiSU_version_dir}","#{@@pwd}/_sisu","#{@@home}/.sisu/#{SiSU_version_dir}","#{@@home}/.sisu","#{@@sisu_etc}/#{SiSU_version_dir}"]
    @@yamlrc_path=(stub_pwd !~/^sisupod$/) \
    ? (["#{@@pwd}/_sisu/#{SiSU_version_dir}","#{@@pwd}/_sisu","#{@@home}/.sisu/#{SiSU_version_dir}","#{@@home}/.sisu","#{@@sisu_etc}/#{SiSU_version_dir}"]) \
    : ["#{@@home}/.sisu/#{SiSU_version_dir}","#{@@home}/.sisu","#{@@sisu_etc}/#{SiSU_version_dir}"]  #security policy: prevent reading of sisurc.yml in sisupod
    @@ad_path=(stub_pwd !~/^sisupod$/) \
    ? (["#{@@pwd}/_sisu/skin/yml","#{@@home}/.sisu/skin/yml","#{@@sisu_etc}/skin/yml"]) \
    : ["#{@@home}/.sisu",@@sisu_etc]
    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,:yamlrc_path,:ad_path
    def initialize
      @user,@home,@hostname,@pwd,@sisu_etc,@host,@arch,@rbver,@dir_arch,@dir_sitearch,@dir_bin,@locale,@default_dir,@rc_path,@yamlrc_path,@ad_path=@@user,@@home,@@hostname,@@pwd,@@sisu_etc,@@host,@@arch,@@rbver,@@dir_arch,@@dir_sitearch,@@dir_bin,@@locale,@@default_dir,@@rc_path,@@yamlrc_path,@@ad_path
      #note rbver is duplicated in Info_version
    end
  end
  class Load
    def initialize(prog,mandatory=false)
      @prog,@mandatory=prog,mandatory
    end
    def prog
      load_prog=false
      pp=''
      $:.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(@cmd,"module required: #{@prog}").warn) \
        : (SiSU_Screen::Ansi.new(@cmd,"#{@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 Get_init < Info_system
    include Singleton
    @@noyaml=false
    @@rc,@@vz,@@tx=nil,nil,nil
    @@ad={ :promo=>nil,:promo_list=>nil,:flag_promo=>false }
    attr_accessor :yaml
    def initialize
      super()
    end
    def skin
      @@vz ||=SiSU_Viz::Skin.new
    end
    def tex
      @@tx ||=SiSU_Viz::TeX.new
    end
    def yamlrc
      unless @@rc
        @yamlrc_path.each do |v|
          if @@noyaml \
          or FileTest.exist?("#{v}/noyaml")
            puts "WARNING - YAML loading switched off, to enable delete the file:\n\t#{v}/noyaml\n\n" unless @@noyaml
            @@noyaml=true
            break
          else
            if FileTest.exist?("#{v}/sisurc.yml")
              unless @@rc
                require 'yaml'
                @@rc ||= YAML::load(File::open("#{v}/sisurc.yml"))
              end
              break
            end
            unless @@rc
              if FileTest.exist?("#{v}/sisurc.yaml")
                unless @@rc
                  require 'yaml'
                  @@rc ||= YAML::load(File::open("#{v}/sisurc.yaml"))
                end
                break
              end
            end
          end
        end
      end
      @@rc
    end
    def ads #WORK AREA
      tell_no_yaml='WARNING - YAML loading switched off, to enable delete the file:'
      @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
      @@ad
    end
  end
  class Env_call
    @@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='')
      super()
      @fns=fns
      @sys=Info_system.instance
      @rc=Get_init.instance.yamlrc
      @ad=Get_init.instance.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
        if multilingual
          m=/((.+?)(?:\~\w{2,3})?)\.((?:-|ssm\.)?sst|ssm)$/
          @@fnn ||=@fns[m,1]
          @@fnb ||=@fns[m,2]
          @@fnt ||=@fns[m,3]
          @@flv ||=document_language_versions_found[:f]
          unless @@fns =~/\S+?\.zip/
            @@fnz ||=if @@fns =~/(?:\~\S{2,3})?\.(?:ssm\.sst|ssm)$/; @@fnb + '.ssm.zip'
            elsif @@fnb; @@fnb + '.sst.zip'
            else '' # e.g. termsheet
            end
          end
        else m=/(.+?)\.((?:-|ssm\.)?sst|ssm)$/
          @@fnb ||=@fns[m,1]
          @@fnt ||=@fns[m,2]
          unless @@fns =~/\S+?\.zip/
            @@fnz ||=if @@fns =~/(?:\~\S{2,3})?\.(?:ssm\.sst|ssm)$/; @@fnb + '.ssm.zip'
            else @@fnb + '.sst.zip'
            end
          end
        end
      end
      @fnn,@fnb,@fnt,@flv,@fnz=@@fnn,@@fnb,@@fnt,@@flv,@@fnz
    end
    def multilingual
      if defined? @rc['default']['multilingual'] \
      and @rc['default']['multilingual'] != nil
        @rc['default']['multilingual']
      else true
      end
    end
    def document_language_versions_found
      @fn={}
      unless (@fns.nil? \
      or @fns.empty?)
        if multilingual
          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::Standardise_language.new
      langs=lang.codes
      x=[]
      if FileTest.file?("#{@fn[:m]}.#{@fn[:t]}"); x << "#{@fn[:m]}.#{@fn[:t]}"
      end
      x << @fns
      langs.each do |l|
        lng=SiSU_Env::Standardise_language.new(l)
        if FileTest.file?("#{@fn[:m]}~#{lng.code}.#{@fn[:t]}")
          x << "#{@fn[:m]}~#{lng.code}.#{@fn[:t]}"
        elsif FileTest.file?("#{@fn[:m]}~#{lng.name}.#{@fn[:t]}")
          x << "#{@fn[:m]}~#{lng.name}.#{@fn[:t]}"
        end
      end
      @fn[:f]=x.uniq!
      @fn
    end
    def published_manifests?(output_base)
      ob=output_base
      @fn={}
      @m=[]
      unless (@fns.nil? \
      or @fns.empty?)
        if multilingual
          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::Standardise_language.new
      langs=lang.codes
      x=[]
      if FileTest.file?("#{@fn[:m]}.#{@fn[:t]}"); x << "#{@fn[:m]}.#{@fn[:t]}"
      end
      dir=SiSU_Env::Info_env.new(@fns)
      @m << {:m => 'sisu_manifest.html', :l => 'English' } #fix later, default language
      langs.each do |l|
        lng=SiSU_Env::Standardise_language.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::Standardise_language.new.file_to_language(fns_c)
          lng=fn_set_lang[:l]
          fn=SiSU_Env::Env_call.new(fns_c).lang(fn_set_lang[:c])
          @m << {:m => fn[:manifest], :l => lng }
        elsif FileTest.file?(fns_l)
          fn_set_lang=SiSU_Env::Standardise_language.new.file_to_language(fns_l)
          @fnl=dir.i18n.lang_filename(fn_set_lang[:c])
          fn=SiSU_Env::Env_call.new(fns_l).lang(fn_set_lang[:c])
          @m << {:m => fn[:manifest], :l => lng }
        end
      end
      @m.uniq!
      @m
    end
    def filename(code,name,suffix)
      d=SiSU_Env::Info_env.new(@fns)
      fnl=d.i18n.lang_filename(code)
      if code
        "#{fnl[:pre]}#{name}#{fnl[:mid]}#{suffix}#{fnl[:post]}"
      else "#{name}#{suffix}"
      end
    end
    def lang(code)
      @fn={
        :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,'landscape','.pdf'),
        :pdf_p           => filename(code,'portrait','.pdf'),
        :pdf_l_a4        => filename(code,'landscape.a4','.pdf'),
        :pdf_p_a4        => filename(code,'portrait.a4','.pdf'),
        :pdf_l_a5        => filename(code,'landscape.a5','.pdf'),
        :pdf_p_a5        => filename(code,'portrait.a5','.pdf'),
        :pdf_l_b5        => filename(code,'landscape.b5','.pdf'),
        :pdf_p_b5        => filename(code,'portrait.b5','.pdf'),
        :pdf_l_letter    => filename(code,'landscape.letter','.pdf'),
        :pdf_p_letter    => filename(code,'portrait.letter','.pdf'),
        :pdf_l_legal     => filename(code,'landscape.legal','.pdf'),
        :pdf_p_legal     => filename(code,'portrait.legal','.pdf'),
        :toc             => filename(code,'toc','.html'),
        :doc             => filename(code,'doc','.html'),
        :index           => filename(code,'index','.html'),
        :odf             => filename(code,'opendocument','.odt'),
        :epub            => filename(code,@fnb,'.epub'),
        :plain           => filename(code,'plain','.txt'),
        :manpage         => filename(code,@fnb,'.1'),          #fix, section number
        :wiki            => filename(code,'wiki','.txt'),
        :digest          => filename(code,'digest','.txt'),
        :metadata        => filename(code,'metadata','.html'), #chk
        :manifest        => filename(code,'sisu_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'),
      }
      @fn
    end
  end
  class System_call
    @@locale_flag=false
    def initialize(input='',output='',cmd='')
      @input,@output,@cmd=input,output,cmd
      @prog=SiSU_Env::Info_program.new
      @sys=Info_system.instance
    end
    def program_found?(program)
      found=`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=Info_env.new(filename).source_file_with_path
      if program_found?(program)
        encoding=%x{file -L #{fnsp}}.strip
        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 puts "\tWARN: #{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 puts "\tWARN: #{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 puts "\tWARN: #{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 puts "\tWARN: #{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 puts "\tWARN: #{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 puts "\tWARN: #{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"
      if program_found?(program); system("createdb #{dbname_name}")
      else puts "\tWARN: #{program} is not available #{program_ref}"               #if @cmd =~/v/
      end
    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"
      if program_found?(program); system("trang #{@input} #{@output}")
      else                        puts "\tWARN: #{program} is not installed #{program_ref}" if cmd =~/V/
      end
    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
      puts "\tWARN: #{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
      puts "\tWARN: #{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/"
      if program_found?(program); system("#{@prog.tidy} -xml #{@input} > #{@output}")
      else                        puts "\tWARN: #{program} is not installed #{program_ref}"
      end
    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=((@cmd =~/[MVv]/) ? '' : '> /dev/null' )
      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/
          @input =~/landscape\.tex$/ \
          ? %{#{texpdf} -interaction=#{mode} -fmt=xelatex -papersize="#{papersize} -l" #{@input} #{tell}\n} \
          : %{#{texpdf} -interaction=#{mode} -fmt=xelatex  -papersize="#{papersize}"  #{@input} #{tell}\n}
        when /xelatex/
          @input =~/landscape\.tex$/ \
          ? %{#{texpdf} -interaction=#{mode} -papersize="#{papersize} -l" #{@input} #{tell}\n} \
          : %{#{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 puts "\tWARN: none of the following programs are installed: #{program[0]}, #{program[1]}, #{program[2]} is installed. #{program_ref}"
      end
    end
    def makeinfo                                                               #texinfo
      program='makeinfo'
      program_ref="\n\t\tsee http://www.gnu.org/software/texinfo/"
      (program_found?(program)) \
      ? system("#{program} #{@input}\n") \
      : (puts "\tWARN: #{program} is not installed #{program_ref}")
    end
    def scp
      program='scp'
      puts "scp -Cr #{@input} #{@output}" if @cmd =~/[vVM]/
      (program_found?(program)) \
      ? system("scp -Cr #{@input} #{@output}") \
      : (puts "\tWARN: #{program} not found" )
    end
    def rsync(action='')
      program='rsync'
      if program_found?(program)
        vb=if @cmd =~/q/; 'q'
        elsif @cmd =~/v/; 'v'
        else              ''
        end
        msg=''
        msg=" && echo 'OK: #{@input} -> #{@output}'" unless @cmd =~/q/
        puts "rsync -az#{vb} #{action} #{@input} #{@output}" if @cmd =~/[vVM]/
        system("rsync -az#{vb} #{action} #{@input} #{@output} #{msg}")
      else puts "\tWARN: #{program} not found"
      end
    end
    def rm
      if @cmd =~/^-Z[mMvVq]*$/;      rm_rf(@input)
      elsif @cmd =~/V/;              rm(@input)
      elsif @cmd !~/q/;              rm(@input)
      elsif @cmd =~/q/;              rm(@input)
      else                          puts "\tWARN: operation ignored"
      end
    end
  end
  class Standardise_language
    def initialize(l='')
      @language=l
      if @language.empty?
        @language=Info_env.new.defaults[:language]
      end
    end
    def language #use ISO_639-2
      lang={}
      case @language
      when /American|^us$/i;                  d,c,l=false,'en','American English' #depreciated, see iso 639-2
      when /English|^en$/i;                   d,c,l=false,'en','English'
      when /French|Francais|^fr$/i;           d,c,l=false,'fr','French'
      when /German|^de$/i;                    d,c,l=false,'de','German'
      when /Italian|^it$/i;                   d,c,l=false,'it','Italian'
      when /Spanish|Espanol|^es$/i;           d,c,l=false,'es','Spanish'
      when /Brazilian(?: Portuguese)?|^br$/i; d,c,l=false,'pt','Brazilian Portuguese' #depreciated, see iso 639-2
      when /Portuguese|^pt$/i;                d,c,l=false,'pt','Portuguese'
      when /Swedish|Svensk|^sv$/i;            d,c,l=false,'sv','Swedish'
      when /Danish|Dansk|^da$/i;              d,c,l=false,'da','Danish'
      when /Finnish|Finsk|Suomi|^fi$/i;       d,c,l=false,'fi','Finnish'
      when /Norwegian|Norsk|^no$/i;           d,c,l=false,'no','Norwegian'
      when /Icelandic|^is$/i;                 d,c,l=false,'is','Icelandic'
      when /Dutch|^nl$/i;                     d,c,l=false,'nl','Dutch'
      when /Estonian|^et$/i;                  d,c,l=false,'et','Estonian'
      when /Hungarian|^hu$/i;                 d,c,l=false,'hu','Hungarian'
      when /Polish|^pl$/i;                    d,c,l=false,'pl','Polish'
      when /Romanian|^ro$/i;                  d,c,l=false,'ro','Romanian'
      when /Russian|^ru$/i;                   d,c,l=false,'ru','Russian'
      when /Greek|^el$/i;                     d,c,l=false,'el','Greek'
      when /Ukranian|^uk$/i;                  d,c,l=false,'uk','Ukranian'
      when /Turkish|^tr$/i;                   d,c,l=false,'tr','Turkish'
      #when /Serbian/i;                       d,c,l=false,'', 'Serbian'
      #when /Welsh/i;                         d,c,l=false,'', 'Welsh'
      #when /Basque/i;                        d,c,l=false,'', 'Basque'
      #when /Breton/i;                        d,c,l=false,'', 'Breton'
      #when /Catalan/i;                       d,c,l=false,'', 'Catalan'
      #when /Galician/i;                      d,c,l=false,'', 'Galician'
      #when /Saa?mi/i;                        d,c,l=false,'', 'Saami'
      #when /Hebrew/i;                        d,c,l=false,'', 'Hebrew'
      #when /Latin/i;                         d,c,l=false,'', 'Latin'
      #when /Esperanto/i;                     d,c,l=false,'', 'Esperanto'
      when /Slovenian|^sl$/i;                 d,c,l=false,'sl','Slovenian'
      when /Croatian|^hr$/i;                  d,c,l=false,'hr','Croatian'
      when /Slovak(?:ian)?|^sk$/i;            d,c,l=false,'sk','Slovakian'
      when /Czech|^cs$/i;                     d,c,l=false,'cs','Czech'
      when /Bulgarian|^bg$/i;                 d,c,l=false,'bg','Bulgarian'
      else                                    d,c,l=true,'en','English (default)'
      #else                                   d,c,l=true,'xx','Default'
      end
      lang[:d],lang[:c],lang[:l]=d,c,l
      lang
    end
    def name
      language[:l].downcase
    end
    def title
      language[:l]
    end
    def code
      language[:c]
    end
    def file_to_language(file)
      m=/.+?\~(\w{2,3})\.(?:-|ssm\.)?sst$/
      @language=if file =~m ; file[m,1]
      else ''
      end
      language
    end
    def codes
      codes=['us','en','fr','de','it','es','br','pt','sv','da','fi','no','is','nl','et','hu','pl','ro','ru','el','uk','tr','sk','hr','sl','cs','bg'] # remove us and br see iso-639-2
    end
  end
  class Info_env < Env_call
    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!
      @fns,@md=fns,md
      @env=Env_call.new(fns) if fns
      fnb=if @md \
      and defined? @md.fnb
        @md.fnb
      elsif defined? @env.fnb \
      and @env.fnb
        @env.fnb
      elsif not @fns.nil? \
      and not @fns.empty?
        m=/(.+)?\.(?:(?:-|ssm\.)?sst|ssm)$/m
        @fns[m,1] if not @fns.empty?
      end
      if fnb; @@fb ||=fnb
      end
      @sys=Info_system.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_epub=@stub_pwd + '/epub'
      @stub_src=@stub_pwd + '/src'
      @stub_pod=@stub_pwd + '/pod'
      @stub_md=@stub_pwd + '/sisu_site_metadata'
    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 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
      @stub_md
    end
    def stub_src
      @stub_src
    end
    def stub_pod
      @stub_pod
    end
    def sisupod
      #path.processing
      #  sisupod
      #    sisu
      #      content.sst              [file content]
      #      filename.sst             [link to content.sst]
      #      _sisu
      #        conf
      #          skin/
      #            doc                [relevant skin if any other than default]
      #        image                  [all images for specific document gathered here]
      sisupod_processing_path="#{path.processing}/sisupod"
      if FileTest.directory?(sisupod_processing_path) \
      or FileTest.file?(sisupod_processing_path)
        rm_rf(sisupod_processing_path)
      end
      paths=[]
      paths=["#{path.processing}/sisupod/_sisu/skin/doc","#{path.processing}/sisupod/_sisu/skin/dir","#{path.processing}/sisupod/_sisu/skin/site","#{path.processing}/sisupod/_sisu/image"]
      paths.each {|x| mkdir_p(x) unless FileTest.directory?(x) }
    end
    def defaults #multiple default directories
      @default_dir ||=@sys.default_dir #DEFAULT_DIR
    end
    def manifest_minitoc?
      flag=if defined? @rc['manifest']['minitoc'] \
      and not @rc['manifest']['minitoc'].nil?
        @rc['manifest']['minitoc']
      else false
      end
    end
    def widget #needs (md) #move
      @rc=SiSU_Env::Get_init.instance.yamlrc
      @ad=SiSU_Env::Get_init.instance.ads
      @vz=SiSU_Env::Get_init.instance.skin
      @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.class==Array \
        and @vz.widget_promo.length > 0
          @flag[:sk]=true
          true
        elsif defined? @rc['promo'] \
        and not @rc['promo'].nil? \
        and @rc['promo'].length > 0
          @flag[:rc]=true
          true
        else false
        end
        @flag
      end
      def search?
        searches=['sisu','hyperestraier']
        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::Get_init.instance.yamlrc
        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::Get_init.instance.yamlrc
        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
        action=if search?
        else ''
        end
      end
      self
    end
    def widget_static
      @rc=SiSU_Env::Get_init.instance.yamlrc
      @vz=SiSU_Env::Get_init.instance.skin
      @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+/ \
        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::Get_init.instance.yamlrc
        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
        action=if search?
        else ''
        end
      end
      self
    end
    def source_file_path
      file=@fns.gsub(/\.ssm(?:\.sst)?/,'.ssm.sst')
      pth=unless file =~/\.ssm\.sst$/; "#{Dir.pwd}"
      else "#{path.composite_file}"
      end
    end
    def source_file_with_path
      file=@fns.gsub(/\.ssm(?:\.sst)?/,'.ssm.sst')
      "#{source_file_path}/#{file}"
    end
    def read_source_file(fns)
      fns_array=if RUBY_VERSION < '1.9'
        x=unless fns =~/\.ssm.sst$/
          IO.readlines(fns,'')
        else IO.readlines("#{path.composite_file}/#{fns}",'')
        end
      else #ruby version >= '1.9'
        x=unless fns =~/\.ssm.sst$/
          IO.readlines(fns,'r:utf-8')
        else IO.readlines("#{path.composite_file}/#{fns}",'r:utf-8')
        end
      end
    end
    def font
      def texpdf
        (defined? @rc['default']['texpdf_font']) \
        && (@rc['default']['texpdf_font']=~/\S{3,}/)  \
        ? @rc['default']['texpdf_font'] \
        : 'Liberation Sans' #'Liberation Sans' #'Liberation Serif'
      end
      self
    end
    def path                                                                     #dir
      def home
        @sys.home
      end
      def pwd
        @sys.pwd
      end
      def stub_pwd
        @stub_pwd
      end
      def stub_epub
        @stub_epub
      end
      def stub_src
        @stub_src
      end
      def stub_pod
        @stub_pod
      end
      def stub_md_harvest
        @stub_md
      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
        defaults[:stylesheet_stub]
      end
      def sample_data                                                          #sample data repository source directory
        defaults[:sample_data_path]
      end
      def rc
        @sys.rc_path
      end
      def yamlrc
        rc.each do |v|
          if FileTest.exist?("#{v}/sisurc.yml")
            @yamlrc_dir="#{v}/sisurc.yml"
            break
          end
        end
        unless @yamlrc_dir
          rc.each do |v|
            if FileTest.exist?("#{v}/sisurc.yaml")
              @yamlrc_dir="#{v}/sisurc.yaml"
              break
            end
          end
        end
        @yamlrc_dir
      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+/
            man_path=@@man_path=File.expand_path(@rc['webserv']['path'])
          else defaults[:webserv_path]
          end
        else @@man_path
        end
        man_path_head=man_path.gsub(/(\S+)\/[^\/\s]+$/,'\1')
        unless FileTest.directory?(man_path)
          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])
            mkdir_p(defaults[:output_local])
          end
          defaults[:output_local]
        end
      end
      def webserv_stub_ensure
        mkdir_p(path.webserv) unless FileTest.directory?(path.webserv)
        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
        "#{path.webserv}/#{@stub_pwd}"
      end
      def output_src
        "#{path.output}/src"
      end
      def output_md_harvest
        "#{path.output}/sisu_site_metadata"
      end
      def output_pod
        "#{path.output}/pod"
      end
      def output_epub
        "#{path.output}/epub"
      end
      def output_harvest
        "#{path.output}/sisu_site_metadata"
      end
      def manpage
        "#{path.output}/man"
      end
      def sitemaps
        "#{path.output}/sitemaps"
      end
      def encoding
        pth="#{processing}/#{defaults[:processing_encoding]}"
        mkdir_p(pth) unless FileTest.directory?(pth)
        pth
      end
      def processing_base_tmp
        defaults[:processing_path_tmp_base]
      end
      def processing_dir_tmp_root
        defaults[:processing_dir_tmp_root]
      end
      def processing_path_root
        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
        path=if proposed_path_base \
        and FileTest.directory?(proposed_path_base) \
        and File.writable?("#{proposed_path_base}/.")
          x=if proposed_dir
            "#{proposed_path_base}/#{proposed_dir}"
          else
            "#{proposed_path_base}/#{defaults[:processing_dir]}"
          end
        else defaults[:processing_dir_tmp_root]
        end
      end
      def processing_path_usr?
        case processing_path_root
        when /^\/home/; false
        else true
        end
      end
      def processing_path
        (processing_path_usr?) \
        ? ("#{processing_path_root}/#{user}/#{stub_pwd}") \
        : ("#{processing_path_root}/#{stub_pwd}") # see defaults[:processing_path]
      end
      def processing                                                             #processing directory, used/needed for sisu work files, has sub-directories (dal,tex etc)
        unless FileTest.directory?(processing_path_root)
          mkdir_p(processing_path_root)
          File.chmod(0777,processing_path_root)
        end
        if processing_path_usr?
          processing_path_usr="#{processing_path_root}/#{user}"
          mkdir_p(processing_path_usr) unless FileTest.directory?(processing_path_usr)
          File.chmod(0700,processing_path_usr)
        end
        mkdir_p(processing_path) unless FileTest.directory?(processing_path)
        File.chmod(0700,processing_path)
        path_processing=[processing_path,defaults[:processing_path],defaults[:processing_path_home]]
        processing=nil
        path_processing.each do |v|                                              #
          processing=v
          unless FileTest.directory?(processing)
            puts "a processing directory (#{processing}) is being created for use by sisu"
            mkdir_p(processing)
            File.chmod(0700,processing)
          end
          break
        end
        processing
      end
      def processing_path_git
        proposed_dir=if defined? @rc['git']['dir'] \
        and not @rc['git']['dir'].nil? \
        and not @rc['git']['dir'].empty?
          x=(@rc['git']['dir'] =~/^(?:~|home)$/) \
          ? home + '/' + 'sisu:' \
          : @rc['git']['dir'] + '/' + 'sisu:'
        else defaults[:processing_git]
        end
      end
      def processing_git
        unless FileTest.directory?(processing_path_git)
          mkdir_p(processing_path_git)
          File.chmod(0700,processing_path_git)
        end
        processing_path_git
      end
      def epub
        "#{processing}/epub/#{@fnb}"
      end
      def sql
        pth="#{processing}/sql"
        mkdir_p(pth) unless FileTest.directory?(pth)
        pth
      end
      def composite_file
        pth=path.dal  #"#{processing}/composite"
        mkdir_p(pth) unless FileTest.directory?(pth)
        pth
      end
      def dal
        pth=if defined? @rc['processing']['dal'] \
          and not @rc['processing']['dal'].nil? \
          and not @rc['processing']['dal'].empty?
          "#{processing}/#{@rc['processing']['dal']}"
        else "#{processing}/#{defaults[:processing_dal]}"
        end
        mkdir_p(pth) unless FileTest.directory?(pth)
        pth
      end
      def tune
        pth=if defined? @rc['processing']['tune'] \
          and not @rc['processing']['tune'].nil? \
          and not @rc['processing']['tune'].empty?
          "#{processing}/#{@rc['processing']['tune']}"
        else "#{processing}/#{defaults[:processing_tune]}"
        end
        mkdir_p(pth) unless FileTest.directory?(pth)
        pth
      end
      def odf #_bld
        pth="#{processing}/odf"
        mkdir_p(pth) unless FileTest.directory?(pth)
        pth
      end
      def odf_bld
        rm_rf(path.odf)
        mkdir_p(path.odf) unless FileTest.directory?(path.odf)
        mkdir_p("#{path.odf}/Configurations2") unless FileTest.directory?("#{path.odf}/Configurations2")
        mkdir_p("#{path.odf}/META-INF") unless FileTest.directory?("#{path.odf}/META-INF")
        mkdir_p("#{path.odf}/Pictures") unless FileTest.directory?("#{path.odf}/Pictures")
        mkdir_p("#{path.odf}/Thumbnails") unless FileTest.directory?("#{path.odf}/Thumbnails")
        path.odf
      end
      def epub_bld
        mkdir_p(path.epub) unless FileTest.directory?(path.epub)
        mkdir_p("#{path.epub}/META-INF") unless FileTest.directory?("#{path.epub}/META-INF")
        mkdir_p("#{path.epub}/OPS/image") unless FileTest.directory?("#{path.epub}/OPS/image")
        mkdir_p("#{path.epub}/OPS/css") unless FileTest.directory?("#{path.epub}/OPS/css")
        images=%W[bullet_09.png arrow_next_red.png arrow_prev_red.png arrow_up_red.png]
        path.epub
      end
      def epub_cp_images(md)
        pth="#{path.epub}/OPS/image"
        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
          cp("#{src}/#{i}","#{pth}/#{i}") unless FileTest.file?("#{pth}/#{i}")
        end
        pth
      end
      def tex
        pth=if defined? @rc['processing']['latex'] \
        and not @rc['processing']['latex'].nil? \
        and not @rc['processing']['latex'].empty?
          "#{processing}/#{@rc['processing']['latex']}"
        else "#{processing}/#{defaults[:processing_latex]}"
        end
        mkdir_p(pth) unless FileTest.directory?(pth)
        pth
      end
      def texi
        pth=if defined? @rc['processing']['texinfo'] \
        and not @rc['processing']['texinfo'].nil? \
        and not @rc['processing']['texinfo'].empty?
          "#{processing}/#{@rc['processing']['texinfo']}"
        else "#{processing}/#{defaults[:processing_texinfo]}"
        end
        mkdir_p(pth) unless FileTest.directory?(pth)
        pth
      end
      def texinfo                                                                #texinfo webserv, check
        "#{processing}/#{defaults[:processing_texinfo]}"
      end
      def lout
        pth=if defined? @rc['processing']['lout'] \
        and not @rc['processing']['lout'].nil? \
        and not @rc['processing']['lout'].empty?
          "#{processing}/#{@rc['processing']['lout']}"
        else "#{processing}/#{defaults[:processing_lout]}"
        end
        mkdir_p(pth) unless FileTest.directory?(pth)
        pth
      end
      def sqlite
        pth=if defined? @rc['processing']['sqlite'] \
        and not @rc['processing']['sqlite'].nil? \
        and not @rc['processing']['sqlite'].empty?
          "#{processing}/#{@rc['processing']['sqlite']}"
        else "#{processing}/#{defaults[:processing_sqlite]}"
        end
        mkdir_p(pth) unless FileTest.directory?(pth)
        pth
      end
      def postgresql
        pth=if defined? @rc['processing']['postgresql'] \
        and not @rc['processing']['postgresql'].nil? \
        and not @rc['processing']['postgresql'].empty?
          "#{processing}/#{@rc['processing']['postgresql']}"
        else "#{processing}/#{defaults[:processing_postgresql]}"
        end
        mkdir_p(pth) unless FileTest.directory?(pth)
        pth
      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
        image_path=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_tex                                                       #image repository source directory
        image_path=if defined? @rc['image']['path'] \
        and defined? @rc['image']['public']
          pth="#{@rc['image']['path']}"
          "#{pth}/#{@rc['image']['public']}"
        else
          image=defaults[:image_stub]
          "#{share}/image"
        end
      end
      def image_external
        "#{processing}/external_document/image"
      end
      def image_source_local_tex
        if FileTest.directory?(defaults[:image_local]); defaults[:image_local]
        end
      end
      def image_source_remote_tex
        if FileTest.directory?(image_external); image_external
        end
      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 epub
        "#{root}/epub"
      end
      def src_txt
        "#{root}/src"
      end
      def src_pod
        "#{root}/pod"
      end
      def webserv_host_base
        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 webrick_port
        if @md \
        and @md.cmd.inspect=~/-F/ \
        and @md.mod.inspect=~/port=(\d+)/
           $1
        else
          if defined? @rc['webserv_cgi']['port']
            if @rc['webserv_cgi']['port'].nil? \
            and (defined? @md.mod \
            and not @md.mod.nil? \
            and @md.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
        if @md \
        and @md.cmd.inspect=~/-F/ \
        and @md.mod.inspect=~/port=(\d+)/
           $1
        else
          if defined? @rc['webserv_cgi']['port']
            if @rc['webserv_cgi']['port'].nil? \
            and (defined? @md.mod \
            and not @md.mod.nil? \
            and @md.mod.inspect=~/webrick/)
              defaults[:webserv_port_cgi]
            elsif not @rc['webserv_cgi']['port'].nil?
              @rc['webserv_cgi']['port']
            else nil
            end
          else   nil
          end
        end
      end
      def webserv_cgi                                                          #web url for local webserv (localhost, or hostname)
        if defined? @rc['webserv_cgi']['host'] \
        and not @rc['webserv_cgi']['host'].nil?
          http=((@rc['webserv_cgi']['host'] =~ /https?:\/\//) ? '' : 'http://') #check https? missing
          if webserv_port_cgi
            "#{http}#{@rc['webserv_cgi']['host']}:#{webserv_port_cgi}/#{@stub_pwd}"
          else "#{http}#{@rc['webserv_cgi']['host']}/#{@stub_pwd}"
          end
        else
          http=((webserv_host_base=~/https?:\/\//) ? '' : 'http://')
          if webserv_port_cgi
            "#{http}#{webserv_host_base}:#{webserv_port_cgi}/#{@stub_pwd}"
          else "#{http}#{webserv_host_base}/#{@stub_pwd}"
          end
        end
      end
      def webserv_base_cgi                                                     #web url for local webserv (localhost, or hostname)
        if defined? @rc['webserv_cgi']['host'] \
        and not @rc['webserv_cgi']['host'].nil?
          http=((@rc['webserv_cgi']['host'] =~ /https?:\/\//) ? '' : 'http://')
          if webserv_port_cgi
            "#{http}#{@rc['webserv_cgi']['host']}:#{webserv_port_cgi}"
          else "#{http}#{@rc['webserv_cgi']['host']}"
          end
        else
          http=((webserv_host_base=~/https?:\/\//) ? '' : 'http://')
          if webserv_port_cgi
            "#{http}#{webserv_host_base}:#{webserv_port_cgi}"
          else "#{http}#{webserv_host_base}"
          end
        end
      end
      def webrick #must have a port #REMOVE
        if defined? @rc['webserv_cgi']['host'] \
        and not @rc['webserv_cgi']['host'].nil?
          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 not webserv_host_base.nil?
          "#{http}#{webserv_host_base}"
        else "#{http}localhost" end
      end
      def webserv                                                              #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}/#{@stub_pwd}")
        elsif defined? @rc['webserv']['webrick_url'] \
        and @rc['webserv']['webrick_url']==false
          "file://#{path.webserv}/#{@stub_pwd}"
        elsif webserv_port_cgi =~/\S+/
          "#{url.hostname}:#{webserv_port_cgi}/#{@stub_pwd}"
        else "#{url.hostname}/#{@stub_pwd}"
        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 #sort this out, messy
        if defined? @rc['webserv_cgi']['file_links']
          case @rc['webserv_cgi']['file_links']
          when /webserv_cgi/; url.webserv_base_cgi
          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
          end
        else                  webserv_base_cgi
        end
      end
      def sample_search_form_title
        if defined? @rc['search']['sisu']['title'] \
        and @rc['search']['sisu']['title'] =~/\S+/
          @rc['search']['sisu']['title']
        else %{(SiSU (generated sample) search form}
        end
      end
      def output_tell
        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
        output=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
        '../_sisu/image'
      end
      def images_local
        if FileTest.directory?(defaults[:image_local])
          if @@image_flag
            images=Dir.glob("#{defaults[:image_local]}/*.{png,jpg,gif}")
            pth="#{path.webserv}/#{@stub_pwd}"
            mkdir_p("#{pth}/_sisu/image") unless FileTest.directory?("#{pth}/_sisu/image")
            images.each { |i| File.install(i,"#{pth}/#{i}") } unless images.length > 0
            @@image_flag=false
          end
          '../_sisu/image'
        else
          if @@local_image==true
            cmd=if @cmd; @cmd
            else ''
            end
            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}"
            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
          '../_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 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' 'links2' 'elinks' 'epiphany'
        end
      end
      def console_www_browser
        web_browser
      end
      def epub_viewer
        if defined? @rc['program_select']['epub_viewer'] \
        and @rc['program_select']['epub_viewer'] =~/\S\S+/
          @rc['program_select']['epub_viewer']
        elsif defined? @rc['program_select']['epub_viewer'] \
        and @rc['program_select']['epub_viewer'] =~/\S\S+/
          @rc['program_select']['epub_viewer']
        else 'ebook-viewer'                                                            #'calibre' 'fbreader'
        end
      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 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::Standardise_language.new(l)
      end
      def multilingual
        ((defined? @rc['default']['multilingual']) \
        && @rc['default']['multilingual'] != nil) \
        ? @rc['default']['multilingual'] \
        : (defaults[:multilingual])
      end
      def lang_filename(l)
        @lang={}
        x=if multilingual
          (( 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
      rm_rf("#{path.processing}/odf")
      system("unzip -q #{path.share}/#{SiSU_version_dir}/odf/odt.zip -d      #{path.processing}")
    end
    def sisupod_gen(fns_pod)
      pwd=Dir.pwd
      sisupod_processing_path="#{path.processing}/sisupod"
      if FileTest.directory?(sisupod_processing_path) \
      or FileTest.file?(sisupod_processing_path)
        rm_rf(sisupod_processing_path)
      end
      unless FileTest.directory?(sisupod_processing_path)
        mkdir_p(sisupod_processing_path)
      end
      if FileTest.file?("#{Dir.pwd}/#{fns_pod}")
        system("unzip -q #{Dir.pwd}/#{fns_pod} -d #{path.processing}")
      else
        SiSU_Screen::Ansi.new('',"file not found: #{fns_pod}").warn unless @cmd=~/q/
      end
      sisupod_processing_path
    end
  end
  class Info_processing_flag
    attr_accessor :color,:cf_0,:cf_1,:cf_2,:cf_3,:cf_4,:cf_5
    def initialize
      @rc=Get_init.instance.yamlrc
    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 not (@rc['flag']['default'].nil? \
      or @rc['flag']['default'].empty?)
        @rc['flag']['default']
      else                               '-NhwepoabxXyYv'
      end
    end
    def cf_1                                                                   #processing flag shortcuts
      if defined? @rc['flag']['i'] \
      and not (@rc['flag']['i'].nil? \
      or @rc['flag']['i'].empty?)
        @rc['flag']['i']
      else                               '-hwepoay'
      end
    end
    def cf_2                                                                   #processing flag shortcuts
      if defined? @rc['flag']['ii'] \
      and not (@rc['flag']['ii'].nil? \
      or @rc['flag']['ii'].empty?)
        @rc['flag']['ii']
      else                               '-NhwepoabxXy'
      end
    end
    def cf_3                                                                   #processing flag shortcuts
      if defined? @rc['flag']['iii'] \
      and not (@rc['flag']['iii'].nil? \
      or @rc['flag']['iii'].empty?)
        @rc['flag']['iii']
      else                               '-NhwepoabxXyY'
      end
    end
    def cf_4                                                                   #processing flag shortcuts
      if defined? @rc['flag']['iv'] \
      and not (@rc['flag']['iv'].nil? \
      or @rc['flag']['iv'].empty?)
        @rc['flag']['iv']
      else                               '-NhwepoabxXDyY --update'
      end
    end
    def cf_5                                                                   #processing flag shortcuts
      if defined? @rc['flag']['v'] \
      and not (@rc['flag']['v'].nil? \
      or @rc['flag']['v'].empty?)
        @rc['flag']['v']
      else                               '-NhwepoabxXDyYv --update'
      end
    end
  end
  class Info_settings < Info_env
    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 File_map < Info_env
    attr_accessor :local_sisu_source
    def initialize(opt='') #watch
      super()
      @opt=opt #,opt.fns,opt.cmd
      @env=(@opt.fns && !(@opt.fns.empty?) \
      ? (SiSU_Env::Info_env.new(@opt.fns)) \
      : (SiSU_Env::Info_env.new('dummy.sst')))
      if @opt.cmd =~/m/; @md=SiSU_Param::Parameters.new(@opt).get
      end
      ft=[]
      if @md \
      and defined? @md.fn \
      and @md.fn        # used for multilingual
        if @md.cmd =~ /[hH]/
          ft << @md.fn[:html]
        end
        if @md.cmd =~ /w/ \
        and @md.cmd !~ /[hH]/
          ft << @md.fn[:concordance]
        end
        if @md.cmd =~ /y/ \
        and @md.cmd !~ /[hH]/
          ft << @md.fn[:manifest]
        end
        if @md.cmd =~ /[at]/; ft << @md.fn[:plain]
        end
        if @md.cmd =~ /b/; ft << @md.fn[:xhtml]
        end
        if @md.cmd =~ /e/; ft << @md.fn[:epub]
        end
        if @md.cmd =~ /g/; ft << @md.fn[:wiki]
        end
        if @md.cmd =~ /i/; ft << @md.fn[:manpage]
        end
        if @md.cmd =~ /N/; ft << @md.fn[:digest]
        end
        if @md.cmd =~ /o/; ft << @md.fn[:odf]
        end
        if @md.cmd =~ /O/; ft << @md.fn[:oai_pmh]
        end
        if @md.cmd =~ /p/; ft << @md.fn[:pdf_l] << @md.fn[:pdf_p]
        end
        if @md.cmd =~ /s/; ft << @md.fns
        end
        if @md.cmd =~ /S/; ft << @md.fn[:sisupod] << '.kdi'
        end
        if @md.cmd =~ /x/; ft << @md.fn[:sax]
        end
        if @md.cmd =~ /X/; ft << @md.fn[:dom]
        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}/sisu_site_metadata" \
      : @env.path.output_harvest)
      @local_sisu_source=(@filetypes =~/\S/) \
      ? "#{@source_path}/#{@filetypes}" \
      : @source_path
    end
  end
  class Clean_output
    require 'fileutils'
      include FileUtils::Verbose
    def initialize(opt)
      @opt=opt
      z=File_map.new(@opt)
      @zap=z.local_sisu_source
      if @opt.cmd =~ /[hH]/
        @zap=Dir.glob(@zap).join(' ')
        if @opt.cmd !~ /w/; @zap.gsub!(/#{@source_path}\/concordance.html/,'')
        end
      end
      @env=SiSU_Env::Info_env.new
    end
    def zap
      def main_output
        (@zap !~/\/\//) \
        ? (rm_rf(@zap) if FileTest.directory?(@zap)) \
        : (puts 'suspect zap request, ignored')
      end
      def site_map
        if @opt.fnb \
        and not @opt.fnb.empty?
          sm="#{@env.path.output}/sitemaps/sitemap_#{@opt.fnb}.xml"
          rm(sm) if FileTest.file?(sm)
        end
      end
      def epub
        if @opt.fnb \
        and not @opt.fnb.empty?
          sm="#{@env.path.output}/epub/#{@opt.fnb}.epub"
          rm(sm) if FileTest.file?(sm)
        end
      end
      def src # consider
        if @opt.fnb \
        and not @opt.fnb.empty?
          sm="#{@env.path.output}/pod/#{@opt.fns}.zip"
          rm(sm) if FileTest.file?(sm)
          sm="#{@env.path.output}/src/#{@opt.fns}"
          rm(sm) if FileTest.file?(sm)
        end
      end
      self
    end
  end
  class Info_remote_host
    def initialize
      @rc=Get_init.instance.yamlrc
    end
    def remote_host #see Info_remote remote_host_base_general
      r=[]
      r=if (defined? @rc['remote'] \
      and @rc['remote'].class==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'].class==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::Info_remote_host.new.remote_host[0][:name]) \
        ? (SiSU_Env::Info_remote_host.new.remote_host[0][:name]) \
        : nil
      end
      def r2
        (defined? SiSU_Env::Info_remote_host.new.remote_host[1][:name]) \
        ? (SiSU_Env::Info_remote_host.new.remote_host[1][:name]) \
        : nil
      end
      def r3
        (defined? SiSU_Env::Info_remote_host.new.remote_host[2][:name]) \
        ? (SiSU_Env::Info_remote_host.new.remote_host[2][:name]) \
        : nil
      end
      def r4
        (defined? SiSU_Env::Info_remote_host.new.remote_host[3][:name]) \
        ? (SiSU_Env::Info_remote_host.new.remote_host[3][:name]) \
        : nil
      end
      def r5
        (defined? SiSU_Env::Info_remote_host.new.remote_host[4][:name]) \
        ? (SiSU_Env::Info_remote_host.new.remote_host[4][:name]) \
        : nil
      end
      def r6
        (defined? SiSU_Env::Info_remote_host.new.remote_host[5][:name]) \
        ? (@ls + SiSU_Env::Info_remote_host.new.remote_host[5][:name]) \
         : nil
      end
      self
    end
  end
  class Info_remote < File_map
    @@flag_remote=false
    require 'socket'
    def initialize(opt)
      super(opt) #
      @opt=opt
      @rc=Get_init.instance.yamlrc
    end
    def remote_host_base_general
      SiSU_Env::Info_remote_host.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
      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.zip')
        if (local_gen =~/\S/ \
        and local_gen !~/\/\//) \
        and (remote_gen =~/\S/ \
        and remote_gen !~/\/\//) \
        and @@flag_remote==true \
        and @opt.cmd !~/U/
          System_call.new(local_gen,remote_gen).scp
          if FileTest.file?("#{local_src}/#{src_txt}")
            System_call.new("#{local_src}/#{src_txt}",remote_src).scp
          end
          if FileTest.file?("#{local_pod}/#{src_pod}")
            System_call.new("#{local_src}/#{src_pod}",remote_pod).scp
          end
          if FileTest.file?("#{local_epub}/#{@opt.fnb}.epub")
            System_call.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}.zip")
            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 rsync
      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_images="#{remote_conn[:name]}/#{@env.path.stub_pwd}/_sisu/image/."
        remote_images_external="#{remote_conn[:name]}/#{@env.path.stub_pwd}/_sisu/image_external/."
        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.zip')
        if (local_gen =~/\S/ \
        and local_gen !~/\/\//) \
        and (remote_gen =~/\S/ \
        and remote_gen !~/\/\//) \
        and @@flag_remote==true \
        and @opt.cmd !~/U/
          delete_extra_files='--delete' # '--delete-after'
          System_call.new(local_gen,remote_gen,@opt.cmd).rsync(delete_extra_files)
          if FileTest.file?("#{local_src}/#{src_txt}")
            System_call.new("#{local_src}/#{src_txt}",remote_src,@opt.cmd).rsync
            if defined? @md.ec[:image] and not @md.ec[:image].empty?
              images="#{local_gen_image}/" + @md.ec[:image].join(" #{local_gen_image}/")
              System_call.new(images,remote_images,@opt.cmd).rsync
              images_external="#{local_gen_image_external}/" + @md.ec[:image].join(" #{local_gen_image_external}/")
              System_call.new(images_external,remote_images_external,@opt.cmd).rsync
            end
          end
          if FileTest.file?("#{local_epub}/#{@opt.fnb}.epub")
            System_call.new("#{local_epub}/#{@opt.fnb}.epub",remote_epub,@opt.cmd).rsync
          end
          if FileTest.file?("#{local_pod}/#{src_pod}")
            System_call.new("#{local_pod}/#{src_pod}",remote_pod,@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}.zip")
            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
    def scp_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}"
          System_call.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 scp_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}"
          System_call.new("#{local}/_sisu/image_sys/",remote).scp
          System_call.new("#{local}/_sisu/image/",remote).scp
          System_call.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
    def rsync_base                                                             #base site
      ldest="#{@env.path.webserv}/#{@env.path.stub_pwd}/_sisu"
      image_sys="#{@env.path.webserv}/_sisu/image_sys"
      images="#{@env.path.webserv}/_sisu/image"
      self.remote_host_base.each do |remote_conn|
        remote="#{remote_conn[:name]}/#{@env.path.stub_pwd}/."
        remote_conf="#{remote_conn[:name]}/_sisu"
        if defined? @rc['permission_set']['remote_base_site'] \
        and @rc['permission_set']['remote_base_site'] \
        and @@flag_remote==true \
        and @opt.cmd !~/U/
          System_call.new("#{image_sys}","#{remote_conf}").rsync
          System_call.new("#{images}","#{remote_conf}").rsync
          System_call.new("#{ldest}","#{remote}").rsync
        elsif @opt.cmd =~/U/
          puts "#{__FILE__} #{__LINE__}" if @opt.cmd =~/M/
          puts "rsync_base: #{local} -> #{remote}"
          puts "#{local}/_sisu/image -> #{remote}"
          puts "#{local}/_sisu/image_sys/ -> #{remote}"
          puts "#{local}/#{@env.path.style}/ -> #{remote}"
        else  puts "permission not granted #{__FILE__} #{__LINE__}" if @opt.cmd =~/M/
        end
      end
    end
    def rsync_base_sync                                                        #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/
          delete_extra_files='--delete' # '--delete-after'
          puts "begin rsync_base_sync: #{local} -> #{remote}"
          System_call.new("#{local}/_sisu/image_sys/",remote).rsync(delete_extra_files)
          System_call.new("#{local}/_sisu/image/",remote).rsync(delete_extra_files)
          System_call.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
    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'
          System_call.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
    def rsync_harvest
      self.remote_host_base.each do |remote_conn|
        local=@source_path_harvest
        remote="#{remote_conn[:name]}/#{@env.path.stub_pwd}/."
        if @@flag_remote
          delete_extra_files='--delete' # '--delete-after'
          System_call.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 Info_version <Info_env
    include Singleton
    require 'rbconfig'
    @@lib_path=nil
    def get_version
      @version={}
      @pwd=ENV['PWD']
      yst_ver="#{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 Create_system_link #< Info_env                                          #revisit problems created 2004w41
    def initialize
      @env=SiSU_Env::Info_env.new
    end
    def images
      unless FileTest.directory?("#{@env.path.output}/_sisu")
        mkdir_p("#{@env.path.output}/_sisu")
      end
      unless File.exist?("#{@env.path.output}/_sisu/image_sys") \
      or File.symlink?("#{@env.path.output}/_sisu/image_sys")
        File.symlink("../../_sisu/image_sys", "#{@env.path.output}/_sisu/image_sys")
      end
    end
    def man_forms
      #File.symlink("../../man/form", "#{@env.path.output}/man/form") unless File.symlink?("#{@env.path.output}/man/form")==true
    end
    def man_pdf
      #File.symlink("../../man/form", "#{@env.path.output}/man/pdf") unless File.symlink?("#{@env.path.output}/man/pdf")==true
    end
  end
  class Info_file < Info_env
    def initialize(fns='')
      @env=SiSU_Env::Info_env.new
      @fns=fns
    end
    def basefilename
      m=/(.+?)\.(?:(?:-|ssm\.)?sst|ssm)$/m
      fnb=@fns[m,1]
    end
    def project
      "#{@env.development}/sisu.lnk"
    end
    def project_info
      "#{@env.datapriv_i}/sisu.er3"
    end
    def project_todo
      "#{@env.development}/todo.txt"
    end
    def admin_self
      "#{@env.path.home}/.corundum/dots.lnk"
    end
    def admin_root
      '/root/.corundum/admin.txt'
    end
  end
  class Info_db < Info_env
    @@rc=nil
    def initialize
      @@pwd ||=Dir.pwd
      @pwd=Dir.pwd
      @env=SiSU_Env::Info_env.new
      m=/.+\/(?:src\/)?(\S+)/m # m=/.+?\/(?:src\/)?([^\/]+)$/im # m=/.+\/(\S+)/m
      @pwd_stub=@pwd[m,1]
      @rc=@@rc ||=Get_init.instance.yamlrc
      @defaults=Info_env.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
        ((defined? @rc['db']['postgresql']['user']) \
        && @rc['db']['postgresql']['user']=~/\S+/) \
        ? @rc['db']['postgresql']['user'] \
        : @env.user
      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'].class==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 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 Info_port < Info_env
    def initialize
      @env=SiSU_Env::Info_env.new
    end
    def webrick
      @env.url.webrick_port
    end
  end
  class Info_program < Info_env                                                #revisit
    attr_accessor :editor,:wc,:tidy,:rexml,:pdflatex,:postgresql,:sqlite
    def initialize
      prog=SiSU_Env::Info_env.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 Info_skin
    def initialize(md=nil,skin=nil)
      @md=md
      @d_sk=if skin.class==String ; skin
      elsif defined? md.doc_skin \
      and md.doc_skin
        md.doc_skin
      else nil
      end
      @home,@pwd=ENV['HOME'],ENV['PWD']
      m=/.+\/(?:src\/)?(\S+)/m # m=/.+?\/(?:src\/)?([^\/]+)$/im # m=/.+\/(\S+)/m
      @pwd_stub=@pwd[m,1]
      @env=SiSU_Env::Info_env.new
    end
    def select                                                                 # skin loading logic here
      load "#{SiSU_lib}/defaults.rb"
      skin_path=[]
      @env.sys.rc_path.each{|x| skin_path << "#{x}/skin"}
      skin_path << "#{@env.path.processing}/external_document/skin"
      skin=true
      if @pwd_stub =~/^sisupod$/ \
      and @md.mod.inspect !~/--trust/
        skin=false  #security only run skins on sisupod if --trust flag is provided
      end
      doc_skin,dir_skin=nil,nil
      if skin
        unless @d_sk.nil?
          sk_doc="doc/#{@d_sk}.rb"
          skin_path.each do |v|                                                    #document skin priority 1
            if FileTest.file?("#{v}/#{sk_doc}")
              doc_skin="#{v}/#{sk_doc}"
              load doc_skin
              break
            end
          end
        end
        unless doc_skin
          sk_dir="dir/skin_#{@pwd_stub}.rb"
          skin_path.each do |v|                                                  #directory skin priority 2
            if FileTest.file?("#{v}/#{sk_dir}")
              dir_skin="#{v}/#{sk_dir}"
              load dir_skin
              break
            end
          end
        end
      end
      sk=if doc_skin; doc_skin
      elsif dir_skin; dir_skin
      else            nil
      end
    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 < Info_env
    def initialize(md)
      @md=md
      @env=SiSU_Env::Info_env.new
    end
    def html
      css=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 CSS_default.new.html
      end
    end
    def html_tables
      css=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 CSS_default.new.html_tables
      end
    end
    def xhtml
      css=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 CSS_default.new.xhtml
      end
    end
    def xml_sax
      css=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 CSS_default.new.xml_sax
      end
    end
    def xml_dom
      css=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 CSS_default.new.xml_dom
      end
    end
    def docbook_xml
      css=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 CSS_default.new.docbook_xml
      end
    end
    def homepage
      css=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 CSS_default.new.homepage
      end
    end
  end
  class CSS_stylesheet
    def initialize(md)
      @md=md
      @css=CSS_select.new(@md)
      @env=SiSU_Env::Info_env.new
    end
    def html
      %{  <link rel="stylesheet" href="../#{@env.path.style}/#{@css.html}" type="text/css" />}
    end
    def html_tables
      %{  <link rel="stylesheet" href="../#{@env.path.style}/#{@css.html_tables}" type="text/css" />}
    end
    def xhtml_epub
      %{  <link rel="stylesheet" href="css/xhtml.css" type="text/css" />}
    end
  end
  class SiSU_file <Info_env                                                    #todo unify with Create_file
    def initialize(md,fno='')
      begin
        @fno,@fns,@fnb=fno,md.fns,md.fnb
        @env=SiSU_Env::Info_env.new(@fns)
        @env_out="#{@env.path.output}/#{@fnb}"
      rescue; STDERR.puts SiSU_Screen::Ansi.new(@cmd,$!,$@).rescue
      ensure
      end
    end
    def make_file(path,filename)
      if File.writable?("#{path}/."); File.new("#{path}/#{filename}",'w+')
      else SiSU_Screen::Ansi.new('',"is the file or directory writable?, could not create #{filename}").warn
      end
    end
    def touch_file(path,filename)
      if File.writable?("#{path}/.");
        system("touch #{path}/#{filename}")
      else SiSU_Screen::Ansi.new('',"is the file or directory writable?, could not create #{filename}").warn
      end
    end
    def make_path(path)
      mkdir_p(path) unless FileTest.directory?(path)
    end
    def mkdir_initialize                                                       # not used but consider using
      mkdir_p(@env.path.output) unless FileTest.directory?(@env.path.output)
      mkdir_p("#{@env.path.output}/#{@fnb}") unless FileTest.directory?("#{@env.path.output}/#{@fnb}")
      mkdir_p("#{@env.path.output}/#{@env.path.style}") unless FileTest.directory?("#{@env.path.output}/#{@env.path.style}")
      mkdir_p(@env.path.dal) unless FileTest.directory?(@env.path.dal)
      mkdir_p(@env.path.tune) unless FileTest.directory?(@env.path.tune)
    end
    def mkdir
      dir=@env.path.output
      txt_path="#{dir}/#{@fnb}"
      mkdir_p(dir) unless FileTest.directory?(dir)
      mkdir_p(txt_path) unless FileTest.directory?(txt_path)
      mkdir_p("#{dir}/#{@env.path.style}") unless FileTest.directory?("#{dir}/#{@env.path.style}")
      mkdir_p(@env.path.dal) unless FileTest.directory?(@env.path.dal)
      mkdir_p(@env.path.tune) unless FileTest.directory?(@env.path.tune)
    end
    def mkfile #consider using more
      path="#{@env.path.output}/#{@fnb}"
      filename=@fno
      file=make_file(path,filename)
    end
    def mkfile_man
      path="#{@env.path.output}/man"
      make_path(path)
      filename=@fno
      file=make_file(path,filename)
    end
    def mkfile_pwd
      path=Dir.pwd
      filename=@fno
      file=make_file(path,filename)
    end
  end
  class Create_file <Info_env                                                  #todo unify with SiSU_file
    def initialize(cmd,fns,operation='')
      @cmd=cmd
      begin
        super(fns)
        @env=SiSU_Env::Info_env.new(fns)
        ver=Info_version.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}"
            @env_tex=@env.path.tex
            @env_lout=@env.path.lout
            @@publisher='SiSU http://www.jus.uio.no/sisu'
            @env_pdf="#{@env_out_root}/pdf"
          end
        end
      rescue; STDERR.puts SiSU_Screen::Ansi.new(@cmd,$!,$@).rescue
      ensure
      end
    end
    def param_instantiate
      @cX||=SiSU_Screen::Ansi.new(@cmd)
      @@date=Info_date.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
    def marshal
      def dal_content
        "#{@env.path.dal}/#{@fns}.content.rbm"
      end
      def dal_idx_sst_rel_html_seg
        "#{@env.path.dal}/#{@fns}.idx_sst.rbm"
      end
      def dal_idx_sst_rel
        "#{@env.path.dal}/#{@fns}.idx_tex.rbm"
      end
      def dal_idx_html
        "#{@env.path.dal}/#{@fns}.idx_html.rbm"
      end
      def dal_idx_xhtml
        "#{@env.path.dal}/#{@fns}.idx_xhtml.rbm"
      end
      def dal_metadata
        "#{@env.path.dal}/#{@fns}.metadata.rbm"
      end
      def dal_map_nametags
        "#{@env.path.dal}/#{@fns}.map_name_tags.rbm"
      end
      def dal_map_ocn_htmlseg
        "#{@env.path.dal}/#{@fns}.map_ocn_htmlseg.rbm"
      end
      self
    end
    def html_root
      #@env.path.output
    end
    def mkdir_pdf
      Dir.mkdir(@env.path.tex) unless FileTest.directory?(@env.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.path.dal}/#{@fns}.txt",'w+')
    end
    def file_debug
      File.new("#{@env.path.dal}/#{@fns}.debug.txt",'w+')
    end
    def file_meta
      File.new("#{@env.path.dal}/#{@fns}.meta",'w+')
    end
    def file_meta_idx_html
      File.new("#{@env.path.dal}/#{@fns}.idx.html",'w+')
    end
    def file_note
      File.new("#{Dir.pwd}/#{@fns}.fn",'w+')
    end
    def meta
      "#{@env.path.dal}/#{@fns}.meta"
    end
    def file_tune
      File.new("#{@env.path.tune}/#{@fns}.tune",'w+')
    end
    def marshal_tune
      "#{@env.path.tune}/#{@fns}.marshal_tune"
    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 file_html_scroll(md)
      filename_scroll="#{@env.path.output}/#{md.fnb}/#{md.fnl[:pre]}doc#{md.fnl[:mid]}.html#{md.fnl[:post]}"
      @@filename_html_scroll=File.new(filename_scroll,'w+')
    end
    def file_html_index(md)
      filename_index="#{@env.path.output}/#{md.fnb}/#{md.fnl[:pre]}index#{md.fnl[:mid]}.html#{md.fnl[:post]}"
      @@filename_html_index=File.new(filename_index,'w+')
    end
    def file_html_segtoc(md)
      filename_segtoc="#{@env.path.output}/#{md.fnb}/#{md.fnl[:pre]}toc#{md.fnl[:mid]}.html#{md.fnl[:post]}"
      File.new(filename_segtoc,'w+')
    end
    def epub
      @pth=@env.path.epub
      def xhtml_index
        filename_index="#{@pth}/OPS/index.xhtml"
        File.new(filename_index,'w+')
      end
      def xhtml_segtoc
        filename_segtoc="#{@pth}/OPS/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}/OPS/epb.opf",'w')
      end
      def toc_ncx  #variable toc ~/grotto/theatre/dbld/builds/epub_sample/toc.ncx
        File.new("#{@pth}/OPS/epb.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}/OPS/css/xhtml.css",'w')
      end
      self
    end
    def file_texinfo
      File.new("#{@env.path.texinfo}/#{@fnb}.texinfo",'w+')
    end
  end
  class Create_site < Info_env
    require "#{SiSU_lib}/css"                              # css.rb
      include SiSU_Style
    def initialize(cmd)
      @cmd=cmd
      @env=SiSU_Env::Info_env.new
      @home,@pwd=ENV['HOME'],ENV['PWD'] #@pwd=Dir.pwd
      @rc=Get_init.instance.yamlrc
      @vz=SiSU_Env::Get_init.instance.skin
      @vz_home=SiSU_Viz::Home.new
    end
    def homepage
      homepage_path=nil
      @env.sys.rc_path.each do |v|
        if FileTest.file?("#{v}/home/index.html")
          homepage_path="#{v}/home/index.html"
          break
        end
      end
      mkdir_p("#{@env.path.webserv}/#{@env.path.stub_pwd}") unless FileTest.directory?("#{@env.path.webserv}/#{@env.path.stub_pwd}")
      if homepage_path \
      and FileTest.file?(homepage_path)
        cp(homepage_path,"#{@env.path.webserv}/#{@env.path.stub_pwd}/index.html")
        cp(homepage_path,"#{@env.path.webserv}/#{@env.path.stub_pwd}/toc.html")
      else
        doc_skin=nil
        sk_doc='doc/skin_sisu.rb'
        @env.sys.rc_path.each do |v|                                                     #document skin priority 1
          if FileTest.file?("#{v}/skin/#{sk_doc}")
            doc_skin="#{v}/skin/#{sk_doc}"
            load doc_skin
            break
          end
        end
        filename_homepage=File.new("#{@env.path.webserv}/#{@env.path.stub_pwd}/index.html",'w')
        filename_homepage_toc=File.new("#{@env.path.webserv}/#{@env.path.stub_pwd}/toc.html",'w')
        filename_homepage << @vz_home.homepage
        filename_homepage_toc << @vz_home.homepage
      end
    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 cp_images(src_path,dest_path)
      if FileTest.directory?(src_path)
        cd(src_path)
        source=Dir.glob("*.{png,jpg,gif,ico}")
        mkdir_p(dest_path) unless FileTest.directory?(dest_path)
        chmod(0755,dest_path)
        source.each do |i|
          cp_r(i,"#{dest_path}/#{i}")
          chmod(0644,"#{dest_path}/#{i}")
        end
        cd(@pwd)
      else puts "\tWARN, did not find - #{src_path}"
      end
    end
    def cp_local_images
      src="#{@pwd}/_sisu/image"
      dest="#{@env.path.webserv}/#{@env.path.stub_pwd}/_sisu/image"
      cp_images(src,dest)
    end
    def cp_external_images
      src="#{@env.path.processing}/external_document/image"
      dest="#{@env.path.webserv}/#{@env.path.stub_pwd}/_sisu/image_external"
      cp_images(src,dest)
    end
    def cp_webserver_images
      src=@env.path.image_source
      dest="#{@env.path.webserv}/_sisu/image"
      cp_images(src,dest)
    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)
    end
    def cp_base_images #fix images
      src="#{@env.path.share}/image"
      dest="#{@env.path.webserv}/_sisu/image_sys"
      cp_images(src,dest)
    end
    def cp_css
      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,"modify is css set to: #{@rc['permission_set']['css_modify']}").warn if @cmd=~/[MV]/
        css_path.each do |x|
          if FileTest.directory?(x)
            cd(x)
            source=Dir.glob("*.{css}")
            source.each do |i|
              cp(i,"#{@env.path.output}/#{@env.path.style}")
            end
            cd(@pwd)
          end
        end
      else SiSU_Screen::Ansi.new(@cmd,"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}"
      mkdir_p(path_style) unless FileTest.directory?(path_style)
      style=File.new("#{path_style}/#{fn_css.homepage}",'w')
      style << css.homepage
      style.close
      style=File.new("#{path_style}/#{fn_css.html_tables}",'w')
      style << css.html_tables
      style.close
      style=File.new("#{path_style}/#{fn_css.html}",'w')
      style << css.html
      style.close
      style=File.new("#{path_style}/#{fn_css.xml_sax}",'w')
      style << css.xml_sax
      style.close
      style=File.new("#{path_style}/#{fn_css.xml_dom}",'w')
      style << css.xml_dom
      style=File.new("#{path_style}/#{fn_css.docbook_xml}",'w')
      style << css.docbook_xml
      style.close
      style=File.new("#{path_style}/#{fn_css.xhtml}",'w')
      style << css.xhtml
      style=File.new("#{path_style}/#{fn_css.harvest}",'w')
      style << css.harvest
      style.close
    end
  end
end
module SiSU_Screen
  require "#{SiSU_lib}/screen_text_color"                  # screen_text_color.rb
end
module SiSU_Errors
  require "#{SiSU_lib}/errors"                             # errors.rb
end
__END__
https? intro check 2007-09-22

fns_array=unless fns =~/\.ssm.sst$/
  if RUBY_VERSION < '1.9'
    IO.readlines(fns,'')
  else IO.readlines(fns,'r:utf-8')
  end
else
  if RUBY_VERSION < '1.9'
    IO.readlines("#{path.composite_file}/#{fns}",'')
  else IO.readlines("#{path.composite_file}/#{fns}",'r:utf-8')
  end
end
