Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 25 additions & 6 deletions WIP.Indexer.md
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,10 @@ which would write the snapshots of another build.
- **Snapshots are committed only for the documented packages, to start with**: 14 files, 3.2 MB
(about 350 KB compressed). The contributed packages and the extra CEF builds are indexed into
the store and left out of the repository. A package joins when its section does; `sync`
copies a snapshot for a documented package it indexed in that run.
copies a snapshot for a documented package it indexed in that run, and gives a documented
package with none the store's `api.json` when that is of its `indexed_from` version
(`adoptSnapshots`): a package is usually synced before its section exists, and a later
sync finds its store current and indexes nothing.
- **They are taken from the build the reference was last indexed against, BETA 997**
(`beta-x-0997`), not from a newer one, so that the pages and the baseline agree and
`analyze` of a newer build shows the real distance.
Expand Down Expand Up @@ -220,6 +223,12 @@ the old tool's at BETA 997, and it takes half a second with no cache.
folder of the type returning it is limited to folders that already keep a type, because
without that limit it moved Printer under Printers, Dictionary under JsonConverter and
eight others that the sections keep at their roots.
- **A new section borrows its model pages from its group.** Its pages have no sibling of
their kind to follow, so the plan of the first package drafted into a new section
(tbRegExp) gave every task `model: null`, and the agents would have invented a page
layout. A page of a kind its section lacks now takes a model from the group's largest
section that has one, of the same shape: a folder's `index.md` for a class that gets a
folder, never a one-page class.
- **A permalink is computed only where the rule holds for every existing page** of the
section (`followsFolders`). On staging at BETA 997 that is every section but VBA's, whose
pages live under `/tB/Modules/`. A section that breaks the rule once gets no computed
Expand All @@ -237,10 +246,24 @@ the old tool's at BETA 997, and it takes half a second with no cache.
- **The check step compiles before a person reads.** One agent per package runs
`check_examples --only` on the section, at a port of its own (9700 up, clear of the
harness's default 9480), and fixes the pages. A contributed package without a
`contributed-<Package>` template cannot be compiled, and the agent says so.
`contributed-<Package>` template cannot be compiled, and the agent says so. **It also runs
the doubts the other agents return**: the workflow passes their results into its prompt,
and it settles each one a run can on a scratch page (`zz-probe.md`, every line expecting
`' ?`, so the report prints what each line printed) and, for a package that replaces
another object, on that object too (`cscript` for VBScript, `vb6run.mjs` for VB6). The
Draft agents only list doubts: they run concurrently, so none of them compiles. The Lists
agent reads a new package's README through read-only `gh` and lists the README's claims
as doubts as well.
- **The agents are Sonnet**, as the content agents of the contributed packages were; the
drafts are read against the sources before they are committed, which no model choice
replaces.
- **The first run, tbRegExp 1.0.5.0 (28 pages, 5 batches), took 7 agents, 7 minutes and
0.96 M subagent tokens**, and its 30 samples compiled and ran on the first Check. The
review still found what no compile finds: the drafts state only what the code says, so
where the package differs from the object it replaces (VBScript's **RegExp**, run under
`cscript`) nothing said so, and claims read from the code but never run (`$0`, a lone `$`)
needed a probe page. Running the doubts is now the Check agent's (above); the review
still reads the pages against the sources.
- **It is not in the published docs.** `draft` is (Tools-Build), because its plans serve a
person writing pages by hand; the workflow is described here and in `WIP.md`, because
nothing under `docs/Documentation/` may require Claude.
Expand All @@ -260,10 +283,6 @@ the old tool's at BETA 997, and it takes half a second with no cache.
`Assert` functions on `Exact.md`) shows as undocumented, and a name shared by several types
shows as documented once any page carries it. Update mode does not audit, but finds a
changed symbol's `doc_page` the same way.
- **Adopting a package whose store is already current writes no snapshot.** By reading `runSync`:
the snapshots are copied for the packages the run indexed, and a package that is up to date
is not among them. Documenting a package that `sync` has already read needs its store folder
removed first, or a build newer than the store's.
- **`indexer/TWINSERV-protocol.md` stays where it is, as reference beside the code.** It
describes a third party's HTTP API, which is neither a reason nor a decision, and folding 239
lines of it into this note would bury both. Its one reader is `lib/twinserv-client.mjs`, which
Expand Down
2 changes: 1 addition & 1 deletion WIP.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ sibling. History goes nowhere: git keeps it.

Reference documentation is **complete** for all thirteen packages: VBA, VBRUN, VB, WebView2, Assert, CustomControls, CEF, WinEventLogLib, WinNamedPipesLib, WinServicesLib, tbIDE, WinNativeCommonCtls and AppGlobalClassObject. It is adapted from primary sources: Microsoft VBA-Docs (CC-BY-4.0) for the runtime library, `.twin` source for the twinBASIC-specific packages. The CEF and WebView2 packages also carry a tutorial set.

Eleven **contributed** packages from TWINSERV have sections under `docs/Reference/Contributed/`: FileProps, Fmt, OLEGuids, WinReg, TwinTimerPackage, TBMANLIB_ListBoxHScroll, TBMANLIB_RES and VBA_JSON complete; AutoCompleteLib, BigNumberLib and VBComDlg their main class only. Fmt documents its test code (`HelloWorldClass`, `HelloWorldModule`, `Pootle`) in one paragraph of its landing page, which `exclude_from_docs` names; OLEGuids documents each interface's methods on the interface's page. Each published one has a chapter in the book's Packages part. **BigNumberLib and WinReg are not published**: their packages do not compile on BETA 1005, so their pages are kept but excluded in `_config.yml`'s `exclude:` (owner, 2026-10-11), whose comment says how to bring one back.
Fourteen **contributed** packages from TWINSERV have sections under `docs/Reference/Contributed/`: FileProps, Fmt, OLEGuids, WinReg, TwinTimerPackage, TBMANLIB_Dialog, TBMANLIB_ListBoxHScroll, TBMANLIB_RES, tbProjPacker, tbRegExp and VBA_JSON complete; AutoCompleteLib, BigNumberLib and VBComDlg their main class only. Fmt documents its test code (`HelloWorldClass`, `HelloWorldModule`, `Pootle`) in one paragraph of its landing page, which `exclude_from_docs` names. tbRegExp's `exclude_from_docs` names its private engine module, `StaticRegex`, and tbProjPacker's its helper modules, `modPackUnpack` and `modWin32`: the indexer counts a Public Enum as public even inside a Private Module, because a built-in package's are reached through its library symbol written with an asterisk (`*WinNativeCommonCtls`, as `ImlDrawConstants` says). By its bare name no such enum is reachable, in a built-in or a contributed package (TB5079 on BETA 1005). OLEGuids documents each interface's methods on the interface's page. What TBMANLIB_Dialog's pages say its dialogs do comes from `test/package-probes/TBMANLIB_Dialog/`, which operates them in a built exe on a private desktop; run it again when the package's version changes. tbRegExp is the first section drafted by the doc-draft workflow ([WIP.Indexer.md](WIP.Indexer.md#draft-and-the-doc-draft-workflow)), then reviewed against the sources, the package's README and VBScript's own **RegExp** under `cscript`. Each published one has a chapter in the book's Packages part. **BigNumberLib and WinReg are not published**: their packages do not compile on BETA 1005, so their pages are kept but excluded in `_config.yml`'s `exclude:` (owner, 2026-10-11), whose comment says how to bring one back.

The rest of this file is the maintenance guide for updating existing pages or adding new ones: package surface notes, page conventions, and the integrity check.

Expand Down
2 changes: 1 addition & 1 deletion builder/page-baseline.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"src": "docs",
"pages": 1066,
"pages": 1131,
"staticFiles": 794
}
2 changes: 1 addition & 1 deletion docs/Documentation/Tools-Build.md
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,7 @@ A name that matches no package is reported, the other packages are done, and the

`sync` judges a package by what the store holds, never by the manifest. A package is read again when the store lacks its sources or its `api.json`, or holds an `api.json` in an older format or from another build. A package whose `api.json` another version of the scanner wrote is indexed again from the sources already in the store, with no download. A clone has no store, so its first `sync` reads every package.

**Which packages are documented.** A section of the reference documents a package when its folder under `docs/Reference/Default/`, `Built-In/` or `Contributed/` has an `index.md`, and the landing page's `package_name` lists the package (without that key, the folder's name is the package's). The page's `package_name`, `indexed_from`, `exclude_from_docs` and `exclude_kinds` are described under [Frontmatter and permalinks](Authoring#frontmatter-and-permalinks); the indexer reads them and the build does not put them into any page. `sync` copies a package's `api.json` to `indexer/snapshots/` only if the reference documents the package and that run indexed it.
**Which packages are documented.** A section of the reference documents a package when its folder under `docs/Reference/Default/`, `Built-In/` or `Contributed/` has an `index.md`, and the landing page's `package_name` lists the package (without that key, the folder's name is the package's). The page's `package_name`, `indexed_from`, `exclude_from_docs` and `exclude_kinds` are described under [Frontmatter and permalinks](Authoring#frontmatter-and-permalinks); the indexer reads them and the build does not put them into any page. `sync` copies a package's `api.json` to `indexer/snapshots/` only if the reference documents the package and that run indexed it, or the package has no snapshot yet and the store's `api.json` is of the version its section's `indexed_from` names. The second case is a new section: its package was synced before the section existed, so the next `sync` finds the store up to date and indexes nothing.

**What `analyze` reports.** By default it covers the documented packages and says how many others it left out. `--package` and `--packages` name any package. A package that no section documents has no pages to compare with, so every public symbol of it is listed as one to create, and so it is for every package under `--all`. A symbol is a type, or a name that a type declares: the Get, Let and Set of a property, and the overloads of a name, are one symbol, as the reference has one page for each. Only Public and Protected members of public types count, less what `exclude_from_docs` and `exclude_kinds` name. Each package is analyzed in one of two modes.

Expand Down
3 changes: 3 additions & 0 deletions docs/Reference/Contributed.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,11 @@ Each package is versioned apart from twinBASIC, and its section says which versi
- [**FileProps**](FileProps/) -- the Windows shell properties of a file, read and written
- [**Fmt**](Fmt/) -- **StringFormat**, a string built from a format string and values, in the style of C#'s **String.Format**
- [**OLEGuids**](OLEGuids/) -- OLE and COM interfaces and structures in twinBASIC source, in place of `OLEGuids.tlb`
- [**TBMANLIB_Dialog**](TBMANLIB_Dialog/) -- the **cDialog** class: the Open, Save and folder dialogs, with file filters and path helpers
- [**TBMANLIB_ListBoxHScroll**](TBMANLIB_ListBoxHScroll/) -- a horizontal scroll bar for a **ListBox**
- [**TBMANLIB_RES**](TBMANLIB_RES/) -- resources embedded in an executable, as bytes, strings, hex, Base64 or pictures
- [**tbProjPacker**](tbProjPacker/) -- a `.twinproj` or `.twinpack` file unpacked into a folder of source files, and packed again
- [**tbRegExp**](tbRegExp/) -- regular expressions, in place of VBScript's **RegExp** object
- [**TwinTimerPackage**](TwinTimerPackage/) -- a Win32 timer class that reports the elapsed time
- [**VBA_JSON**](VBA_JSON/) -- JSON parsing and serialization, with UTC and ISO 8601 date conversion
- [**VBComDlg**](VBComDlg/) -- the **CommonDialog** class, for the Windows common dialogs
55 changes: 55 additions & 0 deletions docs/Reference/Contributed/TBMANLIB_Dialog/cDialog/AddFilter.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
---
title: AddFilter
parent: cDialog
permalink: /tB/Packages/Contributed/TBMANLIB_Dialog/cDialog/AddFilter
has_toc: false
---

# AddFilter
{: .no_toc }

Appends a description and a pattern to the [**Filter**](Filter) of the Open and Save As dialogs.

Syntax: *object*.**AddFilter** ( *strDescription*, *strExtension* )

*object*
: *required* An object expression that evaluates to a **cDialog**.

*strDescription*
: *required* A **String**, the text that the dialog shows for the pair, such as `Text Files (*.txt)`.

*strExtension*
: *required* A **String**, the pattern that selects the files, such as `*.txt`. Several patterns are separated by semicolons: `*.jpg;*.jpeg`.

## Remarks

**AddFilter** appends `description|pattern` to the text of **Filter**, with a `|` in front of it when **Filter** is not empty. The first pair added is the one that the dialog selects when it opens.

A filter with one pair gives a file-type list with one item. Despite its name, *strExtension* is a pattern, and the class uses the text as it is: it adds no `*.` in front. Write the pattern in the form that the Windows documentation of `OPENFILENAME` gives, such as `*.txt`.

The class does not check the arguments. A `|` in either one adds an element, so the later elements are no longer paired correctly.

## Example

```tb check_build check_run
Dim dlg As New cDialog
dlg.AddFilter "Text Files (*.txt)", "*.txt"
dlg.AddFilter "Pictures", "*.png;*.jpg"
Debug.Print dlg.Filter ' Text Files (*.txt)|*.txt|Pictures|*.png;*.jpg
```

A `|` in a description makes three elements out of two:

```tb check_build check_run
Dim dlg As New cDialog
dlg.AddFilter "Text|Notes", "*.txt"
Debug.Print UBound(Split(dlg.Filter, "|")) + 1 ' 3
```

## See Also

- [Filter](Filter) property -- the whole list as one string
- [ClearFilter](ClearFilter) method -- empties the filter
- [SetCommonFilters](SetCommonFilters) method -- replaces the filter with a ready-made list
- [ShowOpen](ShowOpen) method -- shows the Open dialog
- [cDialog](.) class -- overview
38 changes: 38 additions & 0 deletions docs/Reference/Contributed/TBMANLIB_Dialog/cDialog/ClearFilter.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
---
title: ClearFilter
parent: cDialog
permalink: /tB/Packages/Contributed/TBMANLIB_Dialog/cDialog/ClearFilter
has_toc: false
---

# ClearFilter
{: .no_toc }

Empties the [**Filter**](Filter) of the Open and Save As dialogs.

Syntax: *object*.**ClearFilter**

*object*
: *required* An object expression that evaluates to a **cDialog**.

## Remarks

**ClearFilter** sets **Filter** to an empty string, as `dlg.Filter = ""` does. The four `Set...Filters` methods call it first, so each of them replaces the filter.

## Example

```tb check_build check_run
Dim dlg As New cDialog
dlg.AddFilter "Text Files (*.txt)", "*.txt"
Debug.Print Len(dlg.Filter) > 0 ' True

dlg.ClearFilter
Debug.Print Len(dlg.Filter) ' 0
```

## See Also

- [Filter](Filter) property -- the whole list as one string
- [AddFilter](AddFilter) method -- appends a pair
- [Reset](Reset) method -- clears the filter along with every other property
- [cDialog](.) class -- overview
59 changes: 59 additions & 0 deletions docs/Reference/Contributed/TBMANLIB_Dialog/cDialog/CreatePrompt.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
---
title: CreatePrompt
parent: cDialog
permalink: /tB/Packages/Contributed/TBMANLIB_Dialog/cDialog/CreatePrompt
has_toc: false
---

# CreatePrompt
{: .no_toc }

Returns or sets whether the Open dialog asks permission before it accepts the name of a file that does not exist.

Syntax: *object*.**CreatePrompt** [ = *boolean* ]

*object*
: *required* An object expression that evaluates to a **cDialog**.

*boolean*
: A **Boolean**. **True** sets `OFN_CREATEPROMPT`. The default is **False**.

## Remarks

Only [**ShowOpen**](ShowOpen) uses the property. [**ShowSave**](ShowSave) never sets `OFN_CREATEPROMPT`, and [**ShowBrowseForFolder**](ShowBrowseForFolder) ignores the property.

When the user types the name of a file that does not exist, such as `nosuch.txt`, the box *This file doesn't exist. Create the file?* appears, with the buttons *Yes* and *No*. *Yes* closes the dialog and returns the path. *No* leaves the dialog open. This happens whether [**FileMustExist**](FileMustExist) is **True** or **False**, so the question takes the place of the *File not found* box that **FileMustExist** shows.

The file is not created: neither the dialog nor the class creates it, and the program has to do so.

## Example

```tb check_build check_run
Dim dlg As New cDialog
Debug.Print dlg.CreatePrompt ' False

dlg.CreatePrompt = True
Debug.Print dlg.CreatePrompt ' True
```

This example lets the user name a new file in the Open dialog and creates it when the user agrees.

```tb check_build
Dim dlg As New cDialog
Dim path As String

dlg.CreatePrompt = True
path = dlg.ShowOpen()
If Len(path) > 0 Then
If Len(Dir$(path)) = 0 Then
Open path For Output As #1
Close #1
End If
End If
```

## See Also

- [FileMustExist](FileMustExist) property -- lets only names of existing files through
- [ShowOpen](ShowOpen) method -- shows the Open dialog
- [cDialog](.) class -- overview
61 changes: 61 additions & 0 deletions docs/Reference/Contributed/TBMANLIB_Dialog/cDialog/DefaultExt.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
---
title: DefaultExt
parent: cDialog
permalink: /tB/Packages/Contributed/TBMANLIB_Dialog/cDialog/DefaultExt
has_toc: false
---

# DefaultExt
{: .no_toc }

Returns or sets the extension that Windows adds to a file name that the user types without one.

Syntax: *object*.**DefaultExt** [ = *string* ]

*object*
: *required* An object expression that evaluates to a **cDialog**.

*string*
: A **String**, an extension written without a period, such as `txt`. The default is an empty string.

## Remarks

[**ShowOpen**](ShowOpen) and [**ShowSave**](ShowSave) pass the text as the `lpstrDefExt` member of `OPENFILENAME`. [**ShowBrowseForFolder**](ShowBrowseForFolder) ignores it.

Windows appends the extension to a name that the user types without one. Write the extension without a period. The class does not change the text, and does not take an extension from the selected pair of [**Filter**](Filter).

In the Save As dialog, with the user typing `out`:

| **DefaultExt** | **ShowSave** returns |
|---|---|
| `txt` | `<dir>\out.txt` |
| `.txt` | `<dir>\out..txt` |
| An empty string | `<dir>\out` |

`<dir>` is the folder of the dialog. A period in **DefaultExt** is kept, and gives a name with two periods. An empty **DefaultExt** appends nothing.

## Example

```tb check_build check_run
Dim dlg As New cDialog
Debug.Print "[" & dlg.DefaultExt & "]" ' []

dlg.DefaultExt = "txt"
Debug.Print dlg.DefaultExt ' txt
```

This example shows the Save As dialog and adds `.txt` to a name typed without an extension.

```tb check_build
Dim dlg As New cDialog
dlg.DefaultExt = "txt"
dlg.SetCommonFilters
Debug.Print dlg.ShowSave()
```

## See Also

- [Filter](Filter) property -- the file-type list, which does not set the extension
- [ShowSave](ShowSave) method -- shows the Save As dialog
- [ShowOpen](ShowOpen) method -- shows the Open dialog
- [cDialog](.) class -- overview
Loading
Loading