-
Notifications
You must be signed in to change notification settings - Fork 36
Announcing v0.10 #70
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
I had closed some outdated issues and pull requests, and what remains is mostly about adding new feature: support repeater/delay in timestamp:
support latex environment:
support org entities: and bug about handling special type of whitespace: |
Hey PoiScript. Thanks for the update. I've forked orgize to add a few things I needed, so I'd love to get them into 0.10. You've fixed the exporter need I have w/ the You can see my expected use-case here: https://github.com/justinabrahms/org-roam-to-subtext/blob/main/src/main.rs#L65-L72 I need to know if I'm within a quote so I can prefix Text lines with This was my commit which added it to the older code base: 8f66d5c |
hi @justinabrahms, it's possible to access the ancestors of parsed element by using some low-level apis in rowan: use orgize::SyntaxKind;
fn text(&mut self, token: SyntaxToken, _ctx: &mut TraversalContext) {
let inside_quote = token
.parent_ancestors()
.any(|n| n.kind() == SyntaxKind::QUOTE_BLOCK);
// ...
} but it's not performant for your use case, since you have to check ancestors in each pub struct MyTraverser {
inside_quote: bool
}
fn text(&mut self, token: SyntaxToken, _ctx: &mut TraversalContext) {
self.inside_quote
// ...
}
fn quote_block(&mut self, event: WalkEvent<&QuoteBlock>, _ctx: &mut TraversalContext) {
self.inside_quote = matches!(event, WalkEvent::Enter(_));
} |
So I've spent a bit of time this morning attempting to convert my tool to v0.10. Some observations:
|
hi, @justinabrahms, thanks for the feedback! I also find out it's tedious to impl And now it should be pretty straightforward to create a plain text format: struct PlainText(String);
impl Traverser for PlainText {
fn event(&mut self, event: Event, ctx: &mut TraversalContext) {
if let Event::Text(text) = event {
self.0 += text.text();
}
}
}
We re-export
You cannot call |
@PoiScript I've picked this back up and have tried to get it working, but I can't get it to 100%. The parsing changes do feel better, so thank you. I'm unclear how to print out the AST of what the system thinks my document structure is. I need this for debugging. The main problem is all of the In a similar vein, you've removed the ability for me to look at the ancestry of my node b/c I no longer get a SyntaxToken in the The API for |
You can import the
Also, you use the demo website: https://poiscript.github.io/orgize/, the structure of you input will be shown under the 'Syntax' tab
I don't really get it, did you mean the
Headline title can contain other elements, like bold and italic. So |
Wild. I've never seen an import change the behavior like that, though I'm a rust newbie. This is the error I was getting otherwise. Do you know the search term for what this pattern is called so I can learn more?
I'm good now. I don't think I realized that the text element was being passed a rowan::SyntaxToken.
I don't think you need to add this. I forgot that headlines in org were rich so this makes sense now. <3 I'm a happy camper now. Thanks for your patience. |
The pattern is just rust's traits, in this case there is a trait called |
thank @rynoV for explaining! I actually don't have such problem when writing rust code, since rust-analyzer should be smart enough for locating and importing trait you want: ![]() |
I find the removal of the |
@gmemstr I'm not sure exactly what use orgize::{Org, ast::Keyword};
use rowan::ast::{support, AstNode};
let org = Org::parse("#+KEY1: VALUE1\n#+KEY2: VALUE2\nabc");
let keywords: Vec<Keyword> =
support::children::<Keyword>(org.document().section().expect("No section").syntax()).collect();
assert_eq!(keywords.len(), 2);
assert_eq!(keywords[0].key(), "KEY1");
assert_eq!(keywords[0].value(), " VALUE1");
assert_eq!(keywords[1].key(), "KEY2");
assert_eq!(keywords[1].value(), " VALUE2"); |
i'm finally coming around to rewriting my org tool to use the 0.10 api and trying to solve some of these issues
this will only report keywords under the "0th" heading/section. There is also a Document::keywords() in at least alpha8 but this also does not descend in to grand-child headings, reporting only the top-level keywords and the first child sections. i cooked up a traverse handler fn that does this: let mut handler = from_fn(|event| match event {
// others ...
Event::Enter(Container::Section(the_section)) => {
for kw in the_section.syntax().children().filter_map(Keyword::cast) {
keywords.push(dbg!(kw))
}
}
_ => {}
}); |
@rrix actually traverser can handle keyword for you: let org = Org::parse("#+KEY1: VALUE1\n* HELLO\n#+KEY2: VALUE2");
let mut keywords = vec![];
let mut handle = from_fn(|event| {
if let Event::Enter(Container::Keyword(kw)) = event {
keywords.push((kw.key(), kw.value()));
}
});
org.traverse(&mut handle);
for (key, value) in keywords {
println!("{} -> {}", key.as_ref(), value.as_ref());
}
// KEY1 -> VALUE1
// KEY2 -> VALUE2 |
ack, thank you, i did eventually see that in my implementation. i took some notes as i've been going about rewriting my site's metadata extractor from 0.9 to 0.10 the last few days. my code is online at https://code.rix.si/rrix/arroyo_rs2/ mind the built-in assumptions tailored for my site engine data model. mind the ugly state tracking, i still don't know rust very well and am not a great programmer in general. mind that that url may be dead in the future as it is folded in to a canonical url, a literate, self-hosted engine driven by orgize 0.9 https://cce.whatthefuck.computer/arroyo/arroyo-rs) Overall, I think this iteration of the API is quite nice, well done and ty. i'm finding the rowan stuff a lot easier to work with than the previous arena thingy, and the handler fn is easier to work with as a newbie than the prior HtmlHandler trait and all the boilerplate i had to supply for the error types. i have a few questions, some with example snippets:
[1]: Event::Enter(Container::Drawer(the_drawer)) => {
if the_drawer.name() == "PROPERTIES" {
let h = format!("* Throwaway\n{}", the_drawer.raw());
let parsed = dbg!(Org::parse(h));
let drawer = parsed.first_node::<PropertyDrawer>().unwrap();
// do sth with orgize::ast::Drawer here
}
} [2]: let desc: Option<String> =
support::token(the_link.syntax(), orgize::SyntaxKind::TEXT).map(|t| t.to_string()); |
@rrix thanks for your feedback and that's a really cool project! I'm not familiar with would you be willing to create a new issue including some example usage? we could have a feature flag for parsing these extension syntax, allowing user to opt-in manually. |
this issue was fixed in
actually the previous implementation of |
nice, ty :) i'll open some issues for the org-fc and org-roam syntaxes |
yup, thanks! org-roam is actually relying on syntax which was recently allowed in org 9.5. I opened cheers! |
Hello everyone. After leaving this crate for almost unmaintained for over three years, I finally had some time to pick up what we left off. :)
Three years has passed, and many new feature and awesome crates have been introduced in the Rust world. So I think it's time for us to rebuild orgize with these new features and crates in mind. So I'm thrilled to announce that i'll be publishing orgize v0.10 in the next couple of weeks.
This version is total rewrite of orgize. Some notable changes including:
Switching to
rowan
In this version, we're replacing the underlying data structure from
indextree
torowan
, one of the core crates ofrust-analyzer
.To visualise that, input
* Heading *bold*
will now becomes something like:rowan
help us resolves some long exist problem like high memory usage and not able to get position of each parsed element.Also thanks to the rich ecosystem of
rowan
, we might have a lsp server for org mode in future, just likerust-analyzer
does for rust language.Traversing org element tree
Another big change in this version is that
org.iter()
is now superseded byorg.traverse()
. When walking through org element tree, traversal is much more flexible than simple iteration. For example, you can now skip the whole subtree but continue on its sibling without breaking the entire traversing by callingtraversal_context.skip()
.Lossless parsing
Orgize is now a loessless parser. It means you can always get original input back from
Org
struct:Try it out today
You can try out v0.10 by installing it from crates.io:
or using new demo website: https://poiscript.github.io/orgize
I hope you guys enjoy the new release, and feel free to send any feedback!
What's next
Before publishing v0.10, I want to fix other issues and merge pull requests as much as possible.
After that, I want to support parsing org entities and inlinetasks and try build a lsp server for org-mode using tower-lsp and orgize.
The text was updated successfully, but these errors were encountered: