Tuesday 21 April 2015

在 blogger 让代码 highlight

[ 2016 May 25 更新] 最新必须改成 <script src="https://cdn.rawgit.com/google/code-prettify/master/loader/run_prettify.js?lang=bsh&amp;skin=sunburst"></script> 才能用。

步骤:

1. 点进 New post 后, 选 HTML tab, 然后把下面这行置顶。

<script src="https://google-code-prettify.googlecode.com/svn/loader/run_prettify.js?lang=bash&skin=sunburst"></script>

2. paste 你的代码。 例子: echo -e "hello, world\n"

3. 然后把 <pre class="prettyprint"> 放在代码的前面

4. 然后把 </pre>放在代码的后面。


5. 去 Preview 就看得见代码 highlight了.
更多详情可以看这边 https://code.google.com/p/google-code-prettify/wiki/GettingStarted

然后就搞掂了, 故事很短有点无聊, 所以就讲下小白的故事凑下版面。
 
刚开始弄的时候,小白有时弄来弄去都有问题。不是字体变小,就是放了却看不到东西出来。

小白心里是这么认为, 只要能 paste 就可以了,管它是在 Compose 还是 HTML tab。

这就是问题所在咯,HTML tab 是读 HTML 代码的, 写 <table>... 代码是为了让读者看见一个表格。读者不会看见 <table>... 这些字眼。

比如在 HTML tab 那里输入

<table border="1"><tr><td><b>我是</b></td><td><b>小白</b></td></tr></table>


 ,读者打开 blog 看到的是加工后的表格


Compose tab 是写让读者直接看见的文章, 图片。如果你在 Compose 那里输入

<table border="1"><tr><td><b>我是</b></td><td><b>小白</b></td></tr></table>

读者打开你的 blog 看见的就不是 HTML 表格, 而是完整的纯文字。


但是纯文字不代表说跟 HTML 没有瓜葛, 其实那个纯文字已经暗地里, 自动转去 html 的哟,如果去 HTML tab, 就会看见转换 liao 的字眼:

&lt;table border="1"&gt;&lt;tr&gt;&lt;td&gt;&lt;b&gt;我是&lt;/b&gt;&lt;/td&gt;&lt;td&gt;&lt;b&gt;小白&lt;/b&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
对比一下, &lt; 就是相对应着 < , &gt; 就是相对应着 >, 还有一个是 &amp; 相对应着 &

lt 就是 less than (小过)的缩写, gt 就是 greater than(大过) 的缩写。

转换后, 显示你的 blog 时, web browser 才能区分内容的哪一个部分需要 html 加工(<>) , 哪一个部分是纯文字处理 (&lt; &gt;)。

< 转换成 &lt; 的行为我们称它为 "escape"


所以, 现在讲回开头的步骤,步骤二:

2. paste 你的代码。 例子: echo -e "hello, world\n"

步骤一,三,四 不是纯文字, 不需要 escape, 因为我们不是要让读者看见 <pre class="prettyprint"> 这行字,而是 html 加工用的。

只有步骤二,是要让读者看见 echo -e "hello, world\n" 这行纯文字。所以必须 escape 处理。

如果是在 Compose tab 写,系统就会用纯文字处理的手法,暗地里自动 escape 你的内容。
如果是在 HTML tab 写,内容本身就是 html 了,所以不会帮你 escape。

所以步骤二少讲了一些东西:
方法一. 如果你要在 Compose tab 写纯文字, 就不需要自己手动 escape 。&, < 和 > 可以直接使用。
方法二. 如果你要在 HTML tab 写纯文字, 就要自己手动 escape 。把 &, < 和 > 字眼转换成 &amp;, &lt;, 和 &gt;。当然不一定要手动,有很多网站提供 escape  的服务, 比如 http://accessify.com/tools-and-wizards/developer-tools/quick-escape/default.php

可能小白会说, 方法一很好阿,不用自己 escape, 干脆就在 Compose tab 粘贴代码好了。

忽略了一个问题。

在 Compose tab 看得见 html <> 那些内容吗 ? 当然看不见。

上面的截图是 Compose tab里头, 直接行列之间 按 Enter , 中间就空了很多行,

可是实际上,在 HTML tab 的另一边厢, 已经变得惨不忍睹

什么原因呢, 让我们做个实验, 在 Compose tab 那里中间空位加一个 g

我们再去 HTML tab 看:

发现了,g 就在 <pre ... 第三行,夹在 &nbsp 和 <pre> 的中间。

要知道, <pre> 和 </pre> 是 html 加工的开关 tags。 却在中间加入纯文字,bogger 又希望 <pre></pre>在同一条 line。你在 Compose 里头按 Enter 就会越按越多 html tags。

可以想象得到, 如果把要 highlight 的代码加进去 html tags 里头, 系统就会帮你乱乱 escape,然后就会看不见某个内容, 或者多了很多空行, 字体变小, 各种奇怪的情况让小白们抓头。


懂了这个原理,要在 Compose tab 准确放纯文字代码是可以的。那就是 "放边界记号"

首先,在 HTML tab 里头,Enter 拉开 <pre class="prettyprint"> </pre>, 在中间写上 s 和 g 记号。



然后去 Compose tab 那里就看见


把代码 paste 去 s和 g 之间。记得要紧贴 s的后面光标

正确示范:


错误示范(请用 ctrl+u undo paste 的步骤,不要直接用 backspace 改):


回到 HTML tab, 看到代码完美的夹在 s 和 g 之间, 而且也正确 escape 了。


在这里, 把 s和 g  删掉。

看结果:

如果要换代码,就先在 HTML tab 丢掉(不是在 Compose tab 那里删哟, 你看不见要删的 html tags 边界),再跟着上面的 s g 步骤即可。

下次 edit 的地方要小心上下有没有重要的 html tags。如果只是 <br /> 那些分行 tags 就不用担心。

学会了这个, 小白们就不会把自己的 blog 越 edit 越乱, 飞来飞去了。


Sunday 12 April 2015

在 fedora 21 自制谷歌翻译




【代码更新】 2015-10-31
1. 不再 recompile lex.yy 防止 delay。
2. mpg123 加 client=t 以及 tk=1|0,用 curl 加 UA, 才能跑。

【代码更新】 ?? (有点忙, 得空才 fix)

1. bug:dash 号开头就没有 dialog pop up, 虽然声音有。

【代码更新】 2015 april 19
1. 支持连续的特别字符会比较容易辨识。显示非跨线的 dash(也要小心 ab-\nc-d bug)。
2. 用 text 来取代之前的 html, 要知道区分 <b> 是内容还是 tag 是不可能的任务(即使 compare 之前的 source, 但是如果是语言转换后就不准了)。开头结尾不再有多余的 ""
3. 解决 one way replace (上面错的, 下面对的):

4. notify-send 有时会 truncate, 所以必须让它正确地显示 \\ 和 \n 诸如之类的。
5. silent 掉 curl 和 kill
6. 先 detect 有没有用到的 commands, 没有就用 xmessage 显示信息(notify-send 可能没有, 所以用 x 的内置 xmessage)
7.  bug fixed, [ ]+ only works when dealt with -E, so choose 1 style, i.e. <SPACE><SPACE>* over -E []+ bcoz the former always works regardless of -E
8.  bug fixed, $pre_fold forgot to quotes before pass to fold, and * expand to list files and dir names

【代码更新】 2015 april 15
1. 能够显示/翻译特别字符。 并且规定特别字符至多只能连续一个字(太占位子了,比如说 a is ????? apple) 。(april 19 支持连续)

2. 支持 ecc。

3. bug fixed, dash 的跨 line bugs, 还有更好地优先处理 dash。 ab-\nc-d 只能保留 c-d
4. bug fixed, 中文去英文的 html tag 以及 中文去英文的 F3 speak english bugs。

制作步骤:

1. 把下面的代码 save as 文件, e.g. seltr (纠正: 不是 .sh, 如果你想换别的名(我这个名字 seltr 的含义是 selECTION trANSLATE), 记得把代码的名字, "/usr/bin/seltr" 以及 "Usage: seltr " 改掉。)
2. sudo chmod 777 那个文件, e.g. `sudo chmod 777 seltr`
3. sudo mv 去 /usr/bin/ directory 那里, e.g. `sudo mv seltr /usr/bin/`
4. `gnome-control-center keyboard` 打开, -> "Shortcuts" Tab -> "Custom Shortcuts"
5. 在那里制作三个 command 捷径, 分别是:
(a)
Name: translate english to chinese and speak english
Command: seltr --ece
Accelerator: F1

(b)
Name: translate chinese to english and speak chinese
Command: seltr --cec
Accelerator: F2

(c)
Name: translate chinese to english and speak english
Command: seltr --cee
Accelerator: F3

(d)
Name: translate english to chinese and speak chinese
Command: seltr --ecc
Accelerator: F4



6. 酱就完成了。现在只需要用滑鼠 highlight/选你要翻译的文字范围, 按F1 或 F2 或 F3 或 F4, 下方就会 pop up 翻译结果, 并且发出相对的声音 :)

FAQ:
Q. 做么不用 stardict ?
A: 我最近有点 beh than stardict 的发音。不是不准确就是 quality 不好。 有时 pop up 太过 sensitive 了。而且最新版本的也无法使用 Google Translate, 我用 strace 检测发现它没有 follow HTTP 301 redirection 是主要原因。

Q: Where's the notification dialogue goes after multiple dialogue overlay ?
A: Super+m key to trigger messages menu tray,click gear icon to "Clear Messages" 就能清除全部累积的翻译 dialogues。

Q: 电脑没有 /usr/share/icons/hicolor/scalable/apps/im-google-talk.svg 这个 icon
A: 改成别的路径。不过看不见 error, 所以不重要。

Q: 优点/缺点
A: 优点是声音比较好听,只需要 highlight 一次,那个字就会在 buffer 里头, 此时不需要再 highlight, 再按 F1/F2/F3/F4 就能重复翻译/发音。而且支持多 lines /跨 line 字眼。也会把冗长的 link 翻译成 URL。缺点是需要网络,新的 dialogue 无法直接 ganti 旧的 dialogue。要先关掉旧的 dialogue 才能看到新的。 而且我的代码没有 handle cache 来减少流量。

Q: 做么你的代码没有 comments?
A: 有, 而且夸张多, 所以就干脆弄干净放在 blog。而且有些 tricks 解释太多给 google 看到就见光死了。当然要留后路。

Q:  做么在编辑(vi/gedit)着的 seltr 有时会自动关掉  ?
A:  因为你按 F[1-4] 会启动代码里头 kill 掉其它的 seltr process

Q: 做么有时翻译到有空格,有时特别字符, 如 ! 又会不见掉。
A: 你问 google 拉,鬼懂它的 bug。

无论如何, 语言之间的转换,比如英文翻译到中文,有时不见或多了空格都是正常的。在这里提醒一下,web browser 会先翻译 suggestion, 所以要再选 "Translate instead from"。


Q: 网上有条水用 iconv, awk, html2text 代码
A: 如果只比较关键的 curl, 我不但要考虑把结果 pass 去 mpg123(所以不能依赖 curl 的 --data-urlencode), 而且我用的 url 也不同(我知道有5种不同的 api, 实际数目当然不止)。那条水的 response 是包括大量的 html/js/css tag, 真的是名副其实的 web scraping, 很容易 broken。 最后,真的只依赖 html2text 就收工过年 ? 看下面的例子,google 那里是 source, notify-send 是我的, terminal 是那条水的, 仔细看 terminal 的 &quot; 和 &amp; bug。



Tips:
1. highlight 英文就要使用 F1/F4,highlight 中文就 F2/F3

2. 请先检查电脑有 xmessage, curl, xsel, mpg123, sed, fold, notify-send, pkill 这些 commands。

3. 我的平台 Fedora 21 gnome 3, 没在 Ubuntu 其它 platforms 测试。

4. 如果想中途 stop 掉很长的发声, 只需要选其它的很短的字体来翻译, 就可以ganti 掉了。当然别忘了得空清理下 Super+m 的 messages。

5. 发音没有用 https, 所以别手痒翻译密码哟 :p

代码:


#!/usr/bin/env bash
#Author: <limkokhole@facebook.com>
notify_icon='/usr/share/icons/hicolor/scalable/apps/im-google-talk.svg'

<<update_2015_april_20
1. xmessage use LANG=POSIX instead of LC_ALL
2. check curl return code and show xmessage for relevant error
3. use || and == instead of && and != for more intuitive
4. todo: avoid kill vi/gedit /usr/bin/seltr
update_2015_april_20

if [[ "$@" == "--ece" ]]; then
 text_sl='en'
 text_tl='zh-CN'
 ao_tl='en'
elif [[ "$@" == "--cec" ]]; then
 text_sl='zh-CN'
 text_tl='en'
 ao_tl='zh-CN'
elif [[ "$@" == "--cee" ]]; then
 text_sl='zh-CN'
 text_tl='en'
 ao_tl='en'
elif [[ "$@" == "--ecc" ]]; then
 text_sl='en'
 text_tl='zh-CN'
 ao_tl='zh-CN'
else
        echo -e 'Usage: seltr --[ece|cec|cee|ecc]
\n In which:
 ece means translate english to chinese but speak english
 cec means translate chinese to english but speak chinese
 cee means translate chinese to english but speak english
 ecc means translate english to chinese but speak chinese
'
        exit 1
fi

for cmd in "xsel" "mktemp" "cc" "lex" "curl" "mpg123" "sed" "fold" "notify-send" "pkill" "kill" "pgrep" "grep"; do
    command -v $cmd >/dev/null 2>&1 || {  LANG=POSIX; xmessage "Require $cmd but it's not installed.  Aborting." >&2; exit 1; }; :;
done

one_way_replace() {
  if [ ! -f /tmp/lex.yy ]; then
  #local dir=$(mktemp -d)
  ( #cd "$dir"
    echo 1 >> /tmp/lala
    { printf %s\\n "%option 8bit noyywrap nounput" "%%"
      printf '"%s" {fputs("%s", yyout);}\n' "${@//\"/\\\"}"
      printf %s\\n "%%" "int main(int argc, char** argv) { return yylex(); }"
    } | lex && cc lex.yy.c -o /tmp/lex.yy
  ) && /tmp/lex.yy
  else
      /tmp/lex.yy
  fi
  #rm -fR "$dir"
}

pre_mysed="$(xsel -o | sed ':a;N;$!ba;s/\xe2\x80\x90 *\n//g;s/\x2d *\n//g' | sed -E "s/[^ ]*http[s]?\:\/\/[^ ]*|[^ ]*www\.[^ ]*/URL/g;s/[^ ]*\.com[^ ]*/URL/g;s/[^ ]*\.net[^ ]*/URL/g;" )"

enc() { sed -E "s/\%/%25/g;s/\"/%22/g;s/'/%27/g;s/\./%2e/g;s/\,/%2c/g;s/\?/%3F/g;s/[\x5b]/%5b/g;s/[\x5d]/%5d/g;s/\!/%21/g;s/\;/%3b/g;s/\(/%28/g;s/\)/%29/g;s/\{/%7b/g;s/\}/%7d/g;s/\\\$/%24/g;s/\@/%40/g;s/\#/%23/g;s/\+/%2b/g;s/=/%3d/g;s/</%3c/g;s/>/%3e/g;s|/|%2f|g;s|\\\|%5c|g;s/_/%5f/g;s/~/%7e/g;s/:/%3a/g;s/&/%26/g;s/\^/%5e/g;s/\`/%60/g;s/\*/%2a/g;s/  */%20/g"; }

mysed="$(echo "$pre_mysed" | enc)"

translated="$(curl -d "q=$mysed" --post301 --post302 -sLk -A 'Mozilla/5.0' 'https://translate.googleapis.com/translate_a/t?anno=2&client=te&format=text&key&v=1.0&scid=&logld=v26&sl='"$text_sl"'&tl='"$text_tl"'&tc=2&mode=1')"

status=$?
case $status in
    0):;;
    6)LANG=POSIX; xmessage "Couldn't resolve host." >&2; exit 1;;
    7)LANG=POSIX; xmessage "Failed to connect to host." >&2; exit 1;;
    *)LANG=POSIX; xmessage "Curl error $status, exiting." >&2; exit $status;
esac

translated="$(echo "${translated:1:-1}" | one_way_replace '\\\\' '\\' '\\u0026' '&' '\\u003c' '<' '\\u003e' '>' | sed 's/\\\x5c\x74\x20/ /g;s/  */ /g')"

notif_txt="$(echo "$translated" | sed -E 's|\\|\\\\|g;s|\\"|"|g;s|\\n|\n|g;')"; notify-send -i "$notify_icon" -u critical " " "$notif_txt"

kill $(pgrep -f "/usr/bin/seltr" | grep -v ^$$\$) 2>/dev/null
pkill mpg123

if [[ "$@" == "--cee" ]] || [[ "$@" == "--ecc" ]]; then
 pre_fold="$translated"
else
 pre_fold="$pre_mysed"
fi

echo "$pre_fold" |fold -s -100 | enc | 
 while read line; do
  curl -sLk -A 'Mozilla/5.0' "http://translate.google.com/translate_tts?ie=UTF-8&q=${line}&tl=${ao_tl}&client=t&tk=1|0" | mpg123 -
 done




截图:


网页上使用


terminal 上使用


在 pdf 上使用, 跨界也没问题


留意那些冗长的 link 都会转换去 URL 字眼


用 F2, 中文去英文, speak 中文