OLD | NEW |
(Empty) | |
| 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 |
| 18 set ::fts5_docs_output "" |
| 19 if {[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 } |
| 29 if {[info exists ::extract_api_docs_mode]==0} {set ::extract_api_docs_mode api} |
| 30 |
| 31 |
| 32 set input_file [file join [file dir [info script]] fts5.h] |
| 33 set fd [open $input_file] |
| 34 set data [read $fd] |
| 35 close $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 # |
| 44 proc 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 |
| 66 proc 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 |
| 101 proc 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 |
| 124 proc 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 |
| 180 proc 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 |
| 205 proc 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 } |
| 245 main $data |
| 246 |
| 247 set ::fts5_docs_output |
| 248 |
| 249 |
| 250 |
| 251 |
| 252 |
OLD | NEW |