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
//! Custom rendering of fenced code blocks.
//!
//! A [`BlockRenderer`] draws fenced code blocks of certain languages in
//! WYSIWYG mode instead of showing their code, e.g. formulas for `math`,
//! diagrams for `mermaid` or a chart for `csv`. The document keeps the code
//! block, so the Markdown does not change:
//!
//! * the block is drawn by the renderer while the caret is elsewhere,
//! * clicking it or moving the caret into it shows the code for editing,
//! * without the renderer (or when it returns `None`), it is a normal code
//! block.
//!
//! Renderers draw with Iced's canvas [`Frame`], so they work on the desktop
//! and in the browser.
//!
//! ```
//! use iced_markdown_editor::extension::{
//! BlockRenderer, Color, Frame, Point, Rectangle, RenderRequest, Size,
//! };
//!
//! /// Draws ```` ```swatch ```` blocks (one `r g b` per line, 0-255) as colour swatches.
//! struct Swatches;
//!
//! fn colors(code: &str) -> Vec<Color> {
//! code.lines()
//! .filter_map(|line| {
//! let rgb: Vec<u8> = line.split_whitespace().filter_map(|n| n.parse().ok()).collect();
//! (rgb.len() == 3).then(|| Color::from_rgb8(rgb[0], rgb[1], rgb[2]))
//! })
//! .collect()
//! }
//!
//! impl BlockRenderer for Swatches {
//! fn languages(&self) -> Vec<String> {
//! vec!["swatch".into()]
//! }
//!
//! fn measure(&self, request: &RenderRequest<'_>) -> Option<Size> {
//! let count = colors(request.code).len();
//! (count > 0).then(|| Size::new(count as f32 * 40.0 * request.zoom, 32.0 * request.zoom))
//! }
//!
//! fn draw(&self, frame: &mut Frame, bounds: Rectangle, request: &RenderRequest<'_>) {
//! let size = 40.0 * request.zoom;
//! for (i, color) in colors(request.code).into_iter().enumerate() {
//! let at = Point::new(bounds.x + i as f32 * size, bounds.y);
//! frame.fill_rectangle(at, Size::new(size - 4.0, bounds.height), color);
//! }
//! }
//! }
//! ```
use crateEditorStyle;
/// Types used by renderers (re-exports from `iced`).
pub use Frame;
pub use ;
/// One code block to measure or draw.
/// Draws fenced code blocks of some languages instead of their code.
///
/// [`measure`](Self::measure) is called on layout and cached per code,
/// size and zoom; [`draw`](Self::draw) is called when the page is redrawn.