-*- mode: org -*-
#+TITLE:       sisu
#+DESCRIPTION: documents - structuring, various output representations & search
#+FILETAGS:    :sisu:
#+AUTHOR:      Ralph Amissah
#+EMAIL:       [[mailto:ralph.amissah@gmail.com][ralph.amissah@gmail.com]]
#+COPYRIGHT:   Copyright (C) 2015 - 2021 Ralph Amissah
#+LANGUAGE:    en
#+STARTUP:     content hideblocks hidestars noindent entitiespretty
#+OPTIONS:     H:3 num:nil toc:t \n:nil @:t ::t |:t ^:nil _:nil -:t f:t *:t <:t
#+PROPERTY:    header-args  :exports code
#+PROPERTY:    header-args+ :noweb yes
#+PROPERTY:    header-args+ :eval no
#+PROPERTY:    header-args+ :results no
#+PROPERTY:    header-args+ :cache no
#+PROPERTY:    header-args+ :padline no
#+PROPERTY:    header-args+ :mkdirp yes

[[./sisu_info.org][sisu_info.org]]  [[./][org/]]
[[./sisu_build.org][make/build]] VERSION

* version.txt (set version) :version:
** set program tangle

#+BEGIN_SRC txt  :NO-tangle "../data/sisu/version.yml"
<<sisu_project_version_current_set>>
#+END_SRC

#+NAME: sisu_version_current_set
#+BEGIN_SRC yaml
---
:project: SiSU
:version: 7.2.1_pre_rel
:date_stamp: 2019w35/4
:date: "2019-09-05"
#+END_SRC

* bin
** bin/sisu

#+HEADER: :tangle "../bin/sisu"
#+HEADER: :shebang "#!/usr/bin/env ruby"
#+HEADER: :tangle-mode (identity #o755)
#+BEGIN_SRC ruby
#<<sisu_document_header>>
class Orient
  require 'singleton'
  include Singleton
  def initialize #(called_as_,argv)
    super()
    @called_as,@argv=$0,$*
  end
  def version_major
   '7'
  end
  def sisu_called_from_directory
    @@sisu_called_from_directory ||= Dir.pwd
  end
  def sisu_run_from?
    if processing.called_as == processing.sisu_runtime_path \
    and File.dirname(processing.sisu_runtime_path) != RbConfig::CONFIG['bindir']
      :full_path_to_sisu_bin_in_sisu_dir_tree
    elsif processing.sisu_runtime_path =~/\/gems\// \
    and processing.sisu_runtime_path \
    =~ /\/#{processing.gem_regex}\//
      :gem_install
    else
      :system_install
    end
  end
  def processing
    def called_as
      @called_as
    end
    def argv
      @argv
    end
    def argv_str
      argv.inspect
    end
    def sisu_runtime_path
      __FILE__
    end
    def bin_file_regex
      %r{\bsisu$}
    end
    def gem_regex
      %r{sisu-[0-9]+\.[0-9]+\.[0-9]+(?:\.r[0-9]+\.g[0-9a-f]{7})?}
    end
    self
  end
  def sisu_lib
    'sisu'
  end
  def sisu_version_info_path
    "#{sisu_path_base_system_data}/version.yml"
  end
  def paths_set
    if sisu_run_from? == :system_install \
    and processing.called_as \
    =~ /^#{RbConfig::CONFIG['bindir']}\/sisu$/
      :set_path_system
    elsif sisu_run_from? == :full_path_to_sisu_bin_in_sisu_dir_tree \
    and processing.called_as \
    !~ /^#{RbConfig::CONFIG['bindir']}\/sisu$/ \
    && File.expand_path(processing.called_as) \
    =~ /bin\/sisu$/ \
    && FileTest.file?(processing.called_as)
      :set_dir_tree_full_path
    elsif sisu_run_from? ==:gem_install
      :set_path_gem
    else nil
    end
  end
  def git_version
    if sisu_run_from? == :full_path_to_sisu_bin_in_sisu_dir_tree \
    && FileTest.file?('/usr/bin/git') \
    && FileTest.directory?(processing.sisu_runtime_path.gsub(/\/bin\/sisu\S*/,'/.git'))
      bin_base=processing.sisu_runtime_path.gsub(/\/bin\/sisu\S*/,'')
      pwd=Dir.pwd
      Dir.chdir(bin_base)
      x=`git describe --long --tags 2>&1`.strip.
        gsub(/^[a-z_-]*([0-9.]+)/,'\1').
        gsub(/([^-]*-g)/,'r\1').
        gsub(/-/,'.')
      x=(x=~/^[0-9]+\.[0-9]+\.[0-9]+\.r[0-9]+\.g[0-9a-f]{7}/) \
      ? x
      : nil
      Dir.chdir(pwd)
      x
    else nil
    end
  end
  def sisu_path_base
    case paths_set
    when :set_path_system
      RbConfig::CONFIG['datadir'] + '/sisu'
    when :set_dir_tree_full_path
      File.expand_path(processing.called_as).
        sub(/\/bin\/sisu$/,'')
    when :set_path_gem
      Gem::Specification.find_by_name("sisu").gem_dir
    else nil
    end
  end
  def sisu_path_base_system_data
    case paths_set
    when :set_path_system
      RbConfig::CONFIG['datadir'] + '/sisu'
    when :set_dir_tree_full_path
      File.expand_path(processing.called_as).
        sub(/\/bin\/sisu$/,'/data/sisu')
    when :set_path_gem
      Gem::Specification.find_by_name("sisu").gem_dir \
      + '/data/sisu'
    else nil
    end
  end
  def sisu_this_lib
    if Gem::Specification.any? \
    and processing.sisu_runtime_path =~/\/gems\// \
    and processing.sisu_runtime_path \
    =~ /\/#{processing.gem_regex}\//
      # gem sought
      processing.sisu_runtime_path.
        gsub(/\/bin\/sisu[a-z0-9._-]*$/,
          '/lib/sisu')
    elsif (processing.called_as \
    !~ /^#{RbConfig::CONFIG['bindir']}\/sisu$/)
      # called off file system, project directory tree
      File.expand_path(processing.called_as).
        sub(/bin\/sisu\S*/,'lib/sisu')
    else
      # distro installation
      sisulib={
        vendorlib: RbConfig::CONFIG['vendorlibdir'] + '/sisu',
        sitelib: RbConfig::CONFIG['sitelibdir'] + '/sisu',
      }
      if FileTest.directory?(sisulib[:sitelib])            # local install
        sisulib[:sitelib]
      elsif FileTest.directory?(sisulib[:vendorlib])       # system install
        sisulib[:vendorlib]
      else 'sisu'                                          # assume lib paths work
      end
    end
  end
  def sisu_this_lib_
    if (processing.called_as \
    !~ /^#{RbConfig::CONFIG['bindir']}\/sisu$/)
      File.expand_path(processing.called_as).
        sub(/bin\/sisu\S*/,'lib/sisu')
    else 'sisu'
    end
  end
  def language_list
    def codes
      %w[am bg bn br ca cs cy da de el en eo es et eu fi fr ga gl he hi hr hy ia is it ja ko la lo lt lv ml mr nl nn no oc pl pt pt_BR ro ru sa se sk sl sq sr sv ta te th tk tr uk ur us vi zh]
    end
    def regex
      codes.join('|')
    end
    self
  end
  def sisu_is
    def version_major?
      version_major
    end
    def runtime_path?
      processing.sisu_runtime_path
    end
    def runtime_type?
      sisu_run_from?
    end
    def called_from?
      sisu_called_from_directory
    end
    def path_base?
      sisu_path_base
    end
    def path_base_system_data?
      sisu_path_base_system_data
    end
    def version_info_path?
      sisu_version_info_path
    end
    def language_list?
      language_list.codes
    end
    def language_list_regex?
      language_list.regex
    end
    def git_version_info?
      git_version
    end
    def runtime?
      {
        call_path:    called_from?,
        runtime_path: runtime_path?,
        runtime_type: runtime_type?,
      }
    end
    self
  end
  def get_processing_info
    def sortout
      unless @clm_pf
        processing_files={}
        command_line_modifiers=[]
        processing.argv.each do |x|
          if x =~/^-+/
            command_line_modifiers << x
          elsif x =~/\.ss[tm]/
            if x =~/\//
              markup_path,markup_file =
                (/(\S+\/)((?:#{language_list.regex})?[^\/]+)/).
                match(x)[1,2]
              if not processing_files[markup_path]
                processing_files[markup_path]=[]
              end
              processing_files[markup_path] << markup_file
            else
              if not processing_files['./']
                processing_files['./']=[]
              end
              processing_files['./'] << x
            end
          end
        end
      end
      @clm_pf ||={
        command_line_modifiers: command_line_modifiers,
        processing_files:       processing_files,
      }
    end
    def command_line_modifiers
      sortout[:command_line_modifiers]
    end
    def processing_files
      sortout[:processing_files]
    end
    self
  end
  def control
    require sisu_this_lib
    sisu_called_from_directory
    begin
      if get_processing_info.processing_files.length > 0
        get_processing_info.processing_files.each_pair do |markup_dir,markup_file|
          begin
            $sisu_document_markup_directory=markup_dir.gsub(/\/$/,'')
            argv_sub=get_processing_info.command_line_modifiers + markup_file
            if FileTest.directory?(markup_dir)
              system("cd #{markup_dir}")
              Dir.chdir(markup_dir)
              $sisu_document_markup_directory_base_fixed_path=
                Dir.pwd.gsub(/\/(?:#{language_list.regex})$/,'')
              SiSU_libs::CallHubMaster.new(argv_sub,sisu_is.runtime?)
            elsif markup_dir =~/https?:/
              markup_file.each do |mf|
                (FileTest.file?(mf)) \
                ? (puts 'requested remote file already exists in current directory ' \
                  + Dir.pwd + ' using ' + mf)
                : (system("wget #{markup_dir}/#{mf}"))
              end
              $sisu_document_markup_directory_base_fixed_path=
                Dir.pwd.gsub(/\/(?:#{language_list.regex})$/,'')
              argv_sub=command_line_modifiers + markup_file
              SiSU_libs::CallHubMaster.new(argv_sub,sisu_is.runtime?)
            else p "Error directory specified #{markup_dir} not found"
            end
          ensure
            Dir.chdir(sisu_called_from_directory)
            system("cd #{sisu_called_from_directory}")
          end
        end
      else
        $sisu_document_markup_directory=Dir.pwd.gsub(/\/$/,'')
        $sisu_document_markup_directory_base_fixed_path=
          Dir.pwd.gsub(/(^|\/)(?:#{language_list.regex})$/,'')
        SiSU_libs::CallHubMaster.new(processing.argv,sisu_is.runtime?)
      end
    rescue
    ensure
      SiSU_libs::HubClose.new(@argv,sisu_called_from_directory)
      Dir.chdir(sisu_called_from_directory)
      system("cd #{sisu_called_from_directory}")
    end
  end
end
#% sisu select source & branch, begin
$VERBOSE=nil
require 'rbconfig'
begin
  require 'singleton'
  s=Orient.instance
  SiSU_is=s.sisu_is
  s.control
rescue #% -
  STDERR.puts 'ERROR'
  STDERR.puts $!
  STDERR.puts $@
  puts %{
                    #{%x{ruby -v}.strip.to_s}
                    #{RUBY_VERSION}
    ruby version:   #{RbConfig::CONFIG['RUBY_PROGRAM_VERSION']}p#{RbConfig::CONFIG['PATCHLEVEL']}
    ruby named:     #{RbConfig::CONFIG['ruby_version']}
    rubylib:        #{RbConfig::CONFIG['rubylibdir']}
    vendor lib      #{RbConfig::CONFIG['vendordir']}
    site lib local: #{RbConfig::CONFIG['sitelibdir']}
    gem dir:        #{Gem.dir}
    gem path:       #{Gem.path}
  }
  system(%{echo "
    system RUBYPATH: ${RUBYPATH}
    system RUBYLIB:  ${RUBYLIB}
  "})
end
__END__
#+END_SRC

** bin/sisu-concordance
#+HEADER: :tangle "../bin/sisu-concordance"
#+HEADER: :shebang "#!/usr/bin/env sh"
#+HEADER: :tangle-mode (identity #o755)
#+BEGIN_SRC sh
sisu --concordance ${@}
#+END_SRC

** bin/sisu-epub

#+HEADER: :tangle "../bin/sisu-epub"
#+HEADER: :shebang "#!/usr/bin/env sh"
#+HEADER: :tangle-mode (identity #o755)
#+BEGIN_SRC sh
sisu --epub ${@}
#+END_SRC

** bin/sisu-harvest

#+HEADER: :tangle "../bin/sisu-harvest"
#+HEADER: :shebang "#!/usr/bin/env sh"
#+HEADER: :tangle-mode (identity #o755)
#+BEGIN_SRC sh
sisu --harvest ${@}
#+END_SRC

** bin/sisu-html

#+HEADER: :tangle "../bin/sisu-html"
#+HEADER: :shebang "#!/usr/bin/env sh"
#+HEADER: :tangle-mode (identity #o755)
#+BEGIN_SRC sh
sisu --html ${@}
#+END_SRC

** bin/sisu-html_scroll

#+HEADER: :tangle "../bin/sisu-html-scroll"
#+HEADER: :shebang "#!/usr/bin/env sh"
#+HEADER: :tangle-mode (identity #o755)
#+BEGIN_SRC sh
sisu --html-scroll ${@}
#+END_SRC

** bin/sisu-html-seg

#+HEADER: :tangle "../bin/sisu-html-seg"
#+HEADER: :shebang "#!/usr/bin/env sh"
#+HEADER: :tangle-mode (identity #o755)
#+BEGIN_SRC sh
sisu --html-seg ${@}
#+END_SRC

** bin/sisu-odf

#+HEADER: :tangle "../bin/sisu-odf"
#+HEADER: :shebang "#!/usr/bin/env sh"
#+HEADER: :tangle-mode (identity #o755)
#+BEGIN_SRC sh
sisu --odt ${@}
#+END_SRC

** bin/sisu-pdf

#+HEADER: :tangle "../bin/sisu-pdf"
#+HEADER: :shebang "#!/usr/bin/env sh"
#+HEADER: :tangle-mode (identity #o755)
#+BEGIN_SRC sh
sisu --pdf ${@}
#+END_SRC

** bin/sisu-pdf-portrait

#+HEADER: :tangle "../bin/sisu-pdf-portrait"
#+HEADER: :shebang "#!/usr/bin/env sh"
#+HEADER: :tangle-mode (identity #o755)
#+BEGIN_SRC sh
sisu --pdf-portrait ${@}
#+END_SRC

** bin/sisu-pdf-landscape

#+HEADER: :tangle "../bin/sisu-pdf-landscape"
#+HEADER: :shebang "#!/usr/bin/env sh"
#+HEADER: :tangle-mode (identity #o755)
#+BEGIN_SRC sh
sisu --pdf-landscape ${@}
#+END_SRC

** bin/sisu-pg

#+HEADER: :tangle "../bin/sisu-pg"
#+HEADER: :shebang "#!/usr/bin/env sh"
#+HEADER: :tangle-mode (identity #o755)
#+BEGIN_SRC sh
sisu --pg ${@}
#+END_SRC

** bin/sisu-sqlite

#+HEADER: :tangle "../bin/sisu-sqlite"
#+HEADER: :shebang "#!/usr/bin/env sh"
#+HEADER: :tangle-mode (identity #o755)
#+BEGIN_SRC sh
sisu --sqlite ${@}
#+END_SRC

** bin/sisu-txt

#+HEADER: :tangle "../bin/sisu-txt"
#+HEADER: :shebang "#!/usr/bin/env sh"
#+HEADER: :tangle-mode (identity #o755)
#+BEGIN_SRC sh
sisu --txt ${@}
#+END_SRC

** bin/sisu-webrick

#+HEADER: :tangle "../bin/sisu-webrick"
#+HEADER: :shebang "#!/usr/bin/env sh"
#+HEADER: :tangle-mode (identity #o755)
#+BEGIN_SRC sh
sisu -W ${@}
#+END_SRC

** bin/sisu-misc-utils

#+HEADER: :tangle "../bin/sisu-misc-utils"
#+HEADER: :shebang "#!/usr/bin/env ruby"
#+HEADER: :tangle-mode (identity #o755)
#+BEGIN_SRC ruby
#<<sisu_document_header>>
begin
  require 'thor'
rescue LoadError
  puts 'thor (package ruby-thor) not found'
end
require 'find'
require 'fileutils'
  include FileUtils
require 'pathname'
require 'rbconfig.rb'
module SiSUconf
  class LanguageCodes
    def language_list
      def codes
        %w[am bg bn br ca cs cy da de el en eo es et eu fi fr ga gl he hi hr hy ia is it ja ko la lo lt lv ml mr nl nn no oc pl pt pt_BR ro ru sa se sk sl sq sr sv ta te th tk tr uk ur us vi zh]
      end
      def regex
        codes.join('|')
      end
      self
    end
  end
  class DetermineLibsPath
    def version
      def stable
       '5'
      end
      def unstable
       '6'
      end
      self
    end
    def processing
      def called_as
        $0
        #$called_as
      end
      def called_as_exe
        File.basename(called_as)
      end
      def called_as_exe_strip_current_develop
        File.basename(called_as).gsub(/-(?:current|develop)/,'')
      end
      def argv
        $*
        #$argv
      end
      def argv_str
        argv.inspect
      end
      def file_full_path
        __FILE__
      end
      def current
        'current'
      end
      def next
        'develop'
      end
      def stable_bin_file_regex
        %r{\bsisu#{version.stable}$}
      end
      def unstable_bin_file_regex
        %r{\bsisu#{version.unstable}$}
      end
      def stable_modifier_regex
        %r{"(?:--v#{version.stable}|--current|--stable)"}
      end
      def unstable_modifier_regex
        %r{"(?:--v#{version.unstable}|--next|--unstable)"}
      end
      def lib_filename
        'sisu_thor_lib'
      end
      self
    end
    def sisu_run_from?
      if processing.called_as == processing.file_full_path \
      and File.dirname(processing.file_full_path) != RbConfig::CONFIG['bindir']
        :full_path_to_sisu_bin_in_sisu_dir_tree
      elsif processing.file_full_path =~/\/gems\// \
      and processing.file_full_path \
      =~ /\/#{called_as_exe_strip_current_develop}(?:-(?:current|develop))\.(?:\d+|[a-z])\.(?:\d+|[a-z])\//
        :gem_install
      else
        :system_install
      end
    end
    def branch_name_
      if sisu_run_from? == :full_path_to_sisu_bin_in_sisu_dir_tree \
      or sisu_run_from? == :system_install
        case processing.called_as
        when processing.stable_bin_file_regex      then processing.current
        when processing.unstable_bin_file_regex    then processing.next
        else
          case processing.argv_str
          when processing.stable_modifier_regex    then processing.current
          when processing.unstable_modifier_regex  then processing.next
          else                                          processing.current
          end
        end
      elsif sisu_run_from? == :gem_install
        case processing.file_full_path
        when processing.stable_gem_regex           then processing.current
        when processing.unstable_gem_regex         then processing.next
        else                                            processing.current
        end
      else                                              processing.current
      end
    end
    def sisu_path_specified_lib
      if (processing.called_as \
      !~ /^#{RbConfig::CONFIG['bindir']}\/#{called_as_exe_strip_current_develop}(?:-(?:current|develop))?$/)
        File.expand_path(processing.called_as).
          sub(/bin\/#{called_as_exe_strip_current_develop}(?:-(?:current|develop))?$/,'lib')
      else nil
      end
    end
    def sisu_lib
      "sisu/#{branch_name_}"
    end
    def sisu_path_lib
      if sisu_path_specified_lib \
      && FileTest.file?("#{sisu_path_specified_lib}/#{sisu_lib}/#{lib_filename}.rb")
        "#{sisu_path_specified_lib}/#{sisu_lib}"
      else sisu_lib
      end
    end
  end
  class Configure < Thor
    $SiSU_Language_Codes=LanguageCodes.new
    paths= DetermineLibsPath.new
    #p "#{paths.sisu_path_lib}/#{paths.processing.lib_filename}"
    require "#{paths.sisu_path_lib}/#{paths.processing.lib_filename}" # sisu_thor_lib.rb
    @@source=@@targets=nil
    include SiSU_Po4a_Actions
    class_option :verbose, :type => :boolean
# rake help clean default distclean make manpage readme rebuild
    desc 'po4a',
      'place SiSU translations under po4a management' \
      + 'assist with having sisu markup files managed by po4a' \
      + 'create configuration files, and language directories and' \
      + 'populate them with po4a pot & po files for translation and' \
      + 'from those (as translated) create translated sisu markup' \
      + '.ssm .sst & .ssi files in corresponding language sub-directories' \
      + '*WARNING* creates, destroys, overwrites directories not managed by po4a'
    options \
      :help => :boolean,
      :clean => :boolean,
      #:default => :boolean,
      :distclean => :boolean,
      :make => :boolean,
      :lang_source => :string,
      :lang_targets => :array,
      :manpage => :boolean,
      :readme => :boolean,
      :rebuild => :boolean,
      :current => :string,
      :next => :string,
      :stable => :string,
      :unstable => :string
    def po4a
      @@source=source=if options[:lang_source] \
      and not options[:lang_source].empty?
        options[:lang_source]
      else nil
      end
      @@targets=targets=if options[:lang_targets]
        options[:lang_targets]
      else nil
      end
      language.translation_languages_selected(targets)
      language.source_language_selected(source)
      if options[:help]
        notice.project_help
      end
      if options[:clean]
        notice.default(:clean)
        project.clean
      end
      #if options[:default]
      #  notice.project_help
      #end
      if options[:distclean]
        notice.default(:distclean)
        project.distclean
      end
      if options[:make]
        notice.default(:make)
        project.make
      end
      if options[:manpage]
        generate.manpage
      end
      if options[:readme]
        generate.readme
      end
      if options[:rebuild]
        notice.default(:rebuild)
        project.distclean
        project.make
      end
    end
  end
end
begin
  require 'rbconfig'
  $called_as,$argv=$0,$*
  SiSUconf::Configure.start(ARGV)
rescue
end
__END__
#% manual settings, edit/update as required (note current default settings are obtained from sisu version yml file)
__END__
#+END_SRC

* document header

#+NAME: sisu_document_header
#+BEGIN_SRC text
encoding: utf-8
- Name: SiSU

  - Description: documents, structuring, processing, publishing, search
    sisu

  - Author: Ralph Amissah
    <ralph.amissah@gmail.com>

  - Copyright: (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
    2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2019,
    2020, 2021, Ralph Amissah,
    All Rights Reserved.

  - License: GPL 3 or later:

    SiSU, a framework for document structuring, publishing and search

    Copyright (C) Ralph Amissah

    This program is free software: you can redistribute it and/or modify it
    under the terms of the GNU General Public License as published by the Free
    Software Foundation, either version 3 of the License, or (at your option)
    any later version.

    This program is distributed in the hope that it will be useful, but WITHOUT
    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
    more details.

    You should have received a copy of the GNU General Public License along with
    this program. If not, see <http://www.gnu.org/licenses/>.

    If you have Internet connection, the latest version of the GPL should be
    available at these locations:
    <http://www.fsf.org/licensing/licenses/gpl.html>
    <http://www.gnu.org/licenses/gpl.html>

    <http://www.sisudoc.org/sisu/en/manifest/gpl.fsf.html>

  - SiSU uses:
    - Standard SiSU markup syntax,
    - Standard SiSU meta-markup syntax, and the
    - Standard SiSU object citation numbering and system

  - Homepages:
    <http://www.sisudoc.org>

  - Git
    <https://git.sisudoc.org/projects/>
    <https://git.sisudoc.org/projects/?p=software/sisu.git;a=summary>
    <https://git.sisudoc.org/projects/?p=markup/sisu-markup-samples.git;a=summary>
#+END_SRC