GitLab Flavored Markdown(GLFM) 仕様ガイド
要約
- _GitLab_Flavored Markdown(GLFM) は_GitHub_Flavored Markdown (GFM)をベースにしており、CommonMarkをベースにしています。
- GLFMはMarkdown構文の2つの「セット」に分かれています:
- これらの構文はすべて、CommonMark仕様の構文に基づいた特別なMarkdownファイルによって指定されます。このファイルには、Markdownとそれに対応する生成されたHTMLの「例」と、それぞれの例を説明する関連文書が並んでいます。
- また、YAMLメタデータファイルもあり、個々のMarkdown/HTML例がどのように処理され、レンダリングされるべきかについての追加情報が含まれています。
- これらのMarkdown/YAMLファイルとそれらが含むコンテナは複数の目的を果たします:
- それらはGLFMがどのように表示されるべきかの「真実の源」です。
- GFMやCommonMark仕様がそうであるように、すべての例と関連文書を含むフォーマットされたHTML文書のレンダリングをサポートしています。
- 公式仕様に対する標準的な CommonMark適合性テストをサポートします。
- GitLab内部GLFM処理ロジックのスナップショットテストをサポートします。これは、GitLabアプリ内で自動テストを行うためのフィクスチャとして使用されるYAMLの“example snapshot files “を自動的に生成することで実現されます。
- 上記の目標を達成するために、様々なスクリプトとロジックがあります。
導入
GitLabは様々な場所でMarkdownをサポートしています。私たちが使っているMarkdownの方言はGitLab Flavored Markdown(GLFM) と呼ばれています。
GLFM方言の仕様はGitHub Flavored Markdown(GFM) 仕様に基づいています。GLFM仕様には、GFM仕様に比べて多くの追加事項があります。
このガイドは、GLFM仕様に関連するさまざまな用語や定義、目標、ツール、実装について説明する開発者向けのドキュメントです。GitLab Flavored Markdownのユーザー向けドキュメントをサポートし、補強することを目的としています。
用語と定義
略語GLFM、GHFM、GFM、コモンマーク
_GitHub_Flavored MarkdownはGFMという頭字語で広く呼ばれており、このドキュメントもそれに従います。_GitLab_Flavored MarkdownはGitHub Flavored Markdownと区別するために、このドキュメントではGLFMと呼びます。
残念ながら、この慣例は他のドキュメントやGitLabコードベースではまだ一貫して守られていません。多くの場所で、GFMという頭字語が_GitLab_Flavored Markdownを指すのに使われています。この矛盾を解決するためのオープンイシューが存在します。
コードの中には、ロジックの同じ領域で GitLab と GitHub の両方の仕様を同時に参照している場所があります。このような状況では、混乱を避けるために_GitHub_Flavored Markdownをghfm_
のような変数名や定数名で参照することがあります。例えば、ghfm_spec_v_0.29.md
GitHub Flavored Markdown 仕様ファイルはgitlab
リポジトリにコミットされ、update_specification.rb
スクリプトの入力として使用されますが、ghfm
の頭文字を使用しています。
オリジナルのCommonMark仕様は_CommonMark_(頭文字なし)と呼ばれています。
さまざまなMarkdown仕様
私たちが使用している仕様書フォーマットは、CommonMarkで使用されているアプローチに基づいています。spec.txt
ファイルは、ドキュメントとして機能するだけでなく、自動化された適合性テストの入力としても使用できるフォーマットになっています。これはCommonMark仕様で説明されています:
このドキュメントはMarkdown構文を明確に指定することを試みます。それはMarkdownとHTMLを並べた多くの例を含んでいます。これらの例は適合性テストを兼ねています。
仕様のHTMLレンダリング・バージョンはこちらです:
- GitLab Flavored Markdown(GLFM) 仕様を拡張したものです:
-
GitHub Flavored Markdown(GFM)仕様 ([GFM 仕様のソース
spec.txt
spec.txt
からのレンダリング): -
CommonMark仕様(レンダリング元:ソース
spec.txt
for CommonMark仕様)
しかし、GLFMはGFMやCommonMarkよりも複雑な解析、レンダリング、テストが必要です。そのため、静的でハードコードされ、手動で更新されるspec.txt
はありません。その代わり、GLFMspec.txt
は他の入力ファイルに基づいて自動的に生成されます。このプロセスについては、以下の実装のセクションで詳しく説明します。
spec.txt
と一致していません。このことを報告するためにspec.txt
cmark-gfm
プロジェクトでspec.txt
イシューが提出されています。公式仕様と内部拡張の比較
GitHubのGFMとGitLabのGLFMには、サポートするMarkdownの「セット」が2つあります:
- 公式仕様
- 内部拡張
以下のChartは、様々な仕様の分類と用語を示しています:
公式仕様
GFMとGLFMは、それぞれ公式仕様書を定めています:
- コモンマーク規格
- CommonMark 規格の汎用拡張。
例えば、GFM はstrikethrough
拡張を追加し、GLFM はcolor chips
拡張 を追加します。公式仕様のこれらの拡張機能は、特定の実装や環境に依存しません。これらはサードパーティのMarkdownレンダリング・エンジンで実装することができます。
内部拡張
GFMとGLFMはそれぞれ内部拡張機能を持っています。これらの拡張はGFMやGLFMの公式仕様の一部ではなく、GitHubやGitLab内部のMarkdownレンダラーやパーサーの実装の一部です。これらの内部拡張は、GitHubやGitLabの実装や環境に依存していることが多く、それらの環境との相互作用によってのみ利用可能なメタデータに依存していることがあります。例えば、GitHubはGitHub固有の自動リンク参照をサポートしており、GitLabもGitLab固有の参照をサポートしています。これらはGitHubやGitLabとインテグレーションするサードパーティのMarkdownレンダリングエンジンによって実装されることもあります。例えば、エディタやIDEのプラグインで、ユーザーはエディタやIDE内でイシュー、プルリクエスト、マージリクエストのMarkdownを直接編集することができます。
Markdownの例
仕様とこのガイドの文脈のあらゆるところで、_例という_用語は、標準的なCommonMark仕様フォーマットにおける様々なMarkdownソース文字列の正規パース(またはレンダリング)動作を説明するために、バックティックで区切られたMarkdown + HTMLペアを使用する慣習を指すために特別に使用されています。
この文脈では、RSpecのexampleのような_exampleの_他の類似または関連する意味と混同しないでください。
バックティックで区切られたMarkdown+HTMLのexample構文の詳細については、glfm_official_specification.md
ファイルのセクションを参照してください。
パーサーとレンダラー
仕様が使用されるさまざまな方法を理解し、指定されたMarkdown方言にどのように関連するかを理解するためには、パーサーと _レンダ_ラーの区別を理解することが重要です:
- Markdown_パーサーは_入力としてMarkdownを受け入れ、出力としてMarkdown Abstract Syntax Tree(AST) を生成します。
- Markdown_レンダラーは_パーサーによって生成されたASTを受け入れ、出力としてHTML(またはPDF、またはその他の関連するレンダリングフォーマット)を生成します。
GLFM仕様によって駆動されるMarkdownテストのタイプ
自動テストの2つの主なタイプは、GLFM仕様に含まれるMarkdownの例とデータによって駆動されます。私たちはそれらをこう呼びます:
- Markdown適合性テスト。
- Markdownスナップショットテスト。
GitLab のコードベースには他にも多くの種類のテストがあり、その中には GLFM Markdown 方言に関連するものもあります。そのため、混乱を避けるために、この文書や他の場所で言及されている二種類の仕様駆動型テストにはこれらの標準的な用語を使います。
Markdown適合性テスト
Markdown適合性テストは、特定の実装がCommonMark Markdown仕様に適合していることを検証するために、すべてのCommonMark Markdown方言で使用される標準的なテスト方法を指します。仕様自体に記述されているように、与えられたspec.txt
仕様と実装に対して標準的なCommonMarkツールspec_tests.py
を実行することによって実施されます。
適合性テストはGLFM公式仕様の 例に対してのみ_実行され、内部拡張の例に対しては実行さ_れません。これは、内部拡張例はGitLab環境やメタデータに依存している可能性がありますが、標準的なCommonMark適合性テストツールはこれをサポートしていないからです。
spec_tests.py
Python に依存しないように、最終的には Ruby で再実装されるかもしれません。Markdownスナップショットテスト
_Markdownスナップショットテストは_GitLabコードベースで実行される自動テストのことで、GLFM仕様のすべての例から得られたexample_snapshots
フィクスチャデータによって駆動されます。バックエンドのRSpecテストと、フィクスチャデータを使うフロントエンドのJestテストの両方で構成されています。このフィクスチャデータは YAML ファイルにコンテナされています。これらのファイルは仕様の中のMarkdownの例と、既存のGLFMパーサーとレンダリングの実装に基づいて生成され、更新されます。また、不完全な実装をテストドライブするために、必要に応じて手動で更新されることもあります。
スナップショットテストは包括的であることを意図しているので、GLFM公式仕様と 内部拡張の例の両方、_すべての_例に対して実行されます。つまり、glfm_example_metadata.yml
のような内部拡張例で必要とされる GitLab 固有の環境やメタデータを提供するための設定ファイルを使います。
スナップショットテストの設計は、ユーザー向けのGLFM Markdownの正しさを保証するのに役立ちます。このテストでは、ブラックボックステストのアプローチを使って、バックエンドとフロントエンドのパーサーとレンダラーを徹底的に調べます。この包括的なスタイルにより、「テストピラミッドの頂点」に位置する高レベルテストの一種と考えることができます。
Markdownスナップショットテストに使用される用語について:
- Markdownスナップショットテストは、承認テストまたは特性テストとも呼ばれるゴールデンマスターテストアプローチの一形態と考えることができます。
- ゴールデンマスターという用語はもともとレコーディング業界に由来し、マスタリングのプロセス、つまり、他のすべてのコピーが作成される最終的なミックスを作成することを指します。
- より詳しい情報と背景については、キャラクタライゼーション・テストと ゴールデン・マスターをお読みください。
- _スナップショットという_言葉の使い方は、GitLabのフロントエンドテストスイートで使われているようなJestスナップショットテストのアプローチを指すものではありません。しかし、Markdown のスナップショットテストは Jest のスナップショットテストと同じ考え方とパターンに従います:
- スナップショットの例のフィクスチャデータは、ソースコントロールにチェックされるファイルとして表されます。
- ファイルは自動的に生成され、テスト対象のコードの実装に基づいて更新されます。
- また、不完全な実装やバグのある実装の変更をテストするためなど、 必要に応じてファイルを手動で更新することもできます。
- _フィクスチャという_用語の用法は、標準的なRailsデータベースのフィクスチャファイルを指すものではありません。代わりに、自動テストをサポートする入力データとして、より一般的な定義の _テストフィクスチャを_指します。
- これらのスナップショット例のフィクスチャファイルは、GLFM仕様の残りの部分から生成され、密接に関連しています。そのため、
example_snapshots
ディレクトリは、glfm_specification
ディレクトリの下に、残りのGLFM仕様ファイルと一緒に配置されています。これらは意図的に_、_GitLab Railsアプリケーションのフィクスチャデータの残りと一緒にspec/fixtures
。実際には、開発者はこれらのファイルをspec/fixtures
ディレクトリに分割するよりも、glfm_specification
ディレクトリの下にすべてを配置する方がシンプルでわかりやすいと考えています。
以下の正規化のセクションもご覧ください。これはMarkdownスナップショットテストで使用される重要な概念です。
構文解析とレンダリング
GitLabアプリケーションで使われているMarkdown方言には、レンダリングに二重の要件があります:
- 静的な読み取り専用のHTMLフォーマットへのレンダリング。
- What You See Is What You Get”(WYSIWYG)エディタであるリッチテキストエディタでの編集可能なコンテンツのレンダリング。リッチテキストエディタは、編集可能なMarkdownソースと編集可能なWYSIWYGドキュメント間のリアルタイムの即時切り替えをサポートします。
これらの要件は、GitLabが2つの独立したパーサーとレンダラーの実装を持っていることを意味します:
- バックエンドのパーサー/レンダラーは、_静的な_読み取り専用HTMLのパースとレンダリングをサポートします。Rubyで実装されています。これは
libcmark-gfm
の Ruby ラッパーであるcommonmarker
gem を活用しています。libcmark-gfm
はCommonMarkの C リファレンス実装の拡張バージョンです。 - フロントエンドのパーサー/レンダラーは、リッチテキストエディタの解析と_WYSIWYG_レンダリングをサポートします。JavaScriptで実装されています。パーシングはRemarkMarkdownパーサーに基づいており、MDAST Abstract Syntax Tree(MDAST)を生成します。レンダリングはMDASTをProseMirrorドキュメントに変換するプロセスです。そして、ProseMirrorはProseMirrorドキュメントをWYSIWYG HTMLにレンダリングするために使用されます。このドキュメントでは、MarkdownをMDASTに変換するプロセスを_フロントエンド/JavaScriptパーサーと_呼び、ProseMirrorでMarkdownをWYSIWYG HTMLにレンダリングするプロセス全体を_リッチテキストエディタと_呼びます。独立したフロントエンドパーサー/レンダラー実装の必要性には、以下のような要件があります:
- バックエンドで使用されるHTMLレンダラー実装に、正確なソース マッピングに必要なサポートがないこと。
- 待ち時間と帯域幅に関する懸念: ユーザーがMarkdownソースとWYSIWYGドキュメントを切り替えるたびに、バックエンドへのラウンドトリップが不要になります。
- WYSIWYGドキュメントに対するさまざまなHTMLおよびブラウザのレンダリング要件。たとえば、ダイアグラムや参照などの読み取り専用の要素を編集可能な形で表示することなど。
レンダリングされたHTMLの複数のバージョン
これらのGLFMレンダラー実装(静的およびWYSIWYG)はどちらも、GLFMの標準的なHTML例とは異なるHTMLを生成します。 公式仕様のHTML例とは異なる可能性があります。したがって、GLFM仕様のすべてのMarkdownの例に対して、3つのバージョンのHTMLがその例からレンダリングされる可能性があります:
- 静的HTML
- WYSIWYG HTML
- 正規のHTML
静的HTML
静的HTMLはバックエンド(Ruby)のレンダラーによって生成されるHTMLで、余分なスタイリングや動作HTMLを含んでいます。例えば、タスクリストの項目から動的にイシューを作成するために追加されたタスク作成ボタンなどです。GitLabMarkdown APIはこのメソッドを使って、与えられた Markdown 文字列に対して HTML を生成します。
Markdownの例で指定されたMarkdownは、update-example-snapshots.rb
を介してglfm_specification/output_example_snapshots/html.yml
で自動的にHTMLを生成するために使われます。これらの例は、Markdownスナップショットテストを実行するときに使われます。
WYSIWYG HTML
WYSIWYG HTMLは、フロントエンド(JavaScript)のリッチテキストエディタによって生成されるHTMLで、解析とレンダリングのロジックを含みます。ProseMirror WYSIWYGエディタで編集可能なドキュメントを表示するために使用されます。
静的HTMLと同様に、Markdownの例で指定されたMarkdownは、update-example-snapshots.rb
を介して、glfm_specification/output_example_snapshots/html.yml
のHTMLを自動的に生成するために使用されます。これらの例は、Markdownスナップショットテストを実行する際に使用されます。
正規のHTML
Canonical HTMLはMarkdownからレンダリングされるHTMLのクリーンで基本的なバージョンで、スタイルやその他の実装特有の動作に関連する不要なクラスや要素はありません。
その目的はGLFMspec.txt
に対するMarkdownの適合性テストをサポートすることです。
常にハードコードされ、手動で管理され、HTMLが自動的に生成されることはありません。HTMLを指定するMarkdownの例は、どのMarkdown仕様に由来するかによって、異なるファイルにコンテナされています。
カノニカルHTMLは 常に指定されていますCommonMark,GFM, andGLFM 公式仕様のすべてのMarkdownの例で指定されています。
しかし 指定されることはありませんGLFM内部拡張については、Markdownの例では指定されていません。これは内部拡張がMarkdownの適合性テストでテストされることがないからです。そのため、内部拡張の例のcanonical HTMLは、スクリプトや自動化されたテストで使われることはありません。
以下はcanonical HTMLサンプルのソースについての詳細です:
- CommonMark仕様とGFM拡張仕様の一部である例については、正準HTMLはGFM
spec.txt
Markdown例ブロックにあるものと全く同じHTMLです。これらの例はGFMspec.txt
からGLFM版spec.txt
にそのままコピーされています。 - GLFMの一部である例については 公式仕様GLFM公式仕様の一部である例については、
glfm_official_specification.md
の入力仕様ファイルに含まれる例によって、標準的なHTMLが手動でメンテナーされ、管理されています。 - GLFM 内部拡張GLFM内部拡張の一部である例では、標準的なHTMLは決して指定されず、
glfm_internal_extensions.md
入力仕様ファイルに含まれるすべての例で空のままでなければなりません。
HTMLの正規化
バックエンド(Ruby)およびフロントエンド(JavaScript)レンダラーからレンダリングされた静的 HTMLおよびWYSIWYG HTMLには、通常、特定の外観要件や動作要件をサポートするために、余分なスタイリングや HTML 要素が含まれています。
バックエンドもフロントエンドのレンダリングロジックも、GLFM公式仕様例の Markdown適合性テストを実行する際に正規HTMLとの比較を行うために必要な、クリーンで基本的なHTMLを直接レンダリングすることはできません。
なぜなら
- GitLabアプリケーションの機能をサポートするための直接的な要件ではないからです。
- この機能を追加すると、実装に不必要な要件や複雑さが加わります。
代わりに、レンダリングされた静的HTMLやWYSIWYG HTMLは、_正規化_処理によって正規HTMLに変換されます。このプロセスは、静的HTMLやWYSIWYG HTMLから余分なスタイルや動作のHTMLをすべて取り除くことができ、その結果、標準spec.txt
仕様にある正規化HTMLの例と正確に一致する正規化HTMLになります。
この処理にはcanonicalize-html.rb
スクリプト を使ってください。
正規化
レンダリングされた HTML と ProseMirror JSON のバージョンは、さまざまな理由で異なることがあります。スタイリングや HTML 構造の違いだけでなく、属性やノードの値もテスト実行や環境によって異なる場合があります。たとえば、次のようになります:
- データベースのレコード識別子
- 名前空間またはプロジェクトの識別子
- URIの一部
- ファイルパスまたはファイル名
- ランダム値
Markdownスナップショットテストが適切に動作するためには、テストの信頼性を確保し、異なるテスト実行や環境間で常に同じ動作をするように、これらの違いを考慮する必要があります。
これらの違いを考慮するために、次のようなプロセスがあります。 正規化.正規化にはいくつかの方法があります:
- フィクスチャベースの正規化
- 環境変数ベースの正規化
- 正規表現ベースの正規化
フィクスチャベースの正規化
正規表現に基づく正規化よりもシンプルで理解しやすいので、可能な限りフィクスチャに基づく正規化を使うべきです。
Markdownスナップショットテストでは、スナップショットファイルの例を生成するためにRSpecを使用します。RSpecでは以下のことが可能です:
- GitLab RSpecスイートの他の部分と同じ強力なフィクスチャサポートとヘルパーを使用します。
- サンプルのスナップショットが生成されるときのデータベースの状態を制御するためにフィクスチャを使いましょう。
- このフィクスチャの設定を RSpec の共有コンテキストに展開します。この共有コンテキストは、スナップショットテストが CI スイートあるいは
run-snapshot-tests.sh
を経由して内部で実行される場合に、同じデータベース状態が存在することを保証するために使用されます。
spec/support/shared_contexts/glfm/example_snapshot_fixtures.rb
で、これらのフィクスチャを含む RSpec 共有コンテキストを見ることができます。
環境変数ベースの正規化
場合によっては、フィクスチャは変化する値を制御できないので、使えないかもしれません。このような場合、運用コードに環境変数のサポートを導入することで、脚注の例のHTMLを生成するときにテスト環境のランダム性を上書きすることができます。環境変数が実運用コードのパスにあっても、明示的に設定されない限り何の効果もありません。これにより、後述するより複雑な正規表現に基づく正規化を避けることができます。
現在の例では、通常はランダムである脚注IDを、GITLAB_TEST_FOOTNOTE_ID
を設定することで決定論的に上書きしています。これは、spec/support/shared_contexts/glfm/example_snapshot_fixtures.rb
共有コンテキストのフィクスチャのセットアップとともに設定されます。
正規表現ベースの正規化
フィクスチャベースの正規化も環境変数ベースの正規化も使えない場合、正規表現ベースの正規化を使います。これは強力ですが、より複雑で、よりメンテナンスが必要です。特定の例を名前で参照し、適切な正規表現を作成する必要があります。
正規表現ベースの正規化では、カスタム正規表現で キャプチャグループを2つの異なるバージョンのHTMLまたはJSONに適用し、キャプチャされたグループの内容を同じ固定値に置き換えることができます。
そして、正規化された2つのバージョンを比較し、変数以外のコンテンツがすべて同じであることを確認することができます。
- Markdownスナップショット・テストはレンダリングされたHTML/JSONの構造を強制し、正規化仕様に準拠していることを確認することを目的としています。
- 特定のMarkdownの例に対する実装の個々のユニットテストは、これらの変数値の特定の、そして、ターゲットを絞ったテストを担当します。
また、HTMLの正規化にもこの同じ正規表現キャプチャと置換の正規化アプローチを使用しています。正規化では、単に変数値を置き換えるのではなく、HTMLの正規化されていない部分を削除します。
正規化の指定方法についての詳しい説明はglfm_example_normalizations.yml
を参照してください。
目標
上記のすべての制約を考えると、GLFM仕様とテストインフラに関連するさまざまな目標を要約することができます:
- GLFMがどのようにMarkdownをHTMLにレンダリングするかについて、公式の仕様と単一の真実の源があります。この真実の源は、3つのMarkdownファイルで表されます:
-
ghfm_spec_v_?.??.md
CommonMark + GFMの例です。 -
glfm_official_specification.md
GLFM公式の例 -
glfm_internal_extensions.md
GLFM内部拡張用。
-
- この公式仕様はこれらの要求を満たしています:
- GFM がCommonMark 仕様の厳密なスーパーセットであるように、この仕様は GitHub Flavored Markdown(GFM) 仕様の厳密なスーパーセットです。
- したがって、CommonMarkとGFMのすべてのMarkdownサンプルのスーパーセット、GLFM公式仕様と 内部拡張が含まれています。
- GLFM公式仕様と 内部拡張に含まれるすべての追加的なMarkdownのセクションと例を含み、CommonMarkとGFMの例と同じように、Markdownの例と付随するすべての散文があります。
- すべてのヘッダーとMarkdownの例は、
spec.txt
に含まれるすべての例に対してMarkdownの適合性テストを行うために使われる標準的なCommonMarkツールspec_tests.py
で処理できる標準フォーマットでなければなりません。
-
静的バックエンド(Ruby)とWYSIWYGフロントエンド(JavaScript)の両方の実装のためのGLFMパーサーとHTMLレンダラーは、
run-spec-tests.sh
によって検証されたように、仕様のすべての正規のMarkdown + HTML例の_一貫した_レンダリングをサポートします。一貫しているというのは、これらの実装の両方が同一のHTMLにレンダリングするという意味ではありません。これらの実装はそれぞれ、レンダリングするHTMLに異なる実装固有の追加を行っているため、レンダリングされたHTMLはMarkdownの適合性テストを実行する前に、標準的なHTMLに“正規化 “されます。 - 静的なバックエンド(Ruby)とWYSIWYGフロントエンド(JavaScript)の_両方の_実装のために、GLFM
spec.txt
のすべてのMarkdownの例に対応するYAMLファイルの形でスナップショットの例のセットが存在します。これらのスナップショットはGLFMのすべてのMarkdownの例で以下の使い方をサポートしています:- バックエンド(Ruby)のパーサーとレンダラーはMarkdownを期待されるカスタム静的HTMLに変換することができます。
- フロントエンド(JavaScript)のパーサーとレンダラー(GitLabのカスタムコードとRemarkを含む)は、MarkdownをProseMirrorドキュメントを表す期待されるProseMirror JSONに変換することができます。
- リッチテキストエディタ(フロントエンド(JavaScript)パーサーとレンダラー、ProseMirrorを含む)は、MarkdownをProseMirrorによってレンダリングされる期待されるカスタムWYSIWYG HTMLに変換できます。
- リッチテキストエディタは、MarkdownからMDAST、ProseMirrorドキュメントに変換し、Markdownに戻すラウンドトリップテストを行うことができます。これにより、結果のMarkdownがまったく同じであり、相違がないことが確認されます。
実施
以下のスクリプトとファイルのセットは複雑です。しかし、上記のすべての目標を達成することを可能にし、以下の実装目標を達成するために慎重に設計されています:
- GLFM仕様と関連ファイルの手動編集、管理、保守を最小限にすること。
- アップストリームのCommonMark仕様、GFM拡張、GLFM拡張に変更があった場合、GLFM仕様と関連ファイルを更新するプロセスを自動化し、簡素化します。
- GLFM仕様の部分的または不完全な実装を、進行中の作業、バグ、または新しい将来のMarkdownサポートに関わらず、サポートします。
- 標準的なCommonMark適合性テストとGLFM実装固有のユニット/受け入れMarkdownスナップショットテストを含む、さまざまなテストの自動化、簡素化、および実行をサポートします。
- 自動化された受け入れテストや自動化されたドキュメンテーションの更新のような、現在と将来の要求をサポートするために、すべてのGLFM仕様例の周りに拡張可能なメタデータの豊富なセットを提供します。
実装に関する文書は3つのセクションに分かれています:
- スクリプト
- 仕様ファイル
-
スナップショットファイルの例:これらの YAML ファイルはさまざまなテストを実行するための入力データやフィクスチャとして使われ、
glfm_specification/output_example_snapshots
の下にあります。すべてのスナップショットファイルは仕様ファイルとパーサーとレンダラーの実装に基づいて自動的に生成されます。ただし、不完全な実装をテストドライブする場合など、必要に応じて直接編集することもできます。
スクリプト
これらの実行スクリプトは、仕様のメンテンナンスやテストの実行に関連するさまざまなタスクを実行します。各スクリプトは、scripts/glfm
にあるシェル実行可能なエントリポイントファイルを持っていますが、実際の実装はscripts/lib/glfm
のユニットテストされたクラスで行われます。
scripts/glfm
の Ruby 実行スクリプトのファイル名には、アンダースコアではなくダッシュが使われています。この命名はRubyファイルとしては標準的ではありませんが、ファイル名で検索する際に、scripts/lib/glfm
の対応する実装クラスエントリポイントファイルと区別するために使われています。
update-specification.rb
スクリプト
scripts/glfm/update-specification.rb
スクリプトは、入力仕様ファイルを使用して、spec.txt
とspec.html
出力仕様ファイル、およびsnapshot_spec.md
とsnapshot_spec.html
出力例スナップショットファイルの Markdown と HTML 出力ファイルを生成および更新します。
HTMLファイルは、生成された(または更新された)MarkdownをHTMLにレンダリングするためにバックエンドAPIに渡すことで作成されます。
canonicalize-html.rb
スクリプト
scripts/glfm/canonicalize-html.rb
はHTMLの「正規化」を扱います。これは、余分なHTMLを含む静的またはWYSIWYGのHTML文字列を入力として受け取り、正規化されたHTML文字列を出力するパイプスルーのヘルパースクリプトです。
Unixの哲学に基づき、スタンドアロンでモジュール化された単一目的のスクリプトとして実装されています。GitLabレンダラーの実装に対して、標準のCommonMarkspec_tests.py
スクリプトを実行すると、カノニカルHTMLを期待するため、使いやすいです。
run-spec-tests.sh
スクリプト
scripts/glfm/run-spec-tests.sh
spec_tests.py
このスクリプトは、scripts/glfm/canonicalize-html.rb
ヘルパースクリプトでghfm_spec_v_0.29.md
とglfm_specification/output_spec/spec.txt
ファイルを使用し、GLFMレンダラー実装がMarkdown仕様の例を正規化されたHTMLにレンダリングするためのサポートをテストします。
update-example-snapshots.rb
スクリプト
scripts/glfm/update-example-snapshots.rb
スクリプトはサンプルのスナップショットYAML ファイルを作成し、更新します。
入力は
-
glfm_specification/output_spec/snapshot_spec.md
。CommonMark、GFM、GLFMの公式および内部例のスーパーセットです。 -
glfm_specification/input/gitlab_flavored_markdown/glfm_example_*.yml
YAMLファイル。スナップショットファイルの生成方法を制御するためのメタデータが含まれています。
run-snapshot-tests.sh
スクリプト
scripts/glfm/run-snapshot-tests.sh
便利なシェルスクリプトはexample_snapshot
YAMLファイルによって駆動されるRSpecとJest*_spec
ファイル (メインアプリspec
フォルダから) に関連するすべてのMarkdownスナップショットを実行します。
実際のRSpecとJestのテストファイル*_spec
(フロントエンドとバックエンド)は、spec
、対応する実装の場所と一致する、通常の関連する場所にあります。これらは次のどちらかで実行できます:
- 標準パイプラインの一部として。
- コマンドラインやIDEから、
spec
の他のファイルと同じように。
しかし、これらは4つの異なる場所に分散しています:
- バックエンドテストは
spec/requests
の下にあります。 -
ee/spec/requests
でのバックエンド EE テスト . -
spec/frontend
でのフロントエンドのテスト。 -
ee/spec/frontend
のフロントエンド EE テスト .
したがって、この便利なスクリプトは、ローカル開発者のみが使用することを想定しています。すべてのテストを一度に実行し、単一のリターンコードを返すことができます。このスクリプトには、関連するbundle exec rspec ...
およびyarn jest ...
コマンド用のシェルスクリプトコマンドのみが含まれています。
verify-all-generated-files-are-up-to-date.rb
スクリプト
scripts/glfm/verify-all-generated-files-are-up-to-date.rb
スクリプトは、update-specification.rb
.update-example-snapshots.rb
スクリプトを実行します。これらのスクリプトを実行した結果、生成された出力仕様ファイルやコミットされた出力仕様ファイル、またはスナップショットファイルの例に差分が生じた場合、例外とゼロ以外のリターンコードが発生して失敗します。
このスクリプトは、glfm-verify
CIジョブを介して実行され、入力仕様ファイルへのすべての変更が、生成された出力仕様ファイルとスナップショット例に反映されることを保証します。
仕様ファイル
これらのファイルはGLFM仕様そのものです。これらはすべてルートglfm_specification
の下にあり、さらに用途や目的に応じてサブカテゴリーに分けられています:
-
glfm_specification
-
input
:ダウンロードまたは手動で編集されたファイルを含みます。これらは、他のすべての自動化されたGLFM仕様スクリプト、プロセス、またはテストを動かすためのオリジナルの入力です。-
github_flavored_markdown
:ダウンロードされ、コミットされたghfm_spec_v_0.29.md
仕様のみを含みます。 -
gitlab_flavored_markdown
:すべてのglfm_*
ファイルを含みます。-
*.md
これはGLFM仕様と関連するすべての例の真理の源です。 -
*.yml
自動化されたGLFMスクリプトとプロセスの様々な側面を制御する入力仕様設定ファイル。
-
-
-
output_spec
:spec.txt
とspec.html
出力仕様ファイルのコンテナ。これはGLFMの公式仕様を表すもので、update-specification.rb
スクリプトの実行によって入力ファイルから自動的に生成されます。 -
output_example_snapshots
:スナップショットテストに使用され、update-specification.rb
とscripts/glfm/update-example-snapshots.rb
スクリプトの実行により入力ファイルから自動的に生成されます。
-
入力仕様ファイル
入力仕様ファイルは、仕様自体を表す手動でキュレーションされたMarkdownファイルです。glfm_specification/input/github_flavored_markdown/*.md
とglfm_specification/input/gitlab_flavored_markdown/*.md
に内部ファイルがあります。
より多くのコンテキストと詳細については、メイン仕様ファイルのセクションを参照してください。
GitHub Flavored Markdown仕様書
glfm_specification/input/github_flavored_markdown/ghfm_spec_v_0.29.md
は、公式の最新版GFMspec.txt
のコピーです。
-
update-specification.rb
スクリプトによって自動的にダウンロードされ、更新されます。 - ダウンロードされると、ファイル名にバージョン番号が追加されます。
- 拡張子はMarkdownエディターで扱いやすいように、
*.txt
から*.md
に変更されています。
現在、序文と 付録の散文のみのヘッダーセクションが追加されています。
例を含むすべてのヘッダーセクションは、次のように区切られた連続したファイルセクションに含まれることが期待されています:
- 2番目のH1ヘッダーの冒頭(「はじめに」セクションの後の最初のヘッダー)
-
<!-- END TESTS -->
HTMLコメント行。
glfm_official_specification.md
glfm_specification/input/gitlab_flavored_markdown/glfm_official_specification.md
GLFM公式仕様のために手動で更新されたMarkdown+HTMLの例と、関連する文書と説明から構成されています。
- これは、標準のバックティックで区切られた
spec.txt
フォーマットの[Markdownの例](#markdown-examples) 、それぞれのMarkdownとレンダリングされるべき対応する正規のHTMLを含んでいます。 - すべてのGitLabの例では、バックティックの後の “extension “アノテーションは
example
のみです。GitHub Flavored Markdownの例ではこのような追加のアノテーションが含まれていますが(例えばexample strikethrough
)、現在のところ特定のMarkdownを説明する追加の拡張アノテーションは含まれていません。 -
update-specification.rb
スクリプトは生成されたspec.txt
の付録の前に新しいセクションとして挿入します。 - これは
H1
のヘッダーセクションで構成され、すべての例はH2
またはH3
のヘッダーセクションの中に2レベルまたは3レベル深く入れ子になっています。 -
H3
ヘッダーセクションはH2
ヘッダーセクションの中に入れ子になっていなければなりません。H1
ヘッダーセクションの中に直接入れ子にすることはできません。
例文を含まない、散文だけのヘッダーセクションを追加_してもかまいません_。
例を含むすべてのヘッダーセクションは、<!-- BEGIN TESTS -->
と<!-- END TESTS -->
HTMLコメント行で区切られた、連続したファイルセクション内に含まれて_いなければなりません_。
glfm_specification/input/gitlab_flavored_markdown/glfm_official_specification.md
サンプルエントリ
# Section with GLFM official specification examples
## Strong
{: #strong}
### Strong with two asterisks
{: #strong-with-two-asterisks}
```````````````````````````````` example
**bold**
.
<p><strong>bold</strong></p>
````````````````````````````````
### Strong with HTML
{: #strong-with-html}
```````````````````````````````` example
<strong>
bold
</strong>
.
<p><strong>
bold
</strong></p>
````````````````````````````````
glfm_internal_extensions.md
glfm_specification/input/gitlab_flavored_markdown/glfm_internal_extensions.md
手動で更新されたGLFM内部拡張のMarkdownサンプルと、それに関連する文書と説明から構成されています。
その一般的なフォーマットはglfm_official_specification.md
と同じで、H1
,H2
, またはH3
のセクションで構成され、標準のバックティック区切りのspec.txt
フォーマットのMarkdown サンプルが含まれています。
しかし、標準的なHTMLのセクションで説明されたように、各例のMarkdownの部分だけが指定され、HTMLの部分は空のままです。
例文を含まない、散文だけのヘッダーセクションを追加_してもかまいません_。
例を含むすべてのヘッダーセクションは、<!-- BEGIN TESTS -->
と<!-- END TESTS -->
HTMLコメント行で区切られた、連続したファイルセクション内に含まれて_いなければなりません_。
glfm_specification/input/gitlab_flavored_markdown/glfm_official_specification.md
サンプルエントリ
|
。この接頭辞は、このファイルがmarkdownlint
でチェックされたときの誤ったエラーや、他のMarkdownエディタでのエラーの可能性を避けるのに役立ちます。実際のファイルには、これらの接頭辞|
。|# Section with GLFM Internal Extension Examples
|
|## Video
|
|```````````````````````````````` example
|![video](video.m4v "video title")
|.
|````````````````````````````````
入力仕様設定ファイル
入力設定ファイルは、自動化されたGLFMスクリプトとプロセスの様々な側面を制御する手動でキュレーションされたYAMLファイルです。これらのファイルはglfm_specification/input/gitlab_flavored_markdown/*.yml
にあります。
より多くのコンテキストと詳細については、メイン仕様ファイルのセクションを参照してください。
設定ファイルの検証
設定ファイル内の手動でキュレーションされたサンプル名はすべて、output_example_snapshots/examples_index.yml
、入力仕様ファイルに基づいて自動的に生成される既存のMarkdownサンプル名に対応していなければなりません。
存在しないサンプル名への無効な参照がある場合、scripts/glfm/update-example-snapshots.rb
スクリプトは記述的なエラーで失敗します。
このバリデーションの唯一の例外は00_
で始まるサンプル名で、これはYAML エイリアス用に予約されています。詳細と例についてはglfm_example_normalizations.yml
のセクションを参照してください。
glfm_example_status.yml
glfm_specification/input/gitlab_flavored_markdown/glfm_example_status.yml
はスクリプトと テストのふるまいをコントロールします。
- 手動で更新します。
-
skip_update_example_snapshot*
フィールドはMarkdownサンプルに基づくスナップショットエントリの自動生成のステータスを制御します。 -
skip_running_*
コントロールはMarkdown適合性テストもしくはMarkdownスナップショットテストを個々の例に対してスキップすることを許可します。 - これにより、さまざまな例が未実装、部分的な実装、壊れている、生成できない、何らかの理由でテストできない場合に、この処理やテストをスキップすることを制御することができます。
- すべてのエントリのデフォルトは false です。trueと評価されるRubyの値を指定することで、trueに設定することができます。これは
true
の真偽値でもよいのですが、理想的には、サンプルの更新やテストがスキップされる理由を説明する文字列であるべきです。 -
skip_update_example_snapshot*
のエントリが真であるとき、既存の値は保存されます。psych
しかしながら、YAML は書き直されるので、文字列の値のスタイルとBlock Chomping Indicator (|
) は修正される可能性があります。
それぞれの例では次のオプションのエントリがサポートされています。デフォルトはfalse
です:
-
skip_update_example_snapshots
:trueの場合、glfm_specification/output_example_snapshots/html.yml
ファイルまたはglfm_specification/output_example_snapshots/prosemirror_json.yml
ファイル内のこの例のエントリーの追加または更新をスキップします。この値がtrueの場合、他のskip_update_example_snapshot_*
のエントリーはtrueになりえず、trueの場合はエラーが発生します。 -
skip_update_example_snapshot_html_static
:true の場合、glfm_specification/output_example_snapshots/html.yml
ファイル内のこの例の静的 HTMLエントリの追加または更新をスキップします。 -
skip_update_example_snapshot_html_wysiwyg
:trueを指定すると、glfm_specification/output_example_snapshots/html.yml
ファイル内のこの例のWYSIWYG HTMLエントリの追加や更新を省略します。 -
skip_update_example_snapshot_prosemirror_json
:trueを指定すると、glfm_specification/output_example_snapshots/prosemirror_json.yml
ファイル内のこの例のエントリーの追加や更新を省略します。 -
skip_running_conformance_static_tests
:trueの場合、この例の静的HTMLの Markdown適合性テストの実行をスキップします。 -
skip_running_conformance_wysiwyg_tests
:trueの場合、この例のWYSIWYG HTMLのMarkdown適合性テストの実行をスキップします。 -
skip_running_snapshot_static_html_tests
:trueを指定すると、この例の静的HTMLのMarkdownスナップショットテストの実行をスキップします。 -
skip_running_snapshot_wysiwyg_html_tests
:trueの場合、この例のWYSIWYG HTMLのMarkdownスナップショットテストの実行をスキップします。 -
skip_running_snapshot_prosemirror_json_tests
:trueを指定すると、この例のProseMirror JSONのMarkdownスナップショットテストの実行をスキップします。
glfm_specification/input/gitlab_flavored_markdown/glfm_example_status.yml
サンプルエントリを参照してください:
07_99_00_an_example_with_incomplete_wysiwyg_implementation_1:
skip_update_example_snapshots: 'An explanation of the reason for skipping.'
skip_update_example_snapshot_html_static: 'An explanation of the reason for skipping.'
skip_update_example_snapshot_html_wysiwyg: 'An explanation of the reason for skipping.'
skip_update_example_snapshot_prosemirror_json: 'An explanation of the reason for skipping.'
skip_running_conformance_static_tests: 'An explanation of the reason for skipping.'
skip_running_conformance_wysiwyg_tests: 'An explanation of the reason for skipping.'
skip_running_snapshot_static_html_tests: 'An explanation of the reason for skipping.'
skip_running_snapshot_wysiwyg_html_tests: 'An explanation of the reason for skipping.'
skip_running_snapshot_prosemirror_json_tests: 'An explanation of the reason for skipping.'
glfm_example_normalizations.yml
glfm_specification/input/gitlab_flavored_markdown/glfm_example_normalizations.yml
はフィクスチャベースの正規化プロセスをコントロールするために使用されます。1つもしくは複数のregex
/replacement
のペアをMarkdownのサンプルに指定することができます。
- 手動で更新します。
- これは、参照する例とエントリーのタイプに対応する入れ子構造を持っています。
-
regex
/replacement
のペアの重複を避け、複数のサンプルで共有できるようにするために、YAMLアンカーとエイリアスを広範囲に使います。 - YAMLアンカーはユニークなアンカー名を保証し名前の衝突を避けるためにサンプルのインデックス番号に基づいた命名規約を使います。
glfm_specification/input/gitlab_flavored_markdown/glfm_example_normalizations.yml
サンプルエントリ
# NOTE: All YAML anchors which are shared across one or more examples are defined in the `00_shared` section.
00_shared:
00_uri: &00_uri
- regex: '(href|data-src)(=")(.*?)(test-file\.(png|zip)")'
replacement: '\1\2URI_PREFIX\4'
01_01_00__section_one__example_containing_a_uri__001:
html:
static:
canonical:
01_01_00_uri: *00_uri
snapshot:
01_01_00_uri: *00_uri
wysiwyg:
01_01_00_uri: *00_uri
prosemirror_json:
01_01_00_uri: *00_uri
07_01_00__gitlab_specific_markdown__footnotes__001:
# YAML anchors which are only shared within a single example should be defined within the example
shared:
07_01_00_href: &07_01_00_href
- regex: '(href)(=")(.+?)(")'
replacement: '\1\2REF\4'
07_01_00_id: &07_01_00_id
- regex: '(id)(=")(.+?)(")'
replacement: '\1\2ID\4'
html:
static:
canonical:
07_01_00_href: *07_01_00_href
07_01_00_id: *07_01_00_id
snapshot:
07_01_00_href: *07_01_00_href
07_01_00_id: *07_01_00_id
wysiwyg:
07_01_00_href: *07_01_00_href
07_01_00_id: *07_01_00_id
prosemirror_json:
07_01_00_href: *07_01_00_href
07_01_00_id: *07_01_00_id
glfm_example_metadata.yml
glfm_specification/input/gitlab_flavored_markdown/glfm_example_metadata.yml
は、スナップショットサンプル生成プロセスの他の側面を制御できます。
- 手動で更新します。
-
ee
フィールドは、サンプルがEEのみのサンプルであるかどうかを決定ee
します。ee
フィールドがee
true
の場合、サンプルはee/spec/requests/api/markdown_snapshot_spec.rb
によってのみ実行され、spec/requests/api/markdown_snapshot_spec.rb
では実行されません。 -
api_request_override_path
フィールドは、指定されたサンプルのstatic
HTMLを生成するために使用されるAPIエンドポイントパスをオーバーライドします。異なるエンドポイントは、場合によっては異なるHTMLを生成する可能性があるため、同じMarkdownに対して異なるAPIエンドポイントを使用できるようにしたいものです。デフォルトでは、/markdown
エンドポイントが使用されます。
glfm_specification/input/gitlab_flavored_markdown/glfm_example_metadata.yml
サンプルエントリ
---
08_01_00__examples_using_internal_extensions__markdown_preview_api_request_overrides__001:
api_request_override_path: /groups/glfm_group/preview_markdown
08_01_00__examples_using_internal_extensions__markdown_preview_api_request_overrides__002:
api_request_override_path: /glfm_group/glfm_project/preview_markdown
08_01_00__examples_using_internal_extensions__markdown_preview_api_request_overrides__003:
api_request_override_path: /glfm_group/glfm_project/preview_markdown
08_01_00__examples_using_internal_extensions__markdown_preview_api_request_overrides__004:
api_request_override_path: /-/snippets/preview_markdown
08_01_00__examples_using_internal_extensions__markdown_preview_api_request_overrides__005:
api_request_override_path: /glfm_group/glfm_project/-/wikis/new_page/preview_markdown
08_01_00__examples_using_internal_extensions__markdown_preview_api_request_overrides__006:
ee: true
api_request_override_path: /groups/glfm_group/-/wikis/new_page/preview_markdown
出力仕様ファイル
glfm_specification/output
ディレクトリには、update-specification.rb
スクリプトによって生成された GLFM 仕様を表す CommonMark 標準フォーマットspec.txt
ファイルが含まれます。また、spec.txt
を入力として生成されるレンダリングされたspec.html
も含まれます。
GLFM仕様を表すこれらの出力spec.*
ファイルは、他のinput
仕様ファイルと同じ親フォルダglfm_specification
の下に配置されています。これらは便宜上、また手動で編集されたファイルと生成されたファイルが混在しているため、ここに置かれています。
GFMでは、spec.txt
はtest dirにあり、CommonMarkではプロジェクトルートにあります。標準的な場所の前例はありません。将来、レンダリングされたHTMLspec.html
バージョンのホストされたバージョンを別の場所やサイトに移動またはコピーすることになるかもしれません。
spec.txt
glfm_specification/output_spec/spec.txt
はMarkdown仕様ファイルで、散文とMarkdown + 正式なHTML例を含む標準フォーマットです。
GLFM仕様の中で、spex.txt
はglfm_official_specification.md
からの公式な仕様例のみを含んでいます。glfm_internal_extensions.md
からの内部拡張例は含んでいません。
また、run-spec-tests.sh
のような他のスクリプトの入力にもなっています。
入力仕様ファイルを入力として、update-specification.rb
スクリプトによって生成または更新されます。このプロセスの図と詳細については、update-specification.rb
スクリプトセクション を参照してください。
spec.txt
はMarkdownファイルですが、GFMやCommonMarkの仕様との整合性を保つため、*.txt
という拡張子をつけています。他のすべてのGLFM Markdownファイルは、Markdownフォーマットとシンタックスハイライトを有効にするための様々なエディタとの互換性のために、*.md
拡張子で命名されています。spec.html
glfm_specification/output_spec/spec.html
は、spec.txt
に基づいてレンダリングされたHTMLファイルです。これはspec.txt
と同時にupdate-specification.rb
スクリプトによって生成(または更新)されます。
これは “GitHub Flavored Markdown” (GFM)仕様と CommonMark仕様のHTMLレンダリング版に相当しますが、GitLab Flavored Markdown(GLFM) の例のみが含まれています。
このHTMLのフォーマットは、現在のところGFMとCommonMarkのHTMLレンダリング仕様と同一ではありません。これはGitLab Markdownレンダラーでspec.txt
。HTMLを適切にフォーマットするには、CommonMarkプロジェクトのLuaスクリプトとテンプレートを複製または再利用する必要があります:CommonMark Makefile
スナップショットファイルの出力例
output_example_snapshots
ディレクトリには、glfm_specification/input
ディレクトリのファイルに基づいてupdate-specification.rb
とupdate-example-snapshots.rb
スクリプトによって生成されるファイルが含まれています。
output-specification.rb
スクリプトはoutput_snapshot_examples/snapshot_spec.md
とoutput_snapshot_examples/snapshot_spec.html
を生成します。これらのファイルは、入力ファイルに基づいて生成された例を含むMarkdown仕様ファイルで、output_spec/spec.txt
とoutput_spec/spec.html
に似ていますが、以下の違いがあります:
- これらのファイルには、CommonMark、GitHub Flavored Markdown、GitLab Flavored Markdown仕様の_すべての_例のスーパーセットが含まれていますが、
spec.*
にはGLFM仕様のみが含まれています。これは、スナップショット・テストで作業するときに、すべての例を参照するための単一の場所を提供するためです。 - これらは例を含む_ヘッダーセクションだけを_含んでいます。例を含まない散文のみのセクションは含まれていません。
update-example-snapshots.rb
スクリプトはさまざまなoutput_snapshot_examples/*.yml
ファイルを生成し、スナップショットテストのフィクスチャとして使われます。
バックエンド(Ruby)とフロントエンド(JavaScript)の両方のGLFM実装が完了した後、これらのYAMLファイルはすべて自動的に生成されます。しかしながら、実装がまだ進行中である間は、glfm_specification/input/gitlab_flavored_markdown/glfm_example_status.yml
のskip_update_example_snapshots
キーを使っていくつかの例の自動生成を無効にすることができます。代わりに、実装を促進するために必要に応じて手動で編集できます。
snapshot_spec.md
glfm_specification/output_example_snapshots/snapshot_spec.md
はMarkdownファイルで、spec.txt
のような標準的なMarkdown + 標準的なHTMLの例を含んでいます。
これは、入力仕様ファイルを入力として、update-specification.rb
スクリプトによって生成または更新されます。このプロセスの図と詳細については、update-specification.rb
スクリプトセクション を参照してください。また、update-example-snapshots.rb
のような他のスクリプトの入力としても機能します。
spec.txt
と似ていますが、以下の点が異なります:
-
spec.txt
にはGitLab Flavored Markdownの例のみが含まれていますが、snapshot_spec.md
。また、”GitHub Flavored Markdown” (GFMspec.txt
)仕様とspec.txt
CommonMark仕様の例の完全なスーパーセットも含まれています。 -
spec.txt
はGLFM仕様の全文を表し、説明文のみで例文を含まない追加のヘッダーセクションを含みますが、snapshot_spec.md
は例文を含むヘッダーセクションのみで構成されています。これは、このファイルの目的が、他のoutput example snapshot files
の入力として機能することであり、spec.txt
やspec.html
のような実際の仕様ファイルとして機能することを意図していないからです。
snapshot_spec.html
glfm_specification/output_snapshot_examples/snapshot_spec.html
は、snapshot_spec.md
に基づいてレンダリングされたHTMLファイルです。これはsnapshot_spec.md
と同時にupdate-specification.rb
スクリプトによって生成(または更新)されます。
snapshot_spec.md
を GitLab Markdown レンダラーを通して実行した生の出力に過ぎません。HTMLを適切にフォーマットするには、CommonMarkプロジェクトのLuaスクリプトとテンプレートを複製または再利用する必要があります:snapshot_spec.md
CommonMark Makefilesnapshot_spec.md
examples_index.yml
glfm_specification/output_example_snapshots/examples_index.yml
は、CommonMark、GFM、GLFMのすべての例名のメインリストで、それぞれ一意に識別できる名前が付けられています。
- GFM
spec.txt
仕様書の階層的なセクションと例から生成されます。 - CommonMark と GFM の例については、これらのセクションはもともと GFM
spec.txt
から取得したものです。 - GLFMの例については、
glfm_official_specification.md
とglfm_internal_extensions.md
から生成されています。 - また、以下のような各例に関する特別なメタデータも含まれています:
-
spec_example_position
- 生成されたGLFMspec.txt
ファイル内の例の位置。- この値はファイル内の個々のMarkdown + HTML5例のインデックス順です。ファイルの行番号では_ありません_。
- この値は、レンダリングされた
spec.html
ファイル内の例を見つけるために使用できます。標準の CommonMark ツールには、レンダリングされた HTML ファイル内の各例のインデックス番号が含まれているからです。例:https://spec.commonmark.org/0.30/#example-42
-
source_specification
- この例が元々どの仕様に由来するか:commonmark
、github
、またはgitlab
。
-
- exampleエントリ名の命名規則は、入れ子になったヘッダーセクション名とヘッダーの exampleインデックスに基づいています。
- この命名規則は、かなり安定した名前と例の位置になるはずです。CommonMark / GLFMの仕様が変更されることはほとんどなく、同じセクション7のサブセクションに複数の例が存在するほとんどのGLFMの例は、サブセクションの最後に追加されます。
examples_index.yml
サンプルエントリ
02_01_00_preliminaries_characters_and_lines_1:
spec_example_position: 1
source_specification: commonmark
03_01_00_blocks_and_inlines_precedence_1:
spec_example_position: 12
source_specification: commonmark
05_03_00_container_blocks_task_list_items_1:
spec_example_position: 279
source_specification: github
06_04_00_inlines_emphasis_and_strong_emphasis_1:
spec_example_position: 360
source_specification: github
07_01_00_audio_link_1:
spec_example_position: 301
source_specification: gitlab
markdown.yml
glfm_specification/output_example_snapshots/markdown.yml
glfm_specification/output_example_snapshots/examples_index.yml
の各エントリの元の Markdown が含まれています:
- CommonMarkとGFM Markdownについては、
update-example-snapshots.rb
スクリプトを使用して、標準のGFMspec.txt
から生成(または更新)されます。 - GLFMの場合は,
glfm_official_specification.md
とglfm_internal_extensions.md
の入力仕様ファイルから生成(または更新)されます.
glfm_specification/output_example_snapshots/markdown.yml
サンプルエントリを参照してください:
06_04_00_inlines_emphasis_and_strong_emphasis_1: |
*foo bar*
html.yml
glfm_specification/output_example_snapshots/html.yml
glfm_specification/output_example_snapshots/examples_index.yml
の各エントリの HTML を含みます:
3種類のエントリーが存在し、それぞれに異なるHTMLがあります:
-
正規表現
- Canonical」HTML。
- CommonMark と GFM の例では、HTML は
spec.txt
の例に由来しています。 -
GLFM公式仕様の例については、
glfm_official_specification.md
から生成/更新されます。
-
静的
- これは
glfm_specification/output_example_snapshots/examples_index.yml
の各エントリーの静的な(バックエンド(Ruby)が生成した)HTMLです。 - バックエンドのMarkdown API(または基礎となる内部クラス) から
update-example-snapshots.rb
スクリプトを通して生成/更新されますが、実装が不完全な静的な例については手動で更新することができます。
- これは
-
WYSIWYG
-
glfm_specification/output_example_snapshots/examples_index.yml
の各エントリのWYSIWYG(フロントエンド、JavaScript生成)HTML。 - これは
update-example-snapshots.rb
スクリプトを通してフロントエンドのリッチテキストエディタの実装から生成(または更新)されます。不完全な実装のWYSIWYG例のために手動で更新することができます。
-
HTMLを生成するときに発生する例外や失敗は、Error - check implementation
の値に置き換えられます。
glfm_specification/output_example_snapshots/html.yml
サンプルエントリを参照してください:
06_04_00_inlines_emphasis_and_strong_emphasis_1:
canonical: |
<p><em>foo bar</em></p>
static: |
<p data-sourcepos="1:1-1:9" dir="auto"><strong>foo bar</strong></p>
wysiwyg: |
<p><strong>foo bar</strong></p>
static
またはWYSIWYG
のエントリーは、実装の進展に応じて、html.yml
の例とは異なる可能性があります。
prosemirror_json.yml
glfm_specification/output_example_snapshots/prosemirror_json.yml
の各エントリの ProseMirror JSON がコンテナに格納されています。glfm_specification/output_example_snapshots/examples_index.yml
- これは
update-example-snapshots.rb
スクリプトによってフロントエンドのコードから生成(または更新)されますが、不完全な実装の例では手動で更新することもできます。 - 生成時の例外や失敗は
Error - check implementation
の値に置き換えられます。
glfm_specification/output_example_snapshots/prosemirror_json.yml
サンプルエントリを参照してください:
06_04_00_inlines_emphasis_and_strong_emphasis_1: |-
{
"type": "doc",
"content": [
{
"type": "paragraph",
"content": [
{
"type": "text",
"marks": [
{
"type": "bold"
}
],
"text": "foo bar"
},
]
},
]
}
ワークフロー
このセクションでは、スクリプトを使用してGLFM仕様とテストを管理する方法について説明します。
GLFM仕様の更新と適合性テストの実行
-
update-specification.rb
、GLFM仕様の出力仕様ファイルを更新します。 - 出力仕様ファイルの変更を目視で確認します。
-
run-spec-tests.sh
を実行します。このスクリプトはまだ実装されておらず、プレースホルダのメッセージを表示するだけです。実装されれば、正規化されたGLFM仕様に対する適合性テストを実行するはずです。 - 出力仕様ファイルに変更があればコミットしてください。
スナップショット例を更新し、スナップショットテストを実行します。
- 進行中の機能やバグに取り組んでいる場合は、入力仕様ファイルに必要な手動更新を行います。これには以下が含まれます:
-
glfm_official_specification.md
またはglfm_internal_extensions.md
の正規のMarkdownまたはHTMLの例を更新します。 -
glfm_specification/input/gitlab_flavored_markdown/glfm_example_status.yml
を更新して、例やテストの現在の状態を反映します。
-
-
update-specification.rb
を実行してspec.txt
を更新し、入力仕様ファイルに加えられた変更を反映させます。 - 出力仕様ファイルの変更を目視で確認します。
-
update-example-snapshots.rb
を実行して、スナップショット・ファイルの例を更新します。 - スナップショットファイルの変更を目視で確認します。
-
run-snapshot-tests.sh
を便利なスクリプトとして実行し、 サンプルスナップショットを使用するフロントエンド (RSpec) およびバックエンド (Jest) のテストをすべて実行します。- フロントエンドやバックエンドのスナップショットテストを個別に実行することもできます。
- すべてのフロントエンドとバックエンドのテストは、継続的インテグレーションスイートの一部として実行されます。
- 入力仕様ファイル、出力仕様ファイル、あるいはスナップショット例のファイルに対するすべての変更をコミットします。