gitlab_kramdown 0.2.0 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.rubocop.yml +12 -3
- data/CHANGELOG.md +8 -0
- data/README.md +10 -1
- data/VERSION +1 -1
- data/gitlab_kramdown.gemspec +7 -3
- data/lib/gitlab_kramdown/parser/fenced_blockquote.rb +7 -6
- data/lib/gitlab_kramdown/parser/header.rb +82 -0
- data/lib/gitlab_kramdown/parser.rb +1 -0
- data/lib/kramdown/parser/gitlab_kramdown.rb +7 -1
- data/spec/fixtures/header.html +12 -0
- data/spec/fixtures/header.linkable_headers.html +12 -0
- data/spec/fixtures/header.text +14 -0
- data/spec/fixtures/multi_blockquote.html +2 -0
- data/spec/fixtures/multi_blockquote.text +2 -0
- data/spec/integration/parser_spec.rb +18 -1
- data/spec/support/fixtures.rb +2 -2
- metadata +6 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b1300ec014cee9ac392ba0934415585953a90c1d
|
4
|
+
data.tar.gz: 252c205835324990971e33f54a34e59bab01203e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e87efac88a9b5c980a67a8c6f74da59cf4b0bfa07d95d0b148ccc6db536380bc10f8a5a40c9bd3de860fa35a20aa850b7a0f9ed003a2ee39cd254971f9bc794e
|
7
|
+
data.tar.gz: aea0b96c06aaeba06ce712eb984b8ceb5eb754333ed321aef5ff1ef1c6372be97b406d5257a616e32be9adc6a29eb66207ad669c2e5f2b78b9cda1785a3cfde5
|
data/.rubocop.yml
CHANGED
@@ -6,14 +6,23 @@ AllCops:
|
|
6
6
|
- '*.gemspec'
|
7
7
|
Layout/IndentArray:
|
8
8
|
EnforcedStyle: consistent
|
9
|
+
Lint/InterpolationCheck:
|
10
|
+
Enabled: false
|
11
|
+
Metrics/BlockLength:
|
12
|
+
Exclude:
|
13
|
+
- 'spec/**/**'
|
9
14
|
Metrics/LineLength:
|
10
15
|
Max: 120
|
16
|
+
Metrics/MethodLength:
|
17
|
+
Enabled: false
|
18
|
+
Metrics/ModuleLength:
|
19
|
+
Enabled: false
|
20
|
+
Metrics/AbcSize:
|
21
|
+
Max: 30
|
11
22
|
Style/FrozenStringLiteralComment:
|
12
23
|
Exclude:
|
13
24
|
- 'spec/**/**'
|
14
25
|
Style/RegexpLiteral:
|
15
26
|
EnforcedStyle: mixed
|
16
|
-
|
17
|
-
Enabled: false
|
18
|
-
Metrics/ModuleLength:
|
27
|
+
Style/ParallelAssignment:
|
19
28
|
Enabled: false
|
data/CHANGELOG.md
CHANGED
@@ -6,6 +6,14 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
|
|
6
6
|
|
7
7
|
## [Unreleased]
|
8
8
|
|
9
|
+
## [0.3.0] - 2018-03-23
|
10
|
+
### Added
|
11
|
+
- Headers will include by default an anchor tag (you can disable with `linkable_headers: false`)
|
12
|
+
|
13
|
+
### Changed
|
14
|
+
- Fixed multiline blockquote delimiter
|
15
|
+
- GitLab URL is not customizable with `gitlab_url: 'http://yourcustomgitlab.com'`
|
16
|
+
|
9
17
|
## [0.2.0] - 2018-03-19
|
10
18
|
### Added
|
11
19
|
- Syntax highlighter uses ``` or ~~~
|
data/README.md
CHANGED
@@ -10,6 +10,7 @@ This is a list of GitLab Flavored Markdown (GFM) extensions and their status of
|
|
10
10
|
|---------------------------------|--------------|
|
11
11
|
| [Newlines] | No |
|
12
12
|
| [Multiple underscores in words] | _Kramdown_ |
|
13
|
+
| [Headers with Anchors] | **Yes** |
|
13
14
|
| [URL auto-linking] | No |
|
14
15
|
| [Multiline Blockquote] | **Yes** |
|
15
16
|
| [Code and Syntax Highlighting] | **Yes** |
|
@@ -23,7 +24,14 @@ This is a list of GitLab Flavored Markdown (GFM) extensions and their status of
|
|
23
24
|
| [Mermaid] | No |
|
24
25
|
|
25
26
|
> **Note**: Extensions marked as `Kramdown` in the `Implemented?` means behavior already exists
|
26
|
-
in Kramdown flavor.
|
27
|
+
in Kramdown flavor.
|
28
|
+
|
29
|
+
## Configuration parameters
|
30
|
+
|
31
|
+
| Parameter | Default | Description |
|
32
|
+
| :------------------| :------------------: | -------------------------------------------- |
|
33
|
+
| `gitlab_url` | `https://gitlab.com` | GitLab instance URL to build reference links |
|
34
|
+
| `linkable_headers` | true | Generate anchor tags with headers? |
|
27
35
|
|
28
36
|
## Usage example
|
29
37
|
|
@@ -76,6 +84,7 @@ further details.
|
|
76
84
|
[Kramdown]: https://kramdown.gettalong.org/
|
77
85
|
[Newlines]: https://docs.gitlab.com/ee/user/markdown.html#newlines
|
78
86
|
[Multiple underscores in words]: https://docs.gitlab.com/ee/user/markdown.html#multiple-underscores-in-words
|
87
|
+
[Headers with Anchors]: https://docs.gitlab.com/ee/user/markdown.html#headers
|
79
88
|
[URL auto-linking]: https://docs.gitlab.com/ee/user/markdown.html#url-auto-linking
|
80
89
|
[Multiline Blockquote]: https://docs.gitlab.com/ee/user/markdown.html#multiline-blockquote
|
81
90
|
[Code and Syntax Highlighting]: https://docs.gitlab.com/ee/user/markdown.html#code-and-syntax-highlighting
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.3.0
|
data/gitlab_kramdown.gemspec
CHANGED
@@ -2,16 +2,16 @@
|
|
2
2
|
# DO NOT EDIT THIS FILE DIRECTLY
|
3
3
|
# Instead, edit Juwelier::Tasks in Rakefile, and run 'rake gemspec'
|
4
4
|
# -*- encoding: utf-8 -*-
|
5
|
-
# stub: gitlab_kramdown 0.
|
5
|
+
# stub: gitlab_kramdown 0.3.0 ruby lib
|
6
6
|
|
7
7
|
Gem::Specification.new do |s|
|
8
8
|
s.name = "gitlab_kramdown".freeze
|
9
|
-
s.version = "0.
|
9
|
+
s.version = "0.3.0"
|
10
10
|
|
11
11
|
s.required_rubygems_version = Gem::Requirement.new(">= 0".freeze) if s.respond_to? :required_rubygems_version=
|
12
12
|
s.require_paths = ["lib".freeze]
|
13
13
|
s.authors = ["Gabriel Mazetto".freeze]
|
14
|
-
s.date = "2018-03-
|
14
|
+
s.date = "2018-03-23"
|
15
15
|
s.description = "GitLab Flavored Markdown extensions on top of Kramdown markup. Tries to be as close as possible to existing extensions.".freeze
|
16
16
|
s.email = "brodock@gmail.com".freeze
|
17
17
|
s.extra_rdoc_files = [
|
@@ -35,10 +35,14 @@ Gem::Specification.new do |s|
|
|
35
35
|
"lib/gitlab_kramdown/parser.rb",
|
36
36
|
"lib/gitlab_kramdown/parser/fenced_blockquote.rb",
|
37
37
|
"lib/gitlab_kramdown/parser/fenced_codeblock.rb",
|
38
|
+
"lib/gitlab_kramdown/parser/header.rb",
|
38
39
|
"lib/gitlab_kramdown/parser/reference.rb",
|
39
40
|
"lib/kramdown/parser/gitlab_kramdown.rb",
|
40
41
|
"spec/fixtures/code_highlight.html",
|
41
42
|
"spec/fixtures/code_highlight.text",
|
43
|
+
"spec/fixtures/header.html",
|
44
|
+
"spec/fixtures/header.linkable_headers.html",
|
45
|
+
"spec/fixtures/header.text",
|
42
46
|
"spec/fixtures/multi_blockquote.html",
|
43
47
|
"spec/fixtures/multi_blockquote.text",
|
44
48
|
"spec/fixtures/references.html",
|
@@ -11,13 +11,14 @@ module GitlabKramdown
|
|
11
11
|
FENCED_BLOCKQUOTE_START = />{3}/x
|
12
12
|
|
13
13
|
FENCED_BLOCKQUOTE_MATCH = %r{
|
14
|
-
^(?<delimiter>>{3})
|
15
|
-
\s*
|
16
|
-
\n
|
17
|
-
(?<content>[\S\s]+)
|
14
|
+
^(?<delimiter>>{3}) # line must start with >>>
|
15
|
+
\s* # any amount of trailling whitespace
|
16
|
+
\n # followed by a linebreak
|
17
|
+
(?<content>[\S\s]+) # at least one non whitespace chracter
|
18
18
|
\n
|
19
|
-
\k<delimiter>
|
20
|
-
\
|
19
|
+
\k<delimiter> # same delimiter used to open the block
|
20
|
+
[ \t]* # any amount of trailling whitespace
|
21
|
+
\s
|
21
22
|
}xm
|
22
23
|
|
23
24
|
def self.included(klass)
|
@@ -0,0 +1,82 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module GitlabKramdown
|
4
|
+
module Parser
|
5
|
+
# Header with embedded link anchor
|
6
|
+
#
|
7
|
+
# This parser implements header with additional a tag linking to own anchor
|
8
|
+
# For best results, some CSS styling can be used to emulate :hover behavior
|
9
|
+
#
|
10
|
+
# @see https://docs.gitlab.com/ee/user/markdown.html#headers
|
11
|
+
module Header
|
12
|
+
HEADER_ID = /(?:[ \t]+\{#([A-Za-z][\w:-]*)\})?/
|
13
|
+
SETEXT_HEADER_START = /^(#{Kramdown::Parser::Kramdown::OPT_SPACE}[^ \t].*?)#{HEADER_ID}[ \t]*?\n(-|=)+\s*?\n/
|
14
|
+
|
15
|
+
def self.included(klass)
|
16
|
+
klass.define_parser(:setext_gitlab_header, SETEXT_HEADER_START)
|
17
|
+
klass.define_parser(:atx_gitlab_header, ATX_HEADER_START)
|
18
|
+
end
|
19
|
+
|
20
|
+
# Parse the Setext header at the current location.
|
21
|
+
def parse_setext_gitlab_header
|
22
|
+
start_line_number = @src.current_line_number
|
23
|
+
@src.pos += @src.matched_size
|
24
|
+
text, id, level = @src[1], @src[2], @src[3]
|
25
|
+
text.strip!
|
26
|
+
|
27
|
+
el = new_block_el(:header, nil, nil, level: (level == '-' ? 2 : 1), raw_text: text, location: start_line_number)
|
28
|
+
add_text(text, el)
|
29
|
+
el.attr['id'] = id ? id : generate_header_id(text)
|
30
|
+
|
31
|
+
if @options[:linkable_headers]
|
32
|
+
el.children << Kramdown::Element.new(:a, nil, {
|
33
|
+
'href' => "##{el.attr['id']}",
|
34
|
+
'title' => 'Permalink',
|
35
|
+
'class' => 'anchor'
|
36
|
+
}, location: start_line_number)
|
37
|
+
end
|
38
|
+
|
39
|
+
@tree.children << el
|
40
|
+
true
|
41
|
+
end
|
42
|
+
|
43
|
+
ATX_HEADER_START = /^\#{1,6}/
|
44
|
+
ATX_HEADER_MATCH = /^(\#{1,6})(.+?(?:\\#)?)\s*?#*#{HEADER_ID}\s*?\n/
|
45
|
+
|
46
|
+
# Parse the Atx header at the current location.
|
47
|
+
def parse_atx_gitlab_header
|
48
|
+
start_line_number = @src.current_line_number
|
49
|
+
@src.check(ATX_HEADER_MATCH)
|
50
|
+
level, text, id = @src[1], @src[2].to_s.strip, @src[3]
|
51
|
+
return false if text.empty?
|
52
|
+
|
53
|
+
@src.pos += @src.matched_size
|
54
|
+
|
55
|
+
el = new_block_el(:header, nil, nil, level: level.length, raw_text: text, location: start_line_number)
|
56
|
+
add_text(text, el)
|
57
|
+
el.attr['id'] = id ? id : generate_header_id(text)
|
58
|
+
|
59
|
+
if @options[:linkable_headers]
|
60
|
+
el.children << Kramdown::Element.new(:a, nil, {
|
61
|
+
'href' => "##{el.attr['id']}",
|
62
|
+
'title' => 'Permalink',
|
63
|
+
'class' => 'anchor'
|
64
|
+
}, location: start_line_number)
|
65
|
+
end
|
66
|
+
|
67
|
+
@tree.children << el
|
68
|
+
true
|
69
|
+
end
|
70
|
+
|
71
|
+
NON_WORD_RE = /[^\p{Word}\- \t]/
|
72
|
+
|
73
|
+
def generate_header_id(text)
|
74
|
+
result = text.downcase
|
75
|
+
result.gsub!(NON_WORD_RE, '')
|
76
|
+
result.tr!(" \t", '-')
|
77
|
+
@id_counter[result] += 1
|
78
|
+
result << (@id_counter[result].positive? ? "-#{@id_counter[result]}" : '')
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
@@ -7,6 +7,7 @@ module GitlabKramdown
|
|
7
7
|
module Parser
|
8
8
|
autoload :FencedBlockquote, 'gitlab_kramdown/parser/fenced_blockquote'
|
9
9
|
autoload :FencedCodeblock, 'gitlab_kramdown/parser/fenced_codeblock'
|
10
|
+
autoload :Header, 'gitlab_kramdown/parser/header'
|
10
11
|
autoload :Reference, 'gitlab_kramdown/parser/reference'
|
11
12
|
end
|
12
13
|
end
|
@@ -11,15 +11,21 @@ module Kramdown
|
|
11
11
|
class GitlabKramdown < Kramdown::Parser::Kramdown
|
12
12
|
include ::GitlabKramdown::Parser::FencedBlockquote
|
13
13
|
include ::GitlabKramdown::Parser::FencedCodeblock
|
14
|
+
include ::GitlabKramdown::Parser::Header
|
14
15
|
include ::GitlabKramdown::Parser::Reference
|
15
16
|
|
16
17
|
def initialize(source, options)
|
17
18
|
super
|
18
19
|
|
19
|
-
@options[:gitlab_url]
|
20
|
+
@options[:gitlab_url] ||= 'https://gitlab.com'
|
21
|
+
@options[:linkable_headers] = true if @options[:linkable_headers].nil?
|
22
|
+
@id_counter = Hash.new(-1)
|
23
|
+
|
20
24
|
prepend_span_parsers(:commit_diff, :commit, :user_group_mention, :issue, :merge_request, :snippet, :label)
|
21
25
|
prepend_block_parsers(:fenced_blockquote)
|
22
26
|
replace_block_parser!(:codeblock_fenced, :codeblock_fenced_gitlab)
|
27
|
+
replace_block_parser!(:atx_header, :atx_gitlab_header)
|
28
|
+
replace_block_parser!(:setext_header, :setext_gitlab_header)
|
23
29
|
end
|
24
30
|
|
25
31
|
private
|
@@ -0,0 +1,12 @@
|
|
1
|
+
<h1 id="h1">H1</h1>
|
2
|
+
<h2 id="h2">H2</h2>
|
3
|
+
<h3 id="h3">H3</h3>
|
4
|
+
<h4 id="h4">H4</h4>
|
5
|
+
<h5 id="h5">H5</h5>
|
6
|
+
<h6 id="h6">H6</h6>
|
7
|
+
|
8
|
+
<p>Alternatively, for H1 and H2, an underline-ish style:</p>
|
9
|
+
|
10
|
+
<h1 id="alt-h1">Alt-H1</h1>
|
11
|
+
|
12
|
+
<h2 id="alt-h2">Alt-H2</h2>
|
@@ -0,0 +1,12 @@
|
|
1
|
+
<h1 id="h1">H1<a href="#h1" title="Permalink" class="anchor"></a></h1>
|
2
|
+
<h2 id="h2">H2<a href="#h2" title="Permalink" class="anchor"></a></h2>
|
3
|
+
<h3 id="h3">H3<a href="#h3" title="Permalink" class="anchor"></a></h3>
|
4
|
+
<h4 id="h4">H4<a href="#h4" title="Permalink" class="anchor"></a></h4>
|
5
|
+
<h5 id="h5">H5<a href="#h5" title="Permalink" class="anchor"></a></h5>
|
6
|
+
<h6 id="h6">H6<a href="#h6" title="Permalink" class="anchor"></a></h6>
|
7
|
+
|
8
|
+
<p>Alternatively, for H1 and H2, an underline-ish style:</p>
|
9
|
+
|
10
|
+
<h1 id="alt-h1">Alt-H1<a href="#alt-h1" title="Permalink" class="anchor"></a></h1>
|
11
|
+
|
12
|
+
<h2 id="alt-h2">Alt-H2<a href="#alt-h2" title="Permalink" class="anchor"></a></h2>
|
@@ -2,7 +2,7 @@ require 'spec_helper'
|
|
2
2
|
|
3
3
|
context 'GitLab Kramdown Integration tests' do
|
4
4
|
let(:options) do
|
5
|
-
{ input: 'GitlabKramdown' }
|
5
|
+
{ input: 'GitlabKramdown', linkable_headers: false }
|
6
6
|
end
|
7
7
|
|
8
8
|
context 'HTML render' do
|
@@ -15,5 +15,22 @@ context 'GitLab Kramdown Integration tests' do
|
|
15
15
|
expect(parser.to_html).to eq(target)
|
16
16
|
end
|
17
17
|
end
|
18
|
+
|
19
|
+
context 'linkable_headers enabled' do
|
20
|
+
let(:options) do
|
21
|
+
{ input: 'GitlabKramdown', linkable_headers: true }
|
22
|
+
end
|
23
|
+
|
24
|
+
it 'Renders header as headers.linkable_headers.html' do
|
25
|
+
text_file = File.join(Fixtures.fixtures_path, 'header.text')
|
26
|
+
html_file = File.join(Fixtures.fixtures_path, 'header.linkable_headers.html')
|
27
|
+
|
28
|
+
source = File.read(text_file)
|
29
|
+
target = File.read(html_file)
|
30
|
+
parser = Kramdown::Document.new(source, options)
|
31
|
+
|
32
|
+
expect(parser.to_html).to eq(target)
|
33
|
+
end
|
34
|
+
end
|
18
35
|
end
|
19
36
|
end
|
data/spec/support/fixtures.rb
CHANGED
@@ -2,14 +2,14 @@
|
|
2
2
|
|
3
3
|
module Fixtures
|
4
4
|
def self.text_files
|
5
|
-
Dir[File.join(
|
5
|
+
Dir[File.join(fixtures_path, '**/*.text')]
|
6
6
|
end
|
7
7
|
|
8
8
|
def self.html_file(text_file)
|
9
9
|
text_file.sub('.text', '.html')
|
10
10
|
end
|
11
11
|
|
12
|
-
def self.
|
12
|
+
def self.fixtures_path
|
13
13
|
File.expand_path(File.join(File.dirname(__FILE__), '../fixtures'))
|
14
14
|
end
|
15
15
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: gitlab_kramdown
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Gabriel Mazetto
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-03-
|
11
|
+
date: 2018-03-23 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: kramdown
|
@@ -147,10 +147,14 @@ files:
|
|
147
147
|
- lib/gitlab_kramdown/parser.rb
|
148
148
|
- lib/gitlab_kramdown/parser/fenced_blockquote.rb
|
149
149
|
- lib/gitlab_kramdown/parser/fenced_codeblock.rb
|
150
|
+
- lib/gitlab_kramdown/parser/header.rb
|
150
151
|
- lib/gitlab_kramdown/parser/reference.rb
|
151
152
|
- lib/kramdown/parser/gitlab_kramdown.rb
|
152
153
|
- spec/fixtures/code_highlight.html
|
153
154
|
- spec/fixtures/code_highlight.text
|
155
|
+
- spec/fixtures/header.html
|
156
|
+
- spec/fixtures/header.linkable_headers.html
|
157
|
+
- spec/fixtures/header.text
|
154
158
|
- spec/fixtures/multi_blockquote.html
|
155
159
|
- spec/fixtures/multi_blockquote.text
|
156
160
|
- spec/fixtures/references.html
|