asciidoc_parser/blocks/is_block.rs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73
use std::{fmt::Debug, slice::Iter};
use crate::{blocks::Block, strings::CowStr, HasSpan};
/// Block elements form the main structure of an AsciiDoc document, starting
/// with the document itself.
///
/// A block element (aka block) is a discrete, line-oriented chunk of content in
/// an AsciiDoc document. Once parsed, that chunk of content becomes a block
/// element in the parsed document model. Certain blocks may contain other
/// blocks, so we say that blocks can be nested. The converter visits each block
/// in turn, in document order, converting it to a corresponding chunk of
/// output.
///
/// This trait implements many of the same core methods as the
/// [Block](crate::blocks::Block) enum but provides a mechanism for third-party
/// code to extend the behavior of blocks.
pub trait IsBlock<'src>: HasSpan<'src> + Clone + Debug + Eq + PartialEq {
/// Returns the [ContentModel] for this block.
fn content_model(&self) -> ContentModel;
/// Returns the context for this block.
///
/// A block’s context is also sometimes referred to as a name, such as an
/// example block, a sidebar block, an admonition block, or a section.
///
/// Every block has a context. The context is often implied by the syntax,
/// but can be declared explicitly in certain cases. The context is what
/// distinguishes one kind of block from another. You can think of the
/// context as the block’s type.
///
/// For that reason, the context is not defined as an enumeration, but
/// rather as a string type that is optimized for the case where predefined
/// constants are viable.
fn context(&self) -> CowStr<'src>;
/// Returns an iterator over the nested blocks contained within
/// this block.
///
/// Many block types do not have nested blocks so the default implementation
/// returns an empty iterator.
fn nested_blocks(&'src self) -> Iter<'src, Block<'src>> {
const NO_BLOCKS: &[Block<'static>] = &[];
NO_BLOCKS.iter()
}
}
/// The content model of a block determines what kind of content the block can
/// have (if any) and how that content is processed.
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub enum ContentModel {
/// A block that may only contain other blocks (e.g., a section)
Compound,
/// A block that's treated as contiguous lines of paragraph text (and
/// subject to normal substitutions) (e.g., a paragraph block)
Simple,
/// A block that holds verbatim text (displayed "`as is`") (and subject to
/// verbatim substitutions) (e.g., a listing block)
Verbatim,
/// A block that holds unprocessed content passed directly through to the
/// output with no substitutions applied (e.g., a passthrough block)
Raw,
/// Ablock that has no content (e.g., an image block)
Empty,
/// A special content model reserved for tables that enforces a fixed
/// structure
Table,
}