# encoding: utf-8
=begin

 * Name: SiSU

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

 * Author: Ralph Amissah

 * Copyright: (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
   2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014 Ralph Amissah,
   All Rights Reserved.

 * License: GPL 3 or later:

   SiSU, a framework for document structuring, publishing and search

   Copyright (C) Ralph Amissah

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

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

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

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

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

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

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

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

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

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

 ** Description: document abstraction

=end
module SiSU_AO_DocumentStructure
  class Extract
    def extract(h,o)
      h ? h : o
    end
  end
  class ObjectMetadata
    attr_accessor :is,:of,:tags,:obj,:digest
    def initialize
      @tags={}
      @is=@tmp=@digest=nil
      @of=:meta
    end
    def metadata(tags)
      of=     @of                                                              #String, classification - group
      is=     :meta                                                            #String, classification - specific type
      tags=   tags        || ((defined? o.tags)      ? o.tags    : {})         #String, metadata type/tag
      obj=     nil
      @of,@is,@tags,@obj=of,is,tags,obj
      self
    end
  end
  class ObjectMeta
    attr_accessor :obj,:is,:of,:tag,:digest,:tmp
    def initialize
      @is=@obj=@tag=@digest=@digest=@tmp=nil
      @of=:meta
    end
    def metadata(h,o=nil)
      of=     @of                                                              #String, classification - group
      is=     :meta                                                            #String, classification - specific type
      tag=    h[:tag]     || ((defined? o.tag)       ? o.tag     : nil)        #String, metadata type/tag
      obj=    h[:obj]     || ((defined? o.obj)       ? o.obj     : nil)        #String, text content
      tmp=    h[:tmp]     || ((defined? o.tmp)       ? o.tmp     : nil)        #available for processing, empty after use
      digest= h[:digest]  || ((defined? o.digest)    ? o.digest  : nil)        #hash digests, either sha256 or md5
      @of,@is,@tag,@obj,@digest,@tmp=of,is,tag,obj,digest,tmp
      self
    end
  end
  class ObjectHeading
    attr_accessor :obj,:is,:tags,:of,:lv,:ln,:lc,:toc_,:name,:idx,:ocn,:odv,:osp,:node,:parent,:ocn_,:note_,:autonum_,:digest,:tmp
    def initialize
      @of=:para
      @is=@obj=@lv=@ln=@lc=@toc_=@name=@idx=@size=@ocn=@odv=@osp=@node=@parent=@ocn_=@note_=@autonum_=@digest=@tmp=nil
      @tags=[]
    end
    def heading_ln(lv)
      case lv
      when /A/ then 0
      when /B/ then 1
      when /C/ then 2
      when /D/ then 3
      when /1/ then 4
      when /2/ then 5
      when /3/ then 6
      when /4/ then 7
      when /5/ then 8
      when /6/ then 9
      end
    end
    def heading_lv(ln)
      case ln.to_s
      when /0/ then 'A'
      when /1/ then 'B'
      when /2/ then 'C'
      when /3/ then 'D'
      when /4/ then '1'
      when /5/ then '2'
      when /6/ then '3'
      when /7/ then '4'
      when /8/ then '5'
      when /9/ then '6'
      end
    end
    def heading(h,o=nil)
      if not h[:ln] \
      and (h[:lv] and h[:lv]=~/[1-6A-D]/)
        h[:ln]=heading_ln(h[:lv])
      elsif not h[:lv] \
      and (h[:ln] and h[:ln].to_s=~/[0-9]/)
        h[:lv]=heading_lv(h[:ln])
      end
      of=     @of                                                              #String, classification - group
      is=     :heading                                                         #String, classification - specific type
      name=   h[:name]    || ((defined? o.name)      ? o.name    : nil)        #String, named object?
      tags=   h[:tags]    || ((defined? o.tags)      ? o.tags    : [])         #Array, associated object tags, names if any
      obj=    h[:obj]     || ((defined? o.obj)       ? o.obj     : nil)        #String, text content
      idx=    h[:idx]     || ((defined? o.idx)       ? o.idx     : nil)        #String, book index provided?
      ocn=    h[:ocn]     || ((defined? o.ocn)       ? o.ocn     : nil)        #Integer, sequential on substantive-content objects
      odv=    h[:odv]     || ((defined? o.odv)       ? o.odv     : nil)
      osp=    h[:osp]     || ((defined? o.osp)       ? o.osp     : nil)
      node=   h[:node]    || ((defined? o.node)      ? o.node    : nil)        #[Node relationship doc structure info]
      parent= h[:parent]  || ((defined? o.parent)    ? o.parent  : nil)        #[Node parent]
      lv=     h[:lv]      || ((defined? o.lv)        ? o.lv      : nil)        #Alpha-numeric, document structure as used in markup, A-D then 1-6
      ln=     h[:ln]      || ((defined? o.ln)        ? o.ln      : nil)        #Integer, document structure level, for convenience in processing 1-9
      lc=     h[:lc]      || ((defined? o.lc)        ? o.lc      : nil)        #Integer, document structure collapsed level, convenience (collapse sisu's dual level document structure for markup with simple linear structure)
      toc_=   h[:toc_]    || ((defined? o.toc_)      ? o.toc_    : false)      #Bool, do not include in toc, (relevant to headings)
      ocn_=if h[:ocn_].nil? then ((defined? o.ocn_)  ? o.ocn_    : true)       #Bool? no ocn, non-substantive content, do not include in toc #consider
      else  h[:ocn_]
      end
      autonum_= if h[:autonum_].nil? then ((defined? o.autonum_) ? o.autonum_ : true) #Bool? auto-numbering if requested default on, false suppresses
      else  h[:autonum_]
      end
      note_=  h[:note_]   || ((defined? o.note_)     ? o.note_   : false)      #Bool, endnotes/footnotes? (processing optimization)
      digest= h[:digest]  || ((defined? o.digest)    ? o.digest  : nil)        #hash digests, either sha256 or md5
      tmp=    h[:tmp]     || ((defined? o.tmp)       ? o.tmp     : nil)        #available for processing, empty after use
      @of,@is,@lv,@ln,@lc,@name,@tags,@obj,@idx,@ocn,@odv,@osp,@node,@parent,@toc_,@ocn_,@note_,@autonum_,@digest,@tmp=of,is,lv,ln,lc,name,tags,obj,idx,ocn,odv,osp,node,parent,toc_,ocn_,note_,autonum_,digest,tmp
      self
    end
    def heading_insert(h,o=nil)
      heading(h,o=nil)
      @is=     :heading_insert                                                 #String, classification - specific type
      self
    end
  end
  class ObjectPara
    attr_accessor :obj,:is,:tags,:of,:name,:idx,:bullet_,:indent,:hang,:ocn,:odv,:osp,:parent,:note_,:image_,:ocn_,:digest,:tmp
    def initialize
      @of=:para
      @is=@obj=@name=@idx=@bullet_=@indent=@hang=@size=@ocn=@odv=@osp=@parent=@note_=@image_=@ocn_=@digest=@tmp=nil
      @tags=[]
    end
    def paragraph(h,o=nil)
      of=    @of                                                               #String, classification - group
      is=    :para                                                             #String, classification - specific type
      name=   h[:name]    || ((defined? o.name)      ? o.name    : nil)        #String, named object?
      tags=   h[:tags]    || ((defined? o.tags)      ? o.tags    : [])         #Array, associated object tags, names if any
      obj=    h[:obj]     || ((defined? o.obj)       ? o.obj     : nil)        #String, text content
      idx=    h[:idx]     || ((defined? o.idx)       ? o.idx     : nil)        #String, book index provided?
      ocn=    h[:ocn]     || ((defined? o.ocn)       ? o.ocn     : nil)        #Integer, sequential on substantive-content objects
      odv=    h[:odv]     || ((defined? o.odv)       ? o.odv     : nil)
      osp=    h[:osp]     || ((defined? o.osp)       ? o.osp     : nil)
      parent= h[:parent]  || ((defined? o.parent)    ? o.parent  : nil)        #[Node parent]
      indent= h[:indent].to_s || ((defined? o.indent) ? o.indent.to_s : nil)   #Integer, indent level
      hang=   h[:hang].to_s || ((defined? o.hang)    ? o.hang.to_s : nil)      #Integer, hanging indent level
      bullet_=h[:bullet_] || ((defined? o.bullet_)   ? o.bullet_ : false)      #Bool, bulleted?
      note_=  h[:note_]   || ((defined? o.note_)     ? o.note_   : false)      #Bool, endnotes/footnotes? (processing optimization)
      image_= h[:image_]  || ((defined? o.image_)    ? o.image_  : false)      #Bool, images? (processing optimization)
      ocn_=if h[:ocn_].nil? then ((defined? o.ocn_)  ? o.ocn_    : true)       #Bool? no ocn, non-substantive content, do not include in toc #consider
      else  h[:ocn_]
      end
      digest= h[:digest]  || ((defined? o.digest)    ? o.digest  : nil)        #hash digests, either sha256 or md5
      tmp=    h[:tmp]     || ((defined? o.tmp)       ? o.tmp     : nil)        #available for processing, empty after use
      @of,@is,@name,@tags,@obj,@indent,@hang,@bullet_,@idx,@ocn,@odv,@osp,@parent,@image_,@note_,@ocn_,@digest,@tmp=of,is,name,tags,obj,indent,hang,bullet_,idx,ocn,odv,osp,parent,image_,note_,ocn_,digest,tmp
      self
    end
    def docinfo(h,o=nil)
      of=    @of                                                               #String, classification - group
      is=    :docinfo                                                          #String, classification - specific type
      name=   h[:name]    || ((defined? o.name)      ? o.name    : nil)        #String, named object?
      tags=   h[:tags]    || ((defined? o.tags)      ? o.tags    : nil)        #Array, associated object tags, names if any
      obj=    h[:obj]     || ((defined? o.obj)       ? o.obj     : nil)        #String, text content
      idx=    nil                                                              #String, book index provided?
      ocn=    nil                                                              #Integer, sequential on substantive-content objects
      odv=    h[:odv]     || ((defined? o.odv)       ? o.odv     : nil)
      osp=    h[:osp]     || ((defined? o.osp)       ? o.osp     : nil)
      parent= h[:parent]  || ((defined? o.parent)    ? o.parent  : nil)        #[Node parent]
      indent= nil                                                              #Integer, indent level
      hang= nil                                                                #Integer, indent level
      bullet_=false                                                            #Bool, bulleted?
      note_=  false                                                            #Bool, endnotes/footnotes? (processing optimization)
      image_= h[:image_]  || ((defined? o.image_)    ? o.image_  : false)      #Bool, images? (processing optimization)
      ocn_=if h[:ocn_].nil? then ((defined? o.ocn_)  ? o.ocn_    : true)       #Bool? no ocn, non-substantive content, do not include in toc #consider
      else  h[:ocn_]
      end
      digest= h[:digest]  || ((defined? o.digest)    ? o.digest  : nil)        #hash digests, either sha256 or md5
      tmp=    h[:tmp]     || ((defined? o.tmp)       ? o.tmp     : nil)        #available for processing, empty after use
      @of,@is,@name,@tags,@obj,@indent,@hang,@bullet_,@idx,@ocn,@odv,@osp,@parent,@image_,@note_,@ocn_,@digest,@tmp=of,is,name,tags,obj,indent,hang,bullet_,idx,ocn,odv,osp,parent,image_,note_,ocn_,digest,tmp
      self
    end
  end
  class ObjectBlockTxt
    attr_accessor :obj,:is,:of,:tags,:idx,:ocn,:odv,:osp,:parent,:note_,:number_,:ocn_,:digest,:tmp
    def initialize
      @of=:block
      @is=@obj=@idx=@ocn=@odv=@osp=@parent=@note_=@number_=@ocn_=@digest=@tmp=nil
      @tags=[]
    end
    def code(h,o=nil)
      of=      @of                                                             #String, classification - group #alt 'code'
      is=      :code                                                           #String, classification - specific type
      tags=    h[:tags]    || ((defined? o.tags)     ? o.tags    : [])         #Array, associated object tags, names if any
      obj=     h[:obj]     || ((defined? o.obj)      ? o.obj     : nil)        #String, text content
      idx=     h[:idx]     || ((defined? o.idx)      ? o.idx     : nil)        #String, book index provided?
      ocn=     h[:ocn]     || ((defined? o.ocn)      ? o.ocn     : nil)        #Integer, sequential on substantive-content objects
      odv=     h[:odv]     || ((defined? o.odv)      ? o.odv     : nil)
      osp=     h[:osp]     || ((defined? o.osp)      ? o.osp     : nil)
      parent=  h[:parent]  || ((defined? o.parent)   ? o.parent  : nil)        #[Node parent]
      number_= h[:number_] || ((defined? o.number_)  ? o.number_ : false)      #Bool, numbered or not?
      note_=   h[:note_]   || ((defined? o.note_)    ? o.note_   : false)      #Bool, endnotes/footnotes? (processing optimization)
      ocn_= if h[:ocn_].nil? then ((defined? o.ocn_) ? o.ocn_    : true)       #Bool? no ocn, non-substantive content, do not include in toc #consider
      else     h[:ocn_]
      end
      num=     h[:num]     || ((defined? o.num)      ? o.num     : nil)
      digest=  h[:digest]  || ((defined? o.digest)   ? o.digest  : nil)        #hash digests, either sha256 or md5
      tmp=     h[:tmp]     || ((defined? o.tmp)      ? o.tmp     : nil)        #available for processing, empty after use
      @of,@is,@tags,@obj,@idx,@ocn,@odv,@osp,@parent,@number_,@note_,@ocn_,@num,@digest,@tmp=of,is,tags,obj,idx,ocn,odv,osp,parent,number_,note_,ocn_,num,digest,tmp
      self
    end
    def block(h,o=nil)
      of=      @of                                                             #String, classification - group
      is=      :block                                                          #String, classification - specific type
      tags=    h[:tags]    || ((defined? o.tags)     ? o.tags    : [])         #Array, associated object tags, names if any
      obj=     h[:obj]     || ((defined? o.obj)      ? o.obj     : nil)        #String, text content
      idx=     h[:idx]     || ((defined? o.idx)      ? o.idx     : nil)        #String, book index provided?
      ocn=     h[:ocn]     || ((defined? o.ocn)      ? o.ocn     : nil)        #Integer, sequential on substantive-content objects
      odv=     h[:odv]     || ((defined? o.odv)      ? o.odv     : nil)
      osp=     h[:osp]     || ((defined? o.osp)      ? o.osp     : nil)
      parent=  h[:parent]  || ((defined? o.parent)   ? o.parent  : nil)        #[Node parent]
      note_=   h[:note_]   || ((defined? o.note_)    ? o.note_   : false)      #Bool, endnotes/footnotes? (processing optimization)
      ocn_= if h[:ocn_].nil? then ((defined? o.ocn_) ? o.ocn_    : true)       #Bool? no ocn, non-substantive content, do not include in toc #consider
      else     h[:ocn_]
      end
      num=     h[:num]     || ((defined? o.num)      ? o.num     : nil)
      digest=  h[:digest]  || ((defined? o.digest)   ? o.digest  : nil)        #hash digests, either sha256 or md5
      tmp=     h[:tmp]     || ((defined? o.tmp)      ? o.tmp     : nil)        #available for processing, empty after use
      @of,@is,@tags,@obj,@idx,@ocn,@odv,@osp,@parent,@note_,@ocn_,@num,@digest,@tmp=of,is,tags,obj,idx,ocn,odv,osp,parent,note_,ocn_,num,digest,tmp
      self
    end
    def group(h,o=nil)
      of=      @of                                                             #String, classification - group
      is=      :group                                                          #String, classification - specific type
      tags=    h[:tags]    || ((defined? o.tags)     ? o.tags    : [])         #Array, associated object tags, names if any
      obj=     h[:obj]     || ((defined? o.obj)      ? o.obj     : nil)        #String, text content
      idx=     h[:idx]     || ((defined? o.idx)      ? o.idx     : nil)        #String, book index provided?
      ocn=     h[:ocn]     || ((defined? o.ocn)      ? o.ocn     : nil)        #Integer, sequential on substantive-content objects
      odv=     h[:odv]     || ((defined? o.odv)      ? o.odv     : nil)
      osp=     h[:osp]     || ((defined? o.osp)      ? o.osp     : nil)
      parent=  h[:parent]  || ((defined? o.parent)   ? o.parent  : nil)        #[Node parent]
      note_=   h[:note_]   || ((defined? o.note_)    ? o.note_   : false)      #Bool, endnotes/footnotes? (processing optimization)
      ocn_= if h[:ocn_].nil? then ((defined? o.ocn_) ? o.ocn_    : true)       #Bool? no ocn, non-substantive content, do not include in toc #consider
      else     h[:ocn_]
      end
      num=     h[:num]     || ((defined? o.num)      ? o.num     : nil)
      digest=  h[:digest]  || ((defined? o.digest)   ? o.digest  : nil)        #hash digests, either sha256 or md5
      tmp=     h[:tmp]     || ((defined? o.tmp)      ? o.tmp     : nil)        #available for processing, empty after use
      @of,@is,@tags,@obj,@idx,@ocn,@odv,@osp,@parent,@note_,@ocn_,@num,@digest,@tmp=of,is,tags,obj,idx,ocn,odv,osp,parent,note_,ocn_,num,digest,tmp
      self
    end
    def alt(h,o=nil)                                                           #see block
      of=      @of                                                             #String, classification - group
      is=      :alt                                                            #String, classification - specific type
      tags=    h[:tags]    || ((defined? o.tags)     ? o.tags    : [])         #Array, associated object tags, names if any
      obj=     h[:obj]     || ((defined? o.obj)      ? o.obj     : nil)        #String, text content
      idx=     h[:idx]     || ((defined? o.idx)      ? o.idx     : nil)        #String, book index provided?
      ocn=     h[:ocn]     || ((defined? o.ocn)      ? o.ocn     : nil)        #Integer, sequential on substantive-content objects
      odv=     h[:odv]     || ((defined? o.odv)      ? o.odv     : nil)
      osp=     h[:osp]     || ((defined? o.osp)      ? o.osp     : nil)
      parent=  h[:parent]  || ((defined? o.parent)   ? o.parent  : nil)        #[Node parent]
      note_=   h[:note_]   || ((defined? o.note_)    ? o.note_   : false)      #Bool, endnotes/footnotes? (processing optimization)
      ocn_= if h[:ocn_].nil? then ((defined? o.ocn_) ? o.ocn_    : true)       #Bool? no ocn, non-substantive content, do not include in toc #consider
      else     h[:ocn_]
      end
      num=     h[:num]     || ((defined? o.num)      ? o.num     : nil)
      digest=  h[:digest]  || ((defined? o.digest)   ? o.digest  : nil)        #hash digests, either sha256 or md5
      tmp=     h[:tmp]     || ((defined? o.tmp)      ? o.tmp     : nil)        #available for processing, empty after use
      @of,@is,@tags,@obj,@idx,@ocn,@odv,@osp,@parent,@note_,@ocn_,@num,@digest,@tmp=of,is,tags,obj,idx,ocn,odv,osp,parent,note_,ocn_,num,digest,tmp
      self
    end
    def verse(h,o=nil)                                                         #part of poem decide how you deal with this
      of=      @of                                                             #String, classification - group
      is=      :verse                                                          #String, classification - specific type
      tags=    h[:tags]    || ((defined? o.tags)     ? o.tags    : [])         #Array, associated object tags, names if any
      obj=     h[:obj]     || ((defined? o.obj)      ? o.obj     : nil)        #String, text content
      idx=     h[:idx]     || ((defined? o.idx)      ? o.idx     : nil)        #String, book index provided?
      ocn=     h[:ocn]     || ((defined? o.ocn)      ? o.ocn     : nil)        #Integer, sequential on substantive-content objects
      odv=     h[:odv]     || ((defined? o.odv)      ? o.odv     : nil)
      osp=     h[:osp]     || ((defined? o.osp)      ? o.osp     : nil)
      parent=  h[:parent]  || ((defined? o.parent)   ? o.parent  : nil)        #[Node parent]
      ocn_= if h[:ocn_].nil? then ((defined? o.ocn_) ? o.ocn_    : true)       #Bool? no ocn, non-substantive content, do not include in toc #consider
      else     h[:ocn_]
      end
      num=     h[:num]     || ((defined? o.num)      ? o.num     : nil)
      digest=  h[:digest]  || ((defined? o.digest)   ? o.digest  : nil)        #hash digests, either sha256 or md5
      tmp=     h[:tmp]     || ((defined? o.tmp)      ? o.tmp     : nil)        #available for processing, empty after use
      @of,@is,@tags,@obj,@idx,@ocn,@odv,@osp,@parent,@note_,@ocn_,@num,@digest,@tmp=of,is,tags,obj,idx,ocn,odv,osp,parent,note_,ocn_,num,digest,tmp
      @h=nil
      self
    end
  end
  class ObjectTable
    attr_accessor :obj,:is,:of,:lv,:tags,:name,:idx,:indent,:hang,:size,:ocn,:number,:head_,:cols,:widths,:odv,:osp,:parent,:note_,:ocn_,:digest,:tmp
    def initialize
      @of=:block
      @is=@obj=@lv=@name=@idx=@indent=@hang=@size=@ocn,@number,@head_,@cols,@widths=@odv=@osp=@parent=@note_=@ocn_=@num=@digest=@tmp=nil
      @tags=[]
    end
    def table(h,o=nil)
      of=     @of                                                              #String, classification - group
      is=     :table                                                           #String, classification - specific type
      tags=   h[:tags]    || ((defined? o.tags)      ? o.tags    : [])         #Array, associated object tags, names if any
      cols=   h[:cols]    || ((defined? o.cols)      ? o.cols    : nil)
      widths= h[:widths]  || ((defined? o.widths)    ? o.widths  : nil)
      obj=    h[:obj]     || ((defined? o.obj)       ? o.obj     : nil)        #String, text content
      idx=    h[:idx]     || ((defined? o.idx)       ? o.idx     : nil)        #String, book index provided?
      ocn=    h[:ocn]     || ((defined? o.ocn)       ? o.ocn     : nil)        #Integer, sequential on substantive-content objects
      odv=    h[:odv]     || ((defined? o.odv)       ? o.odv     : nil)
      osp=    h[:osp]     || ((defined? o.osp)       ? o.osp     : nil)
      parent= h[:parent]  || ((defined? o.parent)    ? o.parent  : nil)        #[Node parent]
      head_=  h[:head_]   || ((defined? o.head_)     ? o.head_   : false)
      note_=  h[:note_]   || ((defined? o.note_)     ? o.note_   : false)      #Bool, endnotes/footnotes? (processing optimization)
      ocn_=if h[:ocn_].nil? then ((defined? o.ocn_)  ? o.ocn_    : true)       #Bool? no ocn, non-substantive content, do not include in toc #consider
      else  h[:ocn_]
      end
      num=     h[:num]     || ((defined? o.num)      ? o.num     : nil)
      digest= h[:digest]  || ((defined? o.digest)    ? o.digest  : nil)        #hash digests, either sha256 or md5
      tmp=    h[:tmp]     || ((defined? o.tmp)       ? o.tmp     : nil)        #available for processing, empty after use
      @of,@is,@tags,@cols,@widths,@obj,@idx,@ocn,@odv,@osp,@parent,@head_,@note_,@ocn_,@num,@digest,@tmp=of,is,tags,cols,widths,obj,idx,ocn,odv,osp,parent,head_,note_,ocn_,num,digest,tmp
      self
    end
  end
  class ObjectImage
    attr_accessor :obj,:is,:of,:lv,:idx,:size,:ocn,:parent,:note_,:ocn_,:digest,:tmp
    def initialize
      @of=:image
      @is=@obj=@lv=@idx=@size=@ocn=@parent=@note_=@ocn_=@tmp=@digest=nil
      @tags=[]
    end
    def image(h,o=nil)                                                         #not yet used, and what of a paragraph containing several images, consider
      of=     @of                                                              #String, classification - group
      is=     :image                                                           #String, classification - specific type
      tags=   h[:tags]    || ((defined? o.tags)      ? o.tags    : [])         #Array, associated object tags, names if any
      obj=    h[:obj]     || ((defined? o.obj)       ? o.obj     : nil)        #String, text content
      size=   h[:size]    || ((defined? o.size)      ? o.size    : nil)
      idx=    h[:idx]     || ((defined? o.idx)       ? o.idx     : nil)        #String, book index provided?
      ocn=    h[:ocn]     || ((defined? o.ocn)       ? o.ocn     : nil)        #Integer, sequential on substantive-content objects
      odv=    h[:odv]     || ((defined? o.odv)       ? o.odv     : nil)
      osp=    h[:osp]     || ((defined? o.osp)       ? o.osp     : nil)
      parent= h[:parent]  || ((defined? o.parent)    ? o.parent  : nil)        #[Node parent]
      note_=  h[:note_]   || ((defined? o.note_)     ? o.note_   : false)      #Bool, endnotes/footnotes? (processing optimization)
      ocn_=if h[:ocn_].nil? then ((defined? o.ocn_)  ? o.ocn_    : true)       #Bool? no ocn, non-substantive content, do not include in toc #consider
      else  h[:ocn_]
      end
      digest= h[:digest]  || ((defined? o.digest)    ? o.digest  : nil)        #hash digests, either sha256 or md5
      tmp=    h[:tmp]     || ((defined? o.tmp)       ? o.tmp     : nil)        #available for processing, empty after use
      @of,@is,@tags,@obj,@size,@idx,@ocn,@odv,@osp,@parent,@note_,@ocn_,@digest,@tmp=of,is,tags,obj,size,idx,ocn,odv,osp,parent,note_,ocn_,digest,tmp
      self
    end
  end
  class ObjectStructure
    attr_accessor :obj,:tag,:node,:lv,:ln,:lc,:status,:is,:of,:tmp
    def initialize
      @of=:structure
      @is=@obj=@node=@lv=@ln=@lc=@status=@tmp=nil
    end
    def xml_dom(h,o=nil)
      of=     @of                                                              #String, classification - group
      is=     :xml_dom                                                         #String, classification - specific type
      obj=    h[:obj]     || ((defined? o.obj)       ? o.obj     : '')         #String, text content
      lv=     h[:lv]      || ((defined? o.lv)        ? o.lv      : nil)        #Alpha-numeric, document structure as used in markup, A-D then 1-6
      ln=     h[:ln]      || ((defined? o.ln)        ? o.ln      : nil)        #Integer, document structure level, for convenience in processing 1-9
      lc=     h[:lc]      || ((defined? o.lc)        ? o.lc      : nil)        #Integer, document structure collapsed level, convenience (collapse sisu's dual level document structure for markup with simple linear structure)
      node=   h[:node]    || ((defined? o.node)      ? o.node    : nil)        #[Node relationship doc structure info]
      status= h[:status]  || ((defined? o.status)    ? o.status  : nil)        #tag status open or close
      tmp=    h[:tmp]     || ((defined? o.tmp)       ? o.tmp     : nil)        #available for processing, empty after use
      @of,@is,@obj,@status,@node,@lv,@ln,@lc,@tmp=of,is,obj,status,node,lv,ln,lc,tmp
      self
    end
  end
  class ObjectComment
    attr_accessor :obj,:is,:of,:tmp
    def initialize
      @of=:comment
      @is=@obj=@tmp=nil
    end
    def comment(h,o=nil)
      of=     @of                                                              #String, classification - group
      is=     :comment                                                         #String, classification - specific type
      obj=    h[:obj]     || ((defined? o.obj)       ? o.obj     : nil)        #String, text content
      tmp=    h[:tmp]     || ((defined? o.tmp)       ? o.tmp     : nil)        #available for processing, empty after use
      @of,@is,@obj,@tmp=of,is,obj,tmp
      self
    end
  end
  class ObjectFlag
    attr_accessor :obj,:is,:of,:flag,:mod,:tmp
    def initialize
      @of=:flag
      @is=@obj=@flag=@mod=@tmp=nil
    end
    def flag(h,o=nil)
      of=     @of                                                              #String, classification - group
      is=     :flag                                                            #String, classification - specific type
      obj=    nil                                                              #String, text content
      flag=   h[:flag]     || ((defined? o.flag)      ? o.flag    : nil)       #String, text content
      mod=    h[:mod]      || ((defined? o.mod)       ? o.mod     : nil)       #String, text content
      tmp=    h[:flag]     || ((defined? o.tmp)       ? o.tmp     : nil)       #available for processing, empty after use
      @of,@is,@obj,@flag,@mod,@tmp=of,is,obj,flag,mod,tmp
      self
    end
    def flag_ocn(h,o=nil)
      of=     @of                                                              #String, classification - group
      is=     :flag_ocn                                                        #String, classification - specific type
      obj=    nil                                                              #String, text content
      flag=   h[:flag]     || ((defined? o.flag)      ? o.flag    : nil)       #String, text content
      mod=    h[:mod]      || ((defined? o.mod)       ? o.mod     : nil)       #String, text content
      tmp=    h[:flag]     || ((defined? o.tmp)       ? o.tmp     : nil)       #available for processing, empty after use
      @of,@is,@obj,@flag,@mod,@tmp=of,is,obj,flag,mod,tmp
      self
    end
  end
  class ObjectLayout
    attr_accessor :obj,:is,:of,:from,:tmp
    def initialize
      @of=:layout
      @is=@obj=@from=@tmp=nil
    end
    def break(h,f=nil)                                                         #decide how to deal with
      of=     @of                                                              #String, classification - group
      is=     :break                                                           #String, classification - specific type
      obj=    h[:obj]                                                          #String, text content
      from=   f
      tmp=    h[:tmp]                                                          #available for processing, empty after use
      @of,@is,@obj,@from,@tmp=of,is,obj,from,tmp
      self
    end
    def insert(h,o=nil)                                                        #decide how to deal with, could mimic paragraph?
      of=     @of                                                              #String, classification - group
      is=     :insert                                                          #String, classification - specific type
      obj=    h[:obj]     || ((defined? o.obj)       ? o.obj     : nil)        #String, text content
      tmp=    h[:tmp]     || ((defined? o.tmp)       ? o.tmp     : nil)        #available for processing, empty after use
      @of,@is,@obj,@tmp=of,is,obj,tmp
      self
    end
  end
end
__END__
# ~# |-# no paragraph number # -# not included in toc
