📄 input.c
字号:
if (t.type == tok_cmd && t.cmd == c__escaped)
{
t.type = tok_word; /* nice and simple */
t.aux = 0; /* even if `\-' - nonbreaking! */
}
if (t.type == tok_cmd && t.cmd == c__nbsp)
{
t.type = tok_word; /* nice and simple */
sfree(t.text);
t.text = ustrdup(L" "); /* text is ` ' not `_' */
t.aux = 0; /* (nonbreaking) */
}
switch (t.type)
{
case tok_white:
if (whptr == &par.words)
break; /* strip whitespace at start of para */
wd.text = NULL;
wd.type = spcstyle;
wd.alt = NULL;
wd.aux = 0;
wd.fpos = t.pos;
wd.breaks = FALSE;
/*
* Inhibit use of whitespace if it's (probably the
* newline) before a repeat \IM / \BR type
* directive.
*/
if (start_cmd != c__invalid)
{
dtor(t), t = get_token(in);
already = TRUE;
if (t.type == tok_cmd && t.cmd == start_cmd)
break;
}
if (indexing)
rdadd(&indexstr, ' ');
if (!indexing || index_visible)
addword(wd, &whptr);
if (indexing)
addword(wd, &idximplicit);
iswhite = TRUE;
break;
case tok_word:
if (indexing)
rdadds(&indexstr, t.text);
wd.type = style;
wd.alt = NULL;
wd.aux = 0;
wd.fpos = t.pos;
wd.breaks = t.aux;
if (!indexing || index_visible)
{
wd.text = ustrdup(t.text);
addword(wd, &whptr);
}
if (indexing)
{
wd.text = ustrdup(t.text);
addword(wd, &idximplicit);
}
break;
case tok_lbrace:
error(err_unexbrace, &t.pos);
/* Error recovery: push nop */
sitem = mknew(struct stack_item);
sitem->type = stack_nop;
stk_push(parsestk, sitem);
break;
case tok_rbrace:
sitem = stk_pop(parsestk);
if (!sitem)
error(err_unexbrace, &t.pos);
else
{
if (sitem->type & stack_ualt)
{
whptr = sitem->whptr;
idximplicit = sitem->idximplicit;
}
if (sitem->type & stack_style)
{
style = word_Normal;
spcstyle = word_WhiteSpace;
}
if (sitem->type & stack_idx ) {
indexword->text = ustrdup(indexstr.text);
if (index_downcase)
ustrlow(indexword->text);
indexing = FALSE;
rdadd(&indexstr, L'\0');
index_merge(idx, FALSE, indexstr.text, idxwordlist);
sfree(indexstr.text);
}
if (sitem->type & stack_hyper)
{
wd.text = NULL;
wd.type = word_HyperEnd;
wd.alt = NULL;
wd.aux = 0;
wd.fpos = t.pos;
wd.breaks = FALSE;
if (!indexing || index_visible)
addword(wd, &whptr);
if (indexing)
addword(wd, &idximplicit);
}
if (sitem->type & stack_quote)
{
wd.text = NULL;
wd.type = toquotestyle(style);
wd.alt = NULL;
wd.aux = quote_Close;
wd.fpos = t.pos;
wd.breaks = FALSE;
if (!indexing || index_visible)
addword(wd, &whptr);
if (indexing)
{
rdadd(&indexstr, L'"');
addword(wd, &idximplicit);
}
}
}
sfree(sitem);
break;
case tok_cmd:
switch (t.cmd)
{
case c__comment:
/*
* In-paragraph comment: \#{ balanced braces }
*
* Anything goes here; even tok_eop. We should
* eat whitespace after the close brace _if_
* there was whitespace before the \#.
*/
dtor(t), t = get_token(in);
if (t.type != tok_lbrace)
{
error(err_explbr, &t.pos);
} else
{
int braces = 1;
while (braces > 0)
{
dtor(t), t = get_token(in);
if (t.type == tok_lbrace)
braces++;
else if (t.type == tok_rbrace)
braces--;
else if (t.type == tok_eof)
{
error(err_commenteof, &t.pos);
break;
}
}
}
if (seenwhite)
{
already = TRUE;
dtor(t), t = get_token(in);
if (t.type == tok_white)
{
iswhite = TRUE;
already = FALSE;
}
}
break;
case c_q:
dtor(t), t = get_token(in);
if (t.type != tok_lbrace)
{
error(err_explbr, &t.pos);
} else
{
wd.text = NULL;
wd.type = toquotestyle(style);
wd.alt = NULL;
wd.aux = quote_Open;
wd.fpos = t.pos;
wd.breaks = FALSE;
if (!indexing || index_visible)
addword(wd, &whptr);
if (indexing)
{
rdadd(&indexstr, L'"');
addword(wd, &idximplicit);
}
sitem = mknew(struct stack_item);
sitem->type = stack_quote;
stk_push(parsestk, sitem);
}
break;
case c_K:
case c_k:
case c_R:
case c_W:
case c_L:
case c_date:
/*
* Keyword, hyperlink, or \date. We expect a
* left brace, some text, and then a right
* brace. No nesting; no arguments.
*/
wd.fpos = t.pos;
wd.breaks = FALSE;
if (t.cmd == c_K)
wd.type = word_UpperXref;
else if (t.cmd == c_k)
wd.type = word_LowerXref;
else if (t.cmd == c_R)
wd.type = word_FreeTextXref;
else if (t.cmd == c_W)
wd.type = word_HyperLink;
else if (t.cmd == c_L)
wd.type = word_LocalHyperLink;
else
wd.type = word_Normal;
dtor(t), t = get_token(in);
if (t.type != tok_lbrace)
{
if (wd.type == word_Normal)
{
time_t thetime = time(NULL);
struct tm *broken = localtime(&thetime);
already = TRUE;
wdtext = ustrftime(NULL, broken);
wd.type = style;
} else
{
error(err_explbr, &t.pos);
wdtext = NULL;
}
} else
{
rdstring rs = { 0, 0, NULL };
while (dtor(t), t = get_token(in),
t.type == tok_word || t.type == tok_white)
{
if (t.type == tok_white)
rdadd(&rs, ' ');
else
rdadds(&rs, t.text);
}
if (wd.type == word_Normal)
{
time_t thetime = time(NULL);
struct tm *broken = localtime(&thetime);
wdtext = ustrftime(rs.text, broken);
wd.type = style;
} else
{
wdtext = ustrdup(rs.text);
}
sfree(rs.text);
if (t.type != tok_rbrace)
{
error(err_kwexprbr, &t.pos);
}
}
wd.alt = NULL;
wd.aux = 0;
if (!indexing || index_visible)
{
wd.text = ustrdup(wdtext);
addword(wd, &whptr);
}
if (indexing)
{
wd.text = ustrdup(wdtext);
addword(wd, &idximplicit);
}
sfree(wdtext);
if (wd.type == word_FreeTextXref || wd.type == word_HyperLink || wd.type == word_LocalHyperLink)
{
/*
* Hyperlinks are different: they then
* expect another left brace, to begin
* delimiting the text marked by the link.
*/
dtor(t), t = get_token(in);
/*
* Special cases: \W{}\c, \W{}\e, \W{}\cw
*/
sitem = mknew(struct stack_item);
sitem->type = stack_hyper;
if (t.type == tok_cmd &&
(t.cmd == c_e || t.cmd == c_c || t.cmd == c_cw))
{
if (style != word_Normal)
error(err_nestedstyles, &t.pos);
else
{
style = (t.cmd == c_c ? word_Code :
t.cmd == c_cw ? word_WeakCode : word_Emph);
spcstyle = tospacestyle(style);
sitem->type |= stack_style;
}
dtor(t), t = get_token(in);
}
if (t.type != tok_lbrace)
{
error(err_explbr, &t.pos);
sfree(sitem);
} else
{
stk_push(parsestk, sitem);
}
}
break;
case c_c:
case c_cw:
case c_e:
type = t.cmd;
if (style != word_Normal)
{
error(err_nestedstyles, &t.pos);
/* Error recovery: eat lbrace, push nop. */
dtor(t), t = get_token(in);
sitem = mknew(struct stack_item);
sitem->type = stack_nop;
stk_push(parsestk, sitem);
}
dtor(t), t = get_token(in);
if (t.type != tok_lbrace)
{
error(err_explbr, &t.pos);
} else
{
style = (type == c_c ? word_Code :
type == c_cw ? word_WeakCode : word_Emph);
spcstyle = tospacestyle(style);
sitem = mknew(struct stack_item);
sitem->type = stack_style;
stk_push(parsestk, sitem);
}
break;
case c_i:
case c_ii:
case c_I:
type = t.cmd;
if (indexing)
{
error(err_nestedindex, &t.pos);
/* Error recovery: eat lbrace, push nop. */
dtor(t), t = get_token(in);
sitem = mknew(struct stack_item);
sitem->type = stack_nop;
stk_push(parsestk, sitem);
}
sitem = mknew(struct stack_item);
sitem->type = stack_idx;
dtor(t), t = get_token(in);
/*
* Special cases: \i\c, \i\e, \i\cw
*/
wd.fpos = t.pos;
if (t.type == tok_cmd &&
(t.cmd == c_e || t.cmd == c_c || t.cmd == c_cw))
{
if (style != word_Normal)
error(err_nestedstyles, &t.pos);
else
{
style = (t.cmd == c_c ? word_Code :
t.cmd == c_cw ? word_WeakCode : word_Emph);
spcstyle = tospacestyle(style);
sitem->type |= stack_style;
}
dtor(t), t = get_token(in);
}
if (t.type != tok_lbrace)
{
sfree(sitem);
error(err_explbr, &t.pos);
} else
{
/* Add an index-reference word with no text as yet */
wd.type = word_IndexRef;
wd.text = NULL;
wd.alt = NULL;
wd.aux = 0;
wd.breaks = FALSE;
indexword = addword(wd, &whptr);
/* Set up a rdstring to read the index text */
indexstr = nullrs;
/* Flags so that we do the Right Things with text */
index_visible = (type != c_I);
index_downcase = (type == c_ii);
indexing = TRUE;
idxwordlist = NULL;
idximplicit = &idxwordlist;
/* Stack item to close the indexing on exit */
stk_push(parsestk, sitem);
}
break;
case c_u:
uchr = t.aux;
utext[0] = uchr;
utext[1] = 0;
wd.type = style;
wd.breaks = FALSE;
wd.alt = NULL;
wd.aux = 0;
wd.fpos = t.pos;
if (!indexing || index_visible)
{
wd.text = ustrdup(utext);
uword = addword(wd, &whptr);
} else
uword = NULL;
if (indexing)
{
wd.text = ustrdup(utext);
iword = addword(wd, &idximplicit);
} else
iword = NULL;
dtor(t), t = get_token(in);
if (t.type == tok_lbrace)
{
/*
* \u with a left brace. Until the brace
* closes, all further words go on a
* sidetrack from the main thread of the
* paragraph.
*/
sitem = mknew(struct stack_item);
sitem->type = stack_ualt;
sitem->whptr = whptr;
sitem->idximplicit = idximplicit;
stk_push(parsestk, sitem);
whptr = uword ? &uword->alt : NULL;
idximplicit = iword ? &iword->alt : NULL;
} else
{
if (indexing)
rdadd(&indexstr, uchr);
already = TRUE;
}
break;
default:
if (!macrolookup(macros, in, t.text, &t.pos))
error(err_badmidcmd, t.text, &t.pos);
break;
}
}
if (!already)
dtor(t), t = get_token(in);
seenwhite = iswhite;
}
/* Check the stack is empty */
if (NULL != (sitem = stk_pop(parsestk)))
{
do
{
sfree(sitem);
sitem = stk_pop(parsestk);
}
while (sitem);
error(err_missingrbrace, &t.pos);
}
stk_free(parsestk);
addpara(par, ret);
}
/*
* We break to here rather than returning, because otherwise
* this cleanup doesn't happen.
*/
dtor(t);
macrocleanup(macros);
}
paragraph *read_input(input * in, indexdata * idx)
{
paragraph *head = NULL;
paragraph **hptr = &head;
while (in->currindex < in->nfiles)
{
in->currfp = fopen(in->filenames[in->currindex], "r");
if (in->currfp)
{
setpos(in, in->filenames[in->currindex]);
read_file(&hptr, in, idx);
}
in->currindex++;
}
return head;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -