patcito-maruku 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (162) hide show
  1. data/AUTHORS +23 -0
  2. data/LICENSE +340 -0
  3. data/README.md +73 -0
  4. data/bin/maruku +196 -0
  5. data/bin/marutex +4 -0
  6. data/data/entities.xml +261 -0
  7. data/docs/changelog.md +334 -0
  8. data/docs/div_syntax.md +36 -0
  9. data/docs/entity_test.md +23 -0
  10. data/docs/markdown_syntax.md +899 -0
  11. data/docs/maruku.md +346 -0
  12. data/docs/math.md +194 -0
  13. data/docs/other_stuff.md +51 -0
  14. data/docs/proposal.md +309 -0
  15. data/docs/website/src/bluecloth.md +25 -0
  16. data/docs/website/src/download.md +31 -0
  17. data/docs/website/src/maruku.md +261 -0
  18. data/docs/website/src/proposal.md +271 -0
  19. data/lib/maruku.rb +132 -0
  20. data/lib/maruku/attributes.rb +138 -0
  21. data/lib/maruku/defaults.rb +69 -0
  22. data/lib/maruku/errors.rb +89 -0
  23. data/lib/maruku/ext/div.rb +121 -0
  24. data/lib/maruku/ext/fenced_code.rb +78 -0
  25. data/lib/maruku/ext/math.rb +37 -0
  26. data/lib/maruku/ext/math/elements.rb +21 -0
  27. data/lib/maruku/ext/math/latex_fix.rb +12 -0
  28. data/lib/maruku/ext/math/mathml_engines/blahtex.rb +93 -0
  29. data/lib/maruku/ext/math/mathml_engines/itex2mml.rb +39 -0
  30. data/lib/maruku/ext/math/mathml_engines/none.rb +21 -0
  31. data/lib/maruku/ext/math/mathml_engines/ritex.rb +24 -0
  32. data/lib/maruku/ext/math/parsing.rb +125 -0
  33. data/lib/maruku/ext/math/to_html.rb +237 -0
  34. data/lib/maruku/ext/math/to_latex.rb +36 -0
  35. data/lib/maruku/ext/yaml.rb +43 -0
  36. data/lib/maruku/helpers.rb +214 -0
  37. data/lib/maruku/input/charsource.rb +326 -0
  38. data/lib/maruku/input/extensions.rb +69 -0
  39. data/lib/maruku/input/html_helper.rb +189 -0
  40. data/lib/maruku/input/linesource.rb +111 -0
  41. data/lib/maruku/input/parse_block.rb +608 -0
  42. data/lib/maruku/input/parse_doc.rb +240 -0
  43. data/lib/maruku/input/parse_span_better.rb +746 -0
  44. data/lib/maruku/input/rubypants.rb +225 -0
  45. data/lib/maruku/input/type_detection.rb +147 -0
  46. data/lib/maruku/input_textile2/t2_parser.rb +163 -0
  47. data/lib/maruku/maruku.rb +31 -0
  48. data/lib/maruku/output/s5/fancy.rb +756 -0
  49. data/lib/maruku/output/s5/to_s5.rb +138 -0
  50. data/lib/maruku/output/to_html.rb +994 -0
  51. data/lib/maruku/output/to_latex.rb +580 -0
  52. data/lib/maruku/output/to_latex_entities.rb +101 -0
  53. data/lib/maruku/output/to_latex_strings.rb +64 -0
  54. data/lib/maruku/output/to_markdown.rb +164 -0
  55. data/lib/maruku/output/to_s.rb +54 -0
  56. data/lib/maruku/string_utils.rb +185 -0
  57. data/lib/maruku/structures.rb +143 -0
  58. data/lib/maruku/structures_inspect.rb +51 -0
  59. data/lib/maruku/structures_iterators.rb +48 -0
  60. data/lib/maruku/textile2.rb +1 -0
  61. data/lib/maruku/toc.rb +214 -0
  62. data/lib/maruku/usage/example1.rb +33 -0
  63. data/lib/maruku/version +0 -0
  64. data/lib/maruku/version.rb +54 -0
  65. data/spec/block_docs/abbreviations.md +52 -0
  66. data/spec/block_docs/alt.md +17 -0
  67. data/spec/block_docs/attributes/att2.md +20 -0
  68. data/spec/block_docs/attributes/att3.md +28 -0
  69. data/spec/block_docs/attributes/attributes.md +57 -0
  70. data/spec/block_docs/attributes/circular.md +26 -0
  71. data/spec/block_docs/attributes/default.md +22 -0
  72. data/spec/block_docs/blank.md +24 -0
  73. data/spec/block_docs/blanks_in_code.md +75 -0
  74. data/spec/block_docs/bug_def.md +16 -0
  75. data/spec/block_docs/bug_table.md +46 -0
  76. data/spec/block_docs/code.md +34 -0
  77. data/spec/block_docs/code2.md +28 -0
  78. data/spec/block_docs/code3.md +71 -0
  79. data/spec/block_docs/data_loss.md +25 -0
  80. data/spec/block_docs/divs/div1.md +167 -0
  81. data/spec/block_docs/divs/div2.md +21 -0
  82. data/spec/block_docs/divs/div3_nest.md +45 -0
  83. data/spec/block_docs/easy.md +15 -0
  84. data/spec/block_docs/email.md +20 -0
  85. data/spec/block_docs/encoding/iso-8859-1.md +23 -0
  86. data/spec/block_docs/encoding/utf-8.md +18 -0
  87. data/spec/block_docs/entities.md +94 -0
  88. data/spec/block_docs/escaping.md +67 -0
  89. data/spec/block_docs/extra_dl.md +52 -0
  90. data/spec/block_docs/extra_header_id.md +63 -0
  91. data/spec/block_docs/extra_table1.md +37 -0
  92. data/spec/block_docs/footnotes.md +97 -0
  93. data/spec/block_docs/headers.md +37 -0
  94. data/spec/block_docs/hex_entities.md +37 -0
  95. data/spec/block_docs/hrule.md +39 -0
  96. data/spec/block_docs/html2.md +22 -0
  97. data/spec/block_docs/html3.md +31 -0
  98. data/spec/block_docs/html4.md +25 -0
  99. data/spec/block_docs/html5.md +23 -0
  100. data/spec/block_docs/ie.md +49 -0
  101. data/spec/block_docs/images.md +90 -0
  102. data/spec/block_docs/images2.md +31 -0
  103. data/spec/block_docs/inline_html.md +152 -0
  104. data/spec/block_docs/inline_html2.md +21 -0
  105. data/spec/block_docs/links.md +152 -0
  106. data/spec/block_docs/links2.md +22 -0
  107. data/spec/block_docs/list1.md +46 -0
  108. data/spec/block_docs/list12.md +28 -0
  109. data/spec/block_docs/list2.md +56 -0
  110. data/spec/block_docs/list3.md +64 -0
  111. data/spec/block_docs/list4.md +89 -0
  112. data/spec/block_docs/lists.md +192 -0
  113. data/spec/block_docs/lists10.md +34 -0
  114. data/spec/block_docs/lists11.md +23 -0
  115. data/spec/block_docs/lists6.md +41 -0
  116. data/spec/block_docs/lists9.md +64 -0
  117. data/spec/block_docs/lists_after_paragraph.md +208 -0
  118. data/spec/block_docs/lists_ol.md +262 -0
  119. data/spec/block_docs/loss.md +16 -0
  120. data/spec/block_docs/math/equations.md +45 -0
  121. data/spec/block_docs/math/inline.md +46 -0
  122. data/spec/block_docs/math/math2.md +45 -0
  123. data/spec/block_docs/math/notmath.md +25 -0
  124. data/spec/block_docs/math/table.md +25 -0
  125. data/spec/block_docs/math/table2.md +42 -0
  126. data/spec/block_docs/misc_sw.md +525 -0
  127. data/spec/block_docs/notyet/escape.md +21 -0
  128. data/spec/block_docs/notyet/header_after_par.md +58 -0
  129. data/spec/block_docs/notyet/ticks.md +18 -0
  130. data/spec/block_docs/notyet/triggering.md +157 -0
  131. data/spec/block_docs/olist.md +45 -0
  132. data/spec/block_docs/one.md +15 -0
  133. data/spec/block_docs/paragraph.md +16 -0
  134. data/spec/block_docs/paragraph_rules/dont_merge_ref.md +42 -0
  135. data/spec/block_docs/paragraph_rules/tab_is_blank.md +24 -0
  136. data/spec/block_docs/paragraphs.md +46 -0
  137. data/spec/block_docs/pending/amps.md +15 -0
  138. data/spec/block_docs/pending/empty_cells.md +37 -0
  139. data/spec/block_docs/pending/link.md +72 -0
  140. data/spec/block_docs/pending/ref.md +21 -0
  141. data/spec/block_docs/recover/recover_links.md +15 -0
  142. data/spec/block_docs/red_tests/abbrev.md +679 -0
  143. data/spec/block_docs/red_tests/lists7.md +32 -0
  144. data/spec/block_docs/red_tests/lists7b.md +65 -0
  145. data/spec/block_docs/red_tests/lists8.md +42 -0
  146. data/spec/block_docs/red_tests/ref.md +23 -0
  147. data/spec/block_docs/red_tests/xml.md +35 -0
  148. data/spec/block_docs/references/long_example.md +71 -0
  149. data/spec/block_docs/references/spaces_and_numbers.md +15 -0
  150. data/spec/block_docs/smartypants.md +114 -0
  151. data/spec/block_docs/syntax_hl.md +52 -0
  152. data/spec/block_docs/table_attributes.md +34 -0
  153. data/spec/block_docs/test.md +19 -0
  154. data/spec/block_docs/underscore_in_words.md +15 -0
  155. data/spec/block_docs/wrapping.md +67 -0
  156. data/spec/block_docs/xml2.md +19 -0
  157. data/spec/block_docs/xml3.md +26 -0
  158. data/spec/block_docs/xml_instruction.md +52 -0
  159. data/spec/block_spec.rb +49 -0
  160. data/spec/span_spec.rb +254 -0
  161. data/spec/spec_helper.rb +6 -0
  162. metadata +247 -0
@@ -0,0 +1,271 @@
1
+ CSS: style.css
2
+ LaTeX_use_listings: true
3
+ html_use_syntax: true
4
+ use_numbered_headers: true
5
+
6
+ Meta-data syntax implemented by Maruku
7
+ ======================================
8
+
9
+ This document describes a syntax for attaching meta-data to
10
+ block-level elements (headers, paragraphs, code blocks,…),
11
+ and to span-level elements (links, images,…).
12
+
13
+
14
+ *Table of contents:*
15
+
16
+ > * Table of contents
17
+ > {:toc}
18
+
19
+ Overview
20
+ --------
21
+
22
+ This proposal describes two additions to the Markdown syntax:
23
+
24
+ 1. inline attribute lists (IAL)
25
+
26
+ ## Header ## {: key=val .class #id ref_id}
27
+
28
+ 2. attribute lists definitions (ALD)
29
+
30
+ {:ref_id: key=val .class #id}
31
+
32
+ Every span-level or block-level element can be followed by an IAL:
33
+
34
+ ### Header ### {: #header1 class=c1}
35
+
36
+ Paragraph *with emphasis*{: class=c1}
37
+ second line of paragraph
38
+ {: class=c1}
39
+
40
+ In this example, the three IALs refer to the header, the emphasis span, and the entire paragraph, respectively.
41
+
42
+ IALs can reference ALDs. The result of the following example is the same as the previous one:
43
+
44
+ ### Header ### {: #header1 c1}
45
+
46
+ Paragraph *with emphasis*{:c1}
47
+ second line of paragraph
48
+ {:c1}
49
+
50
+ {:c1: class=c1}
51
+
52
+ Attribute lists
53
+ ---------------
54
+
55
+ This is an example attribute list, which shows
56
+ everything you can put inside:
57
+
58
+ {: key1=val key2="long val" #myid .class1 .class2 ref1 ref2}
59
+
60
+ More in particular, an attribute list is a whitespace-separated list
61
+ of elements of 4 different kinds:
62
+
63
+ 1. key/value pairs (quoted if necessary)
64
+ 2. [references to ALD](#using_tags) (`ref1`,`ref2`)
65
+ 3. [id specifiers](#class_id) (`#myid`)
66
+ 4. [class specifiers](#class_id) (`.myclass`)
67
+
68
+ ### `id` and `class` are special ### {#class_id}
69
+
70
+ For ID and classes there are special shortcuts:
71
+
72
+ * `#myid` is a shortcut for `id=myid`
73
+ * `.myclass` means "add `myclass` to the current `class` attribute".
74
+
75
+ So these are equivalent:
76
+
77
+ {: .class1 .class2}
78
+ {: class="class1 class2"}
79
+
80
+
81
+ The following attribute lists are equivalent:
82
+
83
+ {: #myid .class1 .class2}
84
+ {: id=myid class=class1 .class2}
85
+ {: id=myid class="class1 class2"}
86
+ {: id=myid class="will be overridden" class=class1 .class2}
87
+
88
+ Where to put inline attribute lists
89
+ ----------------------------------
90
+
91
+ ### For block-level elements ###
92
+
93
+ For paragraphs and other block-level elements, IAL go
94
+ **after** the element:
95
+
96
+ This is a paragraph.
97
+ Line 2 of the paragraph.
98
+ {: #myid .myclass}
99
+
100
+ A quote with a citation url:
101
+ > Who said that?
102
+ {: cite=google.com}
103
+
104
+ Note: empty lines between the block and the IAL are not tolerated.
105
+ So this is not legal:
106
+
107
+ This is a paragraph.
108
+ Line 2 of the paragraph.
109
+
110
+ {: #myid .myclass}
111
+
112
+ Attribute lists may be indented up to 3 spaces:
113
+
114
+ Paragraph1
115
+ {:ok}
116
+
117
+ Paragraph2
118
+ {:ok}
119
+
120
+ Paragraph2
121
+ {:ok}
122
+ {:code_show_spaces}
123
+
124
+ ### For headers ###
125
+
126
+ For headers, you can put attribute lists on the same line:
127
+
128
+ ### Header ### {: #myid}
129
+
130
+ Header {: #myid .myclass}
131
+ ------
132
+
133
+ or, as like other block-level elements, on the line below:
134
+
135
+ ### Header ###
136
+ {: #myid}
137
+
138
+ Header
139
+ ------
140
+ {: #myid .myclass}
141
+
142
+ ### For span-level elements ###
143
+
144
+ For span-level elements, meta-data goes immediately **after** in the
145
+ flow.
146
+
147
+ For example, in this:
148
+
149
+ This is a *chunky paragraph*{: #id1}
150
+ {: #id2}
151
+
152
+ the ID of the `em` element is set to `id1`
153
+ and the ID of the paragraph is set to `id2`.
154
+
155
+ This works also for links, like this:
156
+
157
+ This is [a link][ref]{:#myid rel=abc rev=abc}
158
+
159
+ For images, this:
160
+
161
+ This is ![Alt text](url "fresh carrots")
162
+
163
+ is equivalent to:
164
+
165
+ This is ![Alt text](url){:title="fresh carrots"}
166
+
167
+ Using attributes lists definition {#using_tags}
168
+ ---------------------------------
169
+
170
+ In an attribute list, you can have:
171
+
172
+ 1. `key=value` pairs,
173
+ 2. id attributes (`#myid`)
174
+ 3. class attributes (`.myclass`)
175
+
176
+ Everything else is interpreted as a reference to
177
+ an ALD.
178
+
179
+ # Header # {:ref}
180
+
181
+ Blah blah blah.
182
+
183
+ {:ref: #myhead .myclass lang=fr}
184
+
185
+ Of course, more than one IAL can reference the same ALD:
186
+
187
+ # Header 1 # {:1}
188
+ ...
189
+ # Header 2 # {:1}
190
+
191
+ {:1: .myclass lang=fr}
192
+
193
+
194
+ The rules {:#grammar}
195
+ ---------
196
+
197
+ ### The issue of escaping ###
198
+
199
+ 1. No escaping in code spans/blocks.
200
+
201
+ 2. Everywhere else, **all** PUNCTUATION characters **can** be escaped,
202
+ and **must** be escaped when they could trigger links, tables, etc.
203
+
204
+ A punctuation character is anything not a letter, a number, or whitespace
205
+ (`[^a-zA-Z0-9\s\n]`).
206
+
207
+ 3. As a rule, quotes **must** be escaped inside quoted values:
208
+
209
+ * Inside `"quoted values"`, you **must** escape `"`.
210
+ * Inside `'quoted values'`, you **must** escape `'`.
211
+
212
+ * Other examples:
213
+
214
+ `"bah 'bah' bah"` = `"bah \'bah\' bah"` = `'bah \'bah\' bah'`
215
+
216
+ `'bah "bah" bah'` = `'bah \"bah\" bah'` = `"bah \"bah\" bah"`
217
+
218
+
219
+ 4. There is an exception for backward compatibility, in links/images titles:
220
+
221
+ [text](url "title"with"quotes")
222
+
223
+ The exception is not valid for attribute lists and in other
224
+ contexts, where you have to use the canonical syntax.
225
+
226
+
227
+ ### Syntax for attribute lists ####
228
+
229
+ Consider the following attribute list:
230
+
231
+ {: key=value ref key2="quoted value" }
232
+
233
+ In this string, `key`, `value`, and `ref` can be substituted by any
234
+ string that does not contain whitespace, or the unescaped characters `}`,`=`,`'`,`"`.
235
+
236
+ Inside a quoted value you **must** escape the other kind of quote.
237
+
238
+ Also, you **must** escape a closing curly brace `}` inside quoted values.
239
+ This rule is for making life easier for interpreter that just want to skip
240
+ the meta-data.
241
+
242
+ ### Just skip, if you want ####
243
+
244
+ If you don't implement this syntax, you can get rid of the IAL by using this
245
+ regular expression (this is written in Ruby):
246
+
247
+ r = /\{:(\\\}|[^\}])*\}/
248
+
249
+ s.gsub(r, '') # ignore metadata
250
+ {:ruby}
251
+
252
+ Basically: match everything contained in a couple of `{:` and `}`, taking care
253
+ of escaping of `}`. This `\\\}|[^\}]` means: eat either any character which
254
+ is not a `}` or an escape sequence `\}`.
255
+
256
+ For this example,
257
+
258
+ this is
259
+ {: skipped="\}" val=\} bar}
260
+
261
+ for me
262
+ {: also this}
263
+
264
+ the result is:
265
+
266
+ this is
267
+
268
+
269
+ for me
270
+
271
+
@@ -0,0 +1,132 @@
1
+ # Copyright (C) 2006 Andrea Censi <andrea (at) rubyforge.org>
2
+ #
3
+ # This file is part of Maruku.
4
+ #
5
+ # Maruku is free software; you can redistribute it and/or modify
6
+ # it under the terms of the GNU General Public License as published by
7
+ # the Free Software Foundation; either version 2 of the License, or
8
+ # (at your option) any later version.
9
+ #
10
+ # Maruku is distributed in the hope that it will be useful,
11
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ # GNU General Public License for more details.
14
+ #
15
+ # You should have received a copy of the GNU General Public License
16
+ # along with Maruku; if not, write to the Free Software
17
+ # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18
+
19
+ dir = File.dirname(__FILE__)
20
+ $LOAD_PATH.unshift dir unless $LOAD_PATH.include?(dir)
21
+
22
+ require 'rexml/document'
23
+
24
+ module MaRuKu
25
+ module In
26
+ module Markdown
27
+ module SpanLevelParser; end
28
+ module BlockLevelParser; end
29
+ end
30
+ end
31
+
32
+ module Out
33
+ module Markdown; end
34
+ module HTML; end
35
+ module Latex; end
36
+ end
37
+
38
+ module Strings; end
39
+
40
+ module Helpers; end
41
+
42
+ module Errors; end
43
+
44
+ class MDElement
45
+ include REXML
46
+ include MaRuKu
47
+ include Out::Markdown
48
+ include Out::HTML
49
+ include Out::Latex
50
+ include Strings
51
+ include Helpers
52
+ include Errors
53
+ end
54
+
55
+
56
+ class MDDocument < MDElement
57
+ include In::Markdown
58
+ include In::Markdown::SpanLevelParser
59
+ include In::Markdown::BlockLevelParser
60
+ end
61
+ end
62
+
63
+ class Maruku < MaRuKu::MDDocument; end
64
+
65
+
66
+ # Structures definition
67
+ require 'maruku/structures'
68
+ require 'maruku/structures_inspect'
69
+
70
+ require 'maruku/defaults'
71
+ # Less typing
72
+ require 'maruku/helpers'
73
+
74
+ # Code for parsing whole Markdown documents
75
+ require 'maruku/input/parse_doc'
76
+
77
+ # Ugly things kept in a closet
78
+ require 'maruku/string_utils'
79
+ require 'maruku/input/linesource'
80
+ require 'maruku/input/type_detection'
81
+
82
+ # A class for reading and sanitizing inline HTML
83
+ require 'maruku/input/html_helper'
84
+
85
+ # Code for parsing Markdown block-level elements
86
+ require 'maruku/input/parse_block'
87
+
88
+ # Code for parsing Markdown span-level elements
89
+ require 'maruku/input/charsource'
90
+ require 'maruku/input/parse_span_better'
91
+ require 'maruku/input/rubypants'
92
+
93
+ require 'maruku/input/extensions'
94
+
95
+ require 'maruku/attributes'
96
+
97
+ require 'maruku/structures_iterators'
98
+
99
+ require 'maruku/errors'
100
+
101
+ # Code for creating a table of contents
102
+ require 'maruku/toc'
103
+
104
+ # Support for div Markdown extension
105
+ require 'maruku/ext/div'
106
+ # Support for fenced codeblocks extension
107
+ require 'maruku/ext/fenced_code'
108
+
109
+ # Version and URL
110
+ require 'maruku/version'
111
+
112
+
113
+ # Exporting to html
114
+ require 'maruku/output/to_html'
115
+
116
+ # Exporting to latex
117
+ require 'maruku/output/to_latex'
118
+ require 'maruku/output/to_latex_strings'
119
+ require 'maruku/output/to_latex_entities'
120
+
121
+ # Pretty print
122
+ require 'maruku/output/to_markdown'
123
+
124
+ # S5 slides
125
+ require 'maruku/output/s5/to_s5'
126
+ require 'maruku/output/s5/fancy'
127
+
128
+ # Exporting to text: strips all formatting (not complete)
129
+ require 'maruku/output/to_s'
130
+
131
+ # class Maruku is the global interface
132
+ require 'maruku/maruku'
@@ -0,0 +1,138 @@
1
+ # Copyright (C) 2006 Andrea Censi <andrea (at) rubyforge.org>
2
+ #
3
+ # This file is part of Maruku.
4
+ #
5
+ # Maruku is free software; you can redistribute it and/or modify
6
+ # it under the terms of the GNU General Public License as published by
7
+ # the Free Software Foundation; either version 2 of the License, or
8
+ # (at your option) any later version.
9
+ #
10
+ # Maruku is distributed in the hope that it will be useful,
11
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ # GNU General Public License for more details.
14
+ #
15
+ # You should have received a copy of the GNU General Public License
16
+ # along with Maruku; if not, write to the Free Software
17
+ # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18
+
19
+
20
+ module MaRuKu
21
+ # This represents a list of attributes specified in the Markdown document
22
+ # that apply to a Markdown-generated tag.
23
+ # What was `{#id .class key="val" ref}` in the Markdown
24
+ # is parsed into `[[:id, 'id'], [:class, 'id'], ['key', 'val'], [:ref, 'ref']]`.
25
+ class AttributeList < Array
26
+ def to_s
27
+ map do |k, v|
28
+ case k
29
+ when :id; "#" + quote_if_needed(v)
30
+ when :class; "." + quote_if_needed(v)
31
+ when :ref; quote_if_needed(v)
32
+ else quote_if_needed(k) + "=" + quote_if_needed(v)
33
+ end
34
+ end.join(' ')
35
+ end
36
+ alias to_md to_s
37
+
38
+ private
39
+
40
+ def quote_if_needed(str)
41
+ return str unless str =~ /[\s'"]/
42
+ str.inspect
43
+ end
44
+ end
45
+
46
+ module In::Markdown::SpanLevelParser
47
+ def md_al(s = []); AttributeList.new(s); end
48
+
49
+ # @return [AttributeList, nil]
50
+ def read_attribute_list(src, con, break_on_chars)
51
+ separators = break_on_chars + [?=, ?\s, ?\t]
52
+ escaped = Maruku::EscapedCharInQuotes
53
+
54
+ al = AttributeList.new
55
+ loop do
56
+ src.consume_whitespace
57
+ break if break_on_chars.include? src.cur_char
58
+
59
+ case src.cur_char
60
+ when nil
61
+ maruku_error "Attribute list terminated by EOF:\n #{al.inspect}", src, con
62
+ tell_user "Returning partial attribute list:\n #{al.inspect}"
63
+ break
64
+ when ?= # error
65
+ src.ignore_char
66
+ maruku_error "In attribute lists, cannot start identifier with `=`."
67
+ tell_user "Ignoring and continuing."
68
+ when ?# # id definition
69
+ src.ignore_char
70
+ if id = read_quoted_or_unquoted(src, con, escaped, separators)
71
+ al << [:id, id]
72
+ else
73
+ maruku_error 'Could not read `id` attribute.', src, con
74
+ tell_user 'Ignoring bad `id` attribute.'
75
+ end
76
+ when ?. # class definition
77
+ src.ignore_char
78
+ if klass = read_quoted_or_unquoted(src, con, escaped, separators)
79
+ al << [:class, klass]
80
+ else
81
+ maruku_error 'Could not read `class` attribute.', src, con
82
+ tell_user 'Ignoring bad `class` attribute.'
83
+ end
84
+ else
85
+ unless key = read_quoted_or_unquoted(src, con, escaped, separators)
86
+ maruku_error 'Could not read key or reference.'
87
+ next
88
+ end
89
+
90
+ if src.cur_char != ?=
91
+ al << [:ref, key]
92
+ next
93
+ end
94
+
95
+ src.ignore_char # skip the =
96
+ if val = read_quoted_or_unquoted(src, con, escaped, separators)
97
+ al << [key, val]
98
+ else
99
+ maruku_error "Could not read value for key #{key.inspect}.", src, con
100
+ tell_user "Ignoring key #{key.inspect}"
101
+ end
102
+ end
103
+ end
104
+ al
105
+ end
106
+
107
+ def merge_ial(elements, src, con)
108
+ # Apply each IAL to the element before
109
+ (elements + [nil]).each_cons(3) do |before, e, after|
110
+ next unless ial?(e)
111
+
112
+ if before.kind_of? MDElement
113
+ before.al = e.ial
114
+ elsif after.kind_of? MDElement
115
+ after.al = e.ial
116
+ else
117
+ maruku_error <<ERR, src, con
118
+ It's unclear which element the attribute list {:#{e.ial.to_md}}
119
+ is referring to. The element before is a #{before.class},
120
+ the element after is a #{after.class}.
121
+ before: #{before.inspect}
122
+ after: #{after.inspect}
123
+ ERR
124
+ end
125
+ end
126
+
127
+ unless Globals[:debug_keep_ials]
128
+ elements.delete_if {|x| ial?(x) && x != elements.first}
129
+ end
130
+ end
131
+
132
+ private
133
+
134
+ def ial?(e)
135
+ e.is_a?(MDElement) && e.node_type == :ial
136
+ end
137
+ end
138
+ end