[转]在Emacs下用C、C++编程


  转自http://hi.baidu.com/yilinghl/blog/item/5dc7d55cb4271f43faf2c069.html

用emacs写程序也有5个年头了,深切地体会到Emacs的强大。程序员有三种,一种是用vi的,一种是用emacs的,还有一种是其他。或许有些夸张,但也颇能体现出emacs在程序员中的地位。

emacs最大的问题在于入门门槛较高。它看起来和多数人想象中的IDE相差甚远,很多人看到emacs的第一眼就觉得它是个记事本(还是个非常难用的记事本),稍微好些的往往觉得emacs也就是个ultraEditor而已,真是暴殄天物了。

我是个懒人,不喜欢记太多的快捷键,相信很多人和我一样。所以从我后面的叙述可以看出来,除了常用的命令都是快捷键外,其他命令多数都是用M-x执行或者用鼠标点菜单。这仅仅是个人风格问题,先说明一下。

我的基本编程环境是:

  • Debian GNU/Linux sid 操作系统
  • Gnome 2.10.0 桌面环境
  • GUN Emacs 23.0.0.1 for debian
  • 使用 Gnu tool chains(gcc,make,gdb等等)

后面的叙述都基于上述环境。另外,本文主要针对C/C++程序开发,对其他语言有些也适用,从难度上说,本文主要针对入门者。

本文肯定会有很多错误,请指正,谢谢。

基本流程

写C++程序基本上是这么几个步骤:

  1. 编辑代码
  2. 编写Makefile
  3. 编译代码,修改编译错误
  4. 调试代码,修改逻辑错误

当然,往往还需要阅读别人的代码。

根据上述步骤,本文主要针对以下几个方面:

  • 配置Emacs,建立便利的代码编辑环境和Makefile编写环境。
  • 在Emacs中编译代码,并修改编译错误。
  • 在Emacs中配合GDB调试程序。
  • 利用cscope和ecb在emacs中阅读代码。

基本环境设置

编辑环境配置

要写C++程序,当然要用到cc-mode插件。CC-Mode原本是支持C语言的,但现在也能支持很多语言,比如C++,Java, Objective-C,CORBA,AWK,Pike等等。CC-Mode是gnu-emacs的标准插件。如果您要求不高,那么默认的配置或许就能满 足。CC-Mode的各种行为都可以自由地定制,您可以参考这里的文档:CC-Mode参考文档

这里是我的.emacs文件中关于CC-Mode配置的部分,仅供参考:

;;;; CC-mode配置  http://cc-mode.sourceforge.net/
(require 'cc-mode)
(c-set-offset 'inline-open 0)
(c-set-offset 'friend '-)
(c-set-offset 'substatement-open 0)
;;;;我的C/C++语言编辑策略

(defun my-c-mode-common-hook()
  (setq tab-width 4 indent-tabs-mode nil)
  ;;; hungry-delete and auto-newline
  (c-toggle-auto-hungry-state 1)
  ;;按键定义
  (define-key c-mode-base-map [(control \`)] 'hs-toggle-hiding)
  (define-key c-mode-base-map [(return)] 'newline-and-indent)
  (define-key c-mode-base-map [(f7)] 'compile)
  (define-key c-mode-base-map [(meta \`)] 'c-indent-command)
;;  (define-key c-mode-base-map [(tab)] 'hippie-expand)
  (define-key c-mode-base-map [(tab)] 'my-indent-or-complete)
  (define-key c-mode-base-map [(meta ?/)] 'semantic-ia-complete-symbol-menu)
;;;;我的C/C++语言编辑策略

(defun my-c-mode-common-hook()
  (setq tab-width 4 indent-tabs-mode nil)
  ;;; hungry-delete and auto-newline
  (c-toggle-auto-hungry-state 1)
  ;;按键定义
  (define-key c-mode-base-map [(control \`)] 'hs-toggle-hiding)
  (define-key c-mode-base-map [(return)] 'newline-and-indent)
  (define-key c-mode-base-map [(f7)] 'compile)
  (define-key c-mode-base-map [(meta \`)] 'c-indent-command)
;;  (define-key c-mode-base-map [(tab)] 'hippie-expand)
  (define-key c-mode-base-map [(tab)] 'my-indent-or-complete)
  (define-key c-mode-base-map [(meta ?/)] 'semantic-ia-complete-symbol-menu)

注意一下,上面最后两行是代码自动补齐的快捷键。后面我会提到代码自动补齐。

  ;;预处理设置
  (setq c-macro-shrink-window-flag t)
  (setq c-macro-preprocessor "cpp")
  (setq c-macro-cppflags " ")
  (setq c-macro-prompt-flag t)
  (setq hs-minor-mode t)
  (setq abbrev-mode t)
)
(add-hook 'c-mode-common-hook 'my-c-mode-common-hook)

;;;;我的C++语言编辑策略
(defun my-c++-mode-hook()
  (setq tab-width 4 indent-tabs-mode nil)
  (c-set-style "stroustrup")
;;  (define-key c++-mode-map [f3] 'replace-regexp)
)

自动补齐

自动补齐通常用的都是hippie-expand,我也用了很长时间。不过有时候会觉得这个自动补齐“傻”了一点,常会补齐出一些毫不相干的东西,因为hippie-expand是根据你敲过的词和kill-ring等进行判断的,并不对程序语法进行分析。

所以你还需要安装一个代码分析工具,然后把它加进hippie-expand的扩展策略里去。我们可以用semantic。实际上,hippie-expand+semantic是我所发现的最好的选择了,如果您有更好的,请您也告诉我一声:)

Semantic是CEDET中的一个工具,CEDET是Collection of Emacs Development Environment Tools的缩写,它包含了好几个工具,都挺不错的。可惜我只会用其中两个。

您可以在.emacs中对Semantic进行配置,下面是我的.emacs相关的配置,仅供参考:

导入cedet:

(load-file "~/lib/emacs-lisp/cedet-1.0pre3/common/cedet.el")

配置Semantic的检索范围:

(setq semanticdb-project-roots
   (list
        (expand-file-name "/")))
 

自定义自动补齐命令,这部分是抄hhuu的,如果在单词中间就补齐,否则就是tab。

(defun my-indent-or-complete ()
   (interactive)
   (if (looking-at "\>")
    (hippie-expand nil)
    (indent-for-tab-command))
 )

(global-set-key [(control tab)] 'my-indent-or-complete)

hippie的自动补齐策略,优先调用了senator的分析结果:

(autoload 'senator-try-expand-semantic "senator")

(setq hippie-expand-try-functions-list
    '(
  senator-try-expand-semantic
  try-expand-dabbrev
  try-expand-dabbrev-visible
  try-expand-dabbrev-all-buffers
  try-expand-dabbrev-from-kill
  try-expand-list
  try-expand-list-all-buffers
  try-expand-line
        try-expand-line-all-buffers
        try-complete-file-name-partially
        try-complete-file-name
        try-expand-whole-kill
        )
)

注意一下我前面CC-Mode配置中有这么两行:

  (define-key c-mode-base-map [(tab)] 'my-indent-or-complete)
  (define-key c-mode-base-map [(meta ?/)] 'semantic-ia-complete-symbol-menu)

这样,我们在CC-Mode中就可以调用自定义的hippie补全了,快捷键是Tab。

另外,我还把快捷键“Alt + / ”绑定到了semantic-ia-complete-symbol-menu命令上,这是semantic的命令,它会根据分析结果弹出补齐的菜单,效果如图显示:

CEDET中还有一个不错的工具是speedbar,你可以用它在多个文件中快速切换。在我的.emacs配置文件里,我把speedbar关联到了F5上:

(global-set-key [(f5)] 'speedbar)

这样用F5就可以调出speedbar,效果如下:

 

不过说实话,我自己很少用到speedbar,我通常都是用dired配合bookmark使用:)

编译和调试程序

按上面的配置,写完程序和Makefile文件后,在Emacs源代码窗口中按F7就可以进行编译。因为在my-c-mode-common-hook()函数里,有这么一行:

(define-key c-mode-base-map [(f7)] 'compile)

默认情况下,emacs的compile命令是调用make -k,我把它改成了make。你也可以把它改成其他的,比如gcc之类的。改下面的“make”就行了。

'(compile-command "make")

Emacs会划分一个窗格显示编译的消息,在编译结束后,emacs会自动将编译器的输出和程序关联起来,告诉你第几行的程序有问题。直接在出错的行号上按Enter,就可以跳转到相应文件的相应行。其实我通常都是用鼠标中键去点出错行号:)

搞定了编译错误后,接着要和逻辑错误斗争了。其实对简单的程序来说,把中间结果打印到终端是最简单好用的调试办法:)不过稍微复杂点的程序就会晕菜了,这时我们就需要拿gdb跟踪程序流程了。

你用下面的命令就可以启动gdb了。

M-x gdb

通常我喜欢进入gdb-many-windows模式,这样就会把一个Frame划分为5个窗格,同时显示:gdb命令窗口,当前局部变量,程序文本,调用栈和断点。

gdb的命令就不在这里说了,它的文档几乎到处都是。emacs把gdb的命令和快捷键做了绑定,对于常用的命令,还是输入快捷键比较方便。比如,C-c C-n是Next line,C-c C-s是step in,其实用的最多的快捷键也就是这两个。

下面是我的gdb效果图:

阅读代码

在emacs下读代码通常有三种工具,最简单的是etags,最复杂的是ecb(emacs code browser),位于中间的是cscope。

etags和ctags一样,只不过前者是用于emacs的,后者是用于vi的。我个人觉得etags功能稍稍显得不够用一点,当然,也可能是我用的不好:) 欢迎大牛指导。

使用tags之前要先对源代码分析建立tags文件,在代码所在目录中运行:etags -R 即可。

我常用的就这几个命令和快捷键:

M-x visit-tags-table <RET> FILE <RET>   选择tags文件
M-. [TAG] <RET>                         访问标签
M-*                                     返回
C-u M-.                                 寻找标签的下一个定义

ecb据说功能强大,但是太复杂了,我懒得折腾它。谁搞定了教教我吧:) 下面是一张ecb的效果图。

cscope是我感觉比较合适的一个工具。它其实是一个独立的软件,完全可以脱离vi和emacs使用。但是结合emacs的强大功能, cscope就显得更加方便了。GNU Emacs默认自带cscope的支持。在使用之前,cscope也需要对代码进行索引。在emacs中可以这样做:

C-c s a             设定初始化的目录,一般是你代码的根目录
C-s s I             对目录中的相关文件建立列表并进行索引

建完索引之后,你就可以用cscope在代码里游荡了。常用的一些命令如下:

C-c s s             序找符号
C-c s g             寻找全局的定义
C-c s c             看看指定函数被哪些函数所调用
C-c s C             看看指定函数调用了哪些函数
C-c s e             寻找正则表达式
C-c s f             寻找文件
C-c s i             看看指定的文件被哪些文件include

上面这些快捷键其实我自己也常常记不全,没关系,抬头看看上面的菜单栏,有一栏就是Cscope,这些命令里头都有:)

贴一个cscope的效果图吧:

linux Comments(1) 2008年4月04日 03:57

Ubuntu配置记录-3:安装网络服务(未完)

一、安装Web服务器

1、Apache

首先是安装Apache,输入

sudo apt-get install apache2

安装后的Apache就已经直接可以运行了,可以输入http://127.0.0.1查看效果。 之后是根据自己需要配置了 Apache的配置文件在/etc/apache2/apache2.conf中 Apache的默认站点配置文件在/etc/apache2/sites-enabled/000-default中 Apache的默认站点目录在/var/www/中 要为站点建立子目录,可以在/var/www/下建立相应的目录,也可以在/etc/apache2/sites-enabled创建专用的配置文件。

 

接下来是设置虚拟站点。我是直接在/etc/apache2/sites-enabled下创建专用的配置文件的。

 

在其中任意创建一个文件,然后写入别名站点信息:

Alias /test/ "/home/www/"

Alias的作用是为地址创建别名。假设主机地址是localhost,那么http://localhost/test/就会被Apache映射到/home/www目录下

注意:要确保Apache对目标目录至少有读取权限,最好是有读写权限。一个简单的方法是用“sudo chmod 777 目录名”来开放权限,但是更好的方法是将此目录的所有者设为www-data(Apache所使用的账号)或者将组设为www-data并用chmod 775或者chmod 771。

接着就是写入权限设置了,使用<Directory />段来配置:

<Directory "/home/www/">
    Options Indexes MultiViews FollowSymLinks
    AllowOverride None
    Order deny,allow
    Deny from all
    Allow from 127.0.0.1
</Directory>

相关选项的含义如下:


Options: 提供一系列权限选项,有Indexes(允许列出目录)、MultiViews(多种内容显示方法)、FollowSymLinks(使用符号链接)。其 中Indexes是非常危险的,如果不是作为调试或者个人使用,最好去除。FollowSymLinks应该是指能把Linux的符号链接当作一个正常的 文件吧,没仔细研究。


AllowOverride:是否启用.htaccess配置文件。

 

Order:控制默认的访问状态与Allow和Deny指令生效的顺序。

AllowDeny:设置授权和禁止列表,格式为 Allow(Deny) from all|host|env=env-variable [host|env=env-variable] ...。一般主要用All和host,其中host可以有以下几种用法:

一个(部分)域名

示例:

Allow from apache.org
Allow from .net example.edu

主机名与给定字符串匹配或者以给定字符串结尾的主机允许访问。只有完整的名字组成部分才被匹配,因此上述例子将匹配foo.apache.org但不能匹配fooapache.org 。这样的配置将导致Apache不管HostnameLookups指令是如何设置的,对一个对客户IP地址都要执行两次DNS查询:一次正查询保证IP没有伪造,一次反查询保证主机名没有伪造。只有两次查询的结果都吻合,并且主机名能够被匹配,访问才被允许。

完整的IP地址

示例:

Allow from 10.1.2.3
Allow from 192.168.1.104 192.168.1.205

;允许拥有这些IP地址的主机进行访问。

部分IP地址

示例:

Allow from 10.1
Allow from 10 172.20 192.168.2

IP地址的开始1到3个字节,用于子网限制。

网络/掩码对

示例:

Allow from 10.1.0.0/255.255.0.0

一个网络"a.b.c.d"和一个掩码"w.x.y.z",用于更精确的子网限制。

网络/nnn无类别域间路由规格(CIDR specification)

示例:

Allow from 10.1.0.0/16

同前一种情况相似,除了掩码由nnn个高位字节构成。

注意以上例子中的后三个匹配完全相同的一组主机。

IPv6地址和IPv6子网可以像下面这样指定:

Allow from 2001:db8::a00:20ff:fea7:ccea
Allow from 2001:db8::a00:20ff:fea7:ccea/10

安装PHP

安装PHP很简单,直接用apt-get就行:

sudo apt-get install php5

安装后自动与Apache集成,不用进行额外设置,很方便。

安装MySQL

首先安装MySQL:

sudo apt-get install mysql-server

安装过程中会要求设置root账号。 然后是安装PHP对MySQL的支持:

sudo apt-get install php5-mysql
安装SSH服务

安装:

sudo apt-get install openssh-*

安完就能用了

要重启ssh,可以使用这个命令

sudo /etc/init.d/ssh restart

 

 

要启动和停止ssh,只要把restart换成start和stop就行了

安装vsftpd

安装:

sudo apt-get install vsftpd

为了使用虚拟帐户,还要安装Berkeley Database Utilities:

sudo apt-get install db4.6-util

编辑配置文件:

sudo gedit /etc/vsftpd.conf

内容如下:

# 开启监听模式
listen=YES
# 允许列出文件
dirlist_enable=YES
# 本地用户登录后的要目录位置为home目录
local_root=
# 允许匿名用户
anonymous_enable=YES
# 允许本地用户登录
local_enable=YES
# 默认不允许上传文件
write_enable=NO
# 上传的文件的权限设为644
local_umask=022
# 定义用户个人配置文件所在的目录
user_config_dir=/etc/vsftpd/vsftpd_user_dir
# 允许使用目录欢迎信息文件
dirmessage_enable=YES
# 启用默认数据链接端口
connect_from_port_20=YES
# 禁止用户访问local_root之上的目录,将local_root作为用户的根目录
chroot_local_user=YES
# 启用虚拟用户
guest_enable=YES
# 虚拟用户所使用的本地账号
guest_username=tigersoldier
# 赋予虚拟用户和本地对应账号相同的权限
virtual_use_local_privs=YES
# PAM服务名,用于虚拟用户验证
pam_service_name=vsftpd
#########################################
# 一些其他我不关心也不了解的默认选项
#
# 上传下载日志
xferlog_enable=YES
# 空目录,作为限制目录使用
secure_chroot_dir=/var/run/vsftpd
# SSL的RSA密钥
rsa_cert_file=/etc/ssl/certs/ssl-cert-snakeoil.pem
rsa_private_key_file=/etc/ssl/private/ssl-cert-snakeoil.key

建立相关配置目录:

sudo mkdir -p /etc/vsftpd/vsftpd_user_dir/

 创建编辑虚拟用户文件

sudo gedit /etc/vsftpd/login.txt

内容为一行用户名一行密码,如

upload
up
anim
manga

就创建了两个虚拟用户,一个是upload,密码为up;另一个是anim,密码为manga

生成账号文件对应的db文件,要用上刚才安装的Berkeley Database Utilities:

sudo db4.6_load -T -t hash -f /etc/vsftpd/login.txt /etc/vsftpd/vsftpd_login.db
chmod 600 /etc/vsftpd/vsftpd_login.db

编辑vsftpd的pam服务,用于账号验证:

sudo gedit /etc/pam.d/vsftpd

注意服务的文件名是由vsftpd.conf的pam_service_name决定的

把服务替换成如下内容

auth    required    /lib/security/pam_userdb.so db=/etc/vsftpd/vsftpd_login
account required    /lib/security/pam_userdb.so db=/etc/vsftpd/vsftpd_login  

这个文件原来可能有其他内容,必须去掉,不然会产生认证冲突无法登录

要注意的是,这样做之后就无法用本地账号登录了,如果在配置里没有开启virtual_use_local_privs,虚拟账号的权限等同于匿名用户

为每个账号作特别配置:

账号配置文件要放在vsftpd.conf的user_config_dir段所指定的目录下,在这里是/etc/vsftpd/vsftpd_user_dir

以upload账号为例,编辑文件

sudo gedit /etc/vsftpd/vsftpd_user_dir/upload

格式与vsftpd的配置文件相同,不过只能设置与用户相关的选项。在这里设置上传权限和根目录:

local_root=/home/ftp/upload
write_enable=YES
#anon_upload_enable=YES

注意anon_upload_enable,如果没有配置virtual_use_local_privs=YES,则虚拟账号相当于匿名用户,所以只设write_enable是不够的

研究中……

linux Comments(11) 2008年4月04日 03:53

Ubuntu配置记录-2:关于开发环境的配置

安装配置程序开发的相关环境: emacs、eclipse、GTK、doxygen、svn

阅读全文

linux Comments(2) 2008年4月04日 03:52

Ubuntu配置记录-1 网络与源

把Ubuntu重装了一遍,配置起来挺麻烦的,于是干脆记录一下,以免以后又忘记。

安装完成后,最重要的是网络问题。学校使用802.1x认证,需要特殊的软件来登录。我用的是华为的H3C。
以下是别人给的一份文档,很有用,我就不自己写了XD

在Ubuntu Linux下面使用H3C认证客户端上网,这需要华为公司专门为Linux开发的软件h3c802.1xclient.tar.gz
1)下载了H3C后,解压文件:

$sudo tar –xvzf h3c802.1xclient.tar.gz

这会解压到当前目录下,生成一个h3c802.1xClient目录。

或者可以指定解压路径:

$sudo tar –C h3c802.1xclient.tar.gz [path]

2)转到此目录下:$cd h3c802.1xClient

运行里面的pre.ps文件:

$sudo ./pre.ps

再运行里面的linux1x文件(可以查看里面的说明文档):

$sudo linux1x

3)如果里面的链接库缺少H3C必要的libstdc++-libc6.2-2.so.3文件,会报错.

根据提示信息,先转到链接库目录:

$cd lib

在里面找到一个相似的文件,与所需的文件建立硬链接:

$sudo ln libc.so.6 libstdc++-libc6.2-2.so.3

4)再次运行linux1x文件,可以上网了!:

$sudo linux1x [-p|-d|-k]

其中,参数-p表示注销当前帐号信息,重新验证;-d表示通过验证后返回控制

台继续执行其他命令;-k表示断开网络连接。

5)PS:经常出现这种情况--不知道什么时候网络断了,而用户无法及时得知。解决办法之一是:按

下Ctrl+Alt+F1切换到命令行控制台,使用任何一个本地帐户登录联网,然后输入命令:

$ping [学校服务器代理(202.116.64.226)]。

在此命令下,如果网络畅通,会一直有数据包返回。

在运行时千万不能忘了sudo,我之前就是因为忘了sudo导致老是提示“ERROR! Can't initial authentication program !”,搞得我还以为软件坏了OTL……

然后就是设置更新的源,用官方的源会慢死的……

apt的源列表文件保存在/etc/apt/source.list文件中,可以用任意文本编辑器编辑,注意要用root权限来编辑,也就是用sudo。编辑前最好保存一份复本:

$sudo cp /etc/apt/sources.list /etc/apt/sources.list_backup

然后就可以编辑了:

$sudo gedit /etc/apt/sources.list

因为在教育网里,所以用中科大的源会很爽:

deb http://debian.ustc.edu.cn/ubuntu/ gutsy main restricted universe multiverse
deb http://debian.ustc.edu.cn/ubuntu/ gutsy-backports restricted universe multiverse
deb http://debian.ustc.edu.cn/ubuntu/ gutsy-proposed main restricted universe multiverse
deb http://debian.ustc.edu.cn/ubuntu/ gutsy-security main restricted universe multiverse
deb http://debian.ustc.edu.cn/ubuntu/ gutsy-updates main restricted universe multiverse
deb-src http://debian.ustc.edu.cn/ubuntu/ gutsy main restricted universe multiverse
deb-src http://debian.ustc.edu.cn/ubuntu/ gutsy-backports main restricted universe multiverse
deb-src http://debian.ustc.edu.cn/ubuntu/ gutsy-proposed main restricted universe multiverse
deb-src http://debian.ustc.edu.cn/ubuntu/ gutsy-security main restricted universe multiverse
deb-src http://debian.ustc.edu.cn/ubuntu/ gutsy-updates main restricted universe multiverse

另外cn99也很重要:

deb http://ubuntu.cn99.com/ubuntu/ gutsy main restricted universe multiverse
deb http://ubuntu.cn99.com/ubuntu/ gutsy-security main restricted universe multiverse
deb http://ubuntu.cn99.com/ubuntu/ gutsy-updates main restricted universe multiverse
deb http://ubuntu.cn99.com/ubuntu/ gutsy-proposed main restricted universe multiverse
deb http://ubuntu.cn99.com/ubuntu/ gutsy-backports main restricted universe multiverse
deb-src http://ubuntu.cn99.com/ubuntu/ gutsy main restricted universe multiverse
deb-src http://ubuntu.cn99.com/ubuntu/ gutsy-security main restricted universe multiverse
deb-src http://ubuntu.cn99.com/ubuntu/ gutsy-updates main restricted universe multiverse
deb-src http://ubuntu.cn99.com/ubuntu/ gutsy-proposed main restricted universe multiverse
deb-src http://ubuntu.cn99.com/ubuntu/ gutsy-backports main restricted universe multiverse
deb http://ubuntu.cn99.com/ubuntu-cn/ gutsy main restricted universe multiverse

把这两个源加到source.list的最前端就行,不用像有些教程说的那样要把其它的覆盖掉。

这些源都是用于Ubuntu 7.10(Gutsy)的,要给其他版本添加源的应该把gutsy换成相应的代号就行了吧(中科大的源我就是这么干的XD)。

linux Comments(2) 2008年4月04日 03:50

更新了文泉驿

把文泉驿正黑更新到了夸父正式版(0.5 Final),终于可以正常显示9pt的“/”号了

话说文泉驿确实挺美观的,不必再用Win下的版权字体了。

衷心希望文泉驿越做越好

附:文泉驿正黑相关页面:http://wenq.org/index.cgi?ZenHei

linux Comments(1) 2008年4月03日 10:11

[转]listings 宏包札记

原文貌似是在 http://blog.linuxgem.org/lyanry/show/319.html,不过链接已经失效了

此文是从http://hi.baidu.com/shawpinlee/blog/item/9ec431cbae28e41cbe09e6e4.html搬过来的


listings 是专用于代码排版的 LaTeX 宏包,可对关键词、注释和字符串等使用不同的字体和颜色或颜色,也可以为代码添加边框、背景等风格。

1 基本用法

下面给出一份用于排版 C 语言 HelloWorld 程序代码的完整的 LaTeX 文档:

\documentclass{article}
\usepackage{listings}

\begin{document}

\begin{lstlisting}[language=C]
int main(int argc, char ** argv)
{
/* print a string "Hello world!"
printf("Hello world!\n");

return 0;
}
\end{lstlisting}

\end{document}

排版效果如下图所示:

2 对计算机语言的支持

listings 宏包支持大约近百种计算机语言,下面只列举几个常用的:

  • C :ANSI, Handel, Objective, Sharp
  • C :ANSI, GNU, ISO, Visual
  • Delphi
  • Java :empty, AspectJ
  • TeX :AlLaTeX, common, LaTeX, plain, primitive
  • XML
  • Gnuplot
  • HTML
  • Python
  • Ruby
  • make :empty, gnu

从上面的语言支持列表可看到有些语言是分为了多种类型的,比如 C 语言分为了 ANSI, Handel, Objective, Sharp 等类型。在使用 listings 宏包时,对某种语言存在多种类型的情况下,可以指定所需类型的,例如:

\begin{lstlisting}[language={[ANSI]C}]
int main(int argc, char ** argv)
{
/* print a string "Hello world!"
printf("Hello world!\n");

return 0;
}
\end{lstlisting}

3 语法高亮

listings 宏包提供了关键词高亮与注释高亮,分别体现为 keywordstyle 与 commentstyle 参数。

下面将 C 语言关键词使用浅蓝色高亮显示,代码采用灰色显示:

\documentclass{article}
\usepackage{listings}
\usepackage{xcolor} % 使用颜色宏包

\begin{document}

\begin{lstlisting}[language={[ANSI]C}, keywordstyle=\color{blue!70}, commentstyle=\color{red!50!green!50!blue!50}]
int main(int argc, char ** argv)
{
/* print a string "Hello world!" */
printf("Hello world!\n");

return 0;
}
\end{lstlisting}

\end{document}

注意,要使用 listings 宏包提供的语法高亮,需要 xcolor 宏包支持。

语法高亮的排版效果如下图所示:

4 添加边框

listings 宏包为代码边框提供了很多风格,大体可分为带有阴影的边框与圆角边框。这里仅仅给出一个阴影边框的示例,至于其它边框风格,可查阅 listings 宏包文档,里面给出了一些示例。

下面 LaTeX 源文档将为代码添加阴影边框,并将阴影设置为浅灰色:

\begin{lstlisting}[language={[ANSI]C}, keywordstyle=\color{blue!70}, commentstyle=\color{red!50!green!50!blue!50}, frame=shadowbox, rulesepcolor=\color{red!20!green!20!blue!20}]
int main(int argc, char ** argv)
{
/* print a string "Hello world!" */
printf("Hello world!\n");

return 0;
}
\end{lstlisting}

排版效果如下图:

5 添加行号

很多时候需要对文档中的代码进行解释,只有带有行号的代码才可以让解释更清晰,因为你只需要说第 x 行代码有什么作用即可。如果没有行号,那对读者而言就太残忍了,他们不得不从你的文字叙述中得知行号信息,然后去一行一行的查到相应代码行。

listings 宏包通过参数 numbers 来设定行号,该参数的值有两个,分别是 left 与 right,表示行号显示在代码的左侧还是右侧。下面为带有边框的代码添加行号,并设置行号字体为 \tiny:

\begin{lstlisting}[language={[ANSI]C}, numbers=left, numberstyle=\tiny, keywordstyle=\color{blue!70}, commentstyle=\color{red!50!green!50!blue!50}, frame=shadowbox, rulesepcolor=\color{red!20!green!20!blue!20}]
int main(int argc, char ** argv)
{
/* print a string "Hello world!" */
printf("Hello world!\n");

return 0;
}
\end{lstlisting}

排版效果如下图所示:

6 全局设置

上面所给的各个示例中,lstlisting 环境后面尾随了很多参数,要是每使用一次 lstlisting 环境就要设置这么多参数,那就没什么意思了。

可以使用 \lstset 命令在 LaTeX 源文档的导言区设定好 lstlisting 环境所用的公共参数,如下:

\documentclass{article}
\usepackage{listings}
\usepackage{xcolor}

\begin{document}

\lstset{numbers=left,
numberstyle=\tiny,
keywordstyle=\color{blue!70}, commentstyle=\color{red!50!green!50!blue!50},
frame=shadowbox,
rulesepcolor=\color{red!20!green!20!blue!20}
}

\begin{lstlisting}[language={[ANSI]C}]
int main(int argc, char ** argv)
{
/* print a string "Hello world!" */
printf("Hello world!\n");

return 0;
}
\end{lstlisting}

\end{document}

7 显示中文

listings 宏包默认是不支持包含中文字串的代码显示的,但是可以使用 “逃逸” 字串来显示中文。

在 \lstset 命令中设置逃逸字串的开始符号与终止符号,推荐使用的符号是左引号,即 “ `

\lstset{numbers=left,
numberstyle=\tiny, keywordstyle=\color{blue!70}, commentstyle=\color{red!50!green!50!blue!50},
frame=shadowbox, rulesepcolor=\color{red!20!green!20!blue!20},
escapeinside=``}

……

\begin{lstlisting}[language={[ANSI]C}]
int main(int argc, char ** argv)
{
/* print a string "Hello world!" */
printf("`我爱中文`!\n");

return 0;
}
\end{lstlisting}

8 调整一下边距

listings 的代码框的宽度默认是与页芯等宽的,其上边距也过于小,可根据自己的审美观念适度调整一下。我通常是将代码框的左右边距设置为 2em,上边距为 1em,下边距采用默认值即可,所作设定如下:

\lstset{numbers=left, numberstyle=\tiny, keywordstyle=\color{blue!70}, commentstyle=\color{red!50!green!50!blue!50}, frame=shadowbox, rulesepcolor=\color{red!20!green!20!blue!20},escapeinside=``, xleftmargin=2em,xrightmargin=2em, aboveskip=1em}
...

阅读全文

TeX Comments(2) 2008年4月02日 07:04

IE6中关于文本框中的光标位置与选中区

在FireFox下,要获取一个文本框的光标位置,可以通过获取它的选择起点和终点解决:当没有选中文字时,selectionStart和selectionEnd均等于文本框的光标位置;有选中文字时,seletionStart和selectionEnd的含义与它们名字的字面含义相同。

但是IE6里没有提供这两个属性,只能通过它的TextRange对象来曲线解决:

var expobj = document.getElementById("aTextbox");
if (document.selection){               //IE
  expobj.focus();
  sel = document.selection.createRange();
  ……
}
通过document.selection.createRange(),可以返回当前文档选中部分的TextRange对象。为了防止操作到文档的其他选中区域,要首先把焦点转给要操作的文本框。
之后就可以通过更改sel来操作选中的文本,包括改变文字什么的。
要获得选中区在文本框的位置,要用曲线点的方法:把选中区开头移动到文本框的最前端,然后选中区文本的长度就是选中区末端在文本框中的位置了:
sel.moveStart("character",-expobj.value.length);
pos = sel.text.length;
同理可得选中开头处的位置。
使用sel.select()可以令改动后的选择范围生效。...

阅读全文

javascript Comments(1) 2008年4月01日 19:04

[转]在Ubuntu下简易配置Tex UTF-8中文环境

转自LDCN

在Ubuntu下配置使用Tex中文环境有好几种选择和相关方法,有些比较简单(比如直接用XeTeX),有些则相对麻烦一点(比如手动去生成相关字体)。

现在应用最广的一般是TexLive CJK,如果想尽量使你的Tex文档在Windows/Linux下互相通用,一般都选择这种组合,而且这也是目前最成熟的(相对于XeTeX)。

今天这篇文章中的方法,是利用目前已经成功的方法,再结合Ubuntu的特定环境所作的。希望能给想在Ubuntu下配置Tex中文环境的朋友一个参考。

—–

先介绍一下之前最流行的在Linux下配置Tex的方法,一般是参考这篇文章:

http://mailboxpublic.googlepages.com/texlive2007cjkchinesehowto

下载1GB左右的ISO档,挂载ISO并安装其中的TexLive,再自己生动生成相关字体文件。一般都能顺利的配置好Tex UTF-8的中文环境。

但是对于习惯了apt-get的用户,可能不愿意从外部安装Tex套件。因此,我参考了一些文章,琢磨出了这个利用Ubuntu源里的TexLive,再手动生成字体包的方法,优点是:

  • 不需要下载1GB的ISO档,只需要下载我准备的几百KB的字体生成要用的相关文件。
  • 只从Ubuntu源里安装相关Tex套件,不往系统目录写入其他文件,方便删除。
  • 仍需要手动生成字体文件,不过是安装在自己的主目录下。

好。请看详细方法:

一、安装TexLive Latex CJK:

打开终端,执行下述命令安装TexLive和常用的一些Latex宏包(可以根据自己的需要增改):

sudo apt-get install texlive texlive-math-extra texlive-latex-base texlive-latex-extra texlive-latex-recommended texlive-pictures texlive-science texlive-bibtex-extra texlive-common latex-beamer

如果硬盘充裕的话,直接完整安装也可以:

sudo apt-get install texlive-full latex-beamer

安装完后,就可以安装CJK的相关软件包了,如果只需要获得中文支持,那么执行:

sudo apt-get install latex-cjk-chinese ttf-arphic-* hbf-*

否则,建议安装latex-cjk-all以获取完整支持。

二、生成中文字体包

安装好TexLive CJK以后,还需要安装一个软件──fontforge用于生成字体:

sudo apt-get install fontforge

好了,前面所做的,都是标准的Debian式安装,假如哪天你不需要了,直接remove安装即可。

生成字体前,请自己准备你需要生成的字体文件:simsun.ttc,simhei.ttf等,这里以simsun.ttc(宋体)为例。

准备好后下载下面这个包,解压到一个地方,如自己的主目录~/font:

font.tar.bz2

然后把simsun.ttc也复制到~/font里去,执行下面的命令生成字体地图:

cd ~/font
time fontforge -script subfonts.pe simsun.ttc song Unicode.sfd

加time是为了计算时间,因为比较耗时,在我的Core 2 Duo T5500下,生成song花了40分钟,生成hei花了24分钟,仅供参考。

字体生成好了,再建立一个描述文件吧。

在~/font下,建立一个makemap文件,内容如下:

for i in *.tfm
do
cat >> song.map << EOF
${i%.tfm} ${i%.tfm} < ${i%.tfm}.pfb
EOF
done

然后在终端下执行:chmod x makemap让文件加上执行权限,最后执行:

./makemap

再建立一个一个c70song.fd文件:

% This is c70song.fd for CJK package.
% created by Edward G.J. Lee
% modify by Yue Wang
\ProvidesFile{c70song.fd}
\DeclareFontFamily{C70}{song}{\hyphenchar \font\m@ne}
\DeclareFontShape{C70}{song}{m}{n}{<-> CJK * song}{}
\DeclareFontShape{C70}{song}{bx}{n}{<-> CJKb * song}{\CJKbold}
\endinput

好的,相关文件都已生成,开始复制字体使其生效。

执行下面的命令,在你的主目录下生成隐藏的个人Tex配置,如果你哪天不需要了,也可以删除:

mkdir -p ~/.texmf-var/fonts/map/dvips/CJK
mkdir -p ~/.texmf-var/fonts/tfm/CJK/song
mkdir -p ~/.texmf-var/fonts/type1/CJK/song
mkdir -p ~/.texmf-var/tex/latex/CJK/UTF8

建立完这层层叠叠的目录以后,就把刚刚生成的字体复制进去吧。

cp ~/font/song.map ~/.texmf-var/fonts/map/dvips/CJK
cp ~/font/*.tfm ~/.texmf-var/fonts/tfm/CJK/song
cp ~/font/*.pfb ~/.texmf-var/fonts/type1/CJK/song
cp ~/font/c70song.fd ~/.texmf-var/tex/latex/CJK/UTF8

复制完后就执行命令刷新缓存,让它生效:

sudo texhash
updmap --enable Map song.map

假如一切顺序的话, 就测试一下我们安装的song体是否能用吧。

在任意位置编辑这个文件,然后保存为test.tex,支持UTF-8格式:

\documentclass{article}
\usepackage{CJKutf8}
\begin{document}
\begin{CJK}{UTF8}{song}
你好!这里是Ubuntu下的TexLive CJK环境!
\end{CJK}
\end{document}

 

执行分别生成pdf文档和用evince来查看文档:

pdflatex test.tex
evince test.pdf

看看你的过程顺不顺利,生成的PDF档也是下面这样吗?

texlive.png

texlive-2.png

用同样的方法搞定hei和kai等常用中文标准字体,开始享受你的Tex吧!

参考资料是:

Fedora上配置Tex UTF-8 中文系统

TeXLive 2007 CJK Chinese Howto

ubuntu 7.10下搞定Latex CJK

...

阅读全文

TeX Comments(1) 2008年3月30日 19:03

下一个目标:LaTeX与MetaPost

这个Ubuntu弄了一两个星期,现在终于可以干不少事了:
我用它听歌、看电影
用它上网、查资料
用它写程序
用它开FTP、WEB服务
用它聊天,收发邮件
还差什么?
文档,最重要的就是文档,我还要写作业啊
于是昨天用Open Office Dia写了一次,越来越觉得图形化的拖拉选按不能满足我的要求
果然还是可以自己完全精确控制的脚本语言王道,要下定决心学LaTex和MetaPost了...

阅读全文

linux Comments(1) 2008年3月29日 21:03

安装了新版EVA

装了3月8号的版本后发现有了挺大的改变,终于可以正常地复制粘贴了,选中文字后右键也不会崩溃
不过还是不支持单人聊天时发自定义表情,图标也变成了我讨厌的新版
不知道有没有支持验证码输入……
希望EVA越做越好吧,毕竟Linux下上QQ最好的就是它了...

阅读全文

linux Comments(1) 2008年3月29日 20:03