たまに18歳未満の人や心臓の弱い人にはお勧めできない情報が含まれることもあるかもしれない、甘くなくて酸っぱくてしょっぱいチラシの裏。RSSによる簡単な更新情報を利用したりすると、ハッピーになるかも知れませんしそうでないかも知れません。
の動向はもえじら組ブログで。
宣伝。日経LinuxにてLinuxの基礎?を紹介する漫画「シス管系女子」を連載させていただいています。 以下の特設サイトにて、単行本まんがでわかるLinux シス管系女子の試し読みが可能!
サークル「シス管系女子会」のここまでの活動の振り返りです。 技術書典と技術書典2、コミティア119、あとデブサミのDevBooks 2017にサークル参加して得られたデータや思った事を書き留めておきます。
最初にお金の絡む話から書いていきます。
技術書典とコミティアは商業誌の販売が可能とのことだったので、シス管系女子1と[2]を持っていった他、技術書典と技術書典2では無料頒布のフリーペーパーやリーフレットも持っていきました。先に大まかな数字を出しておくと、かかった費用と実績は以下のような感じでした。
イベント参加費と技術書典・DevBooksのコピー本、あと技術書典2のリーフレットの印刷費は日経BP持ちで、ムックの販売は中間マージン無しの委託販売の体裁として、ムック売上額はそっくりそのまま日経BP社に渡しています(oh, ボランティア……)。1日人を張り付ける人件費を考慮に入れなければ、多分黒字にはなっていそうな気がします。
技術書典1ではコピー本を無料配布し、技術書典2ではリーフレットを無料配布しました。 ただのチラシを配ってもどうせ見てもらえないと思ったので、中身は漫画になっています(シス管系女子BEGINSの前後に「いかにも宣伝」という感じの漫画を足した)。通り過ぎる一瞬で目を留めてもらうのは無理でも、持って帰ってじっくり読んでもらえるといいな……という魂胆です。この辺は、イベント以外の場でも買える商業出版物ならではの割り切りですね。
元々、技術書典2でもコピー本の体裁の物を無料配布する事を考えていたのですが、思ったよりページ数が増えて表紙込みで24ページになってしまった結果、どう作っても1冊あたりの原価が100円近くになってしまう事が分かった(なのでDevBooksでは一応100円での頒布としました)ため、A4サイズ3つ折りのリーフレット両面を使った縮刷版という体裁にしました。苦肉の策でしたが、これだと印刷枚数次第ではフルカラーでも1枚20円を下回るくらいになるので、結構アリな気がしています。
最初の技術書典では当初は、スペースに置いておいて立ち寄って話を聞いてくれた方や希望者に手渡すつもりだったのですが、「どうせ無料で配布するのなら通りかかった人にどんどん渡しても同じなのでは?」とツッコまれて、それもそうかと思って「無料配布のサンプルです」と声をかけて渡していくスタイルに切り替えたのでした。
通行中の人への声かけは同人イベントではマナー違反とされている事が多いようで、COMITIAに至っては「呼び込み禁止」とはっきり明記されています。技術書典では「商業出版物を取り扱う場合は企業参加扱い」というレギュレーションで、特に明示的に禁止するようなルールの記載も無かったので「企業ならこのくらいはやってもバチは当たるめぇ」と開き直って声を出していましたが、迷惑行為と言われてしまうとグウの音も出ないので、チラシ撒きともども、やるならせいぜい前を通りかかる人に届く程度の声量に留めた上で、恨まれる&出禁になる覚悟でやりましょう。とだけ書いておきます。
元々、シス管系女子会としてのイベント参加は以下のような目論見で始めました。
結論から言うと、このうち1と2は実現され、3は目立った結果には繋がっていないという印象です。
1は、前述の通り会場でのムック売り上げがそこそこあり、その際にシリーズ2冊をまとめ買いしてくださる方が多かったという事から、やはりまだまだリーチできていない潜在読者がいるという事の証明にもなっていると思います。
2は、元々出版社サイドに何度か「試し読みになるように本編の一部を公開したい」という事を打診しているのですが、「原稿料を支払って下請けに制作させたコンテンツを、何故下請けが勝手に外に出したがるのだ?」という意識があるのかないのか進展が無いので、だったら原稿料もらわなくていいから自分で好きに使えるように勝手に描くわという事でコンテンツを制作したという事です。実際にこれを動機として特別編を制作し公開に繋げられていることから、〆切駆動型の自分には確かに効果的でした。
3は、その後のイベントレポートやTwitterでの反応を見る限りでは、「このイベントで初めて知った」「この試し読みで初めて意識した」みたいな新規開拓の方の反応はあまり見られませんでした。また、全一般参加者の方のうち1/5~1/6にリーフレットを受け取って頂けた計算になりますが、イベントレポートの写真等で「会場で入手した物」の一覧に写っている例は少なかったように思いました。
理由は色々考えられますが、成果を上げるためにはまだまだ工夫が必要そうです。
初回の技術書典の話はその時のエントリをご参照下さい。以下は技術書典2の感想です。
技術書典2当日のTwitterの反応まとめを見ると、来場者が多すぎて入場が遅々として進まない事へのコメントが多く、参加を諦めた人も多かったというのは終わった後で知りました。方や会場内では、サークルによっては開場1時間や2時間で完売の拍手が上がっていました(6時間あるイベントの序盤での在庫切れというのは相当な読み違えがあったということになります)。「技術書オンリー」「同日に別の場所でも同人イベントが開催されており、その中にはけものフレンズのオンリーイベントも含まれていた」「天気は雨」など、来場者が少なくなる方向の材料ばかりがあったにも関わらずこの盛況さということで、当日に至ってすらも来場者数の読みが極めて難しい状況でした。
前回は会場が建物内の地下と2階に分断されていた上に、入場が整理券制になっていたことから、全体の様子というのは正直見えにくかったのですが、今回は他の同人誌即売会イベントに近いレイアウトだったので、全体の混雑具合などが俯瞰しやすかったです。そこで抱いた率直な感想は、まさに普通の同人誌即売会だなという事でした。
これは、コミケやコミティアなどに行った事のある自分からすると驚くべき事です。というのも、これらのイベントで評論・技術ジャンルのスペースを訪れると、他の混雑具合とは一転してびっくりするぐらい人がいないからです。そんなガラガラ具合のジャンルのサークルだけを集めるわけですから、本当にイベントとして成立するのか?という心配の声が運営サイドからすらも上がっていたのも頷けます。
別にアンケートや聞き取り調査をやったわけではないのでただの想像ですが、実はみんなこういう「知の共有」に焦点を当てたイベントを求めていたということなのではないでしょうか。
既存のイベントで技術同人が参加できるイベントといったら、基本的にはオールジャンル(取り扱う内容のジャンルを問わない、なんでもあり)のイベントですが、それらのイベントでは技術同人以外のサークルはほとんどが漫画やイラスト、エンターテインメント作品をメインにしていますし、比較的近いジャンルのオンリーイベントと思われる文学フリマであってもメインは小説や評論です。そういう状況では、技術同人に興味がある人でも、行く苦労や金銭的コストに対して得られる物が少ない、つまり「割に合わない」と判断されて、行ってみようという気が起こりにくいのではないかと思います。例えて言うと、アニメイトの一角で技術書籍のコーナーが設けられていたとして、技術者を自認する人がわざわざそこまで買いに行くのか? あるいは、アニメイトに来る客が技術書コーナーまで見て回るのか? っていう話です。
その点、技術書典は最初から技術書オンリーと銘打っていますから、「当たり」に出会えるだろうという期待値はグッと高まります。来場者が多いのは、他に類似のイベントが無いからそういうニーズがここに一気に集中してしまっているという事なのではないか。というのが、僕なりの予想です。
IT技術者をやっていると、よく「技術カンファレンスや勉強会は、発表する人が一番勉強になる」「雑誌の記事や本は、著者が一番勉強になる」なんて話を聞きます。
知見やノウハウは、自分だけが見るメモ程度であればいくらでも書けますが、他の人にも共有できるレベルの内容に引き上げるのには手間がかかります。話を一般化したり、あやふやだった所を調べ直して根拠をはっきりさせたり、話題を整理したり……こういう事が面倒で、メモのまま放置されてしまう情報や、メモすら残されないまま忘れられてしまう情報というのは結構あります。
1コマの発表内容だったり1冊の本だったりといった「パッケージ」の形にまとめる時には、必然的にそういった作業が発生します。「イベントに参加するので」「そこで新刊として発表するので」という風に〆切を設定する事で、情報を精錬するための動機が生まれ、より価値の高い情報が出てくる、そういう動機になるというのは、技術書典というイベントの重要な意義の1つと言えるでしょう。
イベント終了後、技術書典2での刊行物をベースに商業出版する事になったという話を見かけました。同人誌で活躍していた人が商業誌で活躍するようになるというのはマンガ・ゲーム業界にはよくある話で、出版社の人が会場内を見て回って、有望そうな人に声をかけるという事が、技術書でも起こっているということのようです。
会場内で実際に売れ行きが良ければ商品化する好材料になるというのはもちろんあるでしょうが、そもそもこういうイベントに物を出している時点で「〆切を設定して」「それに間に合うように」「情報を整理してパッケージ化して」同人誌として世に出すという事ができている訳で、ネットでブログに断片的な情報を書き散らかしているだけの人に比べれば、商業出版物の原稿を書くという仕事にちゃんと取り組んでくれそうだと期待できるのではないかと思います。
最後に、これは同人誌即売会一般の話ですが、対面での頒布は「読者の方と直接触れ合える」という事が最大の特長でしょう。
先のまとめで「ネットでええやん」という感じのコメントをいくつか見かけましたが、VRでないただのインターネットモールを想定しているのであれば、それは「欲しい物を事前に決めて、買いに行って、買う」という事以上の意義をイベントに対して見出していないという事なのではないかと思います。同人イベントには、会場で作者に直接感想やお礼を言いに行く人もいれば、会場で読者が喜び興奮している様子を見たくて出展する人もいます。
自分の場合は、Webでない紙媒体で連載をやっていて、読者層がWebでアクティブな人達の層とは微妙に違うらしいという日経Linux誌での連載であることから、いつもはあまり「読者の方々に実際読まれている」という実感を持てずにいます。そのため、目の前にいる方に「持ってる」とか「読んでる」とか言って頂けるのは素直に嬉しかったです。普段なかなか認識できない「読者の実在」を意識することができて、励みになるのは間違いないです。
あと、対読者というのとはちょっとズレますが、ご同業の方と話せる機会としても自分にとっては有意義でした。技術書典2ではお隣のスペースがマンガで分かるWebデザイン/マンガでわかるGitの湊川さんのスペースだったため、イベント中やイベント終了後の合同打ち上げでこの仕事の事やそれ以外の事など色々話せたのがとても嬉しかったです。
そういえば個別にレポートを書いていなかったので、DevBooksの事についてもここに書き留めておこうと思います。
恐らく技術書典の成功を受けてだと思いますが、今年はDevelopers Summit 2017の会場内の1室に小規模な同人誌即売スペースが設けられていました。商業出版物の頒布は不可というレギュレーションだったので、直前のコミティア119での在庫放出と技術書典2向けの頒布物のプレお目見えだけできればいいかと思って参加してみました。
で、参加してみた感想なのですが、とにかく精神的にキツかったです。
というのも、通常の同人イベントだと全時間を通じて人の流れがありますが、DevBooksはデブサミの1コーナーという性質上、セッションとセッションの合間にどっと人が来るもののそれ以外の時間はガラッガラで、もう暇で暇でしょうがなかったです。一人での参加だったので、誰かに店番を任せてセッションを見に行くという事もできませんでしたし……
あと、「シス管系女子」というコンテンツとイベントの来場者層がマッチしていなかったようだという事も感じました。デブサミはどちらかというと流行りの技術に強い関心のある方が多いようで、DevOpsとかと真逆の方向を向いている「シス管系女子」は訴求力が無いのでしょう……多分。
ということで、もし2回目以降があるとしたらですが、「元々デブサミのセッションに興味があって」「技術同人もやっている」「当日は店番の手伝いをしてくれる人がいる」という条件を満たせる方が、会場内での荷物置き場確保も兼ねて参加するのが良いのではないかと思います。
まあ何というかタラタラ書いてきましたが、オフラインのイベントはやっぱ良いですよ。オンラインでオンデマンドでいつでも欲しい情報が手に入る、どころか、欲しくない情報まで洪水のように押し寄せてくるのが当たり前の今だから、身体感覚を伴うライブな体験の価値がより際立つ。などという言い方も実に月並みですが、その月並みな体験をした上で「やっぱり月並みだね」と言うのと、体験しない状態で想像で物を言うのとでは違うと思いますので、未体験の人は体験してみて欲しいです。直近では4月29日に幕張メッセで「超技術書典」というのが開催されるので、まずはここから。
続き:技術書典3のご報告
このエントリはQiitaとのクロスポストです。
複数のファイルに共通する部分があるとき、共通箇所をまとめて切り出しておいて、各ファイルからはそれらを参照するだけにする、というのはよくある話です。C言語なら#include <stdio.h>
という書き方をしますし、Web制作をやる人なら、CSSの@import
規則をご存じだと思います。
しかしたまに、これに似たことを静的なファイルで行って「include文の位置に参照先のファイルがそのまま埋め込まれたファイル」を作りたいという場面が出てきます。
この記事では、そんな「静的なファイルを生成するために、ソースとなるテキストファイルに書かれたinclude文をシェルスクリプトで処理して、参照先ファイルの内容をその位置に埋め込んだ結果のファイルを得たい」というニーズに対する、なるべく効率のよい実現方法を模索してみます。
以前、さくらのレンタルサーバーの一番安いプランでWebサイトを公開するノウハウという記事で、「ssh接続できない月額129円の激安レンタルサーバーでも、手元にLinuxな環境があるならコマンドラインのFTPクライアントとシェルスクリプトでrsyncっぽいことができるよ! ついでに色々前処理もさせられるし、シス管系女子のサイトのようにチープな静的コンテンツだけのサイトなら全然余裕で運用できちゃう! やったね!」という事例をご紹介しました。
その際にやりたかった前処理のひとつに前述のinclude文があり、全ページで共通のヘッダやフッタを
html/_parts/metadata.html(共通パーツ):
<meta charset="UTF-8">
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:site" content="@piro_or">
<meta name="twitter:creator" content="@piro_or">
...
こんな風に断片ファイルとして切り出して用意しておいて、HTMLファイルの中に
html/index.html(ソースファイル):
<!DOCTYPE html>
<html lang="ja" xmlns:og="http://ogp.me/ns#" xmlns:fb="http://www.facebook.com/2008/fbml">
<head prefix="og: http://ogp.me/ns# fb: http://ogp.me/ns/fb# article: http://ogp.me/ns/article#">
<!--EMBED(metadata.html)-->
<title>シス管系女子って何!? - 【シス管系女子】特設サイト</title>
...
のように書いておき、アップロード直前に
html_resolved/index.html(埋め込み後):
<!DOCTYPE html>
<html lang="ja" xmlns:og="http://ogp.me/ns#" xmlns:fb="http://www.facebook.com/2008/fbml">
<head prefix="og: http://ogp.me/ns# fb: http://ogp.me/ns/fb# article: http://ogp.me/ns/article#">
<meta charset="UTF-8">
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:site" content="@piro_or">
<meta name="twitter:creator" content="@piro_or">
...
<title>シス管系女子って何!? - 【シス管系女子】特設サイト</title>
...
のように解決する、という事をしていました。
最初に先の記事を公開した時の実装は、以下のようなものでした(実際にはちょっと違う書き方でしたが、要旨としてはこんな感じ、ということで)。
build.sh:共通パーツを埋め込む:
#!/bin/bash
# 環境によってsedで拡張正規表現を使うためのオプションが違うので、
# egrepコマンドのように使える「$esed」を定義しておく。
case $(uname) in
Darwin|*BSD|CYGWIN*)
esed="sed -E"
;;
*)
esed="sed -r"
;;
esac
rm -rf html_resolved
cp -r html html_resolved
# include文の検出用正規表現。
# ファイル名部分は、後方参照で取り出せるように`()`で囲っておく。
embed_matcher='<!-- *EMBED\( *([^) ]+) *\) *-->'
# 処理対象のファイル(include文があるファイル)を検索する。
egrep -r \
--include='*.html' \
"$embed_matcher" \
html_resolved |
cut -d ':' -f 1 | # ファイルパスだけを取り出す。
uniq | # 1ファイルの中で何カ所も見つかる事があるので、重複を取り除く。
while read path
do
# 見つかった各ファイルに対して処理を行う。
echo "updating $path"
# ファイルを退避し、
mv "$path"{,.tmp}
# ファイルの内容を1行ずつスキャンする。
# `IFS= read -r`とすることで、行頭・行末の連続する空白文字や
# 行の中のエスケープ文字を保持する。
cat "$path.tmp" | while IFS= read -r line
do
# include文がある行だったら、
if echo "$line" | egrep "$embed_matcher" 2>&1 > /dev/null
then
# 埋め込み対象のファイルの内容をcatして、
# リダイレクトで書き出す。
parts_name="$(echo "$line" |
$esed -e "s/^.*$embed_matcher.*/\\1/")"
cat "html/_parts/$parts_name" >> "$path"
else
# それ以外の行はそのまま書き出す。
echo "$line" >> "$path"
fi
done
rm "$path.tmp"
done
これでも一応目的は達成されていたのですが、以下のような問題が残ってしまっていました。
while
ループを回すので、とにかく遅い。1は、処理対象のファイルの行数とファイル数が増えるごとに大きな負担となります。前の記事を書いた時には「変更が無かったファイルは無視する」という別方向からの対策を取ってみましたが、それでも全ファイルを対象に処理し直す時にはずいぶん待たされてしまいます。
2は、とりあえず今のところ問題にはなっていませんが、include文をHTMLのコメントの形式にしたので、もしかしたらこの制約の事を忘れて行中に書きたくなってしまうかもしれません。その時に「えっそんな制約あったなんて……」と戸惑う羽目になる前に、なんとかできるものならなんとかしておきたいところです。
その後長らくそれっきりになっていたのですが、仕事の中でまた似たようなことをやりたい場面(Firefoxの法人導入では管理者による設定を静的なJavaScriptファイルとして用意するのですが、「大部分は共通だけれども一部分だけが異なる」という設定ファイルを複数種類用意する必要が生じたのでした。共通部分を括り出すのでなく、ソースファイルに書かれたプレースホルダの位置に、環境ごとの別のソースファイルの内容を埋め込んで各環境ごとの静的なファイルをビルドしたい、という感じです)が出てたので、これを機にもっとマシなやり方を探してみました。すると、sed
のr
コマンドというまさにこういう事をやるためにあるような機能の情報が見つかりました。
ということで、ここからがこの記事の本題です。
sed
のr
コマンドは、「カーソル行の直後(次の行の直前)に別のファイルの内容を読み込んで挿入する」という物です。パターンマッチと組み合わせれば、「include文をパターンマッチで見つける→見つけたinclude文の箇所にinclude対象の外部ファイルの内容を埋め込む」という事もできるはずです。
例えば、最初に示した例をべた書きするとこうなります。
$ cat html/index.html |
sed '/<!--EMBED(metadata.html)-->/r html/_parts/metadata.html' \
> html_resolved/index.html
sed
の機能なので、Bashのwhile
ループと比べると圧倒的に高速です。これで、問題の1つ目の「とにかく遅い」という点が解消されます。やりましたね!
ただ、まだ問題はもう1つ残っています。sed
のr
は「マッチしたまさにその箇所」ではなく「マッチした箇所が含まれる行とその次の行の間」にファイルの内容を出力するため、行の中程にinclude文があると「include文の前の文字列→include文の後の文字列→参照されたファイルの内容→次の行」という結果になってしまいます。
この問題を解消するには、include文の後で必ず改行するように事前処理してしまうのが手っ取り早いです。
$ cat html/index.html |
$esed "s/($embed_matcher)( *[^$])/\1"\\$'\n''\3/g' |
sed '/<!--EMBED(metadata.html)-->/r html/_parts/metadata.html' \
> html_resolved/index.html
何だかゴチャゴチャ書いてあって分かりにくいですが、置換の指定としては以下のような内容になっています。
(<include文>)(<改行と空白以外でinclude文より後の文字列>)
<マッチしたinclude文><改行文字><include文より後の文字列>
g
フラグ)sed
で置換後の文字に改行文字を含めれば行の途中で改行することができますが、それには色々と工夫が必要です。詳細はsedで改行を出力するをご覧下さい。
このように置換してからsed
のr
でinclude文を処理すれば、ちゃんと「include文の前の文字列→参照されたファイルの内容→include文の後の文字列→次の行」という順で出力されるようになるわけです。
ここまでのコマンド列にはinclude文を解決するための指定をべた書きしていましたが、実際には任意のファイルでいろんなファイルに対するinclude文を処理する必要があります。後方参照でsed -r '/<!--EMBED\((metadata.html)\)-->/r html/_parts/\1'
みたいなことができると楽なのですが、残念ながらsed
のr
コマンドの読み込み対象ファイルの指定には後方参照は使えません。
解決策としては、sed
を実行するコマンド列をsed
で組み立てるという方法があります。
$ embed_matcher='<!-- *EMBED\( *([^) ]+) *\) *-->'
$ embed_mark_to_resolver="s|($embed_matcher)| -e '/\\1/r html/_parts/\\2'|"
$ cat html/index.html |
egrep -o "$embed_matcher" |
sort |
uniq
<!--EMBED(metadata.html)-->
<!--EMBED(footer.html)-->
<!--EMBED(header.html)-->
...
grep
やegrep
(grep -E
と同等)に-o
オプションを指定すると、「マッチした文字列がある行」ではなく「マッチした文字列そのもの」、ここではinclude文の部分だけが出力されます。それをsed -r "s|($embed_matcher)| -e '/\\1/r html/_parts/\\2'|"
で置換して-e 'sedスクリプト'
というコマンドラインオプションに変換すると、こうなります。
$ cat html/index.html |
egrep -o "$embed_matcher" |
sort |
uniq |
sed -r -e "$embed_mark_to_resolver"
-e '/<!--EMBED(metadata.html)-->/r html/_parts/metadata.html'
-e '/<!--EMBED(footer.html)-->/r html/_parts/footer.html'
-e '/<!--EMBED(header.html)-->/r html/_parts/header.html'
...
この出力に対してtr -d '\n'
で改行を削除し(1行に繋げ)てsed
のコマンドライン引数に指定すれば、ファイル内のすべてのinclude文を一気に処理することができます。
$ resolve_embedded_resources="sed $(cat "$path" |
egrep -o "$embed_matcher" |
sort |
uniq |
$esed -e "$embed_mark_to_resolver" |
tr -d '\n')"
$ cat html/index.html |
$esed "s/($embed_matcher)( *[^$])/\1"\\$'\n''\3/g' |
eval "$resolve_embedded_resources" \
> html_resolved/index.html
ちなみに、-e
オプションの指定の中には丸括弧など拡張正規表現では特別な意味を持つ文字があるので、これらは本来スケープする必要があります。が、$esed
ではなくsed
を使うようにすればエスケープは不要です。
$resolve_embedded_resources
と直接書くのではなく、わざわざeval
コマンドを使ってeval "$resolve_embedded_resources"
と書いているのは、組み立てたコマンドラインオプションの'
が値の一部にならないようにするためです。というのも、そのままパイプラインの中に
cat ... | $resolve_embedded_resources | ...
と書くと、シェル変数が展開されてsed -e "'/<!--EMBED(metadata.html)-->/r html/_parts/metadata.html'" ...
のように書かれた扱いとなってしまい、sed
に「'
なんてコマンドは無い」と言われてしまからです。eval
を使えば、指定文字列を改めてシェルのコマンド列としてパースするため、sed -e '/<!--EMBED(metadata.html)-->/r html/_parts/metadata.html' ...
と書いたのと同じに扱われるようになります。
また、これだけだとinclude文自体がソースの中に残ってしまうので、ついでにそれらを消す置換操作の指定も加えるとこうなります。
$ embed_mark_to_resolver="s|($embed_matcher)| -e '/\\1/r html/_parts/\\2' -e '/^ *\\1 *$/d' -e 's/ *\\1 *//'|"
1つのinclude文から3つの-e
オプションができる形ですね。
さらに、これだとマッチしたinclude文の中にファイルパスのデリミタの/
が入った時に破綻してしまうので、マッチングパターンの正規表現を囲う文字を/
から;
に変えておきます。
$ embed_mark_to_resolver="s|($embed_matcher)| -e '\\\\;\\1;r html/_parts/\\2' -e '\\\\;^ *\\1 *$;d' -e 's; *\\1 *;;'|"
s
コマンドでは単に;
で囲うだけでいいですが、r
コマンドとd
コマンドについては\;マッチングパターン;
という風に最初に\
を付ける必要があります。それをまた全体として1つの文字列の中に入れているので、エスケープがたくさん並ぶ読みにくいスクリプトになってしまいました……まぁこれはしょうがないです。
以上を踏まえて前述のスクリプトの例を書き直すと、こうなります。
build.sh:共通パーツを埋め込む(改良版):
#!/bin/bash
case $(uname) in
Darwin|*BSD|CYGWIN*)
esed="sed -E"
;;
*)
esed="sed -r"
;;
esac
rm -rf html_resolved
cp -r html html_resolved
embed_matcher='<!-- *EMBED\( *([^) ]+) *\) *-->'
embed_mark_to_resolver="s|($embed_matcher)| -e '\\\\;\\1;r html/_parts/\\2' -e '\\\\;^ *\\1 *$;d' -e 's; *\\1 *;;'|"
egrep -r \
--include='*.html' \
"$embed_matcher" \
html_resolved |
cut -d ':' -f 1 |
uniq |
while read path
do
echo "updating $path"
resolve_embedded_resources="sed $(cat "$path" |
egrep -o "$embed_matcher" |
sort |
uniq |
$esed -e "$embed_mark_to_resolver" |
tr -d '\n')"
mv "$path"{,.tmp}
cat "$path.tmp" |
$esed "s/($embed_matcher)( *[^$])/\1"\\$'\n''\3/g' |
eval "$resolve_embedded_resources" \
> "$path"
rm "$path.tmp"
done
筆者が普段使用している環境で新旧それぞれのスクリプトをtime ./build.sh -f
という感じで実行して計測してみたところ、
環境 | 改修前のrealtime | 改修後のrealtime |
---|---|---|
Ubuntu on Let's note CF-SX3 | 3.217秒 | 0.644秒 |
Raspbian on Raspberry Pi2 Model B | 20.072秒 | 2.475秒 |
という感じで実時間で5~8倍の高速化となりました。ラズパイでも、カジュアルに全ファイルを処理させても気にならない程度まで高速になっています。万歳!
sed
やawk
だけでも頑張ればこういう事ができるのかもしれません。でも、ごく基本的な機能だけしか知らなくても「コマンドの実行結果でコマンド列を作る」という一工夫によってできる事の幅はかなり広がると思います。実際、この記事に「grep
の結果をcut | uniq
で加工しなくてもgrep -l
でいける」というフィードバックを頂きましたが、これもまさに「grep
の-l
オプションを知らなくても、基本的な文字列加工コマンドの組み合わせで目的は達成できる」という事の一例と言えるでしょう。
この記事をご覧になった皆さんも、「自分はどうせ基本的な使い方くらいしか知らないから……ガッツリ覚えるつもりもないし……」と卑屈にならず、ぜひ柔軟な発想で問題を解決してみてはいかがでしょうか?
cpp
コマンド)を使うここまで「include文のようなことをsed
でやる」という事を頑張ってみましたが、C言語のプリプロセッサ向けのinclude文そのものと同じ仕様でよければ、それこそCプリプロセッサをそのまま使うという方法もあります。
C言語のプリプロセッサはcpp
というコマンドとして単体で使う事ができ、UbuntuやDebianであればその名もcpp
というパッケージでインストールできます。Gemのパッケージ等でバイナリをビルドする必要がある物をインストールする際の依存関係で既にインストールされているという人も多いのではないでしょうか。これがインストールされている環境であれば、
html/index.html(ソースファイル):
<!DOCTYPE html>
<html lang="ja" xmlns:og="http://ogp.me/ns#" xmlns:fb="http://www.facebook.com/2008/fbml">
<head prefix="og: http://ogp.me/ns# fb: http://ogp.me/ns/fb# article: http://ogp.me/ns/article#">
#include "html/_parts/metadata.html"
<title>シス管系女子って何!? - 【シス管系女子】特設サイト</title>
...
このようにソースに書いておいて
$ cat html/index.html |
cpp -P \
> html_resolved/index.html
と実行すれば、まさにC言語のソースと同じ要領でinclude文を処理した結果を得る事ができます(cpp
コマンドの-P
オプションは、プリプロセッサの行番号情報を出力しないようにする指定です。これを指定しないと、# 1 "<command-line>"
やら# 1 "html_resolved/index.html" 1
やらといった処理中のデバッグ情報的なメッセージまでが出力に含まれてしまいます)。
もちろん、include以外の構文も使えます。ただ、たまたまプリプロセッサ向けの書き方と同じ文字列があると意図せず処理されてしまうというリスクはあります。自分はC言語には詳しくなくて地雷を踏むのが怖いので、しこしこsed
で頑張ろうと思います……
昨年、このツイートを見たんですよ。
夏コミでポルリン(@porurin0 )さんと湊川あい(@llminatoll )さんとお会いしました!
— もっちー黒蜜きな粉フレンズ (@singen_motti) 2016年9月2日
おふたりとも、とてもいい方でした!これからも応援してます٩( ๑╹ ×╹)۶
カフェちゃんとHTMLちゃんの共演でーすwww pic.twitter.com/RlgmYf1PU6
それで「うらやましすぎる!!!」とテンション爆上がりになってしまった勢いで妄想グッズの絵を描いてしまったりなんかしまして。
作者さんが「カフェちゃんブックエンド https://t.co/kYaHsUBNHj いいなあ、見てたら #シス管系女子 もブックエンド作りたくなってきた! 」って言って妄想画像作られたみたいですよ〜😲💦 まさかの実用的グッズ⁉ pic.twitter.com/1iYo4hF3D0
— 利奈みんとbot/マンガでLinux! (@sysadgirl_mint) 2016年9月10日
いやね、元々シス管系女子も何かグッズ作りたいなあとは思ってたんですよ。でも、ステッカーとかマグカップとかの比較的すぐ作れそうな物で読者の方に喜んで頂けるイメージがわかなくて。
思えば、以前Mozilla JapanのFirefoxマーケティング活動のお手伝いをしてた頃にストラップや紙袋やフォクすけぬいぐるみのデザインをやらせてもらった時も、やれ「印刷のペラいのじゃなくてちゃんとしたラバーストラップの方が絶対満足感ありますって!!」だの「紐の色と紙袋本体のコントラストが大事なんですよ!!」だの「もっと鼻の所がツンと出てた方がカワイイですって!!」だのと好き勝手駄目出しして、自分が素直に欲しいと思える物を他人のお金で作ってもらうというヤクザなことをしていたのでした(ぬいぐるみは根来さんの駄目出しもすごかったけど)。
でも、Firefoxならロゴマークがかっこいいからそれだけで満足感あるけど、自作の美(少)女イラストとなると、まず美(少)女という時点で照れの方が勝ってしまうし、そもそも自分の絵自体がそんなに上手なわけじゃないし……と色々考えてしまって、何作っても素直に自分で使える気がしなかったのです。
そんな折に見かけたのが冒頭の写真。見た瞬間に「これだ!!!っていうか自分が欲しいわ!!!!」と思いましたね。
だってシス管系女子って一応技術の本で学習(解説)マンガですやん。「これ使って本棚が技術書で埋まるくらいにいっぱい勉強しましょう!」っていうの、シャレが効いててよくないすか? 作品コンセプトにめっちゃマッチしてません? いや「今どき紙の本かよ」って呆れられそうですけども……
あと、仕様上どうしたって単色にならざるを得なくて、でもそれが却ってポップでかっこよくね?とも思いましたし。自分の絵ってそんな上手な方じゃないから丁寧に描いたり塗ったりすればするほどアラが目立って死にたい気持ちが増してくるけど、デザイン的に処理すれば見る側の脳内で勝手に補って見てもらえて実物以上に良く見えそうだし。
そう思ったらもう止まらなくて、妄想絵だけじゃ満足できず、実現できないものかと水面下でなんやかや動いていたのです。日経BPからは予算が出ない自主制作で、完全に趣味の世界です。
そしてついに実現された試作品がこちら!!! まさにイラストの通りの仕上がり!!!! 素晴らしい!!!!
ですがひとつ難点が。
単色の場合はまだマシで、絵が入ってきちゃうと もうワケが分からないことに…… これは正直盲点でした。デザイン画の時点で表紙画像と合わせたりすれば一発で分かる事だったのに、それを怠ったばかりに、試作品で実物を見るまでこの問題に全く気付いてなかったという。
なので泣く泣く一からやり直しました。 明暗反転版です。 といっても、単純に図案の明暗を反転するだけだとパーツが宙に浮いてしまう箇所が結構ありました。そこで、妄想イラストの単純化された図案から「元絵」にあたる線画を起こして、そこから改めて各所の線を拾い上げる形で図案化するという事をした結果がこれです。
これなら、多少うるさい内容の表紙と合わせても顔がちゃんと判別できます(真っ白の紙でも、本の表紙に対してブックエンド自体の影が落ちるので)。
しかも、タイツの部分を抜いたので、本の表紙の色や柄がそのままみんとちゃんのタイツの色や柄になります。つまりタイツの履き替え遊びができます。試しに手元の本をいくつか合わせてみました。 濃い色はもちろん合いますし…… 文字が入っててもへっちゃら。 帯部分だけ色が違うのも良いですね。 オライリー柄とか。 英字柄とか。 淡い色もいいですね。
試作2号で勝利が見えたので、これをベースに微修正した物を最小ロットで量産して、シス管系女子Advent Calendar 2016にご参加頂いた皆様にお礼として贈答した残りを4月9日の技術書典2に持っていこうと思ってます。利益をほとんど載せない状態でも数千円にはなってしまいます(少数生産だとどうしても割高になってしまう……かといって個人で何百個もこんなかさばる物を発注しても手に負えませんし)が、もし良かったら手に取ってみて頂ければと思います。
以下、デザインするときに分かったこととかコツとかをメモしておきます。
基本的には切り絵の要領なんですが、切り絵の中でも全パーツが繋がってるタイプの形になってないといけないというのがポイントです。
試作1号の図案の時は顔の肌部分を抜いて輪郭を残すデザインにしようとしたのですが、そうすると普通に絵を描くと鼻と口がどうしても輪郭に繋がらないパーツになってしまいます。なので、顔の角度やポーズを工夫してそれらのパーツに髪や目や膝が接するようにすることで、どうにか浮かない形でパーツを残すことができました。
明暗反転版では鼻や口のように短い線は逆に穴を開けるだけなので簡単だったのですが、顔全体を残して輪郭を穴にする場合、輪郭を全部繋げないでちょっとだけ橋渡しする部分を残してやらないといけません。あまり橋をかけすぎると見た目が悪いと思って、目立たない所(普通に線画を描く時に輪郭を途切れさせるような所)に絞って橋をかけてみました。ただ、試作2号では数を絞りすぎて頭の曲線部分が完全に枠から切り離されてしまい、枠が歪むと頭の方が飛び出てしまうようだったので、強度を増すために量産版では頭と枠の間に2箇所橋を増やそうと思ってます。
ということで、ご報告という体裁でのただの見せびらかし記事でした。
2016年4月2日でに始めて、途中からペースダウンしつつも同年12月25日に100枚を達成したので、これを一区切りとして振り返ってみます。
シス管系女子 イラスト100枚まとめ❗/2016春 シス管系女子 イラスト100枚まとめ❗/2016夏 シス管系女子 イラスト100枚まとめ❗/2016秋・冬
背景事情の要点を整理すると、
そんな感じで、現状分析も甘ければ効果測定の方法も定義できないまま、とにかく数を増やさねばという焦燥感にのみ駆られて始めたのでした。
広報的な成果は、期待したほどには無かったように思います。
タイムラインによく艦これ等のラフなイラストが流れてきていたので勘違いしてしまっていましたが、あれは作品のファン同士のコミュニケーション、あるいは神絵師とそのフォロワーの方々のコミュニケーションという文脈のものであって、すでにある巨大なコミュニティからこぼれ落ちる雫のようなものなのですよね。焦りと「これくらいならやれるかも」という妥協とで完全に見誤ってしまっていました。
それに、シス管系女子というコンテンツの最も大事な価値は解説する事にこそあるわけで、日常の一コマを切り取ってもプレビューになりません。宣伝としてやるなら1枚絵ではなく、本編同様の解説絵にするべきだったのだと今となっては思います。1枚絵で喜んで頂けるのは既存のファンの方だけですし、落描きレベルの雑なイラストではそれすらも……
自分の中で絵を描く事の心理的ハードルが下がったのは、収穫と言えると思います。学生時代にはノートの隅に落描きをしていましたが、社会人になってからはその機会がなくなり、なにか特別な理由がないと絵を描かないようになってしまっていました。1日に1時間だけでも無理やりにでも絵を描く時間を設けたことで、季節のイラストもそれほど気負わず描くことができました。
副次的な効果として、絵描きの方との交流のきっかけになったのも良かったです。絵を描く事のハードルが下がったことで、他の人へのお祝いイラストや、オリジナルキャラの絵等を描きやすくなりました。億劫がっていたら、気に入った絵の描き手の方にご挨拶すらできないままだったでしょう。
また、なるべく手をかけずに見栄えのする絵を描くノウハウが多少は身に付いたとも思っています。例えば、自分の場合はペン入れ工程が最も時間を食うため、それをスキップするやり方を取るようになりました。また、背景や小物などについて、今まではいつも律儀に線画を仕上げてから塗っていたのを、いきなり塗りから始めるというやり方を取れるようになりました。夏に描いたヒマワリや七夕の笹、仙台七夕の飾り等は、このやり方でなければもっと時間がかかっていたでしょう。
総評としては、よく頑張ったけどピントがずれてたね、というあたりでしょうか。
来年以降は、無理の無い範囲までペースを落としつつも、当初の目的である広報に繋がるように、解説を主にしたイラストの割合を増やしていきたいです。
今までアドベントカレンダーには熱心に参加した事はなかったと思うのですが、今年はシス管系女子の草の根広報活動の一環として、自分でもびっくりするくらい力を注いでおりました。
まず、自分で初めてシス管系女子 Advent Calendar 2016というアドベントカレンダーを立てました。IT系のクリスマスといえばアドベントカレンダーが定番という印象があったので、思いつきでのチャレンジです。
とはいえ、現状のWebでの認知度を鑑みるに読者の方のご協力だけで全日程はまず埋まらないだろうと見込んでいたため、全25コマの構成で事前にマンガを用意しておき、最悪の場合でも1日1コマ公開していけば日程は埋められるという準備を整えた上でスタートしました。Webでの試し読み代わりに自由に使える話を増やしたいという動機が元々あったので、「描くつもりだった話を描ければそれでまず成功。アドベントカレンダー関係のブームに乗っかって露出が増えれば一石二鳥。読者の方のご協力を得られれば一石三鳥」というつもりでした。
蓋を開けてみると、およそ3割の日程を読者の方に寄稿して頂けており、予想以上の結果に大変嬉しい思いをしております。自分なんかの思いつきに乗っかってくれた方がこんなにいた事、エールを頂けた事がとても励みになりました。本当にありがとうございます。
一方で、課題も色々あったと思っています。
以上を総合すると、今回誰が一番得をしたかというと自分自身だった(自由に使える特別編を1つ増やす契機になった、読者の方々からのエールを頂けて元気が出た)という気がします。つまり俺得。自己満足に付き合わせるだけになってしまってすみませんでした……こんな風に人の厚意を食んで自分のやる気に変えるような事ばかりしてたら信頼を損なうばかりですよね。ほんとに。
元々、自分から見つけてきてくれる人だけを対象にしていても認知は広がらないので、どこか「外」に出ていく必要があるという事は認識していました。
そんな折、Geek Women Japan 2016の懇親会で、「シス管系女子」を読まれた方から本編で扱っていなかった話についての質問を頂きました。それに対する回答を記事化して公開するにあたり、ちょうどそのタイミングで各アドベントカレンダーの参加募集が始まっていたため、「外」のアドベントカレンダーに参加すればその読者層に認知を広げる機会になるのでは?と思い至りました。ただ、無差別に参加して宣伝をばらまくだけではただのspam行為なので、
といったあたりの事を考えながらエントリーを増やしていった結果、以下の8記事ができました。
結論としては、この試みは一定の成功を見たと思っています。特にShellscript Advent Calendarに投稿した記事がどういうわけか若干バズってくれて、ここからの流入が突出して多かったです。この記事は日を開けて何度か紹介されていて、その度にアクセスが発生するという状況になっていました。
ただ、このアクセス増は狙って起こせたものではなく(記事のタイトルを付ける際に若干挑発的なタイトルを意識したのは事実ですが……)、それ以外の記事のPVはそれほど伸びなかった事、また増加したアクセスも継続的なものではなくあくまでスパイク状の一過性の増加に留まった事から、やるならもっと継続的にやった方が良さそうという事は思っています。そうする事で、「シス管系女子」の内容や技術レベルに対する懐疑的な見方を払拭する材料を増やせれば、という思いもあります。
自分のサイト内でコンテンツを公開するよりも、技術情報であればQiitaのように、多くの人が見ていて且つ情報をシェアしやすい場所で公開するようにした方が良いという事も実感しました。
会社の業務の一環で、Groonga Advent Calendar 2016にもGroonga名義でいくつか記事を投稿しました。
これらはGroongaの知名度向上や盛り上がり感の演出、既存ユーザ・新規ユーザ向けの情報の整備を目的に行いましたが、シス管系女子の場合と同様、これ自体が知名度向上に役立ったという事は言えなさそうです。
以上をまとめると、認知度向上のための手段としてアドベントカレンダーを使う時は、既に人が多く集まっている場所(サイトもそうだし、アドベントカレンダーもそう)に飛び込んでいくのが有効なようです。 という、当たり前といえば実に当たり前の話なのでした。
このエントリはGit Advent Calendarとのクロスポストです。(→Qiitaの方の投稿)
今日の記事では、「SSHって何?」や「SSHは知ってるし時々使うけど、普段そんなに使う機会は無い」くらいのレベルの方を対象に、SSHとGitの組み合わせだけでこんな事もできるんですよ!という事をご紹介します。アドベントカレンダー的には最後の方の日なのに初心者向けの話で恐縮ですが、まあせっかくなのでおつきあい下さい。
妻・夫を愛してるITエンジニア Advent Calendar 2016その2をご覧の皆様、はじめまして。Piroといいます。
自分は現職のITエンジニアですが、会社の仕事とは別に、日経LinuxというLinux関係の技術情報の月刊誌でシス管系女子と題した漫画形式の記事を連載しています。
基本的に話も技術面での検証も作画も全部一人でやっているのですが、そのせいで内容を冷静な目で見られなくなってしまうことがあります。そんな時、幸いなことに妻も現職のITエンジニアなので、「話の展開に無理が無いか?」とか「この解説で通じるか?」とか不安を覚えると度々、妻に下描きを見せて率直な感想を聞かせてもらっています。率直に言って大変助かっています。 だというのに、最近は連載の〆切に追われて平日も休日も一杯一杯になってしまっている事が多く、妻には迷惑をかけてばかりで申し訳ない限りです。
さて。「シス管系女子」はとある企業の新米システム管理者の女の子「みんとちゃん」が主人公なのですが、今日の話はみんとちゃんの衣装の話です。
自慢じゃないですが、自分はファッションセンスがありません。そんな自分が女性キャラの衣装を自分でゼロから考えても碌な事にならない、しかし巷のファッション誌を参考にしようにも色々ありすぎてどんな服を着せればいいか分からない、ということでみんとちゃんの衣装はもっぱら妻の私服を参考にさせてもらっています。
<script src="http://source.pixiv.net/source/embed.js" data-id="58957204_7f2f3332231d9e925534c71343fcecc9" data-size="medium" data-border="on" charset="utf-8"></script><noscript>
シス管系女子 利奈みんと 作画設定(2016年版) by Piro/結城洋志 on pixiv
</noscript>(そんな訳なので、たまに読者の方に「みんとちゃんの服装かわいいですね!」と言っていただけると、「でしょ!?かわいいっすよね!!」と全力で同意して間接的にのろけているのです。)
実をいうとみんとちゃんの衣装には単純にデザインのみならず、ポリシー面についても妻から学んだ事が反映されています。 それは、「男にウケるためでもなければ、周囲に文句を言われないためでもない、自分(みんとちゃん自身)のために自分(みんとちゃん)が好きな服を着る」ということです。
聞いた所によると、妻の最初の就職先は色々とお堅い会社で、服装規定も結構厳しかったそうです。 女性社員は私服であっても地味目のおとなしい服でなければならず、そのため妻も本人の好みに合わない服を買って着ていたそうです。 そんな訳なので、転職して服装既定の厳しくない会社に移ってからはその頃の服はほとんど全くと言っていいほど着なくなってしまい、結局、クローゼットの中を整理した時にそれらはほとんどすべて処分してしまいました。
社会人、特に普通に会社に通勤するという働き方の人にとっては、人生の中でもそれなりの長い時間を会社で過ごすことになります。 そんな長時間を、いたくもない姿の自分でいることを強いられるというのは実に不毛なことです。
せっかくなら、周囲の目を気にして好みに合わない格好を我慢してするのではなく、自分が本心から「可愛い!」とか「格好いい!」とか「楽だ!」とか思えるような格好でいられる方がいいに決まっていますよね。 一度きりの人生なのですから、しなくてもいい無理をせずに自分の生きたいように生きるのに越したことはないです。
実際に作品中で描いてる服のチョイスは妻の好みと僕の好みの論理積なので、どうしても偏りが生じてしまっているのは否めない(実際には妻はジーンズをはいている時も多々あります)のですが、それでも描き手の思いとしては、(ネタのコスプレ以外では)少なくともみんとちゃん本人が着たいと思わないであろう服は着させないようにしたいし、本人が見せたくないであろう物は見せないようにしたいと思っています。
例えば、みんとちゃんは丈の短いワンピースやミニスカートを着ていることが多いですが、下に短パンをはいているので絶対にパンチラしないということにしています。これには「掲載誌がお堅いのでえっちなのはNGだから」という理由もありますが、それより何より、彼女はかわいい服を着たいだけであってパンツを見せたい訳ではないのです。周囲の男性社員に対するサービスでかわいい服を着ているのではなく、彼女自身がその服を好きだから着ているのです。
「シス管系女子」は技術の話の学習漫画ですが、それとは別のささやかな裏テーマとして、みんとちゃんというキャラクターのありようを通して、女性エンジニアが当たり前に自分の生きたいように生きられている様子を描きたいという思いが自分にはあります。
それが妻の仕事環境や生活環境に何か直接影響を及ぼすわけではありませんが、「そういうのが当たり前」という様子を描いて、そういうコンテンツが増えていくことで、妻や後に続く人達が少しでも生きやすい世の中になってくれれば。 そう思って自分は今月号も、誰に頼まれたわけでもないのにみんとちゃんに先月号とは違う衣装を着せている次第です。 (そして絵を使い回せなくなり、また自分で自分の首を絞めているのでした……)
以上、飛び入りで妻・夫を愛してるITエンジニア Advent Calendar 2016その2の8日目に参加してみました。 明日の記事もお楽しみに!
このエントリはShell Script Advent Calendarとのクロスポストです。(→Qiitaの方の投稿)
前回は自作のBashスクリプト製Twitterクライアントをネタに実装を解説しましたが、今日は他の言語で多少のプログラミング経験はあるんだけど、どうにもシェルスクリプトは苦手だ……という人のための、シェルスクリプトによるプログラミングの勘所を解説してみようと思います。多分、プログラミング入門レベルの人や上級レベルの人よりは、中級レベルにいる人や、初級から中級以上に成長したいという感じの人にとって役に立つ話だと思います。
結論から先にいうと、「引数」と「配列」の事を忘れればシェルスクリプトはグッと書きやすくなります。というおはなしです。タイトルからして期せずして前の日の方の話の全否定になっちゃいました。ごめんなさい、他意は無かったんです……
このエントリはチャットボット Advent Calendarとのクロスポストです。(→Qiitaの方の投稿)
チャットボット Advent Calendarをご覧になっているような方々はフレームワークやニューラルネットでディープラーニングなAIといった最新のbot事情に関心の強い方が多いと思うのですが、今日の記事は時代に逆行しまくって、Bashスクリプトで昔ながらの人工無脳botを作りましたというお話です。
この記事では以下のことを書いています。
このエントリはShell Script Advent Calendar 2016とのクロスポストです。(→Qiitaの方の投稿)st
Linux Advent Calendarの方にGUIアプリのスクショを定期的にSlackに流すシェルスクリプトの話でエントリーしたのですが、Shell Script Advent Calendar的にはそれをこっちを投稿した方が良かったかもと今更思いつつ、今日は別の話題です。
シェルスクリプト製Twitterクライアントには恐怖!小鳥男やtweet.sh(同名の別実装)などいくつか実装例がありますが、自分も2015年末頃からtweet.shという汎用のTwitterクライアントを開発しています。この記事ではtweet.shをネタに、以下の事を解説します。
nkf
といくつかの一般的なコマンドでURLエンコードするキー1=値1,キー2=値2,...
の形に変換する