[ncman] handle paras and free text #2323

pull/2441/head
nick black 3 years ago committed by nick black
parent 55f48fb6e9
commit a50cd595c0

@ -212,6 +212,7 @@ static const trofftype trofftypes[] = {
#define TROFF_SYNOPSIS(x) { .ltype = LINE_##x, .symbol = #x, .ttype = TROFF_SYNOPSIS, },
TROFF_SYNOPSIS(OP) TROFF_SYNOPSIS(SY) TROFF_SYNOPSIS(YS)
#undef TROFF_SYNOPSIS
{ .ltype = LINE_UNKNOWN, .symbol = "hy", .ttype = TROFF_UNKNOWN, },
};
// the troff trie is only defined on the 128 ascii values.
@ -445,7 +446,7 @@ lex_title(pagedom* dom){
}
static pagenode*
add_subsection(pagenode* pnode, char* text){
add_node(pagenode* pnode, char* text){
unsigned ncount = pnode->subcount + 1;
pagenode* tmpsubs = realloc(pnode->subs, sizeof(*pnode->subs) * ncount);
if(tmpsubs == NULL){
@ -460,29 +461,33 @@ add_subsection(pagenode* pnode, char* text){
return r;
}
static pagenode*
add_section(pagedom* dom, char* text){
unsigned ncount = dom->root->subcount + 1;
pagenode* tmpsubs = realloc(dom->root->subs, sizeof(*dom->root->subs) * ncount);
if(tmpsubs == NULL){
static char*
extract_text(const unsigned char* ws, const unsigned char* feol){
if(ws == feol || ws + 1 == feol){
fprintf(stderr, "bogus empty title\n");
return NULL;
}
dom->root->subs = tmpsubs;
pagenode* r = dom->root->subs + dom->root->subcount;
dom->root->subcount = ncount;
memset(r, 0, sizeof(*r));
r->text = text;
//fprintf(stderr, "ADDED SECTION %s %u\n", text, dom->root->subcount);
return r;
return strndup((const char*)ws + 1, feol - ws);
}
static char*
extract_text(const unsigned char* ws, const unsigned char* feol){
augment_text(pagenode* pnode, const unsigned char* ws, const unsigned char* feol){
if(ws == feol || ws + 1 == feol){
fprintf(stderr, "bogus empty title\n");
fprintf(stderr, "bogus empty text\n");
return NULL;
}
return strndup((const char*)ws + 1, feol - ws);
const size_t slen = pnode->text ? strlen(pnode->text) + 1 : 0;
char* tmp = realloc(pnode->text, slen + (feol - ws) + 2);
if(tmp == NULL){
return NULL;
}
pnode->text = tmp;
if(slen){
pnode->text[slen - 1] = ' ';
}
memcpy(pnode->text + slen, ws, feol - ws + 1);
pnode->text[slen + (feol - ws + 1)] = '\0';
return pnode->text;
}
// extract the page structure.
@ -492,6 +497,7 @@ troff_parse(const unsigned char* map, size_t mlen, pagedom* dom){
const unsigned char* line = map;
pagenode* current_section = NULL;
pagenode* current_subsection = NULL;
pagenode* current_para = NULL;
for(size_t off = 0 ; off < mlen ; ++off){
const unsigned char* ws = line;
size_t left = mlen - off;
@ -528,17 +534,23 @@ troff_parse(const unsigned char* map, size_t mlen, pagedom* dom){
if(lex_title(dom)){
return -1;
}
current_para = dom->root;
}else if(node->ltype == LINE_SH){
if(dom->root == NULL){
fprintf(stderr, "section transcends structure\n");
return -1;
}
char* et = extract_text(ws, feol);
if(et == NULL){
return -1;
}
if((current_section = add_section(dom, et)) == NULL){
if((current_section = add_node(dom->root, et)) == NULL){
free(et);
return -1;
}
current_section->ttype = node;
current_subsection = NULL;
current_para = current_section;
}else if(node->ltype == LINE_SS){
char* et = extract_text(ws, feol);
if(et == NULL){
@ -549,11 +561,31 @@ troff_parse(const unsigned char* map, size_t mlen, pagedom* dom){
free(et);
return -1;
}
if((current_subsection = add_subsection(current_section, et)) == NULL){
if((current_subsection = add_node(current_section, et)) == NULL){
free(et);
return -1;
}
current_subsection->ttype = node;
current_para = current_subsection;
}else if(node->ltype == LINE_PP){
if(dom->root == NULL){
fprintf(stderr, "paragraph transcends structure\n");
return -1;
}
if((current_para = add_node(current_para, NULL)) == NULL){
return -1;
}
current_para->ttype = node;
}
}else{
if(current_para == NULL){
fprintf(stderr, "free-floating text transcends para\n");
fprintf(stderr, "[%s]\n", line);
return -1;
}
char* et = augment_text(current_para, line, feol);
if(et == NULL){
return -1;
}
}
off += eol - line;
@ -589,6 +621,14 @@ draw_domnode(struct ncplane* p, const pagedom* dom, const pagenode* n){
ncplane_set_styles(p, NCSTYLE_NONE);
ncplane_cursor_move_yx(p, -1, 0);
break;
case LINE_PP: // paragraph
if(n->text){
ncplane_cursor_move_rel(p, 2, 0);
size_t b = 0;
ncplane_puttext(p, -1, NCALIGN_LEFT, n->text, &b);
ncplane_cursor_move_yx(p, -1, 0);
}
break;
default:
fprintf(stderr, "unhandled ltype %d\n", n->ttype->ltype);
return 0; // FIXME

Loading…
Cancel
Save