Module: GitlabKramdown::Parser::Header

Included in:
Kramdown::Parser::GitlabKramdown
Defined in:
lib/gitlab_kramdown/parser/header.rb

Overview

Header with embedded link anchor

This parser implements header with additional a tag linking to own anchor For best results, some CSS styling can be used to emulate :hover behavior

Constant Summary collapse

HEADER_ID =
/(?:[ \t]+\{\#([A-Za-z][\w:-]*)\})?/
SETEXT_HEADER_START =
%r{
  ^(#{Kramdown::Parser::Kramdown::OPT_SPACE}[^ \t].*?)
    #{HEADER_ID}[ \t]*?\n
    (-|=)+\s*?\n
}x
ATX_HEADER_START =
/^\#{1,6}/
ATX_HEADER_MATCH =
/^(\#{1,6})(.+?(?:\\#)?)\s*?#*#{HEADER_ID}\s*?\n/
NON_WORD_RE =
/[^\p{Word}\- \t]/
/\[(?<link_text>[^\]]+)\]\((?<link_url>[^)]+)\)/

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.included(klass) ⇒ Object



19
20
21
22
# File 'lib/gitlab_kramdown/parser/header.rb', line 19

def self.included(klass)
  klass.define_parser(:setext_gitlab_header, SETEXT_HEADER_START)
  klass.define_parser(:atx_gitlab_header, ATX_HEADER_START)
end

Instance Method Details

#generate_header_id(text) ⇒ Object



78
79
80
81
82
83
84
85
# File 'lib/gitlab_kramdown/parser/header.rb', line 78

def generate_header_id(text)
  result = text.downcase
  result.gsub!(MARKDOWN_LINK_TEXT) { |s| MARKDOWN_LINK_TEXT.match(s)[:link_text].gsub(NON_WORD_RE, '') }
  result.gsub!(NON_WORD_RE, '')
  result.tr!(" \t", '-')
  @id_counter[result] += 1
  result << (@id_counter[result].positive? ? "-#{@id_counter[result]}" : '')
end

#parse_atx_gitlab_headerObject

Parse the Atx header at the current location.



51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
# File 'lib/gitlab_kramdown/parser/header.rb', line 51

def parse_atx_gitlab_header
  start_line_number = @src.current_line_number
  @src.check(ATX_HEADER_MATCH)
  level, text, id = @src[1], @src[2].to_s.strip, @src[3]
  return false if text.empty?

  @src.pos += @src.matched_size

  el = new_block_el(:header, nil, nil, level: level.length, raw_text: text, location: start_line_number)
  add_text(text, el)
  el.attr['id'] = id || generate_header_id(text)

  if @options[:linkable_headers]
    el.children << Kramdown::Element.new(:a, nil, {
      'href' => "##{el.attr['id']}",
      'title' => 'Permalink',
      'class' => 'anchor'
    }, location: start_line_number)
  end

  @tree.children << el
  true
end

#parse_setext_gitlab_headerObject

Parse the Setext header at the current location.



25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
# File 'lib/gitlab_kramdown/parser/header.rb', line 25

def parse_setext_gitlab_header
  start_line_number = @src.current_line_number
  @src.pos += @src.matched_size
  text, id, level = @src[1], @src[2], @src[3]
  text.strip!

  el = new_block_el(:header, nil, nil, level: (level == '-' ? 2 : 1), raw_text: text, location: start_line_number)
  add_text(text, el)
  el.attr['id'] = id || generate_header_id(text)

  if @options[:linkable_headers]
    el.children << Kramdown::Element.new(:a, nil, {
      'href' => "##{el.attr['id']}",
      'title' => 'Permalink',
      'class' => 'anchor'
    }, location: start_line_number)
  end

  @tree.children << el
  true
end