Skip to content

Commit 865a34b

Browse files
committed
add critic markup syntax extensions
1 parent 43cb7dc commit 865a34b

File tree

13 files changed

+138607
-107655
lines changed

13 files changed

+138607
-107655
lines changed

crates/quarto-markdown-pandoc/src/filters.rs

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,10 @@ pub struct Filter<'a> {
5353
pub shortcode: InlineFilterField<'a, pandoc::Shortcode>,
5454
pub note_reference: InlineFilterField<'a, pandoc::NoteReference>,
5555
pub attr: InlineFilterField<'a, pandoc::Attr>,
56+
pub insert: InlineFilterField<'a, pandoc::Insert>,
57+
pub delete: InlineFilterField<'a, pandoc::Delete>,
58+
pub highlight: InlineFilterField<'a, pandoc::Highlight>,
59+
pub edit_comment: InlineFilterField<'a, pandoc::EditComment>,
5660

5761
pub paragraph: BlockFilterField<'a, pandoc::Paragraph>,
5862
pub plain: BlockFilterField<'a, pandoc::Plain>,
@@ -119,6 +123,11 @@ impl Default for Filter<'static> {
119123
horizontal_rule: None,
120124
attr: None,
121125

126+
insert: None,
127+
delete: None,
128+
highlight: None,
129+
edit_comment: None,
130+
122131
meta: None,
123132
}
124133
}
@@ -200,6 +209,10 @@ define_filter_with_methods!(
200209
shortcode,
201210
note_reference,
202211
attr,
212+
insert,
213+
delete,
214+
highlight,
215+
edit_comment
203216
);
204217

205218
define_filter_with_methods!(
@@ -300,7 +313,11 @@ impl_inline_filterable_simple!(
300313
Quoted,
301314
Link,
302315
Image,
303-
Span
316+
Span,
317+
Insert,
318+
Delete,
319+
Highlight,
320+
EditComment
304321
);
305322

306323
impl InlineFilterableStructure for pandoc::Note {
@@ -617,6 +634,18 @@ pub fn topdown_traverse_inline(inline: Inline, filter: &mut Filter) -> Inlines {
617634
Inline::Attr(attr) => {
618635
handle_inline_filter!(Attr, attr, attr, filter)
619636
}
637+
Inline::Insert(ins) => {
638+
handle_inline_filter!(Insert, ins, insert, filter)
639+
}
640+
Inline::Delete(del) => {
641+
handle_inline_filter!(Delete, del, delete, filter)
642+
}
643+
Inline::Highlight(hl) => {
644+
handle_inline_filter!(Highlight, hl, highlight, filter)
645+
}
646+
Inline::EditComment(ec) => {
647+
handle_inline_filter!(EditComment, ec, edit_comment, filter)
648+
}
620649
}
621650
}
622651

crates/quarto-markdown-pandoc/src/pandoc/inline.rs

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,12 @@ pub enum Inline {
4040
// this is used to represent commonmark attributes in the document in places
4141
// where they are not directly attached to a block, like in headings and tables
4242
Attr(Attr),
43+
44+
// CriticMarkup-like extensions
45+
Insert(Insert),
46+
Delete(Delete),
47+
Highlight(Highlight),
48+
EditComment(EditComment),
4349
}
4450

4551
pub type Inlines = Vec<Inline>;
@@ -194,6 +200,26 @@ pub enum CitationMode {
194200
NormalCitation,
195201
}
196202

203+
#[derive(Debug, Clone, PartialEq)]
204+
pub struct Insert {
205+
pub content: Inlines,
206+
}
207+
208+
#[derive(Debug, Clone, PartialEq)]
209+
pub struct Delete {
210+
pub content: Inlines,
211+
}
212+
213+
#[derive(Debug, Clone, PartialEq)]
214+
pub struct Highlight {
215+
pub content: Inlines,
216+
}
217+
218+
#[derive(Debug, Clone, PartialEq)]
219+
pub struct EditComment {
220+
pub content: Inlines,
221+
}
222+
197223
impl_source_location!(Space, LineBreak, SoftBreak);
198224

199225
pub trait AsInline {
@@ -241,7 +267,11 @@ impl_as_inline!(
241267
Span,
242268
Shortcode,
243269
NoteReference,
244-
Attr
270+
Attr,
271+
Insert,
272+
Delete,
273+
Highlight,
274+
EditComment
245275
);
246276

247277
pub fn is_empty_target(target: &Target) -> bool {

crates/quarto-markdown-pandoc/src/pandoc/mod.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,10 @@ pub use crate::pandoc::block::{
2222
};
2323
pub use crate::pandoc::caption::Caption;
2424
pub use crate::pandoc::inline::{
25-
Citation, CitationMode, Cite, Code, Emph, Image, Inline, Inlines, LineBreak, Link, Math,
26-
MathType, Note, NoteReference, QuoteType, Quoted, RawInline, SmallCaps, SoftBreak, Space, Span,
27-
Str, Strikeout, Strong, Subscript, Superscript, Underline,
25+
Citation, CitationMode, Cite, Code, Delete, EditComment, Emph, Highlight, Image, Inline,
26+
Inlines, Insert, LineBreak, Link, Math, MathType, Note, NoteReference, QuoteType, Quoted,
27+
RawInline, SmallCaps, SoftBreak, Space, Span, Str, Strikeout, Strong, Subscript, Superscript,
28+
Underline,
2829
};
2930
pub use crate::pandoc::list::{ListAttributes, ListNumberDelim, ListNumberStyle};
3031
pub use crate::pandoc::pandoc::Pandoc;

crates/quarto-markdown-pandoc/src/pandoc/treesitter.rs

Lines changed: 105 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,10 @@ use crate::pandoc::block::{
1010
};
1111
use crate::pandoc::caption::Caption;
1212
use crate::pandoc::inline::{
13-
Citation, CitationMode, Cite, Code, Emph, Image, Inline, Inlines, LineBreak, Link, Math,
14-
MathType, Note, NoteReference, QuoteType, Quoted, RawInline, SoftBreak, Space, Span, Str,
15-
Strikeout, Strong, Subscript, Superscript, Target, is_empty_target,
13+
Citation, CitationMode, Cite, Code, Delete, EditComment, Emph, Highlight, Image, Inline,
14+
Inlines, Insert, LineBreak, Link, Math, MathType, Note, NoteReference, QuoteType, Quoted,
15+
RawInline, SoftBreak, Space, Span, Str, Strikeout, Strong, Subscript, Superscript, Target,
16+
is_empty_target,
1617
};
1718

1819
use crate::pandoc::inline::{make_cite_inline, make_span_inline};
@@ -894,7 +895,11 @@ fn native_visitor<T: Write>(
894895
| "superscript_delimiter"
895896
| "subscript_delimiter"
896897
| "strikeout_delimiter"
897-
| "emphasis_delimiter" => {
898+
| "emphasis_delimiter"
899+
| "insert_delimiter"
900+
| "delete_delimiter"
901+
| "highlight_delimiter"
902+
| "edit_comment_delimiter" => {
898903
PandocNativeIntermediate::IntermediateUnknown(node_location(node))
899904
}
900905
"soft_line_break" => {
@@ -971,6 +976,46 @@ fn native_visitor<T: Write>(
971976
content: inlines,
972977
}))
973978
}
979+
"insert" => {
980+
let inlines: Vec<_> = children
981+
.into_iter()
982+
.filter(|(node, _)| node != "insert_delimiter")
983+
.map(native_inline)
984+
.collect();
985+
PandocNativeIntermediate::IntermediateInline(Inline::Insert(Insert {
986+
content: inlines,
987+
}))
988+
}
989+
"delete" => {
990+
let inlines: Vec<_> = children
991+
.into_iter()
992+
.filter(|(node, _)| node != "delete_delimiter")
993+
.map(native_inline)
994+
.collect();
995+
PandocNativeIntermediate::IntermediateInline(Inline::Delete(Delete {
996+
content: inlines,
997+
}))
998+
}
999+
"highlight" => {
1000+
let inlines: Vec<_> = children
1001+
.into_iter()
1002+
.filter(|(node, _)| node != "highlight_delimiter")
1003+
.map(native_inline)
1004+
.collect();
1005+
PandocNativeIntermediate::IntermediateInline(Inline::Highlight(Highlight {
1006+
content: inlines,
1007+
}))
1008+
}
1009+
"edit_comment" => {
1010+
let inlines: Vec<_> = children
1011+
.into_iter()
1012+
.filter(|(node, _)| node != "edit_comment_delimiter")
1013+
.map(native_inline)
1014+
.collect();
1015+
PandocNativeIntermediate::IntermediateInline(Inline::EditComment(EditComment {
1016+
content: inlines,
1017+
}))
1018+
}
9741019

9751020
"quoted_span" => {
9761021
let mut quote_type = QuoteType::SingleQuote;
@@ -1895,6 +1940,62 @@ fn desugar(doc: Pandoc) -> Result<Pandoc, Vec<String>> {
18951940
false,
18961941
)
18971942
})
1943+
.with_insert(|insert| {
1944+
let (content, _changed) = trim_inlines(insert.content);
1945+
FilterResult(
1946+
vec![Inline::Span(Span {
1947+
attr: (
1948+
"".to_string(),
1949+
vec!["quarto-insert".to_string()],
1950+
HashMap::new(),
1951+
),
1952+
content,
1953+
})],
1954+
true,
1955+
)
1956+
})
1957+
.with_delete(|delete| {
1958+
let (content, _changed) = trim_inlines(delete.content);
1959+
FilterResult(
1960+
vec![Inline::Span(Span {
1961+
attr: (
1962+
"".to_string(),
1963+
vec!["quarto-delete".to_string()],
1964+
HashMap::new(),
1965+
),
1966+
content,
1967+
})],
1968+
true,
1969+
)
1970+
})
1971+
.with_highlight(|highlight| {
1972+
let (content, _changed) = trim_inlines(highlight.content);
1973+
FilterResult(
1974+
vec![Inline::Span(Span {
1975+
attr: (
1976+
"".to_string(),
1977+
vec!["quarto-highlight".to_string()],
1978+
HashMap::new(),
1979+
),
1980+
content,
1981+
})],
1982+
true,
1983+
)
1984+
})
1985+
.with_edit_comment(|edit_comment| {
1986+
let (content, _changed) = trim_inlines(edit_comment.content);
1987+
FilterResult(
1988+
vec![Inline::Span(Span {
1989+
attr: (
1990+
"".to_string(),
1991+
vec!["quarto-edit-comment".to_string()],
1992+
HashMap::new(),
1993+
),
1994+
content,
1995+
})],
1996+
true,
1997+
)
1998+
})
18981999
.with_inlines(|inlines| {
18992000
let mut result = vec![];
19002001
// states in this state machine:

crates/quarto-markdown-pandoc/src/writers/json.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,13 @@ fn write_inline(inline: &Inline) -> Value {
144144
})
145145
}).collect::<Vec<_>>()
146146
}),
147-
Inline::Shortcode(_) | Inline::NoteReference(_) | Inline::Attr(_) => {
147+
Inline::Shortcode(_)
148+
| Inline::NoteReference(_)
149+
| Inline::Attr(_)
150+
| Inline::Insert(_)
151+
| Inline::Delete(_)
152+
| Inline::Highlight(_)
153+
| Inline::EditComment(_) => {
148154
panic!("Unsupported inline type: {:?}", inline)
149155
}
150156
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
[++insertions with markdown _inside_ them], [--deletions, **likewise**], [!! highlight this part][>> with a comment about the previous highlight].
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
[ Para [Span ( "" , ["quarto-insert"] , [] ) [Str "insertions", Space, Str "with", Space, Str "markdown", Space, Emph [Str "inside"], Space, Str "them"], Str ",", Space, Span ( "" , ["quarto-delete"] , [] ) [Str "deletions,", Space, Strong [Str "likewise"]], Str ",", Space, Span ( "" , ["quarto-highlight"] , [] ) [Str "highlight", Space, Str "this", Space, Str "part"], Span ( "" , ["quarto-edit-comment"] , [] ) [Str "with", Space, Str "a", Space, Str "comment", Space, Str "about", Space, Str "the", Space, Str "previous", Space, Str "highlight"], Str "."] ]

crates/tree-sitter-qmd/tree-sitter-markdown-inline/grammar.js

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,30 @@ module.exports = grammar(add_inline_rules({
149149
alias($._latex_span_close, $.latex_span_delimiter),
150150
),
151151

152+
insert: $ => seq(
153+
prec(3, alias(/\[\+\+[ ]*/, $.insert_delimiter)),
154+
repeat($._inline_element),
155+
prec(3, alias(/[ ]*\]/, $.insert_delimiter)),
156+
),
157+
158+
delete: $ => seq(
159+
prec(3, alias(/\[\-\-[ ]*/, $.delete_delimiter)),
160+
repeat($._inline_element),
161+
prec(3, alias(/[ ]*\]/, $.delete_delimiter)),
162+
),
163+
164+
highlight: $ => seq(
165+
prec(3, alias(/\[\!\![ ]*/, $.highlight_delimiter)),
166+
repeat($._inline_element),
167+
prec(3, alias(/[ ]*\]/, $.highlight_delimiter)),
168+
),
169+
170+
edit_comment: $ => seq(
171+
prec(3, alias(/\[>>[ ]*/, $.edit_comment_delimiter)),
172+
repeat($._inline_element),
173+
prec(3, alias(/[ ]*\]/, $.edit_comment_delimiter)),
174+
),
175+
152176
superscript: $ => seq(
153177
alias($._superscript_open, $.superscript_delimiter),
154178
repeat($._inline_element),
@@ -399,6 +423,10 @@ module.exports = grammar(add_inline_rules({
399423
$.shortcode_escaped,
400424
$.note_reference,
401425
$.commonmark_attribute,
426+
$.insert,
427+
$.delete,
428+
$.highlight,
429+
$.edit_comment,
402430

403431
alias($._text_base, $.text_base),
404432
$._unclosed_span,

0 commit comments

Comments
 (0)