<?xml version='1.0' encoding='utf-8'?>
<!-- generator="bashblogger/0.3.7" -->
<rss version="2.0" 
        xmlns:content="http://purl.org/rss/1.0/modules/content/"
        xmlns:wfw="http://wellformedweb.org/CommentAPI/"
        xmlns:dc="http://purl.org/dc/elements/1.1/"
>

	<channel>
		<title>110碼:AAA2369</title>
		<link>http://kalug.linux.org.tw/~lloyd/bblog/</link>
		<description>echo Impossible|sed 's/Im/To be /'</description>
		<pubDate>Fri, 29 Dec 2017 11:09:52 CST</pubDate>
		<generator>Bash Blogger-0.3.7</generator>
		<language>zh_TW</language>
		<image>
			<url>http://kalug.linux.org.tw/~lloyd/bblog/img/rss-logo.jpg</url>
			<title>110碼:AAA2369</title>
			<link>http://kalug.linux.org.tw/~lloyd/bblog/</link>
			<width>88</width>
			<height>31</height>
		</image>
			<item>
		<title>Lisp Web - Parenscript Emacs Trident-mode slime skewer - HowTo</title>
		<link>http://kalug.linux.org.tw/~lloyd/bblog//archives/2017/12/29/lisp_web_-_parenscript_emacs_trident-mode_slime_skewer_-_howto/</link>
		<pubDate>Fri, 29 Dec 2017 10:56:46 CST</pubDate>
		<dc:creator>Lloyd Huang</dc:creator>
		<guid>http://kalug.linux.org.tw/~lloyd/bblog//archives/2017/12/29/lisp_web_-_parenscript_emacs_trident-mode_slime_skewer_-_howto/</guid>
		<category>Emacs</category>
<category>Common-Lisp</category>
		<enclosure url="http://kalug.linux.org.tw/~lloyd/bblog//podcasts/" length="" type="" />
		<description><![CDATA[ [...] ]]></description>
		<content:encoded><![CDATA[

<div class="section" id="&quot;&quot;lisp-web-parenscript-emacs-trident-mode-slime-skewer-howto">

<p>想用 Lisp 寫 web ，如果是全端工程師，前後台都包的話，Caveman2 + Parenscript 這樣的工作流程就很方便。但要與他人合作的話，而且要切進個別案子或是即有的工作流程那就有點點尷尬了。Team 的後台主力開發工具是 node.js ，前台是 angular 或 react ，所以協同開發輸出 JS 變成是必要的。</p>
<p>將 Parenscript 轉成 JS 的工具不少，自已也寫了一個簡單的版本，實作上不難。 github 上就有好幾個像是 <a class="reference external" href="https://github.com/cmoore/pikey">pikey</a> <a class="reference external" href="https://github.com/burtonsamograd/sigil">sigil</a> <a class="reference external" href="https://github.com/josrr/lisp2js">lisp2js</a> ，就連 parenscript-react-examples 裏面都有個 <a class="reference external" href="https://github.com/l04m33/parenscript-react-examples/blob/master/ps-compile.lisp">ps-compile.lisp</a> 在處理 parenscript to JS，而在 npm 上也有 <a class="reference external" href="https://www.npmjs.com/package/sigil_">sigil_</a> 與 <a class="reference external" href="https://www.npmjs.com/package/sigil-cli">sigil-cli</a> ，估計大家都有這樣的需求。</p>
<div class="section" id="&quot;&quot;trident-mode">
<h3>Trident-mode</h3>
<p>Emacs 上有個 <a class="reference external" href="https://github.com/johnmastro/trident-mode.el">Trident-mode</a> 搭配 <a class="reference external" href="https://common-lisp.net/project/slime/">slime</a> 可以作到同樣的效果。更特別的是它可以配合 <a class="reference external" href="https://github.com/skeeto/skewer-mode">skewer-mode</a> + simple-httpd + browser (firefox/chrome)，直接把轉譯好的 JS 送到 browser 端執行，達到 REPL 的效果。</p>
<p>大概的關係圖如下：</p>
<pre class="literal-block">
                      /+-- slime                    &lt;--&gt; SBCL Lisp (in-package :parenscript)
Emacs (Trident-mode) /
                     \
                      \+-- (skewer + simple-httpd)  &lt;--&gt; Browser (firefox/chrome open http://localhost:8080/skewer.html)

[Trident] Paren -&gt; Paren [slime|SBCL|Parenscript] JS -&gt; [Trident] JS -&gt; [skewer|simple-httpd|browser] eval(JS)
</pre>
<div class="section" id="&quot;&quot;trident-mode-install-setup">
<h4>Trident-mode Install &amp; Setup</h4>
<p>請參照 <a class="reference external" href="https://github.com/johnmastro/trident-mode.el/blob/master/README.org">https://github.com/johnmastro/trident-mode.el/blob/master/README.org</a> 幾乎可以無痛完成。</p>
</div>
<div class="section" id="&quot;&quot;">
<h4>測試</h4>
<ul class="simple">
<li>用 emacs 打開檔案 test.paren (進入 trident-mode)</li>
<li>在 emacs 編輯區下輸入 (lisp *ps-lisp-library*)</li>
<li>在 emacs 下鍵入 Mx trident-expand-sexp RET</li>
</ul>
<pre class="literal-block">
$&gt; emacs test.paren

(lisp *ps-lisp-library*)

M-x trident-expand-sexp
</pre>
<img alt="emacs-trident-mode" class="align-center" src="/~lloyd/bblog/img/emacs-trident-mode.png" />
<p>如果執行有錯，請確認 slime 上目前是處於 PS&gt;</p>
<img alt="emacs-slime-ps" class="align-center" src="/~lloyd/bblog/img/emacs-slime-ps.png" />
</div>
<div class="section" id="&quot;&quot;emacs-after-save-hook-trident-compile-buffer-to-file">
<h4>emacs after-save-hook trident-compile-buffer-to-file</h4>
<p>另一個方便的設定則是透過 after-save-hook 在每次存檔時喚起 trident-compile-buffer-to-file 將 paren 轉成 JS。在每個 paren 的檔尾加上設定如下：</p>
<pre class="literal-block">
;; Local Variables:
;; eval: (add-hook 'after-save-hook (lambda () (trident-compile-buffer-to-file)) nil t)
;; End:
</pre>
</div>
</div>
<div class="section" id="&quot;&quot;skewer-live-web-development-with-emacs">
<h3>Skewer live web development with Emacs</h3>
<p>skewer-mode 是個方便開發 Web front end 工具，可以把 js, css, html 注入 browser 中，由 browser 來解譯與呈現。</p>
<ul class="simple">
<li>Watch the <a class="reference external" href="http://youtu.be/4tyTgyzUJqM">demo video on YouTube</a> (webm)</li>
</ul>
<div class="section" id="&quot;&quot;skewer-mode-install-setup">
<h4>skewer-mode Install &amp; Setup</h4>
<ul>
<li><p class="first">透過 MELPA 安裝 simple-httpd js2-mode 及 skewer-mode</p>
</li>
<li><p class="first">設定好 simple-httpd httpd-root</p>
<pre class="code common-lisp literal-block">
<span class="punctuation">(</span><span class="name builtin">require</span> <span class="literal string symbol">'simple-httpd</span><span class="punctuation">)</span>
<span class="comment single">;; set root folder for httpd server</span>
<span class="punctuation">(</span><span class="keyword">setq</span> <span class="name variable">httpd-root</span> <span class="literal string">&quot;~/public_html&quot;</span><span class="punctuation">)</span>

<span class="comment single">;; chrome open http://127.0.0.1:8080/skewer.html</span>
<span class="punctuation">(</span><span class="name variable">httpd-start</span><span class="punctuation">)</span>
</pre>
</li>
<li><p class="first">設定 skewer mode</p>
<pre class="code common-lisp literal-block">
<span class="punctuation">(</span><span class="name variable">add-hook</span> <span class="literal string symbol">'js2-mode-hook</span> <span class="literal string symbol">'skewer-mode</span><span class="punctuation">)</span>
<span class="punctuation">(</span><span class="name variable">add-hook</span> <span class="literal string symbol">'css-mode-hook</span> <span class="literal string symbol">'skewer-css-mode</span><span class="punctuation">)</span>
<span class="punctuation">(</span><span class="name variable">add-hook</span> <span class="literal string symbol">'html-mode-hook</span> <span class="literal string symbol">'skewer-html-mode</span><span class="punctuation">)</span>
</pre>
</li>
<li><p class="first">建立文件 ~/public-html/skewer.html 提供給 browser 載入 skewer</p>
<pre class="code html literal-block">
<span class="comment preproc">&lt;!doctype html&gt;</span>
<span class="punctuation">&lt;</span><span class="name tag">html</span><span class="punctuation">&gt;</span>
<span class="punctuation">&lt;</span><span class="name tag">head</span><span class="punctuation">&gt;</span>
    <span class="comment">&lt;!-- Include skewer.js as a script --&gt;</span>
    <span class="punctuation">&lt;</span><span class="name tag">script</span> <span class="name attribute">src</span><span class="operator">=</span><span class="literal string">&quot;http://localhost:8080/skewer&quot;</span><span class="punctuation">&gt;&lt;/</span><span class="name tag">script</span><span class="punctuation">&gt;</span>
    <span class="comment">&lt;!-- Testing.js for testing or mark it and skip. --&gt;</span>
    <span class="punctuation">&lt;</span><span class="name tag">script</span> <span class="name attribute">src</span><span class="operator">=</span><span class="literal string">&quot;testing.js&quot;</span><span class="punctuation">&gt;&lt;/</span><span class="name tag">script</span><span class="punctuation">&gt;</span>
<span class="punctuation">&lt;/</span><span class="name tag">head</span><span class="punctuation">&gt;</span>
<span class="punctuation">&lt;</span><span class="name tag">body</span><span class="punctuation">&gt;</span>
    <span class="punctuation">&lt;</span><span class="name tag">p</span><span class="punctuation">&gt;</span>Hello world skewer<span class="punctuation">&lt;/</span><span class="name tag">p</span><span class="punctuation">&gt;</span>
<span class="punctuation">&lt;/</span><span class="name tag">body</span><span class="punctuation">&gt;</span>
<span class="punctuation">&lt;/</span><span class="name tag">html</span><span class="punctuation">&gt;</span>
</pre>
</li>
<li><p class="first">browser 開啟 <a class="reference external" href="http://localhost:8080/skewer.html">http://localhost:8080/skewer.html</a></p>
</li>
<li><p class="first">emacs M-x skewer-repl 進入交談介面，測試看看。</p>
</li>
</ul>
</div>
</div>
<div class="section" id="&quot;&quot;'id'3">
<h3>小結</h3>
<p>emacs + trident-mode + skewer-mode 提供一個與 browser 互動 REPL 的交談介面。單用 trident-mode 幫忙將 Parenscript 轉成 JS 就非常實用了。</p>
<p>與 Team 的合作模式，則是自已寫用 Parenscript ，提交到 git 跟 Team 合作仍然使用 JS 溝通。</p>
</div>
</div>
</div>
</body>
</html>]]></content:encoded>
	</item>
	</channel>
</rss>
