markita 4.1.230214 → 6.0.250327
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 +194 -237
- data/bin/markita +16 -19
- data/lib/markita/base.rb +37 -38
- data/lib/markita/config.rb +41 -10
- data/lib/markita/html.rb +35 -20
- data/lib/markita/markdown/attributes.rb +23 -0
- data/lib/markita/markdown/blockquote.rb +41 -0
- data/lib/markita/markdown/code.rb +44 -0
- data/lib/markita/markdown/code_block.rb +29 -0
- data/lib/markita/markdown/definitions.rb +42 -0
- data/lib/markita/markdown/embed.rb +63 -0
- data/lib/markita/markdown/empty.rb +22 -0
- data/lib/markita/markdown/fold.rb +39 -0
- data/lib/markita/markdown/footnotes.rb +28 -0
- data/lib/markita/markdown/form.rb +125 -0
- data/lib/markita/markdown/heading.rb +33 -0
- data/lib/markita/markdown/horizontal_rule.rb +25 -0
- data/lib/markita/markdown/image.rb +60 -0
- data/lib/markita/markdown/inline.rb +123 -0
- data/lib/markita/markdown/list.rb +65 -0
- data/lib/markita/markdown/markup.rb +23 -0
- data/lib/markita/markdown/script.rb +28 -0
- data/lib/markita/markdown/split.rb +38 -0
- data/lib/markita/markdown/table.rb +52 -0
- data/lib/markita/markdown.rb +51 -498
- data/lib/markita/plug/about.rb +28 -17
- data/lib/markita/plug/favicon.rb +14 -10
- data/lib/markita/plug/highlight.rb +18 -12
- data/lib/markita/plug/login.rb +35 -28
- data/lib/markita/plug/navigation.rb +4 -1
- data/lib/markita/plug/plugs.rb +7 -1
- data/lib/markita/plug/readme.rb +8 -4
- data/lib/markita/preprocess.rb +52 -23
- data/lib/markita/refinement.rb +21 -0
- data/lib/markita/requires.rb +29 -0
- data/lib/markita.rb +15 -24
- metadata +52 -116
data/lib/markita/config.rb
CHANGED
@@ -1,21 +1,52 @@
|
|
1
|
-
|
2
|
-
OPTIONS ||= nil
|
1
|
+
# frozen_string_literal: true
|
3
2
|
|
3
|
+
# Markita namespace
|
4
|
+
# :reek:TooManyConstants because it's a configuration file!
|
5
|
+
module Markita
|
4
6
|
HEADER_LINKS = ''
|
5
|
-
NAVIGATION
|
7
|
+
NAVIGATION = ''
|
8
|
+
|
9
|
+
BIND = OPTIONS.bind || '0.0.0.0'
|
10
|
+
PORT = OPTIONS.port || '8080'
|
11
|
+
SERVER = 'webrick'
|
12
|
+
|
13
|
+
MDX = '.md'
|
14
|
+
INDEX = 'index'
|
15
|
+
|
16
|
+
ROOT = File.expand_path OPTIONS.root || '~/vimwiki'
|
17
|
+
raise "Missing site root directory: #{ROOT}" unless File.directory? ROOT
|
18
|
+
|
19
|
+
ssl_certificate = File.join(ROOT, '.cert.crt')
|
20
|
+
ssl_private_key = File.join(ROOT, '.pkey.pem')
|
21
|
+
SERVER_SETTINGS =
|
22
|
+
if [ssl_certificate, ssl_private_key].all? { File.exist? it }
|
23
|
+
{
|
24
|
+
SSLEnable:
|
25
|
+
true,
|
26
|
+
SSLVerifyClient:
|
27
|
+
OpenSSL::SSL::VERIFY_NONE,
|
28
|
+
SSLCertificate:
|
29
|
+
OpenSSL::X509::Certificate.new(File.read(ssl_certificate)),
|
30
|
+
SSLPrivateKey:
|
31
|
+
OpenSSL::PKey::RSA.new(File.read(ssl_private_key))
|
32
|
+
}
|
33
|
+
end
|
6
34
|
|
7
|
-
|
8
|
-
|
9
|
-
|
35
|
+
SERVER_CONFIG = lambda do |server|
|
36
|
+
puts "#{$PROGRAM_NAME}-#{VERSION}".blue
|
37
|
+
puts "Sinatra-#{Sinatra::VERSION} using #{server.class}".blue
|
38
|
+
end
|
39
|
+
|
40
|
+
APPDIR = File.dirname __dir__, 2
|
10
41
|
APPDATA = File.join APPDIR, 'data'
|
42
|
+
|
11
43
|
PATH = lambda do |basename|
|
12
|
-
[ROOT, APPDATA].map{ File.join
|
44
|
+
[ROOT, APPDATA].map { File.join it, basename }.detect { File.exist? it }
|
13
45
|
end
|
14
|
-
NOT_FOUND = File.read PATH['not_found.html']
|
15
46
|
|
16
|
-
|
47
|
+
NOT_FOUND = File.read PATH['not_found.html']
|
17
48
|
|
18
|
-
PAGE_KEY = %r{/(\w[\w/-]*\w)}
|
49
|
+
PAGE_KEY = %r{/(\w[\w/-]*\w)} # Note that it starts with a slash
|
19
50
|
SEND_FILE = %r{/(\w[\w/-]*\w\.\w+)}
|
20
51
|
|
21
52
|
START_TIME = Time.now
|
data/lib/markita/html.rb
CHANGED
@@ -1,25 +1,40 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Markita namespace
|
1
4
|
module Markita
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
<head>
|
8
|
-
<title>#{key}</title>
|
9
|
-
#{HEADER_LINKS}</head>
|
10
|
-
<body>
|
11
|
-
HEADER
|
12
|
-
end
|
5
|
+
# HTML template
|
6
|
+
# :reek:ClassVariable
|
7
|
+
# rubocop:disable Style/ClassVars
|
8
|
+
module Html
|
9
|
+
# category: header
|
13
10
|
|
14
|
-
|
15
|
-
|
16
|
-
|
11
|
+
def self.header(title)
|
12
|
+
<<~HEADER
|
13
|
+
<!DOCTYPE html>
|
14
|
+
<html>
|
15
|
+
<head>
|
16
|
+
<title>#{title}</title>
|
17
|
+
#{@@header_links}</head>
|
18
|
+
<body>
|
19
|
+
HEADER
|
20
|
+
end
|
21
|
+
|
22
|
+
@@header_links = String.new(HEADER_LINKS)
|
23
|
+
def self.header_links = @@header_links
|
17
24
|
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
25
|
+
# category: body
|
26
|
+
|
27
|
+
@@navigation = String.new(NAVIGATION)
|
28
|
+
def self.navigation = @@navigation
|
29
|
+
|
30
|
+
# category: footer
|
31
|
+
|
32
|
+
def self.footer
|
33
|
+
<<~FOOTER
|
34
|
+
</body>
|
35
|
+
</html>
|
36
|
+
FOOTER
|
37
|
+
end
|
23
38
|
end
|
24
|
-
|
39
|
+
# rubocop:enable Style/ClassVars
|
25
40
|
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Markita top level namespace
|
4
|
+
module Markita
|
5
|
+
# Markdown namespace
|
6
|
+
# :reek:InstanceVariableAssumption :reek:ClassVariable
|
7
|
+
class Markdown
|
8
|
+
# Module to isolate from Markdown
|
9
|
+
module Attributes
|
10
|
+
RGX = /^\{:( [^\{\}]+)\}/
|
11
|
+
end
|
12
|
+
|
13
|
+
@@parsers << :attributes
|
14
|
+
|
15
|
+
def attributes
|
16
|
+
return false unless (md = Attributes::RGX.match(@line))
|
17
|
+
|
18
|
+
@attributes.push md[1]
|
19
|
+
@line = md.post_match
|
20
|
+
true
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Markita top level namespace
|
4
|
+
module Markita
|
5
|
+
# Markdown namespace
|
6
|
+
# :reek:InstanceVariableAssumption :reek:ClassVariable
|
7
|
+
class Markdown
|
8
|
+
# Module to isolate from Markdown
|
9
|
+
module Blockquote
|
10
|
+
RGX = /^( {0,3})> (.*)$/
|
11
|
+
|
12
|
+
def self.level_quote(line)
|
13
|
+
mdt = RGX.match(line)
|
14
|
+
[mdt[1].length, mdt[2]] if mdt
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
@@parsers << :blockquote
|
19
|
+
|
20
|
+
# category: method
|
21
|
+
# :reek:DuplicateMethodCall :reek:TooManyStatements
|
22
|
+
# rubocop:disable Metrics/MethodLength
|
23
|
+
def blockquote
|
24
|
+
return false unless (level, quote = Blockquote.level_quote(@line))
|
25
|
+
|
26
|
+
@html << "<blockquote#{@attributes.shift}>\n"
|
27
|
+
current = level
|
28
|
+
while current.eql?(level)
|
29
|
+
@html << "#{inline(quote)}\n"
|
30
|
+
current, quote = Blockquote.level_quote(line_gets)
|
31
|
+
next unless current&.>(level)
|
32
|
+
|
33
|
+
blockquote
|
34
|
+
level, quote = Blockquote.level_quote(@line)
|
35
|
+
end
|
36
|
+
@html << "</blockquote>\n"
|
37
|
+
true
|
38
|
+
end
|
39
|
+
# rubocop:enable Metrics/MethodLength
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Markita top level namespace
|
4
|
+
module Markita
|
5
|
+
# Markdown namespace
|
6
|
+
# :reek:InstanceVariableAssumption :reek:ClassVariable
|
7
|
+
class Markdown
|
8
|
+
# Module to isolate from Markdown
|
9
|
+
module Code
|
10
|
+
RGX = /^[`]{3}\s*(\w+)?$/
|
11
|
+
|
12
|
+
def self.code(file, lang, code = String.new)
|
13
|
+
# Note that we can ignore the final shifted
|
14
|
+
# line because it will be the closing fence.
|
15
|
+
while (line = file.gets) && !RGX.match?(line)
|
16
|
+
code << line
|
17
|
+
end
|
18
|
+
lang ? ROUGE.format(lang.new.lex(code)) : code
|
19
|
+
end
|
20
|
+
|
21
|
+
def self.klass_lang(line)
|
22
|
+
if (mdt = RGX.match(line))
|
23
|
+
lang = Rouge::Lexer.find(mdt[1])
|
24
|
+
klass = lang ? ' class="highlight"' : ''
|
25
|
+
[klass, lang]
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
@@parsers << :code
|
31
|
+
|
32
|
+
# category: method
|
33
|
+
# :reek:TooManyStatements
|
34
|
+
def code
|
35
|
+
return false unless (klass, lang = Code.klass_lang(@line))
|
36
|
+
|
37
|
+
@html << "<pre#{klass}#{@attributes.shift}><code>\n"
|
38
|
+
@html << Code.code(@line_getter, lang)
|
39
|
+
@html << "</code></pre>\n"
|
40
|
+
line_gets
|
41
|
+
true
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Markita top level namespace
|
4
|
+
module Markita
|
5
|
+
# Markdown namespace
|
6
|
+
# :reek:InstanceVariableAssumption :reek:ClassVariable
|
7
|
+
class Markdown
|
8
|
+
# Module to isolate from Markdown
|
9
|
+
module CodeBlock
|
10
|
+
RGX = /^ {4}(.*)$/
|
11
|
+
end
|
12
|
+
|
13
|
+
@@parsers << :code_block
|
14
|
+
|
15
|
+
# category: method
|
16
|
+
# :reek:TooManyStatements
|
17
|
+
def code_block
|
18
|
+
return false unless (md = CodeBlock::RGX.match(@line))
|
19
|
+
|
20
|
+
@html << "<pre#{@attributes.shift}>\n"
|
21
|
+
while md
|
22
|
+
@html << "#{md[1]}\n"
|
23
|
+
md = CodeBlock::RGX.match(line_gets)
|
24
|
+
end
|
25
|
+
@html << "</pre>\n"
|
26
|
+
true
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Markita top level namespace
|
4
|
+
module Markita
|
5
|
+
# Markdown namespace
|
6
|
+
# :reek:InstanceVariableAssumption :reek:ClassVariable
|
7
|
+
class Markdown
|
8
|
+
# Module to isolate from Markdown
|
9
|
+
module Definitions
|
10
|
+
RGX = /^[+] (\S.+)$/
|
11
|
+
def self.phrase(line)
|
12
|
+
mdt = RGX.match(line)
|
13
|
+
mdt[1] if mdt
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.split(phrase)
|
17
|
+
return [phrase.chop, nil] if /:$/.match?(phrase)
|
18
|
+
return [nil, phrase] unless (mdt = /^(.*): +(\S.*)$/.match(phrase))
|
19
|
+
|
20
|
+
[mdt[1], mdt[2]]
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
@@parsers << :definitions
|
25
|
+
|
26
|
+
# category: method
|
27
|
+
# :reek:TooManyStatements
|
28
|
+
def definitions
|
29
|
+
return false unless (phrase = Definitions.phrase(@line))
|
30
|
+
|
31
|
+
@html << "<dl#{@attributes.shift}>\n"
|
32
|
+
while phrase
|
33
|
+
term, definition = Definitions.split(phrase)
|
34
|
+
@html << "<dt>#{inline term}</dt>\n" if term
|
35
|
+
@html << "<dd>#{inline definition}</dd>\n" if definition
|
36
|
+
phrase = Definitions.phrase(line_gets)
|
37
|
+
end
|
38
|
+
@html << "</dl>\n"
|
39
|
+
true
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,63 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Markita top level namespace
|
4
|
+
module Markita
|
5
|
+
# Markdown namespace
|
6
|
+
# :reek:InstanceVariableAssumption :reek:ClassVariable
|
7
|
+
class Markdown
|
8
|
+
# Module to isolate from Markdown
|
9
|
+
module Embed
|
10
|
+
RGX = /^!> (#{PAGE_KEY}\.\w+)$/
|
11
|
+
|
12
|
+
def self.code(filename, lang)
|
13
|
+
code = File.read(filename)
|
14
|
+
lang ? ROUGE.format(lang.new.lex(code)) : code
|
15
|
+
end
|
16
|
+
|
17
|
+
# :reek:TooManyStatements
|
18
|
+
def self.ext_klass_lang(filename, lang = nil)
|
19
|
+
extension = filename.split('.').last
|
20
|
+
unless extension == 'html'
|
21
|
+
lang = Rouge::Lexer.find(extension) unless extension == 'txt'
|
22
|
+
klass = lang ? ' class="highlight"' : ''
|
23
|
+
return [true, klass, lang]
|
24
|
+
end
|
25
|
+
[false, nil, nil]
|
26
|
+
end
|
27
|
+
|
28
|
+
def self.filename(line)
|
29
|
+
if (mdt = RGX.match(line))
|
30
|
+
mdt[1]
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
@@parsers << :embed
|
36
|
+
|
37
|
+
# category: method
|
38
|
+
# :reek:TooManyStatements
|
39
|
+
# rubocop:disable Metrics/MethodLength
|
40
|
+
def embed
|
41
|
+
return false unless (filename = Embed.filename(@line))
|
42
|
+
|
43
|
+
if File.exist?(filename = File.join(ROOT, filename))
|
44
|
+
code, klass, lang = Embed.ext_klass_lang(filename)
|
45
|
+
if code
|
46
|
+
@html << "<pre#{klass}#{@attributes.shift}>"
|
47
|
+
@html << '<code>' if lang
|
48
|
+
@html << "\n"
|
49
|
+
end
|
50
|
+
@html << Embed.code(filename, lang)
|
51
|
+
if code
|
52
|
+
@html << '</code>' if lang
|
53
|
+
@html << "</pre>\n"
|
54
|
+
end
|
55
|
+
else
|
56
|
+
@html << @line
|
57
|
+
end
|
58
|
+
line_gets
|
59
|
+
true
|
60
|
+
end
|
61
|
+
# rubocop:enable Metrics/MethodLength
|
62
|
+
end
|
63
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Markita top level namespace
|
4
|
+
module Markita
|
5
|
+
# Markdown namespace
|
6
|
+
# :reek:InstanceVariableAssumption :reek:ClassVariable
|
7
|
+
class Markdown
|
8
|
+
# Module to isolate from Markdown
|
9
|
+
module Empty
|
10
|
+
RGX = /^$/
|
11
|
+
end
|
12
|
+
|
13
|
+
@@parsers << :empty
|
14
|
+
|
15
|
+
def empty
|
16
|
+
return false unless Empty::RGX.match?(@line)
|
17
|
+
|
18
|
+
line_gets
|
19
|
+
true
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Markita top level namespace
|
4
|
+
module Markita
|
5
|
+
# Markdown namespace
|
6
|
+
# :reek:InstanceVariableAssumption :reek:ClassVariable
|
7
|
+
class Markdown
|
8
|
+
# Module to isolate from Markdown
|
9
|
+
# :reek:DuplicateMethodCall
|
10
|
+
module Fold
|
11
|
+
RGX = /^[-.]{3} #/
|
12
|
+
METADATA = /^(\w+): (.*)$/
|
13
|
+
def self.scrape4metadata(line, metadata, attributes)
|
14
|
+
if (md = Fold::METADATA.match(line))
|
15
|
+
if (key = md[1]) == 'attributes'
|
16
|
+
attributes.push " #{md[2]}"
|
17
|
+
else
|
18
|
+
metadata[key] = md[2]
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
@@parsers << :fold
|
25
|
+
|
26
|
+
# category: method
|
27
|
+
# :reek:DuplicateMethodCall ok here
|
28
|
+
def fold
|
29
|
+
return false unless Fold::RGX.match?(@line)
|
30
|
+
|
31
|
+
# Fold with optional metadata
|
32
|
+
until Fold::RGX.match?(line_gets)
|
33
|
+
Fold.scrape4metadata(@line, @metadata, @attributes)
|
34
|
+
end
|
35
|
+
line_gets
|
36
|
+
true
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Markita top level namespace
|
4
|
+
module Markita
|
5
|
+
# Markdown namespace
|
6
|
+
# :reek:InstanceVariableAssumption :reek:ClassVariable
|
7
|
+
class Markdown
|
8
|
+
# Module to isolate from Markdown
|
9
|
+
module Footnotes
|
10
|
+
RGX = /^\[\^\d+\]:/
|
11
|
+
end
|
12
|
+
|
13
|
+
@@parsers << :footnotes
|
14
|
+
|
15
|
+
# :reek:TooManyStatements
|
16
|
+
def footnotes
|
17
|
+
return false unless (continue = Footnotes::RGX.match?(@line))
|
18
|
+
|
19
|
+
@html << "<small>\n"
|
20
|
+
while continue
|
21
|
+
@html << "#{inline(@line.chomp)}<br>\n"
|
22
|
+
continue = Footnotes::RGX.match?(line_gets)
|
23
|
+
end
|
24
|
+
@html << "</small>\n"
|
25
|
+
true
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,125 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Markita top level namespace
|
4
|
+
module Markita
|
5
|
+
# Markdown namespace
|
6
|
+
# :reek:InstanceVariableAssumption :reek:ClassVariable
|
7
|
+
class Markdown
|
8
|
+
# Module to isolate from Markdown
|
9
|
+
module Form
|
10
|
+
field = '(\w+:)?\[(\*)?(\w+)(=("[^"]+")(,"[^"]+")*)?\]'
|
11
|
+
FIELD = Regexp.new field
|
12
|
+
RGX = /^!( #{field})+/
|
13
|
+
POST = /!$/
|
14
|
+
ACTION = /\(([^()]*)\)!?$/
|
15
|
+
|
16
|
+
def self.input_select(field, name, values)
|
17
|
+
%( #{field}:<select name="#{name}">\n).tap do |html|
|
18
|
+
values.each do |value|
|
19
|
+
html << %( <option value="#{value}">#{value}</option>\n)
|
20
|
+
end
|
21
|
+
html << " </select>\n"
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def self.input_text(field, type, name)
|
26
|
+
%( #{field}:<input type="#{type}" name="#{name}">\n)
|
27
|
+
end
|
28
|
+
|
29
|
+
# :reek:LongParameterList :reek:TooManyStatements
|
30
|
+
def self.input(type, field, name, values)
|
31
|
+
if field
|
32
|
+
if values.empty? then input_text(field, type, name)
|
33
|
+
elsif values.count > 1 then input_select(field, name, values)
|
34
|
+
else
|
35
|
+
input_defaulted(field, type, name, values)
|
36
|
+
end
|
37
|
+
elsif name == 'submit' then input_submit(values)
|
38
|
+
else
|
39
|
+
input_hidden(name, values)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
def self.input_submit(values)
|
44
|
+
%( <input type="submit" value="#{values[0] || 'Submit'}">\n)
|
45
|
+
end
|
46
|
+
|
47
|
+
def self.input_hidden(name, values)
|
48
|
+
%( <input type="hidden" name="#{name}" value="#{values[0]}">\n)
|
49
|
+
end
|
50
|
+
|
51
|
+
# :reek:LongParameterList
|
52
|
+
def self.input_defaulted(field, type, name, values)
|
53
|
+
<<-INPUT
|
54
|
+
#{field}:<input type="#{type}" name="#{name}"
|
55
|
+
value="#{values[0]}">
|
56
|
+
INPUT
|
57
|
+
end
|
58
|
+
|
59
|
+
def self.match?(line) = RGX.match?(line)
|
60
|
+
|
61
|
+
# :reek:ControlParameter :reek:NilCheck :reek:LongParameterList
|
62
|
+
def self.maybe(yon, name, field, values)
|
63
|
+
return :NO if yon == :NO || (field.nil? && name == 'submit')
|
64
|
+
return yon unless field && values.count < 2
|
65
|
+
|
66
|
+
yon == :yes ? :no : :YES
|
67
|
+
end
|
68
|
+
|
69
|
+
# :reek:LongYieldList :reek:TooManyStatements
|
70
|
+
def self.scan(line)
|
71
|
+
line.scan(FIELD).each do |field, pwd, name, value|
|
72
|
+
field &&= field[0...-1]
|
73
|
+
values = value ? value[2...-1].split('","') : []
|
74
|
+
type = pwd ? 'password' : 'text'
|
75
|
+
yield field, type, name, values
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
def self.start(line, attributes)
|
80
|
+
method = POST.match?(line) ? ' method="post"' : ''
|
81
|
+
action = (mdt = ACTION.match(line)) ? %( action="#{mdt[1]}") : ''
|
82
|
+
%(<form#{action}#{method}#{attributes.shift}>\n)
|
83
|
+
end
|
84
|
+
|
85
|
+
def self.stop = %(</form>\n)
|
86
|
+
|
87
|
+
# :reek:ControlParameter
|
88
|
+
def self.submit(yon)
|
89
|
+
case yon
|
90
|
+
when :yes
|
91
|
+
%( <input type="submit">\n)
|
92
|
+
when :YES
|
93
|
+
%( <br>\n <input type="submit">\n)
|
94
|
+
else
|
95
|
+
''
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
@@parsers << :form
|
101
|
+
|
102
|
+
# category: method
|
103
|
+
# :reek:TooManyStatements
|
104
|
+
# rubocop:disable Metrics/MethodLength
|
105
|
+
def form
|
106
|
+
return false unless Form.match?(@line)
|
107
|
+
|
108
|
+
yon = :yes # Append submit button?
|
109
|
+
@html << Form.start(@line, @attributes)
|
110
|
+
loop do
|
111
|
+
Form.scan(@line) do |field, type, name, values|
|
112
|
+
yon = Form.maybe(yon, name, field, values)
|
113
|
+
@html << Form.input(type, field, name, values)
|
114
|
+
end
|
115
|
+
break unless Form.match?(line_gets)
|
116
|
+
|
117
|
+
@html << " <br>\n"
|
118
|
+
end
|
119
|
+
@html << Form.submit(yon)
|
120
|
+
@html << Form.stop
|
121
|
+
true
|
122
|
+
end
|
123
|
+
# rubocop:enable Metrics/MethodLength
|
124
|
+
end
|
125
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Markita top level namespace
|
4
|
+
module Markita
|
5
|
+
# Markdown namespace
|
6
|
+
# :reek:InstanceVariableAssumption :reek:ClassVariable
|
7
|
+
class Markdown
|
8
|
+
# Module to isolate from Markdown
|
9
|
+
module Heading
|
10
|
+
RGX = /^(\#{1,6}) (.*)$/
|
11
|
+
|
12
|
+
def self.level_header(line)
|
13
|
+
mdt = RGX.match(line)
|
14
|
+
[mdt[1].length, mdt[2]] if mdt
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
@@parsers << :heading
|
19
|
+
|
20
|
+
# category: method
|
21
|
+
# :reek:TooManyStatements :reek:UncommunicativeVariableName
|
22
|
+
def heading
|
23
|
+
return false unless (n, header = Heading.level_header(@line))
|
24
|
+
|
25
|
+
id = header.gsub(/\([^()]*\)/, '').scan(/\w+/).join('+')
|
26
|
+
@html << %(<a id="#{id}">\n)
|
27
|
+
@html << " <h#{n}#{@attributes.shift}>#{inline(header)}</h#{n}>\n"
|
28
|
+
@html << "</a>\n"
|
29
|
+
line_gets
|
30
|
+
true
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Markita top level namespace
|
4
|
+
module Markita
|
5
|
+
# Markdown namespace
|
6
|
+
# :reek:InstanceVariableAssumption :reek:ClassVariable
|
7
|
+
class Markdown
|
8
|
+
# Module to isolate from Markdown
|
9
|
+
module HorizontalRule
|
10
|
+
RGX = /^---+$/
|
11
|
+
end
|
12
|
+
|
13
|
+
@@parsers << :horizontal_rule
|
14
|
+
|
15
|
+
# category: method
|
16
|
+
def horizontal_rule
|
17
|
+
return false unless HorizontalRule::RGX.match?(@line)
|
18
|
+
|
19
|
+
line_gets
|
20
|
+
# Display HR
|
21
|
+
@html << "<hr#{@attributes.shift}>\n"
|
22
|
+
true
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|