markita 4.1.230116 → 5.0.241001

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.
@@ -5,8 +5,8 @@ class Markdown
5
5
 
6
6
  def initialize(title)
7
7
  @title = title
8
- @line=@html=@file=@opt=nil
9
- @metadata = {}
8
+ @line=@html=@file=nil
9
+ @metadata,@attributes = {},[]
10
10
  end
11
11
 
12
12
  def start
@@ -15,31 +15,39 @@ class Markdown
15
15
  end
16
16
 
17
17
  def finish
18
- if title = @metadata['Title']
19
- @html << %Q(<script> document.title = "#{title}" </script>\n)
18
+ if (title=@metadata['Title'])
19
+ @html << %(<script> document.title = "#{title}" </script>\n)
20
20
  end
21
21
  @html << HTML.footer
22
22
  @line = nil
23
23
  end
24
24
 
25
- def default
26
- @html << @line
27
- @line = @file.gets
28
- end
29
-
30
25
  def init(fh)
31
- @file,@html,@opt = Preprocess.new(fh),'',{}
26
+ @file,@html = Preprocess.new(fh),''
32
27
  end
33
28
 
34
29
  def parse(fh)
35
30
  init(fh)
36
31
  start
37
- while @line
38
- PARSERS.detect{method(_1).call} or default
39
- end
32
+ PARSERS.detect{method(_1).call} or default while @line
40
33
  finish
41
34
  end
42
35
 
36
+ def default
37
+ # Defaults to paragraph
38
+ # Let html take the original @html object and set @html to ''
39
+ html,@html = @html,''
40
+ html << "<p#{@attributes.shift}>\n"
41
+ loop do
42
+ html << inline(@line)
43
+ break if (@line=@file.gets).nil? || PARSERS.detect{method(_1).call}
44
+ end
45
+ html << "</p>\n"
46
+ html << @html
47
+ # Give back the original object to @html
48
+ @html = html
49
+ end
50
+
43
51
  def markdown(string)
44
52
  parse StringIO.new string
45
53
  @html
@@ -51,44 +59,52 @@ class Markdown
51
59
  end
52
60
 
53
61
  Ux = /_([^_]+)_/
54
- U = lambda {|m| "<u>#{m[1]}</u>"}
62
+ U = ->(m){"<u>#{m[1]}</u>"}
55
63
 
56
64
  Sx = /~([^~]+)~/
57
- S = lambda {|m| "<s>#{m[1]}</s>"}
65
+ S = ->(m){"<s>#{m[1]}</s>"}
58
66
 
59
67
  Ix = /"([^"]+)"/
60
- I = lambda {|m| "<i>#{m[1]}</i>"}
68
+ I = ->(m){"<i>#{m[1]}</i>"}
61
69
 
62
- Bx = /\*([^\*]+)\*/
63
- B = lambda {|m| "<b>#{m[1]}</b>"}
70
+ Bx = /\*([^*]+)\*/
71
+ B = ->(m){"<b>#{m[1]}</b>"}
64
72
 
65
73
  CODEx = /`([^`]+)`/
66
- CODE = lambda {|m| "<code>#{m[1].gsub('<','&lt;')}</code>"}
74
+ CODE = ->(m){"<code>#{m[1].gsub('<','&lt;')}</code>"}
67
75
 
68
76
  Ax = /\[([^\[\]]+)\]\(([^()]+)\)/
69
77
  def anchor(m)
70
78
  href = ((_=m[2]).match?(/^\d+$/) and @metadata[_] or _)
71
79
  text = Markdown.tag(m[1], EMOJIx, EMOJI)
72
- %Q(<a href="#{href}">#{text}</a>)
80
+ %(<a href="#{href}">#{text}</a>)
73
81
  end
74
82
 
75
- URLx = %r((https?://[\w\.\-\/\&\+\?\%]+))
76
- URL = lambda {|m| %Q(<a href="#{m[1]}">#{m[1]}</a>)}
83
+ URLx = %r{(https?://[\w./&+?%-]+)}
84
+ URL = ->(m){%(<a href="#{m[1]}">#{m[1]}</a>)}
77
85
 
78
86
  EMOJIx = /:(\w+):/
79
- EMOJI = lambda {|m| (_=EMOJIS[m[1]])? "&\#x#{_};" : m[0]}
87
+ EMOJI = ->(m){(_=EMOJIS[m[1]])? "&#x#{_};" : m[0]}
80
88
 
81
89
  FOOTNOTEx = /\[\^(\d+)\](:)?/
82
90
  FOOTNOTE = lambda do |m|
83
91
  if m[2]
84
- %Q(<a id="fn:#{m[1]}" href="\#fnref:#{m[1]}">#{m[1]}:</a>)
92
+ %(<a id="fn:#{m[1]}" href="#fnref:#{m[1]}">#{m[1]}:</a>)
85
93
  else
86
- %Q(<a id="fnref:#{m[1]}" href="\#fn:#{m[1]}"><sup>#{m[1]}</sup></a>)
94
+ %(<a id="fnref:#{m[1]}" href="#fn:#{m[1]}"><sup>#{m[1]}</sup></a>)
87
95
  end
88
96
  end
89
97
 
90
- def Markdown.tag(entry, regx, m2string, &block)
91
- if m = regx.match(entry)
98
+ SUPERSCRIPTx = /\\\^\(([^()]+)\)/
99
+ SUPERSCRIPT = ->(m){"<sup>#{m[1]}</sup>"}
100
+ SUBSCRIPTx = /\\\(([^()]+)\)/
101
+ SUBSCRIPT = ->(m){"<sub>#{m[1]}</sub>"}
102
+
103
+ ENTITYx = /\\([<>*"~`_&;:\\])/
104
+ ENTITY = ->(m){"&##{m[1].ord};"}
105
+
106
+ def self.tag(entry, regx, m2string, &block)
107
+ if (m=regx.match entry)
92
108
  string = ''
93
109
  while m
94
110
  pre_match = (block ? block.call(m.pre_match) : m.pre_match)
@@ -99,10 +115,11 @@ class Markdown
99
115
  string << (block ? block.call(post_match) : post_match)
100
116
  return string
101
117
  end
102
- return (block ? block.call(entry) : entry)
118
+ block ? block.call(entry) : entry
103
119
  end
104
120
 
105
121
  def inline(entry)
122
+ entry = Markdown.tag(entry, ENTITYx, ENTITY)
106
123
  string = Markdown.tag(entry, CODEx, CODE) do |entry|
107
124
  Markdown.tag(entry, Ax, method(:anchor)) do |entry|
108
125
  Markdown.tag(entry, URLx, URL) do |entry|
@@ -112,10 +129,12 @@ class Markdown
112
129
  entry = Markdown.tag(entry, Sx, S)
113
130
  entry = Markdown.tag(entry, Ux, U)
114
131
  entry = Markdown.tag(entry, FOOTNOTEx, FOOTNOTE)
132
+ entry = Markdown.tag(entry, SUPERSCRIPTx, SUPERSCRIPT)
133
+ Markdown.tag(entry, SUBSCRIPTx, SUBSCRIPT)
115
134
  end
116
135
  end
117
136
  end
118
- string.sub(/ $/,'<br>')
137
+ string.sub(/ ?[ \\]$/,'<br>')
119
138
  end
120
139
 
121
140
  # Empty
@@ -127,82 +146,33 @@ class Markdown
127
146
  true
128
147
  end
129
148
 
130
- # Ordered list
131
- ORDERED = /^( {0,3})\d+\. (\S.*)$/
132
- PARSERS << :ordered
133
- def ordered(md=nil)
134
- md ||= ORDERED.match(@line) or return false
135
- level = md[1].length
136
- @html << "<ol#{@opt[:attributes]}>\n"
137
- @opt.delete(:attributes)
138
- while md and level==md[1].length
139
- @html << " <li>#{inline(md[2])}</li>\n"
140
- if md = (@line=@file.gets)&.match(ORDERED)
141
- if level < md[1].length
142
- ordered(md)
143
- md = @line&.match(ORDERED)
144
- end
145
- end
146
- end
147
- @html << "</ol>\n"
148
- true
149
- end
150
-
151
- # Paragraph
152
- PARAGRAPHS = /^[\[\(*`'"~_]?:?\w/
153
- PARSERS << :paragraphs
154
- def paragraphs
155
- md = PARAGRAPHS.match(@line) or return false
156
- @html << "<p#{@opt[:attributes]}>\n"
157
- @opt.delete(:attributes)
158
- while md
159
- @html << inline(@line)
160
- while (@line=@file.gets)&.start_with?('<')
161
- @html << @line # Exceptional HTML injection into the paragraph
162
- end
163
- md = @line&.match PARAGRAPHS
164
- end
165
- @html << "</p>\n"
166
- true
167
- end
168
-
169
- # Unordered list
170
- UNORDERED = /^( {0,3})[*] (\S.*)$/
171
- PARSERS << :unordered
172
- def unordered(md=nil)
173
- md ||= UNORDERED.match(@line) or return false
174
- level = md[1].length
175
- @html << "<ul#{@opt[:attributes]}>\n"
176
- @opt.delete(:attributes)
177
- while md and level==md[1].length
178
- @html << " <li>#{inline(md[2])}</li>\n"
179
- if md = (@line=@file.gets)&.match(UNORDERED)
180
- if level < md[1].length
181
- unordered(md)
182
- md = @line&.match(UNORDERED)
183
- end
149
+ # List
150
+ LIST = /^(?<spaces> {0,3})(?<bullet>[*]|(\d+\.)|(- \[( |x)\])) (?<text>\S.*)$/
151
+ PARSERS << :list
152
+ def list(md=nil)
153
+ md ||= LIST.match(@line) or return false
154
+ level = md[:spaces].length
155
+ list = md[:bullet][0]=~/\d/ ? 'ol' : 'ul'
156
+ @html << "<#{list}#{@attributes.shift}>\n"
157
+ loop do
158
+ style = case md[:bullet][3]
159
+ when ' '
160
+ %q( style="list-style-type: '&#9744; '")
161
+ when 'x'
162
+ %q( style="list-style-type: '&#9745; '")
163
+ else
164
+ ''
165
+ end
166
+ @html << " <li#{style}>#{inline(md[:text])}</li>\n"
167
+ if (md=(@line=@file.gets)&.match LIST) && level<md[:spaces].length
168
+ list(md)
169
+ md = @line&.match(LIST)
184
170
  end
171
+ break unless md &&
172
+ (level == md[:spaces].length) &&
173
+ (list == (md[:bullet][0]=~/\d/ ? 'ol' : 'ul'))
185
174
  end
186
- @html << "</ul>\n"
187
- true
188
- end
189
-
190
- # Ballot box
191
- BALLOTS = /^- \[(x| )\] (.*)$/
192
- PARSERS << :ballots
193
- def ballots
194
- md = BALLOTS.match(@line) or return false
195
- @html << "<ul#{@opt[:attributes]}>\n"
196
- @opt.delete(:attributes)
197
- while md
198
- x,t = md[1],md[2]
199
- li = (x=='x')?
200
- %q{<li style="list-style-type: '&#9745; '">} :
201
- %q{<li style="list-style-type: '&#9744; '">}
202
- @html << " #{li}#{inline(t)}</li>\n"
203
- md = (@line=@file.gets)&.match BALLOTS
204
- end
205
- @html << "</ul>\n"
175
+ @html << "</#{list}>\n"
206
176
  true
207
177
  end
208
178
 
@@ -211,8 +181,7 @@ class Markdown
211
181
  PARSERS << :definitions
212
182
  def definitions
213
183
  md = DEFINITIONS.match(@line) or return false
214
- @html << "<dl#{@opt[:attributes]}>\n"
215
- @opt.delete(:attributes)
184
+ @html << "<dl#{@attributes.shift}>\n"
216
185
  while md
217
186
  case md[1]
218
187
  when /(.*): (.*)$/
@@ -230,16 +199,15 @@ class Markdown
230
199
  end
231
200
 
232
201
  # Headers
233
- HEADERS = /^([#]{1,6}) (.*)$/
202
+ HEADERS = /^(\#{1,6}) (.*)$/
234
203
  PARSERS << :headers
235
204
  def headers
236
205
  md = HEADERS.match(@line) or return false
237
206
  i,header = md[1].length,md[2]
238
- id = header.gsub(/\([^\(\)]*\)/,'').scan(/\w+/).join('+')
239
- @html << %Q(<a id="#{id}">\n)
240
- @html << " <h#{i}#{@opt[:attributes]}>#{inline(header)}</h#{i}>\n"
207
+ id = header.gsub(/\([^()]*\)/,'').scan(/\w+/).join('+')
208
+ @html << %(<a id="#{id}">\n)
209
+ @html << " <h#{i}#{@attributes.shift}>#{inline(header)}</h#{i}>\n"
241
210
  @html << "</a>\n"
242
- @opt.delete(:attributes)
243
211
  @line = @file.gets
244
212
  true
245
213
  end
@@ -250,62 +218,40 @@ class Markdown
250
218
  def blockqs(md=nil)
251
219
  md ||= BLOCKQS.match(@line) or return false
252
220
  level = md[1].length
253
- @html << "<blockquote#{@opt[:attributes]}>\n"
254
- @opt.delete(:attributes)
255
- while md and level==md[1].length
221
+ @html << "<blockquote#{@attributes.shift}>\n"
222
+ while md && level==md[1].length
256
223
  @html << inline(md[2])
257
224
  @html << "\n"
258
- if md = (@line=@file.gets)&.match(BLOCKQS)
259
- if level < md[1].length
260
- blockqs(md)
261
- md = @line&.match(BLOCKQS)
262
- end
263
- end
225
+ next unless (md=(@line=@file.gets)&.match BLOCKQS) && level<md[1].length
226
+ blockqs(md)
227
+ md = @line&.match(BLOCKQS)
264
228
  end
265
229
  @html << "</blockquote>\n"
266
230
  true
267
231
  end
268
232
 
269
233
  # Code
270
- CODES = /^[`~]{3}\s*(\w+)?$/
234
+ CODES = /^[`]{3}\s*(\w+)?$/
271
235
  PARSERS << :codes
272
236
  def codes
273
237
  md = CODES.match(@line) or return false
274
238
  lang = Rouge::Lexer.find md[1]
275
239
  klass = lang ? ' class="highlight"' : nil
276
- @html << "<pre#{klass}#{@opt[:attributes]}><code>\n"
277
- @opt.delete(:attributes)
240
+ @html << "<pre#{klass}#{@attributes.shift}><code>\n"
278
241
  code = ''
279
- while @line=@file.gets and not CODES.match?(@line)
280
- code << @line
281
- end
242
+ code << @line while (@line=@file.gets) && !CODES.match?(@line)
282
243
  @html << (lang ? ROUGE.format(lang.new.lex(code)) : code)
283
244
  @html << "</code></pre>\n"
284
245
  @line = @file.gets if @line # then it's code close and thus need next @line.
285
246
  true
286
247
  end
287
248
 
288
- # Script
289
- SCRIPT = /^<script/
290
- PARSERS << :script
291
- def script
292
- md = SCRIPT.match(@line) or return false
293
- @html << @line
294
- while @line=@file.gets
295
- @html << @line
296
- break if %r(^</script>).match?(@line)
297
- end
298
- @line = @file.gets if @line
299
- true
300
- end
301
-
302
249
  # Preform
303
250
  PREFORMS = /^ {4}(.*)$/
304
251
  PARSERS << :preforms
305
252
  def preforms
306
253
  md = PREFORMS.match(@line) or return false
307
- @html << "<pre#{@opt[:attributes]}>\n"
308
- @opt.delete(:attributes)
254
+ @html << "<pre#{@attributes.shift}>\n"
309
255
  while md
310
256
  @html << md[1]
311
257
  @html << "\n"
@@ -337,8 +283,7 @@ class Markdown
337
283
  @line = @file.gets if @line&.match? HRS
338
284
  else
339
285
  # Display HR
340
- @html << "<hr#{@opt[:attributes]}>\n"
341
- @opt.delete(:attributes)
286
+ @html << "<hr#{@attributes.shift}>\n"
342
287
  end
343
288
  true
344
289
  end
@@ -348,9 +293,8 @@ class Markdown
348
293
  PARSERS << :tables
349
294
  def tables
350
295
  TABLES.match? @line or return false
351
- @html << "<table#{@opt[:attributes]}>\n"
352
- @opt.delete(:attributes)
353
- @html << '<thead><tr><th>'
296
+ @html << "<table#{@attributes.shift}>\n"
297
+ @html << "<thead#{@attributes.shift}><tr><th>"
354
298
  @html << @line[1...-1].split('|').map{inline(_1.strip)}.join('</th><th>')
355
299
  @html << "</th></tr></thead>\n"
356
300
  align = []
@@ -384,21 +328,20 @@ class Markdown
384
328
  SPLITS.match? @line or return false
385
329
  case @line.chomp
386
330
  when '|:'
387
- @html << %Q(<table><tr><td#{@opt[:attributes]}>\n)
331
+ @html << %(<table><tr><td#{@attributes.shift}>\n)
388
332
  when '|'
389
- @html << %Q(</td><td#{@opt[:attributes]}>\n)
333
+ @html << %(</td><td#{@attributes.shift}>\n)
390
334
  when ':|:'
391
- @html << %Q(</td></tr><tr><td#{@opt[:attributes]}>\n)
335
+ @html << %(</td></tr><tr><td#{@attributes.shift}>\n)
392
336
  when ':|'
393
- @html << %Q(</td></tr></table>\n)
337
+ @html << %(</td></tr></table>\n)
394
338
  end
395
- @opt.delete(:attributes)
396
339
  @line = @file.gets
397
340
  true
398
341
  end
399
342
 
400
343
  # Image
401
- IMAGES = /^!\[([^\[\]]+)\]\(([^\(\)]+)\)$/
344
+ IMAGES = /^!\[([^\[\]]+)\]\(([^()]+)\)$/
402
345
  PARSERS << :images
403
346
  def images
404
347
  md = IMAGES.match(@line) or return false
@@ -406,75 +349,24 @@ class Markdown
406
349
  style = ' '
407
350
  case alt
408
351
  when /^:.*:$/
409
- style = %Q( style="display: block; margin-left: auto; margin-right: auto;" )
352
+ style =
353
+ %( style="display: block; margin-left: auto; margin-right: auto;" )
410
354
  when /:$/
411
- style = %Q( style="float:left;" )
355
+ style = %( style="float:left;" )
412
356
  when /^:/
413
- style = %Q( style="float:right;" )
357
+ style = %( style="float:right;" )
414
358
  end
415
359
  if /(\d+)x(\d+)/.match alt
416
- style << %Q(width="#{$1}" height="#{$2}" )
360
+ style << %(width="#{$1}" height="#{$2}" )
417
361
  end
418
- @html << %Q(<a href="#{href}">\n) if href
419
- @html << %Q(<img src="#{src}"#{style}alt="#{alt.strip}"#{@opt[:attributes]}>\n)
420
- @html << %Q(</a>\n) if href
421
- @opt.delete(:attributes)
362
+ @html << %(<a href="#{href}">\n) if href
363
+ @html <<
364
+ %(<img src="#{src}"#{style}alt="#{alt.strip}"#{@attributes.shift}>\n)
365
+ @html << %(</a>\n) if href
422
366
  @line = @file.gets
423
367
  true
424
368
  end
425
369
 
426
- # Forms
427
- FIELD = '(\w+:)?\[(\*)?(\w+)(=("[^"]+")(,"[^"]+")*)?\]'
428
- FIELDS = Regexp.new FIELD
429
- FORMS = Regexp.new "^!( #{FIELD})+"
430
- PARSERS << :forms
431
- def forms
432
- md = FORMS.match(@line) or return false
433
- fields,nl,submit = 0,false,nil
434
- action = (_=/\(([^\(\)]*)\)!?$/.match(@line))? %Q( action="#{_[1]}") : nil
435
- method = @line.match?(/!$/) ? ' method="post"' : nil
436
- @html << %Q(<form#{action}#{method}#{@opt[:attributes]}>\n)
437
- @opt.delete(:attributes)
438
- while md
439
- @html << " <br>\n" if nl
440
- @line.scan(FIELDS).each do |field, pwd, name, value|
441
- field &&= field[0...-1]
442
- value &&= value[2...-1]
443
- if field
444
- type = (pwd)? 'password' : 'text'
445
- if value
446
- if (values = value.split('","')).length > 1
447
- @html << %Q(#{field}:<select name="#{name}">\n)
448
- values.each do |value|
449
- fields += 1
450
- @html << %Q( <option value="#{value}">#{value}</option>\n)
451
- end
452
- @html << "</select>\n"
453
- else
454
- fields += 1
455
- @html << %Q{ #{field}:<input type="#{type}" name="#{name}" value="#{value}">\n}
456
- end
457
- else
458
- fields += 1
459
- @html << %Q{ #{field}:<input type="#{type}" name="#{name}">\n}
460
- end
461
- elsif name=='submit'
462
- submit = value
463
- else
464
- @html << %Q{ <input type="hidden" name="#{name}" value="#{value}">\n}
465
- end
466
- end
467
- md=(@line=@file.gets)&.match(FORMS) and nl=true
468
- end
469
- if submit or not fields==1
470
- submit ||= 'Submit'
471
- @html << " <br>\n" if nl
472
- @html << %Q( <input type="submit" value="#{submit}">\n)
473
- end
474
- @html << %Q(</form>\n)
475
- true
476
- end
477
-
478
370
  # Embed text
479
371
  EMBED_TEXTS = /^!> (#{PAGE_KEY}\.\w+)$/
480
372
  PARSERS << :embed_texts
@@ -485,8 +377,7 @@ class Markdown
485
377
  unless extension=='html'
486
378
  lang = Rouge::Lexer.find(extension) unless extension=='txt'
487
379
  klass = lang ? ' class="highlight"' : nil
488
- @html << "<pre#{klass}#{@opt[:attributes]}>"
489
- @opt.delete(:attributes)
380
+ @html << "<pre#{klass}#{@attributes.shift}>"
490
381
  @html << '<code>' if lang
491
382
  @html << "\n"
492
383
  end
@@ -519,13 +410,89 @@ class Markdown
519
410
  end
520
411
 
521
412
  # Attributes
522
- ATTRIBUTES = /^\{:( .*)\}/
413
+ ATTRIBUTES = /^\{:( [^\{\}]+)\}/
523
414
  PARSERS << :attributes
524
415
  def attributes
525
416
  md = ATTRIBUTES.match(@line) or return false
526
- @opt[:attributes] = md[1]
417
+ @attributes.push md[1]
527
418
  @line = md.post_match
528
419
  true
529
420
  end
421
+
422
+ # Script
423
+ SCRIPT = /^<script/
424
+ PARSERS << :script
425
+ def script
426
+ SCRIPT.match(@line) or return false
427
+ @html << @line
428
+ while (@line=@file.gets)
429
+ @html << @line
430
+ break if %r{^</script>}.match?(@line)
431
+ end
432
+ @line = @file.gets if @line
433
+ true
434
+ end
435
+
436
+ # Html
437
+ HTML_MARKUP = /^ {0,3}<.*>$/
438
+ PARSERS << :html_markup
439
+ def html_markup
440
+ HTML_MARKUP.match(@line) or return false
441
+ @html << @line
442
+ @line = @file.gets
443
+ true
444
+ end
445
+
446
+ # Forms
447
+ FIELD = '(\w+:)?\[(\*)?(\w+)(=("[^"]+")(,"[^"]+")*)?\]'
448
+ FIELDS = Regexp.new FIELD
449
+ FORMS = Regexp.new "^!( #{FIELD})+"
450
+ PARSERS << :forms
451
+ def forms
452
+ md = FORMS.match(@line) or return false
453
+ fields,nl,submit = 0,false,nil
454
+ action = (_=/\(([^()]*)\)!?$/.match(@line))? %( action="#{_[1]}") : nil
455
+ method = @line.match?(/!$/) ? ' method="post"' : nil
456
+ @html << %(<form#{action}#{method}#{@attributes.shift}>\n)
457
+ while md
458
+ @html << " <br>\n" if nl
459
+ @line.scan(FIELDS).each do |field, pwd, name, value|
460
+ field &&= field[0...-1]
461
+ value &&= value[2...-1]
462
+ if field
463
+ type = pwd ? 'password' : 'text'
464
+ if value
465
+ if (values = value.split('","')).length > 1
466
+ @html << %(#{field}:<select name="#{name}">\n)
467
+ values.each do |value|
468
+ fields += 1
469
+ @html << %( <option value="#{value}">#{value}</option>\n)
470
+ end
471
+ @html << "</select>\n"
472
+ else
473
+ fields += 1
474
+ @html << %( #{field}:<input type="#{type}" name="#{name}")
475
+ @html << %( value="#{value}">\n)
476
+ end
477
+ else
478
+ fields += 1
479
+ @html << %( #{field}:<input type="#{type}" name="#{name}">\n)
480
+ end
481
+ elsif name=='submit'
482
+ submit = value
483
+ else
484
+ @html << %( <input type="hidden" name="#{name}" value="#{value}">\n)
485
+ end
486
+ end
487
+ md=(@line=@file.gets)&.match(FORMS) and nl=true
488
+ end
489
+ if submit || fields!=1
490
+ submit ||= 'Submit'
491
+ @html << " <br>\n" if nl
492
+ @html << %( <input type="submit" value="#{submit}">\n)
493
+ end
494
+ @html << %(</form>\n)
495
+ true
496
+ end
530
497
  end
531
498
  end
@@ -15,11 +15,11 @@ class Base
15
15
  TEXT
16
16
  Base.routes['GET'].each do |route|
17
17
  path = route[0].to_s
18
- next unless %r{^/\w+\.html$}.match? path
18
+ next unless %r{^/\w+\.html$}.match? path
19
19
  basename = File.basename(path, '.*')
20
20
  text << "* [#{basename}](#{path})\n"
21
21
  end
22
- if defined? Favicon and Favicon::ICO
22
+ if defined? Favicon && Favicon::ICO
23
23
  text << "\n![Favicon](/favicon.ico)\n"
24
24
  end
25
25
  text
@@ -1,6 +1,8 @@
1
1
  module Markita
2
2
  class Base
3
- HEADER_LINKS << %Q( <link rel="icon" type="image/x-icon" href="/favicon.ico">\n)
3
+ HEADER_LINKS <<
4
+ %(\n<link rel="icon" type="image/x-icon" href="/favicon.ico">)
5
+
4
6
  module Favicon
5
7
  ICO = File.read PATH['favicon.ico']
6
8
  end
@@ -1,10 +1,12 @@
1
1
  module Markita
2
2
  class Base
3
- HEADER_LINKS << %Q( <link rel="stylesheet" href="/highlight.css" type="text/css">\n)
3
+ HEADER_LINKS <<
4
+ %(\n<link rel="stylesheet" href="/highlight.css" type="text/css">)
5
+
4
6
  module Highlight
5
- theme = OPTIONS&.theme || 'base16.light'
7
+ theme = OPTIONS.theme || 'base16.light'
6
8
  CSS = Rouge::Theme.find(theme)&.render(scope: '.highlight')
7
- raise "Can't find Rouge Theme "+theme unless CSS
9
+ raise "Can't find Rouge Theme "+theme unless CSS
8
10
  end
9
11
 
10
12
  get '/highlight.css' do
@@ -4,17 +4,17 @@ class Base
4
4
  ID = File.exist?(_=File.join(ROOT, '.valid-id')) ?
5
5
  File.read(_).strip :
6
6
  nil
7
- IPS = (_=OPTIONS&.allowed)? _.split(',') : nil
8
- if IPS and not ID
9
- raise "Allowed ips without site password does not make sense."
7
+ IPS = (_=OPTIONS.allowed)? _.split(',') : []
8
+ if !IPS.empty? && !ID
9
+ raise 'Allowed ips without site password does not make sense.'
10
10
  end
11
11
  FORM = File.read PATH['login_form.html']
12
12
  FAILED = File.read PATH['login_failed.html']
13
13
  end
14
14
 
15
15
  before do
16
- unless Login::ID.nil? or Login::IPS&.include?(request.ip)
17
- if id = params[:id]
16
+ unless Login::ID.nil? || Login::IPS.include?(request.ip)
17
+ if (id=params[:id])
18
18
  session[:id] = Digest::SHA256.hexdigest id
19
19
  end
20
20
  if session[:id] == Login::ID
@@ -1,3 +1,3 @@
1
1
  module Markita
2
- NAVIGATION << %Q(![:Navigation](/favicon.ico /index)\n)
2
+ NAVIGATION << %(![:Navigation](/favicon.ico /index)\n)
3
3
  end