maruku 0.4.1 → 0.4.2
Sign up to get free protection for your applications and to get access to all the features.
- data/bin/maruku +41 -25
- data/docs/char.html +1924 -0
- data/docs/entity_test.html +2 -2
- data/docs/exd.html +92 -0
- data/docs/index.html +77 -23
- data/docs/markdown_syntax.html +6 -6
- data/docs/maruku.html +75 -21
- data/docs/maruku.md +60 -26
- data/docs/proposal.html +105 -123
- data/docs/proposal.md +121 -109
- data/lib/maruku/attributes.rb +33 -1
- data/lib/maruku/defaults.rb +8 -0
- data/lib/maruku/input/charsource.rb +8 -2
- data/lib/maruku/input/parse_block.rb +44 -18
- data/lib/maruku/input/parse_doc.rb +28 -26
- data/lib/maruku/input/parse_span_better.rb +57 -41
- data/lib/maruku/input/type_detection.rb +3 -2
- data/lib/maruku/output/to_html.rb +6 -6
- data/lib/maruku/output/to_latex.rb +21 -5
- data/lib/maruku/structures.rb +0 -4
- data/lib/maruku/tests/new_parser.rb +6 -1
- data/lib/maruku/version.rb +1 -1
- data/tests/unittest/attributes/att2.md +36 -0
- data/tests/unittest/attributes/att3.md +55 -0
- data/tests/unittest/attributes/attributes.md +23 -18
- data/tests/unittest/attributes/circular.md +9 -9
- data/tests/unittest/email.md +2 -2
- data/tests/unittest/links.md +2 -2
- data/tests/unittest/misc_sw.md +1 -1
- data/tests/unittest/syntax_hl.md +3 -5
- data/tests/unittest/xml_instruction.md +1 -2
- metadata +6 -2
data/docs/proposal.md
CHANGED
@@ -10,13 +10,51 @@ This document describes a syntax for attaching meta-data to
|
|
10
10
|
block-level elements (headers, paragraphs, code blocks,…),
|
11
11
|
and to span-level elements (links, images,…).
|
12
12
|
|
13
|
-
|
14
|
-
|
13
|
+
***Note: this is an evolving proposal***
|
14
|
+
|
15
|
+
Last updated **January 10th, 2007**:
|
16
|
+
|
17
|
+
* Changed the syntax for compatibility with a future extension mechanism.
|
18
|
+
|
19
|
+
The first character in the curly braces must be a colon, optionally
|
20
|
+
followed by a space:
|
21
|
+
|
22
|
+
{: ref .class #id}
|
23
|
+
|
24
|
+
The old syntax was `{ref .class #id}`.
|
25
|
+
|
26
|
+
For ALDs, the new syntax is:
|
27
|
+
|
28
|
+
{:ref_id: key=val .class #id }
|
29
|
+
|
30
|
+
instead of:
|
31
|
+
|
32
|
+
{ref_id}: key=val .class #id
|
33
|
+
|
34
|
+
Converters that don't use this syntax may just ignore everything
|
35
|
+
which is in curly braces and starts with ":".
|
36
|
+
|
37
|
+
* IAL can be put both *before* and *after* the element.
|
38
|
+
There is no ambiguity as a blank line is needed between elements:
|
39
|
+
|
40
|
+
Paragraph 1
|
41
|
+
|
42
|
+
{:par2}
|
43
|
+
Paragraph 2
|
44
|
+
|
45
|
+
is equivalent to:
|
46
|
+
|
47
|
+
Paragraph 1
|
48
|
+
|
49
|
+
Paragraph 2
|
50
|
+
{:par2}
|
51
|
+
|
52
|
+
* Simplified rules for escaping.
|
15
53
|
|
16
54
|
*Table of contents:*
|
17
55
|
|
18
56
|
> * Table of contents
|
19
|
-
> {toc}
|
57
|
+
> {:toc}
|
20
58
|
|
21
59
|
Overview
|
22
60
|
--------
|
@@ -25,31 +63,31 @@ This proposal describes two additions to the Markdown syntax:
|
|
25
63
|
|
26
64
|
1. inline attribute lists (IAL)
|
27
65
|
|
28
|
-
## Header ## {key=val .class #id ref_id}
|
66
|
+
## Header ## {: key=val .class #id ref_id}
|
29
67
|
|
30
68
|
2. attribute lists definitions (ALD)
|
31
69
|
|
32
|
-
{ref_id
|
70
|
+
{:ref_id: key=val .class #id}
|
33
71
|
|
34
72
|
Every span-level or block-level element can be followed by an IAL:
|
35
73
|
|
36
|
-
### Header ### {#header1 class=c1}
|
74
|
+
### Header ### {: #header1 class=c1}
|
37
75
|
|
38
|
-
Paragraph *with emphasis*{class=c1}
|
76
|
+
Paragraph *with emphasis*{: class=c1}
|
39
77
|
second line of paragraph
|
40
|
-
{class=c1}
|
78
|
+
{: class=c1}
|
41
79
|
|
42
80
|
In this example, the three IALs refer to the header, the emphasis span, and the entire paragraph, respectively.
|
43
81
|
|
44
82
|
IALs can reference ALDs. The result of the following example is the same as the previous one:
|
45
83
|
|
46
|
-
### Header ### {#header1 c1}
|
84
|
+
### Header ### {: #header1 c1}
|
47
85
|
|
48
|
-
Paragraph *with emphasis*{c1}
|
86
|
+
Paragraph *with emphasis*{:c1}
|
49
87
|
second line of paragraph
|
50
|
-
{c1}
|
88
|
+
{:c1}
|
51
89
|
|
52
|
-
{c1
|
90
|
+
{:c1: class=c1}
|
53
91
|
|
54
92
|
Attribute lists
|
55
93
|
---------------
|
@@ -57,7 +95,7 @@ Attribute lists
|
|
57
95
|
This is an example attribute list, which shows
|
58
96
|
everything you can put inside:
|
59
97
|
|
60
|
-
key1=val key2="long val" #myid .class1 .class2 ref1 ref2
|
98
|
+
{: key1=val key2="long val" #myid .class1 .class2 ref1 ref2}
|
61
99
|
|
62
100
|
More in particular, an attribute list is a whitespace-separated list
|
63
101
|
of elements of 4 different kinds:
|
@@ -76,16 +114,16 @@ For ID and classes there are special shortcuts:
|
|
76
114
|
|
77
115
|
So these are equivalent:
|
78
116
|
|
79
|
-
{.class1 .class2}
|
80
|
-
{class="class1 class2"}
|
117
|
+
{: .class1 .class2}
|
118
|
+
{: class="class1 class2"}
|
81
119
|
|
82
120
|
|
83
121
|
The following attribute lists are equivalent:
|
84
122
|
|
85
|
-
{#myid .class1 .class2}
|
86
|
-
{id=myid class=class1 .class2}
|
87
|
-
{id=myid class="class1 class2"}
|
88
|
-
{id=myid class="will be overridden" class=class1 .class2}
|
123
|
+
{: #myid .class1 .class2}
|
124
|
+
{: id=myid class=class1 .class2}
|
125
|
+
{: id=myid class="class1 class2"}
|
126
|
+
{: id=myid class="will be overridden" class=class1 .class2}
|
89
127
|
|
90
128
|
Where to put inline attribute lists
|
91
129
|
----------------------------------
|
@@ -97,49 +135,49 @@ For paragraphs and other block-level elements, IAL go
|
|
97
135
|
|
98
136
|
This is a paragraph.
|
99
137
|
Line 2 of the paragraph.
|
100
|
-
{#myid .myclass}
|
138
|
+
{: #myid .myclass}
|
101
139
|
|
102
140
|
A quote with a citation url:
|
103
141
|
> Who said that?
|
104
|
-
{cite=google.com}
|
142
|
+
{: cite=google.com}
|
105
143
|
|
106
|
-
Note: empty lines between the block and the IAL are not
|
144
|
+
Note: empty lines between the block and the IAL are not tolerated.
|
107
145
|
So this is not legal:
|
108
146
|
|
109
147
|
This is a paragraph.
|
110
148
|
Line 2 of the paragraph.
|
111
149
|
|
112
|
-
{#myid .myclass}
|
150
|
+
{: #myid .myclass}
|
113
151
|
|
114
152
|
Attribute lists may be indented up to 3 spaces:
|
115
153
|
|
116
154
|
Paragraph1
|
117
|
-
{ok}
|
155
|
+
{:ok}
|
118
156
|
|
119
157
|
Paragraph2
|
120
|
-
{ok}
|
158
|
+
{:ok}
|
121
159
|
|
122
160
|
Paragraph2
|
123
|
-
{ok}
|
124
|
-
{code_show_spaces}
|
161
|
+
{:ok}
|
162
|
+
{:code_show_spaces}
|
125
163
|
|
126
164
|
### For headers ###
|
127
165
|
|
128
166
|
For headers, you can put attribute lists on the same line:
|
129
167
|
|
130
|
-
### Header ### {#myid}
|
168
|
+
### Header ### {: #myid}
|
131
169
|
|
132
|
-
Header {#myid .myclass}
|
170
|
+
Header {: #myid .myclass}
|
133
171
|
------
|
134
172
|
|
135
173
|
or, as like other block-level elements, on the line below:
|
136
174
|
|
137
175
|
### Header ###
|
138
|
-
{#myid}
|
176
|
+
{: #myid}
|
139
177
|
|
140
178
|
Header
|
141
179
|
------
|
142
|
-
{#myid .myclass}
|
180
|
+
{: #myid .myclass}
|
143
181
|
|
144
182
|
### For span-level elements ###
|
145
183
|
|
@@ -148,15 +186,15 @@ flow.
|
|
148
186
|
|
149
187
|
For example, in this:
|
150
188
|
|
151
|
-
This is a *chunky paragraph*{#id1}
|
152
|
-
{#id2}
|
189
|
+
This is a *chunky paragraph*{: #id1}
|
190
|
+
{: #id2}
|
153
191
|
|
154
192
|
the ID of the `em` element is set to `id1`
|
155
193
|
and the ID of the paragraph is set to `id2`.
|
156
194
|
|
157
195
|
This works also for links, like this:
|
158
196
|
|
159
|
-
This is [a link][ref]{
|
197
|
+
This is [a link][ref]{:#myid rel=abc rev=abc}
|
160
198
|
|
161
199
|
For images, this:
|
162
200
|
|
@@ -164,7 +202,7 @@ For images, this:
|
|
164
202
|
|
165
203
|
is equivalent to:
|
166
204
|
|
167
|
-
This is ![Alt text](url){title="fresh carrots"}
|
205
|
+
This is ![Alt text](url){:title="fresh carrots"}
|
168
206
|
|
169
207
|
Using attributes lists definition {#using_tags}
|
170
208
|
---------------------------------
|
@@ -178,120 +216,94 @@ In an attribute list, you can have:
|
|
178
216
|
Everything else is interpreted as a reference to
|
179
217
|
an ALD.
|
180
218
|
|
181
|
-
# Header # {ref}
|
219
|
+
# Header # {:ref}
|
182
220
|
|
183
221
|
Blah blah blah.
|
184
222
|
|
185
|
-
{ref
|
223
|
+
{:ref: #myhead .myclass lang=fr}
|
186
224
|
|
187
225
|
Of course, more than one IAL can reference the same ALD:
|
188
226
|
|
189
|
-
# Header 1 # {1}
|
227
|
+
# Header 1 # {:1}
|
190
228
|
...
|
191
|
-
# Header 2 # {1}
|
229
|
+
# Header 2 # {:1}
|
192
230
|
|
193
|
-
{1
|
231
|
+
{:1: .myclass lang=fr}
|
194
232
|
|
195
233
|
|
196
|
-
The rules {
|
234
|
+
The rules {:#grammar}
|
197
235
|
---------
|
198
236
|
|
199
237
|
### The issue of escaping ###
|
200
238
|
|
201
|
-
1.
|
239
|
+
1. No escaping in code spans/blocks.
|
240
|
+
|
241
|
+
2. Everywhere else, **all** PUNCTUATION characters **can** be escaped,
|
242
|
+
and **must** be escaped when they could trigger links, tables, etc.
|
243
|
+
|
244
|
+
A punctuation character is anything not a letter, a number, or whitespace
|
245
|
+
(`[^a-zA-Z0-9\s\n]`).
|
202
246
|
|
203
|
-
|
247
|
+
3. As a rule, quotes **must** be escaped inside quoted values:
|
204
248
|
|
205
|
-
|
249
|
+
* Inside `"quoted values"`, you **must** escape `"`.
|
250
|
+
* Inside `'quoted values'`, you **must** escape `'`.
|
206
251
|
|
207
|
-
|
208
|
-
* `\ ` represents a non-breaking space.
|
209
|
-
* `\` followed by a newline represents a linebreak.
|
252
|
+
* Other examples:
|
210
253
|
|
211
|
-
|
212
|
-
|
213
|
-
* Inside `"quoted values"`, you **must** escape `"`.
|
214
|
-
* Inside `'quoted values'`, you **must** escape `'`.
|
254
|
+
`"bah 'bah' bah"` = `"bah \'bah\' bah"` = `'bah \'bah\' bah'`
|
215
255
|
|
216
|
-
|
256
|
+
`'bah "bah" bah'` = `'bah \"bah\" bah'` = `"bah \"bah\" bah"`
|
217
257
|
|
218
|
-
`"bah 'bah' bah"` = `"bah \'bah\' bah"` = `'bah \'bah\' bah'`
|
219
|
-
|
220
|
-
`'bah "bah" bah'` = `'bah \"bah\" bah'` = `"bah \"bah\" bah"`
|
221
258
|
|
259
|
+
4. There is an exception for backward compatibility, in links/images titles:
|
222
260
|
|
223
|
-
|
261
|
+
[text](url "title"with"quotes")
|
224
262
|
|
225
|
-
|
263
|
+
The exception is not valid for attribute lists and in other
|
264
|
+
contexts, where you have to use the canonical syntax.
|
226
265
|
|
227
266
|
|
228
267
|
### Syntax for attribute lists ####
|
229
268
|
|
230
269
|
Consider the following attribute list:
|
231
270
|
|
232
|
-
{key=value ref key2="quoted value" }
|
271
|
+
{: key=value ref key2="quoted value" }
|
233
272
|
|
234
273
|
In this string, `key`, `value`, and `ref` can be substituted by any
|
235
274
|
string that does not contain whitespace, or the unescaped characters `}`,`=`,`'`,`"`.
|
236
275
|
|
237
|
-
Inside a quoted value
|
238
|
-
escape the other kind of quote.
|
239
|
-
|
240
|
-
|
241
|
-
Things to discuss
|
242
|
-
-----------------
|
243
|
-
|
244
|
-
* A syntax for creating `SPAN` elements in the paragraphs and setting their attributes.
|
245
|
-
|
246
|
-
This is my proposal:
|
247
|
-
|
248
|
-
a long paragraph with [special words]{#myspan} that I want to
|
249
|
-
highlight
|
250
|
-
|
251
|
-
should originate the following HTML:
|
252
|
-
|
253
|
-
<p>a long paragraph with <span id="myspan">special words</span>
|
254
|
-
that I want to highlight</p>
|
255
|
-
|
256
|
-
***Note: I changed the old `{special words}{#myspan}` with `[special words]{#myspan}` which is less ambiguous.***
|
276
|
+
Inside a quoted value you **must** escape the other kind of quote.
|
257
277
|
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
> where should it be? Another good question for the list.
|
278
|
+
Also, you **must** escape a closing curly brace `}` inside quoted values.
|
279
|
+
This rule is for making life easier for interpreter that just want to skip
|
280
|
+
the meta-data.
|
262
281
|
|
263
|
-
|
264
|
-
|
265
|
-
* **Default ALD for classes of elements.** For example, an header of level 2 inherits automatically the attributes of `{header2}`, if it is defined.
|
266
|
-
|
267
|
-
## Header ##
|
268
|
-
|
269
|
-
Paragraph..
|
270
|
-
|
271
|
-
## Second Header ## {.mah}
|
272
|
-
|
273
|
-
Paragraph..
|
274
|
-
|
275
|
-
{header2}: .myclass
|
276
|
-
{paragraph}: .withmargins
|
277
|
-
|
278
|
-
In this example:
|
279
|
-
|
280
|
-
* the first header has attributes `class=myclass`
|
281
|
-
* the second header has attributes `class="myclass mah"`
|
282
|
-
* the two paragraphs have attributes `class=withmargins`
|
282
|
+
If you don't implement this syntax, you can get rid of the IAL by using this
|
283
|
+
regular expression (this is written in Ruby):
|
283
284
|
|
285
|
+
r = /\{:(\\\}|[^\}])*\}/
|
286
|
+
|
287
|
+
s.gsub(r, '') # ignore metadata
|
288
|
+
{:ruby}
|
284
289
|
|
285
|
-
|
286
|
-
|
290
|
+
Basically: match everything contained in a couple of `{:` and `}`, taking care
|
291
|
+
of escaping of `}`. This `\\\}|[^\}]` means: eat either any character which
|
292
|
+
is not a `}` or an escape sequence `\}`.
|
287
293
|
|
288
|
-
|
294
|
+
For this example,
|
289
295
|
|
290
|
-
|
296
|
+
this is
|
297
|
+
{: skipped="\}" val=\} bar}
|
298
|
+
|
299
|
+
for me
|
300
|
+
{: also this}
|
291
301
|
|
292
|
-
|
302
|
+
the result is:
|
293
303
|
|
294
|
-
|
304
|
+
this is
|
305
|
+
|
306
|
+
|
307
|
+
for me
|
295
308
|
|
296
309
|
|
297
|
-
|
data/lib/maruku/attributes.rb
CHANGED
@@ -30,6 +30,7 @@ class String
|
|
30
30
|
end
|
31
31
|
|
32
32
|
module MaRuKu;
|
33
|
+
MagicChar = ':'
|
33
34
|
|
34
35
|
class AttributeList < Array
|
35
36
|
|
@@ -80,6 +81,9 @@ module MaRuKu; module In; module Markdown; module SpanLevelParser
|
|
80
81
|
[ "a =b", :throw, "No whitespace before `=`." ],
|
81
82
|
[ "a= b", :throw, "No whitespace after `=`." ],
|
82
83
|
|
84
|
+
[ "a b c", [[:ref, 'a'],[:ref, 'b'],[:ref, 'c']], "More than one ref" ],
|
85
|
+
[ "hello notfound", [[:ref, 'hello'],[:ref, 'notfound']]],
|
86
|
+
|
83
87
|
[ "'a'", [[:ref, 'a']], "Quoted value." ],
|
84
88
|
[ '"a"' ],
|
85
89
|
|
@@ -117,7 +121,7 @@ module MaRuKu; module In; module Markdown; module SpanLevelParser
|
|
117
121
|
@comment = (comment ||= (last=@comment) )
|
118
122
|
(comment == last && (comment += (@count+=1).to_s)) || @count = 1
|
119
123
|
expected = [md_ial(expected)] if expected.kind_of? Array
|
120
|
-
["{#{s}}", expected, "Attributes: #{comment}"]
|
124
|
+
["{#{MagicChar}#{s}}", expected, "Attributes: #{comment}"]
|
121
125
|
}
|
122
126
|
end
|
123
127
|
|
@@ -181,6 +185,34 @@ module MaRuKu; module In; module Markdown; module SpanLevelParser
|
|
181
185
|
end # while true
|
182
186
|
al
|
183
187
|
end
|
188
|
+
|
189
|
+
|
190
|
+
def merge_ial(elements, src, con)
|
191
|
+
# We need a helper
|
192
|
+
def is_ial(e); e.kind_of? MDElement and e.node_type == :ial end
|
193
|
+
|
194
|
+
# Apply each IAL to the element before
|
195
|
+
elements.each_with_index do |e, i|
|
196
|
+
if is_ial(e) && i>= 1 then
|
197
|
+
before = elements[i-1]
|
198
|
+
after = elements[i+1]
|
199
|
+
if before.kind_of? MDElement
|
200
|
+
before.al = e.ial
|
201
|
+
elsif after.kind_of? MDElement
|
202
|
+
after.al = e.ial
|
203
|
+
else
|
204
|
+
maruku_error "I don't know who you are referring to:"+
|
205
|
+
" {#{e.ial.to_md}}", src, con
|
206
|
+
# xxx dire se c'è empty vicino
|
207
|
+
maruku_recover "Ignoring IAL: {#{e.ial.to_md}}", src, con
|
208
|
+
end
|
209
|
+
end
|
210
|
+
end
|
211
|
+
|
212
|
+
if not Globals[:debug_keep_ials]
|
213
|
+
elements.delete_if {|x| is_ial(x)}
|
214
|
+
end
|
215
|
+
end
|
184
216
|
|
185
217
|
end end end end
|
186
218
|
#module MaRuKu; module In; module Markdown; module SpanLevelParser
|
data/lib/maruku/defaults.rb
CHANGED