gitlab_kramdown 0.2.0 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|