2004年12月20日

唉,上次因为这里的排版不方便,搬到chinaunix了。。
但是那里没有2级域名,比较郁闷
最近发现这里的排版又很舒服了,,哇
爽,希望donews越办越好。。。
以后就不换了

搬家好累啊,,,

前言

正则表达式是烦琐的,但是强大的,学会之后的应用会让你除了提高效率外,会给你带来绝对的成就感。只要认真去阅读这些资料,加上应用的时候进行一定的参考,掌握正则表达式不是问题。


索引

1._引子

2._正则表达式的历史

3._正则表达式定义

3.1_普通字符

3.2_非打印字符

3.3_特殊字符

3.4_限定符

3.5_定位符

3.6_选择

3.7_后向引用

4._各种操作符的运算优先级

5._全部符号解释

6._部分例子

7._正则表达式匹配规则

7.1_基本模式匹配

7.2_字符簇

7.3_确定重复出现


1. 引子

  目前,正则表达式已经在很多软件中得到广泛的应用,包括*nix(Linux, Unix等),HP等操作系统,PHP,C#,Java等开发环境,以及很多的应用软件中,都可以看到正则表达式的影子。

  正则表达式的使用,可以通过简单的办法来实现强大的功能。为了简单有效而又不失强大,造成了正则表达式代码的难度较大,学习起来也不是很容易,所以需要付出一些努力才行,入门之后参照一定的参考,使用起来还是比较简单有效的。

例子: ^.+@.+..+$

  这样的代码曾经多次把我自己给吓退过。可能很多人也是被这样的代码给吓跑的吧。继续阅读本文将让你也可以自由应用这样的代码。

  注意:这里的第7部分跟前面的内容看起来似乎有些重复,目的是把前面表格里的部分重新描述了一次,目的是让这些内容更容易理解。

2. 正则表达式的历史

  正则表达式的“祖先”可以一直上溯至对人类神经系统如何工作的早期研究。Warren McCulloch 和 Walter Pitts
这两位神经生理学家研究出一种数学方式来描述这些神经网络。

  1956 年, 一位叫 Stephen Kleene 的数学家在 McCulloch 和
Pitts
早期工作的基础上,发表了一篇标题为“神经网事件的表示法”的论文,引入了正则表达式的概念。正则表达式就是用来描述他称为“正则集的代数”的表达式,因此采用“正则表达式”这个术语。

  随后,发现可以将这一工作应用于使用 Ken Thompson 的计算搜索算法的一些早期研究,Ken Thompson 是 Unix
的主要发明人。正则表达式的第一个实用应用程序就是 Unix 中的 qed 编辑器。

  如他们所说,剩下的就是众所周知的历史了。从那时起直至现在正则表达式都是基于文本的编辑器和搜索工具中的一个重要部分。

 

3. 正则表达式定义

  正则表达式(regular
expression)描述了一种字符串匹配的模式,可以用来检查一个串是否含有某种子串、将匹配的子串做替换或者从某个串中取出符合某个条件的子串等。

  • 列目录时, dir *.txt或ls
    *.txt中的*.txt就是一个正则表达式,因为这里*与正则式的*的含义是不同的。

  正则表达式是由普通字符(例如字符 a 到 z)以及特殊字符(称为元字符)组成的文字模式。正则表达式作为一个模板,将某个字符模式与所搜索的字符串进行匹配。

3.1 普通字符

  由所有那些未显式指定为元字符的打印和非打印字符组成。这包括所有的大写和小写字母字符,所有数字,所有标点符号以及一些符号。

3.2 非打印字符

字符 含义
cx 匹配由x指明的控制字符。例如, cM 匹配一个 Control-M 或回车符。x
的值必须为 A-Z 或 a-z 之一。否则,将 c 视为一个原义的 ‘c’ 字符。
f 匹配一个换页符。等价于 x0c 和 cL。
n 匹配一个换行符。等价于 x0a 和 cJ。
r 匹配一个回车符。等价于 x0d 和 cM。
s 匹配任何空白字符,包括空格、制表符、换页符等等。等价于 [ fnrtv]。
S 匹配任何非空白字符。等价于 [^ fnrtv]。
t 匹配一个制表符。等价于 x09 和 cI。
v 匹配一个垂直制表符。等价于 x0b 和 cK。


 

3.3 特殊字符

  所谓特殊字符,就是一些有特殊含义的字符,如上面说的”*.txt”中的*,简单的说就是表示任何字符串的意思。如果要查找文件名中有*的文件,则需要对*进行转义,即在其前加一个。ls
*.txt。正则表达式有以下特殊字符。

 

特别字符 说明
$ 匹配输入字符串的结尾位置。如果设置了 RegExp 对象的 Multiline 属性,则
$ 也匹配 ‘n’ 或 ‘r’。要匹配 $ 字符本身,请使用 $。
( ) 标记一个子表达式的开始和结束位置。子表达式可以获取供以后使用。要匹配这些字符,请使用
( 和 )。
* 匹配前面的子表达式零次或多次。要匹配 * 字符,请使用 *。
+ 匹配前面的子表达式一次或多次。要匹配 + 字符,请使用 +。
. 匹配除换行符 n之外的任何单字符。要匹配 .,请使用 。
[ 标记一个中括号表达式的开始。要匹配 [,请使用 [。
? 匹配前面的子表达式零次或一次,或指明一个非贪婪限定符。要匹配 ? 字符,请使用 ?。

将下一个字符标记为或特殊字符、或原义字符、或向后引用、或八进制转义符。例如, 'n'
匹配字符 'n'。'n' 匹配换行符。序列 '' 匹配 "",而 '(' 则匹配 "("。
^ 匹配输入字符串的开始位置,除非在方括号表达式中使用,此时它表示不接受该字符集合。要匹配
^ 字符本身,请使用 ^。
{ 标记限定符表达式的开始。要匹配 {,请使用 {。
| 指明两项之间的一个选择。要匹配 |,请使用 |。

  •   构造正则表达式的方法和创建数学表达式的方法一样。也就是用多种元字符与操作符将小的表达式结合在一起来创建更大的表达式。正则表达式的组件可以是单个的字符、字符集合、字符范围、字符间的选择或者所有这些组件的任意组合。

 

3.4 限定符

  限定符用来指定正则表达式的一个给定组件必须要出现多少次才能满足匹配。有*或+或?或{n}或{n,}或{n,m}共6种。

*、+和?限定符都是贪婪的,因为它们会尽可能多的匹配文字,只有在它们的后面加上一个?就可以实现非贪婪或最小匹配。

  正则表达式的限定符有:

 

字符 描述
* 匹配前面的子表达式零次或多次。例如,zo* 能匹配 "z" 以及 "zoo"。*
等价于{0,}。
+ 匹配前面的子表达式一次或多次。例如,'zo+' 能匹配 "zo" 以及
"zoo",但不能匹配 "z"。+ 等价于 {1,}。
? 匹配前面的子表达式零次或一次。例如,"do(es)?" 可以匹配 "do" 或
"does" 中的"do" 。? 等价于 {0,1}。
{n} n 是一个非负整数。匹配确定的 n 次。例如,'o{2}' 不能匹配 "Bob" 中的
'o',但是能匹配 "food" 中的两个 o。
{n,} n 是一个非负整数。至少匹配n 次。例如,'o{2,}' 不能匹配 "Bob" 中的
'o',但能匹配 "foooood" 中的所有 o。'o{1,}' 等价于 'o+'。'o{0,}' 则等价于 'o*'。
{n,m} m 和 n 均为非负整数,其中n <= m。最少匹配 n 次且最多匹配 m
次。例如,"o{1,3}" 将匹配 "fooooood" 中的前三个 o。'o{0,1}' 等价于
'o?'。请注意在逗号和两个数之间不能有空格。

3.5 定位符

  用来描述字符串或单词的边界,^和$分别指字符串的开始与结束,b描述单词的前或后边界,B表示非单词边界。不能对定位符使用限定符。

3.6 选择

  用圆括号将所有选择项括起来,相邻的选择项之间用|分隔。但用圆括号会有一个副作用,是相关的匹配会被缓存,此时可用?:放在第一个选项前来消除这种副作用。

  其中?:是非捕获元之一,还有两个非捕获元是?=和?!,这两个还有更多的含义,前者为正向预查,在任何开始匹配圆括号内的正则表达式模式的位置来匹配搜索字符串,后者为负向预查,在任何开始不匹配该正则表达式模式的位置来匹配搜索字符串。

3.7 后向引用

  对一个正则表达式模式或部分模式两边添加圆括号将导致相关匹配存储到一个临时缓冲区中,所捕获的每个子匹配都按照在正则表达式模式中从左至右所遇到的内容存储。存储子匹配的缓冲区编号从
1 开始,连续编号直至最大 99 个子表达式。每个缓冲区都可以使用 'n' 访问,其中 n 为一个标识特定缓冲区的一位或两位十进制数。

  可以使用非捕获元字符 '?:', '?=', or '?!' 来忽略对相关匹配的保存。

4. 各种操作符的运算优先级

  相同优先级的从左到右进行运算,不同优先级的运算先高后低。各种操作符的优先级从高到低如下:

 

操作符 描述

转义符
(), (?:), (?=), [] 圆括号和方括号
*, +, ?, {n}, {n,}, {n,m} 限定符
^, $, anymetacharacter 位置和顺序
| “或”操作

5. 全部符号解释

字符 描述

将下一个字符标记为一个特殊字符、或一个原义字符、或一个
向后引用、或一个八进制转义符。例如,’n’ 匹配字符 “n”。’n’ 匹配一个换行符。序列 ” 匹配 “” 而 “(” 则匹配
“(“。
^ 匹配输入字符串的开始位置。如果设置了 RegExp 对象的 Multiline 属性,^
也匹配 ‘n’ 或 ‘r’ 之后的位置。
$ 匹配输入字符串的结束位置。如果设置了RegExp 对象的 Multiline 属性,$
也匹配 ‘n’ 或 ‘r’ 之前的位置。
* 匹配前面的子表达式零次或多次。例如,zo* 能匹配 “z” 以及 “zoo”。*
等价于{0,}。
+ 匹配前面的子表达式一次或多次。例如,’zo+’ 能匹配 “zo” 以及
“zoo”,但不能匹配 “z”。+ 等价于 {1,}。
? 匹配前面的子表达式零次或一次。例如,”do(es)?” 可以匹配 “do” 或
“does” 中的”do” 。? 等价于 {0,1}。
{n} n 是一个非负整数。匹配确定的 n 次。例如,’o{2}’ 不能匹配 “Bob” 中的
‘o’,但是能匹配 “food” 中的两个 o。
{n,} n 是一个非负整数。至少匹配n 次。例如,’o{2,}’ 不能匹配 “Bob” 中的
‘o’,但能匹配 “foooood” 中的所有 o。’o{1,}’ 等价于 ‘o+’。’o{0,}’ 则等价于 ‘o*’。
{n,m} m 和 n 均为非负整数,其中n <= m。最少匹配 n 次且最多匹配 m
次。例如,”o{1,3}” 将匹配 “fooooood” 中的前三个 o。’o{0,1}’ 等价于
‘o?’。请注意在逗号和两个数之间不能有空格。
? 当该字符紧跟在任何一个其他限制符 (*, +, ?, {n}, {n,}, {n,m})
后面时,匹配模式是非贪婪的。非贪婪模式尽可能少的匹配所搜索的字符串,而默认的贪婪模式则尽可能多的匹配所搜索的字符串。例如,对于字符串 “oooo”,’o+?’
将匹配单个 “o”,而 ‘o+’ 将匹配所有 ‘o’。
. 匹配除 “n” 之外的任何单个字符。要匹配包括 ‘n’ 在内的任何字符,请使用象
‘[.n]‘ 的模式。
(pattern) 匹配 pattern 并获取这一匹配。所获取的匹配可以从产生的 Matches
集合得到,在VBScript 中使用 SubMatches 集合,在JScript 中则使用 $0…$9 属性。要匹配圆括号字符,请使用
‘(‘ 或 ‘)’。
(?:pattern) 匹配 pattern
但不获取匹配结果,也就是说这是一个非获取匹配,不进行存储供以后使用。这在使用 “或” 字符 (|) 来组合一个模式的各个部分是很有用。例如, ‘industr(?:y|ies)
就是一个比 ‘industry|industries’ 更简略的表达式。
(?=pattern) 正向预查,在任何匹配 pattern
的字符串开始处匹配查找字符串。这是一个非获取匹配,也就是说,该匹配不需要获取供以后使用。例如,’Windows
(?=95|98|NT|2000)’ 能匹配 “Windows 2000″ 中的 “Windows” ,但不能匹配 “Windows 3.1″
中的
“Windows”。预查不消耗字符,也就是说,在一个匹配发生后,在最后一次匹配之后立即开始下一次匹配的搜索,而不是从包含预查的字符之后开始。
(?!pattern) 负向预查,在任何不匹配 pattern
的字符串开始处匹配查找字符串。这是一个非获取匹配,也就是说,该匹配不需要获取供以后使用。例如’Windows
(?!95|98|NT|2000)’ 能匹配 “Windows 3.1″ 中的 “Windows”,但不能匹配 “Windows 2000″
中的 “Windows”。预查不消耗字符,也就是说,在一个匹配发生后,在最后一次匹配之后立即开始下一次匹配的搜索,而不是从包含预查的字符之后开始
x|y 匹配 x 或 y。例如,’z|food’ 能匹配 “z” 或 “food”。’(z|f)ood’
则匹配 “zood” 或 “food”。
[xyz] 字符集合。匹配所包含的任意一个字符。例如, ‘[abc]‘ 可以匹配 “plain”
中的 ‘a’。
[^xyz] 负值字符集合。匹配未包含的任意字符。例如, ‘[^abc]‘ 可以匹配 “plain”
中的’p'。
[a-z] 字符范围。匹配指定范围内的任意字符。例如,’[a-z]‘ 可以匹配 ‘a’ 到 ‘z’
范围内的任意小写字母字符。
[^a-z] 负值字符范围。匹配任何不在指定范围内的任意字符。例如,’[^a-z]‘ 可以匹配任何不在
‘a’ 到 ‘z’ 范围内的任意字符。
b 匹配一个单词边界,也就是指单词和空格间的位置。例如, ‘erb’
可以匹配”never” 中的 ‘er’,但不能匹配 “verb” 中的 ‘er’。
B 匹配非单词边界。’erB’ 能匹配 “verb” 中的 ‘er’,但不能匹配
“never” 中的 ‘er’。
cx 匹配由 x 指明的控制字符。例如, cM 匹配一个 Control-M 或回车符。x
的值必须为 A-Z 或 a-z 之一。否则,将 c 视为一个原义的 ‘c’ 字符。
d 匹配一个数字字符。等价于 [0-9]。
D 匹配一个非数字字符。等价于 [^0-9]。
f 匹配一个换页符。等价于 x0c 和 cL。
n 匹配一个换行符。等价于 x0a 和 cJ。
r 匹配一个回车符。等价于 x0d 和 cM。
s 匹配任何空白字符,包括空格、制表符、换页符等等。等价于 [ fnrtv]。
S 匹配任何非空白字符。等价于 [^ fnrtv]。
t 匹配一个制表符。等价于 x09 和 cI。
v 匹配一个垂直制表符。等价于 x0b 和 cK。
w 匹配包括下划线的任何单词字符。等价于’[A-Za-z0-9_]‘。
W 匹配任何非单词字符。等价于 ‘[^A-Za-z0-9_]‘。
xn 匹配 n,其中 n
为十六进制转义值。十六进制转义值必须为确定的两个数字长。例如,’x41′ 匹配 “A”。’x041′ 则等价于 ‘x04′ &
“1″。正则表达式中可以使用 ASCII 编码。.
num 匹配 num,其中 num 是一个正整数。对所获取的匹配的引用。例如,’(.)1′
匹配两个连续的相同字符。
n 标识一个八进制转义值或一个向后引用。如果 n 之前至少 n 个获取的子表达式,则 n
为向后引用。否则,如果 n 为八进制数字 (0-7),则 n 为一个八进制转义值。
nm 标识一个八进制转义值或一个向后引用。如果 nm 之前至少有 nm 个获得子表达式,则
nm 为向后引用。如果 nm 之前至少有 n 个获取,则 n 为一个后跟文字 m 的向后引用。如果前面的条件都不满足,若 n 和 m
均为八进制数字 (0-7),则 nm 将匹配八进制转义值 nm。
nml 如果 n 为八进制数字 (0-3),且 m 和 l 均为八进制数字
(0-7),则匹配八进制转义值 nml。
un 匹配 n,其中 n 是一个用四个十六进制数字表示的 Unicode 字符。例如,
u00A9 匹配版权符号 (?)。

 

6. 部分例子

正则表达式 说明
/b([a-z]+) 1b/gi 一个单词连续出现的位置
/(w+)://([^/:]+)(:d*)?([^# ]*)/ 将一个URL解析为协议、域、端口及相对路径
/^(?:Chapter|Section) [1-9][0-9]{0,1}$/ 定位章节的位置
/[-a-z]/ A至z共26个字母再加一个-号。
/terb/ 可匹配chapter,而不能terminal
/Bapt/ 可匹配chapter,而不能aptitude
/Windows(?=95 |98 |NT )/ 可匹配Windows95或Windows98或WindowsNT,当找到一个匹配后,从Windows后面开始进行下一次的检索匹配。

 

7. 正则表达式匹配规则

7.1 基本模式匹配

  
一切从最基本的开始。模式,是正规表达式最基本的元素,它们是一组描述字符串特征的字符。模式可以很简单,由普通的字符串组成,也可以非常复杂,往往用特殊的字符表示一个范围内的字符、重复出现,或表示上下文。例如:

^once

  这个模式包含一个特殊的字符^,表示该模式只匹配那些以once开头的字符串。例如该模式与字符串”once upon a time”匹配,与”There once
was a man from NewYork”不匹配。正如如^符号表示开头一样,$符号用来匹配那些以给定模式结尾的字符串。

bucket$

  
这个模式与”Who kept all of this cash in a
bucket”匹配,与”buckets”不匹配。字符^和$同时使用时,表示精确匹配(字符串与模式一样)。例如:

^bucket$

  
只匹配字符串”bucket”。如果一个模式不包括^和$,那么它与任何包含该模式的字符串匹配。例如:模式

once

与字符串

There once was a man from NewYork
Who kept all of his cash in a bucket.

是匹配的。

  
在该模式中的字母(o-n-c-e)是字面的字符,也就是说,他们表示该字母本身,数字也是一样的。其他一些稍微复杂的字符,如标点符号和白字符(空格、
制表符等),要用到转义序列。所有的转义序列都用反斜杠()打头。制表符的转义序列是:t。所以如果我们要检测一个字符串是否以制表符开头,可以用这
个模式:

^t

类似的,用n表示“新行”,r表示回车。其他的特殊符号,可以用在前面加上反斜杠,如反斜杠本身用表示,句号.用.表示,以此类推。


7.2 字符簇

在INTERNET的程序中,正规表达式通常用来验证用户的输入。当用户提交一个FORM以后,要判断输入的电话号码、地址、EMAIL地址、信用卡号码等是否有效,用普通的基于字面的字符是不够的。


所以要用一种更自由的描述我们要的模式的办法,它就是字符簇。要建立一个表示所有元音字符的字符簇,就把所有的元音字符放在一个方括号里:

[AaEeIiOoUu]

这个模式与任何元音字符匹配,但只能表示一个字符。用连字号可以表示一个字符的范围,如:

[a-z] //匹配所有的小写字母
[A-Z] //匹配所有的大写字母
[a-zA-Z] //匹配所有的字母
[0-9] //匹配所有的数字

[0-9.-] //匹配所有的数字,句号和减号
[ frtn] //匹配所有的白字符

同样的,这些也只表示一个字符,这是一个非常重要的。如果要匹配一个由一个小写字母和一位数字组成的字符串,比如”z2″、”t6″或”g7″,但不是”ab2″、”r2d3″
或”b52″的话,用这个模式:

^[a-z][0-9]$

尽管[a-z]代表26个字母的范围,但在这里它只能与第一个字符是小写字母的字符串匹配。

前面曾经提到^表示字符串的开头,但它还有另外一个含义。当在一组方括号里使用^是,它表示“非”或“排除”的意思,常常用来剔除某个字符。还用前面的例子,我们要求第一个字符不能是数字:

^[^0-9][0-9]$

这个模式与”&5″、”g7″及”-2″是匹配的,但与”12″、”66″是不匹配的。下面是几个排除特定字符的例子:

[^a-z] //除了小写字母以外的所有字符
[^/^] //除了()(/)(^)之外的所有字符
[^"'] //除了双引号(“)和单引号(‘)之外的所有字符

特殊字符”.”
(点,句号)在正规表达式中用来表示除了“新行”之外的所有字符。所以模式”^.5$”与任何两个字符的、以数字5结尾和以其他非“新行”字符开头的字符串匹配。模式”.”可以匹配任何字符串,除了空串和只包括一个“新行”的字符串。


PHP的正规表达式有一些内置的通用字符簇,列表如下:

字符簇 含义
[[:alpha:]] 任何字母
[[:digit:]] 任何数字
[[:alnum:]] 任何字母和数字

[[:space:]] 任何白字符
[[:upper:]] 任何大写字母
[[:lower:]] 任何小写字母
[[:punct:]] 任何标点符号

[[:xdigit:]] 任何16进制的数字,相当于[0-9a-fA-F]

7.3 确定重复出现

到现在为止,你已经知道如何去匹配一个字母或数字,但更多的情况下,可能要匹配一个单词或一组数字。一个单词有若干个字母组成,一组数字有若干个单数组成。跟在字符或字符簇后面的花括号({})用来确定前面的内容的重复出现的次数。

字符簇 含义
^[a-zA-Z_]$ 所有的字母和下划线
^[[:alpha:]]{3}$ 所有的3个字母的单词
^a$ 字母a

^a{4}$ aaaa
^a{2,4}$ aa,aaa或aaaa
^a{1,3}$ a,aa或aaa
^a{2,}$ 包含多于两个a的字符串

^a{2,} 如:aardvark和aaab,但apple不行
a{2,} 如:baad和aaa,但Nantucket不行
t{2} 两个制表符

.{2} 所有的两个字符

这些例子描述了花括号的三种不同的用法。一个数字,{x}的意思是“前面的字符或字符簇只出现x次”;一个数字加逗号,{x,}的意思是“前面的内
容出现x或更多的次数”;两个用逗号分隔的数字,{x,y}表示“前面的内容至少出现x次,但不超过y次”。我们可以把模式扩展到更多的单词或数字:

^[a-zA-Z0-9_]{1,}$ //所有包含一个以上的字母、数字或下划线的字符串
^[0-9]{1,}$ //所有的正数
^-{0,1}[0-9]{1,}$ //所有的整数

^-{0,1}[0-9]{0,}.{0,1}[0-9]{0,}$ //所有的小数

最后一个例子不太好理解,是吗?这么看吧:与所有以一个可选的负号(-{0,1})开头(^)、跟着0个或更多的数字([0-9]{0,})、和
一个可选的小数点(.{0,1})再跟上0个或多个数字([0-9]{0,}),并且没有其他任何东西($)。下面你将知道能够使用的更为简单的方法。


特殊字符”?”与{0,1}是相等的,它们都代表着:“0个或1个前面的内容”或“前面的内容是可选的”。所以刚才的例子可以简化为:

^-?[0-9]{0,}.?[0-9]{0,}$

特殊字符”*”与{0,}是相等的,它们都代表着“0个或多个前面的内容”。最后,字符”+”与
{1,}是相等的,表示“1个或多个前面的内容”,所以上面的4个例子可以写成:

^[a-zA-Z0-9_]+$ //所有包含一个以上的字母、数字或下划线的字符串
^[0-9]+$ //所有的正数
^-?[0-9]+$ //所有的整数

^-?[0-9]*.?[0-9]*$ //所有的小数

当然这并不能从技术上降低正规表达式的复杂性,但可以使它们更容易阅读。

 

参考文献:


JScript 和 VBScript 正则表达式

微软MSDN上的例子(英文):


Scanning for HREFS

Provides an example that searches an
input string and prints out all the href=”…” values and
their locations in the string.

Changing Date Formats

Provides an example that replaces dates
of the form mm/dd/yy with dates of the form dd-mm-yy.

Extracting URL Information

Provides an example that extracts a
protocol and port number from a string containing a URL. For
example, “http://www.contoso.com:8080/letters/readme.html”
returns “http:8080″.

Cleaning an Input String

provides an example that strips invalid
non-alphanumeric characters from a string.

Confirming Valid E-Mail Format

Provides an example that you can use to
verify that a string is in valid e-mail format。

    有的哥们说,linux的自己安装的程序怎么办,每次还要进到目录里执行程序,能不能象系统默认安装的那些可以直接执行呢
答案当然是肯定的!
    比如假如我的Lumaqq。默认安装以后,在终端里执行lumaqq是没有用的。那么可以加一个连接到/usr/bin/lumaqq。。
这样系统默认搜索路径到/usr/bin执行程序就可以找到lumaqq了。。。
操作:ln -s /bak/softs/Lumaqq/lumaqq /usr/bin/lumaqq

(注:本文以Debian GNU/Linux为蓝本。各版本中个别路径用法等不同请自行查看修改。)
1、首先拷贝字体到系统字体目录下比如/usr/share/fonts/truetype/hahafonts(hahafonts请自行建立),我在Debian sid中:
(这里以大家都比较好找的windows字体为例。)
到win下找到你需要的字体,比如我拷了simhei.ttf simyou.ttf tahoma.ttf verdana.ttf simsun.ttc tahomabd.ttf verdanab.ttf等7款字体
当然,如果想要简单可以只拷simsun,tahoma就行了
cp *.tt* /usr/share/fonts/truetype/hahafonts/
cd /usr/share/fonts/truetype/hahafonts/


2、生成你字体的fonts.dir+fonts.scale文件

Debian下:

apt-get install ttmkfdir




ttmkfdir && cp fonts.scale fonts.dir




3、把字体路径加到您的xfree86文件中

比如我的/etc/X11/XF86Config-4

添加:

FontPath “/var/lib/defoma/x-ttcidfont-conf.d/dirs/TrueType”


FontPath “/var/lib/defoma/x-ttcidfont-conf.d/dirs/CID”


FontPath “/usr/share/fonts/truetype/gbk”


FontPath “/usr/share/fonts/truetype/hahafonts”


注意:::其中/usr/share/fonts/truetype/gbk中为我的其他点阵字体,您可以不加!!!



4、执行fc-cache -v -f
注:fc-cache — build font information cache files

5、firefly补丁:

debian下很简单,呵呵
http://hahaghost.512j.com/linuxbak/fonts.conf替换/etc/fonts/里的fonts.conf文件,然后加上源:

我的如下,当然,ustc.edu.cn的源也可的,但是我这里连不上。。

把下面2行加到您的/etc/apt/sources.list里

deb http://debian.okey.net/debian-uo/ sid firefly java marillat rareware misc


deb http://debian.okey.net/debian-fonts/ ./




然后执行apt-get update&&apt-get upgrade就行了。
注:执行apt-get upgrade后,自动升级的有:libfontconfig,libxft,fontconfig都是firefly大虾修改的过的补丁。。



然后重启,就可以可以看到比较合适的字体了

然后xfsfonts | grep gbk

查找您需要的字体,添加到gtkrc或者gtkrc.zh_CN中

其中的gbk是个例子,您可以换成您想要的,比如simsun等。。。

后记:很典型的Linux字体的安装,老鸟们或许会不屑一顾了,但是对新手或许有点意义吧哈,呵呵
欢迎指正。

What does FVWM stand for?? “Fill_in_the_blank_with_whatever_f_word_you_like_at_the_time Virtual Window Manager”

其实早都听说FVWM的强大。尤其对于我这样的完美主义者。但是一直迫于没时间。总在想,以后有空了再好好研究她,总之,她是我的了,跑不掉的,哈哈。

没想到,今天,今天终于受不了啦!

哈哈,我要用,我要征服FVWM,于是乎,辛苦的征程拉开了序幕。虽然以前也用过几天的FVWM,但那些都算是简单的尝试吧哈,呵呵。这次应该动真格的了。



不喜欢term里的man fvwm,于是到www.fvwm.org里,看html的man
pages,好长啊,走马观花看了一遍都花了我2个小时多。详细地址见这里:http:
//www.fvwm.org/documentation/manpages/unstable/fvwm.php

当然,她的FAQ也是不可不看的:http://www.fvwm.org/documentation/faq/



What does FVWM stand for?? “Fill_in_the_blank_with_whatever_f_word_you_like_at_the_time Virtual Window Manager”

Rob Nation (the original Author of FVWM)
doesn't really remember what the F stood for originally, so we
have several potential answers:

Feeble, Fabulous, Famous, Fast, Foobar, Fantastic, Flexible,
F!@#$%, Flashy, FVWM (the GNU recursive approach), Free, Final,
Funky, Fred's (who the heck is Fred?), Freakin', Flawed,
Father-of-all, Feivel (the mouse from "An American Tail"),
Frungy (hey, where does that come from?), Floppy, Foxy,
Frenzied, Funny, Fumbling etc.

Just pick your Favorite (hey, there's another one!), which will of
course change depending on your mood and whether or not you've run
across any bugs recently. I prefer Fabulous or Fantastic myself,
although I often use F!@#$% or Freakin' while debugging...

Recently 'Feline' is becoming popular. Perhaps this has something
to do with the discovery that four of the six core developers have
cats (averaging 1.17 cats)? Miaow.

Know what? I found another one while stroking my cats: FEEDING :-)

Check this link:
http://fvwm.org/fvwm-cats/



FVWM征程开始了!

最近又想深入的了解一下wget这个强大的downloader,,
下面是man wget的一段。本人翻译的不好,就不翻译了。 但请您不要轻视这个终端下的小工具。
Wget – The non-interactive network downloader.

   GNU Wget is a free utility for non-interactive download of files fromthe Web. 

It supports HTTP, HTTPS, and FTP protocols, as well as retrieval through HTTP proxies.

    Wget is non-interactive, meaning that it can work in the background, while the user is not logged on.

  This allows you to start a retrieval and disconnect from the system, letting Wget finish the work.
 By
con-trast, most of the Web browsers require constant user’s presence,
which can be a great hindrance when transferring a lot of data

wget常用参数如下

  GNY Wget ,一个非交谈式的网路抓档工具.

  用法: wget [选项]… [URL]…

  命令的引数使用长项目与短项目相同.

  启动:

  -V, –version显示Wget的版本并且离开.

  -h, –help显示这个说明档.

  -b, -background在启动之後跳到背景去.

  -e, -execute=COMMAND执行一个`.wgetrc’里面的COMMAND指令.

  纪录档与输入的档案:

  -o, –output-file=FILE纪录讯息到FILE去.

  -a, -append-output=FILE增加讯息到FILE去.

  -d, –debug显示除错的输出.

  -q, –quiet安静模式(不输入任何讯息).

  -v, –verbose冗长模式(这是内定值).

  -nv, –non-verbose关闭verboseness,但不是安静模式.

  -i, –input-file=FILE从FILE读取URL .

  -F, –force-html把输入的档案当作HTML.

  下载:

  -t, –tries=NUMBER设定重复尝试NUMBER次(0是无限制).

  -O –output-document=FILE把文件写到FILE里.

  -nc, –no-clobber不破坏已经存在的档案.

  -c, –continue重新取得一个已经存在的档案.

  –dot-style=STYLE设定取回状况的显示风格.

  -N, –timestamping不取回比本地旧的档案.

  -S, –server-response显示伺服器回应状况.

  –spider不下载任何东西.

  -T, –timeout=SECONDS设定读取时超过的时间为SECONDS秒.

  -w, –wait=SECONDS在取回档案时等待SECONDS秒.

  -Y, –proxy=on/off开启或关闭Proxy.

  -Q, –quota=NUMBER设定取回档案的定额限制为NUMBER个.

  目录:

  -nd –no-directories不建立目录.

  -x, –force-directories强制进行目录建立的工作.

  -nH, –no-host-directories不建立主机的目录.

  -P, –directory-prefix=PREFIX把档案存到PREFIX/…

  –cut-dirs=NUMBER忽略NUMBER个远端的目录元件.

  HTTP选项:

  –http-user=USER设http使用者为USER.

  –http0passwd=PASS设http使用者的密码为PASS.

  -C, –cache=on/off提供/关闭快取伺服器资料(正常情况为提供).

  –ignore-length忽略`Content-Length’标头栏位.

  –proxy-user=USER设USER为Proxy使用者名称.

  –proxy-passwd=PASS设PASS为Proxy密码.

  -s, –save-headers储存HTTP标头成为档案.

  -U, –user-agent=AGENT使用AGENT取代Wget/VERSION作为识别代号.

  FTP选项:

  –retr-symlinks取回FTP的象徵连结.

  -g, –glob=on/off turn file name globbing on ot off.

  –passive-ftp使用”passive”传输模式.

  使用递回方式的取回:

  -r, –recursive像是吸入web的取回–请小心使用!.

  -l, –level=NUMBER递回层次的最大值(0不限制).

  –delete-after删除下载完毕的档案.

  -k, –convert-links改变没有关连的连结成为有关连.

  -m, –mirror开启适合用来映射的选项.

  -nr, –dont-remove-listing不要移除`.listing’档.

  递回式作业的允许与拒绝选项:

  -A, –accept=LIST允许的扩充项目的列表.

  -R, –reject=LIST拒绝的扩充项目的列表.

  -D, –domains=LIST允许的网域列表.

  –exclude-domains=LIST拒绝的网域列表(使用逗号来分隔).

  -L, –relative只跟随关联连结前进.

  –follow-ftp跟随HTML文件里面的FTP连结.

  -H, –span-hosts当开始递回时便到外面的主机.

  -I, –include-directories=LIST允许的目录列表.

  -X, –exclude-directories=LIST排除的目录列表.

  -nh, –no-host-lookup不透过DNS查寻主机.

  -np, –no-parent不追朔到起源目录.

  范例一:mirror一个网站

  wget -r www.redhat.com

  范例二:mirror一个网站下的某个目录:

  wget -r www.redhat.com/mirrors/LDP

Linux的字体引擎已经统一采用fontconfig+xft2体系。Fontconfig负责字体的安装确认和匹配,xft2则负责字体渲染。这篇翻译的Fontconfig手册希望可以让大家更深入地了解Fontconfig的配置和机理。
原文:http://www.fontconfig.org/fontconfig-user.html

作者:Keith Packard , HP Cambridge Research Lab

翻译:Conner Mo  
(connermo@hotmail.com)  中国Linux公社 (www.linuxfans.org )



Fonts-conf



名称



fonts.conf – 字体配置文件





文件纲要




/etc/fonts/fonts.conf

/etc/fonts/fonts.dtd

~/.fonts.conf





描述



fontconfig 是提供系统范围内字体设置,定制和允许应用程序访问的函数库。



功能概述



fontconfig
包含两个基本的模块,即读取XML文件并建立内部配置的配置模块和接受请求的字体样板并返回最接近所需字体的匹配模块。



字体设置

fontconfig的配置模块由FcConfig 数据类型,libexpat和FcConfigParse
组成。它扫描一个XML树并将其中的数据处理成一个配置文件。从外部来看,函数库的配置就是生成一个有效的XML树并将其填充到FcConfigParse里。应用程序改变运行中的函数库配置的唯一途径就是添加字体和目录到用户的字体文件列表中。



这样做的目的就是让字体的配置变得相对静态,并且可以尽可能多地让其他应用程序共享。这种做法预计可以在应用程序相互传递字体名称的时候获得相对稳定的字体选择。XML被选为配置文件的标准格式是因为它是一个既便于外部程序编辑又可以保留正确结构和语法的格式。



字体的配置和字体的是分开的。需要采取自身特定匹配方式的应用程序可以从库中访问已有的字体并执行独立的匹配操作。这样做是为了让应用程序可以从字体库中
挑选并选定合适的库功能,而不是强迫他们选择这个库或者私有的设置机制。这种做法预计可以让所有应用程序的字体配置可以集中在一处。集中的字体配置可以标
准化和简化字体安装和定制。



字体属性




虽然字体样板可能包含任意基本属性,但还是有一些众所周知的属性及其附带的类型。Fontconfig利用这些属性来匹配和完成字体配置。其他属性则被用来为应用程序的渲染机制提供方便。


属性
类型
描述
family
String
字体家族名称 (宋体,仿宋体等)
style
String
字体风格,包括粗度(weight)和倾斜度(slant)。
slant
Int
倾斜度,分为Italic(斜体),
oblique(倾斜罗马体)或者roman(罗马体)
weight
Int
Light
(微粗),medium(稍粗),demibold(略粗),bold(粗)或者black(黑体)
size
Double
尺寸大小
aspect
Double
在微调(hinting)前水平拉伸字体
pixelsize
Double
像素大小
spacing
Int
间距,Proportial (可变),monospace
(等宽) 或者charcell (字符单元)
foundry
String
字体厂商名称
antialias
Bool
字体渲染是否采用抗锯齿功能
hinting
Bool
渲染引擎是否采用微调
verticallayout
Bool
采用竖直排版
autohint
Bool
采用自动微调代替普通微调
globaladvance
Bool
使用字体全局间距数据
file
String
存储字体的文件名称
index
Int
字体文件内的字体索引
ftface
FT_Face
使用指定的Freetype格式对象
rasterizer
String
正在使用的渲染引擎
outline
Bool
字型是否中空
scalable
Bool
字型是否可以放缩
scale
Double
尺寸->像素的放缩比例
dpi
Double
目标点数/英寸
rgba
Int
unkonw, rgb, brg, vrgb, vbgr,
none -子像素的几何排列
minspace
Bool
是否采用最小行间距
charset
CharSet
字体的编码
lang
String
字体支持的RFC-3066-style 语言列表。





字体匹配



Fontconfig用计算输入的字体样板和现有系统中字体的距离来实现字体匹配。最接近的字体将被选择。这样可以保证任何时候都能够返回一个字体,但不能保证它和所需要的样板类似。



字体的匹配是从应用程序所创建的样板开始的。请求字体的所有属性会被搜集到一个样板里。每个属性可以包含一个或多个值。它们按照优先等级排列。匹配列表前的被认为是比符和列表后的更加接近所需属性。



最初的字体样板会按照配置文件中的编辑指令按顺序修改。每个修改的过程包括匹配和其它一系列的编辑操作,并且每个匹配的过程都会执行相应的编辑操作。



当字体样板编辑修改完后,将会执行一系列默认的替换操作,从而标准化已有的一套属性。这样可以避免较低层程序在渲染的时候为不同的字体属性提供一成不变的默认值。



标准化后的字体样板最后将和系统所有拥有的字体进行匹配。样板和字体的距离是用它的每个属性,厂商,编码,家族,语言,间距,像素大小,风格,斜度,粗度,防锯齿,渲染引擎和中空测量出来的。这个列表是按照优先级排序的,排在前面的元素比后面的元素占的比重大。

 

这个规则中有一个特殊的例子:家族的名称分成两个部分,strong(强)和weak
(弱)。强家族名称在匹配中比语言元素优先级要高,而弱家族名称在匹配中比语言元素的优先级别要低。这样允许在文档指定字体都不存在的时候,文档的语言属性可以指导字体的选择。



代表所属字体的样板会包含所有在那个样板找到的属性,而不只是在字体中找到的。这允许应用程序通过匹配系统传送渲染指令和其它数据。最后,在配置文件中找到字体的编辑指令列表将被应用到样板。修改过的样板会返回给应用程序。



返回的值包括充足的字体定位和渲染信息,包括文件名,像素大小和其他渲染数据。因为没有任何包含的信息属于Freetype库,引用程序可以自由选择渲染引擎,甚至直接获取和访问字体文件。



在编辑文件中,匹配和编辑的序列是按照两步执行的,
因为需要有两个不同操作。第一步是修改如何选取字体,为字体家族取别名和添加合适的默认值。第二步是修改如何渲染已选择的字体。这些步骤必须应用在已选择的字体上,而不是原有的字体样板,因为经常会发生错误的匹配。



字体名称



Fontconfig
为样板提供一个可以让函数库接受和产生的文本表达。表达有三个部分,第一个是字体家族名称列表,第二个是尺寸大小列表,最后是附加属性列表:



<families>-<point
sizes>:<name1>=<values1>:<name2>=<values2>…

<家族名称>-<尺寸大小>:<名称1>=<赋值1>:<名称2>=<赋值2>…



在列表中的赋值用逗号分开。名称不需要包含家族或者尺寸大小,它们可以省略。另外,还有一些字符常量可以同时说明名称和赋值。这里有一些例子:


名称
含义
Times-12
尺寸12的Times Roman
Times-12:bold
尺寸12的Times粗体
Courier:italic
Courier默认尺寸的斜体
Monospace:matrix=1 .1 0 1
用户首选的采用人工斜体的等宽字体





语言标记



每种在数据库中的字体包括一个它所支持的语言列表。这是用比较字体的unicode范围和语言的正词法(orthography)计算出来的。语言使用一个兼容RFC-3066的命名标准并且具有两个部分——ISO693语言标记跟一个连字符,然后是ISO3166国家代码。连字符和国家代码可以省略。



Fontconfig在函数库中有几种语言的正词法。除了重新编译函数库外,还没有其他途径添加新的正词法。Fontconfig现在支持ISO639-1中命名的139种语言的122种,ISO
639-2的141种有双字符编码的语言和另外30种三字符编码的语言。



配置文件的格式



Fontconfig的配置文件的存储格式为XML格式。这种格式可以让延伸的配置工具更加方便的编写并且可以保证他们可以生成语法结构正确的文件。由于XML文件是纯文本文件,专家用户可以用文本编辑器处理它们。



Fontconfig
文件类型定义在延伸的实体“fonts.dtd”中,通常存储在默认的字体设置目录(/etc/fonts)。每个配置文件必须包括下列的结构:



    <?xml version=”1.0″?>

    <!DOCTYPE fontconfig SYSTEM “fonts.dtd”>

    <fontconfig>

    …

    </fontconfig>



<fontconfig>



这是字体配置顶层的单元,可以按照任意顺序包括dir, cache, include, match和alias单元。



dir

这个单元包含一个会被扫描目录名称,扫描到字体文件将被包括到可用的字体列表中里。



cache

这个单元包含一个为每个用户设置的缓存字体信息的文件名称。如果它以“~”开始的话,代表一个在用户主目录的文件。这个文件是用来保留在为每个目录设置的
缓存文件中没有的字体信息的。Fontconfig将会自动处理缓存文件。默认的缓存文件是“~/.fonts.cache-version”,这里
version是字体配置文件的版本号。(目前是1)。



include ignore_missing=”no”



这个单元包含一个附加的配置文件名称。当XML数据类型被FcConfigParse扫描处理后,这个文件的内容也将会通过传送文件名称到
FcConfigLoadAndParse,从而被包括在配置中。如果“ignore_missing”设成“yes”而不是默认的“no”的话,一个丢
失的文件将不会引起函数库的警告信息。



config



这个单元提供一个整合附加的配置信息的地方。config可以按照任意顺序包含blank和rescan单元。



blank



字体通常包含“破碎”的字型,它们在编码中存在但在屏幕上却被绘制成空白。我们在blank单元中放置每个预计是空白的unicode字符到int单元中。这些绘制为空白的字符将从字体支持的字符集中忽略。



rescan



rescan单元存放一个表示自动扫描字体配置文件变化间隔时间的int单元。每次间隔过后,Fontconfig都将验证所有的配置文件和目录并且自动重建内部的数据结构




match target=”pattern”



这个单元先存放(可能是空的)test元素列表,然后是一个edit元素列表(也可能是空的)。匹配检测(test元素)条件的样板将受到
edit元素列表的影响。如果“target”设定为“font”而不是默认的“pattern”的话,那么这个单元就将应用到一个匹配后的字体名称,而
不是一个需要匹配的字体样板。



test qual=”any” name=”property”
compare=”eq”




这个单元包含一个单独的值,用来和样本的属性“property”比较(可以替换property为任意一个上面列出的属性)。
“compare”可以是“eq”(等于),“not_eq”(不等于),“less”(小于),“less_eq”(小于等于),“more”(大
于),“more_eq”(大于等于)。“qual”可以为默认的“any”,在这种情况下,只要任意一个之字体属性符合比较的值,匹配就成功。如果
“qual”为“all”的话,只有当所有的字体属性都符合比较的值的时候,匹配才成功。



edit name=”property” mode=”assign”
binding=”weak”




这个单元包括一个表达式单元的列表(任何赋值和操作单元)。表达式单元将在运行的时候被执行并且将修改属性“property”。是否修改依赖于
“property”的值是否匹配相应的test单元。如果匹配的话,这个修改将会影响第一个匹配的值。任何插入到属性的值都可以给出绑定
(binding)说明。“mode”可以是以下列表其中的一个:


Mode
有匹配条件
没有匹配条件
“assign”
替换匹配的值
替换所有值
“assign_replace”
替换所有值
替换所有值
“prepend”
在匹配前插入
在列表头部插入
“prepend_first”
在列表头部插入
在列表头部插入
“append”
在匹配后添加
在列表底部添加
“append_last”
在列表底部添加 在列表底部添加





int, double, string, bool



这些单元保存单独一个声明的类型。bool
单元保存true或者false。在赋浮点数的时候有一个重要的限制——fontconfig要求尾数必须以一个数字开始,而不是一个小数点,所以应该碰到纯小数的时候应该插入一个起始的”0″。(例如用0.5而不是.5,-0.5而不是-.5。)



matrix



这个单元保存一个防射变换的四个double元素。



name



保存一个属性名称。从字体属性的第一个值判断出来的,而不是样板的第一个值。



const



保存一个常量的名称。以下这些数值总是整数并且作为一般字体值的字符表达。


常量
属性

light
weight
0
medium
weight 100
demibold
weight
180
bold
weight
200
black
weight
210
roman
slant
0
oblique
slant
110
proportional
spacing 0
mono
spacing
100
charcell
spacing
110
unknow
rgba
0
rgb rgba
1
bgr
rgba
2
vrgb
rgba
3
vbgr
rgba
4
none
rgba
5





or(与), and(或), plus(加), minus(减),
times(乘), divide(除)




这些元素在一个表达试列表上执行特定的操作。or和and是布尔操作,不是位操作。



eq(等于), not_eq(不等于), less(小于),
less_eq(小于等于), more(大于), more_eq(大于等于)




这些元素比较两个值,产生一个布尔值。



not



对一个表达式的布尔值进行“非”操作。



if



这个单元包含三个表达单元。如果第一个单元为真,则产生第二个单元的值,否则产生第三个单元的值。



alias



Alias
(别名)单元为需要替代一个字体家族名称到另一个的一套通用匹配操作提供简化符号。它们包含一个family单元,紧跟着是可选的prefer,
accept和default单元。匹配family单元的字体将被编辑,使得prefer家族在匹配family的前面,accept家族在匹配的
family后面并且default家族在家族列表的最后。



family



保存一个单独的字体家族名称



prefer, accpet, default 



这些单元保存一个让alias单元使用的字体列表。



配置文件举例


系统配置文件

这是一个系统范围的配置文件例子

<?xml version="1.0"?>
<!DOCTYPE fontconfig SYSTEM "fonts.dtd">
<!-- /etc/fonts/fonts.conf 配置系统自体的文件 -->
<fontconfig>
<!--
在以下目录寻找字体
-->
<dir>/usr/X11R6/lib/X11/fonts/truetype</dir>
<dir>/usr/X11R6/lib/X11/fonts/Type1</dir>

<!--
接受不受欢迎的'mono'别名,用'monospace'替代它。
-->
<match target="pattern">
<test qual="any" name="family"><string>mono</string></test>
<edit name="family" mode="assign"><string>monospace</string></edit>
</match>

<!--
没有使用众所周知别名的名称将用'sans'赋值。
-->
<match target="pattern">
<test qual="all" name="family" mode="not_eq">sans</test>
<test qual="all" name="family" mode="not_eq">serif</test>
<test qual="all" name="family" mode="not_eq">monospace</test>
<edit name="family" mode="append_last"><string>sans</string></edit>
</match>

<!--
读入用户配置文件,如果不存在的话不发出警告信息。
-->
<include ignore_missing="yes">~/.fonts.conf</include>

<!--
创建众所周知的字体名称别名到可用的Truetype字体。
将Type1字体类别替代为Truetype字体类别可以提高屏幕显示质量。
-->
<alias>
<family>Times</family>
<prefer><family>Times New Roman</family></prefer>
<default><family>serif</family></default>
</alias>
<alias>
<family>Helvetica</family>
<prefer><family>Verdana</family></prefer>
<default><family>sans</family></default>
</alias>
<alias>
<family>Courier</family>
<prefer><family>Courier New</family></prefer>
<default><family>monospace</family></default>
</alias>

<!--
为标准名称提供所需的别名。
在用户文件后面进行可以让所有的别名都可以使用所推荐的别名。
-->
<alias>
<family>serif</family>
<prefer><family>Times New Roman</family></prefer>
</alias>
<alias>
<family>sans</family>
<prefer><family>Verdana</family></prefer>
</alias>
<alias>
<family>monospace</family>
<prefer><family>Andale Mono</family></prefer>
</alias>
</fontconfig>
用户配置文件

这是一个以用户为单位的字体配置文件例子,文件名为 ~/.fonts.conf

<?xml version="1.0"?>
<!DOCTYPE fontconfig SYSTEM "fonts.dtd">
<!-- ~/.fonts.conf 用户的字体配置文件 -->
<fontconfig>

<!--
用户字体文件目录
-->
<dir>~/misc/fonts</dir>

<!--
使用rgb子像素显示顺序来提高字型在液晶显示器上的显示效果。效果会影响渲染,
但不会影响匹配。记得应该总是使用target="font"。
-->
<match target="font">
<edit name="rgba" mode="assign"><const>rgb</const></edit>
</match>
</fontconfig>

文件

fonts.conf   
   
包含了fontconfig函数库的配置信息,其中有用来寻找字体及相关信息的目录名称,还有在尝试匹配现有字体前执行的字体样板编辑指令。它使用的是xml格式。

fonts.dtd    
    是一个描述配置文件格式的DTD文件。

~/.fonts.conf  
是当前用户字体配置的默认位置,实际的位置可以在fonts.conf文件里指定。

~/.fonts.cache-*
是在没有发现字体目录中的缓存文件时,在当前用户目录存储字体信息的文件。这个文件是fontconfig自动维护的。



版本号

Fontconfig version2.2.0


引言


「為什麼我把 xxx 升了之後字就變難看了?」


「X 的字真是又醜又難設」



「Fontconfig Xft Freetype 到底是什麼關係啊!?!?」



螢幕上的字是用電腦的人整天會看到的,而用螢幕上有限的像素來有效顯示文字,又要提高文字的可讀性一直不容易。除了點陣字外,早在 80 年代就有的 anti-alias 也使得情況變得很複雜,即使已經過了 20 年,由於



1、各人的視覺喜好不同 – 沒有一種樣式可以使每一個人都滿意


2、不同的操作環境與平台以及顯示用的裝置 (CRT || LCD)


3、多國語言文字的同時顯示


所以能夠隨著自己的喜好而設定的字型是挺重要的。在各家 X desktop, toolkit 與瀏覽器的戰國時代,前後出現了許多解決方案,而
Fontconfig 是到目前為止,算是廣為被支援的一種新的不錯的方式,姑且一試,也許它還不能完全令你滿意,不過比起從前是來得有彈性多了。


警告


萬一本文有更新的版本, 也許可以在 http://fractal.csie.org/~eric/fontconfig 找到,任何使用本文中提及的方法所造成之社會成本損失將不會被負責。



版權聲明


在保留此版權聲明及原作者的情況下, 本文可以被任意轉錄。有關於更詳細的條件請見: http://creativecommons.org/licenses/by-nc-sa/1.0/ — EricCheng



See also:


Wprint 中文列印 Patch 與 freetype




Fontconfig


晚近的 XFree86 除了有了 freetype 的內建,加強了對於 TrueType 等向量字型的支援外,最近 Keith Packard
的 Xft 與 Fontconfig 也是一個對於字型整合所做的嘗試,在最新的 XFree86 4.3.x 與
freetype/Xft2/Fontconfig 的支援下,X 下的程式對於一個統一的字型選擇與繪製介面又進了一步。

雖然 XFree86 本身包含 Fontconfig, Fontconfig 事實上是一個可以獨立出來的介面,它是一個 library
不是一套 user app, 它所做的就是提供一套 font matching 的機制,讓使用 Fontconfig
的程式可以不必自己實作一套字型的選取方法。如此只要使用 Fontconfig
的程式愈多,單一的一套設定檔就可以被用在愈多的應用程式,應用程式本身可以利用 Fontconfig
所得到的字型名稱去畫字,也可以架構在自己原先的字型選擇架構之上 (如 Qt), 以達成對舊的設定的一定的向後相容性。



Fontconfig 有許多好處,例如:



字型的安裝。與其把要用的字型拿來放在一個目錄, 然後用 ttfmkdir / defoma / ttfm 等東西生出 fonts.dir
再指給 xtt/freetype, 再重新啟動 X font server 或 xset fp rehash, 現在只要把字型丟或
symlink 到 ~/.fonts 或任何其他經過指定的目錄, 就可以 _立即_ 開始使用了。當然在使用沒有支援 Fontconfig
的程式時, 仍然要用傳統的方法。Fontconfig 除了可以吃 TrueType, 也可以吃 Type1 或 pcf 等等傳統的點陣字。

字型 matching 的設定。雖然 Fontconfig 已經附上了一套不錯的設定檔讓在未被設定的情況下也都能夠有一個可以使用的系統,但其實對於個別字型的設定更有彈性。這個是透過 Fontconfig 所使用的 xml 設定檔達成的。稍後再說。


Fontconfig 會儘可能找出一套字,可以滿足顯示不同語言的需求。



Xft


Xft 也是一套 library, 它使用 Fontconfig match 到了所要的字型之後, 來決定該如何畫這些字。Xft
會看情況而決定要不要使用 core protocol 或 XRender 來畫字。XRender 是 XFree86 4.x 新增的
extension, 我認為這是為了保留 X 的向後相容性所新增的一個 hack, 不過因為它可以用來畫 anti-aliased
的字,目前的使用愈來愈廣泛。不過 anti-aliased text 只有在使用向量字型的時候有用, 繪製點陣字的時候就要使用 core
lib. Core library(以 x-truetype 或 freetype 作為
backend)自然也是可以畫向量字,只不過畫出來的就不能有 anti-aliased 的效果了。

有時當 XRender 不能使用時(如你是透過網路用一個舊的 X server 來執行 X apps), Xft 也可以使用 core lib 來畫字。應用程式不必為這些問題操心,達到資訊隱藏、各制湔哪康摹�




Freetype


Freetype 是一個很棒的畫字函式庫,XFree86 4.3 內含了 2.1.2. Freetype 提供 Xft
如何畫字的資訊,包括處理 anti-aliasing 或 hinting. 因此 freetype 的改變會影響到 Xft 畫出來的字,而
Fontconfig 的改變會影響到 Xft 如何去選字來畫。



fonts.conf


這裡所講的就是最新的 Fontconfig 與 Xft2 的設定。對於舊的 Xft1.0 的 ~/.xftconfig 就不提了。


如果你裝了 fontconfig, 那麼它應該已經附上了一套預設的設定檔。可以到 /etc/fonts/ (一些 Linux
distributions) 或 /usr/X11R6/etc/fonts (一些 BSD flavors) 底下找找看 fonts.conf
這個檔案。



fonts.conf 是簡單的 xml 格式,在 etc/ 裡面的 fonts.conf 是 system-wide
的設定,一般不建議直接更改它,可以更改 local.conf 或是自己家目錄下面的 ~/.fonts.conf . 關於 fonts.conf
的各種語法,由於 manpage 裡頭已經寫得很詳盡,所以這裡只是提及比較重要的一些部份,有興趣者可以 man fonts-conf.
所有的設定都放在 <fontconfig> 與 </fontconfig> 之間,而其中可以包含許多 tags,
詳細的 tags 可以參照 fonts.dtd 或者是 manpage.



<dir> 裡面是一個路徑,fontconfig 會自己遞迴地去找這個路徑裡頭的所有字型,如: <dir>/foo/bar/myfonts</dir>



<include> 可以把其他的設定檔引進來,它們的格式是一樣的。



其中最重要的 element 應該是 <match> 了。match 主要有兩種用法, 一種是 pattern match,
另一種是 font match. 前者會把所有的字型 match
出來,所以針對它的更改會套用到所有的字型的選擇方式上。為什麼要更改字型的屬性? 因為這樣可以針對個別的字型告訴 Fontconfig
該如何去處理這些字型,或是告訴 renderer 該如何去畫這些字型。這裡是一些常用到屬性的列表,關於所有的屬性請洽 manpage:




family – String – 就是一般所看到的字型的名稱了, 如 Arial


style – String – 字型的 style, 像是 Regular, Bold, Italic…


spacing – Int – 字型的寬度, Proportional 是有不同的寬度, monospace 是單一的寬度 (如 terminal 的字型)


antialias – Bool – 決定該字型是否要被 anti-alias 繪製; 只能用在向量字型上


hinting – Bool – 決定該字型是否要打開 hinting


autohint – Bool – 決定是否要用 Freetype 自己的 hint 方法來 hint 字型, 還是用預設的方法來 hint


rgba – Bool – 決定是否要用 subpixel 的方式來畫字, 可以是 none (只用灰階), rgb, bgr, vrgb, vbgr


Hinting 用來最佳化字型顯示的方法。由於螢幕的像素有限,向量字型的縮放需要有更多的考量, 例如當一條線位在兩個像素格子中間時,
該取左邊的格子還是右邊的格子? 如果這方面的控制沒有做好,就常常會出現字型的襯線沒有對齊,或是小字歪七扭八的情況。 Hinting
是額外的資訊, 它告訴 renderer 該如何處理這些細節的部份,使得向量字在小字的時候能夠好看。也因此 Hinting
是非常費時費人力的工作,TrueType 字型很多,但是有良好 Hinting 的字型不多。拙劣的 Hinting 就會讓字變得很難看。



為了稍微改善這個問題,freetype 有 autohint 的功能,可以自動為沒有 hint 的字型做 hinting 的工作。另外由於
TrueType 的 hinting 是有專利的,不能完全自由地使用, autohint 就不受這個限制。autohint
自然無法做得像人力的 hint 一樣好,不過至少比沒有 hint 要好些。話雖如此,對於許多筆劃複雜的文字 (如中文) 目前 freetype
的 autohint 還做得不甚完美,而因為建立完整的 hinting 的難度,即使是英文字,原本就很高,內建有 hinting
的中文字型就少之又少了。所以常常有人抱怨中文字在螢幕上很難看,就是沒有理想 hinting, 或者是使用了 autohinter
所造成的一些反效果。



Anti-alias 是將字型在幕後先以數倍的大小來繪製,然後再縮成想要的大小,未滿一格的格子用灰階補點。由於原本 X 所支援的 logic
咚悴环笫褂茫圆庞� XRender 的 extension 來達成目的。除了一般的 Anti-alias 之外,Xft 還支援了為 LCD
所設計的 subpixel rendering.



什麼是 subpixel rendering? 如果你用放大鏡去看 LCD,
會發現一個正方形的像素是由三個長方形小像素構成的。這排列通常是紅綠藍,也就代表如果液晶螢幕的水平解析度是 1024 個像素,它其實有
1024×3 = 3072 個點,只不過這些點是 rgbrgbrgb… 依序排列的。以白底黑字為例,如果需要滿格的像素,rgb
三格就需是全關 (0,0,0), 如果只是右邊三分之二部份, 就關掉 g 和 b, 留下最左邊的 r
開著。這樣子理論上就會有原來三倍的水平像素可以使用,大幅增加了液晶螢幕的解析度。但由於只開著紅色或黃色或其他顏色,會有很明顯的光暈,所以一般會採
用 filtering
的方式,把一個次像素的值往左右兩格分散(因為無論對哪一格次像素來說,它的左右兩格的顏色和本身都是不同的,所以往左右兩格分散可以均勻影響亮度),成
為 1/3, 1/3, 1/3 分佈;但這樣的壞處是會顯得太模糊了一點,於是再多一層,把原先三格分成 5 格,但權重改為 1/9 2/9
3/9 2/9 1/9。3/9
那一格就是原本的次像素,而鄰近的格子就用這樣的方法分散後和原來該次像素格子的光度值相加,達到像素往中央集中,卻又不太模糊的效果。Windows
XP 有個 ClearType 選項可以打開對液晶螢幕顯示最佳化,其基本原理就是 subpixel rendering. Xft
也有這樣的功能,不過 Xft 做得更多,除了 subpixel 外,還加上了 anti-aliasing。Fontconfig 的 rgba
選項就是設定液晶螢幕次像素的排列方式,一般都是 rgb, v
開頭的表示三種顏色是縱向排列。如果好奇的話可以拿放大鏡仔細瞧瞧,或用數位相機近拍下來放大觀察。



很多問題是出在 hinting, 因為許多時候, distribution 會把 freetype 的 bytecode hinting
打開,代表使用字型內部的 bytecode 來做 hinting 修正,如果像 freetype 預設沒有打開或是使用 freetype
裡頭的 autohinter, 有時效果不錯,有時卻不盡人意。另外 hinting 費時費力,大部分的字型設計師在做 hinting
的時候都只有針對點陣字的顯示做 hinting 的工作,這表示如果我們在顯示小字又用 anti-aliasing
的話,通常是不在字型設計師最佳化的範圍內的; 當 hinting 不當的時候,小字 anti-aliasing
就會顯得非常難看(如歪七扭八或擠成一團)。關於這方面 freetype 做了很多的努力, autohinter 也就是讓程式自己做
hinting 的演算法。由於 hinting 實在是個很棘手的問題,Mac OS X 對於 anti-aliasing 字型就都不使用
hinting. 好在 fontconfig 可以讓我們調整這些細部的設定,讓我們針對個別的字型做不同的處理。



話題回到 pattern match: 要使用 pattern match, 只需要加入如下的 pattern, 它就會對所有的字型作用:



<match target=”pattern”>





</match>


中間放的可以是一連串的 test, 然後是一連串的 edit. test 的用法是:




<test qual=”any|all|first|not_first”


name=”屬性”


compare=”eq|not_eq|less|less_eq|more|more_eq|contains|not_contains”>





</test>


any 指的是說, 只要字型的該屬性 list 之中有一項有符合要 test 的值, test 就會成立。all 的話要 list
之中所有的都符合,first 要第一個符合, not_first 要除了第一個以外有符合的。通常只會用到 any, 預設也是 any.
name 裡面填的就是前面所提的屬性, 如 name=”family”. compare 是比較的條件, eq 是相等, less 是小於,
以此類推。 <test> 所包住的那個值就是要用來比較的值,包括: int, double, string, matrix,
bool 等等。一旦 test 的條件都成立, 就會進行到 edit 的階段,代表編輯符合條件上述 test 條件的屬性:




<edit name=”屬性”


mode=”assign|assign_replace|prepend|append|prepend_first|append_last”>





</edit>


注意在 fontconfig 中, 屬性 (property) 可以是一個 list, 亦即一個屬性可有許多的值。 assign 是說把
match 到的值取代掉, assign_replace 是說把該 list 的所有值取代成指定的值, prepend 則是插在 list
中被 match 到的那個值的前頭, 以此類推。



fonts.conf 裡面有一個範例:




<match target=”pattern”>


<test name=”prefer_outline”>


<bool>true</bool>


</test>


<test name=”family”>


<string>Times</string>


</test>


<edit name=”family” mode=”prepend” binding=”same”>


<string>Times New Roman</string>


</edit>


</match>


這個 pattern match 是說, 當 prefer_outline 的值是 true 的時候, 而且字型的 family 又叫做
Times, 那麼就把它的 family list 前面加入 Times New Roman。這樣做的原因是, Times 本身是點陣字,
如果希望在許多應用程式指定用 Times 顯示時, 不要用點陣字顯示, 而要用 Times New Roman 這個 TrueType
字型顯示, 這樣可以把 Times New Roman 的優先權提在 Times 的前面。 Family matching 是另一種
match 方法,它的用法和 pattern matching 差不多,只是它是針對個別字型的屬性作修改,用法是:




<match target=”font”>





</match>


舉個例子,如果我想讓所有字型預設能夠打開 anti-aliasing, hinting 並且使用 subpixel rendering, 我就寫:




<match target=”font”>


<edit name=”antialias”><bool>true</bool></edit>


<edit name=”rgba” mode=”assign”><const>rgb</const></edit>


<edit name=”hinting”><bool>true</bool></edit>


</match>


但是我可能覺得 Luxi Mono 這個字型在某些時候, subpixel 不太好看, 我就寫:




<match target=”font”>


<test name=”family”><string>Luxi Mono</string></test>


<edit name=”rgba”><const>none</const></edit>


</match>



FAQ


Q. 我手上有很多 ttf, 我要怎麼裝它們?



前面說過啦, 把它們全部丟到 ~/.fonts/ 裡頭去吧。做 symbolic link 也可以。丟完之後就跑一下 fc-list 列出所有已安裝的字型看看有沒有在裡面。


Q. 我裝好了字型, 可是我的程式 (rxvt, aterm, gtk1.x) 卻不能使用它們?




因為這些程式是使用 X 的 core fonts, 不是使用 fontconfig 也沒有支援 Xft,
就沒有辦法享受這樣的便利,不過還是可以透過傳統的方式來裝這些字型。新的 gtk2, Gnome2, mlterm, Mozilla
(Firebird), Qt3.x 都支援了 fontconfig。

Q. 我想要使用新細明體,可以嗎?




可以, 把 mingliu.ttc 丟到 ~/.fonts 就行了。


Q. 我想要像 Windows 上小字那樣的新細明體,那是怎樣辦到的呢?為什麼在一些大小,新細明體的筆劃會破碎呢?




(新)細明體在 11, 12, 13, 15, 16, 20 點的大小有特別做內嵌的點陣字,換句話說,由於中文字的 hinting
不易,有時點陣字會比較有效。又因為新細明體使用了 bytecode 來組合筆劃, 沒有編進 bytecode interpreter 的
freetype 版本在 render 的時候,就會碎掉。請確定您系統上 freetype2 的 source 之中,
include/freetype/config/ftoption.h 裡面的
#defineTT_CONFIG_OPTION_BYTECODE_INTERPRETER 是不是有打開。也不可以使用內建的
autohinter. 由於是上述幾個特定的大小是內建點陣字型,所以沒有被 bytecode interpreter 影響。



確定了 freetype 有編進 bytecode interpreter 之後, 設定讓新細明體在這些大小時顯示內建的點陣字而不要用 anti-aliased, 可以在 ~/.fonts.conf 加入:



<match target=”font”>


<test name=”family”><string>PMingLiU</string></test>


<edit name=”antialias”><bool>true</bool></edit>


<edit name=”hinting”><bool>true</bool></edit>


<edit name=”autohint”><bool>false</bool></edit>


</match>


<match target=”font”>


<test name=”family”><string>PMingLiU</string></test>


<test name=”size” compare=”less_eq”><int>12</int></test>


<edit name=”antialias” mode=”assign”><bool>false</bool></edit>


<edit name=”hinting” mode=”assign”><bool>true</bool></edit>


</match>



Q. 我的細明體 (MingLiU) 的英文字和中文字會等寬?




因為 MingLiU 宣稱自己是 monospaced 字型,但實際上它有兩種寬度:中文的全形以及英文的半形。於是 freetype 就被騙了; 同樣的事情也發生在其他華康的一些字型上。Freetype 有個 globaladvance 的 flag:



<match target=”font”>


<test name=”family”><string>MingLiU</string></test>


<edit name=”globaladvance”><bool>false</bool></edit>


</match>



萬一因為不明的原因, 這樣做沒有用, 那麼還可以改 spacing:



<match target=”font”>


<test name=”family”><string>MingLiU</string></test>


<edit name=”spacing”><int>0</int></edit>


</match>



0 是 proportional 的 spacing, 100 是 mono, 110 是 charcell.


Q. 我想要把 Gnome2 選單的中英文字型分開設。




Gtk2 可以使用兩組特殊的 alias: Sans 和 Serif. Sans 是無襯線的意思,也就是如 Arial, Verdana
等等邊緣是方的字。Serif 則是有襯線的字,如 Times. 由於 fontconfig 有字型取代的機制, 可以修改
/etc/fonts/fonts.conf 裡面的這一段:



相關:


Screenshot



<alias>


<family>Bitstream Vera Sans</family>


<family>Helvetica</family>


<family>Arial</family>


<family>Verdana</family>


<family>Nimbus Sans L</family>


<family>Luxi Sans</family>


<family>Kochi Gothic</family>


<family>PMingLiU</family>


<family>AR PL KaitiM GB</family>


<family>AR PL KaitiM Big5</family>


<family>Baekmuk Dotum</family>


<family>SimSun</family>


<default><family>sans-serif</family></default>


</alias>



與這一段:



<alias>


<family>sans-serif</family>


<prefer>


<family>Bitstream Vera Sans</family>


<family>Verdana</family>


<family>Nimbus Sans L</family>


<family>Luxi Sans</family>


<family>Arial</family>


<family>Helvetica</family>


<family>Kochi Gothic</family>


<family>PMingLiU</family>


<family>AR PL KaitiM GB</family>


<family>AR PL KaitiM Big5</family>


<family>Baekmuk Dotum</family>


<family>SimSun</family>


</prefer>


</alias>



把想要加入替換 list 的字型加進去。排愈前面的字型, 在當他有符合要顯示的語言的文字的時候就會被用上,如我把 PMingLiU
設在文鼎字型前面,PMingLiU 就會在需要顯示中文的時候優先被選到。當然嚴格來說,PMingLiU 並不能算是 Sans-serif
而要算是 serif, 但因為我要跟 Bitstream Vera Sans 搭配,故放在一起。

Q. 我遇到了奇怪的問題,可是不知從何找起,怎麼辦?




XFT_DEBUG 這個環境變數可以顯示不同的偵錯資訊,打開一個 terminal, 把 XFT_DEBUG 設在要執行的程式之前,也許它可以幫助你找到問題。其中可以設的數值有:



XFT_DBG_OPEN 1


XFT_DBG_OPENV 2


XFT_DBG_RENDER 4


XFT_DBG_DRAW 8


XFT_DBG_REF 16


XFT_DBG_GLYPH 32


XFT_DBG_GLYPHV 64


XFT_DBG_CACHE 128


XFT_DBG_CACHEV 256


XFT_DBG_MEMORY 512



要同時開啟某幾個偵錯選項,就把它們的值相加就可以了。如 XFT_DEBUG=3 mozilla 就是以開啟第一和第二選項的模式來開啟
mozilla. 有趣的是,當 GLYPH 和 GLYPHV 同時開啟時, Xft 會在 console 用 ascii art
印出它所畫的字 Smile


Q. 我手上的字型都很難看。有什麼比較不錯的字型?




英文字型來說, Bitstream Vera Sans, Bitstream Vera Serif, Bitstream Vera Mono
都是高品質又是 free 的字型。Bitstream Cyberbit 可以免費取得(現在已經不是免費的了),又有頗完整的 Unicode
coverage, 包含中日韓等等的字集。另外 Microsoft 和 Monotype 買的 Verdana, Times New
Roman 等等也都具有漂亮的 hinting; Kochi Gothic 和 Kochi Mincho 是高品質的 free
日文字型。Arial Unicode MS 的 Unicode coverage 也很大,只是這套字型為了這麼大的 coverage,
相對地在許多地方,如筆劃與外觀,就必須做出一些犧牲。如果要拿來看中文的小字的話,目前最好把 hinting 關掉(中文字型大部分把
hinting 關掉會有比較令人高興的外觀,除了新細明體是一定要打開以外)

Q. 這份 FAQ 實在太沒有幫助了。我要找的問題都找不到。很多地方都寫錯了。



如果有寫錯的地方,為免再造成誤導,也請不吝指正。這裡是 wiki, 也可以直接點上面的 Edit this page 來加入自己的修改。


Q. 我照著這些方法設卻不能動。一切都太麻煩了!



要讓一切合自己的意要付出一定的代價。或許你可以找到一個會設的人,請他吃一頓飯或什麼的,然後找他來幫你照你的意思設。

最近还有一些哥们问:啥是Wiki呢?那么好吧,让我们来看看什么是Wiki。。。
“独乐乐不如众乐乐”,玩玩博客(
blog)已经不够过瘾,于是玩Wiki开始成为时尚。如今,有人将Wiki翻译为“维客”,在形声义方面,也算得上一个合格的中文译名。与大多数网络亚文化一样,Wiki也同样是体现开放,合作,平等,共享的网络文化!那么wiki究竟是什么玩意?你肯定不知道,我也才刚刚明白。但是,不要着急,让我们慢慢看下去,你就知道wiki很可能是互联网奉献的又一个让你疯狂的新生事物。

何为Wiki(维客)?

首先,我们要搞清楚:wiki概念的发明人是Ward Cunninghamwiki这个字到底是什幺意思呢?根据FAQ的说法,WikiWiki一词来源于夏威夷语的“wee kee wee kee”,原本是“快点快点” (quick)的意思。实际上 wiki 也真的是既简单又快速,你可以看到 wiki 每天都在成长。


新概念的定义总是让人有点摸不着头脑,wiki 也不例外。先看看简单解释:Wiki——一种多人协作的写作工具。Wiki站点可以有多人(甚至任何访问者)维护,每个人都可以发表自己的意见,或者对共同的主题进行扩展或者探讨。

还不明白,那就给你看看更复杂、更晕眩的解释:Wiki指一种超文本系统。这种超文本系统支持面向社群的协作式写作,同时也包括一组支持这种写作的辅助工具。我们可以在Web的基础上对Wiki文本进行浏览、创建、更改,而且创建、更改、发布的代价远比HTML文本为小;同时Wiki系统还支持面向社群的协作式写作,为协作式写作提供必要帮助;最后,Wiki的写作者自然构成了一个社群,Wiki系统为这个社群提供简单的交流工具。与其它超文本系统相比,Wiki有使用方便及开放的特点,所以Wiki系统可以帮助我们在一个社群内共享某领域的知识。

Wiki概念的通俗解说

还是有点云里雾里?那就通俗一点:根据 wiki 社群的定义,wiki 是一种提供「共同创作(collaborative)」环境的网站,也就是说,每个人都可以任意修改网站上的页面资料。这听起来挺疯狂的,万一有陌生人来网站上乱搞怎幺办?别担心,所有的 wiki 都有「版本控制(Version Control)」的概念,你随时都可以找回之前的正确版本;更何况你可不是单打独斗,社群的力量是非常惊人的。就在这种相信人性本善的概念下,整个 wiki 社群迅速地成长茁壮。如果你还是很担心,更可以帮 wiki 加入权限管理(Access Control)的机制,保证万无一失。除了版本控制之外,值得一题的是「格式化语法(Formating Rule)」。因为对一般人来说,HTML 语法实在是个恶梦,所以 wiki 创造了一套更简单的写作语法,让大家可以专注在写作上。

你还是不明白,那也不要紧,我们就先不要咬文嚼字,还是以一种看热闹的从容心态,先慢慢看下去。

Wiki发展历史

Wiki的历史还不长,无论是Wiki概念自身,还是相关软件系统的特性,还都在热烈的讨论中;所以怎样的一个站点才能称得上是一个Wiki系统还是有争议的。与Wiki相关最近出现的技术还有blog,它们都降低了超文本写作和发布的难度。这两者都与内容管理系统关系紧密。第一个 Wiki 网站诞生于 1995 年,Ward Cunningham 创建的,作为波特兰的模式仓库的模式定义和讨论的交互性场所: http://c2.com/ppr/;而其根源可以上述到 1972 年卡耐基-梅隆大学的 ZOG 数据库系统。

1995Ward Cunningham为了方便模式社群的交流建立了一个工具-波特兰模式知识库(Portland Pattern Repository)。在建立这个系统的过程中,Ward Cunningham创造了Wiki的概念和名称,并且实现了支持这些概念的服务系统。这个系统是最早的Wiki系统。从1996年至2000年间,波特兰模式知识库围绕着面向社群的协作式写作,不断发展出一些支持这种写作的辅助工具,从而使Wiki的概念不断得到丰富。同时Wiki的概念也得到了传播,出现了许多类似的网站和软件系统。

历史资料:http://c2.com/cgi/wiki?WikiHistory

Wiki可以做什幺?

说法1wiki可以说是一种建站的工具,wiki考虑让更多人参与建设,因此它的语法与HTML相比要容易的多,几乎与普通写字板编辑文字差不多,很容易上手。w iki最适合做百科全书、知识库、整理某一个领域的知识等知识型站点,几个分在不同地区的人利用wiki协同工作可以共同写一本书。我们计划用w iki来编辑一部elearning百科全书,有兴趣的朋友可以与我联系,我们可以共同编辑。

说法2:首先会想到的当然是共笔系统(例如 FreeBSD 共笔 )、读书会、项目开发、写书、翻译、资料整理(例如网站设计资源)、常见问题整理等等,这些本来就非常适合一群人来做。其次你可以想想怎幺样来利用版本控制的功能,例如拿来整理想法(可以时常比对旧版本)、写作业、记上课笔记等等。甚至有人用 wiki 写百科全书喔!如果你还想到可以怎幺玩,欢迎告诉我。

Wiki 是什么做到的?

l Wiki 使用了简化的语法,替代复杂的 HTML,加上 WEB 界面的编辑工具,降低内容维护的门槛;

l Wiki 通过文本数据库或者关系型数据库实现了版本控制,可以随时找回以前的版本,也可以和以前的版本进行对比,版本控制使多人协作成为可能,又保护了内容不会丢失;

l 任何信息都可以被任何人修改和删除,页面内容保持了一致性,因为清除垃圾文字、广告是那么的容易,最终剩下的是最有意义的内容;任何人都可以参与,但是最后剩下的是最好的参与者;

l Wiki 通过协作精神,实现了快速的信息整合;“Wiki” 这个单词本身来自于夏威夷语,就是快速的意思,“WikiWiki”自然就是极快的意思了。

Wiki技术和规范

wiki是任何人都可以编辑的网页。在每个正常显示的页面下面都有一个编辑按钮,点击这个按钮你就可以编辑页面了。有些人要问:任何人都可以编辑?那不是乱套了幺?其实不然,w iki体现了一种哲学思想:“人之初,性本善”。wiki认为不会有人故意破坏wiki网站,大家来编辑网页是为了共同参与。虽然如此,还是不免有很多好奇者无意中更改了w iki网站的内容,那幺为了维持网站的正确性,wiki在技术上和运行规则上做了一些规范,做到既持面向大宗公开参与的原则又尽量降低众多参与者带来的风险。这些技术和规范包括:

1)保留网页每一次更动的版本,即使参与者将整个页面删掉,管理者也会很方便地从纪录中恢复最正确的页面版本。

2)页面锁定,一些主要页面可以用锁定技术将内容锁定,外人就不可再编辑了。(虽然wiki都有这个功能,但我看到使用它的甚少,这可能跟w iki倡导的精神相违背吧)。

3)版本对比,wiki站点的每个页面都有更新纪录,任意两个版本之间都可以进行对比,wiki会自动找出他们的差别。

4)更新描述,你在更新一个页面的时候可以在描述栏中写上几句话,如你更新内容的依据、或是跟管理员的对话等。这样,管理员就知道你更新页面的情况。

5IP禁止,尽管wiki倡导“人之初,性本善”,人人都可参与,但破坏者、恶作剧者总是存在的,wiki有纪录和封存IP的功能,将破坏者的I P纪录下来他就不能在胡作非为了。

6Sand Box(沙箱)测试,一般的wiki都建有一个Sand Box的页面,这个页面就是让初次参与的人先到Sand Box页面做测试,Sand Box与普通页面是一样的,这里你可以任意涂鸦、随意测试。

7)编辑规则,任何一个开放的wiki都有一个编辑规则,上面写明大家建设维护wiki站点的规则。没有规矩不成方圆的道理任何地方都是适用的。

Wiki的特点

使用方便

l 维护快捷:快速创建、存取、更改超文本页面(这也是为什幺叫作 “wiki wiki” 的原因)。

l 格式简单:用简单的格式标记来取代 HTML 的复杂格式标记。(类似所见即所得的风格)

l 链接方便:通过简单标记,直接以关键字名来建立链接(页面、外部连接、图像等)。

l 命名平易:关键字名就是页面名称,并且被置于一个单层、平直的名空间中。

有组织

l 自组织的:同页面的内容一样,整个超文本的组织结构也是可以修改、演化的。

l 可汇聚的:系统内多个内容重复的页面可以被汇聚于其中的某个,相应的链接结构也随之改变。

可增长

l 可增长:页面的链接目标可以尚未存在,通过点击链接,我们可以创建这些页面,从而使系统得到增长。

l 修订历史:记录页面的修订历史,页面的各个版本都可以被获取。

开放性

l 开放的:社群的成员可以任意创建、修改、删除页面。

l 可观察:系统内页面的变动可以被访问者观察到。

BlogWiki的不同之处

毫无疑问,你完全可以用Wiki(工具)架设你的blog站点。但是我认为从比较严格的意义上来说,blogwiki是完全不同的东西,服务这完全不同的目的。

简单来说,blog更是一种无主题变奏,一般来说是少数人(大多数情况下是一个人)的关注的蔓延。一般的blog站点都会有一个主题,凡是这个主旨往往都是很松散的,而且一般不会去刻意地控制内容的相关性。blog注重的是个人的思想(不管多幺不成熟,多幺地匪夷所思),个性化是blog的最重要特色。blog注重交流,一般是小范围的交流,通过访问者对一些或者一篇blog文章的评论和交互。blog也有协作的意思,但是协作一般是指多人维护,而维护者之间可能着力于完全不同的内容。这种协作在内容而言是比较松散的。任何人,任何主体的站点,你都可以以blog方式展示,都有它的生机和活力。

Wiki则不同。Wiki站点一般都有着一个严格的共同关注,Wiki的主体一般是明确的坚定的。Wiki站点的内容要求着高度相关性。最其确定的主旨,任何写作者和参与者都应当严肃地遵从。Wiki的协作是针对同一主题作外延式和内涵式的扩展,将同一个问题谈得很充分很深入。Wiki非常适合于做一种 All about something”的站点。个性化在这里不是最重要的,信息的完整性和充分性以及权威性才是真正的目标。Wiki由于其技术实现和含义的交织和复杂性,如果你漫无主题地去发挥,最终连建立者自己都会很快的迷失。Wiki使用最多也最合适的就是去共同进行文档的写作或者文章/书籍的写作。特别是技术相关的(尤以程序开发相关的)FAQ,更多的也是更合适地以Wiki来展现。

来源:http://www.bizbeez.com/index.php?cat=7

Wikipedia:地球上最大的Wiki工程

Wikipedia(维基百科)是目前世界上最大的Wiki系统,它是一个基于WikiGNU FDL的百科全书网站系统。该系统于20011月投入运行,20012月超过1,000条条目,20017月超过10,000条条目,目前(20031月)已经接近100,000条条目。截止到200310月,40个语言版本的维基百科总文章数超过30万条,而且非英语版本的总文章数首次超过英语版本。Wikipedia条目的迅速增长说明了Wikipedia系统的健壮,也说明了Wiki的概念是经得起验证的。中文维基百科开始于200210月底。

维基百科最初的构想是在Larry Sanger(当时Nupedia的主编)和一个电脑程序员Ben Kovitz200112日在美国加利福尼亚州的一次谈话中最早提出的。Kovitz当时是wiki程序的协作开发者之一(现在依然是)。当他在晚餐中向Sanger解释wiki的概念时,Sanger立即发现wiki可能是创建一个更开放的百科全书计划的技术。在此之前几个月,Sanger和他的老板,Jimmy WalesBomis, Inc. 的总裁兼CEO,讨论过如何通过建立一个更开放、轻松的计划来协助Nupedia的发展。

因此Sanger立即说服WalesNupedia中建立一个wikiNupedia的第一个wiki110日上线,不过在Nupedia的编写人员中遇到极大阻力。因此,一个新的以“维基百科”命名的新计划于115日在维基百科.com正式启动。位于圣地亚哥的服务器和电缆都由Walses捐献。在科技站点Slashdot的三次报道后,维基百科开始受到越来越多的关注。此外,Google一天也会带来上百人的新流量。

英文维基百科在2001212日达到1,000页,97日达到10,000条条目。在计划的第一年,有超过20,000条条目被创建,平均每月1,500条。2002830日,已经有40,000条条目。成长的速度从计划之初就在平稳增长。

随之而来的就是国际化的维基百科。20015月,12个非英语维基百科版本计划开始(包括了阿拉伯语, 中文注1,荷兰语,德语,世界语, 法语,希伯来文,意大利语,日语,葡萄牙语,俄语,西班牙语和瑞典语)。到九月,由有三个语言版本加入了维基百科大家族。到了该年度末,挪威语等另外三个语言版本也宣布成立。

当然,你最好自己进去看看,就可以亲身感受到Wiki神奇的力量了。

英文版地址:http://simple.wikipedia.org/wiki/Wikipedia

英文版让你头晕,就先参观一下略微简陋的中文版:http://zh.wikipedia.org/wiki/Wikipedia

Wikipedia的风风雨雨

维基百科是由全球无数志愿学者、玩家、学生等等有知识的人共同建筑的。计划的参与者叫作维基百科人。参与者的人数在不断增加,特别是受到良好教育的人士。

全计划中没有所谓的主编。两个创立维基百科的人,Jimmy Wales(一个小型互联网公司BomisCEO)和Larry Sanger,喜欢将自己看作是负责防止计划走回头路的普通参与者。

在计划的最初几年,Larry Sanger是一个受雇佣的带薪职员。他的工作是管理维基百科(和Nupedia);当有意见分歧时,他可以在听取各种意见后作出最终决定。但是随着资金的短缺,Larry Sanger最终不得不辞职,不过他依然参与维基百科计划。

Jimmy Wales及全体维基百科人现在负责Larry Sanger之前的部分工作。为维基百科作出过贡献的其他现在和过去Bomis的雇员包括了Tim ShellBomis的创办人之一,和程序员Jason Richey以及Toan Vo

20022月,由Edgar Enyedy领导的非常活跃的西班牙语维基百科突然退出维基百科并建立了他们自己的Enciclopedia Libre(http://enciclopedia.us.es/ );理由是未来可能的商业广告及控制权的丢失。同年十月,在维基百科参与者Daniel Mayer(“maveric149″)及其他参与者试图重新整和两个计划,但是Enciclopedia Libre的参与者投票决定,在维基百科能够提出一个团圆提案之前,反对重新整和。然而,Enciclopedia Libre的用户不排除在未来重新合并的可能性,并且希望继续与维基百科保持联系。这场纷争也引起了关于非英语维基百科版本的角色的广泛讨论,并且直接导致了非英语维基百科的几项重大改革。

也经常有破坏者访问维基百科并大肆破坏该计划,通常,这些破坏都很快被修复,但是对英文维基百科首页的不断破坏最终导致首页被“保护”,以确保只有管理员可以对其进行修改。20023月,用户ID24开始在英文维基百科发表许多左倾文章;关于他的激烈讨论最终导致严重的人身攻击。Jimbo Wales最后于20024月禁止ID24对维基百科进行编辑(但允许继续浏览)。而经常在德国历史相关的文章中发表亲右翼观点,并且导致多次争论的用户“Helga”,则在20029月被禁止编辑维基百科。20028月,在Jimbo Wales宣布他将不会在维基百科上刊登商业广告之后不久,维基百科的地址从wikipedia.com变为wikipedia.org

同年十月,Derek Ramsey(“Ram-Man”)开始使用软件(“bot”)自动添加有关美国城市的信息。这些文章都是自动从人口普查报告中产生的。同时,类似的程序还用于部分其他议题。

200212月,兄弟计划Wiktionary正式开始;它的宗旨是建立一个所有语言的词典。它与维基百科在同一个服务器上运行,使用同样的软件。

20031月,维基百科开始支援TeX数学公式显示,代码由Taw编写。

2003122日,英语维基百科达到了100,000条条目的里程碑,并再次被Slashdot报道。两天后,德文维基百科,最大的非英语维基百科,也达到了10,000条条目里程碑。

中文Wikipedia

中文维基百科是维基百科协作计划的中文版本,繁简同站,大部分内容由世界各地的华人一起合作完成。中文维基百科希望能为丰富汉语互联网络作贡献。

特色
除了关注于人类共同享有的知识之外,相对其他语言的维基百科协作计划,中文维基百科更注重于华人自己的视角:中文维基百科撰写了大量关于中国的地理、历史、文化方面的条目,内容更贴近于华人自己的理解。

历史
·
2001年5月,中文维基百科与阿拉伯语、荷兰语、德语、世界语、法语、希伯来文、意大利语、日语、葡萄牙语、俄语、西班牙语、瑞典语的维基百科协作计划
一起成立,但没有人撰写条目。当时中文维基百科的域名为zh.wikipedia.com,不支持中文直接输入。

· 2002年10月24日,用户Ghyll在工具软件的帮助下撰写了中文维基百科第一个有意义的条目HomePage。

· 2002年10月27日,中文维基百科移动到新服务器,软件正式升级到Phase III,域名改为zh.wikipedia.org。

· 2003年6月14日,中文维基百科有了华人管理员。

· 2003年9月21日,中文维基百科突破了2000条条目,但其中包括同一文章的繁简两个版本。

· 2003年10月20日,《中国电脑教育报》文章《我也来写百科全书》介绍中文维基百科,这是中文媒体第一次正式报道中文维基百科。

· 2003年10月21日,中文维基百科注册用户数突破了1000人。

· 2003年11月21日,中文维基百科突破了3000条条目,但其中包括同一文章的繁简两个版本。

· 2003年12月,中文维基百科出现多次争议,见投票:模拟退火与模拟煺火和投票:删除理想语。

· 2004年1月6日,中文维基百科注册用户数突破了2000人。

· 2004年1月23日:中文维基百科突破了4000条条目,但其中包括同一文章的繁简两个版本。

人类梦想和现实:Wikipedia之前

最早将全世界的知识收集于一个屋顶下,供人查阅的要数古代亚历山大图书馆。而出版百科全书的的想法则可以追溯到狄德多等18世纪百科全书派。在各国的大学中,图书馆是最佳的百科全书会集点。今天最常见百科全书的包括了英语的《大不列颠百科全书》、《美国哥伦比亚百科全书》,西班牙语的Enciclopedia Universal Illustrada,德语的Meyer’s Konversationslexikon and Brockhaus,以及中文的《中国大百科全书》等。参见百科全书。

而至于使用一台自动机器来编写一部更有用的百科全书的想法可以追溯到H. G. Well的短篇小说《大脑世界》(World Brain, 1937)以及Vannevar Bush的科幻小说,《我们可能思考》(As We May Think, 1945)。之后的一个重要里程碑是Ted NelsonXandu计划(1960)

利用国际互联网来编写一部免费的百科全书的构想在二十世纪九十年代初就被提出。这些活动的一个分支就是旧版本的百科全书的电子化。19951月,Gutenberg计划开始出版《大不列颠百科全书》第十一版(1911)ASCII版本,但是由于方法上的分歧,在第一卷出版后整个计划就终止了。2002年,另一方出版了整套28卷的1911《大不列颠百科全书》电子版,发表在 http://1911encyclopedia.org/ ;版本中加入了版权声明,但是该声明应该没有法律效力。其他的电子化计划则出版了许多其他的百科全书,例如由基督教经典图书馆出版的电子Easton圣经辞典(1891)

另一个更有趣的分支则是编写全新的、自由免费的百科全书。1991年,新闻组alt.fan.douglas-adams的参与者开始了一个以出版真正的The Hitchhiker’s Guide to Galaxy百科全书的计划。该百科全书是出现在Douglas Adams的小说中的一个虚构的百科全书。该计划就是星系指导计划(Project Galactic Guide)。尽管最初的宗旨是百科全书只能包括真实的条目,但之后政策改变,允许并鼓励半真实及虚构的条目出现。星系指导计划包含了超过1700条条目,但从2000年起就没有新条目加入。

1993年,一个叫做Interpedia的计划开始被广泛讨论;它的计划是编写一个任何人都可以参与的互联网百科全书。但该计划为还未开始就夭折,互联网的飞速发展使得建立一个有效的搜索引擎成为更紧迫的任务。

Wiki站点一览

20038月,cnic.orgWiki翻译成中文维客。百科全书:http://www.cnic.org ,它是一个基于维客和GNU FDL的百科全书网站系统。该系统于20039月投入运行.

重要英文参考文献

http://zh.wikipedia.org/wiki/Wiki%E5%BC%95%E6%93%8E

http://c2.com/cgi/wiki?WikiHistory

http://c2.com/cgi/wiki?WikiDesignPrinciples

http://c2.com/cgi/wiki?WikiPrinciples

http://c2.com/cgi/wiki?ElementsOfWikiEssence

http://c2.com/cgi/wiki?WikiEssence

http://c2.com/cgi/wiki?LinkNameIsPageName

http://c2.com/cgi/wiki?WhyWikiWorks

http://c2.com/cgi/wiki?WhyWikiWorksNot

http://c2.com/cgi/wiki?InterWiki

http://c2.com/cgi/wiki?WikiProgramming

http://c2.com/cgi/wiki?WikiEngines


原地址:http://www.blogchina.com/new/source/180.html博客中国

软件的开发和维护过程,离不开版本管理。对于一份文件,我们经常需要按不同
的版本进行归档,或者从资料库里找出反映文件修改历史的不同版本。这样一方面可以使各个阶段的代码和文档变得井然有序,另一方面可以在当前版本出现问题的
时候,找回先前的版本。当然,人们希望的还不止这些,例如,人们希望规定谁在什么时候可以如何存取某个版本的内容,也希望差异不大的版本按增量的方式存成
一个文件,以节省存储空间……毫无疑问,我们需要一种对文件版本进行控制管理的工具,以有效地控制产品的质量,提高项目开发管理水平。


    CVS(Concurrent Versions
System)就是一个能让很多程序开发者同时进行软件开发的、强大的版本管理控制工具。CVS并不是Internet的产物,而它的出现却是历史的必
然。Richard Stallman倡导的开源软件运动大大加速了这一过程。

起因


    开源软件的一个重要特点就是可以从世界任何地方获得代码和改进代码,这是传统软件开发所不具备的。这意味着开源软件的开发在全球
开发者的协作下成为一个不间断的过程,每个人都可能成为开发队伍的一员,并且每个人都会随时流动。一个地域上分散的志愿者组织显然不能投入很多的时间来训
练其成员彼此合作,这就需要一套项目管理办法,确保新成员能较容易地适应工作;同时有一个自动的机制接收外来代码,使每个成员能及时得到最新修改的代码。
当然,这不仅仅是开源社区的需要,只是开源社区的人员分散、资源不易管理,更需要一个版本管理工具。这样的一个工具首先应该支持世界范围的协作,保持发布
版本的一致性;其次它能够容易地汇集各个特定版本的Bug,并在全球范围同步一致地进行修改;再者它需要使任何一个开发者能够追踪软件的变化;而在开发者
为软件增加新功能的同时,不能妨碍一般用户使用一个相对稳定的版本。


    CVS很好地解决了这一问题。
除了开发人员可以使用CVS很容易地把代码变化存入代码库之外,它还为不同角色的人员设置了不同的访问权限。例如,不需要修改代码的人员可以以匿名只读方
式访问代码库。而需要修改代码的开发人员每个人都能在自己的机器上建立一个开发树,当需要在一个特殊的代码区工作时,首先通过简单的命令,使开发树获得更
新,以保持全球范围开发状态的同步一致。这样就可以避免出现这样的问题:花了半天时间修改的Bug,在提交的时候发现别人已经解决了。一旦确认代码中的
Bug别人还没解决,开发者可以马上开始工作。当这些问题解决后,CVS会自动产生补丁,并将补丁发送给维护人员进行检查,最后可能将其并入主项目树中
去。


    发展历程


    早在CVS之前,就出现过对变化前后的文件进行比较,并根据异同形成“补丁”(Patch)的工具。例如,Unix上使用的
Diff和Lany
Wall写的Patch,这两个工具对程序代码的传播和维护起到了重要作用。但是,后来出现的许多要求Diff和Pach都显得无能为力,例如,发现修补
出错而需要退回到以前未修改的状态等。这就要求有一个保存项目历史纪录的系统。


    当时初步具备这个功能的工具是SCCS(Source Code Control System),是贝尔实验室的Marc
Rochkind在1972年写成的。SCCS是一种基本的源文件版本控制工具,适用于正文文件的版本维护。它基于单一文件的版本控制,代码库和要维护的
文件通常在同一目录下。SCCS有一个专门的SCCS文件保留源文件的各编码版本,其中记录了足够的信息来恢复一个版本,并记录了谁对文件有修改权、有版
本锁的功能。SCCS是AT&T Unix发行版的一部分。


    然而,自由软件项目最终选择了Walter F.
Tichy的版本控制系统(RCS)来满足他们的需要。RCS在SCCS基础上加以改进,界面也更加友好,是BSD
Unix发行版的一部分。它可以追踪文件的改变,在工作组中对文件的共享和访问进行控制,通常用于维护源代码;也能追踪文件的修改历史。RCS包含一套命
令,用于设置RCS源码库中的文件属性、检入检出文件、清除文件、比较修订版本,以及合并文件等。由RCS管理的文件可以既可以是纯文本文件,也可以是二
进制文件。


    然而,RCS仍存在几个重要缺陷,其中最主要的是由于使用单一目录控制与档案锁,无法让多个编程人员同时开发。因为RCS本身
不是针对网络环境写的,开发者只能在RCS代码库所在的机器上工作,难以在分布式环境下开发。这些缺点后来在CVS中都得到了改进。1956年Dick
Grune写了一段Shell脚本来简化RCS的使用。1986年10月,它的第6个发行版被放到USENET新闻组comp.soures.unix之
中。1989年3月,Brian Berlinor用C语言重新设计并编写了CVS的代码。后来,Jett
Polk帮助Brian完成了CVS模型设计,增加了一些关键特性。1993年前后,Jim
Kingdon最终将CVS设计成基于网络的平台,开发者们能从Internet任何地方获得程序源代码。


    特点


    CVS本身是开源项目,通过其方便的功能使众多的人们加入到开源软件项目之中,促进了开源运动的发展。反过来,开源项目的成功又
促使版本管理工具不断完善。现在大多数开源软件项目都使用CVS做为版本控制和协作开发的工具,其中不乏像GNOME、KDE、Apache这样的庞大的
项目,充分显示了CVS做为版本控制工具的成功。


    归结起来,CVS为开源项目做出的贡献大致有两点:一是由于它通过众人的参与使开源软件质量不断提高;二是它方便了全球软件工作者的协作,使软件成为全人类智慧的结晶。这大概就是今天CVS在自由软件世界中处于主导地位的原因了。


    尽管CVS的功能和使用方法看起来颇为庞大复杂,其实CVS最重要的只有两点,即记录保存和协作。人们有时要将一个程序的当前状
态与先前某一状态做比较。例如,在为程序添加新功能的过程中,有人可能会通报试用版的Bug。为了找到问题之所在,一方面程序必须可以找回原来某时的可用
状态。事实上,开发者可以简单地说一句,把以前程序的状态给我,或者说把最新公开发行的版本给我,这就是CVS对历史记录的保存作用。另一方面,CVS系
统要顺利工作,开发者必须彼此知道在某个时刻准备做什么工作。CVS能够在代码提交的时候提醒开发者代码是否存在冲突;当某人因为权限问题不能工作的时
候,彼此能很快地沟通。这就是CVS协同工作、跟踪冲突的能力。CVS的一般任务主要是访问已有的代码库、创建新项目、检出工作拷贝、进行更改、检测并解
决冲突、浏览记录信息、检查并还原更改等。


    CVS现已成为广泛使用的版本管理系统,普遍应用在软件开发过程中,是基本的软件工程配置管理工具之一。不论是一个庞大的工程,如GNOME、Apache,还是个人开发一个小软件,都可以方便地使用CVS来管理开发过程,提高效率,方便管理。


    创始者


    CVS的开发队伍共有18个人,其管理者都是对CVS的发展有过突出贡献的。CVS由开发者们共同决定如何发展,要做什么关键的改进。但是这个过程并不完全民主。仅在吸收新的开发成员时,须有多数人同意才行。其它方面大多不必如此,更不用投票。


    CVS主要开发者Jim
Kingdon认为,在自由软件项目中过分民主会陷入无休止投票的泥潭,导致效率低下。而指定单一人员来维护,对于自由软件的开发来说是最通行、最成功的
做法,当然也是倍受争议的。对于软件的每一处修改,需要这个维护人员的同意,也只能通过这个单一的维护人员授权给其它下层维护人员。诚然,开源软件的成功
要依靠众人的参与,但是,愿意为软件效力的每个人并不都具备编码的水准,都了解局部改变和整体的关系,因此不能谁说了都算,而是要把目光集中在真正有可能
给软件带来贡献的那些人身上。


    CVS走过了一段坎坷的路程。Jim Kongdon既是一个了不起的程序员,又具有商人的特质。Jim
Kingdon毕业于美国俄亥俄州的Oberlin学院,之后曾为自由软件基金会(FSF)工作过。1993年之后,除了开发CVS之外,他还是
Cygnus的工程师,为GDB修补Bug。他自己开过一个Cyclic公司。Cyclic是靠提供CVS支持服务来赚钱的公司。Jim
Kingdon 1995年白手起家,到了1998年经营收入已达到了13.5万美元。离开Cyclic之后,Jim Kingdon在Red
Hat工作了一年,后来频繁“跳槽”。2002年之后,他在加利福尼亚Fremont的Enlighta公司当程序员,为Web/SQL做测试。他的自我
发展目标是甘愿当一个程序员,与同事、客户、合作伙伴一道创造和维护高质量的软件。他本人兴趣甚广,
除了编程,他还热衷太空市场,学习西班牙语、日语和世界语等。


    长期以来,Cyclic维护着CVS的“官方”网站http://www.cvshome.org/。但是,除少数人员的重合
外,Cyclic和CVS的开发队伍基本上是独立的。1999年,Jim Kingdon突然宣布他要离开Cyclic去Red
Hat工作,他将Cyclic卖给了Source Gear公司,同时Cyclic也发布了一个声明,说它不再正式支持CVS。这带来一场不小的震动。


    Source
Gear也是一家销售和维护软件的公司,它希望能够作为CVS的供应商,使CVS变得有利可图,最终成为CVS发展的领头羊。尽管实际情况不尽人愿,一些
CVS的开发者并不买他们的账,但Source Gear还是为CVS做了一些实质性的工作。而CVS的开发者迅速成立了一个新的项目CVS
Continuity Project,其目的是使CVS开发、维护工作能够继续正常进展下去。现在CVS的网站挂在Yankee
Group麾下CollabNet公司的SourceCase网站上,SourceCase是专门为全球志愿的开发人员协同开发软件提供的Web空间。


    除了Jim Kingdon以外,CVS开发队伍中的一些关键人物是:
    ◆Steve Willer为CVS社团做了大量的服务工作,在邮件组中回答各种问题,并向开发团队报告具有共性的Bug。
    ◆Pascal Molli负责网站http://www.loria.fr/~molli/cvs-index.html的维护。这个网站上面放着最新版本的CVS和各种CVS文档,以及与相关资源的链接等。
    ◆David Klann维护着info-cvs MINI-FAQ(常见问题解答),并定期更新。这个FAQ链接着各个相关的地址,提供各种公众需要的信息。
    ◆David W. Eaton维护着comp.software.config-mgmt FAQ。这是一项艰巨的工作,因为他试图把整个配置管理领域都囊括进去,而不仅仅是CVS。


    版本与相关项目


    目前,最新的CVS版本是2004年3月13日发布的1.12.6,稳定版本是2004年3月11日发布的1.11.14。CVS支持的平台包括Windows 32、Linux和Unix等。


    CVS有多个发展方向,相关的开发项目主要有:
    ◆Anonymous CVS Access Via ssh 加强CVS的安全。
    ◆Bonsai 为CVS增加基于web的图形界面。
    ◆CHalogen The Change Log Generator,产生HTML形式的变化日志。
    ◆Component Software CVS for Windows Windows平台下的CVS前端。
    ◆CVS Access Control List Extension 为CVS远程代码库增加ACL访问控制。
    ◆CVS Code Historian 在MS VisualStudio或浏览器中,利用CVS记载的信息进行文件比较或分析。
    ◆CVS for MVS 把CVS移植到MVS/OS390/USS主机。
    ◆CVS Monitor CVS代码库浏览器。
    ◆CVS version control for web development 为Web开发者写的CVS工具。
    ◆CVS via FTP 通过FTP实现CVS网站镜像。
    ◆cvs2cl CVS日志转换。
    ◆cvsdude 在Windows和类Unix客户端平台上用命令行访问CVS。
    ◆CVSGrab 通过防火墙获得CVS树。
    ◆cvs2html 将CVS日志转成HTML格式。
    ◆cvsknit A CVS automation suite,粘合多个CVS代码库的自动工具。
    ◆cvslock 维护和检视多个代码库,保持同步。
    ◆CVSNT 在Windows NT/2000下运行的CVS服务器。
    ◆Cvsplot 为CVS控制的文件提供统计信息。
    ◆CVSSearch 通过CVS命令来检索代码片断的工具。
    ◆CVSspam Notification of CVS committs, by email。当CVS有变化提交时发出E-mail。
    ◆CVSSupport 用Perl写的CVS工具。
    ◆CVSToys CVS变化提交时的通知工具。
    ◆CVSTrac 基于Web的Bug和补丁跟踪系统。
    ◆CVSup 通过网络发布和更新批量文件的软件包。
    ◆CVSweb for Windows 95/NT/2000 为在Windows PWS/IIS上运行CVS Web提供的指令。
    ◆CVSweb (Henner Zeller version) 用Perl脚本通过RCS命令为CVS加上Web接口。
    ◆StatCvs 产生HTML和PNG格式的CVS代码库的统计信息。
    ◆ViewCVS 用Python写的类似CVS Web工具。
    ◆ViewCVS for Windows ViewCVS到Windows平台的移植,运行于IIS。


    要想了解关于CVS更多的信息,可以参看下面的网址http://www.cvshome.org;http:
//www.loria.fr/~molli/cvs-index.html;http:
//www.soforge.com/cvsdoc/zh_CN/book1.html;http://cvsbook.red-bean.com/;

http://cvsgui.sourceforge.net/。



    CVS是一个广泛使用的版本控制系统,随着互联网的普及,分布在世界各地的程序员会越来越多地采用它进行版本控制和开发。(T111)
转自赛迪网。
http://tech.ccidnet.com/pub/article/c1060_a185163_p1.html