看板Maple
标 题附件,引用文章以及Bbs Resource Locator
发信站明月水轩BBS (Thu Jun 5 22:12:51 2003)
转信站Ptt!news.cs.nthu!news.neu.edu.cn!hightman
bbs中不像http没有链接的功能。
我们一般在版面上说:参考本版3321文
但是如果一个大站,发文很快,版主清得又勤,前面的3321文过几个小时可能
已经变成3105文。去找时已经找不到。
如果是几天前的文章,那这个3321文就不知哪去找了。
于是一些特别善心的人们会这样来表示,参考 “02/04/02 lkchu 很好的一篇文章”
一些bbs会加入查找某段日期文章的功能,也比较好地应对这个问题。
我们这里在尝试的是一种通用性的表示文章引用的方法。
起意是在和hightman研究在一篇文章中上载多个二进制附件时聊出来的。
一篇文章上载了相关的附件,附件是肯定另存一个地方会比较好。
因而就引入了在一篇文章中如何描述附件的位置的问题。
先谈谈本站“笑书亭”中使用的步骤:
1. ctrl-p发表文章
2. 写着写着需要一个附图来说明,就按ctrl-x,这里借用了windtop的popupmenu
□□□□□□□□□□□□□□□□□□
□【存档选项】 □
□
┤[L]ocal 存为站内档 ├□□
□ (
S)ave 存档
□□
□ (
A)bort 放弃
□□
□ (
T)itle 改标题
□□
□ (
E)dit 继续编辑
□□
□ (
R)ead 读取暂存档
□□
□ (
W)rite 写入暂存档
□□
□ (
P)aste 插入引用链接
□□
□ (
U)pload 上载附件
□□
□□□□□□□□□□□□□□□□□□□
3. 选择Upload上载附件,底行提示:
请问选择上载途径. 1) HTTP 2) Zmodem. 0) 退出 [0]
4. 选2,再按Y,支持Zmodem的telnet client就会弹出对话框选择文件
5. 上载结束,提示输入文件描述,直接回车就记下文件名作为描述:
正在保存文件: 样品.jpg (9894 bytes)
输入描述:
6. 文章中插入一串字符:
"样品.jpg":xfile:@0VDUEE9
显示的这一串字符中,实际还包括头尾的两个不可见分隔码,实际是
\004"样品.jpg":xfile:@0VDUEE9\004
^^^^这个\004在vim中看是^D,cat的话是小黑块,用户从bbs界面无法输入
7. 文章发表后,more中显示:
"样品.jpg":xfile:@0VDUEE9
8. 在more时按ctrl-d,用popupmenu列出本文内的所有链接:
□□□□□□□□□□□□□□□□□□
□【附件列表】 □
□
┤[0] - 取消 ├□□
□ (
1) - 样品.jpg
□□
□□□□□□□□□□□□□□□□□□□
9. 选择文件按回车,支持ZModem的telnet client即开始下载。
----------------------------------------------------------------
上面这个 \004"样品.jpg":xfile:@0VDUEE9\004
就是我们想说的BBS Resource Locator,用于定位在一个bbs站的资源。
这里提到的资源是指:版面文章,文章,附件,以及投票结果,十大统计等。
目的是用于一串人类可以理解,又可以存在于文章中的字串来确切地
定位在一个bbs中的位址。
在阅读文章时按ctrl-d用popupmenu的方式列出文章中的这种定位串,
供用户选择。
----------------------------------------------------------------
再谈引用文章:
为了在文章中引用其它文章,也可以使用这种定位串。
在本站“笑书亭”中使用方法如下:
1. 上下左右找到你想引用文章
2. 按大写M 生成文章的BRL引用串,存在内存中,底行显示:
◆ 收录剪贴板中: brl="Re: [问题] 匿名板的文章评分":A0VDRKKP
3. 发表文章时,ctrl-x,选取Paste
□□□□□□□□□□□□□□□□□□
□【存档选项】 □
$"样品.jpg":xfile:@0 □ [
S]ave 存档
□□
□ (
A)bort 放弃
□□
□ (
T)itle 改标题
□□
-- □ (
E)dit 继续编辑
□□
*[1;31m#*[33m Origin □ (
R)ead 读取暂存档
□□ 66.net *[m
*[1;31m#*[35m Author □ (
W)rite 写入暂存档
□□
□
┤(P)aste 插入引用链接 ├□□
□ (
U)pload 上载附件
□□
□□□□□□□□□□□□□□□□□□□
4. 文章中会插入一行:
"Re: [问题] 匿名板的文章评分":A0VDRKKP$TW-itoc
^同样地,头尾两端包还包含\004这个不可见字符 ^
5. 阅读文章时,显示:
"样品.jpg":xfile:@0VDUEE9
"Re: [问题] 匿名板的文章评分":A0VDRKKP$TW-itoc
6. 按ctrl-d,弹popupmenu列出所有链接:
□□□□□□□□□□□□□□□□□□
□【附件列表】 □
□
┤[0] - 取消 ├□□
□ (
1) - 样品.jpg
□□
□ (
2) - Re: [问题] 匿名板的文
□□
□□□□□□□□□□□□□□□□□□□
7. 选择阅读或下载
8. 阅读的文章读完后会返回原来XO所在位置
--------------------------------------------------------------------
BRL = BRLDESC:(RTYPE)?:BRLPATH
BRLDESC = "[~"]*"
RTYPE = ("post", "gem", "xfile", "unkown")
BRLPATH = FILENAME($BOARD)?
FILENAME = ('A'..'Z', '0'..'9')+
BOARD = ('A'..'Z', '0'..'9')+
/*-------------------------------------------------------*/
/* BRL 在本站的资源定位 */
/* 0x4 "Description":A0UF95DL 0x4 最简写,默认本版版面文章 */
/* 0x4 "Description":post:A0UF95DL 0x4 本版文章 */
/* 0x4 "Description":A0UF95DL$sysop 0x4 sysop版上文章 */
/* 0x4 "Description":A0UF95DL$sysop 0x4 sysop版上文章 */
/* 0x4 "Description":post:A0UF95DL$sysop 0x4 sysop版上文章 */
/* 0x4 "Description":gem:A0UF95DL 0x4 本版 */
/* 0x4 "Description":gem:A0UF95DL$sysop 0x4 sysop版 */
/* 0x4 "Description":xfile:A0UF95DL 0x4 本版附件 */
/* 0x4 "Description":vote:A0UF95DL 0x4 本版投票结果 */
/* */
--------------------------------------------------------
限于篇幅,这里仅贴出解析代码,完整的代码等整理好
之后打包放出来,或者你知道笑书亭在哪的话,找我来要。
#define BRL_ESCCHAR 4
typedef struct {
int rtype;
char rtypestr[10];
char brdid[24];
char brldesc[64];
char brlpath[64];
} BRL;
enum
{
RT_POST=0, RT_GEM, RT_XFILE, RT_VOTE, RT_UNKNOWN=99
};
/*-------------------------------------------------------
Search brl in a char*;
return the first pos occur a complete BRL in str;
return null if not found.
if found, the desc and path are stored in brl;
-------------------------------------------------------*/
char *brl_find(unsigned char *str, BRL *brl, unsigned char **end)
{
int bstate, i;
unsigned char *ptr, *qtr, *t;
unsigned char whitespace[]=" ";
char brdidchars[] = "@0123456789_.-";
/*
暂时不用,什么都有可能
char brlchars[]="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
*/
#define BRLERROR 8
#define BRLFOUND 9
*brl->brldesc = NULL;
*brl->brlpath = NULL;
*brl->rtypestr = NULL;
*brl->brdid = NULL;
ptr = strchr(str, BRL_ESCCHAR);
if (ptr == NULL) return NULL;
ptr++;
qtr=ptr;
bstate = 0;
while ((*qtr != NULL)&&(*qtr!='\r')&&(*qtr!='\n')&&(*qtr!='\t')
&&(bstate != BRLERROR)&&(bstate!=BRLFOUND)) {
switch (bstate)
{
case 0 :
if (*qtr == '"') {
*brl->brldesc = '\0';
bstate = 1;
}
else if (strchr(whitespace, *qtr)) {
}
else bstate = BRLERROR;
break;
case 1 : /* description */
if (*qtr == '"'){
bstate = 2;
}
else if (*qtr >= 0x20) {
strncat(brl->brldesc, qtr, 1);
}
else bstate = BRLERROR;
break;
case 2 : /* brltype */
if (*qtr == ':') {
if ((*(qtr+1) != NULL) && (t = strchr(qtr+1, ':'))) {
strncpy(brl->rtypestr, qtr+1, t-qtr-1);
brl->rtypestr[t-qtr-1] = '\0';
qtr = t; /* 后面会 qtr++ */
}
bstate = 3;
*brl->brlpath = '\0';
}
else if (strchr(whitespace, *qtr)) {
}
else bstate = BRLERROR;
break;
case 3 : /* brlpath */
if (*qtr == BRL_ESCCHAR) {
bstate = BRLFOUND;
}
else if (*qtr == '$') {
bstate = 4;
}
else if (isalpha(*qtr) || strchr(brdidchars, *qtr)) {
strncat(brl->brlpath, qtr, 1);
}
else if (strchr(whitespace, *qtr)) {
}
else bstate = BRLERROR;
break;
case 4 : /* 版名 */
if (*qtr == BRL_ESCCHAR) {
bstate = BRLFOUND;
}
else if (isalpha(*qtr) || strchr(brdidchars, *qtr)) {
strncat(brl->brdid, qtr, 1);
}
else if (strchr(whitespace, *qtr)) {
}
else bstate = BRLERROR;
break;
case BRLERROR:
break;
case BRLFOUND:
break;
} /* switch (bstate)*/
qtr++;
}
if (bstate != BRLFOUND) {
return NULL;
}
*end = qtr; /* 指向 BRL_ESCCHAR 后面那个char */
if (strlen(brl->rtypestr) == 0) {
brl->rtype = RT_POST;
}
else {
str_lower(brl->rtypestr, brl->rtypestr);
i = 0;
while ((DEF_RTYPE[i]) && (!strstr(brl->rtypestr,DEF_RTYPE[i])))
i++;
if (!DEF_RTYPE[i]) brl->rtype = RT_UNKNOWN;
else brl->rtype = i;
}
return ptr;
}
--
# Origin # 笑书亭 bbs.dot66.net
# Author # 218.108.188.200