qiita-markdown 0.2.2 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of qiita-markdown might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/.rubocop.yml +7 -0
- data/.rubocop_todo.yml +103 -0
- data/CHANGELOG.md +5 -0
- data/Gemfile +1 -1
- data/README.md +27 -1
- data/Rakefile +3 -1
- data/lib/qiita/markdown.rb +3 -0
- data/lib/qiita/markdown/filters/code.rb +1 -1
- data/lib/qiita/markdown/filters/simplify.rb +47 -0
- data/lib/qiita/markdown/filters/syntax_highlight.rb +1 -1
- data/lib/qiita/markdown/filters/toc.rb +1 -1
- data/lib/qiita/markdown/filters/truncate.rb +81 -0
- data/lib/qiita/markdown/summary_processor.rb +23 -0
- data/lib/qiita/markdown/version.rb +1 -1
- data/qiita-markdown.gemspec +1 -0
- data/spec/qiita/markdown/processor_spec.rb +5 -5
- data/spec/qiita/markdown/summary_processor_spec.rb +235 -0
- data/spec/spec_helper.rb +1 -1
- metadata +23 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 180a959e88bbb1c45168ff83dcf6c3df486f12d7
|
4
|
+
data.tar.gz: b7e6dff4bf6b4810ccdc14fabb1ebb8c4c081053
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c13f02a0d3b10205576e12233a80f880ac6b540897bcc5bc7ab8eefde14a1090055dd8c452ac09bad53e5b6b85e49bef74b1aabe03e2b3df7b87bca5f4babc0e
|
7
|
+
data.tar.gz: 1154d125bf9c9844e61242810b3610ace6b59b197edbd925228435246f0b3a49980686d51270d50ad9966b1449aadb1bb289f81623829f7c43de60b1f6f8b66c
|
data/.rubocop.yml
ADDED
data/.rubocop_todo.yml
ADDED
@@ -0,0 +1,103 @@
|
|
1
|
+
# This configuration was generated by `rubocop --auto-gen-config`
|
2
|
+
# on 2015-03-12 12:56:25 +0900 using RuboCop version 0.29.1.
|
3
|
+
# The point is for the user to remove these configuration records
|
4
|
+
# one by one as the offenses are removed from the code base.
|
5
|
+
# Note that changes in the inspected code, or installation of new
|
6
|
+
# versions of RuboCop, may require this file to be generated again.
|
7
|
+
|
8
|
+
# Offense count: 1
|
9
|
+
Metrics/AbcSize:
|
10
|
+
Max: 21
|
11
|
+
|
12
|
+
# Offense count: 1
|
13
|
+
# Configuration parameters: CountComments.
|
14
|
+
Metrics/ClassLength:
|
15
|
+
Max: 169
|
16
|
+
|
17
|
+
# Offense count: 27
|
18
|
+
# Configuration parameters: AllowURI, URISchemes.
|
19
|
+
Metrics/LineLength:
|
20
|
+
Max: 122
|
21
|
+
|
22
|
+
# Offense count: 3
|
23
|
+
# Configuration parameters: CountComments.
|
24
|
+
Metrics/MethodLength:
|
25
|
+
Max: 17
|
26
|
+
|
27
|
+
# Offense count: 1
|
28
|
+
# Cop supports --auto-correct.
|
29
|
+
# Configuration parameters: EnforcedStyle, SupportedStyles.
|
30
|
+
Style/AndOr:
|
31
|
+
Enabled: false
|
32
|
+
|
33
|
+
# Offense count: 3
|
34
|
+
# Cop supports --auto-correct.
|
35
|
+
# Configuration parameters: EnforcedStyle, SupportedStyles.
|
36
|
+
Style/BarePercentLiterals:
|
37
|
+
Enabled: false
|
38
|
+
|
39
|
+
# Offense count: 1
|
40
|
+
Style/ConstantName:
|
41
|
+
Enabled: false
|
42
|
+
|
43
|
+
# Offense count: 10
|
44
|
+
Style/Documentation:
|
45
|
+
Enabled: false
|
46
|
+
|
47
|
+
# Offense count: 3
|
48
|
+
Style/DoubleNegation:
|
49
|
+
Enabled: false
|
50
|
+
|
51
|
+
# Offense count: 1
|
52
|
+
# Configuration parameters: Exclude.
|
53
|
+
Style/FileName:
|
54
|
+
Enabled: false
|
55
|
+
|
56
|
+
# Offense count: 1
|
57
|
+
# Configuration parameters: MinBodyLength.
|
58
|
+
Style/GuardClause:
|
59
|
+
Enabled: false
|
60
|
+
|
61
|
+
# Offense count: 1
|
62
|
+
# Configuration parameters: EnforcedStyle, MinBodyLength, SupportedStyles.
|
63
|
+
Style/Next:
|
64
|
+
Enabled: false
|
65
|
+
|
66
|
+
# Offense count: 9
|
67
|
+
# Cop supports --auto-correct.
|
68
|
+
# Configuration parameters: PreferredDelimiters.
|
69
|
+
Style/PercentLiteralDelimiters:
|
70
|
+
Enabled: false
|
71
|
+
|
72
|
+
# Offense count: 1
|
73
|
+
# Cop supports --auto-correct.
|
74
|
+
Style/PerlBackrefs:
|
75
|
+
Enabled: false
|
76
|
+
|
77
|
+
# Offense count: 10
|
78
|
+
# Configuration parameters: NamePrefix, NamePrefixBlacklist.
|
79
|
+
Style/PredicateName:
|
80
|
+
Enabled: false
|
81
|
+
|
82
|
+
# Offense count: 2
|
83
|
+
# Configuration parameters: MaxSlashes.
|
84
|
+
Style/RegexpLiteral:
|
85
|
+
Enabled: false
|
86
|
+
|
87
|
+
# Offense count: 2
|
88
|
+
# Cop supports --auto-correct.
|
89
|
+
# Configuration parameters: EnforcedStyle, SupportedStyles.
|
90
|
+
Style/SignalException:
|
91
|
+
Enabled: false
|
92
|
+
|
93
|
+
# Offense count: 2
|
94
|
+
# Cop supports --auto-correct.
|
95
|
+
# Configuration parameters: EnforcedStyleForMultiline, SupportedStyles.
|
96
|
+
Style/TrailingComma:
|
97
|
+
Enabled: false
|
98
|
+
|
99
|
+
# Offense count: 6
|
100
|
+
# Cop supports --auto-correct.
|
101
|
+
# Configuration parameters: WordRegex.
|
102
|
+
Style/WordArray:
|
103
|
+
Enabled: false
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,8 @@
|
|
1
|
+
## Unreleased
|
2
|
+
|
3
|
+
## 0.3.0
|
4
|
+
- Introduce another processor Qiita::Markdown::SummaryProcessor, which is for rendering a summary of markdown document.
|
5
|
+
|
1
6
|
## 0.2.2
|
2
7
|
- Fix a bug that raised error on rendering `<a>` tag with href for unknown fragment inside of `<sup>` tag (e.g. `<sup><a href="#foo.1">Link</a></sup>`)
|
3
8
|
|
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -12,7 +12,7 @@ Qiita-specified markdown processor.
|
|
12
12
|
* Task list
|
13
13
|
* Footnotes
|
14
14
|
|
15
|
-
## Usage
|
15
|
+
## Basic Usage
|
16
16
|
Qiita::Markdown::Processor provides markdown rendering logic.
|
17
17
|
|
18
18
|
```ruby
|
@@ -62,3 +62,29 @@ processor.call(text)
|
|
62
62
|
processor = Qiita::Markdown::Processor.new(asset_root: "http://example.com/assets")
|
63
63
|
processor.call(text)
|
64
64
|
```
|
65
|
+
|
66
|
+
## Rendering Summary
|
67
|
+
There's another processor Qiita::Markdown::SummaryProcessor,
|
68
|
+
which is for rendering a summary of markdown document.
|
69
|
+
It simplifies a document by removing complex markups
|
70
|
+
and also truncates it to a specific length without breaking the document structure.
|
71
|
+
|
72
|
+
Note that this processor does not produce the `:codes` output in contrast to the Processor.
|
73
|
+
|
74
|
+
### Context
|
75
|
+
|
76
|
+
SummaryProcessor accepts the following context in addition to the Processor's context:
|
77
|
+
|
78
|
+
```ruby
|
79
|
+
{
|
80
|
+
truncate: {
|
81
|
+
length: 100, # Documents will be truncated if it exceeds this character count. (Integer)
|
82
|
+
omission: '…' # A string added to the end of document when it's truncated. (String, nil)
|
83
|
+
}
|
84
|
+
}
|
85
|
+
```
|
86
|
+
|
87
|
+
```ruby
|
88
|
+
processor = Qiita::Markdown::SummaryProcessor.new(truncate: { length: 80 })
|
89
|
+
processor.call(text)
|
90
|
+
```
|
data/Rakefile
CHANGED
data/lib/qiita/markdown.rb
CHANGED
@@ -13,7 +13,10 @@ require "qiita/markdown/filters/footnote"
|
|
13
13
|
require "qiita/markdown/filters/mention"
|
14
14
|
require "qiita/markdown/filters/redcarpet"
|
15
15
|
require "qiita/markdown/filters/sanitize"
|
16
|
+
require "qiita/markdown/filters/simplify"
|
16
17
|
require "qiita/markdown/filters/syntax_highlight"
|
17
18
|
require "qiita/markdown/filters/toc"
|
19
|
+
require "qiita/markdown/filters/truncate"
|
18
20
|
require "qiita/markdown/processor"
|
21
|
+
require "qiita/markdown/summary_processor"
|
19
22
|
require "qiita/markdown/version"
|
@@ -0,0 +1,47 @@
|
|
1
|
+
module Qiita
|
2
|
+
module Markdown
|
3
|
+
module Filters
|
4
|
+
# A filter for simplifying document structure by removing complex markups
|
5
|
+
# (mainly block elements) and complex contents.
|
6
|
+
#
|
7
|
+
# The logic of this filter is similar to the `Sanitize` filter, but this
|
8
|
+
# does not use the `sanitize` gem internally for the following reasons:
|
9
|
+
#
|
10
|
+
# * Each filter should do only its own responsibility, and this filter is
|
11
|
+
# _not_ for sanitization.
|
12
|
+
#
|
13
|
+
# * The `sanitize` gem automatically adds extra transformers even if we
|
14
|
+
# want to clean up only some elements, and they would be run in the
|
15
|
+
# `Sanitize` filter later.
|
16
|
+
# https://github.com/rgrove/sanitize/blob/v3.1.2/lib/sanitize.rb#L77-L100
|
17
|
+
class Simplify < HTML::Pipeline::Filter
|
18
|
+
SIMPLE_ELEMENTS = %w(a b code em i ins q s samp span strike strong sub sup var)
|
19
|
+
|
20
|
+
COMPLEX_CONTENT_ELEMENTS = %w(table)
|
21
|
+
|
22
|
+
def call
|
23
|
+
remove_complex_contents
|
24
|
+
clean_complex_markups
|
25
|
+
doc
|
26
|
+
end
|
27
|
+
|
28
|
+
private
|
29
|
+
|
30
|
+
# Remove complex elements along with their contents entirely.
|
31
|
+
def remove_complex_contents
|
32
|
+
selector = COMPLEX_CONTENT_ELEMENTS.join(",")
|
33
|
+
doc.search(selector).each(&:remove)
|
34
|
+
end
|
35
|
+
|
36
|
+
# Remove complex markups while keeping their contents.
|
37
|
+
def clean_complex_markups
|
38
|
+
doc.traverse do |node|
|
39
|
+
next unless node.element?
|
40
|
+
next if SIMPLE_ELEMENTS.include?(node.name)
|
41
|
+
node.replace(node.children)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -32,7 +32,7 @@ module Qiita
|
|
32
32
|
|
33
33
|
def call
|
34
34
|
outer = Nokogiri::HTML.fragment(%Q[<div class="code-frame" data-lang="#{language}">])
|
35
|
-
frame = outer.at(
|
35
|
+
frame = outer.at("div")
|
36
36
|
frame.add_child(filename_node) if filename
|
37
37
|
frame.add_child(highlighted_node)
|
38
38
|
@node.replace(outer)
|
@@ -0,0 +1,81 @@
|
|
1
|
+
module Qiita
|
2
|
+
module Markdown
|
3
|
+
module Filters
|
4
|
+
# A filter for truncating a document without breaking the document
|
5
|
+
# structure.
|
6
|
+
#
|
7
|
+
# You can pass `:length` and `:omission` option to :truncate context.
|
8
|
+
#
|
9
|
+
# @example
|
10
|
+
# Truncate.new(doc, truncate: { length: 50, omission: '... (continued)' })
|
11
|
+
class Truncate < HTML::Pipeline::Filter
|
12
|
+
DEFAULT_OPTIONS = {
|
13
|
+
length: 100,
|
14
|
+
omission: "…".freeze
|
15
|
+
}.freeze
|
16
|
+
|
17
|
+
def call
|
18
|
+
@current_length = 0
|
19
|
+
@previous_char_was_blank = false
|
20
|
+
|
21
|
+
traverse(doc) do |node|
|
22
|
+
if exceeded?
|
23
|
+
node.remove
|
24
|
+
elsif node.text?
|
25
|
+
process_text_node(node)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
doc
|
30
|
+
end
|
31
|
+
|
32
|
+
private
|
33
|
+
|
34
|
+
# Traverse the given node recursively in the depth-first order.
|
35
|
+
# Note that we cannot use Nokogiri::XML::Node#traverse
|
36
|
+
# since it traverses the node's descendants _before_ the node itself.
|
37
|
+
# https://github.com/sparklemotion/nokogiri/blob/v1.6.6.2/lib/nokogiri/xml/node.rb#L571-L574
|
38
|
+
def traverse(node, &block)
|
39
|
+
block.call(node)
|
40
|
+
|
41
|
+
node.children.each do |child_node|
|
42
|
+
traverse(child_node, &block)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def exceeded?
|
47
|
+
@current_length > max_length
|
48
|
+
end
|
49
|
+
|
50
|
+
def process_text_node(node)
|
51
|
+
node.content.each_char.with_index do |char, index|
|
52
|
+
current_char_is_blank = char.strip.empty?
|
53
|
+
|
54
|
+
if !@previous_char_was_blank || !current_char_is_blank
|
55
|
+
@current_length += 1
|
56
|
+
end
|
57
|
+
|
58
|
+
@previous_char_was_blank = current_char_is_blank
|
59
|
+
|
60
|
+
if exceeded?
|
61
|
+
node.content = node.content.slice(0...(index - omission.size)) + omission
|
62
|
+
break
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
def max_length
|
68
|
+
options[:length]
|
69
|
+
end
|
70
|
+
|
71
|
+
def omission
|
72
|
+
options[:omission] || "".freeze
|
73
|
+
end
|
74
|
+
|
75
|
+
def options
|
76
|
+
@options ||= DEFAULT_OPTIONS.merge(context[:truncate] || {})
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module Qiita
|
2
|
+
module Markdown
|
3
|
+
# A processor for rendering a summary of markdown document. This simplifies
|
4
|
+
# a document by removing complex markups and also truncates it to a
|
5
|
+
# specific length without breaking the document structure.
|
6
|
+
class SummaryProcessor < Processor
|
7
|
+
DEFAULT_FILTERS = [
|
8
|
+
Filters::Redcarpet,
|
9
|
+
Filters::Simplify,
|
10
|
+
HTML::Pipeline::EmojiFilter,
|
11
|
+
Filters::Mention,
|
12
|
+
Filters::Sanitize,
|
13
|
+
Filters::Truncate
|
14
|
+
]
|
15
|
+
|
16
|
+
# @note Modify filters if you want.
|
17
|
+
# @return [Array<HTML::Pipeline::Filter>]
|
18
|
+
def filters
|
19
|
+
@filters ||= DEFAULT_FILTERS
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
data/qiita-markdown.gemspec
CHANGED
@@ -256,13 +256,13 @@ describe Qiita::Markdown::Processor do
|
|
256
256
|
@justin
|
257
257
|
@justin
|
258
258
|
@mallory@github
|
259
|
-
@#{
|
259
|
+
@#{'o' * 33}
|
260
260
|
@oo
|
261
261
|
EOS
|
262
262
|
end
|
263
263
|
|
264
264
|
it "extracts mentions correctly" do
|
265
|
-
expect(result[:mentioned_usernames]).to eq %
|
265
|
+
expect(result[:mentioned_usernames]).to eq %w[
|
266
266
|
alice
|
267
267
|
dave
|
268
268
|
ell_en
|
@@ -522,7 +522,7 @@ describe Qiita::Markdown::Processor do
|
|
522
522
|
end
|
523
523
|
end
|
524
524
|
|
525
|
-
context
|
525
|
+
context "with footenotes syntax" do
|
526
526
|
let(:markdown) do
|
527
527
|
<<-EOS.strip_heredoc
|
528
528
|
[^1]
|
@@ -548,7 +548,7 @@ describe Qiita::Markdown::Processor do
|
|
548
548
|
end
|
549
549
|
end
|
550
550
|
|
551
|
-
context
|
551
|
+
context "with manually written link inside of <sup> tag" do
|
552
552
|
let(:markdown) do
|
553
553
|
<<-EOS.strip_heredoc
|
554
554
|
<sup>[Qiita](http://qiita.com/)</sup>
|
@@ -562,7 +562,7 @@ describe Qiita::Markdown::Processor do
|
|
562
562
|
end
|
563
563
|
end
|
564
564
|
|
565
|
-
context
|
565
|
+
context "with manually written <a> tag with strange href inside of <sup> tag" do
|
566
566
|
let(:markdown) do
|
567
567
|
<<-EOS.strip_heredoc
|
568
568
|
<sup><a href="#foo.1">Link</a></sup>
|
@@ -0,0 +1,235 @@
|
|
1
|
+
require "active_support/core_ext/string/strip"
|
2
|
+
|
3
|
+
describe Qiita::Markdown::SummaryProcessor do
|
4
|
+
describe "#call" do
|
5
|
+
subject(:html) do
|
6
|
+
result[:output].to_s
|
7
|
+
end
|
8
|
+
|
9
|
+
let(:context) do
|
10
|
+
{}
|
11
|
+
end
|
12
|
+
|
13
|
+
let(:markdown) do
|
14
|
+
fail NotImplementedError
|
15
|
+
end
|
16
|
+
|
17
|
+
let(:result) do
|
18
|
+
described_class.new(context).call(markdown)
|
19
|
+
end
|
20
|
+
|
21
|
+
context "with valid condition" do
|
22
|
+
let(:markdown) do
|
23
|
+
<<-EOS.strip_heredoc
|
24
|
+
example
|
25
|
+
EOS
|
26
|
+
end
|
27
|
+
|
28
|
+
it "returns a Hash with HTML output and other metadata but no codes" do
|
29
|
+
expect(result[:mentioned_usernames]).to be_an Array
|
30
|
+
expect(result[:output]).to be_a Nokogiri::HTML::DocumentFragment
|
31
|
+
expect(result).not_to have_key(:codes)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
context "with HTML-characters" do
|
36
|
+
let(:markdown) do
|
37
|
+
"<>&"
|
38
|
+
end
|
39
|
+
|
40
|
+
it "sanitizes them" do
|
41
|
+
should eq <<-EOS.strip_heredoc
|
42
|
+
<>&
|
43
|
+
EOS
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
context "with code" do
|
48
|
+
let(:markdown) do
|
49
|
+
<<-EOS.strip_heredoc
|
50
|
+
```ruby
|
51
|
+
puts 'hello world'
|
52
|
+
```
|
53
|
+
EOS
|
54
|
+
end
|
55
|
+
|
56
|
+
it "returns simple code element" do
|
57
|
+
should eq <<-EOS.strip_heredoc
|
58
|
+
<code class="ruby">puts 'hello world'
|
59
|
+
</code>
|
60
|
+
EOS
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
context "with emoji" do
|
65
|
+
let(:markdown) do
|
66
|
+
":+1:"
|
67
|
+
end
|
68
|
+
|
69
|
+
it "replaces it with img element" do
|
70
|
+
should include("img")
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
context "with image" do
|
75
|
+
let(:markdown) do
|
76
|
+
<<-EOS.strip_heredoc
|
77
|
+
![Qiita](http://qiita.com/icons/favicons/public/apple-touch-icon.png)
|
78
|
+
EOS
|
79
|
+
end
|
80
|
+
|
81
|
+
it "removes it" do
|
82
|
+
expect(html.strip).to be_empty
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
context "with line breaks" do
|
87
|
+
let(:markdown) do
|
88
|
+
<<-EOS.strip_heredoc
|
89
|
+
foo
|
90
|
+
bar
|
91
|
+
EOS
|
92
|
+
end
|
93
|
+
|
94
|
+
it "removes them" do
|
95
|
+
should eq <<-EOS.strip_heredoc
|
96
|
+
foo
|
97
|
+
bar
|
98
|
+
EOS
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
context "with paragraphs" do
|
103
|
+
let(:markdown) do
|
104
|
+
<<-EOS.strip_heredoc
|
105
|
+
Lorem ipsum dolor sit amet.
|
106
|
+
|
107
|
+
Consectetur adipisicing elit.
|
108
|
+
EOS
|
109
|
+
end
|
110
|
+
|
111
|
+
it "flattens them" do
|
112
|
+
should eq <<-EOS.strip_heredoc
|
113
|
+
Lorem ipsum dolor sit amet.
|
114
|
+
|
115
|
+
Consectetur adipisicing elit.
|
116
|
+
EOS
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
context "with normal list items" do
|
121
|
+
let(:markdown) do
|
122
|
+
<<-EOS.strip_heredoc
|
123
|
+
- foo
|
124
|
+
- bar
|
125
|
+
EOS
|
126
|
+
end
|
127
|
+
|
128
|
+
it "flattens them" do
|
129
|
+
should eq <<-EOS.strip_heredoc
|
130
|
+
|
131
|
+
foo
|
132
|
+
bar
|
133
|
+
|
134
|
+
EOS
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
138
|
+
context "with task list items" do
|
139
|
+
let(:markdown) do
|
140
|
+
<<-EOS.strip_heredoc
|
141
|
+
- [ ] foo
|
142
|
+
- [x] bar
|
143
|
+
EOS
|
144
|
+
end
|
145
|
+
|
146
|
+
it "flattens them without converting to checkboxes" do
|
147
|
+
should eq <<-EOS.strip_heredoc
|
148
|
+
|
149
|
+
[ ] foo
|
150
|
+
[x] bar
|
151
|
+
|
152
|
+
EOS
|
153
|
+
end
|
154
|
+
end
|
155
|
+
|
156
|
+
context "with table" do
|
157
|
+
let(:markdown) do
|
158
|
+
<<-EOS.strip_heredoc
|
159
|
+
| a | b | c |
|
160
|
+
|---|---|---|
|
161
|
+
| a | b | c |
|
162
|
+
EOS
|
163
|
+
end
|
164
|
+
|
165
|
+
it "removes it entirely" do
|
166
|
+
expect(html.strip).to be_empty
|
167
|
+
end
|
168
|
+
end
|
169
|
+
|
170
|
+
context "with a simple long document" do
|
171
|
+
before do
|
172
|
+
context[:truncate] = { length: 10 }
|
173
|
+
end
|
174
|
+
|
175
|
+
let(:markdown) do
|
176
|
+
<<-EOS.strip_heredoc
|
177
|
+
Lorem ipsum dolor sit amet.
|
178
|
+
EOS
|
179
|
+
end
|
180
|
+
|
181
|
+
it "truncates it to the specified length" do
|
182
|
+
should eq "Lorem ips…"
|
183
|
+
end
|
184
|
+
end
|
185
|
+
|
186
|
+
context "with a long document consisting of nested elements" do
|
187
|
+
before do
|
188
|
+
context[:truncate] = { length: 10 }
|
189
|
+
end
|
190
|
+
|
191
|
+
let(:markdown) do
|
192
|
+
<<-EOS.strip_heredoc
|
193
|
+
_[Qiita](http://qiita.com/) is **a technical knowledge sharing and collaboration platform for programmers**._
|
194
|
+
EOS
|
195
|
+
end
|
196
|
+
|
197
|
+
it "truncates it while honoring the document structure" do
|
198
|
+
should eq '<em><a href="http://qiita.com/">Qiita</a> is <strong>…</strong></em>'
|
199
|
+
end
|
200
|
+
end
|
201
|
+
|
202
|
+
context "with a long document including consecutive whitespaces" do
|
203
|
+
before do
|
204
|
+
context[:truncate] = { length: 10 }
|
205
|
+
end
|
206
|
+
|
207
|
+
let(:markdown) do
|
208
|
+
<<-EOS.strip_heredoc
|
209
|
+
**12** 4 [ 6](http://qiita.com/)_7
|
210
|
+
9_ 123
|
211
|
+
EOS
|
212
|
+
end
|
213
|
+
|
214
|
+
it "truncates it while counting the consecutive whilespaces as one" do
|
215
|
+
should eq "<strong>12</strong> 4 <a href=\"http://qiita.com/\"> 6</a><em>7\n9</em>…"
|
216
|
+
end
|
217
|
+
end
|
218
|
+
|
219
|
+
context "with truncate: { omission: nil } context" do
|
220
|
+
before do
|
221
|
+
context[:truncate] = { length: 10, omission: nil }
|
222
|
+
end
|
223
|
+
|
224
|
+
let(:markdown) do
|
225
|
+
<<-EOS.strip_heredoc
|
226
|
+
Lorem ipsum dolor sit amet.
|
227
|
+
EOS
|
228
|
+
end
|
229
|
+
|
230
|
+
it "does not add extra omission text" do
|
231
|
+
should eq "Lorem ipsu"
|
232
|
+
end
|
233
|
+
end
|
234
|
+
end
|
235
|
+
end
|
data/spec/spec_helper.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: qiita-markdown
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ryo Nakamura
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-
|
11
|
+
date: 2015-03-12 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
@@ -192,6 +192,20 @@ dependencies:
|
|
192
192
|
- - '='
|
193
193
|
- !ruby/object:Gem::Version
|
194
194
|
version: 3.1.0
|
195
|
+
- !ruby/object:Gem::Dependency
|
196
|
+
name: rubocop
|
197
|
+
requirement: !ruby/object:Gem::Requirement
|
198
|
+
requirements:
|
199
|
+
- - "~>"
|
200
|
+
- !ruby/object:Gem::Version
|
201
|
+
version: '0.29'
|
202
|
+
type: :development
|
203
|
+
prerelease: false
|
204
|
+
version_requirements: !ruby/object:Gem::Requirement
|
205
|
+
requirements:
|
206
|
+
- - "~>"
|
207
|
+
- !ruby/object:Gem::Version
|
208
|
+
version: '0.29'
|
195
209
|
description:
|
196
210
|
email:
|
197
211
|
- r7kamura@gmail.com
|
@@ -201,6 +215,8 @@ extra_rdoc_files: []
|
|
201
215
|
files:
|
202
216
|
- ".gitignore"
|
203
217
|
- ".rspec"
|
218
|
+
- ".rubocop.yml"
|
219
|
+
- ".rubocop_todo.yml"
|
204
220
|
- ".travis.yml"
|
205
221
|
- CHANGELOG.md
|
206
222
|
- Gemfile
|
@@ -215,12 +231,16 @@ files:
|
|
215
231
|
- lib/qiita/markdown/filters/mention.rb
|
216
232
|
- lib/qiita/markdown/filters/redcarpet.rb
|
217
233
|
- lib/qiita/markdown/filters/sanitize.rb
|
234
|
+
- lib/qiita/markdown/filters/simplify.rb
|
218
235
|
- lib/qiita/markdown/filters/syntax_highlight.rb
|
219
236
|
- lib/qiita/markdown/filters/toc.rb
|
237
|
+
- lib/qiita/markdown/filters/truncate.rb
|
220
238
|
- lib/qiita/markdown/processor.rb
|
239
|
+
- lib/qiita/markdown/summary_processor.rb
|
221
240
|
- lib/qiita/markdown/version.rb
|
222
241
|
- qiita-markdown.gemspec
|
223
242
|
- spec/qiita/markdown/processor_spec.rb
|
243
|
+
- spec/qiita/markdown/summary_processor_spec.rb
|
224
244
|
- spec/spec_helper.rb
|
225
245
|
homepage: https://github.com/increments/qiita-markdown
|
226
246
|
licenses:
|
@@ -248,5 +268,6 @@ specification_version: 4
|
|
248
268
|
summary: Qiita-specified markdown processor.
|
249
269
|
test_files:
|
250
270
|
- spec/qiita/markdown/processor_spec.rb
|
271
|
+
- spec/qiita/markdown/summary_processor_spec.rb
|
251
272
|
- spec/spec_helper.rb
|
252
273
|
has_rdoc:
|