feat: various update
This commit is contained in:
parent
be32dc24e0
commit
3c2c8b28fd
7 changed files with 73 additions and 54 deletions
|
|
@ -30,6 +30,7 @@ curl -q https://orgmode.org/worg/org-faq.org --output ./benches/org-faq.org
|
|||
curl -q https://orgmode.org/worg/org-hacks.org --output ./benches/org-hacks.org
|
||||
curl -q https://orgmode.org/worg/org-release-notes.org --output ./benches/org-release-notes.org
|
||||
curl -q https://orgmode.org/worg/org-syntax.org --output ./benches/org-syntax.org
|
||||
curl -q https://raw.githubusercontent.com/bzg/org-mode/main/doc/org-manual.org --output ./benches/org-manual.org
|
||||
|
||||
cargo bench --bench parse
|
||||
```
|
||||
|
|
|
|||
|
|
@ -9,7 +9,6 @@ use orgize::{
|
|||
rowan::WalkEvent,
|
||||
Org,
|
||||
};
|
||||
use rowan::NodeOrToken;
|
||||
use slugify::slugify;
|
||||
use std::cmp::min;
|
||||
use std::env::args;
|
||||
|
|
@ -34,10 +33,7 @@ impl Traverser for MyHtmlHandler {
|
|||
slugify!(&title)
|
||||
));
|
||||
for elem in headline.title() {
|
||||
match elem {
|
||||
NodeOrToken::Node(node) => self.node(node, ctx),
|
||||
NodeOrToken::Token(token) => self.token(token, ctx),
|
||||
}
|
||||
self.element(elem, ctx);
|
||||
}
|
||||
self.0.push_str(format!("</a></h{level}>"));
|
||||
}
|
||||
|
|
@ -50,7 +46,7 @@ impl Traverser for MyHtmlHandler {
|
|||
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 latex_fragment
|
||||
latex_environment entity line_break superscript subscript
|
||||
latex_environment entity line_break superscript subscript keyword property_drawer
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@
|
|||
/// ast::Headline,
|
||||
/// export::{HtmlExport, TraversalContext, Traverser},
|
||||
/// forward_handler,
|
||||
/// rowan::{ast::AstNode, WalkEvent, NodeOrToken},
|
||||
/// rowan::{ast::AstNode, WalkEvent},
|
||||
/// Org,
|
||||
/// };
|
||||
/// use slugify::slugify;
|
||||
|
|
@ -33,10 +33,7 @@
|
|||
/// slugify!(&title)
|
||||
/// ));
|
||||
/// for elem in headline.title() {
|
||||
/// match elem {
|
||||
/// NodeOrToken::Node(node) => self.node(node, ctx),
|
||||
/// NodeOrToken::Token(token) => self.token(token, ctx),
|
||||
/// }
|
||||
/// self.element(elem, ctx);
|
||||
/// }
|
||||
/// self.0.push_str(format!("</a></h{level}>"));
|
||||
/// }
|
||||
|
|
@ -49,7 +46,7 @@
|
|||
/// 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 latex_fragment
|
||||
/// latex_environment entity line_break superscript subscript
|
||||
/// latex_environment entity line_break superscript subscript keyword property_drawer
|
||||
/// }
|
||||
/// }
|
||||
///
|
||||
|
|
@ -209,6 +206,12 @@ macro_rules! forward_handler {
|
|||
(@method $handler:ty, subscript) => {
|
||||
forward_handler!(@method $handler, subscript, WalkEvent<&$crate::ast::Subscript>);
|
||||
};
|
||||
(@method $handler:ty, keyword) => {
|
||||
forward_handler!(@method $handler, keyword, WalkEvent<&$crate::ast::Keyword>);
|
||||
};
|
||||
(@method $handler:ty, property_drawer) => {
|
||||
forward_handler!(@method $handler, property_drawer, WalkEvent<&$crate::ast::PropertyDrawer>);
|
||||
};
|
||||
(@method $handler:ty, $x:ident) => {
|
||||
std::compile_error!(std::concat!(std::stringify!($x), " is not a method"));
|
||||
};
|
||||
|
|
|
|||
|
|
@ -125,10 +125,7 @@ impl Traverser for HtmlExport {
|
|||
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.element(elem, ctx);
|
||||
}
|
||||
self.output += "</dt><dd>";
|
||||
}
|
||||
|
|
@ -379,10 +376,7 @@ impl Traverser for HtmlExport {
|
|||
let level = min(headline.level(), 6);
|
||||
let _ = write!(&mut self.output, "<h{level}>");
|
||||
for elem in headline.title() {
|
||||
match elem {
|
||||
NodeOrToken::Node(node) => self.node(node, ctx),
|
||||
NodeOrToken::Token(token) => self.token(token, ctx),
|
||||
}
|
||||
self.element(elem, ctx);
|
||||
}
|
||||
let _ = write!(&mut self.output, "</h{level}>");
|
||||
}
|
||||
|
|
@ -534,4 +528,14 @@ impl Traverser for HtmlExport {
|
|||
WalkEvent::Leave(_) => self.output += "</sup>",
|
||||
}
|
||||
}
|
||||
|
||||
#[tracing::instrument(skip(self, ctx))]
|
||||
fn keyword(&mut self, _event: WalkEvent<&Keyword>, ctx: &mut TraversalContext) {
|
||||
ctx.skip();
|
||||
}
|
||||
|
||||
#[tracing::instrument(skip(self, ctx))]
|
||||
fn property_drawer(&mut self, _event: WalkEvent<&PropertyDrawer>, ctx: &mut TraversalContext) {
|
||||
ctx.skip()
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -143,10 +143,16 @@ pub trait Traverser {
|
|||
LINE_BREAK => traverse!(LineBreak, line_break),
|
||||
SUPERSCRIPT => traverse!(Superscript, superscript),
|
||||
SUBSCRIPT => traverse!(Subscript, subscript),
|
||||
KEYWORD => traverse!(Keyword, keyword),
|
||||
PROPERTY_DRAWER => traverse!(PropertyDrawer, property_drawer),
|
||||
|
||||
BLOCK_CONTENT | LIST_ITEM_CONTENT => traverse_children!(node),
|
||||
|
||||
kind => debug_assert!(!kind.is_element() && !kind.is_object()),
|
||||
kind => debug_assert!(
|
||||
!kind.is_element() && !kind.is_object(),
|
||||
"{:?} is not handled",
|
||||
kind
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -258,4 +264,8 @@ pub trait Traverser {
|
|||
fn superscript(&mut self, event: WalkEvent<&Superscript>, ctx: &mut TraversalContext);
|
||||
/// Called when entering or leaving `Subscript` node
|
||||
fn subscript(&mut self, event: WalkEvent<&Subscript>, ctx: &mut TraversalContext);
|
||||
/// Called when entering or leaving `Keyword` node
|
||||
fn keyword(&mut self, event: WalkEvent<&Keyword>, ctx: &mut TraversalContext);
|
||||
/// Called when entering or leaving `PropertyDrawer` node
|
||||
fn property_drawer(&mut self, event: WalkEvent<&PropertyDrawer>, ctx: &mut TraversalContext);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -133,11 +133,8 @@ fn headline_stars(input: Input) -> IResult<Input, Input, ()> {
|
|||
if level == 0 {
|
||||
return Err(nom::Err::Error(()));
|
||||
}
|
||||
// followed by eof, new line, or whitespace
|
||||
else if matches!(
|
||||
bytes.get(level),
|
||||
None | Some(b'\n') | Some(b'\r') | Some(b' ')
|
||||
) {
|
||||
// headline stars must be followed by space
|
||||
else if matches!(bytes.get(level), Some(b' ')) {
|
||||
Ok(input.take_split(level))
|
||||
} else {
|
||||
Err(nom::Err::Error(()))
|
||||
|
|
@ -232,7 +229,7 @@ fn headline_priority_node(input: Input) -> IResult<Input, (GreenElement, Input),
|
|||
|
||||
#[test]
|
||||
fn parse() {
|
||||
use crate::{ast::Headline, tests::to_ast};
|
||||
use crate::{ast::Headline, tests::to_ast, ParseConfig};
|
||||
|
||||
let to_headline = to_ast::<Headline>(headline_node);
|
||||
|
||||
|
|
@ -307,6 +304,16 @@ fn parse() {
|
|||
NEW_LINE@11..12 "\n"
|
||||
"###
|
||||
);
|
||||
|
||||
let config = &ParseConfig::default();
|
||||
|
||||
assert!(headline_node(("_ ", config).into()).is_err());
|
||||
assert!(headline_node(("*", config).into()).is_err());
|
||||
assert!(headline_node((" * ", config).into()).is_err());
|
||||
assert!(headline_node(("**", config).into()).is_err());
|
||||
assert!(headline_node(("**\n", config).into()).is_err());
|
||||
assert!(headline_node(("**\r", config).into()).is_err());
|
||||
assert!(headline_node(("**\t", config).into()).is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ use memchr::{memchr, memchr2};
|
|||
use nom::{
|
||||
branch::alt,
|
||||
bytes::complete::{tag, take},
|
||||
character::complete::{alphanumeric1, digit1, space0},
|
||||
character::complete::{alphanumeric1, digit1, space0, space1},
|
||||
combinator::{cond, map, opt, recognize, verify},
|
||||
sequence::{preceded, tuple},
|
||||
AsBytes, IResult, InputLength, InputTake,
|
||||
|
|
@ -10,7 +10,7 @@ use nom::{
|
|||
|
||||
use super::{
|
||||
combinator::{
|
||||
at_token, blank_lines, colon2_token, l_bracket_token, line_starts_iter, node,
|
||||
at_token, blank_lines, colon2_token, eol_or_eof, l_bracket_token, line_starts_iter, node,
|
||||
r_bracket_token, GreenElement,
|
||||
},
|
||||
element::element_node,
|
||||
|
|
@ -82,25 +82,23 @@ fn list_item_node<'a>(
|
|||
preceded(digit1, tag(".")),
|
||||
preceded(digit1, tag(")")),
|
||||
)),
|
||||
space0,
|
||||
alt((space1, eol_or_eof)),
|
||||
)))(input)?;
|
||||
|
||||
// bullet must ends with whitespace,
|
||||
if !(bullet
|
||||
.s
|
||||
.bytes()
|
||||
.last()
|
||||
.map(|b| b == b' ' || b == b'\t')
|
||||
.unwrap_or(true)
|
||||
// or input should be a line end
|
||||
|| input
|
||||
.s
|
||||
.bytes()
|
||||
.next()
|
||||
.map(|b| b == b'\r' || b == b'\n')
|
||||
.unwrap_or(true))
|
||||
{
|
||||
return Err(nom::Err::Error(()));
|
||||
if input.is_empty() {
|
||||
return Ok((
|
||||
input,
|
||||
(
|
||||
false,
|
||||
node(
|
||||
LIST_ITEM,
|
||||
[
|
||||
indent.token(LIST_ITEM_INDENT),
|
||||
bullet.token(LIST_ITEM_BULLET),
|
||||
],
|
||||
),
|
||||
),
|
||||
));
|
||||
}
|
||||
|
||||
let is_ordered = bullet.s.starts_with(|c: char| c.is_ascii_digit());
|
||||
|
|
@ -289,8 +287,6 @@ fn parse() {
|
|||
LIST_ITEM@0..2
|
||||
LIST_ITEM_INDENT@0..0 ""
|
||||
LIST_ITEM_BULLET@0..2 "1)"
|
||||
LIST_ITEM_CONTENT@2..2
|
||||
PARAGRAPH@2..2
|
||||
"###
|
||||
);
|
||||
|
||||
|
|
@ -301,8 +297,6 @@ fn parse() {
|
|||
LIST_ITEM@0..2
|
||||
LIST_ITEM_INDENT@0..0 ""
|
||||
LIST_ITEM_BULLET@0..2 "+ "
|
||||
LIST_ITEM_CONTENT@2..2
|
||||
PARAGRAPH@2..2
|
||||
"###
|
||||
);
|
||||
|
||||
|
|
@ -312,10 +306,7 @@ fn parse() {
|
|||
LIST@0..2
|
||||
LIST_ITEM@0..2
|
||||
LIST_ITEM_INDENT@0..0 ""
|
||||
LIST_ITEM_BULLET@0..1 "-"
|
||||
LIST_ITEM_CONTENT@1..2
|
||||
PARAGRAPH@1..2
|
||||
BLANK_LINE@1..2 "\n"
|
||||
LIST_ITEM_BULLET@0..2 "-\n"
|
||||
"###
|
||||
);
|
||||
|
||||
|
|
@ -594,6 +585,13 @@ fn parse() {
|
|||
"###
|
||||
);
|
||||
|
||||
to_list("- ");
|
||||
to_list("-\t");
|
||||
to_list("-\r");
|
||||
to_list("-\t\n");
|
||||
to_list("-\r\n");
|
||||
to_list("-");
|
||||
|
||||
let config = &ParseConfig::default();
|
||||
|
||||
assert!(list_node(("-a", config).into()).is_err());
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue