summaryrefslogtreecommitdiff
path: root/src/syntax
diff options
context:
space:
mode:
authorLaurenz <laurmaedje@gmail.com>2021-06-09 00:37:13 +0200
committerLaurenz <laurmaedje@gmail.com>2021-06-09 00:37:13 +0200
commit5afb42ad89abb518a01a09051f0f9b6f75bd383e (patch)
treeb12368a287f22de711df8d759c20ee742ed5b4c2 /src/syntax
parentd69dfa84ec957ac4037f60a3335416a9f73b97c8 (diff)
Lists with indent-based parsing
- Unordered lists with indent-based parsing and basic layout using stacks - Headings are now also indent based - Removes syntax functions since they will be superseded by select & transform
Diffstat (limited to 'src/syntax')
-rw-r--r--src/syntax/node.rs110
-rw-r--r--src/syntax/token.rs14
-rw-r--r--src/syntax/visit.rs15
3 files changed, 42 insertions, 97 deletions
diff --git a/src/syntax/node.rs b/src/syntax/node.rs
index 5f76b56a..b4684d0b 100644
--- a/src/syntax/node.rs
+++ b/src/syntax/node.rs
@@ -17,70 +17,16 @@ pub enum Node {
Strong(Span),
/// Emphasized text was enabled / disabled: `_`.
Emph(Span),
- /// A section heading: `= Introduction`.
- Heading(HeadingNode),
/// A raw block with optional syntax highlighting: `` `...` ``.
Raw(RawNode),
+ /// A section heading: `= Introduction`.
+ Heading(HeadingNode),
+ /// A single list item: `- ...`.
+ List(ListNode),
/// An expression.
Expr(Expr),
}
-impl Node {
- // The names of the corresponding library functions.
- pub const LINEBREAK: &'static str = "linebreak";
- pub const PARBREAK: &'static str = "parbreak";
- pub const STRONG: &'static str = "strong";
- pub const EMPH: &'static str = "emph";
- pub const HEADING: &'static str = "heading";
- pub const RAW: &'static str = "raw";
-
- /// Desugar markup into a function call.
- pub fn desugar(&self) -> Option<CallExpr> {
- match *self {
- Self::Text(_) => None,
- Self::Space => None,
- Self::Linebreak(span) => Some(call(span, Self::LINEBREAK)),
- Self::Parbreak(span) => Some(call(span, Self::PARBREAK)),
- Self::Strong(span) => Some(call(span, Self::STRONG)),
- Self::Emph(span) => Some(call(span, Self::EMPH)),
- Self::Heading(ref heading) => Some(heading.desugar()),
- Self::Raw(ref raw) => Some(raw.desugar()),
- Self::Expr(_) => None,
- }
- }
-}
-
-/// A section heading: `= Introduction`.
-#[derive(Debug, Clone, PartialEq)]
-pub struct HeadingNode {
- /// The source code location.
- pub span: Span,
- /// The section depth (numer of equals signs).
- pub level: usize,
- /// The contents of the heading.
- pub contents: Rc<Tree>,
-}
-
-impl HeadingNode {
- pub const LEVEL: &'static str = "level";
- pub const BODY: &'static str = "body";
-
- /// Desugar into a function call.
- pub fn desugar(&self) -> CallExpr {
- let Self { span, level, ref contents } = *self;
- let mut call = call(span, Node::HEADING);
- call.args.items.push(CallArg::Named(Named {
- name: ident(span, Self::LEVEL),
- expr: Expr::Int(span, level as i64),
- }));
- call.args.items.push(CallArg::Pos(Expr::Template(TemplateExpr {
- span,
- tree: Rc::clone(&contents),
- })));
- call
- }
-}
-
/// A raw block with optional syntax highlighting: `` `...` ``.
///
/// Raw blocks start with 1 or 3+ backticks and end with the same number of
@@ -158,38 +104,22 @@ pub struct RawNode {
pub block: bool,
}
-impl RawNode {
- pub const LANG: &'static str = "lang";
- pub const BLOCK: &'static str = "block";
- pub const TEXT: &'static str = "text";
-
- /// Desugar into a function call.
- pub fn desugar(&self) -> CallExpr {
- let Self { span, ref lang, ref text, block } = *self;
- let mut call = call(span, Node::RAW);
- if let Some(lang) = lang {
- call.args.items.push(CallArg::Named(Named {
- name: ident(span, Self::LANG),
- expr: Expr::Str(span, lang.string.clone()),
- }));
- }
- call.args.items.push(CallArg::Named(Named {
- name: ident(span, Self::BLOCK),
- expr: Expr::Bool(span, block),
- }));
- call.args.items.push(CallArg::Pos(Expr::Str(span, text.clone())));
- call
- }
-}
-
-fn call(span: Span, name: &str) -> CallExpr {
- CallExpr {
- span,
- callee: Box::new(Expr::Ident(Ident { span, string: name.into() })),
- args: CallArgs { span, items: vec![] },
- }
+/// A section heading: `= Introduction`.
+#[derive(Debug, Clone, PartialEq)]
+pub struct HeadingNode {
+ /// The source code location.
+ pub span: Span,
+ /// The section depth (numer of equals signs).
+ pub level: usize,
+ /// The contents of the heading.
+ pub body: Rc<Tree>,
}
-fn ident(span: Span, string: &str) -> Ident {
- Ident { span, string: string.into() }
+/// A single list item: `- ...`.
+#[derive(Debug, Clone, PartialEq)]
+pub struct ListNode {
+ /// The source code location.
+ pub span: Span,
+ /// The contents of the list item.
+ pub body: Tree,
}
diff --git a/src/syntax/token.rs b/src/syntax/token.rs
index 538d81b7..9098f176 100644
--- a/src/syntax/token.rs
+++ b/src/syntax/token.rs
@@ -24,6 +24,10 @@ pub enum Token<'s> {
Hashtag,
/// A tilde: `~`.
Tilde,
+ /// Two hyphens: `--`.
+ HyphHyph,
+ /// Three hyphens: `---`.
+ HyphHyphHyph,
/// A backslash followed by nothing or whitespace: `\`.
Backslash,
/// A comma: `,`.
@@ -103,15 +107,15 @@ pub enum Token<'s> {
Space(usize),
/// A consecutive non-markup string.
Text(&'s str),
+ /// A slash and the letter "u" followed by a hexadecimal unicode entity
+ /// enclosed in curly braces: `\u{1F5FA}`.
+ UnicodeEscape(UnicodeEscapeToken<'s>),
/// An arbitrary number of backticks followed by inner contents, terminated
/// with the same number of backticks: `` `...` ``.
Raw(RawToken<'s>),
/// One or two dollar signs followed by inner contents, terminated with the
/// same number of dollar signs.
Math(MathToken<'s>),
- /// A slash and the letter "u" followed by a hexadecimal unicode entity
- /// enclosed in curly braces: `\u{1F5FA}`.
- UnicodeEscape(UnicodeEscapeToken<'s>),
/// An identifier: `center`.
Ident(&'s str),
/// A boolean: `true`, `false`.
@@ -204,6 +208,8 @@ impl<'s> Token<'s> {
Self::Underscore => "underscore",
Self::Hashtag => "hashtag",
Self::Tilde => "tilde",
+ Self::HyphHyph => "en dash",
+ Self::HyphHyphHyph => "em dash",
Self::Backslash => "backslash",
Self::Comma => "comma",
Self::Semicolon => "semicolon",
@@ -242,9 +248,9 @@ impl<'s> Token<'s> {
Self::Using => "keyword `using`",
Self::Space(_) => "space",
Self::Text(_) => "text",
+ Self::UnicodeEscape(_) => "unicode escape sequence",
Self::Raw(_) => "raw block",
Self::Math(_) => "math formula",
- Self::UnicodeEscape(_) => "unicode escape sequence",
Self::Ident(_) => "identifier",
Self::Bool(_) => "boolean",
Self::Int(_) => "integer",
diff --git a/src/syntax/visit.rs b/src/syntax/visit.rs
index 40d8e664..86481d4e 100644
--- a/src/syntax/visit.rs
+++ b/src/syntax/visit.rs
@@ -52,16 +52,25 @@ visit! {
match node {
Node::Text(_) => {}
Node::Space => {}
- Node::Strong(_) => {}
Node::Linebreak(_) => {}
Node::Parbreak(_) => {}
+ Node::Strong(_) => {}
Node::Emph(_) => {}
- Node::Heading(heading) => v.visit_tree(&heading.contents),
Node::Raw(_) => {}
- Node::Expr(expr) => v.visit_expr(expr),
+ Node::Heading(n) => v.visit_heading(n),
+ Node::List(n) => v.visit_list(n),
+ Node::Expr(n) => v.visit_expr(n),
}
}
+ fn visit_heading(v, node: &HeadingNode) {
+ v.visit_tree(&node.body);
+ }
+
+ fn visit_list(v, node: &ListNode) {
+ v.visit_tree(&node.body);
+ }
+
fn visit_expr(v, node: &Expr) {
match node {
Expr::None(_) => {}