├── Gemfile ├── test ├── test_helper.rb ├── fixtures │ ├── octicon.md │ ├── block_octicon.md │ ├── intro.md │ ├── block_intro.md │ ├── command_line.md │ ├── command_line_indented.md │ ├── os_blocks.md │ ├── block_os_blocks.md │ ├── command_line_nested.md │ ├── admonition.md │ ├── block_admonition.md │ └── helper.md └── test_extended_markdown_filter.rb ├── .rubocop.yml ├── .gitignore ├── lib ├── filters │ ├── post │ │ ├── octicon.rb │ │ ├── intro.rb │ │ ├── os-blocks.rb │ │ ├── admonition.rb │ │ └── command-line.rb │ ├── filters.rb │ └── pre │ │ └── helper.rb ├── jekyll-override.rb └── extended-markdown-filter.rb ├── Rakefile ├── .travis.yml ├── LICENSE.txt ├── extended-markdown-filter.gemspec └── README.md /Gemfile: -------------------------------------------------------------------------------- 1 | source 'https://rubygems.org' 2 | 3 | gemspec 4 | -------------------------------------------------------------------------------- /test/test_helper.rb: -------------------------------------------------------------------------------- 1 | require 'rubygems' 2 | 3 | require 'minitest/autorun' 4 | 5 | require 'extended-markdown-filter' 6 | 7 | require 'pry' 8 | -------------------------------------------------------------------------------- /test/fixtures/octicon.md: -------------------------------------------------------------------------------- 1 | {{ octicon-cat This is a cat }} 2 | 3 | {{ octicon dog This is nothing. }} 4 | 5 | [Click {{ octicon-gear Settings }}](http://alink.com) 6 | -------------------------------------------------------------------------------- /test/fixtures/block_octicon.md: -------------------------------------------------------------------------------- 1 | [[ octicon-cat This is a cat ]] 2 | 3 | [[ octicon dog This is nothing. ]] 4 | 5 | [Click [[ octicon-gear Settings ]]](http://alink.com) 6 | -------------------------------------------------------------------------------- /test/fixtures/intro.md: -------------------------------------------------------------------------------- 1 | {{#intro}} 2 | 3 | [Gists](https://gist.github.com) are a great way to share your work. You can share single files, parts of files, or full applications. 4 | 5 | {{/intro}} 6 | -------------------------------------------------------------------------------- /test/fixtures/block_intro.md: -------------------------------------------------------------------------------- 1 | [[#intro]] 2 | 3 | [Gists](https://gist.github.com) are a great way to share your work. You can share single files, parts of files, or full applications. 4 | 5 | [[/intro]] 6 | -------------------------------------------------------------------------------- /.rubocop.yml: -------------------------------------------------------------------------------- 1 | inherit_gem: 2 | rubocop-github: 3 | - config/default.yml 4 | 5 | Style/StringLiterals: 6 | Enabled: true 7 | EnforcedStyle: single_quotes 8 | 9 | Naming/FileName: 10 | Enabled: false 11 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 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 | .byebug_history 19 | -------------------------------------------------------------------------------- /lib/filters/post/octicon.rb: -------------------------------------------------------------------------------- 1 | module Filters 2 | module PostFilter 3 | def format_octicons!(html) 4 | html.gsub!(/#{@front_wrap}\s*octicon-(\S+)\s*([^\\#{@wrap_symbol}]+)\s*#{@end_wrap}/, %||) 5 | end 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /lib/filters/filters.rb: -------------------------------------------------------------------------------- 1 | module Filters 2 | CLOSE_DIV = '' 3 | end 4 | 5 | Dir[File.join(File.expand_path(File.dirname(__FILE__)), 'pre', '*.rb')].each do |file| 6 | require file 7 | end 8 | 9 | Dir[File.join(File.expand_path(File.dirname(__FILE__)), 'post', '*.rb')].each do |file| 10 | require file 11 | end 12 | -------------------------------------------------------------------------------- /test/fixtures/command_line.md: -------------------------------------------------------------------------------- 1 | # Header 2 | 3 | ``` command-line 4 | $ git remote add origin https://github.com/user/repo.git 5 | # Set a new remote 6 | > origin https://github.com/user/repo.git 7 | $ git remote add -f spoon-knife git@github.com:octocat/Spoon-Knife.git 8 | ``` 9 | 10 | next paragraph 11 | -------------------------------------------------------------------------------- /Rakefile: -------------------------------------------------------------------------------- 1 | require 'bundler/gem_tasks' 2 | 3 | task default: [:test] 4 | 5 | require 'rake/testtask' 6 | Rake::TestTask.new(:test) do |test| 7 | test.libs << 'lib' << 'test' 8 | test.pattern = 'test/**/test_*.rb' 9 | test.verbose = true 10 | end 11 | 12 | require 'rubocop/rake_task' 13 | 14 | RuboCop::RakeTask.new(:rubocop) 15 | -------------------------------------------------------------------------------- /lib/filters/post/intro.rb: -------------------------------------------------------------------------------- 1 | module Filters 2 | module PostFilter 3 | INTRO_HTML = '
#{@front_wrap}#intro#{@end_wrap}<\/p>/, INTRO_HTML) 7 | html.gsub!(/
#{@front_wrap}\/intro#{@end_wrap}<\/p>/, Filters::CLOSE_DIV) 8 | end 9 | end 10 | end 11 | -------------------------------------------------------------------------------- /test/fixtures/command_line_indented.md: -------------------------------------------------------------------------------- 1 | # Header 2 | 3 | ``` command-line 4 | $ git remote add origin https://github.com/user/repo.git 5 | # Set a new remote 6 | > origin https://github.com/user/repo.git 7 | $ git remote add -f spoon-knife git@github.com:octocat/Spoon-Knife.git 8 | ``` 9 | 10 | next paragraph 11 | -------------------------------------------------------------------------------- /test/fixtures/os_blocks.md: -------------------------------------------------------------------------------- 1 | {{#mac}} 2 | 3 | 1. [Create a new repository](/articles/creating-a-new-repository). 4 | 5 | {{/mac}} 6 | 7 | {{#windows}} 8 | 9 | 1. [Try to create a new repository](/articles/creating-a-new-repository). 10 | 11 | {{/windows}} 12 | 13 | {{#linux}} 14 | 15 | 1. You *already* know what you're doing. 16 | 17 | {{/linux}} 18 | 19 | {{#all}} 20 | 21 | What? 22 | 23 | {{/all}} 24 | -------------------------------------------------------------------------------- /test/fixtures/block_os_blocks.md: -------------------------------------------------------------------------------- 1 | [[#mac]] 2 | 3 | 1. [Create a new repository](/articles/creating-a-new-repository). 4 | 5 | [[/mac]] 6 | 7 | [[#windows]] 8 | 9 | 1. [Try to create a new repository](/articles/creating-a-new-repository). 10 | 11 | [[/windows]] 12 | 13 | [[#linux]] 14 | 15 | 1. You *already* know what you're doing. 16 | 17 | [[/linux]] 18 | 19 | [[#all]] 20 | 21 | What? 22 | 23 | [[/all]] 24 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: ruby 2 | rvm: 3 | - 2.3.6 4 | - 2.4.3 5 | - 2.5.0 6 | 7 | git: 8 | depth: 10 9 | 10 | sudo: false 11 | 12 | # we need a more recent cmake than travis/linux provides (at least 2.8.9): 13 | addons: 14 | apt: 15 | sources: 16 | - kalakris-cmake 17 | packages: 18 | - cmake 19 | 20 | cache: bundler 21 | 22 | matrix: 23 | include: 24 | - script: bundle exec rake rubocop 25 | rvm: 2.5.0 26 | -------------------------------------------------------------------------------- /test/fixtures/command_line_nested.md: -------------------------------------------------------------------------------- 1 | 2. Create a bare clone of the repository. 2 | ``` command-line 3 | $ git clone --bare https://{{ site.data.variables.command_line.codeblock }}/exampleuser/old-repository.git 4 | ``` 5 | 3. Mirror-push to the new repository. 6 | ``` command-line 7 | $ cd old-repository.git 8 | $ git push --mirror https://{{ site.data.variables.command_line.codeblock }}/exampleuser/new-repository.git 9 | ``` 10 | -------------------------------------------------------------------------------- /test/fixtures/admonition.md: -------------------------------------------------------------------------------- 1 | {{#tip}} 2 | 3 | Here's a hot tip: **line one** 4 | Here's a hot tip: line two 5 | 6 | {{/tip}} 7 | 8 | {{#note}} 9 | 10 | This is something you should know! line one 11 | This is something you should know! line two 12 | 13 | {{/note}} 14 | 15 | {{#warning}} 16 | 17 | Yo, check this out: line one 18 | Yo, check this out: line two 19 | 20 | {{/warning}} 21 | 22 | {{#danger}} 23 | 24 | Sheeeeit, this is a problem: ~~line one~~ 25 | Sheeeeit, this is a problem: line two 26 | 27 | {{/danger}} 28 | -------------------------------------------------------------------------------- /test/fixtures/block_admonition.md: -------------------------------------------------------------------------------- 1 | [[#tip]] 2 | 3 | Here's a hot tip: **line one** 4 | Here's a hot tip: line two 5 | 6 | [[/tip]] 7 | 8 | [[#note]] 9 | 10 | This is something you should know! line one 11 | This is something you should know! line two 12 | 13 | [[/note]] 14 | 15 | [[#warning]] 16 | 17 | Yo, check this out: line one 18 | Yo, check this out: line two 19 | 20 | [[/warning]] 21 | 22 | [[#danger]] 23 | 24 | Sheeeeit, this is a problem: ~~line one~~ 25 | Sheeeeit, this is a problem: line two 26 | 27 | [[/danger]] 28 | -------------------------------------------------------------------------------- /test/fixtures/helper.md: -------------------------------------------------------------------------------- 1 | 2 | ``` helper 3 | #### A note about Sync in GitHub for Mac 4 | 5 | Those that are already familiar with Git may notice that there are no "Push" or "Pull" buttons in GitHub for Mac. 6 | 7 | Instead of bringing in new changes from the remote copy with one command and pushing your unpublished commits with another, GitHub for Mac uses a single "Sync" button that quickly completes both operations at the same. Behind the scenes, we do the equivalent of a `git pull --rebase` (but make sure to never rewrite merges). 8 | ``` 9 | -------------------------------------------------------------------------------- /lib/filters/pre/helper.rb: -------------------------------------------------------------------------------- 1 | module Filters 2 | module PreFilter 3 | def format_helper(text) 4 | prefix = '
#{@front_wrap}#mac#{@end_wrap}<\/p>/, MAC_HTML) 10 | html.gsub!(/
#{@front_wrap}#windows#{@end_wrap}<\/p>/, WIN_HTML) 11 | html.gsub!(/
#{@front_wrap}#linux#{@end_wrap}<\/p>/, LINUX_HTML) 12 | html.gsub!(/
#{@front_wrap}#all#{@end_wrap}<\/p>/, ALL_HTML) 13 | html.gsub!(/
#{@front_wrap}\/(mac|windows|linux|all)#{@end_wrap}<\/p>/, Filters::CLOSE_DIV) 14 | end 15 | end 16 | end 17 | -------------------------------------------------------------------------------- /lib/filters/post/admonition.rb: -------------------------------------------------------------------------------- 1 | module Filters 2 | module PostFilter 3 | TIP_HTML = '
#{@front_wrap}#tip#{@end_wrap}<\/p>/, TIP_HTML) 10 | html.gsub!(/
#{@front_wrap}#note#{@end_wrap}<\/p>/, NOTE_HTML) 11 | html.gsub!(/
#{@front_wrap}#warning#{@end_wrap}<\/p>/, WARNING_HTML) 12 | html.gsub!(/
#{@front_wrap}#danger#{@end_wrap}<\/p>/, DANGER_HTML) 13 | html.gsub!(/
#{@front_wrap}\/(tip|note|warning|danger)#{@end_wrap}<\/p>/, Filters::CLOSE_DIV) 14 | end 15 | end 16 | end 17 | -------------------------------------------------------------------------------- /lib/filters/post/command-line.rb: -------------------------------------------------------------------------------- 1 | module Filters 2 | module PostFilter 3 | def format_command_line!(html) 4 | html.gsub!(/
``` command-line\n/, "\n")
5 | html.gsub!(//, "\n")
6 |
7 | html.gsub! /^\n?\s*(.+?)<\/pre>/m do |block|
8 | block.gsub!(/<\/*code>/, '')
9 | block.gsub!(/```/, '')
10 | block.gsub!(/^\s*\$ (.+)$/) { %(#{$1.rstrip}) }
11 | block.gsub!(/^\s*(\# .+)$/) { %(#{$1.rstrip}) }
12 | block.gsub!(/^\s*> (.+)$/) { %(#{$1.rstrip}) }
13 | block.gsub!(/</, '<')
14 | block.gsub!(/>/, '>')
15 |
16 | block
17 | end
18 | end
19 | end
20 | end
21 |
--------------------------------------------------------------------------------
/lib/jekyll-override.rb:
--------------------------------------------------------------------------------
1 | # Liquid disregards tags it doesn't know,
2 | # so rather than define a new format for additions like {{#tip}},
3 | # we'll convert them to bracket form
4 | module Jekyll
5 | class Renderer
6 | alias_method :old_run, :run
7 |
8 | def run
9 | if ExtendedMarkdownFilter.should_jekyll_replace?(site)
10 | document.content = ExtendedMarkdownFilter.convert_curly_to_bracket(document.content)
11 | end
12 | old_run
13 | end
14 |
15 | end
16 | end
17 |
18 | module Jekyll
19 | class Page
20 | alias_method :old_render, :render
21 |
22 | def render(layouts, site_payload)
23 | if ExtendedMarkdownFilter.should_jekyll_replace?(site)
24 | self.content = ExtendedMarkdownFilter.convert_curly_to_bracket(content)
25 | end
26 | old_render(layouts, site_payload)
27 | end
28 | end
29 | end
30 |
--------------------------------------------------------------------------------
/LICENSE.txt:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2014 Garen Torikian
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy of
6 | this software and associated documentation files (the "Software"), to deal in
7 | the Software without restriction, including without limitation the rights to
8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
9 | the Software, and to permit persons to whom the Software is furnished to do so,
10 | subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
17 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
18 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
19 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21 |
--------------------------------------------------------------------------------
/extended-markdown-filter.gemspec:
--------------------------------------------------------------------------------
1 | Gem::Specification.new do |spec|
2 | spec.name = 'extended-markdown-filter'
3 | spec.version = '0.7.0'
4 | spec.authors = ['Garen Torikian']
5 | spec.email = ['gjtorikian@gmail.com']
6 | spec.summary = %q{Add extended markup syntax to the HTML::Pipeline}
7 | spec.description = %q{This is a custom Markdown processor to be used with GitHub's HTML::Pipeline. }
8 | spec.homepage = ''
9 | spec.license = 'MIT'
10 |
11 | spec.files = `git ls-files`.split($/)
12 | spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
13 | spec.test_files = spec.files.grep(%r{^(test)/})
14 | spec.require_paths = ['lib']
15 |
16 | spec.add_dependency 'html-pipeline', '~> 2.9'
17 |
18 | spec.add_development_dependency 'bundler', '~> 1.4'
19 | spec.add_development_dependency 'rake'
20 | spec.add_development_dependency 'minitest', '~> 5.0'
21 | spec.add_development_dependency 'commonmarker', '~> 0.18'
22 | spec.add_development_dependency 'pry-byebug', '~> 3.6'
23 | spec.add_development_dependency 'rubocop', '~> 0.60'
24 | spec.add_development_dependency 'rubocop-github', '~> 0.12'
25 | end
26 |
--------------------------------------------------------------------------------
/lib/extended-markdown-filter.rb:
--------------------------------------------------------------------------------
1 | require 'html/pipeline'
2 | require 'filters/filters'
3 | require 'jekyll-override' unless defined?(Jekyll).nil?
4 |
5 | class ExtendedMarkdownFilter < HTML::Pipeline::MarkdownFilter
6 | include Filters::PreFilter
7 | include Filters::PostFilter
8 |
9 | EMF_CURLY_TAGS = %w(intro mac windows linux all tip note warning danger).join('|')
10 |
11 | def initialize(text, context = nil, result = nil)
12 | if context[:emf_use_blocks]
13 | text = self.class.convert_curly_to_bracket(text)
14 | @front_wrap = '\\[\\['
15 | @end_wrap = '\\]\\]'
16 | @wrap_symbol = '\\]'
17 | else
18 | @front_wrap = "\{\{"
19 | @end_wrap = "\}\}"
20 | @wrap_symbol = '}'
21 | end
22 |
23 | # do preprocessing, then call HTML::Pipeline::Markdown
24 | text = format_helper text
25 |
26 | super text, context, result
27 | end
28 |
29 | def self.convert_curly_to_bracket(text)
30 | return text if text.nil?
31 | text = text.gsub(/\{\{#(#{EMF_CURLY_TAGS})\}\}/, '[[#\1]]')
32 | text = text.gsub(/\{\{\/(#{EMF_CURLY_TAGS})\}\}/, '[[/\1]]')
33 | text = text.gsub(/\{\{ (octicon-\S+\s*[^\}]+) \}\}/, '[[\1]]')
34 |
35 | text
36 | end
37 |
38 | def self.should_jekyll_replace?(site)
39 | html_pipeline_context = site.site_payload['site']['html_pipeline'] && site.site_payload['site']['html_pipeline']['context']
40 | return false if html_pipeline_context.nil?
41 | pipeline_emf_context = site.site_payload['site']['html_pipeline']['context'][:emf_use_blocks] || site.site_payload['site']['html_pipeline']['context']['emf_use_blocks']
42 | site.site_payload['site']['markdown'] == 'HTMLPipeline' && html_pipeline_context && pipeline_emf_context
43 | end
44 |
45 | def call
46 | # initialize HTML::Pipeline::Markdown, then do post-processing
47 | html = super
48 |
49 | format_intro! html
50 | format_os_blocks! html
51 | format_admonitions! html
52 | format_octicons! html
53 | format_command_line! html
54 |
55 | html
56 | end
57 |
58 | end
59 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # extended-markdown-filter
2 |
3 | Extended Markdown filters for the [HTML::Pipeline](https://github.com/jch/html-pipeline).
4 |
5 | [](https://travis-ci.org/gjtorikian/extended-markdown-filter)
6 |
7 | ## Installation
8 |
9 | Add this line to your application's Gemfile:
10 |
11 | gem 'extended-markdown-filter'
12 |
13 | And then execute:
14 |
15 | $ bundle
16 |
17 | Or install it yourself as:
18 |
19 | $ gem install extended-markdown-filter
20 |
21 | ## Usage
22 |
23 | The simplest way to do this is
24 |
25 | ``` ruby
26 | require 'extended-markdown-filter'
27 | ```
28 |
29 | Then just use the HTML pipeline normally. With Jekyll, this is meant to be used with another plugin in conjunction, https://github.com/gjtorikian/jekyll-html-pipeline.
30 |
31 | A minimum config file might look like:
32 | ``` yaml
33 | gems:
34 | - extended-markdown-filter
35 | - jekyll-html-pipeline
36 |
37 | markdown: HTMLPipeline
38 | html_pipeline:
39 | filters:
40 | - "ExtendedMarkdownFilter"
41 | context:
42 | emf_use_blocks: true
43 | ```
44 |
45 | ### Within Jekyll
46 |
47 | Because of the Liquid template engine, if you use this filter with Jekyll, you might find that your curly brace tags--such as `{{#tip}}`--disappear.
48 |
49 | You'll need to pass the context `emf_use_blocks` through your filter. This sets up a totally safe monkey-patch to convert the `{{ }}` blocks into `[[ ]]`, so that Liquid ignores them. Then, this renderer will convert the Markdown appropriately.
50 |
51 | ## What does this add?
52 |
53 | You may be wondering what features this filter adds to Markdown. Great question! Here's what we've got:
54 |
55 | ### Command-line highlighting
56 |
57 | A new pre block, `command-line`, adds some divs to allow for better highlighting for terminal code.
58 |
59 | #### Example
60 |
61 | ``` command-line
62 | $ git remote add origin https://github.com/user/repo.git
63 | # Set a new remote
64 | > origin https://github.com/user/repo.git
65 | ```
66 |
67 | * `$` represents content a user enters
68 | * `` highlights content for the user
69 | * `#` represents comments
70 | * `>` represents output as a result of a command
71 |
72 | ### Helper
73 |
74 | The `helper` notation wraps content in an [accordion fold](http://jqueryui.com/accordion/).
75 |
76 | #### Example
77 |
78 | ``` helper
79 | I'm not really important enough to show.
80 | ```
81 |
82 | ### Admonition blocks
83 |
84 | You can create separate, priority-colored callouts with `{{#tip}}`, `{{#note}}`, `{{#warning}}`, and `{{#error}}` tags.
85 |
86 | #### Example
87 |
88 | {{#tip}}
89 |
90 | Here's a hot tip: **line one**
91 | Here's a hot tip: line two
92 |
93 | {{/tip}}
94 |
95 | {{#note}}
96 |
97 | You should probably know this! line one
98 | You should probably know this! line two
99 |
100 | {{/note}}
101 |
102 | {{#warning}}
103 |
104 | Yo, check this out: line one
105 | Yo, check this out: line two
106 |
107 | {{/warning}}
108 |
109 | {{#danger}}
110 |
111 | Sheeeeit, this is a problem: ~~line one~~
112 | Sheeeeit, this is a problem: line two
113 |
114 | {{/danger}}
115 |
116 | ### Intro
117 |
118 | The `intro` block demarcates a special section that provides a summary of the content to follow.
119 |
120 | #### Example
121 |
122 | {{#intro}}
123 |
124 | [Gists](https://gist.github.com) are a great way to share your work. You can share single files, parts of files, or full applications.
125 |
126 | {{/intro}}
127 |
128 | ### Octicon
129 |
130 | The `{{ octicon }}` helper lets you easily render [any Octicon](https://octicons.github.com/) in the content, including an aria label.
131 |
132 | #### Example
133 |
134 | {{ octicon-gear The Settings gear }}
135 |
136 | ### Operating system blocks
137 |
138 | Sometimes, certain content needs to be rendered for only a certain operating system. Use `{{#mac}}` of Mac OS specific content, `{{#windows}}` for Windows, `{{#linux}}` for Linux, and `{{#all}}` as a catch-all for everything else.
139 |
140 | #### Example
141 |
142 | {{#mac}}
143 |
144 | 1. Command-click on the option.
145 |
146 | {{/mac}}
147 |
148 | {{#windows}}
149 |
150 | 1. Right click on the **Start** menu.
151 |
152 | {{/windows}}
153 |
154 | {{#linux}}
155 |
156 | 1. Open the terminal.
157 |
158 | {{/linux}}
159 |
160 | {{#all}}
161 |
162 | 1. Double-click on the icon.
163 |
164 | {{/all}}
165 |
--------------------------------------------------------------------------------
/test/test_extended_markdown_filter.rb:
--------------------------------------------------------------------------------
1 | require 'test_helper'
2 |
3 | class HTML::Pipeline::ExtendedMarkdownFilterTest < Minitest::Test
4 | def fixture(name)
5 | File.open(File.join("#{File.expand_path(File.dirname(__FILE__))}", 'fixtures', name)).read
6 | end
7 |
8 | def test_command_line
9 | doc = ExtendedMarkdownFilter.to_document(fixture('command_line.md'), {})
10 | assert doc.kind_of?(HTML::Pipeline::DocumentFragment)
11 |
12 | assert_equal 1, doc.css('pre.command-line').size
13 | assert_equal 2, doc.css('span.command').size
14 | assert_equal 1, doc.css('span.comment').size
15 | assert_equal 2, doc.css('em').size
16 | assert_equal 1, doc.css('span.output').size
17 | assert_equal 0, doc.css('code').size
18 |
19 | assert_equal 0, doc.css('.command-line a').size
20 | assert_equal 8, doc.to_html.lines.count
21 | refute_equal 0, doc.css('pre').inner_text.length
22 | end
23 |
24 | def test_command_line_indented
25 | doc = ExtendedMarkdownFilter.to_document(fixture('command_line_indented.md'), {})
26 | assert doc.kind_of?(HTML::Pipeline::DocumentFragment)
27 |
28 | assert_equal 1, doc.css('pre.command-line').size
29 | assert_equal 2, doc.css('span.command').size
30 | assert_equal 1, doc.css('span.comment').size
31 | assert_equal 2, doc.css('em').size
32 | assert_equal 1, doc.css('span.output').size
33 |
34 | assert_equal 0, doc.css('.command-line a').size
35 | refute_equal 0, doc.css('pre').inner_text.length
36 | end
37 |
38 | def test_nested_command_line
39 | doc = ExtendedMarkdownFilter.to_document(fixture('command_line_nested.md'), {})
40 | assert doc.kind_of?(HTML::Pipeline::DocumentFragment)
41 |
42 | assert_equal 1, doc.css('ol').size
43 | assert_equal 2, doc.css('li').size
44 | assert_equal 2, doc.css('pre').size
45 |
46 | list = doc.css('ol')[0]
47 | first_list_item = doc.css('li')[0]
48 | first_command_line_block = doc.css('pre')[0]
49 | second_list_item = doc.css('li')[1]
50 | second_command_line_block = doc.css('pre')[1]
51 |
52 | assert list.children.include?(first_list_item)
53 | assert list.children.include?(second_list_item)
54 | assert_equal first_command_line_block.parent, first_list_item
55 | assert_equal second_command_line_block.parent, second_list_item
56 | end
57 |
58 | def test_helper_works_and_requires_unsafe
59 | doc = ExtendedMarkdownFilter.to_document(fixture('helper.md'), { unsafe: false })
60 | assert doc.kind_of?(HTML::Pipeline::DocumentFragment)
61 |
62 | assert_equal 0, doc.css('div.helper').size
63 |
64 | doc = ExtendedMarkdownFilter.to_document(fixture('helper.md'), { unsafe: true })
65 | assert doc.kind_of?(HTML::Pipeline::DocumentFragment)
66 |
67 | assert_equal 1, doc.css('div.helper').size
68 | assert_equal 1, doc.css('h4.header').size
69 | assert_equal 1, doc.css('a').size
70 | assert_equal 1, doc.css('div.content').size
71 | end
72 |
73 | def test_intro
74 | doc = ExtendedMarkdownFilter.to_document(fixture('intro.md'), {})
75 | assert doc.kind_of?(HTML::Pipeline::DocumentFragment)
76 |
77 | assert_equal 1, doc.css('div.intro').size
78 | assert_equal 1, doc.css('a').size # the inner Markdown converted!
79 | end
80 |
81 | def test_block_intro
82 | doc = ExtendedMarkdownFilter.to_document(fixture('block_intro.md'), {emf_use_blocks: true})
83 | assert doc.kind_of?(HTML::Pipeline::DocumentFragment)
84 |
85 | assert_equal 1, doc.css('div.intro').size
86 | assert_equal 1, doc.css('a').size # the inner Markdown converted!
87 | end
88 |
89 | def test_intro_conversion
90 | doc = ExtendedMarkdownFilter.to_document(fixture('intro.md'), {emf_use_blocks: true})
91 | assert doc.kind_of?(HTML::Pipeline::DocumentFragment)
92 |
93 | assert_equal 1, doc.css('div.intro').size
94 | assert_equal 1, doc.css('a').size # the inner Markdown converted!
95 | end
96 |
97 | def test_os_blocks
98 | doc = ExtendedMarkdownFilter.to_document(fixture('os_blocks.md'), {})
99 | assert doc.kind_of?(HTML::Pipeline::DocumentFragment)
100 |
101 | assert_equal 1, doc.css('div.platform-mac').size
102 | assert_equal 1, doc.css('div.platform-windows').size
103 | assert_equal 1, doc.css('div.platform-linux').size
104 | assert_equal 1, doc.css('div.platform-all').size
105 | # the inner Markdown converted!
106 | assert_equal 3, doc.css('ol').size
107 | assert_equal 2, doc.css('a').size
108 | assert_equal 1, doc.css('em').size
109 | end
110 |
111 | def test_block_os_blocks
112 | doc = ExtendedMarkdownFilter.to_document(fixture('block_os_blocks.md'), {emf_use_blocks: true})
113 | assert doc.kind_of?(HTML::Pipeline::DocumentFragment)
114 |
115 | assert_equal 1, doc.css('div.platform-mac').size
116 | assert_equal 1, doc.css('div.platform-windows').size
117 | assert_equal 1, doc.css('div.platform-linux').size
118 | assert_equal 1, doc.css('div.platform-all').size
119 | # the inner Markdown converted!
120 | assert_equal 3, doc.css('ol').size
121 | assert_equal 2, doc.css('a').size
122 | assert_equal 1, doc.css('em').size
123 | end
124 |
125 | def test_block_conversion
126 | doc = ExtendedMarkdownFilter.to_document(fixture('os_blocks.md'), {emf_use_blocks: true})
127 | assert doc.kind_of?(HTML::Pipeline::DocumentFragment)
128 |
129 | assert_equal 1, doc.css('div.platform-mac').size
130 | assert_equal 1, doc.css('div.platform-windows').size
131 | assert_equal 1, doc.css('div.platform-linux').size
132 | assert_equal 1, doc.css('div.platform-all').size
133 | # the inner Markdown converted!
134 | assert_equal 3, doc.css('ol').size
135 | assert_equal 2, doc.css('a').size
136 | assert_equal 1, doc.css('em').size
137 | end
138 |
139 | def test_admonition
140 | doc = ExtendedMarkdownFilter.to_document(fixture('admonition.md'), {})
141 | assert doc.kind_of?(HTML::Pipeline::DocumentFragment)
142 |
143 | assert_equal 1, doc.css('div.tip').size
144 | assert_equal 1, doc.css('div.note').size
145 | assert_equal 1, doc.css('div.warning').size
146 | assert_equal 1, doc.css('div.danger').size
147 | # the inner Markdown converted!
148 | assert_equal 1, doc.css('strong').size
149 | assert_equal 1, doc.css('del').size
150 | end
151 |
152 | def test_block_admonition
153 | doc = ExtendedMarkdownFilter.to_document(fixture('block_admonition.md'), {emf_use_blocks: true})
154 | assert doc.kind_of?(HTML::Pipeline::DocumentFragment)
155 |
156 | assert_equal 1, doc.css('div.tip').size
157 | assert_equal 1, doc.css('div.note').size
158 | assert_equal 1, doc.css('div.warning').size
159 | assert_equal 1, doc.css('div.danger').size
160 | # the inner Markdown converted!
161 | assert_equal 1, doc.css('strong').size
162 | assert_equal 1, doc.css('del').size
163 | end
164 |
165 | def test_admonition_conversion
166 | doc = ExtendedMarkdownFilter.to_document(fixture('admonition.md'), {emf_use_blocks: true})
167 | assert doc.kind_of?(HTML::Pipeline::DocumentFragment)
168 |
169 | assert_equal 1, doc.css('div.tip').size
170 | assert_equal 1, doc.css('div.note').size
171 | assert_equal 1, doc.css('div.warning').size
172 | assert_equal 1, doc.css('div.danger').size
173 | # the inner Markdown converted!
174 | assert_equal 1, doc.css('strong').size
175 | assert_equal 1, doc.css('del').size
176 | end
177 |
178 | def test_octicon
179 | doc = ExtendedMarkdownFilter.to_document(fixture('octicon.md'), {})
180 | assert doc.kind_of?(HTML::Pipeline::DocumentFragment)
181 |
182 | assert_equal 1, doc.css('span.octicon-cat').size
183 | assert_match '{{ octicon dog', doc.to_s
184 | assert_match '', doc.to_s
185 | end
186 |
187 | def test_block_octicon
188 | doc = ExtendedMarkdownFilter.to_document(fixture('block_octicon.md'), {emf_use_blocks: true})
189 | assert doc.kind_of?(HTML::Pipeline::DocumentFragment)
190 |
191 | assert_equal 1, doc.css('span.octicon-cat').size
192 | assert_match '[[ octicon dog', doc.to_s
193 | assert_match '', doc.to_s
194 | end
195 |
196 | def test_oction_conversion
197 | doc = ExtendedMarkdownFilter.to_document(fixture('octicon.md'), {emf_use_blocks: true})
198 | assert doc.kind_of?(HTML::Pipeline::DocumentFragment)
199 |
200 | assert_equal 1, doc.css('span.octicon-cat').size
201 | assert_match '{{ octicon dog', doc.to_s
202 | assert_match '', doc.to_s
203 | end
204 |
205 | end
206 |
--------------------------------------------------------------------------------