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
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
|
extern crate micromark;
use micromark::{micromark, micromark_with_options, Options};
use pretty_assertions::assert_eq;
#[test]
fn tabs_flow() -> Result<(), String> {
let danger = &Options {
allow_dangerous_html: true,
..Options::default()
};
assert_eq!(
micromark(" x"),
"<pre><code>x\n</code></pre>",
"should support a 4*SP to start code"
);
assert_eq!(
micromark("\tx"),
"<pre><code>x\n</code></pre>",
"should support a HT to start code"
);
assert_eq!(
micromark(" \tx"),
"<pre><code>x\n</code></pre>",
"should support a SP + HT to start code"
);
assert_eq!(
micromark(" \tx"),
"<pre><code>x\n</code></pre>",
"should support a 2*SP + HT to start code"
);
assert_eq!(
micromark(" \tx"),
"<pre><code>x\n</code></pre>",
"should support a 3*SP + HT to start code"
);
assert_eq!(
micromark(" \tx"),
"<pre><code>\tx\n</code></pre>",
"should support a 4*SP to start code, and leave the next HT as code data"
);
assert_eq!(
micromark(" \t# x"),
"<pre><code># x\n</code></pre>",
"should not support a 3*SP + HT to start an ATX heading"
);
assert_eq!(
micromark(" \t> x"),
"<pre><code>> x\n</code></pre>",
"should not support a 3*SP + HT to start a block quote"
);
assert_eq!(
micromark(" \t- x"),
"<pre><code>- x\n</code></pre>",
"should not support a 3*SP + HT to start a list item"
);
assert_eq!(
micromark(" \t---"),
"<pre><code>---\n</code></pre>",
"should not support a 3*SP + HT to start a thematic break"
);
assert_eq!(
micromark(" \t```"),
"<pre><code>```\n</code></pre>",
"should not support a 3*SP + HT to start a fenced code"
);
assert_eq!(
micromark(" \t<div>"),
"<pre><code><div>\n</code></pre>",
"should not support a 3*SP + HT to start HTML"
);
assert_eq!(
micromark("#\tx\t#\t"),
"<h1>x</h1>",
"should support tabs around ATX heading sequences"
);
assert_eq!(
micromark("#\t\tx\t\t#\t\t"),
"<h1>x</h1>",
"should support arbitrary tabs around ATX heading sequences"
);
assert_eq!(
micromark("```\tx\ty\t\n```\t"),
"<pre><code class=\"language-x\"></code></pre>",
"should support tabs around fenced code fences, info, and meta"
);
assert_eq!(
micromark("```\t\tx\t\ty\t\t\n```\t\t"),
"<pre><code class=\"language-x\"></code></pre>",
"should support arbitrary tabs around fenced code fences, info, and meta"
);
assert_eq!(
micromark("```x\n\t```"),
"<pre><code class=\"language-x\">\t```\n</code></pre>\n",
"should not support tabs before fenced code closing fences"
);
assert_eq!(
micromark_with_options("<x\ty\tz\t=\t\"\tx\t\">", danger)?,
"<x\ty\tz\t=\t\"\tx\t\">",
"should support tabs in HTML (if whitespace is allowed)"
);
assert_eq!(
micromark("*\t*\t*\t"),
"<hr />",
"should support tabs in thematic breaks"
);
assert_eq!(
micromark("*\t\t*\t\t*\t\t"),
"<hr />",
"should support arbitrary tabs in thematic breaks"
);
Ok(())
}
#[test]
fn tabs_text() -> Result<(), String> {
assert_eq!(
micromark("<http:\t>"),
"<p><http:\t></p>",
"should not support a tab to start an autolink w/ protocol’s rest"
);
assert_eq!(
micromark("<http:x\t>"),
"<p><http:x\t></p>",
"should not support a tab in an autolink w/ protocol’s rest"
);
assert_eq!(
micromark("<example\t@x.com>"),
"<p><example\t@x.com></p>",
"should not support a tab in an email autolink’s local part"
);
assert_eq!(
micromark("<example@x\ty.com>"),
"<p><example@x\ty.com></p>",
"should not support a tab in an email autolink’s label"
);
assert_eq!(
micromark("\\\tx"),
"<p>\\\tx</p>",
"should not support character escaped tab"
);
assert_eq!(
micromark("	"),
"<p>\t</p>",
"should support character reference resolving to a tab"
);
assert_eq!(
micromark("`\tx`"),
"<p><code>\tx</code></p>",
"should support a tab starting code"
);
assert_eq!(
micromark("`x\t`"),
"<p><code>x\t</code></p>",
"should support a tab ending code"
);
assert_eq!(
micromark("`\tx\t`"),
"<p><code>\tx\t</code></p>",
"should support tabs around code"
);
assert_eq!(
micromark("`\tx `"),
"<p><code>\tx </code></p>",
"should support a tab starting, and a space ending, code"
);
assert_eq!(
micromark("` x\t`"),
"<p><code> x\t</code></p>",
"should support a space starting, and a tab ending, code"
);
// Note: CM does not strip it in this case.
// However, that should be a bug there: makes more sense to remove it like
// trailing spaces.
assert_eq!(
micromark("x\t\ny"),
"<p>x\ny</p>",
"should support a trailing tab at a line ending in a paragraph"
);
assert_eq!(
micromark("x\n\ty"),
"<p>x\ny</p>",
"should support an initial tab after a line ending in a paragraph"
);
assert_eq!(
micromark("x[\ty](z)"),
"<p>x<a href=\"z\">\ty</a></p>",
"should support an initial tab in a link label"
);
assert_eq!(
micromark("x[y\t](z)"),
"<p>x<a href=\"z\">y\t</a></p>",
"should support a final tab in a link label"
);
assert_eq!(
micromark("[x\ty](z)"),
"<p><a href=\"z\">x\ty</a></p>",
"should support a tab in a link label"
);
// Note: CM.js bug, see: <https://github.com/commonmark/commonmark.js/issues/191>
assert_eq!(
micromark("[x](\ty)"),
"<p><a href=\"y\">x</a></p>",
"should support a tab starting a link resource"
);
assert_eq!(
micromark("[x](y\t)"),
"<p><a href=\"y\">x</a></p>",
"should support a tab ending a link resource"
);
assert_eq!(
micromark("[x](y\t\"z\")"),
"<p><a href=\"y\" title=\"z\">x</a></p>",
"should support a tab between a link destination and title"
);
Ok(())
}
#[test]
fn tabs_virtual_spaces() -> Result<(), String> {
assert_eq!(
micromark("```\n\tx"),
"<pre><code>\tx\n</code></pre>\n",
"should support a tab in fenced code"
);
assert_eq!(
micromark(" ```\n\tx"),
"<pre><code> x\n</code></pre>\n",
"should strip 1 space from an initial tab in fenced code if the opening fence is indented as such"
);
assert_eq!(
micromark(" ```\n\tx"),
"<pre><code> x\n</code></pre>\n",
"should strip 2 spaces from an initial tab in fenced code if the opening fence is indented as such"
);
assert_eq!(
micromark(" ```\n\tx"),
"<pre><code> x\n</code></pre>\n",
"should strip 3 spaces from an initial tab in fenced code if the opening fence is indented as such"
);
assert_eq!(
micromark("-\ta\n\n\tb"),
"<ul>\n<li>\n<p>a</p>\n<p>\tb</p>\n</li>\n</ul>",
// To do: CM.js does not output the tab before `b`. See if that makes sense?
// "<ul>\n<li>\n<p>a</p>\n<p>b</p>\n</li>\n</ul>",
"should support a part of a tab as a container, and the rest of a tab as flow"
);
Ok(())
}
|