1use std::collections::{BTreeMap, HashMap};
2
3use serde::Deserialize;
4
5#[derive(Clone, Debug, Default, Deserialize, PartialEq)]
7#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
8#[serde(default, rename_all = "camelCase")]
9#[cfg_attr(feature = "schema", schemars(rename = "StringifyOptions"))]
10pub struct Stringify {
11 pub allow_dangerous_html: bool,
13 pub allow_dangerous_characters: bool,
15 pub allow_parse_errors: bool,
17 pub bogus_comments: bool,
19 pub close_empty_elements: bool,
21 pub close_self_closing: bool,
23 pub collapse_empty_attributes: bool,
25 pub omit_optional_tags: bool,
27 pub prefer_unquoted: bool,
29 pub quote: Option<String>,
31 pub quote_smart: bool,
33 pub space: Option<String>,
35 pub tight_attributes: bool,
37 pub tight_comma_separated_lists: bool,
39 pub tight_doctype: bool,
41 pub tight_self_closing: bool,
43 pub upper_doctype: bool,
45 pub voids: Option<Vec<String>>,
47}
48
49#[derive(Clone, Debug, Default, Deserialize)]
51#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
52#[serde(default, rename_all = "camelCase")]
53#[cfg_attr(feature = "schema", schemars(rename = "ParseOptions"))]
54pub struct Parse {
55 pub fragment: bool,
57 pub emit_parse_errors: bool,
59 pub verbose: bool,
61}
62
63#[derive(Clone, Debug, Default, Deserialize)]
66#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
67#[serde(default, rename_all = "camelCase")]
68#[cfg_attr(feature = "schema", schemars(rename = "SanitizeOptions"))]
69pub struct Sanitize {
70 pub allow_comments: Option<bool>,
72 pub allow_doctypes: Option<bool>,
74 pub ancestors: Option<HashMap<String, Vec<String>>>,
76 pub attributes: Option<HashMap<String, Vec<AttributeDefinition>>>,
79 pub clobber: Option<Vec<String>>,
81 pub clobber_prefix: Option<String>,
83 pub protocols: Option<HashMap<String, Vec<String>>>,
85 pub required: Option<HashMap<String, BTreeMap<String, Primitive>>>,
87 pub strip: Option<Vec<String>>,
89 pub tag_names: Option<Vec<String>>,
91}
92
93#[derive(Clone, Debug, Deserialize)]
95#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
96#[serde(untagged)]
97pub enum AttributeDefinition {
98 Name(String),
99 Values(Vec<Primitive>),
100}
101
102#[derive(Clone, Debug, PartialEq, Deserialize)]
104#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
105#[serde(untagged)]
106pub enum Primitive {
107 Boolean(bool),
108 Number(f64),
109 String(String),
110}
111
112#[derive(Clone, Debug, Default, Deserialize)]
115#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
116#[serde(default, rename_all = "camelCase")]
117#[cfg_attr(feature = "schema", schemars(rename = "HighlightOptions"))]
118pub struct Highlight {
119 pub themes: Option<serde_json::Map<String, serde_json::Value>>,
121 pub theme: Option<String>,
123 pub default_language: Option<String>,
125 pub fallback_language: Option<String>,
127 pub color_replacements: BTreeMap<String, ColorReplacement>,
130 pub add_language_class: bool,
132 pub inline: Option<InlineCode>,
135 pub meta_property: Option<String>,
138 pub transformers: Vec<HighlightTransformer>,
140 pub tokenize_max_line_length: Option<usize>,
144}
145
146#[derive(Clone, Debug, Deserialize)]
148#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
149#[serde(untagged)]
150pub enum ColorReplacement {
151 Color(String),
152 Theme(BTreeMap<String, String>),
153}
154
155#[derive(Clone, Copy, Debug, PartialEq, Eq, Deserialize)]
157#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
158pub enum InlineCode {
159 #[serde(rename = "tailing-curly-colon")]
160 TailingCurlyColon,
161}
162
163#[derive(Clone, Debug, Deserialize)]
165#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
166#[serde(untagged)]
167pub enum HighlightTransformer {
168 Name(TransformerName),
169 Configured(ConfiguredTransformer),
170}
171
172#[derive(Clone, Copy, Debug, PartialEq, Eq, Deserialize)]
174#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
175#[serde(rename_all = "camelCase")]
176pub enum TransformerName {
177 NotationDiff,
178 NotationFocus,
179 NotationHighlight,
180 NotationErrorLevel,
181 MetaHighlight,
182 MetaWordHighlight,
183 RenderLineNumber,
184}
185
186#[derive(Clone, Debug, Deserialize)]
188#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
189#[serde(tag = "name", rename_all = "camelCase")]
190pub enum ConfiguredTransformer {
191 #[serde(rename_all = "camelCase")]
193 NotationDiff {
194 class_line_add: Option<Classes>,
195 class_line_remove: Option<Classes>,
196 class_active_pre: Option<Classes>,
197 class_active_code: Option<Classes>,
198 },
199 #[serde(rename_all = "camelCase")]
201 NotationFocus {
202 class_active_line: Option<Classes>,
203 class_active_pre: Option<Classes>,
204 class_active_code: Option<Classes>,
205 },
206 #[serde(rename_all = "camelCase")]
208 NotationHighlight {
209 class_active_line: Option<Classes>,
210 class_active_pre: Option<Classes>,
211 class_active_code: Option<Classes>,
212 },
213 #[serde(rename_all = "camelCase")]
215 NotationErrorLevel {
216 class_map: Option<BTreeMap<String, Classes>>,
217 class_active_pre: Option<Classes>,
218 class_active_code: Option<Classes>,
219 },
220 #[serde(rename_all = "camelCase")]
222 MetaHighlight {
223 class_name: Option<Classes>,
224 #[serde(default)]
225 zero_indexed: bool,
226 },
227 #[serde(rename_all = "camelCase")]
229 MetaWordHighlight { class_name: Option<Classes> },
230 #[serde(rename_all = "camelCase")]
232 RenderLineNumber {
233 class_line_number: Option<Classes>,
234 start: Option<usize>,
235 },
236}
237
238#[derive(Clone, Debug, Deserialize)]
240#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
241#[serde(untagged)]
242pub enum Classes {
243 One(String),
244 Many(Vec<String>),
245}
246
247#[derive(Clone, Debug, Default, Deserialize)]
250#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
251#[serde(default, rename_all = "camelCase")]
252#[cfg_attr(feature = "schema", schemars(rename = "ExternalLinksOptions"))]
253pub struct ExternalLinks {
254 pub target: Option<String>,
256 pub rel: Option<Tokens>,
259 pub protocols: Option<Vec<String>>,
262 pub properties: Option<serde_json::Map<String, serde_json::Value>>,
264 pub content: Option<serde_json::Value>,
266 pub content_properties: Option<serde_json::Map<String, serde_json::Value>>,
268}
269
270#[derive(Clone, Debug, Deserialize)]
272#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
273#[serde(untagged)]
274pub enum Tokens {
275 One(String),
276 Many(Vec<String>),
277}
278
279#[derive(Clone, Debug, Default, Deserialize)]
282#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
283#[serde(default, rename_all = "camelCase")]
284#[cfg_attr(feature = "schema", schemars(rename = "KatexOptions"))]
285pub struct Katex {
286 pub output: Option<KatexOutput>,
288 pub leqno: bool,
290 pub fleqn: bool,
292 pub error_color: Option<String>,
294 pub macros: BTreeMap<String, String>,
296 pub min_rule_thickness: Option<f64>,
298 pub color_is_text_color: bool,
300 pub strict: Option<KatexStrict>,
303 pub trust: bool,
305 pub max_size: Option<f64>,
307 pub max_expand: Option<usize>,
309 pub global_group: bool,
311}
312
313#[derive(Clone, Copy, Debug, PartialEq, Deserialize)]
315#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
316#[serde(rename_all = "camelCase")]
317pub enum KatexOutput {
318 Html,
319 Mathml,
320 HtmlAndMathml,
321}
322
323#[derive(Clone, Debug, PartialEq, Deserialize)]
325#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
326#[serde(untagged)]
327pub enum KatexStrict {
328 Boolean(bool),
329 Mode(KatexStrictMode),
330}
331
332#[derive(Clone, Copy, Debug, PartialEq, Deserialize)]
334#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
335#[serde(rename_all = "camelCase")]
336pub enum KatexStrictMode {
337 Ignore,
338 Warn,
339 Error,
340}
341
342#[derive(Clone, Debug, Default, Deserialize)]
345#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
346#[serde(default, rename_all = "camelCase")]
347#[cfg_attr(feature = "schema", schemars(rename = "ExtractTocOptions"))]
348pub struct ExtractToc {
349 pub skip: Vec<String>,
352}
353
354#[derive(Clone, Debug, Default, Deserialize)]
357#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
358#[serde(default, rename_all = "camelCase")]
359#[cfg_attr(feature = "schema", schemars(rename = "SlugOptions"))]
360pub struct Slug {
361 pub prefix: String,
363 pub autolink: Option<Autolink>,
366}
367
368#[derive(Clone, Debug, Deserialize)]
370#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
371#[serde(untagged)]
372pub enum Autolink {
373 Enabled(bool),
374 Options(Box<AutolinkOptions>),
375}
376
377#[derive(Clone, Debug, Default, Deserialize)]
379#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
380#[serde(default, rename_all = "camelCase")]
381pub struct AutolinkOptions {
382 pub behavior: AutolinkBehavior,
385 pub properties: Option<serde_json::Map<String, serde_json::Value>>,
388 pub content: Option<serde_json::Value>,
391 pub group: Option<serde_json::Value>,
393 pub heading_properties: Option<serde_json::Map<String, serde_json::Value>>,
395 pub test: Option<TagNames>,
397}
398
399#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Deserialize)]
401#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
402#[serde(rename_all = "lowercase")]
403pub enum AutolinkBehavior {
404 #[default]
405 Prepend,
406 Append,
407 Wrap,
408 Before,
409 After,
410}
411
412#[derive(Clone, Debug, Deserialize)]
414#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
415#[serde(untagged)]
416pub enum TagNames {
417 One(String),
418 Many(Vec<String>),
419}
420
421#[derive(Clone, Debug, Default, Deserialize)]
423#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
424#[serde(default, rename_all = "camelCase")]
425#[cfg_attr(feature = "schema", schemars(rename = "ToMarkdownOptions"))]
426pub struct ToMarkdown {
427 pub document: bool,
429 pub newlines: bool,
431 pub checked: Option<String>,
433 pub unchecked: Option<String>,
435 pub quotes: Option<Vec<String>>,
438}
439
440#[derive(Clone, Debug, Default, Deserialize)]
443#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
444#[serde(default, rename_all = "camelCase")]
445#[cfg_attr(feature = "schema", schemars(rename = "RawOptions"))]
446pub struct Raw {
447 pub pass_through: Vec<String>,
450 pub tagfilter: bool,
452}
453
454#[derive(Clone, Debug, Default, Deserialize)]
457#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
458#[serde(default, rename_all = "camelCase")]
459#[cfg_attr(feature = "schema", schemars(rename = "FormatOptions"))]
460pub struct Format {
461 pub blanks: Vec<String>,
463 pub indent: Option<Indent>,
466 pub indent_initial: Option<bool>,
468 pub minify: Option<Minify>,
471}
472
473#[derive(Clone, Debug, Deserialize)]
475#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
476#[serde(untagged)]
477pub enum Minify {
478 Enabled(bool),
479 Options(MinifyOptions),
480}
481
482#[derive(Clone, Debug, Default, Deserialize)]
484#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
485#[serde(default, rename_all = "camelCase")]
486pub struct MinifyOptions {
487 pub newlines: bool,
489}
490
491impl Format {
492 pub(crate) fn minify_newlines(&self) -> Option<bool> {
494 match &self.minify {
495 Some(Minify::Enabled(true)) => Some(false),
496 Some(Minify::Options(options)) => Some(options.newlines),
497 Some(Minify::Enabled(false)) | None => None,
498 }
499 }
500}
501
502#[derive(Clone, Debug, Deserialize)]
504#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
505#[serde(untagged)]
506pub enum Indent {
507 Spaces(usize),
508 Text(String),
509}