makeup 0.0.0 → 0.1.0
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.
- data/Gemfile +3 -0
- data/Gemfile.lock +30 -0
- data/Rakefile +10 -0
- data/Readme.md +68 -0
- data/lib/makeup/code_block_parser.rb +85 -0
- data/lib/makeup/markup.rb +56 -0
- data/lib/makeup/syntax_highlighter.rb +94 -0
- data/lib/makeup.rb +28 -0
- data/makeup.gemspec +32 -0
- data/test/makeup/markup_test.rb +92 -0
- data/test/makeup/syntax_highlighter_test.rb +108 -0
- data/test/test_helper.rb +36 -0
- metadata +110 -7
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
makeup (0.1.0)
|
5
|
+
github-markup (~> 0.7)
|
6
|
+
htmlentities (~> 4.3)
|
7
|
+
pygments.rb (~> 0.2)
|
8
|
+
|
9
|
+
GEM
|
10
|
+
remote: http://rubygems.org/
|
11
|
+
specs:
|
12
|
+
github-markup (0.7.4)
|
13
|
+
htmlentities (4.3.1)
|
14
|
+
minitest (2.12.1)
|
15
|
+
posix-spawn (0.3.6)
|
16
|
+
pygments.rb (0.3.1)
|
17
|
+
posix-spawn (~> 0.3.6)
|
18
|
+
yajl-ruby (~> 1.1.0)
|
19
|
+
rake (0.9.2.2)
|
20
|
+
redcarpet (2.1.1)
|
21
|
+
yajl-ruby (1.1.0)
|
22
|
+
|
23
|
+
PLATFORMS
|
24
|
+
ruby
|
25
|
+
|
26
|
+
DEPENDENCIES
|
27
|
+
makeup!
|
28
|
+
minitest (~> 2.0)
|
29
|
+
rake (~> 0.9)
|
30
|
+
redcarpet
|
data/Rakefile
ADDED
data/Readme.md
ADDED
@@ -0,0 +1,68 @@
|
|
1
|
+
# Makeup
|
2
|
+
|
3
|
+
Makeup provides markup rendering and syntax highlighting in one glorious
|
4
|
+
package. It can also syntax highlight "fenced code blocks" in markdown files.
|
5
|
+
|
6
|
+
`Makeup` does all its heavylifting through `GitHub::Markup` and `Pygments.rb`,
|
7
|
+
and combines the two for killer code blocks in markup files.
|
8
|
+
|
9
|
+
## Markup
|
10
|
+
|
11
|
+
Rendering markup is done through `Makeup::Markup`. For information about markup
|
12
|
+
formats, what gems to install for various format support etc see the
|
13
|
+
[`GitHub::Markup` docs](https://github.com/github/markup/).
|
14
|
+
|
15
|
+
```ruby
|
16
|
+
require "makeup"
|
17
|
+
|
18
|
+
Makeup::Markup.new.render("file.md", "# Some markdown")
|
19
|
+
```
|
20
|
+
|
21
|
+
`GitHub::Markup` uses the file name to decide what markup format to render the
|
22
|
+
contents with.
|
23
|
+
|
24
|
+
To extract and syntax highlight "fenced code blocks" with Pygments, give the
|
25
|
+
markup renderer a highlighter:
|
26
|
+
|
27
|
+
```ruby
|
28
|
+
require "makeup"
|
29
|
+
|
30
|
+
highlighter = Makeup::SyntaxHighlighter.new
|
31
|
+
renderer = Makeup::Markup.new(:highlighter => highlighter)
|
32
|
+
renderer.render("file.md", <<MD)
|
33
|
+
# Documentation and examples
|
34
|
+
|
35
|
+
## s-trim `(s)`
|
36
|
+
|
37
|
+
Remove whitespace at the beginning and end of `s`.
|
38
|
+
|
39
|
+
\`\`\`cl
|
40
|
+
(s-trim "trim ") ;; => "trim"
|
41
|
+
(s-trim " this") ;; => "this"
|
42
|
+
(s-trim " only trims beg and end ") ;; => "only trims beg and end"
|
43
|
+
\`\`\`
|
44
|
+
MD
|
45
|
+
```
|
46
|
+
|
47
|
+
The fenced code block will be syntax highlighted with the common lisp lexer.
|
48
|
+
|
49
|
+
## Syntax highlighting
|
50
|
+
|
51
|
+
`Makeup` provides a very thin abstraction around `Pygments.rb` for syntax
|
52
|
+
highlighting:
|
53
|
+
|
54
|
+
```ruby
|
55
|
+
require "makeup"
|
56
|
+
|
57
|
+
highlighter = Makeup::SyntaxHighlighter.new
|
58
|
+
res = highlighter.highlight(person.rb", <<RUBY)
|
59
|
+
class Person
|
60
|
+
def speak
|
61
|
+
"Hello"
|
62
|
+
end
|
63
|
+
end
|
64
|
+
RUBY
|
65
|
+
|
66
|
+
res.lexer # "ruby"
|
67
|
+
res.code # HTML-formatted syntax highlighted code
|
68
|
+
```
|
@@ -0,0 +1,85 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
# --
|
3
|
+
# The MIT License (MIT)
|
4
|
+
#
|
5
|
+
# Copyright (C) 2012 Gitorious AS
|
6
|
+
#
|
7
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
8
|
+
# of this software and associated documentation files (the "Software"), to deal
|
9
|
+
# in the Software without restriction, including without limitation the rights
|
10
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
11
|
+
# copies of the Software, and to permit persons to whom the Software is
|
12
|
+
# furnished to do so, subject to the following conditions:
|
13
|
+
#
|
14
|
+
# The above copyright notice and this permission notice shall be included in all
|
15
|
+
# copies or substantial portions of the Software.
|
16
|
+
#
|
17
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
18
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
19
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
20
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
21
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
22
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
23
|
+
# SOFTWARE.
|
24
|
+
#++
|
25
|
+
|
26
|
+
module Makeup
|
27
|
+
class CodeBlockParser
|
28
|
+
attr_reader :lines
|
29
|
+
|
30
|
+
def self.parse(markup, &block)
|
31
|
+
new(markup).parse(&block)
|
32
|
+
end
|
33
|
+
|
34
|
+
def initialize(markup)
|
35
|
+
@lines = markup.split("\n")
|
36
|
+
@current_code_bock = nil
|
37
|
+
end
|
38
|
+
|
39
|
+
def parse(&block)
|
40
|
+
result = []
|
41
|
+
|
42
|
+
while line = @lines.shift
|
43
|
+
if closes_code_block?(line)
|
44
|
+
result << block.call(*close_active_code_block)
|
45
|
+
elsif active_code_block?
|
46
|
+
append_active_code_block(line)
|
47
|
+
elsif starts_code_block?(line)
|
48
|
+
start_code_block(line)
|
49
|
+
else
|
50
|
+
result << line
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
result.join("\n")
|
55
|
+
end
|
56
|
+
|
57
|
+
def active_code_block?
|
58
|
+
!@current_code_bock.nil?
|
59
|
+
end
|
60
|
+
|
61
|
+
def starts_code_block?(line)
|
62
|
+
line.match(/^```.*/)
|
63
|
+
end
|
64
|
+
|
65
|
+
def closes_code_block?(line)
|
66
|
+
active_code_block? && line == "```"
|
67
|
+
end
|
68
|
+
|
69
|
+
def start_code_block(line)
|
70
|
+
m = line.match(/```([^\s]+)/)
|
71
|
+
@current_code_bock = [m && m[1], []]
|
72
|
+
end
|
73
|
+
|
74
|
+
def append_active_code_block(line)
|
75
|
+
@current_code_bock[1] << line
|
76
|
+
end
|
77
|
+
|
78
|
+
def close_active_code_block
|
79
|
+
lexer = @current_code_bock[0]
|
80
|
+
code = @current_code_bock[1].join("\n")
|
81
|
+
@current_code_bock = nil
|
82
|
+
[lexer, code]
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
# --
|
3
|
+
# The MIT License (MIT)
|
4
|
+
#
|
5
|
+
# Copyright (C) 2012 Gitorious AS
|
6
|
+
#
|
7
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
8
|
+
# of this software and associated documentation files (the "Software"), to deal
|
9
|
+
# in the Software without restriction, including without limitation the rights
|
10
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
11
|
+
# copies of the Software, and to permit persons to whom the Software is
|
12
|
+
# furnished to do so, subject to the following conditions:
|
13
|
+
#
|
14
|
+
# The above copyright notice and this permission notice shall be included in all
|
15
|
+
# copies or substantial portions of the Software.
|
16
|
+
#
|
17
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
18
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
19
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
20
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
21
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
22
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
23
|
+
# SOFTWARE.
|
24
|
+
#++
|
25
|
+
require "github/markup"
|
26
|
+
require "makeup/code_block_parser"
|
27
|
+
require "makeup/syntax_highlighter"
|
28
|
+
|
29
|
+
module Makeup
|
30
|
+
class NoopHighlighter
|
31
|
+
def highlight(path, code, options = {})
|
32
|
+
lexer = options[:lexer] || path.split(".").last
|
33
|
+
CodeBlock.new(lexer, code)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
class Markup
|
38
|
+
def initialize(options = {})
|
39
|
+
@markup_class_name = options[:markup_class_name] || "prettyprint"
|
40
|
+
@highlighter = options[:highlighter] || NoopHighlighter.new
|
41
|
+
end
|
42
|
+
|
43
|
+
def render(path, content)
|
44
|
+
content = highlight_code_blocks(path, content)
|
45
|
+
GitHub::Markup.render(path, content)
|
46
|
+
end
|
47
|
+
|
48
|
+
def highlight_code_blocks(path, markup)
|
49
|
+
return markup unless path =~ /\.(md|mkdn?|mdwn|mdown|markdown)$/
|
50
|
+
CodeBlockParser.parse(markup) do |lexer, code|
|
51
|
+
hb = @highlighter.highlight(path, code, { :lexer => lexer })
|
52
|
+
"<pre class=\"#{hb.lexer} #{@markup_class_name}\">#{hb.code}</pre>"
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
@@ -0,0 +1,94 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
# --
|
3
|
+
# The MIT License (MIT)
|
4
|
+
#
|
5
|
+
# Copyright (C) 2012 Gitorious AS
|
6
|
+
#
|
7
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
8
|
+
# of this software and associated documentation files (the "Software"), to deal
|
9
|
+
# in the Software without restriction, including without limitation the rights
|
10
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
11
|
+
# copies of the Software, and to permit persons to whom the Software is
|
12
|
+
# furnished to do so, subject to the following conditions:
|
13
|
+
#
|
14
|
+
# The above copyright notice and this permission notice shall be included in all
|
15
|
+
# copies or substantial portions of the Software.
|
16
|
+
#
|
17
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
18
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
19
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
20
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
21
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
22
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
23
|
+
# SOFTWARE.
|
24
|
+
#++
|
25
|
+
require "pygments"
|
26
|
+
require "htmlentities"
|
27
|
+
|
28
|
+
module Makeup
|
29
|
+
CodeBlock = Struct.new(:lexer, :code)
|
30
|
+
|
31
|
+
class SyntaxHighlighter
|
32
|
+
def initialize
|
33
|
+
@entities = HTMLEntities.new
|
34
|
+
end
|
35
|
+
|
36
|
+
def highlight(path, code, options = {})
|
37
|
+
options[:lexer] ||= lexer(path, code)
|
38
|
+
lexer = Pygments::Lexer.find(options[:lexer])
|
39
|
+
CodeBlock.new(lexer && lexer.aliases.first,
|
40
|
+
Pygments.highlight(code, highlight_options(options)))
|
41
|
+
rescue MentosError => e
|
42
|
+
# "MentosError" is what Pyments.rb raises when an unknown lexer is
|
43
|
+
# attempted used
|
44
|
+
CodeBlock.new(nil, @entities.encode(code))
|
45
|
+
end
|
46
|
+
|
47
|
+
def lexer(path, code = nil)
|
48
|
+
self.class.lexer(path.split(".").pop, code)
|
49
|
+
end
|
50
|
+
|
51
|
+
def self.lexer(suffix, code = nil)
|
52
|
+
return @@lexer_aliases[suffix] if @@lexer_aliases[suffix]
|
53
|
+
lexer = Pygments::Lexer.find_by_extname(".#{suffix}")
|
54
|
+
return lexer.aliases.first || lexer.name if lexer
|
55
|
+
shebang_language(shebang(code)) || suffix
|
56
|
+
end
|
57
|
+
|
58
|
+
def self.shebang(code)
|
59
|
+
first_line = (code || "").split("\n")[0]
|
60
|
+
first_line =~ /^#!/ ? first_line : nil
|
61
|
+
end
|
62
|
+
|
63
|
+
def self.shebang_language(shebang)
|
64
|
+
shebang = @@lexer_shebangs.find { |s| (shebang || "") =~ s[:pattern] }
|
65
|
+
shebang && shebang[:lexer]
|
66
|
+
end
|
67
|
+
|
68
|
+
def self.add_lexer_alias(extension, lexer)
|
69
|
+
@@lexer_aliases ||= {}
|
70
|
+
@@lexer_aliases[extension] = lexer
|
71
|
+
end
|
72
|
+
|
73
|
+
def self.add_lexer_shebang(pattern, lexer)
|
74
|
+
@@lexer_shebangs ||= []
|
75
|
+
@@lexer_shebangs << { :pattern => pattern, :lexer => lexer }
|
76
|
+
end
|
77
|
+
|
78
|
+
private
|
79
|
+
def highlight_options(options = {})
|
80
|
+
options[:options] ||= {}
|
81
|
+
options[:options][:nowrap] = true
|
82
|
+
options[:options][:encoding] ||= "utf-8"
|
83
|
+
options
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
Makeup::SyntaxHighlighter.add_lexer_alias("txt", "text")
|
89
|
+
Makeup::SyntaxHighlighter.add_lexer_alias("ru", "rb")
|
90
|
+
Makeup::SyntaxHighlighter.add_lexer_alias("Rakefile", "rb")
|
91
|
+
Makeup::SyntaxHighlighter.add_lexer_alias("Gemfile", "rb")
|
92
|
+
Makeup::SyntaxHighlighter.add_lexer_alias("Gemfile.lock", "yaml")
|
93
|
+
|
94
|
+
Makeup::SyntaxHighlighter.add_lexer_shebang(/\bruby\b/, "rb")
|
data/lib/makeup.rb
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
# --
|
3
|
+
# The MIT License (MIT)
|
4
|
+
#
|
5
|
+
# Copyright (C) 2012 Gitorious AS
|
6
|
+
#
|
7
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
8
|
+
# of this software and associated documentation files (the "Software"), to deal
|
9
|
+
# in the Software without restriction, including without limitation the rights
|
10
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
11
|
+
# copies of the Software, and to permit persons to whom the Software is
|
12
|
+
# furnished to do so, subject to the following conditions:
|
13
|
+
#
|
14
|
+
# The above copyright notice and this permission notice shall be included in all
|
15
|
+
# copies or substantial portions of the Software.
|
16
|
+
#
|
17
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
18
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
19
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
20
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
21
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
22
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
23
|
+
# SOFTWARE.
|
24
|
+
#++
|
25
|
+
|
26
|
+
module Makeup
|
27
|
+
VERSION = "0.1.0"
|
28
|
+
end
|
data/makeup.gemspec
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
dir = File.expand_path(File.dirname(__FILE__))
|
3
|
+
require File.join(dir, "lib", "makeup")
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = "makeup"
|
7
|
+
s.version = Makeup::VERSION
|
8
|
+
s.authors = ["Christian Johansen"]
|
9
|
+
s.email = ["christian@gitorious.org"]
|
10
|
+
s.homepage = "http://gitorious.org/gitorious/makeup"
|
11
|
+
s.summary = %q{Pretty markup}
|
12
|
+
s.description = <<-DESC
|
13
|
+
Makeup provides markup rendering and code highlighting. It renders all kinds of
|
14
|
+
markup formats using GitHub::Markup, and implements "fenced code blocks" for
|
15
|
+
markdown files.
|
16
|
+
DESC
|
17
|
+
|
18
|
+
s.rubyforge_project = "makeup"
|
19
|
+
|
20
|
+
s.add_dependency "pygments.rb", "~>0.2"
|
21
|
+
s.add_dependency "github-markup", "~> 0.7"
|
22
|
+
s.add_dependency "htmlentities", "~> 4.3"
|
23
|
+
|
24
|
+
s.add_development_dependency "minitest", "~> 2.0"
|
25
|
+
s.add_development_dependency "rake", "~> 0.9"
|
26
|
+
s.add_development_dependency "redcarpet"
|
27
|
+
|
28
|
+
s.files = `git ls-files`.split("\n")
|
29
|
+
s.test_files = `git ls-files -- {test}/*`.split("\n")
|
30
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
31
|
+
s.require_paths = ["lib"]
|
32
|
+
end
|
@@ -0,0 +1,92 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
# --
|
3
|
+
# The MIT License (MIT)
|
4
|
+
#
|
5
|
+
# Copyright (C) 2012 Gitorious AS
|
6
|
+
#
|
7
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
8
|
+
# of this software and associated documentation files (the "Software"), to deal
|
9
|
+
# in the Software without restriction, including without limitation the rights
|
10
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
11
|
+
# copies of the Software, and to permit persons to whom the Software is
|
12
|
+
# furnished to do so, subject to the following conditions:
|
13
|
+
#
|
14
|
+
# The above copyright notice and this permission notice shall be included in all
|
15
|
+
# copies or substantial portions of the Software.
|
16
|
+
#
|
17
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
18
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
19
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
20
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
21
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
22
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
23
|
+
# SOFTWARE.
|
24
|
+
#++
|
25
|
+
require "test_helper"
|
26
|
+
require "makeup/markup"
|
27
|
+
|
28
|
+
describe Makeup::Markup do
|
29
|
+
before do
|
30
|
+
@highlighter = Makeup::SyntaxHighlighter.new
|
31
|
+
@renderer = Makeup::Markup.new(:highlighter => @highlighter)
|
32
|
+
end
|
33
|
+
|
34
|
+
describe "#render" do
|
35
|
+
it "renders multi-line code blocks with syntax highlighting" do
|
36
|
+
html = @renderer.render("file.md", <<-MD)
|
37
|
+
```cl
|
38
|
+
(s-trim-left "trim ") ;; => "trim "
|
39
|
+
(s-trim-left " this") ;; => "this"
|
40
|
+
```
|
41
|
+
MD
|
42
|
+
|
43
|
+
assert_match "<pre class=\"common-lisp prettyprint\">", html
|
44
|
+
end
|
45
|
+
|
46
|
+
it "highlights multiple separate multi-line code blocks" do
|
47
|
+
html = @renderer.render("file.md", <<-MD)
|
48
|
+
# This stuff
|
49
|
+
|
50
|
+
```cl
|
51
|
+
(s-trim-left "trim ") ;; => "trim "
|
52
|
+
(s-trim-left " this") ;; => "this"
|
53
|
+
```
|
54
|
+
|
55
|
+
# And this stuff
|
56
|
+
|
57
|
+
```cl
|
58
|
+
(s-trim-left "trim ") ;; => "trim "
|
59
|
+
(s-trim-left " this") ;; => "this"
|
60
|
+
```
|
61
|
+
MD
|
62
|
+
|
63
|
+
assert_equal 2, html.scan(/common-lisp/).length
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
describe "#highlight_code_blocks" do
|
68
|
+
it "does not touch non-markdown files" do
|
69
|
+
content = "```cl\n(yup)\n```"
|
70
|
+
highlighted = @renderer.highlight_code_blocks("file.rst", content)
|
71
|
+
assert_equal content, highlighted
|
72
|
+
end
|
73
|
+
|
74
|
+
it "highlights one-line code block" do
|
75
|
+
content = "```cl\n(yup)\n```"
|
76
|
+
highlighted = @renderer.highlight_code_blocks("file.md", content)
|
77
|
+
assert_match "common-lisp", highlighted
|
78
|
+
end
|
79
|
+
|
80
|
+
it "highlights multi-line code block" do
|
81
|
+
content = "```cl\n(yup)\n(yessir-p t)\n```"
|
82
|
+
highlighted = @renderer.highlight_code_blocks("file.md", content)
|
83
|
+
assert_match "(</span><span class=\"nv\">yessir-p</span>", highlighted
|
84
|
+
end
|
85
|
+
|
86
|
+
it "preserves code block white-space" do
|
87
|
+
content = "```cl\n(yup\n (yessir-p t))\n```"
|
88
|
+
highlighted = @renderer.highlight_code_blocks("file.md", content)
|
89
|
+
assert_match "\n <span class=\"p\">(</span>", highlighted
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
@@ -0,0 +1,108 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
# --
|
3
|
+
# The MIT License (MIT)
|
4
|
+
#
|
5
|
+
# Copyright (C) 2012 Gitorious AS
|
6
|
+
#
|
7
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
8
|
+
# of this software and associated documentation files (the "Software"), to deal
|
9
|
+
# in the Software without restriction, including without limitation the rights
|
10
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
11
|
+
# copies of the Software, and to permit persons to whom the Software is
|
12
|
+
# furnished to do so, subject to the following conditions:
|
13
|
+
#
|
14
|
+
# The above copyright notice and this permission notice shall be included in all
|
15
|
+
# copies or substantial portions of the Software.
|
16
|
+
#
|
17
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
18
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
19
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
20
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
21
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
22
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
23
|
+
# SOFTWARE.
|
24
|
+
#++
|
25
|
+
require "test_helper"
|
26
|
+
require "makeup/syntax_highlighter"
|
27
|
+
|
28
|
+
describe Makeup::SyntaxHighlighter do
|
29
|
+
include Makeup::Html
|
30
|
+
before { @highlighter = Makeup::SyntaxHighlighter.new }
|
31
|
+
|
32
|
+
def highlight(path, code)
|
33
|
+
@highlighter.highlight(path, code).code
|
34
|
+
end
|
35
|
+
|
36
|
+
describe "#highlight" do
|
37
|
+
it "returns code and lexer name" do
|
38
|
+
block = @highlighter.highlight("file.rb", "class File;")
|
39
|
+
|
40
|
+
assert_match "<span class=\"k\">class</span>", block.code
|
41
|
+
assert_equal "rb", block.lexer
|
42
|
+
end
|
43
|
+
|
44
|
+
it "highlights a Ruby file" do
|
45
|
+
html = highlight("file.rb", "class File\n attr_reader :path\nend")
|
46
|
+
|
47
|
+
assert_match "<span class=\"k\">class</span>", html
|
48
|
+
assert_match "<span class=\"nc\">File</span>", html
|
49
|
+
end
|
50
|
+
|
51
|
+
it "highlights a YAML file" do
|
52
|
+
html = highlight("file.yml", "something:\n is: true")
|
53
|
+
|
54
|
+
assert_match "<span class=\"l-Scalar-Plain\">something</span>", html
|
55
|
+
assert_match "<span class=\"p-Indicator\">:", html
|
56
|
+
end
|
57
|
+
|
58
|
+
it "highlights an .htm file" do
|
59
|
+
html = highlight("file.htm", "<h1>Hey</h1>")
|
60
|
+
|
61
|
+
assert_match "<span class=\"nt\"><h1></span>", html
|
62
|
+
assert_match "Hey<span class=\"nt\"></h1></span>", html
|
63
|
+
end
|
64
|
+
|
65
|
+
it "highlights file with custom suffix" do
|
66
|
+
Makeup::SyntaxHighlighter.add_lexer_alias("derp", "rb")
|
67
|
+
html = highlight("file.derp", "class File")
|
68
|
+
|
69
|
+
assert_match "<span class=\"k\">class</span>", html
|
70
|
+
assert_match "<span class=\"nc\">File</span>", html
|
71
|
+
end
|
72
|
+
|
73
|
+
it "skips highlighting if lexer is missing" do
|
74
|
+
html = highlight("file.trololol", "Yeah yeah yeah")
|
75
|
+
|
76
|
+
assert_equal "Yeah yeah yeah", html
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
describe "#lexer" do
|
81
|
+
it "uses known suffix" do
|
82
|
+
assert_equal "rb", @highlighter.lexer("file.rb")
|
83
|
+
end
|
84
|
+
|
85
|
+
it "uses registered suffix" do
|
86
|
+
Makeup::SyntaxHighlighter.add_lexer_alias("blarg", "blarg")
|
87
|
+
assert_equal "blarg", @highlighter.lexer("file.blarg")
|
88
|
+
end
|
89
|
+
|
90
|
+
it "uses registered lexer" do
|
91
|
+
Makeup::SyntaxHighlighter.add_lexer_alias("bg", "blarg")
|
92
|
+
assert_equal "blarg", @highlighter.lexer("file.bg")
|
93
|
+
end
|
94
|
+
|
95
|
+
it "uses known shebang" do
|
96
|
+
assert_equal "rb", @highlighter.lexer("some-binary", "#!/usr/bin/env ruby\n")
|
97
|
+
end
|
98
|
+
|
99
|
+
it "uses registered shebang" do
|
100
|
+
Makeup::SyntaxHighlighter.add_lexer_shebang(/\bnode\b/, "js")
|
101
|
+
assert_equal "js", @highlighter.lexer("some-binary", "#!/usr/bin/env node\n")
|
102
|
+
end
|
103
|
+
|
104
|
+
it "uses filename for unknown lexer" do
|
105
|
+
assert_equal "some-binary", @highlighter.lexer("some-binary", "class Person\nend")
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
data/test/test_helper.rb
ADDED
@@ -0,0 +1,36 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
# --
|
3
|
+
# The MIT License (MIT)
|
4
|
+
#
|
5
|
+
# Copyright (C) 2012 Gitorious AS
|
6
|
+
#
|
7
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
8
|
+
# of this software and associated documentation files (the "Software"), to deal
|
9
|
+
# in the Software without restriction, including without limitation the rights
|
10
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
11
|
+
# copies of the Software, and to permit persons to whom the Software is
|
12
|
+
# furnished to do so, subject to the following conditions:
|
13
|
+
#
|
14
|
+
# The above copyright notice and this permission notice shall be included in all
|
15
|
+
# copies or substantial portions of the Software.
|
16
|
+
#
|
17
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
18
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
19
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
20
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
21
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
22
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
23
|
+
# SOFTWARE.
|
24
|
+
#++
|
25
|
+
require "bundler/setup"
|
26
|
+
require "minitest/autorun"
|
27
|
+
|
28
|
+
Bundler.require(:default, :test)
|
29
|
+
|
30
|
+
module Makeup
|
31
|
+
module Html
|
32
|
+
def select(html, tag_name)
|
33
|
+
html.scan(/<#{tag_name}[^>]*>.*?<\/#{tag_name}>/m)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: makeup
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 27
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 0
|
8
|
+
- 1
|
8
9
|
- 0
|
9
|
-
|
10
|
-
version: 0.0.0
|
10
|
+
version: 0.1.0
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Christian Johansen
|
@@ -17,9 +17,101 @@ cert_chain: []
|
|
17
17
|
|
18
18
|
date: 2012-10-05 00:00:00 +02:00
|
19
19
|
default_executable:
|
20
|
-
dependencies:
|
20
|
+
dependencies:
|
21
|
+
- !ruby/object:Gem::Dependency
|
22
|
+
name: pygments.rb
|
23
|
+
prerelease: false
|
24
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ~>
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
hash: 15
|
30
|
+
segments:
|
31
|
+
- 0
|
32
|
+
- 2
|
33
|
+
version: "0.2"
|
34
|
+
type: :runtime
|
35
|
+
version_requirements: *id001
|
36
|
+
- !ruby/object:Gem::Dependency
|
37
|
+
name: github-markup
|
38
|
+
prerelease: false
|
39
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
40
|
+
none: false
|
41
|
+
requirements:
|
42
|
+
- - ~>
|
43
|
+
- !ruby/object:Gem::Version
|
44
|
+
hash: 5
|
45
|
+
segments:
|
46
|
+
- 0
|
47
|
+
- 7
|
48
|
+
version: "0.7"
|
49
|
+
type: :runtime
|
50
|
+
version_requirements: *id002
|
51
|
+
- !ruby/object:Gem::Dependency
|
52
|
+
name: htmlentities
|
53
|
+
prerelease: false
|
54
|
+
requirement: &id003 !ruby/object:Gem::Requirement
|
55
|
+
none: false
|
56
|
+
requirements:
|
57
|
+
- - ~>
|
58
|
+
- !ruby/object:Gem::Version
|
59
|
+
hash: 29
|
60
|
+
segments:
|
61
|
+
- 4
|
62
|
+
- 3
|
63
|
+
version: "4.3"
|
64
|
+
type: :runtime
|
65
|
+
version_requirements: *id003
|
66
|
+
- !ruby/object:Gem::Dependency
|
67
|
+
name: minitest
|
68
|
+
prerelease: false
|
69
|
+
requirement: &id004 !ruby/object:Gem::Requirement
|
70
|
+
none: false
|
71
|
+
requirements:
|
72
|
+
- - ~>
|
73
|
+
- !ruby/object:Gem::Version
|
74
|
+
hash: 3
|
75
|
+
segments:
|
76
|
+
- 2
|
77
|
+
- 0
|
78
|
+
version: "2.0"
|
79
|
+
type: :development
|
80
|
+
version_requirements: *id004
|
81
|
+
- !ruby/object:Gem::Dependency
|
82
|
+
name: rake
|
83
|
+
prerelease: false
|
84
|
+
requirement: &id005 !ruby/object:Gem::Requirement
|
85
|
+
none: false
|
86
|
+
requirements:
|
87
|
+
- - ~>
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
hash: 25
|
90
|
+
segments:
|
91
|
+
- 0
|
92
|
+
- 9
|
93
|
+
version: "0.9"
|
94
|
+
type: :development
|
95
|
+
version_requirements: *id005
|
96
|
+
- !ruby/object:Gem::Dependency
|
97
|
+
name: redcarpet
|
98
|
+
prerelease: false
|
99
|
+
requirement: &id006 !ruby/object:Gem::Requirement
|
100
|
+
none: false
|
101
|
+
requirements:
|
102
|
+
- - ">="
|
103
|
+
- !ruby/object:Gem::Version
|
104
|
+
hash: 3
|
105
|
+
segments:
|
106
|
+
- 0
|
107
|
+
version: "0"
|
108
|
+
type: :development
|
109
|
+
version_requirements: *id006
|
110
|
+
description: |
|
111
|
+
Makeup provides markup rendering and code highlighting. It renders all kinds of
|
112
|
+
markup formats using GitHub::Markup, and implements "fenced code blocks" for
|
113
|
+
markdown files.
|
21
114
|
|
22
|
-
description:
|
23
115
|
email:
|
24
116
|
- christian@gitorious.org
|
25
117
|
executables: []
|
@@ -28,8 +120,19 @@ extensions: []
|
|
28
120
|
|
29
121
|
extra_rdoc_files: []
|
30
122
|
|
31
|
-
files:
|
32
|
-
|
123
|
+
files:
|
124
|
+
- Gemfile
|
125
|
+
- Gemfile.lock
|
126
|
+
- Rakefile
|
127
|
+
- Readme.md
|
128
|
+
- lib/makeup.rb
|
129
|
+
- lib/makeup/code_block_parser.rb
|
130
|
+
- lib/makeup/markup.rb
|
131
|
+
- lib/makeup/syntax_highlighter.rb
|
132
|
+
- makeup.gemspec
|
133
|
+
- test/makeup/markup_test.rb
|
134
|
+
- test/makeup/syntax_highlighter_test.rb
|
135
|
+
- test/test_helper.rb
|
33
136
|
has_rdoc: true
|
34
137
|
homepage: http://gitorious.org/gitorious/makeup
|
35
138
|
licenses: []
|