markita 4.1.230116 → 4.1.230214
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 +4 -4
- data/README.md +2 -2
- data/bin/markita +32 -32
- data/lib/markita/base.rb +5 -5
- data/lib/markita/config.rb +4 -4
- data/lib/markita/html.rb +3 -3
- data/lib/markita/markdown.rb +68 -78
- data/lib/markita/plug/about.rb +2 -2
- data/lib/markita/plug/favicon.rb +3 -1
- data/lib/markita/plug/highlight.rb +3 -2
- data/lib/markita/plug/login.rb +4 -4
- data/lib/markita/plug/navigation.rb +1 -1
- data/lib/markita/preprocess.rb +5 -5
- data/lib/markita.rb +13 -13
- metadata +113 -12
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 3f0f724a5032aef309176a00528c84199b06fc0a6f9f8fa9b36b0ad81077adca
|
|
4
|
+
data.tar.gz: 371e1025357b9686e31697f563ba6534e2706df21bb2ce1e0586ea818467f387
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 59e8791389f0bc45488a9e80d6dc8cbd84abe8eb663550e46aff32d1ee8c32f0d0ea60e3dee4be57f589672aa4c23e7e41a305ac491141d2df955cb0aa230e88
|
|
7
|
+
data.tar.gz: 64ab90255ad7ab0ba1dcce4824bd33b5585e4ecf61333ad5bdabf75f9650eb625131fd79efb7b0968e7d99ab6c3c5eeff978e832eb7c2ce4fe95b6bb3c4202a1
|
data/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Markita
|
|
2
2
|
|
|
3
|
-
* [VERSION 4.1.
|
|
3
|
+
* [VERSION 4.1.230214](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
|
|
|
@@ -351,7 +351,7 @@ $ GET https://raw.githubusercontent.com/carlosjhr64/markita/main/plug/todotxt.rb
|
|
|
351
351
|
```
|
|
352
352
|
## LICENSE
|
|
353
353
|
|
|
354
|
-
Copyright 2023 CarlosJHR64
|
|
354
|
+
Copyright (c) 2023 CarlosJHR64
|
|
355
355
|
|
|
356
356
|
Permission is hereby granted, free of charge,
|
|
357
357
|
to any person obtaining a copy of this software and
|
data/bin/markita
CHANGED
|
@@ -2,36 +2,36 @@
|
|
|
2
2
|
require 'help_parser'
|
|
3
3
|
require 'markita'
|
|
4
4
|
|
|
5
|
-
OPTIONS = HelpParser[Markita::VERSION,
|
|
6
|
-
Usage:
|
|
7
|
-
|
|
8
|
-
Options:
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
Exclusive:
|
|
22
|
-
|
|
23
|
-
Types:
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
# NOTE:
|
|
30
|
-
# Assuming site is in ~/vimwiki,
|
|
31
|
-
# when ~/vimwiki/.valid-id is set with a sha256sum of a password,
|
|
32
|
-
# that password will restrict the site.
|
|
33
|
-
# Allowed IPs bypass the need for site password
|
|
34
|
-
# when the site is accessed from those locations.
|
|
5
|
+
OPTIONS = HelpParser[Markita::VERSION, <<~HELP]
|
|
6
|
+
Usage:
|
|
7
|
+
markita [:options+]
|
|
8
|
+
Options:
|
|
9
|
+
--root=DIRECTORY \t ~/vimwiki
|
|
10
|
+
--bind=BIND \t 0.0.0.0
|
|
11
|
+
--port=PORT \t 8080
|
|
12
|
+
--theme=THEME \t base16.light
|
|
13
|
+
--allowed=IPS
|
|
14
|
+
--no_about
|
|
15
|
+
--no_favicon
|
|
16
|
+
--no_highlight
|
|
17
|
+
--no_login
|
|
18
|
+
--no_navigation
|
|
19
|
+
--no_plugs
|
|
20
|
+
--no_readme
|
|
21
|
+
Exclusive:
|
|
22
|
+
no_login allowed
|
|
23
|
+
Types:
|
|
24
|
+
DIRECTORY /^~?[\\/\\w\\.]+$/
|
|
25
|
+
BIND /^[\\w\\.]+$/
|
|
26
|
+
PORT /^\\d+$/
|
|
27
|
+
IPS /^[\\d\\.\\,]+$/
|
|
28
|
+
THEME /^[\\w\\.]+$/
|
|
29
|
+
# NOTE:
|
|
30
|
+
# Assuming site is in ~/vimwiki,
|
|
31
|
+
# when ~/vimwiki/.valid-id is set with a sha256sum of a password,
|
|
32
|
+
# that password will restrict the site.
|
|
33
|
+
# Allowed IPs bypass the need for site password
|
|
34
|
+
# when the site is accessed from those locations.
|
|
35
35
|
HELP
|
|
36
36
|
begin
|
|
37
37
|
Markita.run!
|
|
@@ -41,8 +41,8 @@ rescue LoadError
|
|
|
41
41
|
rescue RuntimeError
|
|
42
42
|
HelpParser::REDTTY["#{$!.class}: #{$!.message}"]
|
|
43
43
|
exit 65
|
|
44
|
-
rescue
|
|
45
|
-
|
|
44
|
+
rescue
|
|
45
|
+
warn $!.backtrace
|
|
46
46
|
HelpParser::REDTTY["#{$!.class}: #{$!.message}"]
|
|
47
47
|
exit 70
|
|
48
48
|
end
|
data/lib/markita/base.rb
CHANGED
|
@@ -4,7 +4,7 @@ class Base < Sinatra::Base
|
|
|
4
4
|
set port: OPTIONS&.port || '8080'
|
|
5
5
|
set sessions: true
|
|
6
6
|
|
|
7
|
-
def
|
|
7
|
+
def self.run!
|
|
8
8
|
puts "#{$0}-#{VERSION}"
|
|
9
9
|
super do |server|
|
|
10
10
|
if ['.cert.crt', '.pkey.pem'].all?{ File.exist? File.join(ROOT, _1)}
|
|
@@ -20,13 +20,13 @@ class Base < Sinatra::Base
|
|
|
20
20
|
|
|
21
21
|
get PAGE_KEY do |key|
|
|
22
22
|
filepath = File.join ROOT, key+'.md'
|
|
23
|
-
raise Sinatra::NotFound
|
|
23
|
+
raise Sinatra::NotFound unless File.exist? filepath
|
|
24
24
|
Markdown.new(key).filepath filepath
|
|
25
25
|
end
|
|
26
26
|
|
|
27
27
|
get SEND_FILE do |path|
|
|
28
|
-
pass unless params.length==1
|
|
29
|
-
filepath
|
|
28
|
+
pass unless params.length==1 &&
|
|
29
|
+
(filepath=File.join ROOT, path) &&
|
|
30
30
|
File.exist?(filepath)
|
|
31
31
|
send_file filepath
|
|
32
32
|
end
|
|
@@ -36,7 +36,7 @@ class Base < Sinatra::Base
|
|
|
36
36
|
if File.exist? filepath
|
|
37
37
|
Markdown.new('index').filepath filepath
|
|
38
38
|
else
|
|
39
|
-
redirect '/about.html'
|
|
39
|
+
redirect '/about.html' unless OPTIONS&.no_about
|
|
40
40
|
raise Sinatra::NotFound
|
|
41
41
|
end
|
|
42
42
|
end
|
data/lib/markita/config.rb
CHANGED
|
@@ -5,8 +5,8 @@ module Markita
|
|
|
5
5
|
NAVIGATION = ''
|
|
6
6
|
|
|
7
7
|
ROOT = File.expand_path OPTIONS&.root || '~/vimwiki'
|
|
8
|
-
raise
|
|
9
|
-
APPDIR = File.dirname
|
|
8
|
+
raise 'Missing site root directory: '+ROOT unless File.directory? ROOT
|
|
9
|
+
APPDIR = File.dirname __dir__, 2
|
|
10
10
|
APPDATA = File.join APPDIR, 'data'
|
|
11
11
|
PATH = lambda do |basename|
|
|
12
12
|
[ROOT, APPDATA].map{ File.join _1, basename}.detect{ File.exist? _1}
|
|
@@ -15,8 +15,8 @@ module Markita
|
|
|
15
15
|
|
|
16
16
|
EMOJIS = Hash[*File.read(PATH['emojis.tsv']).split(/\s+/)]
|
|
17
17
|
|
|
18
|
-
PAGE_KEY = %r{/(\w[\w
|
|
19
|
-
SEND_FILE = %r{/(\w[\w
|
|
18
|
+
PAGE_KEY = %r{/(\w[\w/-]*\w)}
|
|
19
|
+
SEND_FILE = %r{/(\w[\w/-]*\w\.\w+)}
|
|
20
20
|
|
|
21
21
|
START_TIME = Time.now
|
|
22
22
|
end
|
data/lib/markita/html.rb
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
module Markita
|
|
2
2
|
module HTML
|
|
3
|
-
def
|
|
3
|
+
def self.header(key)
|
|
4
4
|
<<~HEADER
|
|
5
5
|
<!DOCTYPE html>
|
|
6
6
|
<html>
|
|
@@ -11,11 +11,11 @@ module HTML
|
|
|
11
11
|
HEADER
|
|
12
12
|
end
|
|
13
13
|
|
|
14
|
-
def
|
|
14
|
+
def self.navigation
|
|
15
15
|
NAVIGATION
|
|
16
16
|
end
|
|
17
17
|
|
|
18
|
-
def
|
|
18
|
+
def self.footer
|
|
19
19
|
<<~FOOTER
|
|
20
20
|
</body>
|
|
21
21
|
</html>
|
data/lib/markita/markdown.rb
CHANGED
|
@@ -15,8 +15,8 @@ class Markdown
|
|
|
15
15
|
end
|
|
16
16
|
|
|
17
17
|
def finish
|
|
18
|
-
if title
|
|
19
|
-
@html << %
|
|
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
|
|
@@ -34,9 +34,7 @@ class Markdown
|
|
|
34
34
|
def parse(fh)
|
|
35
35
|
init(fh)
|
|
36
36
|
start
|
|
37
|
-
while @line
|
|
38
|
-
PARSERS.detect{method(_1).call} or default
|
|
39
|
-
end
|
|
37
|
+
PARSERS.detect{method(_1).call} or default while @line
|
|
40
38
|
finish
|
|
41
39
|
end
|
|
42
40
|
|
|
@@ -51,44 +49,44 @@ class Markdown
|
|
|
51
49
|
end
|
|
52
50
|
|
|
53
51
|
Ux = /_([^_]+)_/
|
|
54
|
-
U =
|
|
52
|
+
U = ->(m){"<u>#{m[1]}</u>"}
|
|
55
53
|
|
|
56
54
|
Sx = /~([^~]+)~/
|
|
57
|
-
S =
|
|
55
|
+
S = ->(m){"<s>#{m[1]}</s>"}
|
|
58
56
|
|
|
59
57
|
Ix = /"([^"]+)"/
|
|
60
|
-
I =
|
|
58
|
+
I = ->(m){"<i>#{m[1]}</i>"}
|
|
61
59
|
|
|
62
|
-
Bx = /\*([
|
|
63
|
-
B =
|
|
60
|
+
Bx = /\*([^*]+)\*/
|
|
61
|
+
B = ->(m){"<b>#{m[1]}</b>"}
|
|
64
62
|
|
|
65
63
|
CODEx = /`([^`]+)`/
|
|
66
|
-
CODE =
|
|
64
|
+
CODE = ->(m){"<code>#{m[1].gsub('<','<')}</code>"}
|
|
67
65
|
|
|
68
66
|
Ax = /\[([^\[\]]+)\]\(([^()]+)\)/
|
|
69
67
|
def anchor(m)
|
|
70
68
|
href = ((_=m[2]).match?(/^\d+$/) and @metadata[_] or _)
|
|
71
69
|
text = Markdown.tag(m[1], EMOJIx, EMOJI)
|
|
72
|
-
%
|
|
70
|
+
%(<a href="#{href}">#{text}</a>)
|
|
73
71
|
end
|
|
74
72
|
|
|
75
|
-
URLx = %r(
|
|
76
|
-
URL =
|
|
73
|
+
URLx = %r{(https?://[\w./&+?%-]+)}
|
|
74
|
+
URL = ->(m){%(<a href="#{m[1]}">#{m[1]}</a>)}
|
|
77
75
|
|
|
78
76
|
EMOJIx = /:(\w+):/
|
|
79
|
-
EMOJI =
|
|
77
|
+
EMOJI = ->(m){(_=EMOJIS[m[1]])? "&#x#{_};" : m[0]}
|
|
80
78
|
|
|
81
79
|
FOOTNOTEx = /\[\^(\d+)\](:)?/
|
|
82
80
|
FOOTNOTE = lambda do |m|
|
|
83
81
|
if m[2]
|
|
84
|
-
%
|
|
82
|
+
%(<a id="fn:#{m[1]}" href="#fnref:#{m[1]}">#{m[1]}:</a>)
|
|
85
83
|
else
|
|
86
|
-
%
|
|
84
|
+
%(<a id="fnref:#{m[1]}" href="#fn:#{m[1]}"><sup>#{m[1]}</sup></a>)
|
|
87
85
|
end
|
|
88
86
|
end
|
|
89
87
|
|
|
90
|
-
def
|
|
91
|
-
if m
|
|
88
|
+
def self.tag(entry, regx, m2string, &block)
|
|
89
|
+
if (m=regx.match entry)
|
|
92
90
|
string = ''
|
|
93
91
|
while m
|
|
94
92
|
pre_match = (block ? block.call(m.pre_match) : m.pre_match)
|
|
@@ -99,7 +97,7 @@ class Markdown
|
|
|
99
97
|
string << (block ? block.call(post_match) : post_match)
|
|
100
98
|
return string
|
|
101
99
|
end
|
|
102
|
-
|
|
100
|
+
block ? block.call(entry) : entry
|
|
103
101
|
end
|
|
104
102
|
|
|
105
103
|
def inline(entry)
|
|
@@ -111,7 +109,7 @@ class Markdown
|
|
|
111
109
|
entry = Markdown.tag(entry, Ix, I)
|
|
112
110
|
entry = Markdown.tag(entry, Sx, S)
|
|
113
111
|
entry = Markdown.tag(entry, Ux, U)
|
|
114
|
-
|
|
112
|
+
Markdown.tag(entry, FOOTNOTEx, FOOTNOTE)
|
|
115
113
|
end
|
|
116
114
|
end
|
|
117
115
|
end
|
|
@@ -135,21 +133,18 @@ class Markdown
|
|
|
135
133
|
level = md[1].length
|
|
136
134
|
@html << "<ol#{@opt[:attributes]}>\n"
|
|
137
135
|
@opt.delete(:attributes)
|
|
138
|
-
while md
|
|
136
|
+
while md && level==md[1].length
|
|
139
137
|
@html << " <li>#{inline(md[2])}</li>\n"
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
md = @line&.match(ORDERED)
|
|
144
|
-
end
|
|
145
|
-
end
|
|
138
|
+
next unless (md=(@line=@file.gets)&.match ORDERED) && level<md[1].length
|
|
139
|
+
ordered(md)
|
|
140
|
+
md = @line&.match(ORDERED)
|
|
146
141
|
end
|
|
147
142
|
@html << "</ol>\n"
|
|
148
143
|
true
|
|
149
144
|
end
|
|
150
145
|
|
|
151
146
|
# Paragraph
|
|
152
|
-
PARAGRAPHS = /^[\[
|
|
147
|
+
PARAGRAPHS = /^[\[(*`'"~_]?:?\w/
|
|
153
148
|
PARSERS << :paragraphs
|
|
154
149
|
def paragraphs
|
|
155
150
|
md = PARAGRAPHS.match(@line) or return false
|
|
@@ -174,14 +169,11 @@ class Markdown
|
|
|
174
169
|
level = md[1].length
|
|
175
170
|
@html << "<ul#{@opt[:attributes]}>\n"
|
|
176
171
|
@opt.delete(:attributes)
|
|
177
|
-
while md
|
|
172
|
+
while md && level==md[1].length
|
|
178
173
|
@html << " <li>#{inline(md[2])}</li>\n"
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
md = @line&.match(UNORDERED)
|
|
183
|
-
end
|
|
184
|
-
end
|
|
174
|
+
next unless (md=(@line=@file.gets)&.match UNORDERED) && level<md[1].length
|
|
175
|
+
unordered(md)
|
|
176
|
+
md = @line&.match(UNORDERED)
|
|
185
177
|
end
|
|
186
178
|
@html << "</ul>\n"
|
|
187
179
|
true
|
|
@@ -196,9 +188,9 @@ class Markdown
|
|
|
196
188
|
@opt.delete(:attributes)
|
|
197
189
|
while md
|
|
198
190
|
x,t = md[1],md[2]
|
|
199
|
-
li =
|
|
200
|
-
%q
|
|
201
|
-
%q
|
|
191
|
+
li = x=='x' ?
|
|
192
|
+
%q(<li style="list-style-type: '☑ '">) :
|
|
193
|
+
%q(<li style="list-style-type: '☐ '">)
|
|
202
194
|
@html << " #{li}#{inline(t)}</li>\n"
|
|
203
195
|
md = (@line=@file.gets)&.match BALLOTS
|
|
204
196
|
end
|
|
@@ -230,13 +222,13 @@ class Markdown
|
|
|
230
222
|
end
|
|
231
223
|
|
|
232
224
|
# Headers
|
|
233
|
-
HEADERS = /^(
|
|
225
|
+
HEADERS = /^(\#{1,6}) (.*)$/
|
|
234
226
|
PARSERS << :headers
|
|
235
227
|
def headers
|
|
236
228
|
md = HEADERS.match(@line) or return false
|
|
237
229
|
i,header = md[1].length,md[2]
|
|
238
|
-
id = header.gsub(/\([
|
|
239
|
-
@html << %
|
|
230
|
+
id = header.gsub(/\([^()]*\)/,'').scan(/\w+/).join('+')
|
|
231
|
+
@html << %(<a id="#{id}">\n)
|
|
240
232
|
@html << " <h#{i}#{@opt[:attributes]}>#{inline(header)}</h#{i}>\n"
|
|
241
233
|
@html << "</a>\n"
|
|
242
234
|
@opt.delete(:attributes)
|
|
@@ -252,15 +244,12 @@ class Markdown
|
|
|
252
244
|
level = md[1].length
|
|
253
245
|
@html << "<blockquote#{@opt[:attributes]}>\n"
|
|
254
246
|
@opt.delete(:attributes)
|
|
255
|
-
while md
|
|
247
|
+
while md && level==md[1].length
|
|
256
248
|
@html << inline(md[2])
|
|
257
249
|
@html << "\n"
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
md = @line&.match(BLOCKQS)
|
|
262
|
-
end
|
|
263
|
-
end
|
|
250
|
+
next unless (md=(@line=@file.gets)&.match BLOCKQS) && level<md[1].length
|
|
251
|
+
blockqs(md)
|
|
252
|
+
md = @line&.match(BLOCKQS)
|
|
264
253
|
end
|
|
265
254
|
@html << "</blockquote>\n"
|
|
266
255
|
true
|
|
@@ -276,9 +265,7 @@ class Markdown
|
|
|
276
265
|
@html << "<pre#{klass}#{@opt[:attributes]}><code>\n"
|
|
277
266
|
@opt.delete(:attributes)
|
|
278
267
|
code = ''
|
|
279
|
-
while @line=@file.gets
|
|
280
|
-
code << @line
|
|
281
|
-
end
|
|
268
|
+
code << @line while (@line=@file.gets) && !CODES.match?(@line)
|
|
282
269
|
@html << (lang ? ROUGE.format(lang.new.lex(code)) : code)
|
|
283
270
|
@html << "</code></pre>\n"
|
|
284
271
|
@line = @file.gets if @line # then it's code close and thus need next @line.
|
|
@@ -289,11 +276,11 @@ class Markdown
|
|
|
289
276
|
SCRIPT = /^<script/
|
|
290
277
|
PARSERS << :script
|
|
291
278
|
def script
|
|
292
|
-
|
|
279
|
+
SCRIPT.match(@line) or return false
|
|
293
280
|
@html << @line
|
|
294
|
-
while @line=@file.gets
|
|
281
|
+
while (@line=@file.gets)
|
|
295
282
|
@html << @line
|
|
296
|
-
break if %r
|
|
283
|
+
break if %r{^</script>}.match?(@line)
|
|
297
284
|
end
|
|
298
285
|
@line = @file.gets if @line
|
|
299
286
|
true
|
|
@@ -384,13 +371,13 @@ class Markdown
|
|
|
384
371
|
SPLITS.match? @line or return false
|
|
385
372
|
case @line.chomp
|
|
386
373
|
when '|:'
|
|
387
|
-
@html << %
|
|
374
|
+
@html << %(<table><tr><td#{@opt[:attributes]}>\n)
|
|
388
375
|
when '|'
|
|
389
|
-
@html << %
|
|
376
|
+
@html << %(</td><td#{@opt[:attributes]}>\n)
|
|
390
377
|
when ':|:'
|
|
391
|
-
@html << %
|
|
378
|
+
@html << %(</td></tr><tr><td#{@opt[:attributes]}>\n)
|
|
392
379
|
when ':|'
|
|
393
|
-
@html << %
|
|
380
|
+
@html << %(</td></tr></table>\n)
|
|
394
381
|
end
|
|
395
382
|
@opt.delete(:attributes)
|
|
396
383
|
@line = @file.gets
|
|
@@ -398,7 +385,7 @@ class Markdown
|
|
|
398
385
|
end
|
|
399
386
|
|
|
400
387
|
# Image
|
|
401
|
-
IMAGES = /^!\[([^\[\]]+)\]\(([
|
|
388
|
+
IMAGES = /^!\[([^\[\]]+)\]\(([^()]+)\)$/
|
|
402
389
|
PARSERS << :images
|
|
403
390
|
def images
|
|
404
391
|
md = IMAGES.match(@line) or return false
|
|
@@ -406,18 +393,20 @@ class Markdown
|
|
|
406
393
|
style = ' '
|
|
407
394
|
case alt
|
|
408
395
|
when /^:.*:$/
|
|
409
|
-
style =
|
|
396
|
+
style =
|
|
397
|
+
%( style="display: block; margin-left: auto; margin-right: auto;" )
|
|
410
398
|
when /:$/
|
|
411
|
-
style = %
|
|
399
|
+
style = %( style="float:left;" )
|
|
412
400
|
when /^:/
|
|
413
|
-
style = %
|
|
401
|
+
style = %( style="float:right;" )
|
|
414
402
|
end
|
|
415
403
|
if /(\d+)x(\d+)/.match alt
|
|
416
|
-
style << %
|
|
404
|
+
style << %(width="#{$1}" height="#{$2}" )
|
|
417
405
|
end
|
|
418
|
-
@html << %
|
|
419
|
-
@html <<
|
|
420
|
-
|
|
406
|
+
@html << %(<a href="#{href}">\n) if href
|
|
407
|
+
@html <<
|
|
408
|
+
%(<img src="#{src}"#{style}alt="#{alt.strip}"#{@opt[:attributes]}>\n)
|
|
409
|
+
@html << %(</a>\n) if href
|
|
421
410
|
@opt.delete(:attributes)
|
|
422
411
|
@line = @file.gets
|
|
423
412
|
true
|
|
@@ -431,9 +420,9 @@ class Markdown
|
|
|
431
420
|
def forms
|
|
432
421
|
md = FORMS.match(@line) or return false
|
|
433
422
|
fields,nl,submit = 0,false,nil
|
|
434
|
-
action = (_=/\(([
|
|
423
|
+
action = (_=/\(([^()]*)\)!?$/.match(@line))? %( action="#{_[1]}") : nil
|
|
435
424
|
method = @line.match?(/!$/) ? ' method="post"' : nil
|
|
436
|
-
@html << %
|
|
425
|
+
@html << %(<form#{action}#{method}#{@opt[:attributes]}>\n)
|
|
437
426
|
@opt.delete(:attributes)
|
|
438
427
|
while md
|
|
439
428
|
@html << " <br>\n" if nl
|
|
@@ -441,37 +430,38 @@ class Markdown
|
|
|
441
430
|
field &&= field[0...-1]
|
|
442
431
|
value &&= value[2...-1]
|
|
443
432
|
if field
|
|
444
|
-
type =
|
|
433
|
+
type = pwd ? 'password' : 'text'
|
|
445
434
|
if value
|
|
446
435
|
if (values = value.split('","')).length > 1
|
|
447
|
-
@html << %
|
|
436
|
+
@html << %(#{field}:<select name="#{name}">\n)
|
|
448
437
|
values.each do |value|
|
|
449
438
|
fields += 1
|
|
450
|
-
@html << %
|
|
439
|
+
@html << %( <option value="#{value}">#{value}</option>\n)
|
|
451
440
|
end
|
|
452
441
|
@html << "</select>\n"
|
|
453
442
|
else
|
|
454
443
|
fields += 1
|
|
455
|
-
@html << %
|
|
444
|
+
@html << %( #{field}:<input type="#{type}" name="#{name}")
|
|
445
|
+
@html << %( value="#{value}">\n)
|
|
456
446
|
end
|
|
457
447
|
else
|
|
458
448
|
fields += 1
|
|
459
|
-
@html << %
|
|
449
|
+
@html << %( #{field}:<input type="#{type}" name="#{name}">\n)
|
|
460
450
|
end
|
|
461
451
|
elsif name=='submit'
|
|
462
452
|
submit = value
|
|
463
453
|
else
|
|
464
|
-
@html << %
|
|
454
|
+
@html << %( <input type="hidden" name="#{name}" value="#{value}">\n)
|
|
465
455
|
end
|
|
466
456
|
end
|
|
467
457
|
md=(@line=@file.gets)&.match(FORMS) and nl=true
|
|
468
458
|
end
|
|
469
|
-
if submit
|
|
459
|
+
if submit || fields!=1
|
|
470
460
|
submit ||= 'Submit'
|
|
471
461
|
@html << " <br>\n" if nl
|
|
472
|
-
@html << %
|
|
462
|
+
@html << %( <input type="submit" value="#{submit}">\n)
|
|
473
463
|
end
|
|
474
|
-
@html << %
|
|
464
|
+
@html << %(</form>\n)
|
|
475
465
|
true
|
|
476
466
|
end
|
|
477
467
|
|
data/lib/markita/plug/about.rb
CHANGED
|
@@ -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
|
|
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
|
|
22
|
+
if defined? Favicon && Favicon::ICO
|
|
23
23
|
text << "\n\n"
|
|
24
24
|
end
|
|
25
25
|
text
|
data/lib/markita/plug/favicon.rb
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
module Markita
|
|
2
2
|
class Base
|
|
3
|
-
HEADER_LINKS <<
|
|
3
|
+
HEADER_LINKS <<
|
|
4
|
+
%( <link rel="stylesheet" href="/highlight.css" type="text/css">\n)
|
|
4
5
|
module Highlight
|
|
5
6
|
theme = OPTIONS&.theme || 'base16.light'
|
|
6
7
|
CSS = Rouge::Theme.find(theme)&.render(scope: '.highlight')
|
|
7
|
-
raise "Can't find Rouge Theme "+theme
|
|
8
|
+
raise "Can't find Rouge Theme "+theme unless CSS
|
|
8
9
|
end
|
|
9
10
|
|
|
10
11
|
get '/highlight.css' do
|
data/lib/markita/plug/login.rb
CHANGED
|
@@ -5,16 +5,16 @@ class Base
|
|
|
5
5
|
File.read(_).strip :
|
|
6
6
|
nil
|
|
7
7
|
IPS = (_=OPTIONS&.allowed)? _.split(',') : nil
|
|
8
|
-
if IPS
|
|
9
|
-
raise
|
|
8
|
+
if IPS && !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?
|
|
17
|
-
if 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
|
data/lib/markita/preprocess.rb
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
module Markita
|
|
2
2
|
class Preprocess
|
|
3
3
|
def initialize(file)
|
|
4
|
-
@file =
|
|
4
|
+
@file = file.is_a?(String)? StringIO.new(file) : file
|
|
5
5
|
@regx = @template = nil
|
|
6
6
|
end
|
|
7
7
|
|
|
8
8
|
def gets
|
|
9
|
-
while line
|
|
9
|
+
while (line=@file.gets)
|
|
10
10
|
case line
|
|
11
11
|
when @regx
|
|
12
12
|
line = @template if @template
|
|
@@ -15,16 +15,16 @@ class Preprocess
|
|
|
15
15
|
line = line.gsub("&#{name.upcase};", CGI.escape(value))
|
|
16
16
|
end
|
|
17
17
|
return line
|
|
18
|
-
when %r
|
|
18
|
+
when %r{^! regx = /(.*)/$}
|
|
19
19
|
@regx = Regexp.new $1
|
|
20
|
-
when %r
|
|
20
|
+
when %r{^! template = "(.*)"$}
|
|
21
21
|
@template = $1+"\n"
|
|
22
22
|
else
|
|
23
23
|
@regx &&= (@template=nil)
|
|
24
24
|
return line
|
|
25
25
|
end
|
|
26
26
|
end
|
|
27
|
-
|
|
27
|
+
nil
|
|
28
28
|
end
|
|
29
29
|
end
|
|
30
30
|
end
|
data/lib/markita.rb
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
module Markita
|
|
2
|
-
VERSION = '4.1.
|
|
2
|
+
VERSION = '4.1.230214'
|
|
3
3
|
|
|
4
4
|
def self.run!
|
|
5
5
|
# Standard libraries
|
|
@@ -10,19 +10,19 @@ module Markita
|
|
|
10
10
|
require 'sinatra/base'
|
|
11
11
|
require 'thin'
|
|
12
12
|
# Local
|
|
13
|
-
require_relative 'markita/config
|
|
14
|
-
require_relative 'markita/html
|
|
15
|
-
require_relative 'markita/preprocess
|
|
16
|
-
require_relative 'markita/markdown
|
|
17
|
-
require_relative 'markita/base
|
|
13
|
+
require_relative 'markita/config'
|
|
14
|
+
require_relative 'markita/html'
|
|
15
|
+
require_relative 'markita/preprocess'
|
|
16
|
+
require_relative 'markita/markdown'
|
|
17
|
+
require_relative 'markita/base'
|
|
18
18
|
# Plugs
|
|
19
|
-
require_relative 'markita/plug/about
|
|
20
|
-
require_relative 'markita/plug/favicon
|
|
21
|
-
require_relative 'markita/plug/highlight
|
|
22
|
-
require_relative 'markita/plug/login
|
|
23
|
-
require_relative 'markita/plug/navigation
|
|
24
|
-
require_relative 'markita/plug/plugs
|
|
25
|
-
require_relative 'markita/plug/readme
|
|
19
|
+
require_relative 'markita/plug/about' unless OPTIONS&.no_about
|
|
20
|
+
require_relative 'markita/plug/favicon' unless OPTIONS&.no_favicon
|
|
21
|
+
require_relative 'markita/plug/highlight' unless OPTIONS&.no_highlight
|
|
22
|
+
require_relative 'markita/plug/login' unless OPTIONS&.no_login
|
|
23
|
+
require_relative 'markita/plug/navigation' unless OPTIONS&.no_navigation
|
|
24
|
+
require_relative 'markita/plug/plugs' unless OPTIONS&.no_plugs
|
|
25
|
+
require_relative 'markita/plug/readme' unless OPTIONS&.no_readme
|
|
26
26
|
Base.run!
|
|
27
27
|
end
|
|
28
28
|
end
|
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.1.
|
|
4
|
+
version: 4.1.230214
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- CarlosJHR64
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2023-
|
|
11
|
+
date: 2023-02-14 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: help_parser
|
|
@@ -16,40 +16,40 @@ dependencies:
|
|
|
16
16
|
requirements:
|
|
17
17
|
- - "~>"
|
|
18
18
|
- !ruby/object:Gem::Version
|
|
19
|
-
version: '8.
|
|
19
|
+
version: '8.2'
|
|
20
20
|
- - ">="
|
|
21
21
|
- !ruby/object:Gem::Version
|
|
22
|
-
version: 8.
|
|
22
|
+
version: 8.2.230210
|
|
23
23
|
type: :runtime
|
|
24
24
|
prerelease: false
|
|
25
25
|
version_requirements: !ruby/object:Gem::Requirement
|
|
26
26
|
requirements:
|
|
27
27
|
- - "~>"
|
|
28
28
|
- !ruby/object:Gem::Version
|
|
29
|
-
version: '8.
|
|
29
|
+
version: '8.2'
|
|
30
30
|
- - ">="
|
|
31
31
|
- !ruby/object:Gem::Version
|
|
32
|
-
version: 8.
|
|
32
|
+
version: 8.2.230210
|
|
33
33
|
- !ruby/object:Gem::Dependency
|
|
34
34
|
name: rouge
|
|
35
35
|
requirement: !ruby/object:Gem::Requirement
|
|
36
36
|
requirements:
|
|
37
37
|
- - "~>"
|
|
38
38
|
- !ruby/object:Gem::Version
|
|
39
|
-
version: '4.
|
|
39
|
+
version: '4.1'
|
|
40
40
|
- - ">="
|
|
41
41
|
- !ruby/object:Gem::Version
|
|
42
|
-
version: 4.0
|
|
42
|
+
version: 4.1.0
|
|
43
43
|
type: :runtime
|
|
44
44
|
prerelease: false
|
|
45
45
|
version_requirements: !ruby/object:Gem::Requirement
|
|
46
46
|
requirements:
|
|
47
47
|
- - "~>"
|
|
48
48
|
- !ruby/object:Gem::Version
|
|
49
|
-
version: '4.
|
|
49
|
+
version: '4.1'
|
|
50
50
|
- - ">="
|
|
51
51
|
- !ruby/object:Gem::Version
|
|
52
|
-
version: 4.0
|
|
52
|
+
version: 4.1.0
|
|
53
53
|
- !ruby/object:Gem::Dependency
|
|
54
54
|
name: sinatra
|
|
55
55
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -90,6 +90,106 @@ dependencies:
|
|
|
90
90
|
- - ">="
|
|
91
91
|
- !ruby/object:Gem::Version
|
|
92
92
|
version: 1.8.1
|
|
93
|
+
- !ruby/object:Gem::Dependency
|
|
94
|
+
name: colorize
|
|
95
|
+
requirement: !ruby/object:Gem::Requirement
|
|
96
|
+
requirements:
|
|
97
|
+
- - "~>"
|
|
98
|
+
- !ruby/object:Gem::Version
|
|
99
|
+
version: '0.8'
|
|
100
|
+
- - ">="
|
|
101
|
+
- !ruby/object:Gem::Version
|
|
102
|
+
version: 0.8.1
|
|
103
|
+
type: :development
|
|
104
|
+
prerelease: false
|
|
105
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
106
|
+
requirements:
|
|
107
|
+
- - "~>"
|
|
108
|
+
- !ruby/object:Gem::Version
|
|
109
|
+
version: '0.8'
|
|
110
|
+
- - ">="
|
|
111
|
+
- !ruby/object:Gem::Version
|
|
112
|
+
version: 0.8.1
|
|
113
|
+
- !ruby/object:Gem::Dependency
|
|
114
|
+
name: nokogiri
|
|
115
|
+
requirement: !ruby/object:Gem::Requirement
|
|
116
|
+
requirements:
|
|
117
|
+
- - "~>"
|
|
118
|
+
- !ruby/object:Gem::Version
|
|
119
|
+
version: '1.14'
|
|
120
|
+
- - ">="
|
|
121
|
+
- !ruby/object:Gem::Version
|
|
122
|
+
version: 1.14.2
|
|
123
|
+
type: :development
|
|
124
|
+
prerelease: false
|
|
125
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
126
|
+
requirements:
|
|
127
|
+
- - "~>"
|
|
128
|
+
- !ruby/object:Gem::Version
|
|
129
|
+
version: '1.14'
|
|
130
|
+
- - ">="
|
|
131
|
+
- !ruby/object:Gem::Version
|
|
132
|
+
version: 1.14.2
|
|
133
|
+
- !ruby/object:Gem::Dependency
|
|
134
|
+
name: parser
|
|
135
|
+
requirement: !ruby/object:Gem::Requirement
|
|
136
|
+
requirements:
|
|
137
|
+
- - "~>"
|
|
138
|
+
- !ruby/object:Gem::Version
|
|
139
|
+
version: '3.2'
|
|
140
|
+
- - ">="
|
|
141
|
+
- !ruby/object:Gem::Version
|
|
142
|
+
version: 3.2.1
|
|
143
|
+
type: :development
|
|
144
|
+
prerelease: false
|
|
145
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
146
|
+
requirements:
|
|
147
|
+
- - "~>"
|
|
148
|
+
- !ruby/object:Gem::Version
|
|
149
|
+
version: '3.2'
|
|
150
|
+
- - ">="
|
|
151
|
+
- !ruby/object:Gem::Version
|
|
152
|
+
version: 3.2.1
|
|
153
|
+
- !ruby/object:Gem::Dependency
|
|
154
|
+
name: rubocop
|
|
155
|
+
requirement: !ruby/object:Gem::Requirement
|
|
156
|
+
requirements:
|
|
157
|
+
- - "~>"
|
|
158
|
+
- !ruby/object:Gem::Version
|
|
159
|
+
version: '1.45'
|
|
160
|
+
- - ">="
|
|
161
|
+
- !ruby/object:Gem::Version
|
|
162
|
+
version: 1.45.1
|
|
163
|
+
type: :development
|
|
164
|
+
prerelease: false
|
|
165
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
166
|
+
requirements:
|
|
167
|
+
- - "~>"
|
|
168
|
+
- !ruby/object:Gem::Version
|
|
169
|
+
version: '1.45'
|
|
170
|
+
- - ">="
|
|
171
|
+
- !ruby/object:Gem::Version
|
|
172
|
+
version: 1.45.1
|
|
173
|
+
- !ruby/object:Gem::Dependency
|
|
174
|
+
name: test-unit
|
|
175
|
+
requirement: !ruby/object:Gem::Requirement
|
|
176
|
+
requirements:
|
|
177
|
+
- - "~>"
|
|
178
|
+
- !ruby/object:Gem::Version
|
|
179
|
+
version: '3.5'
|
|
180
|
+
- - ">="
|
|
181
|
+
- !ruby/object:Gem::Version
|
|
182
|
+
version: 3.5.7
|
|
183
|
+
type: :development
|
|
184
|
+
prerelease: false
|
|
185
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
186
|
+
requirements:
|
|
187
|
+
- - "~>"
|
|
188
|
+
- !ruby/object:Gem::Version
|
|
189
|
+
version: '3.5'
|
|
190
|
+
- - ">="
|
|
191
|
+
- !ruby/object:Gem::Version
|
|
192
|
+
version: 3.5.7
|
|
93
193
|
description: |
|
|
94
194
|
A Sinatra Markdown server.
|
|
95
195
|
|
|
@@ -139,8 +239,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
139
239
|
- !ruby/object:Gem::Version
|
|
140
240
|
version: '0'
|
|
141
241
|
requirements:
|
|
142
|
-
- '
|
|
143
|
-
|
|
242
|
+
- 'git: 2.30'
|
|
243
|
+
- 'ruby: 3.2'
|
|
244
|
+
rubygems_version: 3.4.6
|
|
144
245
|
signing_key:
|
|
145
246
|
specification_version: 4
|
|
146
247
|
summary: A Sinatra Markdown server.
|