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                };
245                ind += 4;
246            }
247            Event::End(v) => {
248                ind -= 4;
249                match v {
250                    TagEnd::Paragraph => {
251                        info!("{}/Paragraph {:?}", " ".repeat(ind), r.clone(),);
252                    }
253                    TagEnd::Heading(level) => {
254                        info!(
255                            "{}/Heading Level={:?} {:?} ",
256                            " ".repeat(ind),
257                            level,
258                            r.clone(),
259                        );
260                    }
261                    TagEnd::BlockQuote(kind) => {
262                        info!(
263                            "{}/BlockQuote Kind={:?} {:?}",
264                            " ".repeat(ind),
265                            kind,
266                            r.clone(),
267                        );
268                    }
269                    TagEnd::CodeBlock => {
270                        info!("{}/CodeBlock {:?} ", " ".repeat(ind), r.clone(),);
271                    }
272                    TagEnd::HtmlBlock => {
273                        info!("{}/HtmlBlock {:?} ", " ".repeat(ind), r.clone(),);
274                    }
275                    TagEnd::List(ordered) => {
276                        info!(
277                            "{}/List Ordered={:?} {:?}",
278                            " ".repeat(ind),
279                            ordered,
280                            r.clone(),
281                        );
282                    }
283                    TagEnd::Item => {
284                        info!("{}/Item {:?} ", " ".repeat(ind), r.clone(),);
285                    }
286                    TagEnd::FootnoteDefinition => {
287                        info!("{}/FootnoteDefinition {:?}", " ".repeat(ind), r.clone(),);
288                    }
289                    TagEnd::DefinitionList => {
290                        info!("{}/DefinitionList {:?}", " ".repeat(ind), r.clone(),);
291                    }
292                    TagEnd::DefinitionListTitle => {
293                        info!("{}/DefinitionListTitle {:?}", " ".repeat(ind), r.clone(),);
294                    }
295                    TagEnd::DefinitionListDefinition => {
296                        info!(
297                            "{}/DefinitionListDefinition {:?}",
298                            " ".repeat(ind),
299                            r.clone(),
300                        );
301                    }
302                    TagEnd::Table => {
303                        info!("{}/Table {:?}", " ".repeat(ind), r.clone(),);
304                    }
305                    TagEnd::TableHead => {
306                        info!("{}/TableHead {:?}", " ".repeat(ind), r.clone(),);
307                    }
308                    TagEnd::TableRow => {
309                        info!("{}/TableRow {:?}", " ".repeat(ind), r.clone(),);
310                    }
311                    TagEnd::TableCell => {
312                        info!("{}/TableCell {:?}", " ".repeat(ind), r.clone(),);
313                    }
314                    TagEnd::Emphasis => {
315                        info!(
316                            "{}/Emphasis {:?} {:?}",
317                            " ".repeat(ind),
318                            r.clone(),
319                            &txt[r.clone()]
320                        );
321                    }
322                    TagEnd::Strong => {
323                        info!(
324                            "{}/Strong {:?} {:?}",
325                            " ".repeat(ind),
326                            r.clone(),
327                            &txt[r.clone()]
328                        );
329                    }
330                    TagEnd::Strikethrough => {
331                        info!(
332                            "{}/Strikethrough {:?} {:?}",
333                            " ".repeat(ind),
334                            r.clone(),
335                            &txt[r.clone()]
336                        );
337                    }
338                    TagEnd::Link => {
339                        info!(
340                            "{}/Link {:?} {:?}",
341                            " ".repeat(ind),
342                            r.clone(),
343                            &txt[r.clone()]
344                        );
345                    }
346                    TagEnd::Image => {
347                        info!(
348                            "{}/Image {:?} {:?}",
349                            " ".repeat(ind),
350                            r.clone(),
351                            &txt[r.clone()]
352                        );
353                    }
354                    TagEnd::MetadataBlock(kind) => {
355                        info!(
356                            "{}/MetadataBlock Kind={:?} {:?} {:?}",
357                            " ".repeat(ind),
358                            kind,
359                            r.clone(),
360                            &txt[r.clone()]
361                        );
362                    }
363                }
364            }
365            Event::Text(_v) => {
366                info!(
367                    "{}Text {:?} {:?}",
368                    " ".repeat(ind),
369                    r.clone(),
370                    &txt[r.clone()]
371                );
372            }
373            Event::Code(v) => {
374                info!(
375                    "{}Code V={:?} {:?} {:?}",
376                    " ".repeat(ind),
377                    v.as_ref(),
378                    r.clone(),
379                    &txt[r.clone()]
380                );
381            }
382            Event::InlineMath(v) => {
383                info!(
384                    "{}InlineMath V={:?} {:?} {:?}",
385                    " ".repeat(ind),
386                    v.as_ref(),
387                    r.clone(),
388                    &txt[r.clone()]
389                );
390            }
391            Event::DisplayMath(v) => {
392                info!(
393                    "{}DisplayMath V={:?} {:?} {:?}",
394                    " ".repeat(ind),
395                    v.as_ref(),
396                    r.clone(),
397                    &txt[r.clone()]
398                );
399            }
400            Event::Html(v) => {
401                info!(
402                    "{}Html V={:?} {:?} {:?}",
403                    " ".repeat(ind),
404                    v.as_ref(),
405                    r.clone(),
406                    &txt[r.clone()]
407                );
408            }
409            Event::InlineHtml(v) => {
410                info!(
411                    "{}InlineHtml V={:?} {:?} {:?}",
412                    " ".repeat(ind),
413                    v.as_ref(),
414                    r.clone(),
415                    &txt[r.clone()]
416                );
417            }
418            Event::FootnoteReference(v) => {
419                info!(
420                    "{}FootnoteReference V={:?} {:?} {:?}",
421                    " ".repeat(ind),
422                    v.as_ref(),
423                    r.clone(),
424                    &txt[r.clone()]
425                );
426            }
427            Event::SoftBreak => {
428                info!(
429                    "{}SoftBreak {:?} {:?}",
430                    " ".repeat(ind),
431                    r.clone(),
432                    &txt[r.clone()]
433                );
434            }
435            Event::HardBreak => {
436                info!(
437                    "{}HardBreak {:?} {:?}",
438                    " ".repeat(ind),
439                    r.clone(),
440                    &txt[r.clone()]
441                );
442            }
443            Event::Rule => {
444                info!(
445                    "{}Rule {:?} {:?}",
446                    " ".repeat(ind),
447                    r.clone(),
448                    &txt[r.clone()]
449                );
450            }
451            Event::TaskListMarker(checked) => {
452                info!(
453                    "{}TaskListMarker Checked={:?} {:?} {:?}",
454                    " ".repeat(ind),
455                    checked,
456                    r.clone(),
457                    &txt[r.clone()]
458                );
459            }
460        }
461    }
462
463    let rdef = it.reference_definitions();
464    for (rstr, rdef) in rdef.iter() {
465        info!(
466            "ReferenceDefinition {:?} {:?} = {:?} {:?}",
467            rdef.span,
468            rstr,
469            rdef.dest.as_ref(),
470            rdef.title.as_ref().map(|v| v.as_ref())
471        )
472    }
473}