require 'slaw/parse/grammar_helpers' require 'slaw/grammars/za/act_nodes' require 'slaw/grammars/za/postprocess'
require 'slaw/grammars/terminals' require 'slaw/grammars/tables' require 'slaw/grammars/schedules' require 'slaw/grammars/inlines'
module Slaw
module Grammars module ZA grammar Act include Slaw::Parse::GrammarHelpers include Slaw::Grammars::ZA::Postprocess ######## # major containers # # These are AKN's heirarchical containers which wrap actual content. rule act empty_line* preface:preface? preamble:preamble? body schedules:schedules_container? <Act> end rule preface !'PREAMBLE' !'BODY' ('PREFACE'i space? eol)? statements:(!'PREAMBLE' !'BODY' preface_statement)* <Preface> end rule preamble !'BODY' 'PREAMBLE'i space? eol statements:(!'BODY' preamble_statement)* <Preamble> end rule body ('BODY' space? eol)? children:(chapter / part / subpart / section / subsection / generic_container)* <Body> end # chapter (parts allowed) rule chapter heading:chapter_heading children:(part_no_chapter / subpart / section / subsection / generic_container)* <Chapter> end # part (chapters allowed) rule part heading:part_heading children:(chapter_no_part / subpart / section / subsection / generic_container)* <Part> end # part (no chapters) rule part_no_chapter heading:part_heading children:(subpart / section / subsection / generic_container)* <Part> end # chapter (no parts) rule chapter_no_part heading:chapter_heading children:(subpart / section / subsection / generic_container)* <Chapter> end rule subpart heading:subpart_heading children:(section / subsection / generic_container)* <Subpart> end rule section section_title children:(subsection / generic_container)* <Section> end rule subsection space? subsection_prefix space? block_elements_with_inline <Subsection> end rule generic_container crossheading / block_elements end rule crossheading 'CROSSHEADING ' inline_items:inline_items eol <Crossheading> end # An option inline block element, followed by consecutive non-structured content. # This is useful after a rule that can start a new container and have # the first element of the container on the same line, eg.: # # (1) subsection with content # (a) list a... # rule block_elements_with_inline first_child:inline_block_element? children:block_element* <BlockElementsWithInline> end # Consecutive non-structured content. We allow many elements # here so that we wrap consecutive block elements in one <content> tag, # rather than multiple containers for each. rule block_elements block_element+ <BlockElements> end ########## # group elements # # these are used externally and provide support when parsing just # a particular portion of a document rule chapters children:chapter+ <GroupNode> end rule chapters_no_parts children:chapter_no_part+ <GroupNode> end rule parts children:part+ <GroupNode> end rule parts_no_chapters children:part_no_chapter+ <GroupNode> end rule subparts children:subpart+ <GroupNode> end rule sections children:section+ <GroupNode> end ########## # headings rule chapter_heading space? chapter_heading_prefix heading:(newline? space? inline_items)? eol <ChapterHeading> end rule part_heading space? part_heading_prefix heading:(newline? space? inline_items)? eol <PartHeading> end rule subpart_heading space? subpart_heading_prefix heading:(newline? space? inline_items)? eol <SubpartHeading> end rule section_title section_title_1 / section_1_title end rule section_title_1 &{ |s| options[:section_number_after_title] } # Section title # 1. Section content space? inline_items eol section_title_prefix whitespace <SectionTitleType1> end rule section_1_title # 1. Section title # Section content # # Additionally, the section title is optional. !{ |s| options[:section_number_after_title] } space? section_title_prefix section_title:section_title_content? eol? <SectionTitleType2> end rule section_title_content # don't match subsections, eg. # # 10. (1) subsection content... space !subsection_prefix inline_items eol end ########## # blocks of content inside containers rule block_element (table / blocklist / naked_statement) end # Block elements that don't have to appear at the start of a line. # ie. we don't need to guard against the start of a chapter, section, etc. rule inline_block_element (table / blocklist / inline_statement) end rule blocklist blocklist_item+ <Blocklist> end rule blocklist_item # TODO: this whitespace should probably be space, to allow empty blocklist items followed by plain text space? blocklist_item_prefix whitespace item_content:(!blocklist_item_prefix inline_items:inline_items? eol)? eol? <BlocklistItem> end rule blocklist_item_prefix ('(' letter_ordinal ')') / dotted_number_3 end ########## # statements - single lines of content # # If a statement starts with a backslash, it's considered to have escaped the subsequent word, # and is ignored. This allows escaping of section headings, etc. rule naked_statement space? !body_hierarchy_prefix '\\'? inline_items:inline_items? eol <NakedStatement> end rule preface_statement space? !non_body_hierarchy_prefix content:(longtitle / ('\\'? inline_items:inline_items eol)) <PrefaceStatement> end rule preamble_statement space? !non_body_hierarchy_prefix '\\'? inline_items eol <NakedStatement> end rule longtitle 'LONGTITLE ' inline_items:inline_items eol <LongTitle> end ########## # prefixes rule part_heading_prefix 'part'i space alphanums [ :-]* end rule subpart_heading_prefix 'subpart'i num:(space alphanums)? [ :-]* end rule chapter_heading_prefix 'chapter'i space alphanums [ :-]* end rule section_title_prefix number_letter '.'? end rule subsection_prefix # there are two subsection handling syntaxes: # # (1) foo # (2A) foo # # and # # 8.2 for # 8.3 bar # # The second is less common, but this allows us to handle it. # Note that it is usually accompanied by a similar list number format: # # 8.2.1 item 1 # 8.2.2 item 2 # # which aren't subsections, but lists, so force the space at the end # of the number to catch this case. num:('(' number_letter ')') / num:dotted_number_2 '.'? (space / newline) end rule body_hierarchy_prefix # Text that indicates the start of a hierarchy element, in the body chapter_heading / part_heading / subpart_heading / section_title / schedule_title / subsection_prefix / crossheading end rule non_body_hierarchy_prefix # Text that indicates the start of a hierarchy element, in the preamble or preface chapter_heading / part_heading / subpart_heading / section_title / schedule_title / crossheading end include Slaw::Grammars::Inlines include Slaw::Grammars::Tables include Slaw::Grammars::Schedules include Slaw::Grammars::Terminals end end end
end