madness 0.9.9 → 1.0.0.rc1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +56 -63
- data/app/public/css/main.css +457 -239
- data/app/public/css/main.css.map +26 -22
- data/app/public/font/fontello.eot +0 -0
- data/app/public/font/fontello.svg +16 -0
- data/app/public/font/fontello.ttf +0 -0
- data/app/public/font/fontello.woff +0 -0
- data/app/public/font/fontello.woff2 +0 -0
- data/app/public/js/clipboard.js +2 -2
- data/app/styles/_anchor.scss +4 -0
- data/app/styles/_code.scss +34 -41
- data/app/styles/{_icons.scss → _fontello.scss} +28 -19
- data/app/styles/_footnotes.scss +6 -0
- data/app/styles/_general.scss +4 -0
- data/app/styles/_manifest.scss +10 -8
- data/app/styles/_nav.scss +1 -11
- data/app/styles/_rouge.scss +213 -0
- data/app/styles/_scrollbar.scss +9 -0
- data/app/styles/main.scss +2 -2
- data/lib/madness/command_line.rb +2 -11
- data/lib/madness/docopt.txt +1 -35
- data/lib/madness/document.rb +5 -110
- data/lib/madness/highlight_renderer.rb +10 -0
- data/lib/madness/markdown_document.rb +103 -0
- data/lib/madness/settings.rb +1 -1
- data/lib/madness/templates/madness.yml +5 -3
- data/lib/madness/version.rb +1 -1
- metadata +46 -48
- data/app/public/fonts/fontello.eot +0 -0
- data/app/public/fonts/fontello.svg +0 -16
- data/app/public/fonts/fontello.ttf +0 -0
- data/app/public/fonts/fontello.woff +0 -0
- data/app/public/fonts/fontello.woff2 +0 -0
- data/app/styles/_coderay.scss +0 -37
@@ -0,0 +1,213 @@
|
|
1
|
+
.highlight table td { padding: 5px; }
|
2
|
+
.highlight table pre { margin: 0; }
|
3
|
+
.highlight .cm {
|
4
|
+
color: #999988;
|
5
|
+
font-style: italic;
|
6
|
+
}
|
7
|
+
.highlight .cp {
|
8
|
+
color: #999999;
|
9
|
+
font-weight: bold;
|
10
|
+
}
|
11
|
+
.highlight .c1 {
|
12
|
+
color: #999988;
|
13
|
+
font-style: italic;
|
14
|
+
}
|
15
|
+
.highlight .cs {
|
16
|
+
color: #999999;
|
17
|
+
font-weight: bold;
|
18
|
+
font-style: italic;
|
19
|
+
}
|
20
|
+
.highlight .c, .highlight .ch, .highlight .cd, .highlight .cpf {
|
21
|
+
color: #999988;
|
22
|
+
font-style: italic;
|
23
|
+
}
|
24
|
+
.highlight .err {
|
25
|
+
color: #a61717;
|
26
|
+
background-color: #e3d2d2;
|
27
|
+
}
|
28
|
+
.highlight .gd {
|
29
|
+
color: #000000;
|
30
|
+
background-color: #ffdddd;
|
31
|
+
}
|
32
|
+
.highlight .ge {
|
33
|
+
color: #000000;
|
34
|
+
font-style: italic;
|
35
|
+
}
|
36
|
+
.highlight .gr {
|
37
|
+
color: #aa0000;
|
38
|
+
}
|
39
|
+
.highlight .gh {
|
40
|
+
color: #999999;
|
41
|
+
}
|
42
|
+
.highlight .gi {
|
43
|
+
color: #000000;
|
44
|
+
background-color: #ddffdd;
|
45
|
+
}
|
46
|
+
.highlight .go {
|
47
|
+
color: #888888;
|
48
|
+
}
|
49
|
+
.highlight .gp {
|
50
|
+
color: #555555;
|
51
|
+
}
|
52
|
+
.highlight .gs {
|
53
|
+
font-weight: bold;
|
54
|
+
}
|
55
|
+
.highlight .gu {
|
56
|
+
color: #aaaaaa;
|
57
|
+
}
|
58
|
+
.highlight .gt {
|
59
|
+
color: #aa0000;
|
60
|
+
}
|
61
|
+
.highlight .kc {
|
62
|
+
color: #000000;
|
63
|
+
font-weight: bold;
|
64
|
+
}
|
65
|
+
.highlight .kd {
|
66
|
+
color: #000000;
|
67
|
+
font-weight: bold;
|
68
|
+
}
|
69
|
+
.highlight .kn {
|
70
|
+
color: #000000;
|
71
|
+
font-weight: bold;
|
72
|
+
}
|
73
|
+
.highlight .kp {
|
74
|
+
color: #000000;
|
75
|
+
font-weight: bold;
|
76
|
+
}
|
77
|
+
.highlight .kr {
|
78
|
+
color: #000000;
|
79
|
+
font-weight: bold;
|
80
|
+
}
|
81
|
+
.highlight .kt {
|
82
|
+
color: #445588;
|
83
|
+
font-weight: bold;
|
84
|
+
}
|
85
|
+
.highlight .k, .highlight .kv {
|
86
|
+
color: #000000;
|
87
|
+
font-weight: bold;
|
88
|
+
}
|
89
|
+
.highlight .mf {
|
90
|
+
color: #009999;
|
91
|
+
}
|
92
|
+
.highlight .mh {
|
93
|
+
color: #009999;
|
94
|
+
}
|
95
|
+
.highlight .il {
|
96
|
+
color: #009999;
|
97
|
+
}
|
98
|
+
.highlight .mi {
|
99
|
+
color: #009999;
|
100
|
+
}
|
101
|
+
.highlight .mo {
|
102
|
+
color: #009999;
|
103
|
+
}
|
104
|
+
.highlight .m, .highlight .mb, .highlight .mx {
|
105
|
+
color: #009999;
|
106
|
+
}
|
107
|
+
.highlight .sa {
|
108
|
+
color: #000000;
|
109
|
+
font-weight: bold;
|
110
|
+
}
|
111
|
+
.highlight .sb {
|
112
|
+
color: #d14;
|
113
|
+
}
|
114
|
+
.highlight .sc {
|
115
|
+
color: #d14;
|
116
|
+
}
|
117
|
+
.highlight .sd {
|
118
|
+
color: #d14;
|
119
|
+
}
|
120
|
+
.highlight .s2 {
|
121
|
+
color: #d14;
|
122
|
+
}
|
123
|
+
.highlight .se {
|
124
|
+
color: #d14;
|
125
|
+
}
|
126
|
+
.highlight .sh {
|
127
|
+
color: #d14;
|
128
|
+
}
|
129
|
+
.highlight .si {
|
130
|
+
color: #d14;
|
131
|
+
}
|
132
|
+
.highlight .sx {
|
133
|
+
color: #d14;
|
134
|
+
}
|
135
|
+
.highlight .sr {
|
136
|
+
color: #009926;
|
137
|
+
}
|
138
|
+
.highlight .s1 {
|
139
|
+
color: #d14;
|
140
|
+
}
|
141
|
+
.highlight .ss {
|
142
|
+
color: #990073;
|
143
|
+
}
|
144
|
+
.highlight .s, .highlight .dl {
|
145
|
+
color: #d14;
|
146
|
+
}
|
147
|
+
.highlight .na {
|
148
|
+
color: #008080;
|
149
|
+
}
|
150
|
+
.highlight .bp {
|
151
|
+
color: #999999;
|
152
|
+
}
|
153
|
+
.highlight .nb {
|
154
|
+
color: #0086B3;
|
155
|
+
}
|
156
|
+
.highlight .nc {
|
157
|
+
color: #445588;
|
158
|
+
font-weight: bold;
|
159
|
+
}
|
160
|
+
.highlight .no {
|
161
|
+
color: #008080;
|
162
|
+
}
|
163
|
+
.highlight .nd {
|
164
|
+
color: #3c5d5d;
|
165
|
+
font-weight: bold;
|
166
|
+
}
|
167
|
+
.highlight .ni {
|
168
|
+
color: #800080;
|
169
|
+
}
|
170
|
+
.highlight .ne {
|
171
|
+
color: #990000;
|
172
|
+
font-weight: bold;
|
173
|
+
}
|
174
|
+
.highlight .nf, .highlight .fm {
|
175
|
+
color: #990000;
|
176
|
+
font-weight: bold;
|
177
|
+
}
|
178
|
+
.highlight .nl {
|
179
|
+
color: #990000;
|
180
|
+
font-weight: bold;
|
181
|
+
}
|
182
|
+
.highlight .nn {
|
183
|
+
color: #555555;
|
184
|
+
}
|
185
|
+
.highlight .nt {
|
186
|
+
color: #000080;
|
187
|
+
}
|
188
|
+
.highlight .vc {
|
189
|
+
color: #008080;
|
190
|
+
}
|
191
|
+
.highlight .vg {
|
192
|
+
color: #008080;
|
193
|
+
}
|
194
|
+
.highlight .vi {
|
195
|
+
color: #008080;
|
196
|
+
}
|
197
|
+
.highlight .nv, .highlight .vm {
|
198
|
+
color: #008080;
|
199
|
+
}
|
200
|
+
.highlight .ow {
|
201
|
+
color: #000000;
|
202
|
+
font-weight: bold;
|
203
|
+
}
|
204
|
+
.highlight .o {
|
205
|
+
color: #000000;
|
206
|
+
font-weight: bold;
|
207
|
+
}
|
208
|
+
.highlight .w {
|
209
|
+
color: #bbbbbb;
|
210
|
+
}
|
211
|
+
.highlight {
|
212
|
+
background-color: #f8f8f8;
|
213
|
+
}
|
data/app/styles/main.scss
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
@import "manifest";
|
2
2
|
|
3
3
|
body {
|
4
|
-
max-width:
|
4
|
+
max-width: 1400px;
|
5
5
|
margin: 0 auto;
|
6
6
|
}
|
7
7
|
|
@@ -20,7 +20,7 @@ body {
|
|
20
20
|
@include desktop {
|
21
21
|
&.with-sidebar {
|
22
22
|
min-height: 100vh;
|
23
|
-
margin-left:
|
23
|
+
margin-left: 300px;
|
24
24
|
}
|
25
25
|
}
|
26
26
|
|
data/lib/madness/command_line.rb
CHANGED
@@ -66,17 +66,8 @@ module Madness
|
|
66
66
|
config.toc = args['--toc'] if args['--toc']
|
67
67
|
config.auth = args['--auth'] if args['--auth']
|
68
68
|
config.auth_realm = args['--auth-realm'] if args['--auth-realm']
|
69
|
-
|
70
|
-
config.
|
71
|
-
config.auto_nav = false if args['--no-auto-nav']
|
72
|
-
config.sidebar = false if args['--no-sidebar']
|
73
|
-
config.highlighter = false if args['--no-syntax']
|
74
|
-
config.line_numbers = false if args['--no-line-numbers']
|
75
|
-
config.copy_code = false if args['--no-copy-code']
|
76
|
-
config.shortlinks = true if args['--shortlinks']
|
77
|
-
config.open = true if args['--open']
|
78
|
-
|
79
|
-
config.theme = File.expand_path(args['--theme'], config.path) if args['--theme']
|
69
|
+
config.open = true if args['--open']
|
70
|
+
config.theme = File.expand_path(args['--theme'], config.path) if args['--theme']
|
80
71
|
end
|
81
72
|
|
82
73
|
# Generate index and toc, if requested by the user.
|
data/lib/madness/docopt.txt
CHANGED
@@ -28,37 +28,6 @@ Options:
|
|
28
28
|
Set server listen address.
|
29
29
|
(Config option: bind, default: 0.0.0.0)
|
30
30
|
|
31
|
-
--no-auto-h1
|
32
|
-
By default, if a markdown document does not start with an H1 caption,
|
33
|
-
it will be added automatically based on the file name. To disable this
|
34
|
-
behavior, use --no-auto-h1.
|
35
|
-
(Config option: auto_h1)
|
36
|
-
|
37
|
-
--no-syntax
|
38
|
-
Disable code syntax highlighting.
|
39
|
-
(Config option: highlighter)
|
40
|
-
|
41
|
-
--no-line-numbers
|
42
|
-
Disable line numbering for syntax highlighter.
|
43
|
-
(Config option: line_numbers)
|
44
|
-
|
45
|
-
--no-copy-code
|
46
|
-
Disable copy to cliboard icon for code snippets.
|
47
|
-
(Config option: copy_code)
|
48
|
-
|
49
|
-
--no-sidebar
|
50
|
-
Disable sidebar navigation.
|
51
|
-
(Config option: sidebar)
|
52
|
-
|
53
|
-
--no-auto-nav
|
54
|
-
Disable automatic generation of footer navigation for folder README
|
55
|
-
files.
|
56
|
-
(Config option: auto_nav)
|
57
|
-
|
58
|
-
--shortlinks
|
59
|
-
Enable support for [[Short Links]].
|
60
|
-
(Config option: shortlinks)
|
61
|
-
|
62
31
|
--theme FOLDER
|
63
32
|
Use a custom theme. FOLDER is either absolute or relative to the main
|
64
33
|
documentation path.
|
@@ -86,13 +55,10 @@ Options:
|
|
86
55
|
Examples:
|
87
56
|
madness
|
88
57
|
madness docs
|
89
|
-
madness docs
|
58
|
+
madness docs -p 4567
|
90
59
|
madness docs --open
|
91
|
-
madness --no-sidebar --no-auto-nav
|
92
60
|
madness --toc "Table of Contents.md" --and-quit
|
93
61
|
madness --auth user:secret --port 4000
|
94
62
|
madness --theme _mytheme
|
95
63
|
madness create config
|
96
64
|
madness create theme
|
97
|
-
|
98
|
-
|
data/lib/madness/document.rb
CHANGED
@@ -1,8 +1,5 @@
|
|
1
|
-
require 'commonmarker'
|
2
|
-
require 'coderay'
|
3
|
-
|
4
1
|
module Madness
|
5
|
-
# Handle a single
|
2
|
+
# Handle a single document path.
|
6
3
|
class Document
|
7
4
|
include ServerHelper
|
8
5
|
using StringRefinements
|
@@ -18,12 +15,7 @@ module Madness
|
|
18
15
|
|
19
16
|
# Return the HTML for that document
|
20
17
|
def content
|
21
|
-
@content ||=
|
22
|
-
end
|
23
|
-
|
24
|
-
# Return the HTML for that document, force re-read.
|
25
|
-
def content!
|
26
|
-
%i[empty missing].include?(type) ? "<h1>#{title}</h1>" : markdown_to_html
|
18
|
+
@content ||= %i[empty missing].include?(type) ? "<h1>#{title}</h1>" : markdown.to_html
|
27
19
|
end
|
28
20
|
|
29
21
|
private
|
@@ -65,108 +57,11 @@ module Madness
|
|
65
57
|
end
|
66
58
|
|
67
59
|
def markdown
|
68
|
-
@markdown ||=
|
69
|
-
end
|
70
|
-
|
71
|
-
def pre_process_markdown
|
72
|
-
result = File.read file
|
73
|
-
result = evaluate_shortlinks result if config.shortlinks
|
74
|
-
result
|
75
|
-
end
|
76
|
-
|
77
|
-
def doc
|
78
|
-
@doc ||= CommonMarker.render_doc markdown, :DEFAULT, [:table]
|
79
|
-
end
|
80
|
-
|
81
|
-
# Convert markdown to HTML, with some additional processing:
|
82
|
-
# 1. Add anchors to headers
|
83
|
-
# 2. Syntax highilghting
|
84
|
-
# 3. Prepend H1 if needed
|
85
|
-
def markdown_to_html
|
86
|
-
replace_toc_marker
|
87
|
-
prepend_h1 if config.auto_h1
|
88
|
-
add_anchor_ids
|
89
|
-
html = doc.to_html :UNSAFE
|
90
|
-
html = syntax_highlight(html) if config.highlighter
|
91
|
-
html
|
92
|
-
end
|
93
|
-
|
94
|
-
# Add anchors with IDs before all headers
|
95
|
-
def add_anchor_ids
|
96
|
-
doc.walk do |node|
|
97
|
-
if node.type == :header
|
98
|
-
anchor = CommonMarker::Node.new(:inline_html)
|
99
|
-
|
100
|
-
next unless node.first_child.type == :text
|
101
|
-
|
102
|
-
anchor_id = node.first_child.string_content.to_slug
|
103
|
-
anchor.string_content = "<a id='#{anchor_id}'></a>"
|
104
|
-
node.prepend_child anchor
|
105
|
-
end
|
106
|
-
end
|
60
|
+
@markdown ||= MarkdownDocument.new(markdown_text, title: title)
|
107
61
|
end
|
108
62
|
|
109
|
-
|
110
|
-
|
111
|
-
toc_marker = doc.find do |node|
|
112
|
-
node.type == :html and node.string_content.include? '<!-- TOC -->'
|
113
|
-
end
|
114
|
-
|
115
|
-
return unless toc_marker
|
116
|
-
|
117
|
-
toc_marker.insert_after document_toc
|
118
|
-
toc_marker.insert_after CommonMarker.render_doc('## Table of Contents').first_child
|
119
|
-
end
|
120
|
-
|
121
|
-
# Replace [[link]] with [link](link)
|
122
|
-
def evaluate_shortlinks(raw)
|
123
|
-
raw.gsub(/\[\[([^\]]+)\]\]/) { "[#{$1}](#{$1.to_href})" }
|
124
|
-
end
|
125
|
-
|
126
|
-
# Returns a UL object containing the document table of contents
|
127
|
-
def document_toc
|
128
|
-
toc = []
|
129
|
-
doc.walk do |node|
|
130
|
-
next unless node.type == :header
|
131
|
-
|
132
|
-
level = node.header_level
|
133
|
-
next unless level.between? 2, 3
|
134
|
-
|
135
|
-
text = node.first_child.string_content
|
136
|
-
spacer = ' ' * (level - 1)
|
137
|
-
toc << "#{spacer}- [#{text}](##{text.to_slug})"
|
138
|
-
end
|
139
|
-
|
140
|
-
toc = toc.join "\n"
|
141
|
-
CommonMarker.render_doc(toc).first_child
|
142
|
-
end
|
143
|
-
|
144
|
-
# If the document does not start with an H1 tag, add it.
|
145
|
-
def prepend_h1
|
146
|
-
return unless doc.first_child
|
147
|
-
return if (doc.first_child.type == :header) && (doc.first_child.header_level == 1)
|
148
|
-
|
149
|
-
h1 = CommonMarker.render_doc("# #{title}").first_child
|
150
|
-
doc.first_child.insert_before h1
|
151
|
-
end
|
152
|
-
|
153
|
-
# Apply syntax highlighting with CodeRay. This will parse for any
|
154
|
-
# <code class='LANG'> sections in the HTML, pass it to CodeRay for
|
155
|
-
# highlighting.
|
156
|
-
# Since CodeRay adds another HTML escaping, on top of what RDiscount
|
157
|
-
# does, we unescape it before passing it to CodeRay.
|
158
|
-
#
|
159
|
-
# Open StackOverflow question:
|
160
|
-
# http://stackoverflow.com/questions/37771279/prevent-double-escaping-with-coderay-and-rdiscount
|
161
|
-
def syntax_highlight(html)
|
162
|
-
line_numbers = config.line_numbers ? :table : nil
|
163
|
-
opts = { css: :style, wrap: nil, line_numbers: line_numbers }
|
164
|
-
html.gsub(%r{<code class="language-(.+?)">(.+?)</code>}m) do
|
165
|
-
lang = $1
|
166
|
-
code = $2
|
167
|
-
code = CGI.unescapeHTML code
|
168
|
-
CodeRay.scan(code, lang).html opts
|
169
|
-
end
|
63
|
+
def markdown_text
|
64
|
+
@markdown_text ||= File.read file
|
170
65
|
end
|
171
66
|
|
172
67
|
def md_file?
|
@@ -0,0 +1,103 @@
|
|
1
|
+
require 'redcarpet'
|
2
|
+
|
3
|
+
module Madness
|
4
|
+
# Handle a pure markdown document.
|
5
|
+
class MarkdownDocument
|
6
|
+
include ServerHelper
|
7
|
+
using StringRefinements
|
8
|
+
|
9
|
+
attr_reader :markdown, :title
|
10
|
+
|
11
|
+
def initialize(markdown, title: nil)
|
12
|
+
@markdown = markdown
|
13
|
+
@title = title || ''
|
14
|
+
end
|
15
|
+
|
16
|
+
def text
|
17
|
+
@text ||= begin
|
18
|
+
result = markdown
|
19
|
+
result = parse_toc(result) if config.auto_toc
|
20
|
+
result = parse_shortlinks(result) if config.shortlinks
|
21
|
+
result = prepend_h1(result) if config.auto_h1
|
22
|
+
result
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def to_html
|
27
|
+
@to_html ||= Redcarpet::Markdown.new(redcarpet_renderer, redcarpet_options).render text
|
28
|
+
end
|
29
|
+
|
30
|
+
private
|
31
|
+
|
32
|
+
def parse_toc(input)
|
33
|
+
input.gsub '<!-- TOC -->', toc
|
34
|
+
end
|
35
|
+
|
36
|
+
def parse_shortlinks(input)
|
37
|
+
input.gsub(/\[\[([^\]]+)\]\]/) { "[#{$1}](#{$1.to_href})" }
|
38
|
+
end
|
39
|
+
|
40
|
+
def prepend_h1(input)
|
41
|
+
return input if has_h1?(input)
|
42
|
+
|
43
|
+
"# #{title}\n\n#{input}"
|
44
|
+
end
|
45
|
+
|
46
|
+
def has_h1?(input)
|
47
|
+
lines = input.lines(chomp: true).reject(&:empty?)
|
48
|
+
return false if lines.empty?
|
49
|
+
|
50
|
+
lines[0].match(/^# \w+/) || (lines[1] && lines[0].match(/^\w+/) && lines[1].start_with?('='))
|
51
|
+
end
|
52
|
+
|
53
|
+
def redcarpet_options
|
54
|
+
@redcarpet_options ||= {
|
55
|
+
no_intra_emphasis: true,
|
56
|
+
autolink: true,
|
57
|
+
tables: true,
|
58
|
+
fenced_code_blocks: true,
|
59
|
+
strikethrough: true,
|
60
|
+
space_after_headers: true,
|
61
|
+
superscript: true,
|
62
|
+
underline: true,
|
63
|
+
highlight: true,
|
64
|
+
quote: false,
|
65
|
+
footnotes: true,
|
66
|
+
}
|
67
|
+
end
|
68
|
+
|
69
|
+
def redcarpet_renderer
|
70
|
+
redcarpet_handler.new with_toc_data: true
|
71
|
+
end
|
72
|
+
|
73
|
+
def redcarpet_handler
|
74
|
+
config.highlighter ? HighlightRenderer : Redcarpet::Render::HTML
|
75
|
+
end
|
76
|
+
|
77
|
+
def toc_caption
|
78
|
+
@toc_caption ||= if config.auto_toc.is_a?(String)
|
79
|
+
config.auto_toc
|
80
|
+
else
|
81
|
+
'## Table of Contents'
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
def toc
|
86
|
+
result = ["#{toc_caption}\n"]
|
87
|
+
markdown.lines(chomp: true).each do |line|
|
88
|
+
next unless line.start_with? '#'
|
89
|
+
|
90
|
+
matches = line.match(/^(?<level>\#{2,3})\s+(?<text>.+)/)
|
91
|
+
next unless matches
|
92
|
+
|
93
|
+
level = matches[:level].size - 1
|
94
|
+
text = matches[:text]
|
95
|
+
|
96
|
+
spacer = ' ' * level
|
97
|
+
result.push "#{spacer}- [#{text}](##{text.to_slug})"
|
98
|
+
end
|
99
|
+
|
100
|
+
result.join "\n"
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
data/lib/madness/settings.rb
CHANGED
@@ -20,12 +20,14 @@ auto_h1: true
|
|
20
20
|
# append navigation to directory READMEs
|
21
21
|
auto_nav: true
|
22
22
|
|
23
|
+
# replace <!-- TOC --> in any file with its internal table of contents
|
24
|
+
# set to true to enable it with the default '## Table of Contents' caption,
|
25
|
+
# or set to any string that will be inserted before it as a caption.
|
26
|
+
auto_toc: true
|
27
|
+
|
23
28
|
# enable syntax highlighter for code snippets
|
24
29
|
highlighter: true
|
25
30
|
|
26
|
-
# enable line numbers for code snippets
|
27
|
-
line_numbers: true
|
28
|
-
|
29
31
|
# enable the copy to clipboard icon for code snippets
|
30
32
|
copy_code: true
|
31
33
|
|
data/lib/madness/version.rb
CHANGED