diff --git a/parser/src/blocks/is_block.rs b/parser/src/blocks/is_block.rs index 9f64949a..bb399b86 100644 --- a/parser/src/blocks/is_block.rs +++ b/parser/src/blocks/is_block.rs @@ -36,6 +36,23 @@ pub trait IsBlock<'src>: HasSpan<'src> + Clone + Debug + Eq + PartialEq { /// built-in context. That transformation is not performed by this function. fn raw_context(&self) -> CowStr<'src>; + /// Returns the declared (uninterpreted) style for this block. + /// + /// Above some blocks, you may notice a name at the start of the block + /// attribute list (e.g., `[source]` or `[verse]`). The first positional + /// (unnamed) attribute in the block attribute list is used to declare the + /// block style. + /// + /// The declared block style is the value the author supplies. + /// + /// That value is then interpreted and resolved. That interpretation is not + /// performed by this function. + fn declared_style(&'src self) -> Option> { + self.attrlist() + .and_then(|attrlist| attrlist.nth_attribute(1)) + .and_then(|attr| attr.block_style()) + } + /// Returns an iterator over the nested blocks contained within /// this block. /// diff --git a/parser/src/tests/asciidoc_lang/blocks/index.rs b/parser/src/tests/asciidoc_lang/blocks/index.rs index e9572e63..93785b42 100644 --- a/parser/src/tests/asciidoc_lang/blocks/index.rs +++ b/parser/src/tests/asciidoc_lang/blocks/index.rs @@ -103,6 +103,7 @@ You can think of the context as the block's type. .unwrap(); assert_eq!(mi.item.raw_context().deref(), "section"); + assert!(mi.item.declared_style().is_none()); } #[test] @@ -309,8 +310,8 @@ In the converter, these blocks must be accessed from their parent block. mod block_style { use crate::{ - blocks::{Block, IsBlock}, - tests::sdd::{non_normative, to_do_verifies}, + blocks::{Block, ContentModel, IsBlock}, + tests::{fixtures::TSpan, sdd::{non_normative, verifies}}, Span, }; @@ -335,9 +336,8 @@ The resolved block style, if non-empty, specializes the block's context. ); #[test] - #[ignore] fn source_block() { - to_do_verifies!( + verifies!( r#" Consider the following example of a source block: @@ -364,8 +364,16 @@ The context of the block is still the same, but it has additional metadata to in .unwrap(); assert_eq!(mi.item.raw_context().as_ref(), "listing"); - // assert_eq!(mi.item.style(), "source"); - // assert_eq!(mi.item.content_model(), ContentModel::Verbatim); + + assert_eq!(mi.item.declared_style().unwrap(), + TSpan { + data: "source", + line: 1, + col: 2, + offset: 1, + }); + + assert_eq!(mi.item.content_model(), ContentModel::Verbatim); } // TO DO: Cover the remainder ... diff --git a/parser/src/tests/blocks/block/compound_delimited.rs b/parser/src/tests/blocks/block/compound_delimited.rs index 2fb07074..ad28e4d3 100644 --- a/parser/src/tests/blocks/block/compound_delimited.rs +++ b/parser/src/tests/blocks/block/compound_delimited.rs @@ -206,6 +206,7 @@ mod example { assert_eq!(mi.item.content_model(), ContentModel::Compound); assert_eq!(mi.item.raw_context().as_ref(), "example"); + assert!(mi.item.declared_style().is_none()); assert!(mi.item.nested_blocks().next().is_none()); assert!(mi.item.title().is_none()); assert!(mi.item.attrlist().is_none()); diff --git a/parser/src/tests/blocks/block/mod.rs b/parser/src/tests/blocks/block/mod.rs index f7fbc88f..ba5f2a55 100644 --- a/parser/src/tests/blocks/block/mod.rs +++ b/parser/src/tests/blocks/block/mod.rs @@ -44,6 +44,7 @@ mod error_cases { assert_eq!(mi.item.content_model(), ContentModel::Compound); assert_eq!(mi.item.raw_context().deref(), "section"); + assert!(mi.item.declared_style().is_none()); assert!(mi.item.title().is_none()); assert!(mi.item.attrlist().is_none()); @@ -153,6 +154,7 @@ mod error_cases { assert_eq!(mi.item.content_model(), ContentModel::Simple); assert_eq!(mi.item.raw_context().deref(), "paragraph"); + assert!(mi.item.declared_style().is_none()); assert!(mi.item.title().is_none()); assert!(mi.item.attrlist().is_none()); @@ -215,6 +217,7 @@ mod error_cases { assert_eq!(mi.item.content_model(), ContentModel::Compound); assert_eq!(mi.item.raw_context().deref(), "section"); + assert!(mi.item.declared_style().is_none()); assert!(mi.item.title().is_none()); assert_eq!( diff --git a/parser/src/tests/blocks/block/raw_delimited.rs b/parser/src/tests/blocks/block/raw_delimited.rs index 7d6c4f00..7e5c609f 100644 --- a/parser/src/tests/blocks/block/raw_delimited.rs +++ b/parser/src/tests/blocks/block/raw_delimited.rs @@ -210,6 +210,7 @@ mod comment { assert_eq!(mi.item.content_model(), ContentModel::Raw); assert_eq!(mi.item.raw_context().as_ref(), "comment"); + assert!(mi.item.declared_style().is_none()); assert!(mi.item.title().is_none()); assert!(mi.item.attrlist().is_none()); } @@ -257,6 +258,7 @@ mod comment { assert_eq!(mi.item.content_model(), ContentModel::Raw); assert_eq!(mi.item.raw_context().as_ref(), "comment"); + assert!(mi.item.declared_style().is_none()); assert_eq!( mi.item.title().unwrap(), @@ -309,6 +311,7 @@ mod comment { assert_eq!(mi.item.content_model(), ContentModel::Raw); assert_eq!(mi.item.raw_context().as_ref(), "comment"); + assert!(mi.item.declared_style().is_none()); assert!(mi.item.title().is_none()); assert!(mi.item.attrlist().is_none()); } @@ -357,6 +360,7 @@ mod comment { assert_eq!(mi.item.content_model(), ContentModel::Raw); assert_eq!(mi.item.raw_context().as_ref(), "comment"); + assert!(mi.item.declared_style().is_none()); assert!(mi.item.title().is_none()); assert!(mi.item.attrlist().is_none()); } @@ -400,6 +404,7 @@ mod listing { assert_eq!(mi.item.content_model(), ContentModel::Verbatim); assert_eq!(mi.item.raw_context().as_ref(), "listing"); + assert!(mi.item.declared_style().is_none()); assert!(mi.item.title().is_none()); assert!(mi.item.attrlist().is_none()); } @@ -442,6 +447,7 @@ mod listing { assert_eq!(mi.item.content_model(), ContentModel::Verbatim); assert_eq!(mi.item.raw_context().as_ref(), "listing"); + assert!(mi.item.declared_style().is_none()); assert_eq!(mi.item.nested_blocks().next(), None); assert!(mi.item.title().is_none()); assert!(mi.item.attrlist().is_none()); @@ -500,6 +506,7 @@ mod listing { assert_eq!(mi.item.content_model(), ContentModel::Verbatim); assert_eq!(mi.item.raw_context().as_ref(), "listing"); + assert!(mi.item.declared_style().is_none()); assert_eq!(mi.item.nested_blocks().next(), None); assert_eq!( @@ -569,6 +576,7 @@ mod listing { assert_eq!(mi.item.content_model(), ContentModel::Verbatim); assert_eq!(mi.item.raw_context().as_ref(), "listing"); + assert!(mi.item.declared_style().is_none()); assert_eq!(mi.item.nested_blocks().next(), None); assert!(mi.item.title().is_none()); assert!(mi.item.attrlist().is_none()); @@ -623,6 +631,7 @@ mod pass { assert_eq!(mi.item.content_model(), ContentModel::Raw); assert_eq!(mi.item.raw_context().as_ref(), "pass"); + assert!(mi.item.declared_style().is_none()); assert_eq!(mi.item.nested_blocks().next(), None); assert!(mi.item.title().is_none()); assert!(mi.item.attrlist().is_none()); @@ -676,6 +685,7 @@ mod pass { assert_eq!(mi.item.content_model(), ContentModel::Raw); assert_eq!(mi.item.raw_context().as_ref(), "pass"); + assert!(mi.item.declared_style().is_none()); assert_eq!(mi.item.nested_blocks().next(), None); assert!(mi.item.title().is_none()); assert!(mi.item.attrlist().is_none()); @@ -734,6 +744,7 @@ mod pass { assert_eq!(mi.item.content_model(), ContentModel::Raw); assert_eq!(mi.item.raw_context().as_ref(), "pass"); + assert!(mi.item.declared_style().is_none()); assert_eq!(mi.item.nested_blocks().next(), None); assert_eq!( @@ -803,6 +814,7 @@ mod pass { assert_eq!(mi.item.content_model(), ContentModel::Raw); assert_eq!(mi.item.raw_context().as_ref(), "pass"); + assert!(mi.item.declared_style().is_none()); assert_eq!(mi.item.nested_blocks().next(), None); assert!(mi.item.title().is_none()); assert!(mi.item.attrlist().is_none()); diff --git a/parser/src/tests/blocks/block/section.rs b/parser/src/tests/blocks/block/section.rs index 16060406..e26958f3 100644 --- a/parser/src/tests/blocks/block/section.rs +++ b/parser/src/tests/blocks/block/section.rs @@ -70,6 +70,7 @@ fn simplest_section_block() { assert_eq!(mi.item.content_model(), ContentModel::Compound); assert_eq!(mi.item.raw_context().deref(), "section"); + assert!(mi.item.declared_style().is_none()); assert!(mi.item.title().is_none()); assert!(mi.item.attrlist().is_none()); @@ -116,6 +117,7 @@ fn has_child_block() { assert_eq!(mi.item.content_model(), ContentModel::Compound); assert_eq!(mi.item.raw_context().deref(), "section"); + assert!(mi.item.declared_style().is_none()); assert!(mi.item.title().is_none()); assert!(mi.item.attrlist().is_none()); @@ -209,6 +211,7 @@ fn title() { assert_eq!(mi.item.content_model(), ContentModel::Compound); assert_eq!(mi.item.raw_context().deref(), "section"); + assert!(mi.item.declared_style().is_none()); assert_eq!( mi.item, diff --git a/parser/src/tests/blocks/block/simple.rs b/parser/src/tests/blocks/block/simple.rs index 5c582e1a..299f1ca2 100644 --- a/parser/src/tests/blocks/block/simple.rs +++ b/parser/src/tests/blocks/block/simple.rs @@ -76,6 +76,7 @@ fn single_line() { assert_eq!(mi.item.content_model(), ContentModel::Simple); assert_eq!(mi.item.raw_context().deref(), "paragraph"); + assert!(mi.item.declared_style().is_none()); assert_eq!(mi.item.nested_blocks().next(), None); assert!(mi.item.title().is_none()); assert!(mi.item.attrlist().is_none()); diff --git a/parser/src/tests/blocks/compound_delimited.rs b/parser/src/tests/blocks/compound_delimited.rs index 91f0fa34..47eaafa1 100644 --- a/parser/src/tests/blocks/compound_delimited.rs +++ b/parser/src/tests/blocks/compound_delimited.rs @@ -253,6 +253,7 @@ mod example { assert_eq!(mi.item.content_model(), ContentModel::Compound); assert_eq!(mi.item.raw_context().as_ref(), "example"); + assert!(mi.item.declared_style().is_none()); assert!(mi.item.nested_blocks().next().is_none()); assert!(mi.item.title().is_none()); assert!(mi.item.attrlist().is_none()); @@ -316,6 +317,7 @@ mod example { assert_eq!(mi.item.content_model(), ContentModel::Compound); assert_eq!(mi.item.raw_context().as_ref(), "example"); + assert!(mi.item.declared_style().is_none()); assert!(mi.item.title().is_none()); assert!(mi.item.attrlist().is_none()); @@ -434,6 +436,7 @@ mod example { assert_eq!(mi.item.content_model(), ContentModel::Compound); assert_eq!(mi.item.raw_context().as_ref(), "example"); + assert!(mi.item.declared_style().is_none()); assert!(mi.item.title().is_none()); assert!(mi.item.attrlist().is_none()); @@ -561,6 +564,7 @@ mod open { assert_eq!(mi.item.content_model(), ContentModel::Compound); assert_eq!(mi.item.raw_context().as_ref(), "open"); + assert!(mi.item.declared_style().is_none()); assert!(mi.item.nested_blocks().next().is_none()); assert!(mi.item.title().is_none()); assert!(mi.item.attrlist().is_none()); @@ -624,6 +628,7 @@ mod open { assert_eq!(mi.item.content_model(), ContentModel::Compound); assert_eq!(mi.item.raw_context().as_ref(), "open"); + assert!(mi.item.declared_style().is_none()); assert!(mi.item.title().is_none()); assert!(mi.item.attrlist().is_none()); @@ -753,6 +758,7 @@ mod open { assert_eq!(mi.item.content_model(), ContentModel::Compound); assert_eq!(mi.item.raw_context().as_ref(), "open"); + assert!(mi.item.declared_style().is_none()); assert!(mi.item.title().is_none()); assert!(mi.item.attrlist().is_none()); @@ -859,6 +865,7 @@ mod sidebar { assert_eq!(mi.item.content_model(), ContentModel::Compound); assert_eq!(mi.item.raw_context().as_ref(), "sidebar"); + assert!(mi.item.declared_style().is_none()); assert!(mi.item.nested_blocks().next().is_none()); assert!(mi.item.title().is_none()); assert!(mi.item.attrlist().is_none()); @@ -922,6 +929,7 @@ mod sidebar { assert_eq!(mi.item.content_model(), ContentModel::Compound); assert_eq!(mi.item.raw_context().as_ref(), "sidebar"); + assert!(mi.item.declared_style().is_none()); assert!(mi.item.title().is_none()); assert!(mi.item.attrlist().is_none()); @@ -1040,6 +1048,7 @@ mod sidebar { assert_eq!(mi.item.content_model(), ContentModel::Compound); assert_eq!(mi.item.raw_context().as_ref(), "sidebar"); + assert!(mi.item.declared_style().is_none()); assert!(mi.item.title().is_none()); assert!(mi.item.attrlist().is_none()); @@ -1179,6 +1188,7 @@ mod quote { assert_eq!(mi.item.content_model(), ContentModel::Compound); assert_eq!(mi.item.raw_context().as_ref(), "quote"); + assert!(mi.item.declared_style().is_none()); assert!(mi.item.nested_blocks().next().is_none()); assert!(mi.item.title().is_none()); assert!(mi.item.attrlist().is_none()); @@ -1242,6 +1252,7 @@ mod quote { assert_eq!(mi.item.content_model(), ContentModel::Compound); assert_eq!(mi.item.raw_context().as_ref(), "quote"); + assert!(mi.item.declared_style().is_none()); assert!(mi.item.title().is_none()); assert!(mi.item.attrlist().is_none()); @@ -1360,6 +1371,7 @@ mod quote { assert_eq!(mi.item.content_model(), ContentModel::Compound); assert_eq!(mi.item.raw_context().as_ref(), "quote"); + assert!(mi.item.declared_style().is_none()); assert!(mi.item.title().is_none()); assert!(mi.item.attrlist().is_none()); diff --git a/parser/src/tests/blocks/macro.rs b/parser/src/tests/blocks/macro.rs index 4c066c04..97b0c82e 100644 --- a/parser/src/tests/blocks/macro.rs +++ b/parser/src/tests/blocks/macro.rs @@ -128,6 +128,7 @@ fn simplest_block_macro() { assert_eq!(mi.item.content_model(), ContentModel::Simple); assert_eq!(mi.item.raw_context().deref(), "paragraph"); + assert!(mi.item.declared_style().is_none()); assert!(mi.item.title().is_none()); assert!(mi.item.attrlist().is_none()); diff --git a/parser/src/tests/blocks/raw_delimited.rs b/parser/src/tests/blocks/raw_delimited.rs index 56364038..f6121fab 100644 --- a/parser/src/tests/blocks/raw_delimited.rs +++ b/parser/src/tests/blocks/raw_delimited.rs @@ -168,6 +168,7 @@ mod comment { assert_eq!(mi.item.content_model(), ContentModel::Raw); assert_eq!(mi.item.raw_context().as_ref(), "comment"); + assert!(mi.item.declared_style().is_none()); assert!(mi.item.lines().next().is_none()); assert!(mi.item.title().is_none()); assert!(mi.item.attrlist().is_none()); @@ -211,6 +212,7 @@ mod comment { assert_eq!(mi.item.content_model(), ContentModel::Raw); assert_eq!(mi.item.raw_context().as_ref(), "comment"); + assert!(mi.item.declared_style().is_none()); assert!(mi.item.title().is_none()); assert!(mi.item.attrlist().is_none()); @@ -283,6 +285,7 @@ mod comment { assert_eq!(mi.item.content_model(), ContentModel::Raw); assert_eq!(mi.item.raw_context().as_ref(), "comment"); + assert!(mi.item.declared_style().is_none()); assert!(mi.item.title().is_none()); assert!(mi.item.attrlist().is_none()); @@ -368,6 +371,7 @@ mod listing { assert_eq!(mi.item.content_model(), ContentModel::Verbatim); assert_eq!(mi.item.raw_context().as_ref(), "listing"); + assert!(mi.item.declared_style().is_none()); assert!(mi.item.lines().next().is_none()); assert!(mi.item.title().is_none()); assert!(mi.item.attrlist().is_none()); @@ -411,6 +415,7 @@ mod listing { assert_eq!(mi.item.content_model(), ContentModel::Verbatim); assert_eq!(mi.item.raw_context().as_ref(), "listing"); + assert!(mi.item.declared_style().is_none()); assert!(mi.item.title().is_none()); assert!(mi.item.attrlist().is_none()); @@ -483,6 +488,7 @@ mod listing { assert_eq!(mi.item.content_model(), ContentModel::Verbatim); assert_eq!(mi.item.raw_context().as_ref(), "listing"); + assert!(mi.item.declared_style().is_none()); assert!(mi.item.title().is_none()); assert!(mi.item.attrlist().is_none()); @@ -588,6 +594,7 @@ mod pass { assert_eq!(mi.item.content_model(), ContentModel::Raw); assert_eq!(mi.item.raw_context().as_ref(), "pass"); + assert!(mi.item.declared_style().is_none()); assert!(mi.item.lines().next().is_none()); assert!(mi.item.title().is_none()); assert!(mi.item.attrlist().is_none()); @@ -631,6 +638,7 @@ mod pass { assert_eq!(mi.item.content_model(), ContentModel::Raw); assert_eq!(mi.item.raw_context().as_ref(), "pass"); + assert!(mi.item.declared_style().is_none()); assert!(mi.item.title().is_none()); assert!(mi.item.attrlist().is_none()); @@ -703,6 +711,7 @@ mod pass { assert_eq!(mi.item.content_model(), ContentModel::Raw); assert_eq!(mi.item.raw_context().as_ref(), "pass"); + assert!(mi.item.declared_style().is_none()); assert!(mi.item.title().is_none()); assert!(mi.item.attrlist().is_none()); diff --git a/parser/src/tests/blocks/section.rs b/parser/src/tests/blocks/section.rs index 74df81b0..a3381ea4 100644 --- a/parser/src/tests/blocks/section.rs +++ b/parser/src/tests/blocks/section.rs @@ -50,6 +50,7 @@ fn simplest_section_block() { assert_eq!(mi.item.content_model(), ContentModel::Compound); assert_eq!(mi.item.raw_context().deref(), "section"); + assert!(mi.item.declared_style().is_none()); assert!(mi.item.title().is_none()); assert!(mi.item.attrlist().is_none()); @@ -94,6 +95,7 @@ fn has_child_block() { assert_eq!(mi.item.content_model(), ContentModel::Compound); assert_eq!(mi.item.raw_context().deref(), "section"); + assert!(mi.item.declared_style().is_none()); assert!(mi.item.title().is_none()); assert!(mi.item.attrlist().is_none()); @@ -155,6 +157,7 @@ fn has_macro_block_with_extra_blank_line() { assert_eq!(mi.item.content_model(), ContentModel::Compound); assert_eq!(mi.item.raw_context().deref(), "section"); + assert!(mi.item.declared_style().is_none()); assert!(mi.item.title().is_none()); assert!(mi.item.attrlist().is_none()); @@ -296,6 +299,7 @@ fn has_child_block_with_errors() { assert_eq!(mi.item.content_model(), ContentModel::Compound); assert_eq!(mi.item.raw_context().deref(), "section"); + assert!(mi.item.declared_style().is_none()); assert!(mi.item.title().is_none()); assert!(mi.item.attrlist().is_none()); @@ -449,6 +453,7 @@ fn dont_stop_at_child_section() { assert_eq!(mi.item.content_model(), ContentModel::Compound); assert_eq!(mi.item.raw_context().deref(), "section"); + assert!(mi.item.declared_style().is_none()); assert!(mi.item.title().is_none()); assert!(mi.item.attrlist().is_none()); @@ -545,6 +550,7 @@ fn stop_at_peer_section() { assert_eq!(mi.item.content_model(), ContentModel::Compound); assert_eq!(mi.item.raw_context().deref(), "section"); + assert!(mi.item.declared_style().is_none()); assert!(mi.item.title().is_none()); assert!(mi.item.attrlist().is_none()); @@ -607,6 +613,7 @@ fn stop_at_ancestor_section() { assert_eq!(mi.item.content_model(), ContentModel::Compound); assert_eq!(mi.item.raw_context().deref(), "section"); + assert!(mi.item.declared_style().is_none()); assert!(mi.item.title().is_none()); assert!(mi.item.attrlist().is_none()); diff --git a/parser/src/tests/blocks/simple.rs b/parser/src/tests/blocks/simple.rs index 2efd7c8e..8f14a3d2 100644 --- a/parser/src/tests/blocks/simple.rs +++ b/parser/src/tests/blocks/simple.rs @@ -51,6 +51,7 @@ fn single_line() { assert_eq!(mi.item.content_model(), ContentModel::Simple); assert_eq!(mi.item.raw_context().deref(), "paragraph"); + assert!(mi.item.declared_style().is_none()); assert!(mi.item.title().is_none()); assert!(mi.item.attrlist().is_none()); diff --git a/parser/src/tests/document/document.rs b/parser/src/tests/document/document.rs index 4cc94c6d..fb66f63b 100644 --- a/parser/src/tests/document/document.rs +++ b/parser/src/tests/document/document.rs @@ -30,6 +30,7 @@ fn empty_source() { assert_eq!(doc.content_model(), ContentModel::Compound); assert_eq!(doc.raw_context().deref(), "document"); + assert!(doc.declared_style().is_none()); assert!(doc.title().is_none()); assert!(doc.attrlist().is_none());