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