<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xml:lang="ja">
	<channel>
		<title>mayokara note</title>
		<link>http://mayokara.info/note/</link>
		<description>Enjoy everything.</description>
		<language>ja</language>
		<pubDate>Sat, 25 Oct 2008 17:57:00 +0900</pubDate>
		<lastBuildDate>Sat, 25 Oct 2008 17:57:00 +0900</lastBuildDate>
		<docs>http://blogs.law.harvard.edu/tech/rss</docs>
		<atom:link href="http://mayokara.info/note/rss2" rel="self" type="application/rss+xml" />
				<item>
			<title>「sbmc.user.js」更新 その2</title>
			<link>http://mayokara.info/note/view/338</link>
			<guid isPermaLink="true">http://mayokara.info/note/view/338</guid>
			<description><![CDATA[
<div class="section">
<p><a href="http://mayokara.info/note/view/262">Greasemonkey: sbmc.user.js - mayokara note</a></p>
<p>セキュリティ・フィックス。</p>
<ul>
<li>innerHTMLを使っている箇所できちんとHTMLエスケープするようにした
<ul>
<li>HTMLエスケープされた状態で送ってくるJSONがあって微妙……<ins>→対処した</ins></li>
</ul>
</li>
<li>z-indexを256から512に変更</li>
</ul>
</div>
<div class="section">
<h3>HTMLエスケープとリンク生成</h3>
<pre class="javascript">
var h = function(str){
    return String(str).replace(/[&amp;&lt;&gt;&quot;&#039;]/g, function($0){
        return {&quot;&amp;&quot;: &quot;&amp;amp;&quot;, &quot;&lt;&quot;: &quot;&amp;lt;&quot;, &quot;&gt;&quot;: &quot;&amp;gt;&quot;, &#039;&quot;&#039;: &quot;&amp;quot;&quot;, &quot;&#039;&quot;: &quot;&amp;#39;&quot;}[$0];
    });
};

var makeanchor = function(str){
    return str.replace(/https?:\/\/[\w\-.!~*&#039;();\/?:@&amp;=+$,%#]+/g, &#039;&lt;a href=&quot;$&amp;&quot; target=&quot;_blank&quot;&gt;$&amp;&lt;/a&gt;&#039;);
};
</pre>
<p>後者は厳密なものではないです。</p>
</div>

			]]></description>
			<category>雑記</category><category>雑感</category>			<pubDate>Sat, 25 Oct 2008 17:57:00 +0900</pubDate>
		</item>
				<item>
			<title>「sbmc.user.js」更新</title>
			<link>http://mayokara.info/note/view/337</link>
			<guid isPermaLink="true">http://mayokara.info/note/view/337</guid>
			<description><![CDATA[
<div class="section">
<p><a href="http://mayokara.info/note/view/262">Greasemonkey: sbmc.user.js - mayokara note</a></p>
<p><a href="http://delicious.com/">delicious.com</a>に対応した。</p>
<p>あと、tr要素にユーザ名つきのclassNameを追加したので</p>
<pre class="css">
#sbmc-user-js tr.sbmc-user-js-hatena-mayokara384 {
  display: none;
}
</pre>
<p>とかで特定のユーザを消せます。</p>
</div>

			]]></description>
			<category>雑記</category><category>雑感</category>			<pubDate>Mon, 15 Sep 2008 01:17:00 +0900</pubDate>
		</item>
				<item>
			<title>Bookmarklet: deliciousのブックマークページに飛ぶ</title>
			<link>http://mayokara.info/note/view/336</link>
			<guid isPermaLink="true">http://mayokara.info/note/view/336</guid>
			<description><![CDATA[
<div class="section">
<pre class="javascript">
javascript:void(location.href=&quot;http://delicious.com/url?url=&quot;+location.href);
</pre>
<p><a href="javascript:void(location.href=&quot;http://delicious.com/url?url=&quot;+location.href);">delicious表示</a></p>
<p>既出かもしれない。</p>
<p><ins><a href="http://delicious.com/help/bookmarklets">http://delicious.com/help/bookmarklets</a>に書いてあった。</ins></p>
<br />
<p>コメント一覧のJSONは<em>http://feeds.delicious.com/v2/json/url?count=100&amp;url=${url}</em>から取得できるみたいだけど書いてない。</p>
<p><var>count</var>は<a href="http://delicious.com/help/feeds">http://delicious.com/help/feeds</a>にあるようにデフォルト15で最大値100。</p>
<p><em>json</em>を<em>rss</em>にすればRSS 2.0で取得できる。</p>
<p>JSONだとユーザ名が取れないのでRSS 2.0をみたほうが良さげ。</p>
</div>

			]]></description>
			<category>個人的メモ</category><category>Bookmarklet</category><category>Toys</category>			<pubDate>Sun, 14 Sep 2008 23:26:00 +0900</pubDate>
		</item>
				<item>
			<title>ginc</title>
			<link>http://mayokara.info/note/view/335</link>
			<guid isPermaLink="true">http://mayokara.info/note/view/335</guid>
			<description><![CDATA[
<div class="section">
<p><a href="http://mayokara.info/misc/ginc/">ginc</a></p>
<p><a href="http://code.google.com/apis/ajaxsearch/">Google Ajax Search API</a>でインクリメンタル検索。</p>
<p>上部の検索ボックスに入力したあと500msで検索します。</p>
<p>IE、Opera9.2では動きません。</p>
<br />
<p>まあ、ただインクリメンタル検索を作ってみたかっただけ……</p>
</div>

			]]></description>
			<category>個人的メモ</category><category>Toys</category>			<pubDate>Sun, 14 Sep 2008 18:41:00 +0900</pubDate>
		</item>
				<item>
			<title>回文作成補助フォーム</title>
			<link>http://mayokara.info/note/view/334</link>
			<guid isPermaLink="true">http://mayokara.info/note/view/334</guid>
			<description><![CDATA[
<div class="section">
<p><input type="text" size="40" value="" onkeyup="this.nextSibling.innerHTML=this.value.split('').reverse().join('');" /><span></span></p>
</div>

			]]></description>
			<category>個人的メモ</category><category>JavaScript</category><category>Toys</category>			<pubDate>Sat, 06 Sep 2008 13:50:00 +0900</pubDate>
		</item>
				<item>
			<title>Bookmarklet: HTMLエスケープするリンク（＋引用）生成</title>
			<link>http://mayokara.info/note/view/333</link>
			<guid isPermaLink="true">http://mayokara.info/note/view/333</guid>
			<description><![CDATA[
<div class="section">
<pre class="javascript">
javascript:(function(l,t,s){var h=function(s){return s.replace(/[&amp;&lt;&gt;&quot;&#039;]/g,function(m){return ({&quot;&amp;&quot;:&quot;&amp;amp;&quot;,&quot;&lt;&quot;:&quot;&amp;lt;&quot;,&quot;&gt;&quot;:&quot;&amp;gt;&quot;,&#039;&quot;&#039;:&quot;&amp;quot;&quot;,&quot;&#039;&quot;:&quot;&amp;#39;&quot;})[m];});},r=&#039;&lt;a href=&quot;&#039;+h(l)+&#039;&quot;&gt;&#039;+h(t)+&#039;&lt;/a&gt;&#039;+(s?&#039;&lt;blockquote cite=&quot;&#039;+h(l)+&#039;&quot; title=&quot;&#039;+h(t)+&#039;&quot;&gt;&lt;p&gt;&#039;+h(s).replace(/(\r\n|\r|\n)+/g,&#039;&lt;br&gt;&#039;)+&#039;&lt;/p&gt;&lt;/blockquote&gt;&#039;:&#039;&#039;);prompt(r,r);})(location.href,document.title,String(getSelection()));
</pre>
<p><a href="javascript:(function(l,t,s){var h=function(s){return s.replace(/[&amp;&lt;&gt;&quot;&#39;]/g,function(m){return ({&quot;&amp;&quot;:&quot;&amp;amp;&quot;,&quot;&lt;&quot;:&quot;&amp;lt;&quot;,&quot;&gt;&quot;:&quot;&amp;gt;&quot;,&#39;&quot;&#39;:&quot;&amp;quot;&quot;,&quot;&#39;&quot;:&quot;&amp;#39;&quot;})[m];});},r=&#39;&lt;a href=&quot;&#39;+h(l)+&#39;&quot;&gt;&#39;+h(t)+&#39;&lt;/a&gt;&#39;+(s?&#39;&lt;blockquote cite=&quot;&#39;+h(l)+&#39;&quot; title=&quot;&#39;+h(t)+&#39;&quot;&gt;&lt;p&gt;&#39;+h(s).replace(/(\r\n|\r|\n)+/g,&#39;&lt;br&gt;&#39;)+&#39;&lt;/p&gt;&lt;/blockquote&gt;&#39;:&#39;&#39;);prompt(r,r);})(location.href,document.title,String(getSelection()));">makelink</a></p>
<br />
<pre>
&lt;a href=&quot;${url}&quot;&gt;${title}&lt;/a&gt;&lt;blockquote cite=&quot;${url}&quot; title=&quot;${title}&quot;&gt;&lt;p&gt;${selection}&lt;/p&gt;&lt;/blockquote&gt;
</pre>
<p>こんな感じのHTMLタグを作るブックマークレット（選択範囲が空ならa要素のみ）。</p>
<p>文字数的にも<code>window.getSelection</code>的にも多分Firefox限定。</p>
<p>各文字列をHTMLエスケープするところがポイント。</p>
<p>Copy URL+でもできるっぽいけど、なんかもうめんどくさいのでブックマークレットにした。</p>
<br />
<p>blockquote要素の内容モデルは</p>
<dl>
<dt>HTML 4.01 Strict</dt>
<dd><code>(%block;|SCRIPT)+</code></dd>
<dt>HTML 4.01 Transitional</dt>
<dd><code>(%flow;)*</code></dd>
<dt>HTML 5（ドラフト）</dt>
<dd>Flow content</dd>
<dt>XHTML 1.0 Strict</dt>
<dd><code>%Block;</code></dd>
<dt>XHTML 1.0 Transitional</dt>
<dd><code>%Flow;</code></dd>
<dt>XHTML 1.1</dt>
<dd><code>(Heading | Block | List)*</code></dd>
<dt>XHTML 2.0（ドラフト）</dt>
<dd><code>(PCDATA | Text | Heading | Structural | List)*</code></dd>
</dl>
<p>とかいう感じになっているらしいので、p要素つき。</p>
</div>
<div class="section">
<h3>関連</h3>
<p><a href="http://mayokara.info/note/view/267">Bookmarklet: Amazonリンク生成 - mayokara note</a></p>
</div>

			]]></description>
			<category>個人的メモ</category><category>Bookmarklet</category><category>Toys</category>			<pubDate>Thu, 04 Sep 2008 21:23:00 +0900</pubDate>
		</item>
				<item>
			<title>deadspace</title>
			<link>http://mayokara.info/note/view/332</link>
			<guid isPermaLink="true">http://mayokara.info/note/view/332</guid>
			<description><![CDATA[
<div class="section">
<p><a href="http://mayokara.info/deadspace/">deadspace</a></p>
<p>ダメな感じの日記を書くスペースを作った。</p>
</div>

			]]></description>
			<category>雑記</category><category>雑感</category>			<pubDate>Thu, 04 Sep 2008 14:34:00 +0900</pubDate>
		</item>
				<item>
			<title>無題</title>
			<link>http://mayokara.info/note/view/331</link>
			<guid isPermaLink="true">http://mayokara.info/note/view/331</guid>
			<description><![CDATA[
<div class="section">
<p>19姉妹が各種言語を学習するブログ（WHOLE SWEET LANG）をお願いします。</p>
</div>

			]]></description>
			<category>雑記</category><category>雑感</category>			<pubDate>Thu, 04 Sep 2008 01:10:00 +0900</pubDate>
		</item>
				<item>
			<title>feedgen.appjet.net</title>
			<link>http://mayokara.info/note/view/330</link>
			<guid isPermaLink="true">http://mayokara.info/note/view/330</guid>
			<description><![CDATA[
<div class="section">
<p><a href="http://feedgen.appjet.net/">http://feedgen.appjet.net/</a></p>
<p>URLと正規表現からRSS 2.0を作るサービス。</p>
<br />
<p>たとえばこのブログなら（フィードあるから意味ないけど）</p>
<dl>
<dt>url</dt>
<dd>http://mayokara.info/note/</dd>
<dt>re</dt>
<dd>&lt;h2 class=&quot;entrytitle entry-title&quot;&gt;&lt;a[^&gt;]+&gt;([\s\S]+?)&lt;/a&gt;&lt;/h2&gt;\s*&lt;div class=&quot;entrybody entry-content&quot;&gt;([\s\S]+?)&lt;/div&gt;(?=\s*&lt;ul class=&quot;entryinfo&quot;&gt;)</dd>
<dt>title</dt>
<dd>1</dd>
<dt>description</dt>
<dd>2</dd>
</dl>
<p>で</p>
<p><a href="http://feedgen.appjet.net/?url=http%3A%2F%2Fmayokara.info%2Fnote%2F&amp;re=%3Ch2+class%3D%22entrytitle+entry-title%22%3E%3Ca%5B%5E%3E%5D%2B%3E%28%5B%5Cs%5CS%5D%2B%3F%29%3C%2Fa%3E%3C%2Fh2%3E%5Cs%2A%3Cdiv+class%3D%22entrybody+entry-content%22%3E%28%5B%5Cs%5CS%5D%2B%3F%29%3C%2Fdiv%3E%28%3F%3D%5Cs%2A%3Cul+class%3D%22entryinfo%22%3E%29&amp;title=1&amp;description=2">http://feedgen.appjet.net/?url=http%3A%2F%2Fmayokara.info%2Fnote%2F&amp;re=%3Ch2+class%3D%22entrytitle+entry-title%22%3E%3Ca%5B%5E%3E%5D%2B%3E%28%5B%5Cs%5CS%5D%2B%3F%29%3C%2Fa%3E%3C%2Fh2%3E%5Cs%2A%3Cdiv+class%3D%22entrybody+entry-content%22%3E%28%5B%5Cs%5CS%5D%2B%3F%29%3C%2Fdiv%3E%28%3F%3D%5Cs%2A%3Cul+class%3D%22entryinfo%22%3E%29&amp;title=1&amp;description=2</a></p>
<p>こんな感じ。</p>
<p>改行を含む全ての文字<code>[\s\S]</code>や、最小マッチ<code>*?</code>・<code>+?</code>、先読み<code>(?=...)</code>を使うのがコツ。</p>
<br />
<p>optionalなパラメータは</p>
<ul>
<li>html要素の(xml:)lang属性</li>
<li>title要素</li>
<li>meta要素（めんどくさいのでcontent属性が後ろに書かれているもののみ）</li>
</ul>
<p>から補完します。</p>
<p>charsetも元のHTTPヘッダとmeta要素を調べて、見つかれば送信します。</p>
<p>MIME Typeはapplication/rss+xml。</p>
</div>
<div class="section">
<h3>追記</h3>
<p><a href="http://d.hatena.ne.jp/murky-satyr/20080923/1222152972">RRRS - ’ellaneous</a></p>
<p>頂いたパッチ（とほぼ同等のコード）を適用しました。ありがとうございます。</p>
<ul>
<li><var>Date</var>、<var>Last-Modified</var>が送られてこなかったとき、エラーになっていたのを修正</li>
<li>title、descriptionの自由度向上
<ul>
<li><samp>1 hoge 2 fuga 3</samp>が<samp>$1hoge$2fuga$3</samp>になる（前後のスペースは除去）</li>
</ul>
</li>
</ul>
<br />
<p>コードはこちら。</p>
<p><a href="http://appjet.com/app/971183202/source">http://appjet.com/app/971183202/source</a></p>
</div>

			]]></description>
			<category>個人的メモ</category><category>Toys</category>			<pubDate>Wed, 03 Sep 2008 16:52:00 +0900</pubDate>
		</item>
				<item>
			<title>JavaScript: ビット反転とString#indexOf</title>
			<link>http://mayokara.info/note/view/329</link>
			<guid isPermaLink="true">http://mayokara.info/note/view/329</guid>
			<description><![CDATA[
<div class="section">
<blockquote title="hatebu - ’ellaneous" cite="http://d.hatena.ne.jp/murky-satyr/20080902/1220311192">
<pre class="javascript">
if(~block.innerHTML.indexOf(this._key))
      return;
</pre>
<cite><a href="http://d.hatena.ne.jp/murky-satyr/20080902/1220311192">hatebu - ’ellaneous</a></cite>
</blockquote>
<p>これは使える。</p>
<br />
<pre class="javascript">
// 含むとき
if (~str.indexOf(&quot;http://&quot;)) {}

// 含まないとき
if (!~str.indexOf(&quot;http://&quot;)) {}
</pre>
<p><code>+1</code>だと後者に括弧が1組増えるとか、含む含まないの判定なのに<code>+1</code>？みたいな違和感があるけど、これだとけっこうすっきりする。</p>
<p>慣れがいるかもだけど。</p>
</div>

			]]></description>
			<category>個人的メモ</category><category>JavaScript</category><category>Tips</category>			<pubDate>Tue, 02 Sep 2008 19:13:00 +0900</pubDate>
		</item>
				<item>
			<title>1px透過GIF・PNGの最小base64表現</title>
			<link>http://mayokara.info/note/view/328</link>
			<guid isPermaLink="true">http://mayokara.info/note/view/328</guid>
			<description><![CDATA[
<div class="section">
<p><a href="http://subtech.g.hatena.ne.jp/secondlife/20070831/1188535911">透過GIF 1px・Base64 - 8時40分が超えられない - subtech</a></p>
<p>縮めてみた。多分最小。</p>
</div>
<div class="section">
<h3>1px透過GIF 39bytes</h3>
<pre>
R0lGODlhAQABAGAAACH5BAEKAP8ALAAAAAABAAEAAAgEAP8FBAA7
</pre>
<p><a href="data:image/gif;base64,R0lGODlhAQABAGAAACH5BAEKAP8ALAAAAAABAAEAAAgEAP8FBAA7">data:image/gif;base64,R0lGODlhAQABAGAAACH5BAEKAP8ALAAAAAABAAEAAAgEAP8FBAA7</a></p>
</div>
<div class="section">
<h3>1px透過PNG 68bytes</h3>
<pre>
iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVQI12NgYAAAAAMAASDVlMcAAAAASUVORK5CYII=
</pre>
<p><a href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVQI12NgYAAAAAMAASDVlMcAAAAASUVORK5CYII=">data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVQI12NgYAAAAAMAASDVlMcAAAAASUVORK5CYII=</a></p>
</div>
<div class="section">
<h3>使用例</h3>
<pre class="perl">
#!/usr/bin/perl

use strict;
use warnings;
use CGI qw/:cgi/;
use MIME::Base64 qw(decode_base64);

print header(&#039;image/gif&#039;);
print decode_base64(&#039;R0lGODlhAQABAGAAACH5BAEKAP8ALAAAAAABAAEAAAgEAP8FBAA7&#039;);
exit;
</pre>
<p>とか</p>
<pre class="php">
&lt;?php
header(&#039;Content-Type: image/gif&#039;);
echo base64_decode(&#039;R0lGODlhAQABAGAAACH5BAEKAP8ALAAAAAABAAEAAAgEAP8FBAA7&#039;);
exit;
?&gt;
</pre>
<p>とか。</p>
</div>
<div class="section">
<h3>文字列化</h3>
<pre class="javascript">
Array.map(atob(&quot;R0lGODlhAQABAGAAACH5BAEKAP8ALAAAAAABAAEAAAgEAP8FBAA7&quot;), function(v){ return &quot;\\x&quot;+(&quot;0&quot;+v.charCodeAt(0).toString(16)).slice(-2).toUpperCase(); }).join(&quot;&quot;);
// -&gt; &quot;\x47\x49\x46\x38\x39\x61\x01\x00\x01\x00\x60\x00\x00\x21\xF9\x04\x01\x0A\x00\xFF\x00\x2C\x00\x00\x00\x00\x01\x00\x01\x00\x00\x08\x04\x00\xFF\x05\x04\x00\x3B&quot;

Array.map(atob(&quot;iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVQI12NgYAAAAAMAASDVlMcAAAAASUVORK5CYII=&quot;), function(v){ return &quot;\\x&quot;+(&quot;0&quot;+v.charCodeAt(0).toString(16)).slice(-2).toUpperCase(); }).join(&quot;&quot;);
// -&gt; &quot;\x89\x50\x4E\x47\x0D\x0A\x1A\x0A\x00\x00\x00\x0D\x49\x48\x44\x52\x00\x00\x00\x01\x00\x00\x00\x01\x08\x04\x00\x00\x00\xB5\x1C\x0C\x02\x00\x00\x00\x0B\x49\x44\x41\x54\x08\xD7\x63\x60\x60\x00\x00\x00\x03\x00\x01\x20\xD5\x94\xC7\x00\x00\x00\x00\x49\x45\x4E\x44\xAE\x42\x60\x82&quot;
</pre>
<p>こっちはそのままprint/echoすればOK。</p>
</div>

			]]></description>
			<category>個人的メモ</category>			<pubDate>Tue, 02 Sep 2008 12:04:00 +0900</pubDate>
		</item>
				<item>
			<title>JavaScript: Iterator関数をhasOwnProperty代わりに使う</title>
			<link>http://mayokara.info/note/view/327</link>
			<guid isPermaLink="true">http://mayokara.info/note/view/327</guid>
			<description><![CDATA[
<div class="section">
<p><a href="http://d.hatena.ne.jp/javascripter/20080831/1220193619">いちいちhasOwnPropertyを使わなくてよくする(ジェネレータの使いかた) - 素人がプログラミングを勉強するブログ</a></p>
<p>多分Firefox2/3限定。JavaScript1.7相当。</p>
<p>Iterator関数を噛ませる方法もあります。</p>
<pre class="javascript">
Object.prototype.extend = function(){};

var o = {a:1,b:2,c:3};
for (var i in o) console.log(i);
/* -&gt;
a
b
c
extend
*/

for (var i in Iterator(o)) console.log(i);
/* -&gt;
[&quot;a&quot;, 1]
[&quot;b&quot;, 2]
[&quot;c&quot;, 3]
*/

for each (var i in Iterator(o)) console.log(i);
/* -&gt;
[&quot;a&quot;, 1]
[&quot;b&quot;, 2]
[&quot;c&quot;, 3]
*/
</pre>
<p>こんな具合になってるので</p>
<pre class="javascript">
for (var [i,v] in Iterator(o)) console.log(i);
/* -&gt;
a
b
c
*/

for (var [i,v] in Iterator(o)) console.log(v);
/* -&gt;
1
2
3
*/

[p[0] for (p in Iterator(o))]
// -&gt; [&quot;a&quot;, &quot;b&quot;, &quot;c&quot;] keys

[p[1] for (p in Iterator(o))]
// -&gt; [1, 2, 3] values
</pre>
<p>とか。</p>
<p>微妙に形が変わるのが微妙といえば微妙。</p>
<br />
<p>yieldもletも使ってないので、Firefox2のFirebugコンソールでも使えるあたりが強み。</p>
<p>あとArrayでも順序が保証されている（はず）なのでbreakの効くforEachとしても使える。</p>
</div>
<div class="section">
<h3>関連リソース</h3>
<p><a href="http://developer.mozilla.org/en/Core_JavaScript_1.5_Guide/Iterators_and_Generators">Iterators and Generators - MDC</a></p>
<blockquote>
<p>One advantage of using Iterator() to access the contents of an object is that custom properties that have been added to Object.prototype will not be included in the sequence.</p>
</blockquote>
<blockquote>
<p>Iterator() can be used with arrays as well:</p>
</blockquote>
<p><a href="http://d.hatena.ne.jp/fls/20070728/p2">JavaScript 1.8 では配列が自動的に Iterator に変換されなくなった? - やんばるもじら</a></p>
</div>

			]]></description>
			<category>個人的メモ</category><category>JavaScript</category><category>Tips</category>			<pubDate>Mon, 01 Sep 2008 17:48:00 +0900</pubDate>
		</item>
				<item>
			<title>Greasemonkey: tish.user.js</title>
			<link>http://mayokara.info/note/view/326</link>
			<guid isPermaLink="true">http://mayokara.info/note/view/326</guid>
			<description><![CDATA[
<div class="section">
<p><img src="http://mayokara.info/note/files/d20080823_tish-user-js.png" width="500" height="280" alt="tako3.comからJSONを取得の図" title="tako3.comからJSONを取得の図" /></p>
<p><a href="http://mayokara.info/misc/files/tish.user.js">tish.user.js</a></p>
<p><a href="http://mayokara.info/note/view/307">tinyshell.user.js</a>を書き換えたもの。</p>
<p>シェルっぽい何か。</p>
</div>
<div class="section">
<h3>注意</h3>
<ul>
<li>Minibuffer（+LDRize）との併用不可
<ul>
<li>ショートカットキーが競合</li>
<li><kbd>&amp;</kbd>にしようかと思ったけどSHIFT同時押しが使いづらいのでやめた</li>
</ul>
</li>
<li>コマンドの移植度が微妙
<ul>
<li>実装したもの：cat cd clear cut date echo exit expr find go google grep hatena head inspect jot logout ls maketoc open parse printf prompt pwd rm save sed seq settimer sort tac tail tee tr uniq up wc wget xargs</li>
<li>seqが自然数でしか使えなかったり、sedがエディタになってなかったり、いろいろ</li>
</ul>
</li>
</ul>
</div>
<div class="section">
<h3>起動方法など</h3>
<p><kbd>:</kbd>か<kbd>ALT</kbd>+<kbd>x</kbd>で起動。</p>
<p><code>clear</code>コマンドもしくは<kbd>CTRL</kbd>+<kbd>L</kbd>でクリア。</p>
<p><kbd>TAB</kbd>2回で候補表示。候補が1つだけのときは<kbd>TAB</kbd>1回で補完。</p>
</div>
<div class="section">
<h3>ファイルシステムもどき</h3>
<pre>
$ pwd
http://mayokara.info/note/
$ cat links|head &gt; outfile
$ cat outfile
http://mayokara.info/note/
http://mayokara.info/note/1
http://mayokara.info/note/view/325
http://mayokara.info/note/view/257
http://mayokara.info/note/search/tag/個人的メモ
http://mayokara.info/note/search/tag/JavaScript
http://mayokara.info/
http://mayokara.info/note/view/325
http://mayokara.info/note/view/325#comment
http://mayokara.info/note/view/325#trackback
$ cat feeds
http://mayokara.info/note/rss2
$ cat //h2/a/@href
http://mayokara.info/note/view/325
http://mayokara.info/note/view/324
http://mayokara.info/note/view/323
http://mayokara.info/note/view/322
http://mayokara.info/note/view/321
http://mayokara.info/note/view/320
http://mayokara.info/note/view/319
http://mayokara.info/note/view/318
http://mayokara.info/note/view/317
http://mayokara.info/note/view/316
</pre>
<p>text,links,images,stext,slinks,simages,feeds,next,prevなどは読み込み専用で、現在のページ／選択範囲に対するさまざまな情報を返す。</p>
<p>スラッシュを含む指定はXPathとみなされる。</p>
<p>書き出したファイルはコマンド履歴とは異なり、そのタブを開いている間しか参照できない。</p>
</div>
<div class="section">
<h3>wget &amp; parse</h3>
<pre>
$ cat feeds
http://mayokara.info/note/rss2
$ cat feeds|wget -i -|parse //item/link
wget: waiting for response... http://mayokara.info/note/rss2
wget: HTTP/1.x 200 OK
wget: Date: Sat, 23 Aug 2008 11:38:15 GMT
wget: Server: Apache
wget: Last-Modified: Sat, 23 Aug 2008 11:33:34 GMT
wget: Content-Type: text/xml;charset=UTF-8
wget: Content-Encoding: gzip
wget: Content-Length: 13016
http://mayokara.info/note/view/325
http://mayokara.info/note/view/324
http://mayokara.info/note/view/323
http://mayokara.info/note/view/322
http://mayokara.info/note/view/321
http://mayokara.info/note/view/320
http://mayokara.info/note/view/319
http://mayokara.info/note/view/318
http://mayokara.info/note/view/317
http://mayokara.info/note/view/316
http://mayokara.info/note/view/315
http://mayokara.info/note/view/314
http://mayokara.info/note/view/313
http://mayokara.info/note/view/312
http://mayokara.info/note/view/311
</pre>
<p><code>wget</code>でresponseTextを取得し、<code>parse</code>でXPathを用いて抽出。</p>
<p><code>wget -i - -l3</code>とすれば、標準入力の3行目を読み込む。</p>
<p><code>parse -j</code>で入力をJSONとみなし、<a href="http://mayokara.info/note/view/320">DOMツリーに変換</a>する。</p>
</div>
<div class="section">
<h3>tako3.comからデータを取得</h3>
<pre>
$ echo http://tako3.com/json/likely/ `pwd`|tr -d &quot; &quot;|wget -i -|parse -j //jsonarray|tee tako3|cat -n
wget: waiting for response... http://tako3.com/json/likely/http://mayokara.info/note/
wget: HTTP/1.x 200 OK
wget: Date: Sat, 23 Aug 2008 11:43:25 GMT
wget: Server: Apache
wget: Content-Type: text/plain
wget: Transfer-Encoding: chunked
     1  http://mayokara.info/blog/
     2  http://mayokara.info/
     3  http://d.hatena.ne.jp/mayokara384/
     4  http://mayokara.info/note/
$ open tako3 -l3
</pre>
<p>現在のロケーションに関する情報をtako3.comから取得する。</p>
<p>番号を振る前のデータをtako3というファイルにtee。</p>
<p><code>open tako3 -l3</code>で3行目を開く。</p>
<p><code>echo ...|tr -d " "</code>の代わりに<code>printf &quot;%s%s&quot; http://tako3.com/json/likely/ `pwd`</code>でも可。</p>
</div>
<div class="section">
<h3>しょぼいカレンダーから直近の番組データを取得</h3>
<pre>
$ wget &quot;http://cal.syoboi.jp/rss.php?titlefmt=$(StTime) $(ChName) $(Title)&quot;|parse //x:item/x:title|head
wget: waiting for response... http://cal.syoboi.jp/rss.php?titlefmt=$(StTime)%20$(ChName)%20$(Title)
wget: HTTP/1.x 200 OK
wget: Date: Sat, 23 Aug 2008 11:44:53 GMT
wget: Server: Apache/2.2.3 (Unix) PHP/5.2.5
wget: X-Powered-By: PHP/5.2.5
wget: Cache-Control: no-cache, must-revalidate
wget: Expires: Mon, 26 Jul 1997 05:00:00 GMT
wget: Content-Type: text/xml; charset=UTF-8
wget: Transfer-Encoding: chunked
08/23 21:00 文化放送(1134) A&amp;G超RADIO SHOW～アニスパ!～
08/23 22:30 TOKYO MX 鉄腕バーディー DECODE
08/23 22:30 キッズステーション NARUTO -ナルト- 疾風伝
08/23 23:00 BS11デジタル 鉄腕バーディー DECODE
08/23 23:00 文化放送(1134) A&amp;Gメディアステーション こむちゃっとカウントダウン
08/23 23:30 BS11デジタル ウルトラヴァイオレット コード044
08/24 00:00 tvk アニメTV
08/24 00:00 BS11デジタル 真ゲッターロボ 世界最後の日
08/24 00:30 tvk 薬師寺涼子の怪奇事件簿
08/24 01:00 tvk 狂乱家族日記
</pre>
<p>RSS1.0ではデフォルト名前空間があるのでXPathに<code>x:</code>が必要。</p>
</div>
<div class="section">
<h3>Twitterの「フォロー中」にリストされているユーザIDを取得</h3>
<pre>
$ pwd
http://twitter.com/XXXXXX
$ inspect
inspect: &#039;id(&quot;friends&quot;)/span[@class=&quot;vcard&quot;][1]/a[@class=&quot;url&quot;][1]&#039;
$ cat id(&quot;friends&quot;)//a/@href|cut -d / -f 4
XXXXXX
XXXXXX
XXXXXX
...
</pre>
<p>inspectでXPathを調べる。左／右クリックで終了。</p>
<p>@href、@srcはAbsolute URLに変換して返される（場当たり的対応）。</p>
</div>
<div class="section">
<h3>外部ファイルによる操作</h3>
<pre class="javascript">
// ==UserScript==
// @name           dot_tishrc
// @namespace      http://mayokara.info/
// @description    .tishrc
// @include        http://*
// ==/UserScript==

(function(){

var Shell = window.Tish;
if (!Shell) return;

Shell.addAlias(&#039;tako3&#039;, &#039;printf &quot;%s%s&quot; http://tako3.com/json/likely/ `pwd`|wget -i -|parse -j //jsonarray|tee tako3|cat -n&#039;);

Shell.addCommand(&quot;hitori-goto&quot;, function(STDIN, ARGV, $0){
    if (ARGV.length &gt; 0) {
        var callback = function(res){
            Shell.println($0 + &quot;: &quot; + res.status + &quot; &quot; + res.statusText);
        };
        GM_xmlhttpRequest({
            method: &quot;POST&quot;,
            url: &quot;http://hitori-goto.appspot.com/say&quot;,
            data: &quot;comment=&quot; + encodeURIComponent(ARGV.join(&quot; &quot;)),
            headers: { &quot;Content-Type&quot;: &quot;application/x-www-form-urlencoded&quot; },
            onload: callback,
            onerror: callback,
        });
        Shell.println($0 + &quot;: waiting for response...&quot;);
    } else {
        return Shell.exec(&quot;wget http://hitori-goto.appspot.com/rss2|parse //item/title&quot;, &quot;&quot;);
    }
});

})();
</pre>
<p>エイリアスやコマンドを追加できる。</p>
</div>
<div class="section">
<h3>cd、go/open</h3>
<p>cdは引数のURLを開く。go/openは標準入力あるいはファイル内のURLを開く。</p>
</div>
<div class="section">
<h3>googleとかhatenaとか</h3>
<pre>
$ google --code printf
http://www.google.com/codesearch?q=printf
$ hatena id:mayokara384
http://d.hatena.ne.jp/mayokara384/
$ hatena b:id:mayokara384
http://b.hatena.ne.jp/mayokara384/
</pre>
<p>URLを作って返すだけ。</p>
</div>

			]]></description>
			<category>個人的メモ</category><category>Greasemonkey</category><category>Toys</category>			<pubDate>Sat, 23 Aug 2008 20:22:00 +0900</pubDate>
		</item>
				<item>
			<title>JavaScript: defer関数でいろいろ</title>
			<link>http://mayokara.info/note/view/325</link>
			<guid isPermaLink="true">http://mayokara.info/note/view/325</guid>
			<description><![CDATA[
<div class="section">
<p><a href="http://mayokara.info/note/view/257">JavaScript: 普通に同期処理 - mayokara note</a></p>
<pre class="javascript">
var defer = function(/* f1, f2, ... */){
    var self = this, fn = Array.prototype.slice.call(arguments);
    (function(/* arg2, arg3, ... */){
        var args = Array.prototype.slice.call(arguments);
        (fn.shift()).apply(self, [arguments.callee].concat(args));
    })();
};
</pre>
<p>この関数の説明をきちんと書いてなかったので補足。</p>
</div>
<div class="section">
<h3>bind</h3>
<p>deferのthisが、引数に与えた関数すべてのthisになる。</p>
<pre class="javascript">
defer.call(this, F1, F2, F3);
</pre>
<p>のように呼ぶことで、F1、F2、F3すべてに<code>bind(this)</code>（Prototype.js）するのと同じ効果が得られる。</p>
</div>
<div class="section">
<h3>wait（あるいはsleep、pause）</h3>
<p>1秒のwaitを置く例。</p>
<pre class="javascript">
defer(function(next){
    alert(&quot;1000ms wait&quot;);
    window.setTimeout(function(){ next(&quot;finished&quot;); }, 1000);
}, function(next, str){
    alert(str); // -&gt; (alert &quot;finished&quot;)
});
</pre>
<p>deferもnextも、いくつでも引数を取れる。</p>
<p>nextに与えた第n引数は次の関数の第n+1引数になる。</p>
<p>第1引数はnext（次の関数を呼ぶ関数）で固定。</p>
<p>各関数の返り値は意味を持たない。defer自身も値を返さない。</p>
<p>setTimeoutの代わりに(GM_)XMLHttpRequestを入れれば、onloadが呼ばれるまで次の関数の実行を遅延できる。</p>
</div>
<div class="section">
<h3>loop</h3>
<pre class="javascript">
defer(function loop(next, i){
    i = i || 0;
    if (!(i &lt; 5)) return next();
    console.log(&quot;count &quot; + i);
    window.setTimeout(function(){ loop(next, i+1); }, 1000);
}, function(next){
    console.log(&quot;5 times loop finished&quot;);
});
</pre>
<pre>
count 0
count 1
count 2
count 3
count 4
5 times loop finished
</pre>
<p>nextをきちんと引き継げばloopもできる。</p>
<p>setTimeoutに与えた関数の中ではarguments.calleeが使えないので、ループさせる関数にloopという名前をつけ、それを使う。</p>
<p>前述の<code>defer.call</code>でthisをbindしている場合は、それに合わせてloopにthisをセットする必要がある。</p>
<pre class="javascript">
defer(function(next){
    next(0);
}, function loop(next, i){
    if (!(i &lt; 5)) return next();
    console.log(&quot;count &quot; + i);
    window.setTimeout(function(){ loop(next, i+1); }, 1000);
}, function(next){
    console.log(&quot;5 times loop finished&quot;);
});
</pre>
<p>毎回<code>i = i || 0;</code>を実行するのが無駄に感じる場合はこうする。</p>
<p>同様にして、特定の条件を満たすまで次の関数の実行を引き伸ばしたりできる。</p>
</div>
<div class="section">
<h3>parallel</h3>
<pre class="javascript">
defer(function(next){
    var obj = {},
        stock = function(key, value){
            obj[key] = value;
            // 全部揃ったらnextを呼ぶ
            if (obj.a &amp;&amp; obj.b &amp;&amp; obj.c) next(obj.a, obj.b, obj.c);
        };
    window.setTimeout(function(){ stock(&quot;a&quot;, &quot;AAAAA&quot;); }, 3000);
    window.setTimeout(function(){ stock(&quot;b&quot;, &quot;BBBBB&quot;); }, 2000);
    window.setTimeout(function(){ stock(&quot;c&quot;, &quot;CCCCC&quot;); }, 5000);
}, function(next, a, b, c){
    alert(a + b + c); // (alert &quot;AAAAABBBBBCCCCC&quot;)
});
</pre>
<p>setTimeoutの代わりに、(GM_)XMLHttpRequestなどが入る。</p>
<p>objそのものを引き渡しても良い。</p>
</div>

			]]></description>
			<category>個人的メモ</category><category>JavaScript</category>			<pubDate>Mon, 18 Aug 2008 21:43:00 +0900</pubDate>
		</item>
				<item>
			<title>「ads-display-none」というデータベースをwedataに作った</title>
			<link>http://mayokara.info/note/view/324</link>
			<guid isPermaLink="true">http://mayokara.info/note/view/324</guid>
			<description><![CDATA[
<div class="section">
<p><a href="http://wedata.net/databases/ads-display-none/items">アイテム - データベース: ads-display-none - wedata</a></p>
<p><a href="http://mayokara.info/misc/ads-display-none/">ads-display-none</a></p>
<p>御察し下さい。</p>
<br />
<p>どなたでも自由に編集していただいて構いませんが、データベース名の頭3文字を良くお読みになった上、余計なものが含まれないようお願いします。</p>
<p>ブログパーツや単なるサイドバー、フッターなどは対象外です。</p>
</div>

			]]></description>
			<category>個人的メモ</category><category>Toys</category>			<pubDate>Wed, 13 Aug 2008 17:02:00 +0900</pubDate>
		</item>
			</channel>
</rss>