madness 0.9.8 → 1.0.0.rc1

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.
@@ -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
+ }
@@ -0,0 +1,9 @@
1
+ // Scrollbar
2
+ ::-webkit-scrollbar {
3
+ width: 6px;
4
+ height: 6px;
5
+ }
6
+ ::-webkit-scrollbar-thumb {
7
+ background: #ccc;
8
+ -webkit-border-radius: 3px;
9
+ }
data/app/styles/main.scss CHANGED
@@ -1,7 +1,7 @@
1
1
  @import "manifest";
2
2
 
3
3
  body {
4
- max-width: 1300px;
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: 250px;
23
+ margin-left: 300px;
24
24
  }
25
25
  }
26
26
 
@@ -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.auto_h1 = false if args['--no-auto-h1']
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.
@@ -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 --no-auto-h1 -p 4567
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
-
@@ -1,8 +1,5 @@
1
- require 'commonmarker'
2
- require 'coderay'
3
-
4
1
  module Madness
5
- # Handle a single markdown document.
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 ||= 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 ||= pre_process_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
- # Replace <!-- TOC --> with a Table of Contents for the page
110
- def replace_toc_marker
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,10 @@
1
+ require 'redcarpet'
2
+ require 'rouge'
3
+ require 'rouge/plugins/redcarpet'
4
+
5
+ module Madness
6
+ # Renderer with syntax highlighting support
7
+ class HighlightRenderer < Redcarpet::Render::HTML
8
+ include Rouge::Plugins::Redcarpet
9
+ end
10
+ end
@@ -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
@@ -57,8 +57,8 @@ module Madness
57
57
  sidebar: true,
58
58
  auto_h1: true,
59
59
  auto_nav: true,
60
+ auto_toc: true,
60
61
  highlighter: true,
61
- line_numbers: true,
62
62
  copy_code: true,
63
63
  shortlinks: false,
64
64
  toc: nil,
@@ -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
 
@@ -1,3 +1,3 @@
1
1
  module Madness
2
- VERSION = '0.9.8'
2
+ VERSION = '1.0.0.rc1'
3
3
  end
data/lib/madness.rb CHANGED
@@ -5,4 +5,6 @@ end
5
5
 
6
6
  require 'requires'
7
7
 
8
- requires 'madness/refinements', 'madness/server_helper', 'madness'
8
+ requires 'madness/refinements'
9
+ requires 'madness/server_helper'
10
+ requires 'madness'