htmltoadf/
adf_structure.rs

1use serde_json::Value;
2use std::collections::HashMap;
3
4use crate::types::{
5    adf_content_type::{AdfContentType, AdfMark, AdfMarkAttributes},
6    adf_permitted_children::AdfPermittedChildren,
7};
8
9lazy_static! {
10  /**
11   * Placeholder empty child type. Does not permit any child types.
12   */
13  pub static ref EMPTY_CHILD_TYPE: AdfPermittedChildren = AdfPermittedChildren::any(&[]);
14
15  /**
16   * 1. LEGAL_CHILD_TYPES: The allowed nesting of ADF Types that we permit in our output doc.
17   */
18  pub static ref LEGAL_CHILD_TYPES: HashMap<String, AdfPermittedChildren> = HashMap::from([
19    (
20      String::from("paragraph"),
21      AdfPermittedChildren::any(&["text", "emoji", "hardBreak"])
22    ),
23    (
24      String::from("heading"),
25      AdfPermittedChildren::any(&["text", "emoji", "hardBreak"])
26    ),
27    (
28      String::from("bulletList"),
29      AdfPermittedChildren::any(&["listItem"])
30    ),
31    (
32      String::from("orderedList"),
33      AdfPermittedChildren::any(&["listItem"])
34    ),
35    (
36      String::from("blockquote"),
37      AdfPermittedChildren::any(&["paragraph"])
38    ),
39    (
40      String::from("codeBlock"),
41      AdfPermittedChildren::any(&["paragraph"])
42    ),
43    (
44      String::from("listItem"),
45      AdfPermittedChildren::any_starts_with(&["paragraph", "mediaSingle", "codeBlock"], &["paragraph", "mediaAdfPermittedChildren", "codeBlock", "orderedList", "bulletList"])
46    ),
47    (
48      String::from("table"),
49      AdfPermittedChildren::any(&["tableRow"])
50    ),
51    (
52      String::from("tableRow"),
53      AdfPermittedChildren::any(&["tableHeader","tableCell"])
54    ),
55    (
56      String::from("tableHeader"),
57      AdfPermittedChildren::any(&["codeBlock", "blockCard", "paragraph", "bulletList", "mediaSingle", "orderedList", "heading", "panel", "blockquote", "rule", "mediaGroup", "decisionList", "taskList", "extension", "embedCard", "nestedExpand"])
58    ),
59    (
60      String::from("tableCell"),
61      AdfPermittedChildren::any(&["codeBlock", "blockCard", "paragraph", "bulletList", "mediaSingle", "orderedList", "heading", "panel", "blockquote", "rule", "mediaGroup", "decisionList", "taskList", "extension", "embedCard", "nestedExpand", "hardBreak"])
62    ),
63    (
64      String::from("doc"),
65      AdfPermittedChildren::any(&["blockCard", "blockquote", "bodiedExtension", "bulletList", "codeBlock", "decisionList", "embedCard", "expand", "extension", "heading", "layoutSection", "mediaGroup", "mediaSingle", "orderedList", "panel", "paragraph", "rule", "table", "taskList"])
66    )
67  ]);
68
69  #[derive(Debug, Clone)]
70  /**
71   * NODE_MAP: The legal mappings from HTML element types to ADF types that we permit.
72   */
73  pub static ref NODE_MAP: HashMap<&'static str, AdfContentType> = HashMap::from([
74    (
75      "p",
76      AdfContentType::from_name("paragraph")
77    ),
78    (
79      "blockquote",
80      AdfContentType::from_name("blockquote")
81    ),
82    (
83      "span",
84      AdfContentType::from_name("text")
85    ),
86    (
87      "text",
88      AdfContentType::from_name("text")
89    ),
90    (
91      "ul",
92      AdfContentType::from_name("bulletList")
93    ),
94    (
95      "ol",
96      AdfContentType::from_name("orderedList")
97    ),
98    (
99      "li",
100      AdfContentType::from_name("listItem")
101    ),
102    (
103      "hr",
104      AdfContentType::from_name("rule")
105    ),
106    (
107      "br",
108      AdfContentType::from_name("hardBreak")
109    ),
110    (
111      "html",
112      AdfContentType::from_name("doc")
113    ),
114    (
115      "body",
116      AdfContentType::from_name("doc")
117    ),
118    (
119      "table",
120      AdfContentType::from_name("table")
121    ),
122    (
123      "tr",
124      AdfContentType::from_name("tableRow")
125    ),
126    (
127      "th",
128      AdfContentType::from_name("tableHeader")
129    ),
130    (
131      "td",
132      AdfContentType::from_name("tableCell")
133    ),
134    (
135      "iframe",
136      AdfContentType::from_name_and_attributes("paragraph", |node|{
137        match node.value().attr("src"){
138          Some(attribute) => vec![("src".to_string(), Value::String(attribute.to_string()))],
139          None => vec!()
140        }
141      }
142      )
143    ),
144    (
145      "b",
146      AdfContentType::from_name_and_marks("text", &[
147        AdfMark{
148          typename: "strong".to_string(),
149          attributes: AdfMarkAttributes::List(vec!())
150        }
151      ])
152    ),
153    (
154      "strong",
155      AdfContentType::from_name_and_marks("text", &[
156        AdfMark{
157          typename: "strong".to_string(),
158          attributes: AdfMarkAttributes::List(vec!())
159        }
160      ])
161    ),
162    (
163      "i",
164      AdfContentType::from_name_and_marks("text", &[
165        AdfMark{
166          typename: "em".to_string(),
167          attributes: AdfMarkAttributes::List(vec!())
168        }
169      ])
170    ),
171    (
172      "em",
173      AdfContentType::from_name_and_marks("text", &[
174        AdfMark{
175          typename: "em".to_string(),
176          attributes: AdfMarkAttributes::List(vec!())
177        }
178      ])
179    ),
180    (
181      "u",
182      AdfContentType::from_name_and_marks("text", &[
183        AdfMark{
184          typename: "underline".to_string(),
185          attributes: AdfMarkAttributes::List(vec!())
186        }
187      ])
188    ),
189    (
190      "code",
191      AdfContentType::from_name_and_marks("text", &[
192        AdfMark{
193          typename: "code".to_string(),
194          attributes: AdfMarkAttributes::List(vec!())
195        }
196      ])
197    ),
198    (
199      "a",
200      AdfContentType::from_name_and_marks("text", &[
201        AdfMark{
202          typename: "link".to_string(),
203          attributes: AdfMarkAttributes::Generator(|element| -> Vec<(String, String)>{
204            match element.value().attr("href"){
205              Some(attribute) => vec![
206                ("href".to_string(), attribute.to_string())
207              ],
208              None => vec!()
209            }
210          })
211        }
212      ])
213    ),
214    (
215      "sub",
216      AdfContentType::from_name_and_marks("text", &[
217        AdfMark{
218          typename: "subsup".to_string(),
219          attributes: AdfMarkAttributes::List(vec![("type".to_string(), "sub".to_string())])
220        }
221      ])
222    ),
223    (
224      "sup",
225      AdfContentType::from_name_and_marks("text", &[
226        AdfMark{
227          typename: "subsup".to_string(),
228          attributes: AdfMarkAttributes::List(vec![("type".to_string(), "sup".to_string())])
229        }
230      ])
231    ),
232    (
233      "h1",
234      AdfContentType::from_name_and_attributes("heading", |_|
235        {
236          vec!(
237            ("level".to_string(), Value::Number(serde_json::Number::from(1))),
238          )
239        }
240      )
241    ),
242    (
243      "h2",
244      AdfContentType::from_name_and_attributes("heading", |_|
245        {
246          vec!(
247            ("level".to_string(), Value::Number(serde_json::Number::from(2))),
248          )
249        }
250      )
251    ),
252    (
253      "h3",
254      AdfContentType::from_name_and_attributes("heading", |_|
255        {
256          vec!(
257            ("level".to_string(), Value::Number(serde_json::Number::from(3))),
258          )
259        }
260      )
261    ),
262    (
263      "h4",
264      AdfContentType::from_name_and_attributes("heading", |_|
265        {
266          vec!(
267            ("level".to_string(), Value::Number(serde_json::Number::from(4))),
268          )
269        }
270      )
271    ),
272    (
273      "h5",
274      AdfContentType::from_name_and_attributes("heading", |_|
275        {
276          vec!(
277            ("level".to_string(), Value::Number(serde_json::Number::from(5))),
278          )
279        }
280      )
281    ),
282    (
283      "h6",
284      AdfContentType::from_name_and_attributes("heading", |_|
285        {
286          vec!(
287            ("level".to_string(), Value::Number(serde_json::Number::from(6))),
288          )
289        }
290      )
291    ),
292    (
293      "img",
294      AdfContentType::from_name_and_attributes("mediaSingle", |node|
295        {
296          match node.value().attr("src"){
297            Some(attribute) => vec!(
298              ("url".to_string(), Value::String(attribute.to_string())),
299              ("type".to_string(), Value::String("external".to_string()))
300            ),
301            None => vec!()
302          }
303
304        }
305      )
306    ),
307]);
308}