/* parent node is "current" node in block.c */ int note_parse_tlit(struct node *parent, int current_level, unsigned char **lines) { int nlines; struct node *n; char tagbuf[8], *m = tagbuf; unsigned char *notelabel = NULL, *notetext = NULL; const unsigned char *tag = NULL, *mark = NULL; *tagbuf = '\0'; lines[0] += 6; while (isspace(lines[0][0])) ++lines[0]; if ('^' == lines[0][0]) { struct note *np; /* the note should already be registered at the tag-point in the line */ ++lines[0]; while (lines[0][0] && '^' != lines[0][0]) { *m++ = lines[0][0]; ++lines[0]; } *m = '\0'; ++lines[0]; tag = (const unsigned char *)tagbuf; np = note_find_in_line(tag); if (np) { mark = np->mark; } else { warning("tag in note does not have corresponding tag in preceding line"); return 1; } } else { if (list_len(notes_in_line)) { warning("tagged notes cannot be mixed with untagged ones"); return 1; } else { struct node *lastC = note_attach_point(parent); /* If there is no note tag we have to do two things: fix the attach point and set the tag to "1" */ if (lastC) { struct node *xmark = NULL; enum e_type e; enum block_levels l; switch (lastC->etype) { case e_l: { struct node *lastCchild = lastChild(lastC); if (lastCchild && lastCchild->etype == e_c) { /* the attach point is either the cell or its chield field if there is one */ struct node *cField = lastChild(lastCchild); if (cField->etype == e_f) lastC = cField; else lastC = lastCchild; l = WORD; } else if (lastCchild && lastCchild->etype == e_f) { /* the attach point is the field */ lastC = lastCchild; l = WORD; } else l = LINE; e = e_g_nonw; } break; case e_composite: case e_score: case e_transliteration: l = TEXT; e = e_note_link; break; case e_object: l = OBJECT; e = e_note_link; break; case e_surface: l = SURFACE; e = e_note_link; break; case e_column: l = COLUMN; e = e_note_link; break; /* FIXME: THIS CAN'T BE RIGHT */ case e_variant: l = LINE; e = e_note_link; break; default: vwarning("unhandled note parent %s", lastC->names[0].pname); break; } xmark = elem(e,NULL,lnum,l); if (e == e_g_nonw) appendAttr(xmark, attr(a_type, (unsigned char *)"notelink")); appendChild(lastC, xmark); tag = "1"; mark = note_register_tag(tag, xmark); } else { warning("nowhere to attach note mark to; please provide context and mark"); tag = NULL; } } } if (tag) { while (isspace(lines[0][0])) ++lines[0]; if (!strncmp((char*)lines[0],"@notelabel{", 11)) { lines[0] += 11; notelabel = lines[0]; while (lines[0][0] != '}') ++lines[0]; lines[0][0] = '\0'; ++lines[0]; while (isspace(lines[0][0])) ++lines[0]; } n = elem(e_note_text,NULL,lnum,current_level); appendAttr(n, attr(a_note_mark, mark)); note_register_note(tag, n); if (notelabel) set_or_append_attr(n,a_note_label,"notelabel",notelabel); /* This is a bit weird, but the last character before the content is either a space after #note:, or a space or the closer character after a note mark or label, so we are safe to play this trick with the scan_comment routine */ --lines[0]; lines[0][0] = '#'; notetext = npool_copy(scan_comment_sub(lines,&nlines,0), note_pool); (void)trans_inline(n,notetext,NULL,0); appendChild(parent,n); } return nlines; }
//======================================================== // Name : AppendAttr // Desc : add attribute //======================================================== LPXAttr _tagXMLNode::appendAttr( const char* name /*= NULL*/, const char* value /*= NULL*/ ) { return appendAttr( createAttr( name, value ) ); }