/* * print_rect_troff * convert a rectangular area of 'curscr' to troff commands which * do a credible job of replicating the screen image. * * The output should be compatible with nroff, groff 1.17 without * color support, and groff 1.18+ with color support. * * Typical use: * print_rect_troff(getbegy(Win), getbegx(Win), * getmaxy(Win), getmaxx(Win), * NULL, "screen.tr"); * * Rick Richardson , retro-programming enthusiast */ void print_rect_troff(int sy, int sx, int lines, int cols, char *spchar, char *filename) { FILE *fp; int my = sy + lines; int mx = sx + cols; int x, y; WINDOW *win = curscr; char chbuf[2] = {0,0}; char *chp; char *fgstr[8] = { "bla", "red", "gre", "yel", "blu", "mag", "cya", "whi" }; char *bgstr[8] = { "Bla", "Red", "Gre", "Yel", "Blu", "Mag", "Cya", "Whi" }; fp = fopen(filename, "w"); if (!fp) { beep(); return; } fprintf(fp, "'\\\"\n" "'\\\" curses to troff screen dump conversion helpers\n" "'\\\"\n" "'\\\"\n" "'\\\" Define foreground and background colors\n" "'\\\"\n" ".if mred .ds bla \\m[black]\n" "'\\\" Some issue with groff - a pure black bg doesn't cause a color change.\n" ".if mred .ds Bla \\M[grey1]\n" ".if mred .ds red \\m[red]\n" ".if mred .ds Red \\M[red]\n" ".if mred .ds gre \\m[green]\n" ".if mred .ds Gre \\M[green]\n" "'\\\" in curses on an xterm, yellow is actually orange. Go figure.\n" ".if mred .ds yel \\m[orange]\n" ".if mred .ds Yel \\M[orange]\n" ".if mred .ds blu \\m[blue]\n" ".if mred .ds Blu \\M[blue]\n" ".if mred .ds mag \\m[magenta]\n" ".if mred .ds Mag \\M[magenta]\n" ".if mred .ds cya \\m[cyan]\n" ".if mred .ds Cya \\M[cyan]\n" ".if mred .ds whi \\m[white]\n" ".if mred .ds Whi \\M[white]\n" ".if mred .ds pre \\mP\n" ".if mred .ds Pre \\MP\n" "'\\\"\n" "'\\\" Define 1 character wide filled box\n" "'\\\"\n" ".ds UBOX \\v'+.35v'\\D'P 0 -1.0v \\w'0'u 0 0 +1.0v -\\w'0'u 0'" "\\v'-.35v'\n" ".ie mred .ds BOX \\*[UBOX]\n" ".el .ds BOX\n" "'\\\"\n" "'\\\" Define line drawing characters\n" "'\\\"\n" ".ie t .ds VL \\h'\\w'0'u/2u'\\v'-.625v'\\D'l 0 1v'\\v'-.375v'\\h'\\w'0'u/2u'\n" ".el .ds VL |\n" ".ie t .ds HL \\v'-0.375v'\\D'l \\w'0'u 0'\\v'+0.375v'\n" ".el .ds HL -\n" ".ie t .ds UL \\h'\\w'0'u/2u'\\v'-0.375v'\\D'l 0 1v'\\v'-1v'" "\\D'l \\w'0'u/2u 0'\\v'+0.375v'\n" ".el .ds UL +\n" ".ie t .ds UR \\v'-0.375v'\\D'l \\w'0'u/2u 0'\\D'l 0 1v'" "\\v'-0.625v'\\h'\\w'0'u/2u'\n" ".el .ds UR +\n" ".ie t .ds LL \\h'\\w'0'u/2u'\\v'-0.375v'\\D'l 0 -1v'\\v'1v'" "\\D'l \\w'0'u/2u 0'\\v'+0.375v'\n" ".el .ds LL +\n" ".ie t .ds LR \\v'-0.375v'\\D'l \\w'0'u/2u 0'\\D'l 0 -1v'" "\\v'1.375v'\\h'\\w'0'u/2u'\n" ".el .ds LR +\n" "'\\\"\n" "'\\\" Define bold font\n" "'\\\"\n" ".ie t \\{\\\n" ". ie '\\*[.T]'ps' .ds CB \\f(CB\n" ". el .ds CB \\f(CW\n" ".\\}\n" ".el .ds CB \\fB\n" "'\\\"\n" "'\\\" curses screen dump starts here\n" "'\\\"\n" ); fprintf(fp, ".ie mred .ds SPC \\0\n"); fprintf(fp, ".el \\{\\\n"); fprintf(fp, ". ie n .ds SPC %s\n", spchar ? spchar : "\\0"); fprintf(fp, ". el .ds SPC \\*[UBOX]\\0\n"); fprintf(fp, ".\\}\n"); fprintf(fp, ".TS\n"); fprintf(fp, "lf(CW).\n"); for (y = sy; y < my; ++y) { short ofg, obg; int obold; ofg = -1; obg = -1; obold = 0; for (x = sx; x < mx; ++x) { chtype ch; attr_t attr; short pair; short fg, bg; int tmp; ch = mvwinch(win, y, x); wattr_get(win, &attr, &pair, NULL); attr = ch; pair = PAIR_NUMBER(attr); pair_content(pair, &fg, &bg); ch &= 0xff; if (0) fprintf(stderr, "ch=%lx attr=%lx pair=%d fg=%d bg=%d\n", ch, attr, pair, fg, bg); chbuf[0] = ch; chp = chbuf; bg &= 0x07; fg &= 0x07; if (pair == 0) { fg = 0; bg = 7; } if (attr & A_BOLD) { if (!obold) fprintf(fp, "\\*(CB"); obold = 1; } else { if (obold) fprintf(fp, "\\fP"); obold = 0; } if (attr & A_REVERSE) { tmp = fg; fg = bg; bg = tmp; } if (attr & A_ALTCHARSET) { switch (ch) { case 'x': chp = "\\*[VL]"; break; case 'q': chp = "\\*[HL]"; break; case 'k': chp = "\\*[UR]"; break; case 'l': chp = "\\*[UL]"; break; case 'j': chp = "\\*[LR]"; break; case 'm': chp = "\\*[LL]"; break; default: chp = "?"; break; } } if (fg != ofg) fprintf(fp, "\\*[%s]", fgstr[fg]); if (bg != obg) fprintf(fp, "\\*[%s]", bgstr[bg]); if (bg != 7) fprintf(fp, "\\*[BOX]"); if (bg != 7 && ch == ' ') fputs("\\*[SPC]", fp); else fputs(chp, fp); ofg = fg; obg = bg; } if (ofg != 0) fprintf(fp, "\\*[bla]"); if (obg != 7) fprintf(fp, "\\*[Whi]"); fputc('\n', fp); } fprintf(fp, ".TE\n"); fprintf(fp, "'\\\"\n"); fprintf(fp, "'\\\" curses screen dump ends here\n"); fprintf(fp, "'\\\"\n"); fclose(fp); }