markascend 0.1
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.
- checksums.yaml +7 -0
- data/Gemfile +9 -0
- data/copying +18 -0
- data/doc/api.ma +65 -0
- data/doc/index.ma +23 -0
- data/doc/syntax.ma +264 -0
- data/lib/markascend.rb +172 -0
- data/lib/markascend/builtin_macros.rb +154 -0
- data/lib/markascend/env.rb +68 -0
- data/lib/markascend/line_unit.rb +226 -0
- data/lib/markascend/macro.rb +13 -0
- data/lib/markascend/parser.rb +220 -0
- data/lib/markascend/popular_company_macros.rb +87 -0
- data/rakefile +176 -0
- data/readme +4 -0
- data/test/builtin_macros_test.rb +73 -0
- data/test/line_unit_test.rb +40 -0
- data/test/markascend_test.rb +19 -0
- data/test/parser_test.rb +93 -0
- data/test/popular_company_macros_test.rb +42 -0
- data/test/test_helper.rb +21 -0
- metadata +64 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: da8df76e1fec2a44dfd1dcaa2b8b27d7f12a86fe
|
4
|
+
data.tar.gz: bfd019319d0b249bb1bfca43a3aea1b8dd9943f9
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: d53e8a4039c10b9f74eebd2be669a48b9b328859b53f2397e7b356bfece745ec5f15183959a50856713fa0cc15aad04a4569e596d94de3500b0d49b3b300e156
|
7
|
+
data.tar.gz: f6199c6c3052ad1fd5db6d7001c193b0be5550e6b8c0592a6dee94e48d07a142557b05bbb2a6749eb0b7ece9fb07fa898a1bafbb656faa143920efe657caffc6
|
data/Gemfile
ADDED
data/copying
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
Copyright (C) 2013 by Zete Lui (BSD)
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
4
|
+
this software and associated documentation files (the "Software"), to deal in
|
5
|
+
the Software without restriction, including without limitation the rights to
|
6
|
+
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
7
|
+
the Software, and to permit persons to whom the Software is furnished to do so,
|
8
|
+
subject to the following conditions:
|
9
|
+
|
10
|
+
The above copyright notice and this permission notice shall be included in all
|
11
|
+
copies or substantial portions of the Software.
|
12
|
+
|
13
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
14
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
15
|
+
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
16
|
+
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
17
|
+
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
18
|
+
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
data/doc/api.ma
ADDED
@@ -0,0 +1,65 @@
|
|
1
|
+
\hi(ruby)
|
2
|
+
h2 Compile
|
3
|
+
|
4
|
+
|
|
5
|
+
Markascend.compile src, options
|
6
|
+
|
7
|
+
h2 Options
|
8
|
+
|
9
|
+
- `:autolink`, default value is `%w[http https ftp mailto]`
|
10
|
+
- `:inline_img`, compile image into inlined base64, default = `false`
|
11
|
+
- `:macros`, specify the names of enabled macros. Other macros will be treated as plain text. The default value is `Markascend::DEFAULT_MACROS`.
|
12
|
+
- `:line_units`, specify the inline parsers to be used (be careful with the order!). The default value is `Markascend::DEFAULT_LINE_UNITS`.
|
13
|
+
- `:sandbox`, a hybrid option to tweak the syntax to be generally safe for user inputs. `false` by default. When set to `true`, footnotes are disabled, header anchors are ignored, and enabled macros are set to `Markascend::SANDBOX_MACROS`. The sandbox macro list can be overriden by the `:macros` option.
|
14
|
+
- `:toc`, whether generate table of contents. `false` by default. Header anchors can be customized or generated in the form of `"-#{N}"`. Note that there's no "permalink" generator for headers, but you can implement one with simple javascript.
|
15
|
+
|
16
|
+
h2 Customizing macros
|
17
|
+
|
18
|
+
More macro processors can be added by
|
19
|
+
|
20
|
+
|
|
21
|
+
class Markascend::Macro
|
22
|
+
def parse_fancy_macro
|
23
|
+
... compose result string with: env, content, inline
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
Macro names are limited to names like ruby methods.
|
28
|
+
|
29
|
+
|
|
30
|
+
Markascend.compile src, macros: %w[fancy_macro del]
|
31
|
+
|
32
|
+
h2 Customizing line-unit parsers
|
33
|
+
|
34
|
+
More line-unit parsers can be added by
|
35
|
+
|
36
|
+
|
|
37
|
+
class Markascend::LineUnit
|
38
|
+
def parse_at
|
39
|
+
... compose result string with: env, line, block, linenum
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
The list of inline parsers can be changed, or reordered
|
44
|
+
|
45
|
+
|
|
46
|
+
Markascend.compile src, line_units: Markascend::DEFAULT_LINE_UNITS + %w[at]
|
47
|
+
|
48
|
+
h2 Notes on `\slim`
|
49
|
+
|
50
|
+
You need to install slim \hi(bash)(`gem ins slim`) and require it before using the \hi(ma)`\slim` macro:
|
51
|
+
\hi(ruby)
|
52
|
+
|
|
53
|
+
require 'slim'
|
54
|
+
|
55
|
+
It is disabled in sandbox mode.
|
56
|
+
|
57
|
+
h2 Notes on `\dot`
|
58
|
+
|
59
|
+
You need to install [graphviz](graphviz.org) before using the \hi(ma)`\dot` macro.
|
60
|
+
|
61
|
+
It is disabled in sandbox mode.
|
62
|
+
|
63
|
+
h2 Notes on output format
|
64
|
+
|
65
|
+
The output is valid HTML5, but not XHTML.
|
data/doc/index.ma
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
h2 Introduction
|
2
|
+
|
3
|
+
Markascend is an extensible markdown-like, macro-powered html document syntax and processor.
|
4
|
+
Can be used as blog-generator, post-formatter or for literate programing.
|
5
|
+
|
6
|
+
h2 Install
|
7
|
+
|
8
|
+
Requires Ruby 2.0.0+
|
9
|
+
|
10
|
+
|sh
|
11
|
+
gem ins markascend
|
12
|
+
|
13
|
+
h2 Cheat Sheet
|
14
|
+
|
15
|
+
h2 Document
|
16
|
+
|
17
|
+
- [Syntax in Details](syntax)
|
18
|
+
- [API in Details](api)
|
19
|
+
- [Editor Support (Textmate/Sublime)](https://github.com/luikore/Markascend.tmbundle)
|
20
|
+
|
21
|
+
h2 License
|
22
|
+
|
23
|
+
[BSD](https://github.com/luikore/markascend/tree/master/copying)
|
data/doc/syntax.ma
ADDED
@@ -0,0 +1,264 @@
|
|
1
|
+
\options
|
2
|
+
title: Syntax
|
3
|
+
|
4
|
+
h2 Design principles
|
5
|
+
|
6
|
+
- A simpler *Markdown* should be better.
|
7
|
+
- Since a markup language usually need to process several different syntaces in one article, language composition becomes important in syntax design.
|
8
|
+
- TeX macro syntax is nearly perfect for extending the language, but not very visual intuitive when there are too much backslashes and bracers.
|
9
|
+
- Layout-based grammar (indentation sensitive) shows a cleaner way for language composition and cleaning up macros.
|
10
|
+
|
11
|
+
\hi(ma)
|
12
|
+
|
13
|
+
h2 Inline elements
|
14
|
+
*italic*
|
15
|
+
|
|
16
|
+
*italic*
|
17
|
+
|
18
|
+
**bold**
|
19
|
+
|
|
20
|
+
**bold**
|
21
|
+
|
22
|
+
Italic and bold elements can interpolate
|
23
|
+
|
|
24
|
+
***bold and italic*bold**
|
25
|
+
|
26
|
+
`code` suject to the same rule as in markdown, no escape chars
|
27
|
+
|
|
28
|
+
`code`
|
29
|
+
``to include "`", use more backticks as delimiter``
|
30
|
+
`` ` space before and after to disambig backtick number ``
|
31
|
+
|
32
|
+
$math$, inside which `\\` and `\$` are treated as atomic elements, no escape chars
|
33
|
+
|
|
34
|
+
$math$
|
35
|
+
$\\\$$ <- the content is parsed to latex processer as '\\\$'
|
36
|
+
$\\$$ <- NOTE this is a math elem with a pending dollar
|
37
|
+
|
38
|
+
Link:
|
39
|
+
|
|
40
|
+
url in lexical parens: [a](example.com/use/\\/for/backslash/and/\)/for/right/paren)
|
41
|
+
url in recursive braces: [a]{example.com/allow/{nested{braces}}/and/(parens)/in/url}
|
42
|
+
no need to escape backslashes in braces: [a]{file:\\\C:\windows}
|
43
|
+
link to anchor: [a](#anchor)
|
44
|
+
|
45
|
+
Footnotes:
|
46
|
+
|
|
47
|
+
[.](this is shown in footnote and replaced by a number)
|
48
|
+
[.*](this is shown in footnote and replaced by the acronym: *)
|
49
|
+
|
50
|
+
Using already defined footnote ("one more dot to use"):
|
51
|
+
|
|
52
|
+
[:1]
|
53
|
+
[:link by acronym]
|
54
|
+
|
55
|
+
Except math and code, inline elements can be nested.
|
56
|
+
|
57
|
+
By default, text starting with `http://`, `https://` or `mailto://` will be auto-linked, you can change supported protocols or disable all with compile options.
|
58
|
+
|
59
|
+
NOTE: Not very different from markdown here, just less, math and footnotes added. Images are too complex for a simple syntax, it is made into a macro.
|
60
|
+
|
61
|
+
h2 Headers
|
62
|
+
|
|
63
|
+
h1 title
|
64
|
+
h2#anchor-name title
|
65
|
+
|
66
|
+
NOTE: Anchors are disabled in sandbox mode.
|
67
|
+
h2 Lists
|
68
|
+
|
69
|
+
`-` is the bullet for unordered list
|
70
|
+
|
|
71
|
+
- an entry
|
72
|
+
- another entry
|
73
|
+
|
74
|
+
`+` is the bullet for ordered list
|
75
|
+
|
|
76
|
+
+ entry 1
|
77
|
+
+ entry 2
|
78
|
+
|
79
|
+
h2 Quote
|
80
|
+
|
81
|
+
Just one `>` is enough for a quote containing many lines (NOTE: use the similar rule as code block and allow quoter name?)
|
82
|
+
|
|
83
|
+
> You
|
84
|
+
can
|
85
|
+
input
|
86
|
+
new line
|
87
|
+
on twitter
|
88
|
+
now
|
89
|
+
|
90
|
+
h2 Escape characters
|
91
|
+
|
|
92
|
+
\h3
|
93
|
+
\\
|
94
|
+
\$
|
95
|
+
\*
|
96
|
+
\[
|
97
|
+
\%
|
98
|
+
\@
|
99
|
+
\#
|
100
|
+
...
|
101
|
+
|
102
|
+
All HTML4 entities are supported
|
103
|
+
|
|
104
|
+
&
|
105
|
+
ॎ
|
106
|
+
?
|
107
|
+
|
108
|
+
h2 Built-in macros
|
109
|
+
|
110
|
+
The following macros explains themselves:
|
111
|
+
|
|
112
|
+
\del{deleted}
|
113
|
+
\underline{underline}
|
114
|
+
\sub{subscript}
|
115
|
+
\sup{supscript}
|
116
|
+
\img{hello/a.png alt="an image" href="a.b.c"}
|
117
|
+
|
118
|
+
Unlike in *Mardown*, all html tags in *Markascend* are escaped. If you write
|
119
|
+
|ma
|
120
|
+
<div></div>
|
121
|
+
|
122
|
+
You get HTML like this
|
123
|
+
|html
|
124
|
+
<div></div>
|
125
|
+
|
126
|
+
To put HTML in, you can use the `\html` macro
|
127
|
+
|
|
128
|
+
\html{<hr>}
|
129
|
+
|
130
|
+
*Slim* is a template engine which makes html much cleaner:
|
131
|
+
|
|
132
|
+
\slim{a href="/" Home}
|
133
|
+
|
134
|
+
Note that with `\slim`, you can embed a bunch of other template engines, or write ruby logic, or do all kinds of evil things:
|
135
|
+
|
|
136
|
+
\slim
|
137
|
+
- 3.times do
|
138
|
+
markdown:
|
139
|
+
# h1 hello world
|
140
|
+
sass:
|
141
|
+
h1
|
142
|
+
color: red
|
143
|
+
coffee:
|
144
|
+
alert "hello world"
|
145
|
+
|
146
|
+
To build a table from a CSV
|
147
|
+
|
|
148
|
+
\csv
|
149
|
+
name,type
|
150
|
+
"Ahri",Mage
|
151
|
+
"Miss Fortune",DPS
|
152
|
+
|
153
|
+
A table from CSV, without header
|
154
|
+
|
|
155
|
+
\headless_csv
|
156
|
+
"Ahri",Mage
|
157
|
+
"Miss Fortune",DPS
|
158
|
+
|
159
|
+
For block-styled math
|
160
|
+
|
|
161
|
+
\latex
|
162
|
+
\begin{align} \\
|
163
|
+
& \rm{MathJax}\ \LaTeX \ \rm{Example} \\ \\
|
164
|
+
\end{align}
|
165
|
+
|
166
|
+
`\options` is a special macro. The content *YAML* is not processed by *Markascend*, but retrievable with API. This is designed for blogger generators: you can put metadata inside the document.
|
167
|
+
|
|
168
|
+
\options
|
169
|
+
tags: [markascend readme]
|
170
|
+
|
171
|
+
To change default code syntax highliter (See [below](#syn-hi-macros) for details]:
|
172
|
+
|
|
173
|
+
\hi(rb)
|
174
|
+
\hi(none)
|
175
|
+
|
176
|
+
h2 Notes on macros
|
177
|
+
|
178
|
+
Macro name is case sensitive, starts with a word-character but not digit, and contains no symbols or punctuations. The rule expressed in (Onigmo) regexp is `(?!\d)\w+`. For example, `你2` is valid name, but `2你` is invalid.
|
179
|
+
|
180
|
+
Macros can be of inline form (`\macro{content}`) or block form (`\macro` and the indented block in following lines is the content of the macro).
|
181
|
+
|
182
|
+
Inline macros can use some different delimiters for convinience, allowed ones are: `\macro(content)` and `\macro{content}`.
|
183
|
+
|
184
|
+
In the form `\macro(content)`, the content is parsed by lexical rule. The parser handles and only handles 2 escape chars: `\\` and `\)`, very much like single quoted string in Ruby.
|
185
|
+
Example: `\macro(\ and \\ are both single-backslash. nest: (\))`
|
186
|
+
|
187
|
+
In the form `\macro{content}`, you don't escape chars in the content, and can put in recursively nested braces. When you need to put an unmatched `{` or `}` in the content, use the previous form.
|
188
|
+
Example: `\macro{\\ is two backslashes. nest: {}}`
|
189
|
+
|
190
|
+
Design NOTE: There are actual very few symbols left for us... for example `[]`, `$$`, `|` may confuse with link or math or code elements. Symbols like `"`, `'`, `()`, `<>` are not good either, because they are common when composing an article.
|
191
|
+
|
192
|
+
User NOTE:
|
193
|
+
- The parsing rules for `(content)` and `{content}` are the same as in links.
|
194
|
+
- Only 1 block-style macro name is allowed inside a line.
|
195
|
+
- The basic parsing unit is a line and a block, every parsing starts with this unit --- so don't hand-add space indentations to paragraphs, let css do it.
|
196
|
+
|
197
|
+
h2 Charting macros
|
198
|
+
|
199
|
+
You need to install [graphviz](http://graphviz.org/) first.
|
200
|
+
|
201
|
+
|
|
202
|
+
\dot
|
203
|
+
digraph G{
|
204
|
+
main -> parse;
|
205
|
+
}
|
206
|
+
|
207
|
+
h2 Popular-company macros
|
208
|
+
|
209
|
+
This is the transient part but provides some convienience. The list will change if some of them dies before *Markascend*.
|
210
|
+
|
211
|
+
To generate a twitter or weibo link
|
212
|
+
|
|
213
|
+
\twitter(@night_song)
|
214
|
+
\twitter(#HotS)
|
215
|
+
\weibo(@yavaeye)
|
216
|
+
|
217
|
+
To generate a wiki link (though wiki is an organization, not a company...)
|
218
|
+
|
|
219
|
+
\wiki{ruby(programing_language)}
|
220
|
+
|
221
|
+
Embed gist
|
222
|
+
|
|
223
|
+
\gist(12321)
|
224
|
+
|
225
|
+
Embed video (currently should recognize youtube, vimeo and niconico links, the size is a problem)
|
226
|
+
|
|
227
|
+
\video(500x400 http://www.youtube.com/watch?v=TGPvtlnwH6E)
|
228
|
+
\video(500x400 http://www.youtube.com/watch?v=TGPvtlnwH6E)
|
229
|
+
\video(500x400 http://www.youtube.com/watch?v=TGPvtlnwH6E)
|
230
|
+
|
231
|
+
h2#syn-hi-macros Syntax hilite macros and code blocks
|
232
|
+
|
233
|
+
Inline code can also have syntax hiliter
|
234
|
+
|
235
|
+
|
|
236
|
+
\hi(rb)`str.size` in ruby is equivalent to \hi(objc)`str.length` in objc
|
237
|
+
|
|
238
|
+
this part is also hilited in objc
|
239
|
+
\hi(none)`\hi(none)` removes hilite state in document
|
240
|
+
|
|
241
|
+
this part also has no syntax hilite
|
242
|
+
|
243
|
+
To specify syntax in block form (this won't change default syntax):
|
244
|
+
|
|
245
|
+
|rb
|
246
|
+
puts 'hello world'
|
247
|
+
|
248
|
+
h2 Combining macro blocks, lists and quotes
|
249
|
+
|
250
|
+
Lists and quotes are parsed as recursive block elements.
|
251
|
+
If the inside contains macros, need to indent more for the content of the macro:
|
252
|
+
|
|
253
|
+
> Though the \music macro..
|
254
|
+
1232. 1232. 1232.
|
255
|
+
is not defined.
|
256
|
+
|
257
|
+
Another nesting example:
|
258
|
+
|
|
259
|
+
- an entry
|
260
|
+
contains an ordered list
|
261
|
+
+ entry \latex
|
262
|
+
\mathbb{one}
|
263
|
+
+ entry 2
|
264
|
+
- another entry
|
data/lib/markascend.rb
ADDED
@@ -0,0 +1,172 @@
|
|
1
|
+
require "strscan"
|
2
|
+
require "cgi"
|
3
|
+
require "csv"
|
4
|
+
require "yaml"
|
5
|
+
require "base64"
|
6
|
+
require "open3"
|
7
|
+
require "pygments"
|
8
|
+
require "open-uri"
|
9
|
+
require "filemagic"
|
10
|
+
|
11
|
+
module Markascend
|
12
|
+
VERSION = '0.1'
|
13
|
+
|
14
|
+
DEFAULT_MACROS = Hash.[] %w[
|
15
|
+
del underline sub sup
|
16
|
+
img html slim
|
17
|
+
csv headless_csv
|
18
|
+
latex
|
19
|
+
options hi
|
20
|
+
dot
|
21
|
+
|
22
|
+
twitter weibo
|
23
|
+
wiki
|
24
|
+
gist
|
25
|
+
video
|
26
|
+
].map{|k| [k, "parse_#{k}"]}
|
27
|
+
|
28
|
+
SANDBOX_MACROS = DEFAULT_MACROS.dup.delete_if do |k, v|
|
29
|
+
%w[html slim options dot].include? k
|
30
|
+
end
|
31
|
+
|
32
|
+
# NOTE on the order:
|
33
|
+
# - link/bold/italic can contain char
|
34
|
+
# but link need not interpolate with bold or italic, seems too rare cased
|
35
|
+
# - bold/italic can interpolate with each other
|
36
|
+
# - escapes are processed in the char parser, link/bold/italic can use escape chars
|
37
|
+
DEFAULT_LINE_UNITS = %w[
|
38
|
+
inline_code
|
39
|
+
math
|
40
|
+
auto_link
|
41
|
+
macro
|
42
|
+
link
|
43
|
+
bold_italic
|
44
|
+
char
|
45
|
+
].map{|k| "parse_#{k}"}
|
46
|
+
|
47
|
+
class << Markascend
|
48
|
+
def compile src, opts={}
|
49
|
+
src = src.gsub "\t", ' '
|
50
|
+
env = Env.new opts
|
51
|
+
res = Parser.new(env, src).parse
|
52
|
+
|
53
|
+
if env.toc and !env.toc.empty?
|
54
|
+
res = (generate_toc(env.toc) << res)
|
55
|
+
end
|
56
|
+
|
57
|
+
if env.footnotes and !env.footnotes.empty?
|
58
|
+
res << generate_footnotes(env.footnotes)
|
59
|
+
end
|
60
|
+
|
61
|
+
res
|
62
|
+
end
|
63
|
+
|
64
|
+
attr_accessor :inline_parsers, :macros
|
65
|
+
|
66
|
+
# escape html
|
67
|
+
def escape_html s
|
68
|
+
CGI.escape_html s
|
69
|
+
end
|
70
|
+
|
71
|
+
# escape string so that the result can be placed inside double-quoted value of a tag property
|
72
|
+
def escape_attr s
|
73
|
+
# http://www.w3.org/TR/html5/syntax.html#attributes-0
|
74
|
+
s ? (s.gsub /"/, '"') : ''
|
75
|
+
end
|
76
|
+
|
77
|
+
# escape string so that the result can be placed inside a `<pre>` tag
|
78
|
+
def escape_pre s
|
79
|
+
s.gsub(/(<)|(>)|&/){$1 ? '<' : $2 ? '>' : '&'}
|
80
|
+
end
|
81
|
+
|
82
|
+
# syntax hilite s with lang
|
83
|
+
def hilite s, lang, inline=false
|
84
|
+
if !lang or lang =~ /\A(ma(rkascend)?)?\z/i or !(::Pygments::Lexer.find lang)
|
85
|
+
# TODO ma lexer
|
86
|
+
s = inline ? (escape_html s) : (escape_pre s)
|
87
|
+
else
|
88
|
+
s = Pygments.highlight s, lexer: lang, options: {nowrap: true}
|
89
|
+
end
|
90
|
+
|
91
|
+
# TODO config class
|
92
|
+
if inline
|
93
|
+
%Q|<code class="highlight">#{s}</code>|
|
94
|
+
else
|
95
|
+
%Q|<pre><code class="highlight">#{s}</code></pre>|
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
# detect mime type of the buffer
|
100
|
+
def mime buffer
|
101
|
+
fm = FileMagic.new FileMagic::MAGIC_MIME_TYPE
|
102
|
+
res = fm.buffer buffer
|
103
|
+
fm.close
|
104
|
+
res
|
105
|
+
end
|
106
|
+
|
107
|
+
# strip tags from s
|
108
|
+
def strip_tags s
|
109
|
+
# deal with html tags only
|
110
|
+
s.gsub(/
|
111
|
+
\<\s*script\b
|
112
|
+
(?:
|
113
|
+
(["']).*?\1|[^\>] # properties
|
114
|
+
)*
|
115
|
+
\>
|
116
|
+
.*?
|
117
|
+
\<\s*\/\s*script\s*\>
|
118
|
+
/x, '').gsub(/
|
119
|
+
\<\s*(?:\/\s*)?
|
120
|
+
\w+\b # tag name, no need to care xml namespace
|
121
|
+
(?:
|
122
|
+
(["']).*?\1|[^\>] # properties
|
123
|
+
)*
|
124
|
+
\>
|
125
|
+
/x, '')
|
126
|
+
end
|
127
|
+
|
128
|
+
private
|
129
|
+
|
130
|
+
def generate_toc toc
|
131
|
+
res = '<div id="toc"><ol>'
|
132
|
+
levels = toc.values.map(&:first).uniq.sort
|
133
|
+
prev_level = 0
|
134
|
+
toc.each do |id, (x, header_content)| # x as in "hx"
|
135
|
+
level = levels.index(x)
|
136
|
+
if level >= prev_level
|
137
|
+
(level - prev_level).times do
|
138
|
+
res << "<ol>"
|
139
|
+
end
|
140
|
+
elsif
|
141
|
+
(prev_level - level).times do
|
142
|
+
res << "</ol>"
|
143
|
+
end
|
144
|
+
end
|
145
|
+
prev_level = level
|
146
|
+
title = strip_tags header_content
|
147
|
+
res << %Q{<li><a href="\##{id}">#{title}</a></li>}
|
148
|
+
end
|
149
|
+
prev_level.times do
|
150
|
+
res << "</ol>"
|
151
|
+
end
|
152
|
+
res << "</ol></div>"
|
153
|
+
end
|
154
|
+
|
155
|
+
def generate_footnotes footnotes
|
156
|
+
res = '<div id="footnotes"><ol>'
|
157
|
+
i = 0
|
158
|
+
footnotes.each do |abbrev, detail|
|
159
|
+
res << %Q|<li id="footnote-#{i}">#{escape_html detail}</li>|
|
160
|
+
i += 1
|
161
|
+
end
|
162
|
+
res << "</ol></div>"
|
163
|
+
end
|
164
|
+
end
|
165
|
+
end
|
166
|
+
|
167
|
+
require_relative "markascend/env"
|
168
|
+
require_relative "markascend/parser"
|
169
|
+
require_relative "markascend/line_unit"
|
170
|
+
require_relative "markascend/macro"
|
171
|
+
require_relative "markascend/builtin_macros"
|
172
|
+
require_relative "markascend/popular_company_macros"
|