github-markdown-preview 1.6.1 → 2.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +6 -14
- data/.gitignore +5 -1
- data/.travis.yml +7 -2
- data/CHANGELOG.md +8 -0
- data/Gemfile.optional +12 -0
- data/bin/github-markdown-preview +6 -4
- data/github-markdown-preview.gemspec +8 -8
- data/lib/github-markdown-preview.rb +1 -1
- data/lib/github-markdown-preview/filter/task_list_filter.rb +48 -0
- data/lib/github-markdown-preview/html_preview.rb +39 -18
- data/lib/github-markdown-preview/version.rb +1 -1
- data/readme.md +49 -25
- data/test/filter/task_list_filter_test.rb +87 -0
- data/test/github-markdown-preview_test.rb +1 -1
- data/test/html_preview_test.rb +92 -7
- metadata +44 -40
checksums.yaml
CHANGED
@@ -1,15 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
metadata.gz: !binary |-
|
9
|
-
ZmY1OWYxYWIxMGZiYWMyNjQwMGMyZDlmNmM5OGExM2UwYzc4ODI4ZTc0N2Y4
|
10
|
-
YmRjZmU0YmVkYTMxN2ZmM2NmNzkyY2Q2ZWRjOTQwOGNkOGFlOTNjNzk1NTQ5
|
11
|
-
ZjA4NTcyZDcwNDA0MjdkYjliYzk1MDRkMmM4ZWRjZjQxNjI1NmE=
|
12
|
-
data.tar.gz: !binary |-
|
13
|
-
MjlhYjhlMmExNjczNGEzNWE5MWJlODc4NzliZjc4OTYwZjI3OWY3NTM1YWY2
|
14
|
-
ZWU5NTk5MGU3MjAzNWQzODQxYTFkYmJmNDU3MDI2YWM1NzhmODUzNjRlNDUy
|
15
|
-
Yzg3NjNhOWMyNWY3ZDhmMDBjM2E5ZmNlNDlmODIxOWY3ZTc4OWI=
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 934cef69d969c91a47e1a83202610d45ae2b9eb5
|
4
|
+
data.tar.gz: e428f16a7f79b7e75d0c660b97176be16d8cf223
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: ffdacce3bc2c2e0ece0bc594884e17fd8fb6d4eb364ee25df2028a288062a555f0774ce8644455f4311795b4b12d485639f7e9ca03abc0adbe64b9ea755a4b1c
|
7
|
+
data.tar.gz: 7819d7183b111e3e5f3567bf23bb14018d50c5a1a4d7b71dcd4c07664f2abf62475b730b6fef36e3a0cf6be36e75ca073608f09b2025e1099e65a2137b6b8779
|
data/.gitignore
CHANGED
@@ -30,6 +30,9 @@ target
|
|
30
30
|
.idea
|
31
31
|
out
|
32
32
|
|
33
|
+
# markdown previews
|
34
|
+
*.md.html
|
35
|
+
|
33
36
|
# bundler suggested ignores
|
34
37
|
*.gem
|
35
38
|
*.rbc
|
@@ -37,6 +40,7 @@ out
|
|
37
40
|
.config
|
38
41
|
.yardoc
|
39
42
|
Gemfile.lock
|
43
|
+
Gemfile.optional.lock
|
40
44
|
InstalledFiles
|
41
45
|
_yardoc
|
42
46
|
coverage
|
@@ -47,4 +51,4 @@ rdoc
|
|
47
51
|
spec/reports
|
48
52
|
test/tmp
|
49
53
|
test/version_tmp
|
50
|
-
tmp
|
54
|
+
tmp
|
data/.travis.yml
CHANGED
@@ -1,7 +1,12 @@
|
|
1
|
-
before_install: sudo apt-get install libicu-dev -y
|
2
1
|
language: ruby
|
3
2
|
rvm:
|
4
3
|
- "1.8.7"
|
5
4
|
- "1.9.3"
|
6
5
|
- "2.0.0"
|
7
|
-
env:
|
6
|
+
env:
|
7
|
+
- INCLUDE_LINGUIST=true
|
8
|
+
- INCLUDE_LINGUIST=false
|
9
|
+
|
10
|
+
before_install:
|
11
|
+
- gem update --system 2.1.11 # todo: workaround for https://github.com/rubygems/rubygems/pull/763. Delete it once that fix is released
|
12
|
+
- if [[ "$INCLUDE_LINGUIST" == "true" ]]; then BUNDLE_GEMFILE=Gemfile.optional; sudo apt-get install libicu-dev -y; fi
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,13 @@
|
|
1
1
|
# Changelog
|
2
2
|
|
3
|
+
## v2.0.0
|
4
|
+
* Add the ability to render a [preview of how Github renders comments/issues](https://github.com/dmarcotte/github-markdown-preview#comment-mode)
|
5
|
+
* Make the `github-linguist` dependency [optional](https://github.com/dmarcotte/github-markdown-preview/pull/14)
|
6
|
+
* [Update dependencies](https://github.com/dmarcotte/github-markdown-preview/pull/13)
|
7
|
+
* Breaking changes:
|
8
|
+
- `preview.delete_on_exit` no longer exists. To delete the preview on exit, pass the `:delete_on_exit = true` option ([example here](https://github.com/dmarcotte/github-markdown-preview#code))
|
9
|
+
- Since `github-linguist` is not longer required, previews on systems without it installed will not have syntax highlighting
|
10
|
+
|
3
11
|
## v1.6.1
|
4
12
|
* Fix [#11](https://github.com/dmarcotte/github-markdown-preview/issues/11)
|
5
13
|
|
data/Gemfile.optional
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
# custom Gemfile for bundling/testing with optional 'github-linguist' dep
|
2
|
+
# usage: BUNDLE_GEMFILE=Gemfile.optional bundle <command>
|
3
|
+
|
4
|
+
source 'https://rubygems.org'
|
5
|
+
|
6
|
+
gemspec
|
7
|
+
|
8
|
+
if RUBY_VERSION =~ /1.8/
|
9
|
+
gem 'escape_utils', '~> 0.3'
|
10
|
+
end
|
11
|
+
|
12
|
+
gem 'github-linguist'
|
data/bin/github-markdown-preview
CHANGED
@@ -3,11 +3,16 @@
|
|
3
3
|
require 'github-markdown-preview'
|
4
4
|
require 'optparse'
|
5
5
|
|
6
|
+
comment_mode = false
|
6
7
|
opt_parser = OptionParser.new do |opt|
|
7
8
|
opt.banner = "Usage: github-markdown-preview PATH_TO_MD_FILE"
|
8
9
|
opt.separator ""
|
9
10
|
opt.separator "Options"
|
10
11
|
|
12
|
+
opt.on("-c", "--comment-mode", "renders a preview for Github comments/issues") do
|
13
|
+
comment_mode = true
|
14
|
+
end
|
15
|
+
|
11
16
|
opt.on("-v", "--version", "print the version") do
|
12
17
|
$stdout.puts 'github-markdown-preview version ' + GithubMarkdownPreview::VERSION
|
13
18
|
Kernel.exit
|
@@ -23,7 +28,7 @@ end
|
|
23
28
|
|
24
29
|
begin
|
25
30
|
source_file = ARGV.at(0)
|
26
|
-
preview = GithubMarkdownPreview::HtmlPreview.new(source_file)
|
31
|
+
preview = GithubMarkdownPreview::HtmlPreview.new(source_file, { :delete_on_exit => true, :comment_mode => comment_mode })
|
27
32
|
rescue GithubMarkdownPreview::FileNotFoundError
|
28
33
|
$stderr.puts "#{source_file}: No such file"
|
29
34
|
exit 1
|
@@ -35,9 +40,6 @@ else
|
|
35
40
|
$stdout.puts preview.preview_file
|
36
41
|
end
|
37
42
|
|
38
|
-
# delete preview html on exit
|
39
|
-
preview.delete_on_exit = true
|
40
|
-
|
41
43
|
# make sure we've said what we have to say before we block watching the file
|
42
44
|
$stdout.flush
|
43
45
|
|
@@ -9,17 +9,17 @@ Gem::Specification.new do |s|
|
|
9
9
|
s.authors = ['Daniel Marcotte']
|
10
10
|
s.email = 'dmarcotte@gmail.com'
|
11
11
|
s.homepage = 'https://github.com/dmarcotte/github-markdown-preview'
|
12
|
-
s.summary = %q{Use your favorite editor plus the usual edit/refresh cycle to quickly write and polish your Github markdown
|
13
|
-
s.description = %q{Local previews for Github
|
12
|
+
s.summary = %q{Use your favorite editor plus the usual edit/refresh cycle to quickly write and polish your Github markdown}
|
13
|
+
s.description = %q{Local previews for Github markdown}
|
14
14
|
s.license = 'MIT'
|
15
15
|
|
16
|
-
s.add_dependency '
|
17
|
-
s.add_dependency '
|
18
|
-
s.add_dependency '
|
19
|
-
s.add_dependency 'github-
|
20
|
-
s.add_dependency '
|
16
|
+
s.add_dependency 'listen', '1.3.1' # pin to latest version of listen which supports Ruby 1.8
|
17
|
+
s.add_dependency 'html-pipeline', '~> 1.1'
|
18
|
+
s.add_dependency 'sanitize', '2.0.3' # pin to latest version of sanitize which supports Ruby 1.8
|
19
|
+
s.add_dependency 'github-markdown', '~> 0.6'
|
20
|
+
s.add_dependency 'gemoji', '~> 1.5'
|
21
21
|
|
22
|
-
s.add_development_dependency 'minitest', '~>
|
22
|
+
s.add_development_dependency 'minitest', '~> 5.2'
|
23
23
|
s.add_development_dependency 'bundler', '~> 1.3'
|
24
24
|
s.add_development_dependency 'rake', '~> 10.1'
|
25
25
|
|
@@ -1,8 +1,8 @@
|
|
1
|
-
|
2
1
|
module GithubMarkdownPreview
|
3
2
|
class FileNotFoundError < StandardError; end
|
4
3
|
|
5
4
|
require 'github-markdown-preview/version'
|
6
5
|
require 'github-markdown-preview/resources'
|
7
6
|
require 'github-markdown-preview/html_preview'
|
7
|
+
require 'github-markdown-preview/filter/task_list_filter'
|
8
8
|
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
require 'html/pipeline'
|
2
|
+
|
3
|
+
module GithubMarkdownPreview
|
4
|
+
class Pipeline
|
5
|
+
# HTML filter that replaces `[ ] task` and `[x] task` list items with "task list" checkboxes
|
6
|
+
class TaskListFilter < HTML::Pipeline::Filter
|
7
|
+
|
8
|
+
COMPLETE_TASK_PATTERN = /^[\s]*(\[\s\])([\s]+[^\s]*)/
|
9
|
+
INCOMPLETE_TASK_PATTERN = /^[\s]*(\[x\])([\s]+[^\s]*)/
|
10
|
+
|
11
|
+
def task_pattern(complete)
|
12
|
+
task_character = complete ? 'x' : '\s'
|
13
|
+
/^[\s]*(\[#{task_character}\])([\s]+[^\s]*)/
|
14
|
+
end
|
15
|
+
|
16
|
+
def task_markup(complete)
|
17
|
+
"<input class=\"task-list-item-checkbox\" type=\"checkbox\" #{complete ? 'checked' : ''}>"
|
18
|
+
end
|
19
|
+
|
20
|
+
def call
|
21
|
+
doc.search('ul/li').each do |node|
|
22
|
+
first_child = node.children.first
|
23
|
+
next if !first_child.text?
|
24
|
+
content = first_child.to_html
|
25
|
+
html = task_list_item_filter(content)
|
26
|
+
next if html == content
|
27
|
+
node['class'] = 'task-list-item'
|
28
|
+
node.parent()['class'] = 'task-list'
|
29
|
+
first_child.replace(html)
|
30
|
+
end
|
31
|
+
doc
|
32
|
+
end
|
33
|
+
|
34
|
+
# Replace "[ ]" or "[x]" with corresponding checkbox input
|
35
|
+
def task_list_item_filter(text)
|
36
|
+
return text unless text.include?('[ ]') || text.include?('[x]')
|
37
|
+
|
38
|
+
[true, false].each do |complete|
|
39
|
+
text = text.gsub task_pattern(complete) do
|
40
|
+
task_markup(complete) + $2
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
text
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -8,41 +8,62 @@ module GithubMarkdownPreview
|
|
8
8
|
#
|
9
9
|
# For a given file /path/to/file.md, generates /path/to/file.md.html
|
10
10
|
class HtmlPreview
|
11
|
-
|
12
|
-
VERSION = '1.5'
|
13
|
-
|
14
11
|
attr_reader :source_file, :preview_file
|
15
|
-
attr_accessor :delete_on_exit
|
16
12
|
|
17
|
-
|
13
|
+
begin
|
14
|
+
require 'linguist'
|
15
|
+
SYNTAX_HIGHLIGHTS = true
|
16
|
+
rescue LoadError => _
|
17
|
+
SYNTAX_HIGHLIGHTS = false
|
18
|
+
end
|
19
|
+
|
20
|
+
def initialize(source_file, options = {})
|
18
21
|
unless File.exist?(source_file)
|
19
22
|
raise FileNotFoundError.new("Cannot find source file: #{source_file}")
|
20
23
|
end
|
21
24
|
|
25
|
+
options = {
|
26
|
+
:delete_on_exit => false,
|
27
|
+
:comment_mode => false
|
28
|
+
}.merge(options)
|
29
|
+
|
22
30
|
@source_file = Pathname.new(source_file).realpath.to_s
|
23
31
|
|
24
32
|
@preview_file = @source_file + '.html'
|
33
|
+
@preview_width = options[:comment_mode] ? 712 : 722
|
34
|
+
|
25
35
|
@update_callbacks = []
|
26
36
|
|
27
37
|
@pipeline_context = {
|
28
38
|
:asset_root => "https://a248.e.akamai.net/assets.github.com/images/icons/",
|
29
|
-
:
|
39
|
+
:base_url => "https://github.com/",
|
40
|
+
:gfm => options[:comment_mode]
|
30
41
|
}
|
31
42
|
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
43
|
+
filters = [
|
44
|
+
HTML::Pipeline::MarkdownFilter,
|
45
|
+
HTML::Pipeline::SanitizationFilter,
|
46
|
+
HTML::Pipeline::ImageMaxWidthFilter,
|
47
|
+
HTML::Pipeline::HttpsFilter,
|
48
|
+
HTML::Pipeline::EmojiFilter
|
49
|
+
]
|
50
|
+
|
51
|
+
if HtmlPreview::SYNTAX_HIGHLIGHTS
|
52
|
+
filters << HTML::Pipeline::SyntaxHighlightFilter
|
53
|
+
end
|
54
|
+
|
55
|
+
if options[:comment_mode]
|
56
|
+
filters << HTML::Pipeline::MentionFilter
|
57
|
+
filters << GithubMarkdownPreview::Pipeline::TaskListFilter
|
58
|
+
end
|
59
|
+
|
60
|
+
@preview_pipeline = HTML::Pipeline.new filters
|
40
61
|
|
41
62
|
# generate initial preview
|
42
63
|
update
|
43
64
|
|
44
65
|
at_exit do
|
45
|
-
if :delete_on_exit
|
66
|
+
if options[:delete_on_exit]
|
46
67
|
delete
|
47
68
|
end
|
48
69
|
end
|
@@ -69,7 +90,7 @@ module GithubMarkdownPreview
|
|
69
90
|
raise FileNotFoundError.new("Source file deleted")
|
70
91
|
end
|
71
92
|
|
72
|
-
markdown_render = @preview_pipeline.call(
|
93
|
+
markdown_render = @preview_pipeline.call(IO.read(@source_file), @pipeline_context, {})[:output].to_s
|
73
94
|
preview_html = wrap_preview(markdown_render)
|
74
95
|
|
75
96
|
File.open(@preview_file, 'w') do |f|
|
@@ -132,7 +153,7 @@ module GithubMarkdownPreview
|
|
132
153
|
margin-top: 0;
|
133
154
|
}
|
134
155
|
.readme-content {
|
135
|
-
width:
|
156
|
+
width: #{@preview_width}px;
|
136
157
|
}
|
137
158
|
</style>
|
138
159
|
</head>
|
@@ -147,4 +168,4 @@ CONTENT
|
|
147
168
|
|
148
169
|
end
|
149
170
|
|
150
|
-
end
|
171
|
+
end
|
data/readme.md
CHANGED
@@ -1,38 +1,62 @@
|
|
1
1
|
# Local Github Markdown Preview [![Build Status](https://secure.travis-ci.org/dmarcotte/github-markdown-preview.png)](http://travis-ci.org/dmarcotte/github-markdown-preview)
|
2
2
|
|
3
|
-
Use your favorite editor plus the usual edit/refresh cycle to quickly write and polish your
|
3
|
+
Use your favorite editor plus the usual edit/refresh cycle to quickly write and polish your markdown for Github.
|
4
4
|
|
5
|
-
This program marries [html-pipeline](https://github.com/jch/html-pipeline) with the [Listen file watcher](https://github.com/guard/listen) to provide a high-fidelity preview
|
5
|
+
This program marries [html-pipeline](https://github.com/jch/html-pipeline) with the [Listen file watcher](https://github.com/guard/listen) to provide a high-fidelity preview (in your local browser, automatically updating on edit) of how Github will render your markdown.
|
6
6
|
|
7
7
|
![sample screenshot](sample.png "Local Github Markdown Preview output")
|
8
8
|
|
9
|
-
##
|
9
|
+
## Installation
|
10
10
|
```
|
11
11
|
gem install github-markdown-preview
|
12
12
|
```
|
13
|
-
If the install fails, you may be missing a build dependency for the native extensions used in `github-linguist`. Check your output for the following error, and install the suggested package:
|
14
|
-
```
|
15
|
-
*********** icu required (brew install icu4c or apt-get install libicu-dev) ***********
|
16
|
-
```
|
17
|
-
For any other failure, please [file an issue!](https://github.com/dmarcotte/github-markdown-preview/issues)
|
18
13
|
|
19
14
|
## Usage
|
20
|
-
|
15
|
+
|
16
|
+
Generate a preview of how Github renders markdown files in a repository:
|
17
|
+
|
21
18
|
```bash
|
22
|
-
|
23
|
-
# Open in your favorite browser and enjoy!
|
24
|
-
github-markdown-preview <path/to/github-flavored/file.md>
|
19
|
+
$ github-markdown-preview <path/to/markdown/file.md> # writes <path/to/markdown/file.md>
|
25
20
|
```
|
21
|
+
|
26
22
|
* The `.html` preview is written beside your `.md` file so that you can validate [relative links](https://github.com/blog/1395-relative-links-in-markup-files) locally
|
27
23
|
* The `.html` preview is deleted when the script exits
|
28
24
|
|
29
|
-
###
|
25
|
+
### Comment mode
|
26
|
+
Use the `-c` switch to generate a preview of how Github renders comments/issues, which differs from repository markdown files in a few ways:
|
27
|
+
* [newlines](https://help.github.com/articles/github-flavored-markdown#newlines) are rendered as hard breaks
|
28
|
+
* `@mentions` are linked to the user's home page
|
29
|
+
* [task lists](https://help.github.com/articles/github-flavored-markdown#task-lists) are rendered as checkboxes
|
30
|
+
* [TODO](https://github.com/dmarcotte/github-markdown-preview/issues/17): auto-linked [references](https://help.github.com/articles/github-flavored-markdown#references)
|
31
|
+
|
32
|
+
```bash
|
33
|
+
$ github-markdown-preview -c <path/to/comment/draft.md> # writes <path/to/comment/draft.md.html>
|
34
|
+
```
|
35
|
+
|
36
|
+
### Enable syntax highlighting for code blocks
|
37
|
+
To enable syntax highlighting for code blocks, you will need to install [`github-linguist`](https://github.com/github/linguist):
|
38
|
+
```
|
39
|
+
gem install github-linguist
|
40
|
+
```
|
41
|
+
|
42
|
+
Note that this install will fail unless your system meets the requirements needed to build its native extensions:
|
43
|
+
* You will to either `brew install icu4c` or `apt-get install libicu-dev`
|
44
|
+
* On Mac, you will need to have XCode installed (seems like a full install is required, not just the Command Line Tools)
|
45
|
+
|
46
|
+
## Code
|
47
|
+
Here's a sample file demonstrating how to call `github-markdown-preview` from your own code:
|
30
48
|
```ruby
|
31
49
|
require 'github-markdown-preview'
|
32
50
|
|
33
51
|
# create a preview, which writes the source_file.md.html file to disk
|
34
52
|
preview = GithubMarkdownPreview::HtmlPreview.new('source_file.md')
|
35
53
|
|
54
|
+
# you can also configure your preview with a couple of options
|
55
|
+
preview = GithubMarkdownPreview::HtmlPreview.new('source_file.md', {
|
56
|
+
:delete_on_exit => true, # delete the preview when the program exits
|
57
|
+
:comment_mode => true # render using the rules for Github comments/issues
|
58
|
+
})
|
59
|
+
|
36
60
|
# access the preview information
|
37
61
|
preview.source_file # returns 'source_file.md'
|
38
62
|
preview.preview_file # returns 'source_file.md.html'
|
@@ -52,27 +76,27 @@ preview.end_watch
|
|
52
76
|
|
53
77
|
# delete the preview file from disk
|
54
78
|
preview.delete
|
55
|
-
|
56
|
-
# alternatively, tell the preview to delete itself when your program exits
|
57
|
-
preview.delete_on_exit = true
|
58
79
|
```
|
59
80
|
|
60
|
-
##
|
81
|
+
## Development
|
61
82
|
```bash
|
62
|
-
bundle
|
63
|
-
rake test
|
83
|
+
$ bundle install
|
84
|
+
$ rake test
|
64
85
|
```
|
65
|
-
|
86
|
+
|
87
|
+
Alternatively, to test with optional dependencies
|
66
88
|
```bash
|
67
|
-
|
89
|
+
$ BUNDLE_GEMFILE=Gemfile.optional bundle install
|
90
|
+
$ BUNDLE_GEMFILE=Gemfile.optional rake test
|
68
91
|
```
|
92
|
+
|
69
93
|
To run your development copy of the main script without installing it
|
70
|
-
```
|
71
|
-
bundle exec bin/github-markdown-preview
|
94
|
+
```bash
|
95
|
+
$ bundle exec bin/github-markdown-preview
|
72
96
|
```
|
73
97
|
To install the your development copy to your system
|
74
|
-
```
|
75
|
-
rake install
|
98
|
+
```bash
|
99
|
+
$ rake install
|
76
100
|
```
|
77
101
|
|
78
102
|
## Contributing
|
@@ -0,0 +1,87 @@
|
|
1
|
+
require 'bundler/setup'
|
2
|
+
require 'minitest/autorun'
|
3
|
+
require 'github-markdown-preview'
|
4
|
+
|
5
|
+
class HTML::Pipeline::MentionFilterTest < Minitest::Test
|
6
|
+
|
7
|
+
def filter(html)
|
8
|
+
doc = Nokogiri::HTML::DocumentFragment.parse(html)
|
9
|
+
|
10
|
+
res = GithubMarkdownPreview::Pipeline::TaskListFilter.call(doc)
|
11
|
+
assert_same doc, res
|
12
|
+
|
13
|
+
res.to_html
|
14
|
+
end
|
15
|
+
|
16
|
+
def test_filter_text_task
|
17
|
+
html = "<ul><li>[ ] task</li></ul>"
|
18
|
+
result = filter(html)
|
19
|
+
|
20
|
+
assert_equal "<ul class=\"task-list\"><li class=\"task-list-item\">\n<input class=\"task-list-item-checkbox\" type=\"checkbox\"> task</li></ul>",
|
21
|
+
result
|
22
|
+
end
|
23
|
+
|
24
|
+
def test_filter_text_task_done
|
25
|
+
html = "<ul><li>[x] task</li></ul>"
|
26
|
+
result = filter(html)
|
27
|
+
|
28
|
+
assert_equal "<ul class=\"task-list\"><li class=\"task-list-item\">\n<input class=\"task-list-item-checkbox\" type=\"checkbox\" checked> task</li></ul>",
|
29
|
+
result
|
30
|
+
end
|
31
|
+
|
32
|
+
def test_filter_tasks_with_leading_whitespace
|
33
|
+
html = "<ul><li> [ ] task</li></ul>"
|
34
|
+
result = filter(html)
|
35
|
+
|
36
|
+
assert_equal "<ul class=\"task-list\"><li class=\"task-list-item\">\n<input class=\"task-list-item-checkbox\" type=\"checkbox\"> task</li></ul>",
|
37
|
+
result
|
38
|
+
end
|
39
|
+
|
40
|
+
def test_filter_rich_task
|
41
|
+
html = "<ul><li>[ ] <em>task</em></li></ul>"
|
42
|
+
result = filter(html)
|
43
|
+
|
44
|
+
assert_equal "<ul class=\"task-list\"><li class=\"task-list-item\">\n<input class=\"task-list-item-checkbox\" type=\"checkbox\"><em>task</em>\n</li></ul>",
|
45
|
+
result
|
46
|
+
end
|
47
|
+
|
48
|
+
def test_filter_sub_task
|
49
|
+
html = "<ul><li>[ ] task</li><ul><li>[ ] subtask</li></ul></ul>"
|
50
|
+
result = filter(html)
|
51
|
+
|
52
|
+
assert_equal "<ul class=\"task-list\">\n<li class=\"task-list-item\">\n<input class=\"task-list-item-checkbox\" type=\"checkbox\"> task</li>\n<ul class=\"task-list\"><li class=\"task-list-item\">\n<input class=\"task-list-item-checkbox\" type=\"checkbox\"> subtask</li></ul>\n</ul>",
|
53
|
+
result
|
54
|
+
end
|
55
|
+
|
56
|
+
def test_filter_combined_tasks
|
57
|
+
html = "<ul><li>[ ] task</li><li>[x] done task</li></ul>"
|
58
|
+
result = filter(html)
|
59
|
+
|
60
|
+
assert_equal "<ul class=\"task-list\">\n<li class=\"task-list-item\">\n<input class=\"task-list-item-checkbox\" type=\"checkbox\"> task</li>\n<li class=\"task-list-item\">\n<input class=\"task-list-item-checkbox\" type=\"checkbox\" checked> done task</li>\n</ul>",
|
61
|
+
result
|
62
|
+
end
|
63
|
+
|
64
|
+
def test_ignores_taskless_brackets
|
65
|
+
html = "<ul><li>[ ]</li></ul>"
|
66
|
+
result = filter(html)
|
67
|
+
|
68
|
+
assert_equal "<ul><li>[ ]</li></ul>",
|
69
|
+
result
|
70
|
+
end
|
71
|
+
|
72
|
+
def test_ignores_no_space_brackets
|
73
|
+
html = "<ul><li>[x]nospace</li></ul>"
|
74
|
+
result = filter(html)
|
75
|
+
|
76
|
+
assert_equal "<ul><li>[x]nospace</li></ul>",
|
77
|
+
result
|
78
|
+
end
|
79
|
+
|
80
|
+
def test_ignores_non_start_brackets
|
81
|
+
html = "<ul><li>nope [ ] not a task</li></ul>"
|
82
|
+
result = filter(html)
|
83
|
+
|
84
|
+
assert_equal "<ul><li>nope [ ] not a task</li></ul>",
|
85
|
+
result
|
86
|
+
end
|
87
|
+
end
|
data/test/html_preview_test.rb
CHANGED
@@ -2,7 +2,14 @@ require 'github-markdown-preview'
|
|
2
2
|
require 'minitest/autorun'
|
3
3
|
require 'tmpdir'
|
4
4
|
|
5
|
-
|
5
|
+
begin
|
6
|
+
require 'linguist'
|
7
|
+
LINGUIST_LOADED = true
|
8
|
+
rescue LoadError => _
|
9
|
+
LINGUIST_LOADED = false
|
10
|
+
end
|
11
|
+
|
12
|
+
class TestHtmlPreview < Minitest::Test
|
6
13
|
|
7
14
|
def setup
|
8
15
|
@ghp = GithubMarkdownPreview::HtmlPreview
|
@@ -10,7 +17,9 @@ class TestHtmlPreview < Minitest::Unit::TestCase
|
|
10
17
|
end
|
11
18
|
|
12
19
|
def write(file_name, text)
|
13
|
-
File.open(file_name, 'w')
|
20
|
+
File.open(file_name, 'w') do |f|
|
21
|
+
f.puts(text)
|
22
|
+
end
|
14
23
|
end
|
15
24
|
|
16
25
|
def read(file_name)
|
@@ -43,12 +52,68 @@ class TestHtmlPreview < Minitest::Unit::TestCase
|
|
43
52
|
'Preview should be correct on initialization'
|
44
53
|
end
|
45
54
|
|
46
|
-
def
|
55
|
+
def test_word_immediately_after_hash
|
47
56
|
write(@source_file_path, '#foo')
|
48
57
|
markdown_preview = @ghp.new( @source_file_path )
|
49
58
|
assert_match /.*<h1>foo<\/h1>.*/,
|
50
59
|
read(markdown_preview.preview_file),
|
51
|
-
'Preview should
|
60
|
+
'Preview should render #foo as a header'
|
61
|
+
end
|
62
|
+
|
63
|
+
def test_comment_mode_word_immediately_after_hash
|
64
|
+
write(@source_file_path, '#foo')
|
65
|
+
markdown_preview = @ghp.new( @source_file_path, { :comment_mode => true } )
|
66
|
+
assert_match /.*#foo*/,
|
67
|
+
read(markdown_preview.preview_file),
|
68
|
+
'Preview should render #foo directly'
|
69
|
+
end
|
70
|
+
|
71
|
+
def test_default_mode_ignores_task_lists
|
72
|
+
write(@source_file_path, '- [ ] task')
|
73
|
+
markdown_preview = @ghp.new( @source_file_path)
|
74
|
+
assert_match markdown_preview.wrap_preview("<ul>\n<li>[ ] task</li>\n</ul>"),
|
75
|
+
read(markdown_preview.preview_file),
|
76
|
+
'Should not contain a task list item in default mode'
|
77
|
+
end
|
78
|
+
|
79
|
+
def test_comment_mode_task_lists
|
80
|
+
write(@source_file_path, '- [ ] task')
|
81
|
+
markdown_preview = @ghp.new( @source_file_path, { :comment_mode => true } )
|
82
|
+
assert_match markdown_preview.wrap_preview("<ul class=\"task-list\">\n<li class=\"task-list-item\">\n<input class=\"task-list-item-checkbox\" type=\"checkbox\"> task</li>\n</ul>"),
|
83
|
+
read(markdown_preview.preview_file),
|
84
|
+
'Should contain a task list item in comment mode'
|
85
|
+
end
|
86
|
+
|
87
|
+
def test_newlines_ignored
|
88
|
+
write(@source_file_path, "foo\nbar")
|
89
|
+
markdown_preview = @ghp.new( @source_file_path )
|
90
|
+
assert_match /.*foo\nbar*/,
|
91
|
+
read(markdown_preview.preview_file),
|
92
|
+
'Should not contain <br> for newline'
|
93
|
+
end
|
94
|
+
|
95
|
+
def test_comment_mode_newlines_respected
|
96
|
+
write(@source_file_path, "foo\nbar")
|
97
|
+
markdown_preview = @ghp.new( @source_file_path, { :comment_mode => true } )
|
98
|
+
assert_match markdown_preview.wrap_preview("<p>foo<br>\nbar</p>"),
|
99
|
+
read(markdown_preview.preview_file),
|
100
|
+
'Should insert <br> for newline in comment mode'
|
101
|
+
end
|
102
|
+
|
103
|
+
def test_at_mentions_not_linked
|
104
|
+
write(@source_file_path, "@username")
|
105
|
+
markdown_preview = @ghp.new( @source_file_path )
|
106
|
+
assert_match markdown_preview.wrap_preview("<p>@username</p>"),
|
107
|
+
read(markdown_preview.preview_file),
|
108
|
+
'@mentions should not be linked'
|
109
|
+
end
|
110
|
+
|
111
|
+
def test_comment_mode_at_mentions_linked
|
112
|
+
write(@source_file_path, "@username")
|
113
|
+
markdown_preview = @ghp.new( @source_file_path, { :comment_mode => true } )
|
114
|
+
assert_match markdown_preview.wrap_preview('<p><a href="https://github.com/username" class="user-mention">@username</a></p>'),
|
115
|
+
read(markdown_preview.preview_file),
|
116
|
+
'@mentions should create links'
|
52
117
|
end
|
53
118
|
|
54
119
|
def test_wrapper_markup_included
|
@@ -59,6 +124,25 @@ class TestHtmlPreview < Minitest::Unit::TestCase
|
|
59
124
|
'Wrapper markup should be in preview file'
|
60
125
|
end
|
61
126
|
|
127
|
+
if LINGUIST_LOADED
|
128
|
+
def test_uses_syntax_highlighting
|
129
|
+
write(@source_file_path, "```ruby\nnil\n```")
|
130
|
+
markdown_preview = @ghp.new( @source_file_path )
|
131
|
+
|
132
|
+
assert_equal markdown_preview.wrap_preview("<div class=\"highlight highlight-ruby\"><pre><span class=\"kp\">nil</span>\n</pre></div>"),
|
133
|
+
read(markdown_preview.preview_file),
|
134
|
+
'Decorated code should be in preview file'
|
135
|
+
end
|
136
|
+
else
|
137
|
+
def test_no_syntax_highlighting
|
138
|
+
write(@source_file_path, "```ruby\nnil\n```")
|
139
|
+
markdown_preview = @ghp.new( @source_file_path )
|
140
|
+
assert_equal markdown_preview.wrap_preview("<pre lang=\"ruby\"><code>nil\n</code></pre>"),
|
141
|
+
read(markdown_preview.preview_file),
|
142
|
+
'Undecorated code should be in preview file'
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
62
146
|
def test_update_preview
|
63
147
|
write(@source_file_path, '## foo')
|
64
148
|
markdown_preview = @ghp.new( @source_file_path )
|
@@ -90,8 +174,7 @@ class TestHtmlPreview < Minitest::Unit::TestCase
|
|
90
174
|
def test_preview_delete_on_exit
|
91
175
|
at_exit { assert !File.exist?(@source_file_path + '.html'), 'Preview file should be deleted on exit' }
|
92
176
|
write(@source_file_path, '## foo')
|
93
|
-
|
94
|
-
markdown_preview.delete_on_exit = true
|
177
|
+
@ghp.new( @source_file_path, { :delete_on_exit => true } )
|
95
178
|
end
|
96
179
|
|
97
180
|
def test_update_callbacks
|
@@ -118,6 +201,8 @@ class TestHtmlPreview < Minitest::Unit::TestCase
|
|
118
201
|
updated_by_watch
|
119
202
|
}
|
120
203
|
|
204
|
+
markdown_preview.end_watch
|
205
|
+
|
121
206
|
assert_match /.*<h2>foo bar<\/h2>.*/,
|
122
207
|
read(markdown_preview.preview_file)
|
123
208
|
'Preview file should be updated correctly by file watcher'
|
@@ -138,4 +223,4 @@ class TestHtmlPreview < Minitest::Unit::TestCase
|
|
138
223
|
end
|
139
224
|
end
|
140
225
|
|
141
|
-
end
|
226
|
+
end
|
metadata
CHANGED
@@ -1,138 +1,139 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: github-markdown-preview
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 2.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Daniel Marcotte
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2013-
|
11
|
+
date: 2013-12-31 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
|
-
name:
|
14
|
+
name: listen
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- -
|
17
|
+
- - '='
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: 3.
|
19
|
+
version: 1.3.1
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
|
-
- -
|
24
|
+
- - '='
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: 3.
|
26
|
+
version: 1.3.1
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
|
-
name:
|
28
|
+
name: html-pipeline
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
|
-
- - ~>
|
31
|
+
- - "~>"
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: 1.
|
33
|
+
version: '1.1'
|
34
34
|
type: :runtime
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
|
-
- - ~>
|
38
|
+
- - "~>"
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version: 1.
|
40
|
+
version: '1.1'
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
|
-
name:
|
42
|
+
name: sanitize
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
45
|
- - '='
|
46
46
|
- !ruby/object:Gem::Version
|
47
|
-
version: 0.
|
47
|
+
version: 2.0.3
|
48
48
|
type: :runtime
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
52
|
- - '='
|
53
53
|
- !ruby/object:Gem::Version
|
54
|
-
version: 0.
|
54
|
+
version: 2.0.3
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
|
-
name: github-
|
56
|
+
name: github-markdown
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
58
58
|
requirements:
|
59
|
-
- - ~>
|
59
|
+
- - "~>"
|
60
60
|
- !ruby/object:Gem::Version
|
61
|
-
version:
|
61
|
+
version: '0.6'
|
62
62
|
type: :runtime
|
63
63
|
prerelease: false
|
64
64
|
version_requirements: !ruby/object:Gem::Requirement
|
65
65
|
requirements:
|
66
|
-
- - ~>
|
66
|
+
- - "~>"
|
67
67
|
- !ruby/object:Gem::Version
|
68
|
-
version:
|
68
|
+
version: '0.6'
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
|
-
name:
|
70
|
+
name: gemoji
|
71
71
|
requirement: !ruby/object:Gem::Requirement
|
72
72
|
requirements:
|
73
|
-
- - ~>
|
73
|
+
- - "~>"
|
74
74
|
- !ruby/object:Gem::Version
|
75
|
-
version:
|
75
|
+
version: '1.5'
|
76
76
|
type: :runtime
|
77
77
|
prerelease: false
|
78
78
|
version_requirements: !ruby/object:Gem::Requirement
|
79
79
|
requirements:
|
80
|
-
- - ~>
|
80
|
+
- - "~>"
|
81
81
|
- !ruby/object:Gem::Version
|
82
|
-
version:
|
82
|
+
version: '1.5'
|
83
83
|
- !ruby/object:Gem::Dependency
|
84
84
|
name: minitest
|
85
85
|
requirement: !ruby/object:Gem::Requirement
|
86
86
|
requirements:
|
87
|
-
- - ~>
|
87
|
+
- - "~>"
|
88
88
|
- !ruby/object:Gem::Version
|
89
|
-
version: '
|
89
|
+
version: '5.2'
|
90
90
|
type: :development
|
91
91
|
prerelease: false
|
92
92
|
version_requirements: !ruby/object:Gem::Requirement
|
93
93
|
requirements:
|
94
|
-
- - ~>
|
94
|
+
- - "~>"
|
95
95
|
- !ruby/object:Gem::Version
|
96
|
-
version: '
|
96
|
+
version: '5.2'
|
97
97
|
- !ruby/object:Gem::Dependency
|
98
98
|
name: bundler
|
99
99
|
requirement: !ruby/object:Gem::Requirement
|
100
100
|
requirements:
|
101
|
-
- - ~>
|
101
|
+
- - "~>"
|
102
102
|
- !ruby/object:Gem::Version
|
103
103
|
version: '1.3'
|
104
104
|
type: :development
|
105
105
|
prerelease: false
|
106
106
|
version_requirements: !ruby/object:Gem::Requirement
|
107
107
|
requirements:
|
108
|
-
- - ~>
|
108
|
+
- - "~>"
|
109
109
|
- !ruby/object:Gem::Version
|
110
110
|
version: '1.3'
|
111
111
|
- !ruby/object:Gem::Dependency
|
112
112
|
name: rake
|
113
113
|
requirement: !ruby/object:Gem::Requirement
|
114
114
|
requirements:
|
115
|
-
- - ~>
|
115
|
+
- - "~>"
|
116
116
|
- !ruby/object:Gem::Version
|
117
117
|
version: '10.1'
|
118
118
|
type: :development
|
119
119
|
prerelease: false
|
120
120
|
version_requirements: !ruby/object:Gem::Requirement
|
121
121
|
requirements:
|
122
|
-
- - ~>
|
122
|
+
- - "~>"
|
123
123
|
- !ruby/object:Gem::Version
|
124
124
|
version: '10.1'
|
125
|
-
description: Local previews for Github
|
125
|
+
description: Local previews for Github markdown
|
126
126
|
email: dmarcotte@gmail.com
|
127
127
|
executables:
|
128
128
|
- github-markdown-preview
|
129
129
|
extensions: []
|
130
130
|
extra_rdoc_files: []
|
131
131
|
files:
|
132
|
-
- .gitignore
|
133
|
-
- .travis.yml
|
132
|
+
- ".gitignore"
|
133
|
+
- ".travis.yml"
|
134
134
|
- CHANGELOG.md
|
135
135
|
- Gemfile
|
136
|
+
- Gemfile.optional
|
136
137
|
- LICENSE.txt
|
137
138
|
- Rakefile
|
138
139
|
- bin/github-markdown-preview
|
@@ -141,12 +142,14 @@ files:
|
|
141
142
|
- data/css/github2.css
|
142
143
|
- github-markdown-preview.gemspec
|
143
144
|
- lib/github-markdown-preview.rb
|
145
|
+
- lib/github-markdown-preview/filter/task_list_filter.rb
|
144
146
|
- lib/github-markdown-preview/html_preview.rb
|
145
147
|
- lib/github-markdown-preview/resources.rb
|
146
148
|
- lib/github-markdown-preview/version.rb
|
147
149
|
- readme.md
|
148
150
|
- sample.png
|
149
151
|
- sample_preview.md
|
152
|
+
- test/filter/task_list_filter_test.rb
|
150
153
|
- test/github-markdown-preview_test.rb
|
151
154
|
- test/html_preview_test.rb
|
152
155
|
homepage: https://github.com/dmarcotte/github-markdown-preview
|
@@ -159,21 +162,22 @@ require_paths:
|
|
159
162
|
- lib
|
160
163
|
required_ruby_version: !ruby/object:Gem::Requirement
|
161
164
|
requirements:
|
162
|
-
- -
|
165
|
+
- - ">="
|
163
166
|
- !ruby/object:Gem::Version
|
164
167
|
version: '0'
|
165
168
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
166
169
|
requirements:
|
167
|
-
- -
|
170
|
+
- - ">="
|
168
171
|
- !ruby/object:Gem::Version
|
169
172
|
version: '0'
|
170
173
|
requirements: []
|
171
174
|
rubyforge_project:
|
172
|
-
rubygems_version: 2.0
|
175
|
+
rubygems_version: 2.2.0
|
173
176
|
signing_key:
|
174
177
|
specification_version: 4
|
175
178
|
summary: Use your favorite editor plus the usual edit/refresh cycle to quickly write
|
176
|
-
and polish your Github markdown
|
179
|
+
and polish your Github markdown
|
177
180
|
test_files:
|
181
|
+
- test/filter/task_list_filter_test.rb
|
178
182
|
- test/github-markdown-preview_test.rb
|
179
183
|
- test/html_preview_test.rb
|