maruku 0.4.1 → 0.4.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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 {title="fresh carrots"}
|
205
|
+
This is {: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