目次: マンガ紹介
久しぶりにお気に入りのマンガ紹介シリーズ。短めの完結作品を2つ。
目次: Linux
簡単なドキュメントやメモはMarkDownで書くことが多いですが、気合を入れた文章にはやや不向きで、図表を入れ始めた辺りから表現力不足が辛くなってきます。
MarkDownで強行突破しても良いですが、より表現力がある主にドキュメント向けのマークアップテキスト……となると、太古から続くTeX、最近だとAsciiDoc、reST(reStructured Text)、Sphinx などが覇権を争っているようです。
私は良し悪しを語るほどマークアップテキストに詳しくないですし、特にAsciidocでなければダメってこともなくて、好きなものを使えば良いと思いますが、今回は訳あってAsciidocを使います。
マークアップテキストの読み書きは普段お使いのテキストエディタを使えば良いです。しかしプレビューはテキストエディタではできないことが多く、ちょっと困ります。Asciidocのプレビュー環境として、
私はこの2つを使うことが多いです。下記に設定方法のメモを残しておきます。
ChromeウェブストアからAsciidoctorと検索するだけです。
Chrome AsciiDoctor.js Live Preview
あとはオプションの「オン」と「ファイルのURLへのアクセスを許可する」を有効にすると、
Chromeに *.adocのファイルをドラッグ&ドロップなどして開けば、プレビュー画面が出るはずです。内容を更新すると自動的にプレビューも更新されます。
これでテキストエディタで編集しつつ、Chromeからローカルディスク上のAsciidocがプレビューできます。簡単で良いですね。
VSCodeのExtensionsからasciidocと検索するだけです。
フォルダ内の *.adocファイルを開いて、Ctrl+Shift+Vを押すとプレビュー画面が出るはずです。2分割して右側に出せるので便利ですね。
これでVSCodeからローカルディスク上のAsciidocを編集しながらプレビューできます。これも簡単ですね。
目次: Linux
前回(2022年9月3日の日記参照)、Asciidocのプレビュー環境の設定方法を紹介(Chrome or VSCode)しました。今回はさらにAsciidocの便利機能とそのプレビューを使えるようにします。
ちなみにこのプレビュー機能はVSCode限定となります。Chromeでも使えると便利なんですけどね……。
Asciidocにはasciidoctor-diagram extensionがあり、他のツール向けテキストを *.adoc内に記述すると、ツールと連携して自動的に画像を生成し、自動的に文書内に埋め込む機能があります。
例えばUMLをテキストで記述するPlatUMLと連携する場合は、
= Hello
== World
This is hello world.
[plantuml]
----
@startuml
A -> B : ccc
@enduml
----
このように [plantuml] の後にPlantUML向けのテキストを書きます。プレビューや他形式に変換した場合、PlantUMLのテキストの代わりにPlantUMLが出力した画像が表示されていることがわかると思います。
各ツールを起動して画像に変換&リネームしてAsciidocに画像表示の記述を書く方法と比べれば、利便性は天と地の差でしょう。
AsciidoctorやextensionはRubyで実装されているため、Rubyをインストールする必要があります。
Rubyの公式サイト(サイトへのリンク)を見る限り、Windows向けインストールにはRubyInstallerツール(サイトへのリンク)がおススメのようです。
c:\app>ruby --version ruby 3.1.2p20 (2022-04-12 revision 4491bb740a) [x64-mingw-ucrt]
RubyInstallerはPATHの設定も自動的に行います。インストール後、コマンドプロンプトを起動してrubyを起動できればインストール成功です。
Rubyをインストールしたら、asciidoctor-diagramをインストールします。同時にasciidoctorもインストールされます。
C:\app>gem install asciidoctor-diagram Fetching asciidoctor-diagram-plantuml-1.2022.5.gem Fetching asciidoctor-diagram-ditaamini-1.0.3.gem Fetching asciidoctor-diagram-2.2.3.gem Fetching asciidoctor-2.0.17.gem Successfully installed asciidoctor-diagram-plantuml-1.2022.5 Successfully installed asciidoctor-diagram-ditaamini-1.0.3 Successfully installed asciidoctor-2.0.17 Successfully installed asciidoctor-diagram-2.2.3 Parsing documentation for asciidoctor-diagram-plantuml-1.2022.5 Installing ri documentation for asciidoctor-diagram-plantuml-1.2022.5 Parsing documentation for asciidoctor-diagram-ditaamini-1.0.3 Installing ri documentation for asciidoctor-diagram-ditaamini-1.0.3 Parsing documentation for asciidoctor-2.0.17 Installing ri documentation for asciidoctor-2.0.17 Parsing documentation for asciidoctor-diagram-2.2.3 Installing ri documentation for asciidoctor-diagram-2.2.3 Done installing documentation for asciidoctor-diagram-plantuml, asciidoctor-diagram-ditaamini, asciidoctor, asciidoctor-diagram after 4 seconds 4 gems installed
コマンドプロンプトからGemで一発インストール可能で便利です。asciidoctorはRubyのbinディレクトリの配下にスクリプトが配置されるようです。
c:\app>asciidoctor --version Asciidoctor 2.0.17 [https://asciidoctor.org] Runtime Environment (ruby 3.1.2p20 (2022-04-12 revision 4491bb740a) [x64-mingw-ucrt]) (lc:Windows-31J fs:UTF-8 in:UTF-8 ex:UTF-8)
インストール後、コマンドプロンプトからasciidoctorを起動できればインストール成功です。
今回はPlantUMLとの連携を試しますので、PlantUMLの環境も整えます。PlantUMLの実行にはJavaが必要です。
PlantUMLを実行するだけならJRE(Java Runtime Environment)で十分ですが、もし今後Java言語での開発を行う予定があれば、OpenJDKをインストールした方が良いです。私はJavaも使うので Oracle OpenJDKのダウンロードサイト からOpenJDKをダウンロードしました。現状の最新版は18.0.2.1でアーカイブのファイル名はopenjdk-18.0.2.1_windows-x64_bin.zipです。
ダウンロードしたzipファイルを展開すると、jdk-18.0.2.1のような名前のディレクトリがあるので適当な場所に移動(= インストールに相当)します。この際にディレクトリ名をリネームしても良いです。
JDKを適当な場所に配置したらPATHを設定します。例えばJDKをc:\app\jdkにインストールしたとすると、
こんな感じでPATHに追加します。
c:\app>java -version openjdk version "18.0.2.1" 2022-08-18 OpenJDK Runtime Environment (build 18.0.2.1+1-1) OpenJDK 64-Bit Server VM (build 18.0.2.1+1-1, mixed mode, sharing)
PATH追加後、コマンドプロンプトからjavaを起動できればインストール成功です。
VSCode側のプレビュー設定も変更する必要があります。
まずはAsciiDocの設定ページを開いてasciidoctor_jsによるプレビュー生成を無効化します。asciidoctor_jsはasciidoctor-diagramに対応していないからです。プレビュー画面がエラー表示になるかもしれませんが、気にしないでください。
次にasciidoctorがasciidoctor-diagramを使うように設定します。具体的には起動時のオプションに -r asciidoctor-diagramを追加します。
今までの設定がうまくいっているなら、プレビュー画面が更新されてPlantUMLのテキストの代わりにUMLの画像が表示されるはずです。
手順として書いてみると思ったより長いですが、asciidoctor-diagramはなかなか便利です。描画ツールでUMLを書いて、画像にしてAsciidocに埋め込んで……みたいなウザい作業とはお別れです。
画像を使わずテキストで記述するので、差分取得も容易です。画像ファイルで往々にして発生する、原稿がどっか行って更新できなくなった、などのトラブルも防いでくれることでしょう。
目次: C言語とlibc
コンピュータで負の値を表現するときは「2の補数を使います」と習った方は多いと思います。C言語もそうでしょうか?
答えは「いいえ。そして、はい。」です。
「いいえ。」の方は、整数型intやlongです。これらの型は2の補数とは限りません。sign and magnitudeや、1の補数表現が許されます。符号と値だけでなく、意味のないビット(パディングビット)の存在も許されています。C11 committee draftの6.2.6.2の定義を見ましょう。
6.2.6.2 Integer types 1 (unsigned系の話なので省略) 2 For signed integer types, the bits of the object representation shall be divided into three groups: value bits, padding bits, and the sign bit. There need not be any padding bits; signed char shall not have any padding bits. There shall be exactly one sign bit. Each bit that is a value bit shall have the same value as the same bit in the object representation of the corresponding unsigned type (if there are M value bits in the signed type and N in the unsigned type, then M <= N). If the sign bit is zero, it shall not affect the resulting value. If the sign bit is one, the value shall be modified in one of the following ways: - the corresponding value with sign bit 0 is negated (sign and magnitude); - the sign bit has the value -(2^M ) (two’s complement); - the sign bit has the value -(2^M - 1) (ones’ complement). Which of these applies is implementation-defined, as is whether the value with sign bit 1 and all value bits zero (for the first two), or with sign bit and all value bits 1 (for one's complement), is a trap representation or a normal value. In the case of sign and magnitude and ones’ complement, if this representation is a normal value it is called a negative zero.
この節は何を言っているのかすこぶるわかりにくいので、ざっくり和訳と具体例を載せます。わかりやすくなっていると嬉しいです。間違いがあったら教えていただけると嬉しいです。
6.2.6.2 Integer types 1省略 2符号付き整数型の場合、オブジェクト表現のビットは、値ビット、パディングビット、符号ビットの3つのグループに分けなければならない。 パディングビットは持っても持たなくても構わないが、符号付きchar型はパディングビットをもってはならない。符号ビットは1ビットで なければならない。値ビットの各ビットは、対応する符号なし型のオブジェクト表現と同じビットでなければならない。 (もし符号付き型にMビットの値ビットがあって、符号なし型にNビットの値ビットがあるなら、M <= Nである) 符号ビットが0なら結果の値には影響しない。符号ビットが1なら、値は次のいずれかの方法で修正されなければならない。 - 符号ビットが0の時の値がそのまま負の値(sign and magnitude) (例) 10000000 -> -0 ←負のゼロ、もしくはトラップ 10000001 -> -1 10000010 -> -2 ... 11111101 -> -125 11111110 -> -126 11111111 -> -127 - 符号ビットが -(2^M) の値(2の補数) (例) 10000000 -> -128 10000001 -> -127 10000010 -> -126 ... 11111101 -> -3 11111110 -> -2 11111111 -> -1 - 符号ビットが -(2^M - 1) の値(1の補数) (例) 10000000 -> -127 10000001 -> -126 10000010 -> -125 ... 11111101 -> -2 11111110 -> -1 11111111 -> -0 ←負のゼロ、もしくはトラップ このうちどれを適用するかは実装依存である。符号ビットが1で値ビットが全て0(sign and magnitudeと2の補数のとき)、 もしくは符号ビットと値ビットが全て1(1の補数のとき)を持つ値が、トラップ表現か正常な表現かについても同様に実装依存である。 sign and magnitudeと1の補数の場合は、この表現を正常な値とするなら、その値は「負のゼロ(negative zero)」と 呼ばれる。
負の値を表現する方法はいくつかあって、今はほぼ全てのアーキテクチャで2の補数が一般的です。しかし古いアーキテクチャではsign and magnitudeや1の補数を採用していたものがあったのかもしれませんね。
「はい。」の方は、C99で登場した新しい整数型(intN_tのような型)です。こちらは2の補数、パディングビットなしの割り切った仕様です。しかし一般的に良く使われているint8_t, int16_t, int32_tが必ず使えるとは限らないことに注意が必要です。
7.20.1.1 Exact-width integer types 1 The typedef name intN_t designates a signed integer type with width N, no padding bits, and a two's complement representation. Thus, int8_t denotes such a signed integer type with a width of exactly 8 bits. 2 The typedef name uintN_t designates an unsigned integer type with width N and no padding bits. Thus, uint24_t denotes such an unsigned integer type with a width of exactly 24 bits. 3 These types are optional. However, if an implementation provides integer types with widths of 8, 16, 32, or 64 bits, no padding bits, and (for the signed types) that have a two's complement representation, it shall define the corresponding typedef names. (ざっくり和訳) 1型名intN_tは、幅N、パディングビットなし、2の補数表現の符号付き整数型であることを示す。 したがってint8_tは、幅が正確に8ビットの符号付き整数型を示す。 2型名uintN_tは、幅N、パディングビットなし、2の補数表現の符号なし整数型であることを示す。 したがってuint24_tは、幅が正確に24ビットの符号付き整数型を示す。 3これらの型はオプションである。しかし実装が8, 16, 32, 64ビット、パディングビットなし、 2の補数表現(符号付きの場合)を持つ整数型を提供する場合は、対応するtypedef名を定義しなければならない。
現代のアーキテクチャに合わせてsign and magnitudeと1の補数をバッサリ切った雰囲気を感じます。仕様で気になるのは3ですね。optionalで実装依存とおっしゃっています。これは困ります……。
確実を期すならint_least32_t(規格上requiredなので)を使えば良いですが、最低でも32bitだと仕様として不便です。本当は何bitですか?を求める処理を書かねばならないでしょう。名前も長くて使いにくいですし。
< | 2022 | > | ||||
<< | < | 08 | > | >> | ||
日 | 月 | 火 | 水 | 木 | 金 | 土 |
- | 1 | 2 | 3 | 4 | 5 | 6 |
7 | 8 | 9 | 10 | 11 | 12 | 13 |
14 | 15 | 16 | 17 | 18 | 19 | 20 |
21 | 22 | 23 | 24 | 25 | 26 | 27 |
28 | 29 | 30 | 31 | - | - | - |
合計:
本日: