📄 clean.c
字号:
void MergeStyles(Node *node, Node *child){ AttVal *av; char *s1, *s2, *style; for (s2 = null, av = child->attributes; av; av = av->next) { if (wstrcmp(av->attribute, "style") == 0) { s2 = av->value; break; } } for (s1 = null, av = node->attributes; av; av = av->next) { if (wstrcmp(av->attribute, "style") == 0) { s1 = av->value; break; } } if (s1) { if (s2) /* merge styles from both */ { style = MergeProperties(s1, s2); MemFree(av->value); av->value = style; } } else if (s2) /* copy style of child */ { av = NewAttribute(); av->attribute = wstrdup("style"); av->value = wstrdup(s2); av->delim = '"'; av->dict = FindAttribute(av); av->next = node->attributes; node->attributes = av; }}char *FontSize2Name(char *size){#if 0 static char *sizes[7] = { "50%", "60%", "80%", null, "120%", "150%", "200%" };#endif static char *sizes[7] = { "60%", "70%", "80%", null, "120%", "150%", "200%" }; static char buf[16]; if ('0' <= size[0] && size[0] <= '6') { int n = size[0] - '0'; return sizes[n]; } if (size[0] == '-') { if ('0' <= size[1] && size[1] <= '6') { int n = size[1] - '0'; double x; for (x = 1; n > 0; --n) x *= 0.8; x *= 100; sprintf(buf, "%d%%", (int)(x)); return buf; } return "smaller"; /*"70%"; */ } if ('0' <= size[1] && size[1] <= '6') { int n = size[1] - '0'; double x; for (x = 1; n > 0; --n) x *= 1.2; x *= 100; sprintf(buf, "%d%%", (int)(x)); return buf; } return "larger"; /* "140%" */}void AddFontFace(Node *node, char *face){ char buf[1024]; sprintf(buf, "font-family: %s", face); AddStyleProperty(node, buf);}void AddFontSize(Node *node, char *size){ char *value, buf[1024]; if (wstrcmp(size, "6") == 0 && node->tag == tag_p) { MemFree(node->element); node->element = wstrdup("h1"); FindTag(node); return; } if (wstrcmp(size, "5") == 0 && node->tag == tag_p) { MemFree(node->element); node->element = wstrdup("h2"); FindTag(node); return; } if (wstrcmp(size, "4") == 0 && node->tag == tag_p) { MemFree(node->element); node->element = wstrdup("h3"); FindTag(node); return; } value = FontSize2Name(size); if (value) { sprintf(buf, "font-size: %s", value); AddStyleProperty(node, buf); }}void AddFontColor(Node *node, char *color){ char buf[1024]; sprintf(buf, "color: %s", color); AddStyleProperty(node, buf);}void AddAlign(Node *node, char *align){ char buf[1024], *p, *q; /* force alignment value to lower case */ for (p = buf, q = "text-align: "; (*p++ = *q++);); for (p = p-1; (*p++ = ToLower(*align++));); AddStyleProperty(node, buf);}/* add style properties to node corresponding to the font face, size and color attributes*/void AddFontStyles(Node *node, AttVal *av){ while (av) { if (wstrcmp(av->attribute, "face") == 0) AddFontFace(node, av->value); else if (wstrcmp(av->attribute, "size") == 0) AddFontSize(node, av->value); else if (wstrcmp(av->attribute, "color") == 0) AddFontColor(node, av->value); av = av->next; }}/* Symptom: <p align=center> Action: <p style="text-align: center">*/void TextAlign(Lexer *lexer, Node *node){ AttVal *av, *prev; prev = null; for (av = node->attributes; av; av = av->next) { if (wstrcmp(av->attribute, "align") == 0) { if (prev) prev->next = av->next; else node->attributes = av->next; MemFree(av->attribute); if (av->value) { AddAlign(node, av->value); MemFree(av->value); } MemFree(av); break; } prev = av; }}/* The clean up rules use the pnode argument to return the next node when the orignal node has been deleted*//* Symptom: <dir> <li> where <li> is only child Action: coerce <dir> <li> to <div> with indent.*/Bool Dir2Div(Lexer *lexer, Node *node, Node **pnode){ Node *child; if (node->tag == tag_dir || node->tag == tag_ul || node->tag == tag_ol) { child = node->content; if (child == null) return no; /* check child has no peers */ if (child->next) return no; if (child->tag != tag_li) return no; if (!child->implicit) return no; /* coerce dir to div */ node->tag = tag_div; MemFree(node->element); node->element = wstrdup("div"); AddStyleProperty(node, "margin-left: 2em"); StripOnlyChild(node); return yes;#if 0 content = child->content; last = child->last; child->content = null; /* adjust parent and set margin on contents of <li> */ for (child = content; child; child = child->next) { child->parent = node->parent; AddStyleProperty(child, "margin-left: 1em"); } /* hook first/last into sequence */ if (content) { content->prev = node->prev; last->next = node->next; FixNodeLinks(content); FixNodeLinks(last); } node->next = null; FreeNode(node); /* ensure that new node is cleaned */ *pnode = CleanNode(lexer, content); return yes;#endif } return no;}/* Symptom: <center> Action: replace <center> by <div style="text-align: center">*/Bool Center2Div(Lexer *lexer, Node *node, Node **pnode){ if (node->tag == tag_center) { if (DropFontTags) { if (node->content) { Node *last = node->last, *parent = node->parent; DiscardContainer(node, pnode); node = InferredTag(lexer, "br"); if (last->next) last->next->prev = node; node->next = last->next; last->next = node; node->prev = last; if (parent->last == last) parent->last = node; node->parent = parent; } else { Node *prev = node->prev, *next = node->next, *parent = node->parent; DiscardContainer(node, pnode); node = InferredTag(lexer, "br"); node->next = next; node->prev = prev; node->parent = parent; if (next) next->prev = node; else parent->last = node; if (prev) prev->next = node; else parent->content = node; } return yes; } node->tag = tag_div; MemFree(node->element); node->element = wstrdup("div"); AddStyleProperty(node, "text-align: center"); return yes; } return no;}/* Symptom <div><div>...</div></div> Action: merge the two divs This is useful after nested <dir>s used by Word for indenting have been converted to <div>s*/Bool MergeDivs(Lexer *lexer, Node *node, Node **pnode){ Node *child; if (node->tag != tag_div) return no; child = node->content; if (!child) return no; if (child->tag != tag_div) return no; if (child->next != null) return no; MergeStyles(node, child); StripOnlyChild(node); return yes;}/* Symptom: <ul><li><ul>...</ul></li></ul> Action: discard outer list*/Bool NestedList(Lexer *lexer, Node *node, Node **pnode){ Node *child, *list; if (node->tag == tag_ul || node->tag == tag_ol) { child = node->content; if (child == null) return no; /* check child has no peers */ if (child->next) return no; list = child->content; if (!list) return no; if (list->tag != node->tag) return no; *pnode = node->next; /* move inner list node into position of outer node */ list->prev = node->prev; list->next = node->next; list->parent = node->parent; FixNodeLinks(list); /* get rid of outer ul and its li */ child->content = null; node->content = null; node->next = null; FreeNode(node); /* If prev node was a list the chances are this node should be appended to that list. Word has no way of recognizing nested lists and just uses indents */ if (list->prev) { node = list; list = node->prev; if (list->tag == tag_ul || list->tag == tag_ol) { list->next = node->next; if (list->next) list->next->prev = list; child = list->last; /* <li> */ node->parent = child; node->next = null; node->prev = child->last; FixNodeLinks(node); } } CleanNode(lexer, node); return yes; } return no;}/* Symptom: the only child of a block-level element is a presentation element such as B, I or FONT Action: add style "font-weight: bold" to the block and strip the <b> element, leaving its children. example: <p> <b><font face="Arial" size="6">Draft Recommended Practice</font></b> </p> becomes: <p style="font-weight: bold; font-family: Arial; font-size: 6"> Draft Recommended Practice </p> This code also replaces the align attribute by a style attribute. However, to avoid CSS problems with Navigator 4, this isn't done for the elements: caption, tr and table*/Bool BlockStyle(Lexer *lexer, Node *node, Node **pnode){ Node *child; if (node->tag->model & (CM_BLOCK | CM_LIST | CM_DEFLIST | CM_TABLE)) { if (node->tag != tag_table && node->tag != tag_tr && node->tag != tag_li) { /* check for align attribute */ if (node->tag != tag_caption) TextAlign(lexer, node); child = node->content; if (child == null) return no; /* check child has no peers */ if (child->next) return no; if (child->tag == tag_b)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -