Rename SyntaxTree to Markup

Also `SyntaxNode` -> `MarkupNode`.
This commit is contained in:
Laurenz 2021-09-15 12:43:57 +02:00
parent c18321a4c2
commit 5de791d9e6
9 changed files with 98 additions and 99 deletions

View File

@ -1,4 +1,4 @@
//! Evaluation of syntax trees into modules.
//! Evaluation of markup into modules.
#[macro_use]
mod array;
@ -46,9 +46,9 @@ use crate::util::RefMutExt;
use crate::Context;
/// 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 template = ast.eval(&mut ctx)?;
let template = markup.eval(&mut ctx)?;
Ok(Module { scope: ctx.scopes.top, template })
}
@ -159,7 +159,7 @@ pub trait Eval {
fn eval(&self, ctx: &mut EvalContext) -> TypResult<Self::Output>;
}
impl Eval for SyntaxTree {
impl Eval for Markup {
type Output = Template;
fn eval(&self, ctx: &mut EvalContext) -> TypResult<Self::Output> {
@ -253,7 +253,7 @@ impl Eval for TemplateExpr {
type Output = Template;
fn eval(&self, ctx: &mut EvalContext) -> TypResult<Self::Output> {
self.tree.eval(ctx)
self.body.eval(ctx)
}
}

View File

@ -7,13 +7,13 @@ use crate::layout::{ParChild, ParNode, StackChild, StackNode};
use crate::syntax::*;
use crate::util::BoolExt;
/// Walk a syntax node and fill the currently built template.
/// Walk markup, filling the currently built template.
pub trait Walk {
/// Walk the node.
fn walk(&self, ctx: &mut EvalContext) -> TypResult<()>;
}
impl Walk for SyntaxTree {
impl Walk for Markup {
fn walk(&self, ctx: &mut EvalContext) -> TypResult<()> {
for node in self.iter() {
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<()> {
match self {
Self::Space => ctx.template.space(),

View File

@ -2,25 +2,26 @@
//!
//! # Steps
//! - **Parsing:** The parsing step first transforms a plain string into an
//! [iterator of tokens][tokens]. This token stream is [parsed] into a [syntax
//! tree]. The structures describing the tree can be found in the [syntax]
//! module.
//! - **Evaluation:** The next step is to [evaluate] the syntax tree. This
//! produces a [module], consisting of a scope of values that were exported by
//! the module and a template with the contents of the module. This template
//! can be [instantiated] in a state to produce a layout tree, a high-level,
//! fully styled representation of the document. The nodes of this tree are
//! [iterator of tokens][tokens]. This token stream is [parsed] into [markup].
//! The syntactical structures describing markup and embedded code can be
//! found in the [syntax] module.
//! - **Evaluation:** The next step is to [evaluate] the markup. This produces a
//! [module], consisting of a scope of values that were exported by the code
//! and a template with the contents of the module. This template can be
//! [instantiated] in a state to produce a layout tree, a high-level, fully
//! styled representation of the document. The nodes of this tree are
//! 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
//! typeset document. The output of this is a collection of [`Frame`]s (one
//! per page), ready for exporting.
//! - **Exporting:** The finished layout can be exported into a supported
//! format. Currently, the only supported output format is [PDF].
//!
//! [tokens]: parse::Tokens
//! [parsed]: parse::parse
//! [syntax tree]: syntax::SyntaxTree
//! [markup]: syntax::Markup
//! [evaluate]: eval::eval
//! [module]: eval::Module
//! [instantiated]: eval::Template::to_tree
@ -57,7 +58,7 @@ use crate::layout::{EvictionPolicy, LayoutCache};
use crate::layout::{Frame, LayoutTree};
use crate::loading::Loader;
use crate::source::{SourceId, SourceStore};
use crate::syntax::SyntaxTree;
use crate::syntax::Markup;
/// The core context which holds the loader, configuration and cached artifacts.
pub struct Context {
@ -99,8 +100,8 @@ impl Context {
&self.state
}
/// Parse a source file and return the resulting syntax tree.
pub fn parse(&mut self, id: SourceId) -> TypResult<SyntaxTree> {
/// Parse a source file and return the resulting markup.
pub fn parse(&mut self, id: SourceId) -> TypResult<Markup> {
parse::parse(self.sources.get(id))
}

View File

@ -18,31 +18,31 @@ use crate::syntax::*;
use crate::util::EcoString;
/// 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 tree = tree(&mut p);
let markup = markup(&mut p);
let errors = p.finish();
if errors.is_empty() {
Ok(tree)
Ok(markup)
} else {
Err(Box::new(errors))
}
}
/// Parse a syntax tree.
fn tree(p: &mut Parser) -> SyntaxTree {
tree_while(p, true, &mut |_| true)
/// Parse markup.
fn markup(p: &mut Parser) -> Markup {
markup_while(p, true, &mut |_| true)
}
/// Parse a syntax tree that stays right of the given column.
fn tree_indented(p: &mut Parser, column: usize) -> SyntaxTree {
/// Parse markup that stays right of the given column.
fn markup_indented(p: &mut Parser, column: usize) -> Markup {
p.eat_while(|t| match t {
Token::Space(n) => n == 0,
Token::LineComment(_) | Token::BlockComment(_) => true,
_ => 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,
_ => 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
/// 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
F: FnMut(&mut Parser) -> bool,
{
let mut tree = vec![];
while !p.eof() && f(p) {
if let Some(node) = node(p, &mut at_start) {
at_start &= matches!(node, SyntaxNode::Space | SyntaxNode::Parbreak(_));
if let Some(node) = markup_node(p, &mut at_start) {
at_start &= matches!(node, MarkupNode::Space | MarkupNode::Parbreak(_));
tree.push(node);
}
}
@ -67,8 +67,8 @@ where
tree
}
/// Parse a syntax node.
fn node(p: &mut Parser, at_start: &mut bool) -> Option<SyntaxNode> {
/// Parse a markup node.
fn markup_node(p: &mut Parser, at_start: &mut bool) -> Option<MarkupNode> {
let token = p.peek()?;
let span = p.peek_span();
let node = match token {
@ -76,23 +76,23 @@ fn node(p: &mut Parser, at_start: &mut bool) -> Option<SyntaxNode> {
Token::Space(newlines) => {
*at_start |= newlines > 0;
if newlines < 2 {
SyntaxNode::Space
MarkupNode::Space
} else {
SyntaxNode::Parbreak(span)
MarkupNode::Parbreak(span)
}
}
// Text.
Token::Text(text) => SyntaxNode::Text(text.into()),
Token::Tilde => SyntaxNode::Text("\u{00A0}".into()),
Token::HyphHyph => SyntaxNode::Text("\u{2013}".into()),
Token::HyphHyphHyph => SyntaxNode::Text("\u{2014}".into()),
Token::UnicodeEscape(t) => SyntaxNode::Text(unicode_escape(p, t)),
Token::Text(text) => MarkupNode::Text(text.into()),
Token::Tilde => MarkupNode::Text("\u{00A0}".into()),
Token::HyphHyph => MarkupNode::Text("\u{2013}".into()),
Token::HyphHyphHyph => MarkupNode::Text("\u{2014}".into()),
Token::UnicodeEscape(t) => MarkupNode::Text(unicode_escape(p, t)),
// Markup.
Token::Backslash => SyntaxNode::Linebreak(span),
Token::Star => SyntaxNode::Strong(span),
Token::Underscore => SyntaxNode::Emph(span),
Token::Backslash => MarkupNode::Linebreak(span),
Token::Star => MarkupNode::Strong(span),
Token::Underscore => MarkupNode::Emph(span),
Token::Raw(t) => raw(p, t),
Token::Eq if *at_start => return Some(heading(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.
Token::Eq | Token::Hyph | Token::Numbering(_) => {
SyntaxNode::Text(p.peek_src().into())
MarkupNode::Text(p.peek_src().into())
}
// Hashtag + keyword / identifier.
@ -121,12 +121,12 @@ fn node(p: &mut Parser, at_start: &mut bool) -> Option<SyntaxNode> {
}
p.end_group();
return expr.map(SyntaxNode::Expr);
return expr.map(MarkupNode::Expr);
}
// Block and template.
Token::LeftBrace => return Some(SyntaxNode::Expr(block(p, false))),
Token::LeftBracket => return Some(SyntaxNode::Expr(template(p))),
Token::LeftBrace => return Some(MarkupNode::Expr(block(p, false))),
Token::LeftBracket => return Some(MarkupNode::Expr(template(p))),
// Comments.
Token::LineComment(_) | Token::BlockComment(_) => {
@ -163,17 +163,17 @@ fn unicode_escape(p: &mut Parser, token: UnicodeEscapeToken) -> EcoString {
}
/// 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 raw = resolve::resolve_raw(span, token.text, token.backticks);
if !token.terminated {
p.error(span.end, "expected backtick(s)");
}
SyntaxNode::Raw(Box::new(raw))
MarkupNode::Raw(Box::new(raw))
}
/// Parse a heading.
fn heading(p: &mut Parser) -> SyntaxNode {
fn heading(p: &mut Parser) -> MarkupNode {
let start = p.next_start();
let column = p.column(start);
p.eat_assert(Token::Eq);
@ -185,11 +185,11 @@ fn heading(p: &mut Parser) -> SyntaxNode {
}
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);
SyntaxNode::Heading(Box::new(HeadingNode {
let body = markup_indented(p, column);
MarkupNode::Heading(Box::new(HeadingNode {
span: p.span_from(start),
level,
body,
@ -197,21 +197,21 @@ fn heading(p: &mut Parser) -> SyntaxNode {
}
/// 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 column = p.column(start);
p.eat_assert(Token::Hyph);
let body = tree_indented(p, column);
SyntaxNode::List(Box::new(ListNode { span: p.span_from(start), body }))
let body = markup_indented(p, column);
MarkupNode::List(Box::new(ListNode { span: p.span_from(start), body }))
}
/// 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 column = p.column(start);
p.eat_assert(Token::Numbering(number));
let body = tree_indented(p, column);
SyntaxNode::Enum(Box::new(EnumNode {
let body = markup_indented(p, column);
MarkupNode::Enum(Box::new(EnumNode {
span: p.span_from(start),
number,
body,
@ -521,9 +521,9 @@ fn idents(p: &mut Parser, items: Vec<CallArg>) -> Vec<Ident> {
// Parse a template block: `[...]`.
fn template(p: &mut Parser) -> Expr {
p.start_group(Group::Bracket, TokenMode::Markup);
let tree = tree(p);
let tree = markup(p);
let span = p.end_group();
Expr::Template(Box::new(TemplateExpr { span, tree }))
Expr::Template(Box::new(TemplateExpr { span, body: tree }))
}
/// Parse a code block: `{...}`.

View File

@ -1,7 +1,8 @@
use std::rc::Rc;
use super::*;
use super::{Ident, Markup, Span, Token};
use crate::geom::{AngularUnit, LengthUnit};
use crate::util::EcoString;
/// An expression.
#[derive(Debug, Clone, PartialEq)]
@ -170,7 +171,7 @@ pub struct TemplateExpr {
/// The source code location.
pub span: Span,
/// The contents of the template.
pub tree: SyntaxTree,
pub body: Markup,
}
/// A grouped expression: `(1 + 2)`.

View File

@ -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)]
pub enum SyntaxNode {
pub enum MarkupNode {
/// Whitespace containing less than two newlines.
Space,
/// A forced line break: `\`.
@ -50,7 +54,7 @@ pub struct HeadingNode {
/// The section depth (numer of equals signs).
pub level: usize,
/// The contents of the heading.
pub body: SyntaxTree,
pub body: Markup,
}
/// An item in an unordered list: `- ...`.
@ -59,7 +63,7 @@ pub struct ListNode {
/// The source code location.
pub span: Span,
/// The contents of the list item.
pub body: SyntaxTree,
pub body: Markup,
}
/// An item in an enumeration (ordered list): `1. ...`.
@ -70,5 +74,5 @@ pub struct EnumNode {
/// The number, if any.
pub number: Option<usize>,
/// The contents of the list item.
pub body: SyntaxTree,
pub body: Markup,
}

View File

@ -2,7 +2,7 @@
mod expr;
mod ident;
mod node;
mod markup;
mod pretty;
mod span;
mod token;
@ -10,14 +10,7 @@ pub mod visit;
pub use expr::*;
pub use ident::*;
pub use node::*;
pub use markup::*;
pub use pretty::*;
pub use span::*;
pub use token::*;
use crate::util::EcoString;
/// The abstract syntax tree.
///
/// This type can represent a full parsed document.
pub type SyntaxTree = Vec<SyntaxNode>;

View File

@ -75,7 +75,7 @@ impl Write for Printer {
}
}
impl Pretty for SyntaxTree {
impl Pretty for Markup {
fn pretty(&self, p: &mut Printer) {
for node in self {
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) {
match self {
// TODO: Handle escaping.
@ -266,7 +266,7 @@ impl Pretty for Named {
impl Pretty for TemplateExpr {
fn pretty(&self, p: &mut Printer) {
p.push('[');
self.tree.pretty(p);
self.body.pretty(p);
p.push(']');
}
}

View File

@ -1,6 +1,6 @@
//! Mutable and immutable syntax tree traversal.
use crate::syntax::*;
use super::*;
/// Implement the immutable and the mutable visitor version.
macro_rules! impl_visitors {
@ -78,25 +78,25 @@ macro_rules! impl_visitor {
}
impl_visitors! {
visit_tree(v, tree: SyntaxTree) {
for node in tree {
visit_tree(v, markup: Markup) {
for node in markup {
v.visit_node(node);
}
}
visit_node(v, node: SyntaxNode) {
visit_node(v, node: MarkupNode) {
match node {
SyntaxNode::Space => {}
SyntaxNode::Linebreak(_) => {}
SyntaxNode::Parbreak(_) => {}
SyntaxNode::Strong(_) => {}
SyntaxNode::Emph(_) => {}
SyntaxNode::Text(_) => {}
SyntaxNode::Raw(_) => {}
SyntaxNode::Heading(n) => v.visit_heading(n),
SyntaxNode::List(n) => v.visit_list(n),
SyntaxNode::Enum(n) => v.visit_enum(n),
SyntaxNode::Expr(n) => v.visit_expr(n),
MarkupNode::Space => {}
MarkupNode::Linebreak(_) => {}
MarkupNode::Parbreak(_) => {}
MarkupNode::Strong(_) => {}
MarkupNode::Emph(_) => {}
MarkupNode::Text(_) => {}
MarkupNode::Raw(_) => {}
MarkupNode::Heading(n) => v.visit_heading(n),
MarkupNode::List(n) => v.visit_list(n),
MarkupNode::Enum(n) => v.visit_enum(n),
MarkupNode::Expr(n) => v.visit_expr(n),
}
}
@ -149,7 +149,7 @@ impl_visitors! {
visit_template(v, template: TemplateExpr) {
v.visit_enter();
v.visit_tree(r!(template.tree));
v.visit_tree(r!(template.body));
v.visit_exit();
}