bin/sisu-misc-utils + c&d: lib sisu_thor_lib currently only po4a
authorRalph Amissah <ralph@amissah.com>
Mon, 12 Jan 2015 15:17:45 +0000 (10:17 -0500)
committerRalph Amissah <ralph@amissah.com>
Tue, 20 Jan 2015 04:46:16 +0000 (23:46 -0500)
* uses po4a to create po files with empty translation strings
* in appropriately configured directory e.g.
  "data/doc/sisu/markup-samples/manual" have file named:
  "languages_source_and_targets" containing e.g.:
    source: en
    targets: de fr es ja ru zh
  command examples:
    ruby ~snx/bin/sisu-misc-utils po4a --next --clean
    ruby ~snx/bin/sisu-misc-utils po4a --next --distclean
    ruby ~snx/bin/sisu-misc-utils po4a --next --make

bin/sisu-misc-utils [new file with mode: 0644]
data/doc/sisu/CHANGELOG_v5
data/doc/sisu/CHANGELOG_v6
lib/sisu/current/sisu_thor_lib.rb [new file with mode: 0644]
lib/sisu/develop/sisu_thor_lib.rb [new file with mode: 0644]

diff --git a/bin/sisu-misc-utils b/bin/sisu-misc-utils
new file mode 100644 (file)
index 0000000..e5be5c0
--- /dev/null
@@ -0,0 +1,228 @@
+#!/usr/bin/env ruby
+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
+    lib_filename='sisu_thor_lib'
+    #p "#{DetermineLibsPath.new.sisu_path_lib}/#{lib_filename}"
+    require "#{DetermineLibsPath.new.sisu_path_lib}/#{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__
+
+**  Description: 
+
+**  Homepage: <http://www.jus.uio.no/sisu/SiSU>
+             <http://search.sisudoc.org>
+**  Download: <http://www.jus.uio.no/sisu/download>
+
+**  Copyright: (C) 2007 - 2015 Ralph Amissah
+
+**  License: 
+
+**  Ralph Amissah <ralph@amissah.com>
+  Ralph Amissah <ralph.amissah@gmail.com>
+
+#% manual settings, edit/update as required (note current default settings are obtained from sisu version yml file)
index 33b3e5f95ca69b2bc93fbe6a80b01524c49bf6b6..1a00121364fa34179b0b315e8cf85e411b20f127 100644 (file)
@@ -86,6 +86,18 @@ http://www.jus.uio.no/sisu/pkg/src/sisu_5.8.0.orig.tar.xz
 
   * use RbConfig instead of Config
 
+  * bin/sisu-misc-utils, sisu_thor_lib, currently only for po4a
+    * uses po4a to create po files with empty translation strings
+    * in appropriately configured directory e.g.
+      "data/doc/sisu/markup-samples/manual" have file named:
+      "languages_source_and_targets" containing e.g.:
+        source: en
+        targets: de fr es ja ru zh
+      command examples:
+        ruby ~snx/bin/sisu-misc-utils po4a --next --clean
+        ruby ~snx/bin/sisu-misc-utils po4a --next --distclean
+        ruby ~snx/bin/sisu-misc-utils po4a --next --make
+
   * sisu.org addition, modification, consider
 
 ** SiSU "UnFrozen" - prior to end of Debian Freeze
index 6306cb95f2ddd6a2e31c353ae941a2073810fb1c..1d4fe844075a15833826a3eb23edbef14fa2c14b 100644 (file)
@@ -102,6 +102,18 @@ http://www.jus.uio.no/sisu/pkg/src/sisu_6.4.0.orig.tar.xz
 
   * use RbConfig instead of Config
 
+  * bin/sisu-misc-utils, sisu_thor_lib, currently only for po4a
+    * uses po4a to create po files with empty translation strings
+    * in appropriately configured directory e.g.
+      "data/doc/sisu/markup-samples/manual" have file named:
+      "languages_source_and_targets" containing e.g.:
+        source: en
+        targets: de fr es ja ru zh
+      command examples:
+        ruby ~snx/bin/sisu-misc-utils po4a --next --clean
+        ruby ~snx/bin/sisu-misc-utils po4a --next --distclean
+        ruby ~snx/bin/sisu-misc-utils po4a --next --make
+
   * under data/.../manual sisu po4a a ruby thor (Rakefile equivalent)
 
   * sisu.org addition, modification, consider
diff --git a/lib/sisu/current/sisu_thor_lib.rb b/lib/sisu/current/sisu_thor_lib.rb
new file mode 100644 (file)
index 0000000..3212e92
--- /dev/null
@@ -0,0 +1,407 @@
+module SiSU_Po4a_Actions
+  require_relative 'utils_response'                   # utils_response.rb
+  include SiSU_Response
+  @@source=@@targets=nil
+  def project_details
+    def name
+      'SiSU translations under po4a management'
+    end
+    def name_warning
+      <<-WOK
+#{name}
+
+WARNING all sisu markup files (.ssm, .sst, .ssi) in languages other than #{language.source_language_selected}
+are managed by po4a, through translations of the source language to other languages.
+
+#{language.info_on_selection}
+      WOK
+    end
+    def setup_project
+      "Setup file for placing #{name}"
+    end
+    self
+  end
+  def notice
+    def warn_and_proceed?
+      '*WARNING* this software module creates, destroys, overwrites directories' + "\n" \
+      + '*WARNING*: Use this Software at your own risk!'
+    end
+    def default(selection=nil)
+      selections=:strict #selections=:short
+      ans=if selection
+        case selection
+        when selection.is_a?(String)
+          selections=:strict
+          <<-WOK
+  #{project_details.setup_project}
+    Default action selected - "#{selection} #{project_details.name}"
+#{warn_and_proceed?}
+          WOK
+        when :make
+          selections=:strict
+          <<-WOK
+  #{project_details.setup_project}
+    "--#{selection}" selected - #{selection} #{project_details.name}
+    selected (or configured) languages to be used
+      source language: #{language.source_language_available_str}
+      target languages: #{language.translation_languages_selected_that_are_available.inspect}
+
+    WARNING: this action assumes (and places) this project is under po4a
+    (translation) management. It will create sub-directories for the
+    selected (or configured) target languages:
+      #{language.translation_languages_selected_that_are_available.inspect}
+    & the po4a configuration file: #{filename.po4a_cfg}
+    in the current directory:
+      #{Dir.pwd}
+    It will populate the sub-directories with translation files created from
+    the pot and po files found under the corresponding language
+    sub-directories, (under #{dir.pot}/ & #{dir.po}/).
+    (OVERWRITING any existing translated .ssm .sst .ssi files
+    in language subdirectories that are not under po4a management).
+
+    You should backup the current directory:
+      #{Dir.pwd}
+
+#{warn_and_proceed?}
+          WOK
+        when :clean
+          selections=:strict
+          <<-WOK
+  #{project_details.setup_project}
+    "--#{selection}" selected - #{selection} #{project_details.name}
+#{warn_and_proceed?}
+          WOK
+        when :distclean
+          selections=:strict
+          <<-WOK
+  #{project_details.setup_project}
+    "--#{selection}" selected - #{selection} #{project_details.name}
+    WARNING: this action assumes (and places) this project is under po4a
+    (translation) management. It will remove the sub-directories (if they exist):
+      #{language.possible_translations.inspect}
+
+      #{language.translation_languages_selected_that_are_available.inspect}
+    & file: #{filename.po4a_cfg}
+    in the current directory:
+      #{Dir.pwd}
+    Note: these sub-directories & the config file #{filename.po4a_cfg}
+    should be auto-generated from pot and po files if this project translation
+    is under po4a management.
+    This query is to give you the chance to make sure you know what you are doing.
+#{warn_and_proceed?}
+          WOK
+        when :rebuild
+          selections=:strict
+          <<-WOK
+  #{project_details.setup_project}
+    "--#{selection}" selected - #{selection} #{project_details.name}
+    WARNING: this action assumes (and places) this project is under po4a
+    (translation) management. It will destroy/clobber and then create again the
+    sub-directories:
+      #{language.translation_languages_selected_that_are_available.inspect}
+    populating them with translation files created from the pot and po files
+    found under the corresponding language sub-directories in (#{dir.pot}/
+    & #{dir.po}/).
+    It will also generate the file: #{filename.po4a_cfg}
+    These actions will be taken in the current directory:
+      #{Dir.pwd}
+    This query is to give you the chance to make sure you know what you are doing.
+#{warn_and_proceed?}
+          WOK
+        else
+          selections=:strict
+          <<-WOK
+  #{project_details.setup_project}
+    Default action selected - "#{selection} #{project_details.name}"
+#{warn_and_proceed?}
+          WOK
+        end
+      else
+        selections=:strict
+        <<-WOK
+  #{project_details.setup_project}
+    Default action selected - "install and to setup #{project_details.name}"
+#{warn_and_proceed?}
+        WOK
+      end
+      exit unless query.answer?(ans)
+    end
+    def project_help
+      puts <<-WOK
+#{project_details.name}
+#{project_details.setup_project}
+
+This setup file is primarily to assist with having sisu markup files under po4a
+translation management. It assumes that the source language files are placed
+under the sub-directory identifying the source language set, which is currently
+#{language.source_language_selected}
+The files there are used to make the source translation file in the directory #{dir.pot}/
+Which is then used to create files for translation under the directory #{dir.po}/
+in sub-directories bearing the translation languages ISO code.
+
+The current language translation selection is:  #{translation_languages_selected_str}
+The languages selected are located in the file: #{filename.languages_src_tgt}
+
+sisu available language list: #{sisu_languages_available_str}
+
+      WOK
+    end
+    self
+  end
+  def generate
+    def readme
+      system(%{ruby ../../../../../bin/sisu6 --txt -v --no-manifest --dump='../../../../../..' en/README.ssm})
+    end
+    def manpage
+      system(%{ruby ../../../../../bin/sisu6 --manpage -v --no-manifest --dump='../../../../../../man/man1' en/sisu.ssm})
+    end
+    self
+  end
+  def filename
+    def languages_src_tgt
+      #'translation_languages'
+      'languages_source_and_targets'
+    end
+    def po4a_cfg
+      'po4a.cfg'
+    end
+    self
+  end
+  def dir
+    def pwd
+      Dir.pwd
+    end
+    def po4a_
+      'po4a/' # ''
+    end
+    def pot
+      po4a_ + 'pot'
+    end
+    def po
+      po4a_ + 'po'
+    end
+    self
+  end
+  def dir_mk(dir)
+    FileUtils::mkdir_p(dir) unless FileTest.directory?(dir)
+  end
+  def po4a_flags
+    def debug
+      '-d -v'
+    end
+    def normal
+      ''
+    end
+    def quiet
+      '-q'
+    end
+    self
+  end
+  def languages_from_file
+    def language_source
+      if @@source.is_a?(String) \
+      and @@source =~ /w{2,4}/
+      else languages_extract_from_file
+      end
+      @@source
+    end
+    def language_targets
+      if @@targets.is_a?(Array) \
+      and @@targets.length > 0
+      else languages_extract_from_file
+      end
+      @@targets
+    end
+    def languages_extract_from_file
+      if (@@source.is_a?(String) \
+      and @@source =~/\w{2,4}/) \
+      and (@@targets.is_a?(Array) \
+      and @@targets.length > 0)
+      else
+        if FileTest.file?(filename.languages_src_tgt)
+          puts 'file: "' + filename.languages_src_tgt + '" found and used (unless overridden)'
+          langs=IO.read(filename.languages_src_tgt, mode: 'r:utf-8').scan(/source:\s+\w+|target:\s+\w.+/)
+          langs.each do |sel|
+            case sel
+            when /source:/
+              source=sel.split(/source:\s*|\s+/).join
+              source=(source =~/\w{2,4}/) ? source : nil
+              @@source=unless @@source.is_a?(String) \
+              and @@source =~/\w{2,4}/
+                source
+              else @@source
+              end
+            when /target:/
+              @@targets=unless @@targets.is_a?(Array)
+                sel.split(/targets?:\s*|\s+/) - ['']
+              else @@targets
+              end
+            end
+          end
+        else
+          puts %{(create) missing instruction file: "#{filename.languages_src_tgt}"\n  contents e.g.:\n    source: en\n    target: de fr es ja ru zh\n  no po target languages found}
+          exit
+        end
+      end
+    end
+    self
+  end
+  def language
+    def source_language_selected(src=nil)
+      @@source=if not @@source.nil? \
+      and @@source.is_a?(String) \
+      and @@source =~/\w{2,4}/
+        @@source
+      elsif (src \
+      && src.is_a?(String) \
+      && src.length > 1)
+        src
+      else
+        src=languages_from_file.language_source
+      end
+    end
+    def translation_languages_selected(targets=nil) #translation_languages
+      @@targets=if not @@targets.nil? \
+      and @@targets.is_a?(Array) \
+      and @@targets.length > 0
+        @@targets
+      elsif (targets \
+      && targets.is_a?(Array) \
+      && targets.length > 0)
+        targets
+      else
+        targets=languages_from_file.language_targets
+      end
+    end
+    def source_language_available
+      [source_language_selected] & sisu_languages_available
+    end
+    def translation_languages_selected_that_are_available
+      translation_languages_selected & sisu_languages_available
+    end
+    def info_on_selection
+      if translation_languages_selected != translation_languages_selected_that_are_available
+        <<-WOK
+WARNING: language selections mismatch
+
+The current language translation selection appears to be: #{translation_languages_selected_str}
+Of which the following are valid (available) selections:  #{translation_languages_selected_that_are_available_str}
+
+sisu available language list: #{sisu_languages_available_str}
+
+the following will be used: #{translation_languages_selected_that_are_available_str}
+The languages selected are located in the file:    #{filename.languages_src_tgt}
+        WOK
+      else
+        <<-WOK
+The current language translation selection is:  #{translation_languages_selected_str}
+The languages selected are located in the file: #{filename.languages_src_tgt}
+
+sisu available language list: #{sisu_languages_available_str}
+        WOK
+      end
+    end
+    def sisu_languages_available
+      $SiSU_Language_Codes.language_list.codes
+    end
+    def possible_translations
+      sisu_languages_available -  [source_language_selected]
+    end
+    def translation_languages_selected_str
+      language.translation_languages_selected.join(' ')
+    end
+    def source_language_available_str
+      source_language_available.join
+    end
+    def translation_languages_selected_that_are_available_str
+      language.translation_languages_selected_that_are_available.join(' ')
+    end
+    def sisu_languages_available_str
+      language.sisu_languages_available.join(' ')
+    end
+    def posible_translations_str
+      language.posible_translations.join(' ')
+    end
+    self
+  end
+  def files_src
+    def ssm
+      Dir.glob("#{language.source_language_selected}/*.ssm").sort
+    end
+    def sst
+      Dir.glob("#{language.source_language_selected}/*.sst").sort
+    end
+    def ssi
+      Dir.glob("#{language.source_language_selected}/*.ssi").sort
+    end
+    def all
+      Dir.glob("#{language.source_language_selected}/*{.ssm,.sst,.ssi}").sort
+    end
+    self
+  end
+  def po4a_cfg_file
+    File.open("#{Dir.pwd}/#{filename.po4a_cfg}",'w')
+  end
+  def po4a_create
+    def configure #po4a_cfg
+      po4a_cfg_arr=[]
+      po4a_cfg_arr \
+        << "[po4a_langs] #{language.translation_languages_selected_that_are_available_str}"
+      po4a_cfg_arr \
+        << "[po4a_paths] #{dir.pot}/$master.pot $lang:#{dir.po}/$lang/$master.po"
+      files_src.ssm.each do |file_src|
+        file_src_fn=file_src.gsub(/#{language.source_language_selected}\//,'')
+        po4a_cfg_arr \
+          << "[type: text] #{file_src} $lang:$lang/#{file_src_fn}"
+      end
+      files_src.sst.each do |file_src|
+        file_src_fn=file_src.gsub(/#{language.source_language_selected}\//,'')
+        po4a_cfg_arr \
+          << "[type: text] #{file_src} $lang:$lang/#{file_src_fn}"
+      end
+      files_src.ssi.each do |file_src|
+        file_src_fn=file_src.gsub(/#{language.source_language_selected}\//,'')
+        po4a_cfg_arr \
+          << "[type: text] #{file_src} $lang:$lang/#{file_src_fn}"
+      end
+      file=po4a_cfg_file
+      po4a_cfg_arr.each do |txt|
+      puts txt
+        file << txt << "\n"
+      end
+      file.close
+      cmd='po4a --keep 0 ' \
+      + po4a_flags.normal + ' ' \
+      + filename.po4a_cfg
+      #cmd='po4a --keep 0 --no-backups --package-name ' \
+      #+ 'sisu-manual' + ' ' \
+      #+ po4a_flags.normal + ' ' \
+      #+ filename.po4a_cfg
+      system(cmd); puts cmd
+    end
+    self
+  end
+  def project
+    def make
+      dir_mk(dir.pot)
+      language.translation_languages_selected_that_are_available.each do |lang_dir|
+        dir_lang="#{Dir.pwd}/#{dir.po}/#{lang_dir}"
+        dir_mk(dir_lang)
+      end
+      po4a_create.configure
+    end
+    def clean
+      #rm -f po/*/*.po~
+      #rm -rf ../build
+      FileUtils.rm_f Dir.glob("./#{dir.po}/*/*.po~")
+    end
+    def distclean
+      #rm -f po4a.cfg
+      #rm -rf $(LANGUAGES)
+      FileUtils::rm_f(filename.po4a_cfg)
+      FileUtils::rm_r(language.possible_translations,:force => true)
+    end
+    self
+  end
+end
+__END__
diff --git a/lib/sisu/develop/sisu_thor_lib.rb b/lib/sisu/develop/sisu_thor_lib.rb
new file mode 100644 (file)
index 0000000..3212e92
--- /dev/null
@@ -0,0 +1,407 @@
+module SiSU_Po4a_Actions
+  require_relative 'utils_response'                   # utils_response.rb
+  include SiSU_Response
+  @@source=@@targets=nil
+  def project_details
+    def name
+      'SiSU translations under po4a management'
+    end
+    def name_warning
+      <<-WOK
+#{name}
+
+WARNING all sisu markup files (.ssm, .sst, .ssi) in languages other than #{language.source_language_selected}
+are managed by po4a, through translations of the source language to other languages.
+
+#{language.info_on_selection}
+      WOK
+    end
+    def setup_project
+      "Setup file for placing #{name}"
+    end
+    self
+  end
+  def notice
+    def warn_and_proceed?
+      '*WARNING* this software module creates, destroys, overwrites directories' + "\n" \
+      + '*WARNING*: Use this Software at your own risk!'
+    end
+    def default(selection=nil)
+      selections=:strict #selections=:short
+      ans=if selection
+        case selection
+        when selection.is_a?(String)
+          selections=:strict
+          <<-WOK
+  #{project_details.setup_project}
+    Default action selected - "#{selection} #{project_details.name}"
+#{warn_and_proceed?}
+          WOK
+        when :make
+          selections=:strict
+          <<-WOK
+  #{project_details.setup_project}
+    "--#{selection}" selected - #{selection} #{project_details.name}
+    selected (or configured) languages to be used
+      source language: #{language.source_language_available_str}
+      target languages: #{language.translation_languages_selected_that_are_available.inspect}
+
+    WARNING: this action assumes (and places) this project is under po4a
+    (translation) management. It will create sub-directories for the
+    selected (or configured) target languages:
+      #{language.translation_languages_selected_that_are_available.inspect}
+    & the po4a configuration file: #{filename.po4a_cfg}
+    in the current directory:
+      #{Dir.pwd}
+    It will populate the sub-directories with translation files created from
+    the pot and po files found under the corresponding language
+    sub-directories, (under #{dir.pot}/ & #{dir.po}/).
+    (OVERWRITING any existing translated .ssm .sst .ssi files
+    in language subdirectories that are not under po4a management).
+
+    You should backup the current directory:
+      #{Dir.pwd}
+
+#{warn_and_proceed?}
+          WOK
+        when :clean
+          selections=:strict
+          <<-WOK
+  #{project_details.setup_project}
+    "--#{selection}" selected - #{selection} #{project_details.name}
+#{warn_and_proceed?}
+          WOK
+        when :distclean
+          selections=:strict
+          <<-WOK
+  #{project_details.setup_project}
+    "--#{selection}" selected - #{selection} #{project_details.name}
+    WARNING: this action assumes (and places) this project is under po4a
+    (translation) management. It will remove the sub-directories (if they exist):
+      #{language.possible_translations.inspect}
+
+      #{language.translation_languages_selected_that_are_available.inspect}
+    & file: #{filename.po4a_cfg}
+    in the current directory:
+      #{Dir.pwd}
+    Note: these sub-directories & the config file #{filename.po4a_cfg}
+    should be auto-generated from pot and po files if this project translation
+    is under po4a management.
+    This query is to give you the chance to make sure you know what you are doing.
+#{warn_and_proceed?}
+          WOK
+        when :rebuild
+          selections=:strict
+          <<-WOK
+  #{project_details.setup_project}
+    "--#{selection}" selected - #{selection} #{project_details.name}
+    WARNING: this action assumes (and places) this project is under po4a
+    (translation) management. It will destroy/clobber and then create again the
+    sub-directories:
+      #{language.translation_languages_selected_that_are_available.inspect}
+    populating them with translation files created from the pot and po files
+    found under the corresponding language sub-directories in (#{dir.pot}/
+    & #{dir.po}/).
+    It will also generate the file: #{filename.po4a_cfg}
+    These actions will be taken in the current directory:
+      #{Dir.pwd}
+    This query is to give you the chance to make sure you know what you are doing.
+#{warn_and_proceed?}
+          WOK
+        else
+          selections=:strict
+          <<-WOK
+  #{project_details.setup_project}
+    Default action selected - "#{selection} #{project_details.name}"
+#{warn_and_proceed?}
+          WOK
+        end
+      else
+        selections=:strict
+        <<-WOK
+  #{project_details.setup_project}
+    Default action selected - "install and to setup #{project_details.name}"
+#{warn_and_proceed?}
+        WOK
+      end
+      exit unless query.answer?(ans)
+    end
+    def project_help
+      puts <<-WOK
+#{project_details.name}
+#{project_details.setup_project}
+
+This setup file is primarily to assist with having sisu markup files under po4a
+translation management. It assumes that the source language files are placed
+under the sub-directory identifying the source language set, which is currently
+#{language.source_language_selected}
+The files there are used to make the source translation file in the directory #{dir.pot}/
+Which is then used to create files for translation under the directory #{dir.po}/
+in sub-directories bearing the translation languages ISO code.
+
+The current language translation selection is:  #{translation_languages_selected_str}
+The languages selected are located in the file: #{filename.languages_src_tgt}
+
+sisu available language list: #{sisu_languages_available_str}
+
+      WOK
+    end
+    self
+  end
+  def generate
+    def readme
+      system(%{ruby ../../../../../bin/sisu6 --txt -v --no-manifest --dump='../../../../../..' en/README.ssm})
+    end
+    def manpage
+      system(%{ruby ../../../../../bin/sisu6 --manpage -v --no-manifest --dump='../../../../../../man/man1' en/sisu.ssm})
+    end
+    self
+  end
+  def filename
+    def languages_src_tgt
+      #'translation_languages'
+      'languages_source_and_targets'
+    end
+    def po4a_cfg
+      'po4a.cfg'
+    end
+    self
+  end
+  def dir
+    def pwd
+      Dir.pwd
+    end
+    def po4a_
+      'po4a/' # ''
+    end
+    def pot
+      po4a_ + 'pot'
+    end
+    def po
+      po4a_ + 'po'
+    end
+    self
+  end
+  def dir_mk(dir)
+    FileUtils::mkdir_p(dir) unless FileTest.directory?(dir)
+  end
+  def po4a_flags
+    def debug
+      '-d -v'
+    end
+    def normal
+      ''
+    end
+    def quiet
+      '-q'
+    end
+    self
+  end
+  def languages_from_file
+    def language_source
+      if @@source.is_a?(String) \
+      and @@source =~ /w{2,4}/
+      else languages_extract_from_file
+      end
+      @@source
+    end
+    def language_targets
+      if @@targets.is_a?(Array) \
+      and @@targets.length > 0
+      else languages_extract_from_file
+      end
+      @@targets
+    end
+    def languages_extract_from_file
+      if (@@source.is_a?(String) \
+      and @@source =~/\w{2,4}/) \
+      and (@@targets.is_a?(Array) \
+      and @@targets.length > 0)
+      else
+        if FileTest.file?(filename.languages_src_tgt)
+          puts 'file: "' + filename.languages_src_tgt + '" found and used (unless overridden)'
+          langs=IO.read(filename.languages_src_tgt, mode: 'r:utf-8').scan(/source:\s+\w+|target:\s+\w.+/)
+          langs.each do |sel|
+            case sel
+            when /source:/
+              source=sel.split(/source:\s*|\s+/).join
+              source=(source =~/\w{2,4}/) ? source : nil
+              @@source=unless @@source.is_a?(String) \
+              and @@source =~/\w{2,4}/
+                source
+              else @@source
+              end
+            when /target:/
+              @@targets=unless @@targets.is_a?(Array)
+                sel.split(/targets?:\s*|\s+/) - ['']
+              else @@targets
+              end
+            end
+          end
+        else
+          puts %{(create) missing instruction file: "#{filename.languages_src_tgt}"\n  contents e.g.:\n    source: en\n    target: de fr es ja ru zh\n  no po target languages found}
+          exit
+        end
+      end
+    end
+    self
+  end
+  def language
+    def source_language_selected(src=nil)
+      @@source=if not @@source.nil? \
+      and @@source.is_a?(String) \
+      and @@source =~/\w{2,4}/
+        @@source
+      elsif (src \
+      && src.is_a?(String) \
+      && src.length > 1)
+        src
+      else
+        src=languages_from_file.language_source
+      end
+    end
+    def translation_languages_selected(targets=nil) #translation_languages
+      @@targets=if not @@targets.nil? \
+      and @@targets.is_a?(Array) \
+      and @@targets.length > 0
+        @@targets
+      elsif (targets \
+      && targets.is_a?(Array) \
+      && targets.length > 0)
+        targets
+      else
+        targets=languages_from_file.language_targets
+      end
+    end
+    def source_language_available
+      [source_language_selected] & sisu_languages_available
+    end
+    def translation_languages_selected_that_are_available
+      translation_languages_selected & sisu_languages_available
+    end
+    def info_on_selection
+      if translation_languages_selected != translation_languages_selected_that_are_available
+        <<-WOK
+WARNING: language selections mismatch
+
+The current language translation selection appears to be: #{translation_languages_selected_str}
+Of which the following are valid (available) selections:  #{translation_languages_selected_that_are_available_str}
+
+sisu available language list: #{sisu_languages_available_str}
+
+the following will be used: #{translation_languages_selected_that_are_available_str}
+The languages selected are located in the file:    #{filename.languages_src_tgt}
+        WOK
+      else
+        <<-WOK
+The current language translation selection is:  #{translation_languages_selected_str}
+The languages selected are located in the file: #{filename.languages_src_tgt}
+
+sisu available language list: #{sisu_languages_available_str}
+        WOK
+      end
+    end
+    def sisu_languages_available
+      $SiSU_Language_Codes.language_list.codes
+    end
+    def possible_translations
+      sisu_languages_available -  [source_language_selected]
+    end
+    def translation_languages_selected_str
+      language.translation_languages_selected.join(' ')
+    end
+    def source_language_available_str
+      source_language_available.join
+    end
+    def translation_languages_selected_that_are_available_str
+      language.translation_languages_selected_that_are_available.join(' ')
+    end
+    def sisu_languages_available_str
+      language.sisu_languages_available.join(' ')
+    end
+    def posible_translations_str
+      language.posible_translations.join(' ')
+    end
+    self
+  end
+  def files_src
+    def ssm
+      Dir.glob("#{language.source_language_selected}/*.ssm").sort
+    end
+    def sst
+      Dir.glob("#{language.source_language_selected}/*.sst").sort
+    end
+    def ssi
+      Dir.glob("#{language.source_language_selected}/*.ssi").sort
+    end
+    def all
+      Dir.glob("#{language.source_language_selected}/*{.ssm,.sst,.ssi}").sort
+    end
+    self
+  end
+  def po4a_cfg_file
+    File.open("#{Dir.pwd}/#{filename.po4a_cfg}",'w')
+  end
+  def po4a_create
+    def configure #po4a_cfg
+      po4a_cfg_arr=[]
+      po4a_cfg_arr \
+        << "[po4a_langs] #{language.translation_languages_selected_that_are_available_str}"
+      po4a_cfg_arr \
+        << "[po4a_paths] #{dir.pot}/$master.pot $lang:#{dir.po}/$lang/$master.po"
+      files_src.ssm.each do |file_src|
+        file_src_fn=file_src.gsub(/#{language.source_language_selected}\//,'')
+        po4a_cfg_arr \
+          << "[type: text] #{file_src} $lang:$lang/#{file_src_fn}"
+      end
+      files_src.sst.each do |file_src|
+        file_src_fn=file_src.gsub(/#{language.source_language_selected}\//,'')
+        po4a_cfg_arr \
+          << "[type: text] #{file_src} $lang:$lang/#{file_src_fn}"
+      end
+      files_src.ssi.each do |file_src|
+        file_src_fn=file_src.gsub(/#{language.source_language_selected}\//,'')
+        po4a_cfg_arr \
+          << "[type: text] #{file_src} $lang:$lang/#{file_src_fn}"
+      end
+      file=po4a_cfg_file
+      po4a_cfg_arr.each do |txt|
+      puts txt
+        file << txt << "\n"
+      end
+      file.close
+      cmd='po4a --keep 0 ' \
+      + po4a_flags.normal + ' ' \
+      + filename.po4a_cfg
+      #cmd='po4a --keep 0 --no-backups --package-name ' \
+      #+ 'sisu-manual' + ' ' \
+      #+ po4a_flags.normal + ' ' \
+      #+ filename.po4a_cfg
+      system(cmd); puts cmd
+    end
+    self
+  end
+  def project
+    def make
+      dir_mk(dir.pot)
+      language.translation_languages_selected_that_are_available.each do |lang_dir|
+        dir_lang="#{Dir.pwd}/#{dir.po}/#{lang_dir}"
+        dir_mk(dir_lang)
+      end
+      po4a_create.configure
+    end
+    def clean
+      #rm -f po/*/*.po~
+      #rm -rf ../build
+      FileUtils.rm_f Dir.glob("./#{dir.po}/*/*.po~")
+    end
+    def distclean
+      #rm -f po4a.cfg
+      #rm -rf $(LANGUAGES)
+      FileUtils::rm_f(filename.po4a_cfg)
+      FileUtils::rm_r(language.possible_translations,:force => true)
+    end
+    self
+  end
+end
+__END__