aboutsummaryrefslogtreecommitdiffstats
path: root/anchor.c
diff options
context:
space:
mode:
authorTatsuya Kinoshita <tats@vega.ocn.ne.jp>2011-05-04 07:05:14 +0000
committerTatsuya Kinoshita <tats@vega.ocn.ne.jp>2011-05-04 07:05:14 +0000
commit72f72d64a422d6628c4796f5c0bf2e508f134214 (patch)
tree0c9ea90cc53310832c977265521fb44db24a515e /anchor.c
parentAdding upstream version 0.3 (diff)
downloadw3m-72f72d64a422d6628c4796f5c0bf2e508f134214.tar.gz
w3m-72f72d64a422d6628c4796f5c0bf2e508f134214.zip
Adding upstream version 0.5.1upstream/0.5.1
Diffstat (limited to 'anchor.c')
-rw-r--r--anchor.c865
1 files changed, 865 insertions, 0 deletions
diff --git a/anchor.c b/anchor.c
new file mode 100644
index 0000000..5211048
--- /dev/null
+++ b/anchor.c
@@ -0,0 +1,865 @@
+/* $Id: anchor.c,v 1.30 2003/09/26 17:59:51 ukai Exp $ */
+#include "fm.h"
+#include "myctype.h"
+#include "regex.h"
+
+#define FIRST_ANCHOR_SIZE 30
+
+AnchorList *
+putAnchor(AnchorList *al, char *url, char *target, Anchor **anchor_return,
+ char *referer, char *title, unsigned char key, int line, int pos)
+{
+ int n, i, j;
+ Anchor *a;
+ BufferPoint bp;
+ if (al == NULL) {
+ al = New(AnchorList);
+ al->anchors = NULL;
+ al->nanchor = al->anchormax = 0;
+ al->acache = -1;
+ }
+ if (al->anchormax == 0) {
+ /* first time; allocate anchor buffer */
+ al->anchors = New_N(Anchor, FIRST_ANCHOR_SIZE);
+ al->anchormax = FIRST_ANCHOR_SIZE;
+ }
+ if (al->nanchor == al->anchormax) { /* need realloc */
+ al->anchormax *= 2;
+ al->anchors = New_Reuse(Anchor, al->anchors, al->anchormax);
+ }
+ bp.line = line;
+ bp.pos = pos;
+ n = al->nanchor;
+ if (!n || bpcmp(al->anchors[n - 1].start, bp) < 0)
+ i = n;
+ else
+ for (i = 0; i < n; i++) {
+ if (bpcmp(al->anchors[i].start, bp) >= 0) {
+ for (j = n; j > i; j--)
+ al->anchors[j] = al->anchors[j - 1];
+ break;
+ }
+ }
+ a = &al->anchors[i];
+ a->url = url;
+ a->target = target;
+ a->referer = referer;
+ a->title = title;
+ a->accesskey = key;
+ a->slave = FALSE;
+ a->start = bp;
+ a->end = bp;
+ al->nanchor++;
+ if (anchor_return)
+ *anchor_return = a;
+ return al;
+}
+
+
+Anchor *
+registerHref(Buffer *buf, char *url, char *target, char *referer, char *title,
+ unsigned char key, int line, int pos)
+{
+ Anchor *a;
+ buf->href = putAnchor(buf->href, url, target, &a, referer, title, key,
+ line, pos);
+ return a;
+}
+
+Anchor *
+registerName(Buffer *buf, char *url, int line, int pos)
+{
+ Anchor *a;
+ buf->name = putAnchor(buf->name, url, NULL, &a, NULL, NULL, '\0', line,
+ pos);
+ return a;
+}
+
+Anchor *
+registerImg(Buffer *buf, char *url, char *title, int line, int pos)
+{
+ Anchor *a;
+ buf->img = putAnchor(buf->img, url, NULL, &a, NULL, title, '\0', line,
+ pos);
+ return a;
+}
+
+Anchor *
+registerForm(Buffer *buf, FormList *flist, struct parsed_tag *tag, int line,
+ int pos)
+{
+ Anchor *a;
+ FormItemList *fi;
+
+ fi = formList_addInput(flist, tag);
+ if (fi == NULL)
+ return NULL;
+ buf->formitem = putAnchor(buf->formitem, (char *)fi, flist->target, &a,
+ NULL, NULL, '\0', line, pos);
+ return a;
+}
+
+int
+onAnchor(Anchor *a, int line, int pos)
+{
+ BufferPoint bp;
+ bp.line = line;
+ bp.pos = pos;
+
+ if (bpcmp(bp, a->start) < 0)
+ return -1;
+ if (bpcmp(a->end, bp) <= 0)
+ return 1;
+ return 0;
+}
+
+Anchor *
+retrieveAnchor(AnchorList *al, int line, int pos)
+{
+ Anchor *a;
+ size_t b, e;
+ int cmp;
+
+ if (al == NULL || al->nanchor == 0)
+ return NULL;
+
+ if (al->acache < 0 || al->acache >= al->nanchor)
+ al->acache = 0;
+
+ for (b = 0, e = al->nanchor - 1; b <= e; al->acache = (b + e) / 2) {
+ a = &al->anchors[al->acache];
+ cmp = onAnchor(a, line, pos);
+ if (cmp == 0)
+ return a;
+ else if (cmp > 0)
+ b = al->acache + 1;
+ else if (al->acache == 0)
+ return NULL;
+ else
+ e = al->acache - 1;
+ }
+ return NULL;
+}
+
+Anchor *
+retrieveCurrentAnchor(Buffer *buf)
+{
+ if (buf->currentLine == NULL)
+ return NULL;
+ return retrieveAnchor(buf->href, buf->currentLine->linenumber, buf->pos);
+}
+
+Anchor *
+retrieveCurrentImg(Buffer *buf)
+{
+ if (buf->currentLine == NULL)
+ return NULL;
+ return retrieveAnchor(buf->img, buf->currentLine->linenumber, buf->pos);
+}
+
+Anchor *
+retrieveCurrentForm(Buffer *buf)
+{
+ if (buf->currentLine == NULL)
+ return NULL;
+ return retrieveAnchor(buf->formitem,
+ buf->currentLine->linenumber, buf->pos);
+}
+
+Anchor *
+searchAnchor(AnchorList *al, char *str)
+{
+ int i;
+ Anchor *a;
+ if (al == NULL)
+ return NULL;
+ for (i = 0; i < al->nanchor; i++) {
+ a = &al->anchors[i];
+ if (!strcmp(a->url, str))
+ return a;
+ }
+ return NULL;
+}
+
+Anchor *
+searchURLLabel(Buffer *buf, char *url)
+{
+ return searchAnchor(buf->name, url);
+}
+
+#ifdef USE_NNTP
+static Anchor *
+_put_anchor_news(Buffer *buf, char *p1, char *p2, int line, int pos)
+{
+ Str tmp;
+
+ if (*p1 == '<') {
+ p1++;
+ if (*(p2 - 1) == '>')
+ p2--;
+ }
+ tmp = wc_Str_conv_strict(Strnew_charp_n(p1, p2 - p1), InnerCharset,
+ buf->document_charset);
+ tmp = Sprintf("news:%s", file_quote(tmp->ptr));
+ return registerHref(buf, tmp->ptr, NULL, NO_REFERER, NULL, '\0', line,
+ pos);
+}
+#endif /* USE_NNTP */
+
+static Anchor *
+_put_anchor_all(Buffer *buf, char *p1, char *p2, int line, int pos)
+{
+ Str tmp;
+
+ tmp = wc_Str_conv_strict(Strnew_charp_n(p1, p2 - p1), InnerCharset,
+ buf->document_charset);
+ return registerHref(buf, url_quote(tmp->ptr), NULL, NO_REFERER, NULL,
+ '\0', line, pos);
+}
+
+static void
+reseq_anchor0(AnchorList *al, short *seqmap)
+{
+ int i;
+ Anchor *a;
+
+ if (!al)
+ return;
+
+ for (i = 0; i < al->nanchor; i++) {
+ a = &al->anchors[i];
+ if (a->hseq >= 0) {
+ a->hseq = seqmap[a->hseq];
+ }
+ }
+}
+
+/* renumber anchor */
+static void
+reseq_anchor(Buffer *buf)
+{
+ int i, j, n, nmark = (buf->hmarklist) ? buf->hmarklist->nmark : 0;
+ short *seqmap;
+ Anchor *a, *a1;
+ HmarkerList *ml = NULL;
+
+ if (!buf->href)
+ return;
+
+ n = nmark;
+ for (i = 0; i < buf->href->nanchor; i++) {
+ a = &buf->href->anchors[i];
+ if (a->hseq == -2)
+ n++;
+ }
+
+ if (n == nmark)
+ return;
+
+ seqmap = NewAtom_N(short, n);
+
+ for (i = 0; i < n; i++)
+ seqmap[i] = i;
+
+ n = nmark;
+ for (i = 0; i < buf->href->nanchor; i++) {
+ a = &buf->href->anchors[i];
+ if (a->hseq == -2) {
+ a->hseq = n;
+ a1 = closest_next_anchor(buf->href, NULL, a->start.pos,
+ a->start.line);
+ a1 = closest_next_anchor(buf->formitem, a1, a->start.pos,
+ a->start.line);
+ if (a1 && a1->hseq >= 0) {
+ seqmap[n] = seqmap[a1->hseq];
+ for (j = a1->hseq; j < nmark; j++)
+ seqmap[j]++;
+ }
+ ml = putHmarker(ml, a->start.line, a->start.pos, seqmap[n]);
+ n++;
+ }
+ }
+
+ for (i = 0; i < nmark; i++) {
+ ml = putHmarker(ml, buf->hmarklist->marks[i].line,
+ buf->hmarklist->marks[i].pos, seqmap[i]);
+ }
+ buf->hmarklist = ml;
+
+ reseq_anchor0(buf->href, seqmap);
+ reseq_anchor0(buf->formitem, seqmap);
+}
+
+static char *
+reAnchorPos(Buffer *buf, Line *l, char *p1, char *p2,
+ Anchor *(*anchorproc) (Buffer *, char *, char *, int, int))
+{
+ Anchor *a;
+ int spos, epos;
+ int i, hseq = -2;
+
+ spos = p1 - l->lineBuf;
+ epos = p2 - l->lineBuf;
+ for (i = spos; i < epos; i++) {
+ if (l->propBuf[i] & (PE_ANCHOR | PE_FORM))
+ return p2;
+ }
+ for (i = spos; i < epos; i++)
+ l->propBuf[i] |= PE_ANCHOR;
+ while (spos > l->len && l->next && l->next->bpos) {
+ spos -= l->len;
+ epos -= l->len;
+ l = l->next;
+ }
+ while (1) {
+ a = anchorproc(buf, p1, p2, l->linenumber, spos);
+ a->hseq = hseq;
+ if (hseq == -2) {
+ reseq_anchor(buf);
+ hseq = a->hseq;
+ }
+ a->end.line = l->linenumber;
+ if (epos > l->len && l->next && l->next->bpos) {
+ a->end.pos = l->len;
+ spos = 0;
+ epos -= l->len;
+ l = l->next;
+ }
+ else {
+ a->end.pos = epos;
+ break;
+ }
+ }
+ return p2;
+}
+
+void
+reAnchorWord(Buffer *buf, Line *l, int spos, int epos)
+{
+ reAnchorPos(buf, l, &l->lineBuf[spos], &l->lineBuf[epos], _put_anchor_all);
+}
+
+/* search regexp and register them as anchors */
+/* returns error message if any */
+static char *
+reAnchorAny(Buffer *buf, char *re,
+ Anchor *(*anchorproc) (Buffer *, char *, char *, int, int))
+{
+ Line *l;
+ char *p = NULL, *p1, *p2;
+
+ if (re == NULL || *re == '\0') {
+ return NULL;
+ }
+ if ((re = regexCompile(re, 1)) != NULL) {
+ return re;
+ }
+ for (l = MarkAllPages ? buf->firstLine : buf->topLine; l != NULL &&
+ (MarkAllPages || l->linenumber < buf->topLine->linenumber + LASTLINE);
+ l = l->next) {
+ if (p && l->bpos)
+ goto next_line;
+ p = l->lineBuf;
+ for (;;) {
+ if (regexMatch(p, &l->lineBuf[l->size] - p, p == l->lineBuf) == 1) {
+ matchedPosition(&p1, &p2);
+ p = reAnchorPos(buf, l, p1, p2, anchorproc);
+ }
+ else
+ break;
+ }
+ next_line:
+ if (MarkAllPages && l->next == NULL && buf->pagerSource &&
+ !(buf->bufferprop & BP_CLOSE))
+ getNextPage(buf, PagerMax);
+ }
+ return NULL;
+}
+
+char *
+reAnchor(Buffer *buf, char *re)
+{
+ return reAnchorAny(buf, re, _put_anchor_all);
+}
+
+#ifdef USE_NNTP
+char *
+reAnchorNews(Buffer *buf, char *re)
+{
+ return reAnchorAny(buf, re, _put_anchor_news);
+}
+
+char *
+reAnchorNewsheader(Buffer *buf)
+{
+ Line *l;
+ char *p, *p1, *p2;
+ static char *header_mid[] = {
+ "Message-Id:", "References:", "In-Reply-To:", NULL
+ };
+ static char *header_group[] = {
+ "Newsgroups:", NULL
+ };
+ char **header, **q;
+ int i, search = FALSE;
+
+ if (!buf || !buf->firstLine)
+ return NULL;
+ for (i = 0; i <= 1; i++) {
+ if (i == 0) {
+ regexCompile("<[!-;=?-~]+@[a-zA-Z0-9\\.\\-_]+>", 1);
+ header = header_mid;
+ }
+ else {
+ regexCompile("[a-zA-Z0-9\\.\\-_]+", 1);
+ header = header_group;
+ }
+ for (l = buf->firstLine; l != NULL && l->real_linenumber == 0;
+ l = l->next) {
+ if (l->bpos)
+ continue;
+ p = l->lineBuf;
+ if (!IS_SPACE(*p)) {
+ search = FALSE;
+ for (q = header; *q; q++) {
+ if (!strncasecmp(p, *q, strlen(*q))) {
+ search = TRUE;
+ p = strchr(p, ':') + 1;
+ break;
+ }
+ }
+ }
+ if (!search)
+ continue;
+ for (;;) {
+ if (regexMatch(p, &l->lineBuf[l->size] - p, p == l->lineBuf)
+ == 1) {
+ matchedPosition(&p1, &p2);
+ p = reAnchorPos(buf, l, p1, p2, _put_anchor_news);
+ }
+ else
+ break;
+ }
+ }
+ }
+ reseq_anchor(buf);
+ return NULL;
+}
+#endif /* USE_NNTP */
+
+#define FIRST_MARKER_SIZE 30
+HmarkerList *
+putHmarker(HmarkerList *ml, int line, int pos, int seq)
+{
+ if (ml == NULL) {
+ ml = New(HmarkerList);
+ ml->marks = NULL;
+ ml->nmark = 0;
+ ml->markmax = 0;
+ ml->prevhseq = -1;
+ }
+ if (ml->markmax == 0) {
+ ml->markmax = FIRST_MARKER_SIZE;
+ ml->marks = NewAtom_N(BufferPoint, ml->markmax);
+ bzero(ml->marks, sizeof(BufferPoint) * ml->markmax);
+ }
+ if (seq + 1 > ml->nmark)
+ ml->nmark = seq + 1;
+ if (ml->nmark >= ml->markmax) {
+ ml->markmax = ml->nmark * 2;
+ ml->marks = New_Reuse(BufferPoint, ml->marks, ml->markmax);
+ }
+ ml->marks[seq].line = line;
+ ml->marks[seq].pos = pos;
+ return ml;
+}
+
+Anchor *
+closest_next_anchor(AnchorList *a, Anchor *an, int x, int y)
+{
+ int i;
+
+ if (a == NULL || a->nanchor == 0)
+ return an;
+ for (i = 0; i < a->nanchor; i++) {
+ if (a->anchors[i].hseq < 0)
+ continue;
+ if (a->anchors[i].start.line > y ||
+ (a->anchors[i].start.line == y && a->anchors[i].start.pos > x)) {
+ if (an == NULL || an->start.line > a->anchors[i].start.line ||
+ (an->start.line == a->anchors[i].start.line &&
+ an->start.pos > a->anchors[i].start.pos))
+ an = &a->anchors[i];
+ }
+ }
+ return an;
+}
+
+Anchor *
+closest_prev_anchor(AnchorList *a, Anchor *an, int x, int y)
+{
+ int i;
+
+ if (a == NULL || a->nanchor == 0)
+ return an;
+ for (i = 0; i < a->nanchor; i++) {
+ if (a->anchors[i].hseq < 0)
+ continue;
+ if (a->anchors[i].end.line < y ||
+ (a->anchors[i].end.line == y && a->anchors[i].end.pos <= x)) {
+ if (an == NULL || an->end.line < a->anchors[i].end.line ||
+ (an->end.line == a->anchors[i].end.line &&
+ an->end.pos < a->anchors[i].end.pos))
+ an = &a->anchors[i];
+ }
+ }
+ return an;
+}
+
+void
+shiftAnchorPosition(AnchorList *al, HmarkerList *hl, int line, int pos,
+ int shift)
+{
+ Anchor *a;
+ size_t b, e, s = 0;
+ int cmp;
+
+ if (al == NULL || al->nanchor == 0)
+ return;
+
+ s = al->nanchor / 2;
+ for (b = 0, e = al->nanchor - 1; b <= e; s = (b + e + 1) / 2) {
+ a = &al->anchors[s];
+ cmp = onAnchor(a, line, pos);
+ if (cmp == 0)
+ break;
+ else if (cmp > 0)
+ b = s + 1;
+ else if (s == 0)
+ break;
+ else
+ e = s - 1;
+ }
+ for (; s < al->nanchor; s++) {
+ a = &al->anchors[s];
+ if (a->start.line > line)
+ break;
+ if (a->start.pos > pos) {
+ a->start.pos += shift;
+ if (hl->marks[a->hseq].line == line)
+ hl->marks[a->hseq].pos = a->start.pos;
+ }
+ if (a->end.pos >= pos)
+ a->end.pos += shift;
+ }
+}
+
+#ifdef USE_IMAGE
+void
+addMultirowsImg(Buffer *buf, AnchorList *al)
+{
+ int i, j, k, col, ecol, pos;
+ Image *img;
+ Anchor a_img, a_href, a_form, *a;
+ Line *l, *ls;
+
+ if (al == NULL || al->nanchor == 0)
+ return;
+ for (i = 0; i < al->nanchor; i++) {
+ a_img = al->anchors[i];
+ img = a_img.image;
+ if (a_img.hseq < 0 || !img || img->rows <= 1)
+ continue;
+ for (l = buf->firstLine; l != NULL; l = l->next) {
+ if (l->linenumber == img->y)
+ break;
+ }
+ if (!l)
+ continue;
+ if (a_img.y == a_img.start.line)
+ ls = l;
+ else {
+ for (ls = l; ls != NULL;
+ ls = (a_img.y < a_img.start.line) ? ls->next : ls->prev) {
+ if (ls->linenumber == a_img.start.line)
+ break;
+ }
+ if (!ls)
+ continue;
+ }
+ a = retrieveAnchor(buf->href, a_img.start.line, a_img.start.pos);
+ if (a)
+ a_href = *a;
+ else
+ a_href.url = NULL;
+ a = retrieveAnchor(buf->formitem, a_img.start.line, a_img.start.pos);
+ if (a)
+ a_form = *a;
+ else
+ a_form.url = NULL;
+ col = COLPOS(ls, a_img.start.pos);
+ ecol = COLPOS(ls, a_img.end.pos);
+ for (j = 0; l && j < img->rows; l = l->next, j++) {
+ if (a_img.start.line == l->linenumber)
+ continue;
+ pos = columnPos(l, col);
+ a = registerImg(buf, a_img.url, a_img.title, l->linenumber, pos);
+ a->hseq = -a_img.hseq;
+ a->slave = TRUE;
+ a->image = img;
+ a->end.pos = pos + ecol - col;
+ for (k = pos; k < a->end.pos; k++)
+ l->propBuf[k] |= PE_IMAGE;
+ if (a_href.url) {
+ a = registerHref(buf, a_href.url, a_href.target,
+ a_href.referer, a_href.title,
+ a_href.accesskey, l->linenumber, pos);
+ a->hseq = a_href.hseq;
+ a->slave = TRUE;
+ a->end.pos = pos + ecol - col;
+ for (k = pos; k < a->end.pos; k++)
+ l->propBuf[k] |= PE_ANCHOR;
+ }
+ if (a_form.url) {
+ buf->formitem = putAnchor(buf->formitem, a_form.url,
+ a_form.target, &a, NULL, NULL, '\0',
+ l->linenumber, pos);
+ a->hseq = a_form.hseq;
+ a->end.pos = pos + ecol - col;
+ }
+ }
+ img->rows = 0;
+ }
+}
+#endif
+
+void
+addMultirowsForm(Buffer *buf, AnchorList *al)
+{
+ int i, j, k, col, ecol, pos;
+ Anchor a_form, *a;
+ FormItemList *fi;
+ Line *l, *ls;
+
+ if (al == NULL || al->nanchor == 0)
+ return;
+ for (i = 0; i < al->nanchor; i++) {
+ a_form = al->anchors[i];
+ al->anchors[i].rows = 1;
+ if (a_form.hseq < 0 || a_form.rows <= 1)
+ continue;
+ for (l = buf->firstLine; l != NULL; l = l->next) {
+ if (l->linenumber == a_form.y)
+ break;
+ }
+ if (!l)
+ continue;
+ if (a_form.y == a_form.start.line)
+ ls = l;
+ else {
+ for (ls = l; ls != NULL;
+ ls = (a_form.y < a_form.start.line) ? ls->next : ls->prev) {
+ if (ls->linenumber == a_form.start.line)
+ break;
+ }
+ if (!ls)
+ continue;
+ }
+ fi = (FormItemList *)a_form.url;
+ col = COLPOS(ls, a_form.start.pos);
+ ecol = COLPOS(ls, a_form.end.pos);
+ for (j = 0; l && j < a_form.rows; l = l->next, j++) {
+ pos = columnPos(l, col);
+ if (j == 0) {
+ buf->hmarklist->marks[a_form.hseq].line = l->linenumber;
+ buf->hmarklist->marks[a_form.hseq].pos = pos;
+ }
+ if (a_form.start.line == l->linenumber)
+ continue;
+ buf->formitem = putAnchor(buf->formitem, a_form.url,
+ a_form.target, &a, NULL, NULL, '\0',
+ l->linenumber, pos);
+ a->hseq = a_form.hseq;
+ a->y = a_form.y;
+ a->end.pos = pos + ecol - col;
+ l->lineBuf[pos - 1] = '[';
+ l->lineBuf[a->end.pos] = ']';
+ for (k = pos; k < a->end.pos; k++)
+ l->propBuf[k] |= PE_FORM;
+ }
+ }
+}
+
+char *
+getAnchorText(Buffer *buf, AnchorList *al, Anchor *a)
+{
+ int hseq, i;
+ Line *l;
+ Str tmp = NULL;
+ char *p, *ep;
+
+ if (!a || a->hseq < 0)
+ return NULL;
+ hseq = a->hseq;
+ l = buf->firstLine;
+ for (i = 0; i < al->nanchor; i++) {
+ a = &al->anchors[i];
+ if (a->hseq != hseq)
+ continue;
+ for (; l; l = l->next) {
+ if (l->linenumber == a->start.line)
+ break;
+ }
+ if (!l)
+ break;
+ p = l->lineBuf + a->start.pos;
+ ep = l->lineBuf + a->end.pos;
+ for (; p < ep && IS_SPACE(*p); p++) ;
+ if (p == ep)
+ continue;
+ if (!tmp)
+ tmp = Strnew_size(ep - p);
+ else
+ Strcat_char(tmp, ' ');
+ Strcat_charp_n(tmp, p, ep - p);
+ }
+ return tmp ? tmp->ptr : NULL;
+}
+
+Buffer *
+link_list_panel(Buffer *buf)
+{
+ LinkList *l;
+ AnchorList *al;
+ Anchor *a;
+ FormItemList *fi;
+ int i;
+ char *t, *u, *p;
+ ParsedURL pu;
+ /* FIXME: gettextize? */
+ Str tmp = Strnew_charp("<title>Link List</title>\
+<h1 align=center>Link List</h1>\n");
+
+ if (buf->bufferprop & BP_INTERNAL ||
+ (buf->linklist == NULL && buf->href == NULL && buf->img == NULL)) {
+ return NULL;
+ }
+
+ if (buf->linklist) {
+ Strcat_charp(tmp, "<hr><h2>Links</h2>\n<ol>\n");
+ for (l = buf->linklist; l; l = l->next) {
+ if (l->url) {
+ parseURL2(l->url, &pu, baseURL(buf));
+ p = parsedURL2Str(&pu)->ptr;
+ u = html_quote(p);
+ if (DecodeURL)
+ p = html_quote(url_unquote_conv(p, buf->document_charset));
+ else
+ p = u;
+ }
+ else
+ u = p = "";
+ if (l->type == LINK_TYPE_REL)
+ t = " [Rel]";
+ else if (l->type == LINK_TYPE_REV)
+ t = " [Rev]";
+ else
+ t = "";
+ t = Sprintf("%s%s\n", l->title ? l->title : "", t)->ptr;
+ t = html_quote(t);
+ Strcat_m_charp(tmp, "<li><a href=\"", u, "\">", t, "</a><br>", p,
+ "\n", NULL);
+ }
+ Strcat_charp(tmp, "</ol>\n");
+ }
+
+ if (buf->href) {
+ Strcat_charp(tmp, "<hr><h2>Anchors</h2>\n<ol>\n");
+ al = buf->href;
+ for (i = 0; i < al->nanchor; i++) {
+ a = &al->anchors[i];
+ if (a->slave)
+ continue;
+ parseURL2(a->url, &pu, baseURL(buf));
+ p = parsedURL2Str(&pu)->ptr;
+ u = html_quote(p);
+ if (DecodeURL)
+ p = html_quote(url_unquote_conv(p, buf->document_charset));
+ else
+ p = u;
+ t = getAnchorText(buf, al, a);
+ t = t ? html_quote(t) : "";
+ Strcat_m_charp(tmp, "<li><a href=\"", u, "\">", t, "</a><br>", p,
+ "\n", NULL);
+ }
+ Strcat_charp(tmp, "</ol>\n");
+ }
+
+ if (buf->img) {
+ Strcat_charp(tmp, "<hr><h2>Images</h2>\n<ol>\n");
+ al = buf->img;
+ for (i = 0; i < al->nanchor; i++) {
+ a = &al->anchors[i];
+ if (a->slave)
+ continue;
+ parseURL2(a->url, &pu, baseURL(buf));
+ p = parsedURL2Str(&pu)->ptr;
+ u = html_quote(p);
+ if (DecodeURL)
+ p = html_quote(url_unquote_conv(p, buf->document_charset));
+ else
+ p = u;
+ if (a->title && *a->title)
+ t = html_quote(a->title);
+ else if (DecodeURL)
+ t = html_quote(url_unquote_conv
+ (a->url, buf->document_charset));
+ else
+ t = html_quote(a->url);
+ Strcat_m_charp(tmp, "<li><a href=\"", u, "\">", t, "</a><br>", p,
+ "\n", NULL);
+ a = retrieveAnchor(buf->formitem, a->start.line, a->start.pos);
+ if (!a)
+ continue;
+ fi = (FormItemList *)a->url;
+ fi = fi->parent->item;
+ if (fi->parent->method == FORM_METHOD_INTERNAL &&
+ !Strcmp_charp(fi->parent->action, "map") && fi->value) {
+ MapList *ml = searchMapList(buf, fi->value->ptr);
+ ListItem *mi;
+ MapArea *m;
+ if (!ml)
+ continue;
+ Strcat_charp(tmp, "<br>\n<b>Image map</b>\n<ol>\n");
+ for (mi = ml->area->first; mi != NULL; mi = mi->next) {
+ m = (MapArea *) mi->ptr;
+ if (!m)
+ continue;
+ parseURL2(m->url, &pu, baseURL(buf));
+ p = parsedURL2Str(&pu)->ptr;
+ u = html_quote(p);
+ if (DecodeURL)
+ p = html_quote(url_unquote_conv(p,
+ buf->
+ document_charset));
+ else
+ p = u;
+ if (m->alt && *m->alt)
+ t = html_quote(m->alt);
+ else if (DecodeURL)
+ t = html_quote(url_unquote_conv(m->url,
+ buf->
+ document_charset));
+ else
+ t = html_quote(m->url);
+ Strcat_m_charp(tmp, "<li><a href=\"", u, "\">", t,
+ "</a><br>", p, "\n", NULL);
+ }
+ Strcat_charp(tmp, "</ol>\n");
+ }
+ }
+ Strcat_charp(tmp, "</ol>\n");
+ }
+
+ return loadHTMLString(tmp);
+}