#!/usr/local/bin/kermit + # # Converts a plain text file to HTML. # Handles paragraphs and single-level numbered and bullet lists. # Works best with block-style text. # # F. da Cruz, Columbia University, Jan 2004. # Requires C-Kermit 8.0 or Kermit 95 2.1. # Last update: Mon Jan 12 10:34:50 2004 # # Usage: # html.ksc inputfilename [ "title" ] # # Illustrates: # . File i/o # . String functions # . Modularization # # Assumes: # . Bullet or numbered list items are indented by at least one space. # . Bullet characters can be "." "-" "+" "o". # . Numbered lists are numbered 1, 2, 3, ... 99. # . A list is terminated by a line that is not indented. # . If first text line is followed by a blank line it is to be the title. # # Paragraphs are separated by blank lines. Some attempt is made to also # handle paragraphs marked by indentation alone, but these don't mix well # with lists. # # Does not handle: # . multilevel lists # . description lists # . ordered lists numbered with anything but consecutive numbers # . blockquotes # . preformatted text # . tables, etc # . headings within the text # . anchors and links # . email (add an otion to handle mail headers) # # Result file will need some hand-tuning if it contains any of the # elements listed just above. define badversion echo C-Kermit 8.0 or K95 2.0 required, exit if LLT \v(version) 80000 badversion if not def \%1 exit 1 "Usage: \%0 filename [ title ]" # Open input and output files fopen /read \%i \%1 # Input file if fail exit 1 .oname := \fstripx(\fcontents(\%1)).html # Name of output file fopen /write \%o \m(oname) # Try to open it if fail exit 1 # Major states: # 0 start # 1 in a paragraph # 2 between paragraphs .state = 0 # State .\%n = 0 # Input line count .oldlen = 0 # Length of previous output line .inol = 0 # In ordered list .inul = 0 # In unordered list .cset = utf-8 # Change if necessary # Macro Definitions... def putout { # File output routine local out # Avoids consecutive blank lines .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 \%i next if fail end 1 incr \%n asg next \freplace(\ftrim(\m(next)),\9,\32) } 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 local bullet .out := \freplace(\m(line),&,&) .out := \freplace(\m(out),<,<) .out := \freplace(\m(out),>,>) .tmp := \fltrim(\m(out)) if not def tmp { putout, end 0 } .bullet = 0 .number = 0 if ( equal "\s(out[1:1])" "\32" ) { # Line starts with blank if ( eq "\s(tmp[2:1])" "\32" ) { # Unordered list item? .\%9 := \fleft(\m(tmp),1) # Bullet candidate if \findex(\%9,.-+o) { # If valid bullet character .bullet = 1 # It's a bullet item if not \m(inul) { # If new list start it. putout "
" putout .inul := 0 } else if \m(inol) { putout "" # If in ordered list close it. putout "
" putout .inol := 0 } if \m(bullet) { # This line has bullet .out :=
" putout .state = 2 # State becomes "between paragraphs" continue } else if ( eq "\fleft(\m(line),1)" "\32" ) { # Line is indented .\%8 := \fcode(\m(prev)) # Check previous and next lines if not def \%8 .\%8 = 32 .\%9 := \fcode(\m(next)) if not def \%9 .\%9 = 32 if ( > \%8 32 && > \%9 32 ) { # Previous and next line not indented putout # So this is a new paragraph putout "
" # but not separated by blank lines. putout } } .state = 1 # State become "in paragraph" if \%n putline # If we have a line write it out } if > \%n 0 { # Last lookahead line (if any) putline putout putout "
" } putout "