📄 art.c
字号:
/* $Id: art.c,v 3.0 1992/02/01 03:09:32 davison Trn $ *//* This software is Copyright 1991 by Stan Barber. * * Permission is hereby granted to copy, reproduce, redistribute or otherwise * use this software as long as: there is no monetary profit gained * specifically from the use or reproduction of this software, it is not * sold, rented, traded or otherwise marketed, and this copyright notice is * included prominently in any copy made. * * The author make no claims as to the fitness or correctness of this software * for any use whatsoever, and it is provided as is. Any use of this software * is at the user's own risk. */#include "EXTERN.h"#include "common.h"#include "trn.h"#include "ngstuff.h"#include "ngdata.h"#include "cache.h"#include "bits.h"#include "head.h"#include "help.h"#include "search.h"#include "artio.h"#include "ng.h"#include "final.h"#include "artstate.h"#include "rcstuff.h"#include "term.h"#include "sw.h"#include "util.h"#include "backpage.h"#include "intrp.h"#include "rthread.h"#include "rt-select.h"#include "rt-util.h"#include "rt-wumpus.h"#include "INTERN.h"#include "art.h"/* page_switch() return values */#define PS_NORM 0#define PS_ASK 1#define PS_RAISE 2#define PS_TOEND 3bool special = FALSE; /* is next page special length? */int slines = 0; /* how long to make page when special */ART_LINE highlight = -1; /* next line to be highlighted */char *restart = Nullch; /* if nonzero, the place where last */ /* line left off on line split */char *blinebeg; /* where in buffer current line began */ART_POS alinebeg; /* where in file current line began */#ifdef INNERSEARCHART_POS innersearch = 0; /* artpos of end of line we found */ /* for 'g' command */ART_LINE isrchline = 0; /* last line to display */bool hide_everything = FALSE; /* if set, do not write page now, */ /* but refresh when done with page */COMPEX gcompex; /* in article search pattern */#endifbool firstpage; /* is this the 1st page of article? */char art_buf[LBUFLEN]; /* place for article lines */voidart_init(){ ;}#ifdef METAMAIL#define VERY_LONG_STRING 200intdisplay_mime(){ if (!getenv("NOMETAMAIL")) { int code; interp(cmd_buf,(sizeof cmd_buf),getval("MIMESHOW",MIMESHOW)); termlib_reset(); resetty(); code = doshell(SH,cmd_buf); noecho(); crmode(); termlib_init(); return code; } return 1;}#endifintdo_article(){ register char *s; ART_POS artsize; /* size in bytes of article */ bool hide_this_line = FALSE; /* hidden header line? */ ART_LINE linenum; /* line # on page, 1 origin */#ifdef ULSMARTS bool under_lining = FALSE; /* are we underlining a word? */#endif register char *bufptr = art_buf; /* pointer to input buffer */ register int outpos; /* column position of output */ static char prompt_buf[64]; /* place to hold prompt */ bool notesfiles = FALSE; /* might there be notesfiles junk? */ char oldmode = mode; char *ctime();#ifdef METAMAIL bool tried_display_mime = FALSE;#endif#ifdef INNERSEARCH register int outputok;#endif#ifdef METAMAIL mime_article = FALSE;#endif if (fstat(fileno(artfp),&filestat)) /* get article file stats */ return DA_CLEAN; if ((filestat.st_mode & S_IFMT) != S_IFREG) return DA_NORM; artsize = filestat.st_size; /* from that get article size */ sprintf(prompt_buf, "%%sEnd of article %ld (of %ld) -- what next? [%%s]", (long)art,(long)lastart); /* format prompt string */ prompt = prompt_buf; int_count = 0; /* interrupt count is 0 */ if ((firstpage = (topline < 0)) != 0) { parseheader(art); fseek(artfp,htype[PAST_HEADER].ht_minpos,0); } for (;;) { /* for each page */ if (ThreadedGroup && max_tree_lines) init_tree(); /* init tree display */ assert(art == openart); if (do_fseek) { parseheader(art); /* make sure header is ours */ artpos = vrdary(artline); if (artpos < 0) artpos = -artpos; /* labs(), anyone? */ if (firstpage) artpos = (ART_POS)0; if (artpos < htype[PAST_HEADER].ht_minpos) { in_header = SOME_LINE; fseek(artfp,htype[PAST_HEADER].ht_minpos,0); } else fseek(artfp,artpos,0); do_fseek = FALSE; restart = Nullch; } linenum = 1; if (firstpage) { if (firstline) { interp(art_buf, (sizeof art_buf), firstline); linenum += tree_puts(art_buf,linenum+topline,0); artopen(art); /* rewind article in case interp */ /* forced a header parse */ } else { ART_NUM i; int selected, unseen; selected = (curr_artp->flags & AF_SEL); unseen = !was_read(art); sprintf(art_buf,"%s%s #%ld",ngname,moderated,(long)art); if (selected_only) { i = selected_count - (unseen && selected); sprintf(art_buf+strlen(art_buf)," (%ld + %ld more)", (long)i,(long)toread[ng] - selected_count - (!selected && unseen)); } else if ((i = (ART_NUM)(toread[ng] - unseen)) != 0 || (!ThreadedGroup && dmcount)) sprintf(art_buf+strlen(art_buf)," (%ld more)",(long)i); if (!ThreadedGroup && dmcount) sprintf(art_buf+strlen(art_buf)-1," + %ld Marked to return)", (long)dmcount); linenum += tree_puts(art_buf,linenum+topline,0); } start_header(art); forcelast = FALSE; /* we will have our day in court */ restart = Nullch; artline = 0; /* start counting lines */ artpos = 0; vwtary(artline,artpos); /* remember pos in file */ } for (; /* linenum already set */ in_header || (#ifdef INNERSEARCH innersearch ? innermore() :#endif linenum<(firstpage?initlines:(special?slines:LINES)) ); linenum++) { /* for each line on page */ if (int_count) { /* exit via interrupt? */ putchar('\n') FLUSH; /* get to left margin */ int_count = 0; /* reset interrupt count */ mode = oldmode; special = FALSE; return DA_NORM; /* skip out of loops */ } if (restart) { /* did not finish last line? */ bufptr = restart; /* then start again here */ restart = Nullch; /* and reset the flag */ } else if (in_header && headbuf[artpos] != '\0') { bufptr = index(headbuf+artpos,'\n') + 1; bcopy(headbuf+artpos,art_buf,bufptr-headbuf-artpos); art_buf[bufptr-headbuf-artpos] = '\0'; bufptr = art_buf; } else { if (fgets(art_buf,LBUFLEN,artfp)==Nullch) { /* if all done */ mode = oldmode; special = FALSE; return DA_NORM; /* skip out of loops */ } bufptr = art_buf; /* so start at beginning */ art_buf[LBUFLEN-1] = '\0'; /* make sure string ends */ } blinebeg = bufptr; /* remember where we began */ alinebeg = artpos; /* both in buffer and file */ if (in_header && bufptr == art_buf) { hide_this_line = parseline(art_buf,do_hiding,hide_this_line); if (!in_header) { linenum += finish_tree(linenum+topline); end_header(); } } else if (notesfiles && do_hiding && bufptr == art_buf && *art_buf == '#' && isupper(art_buf[1]) && art_buf[2] == ':' ) { fgets(art_buf,sizeof(art_buf),artfp); if (index(art_buf,'!') != Nullch) fgets(art_buf,sizeof(art_buf),artfp); htype[PAST_HEADER].ht_minpos = ftell(artfp); /* exclude notesfiles droppings */ hide_this_line = TRUE; /* and do not print either */ notesfiles = FALSE; }#ifdef CUSTOMLINES if (hideline && bufptr == art_buf && execute(&hide_compex,art_buf) ) hide_this_line = TRUE;#endif if (in_header && htype[in_header].ht_flags & HT_MAGIC) { if (in_header == NGS_LINE) { if ((s = index(art_buf,'\n')) != Nullch) *s = '\0'; hide_this_line = (index(art_buf,',') == Nullch) && strEQ(art_buf+12, ngname); if (s != Nullch) *s = '\n'; } else if (in_header == EXPIR_LINE) { if (!(htype[EXPIR_LINE].ht_flags & HT_HIDE)) hide_this_line = (strlen(art_buf) < 10); } else if (in_header == FROM_LINE) { if (do_hiding && (s = extract_name(art_buf+6)) != Nullch) strcpy(art_buf+6,s); } else if (in_header == DATE_LINE) { if (do_hiding && curr_artp->date != -1) strftime(art_buf+6, sizeof(art_buf)-6, getval("LOCALTIMEFMT", LOCALTIMEFMT), localtime(&curr_artp->date)); }#ifdef METAMAIL else if (in_header == CONTENT_LINE) { mime_article = nontext(art_buf+14); }#endif } if (in_header == SUBJ_LINE && htype[SUBJ_LINE].ht_flags & HT_MAGIC) { /* is this the subject? */ int length; length = strlen(art_buf)-1; artline++; art_buf[length] = '\0'; /* wipe out newline */#ifdef NOFIREWORKS no_ulfire();#endif notesfiles = (instr(&art_buf[length-10]," - (nf", TRUE) != Nullch); /* tree_puts(, ,1) underlines subject */ linenum += tree_puts(art_buf,linenum+topline,1)-1; } else if (hide_this_line && do_hiding) { /* do not print line? */ linenum--; /* compensate for linenum++ */ if (!in_header) hide_this_line = FALSE; } else if (in_header) { artline++; linenum += tree_puts(art_buf,linenum+topline,0)-1; } else { /* just a normal line */#ifdef METAMAIL if (mime_article && !tried_display_mime) { if (display_mime() == 0) return DA_NORM; else tried_display_mime = TRUE; }#endif if (highlight==artline) { /* this line to be highlit? */ if (marking == STANDOUT) {#ifdef NOFIREWORKS if (erase_screen) no_sofire();#endif standout(); } else {#ifdef NOFIREWORKS if (erase_screen) no_ulfire();#endif underline(); } if (*bufptr == '\n') putchar(' '); }#ifdef INNERSEARCH outputok = !hide_everything; /* get it into register, hopefully */#endif#ifdef CLEAREOL#ifdef INNERSEARCH if (outputok)#endif maybe_eol(); #endif /* CLEAREOL */#ifdef CUSTOMLINES if (pagestop && bufptr == art_buf && execute(&page_compex,art_buf) ) linenum = 32700;#endif for (outpos = 0; outpos < COLS; ) { /* while line has room */ if (*(unsigned char *)bufptr >= ' ') { /* normal char? */#ifdef ULSMARTS if (*bufptr == '_') { if (bufptr[1] == '\b') { if (!under_lining && highlight!=artline#ifdef INNERSEARCH && outputok#endif ) { under_lining++; if (UG) { if (bufptr != buf && bufptr[-1] == ' ') { outpos--; backspace(); } } underline(); } bufptr += 2; } } else { if (under_lining) { under_lining = 0; un_underline(); if (UG) { if (*bufptr == ' ') goto skip_put; outpos++; } } }#endif#ifdef INNERSEARCH if (outputok)#endif {#ifdef ROTATION if (rotate && !in_header && isalpha(*bufptr)) { if ((*bufptr & 31) <= 13) putchar(*bufptr+13); else putchar(*bufptr-13); } else#endif putchar(*bufptr); } if (*UC && ((highlight==artline && marking == 1)#ifdef ULSMARTS || under_lining#endif )) { backspace(); underchar(); } skip_put: bufptr++; outpos++; } else if (*bufptr == '\n' || !*bufptr) { /* newline? */#ifdef ULSMARTS if (under_lining) { under_lining = 0; un_underline(); }#endif#ifdef DEBUG if (debug & DEB_INNERSRCH && outpos < COLS - 6) { standout(); printf("%4d",artline); un_standout(); }#endif#ifdef INNERSEARCH if (outputok)#endif putchar('\n') FLUSH; restart = 0; outpos = 1000; /* signal normal \n */ } else if (*bufptr == '\t') { /* tab? */ int incpos = 8 - outpos % 8;#ifdef INNERSEARCH if (outputok)#endif if (GT) putchar(*bufptr); else while (incpos--) putchar(' '); bufptr++; outpos += 8 - outpos % 8; } else if (*bufptr == '\f') { /* form feed? */#ifdef INNERSEARCH if (outputok)#endif fputs("^L",stdout); if (bufptr == blinebeg && highlight != artline) linenum = 32700; /* how is that for a magic number? */ bufptr++; outpos += 2; } else { /* other control char */#ifdef INNERSEARCH if (outputok)#endif { if (dont_filter_control) putchar(*bufptr); else { putchar('^'); if (highlight == artline && *UC && marking == 1) { backspace(); underchar(); putchar(*bufptr+64); backspace(); underchar(); } else putchar(*bufptr+64); } } bufptr++; outpos += 2; } } /* end of column loop */ if (outpos < 1000) {/* did line overflow? */ restart = bufptr; /* restart here next time */ if (!AM || XN) {/* no automatic margins on tty? */#ifdef INNERSEARCH /* then move it down ourselves */ if (outputok)#endif putchar('\n') FLUSH; } if (*bufptr == '\n') /* skip the newline */ restart = 0; } /* handle normal end of output line formalities */ if (highlight == artline) { /* were we highlighting line? */ if (marking == STANDOUT) un_standout(); else un_underline(); highlight = -1; /* no more we are */ } artline++; /* count the line just printed */ if (artline - LINES + 1 > topline) /* did we just scroll top line off? */ topline = artline - LINES + 1; /* then recompute top line # */ } /* determine actual position in file */ if (restart) /* stranded somewhere in the buffer? */ artpos += restart - blinebeg; /* just calculate position */ else if (in_header) artpos = index(headbuf+artpos, '\n') - headbuf + 1; else /* no, ftell will do */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -