rat_markdown/
dump.rs

1use crate::styles::MDStyle;
2use log::info;
3use pulldown_cmark::{Event, Options, Parser, Tag, TagEnd};
4use rat_text::event::TextOutcome;
5use rat_text::text_area::TextAreaState;
6use rat_text::TextRange;
7
8pub fn md_dump_styles(state: &mut TextAreaState) -> TextOutcome {
9    let cursor = state.cursor();
10    let cursor_byte = state.byte_at(cursor).start;
11
12    let mut sty = Vec::new();
13    state.styles_at(cursor_byte, &mut sty);
14    for (_r, s) in sty {
15        info!("style {:?}: {:?}", cursor, MDStyle::try_from(s));
16    }
17
18    TextOutcome::Unchanged
19}
20
21pub fn md_dump(state: &TextAreaState) -> TextOutcome {
22    let cursor = state.cursor();
23    let cursor_byte = state.byte_at(cursor).start;
24
25    let selection = if state.selection().is_empty() {
26        let mut sty = Vec::new();
27        state.styles_at(cursor_byte, &mut sty);
28
29        let first = sty
30            .iter()
31            .filter(|(_, s)| {
32                matches!(
33                    MDStyle::try_from(*s).expect("fine"),
34                    MDStyle::Heading1
35                        | MDStyle::Heading2
36                        | MDStyle::Heading3
37                        | MDStyle::Heading4
38                        | MDStyle::Heading5
39                        | MDStyle::Heading6
40                        | MDStyle::Paragraph
41                        | MDStyle::BlockQuote
42                        | MDStyle::CodeBlock
43                        | MDStyle::MathDisplay
44                        | MDStyle::Rule
45                        | MDStyle::Html
46                        | MDStyle::FootnoteDefinition
47                        | MDStyle::List
48                        | MDStyle::DefinitionList
49                        | MDStyle::Table
50                )
51            })
52            .next();
53
54        if let Some((r, _)) = first {
55            let r = state.byte_range(r.clone());
56            TextRange::new((0, r.start.y), r.end)
57        } else {
58            TextRange::new((0, cursor.y), (0, cursor.y + 1))
59        }
60    } else {
61        TextRange::new(
62            (0, state.selection().start.y),
63            (0, state.selection().end.y + 1),
64        )
65    };
66
67    dump_md(state.str_slice(selection).as_ref());
68
69    TextOutcome::Unchanged
70}
71
72fn dump_md(txt: &str) {
73    info!("*** DUMP ***");
74    info!("{:?}", txt);
75
76    let mut it = Parser::new_ext(
77        txt,
78        Options::ENABLE_MATH
79            | Options::ENABLE_TASKLISTS
80            | Options::ENABLE_TABLES
81            | Options::ENABLE_STRIKETHROUGH
82            | Options::ENABLE_SMART_PUNCTUATION
83            | Options::ENABLE_FOOTNOTES
84            | Options::ENABLE_GFM
85            | Options::ENABLE_DEFINITION_LIST,
86    )
87    .into_offset_iter();
88
89    let mut ind = 0;
90    loop {
91        let Some((e, r)) = it.next() else {
92            break;
93        };
94
95        match e {
96            Event::Start(v) => {
97                match v {
98                    Tag::Paragraph => {
99                        info!("{}Paragraph {:?}", " ".repeat(ind), r.clone(),);
100                    }
101                    Tag::Heading {
102                        level,
103                        id,
104                        classes: _todo_classes_,
105                        attrs: _todo_attrs_,
106                    } => {
107                        info!(
108                            "{}Heading Level={:?} Id={:?} {:?}",
109                            " ".repeat(ind),
110                            level,
111                            id,
112                            r.clone(),
113                        );
114                    }
115                    Tag::BlockQuote(kind) => {
116                        info!(
117                            "{}BlockQuote Kind={:?} {:?}",
118                            " ".repeat(ind),
119                            kind,
120                            r.clone(),
121                        );
122                    }
123                    Tag::CodeBlock(kind) => {
124                        info!(
125                            "{}CodeBlock Kind={:?} {:?}",
126                            " ".repeat(ind),
127                            kind,
128                            r.clone(),
129                        );
130                    }
131                    Tag::HtmlBlock => {
132                        info!("{}HtmlBlock {:?}", " ".repeat(ind), r.clone(),);
133                    }
134                    Tag::List(first) => {
135                        info!("{}List First={:?} {:?}", " ".repeat(ind), first, r.clone(),);
136                    }
137                    Tag::Item => {
138                        info!("{}Item {:?}", " ".repeat(ind), r.clone(),);
139                    }
140                    Tag::FootnoteDefinition(label) => {
141                        info!(
142                            "{}FootnoteDefinition Label={:?} {:?}",
143                            " ".repeat(ind),
144                            label,
145                            r.clone(),
146                        );
147                    }
148                    Tag::DefinitionList => {
149                        info!("{}DefinitionList {:?}", " ".repeat(ind), r.clone(),);
150                    }
151                    Tag::DefinitionListTitle => {
152                        info!("{}DefinitionListTitle {:?}", " ".repeat(ind), r.clone(),);
153                    }
154                    Tag::DefinitionListDefinition => {
155                        info!(
156                            "{}DefinitionListDefinition {:?}",
157                            " ".repeat(ind),
158                            r.clone(),
159                        );
160                    }
161                    Tag::Table(align) => {
162                        info!(
163                            "{}Table Alignment={:?} {:?}",
164                            " ".repeat(ind),
165                            align,
166                            r.clone(),
167                        );
168                    }
169                    Tag::TableHead => {
170                        info!("{}TableHead {:?}", " ".repeat(ind), r.clone(),);
171                    }
172                    Tag::TableRow => {
173                        info!("{}TableRow {:?}", " ".repeat(ind), r.clone(),);
174                    }
175                    Tag::TableCell => {
176                        info!("{}TableCell {:?}", " ".repeat(ind), r.clone(),);
177                    }
178                    Tag::Emphasis => {
179                        info!(
180                            "{}Emphasis {:?} {:?}",
181                            " ".repeat(ind),
182                            r.clone(),
183                            &txt[r.clone()]
184                        );
185                    }
186                    Tag::Strong => {
187                        info!(
188                            "{}Strong {:?} {:?}",
189                            " ".repeat(ind),
190                            r.clone(),
191                            &txt[r.clone()]
192                        );
193                    }
194                    Tag::Strikethrough => {
195                        info!(
196                            "{}Strikethrough {:?} {:?}",
197                            " ".repeat(ind),
198                            r.clone(),
199                            &txt[r.clone()]
200                        );
201                    }
202                    Tag::Link {
203                        link_type,
204                        dest_url,
205                        title,
206                        id,
207                    } => {
208                        info!(
209                            "{}Link LinkType={:?} DestUrl={:?} Title={:?} Id={:?} {:?} {:?}",
210                            " ".repeat(ind),
211                            link_type,
212                            dest_url,
213                            title,
214                            id,
215                            r.clone(),
216                            &txt[r.clone()]
217                        );
218                    }
219                    Tag::Image {
220                        link_type,
221                        dest_url,
222                        title,
223                        id,
224                    } => {
225                        info!(
226                            "{}Image LinkType={:?} DestUrl={:?} Title={:?} Id={:?} {:?} {:?}",
227                            " ".repeat(ind),
228                            link_type,
229                            dest_url,
230                            title,
231                            id,
232                            r.clone(),
233                            &txt[r.clone()]
234                        );
235                    }
236                    Tag::MetadataBlock(kind) => {
237                        info!(
238                            "{}MetadataBlock Kind={:?} {:?} {:?}",
239                            " ".repeat(ind),
240                            kind,
241                            r.clone(),
242                            &txt[r.clone()]
243                        );
244                    }
245                };
246                ind += 4;
247            }
248            Event::End(v) => {
249                ind -= 4;
250                match v {
251                    TagEnd::Paragraph => {
252                        info!("{}/Paragraph {:?}", " ".repeat(ind), r.clone(),);
253                    }
254                    TagEnd::Heading(level) => {
255                        info!(
256                            "{}/Heading Level={:?} {:?} ",
257                            " ".repeat(ind),
258                            level,
259                            r.clone(),
260                        );
261                    }
262                    TagEnd::BlockQuote(kind) => {
263                        info!(
264                            "{}/BlockQuote Kind={:?} {:?}",
265                            " ".repeat(ind),
266                            kind,
267                            r.clone(),
268                        );
269                    }
270                    TagEnd::CodeBlock => {
271                        info!("{}/CodeBlock {:?} ", " ".repeat(ind), r.clone(),);
272                    }
273                    TagEnd::HtmlBlock => {
274                        info!("{}/HtmlBlock {:?} ", " ".repeat(ind), r.clone(),);
275                    }
276                    TagEnd::List(ordered) => {
277                        info!(
278                            "{}/List Ordered={:?} {:?}",
279                            " ".repeat(ind),
280                            ordered,
281                            r.clone(),
282                        );
283                    }
284                    TagEnd::Item => {
285                        info!("{}/Item {:?} ", " ".repeat(ind), r.clone(),);
286                    }
287                    TagEnd::FootnoteDefinition => {
288                        info!("{}/FootnoteDefinition {:?}", " ".repeat(ind), r.clone(),);
289                    }
290                    TagEnd::DefinitionList => {
291                        info!("{}/DefinitionList {:?}", " ".repeat(ind), r.clone(),);
292                    }
293                    TagEnd::DefinitionListTitle => {
294                        info!("{}/DefinitionListTitle {:?}", " ".repeat(ind), r.clone(),);
295                    }
296                    TagEnd::DefinitionListDefinition => {
297                        info!(
298                            "{}/DefinitionListDefinition {:?}",
299                            " ".repeat(ind),
300                            r.clone(),
301                        );
302                    }
303                    TagEnd::Table => {
304                        info!("{}/Table {:?}", " ".repeat(ind), r.clone(),);
305                    }
306                    TagEnd::TableHead => {
307                        info!("{}/TableHead {:?}", " ".repeat(ind), r.clone(),);
308                    }
309                    TagEnd::TableRow => {
310                        info!("{}/TableRow {:?}", " ".repeat(ind), r.clone(),);
311                    }
312                    TagEnd::TableCell => {
313                        info!("{}/TableCell {:?}", " ".repeat(ind), r.clone(),);
314                    }
315                    TagEnd::Emphasis => {
316                        info!(
317                            "{}/Emphasis {:?} {:?}",
318                            " ".repeat(ind),
319                            r.clone(),
320                            &txt[r.clone()]
321                        );
322                    }
323                    TagEnd::Strong => {
324                        info!(
325                            "{}/Strong {:?} {:?}",
326                            " ".repeat(ind),
327                            r.clone(),
328                            &txt[r.clone()]
329                        );
330                    }
331                    TagEnd::Strikethrough => {
332                        info!(
333                            "{}/Strikethrough {:?} {:?}",
334                            " ".repeat(ind),
335                            r.clone(),
336                            &txt[r.clone()]
337                        );
338                    }
339                    TagEnd::Link => {
340                        info!(
341                            "{}/Link {:?} {:?}",
342                            " ".repeat(ind),
343                            r.clone(),
344                            &txt[r.clone()]
345                        );
346                    }
347                    TagEnd::Image => {
348                        info!(
349                            "{}/Image {:?} {:?}",
350                            " ".repeat(ind),
351                            r.clone(),
352                            &txt[r.clone()]
353                        );
354                    }
355                    TagEnd::MetadataBlock(kind) => {
356                        info!(
357                            "{}/MetadataBlock Kind={:?} {:?} {:?}",
358                            " ".repeat(ind),
359                            kind,
360                            r.clone(),
361                            &txt[r.clone()]
362                        );
363                    }
364                }
365            }
366            Event::Text(_v) => {
367                info!(
368                    "{}Text {:?} {:?}",
369                    " ".repeat(ind),
370                    r.clone(),
371                    &txt[r.clone()]
372                );
373            }
374            Event::Code(v) => {
375                info!(
376                    "{}Code V={:?} {:?} {:?}",
377                    " ".repeat(ind),
378                    v.as_ref(),
379                    r.clone(),
380                    &txt[r.clone()]
381                );
382            }
383            Event::InlineMath(v) => {
384                info!(
385                    "{}InlineMath V={:?} {:?} {:?}",
386                    " ".repeat(ind),
387                    v.as_ref(),
388                    r.clone(),
389                    &txt[r.clone()]
390                );
391            }
392            Event::DisplayMath(v) => {
393                info!(
394                    "{}DisplayMath V={:?} {:?} {:?}",
395                    " ".repeat(ind),
396                    v.as_ref(),
397                    r.clone(),
398                    &txt[r.clone()]
399                );
400            }
401            Event::Html(v) => {
402                info!(
403                    "{}Html V={:?} {:?} {:?}",
404                    " ".repeat(ind),
405                    v.as_ref(),
406                    r.clone(),
407                    &txt[r.clone()]
408                );
409            }
410            Event::InlineHtml(v) => {
411                info!(
412                    "{}InlineHtml V={:?} {:?} {:?}",
413                    " ".repeat(ind),
414                    v.as_ref(),
415                    r.clone(),
416                    &txt[r.clone()]
417                );
418            }
419            Event::FootnoteReference(v) => {
420                info!(
421                    "{}FootnoteReference V={:?} {:?} {:?}",
422                    " ".repeat(ind),
423                    v.as_ref(),
424                    r.clone(),
425                    &txt[r.clone()]
426                );
427            }
428            Event::SoftBreak => {
429                info!(
430                    "{}SoftBreak {:?} {:?}",
431                    " ".repeat(ind),
432                    r.clone(),
433                    &txt[r.clone()]
434                );
435            }
436            Event::HardBreak => {
437                info!(
438                    "{}HardBreak {:?} {:?}",
439                    " ".repeat(ind),
440                    r.clone(),
441                    &txt[r.clone()]
442                );
443            }
444            Event::Rule => {
445                info!(
446                    "{}Rule {:?} {:?}",
447                    " ".repeat(ind),
448                    r.clone(),
449                    &txt[r.clone()]
450                );
451            }
452            Event::TaskListMarker(checked) => {
453                info!(
454                    "{}TaskListMarker Checked={:?} {:?} {:?}",
455                    " ".repeat(ind),
456                    checked,
457                    r.clone(),
458                    &txt[r.clone()]
459                );
460            }
461        }
462    }
463
464    let rdef = it.reference_definitions();
465    for (rstr, rdef) in rdef.iter() {
466        info!(
467            "ReferenceDefinition {:?} {:?} = {:?} {:?}",
468            rdef.span,
469            rstr,
470            rdef.dest.as_ref(),
471            rdef.title.as_ref().map(|v| v.as_ref())
472        )
473    }
474}