-
Notifications
You must be signed in to change notification settings - Fork 218
Re:VIEW AST/Rendererアーキテクチャーの追加提案 #1956
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
takahashim
wants to merge
661
commits into
master
Choose a base branch
from
ast-renderer
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
f5c4486 to
f5d76dc
Compare
…n ListStructureNormalizer
…ution and indexing
… handling for unknown list types
…in ReferenceResolver
…in InlineProcessor
…nd add comparison test
18efe1b to
f3e4695
Compare
…plicate normalize_id methods
Collaborator
Author
|
このPRによるコミット済みの現行ファイルに対する変更は以下で、それ以外はすべて新規追加になります(なので既存機能への影響は最小限のはずです):
diff --git a/Gemfile b/Gemfile
index fce680bb..f22f26df 100644
--- a/Gemfile
+++ b/Gemfile
@@ -4,3 +4,10 @@ source 'https://rubygems.org'
# Specify your gem's dependencies in review.gemspec
gemspec
+
+# Development dependencies
+group :development do
+ # markly gem (for Markdown support) requires Ruby >= 3.1
+ # On Ruby 3.0, tests will be skipped but Re:VIEW will work with .re files
+ gem 'markly', '~> 0.13' if Gem.ruby_version >= Gem::Version.new('3.1.0')
+end
diff --git a/lib/review/book/book_unit.rb b/lib/review/book/book_unit.rb
index db3e93fb..357f7ecb 100644
--- a/lib/review/book/book_unit.rb
+++ b/lib/review/book/book_unit.rb
@@ -68,6 +68,22 @@ def generate_indexes(use_bib: false)
end
end
+ # Set indexes using AST-based indexing
+ def ast_indexes=(indexes)
+ @footnote_index = indexes[:footnote_index] if indexes[:footnote_index]
+ @endnote_index = indexes[:endnote_index] if indexes[:endnote_index]
+ @list_index = indexes[:list_index] if indexes[:list_index]
+ @table_index = indexes[:table_index] if indexes[:table_index]
+ @equation_index = indexes[:equation_index] if indexes[:equation_index]
+ @image_index = indexes[:image_index] if indexes[:image_index]
+ @icon_index = indexes[:icon_index] if indexes[:icon_index]
+ @numberless_image_index = indexes[:numberless_image_index] if indexes[:numberless_image_index]
+ @indepimage_index = indexes[:indepimage_index] if indexes[:indepimage_index]
+ @headline_index = indexes[:headline_index] if indexes[:headline_index]
+ @column_index = indexes[:column_index] if indexes[:column_index]
+ @book.bibpaper_index = indexes[:bibpaper_index] if @book.present? && indexes[:bibpaper_index]
+ end
+
def dirname
@path && File.dirname(@path)
end
diff --git a/lib/review/book/chapter.rb b/lib/review/book/chapter.rb
index 9f6a9d23..56128400 100644
--- a/lib/review/book/chapter.rb
+++ b/lib/review/book/chapter.rb
@@ -149,7 +149,9 @@ def on_postdef?
private
def on_file?(contents)
- contents.map(&:strip).include?("#{id}#{@book.ext}")
+ contents.map(&:strip).include?("#{id}#{@book.ext}") ||
+ contents.map(&:strip).include?("#{id}.re") ||
+ contents.map(&:strip).include?("#{id}.md")
end
# backward compatibility
diff --git a/lib/review/book/index/item.rb b/lib/review/book/index/item.rb
index 595a364a..c02f01ca 100644
--- a/lib/review/book/index/item.rb
+++ b/lib/review/book/index/item.rb
@@ -18,10 +18,11 @@ module ReVIEW
module Book
class Index
class Item
- def initialize(id, number, caption = nil)
+ def initialize(id, number, caption = nil, caption_node: nil)
@id = id
@number = number
@caption = caption
+ @caption_node = caption_node
@path = nil
@index = nil
end
@@ -29,6 +30,7 @@ def initialize(id, number, caption = nil)
attr_reader :id
attr_reader :number
attr_reader :caption
+ attr_accessor :caption_node
attr_accessor :index # internal use only
alias_method :content, :caption
diff --git a/lib/review/snapshot_location.rb b/lib/review/snapshot_location.rb
index 17eb22a3..e9d971ed 100644
--- a/lib/review/snapshot_location.rb
+++ b/lib/review/snapshot_location.rb
@@ -21,6 +21,21 @@ def string
"#{@filename}:#{@lineno}"
end
+ def to_h
+ {
+ filename: filename,
+ lineno: lineno
+ }
+ end
+
+ # Format location information for error messages
+ # Returns a string like " at line 42 in chapter01.re"
+ def format_for_error
+ info = " at line #{@lineno}"
+ info += " in #{@filename}" if @filename
+ info
+ end
+
alias_method :to_s, :string
def snapshot
diff --git a/lib/review/textutils.rb b/lib/review/textutils.rb
index 34904dfe..bb2bc045 100644
--- a/lib/review/textutils.rb
+++ b/lib/review/textutils.rb
@@ -10,6 +10,7 @@
#
require 'nkf'
require 'digest'
+require 'unicode/eaw'
module ReVIEW
module TextUtils
diff --git a/review.gemspec b/review.gemspec
index 31d6d451..c6b75c44 100644
--- a/review.gemspec
+++ b/review.gemspec
@@ -31,7 +31,9 @@ Gem::Specification.new do |gem|
gem.add_dependency('rubyzip')
gem.add_dependency('tty-logger')
gem.add_development_dependency('chunky_png')
+ gem.add_development_dependency('diff-lcs')
gem.add_development_dependency('math_ml')
+ gem.add_development_dependency('nokogiri')
gem.add_development_dependency('playwright-runner')
gem.add_development_dependency('pygments.rb')
gem.add_development_dependency('rake')
diff --git a/samples/debug-book/edge_cases_test.re b/samples/debug-book/edge_cases_test.re
index 15f69173..151468b2 100644
--- a/samples/debug-book/edge_cases_test.re
+++ b/samples/debug-book/edge_cases_test.re
@@ -277,6 +277,8 @@ class ValidationError extends Error {
対策として@<list>{empty_and_special_cases}で示したnullチェックが重要。
//}
+//blankline
+
== まとめ
このエッジケーステストでは以下を検証:
diff --git a/test/test_helper.rb b/test/test_helper.rb
index 7409904e..79f8becb 100644
--- a/test/test_helper.rb
+++ b/test/test_helper.rb
@@ -7,6 +7,8 @@
require 'review/yamlloader'
require 'review/extentions'
+require_relative 'ast/caption_parser_helper'
+
def touch_file(path)
FileUtils.touch(path)
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
概要
現行のRe:VIEWはそのままに、別途抽象構文木(AST)ベースのレンダリングアーキテクチャーを導入します。
これにより、従来のCompiler/Builderアーキテクチャから独立した処理フローが実現できます。
主な変更内容
AST/Rendererアーキテクチャの実装
BookやChapterはほぼ現行のものを使う形ですが、CompilerとBuilderは新たに作り直しました。
前者はAST::Compiler、後者はRendererになります。
lib/review/ast/compiler.rb): Re:VIEW構文を抽象構文木(AST)に変換lib/review/renderer/base.rb): 各出力形式に対応するRendererの基底クラスHtmlRenderer: HTML出力LatexRenderer: LaTeX/PDF出力IdgxmlRenderer: InDesign XML出力MarkdownRenderer: Markdown出力PlaintextRenderer: プレーンテキスト出力TopRenderer: TOP形式出力graph LR A[Re:VIEW文書] --> B[AST::Compiler] B --> C[AST] C --> D[HTMLRenderer] C --> E[LaTeXRenderer] C --> F[IDGXMLRenderer] C --> G[JSON出力] C --> H[カスタムツール] style C fill:#ccffcc新規コマンドラインツールの追加
review-ast-という共通prefixを使い、既存のコマンドとは干渉しないようにしています。review-ast-compile: AST経由での単一ファイルコンパイルreview-ast-pdfmaker: AST経由でのPDF生成review-ast-epubmaker: AST経由でのEPUB生成review-ast-idgxmlmaker: AST経由でのIDGXML生成review-ast-dump: AST構造のダンプ(デバッグ用)review-ast-dump2re: ASTからRe:VIEW形式への逆変換(デバッグ用)整理された実行プロセス
AST生成処理とASTは各Rendererには依存しない、フォーマット中立なデータ構造とプロセスになっています。
一方、各RendererもAST生成には直接関与せず、完成したASTに対しレンダリングを行うようにしています。
flowchart TB A[Re:VIEW文書] --> B[AST::Compiler] B --> C[AST構築] C --> D[参照解決] D --> E[後処理] E --> F[AST生成完了] F --> G[HTMLRenderer] F --> H[LaTeXRenderer] F --> I[IDGXMLRenderer] F --> J[JSONSerializer] G --> K[HTML出力] H --> L[LaTeX出力] I --> M[IDGXML出力] J --> N[JSON出力] subgraph "1. AST生成フェーズ" B C D E F end subgraph "2. レンダリングフェーズ" G H I J end参照解決システムの強化
参照解決はAST構築とは別に専用のフェーズを設けて解決します。
ReferenceResolver: コンパイル時の参照解決ResolvedData: 参照データ管理インデックス生成システム
ASTに対してインデックスを生成する、Builder/Compilerに依存しない独立したインデックス処理機構を導入しています。
AST::Indexer: 章レベルのインデックス生成AST::BookIndexer: 書籍全体のインデックス生成リスト処理・ブロック処理・テーブル処理機構
parse段階で複雑な処理が必要なリスト、ブロック、テーブルについて、通常のAST::Compilerとは別にAST::ListProcessor、AST::BlockProcessor、AST::BlockProcessor::TableProcessorを導入し、処理を委譲します。
Post-Processor機構
これまでは様々な場所で行われていた複数ノードが関わるような処理を、AST構築後にまとめて実行します。
そのために後処理専用ベースクラスAST::Compiler::PostProcessorを導入し、そのサブクラスとして各後処理機能を実装しています。
AutoIdProcessor: 自動ID生成NoindentProcessor: //noindent処理TsizeProcessor: テーブル幅指定処理OlnumProcessor: リスト開始番号処理FirstlinenumProcessor: コードブロック開始行番号処理ListStructureNormalizer: リスト構造の正規化Markdown入力サポート(experimental)
Re:VIEW記法のみではなく、Markdownで書かれたファイルも直接扱えるようになります。
catalog.ymlに
foo.md等と書けばMarkdownとして解釈されます。包括的なテストスイート
BuilderとRendererでの出力に差がないことを検証するため、専用の差分出力クラスReVIEW::AST::Diff::(Html|Latex|Idgxml)を導入し、出力が(ほぼ)同一であるかもテストしています。
ドキュメント整備
doc/ast.md: AST概要とAPIdoc/ast_architecture.md: アーキテクチャ設計doc/ast_node.md: ノード仕様doc/ast_list_processing.md: リスト処理詳細doc/ast_markdown.md: Markdownサポート詳細アーキテクチャ上の利点
後方互換性
review-compile,review-pdfmaker等の既存コマンドも変更は一切ありません。review-ast-*コマンドとして、新規に追加しています。テスト結果
関連