Module: VivlioStarter::CLI::Lint::NotationGuard
- Defined in:
- lib/vivlio_starter/cli/lint/notation_guard.rb
Overview
VFM 記法の中和(lint 系専用)。
Constant Summary collapse
- MACHINE_DATA_CONTAINERS =
機械データ(座標・オプション)を本文として持つコンテナ名。 記法を追加するときはここへ 1 語加えればガードが追従する。
%w[showcase].freeze
- MACHINE_BLOCK_OPEN =
機械データ・ブロックの開始行(例:
:::{.showcase})。 ShowcaseTransformer::BLOCK_PATTERN の開始側と揃える(行末に本文が続く:::{.showcase} fooは同 PATTERN が消費しない=ブロックではないため、 ガードもブロックとして扱わない)。 /\A:::\s*\{\s*\.(?:#{Regexp.union(MACHINE_DATA_CONTAINERS).source})\s*\}[ \t]*\r?\n?\z/- MACHINE_BLOCK_CLOSE =
機械データ・ブロックの終了行(例:
:::)。 /\A:::[ \t]*\r?\n?\z/- CONTAINER_MARKER =
コンテナのマーカー行(開始・終了とも)。コロン 3 つ以上+任意の属性ブレースで 行全体が構成されるものだけをマーカーとみなす。
「:::" で始まる行」まで広げてはならない: コメントアウトされたコンテナの閉じ
:::-->を空行化すると HTML コメントの-->が消え、コメントが永久に閉じず、 その中身(表・数式)を読んだ textlint が暴走する実害があった(94 章で CPU 99%)。 マーカーでないものはガードの対象外=素のまま textlint へ渡す(現状維持が正しい)。 /\A[ \t]*:{3,}[ \t]*(?:\{[^{}\n]*\})?[ \t]*\r?\n?\z/- FURIGANA =
ふりがな記法
{親文字|ふりがな}。 /\{([^{}|]*)\|[^{}]*\}/- CLASS_ATTRIBUTE =
クラス属性記法
{.classname}。 /\{\.[-\w]+\}/- MATH_PLACEHOLDER =
記法を中和したテキストを返す。行数は入力と必ず一致する(I1)。 数式の退避に使う目印。
--fixに触られず、textlint の指摘も生まないことを実測で選んだ (インラインコード化はspaceAroundCodeを誘発し、Xのような 1 文字は 全角と半角の間のスペース規則に触れる)。 'VSMATH'- MATH_PATTERNS =
数式の綴りは変換器と同じ定義を使う。ここで別に書くと、lint が守る範囲と ビルドが数式として扱う範囲がずれる。
[ PreProcessCommands::MathTransformer::DISPLAY_DOLLAR, PreProcessCommands::MathTransformer::DISPLAY_BRACKET, PreProcessCommands::MathTransformer::INLINE_DOLLAR, PreProcessCommands::MathTransformer::INLINE_PAREN ].freeze
Class Method Summary collapse
-
.blank_math(text) ⇒ Object
解析パス用: 数式を目印を残さず落とす。.
-
.mask_math(text) ⇒ Array(String, Hash)
数式を目印へ退避する。lint は数式を日本語の文として読むべきではない。.
-
.restore_math(text, spans) ⇒ Object
mask_math で退避した数式を戻す。.
- .strip_notation(text) ⇒ Object
Class Method Details
.blank_math(text) ⇒ Object
解析パス用: 数式を目印を残さず落とす。
mask_math の目印(VSMATH0)をそのまま残すと、スペルチェックが未知語として拾う
——Tokenizer.tokenize も記法判定を一本化するために strip_notation を通るため
(実測: VSMATH => smith が本書 21 章で 5 件)。解析パスは復元しないので、
目印を置く必要がない。行数は mask_math が足した改行で保たれる。
131 132 133 134 |
# File 'lib/vivlio_starter/cli/lint/notation_guard.rb', line 131 def blank_math(text) masked, spans = mask_math(text) spans.keys.reduce(masked) { |acc, key| acc.sub(key, '') } end |
.mask_math(text) ⇒ Array(String, Hash)
数式を目印へ退避する。lint は数式を日本語の文として読むべきではない。
放置すると、数式の中の半角括弧が prh に「全角にせよ」と指摘され、--fix が
当たれば $(1/2)πr³$ が $(1/2)πr³$ になって数式が壊れる(実測)。
コードスパンは textlint が Code ノードとして飛ばすのに、数式は素の文として
読まれるための穴で、素の表記を数式として組む機能が入って表面化した。
行数は保存する(I1)——複数行のディスプレイ数式は、落とした改行を目印の後ろへ足す。
102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 |
# File 'lib/vivlio_starter/cli/lint/notation_guard.rb', line 102 def mask_math(text) protected_text, code = Masking.protect_code(text) spans = {} masked = MATH_PATTERNS.reduce(protected_text) do |acc, pattern| acc.gsub(pattern) do original = ::Regexp.last_match(0) # **桁は固定幅にする。** `VSMATH1` は `VSMATH10` の頭に一致してしまい、 # 10 個以上の数式がある章で目印が食い違って残骸が出る(実測: 本書 92 章)。 key = format("%s%04d", MATH_PLACEHOLDER, spans.size) spans[key] = original "#{key}#{"\n" * original.count("\n")}" end end [Masking.restore_code(masked, code), spans] end |
.restore_math(text, spans) ⇒ Object
mask_math で退避した数式を戻す。
119 120 121 122 123 |
# File 'lib/vivlio_starter/cli/lint/notation_guard.rb', line 119 def restore_math(text, spans) spans.reduce(text) do |acc, (key, original)| acc.sub(/#{Regexp.escape(key)}\n{0,#{original.count("\n")}}/) { original } end end |
.strip_notation(text) ⇒ Object
136 137 138 139 140 141 142 143 144 145 146 147 148 |
# File 'lib/vivlio_starter/cli/lint/notation_guard.rb', line 136 def strip_notation(text) text = blank_math(text) prose = prose_lines(text) machine = machine_block_lines(text, prose) text.each_line.with_index(1).map do |line, lineno| if !prose.include?(lineno) then line # コード領域は不変 elsif machine.include?(lineno) then blank(line) # G1 機械データ・ブロック elsif line.match?(CONTAINER_MARKER) then blank(line) # G2 コンテナのマーカー行 else neutralize_inline(line) # G3 ふりがな → G4 クラス属性 end end.join end |