orgize
orgize copied to clipboard
optional support for org-fc cloze markup
I use https://github.com/l3kn/org-fc, an anki-style flashcarding system that has a few "card types"; most of them are based on the shape of a heading (one side of the card is the heading, one is the text therein), a text-input, etc, but it also introduces a custom markup for what it calls "cloze" cards:
The cards text contains one or more holes . During review, one hole is hidden while the text of (some) remaining ones is shown.
These introduce a markup that interacts poorly with orgize's parser, especially if you put non-text syntax inside of the "holes". With the 0.9 parser, I just used a regex match on a Text block to transform these clozes in to <span>
elements on export, but if a link or so is in there it breaks up the text block.
Deletions can have the following forms
{{text}}
{{text}@id}
{{text}{hint}}
{{text}{hint}@id}
It would be nice to have a (perhaps feature gated) extension to the rowan syntax to parse these and have access to the underlying tokens in the text and hint for more robust export.
initial support for org-fc
cloze was landed in commit 6c4513d857402fa53a0ba55dd793e32bb6579881
you can give it a try now by editing you cargo.toml to
orgize = { git = "https://github.com/PoiScript/orgize", branch = "v0.10", features = [
"syntax-org-fc",
] }
one thing that I'm not sure about is the method naming: text() -> impl Iteractor<_>
- it seems a bit wired.
thanks poi, this is quite promising, i appreciate it. I'm having trouble using it within an traverse fn; I don't ever see any Event::Cloze
events though i do see CLOZEs in the Document AST
let mut handler = from_fn_with_ctx(|event, ctx| {
match &event {
Event::Cloze(the_cloze) => {
println!("XXX");
dbg!(the_cloze);
html_export.push_str(r#"<span class="cloze" "#);
if the_cloze.hint().is_some() {
html_export.push_str(format!(r#"alt="{}""#, the_cloze.hint().unwrap()));
}
html_export.push_str(">");
for item in the_cloze.text() {
match item.into_node() {
Some(node) => html_export.render(&node),
None => {}
}
}
html_export.push_str("</span>");
}
// ...
I think I'm using the text()
iterator correctly here, except maybe i should match on .kind()
? Ultimately, I'd like the links and whatnot within the text to render.
W.R.T. the naming, I don't have much advice here. You could call it answer()
to differentiate it from other elements' text(), but that might be more confusing than helpful.
hello, sorry for the late response. the traverser now emits cloze events properly:
let org = Org::parse("{{cloze1}{hint1}}");
let mut cloze = None;
let mut t = from_fn(|event| {
if let Event::Cloze(cloze_) = event {
cloze = Some(cloze_);
}
});
org.traverse(&mut t);
let cloze = cloze.unwrap();
assert_eq!(cloze.text_raw(), "cloze1");
assert_eq!(cloze.hint().unwrap(), "hint1");
and I just checked the anki docs, and it also labels this field as "Text". so I think we're good to go.