/* gentocidx.c */
/* Generate table of content and index for Netscape 4.0 bookmarks file. */

/* Author:   Heiko Purnhagen <purnhage@tnt.uni-hannover.de> */
/* Copying:  GNU copyleft */
/* WWW-site: http://www.fet.uni-hannover.de/purnhage/ */
/* Changes:  970330 970331 980118 */

#include <stdlib.h>
#include <stdio.h>
#include <stdarg.h>
#include <string.h>


#define PROGNAME "gentocidx"

#define STRLEN 256


FILE *in,*out;
int numlink,numfolder;
int level;
char line[STRLEN],folder[STRLEN];
char *s;
char *tocfile;

void errorexit (
  int errorCode,		/* in: error code for exit() */
  char *message,		/* in: error message */
  ...)				/* in: args as for printf */
{
  va_list args;

  va_start(args,message);
  fflush(stdout);
  fprintf(stderr,"%s: ERROR[%d]: ",PROGNAME,errorCode);
  vfprintf(stderr,message,args);
  fprintf(stderr,"\n");
  va_end(args);
  exit (errorCode);
}


void parse (int mode)
{
  int body = 0;

  numlink = numfolder = 0;
  level = 0;
  while (1) {
    fgets(line,STRLEN,in);
    if (feof(in))
      break;
    if (!body) {
      if (strstr(line,"<DL>")) {
	body = 1;
	if (mode==1)
	  fprintf(out,"\n<H3>Contents</H3>\n\n");
      }
      else {
	if (mode==1 || mode==3)
	  fprintf(out,"%s",line);
	continue;
      }
    }
    if (strstr(line,"<DL>")) {
      if (mode==1 || mode==3)
	fprintf(out,"%*s<UL>\n",level*2,"");
      level++;
    }
    if (strstr(line,"</DL>")) {
      level--;
      if (level<0)
	errorexit(-1,"folder level error 1\n");
      if (mode==1 || mode==3)
	fprintf(out,"%*s</UL>\n",level*2,"");
    }
    if (strstr(line,"HREF="))
      numlink++;
    if ((s=strstr(line,"<H3 "))) {
      numfolder++;
      s = strstr(s,">");
      if (!s)
	errorexit(-1,"folder error 1\n");
      strcpy(folder,s+1);
      s = strstr(folder,"<");
      if (!s)
	errorexit(-1,"folder error 2\n");
      *s = '\0';
      if (mode==0)
	fprintf(out,"%d %*s[%s]\n",numfolder,level*2,"",folder);
      if (mode==1)
	fprintf(out,"%*s<LI><A HREF=\"#%d\">%s</A>\n",
		level*2,"",numfolder,folder);
      if (mode==3)
	fprintf(out,"%*s<LI><A HREF=\"%s#%d\">%s</A>\n",
		level*2,"",tocfile,numfolder,folder);
      if (mode==2) {
	s = strstr(line,"<H3 ");
	*s = '\0';
	s++;
	*(s+strlen(s)-1) = '\0';
	fprintf(out,"%s<A NAME=\"%d\"><%s</A>\n",line,numfolder,s);
      }
    }
    else
      if (mode==2)
	fprintf(out,"%s",line);
  }
  if (level!=0)
    errorexit(-1,"folder level error 2\n");
  if (mode==1 || mode==3)
    fprintf(out,"<P>\n<HR>\n\n");
}


int main (int argc, char *argv[])
{
  if (argc < 2 || argc > 4) {
    fprintf(stderr,
	    "usage: %s <bookmarks.html> [-|<bookmarkstoc.html> [<bookmarksidx.html>]]\n",
	    PROGNAME);
    exit(-1);
  }
  if (!(in=fopen(argv[1],"r")))
    errorexit(-1,"error opening input file\n");
  if (argc==2) {
    out = stdout;
    parse(0);
  }
  else {
    if (!strcmp(argv[2],"-"))
      out = stdout;
    else
      if (!(out=fopen(argv[2],"w")))
	errorexit(-1,"error opening output file (toc)\n");
    fprintf(out,
	    "<!-- toc added by gentocidx.c (purnhage@tnt.uni-hannover.de) -->\n");
    parse(1);
    rewind(in);
    parse(2);
    if (argc==4) {
      tocfile = argv[2];
      if (!strcmp(argv[2],"-"))
	errorexit(-1,"error: toc file name missing\n");
      fclose(out);
      if (!(out=fopen(argv[3],"w")))
	errorexit(-1,"error opening output file (idx)\n");
      fprintf(out,
	      "<!-- idx generated by gentocidx.c (purnhage@tnt.uni-hannover.de) -->\n");
      rewind(in);
      parse(3);
    }
  }
  fclose(in);
  if (out!=stdout)
    fclose(out);
  fprintf(stderr,"%s has %d links in %d folders\n",
	  argv[1],numlink,numfolder);

  return 0;
}


