devcenter-parser 2.2.5 → 2.2.11

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b1ecce7a41e0f3665dce79c95b6936d1dd530ed1548055ebe602ede352583192
4
- data.tar.gz: 06a10cc3bb0f7932b79b20bfc481a3408be0996f1e0b8a1ef65d60fe93757dc5
3
+ metadata.gz: dfd75f1b30669185f61feb1051ca91a23a19e6552b4a8f14c6ec60a57205f858
4
+ data.tar.gz: 13929cf26ab3771a28e7f887f0a70dd2e6bf79a922259284c5874da8bff65816
5
5
  SHA512:
6
- metadata.gz: 6b12389bc38dd0bf4d1125e16d10040121b34f55f10065cb891f04b5f23eae1e5129328a31e5e4fb27a2f278f9f120125caf2e753e59c619aa56e5691659113c
7
- data.tar.gz: 0e27a7fdc0f13a3d1a41d1ae8ddddbc38bb02fb7e7c6d26187f3a77e9994b7c4b7bd7787aa391f76998eae8e567542f93994d22cbadd83a8d74fcdf3644ddff6
6
+ metadata.gz: 699004a8938e09580e9f3a3d5f355d88dbea868b207992400d299e1ec073d29ebd3ccf2ff7fb3b42d00ea9da8aa5386d268c8b05a028ea50635f18afec04922b
7
+ data.tar.gz: 1c0a5f037d378b78315e1497cac388074aae7fa3c391b510768eb0ee683b35ac10aec7936bb0b212df15f275727cf4b265ef43eb48c2cc04b1b6b3c056f880f2
@@ -1,27 +1,27 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- devcenter-parser (2.2.5)
4
+ devcenter-parser (2.2.10)
5
5
  nokogiri (>= 1.7.1)
6
- redcarpet (= 3.3.4)
7
- sanitize (~> 4.6.3)
6
+ redcarpet (= 3.5.0)
7
+ sanitize (~> 5.2.1)
8
8
 
9
9
  GEM
10
10
  remote: http://rubygems.org/
11
11
  specs:
12
- crass (1.0.4)
13
- mini_portile2 (2.3.0)
12
+ crass (1.0.6)
13
+ mini_portile2 (2.4.0)
14
14
  minitest (5.10.1)
15
- nokogiri (1.8.5)
16
- mini_portile2 (~> 2.3.0)
17
- nokogumbo (1.5.0)
18
- nokogiri
15
+ nokogiri (1.10.10)
16
+ mini_portile2 (~> 2.4.0)
17
+ nokogumbo (2.0.2)
18
+ nokogiri (~> 1.8, >= 1.8.4)
19
19
  rake (12.0.0)
20
- redcarpet (3.3.4)
21
- sanitize (4.6.6)
20
+ redcarpet (3.5.0)
21
+ sanitize (5.2.1)
22
22
  crass (~> 1.0.2)
23
- nokogiri (>= 1.4.4)
24
- nokogumbo (~> 1.4)
23
+ nokogiri (>= 1.8.0)
24
+ nokogumbo (~> 2.0)
25
25
 
26
26
  PLATFORMS
27
27
  ruby
@@ -32,4 +32,4 @@ DEPENDENCIES
32
32
  rake
33
33
 
34
34
  BUNDLED WITH
35
- 1.16.4
35
+ 1.17.2
@@ -15,8 +15,8 @@ Gem::Specification.new do |gem|
15
15
  gem.require_paths = %w{ lib }
16
16
 
17
17
  gem.add_runtime_dependency 'nokogiri', '>= 1.7.1'
18
- gem.add_runtime_dependency 'redcarpet', '3.3.4'
19
- gem.add_runtime_dependency 'sanitize', '~>4.6.3'
18
+ gem.add_runtime_dependency 'redcarpet', '3.5.0'
19
+ gem.add_runtime_dependency 'sanitize', '~>5.2.1'
20
20
 
21
21
  gem.add_development_dependency 'minitest', '>2.0'
22
22
  gem.add_development_dependency 'rake'
@@ -10,14 +10,14 @@ module DevcenterParser
10
10
  class InvalidMarkdownError < Exception; end
11
11
  class InvalidRawHTMLError < Exception; end
12
12
 
13
- def self.to_html(markdown)
14
- sanitize to_unsanitized_html(markdown)
13
+ def self.to_html(markdown, options = {})
14
+ sanitize to_unsanitized_html(markdown, options)
15
15
  end
16
16
 
17
- def self.to_unsanitized_html(markdown)
17
+ def self.to_unsanitized_html(markdown, options = {})
18
18
  markdown = normalize_markdown(markdown)
19
19
  doc = GitHubParser.parse(markdown)
20
- doc_to_html(doc)
20
+ doc_to_html(doc, options)
21
21
  rescue InvalidRawHTMLError => e
22
22
  raise InvalidMarkdownError, e.message
23
23
  end
@@ -28,9 +28,9 @@ module DevcenterParser
28
28
 
29
29
  private
30
30
 
31
- def self.doc_to_html(doc)
31
+ def self.doc_to_html(doc, options = {})
32
32
  HeaderIdGenerator.apply!(doc)
33
- convert_to_article_links_all_relative_links_with_missing_initial_slashes(doc)
33
+ convert_to_article_links_all_relative_links_with_missing_initial_slashes(doc, options)
34
34
  html = doc.to_html(:encoding => 'utf-8')
35
35
  verify_raw_html(html)
36
36
  html
@@ -92,10 +92,15 @@ module DevcenterParser
92
92
  @@sanitize_config = config.merge({remove_contents: true, allow_comments: true})
93
93
  end
94
94
 
95
- def self.convert_to_article_links_all_relative_links_with_missing_initial_slashes(doc)
95
+ def self.convert_to_article_links_all_relative_links_with_missing_initial_slashes(doc, options = {})
96
+ link_prefix = options[:link_prefix] || '/articles'
96
97
  doc.css('a').each do |node|
97
- unless node['href'].nil? || node['href'] =~ /\Ahttp|\A\/|\Amailto\:|\A#/
98
- node['href'] = "/articles/#{node['href']}".gsub('/articles/articles/', '/articles/')
98
+ next if node['href'].nil? || node['href'] =~ /\Ahttp|\A\/|\Amailto\:|\A#/
99
+
100
+ if node['href'].start_with? 'categories/'
101
+ node['href'] = "/#{node['href']}"
102
+ else
103
+ node['href'] = "#{link_prefix}/#{node['href']}".gsub('/articles/articles/', '/articles/')
99
104
  end
100
105
  end
101
106
  end
@@ -124,7 +129,7 @@ module DevcenterParser
124
129
  end
125
130
 
126
131
  def self.iframe_has_invalid_src?(node)
127
- node.attributes['src'].value !~ /\Ahttps:\/\/player.vimeo.com\//i && node.attributes['src'].value !~ /\Ahttps:\/\/www.youtube.com\/embed/i
132
+ node.attributes['src'].value !~ /https:\/\/player.vimeo.com(.+)(&|\?)dnt=true/i && node.attributes['src'].value !~ /\Ahttps:\/\/www\.youtube-nocookie\.com\/embed/i
128
133
  end
129
134
 
130
135
  def self.iframe?(node)
@@ -34,7 +34,7 @@ module GitHubParser
34
34
 
35
35
  def self.parse(markdown)
36
36
  html = github_parser.render(markdown.to_s)
37
- doc = Nokogiri::HTML::DocumentFragment.parse(html)
37
+ doc = Nokogiri::HTML5::DocumentFragment.parse(html)
38
38
  special_blocks(doc)
39
39
  doc
40
40
  end
@@ -72,7 +72,13 @@ class HeaderIdGenerator
72
72
  end
73
73
 
74
74
  def add_default_ids
75
- @nodes_ids.each{ |node, id| @nodes_ids[node] = subheader_id(node.content) }
75
+ @nodes_ids.each do |node, _|
76
+ if node['id'].to_s.empty?
77
+ @nodes_ids[node] = subheader_id(node.content)
78
+ else
79
+ @nodes_ids[node] = node['id']
80
+ end
81
+ end
76
82
  end
77
83
 
78
84
  def subheader_id(content)
@@ -1,3 +1,3 @@
1
1
  module DevcenterParser
2
- VERSION = '2.2.5'.freeze
2
+ VERSION = '2.2.11'.freeze
3
3
  end
@@ -18,6 +18,10 @@ describe 'DevcenterParser' do
18
18
  assert_parsing_unsanitized_result '<toolbelt />', '<p><toolbelt></toolbelt></p>'
19
19
  end
20
20
 
21
+ it 'keeps html entities' do
22
+ assert_parsing_unsanitized_result '<p>&nbsp;</p>', '<p>&nbsp;</p>'
23
+ end
24
+
21
25
  end
22
26
 
23
27
  describe '.to_html' do
@@ -26,6 +30,10 @@ describe 'DevcenterParser' do
26
30
  assert_parsing_result nil, ''
27
31
  end
28
32
 
33
+ it 'keeps html entities' do
34
+ assert_parsing_result '<p>&nbsp;</p>', '<p>&nbsp;</p>'
35
+ end
36
+
29
37
  it 'does not create <em>s inside words' do
30
38
  assert_parsing_result 'foo_bar_baz', '<p>foo_bar_baz</p>'
31
39
  end
@@ -42,11 +50,31 @@ describe 'DevcenterParser' do
42
50
  assert_parsing_result md, html
43
51
  end
44
52
 
45
- it 'allows embedding vimeo videos' do
46
- src = '<iframe src="https://player.vimeo.com/video/61044807?title=0&amp;byline=0&amp;portrait=0&amp;color=a086ee" width="50" height="281" frameborder="0" webkitallowfullscreen="" mozallowfullscreen="" allowfullscreen=""></iframe>'
53
+ it 'allows embedding vimeo videos when their do-no-track param is set to true' do
54
+ src = '<iframe src="https://player.vimeo.com/video/143343818?api=1&amp;dnt=true&amp;title=foo" width="50" height="281" frameborder="0" webkitallowfullscreen="" mozallowfullscreen="" allowfullscreen=""></iframe>'
55
+ assert_parsing_result src, src
56
+ end
57
+
58
+ it 'allows embedding youtube videos from its no-cookies domain' do
59
+ src = '<iframe width="560" height="315" src="https://www.youtube-nocookie.com/embed/123456ABCDEF" frameborder="0" allowfullscreen=""></iframe>'
47
60
  assert_parsing_result src, src
48
61
  end
49
62
 
63
+ it 'removes youtube videos embedded from the with-cookies domain' do
64
+ src = '<iframe width="560" height="315" src="https://www.youtube.com/embed/123456ABCDEF" frameborder="0" allowfullscreen=""></iframe>'
65
+ assert_parsing_result src, ''
66
+ end
67
+
68
+ it 'does not allow embedding vimeo videos when their do-no-track param is set to something different than true' do
69
+ src = '<iframe src="https://player.vimeo.com/video/143343818?api=1&amp;dnt=foo&amp;title=foo" width="50" height="281" frameborder="0" webkitallowfullscreen="" mozallowfullscreen="" allowfullscreen=""></iframe>'
70
+ assert_parsing_result src, ''
71
+ end
72
+
73
+ it 'does not allow embedding vimeo videos when their do-no-track param is not passed' do
74
+ src = '<iframe src="https://player.vimeo.com/video/143343818?api=1&&amp;title=foo" width="50" height="281" frameborder="0" webkitallowfullscreen="" mozallowfullscreen="" allowfullscreen=""></iframe>'
75
+ assert_parsing_result src, ''
76
+ end
77
+
50
78
  it 'allows images' do
51
79
  src = '<p><img src="http://nav.heroku.com/images/logos/logo.png" alt="image"></p>'
52
80
  assert_parsing_result src, src
@@ -234,7 +262,7 @@ And that's it.
234
262
  more callout</p>
235
263
  </div>
236
264
 
237
- <p class="devcenter-parser-special-block-separator" style="display:none"> </p>
265
+ <p class="devcenter-parser-special-block-separator" style="display:none">&nbsp;</p>
238
266
 
239
267
  <blockquote>
240
268
  <p>normal</p>
@@ -263,7 +291,7 @@ more callout</p>
263
291
  <p>foo</p>
264
292
  </div>
265
293
 
266
- <p class="devcenter-parser-special-block-separator" style="display:none"> </p>
294
+ <p class="devcenter-parser-special-block-separator" style="display:none">&nbsp;</p>
267
295
 
268
296
  <div class="note">
269
297
  <p>bar</p>
@@ -282,14 +310,12 @@ more callout</p>
282
310
  MARKDOWN
283
311
 
284
312
  html = <<-HTML
285
- <table>
286
- <thead>
313
+ <table><thead>
287
314
  <tr>
288
315
  <th>A</th>
289
316
  <th>B</th>
290
317
  </tr>
291
- </thead>
292
- <tbody>
318
+ </thead><tbody>
293
319
  <tr>
294
320
  <td>1</td>
295
321
  <td>2</td>
@@ -298,8 +324,7 @@ more callout</p>
298
324
  <td>3</td>
299
325
  <td>4</td>
300
326
  </tr>
301
- </tbody>
302
- </table>
327
+ </tbody></table>
303
328
  HTML
304
329
 
305
330
  assert_parsing_result md, html
@@ -336,13 +361,21 @@ HTML
336
361
  end
337
362
 
338
363
  it 'converts relative links with missing initial slashes to article links' do
339
- ['foo', 'foo/bar', 'foo#bar', '123'].each do |href|
364
+ ['foo', 'foo/bar', 'foo#bar', '123', 'categories'].each do |href|
340
365
  md = "[link](#{href})"
341
366
  html = "<p><a href=\"/articles/#{href}\">link</a></p>"
342
367
  assert_parsing_result md, html
343
368
  end
344
369
  end
345
370
 
371
+ it 'ignores links with missing initial slashes IFF they start with `categories/`' do
372
+ ['categories/foo', 'categories/foo/bar', 'categories/foo#bar', 'categories/123'].each do |href|
373
+ md = "[link](#{href})"
374
+ html = "<p><a href=\"/#{href}\">link</a></p>"
375
+ assert_parsing_result md, html
376
+ end
377
+ end
378
+
346
379
  it 'converts "articles/foo relative links with missing initial slashes to article links' do
347
380
  md = '[link](articles/foo)'
348
381
  html = '<p><a href="/articles/foo">link</a></p>'
@@ -353,6 +386,14 @@ HTML
353
386
  assert_parsing_result md, html
354
387
  end
355
388
 
389
+ it 'adds a link prefix from options for relative dev center links' do
390
+ md = '[link](foo)'
391
+ expected = '<p><a href="/ja/articles/foo">link</a></p>'
392
+
393
+ result = DevcenterParser.to_html(md, { link_prefix: '/ja/articles' })
394
+ assert_equal expected.strip, result.strip, "Failed when parsing\n#{md}\n.\n\nExpected:\n#{expected}\n\nActual result:\n#{result}\n\n"
395
+ end
396
+
356
397
  it 'does not alter relative links with initial slashes nor absolute links nor anchor links to the same doc' do
357
398
  ['http://foo.com', 'https://foo.com', '/foo', '/foo/bar', '/foo#bar', '#foo', '/123', 'mailto:foo@foobar.com'].each do |href|
358
399
  md = "[link](#{href})"
@@ -380,7 +421,7 @@ HTML
380
421
  <p>foo</p>
381
422
  </blockquote>
382
423
 
383
- <p class="devcenter-parser-special-block-separator" style="display:none"> </p>
424
+ <p class="devcenter-parser-special-block-separator" style="display:none">&nbsp;</p>
384
425
 
385
426
  <blockquote>
386
427
  <p>bar</p>
@@ -13,6 +13,12 @@ describe 'HeaderIdGeneratorTest' do
13
13
  assert_id result(html), 'h2', 'foo-bar-header-123'
14
14
  end
15
15
 
16
+ it 'does not replace existing ids' do
17
+ html = '<h2 id="foo">Foo Bar</h2><p>Content</p><h3>Baz</h3>'
18
+ assert_id result(html), 'h2', 'foo'
19
+ assert_id result(html), 'h3', 'baz'
20
+ end
21
+
16
22
  it 'generates ids replacing inner non-alphanum chars with dashes' do
17
23
  ['Foo Bar', 'Foo-Bar', 'Foo#bar', 'Foo##Bar', 'Foo##Bar', '-$Foo##Bar$-'].each do |title|
18
24
  html = "<h2>#{title}</h2>"
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: devcenter-parser
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.2.5
4
+ version: 2.2.11
5
5
  platform: ruby
6
6
  authors:
7
7
  - Heroku
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-10-31 00:00:00.000000000 Z
11
+ date: 2020-12-01 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: nokogiri
@@ -30,28 +30,28 @@ dependencies:
30
30
  requirements:
31
31
  - - '='
32
32
  - !ruby/object:Gem::Version
33
- version: 3.3.4
33
+ version: 3.5.0
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: 3.3.4
40
+ version: 3.5.0
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: sanitize
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
45
  - - "~>"
46
46
  - !ruby/object:Gem::Version
47
- version: 4.6.3
47
+ version: 5.2.1
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: 4.6.3
54
+ version: 5.2.1
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: minitest
57
57
  requirement: !ruby/object:Gem::Requirement
@@ -103,7 +103,7 @@ files:
103
103
  homepage: https://devcenter.heroku.com
104
104
  licenses: []
105
105
  metadata: {}
106
- post_install_message:
106
+ post_install_message:
107
107
  rdoc_options: []
108
108
  require_paths:
109
109
  - lib
@@ -118,9 +118,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
118
118
  - !ruby/object:Gem::Version
119
119
  version: '0'
120
120
  requirements: []
121
- rubyforge_project:
122
- rubygems_version: 2.7.7
123
- signing_key:
121
+ rubygems_version: 3.1.4
122
+ signing_key:
124
123
  specification_version: 4
125
124
  summary: Parser for Heroku Dev Center's content
126
125
  test_files: