サイト開設のお知らせ
お久しぶりです。
はてなブログのカスタマイズという形でHTMLやCSSを学習していましたが、自分で一からCMSを構築するスキルが身についたので、Laravel・Vue.js・サーバ構築などの勉強も兼ねて自分専用のブログサイトを立ち上げました。
当ブログは2020年7月20日に開設し、初記事はLaTeXの環境構築の雑なメモ書きでしたね… あの頃はパスの意味すらわかりませんでしたが、初めて黒い画面に触れたその日がすべての始まり。
LaTeXのマクロ作りを足掛かりにプログラミングを始めて10ヶ月。良縁もあり、いろいろな経験をさせていただき、ありがたいことに来春からプログラマとしての就職も決まりました。
ちなみに新ブログサイトはこんな感じです。LaTeXで作ったPDF教材などもすべて公開しています。
今後は自サイトでブログを投稿していきますが、思い出が詰まっているので当ブログの記事はそのまま残しておきます。
稚拙な記事ばかりで今となっては恥ずかしくもありますが、ご愛読ありがとうございます。 新ブログサイトにも遊びに来ていただけたら嬉しいです。
tomixy
【改良版】VScodeでのDart Sass環境構築、さらに自動で作業フォルダ作成
jQueryを勉強中なのだが、動作を確認するにはhtmlファイルを作成し、jsファイルを作成し、cssファイルを作成し、場合によっては画像も作業フォルダに入れておかなければならない。
これらをすべて同じフォルダに入れておくとごちゃごちゃになるので、作業フォルダ内にいくつかフォルダを作成し、jsファイルはjsフォルダに、cssファイルはcssフォルダに、画像はimagesフォルダに入れておくことにしよう。
また、私はsassを用いてcssを書いているので、scssファイルを入れておくsassフォルダも作っておこう。そしてコンパイルによって生成されたcssファイルはcssフォルダ内に格納されるようにしたい。
…さて、こんなことをいちいち手動で行うのは泥臭すぎるので、ここはプログラミングの力を借りて自動化しよう、というのが本記事の主題である。
快適なWebページ制作環境となる雛形フォルダを一発で作成できるようにしたい。さらに、前記事のコードを改良し、scssファイルのコンパイルも簡単に行えるようにしたい。
本記事で実現するもの
快適なWebページ制作環境となる雛形フォルダの作成
プロジェクトフォルダを置きたいフォルダをVScodeで開いた上で、shift ctrl B
(macならshift(⬆️) command B
)を押すと、画面上部が次のようになる。
そこで、Sass new project create
を選択する。
デフォルトではプロジェクトフォルダ名がsampleになっているが、ここはお好みの名称に書き換えてEnter
キーを押せば良い。
sampleフォルダの中身を覗いてみよう。
自動的にimagesフォルダ、cssフォルダ、sassフォルダ、jsフォルダ、index.htmlが作成されているのがわかる。config.rbについては後述する。
それぞれのフォルダの中身も覗いてみよう。
scripts.js、style.scss、index.htmlは空のファイルであるので、この中にコードを書いていけば良い。もちろん、お好みでファイル名を変えることもできるが、大概はこのタイトルのままでいいだろう。
また、cssフォルダ内にはreset.cssが用意されている。これは基本的に編集せず、そのままhtmlファイル内で読み込めば良い。
こうして、ショートカットキーとプロジェクト名の入力だけで、快適にWebページ制作を始められる環境が整う。
.scssファイルのコンパイル
コンパイルしたいscssファイルをVScodeで開いた状態で、
1. shift ctrl B
(macならshift(⬆️) command B
)を押す
2. Sass compile
を選択する
すると、そのscssファイルがcssファイルに変換され、cssフォルダ内に吐き出される。
実現のための設定
さて、上述の便利機能をVScodeに増設するまでの過程をこれから解説していく。
インストールするもの
- Visual Studio Code
-
コードを編集するためのテキストエディタ。テキストエディタとは名ばかりで、実際のところこれ一つでなんでもできる統合開発環境。
普通、統合開発環境といえば各言語専用だが、VScodeは本当になんでもできる。今のところ、C, C++, C#, Python, JavaScript, Ruby, HTML, CSS, Sass(Scss), LaTeX…などあらゆる言語をここで編集し、実行できている。
適当にググってカスタマイズしてほしい。 - node.js
- node.jsをインストールすると使えるようになるnpmコマンドがこの記事では(というかいろいろな場面で)必須になる。
インストール方法はOSによって異なるようなので、ググって… - Ruby(Compassと共存させる場合)
-
Sassコードをコンパイル(ブラウザが認識可能なCSSに変換)するために必要。
Macは最初から入っているのでスルー。Windowsの方は申し訳ないがググって… - Sass(SCSS)
-
CSSをプログラミング言語のように効率的に書ける言語。
黒い画面からgem install sass
でインストールできるはず。Macの方はsudo
を先頭につけて。 - compass
-
Sassで使える便利グッズ集(Sassのミックスインや関数をライブラリ化したもの)。Sassのコンパイラとしても使える。
黒い画面からgem install compass
でインストールできるはず。Macの方はsudo
を先頭につけて。 Compassのサポートは2016年に終了しているので、今から使い始めるのは推奨されていない。
この記事では、基本的に雛形作成(ディレクトリの整理整頓)とreset.cssの生成のためだけにCompassを利用し、Sassのコンパイルには、速度が遅いCompassコマンドは使用せず、これからも新機能が増築されていく最新のDart Sassを用いる。
しかし、どんどん新たなツールが生み出されているとはいえ、CSSスプライト作成機能など、未だCompassにしかない機能もいくつかあるらしい。そんなわけで、いつでもCompassも使えるように環境だけは残しておくことにする。
npmコマンドでインストールするもの
まず、sassのコンパイルに必要なものをインストールする。
前記事ではローカルインストールしていたが、プロジェクトフォルダ作成の度にいちいちダウンロードするのは時間がかかるので、個人で使う分にはグローバルインストールで良いと思う。というわけで-g
オプションをつけている。
Terminal or CommandPrompt
npm install -g sass fibers
次に、ベンダープレフィックス(ブラウザごとの表示の差異をなくすために必要なコード)の自動付与に必要なものをインストールする。
Terminal or CommandPrompt
npm install -g postcss postcss-cli autoprefixer
初期設定
MySassCreate.shの配置
次のMySassCreate.shをどこかしらに置く。
zshでしか動作確認していないが、bashでも使えるはず。(というかそもそもbashのためのコード)
windowsの方は…そうだなあ。私はwindows時代、この記事を見ながらbashを導入した気がする。
参考までに、私はホームディレクトリ/Users/tomixy
にMyShellScript
というフォルダを作って、その中にMySassCreate.shを置いている。
置き場所に応じて、以降登場する/Users/tomixy/MyShellScript/
をそのディレクトリ名に書き換えてね。
macの方はchmod u+x /Users/tomixy/MyShellScript/MySassCreate.sh
を実行するのを忘れずに。これを実行しないとMySassCreate.shは動きません。
MySassCreate.sh
#!/bin/sh
PROJECT=$1
compass create $PROJECT
cd $PROJECT
mkdir css
cd stylesheets
rm -f ie.css
rm -f print.css
mv screen.css ../css
cd ..
rm -d stylesheets
cd css
mv screen.css reset.css
cd ../sass
rm -f *.scss
touch styles.scss
cd ..
mkdir js
cd js
touch scripts.js
cd ..
mkdir images
touch index.html
task.jsonを開く
shift ctrl P
(macならshift(⬆️) command P
)task
と入力ユーザータスクを開く
をクリック
task.jsonの編集
次の内容をtask.jsonにコピペする。
task.json
{
// See https://go.microsoft.com/fwlink/?LinkId=733558
// for the documentation about the tasks.json format
"version": "2.0.0",
"tasks": [
{
"label": "Sass new project create",
"type": "shell",
"command": "/Users/tomixy/MyShellScript/MySassCreate.sh",
"args": ["${input:SassProjectName}"],
"group": {
"kind": "build",
"isDefault": true
}
},
{
"label": "Sass compile",
"type": "shell",
"command": "cd ${fileDirname} && cd .. && sass ${file}:css/${fileBasenameNoExtension}.css --style expanded --sourcemap=none && cd css && npx postcss *.css --use autoprefixer -d ./ ",
"group": {
"kind": "build",
"isDefault": true
}
},
],
"inputs": [
{
"id": "SassProjectName",
"description": "Sass new project name:",
"default": "sample",
"type": "promptString"
}
],
}
MySassCreate.shのコード解説
シェバン
MySassCreate.shの一部
#!/bin/sh
『これはbashスクリプトですよ〜』とPCに宣言する部分。この記述のあるファイル名を黒い画面で入力+Enterすると、PCは自動的にbashでこのスクリプトを実行しようとする。
もしzshで実行したのなら、この部分は『これはbashスクリプトですよ〜、でもあなたはzshみたいね…まあいいわ、うまくやってあげる。』とPCに呼びかける意味合いになる。 Z ShellのWikiより、
zshを/bin/shとして実行したとき、Bourne Shellの振りをするようにできる。
bashはBourne Shell、zshはZ Shellの略らしいよ。
しかしシェルとはいえ、Power ShellではMySassCreate.shは実行できないと思われる。構文が結構違うらしい。
コマンドライン引数の取得
MySassCreate.shの一部
PROJECT=$1
/Users/tomixy/MyShellScript/MySassCreate.sh パッケージ名
としてこのシェルスクリプトを実行するわけだが、このとき与えたパッケージ名
が$1
に格納されている。
この定数を、これからはPROJECT
と呼ぶよ〜という意味。
不思議なことに、PROJECT = $1
としてはダメらしい。=
の左右にスペースを空けてはいけません。
compassプロジェクト(npmパッケージとなるフォルダ)の作成
MySassCreate.shの一部
compass create $PROJECT
compass create フォルダ名
で、指定したフォルダ内をSass作業用に整理してくれる。具体的には、次のような中身になる。
私も詳しくは知らないが、
- ie.css
- Internet Exprorer対応のCSSを書くための雛形
- print.css
- 印刷用のCSSを書くための雛形
- screen.css
- 画面表示用の(つまり普通の)CSSを書くための雛形(CSSリセットの宣言つき)
- config.rb
- compassコマンドでのコンパイル用の設定を書いておくファイル
…らしい。
とはいえ、前述したようにcompassのサポートは既に終了しているので、ここで作られたie.cssを使ったところで最新のものに対応できるかはわからない。
シェルスクリプトでは、#
以降は実行されない部分になる。よって、ここには何を書いても良い。
#!
だけは例外なので注意。#!
で始まるものはシェバンとして解釈されてしまう。
compassを使わない場合は、compass create
の前に#
を置く(コメントアウトする)ことでcompass create
コマンドを無効化にする。
また、その場合はcompassが作るはずだったフォルダを手動で作成しなければならないため、# mkdir $PROJECT
の先頭の#
を取る(コメントインする)。
言い忘れていたが、シェルスクリプトでは、事前に宣言しておいた変数は$変数名
で参照できる。
フォルダ内をWeb制作用にカスタマイズする
MySassCreate.shの一部
cd $PROJECT
おそらく、今のカレントディレクトリは$PROJECT
フォルダを置いた場所(つまり、$PROJECT
フォルダの手前のフォルダ)になっていると思うので、cd $PROJECT
でプロジェクトフォルダ内に移動する。
cd フォルダ名
- 指定したフォルダ内に移動
MySassCreate.shの一部
mkdir css
compassで自動作成した場合、拡張子が.css
のファイルがstylesheetsフォルダに格納されている。
わかりづらいので、拡張子が.css
のファイルはcssフォルダに格納されるようにしたい。そのために、まずはmkdir css
でプロジェクトフォルダ内にcssフォルダを作成する。
mkdir フォルダ名
- 今いるフォルダ内に指定した名前のフォルダを作成
MySassCreate.shの一部
cd stylesheets
rm -f ie.css
rm -f print.css
mv screen.css ../css
cd stylesheets
でstylesheetsフォルダ内に移動し、この中にあるie.cssとprint.cssは削除し、screen.cssは新たに作成したcssフォルダに移動させる。
../css
は、一つ前のディレクトリに戻って(stylesheetsディレクトリから出て)、その後cssディレクトリ内に入った場所を表す。
rm -f ファイル名
- 指定したファイルを削除(
remove
)する
(-f
は警告を表示せず処理を実行するためのオプション) mv ファイル名 移動先フォルダのパス
- 指定したファイルを指定したフォルダに移動(
move
)させる
MySassCreate.shの一部
cd ..
rm -d stylesheets
cd ..
で今いるstylesheetsフォルダから出て、stylesheetsフォルダを削除する。
cd ..
- 今いるフォルダから出る(一つ前のフォルダに戻る)
rm -d フォルダ(ディレクトリ)名
- 指定したディレクトリ(
-d
)を削除(remove
)する
MySassCreate.shの一部
cd css
mv screen.css reset.css
cd css
でcssフォルダ内に移動し、mv screen.css reset.css
でscreen.cssをreset.cssに改名する。
mv ファイル名 変更後のファイル名
- ファイル名を変更する
MySassCreate.shの一部
cd ../sass
rm -f *.scss
touch styles.scss
cd ..
cd ../sass
でcssフォルダから出たところにあるsassフォルダに移動する。
その後、rm -f *.scss
でsassフォルダ内の全てのファイルを消去する。*
はワイルドカードといい、どんな文字列でもよいことを表す。つまり、*.scss
は拡張子が.scss
のすべてのファイルである。
touch styles.scss
で空のファイルstyles.scssを作成し、cd ..
でsassフォルダから出る。
touch ファイル名
- 指定した名前のファイルを作成する。このコマンドで作成したファイルの中には、何も書かれていない。
MySassCreate.shの一部
mkdir js
cd js
touch scripts.js
cd ..
mkdir js
でプロジェクトフォルダ内にjsフォルダを作成し、cd js
でjsフォルダ内に移動する。
touch scripts.js
で空のファイルscripts.jsを作成し、cd..
でjsフォルダから出る。
MySassCreate.shの一部
mkdir images
プロジェクトフォルダ内にimagesフォルダを作成する。
MySassCreate.shの一部
touch index.html
プロジェクトフォルダ内に空のファイルindex.htmlを作成する。
task.jsonのコード解説
MySassCreate.shの実行
task.jsonの一部
"tasks": [
{
"label": "Sass new project create",
"type": "shell",
"command": "/Users/tomixy/MyShellScript/MySassCreate.sh",
"args": ["${input:SassProjectName}"],
"group": {
"kind": "build",
"isDefault": true
}
}
],
"inputs": [
{
"id": "SassProjectName",
"description": "Sass new project name:",
"default": "sample",
"type": "promptString"
}
]
"tasks": [ ]
"label"
では、shift ctrl B
(macならshift(⬆️) command B
)を押した時に表示されるタスク名を設定する。
今回実行する
Run Command
/Users/tomixy/MyShellScript/MySassCreate.sh プロジェクト名
というコマンドはターミナルで実行するものなので、"type"
はshell
とする。
引数であるプロジェクト名
は、"args"
で管理する。
${input}
は入力された文字列を表し、後の設定時に参照するために${input:id}
という書式でid(名前)をつけておく。
"group"
では、このタスクの分類を指定する。
"kind"
には開発用タスクを表すbuild
か、デバッグ用タスクを表すtest
を指定することができる。今回は前者である。
shift ctrl B
(macならshift(⬆️) command B
)を押したときにすぐに実行できるように、"isDefault": true
としておく。
inputs: [ ]
idがSassProjectName
である入力引数の設定を行う。
"description"
で何を入力すべきかの説明文を指定し、"default"
でデフォルト入力値を設定する。
最終的にこのコマンドはターミナルで実行されるので、入力タイプはターミナルに表示する文字列であるpromptString
と指定する。
Sassコンパイルコマンドの設定
task.jsonの一部
{
"label": "Sass compile",
"type": "shell",
"command": "cd ${fileDirname} && cd .. && sass ${file}:css/${fileBasenameNoExtension}.css --style expanded --sourcemap=none && cd css && npx postcss *.css --use autoprefixer -d ./ ",
"group": {
"kind": "build",
"isDefault": true
}
}
shift ctrl B
(macならshift(⬆️) command B
)を押し、Sass compile
を選択したときに実行されるコマンドは、次のものである。
"command"
cd ${fileDirname} && cd .. && sass ${file}:css/${fileBasenameNoExtension}.css --style expanded --sourcemap=none && cd css && npx postcss *.css --use autoprefixer -d ./ ",
&&
を使うことで、複数のコマンドを一気に実行することができる。
コマンド1 && コマンド2
- コマンド1が正常に実行されたら、コマンド2を実行する
&&
で結ばれたコマンド一つ一つを見ていこう。
task.jsonで使える変数
${fileDirname}
- task.jsonで使える変数で、今開いているファイルが置かれているディレクトリを表す。
${file}
- task.jsonで使える変数で、今開いているファイルのパスを表す。
${fileBasenameNoExtension}
- task.jsonで使える変数で、今開いているファイル名から拡張子を除いたものを表す。
今開いているファイルがstyles.scssなら、${fileBasenameNoExtension}
はstyles
を表す。
コンパイルコマンドの解剖
cd ${fileDirname}
- 今はコンパイルしたいscssファイルを開いているはずなので、
${fileDirname}
はsassフォルダを表す。
つまり、sassフォルダ内に移動するという意味。 cd ..
- sassフォルダから出て、プロジェクトフォルダに移動する。
sass コンパイルするファイル:コンパイル後のファイル
sass
コマンドで、拡張子が.scssまたは.sassのファイルをコンパイルし、cssファイルに変換できる。sass ${file}:css/${fileBasenameNoExtension}.css
- コンパイルしたいファイルは今開いているファイルなので、
${file}
とする。
コンパイル後のファイルはcssフォルダ内に置きたいのでcss/
をつけ、その中にコンパイル前のscssファイルと同名のcssファイル(${fileBasenameNoExtension}.css
)として出力する。 --style expanded
- コンパイル後のcssファイルの書式を一般的なものに指定するオプション。
他にもいろいろな書式にコンパイルすることができる。詳細を知りたい方はこのブログを読むのがオススメ。 --sourcemap=none
- ソースマップファイルを出力しないためのオプション。cssフォルダの中にはcssファイルだけを入れておきたいので、このオプションを付与した。
cssが長文になる場合はこのオプションをつけない方が良い気がする。
他にもいろいろなオプションがある。その他のオプションや、ソースマップファイルの存在意義についてはこのブログを読むのがオススメ。
ベンダープレフィックス自動付与コマンドの解剖
cd css
- コンパイル済みのcssファイルを改変するため、cssフォルダ内に移動する。
npx postcss *.css
- postcssは、cssファイルを解析、改変するツール。ここでは解析対象をcssフォルダ内にあるすべてのcssファイルにしている。
--use autoprefixer
- autoprefixerは、ベンダープレフィックスを自動付与するツール。
postcssによって解析したcssファイルにベンダープレフィックスを付与する。 -d ./
-d
は、ベンダープレフィックス付与後のcssファイルの置き場所を指定するためのオプション。.
は今いるフォルダ(cssフォルダ)を表し、./
とすることでcssフォルダ内にベンダープレフィックスが付加されたcssファイルが置かれることになる。
同名のファイルは自動的に置換されるので、結局は元のcssファイルを書き換えた事になる。
index.html編集用スペニットの登録
cssファイルやjsファイルを外部に配置すると、htmlファイル内でファイルを読み込むために必ず記述しなければならないコードが増えてしまう。
それをいちいち書くのも面倒なので、htmlファイルの雛形(スペニット)を作っておこう。
html.jsonの開き方
html.jsonの編集
html.jsonの{ }
の中に、次のコードを追加し、保存する。
html.json
"external jQuery and JavaScript and CSS" : {
"prefix": "exjQJSCSS",
"body": [
"<!DOCTYPE html>",
"<html lang=\"ja\">",
"<head>",
"\t<meta charset=\"UTF-8\">",
"\t<meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\">",
"\t<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">",
"\t<title>$1</title>",
"\t<link rel=\"stylesheet\" type=\"text/css\" href=\"css/reset.css\" />",
"\t<link rel=\"stylesheet\" type=\"text/css\" href=\"css/${2:styles}.css\" />",
"\t<script src=\"https://cdnjs.cloudflare.com/ajax/libs/jquery/${3:3.4.1}/jquery.min.js\"></script>",
"\t<script src=\"js/${4:scripts}.js\"></script>",
"</head>",
"<body>",
"\t$5",
"</body>",
"</html>"
]
}
スペニットの威力
早速、登録したスペニットをindex.htmlで使用してみよう。
読み込むcssファイルやjsファイルの名称は、MySassCreate.shでデフォルトで作成されるファイル名になっている。
特に変更する気がなければ、そのままtabキーを押すことでスキップできる。
また、jQueryは端末にダウンロードすることなく使えるように読み込んである。使用するバージョンは適宜変更してほしい。
私は今のところはデフォルトのまま使っていて支障がないので、タイトルを入力した後は4回tabキーを押し、すぐにbody内部の編集に取り掛かっている。
vscodeでのDart Sass開発環境構築、さらにシェルスクリプトで全自動化【Autoprefixer使用・Compass共存可】
2021/4/19追記
この記事に掲載しているソースコードは、時々原因不明のエラーを吐きます。改良版のソースコードをこちらの記事にて公開しました。
この記事はSass環境構築の解説というよりも、npmやシェルスクリプト文法(特にパイプ)の解説としてご活用いただければ幸いです。
Webサイト制作本を何冊か読み、『先ほどのCSSをコピペして〜』という記述に若干の反発を感じ始めた頃、Sassの存在を知った。
Sassを使うと一般的なプログラミング言語のような分岐処理、繰り返し処理、演算などを使ってCSSを書くことができる。念願の脱コピペ。やっぱりみんな考えることは一緒だよね…
- 2021/4/19追記
- インストールするもの
- npmの意義
- Dart Sassをコンパイルするまでの道のり
- Sassを使う環境(npmパッケージ)作成の自動化
- 初期設定
- 実行方法
- 自動化シェルスクリプトMySassCreate.sh全文
- 作成した自動化ツールの使い方
- VScodeで簡単にパッケージ作成&Sassコンパイルできるようにする
- あとがき
※Compassの使用方針について
Compassのサポートは2016年に終了しているので、今から使い始めるのは推奨されていない。
この記事では、基本的に雛形作成(ディレクトリの整理整頓)のためだけにCompassを利用し、Compassを使わない場合にも似たようなディレクトリ構成が用意されるようにコードの修正点を明記していく。
Sassのコンパイルには、速度が遅いCompassコマンドは使用せず、これからも新機能が増築されていく最新のDart Sassを用いる。
しかし、どんどん新たなツールが生み出されているとはいえ、CSSスプライト作成機能など、未だCompassにしかない機能もいくつかあるらしい。そんなわけで、いつでもCompassも使えるように環境だけは残しておくことにする。
インストールするもの
- Visual Studio Code(この記事では必須)
-
コードを編集するためのテキストエディタ。テキストエディタとは名ばかりで、実際のところこれ一つでなんでもできる統合開発環境。
普通、統合開発環境といえば各言語専用だが、VScodeは本当になんでもできる。今のところ、C, C++, C#, Python, JavaScript, Ruby, HTML, CSS, Sass(Scss), LaTeX…などあらゆる言語をここで編集し、実行できている。
適当にググってカスタマイズしてほしい。 - node.js(この記事では必須)
-
node.jsをインストールすると使えるようになるnpmコマンドがこの記事では(というかいろいろな場面で)必須になる。
インストール方法はOSによって異なるようなので、ググって…
Dart SassやAutoprefixerはPC本体には格納せず、npmコマンドでその都度ローカルインストール(自分で作ったSassコードなどと一緒に共有できるように作業ディレクトリにインストール)するので、Compassと共存させない場合はこれ以上のインストール作業は必要ない。 - Ruby(Compassと共存させる場合)
-
Sassコードをコンパイル(ブラウザが認識可能なCSSに変換)するために必要。
Macは最初から入っているのでスルー。Windowsの方は申し訳ないがググって… - Sass(Compassと共存させる場合)
-
CSSをプログラミング言語のように効率的に書ける言語。
黒い画面からgem install sass
でインストールできるはず。Macの方はsudo
を先頭につけて。 - compass(Compassと共存させる場合)
-
Sassで使える便利グッズ集(Sassのミックスインや関数をライブラリ化したもの)。Sassのコンパイラとしても使える。
黒い画面からgem install compass
でインストールできるはず。Macの方はsudo
を先頭につけて。 - autoprefixer-rails(Compassと共存させる場合)
-
CSSベンダープレフィックス(ブラウザごとの表示の差異をなくすために必要なコード)を自動で追加してくれるツール。
黒い画面からgem install autoprefixer-rails
でインストールできるはず。Macの方はsudo
を先頭につけて。 - csso-rails(Compassと共存させる場合)
-
CSS縮小化ツール。別に入れなくてもよさそうだけど一応…
黒い画面からgem install csso-rails
でインストールできるはず。Macの方はsudo
を先頭につけて。
npmの意義
npmでは一つのアプリケーションを構成するソースファイルetc.を集めたフォルダをパッケージという。
ここではあえてソースファイルetc.と書いた。
npmの凄いところは、自分で書いたソースファイルだけでなく、それをコンパイルするコンパイラなども含めて一つのアプリケーションとしてまとめられるところだ。
例えば、作ったアプリケーションを人に提供するとき、中身がHTML, CSS, Javascriptのみであれば、相手のPCでもすぐにブラウザで実行できるだろう。
しかし、TypeScriptで書かれたファイルなどは、JavaScriptへコンパイルしなければ実行できない。相手にわざわざ『TypeScriptのコンパイラをインストールしておいてね』と伝えなくてはならない。これは面倒くさい。
そこでnpmが活躍する。npmでは、ローカルインストールという機能によって、コンパイラなどを好きなディレクトリにインストールすることができる。
アプリケーションをコンパイラとセットで相手に渡せば、相手の環境にかかわらずそれを実行できる。
また、コンパイルのためのコマンドは、オプション指定などで長くなることも多い。npmでは、それらのコマンドを短いコマンドに置き換えられるように、そのパッケージ専用の独自のコマンドを設定することができる。
これから行う工程の目的はこれくらいで理解できるはず。もっと詳しく学びたい方にはこちらの記事をお勧めしておく。(まだ私も読んでいる途中)
Dart Sassをコンパイルするまでの道のり
さて、新しいnpmパッケージを作成してSassをコンパイルするまでの道のりは、結構面倒なものである。
これに加えて、パッケージ内で、拡張子が.scss
やsass
のファイルはsassフォルダに収納し、それをコンパイルして得られる拡張子が.css
のファイルはcssフォルダに吐き出されるように設定したい。
(これはcompassプロジェクトとして作成した雛形を少し書き換えてそれをnpmパッケージとして登録すれば容易に実現できるが、compassを使わない方法も紹介する。)
また、CSSベンダープレフィックス(ブラウザごとの表示の差異を埋めるための追加コード)を自動で書き加えるためのツールを導入した方が良い。
これらの作業を、新たなディレクトリでSassを書くたびに行うのか?
…それは面倒くさすぎるので、自動化ツールを作りました。
Sassを使う環境(npmパッケージ)作成の自動化
初期設定
下のMySassCreate.shとMyConfig.rbを同じディレクトリにコピーしてね。
参考までに、私はホームディレクトリ/Users/tomixy
にMyShellScript
というフォルダを作って、その中にMySassCreate.shとMyConfig.rbを置いている。
置き場所に応じて、以降登場する/Users/tomixy/MyShellScript/
をそのディレクトリ名に書き換えてね。
macの方はchmod u+x /Users/tomixy/MyShellScript/MySassCreate.sh
を実行するのを忘れずに。これを実行しないとMySassCreate.shは動きません。
実行方法
- 黒い画面を開く
- Windowsなら
bash
コマンドでbashを起動 - パッケージ(作業ディレクトリ)を作りたい場所に
cd
コマンドで移動 /Users/tomixy/MyShellScript/MySassCreate.sh パッケージ名
を実行
すると、次のようなフォルダが生成される。
自動化シェルスクリプトMySassCreate.sh全文
zshでしか動作確認していないが、bashでも使えるはず。(というかそもそもbashのためのコード)
windowsの方は…そうだなあ。私はwindows時代、この記事を見ながらbashを導入した気がする。
あ、そうだ忘れてた…jq
をインストールしておかないと動かないので注意。
macならsudo brew install jq
でインストールできるけど…OSによって違うのでjq インストール OS名
と検索。
MySassCreate.sh
#!/bin/sh
PROJECT=$1
compass create $PROJECT # compassを使わない場合はコメントアウト
# mkdir $PROJECT # compassを使わない場合はコメントイン
cd $PROJECT
# mkdir sass # compassを使わない場合はコメントイン
mkdir css
# compassを使わない場合は下の5行をコメントアウト
cd stylesheets
mv *.css ../css
cd ..
rm -d stylesheets
cp -f /Users/tomixy/MyShellScript/MyConfig.rb config.rb
npm init -y
npm install sass fibers --save-dev
npm install postcss postcss-cli autoprefixer --save-dev
cat package.json|jq '.scripts += {"start": "sass sas$FILENAMEscss:css/$FILENAME.css --style expanded --watch | postcs--useautoprefixer -b \"last 10 versions\" css/$FILENAME.css -css$FILENAME.css "}' > package.txt
cat package.txt > package.json
rm -f package.txt
細かく解説
※ここからしばらくはコードの解説なので、早く実行したい人はここに飛んでね
シェバン
MySassCreate.shの一部
#!/bin/sh
『これはbashスクリプトですよ〜』とPCに宣言する部分。この記述のあるファイル名を黒い画面で入力+Enterすると、PCは自動的にbashでこのスクリプトを実行しようとする。
もしzshで実行したのなら、この部分は『これはbashスクリプトですよ〜、でもあなたはzshみたいね…まあいいわ、うまくやってあげる。』とPCに呼びかける意味合いになる。 Z ShellのWikiより、
zshを/bin/shとして実行したとき、Bourne Shellの振りをするようにできる。
bashはBourne Shell、zshはZ Shellの略らしいよ。
しかしシェルとはいえ、Power ShellではMySassCreate.shは実行できないと思われる。構文が結構違うらしい。
コマンドライン引数の取得
MySassCreate.shの一部
PROJECT=$1
/Users/tomixy/MyShellScript/MySassCreate.sh パッケージ名
としてこのシェルスクリプトを実行するわけだが、このとき与えたパッケージ名
が$1
に格納されている。
この定数を、これからはPROJECT
と呼ぶよ〜という意味。
不思議なことに、PROJECT = $1
としてはダメらしい。=
の左右にスペースを空けてはいけません。
compassプロジェクト(npmパッケージとなるフォルダ)の作成
MySassCreate.shの一部
compass create compass create $PROJECT # compassを使わない場合はコメントアウト
# mkdir $PROJECT # compassを使わない場合はコメントイン
compass create フォルダ名
で、指定したフォルダ内をSass作業用に整理してくれる。具体的には、次のような中身になる。
私も詳しくは知らないが、
- ie.css
- Internet Exprorer対応のCSSを書くための雛形
- print.css
- 印刷用のCSSを書くための雛形
- screen.css
- 画面表示用の(つまり普通の)CSSを書くための雛形(CSSリセットの宣言つき)
- config.rb
- compassコマンドでのコンパイル用の設定を書いておくファイル
…らしい。
とはいえ、前述したようにcompassのサポートは既に終了しているので、ここで作られたie.cssを使ったところで最新のものに対応できるかはわからない。
シェルスクリプトでは、#
以降は実行されない部分になる。よって、ここには何を書いても良い。
#!
だけは例外なので注意。#!
で始まるものはシェバンとして解釈されてしまう。
compassを使わない場合は、compass create
の前に#
を置く(コメントアウトする)ことでcompass create
コマンドを無効化にする。
また、その場合はcompassが作るはずだったフォルダを手動で作成しなければならないため、# mkdir $PROJECT
の先頭の#
を取る(コメントインする)。
言い忘れていたが、シェルスクリプトでは、事前に宣言しておいた変数は$変数名
で参照できる。
パッケージ内のフォルダをカスタマイズする
MySassCreate.shの一部
cd $PROJECT
# mkdir sass # compassを使わない場合はコメントイン
mkdir css
# compassを使わない場合は下の5行をコメントアウト
cd stylesheets
mv *.css ../css
cd ..
rm -d stylesheets
おそらく、今のカレントディレクトリは$PROJECT
フォルダを置いた場所(つまり、$PROJECT
フォルダの手前のフォルダ)になっていると思うので、cd $PROJECT
でパッケージフォルダ内に移動する。
compassを使わなかった場合は、まだsassフォルダもcssフォルダも作成されていないので、mkdir
コマンドで作成する。
compassで自動作成した場合は、拡張子が.css
のファイルがstylesheetsフォルダに格納されている。
わかりづらいので、stylesheetsフォルダは削除し、新規に作成したcssフォルダに中身を移すことにする。
cd stylesheets
以降はこの移行作業になるので、compassを使わない場合はコメントアウトで無効化した方が良い。
cd stylesheets
でstylesheetsフォルダ内に移動し、中のファイルをcssフォルダ内に移動する。
*
はワイルドカードといい、どんな文字列でもよいことを表す。つまり、*.css
は拡張子が.css
のすべてのファイルである。
../css
は、一つ前のディレクトリに戻って(stylesheetsディレクトリから出て)、その後cssディレクトリ内に入った場所を表す。
mv *.css ../css
- すべてのcssファイル(
*.css
)をcssディレクトリ(../css
)にmove
する cd ..
- cssディレクトリから出る(一つ前のディレクトリに戻る)
rm -d stylesheets
- stylesheetsというディレクトリ(
-d
)を削除(remove
)する
compassコマンドによるコンパイルの設定をする
compass create
コマンドによって作られたconfig.rbファイルの中身はデフォルトのものである。
これをカスタマイズしたものをMyConfig.rbとし、これをそっくりそのままconfig.rbにcopy
する。
MySassCreate.shの一部
cp -f /Users/tomixy/MyShellScript/MyConfig.rb config.rb
デフォルトのconfig.rb
require 'compass/import-once/activate'
http_path = "/"
css_dir = "stylesheets"
sass_dir = "sass"
images_dir = "images"
javascripts_dir = "javascripts"
compass設定ファイルの雛形のMyConfig.rb
require 'compass/import-once/activate'
# compassコマンドによるコンパイルでもベンダープレフィックスを使用するための設定
require "autoprefixer-rails"
require "csso"
on_stylesheet_saved do |file|
css = File.read(file)
File.open(file, "w") do |io|
io << AutoprefixerRails.process(css, browsers: ["> 1%", "last 2 versions", "ie 10"])
end
end
http_path = "/"
css_dir = "css" # 新規に作ったcssフォルダにcssファイルが出力されるようにする
sass_dir = "sass"
images_dir = "image"
javascripts_dir = "js"
# その他の設定
output_style = :expanded
relative_assets = true
line_comments = false
ベンダープレフィックスの設定は、このブログから丸ごとコピペした。
その他の設定については、このブログを参考に選択した。
npmパッケージを作成
MySassCreate.shの一部
npm init -y
これで$PROJECT
フォルダ内にpackage.jsonファイルやnode_modulesフォルダが作成される。package-look.jsonファイルも作成されているかも。
npm init
コマンドを実行すると、途中でパッケージの設定についていろいろと質問されるが、それらをすべてスキップしてデフォルト値を埋め込むために-y
オプションをつけている。
Sassコンパイラなどをnpmでローカルインストール
MySassCreate.shの一部
npm install sass fibers --save-dev
npm install postcss postcss-cli autoprefixer --save-dev
npm install パッケージ名
- カレントディレクトリにパッケージをローカルインストールする
fibers
- よくわからないが、速くインストールするために処理の仕方を変えるオプション
--save-dev
- インストールしたパッケージを、package.jsonに依存パッケージ(これがないとこのアプリは動かないよ!というパッケージ)として記述するオプション。
依存パッケージがアップデートすると今まで使えていたコマンドなどが使えなくなり、コードの修正が必要になることもある。依存パッケージをpackage.jsonに書いておくと、npm側でいろいろな管理処理をしてくれるらしい。 - PostCSS
- CSSを変換するツール
- postcss-cli
- PostCSSを黒い画面で使えるようにするツール
- Autoprefixer
- PostCSSによってベンダープレフィックスを追加するツール
package.jsonの修正点
JSONは、簡単にいえば{ key : value }
という形で表されたデータの集まりである。
npm init -y
コマンドによりデフォルトで作成されるpackage.jsonは、次のようになっている。
デフォルトのpackage.json
{
"name": "$PROJECT",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" exit 1"
},
"keywords": [],
"author": "",
"license": "ISC"
}
このファイルを自動で次のように書き換えることを目指す。(scripts
インデックスの値に"start":"コンパイルコマンド"
を追加した)
修正後のpackage.json(イメージ)
{
"name": "$PROJECT",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" &exit 1",
"start":"コンパイルコマンド"
},
"keywords": [],
"author": "",
"license": "ISC"
}
コンパイルとベンダープレフィックス付加を一気に行うコマンドを作成
コンパイルコマンド
とだけ示した部分には、次のコードが入る。
($filename
は、コンパイルコマンド実行時に渡す引数)
コンパイルコマンド
sass sass/$FILENAME.scss:css/$FILENAME.css --style expanded --watch | postcss --use autoprefixer -b \"last 10 versions\" css/$FILENAME.css -o css/$FILENAME.css
sassコマンドについて
sass
- 拡張子が.scss、.sassのファイルをコンパイル(.cssファイルに変換)するコマンド
sass sass/$FILENAME.scss:css/$FILENAME.css
sass コンパイルするファイル:コンパイル後のファイル
--style expanded
- コンパイル後のCSSファイルの書式をexpanded(わかりやすいブログはこちら)に設定
--watch
- 以後、黒い画面を開いている間は保存する度にコンパイルを実行してCSSファイルを更新する
postcssコマンドについて
postcss ファイル名.css
- 引数として指定したCSSファイルを解析
--use autoprefixer
- postcssでautoprefixerを使うオプション
-b "last 10 versions"
- 10バージョン前のブラウザまで対応
-o ファイル名
- 指定したファイルに改変後のCSSを出力
シェルスクリプトにおけるパイプ|
コマンドA | コマンドB
- コマンドAを実行し、その標準出力をコマンドBの引数としてコマンドBを実行
- 標準出力
- 黒い画面に吐き出されたテキストのこと
コマンドAがファイルの中身を黒い画面に表示する
というものなら、表示されたファイルの中身をコマンドBで加工するということになる。
ただし、sassコマンドは.cssファイルを作成するだけで、黒い画面には何も表示しない。このままではpostcssの引数は空であり、エラーになってしまうので、postcssにはcss/$FILENAME.css
という引数をわざわざ渡している。
コマンドBにあたる部分である次のコード
コマンドB
postcss --use autoprefixer -b \"last 10 versions\" css/$FILENAME.css -o css/$FILENAME.css
を解体すると、コマンド本体がpostcss
、引数がcss/$FILENAME.css
、オプションが--use autoprefixer
と-b \"last 10 versions\"
と-o css/$FILENAME.css
ということになる。
このように、コマンドAが表示系のコマンドではなく、コマンドBに明示的に引数を渡している場合、パイプ|
はただ単にコマンドAを実行した後にコマンドBを実行する
という意味の記号として使われている。
コマンドを書き加えたjsonテキストを一旦package.txtに吐き出す
MySassCreate.shの一部
cat package.json|jq '.scripts += {"start": "sass sass/$FILENAME.scss:css/$FILENAME.css --style expanded --watch | postcss --use autoprefixer -b \"last 10 versions\" css/$FILENAME.css -o css/$FILENAME.css "}' > package.txt
もっとわかりやすく表すと、
MySassCreate.shの一部
cat package.json | jq '.scripts += {"start": " さっきのコマンド "}' > package.txt
cat ファイル名
ファイルの中身を黒い画面に表示する
表示系コマンド > ファイル
- コマンドの結果を黒い画面に表示するのではなく、ファイルに書き出す
jq '処理' JSON形式のファイル
- JSON形式のファイルの中身を取得し、指定された処理をして、黒い画面に表示
.KEY
- インデックスがKEYである要素{ "KEY" : "value" }
.KEY += { ITEM }
- インデックスがKEYである要素{ "KEY" : value }のvalueの部分にITEMを追加して、要素全体を書き換える
jq
コマンドの引数は一見存在しないかのように見える。
しかし、cat
が表示コマンドであるので、cat
で表示したファイルの中身をそのままjq
コマンドに渡していることになる。
引数として渡されたpackage.jsonのデータを、jqコマンドで処理する。
jq '.scripts += {"start": " コンパイルコマンド "}' package.json > package.txt
でも.jsonファイルは正しく作成されるが、コンパイルコマンドの実行時になぜかコンパイル不良が頻出するので、没とした。
おそらくテキストをそのままjq
で処理させるのではなく、cat
コマンドでテキストをリスト化してからjq
で処理させた方がいいのだろう。
どちらにしてもシェルスクリプトは原因不明の不具合が日常茶飯事らしいので、スマートなコードを目指すよりも経験的にうまくいく方法をとった方がよさそう。
jq '.scripts += {"start": ""sass sass/$FILENAME.scss:css/$FILENAME.css --style expanded --watch | postcss --use autoprefixer -b \"last 10 versions\" css/$FILENAME.css -o css/$FILENAME.css"}'
というコマンドによって、インデックスがscriptsである要素は次のように変わる。
BEFORE
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
}
AFTER
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"start": "sass sass/$FILENAME.scss:css/$FILENAME.css --style expanded --watch | postcss --use autoprefixer -b \"last 10 versions\" css/$FILENAME.css -o css/$FILENAME.css "
}
そして、上のようにscripts
の値を書き換えたものを、本来なら黒い画面に表示するわけだが、代わりに> packge.txt
によってpackage.txtファイルに書き出すことになる。
最初からpackage.jsonに吐き出せばいいのでは?と思うかもしれないが、そうするとpackage.jsonの中身は空になってしまう。この記事に書かれてあるように、直接package.jsonに上書きするのは原理的に不可能なようだ。
package.txtの中身
{
"name": "sample",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"start": "sass sass/$FILENAME.scss:css/$FILENAME.css --style expanded --watch | postcss --use autoprefixer -b \"last 10 versions\" css/$FILENAME.css -o css/$FILENAME.css "
},
"keywords": [],
"author": "",
"license": "ISC",
"devDependencies": {
"autoprefixer": "^10.2.5",
"fibers": "^5.0.0",
"postcss": "^8.2.8",
"postcss-cli": "^8.3.1",
"sass": "^1.32.8"}
}
}
package.txtの中身をpackage.jsonにコピーする
MySassCreate.shの一部
cat package.txt > package.json
rm -f package.txt
cat package.txt > package.json
によって、package.txtの中身を黒い画面に表示する代わりに、package.jsonに吐き出す。
このとき、元々のpackage.jsonの内容は消去され、完全に上書きされる。
一時的なデータ保管用であったpackage.txtはもう不要なので、rm -f package.txt
で削除する。
『削除していいのですか?』的な確認メッセージが出ると、それに回答する手間が生じるので、確認メッセージを表示しないために-f
オプションをつけておく。
作成した自動化ツールの使い方
初期設定が済んでいることを前提で話を進めます。
あと、VScodeユーザーならこの章は読むだけ無駄です。ここに進むことをおすすめします。
SassやCSSを作成するフォルダの作成
実行方法に書かれてある通りなので略。
Sassを書く
さっき作ったフォルダの中の、sassフォルダの中にオリジナルの.scssファイル(または.sassファイル)を追加していってね
Sassのコンパイル
cd
コマンドでsassファイルの中へ移動FILENAME=コンパイルしたいファイル名 npm run start
コマンドを実行
start
というのがpackage.jsonで定義したコンパイルコマンドだが、このコマンドに直接引数を渡すことは不可能なので、FILENAME
という定数を事前に定義して、それをコマンド内で参照する手段をとっている。
cssフォルダを覗いてみると、コンパイルしたかったファイルと同名の.cssファイル(と.css.mapファイル)が作成されているはず。ベンダープレフィックスも自動で追加されています!!
なお、このコマンドの実行以降は、sassファイルをいじって再保存したり、新たなsassファイルを作って保存したりすると、勝手にコンパイルされてcssフォルダ内が更新されていくよ。黒い画面を閉じない限りね!!
…って、これだとまだ面倒臭いじゃん
…と思いませんでした?
VScodeユーザーなら、ワンクリックでできるようになります!!
VScodeで簡単にパッケージ作成&Sassコンパイルできるようにする
初期設定
task.jsonを開く
shift ctrl P
(macならshift(⬆️) command P
)task
と入力ユーザータスクを開く
をクリック
開かれたtask.jsonに次の内容をコピペ
task.json
{
"version": "2.0.0",
"tasks": [
{
"label": "Sass new project create",
"type": "shell",
"command": "/Users/tomixy/MyShellScript/MySassCreate.sh",
"args": ["${input:SassProjectName}"],
"problemMatcher": [],
"group": {
"kind": "build",
"isDefault": true
}
},
{
"label": "Sass compile & watch start",
"type": "shell",
"command": "cd ${fileDirname} && cd .. && FILENAME=${fileBasenameNoExtension} npm run start",
"problemMatcher": [],
"group": {
"kind": "build",
"isDefault": true
}
}
],
"inputs": [
{
"id": "SassProjectName", // ${input:***}で指定したID
"description": "Sass new project name:", // 入力説明文
"default": "sample", // デフォルト入力値
"type": "promptString" // 入力タイプ
}
],
}
使い方
SassやCSSを作成するフォルダの作成
shift ctrl B
(macならshift(⬆️) command B
)Sass new project create
をクリック- 作成したいフォルダ名を入力(デフォルトではsample)
Sassを書く
さっき作ったフォルダの中の、sassフォルダの中にオリジナルの.scssファイル(または.sassファイル)を追加していってね
Sassのコンパイル
shift ctrl B
(macならshift(⬆️) command B
)Sass compile & watch start
をクリック
cssフォルダを覗いてみると、コンパイルしたかったファイルと同名の.cssファイル(と.css.mapファイル)が作成されているはず。ベンダープレフィックスも自動で追加されています!!
これ以降はsassファイルをいじって再保存したり、新たなsassファイルを作って保存したりすると、勝手にコンパイルされてcssフォルダ内が更新されていくよ。
あとがき
この自動化を実現するために初めてきちんとシェルスクリプトを勉強したので、ほぼほぼシェルスクリプト文法のアウトプットブログになってしまった。
実は、ブログに載せるために何度もテストしていく中で、MySassCreate.shに重大な欠陥があることに気がついた。もちろん修正済みのものを掲載している。ブログにまとめること自体がデバッグ作業。 それにしても、その欠陥というものは他の言語であれば即エラーを吐き出すようなヤバいものだった。あんなコードで動いてしまうシェルスクリプトって怖い。
実を言うとSassの勉強はまだしていないので、これからいろいろコンパイルしていく中でエラーが出る可能性も…そうしたらまたこの記事を修正しよう。安定して動作できることがある程度確認できたらGitHubにも載せる。
task.jsonの書き方についてもいつか追記するかも。とりあえず疲れたからこれでおしまい。
pyファイルの実行を極限まで楽にする【Python用のcode runnerショートカット改造】
code runnerを使えば、pyファイルもCtrl + Alt + Nで瞬時に実行できる。…が、その前にcdコマンドなどで実行したいファイルのあるディレクトリまで移動しておかなければならない。
いちいち手動で移動するのは面倒くさいので、Ctrl + Alt + Nショートカットにディレクトリ移動も組み込んでしまおう、というお話。
前提とする環境
- pythonコマンドが使える
- code runnerをインストール済み
ショートカット作成方法
setting.jsonを開き、"code-runner.executorMap":{}内の"python": "なんちゃら"を
"python": "cd $dirWithoutTrailingSlash ; python $fileName"
に変更する。(before → after)
環境によってはpythonじゃなくてpython3かも。 PowerShell等でpythonもしくはpython3と入力+Enterしてみて、エラーにならずにPythonのバージョン情報が表示された方を当てはめて。
簡単に解説
実行したい(今VScodeで開いている)pyファイルのフルパスがkonofolderniaruyo/jikkositai.pyだとすると、
- $dir ...konofolderniaruyo/
- $dirWithoutTrailingSlash ...konofolderniaruyo
- $fileName ...jikkositai.py
として置き換えられる。
つまり、cdコマンドでkonofolderniaruyoディレクトリに移動した後に、pythonコマンドでjikkositai.pyを実行するということ。
移動と実行という2つの操作を続けて行うことを;で表している。(&&や-andだとなぜかエラーが出た)
csファイルだってcode runnerで一発コンパイルしたい!【C#用のcode runnerショートカット】
本来、code runnerはCtrl + Alt + Nでコンパイル・実行できることが最大のメリットなわけだが、どうやらC#ではそうもいかないらしく。 code runnerの初期設定では、CSscriptをインストールしておけばcsxファイルならCtrl + Alt + Nで実行できるとかなんとか。 どちらにせよ、csファイル(というかcsprojファイル)をビルド・実行するには、cdコマンドでビルドしたいcsprojファイルがあるフォルダーに移動した後に、dotnet runコマンドを手打ちする必要がある。
いちいちPowerShellにcd ビルドしたいcsprojがある階層のフルパス + dotnet run と打ち込んでビルドするのは面倒臭いので、ショートカットを作成してしまおうというお話。
前提とする環境
- dotnet runコマンドが使える
- code runnerをインストール済み
ショートカット作成方法
setting.jsonを開き、"code-runner.executorMap":{}内の"csharp": "scriptcs"を"csharp": "cd $dir && dotnet run" に変更する。(before → after)
すると、Ctrl + Alt + Nで今開いているcsファイルのビルドができるようになった。
よくわからないが、
という2つの操作を続けて行うことを&&で表す
という意味合いっぽい。
効率化された試し割りによる素数判定【細かすぎるコード解説:C言語編】
14622回の除算で1000以下の素数を求める
手がかり
とでしか割り切れない整数(素数)を探すとき、それより小さい素数で割り切れないものは、その他の整数(素数の倍数)でも割り切れない。
そのため、より小さいすべての素数で割ってみて割り切れるかのみ調べればよい。
プログラムのソースコード【細かすぎる注釈つき】
#include <stdio.h> int main(void) { //2以上1000以下の整数をnと表すことにする //つまり、整数nの中から素数を探すことになる int n; //除算回数を数えるカウンターを用意 unsigned long counter=0;/*unsigned long…長い桁数の非負整数を格納できる箱の名称(型)*/ //素数を入れる箱を500個用意する //2以外の素数はすべて奇数であり、1から1000までの数の中に奇数は500個しかない //そのうち1は素数ではなく、代わりに2は素数であるから、 //結局素数を入れる箱は500個で足りる int prime[500]; //i番目の素数をprime[i]と表すことにする int i; //既に見つけた素数の個数をptrとする。現時点ではまだ0である int ptr=0; //2と3は素数である prime[ptr++]=2;/*prime[0]=2と記憶した後に、ptrの値を1つ増やす(見つけた素数の個数が1になる)*/ prime[ptr++]=3;/*prime[1]=3と記憶した後に、ptrの値を1つ増やす(見つけた素数の個数が2になる)*/ //このように、小さい数から順に素数を探していくから、 //番号が若い素数の方が小さい素数である //現時点で見つかっている素数2個(prt=2)のうち最大のものはprime[1]=3であるように、 //これまで見つけたptr個の素数のうち最大のものは、prime[ptr-1]で表される //5以上1000以下の数の中から素数を探す for (n=5 ; n <= 1000; n+=2)/*5から始まって2ずつ増やしていくことで、奇数のみが対象になる*/ { //これまで見つけた素数prime[0]~prime[ptr-1]すべてで割ってみる //しかし、これから見つける素数はすべて奇数であるので、2で割り切れる数(偶数)は最初から除外してよい //よってprime[0]である2で割る必要はないので、3=prime[1]~prime[ptr-1]で割ってみる for ( i = 1; i < ptr; i++) { counter++;/*除算回数が1増える*/ if (n % prime[i] ==0)/*もし整数n(>4)がそれより小さい素数で割り切れたなら*/ { break; /*nは素数ではないので、もう他の数で割る必要はない⇒このforから追放*/ } //ここでi++が実行され、iの値が1増える //割り切れなかったものはこのforの冒頭に戻り、iが1大きな値に書き換えられたforの中身を繰り返す // (つまりより大きい素数で割られる) } //途中でforを追放されたものはここに到達している //まだiの値がptrよりはるかに小さい段階で中断されているので、 //ptr=iという条件を満たさず、if(ptr==1){}はスルーしてこのまま外側のforからも抜けることになる //最大素数prime[ptr-1]までのすべての素数で割り切れなかったものは、 //最後までbreakで抜けることなく、後処理i++を受けてここに到達する //つまり、最大素数での最後の除算をする段階ではi=ptr-1だが、その後のi++によって今はi=ptrとなっている //これは次のif文も実行されることになる if (ptr == i)/*i=ptrなら(これまで見つけたprime[ptr-1]までのすべての素数で割り切れなかったら)*/ { prime[ptr++]=n;/*そんな整数nを新たな素数prime[ptr]として登録する *(登録した後に、登録済み素数の数が1増える) */ } //ここでn+=2が実行され、nの値が2増える //外部forの冒頭に戻り、2大きな整数nについて全体の処理が再度行われる //このようにして、1000以下の整数をすべて登録済み素数で割って、選別する } //1000以下の整数すべての選別が終わると、ここに到達する //最終的に登録された素数すべて(prime[1]~prime[ptr-1])を一覧で表示する for ( i = 0; i < ptr; i++) { printf("%d\n",prime[i]); } //除算回数を表示する printf("乗除を行った回数:%lu\n",counter); return (0); }
3774回の乗算・除算で1000以下の素数を求める
強力な武器
改良版プログラムのソースコード【細かすぎる注釈つき】
変更した箇所にのみ補足説明を加えている。
#include <stdio.h> int main(void) { int n; //乗算・除算回数を数えるカウンターを用意 unsigned long counter=0; int prime[500]; int i; int ptr=0; prime[ptr++]=2; prime[ptr++]=3; for (n=5 ; n <= 1000; n+=2) { //2つの状態のどちらか(ONかOFFか)を判定するために使う変数をフラグという //今回は割り切れたか否かを判定する用に使う int flag = 0;/*初期値は0(フラグを下ろしておく)*/ //nの平方根以下のすべての素数で割ってみる //『素数pがnの平方根以下』という条件は、両辺2乗して『pの2乗がn以下』と言い換えられる for ( i = 1; counter++ , prime[i]*prime[i] <= n; i++) /*《A,B …AとBを順に実行し、Bの値を返す》 *for内部を実行するかの判定をするのはprime[i]*prime[i] <= nだが、 *判定の度に乗算*をカウントするということ */ { counter++; if (n % prime[i] ==0)/*割り切れたなら*/ { flag = 1; /*フラグを上げる*/ break; } } if (!flag) /*flag=0(フラグが下がったまま)なら*/ { prime[ptr++]=n;/*割り切れなかったということなので、素数として登録*/ } } for ( i = 0; i < ptr; i++) { printf("%d\n",prime[i]); } printf("乗除を行った回数:%lu\n",counter); return (0); }
コード引用元
今回掲載したコードのベースとなっているのは、柴田望洋先生の著書明解C言語入門編の109・111ページに掲載されているサンプルコードです。 説明の都合上、変数の名称や変数宣言の順序を変えています。また、括弧のレイアウトは自分好みに変えています。
定理の証明に関する参考文献
現在LaTeXで制作中の整数論ノートに今回素数判定に用いた定理の証明も掲載予定です。 厳密な証明ではないですが、コード引用元の書籍では正方形の図によってわかりやすく導出されています。 厳密な証明を追いかけたい方にはモノグラフ 整数をオススメします(が、絶版なんだよなあ…)。
LaTeXで使える付箋風の枠【tcolorboxの可能性】
tcolorboxのマニュアルの8.3節にある作例にちょっとだけ手を加えたら、思いがけず可愛らしい付箋のような枠が生まれたので記録しておく。
コード全文
\usepackage[dvipdfmx]{graphicx,color}%オプションは一例 \usepackage{xcolor} \usepackage{tikz} \usetikzlibrary{calc}%座標を使って図形を描くために必要 \usepackage{xparse}%オプション(省略可能引数)をもつコマンド作成 \usepackage{tcolorbox} \tcbuselibrary{listings,breakable,xparse,skins,hooks} %listings…私の環境ではbreakableを使う際に必要 %breakable…ページまたぎ可能な枠を作成できる %xparse…オプションをもつ枠を作成できる %skins…TikZで枠のデザインを描き足せる %hooks…多種多様な機能が含まれるため、とりあえず読み込んでおくと安全 % たとえばunderlay unbrokenに必要 %付箋環境~水色バージョン~の定義 \DeclareTColorBox{fusenmz}{m O{} }% {enhanced, colframe=white, colback=yellow!10!white, coltitle=cyan!40!black, fonttitle=\bfseries,breakable, underlay unbroken={\begin{tcbclipinterior} \shade[inner color=cyan!80!yellow,outer color=yellow!10!white] (interior.north east) circle (2cm); \draw[help lines,step=5mm,yellow!80!black,shift={(interior.north west)}] (interior.south west) grid (interior.north east); \end{tcbclipinterior}}, underlay first={\begin{tcbclipinterior} \shade[inner color=cyan!80!yellow,outer color=yellow!10!white] (interior.north west) circle (2.5cm); \draw[help lines,step=5mm,yellow!80!black,shift={(interior.north west)}] (interior.south west) grid (interior.north east); \end{tcbclipinterior}}, underlay last={\begin{tcbclipinterior} \draw[help lines,step=5mm,yellow!80!black,shift={(interior.north west)}] (interior.south west) grid (interior.north east); \end{tcbclipinterior}}, title={#1}, attach title to upper=\quad, #2 } %付箋環境~桃色バージョン~の定義 \DeclareTColorBox{fusenmm}{m O{} }% {enhanced, colframe=white, colback=yellow!10!white, coltitle=magenta!40!black, fonttitle=\bfseries, breakable, underlay unbroken={\begin{tcbclipinterior} \shade[inner color=magenta!80!yellow,outer color=yellow!10!white] (interior.north east) circle (2cm); \draw[help lines,step=5mm,yellow!80!black,shift={(interior.north west)}] (interior.south west) grid (interior.north east); \end{tcbclipinterior}}, underlay first={\begin{tcbclipinterior} \shade[inner color=magenta!80!yellow,outer color=yellow!10!white] (interior.north west) circle (2.5cm); \draw[help lines,step=5mm,yellow!80!black,shift={(interior.north west)}] (interior.south west) grid (interior.north east); \end{tcbclipinterior}}, underlay last={\begin{tcbclipinterior} \draw[help lines,step=5mm,yellow!80!black,shift={(interior.north west)}] (interior.south west) grid (interior.north east); \end{tcbclipinterior}}, title={#1}, attach title to upper=\quad, #2 }
使用法
%fusenmzの場合も同様 \begin{fusenmm}{タイトル}[さらなるtcolorboxのオプション] テキスト \end{fusenmm}
使用例ギャラリー
%プリアンブルに追加 \usepackage[math]{anttor}%オシャレな数式・英文フォント \usepackage{enumerate} %この下は\begin{document}以降 \begin{fusenmm}{My Title} \begin{enumerate}[(1)] \item A,A,B,C,Dを1列に並べる並べ方は何通りあるか。 \item A,A,B,B,C,Dを1列に並べる並べ方は何通りあるか。 \end{enumerate} \end{fusenmm} \begin{fusenmz}{My Title} \begin{enumerate}[(1)] \item A,A,B,C,Dを1列に並べる並べ方は何通りあるか。 \item A,A,B,B,C,Dを1列に並べる並べ方は何通りあるか。 \end{enumerate} \end{fusenmz}
前回紹介したリングノート枠の中で使えば、付箋ノート風になってますます可愛いのでは…?
なお、付箋らしさは損なわれるが、一応ページまたぎも可能である。