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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b4bf395f9651feb6f5a7a4ede56db6a75fa0ea50383a0bc06a0cc1c8b39d27c8
4
- data.tar.gz: 5b76214448e81a4c24b01f287d3a8e11fcaead0a6c1b0e188e547d1dbb8617a0
3
+ metadata.gz: 8176e09462f3a78f7e10600cef156aff9d32ed892c97366d242bf299e87adf5e
4
+ data.tar.gz: '0864ffe280f23e7d15b196aef1226a14f7b3443c0ebf4a142667187550665ab9'
5
5
  SHA512:
6
- metadata.gz: 23339420ce626aa7f436ca31641deed88144684df32c4b947adf109f687341a1819e48780305683ab82fbfe63bf5170abf2afd1068aeb86d88b014d370e5e18f
7
- data.tar.gz: a7e8d715ff4d818f92afeec4bf64f074b10b8ac496495225ba0d1beb9e014098713c28690ea36ce46454d9a5a21e4f6780745eb34a7ae4b2f5f379f76abd80ee
6
+ metadata.gz: 16135591f2eb1d7446be0337c0ba7b51624834f169f219c1a0a534d88f263dec04da18e8b8e05f5c4d4998b8d9a96aaf437e53d1d0858b36aab19948f10985bc
7
+ data.tar.gz: ecfc73bc0f9e13e216a1b5e9682bbfdc93a9aada53b3aaa49e19c529324b37a9afeb06761349a2ce4dda10c1bfeb4852d4bc705ff137f488451117afb3eb2612
data/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Markita
2
2
 
3
- * [VERSION 2.0.210906](https://github.com/carlosjhr64/markita/releases)
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
- File.open(filepath, 'r'){|f| Base.page key, f}
24
+ Markdown.new(key).filepath filepath
88
25
  end
89
26
 
90
27
  get IMAGE_PATH do |path, *_|
@@ -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
@@ -1,59 +1,99 @@
1
1
  module Markita
2
- module Markdown
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 {|md| "<u>#{md[1]}</u>"}
44
+ U = lambda {|m| "<u>#{m[1]}</u>"}
5
45
 
6
46
  Sx = /~([^~]+)~/
7
- S = lambda {|md| "<s>#{md[1]}</s>"}
47
+ S = lambda {|m| "<s>#{m[1]}</s>"}
8
48
 
9
49
  Ix = /"([^"]+)"/
10
- I = lambda {|md| "<i>#{md[1]}</i>"}
50
+ I = lambda {|m| "<i>#{m[1]}</i>"}
11
51
 
12
52
  Bx = /\*([^\*]+)\*/
13
- B = lambda {|md| "<b>#{md[1]}</b>"}
53
+ B = lambda {|m| "<b>#{m[1]}</b>"}
14
54
 
15
55
  CODEx = /`([^`]+)`/
16
- CODE = lambda {|md| "<code>#{md[1]}</code>"}
56
+ CODE = lambda {|m| "<code>#{m[1]}</code>"}
17
57
 
18
58
  Ax = /\[([^\[\]]+)\]\(([^()]+)\)/
19
- A = lambda {|md| %Q(<a href="#{md[2]}">#{md[1]}</a>)}
59
+ A = lambda {|m| %Q(<a href="#{m[2]}">#{m[1]}</a>)}
20
60
 
21
61
  URLx = %r(\[(https?://[\w\.\-\/\&\+\?\%]+)\])
22
- URL = lambda {|md| %Q(<a href="#{md[1]}">#{md[1]}</a>)}
62
+ URL = lambda {|m| %Q(<a href="#{m[1]}">#{m[1]}</a>)}
23
63
 
24
64
  EMOJIx = /:(\w+):/
25
- EMOJI = lambda {|md| (_=EMOJIS[md[1]])? "&\#x#{_};" : md[0]}
65
+ EMOJI = lambda {|m| (_=EMOJIS[m[1]])? "&\#x#{_};" : m[0]}
26
66
 
27
67
  FOOTNOTEx = /\[\^(\d+)\](:)?/
28
- FOOTNOTE = lambda do |md|
29
- if md[2]
30
- %Q(<a id="fn:#{md[1]}" href="\#fnref:#{md[1]}">#{md[1]}:</a>)
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:#{md[1]}" href="\#fn:#{md[1]}"><sup>#{md[1]}</sup></a>)
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(line, regx, md2string, &block)
37
- if md = regx.match(line)
38
- pre_match = (block ? block.call(md.pre_match) : md.pre_match)
39
- string = pre_match + md2string[md]
40
- post_match = md.post_match
41
- while md = regx.match(post_match)
42
- pre_match = (block ? block.call(md.pre_match) : md.pre_match)
43
- string << pre_match + md2string[md]
44
- post_match = md.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(line) : line)
89
+ return (block ? block.call(entry) : entry)
50
90
  end
51
91
 
52
- INLINE = lambda do |line|
53
- string = Markdown.tag(line, CODEx, CODE) do |line|
54
- Markdown.tag(line, Ax, A) do |line|
55
- Markdown.tag(line, URLx, URL) do |line|
56
- string = Markdown.tag(line, Bx, B)
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
- PARSER[/^$/] = lambda do |_, _, file, _, _|
72
- file.gets
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
- PARSER[ORDERED] = lambda do |line, html, file, opt, md|
78
- html << "<ol#{opt[:attributes]}>\n"
79
- opt.delete(:attributes)
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=file.gets)&.match ORDERED
125
+ @html << " <li>#{INLINE[md[1]]}</li>\n"
126
+ md = (@line=@file.gets)&.match ORDERED
83
127
  end
84
- html << "</ol>\n"
85
- line
128
+ @html << "</ol>\n"
129
+ true
86
130
  end
87
131
 
88
132
  # Paragraph
89
133
  PARAGRAPHS = /^[\[`*"~_]?\w/
90
- PARSER[PARAGRAPHS] = lambda do |line, html, file, opt, md|
91
- html << "<p#{opt[:attributes]}>\n"
92
- opt.delete(:attributes)
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=file.gets)&.match PARAGRAPHS
140
+ @html << INLINE[@line]
141
+ md = (@line=@file.gets)&.match PARAGRAPHS
96
142
  end
97
- html << "</p>\n"
98
- line
143
+ @html << "</p>\n"
144
+ true
99
145
  end
100
146
 
101
147
  # Unordered list
102
148
  UNORDERED = /^[*] (.*)$/
103
- PARSER[UNORDERED] = lambda do |line, html, file, opt, md|
104
- html << "<ul#{opt[:attributes]}>\n"
105
- opt.delete(:attributes)
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=file.gets)&.match UNORDERED
155
+ @html << " <li>#{INLINE[md[1]]}</li>\n"
156
+ md = (@line=@file.gets)&.match UNORDERED
109
157
  end
110
- html << "</ul>\n"
111
- line
158
+ @html << "</ul>\n"
159
+ true
112
160
  end
113
161
 
114
162
  # Ballot box
115
163
  BALLOTS = /^- \[(x| )\] (.*)$/
116
- PARSER[BALLOTS] = lambda do |line, html, file, opt, md|
117
- html << "<ul#{opt[:attributes]}>\n"
118
- opt.delete(:attributes)
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: '&#9745; '">} :
123
173
  %q{<li style="list-style-type: '&#9744; '">}
124
- html << " #{li}#{INLINE[t]}</li>\n"
125
- md = (line=file.gets)&.match BALLOTS
174
+ @html << " #{li}#{INLINE[t]}</li>\n"
175
+ md = (@line=@file.gets)&.match BALLOTS
126
176
  end
127
- html << "</ul>\n"
128
- line
177
+ @html << "</ul>\n"
178
+ true
129
179
  end
130
180
 
131
181
  # Definition list
132
182
  DEFINITIONS = /^: (.*)$/
133
- PARSER[DEFINITIONS] = lambda do |line, html, file, opt, md|
134
- html << "<dl#{opt[:attributes]}>\n"
135
- opt.delete(:attributes)
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
- line = ((item[-1]==':')? "<dt>#{INLINE[item[0..-2]]}</dt>\n" :
190
+ @html << ((item[-1]==':')? "<dt>#{INLINE[item[0..-2]]}</dt>\n" :
139
191
  "<dd>#{INLINE[item]}</dd>\n")
140
- html << line
141
- md = (line=file.gets)&.match DEFINITIONS
192
+ md = (@line=@file.gets)&.match DEFINITIONS
142
193
  end
143
- html << "</dl>\n"
144
- line
194
+ @html << "</dl>\n"
195
+ true
145
196
  end
146
197
 
147
198
  # Headers
148
199
  HEADERS = /^([#]{1,6}) (.*)$/
149
- PARSER[HEADERS] = lambda do |line, html, file, opt, md|
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
- PARSER[BLOCKQS] = lambda do |line, html, file, opt, md|
162
- html << "<blockquote#{opt[:attributes]}>\n"
163
- opt.delete(:attributes)
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=file.gets)&.match BLOCKQS
221
+ @html << INLINE[md[1]]
222
+ @html << "\n"
223
+ md = (@line=@file.gets)&.match BLOCKQS
168
224
  end
169
- html << "</blockquote>\n"
170
- line
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
- PARSER[CODES] = lambda do |line, html, file, opt, md|
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=file.gets and not CODES.match(line)
184
- code << line
240
+ while @line=@file.gets and not CODES.match(@line)
241
+ code << @line
185
242
  end
186
- html << (lang ? HTML.format(lang.new.lex(code)) : code)
187
- html << "</code></pre>\n"
188
- # line is either nil or the code close
189
- line and file.gets
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
- PARSER[PREFORMS] = lambda do |line, html, file, opt, md|
195
- html << "<pre#{opt[:attributes]}>\n"
196
- opt.delete(:attributes)
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=file.gets)&.match PREFORMS
257
+ @html << md[1]
258
+ @html << "\n"
259
+ md = (@line=@file.gets)&.match PREFORMS
201
260
  end
202
- html << "</pre>\n"
203
- line
261
+ @html << "</pre>\n"
262
+ true
204
263
  end
205
264
 
206
265
  # Horizontal rule
207
266
  HRS = /^---+$/
208
- PARSER[HRS] = lambda do |_, html, file, opt, _|
209
- html << "<hr#{opt[:attributes]}>\n"
210
- opt.delete(:attributes)
211
- file.gets
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
- PARSER[TABLES] = lambda do |line, html, file, opt, _|
217
- html << "<table#{opt[:attributes]}>\n"
218
- opt.delete(:attributes)
219
- html << '<thead><tr><th>'
220
- html << line[1...-1].split('|').map{INLINE[_1.strip]}.join('</th><th>')
221
- html << "</th></tr></thead>\n"
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=file.gets)&.match TABLES
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
- line
306
+ @html << "</table>\n"
307
+ true
244
308
  end
245
309
 
246
310
  # Splits
247
311
  SPLITS = /^:?\|:?$/
248
- PARSER[SPLITS] = lambda do |line, html, file, opt, _|
249
- case line.chomp
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
- PARSER[IMAGES] = lambda do |line, html, file, opt, md|
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
- PARSER[FORMS] = lambda do |line, html, file, opt, md|
353
+ PARSERS << :forms
354
+ def forms
355
+ md = FORMS.match(@line) or return false
284
356
  form = []
285
- lines,fields,submit,method = 0,0,nil,nil
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
- lines += 1
289
- form << ' <br>' if lines > 1
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=file.gets)&.match FORMS
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 lines > 1
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
- line
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
- PARSER[EMBED_TEXTS] = lambda do |line, html, file, opt, md|
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
- PARSER[FOOTNOTES] = lambda do |line, html, file, opt, md|
339
- html << "<small>\n"
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=file.gets)&.match FOOTNOTES
418
+ @html << INLINE[@line.chomp]+"<br>\n"
419
+ md = (@line=@file.gets)&.match FOOTNOTES
343
420
  end
344
- html << "</small>\n"
345
- line
421
+ @html << "</small>\n"
422
+ true
346
423
  end
347
424
 
348
425
  # Attributes
349
426
  ATTRIBUTES = /^\{:( .*)\}/
350
- PARSER[ATTRIBUTES] = lambda do |line, html, file, opt, md|
351
- opt[:attributes] = md[1]
352
- md.post_match
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
@@ -27,7 +27,7 @@ class Base
27
27
  end
28
28
 
29
29
  get '/about.html' do
30
- Base.page 'about', About.page
30
+ Markdown.new('About').markdown About.page
31
31
  end
32
32
  end
33
33
  end
@@ -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.0.210906'
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: 2.0.210906
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-06 00:00:00.000000000 Z
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