簡単なドキュメントやメモは 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 を編集しながらプレビューできます。これも簡単ですね。
前回(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 に埋め込んで……みたいなウザい作業とはお別れです。
画像を使わずテキストで記述するので、差分取得も容易です。画像ファイルで往々にして発生する、原稿がどっか行って更新できなくなった、などのトラブルも防いでくれることでしょう。
コンピュータで負の値を表現するときは「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 です?という処理を書かねばならないでしょう。名前も長くて使いにくいですし。
ノート PC 用の CPU の動作周波数は多数設定できましたが、デスクトップ用の CPU はどんなもんでしょうか?電源オプション - プロセッサの電源管理 - 最大のプロセッサの状態、もしくはプロセッサパフォーマンスの向上モードを変更し、何段階の動作周波数が設定できるか試します。家のデスクトップ PC の CPU は Ryzen 7 2700、OS は Windows 10 です。
ちなみに初期状態だと TurboBoost を ON/OFF する設定が表示されません。設定変更するためにはレジストリを変更する必要があります(2020年 7月 9日の日記参照)。
結果はこんな感じ。動作周波数、フル稼働時の CPU 温度(稼働 1分くらい、リテールクーラー使用)、CPU-Z の Score を示します。Score は CPU-Z のマルチスレッドベンチマークで何点くらい出るか?という数字です。CPU 性能の参考まで。
ノート PC の Core i5 8250U は 7段階ありましたが、デスクトップ PC 向けは 4段階でした。微妙な数ですね、多くも少なくもないです。デスクトップ PC はノート PC ほど細かく節電する必要もないし、動作周波数の設定を多くする必要はないのでしょう。
今日は中秋の名月だそうです。手持ちのコンデジ(CASIO EX-ZR1300)のズームを最大にして月を撮影しました。
満月は非常に明るくて、ISO 80、シャッタースピード 1/50 のような普通なら夜の写真に使わない暗い設定でもばっちり映りました。月のクレーターを認識できるくらいの写真が撮れます。
三脚を使わなかった割にはブレなかったと思います。カメラの手ブレ補正スゴイな〜。プレビューではもっと鮮明に映ったように見えたものの、切り抜いてみるとややボンヤリしていますね……。ズームの倍率も光学 12.5倍ですし、撮影者の腕的にもこんなもんですかね。
私が今使っているグラフィックスカードは MSI 製で、MSI Afterburner というオーバークロック用ツールが使えます(MSI Afterburner 公式サイトへのリンク)。他社製のグラフィクスカードでも類似のツール(ASUS GPU TweakII など)が公開されていると思います。
ツールの名前からしてコアクロックやメモリバスクロックを上げるのが主な目的だと思いますが、逆に下げる方向に使うこともできます。
MSI Afterburner でクロックを下げる方向に設定
GeForce RTX 3060 の性能をフルに必要とするゲームばかりではありませんし、あえてクロックを下げて負荷軽減、省エネ&温度を低目に保てたら良いな〜くらいの期待です。残念ながら GPU 温度を見ている限りでは、効き目はあまりなさそうですが……まあ気休めに。
ノート PC は下記のようなセキュリティ設定で運用している人が多いと思います。会社の PC もこういう設定が多いと思います。
この設定はセキュリティ上は素晴らしいです。ただし展示で使うときはちょっと困るんですよね……。自分のアカウントで画面ロックが掛かると、当然自分しか解除ができませんから自分が PC の前を離れられなくなります。
展示のためだけにセキュリティ設定を緩めるのも何だかイマイチですし、一時的に使える方法はないか?と思ったらありました。ヒントは PowerPoint の全画面表示で、スライドショーを開始すると Windows の画面ロックは発動しないのです。ほほう。
PowerPoint に画面ロックの妨害ができるなら、そこらのアプリでも画面ロックの妨害を実現できるはずです。
どの Windows の API を呼んだらいいのか?と思って調べていましたが、JavaScript で手軽に実現する手段がありました。今のところ Chrome 限定っぽいですが、
function addEvent(obj, name_event, func_event)
{
var func_prev = obj[name_event];
if (func_event == null) {
return;
}
if (func_prev == null) {
obj[name_event] = function() { func_event(); };
} else {
obj[name_event] = function() { func_prev(); func_event(); };
}
}
function f_resolve()
{
var statusElem = document.getElementById('status');
statusElem.textContent += 'Success. ';
}
function f_reject()
{
var statusElem = document.getElementById('status');
statusElem.textContent += 'Rejected. ';
}
function f_release()
{
var statusElem = document.getElementById('status');
statusElem.textContent += 'Released. ';
}
function testWakeLock()
{
var statusElem = document.getElementById('status');
var isSupported = false;
if ('wakeLock' in navigator) {
isSupported = true;
statusElem.textContent += 'Support wakeLock. ';
} else {
statusElem.textContent += 'Not support wakeLock. ';
return;
}
var wakeLock = null;
try {
wakeLock = navigator.wakeLock.request('screen');
} catch (err) {
statusElem.textContent += `${err.name}, ${err.message}`;
}
statusElem.textContent += 'Request. ';
wakeLock.then(f_resolve, f_reject);
wakeLock.addEventListener('release', f_release);
}
addEvent(window, "onload", testWakeLock);
この画面起動ロック(MDN へのリンク)という機能を使うと、タブを切り替えたりしない限り画面ロックを妨害できるようです。
私の環境で試した限りでは、なぜか Release イベントが一切来ないのと、ブラウザをバックグラウンドに持っていくと動作が不安定(たまに効かない = 画面ロックしてしまう)ですが、一応効き目がありました。
画面起動ロックが効いているかどうかは powercfg を使うとわかります。管理者モードでコマンドプロンプトを起動し powercfg /requests と /requestsoverride を実行します(powercfg のヘルプ)。私の環境では /requests の方に表示されていました。
C:\Windows\system32>powercfg /requests DISPLAY: [PROCESS] \Device\HarddiskVolume3\Program Files\Google\Chrome\Application\chrome.exe Blink Wake Lock SYSTEM: なし。 AWAYMODE: なし。 実行: なし。 PERFBOOST: なし。 ACTIVELOCKSCREEN: なし。
先ほどのスクリプトを実行したタブを切り替えると、
C:\Windows\system32>powercfg /requests DISPLAY: なし。 SYSTEM: なし。 AWAYMODE: なし。 実行: なし。 PERFBOOST: なし。 ACTIVELOCKSCREEN: なし。
となるはず、です。
在宅勤務の時、会社の Windows ノート PC(常時コミュニケーション用のツールが入っている)がすぐに画面ロックしてしまって、コミュニケーションツールにアクセスしづらいのと非常にウザくて困ってました。画面ロックを無効にもできなくて困っていたんですが、画面起動ロックで画面ロックを妨害できるようになってだいぶ使いやすくなりました。
画面ロックを仕込んだページを作られたら、画面ロックできなくなるんですかね?どうなるんだろうな?(追記: ローカルファイルじゃないと動作しませんでした)まあ、時限式の画面ロックに頼って、PC の前から立ち去るような運用はそもそも論外なのですが……。
理屈は良いので動くものをくださいという、せっかちな方へお送りします。 動作するページへのリンクです。注意点はネットワーク上のサイトでは機能しません(Not support になります)ので、ローカルにダウンロードしてから開いてください。
不安な方はローカルに保存して開く前に中身をご確認ください。もしくは上記のスクリプトを見て&理解してご自身でページを作成くださいませ。
先日(2022年 9月 19日の日記参照)は JavaScript というか画面起動ロック API(Screen Wake Lock API)にて Windows PC の画面ロックを妨害する方法を紹介しました。
今回は Windows API(SetThreadExecutionState)を使って同様の機能を実現します。詳細は Microsoft の API ドキュメント(SetThreadExecutionState function (winbase.h) - Microsoft Learn)と、スリープに関する日本語の解説(システム スリープ条件 - Microsoft Learn)が参考になります。
そういえば Windows API のドキュメント、今は Microsoft Learn という名前になっていますね。昔は MSDN Online とか Microsoft Docs とか呼ばれてた気がしますが、統合されて消えてしまったのかな……?
さておきコードはこんな感じです。簡単すぎるのでわざわざ載せるまでもないですけども。
#include <iostream>
#include <windows.h>
#include <winbase.h>
int main()
{
EXECUTION_STATE r;
r = SetThreadExecutionState(ES_CONTINUOUS | ES_AWAYMODE_REQUIRED);
if (r == NULL) {
std::cout << "failed!" << std::endl;
}
std::string hoge;
std::cin >> hoge;
return 0;
}
アプリケーション実行中に powercfg でチェックすると、こんな風になるはずです。なお powercfg を実行するには管理者権限でコマンドプロンプトを起動する必要があります。アプリケーション名は適当に読み替えてください。
C:\Windows\system32>powercfg /requests DISPLAY: なし。 SYSTEM: なし。 AWAYMODE: [PROCESS] \Device\HarddiskVolume3\dat\projects\c\ConsoleApplication1\x64\Debug\ConsoleApplication1.exe 実行: なし。 PERFBOOST: なし。 ACTIVELOCKSCREEN: なし。
画面起動ロック API は DISPLAY というモードを要求していましたが、今回は AWAYMODE を要求しているので違うカテゴリに表示されています。もちろん API の引数を適切に変更すれば DISPLAY も要求できます。
画面ロックの妨害機能のユーザーは意外と多いです。前回挙げた PowerPoint の他に、Teams のような会議アプリケーション、メディアプレーヤーなども使っているようです。個人的に意外だったものとしてはセットアッププログラムです。
例えば、下記は Visual Studio のセットアップ中に powercfg を実行した結果です。
C:\Windows\system32>powercfg /requests DISPLAY: なし。 SYSTEM: なし。 AWAYMODE: なし。 実行: [PROCESS] \Device\HarddiskVolume3\Program Files (x86)\Microsoft Visual Studio\Installer\setup.exe Visual Studio インストーラー PERFBOOST: なし。 ACTIVELOCKSCREEN: なし。
普通はセットアップ中にスリープされることなんて想定していませんから、セットアップがエラーになる可能性があります。不都合が起きなかったとしても、スリープ中はセットアップが進みません。と、考えると時間がかかるセットアップ中にスリープを妨害するのは筋が通ってますね。
ニンテンドーのポイントが期限切れになるぞよ、というメールが来ていたのでゼルダの伝説スカイウォードソードに出てくるボム袋を模した巾着をもらいました。思っていたよりでかい。
ゼルダの伝説はほとんどやったことがなくて、家に届いた巾着を見ても何の模様かわからなかったのですが、奥さんに見せたら一発で「あ!ボム袋だ!」って気づいてました。ゲーム画面のキャプチャを観ると思っていたより再現度が高いです(ゲームのボム袋の方がもう少し背が低いくらい)。良いですね。
なぜかシューティングの練習で使うフロンガス缶のサイズと、この巾着のサイズが超ぴったりでした。フロンガス缶はそんなに種類があるわけじゃない(マルイ、レイラックス、サンダーシュート、ウッドランドがメジャーどころ?)し、同じ種類のガス缶を使っている人も多くて紛らわしいので、こういう個性的&コンパクトな袋はありがたいです。
メモ: 技術系?の話は Facebook から転記しておくことにした。色々と加筆修正。
管理者: Katsuhiro Suzuki(katsuhiro( a t )katsuster.net)
This is Simple Diary 1.0
Copyright(C) Katsuhiro Suzuki 2006-2021.
Powered by PHP 5.2.17.
using GD bundled (2.0.34 compatible)(png support.)