Module: VivlioStarter::CLI::Masking
- Defined in:
- lib/vivlio_starter/cli/masking.rb
Overview
Markdown のコード領域解釈の唯一実装。
Constant Summary collapse
- FENCE =
行頭フェンス(``` または ~~~ を 3 連以上)のマーカー。
/\A(?:`{3,}|~{3,})/- CODE_SPAN_PLACEHOLDER_PREFIX =
protect_code が用いるプレースホルダの接頭辞(既存 MarkdownUtils と互換)。
'__VS_CODE_SPAN__'- INLINE_CODE_SPAN =
インラインコードスパン(N 個の連続バッククォート同士の対)。 (?<!
) / (?!) で開き・閉じの両端が「ちょうど N 個のラン」であることを担保し、foo`barのように内部にバッククォートを含むケースも 1 スパンとして保護する。 /(?<!`)(`+)(?!`).+?(?<!`)\1(?!`)/m
Class Method Summary collapse
-
.each_prose_line(text) ⇒ Object
コード(フェンス区切り行・フェンス内容行)を除いた「地の文」の行だけを 行番号(1 始まり)つきで yield する。ブロック未指定なら Enumerator を返す。 行番号は入力テキスト全体に対する通し番号で、コード行を飛ばしても維持される。.
-
.protect_code(text) ⇒ Array(String, Hash)
コードフェンスブロックとインラインコードスパンを一時プレースホルダへ退避し、 後続のテキスト変形処理から除外できるようにする。 フェンス判定は状態機械へ統一(可変長・入れ子に追従)。.
-
.replace_top_level_fences(text) {|block, lineno| ... } ⇒ String
トップレベルのフェンスドコードブロック(開始区切り〜終了区切り)を 1 つずつ yield し、戻り値で置き換える。nil を返したブロックは原文のまま残す。 yield には開始フェンス行の行番号(1 始まり)も渡す——著者向け警告に 「ファイル:行」を添えるため(warning-messages の流儀)。.
-
.restore_code(text, spans) ⇒ Object
protect_code で退避したコードを元に戻す。 後から退避したインラインの原文が、先に退避したフェンスのプレースホルダを 内包しうる(行を跨ぐバッククォート対がフェンス置換後のプレースホルダを 巻き込むケース)。この入れ子を正しく巻き戻すため、挿入の逆順(LIFO / reverse_each)で外側→内側の順に開く。FIFO だと未復元のプレースホルダが残留する。.
-
.strip_code(text) ⇒ Object
フェンス・インラインコードを取り除いたテキストを返す。 フェンス(区切り行・内容行)は空行に置換して行数を保つため、周辺文脈の 行対応は崩れない。インラインコードは空白 1 文字へ潰す。.
-
.strip_inline_code(text) ⇒ Object
インラインコード
...を空白に置き換える。.
Class Method Details
.each_prose_line(text) ⇒ Object
コード(フェンス区切り行・フェンス内容行)を除いた「地の文」の行だけを 行番号(1 始まり)つきで yield する。ブロック未指定なら Enumerator を返す。 行番号は入力テキスト全体に対する通し番号で、コード行を飛ばしても維持される。
43 44 45 46 47 48 49 |
# File 'lib/vivlio_starter/cli/masking.rb', line 43 def each_prose_line(text) return enum_for(:each_prose_line, text) unless block_given? scan_lines(text) do |line, lineno, in_code| yield line, lineno unless in_code end end |
.protect_code(text) ⇒ Array(String, Hash)
コードフェンスブロックとインラインコードスパンを一時プレースホルダへ退避し、 後続のテキスト変形処理から除外できるようにする。 フェンス判定は状態機械へ統一(可変長・入れ子に追従)。
92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 |
# File 'lib/vivlio_starter/cli/masking.rb', line 92 def protect_code(text) spans = {} counter = 0 # 第 2 引数はフェンス経由でのみ渡る行番号(gsub 経由の呼び出しでは省略される) alloc = lambda do |chunk, _lineno = nil| key = "#{CODE_SPAN_PLACEHOLDER_PREFIX}#{counter}__" spans[key] = chunk counter += 1 key end # まずフェンスドコードブロック全体を退避(インラインコードより先に処理)。 protected_text = replace_fenced_blocks(text, &alloc) # 次にインラインコードスパンを退避。 protected_text = protected_text.gsub(INLINE_CODE_SPAN, &alloc) [protected_text, spans] end |
.replace_top_level_fences(text) {|block, lineno| ... } ⇒ String
トップレベルのフェンスドコードブロック(開始区切り〜終了区切り)を 1 つずつ yield し、戻り値で置き換える。nil を返したブロックは原文のまま残す。 yield には開始フェンス行の行番号(1 始まり)も渡す——著者向け警告に 「ファイル:行」を添えるため(warning-messages の流儀)。
コード保護(protect_code)より前段で特定言語のフェンスを横取りする変換 (例: ```mermaid の図化)のための公開 API。フェンス解釈(可変長・入れ子・
独自の再実装を作らせないための入り口でもある(P1「唯一の実装」)。
84 |
# File 'lib/vivlio_starter/cli/masking.rb', line 84 def replace_top_level_fences(text, &) = replace_fenced_blocks(text, &) |
.restore_code(text, spans) ⇒ Object
protect_code で退避したコードを元に戻す。 後から退避したインラインの原文が、先に退避したフェンスのプレースホルダを 内包しうる(行を跨ぐバッククォート対がフェンス置換後のプレースホルダを 巻き込むケース)。この入れ子を正しく巻き戻すため、挿入の逆順(LIFO / reverse_each)で外側→内側の順に開く。FIFO だと未復元のプレースホルダが残留する。
118 119 120 121 122 123 124 |
# File 'lib/vivlio_starter/cli/masking.rb', line 118 def restore_code(text, spans) restored = text.to_s spans.reverse_each do |placeholder, original| restored = restored.gsub(placeholder) { original } end restored end |
.strip_code(text) ⇒ Object
フェンス・インラインコードを取り除いたテキストを返す。 フェンス(区切り行・内容行)は空行に置換して行数を保つため、周辺文脈の 行対応は崩れない。インラインコードは空白 1 文字へ潰す。
56 57 58 59 60 61 62 |
# File 'lib/vivlio_starter/cli/masking.rb', line 56 def strip_code(text) stripped = +'' scan_lines(text) do |line, _lineno, in_code| stripped << (in_code ? "\n" : line) end strip_inline_code(stripped) end |
.strip_inline_code(text) ⇒ Object
インラインコード ... を空白に置き換える。
65 |
# File 'lib/vivlio_starter/cli/masking.rb', line 65 def strip_inline_code(text) = text.gsub(/`[^`\n]+`/, ' ') |