System.Data.SQLite
Check-in [42512a2bfb]
Not logged in

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Preserve selected HTML tags when processing the virtual table methods documentation into the CHM file.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | vtabDocComments
Files: files | file ages | folders
SHA1: 42512a2bfbd526393dcefeb0e0ef0a735bb39090
User & Date: mistachkin 2015-10-18 20:07:44
Context
2015-10-18
20:11
Minor simplification to the previous check-in. Also, correct a comment. Closed-Leaf check-in: fcc756f8d0 user: mistachkin tags: vtabDocComments
20:07
Preserve selected HTML tags when processing the virtual table methods documentation into the CHM file. check-in: 42512a2bfb user: mistachkin tags: vtabDocComments
05:32
Update embedded virtual table methods documentation comments using the new tool. check-in: 29f36edc2d user: mistachkin tags: vtabDocComments
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to Doc/buildChm.tcl.

    41     41       exec fossil.exe sha1sum [file nativename $fileName]
    42     42     } result] == 0} then {
    43     43       return [string trim [lindex [split $result " "] 0]]
    44     44     }
    45     45     return ""
    46     46   }
    47     47   
           48  +#
           49  +# NOTE: This procedure unescapes certain HTML tags that are used within the
           50  +#       documentation for the virtual table methods.
           51  +#
           52  +proc unescapeHtmlTags { fileName cdata } {
           53  +  #
           54  +  # NOTE: Read all the textual data from the file.
           55  +  #
           56  +  set data [readFile $fileName]
           57  +
           58  +  #
           59  +  # NOTE: No replacements made yet.
           60  +  #
           61  +  set count 0
           62  +
           63  +  #
           64  +  # NOTE: If requested by the caller, unwrap all content contained with XML
           65  +  #       CDATA sections as well.
           66  +  #
           67  +  if {$cdata} then {
           68  +    #
           69  +    # NOTE: Grab everything within the CDATA tags and use verbatim.
           70  +    #
           71  +    set cdataCount [regsub -all -- {<![CDATA[(.*?)]]>} $data {\1} data]
           72  +
           73  +    if {$cdataCount > 0} then {
           74  +      incr count $cdataCount
           75  +    } else {
           76  +      # puts stdout "*WARNING* File \"$fileName\" has no CDATA"
           77  +    }
           78  +  }
           79  +
           80  +  #
           81  +  # TODO: Handle all the HTML tags we know may be present in the virtual
           82  +  #       table method documentation.  This may need adjustments in the
           83  +  #       future.
           84  +  #
           85  +  foreach to [list \
           86  +      {<b>} {</b>} {<br>} {<dd>} {</dd>} {<dl>} {</dl>} {<dt>} \
           87  +      {</dt>} {<li>} {</li>} {<ol>} {</ol>} {<tt>} {</tt>} \
           88  +      {<ul>} {</ul>}] {
           89  +    #
           90  +    # NOTE: Figure out the escaped form of this tag and then replace it
           91  +    #       with the unescaped form.
           92  +    #
           93  +    set from [string map [list < &lt\; > &gt\;] $to]
           94  +    incr count [regsub -all -- $from $data $to data]
           95  +  }
           96  +
           97  +  #
           98  +  # NOTE: Issue a warning if the "href" pattern was not matched.
           99  +  #
          100  +  if {$count == 0} then {
          101  +    puts stdout "*WARNING* File \"$fileName\" has no supported HTML tags"
          102  +  }
          103  +
          104  +  #
          105  +  # NOTE: If some replacements were performed on the data from the file,
          106  +  #       then overwrite it with the new data.
          107  +  #
          108  +  if {$count > 0} then {
          109  +    writeFile $fileName $data
          110  +  }
          111  +}
          112  +
    48    113   #
    49    114   # HACK: This procedure checks all the "href" attribute values in the specified
    50    115   #       core documentation file.  For each value, this procedure checks if the
    51    116   #       reference conforms to one of the following general categories:
    52    117   #
    53    118   #       1. A relative reference to a named anchor within the same document.
    54    119   #       2. An absolute reference using HTTP or HTTPS.
................................................................................
   135    200       # NOTE: Perform the replacements, if any, keeping track of how many were
   136    201       #       done.
   137    202       #
   138    203       incr count [regsub -all -- $pattern $data $subSpec data]
   139    204     }
   140    205   
   141    206     #
   142         -  # NOTE: If some replacements were performed on the data from the file, then
   143         -  #       overwrite it with the new data; otherwise, issue a warning.
          207  +  # NOTE: Issue a warning if the "href" pattern was not matched.
          208  +  #
          209  +  if {$count == 0} then {
          210  +    puts stdout "*WARNING* File \"$fileName\" does not match: href=\"(.*?)\""
          211  +  }
          212  +
          213  +  #
          214  +  # NOTE: If some replacements were performed on the data from the file,
          215  +  #       then overwrite it with the new data.
   144    216     #
   145    217     if {$count > 0} then {
   146    218       writeFile $fileName $data
   147         -  } else {
   148         -    puts stdout "*WARNING* File \"$fileName\" does not match: href=\"(.*?)\""
   149    219     }
   150    220   }
   151    221   
   152    222   #
   153    223   # HACK: Copy our local [fixed] copy of the MSDN documenter assembly into the
   154    224   #       installed location of NDoc3, if necessary.  Actually copying the file
   155    225   #       will require elevated administrator privileges; otherwise, it will
................................................................................
   292    362     if {![file isfile $fileName]} then {
   293    363       puts stdout "Cannot find core syntax file: $fileName"
   294    364       exit 1
   295    365     }
   296    366   
   297    367     transformCoreDocumentationFile $fileName https://www.sqlite.org/
   298    368   }
          369  +
          370  +###############################################################################
          371  +
          372  +foreach fileName [glob -nocomplain [file join $temporaryPath \
          373  +    System.Data.SQLite~System.Data.SQLite.ISQLiteNativeModule*.html]] {
          374  +  set fileName [file join $path $fileName]
          375  +
          376  +  if {![file isfile $fileName]} then {
          377  +    puts stdout "Cannot find temporary provider file: $fileName"
          378  +    exit 1
          379  +  }
          380  +
          381  +  unescapeHtmlTags $fileName false
          382  +}
   299    383   
   300    384   ###############################################################################
   301    385   
   302    386   set patterns(.hhc,1) {<!--This document contains Table of Contents information\
   303    387   for the HtmlHelp compiler\.--><UL>}
   304    388   
   305    389   set patterns(.hhp,1) {Default topic=~System\.Data\.SQLite\.html}

Changes to Doc/vtab.tcl.

    46     46         [regexp -- {<h\d(?: |>)} [string range $line 0 3]]} then {
    47     47       return ""
    48     48     }
    49     49   
    50     50     set result $line
    51     51   
    52     52     foreach remove [list \
    53         -      {<a name=".*?">} {<a href=".*?">} {</a>} {<b>} {</b>} \
    54         -      {<dd>} {</dd>} {<dl>} {</dl>} {<dt>} {</dt>} {<li>} \
    55         -      {</li>} {<ol>} {</ol>} {<p>} {</p>} {<ul>} {</ul>}] {
           53  +      {<a name=".*?">} {<a href=".*?">} {</a>} {<p>} {</p>}] {
    56     54       regsub -all -- $remove $result "" result
    57     55   
    58     56       if {[string length [string trim $result]] == 0} then {
    59     57         return ""
    60     58       }
    61     59     }
    62     60   
    63         -  regsub -all -- {<br>} $result \n[escapeSubSpec $prefix] result
           61  +  foreach escape [list \
           62  +      {<b>} {</b>} {<br>} {<dd>} {</dd>} {<dl>} {</dl>} {<dt>} \
           63  +      {</dt>} {<li>} {</li>} {<ol>} {</ol>} {<tt>} {</tt>} \
           64  +      {<ul>} {</ul>}] {
           65  +    regsub -all -- ($escape) $result {<![CDATA[\1]]>} result
           66  +  }
           67  +
    64     68     regsub -all -- {&ne;} $result {\&#8800;} result
    65     69     regsub -all -- {&#91(?:;)?} $result {[} result
    66     70     regsub -all -- {&#93(?:;)?} $result {]} result
    67     71     regsub -all -- {<( |\"|\d|=)} $result {\&lt;\1} result
    68     72     regsub -all -- {( |\"|\d|=)>} $result {\1\&gt;} result
    69     73     regsub -all -- {<blockquote><pre>} $result <para><code> result
    70     74     regsub -all -- {</pre></blockquote>} $result </code></para> result
................................................................................
    74     78     return $result
    75     79   }
    76     80   
    77     81   proc extractMethod { name lines pattern prefix indexVarName methodsVarName } {
    78     82     upvar 1 $indexVarName index
    79     83     upvar 1 $methodsVarName methods
    80     84   
    81         -  set paragraph 0
           85  +  array set levels {p 0}
    82     86     set length [llength $lines]
    83     87   
    84     88     while {$index < $length} {
    85     89       set line [lindex $lines $index]
    86     90   
    87     91       if {[regexp -- $pattern $line]} then {
    88     92         break; # stop on this line for outer loop.
    89     93       } else {
    90     94         set trimLine [string trim $line]; set data ""
    91     95   
    92         -      if {$paragraph > 0 && [string length $trimLine] == 0} then {
           96  +      if {$levels(p) > 0 && [string length $trimLine] == 0} then {
    93     97           # blank line, close paragraph.
    94     98           if {[info exists methods($name)]} then {
    95     99             # non-first line, leading line separator.
    96    100             append data \n $prefix </para>
    97    101           } else {
    98    102             # first line, no leading line separator.
    99    103             append data $prefix </para>
   100    104           }
   101    105   
   102         -        incr paragraph -1
          106  +        incr levels(p) -1
   103    107         } elseif {[string range $trimLine 0 2] eq "<p>"} then {
   104         -        # open paragraph ... maybe one line?
          108  +        # open tag ... maybe one line?
   105    109           if {[string range $trimLine end-3 end] eq "</p>"} then {
   106    110             set newLine [processLine $line $prefix]
   107    111   
   108    112             if {[string length $newLine] > 0} then {
   109         -            # one line paragraph, wrap.
          113  +            # one line tag, wrap.
   110    114               if {[info exists methods($name)]} then {
   111    115                 # non-first line, leading line separator.
   112    116                 append data \n $prefix <para>
   113    117               } else {
   114    118                 # first line, no leading line separator.
   115    119                 append data $prefix <para>
   116    120               }
................................................................................
   129    133   
   130    134             set newLine [processLine $line $prefix]
   131    135   
   132    136             if {[string length $newLine] > 0} then {
   133    137               append data \n $prefix $newLine
   134    138             }
   135    139   
   136         -          incr paragraph
          140  +          incr levels(p)
   137    141           }
   138    142         } else {
   139    143           set newLine [processLine $line $prefix]
   140    144   
   141    145           if {[string length $newLine] > 0} then {
   142    146             if {[info exists methods($name)]} then {
   143    147               # non-first line, leading line separator.

Changes to System.Data.SQLite/ISQLiteNativeModule.cs.

   105    105           /// If a column datatype contains the special keyword "HIDDEN"
   106    106           /// (in any combination of upper and lower case letters) then that keyword
   107    107           /// it is omitted from the column datatype name and the column is marked 
   108    108           /// as a hidden column internally. 
   109    109           /// A hidden column differs from a normal column in three respects:
   110    110           /// </para>
   111    111           /// <para>
   112         -        ///  Hidden columns are not listed in the dataset returned by 
          112  +        /// <![CDATA[<ul>]]>
          113  +        /// <![CDATA[<li>]]> Hidden columns are not listed in the dataset returned by 
   113    114           ///      "PRAGMA table_info",
   114         -        ///  Hidden columns are not included in the expansion of a "*"
          115  +        /// <![CDATA[<li>]]> Hidden columns are not included in the expansion of a "*"
   115    116           ///      expression in the result set of a SELECT, and
   116         -        ///  Hidden columns are not included in the implicit column-list 
          117  +        /// <![CDATA[<li>]]> Hidden columns are not included in the implicit column-list 
   117    118           ///      used by an INSERT statement that lacks an explicit column-list. 
          119  +        /// <![CDATA[</ul>]]>
   118    120           /// </para>
   119    121           /// <para>
   120    122           /// For example, if the following SQL is passed to sqlite3_declare_vtab():
   121    123           /// </para>
   122    124           /// <para><code>
   123    125           ///    CREATE TABLE x(a HIDDEN VARCHAR(12), b INTEGER, c INTEGER Hidden);
   124    126           /// </code></para>
................................................................................
   349    351           ///       unsigned char omit;      /* Do not code a test for this constraint */
   350    352           ///     } *const aConstraintUsage;
   351    353           ///     int idxNum;                /* Number used to identify the index */
   352    354           ///     char *idxStr;              /* String, possibly obtained from sqlite3_malloc */
   353    355           ///     int needToFreeIdxStr;      /* Free idxStr using sqlite3_free() if true */
   354    356           ///     int orderByConsumed;       /* True if output is already ordered */
   355    357           ///     double estimatedCost;      /* Estimated cost of using this index */
   356         -        ///     /* Fields below are only available in SQLite 3.8.2 and later */
          358  +        ///     <![CDATA[<b>]]>/* Fields below are only available in SQLite 3.8.2 and later */<![CDATA[</b>]]>
   357    359           ///     sqlite3_int64 estimatedRows;    /* Estimated number of rows returned */
   358         -        ///     /* Fields below are only available in SQLite 3.9.0 and later */
          360  +        ///     <![CDATA[<b>]]>/* Fields below are only available in SQLite 3.9.0 and later */<![CDATA[</b>]]>
   359    361           ///     int idxFlags;              /* Mask of SQLITE_INDEX_SCAN_* flags */
   360    362           ///   };
   361    363           /// </code></para>
   362    364           /// <para>
   363    365           /// Please note the warnings on the "estimatedRows" and "idxFlags" field.
   364    366           /// These fields were added with SQLite versions 3.8.2 and 3.9.0, respectively. 
   365    367           /// Any extension that reads or writes these fields must first check that the 
................................................................................
   870    872           /// The SQLite core invokes this method in order to find the value for 
   871    873           /// the N-th column of the current row. N is zero-based so the first column 
   872    874           /// is numbered 0. 
   873    875           /// The xColumn method may return its result back to SQLite using one of the
   874    876           /// following interface:
   875    877           /// </para>
   876    878           /// <para>
   877         -        ///  sqlite3_result_blob()
   878         -        ///  sqlite3_result_double()
   879         -        ///  sqlite3_result_int()
   880         -        ///  sqlite3_result_int64()
   881         -        ///  sqlite3_result_null()
   882         -        ///  sqlite3_result_text()
   883         -        ///  sqlite3_result_text16()
   884         -        ///  sqlite3_result_text16le()
   885         -        ///  sqlite3_result_text16be()
   886         -        ///  sqlite3_result_zeroblob()
          879  +        /// <![CDATA[<ul>]]>
          880  +        /// <![CDATA[<li>]]> sqlite3_result_blob()
          881  +        /// <![CDATA[<li>]]> sqlite3_result_double()
          882  +        /// <![CDATA[<li>]]> sqlite3_result_int()
          883  +        /// <![CDATA[<li>]]> sqlite3_result_int64()
          884  +        /// <![CDATA[<li>]]> sqlite3_result_null()
          885  +        /// <![CDATA[<li>]]> sqlite3_result_text()
          886  +        /// <![CDATA[<li>]]> sqlite3_result_text16()
          887  +        /// <![CDATA[<li>]]> sqlite3_result_text16le()
          888  +        /// <![CDATA[<li>]]> sqlite3_result_text16be()
          889  +        /// <![CDATA[<li>]]> sqlite3_result_zeroblob()
          890  +        /// <![CDATA[</ul>]]>
   887    891           /// </para>
   888    892           /// <para>
   889    893           /// If the xColumn method implementation calls none of the functions above,
   890    894           /// then the value of the column defaults to an SQL NULL.
   891    895           /// </para>
   892    896           /// <para>
   893    897           /// To raise an error, the xColumn method should use one of the result_text() 
................................................................................
   971    975           /// The value of argc will be 1 for a pure delete operation or N+2 for an insert
   972    976           /// or replace or update where N is the number of columns in the table.  
   973    977           /// In the previous sentence, N includes any hidden columns.
   974    978           /// </para>
   975    979           /// <para>
   976    980           /// Every argv entry will have a non-NULL value in C but may contain the 
   977    981           /// SQL value NULL.  In other words, it is always true that
   978         -        /// <tt>argv[i]!=0</tt> for i between 0 and <tt>argc-1</tt>.
          982  +        /// <![CDATA[<tt>]]>argv[i]!=0<![CDATA[</tt>]]> for <![CDATA[<b>]]>i<![CDATA[</b>]]> between 0 and <![CDATA[<tt>]]>argc-1<![CDATA[</tt>]]>.
   979    983           /// However, it might be the case that
   980         -        /// <tt>sqlite3_value_type(argv[i])==SQLITE_NULL</tt>.
          984  +        /// <![CDATA[<tt>]]>sqlite3_value_type(argv[i])==SQLITE_NULL<![CDATA[</tt>]]>.
   981    985           /// </para>
   982    986           /// <para>
   983    987           /// The argv[0] parameter is the rowid of a row in the virtual table 
   984    988           /// to be deleted. If argv[0] is an SQL NULL, then no deletion occurs.
   985    989           /// </para>
   986    990           /// <para>
   987    991           /// The argv[1] parameter is the rowid of a new row to be inserted 
................................................................................
   998   1002           /// this will become the value returned by the sqlite3_last_insert_rowid()
   999   1003           /// function. Setting this value in all the other cases is a harmless no-op;
  1000   1004           /// the SQLite engine ignores the *pRowid return value if argc==1 or 
  1001   1005           /// argv[1] is not an SQL NULL.
  1002   1006           /// </para>
  1003   1007           /// <para>
  1004   1008           /// Each call to xUpdate will fall into one of cases shown below.
  1005         -        /// Not that references to argv[i] mean the SQL value
         1009  +        /// Not that references to <![CDATA[<b>]]>argv[i]<![CDATA[</b>]]> mean the SQL value
  1006   1010           /// held within the argv[i] object, not the argv[i]
  1007   1011           /// object itself.
  1008   1012           /// </para>
  1009   1013           /// <para><code>
  1010         -        /// argc = 1
  1011         -        /// The single row with rowid equal to argv[0] is deleted. No insert occurs.
  1012         -        /// argc &gt; 1 
  1013         -        ///  argv[0] = NULL
  1014         -        /// A new row is inserted with a rowid argv[1] and column values in
         1014  +        /// <![CDATA[<dl>]]>
         1015  +        /// <![CDATA[<dt>]]><![CDATA[<b>]]>argc = 1<![CDATA[</b>]]>
         1016  +        /// <![CDATA[<dd>]]>The single row with rowid equal to argv[0] is deleted. No insert occurs.
         1017  +        /// <![CDATA[<dt>]]><![CDATA[<b>]]>argc &gt; 1 <![CDATA[<br>]]> argv[0] = NULL<![CDATA[</b>]]>
         1018  +        /// <![CDATA[<dd>]]>A new row is inserted with a rowid argv[1] and column values in
  1015   1019           ///        argv[2] and following.  If argv[1] is an SQL NULL,
  1016   1020           ///        the a new unique rowid is generated automatically.
  1017         -        /// argc &gt; 1 
  1018         -        ///  argv[0] &#8800; NULL 
  1019         -        ///  argv[0] = argv[1]
  1020         -        /// The row with rowid argv[0] is updated with new values 
         1021  +        /// <![CDATA[<dt>]]><![CDATA[<b>]]>argc &gt; 1 <![CDATA[<br>]]> argv[0] &#8800; NULL <![CDATA[<br>]]> argv[0] = argv[1]<![CDATA[</b>]]>
         1022  +        /// <![CDATA[<dd>]]>The row with rowid argv[0] is updated with new values 
  1021   1023           ///        in argv[2] and following parameters.
  1022         -        /// argc &gt; 1 
  1023         -        ///  argv[0] &#8800; NULL 
  1024         -        ///  argv[0] &#8800; argv[1]
  1025         -        ///  The row with rowid argv[0] is updated with rowid argv[1] 
         1024  +        /// <![CDATA[<dt>]]><![CDATA[<b>]]>argc &gt; 1 <![CDATA[<br>]]> argv[0] &#8800; NULL <![CDATA[<br>]]> argv[0] &#8800; argv[1]<![CDATA[</b>]]>
         1025  +        /// <![CDATA[<dd>]]> The row with rowid argv[0] is updated with rowid argv[1] 
  1026   1026           /// and new values in argv[2] and following parameters. This will occur 
  1027   1027           /// when an SQL statement updates a rowid, as in the statement:
  1028   1028           /// <para><code>
  1029   1029           ///    UPDATE table SET rowid=rowid+1 WHERE ...; 
  1030   1030           /// </code></para>
         1031  +        /// <![CDATA[</dl>]]>
  1031   1032           /// </code></para>
  1032   1033           /// <para>
  1033   1034           /// The xUpdate method must return SQLITE_OK if and only if it is
  1034   1035           /// successful.  If a failure occurs, the xUpdate must return an appropriate
  1035   1036           /// error code.  On a failure, the pVTab->zErrMsg element may optionally
  1036   1037           /// be replaced with error message text stored in memory allocated from SQLite 
  1037   1038           /// using functions such as sqlite3_mprintf() or sqlite3_malloc().