markita 2.0.210906 → 3.0.210907

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 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