📄 link.c
字号:
{ unsigned char *type, *url; /* This is just some dirty wrapper. We emulate various things through * this, which is anyway in the spirit of <object> element, unifying * <img> and <iframe> etc. */ url = get_url_val(a, "data"); if (!url) url = get_url_val(a, "codebase"); if (!url) return; type = get_attr_val(a, "type"); if (!type) { mem_free(url); return; } if (!strncasecmp(type, "text/", 5)) { /* We will just emulate <iframe>. */ html_iframe_do(a, url); html_skip(a); } else if (!strncasecmp(type, "image/", 6)) { /* <img> emulation. */ /* TODO: Use the enclosed text as 'alt' attribute. */ html_img_do(a, url); } else { unsigned char *name = get_attr_val(a, "standby"); html_focusable(a); if (name && *name) { put_link_line("Object: ", name, url, global_doc_opts->framename); } else { put_link_line("Object: ", type, url, global_doc_opts->framename); } mem_free_if(name); } mem_free(type); mem_free(url);}voidhtml_embed(unsigned char *a){ unsigned char *type, *extension; unsigned char *object_src; /* This is just some dirty wrapper. We emulate various things through * this, which is anyway in the spirit of <object> element, unifying * <img> and <iframe> etc. */ object_src = get_url_val(a, "src"); if (!object_src || !*object_src) { mem_free_set(&object_src, NULL); return; } /* If there is no extension we want to get the default mime/type * anyway? */ extension = strrchr(object_src, '.'); if (!extension) extension = object_src; type = get_extension_content_type(extension); if (type && !strncasecmp(type, "image/", 6)) { html_img_do(a, object_src); } else { /* We will just emulate <iframe>. */ html_iframe_do(a, object_src); } mem_free_if(type); mem_free_set(&object_src, NULL);}/* Link types:Alternate Designates substitute versions for the document in which the link occurs. When used together with the lang attribute, it implies a translated version of the document. When used together with the media attribute, it implies a version designed for a different medium (or media).Stylesheet Refers to an external style sheet. See the section on external style sheets for details. This is used together with the link type "Alternate" for user-selectable alternate style sheets.Start Refers to the first document in a collection of documents. This link type tells search engines which document is considered by the author to be the starting point of the collection.Next Refers to the next document in a linear sequence of documents. User agents may choose to preload the "next" document, to reduce the perceived load time.Prev Refers to the previous document in an ordered series of documents. Some user agents also support the synonym "Previous".Contents Refers to a document serving as a table of contents. Some user agents also support the synonym ToC (from "Table of Contents").Index Refers to a document providing an index for the current document.Glossary Refers to a document providing a glossary of terms that pertain to the current document.Copyright Refers to a copyright statement for the current document.Chapter Refers to a document serving as a chapter in a collection of documents.Section Refers to a document serving as a section in a collection of documents.Subsection Refers to a document serving as a subsection in a collection of documents.Appendix Refers to a document serving as an appendix in a collection of documents.Help Refers to a document offering help (more information, links to other sources information, etc.)Bookmark Refers to a bookmark. A bookmark is a link to a key entry point within an extended document. The title attribute may be used, for example, to label the bookmark. Note that several bookmarks may be defined in each document.Some more were added, like top. --Zas */enum hlink_type { LT_UNKNOWN = 0, LT_START, LT_PARENT, LT_NEXT, LT_PREV, LT_CONTENTS, LT_INDEX, LT_GLOSSARY, LT_CHAPTER, LT_SECTION, LT_SUBSECTION, LT_APPENDIX, LT_HELP, LT_SEARCH, LT_BOOKMARK, LT_COPYRIGHT, LT_AUTHOR, LT_ICON, LT_ALTERNATE, LT_ALTERNATE_LANG, LT_ALTERNATE_MEDIA, LT_ALTERNATE_STYLESHEET, LT_STYLESHEET,};enum hlink_direction { LD_UNKNOWN = 0, LD_REV, LD_REL,};struct hlink { enum hlink_type type; enum hlink_direction direction; unsigned char *content_type; unsigned char *media; unsigned char *href; unsigned char *hreflang; unsigned char *title; unsigned char *lang; unsigned char *name;/* Not implemented yet. unsigned char *charset; unsigned char *target; unsigned char *id; unsigned char *class; unsigned char *dir;*/};struct lt_default_name { enum hlink_type type; unsigned char *str;};/* TODO: i18n *//* XXX: Keep the (really really ;) default name first */static struct lt_default_name lt_names[] = { { LT_START, "start" }, { LT_START, "top" }, { LT_START, "home" }, { LT_PARENT, "parent" }, { LT_PARENT, "up" }, { LT_NEXT, "next" }, { LT_PREV, "previous" }, { LT_PREV, "prev" }, { LT_CONTENTS, "contents" }, { LT_CONTENTS, "toc" }, { LT_INDEX, "index" }, { LT_GLOSSARY, "glossary" }, { LT_CHAPTER, "chapter" }, { LT_SECTION, "section" }, { LT_SUBSECTION, "subsection" }, { LT_SUBSECTION, "child" }, { LT_SUBSECTION, "sibling" }, { LT_APPENDIX, "appendix" }, { LT_HELP, "help" }, { LT_SEARCH, "search" }, { LT_BOOKMARK, "bookmark" }, { LT_ALTERNATE_LANG, "alt. language" }, { LT_ALTERNATE_MEDIA, "alt. media" }, { LT_ALTERNATE_STYLESHEET, "alt. stylesheet" }, { LT_STYLESHEET, "stylesheet" }, { LT_ALTERNATE, "alternate" }, { LT_COPYRIGHT, "copyright" }, { LT_AUTHOR, "author" }, { LT_AUTHOR, "made" }, { LT_AUTHOR, "owner" }, { LT_ICON, "icon" }, { LT_UNKNOWN, NULL }};/* Search for default name for this link according to its type. */static unsigned char *get_lt_default_name(struct hlink *link){ struct lt_default_name *entry = lt_names; assert(link); while (entry && entry->str) { if (entry->type == link->type) return entry->str; entry++; } return "unknown";}static voidhtml_link_clear(struct hlink *link){ assert(link); mem_free_if(link->content_type); mem_free_if(link->media); mem_free_if(link->href); mem_free_if(link->hreflang); mem_free_if(link->title); mem_free_if(link->lang); mem_free_if(link->name); memset(link, 0, sizeof(*link));}/* Parse a link and return results in @link. * It tries to identify known types. */static inthtml_link_parse(unsigned char *a, struct hlink *link){ int i; assert(a && link); memset(link, 0, sizeof(*link)); link->href = get_url_val(a, "href"); if (!link->href) return 0; link->lang = get_attr_val(a, "lang"); link->hreflang = get_attr_val(a, "hreflang"); link->title = get_attr_val(a, "title"); link->content_type = get_attr_val(a, "type"); link->media = get_attr_val(a, "media"); link->name = get_attr_val(a, "rel"); if (link->name) { link->direction = LD_REL; } else { link->name = get_attr_val(a, "rev"); if (link->name) link->direction = LD_REV; } if (!link->name) return 1; /* TODO: fastfind */ for (i = 0; lt_names[i].str; i++) if (!strcasecmp(link->name, lt_names[i].str)) { link->type = lt_names[i].type; return 1; } if (strcasestr(link->name, "icon") || (link->content_type && strcasestr(link->content_type, "icon"))) { link->type = LT_ICON; } else if (strcasestr(link->name, "alternate")) { link->type = LT_ALTERNATE; if (link->lang) link->type = LT_ALTERNATE_LANG; else if (strcasestr(link->name, "stylesheet") || (link->content_type && strcasestr(link->content_type, "css"))) link->type = LT_ALTERNATE_STYLESHEET; else if (link->media) link->type = LT_ALTERNATE_MEDIA; } else if (link->content_type && strcasestr(link->content_type, "css")) { link->type = LT_STYLESHEET; } return 1;}voidhtml_link(unsigned char *a){ int link_display = global_doc_opts->meta_link_display; unsigned char *name; struct hlink link; static unsigned char link_rel_string[] = "Link: "; static unsigned char link_rev_string[] = "Reverse link: "; struct string text; int name_neq_title = 0; int first = 1;#ifndef CONFIG_CSS if (!link_display) return;#endif if (!html_link_parse(a, &link)) return; if (!link.href) goto free_and_return;#ifdef CONFIG_CSS if (link.type == LT_STYLESHEET) { int len = strlen(link.href); import_css_stylesheet(&html_context.css_styles, html_context.base_href, link.href, len); } if (!link_display) goto free_and_return;#endif /* Ignore few annoying links.. */ if (link_display < 5 && (link.type == LT_ICON || link.type == LT_AUTHOR || link.type == LT_STYLESHEET || link.type == LT_ALTERNATE_STYLESHEET)) goto free_and_return; if (!link.name || link.type != LT_UNKNOWN) /* Give preference to our default names for known types. */ name = get_lt_default_name(&link); else name = link.name; if (!name) goto free_and_return; if (!init_string(&text)) goto free_and_return; html_focusable(a); if (link.title) { add_to_string(&text, link.title); name_neq_title = strcmp(link.title, name); } else add_to_string(&text, name); if (link_display == 1) goto only_title; if (name_neq_title) { add_to_string(&text, first ? " (" : ", "); add_to_string(&text, name); first = 0; } if (link_display >= 3 && link.hreflang) { add_to_string(&text, first ? " (" : ", "); add_to_string(&text, link.hreflang); first = 0; } if (link_display >= 4 && link.content_type) { add_to_string(&text, first ? " (" : ", "); add_to_string(&text, link.content_type); first = 0; } if (link.lang && link.type == LT_ALTERNATE_LANG && (link_display < 3 || (link.hreflang && strcasecmp(link.hreflang, link.lang)))) { add_to_string(&text, first ? " (" : ", "); add_to_string(&text, link.lang); first = 0; } if (link.media) { add_to_string(&text, first ? " (" : ", "); add_to_string(&text, link.media); first = 0; } if (!first) add_char_to_string(&text, ')');only_title: if (text.length) put_link_line((link.direction == LD_REL) ? link_rel_string : link_rev_string, text.source, link.href, html_context.base_target); else put_link_line((link.direction == LD_REL) ? link_rel_string : link_rev_string, name, link.href, html_context.base_target); if (text.source) done_string(&text);free_and_return: html_link_clear(&link);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -