tree/html.c

226 lines
5.2 KiB
C

/* $Copyright: $
* Copyright (c) 1996 - 2022 by Steve Baker (ice@mama.indstate.edu)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "tree.h"
extern char *version, *hversion;
extern bool dflag, lflag, pflag, sflag, Fflag, aflag, fflag, uflag, gflag;
extern bool Dflag, inodeflag, devflag, Rflag, duflag, hflag, siflag;
extern bool noindent, force_color, xdev, nolinks, metafirst, noreport;
extern char *host, *sp, *title;
extern const char *charset;
extern FILE *outfile;
extern int Level, *dirs, maxdirs;
extern bool colorize, linktargetcolor;
extern char *endcode;
extern const struct linedraw *linedraw;
int htmldirlen = 0;
char *class(struct _info *info)
{
return
info->isdir ? "DIR" :
info->isexe ? "EXEC" :
info->isfifo ? "FIFO" :
info->issok ? "SOCK" : "NORM";
}
void html_encode(FILE *fd, char *s)
{
for(;*s;s++) {
switch(*s) {
case '<':
fputs("&lt;",fd);
break;
case '>':
fputs("&gt;",fd);
break;
case '&':
fputs("&amp;",fd);
break;
case '"':
fputs("&quot;",fd);
break;
default:
fputc(*s,fd);
// fputc(isprint(*s)?*s:'?',fd);
break;
}
}
}
void url_encode(FILE *fd, char *s)
{
for(;*s;s++) {
switch(*s) {
case ' ':
case '"':
case '#':
case '%':
case '<':
case '>':
case '[':
case ']':
case '^':
case '\\':
case '?':
case '+':
fprintf(fd,"%%%02X",*s);
break;
case '&':
fprintf(fd,"&amp;");
break;
default:
fprintf(fd,isprint((u_int)*s)?"%c":"%%%02X",(u_char)*s);
break;
}
}
}
void html_intro(void)
{
fprintf(outfile,
"<!DOCTYPE html>\n"
"<html>\n"
"<head>\n"
" <meta charset=\"UTF-8\">\n"
" <meta name=\"color-scheme\" content=\"dark light\" />\n"
" <link href=\"favicon.svg\" rel=\"icon\" type=\"image/svg+xml\"/>\n"
" <title>%s</title>\n"
" <style type=\"text/css\">\n"
" body {font-family: monospace;}\n"
" p { margin:0px; padding: 0px;}\n"
" a { text-decoration: none; color: unset; }\n"
" a:hover { color: #888; }\n"
" </style>\n"
"</head>\n"
"<body>\n"
"\t<p>\n", title);
}
void html_outtro(void)
{
fprintf(outfile,"</body>\n");
fprintf(outfile,"</html>\n");
}
void html_print(char *s)
{
for(int i=0; s[i]; i++) {
if (s[i] == ' ') fprintf(outfile,"%s",sp);
else fprintf(outfile,"%c", s[i]);
}
fprintf(outfile,"%s%s", sp, sp);
}
int html_printinfo(char *dirname, struct _info *file, int level)
{
char info[512];
fillinfo(info,file);
if (metafirst) {
if (info[0] == '[') {
html_print(info);
fprintf(outfile,"%s%s", sp, sp);
}
if (!noindent) indent(level);
} else {
if (!noindent) indent(level);
if (info[0] == '[') {
html_print(info);
fprintf(outfile,"%s%s", sp, sp);
}
}
return 0;
}
// descend == add 00Tree.html to the link
int html_printfile(char *dirname, char *filename, struct _info *file, int descend)
{
// Switch to using 'a' elements only. Omit href attribute if not a link
fprintf(outfile,"<a");
if (file) {
if (file->comment) {
fprintf(outfile," title=\"");
for(int i=0; file->comment[i]; i++) {
html_encode(outfile, file->comment[i]);
if (file->comment[i+1]) fprintf(outfile, "\n");
}
fprintf(outfile, "\"");
}
if (!nolinks) {
fprintf(outfile," href=\"%s",host);
if (dirname != NULL) {
int len = strlen(dirname);
int off = (len >= htmldirlen? htmldirlen : 0);
url_encode(outfile, dirname + off);
putc('/',outfile);
url_encode(outfile, filename);
fprintf(outfile,"%s%s\"",(descend > 1? "/00Tree.html" : ""), (file->isdir?"/":""));
} else {
fprintf(outfile,"%s\"",(descend > 1? "/00Tree.html" : ""));
}
}
}
fprintf(outfile, ">");
if (dirname) html_encode(outfile,filename);
else html_encode(outfile, host);
fprintf(outfile,"</a>");
return 0;
}
int html_error(char *error)
{
fprintf(outfile, " [%s]", error);
return 0;
}
void html_newline(struct _info *file, int level, int postdir, int needcomma)
{
fprintf(outfile, "<br>\n");
}
void html_close(struct _info *file, int level, int needcomma)
{
fprintf(outfile, "</%s><br>\n", file->tag);
}
void html_report(struct totals tot)
{
char buf[256];
fprintf(outfile,"<br><br><p>\n\n");
if (duflag) {
psize(buf, tot.size);
fprintf(outfile,"%s%s used in ", buf, hflag || siflag? "" : " bytes");
}
if (dflag)
fprintf(outfile,"%ld director%s\n",tot.dirs,(tot.dirs==1? "y":"ies"));
else
fprintf(outfile,"%ld director%s, %ld file%s\n",tot.dirs,(tot.dirs==1? "y":"ies"),tot.files,(tot.files==1? "":"s"));
fprintf(outfile, "\n</p>\n");
}