📄 parser.c
字号:
if a font element wraps an anchor and nothing else then move the font element inside the anchor since otherwise it won't alter the anchor text color */ if (element->tag == tag_font && element->content && element->content == element->last) { Node *child = element->content; if (child->tag == tag_a) { child->parent = element->parent; child->next = element->next; child->prev = element->prev; if (child->prev) child->prev->next = child; else child->parent->content = child; if (child->next) child->next->prev = child; else child->parent->last = child; element->next = null; element->prev = null; element->parent = child; element->content = child->content; element->last = child->last; child->content = child->last = element; for (child = element->content; child; child = child->next) child->parent = element; } } element->closed = yes; TrimEmptyElement(lexer, element); return; } /* <u>...<u> map 2nd <u> to </u> if 1st is explicit */ /* otherwise emphasis nesting is probably unintentional */ if (node->type == StartTag && node->tag == element->tag && IsPushed(lexer, node) && !node->implicit && !element->implicit && node->tag && (node->tag->model & CM_INLINE) && node->tag != tag_a && node->tag != tag_font) { if (node->attributes == null && node->tag == element->tag) { ReportWarning(lexer, element, node, COERCE_TO_ENDTAG); node->type = EndTag; UngetToken(lexer); continue; } ReportWarning(lexer, element, node, NESTED_EMPHASIS); } if (node->type == TextNode) { /* only called for 1st child */ if (element->content == null && !(mode & Preformatted)) TrimTrailingSpace(lexer, element->last); if (node->start >= node->end) { FreeNode(node); continue; } InsertNodeAtEnd(element, node); continue; } /* mixed content model so allow text */ if (InsertMisc(element, node)) continue; /* deal with HTML tags */ if (node->tag == tag_html) { if (node->type == StartTag || node->type == StartEndTag) { ReportWarning(lexer, element, node, DISCARDING_UNEXPECTED); FreeNode(node); continue; } /* otherwise infer end of inline element */ UngetToken(lexer); if (!(mode & Preformatted)) TrimTrailingSpace(lexer, element->last); TrimEmptyElement(lexer, element); return; } /* within <dt> map <p> to <br> */ if (node->tag == tag_p && node->type == StartTag && (element->tag == tag_dt || DescendantOf(element, tag_dt))) { node->tag = tag_br; MemFree(node->element); node->element = wstrdup("br"); TrimTrailingSpace(lexer, element->last); InsertNodeAtEnd(element, node); continue; } /* ignore unknown and PARAM tags */ if (node->tag == null || node->tag == tag_param) { ReportWarning(lexer, element, node, DISCARDING_UNEXPECTED); FreeNode(node); continue; } if (node->tag == tag_br && node->type == EndTag) node->type = StartTag; if (node->type == EndTag) { /* coerce </br> to <br> */ if (node->tag == tag_br) node->type = StartTag; else if (node->tag == tag_p) { /* coerce unmatched </p> to <br><br> */ if (!DescendantOf(element, tag_p)) { CoerceNode(lexer, node, tag_br); TrimTrailingSpace(lexer, element->last); InsertNodeAtEnd(element, node); node = InferredTag(lexer, "br"); continue; } } else if (node->tag->model & CM_INLINE && node->tag != tag_a && !(node->tag->model & CM_OBJECT) && element->tag->model & CM_INLINE) { /* allow any inline end tag to end current element */ PopInline(lexer, element); if (element->tag != tag_a) { if (node->tag == tag_a && node->tag != element->tag) { ReportWarning(lexer, element, node, MISSING_ENDTAG_BEFORE); UngetToken(lexer); } else { ReportWarning(lexer, element, node, NON_MATCHING_ENDTAG); FreeNode(node); } if (!(mode & Preformatted)) TrimTrailingSpace(lexer, element->last); TrimEmptyElement(lexer, element); return; } /* if parent is <a> then discard unexpected inline end tag */ ReportWarning(lexer, element, node, DISCARDING_UNEXPECTED); FreeNode(node); continue; } /* special case </tr> etc. for stuff moved in front of table */ else if (lexer->exiled && node->tag->model && (node->tag->model & CM_TABLE)) { UngetToken(lexer); TrimTrailingSpace(lexer, element->last); TrimEmptyElement(lexer, element); return; } } /* allow any header tag to end current header */ if (node->tag->model & CM_HEADING && element->tag->model & CM_HEADING) { ReportWarning(lexer, element, node, NON_MATCHING_ENDTAG); FreeNode(node); if (!(mode & Preformatted)) TrimTrailingSpace(lexer, element->last); TrimEmptyElement(lexer, element); return; } /* an <A> tag to ends any open <A> element but <A href=...> is mapped to </A><A href=...> */ if (node->tag == tag_a && !node->implicit && IsPushed(lexer, node)) { /* coerce <a> to </a> unless it has some attributes */ if (node->attributes == null) { node->type = EndTag; ReportWarning(lexer, element, node, COERCE_TO_ENDTAG); PopInline(lexer, node); UngetToken(lexer); continue; } UngetToken(lexer); ReportWarning(lexer, element, node, MISSING_ENDTAG_BEFORE); PopInline(lexer, element); if (!(mode & Preformatted)) TrimTrailingSpace(lexer, element->last); TrimEmptyElement(lexer, element); return; } if (element->tag->model & CM_HEADING) { if (node->tag == tag_center || node->tag == tag_div) { if (node->type != StartTag && node->type != StartEndTag) { ReportWarning(lexer, element, node, DISCARDING_UNEXPECTED); FreeNode(node); continue; } ReportWarning(lexer, element, node, TAG_NOT_ALLOWED_IN); /* insert center as parent if heading is empty */ if (element->content == null) { InsertNodeAsParent(element, node); continue; } /* split heading and make center parent of 2nd part */ InsertNodeAfterElement(element, node); if (!(mode & Preformatted)) TrimTrailingSpace(lexer, element->last); element = CloneNode(lexer, element); InsertNodeAtEnd(node, element); continue; } if (node->tag == tag_hr) { if (node->type != StartTag && node->type != StartEndTag) { ReportWarning(lexer, element, node, DISCARDING_UNEXPECTED); FreeNode(node); continue; } ReportWarning(lexer, element, node, TAG_NOT_ALLOWED_IN); /* insert hr before heading if heading is empty */ if (element->content == null) { InsertNodeBeforeElement(element, node); continue; } /* split heading and insert hr before 2nd part */ InsertNodeAfterElement(element, node); if (!(mode & Preformatted)) TrimTrailingSpace(lexer, element->last); element = CloneNode(lexer, element); InsertNodeAfterElement(node, element); continue; } } if (element->tag == tag_dt) { if (node->tag == tag_hr) { Node *dd; if (node->type != StartTag && node->type != StartEndTag) { ReportWarning(lexer, element, node, DISCARDING_UNEXPECTED); FreeNode(node); continue; } ReportWarning(lexer, element, node, TAG_NOT_ALLOWED_IN); dd = InferredTag(lexer, "dd"); /* insert hr within dd before dt if dt is empty */ if (element->content == null) { InsertNodeBeforeElement(element, dd); InsertNodeAtEnd(dd, node); continue; } /* split dt and insert hr within dd before 2nd part */ InsertNodeAfterElement(element, dd); InsertNodeAtEnd(dd, node); if (!(mode & Preformatted)) TrimTrailingSpace(lexer, element->last); element = CloneNode(lexer, element); InsertNodeAfterElement(dd, element); continue; } } /* if this is the end tag for an ancestor element then infer end tag for this element */ if (node->type == EndTag) { for (parent = element->parent; parent != null; parent = parent->parent) { if (node->tag == parent->tag) { if (!(element->tag->model & CM_OPT) && !element->implicit) ReportWarning(lexer, element, node, MISSING_ENDTAG_BEFORE); if (element->tag == tag_a) PopInline(lexer, element); UngetToken(lexer); if (!(mode & Preformatted)) TrimTrailingSpace(lexer, element->last); TrimEmptyElement(lexer, element); return; } } } /* block level tags end this element */ if (!(node->tag->model & CM_INLINE)) { if (node->type != StartTag) { ReportWarning(lexer, element, node, DISCARDING_UNEXPECTED); continue; } if (!(element->tag->model & CM_OPT)) ReportWarning(lexer, element, node, MISSING_ENDTAG_BEFORE); if (node->tag->model & CM_HEAD && !(node->tag->model & CM_BLOCK)) { MoveToHead(lexer, element, node); continue; } /* prevent anchors from propagating into block tags except for headings h1 to h6 */ if (element->tag == tag_a) { if (node->tag && !(node->tag->model & CM_HEADING)) PopInline(lexer, element); else if (!(element->content)) { DiscardElement(element); UngetToken(lexer); return; } } UngetToken(lexer); if (!(mode & Preformatted)) TrimTrailingSpace(lexer, element->last); TrimEmptyElement(lexer, element); return; } /* parse inline element */ if (node->type == StartTag || node->type == StartEndTag) { if (node->implicit) ReportWarning(lexer, element, node, INSERTING_TAG); /* trim white space before <br> */ if (node->tag == tag_br) TrimSpace(lexer, element->last); InsertNodeAtEnd(element, node); ParseTag(lexer, node, mode); continue; } /* discard unexpected tags */ ReportWarning(lexer, element, node, DISCARDING_UNEXPECTED); FreeNode(node); } if (!(element->tag->model & CM_OPT)) ReportWarning(lexer, element, node, MISSING_ENDTAG_FOR); TrimEmptyElement(lexer, element);}void ParseDefList(Lexer *lexer, Node *list, uint mode){ Node *node, *parent; if (list->tag->model & CM_EMPTY) return; lexer->insert = null; /* defer implicit inline start tags */ while ((node = GetToken(lexer, IgnoreWhitespace)) != null) { if (node->tag == list->tag && node->type == EndTag) { FreeNode(node); list->closed = yes; TrimEmptyElement(lexer, list); return; } /* deal with comments etc. */ if (InsertMisc(list, node)) continue; if (node->type == TextNode) { UngetToken(lexer); node = InferredTag(lexer, "dt"); ReportWarning(lexer, list, node, MISSING_STARTTAG); } if (node->tag == null) { ReportWarning(lexer, list, node, DISCARDING_UNEXPECTED); FreeNode(node); continue; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -