[all pages:] introduction message/location/muli format dtd xantlr tdom ops paisley metajava umod option auxiliaries d2d downloads & licenses people bibliography APPENDICES:: white papers white papers 2 white papers 3 project struct proposal SOURCE:option.dtd SOURCE:dtd.umod DOC:deliverables.ddf DOC-DE:deliverables.ddf DOC:mtdocpage.ddf DOC-DE:mtdocpage.ddf DOC-EN:lablog.ddf SOURCE:basic.dd2 DOC:xslt.ddf SOURCE:xslt.dd2 DOC:meta.ddf [site map]



All pages: introduction message/location/muli format dtd xantlr tdom ops paisley metajava umod option auxiliaries d2d downloads & licenses people bibliography APPENDICES:: white papers white papers 2 white papers 3 project struct proposal SOURCE:option.dtd SOURCE:dtd.umod DOC:deliverables.ddf DOC-DE:deliverables.ddf DOC:mtdocpage.ddf DOC-DE:mtdocpage.ddf DOC-EN:lablog.ddf SOURCE:basic.dd2 DOC:xslt.ddf SOURCE:xslt.dd2 DOC:meta.ddf [site map]



go one page back go to start go to start go one page ahead
DOC-EN:lablog.ddf bandm meta_tools DOC:xslt.ddf

APPENDIX: The ddf Document Type Definition File for the General Purpose Document Architecture d2d_gp



The following text shows the d2d text type definition (according to the d2d ddf text type definition mechanism), which defines the general purpose document architecture d2d_gp. Its basic outlines are explained in in a dedicated sectionof the d2d user doc.

The top-level definitions are either to be used directly, or to be instantiated, parametrized and taylored to the user's need by the parametrization mechanimsms described in another dedicated section of the d2d user doc.

Please refer also to the automatically generated html documentation. Please note that this docu is a comment on the instantiated("dynamic") case: The top-level module "basic.deliverables" (to be found at the end of the following source text) does import other modules (from the preceeding parts of the following source text) not in an unaltered way, but by parameterizing them. And so do the other modules, on lower instantiation level, recursively.
This is to be seen clearly in the following sources in the "import ..." at the start of each module. So the dynamic documentation differs substantially from the following file in all regular expressions which are affected by parameterization.

// basic.dd2, General Purpose and Simple Publishing Architecture 


//========================================================
module basic
//========================================================

  xmlns a = "http://bandm.eu/doctypes/d2d_gp/basic" is default

  // is used by several modules (inlineElements, table, image), but 
  // may appear only once as an xslt:param declaration:
  docu to_xhtml_1_0 = "#param user.showlabels"

  docu to_xhtml_1_0 = #d2d

    #param user.refTitle #xp 'inline' " 
  // maybe "toolTip" "inline" or none of these

  //is needed by interdocument AND simpleImage
      #template#name copyAltFromContext
        #choose 
          #when a:alt  
            #attribute alt
               #foreach a:alt#call a:getOneLineText
          #when a:image_alt  // FIXME ???? DISLOC ??
            #attribute alt
               #foreach a:image_alt#call a:getOneLineText
          #when @a:alt  
            #attribute alt#valueof @a:alt
          #when ancestor::a:floating/a:caption 
            #attribute alt#foreach ancestor::a:floating/a:caption#call a:getOneLineText
          #other#message#terminate ERROR, neither direct nor indirect \"alt\" text 
              found for embedded object #valueof .
  #/d2d

  docu user_en =
    #d2d
      #p
      This module is the central starting point for all our current applications
      of #link ../d2d.html#text d2d#/link, and a convenient starting point
      for any user. It contains (a) sub-modules and (b) functional libraries.
      #p
      The sub-modules are listed  the beginning of this file.
      Their sequential order in the 
      #link 0/bandm.eu/metatools/docs/usage/file_basic_ddf.html#text source file#/link
//      #link ../file_basic_ddf.html#text source file#/link
      is bottom-up in complexity: the very first sub-modules define infra-structure
      (like #link #loc __MODULE__basic.sets#text set#/link);
      the middle ones model different organizations of text
      (starting with #link#loc __MODULE__basic.inlineElements#text inlineElements#/link);
      at the end these are combined to a complete text corpus architecture
      (starting with #link #loc __MODULE__basic.structure#text structure#/link).
      #p
      The modules are in very different state of development:
      Some of them are fully operative 
      (like #link #loc __MODULE__basic.citation#text citation#/link);
      others are operative, but utmost simple 
      (like #link #loc __MODULE__basic.simpleLists#text simpleLists#/link);
      few are currently not employed at all, but only for demonstrative purpose
      (like #link #loc __MODULE__basic.personal_names_de#text personal_names_de#/link);
      #p
      Xslt code is currently (20150423) only given into xhtml_1_0, and into
      source files for different processors, allowing to embed the graphical 
      output of lilypond, musixtex and LaTeX source directly. This is supported
      by the module 
      #link #loc __MODULE__basic.interDocuments#text interDocuments#/link
      together with a dedicated Makefile system.
      #p
      The xslt code in the following modules assumes some procedures (for string
      and file name manipulation, etc.) to be provided by the basic library
      "libbasic.xslt". #nl
      On the other side of the scale it assumes that the top-level module,
      which finally plugs all the sub-modules together, provides also some global
      services like a template with name "muliDefault", to find the translation into
      the selected language, and some parameter definitions, which have default values
      depending on the top-level intentions ($user.p_kind_filter, GEHT ABER DOCHNICHT ZURZEITetc.)
      #p
      ((FIXME The basic lib could be moved HERE, as an inline code.))
      #nl
      ((FIXME The muliDefault could be moved from top-level to lowest level (REALLY?) ))
    #/d2d




  //------------------------------------------------------
  module sets
  //------------------------------------------------------

    chars all = 0x0001 .. 0xFFFE 
    docu user_en all = "Currently only four hex digits are decoded for
      character values, so that the higher unicode planes (beyond 0x0_FFFF) 
      can currently (201200208) not be described on the d2d #emph!input! side.
      (They can be output by xslt)."

    chars decimalDigit = '0'  .. '9' 
    chars upto1 = '01'
    chars upto2 = upto1 U '2'
    chars upto3 = upto2 U '3'

    chars decimalPositive = @decimalDigit ~+

    chars ascii_lower = 'a'..'z'
    chars ascii_upper = 'A'..'Z'
    chars ascii_alpha = ascii_lower U ascii_upper 

    chars alpha = @ascii_alpha  // FIXME alpha_lower U alpha_upper
    chars alpha_lower = @ascii_lower  // FIXME plus additonal non-ascii lower case letters
    chars alpha_upper = @ascii_upper  // FIXME plus additonal non-ascii upper case letters

    chars identFirstChar = @alpha
    chars identInnerChar = alpha U '_' U '-' U  decimalDigit

    chars ident = @identFirstChar ~ @identInnerChar ~*

    chars whitespace = ' ' U 0x0009 U 0x000a U 0x000D 
    chars non_whitespace = all - whitespace

  end module // sets

  //------------------------------------------------------
  module xmlInfra
  plain text is trimmed 
  xmlns xml = "http://www.w3.org/XML/1998/namespace" is default 
  import S from sets
  //------------------------------------------------------
	
    docu user_en = 
      #d2d
      Xml infrastructure, definition of ubiquituous attributes and their data type.
      Corresponds mostly to the xml namespace and the definitions in 
      #link 0/www.w3.org/XML/1998/namespace#/link, namely w.r.t. "xml:lang",
      "xml:space", "xml:base" and "xml:id"
      #/d2d


    chars nameStartChar	= ':_'  U  'A'..'Z'  U  'a'..'z' 
                        U (0x00C0..0x02FF - 0x00D7) - 0x00F7
                        U (0x0370..0x1FFF - 0x027E)
                        U 0x200C U 0x200D U 0x2070..0x218F
                        U 0x2C00..0x2FEF U 0x3001..0xD7FF 
                        U 0xF900..0xFDCF U 0xFDF0..0xFFFD 

    chars nameChar	= nameStartChar
                        U '-.' U '0'..'9' U 0x00B7 U 0x0300..0x036F 
                        U 0x203F..0x2040 


    chars name = @nameStartChar ~ @nameChar ~*
    chars nmtoken  = @nameChar ~*

    docu user_en name = 
      #d2d
      #commentchar \
      This definitions closely follows 
      #link http://www.w3.org/TR/2008/REC-xml-20081126/#loc NT-Name#/link,
      but still excludes  0x0001,0000..0x000E,FFFF, because the d2d input parser 
      currently (20120308) supports only sixteen bit characters.
      #commentchar /
      #/d2d


    public chars id = @name 
            with xmlrep att 


    chars lang = @S.ascii_lower~@S.ascii_lower ~( "-" ~ @S.ascii_upper~@S.ascii_upper)?
      with xmlrep att = "xml:lang" 

    chars langs = @lang~('+'~@lang)~*
      with xmlrep att = "xml:lang" 

    docu user_en lang = 
     #d2d The xml namespace description in #link 0/www.w3.org/XML/1998/namespace#/
         refers to #link 0/www.w3.org/TR/xml/#loc sec-lang-tag#/link  for the
         xml:lang attribute, which in turn refers to [IETF BCP 47], 
         which shall consist of "RFC 4646: Tags for Identifying Languages",
         #link 0/tools.ietf.org/html/rfc4646#/link  
         and "RFC 4647: Matching of Language Tags",
         #link 0/tools.ietf.org/html/rfc4647#/link.
         This is currently (20150423) already obsoleted by
         #link 0/tools.ietf.org/html/rfc5646#/link.
         #nl
         The second does define the processing of LISTS of language selectors,
	 but not their syntax. Anyhow, xml:lang seems to be forseen only for one(1)
         such language code. Our handling deliberately violates the specification and
         allows more than one language, cf. parser "langs".
         #nl
         The precedessor is [IETF RFC 3066] #link 0/www.ietf.org/rfc/rfc3066.txt#/link.
         #nl
         The character parser implemented here is a very primitive variant of the 
         older "two-(plus-two)" format of
         the ISO language code, and stores it as the xml standard attribute "xml:lang".
    #/d2d

    docu user_en langs = 
     #d2d Character parser for more than one language, written without spaces
          and separated by #src!+! character.
          They are ALSO stored into ONE SINGLE xml.lang attribute, because
          the spec is not totally clear about the cardinality of language values,
          ie. of tokens in this attribute. 
          INDEED, more than one language value are frequently required.
          The xslt library libbasic.d2d provides a 
	  template "#src!firstLangInList(String p-list)!" used for
          extracting the first language. This is normally treated as 
          dominant/main/default language.
    #/d2d

    enum space =  default, preserve
               with xmlrep att 

    public chars base = #chars   // FIXME more exact structure def: URL 
               with xmlrep trimmed att 

  end module // xmlInfra

    
  //------------------------------------------------------
  module physical
  //------------------------------------------------------
    docu user_en = 
     "Physical mark-up is mostly deprecated. 
      It follows the (old!) html way of physical mark-up.
      In this basic model this can only be applied to physical mark-up 
      itself/recursively.
      The declaration is naive, allowing multiple (nested) application
      of the same modifier.
      It can NOT be applied to semantic mark-up.
      Additionally this module defines some html/xml specific elements."

    tags MIXTURE  = bold| ital| ulin| blink| strikeout| scaps| hh 
                  | larger| smaller| indexlo | indexhi | spanstyle
    docu user_en MIXTURE = "What is recursively subject to physical mark-up"

    public tags EXPORTMIXTURE  = @MIXTURE | src | verbatimXml 

    docu user_en EXPORTMIXTURE = 
        "What can be adressed from outside, from some module using it."

    tags bold, ital, ulin, blink, strikeout, scaps, 
           larger, smaller, indexlo, indexhi = (#chars | @ MIXTURE)*

    tags spanstyle = #implicit style, (#chars | @ MIXTURE)*
    tags style = #chars with xmlrep att 

    tags hh = #empty
    docu to_xhtml_1_0 hh = 
         "#valueof $a:const.hashmark"
    docu user_en hh = "Draws a hashmark sign. Is currently the only
element which can be included in 
#link #loc __DECLARATION__basic.physical:src #text #src!src!."

    public tags verbatimXml = #chars with input verbatim
    docu user_en verbatimXml 
      = "A by-pass when generating html/xhtml documents. This element
         is intended to contain special html fragments which shall be 
         included verbatim in the output. This is achieved simply by an
         xslt rule which disables output escaping."
    docu to_xhtml_1_0 verbatimXml = "#valueof .#noescape"

    tags hr = #empty
    docu to_xhtml_1_0 hr = "#hr/"
    docu user_en hr = "Draws a horizontal line, leaned from html."

    docu to_xhtml_1_0 spanstyle = "#span #style {@a:style} #apply#xp (*|text())"
    docu user_en spanstyle = "Inserts an html-<span style='xxx'>"

    docu to_xhtml_1_0 bold = "#b#apply"
    docu user_en bold = "Explicitly select bold text. Deprecated. 
                         Consider to use #src!basic.inlineElements:xemph! instead."

    docu to_xhtml_1_0 ital = "#i#apply"
    docu user_en ital = "Explicitly select italic text. Deprecated. 
                         Consider to use #src!basic.inlineElements:emph! instead."

    docu to_xhtml_1_0 ulin  = "#span #style text-decoration:underline; #apply"
    docu user_en ital 
    = #d2d  Explicitly select underlined text. Deprecated. #nl
      The xslt rule generates a #src!<span style="text-decoration:underline;">!,
      because the old  #src!<u>! tag has not been taken over to xhtml 1.0 strict.
      #/d2d

    docu to_xhtml_1_0 blink = "#span #style text-decoration:blink; #apply"
    docu user_en blink 
    = #d2d  Explicitly select blinking text. Not only deprecated,
      but also bad manners.  #nl
      The xslt rule generates a #src!<span style="text-decoration:blink;">!,
      because the old  #src!<blink>! tag has not been taken over to xhtml 1.0 strict.
      #/d2d

    docu to_xhtml_1_0 strikeout = "#span #style text-decoration:line-through; #apply"
    docu user_en blink = "Explicitly select stroke-out text. Deprecated."

    docu to_xhtml_1_0 scaps = "#span #style font-variant:small-caps;  #apply"
    docu user_en scaps 
      = "Explicitly select small caps.  Deprecated.
         Consider to use #src!basic.inlineElements:opus! or
         #src!basic.inlineElements:pers!  instead."

    docu to_xhtml_1_0 larger = "#span #style font-size:130%; #apply"
    docu user_en larger = "Explicitly select larger font.  Deprecated."

    docu to_xhtml_1_0 smaller = "#span #style font-size:75%; #apply"
    docu user_en smaller = "Explicitly select smaller font.  Deprecated."

    docu to_xhtml_1_0 indexlo = "#sub #apply"
    docu user_en indexlo = "Explicitly select subscript. Deprecated."

    docu to_xhtml_1_0 indexhi = "#sup #apply"
    docu user_en indexhi = "Explicitly select superscript. Deprecated."


    tags src = (#chars | hh)*
    docu user_en src = 
        "Small piece of program source text, character data only! 
         Is rendered inline and in tele-type fonts.
         Can include #emph!only character data!, or 
         #link #loc __DECLARATION__basic.physical:hh #text #src!#hh hh/! #/link to
         include a hashmark sign \"#hh\"."
    docu to_xhtml_1_0 src = "#span#class source #apply"

  end module // physical

  //------------------------------------------------------
  module inlineElements

  xmlns xml = "http://www.w3.org/XML/1998/namespace"
  local node xmlrep naming = join upcased 
  plain text is trimmed 
  import S from sets
  import X from xmlInfra
  //------------------------------------------------------

    docu user_en = 
      "This module contains semantic (and a few physical) elements/text particles.
       Most of them can appear in every context.
       This module must be instantiated with the contents for emphasizing."

    public tags MIXTURE =  nl | ldots | label | ref | pers | opus | persop
                        | emph | xemph
    docu user_en MIXTURE = "Refers to all tags defined in this module. 
                            Meant as an export mechanism."

    tags emph = (EMPH_CONTENTS)*
    tags xemph = (EMPH_CONTENTS)*
    tags EMPH_CONTENTS = #GENERIC 
    docu user_en emph = "Something emphasized."
    docu user_en xemph = "Something strongly emphasized."
    docu user_en EMPH_CONTENTS = "To be replaced with an expression allowing
            all those things which can appear as subject to emphasis.
            (Should include plain pcdata.)"

    // xhtml:i and xhtml:span have same content model
    docu to_xhtml_1_0 emph = "#i #apply" 
    docu to_xhtml_1_0 xemph = "#b #apply"
    docu to_latex emph = "

    tags nl = #empty
    docu to_xhtml_1_0 nl = "#br/"
    docu user_en nl = "Forces a line break, but not a new paragraph."

    tags ldots = #empty
    docu to_xhtml_1_0 ldots = "#text ...#/text"
    docu user_en ldots = "Draws three low dots surrounded by spaces."

    chars label = @S.ident
    docu user_en label =
    #d2d
    Such a label binds an identifier to that certain location of the text body 
    where itself happens to appear. 
    #nl
    By setting the swich $user.showlabels="yes", these labels and others
    will be printed in the output, for proof reading.
    #nl
    Putting a label is possible nearly anywhere. If it is in the middle of 
    some text flow, it just marks this special text position. 
    But if it is in a structured object, e.g. the caption of a diagram, 
    its meaning is possibly referring to this diagram.
    This interpretation and the way a reference is generated may depend on 
    the "ref" elements.
    #/d2d

    docu to_xhtml_1_0 label = 
    #d2d
      #if $user.showlabels='yes'
         #x-var tx #xp text()
         #if preceding::a:label[text()=$tx] or following::a:label[text()=$tx]
           #span #class error  #i multiple label  // FIXME font-size:75%; 
         #/if
         #span #class debug #valueof text()
      #/if
      #a #name {text()}
    #/template
    #/d2d

	
    chars ref = @S.ident
    docu user_en ref = 
    #d2d
      Refering is possible nearly anywhere. Mostly it is to a label.
      #nl
      A hyper-ref link will be generated and its textual appearance will be constructed
      automatically. There are many different strategies, eg. generating
      text like  "in this list" or "in section 2.1.2 (TITLE OF THE SECTION)".
      These strategies are selectable and respect the current base language
      of the text.
      #nl 
      (This is achieved by calling the named template "muliDefault", which 
      makes translations into the "default" language.)
      #nl 
      The #emph!implementation! of each rendering strategy starts always
      with the Xslt template matching "a:ref" and works as follows:
      #list
      #i Identify the positional context of the reference, e.g. the innermost
	 enclosing section, table, list, etc.
      #i Find the label element referred to.
      #i If not found, an error is generated and an alerting 
         meta-element inserted in the output.
      #i Otherwise, start a #src!mode=getreftext! visiting of the label,
	 with the refering context stored to parameters.
      #i This visiting traverses upward, up to a nearest common parent, while 
         accumulating the text corresponding to the downward navigation so far.
      #i In case of lists and tables as part of TEXT FLOW, the generation of 
         navigation text
         is delayed, until the next hosting level is found and numbering/counting
         will be possible.
      #p
      The text for sections, chapters, parts etc. is constructed to
      #source
           Abschnitt  17.3.1 ("<title-of-the section>")
           ^                 ^ iff user.refTitle=='inline'
           ^                   (otherwise it may be rendered as toolTip)
           ^ translated to doc's default language
      #/s=====ource
      #p
      "floatings" are identified by their genuine reference mechanism.
      #nl
      "lists", "list points", "tables" and "table rows" by counting relative to the 
      nearest "container", which is a list, a table, a floating, a section, etc.
      #nl
      Iff reference and label are in a common container (list, table, or 
      lowest level section), this part of the reference text
      is abbreviated to "this list"/"this table"/"this section", etc.
      #nl
      There is currently NO further abbreviation implemented, like  
      "next section" or "preceding chapter".
      #p
      If you want to determine the refering text appearance 
      #emph!freely! by yourself, using #emph!all mark-up! currently available,
      you can always use 
      an explicit "#src!#hh link!" construct, using only the local part of the 
      link target ("fragment identifier", in w3c speak)
      #nl
      So you can link to "mylabel" directly by 
      #nl
      #commandchar$
      "$src ... and #link#loc mylabel#text here is the #emph!real! text#/link ...$/src"
      $commandchar#
    #/d2d

// FIXME whether container elements are transparent or count (ie. have an impact in
//   the "mode=getreftext" traversal, should be controled by meta-attributes (constant per type).

    // FIXME: In an multi-lingual setting, the language of the paragraph of the
    // REFERENCE must be used for translation. (see template "find_innermost_lang")

    docu to_xhtml_1_0 ref = 
      #d2d
        #x-var tx #xp text()
        #x-var lb #xp /descendant::a:label[text()=$tx][1]
	#if $user.showlabels="yes"
          #span#class debug  #valueof concat("(",$tx,")") 
        #/if
        #choose
          #when $lb 
            #a#href {concat($a:const.hashmark,text())} // FIXME darf kein NL dazwischen??
              #if $user.refTitle='toolTip' 
                #x-var TX #apply #mode getreftextTitle #xp $lb  #/x-var
                #if $TX
                  #attribute title #valueof $TX
                #/if
              #/if
              #apply #mode getreftext #xp $lb 
                #arg referer #xp .
          #other
	    #message#text  label #valueof $tx #text  not found.#/message
	    #span #class error
              #text [label #valueof $tx #text  not found ???]#/text
            #/span

        #template #match * #mode getreftextTitle
          #apply #mode getreftextTitle #xp parent::*

        #template #match * #mode getreftext
          #param referer#/param 
          #param referred#/param 
          #param nsuri#/param 
          #param localname #/param
          #param textMultiple #/param
          #param textSingle #/param
          #apply #xp parent::node() #mode getreftext //ATTENTION: "*" does not visit root
            #arg referer#xp $referer
            #arg referred#xp $referred
            #arg nsuri#xp $nsuri
            #arg localname#xp $localname
            #arg textMultiple#xp $textMultiple
            #arg textSingle#xp $textSingle

        #template #match / #mode getreftext
          #param referred#/param 
          #param nsuri#/param 
          #param localname #/param
          #param textMultiple #/param
          #param textSingle #/param
          #call muliDefault#arg p-key REF_thisDoc#/call
          #if $localname 
            #call reftextByCount
              #arg referred#xp $referred
              #arg nsuri#xp $nsuri
              #arg localname#xp $localname
              #arg textMultiple#xp $textMultiple
              #arg textSingle#xp $textSingle


        #template #name refSameTest
          #param referer#/param  // is label element, test whether it is under $other
          #param other#/param    // is id=string, means current addressing base
//#message IN refSameTest >>#valueof!$referer!<<  
// >>#valueof!generate-id($referer)!<<  >>#valueof!$other!<<#/message
          #choose
            #when generate-id($referer)=$other
              #valueof 'true'
            #when $referer/parent::*
              #call refSameTest
                #arg referer #xp $referer/parent::*
                #arg other #xp $other
            #other // empty rtf ??
        #/template


/* 
        S
      /|\ \ 
     / | T  /\
    /\        t
   t  t        \
  /\           tNO
 NO tNO 

*/

        // Called with current-node = current ref-base = S.
        // Returns the number of all "t" and the position of "T".
        // Descends in neither or these.
        // $textSingle may be empty string, then no comma must be generated.
        #template #name reftextByCount
          #param referred#/param   // = T
          #param nsuri#/param 
          #param localname #/param
          #param textMultiple #/param
          #param textSingle #/param
	  #x-var position 
            #foreach child::*[1]
              #call countref_right
                #arg referred #xp $referred 
                #arg nsuri #xp $nsuri
                #arg localname #xp $localname
          #/x-var
          // /**/#message POSITION =>>#valueof!$position!<<#/message
          #choose
            #when string-length($position)=1 
              #if $textSingle
                #text!, !
                  #call muliDefault #arg p-key #xp $textSingle
            #other
              #text!, !
              #call muliDefault #arg p-key #xp $textMultiple
              #valueof concat(' ', 
                              string(string-length(substring-before($position, 'x'))+1))

        // Counts all descendants of the given type (excluding their descendants).
        // Two results: number of all matching elements, and position of the referred,
        // encoded as string "----x--" :

        #template #name countref_right
          // currentnode = cursor;  starts with first child of 
          //   current ref-base (which has been reached by upward traversal)
          #param referred#/param 
          #param nsuri#/param 
          #param localname #/param
          // /**/#message count ref at #valueof concat(local-name(),'  ',$localname)#/message
	  #x-var right 
            #choose
              #when ./following-sibling::*
                #foreach ./following-sibling::*[1]
                  #call countref_right
                    #arg referred #xp $referred 
                    #arg nsuri #xp $nsuri
                    #arg localname #xp $localname
              #other #valueof ''
          #/x-var
	  #x-var down 
            #choose
              #when local-name()=$localname and namespace-uri()=$nsuri
                #choose
                  #when generate-id()=$referred
                    #valueof "x"
                  #other
                    #valueof "-"
                 #/choose
              #other
                #foreach ./child::*[1] #call countref_right
                  #arg referred #xp $referred 
                  #arg nsuri #xp $nsuri
                  #arg localname #xp $localname
          #/x-var
          #valueof concat($down, $right)
        #/template // countref_right
      #/d2d


    tags pers = #chars 
    docu user_en pers = "Personal name. (This is a candidate for replacement
                         with some more sophisticated, parser based, but locale
                         specific definition.)
                         Our standard to_xhtml_1_0 script 
                         renders it to a span/class=pers, which normally
                         results in small caps." 
    docu to_xhtml_1_0 pers = "#span #class pers #apply"
    docu to_css pers = "span.pers : {font-variant:small-caps;}"

    tags opus = #chars 
    docu user_en opus = "Title of an opus, a work of art, or any product,
                         (This is a candidate for replacement
                         with some more sophisticated, parser based definition.)
                         Our standard to_xhtml_1_0 script
                         renders it to a span/class=opus, which normally
                         results in slanted small caps."
    docu to_xhtml_1_0 opus = "#span #class opus #apply"

    chars persop = [ppers (S.all - '!')*] ~ "!" ~ [popus (S.all - '!')*] ~ "!" 
    docu user_en persop = "Name of its author and name of an opus. Behaves like the
                           sequence of #hh pers and #hh opus. Any separation char 
                           must be appended to the former."
    docu to_xhtml_1_0 persop 
      = "#span #class pers #apply#xp ppers#/span#text! !#span #class opus #apply#xp popus#/span"


    tags xlang = #implicit X.lang, (XLANG_CONTENTS)*
    tags XLANG_CONTENTS = #GENERIC
    docu user_en xlang = "A short sentence/sequence of words in some foreign
                            lanugage, -- less than a whole paragraph.
	                  Our standard to_xhtml_1_0 rendering creates a
                          span element with an xml:lang attribute, which 
                          you may render by css as you like."

    docu to_xhtml_1_0 xlang = "#span #call copyLang_direct #apply"

  end module // inlineElements


  // ------------------------------------------------------
  module calendaric_de
  import S from sets
  // ------------------------------------------------------
    docu user_en =
          #d2d
          This module contains the #xemph!German! form of entering calendaric dates.
          This moduls is likely to be replaced when instantiating
          calling modules in a different language.
          The field 'UTC' may and should be used for the normalized
          and international format, independent of the
          language specific front-end representations.
          Currently a java-coded postprocessor 
          "eu.bandm.tools.d2d2.postproc.Calendaric" fills in
          this field automatically.
          #nl
          #bold Currently not used anywhere,#/  for demonstration purpose only.
          #/d2d

    enum monate = jan 1, januar 1,
                  feb 2, februar 2,
                  mar 3, maer 3, "mär" 3, "märz" 3, maerz 3,
                  apr 4, april 4, 
                  mai 5, 
                  jun 6, juni 6, 
                  jul 7, juli 7, 
                  aug 8,  august 8,
                  sep 9, sept 9, september 9,
                  okt 10, oktober 10,
                  nov 11, november 11,
                  dez 12, dezember 12
           with xmlrep element numeric 

    chars calendaric =
           [dayofmonth  @S.upto3? ~ @S.decimalDigit] ~ ".",
           ([month @S.upto1? ~ @S.decimalDigit] ~"." | [month /*@ FIXME */monate]),
           [year ("-"?) ~ @S.decimalDigit? ~ @S.decimalDigit? ~ 
	                  @S.decimalDigit? ~ @S.decimalDigit]

    public chars date =  @calendaric, [UTC "XXXXX"]?  
	           with postproc "eu.bandm.tools.d2d2.postproc.Calendaric", 
                        xmlrep = calendaric-date

    docu to_xhtml_1_0 date = 
         "#valueof a:dayofmonth#text .#valueof a:month#text .#valueof a:year" 


    chars time = [hour S.upto2? ~ S.decimalDigit] , ":" , 
	           [minute S.decimalDigit ~ S.decimalDigit], ("Uhr"?)

  end module // calendaric_de



  // ------------------------------------------------------
  module interDocuments
  local node xmlrep naming = no mangling

  import S from sets
  // ------------------------------------------------------
 
    docu user_en =
    "Primitive elements for embedding of and linking to other documents."

    tags link = #implicit url, 
                  (  text? & loc? & refdate?)
// PRE 20240902   (  (blank|top|inframe|framename)? & text? & loc? & refdate?)
      with local
        tags text = LINKTEXT*
// PRE 20240902      tags blank, top, inframe = #empty
// PRE 20240902        tags framename = #chars  with xmlrep trimmed
        tags refdate = #chars
      end local

    tags LINKTEXT = #GENERIC
    docu user_en LINKTEXT = 
      "For the visual representation to contain any mark-up, this 
       must be declared by replacing this generic reference."

    tags url = #chars  with xmlrep trimmed
    tags loc = #chars  with xmlrep trimmed

    docu user_en link = 
      "Inter document link, very similar to classical html #src!<a>! element.
       But it is a little bit higher level!"
    docu user_en url = 
       #d2d
       The url of a link or a resource.#nl
       (This is currently NOT YET parsed, but can be any sequence of characters.
       Errors will occur later, when the link is used !-)
       #nl
       Iff the url starts with a #emph!digit=n!, then there must be
       an n-th entry in the self-structured list in the stylesheet parameter 
       #src!$user.linkurlprefices!,
       and the digit is replaced by this.
       #/d2d
    docu user_en link.text = 
      #d2d The text to print when the link is rendered. It is defined
      by a generic parameter, so anything may appear there, depending on
      the instantiation of this module. #nl
      If this field is left out, then the url will be taken as text.#nl
      In this case, if the url starts with a digit, then the prefix replacing
      this digit is taken from the stylesheet parameter #src!$user.linktextprefices!.
      This allows more readable, more symbolic references to frequently used 
      mount points.#nl
      If the text is present and starts with an exclamation mark "#src(!)", 
      then this is also replaced by this prefix.
      #/d2d
    docu user_en loc = 
      "The location/fragment in the document 
       (what normally appears behind a hashmark!-)
       A link must contain either an url or a loc entry, or both."
    docu user_en link.refdate = 
      "The calendaric date when the meant contents of the link had been retrieved."
    // PRE 20240902       
    // docu user_en link.blank, link.top, link.inframe, link.framename = 
    //    #d2d The target where to open the new link. 
    //    #xemph(This cannot be rendered in xhtml 1.0 strict!)
    //    A javascript based implementation must be provided by the user
    //    whenever this "target" feature shall be used in xhtml 1.0 strict.
    //    The standard xslt script will ignore it and emit a warning
    //    iff #src($user.xhtmlVariant) ist set to "strict".
    //    #/d2d

    docu to_xhtml_1_0 link =
      #d2d
         #x-var l-start #xp substring(a:url,1,1)
         #choose 
            #when string-length(normalize-space(a:url))=0 
              #if string-length(normalize-space(a:loc))=0
                #message ERROR invalid link, both url and fragment location are empty
              #/if
              #call makelink
                #arg p-url #xp ''
                #arg p-urlprefix  #xp ''
                #arg p-textprefix #xp ''
            #when contains('0123456789',$l-start) 
               #call makelink 
                   #arg p-url #xp substring(a:url,2)
                   #arg p-urlprefix 
                      #call a:splitbyfirst
                         #arg p-select #xp $l-start
                         #arg p-list   #xp $user.linkurlprefices
                         #arg p-errormsg  #xp a:url 
                      #/call
                   #arg p-textprefix 
                      #call a:splitbyfirst
                         #arg p-select #xp $l-start
                         #arg p-list   #xp $user.linktextprefices
                         #arg p-errormsg  #xp a:url 
            #other
               #call makelink 
                   #arg p-url #xp a:url 
                   #arg p-urlprefix  #xp ''
                   #arg p-textprefix #xp ''
    #/template

    #param user.linkurlprefices #xp '!http:/!' #/param
    #param user.linktextprefices#xp '!http:/!' #/param
// PRE 20230902  #param user.xhtmlVariant#xp 'strict'#/param


    #template #name makelink
      #param p-url#/param
      #param p-urlprefix#/param
      #param p-textprefix#/param
      #param l-loc 
        #choose
          #when a:loc#valueof concat($a:const.hashmark,normalize-space(a:loc))
//          #when a:loc#valueof concat($a:const.hashmark,normalize-space(a:loc/text()))
          #other #valueof  ''
       #/param
//PRE 20240902 
      // #param l-target
      //   #choose
      //     #when a:top #valueof '_top'
      //     #when a:blank #valueof '_blank'
      //     #when a:inframe #valueof '_self'
      //     #when a:framename #valueof a:framename/text()
      //     #other #valueof ''
      //  #/param
       #a #href {concat($p-urlprefix,normalize-space($p-url),$l-loc)}
//PRE 20240902 
          // #choose 
          //   #when $user.xhtmlVariant='strict'
          //     #if not($l-target='') 
          //       #message Trying to set link target in strict xhtml 1.0 is ignored
          //   #other 
          //     #if not($l-target='') 
          //       #attribute target#valueof $l-target
          // #/choose
          #choose
            #when a:text and starts-with(normalize-space(a:text),'!')
               #valueof concat($p-textprefix,substring-after(a:text,'!'))
            #when a:text
               #apply #xp a:text
            #other
               #valueof $p-textprefix
               #valueof normalize-space($p-url)
               #valueof normalize-space($l-loc)
        #/a
      #/template
    #/d2d

    tags treeInclude, treeInclude_PROVIS 
      = #implicit url, path, mode?
        with xmlrep  = treeInclude
    docu user_en treeInclude =
      #d2d
      Includes an xml text corpus into the rendering process.
      "url" gives the file position, and "mode" gives the mode parameter
      to the "apply-templates" call.
      #nl	
      #bold CURRENTLY PATH is not yet operative#/, because there
      are problems serializing the dynamic xpath extension required for its
      execution.
      #/d2d

    docu user_en treeInclude_PROVIS =
     "Same as treeInclude, but callable when parsing VERTICALLY stacked text elements."

    tags path, mode = #chars with xmlrep trimmed

    docu to_xhtml_1_0 treeInclude =
    #d2d
// NO, w3cdom Xerces does not find base url for text node !?!?!?
//      #foreach document(./a:url/text())
      #foreach document(./a:url)
        #apply
/*==== NO, mode is not a "AVT"-attribute; 
cannot be set DYNAMICALLY; "#mode {a:mode}" will be rejected; dynamic extension would be
needed:
        #choose
          #when a:mode
            #apply #mode a:mode
//            #apply #mode {a:mode}
          #other 
            #apply
== */
    #/d2d

   tags embed = #implicit type, (alt? & body) 
    with local
      chars type = @S.ident   with xmlrep attribute=embedType
      tags  body = #chars with input verbatim,
                                xmlrep element=embedBody
      tags alt = EMBED_ALT*
    end local
    tags EMBED_ALT = #GENERIC

    docu user_en embed.type
     = "Suffix of the generated temporary filename in which the body
        will be written. Used to select the tool for subsequent processing."

    docu user_en embed =
    #d2d
      Embeds any third-party source text into the source and the
      rendering result into the output.#nl
      (Eg. "lilypond" source resulting to a ".png" which is included into the 
      xhtml document.) #nl
      This processing must be executed by the #bold make system#/  which controls the
      overall document processing pipeline.#nl
      The xslt code does only
      #list
      #i generate a unique file name
      #i generate an  #src!<img>! element when generating xhtml.
      #i piping all the thirs-party-source into a bash-script, which will
         auto-split into source files for these tools. #nl
         This is done by a second conversion target, "#src!to_embedScript!". #nl
         The filename suffix is taken from the "type" attribute,
         and indicates to the further processing which tool(s) has/have to be
         started (e.g. for creating the png included by the html, or sim.)
      #/list
      An #src!alt! #emph!may! be given, but if omitted, it will be inherited from
      the containing element. In many cases the containing element be a "floating"!
      #/d2d

// does assume a "make" script which makes "png"s of ALL embeds.
// EXCEPT those of type "pdfSourceRef", where the pdf is displayed using an
//   xhtml object tag.
// EXCEPT those type "pdfRef", where the "body" is the path to  a ready-made pdf,

    docu to_xhtml_1_0 embed = #d2d
    #choose
      #when @a:embedType="pdfSourceRef"
        #x-var l-url #call  create-fileid-for-embedded-image #text!.pdf!#/x-var
        #p 
        #object #type application/pdf
//FIXME SOME back-ends lack escaping of ampersand ?  
//   #data {$user.currentkey}_picts/{$l-url}{$a:const.hashmark}statusbar=0&toolbar=0&navpanes=0
          #data {$user.currentkey}_picts/{$l-url}
          #width 711 #height 956
	#br/#br/ YOUR BROWSER DOES NOT SUPPORT PDF EMBEDDING,
          CLICK #a #href!{$user.currentkey}_picts/{$l-url}! HERE #/a 
          TO VIEW .pdf FILE ! #br/#br/
      #when @a:embedType="pdfRef"
        #p 
        #object #type application/pdf
          #data {normalize-space(a:embedBody)}
          #width 711 #height 956
	#br/#br/ YOUR BROWSER DOES NOT SUPPORT EMBEDDING; 
          CLICK #a #href!{normalize-space(a:embedBody)}! HERE #/a 
          TO VIEW FILE #valueof a:body#text!.! #br/#br/
      #other
        #div
        #img 
          #attribute src #valueof $user.currentkey #text!_picts/!
            #call create-fileid-for-embedded-image #text!.png!
          #/attribute
          #call copyAltFromContext
     
    #template #name create-fileid-for-embedded-image
      #text!image!#number #count a:embed#level any 
    #/template
      
    #param user.currentkey#/param
    #/d2d

    docu to_embedScript embed =
      #d2d
        #text!
cat > !#call create-fileid-for-embedded-image#text!.!#valueof @a:embedType 
#text#noescape <<"EOF"
      #/text
      #valueof a:embedBody
#text!
EOF
!      

      #template #match text()
        //NOP

      #template #name create-fileid-for-embedded-image
        #text!image!#number #count a:embed#level any
        #/template
    #/d2d


  end module // interDocuments


  // ------------------------------------------------------
  module personal_names_de
  import S from sets
  // ------------------------------------------------------

    docu user_en =  #d2d
      Character Parsers for personal names, including honours, middle
      initials, etc. Will be replaced when the locale/cultur context
      changes.
      #nl
      #bold Currently not used anywhere,#/  for demonstration purpose only.
      #/d2d
    chars namepart = S.ascii_upper~S.ascii_lower~*
    chars nameprefix = S.ascii_lower~*

    chars personalName  = 
              [honours (@namepart~".")+]?, [prename @namepart +],
                [middleInitials (@namepart~".")*], [familyname "\""~ @namepart] //TEST DQUOTE
            | [family @namepart +], "," ,
              [honours (@namepart~".")+]?, [prename @namepart +], 
                [middleInitials (@namepart~".")]
       
  end module //names_de


  // ------------------------------------------------------
  module citation 

  local node xmlrep naming = no mangling
  plain text is trimmed 

  import S from sets
  import X from xmlInfra
  import LINK from interDocuments
  // ------------------------------------------------------

    docu user_en = #d2d
      A first small solution for bibliographic data, citation keys 
      and bibliographic lists.#nl
      Its structure is based on "bibTeX" and our experiences in bib-style 
      programming, but heavily trying to modernize and orthogonalize.#nl
      The grammar definition of the entries is 
      (of course!-) independent of the "kind" of
      entry, because the complex requirements and implications on the semantical
      level cannot adequately be expressed by a regular expression.
      But we decided to #emph!coarsely! reflect these requirements by 
      grouping the components of an entry. 
      Inside most groups the fields may be permutated.
      #list
        #i First we require key(implicit), kind, title and one or more authors.
	#i Additionally subtitle, latextitle (later:htmltitle !?!)
        #i Then may follow references to copies of the text, which
           have formalized structure, namely url(s), isbn(s), issn(s), doi(s), etc.
        #i Then follows #emph!either! a simple crossref to the collection containing
           the article,
        #i #emph!or! the standard bibliographic co-ordinates in case of stand-alone 
	   publications (place, date, publisher, etc.)
        #i At last there may follow abstracts and keywords in different languages,
           and a list of library signatures where a printed copy is available.
      #/list
      #p
      If there is only one single sub-document cited from a collection,
      its bibliographic co-ordinates may be inlined into the entry for the
      article. But in contrast to BibTex, we recommend the solution with
      two(2) separate entries.
      Nevertheless, we put the "formal references" in the middle of both
      groups, because in the single-entry case these may either describe just
      the article, i.e. the head of the entry, or the whole volume, i.e. 
      the tail of the entry.
      #p
      #bold Please note#/  that the items contained in #src!editors! are tagged
      with #src!author!, as the items in #src!authors!. Firstly, the code for
      rendering is inherited, and secondly editors are professional authors,
      in most cases.
      #p
      #bold Please note#/  that the problem of a generic, standardized and
      widely accepted bib-entry format is still unsolved. We plan a 
      whitepaper on this subject, and a preliminary link collection is found
      in metatools/doc/papers/recherche/recherche_biblio.html.
    #/d2d

    chars key = (S.ascii_alpha U '-_' U S.decimalDigit)~+

    docu user_en key 
      = #d2d The identifier for a bibliographic entry.#nl
      This could be replaced by something more restricted, like
      "alpha~+ ~ digit~*". The key must appear in the bib entry and
      in all cite-elements. When using this standard rendering script
      it is also #emph!immediately the visible representation! of the citation/link.
      This is a signficant difference to BibTex, and could of course be 
      done differently by some more elaborated rendering script. 
      #/d2d

    chars cite = key ~ ('!'~[locus (@S.all - '!')~+]~'!')?
    docu user_en cite = 
      #d2d A citation is a reference to a bibliographic entry,
           plus possibly a location indication ("pg 12 to 13").
           CURRENTLY both is free text, only excluding the delimiter "#src(!)".#nl
           Every cite is rendered as a xhtml link to the bibliographic entry.
           This is assumed to be in the same file, OR in the file given by
           the stylesheet parameter "#src!$user.bibLocation!".
      #/d2d

    docu to_xhtml_1_0 cite =
      #d2d
        #call renderCite
        #/template

        //  "biblio.xml" and "biblio.html" must both be adressable
        #param user.bibLocation#/param

        // used by render cite and render crossref
        // looks for local entries, and for entries in separate file 
        // FIXME more formats/styles of rendering selectable
        #template #name renderCite 
          #x-var entry  #xp /descendant::a:bibentry[a:key/text()=current()/a:key/text()]
          #/x-var
          #x-var entryExtern 
            #if (not($entry) and $user.bibLocation)
                #valueof document(concat($user.bibLocation,'.xml'),.)/descendant::a:bibentry[a:key/text()=current()/a:key/text()]
          #/x-var
          #x-var prefix
            #if not($entry) #valueof concat($user.bibLocation,'.html')
          #/x-var
          #text![!
          #a#href {$prefix}{$a:const.hashmark}__bib{a:key/text()}#/href  
            #title {$entry/a:author} {$entry/a:year}
            #valueof a:key/text() #/a
          #if a:locus #text(, )#i#valueof a:locus/text()#/if
          //	  #message ENTRY IS >>#valueof concat($entry,'<<')#/message
          #if not($entry or $entryExtern) #span#class error#text not found#/if
          #text!]!

/* == OLD OK
        #template #name renderCite 
          #text![!
          #a#href {$user.bibLocation}{$a:const.hashmark}__bib{a:key/text()}#/href  
            #valueof a:key/text() #/a
          #if a:locus #text(, )#i#valueof a:locus/text()#/if]
== */
      #/d2d

    public tags biblist = ( X.lang? & sortMethod? 
                            & abstractLangs? & abstractHiding?  
                          ), bibentry +
    docu user_en biblist =
      "A list of bibliographic entries, rendered as a whole, e.g.
       concering sort order.#nl
       The \"lang\" attribute is taken as the #emph!default language!
       for the contained bibentries. 
      (See the other components for documentation!)"

    enum sortMethod = none, chronAsc, chronDesc, key, author
    docu user_en sortMethod = #d2d 
      How the biblist will be sorted in rendering.#nl
      CURRENTLY there are #bold two Fixmes#/  with the chronological sort methods:#nl
      (a) only "year" and "month" are respected, since the internal structure of
          "date" is not defined.#nl
      (b) these dates do not carry over via "crossref"
       #/d2d

    tags abstractLangs = #chars
    docu user_en abstractLangs 
    = "A list of language codes, determins the selection and sequential
       order of included abstracts.
       The list must be \"self-structured\", i.e. start and end
        with an arbitrary item separator character."

    tags abstractHiding = #empty
    docu user_en abstractHiding
    = "If present, the abstracts will be invisible, and a visibility toggle
       will be added. A corresponding java-script procedure must be 
       present, as well as the translations for the button texts."

    docu to_xhtml_1_0 biblist = 
      #d2d
        #table #tbody 
        #choose
          #when a:sortMethod/text()='chronAsc'
            #apply #xp a:bibentry 
              #sort #xp a:year/text() #data-type number #order ascending 
              #sort #xp a:month/text() #data-type number #order ascending
          #when a:sortMethod/text()='chronDesc'
            #apply #xp a:bibentry 
              #sort #xp a:year/text() #data-type number #order descending
              #sort #xp a:month/text() #data-type number #order descending
          #when a:sortMethod/text()='key'
            #apply #xp a:bibentry 
              #sort #xp a:key #data-type text #order ascending
          #when a:sortMethod/text()='author'
            #apply #xp a:bibentry 
              #sort #xp a:author #data-type text #order ascending
          #when not(a:sortMethod)
            #apply #xp a:bibentry 
          #other
            #message Invalid sort method selection in biblist: #valueof a:sortMethod
        #/tbody#/table
      #/template


      #template #name bib-getlang // focus=biblist
        #choose #when @xml:lang #valueof  @xml:lang
                #other #valueof $baseLanguage 

      #template #name bib-get-author // focus=bibentry FIXME

      #template #name bib-get-year 
        // focus=bibentry if not year, but date, then excerpt  FIXME 
      #template #name bib-get-month 
       // focus=bibentry if not month, but year, then excerpt  FIXME

    #/d2d


    tags bibentry = #implicit key, kind, 
       ( title & subtitle? & latextitle? 
       & X.lang? & (author|authors)?  
       ),
       ( url | isbn | issn | doi)* ,
       ( ( crossref, pages?)
       | (   ((year, month?) | date)
           & booktitle? 
           & publisher? & place
           & (editor|editors)? 
           & (series|journal)? & volume? & number?
           & pages?
         )
       ),
      (abstract | note | available ) *

    tags title, subtitle = (TITLE_CONTENTS)*

    tags url = @LINK.url with xmlrep = bib-url

    docu user_en url = #d2d
      Whenever the target format permits, the rendering is to a hyperlink.
      The visible text is determined by the stylesheet parameter 
      #src!$user.biblistHideUrl!: When this is set, only the suffix is
      shown, intended to represent the document's type. 
      Otherwise the whole URL is shown, what may cause inappropriate visual noise.
      #nl
      FIXME better make it parameter of the biblist structure !?
      #nl
      For the url value, and the displayed url in the latter case, the
      leading digits #src!0!..#src!9! will be replaced by the mount points
      in the stylesheet parameter #src!$user.linkurlprefices! and 
      #src!$user.linktextprefices!, similar as with 
      "base.interdocument:link" elements.
    #/d2d

// FIXME re-use of xslt code from "LINK:url" not possible ?
    docu to_xhtml_1_0 url = #d2d
      #x-var l-start #xp substring(.,1,1)
// XALAN: FIXME      #x-var l-start #xp substring(text(),1,1)
      #choose 
        #when contains('0123456789',$l-start) 
          #x-var l-urlprefix 
            #call a:splitbyfirst
              #arg p-select #xp $l-start
              #arg p-list   #xp $user.linkurlprefices
              #arg p-errormsg  #xp . // text()
            #/call
          #/x-var
          #x-var l-textprefix 
            #call a:splitbyfirst
              #arg p-select #xp $l-start
              #arg p-list   #xp $user.linktextprefices
              #arg p-errormsg  #xp . // XALAN text()
            #/call
          #/x-var
          #x-var l-rest #xp substring(. /*text()*/ ,2)
          #/x-var
          #a#href {concat ($l-urlprefix,$l-rest)}
              #tt #valueof concat ($l-textprefix,$l-rest)
        #other
          #a#href {.} #tt #valueof .
//          #a#href {text()} #tt #valueof text() 
    #/d2d


    tags TITLE_CONTENTS = #chars
    docu user_en TITLE_CONTENTS 
    = "For allowing mark-up in title, subtitle, etc., this
       parameter can be overridden when importing this module."

    tags latextitle = #chars 
    docu user_en latextitle 
    = "Characters only, intended for over-riding LaTeX-bibTex entries,
       because these are hard to synthesize automatically."

    tags author = #chars 
    tags editor = @author

    tags authors = author+
    tags editors = author+

    tags year, month, date = #chars 
    tags publisher, place = #chars 
    tags series, journal, volume, number, pages = #chars

    tags booktitle = @title
    chars crossref = @cite 

    tags isbn, issn, doi = #chars 
    docu user_en isbn, issn, doi 
    = "Currently not yet parsed internally, but whenever the target format
       permits, rendered as a \"clickable\"  link to some service provider."

    enum kind = inproceedings, incollection, report, article,
                proceedings, collection, 
                thesis, masterthesis, phdthesis, book,
                technicalreport, manual, webpage, unpublished, 
                musicsheet, fullscore, vocalscore, 
                radiofeature, audiorecording, 
                tvcast, lecture
                  with xmlrep att = "kind" 
    docu user_en kind = #d2d
      The different kinds of publication, as historically introduced by "bibtex".#nl
      We added further alternatives.#nl
      Please note that in the default rendering there is no relation between 
      this kind value and the  syntax of entries or the format of the rendering.
      Nevertheless, indicating the "kind" is always required.
      #/d2d

    
    tags abstract = #implicit X.lang, (ABSTRACT_CONTENTS)*
    docu user_en abstract 
      = "An abstract in one certain language."

    tags ABSTRACT_CONTENTS = #GENERIC
    docu user_en ABSTRACT_CONTENTS 
      = "Generic parameter which defines what an abstract will be composed of."

    docu to_xhtml_1_0 abstract =
      #d2d
          #choose
            #when ../../a:abstractHiding
              #x-var tableId #xp concat('abstract_',./@xml:lang,'_',../a:key)
              #x-var nichtdatext 
                #call muliLookUp 
                  #arg p-key #xp 'abstract'
                  #arg p-lang #xp ./@xml:lang  // <- correct, language of the abstract
              #/x-var
              #x-var datext 
                #call muliLookUp 
                  #arg p-key #xp 'hideAbstract'
                  #arg p-lang #xp ./@xml:lang
              #/x-var
              #span #class linkLike #id switch_{$tableId} #lang {@xml:lang}
                    #onclick toggleAbstract(this,'{$datext}','{$nichtdatext}')
                    #onmouseover this.style.textDecoration='underline';
                    #onmouseout  this.style.textDecoration='none';
                #valueof concat('[',$nichtdatext,']')
              #/span
              #table #id {$tableId} #style display:none;
                #tbody
                  #tr
                    #td #class abstractText #lang {@xml:lang}
                      #apply 
            #other 
               #table 
                 #tbody
                   #tr
//                     #td #class abstractText #lang {@xml:lang}
// NEU 20141115 xml-tag a:abstract kann auch aus "deliverables" kommen, 
//   da wäre dann  "lang=''", was nicht durch w3c verifier geht !
                      #td #class abstractText 
                        #if @xml:lang 
                          #attribute lang#valueof @xml:lang #/attribute // ??? why 
                          #attribute xml:lang#valueof @xml:lang
                        #/if
                        #apply 


        #template #name renderAbstract
          // focus isa  bibentry
          #param p-langs #/param 
          #param p-sep #/param
          #if string-length($p-langs) > 1
            #x-var l-currentlang #xp substring-before($p-langs,$p-sep)
            #apply #xp a:abstract[@xml:lang=$l-currentlang]
            #call renderAbstract
              #arg p-langs #xp substring-after($p-langs,$p-sep) 
              #arg p-sep #xp $p-sep 
      #/d2d

    tags note = ABSTRACT_CONTENTS*
    docu user_en note =
      "Additional remarks to a bib entry, eg. comments, 
       protocols where it has been used, hints for a rendering process, etc."

    tags available = #chars
    docu user_en available =
      "Indication of one library where to printed text can be found, 
       and the signature they use."


    docu to_xhtml_1_0 bibentry = #d2d
      #x-var l-lang // only needed for <author> "und" <author>, could use "&" or ", "
        #choose 
           #when @xml:lang #valueof  @xml:lang
           #when parent::a:biblist/@xml:lang #valueof parent::a:biblist/@xml:lang 
           #other #valueof $baseLanguage 
      #/x-var
      #tr#td
      #if a:note[normalize-space(text())='recommended'] // SPECIAL for ML FIXME 
                                 // better give it a "class/pkind" attribute !?
        #attribute class #text recommended
      #/if
      #a#name __bib{a:key/text()} #id __bib{a:key/text()} 
        #span #class printKey  #text![!#valueof a:key #text!]!
      #/a
      #br/
      #if a:author|a:authors 
        #apply #xp a:author|a:authors/a:author #arg p-lang #xp $l-lang
        #br/
      #/if
    
      #span #class!publicationTitle! 
        #call copyLang_direct
        #apply #xp a:title/node() 
        // #apply #xp a:title  // wrong,  runs into (section-)title !
      #/span
      #br/
    
      #if a:subtitle 
        #span #class!publicationSubtitle!
          #call copyLang_direct
          #apply #xp a:subtitle/node() 
        #/span
        #br/
      #/if
    
      #if a:booktitle or a:crossref or a:journal
        #i #call muliDefault #arg p-key inCollectionPrefix#/call
        #if a:booktitle 
           #valueof a:booktitle/text()#text!, !
        #/if
        #if a:journal
           #valueof a:journal/text()#text!, !
        #/if
        #if a:series
           #valueof a:series/text()#text!, !
        #/if
        #foreach a:crossref #call renderCite#/foreach
        #if a:number
           #text!Nr.!  #valueof a:number/text()#text!, !
        #/if
        #if a:volume
          #text!Vol.!  #valueof a:volume/text()#text!, !
        #/if
        #if a:pages
          #text!pg.!  #valueof a:pages/text()#text!, !
        #/if
      #/if
      
      #if a:editor 
        #i #valueof a:editor    // NOT a:editor/text()  SEE COMMENT BELOW
        #call muliLookUp #arg p-key editorsAbbrev#arg p-lang #xp $l-lang
        #/call#/i 
      #/if 
      #if a:editors #i #apply #xp a:editors/a:author #arg p-lang #xp $l-lang
        // insert "and", as with authors
        #call muliLookUp #arg p-key editorsAbbrev#arg p-lang #xp $l-lang
        #/i 
      #/if 
    
      #if a:editor|a:editors|a:booktitle|a:crossref
        #br/
      #/if
    
      #if a:place
        #apply #xp a:publisher
        #if a:publisher #text!, !#/if
        #apply #xp a:place 
        #text!, ! 
        #if a:month #valueof a:month/text() #text! !#/if
          #apply #xp a:year  
        #apply #xp a:date
        #br
      #/if
     
      #apply#xp a:isbn|a:issn|a:doi|a:link
    
      #choose
        #when $user.biblistHideUrl
          #foreach a:bib-url 
            #a #href {.} #text![.! #call a:extractFileSuffix #arg p-string #xp . 
                 #call muliLookUp 
                   #arg p-key#xp 'URL_document' #arg p-lang #xp $l-lang
                 #text!]!
            #/a // NO #br !!
        #other
          #apply #xp a:bib-url
      #/choose
    
      //#apply #xp a:note
      #apply #xp a:note[normalize-space(text())!='recommended']//SPECIAL for ML FIXME

      #if a:abstract
        #if ../a:abstractLangs
          #call renderAbstract
            #arg p-sep #xp substring(../a:abstractLangs/text(),1,1)
            #arg p-langs  #xp substring(../a:abstractLangs/text(),2)#/arg
          #br/
        #/if
      #/if
      #br/
      #/td#/tr
    #/template
    
    #param user.biblistHideUrl#/param
    

    #x-var const.ISBN_OFFICIAL_CATAOLOG_RQ 
      #xp concat($a:const.httpPrefix, 'www.worldcat.org/search?q=')
    #/d2d


    docu to_xhtml_1_0 issn = #d2d 
      #a #href {$const.ISBN_OFFICIAL_CATAOLOG_RQ}{.}
         #text!ISSN !#valueof . #br
    #/d2d

    docu to_xhtml_1_0 isbn = #d2d 
      #a #href {$const.ISBN_OFFICIAL_CATAOLOG_RQ}{.}
         #text!ISBN !#valueof . #br
// attention: "#valueof text()" yields a node set of text nodes and converts the FIRST ONLY!
//value-of[xslt1.0:7.6.1] SEE string()[xslt1.0:4.2] SEE string-value[xslt1.0:5.2] ("concatenation")
    #/d2d


    docu to_xhtml_1_0 doi = #d2d
      #a #href {$a:const.httpPrefix}dx.doi.org/{.}  #text!doi:!#valueof .
// attention: "#valueof text()" yields a node set of text nodes and converts the FIRST ONLY!
      #br
    #/d2d

    docu to_xhtml_1_0 author = 
    #d2d
      #param p-lang #/param
      #span #class!author! #valueof . #/span
      #if following-sibling::a:author 
         #text! !
         #call muliLookUp 
           #arg p-key#xp 'and'  #arg p-lang #xp $p-lang
         #text! !
    #/d2d

  end module // citation 


  // ------------------------------------------------------
  module simpleLists 
  local node xmlrep naming = join upcased 

  import S from sets
  import IN from inlineElements

  // ------------------------------------------------------
    docu user_en = "A very simple list module."

    tags CONTENTS = #GENERIC
    docu user_en CONTENTS = "To be replaced by what is allowed 
      as contents of an <i>."
    

    public tags list = (symbol? & (startnum|continues)? & IN.label?), i+
    with local 
      chars startnum = @S.decimalPositive
      chars symbol = @listSymbol
      chars continues = @S.ident
      tags i = (CONTENTS)* 
         with xmlrep el=listitem
    end local

    docu user_en list.startnum = #d2d
      CURRENTLY the starting number of a numbered list 
      CANNOT be set anymore! Once, in former html versions,
      this was possible. NOW it is advised to use CSS-three 
      for this purpose, but this is not yet on the market.#nl
      THEREFORE we ignore the value of "startnum" and of "continues".#nl
      IT COULD be built by rendering the list-items explicitly, not using
      the <ol> construct, but <xsl:number> and <html:dd> instead.
      But we are not sure whether this is sensible.
      #/d2d

    enum listSymbol = i, I, a, A, alpha, arab,
                      plus, minus, longminus,
                      bullet, openBullet, 
                      square, openSquare, 
                      diamond, openDiamond

    docu user_en listSymbol = #d2d
      longminus, openSquare, diamond, openDiamond are not yet supported.
    #/d2d

    docu user_en listSymbol.openDiamond, listSymbol.longminus,
	listSymbol.diamond, listSymbol.openSquare =  "not yet supported #bold!FIXME!"

    docu to_xhtml_1_0 list = 
      #d2d
        #x-var listchar #xp normalize-space(./a:listSymbol)#/x-var
        #choose 
          #when $listchar='' or $listchar='arab'
            #ol#style list-style-type:decimal; #call descendList
          #when $listchar='i'
            #ol#style list-style-type:lower-roman; #call descendList
          #when $listchar='I'
            #ol#style list-style-type:upper-roman; #call descendList
          #when $listchar='a'
            #ol#style list-style-type:lower-alpha; #call descendList
          #when $listchar='A'
            #ol#style list-style-type:upper-alpha; #call descendList
          #when $listchar='alpha'
            #ol#style list-style-type:lower-greek; #call descendList
          #when $listchar='bullet'
            #ul#style list-style-type:disc; #call descendList
          #when $listchar='openBullet'
            #ul#style list-style-type:circle; #call descendList
          #when $listchar='square'
            #ol#style list-style-type:square; #call descendList
          #other 
            #ul#style list-style-type:disc; #call descendList

    // current() is possibly a child of a p, then the lang and kind info must be copied:
    #template #name descendList
      #if parent::a:p
        #call copyLang_1_indirect
        #call copy_kind_to_class
      #/if
      #apply#xp a:listitem

    #template #match a:listitem
      #li#apply

    #template #match a:listitem #mode getreftext
      #param referer#/param
      #param referred#/param
      #param nsuri#/param 
      #param localname #/param
      #param textMultiple #/param
      #param textSingle #/param

      #apply #xp parent::a:list #mode getreftext
        #arg referer#xp $referer 
      #text!, !#
      #call muliDefault#arg p-key listitem#/call #text! !
      #x-var listchar #xp normalize-space(parent::a:list/a:listSymbol/text())#/x-var
      #choose 
        #when $listchar='a' or $listchar='A' or $listchar='i' or $listchar='I'
          #number #format {$listchar}  #count a:listitem 
                        // XALAN BUG WORK-AROUND, xsl:number needs "count" parameter.
        #when $listchar='alpha' or $listchar='α'
           //  U+03B1 (945) = klein-alpha = α 
           #number #format α #count a:listitem 
        #other 
          #number #format 1 #count a:listitem 
      #/choose
      #if $localname 
        #call reftextByCount
          #arg referred#xp $referred
          #arg nsuri#xp $nsuri
          #arg localname#xp $localname
          #arg textMultiple#xp $textMultiple
          #arg textSingle#xp $textSingle


    #template #match a:list #mode getreftext
      #param referer#/param
      #x-var sameList 
        #call refSameTest
          #arg referer #xp $referer
          #arg other #xp generate-id(.)
      #/x-var
      #choose 
        #when boolean(string($sameList)) // ATTENTION 
          #call muliDefault#arg p-key REF_sameList#/call
        #other
          #apply #xp parent::* #mode getreftext
            #arg referer#xp $referer
            #arg referred#xp generate-id(.)
            #arg nsuri#xp namespace-uri()
            #arg localname#xp local-name()
            #arg textMultiple#xp 'list'
            #arg textSingle#xp ''
    #/d2d

   
  end module // simpleLists

  // ------------------------------------------------------
  module simpleTables
  local node xmlrep naming = no mangling

  import IN from inlineElements
//Neu 20201201:
  import SETS from sets

  // ------------------------------------------------------

    tags CONTENTS = #GENERIC 
    tags table = (border? & IN.label?),  tr*
    tags tr    = (IN.label)?, (td*|th*)

//    tags td    = (CONTENTS)*
//Neu 20201201:
    tags td    = c?, (CONTENTS)*
    chars c =  @SETS.identInnerChar ~+ with xmlrep = "tdCls" 

    tags th    = (CONTENTS)*
 
    docu user_en table = #d2d
       Most simple table model; sufficient for many use cases, but can
       of course be replaced by something more elaborate, when necessary.
       #nl
       The nomenclature follows html.
       #p
       Labels at the explicit positions refer to the table or the table row;
       references to labels appearing anywhere in the text
       will contain the full address path   "table <T>, row <R>, column <C>".
       Numbering starts with one(1). 
    #/d2d

    tags border = #chars 
    docu user_en border 
      = "Values for kind, style, width of cell borders, following CSS2.0 syntax.
         Valid for the whole table."

    docu to_xhtml_1_0 table =
    #d2d
      #table 
        #if a:border
          #attribute border#valueof a:border
        #/if
        // current() is possibly a child of a p, then lang and kind info must be copied:
        #if parent::a:p
          #call copyLang_1_indirect
          #call copy_kind_to_class
        #/if
        #tbody
          #apply #xp a:tr

    #template #match a:td|a:th  #mode getreftext 
      #param referer#/param 
      #param referred#/param 
      #param nsuri#/param 
      #param localname #/param
      #param textMultiple #/param
      #param textSingle #/param
      #x-var sameTd 
        #call refSameTest
          #arg referer #xp $referer
          #arg other #xp generate-id(.)
      #/x-var
      #choose
        #when  boolean(string($sameTd)) // ATTENTION 
          #call muliDefault #arg p-key REF_same_td#/call 
        #other
          #x-var table #xp ancestor::a:table
          #apply #xp parent::* #mode getreftext
            #arg referer #xp $referer
          #/apply
          #text!, !
          #call muliDefault#arg p-key REF_table_col#/call
          #text! !
          #valueof count(preceding-sibling::a:tr | preceding-sibling::a:td)+1
      #/choose
      #if $localname
        #call reftextByCount
          #arg referred#xp $referred
          #arg nsuri#xp $nsuri
          #arg localname#xp $localname
          #arg textMultiple#xp $textMultiple
          #arg textSingle#xp $textSingle
        #/call

// can only come from td, or refer to the row as such.
    #template #match a:tr  #mode getreftext 
      #param referer#/param 
      #x-var sameTr
        #call refSameTest
          #arg referer #xp $referer
          #arg other #xp generate-id(.)
      #/x-var
      #choose
        #when  boolean(string($sameTr)) // ATTENTION 
          #call muliDefault #arg p-key REF_same_tr#/call 
        #other
          #apply #xp parent::* #mode getreftext
            #arg referer #xp $referer
          #/apply
          #text!, !
          #call muliDefault#arg p-key REF_table_row#/call
          #text! !
          #valueof count(preceding-sibling::a:tr)+1
      #/choose

    #template #match a:table  #mode getreftext 
      #param referer#/param 
      #x-var sameTable
        #call refSameTest
          #arg referer #xp $referer
          #arg other #xp generate-id(.)
      #/x-var
      #choose
        #when  boolean(string($sameTable)) // ATTENTION 
          #call muliDefault #arg p-key REF_same_table#/call 
        #other
          #apply #xp parent::* #mode getreftext
            #arg referer #xp $referer
            #arg referred#xp generate-id(.)
            #arg nsuri#xp namespace-uri()
            #arg localname#xp local-name()
            #arg textMultiple#xp 'REF_one_of_many_tables'
            #arg textSingle#xp 'REF_single_table'
          #/apply
    #/d2d

// "tr" may e empty in d2d, but not in xhtml:
    docu to_xhtml_1_0 tr = #d2d
       #choose #when ./td #tr#apply 
       #other #tr#td   // generate one emtpy dummy element
    #/d2d 


    docu to_xhtml_1_0 th = "#th#apply"
    docu to_xhtml_1_0 c = ""
    docu to_xhtml_1_0 td = #d2d
    #td
      #if a:tdCls #attribute class #valueof concat('tdCls_',a:tdCls/text()) #/if 
      #apply
    #/d2d

  end module // simpleTables


  // ------------------------------------------------------
  module simpleImage
  local node xmlrep naming = join by "_"

  import LINK from interDocuments
  // ------------------------------------------------------
    
    tags image =  file & alt?  & width? & height? & align? & showLabel?
    with local
      tags file = @ LINK.url with xmlrep trimmed
      tags width, height = #chars with xmlrep trimmed 
      tags align = #chars with xmlrep trimmed 
      tags alt = ALT 
      tags showLabel = #empty
    end local

    tags ALT = #GENERIC 
    docu user_en image.alt 
     = "If you leave it out, some alternative text from the enclosing elements must be found
    for rendering. This searched for by the named template 'copyAltFromContext', which
    otherwise will fail with an error."

    docu to_xhtml_1_0 image = #d2d
      #if $user.showlabels='yes' or a:image_showLabel
        #span#class debug
          #valueof a:image_file #/span#br
      #/if
       #img 
         #src {a:image_file}  
         #call copyAltFromContext
         #if a:image_width #attribute width #valueof a:image_width #/if
         #if a:image_height #attribute height #valueof a:image_height #/if
    #/d2d

  end module // simpleImage


  // ======================================================================
  module floatings 
  local node xmlrep naming = join by "_"

  import S from sets
  import E from inlineElements

  // ======================================================================

    tags tableOfContents = caption? & switchOnText? & switchOffText?

    tags listOf = #implicit  series, ( caption  & numberingScope?
                                     & switchOnText?  & switchOffText?
                                     & initiallyHidden? )

    tags series = #chars with xmlrep trimmed 

    tags caption, shortCaption  = captiontext*
    chars numberingScope = "h"~@S.decimalDigit
    tags switchOnText, switchOffText = switchtext*
    tags initiallyHidden = #empty

    docu user_en tableOfContents = 
      #d2d Will be expanded to a complete table of contents, of the hierarchical
      structure of the whole document.
    #/d2d
    docu user_en listOf = 
      #d2d Will be expanded to a list of the floating objects of a certain series.
      #/d2d
    docu user_en caption = 
      #d2d The headline for the "table of contents", or for any floating object. 
      #/d2d
    docu user_en shortCaption = 
      #d2d A shorter version of the caption of a floating object.
      Iff present, it replaces the longer caption in the "listOf" survey.
      #/d2d
    docu user_en switchOnText =
      #d2d A short text line. When clicked, it will pop-up/open the "listOf" survey.
      #/d2d
    docu user_en switchOffText =
      #d2d A short text line. When clicked, it will hide/close the "listOf" survey.
      If a switchOff text is given, a switch will be installed and a
      switchOnText is required, or at least a "caption", which will be used as such.
      #/d2d
    docu user_en numberingScope =
      #d2d Indication of the structure level (like "h1", "h2", ...) in which 
      the numbering of the floatings will be based on.
      #/d2d
    docu user_en series =
      #d2d The series is NOT an identifier, but can contain arbitrary characters.
      This is usefule because it is #emph!visible! to the end user.
      E.g. in the German language you want to include a list of "Gemälde" and
      floating objects called "Gemälde 1.2"
      #/d2d


    tags switchtext = #GENERIC
    tags captiontext = #GENERIC
                                      
    tags floating = #implicit series, 
      (caption? & shortCaption? & E.label? 
       & width? & height? &  positioning? & body)
      with local 
        tags positioning = #chars with xmlrep trimmed
        tags width, height = #chars with xmlrep trimmed
        tags body = (floating.BODY)*  // just @ BODY does not work !! FIXME ???
        tags BODY = #GENERIC
      end local



    docu to_xhtml_1_0 = #d2d
/*  ATTENTION docu to_xhtml_1_0 tableOfContents = ... DOES NOT WORK because
    in basic.structure "@listOf" does not copy xslt code. FIXME */

      #template #match a:tableOfContents 
        #call makeVisibilitySwitch 
          #arg id-switch #xp'_switch_TOC'
          #arg id-table  #xp'__div_TOC'
        #p#id __div_TOC 
          #a #id  TOC  #span #class tocTitle #apply #xp a:caption#/a
          #br/
          #choose
            #when /descendant::a:part
              #apply #xp /descendant::a:part  #mode maketoc
            #other
              #apply #xp /descendant::a:h1 #mode maketoc
        #/p
    #/d2d



    docu to_xhtml_1_0 = #d2d
/*  ATTENTION docu to_xhtml_1_0 listOf = ... DOES NOT WORK because
    in basic.structure "@listOf" does not copy xslt code. FIXME */

      #template #match a:listOf 
        #x-var myseries#xp a:series/text()
        #hr/
        #call makeVisibilitySwitch 
              #arg id-switch #xp concat('__switch_listOf_',$myseries)
              #arg id-table #xp concat('__div_listOf_',$myseries)
        #div #id __div_listOf_{$myseries} 
          #attribute style
            #choose 
              #when a:initiallyHidden
                #text!display:none;!
              #other
                #text!display:block;!
          #/attribute 
          #span #class tocTitle 
            #a#id {concat('__listOf_',$myseries)} #name {concat('__listOf_',$myseries)}
              #apply #xp a:caption
          #/span	
          #table #tbody 
            #foreach /descendant::a:floating[a:series/text()=$myseries]
              #x-var mynum #call makeFloatingNumber #/x-var 
              #x-var mylab #call makeFloatingLabel #/x-var
///**/ #message FLOAT TABLE LABEL IS #valueof $mylab #text!---! /* #valueof . */ #/message
   //FIXME falsche node-list be count "any" ?? /**/#message#valueof concat(" MYNUM ",$mynum,"---",.)#/message
              #tr #valign top 
            #td #a #href {$a:const.hashmark}{$mylab} #valueof $mynum
            #/a #/td
            #td #a #href {$a:const.hashmark}{$mylab} 
                  #choose 
                    #when a:shortCaption #apply#xp a:shortCaption#mode intoc
                    #other#apply#xp a:caption#mode intoc
                #/a 
            #/foreach
            #tr#td // dummy, since tbody may not be emtpy
      #/div
      #hr/


      #template #name makeFloatingLabel // "." points to a "floating"
       #choose	
         #when a:label #valueof a:label/text()
///**/ #message FLOAT MAKE LABEL xxxxxxxxxxxxxxxx IS #valueof a:label/text() #text!---! /* #valueof . */ #/message
         #other 
           #x-var mynum #call makeFloatingNumber #/x-var 
           #valueof concat('_', a:series, '_', $mynum)

      #template #name makeFloatingNumber // "." points to a "floating"
        #x-var myseries#xp a:series/text()
        #x-var numberbase
          #xp /descendant::a:listOf[a:series/text()=$myseries]/a:numberingScope
        #choose 
          #when $numberbase
            #apply #xp ancestor::*[local-name()=$numberbase] #mode getnumberComplete
                            // = with partnumber,if necessary. Cannot be used in a postappendix.
            #text!.!
            #number #count a:floating[a:series/text()=$myseries]
              #from *[local-name()=$numberbase]
              #level any
          #other
            #number #count a:floating[a:series/text()=$myseries]
                    #level any

      #template #name makeVisibilitySwitch
        #param id-switch#/param
        #param id-table#/param
        #if a:switchOffText and (not(a:switchOnText or a:caption))
           #message ERROR, switchOfftext, but neither switchOnText nor caption
                   in #valueof .
        #/if
        #if a:switchOffText
          #x-var switchontx
              #choose
              #when a:switchOnText 
                #foreach a:switchOnText#call a:getOneLineText
              #other
                #foreach a:caption#call a:getOneLineText
           #/x-var
           #x-var switchofftx#
              #foreach a:switchOffText#call a:getOneLineText
           #/x-var
           #p#span #id {$id-switch}#class switchText
                #onclick toggleVisibility('{$id-switch}', '{$id-table}', '{$switchontx}', '{$switchofftx}')
                #onmouseover this.style.textDecoration='underline'; 
                #onmouseout  this.style.textDecoration='none';
                #choose
                  #when a:initiallyHidden
                    #valueof $switchontx
                  #other
                    #valueof $switchofftx


    #/d2d



    docu to_xhtml_1_0 floating = #d2d
      #x-var mylab #call makeFloatingLabel#/x-var
///**/ #message FLOAT LABEL IS #valueof $mylab#/message
      #x-var myseries #valueof a:series/text()#/x-var
        #table
          #if a:width
            #attribute width #valueof a:width #/if
          #if a:height
            #attribute height#valueof a:height #/if
          #choose
            #when a:positioning/text()='floatleft'
              #attribute style#text float:left;margin:10pt;
            #when a:positioning/text()='floatright'
              #attribute style#text float:right;margin:10pt;
          #/choose
// PRE 20201117          #tbody #tr #td 
          #tbody #tr #td #class floatbody_{$myseries}
             #a #name {$mylab} #id {$mylab}#/a
             #apply #xp a:floating_body
           #/tr
      #if a:caption
        #tr #td #class floatingCaptionField
              #if $user.showlabels="yes" #span #class debug #valueof $mylab #/if
              #choose #when /descendant::a:listOf[a:series/text()=$myseries]
                #a #href {$a:const.hashmark}__listOf_{$myseries}
                  #valueof a:series#text#noescape &#23xA0;#call makeFloatingNumber
              #other
                #valueof a:series#text#noescape &#23xA0;#call makeFloatingNumber
              #/choose
              #text!:  !
              #apply #xp a:caption

     // reflects already the hierarchy of sections as prepended number sequence.
    #template #match a:floating #mode getreftext
      #param referer#/param 
      #param referred#/param 
      #param nsuri#/param 
      #param localname #/param
      #param textMultiple #/param
      #param textSingle #/param
      #x-var sameFloat 
        #call refSameTest
          #arg referer #xp $referer
          #arg other #xp generate-id(.)
      #/x-var
      #choose
        #when sameFloat
          #call muliDefault #arg p-key #xp concat('this ',./a:series/text()) 
        #other
          #valueof a:series#text#noescape &#23xA0;#call makeFloatingNumber
          #if $user.refTitle='inline'
            #valueof concat(' ("', a:caption, '")')
      #/choose
      #if $localname
        #call reftextByCount
          #arg referred#xp $referred
          #arg nsuri#xp $nsuri
          #arg localname#xp $localname
          #arg textMultiple#xp $textMultiple
          #arg textSingle#xp $textSingle
        #/call

     #template #match a:floating #mode getreftextTitle
       #apply #xp ./a:caption #mode puretext

    #/d2d

  end module // floatings


  // ======================================================================
  module structure 
  local node xmlrep naming = join by "-" 
  // ======================================================================

    import SET from sets
    import PHY from physical 
    import X from xmlInfra 

    import E from inlineElements 
        ^(@horizontalText / EMPH_CONTENTS)
        ^(@horizontalText / XLANG_CONTENTS)

    import LINK from interDocuments 
        ^( (@horizontalText ^(#none/LINK.link)) / LINKTEXT)
        ^(@horizontalText / EMBED_ALT)

    import BIB from citation 
     ^(   (@verticalText ^(#none / IM.image)) 
        | (@verticalObjects ^(#none / PHY.hr) ^(#none / LINK.treeInclude)
      )                                      / ABSTRACT_CONTENTS)
     ^( (@horizontalText^(#none/LINK.link))  / TITLE_CONTENTS)
// ATTENTION treeInclude is in verticalText (via horizontalText) AND in verticalObjects

    import LI from simpleLists ^( (@verticalText | p)  / CONTENTS)

    import TA from simpleTables ^( (@verticalText | p) / CONTENTS)

    import IM from simpleImage  ^( #chars / ALT) 
                                ^( LINK / LINK )
// FIXME necessary when doing whole-module-rewrite, due to:
// error: an insertion of the generic (placeholder) definition named "basic.interDocuments:EMBED_ALT" should have been eliminated by a concrete definition, or by "#none".


    import FLOAT from floatings 
      ^( (@horizontalText^(#none/LINK.link)^(#none/BIB.cite)) / switchtext)
      ^( @verticalObjects / floating.BODY )
      ^( @horizontalText / captiontext ) 


    // ------------------------------------------------------

    docu user_en = 
      "This module defines the structural elements like paragraphs, chapters, etc.
       It starts plugging the sub-modules together, and distributing parametrization,
       without yet defining the very top of the corpus structure."

    tags DOMAINSPECIFIC_LINEAR_ELEMENTS = #GENERIC
    docu user_en DOMAINSPECIFIC_LINEAR_ELEMENTS = 
        "Additional domain specific abbreviations, etc. Their xhtml rendering
         must fit under a xhtml:span, e.g. for a d2d:emph or d2d:xemph. 
         Normally they may not be used under physical mark-up like d2d:ital."

    tags DOMAINSPECIFIC_VERTICAL_ELEMENTS = #GENERIC

    public tags horizontalText =
          #chars | @PHY.EXPORTMIXTURE | @E.MIXTURE | E.xlang 
          | DOMAINSPECIFIC_LINEAR_ELEMENTS 
          | LINK.treeInclude  | LINK.link | BIB.cite | IM.image  
    docu user_en horizontalText = #d2d
        All possible structured horizontal (ie. linear) text. 
        Must be restricted for certain use cases, e.g. links are not allowed in links,
        images not in abstracts, but possibly in chapter titles.
	When rendered to xhtml, these yield "inline-elements", i.e. they
        can be enclosed in an xhtml:span.
        (Is already too rich to appear in pure-character data, like those
        rendered as attribute values.)
    #/d2d



    // =@p
    tags verticalText = @horizontalText
                        | LI.list
                        | TA.table
                        | footnote  | footnotemark | footnotetext
//   | @SET.ident  // TESTWEISE --> uber 10 fehlermeldungen ! besser abbrechen?? FIXME 

    docu user_en verticalText = #d2d
         This is the flow contents of a #emph!paragraph!, as defined by the 
         #link #loc __DECLARATION__basic.structure:p #text #src!#hh p! element #/link,
         without the leading attributes kind, lang, etc.#nl
         This is both, horizontal (=linear) text and
	 vertically structured text elements (lists and tables, etc.),
         but not elements which are between paragraphs, like floats, biblists and
         (larger) embedded third-party objects.#nl
         They cannot stand under xhtml:span, but under xhtml:div.#nl
         Since d2d_gp uses the p as the central means of text organisation,
         eg. wrt. language, kind, etc., the d2d:p contains more than the xhtml:p.
         Therefore the "p-rotation algorithm" is applied.
    #/d2d

    tags verticalObjects =   p 
                           | LINK.embed 
                           | PHY.hr 
                           | xvolute
                           | source 
                           | FLOAT.floating 
                           | BIB.biblist 
                           | DOMAINSPECIFIC_VERTICAL_ELEMENTS 
                           | LINK.treeInclude
                           // PRE20240302         | LINK.treeInclude_PROVIS // FIXME necessary!?!? RAUS


    tags p = kind?, X.lang?, (@verticalText)* 
    docu user_en p = #d2d
      #p
      The paragraph is the central means for organizing text, eg. wrt. language
      and kind. 
      #p
      When rendering to xhtml, the items contained in  "kind" are prepended 
      with "paragraphkind_" and then stored  as "css class names", so that
      visual appearance can be controlled via css.
      #nl
      Furthermore, setting the variable user.p_kind_filter lets only
      pass those paragraphs with a non-empty intersection with this value.
      #nl
      ATTENTION: the values of "kind" are currently not restricted by an 
      enumeration type (since enumeration are not yet rewritable!), 
      but are free identifiers. So typos are not recognized
      and can cause missing or ill-rendered text.
      #p
      Due to its central role in organization, the contents of p 
      also includes tables and lists, which cannot be
      rendered in xhtml:p. The difference is bridged by the rotation algorithm.
      The transition between the possible contents is like this:
      #source
             d2d:h2                     xhtml:              
               |
               p                         p      list  p     table
      /    /   |   \    \              /  \           |
 chars link  list chars table       chars  link     chars  
      #/s=====ource
      #p
      In the other direction, a d2d:p can be contained also in containers like
      list item or table cell. Luckily, this is identical to xhtml:
      #source
          table/tr/td      
                   |
                   p
          list/i       = ul(ol)/li
               |                 |
               p                 p
      #/s=====ource
    #/d2d

    chars kind = [pkind @SET.ident]~("+"~[pkind @SET.ident])~*

    docu to_xhtml_1_0 p = #d2d
      #choose 
        #when a:kind
          #if contains($p_kind_filter, ' * ') or 
              contains($p_kind_filter, concat(' ', normalize-space(a:kind),' ')) 
//FIXME only ONE of the a:kind/a:pkind should be necessary to be in common!
            #foreach child::a:kind/following-sibling::node()[position()=1] 
              #call new_p
        #other 
          #foreach child::node()[position()=1] 
            #call new_p
    #/template

    #param user.p_kind_filter#/param

    // ATTENTION undefined var $user.p_kind_filter, must be declared BY CALLER, 
    // e.g. in basic.deliverables, because different default values may be sensible.
    #x-var p_kind_filter
      #choose #when normalize-space($user.p_kind_filter)="" #valueof ' * '
	      #other #valueof concat(' ',$user.p_kind_filter,' ')
    #/d2d


    docu to_xhtml_1_0 = #d2d

      // focus is a child of p, growing output a new structure (p or table or ..)
      // copy kind to class
      #template #name copy_kind_to_class 
	#if parent::a:p/a:kind
          #attribute class
            #foreach parent::a:p/a:kind/a:pkind[position()=1]
              #call collect_p_kind

      #template #name collect_p_kind // focus isA pkind
        #valueof concat('paragraphkind_',text(),' ')
        #foreach following-sibling::a:pkind[position()=1]
          #call collect_p_kind

      // starts a new xhtml:p and stores there all contents as long as possible.
      // current() is a child of d2d:p
      #template #name new_p 
        #choose
          #when local-name()='list' or local-name()='table'
             #foreach . #call from_p // switch to outside html:p
          #other
            #p 
              #call copy_kind_to_class
              #call copyLang_1_indirect
              #call in_p // consumes all, up to the first non-p
            #/p
            #foreach (following-sibling::a:table|following-sibling::a:list)[position()=1]
              #call from_p
            // easier would be "following-sibling-or-self", but this does not exist !?!?


      // loops internally as long current object can be contained INSIDE xhtml:p
      #template #name in_p
        //#message IN P reached, current focus = #valueof . #/message
        #if local-name()!='list' and local-name()!='table'
          #apply #xp .
          #foreach following-sibling::node()[position()=1] 
             #call in_p


      // loops internally as long current object must be OUTSIDE of xhtml:p, then
      //   starts a new html-p 
      #template #name from_p
        #apply #xp . 
        // must call copy_kind_to_class and copyLang_1_indirect explicitly, on its own.
        #foreach following-sibling::node()[position()=1] 
          #choose
            #when local-name()='list' or local-name()='table'
              #call from_p
            #other
              #call new_p
    #/d2d


    tags footnote, footnotetext = (symbol)?, (@p | p+)

    tags footnotemark = symbol?

    chars symbol = (SET.all - SET.whitespace)~+  with xmlrep att

    // FIXME footnotenmark, footnotetext not yet supported

    docu to_xhtml_1_0 footnote = #d2d
      #x-var symbolV
        #choose#when @a:symbol #valueof @a:symbol
          #other #valueof count(preceding::a:footnote[not(@a:symbol)])+1
      #/x-var
      #x-var symbolA
        #choose#when @a:symbol 
          #valueof concat('SYMB_',count(preceding::a:footnote[@a:symbol])+1)
        #other
          #valueof $symbolV
      #/x-var
      #a#href {$a:const.hashmark}__footnote{$symbolA}
      #name __etontoof{$symbolA}
      #id __etontoof{$symbolA}
      #sup #valueof $symbolV


    #template#match a:footnote#mode footn
      #x-var symbolV
        #choose#when @a:symbol #valueof @a:symbol
          #other #valueof count(preceding::a:footnote[not(@a:symbol)])+1
      #/x-var
      #x-var symbolA
        #choose#when @a:symbol 
          #valueof concat('SYMB_',count(preceding::a:footnote[@a:symbol])+1)
        #other
          #valueof $symbolV
      #/x-var
      #choose#when a:p
        #p
          #call copyLang_direct
          #call copy_kind_to_class 
          #a#href {$a:const.hashmark}__etontoof{$symbolA}
            #name __footnote{$symbolA}
            #id __footnote{$symbolA}
            #sup #valueof $symbolV
          #/a
          #foreach a:p[1]/node()[1] #call in_p#/foreach
        #/p
        #foreach a:p[1]
          #foreach (a:table|a:list)[position()=1] #call from_p
          #/foreach
        #/foreach
        #foreach a:p[position()>1]
          #foreach node()[1]
            #call new_p
      #other
        #p
          // no lang or pkind info is copied from the main text into the footnote!
          #a#href {$a:const.hashmark}__etontoof{$symbolA}
            #name __footnote{$symbolA}
            #id __footnote{$symbolA}
            #sup #valueof $symbolV
          #/a
          #foreach ./node()[1] #call in_p#/foreach
        #/p
        #foreach (a:table|a:list)[position()=1] #call from_p
 

    #template#match a:footnote #mode getreftext
      #param referred#/param 
      #param nsuri#/param 
      #param localname #/param
      #param textMultiple #/param
      #param textSingle #/param

      #call muliDefault #arg p-key REF_footnote#/call
      #valueof count(preceding::a:footnote)+1
      #if $localname 
        #call reftextByCount
          #arg referred#xp $referred
          #arg nsuri#xp $nsuri
          #arg localname#xp $localname
          #arg textMultiple#xp $textMultiple
          #arg textSingle#xp $textSingle
    #/d2d

  tags xvolute = #empty
  docu to_xhtml_1_0 xvolute = " #p#style text-align:center#img#alt Volute#src volute148.png "


// neu treeInclude 20160424  GEHT NICHT FIXME (siehe "imtaktVorwort.d2d" / "xx.SCO")
    tags source = (#chars | E.label | LINK.treeInclude)*
//    tags source = (#chars | E.label)*
      with xmlrep el = SRC, input verbatim

    docu to_xhtml_1_0 source = 
        " #table #class source #tbody #tr #td #pre #apply"

    docu user_en source = #d2d
      Larger unit of program source text, rendered as a text block on its own.
      Its input mode is "verbatim". This means (1) respecting whitespace and line 
      breaks, (2) must be ended by an explicit end token, 
      (3) all command characters will be ignored, except of those DIRECTLY 
      followed by a tag of an explicitly mentioned
      direct sub-element (here: "label").
    #/d2d



    docu to_xhtml_1_0 = #d2d

    /* strategy for toc-generation:
     * In this default style, each toc line is the title prefixed by the complete
     * number of the section. 
     * (Realized as one line, not in a table, but with constant distance.)
     * The mode maketoc descends the total structure.
       The modes getnumber<> ascend and collect the hierarchy number.
        (getnumberComplete with prepended part, or NN<n> for post-appendices,
	 getnumberVisible RELATIVE to part, and empty for post-appendices,
         so not usable in anchors and identification.)
       The mode intoc renders the title of the collected sections IN the
         toc, where links and references must be left out.
     */

      #template #match a:title #mode intoc
        #choose #when parent::a:h1 or parent::a:part
                  #b #apply #mode intoc
                #other 
                  #apply #mode intoc

      #template #match a:label|a:footnote #mode intoc
       // NOP 

      #template #match a:link #mode intoc
        #choose #when a:text #apply #xp a:text #mode intoc
                #other #valueof a:url 

      #template #match text() #mode intoc
        #valueof .

     // Create appearances of "pure text", where ALL decoration must be left out
     //   (e.g. for values of an xml attribute like "<img alt='XXX'>"

      #template #match text() #mode puretext 
        #valueof .
      #template #match * #mode puretext 
        #apply #mode puretext

      #template #match a:link #mode puretext 
        #choose#when a:text #apply #xp a:text #mode puretext
               #other #valueof a:url


      #template #match a:label|a:footnote #mode puretext 
        //NOP


      #template #name maketocline 
        #if local-name()='part'
          #br#/if
        #x-var numberV #apply #mode getnumberVisible #xp . #/x-var
        #x-var numberC #apply #mode getnumberComplete #xp . #/x-var
        // start with "NN" indicates intended invisibility of numbering
        #if $numberV
          #a #href {$a:const.hashmark}HIER{$numberC}
            #valueof $numberV
        #/if
        #text#noescape
          &#23xA0;&#23xA0;&#23xA0;&#23xA0;&#23xA0;&#23xA0;&#23xA0;&#23xA0;
        #a #href {$a:const.hashmark}HIER{$numberC}
           #choose
             #when a:toctitle
               #apply #xp a:toctitle #mode intoc
             #other #apply #xp a:title #mode intoc
        #/a
        #if local-name()='part'
          #br#/if
        #br

      #template #match a:part #mode maketoc 
         #call maketocline
         #apply #xp a:h1 #mode maketoc
      #template #match a:h1 #mode maketoc 
         #call maketocline
         #apply #xp a:h2 #mode maketoc
      #template #match a:h2 #mode maketoc 
         #call maketocline
         #apply #xp a:h3 #mode maketoc
      #template #match a:h3 #mode maketoc 
         #call maketocline
         #apply #xp a:h4 #mode maketoc
      #template #match a:h4 #mode maketoc 
         #call maketocline
         #apply #xp a:h5 #mode maketoc
      #template #match a:h5 #mode maketoc 
         #call maketocline
         #apply #xp a:h6 #mode maketoc
      #template #match a:h6 #mode maketoc 
         #call maketocline
     
      /* Mode getnumberComplete constructs the following patterns:
       *   for           #h1 .. #h1 .. #h2      deliver 2.1
       *   for #part ..  #h1 .. #h2             deliver I.2.1 (IF $user.partResetsChapterNumber)
       *   for #appendix #h1 .. #h1 .. #h2      deliver B.1
       *   for #postappendix  .. #h1 .. #h1     deliver NN2 
       * (Postappendices (like "bibliography" or "Bildnachweise") thus cannot be
       *   referred to by numbering.)
       *
       * The result of getnumberVisible  is used for printing toc-lines and chapter headers:
       * Empty for postappendix, and part numbers do not appear.
       */

      #template #match a:part #mode getnumberComplete 
        #number #format I #count a:part
      #template #match a:part #mode getnumberVisible
        #number #format I #count a:part


      #template #match a:h1 #mode getnumberComplete 
        #choose
          #when parent::a:postappendices
            #text NN_#number #count a:h1
          #when parent::a:appendices
            #number #format A  #count a:h1
	  #when $user.partResetsChapterNumber="yes"
            #if parent::a:part  
              #apply #xp parent::a:part#mode getnumberComplete
              #text!.!
            #/if
            #number #count a:h1 
          #other 
            #number #count a:h1 #level any 
      #/template

      #template #match a:h1 #mode getnumberVisible
        #choose
          #when parent::a:postappendices
          #when parent::a:appendices
            #number #format A  #count a:h1
	  #when $user.partResetsChapterNumber="yes"
            #number #count a:h1 
          #other 
            #number #count a:h1 #level any 
      #/template

      #param user.partResetsChapterNumber #xp "no" #/param

      #template #match a:h2 #mode getnumberVisible
        #apply #mode getnumberVisible #xp ancestor::a:h1#text .#number #count a:h2
      #template #match a:h3 #mode getnumberVisible
        #apply #mode getnumberVisible #xp ancestor::a:h2#text .#number #count a:h3
      #template #match a:h4 #mode getnumberVisible
        #apply #mode getnumberVisible #xp ancestor::a:h3#text .#number #count a:h4
      #template #match a:h5 #mode getnumberVisible
        #apply #mode getnumberVisible #xp ancestor::a:h4#text .#number #count a:h5
      #template #match a:h6 #mode getnumberVisible
        #apply #mode getnumberVisible #xp ancestor::a:h5#text .#number #count a:h6

      #template #match a:h2 #mode getnumberComplete
        #apply #mode getnumberComplete #xp ancestor::a:h1#text .#number #count a:h2
      #template #match a:h3 #mode getnumberComplete
        #apply #mode getnumberComplete #xp ancestor::a:h2#text .#number #count a:h3
      #template #match a:h4 #mode getnumberComplete
        #apply #mode getnumberComplete #xp ancestor::a:h3#text .#number #count a:h4
      #template #match a:h5 #mode getnumberComplete
        #apply #mode getnumberComplete #xp ancestor::a:h4#text .#number #count a:h5
      #template #match a:h6 #mode getnumberComplete
        #apply #mode getnumberComplete #xp ancestor::a:h5#text .#number #count a:h6
     

    #template #match a:h1|a:h2|a:h3|a:h4|a:h5|a:h6 #mode getreftext
      #param referer#/param 
      #param referred#/param 
      #param nsuri#/param 
      #param localname #/param
      #param textMultiple #/param
      #param textSingle #/param
      #x-var sameH 
        #call refSameTest
          #arg referer #xp $referer
          #arg other #xp generate-id(.)
      #/x-var
      #choose
        #when boolean(string($sameH)) // ATTENTION non-empty node set, but empty string!
          #choose
            #when local-name()="h1" 
              #call muliDefault #arg p-key REF_sameChapter
            #other
              #call muliDefault #arg p-key REF_sameSection
        #other
          #choose
            #when local-name()="h1" and parent::a:appendices 
              #call muliDefault #arg p-key appendix#/call#text! !
              #number#format A #count a:h1
            #when local-name()="h1" and parent::a:postappendices 
              #apply #mode getreftextTitle // "Glossary" "Index" have no number 
            #when local-name()="h1"
              #call muliDefault #arg p-key chapter#/call#text! !
              #apply #xp .#mode getnumberComplete
            #other
              #call muliDefault #arg p-key #xp 'Section'
              #text! !
              #apply #xp .#mode getnumberComplete 
              // subsections of postappendices = NN1_... are not useful!
          #/choose
          #if $user.refTitle='inline' 
              and not (local-name()="h1" and parent::a:postappendices)
            #text! ("!#apply#xp . #mode getreftextTitle#text!")!
      #/choose
      #if $localname
        #call reftextByCount
          #arg referred#xp $referred
          #arg nsuri#xp $nsuri
          #arg localname#xp $localname
          #arg textMultiple#xp $textMultiple
          #arg textSingle#xp $textSingle
        #/call

      #template #match a:h1|a:h2|a:h3|a:h4|a:h5|a:h6 #mode getreftextTitle
        #choose #when a:reftitle #apply #xp a:reftitle#mode intoc
                #other #apply #xp a:title #mode intoc

      #template #match a:reftitle|a:toctitle
        #apply #xp label
      // not intoc mode => simply NOP, but proofmode print of labels 
     
    #/d2d
     

    tags title, toctitle, reftitle  = (@horizontalText)*
      with xmlrep trimmed
    docu user_en reftitle 
      = "The text with which references to this corpus part will be rendered.
         Defaults to the (normal) title."
    docu user_en toctitle 
      = "The text with which this corpus part will be rendered in the
         Table Of Contents. Defaults to the (normal) title."

    tags htmlTitle  = #chars
      with xmlrep trimmed
    docu user_en htmlTitle 
      = "The text used for html header, DC meta tags, etc, 
         where only plain text is allowed.
         Defaults to the (normal) title stripped from all mark-up."

    tags abstract = @p | p+ 

    tags hierarchie = title, (toctitle? & reftitle?), (@verticalObjects)*, SUBH*
      with local tags SUBH = #GENERIC
           end local

    tags part = @hierarchie ^ (h1 / hierarchie.SUBH)

    tags h1 =  @hierarchie ^ (h2 / hierarchie.SUBH)
    tags h2 =  @hierarchie ^ (h3 / hierarchie.SUBH)
    tags h3 =  @hierarchie ^ (h4 / hierarchie.SUBH)
    tags h4 =  @hierarchie ^ (h5 / hierarchie.SUBH)
    tags h5 =  @hierarchie ^ (h6 /  hierarchie.SUBH)
    tags h6 =  @hierarchie ^ (#none /  hierarchie.SUBH)

    tags appendices, postappendices = h1+


    docu user_en part = 
      "Parts are an optional top-level grid and identified with roman numbers.
       The chapter numbers beneath are reset with a new part, 
       iff $user.partResetsChapterNumber = 'yes'."
    
    docu user_en appendices = 
      "There may be one such part, under which the h1-elements
       are numbered with capital latin characters instead of numbers."
    
    docu user_en postappendices = 
      "There may be one such part, under which (according to tradition)
       the h1-elements do not carry any numbering,
       like \"index\", \"bibliography\", \"glossary\", etc."
    
    /* In this default format, all titles are prefixed with the complete section number
     * (collected by mode=getNumberVisible), in the text body as well as in the toc.
     */   
    docu to_xhtml_1_0 title =
      #d2d
        #choose 
          #when parent::a:webpage  #span #class pagetitle #apply
          #other 
            #x-var number #apply #xp parent::* #mode getnumberVisible #/x-var
            #x-var technicalNumber  #apply #xp parent::* #mode getnumberComplete #/x-var
            #x-var elname // = the name for the xhtml representation
              #choose #when local-name(parent::*)='part' #valueof 'h1'
                      #other #valueof local-name(parent::*)
            #/x-var
            #element {$elname}#namespace!{$a:const.httpPrefix}www.w3.org/1999/xhtml!
              #if local-name(parent::*)='part'
                #attribute class #valueof 'partTitle'
              #/if
              #if $hastoc-internal='true'
                #a #href {$a:const.hashmark}TOC
                   #class backToToc 
                   #sup #text!^!#call muliDefault #arg p-key tocAbbrev
              #/if 
              #a #name {concat('HIER',$technicalNumber)}
                #valueof $number // = is empty for postappendices and does not name the part
              #/a
              #text  #/text
              #apply
            #/element
       #/d2d
    
    docu to_xhtml_1_0 = #d2d
      #x-var hastoc-internal #xp boolean(/descendant::a:tableOfContents)
    #/d2d

    tags metaContentsTag  = #implicit name, content
      with local tags name, content = #chars with xmlrep trimmed
      end local 

    docu to_xhtml_1_0 metaContentsTag =
      "#x-var text #foreach a:metaContentsTag-content #call a:getOneLineText#/x-var
       #meta #name {a:metaContentsTag-name} #content {$text}
      "


    // ==============================================================
    // module structure, UBIQUITUOUS general subroutines 
    //   ATTENTION, named templates must only be included ONCE!
    // ==============================================================

    docu to_xhtml_1_0 = 
      // for ONLY TO LOAD ONCE !!! match() seems idempotent, 
      //  but duplicate name() yields error!!!???
    #d2d 
    #param user.mulitable#/param
    
    #param user.defaultLang#/param
    
    #x-var baseLanguage 
      #choose 
         #when /child::*[@xml:lang] 
           #call firstLangInList #arg p-list #xp /child::*[@xml:lang][1]/@xml:lang
         #when not($user.defaultLang='') 
           #call firstLangInList #arg p-list #xp $user.defaultLang
         #other  
           #message#terminate no base language defined for document ?
      #/choose
    #/x-var
    
    #template #name muliDefault
      #param p-key#/param
      #call muliLookUp 
         #arg p-key #xp $p-key
         #arg p-lang #xp $baseLanguage
    
    // #template #name muliLookUp_with_fallback MISSING FIXME 
    
    
    #template #name muliLookUp 
      #param p-lang#/param
      #param p-key#/param
      // #message MULITABLE LOOK UP #valueof $user.mulitable#/message // 
    
      #choose
        #when document($user.mulitable)/a:translationfile
/a:entry[@key=$p-key and @lang=$p-lang]
          #valueof $p-key
        #when not(document($user.mulitable)/a:translationfile/a:entry[@key=$p-key])
          #message no muli translation entry for key #text >>#valueof $p-key#text <<
          #/message
          #valueof $p-key
        #when not(document($user.mulitable)/a:translationfile/a:entry[@key=$p-key]
                  /a:text[@lang=$p-lang])
          #message no muli translation entry for key 
            #text >>#valueof $p-key#text << with language >>#valueof $p-lang#text <<
          #/message
          //deliver the first "entry/text" as a fall-back.
          #valueof document($user.mulitable)/a:translationfile/a:entry[@key=$p-key]
                  /a:text[position()=1]/text()
        #other
           #valueof document($user.mulitable)/a:translationfile/a:entry[@key=$p-key]
                  /a:text[@lang=$p-lang]/text()
    #/template
   
    #/d2d
   
  end module // structure 


  // ======================================================================
  module deliverables
  local node xmlrep naming = join by "_"

  import E from inlineElements 
  import BIB from citation  ^ ( #none / ABSTRACT_CONTENTS)
  import STR from structure 
                            ^ ( #none  /DOMAINSPECIFIC_LINEAR_ELEMENTS)
                            ^ ( #none  /DOMAINSPECIFIC_VERTICAL_ELEMENTS)
  import X from xmlInfra
  // ======================================================================

    docu user_en = "This module defines top-level containers of documents, i.e.
        certain structures which represent products as a whole,
        in a certain tradition of publishing."


    public tags webpage = ( STR.title & subtitle? & STR.htmlTitle?
                          & (BIB.author|BIB.authors)? 
                          & (STR.metaContentsTag*)
                          & date?  
                          & STR.abstract?  
                          & (X.lang | X.langs)? 
                          ),
                          ( STR.FLOAT.tableOfContents | STR.FLOAT.listOf 
                          | @STR.verticalObjects)*,
                          (STR.h1+ | STR.part+)?,
                          STR.appendices?,
                          STR.postappendices?



    tags subtitle = @STR.title with xmlrep trimmed 
    tags date = #chars with xmlrep trimmed 

    // MISSING FIXME difference to web-page : no meta-tags, etc.
    public tags article = @webpage

    docu to_latex  article = "

    public tags pseq = STR.p* 

    // ------------------------------------------------------


    docu to_xhtml_1_0 webpage =  #d2d
      #html 
        #head 

// according to http://schneegans.de/web/xhtml, this should be the FIRST
// entry in 
// the head, and it should use "text/html", not "application/xml+xhtml", 
// e.g. to be effective for Lynx:
          #meta #http-equiv content-type
	    #content text/html; charset={$user.outputEncoding}#/meta

          // needed for html/xss validation:
          #meta #name referrer #content unsafe-url#/meta

// PRE 20240902
// // FIXME stimmt noch nicht, wird IMMER erzeugt !?! :
//           #if descendant::a:link[a:blank|a:top|a:inframe|a:framename]
//              #pi d2d_gp xhtml_transitional due to a/@target #/pi
//           #/if
          #if $user.iconUrl
            #x-var l-iconType 
              #call a:extractFileSuffix #arg p-string #xp $user.iconUrl#/x-var
            #link #rel icon #href {$user.iconUrl} #type image/{$l-iconType}
          #/if
          #x-var l-njs #xp normalize-space($user.jsUrls)
          #if string-length($l-njs)>2
            #call processJsUrls
              #arg p-separator #xp substring($l-njs,1,1)
              #arg p-list #xp substring($l-njs,2)
          #/if
          #x-var l-css #xp normalize-space($user.cssUrls)
          #if string-length($l-css)>2
            #call processCssUrls
              #arg p-separator #xp substring($l-css,1,1)
              #arg p-list #xp substring($l-css,2)
          #/if

// The "DC.<>" meta tags come from "Dublin Core", as described in
// http://de.selfhtml.org/html/kopfdaten/meta.htm#dublin_core
// and http://dublincore.org/documents/dcmi-terms/

	  #if a:author 
            #meta #name DC.creator  #content {a:author} #/if
// FIXME check FORMAT/schema of date encoding, etc.
          #if $date_source
            #meta #name DC.date  #content {$date_source} 
            #meta #name date     #content {$date_source} 
          #/if
// ATTENTION currently MORE THAN ONE language is permitted, like "#langs de+en"
//   but these are (a) also stored in d2d:(xml:)lang, and (b) only the first
//   language code is extracted into $baseLanguage.
          #meta #name DC.language #content {$baseLanguage} #/meta 
          #apply #xp a:metaContentsTag
          #choose 
            #when a:htmlTitle
              #title #valueof a:htmlTitle
              #meta #name DC.title #content {a:htmlTitle}
            #other
              #x-var oneLineTitle #foreach ./a:title  #call a:getOneLineText #/x-var
              #title #valueof $oneLineTitle #/title
              #meta #name DC.title #content {$oneLineTitle}
          #/choose
        #/head
        #body 
          #call make-header
          #hr/
          #p 
            #apply#xp ./a:title
            #if a:subtitle
              #br
              #span#class pageSubtitle #apply#xp ./a:subtitle#/span
            #/if
            #br/
            #choose
              #when a:author and $date_source
                #apply#xp a:author#text!, !#valueof $date_source
              #other
                #apply#xp a:author
                #valueof $date_source
            #/choose
          #hr/

// statt dessen positiv-liste "h1|p" !?!?!? FIXME

          #apply#xp *[local-name()!='title' and local-name()!='htmlTitle'
         	and local-name()!='subtitle' and local-name()!='author'
                and local-name()!='date'  and local-name()!='metaContentsTag' ]

          #p#br #hr/ // does not know that "if" does not deliver contents to "hr"
          #if /descendant-or-self::node()/a:footnote
            #apply #xp /descendant-or-self::node()/a:footnote #mode footn
            #p#br #hr 
            #p#br #hr 
          #/if
          #call make-footer

/* === 20221009 moved to ./libbasic.xslt.d2d  == GEHT NICHT, da ist kein xhtml bekannt !?!!!! */
/* === ./libbasic_xhtml.xslt.d2d FIXME komische RESOLVER BUG ?!?!? */
      #template #name processJsUrls
        #param p-separator#/param
        #param p-list#/param
        #if string-length($p-list)>1
          #script 
            #type text/javascript #src {substring-before($p-list, $p-separator)}
            // WORKAROUND for browser bugs:
            #commandchar! !text!noescape &#xffef;!/text!commandchar#
          #/script
          #call processJsUrls
            #arg p-separator #xp $p-separator
            #arg p-list #xp substring-after($p-list, $p-separator)

      #template #name processCssUrls
        #param p-separator#/param
        #param p-list#/param
        #if string-length($p-list)>1
          #link #rel stylesheet #type text/css
                #href {substring-before($p-list, $p-separator)}
          #/link
          #call processCssUrls
            #arg p-separator #xp $p-separator
            #arg p-list #xp substring-after($p-list, $p-separator)
/* == */

      #template #name make-header
       // still missing 

      #template #name make-footer
        #hr 
        #p 
          #if $date_translation or $user.host or $user.user
            #span #style font-size:x-small;
              #text#noescape made &#23xA0;&#23xA0;
              #valueof $date_translation 
              #text#noescape &#23xA0;&#23xA0; 
            #if $user.user
                #text#noescape by  &#23xA0;&#23xA0; 
               #valueof $user.user
                #text#noescape &#23xA0;&#23xA0; 
              #/if
              #if $user.host
                #text#noescape on  &#23xA0;&#23xA0; 
                #valueof $user.host
                #text#noescape &#23xA0;&#23xA0; 
              #/if
            #/span
          #/if
    
          #if not($user.footerNoValidator)
            #text#noescape  &#23xA0;&#23xA0;&#23xA0;&#23xA0;&#23xA0;&#23xA0;
            #a #href {$a:const.httpPrefix}validator.w3.org/check?uri=referer
               #img #src valid-xhtml10-blue-66x23.png
                    #alt Valid XHTML 1.0 Strict
                    #style border:0; position:relative; top:5px
            #/a
            #a #href {$a:const.httpPrefix}jigsaw.w3.org/css-validator/check/referer
               #img #src valid-css2-blue-66x23.png
                    #alt Valid CSS 2.1 
                    #style border:0; width:66px; position:relative; top:5px
            #/a
          #/if
          #br/
            #if $user.footerSignet
              #valueof $user.footerSignet #noescape
              #text#noescape &#23xA0;&#23xA0;
            #/if
// ++++
            #span #style font-size:x-small;
              #text  produced with 
              #a#href {$a:const.httpPrefix}bandm.eu/metatools/docs/usage/d2d.html
                #code #style font-size:medium
                      #text eu.bandm.metatools.d2d
              #/a
              #text#noescape   &#23xA0;&#23xA0; and &#23xA0;&#23xA0;
              #a#href {$a:const.httpsPrefix}www.w3.org/TR/xslt-10/ #text XSLT 1.0
// PRE20240913             #a#href {$a:const.httpPrefix}https://www.w3.org/TR/xslt-10/.w3.org/TR/xslt #text XSLT 
              #/a
             #if $user.pageSource
               #text#noescape  &#23xA0;&#23xA0; 
               #call muliDefault #arg p-key fyi_view#/call
               #text#noescape  &#23xA0; 
               #a #href {$user.pageSource} #/href #text page source text
               #/a
             #/if
             #/span#/p
          #hr
      #/template
    #/d2d

    docu to_xhtml_1_0 =  #d2d

    #x-var date_source // the date in the d2d source document, otherwise the call date
      #choose
        #when /a:webpage/a:date  #valueof /a:webpage/a:date
        #when $user.date         #valueof $user.date
    #/x-var

    #x-var date_translation // the date of the rendering call, otherwise the doc date
      #choose
        #when $user.date         #valueof $user.date
        #when /a:webpage/a:date  #valueof /a:webpage/a:date
    #/x-var

    #param user.date#/param
    #param user.user#/param
    #param user.host#/param
    #param user.cssUrls#/param
    #param user.iconUrl#/param
    #param user.jsUrls#/param
    #param user.pageSource#/param
    #param user.footerSignet#/param
    #param user.footerNoValidator#/param

    #/d2d
    
    // ---------------------------------------------------------------
    
   
    docu to_xhtml_1_0 =  #d2d
      #commentchar \
      #output
        #method xml

        #encoding utf-8
        #indent yes 
        #omit-xml-declaration no



        #doctype-public -//W3C//DTD XHTML 1.0 Strict//EN
        #doctype-system http://bandm.eu/doctypes/xhtml/xhtml_1_0.dtd
      #commentchar /


     #param user.outputEncoding #xp 'utf-8'

#/d2d

    // ---------------------------------------------------------------

    // FIXME DISLOC !?!?! template name rootToEmbed ???  match /node()  ????

    docu to_embedScript webpage = #d2d
      #apply 

      #template #match h1|h2|h3|h4|h5|h6   // only HERE embeds may reside, not IN p-s
        #apply 
      #output
        #method text
        #encoding utf-8
        #indent no
        #omit-xml-declaration yes
    #/d2d
 
  end module // deliverables

end module // basic

// eof
\n




go one page back go to start go to start go one page ahead
DOC-EN:lablog.ddf bandm meta_tools DOC:xslt.ddf

made    2024-09-23_07h46   by    lepper   on    happy-ubuntu        Valid XHTML 1.0 Transitional Valid CSS 2.1

produced with eu.bandm.metatools.d2d    and    XSLT    FYI view page d2d source text