#!/net/u/1/f/fdc/kermit/wermit + # Replace the line just above with the full path of C-Kermit on your # computer, followed by a space and a '+' sign. # .version = 2.00 .verdate = 1 May 2017 set debug message off # Debugging... .\%9 := \$(DEBUG) # DEBUG=xxx on command line if def \%9 { # xxx can be ON, OFF, STDERR # If \%9 is defined but not one of the valid choices use STDERR # Example: DEBUG=1 html foo.txt if not \findex(\%9,|ON|OFF|STDERR|) .\%9 = STDERR set debug message \%9 } # Converts a plain text file to HTML. Rules for text file: # . Must be in block style, paragraphs not indented. # . Paragraphs are separated by one or more blank lines. # . Flushleft text is flowed. # . Indented text (e.g. bullet lists, blockquotes) is preserved as-is. # # Author: Frank da Cruz, the Kermit Project, Jan 2004. # Totally rewritten (as version 2.00): April 2017 # Last update: Mon May 1 14:34:50 2017 # # Requires C-Kermit 9.0.304 Dev.22 or later. # # Usage: # html inputfilename [ "title" [ outputfilename ] ] # OR: command | html "" "title" | command # OR: command | html "" "title" > outputfilename # # If a title is not specified, the first nonblank line of the text file # is used but only if it is followed by a blank line. # # Documentation: # . http://www.kermitproject.org/html.html # # Current version: # . http://www.kermitproject.org/ftp/kermit/scripts/html # # Does not handle: # . Multilevel lists # . Headings within the text # . Hanging-indent description lists # . Paragraphs indicated only by indentation of first line # . Any kind of font switching, e.g. to preserve layout of tables # or source code. # # Default configuration items (can be overriden by your ~/.htmlrc file) .destination = # Directory for HTML result .perms = 644 # Permissions for HTML result .lang = en # Language tag .color = black # Text color .bg = white # Background color .font = sans-serif # Font .size = 15px # Font size .margin = 12px # Margins .maxwidth = # Maximum page width # Check version and platform def USAGE { echo {Usage: \m(myname) inputfilename [ "title" [ outputfilename ]]} echo {OR: command | \m(myname) "" "title"} exit 1 } define badversion exit 1 "echo C-Kermit 9.0.304 Dev.22 or later required" if LLT \v(version) 900304 badversion if EQU \v(version) 900304 { if LLT "\v(test)" "Dev.22" badversion } if not EQU "\v(system)" "UNIX" exit 1 "Sorry, this program only works on Unix" if readable ~/.htmlrc take ~/.htmlrc # Load user's default parameters if fail exit 1 "?Problem with .htmlrc" if debug show mac destination perms lang color bg size margin maxwidth .myname := \fbasename(\%0) # Open input and output files .stdio = 0 # Not piping by default if defined \%1 { .\%9 := \ffileinfo(\%1,&a) # Get info about input file if not \%9 exit 1 "\%1: file not found" fopen /read \%i \fcontents(\%1) # Open it if fail exit 1 msg file \fcontents(\%1) open for input if ( not equ "\&a[7]" "regular" ) exit 1 "\%1: Not a regular file" if ( equ "\&a[9]" "binary" ) exit 1 "\%1 is a binary file" if not def cset { # If character set not defined .cset = ISO-8859-1 # check the file itself for switch \&a[9] { # likely possibilities... :text:7bit # 7-bit ASCII .cset = US-ASCII break :text:utf8 # UTF-8 .cset = UTF-8 break :text:8bit # Windows Latin .cset = Windows-1252 break } } msg character-set: \m(cset) } else { fopen /stdin \%i # "Open" the Standard Input stream if fail exit 1 # (shouldn't happen) if not background usage # Nothing waiting on stdin fopen /stdout \%o # If reading from pipe write to stdout if fail exit 1 # (shouldn't happen) .stdio = 1 # Remember we're piping msg using standard i/o } .maybehtml = 0 # Is input file already HTML? if not stdio { .filename := \fbasename(\fcontents(\%1)) # Name of input file .ext := \flop(\m(filename)) # Extension (part after the dot) .stem := \fstripx(\m(filename)) # Stem (part before the dot) if equ ".html" \m(ext) { .maybehtml = 1 } .oname := \fcontents(\%3) # Path for output file if not def oname .oname := \m(stem).html .oname := \m(destination)\m(oname) fopen /write \%o \m(oname) # Try to open the output file if fail exit 1 msg file \m(oname) open for output } # Major states: # 0 start # 1 in a paragraph # 2 between paragraphs .line = # Initialize operating variables .prev = .next = .state = 0 # State .\%n = 0 # Input line count .oldlen = 0 # Length of previous output line # Macro Definitions... def PUTOUT { # File output routine if > \v(argc) 2 { echo "PUTOUT: Line \%n - Too many args:" show args exit 1 } .out := \fcontents(\%1) .\%9 := \flen(\m(out)) if ( == \%9 0 && == \m(oldlen) 0 ) end 0 fwrite /line \%o \m(out) if fail exit 1 "FILE WRITE ERROR: \m(oname)" .oldlen := \%9 } def GETLINE { # Read input line .prev := \m(line) # with lookahead and lookback .line := \m(next) undef next fread /line /trim /untabify \%i next if fail end 1 incr \%n msg \%n. [\m(line)] } def PUTBACK { # "Rewind" the current record .next := \m(line) # (works only once for any given line) .line := \m(prev) undef prev } def PUTLINE { # Write current data line .out := \freplace(\m(line),&,&) .out := \freplace(\m(out),<,<) .out := \freplace(\m(out),>,>) putout {\m(out)} if equ {\fleft(\m(out),20)} {--------------------} putout {
} if equ {\fleft(\m(out),20)} {********************} putout {
} } # Begin actions .title := \fcontents(\%2) # Check for title on command line if not def title { # No Title given while not def line { # Get first nonblank line getline if fail break } if maybehtml if \findex(DOCTYPE HTML,\m(line)) { exit 1 {?\m(name) is already html} } getline # Get line after first nonblank line if ( def prev && not def line ) { # If top line followed by blank line .title := \m(prev) # use it as the title getline # and read another line } else { # Otherwise .title = "Untitled" # use "Untitled" putback # and put this line back } } # Write prolog... putout {} putout {} putout {} putout {} putout {\m(title)} putout {} putout {} .\%8 = if def cset .\%8 := {; charset=\m(cset)} putout {} putout {} putout {} putout {} putout {} if def margin putout {
} putout {

\m(title)

} putout putout {[Go to bottom]

} putout .state = 2 .blockquote = 0 if debug show args if debug show mac state first blockquote while true { # Loop for each line in file. getline # Read a line if fail break msg Line \%n: state=\m(state) blockquote=\m(blockquote) .first = 0 # Check for an unordered list not preceded by a blank line if == \fcode(\m(line)) 32 { if not blockquote { .tmp := \fltrim(\m(line)) putout {

}
            .blockquote = 1
        }
    # A blank line becomes "

" in normal text # but must be kept as-is in a

 block to avoid gaping vertical spaces
    } else if not def line {           # This line is blank
        if ( == state 2 ) continue     # Treat consecutive blanks lines as one
        if not blockquote {            # If not in a 
            putout {

} # Put a

.state = 2 # State becomes "between paragraphs" } else if == \fcode(\m(next)) 32 { # Keep blank line if still in

            putout                     # In 
 blank lines are like 

} continue # An indented line starts a

 block if we're not in one already
    } else if ( == \fcode(\m(line)) 32 ) { # This line is indented 
        # if ( not blockquote && ( == state 2 || == state 0 ) )
        if not blockquote {
            putout {
}        
            .blockquote = 1                
        }
    # A non-indented line terminates the active 
 block (if any)
    } else if ( > \fcode(\m(line)) 32 ) { # This line is not indented
        if blockquote {
            putout {
} putout {

} .state = 2 .blockquote = 0 } } .state = 1 # State becomes "in paragraph" if \%n putline # If we have a line write it out } if > \%n 0 { # Last lookahead line (if any) putline putout {

} } putout {[Go to top]} putout "


" # Write out the epilog putout {
} if not stdio putout "\fbasename(\m(oname)): \v(timestamp) ... " putout {Text to html by \m(myname) - \m(version)} putout "
" putout "
" putout " putout "" fclose \%i # And close the files fclose \%o if not stdio chmod \m(perms) \m(oname) exit ; Local Variables: ; comment-column:40 ; comment-start:"# " ; End: