人生シーケンスブレイク

シーケンスブレイク(Sequence breaking、シークエンスブレイクとも)とは、テレビゲームにおいて開発が想定している攻略ルートを逸脱し、ショートカットする行為のことである。

Bowerを使ってフロントエンドのパッケージ管理を行う

先行きが若干不安だけど。 Bower is alive, looking for contributors · Bower blog

npm はpackage.jsonがカオスになっている為開発用ライブラリのパッケージ管理のみ、BowerはBootstrapなどのフロントエンドのライブラリパッケージ管理で使い分けしている。

Bower インストール

$ npm install bower

Bower によるパッケージインストール

$ bower install bootstrap

デフォルトでは bower_components/ ディレクトリにインストールされる。 bower_components/ を.gitignoreに追加しておくとgitリポジトリに外部ライブラリの歴史が残らず綺麗に管理できる。

bower.jsonの作成

$ bower init

コマンドを叩き、npm init 感覚で幾つかの質問に答えていくとbower.jsonが生成される。

bower.jsonに記述されたライブラリのインストール

$ bower install

インストール先の変更

.bowerrc に以下のように記述すると良い。

{
  "directory": "static/vendor",
  "json": "bower.json"
}

まとめ

Bowerを使う際には以下のファイルを追加する。

$ tree -a
.
├── .bowerrc # パッケージインストール先の指定
├── .gitignore # パッケージインストール先の除外設定を追加
└── bower.json # パッケージ管理ファイル

CSSセレクタ42個ぜんぶ纏めてみた

Sassにせよcssにせよ、出来る限り限定的にCSSセレクタを指定できるといいよねってことで、W3C記載の表に基づいてCSSセレクタを纏めてみた。
なお、CSS3セレクタに関するW3Cのテクニカルレポートとして Selectors Level 3 が著名だが、 2015年時点のCSS情報を纏めた CSS Snapshot 2015CSS WG members によって作成されているのでこちらの情報を参考としている。*1

ブラウザ互換についてだが、まず What's my IP Address? What's my browser? のCSS3 Selectorsの項を見る限り、IE10で全セレクタ対応されている。
そして、IE10以下はVista IE9を除き2016年1月12日(米国時間)にサポート終了する。
Internet Explorerサポートポリシー変更の重要なお知らせ - Microsoft

Vista IE9はシェアがかなり少ないことから、実質ブラウザ互換を考える必要はなさそうである。
IE6に苦しまれたブラウザ互換については、CSSに関しては今後はほぼ考えずに済みそうだ。(たぶん)

CSSセレクタ42個まとめ

セレクタパターン セレクタの意味 セレクタが最初に定義されたCSS Level
* すべての要素 全称セレクタ 2
E E要素 セレクタ 1
E[foo] "foo"属性を持つE要素 属性セレクタ 2
E[foo="bar"] "foo"属性の値が"bar"と等しいE要素 属性セレクタ 2
E[foo~="bar"] "foo"属性の値がスペース区切りのリストで、そのいずれかが"bar"と等しいE要素 属性セレクタ 2
E[foo^="bar"] "foo"属性の値が"bar"で始まるE要素 属性セレクタ 3
E[foo$="bar"] "foo"属性の値が"bar"で終わるE要素 属性セレクタ 3
E[foo*="bar"] "foo"属性の値が"bar"を含むE要素 属性セレクタ 3
E[foo|="en"] "foo"属性の値がハイフン区切りのリストで、"en"はじまりであるE要素 属性セレクタ 2
E:root ドキュメントルートであるE要素 構造模擬クラス 3
E:nth-child(n) n番目の子要素であるE要素 構造模擬クラス 3
E:nth-last-child(n) 最後から数えてn番目の子要素であるE要素 構造模擬クラス 3
E:nth-of-type(n) n番目の兄弟要素であるE要素 構造模擬クラス 3
E:nth-last-of-type(n) 最後から数えてn番目の兄弟要素であるE要素 構造模擬クラス 3
E:first-child 最初の子要素であるE要素 構造模擬クラス 2
E:last-child 最後の子要素であるE要素 構造模擬クラス 3
E:first-of-type 最初の兄弟要素であるE要素 構造模擬クラス 3
E:last-of-type 最後の兄弟要素であるE要素 構造模擬クラス 3
E:only-child 他に子要素を持たないE要素 構造模擬クラス 3
E:only-of-type (兄弟要素のうち、)他に同一要素を持たないE要素 構造模擬クラス 3
E:empty (テキストノードも含めて)空のE要素 構造模擬クラス 3
E:link 未閲覧のハイパーリンクを持つE要素 リンク擬似クラス 1
E:visited 閲覧済みのハイパーリンクを持つE要素 リンク擬似クラス 1
E:active アクティブなE要素 ユーザアクション擬似クラス 1と2
E:hover ホバー中のE要素 ユーザアクション擬似クラス 1と2
E:focus フォーカス中のE要素 ユーザアクション擬似クラス 1と2
E:target 参照URIのターゲットであるE要素 ターゲット擬似クラス 3
E:lang(fr) 言語"fr"のE要素 :lang()擬似クラス 2
E:enabled enabled属性であるE要素 UI要素状態擬似クラス 3
E:disabled disabled属性であるE要素 UI要素状態擬似クラス 3
E:checked checked属性であるE要素 UI要素状態擬似クラス 3
E::first-line E要素の最初の行 ::first-line擬似要素 1
E::first-letter E要素の最初の文字 ::first-letter擬似要素 1
E::before E要素の前に生成されるコンテンツ ::before擬似要素 2
E::after E要素の後に生成されるコンテンツ ::after擬似要素 2
E.warning "warning"クラスを持つE要素 クラスセレクタ 1
E#myid ID"myid"を持つE要素 IDセレクタ 1
E:not(s) 単純セレクタsにマッチしないE要素 否定擬似クラス 3
E F E要素の子孫であるF要素 子孫結合子 1
E > F E要素の子であるF要素 子結合子 2
E + F E要素の直後にあるF要素 隣接兄弟結合子 2
E ~ F E要素の後ろにあるF要素 一般兄弟結合子 3

解説

E F, E > F, E + F, E ~ F などは皆知ってると思うので、CSS Level3で定義されたセレクタを中心に解説する。

E[foo="bar"], E[foo~="bar"]

既にCSSを利用している人は使ったことがあると思うので注意点のみ。
例えば、

<header class="navbar navbar-static-top bs-docs-nav">

の場合、header[class="navbar"] はヒットしない。header[class~="navbar"] はヒットする。
これは定義通り、E[foo="bar"]が単一要素と同一な場合に適用されるセレクタであり、E[foo~="bar"]は複数要素のなかに該当要素が含まれる場合に適用されるセレクタだからである。

Bootstrapをはじめ、マルチクラス設計で作られたCSS Frameworkや、jQueryを利用する場合には複数のクラスを持つケースが多いので、classを指定する場合には、素直に header.navbar を利用した方が良いだろう。

構造擬似クラスの幾つかを解説

E[foo^="bar"], E[foo$="bar"]

"bar"で始まる、または"bar"で終わる要素にマッチする。

利用例

a[href^="#"] {background-color:gold}
a[href$=".cn"] {color: red;}

と指定すると、ページ内リンクを持つa要素にのみ背景色を金にしたり、.cnドメインへのリンクのみ赤字にしたりできる。

属性セレクター - CSS: カスケーディングスタイルシート | MDN

E:nth-child(n), E:nth-last-child(n)

n番目の子要素であるE要素にマッチする。

<div>
  <p>1</p>
  <p>2</p>
  <p>3</p>
</div>

に対して p:nth-child(2) と指定すると<p>2</p>がマッチする。
nth-last-childは最後から数えたn番目の要素とマッチする。

E:nth-of-type(n), E:nth-last-of-type(n)

n番目のE要素にマッチする。

<div>
  <p>1</p>
  <p>2</p>
  <span></span>
  <p>3</p>
</div>

p:nth-of-type(3) と指定すると、<p>3</p>がマッチする。
ちなみに、括弧内に(odd)(even) を指定すると奇数/偶数番目にマッチする。
実は :nth-child(2n) で偶数や :nth-child(3n+1) で3の倍数+1にマッチできたりもする。

Selectors Level 3 に仕様が書いてあるが

:nth-child( +3n - 2 )
:nth-child( -n+ 6)

とか書いてあってなかなかキモい。

E:first-child, E:last-child, E:first-of-type, E:last-of-type

*-child は最初(後)の子要素であるE要素にマッチする。
*-of-type は兄弟要素の内、最初(後)のE要素にマッチする。

<div>
  <p>1</p>
  <p>2</p>
  <span></span>
  <p>3</p>
</div>
<div>
  <p>4</p>
  <p>5</p>
  <span></span>
  <p>6</p>
</div>

p:first-childであれば、 <p>1</p><p>4</p> がマッチする。
p:first-of-typeであれば、 <p>1</p><p>4</p> がマッチする。

ただしこの場合、
span:first-childは、ここではspanは最後の子要素では無いためいずれの要素もマッチせず、
span:first-of-typeであれば、 <span>あ</span><span>い</span> がマッチする。

*-child が子要素全体の中からの検索であり、*-of-typeは該当要素のみの検索であることを考慮する必要がある。

E:only-child, E:only-of-type

E:only-child は唯一の子要素である場合にのみE要素がマッチする。
E:only-of-type は兄弟要素のうち、他にE要素が存在しない場合にのみE要素がマッチする。

<div>
  <p>1</p>
  <p>2</p>
  <span></span>
  <p>3</p>
</div>

の場合、span:only-child は該当なし、 span:only-of-type<span>あ</span> がマッチする。

否定擬似クラスの解説

E:not(s)

単純セレクタsにマッチしないE要素にマッチする。

<li class='active'>1</li>
<li>2</li>
<li>3</li>

の場合、li:not(.active)とすると、 <li>2</li><li>3</li> がマッチする。

ちなみに、単純セレクタとは、要は普段cssdiv.class-name {...;} と定義している際の div.class-name のことである。 Selectors Level 3 の内容を参照するに、

が該当する。つまり#idも.classも:hoverも:linkも大体使える。

纏め

CSSセレクタ多用しまくると何がなんだか分からなりそうなので、使う時はBEMによるCSS設計に基いたりSassを使ったりして構造化を意識して利用しよう。(戒め)。

構造的なCSS設計, Sass設計については、やはり以下の書籍が参考になるのでフロントエンドを学ぶ技術者でまだ買っていない人はぜひ一読をオススメしたい。

Web制作者のためのSassの教科書 これからのWebデザインの現場で必須のCSSメタ言語

Web制作者のためのSassの教科書 これからのWebデザインの現場で必須のCSSメタ言語

参考:

*1:といってもCSSセレクタの内容に変更はない。

flake8 で continuation line under-indented for visual indent [E128] が出る時

flake8でコーディングチェックを行っていると、continuation line under-indented for visual indent [E128] が出る時がある。

f:id:ShineSpark:20151115155229p:plain

Vim標準、もしくは jedi.vim 利用時の自動インデントに倣って入力してるつもりだが、flake8では例えば引数などは、第1引数の開始箇所に倣って第2, 第3引数の開始箇所をあわせていく必要がある。

@app.route('/add', methods=['POST'])
def add_entry():
    if not session.get('logged_in'):
        abort(401)
    g.db.execute('insert into entries (title, text) values(?, ?)',
                 [request.form['title'], request.form['text']])
    g.db.commit()
    flash('New entry was successfully posted')
    return redirect(url_for('show_entries'))

上記のように()内の引数の開始位置を揃えると警告が出なくなる。

みんなのPython 第4版

みんなのPython 第4版

gulpで複数サイトを同時にBrowsersyncで立ち上げる

最近開発にはめっきりBrowsersyncを利用している。 Browsersync - Time-saving synchronised browser testing

通常Webサービスを開発する場合、ユーザ画面と管理画面などと複数サービスを開発するケースが多いので、一つのだけ

$ browser-sync start --config bs-config.js

で立ち上げるのはしんどいものだ。また、他のタスクも走らせるケースが多いので単体でbrowser-syncコマンドで都度立ち上げることもほぼない。

gulpからBrowsersyncを立ち上げる

var gulp = require('gulp');
var browserSync = require('browser-sync').create();
var browserSyncAdmin = require('browser-sync').create();
var browserSyncDefaultSettings = {
  'https': true,
};

function getRewriteRules(matchRule, replaceString) {
  var obj = {};
  obj.match = matchRule;
  obj.fn = function(match) {
    return replaceString;
  };

  return [obj];
}

gulp.task('browser-sync-example.jp', function(){
  var exampleSettings = browserSyncDefaultSettings;
  exampleSettings.files = ['sites/example.jp/public/**/*', 'sites/example.jp/views/**/*.html'];
  exampleSettings.https = true;
  exampleSettings.port  = 3000;
  exampleSettings.proxy = 'https://example.jp';
  exampleSettings.ui = {
    'port': 3001,
    'weinre': {
      'port': 8080
    }
  };
  exampleSettings.rewriteRules = getRewriteRules(/example\(サービス名\)/g, 'さーびすめい');
  browserSync.init(exampleSettings);
});

gulp.task('default', ['browser-sync-example.jp']);

FrameWork内のjs, css, scssファイルとHTMLtemplateファイルを監視対象として、httpsで立ち上げる場合には上記のような形で書いている。 オプション設定は下記を参照。

Browsersync options

$ gulp

複数のサイトをBrowsersyncで立ち上げる

var gulp = require('gulp');
var browserSync = require('browser-sync').create();
var browserSyncAdmin = require('browser-sync').create();
var browserSyncDefaultSettings = {
  'https': true,
};

function getRewriteRules(matchRule, replaceString) {
  var obj = {};
  obj.match = matchRule;
  obj.fn = function(match) {
    return replaceString;
  };

  return [obj];
}

gulp.task('browser-sync-example.jp', function(){
  var exampleSettings = browserSyncDefaultSettings;
  exampleSettings.files = ['sites/example.jp/public/**/*', 'sites/example.jp/views/**/*.html'];
  exampleSettings.https = true;
  exampleSettings.port  = 3000;
  exampleSettings.proxy = 'https://example.jp';
  exampleSettings.ui = {
    'port': 3001,
    'weinre': {
      'port': 8080
    }
  };
  exampleSettings.rewriteRules = getRewriteRules(/example\(サービス名\)/g, 'さーびすめい');
  browserSync.init(exampleSettings);
});

gulp.task('browser-sync-admin.example.jp', function(){
  var adminExampleSettings = browserSyncDefaultSettings;
  adminExampleSettings.files = ['sites/admin.example.jp/public/**/*', 'sites/admin.example.jp/views/**/*.html'];
  adminExampleSettings.https = true;
  adminExampleSettings.port  = 3002;
  adminExampleSettings.proxy = 'https://admin.example.jp';
  adminExampleSettings.ghostMode = false;
  adminExampleSettings.ui = {
    'port': 3003,
    'weinre': {
      'port': 8080
    }
  };
  adminExampleSettings.rewriteRules = getRewriteRules(/サービス名管理画面/g, 'さーびすめい管理画面');
  browserSyncAdmin.init(adminExampleSettings);
});

gulp.task('default', ['browser-sync-example.jp', 'browser-sync-admin.example.jp']);

この場合には gulp実行時に複数サイト同時に稼働するようになる。

Vimのテキストオブジェクトを本気出して纏めてみた

Vimでエディットするにあたり、ダブルクォートで囲まれた部分をシングルクォートにしたいとか、囲まれた部分の内側を置換したいとか、いい加減テキストオブジェクトを使いこなしたいなと思ったので調べつつ憶えてみる。

Vimのコマンドは何らかの単語の頭文字であるケースが殆どなので、コマンドの意味も纏めてみた。

そもそもテキストオブジェクトとは

オブジェクト単位で選択 *object-select* *text-objects*
*v_a* *v_i*

次のものはビジュアルモードかオペレータコマンドの後でのみ使うことができる一連の コマンドを示しています。
"a" で始まるコマンドは "a" (1つの) まとまりをホワイトスペースを含めて選択します。
"i" で始まるコマンドはまとまりの "inner" (内部) をホワイトスペースを含まずに選択するか、もしくはホワイトスペースのみを選択します。
ですので、"inner" コマンドは常に "a" コマンドより少なくテキストを選択する ことになります。

:help text-objects より。

端的に言うと、 従来単語の先頭にカーソルをあわせてから cw としてた所を、
先頭にカーソルをあわせずとも caw で「単語全体を編集」をしたり、 ci' で「'で囲われた内部を編集」が可能とするナイスなオブジェクトのことである。

オペレータコマンドのおさらい

一応オペレータコマンドのおさらい。

コマンド 意味 操作
c change 変更
d delete 削除
y yank ヤンク
~ 大文字/小文字入れ替え
g~ 大文字/小文字入れ替え
gu 小文字にする
gU go Uppercase 大文字にする

他にもzfで折り畳みを作成するなどがあるけどテキストオブジェクトと組み合わせそうにはなさそうなので割愛。
詳細は :help operator を参照で。

テキストオブジェクトのaとiコマンド

コマンド 意味 対象
a an object まとまり(記号を含む)
i inner まとまりの内側(記号を含まない)

a + <移動コマンド> のように指定する。aw なら "a word", iwなら "inner word"となる。
移動コマンドの修飾語のような扱いになる。

aとiコマンドの後に利用可能な移動コマンド

コマンド 意味 対象
w word カーソル前後の単語
W WORD カーソル前後の単語(ホワイトスペース含む)
s sentence カーソル前後の文
p paragraph カーソル前後の段落
[ ] カーソル前後の[]block
( ) または b block カーソル前後の()block
< > カーソル前後の<>block
t tag カーソル前後のtag block. ここでいうタグとはhtmlの<div>...</div>など
{ } または B Block カーソル前後の{}block
" や ' や ` カーソル前後の " や ' や ` それぞれのquote block

移動コマンド単体では使い方が良く分からないと思うので次へどうぞ。

テキストオブジェクトの使い方

上述の オペレータコマンド + a/i + 移動コマンド の組み合わせで使うのが一般的なテキストオブジェクトの利用方法である。

以下に実際の使い方の一例。

コマンド 意味 対象
daw delete a word カーソル前後の単語を削除する
da( delete a block カーソル前後()に囲まれた部分を()も含めて削除する
di( delete inner block カーソル前後の()に囲まれた部分を削除する
ca( change a block カーソル前後()に囲まれた部分を()も含めて変更する
ci( change inner block カーソル前後の()に囲まれた部分を変更する
das delete a sentence カーソル前後の文を削除する
dat delete a tag block カーソル前後のタグを削除する

最もよく使うのは c との組み合わせだろう。
ci' のクォートに囲われた部分の変更を私は既に良く利用している。

s のsentenceはノーマルモードでは( , )で移動する単位のもの。
利用するのであれば日頃からVimの文の単位を理解しておきたいところ。

t がめっちゃ使えそう。と思ったけど、終端タグ </something> があるタグじゃないとダメなので ci< などと使い分けが求められる。
普段からhjkl以外の移動にも慣れておくと、テキストオブジェクトも有効に利用できそうなのでいろいろ使って慣れておきましょう。

Surround.vim

括弧やクォートやタグなどの、文字列を囲むものを簡単に操作するVim Plugin。
テキストオブジェクトとセットで語られることが多いのでこちらも纏めて取り上げる。

github.com

Surround.vim の使い方

<オペレータコマンド> + s + <対象の括弧/クォート/テキストオブジェクト> + (<置換, 挿入する括弧/クォート>) という形で利用する。
英語のSVO型とSVOO型のような形を意識して README.markdown を試すと理解が進む。

まずはじめに"で括られたテキストを用意する

"Hello world!"

cs"' とtypeすると、"を'に置換する

'Hello world!'

cs'<span> とtypeすると、'をspanタグに置換する

<span>Hello world!</span>

cst" とtypeすると、spanタグを"に置換する

"Hello world!"

ds" とtypeすると、"を削除する

Hello world!

ysiw] とtypeすると、inner wordを[]で囲う

[Hello] world!

cs]{ とtypeすると、[]を{}に置換する *1

{ Hello } world!

yssb もしくは yss)とtypeすると、文を()で囲う

({ Hello } world!)

ds{ds{ とtypeすると、括弧を削除する

Hello  world!

ysiw<em> とtypeすると、inner wordをemタグで囲う

<em>Hello</em>  world!

Vで行選択後、S<span class='info'> とtypeすると、行をspan.infoタグで囲う

<span class='info'>
<em>Hello</em>  world!
</span>

あ、これ慣れると最高なやつだ。

  • ccs + <変更対象の括弧> + <変更後の括弧> で括弧の変更
  • dds + <削除対象の括弧> で括弧の削除
  • yys + <括弧で囲う対象のテキストオブジェクト> + 括弧 でテキストオブジェクトを括弧で囲う
  • ビジュアルモードでの呼び出しは S
  • 他のオペレータコマンド ~ とかは使えない*2

を憶えれば基本はOK.

Surround.vim のカスタマイズ

let g:surround_<ASCII code> = "<% \r %"> と.vimrcに書くと yss<ASCII code> などで置換できるようになる。*3

もっと詳しくカスタマイズしたければ :help surround を読めばOK.

まとめ

テキストオブジェクトで括弧内の文字列編集、
Surroud.vimで括弧の編集が楽にできるんや!!

Vimテクニックバイブル ?作業効率をカイゼンする150の技

Vimテクニックバイブル ?作業効率をカイゼンする150の技

参考

*1:cs]}ならスペースなし

*2:というか括弧類に対して働くコマンドではない。

*3:ASCII codeを調べるには :echo char2nr("-")