14aee5dffSdan# 24aee5dffSdan# 2014 August 24 34aee5dffSdan# 44aee5dffSdan# The author disclaims copyright to this source code. In place of 54aee5dffSdan# a legal notice, here is a blessing: 64aee5dffSdan# 74aee5dffSdan# May you do good and not evil. 84aee5dffSdan# May you find forgiveness for yourself and forgive others. 94aee5dffSdan# May you share freely, never taking more than you give. 104aee5dffSdan# 114aee5dffSdan#-------------------------------------------------------------------------- 124aee5dffSdan# 134aee5dffSdan# This script extracts the documentation for the API used by fts5 auxiliary 144aee5dffSdan# functions from header file fts5.h. It outputs html text on stdout that 154aee5dffSdan# is included in the documentation on the web. 164aee5dffSdan# 174aee5dffSdan 1848d70140Sdanset ::fts5_docs_output "" 1948d70140Sdanif {[info commands hd_putsnl]==""} { 2027277c4eSdan if {[llength $argv]>0} { set ::extract_api_docs_mode [lindex $argv 0] } 2148d70140Sdan proc output {text} { 2248d70140Sdan puts $text 2348d70140Sdan } 2448d70140Sdan} else { 2548d70140Sdan proc output {text} { 2627277c4eSdan append ::fts5_docs_output "$text\n" 2748d70140Sdan } 2848d70140Sdan} 2927277c4eSdanif {[info exists ::extract_api_docs_mode]==0} {set ::extract_api_docs_mode api} 3027277c4eSdan 3148d70140Sdan 324aee5dffSdanset input_file [file join [file dir [info script]] fts5.h] 334aee5dffSdanset fd [open $input_file] 344aee5dffSdanset data [read $fd] 354aee5dffSdanclose $fd 364aee5dffSdan 374aee5dffSdan 384aee5dffSdan# Argument $data is the entire text of the fts5.h file. This function 394aee5dffSdan# extracts the definition of the Fts5ExtensionApi structure from it and 404aee5dffSdan# returns a key/value list of structure member names and definitions. i.e. 414aee5dffSdan# 424aee5dffSdan# iVersion {int iVersion} xUserData {void *(*xUserData)(Fts5Context*)} ... 434aee5dffSdan# 444aee5dffSdanproc get_struct_members {data} { 454aee5dffSdan 464aee5dffSdan # Extract the structure definition from the fts5.h file. 4727277c4eSdan regexp "struct Fts5ExtensionApi {(.*?)};" $data -> defn 484aee5dffSdan 494aee5dffSdan # Remove all comments from the structure definition 504aee5dffSdan regsub -all {/[*].*?[*]/} $defn {} defn2 514aee5dffSdan 524aee5dffSdan set res [list] 534aee5dffSdan foreach member [split $defn2 {;}] { 544aee5dffSdan 554aee5dffSdan set member [string trim $member] 564aee5dffSdan if {$member!=""} { 574aee5dffSdan catch { set name [lindex $member end] } 584aee5dffSdan regexp {.*?[(][*]([^)]*)[)]} $member -> name 594aee5dffSdan lappend res $name $member 604aee5dffSdan } 614aee5dffSdan } 624aee5dffSdan 634aee5dffSdan set res 644aee5dffSdan} 654aee5dffSdan 664aee5dffSdanproc get_struct_docs {data names} { 674aee5dffSdan # Extract the structure definition from the fts5.h file. 684aee5dffSdan regexp {EXTENSION API FUNCTIONS(.*?)[*]/} $data -> docs 694aee5dffSdan 704aee5dffSdan set current_doc "" 714aee5dffSdan set current_header "" 724aee5dffSdan 734aee5dffSdan foreach line [split $docs "\n"] { 744aee5dffSdan regsub {[*]*} $line {} line 754aee5dffSdan if {[regexp {^ } $line]} { 764aee5dffSdan append current_doc "$line\n" 774aee5dffSdan } elseif {[string trim $line]==""} { 784aee5dffSdan if {$current_header!=""} { append current_doc "\n" } 794aee5dffSdan } else { 804aee5dffSdan if {$current_doc != ""} { 814aee5dffSdan lappend res $current_header $current_doc 824aee5dffSdan set current_doc "" 834aee5dffSdan } 844aee5dffSdan set subject n/a 854aee5dffSdan regexp {^ *([[:alpha:]]*)} $line -> subject 864aee5dffSdan if {[lsearch $names $subject]>=0} { 874aee5dffSdan set current_header $subject 884aee5dffSdan } else { 894aee5dffSdan set current_header [string trim $line] 904aee5dffSdan } 914aee5dffSdan } 924aee5dffSdan } 934aee5dffSdan 944aee5dffSdan if {$current_doc != ""} { 954aee5dffSdan lappend res $current_header $current_doc 964aee5dffSdan } 974aee5dffSdan 984aee5dffSdan set res 994aee5dffSdan} 1004aee5dffSdan 10127277c4eSdanproc get_tokenizer_docs {data} { 10227277c4eSdan regexp {(xCreate:.*?)[*]/} $data -> docs 10327277c4eSdan 10427277c4eSdan set res "<dl>\n" 10527277c4eSdan foreach line [split [string trim $docs] "\n"] { 10627277c4eSdan regexp {[*][*](.*)} $line -> line 10727277c4eSdan if {[regexp {^ ?x.*:} $line]} { 10827277c4eSdan append res "<dt><b>$line</b></dt><dd><p style=margin-top:0>\n" 10927277c4eSdan continue 11027277c4eSdan } 11127277c4eSdan if {[string trim $line] == ""} { 11227277c4eSdan append res "<p>\n" 11327277c4eSdan } else { 11427277c4eSdan append res "$line\n" 11527277c4eSdan } 11627277c4eSdan } 11727277c4eSdan append res "</dl>\n" 11827277c4eSdan 11927277c4eSdan set res 12027277c4eSdan} 12127277c4eSdan 12227277c4eSdanproc get_api_docs {data} { 1234aee5dffSdan # Initialize global array M as a map from Fts5StructureApi member name 1244aee5dffSdan # to member definition. i.e. 1254aee5dffSdan # 1264aee5dffSdan # iVersion -> {int iVersion} 1274aee5dffSdan # xUserData -> {void *(*xUserData)(Fts5Context*)} 1284aee5dffSdan # ... 1294aee5dffSdan # 1304aee5dffSdan array set M [get_struct_members $data] 1314aee5dffSdan 1324aee5dffSdan # Initialize global list D as a map from section name to documentation 1334aee5dffSdan # text. Most (all?) section names are structure member names. 1344aee5dffSdan # 1354aee5dffSdan set D [get_struct_docs $data [array names M]] 1364aee5dffSdan 137*3eb9024dSdan output "<dl>" 13827277c4eSdan foreach {sub docs} $D { 13927277c4eSdan if {[info exists M($sub)]} { 14027277c4eSdan set hdr $M($sub) 14127277c4eSdan set link " id=$sub" 14227277c4eSdan } else { 14327277c4eSdan set link "" 1444aee5dffSdan } 14527277c4eSdan 146*3eb9024dSdan #output "<hr color=#eeeee style=\"margin:1em 8.4ex 0 8.4ex;\"$link>" 147*3eb9024dSdan #set style "padding-left:6ex;font-size:1.4em;display:block" 148*3eb9024dSdan #output "<h style=\"$style\"><pre>$hdr</pre></h>" 149*3eb9024dSdan 150*3eb9024dSdan regsub -line {^ *[)]} $hdr ")" hdr 151*3eb9024dSdan output "<dt style=\"white-space:pre;font-family:monospace;font-size:120%\"" 152*3eb9024dSdan output "$link>" 153*3eb9024dSdan output "<b>$hdr</b></dt><dd>" 1544aee5dffSdan 1554aee5dffSdan set mode "" 156*3eb9024dSdan set margin " style=margin-top:0.1em" 1574aee5dffSdan foreach line [split [string trim $docs] "\n"] { 1584aee5dffSdan if {[string trim $line]==""} { 15948d70140Sdan if {$mode != ""} {output "</$mode>"} 1604aee5dffSdan set mode "" 1614aee5dffSdan } elseif {$mode == ""} { 1624aee5dffSdan if {[regexp {^ } $line]} { 16348d70140Sdan set mode codeblock 1644aee5dffSdan } else { 1654aee5dffSdan set mode p 1664aee5dffSdan } 167*3eb9024dSdan output "<$mode$margin>" 168*3eb9024dSdan set margin "" 1694aee5dffSdan } 17048d70140Sdan output $line 1714aee5dffSdan } 17248d70140Sdan if {$mode != ""} {output "</$mode>"} 173*3eb9024dSdan output "</dd>" 1744aee5dffSdan } 175*3eb9024dSdan output "</dl>" 17627277c4eSdan} 17727277c4eSdan 17827277c4eSdanproc get_fts5_struct {data start end} { 17927277c4eSdan set res "" 18027277c4eSdan set bOut 0 18127277c4eSdan foreach line [split $data "\n"] { 18227277c4eSdan if {$bOut==0} { 18327277c4eSdan if {[regexp $start $line]} { 18427277c4eSdan set bOut 1 18527277c4eSdan } 18627277c4eSdan } 18727277c4eSdan 18827277c4eSdan if {$bOut} { 18927277c4eSdan append res "$line\n" 19027277c4eSdan } 19127277c4eSdan 19227277c4eSdan if {$bOut} { 19327277c4eSdan if {[regexp $end $line]} { 19427277c4eSdan set bOut 0 19527277c4eSdan } 19627277c4eSdan } 19727277c4eSdan } 19827277c4eSdan 19927277c4eSdan set map [list /* <i>/* */ */</i>] 20027277c4eSdan string map $map $res 20127277c4eSdan} 20227277c4eSdan 20327277c4eSdanproc main {data} { 20427277c4eSdan switch $::extract_api_docs_mode { 20527277c4eSdan fts5_api { 20627277c4eSdan output [get_fts5_struct $data "typedef struct fts5_api" "^\};"] 20727277c4eSdan } 20827277c4eSdan 20927277c4eSdan fts5_tokenizer { 21027277c4eSdan output [get_fts5_struct $data "typedef struct Fts5Tokenizer" "^\};"] 21127277c4eSdan } 21227277c4eSdan 21327277c4eSdan fts5_extension { 21427277c4eSdan output [get_fts5_struct $data "typedef.*Fts5ExtensionApi" "^.;"] 21527277c4eSdan } 21627277c4eSdan 21727277c4eSdan Fts5ExtensionApi { 21827277c4eSdan set struct [get_fts5_struct $data "^struct Fts5ExtensionApi" "^.;"] 21927277c4eSdan set map [list] 22027277c4eSdan foreach {k v} [get_struct_members $data] { 22127277c4eSdan if {[string match x* $k]==0} continue 22227277c4eSdan lappend map $k "<a href=#$k>$k</a>" 22327277c4eSdan } 22427277c4eSdan output [string map $map $struct] 22527277c4eSdan } 22627277c4eSdan 22727277c4eSdan api { 22827277c4eSdan get_api_docs $data 22927277c4eSdan } 23027277c4eSdan 23127277c4eSdan tokenizer_api { 23227277c4eSdan output [get_tokenizer_docs $data] 23327277c4eSdan } 23427277c4eSdan 23527277c4eSdan default { 23627277c4eSdan } 23727277c4eSdan } 23827277c4eSdan} 23927277c4eSdanmain $data 2404aee5dffSdan 24148d70140Sdanset ::fts5_docs_output 2424aee5dffSdan 2434aee5dffSdan 2444aee5dffSdan 2454aee5dffSdan 2464aee5dffSdan 247