⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 clean.c

📁 我搜集到的一个java常用类库的源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
/*  clean.c -- clean up misuse of presentation markup  (c) 1998-2000 (W3C) MIT, INRIA, Keio University  See tidy.c for the copyright notice.  Filters from other formats such as Microsoft Word  often make excessive use of presentation markup such  as font tags, B, I, and the align attribute. By applying  a set of production rules, it is straight forward to  transform this to use CSS.  Some rules replace some of the children of an element by  style properties on the element, e.g.  <p><b>...</b></p> -> <p style="font-weight: bold">...</p>  Such rules are applied to the element's content and then  to the element itself until none of the rules more apply.  Having applied all the rules to an element, it will have  a style attribute with one or more properties.   Other rules strip the element they apply to, replacing  it by style properties on the contents, e.g.    <dir><li><p>...</li></dir> -> <p style="margin-left 1em">...        These rules are applied to an element before processing  its content and replace the current element by the first  element in the exposed content.  After applying both sets of rules, you can replace the  style attribute by a class value and style rule in the  document head. To support this, an association of styles  and class names is built.  A naive approach is to rely on string matching to test  when two property lists are the same. A better approach  would be to first sort the properties before matching.*/#include <stdio.h>#include <stdlib.h>#include <string.h>#include "platform.h"#include "html.h"Node *CleanNode(Lexer *lexer, Node *node);void FreeStyleProps(StyleProp *props){    StyleProp *next;    while (props)    {        next = props->next;        MemFree(props->name);        MemFree(props->value);        MemFree(props);        props = next;    }}StyleProp *InsertProperty(StyleProp *props, char *name, char *value){    StyleProp *first, *prev, *prop;    int cmp;    prev = null;    first = props;    while (props)    {        cmp = wstrcmp(props->name, name);        if (cmp == 0)        {            /* this property is already defined, ignore new value */            return first;        }        if (cmp > 0)        {            /* insert before this */            prop = (StyleProp *)MemAlloc(sizeof(StyleProp));            prop->name = wstrdup(name);            prop->value = wstrdup(value);            prop->next = props;            if (prev)                prev->next = prop;            else                first = prop;            return first;        }        prev = props;        props = props->next;    }    prop = (StyleProp *)MemAlloc(sizeof(StyleProp));    prop->name = wstrdup(name);    prop->value = wstrdup(value);    prop->next = null;    if (prev)        prev->next = prop;    else        first = prop;    return first;}/* Create sorted linked list of properties from style string It temporarily places nulls in place of ':' and ';' to delimit the strings for the property name and value. Some systems don't allow you to null literal strings, so to avoid this, a copy is made first.*/StyleProp *CreateProps(StyleProp *prop, char *style){    char *name, *value, *name_end, *value_end;    Bool more;    style = wstrdup(style);    name = style;    while (*name)    {        while (*name == ' ')            ++name;        name_end = name;        while (*name_end)        {            if (*name_end == ':')            {                value = name_end + 1;                break;            }            ++name_end;        }        if (*name_end != ':')            break;        while (*value == ' ')            ++value;        value_end = value;        more = no;        while (*value_end)        {            if (*value_end == ';')            {                more = yes;                break;            }            ++value_end;        }        *name_end = '\0';        *value_end = '\0';        prop = InsertProperty(prop, name, value);        *name_end = ':';        if (more)        {            *value_end = ';';            name = value_end + 1;            continue;        }        break;    }    MemFree(style);  /* free temporary copy */    return prop;}char *CreatePropString(StyleProp *props){    char *style, *p, *s;    int len;    StyleProp *prop;    /* compute length */    for (len = 0, prop = props; prop; prop = prop->next)    {        len += wstrlen(prop->name) + 2;        len += wstrlen(prop->value) + 2;    }    style = (char *)MemAlloc(len+1);    for (p = style, prop = props; prop; prop = prop->next)    {        s = prop->name;        while((*p++ = *s++));        *--p = ':';        *++p = ' ';        ++p;        s = prop->value;        while((*p++ = *s++));        if (prop->next == null)            break;        *--p = ';';        *++p = ' ';        ++p;    }    return style;}/*  create string with merged properties*/char *AddProperty(char *style, char *property){    StyleProp *prop;    prop = CreateProps(null, style);    prop = CreateProps(prop, property);    style = CreatePropString(prop);    FreeStyleProps(prop);    return style;}void FreeStyles(Lexer *lexer){    Style *style, *next;    for (style = lexer->styles; style; style = next)    {        next = style->next;                MemFree(style->tag);        MemFree(style->tag_class);        MemFree(style->properties);        MemFree(style);    }}char *GensymClass(char *tag){    static int n = 1;    char buf[128];    sprintf(buf, "c%d", n++);    return wstrdup(buf);}char *FindStyle(Lexer *lexer, char *tag, char *properties){    Style *style;    for (style = lexer->styles; style; style=style->next)    {        if (wstrcmp(style->tag, tag) == 0 &&            wstrcmp(style->properties, properties) == 0)            return style->tag_class;    }    style = (Style *)MemAlloc(sizeof(Style));    style->tag = wstrdup(tag);    style->tag_class = GensymClass(tag);    style->properties = wstrdup(properties);    style->next = lexer->styles;    lexer->styles = style;    return style->tag_class;}/* Find style attribute in node, and replace it by corresponding class attribute. Search for class in style dictionary otherwise gensym new class and add to dictionary. Assumes that node doesn't have a class attribute*/void Style2Rule(Lexer *lexer, Node *node){    AttVal *av;    char *classname;    for (av = node->attributes; av; av = av->next)    {        if (wstrcmp(av->attribute, "style") == 0)            break;    }    /* if style attribute already exists then append property */    if (av)    {        classname = FindStyle(lexer, node->element, av->value);        MemFree(av->attribute);        MemFree(av->value);        av->attribute = wstrdup("class");        av->value = wstrdup(classname);    }}/* create style element using rules from dictionary */void CreateStyleElement(Lexer *lexer, Node *doc){    Node *node, *head;    Style *style;    AttVal *av;    if (lexer->styles == null)        return;    node = NewNode();    node->type = StartTag;    node->implicit = yes;    node->element = wstrdup("style");    FindTag(node);    /* insert type attribute */    av = NewAttribute();    av->attribute = wstrdup("type");    av->value = wstrdup("text/css");    av->delim = '"';    av->dict = FindAttribute(av);    node->attributes = av;    lexer->txtstart = lexer->lexsize;    for (style = lexer->styles; style; style = style->next)    {        AddCharToLexer(lexer, ' ');        AddStringLiteral(lexer, style->tag);        AddCharToLexer(lexer, '.');        AddStringLiteral(lexer, style->tag_class);        AddCharToLexer(lexer, ' ');        AddCharToLexer(lexer, '{');        AddStringLiteral(lexer, style->properties);        AddCharToLexer(lexer, '}');        AddCharToLexer(lexer, '\n');    }    lexer->txtend = lexer->lexsize;    InsertNodeAtEnd(node, TextToken(lexer));    /*     now insert style element into document head     doc is root node. search its children for html node     the head node should be first child of html node    */    head = FindHead(doc);        if (head)        InsertNodeAtEnd(head, node);}/* ensure bidirectional links are consistent */void FixNodeLinks(Node *node){    Node *child;    if (node->prev)        node->prev->next = node;    else        node->parent->content = node;    if (node->next)        node->next->prev = node;    else        node->parent->last = node;    for (child = node->content; child; child = child->next)        child->parent = node;}/* used to strip child of node when the node has one and only one child*/void StripOnlyChild(Node *node){    Node *child;    child = node->content;    node->content = child->content;    node->last = child->last;    child->content = null;    FreeNode(child);    for (child = node->content; child; child = child->next)        child->parent = node;}/* used to strip font start and end tags */void DiscardContainer(Node *element, Node **pnode){    Node *node, *parent = element->parent;    if (element->content)    {        element->last->next = element->next;        if (element->next)        {            element->next->prev = element->last;            element->last->next = element->next;        }        else            parent->last = element->last;        if (element->prev)        {            element->content->prev = element->prev;            element->prev->next = element->content;        }        else            parent->content = element->content;        for (node = element->content; node; node = node->next)            node->parent = parent;        *pnode = element->content;    }    else    {        if (element->next)            element->next->prev = element->prev;        else            parent->last = element->prev;        if (element->prev)            element->prev->next = element->next;        else            parent->content = element->next;        *pnode = element->next;    }    element->next = element->content = null;    FreeNode(element);}/* Add style property to element, creating style attribute as needed and adding ; delimiter*/void AddStyleProperty(Node *node, char *property){    AttVal *av;    for (av = node->attributes; av; av = av->next)    {        if (wstrcmp(av->attribute, "style") == 0)            break;    }    /* if style attribute already exists then insert property */    if (av)    {        char *s;        s = AddProperty(av->value, property);        MemFree(av->value);        av->value = s;    }    else /* else create new style attribute */    {        av = NewAttribute();        av->attribute = wstrdup("style");        av->value = wstrdup(property);        av->delim = '"';        av->dict = FindAttribute(av);        av->next = node->attributes;        node->attributes = av;    }}/*  Create new string that consists of the  combined style properties in s1 and s2  To merge property lists, we build a linked  list of property/values and insert properties  into the list in order, merging values for  the same property name.*/char *MergeProperties(char *s1, char *s2){    char *s;    StyleProp *prop;    prop = CreateProps(null, s1);    prop = CreateProps(prop, s2);    s = CreatePropString(prop);    FreeStyleProps(prop);    return s;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -