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