rat_markdown/
dump.rs

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