1# 2# 2014 August 24 3# 4# The author disclaims copyright to this source code. In place of 5# a legal notice, here is a blessing: 6# 7# May you do good and not evil. 8# May you find forgiveness for yourself and forgive others. 9# May you share freely, never taking more than you give. 10# 11#-------------------------------------------------------------------------- 12# 13# This script extracts the documentation for the API used by fts5 auxiliary 14# functions from header file fts5.h. It outputs html text on stdout that 15# is included in the documentation on the web. 16# 17 18set ::fts5_docs_output "" 19if {[info commands hd_putsnl]==""} { 20 if {[llength $argv]>0} { set ::extract_api_docs_mode [lindex $argv 0] } 21 proc output {text} { 22 puts $text 23 } 24} else { 25 proc output {text} { 26 append ::fts5_docs_output "$text\n" 27 } 28} 29if {[info exists ::extract_api_docs_mode]==0} {set ::extract_api_docs_mode api} 30 31 32set input_file [file join [file dir [info script]] fts5.h] 33set fd [open $input_file] 34set data [read $fd] 35close $fd 36 37 38# Argument $data is the entire text of the fts5.h file. This function 39# extracts the definition of the Fts5ExtensionApi structure from it and 40# returns a key/value list of structure member names and definitions. i.e. 41# 42# iVersion {int iVersion} xUserData {void *(*xUserData)(Fts5Context*)} ... 43# 44proc get_struct_members {data} { 45 46 # Extract the structure definition from the fts5.h file. 47 regexp "struct Fts5ExtensionApi {(.*?)};" $data -> defn 48 49 # Remove all comments from the structure definition 50 regsub -all {/[*].*?[*]/} $defn {} defn2 51 52 set res [list] 53 foreach member [split $defn2 {;}] { 54 55 set member [string trim $member] 56 if {$member!=""} { 57 catch { set name [lindex $member end] } 58 regexp {.*?[(][*]([^)]*)[)]} $member -> name 59 lappend res $name $member 60 } 61 } 62 63 set res 64} 65 66proc get_struct_docs {data names} { 67 # Extract the structure definition from the fts5.h file. 68 regexp {EXTENSION API FUNCTIONS(.*?)[*]/} $data -> docs 69 70 set current_doc "" 71 set current_header "" 72 73 foreach line [split $docs "\n"] { 74 regsub {[*]*} $line {} line 75 if {[regexp {^ } $line]} { 76 append current_doc "$line\n" 77 } elseif {[string trim $line]==""} { 78 if {$current_header!=""} { append current_doc "\n" } 79 } else { 80 if {$current_doc != ""} { 81 lappend res $current_header $current_doc 82 set current_doc "" 83 } 84 set subject n/a 85 regexp {^ *([[:alpha:]]*)} $line -> subject 86 if {[lsearch $names $subject]>=0} { 87 set current_header $subject 88 } else { 89 set current_header [string trim $line] 90 } 91 } 92 } 93 94 if {$current_doc != ""} { 95 lappend res $current_header $current_doc 96 } 97 98 set res 99} 100 101proc get_tokenizer_docs {data} { 102 regexp {(xCreate:.*?)[*]/} $data -> docs 103 104 set res "<dl>\n" 105 foreach line [split [string trim $docs] "\n"] { 106 regexp {[*][*](.*)} $line -> line 107 if {[regexp {^ ?x.*:} $line]} { 108 append res "<dt><b>$line</b></dt><dd><p style=margin-top:0>\n" 109 continue 110 } 111 if {[regexp {SYNONYM SUPPORT} $line]} { 112 set line "</dl><h3>Synonym Support</h3>" 113 } 114 if {[string trim $line] == ""} { 115 append res "<p>\n" 116 } else { 117 append res "$line\n" 118 } 119 } 120 121 set res 122} 123 124proc get_api_docs {data} { 125 # Initialize global array M as a map from Fts5StructureApi member name 126 # to member definition. i.e. 127 # 128 # iVersion -> {int iVersion} 129 # xUserData -> {void *(*xUserData)(Fts5Context*)} 130 # ... 131 # 132 array set M [get_struct_members $data] 133 134 # Initialize global list D as a map from section name to documentation 135 # text. Most (all?) section names are structure member names. 136 # 137 set D [get_struct_docs $data [array names M]] 138 139 output "<dl>" 140 foreach {sub docs} $D { 141 if {[info exists M($sub)]} { 142 set hdr $M($sub) 143 set link " id=$sub" 144 } else { 145 set link "" 146 } 147 148 #output "<hr color=#eeeee style=\"margin:1em 8.4ex 0 8.4ex;\"$link>" 149 #set style "padding-left:6ex;font-size:1.4em;display:block" 150 #output "<h style=\"$style\"><pre>$hdr</pre></h>" 151 152 regsub -line {^ *[)]} $hdr ")" hdr 153 output "<dt style=\"white-space:pre;font-family:monospace;font-size:120%\"" 154 output "$link>" 155 output "<b>$hdr</b></dt><dd>" 156 157 set mode "" 158 set margin " style=margin-top:0.1em" 159 foreach line [split [string trim $docs] "\n"] { 160 if {[string trim $line]==""} { 161 if {$mode != ""} {output "</$mode>"} 162 set mode "" 163 } elseif {$mode == ""} { 164 if {[regexp {^ } $line]} { 165 set mode codeblock 166 } else { 167 set mode p 168 } 169 output "<$mode$margin>" 170 set margin "" 171 } 172 output $line 173 } 174 if {$mode != ""} {output "</$mode>"} 175 output "</dd>" 176 } 177 output "</dl>" 178} 179 180proc get_fts5_struct {data start end} { 181 set res "" 182 set bOut 0 183 foreach line [split $data "\n"] { 184 if {$bOut==0} { 185 if {[regexp $start $line]} { 186 set bOut 1 187 } 188 } 189 190 if {$bOut} { 191 append res "$line\n" 192 } 193 194 if {$bOut} { 195 if {[regexp $end $line]} { 196 set bOut 0 197 } 198 } 199 } 200 201 set map [list /* <i>/* */ */</i>] 202 string map $map $res 203} 204 205proc main {data} { 206 switch $::extract_api_docs_mode { 207 fts5_api { 208 output [get_fts5_struct $data "typedef struct fts5_api" "^\};"] 209 } 210 211 fts5_tokenizer { 212 output [get_fts5_struct $data "typedef struct Fts5Tokenizer" "^\};"] 213 output [get_fts5_struct $data \ 214 "Flags that may be passed as the third argument to xTokenize()" \ 215 "#define FTS5_TOKEN_COLOCATED" 216 ] 217 } 218 219 fts5_extension { 220 output [get_fts5_struct $data "typedef.*Fts5ExtensionApi" "^.;"] 221 } 222 223 Fts5ExtensionApi { 224 set struct [get_fts5_struct $data "^struct Fts5ExtensionApi" "^.;"] 225 set map [list] 226 foreach {k v} [get_struct_members $data] { 227 if {[string match x* $k]==0} continue 228 lappend map $k "<a href=#$k>$k</a>" 229 } 230 output [string map $map $struct] 231 } 232 233 api { 234 get_api_docs $data 235 } 236 237 tokenizer_api { 238 output [get_tokenizer_docs $data] 239 } 240 241 default { 242 } 243 } 244} 245main $data 246 247set ::fts5_docs_output 248 249 250 251 252 253