summaryrefslogtreecommitdiffhomepage
path: root/vhosts
diff options
context:
space:
mode:
authornsfisis <nsfisis@gmail.com>2025-04-20 19:22:05 +0900
committernsfisis <nsfisis@gmail.com>2025-04-20 19:22:05 +0900
commitc04b0c1ae786667808f2418673e8222626f4a6b2 (patch)
tree43b1f64bcb94718857a5a09153e3d3537a993020 /vhosts
parent01f5fc18dd9e9549daee2f45b5bbc6a121f687a3 (diff)
downloadnsfisis.dev-c04b0c1ae786667808f2418673e8222626f4a6b2.tar.gz
nsfisis.dev-c04b0c1ae786667808f2418673e8222626f4a6b2.tar.zst
nsfisis.dev-c04b0c1ae786667808f2418673e8222626f4a6b2.zip
feat(blog/content): new post /posts/2025-04-20/trick-2025-most-ruby-on-ruby-award/
Diffstat (limited to 'vhosts')
-rw-r--r--vhosts/blog/content/posts/2025-04-20/trick-2025-most-ruby-on-ruby-award.dj198
-rw-r--r--vhosts/blog/content/posts/2025-04-20/trick-2025-most-ruby-on-ruby-award/screenshot.pngbin0 -> 142365 bytes
-rw-r--r--vhosts/blog/nuldoc.toml2
-rw-r--r--vhosts/blog/public/atom.xml10
-rw-r--r--vhosts/blog/public/posts/2025-04-20/trick-2025-most-ruby-on-ruby-award/index.html286
-rw-r--r--vhosts/blog/public/posts/2025-04-20/trick-2025-most-ruby-on-ruby-award/screenshot.pngbin0 -> 142365 bytes
-rw-r--r--vhosts/blog/public/posts/atom.xml10
-rw-r--r--vhosts/blog/public/posts/index.html15
-rw-r--r--vhosts/blog/public/tags/conference/atom.xml10
-rw-r--r--vhosts/blog/public/tags/conference/index.html15
-rw-r--r--vhosts/blog/public/tags/index.html24
-rw-r--r--vhosts/blog/public/tags/ruby/atom.xml10
-rw-r--r--vhosts/blog/public/tags/ruby/index.html15
-rw-r--r--vhosts/blog/public/tags/rubykaigi/atom.xml19
-rw-r--r--vhosts/blog/public/tags/rubykaigi/index.html66
-rw-r--r--vhosts/blog/public/tags/trick/atom.xml19
-rw-r--r--vhosts/blog/public/tags/trick/index.html66
17 files changed, 759 insertions, 6 deletions
diff --git a/vhosts/blog/content/posts/2025-04-20/trick-2025-most-ruby-on-ruby-award.dj b/vhosts/blog/content/posts/2025-04-20/trick-2025-most-ruby-on-ruby-award.dj
new file mode 100644
index 00000000..d9463d1a
--- /dev/null
+++ b/vhosts/blog/content/posts/2025-04-20/trick-2025-most-ruby-on-ruby-award.dj
@@ -0,0 +1,198 @@
+---
+[article]
+uuid = "039b3dff-3b75-46b7-a731-9a3a0ff8e21f"
+title = "RubyKaigi 2025 の TRICK で入賞した"
+description = "RubyKaigi 2025 で開催された TRICK において、『最もRuby on Ruby賞』として審査員賞をいただいた。"
+tags = [
+ "conference",
+ "ruby",
+ "rubykaigi",
+ "trick",
+]
+
+[[article.revisions]]
+date = "2025-04-20"
+remark = "公開"
+---
+{#intro}
+# はじめに
+
+2025-04-16 から 2025-04-18 にかけて開催された [RubyKaigi 2025](https://rubykaigi.org/2025/) に参加した (私が参加できたのは 1日目の 2025-04-16 のみ)。
+
+地元松山での大規模なカンファレンスということでスケジュールに無理を言わせて 1日目だけでもと参加したのだが、そこで開催された [TRICK 2025](https://github.com/tric/trick2025) で審査員賞をいただいた。
+
+この記事では、提出した作品の紹介と解説をおこなおうと思う。
+
+
+{#trick}
+# TRICK とは
+
+TRICK とは RubyKaigi で不定期に開催されているコンテストで、Ruby で書かれた「変わった」コードを表彰する。早い話が [IOCCC](https://www.ioccc.org/) の Ruby 版である。
+
+存在を知ってから次こそは出したいと思っていたところ、ちょうど RubyKaigi の地元開催と被ったのでこれ幸いとエントリーした。
+
+
+{#my-work}
+# 作品紹介
+
+今回頂いたのは審査員賞の一つ eto award (公式の賞の名前に合わせて敬称略) で、"Most Ruby-on-Ruby" Award (『最もRuby on Ruby賞』) として受賞した (IOCCC と同じく、それぞれの賞に個別の名前が付く)。
+
+ソースコード等はこちら: https://github.com/tric/trick2025/tree/main/10-nsfisis
+
+今回の TRICK では `ruby.wasm` の使用が認められている。
+
+> * *(NEW)* You can use [ruby.wasm](https://github.com/ruby/ruby.wasm).
+
+適当に HTTP サーバを立てて [`index.html`](https://github.com/tric/trick2025/blob/main/10-nsfisis/index.html) を開くと、次のように [`entry.rb`](https://github.com/tric/trick2025/blob/main/10-nsfisis/entry.rb) の内容が表示される。
+
+![ブラウザで表示された index.html のレンダリング結果。entry.rb の内容がシンタックスハイライトされて表示されており、英単語や記号に振り仮名が振られている](/posts/2025-04-20/trick-2025-most-ruby-on-ruby-award/screenshot.png)
+
+自身のソースコードを出力するプログラム、いわゆる quine の亜種になっている。
+
+しかし、このプログラムは単にソースコードをそのまま出力するのではなく、
+
+* シンタックスハイライトして、
+* 英単語や記号に振り仮名を振って、
+* HTML で、
+
+表示している。つまり、Ruby プログラムにルビを振った作品である。例えば、先頭の2行目の `require` は次のような HTML で構成されている。
+
+```html
+<ruby class="IDENTIFIER">require<rp class="">(</rp><rt class="">リクワイア</rt><rp class="">)</rp></ruby>
+```
+
+順に使ったテクニックを解説していく。
+
+{#quine}
+## Quine
+
+改めて quine について説明する。Quine とは、自身のソースコードを出力するようなプログラムである。Ruby では様々な方法で quine を書くことができるが、この作品で使っている基本形は以下のようなものである。
+
+```ruby
+eval $s=<<'EOS'
+print "eval $s=<<'EOS'\n"
+print $s
+print "EOS\n"
+EOS
+```
+
+変数 `$s` に `print` の 3行分が入っており、それに加えて上下の1行ずつを出力すれば元のソースコードが得られる。実際には `$s` を加工してシンタックスハイライトや振り仮名を振ることになる。
+
+{#syntax-highlight}
+## シンタックスハイライト
+
+シンタックスハイライトは、トークナイズとトークン種別に応じた色付けの2段階からなる。
+
+トークナイズには Ruby 3.4 からデフォルトのパーサになった [Prism](https://github.com/ruby/prism) を利用している。
+`Prism.lex()` を使うとトークナイズができるので、トークンに付いているソースコード位置の情報を使いつつ元のソースコードを復元する。
+
+```ruby
+y = 1 # 現在の行
+x = 0 # 現在の列
+Prism.lex($s).value[..-2].each {|t, *|
+ l = t.location
+ r = l.start_line # トークンの開始行
+ if y < r # 改行が必要なら
+ p "\n" * (r - y) # 改行を挿入して
+ x = 0 # 列の先頭へ戻る
+ end
+ c = l.start_column # トークンの開始列
+ if x < c # 空白が必要なら
+ p " " * (c - x) # 空白を挿入
+ end
+ p ruby(t) # トークン本体を出力
+ y = l.end_line # 現在行を更新
+ x = l.end_column # 現在列を更新
+}
+```
+
+補足: 変数名がやたら短いのは、このあとの振り仮名データの量を削減するため。
+
+トークン種別に応じた色付けは CSS でおこなっている。出力する HTML のクラス名に `Prism::Token#type` を指定しておいて、`index.html` でそれぞれのクラスにスタイルを当てた。
+
+```html
+ <style>
+ /* ... */
+
+ .COMMENT {
+ color: #777;
+ font-style: italic;
+ }
+
+ .CONSTANT, .GLOBAL_VARIABLE, .INSTANCE_VARIABLE, .IDENTIFIER {
+ color: #088;
+ }
+
+ /* ... */
+ </style>
+```
+
+トークン種別の列挙にはそれなりに文字数を使ってしまうのだが、今回の TRICK のレギュレーションでは `index.html` にサイズ制限がなかったので好きに色を付けることができた。
+
+{#ruby-text}
+## 振り仮名
+
+それぞれの英単語や記号に対応した振り仮名のデータは、プログラム中に埋め込まれている。
+
+```ruby
+def rt(t)
+ r = {
+ :"&&" => "1136",
+ :"=" => "04199275",
+ :"||" => "623147",
+ :$s => "41750825",
+ :* => "111775",
+ # ...
+ type: "310455",
+ utf_8: "70923803920853080440",
+ value: "48746992",
+ x: "08351525",
+ y: "7904",
+ }
+ kana(
+ r[:"#{t.type}"] ||
+ r[s = :"#{t.value.downcase}"] ||
+ s.end_with?(":") && r[:"#{s[..-2]}"] ||
+ nil
+ )
+end
+```
+
+トークンの種類 (`t.type`) またはトークンの文字列表現そのもの (`t.value.downcase`) を使ってテーブルを引いて振り仮名へ変換している。
+このテーブルのキー部分そのものにも振り仮名を振るために、トークンが `:` で終わっていれば `:` を取り除いて振り仮名を得ている (例: `"value:"` → `"value"` → `"48746992"`)。
+
+このテーブルはサイズ制限を突破するために圧縮されており、`kana()` 関数で展開される。
+
+```ruby
+def kana(s)
+ s
+ &.scan(/.{2}/)
+ &.map{|c| (0x30A0 + c.to_i).chr(Encoding::UTF_8)}
+ &.*("")
+end
+```
+
+例えば `value` に対応する振り仮名データ `"48746992"` であれば、次のような変換を経て振り仮名へと展開される。
+
+```ruby
+ s
+ # => "48746992"
+ &.scan(/.{2}/)
+ # => ["48", "74", "69", "92"]
+ &.map{|c| (0x30A0 + c.to_i).chr(Encoding::UTF_8)}
+ # => ["バ", "リ", "ュ", "ー"]
+ &.*("")
+ # => "バリュー"
+```
+
+これは後で気付いたのだが、Ruby は多倍長整数が扱えるので `"48746992"` のようなデータは単に `48746992` と書けばよかった。
+`kana()` 関数が多少長くはなるが、振り仮名データの数 x 2 バイト分サイズが減るのでこちらの方が短くなる。
+サイズ制限の都合で振り仮名を振るのを諦めた記号もあったのでもったいない。
+
+{#outro}
+# おわりに
+
+本っ当に取りたかったので心から嬉しいです。
+全部で 3作提出したのですが、他の 2つも選外佳作として選出していただけた上、そのうちの "Least Truthful" については最後に Matz 氏から言及があり、審査員賞と合わせて望外の栄誉となりました。
+
+ありがとうございました!
diff --git a/vhosts/blog/content/posts/2025-04-20/trick-2025-most-ruby-on-ruby-award/screenshot.png b/vhosts/blog/content/posts/2025-04-20/trick-2025-most-ruby-on-ruby-award/screenshot.png
new file mode 100644
index 00000000..0bfe3be9
--- /dev/null
+++ b/vhosts/blog/content/posts/2025-04-20/trick-2025-most-ruby-on-ruby-award/screenshot.png
Binary files differ
diff --git a/vhosts/blog/nuldoc.toml b/vhosts/blog/nuldoc.toml
index 69283171..7dec83c2 100644
--- a/vhosts/blog/nuldoc.toml
+++ b/vhosts/blog/nuldoc.toml
@@ -42,9 +42,11 @@ python = "Python"
python3 = "Python 3"
ruby = "Ruby"
ruby3 = "Ruby 3"
+rubykaigi = "RubyKaigi"
rust = "Rust"
scala = "Scala"
scalamatsuri = "ScalaMatsuri"
+trick = "TRICK"
vim = "Vim"
wasm = "WebAssembly"
wireguard = "WireGuard"
diff --git a/vhosts/blog/public/atom.xml b/vhosts/blog/public/atom.xml
index aa931da7..c1c128f2 100644
--- a/vhosts/blog/public/atom.xml
+++ b/vhosts/blog/public/atom.xml
@@ -7,7 +7,15 @@
<author>
<name>nsfisis</name>
</author>
- <updated>2025-04-12T00:00:00+09:00</updated>
+ <updated>2025-04-20T00:00:00+09:00</updated>
+ <entry>
+ <id>urn:uuid:039b3dff-3b75-46b7-a731-9a3a0ff8e21f</id>
+ <link rel="alternate" href="https://blog.nsfisis.dev/posts/2025-04-20/trick-2025-most-ruby-on-ruby-award/"></link>
+ <title>RubyKaigi 2025 の TRICK で入賞した</title>
+ <summary>RubyKaigi 2025 で開催された TRICK において、『最もRuby on Ruby賞』として審査員賞をいただいた。</summary>
+ <published>2025-04-20T00:00:00+09:00</published>
+ <updated>2025-04-20T00:00:00+09:00</updated>
+ </entry>
<entry>
<id>urn:uuid:c6c7c241-46c1-44b5-95b2-c30c3a500df3</id>
<link rel="alternate" href="https://blog.nsfisis.dev/slides/2025-04-12/phpcon-odawara-2025/"></link>
diff --git a/vhosts/blog/public/posts/2025-04-20/trick-2025-most-ruby-on-ruby-award/index.html b/vhosts/blog/public/posts/2025-04-20/trick-2025-most-ruby-on-ruby-award/index.html
new file mode 100644
index 00000000..d600cb54
--- /dev/null
+++ b/vhosts/blog/public/posts/2025-04-20/trick-2025-most-ruby-on-ruby-award/index.html
@@ -0,0 +1,286 @@
+<!DOCTYPE html>
+<html lang="ja-JP">
+ <head>
+ <meta charset="UTF-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
+ <meta name="author" content="nsfisis">
+ <meta name="copyright" content="&copy; 2025 nsfisis">
+ <meta name="description" content="RubyKaigi 2025 で開催された TRICK において、『最もRuby on Ruby賞』として審査員賞をいただいた。">
+ <meta name="keywords" content="カンファレンス,Ruby,RubyKaigi,TRICK">
+ <meta property="og:type" content="article">
+ <meta property="og:title" content="RubyKaigi 2025 の TRICK で入賞した|REPL: Rest-Eat-Program Loop">
+ <meta property="og:description" content="RubyKaigi 2025 で開催された TRICK において、『最もRuby on Ruby賞』として審査員賞をいただいた。">
+ <meta property="og:site_name" content="REPL: Rest-Eat-Program Loop">
+ <meta property="og:locale" content="ja_JP">
+ <link rel="icon" type="image/svg+xml" href="/favicon.svg">
+ <title>RubyKaigi 2025 の TRICK で入賞した|REPL: Rest-Eat-Program Loop</title>
+ <link rel="stylesheet" href="/style.css?h=60eb349e583f5bd51518a7eb98598043">
+ </head>
+ <body class="single">
+ <header class="header">
+ <div class="site-logo">
+ <a href="/">REPL: Rest-Eat-Program Loop</a>
+ </div>
+ <nav class="nav">
+ <ul>
+ <li>
+ <a href="/about/">About</a>
+ </li>
+ <li>
+ <a href="/posts/">Posts</a>
+ </li>
+ <li>
+ <a href="/slides/">Slides</a>
+ </li>
+ <li>
+ <a href="/tags/">Tags</a>
+ </li>
+ </ul>
+ </nav>
+ </header>
+ <main class="main">
+ <article class="post-single">
+ <header class="post-header">
+ <h1 class="post-title">RubyKaigi 2025 の TRICK で入賞した</h1>
+ <ul class="post-tags">
+ <li class="tag">
+ <a href="/tags/conference/">カンファレンス</a>
+ </li>
+ <li class="tag">
+ <a href="/tags/ruby/">Ruby</a>
+ </li>
+ <li class="tag">
+ <a href="/tags/rubykaigi/">RubyKaigi</a>
+ </li>
+ <li class="tag">
+ <a href="/tags/trick/">TRICK</a>
+ </li>
+ </ul>
+ </header>
+ <div class="post-content">
+ <section>
+ <h2 id="changelog">更新履歴</h2>
+ <ol>
+ <li class="revision">
+ <time datetime="2025-04-20">2025-04-20</time>: 公開
+ </li>
+ </ol>
+ </section>
+ <section id="section--intro">
+ <h2><a href="#section--intro">はじめに</a></h2>
+ <p>
+ 2025-04-16 から 2025-04-18 にかけて開催された <a href="https://rubykaigi.org/2025/" rel="noreferrer" target="_blank">RubyKaigi 2025</a> に参加した (私が参加できたのは 1日目の 2025-04-16 のみ)。
+ </p>
+ <p>
+ 地元松山での大規模なカンファレンスということでスケジュールに無理を言わせて 1日目だけでもと参加したのだが、そこで開催された <a href="https://github.com/tric/trick2025" rel="noreferrer" target="_blank">TRICK 2025</a> で審査員賞をいただいた。
+ </p>
+ <p>
+ この記事では、提出した作品の紹介と解説をおこなおうと思う。
+ </p>
+ </section>
+ <section id="section--trick">
+ <h2><a href="#section--trick">TRICK とは</a></h2>
+ <p>
+ TRICK とは RubyKaigi で不定期に開催されているコンテストで、Ruby で書かれた「変わった」コードを表彰する。早い話が <a href="https://www.ioccc.org/" rel="noreferrer" target="_blank">IOCCC</a> の Ruby 版である。
+ </p>
+ <p>
+ 存在を知ってから次こそは出したいと思っていたところ、ちょうど RubyKaigi の地元開催と被ったのでこれ幸いとエントリーした。
+ </p>
+ </section>
+ <section id="section--my-work">
+ <h2><a href="#section--my-work">作品紹介</a></h2>
+ <p>
+ 今回頂いたのは審査員賞の一つ eto award (公式の賞の名前に合わせて敬称略) で、“Most Ruby-on-Ruby” Award (『最もRuby on Ruby賞』) として受賞した (IOCCC と同じく、それぞれの賞に個別の名前が付く)。
+ </p>
+ <p>
+ ソースコード等はこちら: <a href="https://github.com/tric/trick2025/tree/main/10-nsfisis" rel="noreferrer" target="_blank">https://github.com/tric/trick2025/tree/main/10-nsfisis</a>
+ </p>
+ <p>
+ 今回の TRICK では <code>ruby.wasm</code> の使用が認められている。
+ </p>
+ <blockquote>
+ <ul>
+ <li>
+ <strong>(NEW)</strong> You can use <a href="https://github.com/ruby/ruby.wasm" rel="noreferrer" target="_blank">ruby.wasm</a>.
+ </li>
+ </ul>
+ </blockquote>
+ <p>
+ 適当に HTTP サーバを立てて <a href="https://github.com/tric/trick2025/blob/main/10-nsfisis/index.html" rel="noreferrer" target="_blank"><code>index.html</code></a> を開くと、次のように <a href="https://github.com/tric/trick2025/blob/main/10-nsfisis/entry.rb" rel="noreferrer" target="_blank"><code>entry.rb</code></a> の内容が表示される。
+ </p>
+ <p>
+ <img alt="ブラウザで表示された index.html のレンダリング結果。entry.rb の内容がシンタックスハイライトされて表示されており、英単語や記号に振り仮名が振られている" src="/posts/2025-04-20/trick-2025-most-ruby-on-ruby-award/screenshot.png">
+ </img>
+ </p>
+ <p>
+ 自身のソースコードを出力するプログラム、いわゆる quine の亜種になっている。
+ </p>
+ <p>
+ しかし、このプログラムは単にソースコードをそのまま出力するのではなく、
+ </p>
+ <ul>
+ <li>
+ シンタックスハイライトして、
+ </li>
+ <li>
+ 英単語や記号に振り仮名を振って、
+ </li>
+ <li>
+ HTML で、
+ </li>
+ </ul>
+ <p>
+ 表示している。つまり、Ruby プログラムにルビを振った作品である。例えば、先頭の2行目の <code>require</code> は次のような HTML で構成されている。
+ </p>
+ <div class="codeblock" language="html">
+ <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span style="color:#24292E">&#x3C;</span><span style="color:#22863A">ruby</span><span style="color:#6F42C1"> class</span><span style="color:#24292E">=</span><span style="color:#032F62">"IDENTIFIER"</span><span style="color:#24292E">>require&#x3C;</span><span style="color:#22863A">rp</span><span style="color:#6F42C1"> class</span><span style="color:#24292E">=</span><span style="color:#032F62">""</span><span style="color:#24292E">>(&#x3C;/</span><span style="color:#22863A">rp</span><span style="color:#24292E">>&#x3C;</span><span style="color:#22863A">rt</span><span style="color:#6F42C1"> class</span><span style="color:#24292E">=</span><span style="color:#032F62">""</span><span style="color:#24292E">>リクワイア&#x3C;/</span><span style="color:#22863A">rt</span><span style="color:#24292E">>&#x3C;</span><span style="color:#22863A">rp</span><span style="color:#6F42C1"> class</span><span style="color:#24292E">=</span><span style="color:#032F62">""</span><span style="color:#24292E">>)&#x3C;/</span><span style="color:#22863A">rp</span><span style="color:#24292E">>&#x3C;/</span><span style="color:#22863A">ruby</span><span style="color:#24292E">></span></span></code></pre>
+ </div>
+ <p>
+ 順に使ったテクニックを解説していく。
+ </p>
+ <section id="section--my-work--quine">
+ <h3><a href="#section--my-work--quine">Quine</a></h3>
+ <p>
+ 改めて quine について説明する。Quine とは、自身のソースコードを出力するようなプログラムである。Ruby では様々な方法で quine を書くことができるが、この作品で使っている基本形は以下のようなものである。
+ </p>
+ <div class="codeblock" language="ruby">
+ <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span style="color:#005CC5">eval</span><span style="color:#24292E"> $s</span><span style="color:#032F62">=&#x3C;&#x3C;'EOS'</span></span>
+<span class="line"><span style="color:#032F62">print "eval $s=&#x3C;&#x3C;'EOS'</span><span style="color:#005CC5">\n</span><span style="color:#032F62">"</span></span>
+<span class="line"><span style="color:#032F62">print $s</span></span>
+<span class="line"><span style="color:#032F62">print "EOS</span><span style="color:#005CC5">\n</span><span style="color:#032F62">"</span></span>
+<span class="line"><span style="color:#032F62">EOS</span></span></code></pre>
+ </div>
+ <p>
+ 変数 <code>$s</code> に <code>print</code> の 3行分が入っており、それに加えて上下の1行ずつを出力すれば元のソースコードが得られる。実際には <code>$s</code> を加工してシンタックスハイライトや振り仮名を振ることになる。
+ </p>
+ </section>
+ <section id="section--my-work--syntax-highlight">
+ <h3><a href="#section--my-work--syntax-highlight">シンタックスハイライト</a></h3>
+ <p>
+ シンタックスハイライトは、トークナイズとトークン種別に応じた色付けの2段階からなる。
+ </p>
+ <p>
+ トークナイズには Ruby 3.4 からデフォルトのパーサになった <a href="https://github.com/ruby/prism" rel="noreferrer" target="_blank">Prism</a> を利用している。 <code>Prism.lex()</code> を使うとトークナイズができるので、トークンに付いているソースコード位置の情報を使いつつ元のソースコードを復元する。
+ </p>
+ <div class="codeblock" language="ruby">
+ <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span style="color:#E36209">y</span><span style="color:#D73A49"> =</span><span style="color:#005CC5"> 1</span><span style="color:#6A737D"> # 現在の行</span></span>
+<span class="line"><span style="color:#E36209">x</span><span style="color:#D73A49"> =</span><span style="color:#005CC5"> 0</span><span style="color:#6A737D"> # 現在の列</span></span>
+<span class="line"><span style="color:#005CC5">Prism</span><span style="color:#24292E">.</span><span style="color:#6F42C1">lex</span><span style="color:#24292E">($s).</span><span style="color:#6F42C1">value</span><span style="color:#24292E">[..</span><span style="color:#D73A49">-</span><span style="color:#005CC5">2</span><span style="color:#24292E">].</span><span style="color:#6F42C1">each</span><span style="color:#24292E"> {|t, *|</span></span>
+<span class="line"><span style="color:#E36209"> l</span><span style="color:#D73A49"> =</span><span style="color:#24292E"> t.</span><span style="color:#6F42C1">location</span></span>
+<span class="line"><span style="color:#E36209"> r</span><span style="color:#D73A49"> =</span><span style="color:#24292E"> l.</span><span style="color:#6F42C1">start_line</span><span style="color:#6A737D"> # トークンの開始行</span></span>
+<span class="line"><span style="color:#D73A49"> if</span><span style="color:#24292E"> y </span><span style="color:#D73A49">&#x3C;</span><span style="color:#24292E"> r </span><span style="color:#6A737D"># 改行が必要なら</span></span>
+<span class="line"><span style="color:#005CC5"> p</span><span style="color:#032F62"> "</span><span style="color:#005CC5">\n</span><span style="color:#032F62">"</span><span style="color:#D73A49"> *</span><span style="color:#24292E"> (r </span><span style="color:#D73A49">-</span><span style="color:#24292E"> y) </span><span style="color:#6A737D"># 改行を挿入して</span></span>
+<span class="line"><span style="color:#E36209"> x</span><span style="color:#D73A49"> =</span><span style="color:#005CC5"> 0</span><span style="color:#6A737D"> # 列の先頭へ戻る</span></span>
+<span class="line"><span style="color:#D73A49"> end</span></span>
+<span class="line"><span style="color:#E36209"> c</span><span style="color:#D73A49"> =</span><span style="color:#24292E"> l.</span><span style="color:#6F42C1">start_column</span><span style="color:#6A737D"> # トークンの開始列</span></span>
+<span class="line"><span style="color:#D73A49"> if</span><span style="color:#24292E"> x </span><span style="color:#D73A49">&#x3C;</span><span style="color:#24292E"> c </span><span style="color:#6A737D"># 空白が必要なら</span></span>
+<span class="line"><span style="color:#005CC5"> p</span><span style="color:#032F62"> " "</span><span style="color:#D73A49"> *</span><span style="color:#24292E"> (c </span><span style="color:#D73A49">-</span><span style="color:#24292E"> x) </span><span style="color:#6A737D"># 空白を挿入</span></span>
+<span class="line"><span style="color:#D73A49"> end</span></span>
+<span class="line"><span style="color:#005CC5"> p</span><span style="color:#6F42C1"> ruby</span><span style="color:#24292E">(t) </span><span style="color:#6A737D"># トークン本体を出力</span></span>
+<span class="line"><span style="color:#E36209"> y</span><span style="color:#D73A49"> =</span><span style="color:#24292E"> l.</span><span style="color:#6F42C1">end_line</span><span style="color:#6A737D"> # 現在行を更新</span></span>
+<span class="line"><span style="color:#E36209"> x</span><span style="color:#D73A49"> =</span><span style="color:#24292E"> l.</span><span style="color:#6F42C1">end_column</span><span style="color:#6A737D"> # 現在列を更新</span></span>
+<span class="line"><span style="color:#24292E">}</span></span></code></pre>
+ </div>
+ <p>
+ 補足: 変数名がやたら短いのは、このあとの振り仮名データの量を削減するため。
+ </p>
+ <p>
+ トークン種別に応じた色付けは CSS でおこなっている。出力する HTML のクラス名に <code>Prism::Token#type</code> を指定しておいて、<code>index.html</code> でそれぞれのクラスにスタイルを当てた。
+ </p>
+ <div class="codeblock" language="html">
+ <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span style="color:#24292E"> &#x3C;</span><span style="color:#22863A">style</span><span style="color:#24292E">></span></span>
+<span class="line"><span style="color:#6A737D"> /* ... */</span></span>
+<span class="line"></span>
+<span class="line"><span style="color:#6F42C1"> .COMMENT</span><span style="color:#24292E"> {</span></span>
+<span class="line"><span style="color:#005CC5"> color</span><span style="color:#24292E">: </span><span style="color:#005CC5">#777</span><span style="color:#24292E">;</span></span>
+<span class="line"><span style="color:#005CC5"> font-style</span><span style="color:#24292E">: </span><span style="color:#005CC5">italic</span><span style="color:#24292E">;</span></span>
+<span class="line"><span style="color:#24292E"> }</span></span>
+<span class="line"></span>
+<span class="line"><span style="color:#6F42C1"> .CONSTANT</span><span style="color:#24292E">, </span><span style="color:#6F42C1">.GLOBAL_VARIABLE</span><span style="color:#24292E">, </span><span style="color:#6F42C1">.INSTANCE_VARIABLE</span><span style="color:#24292E">, </span><span style="color:#6F42C1">.IDENTIFIER</span><span style="color:#24292E"> {</span></span>
+<span class="line"><span style="color:#005CC5"> color</span><span style="color:#24292E">: </span><span style="color:#005CC5">#088</span><span style="color:#24292E">;</span></span>
+<span class="line"><span style="color:#24292E"> }</span></span>
+<span class="line"></span>
+<span class="line"><span style="color:#6A737D"> /* ... */</span></span>
+<span class="line"><span style="color:#24292E"> &#x3C;/</span><span style="color:#22863A">style</span><span style="color:#24292E">></span></span></code></pre>
+ </div>
+ <p>
+ トークン種別の列挙にはそれなりに文字数を使ってしまうのだが、今回の TRICK のレギュレーションでは <code>index.html</code> にサイズ制限がなかったので好きに色を付けることができた。
+ </p>
+ </section>
+ <section id="section--my-work--ruby-text">
+ <h3><a href="#section--my-work--ruby-text">振り仮名</a></h3>
+ <p>
+ それぞれの英単語や記号に対応した振り仮名のデータは、プログラム中に埋め込まれている。
+ </p>
+ <div class="codeblock" language="ruby">
+ <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span style="color:#D73A49">def</span><span style="color:#6F42C1"> rt</span><span style="color:#24292E">(t)</span></span>
+<span class="line"><span style="color:#E36209"> r</span><span style="color:#D73A49"> =</span><span style="color:#24292E"> {</span></span>
+<span class="line"><span style="color:#005CC5"> :"&#x26;&#x26;"</span><span style="color:#24292E"> => </span><span style="color:#032F62">"1136"</span><span style="color:#24292E">,</span></span>
+<span class="line"><span style="color:#005CC5"> :"="</span><span style="color:#24292E"> => </span><span style="color:#032F62">"04199275"</span><span style="color:#24292E">,</span></span>
+<span class="line"><span style="color:#005CC5"> :"||"</span><span style="color:#24292E"> => </span><span style="color:#032F62">"623147"</span><span style="color:#24292E">,</span></span>
+<span class="line"><span style="color:#005CC5"> :$s</span><span style="color:#24292E"> => </span><span style="color:#032F62">"41750825"</span><span style="color:#24292E">,</span></span>
+<span class="line"><span style="color:#005CC5"> :*</span><span style="color:#24292E"> => </span><span style="color:#032F62">"111775"</span><span style="color:#24292E">,</span></span>
+<span class="line"><span style="color:#6A737D"> # ...</span></span>
+<span class="line"><span style="color:#005CC5"> type:</span><span style="color:#032F62"> "310455"</span><span style="color:#24292E">,</span></span>
+<span class="line"><span style="color:#005CC5"> utf_8:</span><span style="color:#032F62"> "70923803920853080440"</span><span style="color:#24292E">,</span></span>
+<span class="line"><span style="color:#005CC5"> value:</span><span style="color:#032F62"> "48746992"</span><span style="color:#24292E">,</span></span>
+<span class="line"><span style="color:#005CC5"> x:</span><span style="color:#032F62"> "08351525"</span><span style="color:#24292E">,</span></span>
+<span class="line"><span style="color:#005CC5"> y:</span><span style="color:#032F62"> "7904"</span><span style="color:#24292E">,</span></span>
+<span class="line"><span style="color:#24292E"> }</span></span>
+<span class="line"><span style="color:#6F42C1"> kana</span><span style="color:#24292E">(</span></span>
+<span class="line"><span style="color:#24292E"> r[</span><span style="color:#005CC5">:"#{t.</span><span style="color:#6F42C1">type</span><span style="color:#005CC5">}"</span><span style="color:#24292E">] </span><span style="color:#D73A49">||</span></span>
+<span class="line"><span style="color:#24292E"> r[s </span><span style="color:#D73A49">=</span><span style="color:#005CC5"> :"#{t.</span><span style="color:#6F42C1">value</span><span style="color:#005CC5">.</span><span style="color:#6F42C1">downcase</span><span style="color:#005CC5">}"</span><span style="color:#24292E">] </span><span style="color:#D73A49">||</span></span>
+<span class="line"><span style="color:#24292E"> s.</span><span style="color:#6F42C1">end_with?</span><span style="color:#24292E">(</span><span style="color:#032F62">":"</span><span style="color:#24292E">) </span><span style="color:#D73A49">&#x26;&#x26;</span><span style="color:#24292E"> r[</span><span style="color:#005CC5">:"#{s[..</span><span style="color:#D73A49">-</span><span style="color:#005CC5">2]}"</span><span style="color:#24292E">] </span><span style="color:#D73A49">||</span></span>
+<span class="line"><span style="color:#005CC5"> nil</span></span>
+<span class="line"><span style="color:#24292E"> )</span></span>
+<span class="line"><span style="color:#D73A49">end</span></span></code></pre>
+ </div>
+ <p>
+ トークンの種類 (<code>t.type</code>) またはトークンの文字列表現そのもの (<code>t.value.downcase</code>) を使ってテーブルを引いて振り仮名へ変換している。 このテーブルのキー部分そのものにも振り仮名を振るために、トークンが <code>:</code> で終わっていれば <code>:</code> を取り除いて振り仮名を得ている (例: <code>&quot;value:&quot;</code> → <code>&quot;value&quot;</code> → <code>&quot;48746992&quot;</code>)。
+ </p>
+ <p>
+ このテーブルはサイズ制限を突破するために圧縮されており、<code>kana()</code> 関数で展開される。
+ </p>
+ <div class="codeblock" language="ruby">
+ <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span style="color:#D73A49">def</span><span style="color:#6F42C1"> kana</span><span style="color:#24292E">(s)</span></span>
+<span class="line"><span style="color:#24292E"> s</span></span>
+<span class="line"><span style="color:#D73A49"> &#x26;.</span><span style="color:#6F42C1">scan</span><span style="color:#24292E">(</span><span style="color:#032F62">/.{2}/</span><span style="color:#24292E">)</span></span>
+<span class="line"><span style="color:#D73A49"> &#x26;.</span><span style="color:#6F42C1">map</span><span style="color:#24292E">{|c| (</span><span style="color:#005CC5">0x30A0</span><span style="color:#D73A49"> +</span><span style="color:#24292E"> c.</span><span style="color:#6F42C1">to_i</span><span style="color:#24292E">).</span><span style="color:#6F42C1">chr</span><span style="color:#24292E">(</span><span style="color:#005CC5">Encoding</span><span style="color:#24292E">::</span><span style="color:#005CC5">UTF_8</span><span style="color:#24292E">)}</span></span>
+<span class="line"><span style="color:#D73A49"> &#x26;.*</span><span style="color:#24292E">(</span><span style="color:#032F62">""</span><span style="color:#24292E">)</span></span>
+<span class="line"><span style="color:#D73A49">end</span></span></code></pre>
+ </div>
+ <p>
+ 例えば <code>value</code> に対応する振り仮名データ <code>&quot;48746992&quot;</code> であれば、次のような変換を経て振り仮名へと展開される。
+ </p>
+ <div class="codeblock" language="ruby">
+ <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span style="color:#24292E"> s</span></span>
+<span class="line"><span style="color:#6A737D"> # => "48746992"</span></span>
+<span class="line"><span style="color:#D73A49"> &#x26;.</span><span style="color:#6F42C1">scan</span><span style="color:#24292E">(</span><span style="color:#032F62">/.{2}/</span><span style="color:#24292E">)</span></span>
+<span class="line"><span style="color:#6A737D"> # => ["48", "74", "69", "92"]</span></span>
+<span class="line"><span style="color:#D73A49"> &#x26;.</span><span style="color:#6F42C1">map</span><span style="color:#24292E">{|c| (</span><span style="color:#005CC5">0x30A0</span><span style="color:#D73A49"> +</span><span style="color:#24292E"> c.</span><span style="color:#6F42C1">to_i</span><span style="color:#24292E">).</span><span style="color:#6F42C1">chr</span><span style="color:#24292E">(</span><span style="color:#005CC5">Encoding</span><span style="color:#24292E">::</span><span style="color:#005CC5">UTF_8</span><span style="color:#24292E">)}</span></span>
+<span class="line"><span style="color:#6A737D"> # => ["バ", "リ", "ュ", "ー"]</span></span>
+<span class="line"><span style="color:#D73A49"> &#x26;.*</span><span style="color:#24292E">(</span><span style="color:#032F62">""</span><span style="color:#24292E">)</span></span>
+<span class="line"><span style="color:#6A737D"> # => "バリュー"</span></span></code></pre>
+ </div>
+ <p>
+ これは後で気付いたのだが、Ruby は多倍長整数が扱えるので <code>&quot;48746992&quot;</code> のようなデータは単に <code>48746992</code> と書けばよかった。 <code>kana()</code> 関数が多少長くはなるが、振り仮名データの数 x 2 バイト分サイズが減るのでこちらの方が短くなる。 サイズ制限の都合で振り仮名を振るのを諦めた記号もあったのでもったいない。
+ </p>
+ </section>
+ </section>
+ <section id="section--outro">
+ <h2><a href="#section--outro">おわりに</a></h2>
+ <p>
+ 本っ当に取りたかったので心から嬉しいです。 全部で 3作提出したのですが、他の 2つも選外佳作として選出していただけた上、そのうちの “Least Truthful” については最後に Matz 氏から言及があり、審査員賞と合わせて望外の栄誉となりました。
+ </p>
+ <p>
+ ありがとうございました!
+ </p>
+ </section>
+ </div>
+ </article>
+ </main>
+ <footer class="footer">
+ &copy; 2021 nsfisis
+ </footer>
+ </body>
+</html>
diff --git a/vhosts/blog/public/posts/2025-04-20/trick-2025-most-ruby-on-ruby-award/screenshot.png b/vhosts/blog/public/posts/2025-04-20/trick-2025-most-ruby-on-ruby-award/screenshot.png
new file mode 100644
index 00000000..0bfe3be9
--- /dev/null
+++ b/vhosts/blog/public/posts/2025-04-20/trick-2025-most-ruby-on-ruby-award/screenshot.png
Binary files differ
diff --git a/vhosts/blog/public/posts/atom.xml b/vhosts/blog/public/posts/atom.xml
index 47dbbced..db060626 100644
--- a/vhosts/blog/public/posts/atom.xml
+++ b/vhosts/blog/public/posts/atom.xml
@@ -7,7 +7,15 @@
<author>
<name>nsfisis</name>
</author>
- <updated>2025-04-09T00:00:00+09:00</updated>
+ <updated>2025-04-20T00:00:00+09:00</updated>
+ <entry>
+ <id>urn:uuid:039b3dff-3b75-46b7-a731-9a3a0ff8e21f</id>
+ <link rel="alternate" href="https://blog.nsfisis.dev/posts/2025-04-20/trick-2025-most-ruby-on-ruby-award/"></link>
+ <title>RubyKaigi 2025 の TRICK で入賞した</title>
+ <summary>RubyKaigi 2025 で開催された TRICK において、『最もRuby on Ruby賞』として審査員賞をいただいた。</summary>
+ <published>2025-04-20T00:00:00+09:00</published>
+ <updated>2025-04-20T00:00:00+09:00</updated>
+ </entry>
<entry>
<id>urn:uuid:046e4412-bee8-4ffe-9876-6cbeaa0caf6b</id>
<link rel="alternate" href="https://blog.nsfisis.dev/posts/2025-03-28/http-1-1-send-multiple-same-headers/"></link>
diff --git a/vhosts/blog/public/posts/index.html b/vhosts/blog/public/posts/index.html
index 0615e378..b2fa1b46 100644
--- a/vhosts/blog/public/posts/index.html
+++ b/vhosts/blog/public/posts/index.html
@@ -43,6 +43,21 @@
<h1>投稿一覧</h1>
</header>
<article class="post-entry">
+ <a href="/posts/2025-04-20/trick-2025-most-ruby-on-ruby-award/">
+ <header class="entry-header">
+ <h2>RubyKaigi 2025 の TRICK で入賞した</h2>
+ </header>
+ <section class="entry-content">
+ <p>
+ RubyKaigi 2025 で開催された TRICK において、『最もRuby on Ruby賞』として審査員賞をいただいた。
+ </p>
+ </section>
+ <footer class="entry-footer">
+ <time datetime="2025-04-20">2025-04-20</time> 投稿
+ </footer>
+ </a>
+ </article>
+ <article class="post-entry">
<a href="/posts/2025-03-28/http-1-1-send-multiple-same-headers/">
<header class="entry-header">
<h2>【HTTP】HTTP/1.1 で同じヘッダを2回送るとどうなるか</h2>
diff --git a/vhosts/blog/public/tags/conference/atom.xml b/vhosts/blog/public/tags/conference/atom.xml
index 0a1f320d..f230c7d5 100644
--- a/vhosts/blog/public/tags/conference/atom.xml
+++ b/vhosts/blog/public/tags/conference/atom.xml
@@ -7,7 +7,15 @@
<author>
<name>nsfisis</name>
</author>
- <updated>2025-04-12T00:00:00+09:00</updated>
+ <updated>2025-04-20T00:00:00+09:00</updated>
+ <entry>
+ <id>urn:uuid:039b3dff-3b75-46b7-a731-9a3a0ff8e21f</id>
+ <link rel="alternate" href="https://blog.nsfisis.dev/posts/2025-04-20/trick-2025-most-ruby-on-ruby-award/"></link>
+ <title>RubyKaigi 2025 の TRICK で入賞した</title>
+ <summary>RubyKaigi 2025 で開催された TRICK において、『最もRuby on Ruby賞』として審査員賞をいただいた。</summary>
+ <published>2025-04-20T00:00:00+09:00</published>
+ <updated>2025-04-20T00:00:00+09:00</updated>
+ </entry>
<entry>
<id>urn:uuid:c6c7c241-46c1-44b5-95b2-c30c3a500df3</id>
<link rel="alternate" href="https://blog.nsfisis.dev/slides/2025-04-12/phpcon-odawara-2025/"></link>
diff --git a/vhosts/blog/public/tags/conference/index.html b/vhosts/blog/public/tags/conference/index.html
index 726c106c..a586a0b0 100644
--- a/vhosts/blog/public/tags/conference/index.html
+++ b/vhosts/blog/public/tags/conference/index.html
@@ -44,6 +44,21 @@
<h1>タグ「カンファレンス」一覧</h1>
</header>
<article class="post-entry">
+ <a href="/posts/2025-04-20/trick-2025-most-ruby-on-ruby-award/">
+ <header class="entry-header">
+ <h2>RubyKaigi 2025 の TRICK で入賞した</h2>
+ </header>
+ <section class="entry-content">
+ <p>
+ RubyKaigi 2025 で開催された TRICK において、『最もRuby on Ruby賞』として審査員賞をいただいた。
+ </p>
+ </section>
+ <footer class="entry-footer">
+ <time datetime="2025-04-20">2025-04-20</time> 投稿
+ </footer>
+ </a>
+ </article>
+ <article class="post-entry">
<a href="/slides/2025-04-12/phpcon-odawara-2025/">
<header class="entry-header">
<h2>登壇: PHP カンファレンス小田原 2025 (レギュラートーク (20分))</h2>
diff --git a/vhosts/blog/public/tags/index.html b/vhosts/blog/public/tags/index.html
index 4a3a698b..13dafe8c 100644
--- a/vhosts/blog/public/tags/index.html
+++ b/vhosts/blog/public/tags/index.html
@@ -77,7 +77,7 @@
<h2>カンファレンス</h2>
</header>
<footer class="entry-footer">
- 14件の記事、8件のスライド
+ 15件の記事、8件のスライド
</footer>
</a>
</article>
@@ -317,7 +317,7 @@
<h2>Ruby</h2>
</header>
<footer class="entry-footer">
- 2件の記事
+ 3件の記事
</footer>
</a>
</article>
@@ -332,6 +332,16 @@
</a>
</article>
<article class="post-entry">
+ <a href="/tags/rubykaigi/">
+ <header class="entry-header">
+ <h2>RubyKaigi</h2>
+ </header>
+ <footer class="entry-footer">
+ 1件の記事
+ </footer>
+ </a>
+ </article>
+ <article class="post-entry">
<a href="/tags/rust/">
<header class="entry-header">
<h2>Rust</h2>
@@ -362,6 +372,16 @@
</a>
</article>
<article class="post-entry">
+ <a href="/tags/trick/">
+ <header class="entry-header">
+ <h2>TRICK</h2>
+ </header>
+ <footer class="entry-footer">
+ 1件の記事
+ </footer>
+ </a>
+ </article>
+ <article class="post-entry">
<a href="/tags/vim/">
<header class="entry-header">
<h2>Vim</h2>
diff --git a/vhosts/blog/public/tags/ruby/atom.xml b/vhosts/blog/public/tags/ruby/atom.xml
index a0da6b39..04d572e9 100644
--- a/vhosts/blog/public/tags/ruby/atom.xml
+++ b/vhosts/blog/public/tags/ruby/atom.xml
@@ -7,7 +7,15 @@
<author>
<name>nsfisis</name>
</author>
- <updated>2021-10-02T00:00:00+09:00</updated>
+ <updated>2025-04-20T00:00:00+09:00</updated>
+ <entry>
+ <id>urn:uuid:039b3dff-3b75-46b7-a731-9a3a0ff8e21f</id>
+ <link rel="alternate" href="https://blog.nsfisis.dev/posts/2025-04-20/trick-2025-most-ruby-on-ruby-award/"></link>
+ <title>RubyKaigi 2025 の TRICK で入賞した</title>
+ <summary>RubyKaigi 2025 で開催された TRICK において、『最もRuby on Ruby賞』として審査員賞をいただいた。</summary>
+ <published>2025-04-20T00:00:00+09:00</published>
+ <updated>2025-04-20T00:00:00+09:00</updated>
+ </entry>
<entry>
<id>urn:uuid:e1456a50-4fc6-42ef-89f3-8be78e01da13</id>
<link rel="alternate" href="https://blog.nsfisis.dev/posts/2021-10-02/ruby-detect-running-implementation/"></link>
diff --git a/vhosts/blog/public/tags/ruby/index.html b/vhosts/blog/public/tags/ruby/index.html
index c5ac5f19..272cd427 100644
--- a/vhosts/blog/public/tags/ruby/index.html
+++ b/vhosts/blog/public/tags/ruby/index.html
@@ -44,6 +44,21 @@
<h1>タグ「Ruby」一覧</h1>
</header>
<article class="post-entry">
+ <a href="/posts/2025-04-20/trick-2025-most-ruby-on-ruby-award/">
+ <header class="entry-header">
+ <h2>RubyKaigi 2025 の TRICK で入賞した</h2>
+ </header>
+ <section class="entry-content">
+ <p>
+ RubyKaigi 2025 で開催された TRICK において、『最もRuby on Ruby賞』として審査員賞をいただいた。
+ </p>
+ </section>
+ <footer class="entry-footer">
+ <time datetime="2025-04-20">2025-04-20</time> 投稿
+ </footer>
+ </a>
+ </article>
+ <article class="post-entry">
<a href="/posts/2021-10-02/ruby-detect-running-implementation/">
<header class="entry-header">
<h2>【Ruby】 自身を実行している処理系の種類を判定する</h2>
diff --git a/vhosts/blog/public/tags/rubykaigi/atom.xml b/vhosts/blog/public/tags/rubykaigi/atom.xml
new file mode 100644
index 00000000..8fad7b19
--- /dev/null
+++ b/vhosts/blog/public/tags/rubykaigi/atom.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<feed xmlns="http://www.w3.org/2005/Atom">
+ <id>tag:blog.nsfisis.dev,2021:tag-rubykaigi</id>
+ <title>タグ「RubyKaigi」一覧|REPL: Rest-Eat-Program Loop</title>
+ <link rel="alternate" href="https://blog.nsfisis.dev/tags/rubykaigi/"></link>
+ <link rel="self" href="https://blog.nsfisis.dev/tags/rubykaigi/atom.xml"></link>
+ <author>
+ <name>nsfisis</name>
+ </author>
+ <updated>2025-04-20T00:00:00+09:00</updated>
+ <entry>
+ <id>urn:uuid:039b3dff-3b75-46b7-a731-9a3a0ff8e21f</id>
+ <link rel="alternate" href="https://blog.nsfisis.dev/posts/2025-04-20/trick-2025-most-ruby-on-ruby-award/"></link>
+ <title>RubyKaigi 2025 の TRICK で入賞した</title>
+ <summary>RubyKaigi 2025 で開催された TRICK において、『最もRuby on Ruby賞』として審査員賞をいただいた。</summary>
+ <published>2025-04-20T00:00:00+09:00</published>
+ <updated>2025-04-20T00:00:00+09:00</updated>
+ </entry>
+</feed>
diff --git a/vhosts/blog/public/tags/rubykaigi/index.html b/vhosts/blog/public/tags/rubykaigi/index.html
new file mode 100644
index 00000000..173bc430
--- /dev/null
+++ b/vhosts/blog/public/tags/rubykaigi/index.html
@@ -0,0 +1,66 @@
+<!DOCTYPE html>
+<html lang="ja-JP">
+ <head>
+ <meta charset="UTF-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
+ <meta name="author" content="nsfisis">
+ <meta name="copyright" content="&copy; 2025 nsfisis">
+ <meta name="description" content="タグ「RubyKaigi」のついた記事またはスライドの一覧">
+ <meta name="keywords" content="RubyKaigi">
+ <meta property="og:type" content="article">
+ <meta property="og:title" content="タグ「RubyKaigi」一覧|REPL: Rest-Eat-Program Loop">
+ <meta property="og:description" content="タグ「RubyKaigi」のついた記事またはスライドの一覧">
+ <meta property="og:site_name" content="REPL: Rest-Eat-Program Loop">
+ <meta property="og:locale" content="ja_JP">
+ <link rel="alternate" type="application/atom+xml" href="https://blog.nsfisis.dev/tags/rubykaigi/atom.xml">
+ <link rel="icon" type="image/svg+xml" href="/favicon.svg">
+ <title>タグ「RubyKaigi」一覧|REPL: Rest-Eat-Program Loop</title>
+ <link rel="stylesheet" href="/style.css?h=60eb349e583f5bd51518a7eb98598043">
+ </head>
+ <body class="list">
+ <header class="header">
+ <div class="site-logo">
+ <a href="/">REPL: Rest-Eat-Program Loop</a>
+ </div>
+ <nav class="nav">
+ <ul>
+ <li>
+ <a href="/about/">About</a>
+ </li>
+ <li>
+ <a href="/posts/">Posts</a>
+ </li>
+ <li>
+ <a href="/slides/">Slides</a>
+ </li>
+ <li>
+ <a href="/tags/">Tags</a>
+ </li>
+ </ul>
+ </nav>
+ </header>
+ <main class="main">
+ <header class="page-header">
+ <h1>タグ「RubyKaigi」一覧</h1>
+ </header>
+ <article class="post-entry">
+ <a href="/posts/2025-04-20/trick-2025-most-ruby-on-ruby-award/">
+ <header class="entry-header">
+ <h2>RubyKaigi 2025 の TRICK で入賞した</h2>
+ </header>
+ <section class="entry-content">
+ <p>
+ RubyKaigi 2025 で開催された TRICK において、『最もRuby on Ruby賞』として審査員賞をいただいた。
+ </p>
+ </section>
+ <footer class="entry-footer">
+ <time datetime="2025-04-20">2025-04-20</time> 投稿
+ </footer>
+ </a>
+ </article>
+ </main>
+ <footer class="footer">
+ &copy; 2021 nsfisis
+ </footer>
+ </body>
+</html>
diff --git a/vhosts/blog/public/tags/trick/atom.xml b/vhosts/blog/public/tags/trick/atom.xml
new file mode 100644
index 00000000..98341b8a
--- /dev/null
+++ b/vhosts/blog/public/tags/trick/atom.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<feed xmlns="http://www.w3.org/2005/Atom">
+ <id>tag:blog.nsfisis.dev,2021:tag-trick</id>
+ <title>タグ「TRICK」一覧|REPL: Rest-Eat-Program Loop</title>
+ <link rel="alternate" href="https://blog.nsfisis.dev/tags/trick/"></link>
+ <link rel="self" href="https://blog.nsfisis.dev/tags/trick/atom.xml"></link>
+ <author>
+ <name>nsfisis</name>
+ </author>
+ <updated>2025-04-20T00:00:00+09:00</updated>
+ <entry>
+ <id>urn:uuid:039b3dff-3b75-46b7-a731-9a3a0ff8e21f</id>
+ <link rel="alternate" href="https://blog.nsfisis.dev/posts/2025-04-20/trick-2025-most-ruby-on-ruby-award/"></link>
+ <title>RubyKaigi 2025 の TRICK で入賞した</title>
+ <summary>RubyKaigi 2025 で開催された TRICK において、『最もRuby on Ruby賞』として審査員賞をいただいた。</summary>
+ <published>2025-04-20T00:00:00+09:00</published>
+ <updated>2025-04-20T00:00:00+09:00</updated>
+ </entry>
+</feed>
diff --git a/vhosts/blog/public/tags/trick/index.html b/vhosts/blog/public/tags/trick/index.html
new file mode 100644
index 00000000..9dfad6b2
--- /dev/null
+++ b/vhosts/blog/public/tags/trick/index.html
@@ -0,0 +1,66 @@
+<!DOCTYPE html>
+<html lang="ja-JP">
+ <head>
+ <meta charset="UTF-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
+ <meta name="author" content="nsfisis">
+ <meta name="copyright" content="&copy; 2025 nsfisis">
+ <meta name="description" content="タグ「TRICK」のついた記事またはスライドの一覧">
+ <meta name="keywords" content="TRICK">
+ <meta property="og:type" content="article">
+ <meta property="og:title" content="タグ「TRICK」一覧|REPL: Rest-Eat-Program Loop">
+ <meta property="og:description" content="タグ「TRICK」のついた記事またはスライドの一覧">
+ <meta property="og:site_name" content="REPL: Rest-Eat-Program Loop">
+ <meta property="og:locale" content="ja_JP">
+ <link rel="alternate" type="application/atom+xml" href="https://blog.nsfisis.dev/tags/trick/atom.xml">
+ <link rel="icon" type="image/svg+xml" href="/favicon.svg">
+ <title>タグ「TRICK」一覧|REPL: Rest-Eat-Program Loop</title>
+ <link rel="stylesheet" href="/style.css?h=60eb349e583f5bd51518a7eb98598043">
+ </head>
+ <body class="list">
+ <header class="header">
+ <div class="site-logo">
+ <a href="/">REPL: Rest-Eat-Program Loop</a>
+ </div>
+ <nav class="nav">
+ <ul>
+ <li>
+ <a href="/about/">About</a>
+ </li>
+ <li>
+ <a href="/posts/">Posts</a>
+ </li>
+ <li>
+ <a href="/slides/">Slides</a>
+ </li>
+ <li>
+ <a href="/tags/">Tags</a>
+ </li>
+ </ul>
+ </nav>
+ </header>
+ <main class="main">
+ <header class="page-header">
+ <h1>タグ「TRICK」一覧</h1>
+ </header>
+ <article class="post-entry">
+ <a href="/posts/2025-04-20/trick-2025-most-ruby-on-ruby-award/">
+ <header class="entry-header">
+ <h2>RubyKaigi 2025 の TRICK で入賞した</h2>
+ </header>
+ <section class="entry-content">
+ <p>
+ RubyKaigi 2025 で開催された TRICK において、『最もRuby on Ruby賞』として審査員賞をいただいた。
+ </p>
+ </section>
+ <footer class="entry-footer">
+ <time datetime="2025-04-20">2025-04-20</time> 投稿
+ </footer>
+ </a>
+ </article>
+ </main>
+ <footer class="footer">
+ &copy; 2021 nsfisis
+ </footer>
+ </body>
+</html>