1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
//! Module containing the `Renderer` interface for constructing a
//! particular text output.

use crate::Colour;
use crate::Error;

pub mod text_renderer;

/// A type which is a backend for HTML to text rendering.
pub trait Renderer {
    /// Add an empty line to the output (ie between blocks).
    fn add_empty_line(&mut self) -> crate::Result<()>;

    /// Create a sub-renderer for nested blocks.
    fn new_sub_renderer(&self, width: usize) -> crate::Result<Self> where Self: Sized;

    /// Start a new block.
    fn start_block(&mut self) -> crate::Result<()>;

    /// Mark the end of a block.
    fn end_block(&mut self);

    /// Start a new line, if necessary (but don't add a new line).
    fn new_line(&mut self) -> Result<(), Error>;

    /// Start a new line.
    fn new_line_hard(&mut self) -> Result<(), Error>;

    /// Add a horizontal table border.
    fn add_horizontal_border(&mut self) -> Result<(), Error>;

    /// Add a horizontal border which is not the full width
    fn add_horizontal_border_width(&mut self, #[allow(unused_variables)] width: usize)
    -> Result<(), Error> {
        self.add_horizontal_border()
    }

    /// Begin a preformatted block.  Until the corresponding end,
    /// whitespace will used verbatim.  Pre regions can nest.
    fn start_pre(&mut self);

    /// Finish a preformatted block started with `start_pre`.
    fn end_pre(&mut self);

    /// Add some inline text (which should be wrapped at the
    /// appropriate width) to the current block.
    fn add_inline_text(&mut self, text: &str) -> crate::Result<()>;

    /// Return the current width in character cells
    fn width(&self) -> usize;

    /// Add a line to the current block without starting a new one.
    fn add_block_line(&mut self, line: &str);

    /// Add a new block from a sub renderer, and prefix every line by the
    /// corresponding text from each iteration of prefixes.
    fn append_subrender<'a, I>(&mut self, other: Self, prefixes: I)
    -> Result<(), Error>
    where
        I: Iterator<Item = &'a str>;

    /// Append a set of sub renderers joined left-to-right with a vertical line,
    /// and add a horizontal line below.
    /// If collapse is true, then merge top/bottom borders of the subrenderer
    /// with the surrounding one.
    fn append_columns_with_borders<I>(&mut self, cols: I, collapse: bool)
    -> Result<(), Error>
    where
        I: IntoIterator<Item = Self>,
        Self: Sized;

    /// Append a set of sub renderers joined vertically with lines, for tables
    /// which would otherwise be too wide for the screen.
    fn append_vert_row<I>(&mut self, cols: I) -> Result<(), Error>
    where
        I: IntoIterator<Item = Self>,
        Self: Sized;

    /// Returns true if this renderer has no content.
    fn empty(&self) -> bool;

    /// Return the length of the contained text.
    fn text_len(&self) -> usize;

    /// Start a hyperlink
    /// TODO: return sub-builder or similar to make misuse
    /// of start/link harder?
    fn start_link(&mut self, target: &str) -> crate::Result<()>;

    /// Finish a hyperlink started earlier.
    fn end_link(&mut self) -> crate::Result<()>;

    /// Start an emphasised region
    fn start_emphasis(&mut self) -> crate::Result<()>;

    /// Finish emphasised text started earlier.
    fn end_emphasis(&mut self) -> crate::Result<()>;

    /// Start a strong region
    fn start_strong(&mut self) -> crate::Result<()>;

    /// Finish strong text started earlier.
    fn end_strong(&mut self) -> crate::Result<()>;

    /// Start a strikeout region
    fn start_strikeout(&mut self) -> crate::Result<()>;

    /// Finish strikeout text started earlier.
    fn end_strikeout(&mut self) -> crate::Result<()>;

    /// Start a code region
    fn start_code(&mut self) -> crate::Result<()>;

    /// End a code region
    fn end_code(&mut self) -> crate::Result<()>;

    /// Add an image
    fn add_image(&mut self, src: &str, title: &str) -> crate::Result<()>;

    /// Get prefix string of header in specific level.
    fn header_prefix(&mut self, level: usize) -> String;

    /// Get prefix string of quoted block.
    fn quote_prefix(&mut self) -> String;

    /// Get prefix string of unordered list item.
    fn unordered_item_prefix(&mut self) -> String;

    /// Get prefix string of ith ordered list item.
    fn ordered_item_prefix(&mut self, i: i64) -> String;

    /// Record the start of a named HTML fragment
    fn record_frag_start(&mut self, fragname: &str);

    /// Push some CSS classes
    fn push_colour(&mut self, colour: Colour);

    /// Pop the last CSS classes pushed
    fn pop_colour(&mut self);
}