refactor: remove HeadlineTitle, ListItemTag, ListItemContent
This commit is contained in:
parent
d81c1a2966
commit
12bee6fb6b
8 changed files with 240 additions and 346 deletions
|
|
@ -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",
|
||||
|
|
|
|||
|
|
@ -157,9 +157,6 @@ impl Headline {
|
|||
pub fn keyword(&self) -> Option<SyntaxToken> {
|
||||
support::token(&self.syntax, HEADLINE_KEYWORD)
|
||||
}
|
||||
pub fn title(&self) -> Option<HeadlineTitle> {
|
||||
support::child(&self.syntax)
|
||||
}
|
||||
pub fn section(&self) -> Option<Section> {
|
||||
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<SyntaxToken> {
|
||||
support::token(&self.syntax, LIST_ITEM_INDENT)
|
||||
}
|
||||
pub fn bullet(&self) -> Option<SyntaxToken> {
|
||||
support::token(&self.syntax, LIST_ITEM_BULLET)
|
||||
}
|
||||
pub fn content(&self) -> Option<ListItemContent> {
|
||||
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<ListItemIndent> {
|
||||
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<ListItemTag> {
|
||||
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<ListItemBullet> {
|
||||
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<ListItemContent> {
|
||||
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<LatexEnvironment> {
|
||||
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,
|
||||
|
|
|
|||
|
|
@ -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::<Headline>().unwrap();
|
||||
/// let title = hdl.title().map(|n| n.to_string()).collect::<String>();
|
||||
/// assert_eq!(title, "abc *abc* /abc/ ");
|
||||
/// ```
|
||||
pub fn title(&self) -> impl Iterator<Item = SyntaxElement> {
|
||||
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()
|
||||
}
|
||||
|
|
|
|||
134
src/ast/list.rs
134
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<SyntaxToken> {
|
||||
self.syntax
|
||||
.children_with_tokens()
|
||||
.find_map(filter_token(SyntaxKind::LIST_ITEM_BULLET))
|
||||
}
|
||||
|
||||
pub fn checkbox(&self) -> Option<SyntaxToken> {
|
||||
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<SyntaxToken> {
|
||||
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<Item = SyntaxElement> {
|
||||
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::<ListItem>().unwrap();
|
||||
/// assert_eq!(item.indent(), 0);
|
||||
/// let item = Org::parse(" \t * 2").first_node::<ListItem>().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::<ListItem>().unwrap();
|
||||
/// assert_eq!(item.bullet().unwrap().text(), "- ");
|
||||
/// let item = Org::parse("2. [X] item 2").first_node::<ListItem>().unwrap();
|
||||
/// assert_eq!(item.bullet().unwrap().text(), "2. ");
|
||||
/// ```
|
||||
pub fn bullet(&self) -> Option<SyntaxToken> {
|
||||
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::<ListItem>().unwrap();
|
||||
/// assert_eq!(item.checkbox().unwrap().text(), "-");
|
||||
/// let item = Org::parse("2. [X] item 2").first_node::<ListItem>().unwrap();
|
||||
/// assert_eq!(item.checkbox().unwrap().text(), "X");
|
||||
/// let item = Org::parse("3) [ ] item 3").first_node::<ListItem>().unwrap();
|
||||
/// assert_eq!(item.checkbox().unwrap().text(), " ");
|
||||
/// ```
|
||||
pub fn checkbox(&self) -> Option<SyntaxToken> {
|
||||
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<SyntaxToken> {
|
||||
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::<ListItem>().unwrap();
|
||||
/// let tag = item.tag().map(|n| n.to_string()).collect::<String>();
|
||||
/// assert_eq!(tag, "this is *TAG* ");
|
||||
/// ```
|
||||
pub fn tag(&self) -> impl Iterator<Item = SyntaxElement> {
|
||||
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
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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!("<h{level}><a id=\"{0}\" href=\"#{0}\">", slugify!(&raw)));
|
||||
/// }
|
||||
/// WalkEvent::Leave(title) => {
|
||||
/// let level = title.headline().map(|h| min(h.level(), 6)).unwrap_or(1);
|
||||
/// self.0.push_str(format!("</a></h{level}>"));
|
||||
/// 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::<String>();
|
||||
/// self.0.push_str(format!(
|
||||
/// "<h{level}><a id=\"{0}\" href=\"#{0}\">",
|
||||
/// 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!("</a></h{level}>"));
|
||||
/// }
|
||||
/// }
|
||||
///
|
||||
/// 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) {
|
||||
<Self as AsMut<$handler>>::as_mut(self).$name(item, ctx)
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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(_) => "<li>",
|
||||
WalkEvent::Leave(_) => "</li>",
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#[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(_) => "<dd>",
|
||||
WalkEvent::Leave(_) => "</dd>",
|
||||
match event {
|
||||
WalkEvent::Enter(item) => {
|
||||
self.output += "<dt>";
|
||||
for elem in item.tag() {
|
||||
match elem {
|
||||
NodeOrToken::Node(n) => self.node(n, ctx),
|
||||
NodeOrToken::Token(t) => self.token(t, ctx),
|
||||
}
|
||||
}
|
||||
self.output += "</dt><dd>";
|
||||
}
|
||||
WalkEvent::Leave(_) => self.output += "</dd>",
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#[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(_) => "<dt>",
|
||||
WalkEvent::Leave(_) => "</dt>",
|
||||
} else {
|
||||
match event {
|
||||
WalkEvent::Enter(_) => self.output += "<li>",
|
||||
WalkEvent::Leave(_) => self.output += "</li>",
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
@ -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!("<h{level}>")
|
||||
}
|
||||
WalkEvent::Leave(title) => {
|
||||
let level = title.headline().map(|h| min(h.level(), 6)).unwrap_or(1);
|
||||
format!("</h{level}>")
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#[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!("<h{level}>");
|
||||
for elem in headline.title() {
|
||||
match elem {
|
||||
NodeOrToken::Node(node) => self.node(node, ctx),
|
||||
NodeOrToken::Token(token) => self.token(token, ctx),
|
||||
}
|
||||
}
|
||||
self.output += &format!("</h{level}>");
|
||||
}
|
||||
}
|
||||
|
||||
#[tracing::instrument(skip(self, _ctx))]
|
||||
fn inline_src(&mut self, _event: WalkEvent<&InlineSrc>, _ctx: &mut TraversalContext) {}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue