# ========================================================= # # (c) 2004, RenderX # # Author: Alexander Peshkov # # Permission is granted to use this document, copy and # modify free of charge, provided that every derived work # bear a reference to the present document. # # This document contains a computer program written in # XSL Transformations Language. It is published with no # warranty of any kind about its usability, as a mere # example of XSL technology. RenderX shall not be # considered liable for any damage or loss of data caused # by use of this program. # # ========================================================= namespace local = "" default namespace fo = "http://www.w3.org/1999/XSL/Format" namespace rx = "http://www.renderx.com/XSL/Extensions" include "elements.rnc" start = root # **************************************************************************************** # Element structure for top-level elements # **************************************************************************************** # =============================================================== # Root element. Contains everything, generates nothing. It has an # id, a FO namespace prefix declaration, and other namespace # declarations if used. # =============================================================== root = element fo:root { root.attlist, root.content } root.content = meta-info?, layout-master-set, declarations?, outline?, page-sequence+ # =============================================================== # Document meta information - RenderX extension # =============================================================== meta-info = element rx:meta-info { meta-info.attlist, meta-info.content } meta-info.content = meta-field+ meta-field = element rx:meta-field { meta-field.attlist, empty } # =============================================================== # Color profile declarations # =============================================================== declarations = element fo:declarations { declarations.attlist, declarations.content } declarations.content = color-profile+ color-profile = element fo:color-profile { color-profile.attlist, empty } # =============================================================== # Bookmarks - RenderX extension # =============================================================== outline = element rx:outline { outline.attlist, outline.content } outline.content = bookmark+ bookmark = element rx:bookmark { bookmark.attlist, bookmark.content } bookmark.content = bookmark-label, bookmark* bookmark-label = element rx:bookmark-label { bookmark-label.attlist, bookmark-label.content } bookmark-label.content = text # =============================================================== # Layout-master-set. Contains a set of page-masters. # Content model made more strict than in the spec, to enforce # that a page-sequence-master be always accompanied by at least # one simple-page-master. # =============================================================== layout-master-set = element fo:layout-master-set { layout-master-set.attlist, layout-master-set.content } layout-master-set.content = page-sequence-master* & simple-page-master+ # =============================================================== # Page sequence master # =============================================================== page-sequence-master = element fo:page-sequence-master { page-sequence-master.attlist, page-sequence-master.content } page-sequence-master.content = (single-page-master-reference | repeatable-page-master-reference | repeatable-page-master-alternatives)+ # =============================================================== # Sequence specifiers are predefined sequences of page masters # that are used by page sequence master to construct a desired # page collection. # =============================================================== single-page-master-reference = element fo:single-page-master-reference { single-page-master-reference.attlist, empty } repeatable-page-master-reference = element fo:repeatable-page-master-reference { repeatable-page-master-reference.attlist, empty } repeatable-page-master-alternatives = element fo:repeatable-page-master-alternatives { repeatable-page-master-alternatives.attlist, repeatable-page-master-alternatives.content } repeatable-page-master-alternatives.content = conditional-page-master-reference+ conditional-page-master-reference = element fo:conditional-page-master-reference { conditional-page-master-reference.attlist, empty } # =============================================================== # Simple page master defines a page layout. It does not # explicitly generate any content. # =============================================================== simple-page-master = element fo:simple-page-master { simple-page-master.attlist, simple-page-master.content } simple-page-master.content = region-body, region-before?, region-after?, region-start?, region-end? # =============================================================== # Regions. The page instance is divided into subareas, whose # properties are described by the five region-* elements. These # elements by themselves do not generate any content. # =============================================================== # =============================================================== # Body region: middle of the page. # =============================================================== region-body = element fo:region-body { region-body.attlist, empty } # =============================================================== # Side regions: page edges. # =============================================================== region-before = element fo:region-before { region-before.attlist, empty } region-after = element fo:region-after { region-after.attlist, empty } region-start = element fo:region-start { region-start.attlist, empty } region-end = element fo:region-end { region-end.attlist, empty } # =============================================================== # Page sequence defines the order of choosing page masters to # accomodate all the contents generated by its fo:flow and # fo:static-content children, and the way of numbering them. # =============================================================== page-sequence = element fo:page-sequence { page-sequence.attlist, page-sequence.content } page-sequence.content = title?, static-content*, flow # =============================================================== # Title. May not contain out-of-lines. # =============================================================== #MEMO: Spec states: # XSL> Additionally, an fo:title is not permitted to have as a descendant an fo:block-container # XSL> that generates an absolutely positioned area. # We prohibit block-level descendants except for those descendats of fo:inline-container. # This content model shared by fo:leader and fo:inline child of an fo:footnote. title = element fo:title { title.attlist, title.content } title.content = inlines-inline* # =============================================================== # Flows. They are just sequences of blocks. 'flow-name' feature # defines linkage of the flow to a region in the page master. # =============================================================== # =============================================================== # An extension element, rx:flow-section, has been added in order # to overcome limitations on multicolumn layout imposed by XSL FO # =============================================================== #NOTE: We use tricks with nested grammar in order control marker/retrieve-marker #and outlines appearance inside fo:static-content and fo:flow #MEMO: We forcedly prohibit side-floats as descendants of ablsoutely positioned # block-containers. This problem appears due to the 'half-outline' behavior of # an absolute-container - it cannot contain outlines except for side-float and it cannot # be nested into any other outlines. #NOTE: 'Folint' prohibits use of side-floats in static-content that is against the spec. static-content = element fo:static-content { static-content.attlist, static-content.content } static-content.content = grammar { start = blocks+ include "elements.rnc" { retrieve-marker = retrieve-marker-real absolute-container = absolute-container-real absolute-container.content = parent absolute-container.content side-float = side-float-real float.content = parent float.content leader.content = parent leader.content } } flow = element fo:flow { flow.attlist, flow.content } flow.content = grammar { start =marker*, (blocks | flow-section)+ include "elements.rnc" { absolute-container = absolute-container-real #MEMO: We have two options here: # * use parent content model which is too strict (side-floats descendants not allowed); # * use current content model which is too loose (all outline descendants are allowed). # We prefer stricter mode. absolute-container.content = parent absolute-container.content marker = marker-real marker.content = parent marker.content side-float = side-float-real before-float = before-float-real float.content = parent float.content footnote = footnote-real footnote.content = parent footnote.content #NOTE: fo:leader can't have outlines and marker descendants leader.content = parent leader.content } # Extension element. Acts like a top-level block with multiple columns. flow-section = element rx:flow-section { flow-section.attlist, flow-section.content } flow-section.content = blocks+ } #MEMO: Spec prohibits use of fo:leader as a descendant of itself. # We find this constraint somewhat abusive so we do not enforce it. # 'Folint' also does not controll this constraint # However following trick can be used to prevent fo:leader to appear as it's own child. # (to make it work we have to set leader.content to be notAllowed and move # actual content into leader.content-real in elements.rnc) #leader.content |= grammar { # start = leader.content-real # include "elements.rnc" { # leader = notAllowed # } #}