markita 5.0.241001 → 6.0.251015

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.
Files changed (39) hide show
  1. checksums.yaml +4 -4
  2. data/CREDITS.md +20 -0
  3. data/README.md +32 -15
  4. data/bin/markita +16 -19
  5. data/lib/markita/base.rb +38 -31
  6. data/lib/markita/config.rb +27 -18
  7. data/lib/markita/html.rb +35 -20
  8. data/lib/markita/markdown/attributes.rb +23 -0
  9. data/lib/markita/markdown/blockquote.rb +44 -0
  10. data/lib/markita/markdown/code.rb +44 -0
  11. data/lib/markita/markdown/code_block.rb +29 -0
  12. data/lib/markita/markdown/definitions.rb +42 -0
  13. data/lib/markita/markdown/embed.rb +63 -0
  14. data/lib/markita/markdown/empty.rb +22 -0
  15. data/lib/markita/markdown/fold.rb +39 -0
  16. data/lib/markita/markdown/footnotes.rb +28 -0
  17. data/lib/markita/markdown/form.rb +125 -0
  18. data/lib/markita/markdown/heading.rb +33 -0
  19. data/lib/markita/markdown/horizontal_rule.rb +25 -0
  20. data/lib/markita/markdown/image.rb +60 -0
  21. data/lib/markita/markdown/inline.rb +123 -0
  22. data/lib/markita/markdown/list.rb +65 -0
  23. data/lib/markita/markdown/markup.rb +23 -0
  24. data/lib/markita/markdown/script.rb +28 -0
  25. data/lib/markita/markdown/split.rb +38 -0
  26. data/lib/markita/markdown/table.rb +52 -0
  27. data/lib/markita/markdown.rb +51 -475
  28. data/lib/markita/plug/about.rb +28 -17
  29. data/lib/markita/plug/favicon.rb +14 -10
  30. data/lib/markita/plug/highlight.rb +17 -12
  31. data/lib/markita/plug/login.rb +35 -28
  32. data/lib/markita/plug/navigation.rb +4 -1
  33. data/lib/markita/plug/plugs.rb +7 -1
  34. data/lib/markita/plug/readme.rb +8 -4
  35. data/lib/markita/preprocess.rb +52 -23
  36. data/lib/markita/refinement.rb +21 -0
  37. data/lib/markita/requires.rb +29 -0
  38. data/lib/markita.rb +15 -25
  39. metadata +52 -135
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: cd3ec2273b3a06985b04dbcaa4e4cc190ad724b78a95614715bc940d762f0603
4
- data.tar.gz: 45313726512a832f997d4ea3ac16e7be4839a448de674eeabfe62817ddd7128f
3
+ metadata.gz: 21a67b87c8ca2df79de3be5215aed19ab62ca227d98605929b64d45a14e1ff98
4
+ data.tar.gz: 86d8fa6166dbc759f1e456799123baa492deaacaab3c7d248526785598252d0c
5
5
  SHA512:
6
- metadata.gz: 75a93470a33b67d868ed1fabac90b0d6a111f1f2c3e028534ffdc5ce434d8361103e8fa27249c4f34e347c3de57dc8806bd221351bc8abf75396ad9a1500f8bb
7
- data.tar.gz: d1180313131e3487558c863cdd6817c401e37ddd36bc64ad1821eb082a11c432bed0f0eb055dc34a9bb75c68129a0a109e721bd4132efc072a6ca4583c2d655f
6
+ metadata.gz: 998cc045c833cb56073639f7bf40f61a1234338453d12f43f0c5c853473910cf4d9d04a74869df6f7150e2237464a85255506f1fa4e9152e60a048ee7ac64593
7
+ data.tar.gz: 1101459bb6b8ac05fb3c9dd7c45c5c3102e568f9d73e5b100daf95dd54c69eba7c4d364667053903184cf9348ab2796afc3290e33f06ef58c6890efecede33e9
data/CREDITS.md ADDED
@@ -0,0 +1,20 @@
1
+ # Credits
2
+
3
+ We want to credit where credit is due.
4
+ This project owes thanks to the authors of this repository (see their commits),
5
+ the third-party libraries we rely on (check the dependencies),
6
+ and the diffuse pool of ideas and inspirations that shaped it.
7
+
8
+ We welcome contributions to this list!
9
+ If you feel someone or something is missing,
10
+ please submit a pull request with the suggested addition.
11
+
12
+ + [VimWiki](https://github.com/vimwiki/vimwiki): VimWiki is a personal wiki for Vim
13
+ + [GitHub Markdown](https://docs.github.com/en/get-started/writing-on-github): Main specs target
14
+
15
+ And then many alternate specs for Markdown:
16
+
17
+ * [adam-p: Markdown-Cheatsheet](https://github.com/adam-p/markdown-here/wiki/Markdown-Cheatsheet)
18
+ * [lifeparticle: Markdown-Cheatsheed](https://github.com/lifeparticle/Markdown-Cheatsheet)
19
+ * [CommonMark Spec](https://spec.commonmark.org/)
20
+ * [CommonMark Cheat Sheet](https://commonmark.org/help/)
data/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Markita
2
2
 
3
- * [VERSION 5.0.241001](https://github.com/carlosjhr64/markita/releases)
3
+ * [VERSION 6.0.251015](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
 
@@ -14,6 +14,8 @@ With many extra non-standard features.
14
14
  ```console
15
15
  $ gem install markita
16
16
  ```
17
+ * Required Ruby version: `>= 3.4`
18
+
17
19
  ## HELP
18
20
  ```console
19
21
  $ markita --help
@@ -25,27 +27,21 @@ Options:
25
27
  --port=PORT 8080
26
28
  --theme=THEME base16.light
27
29
  --allowed=IPS
28
- --no_about
29
- --no_favicon
30
- --no_highlight
31
- --no_login
32
- --no_navigation
33
- --no_plugs
34
- --no_readme
35
- Exclusive:
36
- no_login allowed
30
+ --no=PLUGS
37
31
  Types:
38
32
  DIRECTORY /^~?[\/\w\.]+$/
39
33
  BIND /^[\w\.]+$/
40
34
  PORT /^\d+$/
41
35
  IPS /^[\d\.\,]+$/
42
36
  THEME /^[\w\.]+$/
37
+ PLUGS /^[\w\,]+$/
43
38
  # NOTE:
44
39
  # Assuming site is in ~/vimwiki,
45
40
  # when ~/vimwiki/.valid-id is set with a sha256sum of a password,
46
41
  # that password will restrict the site.
47
42
  # Allowed IPs bypass the need for site password
48
43
  # when the site is accessed from those locations.
44
+ # You can use the --no option to list plugins to disable.
49
45
  ```
50
46
  ## FEATURES
51
47
 
@@ -58,16 +54,25 @@ Types:
58
54
  * HTML pass through on `/^<.*>$/` lines
59
55
  * And more...
60
56
 
61
- ### Horizontal rule with meta-data
57
+ ### Meta-data
62
58
 
63
- * If `Title` is set via meta-data, the server will set the page's title to that
59
+ * `$key` substitution to its metadata value in text
60
+ * If `Title` is set via meta-data, Javascript will set the page's title to that
64
61
  * One can use numbers to reference long URLs
65
62
  ```markdown
66
- ---
63
+ --- # The hashtag disambiguates the horizontal rule(legal YAML comment).
67
64
  Title: Markita
68
65
  1: https://github.com/carlosjhr64/markita
69
- ---
66
+ name: Don Quixote de la Mancha
67
+ # You can also add to attributes here:
68
+ attributes: style="color: darkgreen;"
69
+ ... # The end marker is needed to end the fold
70
70
  [Markita](1)
71
+ Your name is $name.
72
+ ```
73
+ ### Horizontal rule
74
+ ```markdown
75
+ ---
71
76
  ```
72
77
  ### Attributes
73
78
  ```markdown
@@ -211,9 +216,15 @@ A multi-line form with default entry and hidden field:
211
216
 
212
217
  A selection list:
213
218
  ! Color:[color="Red","White","Blue"]
219
+
220
+ A submit button:
221
+ ! [submit="Go!"]
214
222
  ```
215
223
  ### Template substitutions
216
224
  ```markdown
225
+ ! regx = /^This (?<word>\w+)/
226
+ This cat is a pussy&word;.
227
+
217
228
  ! template = "* [&query;](https://www.google.com/search?q=&QUERY;)"
218
229
  ! regx = /^\* (?<query>.*)$/
219
230
  * Grumpy Cat
@@ -232,6 +243,10 @@ The *bold* and "italics" ~strikes~ at _underlined_,
232
243
  while a [link to #Markita](#Markita)
233
244
  sees the `~ code ~ "a*b*c"` to https://github.com.
234
245
  ```
246
+ The inline links with optional title have the following syntax(with no double quotes):
247
+ ```markdown
248
+ [link text](link title)
249
+ ```
235
250
  ### Entity escapes
236
251
 
237
252
  When you want to escape the inline substitutions or HTML tags, use backslash:
@@ -295,7 +310,7 @@ $ GET https://raw.githubusercontent.com/carlosjhr64/markita/main/plug/todotxt.rb
295
310
  ```
296
311
  ## LICENSE
297
312
 
298
- Copyright (c) 2024 CarlosJHR64
313
+ Copyright (c) 2025 CarlosJHR64
299
314
 
300
315
  Permission is hereby granted, free of charge,
301
316
  to any person obtaining a copy of this software and
@@ -318,3 +333,5 @@ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
318
333
  DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
319
334
  TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH
320
335
  THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
336
+
337
+ ## [CREDITS](CREDITS.md)
data/bin/markita CHANGED
@@ -1,4 +1,6 @@
1
1
  #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
2
4
  require 'help_parser'
3
5
  require 'markita'
4
6
 
@@ -11,38 +13,33 @@ OPTIONS = HelpParser[Markita::VERSION, <<~HELP]
11
13
  --port=PORT \t 8080
12
14
  --theme=THEME \t base16.light
13
15
  --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
16
+ --no=PLUGS
23
17
  Types:
24
18
  DIRECTORY /^~?[\\/\\w\\.]+$/
25
19
  BIND /^[\\w\\.]+$/
26
20
  PORT /^\\d+$/
27
21
  IPS /^[\\d\\.\\,]+$/
28
22
  THEME /^[\\w\\.]+$/
23
+ PLUGS /^[\\w\\,]+$/
29
24
  # NOTE:
30
25
  # Assuming site is in ~/vimwiki,
31
26
  # when ~/vimwiki/.valid-id is set with a sha256sum of a password,
32
27
  # that password will restrict the site.
33
28
  # Allowed IPs bypass the need for site password
34
29
  # when the site is accessed from those locations.
30
+ # You can use the --no option to list plugins to disable.
35
31
  HELP
36
32
  begin
33
+ Markita.no.concat OPTIONS.no.split(',').map(&:to_sym) if OPTIONS.no?
37
34
  Markita.run!
38
- rescue LoadError
39
- HelpParser::REDTTY["#{$!.class}: #{$!.message}"]
40
- exit 72
41
- rescue RuntimeError
42
- HelpParser::REDTTY["#{$!.class}: #{$!.message}"]
43
- exit 65
44
- rescue
45
- warn $!.backtrace
46
- HelpParser::REDTTY["#{$!.class}: #{$!.message}"]
47
- exit 70
35
+ rescue LoadError => e
36
+ HelpParser::REDTTY["#{e.class}: #{e.message}"]
37
+ exit 72 # EX_OSFILE
38
+ rescue RuntimeError => e
39
+ HelpParser::REDTTY["#{e.class}: #{e.message}"]
40
+ exit 65 # EX_DATAERR: generic runtime error raised, usually due to user error.
41
+ rescue StandardError => e
42
+ warn e.backtrace
43
+ HelpParser::REDTTY["#{e.class}: #{e.message}"]
44
+ exit 70 # EX_SOFTWARE
48
45
  end
data/lib/markita/base.rb CHANGED
@@ -1,40 +1,47 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Markita namespace
1
4
  module Markita
2
- class Base < Sinatra::Base
3
- set sessions: true
4
- set bind: OPTIONS.bind || BIND
5
- set port: OPTIONS.port || PORT
6
- set server: SERVER
7
- set server_settings: SERVER_SETTINGS if SERVER_SETTINGS
5
+ # Base class of the Sinatra Markita application
6
+ class Base < Sinatra::Base
7
+ set sessions: true
8
+ set bind: BIND
9
+ set port: PORT
10
+ set server: SERVER
11
+ set server_settings: SERVER_SETTINGS if SERVER_SETTINGS
8
12
 
9
- def self.run!
10
- super {SERVER_CONFIG[_1]}
11
- end
13
+ def self.run!
14
+ super { SERVER_CONFIG[it] }
15
+ end
12
16
 
13
- get PAGE_KEY do |key|
14
- filepath = File.join ROOT, key+MDX
15
- raise Sinatra::NotFound unless File.exist? filepath
16
- Markdown.new(key).filepath filepath
17
- end
17
+ get PAGE_KEY do |key|
18
+ filepath = File.join ROOT, key + MDX
19
+ raise Sinatra::NotFound unless File.exist? filepath
18
20
 
19
- get SEND_FILE do |path|
20
- pass unless params.length==1 &&
21
- (filepath=File.join ROOT, path) &&
22
- File.exist?(filepath)
23
- send_file filepath
24
- end
21
+ Markdown.new(key).filepath filepath
22
+ end
25
23
 
26
- get '/' do
27
- filepath = File.join ROOT, INDEX+MDX
28
- if File.exist? filepath
29
- Markdown.new(INDEX).filepath filepath
30
- else
31
- redirect '/about.html' unless OPTIONS.no_about
32
- raise Sinatra::NotFound
24
+ # For the server to send a static file, the request may only specify a path
25
+ # (no query string) and the file must exist... Else, it passes.
26
+ get SEND_FILE do |path|
27
+ pass unless params.length == 1 &&
28
+ (filepath = File.join ROOT, path) &&
29
+ File.exist?(filepath)
30
+ send_file filepath
31
+ end
32
+
33
+ get '/' do
34
+ filepath = File.join ROOT, INDEX + MDX
35
+ if File.exist? filepath
36
+ Markdown.new(INDEX).filepath filepath
37
+ else
38
+ redirect '/about.html' unless Markita.no.include? :about
39
+ raise Sinatra::NotFound
40
+ end
33
41
  end
34
- end
35
42
 
36
- not_found do
37
- NOT_FOUND
43
+ not_found do
44
+ NOT_FOUND
45
+ end
38
46
  end
39
47
  end
40
- end
@@ -1,43 +1,52 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Markita namespace
4
+ # :reek:TooManyConstants because it's a configuration file!
1
5
  module Markita
2
6
  HEADER_LINKS = ''
3
7
  NAVIGATION = ''
4
8
 
5
- BIND = '0.0.0.0'
6
- PORT = '8080'
9
+ BIND = OPTIONS.bind || '0.0.0.0'
10
+ PORT = OPTIONS.port || '8080'
7
11
  SERVER = 'webrick'
8
12
 
9
13
  MDX = '.md'
10
14
  INDEX = 'index'
11
15
 
12
16
  ROOT = File.expand_path OPTIONS.root || '~/vimwiki'
13
- raise 'Missing site root directory: '+ROOT unless File.directory? ROOT
14
-
15
- SSL_CERTIFICATE = File.join(ROOT, '.cert.crt')
16
- SSL_PRIVATE_KEY = File.join(ROOT, '.pkey.pem')
17
-
18
- SERVER_SETTINGS = [SSL_CERTIFICATE, SSL_PRIVATE_KEY].all?{File.exist?_1} ?
19
- { SSLEnable: true,
20
- SSLVerifyClient: OpenSSL::SSL::VERIFY_NONE,
21
- SSLCertificate: OpenSSL::X509::Certificate.new(File.read SSL_CERTIFICATE),
22
- SSLPrivateKey: OpenSSL::PKey::RSA.new(File.read SSL_PRIVATE_KEY) } : nil
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
23
34
 
24
35
  SERVER_CONFIG = lambda do |server|
25
- puts "#{$0}-#{VERSION}"
26
- puts "Sinatra-#{Sinatra::VERSION} using #{server.class}"
36
+ puts "#{$PROGRAM_NAME}-#{VERSION}".blue
37
+ puts "Sinatra-#{Sinatra::VERSION} using #{server.class}".blue
27
38
  end
28
39
 
29
40
  APPDIR = File.dirname __dir__, 2
30
41
  APPDATA = File.join APPDIR, 'data'
31
42
 
32
43
  PATH = lambda do |basename|
33
- [ROOT, APPDATA].map{ File.join _1, basename}.detect{ File.exist? _1}
44
+ [ROOT, APPDATA].map { File.join it, basename }.detect { File.exist? it }
34
45
  end
35
46
 
36
47
  NOT_FOUND = File.read PATH['not_found.html']
37
48
 
38
- EMOJIS = Hash[*File.read(PATH['emojis.tsv']).split(/\s+/)]
39
-
40
- PAGE_KEY = %r{/(\w[\w/-]*\w)}
49
+ PAGE_KEY = %r{/(\w[\w/-]*\w)} # Note that it starts with a slash
41
50
  SEND_FILE = %r{/(\w[\w/-]*\w\.\w+)}
42
51
 
43
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
- module HTML
3
- def self.header(title)
4
- <<~HEADER
5
- <!DOCTYPE html>
6
- <html>
7
- <head>
8
- <title>#{title}</title>#{HEADER_LINKS}
9
- </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
- def self.navigation
15
- NAVIGATION
16
- end
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
- def self.footer
19
- <<~FOOTER
20
- </body>
21
- </html>
22
- FOOTER
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
- end
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,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 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
+ # rubocop:disable Lint/UselessAssignment
24
+ def blockquote
25
+ return false unless (level, quote = Blockquote.level_quote(@line))
26
+
27
+ @html << "<blockquote#{@attributes.shift}>\n"
28
+ current = level
29
+ while current.eql?(level)
30
+ @html << "#{inline(quote)}\n"
31
+ # `quote` is being used... Code is just gnarly.
32
+ current, quote = Blockquote.level_quote(line_gets)
33
+ next unless current&.>(level)
34
+
35
+ blockquote
36
+ level, quote = Blockquote.level_quote(@line)
37
+ end
38
+ @html << "</blockquote>\n"
39
+ true
40
+ end
41
+ # rubocop:enable Lint/UselessAssignment
42
+ # rubocop:enable Metrics/MethodLength
43
+ end
44
+ 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+(\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