Geminiハイパーテキスト形式(別名「gemtext」)の仕様

バージョン0.24.0

本文書は以下の条項のもと、パブリックドメインに置かれます。

Creative Commons CC0 1.0 Universal Public Domain Dedication

概要

本文書では「gemtext」ハイパーテキスト形式を規定します。Gemtextの目的は、Geminiファイル転送プロトコルの「生来の」応答形式として、サーバーから送られることです。HTMLがHTTP [RFC7230]の生来の応答形式であることと同様です。ただし、相応しいものであれば、他の目的でも利用できます。Gemtextは未登録のMIME種別text/geminiを使い、Geminiを介してサーバーから送られます。

Geminiのネットワークプロトコルの仕様も参照

本文書で使われる慣例

本文書中のキーワード「しなければならない (MUST)」「してはならない (MUST NOT)」「求められる (REQUIRED)」「することになっている (SHALL)」「しないことになっている (SHALL NOT)」「すべき (SHOULD)」「すべきでない (SHOULD NOT)」「勧める (RECOMMENDED)」「してもよい (MAY)」「省ける (OPTIONAL)」は [BCP14] 中に記載されている通りに解釈されます。

概観

Gemtextは単一の電子文書に対応するべく設計されています。他のオンラインの資材と関連付けられ、多種多様な形や大きさの画面を持つ機器で簡単かつ快適に読めるように表示できます。固定数文字で「強固に折り返された」素のテキスト(クライアントの画面では長過ぎたり短過ぎたりして充分とは言い難い可能性があります)にまさる、利用者体験をもたらします。また、素のテキストでは利用者が手作業で文書からURLをコピーし、ユーザーエージェントインターフェースに貼り付けなければなりませんでした。

形式は、手で書く上で単純であることと、実践において構文解析が単純であることを土台に設計されました。gemtext文書に欠かせない構造の条件は、階層的でなく、平板かつ単一であり、上から下に正しく処理が走って構文解析と呈示が行えるところにあります。

形式は、文書の表示のされかたについて、文書の執筆者による、精密で複写可能な水準の制御に役立てられることを意図していません。装飾はユーザーエージェント毎に制御されます。

メディア種別引数

「text」最上位メディア種別の副種別である「text/gemini」は、[RFC2046] に定義されている「charset」引数を継承します。しかしながら、Geminiを介して転送される「text」内容の「charset」の既定値は「UTF-8」です。

「text/gemini」副種別で個別に定義されている、追加の引数が1つあります。それは「lang」引数です。「lang」の値は「text/gemini」文書のテキスト内容が書かれている自然言語を示すものです。「lang」引数は省けます。「lang」引数があるとき、その解釈は完全にクライアントで定義されます。例えばクライアントでは「lang」の値を使い、内容の約物を改善しても構いません。「lang」引数が無い場合、何ら既定値は仮定されません。(テキストから音声への変換を行う画面読み上げ器といった)内容を処理するために言語の検知が必要なクライアントでは、「lang」引数が欠落している場合に、どのように処理を続ければ良いか決定するため、利用者の入力に頼るべきです。

「lang」引数の妥当な値は [BCP47] に定義される1つ以上の言語札のコンマ区切のリストです。例えば以下です。

行指向の設計

Gemtextは行指向の形式です。文書は1行以上からなります。6つの独立する行の種類があります。各行は明確に1つの種類に属し、行の最初の3文字を調べることで、この種類を曖昧さなく判定できます。行の種類と構文解析の状態(後述)を合わせることで、利用者にどのように表示されるかを決めます。特定の行の種類に関連付けられる、表示や呈示の詳細は、厳密に各個別の行の範疇において制限されます。gemtext文書では個別に各行を扱うことで、最初から最後の行まで1回通すことにより、正しく構文解析と呈示が行えます。

6つの種類は以下の通りです。

本仕様に準拠する上では、gemtext文書を構文解析し、表示するソフトウェアでは、テキスト行、リンク行、書式化切替え行を、以下に記述する通りに扱わなければなりません。これらは「中核の」行の種類です。

利用者の体験を向上させるために、ソフトウェアでは追加で見出し行、箇条書の項目、引用行を後述する通りに扱っても構いません。これらの行を記述されている通りに扱わないソフトウェアは、あたかもテキスト行であるかのように扱わなければなりません。

構文解析器の状態

準拠するgemtext構文解析器は、単一ビットの内部状態を保持しなければなりません。これは、構文解析器が「通常モード」と「書式化済みモード」のどちらなのかを制御する、構文解析器の状態です。構文解析器の状態は、行をどのように認識するか、行がその種類であったときにどう扱われるかを制御します。構文解析器は、文書の構文解析を開始する時点で、「通常モード」でなければなりません。構文解析器は、この特定の目的を与える行の種類に遭遇したとき、2つのモードの間を切り替えます。文書の末尾での構文解析器の状態には、何ら意味はなく、結果に作用することもありません。

gemtextの行の認識と扱い

通常モードにおいて

テキスト行

テキスト行は「既定」の行の種類です。これは、その他全ての行の種類が特定の識別用の接頭辞から始まる点で認識されるという意味です。そのような接頭辞から始まらない、いかなる行もテキスト行です。典型的なgemtext文書では、多くの行はこのテキスト行となることでしょう。

テキスト行には何ら特別な意味論が無く、一般的な読み方をする上で、視覚的に見やすいように利用者に表示されるべきです。細かい意味合いについてはクライアント側に裁量があるということです。例えば可変幅のフォントが使われても良いですし、空白が正規化されても良いですし、単語間の空白より文の間の空白が長くなるようにしても良い、といった感じで、表示上の工夫を適用するのは構いません。クライアントでは、利用者がフォントの大きさや背景色などを変えられるようにして、テキスト行の見た目を独自のものにしても構いません。著者はテキストの内容に専念し、テキスト行の精密な呈示について管理できるとは思わないことです。

クライアントの機器の画面に収まる分より長いテキスト行は、収まるように「折り返される」べきです。つまり長い行は、機器に対して適切な幅の、複数の連続する行に(理想的には空白やハイフンのところで)分割されるべきです。この折り返しは、テキストの各行に独立して適用されます。しかし、クライアントの機器の画面より短い、複数の連続するテキスト行は、より少なく長い行に結合されるべきではありません。Gemtext文書中の個々の行は、独立した実体なのです。

空行はテキスト行に含まれ、特別な意味はありません。それぞれについて、垂直な空の空間として、目に見えない形で呈示されるべきです。連続する空白行は、より少ない空白行に縮めるべきではありません。

リンク行

「=>」の2文字から始まる全ての行はリンク行です。リンク行では、Gemtext文書から他のオンラインの資材へリンクを張ることができます。この資材には他のGemtext文書も含まれます。リンク行の構文は以下です。

=>[<空白>]<URL>[<空白><利用者に親しみやすいリンクの名前>]

ここで、次の通りです。

以下の例は、全て正当なリンク行です。

=> gemini://example.org/
=> gemini://example.org/ リンクの一例
=> gemini://example.org/foo	同じホストにある別のリンクの例
=> foo/bar/baz.txt	相対リンク
=> 	gopher://example.org:70/1 gopherのリンク

リンク行内のURLは、RFC 3986にしたがって、予約された文字と空白をパーセント文字で符号化しなければなりません。

クライアントでは、クライアントの著者が望む通りのやり方でリンクを表示できます。しかしクライアントは、スキームがネットワークプロトコルに対応するリンクの表示にあたって、いかなるネットワーク接続も自動でしてはなりません。

書式化切替え行

最初の3文字が「```」である(つまり先頭に空白なく、3つの連続する逆引用符がある)任意の行は、行の切り替えを実施します。これらの行は、利用者に表示する呈示された出力に含めるべきではありません。その代わり、構文解析器を「通常モード」から「書式化済み」モードに切り替えます。

書式化済み切替え行の先頭の「```」以降のテキストは、クライアントで「代替テキスト」と解釈して構いません。このテキストは当該切替え行以降の、書式化済みテキスト行に付随するものです。代替テキストの使用はクライアントの裁量にあり、単純なクライアントでは無視して構いません。代替テキストは、ASCIIアートやそれに類するテキストでない内容に付けることをお勧めします。例えば、画面読み上げ器を通じて呈示される際に、意味のあるものとして捉えられることが無いようにしたり、検索エンジンにより索引として有効活用されるようにしたりということです。代替テキストにプログラミング言語を指定して、コンピュータのソースコードに使い、発展的なクライアントで構文彩色に使えるようにしても良いでしょう。

見出し行

「#」から始まる行は、見出し行です。見出し行は1、2、3個の連続する「#」文字から構成され、任意で空白が続き、その後ろに見出しのテキストが来ます。#文字の数は見出しの「水準」を示します。#行は見出しであり、##行は子見出しであり、###行は孫見出しです。

見出しテキストの内容は利用者に表示されるべきであり、クライアントは特別な書式を使って構いません。例えば見出しになっていることを示すために、より大きかったり太かったりするフォントを使ったり、違う色を使ったりするなどです。しかし、見出し行の主眼の目的は装飾のためでなく、意味論的なものであり、具体的には文書の内部構造の、機械で読み取れる表現を提供することです。発展的なクライアントはこの情報を使って、例えば長い文書については、画面脇に階層的に書式化された「目次」を自動的に生成して表示して構いません。こうすると、利用者は簡単に特定の節に飛ぶことができ、無闇にスクロールせずに済みます。ディレクトリ内の全てのgemtext文書の一覧を自動的に生成するツールや、gemtext文書のディレクトリ用のAtom/RSSフィードを作成するツールについては、ファイル中の見出しを、人間にとって読みやすい題名として使えます。

箇条書の項目

「* 」から始まる行はリスト項目です。この行の種類は、純粋に装飾上の理由から存在しています。*は発展的なクライアントでは点の記号で置き換えても構いません。「* 」の後のテキストは、あたかもテキスト行のように利用者に表示されるべきです。つまり、目に見える範囲に収まるように折り返し、「いい感じ」に書式化するのです。発展的なクライアントでは、点の記号の空白を考慮に入れて、長いリスト項目を折り返すときに、その項目に対応する全ての行が画面端から等しい距離で間が空くようにすることもできます。

引用行

「>」から始まる行は引用行です。この行の種類が存在しているのは、発展的なクライアントで、読者が装飾を区別できるようにするためです。あるテキストは外部の資料から引用されたものだ、というような、重要な意味論的な情報が読者に伝わります。例えば、長い行を目に見える範囲に折り返すとき、結果的に表示される各行には、前方に「>」記号が置かれていても構いません。

書式化済みモード中

テキスト行

「```」の3文字から始まらない行はテキスト行です。書式化済みモードでは、テキスト行は利用者に対して「中立」に表示されるべきです。中立とは、空白の変更や装飾的な改善なしに、固定幅フォントを使うなどです。グラフィカルなクライアントは、クライアントの目に見える範囲よりも長い書式化済みテキスト行の表示については、折り返すよりは、画面スクロールの仕組みを使うべきです。書式化済みテキスト行を表示する上で、クライアントではASCIIアートやコンピュータのソースコードのような活用例を念頭に置くべきです。具体的には、空白が重要な言語で書かれたソースコード(例えばPython)は、クライアントでファイルに切り貼りして、特に問題なく解釈やコンパイルができるようにすべきです。クライアントが表示するやり方で、問題が起こらないようにすべきです。

書式化切替え行

最初の3文字が「```」である行(つまり先頭に空白のない3つの連続する逆引用符)は、書式化済み切替え行です。この行は、利用者���表示する、呈示される出力に含めるべきではありません。その代わり、構文解析器は「書式化済みモード」から「通常モード」に切り替わります。

書式化済み切替え行の、先頭の「```」に続くテキストは、クライアントで無視しなければなりません。

正式な文法

以下はgemtext文書の拡張BNF仕様です。

	gemtext-document = *1gemtext-line
	gemtext-line     =  text-line / link-line / preformat-toggle
	gemtext-line     =/ heading / list-item / quote-line
	link-line        = "=>" *SP URI-reference [1*SP 1*(SP / VCHAR)] *SP CRLF
	heading          = ( "#" / "##" / "###" ) text-line
	list-item        = "*" SP text-line
	quote-line       = ">" text-line
	preformat-toggle = "```" text-line
	text-line        = *(SP / VCHAR) CRLF

	; URI-reference [STD66]から
	;
	; CRLF          [STD68]から
	; SP            [STD68]から
	; VCHAR         [STD68]から

規範的な参照

有益な参照情報