tangled
alpha
login
or
join now
eldridge.cam
/
paper-terminal
0
fork
atom
Print Markdown to a paper in your terminal
0
fork
atom
overview
issues
pulls
pipelines
Update pulldown-cmark
eldridge.cam
5 years ago
435fe488
0febb5a4
+220
-130
3 changed files
expand all
collapse all
unified
split
Cargo.lock
Cargo.toml
src
printer.rs
+2
-2
Cargo.lock
···
520
521
[[package]]
522
name = "pulldown-cmark"
523
-
version = "0.4.1"
524
source = "registry+https://github.com/rust-lang/crates.io-index"
525
-
checksum = "d1b74cc784b038a9921fd1a48310cc2e238101aa8ae0b94201e2d85121dd68b5"
526
dependencies = [
527
"bitflags",
528
"getopts",
···
520
521
[[package]]
522
name = "pulldown-cmark"
523
+
version = "0.8.0"
524
source = "registry+https://github.com/rust-lang/crates.io-index"
525
+
checksum = "ffade02495f22453cd593159ea2f59827aae7f53fa8323f756799b670881dcf8"
526
dependencies = [
527
"bitflags",
528
"getopts",
+1
-1
Cargo.toml
···
19
[dependencies]
20
structopt = "0.3"
21
terminal_size = "0.1"
22
-
pulldown-cmark = "0.4"
23
ansi_term = "0.12"
24
image = "0.23"
25
console = "0.13"
···
19
[dependencies]
20
structopt = "0.3"
21
terminal_size = "0.1"
22
+
pulldown-cmark = "0.8"
23
ansi_term = "0.12"
24
image = "0.23"
25
console = "0.13"
+217
-127
src/printer.rs
···
1
-
use std::convert::{TryInto, TryFrom};
2
-
use std::io::{Read as _, Write as _};
3
-
use std::process::{Command, Stdio};
4
-
use ansi_term::Style;
5
-
use pulldown_cmark::{Alignment, Event, Tag};
6
-
use image::{self, GenericImageView as _};
7
-
use console::{measure_text_width, AnsiCodeIterator};
8
-
use syncat_stylesheet::{Stylesheet, Query};
9
use crate::termpix;
10
use crate::words::Words;
11
-
use crate::table::Table;
0
0
0
0
0
0
0
12
13
#[derive(Debug, PartialEq)]
14
enum Scope {
···
19
Strikethrough,
20
Link,
21
Caption,
22
-
Rule,
23
FootnoteDefinition,
24
FootnoteReference,
25
FootnoteContent,
26
-
List(Option<usize>),
27
-
ListItem(Option<usize>, bool),
28
Code,
29
CodeBlock(String),
30
BlockQuote,
···
32
TableHead,
33
TableRow,
34
TableCell,
35
-
Heading(i32),
36
}
37
38
impl Scope {
···
45
Scope::BlockQuote => 4,
46
Scope::Heading(2) => 5,
47
Scope::Heading(..) => 4,
48
-
_ => 0
49
}
50
}
51
···
82
Scope::CodeBlock(..) => 2,
83
Scope::Heading(2) => 5,
84
Scope::Heading(..) => 4,
85
-
_ => 0
86
}
87
}
88
···
105
Strikethrough => "strikethrough",
106
Link => "link",
107
Caption => "caption",
108
-
Rule => "hr",
109
FootnoteDefinition => "footnote-def",
110
FootnoteReference => "footnote-ref",
111
FootnoteContent => "footnote",
···
144
}
145
146
impl<'a> Printer<'a> {
147
-
pub fn new(centering: &'a str, margin: &'a str, width: usize, stylesheet: &'a Stylesheet, opts: &'a crate::Opts) -> Printer<'a> {
0
0
0
0
0
0
148
Printer {
149
centering,
150
margin,
···
218
}
219
220
fn resolve_scopes(stylesheet: &Stylesheet, scopes: &[&str], token: Option<&str>) -> Style {
221
-
if scopes.is_empty() { return Style::default(); }
0
0
222
let mut query = Query::new(scopes[0], token.unwrap_or(scopes[0]));
223
let mut index = vec![];
224
for scope in &scopes[1..] {
225
query[&index[..]].add_child(Query::new(*scope, token.unwrap_or(scope)));
226
index.push(0);
227
}
228
-
stylesheet.style(&query).unwrap_or_default().try_into().unwrap_or_default()
0
0
0
0
229
}
230
231
fn style2(&self, token: Option<&str>) -> Style {
···
237
}
238
239
fn shadow(&self) -> String {
240
-
format!("{}", Style::try_from(self.stylesheet.style(&"shadow".into()).unwrap_or_default()).unwrap_or_default().paint(" "))
0
0
0
0
0
241
}
242
243
fn paper_style(&self) -> Style {
244
-
Style::try_from(self.stylesheet.style(&"paper".into()).unwrap_or_default()).unwrap_or_default()
0
245
}
246
247
fn queue_empty(&mut self) {
···
256
self.centering,
257
self.margin,
258
prefix,
259
-
self.paper_style().paint(" ".repeat(self.width - prefix_len - suffix_len)),
0
260
suffix,
261
self.margin,
262
self.shadow(),
···
272
self.centering,
273
self.margin,
274
prefix,
275
-
self.style().paint("─".repeat(self.width - prefix_len - suffix_len)),
0
276
suffix,
277
self.margin,
278
self.shadow(),
···
282
fn print_table(&mut self) {
283
let alignments = if let Some(Scope::Table(alignments)) = self.scope.last() {
284
alignments
285
-
} else { return };
0
0
286
let (heading, rows) = std::mem::replace(&mut self.table, (vec![], vec![]));
287
let available_width = self.width - self.prefix_len() - self.suffix_len();
288
-
let table_str = Table::new(heading, rows, available_width)
289
-
.print(self.paper_style(), alignments);
290
for line in table_str.lines() {
291
let (prefix, _) = self.prefix();
292
let (suffix, _) = self.suffix();
···
296
self.margin,
297
line,
298
prefix,
299
-
self.paper_style().paint(" ".repeat(available_width - measure_text_width(line))),
0
300
suffix,
301
self.margin,
302
self.shadow(),
···
352
output = format!("{}{}\n", output, prefix);
353
line = &line[prefix.len()..];
354
}
355
-
format!("{}{}{}\n", output, line, " ".repeat(available_width - line.chars().count()))
0
0
0
0
0
356
})
357
.collect()
358
};
359
360
-
let (prefix, _) = first_prefix.take().unwrap_or_else(|| self.prefix2(Some(&[&language_context[..]])));
361
-
let (suffix, _) = first_suffix.take().unwrap_or_else(|| self.suffix2(Some(&[&language_context[..]])));
0
0
0
0
362
println!(
363
"{}{}{}{}{}{}{}",
364
self.centering,
···
401
);
402
}
403
404
-
let (prefix, _) = first_prefix.take().unwrap_or_else(|| self.prefix2(Some(&[&language_context[..]])));
405
-
let (suffix, _) = first_suffix.take().unwrap_or_else(|| self.suffix2(Some(&[&language_context[..]])));
0
0
0
0
406
println!(
407
"{}{}{}{}{}{}{}",
408
self.centering,
409
self.margin,
410
prefix,
411
-
format!("{}{}",
412
-
style.paint(" ".repeat(available_width - lang.chars().count())),
413
-
self.style3(Some(&[&language_context[..]]), Some("lang-tag")).paint(lang)
0
0
414
),
415
suffix,
416
self.margin,
417
self.shadow(),
418
);
419
-
420
}
421
_ => {}
422
}
···
426
if !self.buffer.is_empty() {
427
return;
428
}
429
-
if self.scope.iter().find(|scope| if let Scope::Table(..) = scope { true } else { false }).is_some() {
0
0
0
0
0
0
0
0
0
0
0
0
0
0
430
return;
431
}
432
-
if self.content.is_empty() { return }
433
let (prefix, prefix_len) = self.prefix();
434
let (suffix, suffix_len) = self.suffix();
435
println!(
···
439
prefix,
440
self.content,
441
suffix,
442
-
self.paper_style().paint(" ".repeat(self.width - measure_text_width(&self.content) - prefix_len - suffix_len)),
0
0
0
0
443
self.margin,
444
self.shadow(),
445
);
···
447
}
448
449
fn target(&mut self) -> &mut String {
450
-
if self.scope.iter().find(|scope| *scope == &Scope::TableHead).is_some() {
0
0
0
0
0
451
self.table.0.last_mut().unwrap()
452
-
} else if self.scope.iter().find(|scope| *scope == &Scope::TableRow).is_some() {
0
0
0
0
0
453
self.table.1.last_mut().unwrap().last_mut().unwrap()
454
} else {
455
&mut self.content
456
}
457
}
458
459
-
fn handle_text<S>(&mut self, text: S) where S: AsRef<str> {
0
0
0
460
let s = text.as_ref();
461
if let Some(Scope::CodeBlock(..)) = self.scope.last() {
462
self.buffer += s;
···
464
}
465
let style = self.style();
466
for word in Words::new(s) {
467
-
if measure_text_width(&self.content) + word.len() + self.prefix_len() + self.suffix_len() > self.width {
0
0
0
0
0
468
self.flush();
469
}
470
let mut word = if self.target().is_empty() {
···
491
self.empty();
492
}
493
match tag {
494
-
Tag::Paragraph => { self.flush(); }
495
-
Tag::Rule => {
496
self.flush();
497
-
self.scope.push(Scope::Rule);
498
}
499
-
Tag::Header(level) => {
500
self.flush();
501
if level == 1 {
502
self.print_rule();
···
507
self.flush();
508
self.scope.push(Scope::BlockQuote);
509
}
510
-
Tag::CodeBlock(language) => {
0
0
0
0
511
self.flush();
512
self.scope.push(Scope::CodeBlock(language.to_string()));
513
}
···
531
self.flush();
532
self.scope.push(Scope::FootnoteContent);
533
}
534
-
Tag::HtmlBlock => { /* do nothing */ }
535
-
Tag::Table(columns) => { self.scope.push(Scope::Table(columns)) }
536
Tag::TableHead => {
537
self.scope.push(Scope::TableHead);
538
}
···
542
}
543
Tag::TableCell => {
544
self.scope.push(Scope::TableCell);
545
-
if self.scope.iter().find(|scope| *scope == &Scope::TableHead).is_some() {
0
0
0
0
0
546
self.table.0.push(String::new());
547
} else {
548
self.table.1.last_mut().unwrap().push(String::new());
549
}
550
}
551
-
Tag::Emphasis => { self.scope.push(Scope::Italic); }
552
-
Tag::Strong => { self.scope.push(Scope::Bold); }
553
-
Tag::Strikethrough => { self.scope.push(Scope::Strikethrough); }
554
-
Tag::Code => { self.scope.push(Scope::Code); }
0
0
0
0
0
555
Tag::Link(_link_type, _destination, _title) => {
556
self.scope.push(Scope::Link);
557
}
···
559
self.flush();
560
561
if !self.opts.no_images {
562
-
let available_width = self.width - self.prefix_len() - self.suffix_len();
0
563
match image::open(destination.as_ref()) {
564
Ok(image) => {
565
let (mut width, mut height) = image.dimensions();
···
626
}
627
}
628
629
-
Event::End(tag) => {
630
-
match tag {
631
-
Tag::Paragraph => {
632
-
self.flush();
633
-
self.queue_empty();
634
-
}
635
-
Tag::Header(level) => {
636
-
self.flush();
637
-
self.scope.pop();
638
-
if level == 1 {
639
-
self.print_rule();
640
-
}
641
-
self.queue_empty();
642
-
}
643
-
Tag::Rule => {
644
-
self.flush();
645
self.print_rule();
646
-
self.scope.pop();
647
-
}
648
-
Tag::List(..) => {
649
-
self.flush();
650
-
self.scope.pop();
651
-
self.queue_empty();
652
-
}
653
-
Tag::Item => {
654
-
self.flush();
655
-
self.scope.pop();
656
-
if let Some(Scope::List(index)) = self.scope.last_mut() {
657
-
*index = index.map(|x| x + 1);
658
-
}
659
-
},
660
-
Tag::BlockQuote => {
661
-
self.flush();
662
-
self.scope.pop();
663
-
self.queue_empty();
664
}
665
-
Tag::Table(..) => {
666
-
self.print_table();
667
-
self.scope.pop();
668
-
self.queue_empty();
669
-
}
670
-
Tag::CodeBlock(..) => {
671
-
self.flush_buffer();
672
-
self.scope.pop();
673
-
self.queue_empty();
674
-
}
675
-
Tag::Link(_link_type, destination, title) => {
676
-
if !title.is_empty() && !destination.is_empty() && !self.opts.hide_urls {
677
-
self.handle_text(format!(" <{}: {}>", title, destination));
678
-
} else if !destination.is_empty() && !self.opts.hide_urls {
679
-
self.handle_text(format!(" <{}>", destination));
680
-
} else if !title.is_empty() {
681
-
self.handle_text(format!(" <{}>", title));
682
-
}
683
-
self.scope.pop();
684
-
}
685
-
Tag::Image(_link_type, _destination, _title) => {
686
-
self.flush();
687
-
self.scope.pop();
688
-
self.scope.pop();
689
-
self.queue_empty();
690
}
691
-
Tag::FootnoteDefinition(..) => {
692
-
self.flush();
693
-
self.scope.pop();
694
-
self.queue_empty();
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
695
}
696
-
Tag::HtmlBlock => { /* do nothing */ }
697
-
_ => { self.scope.pop(); }
0
0
0
0
0
698
}
0
0
0
0
0
0
0
0
0
0
0
0
699
}
700
-
Event::Text(text) => { self.handle_text(text); }
0
0
0
0
0
0
0
701
Event::Html(_text) => { /* unimplemented */ }
702
-
Event::InlineHtml(_text) => { /* unimplemented */ }
703
-
Event::FootnoteReference(text) => {
704
self.scope.push(Scope::FootnoteReference);
705
-
self.handle_text(&format!("[{}]", text));
706
self.scope.pop();
707
}
708
-
Event::SoftBreak => { self.handle_text(" "); }
709
-
Event::HardBreak => { self.flush(); }
0
0
0
0
710
Event::TaskListMarker(checked) => {
711
self.handle_text(if checked { "[✓] " } else { "[ ] " });
712
}
···
1
+
use crate::table::Table;
0
0
0
0
0
0
0
2
use crate::termpix;
3
use crate::words::Words;
4
+
use ansi_term::Style;
5
+
use console::{measure_text_width, AnsiCodeIterator};
6
+
use image::{self, GenericImageView as _};
7
+
use pulldown_cmark::{Alignment, CodeBlockKind, Event, Tag};
8
+
use std::convert::{TryFrom, TryInto};
9
+
use std::io::{Read as _, Write as _};
10
+
use std::process::{Command, Stdio};
11
+
use syncat_stylesheet::{Query, Stylesheet};
12
13
#[derive(Debug, PartialEq)]
14
enum Scope {
···
19
Strikethrough,
20
Link,
21
Caption,
0
22
FootnoteDefinition,
23
FootnoteReference,
24
FootnoteContent,
25
+
List(Option<u64>),
26
+
ListItem(Option<u64>, bool),
27
Code,
28
CodeBlock(String),
29
BlockQuote,
···
31
TableHead,
32
TableRow,
33
TableCell,
34
+
Heading(u32),
35
}
36
37
impl Scope {
···
44
Scope::BlockQuote => 4,
45
Scope::Heading(2) => 5,
46
Scope::Heading(..) => 4,
47
+
_ => 0,
48
}
49
}
50
···
81
Scope::CodeBlock(..) => 2,
82
Scope::Heading(2) => 5,
83
Scope::Heading(..) => 4,
84
+
_ => 0,
85
}
86
}
87
···
104
Strikethrough => "strikethrough",
105
Link => "link",
106
Caption => "caption",
0
107
FootnoteDefinition => "footnote-def",
108
FootnoteReference => "footnote-ref",
109
FootnoteContent => "footnote",
···
142
}
143
144
impl<'a> Printer<'a> {
145
+
pub fn new(
146
+
centering: &'a str,
147
+
margin: &'a str,
148
+
width: usize,
149
+
stylesheet: &'a Stylesheet,
150
+
opts: &'a crate::Opts,
151
+
) -> Printer<'a> {
152
Printer {
153
centering,
154
margin,
···
222
}
223
224
fn resolve_scopes(stylesheet: &Stylesheet, scopes: &[&str], token: Option<&str>) -> Style {
225
+
if scopes.is_empty() {
226
+
return Style::default();
227
+
}
228
let mut query = Query::new(scopes[0], token.unwrap_or(scopes[0]));
229
let mut index = vec![];
230
for scope in &scopes[1..] {
231
query[&index[..]].add_child(Query::new(*scope, token.unwrap_or(scope)));
232
index.push(0);
233
}
234
+
stylesheet
235
+
.style(&query)
236
+
.unwrap_or_default()
237
+
.try_into()
238
+
.unwrap_or_default()
239
}
240
241
fn style2(&self, token: Option<&str>) -> Style {
···
247
}
248
249
fn shadow(&self) -> String {
250
+
format!(
251
+
"{}",
252
+
Style::try_from(self.stylesheet.style(&"shadow".into()).unwrap_or_default())
253
+
.unwrap_or_default()
254
+
.paint(" ")
255
+
)
256
}
257
258
fn paper_style(&self) -> Style {
259
+
Style::try_from(self.stylesheet.style(&"paper".into()).unwrap_or_default())
260
+
.unwrap_or_default()
261
}
262
263
fn queue_empty(&mut self) {
···
272
self.centering,
273
self.margin,
274
prefix,
275
+
self.paper_style()
276
+
.paint(" ".repeat(self.width - prefix_len - suffix_len)),
277
suffix,
278
self.margin,
279
self.shadow(),
···
289
self.centering,
290
self.margin,
291
prefix,
292
+
self.style()
293
+
.paint("─".repeat(self.width - prefix_len - suffix_len)),
294
suffix,
295
self.margin,
296
self.shadow(),
···
300
fn print_table(&mut self) {
301
let alignments = if let Some(Scope::Table(alignments)) = self.scope.last() {
302
alignments
303
+
} else {
304
+
return;
305
+
};
306
let (heading, rows) = std::mem::replace(&mut self.table, (vec![], vec![]));
307
let available_width = self.width - self.prefix_len() - self.suffix_len();
308
+
let table_str =
309
+
Table::new(heading, rows, available_width).print(self.paper_style(), alignments);
310
for line in table_str.lines() {
311
let (prefix, _) = self.prefix();
312
let (suffix, _) = self.suffix();
···
316
self.margin,
317
line,
318
prefix,
319
+
self.paper_style()
320
+
.paint(" ".repeat(available_width - measure_text_width(line))),
321
suffix,
322
self.margin,
323
self.shadow(),
···
373
output = format!("{}{}\n", output, prefix);
374
line = &line[prefix.len()..];
375
}
376
+
format!(
377
+
"{}{}{}\n",
378
+
output,
379
+
line,
380
+
" ".repeat(available_width - line.chars().count())
381
+
)
382
})
383
.collect()
384
};
385
386
+
let (prefix, _) = first_prefix
387
+
.take()
388
+
.unwrap_or_else(|| self.prefix2(Some(&[&language_context[..]])));
389
+
let (suffix, _) = first_suffix
390
+
.take()
391
+
.unwrap_or_else(|| self.suffix2(Some(&[&language_context[..]])));
392
println!(
393
"{}{}{}{}{}{}{}",
394
self.centering,
···
431
);
432
}
433
434
+
let (prefix, _) = first_prefix
435
+
.take()
436
+
.unwrap_or_else(|| self.prefix2(Some(&[&language_context[..]])));
437
+
let (suffix, _) = first_suffix
438
+
.take()
439
+
.unwrap_or_else(|| self.suffix2(Some(&[&language_context[..]])));
440
println!(
441
"{}{}{}{}{}{}{}",
442
self.centering,
443
self.margin,
444
prefix,
445
+
format!(
446
+
"{}{}",
447
+
style.paint(" ".repeat(available_width - lang.chars().count())),
448
+
self.style3(Some(&[&language_context[..]]), Some("lang-tag"))
449
+
.paint(lang)
450
),
451
suffix,
452
self.margin,
453
self.shadow(),
454
);
0
455
}
456
_ => {}
457
}
···
461
if !self.buffer.is_empty() {
462
return;
463
}
464
+
if self
465
+
.scope
466
+
.iter()
467
+
.find(|scope| {
468
+
if let Scope::Table(..) = scope {
469
+
true
470
+
} else {
471
+
false
472
+
}
473
+
})
474
+
.is_some()
475
+
{
476
+
return;
477
+
}
478
+
if self.content.is_empty() {
479
return;
480
}
0
481
let (prefix, prefix_len) = self.prefix();
482
let (suffix, suffix_len) = self.suffix();
483
println!(
···
487
prefix,
488
self.content,
489
suffix,
490
+
self.paper_style().paint(
491
+
" ".repeat(
492
+
self.width - measure_text_width(&self.content) - prefix_len - suffix_len
493
+
)
494
+
),
495
self.margin,
496
self.shadow(),
497
);
···
499
}
500
501
fn target(&mut self) -> &mut String {
502
+
if self
503
+
.scope
504
+
.iter()
505
+
.find(|scope| *scope == &Scope::TableHead)
506
+
.is_some()
507
+
{
508
self.table.0.last_mut().unwrap()
509
+
} else if self
510
+
.scope
511
+
.iter()
512
+
.find(|scope| *scope == &Scope::TableRow)
513
+
.is_some()
514
+
{
515
self.table.1.last_mut().unwrap().last_mut().unwrap()
516
} else {
517
&mut self.content
518
}
519
}
520
521
+
fn handle_text<S>(&mut self, text: S)
522
+
where
523
+
S: AsRef<str>,
524
+
{
525
let s = text.as_ref();
526
if let Some(Scope::CodeBlock(..)) = self.scope.last() {
527
self.buffer += s;
···
529
}
530
let style = self.style();
531
for word in Words::new(s) {
532
+
if measure_text_width(&self.content)
533
+
+ word.len()
534
+
+ self.prefix_len()
535
+
+ self.suffix_len()
536
+
> self.width
537
+
{
538
self.flush();
539
}
540
let mut word = if self.target().is_empty() {
···
561
self.empty();
562
}
563
match tag {
564
+
Tag::Paragraph => {
0
565
self.flush();
0
566
}
567
+
Tag::Heading(level) => {
568
self.flush();
569
if level == 1 {
570
self.print_rule();
···
575
self.flush();
576
self.scope.push(Scope::BlockQuote);
577
}
578
+
Tag::CodeBlock(CodeBlockKind::Indented) => {
579
+
self.flush();
580
+
self.scope.push(Scope::CodeBlock("".to_string()));
581
+
}
582
+
Tag::CodeBlock(CodeBlockKind::Fenced(language)) => {
583
self.flush();
584
self.scope.push(Scope::CodeBlock(language.to_string()));
585
}
···
603
self.flush();
604
self.scope.push(Scope::FootnoteContent);
605
}
606
+
Tag::Table(columns) => self.scope.push(Scope::Table(columns)),
0
607
Tag::TableHead => {
608
self.scope.push(Scope::TableHead);
609
}
···
613
}
614
Tag::TableCell => {
615
self.scope.push(Scope::TableCell);
616
+
if self
617
+
.scope
618
+
.iter()
619
+
.find(|scope| *scope == &Scope::TableHead)
620
+
.is_some()
621
+
{
622
self.table.0.push(String::new());
623
} else {
624
self.table.1.last_mut().unwrap().push(String::new());
625
}
626
}
627
+
Tag::Emphasis => {
628
+
self.scope.push(Scope::Italic);
629
+
}
630
+
Tag::Strong => {
631
+
self.scope.push(Scope::Bold);
632
+
}
633
+
Tag::Strikethrough => {
634
+
self.scope.push(Scope::Strikethrough);
635
+
}
636
Tag::Link(_link_type, _destination, _title) => {
637
self.scope.push(Scope::Link);
638
}
···
640
self.flush();
641
642
if !self.opts.no_images {
643
+
let available_width =
644
+
self.width - self.prefix_len() - self.suffix_len();
645
match image::open(destination.as_ref()) {
646
Ok(image) => {
647
let (mut width, mut height) = image.dimensions();
···
708
}
709
}
710
711
+
Event::End(tag) => match tag {
712
+
Tag::Paragraph => {
713
+
self.flush();
714
+
self.queue_empty();
715
+
}
716
+
Tag::Heading(level) => {
717
+
self.flush();
718
+
self.scope.pop();
719
+
if level == 1 {
0
0
0
0
0
0
0
720
self.print_rule();
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
721
}
722
+
self.queue_empty();
723
+
}
724
+
Tag::List(..) => {
725
+
self.flush();
726
+
self.scope.pop();
727
+
self.queue_empty();
728
+
}
729
+
Tag::Item => {
730
+
self.flush();
731
+
self.scope.pop();
732
+
if let Some(Scope::List(index)) = self.scope.last_mut() {
733
+
*index = index.map(|x| x + 1);
0
0
0
0
0
0
0
0
0
0
0
0
0
734
}
735
+
}
736
+
Tag::BlockQuote => {
737
+
self.flush();
738
+
self.scope.pop();
739
+
self.queue_empty();
740
+
}
741
+
Tag::Table(..) => {
742
+
self.print_table();
743
+
self.scope.pop();
744
+
self.queue_empty();
745
+
}
746
+
Tag::CodeBlock(..) => {
747
+
self.flush_buffer();
748
+
self.scope.pop();
749
+
self.queue_empty();
750
+
}
751
+
Tag::Link(_link_type, destination, title) => {
752
+
if !title.is_empty() && !destination.is_empty() && !self.opts.hide_urls {
753
+
self.handle_text(format!(" <{}: {}>", title, destination));
754
+
} else if !destination.is_empty() && !self.opts.hide_urls {
755
+
self.handle_text(format!(" <{}>", destination));
756
+
} else if !title.is_empty() {
757
+
self.handle_text(format!(" <{}>", title));
758
}
759
+
self.scope.pop();
760
+
}
761
+
Tag::Image(_link_type, _destination, _title) => {
762
+
self.flush();
763
+
self.scope.pop();
764
+
self.scope.pop();
765
+
self.queue_empty();
766
}
767
+
Tag::FootnoteDefinition(..) => {
768
+
self.flush();
769
+
self.scope.pop();
770
+
self.queue_empty();
771
+
}
772
+
_ => {
773
+
self.scope.pop();
774
+
}
775
+
},
776
+
Event::Rule => {
777
+
self.flush();
778
+
self.print_rule();
779
}
780
+
Event::Text(text) => {
781
+
self.handle_text(text);
782
+
}
783
+
Event::Code(text) => {
784
+
self.scope.push(Scope::Code);
785
+
self.handle_text(text);
786
+
self.scope.pop();
787
+
}
788
Event::Html(_text) => { /* unimplemented */ }
789
+
Event::FootnoteReference(text) => {
0
790
self.scope.push(Scope::FootnoteReference);
791
+
self.handle_text(&format!("[{}]", text));
792
self.scope.pop();
793
}
794
+
Event::SoftBreak => {
795
+
self.handle_text(" ");
796
+
}
797
+
Event::HardBreak => {
798
+
self.flush();
799
+
}
800
Event::TaskListMarker(checked) => {
801
self.handle_text(if checked { "[✓] " } else { "[ ] " });
802
}