octopress-code-highlighter 3.0.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.
- checksums.yaml +7 -0
- data/.gitignore +21 -0
- data/.rspec +1 -0
- data/.travis.yml +2 -0
- data/CHANGELOG.md +44 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +31 -0
- data/Rakefile +6 -0
- data/assets/stylesheets/_code-style.scss +103 -0
- data/assets/stylesheets/_solarized.scss +58 -0
- data/assets/stylesheets/code.scss +156 -0
- data/lib/octopress-code-highlighter.rb +67 -0
- data/lib/octopress-code-highlighter/cache.rb +30 -0
- data/lib/octopress-code-highlighter/options_parser.rb +129 -0
- data/lib/octopress-code-highlighter/renderer.rb +165 -0
- data/lib/octopress-code-highlighter/version.rb +6 -0
- data/octopress-code-highlighter.gemspec +26 -0
- data/spec/pygments_spec.rb +139 -0
- data/spec/spec_helper.rb +3 -0
- metadata +147 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 9fc99d5bccc948a519675aa27ad80a7d31a6e02d
|
4
|
+
data.tar.gz: f3ae585a771bdaaed7542ef3dd5b62801191671f
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 7fe60353f22e04b2dc9b306d9a7e4df39419aead59f1a4b3bcea576b1db7082f315d4e16b498386cebc92c4cd544a4e76f178f0b6d4f4db61b2826b8658ba43e
|
7
|
+
data.tar.gz: 469f48187b59a3eb96789564a06b408829a135b8567e545de319108cb98782aa282ae15977f7aa138e83dc449687bf04a6df1430b6834465fe7f402cb6ac0435
|
data/.gitignore
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
*.gem
|
2
|
+
*.rbc
|
3
|
+
.bundle
|
4
|
+
.config
|
5
|
+
.yardoc
|
6
|
+
Gemfile.lock
|
7
|
+
InstalledFiles
|
8
|
+
_yardoc
|
9
|
+
coverage
|
10
|
+
doc/
|
11
|
+
lib/bundler/man
|
12
|
+
pkg
|
13
|
+
rdoc
|
14
|
+
spec/reports
|
15
|
+
test/tmp
|
16
|
+
test/version_tmp
|
17
|
+
tmp
|
18
|
+
.pygments-cache
|
19
|
+
.sass-cache
|
20
|
+
.DS_Store
|
21
|
+
.code-style-cache
|
data/.rspec
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--color
|
data/.travis.yml
ADDED
data/CHANGELOG.md
ADDED
@@ -0,0 +1,44 @@
|
|
1
|
+
# Changelog
|
2
|
+
|
3
|
+
## 3.0.0
|
4
|
+
- Changed name to octopress-code-highlighter.
|
5
|
+
- Now supporting both Pygments.rb and Rouge for highlighting.
|
6
|
+
|
7
|
+
## 2.0.1
|
8
|
+
- Updated Octopress Ink version, added a simple demo project.
|
9
|
+
|
10
|
+
## 2.0.1
|
11
|
+
- Updated Octopress Ink version, added a simple demo project.
|
12
|
+
|
13
|
+
## 2.0.0
|
14
|
+
- Added support for Octopress Ink
|
15
|
+
|
16
|
+
## 1.3.1
|
17
|
+
- Fixed: line numbers now start at 1 instead of zero.
|
18
|
+
- Changed: `escape` option defaults to false.
|
19
|
+
|
20
|
+
## 1.3.0
|
21
|
+
- Added `escape` option which wraps code in {% raw %} tags to escape liquid. Defaults to true.
|
22
|
+
|
23
|
+
## 1.2.3
|
24
|
+
- Fixed: figcaptions now work when specifying a title.
|
25
|
+
|
26
|
+
## 1.2.2
|
27
|
+
- Now you can call Pygments.read_cache directly.
|
28
|
+
- Added an option to specify a label on cache files.
|
29
|
+
- Simplified caching methods.
|
30
|
+
|
31
|
+
## 1.2.1
|
32
|
+
- Fix: No longer overwriting options with `nil` in parse_markup
|
33
|
+
|
34
|
+
## 1.2.0
|
35
|
+
- Added method for users to specify lexer aliases
|
36
|
+
- Removed default aliases:
|
37
|
+
- ru, yml, coffee - now handled by Pygments correctly
|
38
|
+
- pl, m - match multiple languages, enforcing an alias is inappropriate
|
39
|
+
|
40
|
+
## 1.1.0
|
41
|
+
- Boring bug fixes
|
42
|
+
|
43
|
+
## 1.0.0
|
44
|
+
- Initial release
|
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2013 Brandon Mathis
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
# Octopress CodeStyle
|
2
|
+
|
3
|
+
[](https://travis-ci.org/octopress/octopress-code-style)
|
4
|
+
|
5
|
+
TODO: Write a gem description
|
6
|
+
|
7
|
+
## Installation
|
8
|
+
|
9
|
+
Add this line to your application's Gemfile:
|
10
|
+
|
11
|
+
gem 'octopress-code-style'
|
12
|
+
|
13
|
+
And then execute:
|
14
|
+
|
15
|
+
$ bundle
|
16
|
+
|
17
|
+
Or install it yourself as:
|
18
|
+
|
19
|
+
$ gem install octopress-code-style
|
20
|
+
|
21
|
+
## Usage
|
22
|
+
|
23
|
+
TODO: Write usage instructions here
|
24
|
+
|
25
|
+
## Contributing
|
26
|
+
|
27
|
+
1. Fork it
|
28
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
29
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
30
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
31
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
@@ -0,0 +1,103 @@
|
|
1
|
+
%octopress-diff-bg {
|
2
|
+
content: "";
|
3
|
+
position: absolute;
|
4
|
+
z-index: -1;
|
5
|
+
left: 0; right: 0; top: 0; bottom: 0;
|
6
|
+
}
|
7
|
+
|
8
|
+
@mixin octopress-diff-bg($bg) {
|
9
|
+
&:after {
|
10
|
+
background: $bg;
|
11
|
+
@extend %octopress-diff-bg;
|
12
|
+
}
|
13
|
+
}
|
14
|
+
|
15
|
+
.code-highlight {
|
16
|
+
border: 1px solid $code-highlight-border;
|
17
|
+
background: $pre-bg;
|
18
|
+
color: $base1;
|
19
|
+
span { color: $base1; }
|
20
|
+
span { font-style: normal; font-weight: normal; }
|
21
|
+
|
22
|
+
.c { color: $base01; font-style: italic; } /* Comment */
|
23
|
+
.cm { color: $base01; font-style: italic; } /* Comment.Multiline */
|
24
|
+
.cp { color: $base01; font-style: italic; } /* Comment.Preproc */
|
25
|
+
.c1 { color: $base01; font-style: italic; } /* Comment.Single */
|
26
|
+
.cs { /* Comment.Special */
|
27
|
+
color: $base01;
|
28
|
+
font-weight: bold;
|
29
|
+
font-style: italic; }
|
30
|
+
.err { color: $solar-red; background: none; } /* Error */
|
31
|
+
.k { color: $solar-orange; } /* Keyword */
|
32
|
+
.o { color: $base1; font-weight: bold; } /* Operator */
|
33
|
+
.p { color: $base1; } /* Operator */
|
34
|
+
.ow { color: $solar-cyan; font-weight: bold; } /* Operator.Word */
|
35
|
+
.gd {
|
36
|
+
color: $base1; /* Generic.Deleted */
|
37
|
+
@include octopress-diff-bg(mix($solar-red, $base03, 25%));
|
38
|
+
}
|
39
|
+
.gd .x { /* Generic.Deleted.Specific */
|
40
|
+
color: $base1;
|
41
|
+
@include octopress-diff-bg(mix($solar-red, $base03, 35%));
|
42
|
+
}
|
43
|
+
.ge { /* Generic.Emph */
|
44
|
+
color: $base1;
|
45
|
+
font-style: italic; }
|
46
|
+
//.gr { color: #aa0000 } /* Generic.Error */
|
47
|
+
.gh { color: $base01; } /* Generic.Heading */
|
48
|
+
.gi { /* Generic.Inserted */
|
49
|
+
color: $base1;
|
50
|
+
@include octopress-diff-bg(mix($solar-green, $base03, 20%));
|
51
|
+
}
|
52
|
+
.gi .x { /* Generic.Inserted.Specific */
|
53
|
+
color: $base1;
|
54
|
+
@include octopress-diff-bg(mix($solar-green, $base03, 40%));
|
55
|
+
}
|
56
|
+
//.go { color: #888888 } /* Generic.Output */
|
57
|
+
//.gp { color: #555555 } /* Generic.Prompt */
|
58
|
+
.gs { color: $base1; font-weight: bold; } /* Generic.Strong */
|
59
|
+
.gu { color: $solar-violet; } /* Generic.Subheading */
|
60
|
+
//.gt { color: #aa0000 } /* Generic.Traceback */
|
61
|
+
.kc { color: $solar-green; font-weight: bold; } /* Keyword.Constant */
|
62
|
+
.kd { color: $solar-blue; } /* Keyword.Declaration */
|
63
|
+
.kp { color: $solar-orange; font-weight: bold; } /* Keyword.Pseudo */
|
64
|
+
.kr { color: $solar-magenta; font-weight: bold; } /* Keyword.Reserved */
|
65
|
+
.kt { color: $solar-cyan; } /* Keyword.Type */
|
66
|
+
.n { color: $solar-blue; }
|
67
|
+
.na { color: $solar-blue; } /* Name.Attribute */
|
68
|
+
.nb { color: $solar-green; } /* Name.Builtin */
|
69
|
+
.nc { color: $solar-magenta;} /* Name.Class */
|
70
|
+
.no { color: $solar-yellow; } /* Name.Constant */
|
71
|
+
//.ni { color: #800080 } /* Name.Entity */
|
72
|
+
.nl { color: $solar-green; }
|
73
|
+
.ne { color: $solar-blue; font-weight: bold; } /* Name.Exception */
|
74
|
+
.nf { color: $solar-blue; font-weight: bold; } /* Name.Function */
|
75
|
+
.nn { color: $solar-yellow; } /* Name.Namespace */
|
76
|
+
.nt { color: $solar-blue; font-weight: bold; } /* Name.Tag */
|
77
|
+
.nx { color: $solar-yellow; }
|
78
|
+
//.bp { color: #999999 } /* Name.Builtin.Pseudo */
|
79
|
+
//.vc { color: #008080 } /* Name.Variable.Class */
|
80
|
+
.vg { color: $solar-blue; } /* Name.Variable.Global */
|
81
|
+
.vi { color: $solar-blue; } /* Name.Variable.Instance */
|
82
|
+
.nv { color: $solar-blue; } /* Name.Variable */
|
83
|
+
//.w { color: #bbbbbb } /* Text.Whitespace */
|
84
|
+
.mf { color: $solar-cyan; } /* Literal.Number.Float */
|
85
|
+
.m { color: $solar-cyan; } /* Literal.Number */
|
86
|
+
.mh { color: $solar-cyan; } /* Literal.Number.Hex */
|
87
|
+
.mi { color: $solar-cyan; } /* Literal.Number.Integer */
|
88
|
+
//.mo { color: #009999 } /* Literal.Number.Oct */
|
89
|
+
.s { color: $solar-cyan; } /* Literal.String */
|
90
|
+
//.sb { color: #d14 } /* Literal.String.Backtick */
|
91
|
+
//.sc { color: #d14 } /* Literal.String.Char */
|
92
|
+
.sd { color: $solar-cyan; } /* Literal.String.Doc */
|
93
|
+
.s2 { color: $solar-cyan; } /* Literal.String.Double */
|
94
|
+
.se { color: $solar-red; } /* Literal.String.Escape */
|
95
|
+
//.sh { color: #d14 } /* Literal.String.Heredoc */
|
96
|
+
.si { color: $solar-blue; } /* Literal.String.Interpol */
|
97
|
+
//.sx { color: #d14 } /* Literal.String.Other */
|
98
|
+
.sr { color: $solar-cyan; } /* Literal.String.Regex */
|
99
|
+
.s1 { color: $solar-cyan; } /* Literal.String.Single */
|
100
|
+
//.ss { color: #990073 } /* Literal.String.Symbol */
|
101
|
+
//.il { color: #009999 } /* Literal.Number.Integer.Long */
|
102
|
+
}
|
103
|
+
|
@@ -0,0 +1,58 @@
|
|
1
|
+
$base03: #002b36 !default; //darkest blue
|
2
|
+
$base02: #073642 !default; //dark blue
|
3
|
+
$base01: #586e75 !default; //darkest gray
|
4
|
+
$base00: #657b83 !default; //dark gray
|
5
|
+
$base0: #839496 !default; //medium gray
|
6
|
+
$base1: #93a1a1 !default; //medium light gray
|
7
|
+
$base2: #f2f2f2 !default; //very light gray
|
8
|
+
$base3: #ffffff !default; //white
|
9
|
+
$solar-yellow: #b58900 !default;
|
10
|
+
$solar-orange: #cb4b16 !default;
|
11
|
+
$solar-red: #dc322f !default;
|
12
|
+
$solar-magenta: #d33682 !default;
|
13
|
+
$solar-violet: #6c71c4 !default;
|
14
|
+
$solar-blue: #268bd2 !default;
|
15
|
+
$solar-cyan: #2aa198 !default;
|
16
|
+
$solar-green: #859900 !default;
|
17
|
+
|
18
|
+
$marker: rgba(#00baff, .5) !default;
|
19
|
+
$marker-bg: rgba($marker, .13) !default;
|
20
|
+
$marker-border: rgba($marker, .13) !default;
|
21
|
+
$marker-border-left: $marker !default;
|
22
|
+
|
23
|
+
$solarized: light;// !default;
|
24
|
+
|
25
|
+
$solar-scroll-bg: rgba(#fff, .15);
|
26
|
+
$solar-scroll-thumb: rgba(#fff, .2);
|
27
|
+
|
28
|
+
@if $solarized == light {
|
29
|
+
|
30
|
+
$_base03: $base03;
|
31
|
+
$_base02: $base02;
|
32
|
+
$_base01: $base01;
|
33
|
+
$_base00: $base00;
|
34
|
+
$_base0: $base0;
|
35
|
+
$_base1: $base1;
|
36
|
+
$_base2: $base2;
|
37
|
+
$_base3: $base3;
|
38
|
+
|
39
|
+
$base03: $_base3;
|
40
|
+
$base02: $_base2;
|
41
|
+
$base01: $_base1;
|
42
|
+
$base00: $_base0;
|
43
|
+
$base0: $_base00;
|
44
|
+
$base1: $_base01;
|
45
|
+
$base2: $_base02;
|
46
|
+
$base3: $_base03;
|
47
|
+
|
48
|
+
$solar-scroll-bg: rgba(#000, .15);
|
49
|
+
$solar-scroll-thumb: rgba(#000, .15);
|
50
|
+
|
51
|
+
$marker-bg: rgba($marker, .05);
|
52
|
+
}
|
53
|
+
|
54
|
+
$pre-bg: $base03 !default;
|
55
|
+
$pre-border: darken($base02, 5) !default;
|
56
|
+
$pre-color: $base1 !default;
|
57
|
+
$code-highlight-border: $pre-border;
|
58
|
+
|
@@ -0,0 +1,156 @@
|
|
1
|
+
@import 'solarized';
|
2
|
+
@import 'code-style';
|
3
|
+
|
4
|
+
.code-highlight-figure {
|
5
|
+
font-size: 13px;
|
6
|
+
* { box-sizing: border-box; }
|
7
|
+
}
|
8
|
+
|
9
|
+
.code-highlight-pre {
|
10
|
+
background: darken($base03, 1);
|
11
|
+
width: 100%;
|
12
|
+
margin-bottom: 0;
|
13
|
+
display: table;
|
14
|
+
}
|
15
|
+
|
16
|
+
$pre-line-padding: .8em;
|
17
|
+
|
18
|
+
.code-highlight-row {
|
19
|
+
display: table-row;
|
20
|
+
width: 100%;
|
21
|
+
}
|
22
|
+
|
23
|
+
.code-highlight-row {
|
24
|
+
&:before, .code-highlight-line {
|
25
|
+
padding: {left: $pre-line-padding + .8; right: $pre-line-padding + .8 }
|
26
|
+
}
|
27
|
+
&:first-child {
|
28
|
+
&:before, .code-highlight-line { padding-top: $pre-line-padding; }
|
29
|
+
}
|
30
|
+
&:last-child {
|
31
|
+
&:before, .code-highlight-line { padding-bottom: $pre-line-padding; }
|
32
|
+
}
|
33
|
+
&.numbered {
|
34
|
+
&:before, .code-highlight-line {
|
35
|
+
padding: {left: $pre-line-padding; right: $pre-line-padding }
|
36
|
+
}
|
37
|
+
&:before {
|
38
|
+
display: table-cell;
|
39
|
+
content: attr(data-line);
|
40
|
+
min-width: 1.2em;
|
41
|
+
color: $base01;
|
42
|
+
text-align: right;
|
43
|
+
line-height: 1.45em;
|
44
|
+
@if $solarized == light {
|
45
|
+
background: lighten($base03, 1);
|
46
|
+
border-right: 1px solid darken($base02, 2);
|
47
|
+
text-shadow: lighten($base02, 2) 0 -1px;
|
48
|
+
} @else {
|
49
|
+
background: $base02;
|
50
|
+
border-right: 1px solid darken($base03, 2);
|
51
|
+
box-shadow: lighten($base02, 2) -1px 0 inset;
|
52
|
+
text-shadow: darken($base02, 10) 0 -1px;
|
53
|
+
}
|
54
|
+
}
|
55
|
+
}
|
56
|
+
}
|
57
|
+
|
58
|
+
.code-highlight-line {
|
59
|
+
display: table-cell;
|
60
|
+
width: 100%;
|
61
|
+
position: relative;
|
62
|
+
z-index: 1;
|
63
|
+
}
|
64
|
+
|
65
|
+
.marked-line {
|
66
|
+
position: relative;
|
67
|
+
&.unnumbered {
|
68
|
+
}
|
69
|
+
.code-highlight-line {
|
70
|
+
&:before {
|
71
|
+
content: "";
|
72
|
+
position: absolute;
|
73
|
+
background: $marker-bg;
|
74
|
+
left: 0; top: 0; bottom: 0; right: 0;
|
75
|
+
border-right: 1px solid $marker-border;
|
76
|
+
}
|
77
|
+
}
|
78
|
+
&.unnumbered .code-highlight-line:before {
|
79
|
+
border-left: 3px solid $marker-border-left;
|
80
|
+
}
|
81
|
+
&.numbered:before {
|
82
|
+
background: $marker-bg;
|
83
|
+
border-left: 3px solid $marker-border-left;
|
84
|
+
border-right-color: darken($marker-bg, 20);
|
85
|
+
}
|
86
|
+
}
|
87
|
+
|
88
|
+
.start-marked-line {
|
89
|
+
&:before, .code-highlight-line:before {
|
90
|
+
border-top: 1px solid $marker-border;
|
91
|
+
}
|
92
|
+
}
|
93
|
+
.end-marked-line {
|
94
|
+
&:before, .code-highlight-line:before {
|
95
|
+
border-bottom: 1px solid $marker-border;
|
96
|
+
}
|
97
|
+
}
|
98
|
+
|
99
|
+
.code-highlight {
|
100
|
+
overflow: scroll;
|
101
|
+
overflow-y: hidden;
|
102
|
+
overflow-x: auto;
|
103
|
+
line-height: 1.45em;
|
104
|
+
}
|
105
|
+
|
106
|
+
.code-highlight-table {
|
107
|
+
margin-bottom: 0;
|
108
|
+
background: $base03;
|
109
|
+
pre {
|
110
|
+
padding: .8em;
|
111
|
+
background: none;
|
112
|
+
border-radius: 0;
|
113
|
+
border: none;
|
114
|
+
margin-bottom: 0;
|
115
|
+
}
|
116
|
+
}
|
117
|
+
|
118
|
+
.code-highlight-figure {
|
119
|
+
margin: {left: 0; right: 0;}
|
120
|
+
background: none;
|
121
|
+
padding: 0;
|
122
|
+
border: 0;
|
123
|
+
pre { margin-bottom: 0; }
|
124
|
+
}
|
125
|
+
|
126
|
+
.code-highlight-caption {
|
127
|
+
position: relative;
|
128
|
+
text-align: center;
|
129
|
+
line-height: 2em;
|
130
|
+
text-shadow: #fff 0 1px 0;
|
131
|
+
color: #474747;
|
132
|
+
font-weight: normal;
|
133
|
+
margin-bottom: 0;
|
134
|
+
background-color: #ccc;
|
135
|
+
background-image: linear-gradient(#ffffff, #f0f0f0 6%, #e5e5e5 90%, #e5e5e5);
|
136
|
+
border-top-left-radius: 5px;
|
137
|
+
border-top-right-radius: 5px;
|
138
|
+
font-family: "Helvetica Neue", Arial, "Lucida Grande", "Lucida Sans Unicode", Lucida, sans-serif;
|
139
|
+
border: 1px solid #cbcbcb;
|
140
|
+
+ .code-highlight { border-top: 0; }
|
141
|
+
}
|
142
|
+
|
143
|
+
.code-highlight-caption-link {
|
144
|
+
position: absolute; right: .8em;
|
145
|
+
color: #666;
|
146
|
+
z-index: 1;
|
147
|
+
text-shadow: #cbcccc 0 1px 0;
|
148
|
+
padding-left: 3em;
|
149
|
+
}
|
150
|
+
|
151
|
+
pre {
|
152
|
+
margin-top: 0;
|
153
|
+
font-size: 13px;
|
154
|
+
font-family: Menlo, Monaco, 'Andale Mono', 'lucida console', 'Courier New', monospace;
|
155
|
+
}
|
156
|
+
|
@@ -0,0 +1,67 @@
|
|
1
|
+
require 'octopress-code-highlighter/version'
|
2
|
+
require 'fileutils'
|
3
|
+
require 'digest/md5'
|
4
|
+
|
5
|
+
require 'colorator'
|
6
|
+
require 'octopress-ink'
|
7
|
+
|
8
|
+
CODE_CACHE_DIR = '.code-cache'
|
9
|
+
FileUtils.mkdir_p(CODE_CACHE_DIR)
|
10
|
+
|
11
|
+
module Octopress
|
12
|
+
module CodeHighlighter
|
13
|
+
DEFAULTS = {
|
14
|
+
lang: 'plain',
|
15
|
+
linenos: true,
|
16
|
+
marks: [],
|
17
|
+
start: 1
|
18
|
+
}
|
19
|
+
|
20
|
+
autoload :Cache, 'octopress-code-highlighter/cache'
|
21
|
+
autoload :OptionsParser, 'octopress-code-highlighter/options_parser'
|
22
|
+
autoload :Renderer, 'octopress-code-highlighter/renderer'
|
23
|
+
|
24
|
+
def self.highlight(code, options={})
|
25
|
+
Renderer.new(code, options).highlight
|
26
|
+
end
|
27
|
+
|
28
|
+
def self.read_cache(code, options={})
|
29
|
+
Cache.read_cache(code, options)
|
30
|
+
end
|
31
|
+
|
32
|
+
def self.parse_markup(input, defaults={})
|
33
|
+
OptionsParser.new(input).parse_markup(defaults)
|
34
|
+
end
|
35
|
+
|
36
|
+
def self.clean_markup(input)
|
37
|
+
OptionsParser.new(input).clean_markup
|
38
|
+
end
|
39
|
+
|
40
|
+
def self.highlight_failed(error, syntax, markup, code, file = nil)
|
41
|
+
code_snippet = code.split("\n")[0..9].map{|l| " #{l}" }.join("\n")
|
42
|
+
fail_message = "\nError while parsing the following markup#{" in #{file}" if file}:\n\n".red
|
43
|
+
fail_message += " #{markup}\n#{code_snippet}\n"
|
44
|
+
fail_message += "#{" ..." if code.split("\n").size > 10}\n"
|
45
|
+
fail_message += "\nValid Syntax:\n\n#{syntax}\n".yellow
|
46
|
+
fail_message += "\nError:\n\n#{error.message}".red
|
47
|
+
$stderr.puts fail_message.chomp
|
48
|
+
raise ArgumentError
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
class CodeHighlighter < Octopress::Ink::Plugin
|
54
|
+
def initialize(name, type)
|
55
|
+
@assets_path = File.expand_path(File.join(File.dirname(__FILE__), '../assets'))
|
56
|
+
@version = Octopress::CodeHighlighter::VERSION
|
57
|
+
@description = "For beautiful code snippets."
|
58
|
+
super
|
59
|
+
end
|
60
|
+
|
61
|
+
def add_assets
|
62
|
+
add_sass 'code.scss'
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
Octopress::Ink.register_plugin(CodeHighlighter, 'octopress-code-highlighter', 'plugin')
|
67
|
+
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module Octopress
|
2
|
+
module CodeHighlighter
|
3
|
+
class Cache
|
4
|
+
CODE_CACHE_DIR = '.code-style-cache'
|
5
|
+
|
6
|
+
class << self
|
7
|
+
def read_cache(code, options)
|
8
|
+
cache_label = options[:cache_label] || options[:lang] || ''
|
9
|
+
path = get_cache_path(CODE_CACHE_DIR, cache_label, options.to_s + code)
|
10
|
+
File.exist?(path) ? File.read(path) : nil unless path.nil?
|
11
|
+
end
|
12
|
+
|
13
|
+
def write_to_cache(contents, options)
|
14
|
+
FileUtils.mkdir_p(CODE_CACHE_DIR) unless File.directory?(CODE_CACHE_DIR)
|
15
|
+
cache_label = options[:cache_label] || options[:lang] || ''
|
16
|
+
path = get_cache_path(CODE_CACHE_DIR, cache_label, options.to_s + contents)
|
17
|
+
File.open(path, 'w') do |f|
|
18
|
+
f.print(contents)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def get_cache_path(dir, label, str)
|
23
|
+
label += '-' unless label === ''
|
24
|
+
File.join(dir, "#{label}#{Digest::MD5.hexdigest(str)}.html")
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
@@ -0,0 +1,129 @@
|
|
1
|
+
module Octopress
|
2
|
+
module CodeHighlighter
|
3
|
+
class OptionsParser
|
4
|
+
attr_accessor :input
|
5
|
+
|
6
|
+
def initialize(markup)
|
7
|
+
@input = markup.strip
|
8
|
+
end
|
9
|
+
|
10
|
+
def clean_markup
|
11
|
+
input.sub(/\s*lang:\s*\S+/i,'')
|
12
|
+
.sub(/\s*title:\s*(("(.+?)")|('(.+?)')|(\S+))/i,'')
|
13
|
+
.sub(/\s*url:\s*(\S+)/i,'')
|
14
|
+
.sub(/\s*link_text:\s*(("(.+?)")|('(.+?)')|(\S+))/i,'')
|
15
|
+
.sub(/\s*mark:\s*\d\S*/i,'')
|
16
|
+
.sub(/\s*linenos:\s*\w+/i,'')
|
17
|
+
.sub(/\s*start:\s*\d+/i,'')
|
18
|
+
.sub(/\s*end:\s*\d+/i,'')
|
19
|
+
.sub(/\s*range:\s*\d+-\d+/i,'')
|
20
|
+
.sub(/\s*escape:\s*\w+/i,'')
|
21
|
+
end
|
22
|
+
|
23
|
+
def parse_markup(defaults = {})
|
24
|
+
options = {
|
25
|
+
lang: lang,
|
26
|
+
url: url,
|
27
|
+
title: title,
|
28
|
+
linenos: linenos,
|
29
|
+
marks: marks,
|
30
|
+
link_text: link_text,
|
31
|
+
start: start,
|
32
|
+
end: endline,
|
33
|
+
escape: escape
|
34
|
+
}
|
35
|
+
options = options.delete_if { |k,v| v.nil? }
|
36
|
+
defaults.merge(options)
|
37
|
+
end
|
38
|
+
|
39
|
+
def lang
|
40
|
+
extract(/\s*lang:\s*(\S+)/i)
|
41
|
+
end
|
42
|
+
|
43
|
+
def url
|
44
|
+
extract(/\s*url:\s*(("(.+?)")|('(.+?)')|(\S+))/i, [3, 5, 6])
|
45
|
+
end
|
46
|
+
|
47
|
+
def title
|
48
|
+
extract(/\s*title:\s*(("(.+?)")|('(.+?)')|(\S+))/i, [3, 5, 6])
|
49
|
+
end
|
50
|
+
|
51
|
+
def linenos
|
52
|
+
boolize(extract(/\s*linenos:\s*(\w+)/i))
|
53
|
+
end
|
54
|
+
|
55
|
+
def escape
|
56
|
+
boolize(extract(/\s*escape:\s*(\w+)/i))
|
57
|
+
end
|
58
|
+
|
59
|
+
# Public: Matches pattern for line marks and returns array of line
|
60
|
+
# numbers to mark
|
61
|
+
#
|
62
|
+
# Example input
|
63
|
+
# Input: "mark:1,5-10,2"
|
64
|
+
# Output: [1,2,5,6,7,8,9,10]
|
65
|
+
#
|
66
|
+
# Returns an array of integers corresponding to the lines which are
|
67
|
+
# indicated as marked
|
68
|
+
def marks
|
69
|
+
marks = []
|
70
|
+
if input =~ / *mark:(\d\S*)/i
|
71
|
+
marks = $1.gsub /(\d+)-(\d+)/ do
|
72
|
+
($1.to_i..$2.to_i).to_a.join(',')
|
73
|
+
end
|
74
|
+
marks = marks.split(',').collect {|s| s.to_i}.sort
|
75
|
+
end
|
76
|
+
marks
|
77
|
+
end
|
78
|
+
|
79
|
+
def link_text
|
80
|
+
extract(/\s*link[-_]text:\s*(("(.+?)")|('(.+?)')|(\S+))/i, [3, 5, 6], 'link')
|
81
|
+
end
|
82
|
+
|
83
|
+
def start
|
84
|
+
if range
|
85
|
+
range.first
|
86
|
+
else
|
87
|
+
num = extract(/\s*start:\s*(\d+)/i)
|
88
|
+
num = num.to_i unless num.nil?
|
89
|
+
num
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
def endline
|
94
|
+
if range
|
95
|
+
range.last
|
96
|
+
else
|
97
|
+
num = extract(/\s*end:\s*(\d+)/i)
|
98
|
+
num = num.to_i unless num.nil?
|
99
|
+
num
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
def range
|
104
|
+
if input.match(/ *range:(\d+)-(\d+)/i)
|
105
|
+
[$1.to_i, $2.to_i]
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
def extract(regexp, indices_to_try = [1], default = nil)
|
110
|
+
thing = input.match(regexp)
|
111
|
+
if thing.nil?
|
112
|
+
default
|
113
|
+
else
|
114
|
+
indices_to_try.each do |index|
|
115
|
+
return thing[index] if thing[index]
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
def boolize(str)
|
121
|
+
return nil if str.nil?
|
122
|
+
return true if str == true || str =~ (/(true|t|yes|y|1)$/i)
|
123
|
+
return false if str == false || str =~ (/(false|f|no|n|0)$/i) || str.strip.size > 1
|
124
|
+
return str
|
125
|
+
end
|
126
|
+
end
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
@@ -0,0 +1,165 @@
|
|
1
|
+
module Octopress
|
2
|
+
module CodeHighlighter
|
3
|
+
class Renderer
|
4
|
+
attr_reader :code, :options, :lang
|
5
|
+
|
6
|
+
def initialize(code, options = {})
|
7
|
+
@code = code
|
8
|
+
@options = options.delete_if { |k,v| v.nil? }
|
9
|
+
@options = DEFAULTS.merge(@options)
|
10
|
+
@aliases = stringify_keys(@options[:aliases] || {})
|
11
|
+
@lang = @options[:lang]
|
12
|
+
@options[:title] ||= ' ' if @options[:url]
|
13
|
+
@renderer = select_renderer
|
14
|
+
end
|
15
|
+
|
16
|
+
def select_renderer
|
17
|
+
begin
|
18
|
+
require 'rouge'
|
19
|
+
return 'rouge' if defined?(Rouge)
|
20
|
+
rescue LoadError; end
|
21
|
+
begin
|
22
|
+
require 'pygments.rb'
|
23
|
+
return 'pygments' if defined?(Pygments)
|
24
|
+
rescue LoadError
|
25
|
+
puts "To highlight code, install the gem pygments.rb or rouge.".red
|
26
|
+
return 'plain'
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def highlight
|
31
|
+
if cache = Cache.read_cache(code, options)
|
32
|
+
cache
|
33
|
+
else
|
34
|
+
rendered_code = render
|
35
|
+
rendered_code = encode_liquid(rendered_code)
|
36
|
+
rendered_code = tableize_code(rendered_code)
|
37
|
+
rendered_code = "<figure class='code-highlight-figure'>#{caption}#{rendered_code}</figure>"
|
38
|
+
rendered_code = "{% raw %}#{rendered_code}{% endraw %}" if options[:escape]
|
39
|
+
Cache.write_to_cache(rendered_code, options) unless options[:no_cache]
|
40
|
+
rendered_code
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
def plain?
|
45
|
+
options[:lang].empty? || options[:lang] == 'plain'
|
46
|
+
end
|
47
|
+
|
48
|
+
def render
|
49
|
+
case @renderer
|
50
|
+
when 'pygments'
|
51
|
+
code = render_pygments
|
52
|
+
when 'rouge'
|
53
|
+
code = render_rouge
|
54
|
+
else
|
55
|
+
code = render_plain
|
56
|
+
end
|
57
|
+
|
58
|
+
if code =~ /<pre.+?>(.+)<\/pre>/m
|
59
|
+
$1.strip
|
60
|
+
else
|
61
|
+
code
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
def render_plain
|
66
|
+
@code.gsub('<','<')
|
67
|
+
end
|
68
|
+
|
69
|
+
def render_pygments
|
70
|
+
if lexer = Pygments::Lexer.find(lang) || Pygments::Lexer.find(@aliases[lang])
|
71
|
+
begin
|
72
|
+
lexer.highlight @code, {
|
73
|
+
formatter: 'html',
|
74
|
+
options: {
|
75
|
+
encoding: 'utf-8'
|
76
|
+
}
|
77
|
+
}
|
78
|
+
rescue MentosError => e
|
79
|
+
raise e
|
80
|
+
end
|
81
|
+
else
|
82
|
+
render_plain
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
def render_rouge
|
87
|
+
if lexer = Rouge::Lexer.find(lang) || Rouge::Lexer.find(@aliases[lang])
|
88
|
+
formatter = ::Rouge::Formatters::HTML.new()
|
89
|
+
formatter.format(lexer.lex(@code))
|
90
|
+
else
|
91
|
+
render_plain
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
def caption
|
96
|
+
if options[:title]
|
97
|
+
figcaption = "<figcaption class='code-highlight-caption'><span class='code-highlight-caption-title'>#{options[:title]}</span>"
|
98
|
+
figcaption += "<a class='code-highlight-caption-link' href='#{options[:url]}'>#{(options[:link_text] || 'link').strip}</a>" if options[:url]
|
99
|
+
figcaption += "</figcaption>"
|
100
|
+
else
|
101
|
+
''
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
def tableize_code(code)
|
106
|
+
start = options[:start]
|
107
|
+
lines = options[:linenos]
|
108
|
+
marks = options[:marks]
|
109
|
+
|
110
|
+
table = "<div class='code-highlight'>"
|
111
|
+
table += "<pre class='code-highlight-pre'>"
|
112
|
+
code.lines.each_with_index do |line,index|
|
113
|
+
classes = 'code-highlight-row'
|
114
|
+
classes += lines ? ' numbered' : ' unnumbered'
|
115
|
+
if marks.include? index + start
|
116
|
+
classes += ' marked-line'
|
117
|
+
classes += ' start-marked-line' unless marks.include? index - 1 + start
|
118
|
+
classes += ' end-marked-line' unless marks.include? index + 1 + start
|
119
|
+
end
|
120
|
+
line = line.strip.empty? ? ' ' : line
|
121
|
+
table += "<div data-line='#{index + start}' class='#{classes}'><div class='code-highlight-line'>#{line}</div></div>"
|
122
|
+
end
|
123
|
+
table +="</pre></div>"
|
124
|
+
end
|
125
|
+
|
126
|
+
# Public:
|
127
|
+
#
|
128
|
+
#
|
129
|
+
def get_range(code, start, endline)
|
130
|
+
length = code.lines.count
|
131
|
+
start
|
132
|
+
endline ||= length
|
133
|
+
if start > 1 or endline < length
|
134
|
+
raise "#{filepath} is #{length} lines long, cannot begin at line #{start}" if start > length
|
135
|
+
raise "#{filepath} is #{length} lines long, cannot read beyond line #{endline}" if endline > length
|
136
|
+
code = code.split(/\n/).slice(start - 1, endline + 1 - start).join("\n")
|
137
|
+
end
|
138
|
+
code
|
139
|
+
end
|
140
|
+
|
141
|
+
def encode_liquid(code)
|
142
|
+
code.gsub(/{{/, '{{')
|
143
|
+
.gsub(/{%/, '{%')
|
144
|
+
end
|
145
|
+
|
146
|
+
private
|
147
|
+
|
148
|
+
def stringify_keys(hash)
|
149
|
+
hash.inject({}){|result, (key, value)|
|
150
|
+
new_key = case key
|
151
|
+
when String then key.to_s
|
152
|
+
else key
|
153
|
+
end
|
154
|
+
new_value = case value
|
155
|
+
when Hash then stringify_keys(value)
|
156
|
+
else value
|
157
|
+
end
|
158
|
+
result[new_key] = new_value
|
159
|
+
result
|
160
|
+
}
|
161
|
+
end
|
162
|
+
end
|
163
|
+
end
|
164
|
+
end
|
165
|
+
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'octopress-code-highlighter/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |gem|
|
7
|
+
gem.name = "octopress-code-highlighter"
|
8
|
+
gem.version = Octopress::CodeHighlighter::VERSION
|
9
|
+
gem.authors = ["Brandon Mathis"]
|
10
|
+
gem.email = ["brandon@imathis.com"]
|
11
|
+
gem.description = %q{Octopress's core plugin for rendering nice code blocks}
|
12
|
+
gem.summary = %q{Octopress's core plugin for rendering nice code blocks}
|
13
|
+
gem.homepage = "https://github.com/octopress/code-highlighter"
|
14
|
+
gem.license = "MIT"
|
15
|
+
|
16
|
+
gem.add_runtime_dependency 'colorator', '~> 0.1.0'
|
17
|
+
gem.add_runtime_dependency 'octopress-ink', '>= 1.0.0.alpha.33'
|
18
|
+
|
19
|
+
gem.add_development_dependency 'pry-debugger'
|
20
|
+
gem.add_development_dependency 'rake'
|
21
|
+
gem.add_development_dependency 'rspec'
|
22
|
+
gem.add_development_dependency 'rouge', '~> 1.3.2'
|
23
|
+
|
24
|
+
gem.files = `git ls-files`.split($/).reject {|f| f =~ /^demo\// }
|
25
|
+
gem.require_paths = ["lib"]
|
26
|
+
end
|
@@ -0,0 +1,139 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Octopress::CodeHighlighter do
|
4
|
+
let(:wrapper) do
|
5
|
+
Proc.new do |stuff, numbers|
|
6
|
+
[
|
7
|
+
"<figure class='code-highlight-figure'>",
|
8
|
+
"<div class='code-highlight'>",
|
9
|
+
"<pre class='code-highlight-pre'>#{stuff}</pre>",
|
10
|
+
"</div></figure>"
|
11
|
+
].join
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
let(:expected_output_no_options) do
|
16
|
+
stuff = <<-EOF
|
17
|
+
<figure class='code-highlight-figure'><div class='code-highlight'><pre class='code-highlight-pre'><div data-line='1' class='code-highlight-row numbered'><div class='code-highlight-line'> require "hi-there-honey"
|
18
|
+
</div></div><div data-line='2' class='code-highlight-row numbered'><div class='code-highlight-line'> </div></div><div data-line='3' class='code-highlight-row numbered'><div class='code-highlight-line'> def hi-there-honey
|
19
|
+
</div></div><div data-line='4' class='code-highlight-row numbered'><div class='code-highlight-line'> HiThereHoney.new("your name")
|
20
|
+
</div></div><div data-line='5' class='code-highlight-row numbered'><div class='code-highlight-line'> end
|
21
|
+
</div></div><div data-line='6' class='code-highlight-row numbered'><div class='code-highlight-line'> </div></div><div data-line='7' class='code-highlight-row numbered'><div class='code-highlight-line'> hi-there-honey
|
22
|
+
</div></div><div data-line='8' class='code-highlight-row numbered'><div class='code-highlight-line'> # => "Hi, your name"
|
23
|
+
</div></div></pre></div></figure>
|
24
|
+
EOF
|
25
|
+
stuff.strip
|
26
|
+
end
|
27
|
+
|
28
|
+
let(:expected_output_lang_ruby) do
|
29
|
+
stuff = <<-EOF
|
30
|
+
{% raw %}<figure class='code-highlight-figure'><div class='code-highlight'><pre class='code-highlight-pre'><div data-line='1' class='code-highlight-row numbered'><div class='code-highlight-line'><span class="nb">require</span> <span class="s2">"hi-there-honey"</span>
|
31
|
+
</div></div><div data-line='2' class='code-highlight-row numbered'><div class='code-highlight-line'> </div></div><div data-line='3' class='code-highlight-row numbered'><div class='code-highlight-line'> <span class="k">def</span> <span class="nf">hi</span><span class="o">-</span><span class="n">there</span><span class="o">-</span><span class="n">honey</span>
|
32
|
+
</div></div><div data-line='4' class='code-highlight-row numbered'><div class='code-highlight-line'> <span class="no">HiThereHoney</span><span class="p">.</span><span class="nf">new</span><span class="p">(</span><span class="s2">"your name"</span><span class="p">)</span>
|
33
|
+
</div></div><div data-line='5' class='code-highlight-row numbered'><div class='code-highlight-line'> <span class="k">end</span>
|
34
|
+
</div></div><div data-line='6' class='code-highlight-row numbered'><div class='code-highlight-line'> </div></div><div data-line='7' class='code-highlight-row numbered'><div class='code-highlight-line'> <span class="n">hi</span><span class="o">-</span><span class="n">there</span><span class="o">-</span><span class="n">honey</span>
|
35
|
+
</div></div><div data-line='8' class='code-highlight-row numbered'><div class='code-highlight-line'> <span class="c1"># => "Hi, your name"</span></div></div></pre></div></figure>{% endraw %}
|
36
|
+
EOF
|
37
|
+
end
|
38
|
+
|
39
|
+
let(:code) do
|
40
|
+
<<-EOF
|
41
|
+
require "hi-there-honey"
|
42
|
+
|
43
|
+
def hi-there-honey
|
44
|
+
HiThereHoney.new("your name")
|
45
|
+
end
|
46
|
+
|
47
|
+
hi-there-honey
|
48
|
+
# => "Hi, your name"
|
49
|
+
EOF
|
50
|
+
end
|
51
|
+
|
52
|
+
let(:markup) do
|
53
|
+
[
|
54
|
+
"lang:abc",
|
55
|
+
'title:"Hello"',
|
56
|
+
"url:http://something.com/hi/fuaiofnioaf.html",
|
57
|
+
"link_text:'get it here'",
|
58
|
+
"mark:5,8-10,15",
|
59
|
+
"linenos: yes",
|
60
|
+
"start: 5",
|
61
|
+
"end: 15",
|
62
|
+
"range: 5-15"
|
63
|
+
].join(" ")
|
64
|
+
end
|
65
|
+
|
66
|
+
let(:bad_markup) do
|
67
|
+
[
|
68
|
+
"lang:ruby",
|
69
|
+
'title:"Hello"',
|
70
|
+
"url:http://something.com/hi/fuaiofnioaf.html",
|
71
|
+
"link_text: get it here",
|
72
|
+
"mark:5,8-10,15",
|
73
|
+
"linenos: yes",
|
74
|
+
"start: 5",
|
75
|
+
"end: 15",
|
76
|
+
"range: 5-15"
|
77
|
+
].join(" ")
|
78
|
+
end
|
79
|
+
|
80
|
+
let(:options) do
|
81
|
+
{
|
82
|
+
lang: "abc",
|
83
|
+
url: "http://something.com/hi/fuaiofnioaf.html",
|
84
|
+
title: "Hello",
|
85
|
+
linenos: true,
|
86
|
+
marks: [5, 8, 9, 10, 15],
|
87
|
+
link_text: "get it here",
|
88
|
+
start: 5,
|
89
|
+
end: 15
|
90
|
+
}
|
91
|
+
end
|
92
|
+
|
93
|
+
describe ".highlight" do
|
94
|
+
it "returns HTML for an empty code block" do
|
95
|
+
expect(described_class.highlight("", {})).to eql(wrapper.call("", ""))
|
96
|
+
end
|
97
|
+
|
98
|
+
context "with no options" do
|
99
|
+
it "returns the right HTML for a given set of code" do
|
100
|
+
expect(described_class.highlight(code, {})).to eql(expected_output_no_options)
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
context "with a language" do
|
105
|
+
it "returns the right HTML for a given set of code" do
|
106
|
+
expect(described_class.highlight(code, { lang: 'abc', aliases: {'abc'=>'ruby'}, escape: true })).to eql(expected_output_lang_ruby.chop)
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
describe ".highlight_failed" do
|
112
|
+
#described_class.highlight_failed(error, syntax, markup, code, file = nil)
|
113
|
+
end
|
114
|
+
|
115
|
+
describe ".parse_markup" do
|
116
|
+
context "with no defaults" do
|
117
|
+
it "parses the defaults correctly" do
|
118
|
+
expect(described_class.parse_markup(markup, {})).to eql(options)
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
context "with defaults with a nil value" do
|
123
|
+
it "overrides the nil values" do
|
124
|
+
expect(described_class.parse_markup(markup, { lang: nil })).to eql(options)
|
125
|
+
end
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
describe ".clean_markup" do
|
130
|
+
|
131
|
+
it "returns an empty string with good markup" do
|
132
|
+
expect(described_class.clean_markup(markup)).to eql("")
|
133
|
+
end
|
134
|
+
|
135
|
+
it "returns erroneous text that isn't part of the markup" do
|
136
|
+
expect(described_class.clean_markup(bad_markup)).to eql(" it here")
|
137
|
+
end
|
138
|
+
end
|
139
|
+
end
|
data/spec/spec_helper.rb
ADDED
metadata
ADDED
@@ -0,0 +1,147 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: octopress-code-highlighter
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 3.0.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Brandon Mathis
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2014-03-03 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: colorator
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ~>
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 0.1.0
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ~>
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 0.1.0
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: octopress-ink
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - '>='
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 1.0.0.alpha.33
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - '>='
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: 1.0.0.alpha.33
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: pry-debugger
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - '>='
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - '>='
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rake
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - '>='
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: rspec
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - '>='
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - '>='
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: rouge
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ~>
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: 1.3.2
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ~>
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: 1.3.2
|
97
|
+
description: Octopress's core plugin for rendering nice code blocks
|
98
|
+
email:
|
99
|
+
- brandon@imathis.com
|
100
|
+
executables: []
|
101
|
+
extensions: []
|
102
|
+
extra_rdoc_files: []
|
103
|
+
files:
|
104
|
+
- .gitignore
|
105
|
+
- .rspec
|
106
|
+
- .travis.yml
|
107
|
+
- CHANGELOG.md
|
108
|
+
- Gemfile
|
109
|
+
- LICENSE.txt
|
110
|
+
- README.md
|
111
|
+
- Rakefile
|
112
|
+
- assets/stylesheets/_code-style.scss
|
113
|
+
- assets/stylesheets/_solarized.scss
|
114
|
+
- assets/stylesheets/code.scss
|
115
|
+
- lib/octopress-code-highlighter.rb
|
116
|
+
- lib/octopress-code-highlighter/cache.rb
|
117
|
+
- lib/octopress-code-highlighter/options_parser.rb
|
118
|
+
- lib/octopress-code-highlighter/renderer.rb
|
119
|
+
- lib/octopress-code-highlighter/version.rb
|
120
|
+
- octopress-code-highlighter.gemspec
|
121
|
+
- spec/pygments_spec.rb
|
122
|
+
- spec/spec_helper.rb
|
123
|
+
homepage: https://github.com/octopress/code-highlighter
|
124
|
+
licenses:
|
125
|
+
- MIT
|
126
|
+
metadata: {}
|
127
|
+
post_install_message:
|
128
|
+
rdoc_options: []
|
129
|
+
require_paths:
|
130
|
+
- lib
|
131
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
132
|
+
requirements:
|
133
|
+
- - '>='
|
134
|
+
- !ruby/object:Gem::Version
|
135
|
+
version: '0'
|
136
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
137
|
+
requirements:
|
138
|
+
- - '>='
|
139
|
+
- !ruby/object:Gem::Version
|
140
|
+
version: '0'
|
141
|
+
requirements: []
|
142
|
+
rubyforge_project:
|
143
|
+
rubygems_version: 2.1.11
|
144
|
+
signing_key:
|
145
|
+
specification_version: 4
|
146
|
+
summary: Octopress's core plugin for rendering nice code blocks
|
147
|
+
test_files: []
|