markita 5.0.241001 → 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.
Files changed (38) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +28 -15
  3. data/bin/markita +16 -19
  4. data/lib/markita/base.rb +38 -31
  5. data/lib/markita/config.rb +27 -18
  6. data/lib/markita/html.rb +35 -20
  7. data/lib/markita/markdown/attributes.rb +23 -0
  8. data/lib/markita/markdown/blockquote.rb +41 -0
  9. data/lib/markita/markdown/code.rb +44 -0
  10. data/lib/markita/markdown/code_block.rb +29 -0
  11. data/lib/markita/markdown/definitions.rb +42 -0
  12. data/lib/markita/markdown/embed.rb +63 -0
  13. data/lib/markita/markdown/empty.rb +22 -0
  14. data/lib/markita/markdown/fold.rb +39 -0
  15. data/lib/markita/markdown/footnotes.rb +28 -0
  16. data/lib/markita/markdown/form.rb +125 -0
  17. data/lib/markita/markdown/heading.rb +33 -0
  18. data/lib/markita/markdown/horizontal_rule.rb +25 -0
  19. data/lib/markita/markdown/image.rb +60 -0
  20. data/lib/markita/markdown/inline.rb +123 -0
  21. data/lib/markita/markdown/list.rb +65 -0
  22. data/lib/markita/markdown/markup.rb +23 -0
  23. data/lib/markita/markdown/script.rb +28 -0
  24. data/lib/markita/markdown/split.rb +38 -0
  25. data/lib/markita/markdown/table.rb +52 -0
  26. data/lib/markita/markdown.rb +51 -475
  27. data/lib/markita/plug/about.rb +28 -17
  28. data/lib/markita/plug/favicon.rb +14 -10
  29. data/lib/markita/plug/highlight.rb +17 -12
  30. data/lib/markita/plug/login.rb +35 -28
  31. data/lib/markita/plug/navigation.rb +4 -1
  32. data/lib/markita/plug/plugs.rb +7 -1
  33. data/lib/markita/plug/readme.rb +8 -4
  34. data/lib/markita/preprocess.rb +52 -23
  35. data/lib/markita/refinement.rb +21 -0
  36. data/lib/markita/requires.rb +29 -0
  37. data/lib/markita.rb +15 -25
  38. metadata +51 -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: 9ed48aca2238e0b8ac390519ddc7d4c0e8e5e6f798b87a7654da9454f5f92cd3
4
+ data.tar.gz: bfec77d804b3e803c282e4581c6ac7008a716ad0c2d91c2e9dca170b9ecb987a
5
5
  SHA512:
6
- metadata.gz: 75a93470a33b67d868ed1fabac90b0d6a111f1f2c3e028534ffdc5ce434d8361103e8fa27249c4f34e347c3de57dc8806bd221351bc8abf75396ad9a1500f8bb
7
- data.tar.gz: d1180313131e3487558c863cdd6817c401e37ddd36bc64ad1821eb082a11c432bed0f0eb055dc34a9bb75c68129a0a109e721bd4132efc072a6ca4583c2d655f
6
+ metadata.gz: 4feb3c5ba26177dc86f27ab90599c120a3d0631f24d5919d28efacb39edd7bbdb5d6a76d9eb28ee852ec0b0bfdfc41ea3097b82f1bdc29d533686f95756bb13f
7
+ data.tar.gz: b8dfe46d0853061fe8d7d8a666e1c102b249a12cd3ad26558b05ebe5893d899b03add66fe8d9da41fd984e27e7d158cb0b69d1967e7fe365f703c2e2ba74ae20
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.250327](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
 
@@ -25,27 +25,21 @@ Options:
25
25
  --port=PORT 8080
26
26
  --theme=THEME base16.light
27
27
  --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
28
+ --no=PLUGS
37
29
  Types:
38
30
  DIRECTORY /^~?[\/\w\.]+$/
39
31
  BIND /^[\w\.]+$/
40
32
  PORT /^\d+$/
41
33
  IPS /^[\d\.\,]+$/
42
34
  THEME /^[\w\.]+$/
35
+ PLUGS /^[\w\,]+$/
43
36
  # NOTE:
44
37
  # Assuming site is in ~/vimwiki,
45
38
  # when ~/vimwiki/.valid-id is set with a sha256sum of a password,
46
39
  # that password will restrict the site.
47
40
  # Allowed IPs bypass the need for site password
48
41
  # when the site is accessed from those locations.
42
+ # You can use the --no option to list plugins to disable.
49
43
  ```
50
44
  ## FEATURES
51
45
 
@@ -58,16 +52,25 @@ Types:
58
52
  * HTML pass through on `/^<.*>$/` lines
59
53
  * And more...
60
54
 
61
- ### Horizontal rule with meta-data
55
+ ### Meta-data
62
56
 
63
- * If `Title` is set via meta-data, the server will set the page's title to that
57
+ * `$key` substitution to its metadata value in text
58
+ * If `Title` is set via meta-data, Javascript will set the page's title to that
64
59
  * One can use numbers to reference long URLs
65
60
  ```markdown
66
- ---
61
+ --- # The hashtag disambiguates the horizontal rule(legal YAML comment).
67
62
  Title: Markita
68
63
  1: https://github.com/carlosjhr64/markita
69
- ---
64
+ name: Don Quixote de la Mancha
65
+ # You can also add to attributes here:
66
+ attributes: style="color: darkgreen;"
67
+ ... # The end marker is needed to end the fold
70
68
  [Markita](1)
69
+ Your name is $name.
70
+ ```
71
+ ### Horizontal rule
72
+ ```markdown
73
+ ---
71
74
  ```
72
75
  ### Attributes
73
76
  ```markdown
@@ -211,9 +214,15 @@ A multi-line form with default entry and hidden field:
211
214
 
212
215
  A selection list:
213
216
  ! Color:[color="Red","White","Blue"]
217
+
218
+ A submit button:
219
+ ! [submit="Go!"]
214
220
  ```
215
221
  ### Template substitutions
216
222
  ```markdown
223
+ ! regx = /^This (?<word>\w+)/
224
+ This cat is a pussy&word;.
225
+
217
226
  ! template = "* [&query;](https://www.google.com/search?q=&QUERY;)"
218
227
  ! regx = /^\* (?<query>.*)$/
219
228
  * Grumpy Cat
@@ -232,6 +241,10 @@ The *bold* and "italics" ~strikes~ at _underlined_,
232
241
  while a [link to #Markita](#Markita)
233
242
  sees the `~ code ~ "a*b*c"` to https://github.com.
234
243
  ```
244
+ The inline links with optional title have the following syntax(with no double quotes):
245
+ ```markdown
246
+ [link text](link title)
247
+ ```
235
248
  ### Entity escapes
236
249
 
237
250
  When you want to escape the inline substitutions or HTML tags, use backslash:
@@ -295,7 +308,7 @@ $ GET https://raw.githubusercontent.com/carlosjhr64/markita/main/plug/todotxt.rb
295
308
  ```
296
309
  ## LICENSE
297
310
 
298
- Copyright (c) 2024 CarlosJHR64
311
+ Copyright (c) 2025 CarlosJHR64
299
312
 
300
313
  Permission is hereby granted, free of charge,
301
314
  to any person obtaining a copy of this software and
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,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