Blame src/LYList.c

Packit f574b8
/*
Packit f574b8
 * $LynxId: LYList.c,v 1.54 2018/06/10 20:27:01 tom Exp $
Packit f574b8
 *
Packit f574b8
 *			Lynx Document Reference List Support	      LYList.c
Packit f574b8
 *			====================================
Packit f574b8
 *
Packit f574b8
 *	Author: FM	Foteos Macrides (macrides@sci.wfbr.edu)
Packit f574b8
 *
Packit f574b8
 */
Packit f574b8
Packit f574b8
#include <HTUtils.h>
Packit f574b8
#include <HTAlert.h>
Packit f574b8
#include <LYUtils.h>
Packit f574b8
#include <GridText.h>
Packit f574b8
#include <HTParse.h>
Packit f574b8
#include <LYList.h>
Packit f574b8
#include <LYMap.h>
Packit f574b8
#include <LYClean.h>
Packit f574b8
#include <LYGlobalDefs.h>
Packit f574b8
#include <LYCharUtils.h>
Packit f574b8
#include <LYCharSets.h>
Packit f574b8
#include <LYStrings.h>
Packit f574b8
#include <LYHistory.h>
Packit f574b8
Packit f574b8
#ifdef DIRED_SUPPORT
Packit f574b8
#include <LYUpload.h>
Packit f574b8
#include <LYLocal.h>
Packit f574b8
#endif /* DIRED_SUPPORT */
Packit f574b8
Packit f574b8
#include <LYexit.h>
Packit f574b8
#include <LYLeaks.h>
Packit f574b8
Packit f574b8
/*	showlist - F.Macrides (macrides@sci.wfeb.edu)
Packit f574b8
 *	--------
Packit f574b8
 *	Create a temporary text/html file with a list of links to
Packit f574b8
 *	HyperText References in the current document.
Packit f574b8
 *
Packit f574b8
 *  On entry
Packit f574b8
 *	titles		Set:	if we want titles where available
Packit f574b8
 *			Clear:	we only get addresses.
Packit f574b8
 */
Packit f574b8
Packit f574b8
int showlist(DocInfo *newdoc, int titles)
Packit f574b8
{
Packit f574b8
    int cnt;
Packit f574b8
    int refs, hidden_links;
Packit f574b8
    int result;
Packit f574b8
    static char tempfile[LY_MAXPATH];
Packit f574b8
    static BOOLEAN last_titles = TRUE;
Packit f574b8
    FILE *fp0;
Packit f574b8
    char *Address = NULL, *Title = NULL, *cp = NULL;
Packit f574b8
    char *LinkTitle = NULL;	/* Rel stored as property of link, not of dest */
Packit f574b8
    BOOLEAN intern_w_post = FALSE;
Packit f574b8
    const char *desc = "unknown field or link";
Packit f574b8
    void *helper;
Packit f574b8
Packit f574b8
    refs = HText_sourceAnchors(HTMainText);
Packit f574b8
    hidden_links = HText_HiddenLinkCount(HTMainText);
Packit f574b8
    if (refs <= 0 && hidden_links > 0 &&
Packit f574b8
	LYHiddenLinks != HIDDENLINKS_SEPARATE) {
Packit f574b8
	HTUserMsg(NO_VISIBLE_REFS_FROM_DOC);
Packit f574b8
	return (-1);
Packit f574b8
    }
Packit f574b8
    if (refs <= 0 && hidden_links <= 0) {
Packit f574b8
	HTUserMsg(NO_REFS_FROM_DOC);
Packit f574b8
	return (-1);
Packit f574b8
    }
Packit f574b8
Packit f574b8
    if ((fp0 = InternalPageFP(tempfile, titles == last_titles)) == 0)
Packit f574b8
	return (-1);
Packit f574b8
Packit f574b8
    LYLocalFileToURL(&(newdoc->address), tempfile);
Packit f574b8
Packit f574b8
    LYRegisterUIPage(newdoc->address,
Packit f574b8
		     titles ? UIP_LIST_PAGE : UIP_ADDRLIST_PAGE);
Packit f574b8
    last_titles = (BOOLEAN) titles;
Packit f574b8
    LYforce_HTML_mode = TRUE;	/* force this file to be HTML */
Packit f574b8
    LYforce_no_cache = TRUE;	/* force this file to be new */
Packit f574b8
Packit f574b8
#ifdef USE_ADDRLIST_PAGE
Packit f574b8
    if (titles != TRUE)
Packit f574b8
	BeginInternalPage(fp0, ADDRLIST_PAGE_TITLE, LIST_PAGE_HELP);
Packit f574b8
    else
Packit f574b8
#endif
Packit f574b8
	BeginInternalPage(fp0, LIST_PAGE_TITLE, LIST_PAGE_HELP);
Packit f574b8
Packit f574b8
    StrAllocCopy(Address, HTLoadedDocumentURL());
Packit f574b8
    LYEntify(&Address, FALSE);
Packit f574b8
    fprintf(fp0, "%s%s

\n", gettext("References in "),

Packit f574b8
	    (non_empty(Address)
Packit f574b8
	     ? Address
Packit f574b8
	     : gettext("this document:")));
Packit f574b8
    FREE(Address);
Packit f574b8
    if (refs > 0) {
Packit f574b8
	fprintf(fp0, "<%s compact>\n", ((keypad_mode == NUMBERS_AS_ARROWS) ?
Packit f574b8
					"ol" : "ul"));
Packit f574b8
	if (hidden_links > 0)
Packit f574b8
	    fprintf(fp0, "<lh>%s\n", gettext("Visible links:"));
Packit f574b8
    }
Packit f574b8
    if (hidden_links > 0) {
Packit f574b8
	if (LYHiddenLinks == HIDDENLINKS_IGNORE)
Packit f574b8
	    hidden_links = 0;
Packit f574b8
    }
Packit f574b8
    helper = NULL;		/* init */
Packit f574b8
    result = 1;
Packit f574b8
    for (cnt = 1; cnt <= refs; cnt++) {
Packit f574b8
	HTChildAnchor *child = HText_childNextNumber(cnt, &helper);
Packit f574b8
	int value = HText_findAnchorNumber(helper);
Packit f574b8
	HTAnchor *dest_intl = NULL;
Packit f574b8
	HTAnchor *dest;
Packit f574b8
	HTParentAnchor *parent;
Packit f574b8
	char *address;
Packit f574b8
	const char *title;
Packit f574b8
Packit f574b8
	if (child == 0) {
Packit f574b8
	    /*
Packit f574b8
	     * child should not be 0 unless form field numbering is on and cnt
Packit f574b8
	     * is the number of a form input field.  HText_FormDescNumber()
Packit f574b8
	     * will set desc to a description of what type of input field this
Packit f574b8
	     * is.  We'll list it to ensure that the link numbers on the list
Packit f574b8
	     * page match the numbering in the original document, but won't
Packit f574b8
	     * create a forward link to the form.  - FM && LE
Packit f574b8
	     *
Packit f574b8
	     * Changed to create a fake hidden link, to get the numbering right
Packit f574b8
	     * in connection with always treating this file as
Packit f574b8
	     * HIDDENLINKS_MERGE in GridText.c - kw
Packit f574b8
	     */
Packit f574b8
	    if (fields_are_numbered()) {
Packit f574b8
		HText_FormDescNumber(cnt, &desc);
Packit f574b8
		fprintf(fp0,
Packit f574b8
			"
  • form field = %s\n",
  • Packit f574b8
    			cnt, cnt, desc);
    Packit f574b8
    	    }
    Packit f574b8
    	} else if (value >= result) {
    Packit f574b8
    	    if (track_internal_links)
    Packit f574b8
    		dest_intl = HTAnchor_followTypedLink(child, HTInternalLink);
    Packit f574b8
    	    dest = (dest_intl
    Packit f574b8
    		    ? dest_intl
    Packit f574b8
    		    : HTAnchor_followLink(child));
    Packit f574b8
    	    parent = HTAnchor_parent(dest);
    Packit f574b8
    	    if (!intern_w_post && dest_intl &&
    Packit f574b8
    		HTMainAnchor &&
    Packit f574b8
    		HTMainAnchor->post_data &&
    Packit f574b8
    		parent->post_data &&
    Packit f574b8
    		BINEQ(HTMainAnchor->post_data, parent->post_data)) {
    Packit f574b8
    		/*
    Packit f574b8
    		 * Set flag to note that we had at least one internal link, if
    Packit f574b8
    		 * the document from which we are generating the list has
    Packit f574b8
    		 * associated POST data; after an extra check that the link
    Packit f574b8
    		 * destination really has the same POST data so that we can
    Packit f574b8
    		 * believe it is an internal link.
    Packit f574b8
    		 */
    Packit f574b8
    		intern_w_post = TRUE;
    Packit f574b8
    	    }
    Packit f574b8
    	    address = HTAnchor_address(dest);
    Packit f574b8
    	    title = titles ? HTAnchor_title(parent) : NULL;
    Packit f574b8
    	    if (dest_intl) {
    Packit f574b8
    		HTSprintf0(&LinkTitle, "(internal)");
    Packit f574b8
    	    } else if (titles && child->type &&
    Packit f574b8
    		       dest == child->dest &&
    Packit f574b8
    		       !StrNCmp(HTAtom_name(child->type),
    Packit f574b8
    				"RelTitle: ", 10)) {
    Packit f574b8
    		HTSprintf0(&LinkTitle, "(%s)", HTAtom_name(child->type) + 10);
    Packit f574b8
    	    } else {
    Packit f574b8
    		FREE(LinkTitle);
    Packit f574b8
    	    }
    Packit f574b8
    	    StrAllocCopy(Address, address);
    Packit f574b8
    	    FREE(address);
    Packit f574b8
    	    LYEntify(&Address, TRUE);
    Packit f574b8
    	    if (non_empty(title)) {
    Packit f574b8
    		LYformTitle(&Title, title);
    Packit f574b8
    		LYEntify(&Title, TRUE);
    Packit f574b8
    		if (*Title) {
    Packit f574b8
    		    cp = findPoundSelector(Address);
    Packit f574b8
    		} else {
    Packit f574b8
    		    FREE(Title);
    Packit f574b8
    		}
    Packit f574b8
    	    }
    Packit f574b8
    Packit f574b8
    	    fprintf(fp0, "
  • %s%s%s%s%s\n", Address,
  • Packit f574b8
    		    dest_intl ? " TYPE=\"internal link\"" : "",
    Packit f574b8
    		    NonNull(LinkTitle),
    Packit f574b8
    		    ((HTAnchor *) parent != dest) && Title ? "in " : "",
    Packit f574b8
    		    (char *) (Title ? Title : Address),
    Packit f574b8
    		    (Title && cp) ? " - " : "",
    Packit f574b8
    		    (Title && cp) ? (cp + 1) : "");
    Packit f574b8
    Packit f574b8
    	    FREE(Address);
    Packit f574b8
    	    FREE(Title);
    Packit f574b8
    	}
    Packit f574b8
    	result = value + 1;
    Packit f574b8
        }
    Packit f574b8
        FREE(LinkTitle);
    Packit f574b8
    Packit f574b8
        if (hidden_links > 0) {
    Packit f574b8
    	if (refs > 0)
    Packit f574b8
    	    fprintf(fp0, "\n</%s>\n\n

    \n",

    Packit f574b8
    		    ((keypad_mode == NUMBERS_AS_ARROWS) ?
    Packit f574b8
    		     "ol" : "ul"));
    Packit f574b8
    	fprintf(fp0, "<%s compact>\n", ((keypad_mode == NUMBERS_AS_ARROWS) ?
    Packit f574b8
    					"ol continue" : "ul"));
    Packit f574b8
    	fprintf(fp0, "<lh>%s\n", gettext("Hidden links:"));
    Packit f574b8
        }
    Packit f574b8
    Packit f574b8
        for (cnt = 0; cnt < hidden_links; cnt++) {
    Packit f574b8
    	StrAllocCopy(Address, HText_HiddenLinkAt(HTMainText, cnt));
    Packit f574b8
    	LYEntify(&Address, FALSE);
    Packit f574b8
    	if (isEmpty(Address)) {
    Packit f574b8
    	    FREE(Address);
    Packit f574b8
    	    continue;
    Packit f574b8
    	}
    Packit f574b8
    	fprintf(fp0, "
  • %s\n", Address, Address);
  • Packit f574b8
    Packit f574b8
    	FREE(Address);
    Packit f574b8
        }
    Packit f574b8
    Packit f574b8
        fprintf(fp0, "\n</%s>\n", ((keypad_mode == NUMBERS_AS_ARROWS) ?
    Packit f574b8
    			       "ol" : "ul"));
    Packit f574b8
        EndInternalPage(fp0);
    Packit f574b8
        LYCloseTempFP(fp0);
    Packit f574b8
    Packit f574b8
        /*
    Packit f574b8
         * Make necessary changes to newdoc before returning to caller.  If the
    Packit f574b8
         * intern_w_post flag is set, we keep the POST data in newdoc that have
    Packit f574b8
         * been passed in.  They should be the same as in the loaded document for
    Packit f574b8
         * which we generated the list.  In that case the file we have written will
    Packit f574b8
         * be associated with the same POST data when it is loaded after we are
    Packit f574b8
         * done here, so that following one of the links we have marked as
    Packit f574b8
         * "internal link" can lead back to the underlying document with the right
    Packit f574b8
         * address+post_data combination.  - kw
    Packit f574b8
         */
    Packit f574b8
        if (intern_w_post) {
    Packit f574b8
    	newdoc->internal_link = TRUE;
    Packit f574b8
        } else {
    Packit f574b8
    	LYFreePostData(newdoc);
    Packit f574b8
    	newdoc->internal_link = FALSE;
    Packit f574b8
        }
    Packit f574b8
        newdoc->isHEAD = FALSE;
    Packit f574b8
        newdoc->safe = FALSE;
    Packit f574b8
        return (0);
    Packit f574b8
    }
    Packit f574b8
    Packit f574b8
    static int print_refs(FILE *fp, int titles, int refs)
    Packit f574b8
    {
    Packit f574b8
        int result = 0;
    Packit f574b8
        int cnt;
    Packit f574b8
        int value;
    Packit f574b8
        char *address = NULL;
    Packit f574b8
        const char *desc = gettext("unknown field or link");
    Packit f574b8
        void *helper = NULL;	/* init */
    Packit f574b8
    Packit f574b8
        for (cnt = 1; cnt <= refs; cnt++) {
    Packit f574b8
    	HTChildAnchor *child = HText_childNextNumber(cnt, &helper);
    Packit f574b8
    	HTAnchor *dest;
    Packit f574b8
    	HTParentAnchor *parent;
    Packit f574b8
    	const char *title;
    Packit f574b8
    	int counter = result + 1;
    Packit f574b8
    Packit f574b8
    	if (child == 0) {
    Packit f574b8
    	    /*
    Packit f574b8
    	     * child should not be 0 unless form field numbering is on and
    Packit f574b8
    	     * cnt is the number of a form input field. 
    Packit f574b8
    	     * HText_FormDescNumber() will set desc to a description of
    Packit f574b8
    	     * what type of input field this is.  We'll create a
    Packit f574b8
    	     * within-document link to ensure that the link numbers on the
    Packit f574b8
    	     * list page match the numbering in the original document, but
    Packit f574b8
    	     * won't create a forward link to the form.  - FM && LE
    Packit f574b8
    	     */
    Packit f574b8
    	    if (fields_are_numbered()) {
    Packit f574b8
    		HText_FormDescNumber(cnt, &desc);
    Packit f574b8
    		fprintf(fp, "%4d. form field = %s\n", counter, desc);
    Packit f574b8
    	    }
    Packit f574b8
    	} else {
    Packit f574b8
    	    dest = HTAnchor_followLink(child);
    Packit f574b8
    	    /*
    Packit f574b8
    	     * Ignore if child anchor points to itself, i.e., we had something
    Packit f574b8
    	     * like  and it is not treated as a hidden
    Packit f574b8
    	     * link.  Useful if someone 'P'rints the List Page (which isn't a
    Packit f574b8
    	     * very useful action to do, but anyway...) - kw
    Packit f574b8
    	     */
    Packit f574b8
    	    if (dest != (HTAnchor *) child) {
    Packit f574b8
    		parent = HTAnchor_parent(dest);
    Packit f574b8
    		title = titles ? HTAnchor_title(parent) : NULL;
    Packit f574b8
    		if (links_are_numbered()) {
    Packit f574b8
    		    value = HText_findAnchorNumber(helper);
    Packit f574b8
    		    if (value <= result)
    Packit f574b8
    			continue;
    Packit f574b8
    		    fprintf(fp, "%4d. ", value);
    Packit f574b8
    		}
    Packit f574b8
    		if (((HTAnchor *) parent != dest) && title) {
    Packit f574b8
    		    fprintf(fp, "in ");
    Packit f574b8
    		}
    Packit f574b8
    		if (title) {
    Packit f574b8
    		    fprintf(fp, "%s\n", title);
    Packit f574b8
    		} else {
    Packit f574b8
    		    address = HTAnchor_short_address(dest);
    Packit f574b8
    		    if (LYCharSet_UC[current_char_set].enc == UCT_ENC_UTF8) {
    Packit f574b8
    			(void) HTUnEscape(address);
    Packit f574b8
    		    }
    Packit f574b8
    		    fprintf(fp, "%s\n", address);
    Packit f574b8
    		    FREE(address);
    Packit f574b8
    		}
    Packit f574b8
    	    }
    Packit f574b8
    	}
    Packit f574b8
    	if (counter > result)
    Packit f574b8
    	    result = counter;
    Packit f574b8
    #ifdef VMS
    Packit f574b8
    	if (HadVMSInterrupt)
    Packit f574b8
    	    break;
    Packit f574b8
    #endif /* VMS */
    Packit f574b8
        }
    Packit f574b8
        return result;
    Packit f574b8
    }
    Packit f574b8
    Packit f574b8
    static void print_hidden_refs(FILE *fp, int refs, int hidden_links)
    Packit f574b8
    {
    Packit f574b8
        int cnt;
    Packit f574b8
        char *address = NULL;
    Packit f574b8
    Packit f574b8
        fprintf(fp, "%s   %s\n", ((refs > 0) ? "\n" : ""),
    Packit f574b8
    	    gettext("Hidden links:"));
    Packit f574b8
        for (cnt = 0; cnt < hidden_links; cnt++) {
    Packit f574b8
    	StrAllocCopy(address, HText_HiddenLinkAt(HTMainText, cnt));
    Packit f574b8
    	if (isEmpty(address)) {
    Packit f574b8
    	    FREE(address);
    Packit f574b8
    	    continue;
    Packit f574b8
    	}
    Packit f574b8
    Packit f574b8
    	if (links_are_numbered())
    Packit f574b8
    	    fprintf(fp, "%4d. ", ((cnt + 1) + refs));
    Packit f574b8
    	fprintf(fp, "%s\n", address);
    Packit f574b8
    	FREE(address);
    Packit f574b8
    #ifdef VMS
    Packit f574b8
    	if (HadVMSInterrupt)
    Packit f574b8
    	    break;
    Packit f574b8
    #endif /* VMS */
    Packit f574b8
        }
    Packit f574b8
    }
    Packit f574b8
    Packit f574b8
    /*	printlist - F.Macrides (macrides@sci.wfeb.edu)
    Packit f574b8
     *	---------
    Packit f574b8
     *	Print a text/plain list of HyperText References
    Packit f574b8
     *	in the current document.
    Packit f574b8
     *
    Packit f574b8
     *  On entry
    Packit f574b8
     *	titles		Set:	if we want titles where available
    Packit f574b8
     *			Clear:	we only get addresses.
    Packit f574b8
     */
    Packit f574b8
    void printlist(FILE *fp, int titles)
    Packit f574b8
    {
    Packit f574b8
        int refs, hidden_links;
    Packit f574b8
    Packit f574b8
        refs = HText_sourceAnchors(HTMainText);
    Packit f574b8
        if (refs > 0 || LYHiddenLinks == HIDDENLINKS_SEPARATE) {
    Packit f574b8
    	hidden_links = HText_HiddenLinkCount(HTMainText);
    Packit f574b8
    	if (refs > 0 || hidden_links > 0) {
    Packit f574b8
    	    if (links_are_numbered() || fields_are_numbered())
    Packit f574b8
    		fprintf(fp, "\n%s\n\n", gettext("References"));
    Packit f574b8
    	    if (LYHiddenLinks == HIDDENLINKS_IGNORE)
    Packit f574b8
    		hidden_links = 0;
    Packit f574b8
    	    if (hidden_links > 0) {
    Packit f574b8
    		fprintf(fp, "   %s\n", gettext("Visible links:"));
    Packit f574b8
    	    }
    Packit f574b8
    	    refs = print_refs(fp, titles, refs) + 1;
    Packit f574b8
    Packit f574b8
    	    if (hidden_links > 0) {
    Packit f574b8
    		print_hidden_refs(fp, refs, hidden_links);
    Packit f574b8
    	    }
    Packit f574b8
    	}
    Packit f574b8
        }
    Packit f574b8
        LYPrintImgMaps(fp);
    Packit f574b8
        return;
    Packit f574b8
    }