Module: VivlioStarter::CLI::Import::VerbatimRestorer
- Defined in:
- lib/vivlio_starter/cli/import/verbatim_restorer.rb
Overview
//output・//cmd の囲みの復元
Constant Summary collapse
- CODE_DIRECTIVES =
1 命令=1 フェンスを出す Re:VIEW の逐語系ブロック(出現順の照合に使う)
%w[list listnum emlist emlistnum source cmd output terminal].freeze
- WRAP_CLASSES =
囲み直す種別。list 系はソースコードなので素のフェンスのままでよい
{ 'output' => 'output', 'cmd' => 'terminal', 'terminal' => 'terminal' }.freeze
- DIRECTIVE_LINE =
%r{\A//([a-z]+)(?:\[|\{)}- FENCE_OPEN =
/\A(`{3,})\S/- REVIEW_COMMENT =
/\A\#@\#/
Class Method Summary collapse
-
.aligned?(names, fences, md_path) ⇒ Boolean
数が合わなければ当て推量をせず、章を丸ごと見送る.
-
.directive_names(re_lines) ⇒ Object
.re に現れた逐語系命令の名前を出現順に返す.
-
.fence_spans(lines) ⇒ Object
.md のフェンスを [開き行, 閉じ行] の並びで返す.
-
.restore!(temp_dir, starter_dir) ⇒ Object
temp/ の Markdown に対して逐語ブロックの囲みを復元する.
-
.restore_chapter!(md_path, re_path) ⇒ Object
1 章ぶんを復元し、復元できた件数を返す.
-
.wrap_fences!(lines, names, fences) ⇒ Object
行番号がずれないよう後ろから囲む.
Class Method Details
.aligned?(names, fences, md_path) ⇒ Boolean
数が合わなければ当て推量をせず、章を丸ごと見送る
101 102 103 104 105 106 107 108 109 110 |
# File 'lib/vivlio_starter/cli/import/verbatim_restorer.rb', line 101 def aligned?(names, fences, md_path) return true if names.size == fences.size Common.log_warn( " #{File.basename(md_path)}: 逐語ブロックの数が原稿と合わないため(原稿 #{names.size} / 変換後 #{fences.size})、" \ '実行結果の囲みを復元できませんでした。', detail: '対処: 実行結果のブロックを :::{.output} … ::: で囲んでください(22 章「実行結果」)。' ) false end |
.directive_names(re_lines) ⇒ Object
.re に現れた逐語系命令の名前を出現順に返す
71 72 73 74 75 76 77 78 |
# File 'lib/vivlio_starter/cli/import/verbatim_restorer.rb', line 71 def directive_names(re_lines) re_lines.filter_map do |line| next if REVIEW_COMMENT.match?(line) name = DIRECTIVE_LINE.match(line.to_s.chomp)&.[](1) name if CODE_DIRECTIVES.include?(name) end end |
.fence_spans(lines) ⇒ Object
.md のフェンスを [開き行, 閉じ行] の並びで返す
81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 |
# File 'lib/vivlio_starter/cli/import/verbatim_restorer.rb', line 81 def fence_spans(lines) spans = [] index = 0 while index < lines.size match = /\A(`{3,})/.match(lines[index].chomp) unless match index += 1 next end close = MarkdownConverter.closing_fence_index(lines, index + 1, match[1]) spans << [index, [close, lines.size - 1].min] index = close + 1 end spans end |
.restore!(temp_dir, starter_dir) ⇒ Object
temp/ の Markdown に対して逐語ブロックの囲みを復元する
44 45 46 47 48 49 50 51 52 53 54 |
# File 'lib/vivlio_starter/cli/import/verbatim_restorer.rb', line 44 def restore!(temp_dir, starter_dir) re_dir = SideimageRestorer.review_contents_dir(starter_dir) return unless Dir.exist?(re_dir) restored = Dir.glob(File.join(temp_dir, '*.md')).sum do |md_path| re_path = File.join(re_dir, "#{File.basename(md_path, '.md')}.re") File.exist?(re_path) ? restore_chapter!(md_path, re_path) : 0 end Common.log_info(" 実行結果・端末の囲みを #{restored} 件復元しました") if restored.positive? end |
.restore_chapter!(md_path, re_path) ⇒ Object
1 章ぶんを復元し、復元できた件数を返す
57 58 59 60 61 62 63 64 65 66 67 68 |
# File 'lib/vivlio_starter/cli/import/verbatim_restorer.rb', line 57 def restore_chapter!(md_path, re_path) names = directive_names(File.readlines(re_path, encoding: 'utf-8')) return 0 if names.none? { WRAP_CLASSES.key?(it) } lines = File.readlines(md_path, encoding: 'utf-8') fences = fence_spans(lines) return 0 unless aligned?(names, fences, md_path) wrap_fences!(lines, names, fences).tap do |count| File.write(md_path, lines.join, encoding: 'utf-8') if count.positive? end end |
.wrap_fences!(lines, names, fences) ⇒ Object
行番号がずれないよう後ろから囲む
113 114 115 116 117 118 119 120 121 122 |
# File 'lib/vivlio_starter/cli/import/verbatim_restorer.rb', line 113 def wrap_fences!(lines, names, fences) targets = names.each_with_index.filter_map { |name, i| [fences[i], WRAP_CLASSES[name]] if WRAP_CLASSES[name] } targets.reverse_each do |(open_index, close_index), klass| lines[close_index] = "#{lines[close_index].chomp}\n:::\n" lines.insert(open_index, ":::{.#{klass}}\n") end targets.size end |