madness 0.2.0 → 0.2.1
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/app/styles/_anchor.scss +15 -15
- data/app/styles/_breadcrumbs.scss +8 -8
- data/app/styles/_code.scss +54 -54
- data/app/styles/_coderay.scss +9 -9
- data/app/styles/_general.scss +33 -33
- data/app/styles/_image.scss +7 -7
- data/app/styles/_keyboard.scss +14 -14
- data/app/styles/_line.scss +28 -28
- data/app/styles/_list.scss +44 -44
- data/app/styles/_manifest.scss +14 -14
- data/app/styles/_nav.scss +35 -35
- data/app/styles/_search.scss +24 -24
- data/app/styles/_table.scss +28 -28
- data/app/styles/_typography.scss +62 -62
- data/app/styles/main.scss +28 -28
- data/app/views/_breadcrumbs.slim +8 -8
- data/app/views/_content.slim +6 -6
- data/app/views/_index_nav.slim +5 -5
- data/app/views/_nav.slim +11 -11
- data/app/views/document.slim +11 -11
- data/app/views/layout.slim +7 -7
- data/app/views/search.slim +25 -25
- data/lib/madness.rb +1 -1
- data/lib/madness/breadcrumbs.rb +36 -36
- data/lib/madness/command_line.rb +77 -77
- data/lib/madness/docopt.txt +40 -40
- data/lib/madness/document.rb +98 -98
- data/lib/madness/navigation.rb +60 -60
- data/lib/madness/search.rb +63 -63
- data/lib/madness/server.rb +39 -39
- data/lib/madness/server_base.rb +36 -36
- data/lib/madness/server_helper.rb +21 -21
- data/lib/madness/settings.rb +65 -65
- data/lib/madness/version.rb +1 -1
- metadata +3 -4
data/app/views/document.slim
CHANGED
@@ -1,11 +1,11 @@
|
|
1
|
-
== slim :_nav, locals: { nav: nav }
|
2
|
-
|
3
|
-
.main
|
4
|
-
== slim :_breadcrumbs, locals: { breadcrumbs: breadcrumbs }
|
5
|
-
== slim :_content, locals: { nav: nav, content: content}
|
6
|
-
|
7
|
-
- unless type == :file
|
8
|
-
- unless type == :empty
|
9
|
-
hr
|
10
|
-
== slim :_index_nav, locals: { nav: nav }
|
11
|
-
|
1
|
+
== slim :_nav, locals: { nav: nav }
|
2
|
+
|
3
|
+
.main
|
4
|
+
== slim :_breadcrumbs, locals: { breadcrumbs: breadcrumbs }
|
5
|
+
== slim :_content, locals: { nav: nav, content: content}
|
6
|
+
|
7
|
+
- unless type == :file
|
8
|
+
- unless type == :empty
|
9
|
+
hr
|
10
|
+
== slim :_index_nav, locals: { nav: nav }
|
11
|
+
|
data/app/views/layout.slim
CHANGED
@@ -1,8 +1,8 @@
|
|
1
|
-
doctype html
|
2
|
-
|
3
|
-
head
|
4
|
-
title = locals[:title]
|
5
|
-
link href='/css/main.css' rel='stylesheet' type='text/css'
|
6
|
-
|
7
|
-
body
|
1
|
+
doctype html
|
2
|
+
|
3
|
+
head
|
4
|
+
title = locals[:title]
|
5
|
+
link href='/css/main.css' rel='stylesheet' type='text/css'
|
6
|
+
|
7
|
+
body
|
8
8
|
== yield
|
data/app/views/search.slim
CHANGED
@@ -1,25 +1,25 @@
|
|
1
|
-
== slim :_nav, locals: { nav: nav }
|
2
|
-
|
3
|
-
.main
|
4
|
-
h1 Search
|
5
|
-
|
6
|
-
form.search-form action="/_search" method="get"
|
7
|
-
input.search-field type="text" name="q" value="#{params[:q]}" placeholder="Enter search query" autofocus=true
|
8
|
-
input type="submit" value="Search" style='display:none'
|
9
|
-
|
10
|
-
hr
|
11
|
-
|
12
|
-
- if results
|
13
|
-
- results.each_with_index do |result, index|
|
14
|
-
h4
|
15
|
-
= index+1
|
16
|
-
= ". "
|
17
|
-
a href="#{result[:file]}" = result[:label]
|
18
|
-
|
19
|
-
- if result[:highlights]
|
20
|
-
- result[:highlights].each do |highlight|
|
21
|
-
pre.search-excerpt == highlight
|
22
|
-
- else
|
23
|
-
p.quiet No excerpt
|
24
|
-
|
25
|
-
|
1
|
+
== slim :_nav, locals: { nav: nav }
|
2
|
+
|
3
|
+
.main
|
4
|
+
h1 Search
|
5
|
+
|
6
|
+
form.search-form action="/_search" method="get"
|
7
|
+
input.search-field type="text" name="q" value="#{params[:q]}" placeholder="Enter search query" autofocus=true
|
8
|
+
input type="submit" value="Search" style='display:none'
|
9
|
+
|
10
|
+
hr
|
11
|
+
|
12
|
+
- if results
|
13
|
+
- results.each_with_index do |result, index|
|
14
|
+
h4
|
15
|
+
= index+1
|
16
|
+
= ". "
|
17
|
+
a href="#{result[:file]}" = result[:label]
|
18
|
+
|
19
|
+
- if result[:highlights]
|
20
|
+
- result[:highlights].each do |highlight|
|
21
|
+
pre.search-excerpt == highlight
|
22
|
+
- else
|
23
|
+
p.quiet No excerpt
|
24
|
+
|
25
|
+
|
data/lib/madness.rb
CHANGED
data/lib/madness/breadcrumbs.rb
CHANGED
@@ -1,36 +1,36 @@
|
|
1
|
-
module Madness
|
2
|
-
|
3
|
-
# Handle breadcumbs generation by converting a path to an array
|
4
|
-
# of links
|
5
|
-
class Breadcrumbs
|
6
|
-
attr_reader :path
|
7
|
-
|
8
|
-
def initialize(path)
|
9
|
-
@path = path
|
10
|
-
end
|
11
|
-
|
12
|
-
def links
|
13
|
-
path == "" ? [] : get_breadcrumbs
|
14
|
-
end
|
15
|
-
|
16
|
-
private
|
17
|
-
|
18
|
-
def get_breadcrumbs
|
19
|
-
home = OpenStruct.new({ label: "Home", href: '/' })
|
20
|
-
result = breadcrumbs_maker(path).reverse.unshift home
|
21
|
-
result.last.last = true
|
22
|
-
result
|
23
|
-
end
|
24
|
-
|
25
|
-
def breadcrumbs_maker(partial_path)
|
26
|
-
parent, basename = File.split partial_path
|
27
|
-
item = OpenStruct.new({
|
28
|
-
label: basename.tr('-', ' '),
|
29
|
-
href: "/#{partial_path}" }
|
30
|
-
)
|
31
|
-
result = [item]
|
32
|
-
result += breadcrumbs_maker parent unless parent == '.'
|
33
|
-
result
|
34
|
-
end
|
35
|
-
end
|
36
|
-
end
|
1
|
+
module Madness
|
2
|
+
|
3
|
+
# Handle breadcumbs generation by converting a path to an array
|
4
|
+
# of links
|
5
|
+
class Breadcrumbs
|
6
|
+
attr_reader :path
|
7
|
+
|
8
|
+
def initialize(path)
|
9
|
+
@path = path
|
10
|
+
end
|
11
|
+
|
12
|
+
def links
|
13
|
+
path == "" ? [] : get_breadcrumbs
|
14
|
+
end
|
15
|
+
|
16
|
+
private
|
17
|
+
|
18
|
+
def get_breadcrumbs
|
19
|
+
home = OpenStruct.new({ label: "Home", href: '/' })
|
20
|
+
result = breadcrumbs_maker(path).reverse.unshift home
|
21
|
+
result.last.last = true
|
22
|
+
result
|
23
|
+
end
|
24
|
+
|
25
|
+
def breadcrumbs_maker(partial_path)
|
26
|
+
parent, basename = File.split partial_path
|
27
|
+
item = OpenStruct.new({
|
28
|
+
label: basename.tr('-', ' '),
|
29
|
+
href: "/#{partial_path}" }
|
30
|
+
)
|
31
|
+
result = [item]
|
32
|
+
result += breadcrumbs_maker parent unless parent == '.'
|
33
|
+
result
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
data/lib/madness/command_line.rb
CHANGED
@@ -1,77 +1,77 @@
|
|
1
|
-
module Madness
|
2
|
-
|
3
|
-
# Handle command line execution. Used by bin/madness.
|
4
|
-
class CommandLine
|
5
|
-
include Singleton
|
6
|
-
include Colsole
|
7
|
-
|
8
|
-
# Launch the server
|
9
|
-
def execute(argv=[])
|
10
|
-
launch_server_with_options argv
|
11
|
-
end
|
12
|
-
|
13
|
-
private
|
14
|
-
|
15
|
-
# Execute the docopt engine to parse the options and then launch the
|
16
|
-
# server.
|
17
|
-
def launch_server_with_options(argv)
|
18
|
-
doc = File.read File.expand_path('docopt.txt', __dir__)
|
19
|
-
begin
|
20
|
-
args = Docopt::docopt(doc, argv: argv, version: VERSION)
|
21
|
-
set_config args
|
22
|
-
|
23
|
-
build_index if config.index
|
24
|
-
launch_server unless args['--and-quit']
|
25
|
-
|
26
|
-
rescue Docopt::Exit => e
|
27
|
-
puts e.message
|
28
|
-
end
|
29
|
-
end
|
30
|
-
|
31
|
-
# Launch the server, but not before doing some checks and making sure
|
32
|
-
# we ask it to "prepare". This will set the server options such as port
|
33
|
-
# and static files folder.
|
34
|
-
def launch_server
|
35
|
-
unless File.directory? config.path
|
36
|
-
STDERR.puts "Invalid path (#{config.path})"
|
37
|
-
return
|
38
|
-
end
|
39
|
-
|
40
|
-
show_status
|
41
|
-
Server.prepare
|
42
|
-
Server.run!
|
43
|
-
end
|
44
|
-
|
45
|
-
# Get the arguments as provided by docopt, and set them to our own
|
46
|
-
# config object.
|
47
|
-
def set_config(args)
|
48
|
-
config.path = args['PATH'] if args['PATH']
|
49
|
-
config.port = args['--port'] if args['--port']
|
50
|
-
config.bind = args['--bind'] if args['--bind']
|
51
|
-
config.autoh1 = false if args['--no-auto-h1']
|
52
|
-
config.highlighter = false if args['--no-syntax']
|
53
|
-
config.line_numbers = false if args['--no-line-numbers']
|
54
|
-
config.index = true if args['--index']
|
55
|
-
end
|
56
|
-
|
57
|
-
# Say hello to everybody when the server starts, showing the known
|
58
|
-
# config.
|
59
|
-
def show_status
|
60
|
-
say_status :start, 'the madness'
|
61
|
-
say_status :listen, "#{config.bind}:#{config.port}", :txtblu
|
62
|
-
say_status :path, File.realpath(config.path), :txtblu
|
63
|
-
say_status :use, config.filename if config.file_exist?
|
64
|
-
say "-" * 40
|
65
|
-
end
|
66
|
-
|
67
|
-
def build_index
|
68
|
-
say_status :start, 'indexing'
|
69
|
-
Search.new.build_index
|
70
|
-
say_status :done, 'indexing'
|
71
|
-
end
|
72
|
-
|
73
|
-
def config
|
74
|
-
@config ||= Settings.instance
|
75
|
-
end
|
76
|
-
end
|
77
|
-
end
|
1
|
+
module Madness
|
2
|
+
|
3
|
+
# Handle command line execution. Used by bin/madness.
|
4
|
+
class CommandLine
|
5
|
+
include Singleton
|
6
|
+
include Colsole
|
7
|
+
|
8
|
+
# Launch the server
|
9
|
+
def execute(argv=[])
|
10
|
+
launch_server_with_options argv
|
11
|
+
end
|
12
|
+
|
13
|
+
private
|
14
|
+
|
15
|
+
# Execute the docopt engine to parse the options and then launch the
|
16
|
+
# server.
|
17
|
+
def launch_server_with_options(argv)
|
18
|
+
doc = File.read File.expand_path('docopt.txt', __dir__)
|
19
|
+
begin
|
20
|
+
args = Docopt::docopt(doc, argv: argv, version: VERSION)
|
21
|
+
set_config args
|
22
|
+
|
23
|
+
build_index if config.index
|
24
|
+
launch_server unless args['--and-quit']
|
25
|
+
|
26
|
+
rescue Docopt::Exit => e
|
27
|
+
puts e.message
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
# Launch the server, but not before doing some checks and making sure
|
32
|
+
# we ask it to "prepare". This will set the server options such as port
|
33
|
+
# and static files folder.
|
34
|
+
def launch_server
|
35
|
+
unless File.directory? config.path
|
36
|
+
STDERR.puts "Invalid path (#{config.path})"
|
37
|
+
return
|
38
|
+
end
|
39
|
+
|
40
|
+
show_status
|
41
|
+
Server.prepare
|
42
|
+
Server.run!
|
43
|
+
end
|
44
|
+
|
45
|
+
# Get the arguments as provided by docopt, and set them to our own
|
46
|
+
# config object.
|
47
|
+
def set_config(args)
|
48
|
+
config.path = args['PATH'] if args['PATH']
|
49
|
+
config.port = args['--port'] if args['--port']
|
50
|
+
config.bind = args['--bind'] if args['--bind']
|
51
|
+
config.autoh1 = false if args['--no-auto-h1']
|
52
|
+
config.highlighter = false if args['--no-syntax']
|
53
|
+
config.line_numbers = false if args['--no-line-numbers']
|
54
|
+
config.index = true if args['--index']
|
55
|
+
end
|
56
|
+
|
57
|
+
# Say hello to everybody when the server starts, showing the known
|
58
|
+
# config.
|
59
|
+
def show_status
|
60
|
+
say_status :start, 'the madness'
|
61
|
+
say_status :listen, "#{config.bind}:#{config.port}", :txtblu
|
62
|
+
say_status :path, File.realpath(config.path), :txtblu
|
63
|
+
say_status :use, config.filename if config.file_exist?
|
64
|
+
say "-" * 40
|
65
|
+
end
|
66
|
+
|
67
|
+
def build_index
|
68
|
+
say_status :start, 'indexing'
|
69
|
+
Search.new.build_index
|
70
|
+
say_status :done, 'indexing'
|
71
|
+
end
|
72
|
+
|
73
|
+
def config
|
74
|
+
@config ||= Settings.instance
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
data/lib/madness/docopt.txt
CHANGED
@@ -1,40 +1,40 @@
|
|
1
|
-
Madness
|
2
|
-
|
3
|
-
Usage:
|
4
|
-
madness [PATH] [options]
|
5
|
-
madness (-h|--help|--version)
|
6
|
-
|
7
|
-
Parameters:
|
8
|
-
PATH:
|
9
|
-
Optional path to the markdown directory.
|
10
|
-
|
11
|
-
Options:
|
12
|
-
-p, --port <number>
|
13
|
-
Set server port number.
|
14
|
-
|
15
|
-
-b, --bind <address>
|
16
|
-
Set server listen address.
|
17
|
-
|
18
|
-
--no-auto-h1
|
19
|
-
By default, if a markdown document does not start with an H1 caption,
|
20
|
-
it will be added automatically based on the file name. To disable this
|
21
|
-
behavior, use --no-auto-h1.
|
22
|
-
|
23
|
-
--no-syntax
|
24
|
-
Disable code syntax highlighting.
|
25
|
-
|
26
|
-
--no-line-numbers
|
27
|
-
Disable line numbering for syntax highlighter.
|
28
|
-
|
29
|
-
--index
|
30
|
-
Build or rebuild the index for the search page.
|
31
|
-
|
32
|
-
--and-quit
|
33
|
-
Quit after building the index (applicable only with --index).
|
34
|
-
|
35
|
-
Examples:
|
36
|
-
madness
|
37
|
-
madness docs
|
38
|
-
madness docs --no-auto-h1 -p 4567
|
39
|
-
madness --index --and-quit
|
40
|
-
|
1
|
+
Madness
|
2
|
+
|
3
|
+
Usage:
|
4
|
+
madness [PATH] [options]
|
5
|
+
madness (-h|--help|--version)
|
6
|
+
|
7
|
+
Parameters:
|
8
|
+
PATH:
|
9
|
+
Optional path to the markdown directory.
|
10
|
+
|
11
|
+
Options:
|
12
|
+
-p, --port <number>
|
13
|
+
Set server port number.
|
14
|
+
|
15
|
+
-b, --bind <address>
|
16
|
+
Set server listen address.
|
17
|
+
|
18
|
+
--no-auto-h1
|
19
|
+
By default, if a markdown document does not start with an H1 caption,
|
20
|
+
it will be added automatically based on the file name. To disable this
|
21
|
+
behavior, use --no-auto-h1.
|
22
|
+
|
23
|
+
--no-syntax
|
24
|
+
Disable code syntax highlighting.
|
25
|
+
|
26
|
+
--no-line-numbers
|
27
|
+
Disable line numbering for syntax highlighter.
|
28
|
+
|
29
|
+
--index
|
30
|
+
Build or rebuild the index for the search page.
|
31
|
+
|
32
|
+
--and-quit
|
33
|
+
Quit after building the index (applicable only with --index).
|
34
|
+
|
35
|
+
Examples:
|
36
|
+
madness
|
37
|
+
madness docs
|
38
|
+
madness docs --no-auto-h1 -p 4567
|
39
|
+
madness --index --and-quit
|
40
|
+
|
data/lib/madness/document.rb
CHANGED
@@ -1,98 +1,98 @@
|
|
1
|
-
module Madness
|
2
|
-
|
3
|
-
# Handle a single markdown document.
|
4
|
-
class Document
|
5
|
-
include ServerHelper
|
6
|
-
|
7
|
-
attr_reader :file, :dir, :path, :type
|
8
|
-
|
9
|
-
# At initialization, we handle three file "types":
|
10
|
-
# :readme - in case the path is a directory, then the only file we
|
11
|
-
# MAY show, is the README.md in it
|
12
|
-
# :file - in case the path is a *.md file
|
13
|
-
# :empty - in any other case, we don't know.
|
14
|
-
def initialize(path)
|
15
|
-
@path = path
|
16
|
-
|
17
|
-
base = path.empty? ? docroot : "#{docroot}/#{path}"
|
18
|
-
|
19
|
-
if File.directory? base
|
20
|
-
@file = "#{base}/README.md"
|
21
|
-
@dir = base
|
22
|
-
@type = :readme
|
23
|
-
elsif File.exist? "#{base}.md"
|
24
|
-
@file = "#{base}.md"
|
25
|
-
@dir = File.dirname file
|
26
|
-
@type = :file
|
27
|
-
else
|
28
|
-
@file = ''
|
29
|
-
@dir = docroot
|
30
|
-
@type = :empty
|
31
|
-
end
|
32
|
-
end
|
33
|
-
|
34
|
-
# Return the HTML for that document
|
35
|
-
def content
|
36
|
-
@content ||= content!
|
37
|
-
end
|
38
|
-
|
39
|
-
# Return the HTML for that document, force re-read.
|
40
|
-
def content!
|
41
|
-
if File.exist?(file)
|
42
|
-
markdown_to_html
|
43
|
-
else
|
44
|
-
@type = :empty
|
45
|
-
""
|
46
|
-
end
|
47
|
-
end
|
48
|
-
|
49
|
-
# Return a reasonable HTML title for the file or directory
|
50
|
-
def title
|
51
|
-
if file =~ /README.md/
|
52
|
-
result = File.basename File.dirname(file)
|
53
|
-
else
|
54
|
-
result = File.basename(file,'.md')
|
55
|
-
end
|
56
|
-
result.tr '-', ' '
|
57
|
-
end
|
58
|
-
|
59
|
-
private
|
60
|
-
|
61
|
-
# Convert markdown to HTML, wit hsome additional processing:
|
62
|
-
# 1. Syntax highilghting
|
63
|
-
# 2. Prepend H1 if needed
|
64
|
-
def markdown_to_html
|
65
|
-
html = RDiscount.new(File.read file).to_html
|
66
|
-
html = syntax_highlight(html) if config.highlighter
|
67
|
-
html = prepend_h1(html) if config.autoh1
|
68
|
-
html
|
69
|
-
end
|
70
|
-
|
71
|
-
# If the document does not start with an H1 tag, add it.
|
72
|
-
def prepend_h1(html)
|
73
|
-
unless html[0..3] == "<h1>"
|
74
|
-
html = "<h1>#{title}</h1>\n#{html}"
|
75
|
-
end
|
76
|
-
html
|
77
|
-
end
|
78
|
-
|
79
|
-
# Apply syntax highlighting with CodeRay. This will parse for any
|
80
|
-
# <code class='LANG'> sections in the HTML, pass it to CodeRay for
|
81
|
-
# highlighting.
|
82
|
-
# Since CodeRay adds another HTML escaping, on top of what RDiscount
|
83
|
-
# does, we unescape it before passing it to CodeRay.
|
84
|
-
#
|
85
|
-
# Open StackOverflow question:
|
86
|
-
# http://stackoverflow.com/questions/37771279/prevent-double-escaping-with-coderay-and-rdiscount
|
87
|
-
def syntax_highlight(html)
|
88
|
-
line_numbers = config.line_numbers ? :table : nil
|
89
|
-
opts = { css: :style, wrap: nil, line_numbers: line_numbers }
|
90
|
-
html.gsub(/\<code class="(.+?)"\>(.+?)\<\/code\>/m) do
|
91
|
-
lang, code = $1, $2
|
92
|
-
code = CGI.unescapeHTML code
|
93
|
-
CodeRay.scan(code, lang).html opts
|
94
|
-
end
|
95
|
-
end
|
96
|
-
end
|
97
|
-
end
|
98
|
-
|
1
|
+
module Madness
|
2
|
+
|
3
|
+
# Handle a single markdown document.
|
4
|
+
class Document
|
5
|
+
include ServerHelper
|
6
|
+
|
7
|
+
attr_reader :file, :dir, :path, :type
|
8
|
+
|
9
|
+
# At initialization, we handle three file "types":
|
10
|
+
# :readme - in case the path is a directory, then the only file we
|
11
|
+
# MAY show, is the README.md in it
|
12
|
+
# :file - in case the path is a *.md file
|
13
|
+
# :empty - in any other case, we don't know.
|
14
|
+
def initialize(path)
|
15
|
+
@path = path
|
16
|
+
|
17
|
+
base = path.empty? ? docroot : "#{docroot}/#{path}"
|
18
|
+
|
19
|
+
if File.directory? base
|
20
|
+
@file = "#{base}/README.md"
|
21
|
+
@dir = base
|
22
|
+
@type = :readme
|
23
|
+
elsif File.exist? "#{base}.md"
|
24
|
+
@file = "#{base}.md"
|
25
|
+
@dir = File.dirname file
|
26
|
+
@type = :file
|
27
|
+
else
|
28
|
+
@file = ''
|
29
|
+
@dir = docroot
|
30
|
+
@type = :empty
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
# Return the HTML for that document
|
35
|
+
def content
|
36
|
+
@content ||= content!
|
37
|
+
end
|
38
|
+
|
39
|
+
# Return the HTML for that document, force re-read.
|
40
|
+
def content!
|
41
|
+
if File.exist?(file)
|
42
|
+
markdown_to_html
|
43
|
+
else
|
44
|
+
@type = :empty
|
45
|
+
""
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
# Return a reasonable HTML title for the file or directory
|
50
|
+
def title
|
51
|
+
if file =~ /README.md/
|
52
|
+
result = File.basename File.dirname(file)
|
53
|
+
else
|
54
|
+
result = File.basename(file,'.md')
|
55
|
+
end
|
56
|
+
result.tr '-', ' '
|
57
|
+
end
|
58
|
+
|
59
|
+
private
|
60
|
+
|
61
|
+
# Convert markdown to HTML, wit hsome additional processing:
|
62
|
+
# 1. Syntax highilghting
|
63
|
+
# 2. Prepend H1 if needed
|
64
|
+
def markdown_to_html
|
65
|
+
html = RDiscount.new(File.read file).to_html
|
66
|
+
html = syntax_highlight(html) if config.highlighter
|
67
|
+
html = prepend_h1(html) if config.autoh1
|
68
|
+
html
|
69
|
+
end
|
70
|
+
|
71
|
+
# If the document does not start with an H1 tag, add it.
|
72
|
+
def prepend_h1(html)
|
73
|
+
unless html[0..3] == "<h1>"
|
74
|
+
html = "<h1>#{title}</h1>\n#{html}"
|
75
|
+
end
|
76
|
+
html
|
77
|
+
end
|
78
|
+
|
79
|
+
# Apply syntax highlighting with CodeRay. This will parse for any
|
80
|
+
# <code class='LANG'> sections in the HTML, pass it to CodeRay for
|
81
|
+
# highlighting.
|
82
|
+
# Since CodeRay adds another HTML escaping, on top of what RDiscount
|
83
|
+
# does, we unescape it before passing it to CodeRay.
|
84
|
+
#
|
85
|
+
# Open StackOverflow question:
|
86
|
+
# http://stackoverflow.com/questions/37771279/prevent-double-escaping-with-coderay-and-rdiscount
|
87
|
+
def syntax_highlight(html)
|
88
|
+
line_numbers = config.line_numbers ? :table : nil
|
89
|
+
opts = { css: :style, wrap: nil, line_numbers: line_numbers }
|
90
|
+
html.gsub(/\<code class="(.+?)"\>(.+?)\<\/code\>/m) do
|
91
|
+
lang, code = $1, $2
|
92
|
+
code = CGI.unescapeHTML code
|
93
|
+
CodeRay.scan(code, lang).html opts
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|