投稿日:

HTML5 のセクショニングとアウトラインアルゴリズムの再確認


HTML5 では section 要素が導入され、これまでの見出し要素(h1〜h6)のみによる大雑把なドキュメントアウトラインの形成に伴う諸処の問題を、明示的に分かりやすく解決・表現できるようになりました。しかし一方で、見出し要素(h1〜h6)を使った暗黙的なセクショニングも併用することが可能であり、これが人間にとって理解しにくいドキュメントアウトラインを形成することもあります。

例えば次のマークアップの例は、

次のアウトラインを形成します。

どうでしょうか?

もしこれに違和感があるようでしたら、まだ理解が不足していると思います。

実は僕もついちょっと前まで大事な部分を誤解していたのですが、先日参加させて頂いた「MarkupCafe Osaka Vo.1」で、松田さん(@matsudasu)とこのあたりで議論になったことがきっかけで、ようやく改めて理解できた感じです(松田さんには Facebook  上で一緒に考えたり、議論をしたり、色々教えて頂いたりして大変勉強になりました!サンクスです!)。

そこで本稿では、HTML5 のセクショニングとアウトラインアルゴリズムについて、僕が個人的に理解が不足していた箇所を中心に、なるべく分かりやすく解説してみたいと思います。

なお、本稿はアウトラインアルゴリズムについての補足であり、セクショニングコンテンツやセクショニングルート、また明示的・暗黙的セクションに関しての基本的な解説は含みません。必要に応じて、次のリンク先や、他の関連コンテンツを参照してください。

— HTML5 ドキュメントのセクションとアウトラインhttps://developer.mozilla.org/ja/docs/Web/HTML/Sections_and_Outlines_of_an_HTML5_document

— 見出しとセクション
http://www.html5.jp/tag/elements/headings-and-sections.html

また、本稿での例やその他の例のアウトラインを確認したい場合には、次のサイトが便利です。マークアップが実際にはどんなアウトラインを形成するのか、自分で試してみるととても面白い発見があると思います。

— HTML 5 Outliner
http://gsnedders.html5.org/outliner/

セクション内の最初の見出し要素が、そのセクションの見出し

セクションの中の「最初の見出し要素」は、そのセクションの見出しになります。見出し要素は h1 〜 h6 のどれでも構いません。

この時、<h3>いいい</h3> は、それを囲った <section> の見出しになります。また、形成されるアウトラインは次のようなものになります。

【重要ここで <h2>あああ</h2> は、HTMLには書かれいない body 要素(セクショニングルート)の見出しになっています。この後の例でも、body 要素を省略していますが、意味的には必ず body 要素があるものとして読み取ってください。

簡単なようですが、では、次のマークアップではどのように解釈できるでしょうか?

section 内の最初の見出し要素 <h3>いいい</h3> が section の見出しになるのであれば、次の <h3>ううう</h3> はどうなるでしょうか? h3 が連結されて <h3>いいいううう</h3> という意味合いになるでしょうか? あるいは、2個目のセクションは1つ深い階層のアウトラインとなるでしょうか?

正解は次のマークアップと同じ意味になります(分かりやすさの為に、暗黙的に作られたセクション [section] と表記してみました)。

明示的に開始されたセクションの見出しが最初の <h3> になるので、次の同じ <h3> のタグが現れた時点で、セクションは暗黙的に終了して同じレベルで再開されます。

暗黙的セクションは明示的セクションを超えられない

では、次の例ではどうでしょうか?

これは素直に次のようなアウトラインを形成します。

さて、では次の例ではどうでしょうか?

この場合、アウトラインは次のようになります。

セクションの見出しとなった <h3> に比べて、より高いレベルの見出し要素 <h1> が指定された為、明示的なセクションは一旦終了して再開されます。但し、見出し要素による暗黙的なセクショニングは、あくまでも明示的なセクションの中に限ってのものです。ですから、<section> タグを超えることはなく、同じレベルでセクションを再開します。

分かりやすくするために、また [section] という表記を使って、暗黙的に作られたセクションを表してみます(なお、この記法では見出し要素の番号(レベル)は意味が無くなるため、以降、見出し要素の番号の表記を省略します)。

暗黙的なセクションが明示的なセクションを超えていないことが理解できると思います。

では、さらに次の例はどうでしょうか?

これは次のアウトラインを形成します。

複雑なようですが、ここまでのお話で理解できる筈です。暗黙的セクションを [section] として表すと、これは次のように解釈されます。

暗黙的セクションのアウトラインは常に1階層ずつ

見出し要素による暗黙的セクションでは、例えば次のように番号を飛ばして表記することが出来ますが、

セクションの階層は常に1段階ずつなので、 次のようなアウトラインを形成します。

3つの例がありますが、2番目の例のように、h1 から h3 に飛んでもアウトラインは1階層深くなるだけです。また、3つ目の例のように、<h3>ししし</h3> と書いても階層は1つ深くなるだけなので、次の行の <h2>すすす</h2> は同じレベルで開始されます。このように、見出し要素の番号を飛ばして書いても、アウトラインの階層は常に1階層ずつ深くなることに注意が必要です。

より複雑な例で理解する

最後に、ここまでの理解を踏まえて、最初の例について考えてみます。

上の例は、次のアウトラインを形成しました。

順番に考えてみましょう。分かりやすさの為に、暗黙的セクションを [section] と表記します。なお、セクショニングルートとして body タグがあることを忘れないで確認してください。

さて、まず、最初の <h1>あああ</h1> から <h4>えええ</h4> は次の通りになると思います。

これは単純ですね。

さて、<h4>えええ</h4> の後に <section> が来ますので、「暗黙的セクションは明示的セクションを超えられない」ので、全ての暗黙的セクションが終了します。

次に明示的セクションが開始されます。ここで、h5 が明示的セクションの見出しになりますね。

次に <h1>かかか</h1> ですね。明示的セクションの見出し要素となった h5 よりも上の見出しレベルなので、明示的に開始されたセクションは、暗黙的に一旦終了して再開されます。

最後に <h6>ききき</h6> が新しいセクションを開始します。

このように、順序だてて見て行くと、ある程度理解も容易になると思います。

もし「難しいな」と思うようであれば、それは見出し要素(h1〜h6)の番号に惑わされ過ぎなのかも知れません。「見出し要素の番号はアウトラインの階層を表すものでもなく、単に相対的な位置づけを表しているに過ぎない」ぐらいに思うと、より分かりやすくなるのではないかと思います。

まとめ

ここまでに見て来たように、明示的セクションと暗黙的セクションを合わせて利用するときには、いくつかの留意すべき点があり、それを誤ると、マークアップから直感的に理解できるアウトラインと、実際のアウトラインとが乖離してしまうことになります。

個人的には、以下のような点を理解していたら迷うことは無いのではないかと思っています。

  • セクション内の最初の見出し要素(h*)が、そのセクションの見出しになる
  • 見出し要素の番号(レベル)は、明示的セクションを超えて意味を成さない
  • 暗黙的セクションは、明示的セクションを超えられない
  • 暗黙的セクションは、必ず1段階ずつの階層のアウトラインを形成する

また、よく言われることですが、実務では以下のような方針を取ると、混乱が減らせて良いのではないかと思います。

  • 明示的セクションの階層と、見出し要素(h*)タグを一致させる
  • 明示的セクションで統一し、h1 タグしか使わない
  • なるべく見出し要素で飛び番号を用いない(感覚的な階層とすぐズレるため)

以上です。

もし何か誤った解釈などがありましたら、ご指摘いただけると嬉しいです。

 

投稿日:

WordPress 3.7 以降での言語ファイルのロード方法


WordPress 3.7 から、コアやプラグインの自動アップデートの仕組みが準備され、今後言語ファイルのアップデートも自動化されることにると思います。2013 年 10 月 28 日現在、まだその準備段階にあるようですが、関連して今後おそらく、言語ファイルのロード方法が変わるようになります。では、今日現在、プラグイン作者はどのようにしておくのが適切なのかをちょっと考えてみました。

なお、今後の言語ファイルの管理全体がちょっと見えていないので、認識不足や間違いがあればご指摘頂けると嬉しいです。

3.6 以前

WordPress 3.6 以前は概ね次のような記述だったと思います。

どちらも言語ファイル(.mo)の場所をパスで指定しています。プラグインは相対パス、テーマは絶対パスでの指定と、ちょっと一貫性がなくてややこしかったですね。

3.7 以降で、言語ファイルの自動アップデートを利用する場合

WordPress 3.7 以降で、言語ファイルを自動アップデートを適用する場合、次のような記述になるようです。

テキストドメインだけの記述になり、簡潔になりました。これはしっくり来て良いですね。

ではどのように .mo ファイルの場所が特定されるかというと、新しい規定のルールが導入され、それぞれ WordPress 内の次の場所に置かれることになります。

  • /wp-content/languages/plugins/{text-domain}-{locale}.mo
  • /wp-content/languages/themes/{text-domain}-{locale}.mo

この場所へどうやってデプロイするのか、まだ僕は見つけれていません (^_^;A が、おそらく準備中なのかなーと思っています。

課題

さて、翻訳フォイルを上記の場所にデプロイできる環境が整ってそこの言語ファイルを配置できたら、WordPress 3.7 以降をインストールしている環では言語ファイルの自動アップデートが適用されます。また、開発者視点では、言語ファイルの追加や修正でプラグイン自体をアップデートする必要も無くなる改善です。しかし、次の課題があります。

  • 新しい方法だけ採用したら、3.6 以前の環境では言語ファイルが適用されない
  • 古い方法だけ採用したら、当然新しい手法の恩恵が受けれず、また古い将来廃止されるかも知れない不安が残る

2013 年 10 月時点の対処

では、現時点でどう対処するのが良いかというと、現時点では次の感じかなーと思っています。

load_plugin_textdomain()、load_theme_textdomain() のいずれの関数もロード出来なかった場合に false が変えるので、まず新しい仕組みでロードし、失敗して false が返ってきた場合にこれまでの方法でロードします。

これで新しい仕組みで言語ファイルを提供できるようになった段階で、リリースしているプラグインやテーマは自動的に新しい言語ファイルを参照するようになるように思います(おそらく・たぶん…というかこの辺り、運用上の実際の計画や具体的な更新の仕様が見えていななくてちょっと心配。情報が見つけられないでおります…)(直子さんがしっかり情報をまとめてくださっていました 。本稿では実装面のお話をさせて頂きましたが、全体の背景、今後についてなどは次のリンク先の直子さんの記事をご覧ください。http://ja.naoko.cc/2013/10/28/wordpress-37-background-update/ )。

当然ながら、これまで同様にプラグインやテーマに言語ファイルを同梱する必要がありますが、過渡的には仕方ないかなーと思います。そして、新しい仕組みの運用体制が十分に安定したら、3.6 以前の環境には言語ファイルの追加・更新を提供しない、というポリシーとするのが妥当かと思います。

おまけ

おまけというか、実はここからが書きたくてこのこの記事を書いたのが本音です。 (*’-‘*)

WordPress 3.7 の load_plugin_textdomain() の実装ですが、次のようになっています。

これって、次のようにした方が良いと思うんですよね。

要するに、新しい仕組みでのロードを先に行うということなのですが、こうしておくとコードの変更無しに、運用で順次新しい仕組みが適用していけた筈なのですが、どうしてこうなって無いのかなーと疑問に思ってしまうわけです。

どなたか理由を知っていたら教えて頂けたら嬉しいです。

 

(参考URL)
http://ottopress.com/2013/language-packs-101-prepwork/ 

 

 

投稿日:

iOS プロビジョニングプロファイルの作成


iOS の開発におけるプロビジョニングプロファイルの生成は、最初はとても分かりにくいものです。そこで今回、自分が調べた情報をまとめました。Web で検索すると手順を書いてあるものが多く見つかるのですが、個人的には手順はもとより、それぞれのファイルやタスクの意味が知りたいと思ったので、そのあたりを中心にまとめました。

続きを読む iOS プロビジョニングプロファイルの作成

投稿日:

Android (Java) で InputStream / OutputStream の進捗状況の取得・表示


今更なネタです! (*’-‘*)

Android での開発を行っていると、頻繁に In/Out のStream を扱いますが、Stream を扱いながらプログレスバーを更新する方法を検索してみると、while 文などで自ら stream をループさせつつ、AsyncTask#publishProgress() するといった例が見つかります。

しかし、例えば BitmapFactory#decodeStream などのように、直接 Stream を扱うことが出来るメソッドも存在するため、Stream は Stream で、そのまま簡単に進捗状況をモニターしたい場面も多々あります。

本稿では、そのようなケースで利用できる別の方法を簡単にまとめてみました。

続きを読む Android (Java) で InputStream / OutputStream の進捗状況の取得・表示