home *** CD-ROM | disk | FTP | other *** search
/ Columbia Kermit / kermit.zip / ckscripts / html < prev    next >
Text File  |  2020-01-01  |  8KB  |  236 lines

  1. #!/usr/local/bin/kermit +
  2. #
  3. # Converts a plain text file to HTML.
  4. # Handles paragraphs and single-level numbered and bullet lists.
  5. # Works best with block-style text.
  6. #
  7. # F. da Cruz, Columbia University, Jan 2004.
  8. # Requires C-Kermit 8.0 or Kermit 95 2.1.
  9. # Last update: Mon Jan 12 10:34:50 2004
  10. #
  11. # Usage:
  12. #   html.ksc inputfilename [ "title" ]
  13. #
  14. # Illustrates:
  15. #  . File i/o
  16. #  . String functions
  17. #  . Modularization
  18. #
  19. # Assumes:
  20. #  . Bullet or numbered list items are indented by at least one space.
  21. #  . Bullet characters can be "." "-" "+" "o". 
  22. #  . Numbered lists are numbered 1, 2, 3, ... 99.
  23. #  . A list is terminated by a line that is not indented.
  24. #  . If first text line is followed by a blank line it is to be the title.
  25. #
  26. # Paragraphs are separated by blank lines.  Some attempt is made to also
  27. # handle paragraphs marked by indentation alone, but these don't mix well
  28. # with lists.
  29. #
  30. # Does not handle:
  31. #  . multilevel lists
  32. #  . description lists
  33. #  . ordered lists numbered with anything but consecutive numbers
  34. #  . blockquotes
  35. #  . preformatted text
  36. #  . tables, etc
  37. #  . headings within the text
  38. #  . anchors and links
  39. #  . email (add an otion to handle mail headers)
  40. #
  41. # Result file will need some hand-tuning if it contains any of the
  42. # elements listed just above.
  43.  
  44. define badversion echo C-Kermit 8.0 or K95 2.0 required, exit
  45. if LLT \v(version) 80000 badversion
  46. if not def \%1 exit 1 "Usage: \%0 filename [ title ]"
  47.  
  48. # Open input and output files
  49.  
  50. fopen /read \%i \%1                     # Input file
  51. if fail exit 1
  52.  
  53. .oname := \fstripx(\fcontents(\%1)).html # Name of output file
  54. fopen /write \%o \m(oname)              # Try to open it
  55. if fail exit 1
  56.  
  57. # Major states:
  58. # 0 start
  59. # 1 in a paragraph
  60. # 2 between paragraphs
  61.  
  62. .state = 0                              # State
  63. .\%n = 0                                # Input line count
  64. .oldlen = 0                             # Length of previous output line
  65. .inol = 0                               # In ordered list
  66. .inul = 0                               # In unordered list
  67. .cset = utf-8                           # Change if necessary
  68.  
  69. # Macro Definitions...
  70.  
  71. def putout {                            # File output routine
  72.     local out                           # Avoids consecutive blank lines
  73.     .out := \fcontents(\%1)
  74.     .\%9 := \flen(\m(out))
  75.     if ( == \%9 0 && == \m(oldlen) 0 ) end 0
  76.     fwrite /line \%o \m(out)
  77.     if fail exit 1 "FILE WRITE ERROR: \m(oname)"
  78.     .oldlen := \%9
  79. }
  80.  
  81. def getline {                           # Read input line
  82.     .prev := \m(line)                   # with lookahead and lookback
  83.     .line := \m(next)
  84.     undef next
  85.     fread /line \%i next
  86.     if fail end 1
  87.     incr \%n
  88.     asg next \freplace(\ftrim(\m(next)),\9,\32)
  89. }
  90.  
  91. def putback {                           # "Rewind" the current record
  92.     .next := \m(line)                   # (works only once for any given line)
  93.     .line := \m(prev)
  94.     undef prev
  95. }
  96.  
  97. def putline {                           # Write current data line
  98.     local bullet
  99.     .out := \freplace(\m(line),&,&)
  100.     .out := \freplace(\m(out),<,<)
  101.     .out := \freplace(\m(out),>,>)
  102.     .tmp := \fltrim(\m(out))
  103.     if not def tmp { putout, end 0 }
  104.  
  105.     .bullet = 0
  106.     .number = 0
  107.  
  108.     if ( equal "\s(out[1:1])" "\32" ) { # Line starts with blank
  109.         if ( eq "\s(tmp[2:1])" "\32" ) { # Unordered list item?
  110.             .\%9 := \fleft(\m(tmp),1)   # Bullet candidate
  111.             if \findex(\%9,.-+o) {      # If valid bullet character
  112.                 .bullet = 1             # It's a bullet item
  113.                 if not \m(inul) {       # If new list start it.
  114.                     putout "<ul>"           
  115.                     .inul := \fcode(\fleft(\m(tmp),1)) # And remember
  116.                 }
  117.             }
  118.         } else if match "\m(tmp)" "{[1-9],[1-9][0-9]}.\32*" { # Ordered list?
  119.             .number = 1
  120.             if not \m(inol) {
  121.                 putout "<ol>"
  122.                 .inol = 1
  123.             }
  124.         }
  125.     } else if \m(inul) {                # Line does not start with space.
  126.         putout "</ul>"                  # If in unordered list close it.
  127.         putout "<p>"
  128.         putout
  129.         .inul := 0
  130.     } else if \m(inol) {
  131.         putout "</ol>"                  # If in ordered list close it.
  132.         putout "<p>"
  133.         putout
  134.         .inol := 0
  135.     }
  136.     if \m(bullet) {                     # This line has bullet
  137.         .out := <li>\s(tmp[3])
  138.     } else if \m(number) {              # This line has a number
  139.         .\%9 := \findex(.\32,\m(tmp))
  140.         .out := <li>\s(tmp[\%9+2])
  141.     } else if \m(inul) {                # Continuation line of list item
  142.         .out := \m(tmp)
  143.     } else if \m(inol) {                # Ditto
  144.         .out := \m(tmp)
  145.     } else if ( > \flen(\m(tmp)) 8 && == 0 \fverify(-,\m(tmp)) ) { # Rule
  146.         .out = "<hr>"
  147.     }
  148.     putout "\m(out)"
  149. }
  150.  
  151. def dump {                              # For debugging
  152.     echo DUMP \%1:
  153.     echo PREV=[\m(prev)]
  154.     echo LINE=[\m(line)]
  155.     echo NEXT=[\m(next)]
  156.     echo n=\%n
  157. }
  158.  
  159. # Begin actions
  160.  
  161. putout {<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">}
  162. putout "<html><head>"
  163.  
  164. while not def line {                    # Get first nonblank line
  165.     getline
  166.     if fail break
  167. }
  168. getline                                 # Get line after first nonblank line
  169.  
  170. if not def \%2 {                        # No Title given
  171.     if ( def prev && not def line ) {   # If top line followed by blank line
  172.         .\%2 := \m(prev)                # use it as the title
  173.         getline                         # and read another line
  174.     } else {                            # Otherwise
  175.         .\%2 = "Untitled"               # use "Untitled"
  176.         putback                         # and put this line back
  177.     }
  178. } else {                                # Title given on command line
  179.     putback                             # Save this line for next time
  180. }
  181. # Write rest of prolog...
  182.  
  183. putout "<title>\%2</title>"
  184. putout {<META http-equiv="Content-Type" content="text/html; charset=\m(cset)">}
  185. putout "</head>"
  186. putout {<body bgcolor="#ffffff" text="#000000">}
  187. putout "<h3>\%2</h3>"
  188. putout
  189.  
  190. .first = 1                              # Start loop with first = 1
  191.  
  192. while true {                            # Loop for each line in file.
  193.     if not \m(first) {                  # Get next line if not first trip.
  194.         getline
  195.         if fail break
  196.     }
  197.     .first = 0
  198.     if ( > \%n 1 && not \flen(\m(line)) ) { # Blank line
  199.         if ( == \m(state) 2 ) continue      # Ignore extra ones
  200.         if ( \m(inul) || \m(inol) ) {       # Watch out for end of list
  201.             if not eq "\fleft(\m(next),1)" "\32" continue
  202.         }
  203.         putout                          # Emit paragraph separator.
  204.         putout "<p>"
  205.         putout
  206.         .state = 2                      # State becomes "between paragraphs"
  207.         continue
  208.     } else if ( eq "\fleft(\m(line),1)" "\32" ) { # Line is indented
  209.         .\%8 := \fcode(\m(prev))        # Check previous and next lines
  210.         if not def \%8 .\%8 = 32
  211.         .\%9 := \fcode(\m(next))
  212.         if not def \%9 .\%9 = 32
  213.         if ( > \%8 32 && > \%9 32 ) {   # Previous and next line not indented
  214.             putout                      # So this is a new paragraph
  215.             putout "<p>"                # but not separated by blank lines.
  216.             putout
  217.         }
  218.     }
  219.     .state = 1                          # State become "in paragraph"
  220.     if \%n putline                      # If we have a line write it out
  221. }
  222. if > \%n 0 {                            # Last lookahead line (if any)
  223.     putline
  224.     putout
  225.     putout "<p>"
  226. }
  227. putout "<hr>"                           # Write out the epilog
  228. putout "<address>"
  229. putout "\m(oname): \v(date) \v(time)"
  230. putout "</address>"
  231. putout "</body></html>"
  232.  
  233. fclose \%i                              # And close the files
  234. fclose \%o
  235. exit
  236.