Class: BitClust::MarkdownTree
Overview
新パイプラインのファイル発見(MARKUP_SPEC §1.1)。
md ツリー(manual/api/**/*.md 相当)を glob し、各ファイルの front matter と エンティティ H1 から次の3種に分類する。旧 LIBRARIES マニフェストと grouping 用 #@include は使わない。
- エンティティ: エンティティ H1 を1つ以上持つ(front matter の library が所属)
- ライブラリ: type: library を持つ(名前 = パスから .md を除いたもの)
- 共有断片: どちらでもなく、いずれかの #@include から参照される
検証(ビルド警告に相当):
- 孤児: どの分類にも入らないファイル(H1 の書き忘れ・参照されない断片の検出)
- library の無いエンティティ / 未知の library を指すエンティティ
- 関係リント: include/extend/alias の記述場所は front matter のみ。 マルチエンティティファイルの front matter 関係キーと、 本文の H1 直後の関係行(ファイル種を問わず)を警告する
- #@include 先の欠損
Constant Summary collapse
- ENTITY_H1_RE =
/\A#(?!#)\s*(class|module|object|reopen|redefine)\s+(\S+)/- RELATION_LINE_RE =
/\A(?:include|extend|alias)\s+\S/- RELATION_KEY_RE =
/\A(?:include|extend|alias):\s*\z/- INCLUDE_RE =
/\A\#[@%]include\s*\((.*?)\)/- FENCE_RE =
/\A`{3,}/- BLANK_RE =
/\A\s*\z/
Instance Attribute Summary collapse
-
#entities ⇒ Object
readonly
Returns the value of attribute entities.
-
#fragments ⇒ Object
readonly
Returns the value of attribute fragments.
-
#libraries ⇒ Object
readonly
Returns the value of attribute libraries.
-
#warnings ⇒ Object
readonly
Returns the value of attribute warnings.
Class Method Summary collapse
Instance Method Summary collapse
-
#initialize(root) ⇒ MarkdownTree
constructor
A new instance of MarkdownTree.
- #scan ⇒ Object
Constructor Details
#initialize(root) ⇒ MarkdownTree
Returns a new instance of MarkdownTree.
34 35 36 37 38 39 40 |
# File 'lib/bitclust/markdown_tree.rb', line 34 def initialize(root) @root = root @libraries = {} # name => { path: } @entities = {} # path => { names:, library: } @fragments = [] @warnings = [] end |
Instance Attribute Details
#entities ⇒ Object (readonly)
Returns the value of attribute entities.
32 33 34 |
# File 'lib/bitclust/markdown_tree.rb', line 32 def entities @entities end |
#fragments ⇒ Object (readonly)
Returns the value of attribute fragments.
32 33 34 |
# File 'lib/bitclust/markdown_tree.rb', line 32 def fragments @fragments end |
#libraries ⇒ Object (readonly)
Returns the value of attribute libraries.
32 33 34 |
# File 'lib/bitclust/markdown_tree.rb', line 32 def libraries @libraries end |
#warnings ⇒ Object (readonly)
Returns the value of attribute warnings.
32 33 34 |
# File 'lib/bitclust/markdown_tree.rb', line 32 def warnings @warnings end |
Class Method Details
Instance Method Details
#scan ⇒ Object
42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 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 |
# File 'lib/bitclust/markdown_tree.rb', line 42 def scan files = Dir.glob('**/*.md', base: @root).sort warn_case_collisions(files) infos = files.to_h { |f| [f, parse_file(f)] } referenced = {} #: Hash[String, bool] infos.each do |path, info| info[:includes].each do |target| if (resolved = resolve(path, target, infos)) referenced[resolved] = true else @warnings << "include target not found: #{target} (from #{path})" end end end infos.each do |path, info| if info[:library_file] # 名前は原則パス由来。ファイル名衝突回避で改名されたファイル # (rdoc/rdoc.lib.md)は front matter の name: が正 @libraries[info[:name] || path.sub(/\.md\z/, '')] = { path: path, since: info[:since], until: info[:until] } end # include 参照され front matter を持たないファイルは、H1 を含んでいても # 断片(transclusion 用。fiddle の版分岐チェーン等) info[:fragment] = referenced[path] && !info[:library_file] && info[:library].nil? if info[:fragment] @fragments << path elsif !info[:kinds].empty? @entities[path] = { names: info[:kinds].map(&:last), kinds: info[:kinds], library: info[:library], memberships: info[:memberships], since: info[:since], until: info[:until] } elsif !info[:library_file] @warnings << "orphan file (no entity H1, no type: library, not included): #{path}" end end # 検証は全ライブラリの登録後に行う(辞書順で先に来るエンティティが # 未登録ライブラリを誤って「未知」と判定しないように) infos.each do |path, info| validate(path, info) unless info[:fragment] end self end |