mirror of
https://github.com/typst/typst
synced 2025-05-14 04:56:26 +08:00
Rename SyntaxTree
to Markup
Also `SyntaxNode` -> `MarkupNode`.
This commit is contained in:
parent
c18321a4c2
commit
5de791d9e6
@ -1,4 +1,4 @@
|
|||||||
//! Evaluation of syntax trees into modules.
|
//! Evaluation of markup into modules.
|
||||||
|
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
mod array;
|
mod array;
|
||||||
@ -46,9 +46,9 @@ use crate::util::RefMutExt;
|
|||||||
use crate::Context;
|
use crate::Context;
|
||||||
|
|
||||||
/// Evaluate a parsed source file into a module.
|
/// Evaluate a parsed source file into a module.
|
||||||
pub fn eval(ctx: &mut Context, source: SourceId, ast: &SyntaxTree) -> TypResult<Module> {
|
pub fn eval(ctx: &mut Context, source: SourceId, markup: &Markup) -> TypResult<Module> {
|
||||||
let mut ctx = EvalContext::new(ctx, source);
|
let mut ctx = EvalContext::new(ctx, source);
|
||||||
let template = ast.eval(&mut ctx)?;
|
let template = markup.eval(&mut ctx)?;
|
||||||
Ok(Module { scope: ctx.scopes.top, template })
|
Ok(Module { scope: ctx.scopes.top, template })
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -159,7 +159,7 @@ pub trait Eval {
|
|||||||
fn eval(&self, ctx: &mut EvalContext) -> TypResult<Self::Output>;
|
fn eval(&self, ctx: &mut EvalContext) -> TypResult<Self::Output>;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Eval for SyntaxTree {
|
impl Eval for Markup {
|
||||||
type Output = Template;
|
type Output = Template;
|
||||||
|
|
||||||
fn eval(&self, ctx: &mut EvalContext) -> TypResult<Self::Output> {
|
fn eval(&self, ctx: &mut EvalContext) -> TypResult<Self::Output> {
|
||||||
@ -253,7 +253,7 @@ impl Eval for TemplateExpr {
|
|||||||
type Output = Template;
|
type Output = Template;
|
||||||
|
|
||||||
fn eval(&self, ctx: &mut EvalContext) -> TypResult<Self::Output> {
|
fn eval(&self, ctx: &mut EvalContext) -> TypResult<Self::Output> {
|
||||||
self.tree.eval(ctx)
|
self.body.eval(ctx)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7,13 +7,13 @@ use crate::layout::{ParChild, ParNode, StackChild, StackNode};
|
|||||||
use crate::syntax::*;
|
use crate::syntax::*;
|
||||||
use crate::util::BoolExt;
|
use crate::util::BoolExt;
|
||||||
|
|
||||||
/// Walk a syntax node and fill the currently built template.
|
/// Walk markup, filling the currently built template.
|
||||||
pub trait Walk {
|
pub trait Walk {
|
||||||
/// Walk the node.
|
/// Walk the node.
|
||||||
fn walk(&self, ctx: &mut EvalContext) -> TypResult<()>;
|
fn walk(&self, ctx: &mut EvalContext) -> TypResult<()>;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Walk for SyntaxTree {
|
impl Walk for Markup {
|
||||||
fn walk(&self, ctx: &mut EvalContext) -> TypResult<()> {
|
fn walk(&self, ctx: &mut EvalContext) -> TypResult<()> {
|
||||||
for node in self.iter() {
|
for node in self.iter() {
|
||||||
node.walk(ctx)?;
|
node.walk(ctx)?;
|
||||||
@ -22,7 +22,7 @@ impl Walk for SyntaxTree {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Walk for SyntaxNode {
|
impl Walk for MarkupNode {
|
||||||
fn walk(&self, ctx: &mut EvalContext) -> TypResult<()> {
|
fn walk(&self, ctx: &mut EvalContext) -> TypResult<()> {
|
||||||
match self {
|
match self {
|
||||||
Self::Space => ctx.template.space(),
|
Self::Space => ctx.template.space(),
|
||||||
|
27
src/lib.rs
27
src/lib.rs
@ -2,25 +2,26 @@
|
|||||||
//!
|
//!
|
||||||
//! # Steps
|
//! # Steps
|
||||||
//! - **Parsing:** The parsing step first transforms a plain string into an
|
//! - **Parsing:** The parsing step first transforms a plain string into an
|
||||||
//! [iterator of tokens][tokens]. This token stream is [parsed] into a [syntax
|
//! [iterator of tokens][tokens]. This token stream is [parsed] into [markup].
|
||||||
//! tree]. The structures describing the tree can be found in the [syntax]
|
//! The syntactical structures describing markup and embedded code can be
|
||||||
//! module.
|
//! found in the [syntax] module.
|
||||||
//! - **Evaluation:** The next step is to [evaluate] the syntax tree. This
|
//! - **Evaluation:** The next step is to [evaluate] the markup. This produces a
|
||||||
//! produces a [module], consisting of a scope of values that were exported by
|
//! [module], consisting of a scope of values that were exported by the code
|
||||||
//! the module and a template with the contents of the module. This template
|
//! and a template with the contents of the module. This template can be
|
||||||
//! can be [instantiated] in a state to produce a layout tree, a high-level,
|
//! [instantiated] in a state to produce a layout tree, a high-level, fully
|
||||||
//! fully styled representation of the document. The nodes of this tree are
|
//! styled representation of the document. The nodes of this tree are
|
||||||
//! self-contained and order-independent and thus much better suited for
|
//! self-contained and order-independent and thus much better suited for
|
||||||
//! layouting than a syntax tree.
|
//! layouting than the raw markup.
|
||||||
//! - **Layouting:** Next, the tree is [layouted] into a portable version of the
|
//! - **Layouting:** Next, the tree is [layouted] into a portable version of the
|
||||||
//! typeset document. The output of this is a collection of [`Frame`]s (one
|
//! typeset document. The output of this is a collection of [`Frame`]s (one
|
||||||
//! per page), ready for exporting.
|
//! per page), ready for exporting.
|
||||||
//! - **Exporting:** The finished layout can be exported into a supported
|
//! - **Exporting:** The finished layout can be exported into a supported
|
||||||
//! format. Currently, the only supported output format is [PDF].
|
//! format. Currently, the only supported output format is [PDF].
|
||||||
//!
|
//!
|
||||||
|
|
||||||
//! [tokens]: parse::Tokens
|
//! [tokens]: parse::Tokens
|
||||||
//! [parsed]: parse::parse
|
//! [parsed]: parse::parse
|
||||||
//! [syntax tree]: syntax::SyntaxTree
|
//! [markup]: syntax::Markup
|
||||||
//! [evaluate]: eval::eval
|
//! [evaluate]: eval::eval
|
||||||
//! [module]: eval::Module
|
//! [module]: eval::Module
|
||||||
//! [instantiated]: eval::Template::to_tree
|
//! [instantiated]: eval::Template::to_tree
|
||||||
@ -57,7 +58,7 @@ use crate::layout::{EvictionPolicy, LayoutCache};
|
|||||||
use crate::layout::{Frame, LayoutTree};
|
use crate::layout::{Frame, LayoutTree};
|
||||||
use crate::loading::Loader;
|
use crate::loading::Loader;
|
||||||
use crate::source::{SourceId, SourceStore};
|
use crate::source::{SourceId, SourceStore};
|
||||||
use crate::syntax::SyntaxTree;
|
use crate::syntax::Markup;
|
||||||
|
|
||||||
/// The core context which holds the loader, configuration and cached artifacts.
|
/// The core context which holds the loader, configuration and cached artifacts.
|
||||||
pub struct Context {
|
pub struct Context {
|
||||||
@ -99,8 +100,8 @@ impl Context {
|
|||||||
&self.state
|
&self.state
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Parse a source file and return the resulting syntax tree.
|
/// Parse a source file and return the resulting markup.
|
||||||
pub fn parse(&mut self, id: SourceId) -> TypResult<SyntaxTree> {
|
pub fn parse(&mut self, id: SourceId) -> TypResult<Markup> {
|
||||||
parse::parse(self.sources.get(id))
|
parse::parse(self.sources.get(id))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -18,31 +18,31 @@ use crate::syntax::*;
|
|||||||
use crate::util::EcoString;
|
use crate::util::EcoString;
|
||||||
|
|
||||||
/// Parse a source file.
|
/// Parse a source file.
|
||||||
pub fn parse(source: &SourceFile) -> TypResult<SyntaxTree> {
|
pub fn parse(source: &SourceFile) -> TypResult<Markup> {
|
||||||
let mut p = Parser::new(source);
|
let mut p = Parser::new(source);
|
||||||
let tree = tree(&mut p);
|
let markup = markup(&mut p);
|
||||||
let errors = p.finish();
|
let errors = p.finish();
|
||||||
if errors.is_empty() {
|
if errors.is_empty() {
|
||||||
Ok(tree)
|
Ok(markup)
|
||||||
} else {
|
} else {
|
||||||
Err(Box::new(errors))
|
Err(Box::new(errors))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Parse a syntax tree.
|
/// Parse markup.
|
||||||
fn tree(p: &mut Parser) -> SyntaxTree {
|
fn markup(p: &mut Parser) -> Markup {
|
||||||
tree_while(p, true, &mut |_| true)
|
markup_while(p, true, &mut |_| true)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Parse a syntax tree that stays right of the given column.
|
/// Parse markup that stays right of the given column.
|
||||||
fn tree_indented(p: &mut Parser, column: usize) -> SyntaxTree {
|
fn markup_indented(p: &mut Parser, column: usize) -> Markup {
|
||||||
p.eat_while(|t| match t {
|
p.eat_while(|t| match t {
|
||||||
Token::Space(n) => n == 0,
|
Token::Space(n) => n == 0,
|
||||||
Token::LineComment(_) | Token::BlockComment(_) => true,
|
Token::LineComment(_) | Token::BlockComment(_) => true,
|
||||||
_ => false,
|
_ => false,
|
||||||
});
|
});
|
||||||
|
|
||||||
tree_while(p, false, &mut |p| match p.peek() {
|
markup_while(p, false, &mut |p| match p.peek() {
|
||||||
Some(Token::Space(n)) if n >= 1 => p.column(p.next_end()) > column,
|
Some(Token::Space(n)) if n >= 1 => p.column(p.next_end()) > column,
|
||||||
_ => true,
|
_ => true,
|
||||||
})
|
})
|
||||||
@ -52,14 +52,14 @@ fn tree_indented(p: &mut Parser, column: usize) -> SyntaxTree {
|
|||||||
///
|
///
|
||||||
/// If `at_start` is true, things like headings that may only appear at the
|
/// If `at_start` is true, things like headings that may only appear at the
|
||||||
/// beginning of a line or template are allowed.
|
/// beginning of a line or template are allowed.
|
||||||
fn tree_while<F>(p: &mut Parser, mut at_start: bool, f: &mut F) -> SyntaxTree
|
fn markup_while<F>(p: &mut Parser, mut at_start: bool, f: &mut F) -> Markup
|
||||||
where
|
where
|
||||||
F: FnMut(&mut Parser) -> bool,
|
F: FnMut(&mut Parser) -> bool,
|
||||||
{
|
{
|
||||||
let mut tree = vec![];
|
let mut tree = vec![];
|
||||||
while !p.eof() && f(p) {
|
while !p.eof() && f(p) {
|
||||||
if let Some(node) = node(p, &mut at_start) {
|
if let Some(node) = markup_node(p, &mut at_start) {
|
||||||
at_start &= matches!(node, SyntaxNode::Space | SyntaxNode::Parbreak(_));
|
at_start &= matches!(node, MarkupNode::Space | MarkupNode::Parbreak(_));
|
||||||
tree.push(node);
|
tree.push(node);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -67,8 +67,8 @@ where
|
|||||||
tree
|
tree
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Parse a syntax node.
|
/// Parse a markup node.
|
||||||
fn node(p: &mut Parser, at_start: &mut bool) -> Option<SyntaxNode> {
|
fn markup_node(p: &mut Parser, at_start: &mut bool) -> Option<MarkupNode> {
|
||||||
let token = p.peek()?;
|
let token = p.peek()?;
|
||||||
let span = p.peek_span();
|
let span = p.peek_span();
|
||||||
let node = match token {
|
let node = match token {
|
||||||
@ -76,23 +76,23 @@ fn node(p: &mut Parser, at_start: &mut bool) -> Option<SyntaxNode> {
|
|||||||
Token::Space(newlines) => {
|
Token::Space(newlines) => {
|
||||||
*at_start |= newlines > 0;
|
*at_start |= newlines > 0;
|
||||||
if newlines < 2 {
|
if newlines < 2 {
|
||||||
SyntaxNode::Space
|
MarkupNode::Space
|
||||||
} else {
|
} else {
|
||||||
SyntaxNode::Parbreak(span)
|
MarkupNode::Parbreak(span)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Text.
|
// Text.
|
||||||
Token::Text(text) => SyntaxNode::Text(text.into()),
|
Token::Text(text) => MarkupNode::Text(text.into()),
|
||||||
Token::Tilde => SyntaxNode::Text("\u{00A0}".into()),
|
Token::Tilde => MarkupNode::Text("\u{00A0}".into()),
|
||||||
Token::HyphHyph => SyntaxNode::Text("\u{2013}".into()),
|
Token::HyphHyph => MarkupNode::Text("\u{2013}".into()),
|
||||||
Token::HyphHyphHyph => SyntaxNode::Text("\u{2014}".into()),
|
Token::HyphHyphHyph => MarkupNode::Text("\u{2014}".into()),
|
||||||
Token::UnicodeEscape(t) => SyntaxNode::Text(unicode_escape(p, t)),
|
Token::UnicodeEscape(t) => MarkupNode::Text(unicode_escape(p, t)),
|
||||||
|
|
||||||
// Markup.
|
// Markup.
|
||||||
Token::Backslash => SyntaxNode::Linebreak(span),
|
Token::Backslash => MarkupNode::Linebreak(span),
|
||||||
Token::Star => SyntaxNode::Strong(span),
|
Token::Star => MarkupNode::Strong(span),
|
||||||
Token::Underscore => SyntaxNode::Emph(span),
|
Token::Underscore => MarkupNode::Emph(span),
|
||||||
Token::Raw(t) => raw(p, t),
|
Token::Raw(t) => raw(p, t),
|
||||||
Token::Eq if *at_start => return Some(heading(p)),
|
Token::Eq if *at_start => return Some(heading(p)),
|
||||||
Token::Hyph if *at_start => return Some(list_node(p)),
|
Token::Hyph if *at_start => return Some(list_node(p)),
|
||||||
@ -100,7 +100,7 @@ fn node(p: &mut Parser, at_start: &mut bool) -> Option<SyntaxNode> {
|
|||||||
|
|
||||||
// Line-based markup that is not currently at the start of the line.
|
// Line-based markup that is not currently at the start of the line.
|
||||||
Token::Eq | Token::Hyph | Token::Numbering(_) => {
|
Token::Eq | Token::Hyph | Token::Numbering(_) => {
|
||||||
SyntaxNode::Text(p.peek_src().into())
|
MarkupNode::Text(p.peek_src().into())
|
||||||
}
|
}
|
||||||
|
|
||||||
// Hashtag + keyword / identifier.
|
// Hashtag + keyword / identifier.
|
||||||
@ -121,12 +121,12 @@ fn node(p: &mut Parser, at_start: &mut bool) -> Option<SyntaxNode> {
|
|||||||
}
|
}
|
||||||
p.end_group();
|
p.end_group();
|
||||||
|
|
||||||
return expr.map(SyntaxNode::Expr);
|
return expr.map(MarkupNode::Expr);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Block and template.
|
// Block and template.
|
||||||
Token::LeftBrace => return Some(SyntaxNode::Expr(block(p, false))),
|
Token::LeftBrace => return Some(MarkupNode::Expr(block(p, false))),
|
||||||
Token::LeftBracket => return Some(SyntaxNode::Expr(template(p))),
|
Token::LeftBracket => return Some(MarkupNode::Expr(template(p))),
|
||||||
|
|
||||||
// Comments.
|
// Comments.
|
||||||
Token::LineComment(_) | Token::BlockComment(_) => {
|
Token::LineComment(_) | Token::BlockComment(_) => {
|
||||||
@ -163,17 +163,17 @@ fn unicode_escape(p: &mut Parser, token: UnicodeEscapeToken) -> EcoString {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Handle a raw block.
|
/// Handle a raw block.
|
||||||
fn raw(p: &mut Parser, token: RawToken) -> SyntaxNode {
|
fn raw(p: &mut Parser, token: RawToken) -> MarkupNode {
|
||||||
let span = p.peek_span();
|
let span = p.peek_span();
|
||||||
let raw = resolve::resolve_raw(span, token.text, token.backticks);
|
let raw = resolve::resolve_raw(span, token.text, token.backticks);
|
||||||
if !token.terminated {
|
if !token.terminated {
|
||||||
p.error(span.end, "expected backtick(s)");
|
p.error(span.end, "expected backtick(s)");
|
||||||
}
|
}
|
||||||
SyntaxNode::Raw(Box::new(raw))
|
MarkupNode::Raw(Box::new(raw))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Parse a heading.
|
/// Parse a heading.
|
||||||
fn heading(p: &mut Parser) -> SyntaxNode {
|
fn heading(p: &mut Parser) -> MarkupNode {
|
||||||
let start = p.next_start();
|
let start = p.next_start();
|
||||||
let column = p.column(start);
|
let column = p.column(start);
|
||||||
p.eat_assert(Token::Eq);
|
p.eat_assert(Token::Eq);
|
||||||
@ -185,11 +185,11 @@ fn heading(p: &mut Parser) -> SyntaxNode {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if level > 6 {
|
if level > 6 {
|
||||||
return SyntaxNode::Text(p.get(start .. p.prev_end()).into());
|
return MarkupNode::Text(p.get(start .. p.prev_end()).into());
|
||||||
}
|
}
|
||||||
|
|
||||||
let body = tree_indented(p, column);
|
let body = markup_indented(p, column);
|
||||||
SyntaxNode::Heading(Box::new(HeadingNode {
|
MarkupNode::Heading(Box::new(HeadingNode {
|
||||||
span: p.span_from(start),
|
span: p.span_from(start),
|
||||||
level,
|
level,
|
||||||
body,
|
body,
|
||||||
@ -197,21 +197,21 @@ fn heading(p: &mut Parser) -> SyntaxNode {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Parse a single list item.
|
/// Parse a single list item.
|
||||||
fn list_node(p: &mut Parser) -> SyntaxNode {
|
fn list_node(p: &mut Parser) -> MarkupNode {
|
||||||
let start = p.next_start();
|
let start = p.next_start();
|
||||||
let column = p.column(start);
|
let column = p.column(start);
|
||||||
p.eat_assert(Token::Hyph);
|
p.eat_assert(Token::Hyph);
|
||||||
let body = tree_indented(p, column);
|
let body = markup_indented(p, column);
|
||||||
SyntaxNode::List(Box::new(ListNode { span: p.span_from(start), body }))
|
MarkupNode::List(Box::new(ListNode { span: p.span_from(start), body }))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Parse a single enum item.
|
/// Parse a single enum item.
|
||||||
fn enum_node(p: &mut Parser, number: Option<usize>) -> SyntaxNode {
|
fn enum_node(p: &mut Parser, number: Option<usize>) -> MarkupNode {
|
||||||
let start = p.next_start();
|
let start = p.next_start();
|
||||||
let column = p.column(start);
|
let column = p.column(start);
|
||||||
p.eat_assert(Token::Numbering(number));
|
p.eat_assert(Token::Numbering(number));
|
||||||
let body = tree_indented(p, column);
|
let body = markup_indented(p, column);
|
||||||
SyntaxNode::Enum(Box::new(EnumNode {
|
MarkupNode::Enum(Box::new(EnumNode {
|
||||||
span: p.span_from(start),
|
span: p.span_from(start),
|
||||||
number,
|
number,
|
||||||
body,
|
body,
|
||||||
@ -521,9 +521,9 @@ fn idents(p: &mut Parser, items: Vec<CallArg>) -> Vec<Ident> {
|
|||||||
// Parse a template block: `[...]`.
|
// Parse a template block: `[...]`.
|
||||||
fn template(p: &mut Parser) -> Expr {
|
fn template(p: &mut Parser) -> Expr {
|
||||||
p.start_group(Group::Bracket, TokenMode::Markup);
|
p.start_group(Group::Bracket, TokenMode::Markup);
|
||||||
let tree = tree(p);
|
let tree = markup(p);
|
||||||
let span = p.end_group();
|
let span = p.end_group();
|
||||||
Expr::Template(Box::new(TemplateExpr { span, tree }))
|
Expr::Template(Box::new(TemplateExpr { span, body: tree }))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Parse a code block: `{...}`.
|
/// Parse a code block: `{...}`.
|
||||||
|
@ -1,7 +1,8 @@
|
|||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
|
||||||
use super::*;
|
use super::{Ident, Markup, Span, Token};
|
||||||
use crate::geom::{AngularUnit, LengthUnit};
|
use crate::geom::{AngularUnit, LengthUnit};
|
||||||
|
use crate::util::EcoString;
|
||||||
|
|
||||||
/// An expression.
|
/// An expression.
|
||||||
#[derive(Debug, Clone, PartialEq)]
|
#[derive(Debug, Clone, PartialEq)]
|
||||||
@ -170,7 +171,7 @@ pub struct TemplateExpr {
|
|||||||
/// The source code location.
|
/// The source code location.
|
||||||
pub span: Span,
|
pub span: Span,
|
||||||
/// The contents of the template.
|
/// The contents of the template.
|
||||||
pub tree: SyntaxTree,
|
pub body: Markup,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A grouped expression: `(1 + 2)`.
|
/// A grouped expression: `(1 + 2)`.
|
||||||
|
@ -1,8 +1,12 @@
|
|||||||
use super::*;
|
use super::{Expr, Ident, Span};
|
||||||
|
use crate::util::EcoString;
|
||||||
|
|
||||||
/// A syntax node, encompassing a single logical entity of parsed source code.
|
/// The syntactical root capable of representing a full parsed document.
|
||||||
|
pub type Markup = Vec<MarkupNode>;
|
||||||
|
|
||||||
|
/// A single piece of markup.
|
||||||
#[derive(Debug, Clone, PartialEq)]
|
#[derive(Debug, Clone, PartialEq)]
|
||||||
pub enum SyntaxNode {
|
pub enum MarkupNode {
|
||||||
/// Whitespace containing less than two newlines.
|
/// Whitespace containing less than two newlines.
|
||||||
Space,
|
Space,
|
||||||
/// A forced line break: `\`.
|
/// A forced line break: `\`.
|
||||||
@ -50,7 +54,7 @@ pub struct HeadingNode {
|
|||||||
/// The section depth (numer of equals signs).
|
/// The section depth (numer of equals signs).
|
||||||
pub level: usize,
|
pub level: usize,
|
||||||
/// The contents of the heading.
|
/// The contents of the heading.
|
||||||
pub body: SyntaxTree,
|
pub body: Markup,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// An item in an unordered list: `- ...`.
|
/// An item in an unordered list: `- ...`.
|
||||||
@ -59,7 +63,7 @@ pub struct ListNode {
|
|||||||
/// The source code location.
|
/// The source code location.
|
||||||
pub span: Span,
|
pub span: Span,
|
||||||
/// The contents of the list item.
|
/// The contents of the list item.
|
||||||
pub body: SyntaxTree,
|
pub body: Markup,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// An item in an enumeration (ordered list): `1. ...`.
|
/// An item in an enumeration (ordered list): `1. ...`.
|
||||||
@ -70,5 +74,5 @@ pub struct EnumNode {
|
|||||||
/// The number, if any.
|
/// The number, if any.
|
||||||
pub number: Option<usize>,
|
pub number: Option<usize>,
|
||||||
/// The contents of the list item.
|
/// The contents of the list item.
|
||||||
pub body: SyntaxTree,
|
pub body: Markup,
|
||||||
}
|
}
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
mod expr;
|
mod expr;
|
||||||
mod ident;
|
mod ident;
|
||||||
mod node;
|
mod markup;
|
||||||
mod pretty;
|
mod pretty;
|
||||||
mod span;
|
mod span;
|
||||||
mod token;
|
mod token;
|
||||||
@ -10,14 +10,7 @@ pub mod visit;
|
|||||||
|
|
||||||
pub use expr::*;
|
pub use expr::*;
|
||||||
pub use ident::*;
|
pub use ident::*;
|
||||||
pub use node::*;
|
pub use markup::*;
|
||||||
pub use pretty::*;
|
pub use pretty::*;
|
||||||
pub use span::*;
|
pub use span::*;
|
||||||
pub use token::*;
|
pub use token::*;
|
||||||
|
|
||||||
use crate::util::EcoString;
|
|
||||||
|
|
||||||
/// The abstract syntax tree.
|
|
||||||
///
|
|
||||||
/// This type can represent a full parsed document.
|
|
||||||
pub type SyntaxTree = Vec<SyntaxNode>;
|
|
||||||
|
@ -75,7 +75,7 @@ impl Write for Printer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Pretty for SyntaxTree {
|
impl Pretty for Markup {
|
||||||
fn pretty(&self, p: &mut Printer) {
|
fn pretty(&self, p: &mut Printer) {
|
||||||
for node in self {
|
for node in self {
|
||||||
node.pretty(p);
|
node.pretty(p);
|
||||||
@ -83,7 +83,7 @@ impl Pretty for SyntaxTree {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Pretty for SyntaxNode {
|
impl Pretty for MarkupNode {
|
||||||
fn pretty(&self, p: &mut Printer) {
|
fn pretty(&self, p: &mut Printer) {
|
||||||
match self {
|
match self {
|
||||||
// TODO: Handle escaping.
|
// TODO: Handle escaping.
|
||||||
@ -266,7 +266,7 @@ impl Pretty for Named {
|
|||||||
impl Pretty for TemplateExpr {
|
impl Pretty for TemplateExpr {
|
||||||
fn pretty(&self, p: &mut Printer) {
|
fn pretty(&self, p: &mut Printer) {
|
||||||
p.push('[');
|
p.push('[');
|
||||||
self.tree.pretty(p);
|
self.body.pretty(p);
|
||||||
p.push(']');
|
p.push(']');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
//! Mutable and immutable syntax tree traversal.
|
//! Mutable and immutable syntax tree traversal.
|
||||||
|
|
||||||
use crate::syntax::*;
|
use super::*;
|
||||||
|
|
||||||
/// Implement the immutable and the mutable visitor version.
|
/// Implement the immutable and the mutable visitor version.
|
||||||
macro_rules! impl_visitors {
|
macro_rules! impl_visitors {
|
||||||
@ -78,25 +78,25 @@ macro_rules! impl_visitor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl_visitors! {
|
impl_visitors! {
|
||||||
visit_tree(v, tree: SyntaxTree) {
|
visit_tree(v, markup: Markup) {
|
||||||
for node in tree {
|
for node in markup {
|
||||||
v.visit_node(node);
|
v.visit_node(node);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
visit_node(v, node: SyntaxNode) {
|
visit_node(v, node: MarkupNode) {
|
||||||
match node {
|
match node {
|
||||||
SyntaxNode::Space => {}
|
MarkupNode::Space => {}
|
||||||
SyntaxNode::Linebreak(_) => {}
|
MarkupNode::Linebreak(_) => {}
|
||||||
SyntaxNode::Parbreak(_) => {}
|
MarkupNode::Parbreak(_) => {}
|
||||||
SyntaxNode::Strong(_) => {}
|
MarkupNode::Strong(_) => {}
|
||||||
SyntaxNode::Emph(_) => {}
|
MarkupNode::Emph(_) => {}
|
||||||
SyntaxNode::Text(_) => {}
|
MarkupNode::Text(_) => {}
|
||||||
SyntaxNode::Raw(_) => {}
|
MarkupNode::Raw(_) => {}
|
||||||
SyntaxNode::Heading(n) => v.visit_heading(n),
|
MarkupNode::Heading(n) => v.visit_heading(n),
|
||||||
SyntaxNode::List(n) => v.visit_list(n),
|
MarkupNode::List(n) => v.visit_list(n),
|
||||||
SyntaxNode::Enum(n) => v.visit_enum(n),
|
MarkupNode::Enum(n) => v.visit_enum(n),
|
||||||
SyntaxNode::Expr(n) => v.visit_expr(n),
|
MarkupNode::Expr(n) => v.visit_expr(n),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -149,7 +149,7 @@ impl_visitors! {
|
|||||||
|
|
||||||
visit_template(v, template: TemplateExpr) {
|
visit_template(v, template: TemplateExpr) {
|
||||||
v.visit_enter();
|
v.visit_enter();
|
||||||
v.visit_tree(r!(template.tree));
|
v.visit_tree(r!(template.body));
|
||||||
v.visit_exit();
|
v.visit_exit();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user