diff --git a/examples/html-slugify.rs b/examples/html-slugify.rs
index 672ac09..5909731 100644
--- a/examples/html-slugify.rs
+++ b/examples/html-slugify.rs
@@ -3,12 +3,13 @@
//! ```
use orgize::{
- ast::HeadlineTitle,
+ ast::Headline,
export::{HtmlExport, TraversalContext, Traverser},
forward_handler,
- rowan::{ast::AstNode, WalkEvent},
+ rowan::WalkEvent,
Org,
};
+use rowan::NodeOrToken;
use slugify::slugify;
use std::cmp::min;
use std::env::args;
@@ -24,30 +25,31 @@ impl AsMut for MyHtmlHandler {
}
impl Traverser for MyHtmlHandler {
- fn headline_title(&mut self, event: WalkEvent<&HeadlineTitle>, _ctx: &mut TraversalContext) {
- match event {
- WalkEvent::Enter(title) => {
- let level = title.headline().map(|h| min(h.level(), 6)).unwrap_or(1);
- let raw = title.syntax().to_string();
- self.0.push_str(format!(
- "",
- slugify!(&raw)
- ));
- }
- WalkEvent::Leave(title) => {
- let level = title.headline().map(|h| min(h.level(), 6)).unwrap_or(1);
- self.0.push_str(format!(""));
+ fn headline(&mut self, event: WalkEvent<&Headline>, ctx: &mut TraversalContext) {
+ if let WalkEvent::Enter(headline) = event {
+ let level = min(headline.level(), 6);
+ let title = headline.title().map(|e| e.to_string()).collect::();
+ self.0.push_str(format!(
+ "",
+ slugify!(&title)
+ ));
+ for elem in headline.title() {
+ match elem {
+ NodeOrToken::Node(node) => self.node(node, ctx),
+ NodeOrToken::Token(token) => self.token(token, ctx),
+ }
}
+ self.0.push_str(format!(""));
}
}
forward_handler! {
HtmlExport,
- link text document headline paragraph section rule comment
- inline_src inline_call code bold verbatim italic strike underline list list_item list_item_tag
+ link text document paragraph section rule comment
+ inline_src inline_call code bold verbatim italic strike underline list list_item
special_block quote_block center_block verse_block comment_block example_block export_block
source_block babel_call clock cookie radio_target drawer dyn_block fn_def fn_ref macros
- snippet timestamp target fixed_width org_table org_table_row org_table_cell list_item_content
+ snippet timestamp target fixed_width org_table org_table_row org_table_cell
}
}
diff --git a/src/ast/generate.js b/src/ast/generate.js
index 8aca5bd..bd9ff54 100644
--- a/src/ast/generate.js
+++ b/src/ast/generate.js
@@ -25,7 +25,6 @@ const nodes = [
struct: "Headline",
kind: ["HEADLINE"],
first_child: [
- ["title", "HeadlineTitle"],
["section", "Section"],
["planning", "Planning"],
],
@@ -74,7 +73,6 @@ const nodes = [
{
struct: "ListItem",
kind: ["LIST_ITEM"],
- first_child: [["content", "ListItemContent"]],
},
{
struct: "Drawer",
diff --git a/src/ast/generated.rs b/src/ast/generated.rs
index 90c2554..68c796d 100644
--- a/src/ast/generated.rs
+++ b/src/ast/generated.rs
@@ -157,9 +157,6 @@ impl Headline {
pub fn keyword(&self) -> Option {
support::token(&self.syntax, HEADLINE_KEYWORD)
}
- pub fn title(&self) -> Option {
- support::child(&self.syntax)
- }
pub fn section(&self) -> Option {
support::child(&self.syntax)
}
@@ -449,115 +446,6 @@ impl ListItem {
pub fn end(&self) -> u32 {
self.syntax.text_range().end().into()
}
- pub fn indent(&self) -> Option {
- support::token(&self.syntax, LIST_ITEM_INDENT)
- }
- pub fn bullet(&self) -> Option {
- support::token(&self.syntax, LIST_ITEM_BULLET)
- }
- pub fn content(&self) -> Option {
- support::child(&self.syntax)
- }
-}
-
-#[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub struct ListItemIndent {
- pub(crate) syntax: SyntaxNode,
-}
-impl AstNode for ListItemIndent {
- type Language = OrgLanguage;
- fn can_cast(kind: SyntaxKind) -> bool {
- kind == LIST_ITEM_INDENT
- }
- fn cast(node: SyntaxNode) -> Option {
- Self::can_cast(node.kind()).then(|| ListItemIndent { syntax: node })
- }
- fn syntax(&self) -> &SyntaxNode {
- &self.syntax
- }
-}
-impl ListItemIndent {
- pub fn begin(&self) -> u32 {
- self.syntax.text_range().start().into()
- }
- pub fn end(&self) -> u32 {
- self.syntax.text_range().end().into()
- }
-}
-
-#[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub struct ListItemTag {
- pub(crate) syntax: SyntaxNode,
-}
-impl AstNode for ListItemTag {
- type Language = OrgLanguage;
- fn can_cast(kind: SyntaxKind) -> bool {
- kind == LIST_ITEM_TAG
- }
- fn cast(node: SyntaxNode) -> Option {
- Self::can_cast(node.kind()).then(|| ListItemTag { syntax: node })
- }
- fn syntax(&self) -> &SyntaxNode {
- &self.syntax
- }
-}
-impl ListItemTag {
- pub fn begin(&self) -> u32 {
- self.syntax.text_range().start().into()
- }
- pub fn end(&self) -> u32 {
- self.syntax.text_range().end().into()
- }
-}
-
-#[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub struct ListItemBullet {
- pub(crate) syntax: SyntaxNode,
-}
-impl AstNode for ListItemBullet {
- type Language = OrgLanguage;
- fn can_cast(kind: SyntaxKind) -> bool {
- kind == LIST_ITEM_BULLET
- }
- fn cast(node: SyntaxNode) -> Option {
- Self::can_cast(node.kind()).then(|| ListItemBullet { syntax: node })
- }
- fn syntax(&self) -> &SyntaxNode {
- &self.syntax
- }
-}
-impl ListItemBullet {
- pub fn begin(&self) -> u32 {
- self.syntax.text_range().start().into()
- }
- pub fn end(&self) -> u32 {
- self.syntax.text_range().end().into()
- }
-}
-
-#[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub struct ListItemContent {
- pub(crate) syntax: SyntaxNode,
-}
-impl AstNode for ListItemContent {
- type Language = OrgLanguage;
- fn can_cast(kind: SyntaxKind) -> bool {
- kind == LIST_ITEM_CONTENT
- }
- fn cast(node: SyntaxNode) -> Option {
- Self::can_cast(node.kind()).then(|| ListItemContent { syntax: node })
- }
- fn syntax(&self) -> &SyntaxNode {
- &self.syntax
- }
-}
-impl ListItemContent {
- pub fn begin(&self) -> u32 {
- self.syntax.text_range().start().into()
- }
- pub fn end(&self) -> u32 {
- self.syntax.text_range().end().into()
- }
}
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
@@ -1452,31 +1340,6 @@ impl FnRef {
}
}
-#[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub struct LatexEnvironment {
- pub(crate) syntax: SyntaxNode,
-}
-impl AstNode for LatexEnvironment {
- type Language = OrgLanguage;
- fn can_cast(kind: SyntaxKind) -> bool {
- kind == LATEX_ENVIRONMENT
- }
- fn cast(node: SyntaxNode) -> Option {
- Self::can_cast(node.kind()).then(|| LatexEnvironment { syntax: node })
- }
- fn syntax(&self) -> &SyntaxNode {
- &self.syntax
- }
-}
-impl LatexEnvironment {
- pub fn begin(&self) -> u32 {
- self.syntax.text_range().start().into()
- }
- pub fn end(&self) -> u32 {
- self.syntax.text_range().end().into()
- }
-}
-
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct Macros {
pub(crate) syntax: SyntaxNode,
diff --git a/src/ast/headline.rs b/src/ast/headline.rs
index cc274ed..296f699 100644
--- a/src/ast/headline.rs
+++ b/src/ast/headline.rs
@@ -1,4 +1,7 @@
-use crate::syntax::{SyntaxKind, SyntaxToken};
+use crate::{
+ syntax::{SyntaxKind, SyntaxToken},
+ SyntaxElement,
+};
use super::{filter_token, Headline, Timestamp};
@@ -24,6 +27,21 @@ impl Headline {
})
}
+ /// ```rust
+ /// use orgize::{Org, ast::Headline};
+ ///
+ /// let hdl = Org::parse("*** abc *abc* /abc/ :tag:").first_node::().unwrap();
+ /// let title = hdl.title().map(|n| n.to_string()).collect::();
+ /// assert_eq!(title, "abc *abc* /abc/ ");
+ /// ```
+ pub fn title(&self) -> impl Iterator- {
+ self.syntax
+ .children()
+ .find(|n| n.kind() == SyntaxKind::HEADLINE_TITLE)
+ .into_iter()
+ .flat_map(|n| n.children_with_tokens())
+ }
+
/// Return `true` if this headline contains a COMMENT keyword
///
/// ```rust
@@ -38,12 +56,16 @@ impl Headline {
/// ```
pub fn is_commented(&self) -> bool {
self.title()
- .and_then(|title| title.syntax.first_token())
- .map(|title| {
- let text = title.text();
- title.kind() == SyntaxKind::TEXT
- && text.starts_with("COMMENT")
- && (text.len() == 7 || text[7..].starts_with(char::is_whitespace))
+ .next()
+ .map(|first| {
+ if let Some(t) = first.as_token() {
+ let text = t.text();
+ t.kind() == SyntaxKind::TEXT
+ && text.starts_with("COMMENT")
+ && (text.len() == 7 || text[7..].starts_with(char::is_whitespace))
+ } else {
+ false
+ }
})
.unwrap_or_default()
}
diff --git a/src/ast/list.rs b/src/ast/list.rs
index 5a694c7..24e8258 100644
--- a/src/ast/list.rs
+++ b/src/ast/list.rs
@@ -1,55 +1,7 @@
-use super::{filter_token, List};
+use super::{filter_token, List, ListItem};
use crate::{syntax::SyntaxKind, SyntaxElement, SyntaxToken};
impl List {
- pub fn indent(&self) -> usize {
- self.syntax
- .children_with_tokens()
- .find_map(filter_token(SyntaxKind::LIST_ITEM_INDENT))
- .map(|t| t.text().len())
- .unwrap_or_else(|| {
- debug_assert!(false, "list must contains indent token");
- 0
- })
- }
-
- pub fn bullet(&self) -> Option {
- self.syntax
- .children_with_tokens()
- .find_map(filter_token(SyntaxKind::LIST_ITEM_BULLET))
- }
-
- pub fn checkbox(&self) -> Option {
- self.syntax
- .children()
- .find(|n| n.kind() == SyntaxKind::LIST_ITEM_CHECK_BOX)
- .and_then(|n| {
- n.children_with_tokens()
- .find_map(filter_token(SyntaxKind::TEXT))
- })
- }
-
- pub fn counter(&self) -> Option {
- self.syntax
- .children()
- .find(|n| n.kind() == SyntaxKind::LIST_ITEM_COUNTER)
- .and_then(|n| {
- n.children_with_tokens()
- .find_map(filter_token(SyntaxKind::TEXT))
- })
- }
-
- pub fn tag(&self) -> impl Iterator
- {
- self.syntax
- .children()
- .find(|n| n.kind() == SyntaxKind::LIST_ITEM_TAG)
- .into_iter()
- .flat_map(|n| {
- n.children_with_tokens()
- .filter(|n| n.kind() != SyntaxKind::COLON2)
- })
- }
-
/// Returns `true` if this list is an ordered link
///
/// ```rust
@@ -93,3 +45,87 @@ impl List {
.unwrap_or_default()
}
}
+
+impl ListItem {
+ /// ```rust
+ /// use orgize::{Org, ast::ListItem};
+ ///
+ /// let item = Org::parse("- 1").first_node::().unwrap();
+ /// assert_eq!(item.indent(), 0);
+ /// let item = Org::parse(" \t * 2").first_node::().unwrap();
+ /// assert_eq!(item.indent(), 3);
+ /// ```
+ pub fn indent(&self) -> usize {
+ self.syntax
+ .children_with_tokens()
+ .find_map(filter_token(SyntaxKind::LIST_ITEM_INDENT))
+ .map(|t| t.text().len())
+ .unwrap_or_else(|| {
+ debug_assert!(false, "list must contains indent token");
+ 0
+ })
+ }
+
+ /// ```rust
+ /// use orgize::{Org, ast::ListItem};
+ ///
+ /// let item = Org::parse("- some tag").first_node::().unwrap();
+ /// assert_eq!(item.bullet().unwrap().text(), "- ");
+ /// let item = Org::parse("2. [X] item 2").first_node::().unwrap();
+ /// assert_eq!(item.bullet().unwrap().text(), "2. ");
+ /// ```
+ pub fn bullet(&self) -> Option {
+ self.syntax
+ .children_with_tokens()
+ .find_map(filter_token(SyntaxKind::LIST_ITEM_BULLET))
+ }
+
+ /// ```rust
+ /// use orgize::{Org, ast::ListItem};
+ ///
+ /// let item = Org::parse("- [-] item 1").first_node::().unwrap();
+ /// assert_eq!(item.checkbox().unwrap().text(), "-");
+ /// let item = Org::parse("2. [X] item 2").first_node::().unwrap();
+ /// assert_eq!(item.checkbox().unwrap().text(), "X");
+ /// let item = Org::parse("3) [ ] item 3").first_node::().unwrap();
+ /// assert_eq!(item.checkbox().unwrap().text(), " ");
+ /// ```
+ pub fn checkbox(&self) -> Option {
+ self.syntax
+ .children()
+ .find(|n| n.kind() == SyntaxKind::LIST_ITEM_CHECK_BOX)
+ .and_then(|n| {
+ n.children_with_tokens()
+ .find_map(filter_token(SyntaxKind::TEXT))
+ })
+ }
+
+ pub fn counter(&self) -> Option {
+ self.syntax
+ .children()
+ .find(|n| n.kind() == SyntaxKind::LIST_ITEM_COUNTER)
+ .and_then(|n| {
+ n.children_with_tokens()
+ .find_map(filter_token(SyntaxKind::TEXT))
+ })
+ }
+
+ /// ```rust
+ /// use orgize::{Org, ast::ListItem};
+ ///
+ /// let item = Org::parse("+ this is *TAG* :: item1").first_node::().unwrap();
+ /// let tag = item.tag().map(|n| n.to_string()).collect::();
+ /// assert_eq!(tag, "this is *TAG* ");
+ /// ```
+ pub fn tag(&self) -> impl Iterator
- {
+ self.syntax
+ .children()
+ .find(|n| n.kind() == SyntaxKind::LIST_ITEM_TAG)
+ .into_iter()
+ .flat_map(|n| {
+ n.children_with_tokens().filter(|n| {
+ n.kind() != SyntaxKind::WHITESPACE && n.kind() != SyntaxKind::COLON2
+ })
+ })
+ }
+}
diff --git a/src/export/forward.rs b/src/export/forward.rs
index cfe87fc..4711ece 100644
--- a/src/export/forward.rs
+++ b/src/export/forward.rs
@@ -1,14 +1,13 @@
-/// Forward handler method implement to other handler
+/// Forward traverser method implement to other
///
-/// This macros is commonly used if you want to extend
-/// some builtin handlers like HtmlExport.
+/// Used to "extend" some builtin traverser like `HtmlExport`.
///
/// ```rust
/// use orgize::{
-/// ast::HeadlineTitle,
+/// ast::Headline,
/// export::{HtmlExport, TraversalContext, Traverser},
/// forward_handler,
-/// rowan::{ast::AstNode, WalkEvent},
+/// rowan::{ast::AstNode, WalkEvent, NodeOrToken},
/// Org,
/// };
/// use slugify::slugify;
@@ -25,27 +24,31 @@
/// }
///
/// impl Traverser for SlugifyTitleHandler {
-/// fn headline_title(&mut self, event: WalkEvent<&HeadlineTitle>, _ctx: &mut TraversalContext) {
-/// match event {
-/// WalkEvent::Enter(title) => {
-/// let level = title.headline().map(|h| min(h.level(), 6)).unwrap_or(1);
-/// let raw = title.syntax().to_string();
-/// self.0.push_str(format!("", slugify!(&raw)));
-/// }
-/// WalkEvent::Leave(title) => {
-/// let level = title.headline().map(|h| min(h.level(), 6)).unwrap_or(1);
-/// self.0.push_str(format!(""));
+/// fn headline(&mut self, event: WalkEvent<&Headline>, ctx: &mut TraversalContext) {
+/// if let WalkEvent::Enter(headline) = event {
+/// let level = min(headline.level(), 6);
+/// let title = headline.title().map(|e| e.to_string()).collect::();
+/// self.0.push_str(format!(
+/// "",
+/// slugify!(&title)
+/// ));
+/// for elem in headline.title() {
+/// match elem {
+/// NodeOrToken::Node(node) => self.node(node, ctx),
+/// NodeOrToken::Token(token) => self.token(token, ctx),
+/// }
/// }
+/// self.0.push_str(format!(""));
/// }
/// }
///
/// forward_handler! {
/// HtmlExport,
-/// link text document headline paragraph section rule comment
-/// inline_src inline_call code bold verbatim italic strike underline list list_item list_item_tag
+/// link text document paragraph section rule comment
+/// inline_src inline_call code bold verbatim italic strike underline list list_item
/// special_block quote_block center_block verse_block comment_block example_block export_block
/// source_block babel_call clock cookie radio_target drawer dyn_block fn_def fn_ref macros
-/// snippet timestamp target fixed_width org_table org_table_row org_table_cell list_item_content
+/// snippet timestamp target fixed_width org_table org_table_row org_table_cell
/// }
/// }
///
@@ -62,146 +65,137 @@ macro_rules! forward_handler {
};
(@method $handler:ty, text) => {
- forward_handler!(@method $handler, text, ::orgize::SyntaxToken);
+ forward_handler!(@method $handler, text, $crate::SyntaxToken);
};
(@method $handler:ty, document) => {
- forward_handler!(@method $handler, document, WalkEvent<&::orgize::ast::Document>);
+ forward_handler!(@method $handler, document, WalkEvent<&$crate::ast::Document>);
};
(@method $handler:ty, headline) => {
- forward_handler!(@method $handler, headline, WalkEvent<&::orgize::ast::Headline>);
+ forward_handler!(@method $handler, headline, WalkEvent<&$crate::ast::Headline>);
};
(@method $handler:ty, paragraph) => {
- forward_handler!(@method $handler, paragraph, WalkEvent<&::orgize::ast::Paragraph>);
+ forward_handler!(@method $handler, paragraph, WalkEvent<&$crate::ast::Paragraph>);
};
(@method $handler:ty, section) => {
- forward_handler!(@method $handler, section, WalkEvent<&::orgize::ast::Section>);
+ forward_handler!(@method $handler, section, WalkEvent<&$crate::ast::Section>);
};
(@method $handler:ty, rule) => {
- forward_handler!(@method $handler, rule, WalkEvent<&::orgize::ast::Rule>);
+ forward_handler!(@method $handler, rule, WalkEvent<&$crate::ast::Rule>);
};
(@method $handler:ty, comment) => {
- forward_handler!(@method $handler, comment, WalkEvent<&::orgize::ast::Comment>);
+ forward_handler!(@method $handler, comment, WalkEvent<&$crate::ast::Comment>);
};
(@method $handler:ty, inline_src) => {
- forward_handler!(@method $handler, inline_src, WalkEvent<&::orgize::ast::InlineSrc>);
+ forward_handler!(@method $handler, inline_src, WalkEvent<&$crate::ast::InlineSrc>);
};
(@method $handler:ty, inline_call) => {
- forward_handler!(@method $handler, inline_call, WalkEvent<&::orgize::ast::InlineCall>);
+ forward_handler!(@method $handler, inline_call, WalkEvent<&$crate::ast::InlineCall>);
};
(@method $handler:ty, code) => {
- forward_handler!(@method $handler, code, WalkEvent<&::orgize::ast::Code>);
+ forward_handler!(@method $handler, code, WalkEvent<&$crate::ast::Code>);
};
(@method $handler:ty, bold) => {
- forward_handler!(@method $handler, bold, WalkEvent<&::orgize::ast::Bold>);
+ forward_handler!(@method $handler, bold, WalkEvent<&$crate::ast::Bold>);
};
(@method $handler:ty, verbatim) => {
- forward_handler!(@method $handler, verbatim, WalkEvent<&::orgize::ast::Verbatim>);
+ forward_handler!(@method $handler, verbatim, WalkEvent<&$crate::ast::Verbatim>);
};
(@method $handler:ty, italic) => {
- forward_handler!(@method $handler, italic, WalkEvent<&::orgize::ast::Italic>);
+ forward_handler!(@method $handler, italic, WalkEvent<&$crate::ast::Italic>);
};
(@method $handler:ty, strike) => {
- forward_handler!(@method $handler, strike, WalkEvent<&::orgize::ast::Strike>);
+ forward_handler!(@method $handler, strike, WalkEvent<&$crate::ast::Strike>);
};
(@method $handler:ty, underline) => {
- forward_handler!(@method $handler, underline, WalkEvent<&::orgize::ast::Underline>);
+ forward_handler!(@method $handler, underline, WalkEvent<&$crate::ast::Underline>);
};
(@method $handler:ty, list) => {
- forward_handler!(@method $handler, list, WalkEvent<&::orgize::ast::List>);
+ forward_handler!(@method $handler, list, WalkEvent<&$crate::ast::List>);
};
(@method $handler:ty, list_item) => {
- forward_handler!(@method $handler, list_item, WalkEvent<&::orgize::ast::ListItem>);
- };
- (@method $handler:ty, list_item_tag) => {
- forward_handler!(@method $handler, list_item_tag, WalkEvent<&::orgize::ast::ListItemTag>);
- };
- (@method $handler:ty, list_item_content) => {
- forward_handler!(@method $handler, list_item_content, WalkEvent<&::orgize::ast::ListItemContent>);
+ forward_handler!(@method $handler, list_item, WalkEvent<&$crate::ast::ListItem>);
};
(@method $handler:ty, special_block) => {
- forward_handler!(@method $handler, special_block, WalkEvent<&::orgize::ast::SpecialBlock>);
+ forward_handler!(@method $handler, special_block, WalkEvent<&$crate::ast::SpecialBlock>);
};
(@method $handler:ty, quote_block) => {
- forward_handler!(@method $handler, quote_block, WalkEvent<&::orgize::ast::QuoteBlock>);
+ forward_handler!(@method $handler, quote_block, WalkEvent<&$crate::ast::QuoteBlock>);
};
(@method $handler:ty, center_block) => {
- forward_handler!(@method $handler, center_block, WalkEvent<&::orgize::ast::CenterBlock>);
+ forward_handler!(@method $handler, center_block, WalkEvent<&$crate::ast::CenterBlock>);
};
(@method $handler:ty, verse_block) => {
- forward_handler!(@method $handler, verse_block, WalkEvent<&::orgize::ast::VerseBlock>);
+ forward_handler!(@method $handler, verse_block, WalkEvent<&$crate::ast::VerseBlock>);
};
(@method $handler:ty, comment_block) => {
- forward_handler!(@method $handler, comment_block, WalkEvent<&::orgize::ast::CommentBlock>);
+ forward_handler!(@method $handler, comment_block, WalkEvent<&$crate::ast::CommentBlock>);
};
(@method $handler:ty, example_block) => {
- forward_handler!(@method $handler, example_block, WalkEvent<&::orgize::ast::ExampleBlock>);
+ forward_handler!(@method $handler, example_block, WalkEvent<&$crate::ast::ExampleBlock>);
};
(@method $handler:ty, export_block) => {
- forward_handler!(@method $handler, export_block, WalkEvent<&::orgize::ast::ExportBlock>);
+ forward_handler!(@method $handler, export_block, WalkEvent<&$crate::ast::ExportBlock>);
};
(@method $handler:ty, source_block) => {
- forward_handler!(@method $handler, source_block, WalkEvent<&::orgize::ast::SourceBlock>);
+ forward_handler!(@method $handler, source_block, WalkEvent<&$crate::ast::SourceBlock>);
};
(@method $handler:ty, babel_call) => {
- forward_handler!(@method $handler, babel_call, WalkEvent<&::orgize::ast::BabelCall>);
+ forward_handler!(@method $handler, babel_call, WalkEvent<&$crate::ast::BabelCall>);
};
(@method $handler:ty, clock) => {
- forward_handler!(@method $handler, clock, WalkEvent<&::orgize::ast::Clock>);
+ forward_handler!(@method $handler, clock, WalkEvent<&$crate::ast::Clock>);
};
(@method $handler:ty, cookie) => {
- forward_handler!(@method $handler, cookie, WalkEvent<&::orgize::ast::Cookie>);
+ forward_handler!(@method $handler, cookie, WalkEvent<&$crate::ast::Cookie>);
};
(@method $handler:ty, radio_target) => {
- forward_handler!(@method $handler, radio_target, WalkEvent<&::orgize::ast::RadioTarget>);
+ forward_handler!(@method $handler, radio_target, WalkEvent<&$crate::ast::RadioTarget>);
};
(@method $handler:ty, drawer) => {
- forward_handler!(@method $handler, drawer, WalkEvent<&::orgize::ast::Drawer>);
+ forward_handler!(@method $handler, drawer, WalkEvent<&$crate::ast::Drawer>);
};
(@method $handler:ty, dyn_block) => {
- forward_handler!(@method $handler, dyn_block, WalkEvent<&::orgize::ast::DynBlock>);
+ forward_handler!(@method $handler, dyn_block, WalkEvent<&$crate::ast::DynBlock>);
};
(@method $handler:ty, fn_def) => {
- forward_handler!(@method $handler, fn_def, WalkEvent<&::orgize::ast::FnDef>);
+ forward_handler!(@method $handler, fn_def, WalkEvent<&$crate::ast::FnDef>);
};
(@method $handler:ty, fn_ref) => {
- forward_handler!(@method $handler, fn_ref, WalkEvent<&::orgize::ast::FnRef>);
+ forward_handler!(@method $handler, fn_ref, WalkEvent<&$crate::ast::FnRef>);
};
(@method $handler:ty, macros) => {
- forward_handler!(@method $handler, macros, WalkEvent<&::orgize::ast::Macros>);
+ forward_handler!(@method $handler, macros, WalkEvent<&$crate::ast::Macros>);
};
(@method $handler:ty, snippet) => {
- forward_handler!(@method $handler, snippet, WalkEvent<&::orgize::ast::Snippet>);
+ forward_handler!(@method $handler, snippet, WalkEvent<&$crate::ast::Snippet>);
};
(@method $handler:ty, timestamp) => {
- forward_handler!(@method $handler, timestamp, WalkEvent<&::orgize::ast::Timestamp>);
+ forward_handler!(@method $handler, timestamp, WalkEvent<&$crate::ast::Timestamp>);
};
(@method $handler:ty, target) => {
- forward_handler!(@method $handler, target, WalkEvent<&::orgize::ast::Target>);
+ forward_handler!(@method $handler, target, WalkEvent<&$crate::ast::Target>);
};
(@method $handler:ty, fixed_width) => {
- forward_handler!(@method $handler, fixed_width, WalkEvent<&::orgize::ast::FixedWidth>);
- };
- (@method $handler:ty, headline_title) => {
- forward_handler!(@method $handler, headline_title, WalkEvent<&::orgize::ast::HeadlineTitle>);
+ forward_handler!(@method $handler, fixed_width, WalkEvent<&$crate::ast::FixedWidth>);
};
(@method $handler:ty, org_table) => {
- forward_handler!(@method $handler, org_table, WalkEvent<&::orgize::ast::OrgTable>);
+ forward_handler!(@method $handler, org_table, WalkEvent<&$crate::ast::OrgTable>);
};
(@method $handler:ty, org_table_row) => {
- forward_handler!(@method $handler, org_table_row, WalkEvent<&::orgize::ast::OrgTableRow>);
+ forward_handler!(@method $handler, org_table_row, WalkEvent<&$crate::ast::OrgTableRow>);
};
(@method $handler:ty, org_table_cell) => {
- forward_handler!(@method $handler, org_table_cell, WalkEvent<&::orgize::ast::OrgTableCell>);
+ forward_handler!(@method $handler, org_table_cell, WalkEvent<&$crate::ast::OrgTableCell>);
};
(@method $handler:ty, link) => {
- forward_handler!(@method $handler, link, WalkEvent<&::orgize::ast::Link>);
+ forward_handler!(@method $handler, link, WalkEvent<&$crate::ast::Link>);
};
(@method $handler:ty, $x:ident) => {
std::compile_error!(std::concat!(std::stringify!($x), " is not a method"));
};
(@method $handler:ty, $name:ident, $type:ty) => {
- fn $name(&mut self, item: $type, ctx: &mut ::orgize::export::TraversalContext) {
+ fn $name(&mut self, item: $type, ctx: &mut $crate::export::TraversalContext) {
>::as_mut(self).$name(item, ctx)
}
};
diff --git a/src/export/html.rs b/src/export/html.rs
index df894f7..5efba73 100644
--- a/src/export/html.rs
+++ b/src/export/html.rs
@@ -1,4 +1,4 @@
-use rowan::WalkEvent;
+use rowan::{NodeOrToken, WalkEvent};
use std::cmp::min;
use std::fmt;
@@ -116,36 +116,26 @@ impl Traverser for HtmlExport {
};
}
- #[tracing::instrument(skip(self, _ctx))]
- fn list_item(&mut self, event: WalkEvent<&ListItem>, _ctx: &mut TraversalContext) {
- if !self.in_descriptive_list.last().copied().unwrap_or_default() {
- self.output += match event {
- WalkEvent::Enter(_) => "",
- WalkEvent::Leave(_) => "",
- };
- }
- }
-
- #[tracing::instrument(skip(self, _ctx))]
- fn list_item_content(
- &mut self,
- event: WalkEvent<&ListItemContent>,
- _ctx: &mut TraversalContext,
- ) {
+ #[tracing::instrument(skip(self, ctx))]
+ fn list_item(&mut self, event: WalkEvent<&ListItem>, ctx: &mut TraversalContext) {
if self.in_descriptive_list.last().copied().unwrap_or_default() {
- self.output += match event {
- WalkEvent::Enter(_) => "",
- WalkEvent::Leave(_) => "",
+ match event {
+ WalkEvent::Enter(item) => {
+ self.output += "";
+ for elem in item.tag() {
+ match elem {
+ NodeOrToken::Node(n) => self.node(n, ctx),
+ NodeOrToken::Token(t) => self.token(t, ctx),
+ }
+ }
+ self.output += "";
+ }
+ WalkEvent::Leave(_) => self.output += "",
};
- }
- }
-
- #[tracing::instrument(skip(self, _ctx))]
- fn list_item_tag(&mut self, event: WalkEvent<&ListItemTag>, _ctx: &mut TraversalContext) {
- if self.in_descriptive_list.last().copied().unwrap_or_default() {
- self.output += match event {
- WalkEvent::Enter(_) => "",
- WalkEvent::Leave(_) => "",
+ } else {
+ match event {
+ WalkEvent::Enter(_) => self.output += "",
+ WalkEvent::Leave(_) => self.output += "",
};
}
}
@@ -185,20 +175,6 @@ impl Traverser for HtmlExport {
};
}
- #[tracing::instrument(skip(self, _ctx))]
- fn headline_title(&mut self, event: WalkEvent<&HeadlineTitle>, _ctx: &mut TraversalContext) {
- self.output += &match event {
- WalkEvent::Enter(title) => {
- let level = title.headline().map(|h| min(h.level(), 6)).unwrap_or(1);
- format!("")
- }
- WalkEvent::Leave(title) => {
- let level = title.headline().map(|h| min(h.level(), 6)).unwrap_or(1);
- format!("")
- }
- };
- }
-
#[tracing::instrument(skip(self, _ctx))]
fn italic(&mut self, event: WalkEvent<&Italic>, _ctx: &mut TraversalContext) {
self.output += match event {
@@ -403,8 +379,20 @@ impl Traverser for HtmlExport {
};
}
- #[tracing::instrument(skip(self, _ctx))]
- fn headline(&mut self, _event: WalkEvent<&Headline>, _ctx: &mut TraversalContext) {}
+ #[tracing::instrument(skip(self, ctx))]
+ fn headline(&mut self, event: WalkEvent<&Headline>, ctx: &mut TraversalContext) {
+ if let WalkEvent::Enter(headline) = event {
+ let level = min(headline.level(), 6);
+ self.output += &format!("");
+ for elem in headline.title() {
+ match elem {
+ NodeOrToken::Node(node) => self.node(node, ctx),
+ NodeOrToken::Token(token) => self.token(token, ctx),
+ }
+ }
+ self.output += &format!("");
+ }
+ }
#[tracing::instrument(skip(self, _ctx))]
fn inline_src(&mut self, _event: WalkEvent<&InlineSrc>, _ctx: &mut TraversalContext) {}
diff --git a/src/export/traverse.rs b/src/export/traverse.rs
index 9c035b2..3956d0c 100644
--- a/src/export/traverse.rs
+++ b/src/export/traverse.rs
@@ -63,15 +63,19 @@ impl TraversalContext {
///
/// Each handle method can returns a `TraversalControl` to control the traversal.
pub trait Traverser {
+ fn element(&mut self, element: SyntaxElement, ctx: &mut TraversalContext) {
+ match element {
+ SyntaxElement::Node(node) => self.node(node, ctx),
+ SyntaxElement::Token(token) => self.token(token, ctx),
+ };
+ }
+
/// Called when visiting any node
fn node(&mut self, node: SyntaxNode, ctx: &mut TraversalContext) {
macro_rules! traverse_children {
($node:expr) => {{
for child in $node.children_with_tokens() {
- match child {
- SyntaxElement::Node(node) => self.node(node, ctx),
- SyntaxElement::Token(token) => self.token(token, ctx),
- };
+ self.element(child, ctx);
take_control!(ctx);
}
}};
@@ -100,8 +104,6 @@ pub trait Traverser {
UNDERLINE => traverse!(Underline, underline),
LIST => traverse!(List, list),
LIST_ITEM => traverse!(ListItem, list_item),
- LIST_ITEM_CONTENT => traverse!(ListItemContent, list_item_content),
- LIST_ITEM_TAG => traverse!(ListItemTag, list_item_tag),
CODE => traverse!(Code, code),
INLINE_CALL => traverse!(InlineCall, inline_call),
INLINE_SRC => traverse!(InlineSrc, inline_src),
@@ -131,13 +133,12 @@ pub trait Traverser {
TARGET => traverse!(Target, target),
COMMENT => traverse!(Comment, comment),
FIXED_WIDTH => traverse!(FixedWidth, fixed_width),
- HEADLINE_TITLE => traverse!(HeadlineTitle, headline_title),
ORG_TABLE => traverse!(OrgTable, org_table),
ORG_TABLE_RULE_ROW | ORG_TABLE_STANDARD_ROW => traverse!(OrgTableRow, org_table_row),
ORG_TABLE_CELL => traverse!(OrgTableCell, org_table_cell),
LINK => traverse!(Link, link),
- BLOCK_CONTENT => traverse_children!(node),
+ BLOCK_CONTENT | LIST_ITEM_CONTENT => traverse_children!(node),
_ => {}
}
@@ -185,14 +186,6 @@ pub trait Traverser {
fn list(&mut self, _event: WalkEvent<&List>, _ctx: &mut TraversalContext);
/// Called when entering or leaving `ListItem` node
fn list_item(&mut self, _event: WalkEvent<&ListItem>, _ctx: &mut TraversalContext);
- /// Called when entering or leaving `ListItemTag` node
- fn list_item_tag(&mut self, _event: WalkEvent<&ListItemTag>, _ctx: &mut TraversalContext);
- /// Called when entering or leaving `ListItemContent` node
- fn list_item_content(
- &mut self,
- _event: WalkEvent<&ListItemContent>,
- _ctx: &mut TraversalContext,
- );
/// Called when entering or leaving `SpecialBlock` node
fn special_block(&mut self, _event: WalkEvent<&SpecialBlock>, _ctx: &mut TraversalContext);
/// Called when entering or leaving `QuoteBlock` node
@@ -235,8 +228,6 @@ pub trait Traverser {
fn target(&mut self, _event: WalkEvent<&Target>, _ctx: &mut TraversalContext);
/// Called when entering or leaving `FixedWidth` node
fn fixed_width(&mut self, _event: WalkEvent<&FixedWidth>, _ctx: &mut TraversalContext);
- /// Called when entering or leaving `HeadlineTitle` node
- fn headline_title(&mut self, _event: WalkEvent<&HeadlineTitle>, _ctx: &mut TraversalContext);
/// Called when entering or leaving `OrgTable` node
fn org_table(&mut self, _event: WalkEvent<&OrgTable>, _ctx: &mut TraversalContext);
/// Called when entering or leaving `OrgTableRow` node