markita 2.0.210906 → 3.0.210907
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +1 -1
- data/lib/markita/base.rb +1 -64
- data/lib/markita/html.rb +21 -0
- data/lib/markita/markdown.rb +240 -160
- data/lib/markita/plug/about.rb +1 -1
- data/lib/markita/preprocess.rb +30 -0
- data/lib/markita.rb +3 -1
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8176e09462f3a78f7e10600cef156aff9d32ed892c97366d242bf299e87adf5e
|
4
|
+
data.tar.gz: '0864ffe280f23e7d15b196aef1226a14f7b3443c0ebf4a142667187550665ab9'
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 16135591f2eb1d7446be0337c0ba7b51624834f169f219c1a0a534d88f263dec04da18e8b8e05f5c4d4998b8d9a96aaf437e53d1d0858b36aab19948f10985bc
|
7
|
+
data.tar.gz: ecfc73bc0f9e13e216a1b5e9682bbfdc93a9aada53b3aaa49e19c529324b37a9afeb06761349a2ce4dda10c1bfeb4852d4bc705ff137f488451117afb3eb2612
|
data/README.md
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# Markita
|
2
2
|
|
3
|
-
* [VERSION
|
3
|
+
* [VERSION 3.0.210907](https://github.com/carlosjhr64/markita/releases)
|
4
4
|
* [github](https://www.github.com/carlosjhr64/markita)
|
5
5
|
* [rubygems](https://rubygems.org/gems/markita)
|
6
6
|
|
data/lib/markita/base.rb
CHANGED
@@ -1,33 +1,4 @@
|
|
1
1
|
module Markita
|
2
|
-
class Preprocess
|
3
|
-
def initialize(file)
|
4
|
-
@file = (file.is_a? String)? StringIO.new(file) : file
|
5
|
-
@regx = @template = nil
|
6
|
-
end
|
7
|
-
|
8
|
-
def gets
|
9
|
-
if line = @file.gets
|
10
|
-
case line
|
11
|
-
when @regx
|
12
|
-
line = @template if @template
|
13
|
-
$~.named_captures.each do |name, value|
|
14
|
-
line = line.gsub("&#{name.downcase};", value)
|
15
|
-
line = line.gsub("&#{name.upcase};", CGI.escape(value))
|
16
|
-
end
|
17
|
-
when %r(^! regx = /(.*)/$)
|
18
|
-
@regx = Regexp.new $1
|
19
|
-
line = gets
|
20
|
-
when %r(^! template = "(.*)"$)
|
21
|
-
@template = $1+"\n"
|
22
|
-
line = gets
|
23
|
-
else
|
24
|
-
@regx &&= (@template=nil)
|
25
|
-
end
|
26
|
-
end
|
27
|
-
line
|
28
|
-
end
|
29
|
-
end
|
30
|
-
|
31
2
|
class Base < Sinatra::Base
|
32
3
|
set bind: OPTIONS&.bind || '0.0.0.0'
|
33
4
|
set port: OPTIONS&.port || '8080'
|
@@ -47,44 +18,10 @@ class Base < Sinatra::Base
|
|
47
18
|
end
|
48
19
|
end
|
49
20
|
|
50
|
-
def Base.header(key)
|
51
|
-
<<~HEADER
|
52
|
-
<!DOCTYPE html>
|
53
|
-
<html>
|
54
|
-
<head>
|
55
|
-
<title>#{key}</title>
|
56
|
-
#{HEADER_LINKS}</head>
|
57
|
-
<body>
|
58
|
-
HEADER
|
59
|
-
end
|
60
|
-
|
61
|
-
def Base.footer
|
62
|
-
<<~FOOTER
|
63
|
-
</body>
|
64
|
-
</html>
|
65
|
-
FOOTER
|
66
|
-
end
|
67
|
-
|
68
|
-
DEFAULT = lambda do |line, html, file, _, _|
|
69
|
-
html << line
|
70
|
-
file.gets
|
71
|
-
end
|
72
|
-
|
73
|
-
def Base.page(key, f)
|
74
|
-
html,opt,file,line = '',{},Preprocess.new(f),Base.header(key)
|
75
|
-
fct,md = nil,nil
|
76
|
-
while line = (fct||DEFAULT)[line, html, file, opt, md]
|
77
|
-
fct = nil
|
78
|
-
Markdown::PARSER.each{|r,f| break if md=r.match(line) and fct=f}
|
79
|
-
end
|
80
|
-
html << Base.footer
|
81
|
-
html
|
82
|
-
end
|
83
|
-
|
84
21
|
get PAGE_KEY do |key|
|
85
22
|
filepath = File.join ROOT, key+'.md'
|
86
23
|
raise Sinatra::NotFound unless File.exist? filepath
|
87
|
-
|
24
|
+
Markdown.new(key).filepath filepath
|
88
25
|
end
|
89
26
|
|
90
27
|
get IMAGE_PATH do |path, *_|
|
data/lib/markita/html.rb
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
module Markita
|
2
|
+
module HTML
|
3
|
+
def HTML.header(key)
|
4
|
+
<<~HEADER
|
5
|
+
<!DOCTYPE html>
|
6
|
+
<html>
|
7
|
+
<head>
|
8
|
+
<title>#{key}</title>
|
9
|
+
#{HEADER_LINKS}</head>
|
10
|
+
<body>
|
11
|
+
HEADER
|
12
|
+
end
|
13
|
+
|
14
|
+
def HTML.footer
|
15
|
+
<<~FOOTER
|
16
|
+
</body>
|
17
|
+
</html>
|
18
|
+
FOOTER
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
data/lib/markita/markdown.rb
CHANGED
@@ -1,59 +1,99 @@
|
|
1
1
|
module Markita
|
2
|
-
|
2
|
+
class Markdown
|
3
|
+
ROUGE = Rouge::Formatters::HTML.new
|
4
|
+
PARSERS = []
|
5
|
+
|
6
|
+
def initialize(title)
|
7
|
+
@title = title
|
8
|
+
@line=@html=@file=@opt=nil
|
9
|
+
end
|
10
|
+
|
11
|
+
def start
|
12
|
+
@line,@html,@opt = HTML.header(@title),'',{}
|
13
|
+
end
|
14
|
+
|
15
|
+
def finish
|
16
|
+
@html << HTML.footer
|
17
|
+
end
|
18
|
+
|
19
|
+
def default
|
20
|
+
@html << @line
|
21
|
+
@line = @file.gets
|
22
|
+
end
|
23
|
+
|
24
|
+
def parse(fh)
|
25
|
+
@file = Preprocess.new(fh)
|
26
|
+
start
|
27
|
+
while @line
|
28
|
+
PARSERS.detect{method(_1).call} or default
|
29
|
+
end
|
30
|
+
finish
|
31
|
+
end
|
32
|
+
|
33
|
+
def markdown(string)
|
34
|
+
parse StringIO.new string
|
35
|
+
@html
|
36
|
+
end
|
37
|
+
|
38
|
+
def filepath(filepath)
|
39
|
+
File.open(filepath, 'r'){|fh| parse fh}
|
40
|
+
@html
|
41
|
+
end
|
42
|
+
|
3
43
|
Ux = /_([^_]+)_/
|
4
|
-
U = lambda {|
|
44
|
+
U = lambda {|m| "<u>#{m[1]}</u>"}
|
5
45
|
|
6
46
|
Sx = /~([^~]+)~/
|
7
|
-
S = lambda {|
|
47
|
+
S = lambda {|m| "<s>#{m[1]}</s>"}
|
8
48
|
|
9
49
|
Ix = /"([^"]+)"/
|
10
|
-
I = lambda {|
|
50
|
+
I = lambda {|m| "<i>#{m[1]}</i>"}
|
11
51
|
|
12
52
|
Bx = /\*([^\*]+)\*/
|
13
|
-
B = lambda {|
|
53
|
+
B = lambda {|m| "<b>#{m[1]}</b>"}
|
14
54
|
|
15
55
|
CODEx = /`([^`]+)`/
|
16
|
-
CODE = lambda {|
|
56
|
+
CODE = lambda {|m| "<code>#{m[1]}</code>"}
|
17
57
|
|
18
58
|
Ax = /\[([^\[\]]+)\]\(([^()]+)\)/
|
19
|
-
A = lambda {|
|
59
|
+
A = lambda {|m| %Q(<a href="#{m[2]}">#{m[1]}</a>)}
|
20
60
|
|
21
61
|
URLx = %r(\[(https?://[\w\.\-\/\&\+\?\%]+)\])
|
22
|
-
URL = lambda {|
|
62
|
+
URL = lambda {|m| %Q(<a href="#{m[1]}">#{m[1]}</a>)}
|
23
63
|
|
24
64
|
EMOJIx = /:(\w+):/
|
25
|
-
EMOJI = lambda {|
|
65
|
+
EMOJI = lambda {|m| (_=EMOJIS[m[1]])? "&\#x#{_};" : m[0]}
|
26
66
|
|
27
67
|
FOOTNOTEx = /\[\^(\d+)\](:)?/
|
28
|
-
FOOTNOTE = lambda do |
|
29
|
-
if
|
30
|
-
%Q(<a id="fn:#{
|
68
|
+
FOOTNOTE = lambda do |m|
|
69
|
+
if m[2]
|
70
|
+
%Q(<a id="fn:#{m[1]}" href="\#fnref:#{m[1]}">#{m[1]}:</a>)
|
31
71
|
else
|
32
|
-
%Q(<a id="fnref:#{
|
72
|
+
%Q(<a id="fnref:#{m[1]}" href="\#fn:#{m[1]}"><sup>#{m[1]}</sup></a>)
|
33
73
|
end
|
34
74
|
end
|
35
75
|
|
36
|
-
def Markdown.tag(
|
37
|
-
if
|
38
|
-
pre_match = (block ? block.call(
|
39
|
-
string = pre_match +
|
40
|
-
post_match =
|
41
|
-
while
|
42
|
-
pre_match = (block ? block.call(
|
43
|
-
string << pre_match +
|
44
|
-
post_match =
|
76
|
+
def Markdown.tag(entry, regx, m2string, &block)
|
77
|
+
if m = regx.match(entry)
|
78
|
+
pre_match = (block ? block.call(m.pre_match) : m.pre_match)
|
79
|
+
string = pre_match + m2string[m]
|
80
|
+
post_match = m.post_match
|
81
|
+
while m = regx.match(post_match)
|
82
|
+
pre_match = (block ? block.call(m.pre_match) : m.pre_match)
|
83
|
+
string << pre_match + m2string[m]
|
84
|
+
post_match = m.post_match
|
45
85
|
end
|
46
86
|
string << (block ? block.call(post_match) : post_match)
|
47
87
|
return string
|
48
88
|
end
|
49
|
-
return (block ? block.call(
|
89
|
+
return (block ? block.call(entry) : entry)
|
50
90
|
end
|
51
91
|
|
52
|
-
INLINE = lambda do |
|
53
|
-
string = Markdown.tag(
|
54
|
-
Markdown.tag(
|
55
|
-
Markdown.tag(
|
56
|
-
string = Markdown.tag(
|
92
|
+
INLINE = lambda do |entry|
|
93
|
+
string = Markdown.tag(entry, CODEx, CODE) do |entry|
|
94
|
+
Markdown.tag(entry, Ax, A) do |entry|
|
95
|
+
Markdown.tag(entry, URLx, URL) do |entry|
|
96
|
+
string = Markdown.tag(entry, Bx, B)
|
57
97
|
string = Markdown.tag(string, Ix, I)
|
58
98
|
string = Markdown.tag(string, Sx, S)
|
59
99
|
string = Markdown.tag(string, Ux, U)
|
@@ -65,204 +105,233 @@ module Markdown
|
|
65
105
|
string.sub(/ $/,'<br>')
|
66
106
|
end
|
67
107
|
|
68
|
-
PARSER = Hash.new
|
69
|
-
|
70
108
|
# Empty
|
71
|
-
|
72
|
-
|
109
|
+
EMPTY = /^$/
|
110
|
+
PARSERS << :empty
|
111
|
+
def empty
|
112
|
+
EMPTY.match?(@line) or return false
|
113
|
+
@line = @file.gets
|
114
|
+
true
|
73
115
|
end
|
74
116
|
|
75
117
|
# Ordered list
|
76
118
|
ORDERED = /^\d+. (.*)$/
|
77
|
-
|
78
|
-
|
79
|
-
|
119
|
+
PARSERS << :ordered
|
120
|
+
def ordered
|
121
|
+
md = ORDERED.match(@line) or return false
|
122
|
+
@html << "<ol#{@opt[:attributes]}>\n"
|
123
|
+
@opt.delete(:attributes)
|
80
124
|
while md
|
81
|
-
html << " <li>#{INLINE[md[1]]}</li>\n"
|
82
|
-
md = (line
|
125
|
+
@html << " <li>#{INLINE[md[1]]}</li>\n"
|
126
|
+
md = (@line=@file.gets)&.match ORDERED
|
83
127
|
end
|
84
|
-
html << "</ol>\n"
|
85
|
-
|
128
|
+
@html << "</ol>\n"
|
129
|
+
true
|
86
130
|
end
|
87
131
|
|
88
132
|
# Paragraph
|
89
133
|
PARAGRAPHS = /^[\[`*"~_]?\w/
|
90
|
-
|
91
|
-
|
92
|
-
|
134
|
+
PARSERS << :paragraphs
|
135
|
+
def paragraphs
|
136
|
+
md = PARAGRAPHS.match(@line) or return false
|
137
|
+
@html << "<p#{@opt[:attributes]}>\n"
|
138
|
+
@opt.delete(:attributes)
|
93
139
|
while md
|
94
|
-
html << INLINE[line]
|
95
|
-
md = (line
|
140
|
+
@html << INLINE[@line]
|
141
|
+
md = (@line=@file.gets)&.match PARAGRAPHS
|
96
142
|
end
|
97
|
-
html << "</p>\n"
|
98
|
-
|
143
|
+
@html << "</p>\n"
|
144
|
+
true
|
99
145
|
end
|
100
146
|
|
101
147
|
# Unordered list
|
102
148
|
UNORDERED = /^[*] (.*)$/
|
103
|
-
|
104
|
-
|
105
|
-
|
149
|
+
PARSERS << :unordered
|
150
|
+
def unordered
|
151
|
+
md = UNORDERED.match(@line) or return false
|
152
|
+
@html << "<ul#{@opt[:attributes]}>\n"
|
153
|
+
@opt.delete(:attributes)
|
106
154
|
while md
|
107
|
-
html << " <li>#{INLINE[md[1]]}</li>\n"
|
108
|
-
md = (line
|
155
|
+
@html << " <li>#{INLINE[md[1]]}</li>\n"
|
156
|
+
md = (@line=@file.gets)&.match UNORDERED
|
109
157
|
end
|
110
|
-
html << "</ul>\n"
|
111
|
-
|
158
|
+
@html << "</ul>\n"
|
159
|
+
true
|
112
160
|
end
|
113
161
|
|
114
162
|
# Ballot box
|
115
163
|
BALLOTS = /^- \[(x| )\] (.*)$/
|
116
|
-
|
117
|
-
|
118
|
-
|
164
|
+
PARSERS << :ballots
|
165
|
+
def ballots
|
166
|
+
md = BALLOTS.match(@line) or return false
|
167
|
+
@html << "<ul#{@opt[:attributes]}>\n"
|
168
|
+
@opt.delete(:attributes)
|
119
169
|
while md
|
120
170
|
x,t = md[1],md[2]
|
121
171
|
li = (x=='x')?
|
122
172
|
%q{<li style="list-style-type: '☑ '">} :
|
123
173
|
%q{<li style="list-style-type: '☐ '">}
|
124
|
-
html << " #{li}#{INLINE[t]}</li>\n"
|
125
|
-
md = (line
|
174
|
+
@html << " #{li}#{INLINE[t]}</li>\n"
|
175
|
+
md = (@line=@file.gets)&.match BALLOTS
|
126
176
|
end
|
127
|
-
html << "</ul>\n"
|
128
|
-
|
177
|
+
@html << "</ul>\n"
|
178
|
+
true
|
129
179
|
end
|
130
180
|
|
131
181
|
# Definition list
|
132
182
|
DEFINITIONS = /^: (.*)$/
|
133
|
-
|
134
|
-
|
135
|
-
|
183
|
+
PARSERS << :definitions
|
184
|
+
def definitions
|
185
|
+
md = DEFINITIONS.match(@line) or return false
|
186
|
+
@html << "<dl#{@opt[:attributes]}>\n"
|
187
|
+
@opt.delete(:attributes)
|
136
188
|
while md
|
137
189
|
item = md[1]
|
138
|
-
|
190
|
+
@html << ((item[-1]==':')? "<dt>#{INLINE[item[0..-2]]}</dt>\n" :
|
139
191
|
"<dd>#{INLINE[item]}</dd>\n")
|
140
|
-
|
141
|
-
md = (line=file.gets)&.match DEFINITIONS
|
192
|
+
md = (@line=@file.gets)&.match DEFINITIONS
|
142
193
|
end
|
143
|
-
html << "</dl>\n"
|
144
|
-
|
194
|
+
@html << "</dl>\n"
|
195
|
+
true
|
145
196
|
end
|
146
197
|
|
147
198
|
# Headers
|
148
199
|
HEADERS = /^([#]{1,6}) (.*)$/
|
149
|
-
|
200
|
+
PARSERS << :headers
|
201
|
+
def headers
|
202
|
+
md = HEADERS.match(@line) or return false
|
150
203
|
i,header = md[1].length,md[2]
|
151
204
|
id = header.strip.gsub(/\s+/,'+')
|
152
|
-
html << %Q(<a id="#{id}">\n)
|
153
|
-
html << " <h#{i}#{opt[:attributes]}>#{INLINE[header]}</h#{i}>\n"
|
154
|
-
html << "</a>\n"
|
155
|
-
opt.delete(:attributes)
|
156
|
-
file.gets
|
205
|
+
@html << %Q(<a id="#{id}">\n)
|
206
|
+
@html << " <h#{i}#{@opt[:attributes]}>#{INLINE[header]}</h#{i}>\n"
|
207
|
+
@html << "</a>\n"
|
208
|
+
@opt.delete(:attributes)
|
209
|
+
@line = @file.gets
|
210
|
+
true
|
157
211
|
end
|
158
212
|
|
159
213
|
# Block-quote
|
160
214
|
BLOCKQS = /^> (.*)$/
|
161
|
-
|
162
|
-
|
163
|
-
|
215
|
+
PARSERS << :blockqs
|
216
|
+
def blockqs
|
217
|
+
md = BLOCKQS.match(@line) or return false
|
218
|
+
@html << "<blockquote#{@opt[:attributes]}>\n"
|
219
|
+
@opt.delete(:attributes)
|
164
220
|
while md
|
165
|
-
html << INLINE[md[1]]
|
166
|
-
html << "\n"
|
167
|
-
md = (line
|
221
|
+
@html << INLINE[md[1]]
|
222
|
+
@html << "\n"
|
223
|
+
md = (@line=@file.gets)&.match BLOCKQS
|
168
224
|
end
|
169
|
-
html << "</blockquote>\n"
|
170
|
-
|
225
|
+
@html << "</blockquote>\n"
|
226
|
+
true
|
171
227
|
end
|
172
228
|
|
173
|
-
HTML = Rouge::Formatters::HTML.new
|
174
229
|
|
175
230
|
# Code
|
176
231
|
CODES = /^[`~]{3}\s*(\w+)?$/
|
177
|
-
|
232
|
+
PARSERS << :codes
|
233
|
+
def codes
|
234
|
+
md = CODES.match(@line) or return false
|
178
235
|
lang = Rouge::Lexer.find md[1]
|
179
236
|
klass = lang ? ' class="highlight"' : nil
|
180
|
-
html << "<pre#{klass}#{opt[:attributes]}><code>\n"
|
181
|
-
opt.delete(:attributes)
|
237
|
+
@html << "<pre#{klass}#{@opt[:attributes]}><code>\n"
|
238
|
+
@opt.delete(:attributes)
|
182
239
|
code = ''
|
183
|
-
while line
|
184
|
-
code << line
|
240
|
+
while @line=@file.gets and not CODES.match(@line)
|
241
|
+
code << @line
|
185
242
|
end
|
186
|
-
html << (lang ?
|
187
|
-
html << "</code></pre>\n"
|
188
|
-
|
189
|
-
|
243
|
+
@html << (lang ? ROUGE.format(lang.new.lex(code)) : code)
|
244
|
+
@html << "</code></pre>\n"
|
245
|
+
@line = @file.gets if @line # then it's code close and thus need next @line.
|
246
|
+
true
|
190
247
|
end
|
191
248
|
|
192
249
|
# Preform
|
193
250
|
PREFORMS = /^ {4}(.*)$/
|
194
|
-
|
195
|
-
|
196
|
-
|
251
|
+
PARSERS << :preforms
|
252
|
+
def preforms
|
253
|
+
md = PREFORMS.match(@line) or return false
|
254
|
+
@html << "<pre#{@opt[:attributes]}>\n"
|
255
|
+
@opt.delete(:attributes)
|
197
256
|
while md
|
198
|
-
html << md[1]
|
199
|
-
html << "\n"
|
200
|
-
md = (line
|
257
|
+
@html << md[1]
|
258
|
+
@html << "\n"
|
259
|
+
md = (@line=@file.gets)&.match PREFORMS
|
201
260
|
end
|
202
|
-
html << "</pre>\n"
|
203
|
-
|
261
|
+
@html << "</pre>\n"
|
262
|
+
true
|
204
263
|
end
|
205
264
|
|
206
265
|
# Horizontal rule
|
207
266
|
HRS = /^---+$/
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
267
|
+
PARSERS << :hrs
|
268
|
+
def hrs
|
269
|
+
HRS.match? @line or return false
|
270
|
+
@html << "<hr#{@opt[:attributes]}>\n"
|
271
|
+
@opt.delete(:attributes)
|
272
|
+
@line = @file.gets
|
273
|
+
true
|
212
274
|
end
|
213
275
|
|
214
276
|
# Table
|
215
277
|
TABLES = /^\|.+\|$/
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
html <<
|
220
|
-
|
221
|
-
html <<
|
278
|
+
PARSERS << :tables
|
279
|
+
def tables
|
280
|
+
TABLES.match? @line or return false
|
281
|
+
@html << "<table#{@opt[:attributes]}>\n"
|
282
|
+
@opt.delete(:attributes)
|
283
|
+
@html << '<thead><tr><th>'
|
284
|
+
@html << @line[1...-1].split('|').map{INLINE[_1.strip]}.join('</th><th>')
|
285
|
+
@html << "</th></tr></thead>\n"
|
222
286
|
align = []
|
223
|
-
while (line
|
224
|
-
html << '<tr>'
|
225
|
-
line[1...-1].split('|').each_with_index do |cell, i|
|
287
|
+
while (@line=@file.gets)&.match TABLES
|
288
|
+
@html << '<tr>'
|
289
|
+
@line[1...-1].split('|').each_with_index do |cell, i|
|
226
290
|
case cell
|
227
291
|
when /^\s*:-+:\s*$/
|
228
292
|
align[i] = ' align="center"'
|
229
|
-
html << '<td><hr></td>'
|
293
|
+
@html << '<td><hr></td>'
|
230
294
|
when /^\s*-+:\s*$/
|
231
295
|
align[i] = ' align="right"'
|
232
|
-
html << '<td><hr></td>'
|
296
|
+
@html << '<td><hr></td>'
|
233
297
|
when /^\s*:-+\s*$/
|
234
298
|
align[i] = ' align="left"'
|
235
|
-
html << '<td><hr></td>'
|
299
|
+
@html << '<td><hr></td>'
|
236
300
|
else
|
237
|
-
html << "<td#{align[i]}>#{INLINE[cell.strip]}</td>"
|
301
|
+
@html << "<td#{align[i]}>#{INLINE[cell.strip]}</td>"
|
238
302
|
end
|
239
303
|
end
|
240
|
-
html << "</tr>\n"
|
304
|
+
@html << "</tr>\n"
|
241
305
|
end
|
242
|
-
html << "</table>\n"
|
243
|
-
|
306
|
+
@html << "</table>\n"
|
307
|
+
true
|
244
308
|
end
|
245
309
|
|
246
310
|
# Splits
|
247
311
|
SPLITS = /^:?\|:?$/
|
248
|
-
|
249
|
-
|
312
|
+
PARSERS << :splits
|
313
|
+
def splits
|
314
|
+
SPLITS.match? @line or return false
|
315
|
+
case @line.chomp
|
250
316
|
when '|:'
|
251
|
-
html << %Q(<table><tr><td#{opt[:attributes]}>\n)
|
317
|
+
@html << %Q(<table><tr><td#{@opt[:attributes]}>\n)
|
252
318
|
when '|'
|
253
|
-
html << %Q(</td><td#{opt[:attributes]}>\n)
|
319
|
+
@html << %Q(</td><td#{@opt[:attributes]}>\n)
|
254
320
|
when ':|:'
|
255
|
-
html << %Q(</td></tr><tr><td#{opt[:attributes]}>\n)
|
321
|
+
@html << %Q(</td></tr><tr><td#{@opt[:attributes]}>\n)
|
256
322
|
when ':|'
|
257
|
-
html << %Q(</td></tr></table>\n)
|
323
|
+
@html << %Q(</td></tr></table>\n)
|
258
324
|
end
|
259
|
-
opt.delete(:attributes)
|
260
|
-
file.gets
|
325
|
+
@opt.delete(:attributes)
|
326
|
+
@line = @file.gets
|
327
|
+
true
|
261
328
|
end
|
262
329
|
|
263
330
|
# Image
|
264
331
|
IMAGES = /^!\[([^\[\]]+)\]\(([^\(\)]+)\)$/
|
265
|
-
|
332
|
+
PARSERS << :images
|
333
|
+
def images
|
334
|
+
md = IMAGES.match(@line) or return false
|
266
335
|
alt,src=md[1],md[2]
|
267
336
|
style = ' '
|
268
337
|
case alt
|
@@ -273,21 +342,24 @@ module Markdown
|
|
273
342
|
when /^ /
|
274
343
|
style = %Q( style="float:right;" )
|
275
344
|
end
|
276
|
-
html << %Q(<img src="#{src}"#{style}alt="#{alt.strip}"#{opt[:attributes]}>\n)
|
277
|
-
opt.delete(:attributes)
|
278
|
-
file.gets
|
345
|
+
@html << %Q(<img src="#{src}"#{style}alt="#{alt.strip}"#{@opt[:attributes]}>\n)
|
346
|
+
@opt.delete(:attributes)
|
347
|
+
@line = @file.gets
|
348
|
+
true
|
279
349
|
end
|
280
350
|
|
281
351
|
# Forms
|
282
352
|
FORMS = /^!( (\w+:)?\[\*?\w+(="[^"]*")?\])+/
|
283
|
-
|
353
|
+
PARSERS << :forms
|
354
|
+
def forms
|
355
|
+
md = FORMS.match(@line) or return false
|
284
356
|
form = []
|
285
|
-
|
286
|
-
action = (_=/\(([^\(\)]*)\)$/.match(line))? _[1] : nil
|
357
|
+
n,fields,submit,method = 0,0,nil,nil
|
358
|
+
action = (_=/\(([^\(\)]*)\)$/.match(@line))? _[1] : nil
|
287
359
|
while md
|
288
|
-
|
289
|
-
form << ' <br>' if
|
290
|
-
line.scan(/(\w+:)?\[(\*)?(\w+)(="[^"]*")?\]/).each do |field, pwd, name, value|
|
360
|
+
n += 1
|
361
|
+
form << ' <br>' if n > 1
|
362
|
+
@line.scan(/(\w+:)?\[(\*)?(\w+)(="[^"]*")?\]/).each do |field, pwd, name, value|
|
291
363
|
method ||= ' method="post"' if pwd
|
292
364
|
field &&= field[0...-1]
|
293
365
|
value &&= value[2...-1]
|
@@ -305,51 +377,59 @@ module Markdown
|
|
305
377
|
form << %Q{ <input type="hidden" name="#{name}" value="#{value}">}
|
306
378
|
end
|
307
379
|
end
|
308
|
-
md = (line
|
380
|
+
md = (@line=@file.gets)&.match FORMS
|
309
381
|
end
|
310
382
|
if submit or not fields==1
|
311
383
|
submit ||= 'Submit'
|
312
|
-
form << ' <br>' if
|
384
|
+
form << ' <br>' if n > 1
|
313
385
|
form << %Q( <input type="submit" value="#{submit}">)
|
314
386
|
end
|
315
|
-
form.unshift %Q(<form action="#{action}"#{method}#{opt[:attributes]}>)
|
387
|
+
form.unshift %Q(<form action="#{action}"#{method}#{@opt[:attributes]}>)
|
316
388
|
form << %Q(</form>)
|
317
|
-
html << form.join("\n")
|
318
|
-
html << "\n"
|
319
|
-
opt.delete(:attributes)
|
320
|
-
|
389
|
+
@html << form.join("\n")
|
390
|
+
@html << "\n"
|
391
|
+
@opt.delete(:attributes)
|
392
|
+
true
|
321
393
|
end
|
322
394
|
|
323
395
|
# Embed text
|
324
396
|
EMBED_TEXTS = /^!> (#{PAGE_KEY}\.txt)$/
|
325
|
-
|
397
|
+
PARSERS << :embed_texts
|
398
|
+
def embed_texts
|
399
|
+
md = EMBED_TEXTS.match(@line) or return false
|
326
400
|
if File.exist?(filename=File.join(ROOT, md[1]))
|
327
|
-
html << "<pre>\n"
|
328
|
-
html << File.read(filename)
|
329
|
-
html << "</pre>\n"
|
401
|
+
@html << "<pre>\n"
|
402
|
+
@html << File.read(filename)
|
403
|
+
@html << "</pre>\n"
|
330
404
|
else
|
331
|
-
html << line
|
405
|
+
@html << @line
|
332
406
|
end
|
333
|
-
file.gets
|
407
|
+
@line = @file.gets
|
408
|
+
true
|
334
409
|
end
|
335
410
|
|
336
411
|
# Footnotes
|
337
412
|
FOOTNOTES = /^\[\^\d+\]:/
|
338
|
-
|
339
|
-
|
413
|
+
PARSERS << :footnotes
|
414
|
+
def footnotes
|
415
|
+
md = FOOTNOTES.match(@line) or return false
|
416
|
+
@html << "<small>\n"
|
340
417
|
while md
|
341
|
-
html << INLINE[line.chomp]+"<br>\n"
|
342
|
-
md = (line
|
418
|
+
@html << INLINE[@line.chomp]+"<br>\n"
|
419
|
+
md = (@line=@file.gets)&.match FOOTNOTES
|
343
420
|
end
|
344
|
-
html << "</small>\n"
|
345
|
-
|
421
|
+
@html << "</small>\n"
|
422
|
+
true
|
346
423
|
end
|
347
424
|
|
348
425
|
# Attributes
|
349
426
|
ATTRIBUTES = /^\{:( .*)\}/
|
350
|
-
|
351
|
-
|
352
|
-
md.
|
427
|
+
PARSERS << :attributes
|
428
|
+
def attributes
|
429
|
+
md = ATTRIBUTES.match(@line) or return false
|
430
|
+
@opt[:attributes] = md[1]
|
431
|
+
@line = md.post_match
|
432
|
+
true
|
353
433
|
end
|
354
434
|
end
|
355
435
|
end
|
data/lib/markita/plug/about.rb
CHANGED
@@ -0,0 +1,30 @@
|
|
1
|
+
module Markita
|
2
|
+
class Preprocess
|
3
|
+
def initialize(file)
|
4
|
+
@file = (file.is_a? String)? StringIO.new(file) : file
|
5
|
+
@regx = @template = nil
|
6
|
+
end
|
7
|
+
|
8
|
+
def gets
|
9
|
+
if line = @file.gets
|
10
|
+
case line
|
11
|
+
when @regx
|
12
|
+
line = @template if @template
|
13
|
+
$~.named_captures.each do |name, value|
|
14
|
+
line = line.gsub("&#{name.downcase};", value)
|
15
|
+
line = line.gsub("&#{name.upcase};", CGI.escape(value))
|
16
|
+
end
|
17
|
+
when %r(^! regx = /(.*)/$)
|
18
|
+
@regx = Regexp.new $1
|
19
|
+
line = gets
|
20
|
+
when %r(^! template = "(.*)"$)
|
21
|
+
@template = $1+"\n"
|
22
|
+
line = gets
|
23
|
+
else
|
24
|
+
@regx &&= (@template=nil)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
line
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
data/lib/markita.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
module Markita
|
2
|
-
VERSION = '
|
2
|
+
VERSION = '3.0.210907'
|
3
3
|
|
4
4
|
def self.run!
|
5
5
|
# Standard libraries
|
@@ -11,6 +11,8 @@ module Markita
|
|
11
11
|
require 'thin'
|
12
12
|
# Local
|
13
13
|
require_relative 'markita/config.rb'
|
14
|
+
require_relative 'markita/html.rb'
|
15
|
+
require_relative 'markita/preprocess.rb'
|
14
16
|
require_relative 'markita/markdown.rb'
|
15
17
|
require_relative 'markita/base.rb'
|
16
18
|
# Plugs
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: markita
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 3.0.210907
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- CarlosJHR64
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-09-
|
11
|
+
date: 2021-09-07 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: help_parser
|
@@ -111,12 +111,14 @@ files:
|
|
111
111
|
- lib/markita.rb
|
112
112
|
- lib/markita/base.rb
|
113
113
|
- lib/markita/config.rb
|
114
|
+
- lib/markita/html.rb
|
114
115
|
- lib/markita/markdown.rb
|
115
116
|
- lib/markita/plug/about.rb
|
116
117
|
- lib/markita/plug/favicon.rb
|
117
118
|
- lib/markita/plug/highlight.rb
|
118
119
|
- lib/markita/plug/login.rb
|
119
120
|
- lib/markita/plug/plugs.rb
|
121
|
+
- lib/markita/preprocess.rb
|
120
122
|
homepage: https://github.com/carlosjhr64/markita
|
121
123
|
licenses:
|
122
124
|
- MIT
|