Simple Markup

EKB I needed a simple markup language that would handle:

  • Bulleted lists
  • Smart quotes
  • Paragraph breaks

And, as an extra feature, en-dashes.

Here's the resulting code. It has an example at the end that demonstrates all of the features:


 namespace eval smark {
    
    variable u
    array set u {
        bull    "\u2022"
        dqo     "\u201C"
        dqc     "\u201D"
        sqo     "\u2018"
        sqc     "\u2019"
        en      "\u2013"
    }
    
    # Return a converted string
    proc convert {t} {
        variable u
        
        ## Strip spaces at start & end of lines
        regsub -all -line {^[ \t]+|[ \t]+$} $t "" t
        
        ## If there are newlines right at the start or end, get rid of them
        regsub -all {^\n+|\n+$} $t "" t
        
        ## Lines starting with asterisk: convert to bullet; hide newline with bell character
        regsub -all -line {^\*} $t "\a   $u(bull)" t
        # Did we add a bell character as the first character? Get rid of it
        regsub {^\a} $t "" t
        
        ## Get rid of single newlines; dbl newlines become single newlines
        # First hide dbl newlines by (temporarily) replacing them with the bell character
        regsub -all {\n\n} $t "\a" t
        # Next replace single newlines with a space
        regsub -all {\n} $t " " t
        # Finally replace the bell character with the newline character
        regsub -all {\a} $t "\n" t
        
        ## Smart quotes
        # Any quote with a space immediately to the left - replace with open quote
        regsub -all {(\s)'} $t "\\1$u(sqo)" t
        regsub -all {(\s)"} $t "\\1$u(dqo)" t
        
        # Any quote at the start of the whole text - replace with open quote
        regsub {^'} $t $u(sqo) t
        regsub {^"} $t $u(dqo) t
        
        # All others, replace with close quote
        regsub -all {'} $t $u(sqc) t
        regsub -all {"} $t $u(dqc) t
        
        ## Dashes
        # A dash separated by spaces is replaced with an en dash
        regsub -all { - } $t " $u(en) " t
        
        return $t
    }
 }

 ##############################################
 #
 # Example
 #
 ##############################################

 set msg {
    This is a bit of text with line breaks. But only
    a double line break should actually lead to a line
    break.
    
    For example, this is now in a new paragraph. Let's
    see what we can do in the way of "smart quotes" -
    that is, quote marks that are either open or closed
    depending upon their placement relative to words
    and spaces.
    
    It should also be possible to put "quotes inside of other
    'quotes' with this simple markup."
    
    So:
     *  What do you think of this?
     *  Could it be useful?
    
    Thanks for trying it out.
 }
 
 text .t -spacing3 10 -wrap word -font "Times 11" -height 15 -width 50
 .t insert end [smark::convert $msg]
 
 pack .t -fill both -expand yes