%% options
copyright owner = Dirk Krause
copyright year = 2013-2014
license = bsd
%% header
#ifdef __cplusplus
extern "C" {
#endif
/** Process the contents.
@param job Job structure, current node is set.
@param p Previous node (if any).
@param n Next node (if any).
@return 1 on success, 0 on error.
*/
int
hbcont_process(hb_job_t *job, hb_node_t *p, hb_node_t *n);
/** Create contents line structure.
@param il Input line to save.
@param lineno Line number of input line.
@param app Application structure for diagnostics, may be NULL.
@return Pointer to new line structure on success, NULL on error.
*/
hb_line_t *
hbcont_line_new(dkChar const *il, unsigned long lineno, dk3_app_t *app);
/** Delete one contents line.
@param lp Contents line to delete.
*/
void
hbcont_line_delete(hb_line_t *lp);
#ifdef __cplusplus
}
#endif
%% module
#include "dk3all.h"
#include "htmlbook.h"
$!trace-include
/** Object to process a contents line.
*/
typedef struct {
hb_job_t *job; /**< Job structure. */
hb_node_t *nptr; /**< Current node. */
unsigned long lineno; /**< Current line number. */
unsigned long nheader; /**< Next header number. */
unsigned maxheader; /**< Maximum header number found. */
} hb_contents_line_processor_t;
/** Output keywords.
*/
static char const * const hbcont_c8_kw[] = {
$!string-table
#
# 0 Newline
#
\n
#
# 1 Space
#
#
# 2 3 H1 tags.
#
\n
#
# 4 5 Position table
#
\n
\n
#
# 8 9 Position table data
#
| \n
#
# 10 Right arrow
#
→
#
# 11 Position table data with colspan
#
#
# 12 13 Header in variable depth
#
\n
#
# 14 15 Named anchors before headers
#
#
# 16 Start of anchor name for header
#
hb_h
#
# 17 18 Page TOC table
#
\n
#
# 21 Page TOC space data
#
| \n
#
# 22 23 Page TOC data field
#
| \n
#
# 24 25 26 27 Link for page TOC entry
#
#
# 28 29 30 Link division
#
\n
\n
#
# 31 32 Table for links
#
\n
\n
#
# 35 36 37 Table data for number
#
| \n
%lu
#
# 38 Table data for URL
#
#
# 39 40 Table for TOC
#
\n \n
#
# 41 42 43 44 Table row for TOC
#
\n
\n
| \n
#
# 45 46
#
#
# 47 48
#
\n
#
# 49
#
#
# 50
#
#
# 51
#
#
# 52 53
#
\n
#
# 54 55
#
\n
#
# 56 57
#
\n\n\n
#
# 58 59
#
\n
#
# 60 61
#
aname = NULL;
lp->realtext = NULL;
lp->lineno = 0UL;
lp->header = 0UL;
lp->headlevel = 0;
lp->lt = 0;
dk3_release(lp->text);
dk3_delete(lp);
} $? "- hbcont_line_delete"
}
hb_line_t *
hbcont_line_new(dkChar const *il, unsigned long lineno, dk3_app_t *app)
{
hb_line_t *back = NULL;
$? "+ hbcont_line_new"
if(il) {
back = dk3_new_app(hb_line_t,1,app);
if(back) {
back->text = NULL;
back->aname = NULL;
back->realtext = NULL;
back->lineno = lineno;
back->header = 0UL;
back->lt = 0;
back->text = dk3str_dup_app(il, app);
if(!(back->text)) {
hbcont_line_delete(back);
back = NULL;
}
}
} $? "- hbcont_line_new %s", TR_PTR(back)
return back;
}
/** Compare two saved lines.
@param l Left line.
@param r Right line.
@param cr Comparison criteria (ignored).
@return Comparison result.
*/
static
int
hbcont_line_compare(void const *l, void const *r, int cr)
{
hb_line_t *pl;
hb_line_t *pr;
int back = 0;
$? "+ hbcont_line_compare %s %s", TR_PTR(l), TR_PTR(r)
if(l) {
if(r) {
pl = (hb_line_t *)l;
pr = (hb_line_t *)r;
if(pl->lineno > pr->lineno) {
back = 1;
} else {
if(pl->lineno < pr->lineno) {
back = -1;
}
}
} else back = 1;
} else {
if(r) back = -1;
} $? "- hbcont_line_compare %d", back
return back;
}
/** Prepare current node for content processing (allocate
storage and iterator for lines).
@param job Job structure.
@return 1 on success, 0 on error.
*/
static
int
hbcont_prepare(hb_job_t *job)
{
int back = 0;
$? "+ hbcont_prepare"
(job->currentnode)->s_lines = dk3sto_open_app(job->app);
if((job->currentnode)->s_lines) {
dk3sto_set_comp((job->currentnode)->s_lines, hbcont_line_compare, 0);
(job->currentnode)->i_lines = dk3sto_it_open((job->currentnode)->s_lines);
if((job->currentnode)->i_lines) {
back = 1;
}
} $? "- hbcont_prepare %d", back
return back;
}
/** Clean up current node (release contents lines, storage and iterator).
@param job Job structure.
*/
static
void
hbcont_cleanup(hb_job_t *job)
{
hb_line_t *lp;
$? "+ hbcont_cleanup"
if((job->currentnode)->s_lines) {
if((job->currentnode)->i_lines) {
dk3sto_it_reset((job->currentnode)->i_lines);
do {
lp = (hb_line_t *)dk3sto_it_next((job->currentnode)->i_lines);
hbcont_line_delete(lp);
} while(lp);
dk3sto_it_close((job->currentnode)->i_lines);
}
dk3sto_close((job->currentnode)->s_lines);
}
(job->currentnode)->s_lines = NULL;
(job->currentnode)->i_lines = NULL;
$? "- hbcont_cleanup"
}
/** Check whether a line is a header line.
@param il Line to check.
@return 1 for headers, 0 for normal lines.
*/
static
int
hbcont_check_header(dkChar *il)
{
int back = 0;
$? "+ hbcont_check_header \"%s\"", TR_STR(il)
if(dkT('.') == *il) {
il++;
il = dk3str_start(il, NULL);
if(il) {
switch(*il) {
case dkT('1'): case dkT('2'): case dkT('3'):
case dkT('4'): case dkT('5'): case dkT('6'): {
back = 1;
} break;
}
}
} $? "- hbcont_check_header %d", back
return back;
}
/** Line handler processing function.
@param obj Handler object.
@param il Input line to process.
@return 1 on success, 0 on error (continue), -1 on error (exit).
*/
static
int
hbcont_line_handler(void *obj, dkChar *il)
{
hb_contents_line_processor_t *proc; /* Processor */
hb_job_t *job; /* Job structure */
hb_node_t *nptr; /* Current node */
hb_line_t *lptr; /* Current line structure */
dkChar *p1; /* Start of line */
dkChar *p2; /* Start of a name */
dkChar *p3; /* Start of real text */
unsigned u; /* Header level */
int back = 0;
dk3str_delnl(il);
$? "+ hbcont_line_handler \"%s\"", il
proc = (hb_contents_line_processor_t *)obj;
proc->lineno += 1UL;
job = proc->job;
nptr = job->currentnode;
lptr = hbcont_line_new(il, proc->lineno, job->app);
if(lptr) {
if(dk3sto_add(nptr->s_lines, lptr)) {
back = 1;
p1 = dk3str_start(lptr->text, NULL);
if(p1) {
if(hbcont_check_header(p1)) {
back = 0;
p1++;
p1 = dk3str_start(p1, NULL);
if(p1) {
p2 = dk3str_next(p1, NULL);
if(p2) {
lptr->realtext = p2;
lptr->lt = 1;
#if VERSION_BEFORE_20140716
if(dk3sf_sscanf3(p1, dkT("%u"), &u) == 1)
#else
if (0 != dk3ma_ui_from_string(&u, p1, NULL))
#endif
{
lptr->headlevel = u;
lptr->header = proc->nheader;
if(u > proc->maxheader) { proc->maxheader = u; }
proc->nheader += 1UL;
back = 1;
if(dkT('@') == *p2) {
back = 0;
*(p2++) = dkT('\0');
p2 = dk3str_start(p2, NULL);
if(p2) {
p3 = dk3str_chr(p2, dkT('@'));
if(p3) {
*(p3++) = dkT('\0');
p3 = dk3str_start(p3, NULL);
if(p3) {
lptr->aname = p2;
lptr->realtext = p3;
back = 1;
} else { $? "! Missing heading text"
/* ERROR: Missing heading text */
dk3app_log_1(job->app,DK3_LL_ERROR,job->msg,32);
}
} else { $? "! no closing @"
/* ERROR: Missing closing @ */
dk3app_log_1(job->app,DK3_LL_ERROR,job->msg,33);
}
} else { $? "! no text after @"
/* ERROR: No a name text */
dk3app_log_1(job->app,DK3_LL_ERROR,job->msg,34);
}
}
} else { $? "! sscanf3"
/* ERROR: No header level */
dk3app_log_1(job->app,DK3_LL_ERROR,job->msg,35);
}
} else { $? "! no header text"
/* ERROR: No header text */
dk3app_log_1(job->app,DK3_LL_ERROR,job->msg,32);
}
} else { $? "! no text after dot"
/* ERROR: Syntax, no text after dot */
dk3app_log_1(job->app,DK3_LL_ERROR,job->msg,36);
}
}
}
} else { $? "! dk3sto_add"
}
} else { $? "! lptr"
}
$? "- hbcont_line_handler %d", back
return back;
}
/** Read contents into storage.
@param job Job structure.
@param proc Line processing structure.
@return 1 on success, 0 on errors.
*/
static
int
hbcont_read(hb_job_t *job, hb_contents_line_processor_t *proc)
{
int res; /* Result from file processing */
int inenc; /* Input encoding */
int back = 0;
$? "+ hbcont_read"
inenc = dk3app_get_input_file_encoding(job->app);
if(0 <= job->iecmd) { inenc = job->iecmd; }
if(0 <= (job->currentnode)->inenc) { inenc = (job->currentnode)->inenc; }
if((job->currentnode)->filename) {
res = dk3stream_process_filename_lines_app(
(void *)proc, hbcont_line_handler, (job->currentnode)->filename,
job->ilfile, job->bs,
dk3app_get_encoding(job->app),
inenc,
job->app
);
if(1 == res) { back = 1; } $? "- hbcont_read %d", back
} else {
if(0UL == (job->currentnode)->objno) {
back = 1;
}
}
return back;
}
/** Write HTML page title.
@param job Job structure.
@return 1 on success, 0 on error.
*/
static
int
hbcont_write_title(hb_job_t *job)
{
int back = 0;
$? "+ hbcont_write_title"
fputs(hbcont_c8_kw[2], job->of);
if((job->currentnode)->title) {
if (((job->options) & HB_JOB_OPT_NUM_IN_PAGE_HEADER)) {
if (!((job->options) & HB_JOB_OPT_CHM)) {
if((job->currentnode)->depth < job->headlevels) {
if(hbtool_write_header_number(job, job->currentnode)) {
hbhtml_output_for_text(job, (job->kwnl[35]));
}
}
}
}
back = hbhtml_output_for_text(job, (job->currentnode)->title);
}
fputs(hbcont_c8_kw[3], job->of);
$? "- hbcont_write_title %d", back
return back;
}
/** Write position of current node.
@param job Job structure.
@return 1 on success, 0 on error.
*/
static
int
hbcont_write_position(hb_job_t *job)
{
hb_node_t *nptr; /* Current node to handle. */
int i;
int rs; /* td width */
int curl = 0; /* Current level */
int maxl = 0; /* Maximum level */
int back = 1;
$? "+ hbcont_write_position"
nptr = job->rootnode;
while(nptr) {
if((nptr->parent) && (nptr->curchild)) {
maxl++;
}
nptr = nptr->curchild;
}
#if TRACE_DEBUG
/* DEBUG */ fprintf(job->of , "\n", maxl);
#endif
if(0 < maxl) {
fputs(hbcont_c8_kw[49], job->of);
fputs(hbcont_c8_kw[4], job->of);
if(!hbhtml_output_for_text(job, (job->msg)[54])) { back = 1; }
fputs(hbcont_c8_kw[46], job->of);
fputs(hbcont_c8_kw[0], job->of);
nptr = job->rootnode;
while(nptr) {
dk3app_set_source_line(job->app, nptr->lineno);
if((nptr->parent) && (nptr->curchild)) {
#if TRACE_DEBUG
/* DEBUG */ fprintf(job->of, "\n", curl, maxl);
#endif
fputs(hbcont_c8_kw[6], job->of);
if(0 < curl) {
for(i = 0; i < (curl - 1); i++) {
fputs(hbcont_c8_kw[8], job->of);
fputs(hbcont_c8_kw[9], job->of);
}
fputs(hbcont_c8_kw[8], job->of);
fputs(hbcont_c8_kw[10], job->of);
fputs(hbcont_c8_kw[9], job->of);
}
rs = maxl - curl;
fprintf(job->of, hbcont_c8_kw[11], rs);
if(nptr->title) {
#if (!(VERSION_BEFORE_20140412))
/* 2014-04-12
Also write header number in position.
*/
if ((job->options) & HB_JOB_OPT_NUM_IN_POS) {
if (hbtool_write_header_number(job, nptr)) {
if (!hbhtml_output_for_text(job, dkT(" "))) {
back = 0;
}
}
}
#endif
if(!hbhtml_output_for_text(job, nptr->title)) {
back = 0;
}
}
fputs(hbcont_c8_kw[9], job->of);
fputs(hbcont_c8_kw[7], job->of);
curl++;
}
nptr = nptr->curchild;
}
fputs(hbcont_c8_kw[5], job->of);
fputs(hbcont_c8_kw[30], job->of);
fputs(hbcont_c8_kw[0], job->of);
} $? "- hbcont_write_position %d", back
return back;
}
/** Write anchor name for a header line.
@param job Job structure.
@param lptr Line to process.
@return 1 on success, 0 on error.
*/
static
int
hbcont_write_anchor_name_for_header(hb_job_t *job, hb_line_t *lptr)
{
char buffer[64]; /* Buffer to convert number to text */
int back = 1;
$? "+ hbcont_write_anchor_name_for_header"
if(lptr->aname) {
if(!hbhtml_url_output_for_text(job, lptr->aname)) {
back = 0;
}
} else {
#if DK3_SIZEOF_LONG > 4
sprintf(buffer, "%016lx", lptr->header);
#else
sprintf(buffer, "%08lx", lptr->header);
#endif
fputs(hbcont_c8_kw[16], job->of);
fputs(buffer, job->of);
} $? "- hbcont_write_anchor_name_for_header %d", back
return back;
}
/** Process the content lines saved before.
@param job Job structure.
@param proc Line processing structure.
@param p Previous node.
@param n Next node.
@return 1 on success, 0 on error.
*/
static
int
hbcont_write_contents(
hb_job_t *job,
hb_contents_line_processor_t *proc,
hb_node_t *p,
hb_node_t *n
)
{
hb_file_processor_t myproc;
hb_line_t *lptr; /* Current line to process */
hb_line_t *tocptr; /* Current TOC line to process */
hb_node_t *nptr; /* Current node to process */
dk3_sto_it_t *i_toc; /* Line traversal for TOC */
unsigned cs = 0; /* Column space */
unsigned sp = 0; /* Spaces before data field */
unsigned hl = 0; /* Header level */
unsigned i = 0; /* Create spaces */
int tocpr = 0; /* Flag: Page TOC already printed */
int back = 0;
$? "+ hbcont_write_contents \"%s\"", TR_STR((job->currentnode)->title)
if((job->options) & HB_JOB_OPT_CHM) { tocpr = 1; }
nptr = job->currentnode;
i_toc = dk3sto_it_open(nptr->s_lines);
if(i_toc) {
dk3sto_it_reset(nptr->i_lines);
dk3sto_it_reset(i_toc);
back = 1;
do {
lptr = (hb_line_t *)dk3sto_it_next(nptr->i_lines);
if(lptr) {
dk3app_set_source_line(job->app, lptr->lineno);
if(lptr->lt) {
/* Header line */
if((0 == tocpr) && ((nptr->options) & HB_NODE_OPT_PAGE_TOC)) {
tocpr = 1; $? ". print page TOC"
fputs(hbcont_c8_kw[17], job->of);
if(!hbhtml_output_for_text(job, (job->msg)[55])) { back = 0; }
fputs(hbcont_c8_kw[46], job->of);
fputs(hbcont_c8_kw[0], job->of);
do {
tocptr = (hb_line_t *)dk3sto_it_next(i_toc);
if(tocptr) {
if(tocptr->lt) {
dk3app_set_source_line(job->app, tocptr->lineno);
sp = 0;
#if 0
if(tocptr->headlevel < proc->maxheader) {
sp = proc->maxheader - tocptr->headlevel;
}
#endif
if(tocptr->headlevel > 0) {
sp = tocptr->headlevel - 1;
}
cs = proc->maxheader - sp;
fputs(hbcont_c8_kw[19], job->of);
for(i = 0; i < sp; i++) {
fputs(hbcont_c8_kw[21], job->of);
}
fprintf(job->of, hbcont_c8_kw[22], cs);
fputs(hbcont_c8_kw[24], job->of);
if(!hbcont_write_anchor_name_for_header(job, tocptr)) {
back = 0;
}
fputs(hbcont_c8_kw[25], job->of);
if(!hbhtml_output_for_text(job, tocptr->realtext)) {
back = 0;
}
fputs(hbcont_c8_kw[26], job->of);
if(!hbhtml_output_for_text(job, tocptr->realtext)) {
back = 0;
}
fputs(hbcont_c8_kw[27], job->of);
fputs(hbcont_c8_kw[23], job->of);
fputs(hbcont_c8_kw[20], job->of);
dk3app_set_source_line(job->app, lptr->lineno);
}
}
} while(tocptr);
fputs(hbcont_c8_kw[18], job->of);
}
hl = 1 + lptr->headlevel;
if(6 < hl) {
hl = 6;
/* Warning: Header level corrected to 6! */
dk3app_log_1(job->app,DK3_LL_ERROR,job->msg,37);
}
fprintf(job->of, hbcont_c8_kw[14], hl);
if(!hbcont_write_anchor_name_for_header(job, lptr)) {
back = 0; $? "! ERROR"
}
fprintf(job->of, hbcont_c8_kw[15], hl);
fprintf(job->of, hbcont_c8_kw[12], hl);
if(!hbhtml_output_for_text(job, lptr->realtext)) {
back = 0; $? "! ERROR"
}
fprintf(job->of, hbcont_c8_kw[13], hl);
} else {
myproc.job = job;
myproc.in_template = 0;
myproc.stm = 0;
myproc.p = p;
myproc.n = n; $? ". text = \"%s\"", lptr->text
if(1 != hbhtml_line_handler((void *)(&myproc), lptr->text)) {
back = 0; $? "! processing failed"
}
}
}
} while(lptr);
dk3sto_it_close(i_toc);
} $? "- hbcont_write_contents %d", back
return back;
}
/** Write list of external links for current node.
@param job Job structure.
@return 1 on success, 0 on error.
*/
static
int
hbcont_write_link_list(hb_job_t *job)
{
hb_link_t *linkptr; /* Current link to process */
hb_node_t *nptr; /* Current node to process */
int back = 1;
$? "+ hbcont_write_link_list \"%s\"", TR_STR((job->currentnode)->title)
nptr = job->currentnode;
if(nptr->nextlink) {
dk3sto_it_reset(nptr->i_lbylno);
fputs(hbcont_c8_kw[28], job->of);
if(!hbhtml_output_for_text(job, (job->msg)[23])) { back = 0; }
fputs(hbcont_c8_kw[29], job->of);
fputs(hbcont_c8_kw[31], job->of);
if(!hbhtml_output_for_text(job, (job->msg)[56])) { back = 0; }
fputs(hbcont_c8_kw[46], job->of);
fputs(hbcont_c8_kw[0], job->of);
while(NULL != (linkptr = (hb_link_t *)dk3sto_it_next(nptr->i_lbylno))) {
fputs(hbcont_c8_kw[33], job->of);
/* Number */
fputs(hbcont_c8_kw[35], job->of);
fprintf(job->of, hbcont_c8_kw[37], (1UL + linkptr->lno));
fputs(hbcont_c8_kw[36], job->of);
/* URL */
fputs(hbcont_c8_kw[38], job->of);
if(!hbhtml_url_output_for_text(job, linkptr->url)) { back = 1; }
fputs(hbcont_c8_kw[36], job->of);
fputs(hbcont_c8_kw[34], job->of);
}
fputs(hbcont_c8_kw[32], job->of);
fputs(hbcont_c8_kw[30], job->of);
} $? "- hbcont_write_link_list %d", back
return back;
}
/** Create project table of contents.
@param job Job structure.
@return 1 on success, 0 on error.
*/
static
int
hbcont_create_toc(hb_job_t *job)
{
dkChar ofn[DK3_MAX_PATH]; /* Output file name */
hb_node_t *nptr; /* Current node to process */
hb_node_t *dest; /* Print node for cur node */
dkChar const *oldsourcefile; /* Old source file name saved */
unsigned long oldsourceline; /* Old source file line saved */
int res; /* Result from file name cr */
int i;
int back = 1;
$? "+ hbcont_create_toc"
oldsourcefile = dk3app_get_source_file(job->app);
oldsourceline = dk3app_get_source_line(job->app);
dk3app_set_source_file(job->app, job->infilename);
dk3app_set_source_line(job->app, 0UL);
fputs(hbcont_c8_kw[47], job->of);
if(!hbhtml_output_for_text(job, (job->msg)[45])) { back = 0; }
fputs(hbcont_c8_kw[48], job->of);
fputs(hbcont_c8_kw[39], job->of);
if(!hbhtml_output_for_text(job, (job->msg)[57])) { back = 0; }
fputs(hbcont_c8_kw[46], job->of);
fputs(hbcont_c8_kw[0], job->of);
nptr = job->rootnode;
while(nptr) {
$? ". Handling node %lu \"%s\"", nptr->objno, nptr->title
dk3app_set_source_line(job->app, nptr->lineno);
switch(nptr->tocstate) {
case HB_TOC_STATE_INIT: { $? ". initialize node %lu", nptr->objno
if(nptr->parent) {
/* Write TOC entry */
dest = NULL;
if(nptr->filename) {
dest = nptr;
} else {
if(nptr->jumpnode) {
dest = nptr->jumpnode;
}
}
if(dest) { $? ". dest = %lu \"%s\"", dest->objno, dest->title
res =
hbhtml_create_output_filename(ofn,DK3_SIZEOF(ofn,dkChar),job,dest);
if(res) {
fputs(hbcont_c8_kw[41], job->of);
for(i = 1; i < nptr->depth; i++) {
fputs(hbcont_c8_kw[43], job->of);
}
fprintf(
job->of, hbcont_c8_kw[44], ((job->maxdepth) - (nptr->depth) + 1)
);
fputs(hbcont_c8_kw[45], job->of);
if(!hbhtml_url_output_for_text(job, ofn)) { back = 0; }
fputs(hbcont_c8_kw[25], job->of);
if(hbtool_write_header_number(job, nptr)) {
fputs(hbcont_c8_kw[1], job->of);
}
if(!hbhtml_output_for_text(job, nptr->title)) { back = 0; }
fputs(hbcont_c8_kw[46], job->of);
if(hbtool_write_header_number(job, nptr)) {
fputs(hbcont_c8_kw[1], job->of);
}
if(!hbhtml_output_for_text(job, nptr->title)) { back = 0; }
fputs(hbcont_c8_kw[27], job->of);
fputs(hbcont_c8_kw[9], job->of);
fputs(hbcont_c8_kw[42], job->of);
} else {
/* ERROR: Failed to create output file name */
back = 0;
}
} else { $? "! no destination node"
/* ERROR: No destination found */
back = 0;
dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 51);
}
}
dk3sto_it_reset(nptr->i_subnodes);
nptr->tocstate = HB_TOC_STATE_IN_PROGRESS;
} break;
case HB_TOC_STATE_IN_PROGRESS: { $? ". continue node %lu", nptr->objno
nptr->curchild = dk3sto_it_next(nptr->i_subnodes);
if(nptr->curchild) {
nptr = nptr->curchild;
} else {
nptr->tocstate = HB_TOC_STATE_FINISHED;
}
} break;
case HB_TOC_STATE_FINISHED: { $? ". finish node %lu", nptr->objno
nptr = nptr->parent;
} break;
}
}
fputs(hbcont_c8_kw[40], job->of);
dk3app_set_source_file(job->app, oldsourcefile);
dk3app_set_source_line(job->app, oldsourceline);
$? "- hbcont_create_toc %d", back
return back;
}
/** Create keyword index.
@param job Job structure
@return 1 on success, 0 on error.
*/
static
int
hbcont_create_keyword_index(hb_job_t *job)
{
hb_index_entry_t *pp = NULL; /* Previous pointer */
hb_index_entry_t *cp = NULL; /* Current pointer */
dk3_c32_t pstc = 0UL; /* Previous start character */
dk3_c32_t cstc = 0UL; /* Start character */
int nkw = 0; /* Flag: Open new keyword */
int hh2 = 0; /* Flag: Have division and h2 */
int back = 1;
$? "+ hbcont_create_keyword_index"
dk3sto_it_reset(job->i_index);
while(NULL != (cp = (hb_index_entry_t *)dk3sto_it_next(job->i_index))) {
$? ". have current entry \"%s\"", cp->tx
if(!(hh2)) { $? ". no header yet, write header"
hh2 = 1;
fputs(hbcont_c8_kw[50], job->of);
fputs(hbcont_c8_kw[51], job->of);
if(!hbhtml_output_for_text(job, (job->msg)[46])) { back = 0; }
fputs(hbcont_c8_kw[29], job->of);
fputs(hbcont_c8_kw[52], job->of);
}
/* Process entry.
*/
nkw = 0;
if(pp) { $? ". have previous entry"
if(dk3str_cmp(pp->tx, cp->tx)) { $? ". entries differ"
nkw = 1;
fputs(hbcont_c8_kw[57], job->of);
}
} else {
nkw = 1;
}
if(nkw) {
fputs(hbcont_c8_kw[54], job->of);
if(!hbhtml_output_for_text(job, cp->tx)) { back = 0; }
fputs(hbcont_c8_kw[55], job->of);
fputs(hbcont_c8_kw[56], job->of);
}
fputs(hbcont_c8_kw[58], job->of);
fputs(hbcont_c8_kw[60], job->of);
if(!hbhtml_url_output_for_text(job, cp->fn)) { back = 0; }
fputs(hbcont_c8_kw[61], job->of);
if(!hb_index_write_anchor(job, cp)) { back = 0; }
#if (!(VERSION_BEFORE_20140412))
fputs(hbcont_c8_kw[25], job->of);
(void)hbtool_write_all_titles(job, cp->no, 1);
#endif
fputs(hbcont_c8_kw[46], job->of);
if(cp->no) {
if((cp->no)->title) {
#if (!(VERSION_BEFORE_20140412))
if ((job->options) & HB_JOB_OPT_NUM_IN_IDX) {
if (hbtool_write_header_number(job, cp->no)) {
hbhtml_output_for_text(job, dkT(" "));
}
}
#endif
if(!hbhtml_output_for_text(job, (cp->no)->title)) { back = 0; }
} else back = 0;
} else { back = 0; }
fputs(hbcont_c8_kw[27], job->of);
fputs(hbcont_c8_kw[59], job->of);
pp = cp; pstc = cstc;
}
if(hh2) {
fputs(hbcont_c8_kw[57], job->of);
fputs(hbcont_c8_kw[53], job->of);
fputs(hbcont_c8_kw[30], job->of);
fputs(hbcont_c8_kw[0], job->of);
} $? "- hbcont_create_keyword_index %d", back
return back;
}
int
hbcont_process(hb_job_t *job, hb_node_t *p, hb_node_t *n)
{
hb_contents_line_processor_t proc;
dkChar const *oldsourcefile;
unsigned long oldsourceline;
int back = 0;
$? "+ hbcont_process %lu", (job->currentnode)->objno
oldsourcefile = dk3app_get_source_file(job->app);
oldsourceline = dk3app_get_source_line(job->app);
proc.job = job;
proc.nptr = job->currentnode;
proc.lineno = 0UL;
proc.nheader = 0UL;
proc.maxheader = 0;
dk3app_set_source_file(job->app, job->infilename);
dk3app_set_source_line(job->app, (job->currentnode)->lineno);
if(hbcont_prepare(job)) {
dk3app_set_source_file(job->app, (job->currentnode)->filename);
dk3app_set_source_line(job->app, 0UL);
if(hbcont_read(job, &proc)) {
back = 1;
/* For the root node we do not write a position.
*/
if((0UL != (job->currentnode)->objno) && ((job->currentnode)->filename)) {
if(!((job->options) & HB_JOB_OPT_CHM)) {
if(((job->currentnode)->options) & HB_NODE_OPT_HEADER_CHAIN) {
dk3app_set_source_file(job->app, job->infilename);
if(!hbcont_write_position(job)) { back = 0; }
}
}
}
dk3app_set_source_file(job->app, job->infilename);
dk3app_set_source_line(job->app, (job->currentnode)->lineno);
if(!hbcont_write_title(job)) { back = 0; }
/* We can write contents only if an input file is specified.
*/
if((job->currentnode)->filename) {
dk3app_set_source_file(job->app, (job->currentnode)->filename);
dk3app_set_source_line(job->app, 0UL);
if(!hbcont_write_contents(job, &proc, p, n)) { back = 0; }
dk3app_set_source_file(job->app, (job->currentnode)->filename);
dk3app_set_source_line(job->app, 0UL);
if((job->currentnode)->nextlink) {
if(!hbcont_write_link_list(job)) { back = 0; }
}
}
if(0UL == (job->currentnode)->objno) { $? ". TOC node"
if(!((job->options) & HB_JOB_OPT_CHM)) {
if((job->options) & HB_JOB_OPT_CREATE_TOC) { $? ". create TOC"
if(!hbcont_create_toc(job)) { back = 0; }
}
if((job->options) & HB_JOB_OPT_CREATE_INDEX) { $? ". create index"
/* Eventually create index */
if(!hbcont_create_keyword_index(job)) { back = 0; }
}
}
}
}
dk3app_set_source_file(job->app, job->infilename);
dk3app_set_source_line(job->app, (job->currentnode)->lineno);
}
hbcont_cleanup(job);
dk3app_set_source_file(job->app, oldsourcefile);
dk3app_set_source_line(job->app, oldsourceline);
$? "- hbcont_process %d", back
return back;
}
| | |