Open cch123 opened 5 years ago
ciao
// 理论上 section 是支持内嵌的
// 例如 == section 2 then === section 3
// 但问题是在语法定义上,理论上是下一级的 level < 上一级,才能被嵌入进去
// 不能有 === section 3 内部嵌入了 == section 2 的情况
// 在语法上不是很好表达这个意思,需要再考虑考虑
It might be the pest vm taking too much time to load -- I believe intellij's own parser is still working as this file is large but not huge. This means the live preview should be made optional
RT
whenever editing the file, cost a lot time to wait for respond
example grammar is :
View code
``` // --------------------------------------------------- // PreflightDocument - fully parsed document, linearly // --------------------------------------------------- pre_flight_document = { SOI ~ EOLS ~ front_matter* //~ EOLS* ~ document_blocks* ~ EOI } pre_flight_document_within_delimited_block = { SOI ~ front_matter* ~ document_blocks_within_delimited_block ~ EOI } // ------------------------------------------ // Document blocks // ------------------------------------------ document_blocks = { document_block+ } document_block = { document_header? //~ preamble ~ sections } preamble = { (!("="|EOI) ~ section_body)+ } sections = { section+ } /* sections = { !EOI ~ ( simple_paragraph | section | delimited_block | file_inclusion | verse_paragraph // must be before image_block | image_block | list_item | blank_line // must be before Literal_block | literal_block | document_attribute_declaration | document_attribute_reset | table_of_contents_macro | user_macro_block | paragraph ) } */ document_blocks_within_delimited_block = { document_block_within_delimited_block* } document_block_within_delimited_block = { delimited_block | file_inclusion | verse_paragraph | image_block | list_item | blank_line // must be before Literal_block | literal_block | document_attribute_declaration | document_attribute_reset | table_of_contents_macro | user_macro_block | paragraph } // ------------------------------------------ // Front Matter // ------------------------------------------ front_matter = { yaml_front_matter } yaml_front_matter = { yaml_front_matter_token ~ yaml_front_matter_content? ~ yaml_front_matter_token } yaml_front_matter_token = { "---" ~ EOLS } yaml_front_matter_content = { ((!yaml_front_matter_token ~ ANY)+)* } // ------------------------------------------ // Document Header and Metadata // ------------------------------------------ document_header = { "=" ~ WS{1,} ~ title_elements ~ inline_element_id* ~ EOL ~ document_authors? ~ document_revision? } document_authors = { WS* ~ !"=" ~ (document_authors_inline_form | document_authors_attribute_form) } document_authors_inline_form = { !":" ~ document_author+ ~ EOL } document_authors_attribute_form = { ":author:" ~ document_author ~ EOL } document_author = { document_author_name ~ document_author_email? ~ WS* ~ ";"? ~ WS* } // "<" marks the beginning of the author email, and ";" is the authors separator document_author_name = @{ (ASCII_ALPHANUMERIC+ | (!("<" | ";" | NEWLINE ) ~ ANY))+ } document_author_email = @{ "<" ~ (ASCII_ALPHANUMERIC+ | (! (">" | EOL ) ~ ANY))+ ~ ">" } // see http://asciidoctor.org/docs/user-manual/#revision-number-date-and-remark // Eg: "v1.0, October 2, 2013: First incarnation" document_revision = { WS* ~ !(":"|"=") ~ ((document_revision_number ~ ","? ~ document_revision_date? ~ ":"? ~ document_revision_remark?) | (document_revision_date ~ ":"? ~ document_revision_remark?)) ~ EOL } // Document_revisionNumber MUST start with a `v` or MAY start with a `v` but MUST end with a `,` document_revision_number = @{ ASCII_DIGIT } document_revision_date = @{ (ASCII_ALPHANUMERIC+ | spaces | (!(EOL |":") ~ ANY))+ } document_revision_remark = @{ (ASCII_ALPHANUMERIC+ | spaces | (!EOL ~ ANY))+ } // ------------------------------------------ // Document attributes // ------------------------------------------ document_attribute_declaration = { ":" ~ document_attribute_name ~ ":" ~ (WS+ ~ document_attribute_value)? ~ EOLS } // attributeName must be at least one character long, // must begin with a word character (A-Z, a-z, 0-9 or _) and // must only contain word Word and hyphens ("-"). document_attribute_name = { ( ASCII_ALPHANUMERIC+ | "_") ~ (ASCII_ALPHANUMERIC+ | "-")* } document_attribute_value = { (!NEWLINE ~ ANY)+ } document_attribute_reset = { ":!" ~ document_attribute_name ~ ":" ~ EOLS | ":" ~ document_attribute_name ~ "!:" ~ EOLS } document_attribute_substitution = { "{" ~ document_attribute_name ~ "}" } // ------------------------------------------ // Element attributes // ------------------------------------------ element_attributes = { element_attribute+ } element_attribute = { &("[" | "." | "#") // skip if the content does not start with one of those characters ~ ( element_id | element_title | element_role | literal_attribute | source_attributes | quote_attributes | verse_attributes | admonition_marker_attribute | horizontal_layout | attribute_group ) } // identify all attributes that masquerade a block element into something else. masquerade_attribute = { quote_attributes | verse_attributes } element_id = { "[[" ~ ID ~ "]]" ~ EOLS | "[#" ~ ID ~ "]" ~ EOLS } inline_element_id = { "[[" ~ ID ~ "]]" ~ WS* } // a title attached to an element, such as a image_block // a title starts with a single "." followed by the value, without space in-between element_title = { "." ~ ASCII_ALPHANUMERIC+ ~ (ASCII_ALPHANUMERIC+ | spaces | (!NEWLINE ~ ANY))* ~ EOL } // a role attached to an element, such as a image_block // a role starts is wrapped in "[. ]" element_role = { "[." ~ ASCII_ALPHANUMERIC+ ~ (ASCII_ALPHANUMERIC+ | spaces | (!( NEWLINE | "]" ) ~ ANY))* ~ "]" ~ EOLS } literal_attribute = { "[literal]" ~ WS* ~ NEWLINE } // expression for the whole admonition marker, but only retains the actual kind admonition_marker_attribute = { "[" ~ admonition_kind ~ "]" ~ EOLS } // a paragraph or a delimited block may contain source code in a given language source_attributes = { "[source" ~ ","? ~ ((spaces | (!( NEWLINE |"]" ) ~ ASCII_ALPHANUMERIC))+)? ~ "]" ~ EOLS } // one or more attributes. eg: [foo, key1=value1, key2 = value2 , ] attribute_group = { "[" ~ generic_attribute* ~ "]" ~ EOLS } generic_attribute = { attribute_key ~ "="? ~ attribute_value? ~ ","? ~ WS* } attribute_key = { !("quote" |"verse" |"literal") ~ (ASCII_ALPHANUMERIC+ | other_attribute_char)+ ~ WS* } attribute_value = { (ASCII_ALPHANUMERIC+ | spaces | other_attribute_char)+ ~ !"=" } other_attribute_char = { (!(WS |"=" |"," |"]") ~ ANY) } horizontal_layout = { "[horizontal]" ~ EOLS } quote_attributes = { "[quote" ~ WS* ~ ","? ~ quote_attribute? ~ ","? ~ quote_attribute? ~ "]" ~ EOLS } verse_attributes = { "[verse" ~ WS* ~ ","? ~ quote_attribute? ~ ","? ~ quote_attribute? ~ "]" ~ EOLS } quote_attribute = { (ASCII_ALPHANUMERIC+ | spaces | (! ("," |"]" | EOL) ~ ANY))* } inline_attributes = { "[" ~ generic_attribute* ~ "]" } // ------------------------------------------ // Sections // ------------------------------------------ /*section = { element_attributes? ~ "="{1,6} ~ title_elements ~ inline_element_id* ~ EOL } */ section = { section_header ~ section_body* } section_header = { element_attributes? ~ "="{2,6} ~ title_elements ~ inline_element_id* ~ EOL } section_body = { // 理论上 section 是支持内嵌的 // 例如 == section 2 then === section 3 // 但问题是在语法定义上,理论上是下一级的 level < 上一级,才能被嵌入进去 // 不能有 === section 3 内部嵌入了 == section 2 的情况 // 在语法上不是很好表达这个意思,需要再考虑考虑 // section paragraph | simple_paragraph | delimited_block | file_inclusion //| verse_paragraph // must be before image_block | image_block //| list_item | blank_line // must be before Literal_block | literal_block //| document_attribute_declaration //| document_attribute_reset //| table_of_contents_macro //| user_macro_block } title_elements = { (!(NEWLINE | inline_element_id) ~ WS* ~ title_element)+ } title_element = { simple_word | spaces | cross_reference | passthrough | inline_image | link | inline_footnote | quoted_text | document_attribute_substitution | line_break | other_word } // ------------------------------------------ // table of Contents // ------------------------------------------ table_of_contents_macro = { "toc::[]" ~ EOL } // ------------------------------------------ // User Macro // ------------------------------------------ user_macro_block = { user_macro_name ~ "::" ~ user_macro_value ~ user_macro_attributes } inline_user_macro = { user_macro_name ~ ":" ~ user_macro_value ~ user_macro_attributes } user_macro_name = { (ASCII_ALPHANUMERIC+ | "_" | "-")+ } user_macro_value = { (ASCII_ALPHANUMERIC+ | (!(":" |"[" |EOL ) ~ ANY))* } user_macro_attributes = { "[" ~ generic_attribute* ~ "]" } // ------------------------------------------ // file inclusions // ------------------------------------------ file_inclusion = { "include::" ~ file_location ~ file_include_attributes ~ EOLS } file_include_attributes = { "[" ~ (line_ranges_attribute | generic_attribute)* ~ "]" } line_ranges_attribute = { "lines=" ~ line_ranges_attribute_value ~ ","? } // specific entry point for parsing line_ranges_attribute_value = { (multiple_ranges | multiple_quoted_ranges | multiline_range | multiline_quoted_range | singleline_quoted_range | singleline_range | undefined_line_range) ~ WS* ~ (&"," | &"]") } multiple_ranges = { (multiline_range | singleline_range) ~ (";" ~ (multiline_range | singleline_range))+ } multiple_quoted_ranges = { "\"" ~ (multiline_range | singleline_range) ~ ("," ~ (multiline_range | singleline_range))+ ~ "\"" } multiline_range = { NUMBER ~ ".." ~ NUMBER } multiline_quoted_range = { "\"" ~ NUMBER ~ ".." ~ NUMBER ~ "\"" } singleline_range = { NUMBER } singleline_quoted_range = { "\"" ~ NUMBER ~ "\"" } undefined_line_range = { (!("]" |"," |WS) ~ ANY)* } // ------------------------------------------ // Lists // ------------------------------------------ list_items = { list_item+ } list_item = { ordered_list_item | unordered_list_item | labeled_list_item | continued_list_item_element } list_paragraph = { single_line_comment | list_paragraph_line+ } list_paragraph_line = { !(EOI | blank_line | single_line_comment | ordered_list_item_prefix | unordered_list_item_prefix | (labeled_list_item_term ~ labeled_list_item_separator) | list_item_continuation | element_attribute | block_delimiter) ~ inline_element+ ~ line_break? ~ EOL } list_item_continuation = { "+" ~ EOLS } continued_list_item_element = { blank_line* ~ list_item_continuation ~ sections } // ------------------------------------------ // Ordered List Items // ------------------------------------------ ordered_list_item = { element_attributes? ~ ordered_list_item_prefix ~ ordered_list_item_content } ordered_list_item_content = { list_paragraph+ } // ------------------------------------------ // Unordered List Items // ------------------------------------------ unordered_list_item = { element_attributes? ~ unordered_list_item_prefix ~ unordered_list_item_check_style? ~ unordered_list_item_content } unordered_list_item_prefix = { WS* ~ (("*"{1,6} ~ WS*) | (("-") ~ WS+)) } ordered_list_item_prefix = { WS* ~ (("."{1,6} ~ WS*) | (ASCII_DIGIT ~ "." ~ WS+) | (ASCII_ALPHA ~ "." ~ WS+)) } unordered_list_item_check_style = { &"[" ~ ("[ ]" | "[*]" | "[x]") ~ WS+ } unordered_list_item_content = { list_paragraph+ } // ------------------------------------------ // labeled List Items // ------------------------------------------ labeled_list_item = { element_attributes? ~ labeled_list_item_term ~ labeled_list_item_separator ~ labeled_list_item_description? } labeled_list_item_term = { (ASCII_ALPHANUMERIC+ | spaces | (!(NEWLINE |"::") ~ ANY))+ } labeled_list_item_separator = { ("::" ~ !":") | ("::::" ~ !":") ~ ((WS | NEWLINE)+ | EOL) } labeled_list_item_description = { list_paragraph+ } // ------------------------------------------ // Admonitions // ------------------------------------------ admonition_kind = { "TIP" | "NOTE" | "IMPORTANT" | "WARNING" | "CAUTION" } paragraph = { // admonition paragraph (element_attributes? ~ admonition_kind ~ ": " ~ inline_elements+) | (element_attributes? ~ inline_elements+) } // ------------------------------------------ // Paragraphs // ------------------------------------------ // a paragraph is a group of line ending with a blank line (or end of file) // a paragraph cannot start with the `section` sequence (`= `, `== `, etc.) // a paragraph whose first line begins with a word surrounded by spaces simple_paragraph = { element_attributes? ~ !"[literal" ~ first_paragraph_line ~ other_paragraph_line* } paragraph_lines = { first_paragraph_line ~ other_paragraph_line* } first_paragraph_line = @{ !(labeled_list_item_term ~ labeled_list_item_separator) ~ simple_word ~ inline_element* ~ line_break? ~ EOL } other_paragraph_line = { inline_elements } // NOTICE : // original verse_paragraph use ? after element attributes verse_paragraph = { // admonition paragraph ((&"[verse" ~ element_attributes) ~ admonition_kind ~ ": " ~ inline_elements+) | ((&"[verse" ~ element_attributes) ~ inline_elements+) } inline_elements = @{ !(EOI | blank_line | element_attributes) ~ ( single_line_comment | (!block_delimiter ~ inline_element+ ~ line_break? ~ EOL) ) } inline_element = { !(EOL |line_break ) ~ (simple_word | spaces | inline_image | link | passthrough | inline_footnote | inline_user_macro | quoted_text | cross_reference | document_attribute_substitution | inline_element_id | other_word) } // special case for re-parsing a group of elements after a document substitution: // we should treat substitution that did not happen (eg: missing attribute) as regular // strings - (used by the inline element renderer) inline_elements_without_subtitution = { !(blank_line |block_delimiter) ~ inline_element_without_subtitution* ~ line_break? ~ EOL } inline_element_without_subtitution = { !(EOL |line_break ) ~ simple_word | spaces | inline_image | link | passthrough | quoted_text | cross_reference | inline_element_id | other_word } // special case for parsing files to include in delimited blocks with 'verbatim' substitution verbatim_block = { (blank_line | file_inclusion | verbatim_paragraph)* ~ EOI } verbatim_paragraph = { element_attributes? ~ (!EOI ~verbatim_paragraph_line)+ } verbatim_paragraph_line = { !(block_delimiter | blank_line) ~ verbatim_paragraph_line_element* ~ line_break? ~ EOL } verbatim_paragraph_line_element = { ((!EOL |line_break) ~ ANY)+ } // ---------------------------------------------------------------------------- // Explicit line breaks // ---------------------------------------------------------------------------- line_break = { WS ~ "+" ~ WS* ~ &EOL } // ?? // ---------------------------------------------------------------------------- // Quoted Texts (bold, italic and monospace) including substitution prevention // ---------------------------------------------------------------------------- quoted_text = { bold_text | italic_text | monospace_text | subscript_text | superscript_text | escaped_bold_text | escaped_italic_text | escaped_monospace_text | escaped_subscript_text | escaped_superscript_text | subscript_or_superscript_prefix } quoted_text_prefix = { "**" | "*" | "__" | "_" | "``" | "`" | "^" | "~" } subscript_or_superscript_prefix = { "^" | "~" } one_or_more_backslashes = { "\\"+ } two_or_more_backslashes = { "\\\\" ~ "\\"* } // ----------------- // Bold text // ----------------- bold_text = { double_quote_bold_text | single_quote_bold_text } double_quote_bold_text = { !"\\\\" ~ "**" ~ double_quote_bold_text_content ~ "**" } double_quote_bold_text_content = { double_quote_bold_text_element ~ !("**") ~ (WS | double_quote_bold_text_element)* } double_quote_bold_text_element = { !NEWLINE ~ single_quote_bold_text | italic_text | monospace_text | subscript_text | superscript_text | inline_image | link | passthrough | nondouble_quote_bold_text } nondouble_quote_bold_text = { (ANY) ~ (!("**" |WS |"^" |"~" |NEWLINE) ~ ANY)* } single_quote_bold_text = { !("\\" |"**") ~ "*" ~ single_quote_bold_text_content ~ "*" | !"\\\\" ~ "**" ~ single_quote_bold_text_content ~ "*" } single_quote_bold_text_content = { !WS ~ single_quote_bold_text_element ~ (!("*" ~ !ANY) ~ WS* ~ single_quote_bold_text_element)* } single_quote_bold_text_element = { !NEWLINE ~ double_quote_bold_text | italic_text | monospace_text | subscript_text | superscript_text | inline_image | link | passthrough | nonsingle_quote_bold_text } nonsingle_quote_bold_text = { (ANY) ~ (!("*" |WS |"^" |"~" |NEWLINE) ~ ANY)* } escaped_bold_text = { two_or_more_backslashes ~ "**" ~ double_quote_bold_text_content ~ "**" | one_or_more_backslashes ~ "**" ~ single_quote_bold_text_content ~ "*" | one_or_more_backslashes ~ "*" ~ single_quote_bold_text_content ~ "*" } // ----------------- // Italic text // ----------------- italic_text = { double_quote_italic_text | single_quote_italic_text } double_quote_italic_text = { !"\\\\" ~ "__" ~ double_quote_italic_text_content ~ "__" } double_quote_italic_text_content = { double_quote_italic_text_element ~ (!"__" ~ (WS | double_quote_italic_text_element))* } double_quote_italic_text_element = { !NEWLINE ~ single_quote_italic_text | bold_text | monospace_text | subscript_text | superscript_text | inline_image | link | passthrough | nondouble_quote_italic_text } nondouble_quote_italic_text = { (ANY) ~ (!("__" |"^" |"~" |NEWLINE ) ~ ANY)* } single_quote_italic_text = { !("\\" |"__") ~ "_" ~ single_quote_italic_text_content ~ "_" | !"\\" ~ "__" ~ single_quote_italic_text_content ~ "_" } single_quote_italic_text_content = { !WS ~ single_quote_italic_text_element ~ (!("_" ~ !ANY) ~ WS* ~ single_quote_italic_text_element)* } single_quote_italic_text_element = { !NEWLINE ~ double_quote_italic_text | bold_text | monospace_text | subscript_text | superscript_text | inline_image | link | passthrough | nonsingle_quote_italic_text } nonsingle_quote_italic_text = { (ANY) ~ (!("_" |WS |"^" |"~" |NEWLINE) ~ ANY)* } escaped_italic_text = { two_or_more_backslashes ~ "__" ~ double_quote_italic_text_content ~ "__" | one_or_more_backslashes ~ "__" ~ single_quote_italic_text_content ~ "_" | one_or_more_backslashes ~ "_" ~ single_quote_italic_text_content ~ "_" } // ----------------- // Monospace text // ----------------- monospace_text = { double_quote_monospace_text | single_quote_monospace_text } double_quote_monospace_text = { !"\\\\" ~ "``" ~ double_quote_monospace_text_content ~ "``" } double_quote_monospace_text_content = { double_quote_monospace_text_element ~ (!("``") ~ (WS | double_quote_monospace_text_element))* } double_quote_monospace_text_element = { !NEWLINE ~ single_quote_monospace_text | bold_text | italic_text | subscript_text | superscript_text | inline_image | link | passthrough | nondouble_quote_monospace_text } nondouble_quote_monospace_text = { (ANY) ~ (!("``" |WS |"^" |"~" |NEWLINE) ~ ANY)* } single_quote_monospace_text = { !("\\" |"``") ~ "`" ~ single_quote_monospace_text_content ~ "`" | !"\\\\" ~ "``" ~ single_quote_monospace_text_content ~ "`" } single_quote_monospace_text_content = { !WS ~ single_quote_monospace_text_element ~ (!("`" ~ !ANY) ~ WS* ~ single_quote_monospace_text_element)* } single_quote_monospace_text_element = { NEWLINE // allows multiline | double_quote_monospace_text | bold_text | italic_text | subscript_text | superscript_text | inline_image | link | passthrough | nonsingle_quote_monospace_text } nonsingle_quote_monospace_text = { (ANY) ~ (!(WS |"`" |"^" |"~" |NEWLINE) ~ ANY)* } escaped_monospace_text = { two_or_more_backslashes ~ "``" ~ double_quote_monospace_text_content ~ "``" | one_or_more_backslashes ~ "``" ~ single_quote_monospace_text_content ~ "`" | one_or_more_backslashes ~ "`" ~ single_quote_monospace_text_content ~ "`" } subscript_text = { !"\\" ~ "~" ~ subscript_text_element ~ "~" } subscript_text_element = { quoted_text | nonsubscript_text } nonsubscript_text = { (!(NEWLINE |WS |"~" ) ~ ANY)+ } escaped_subscript_text = { one_or_more_backslashes ~ "~" ~ subscript_text_element ~ "~" } superscript_text = { !"\\" ~ "^" ~ superscript_text_element ~ "^" } superscript_text_element = { quoted_text | nonsuperscript_text } nonsuperscript_text = { (!(NEWLINE |WS |"^") ~ ANY)+ } escaped_superscript_text = { one_or_more_backslashes ~ "^" ~ superscript_text_element ~ "^" } // ------------------------------------------ // Passthrough // ------------------------------------------ passthrough = { triple_plus_passthrough | single_plus_passthrough | passthrough_macro } single_plus_passthrough_prefix = { "+" } single_plus_passthrough = { single_plus_passthrough_prefix ~ single_plus_passthrough_content ~ single_plus_passthrough_prefix ~ !ANY } single_plus_passthrough_content = { !(single_plus_passthrough_prefix | WS | NEWLINE) ~ ANY ~ (!(WS+ ~ single_plus_passthrough_prefix) ~ !(single_plus_passthrough_prefix |NEWLINE) ~ ANY)* | !(WS | NEWLINE | single_plus_passthrough_prefix) ~ ANY } triple_plus_passthrough_prefix = { "+++" } triple_plus_passthrough = { triple_plus_passthrough_prefix ~ triple_plus_passthrough_content ~ triple_plus_passthrough_prefix ~ !ANY } triple_plus_passthrough_content = { // spaces and newlines are also allowed in the first or last position of the content and elsewhere too (!triple_plus_passthrough_prefix ~ ANY)+ // 这里原本是 *,但是理论上和下面规则有相容关系 | (!(WS |NEWLINE |triple_plus_passthrough_prefix) ~ ANY)? } passthrough_macro = { "pass:[" ~ passthrough_macro_character* ~ "]" | "pass:q[" ~ (quoted_text | passthrough_macro_character*) ~ "]" } passthrough_macro_character = { ASCII_ALPHANUMERIC+ | spaces | (!"]" ~ ANY) } // ------------------------------------------ // Cross References // ------------------------------------------ cross_reference = { "<<" ~ ID ~ WS* ~ "," ~ cross_reference_label ~ ">>" | "<<" ~ ID ~ ">>" } cross_reference_label = { (ASCII_ALPHANUMERIC+ | spaces | (!">>" ~ ANY))+ } // ------------------------------------------ // Links // ------------------------------------------ link = { relative_link | external_link } // url preceeding with `link:` MUST be followed by square brackets relative_link = { "link:" ~ (location | file_location) ~ link_attributes } external_link = { location ~ link_attributes? } link_attributes = { "[" ~ (link_text_attribute)? ~ ","? ~ WS* ~ generic_attribute* ~ "]" } link_text_attribute = { ( !("=" |"," |"]") ~ (quoted_text | simple_word | spaces | (!quoted_text_prefix ~ ANY)) )+ ~ &(!"=") } // ------------------------------------------ // Images // ------------------------------------------ image_block = { element_attributes? ~ "image::" ~ URL ~ image_attributes ~ EOLS } inline_image = { "image:" ~ !":" ~ URL ~ image_attributes } image_attributes = { "[" ~ attribute_value? ~ ","? ~ attribute_value? ~ ","? ~ attribute_value? ~ ","? ~ WS* ~ generic_attribute* ~ "]" } // ------------------------------------------------------------------------------------ // Inline foot notes // ------------------------------------------------------------------------------------ inline_footnote = { "footnote:[" ~ footnote_content ~ "]" | "footnoteref:[" ~ footnote_ref ~ "," ~ footnote_content ~ "]" | "footnoteref:[" ~ footnote_ref ~ "]" } footnote_ref = { (ASCII_ALPHANUMERIC+ | spaces | (!("," |"]" |EOL) ~ ANY))* } footnote_content = { (!("]" | EOL) ~ WS* ~ !inline_element_id ~ inline_element ~ WS*)+ } // ------------------------------------------------------------------------------------ // delimited_blocks // ------------------------------------------------------------------------------------ delimited_block = { fenced_block | listing_block | example_block | verse_block | quote_block | sidebar_block | table | comment_block | single_line_comment } block_delimiter = { literal_block_delimiter | fenced_block_delimiter | listing_block_delimiter | example_block_delimiter | comment_block_delimiter | quote_block_delimiter | sidebar_block_delimiter } // ------------------------------------------------------------------------------------- // fenced _blocks // ------------------------------------------------------------------------------------- fenced_block_delimiter = { "```" ~ EOLS } fenced_block = { element_attributes? ~ fenced_block_delimiter ~ fenced_block_content* ~ (fenced_block_delimiter | EOI) } fenced_block_content = { blank_line | file_inclusion | list_item | fenced_block_paragraph } // blocks content fenced_block_paragraph = { fenced_block_paragraph_line+ } fenced_block_paragraph_line = { !(fenced_block_delimiter |blank_line) ~ inline_elements } // ------------------------------------------------------------------------------------- // listing blocks // ------------------------------------------------------------------------------------- listing_block_delimiter = { "----" ~ EOLS } // listing block: verbatim content listing_block = { element_attributes? ~ listing_block_delimiter ~ listing_block_element* ~ (listing_block_delimiter | EOI) } listing_block_element = { file_inclusion | listing_block_paragraph } listing_block_paragraph = { listing_block_paragraph_line+ } listing_block_paragraph_line = @{ !listing_block_delimiter ~ (!EOI ~ WS* ~ (ASCII_ALPHANUMERIC+ | spaces | (!EOL ~ ANY))*) ~ EOL } // ------------------------------------------------------------------------------------- // Example blocks // ------------------------------------------------------------------------------------- example_block_delimiter = { "====" ~ EOLS } example_block = { element_attributes? ~ example_block_delimiter ~ (blank_line | file_inclusion | list_item | example_block_paragraph)* ~ (example_block_delimiter | EOI) } // blocks content example_block_paragraph = { example_block_paragraph_line+ } example_block_paragraph_line = { !(example_block_delimiter |blank_line ) ~ inline_elements } // ------------------------------------------------------------------------------------- // Quote blocks // ------------------------------------------------------------------------------------- quote_block_delimiter = { "____" ~ EOLS }// same for verse blocks quote_block = { element_attributes? ~ quote_block_delimiter ~ quote_block_element* ~ (quote_block_delimiter | EOI) } quote_block_element = { !(quote_block_delimiter | EOI) // 这里该用啥来表达啊 ~ ( blank_line | file_inclusion | image_block | list_item | fenced_block | listing_block | example_block | comment_block | single_line_comment | quote_block | sidebar_block | table | literal_block | document_attribute_declaration | document_attribute_reset | table_of_contents_macro | quote_block_paragraph ) } quote_block_paragraph = { inline_elements+ } // ------------------------------------------------------------------------------------- // verse blocks // ------------------------------------------------------------------------------------- // verse_block_delimiter: see Quote_block_delimiter verse_block = { &"[verse" ~ element_attributes ~ quote_block_delimiter ~ verse_block_element* ~ (quote_block_delimiter | EOI) } verse_block_element = { verse_file_include | blank_line | verse_block_paragraph } verse_file_include = { !quote_block_delimiter ~ file_inclusion } // blocks content verse_block_paragraph = { verse_block_paragraph_line+ } verse_block_paragraph_line = { !(quote_block_delimiter | blank_line) ~ verse_block_paragraph_line_element+ ~ EOL } verse_block_paragraph_line_element = { !(EOL |line_break) ~ ( spaces | inline_image | link | passthrough | inline_footnote | inline_user_macro | quoted_text | cross_reference | document_attribute_substitution | inline_element_id | other_word ) } // ------------------------------------------------------------------------------------- // Sidebars // ------------------------------------------------------------------------------------- sidebar_block_delimiter = { "****" ~ EOLS } sidebar_block = { element_attributes? ~ sidebar_block_delimiter ~ sidebar_block_content* ~ (sidebar_block_delimiter | EOI) } sidebar_block_content = { blank_line | file_inclusion | list_item | non_sidebar_block | sidebar_block_paragraph } non_sidebar_block = { !sidebar_block ~ delimited_block } // blocks content sidebar_block_paragraph = { sidebar_block_paragraph_line+ } sidebar_block_paragraph_line = { !( sidebar_block_delimiter | blank_line ) ~ inline_elements } // ------------------------------------------------------------------------------------- // tables // ------------------------------------------------------------------------------------- table = { element_attributes? ~ table_delimiter ~ table_line_header? ~ table_line* ~ (table_delimiter | EOI) } table_cell_separator = _{ "|" ~ WS* } table_delimiter = _{ "|==="~ "="* ~ EOLS } // table line header is a line followed by a blankline table_line_header = { !table_delimiter ~ table_cell+ ~ EOL ~ blank_line } table_line = { !table_delimiter ~ table_cell+ ~ EOL ~ blank_line* } table_cell = { table_cell_separator ~ (!(table_cell_separator | EOL) ~ WS* ~ inline_element ~ WS*)+ } // ------------------------------------------------------------------------------------- // Comments // ------------------------------------------------------------------------------------- comment_block_delimiter = { "////" } comment_block = { comment_block_delimiter ~ WS* ~ NEWLINE ~ comment_block_line* ~ ((comment_block_delimiter ~ EOLS) | EOI) } comment_block_line = { (ASCII_ALPHANUMERIC+ | spaces | (!(comment_block_delimiter | EOL) ~ ANY))* ~ EOL } single_line_comment = { WS* ~ "//" ~ single_line_comment_content ~ EOL } single_line_comment_content = { (ASCII_ALPHANUMERIC+ | spaces | (!EOL ~ ANY))* } // ------------------------------------------------------------------------------------- // Literal_blocks (see http://asciidoctor.org/docs/user-manual/#literal-text-and-blocks) // ------------------------------------------------------------------------------------- literal_block = { paragraph_with_literal_attribute | paragraph_with_headingspaces | paragraph_with_literal_block_delimiter } literal_block_delimiter = { "...." ~ EOLS} // paragraph indented with one or more spaces on the first line paragraph_with_headingspaces = { element_attributes? ~ paragraph_with_headingspaces_lines } // first line MUST start with one (or more) space. Stop when reaching a blank line paragraph_with_headingspaces_lines = { (WS ~ (ASCII_ALPHANUMERIC+ | spaces | (!EOL ~ ASCII_ALPHANUMERIC))+ ) ~ EOL // do not include the trailing 'EOL' on the first line ~ (!blank_line ~ (ASCII_ALPHANUMERIC+ | spaces | (!EOL ~ ANY))+ ~ EOL)* } // paragraph with the literal block delimiter (`....`) paragraph_with_literal_block_delimiter = { element_attributes? ~ literal_block_delimiter ~ WS* ~ NEWLINE ~ paragraph_with_literal_block_delimiter_lines ~ ((literal_block_delimiter ~ EOLS) | EOI) } // include all lines until delimiter is reached paragraph_with_literal_block_delimiter_lines = { paragraph_with_literal_block_delimiter_line* } paragraph_with_literal_block_delimiter_line = { (ASCII_ALPHANUMERIC+ | spaces | (!(literal_block_delimiter | EOL) ~ ANY))* ~ EOL } // paragraph with the literal attribute (`[literal]`) paragraph_with_literal_attribute = { (&"[literal" ~ element_attributes) ~ paragraph_with_literal_attribute_lines } // include all lines until blankline paragraph_with_literal_attribute_lines = { paragraph_with_literal_attribute_line+ } paragraph_with_literal_attribute_line = { !blank_line ~ (ASCII_ALPHANUMERIC+ | spaces | (!EOL ~ ANY))+ ~ EOL } // ------------------------------------------ // blank_line // ------------------------------------------ blank_line = { !EOI ~ EOLS } // ------------------------------------------ // Base Types // ------------------------------------------ parenthesis = { "(" | ")" | "[" | "]" } dot = { "." } simple_word = { ASCII_ALPHANUMERIC+ ~ &(WS | EOL) } // a word may end with a dot, but cannot have dots within other_word = { ASCII_ALPHANUMERIC+ | quoted_text_prefix | parenthesis | (!(NEWLINE |WS |dot |quoted_text_prefix | "=") ~ ANY ~ dot?)+ | "."+ } // spaces will not be eate spaces = { (" " | "\t")+ } file_location = { (FILENAME | document_attribute_substitution)+ } location = { URL_SCHEME ~ (FILENAME | document_attribute_substitution | !(EOL |"[") ~ ANY)+ } FILENAME = { (ASCII_ALPHANUMERIC+ | "." | "_" | "/" | "-" )+ } URL = {(ASCII_ALPHANUMERIC+ | (!(NEWLINE |WS |"[" |"]") ~ ANY))+ } URL_SCHEME = { "http://" | "https://" | "ftp://" | "irc://" | "mailto:" } ID = { ASCII_ALPHANUMERIC+ | (!(NEWLINE |WS |"[" |"]" |"<<" |">>" |",") ~ ANY)+ } WS = _{ " " | "\t" } EOL = _{ NEWLINE | EOI } EOLS = _{ WS* ~ EOL } /*ANY = { !("\"" | "\\") ~ ANY | "\\" ~ ("\"" | "\\" | "/" | "b" | "f" | "n" | "r" | "t") | "\\" ~ ("u" ~ ASCII_HEX_DIGIT{4}) } */ //ANY = { ASCII_ALPHANUMERIC | LETTER } CHAR = { ANY } NEWLINE = _{ "\r\n" | "\r" | "\n"} ```