Tuesday, August 01, 2006

[Tcl] Tag wiki

Once we have sorted out our tag strings based on string length (see previous posting), we can tag them accordingly.
# Examples:
# wikiTag {He likes to play Table Tennis, but not Tennis. Table Tennis is fun} #    {{table tennis} {tennis}}
# He likes to play [Table Tennis], but not [Tennis]. [Table Tennis] is fun
#
# wikiTag {He likes to play Table Tennis, but not Tennis. Table Tennis is fun} #    {{tennis} {table tennis}}
# He likes to play Table [Tennis], but not [Tennis]. Table [Tennis] is fun
proc wikiTag { data maps } {

 foreach map $maps {
  set start 0
  while 1 {
   set pos [string first $map [string tolower $data] $start]
   if { $pos == -1 } {
    break
   }

   if { [wikiOk2Tag $data $map $pos] } {
    regsub -nocase -start $pos "($map)" $data {[\1]} data
   }
   set start [expr $pos + 2]
  }
 }

 return $data
}


#
# left has [, right has ] == not ok
#
proc wikiOk2Tag { data map index } {
 set sleft [string range $data 0 [expr $index - 1]]
 set sright [string range $data [expr $index + [string length $map]] end]

 # left
 foreach c [lreverse [split $sleft {}]] {
  if { [string equal {[} $c] } {
   return 0
  } elseif { [string equal {]} $c] } {
   return 1
  }
 }

 # right
 foreach c [split $sright {}] {
  if { [string equal {]} $c] } {
   return 0
  } elseif { [string equal {[} $c] } {
   return 1
  }

 }

 return 1
}


proc lreverse { l } {
 set n [llength $l]
 set rc {}
 for { set i [expr $n-1] } { $i >= 0 } { incr i -1 } {
  lappend rc [lindex $l $i]
 }
 return $rc
}

Labels: ,