HTML5のidはエンコードして使おう

HTML5の話題としては周回遅れの話題だと思いますが、私は最近HTML5のidはHTML4.01の頃の制約がなくなっていたのでちゃんとエスケープやエンコードをしないと危ないと知ったという話です

現在のHTMLのid属性の値

When specified on HTML elements, the id attribute value must be unique amongst all the IDs in the element's tree and must contain at least one character. The value must not contain any ASCII whitespace.

文書内で一意で、1文字以上で、ASCII空白を含んで居なければよい

ASCII空白はU+0009 TAB, U+000A LF, U+000C FF, U+000D CR, or U+0020 SPACE.のこと

HTML4.01のid属性の値

ID and NAME tokens must begin with a letter ([A-Za-z]) and may be followed by any number of letters, digits ([0-9]), hyphens ("-"), underscores ("_"), colons (":"), and periods (".").

HTML4.01のid (とname) 属性の値は、英字 (A-Za-z) の何れかから始まり、続いて任意の数の英字 (A-Za-z)、数字 (0-9)、ハイフン (-)、アンダースコア (-)、コロン(:)、ピリオド(.) で構成されている必要がありました

具体的な影響

現在のHTMLのid属性の値は、HTML4.01のid属性の値を包括していますので既存のidを変更したり、今後新たなidを作る場合も運用を変える必要はありません

一方、HTML4.01の頃のまま、例えばidからリンク付きの目次を作成する処理やCSSセレクターの作成する支援する処理などがある場合は注意が必要です

例えば以下のHTML断片はHTML5では仕様に準拠しています

<p id="###">###</p>
<p id="abc?query=efg">abc?query=efg</p>
<p id="a>b{color:red;}">a>b{color:red;}</p>

2019年の抱負の進捗状況 (6月3日時点)

この記事は自分向けの記事です

ニャオス

全体的に崩壊しているので、になったら半年経過と言う事で色々再度予定を立て直したいと思っています

もうちょっと頻繁にblogを更新する

一応緩く更新が続いていますので、このまま緩く更新を続けます

体重58kgまで落とし、維持する

やっとリバウンドが収まりつつあり、65kgを維持できてはいるのですが、減ってもいません

HTML LS Developer's Editionを一通り読む

先月は6月頭あたりに何らかの出力を始められれば、と思っていましたが、今の所何か出力に至る所まで行っていません

ざっくり1か月押し位の感じです

情報処理安全確保支援士を受験する

とりあえず秋に向けて勉強をしましょう (していない人の台詞)

江戸時代の元号をレジストリィに足したが.NETのJapaneseCalendar Classの下限値は西暦1868年9月8日だったので和暦変換できなかった話

タイトルが全ての出落ち記事です

何がやりたかったのか

令和のレジストリィがWindows Updateで提供されたりされなかったり、一緒に文字幅が変わる修正が提供されてGUIがぶっ壊れたりしている今日この頃、皆様いかがお過ごしでしょうか

自分は思い付きでトラブルを増やすべく、江戸時代の元号Windows 10のレジストリィに追加してどうなるか試してみることにしました

レジストリィの場所とデータの形式

元号の情報を持っているレジストリィは HKLM:\SYSTEM\CurrentControlSet\Control\Nls\Calendars\Japanese\Eras にあります

内容をPowerShellで取得するとこんな感じです

PS > Get-Item -Path 'HKLM:\SYSTEM\CurrentControlSet\Control\Nls\Calendars\Japanese\Eras';

    Hive: HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Nls\Calendars\Japanese

Name                           Property
----                           --------
Eras                           1868 01 01 : 明治_明_Meiji_M
                               1912 07 30 : 大正_大_Taisho_T
                               1926 12 25 : 昭和_昭_Showa_S
                               1989 01 08 : 平成_平_Heisei_H
                               2019 05 01 : 令和_令_Reiwa_R

このレジストリィの仕様は見当たらなかったのですが、直感的に値の名前を開始年月日を yyyy MM dd の形で持ち、値は元号の漢字表記、漢字表記の1文字目、ヘボン式ローマ字表記、ヘボン式ローマ字表記1文字目を _ を区切り子として持っているようです

江戸時代まで遡って元号レジストリィに登録してみる

元号一覧 (日本) - Wikipedia を参考に江戸時代までのCSVを用意して取り込んでみることにします

[String] $registryKeyPath = 'HKLM:\SYSTEM\CurrentControlSet\Control\Nls\Calendars\Japanese\Eras';
[String] $csvPath = '.\JapanseEraInEdo.csv';

Get-Content -Path $csvPath |
ConvertFrom-CSV |
Where-Object {
    $null -ne ($_.StartDate -as [DateTime])
} |
ForEach-Object {
    Add-Member -InputObject $_ -MemberType NoteProperty -Name 'Name' -Value ($_.StartDate -as [DateTime]).ToString('yyyy MM dd');
    Add-Member -InputObject $_ -MemberType NoteProperty -Name 'Value' -Value (($_.KanjiEraName, $_.KanjiEraName[0], $_.RomanAlphabetEraName, $_.RomanAlphabetEraName[0]) -join '_');
    Write-Output $_;
} |
Where-Object {
    $_.Name -notin (Get-Member -InputObject (Get-ItemProperty -Path $registryKeyPath) | ForEach-Object {$_.Name})
} |
New-ItemProperty -Path $registryKeyPath > $null;
PS > Get-Item -Path 'HKLM:\SYSTEM\CurrentControlSet\Control\Nls\Calendars\Japanese\Eras';

    Hive: HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Nls\Calendars\Japanese


Name                           Property
----                           --------
Eras                           1868 01 01 : 明治_明_Meiji_M
                               1912 07 30 : 大正_大_Taisho_T
                               1926 12 25 : 昭和_昭_Showa_S
                               1989 01 08 : 平成_平_Heisei_H
                               2019 05 01 : 令和_令_Reiwa_R
                               1615 09 05 : 元和_元_Genna_G
                               1624 04 17 : 寛永_寛_Kan'ei_K
                               1645 01 13 : 正保_正_Shouhou_S
                               1648 04 07 : 慶安_慶_Keian_K
                               1652 10 20 : 承応_承_Jouou_J
                               1655 05 18 : 明暦_明_Meireki_M
                               1658 08 21 : 万治_万_Manji_M
                               1661 05 23 : 寛文_寛_Kanbun_K
                               1673 10 30 : 延宝_延_Enpou_E
                               1681 11 09 : 天和_天_Tenna_T
                               1684 04 05 : 貞享_貞_Joukyou_J
                               1688 10 23 : 元禄_元_Genroku_G
                               1704 04 16 : 宝永_宝_Houei_H
                               1711 06 11 : 正徳_正_Shoutoku_S
                               1716 08 09 : 享保_享_Kyouhou_K
                               1736 06 07 : 元文_元_Genbun_G
                               1741 04 12 : 寛保_寛_Kanpou_K
                               1744 04 03 : 延享_延_Enkyou_E
                               1748 08 05 : 寛延_寛_Kan'en_K
                               1751 12 14 : 宝暦_宝_Houreki_H
                               1764 06 30 : 明和_明_Meiwa_M
                               1772 12 10 : 安永_安_An’ei_A
                               1781 04 25 : 天明_天_Tenmei_T
                               1789 02 19 : 寛政_寛_Kansei_K
                               1801 03 19 : 享和_享_Kyouwa_K
                               1804 03 22 : 文化_文_Bunka_B
                               1818 05 26 : 文政_文_Bunsei_B
                               1831 01 23 : 天保_天_Tenpou_T
                               1845 01 09 : 弘化_弘_Kouka_K
                               1848 04 01 : 嘉永_嘉_Kaei_K
                               1855 01 15 : 安政_安_Ansei_A
                               1860 04 08 : 万延_万_Man'en_M
                               1861 03 29 : 文久_文_Bunkyuu_B
                               1864 03 27 : 元治_元_Genji_G
                               1865 05 01 : 慶応_慶_Keiou_K

JapaneseCalendar classを使って江戸時代の日付を元号表示 (しようと) する (がエラーになる)

PS > [CultureInfo] $culture = [CultureInfo]::New("ja-JP");
PS > [Globalization.JapaneseCalendar] $culture.DateTimeFormat.Calendar = [System.Globalization.JapaneseCalendar]::new();
PS > ([Datetime]'1865/05/01').ToString('ggy年', $culture);

"2" 個の引数を指定して "ToString" を呼び出し中に例外が発生しました: "指定された引数は、有効な値の範囲内にありません。
パラメーター名:時間値が年号の範囲を超えています。"
発生場所 行:3 文字:1
+ ([Datetime]'1865/05/01').ToString('ggy年', $culture);
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [], MethodInvocationException
    + FullyQualifiedErrorId : ArgumentOutOfRangeException

エラーになりました

指定された引数は、有効な値の範囲内にありません。パラメーター名:時間値が年号の範囲を超えています。 とのことなのでこの期に及んでJapaneseCalendar Classの仕様を調べます

JapaneseCalendar Class (System.Globalization) | Microsoft Docs

This class handles dates from September 8 in the year Meiji 1 (in the Gregorian calendar, September 8, 1868). Although the Japanese calendar was switched from a lunar calendar to a solar calendar in the year Meiji 6 (1873 of the Gregorian calendar), this implementation is based on the solar calendar only.

どっとはらい

2019年の抱負の進捗状況 (5月7日時点)

この記事は自分向けの記事です

もうちょっと頻繁にblogを更新する

robert.kimata.infoドメインのweblogとの使い分けを考えつつも、一応先月は1本記事を掛けたので、まあいいかくらいの感覚です

blogの更新を目標とはしていますが、義務として更新を始めると途端にやる気がなくなりますし、知ったかぶりをして間違った記事を書き始めたりしますので、書くことがなかった月は正しく書くことがなかったとして処理しております

体重58kgまで落とし、維持する

やっとリバウンドが収まりつつあり、現時点で先月と同等の65kgを維持出来ました

とは言えには61.65kgだった体重が3.3kg程増えていますので、再び体重を減らすところから始めないといけません

経験上、一度減量していると暫くの間は体がそれに慣れていてリバウンドが始まってから同じ方法で減量してもなかなか体重が減らなくなると知っているので何か新しい手を考えないといけません

HTML LS Developer's Editionを一通り読む

5月の連休が明けたので予定通りそろそろ読み始めるつもりです

来月頭あたりに何らかの出力を始められればと思っています

情報処理安全確保支援士を受験する

また秋に頑張りましょう

……今から

しかし、合格したい試験は情報処理安全確保支援士なのですが、現在の私の知識や業務内容と合っていないのでのでそれなりに勉強せねばならず (合格したいならすれば良いだけなのですが) そこがなかなか苦痛です

どうしたものか

<s>未解決: </s>Android版Google Chromeは本文が245文字以上か未満かで文字サイズが変わる、そして245文字以上の場合で`position: absolute;`のstyleを持つ文字サイズは小さくなる

本記事は不具合の再現手順を説明するだけで解決方法の説明はありません

meta要素のviewportを設定することで問題が解消することが分かりました

以下、憶測ですが、スマートフォンなどの小さい画面で表示し、meta要素のviewportがない場合、内部的にviewport相当の設定され、かつ、その時特定の設定 (position: absolute;のstyle) を持つ文字にはその設定が有効になっていないため、文字サイズが変化するものと思われます

要点を箇条書きに

記事名の通りですが、我ながら何を言っているか大変分かりにくいので箇条書きにしてみます

  1. 以下をAndroidGoogle Chromeで確認した
  2. Desktop版Google ChromeでもデベロッパーモードにしてAndroidのモードにすると確認できる
  3. 本文 (Body要素内のtext node)が合計245文字以上か未満かで文字サイズが変わる
  4. この244文字/245文字の境界は、ASCII文字でもマルチバイト文字でも変わらない
  5. 245文字以上の場合で position: absolute; のstyleを持つ文字は小さくなる

やっぱりわかりにくいです

Test Case

244 Characters in body and position absolute contents text.

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <title>244 Characters in body and position absolute contents text.</title>
    <style>
    p::before {
      position: absolute;
      content: 'ABCDEFGHIJ ';
    }
    </style>
  </head>
  <body>
    <p title='Char 001-100'>1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890</p>
    <p title='Char 101-200'>1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890</p>
    <p title='Char 201-244'>12345678901234567890123456789012345678901234</p>
  </body>
</html>

245 Characters in body and position absolute contents text.

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <title>245 Characters in body and position absolute contents text.</title>
    <style>
    p::before {
      position: absolute;
      content: 'ABCDEFGHIJ ';
    }
    </style>
  </head>
  <body>
    <p title='Char 001-100'>1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890</p>
    <p title='Char 101-200'>1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890</p>
    <p title='Char 201-245'>123456789012345678901234567890123456789012345</p>
  </body>
</html>

これをDesktop版Google Chrome検証 (I)で表示してAndroid版として描画すると以下の様になります

f:id:rh-kimata:20190411212510p:plain

ちなみに、本文がASCII互換以外の文字、例えば漢字で 一二三四五六七八九〇... となっている場合も245文字以上か未満かで同じ現象が起こります

そもそも何でこんなことを調べたのか

元は別サイトで p 要素を li 要素みたいにカウンターを付けたくてそういうCSSを書いて AndroidGoogle Chromeで表示してみたら content: counter(paragraph) ". "; として生成したカウンターが読めないほど小さく表示され、色々調査した結果行きつきました

とりあえず、Google Chromeのバグっぽいので良かった、俺のせいじゃないと言う事で今回は良しとします (良くない)

Windowsに令和のレジストリィを追加するPowerShell

昨日、次の元号の令和が公開されたこともあってか、 Windows 10 April 2018 Updateで追加された和暦のレジストリィの話 - 木俣ロバート久の覚書 - Hatena Blog へのアクセスが増えているようですので、令和のレジストリィを追加するPowerShellスクリプトを書いてみました

https://gist.github.com/rh-KIMATA/896b67928942566a9569bfa0c2ab0e18

# Get
Get-Item -Path 'HKLM:\SYSTEM\CurrentControlSet\Control\Nls\Calendars\Japanese\Eras';

# Add
New-ItemProperty -Path 'HKLM:\SYSTEM\CurrentControlSet\Control\Nls\Calendars\Japanese\Eras' -Name '2019 05 01' -Value '令和_令_Reiwa_R';

# Edit
Set-ItemProperty -Path 'HKLM:\SYSTEM\CurrentControlSet\Control\Nls\Calendars\Japanese\Eras' -Name '2019 05 01' -Value '令和_令_Reiwa_R';

# Remove
Remove-ItemProperty -Path 'HKLM:\SYSTEM\CurrentControlSet\Control\Nls\Calendars\Japanese\Eras' -Name '2019 05 01';


# Display
[CultureInfo] $culture = [CultureInfo]::New("ja-JP");
[Globalization.JapaneseCalendar] $culture.DateTimeFormat.Calendar = [System.Globalization.JapaneseCalendar]::new();
([Datetime]'2019/5/1').ToString('ggy年', $culture);

なお、2019-05-01までにWindows Updateで同等のレジストリィの更新が配布されると思いますので、 事前の試験をするなどの理由がない限り、不要な問題を起こさないようこのレジストリィ追加はお勧めしません

また、テスト等でレジストリィを追加した場合も Windows Updateの前には今回追加した値を削除して状態を元に戻しておくことをお勧めします


ちなみに、本日時点 (システム時刻も同じ) の自分のWindows 10端末では令和のレジストリィを追加したうえで以降の日付を和暦に変換すると令和の元号で表示がなされますが、厳密には現時点では改元はなされておりませんので、以降の日付も平成表記になるのが正しい動きになります

2019年の抱負の進捗状況 (4月2日時点)

この記事は自分向けの記事です

ニャオス

もうちょっと頻繁にblogを更新する

最近は robert.kimata.infoドメインのweblog ばかり更新しており、hatenablog の方は全く書いていません

上記weblogは日常の記録の垂れ流し、hatenablog の方は独立して読める記事として何かの話題を纏めたものとして使い分けるつもりではいるのですがなかなか両立できません

3月中の話題としてはSSH完全初心者がWindows 10にOpenSSHを入れてGitHubに接続するまでみたいなものもあるのですが、単なる記録の垂れ流しの域を出ておらず、単独記事に纏める所までは行っていません


日々の記録の垂れ流しと言う意味では、この記事もそうなるのですが、これすらhatenablogに書かなくなると完全に更新が止まるのでなんというか、死活監視用の定期報告くらいの感じでお読みください

体重58kgまで落とし、維持する

引き続きリバウンドを起こしていて現在体重が65kg前後になっています

昨年成功した減量と同じ方式を今年も継続しているのですが、体が飢餓状態に対応してしまったのかなかなか減らず今年に入ってから毎月1kgの割合で増えています

体脂肪率は11%程度、BMIは24なのでまだ健康的な範囲には入っているのですが、この調子だと遠からず肥満に突入するので焦り始めています

HTML LS Developer's Editionを一通り読む

予定通り停滞しており、5月の連休明けあたりから本格的に読み始める予定です

ただ、weblogを書き始めたことで仕様を (通してではなく) 部分的に読む機会は増えているので自分個人としてはHTML LSの知識は増えつつある状態です

情報処理安全確保支援士を受験する

そろそろ本腰入れて勉強しないといけませんので勉強しましょう (勉強していない人の台詞)