Unified djot.parse() to optionally return both - ast and events
I work on creating a WebKitGTK-based djot editor with live preview. I use the following JS script to both - render HTML and obtain parse events back into the main app in order to highlight the syntax of the source text. Using the same JS code for the both tasks is very useful and elegant! Thank you for providing djot.parseEvents()!
This is how I achieve it:
<script>
const djotContent = document.getElementById('djot-source').innerHTML;
const ast = djot.parse(djotContent, { sourcePositions: true });
const htmlContent = djot.renderHTML(ast);
events_str = \"\";
document.getElementById('preview').innerHTML = htmlContent;
const events = djot.parseEvents(djotContent, { sourcePositions: true });
for (let event of events) {
events_str += JSON.stringify(event);
}
window.webkit.messageHandlers.dataChannel.postMessage(events_str);
</script>
The problem - I need to parse the same text twice - first with const ast = djot.parse(djotContent, { sourcePositions: true }); and then with const events = djot.parseEvents(djotContent, { sourcePositions: true });. This is not optimal and can waste resources/time for long texts.
Can we unite djot.parse() and djot.parseEvents() into one function that optionally (e.g. djot.parse(djotContent, { sourcePositions: true, returnEvents: true });) will return an object that will contain both - ast and events?
{ ast: ast, events: events }
const result = djot.parse(djotContent, { sourcePositions: true, returnEvents: true });
console.log(result.ast);
console.log(result.events);
This way we can achieve double speed.
One idea would be to factor out most of the code in parse into a function parseFromEvents that takes an EventParser rather than a string as its input. (We'd need access to the string input in this function, but I think we can just get that from the event parser's subject field.) parse could then be defined by composing parseEvents and parseFromEvents, but it would also be possible to use parseEvents and parseFromEvents separately to avoid having to reparse the events.
@matklad does this seem like a good approach to you?
Yeah, defining parse as a transparent composition of two lower-level functions seems like the most straightforward solution here.
I made a PR (#112) - review would be welcome.