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
//! Custom node definitions for the CommonMark AST.
use crate;
use crate;
use Any;
/// Trait for implementing custom node behavior for the CommonMark AST.
///
/// This trait defines methods that all custom node types must implement.
/// Users can implement dedicated block or inline rendering methods for CommonMark output and
/// optionally override the `html_write` method for HTML output.
///
/// The recommended way to implement this trait is through the `custom_node` macro,
/// which provides a default implementation of most methods and requires users to
/// implement only the node-specific logic.
///
/// # Example
///
/// ```rust
/// use ecow::EcoString;
/// use cmark_writer_macros::custom_node;
/// use cmark_writer::error::WriteResult;
/// use cmark_writer::writer::{HtmlWriteResult, HtmlWriter, InlineWriterProxy};
///
/// // Define a custom node with support for both CommonMark and HTML output
/// #[derive(Debug, Clone, PartialEq)]
/// #[custom_node(block=false, html_impl=true)]
/// struct HighlightNode {
/// content: EcoString,
/// color: EcoString,
/// }
///
/// impl HighlightNode {
/// // Required for CommonMark output
/// fn write_custom(&self, writer: &mut InlineWriterProxy) -> WriteResult<()> {
/// writer.write_str("<span style=\"background-color: ")?;
/// writer.write_str(&self.color)?;
/// writer.write_str("\">")?;
/// writer.write_str(&self.content)?;
/// writer.write_str("</span>")?;
/// Ok(())
/// }
///
/// // Optional HTML-specific implementation
/// fn write_html_custom(&self, writer: &mut HtmlWriter) -> HtmlWriteResult<()> {
/// writer.start_tag("span")?;
/// writer.attribute("style", &format!("background-color: {}", self.color))?;
/// writer.finish_tag()?;
/// writer.text(&self.content)?;
/// writer.end_tag("span")?;
/// Ok(())
/// }
/// }
/// ```
// NOTE: CustomNodeWriter trait is deprecated and will be removed in a future version.
// Custom nodes should now directly use the provided writer proxies instead.
/*
/// Trait for custom node writer implementation
pub trait CustomNodeWriter {
/// Write a string to the output
fn write_str(&mut self, s: &str) -> std::fmt::Result;
/// Write a character to the output
fn write_char(&mut self, c: char) -> std::fmt::Result;
}
*/
// Implement Clone for Box<dyn CustomNode>
// Implement PartialEq for Box<dyn CustomNode>