diff options
author | Kristaps Dzonsons <kristaps@bsd.lv> | 2009-02-20 11:04:23 +0000 |
---|---|---|
committer | Kristaps Dzonsons <kristaps@bsd.lv> | 2009-02-20 11:04:23 +0000 |
commit | 9ca2c862d8cd73c34a7a1b8ceee8eb45c3115d5a (patch) | |
tree | f662e0af14e89eea55ff25935c553b76991418b3 /term.c | |
parent | 0d0191e1509b75f09a185c0ecd6600b832ff9bcc (diff) | |
download | mandoc-9ca2c862d8cd73c34a7a1b8ceee8eb45c3115d5a.tar.gz |
Re-added tree.c (for now).
Added initial terminal-output filter (term.c).
Diffstat (limited to 'term.c')
-rw-r--r-- | term.c | 360 |
1 files changed, 360 insertions, 0 deletions
@@ -0,0 +1,360 @@ +/* $Id$ */ +/* + * Copyright (c) 2008 Kristaps Dzonsons <kristaps@kth.se> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ +#include <assert.h> +#include <curses.h> +#include <err.h> +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <term.h> +#include <unistd.h> + +#include "mdoc.h" + + +static int termprint_r(size_t, size_t, + const struct mdoc_node *); +static void termprint_head(size_t, + const struct mdoc_meta *); +static void termprint_tail(size_t, + const struct mdoc_meta *); + +static char *arch2a(enum mdoc_arch); +static char *vol2a(enum mdoc_vol); +static char *msec2a(enum mdoc_msec); + +static size_t ttitle2a(char *, enum mdoc_vol, enum mdoc_msec, + enum mdoc_arch, size_t); + + +static char * +arch2a(enum mdoc_arch arch) +{ + + switch (arch) { + case (ARCH_alpha): + return("Alpha"); + case (ARCH_amd64): + return("AMD64"); + case (ARCH_amiga): + return("Amiga"); + case (ARCH_arc): + return("ARC"); + case (ARCH_arm): + return("ARM"); + case (ARCH_armish): + return("ARMISH"); + case (ARCH_aviion): + return("AViion"); + case (ARCH_hp300): + return("HP300"); + case (ARCH_hppa): + return("HPPA"); + case (ARCH_hppa64): + return("HPPA64"); + case (ARCH_i386): + return("i386"); + case (ARCH_landisk): + return("LANDISK"); + case (ARCH_luna88k): + return("Luna88k"); + case (ARCH_mac68k): + return("Mac68k"); + case (ARCH_macppc): + return("MacPPC"); + case (ARCH_mvme68k): + return("MVME68k"); + case (ARCH_mvme88k): + return("MVME88k"); + case (ARCH_mvmeppc): + return("MVMEPPC"); + case (ARCH_pmax): + return("PMAX"); + case (ARCH_sgi): + return("SGI"); + case (ARCH_socppc): + return("SOCPPC"); + case (ARCH_sparc): + return("SPARC"); + case (ARCH_sparc64): + return("SPARC64"); + case (ARCH_sun3): + return("Sun3"); + case (ARCH_vax): + return("VAX"); + case (ARCH_zaurus): + return("Zaurus"); + default: + break; + } + + return(NULL); +} + + +static char * +vol2a(enum mdoc_vol vol) +{ + + switch (vol) { + case (VOL_AMD): + return("OpenBSD Ancestral Manual Documents"); + case (VOL_IND): + return("OpenBSD Manual Master Index"); + case (VOL_KM): + return("OpenBSD Kernel Manual"); + case (VOL_LOCAL): + return("OpenBSD Local Manual"); + case (VOL_PRM): + return("OpenBSD Programmer's Manual"); + case (VOL_PS1): + return("OpenBSD Programmer's Supplementary Documents"); + case (VOL_SMM): + return("OpenBSD System Manager's Manual"); + case (VOL_URM): + return("OpenBSD Reference Manual"); + case (VOL_USD): + return("OpenBSD User's Supplementary Documents"); + default: + break; + } + + return(NULL); +} + + +static char * +msec2a(enum mdoc_msec msec) +{ + + switch (msec) { + case(MSEC_1): + return("1"); + case(MSEC_2): + return("2"); + case(MSEC_3): + return("3"); + case(MSEC_3f): + return("3f"); + case(MSEC_3p): + return("3p"); + case(MSEC_4): + return("4"); + case(MSEC_5): + return("5"); + case(MSEC_6): + return("6"); + case(MSEC_7): + return("7"); + case(MSEC_8): + return("8"); + case(MSEC_9): + return("9"); + case(MSEC_X11): + return("X11"); + case(MSEC_X11R6): + return("X11R6"); + case(MSEC_local): + return("local"); + case(MSEC_n): + return("n"); + case(MSEC_unass): + /* FALLTHROUGH */ + case(MSEC_draft): + return("draft"); + case(MSEC_paper): + return("paper"); + default: + break; + } + return(NULL); +} + + +static size_t +ttitle2a(char *dst, enum mdoc_vol vol, enum mdoc_msec msec, + enum mdoc_arch arch, size_t sz) +{ + char *p; + size_t ssz; + + if (NULL == (p = vol2a(vol))) + switch (msec) { + case (MSEC_1): + /* FALLTHROUGH */ + case (MSEC_6): + /* FALLTHROUGH */ + case (MSEC_7): + p = vol2a(VOL_URM); + break; + case (MSEC_8): + p = vol2a(VOL_SMM); + break; + case (MSEC_2): + /* FALLTHROUGH */ + case (MSEC_3): + /* FALLTHROUGH */ + case (MSEC_4): + /* FALLTHROUGH */ + case (MSEC_5): + p = vol2a(VOL_PRM); + break; + case (MSEC_9): + p = vol2a(VOL_KM); + break; + default: + /* FIXME: capitalise. */ + if (NULL == (p = msec2a(msec))) + p = msec2a(MSEC_local); + break; + } + assert(p); + + if ((ssz = strlcpy(dst, p, sz)) >= sz) + return(ssz); + + if ((p = arch2a(arch))) { + if ((ssz = strlcat(dst, " (", sz)) >= sz) + return(ssz); + if ((ssz = strlcat(dst, p, sz)) >= sz) + return(ssz); + if ((ssz = strlcat(dst, ")", sz)) >= sz) + return(ssz); + } + + return(ssz); +} + + +static int +termprint_r(size_t cols, size_t indent, const struct mdoc_node *node) +{ + + return(1); +} + + +static void +termprint_tail(size_t cols, const struct mdoc_meta *meta) +{ + struct tm *tm; + char *buf, *os; + size_t sz, osz, ssz, i; + + if (NULL == (buf = malloc(cols))) + err(1, "malloc"); + if (NULL == (os = malloc(cols))) + err(1, "malloc"); + + tm = localtime(&meta->date); + if (NULL == strftime(buf, cols, "%B %d, %Y", tm)) + err(1, "strftime"); + + osz = strlcpy(os, meta->os, cols); + + sz = strlen(buf); + ssz = sz + osz + 1; + + if (ssz > cols) { + ssz -= cols; + assert(ssz <= osz); + os[osz - ssz] = 0; + ssz = 1; + } else + ssz = cols - ssz + 1; + + printf("%s", os); + for (i = 0; i < ssz; i++) + printf(" "); + + printf("%s\n", buf); + + free(buf); + free(os); +} + + +static void +termprint_head(size_t cols, const struct mdoc_meta *meta) +{ + char *msec, *buf, *title; + size_t ssz, tsz, ttsz, i; + + if (NULL == (buf = malloc(cols))) + err(1, "malloc"); + if (NULL == (title = malloc(cols))) + err(1, "malloc"); + + /* Format the manual page header. */ + + tsz = ttitle2a(buf, meta->vol, meta->msec, meta->arch, cols); + ttsz = strlcpy(title, meta->title, cols); + + if (NULL == (msec = msec2a(meta->msec))) + msec = ""; + + ssz = (2 * (ttsz + 2 + strlen(msec))) + tsz + 2; + + if (ssz > cols) { + if ((ssz -= cols) % 2) + ssz++; + ssz /= 2; + + assert(ssz <= ttsz); + title[ttsz - ssz] = 0; + ssz = 1; + } else + ssz = ((cols - ssz) / 2) + 1; + + printf("%s(%s)", title, msec); + + for (i = 0; i < ssz; i++) + printf(" "); + + printf("%s", buf); + + for (i = 0; i < ssz; i++) + printf(" "); + + printf("%s(%s)\n\n", title, msec); + + free(title); + free(buf); +} + + +int +termprint(const struct mdoc_node *node, + const struct mdoc_meta *meta) +{ + size_t cols; + + if (ERR == setupterm(NULL, STDOUT_FILENO, NULL)) + return(0); + + cols = columns < 60 ? 60 : (size_t)columns; + + termprint_head(cols, meta); + if ( ! termprint_r(cols, 0, node)) + return(0); + termprint_tail(cols, meta); + return(1); +} + + |