Class: BitClust::MarkdownToRRD

Inherits:
Object
  • Object
show all
Defined in:
lib/bitclust/markdown_to_rrd.rb

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(markdown, capi: false) ⇒ MarkdownToRRD

capi: C API リファレンスモード。### は見出しではなくシグネチャ 「--- 」へ復元する(capi に本文見出しは無い)



121
122
123
124
# File 'lib/bitclust/markdown_to_rrd.rb', line 121

def initialize(markdown, capi: false)
  @src = markdown
  @capi = capi
end

Class Method Details

.convert(markdown, capi: false) ⇒ Object



7
8
9
# File 'lib/bitclust/markdown_to_rrd.rb', line 7

def self.convert(markdown, capi: false)
  new(markdown, capi: capi).convert
end

.restore_description(text) ⇒ Object

entry#description(meta description 等のコンパイラ非経由テキスト)と RefsDatabase のラベル用: インラインに加えて行頭構造 (見出し・@param 系・リスト記号・フェンス・エスケープ)も旧表示形へ戻す



34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
# File 'lib/bitclust/markdown_to_rrd.rb', line 34

def self.restore_description(text)
  trailing_newline = text.end_with?("\n")
  saved = [] #: Array[String]
  text = restore_display_fences(text, saved) if text =~ /^`{3,}/
  text = text.lines.map { |l| restore_display_line(l) }.join
  text = text.chomp unless trailing_newline
  # 行頭リスト記号の復元は **N.** 復元より先に行う(復元後の
  # 「N. 」を olist と誤認して (N) 化しないため。DublinCoreModel)
  restore_inline(
    text.gsub(/`(__\w+__)`/, '\1')
        .gsub(/(?<!\\)`([^`'\s]+)`/) { "`#{$1}'" }
        .gsub(/^(\s*)- /, '\1* ')
        .gsub(/^(\s*)(\d+)\. /, '\1(\2) ')
        .gsub(/^\*\*(\d+\.)\*\* /, '\1 ')
        .gsub(/^\\#/, '#')
        .gsub(/\\`/, '`')
  ).gsub(/\x00([-\w]+)\x00/) { "[a:#{$1}]" }
   .gsub(/\x01(\d+)\x01/) { saved[$1.to_i] }
end

.restore_display_fences(text, saved) ⇒ Object

description(段落単位の切り出し)内のフェンスを旧経路の表示形へ戻す: 4+ フェンス(インデントコード由来)→ インデントブロック、

段落分割で閉じフェンスが切れている形も受ける。
フェンス内容はコードなので、後段の行復元・インライン復元から
\x01<idx>\x01 プレースホルダで保護し最後に戻す


60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
# File 'lib/bitclust/markdown_to_rrd.rb', line 60

def self.restore_display_fences(text, saved)
  protect = lambda do |line, ends_nl|
    saved << line
    "\x01#{saved.size - 1}\x01#{ends_nl ? "\n" : ''}"
  end
  out = +''
  # len と indent(emlist 形は nil)
  fence = nil #: [Integer, Integer | nil]?
  text.each_line do |l|
    nl = l.end_with?("\n")
    if fence
      if l =~ /\A`{#{fence[0]}}\s*$/
        out << protect.call('//}', nl) unless fence[1]
        fence = nil
      elsif l =~ /\A\s*$/
        out << l
      elsif fence[1]
        out << protect.call((' ' * fence[1]) + l.chomp, nl)
      else
        out << protect.call(l.chomp, nl)
      end
    elsif l =~ /\A(`{4,})\s*$/
      len = ($1 || raise).length
      fence = [len, len - 3]
    elsif l =~ /\A(`{3,})(\w+)?(?:\s+title="((?:[^"\\]|\\.)*)")?\s*$/
      len = ($1 || raise).length
      lang = $2
      caption = $3&.gsub(/\\(["\\])/, '\1')
      open = lang ? "//emlist[#{caption}][#{lang}]{" : '//emlist{'
      out << protect.call(open, nl)
      fence = [len, nil]
    else
      out << l
    end
  end
  out
end

.restore_display_line(l) ⇒ Object

行頭構造(見出し・メタデータ行)の rd 表示形への復元。 全文変換(convert)の対応箇所と同じ規則の表示専用ミラー



100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
# File 'lib/bitclust/markdown_to_rrd.rb', line 100

def self.restore_display_line(l)
  case l
  when /\A(\#{1,6}) (.*?) \{#([-\w]+)\}([ \t]*\n?)\z/m
    # アンカーは restore_inline の裸参照復元([a:x]→[[a:x]])を
    # 避けるため \x00 で包み、最後に [a:x] へ戻す
    "#{'=' * ($1 || raise).length}\x00#{$3}\x00 #{$2}#{$4}"
  when /\A(\#{1,6}) (.*)\z/m
    "#{'=' * ($1 || raise).length} #{$2}"
  when /\A- \*\*(param|arg|raise)\*\*(\s+)`([^`]+)` --(.*)\z/m
    "@#{$1}#{$2}#{$3}#{$4}"
  when /\A- \*\*return\*\* --(.*)\z/m
    "@return#{$1}"
  when /\A- \*\*SEE\*\*(\s*)(.*)\z/m
    "@see#{$1}#{$2}"
  else
    l
  end
end

.restore_inline(text) ⇒ Object

md テキスト断片のインライン記法を rd 形式へ復元する ([type:target] → [[type:target]]、[ エスケープ解除)。 MDCompiler がテキストノードの処理を共有するための公開 API



14
15
16
# File 'lib/bitclust/markdown_to_rrd.rb', line 14

def self.restore_inline(text)
  new('').send(:convert_bare_refs, text)
end

.restore_text(text) ⇒ Object

md テキストノードを旧経路と同じ表示形(rd のインライン形式)へ戻す: __X__ 自動スパン解除、token → `token'(GNU 風引用)、 行頭 N. → N.、[x:y] → [[x:y]]。 MDCompiler の M1 等価描画(compile_text のテキストノード)用。 行頭構造は触らない(テキストノードの行頭 # や - は本文の一部)



23
24
25
26
27
28
29
# File 'lib/bitclust/markdown_to_rrd.rb', line 23

def self.restore_text(text)
  restore_inline(
    text.gsub(/`(__\w+__)`/, '\1')
        .gsub(/(?<!\\)`([^`'\s]+)`/) { "`#{$1}'" }
        .gsub(/^\*\*(\d+\.)\*\* /, '\1 ')
  )
end

Instance Method Details

#convertObject



126
127
128
129
130
131
132
133
134
135
# File 'lib/bitclust/markdown_to_rrd.rb', line 126

def convert
  @lines = @src.lines
  @out = []
  @index = 0
  @front_matter = {}

  parse_front_matter
  process_body
  @out.join
end