乱入 crx 手册!

好吧,这是有关如何在 42 分钟之内超高速上手 crx 插件开发的一个不怎么靠谱的手册;-)

章节索引

0: 为毛要入?!

先得声明,要想真正在 42 分钟 内进入 crx 玩起来,不是没有前提的,,,

至少:

  • 42 岁 ?! 那还能有好奇心,绝对是人类精品,肯定冇问题了!
  • 42 个月, Linux/Unix 系统使用~注意!是使用不是管理体验;不然各种标准的命令行操作要死人的,,
  • 42 周的, 编程体验,不许什么語言,就是 JS 也成,起码要有一丝码感,,,
  • 42 次的, 蕃茄工作时间 的经历,至少知道什么是” 心流 “般的专注!
  • 42 天的, 相关资料通读,相关社区的加入/旁听,,,一定要摸清楚相关主要开发人员的沟通习惯 ;-)
  • 42 小时, 的周边环境整备,熟悉工作系统以及配置好顺手的工具(git/apt/yum/brew ...)

然后,还是想继续这遭没谱乱入的话 ;-)

Warning

  • 走起!

See also

暗示

JS预备

一切开始前,先必须 相信 !

相信 Chromium

嗯嗯嗯?! crx 是什么? 为毛俺要学习开发这货?

  • 先看Fred Wilson从自己网站 AVC 的访问数据图表:
    • 2006年 bwar2006
    • 2012年 bwar2012

如此剧烈的变化,就在36个月完成了反复逆转!这就是!

  • chromelogo Chrome , 来自 Google 公司的神奇浏览器
  • 核心组件是来自 Apple 公司的 Safari 使用的 WebKit 开源HTML引擎, 以及 Google 独力研发的 V8- JavaScript 解析引擎
  • 其中 V8 被单独抽取出来,变成了 node.js 项目的核心 ~ 一种可以在服务器端运行 JavaScript 提供应用服务的应用框架
  • 更加牛叉的是 Chrome 虽然是 Google 的专用软件产品,但是从一开始就有对应的开源工程 chromiumlogo Chromium
  • 所有代码完全一致!
  • 因而,基于 Chromium 已经形成了一大批非官方发行版, 仅仅在中国就至少有5种发行版!
  • 进一步牛叉的是: 只要是基于 Chromium 代码发行的浏览器,都可以安装/使用 crx ~ 扩展程序!
  • 即,我们只要学会了 crx 的开发,那么我们的作品,基本上可以运行于占人数互联网中近一半用户的浏览器中!

所以,相信 Chromium 将在 浏览器战争 中保持不败! 只要掌握了 crx 的开发,就能进入浏览器扩展的主流市场!

相信JS

...

仅仅是因为以前的 DHTML 体验,就认定 JS 是前端的命! 基本很难相信了 - 不相信,那么任何乱入行为,都会被自个儿否决 - 那真心没招了,,, 说明, JavaScript 不是你的那份儿菜,甭忙了,继续 C++/JAVA/.NET 吧,,,

Warning

但是

  • 你选择了相信 JavaScript 的可能性,愿意体验这种前后合体式的业务开发形式 ?!
  • ~~~ 那么, go!

只要明确一些 JavaScript 的`基本形式` 80% 的实际编程就可以混进去了 !-) :

严正推荐: JavaScript - MDN - 组织良好的所有相关资料!

中文的推荐: - JavaScript 教程 - JavaScript 参考教程

基本语法
// 单行注释
/*
    多行
    注释
*/
var a="hollo"
var b= 1
b++   //  自增运算,此时 b 为2
b--   //  自减运算,此时 b 为1
var c = b+a //字串连接,连接数字会自动转换类型

if (1 != c){}   // 不等于
    console.log("Yes")
    // 不论前台还是后台开发,都不建议使用 alert() 进行调试输出了,,
}else{
    console.log("No")
}

for (i = 1; i < 10; i++){
    console.log("hollo:"+i)
}
// 分类判定
switch (parseInt(score / 10)) {
  case 0:
  case 1:
  case 2:
  case 3:
  case 4:
  case 5:
    result = '不及格';
    break;
  case 6:
  case 7:
    result = '通过';
    break;
  case 8:
    result = '良好';
    break;
  case 9:
    result = '优秀';
    break;
  default:
    if (score == 100)
      result = '非常优秀';
    else
      result = '囧';
}

function d(e,f){
    return e*f
}
  • 基本数据

    • 数字,字串,布尔 基本和其它脚本语言类同
    • NaN, null ~ 空值
  • 全局方法

    • eval() ~ 将给入的字串,尝试执行
    • isFinite(),`isNaN()` 是否有限和空
    • parseInt(),`parseFloat()`,`toString()` 进行类型转换
    • escape(), unescape() 对 url 进行编码和相反,,
  • 基本对象

  • Number 数字
  • String 字串
  • Array 数组
  • Math 数学
  • Date 日期

各自包含一堆内置的各种常用处理操作.

然后,一般教程,会进行复杂的文档对象(Dom) 的说明,,, - 这是特指 html 文档对象的操作

+7分钟:初尝

先通过最简单的插件,整起来,直觉的体验 crx 扩展开发的宏观流程先!

  • 嗯嗯嗯,现在可以计时了:
00:00~安装

嗯嗯嗯,这个真心不用教了吧!

恭喜! 咱们已经获得了完整的 开发/调试/运行/部署 扩展的平台!

hello world

著名的 hello world 是一定要整的,,,

那么在 猎豹浏览器 进行 crx 开发,有个比官网更加简单的例子,

来自: 魔方飛Young 的 第一次做插件就献给了猎豹浏览器,一个简单的插件!(绝对原创) - 扩展插件区 - 猎豹浏览器官方论坛

声明

先开个目录,就叫: halloworldliebao

然后用任意文本编辑器,创立文件: manifest.json 内容如下

{
   "name": "Hallo World猎豹浏览器",
   "version": "1.0",
   "description": "魔方飛Young的第一个猎豹浏览器插件,还不错吧!",
   "browser_action": {
      "default_icon": "icon.gif",
      "popup": "popup.html"
   }
}
图标

再创建关键的:

_images/ch0-1-icon.gif

插图.0-1 扩展的图标

当然,从官网抽个 icon 也成

完成

好了准备工作完成! 正式开展编程!

  • 先通过 主菜单 -> 选项 -> 扩展程序 进入管理界面
_images/ch0-2-devmod.png

插图.0-2 打开”开发人员模式”

  • 打开 开发人员模式 后,才能见到开发相关的功能
  • 目前需要的只是: 载入正在开发的扩展程序
  • 然后就发觉,导航栏中,已经出现了刚刚扒到的图标,点击一下!?
_images/ch0-3-erro.png

插图.0-3 点击图标时报错

  • 嗯嗯嗯,出错了!
  • 不过,不用怕,仔细看,是找不到 popup.html 页面,就是在 manifest.json 中指定的弹出页面嘛!
  • 那么就地创建一个 popup.html 呗:
<p>Hello,World!</p>
<p><a href="http://www.liebao.cn/" target="_blank">猎豹官网</a>
<p><a href="http://bbs.liebao.cn" target="_blank">猎豹论坛</a>
<p><img src="liebao.jpg" /></p>
  • 然后, 点击 重新载入 ,让 猎豹浏览器 重新加载修订后的扩展
  • 再点击小豹子头?!
_images/ch0-4-done.png

插图.0-4 点击图标时报错

BINGO!

07:01 小结

不出意外的话, 7分钟 用在这个阶段,太足够了!

应该已经体验到 crx 开发核心爽直了?!

  • 只要具备 JavaScript 的编程经验,就可以进行任意扩展插件的开发了!
  • 而且, 扩展的具体运行性能在 V8 引擎以及 Chromium 卓越整合之下一点也不差!
  • 以及, 先要习惯,并建立起,依托 猎豹浏览器crx 扩展开发流程:
加载本地开发中的扩展目录
  `->修订页面
      ^ `-> 重新加载
      |   `-> 测试扩展
      |           |
      +-----------/

那么

要干点儿实事儿了!

仅仅以使用 crx 形式,包含 金山网址云安全开放API 为实例,完成一个能自动探查当前网址是否有钓鱼隐患的扩展!

那么,要解决的子问题有:
  • 怎么获得当前页面的 URL?
  • 怎么对字串进行 base64 ?
  • 怎么对字串进行 md5 ?
  • 怎么对字串进行合并 ?
  • 怎么在页面加载完成前,就向外部网站请求数据 ?
  • 怎么理解金山云返回的数据?
  • ...

1: 完成功能原型插件

好吧,想 C/C++/PHP/node.js/Python ... 切换到 crx ?!

  • 其实,真心简单,毕竟, crx 实在是仅仅依赖非常单纯的 JS 以及 HTML 脚本知识
  • 其实,任何开发语言的乱入,完全可以不管什么设计思想,开发模式之类的高级东西

所以,充满信心的:

Warning

  • 走起!

金山云安全整备

好的,俺想象的场景是: - 每当打开一个页面时 - 俺的 crx 就将当前页面的 URL 发送给 金山网址云 - 然后,根据返回的结论,决定,是否对页面进行刷红,并警告!

问题是看 金山云安全开放平台 的文档也是种挑战吼! 必须先研究一下!

简单的説

金山网址云 是个标准的接口服务

/phish/?q=[***]&appkey=[***]&timestamp=[***]&sign=[***]
       |   |            |                |          +- 数字签字
       |   |            |                |          生成忒复杂,详见见下文
       |   |            |                +- 距离1970.1.1零点的秒数
       |   |            |                   要求精确到小数点后3位
       |   |            +- 从金山云申請到的
       |   +- 对目标URL进行 urlsafe base64 编码得到的字串
       +- 使用?引导出参数列表
应用键(APPKEY): k-60666
安全码(SECRET):  99fc9fdbc6761f7d898ad25762407373
  • 那么,每次查询时,必须的 数字签字 是怎么生成的呢?
  • 先组成这样一个字串
/phish/?appkey=[APPKEY]&q=[***]&timestamp=[***][SECRET]
                  |         |               |   +- 安全码
                  |         |               +- 距离1970.1.1零点的秒数,精确到小数后3位
                  |         +- 对目标URL进行 urlsafe base64 编码得到的字串
                  +- 应用键值
  • 然后,将此字串进行 MD5 计算! 得到的字串就是 数字签名

  • 最后将整个 URL 拼到 http://open.pc120.com 后,直接访问,就可以获得 JSON 格式的回答

  • 如果回答形如:

    {"success": 1, "phish ": 3}
    
  • 说明们成功了! 是否钓鱼网站参考:

类型表
phish状态代号 含义
-1 未知
0 非钓鱼
1 钓鱼
2 网站高风险,有钓鱼嫌疑

齐活儿! 这么大篇的技术文档,看穿了其实就以上这么点儿东西;-o

但是,怎么折腾成一个可用的 crx 呢?!

Warning

  • 走起!

+20分钟:突入 elf

google 真心好朋友,通过搜索可以获得很多已经用上 crx 的先驱们的各种代码片段

只要使用 改.js->测试 流程,结合以往的开发经验,驗证猜想,突进就好!

  • 嗯嗯嗯,现在可以计时了:
07:05~ 确认阵地

凡事儿,预则立,不预则废物!

所以,出师要有名,得先有个名字! 嗯,结合想作的,以及依托的 金山云安全开放平台

就叫 elf - elf lockup phishing - 钓鱼欺诈锁死精灵

manifest.json

同前,创建新目录 elf 先来配置 :

{"name": "elf for Chrome"
    ,"version": "1.0"
    ,"description": "金山网络云安全钓鱼网址监察精灵!Alert for urls which is one kinds of Pishing."
    ,"background_page": "background.html"
    ,"page_action" :{
        "default_icon" : "icon-19.png"
        ,"default_title" : "Here's a Pishing URL!"
        }
    ,"permissions" : [
        "tabs"
        , "notifications"
        , "http://*/*"
        ]
    ,"icons" : {
        "19" : "icon-19.png"
        ,"48" : "icon-48.png"
        ,"64" : "icon-64.png"
        ,"128" : "icon-128.png"
        }
}

这里有几个不同的声明了: - background_page ~ 因为 elf 是全自动运行的插件,没有用户交互,不用弹出提示,所以,指定一个作为服务器在默默运行的页面就好 - permissions ~ 这是因为 crx 能力太大了,几乎可以控制一切,所以,从内核就进行了全面的控制,一个扩展,想作什么,应该向内核进行备报,超过声明范畴的行为,将一概被无视! - icons ~ 因为随着扩展出现的位置不同,应该提供不同规格的图标,以便内核使用,以免强行缩放效果不美

background.html
<!DOCTYPE html>
<html>
  <head>
<script type="text/javascript" src="md5.js"></script>
<script type="text/javascript" src="kcpish.js"></script>

<script>

// Listen for any changes to the URL of any tab.
chrome.tabs.onUpdated.addListener(checkForValidUrl);

/* Changelog::
    - 111020 优化代码,清除不必要的尝试;输出有意义的日志到 console.log()
    - 110516 完成可用原型
    - 110512 创建
*/
    </script>
  </head>
</html>

哈! 这是技巧,也是习惯!

_images/ch1-1-devtools.png

插图.1-1 使用开发工具进行编程

  • 内置的编辑器,其实只是个基本的编辑器,并没有自个儿平时用惯的各种专业编辑器好用
_images/ch1-2-editor.png

插图.1-2 喜欢的编辑环境

  • 所以,将所有脚本使用外部引用,就可以使用喜欢的编辑器进行欢乐的撰写了!
  • chrome.tabs.onUpdated.addListener() 就是抄手册来的函式,就一个作用
    • 每当用户打开一个新的 TAB 时
    • 调用自定的 checkForValidUrl 函式!

那么 checkForValidUrl 具体什么样?

kcpish.js
/*
    base http://code.ijinshan.com/api/devmore4.html
    check URL base Kingsoft Cloud API for URI antiPishing
*/
var APPKEY = "k-60666"
var SECRET = "99fc9fdbc6761f7d898ad25762407373"
var ASKHOST = "http://open.pc120.com"
var ASKTYPE = "/phish/?"

// Called when the url of a tab changes.
function checkForValidUrl(tabId, changeInfo, tab) {
    // If the letter 'g' is found in the tab's URL...
    //console.log(tab.url)
    if ("loading"==tab.status) {
        var crtURI = window.btoa (tab.url)
        //console.log(crtURI)
        var timestamp = Date.parse(new Date())/1000+".512"
        //console.log(timestamp)
        var signbase = ASKTYPE+"appkey="+APPKEY+"&q="+crtURI+"&timestamp="+ timestamp
        var sign = hex_md5(signbase+SECRET)
        //console.log(sign)
        var askuri = ASKHOST+signbase+"&sign="+sign
        //console.log(askuri)
        checKcPishing(askuri,tabId)
    }
}

function checKcPishing(URI,tabId) {
    //console.log(URI)
    var req = new XMLHttpRequest()
    req.open("GET"
        ,URI
        ,true)
    req.onreadystatechange = function() {
    if (req.readyState == 4) {
        // JSON.parse does not evaluate the attacker's scripts.
        var resp = JSON.parse(req.responseText)
        //console.log(req.responseText)
        if(1==resp.phish){
            chrome.pageAction.show(tabId)
            showAlertMsg()
            }
        }
    }
    req.send(null)
}

/*
 * A JavaScript implementation of the Pishing check base
 * http://code.ijinshan.com/api/devmore4.html
 * Version 1.1 Copyright (C) ijinshan.com 2010-2011
 * Distributed under the Apache License v2
 * See http://elffic.bitbucket.org/ for more info.
 */

/* Usgae chrome.tabs.executeScript recovered crt page:
*/
function showAlertMsg() {
    msg ="<h1>Alert!报警!</h1>\
        <h2>由<a href=http://code.ijinshan.com/api/devmore4.html>金山云安全网址查询</a>得知</h2>\
        <h2>当前地址包含严重的钓鱼隐患!</h2>\
        <h3>已由elf 插件自动屏蔽内容 请尝试其它同类网站...</h3>\
        <h4>详细参考: <a href=https://bitbucket.org/elffic/elf/wiki/Home>https://bitbucket.org/elffic/elf/wiki/Home</a></h4>\
        "
    chrome.tabs.executeScript(null,
               {code:"document.body.style.backgroundColor='red'"})
    chrome.tabs.executeScript(null,
               {code:"document.body.innerHTML='"+msg+"'"})
}
  • 不到60行齐活儿?!
  • chrome.tabs.onUpdated.addListener() 感应用户操作,有合适的行为就調 checkForValidUrl()
  • checkForValidUrl 组织好查询链接,调 checKcPishing 查询远端的 金山云
  • 如果有问题,用户打开的网址,就调 showAlertMsg 刷屏,输出警告!
调试

不得不推荐国人经验: chrome developer tool 调试技巧 - TaobaoUED

  • 其中最核心的日常最常用的调试技巧,其实就是使用日志打印!
  • 当然,因为 crx 的页面服务器式运行形式,不能使用以往的 alert() 函式打印成警告窗口了
  • 所以,有 console.log()
  • 注意到代码中大量的被注释了的 console.log() 吧?
  • 那都是一点点确认代码无误后才清除的
  • 想知道开发时的调试情景?
_images/ch1-3-console.png

插图.1-3 使用开发工具窗口里的控制台来实时观察扩展的运行情景

搞掂?!

checkForValidUrl()

JS 真心 碉堡 了! 所有最常见的操作都内置了!

  • 字串的 base64 编码?! window.btoa

  • 对外请求,果然是`XMLHttpRequest`

  • 实际数据的接收使用 req.onreadystatechange 进行监控

  • 数据体直接解析: JSON.parse(req.responseText)

  • 当前时间戮只能先模拟小数点后的: Date.parse(new Date())/1000+”.512”

  • 字串的 md5 编码: hex_md5()

    • 不过,这个,真心要使用外部模块
    • 是那个 <script type=”text/javascript” src=”md5.js”>
    • 看其中的注释,感动哪,好人多哪!
/*
 * A JavaScript implementation of the RSA Data Security, Inc. MD5 Message
 * Digest Algorithm, as defined in RFC 1321.
 * Version 2.2 Copyright (C) Paul Johnston 1999 - 2009
 * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet
 * Distributed under the BSD License
 * See http://pajhome.org.uk/crypt/md5 for more info.
 */
27:15 ~ 小结

~ 这一堆,二十分鈡,整出来不难吧?

想来: - 其实,关键功能性行为代码,就8行

  • 其中7 行全部可以在google 中直接搜索到
  • 仅仅有一行,是需要学习新的工具,安装新的组件,学习新的文档,抄进来新的函式
  • 其余,都是力气活儿

    • 只要别抄錯
    • 都是赋值,赋值,赋值,赋值,,,,
  • 只要注意每一步,都使用 console.log 吼回来,测试确认无误,就可以继续前进了,,,

加载本地开发中的扩展目录
  `->修订JS
      ^ `-> 重新加载
      |   `-> 测试扩展
      |       观察控制台输出,确认效果是否吻合设想
      |           |
      +-----------/

这就是脚本语言的直觉式开发调试体验!

那么

接下来出于 程序员的直觉 应该折腾什么?!

  • 代码模块化?

  • 输出友好化?

  • 发布问题:

    • 如何安装管理 crx
    • 上哪儿发布 crx
    • 怎么对运行中的 crx 进行版本控制

Warning

  • 走着...

2: 怎么发布?

好了,已经完成了预期的 :

  • 使用 crx 形式 包装 金山网址云安全开放API 为标签感应式后台扩展
  • 只要用户打开标签访问网站,就会自动向金山云进行查询,如果有问题就刷红整个页面前警告!

但是 :

  • 怎么将这到扩展发布给全世界人民?!
  • 变量名设计的都很挫,需要重构...

...

所以,继续折腾以及反思...

web store

参考文档:

好吧,都是E文哪,普通人,很难看的下去的,,,肿么办!?

Warning

  • 来吧!

+15分钟:整上 web市场

宏观步骤

  1. 注册 Gmail 帐号
  2. 登录,部署 crx 作品
  3. 通过各种渠道宣传!

开始计时:

27:42 进入 web store

什么是 web store ? 就是 Google 管理的类似 Apple 公司的 app store! - 那,什么是 app store ? - 你!问题怎么这么多!?

总而言之, Googleweb store 就是义务为所有 crx 提供的一个作品发布中心/商城/管理平台 ... - 为一名开发者,可以方便的将 crx 作品发布出来 - 可以让全球互联网用户都可以高速的下载到我们的 crx 作品

而提供的一个服务中心!

  • 当然,前提是要有 Gmail 帐号!
_images/ch2-1-devcenter.png

插图.2-1 登录后从web store的配置菜单中进入

  • 开发者信息中心 首先就是作品列表
_images/ch2-2-crx-list.png

插图.2-2 通过 修改 链接进入后

  • 就可以看到,要求对每个 crx 有一系列的必要信息需要提供!

  • 其中最麻烦,却也是最重要的,就是 图标!
    • 因为 web store 中的扩展是成千上万的!
    • 一个设计精良的图标,可以帮助你从一大大大大大大大堆应用图标中跳出来,贏得首批用户!
  • 不过,俺不是专业的设计师,所以,使用 Inkscape 快速根据规格快速画了一组:

    • _images/icon-19.png
    • _images/icon-48.png
    • _images/icon-64.png
    • _images/icon-128.png
  • 以及截了个屏

    • _images/elf-snap.png

齐活儿!

最后,就是将所有,开发目录的东西,打成一个 zip 压缩文件,上传, `web store`_ 会作一系列测试,签名,打包什么的工作,

所有处理无误通过后,就会同步到全球上万台服务器中,完成上架,俺的自制 crx 就算面市鸟!

BINGO!

42:01 小结

~ 整个过程,基本就是一次合法上传

  • 唯一的耗时操作就是设计图标!

15分鈡,整出来不难吧?

整个儿的

最终,完成所有功能的配置和代码:

接下来

其实这个 elf 只能算是 crx 的练习作品, 猎豹浏览器 本身就已经内置了相同机制的功能!

  • 当然,扩展是兼容 Chrome 的,是可以安装到 Chrome 的,以便没有内核级的 钓鱼检测功能的 Chrome 可以通过 crx 透明的享受到 金山云的服务!

  • 其实, crx 的开发乐趣也正在于此:

    • 我们可以自在的通过 JavaScript 令心爱的浏览器,作我们经常需要作的事儿!
    • 不用求/等 Google 将新功能增补到新版本的浏览器来

这就是知识的力量!

开发文档!

好吧,虽然,整个手册看起来的确可以在 42 分钟之内,完成并发布出一个有真实功能的扩展来 - 但是,其实,真心要在之前,浏览足够多的开发文档,E文的,对 crx 的开发,有了正确的想象 - 才能够比较舒服自然的在 JavaScript 的帮助下,快速正确的将想作的事儿表述给 猎豹浏览器 内核明白,并逐一自动达成!

所以,中文版本的完备的开发文档,应该説是所有想自个儿开发 crx 的朋友们最需要的了,,,

接下来,就看俺怎么快速输出各种开发文档了,中文的! 敬请期待!

~ 2012.06.07 24:42 Zoom.Quiet

关于作者

  • Zoom.Quiet 是也乎;-)

    • Python 中文社区创始人 / 管理员之一,热心于各种开源技术社区的公众事业,大家熟知的社区”大妈”;OBP及蟒营工程设计者

修订记要

基于结构化文本~ rsticon 的图书工程

Shinx 说明

参考:

本书行文体例

本书使用不同的体例来区分不同的情景.

精巧地址

本书包含很多外部网站的URL地址,但是图书必竟不是网页,读者无法点击进入相关网站;所以,笔者尝试使用URL精简工具来帮助读者可以快速输入自动跳转到原有网站来访问;

  • 比如说: 本书的维基入口 http://wiki.woodpecker.org.cn/moin/ObpLovelyPython
  • 精巧地址: http://bit.ly/2QA425
  • 输入的字符量少了三倍! 这是借助 http://bit.ly 提供的网址精简服务达到的效果;
  • 提醒:毕竟这是借用外国的免费服务进行的精简,如果读者输入后不能自动跳转的话,可能是网络问题也可能是服务问题,那就只能麻烦读者重新使用原有的URL进入了;
程序体例

使用有语法颜色的代码引用

def foo():
    print "Love Python, Love FreeDome"
    print "E文标点,.0123456789,中文标点,. "

可以 用 .. code-block:: 追加各种语法高亮声明:

.. code-block:: python
    :linenos:

    def foo():
        print "Love Python, Love FreeDome"
        print "E文标点,.0123456789,中文标点,. "

效果:

1
2
3
def foo():
    print "Love Python, Love FreeDome"
    print "E文标点,.0123456789,中文标点,. "

外部包含:

.. literalinclude:: example.py
    :language: python

效果:

@route('%s/'%ini.urlprefix)
def index():
    __urlog("INFO","idx++")
    return template('index.tpl',urlprefix=ini.urlprefix)

文本体例

引用,题词:

No matter where you go, there you are.

—Buckaroo Banzai

技巧警示:

Note

(~_~)

  • This icon signifies a tip, suggestion, or general note.

Warning

(#_#)

  • 警告得注意的...

See also

(^.^)

  • 指向参考的...

附加说明:

进一步的

包含题外的信息,笔者心路,等等和正文有关,但是不直接的信息

知识引用:

  • 使用边注
  • 追随正文
  • 活动説明
  • 效果如右

rST排版技巧

跨章节指引
  • 行文中,经常要对其它章节进行指引,在 html 中对应的就是 锚点链接
  • rST 中提供了非常优雅的解决:
    • 使用通用元素定义
    • 比如説:
各个章节的首页一般是 index.rst
头一行,习惯性加个聲明:
.. _chapter2index:

那么,在其它任意文本中,随时可以使用:
:ref:`基本电子学 <chapter2index>`
来生成一个指向第二章 首页的链接!
插图/表格指代
  • 行文中,经常对指定插图/表格 进行指代
  • rST 中提供了非常优雅的解决:
    • 进行通用元素定义
    • 比如说
.. _fig_2_4:
.. figure:: _static/figs/tmux-curl-test.png

   插图 2-4 命令行测试情景

然后,就可以在任意地方使用 插图 2-4 命令行测试情景 来指代, 实际输出的就是 “插图 2-4 命令行测试情景”

_static/figs/tmux-curl-test.png

插图 2-4 命令行测试情景

上下标号

有时要进行数学/化学的表示,在 html 中就需要上/下标( <sub> , <sup>) 的表达, rST 中当然也有:

H\ :sub:`2`\ O
E = mc\ :sup:`2`

效果:

H2O

E = mc2

Note

注意:

这里的 只是为了制造语法空间,输出时,是没有空格的了,,,

线性表格

中文的非等宽性导致 rST 这种字符艺术式的图表很难作!

=====  =====
 A    not A
=====  =====
False  True
True   False
=====  =====

所以,使用列表也可以方便的生成表格:

.. list-table:: 实例
   :widths: 15 10 30
   :header-rows: 1

   * - Treat
     - Quantity
     - Description
   * - Albatross
     - 2.99
     - On a stick!
   * - Crunchy Frog
     - 1.49
     - If we took the bones out, it wouldn't be
       crunchy, now would it?
   * - Gannet Ripple
     - 1.99
     - On a stick!

效果

实例
Treat Quantity Description
Albatross 2.99 On a stick!
Crunchy Frog 1.49 If we took the bones out, it wouldn’t be crunchy, now would it?
Gannet Ripple 1.99 On a stick!
段落层次约定

使用 reSTsections

共分4级
=======================
大标题
=======================


-----------------------
小标题
-----------------------


^^^^^^^^^^^^^^^^^^^^^^^
二级标题
^^^^^^^^^^^^^^^^^^^^^^^


"""""""""""""""""""""""
三级标题
"""""""""""""""""""""""

再小,就使用列表!:

  • 列表项目1
  • 列表项目2
  • ...

效果:

大标题

小标题

二级标题
三级标题