Tinderbox v.11.8.0 Manual - Table of Contents



A Tinderbox Reference File

Update Status: aTbRef source TBX last updated: Thu, 23 Jul 2026 09:49:18 +0100 :: XML RSS 2.0 Feed RSS 2.0 Feed :: XML Atom 1.0 Feed Atom 1.0 Feed :: JSON Feed JSON 1.0 Feed.

"aTbRef" (A Tinderbox Reference) is a reference file aboutTinderbox's objects and functions, from which this website is generated since 2004. It has been written and updated by Mark Anderson, a long-time user of Tinderbox (see more) and it is offered to the Tinderbox community as a free public service. The site's content is under a Creative Commons BY-NC-SA licence (see licence details); voluntary donations to help defray costs (software tools, hosting, etc.) are welcomed—see the 'donate' link at the bottom of all pages.

This is written as a hypertext—you are expected to follow links! With such a multi-facetted toolbox of features and with a user base of very diverse experience, it is impossible to write a self-contained long-from article for every situation. Instead the articles link to other articles holding possibly relevant information. Otherwise use any page's quicklinks (see below) search page or sitemap, both of which are linked at top and bottom of every page (as 'aTbRef Site Map' and 'aTbRef Search').

Current Version: v11.8.0b808 (7 Jul 2026)

Version Baseline: this section of the aTbRef website is baselined on v11.0.0b733 (released 12 September 2025) and includes changes up to and including v11.8.0b808 (7 Jul 2026). To look at changes to the app over time, see other baselines, based on older versions. Also see Eastgate's version release pages and release dates of versions prior to the current baseline.

Change Log: see this section for significant per-release changes in and since the baseline release (above) for this edition of aTbRef. In-text references to per-release changes prior to the baseline have been removed as they are now baseline features; some may remain if still pertinent to understanding the app's functioning. If a page is listed as created a version not in the Change Log, it is simply because it has been exported using a more recent (non-public) beta build.

Search and Index: this website includes a full-text search page (using fuzzy search) and a sitemap index. Links to both are in the Quicklinks bar at top and bottom of every page—see also Understanding the layout of aTbRef webpages. Tip: do not assume Tinderbox uses the same terminology you may be used to using in [some other app]: over-familiarity is the enemy of effective search.

Quicklinks: a set of 'quicklinks' to key listings within aTbRef are at the top and bottom of every page. It includes a search page (full text, using fuzzy search) and a sitemap which is an index of the source outline from the aTbRef source TBX document.

Contents:

  • Understanding the layout of aTbRef webpages
  • Basic Configuration & Concepts
  • Coding in Tinderbox
  • User Interface Basics
  • Using Tinderbox
  • Under The Hood
  • Resources
  • REMARKS AND CAVEATS

    Is there an index for aTbRef? An auto-index would be too noisy and a human-created one would be too much effort, especially as aTbRef is updated constantly. But the aTbRef Site Map page, used with your web browser's in page Find (⌘+F) is a pretty good substitute.

    Can't find a subject? Please visit the Tinderbox User-to-User forums and ask there. If doing so it helps to know how you phrase your question and where you thought you might find the answer. Sometimes the issue is simply one of terminology/process but sometimes we find something that should and is added to aTbRef (note: 'how-to' for specific tasks is not and will not be in aTbRef: it is a reference not a tutorial). This file is supposed to go along with the existing manual & release notes (available via the app's Help menu) as well as the Tinderbox forum.

    This is not a how-to/tutorial. Although aTbRef contains some examples of use, it is not, by design, a 'how-to' resource. 'how-to' questions are best addressed by the Tinderbox forum. Its main aim is to serve as an "on the go" (online) as well as a personal (TBX file) reference to Tinderbox use.

    Use and re-use. This file is shared "as is", the author will not be held responsible for its content; it may be used/republished under a Creative Commons Licence.

    Install, Uninstall, Support and Registration

    To what does 'TB' refer?

    The word Tinderbox when referring to the application is, by common usage, often shortened to 'TB' in discussion in places like the user-to-user forum. This use of 'TB' is not an acronym. Rather, it is just a simple shorthand for those who find they need to type the word Tinderbox a lot!

    It is also worth noting that the correct spelling of the application name is 'Tinderbox' and not 'TinderBox'. The latter is sometimes assumed from seeing the TB 'short' name.

    'TBX', the file extension used by Tinderbox files, is also used as a shorthand for a Tinderbox document(s).

    Technical Requirements

    Tinderbox runs on all modern Macintosh computers.

    From v11.5.0, Tinderbox requires macOS 12 (Monterey) or later.

    Note that not all features run old the older supported OS versions, especially those using AI and Machine Learning techniques. There is a list of such features.

    The pre-v6 app design was designed for the PowerPC, so used Rosetta to run on Intel CPUs. Rosetta was included in Mac OS 10.4 (Tiger) and dropped after Mac OS Lion (10.6). Thefore using an Mac OS 10.7+, precluded further use of Tinderbox v1.x through v5.x

    Legacy

    These are older requirements (older requirements via the Internet Archive):

    • v9.5.0+, Tinderbox requires macOS 11 (Big Sur) or later.
    • v9.0.0 runs on macOS Big Sur (11.x), Catalina (10.15) and Mojave (10.14) and High Sierra (10.13).
    • v8.5.0 runs on Sierra (10.12), El Capitan (10.11) and Yosemite (10.10)
    • v6.x/7.x runs on Mavericks (10.9) or later.
    • MacOS 10.7 drops Rosetta support needed to run pre-v6 versions of Tinderbox.
    • v5.12.2 supported Lion (10.7).
    • v5.10.2 required Snow Leopard (10.6) or later.
    • v5.0.0 recommended Tiger (10.4), Leopard (20.5) or Snow Leopard (10.6)
    • v4.2.5 recommended Tiger (10.4) or Leopard (20.5).
    • v4.0.0 recommended Tiger (10.4).
    • v3.5.0 recommended Tiger (10.4). (Classic support dropped?)
    • v3.0.0 recommended Tiger (10.4+) or Classic 9.2.
    • v2.5.0 recommended Panther (10.3+) or Classic 9.2, but required Tiger (10.4) for some features.
    • v2.3.4 recommended Panther (10.3+) or Classic 9.2.
    • v2.0.0 XML file format of TBX files updated, older files autoupdated.
    • v1.2.2 recommended Jaguar (10.2.1+) or Classic 9.2.
    • v1.2.1 recommended Jaguar (10.2) and required Classic 9+.
    • v1.1.4 adds OS X support (or classic System 8.6+).
    • v1.1.1 recommended Classic System v8.6+. OS X not yet supported (c. June 2002).
    • v1.1.0 first version to support OS X, then Puma (10.1).
    • At launch, Classic System v8.5+ was recommended.

    Re-starting Tinderbox without reopening TBX documents

    Since the v6 redesign, Tinderbox only re-opens documents if the set to do so via the macOS System Settings. As at macOS 26.x, this is an option at OS System SettingsDesktop & Dock section ▸ Close windows when quitting an application.

    If needing to open Tinderbox without re-opening any documents open in the last app session, e.g. if a document gets corrupted or hangs, press the Shift key ( ⇧) whilst opening Tinderbox. This overrides the OS-wide option above.

    Legacy

    Pre-v6, Tinderbox had its own setting as to whether previously open documents were re-opened in a new session.

    Licence & Registration

    Tinderbox offers a number of method to buy and update Tinderbox.

    Normal licence

    One year from first registering, the right to use new major and minor versions Tinderbox ceases unless you purchase an upgrade licence. for those needing volume license see 'Multi-user (Group) licences' below.

    Upgrade licence

    These are for existing licensed Tinderbox that is out of its free update period of 1 year. This licence essentially re-enables access to new releases and full support. As Tinderbox is under continuous development, the main gain is access to fresh releases and the new features (and fixes) they bring.

    Not all users need all features so some users may care to wait longer between upgrades. Generally, upgrades are significantly cheaper than buying a new licence. Unlike many apps, a user can purchase an upgrade for any existing 'lapsed' licence and jump to using the current app. For those on a budget, or whose Tinderbox use has fallen off, it is simple way to return the app to full support.

    Thus, once initially licensed, Eastgate offers a simply way to refresh an old licence, as well as to support regular users.

    Subscription licence

    For those using Tinderbox regularly, i.e. with a real need to keep their installation up to date, a subscription method is offered. Here, an annual subscription licence is issued/billed automatically by Eastgate. (N.B. this does require them—or their fulfilment house—hold user payment details.)

    'Fest' sales

    For those on a tight budget, such as students and unfunded researchers, Tinderbox has historically been part of the bi-annual festival sale of—mainly macOS—artisanal software: 'WinterFest' (late December) and 'SummerFest' (late June). During the Fest sales discounts of c25% can be obtained on new (individual only) licences, and sometimes on upgrades as well.

    The sales should still be of interest to those with existing Tinderbox licences and other Fest offerings include applications that many use alongside Tinderbox: Bookends (reference manager) , DEVONthink (a powerful 'everything bucket') , BBEdit (an excellent general text-based file editor), … etc. Successive Fests can be a useful budget-conscious way to build out a library of good macOS tools.

    'Backstage' Early Access Program

    For those wanting access to the very latest features, or even just the ability to see what's going on, Eastgate offers a further subscriber-only service (in addition to the normal licensing) called the Backstage. The linked page described the details. The program gives access to interim pre-release (beta) builds and so use of features weeks or months before public release. Suffice it to say, most of aTbRef since c. version 5 has been written in the current beta rather than the current public release: Eastgate's betas are remarkably well-behaved.

    Pricing

    Prices will vary over the years so are not recorded here, but can be checked on the Eastgate's Order page. Note that upgrades are significantly cheaper than original purchase price, and subscriptions are slightly cheaper than upgrades.

    Multi-user (Group) licences

    Tinderbox is a powerful tool for workgroups, classrooms, and laboratories, for whom multi-user licences may make more sense. To multiple options can be purchased directly from the Eastgate website:

    • 'Household' 5-user. Family pack licenses for up to five people living in the same household.
    • 'TenPack' 10-user. Tinderbox ten-user license, ideal for schools, libraries, and work teams.

    Further detail on licencing

    The Tinderbox Licence

    The licence (EULA) can also be view in the Tinderbox Help file.


    License, Copyright and Colophon

    © Copyright 2014-2024 by Eastgate Systems, Inc. All Rights Reserved.

    Tinderbox is © Copyright 2002-2014 by Eastgate Systems, Inc. All Rights Reserved.

    Tinderbox™ is a trademark of Eastgate Systems, Inc. Storyspace™ and CIVILIZED SOFTWARE™ are also trademarks of Eastgate Systems, Inc. All other trademarks are the property of their respective owners and are used for informational and illustrative purposes only.

    This help document was created and edited with Tinderbox Six. Other especially helpful tools included BBEdit, Acorn, Skitch, Xcode, DropDMG, and Transmit.

    Tinderbox™ Software License Agreement

    Eastgate Systems, Inc., grants you a non-exclusive license to use this copy of the program on the following terms:

    YOU MAY:

    I) Use the program on any one computer;

    II) Install the program on a second computer you use provided all copies of the program are used directly and exclusively by yourself.

    II) allow anyone else to use the program, so long as there is never more than one user per licensed program at any time;

    III) make copies of the program in machine-readable form, but only for archival purposes, and only so long as all proprietary notices are reproduced on each copy.

    YOU MAY NOT:

    I) Modify, translate, reverse engineer, decompile, disassemble, create derivative works based upon, or copy (save for archival purposes) the program or the accompanying documentation;

    II) rent, transfer or grant any rights in the program or accompanying documentation in any form to anyone else without the prior written consent of Eastgate Systems, Inc.;

    III) remove any proprietary notices, labels, or marks on the program and accompanying documentation;

    IV) use this program, or permit this program to be used, on more than one computer at any one time.

    Non-compliance with any of the above restrictions will terminate this license.

    This license is not a sale. Title and copyrights to the program and accompanying documentation and any copy remain with Eastgate Systems, Inc.

    Household License:

    You and up to four (4) other persons who occupy the same household may use the program on their respective computers. "Household" means a person or persons who share the same home, apartment, condominium or dormitory suite, but shall also extend to student household members who are primary residents of the household but who reside at a separate on-campus location.

    Limited Warranty and Disclaimer

    This product and associated files are provided without warranty of any kind, express or implied, including without limitation the warranties that it is free of defects, virus free, able to operate on an uninterrupted basis, merchantable, fit for a particular purpose, or non-infringing. The entire risk as to the quality and performance of the product is borne by licensee. Should the product prove defective in any respect, licensee and not licensor assumes the entire cost of any service and repair.

    This disclaimer of warranty constitutes an essential part of this agreement. No use of the product is authorized except under this disclaimer.

    The liability of Eastgate Systems, Inc., shall be limited to the replacement of the product or the refund of the purchase price. This is the entire liability of Eastgate Systems, Inc., and your exclusive remedy. Save for the above express limited warranty, Eastgate Systems, Inc., makes no warranties or conditions express, implied, statutory or in any communication with you.

    This agreement is the entire agreement. If any provision of this agreement is held invalid, the remainder of this agreement shall continue in full force and effect.


    Markdown Copyright (c) 2004 by John Gruber. All rights reserved.

    CommonMark Copyright (c) 2014, John MacFarlane. All rights reserved.

    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.


    Eastgate Systems Inc.

    134 Main Street

    Watertown MA 02472 USA

    Tel: (800) 562-1638 (617) 924-9051

    Email: info@eastgate.com

    Web: https://www.eastgate.com/

    Registering Tinderbox for the first time

    When first purchasing Tinderbox, a registration code will be emailed. The code is applied via the Register tab of Preferences, accessed from the Tinderbox menu.

    Once registered, the Register tab of Preferences will show how many months' entitlement of free updates are left.

    Until a registration code is applied, the application runs in demo mode.

    If Tinderbox cannot run on the macOS version of the current host Mac, Tinderbox will not launch.

    If the host macOS is older but supported, Tinderbox may skip some facilities, or use older or slower versions of those facilities. This is not generally a big concern.

    If the licence is valid, a green tick is shown at bottom right of the dialog, otherwise a grey X is shown.

    Possible problems applying a licence

    The most common registration problems are:

    • The registration code is mistyped.
    • The registration code is too old, e.g. when meaning to apply an upgrade licence but using a previous code
    • Using a different name (or middle initial) in the registration window from the name on the order. To Tinderbox, J. Doe, john doe, and J. Q. Doe are all different names.
    • omitting the optional organisation name (only if one was given during purchase).
    • mistaking the letter "l" (lowercase L) and the numeral "1" in the registration code.
    • Tinderbox thinks (usually incorrectly) that the user's name cannot be a name.

    Licence renewal and upgrade requirements

    One year from first registering, the right to use new major and minor versions Tinderbox ceases unless you purchase an upgrade licence. An 'upgrade' licence renews free use of new releases for a further year, i.e. for 12 months from the issue date of upgrade licence. If your current cover has not quite expired the new period is added to the end of the existing one.

    Therefore, those wanting continued full access to all new releases should purchase upgrade licences on a yearly basis, but this is not a requirement for continued use.

    An upgrade licence allows the user to move from any past Tinderbox version to the latest release. As the licence code controls access to all releases, the terms upgrade and update can be regarded as interchangeable.

    If a user is outside the free update cover period, new releases may still be downloaded and tried, though use a separate install location and note the newer version will run in demo mode.

    The user is not prompted for upgrades, but it is possible to check the number of remaining months access to new versions and the current licence code via the Register tab of Preferences.

    It is not a requirement that upgrades be purchased before expiry of the current free update period. This offers flexibility, especially for those with limited budget for upgrades. Thus it is allowable for the original or a renewal upgrade licence's free upgrade period to elapse and then purchase a new upgrade at some later date. Simply register the upgrade, download the current version and carry on installing new versions for a further year.

    Put another way, an existing user can run any version of Tinderbox. If the release date of that version post-dates the end of their free upgrade access, the app will run in demo mode. If within the current access period, the app will run normally; the upgrade licence ensures continued unlocking of new releases.

    Registering an upgrade

    The process is the same as with initially registering Tinderbox. When purchasing an upgrade licence, a new registration code will be emailed. The code is applied via the Register tab of Preferences, accessed via the Tinderbox 8 menu.

    Once registered, the Preferences Register tab will show how many months' entitlement of free updates is left.

    Possible problems applying a licence

    See Registering Tinderbox for the first time.

    Installing a licence on more than one computer

    Note licence conditions about installing the same licence on more than one computer (see manual for complete licence), in that you may only:

    *Install the program on a second computer you use provided all copies of the program are used directly and exclusively by yourself.

    *Allow anyone else to use the program, so long as there is never more than one user per licensed program at any time;

    Put in simple terms, you can install it as many times as you like on different computers as long as you are the only user. For those who work on multiple computers at once, the licence does not check concurrent use so you can, for example, use your Tinderbox on you desktop and laptop at the same time.

    If your licence for free upgrades has expired, install your current version on the new computer.

    Separately, the 'Household' version of the licence allows:

    *You and up to four (4) other persons who occupy the same household may use the program on their respective computers. "Household" means a person or persons who share the same home, apartment, condominium or dormitory suite, but shall also extend to student household members who are primary residents of the household but who reside at a separate on-campus location.

    In essence, the latter is a 5-seat concurrent access licence.

    Installation

    Installing Tinderbox

    To install Tinderbox, download the disk image (DMG) and double-click it to mount the image. Drag the application icon onto the shortcut to your Applications folder to install the app. If installing over an existing version you will be asked if you wish to replace it or to keep both versions. For normal use, replace any existing version.

    If the mounted image contains no shortcut to Applications (e.g. with beta builds), simply open a Finder window showing the Applications folder and drag the drag the new app icon onto it.

    Once installed, open the Applications folder, find the Tinderbox icon and double-click it to open Tinderbox. On very first use you will be asked for permission to open the app, as part of standard Mac security procedures.

    Multiple versions

    For users with more specialist needs or those just wishing to test a new version before over-writing their existing version, Tinderbox can be installed pretty much anywhere (for which your account has permissions). Note that if several versions are installed, they will share the same application support folder.

    Note that if using multiple versions in different locations and using AI with an MCP bridge, the AI settings will hold the version/location of the app as at the time AI was last enabled.

    Installing a new version

    The process is as simple as:

    • Close Tinderbox (if open)
    • Download the DMG of the latest version from the Eastgate website: https://www.eastgate.com/Tinderbox/download.html 
    • Double-click the DMG to mount it. Depending on system settings this may happen automatically on download. A new Finder window opens.
    • Select the 'Tinderbox.app' icon and drag it:
      • onto the the alias icon next to it to install to the default location (in /Applications). Accept the prompt to overwrite the existing version.
      • into any other location, e.g. the Desktop if installing a second version to test.
    • Unmount the DMG.
    • Use the new version.

    It can also be useful to review the Document Settings and change any defaults that do not suit. It is certainly worth setting the user name value that is stored as the name of the creator of the note. The latter is very useful if sharing a file with other users who may edit it.

    Updating an existing installation

    To replace an existing version, first ensure you have closed the existing version. If required, back up the current app (or ensure you still have its installer). Then:

    *mount the new version's disk image by double-clicking it

    • default install: drag the application icon onto the Applications folder alias in the disk image
    • custom location: drag the application icon onto the folder holding the current version

    *Finder will ask if you wish to replace the current application; click the 'replace' button

    *Tinderbox is now installed

    If you wish to run more than one version, install the new version to a different folder from your existing one. However, do note that both versions will use the same preferences. If the later version has changed significantly, i.e. has differing preferences, this may cause the older version to behave unexpectedly. Versions 6 and 5 can co-exist but it is not recommended to attempt to work in both concurrently as this scenario is not tested.

    Updating the application will inherit existing app preferences so if a preference or attribute default changes in a new version this may not be reflected as the app assumes the existing preference is the users choice. A change to preferences on new version install generally only occurs when completely new preferences are introduced or when the new default choice(s) no longer fit with the pre-existing ones. The user can always manually apply changes to bring preferences back in line with current defaults (assuming these are known!). For those using custom configuration files, also bear these in mind when reviewing changes to preferences.

    Although you may have more than one version installed, and whilst they may both open if started you should not open more than one version/copy of the app at a time or you may get unexpected results. In other words, unless you are a beta tester and/or are specifically instructed to do so, only run one version at a time.

    Installing more than one version

    NOTE: Nearly all users should only ever need to have one version installed—either the current one or the last one available when their free upgrades expired.

    However, occasionally it can be necessary to want to have two versions installed at once. A good example is assessing a new version to decide on purchasing an upgrade after having let cover lapse. This approach is also needed for beta testers.

    So, it is possible, but do so with care. It is not a supported form of general use. Both versions will share the same app settings.

    Do not try to open both versions at the same time—you will not get a warning (or a crash) but you may get unexpected results, so do not do it!

    It is suggested to leave the current version of the application installed in Applications. This user then places secondary versions on the Desktop, or whatever location is chosen. If wishing to keep multiple version in the same folder, one will need renaming before being added to the folder.

    As all installed versions share settings file, if using a much newer version for test, there is a chance the settings may not then work in the older version. This has not been seen, but if it does old app setting may be lost. Plan accordingly.

    As aTbRef's author is also a beta tester, this document has been used editing on multiple versions of Tinderbox (albeit one version at a time) including most betas and without harm.

    Note: it is worth repeating that very few users will ever need to use this configuration, but it is worth documenting for those who do.

    Migrating Tinderbox to a new computer

    With a current original or upgrade licence, simply download the latest version of Tinderbox onto your new compute and register as normally.

    If your licence for free updates has expired the process is the same except you should install the last version that your licence allows. If you no longer have the installer for that version, email Tinderbox support and ask for the download URL for your version.

    Note the limitations on using the same licence on multiple computers.

    Other aspects to consider:

    • Preferences file. This is in ~/Library/Preferences. That folder will contain a preferences file and (if used) a Tinderbox user dictionary.
    • Configuration files. If you have customised badges, colour menus, etc., or have a set of favourite files, check your configuration files which are at ~/Library/Application Support/Tinderbox/. The latter folder can also be opened from the Tinderbox Help menu.

    Uninstalling Tinderbox

    Close Tinderbox, open the folder where it is stored (default is /Applications/) and drag the app to the Trash. Supporting files will be found in the user account Library, i.e. ~/Library/Preferences/ at:

    • com.eastgate.TinderboxSix.plist (Tinderbox v6+)
    • com.eastgate.TinderboxSix.LSSharedFileList.plist (Tinderbox v6+)
    • com.eastgate.Tinderbox.plist (Tinderbox pre v6)
    • Tinderbox user dictionary 
    • Tinderbox™ Preferences 

    Check, especially If you have installed custom configuration files, and remove the folder and its contents at:

    • ~/Library/Application Support/Tinderbox/

    If you have installed the app at a global level (for all accounts) you may need to check:

    • /Library/Preferences/
    • /Library/Application Support/Tinderbox

    Any support files in these locations may deleted (or archived off elsewhere).

    Demo & Viewer mode

    If Tinderbox is installed and not registered it runs a demo. In demo mode the app is fully functional except for the abilities to add more than 24 new notes.

    This means the demo can be used as a viewer for TBX files as there is no cost to downloading and using the demo.

    The demo can open and edit TBXs with more than 24 notes—it just cannot add more than 24 new ones. Thus, if trying out the demo it can be useful to download various demo TBXs just to see how larger documents look and to play around with their arrangement of notes.

    The demo does not expire and on application of a registration code becomes the full application.

    Tinderbox documents

    TBX Documents

    A Tinderbox document is a saved as a single file, with a '.tbx' extension, and thus are often referred to as 'TBX' documents.

    Tinderbox can create and save multiple TBX documents, limited only by storage space available. It can open multiple TBX documents at once, limited only by the host computer's resources. When Tinderbox is started, it will open any documents open when the app was last closed; this behaviour follows the host OS's System Preference/General 'Close windows when quitting an app', so may vary if that preference is changed.

    Tinderbox also tracks recently opened documents on a sub-menu of the File menu. If multiple documents are open, the application's Window menu list all open windows from all documents. The latter listing does not indicate the document to which each document belongs.

    Any non-default Document Settings and other customisations (link types, custom colours, user attributes, etc.) are stored in the TBX.

    A Tinderbox TBX document stores its data in XML format; for some users with XML skills this can provide another way to interface with, or view, the data. Users altering TBX documents by editing the XML source should note that such work is not formally supported as an editing method, i.e. do not expect that Tech Support will be able to fix user mistakes editing source XML.

    An open document can display one or more windows and tabs.

    See more on the XML structure of TBX documents.

    What does a Tinderbox document contain?

    A Tinderbox document is a self-contained storage of your notes and information about them including:

    • every note (including any embedded images)
    • every agent
    • every adornment (including picture adornments)
    • any non-default Document Settings
    • user attributes
    • any user added/customised link types, defined colours, stamps and macros
    • information about open document windows and tabs

    Note that embedding images inside a document—whether as map adornments or in notes—will likely add noticeably to the overall file size of the document.

    The document data is stored as XML. Those whose understand XML can (at their own risk). Use XML tools and techniques to read, extract or even modify data. Do not attempt to edit XML data for Tinderbox files that are also currently open in Tinderbox but rather close them first. Users altering TBX documents by editing the XML source should not this is not formally supported as an editing method; i.e. do not expect Tech Support to clear up after user mistakes. See more on the XML structure of TBX documents.

    Either to save space for long term storage or for safe transmission (e.g. as email attachments), Tinderbox files compress quite well. To make a ZIP format archive of one or more documents, select the Tinderbox file(s) in a Finder window, right-click the selection and choose the 'Compress' option. A Zip file will be created alongside the selection. The name of the file is either the filename plus a '.zip' extension or 'archive.zip' if multiple files are compressed. The name of the compressed file can be altered without affecting the contents (though leave the .zip' extension!).

    TBX file sizes

    Generally most TBX files are pretty small—a few MB or less. There is no hard limit to size to a practical limit will be resources getting maxed out either in the app or the host OS.

    Some of the ideas behind Tinderbox do have limitations at large scale. Spatial hypertext works well with dozens or hundreds of notes. If you have millions of notes, it’s harder to make any sense of the map, and it’s hard to know where a new note ought to go. Hyperbolic view can likewise become very busy with large numbers of notes.

    Adding images to notes (i.e. to their $Text) or as image adornments on maps will have far greater effect on document size than ordinary textual content (in $Text or as attribute values). Occasionally, users will discover hard limits by building documents larger than anyone had tried to build before but there is no fixed limit.

    As a general guideline, Tinderbox is comfortable with hundreds or a few thousand notes. If needing millions of notes, a database application is really the correct. In between those sizes is a grey area. If TBXs are operating smoothly, size should not be a cause for concern.

    Support

    Reporting Problems

    In the event you have problems with the application or with particular TBX(s), formal tech support is offered via email at info@eastgate.com.

    Bear in mind that the online forums are user-to-user (i.e. not formal Eastgate support), so people helping there are fellow users who do not have access to the internals of the app. They can however be a useful source of advice on the how and why of using Tinderbox and specific techniques.

    Tinderbox files have no '.tbx' extension

    First check you have not set Finder's preferences to hide file extensions: see how. If you have, you will not see any file extensions!

    If a Tinderbox file has no '.tbx' extension, even when extensions are shown, then there are some possible causes:

    • If you used Tinderbox before July 2005 (v2.5), the application did not add extensions and relied on old-style Mac OS resource fork info. All such legacy Tinderbox files should now be given a '.tbx' extension.
    • You somehow deleted the extension. If you are certain the file is a Tinderbox document, then give it a '.tbx' extension and try opening it
    • The file is not really a Tinderbox file. Either—if confident to look at XML—look at the source code in a text editor. A Tinderbox file will mention the app name on line #2 of the code. Or, send a copy of the file to support (info@eastgate.com).

    Now your files have the correct extension they should show a Tinderbox file icon and you should be able to open then simply by double-clicking their file icon. If not, see here.

    Showing or hiding filename extensions via Finder

    The setting is normally on the Advanced tab of Finder Preference. To do this:

    • Select Finder
    • Open the Finder menu from the main menubar (top of screen)
    • Click the 'Preferences…' menu option
    • The Finder Preferences dialog will open (illustrated here)
    • If not already selected, click the 'Advanced' button in the dialog's toolbar.
    • Ensure the top tick-box 'Show all filename extensions' is ticked (as shown)
    • Close the Finder Preferences dialog.

    Your Tinderbox documents now show a '.tbx' extension.

    If desired, you can toggle this option back off but all extensions will be hidden. It is certainly advisable to have file extensions visible whilst troubleshooting issues with Tinderbox files being opened correctly on double-click.

    Note that Finder itself can still 'see' any file extensions even if you have told it to hide the file extensions.

    Beyond the scope of this article is that depending on how much fiddling you have done in this area, some extensions may not be hidden, even when Finder has been told to hide extensions. This is because unwittingly you will have told Finder that this particular file's extension or this extension in general must always be shown. That is fixable; look in Finder's Help for how.

    Tinderbox files do not have a Tinderbox icon

    Tinderbox documents should show the file icon illustrated here and open in Tinderbox if double-clicked. If the icon is for some other application or just a plain white page, Finder believes the file is not associated with Tinderbox. In such instances double-clicking the file will cause the other app to try and open the file or finder will ask the user to choose and application to use. This can be fixed.

    In such a case, first check that the file has a '.tbx' file extension.

    If there is an extension but still the wrong icon it is likely that, due to some unintended error, you have told Finder to open this document in some other application and/or the later has now assumed 'ownership' of the document. Such and error can happen for a single file or all files of a given file extension.

    To fix, locate your file in Finder:

    • Use Finder's Get Info on the file (Cmd+i).
    • Click the 'Open With' disclosure triangle to expand an application list.
    • Choose Tinderbox as the application you want all files of this type to open with. If Tinderbox is not already listed as suggested choice, use the "Choose…" option and find Tinderbox in your /Applications folder.
    • Click "Change All" and then "Continue" when the confirmation dialog appears. This last step tells Finder to open not just this file, but every file of this type with Tinderbox.

    The icons for your Tinderbox file(s) should now regain the expected icon type and open correctly in Tinderbox when double-clicked.

    Tinderbox files don't open on double-click

    If you definitely know the file is a Tinderbox document and are in a hurry:

    • Open Tinderbox
    • In Finder, drag the document's file icon onto the Tinderbox application icon in the Dock.
    • The file should open

    If this does not work, or when you have more time to fix things properly, follow this procedure to (re-)inform Finder how to handle files with a '.tbx' extension.

    Read what to do if you get a "Tinderbox was unable to parse this file" message.

    Checking or resetting old System attribute defaults

    Over time, in successive Tinderbox releases, some System attributes' defaults have changed. These changes will not show up for existing users if their Tinderbox Preference file already defines the values, i.e. some but not all values are masked by existing Preferences.

    If it is desired to reset/review attribute defaults:

    • Create a new Preferences file (see how).
    • Create and save a new Tinderbox document.
    • Save the new Preferences file to a new location.
    • Close the Tinderbox and restore the old Preferences file.

    The old and new Preferences file can now be compared for differences. Attribute defaults set directly via the app can be viewed by opening the saved new TBX in a text editor (the source is XML code).

    For long-term users with TBXs originally created in older versions, the issue is the latter are set and fixed at doc creation. New app defaults are not applied. Comparing the attributes section of the new TBX with one or more existing files may show up changes that can then be applied, if required, to the existing document(s) by resetting the document attribute defaults. Note that some attributes, being set via Document Settings, should be altered by that mechanism.

    Message: Tinderbox was unable to parse this file

    Very occasionally, on opening a file you may get a dialog with a message like:

    Tinderbox was unable to parse this file. It may be damaged, or you may need a newer version of Tinderbox. The XML parser said : not-well formed (invalid token) (line 1232).

    Whilst the exact line number stated at then end will vary, Tinderbox is telling you that the TBX file's data includes something it can not understand at the line (as referred to) in the source XML of the document. When Tinderbox opens a file, it has to read in all the XML data stored in the TBX document file. If this data has been corrupted in some way such that it is no longer in valid XML format, Tinderbox cannot read past that point and gives this error message.

    How might such a thing occur? The error is unusual but causes include copying/pasting text from web pages that mis-declare their encoding, such as with web pages where quote marks show as question marks (e.g. character) or less common accented characters as pairs of random characters. It is not always possible for the Tinderbox to detect that the data it is passed is not what it declares itself to be. This can cause the data to be stored inappropriately in Tinderbox, although the effect does not tend to surface until the document is next opened—which for some users can be hours or days after the triggering event. More technically, data is saved in a form that's not intelligible to the XML parser used to read the data when opening a TBX file. Similarly, AutoFetch of data from badly-encoded pages/feeds/sources can ingest data that has the same effect as above.

    The solution is to send the file (or better, a zip of it) to Tinderbox support (info@eastgate.com) and they should be able to fix it and return the document. At times the fix may result in the loss of all or part of $Text (or the affect attribute(s) of the affected note(s), but generally just the offending characters can be excised.

    If you are doing some task where this happens more than once (perhaps you have very 'dirty' source material) then ensure you have reviewed your settings for back-ups and autosave. You can always change back to your defaults once the problem is resolved.

    For the more technically minded…

    If you are confident using a text editor and looking at XML source code you can have a go at fixing this yourself. If you do not have a text (code) editor—do not use TextEdit—a good free option is BBEdit. Now:

    • Make a copy of your broken TBX and give it a new name indicating it is (will be) the 'fixed' version.
    • In your text editor turn on line numbering (see your editor's manual if unsure how). It is also a good idea to turn on 'invisibles' so you see an on screen character for spaces, tabs, control characters, etc. Turn line wrap 'off', at least until you have located the problem.
    • Open the TBX in the text editor app
    • Scroll to the line mentioned in the original Tinderbox error message.
    • Examine that line in the code for anything untoward (use the window's line numbering to find the right place). If your editor has syntax colouring it should stop working around where the error occurs.
    • If it is not self evident as to the exact error, try removing the whole attribute value containing the bad line. Most commonly these errors occur in $Text. In such a case you might delete the value of that $Text, i.e. all code from the last tag preceding the error position and the first tag following it. You can always cut/paste the excised data to a text file for temporary safe keeping.
    • Save the file close and re-open in Tinderbox. You may get another error (likely caused by the same thing in a different note). Rinse and repeat the previous steps until the file opens. You can then review what's been lost and the likely probable cause. If you think you know the latter, it is probably worth letting Tinderbox support know in case it is a cause they can predict and guard against in the future.
    • If you have no joy at all delete your edited file and sent a copy of the original TBX to support.

    For TextWrangler and BBEdit users a slightly more hands-off approach is offered via those apps' "zap gremlins" option. It should prune non-XML-safe characters from the file though you will not know exactly what that is. You will just have to look at the resulting TBX file and guess.

    If interested, the XML format of a TBX is described in aTbRef.

    Where are crash and hang logs found?

    Tinderbox is generally very stable but that does not mean you may not find some data from the app cannot ingest from drag/drop or find some configuration next really designed for.

    Should the unfortunate occur, and the app crashes, macOS will create a crash log which it can be helpful to Tech Support in resolving the cause. Such logs are found inside your home folder at:

    ~/Library/Logs/CrashReporter/ 

    or

    ~/Library/Logs/DiagnosticReports/ 

    Within that folder look for files with names in the format "Tinderbox_yyyy-mm-dd-hhmmss_macbookpro.crash". Basically, the filename retains the date/time of the crash.

    If reporting a crash, attach a copy of the log file(s) to your email. It is also very helpful to support if you can describe the events leading up to the crash and/or a step-by-step method to consistently trigger the crash.

    Occasionally, an app may not crash but become very busy and have to be stopped (by the user or the system). In such cases a hang report may be created. These are stored in in the main, system-wide Library:

    /Library/Logs/DiagnosticReports 

    The logs use a similar naming method to the crash logs but use a '.spin' or '.hang' extension.

    A more detailed tutorial on crash/hang logs for Tinderbox is available elsewhere.

    Resetting Preferences

    It is most unusual to get a problem with Tinderbox's preferences. The file contains the app-installed preference defaults, as subsequently modified. However, if a problem is suspected, a number of things may be tried.

    For the non-tech user…

    …who does not like looking at under-the-hood stuff:

    • Locate the Preferences file (for location see below).
    • Ensure you have your Tinderbox licence code to hand. NB: the licence is needed only if you cannot roll back to existing Preferences after testing.
    • Close Tinderbox, if open.
    • Drag the "Tinderbox™ Preferences" file to another place such as the Desktop.
    • Restart Tinderbox, which causes a new Preferences file to be created. If demo mode does not enable you to test as needed, you will need to re-apply your licence info via the.
    • Test Tinderbox and if no change:
      • Close the app, and copy the old Preferences back over the new set.
      • Contact technical support.
    • Or, if the problem goes away:
      • Continue using the new preferences.
      • Re-apply your licence key if you have not already.
      • Check the Tinderbox Preferences dialog in the app and make any customisations to restore your preferred settings.
      • Archive or delete the old preferences file.

    For the more technical user…

    …the Preferences are a text file so you can open it in a proper text editing (not a word processor!) and look for any obvious corruption. The file includes the Recently Used Files list and in earlier v5 versions some more exotic filenames/paths caused problems. Deleting the corrupt path listing could normally fix Preferences (assuming no other errors). The latter problem seems to have been resolved in later v5 releases.

    If confident using a text editor and if forced to use a new Preferences file, the old file can be viewed/compared and used as a reference to re-apply any desired non-default settings via the Tinderbox Preferences dialog.

    Locating the Tinderbox Preferences file

    Tinderbox's Preferences files normally normal located at:

    ~/Library/Preferences/Tinderbox™ Preferences 

    Users wanting to share Preferences between several users of the same Mac may elect to copy/move their Preferences file to:

    /Library/Preferences/Tinderbox™ Preferences 

    Tinderbox checks the latter folder for a Preferences file and if found, uses it in preference to any local version.

    Image formats for embedding

    Generally, Tinderbox expects bitmapped images of the JPG (JPEG), GIF, or PNG format. Tinderbox will likely accept other older formats such as BMP, PICT but these are best avoided if possible.

    Formats used as wrappers for bitmap content, are not supported directly, but can be used indirectly as discussed below. For instance, more complex bitmap formats such as TIF/ (TIFF) which can support a wide of complex internal formats (hidden from the ordinary user) may work depending on the internal structure of the file.

    In general, if you can open an image with Preview (or some image editor such as Graphic Converter, Lightroom, Aperture or Photoshop), you can select a portion of that image, copy it to the Mac clipboard, and paste it into Tinderbox as an image adornment (though not as an image note). The latter applies to PDF and TIFF files, among others.

    Apple Preview and image editors can also convert TIFF files to JPG or other simple bitmap formats files that can be dragged into Tinderbox as image notes.

    Preferences & Document Settings

    Preferences currently only relate to registration information and Tinderbox versions.

    The old Preferences have now become Document Settings, applying only to the current document. Many Document settings act as default values for System attributes. Whilst a few System attributes are calculated on the fly and thus read-only, all other attributes can be manually set a doc-level default.

    Preferences have been significantly revised and reduced from pre-v6 designs.

    Preferences

    Preferences has the following tabs:

    Register

    The Register tab holds the following information:

    • Name. The user's name as per the registration details (user's details greyed out in screen-grab).
    • Organization. Optional organisation information as per the registration details (user's details greyed out in screen-grab).
    • Registration Code. The licence code as supplied by Eastgate (user's details greyed out in screen-grab).
    • (Remaining months of free updates.) The number of months remaining of access to free updates or a reminder. Or, if expired there is a click-able link to an Eastgate webpage for obtaining upgrades.
    • Anonymized Data Sharing. Tinderbox anonymously reports some simple usage statistics to Eastgate make features easier to discover (see longer discussion). The default is to allow sharing. Un-tick the box to prevent sharingTbRef's author recommends accepting the default, of sharing.

    This is Version. The version of Tinderbox currently being used.

    Latest Version. The latest public release of Tinderbox.

    Tick/Cross. The tick symbol indicates the supplied registration code has been successfully applied.

    A text prompt indicates where to find Document Settings.

    Document Settings

    Document Setting allows the customisation of various application defaults. Most of the setting are also used as defaults for System attributes. The title of the Document Settings dialog is the filename of the current Tinderbox Document when it is opened. If multiple TBXs are open, it is possible to open a Document Setting dialog for each open TBX.

    The controls for settings are divided into a series of tabs:

    General

    The General tab has the following controls:

    User Name

    User Name. Default value: 'system'. The name entered here is used by the $Creator attribute. It is useful to alter this from the default if sharing a Tinderbox file or it is being edited by more than one person.

    In the latter case each user would start their edit session by setting their name (and possibly resetting this preference when done).

    Check spelling as you type

    This toggles the underlining of (possible) spelling mistakes. Default: ticked (on).

    This also sets the document-level default for the system attribute $NoSpelling. For the above default, the $NoSpelling default is false.

    On low-powered systems and/or with documents with large amounts of $Text leaving this off may help with performance. Otherwise, leaving the setting turned off simply avoids the red underline spelling prompts. The latter are not helpful if showing the app in a presentation or if using multiple languages in $Text.

    Show toolbar in new document

    From v11.8.0, this toggles whether the application's toolbar is visible by default in new documents.

    When unticked, opening documents that have a toolbar open avoids an old problem of this casing all document to then show a toolbar.

    Recognize #Prototypes and @Places in Note Names

    This toggles parsing of new noted names for special handling of # and @ syntax, used for setting prototypes/locations.

    This toggle is 'on' (ticked) by default, thus literal use of # and @ in new/edited note titles may be problematic unless the feature is toggled off.

    Enter key

    Enter key (⌤). There is a choice of outcome when pressing the Enter key, or Fn+Return (Fn+↩) on modern keyboards:

    • Renames selected note. (default) This reflects pre-v6 behaviour when Renaming occurred in a separate dialog.
    • Opens Action Inspector. This opens the Action Inspector, with the Action tab selected. It is probably a more useful choice for most users.

    Enable Al Integration in this document

    From v11.0.0 Tinderbox is able to use Model Context Protocol (MCP) to allow AI desktop tools to interact with Tinderbox document. This is an experimental feature using techniques liable to change.

    If the AI Integration option is not ticked in the Tinderbox menu, it disables the checkbox for AI Integration in this document. Thus, to enable the check-box for use, first enable the primary AI Integration option.

    The effects of this tick-box are described in the note on use of AI with MCP.

    Text

    The Text tab controls various defaults relating to note text ($Text):

    Paragraph Spacing

    Paragraph Spacing. Default = 6pt (was 2 pt in older TBXs). A choice of preset values, in points: none/2/4/6/8/10/12/14/16/18/20/22/24.

    This setting controls the amount of white space between paragraphs and sets the default for $ParagraphSpacing. Prior to v11.0.0, 14pt was the largest spacing offered. Larger sizes offer more paragraph spacing, useful for large font sizes and presentation. Default remain 6pt. New options16/18/20/22/24pt

    Text color

    Text color. The default colour of the text used in (all) note text. Default is: #000000 (black). Inherited by $TextColor attribute.

    Once text is added to $Text, its style—at time of entry—is saved in the TDF data and so it is unaffected by subsequent changes to $TextColor. Re reset a note's $Text to use a (new) $Text colour, select all $Text—or that to be repaired—and use menu Format ▸ StyleStandard Font. (N.B.there must be a $Text selection for this to work)

    To re-colour (selections of) existing $Text, i.e. to a colour different from $TextColor, use either the Format ▸ Style or Format ▸ Font menus.

    Background color

    Background color. The background colour of (all) note $Text areas in the text pane. Default is: #ffffff (white). Inherited by $TextBackgroundColor attribute.

    Smart quotes

    Smart Quotes. This controls whether straight single or double quotes are automatically replaced by 'curly' typographical quote symbols; it also controls the automatic conversion of two hyphens (--) to an en-dash (–). This setting forms the document default for $SmartQuotes. Default: ticked.

    Underline on ⌘⌥

    Underline on ⌘⌥. In notes, when this option is ticked, holding down both the Command & Option (⌘+⌥) keys together causes any links in current note window's text to be underlined (default= ticked). This is useful for discovering the exact extent of a text link when there is no distinguishing text colour for the note or try to establish is the link area has opening/trailing white space included. Pre-v6, this effect used a box around the anchor text.

    Update after renaming

    There is an option to disable automatic updates to all note $Text text link anchors when note titles ($Name) are edited. This is useful for those using zettelkasten or wiki type links where link anchors are exact target note names.

    Default is ticked (true). The setting is inherited by $UpdateTextLinksAfterRename, so can be set differently per-note (or via a prototype).

    In large, well-linked documents that do not use note titles as link anchor text, this option is of less use as it is essentially unneeded so nugatory background work for Tinderbox to be doing.

    Text Font

    Text Font. The name and size of the default font for note text ($Text). This sets the default for $TextFont and $TextFontSize. Text size is set directly in Points.

    Default is MercurySSm-Book at 16pt. Previously it has been variously: HoeflerText-Regular, Cochin, Lucida Grande, and originally Geneva.

    As note default text size is also set via the OS Fonts dialog, a wider range of default sizes is possible than in early versions of Tinderbox.

    When the default text font is changed, Tinderbox scans the text of every note in the document and changes each usage of the former text font to adopt the new font family while retaining the current size (see more).

    Changing the default text font in Document Settings now updates both the text font and font size in notes using the former default font and font size.

    Edge case issues:

    • what happens to text styled to other than the default font face/size? Tinderbox does its best to handle bold and italic styles consistently.
    • what happens to text already at a different size? Tinderbox does not resize text at different sizes., i.e. non-normal sizes
    • if the first character of an existing note is not using the document' default Font/Size, do other parts of $Text using the default still update? Tinderbox scans the entire text, and update text that matches the old default.

    Alignment

    Alignment. The justification style for text in the text pane $Text area. Sets the default for $TextAlign. Choices are icons representing:

    • left. (default).
    • center.
    • right.

    Displayed Attributes date format

    A pop-up list offers a choice of 3 doc-wide default formats for the values of Date-type attributes shown in a note's Displayed Attributes table and Get Info's attributes tab.

    The default is to show the local OS' short date format, then a comma, and then the hours:minutes.

    This choice can be overridden at document or note level by setting a date format string in $DisplayedAttributesDateFormat:

    • To set a document-level default that is not one of the 3 built-in defaults listed here, use the document Inspector's system tab, select $DisplayedAttributesDateFormat and replace the default with the desired format string (without enclosing quotes). This will now be the format inherited in the document and the control in Doc Settings will be greyed out. The attribute's doc-level default is "" so as normally to inherit the format set in the above pop-up.
    • To set at prototype or note level simply set that note's $DisplayedAttributesDateFormat.

    The design intent here assumes a customised format will more likely be set in a prototype than at doc level, but the latter is possible (as described above).

    Maps

    The Maps tab controls various defaults relating to Map view (although some may be used in other views too):

    Map Font

    Map Font. This sets the font to be used for titles in views and sets the default for $NameFont (font) and both $MapTextSize and $OutlineTextSize (font size).

    The default is IdealSansSSm-Book, at 16pt. It was 12 pt until v5.x, for v6–10 is was 14pt.

    Map interior scale

    Map interior scale sets the default for the $InteriorScale attribute. This number is the factor by which notes inside a container are smaller than notes elsewhere in a map. The default value is 1.5. If InteriorScale is 2, then interior (child) notes are half their normal map size.

    This scaling helps with viewing the content of a map container's viewport.

    Background Main Color

    Background Main Color. Specifies the background colour to be used for Map views and all other view windows, i.e. all windows except Note windows and Tinderbox dialogs/palettes. Inherited by the $MapBackgroundColor attribute. Default colour value is 'gray'.

    Many views re-use this colour—see more.

    This also sets the primary colour for map background patterns (in Map view only).

    Background Accent Color

    Background Accent Color. Specifies the accent colour used for patterns in Map view backgrounds. Inherited by the $MapBackgroundAccentColor attribute. Default colour value is 'gray' (same as $MapBackgroundColor).

    Background Pattern

    Pattern. This allows a map icon style pattern to be applied to he background of map views, using the main and accent map background colours. The allowable pattern values are:

    The value is stored in $MapBackgroundPattern.

    If note name is too long

    If note name is too long. This option lets you ask Tinderbox to automatically expand notes that have been newly-created or renamed in the map view, if their titles are too large to fit in the current note rectangle.

    This new options is especially nice for quickly making notes in meetings. The choices are:

    • Do nothing (default)
    • Expand horizontally
    • Expand vertically
    • Expand proportionately
    • Use smaller type.

    The Expand proportionately option tries to use a smaller font size in order to fit in the available space. Manually resizing the note will increase the font size again, up to (but not exceeding) the preferred font size.

    The Use smaller type option uses smaller type but it does not resize the title text if the map icon is later re-sized. This option will not make the type larger than the default size if the note is later made larger. Adornments are not affected by this document setting.

    If this setting is used and a note is added in a view other than map view the appropriate map view is updated appropriately even though not currently open.

    Renaming a note in the text pane title box expands the note in the map as necessary, if this setting is using any value other than Do nothing.

    After linking

    After linking. This controls whether focus shifts after creating a link. Values:

    • source
    • destination (default)

    The default setting is best for data input. Making a link to a note, selects that note as a result of completing the link, allowing raid traversal of a new link chain or entry of data into the newly linked note.

    The 'source' option is more useful when reviewing a new document. In this mode it is often desirable that in creating, or correcting links, that the focus does not shift from the current note.

    Opaque Adornments

    Opaque Adornments. If ticked, adornments are completely opaque. Normally, they are drawn slightly translucent as this helps when adornment need to overlap. Default: un-ticked.

    This setting applies to all adornments in the document and cannot be set per adornment.

    Adjacent Notes Form Composites

    This allows the default document setting for $NeverComposite to be altered. By default is unticked meaning notes in new will not form accidental composites.

    Texture

    This pop-up allows pre-setting the default texture for new notes, i.e. the document default for $Fill. The choice is also pre-selected in the Appearance Inspector's Interior tab's Texture control.

    ^⌥⌘ zooms out

    This allows disabling map overview zoom on ^⌥⌘. Some users prefer to assign this key combination to Alfred or Keyboard Maestro.

    The default is ticked/on, which maintains the pre-existing behaviour.

    Un-tick to remove the shortcut use by Tinderbox.

    This setting is saved between sessions.

    Outlines

    The Outlines tab controls various defaults relating to Outline view (although some may be used in other views such as Chart):

    Charts and outlines have:

    Charts and outlines have:

    Two features to assist with legibility when using lighter colours and colour schemes. Some colours (e.g. yellow, pastels) are hard to see against a light background. The effects can be applied singly or together.

    • Darker colors. This darkens the colours used for drawing outline text & icons. Default is 'on' (ticked, previously it was 'off'). However, this does make most colours harder to tell apart, and it is worth trying out documents with this setting off. In documents that use 'Darker colors' in outlines, the selection highlight also uses the darkened colour.
    • Black titles. This enforces the display of all note titles in charts and outlines in black, without regard to the note's $Color value. Default is 'off' (un-ticked).
    • White titles. This enforces the display of all note titles in charts and outlines in black, without regard to the note's $Color value. This can help with use in OS dark mode. Default is 'off' (un-ticked).

    NOTE: although both black and white title options my be un-ticked, only one may be ticked at a time, i.e. you can choose to have:

    • no black/white title option set
    • black
    • white

    … but not both black and white (which would not make sense anyway!).

    Underline alias titles

    Underline alias titles. This allows aliases in Outlines (in fact all major views) to have their titles underlined in order to make them more conspicuous as aliases. Default: un-ticked.

    It is also useful for pre-v6 files where the specified $NameFont may lack an italic font variant: see more.

    Prototype highlight color

    Prototype highlight color. This preference sets the colour of the circle shown behind the Outline view note icons of prototype notes. The default is very light. If prototypes do not show a mark behind them try a darker value for this attribute. To avoid the mark showing, set the value the same as the view's background colour.

    The default value is #DDEEDD and it is inherited by the attribute $PrototypeHighlightColor.

    Outline Spacing

    Outline Spacing. A control for leading in Outline view, i.e. controlling additional space between outline items.

    Accounts

    This tab holds account criteria for various tools with which Tinderbox can communicate.

    Readwise

    This is for Readwise data import, and the box should hold the users Readwise Authorisation Token.

    Zotero

    This is for reference management using the Zotero app. There are three inputs, the first two can be obtained from the Zotero user account Settings page as https://www.zotero.org/settings/security. As user wishing to use this feature will need a (free) online account even if using the macOS native desktop Zotero app as he latter does not generate these codes. The three controls are:

    • ID. The users' Zotero ID, a seven figure number.
    • Key. The key from account settings.
    • Style. The desired publishing format. The default is "apa". You can use any format installed in your Zotero app/account (i.e. you can add other formats besides the default installed formats).

    Colors

    The Colors tab controls selection of the current colour scheme in use in the document. The default is 'Modern'. The list shows both built-in scheme and any stored in the Tinderbox support folders. Read more on colour scheme files.

    The left list box lists available scheme. When selected, a sample bitmap (if supplied) illustrating the scheme is displayed on the right.

    Note that from v8.0.0, Tinderbox's colour schemes have been given an overhaul. In support of these improvements, several old colour schemes have been dropped. This means new documents will have a different set of pre-defined colour schemes. Note that for new documents created in v8+ on OS versions (10.14+) with dark/light modes the document is given a different default colour scheme. The current built-in schemes (and defaults)

    • Coral
    • Dark Coral (default for new TBX files in OS dark mode)
    • Franchi
    • Green
    • London
    • Modern (default for new TBX files in OS light mode)
    • Postmodern (added in v11.5.0)
    • Solarized
    • Sorolla
    • Standard
    • Storyspace
    • Sunny
    • Sunny Dark
    • Tinderbox 7 (default v6-v7 and closest to colours matching colour names)
    • [user colour schemes in the user's 'color schemes' app support folder, if any, list at the end]

    The colour scheme format has been extended to accommodate a wider range of appearances. Experimental support has been added for colour schemes that use dark background colours, in part to determine how difficult this may prove. Tinderbox has always assumed that map and text panes had fairly light backgrounds, but there has clearly some interest in dark colour schemes, especially since the macOS 10.14 introduced a dark mode.

    'Modern' is the light mode default, replacing 'Standard' in older versions; in this scheme, the map background colour, and the colours 0-9, are slightly bluer. "Dark Coral' is the dark mode default. For those who do not primarily work in map view, the colours in 'Modern' may be hard to tell apart when only used for text or icons. In such circumstances

    For those with TBXs pre-dating v8 and who work in dark mode, applying 'Tinderbox 7' should give a better result. The issue this solves is that older colour schemes were not aware of the colours changed when toggling OS dark/light modes and so did not (re-)set some colours accordingly. All the schemes above have been updated to allow for this issue.

    When applying a new colour scheme, if the scheme changes $TextFont, notes that use the old (scheme's) text font will be changed to use the new scheme's text font.

    Attribute inheritance of preferences and settings

    Settings controlling the look or behaviour can be set at various levels. Consider something controlled at note level via an attribute. Working back up the inheritance chain, this is how the value may be derived, if not explicitly set at a given level. The lowest level (and the higher in the list below) at which a value is set dictates the value used at note level:

    - within the TBX:

    • Attribute value for this note
    • (Attribute) value inherited from a prototype
    • (Attribute) value inherited from a doc-level user-set default.
    • Value from Document Settings (i.e. this TBX only)

    - at the TBX creation

    • Value set via a user config.xml file
    • Value from Tinderbox built-in document defaults
    • macOS derived values (e.g. locale-based settings)

    The latter can, in some cases, be also be modified by the user editing configuration files, or at the extreme by modifying the app package's configuration files though this is not suggested!

    This inheritance model is explained in more detail under the Inheritance Cascade section.

    Objects in Tinderbox documents

    Tinderbox can open multiple documents. Each discrete document is saved as an individual TBX file.

    Within a Tinderbox document everything essentially consists of notes and links.

    At the document storage level, 'notes' are of 4 different types:

    In addition, the above may have other discrete functional characteristics such as an outline separator note, that are set via the object's attributes.

    More on the various special forms of note object:

    TBX Documents

    A Tinderbox document is a saved as a single file, with a '.tbx' extension, and thus are often referred to as 'TBX' documents.

    Tinderbox can create and save multiple TBX documents, limited only by storage space available. It can open multiple TBX documents at once, limited only by the host computer's resources. When Tinderbox is started, it will open any documents open when the app was last closed; this behaviour follows the host OS's System Preference/General 'Close windows when quitting an app', so may vary if that preference is changed.

    Tinderbox also tracks recently opened documents on a sub-menu of the File menu. If multiple documents are open, the application's Window menu list all open windows from all documents. The latter listing does not indicate the document to which each document belongs.

    Any non-default Document Settings and other customisations (link types, custom colours, user attributes, etc.) are stored in the TBX.

    A Tinderbox TBX document stores its data in XML format; for some users with XML skills this can provide another way to interface with, or view, the data. Users altering TBX documents by editing the XML source should note that such work is not formally supported as an editing method, i.e. do not expect that Tech Support will be able to fix user mistakes editing source XML.

    An open document can display one or more windows and tabs.

    See more on the XML structure of TBX documents.

    Notes & Containers

    A note is an element of a Tinderbox file and might be thought of as the 'atomic' entity of information within a Tinderbox file. However, a note is really the sum of its attributes. Most obvious of these are the title ($Name) and text ($Text) of the note, but in fact the state of virtually every aspect of a note is stored in an attribute.

    Every note (and agent, etc.) possesses every attribute defined in the document, much as a spreadsheet row possesses every column, or a pre-printed index card has a labelled box for each possible discrete input—regardless of whether the attribute/spreadsheet cell/index box is actually used. Indeed a note may be considered as a set of attributes, the majority of which can be viewed, and most edited.

    In initial use, the note's title and text are the most obvious (attribute-based) affordances you will alter but deeper use will introduce the user to all manner of attributes both system and user types.

    Notes are the basic units of writing and information in Tinderbox document. There is no fixed limit to the number of notes a Tinderbox document can handle; it can easily manage thousands, even tens of thousands of notes. At some point performance will become a limiting factor, but use of agents and rules is a bigger factor in performance than the sheer number of notes.

    A note may also act as a prototype for other notes.

    A note is edited via the text pane, which fills the right side of the default window layout when a note is selected in the (left-side) view pane. The text pane thus displays information about the currently selected note.

    Many other aspects of Tinderbox such as agents, separators and adornments are effectively just specialised forms of the basic note object.

    Notes are often referred to, or their location is described by, their Path within the canonical data outline used to store the document. That is also the outline used in Outline view.

    Any note containing other notes is also regarded as a 'container'; put another way, a container is any note that has children.

    Agents are a special class of container, as they create/control the aliases within themselves. Agents may not contain other notes, with the exception of adding adornments in map view

    Note Text

    Each note (including agents and adornments) has:

    • a title, i.e. the name of the note. This is stored as the $Name attribute of the note.
    • body text: stored as $Text. It is not necessary for a note to have any body text.
    • attributes: other pieces of information about the note. For instance the note's colour, size, position in the map, and whether it is exported or not.

    The equivalent of many pages of styled text and images can be fitted in a note's $Text, but notes are best kept short. Using less text per note also makes it easy to find exactly the desired content, and helps agents find specifically what they are seeking.

    A note is primarily text: it can contain many paragraphs, with colour, bold, italic and underline mark-ups, a choice of font as well. This content can also contain links to other notes or link out to web URLs. Embedded graphics in the text are also supported.

    Under the hood, Tinderbox files are XML allowing a good range of options when it comes to exporting text. HTML is especially easy as an output format, but the HTML export method can be used for pretty much any mark-up format (XML, PHP, OPML, etc.) as well as plain text and including web support text formats such as CSS.

    Note Attributes

    An Attribute has a name, a data type, a value (which may be preset to an optional default value). Some attributes are read-only, meaning they cannot be modified by the user; this is normally because such attributes are calculated on the fly (like the current number of child notes ). If no default value is set the attribute is empty/zero/false/etc., according to data type. There are two primary types of attributes:

    • System attributes: information built into all Tinderbox documents, such as the colour of the note, or its width and height. Tinderbox keeps this information about every note, and you may view, use, and change it.
    • User attributes: you may add your own attributes that are then available to every note. For instance, you could add a user attribute "Priority" and give every note a priority level from one to five. Or in a bibliography, create the attribute "Type" and tag the note for each source as either "Primary" or "Secondary".

    Additionally, system attributes may be:

    • Read-only attributes: information such as the date and time the note was created, or the date and time it was last modified, or its position within the overall document outline structure. Tinderbox keeps this information about every note, and you may view and use it, but you cannot change it.

    In Tinderbox all attributes are global in the sense that they exist and can be given a value for any note or agent, even if it might not be useful in a particular case. Just ignore attributes when they do not make sense. Put in database terms, Tinderbox implements one big table (flat file style), rather than a set of related tables.

    Note that whilst the document itself does not have an (accessible) $Text property, it does have attributes. Thus you can set some document level preferences. For instance, you can set the Map view's background colour through out the document by opening the Document Inspector's System tab and changing the $MapBackgroundColor attribute's default value.

    See here for a deeper discussion of the concept of note attributes.

    Special types of notes

    Although essentially notes, there are a few objects in a document that by design behave differently from normal notes.

    Adornments for Maps and Timelines

    An adornment is seen only in Map and Timeline views and is used to provide a means of adding visual elements to the background of the Map view. In a Timeline, adornments only draw if they have both a $StartDate and $EndDate. Note that Outline view has a rough equivalent in separator notes which are shown only in outlines and not other view types.

    As an adornment cannot be listed in an Outline, an agent cannot match or act on it.

    Although adornments are not listed in most other views like Outline, these objects do have attributes. To control details like the border width, select an adornment and either use the [Cmd]+[Opt]+[I] shortcut or select Get Info from its context menu to open the Info dialog. Most attributes are irrelevant for an adornment except those in the Map section.

    Note that adornments do get counted in the outline order numbering, even if not visible there; the are counted as the last sibling children of the note on whose Map view they appear (see a deeper explanation of this mechanism). This ensures the adornment always sit behind any notes on the map. Using 'send to back' on a note in Map view will not place it behind any adornments. However, if the map has more than one adornment it is still possible to use the sent forward/back commands to re-arrange the stacking order of adornments alone.

    As adornments (can—as 'smart' adornments) act as a form of container, they have support for Actions just like agents and container notes. As with a container note, the action string is stored in the $OnAdd attribute, and is triggered when a note or agent is dragged onto the adornment. A note being 'on' an adornment occurs if all or part of the note lies within the adornment's boundaries.

    Given their role in a map, adornments show their name but not $Text. Indeed, it is not generally useful to use adornment $Text, but it can be used as a form of hidden note.

    Adornments show their locked/sticky states with lock and push-pin icons (though only when the adornment is selected). The push-pin and lock icons are packaged separately in the application allowing custom icons to be added.

    A prototype can hold adornments—at its sub (container) level—though they will only be visible in map view of the prototype container.

    Adornments are discussed further under discussion of the Map view and Timeline view.

    Separators

    A note may be designated as a separator. A separator is drawn in outline view as a horizontal line. The note's name, if any, is shown centred in a box-out in the middle of the separator line. If the note has no Name value or it is "untitled' the separator shows as a solid line. For separators no duplicate name warning is given if the Name value is left blank. A note's status as a separator is held in $IsSeparator.

    Just as adornments are only visible in Map view, separators are only shown as separators in Outline view (and exceptionally in Treemaps). However, in all other views except Map view, a separator is visible as if a normal note. By the same token children of a separator are hidden in Map view, as their parent container is not drawn on the map. The latter can be a useful way to 'hide' content, either notes or containers, in a map without removing the content from the overall document.

    Note that separators were not originally designed to be able to be containers but rather like a (non-smart) adornment for separating groups of siblings in outline views. However, they can be containers; even agents may be a separator. Because of their possible container role, treemap views always show separators (as if they are normal notes). No note icon is shown for a separator note so the age/level of content/age cannot be judged although the separator is a fully functional note. In major views other than Outline and Map views, a separator is shown as a normal note.

    A separator can still have normal note features like a Rule and OnAdd action and become a container by having notes added to it.

    If data columns are enabled for the Outline view, separators still draw normally. Thus the data columns are not displayed for separator notes, unlike all other items in the outline.

    Even if not needed as a separator for Outline purposes, making a Map item into a separator can be a way of hiding it (temporarily) from Map view; note that when hidden like this it cannot be selected from the Map either. To make the item visible to the map it is necessary to find and select it in a view other than map and remove the separator status.

    Separators, but not adornments, are included in $SiblingOrder wheres both are included in $OutlineOrder. This makes sense when considering export is where SiblingOrder values are most regularly used and where adornments do not appear. See more on separators in a map vs. outline context.

    A separator can have inbound and outbound links. It can also have note text; in such cases Treemap views will show a 'dogear' symbol denoting text content.

    To designate a note as a separator, check the Separator checkbox in the Prototype sub-tab of the Properties Inspector set the value of $IsSeparator to true.

    Separator notes default to exporting as HTML (only) if either:

    • they contain both a title and have note text (i.e. have $Name and $Text values)

    …OR…

    • they contain child notes

    If exporting Separator notes with no text (i.e. with children) ensure either the template will link through to the child content or add a ^childLinks^ into the $Text of the separator note.

    Making a note into a separator does not alter any of its font-size related attributes but when drawing an outline view Tinderbox draws separator titles very slightly smaller than for normal notes. Likely this is done so as not to expand line height, i.e. allowing for the box around the separator title. This effect is more noticeable as zoom level is decreased.

    Duplicated separators retain their original name rather than receive the name suffix " copy" making it easier to clone unnamed separators.

    Separators do not appear in hyperbolic view or in the attribute browser.

    Prototype notes

    Any note can be made into a prototype. This includes container notes, adornments and agents.

    Export Template notes

    Formatted export from Tinderbox, such as to HTML, is controlled via templates containing export code. These code templates are stored in ordinary notes that have been marked as templates ($IsTemplate is true).

    Template notes are stored in a 'Templates' container at root of the document. This container does not exist in a new Tinderbox document, as some users may never use export features. Adding a built-in template will result in the container being added and is the easiest way to set this up.

    Containers

    Any notes containing other notes, i.e. in outline terms having child notes, is considered a 'container.' At the most trivial level this allows notes to be nested inside other notes. For instance, a 'Section' container might contain a series of 'Chapter' notes.

    Containers are most useful for structured projects that will mostly be viewed in outline or chart view. In map view, only sibling notes within a a single container are visible on the map. Containers on the current map draw a 'viewport' showing a part of its child map.

    Agents are a special class of container, as their children consist of an alias to every note matching the query stored in their $AgentQuery attribute.

    Adornments (map view only) are not strictly containers but act like containers in that they have OnAdd and OnRemove actions and support the inside() action query.

    Notes as agents

    An agent is a container note that is a persistent search query. It creates/holds an alias for every note/agent/etc. object that matches the agent's query.

    Like other notes, agents can have actions like rules, edicts and On Add, though for agents the latter is called the Agent action.

    Agents are discussed in more detail here.

    Creating notes and agents

    Normal notes, special types of notes (adornments, separators, composites) and agents can be created in a variety of ways:

    Aliases are discussed here.

    Creating via keystroke

    Only normal notes or agents can be created via a keystroke (shortcut):

    Note:

    • Return key (). In most view pane view types except report type views (Attribute Browser, Crosstabs, etc.), pressing Return will add a new note to the document as the next item in sibling/outline order.
    • Shift+Return (+). In Outline and Chart views, this will result in the new note being created as a child of the currently selected note. If the selected note already has children, it is added as the last child of the container.
    • Option+Shift+Return (+). In Outline and Chart views, this will result in the new note being created as a child of the currently selected note. If the selected note already has children, it is added as the first child of the container.

    Agent:

    • Command+Shift+A (++A). This adds a new agent to the document as the next item in sibling/outline order.

    Creating via menus

    Various menus can be used to make a variety of note types and agents.

    Note menu:

    • Create Note. (keyboard alternative)
    • Create Agent. (keyboard alternative)
    • Create Agent As Child. The agent is generated as a child of the current note/container. Note: agents cannot be nested.
    • Create Separator (Outline view only) / Create Adornment (Map view only)
    • Add Composite (Map view only). Adds a new composite from those available in the current document.

    View context menu (i.e. right-click), when no note is selected:

    • Create Note. (keyboard alternative)
    • Create Agent. (keyboard alternative)
    • Create Agent As Child. The agent is generated as a child of the current note/container. Note: agents cannot be nested.
    • Create Separator (Outline view only) / Create Adornment (Map view only)
    • Create Composite (Map view only). Adds a new composite from those available in the current document.

    Other creation methods

    Notes and agents can be generated in a number of other ways.

    Drag-drop or Paste image adornments (Map view only). See more.

    Attributes (via Displayed Attributes, Inspector, Get Info or an action)

    • Separators. $IsSeparator toggles a note between normal and separator. Separators appear in outline view only and are hidden in all other views.
    • Smart Adornments. Setting a query in an adornment's $AgentQuery makes it into a smart adornment; removing the query switches back to normal adornment behaviour.
    • Timeline adornments. Setting $StartDate (and $EndDate) will make an adornment show in a relevantly-scoped Timeline view as well as in a Map.

    Action code:

    AppleScript. See more on Tinderbox AppleScript methods

    Deleting notes and agents

    The most normal methods of deletion are:

    • Keyboard. Use the (backspace) Delete key (⌫) with one or more selected items.
    • Edit menu. Use the Delete option.
    • Action code. Use the delete() operator.
    • AppleScript. See here.

    Aliases

    Making an alias to a note allows a note to be placed (i.e. appear) in more than one location in a Tinderbox document, just like an alias in macOS. The original note can be in one place in the hierarchy whilst the alias can be somewhere else entirely. Both the original note and the alias give access to the content of the note: the same $Text, the same attributes, and so on; see notes below re intrinsic attributes. An original and its alias(es) can share the same container/map, though normally will be in different ones.

    A note can have many aliases, or none. Aliases are a flexible way for organising notes in ways that a simple Outline-style hierarchy does not permit.

    An alias will always have the same name as the original. Change the name of either the alias or the original, and both will change.

    • The name of an alias will appear in italics in all views (more re this further below). Due to limitations in some fonts, there is a (non-default) Document Settings option to underline alias titles instead.
    • A copy of any alias does not take the suffix ' copy', but retains the same $Name as its original note.
    • An alias cannot contain children/descendants, but those of the original can be queried via its aliases (e.g. in an agent). In agent queries aliases assume their original's descendants for purposes of matching.
    • Selecting an alias populates the text pane with the original note (except for intrinsic attributes)of the original note.
    • Intrinsic attributes are those attributes for which an alias can have a discrete value differing from the original (more & listing), for example map position and icon size.
    • Editing the attributes of an alias actually edits the attributes of the original note (except for intrinsic attributes).
    • Deleting an alias removes just that alias: the original and any other aliases are unaffected.
    • Deleting an alias in an agent will cause the alias to be recreated as long as the original (or another alias) continues to match the agent query.
    • Moving an alias out of an agent effectively duplicates the alias as the agent will recreate its now-missing child alias (see above).
    • Original and alias share outbound text links (outbound internal and web links within $Text). All other inbound/outbound basic links are individual to the original or alias.
    • Deleting the original note automatically deletes all its aliases; deleting an alias has no effect on the original. Any in/outbound links affected are also deleted.
    • in Map views, aliases of containers are drawn in normal container style (i.e. title bar at the top) and show the viewport map:
      • if in the same map as the original: same as seen in the original (i.e. with any child objects). Although the alias has intrinsic height and width, the size/scroll state of the originals map is reflected in the alias.
      • if on a different map from the original: the viewport is drawn but is blank.
    • in Map views, regardless of the map on which the alias resides (same or different from the original), drilling down into an alias' map container results in the view shifting to the map of the original container—i.e. shift of context.

    Creating an alias

    If you are in a view window, first select the correct note with the arrow tool. The new alias is inserted immediately after ($OutlineOrder) the source item; noting both have the same title, it is the new alias that is now selected (the styling of the title should indicate this is the alias). There are several methods:

    • choose Make Alias from the Edit menu
    • press Cmd-L (L).

    Drag from Find. A further method is to drag an item from a Find results pop-up/tear-off into the view pane. In this method the alias is placed at the drop point (Map) or closest insertion point in other view types.

    Newly-created aliases in map view take their height and width from that of their original note, and are placed on the map to the right of their source item (assuming there is suitable free space, the alias is otherwise placed to avoid overlapping/compositing with another note).

    Once created, the alias can be moved anywhere in the current document.

    Agents. Another method of making aliases is to create an agent as that will create aliases for any notes matching the agent query. Aliases can then be dragged elsewhere, in which case the agent wiil spawn a new child alias as the source note still matches the query.

    Exporting

    When exporting, aliases also behave as if their original note's children were their own children. Aliases are exported as separate pages in the appropriate location within the output. This makes it easier to use web links to alias content that point to the right place. It also helps when web output uses a hierarchical navigation system as with aTbRef.

    When including children that are aliases such as when using ^children^ and ^descendants^, items that happen to be aliases are included as aliases (so reflecting intrinsic attribute values). Since for most purposes the alias and its original are interchangeable, this seldom affects export. However, intrinsic properties of the alias are exportable (and may differ from those of the original).

    Reflecting the way aliases are treated as separate entities in an export context, basic links to or from aliases belong to those aliases and they support their own Roadmap view and Browse Links windows. However, the links() action code cannot currently address aliases as a destination object so analysis of links to/from an alias is best done visually or by means of Roadmap view. Originals and aliases export their own basic links (i.e. aliases can differ), but if an alias has no in/outbound basic links it will export those of the original. In the latter case the alias will show no basic links internally, e.g. in Roadmap view, but on export will inherit its original's basic links.

    Text links as well as basic links are generated from exported aliases; the destination of the link is the same regardless of whether the source is the original or an alias. An alias can never have $Text/text links that differ from that of its original: that is fundamental of the point of it being an alias.

    Copying aliases

    Any alias can also be copied or aliased. However, do note that when copying/aliasing an existing alias the new alias is created as if being made from the alias's original though it uses the original's attributes rather than the source alias' intrinsic attributes. Likewise, the source alias' discrete basic links are not copied, i.e. the new alias will start with no basic links. In short you cannot make a copy of an alias that maintains the intrinsic differences of the source alias from the original. Aliases cannot be copied outside their current document, as another TBX will not hold the original of the (alias) note being copied. An alias needs to point to its original for many of its attribute values so the two must reside in the same document.

    Identifying aliases in queries

    The $IsAlias attribute can help with identifying whether a note is an alias or note. This is especially helpful within agents where all matches are aliases, regardless of the type of note being matched.

    The $Container attribute is worthy of note as this means the 'parent' designator value of an alias does not equal that of the original note. This becomes important in agent actions where the acted-on note is an alias. It is thus often necessary to use syntax like $Name(parent(original), i.e. the name of the original note's parent container, rather than $Name(parent). In an agent action the latter code returns the name of the agent. Incidentally, in the last scenario $Name(parent) and $Name(agent) would both return the name of the Features needing more recent OS versions (more on the 'Link type honouring operators', 'original' and 'parent' designators).

    Finding and counting aliases

    Normally, the need it to reduce the number of matches but in some cases the opposite is needed: to find and/or count all the aliases of a note. The simplest method is to look at $Aliases for a given note. This is List of the paths of all aliases of the original note. Thus $Aliases.count gives the number of aliases of that note.

    Another approach is using find(). An agent query de-duplicates matches, weeding duplicates and always taking an original over an alias. In contrast find() returns the (paths of) all matching objects, original and aliases. If there is no other scoping query term, find().count returns a count 1 larger than $Aliases.count, i.e. 1 original plus count of all aliases.

    If the need is to find or count aliases within a defined part of the outline, or sharing some common attribute value(s), then find() is the best approach. Remember to add the query term '& $IsAlias' (i.e. $IsAlais is true, the item is an alias) to ensure any match to the original is filtered out. The returned find() list's size can then be checked for a count.

    Aliases render in italics

    In any major view aliases are always drawn with their title ($DisplayName) in italics. There is no way to make an alias be titled in normal type; this is by design, mirroring how the Mac's OSs have shown aliases. One result of this is that when older, pre-v6, TBXs are opened in v6+ they may not render aliases in italics: see more. There is a document setting to also underline alias titles, although they still render in italics (if possible).

    Link counts and aliases

    $InboundLinkCount and $OutboundLinkCount are intrinsic and report separate values for the alias and original note, those they may often be the same (outbound text links are always the same for original and alias).

    Word counts

    Word counts in Get Info/info pane do not include the $Text word counts of alias notes, just the count of the original $Text.

    Composites

    A composite is a group of Tinderbox notes that work together to describe something larger than themselves. For example, when taking notes (in Map view) in a conference, an individual talk might be a composite of notes for the title, the speaker, the content of the talk, and action items requiring follow-up action. Each note has its own text and attributes, but it may sometimes be useful to treat the composite as an object – for example, to move all the notes in the composite to a new map location. Further examples of usage, as envisaged by Eastgate, include the following (giving in parentheses the items the composite might contain):

    • shopping lists (a store, followed by one or more things you want to buy)
    • books (author, title, reading notes, editorial notes on the review we will write)
    • lesson plans (date, topic, assignment, homework, special requirements)
    • restaurant visits for a reviewer (name, phone, hours, credit card info, who dined with you, what you ate, when the review is due)

    Composites are a feature primarily intended for map view use and Tinderbox notes form a composite when their map icon touches another note. Composites make it possible to make compound notes which have individual identities but also are linked to their collaborators in a new (visual) way.

    Some built-in composites can be created from the File menu. This creates a root level 'Composites' container. User-created composites can be added to the container (see instructions). Any composite in this container can be used to create a new copy by choosing Create Composite from the Note menu or the map background's contextual menu.

    When selected, composites are outlined with a darker and thicker bounding box. The composite name and edit widget (a little pen icon at top left of the bounding box) are also displayed when the composite is selected. To (re-)name the composite, click the pen symbol: a pop-up naming box appears over the windows text pane. Enter the desired name for the composite and press the Return key to set and save the new name.

    Clicking on any note within a composite selects the composite; clicking on non-note space within the composite's bounding box does not select the composite. Cmd+click to select individual note(s) within a composite. To edit an individual note, or to see only its text and Displayed Attributes, the note must be individually selected. When a composite is selected the resize handles are not drawn on the individual constituent notes.

    Edit ▸ Break Composite can be used to break up a composite into individual components. Individual notes can be removed from a composite by (Cmd+click) selecting it and dragging it away from the other notes. When using ⌘-drag to remove a note from a composite, the note is removed from the composite immediately. (Previously, it was removed from the composite at mouse-up. The new approach makes the effect of ⌘-drag more clear.)

    When a composite is selected, the text pane displays the text from each member of the composite, as for multiple selections. Composites may have a name. When any item in a composite is selected, the name of the composite is shown above the composite, along with a control widget that allows you to rename the composite.

    When a note joins a composite, its moves in the outline to become the younger sibling of the last member of the composite. Thus, all members of a composite are adjacent in outline order. The relative order of items within a composite should remain unchanged.

    Further composite features:

    See here.

    Automating Tinderbox

    To get an idea how Tinderbox works, it is useful to have some idea as to the main sorts of objects found in a Tinderbox data file, and the concepts behind their use:

    Concepts

    This section contains:

    Windows, Tabs & Views

    A Tinderbox (TBX) document has a single two-paned document window by default, with two tabs. Your work in Tinderbox takes place in one of the two main panes of a document window, the View pane and the Text pane:

    • The View pane (left-hand pane) depicts some, or all, of the document's notes using one of a variety of view (visualisations) types. The View pane represents what were stand-alone windows termed a 'main view' pre-v6; these are now simply the view pane's content visualisation options. There are a number of types of view used by the view pane, as listed here.
    • The Text pane (right-hand) represents the note's pre-v6 text window. It holds the note title, optional Displayed Attributes, and the note's text ($Text). Alternate sub-tabs of this pane show the raw mark-up of the note as exported via HTML (marked-up) Export and the same in web browser preview form.

    Some View pane views show only a narrow context, e.g. Map view, whilst others (by default) show the document's full hierarchical structure such as Outline, Chart or Treemap views.

    All new document windows always have a Map view (tab #1, selected by default) and Outline (tab #2). However, users are free to use as many or as few view types as their work or particular projects demand. Not all users will need to use every view type.

    A small number of the 'secondary' views and windows from earlier Tinderbox designs have become pop-over dialogs (and thus essentially modal); a few such pop-overs 'torn off' text windows can be created, by dragging them to become stand-alone windows. Pop-overs offering this affordance do so with a double rectangle icon in their top right corner. Stand alone text windows show the contents of a note's Displayed Attributes and $Text, but lack some text pane affordances such as the link well, title bar and Preview/HTML tabs.

    Multiple document windows may be open while working in Tinderbox as well as torn-off windows and the Inspector. They can show the same or different parts of your document. It is also possible have multiple windows open for more than one TBX document. Thus, if more than one document is open at a time, the windows from each/every document are be open at the same time. This can be useful when trying out new code techniques, to avoid doing potentially disruptive tests on a primary work document.

    Hierarchy of Content

    A Tinderbox document has two basic kinds of structure: one is the structure formed by links between notes. The other is the hierarchical structure of the document. A Tinderbox note can contain other notes, which can contain other notes, and so on. The notes can thought of this as chapters containing sections containing divisions; or topics containing sub-topics; or in any way that fits the user's workflow.

    In the image for this article, the 'MyString' column shows the relevant designator (in correct case-sensitive form). Note that designators are case-sensitive when used in export/action code; by convention designators are normally not quoted in action code, although they are strings. The OutlineDepth column shows the $OutlineDepth for each note (1 being root level).

    IMPORTANT: inheritance of attribute values (e.g. via prototypes) is not a feature of hierarchy. Put another way, a child note does not automatically inherit all its parent's customisation: that may be made to happen but will require the user to add some action code.

    Several terms are used to describe relationships within a hierarchy:

    • parent: the item one level up. A parent note contains one or more child notes (children), and thus contains one or more levels of sub-notes. A parent note may also be referred to as a 'container' as it contains other notes. ('parent' designator)
    • sibling: an item that has the same parent. ('firstSibling', 'prevSibling', 'nextSibling', 'lastSibling' designators). The group designator siblings means all items with the same parent as the current item.
    • child: an item one level down. In Tinderbox, when a note contains other notes, those notes are its children. A child note is thus any note that has a parent note, i.e. it is not a top level note. ('child', 'lastChild', 'randomChild', 'previous' (child), 'next' (child), Nth child (zero-based) 'child[N]' designators).
    • descendant: a child, or a child of a child, and so on, of the current note.
    • ancestor: a parent, or a parent of a parent, and so on, of the current note.
    • grandparent: specifically the parent of a note's parent. ('grandparent' designator)
    • root: an item that has no parent. In a Tinderbox document, the document as a whole is the root: it contains the top-level notes, and nothing contains it. Root level notes have $OutlineDepth of 1. Root is not used as a designator but does have a role in export code: see ^root^.
    • cover: the first root level sibling. Thus, if there is more than one root-level note, the cover is the oldest sibling. ('cover' designator). This is little used in Tinderbox and has more purpose in its sibling program Storyspace.
    • original. The note upon which an alias is based. ('original' designator)
    • this and current. These generally mean the same thing. 'this' applies to the currently selected item; where transclusion is used (e.g. during export, see ^include^) current applies to the note in current scope of evaluation.
    • agent. This is a method for agent queries to refer to the agent's attribute values and for aliases to refer to their parent agent in agent actions. ('agent' designator)
    • adornment. Not illustrated, as only used in map view. It fulfils the same role as 'agent' in adornments and smart adornments ('adornment' designator)
    • ID. Not a hierarchical element, but an item's $ID value (a 10-digit number) can be used as a designator.

    Not illustrated: item-scope designators: 'that' and 'find()'.

    There are several group terms to describe Tinderbox notes:

    • all: all notes in the current TBX file. ('all' designator)
    • ancestors: all ancestors. ('ancestors' designator)
    • children: all children. ('children' designator)
    • descendants: all descendants, i.e. all children and their children. ('descendants' designator)
    • siblings: all siblings. ('siblings' designator)

    Any note containing other notes is a 'container'; put another way, a container is any note that has children/descendants. Agents are a special class of container, holding an alias to every note matching the query stored in their $AgentQuery attribute. Map adornments are not containers. Though not originally intended as such, outline separators can be used as containers.

    Paths

    ) evaluated resultTinderbox allows you to identify notes by relative or absolute paths, not just name. If a tag's request matches neither a keyword nor a note, Tinderbox tries to interpret it as a path. For example:

    /news …is the top-level note named "news"
    /news/Iraq …is the note named "Iraq", inside the top-level note "news"
    ../Chicago …is the note named "Chicago" that is a sibling of this note
    ../.. …is the grandparent of this note.

    Using paths implies:

    • knowledge of the Tinderbox document's outline structure
    • where in the outline that named notes are used
    • that the outline will not change.

    If a note name contains a forward slash, as in 'Large/Medium', then the path must be enclosed with quotes, e.g. Large/Medium should be cited as "Large/Medium". A deprecated legacy alternate is to escape the slash by a preceding backslash, e.g. Large\/Medium. Doing otherwise, the backslash is treated as part of a path, i.e. is a container delimiter.

    A path beginning with a / is always a (complete) absolute path down from a top-level note (though it need not be the cover if there is more than one top level note). Relative paths start with ../ (i.e. period+period+slash). A path not starting with either of these will result in Tinderbox treating the proffered string as a single note name.

    Quoting of Paths

    Historically paths were not quoted where used in Tinderbox code, and thus may be omitted in many older code examples you find. However, users should switch to quoting paths as they are string literals. Past convention in code examples is to quote paths in action code but not in export code, but this largely reflects past usage and should not prompt current users to omit quotes.

    An exception to quoting paths occurs, where a path argument is actually an action code expression or an attribute name. A simpler way to view this is that quote enclosing a string of text is to say to Tinderbox, "This is just text. Do not try interpreting any control/code characters found within it", i.e. string literal.

    Using Path arguments in Tinderbox

    Many operators and codes in Tinderbox that allow a note name as an argument also allow a 'path' to be used. All attributes can also take a path argument, allowing code to refer to an attribute from some other note.

    For new users, figuring out paths can be a bit confusing. But firstly, why might a path argument needed? If a note name is not unique across the whole TBX document, then when Tinderbox finds a code mentioning that name, it will use the first matching note as found by $OutlineOrder. So, using a path rather than a note name can help identify exactly to which note you wish to refer. Consider using paths explicitly if:

    • Your document deliberately does not use unique note names
    • It may be that names may not remain unique over the life of the document.

    That's the 'why', but how do you refer to a note using a path? To investigate this consider the following TBX outline:

      First Root
        Child A
          Sibling A1
          Sibling A2
        Child Z
      Second Root
        Child A
          Sibling A1
        Child B
          Sibling B1
          Sibling B2
        Child C/D
          Child of D

    In this demo, you will note that there are some duplicate note names. For the examples below, to help give starters code such as they might use for real, the examples are written as if referring to a value of the system attribute 'Created'.

    Note name (i.e. no path)

    Just use the note name on its own:

    $Created(Child B) 
    $Created(Child A) 
    $Created("Child C/D") 
    $Created("/Second Root") N.B. need for root slash

    Notes:

    • note name will not suffice if you want to reach the 'Child A' in 'Second Root'. The note of the same name within 'First Root' will always get called.
    • any paths (or just note names) with forward slashes must be 'escaped' by quoting the whole string.
    • citing root-level note names must include a slash prefix, i.e. when the $Name is the $Path—or rather the $Path is "/"+$Name . See also notes on partial paths further below.
    • there is still legacy support for the now deprecated old usage of preceding (/) slashes in paths with a backslash (\) character.

    Ways to view a note's path

    The clearest way is to view $Path data but various views offer ways to see all or part of the path:

    • hoisted views show a 'breadcrumb' trail indicating ancestor container, and thus the path to notes in the current view.
    • Outline, Chart and (albeit less obviously) Treemap views allow the (ancestor) path to be viewed. In the case of Outline and Chart it may involve expanding the outline branch holding the current note. In the case of the treemap it is a case of spotting the nested containers.
    • Text pane. Holding the cursor over the note name results in a tooltip showing the full path of the note. This is useful when a $Name is not unique within the document.

    Paths from Attribute Values

    A path may be supplied as an attribute to address an attribute of another note than the current one.

    $Text($MyPath) 

    …where $MyPath is a user attribute holding a path.

    Paths from Action Code

    Path may also be supplied in the form of action code such a string concatenation or simple arithmetic:

    $Text('"/Tasks/"+(1+2)') 

    …would collect the $Text of a note named "3" at path /Tasks/3.

    Paths with Designators

    Most Tinderbox designators can use a path to refer to a different context. For example in action or export code use:

    min(child("/some/other map note",$Xpos) 
    ^min(child("/some/other map note",$Xpos)^ 

    Paths with nested designators: it is possible to cite an offset combining designators.

      ancestor
        Examples
          A
            1
            2
          Aliases
            A
      another
        More
          B
            3

    For the alias A

    $Container(this) is "Aliases"
    $Container(original) is "Examples"

    The designator parent(original) will give the parent of the original -- the parent of Examples, So $Container(parent(original)) is "ancestor".

    The designator original(parent) will give the original of the parent -- "Aliases". So $Container(original(parent)) is "another".

    Thus nested designators like this tend to be written as spoken: the 'parent of the original' being parent(original).

    Other ways to identify a note other than via its path

    The $Path attribute holds the note's path. For unique note titles the title alone ($Name) can be used as a proxy for the path in many cases. A robust but less human-readable path alternate (but accurate) is to use $ID or the newer $IDString. The latter can be useful if the $Path data contains problematic characters like a forward slash in any note title in the path.

    Further notes on Paths

    See here:

    Absolute Paths

    With an absolute (or 'full') path you are stating the full and exact path within the Tinderbox document. These are absolute paths:

    $Created(/First Root/Child A/Sibling A1) 
    $Created("/Second Root/Child C/D/Child of D") 

    Points to note:

    • there can be more than one root (top level note) but regardless the path always begins with a slash (/) and the name of a root note.
    • every note from the root to the destination note is included in the path, divided with a forward slash.
    • the path does not end in a slash character.
    • the path may contain spaces but does not needed to be enclosed in single quotes, although for consistency it may be a good idea to quote. Since v4.6, syntax has been moving towards explicit quoting of all strings.
    • any path containing forward slashes must be enclosed in quotes.

    Absolute paths are not a big deal in a small document like the example, but if it is a big TBX with deep nesting, you will want to consider using relative paths.

    Relative Paths

    The basic rules are roughly the same as for absolute paths:

    • the relative path always begins with a dot-dot-slash (../)
    • navigating upwards, a dot-dot-slash is used for every level of outline traversed.
    • navigating downward use the name of the notes working down from that point divided with a forward slash between each nested container's name.
    • the path does not end in a slash character.
    • the path may contain spaces but does not needed to be enclosed in single quotes, although for consistency it may be a good idea to quote. Since v4.6, syntax has been moving towards explicit quoting of all strings.
    • any path containing forward slashes must be enclosed in quotes.

    For the following example assume the currently selected note is 'Child B' within 'Second Root'.

    $Created(../Child A) 
    $Created(../../First Root/Child A) 
    $Created("../Child C/D/Child of D") 

    A relative call from Sibling B2 to its grandparent (Second Root) would be:

    $Created(../../Second Root) 

    The above examples show two subtle points to note about relative paths:

    *to access a sibling (or its children) you must go 'up and back' to the current note's parent. You cannot call a sibling by using its name with no slash prefix.

    *when accessing notes under a different root, you must navigate to a level above the root note (effectively the document itself) before you navigate downwards.

    If you are used to UNIX file navigation, note the absence of the dot '.' method. Also, if you are used to HTML relative links, note the 'up and back' method of navigation: you cannot cite a sub-folder or sibling simply by using its name (without a preceding slash). So some slight variance from what some more expert users may intuit but the usage is consistent within Tinderbox and not difficult to learn.

    Uniqueness, duplicates and matching notes

    Does a note (agent, etc.) need to have a unique title ($Name)?

    No, though usually unique, an object's title ($Name) is not required to be unique. Same-titled objects will have different a $Path path, unless they are in the same container. Even then, all objects (including aliases) have a discrete $ID enabling duplicate objects to be addressed discretely.

    Be aware that generally, that when using code with attributes using an offset address argument, most users only employ an object's $Name and this is apparent in most code examples found in the forums and in this resource.

    Is is possible to test for duplicated titles?

    Yes, by using isDuplicateName(). For instance a stamp with code:

    $MyBoolean = isDuplicateName($Name); 

    … when applied to one or more objects will set $MyBoolean to true for any object whose $Name is not unique. The scope of the test is always the whole document.

    Are there any $Name values to avoid duplicating?

    Yes. A number of build-in features—when used—generate root-level containers: prototypes, (export) templates, composites, and hints. It is a good idea to avoid duplicating these features' default containers, indeed all sub-containers within '/Hints'. If it is necessary to duplicate any of these containers (and at root level) ensure the built-in feature generated one is first by outline order ($OutlineOrder).

    How do duplicate titles affect queries and finds?

    Duplicate-titled notes have no effect on queries which will generate an alias (agent) or path (find()) for each discrete note, even if the duplicate-titled notes are in the same container. It is not documented but it may be because the duplicates are resolved using $ID or $IDString which will be unique for each note. Note that whilst a find() uses a query, like an agent, the difference is that a find() does not weed out matches aliases whereas an agent does so..

    How do duplicate titles affect queries and finds?

    When referring to another note via its $Name as an attribute argument, e.g. $MyString("Some note"), if there is more than one match the resulting action(s) will be carried out only on the first match by outline order ($OutlineOrder). Thus if the $Name matches 3 discrete notes, the action will occur three times on the first matched not and not once each on each matched note. This issue can be countered in part by using $Path rather than $Name for the argument. If the matches are duplicates within a single container, only $ID can be used to ensure every match note is acted on by the action.

    Summary

    It can be seen that actions—including agent actions—rather than queries that are affected badly by notes with a common name. If document's subject requires the existence of duplicate note titles, extra care should be taken in how actions are addressed to the corrected note(s).

    Attributes

    Many aspects of Tinderbox are set and stored by using attributes, such as a note's name, the colour of its icon in a Map view, etc. Attributes apply to every note (including special notes like separators and adornments) and agents.

    An Attribute has a case-sensitive name, a value type, a value and an optional default value. Some attributes are read-only, meaning they cannot be modified by the user. If no default value is set the attribute is empty/zero/false/etc., according to data type. There are two primary types of attributes:

    • System attributes: information built into all Tinderbox documents, such as the colour of the note, or its width and height. Tinderbox keeps this information about every note, and you may view, use, and change it. Some system attribute properties can be altered via the Document Inspector System tab.
    • User attributes: you may add your own attributes that every note will have. For instance, you could add the attribute "Priority" and give every note a priority level from one to five. Or, in a bibliography create the attribute "Type" and tag the note for each source as either "Primary" or "Secondary". More on naming attributes. Some user attribute properties can be altered via the Document Inspector User tab.

    Additionally, system attributes may be:

    • Read-only attributes: information such as the date and time the note was created, or the date and time it was last modified. Tinderbox keeps this information about every note, and you may view and use it, but you cannot change it.
    • Added to by new Tinderbox versions. At creation of a new TBX document, Tinderbox adds all the currently defined system system attributes with their existing properties, default values, etc.

    **Opening the document in later releases will add any 'missing' system attributes added to the roster since the originating (or last-used version). These new attributes use current defaults.

    • NOTE: pre-existing attribute defaults are not updated. Even if the newer Tinderbox version has different defaults to those in a pre-existing document, these are not updated. It is down to the user to update these if required. Changes to system attributes (if documented) are reflected in aTbRef's listing of system attributes where the current default is given.
    • reference derived values. Some System attributes will have a default value which is set via preferences in Document Settings and inherited from there (unless inheritance is broken by manually setting a default in the System Attributes Inspector)

    The two primary attribute listings, General and User, and their data types, etc., are covered in more detail in the Attributes section and all General attributes are described system attribute list. Values used by attributes are often inherited. There are also naming rules for attributes.

    In Tinderbox all attributes are global in the sense that they exist and can be given a value for any note or agent, even if it might not be useful in a particular case. Just ignore attributes when they do not make sense. Put in database terms, Tinderbox implements one big table (flat file style), rather than a set of related tables.

    The attributes of TBX document are set at document creation by Tinderbox and may be altered via the Document Inspector's System tab, though some can also be set via Document Settings. Thus you can set the Map view's background colour by opening the document's Info view and changing the $MapBackgroundColor attribute; be aware changing this attribute only affects the document if the current 'item' is the document and not a note, i.e. no note is currently selected.

    In Action code, attribute values are referred to in Tinderbox attribute coding by using a '$' prefix, e.g. $Color returns the _value_ for the attribute 'Color' (i.e. the note's colour in the view pane). By general informal usage, the Tinderbox community will also use (misuse!) the $-prefix in general writing to make explicit they are talking about a the name of an attribute. Thus "See the $Name of…" or "You can use the $Height…" where in both cases the context implies that "$X" means the "the attribute named X". This latter convention is used in aTbRef.

    There are a variety of methods for editing attribute values.

    Give consideration to naming attributes in a manner that matches Tinderbox's assumptions. If attribute names are wrong, either due to import or because they were created before reading the notes on naming styles, attributes can be renamed.

    Attributes all have one of a number of data types.

    Attribute use in the context of automation ('coding') in Tinderbox is discussed in detail under Use of Attributes.

    See also:

    Offset addressing or referencing of attributes

    Much activity in Tinderbox, whether internal to the app or as the result of user interaction, involves reading data from attributes or writing data to them. Most often, this involves attributes in the note currently selected (visibly or with focus during automation).

    However, sometimes it is necessary to interact with an attribute of another, different note. In aTbRef this is referred to as 'offset' addressing, i.e. the target is set elsewhere than current focus. Why might an offset be needed? Some examples are:

    • addressing notes in the outline hierarchy, e.g. a notes parent, child or sibling. In many cases these use designators. So: $Color = $Color(parent); sets $Color of the current note to that of its container (its parent as seen in Outline or chart view)
    • addressing notes at a given path, e.g. when looping though a list of stored paths in automation. So: $Color = $Color(/path/to/some/note); sets $Color of the current note to that of the note 'note' at the path specified.
    • addressing the location of a stored value being used as a global constant, as in the pattern of using a single note to store values needed during automation. So: $Color = $Color("Config-note"); sets $Color of the current note to that of the note with the unique title ($Name) of 'Config-note'. See more on 'config' type notes.

    Regardless the terms 'offset addressing', offset referencing' and 'attribute referencing' all mean the same thing, i.e. addressing—or read or write—the attribute is a non-current note.

    Prototypes

    Prototypes are a method to let a single note specify the default value for an entire class of notes. This is achieved by specifying an existing note as the prototype, via the $IsPrototype attribute; this tells Tinderbox to use the prototype's values for the all the notes set to use that prototype. The easiest way to make a note a prototype is via the Properties Inspector's Prototype tab.

    Attribute inheritance

    See also: Inheritance of attribute values.

    Whenever Tinderbox uses a prototype it will re-use an attribute value from the prototype for its own attributes unless the attribute is specifically set for that note (by action or manual edit). Such manual edits break inheritance (for that attribute only) but inheritance can be reset. There are some special mechanisms for disabling action inheritance.

    When you change an attribute in a prototype, you change it for the notes that use that prototype. A note inherits all attributes from its prototype except for intrinsic attributes. Prototypes are not a necessary feature for everyday use but they can powerful time-savers for complex projects. Indeed, any large or long term Tinderbox project is likely to benefit for judicious use of prototypes.

    As well as normal notes, an agent or adornment may be a prototype, but setting a normal note to use either of those will note change the nature of the note; it will simply use the customisations it can so, for example an agent query would be ignored. Nonetheless if making large use of agents or adornments, prototypes can speed their configuration.With agents, ideally the prototype should not have a query set though Tinderbox will cope with such a configuration. The Rule and Display Expression disabling attributes can help by ensuring things like self-resetting rules only run in non-prototype notes.

    If a note or agent is copied and pasted to a different document, the new item does not inherit its source's $Prototype value. This is a defensive assumption by Tinderbox as it cannot be sure pasted notes are from the current TBX and thus that all source prototypes exist. When creating 'template' type notes/containers bear this in mind. Think about using an agent to help set prototype values directly or indirectly via rules and actions. The |= operator can be used to ensure actions occur once only.

    Inheritance of Text

    When a note’s prototype is set or changed, the note copies the prototype’s text ($Text) if the note has none, or if the text it inherited from its former prototype has not been changed.

    Inheritance of Text links

    If the prototype's $Text contains any text links, these are inherited when $Text is inherited (as described above)

    Prototypes bequeathing child notes

    Prototypes can have children that are created/added to a note if that prototype is applied, described in Tinderbox as 'bequeathing' notes—see more.

    Built-in Prototypes

    Tinderbox makes it easy to experiment with prototypes as a number of simple generic ones are predefined and built-in, noting that a few of these—such as for notes in DEVONthink watch folders—are added as-needed by the app and are not available for manual insertion via the File menu.

    See more:

    Setting prototypes

    There are many ways to set prototypes, many using the prototype pop-up menu:

    • View pane:
      • Outline or Chart view. Right click icon of selected item(s), select from pop-up menu
      • Map view. Right click prototype tab of selected item(s), select from pop-up menu.
    • Text pane. Edit the $Prototype attribute displayed as a displayed attribute.
    • Properties Inspector, Prototype sub-tab. A tick-box is available to set prototype status.
    • Properties Inspector, Quickstamp sub-tab. Select one or more items. Either:
      • Type all or part of the attribute name. If part, pick a completion from the pop-up auto-complete list. Press Return (↩) top populate the relevant Group and Attribute selections. Click the 'Apply' button.
      • First select the 'General' attribute group (second pop-up list). Now from the third pop-up select 'Prototype'. Click the 'Apply' button
    • Get Info dialog, attributes tab. Edit the $Prototype attribute.
    • Action code, via Stamps, or OnAdd/AgentAction, Rule, Edict, etc. Set the prototype directly in code, e.g. $Prototype="Person".

    Disabling action inheritance

    Three special boolean system attributes control inheritance of rules, edicts and display expressions: $RuleDisabled, $EdictDisabled and $DisplayExpressionDisabled. Importantly, these attributes are all intrinsic, i.e. their values are not inherited.

    This mechanism allows a prototype to store a rules, edict or display expression, but have the option to not execute the code in the prototype. Consider a rule that alters one of the note's attributes. If run in the prototype, this modified would be unintentionally inherited by other notes. By disabling the prototype's rule via $RuleDisabled, the rule does not run in the prototype but does run in notes using the prototype. Of course, any note using the prototype is still free to disable the rule via its own $RuleDisabled as it doesn't inherit the prototype's value.

    The document default value of $RuleDisabled is false. If it is set to true in the prototype, then the value inherited by notes using the prototype is false. Why not a true value? This occurs because the attribute is intrinsic and its state is never inherited so the (inherited) default value is always the document level default.

    This leads to a reverse problem, what if it is desirable for the prototype to tell inheriting notes to observe the disablement state in their prototype? See chaining prototypes.

    Prototypes 'Bequeathing' Child Notes

    If you want a note that has children to be a prototype, but without its children being inherited, there is an attribute ($PrototypeBequeathsChildren) to control this aspect of inheritance. Inheriting notes gain (a new copy of) all the descendants of the prototype, not just immediate children. The outline arrangement of descendants is preserved, i.e. the note using the prototype becomes a container with the same descendant layout as the prototype. The maximum limit on bequeathed items, limited to avoid accidental infinite recursion, is 500 children (originally 100).

    A note with existing children will not be bequeathed children, even if an applied prototype is set to do so. This is because the bequeathal notion was for implementing data structures rather than as some form of stamp to add additional children.

    Note: prototype children are not copied recursively. When setting the prototype for a note that already exists, Tinderbox will add new children if the prototype has children, but Tinderbox will not delete any child notes that already exists. If the cloned note would have the same name as an existing child, the existing child will be unchanged and the prototype child will not be cloned.

    Therefore, do ensure that none of the bequeathed descendants are actual prototypes, i.e. all prototypes used in the bequeathal should be direct children of the /Prototypes container. If any of them need to be prototype-based, create separate prototypes and store these outside the bequeathing prototype container. Thus if prototype A has child AB and grandchild ABC, then if either both AB and ABC are prototyped, their bequeathed copies are non-prototype copies of AB or ABC. Instead, if AB and ABC are based on prototypes, then the bequeathed notes inherit their source note's prototype (i.e. achieving the original desired aim).

    Agent prototypes can bequeath any adornments saved within them, including image adornments.

    If nesting prototypes with no intent to bequeath children, $PrototypeBequeathesChildren should be set to false. Note this is the attribute's non-default value.

    It is possible to designate some prototypes as 'private' ($Private), meaning it does not appear in the selector lists available in Map & Outline view. Private prototypes can only be created via setting $Private and not via the UI.

    Duplication and prototype assignment

    Duplicated notes retain the source note's $Prototype assignment. Consider prototype 'Note A' used by 'Note B', then

    • duplicating 'Note A' makes a new note 'Note A copy'. The duplicate 'Note A copy' is itself a new prototype note but has no prototype link to B; B retains its 'A' $Prototype assignment. That is congruent with links & duplication, noting that prototype assignment is effected as a (hidden) link. The duplicate does have copies of other outbound links for A, but prototype links are no longer duplicated.
    • duplicating 'Note B' makes a new note 'Note B copy'. The duplicate 'Note B copy' is a new normal note as retains 'note A' as its prototype.
    • duplicating both notes togetherhe same outcome occurs. Although 'Note A copy' is a prototype, both 'Note B' and 'Note B copy' retain 'Note A' as their prototype.

    Shared prototypes

    Tinderbox allows users to store prototypes that can be added to any Tinderbox document open on the same Mac. These stored prototypes essentially allow adding 'custom' built-in templates1, and this can assist with configuring new documents more quickly.

    Locally shared prototypes are stored as top-level notes in a Tinderbox document named Prototypes.tbx in the Tinderbox support folder's sub-folder "prototypes", at:

    ~/Library/Application Support/Tinderbox/prototypes/Prototypes.tbx 

    These shared prototypes will appear at the bottom of the Built-In Prototypes sub-menu. Choosing one of these prototypes will add it to the current document's 'Prototypes' container.

    If the current document's 'Prototypes' container already holds a prototype with the chosen name, the command has no effect and no new prototype is created.

    The newly added prototype shares most attributes with the source prototype in Prototypes.tbx, with the following exceptions:

    • User attributes that do not exist in your document
    • Intrinsic attributes such as $Xpos and $Container, that are never inherited and can be different for a note and each of its alias(es).
    • Read-only attributes.

    Chaining prototypes

    Prototypes may themselves use a prototype, i.e. assign a $Prototype value. This can be useful where several different prototypes share a common base. In such circumstances, it can be useful to use one precursor template and then have several other prototypes using it as their prototype. Changing the upstream prototype will affect all prototypes using it and all notes/agents using the downstream prototype.

    An example is swapping in/out a complex Displayed Attributes table, rather than constantly showing/hiding the table. Here, the main prototype has no $DisplayedAttributes value set as does one of the two upstream prototypes. The other upstream prototypes has the desired full Displayed Attributes table set. Toggling the main prototype between using the other two prototypes magically sets/removes the Displayed Attributes table.

    Beware the above scales awkwardly if you want to toggle more than one feature separately from others. We might want to alternate between two differing Displayed Attributes tables or none. For that, three upstream prototypes (none, table A, table B). But, it we want to separately control Displayed Attributes and Display Expression, for example, we need four upstream prototype: A & B, A only, B only, neither. For 3 things, it is 3 (ABC on, AB only, AC only, BC only, A only, B only, C only, none). Four discrete aspects? Sixteen upstream prototypes.

    So, this is best used to control one or two discrete features. However, if all affected features change together, then only two upstream prototypes could toggle rule/edit/Displayed Attributes/Display Expression/shape/colour/export templates/etc. via one prototype selection switch.

    Another instance is where it is desirable for the prototype to tell inheriting notes to observe the disablement state of their prototype's rule, edict or code: recall that being controlled by intrinsic attributes that state is not inherited). For instance, if hundreds of notes re-use a complex rule inherited from their prototype and constant code execution slows the document down. One solution is to use an edict as that runs less frequently. But how to make an on/off switch?

    An elegant solution is for the prototype itself to use a pair of upstream prototypes. Thus, one upstream prototype has no rule set, the other one does. By resetting the main prototype's rule to the default, it now inherits its rule for (no rule code or for a rule) from the upstream prototype selected.

    Inheritance of attribute values

    The series of notes in this section of aTbRef describe how inheritance of attribute values works in Tinderbox as this can be confusing for those beginning to use Tinderbox.

    Gaining a working understanding of the process is a solid step towards deeper use of the program.

    Attribute value inheritance flows downwards

    The relationship illustrated here shows the possible sources of the default for an attribute value as found in a Tinderbox note. As attributes also control many aspects of how data is displayed within Tinderbox, knowing how these values are inherited and (re-)set will help you understand the look and feel of a Tinderbox document as well as any data the user adds.

    The inheritance principle applies to attributes of all data types. There is a slight difference of scope in the case of user attributes. As these are created within a document, their inheritance tree starts part way down the above sequence, at "Document attribute defaults".

    A few special attributes do not inherit values in this manner and are termed 'intrinsic 'attributes, which we come to next

    Inheritance for Intrinsic or Read-only attributes

    An exception to the inheritance principle is that intrinsic attributes do not inherit. This is deliberate design intent. This is to allow aliases and original notes to hold a different value of the same attribute in pertinent circumstances.

    For instance, have a different $Xpos and $Ypos from that of their original note. This enables an aliases to hold a different map position on the map to that of its original, be it the same map or a different one.

    A number of System attributes are read-only because their values are constantly (re-)calculated. They actually inherit defaults, but these are generally not seen as the calculated value supersedes it.

    Next, inheritance vs. hierarchy

    Inheritance is not based on the actual outline of your data

    Regardless of how other outliners behave, Tinderbox's attribute value inheritance is not connected with a note's outline position. Simply placing one item inside another does not create inheritance.

    In Tinderbox, notes inherit from their grandchild as easily as from their parent, or indeed from a completely different branch of the outline.

    If desired, Tinderbox can be manually configured by the user to make notes inherit values from their parent, but that required using actions rather than normal inheritance. The document's outline hierarchy of content is described separately.

    With these factors in mind, it is now time to consider the inheritance cascade

    The Inheritance Cascade

    In broad terms, an attribute inherits its value from the element above it in the cascade. Change an attribute value at high level, thus cascades down to all elements below.

    For those used to the functioning of Cascading Style Sheet (CSS) styles in Web pages, the cascade is a similar process. The cascade flows downwards as long as a lower object does not set a value for the same thing, in which case the cascade is broken from above and restarted with a new value for objects further below.

    Remember, the cascade is not the outline hierarchy. Also, several levels of the cascade are optional:

    • only a few users with use a custom config file
    • only some notes use a prototype

    So, whilst the above items may be missing from the cascade for some notes, the general principle holds: setting a value anywhere in the cascade alters what is inherited downstream. In other words, setting a value at any level changes that attribute's inherited value further down the cascade.

    The inheritance cascade is as follows (please read all articles in the list to understand the process):

    Next, inheritance and prototypes

    OS Settings

    Note the OS dialog illustrated tends to get tweaked over successive OS releases so your own Mac's version of the dialog may differ slightly in layout & labelling.

    This section is a slight aside, as OS Settings inform how some data types are shown rather than actual attribute values. However, it is pertinent to consider in inheritance terms, as these settings affect how you will see some data displayed in Tinderbox (and therefore dictate the format used to enter things like dates). Here the author is British, so the OS is set to use UK settings. These will affect things like:

    • Date formats, including day/month vs. month/day order, date format delimiters (slashes, hyphens, etc.), time formats.
    • Currency delimiters (full stop, coma, hyphen, etc.).
    • Alpha-numeric sort order: for accented languages this may differ from English.

    So, the 'locale' of settings used on your Mac will affect how attribute data is shown and/or edited. The most obvious example is that of dates: on a UK system, 24 March 2014 would be shown or entered as "24/03/2014" whereas for a US locale it would be "03/24/2014". If you change your OS settings, Tinderbox will adapt to reflect the change (if Tinderbox is open during the OS settings change to may need to restart the app).

    Tinderbox also has action code support for altering the locale used in certain aspects of the app. If you need this, see the locale() operator.

    The true cascade starts with the built-in app defaults

    Tinderbox app built-in defaults

    When Tinderbox creates a new document, it pre-configures all the System attributes and assigns each a default value (which can be a value of nothing/no value). If no other changes intervene, when a new note is added to the document, it directly inherits those values as the defaults of its own attributes.

    The default values for each attribute data-type (e.g. String, Number, Date, etc.) are listed here.

    Next in the cascade are config files

    Config files—for expert users

    N.B.: these are a feature for the more expert user, so learners and general users can skip straight to the next section, Document Settings, and return to this later if needs be.

    Config files are a way of pre-setting some document preferences/attribute defaults so that all new documents receive that customisation. Effectively it allows customisation of a limited number the app's built-in defaults.

    Next in the cascade are Document-level Settings

    Document Settings

    These are effectively per-document preferences that can, if desired, alter the defaults for some System attributes. The Document Settings dialog tabs do not list attributes directly, but rather some of the controls have the effect of altering the built-in default values of some of the System attributes (c.20 in all).

    For instance, the font used for all note text is 'MercurySSm-Book', a serif font. But, you may prefer a non-serif such as 'Helvetica Neue'. By changing the Documents Settings ▸ Text tab's ▸ Text Font control to 'Helvetica Neue' you are in fact seeding a new default for the system attribute $TextFont—but only for the current document—which tells Tinderbox which font to use when adding text to a new note.

    System attributes whose defaults by Document Settings cannot be edited in the Document Inspector's System tab—use the appropriate control in Document Settings.

    Next in the cascade are Document system attribute defaults

    Document attribute defaults

    Document attribute defaults are the result of all of the processes already described and are effectively the baseline for attributes' default values once a document is created. System attribute defaults are documented. New user attributes take their data-type defaults.

    The document is the highest possible level for configuration of User attributes, as they only exist in a document if added by the user.

    Document defaults can always be reviewed—or indeed altered, where allowed—using the Document Inspector's System and User tabs.

    Next, the role of prototypes

    Using Prototypes

    Note: prototypes aren't a fixed feature—not all notes have prototypes. A note only uses a prototype is its $Prototype attribute is set. So for notes with no prototype, this part of the inheritance cascade is ignored.

    A way to think of a prototype in Tinderbox is as a pre-customised note. Any note may be made into a prototype at any time (or indeed cease to act as a prototype); more details here. As well as ordinary notes, container notes, agents, adornments and separators may all use a prototype (N.B. prototype adornments can only be seen in map view, just as with normal adornments).

    Should a prototype's attribute values differ from higher-level inherited defaults, notes using the prototype inherit the prototype's value rather than the higher level default.

    A prototype's customisation is achieved by setting (non-inherited) values for some attributes. These become the inherited defaults for that attribute for any notes using the prototype. Customisation does not need to be visual, though it often helps if some inherited visual feature (e.g. note colour or badge) indicates a note is using a prototype.

    A note inherits the contents of a prototype's Displayed Attributes table via the $DisplayedAttributes system attribute.

    Remember that intrinsic attributes are excluded from inheritance via prototypes.

    The status of a note acting as a prototype is stored in the attribute $IsPrototype. The prototype, if any, that is being used by a note is set in that note's $Prototype attribute. Both settings can easily be viewed/set via the Properties Inspector's Prototype tab.

    Not something to try from first use, but be aware prototypes can inherit from other prototypes. So in the diagram here, 'Prototypes' might be zero, one or several (inheriting) prototypes. Note that be it a note, agent, etc. or prototype, any project can only have zero or one prototypes (which is stored in $Prototype).

    Prototype attribute values cascade to note 'local' level…

    Local Values at Note Level

    Lastly, an attribute value can be set in a note. Even if other notes use the same value for the same attribute this is coincidental. The note with a local value is now no longer inheriting a value for that attribute. Note though that inheritance is per attribute. Even if one or more attributes have a local value, all other attributes still retain their inheritance.

    For most users, this is the context wherein you undertake the majority most of your editing of attribute values. Attributes can also be altered by action code as well as by manual edit or inheritance.

    Note that the cascade does not need to use prototypes

    Note local values can inherit directly or via prototypes

    Summing up, the original inheritance hierarchy can be re-stated as shown above. Prototypes are an optional part of the inheritance chain - they are part of it only if a note is set to use a prototype. Otherwise a note inherits from document level defaults.

    It has also been shown that whilst local values trump inherited ones, it is still possible to re-enable inheritance, offering a lot of flexibility.

    †. Prototypes can inherit from other prototypes, so there may be several in the chain between the document level default and the inheriting note. However, this behaviour is uncommon and only needed in more specialist documents with a highly defined rule-based structure. Intrinsic attribute values are never inherited.

    Back to the cascade overview

    Inheritance and prototypes

    This section deals with the mechanics of how inheritance works in the context of a prototype. Note: the same general process occurs if attributes are edited at a higher level in the cascade, e.g. at document level, and with or without the involvement of prototypes.

    Are prototypes required in a document?

    No. There is not a requirement for you to use prototypes at all, or to use them with all notes if present. They are simply an easy and powerful affordance offered by Tinderbox. It is important to understand how they work so you know their effect if you want to use them. Once comfortable with how prototypes work, their usefulness will become apparent.

    A note can be turned into a prototype at any point. This is part of Tinderbox's ability to allow for emergent structure (delayed formalisation). In a traditional application, such usage would likely have to be planned and implemented before other content was added, or re-added.

    Prototypes can even inherit from other prototypes allowing for quite nuanced behaviours.

    Note: this section uses Displayed Attributes for illustrative purposes. Remember, Displayed Attributes are a means of displaying user-selected attributes. Displayed Attributes have no special importance beyond their display in the text pane.

    Now to explore the inheritance process:

    Prototypes can change the cascade—I

    Any note set to use a prototype then begins to inherit the prototype's customisations, as will be seen

    Prototypes can change the cascade—II

    Thus if the normal colour of a note (attribute $Color) is 'warm gray dark', and a prototype then has its $Color altered to 'green' then the notes using that prototype will inherit that change whereas other notes will not. This holds for any attribute, System or User, that can be altered by the user—i.e. all except read-only attributes.

    Also notice that compared to the previous step's image, when $Color is displayed as a Displayed Attribute, the name and value were shown in normal weight font but are now in bold. This is a deliberate tell-tale. Bold text indicates that this particular attribute in this particular note is set 'locally' (or immediately'). Local values always override defaults.

    The same normal/bold hinting is used in both Displayed Attributes tables in notes (as seen above) as well as in the attribute tables used in the Get Info dialog. One other styling used in these tables is a light grey text for attributes that are read-only, and which cannot be edited.

    Now to see how prototype alter the cascade from higher levels…

    Prototype values override document defaults

    Proving the point that the set-in-prototype values override defaults inherited from higher levels in the inheritance chain, if the document default for attribute $Color is now set to 'red', notice that only the note not using the prototype takes on the revised document default of red. The prototype is coloured green because its $Color was expressly changed to 'green', whilst the current note is inheriting a $Color value of green via the prototype's $Color.

    Notice also that for the note using the prototype, the listing for $Color is not in bold. This is because, whilst the $Color value is set locally in the prototype, the same value is simply inherited by the note using the prototype.

    What about 'local' values, set at a note level…

    Note local values override inheritance

    Consider the diagram above and the note at the bottom of the map. It is using a prototype ('A prototype'), inheriting the $Color 'green'. If the note has its $Color set to 'orange', the new colour—by being set local to the note—overrides the prototype-inherited colour. Note the $Color data in the Displayed Attributes is listed in bold as it is now set specifically for this note. In Tinderbox terminology this is a local value.

    You may now see this is also how a prototype alters the cascade. If a prototype sets a local value, it breaks inheritance from above, yet creates a new one below it in the cascade. Thus a local value in a note using a prototype also breaks the cascade, i.e. the note now does not use the prototype's cascaded value.

    But, can cascaded inheritance be restored?

    Can inheritance be restored after setting a local value?

    There is one other important aspect to consider: how to re-enable normal inheritance once a local value is set? What happens if the bottom note's $Color is simply set to be the old inherited value? Whilst the bottom note is now green as before, notice the $Color data is still in bold. So, the note has the same value as the prototype but is not inherited.

    Next

    Re-enabling inheritance—I

    The answer to re-enabling inheritance is to right click the relevant attribute in the Displayed Attributes table (in either the caption or value columns) and in the pop-up menu then click 'Use Inherited Value'. This resets inheritance. Will the note be red or green?

    Next

    Re-enabling inheritance—II

    It is 'green', inheritance is restored. As the $Color entry is now not bolded, it is signalling that the 'green' value is now inherited from prototype 'A prototype'.

    Because the prototype's own $Color is set locally, that blocks it inheriting the document's 'red' default. Another way to prove the point is to remove the prototype assignment from the current note.

    To reset inheritance in action code, set a (null) value of ';' , thus:

    $Color =; 

    This method is described further under the Actions & Rules section.

    Remember, inheritance can occur without prototype involvement

    Inherited local values without a prototype

    Here, without a prototype, the bottom note inherits the altered document default colour of 'red'. Note too, that $Color is not shown as a Displayed Attribute any more, even though the bottom note has focus. Why? Because that too was a customisation inherited from the prototype, showing that inheritance involves more than just aspects as obvious as a note's colour.

    It is also possible to re-assert the full cascade

    Re-setting all defaults

    For completeness, restoring the document-level $Color default back to the standard new document default re-applies a value of 'warm gray dark'.

    This completes the walk-through of the attribute value cascade. Hopefully it has shown the flexibility of the cascade. That is one of the aspects of Tinderbox that makes it so flexible in terms of implementing structure as it becomes apparent, rather than having to know in advance. In the same way, if a false start is made, it is quite easy to roll back changes.

    As should now be apparent, using prototypes to set values and insert them into the cascade (or remove them from it) can rapidly alter the nature of your document. I the preceding example the colour of a note was used because it is easy to illustrate in a screen-grab, but remember that prototypes can be used to set any non-read-only attribute.

    Back to inheritance and prototypes overview…

    Data export

    Tinderbox offers extremely flexible export, both in format and scope.

    The is all covered in the section on Export.

    Data import

    Tinderbox can both import data via a variety of means though there is no primary 'Import' command or mechanism. Broadly, Tinderbox accepts drag drop of plain text data including tab-delimited text. There is also support for data interchange with some specific applications.

    Data import is explored in detail in the section on Import.

    Unicode

    Since Tinderbox version 5.x, Unicode is supported in note text ($Text) and all system/user attributes. From version 6.x, all UI elements support Unicode display and input.

    Data exported from Tinderbox will use Unix-style line ends, i.e. a line feed character. In Action code this is inserted as the string "\n".

    Inline images

    Tinderbox can embed and show bitmap images in two places:

    • In note body text. Such images are exported via HTML export.
    • Map image adornments. These cannot be exported but the overall View pane can be exported using the 'Copy View as Image' Edit menu option.

    These images are embedded into the Tinderbox document and form part of the data (and stored size) to the TBX file. Depending on the nature of a TBX document, it may make sense to store large images externally and link to them.

    If the TBX is primarily intended for export, such as this document, it may make more sense to store the images outside the TBX and link the exported pages to the external assets. Given that embedded images do not export (at least not currently) then it is possible for a note to have both an embedded image for viewing within Tinderbox and separately alongside it export code that links to an externally stored copy of the image for use with HTML output.

    Tinderbox compresses images; this substantially decreases the size of Tinderbox files with embedded images. Tinderbox currently uses JPEG compression, and compresses fairly aggressively; this significantly diminishes the size and loading time of Tinderbox files at the cost of some image degradation.

    Another way images may be used as fills for Map view notes and adornments and the view background (see $Fill and $MapBackgroundFill).

    Fonts: italics and bold

    Using current Apple frameworks, italics and bold are generated by using the italic or bold font variants of the normal version of the specified typeface. Thus if $TextFont is Helvetica, italic text is rendered in Helvetica Italic and not a false italic of Helvetica; similar for bold text.

    Some fonts well used in the past as Tinderbox defaults may lack these font variants. For instance, macOS currently has no italic variant of Lucida Grande, as was used for $TextFont in earlier versions of Tinderbox. This can be problematic when opening TBX documents created using the latter as italic text and titles are rendered as normal text. In particular this makes it difficult to tell aliases apart from original notes.

    As $Text is saved as Rich Text (i.e. with embedded style information) it is not possible to recover 'lost' style caused by the above issue and it will need to be re-applied manually. For title contexts (e.g. aliases styled in italics), there are two possible solutions.

    • If a permanent change of font is acceptable, change to one that has both italic and bold variants. If in doubt, use the v7 defaults for the relevant attribute.
    • If the existing font is still desired, there is a document setting that allows for aliases to be rendered in underlined normal fonts in addition to the italic styling; i.e. if italics are available the title is underlined and in italics, otherwise it is only underlined).

    Action Code Expressions

    Using in the context of Tinderbox Action code, an expression is a combination of values, variables, and operators that Tinderbox computes. This computation results in a new value. Commonly, that new value is then stored in a system or user attribute.

    Used widely, in programming and data manipulation, 'expression' is a common concept. For example, an 'expression' can be a repeatable recipe use to calculate or derive information based on existing data.

    In the context of Tinderbox, expressions are used to define values, set conditions, or perform computations to automate tasks and customise data handling.

    A Tinderbox expression is normally a part of a complete Action code action (though in some edge cases the two are functionally the same).

    See more at:

    Coding

    To quickly find listings of system attributes, action code operators, designators and export codes, please use the quick links at top and bottom of the page.

    This section contains:

    Use of Attributes

    Aside from what an attribute is as a concept within Tinderbox, it is useful to understand how code interacts with attributes and how choices about attribute type and name can affect their use. See:

    Attribute Naming

    Attribute names, whatever their type, are:

    • Case-sensitive. 'pronoun', 'ProNoun', 'Pronoun', 'PRONOUN' are all valid names that if created would be 4 discrete attributes.
    • The first character must be a letter (upper or lower case) from the Roman alphabet, i.e. A to Z. It must not be a number or an underscore. The initial letter can be accented (bearing in mind that at a computer code level, accented letters are a different character) and may be a non-roman script character.
    • The name must include at least one character (see further below for why single-character named attributes are not generally a good idea).
    • Until v6 only Roman letters and numerals, plus the underscore character, were permitted in attribute names. So, the allowed characters are:
      • capital A to Z (including accented characters), including non-Roman scripts.
      • lowercase a to z (including accented characters), including non-Roman scripts.
      • numerals 0 to 9 (not recommended - see below)
      • underscore
    • non-Roman alphabet Unicode characters may be used for all except the first character. This can include characters from double-byte languages, but right-to-left oriented languages (e.h. Hebrew, Arabic) should be avoided; in both these cases check carefully before committing to extensive use.

    The Document Inspector's User tab for making new user attributes will suppress keyboard input for any other characters to help enforce this rule. So you may have 'ToDo' but not 'To-Do', or To Do' as an attribute name. A name of '8' or '009' is not allowed. When typing a new attribute name in the Inspector, or changing an existing one, unsupported characters (in the position as typed) appear in red. The attribute's name cannot be saved if any red characters are showing.

    When importing spreadsheet type data tables and new attribute names are coerced from column names, an underscore will be used to replace any unsupported characters (e.g. accented characters).

    Take great care when importing data with numerical column heads, e.g. '2' or '37'. If the attribute names and default value (likely zero) differ this can confuse Tinderbox's legacy support in code parsing. Thus id attribute '2' has a default value of zero, $SomeNumber + 2 may be misinterpreted as $SomeNumber + $2, i.e. $SomeNumber + 0, and thus no change. Or, if the $2 in context has a value of '10' then the code might parse as $SomeNumber + 10o not as expected. So, number-only attribute names are allowed, but liable to cause problems so are an ill-advised choice unless circumstances dictates so.

    User Attributes: suggested naming style

    Although you may use any letter case combination it is worth noting that the general style in Tinderbox, and examples in the manual etc., tend to one of two styles opening capital ('Prototype') or inter-capitalised ('AgentPriority'). For newer users, adopting the latter form for user attributes will help to distinguish attributes when seen in action and export code - see more on suggested naming.

    Perhaps self-evident, but adopting self explanatory names is useful both in writing codes but also when displaying Displayed Attributes. Also make use of the attribute's Description box, to describe the attribute's purpose (do not rely on your memory some years later).

    Further naming considerations

    User Attributes can be renamed (but not system attributes).

    Single character names (i.e. single letter - see list above) are allowed though are impractical and not recommended. Such brevity is likely to cause error at some point.

    NOTE re Attribute names & the $-prefix. In action code, when referring to an attribute's value a $-prefix is used. Thus to call the value if the attribute WordCount, $WordCount is used. To refer to the name of said attribute, use "WordCount". Within aTbRef, inline mention in general text which refer to Tinderbox attributes names generally use a $-prefix as a marker that it is an attribute name being cited. The latter is a slight variance with in-app usage but does aid clarity in the articles.

    Creating a new user attribute

    The role and purpose of attributes is described in the section on Tinderbox concepts. This note addresses the means of creating an attribute. By definition, system attributes belong to the Tinderbox program but the user is free to make as many user attributes as they please. There is no hard limit but, practically, having too many to keep track of is 'too many'.

    There are three methods for making a new user attribute:

    • Inspector. Using the Document Inspector's User tab. Note: this is the oldest, and primary, method and allows setting/editing all attribute properties.
    • Text pane. By adding a new name to the text pane's Text tab's pop-over for picking Displayed Attributes and then completing the resulting Define Displayed Attributes pop-over. This allows setting only the new attribute name and data type.
    • Action code. The action code operator createAttribute(). This is generally only associated with more complex/export use of action code in libraries and functions. The operator allows the same range of settings as manually using the Inspector (as above)

    The quickest method is the second, although only attribute name and data type may be specified. The first and last methods allow access to all possible properties of the new attribute. The differences are more fully examined in the linked articles above.

    If new to creating attributes, it is strongly recommended to first read about attribute naming rules and conventions.

    Attributes can be renamed, see that article for some considerations that apply.

    Renaming an attribute

    Attribute names are case-sensitive. Unlike previous versions, User [sic] attributes can be renamed and re-data-typed after creation. System attributes cannot be renamed or have their data type changed. A rename might be to use a completely different term, e.g. $Cost renamed to $Price, or it might be a change of case, $cost to $Cost.

    Simply select the attribute in the Document Inspector's User tab, select the name, enter a new value and press Return. Attribute listings and Displayed Attributes entries will update. However, any explicit use of the old name in action or export code, templates, boilerplate code, etc., will be unaffected. Such mentions must be manually edited to reflect the change but do not overlook agents as a help to find such code passages for correction. Places where you may need to manually change attribute names:

    Changing attribute name or data type & existing values

    Do not assume renaming an attribute will retain the values used under the old name. Although values may persist in some cases, do not rename attribute based on that premise. If the attribute you wish to rename already has values in some notes, do not rename but rather make a new attribute, transfer the values and then delete the old attribute. For example, an existing Number-type user attribute $Price needs to be renamed to $TotalPrice but $Price already has values. The process advised is as follows (it only looks long as it is given in a lot of detail) it is actually very quick to do:

    • Work on a copy of the data: make a copy of the TBX before starting this process
    • Make a new Number-type user attribute 'TotalPrice'
    • Disable any rules/agents that might be alter values of $Price while making this attribute change.
    • Create an agent with the query hasLocalValue("Price"). This will match all notes that have a (local, not inherited) value set for the existing Price attribute. If you have a prototype that sets a value inherited b other notes, only the prototype will match as well as notes that have a value set deliberately in that note.
    • Check the agent matches to sort of notes expected: this is good to do before diving straight in to copying any values. If all looks good…
    • Set an agent action $TotalPrice = $Price. For each matched note—and only matched notes—the value of the $TotalPrice attribute is set to the notes existing $Price value.
    • At this point both attributes in matching notes have a value, and the same one. This is another opportunity to check things look good if trying this for the first time (Outline column view can help). Assuming all looks good…
    • Delete the agent. Do not forget this step!
    • Open the Document Inspector's User tab, and select the 'Price' attribute. Using the gear-wheel button (at right) from the pop-up choose the 'Delete user attribute' option. The 'Price' attribute is deleted along with any data.
    • Other tidy-up issues:
      • Displayed Attributes. If $Price was used as a Displayed Attribute you will need to use an agent to find and remove the old name and add the new one.
      • Action code. Review code in Stamps and any Action-type attributes (e.g. $Rule, $AgentAction, etc.) to find and remove the old name and add the new one.

    Changing data type

    If changing the data type of an attribute, consider coercion effects:

    • To Boolean. No value: false. All other values: true.
    • String-based to Number. Strings of number characters: numbers. All other strings: no value.
    • Number to string-based. Numbers become literal strings.
    • To/from Date. Date to String will likely give the date in string form as would be shown in Displayed Attributes in the current TBX. Other type conversions may have variable effects, e.g. Date to Number which is not a sensible change, anyway.
    • List or Set to String. A semi-colon concatenated string of list values.
    • String to List or Set. The current string will split to list values at any semi-colons in the original value.
    • To/From Interval. Not documented.

    Bear in mind that Colour, URL and File types are essentially String type with a special form of handling

    Correct setting of Font names as attribute values

    Confusingly, the font names used internally (the app talking to the OS) are often not the same. So, the default font used to render $Text may be 'Mercury SSm', yet the stored value of $TextFont would be 'MercurySSm-Book'. Not the same exact string.

    UI like the Inspector and Document Settings controls that set Font-type attributes use a button that opens the macOS Fonts palette. The selection made in the latter correctly sets the font name stored as the attribute's value.

    For the Displayed Attributes table and Get Info/attributes, any Font-type attribute shows an 'A' symbol button between the attribute's name and its value. Clicking on the button opens the macOS Fonts palette. Selecting a font in the latter stores the correct address in the attribute.

    How to know the correct value for setting a font-type attribute via Action code

    If the desired value is already stored in an attribute, simply copy/paste the value as a quoted string value to use in the action code.

    Otherwise, the sensible course is to use a dummy Font-type attribute in the current TBX to set and copy a value—do not forget to delete the attribute when done! Or make a new unsaved TBX document set any system Font-type font to the desired font then copy/paste the value to action code: when done, close/delete the unsaved TBX.

    How to store valid font string in non-Font-type attributes

    As fonts essentially store a string, a String-type attribute can hold a font name. To ensure the value is correct, if not storing a known valid value use the method in the section above to derive a correct font 'name' and then store that in the String-type attribute, e.g. for use in action code, etc.

    Attribute Data Types

    All Tinderbox attributes use a specific data types. If not the author of the document, there are ways to determine an attribute's data type. In general descriptive usage, and in the UI, Tinderbox's labelling of data types is case insensitive, i.e. 'number' or 'Number' are the same in meaning.

    There are 14 types of attribute data types. Note that Action and Font types are not available for use by User attributes.

    An Unsigned type is listed but not used or currently described, it should be regarded as experimental. Experimental attribute types appear from time to time and are usually adopted formally or removed; the release notes normally give detail on these types.

    Note that Action, Color, File, Font, List, Set and URL data types are effectively all special forms of String data type attributes and share a common default: an empty string. Boolean attributes default to false (which is not a string), Date attributes to the string "never", Interval attributes to the string "00:00" and Numbers to 0 (zero). Empty/Default values are discussed further for each action type in the articles linked in the list below.

    A combined list of default values for each individual data type can be found here. See per-type listings for detail of the value sorting order of that type.

    These are the current Tinderbox attribute data types

    Legacy - discontinued file types

    Originally there were two other types of attribute, neither expressly described in :

    • enumerated. Never used. Not present in v4.5.0.
    • binary. Used for 3 (?) blogging-related system attributes (all beginning 'mt_'). By v3.0.0. these had been remapped to other data types. The v3.0.0 manual lists them as type 'boolean' but in fact they were re-types to number and string as per their current types. The binary type was removed in v4.6.0.
    Action-Type Attributes

    [First introduced in v4.0.0]

    Action

    The attribute data type of 'action' represents a string that can be used as an action; under the hood, Tinderbox caches the compiled action so it does not have to constantly re-parse the same code. Thus these attributes should contain a string [sic] of valid Tinderbox action code.

    Some pre-existing system attributes, such as OnAdd and Rule have been re-classed from 'string' to 'action' type.

    This data type is not available for user attributes. Use 'string' instead.

    Default/Empty value

    An empty string.

    Sorting order

    As for String Data Type.

    Action-type System Attributes

    Built-in attributes of the action data type are listed below:

    Boolean-Type Attributes

    [First introduced in v1.0.0]

    Boolean

    A binary value: either true or false. These values are case sensitive. If no default value is specified, a Boolean type defaults to a value of false.

    In the Tinderbox UI, Boolean attributes may often be represented as tick-boxes, e.g. in a note's displayed attributes table. A ticked box equates to true, and an empty box to false.

    When coercing a Boolean value—such as the result of evaluated action code—to Number-type of data, true coerces to 1 and false coerces to 0 (zero).

    Default/Empty value

    A value of false.

    Sorting order

    false (un-ticked), then true (ticked).

    Boolean-type System Attributes

    Built-in attributes of the boolean data type are listed below:

    Boolean-type System Attributes set via Document Settings

    A number of Document Settings controls set the defaults for Boolean-type system attributes, directly or indirectly:

    Color-Type Attributes

    [First introduced in v1.0.0]

    Color

    Any one of the following:

    • Hexadecimal. A colour represented as s string "#RRGGBB"; a hash sign followed by 6 hexadecimal digits, a pair for the intensity level 0 to 250 in hexadecimal of Red, Green and Blue. This is the same format used for describing colours in HTML. Example: "#A482BF". The short form is also accepted, e.g. "#f00" for "#ff0000", where the two hex characters of each per-colour value are identical and the second character is omitted. Bare hex strings in action code, i.e. unquoted numbers preceded by a hash sign, are correctly identified as hex input values.
    • Named Colours. The name of a colour that either comes pre-defined in Tinderbox, or which you have defined for this Tinderbox document using the Colors pane of the attribute palette. Examples: blue, red, minty-fresh-green. When setting a shade of a named colour in a string the shade value (lighter, darkest, etc.) comes before the colour, unlike listings in Info view and the Inspectors; thus "dark warm gray" not "warm gray dark", "light cyan" not "cyan light".
    • HSV (Hue-Saturation-Value) value. Hue: a value from 0 to 360 degrees. Saturation and Value: a value from 0 to 100 percent. Enclosed in parentheses and preceded by 'hsv'. Examples: "hsv(0,100,50)", "hsv(240,80,80)".
    • RGB (Red-Green-Blue). Intensity levels represented as integers from 0 to 250. Enclosed in parentheses and preceded by 'rgb'. Examples: "rgb(0,0,0)" and "rgb(68,153,68)". This should not be confused with the rgb() action operator (which sets a hex format value string (see first bullet above).

    When displayed in a note's displayed attributes table, Color-type attributes show a colour-chip icon before the attribute value. Pressing the icon opens an OS colour picker dialog.

    If no default value is specified, a Color type defaults to an empty string (which is treated by Tinderbox as the value 'normal'); in Displayed Attributes table displays a white colour chip is displayed. In some cases, Tinderbox will show a dark red colour as a 'not initialised' colour value; it is hex colour code #6f0000, though its derivation as a value is not clear.

    Note that as 8-bit colour settings are translated within the app into 16-bit colours, rounding errors can occur. So, in some cases—most likely using HSV and HSV based transforms—the values used might not correspond precisely to those set by the user.

    Similarly, using format() with a colour attribute will always result in a hexadecimal value string regardless of the stored value. Thus it makes sense to export colour attributes as ^value(format($ColorAttr))^ or ^value($ColorAttr.format())^. However, note that coercing a default (blank) colour to a string value using format() or .format() will result in the colour value "#ffffff", which is not strictly the blank value. So, be wary of using that formatting as a means to check for a blank colour value; better is to use a short form Boolean test.

    Use in Export code

    When accessed via ^value()^ export code, it will return either a hex colour value or a named Tinderbox colour, depending on what is set for the destination attribute.

    Legacy only: using the deprecated ^get()^ or ^getFor()^ export codes, the colour is always returned as a hex figure including a # prefix, e.g. "#FF9900".

    Default/Empty value

    An empty string.

    Sorting order

    Named colours in decreasing lexical sort order, then #-based codes in decreasing lexical sort order with same valued three-character codes sorting after six-character ones (i.e. #ffffff before #fff).

    Color-type System Attributes

    Built-in attributes of the Color data type are listed below:

    Color-type System Attributes set via Document Settings

    A number of Document Settings controls set the defaults for Color-type system attributes, directly or indirectly:

    Date-Type Attributes

    [First introduced in v1.0.0]

    Date

    A date and time string. It should always be enclosed in double quotes (legacy code without these may cease to work as expected). Dates can be added/subtracted/compared in mathematical fashion, as per number data types. The resulting 'string' can be formatted by means of date format codes. If no default value is specified, a Date type defaults to a value of never.

    Date includes a time element even if not displayed

    If a date is specified but not a time, time always defaults to current system time except the seconds are not shown in Displayed Attributes (visual format may vary by locale, e.g. on the use of the colon delimiter).

    The element in Date comparisons

    Time is used in date comparisons except when the == or != operators are used. Also see Basic Comparison Operators and date comparisons; the same rules hold true for data comparisons in action code expressions. Seconds are acknowledged in comparisons, except those excluding all time elements of a date/time (Previously, seconds were not used and/or are always considered to be 00. To use exact equality tests on full date-time data use interval()).

    Considering date vs. date-time in queries is discussed here.

    Date keywords

    Tinderbox recognises date keywords such as today, now, yesterday, tomorrow, day, week, month, year, hour and minute as date-defining placeholders when working in action code (see date keywords link for a full list). Constructions like "yesterday + 1 week", "tomorrow + 1 year" or "tomorrow - 2 hours" are also possible; note how the whole action code expression is placed in one set of double quotes. If number is supplied without a date placeholder, e.g. "today + 1", then 'day' is assumed as a default unit value, i.e. as if the input was "today +1 week". See more on the syntax for setting/adjusting dates using date keyword strings.

    The 'now' placeholder can be used as an alternate for 'today'. As both the latter use the current system clock time for their time element, note that it is possible to set an explicit time alongside designators (only use 24-hour clock time: "today 16:00" or "tomorrow - 2 days 23:59". See more on setting times.

    Initialising a Date attribute without time information

    Beware the use of only date placeholders, without time indicators, to initially set a Date attribute will result in the time portion (hours:minutes) being set to the users local OS system time. Entering a time-less date into a Displayed Attribute value box, e.g. "21 Aug 2001" will also result in the time portion being set from the OS local time. Using a date designator to alter an existing date never alters the time part of the date attribute value. The time part of a date can be altered either by manually (re-)setting it or by use of time-related action codes. If current time is 17:03:24 (5 PM, 3 minutes and 24 seconds):

    $StartTime = date("27/03/2022") gives a time of 17:03:24 on 27 March 2002 (US users only, reverse day/month order)
    $StartTime = date("27/03/2022 00:00:00") gives a time of 00:00:00 on 27 March 2002 (US users only, reverse day/month order)

    Similarly if initialising a Date attribute by typing in a Displayed Attributes or Get Info value, you must explicitly include the h/m/s time unless you wish to use the default (system) time.

    Effects of OS locale. Tinderbox will assume a manually supplied version uses the same day/month order as the user's current locale settings. In other words, if working on a US system using month/day order enter 6 July 2001 as "7/6/2011" whereas on a British system using day/month order use "6/7/2011", and so on for other locales. Dates that use slashes "1/7/05" and the European Continental format with periods, e.g. "1.7.05" are both recognised.

    For years with only one or two digits, e.g. 10CE, you should always enter the year part of the dates as 4 digits (e.g. 0010) when setting dates via code or Displayed Attribute input.

    Users should check the Formats pane of the International pane (Formats tab) of their macOS System Preferences and ensure the 'short' format uses four-digit year numbers. To do this (for a region), on the Formats tab, click the 'Customize…' button to the right of the example dates. The 'Show' pop-up is most likely set to 'Short'; leave it as that. In the white text box below click on to year; you will see a drop-down menu that will allow you to choose either 2-digit or 4-digit dates, select the four-digit date. US users should note the default US setting for "short" date formats is to display 2-digit years, i.e. 10/3/65 (for 1765, 1865, etc.). All numeric reverse-order dates like '20090130' can be used though do test the exact desired format before committing to extensive use.

    Use of negative (BCE) dates

    Tinderbox will allow negative dates to allow analysis of data either side of the CE/BCE (AD/BC) boundary. Negative integers from -1 to -2500, when coerced to dates, are interpreted as years BCE (BC). Some current limitations re 'negative' dates:

    • Currently, there is no way in a Displayed Attribute box or in display expressions to display the fact that a date is negative.
    • Negative dates cannot be tested for using greater than/less than comparisons.
    • Negative dates cannot easily be set via a Displayed Attribute input. The easiest method is to make a stamp with code like this: $StartDate.year = ($StartDate.year-(2*$StartDate.year)-1). That code will flip a positive date to a negative one. Given the first limitation above re displaying BCE dates, you will need to check out that the result is correct.
    • Date.year always returns a positive number, even from a negative date.
    • There are no date-format strings that will show the epoch.

    Handling ancient dates

    Dates before the common era now appear in displayed attributes as "BCE", and may be edited. Date strings such as "44 BCE" are now handled appropriately. "BCE" is added to BCE dates in OS short format as well as medium format.

    When integers are converted to dates, the conversion is as follows:

    • -35000 to +2500: refers to a year between 35,000 BCE and 2500 CE.
    • otherwise: refers to the number of seconds before or after midnight UTC on 1 Jan 1970.

    Miscellanea about Date-type data

    Tinderbox XML documents store dates using ISO 8601 format. Tinderbox also recognises date strings entered as Displayed Attributes or converted from strings in actions when in the ISO 8601 format (e.g. 2008-11-20 16:55:00).

    Two dates may be subtracted with a result in days even if the result is a string. This helps with tasks like setting $DisplayExpression.

    Tinderbox offers numerous date formats to allow non-default representations of date/time both in internal action code (use with format()) or for export (use with ^value(format())^).

    Default/Empty value

    The string "never" (no date set).

    Sorting order

    Ascending (later) date/time order; the default value "never" always sorts last. When sorting lists of Data-type data always use .sort and not .nsort (the latter gives an incorrect sort result).

    Storing date/time durations

    This is done using the Interval data type. The maximum unit size in an Interval is a day and it can work for up to 30 days. But generally it is for periods of a day or less as thought of in hours, minutes and seconds.

    Doing date/time calculations with Date and Interval types

    This is described in discussion of the Interval data type and here. Adding or subtracting Interval data from Date data whose value is "never", correctly returns "never".

    Date-type System Attributes

    Built-in attributes of the date data type are listed below:

    Date-type System Attributes set via Document Settings

    A number of Document Settings controls set the defaults for Date-type system attributes, directly or indirectly:

    Dictionary-Type Attributes

    [First introduced in v9.0.0]

    Dictionary

    A Dictionary attribute replaces like the older Tinderbox feature of lookup tables, as a list of paired keys with values: key:value; 

    The key part comes first with a terminating colon. The value part follows, terminated by a semi-colon. White space handling in key:value pairs is described below.

    Dictionaries are faster to construct, and large dictionaries are far faster to check, than lookup tables. Dictionaries are not generally intended for handing large/complex values or for values including punctuation and symbols. A Dictionary may be considered better for tasks previously configured using look-up lists.

    Like other attribute types, a Dictionary follows normal rules of scope and inheritance. A note using a prototype with a Dictionary holding data, will inherit that data dictionary. Similar to a Set type, a Dictionary does not allow duplicate keys, but multiple keys may use the same value.

    A key may have multiple values; this can be either []-enclosed List-type or {}-enclosed Dictionary-type data. For example, the dictionary:

    {Tinderbox: 1;Storyspace: {Editor: 2; Reader:3}} 

    contains two elements. The first has a key of "Tinderbox" and a value of 1. The second has a key of "Storyspace" and the value that is itself a dictionary, {Editor: 2; Reader:3}.

    Dictionary key:value syntax

    A dictionary collects pairs of strings separated by a colon, noting that whitespace before/after the colon in the key:value: pair is ignored when the data is added. The first string is the key, and the second string is the value. In these examples there are 3 such key:value pairs. These first two forms are better practice than the third just below:

    $MyDictionary={cat:animal; dog:animal; rock: mineral}; 
    $MyDictionary=$MyDictionary.add("cat:animal").add("dog:animal').add("rock: mineral"); 

    The dictionary() operator creates a dictionary (in the current note),

    $MyDictionary=dictionary("cat:animal; dog:animal; rock: mineral"); 

    The key "cat" has the value "animal", while the key "rock" has the value "mineral".

    Although it is still possible, via legacy support, to populate a directory by passing a dictionary-formatted list as a quoted string to a Dictionary-type attribute, this is deprecated in favour of the {} method, or using the dictionary() operator is explicit and indicates intent unambiguously when parsed by Tinderbox. See dictionary() for usage.

    Case-sensitivity

    A key is case-sensitive and must be unique to the dictionary; the value may be the same as values for different keys within the current dictionary. Rather like the Set data type, duplicates are weeded. If a new key:pair is added to a dictionary and the key (case-sensitively) already exists, the existing value (only) for that key is updated to use the value from the new pair.

    $MyDictionary = dictionary("cat:animal; dog:animal; rock: mineral"); 
    $MyDictionary = $MyDictionary + "cat:mammal"; 

    Now, the value of key "cat" becomes "mammal" and the older value is lost.

    Quoting of keys and values

    From v11.5.0, the key is always treated as a string, and does not require to be quoted: quoted keys, e.g. in older code, will still work correctly. If the value of that key is a string, it should be quoted. In addiction, the value must be quoted if the string value contains any of the following: {}():// or quotation marks.

    Use of whitespace, symbols, quotes, etc., with keys & values

    Any whitespace either side of a colon (:), or semi-colon (;), or at beginning or end of dictionary data is ignored. As the colon (:) and semi-colon (;) characters are used as delimiters in the stored Dictionary data, they should also not be used within key names or values.

    The expectation is that keys and values will be simple strings or numbers, so avoid use of characters like punctuation as you may experience unexpected results; additionally avoid using parentheses (), square [] or curly {} brackets, backward \ and forward / slashes, single/double quotes or commas.

    A good rule of thumb is to think hard if using other than A-za-z0-9 or underscore/hyphen/period (the period might be needed for a decimal number value).

    Adding key:value pairs

    To add to a new key:value pair, use addition, as with Lists and Sets…

    $MyDictionary = $MyDictionary + {apple:plant}; 
    $MyDictionary += {apple:plant}"; 

    adds they key "apple" and associates it with the value "plant". If the key was already found in the dictionary, its value is replaced by the new value. If the key was not found in the dictionary, both the new key and the new value are added.

    As well as using a literal value, the key (and value) to be added can be give as an attribute value or variable:

    $MyString = "apple:plant"; $MyDictionary += $MyString; 
    var:string vKey = "apple:plant"; $MyDictionary += vKey; 

    There also a Dictionary.add() operator. This does the same as the above:

    $MyDictionary = $MyDictionary.add("apple:plant"); 

    Deleting keys (implicitly key:value pairs)

    Entries can be deleted from a dictionary by subtracting the key:

    $MyDictionary = dictionary("dog:animal; cat:animal; rock:mineral"); 
    $MyDictionary = $MyDictionary - "dog"; // gives "cat:animal; rock:mineral" 

    or in newer form:

    $MyDictionary -= "dog"; // gives "cat:animal; rock:mineral" 

    Be aware that setting an empty value for a key doesn't delete the key:

    $MyDictionary[somekey] = ""; 

    leaves the key 'somekey' with no value, which is not encouraged (q.v. below).

    As well as using a literal value, the key to be removed can be give as an attribute value or variable:

    $MyString = "dog"; $MyDictionary -= $MyString; 
    var:string vKey = "dog"; $MyDictionary -= vKey; 

    It is not possible to subtract a list of keys. Instead, such a list must be iterated as a succession of individual key deletions. The only exception to this is if all keys are to be deleted, in which case set the dictionary object (attribute or variable) to the default value to delete existing data:

    vDict=; $MyDictionary=; 

    Changing the value of a key

    New values may be assigned to specific dictionary keys.

    $MyDictionary[apple] = "pie" 

    Adds the key "apple" to $MyDictionary with the value "pie". If the dictionary previously contained a value for "apple", it is replaced by "pie"; if not, a new key and a new value are added to the dictionary. Or, use .add() can be used:

    $MyDictionary.add("apple","pie"); 

    Note that the += and -= operators are not currently available for changes to dictionary (numerical) values of the form

    $MyDictionary[key] += 1; WRONG!

    Instead, use the conventional form:

    $MyDictionary[key] = $MyDictionary["key"] + 1; 

    Adding to a key's value(s)

    The Dictionary.extend() operator offers such a feature.

    Deleting the (single) value of a key

    Ideally in such a case remove the key. However is possible to delete a key's value, by setting it to an empty string "" (or reading from a stored value that is such). To set the value of key 'apple' to "":

    $MyDictionary[apple] = "" 

    Generally, the expectation is that a key has an actual value.

    Keys with multi-item values are supported using [] or {} notation

    Dictionary key values can be multi-valued using either the new [] (list or set) or {} (dictionary) notation. This holds for creating dictionaries or setting key values. When retrieving a multi-value result pass the data to an appropriately type attribute or variable. The data can then be accessed using appropriate key or list address syntax. Examples of nested multi-value values:

    $MyDictionary={cat:animal; dog:animal; rock:{granite:mineral;basalt:mineral}}; 
    $MyDictionary={cat:animal; dog:{terrier:dog;labrador:dog}; rock:mineral}; 

    From v11.6.0, lists now allow blank (empty) list items when using the [ ] list notation. As a result, a trailing semi-colon will imply the intent of a last list item that is empty.

    Merging Dictionaries

    Dictionaries may be merged by adding them.

    $MyDictionary = $MyDictionary+"apple:plant" 

    adds they key "apple" and associates it with the value "plant". If the key was already found in the dictionary, its value is replaced by the new value. If the key was not found in the dictionary, both the new key and the new value are added.

    It is possible to add two dictionaries.

    $MyNewDictionary = $MyDictionary+$MyOtherDictionary 

    Note that if the dictionaries share (case-sensitive) keys that have differing values, the values from the last-added, therefore those in $MyDictionary, will replace those in $MyDictionary. Thus:

    $MyFirstDictionary = dictionary("apple:fruit; granite:mineral"); 
    $MyOtherDictionary = dictionary("pear:fruit; granite:rock"); 
    $MyDictionary = $MyFirstDictionary + $MyOtherDictionary; 

    MyDictionary now contains "granite: rock; pear: fruit; apple: fruit" 

    Note the order of dictionary items is re-ordered, reinforcing the point that additions/subtraction of dictionary data may alter item order, and which the user does not control. It is not possible to:

    • subtract a dictionary from a dictionary
    • subtract lists of keys
    • subtract individual values

    Dictionaries lack the 'default' key used by look-up lists

    User of look-up lists with list-type data might assume the same notion holds for Dictionary-type: it does not! It is still possible to define a 'default' key but using it requires a little extra code. Whilst it is possible to check if a key exists with Dictionary.contains(), it may be more useful to check for a default empty ("") value being returned. For instance, instead of, in a .each(aKey){} loop, where you might code:

    $MyString = $MyDictionary[aKey]; 

    consider (and assuming a 'default' key/value exists):

    if($MyDictionary[aKey]){$MyString = $MyDictionary[aKey];}else{$MyString = $MyDictionary[default];}; 

    or:

    if($MyDictionary.contains(aKey)){$MyString = $MyDictionary[aKey];}else{$MyString = $MyDictionary[default];}; 

    But, the key point is that is a default response is needed, the user must (a) define the 'default' key:vale pair and (b) add the code to invoke it. More code-savvy users may choose to encapsulate this in a user function.

    Dictionary and values()

    You can get the values of a Dictionary, but you cannot look up a key that corresponds to a given value. Remember, multiple keys may same value. Therefore, using values() with dictionaries is not recommended as this returns all the unique key:pair values as opposed to only keys or only values.

    Iterating Dictionaries

    Use Dictionary.keys to get a list of the keys and then iterate that list using list.each().

    Default/Empty value

    If a requested key is not defined, or the key has no value, an empty string is returned.

    Dictionary sorting

    Not applicable, as Dictionaries cannot be sorted. As a Dictionary is addressed via a key value rather than a list offset, the stored order for keys is moot. By observation, a Dictionary is generally stored in key lexical sort order but this should not be assumed to always be the case.

    Whilst a Dictionary itself cannot be sorted, it is possible to make a list of the keys then sort and iterate that list. for example:

    	var:list vKeyList = $MyDictionary.keys;
    	vKeyList = vKeyList.sort; // Use .nsort if keys are numbers
    	var:list vSortResults; // Use List so it stays sorted
    	vKeyList.each(aKey){
    		vSortResults+=(aKey+" | "+$MyDictionary[aKey]);
    	};
    	//Test
    	//$Text = vSortResults.format("\n"); 

    Note that the initial sort could be lexical (.sort), lexical case insensitive (.isort) or numerical (.nsort)

    Additional Dictionary definition mark-up

    Dictionaries may be written by enclosing them in braces, for example a dictionary with two key:value pair elements:

    $MyDictionary = dictionary({Dog: animal; Crocus: plant}); 

    The use of the braces removes the need to use quotes around string values.

    This new form of Dictionary-type data allows for nesting; for example, the dictionary

    {Tinderbox: 1;Storyspace: {Editor: 2; Reader:3}} 

    contains two elements. The first has a key of "Tinderbox" and a value of 1. The second has a key of "Storyspace" and the value that is itself a dictionary, {Editor: 2; Reader:3} .

    The dictionary .add() and .extend() operators now take a single argument — a dictionary of elements which will replace or extend the current elements.


    Legacy behaviour: Prior to v9.6.0, a value could not contain more than one value The value for a key 'pie' might reasonably be apple, lemon and quince. Whilst it was possible to define a dictionary like this:

    $MyDictionary["pie"] = "apple;lemon;quince" 

    … the fact a semi-colon is used as both a list delimiter (within the value) and as a key:value pair delimiter, means Tinderbox currently does not know how to parse this; work is in hand to support multi-item value, i.e. lists.

    Temporary note. Presently generating a dictionary with nested multi-values (list/dictionary) may be possible only if using literal string values but not if using variables/attribute values. This is likely a by-product of the newer [ ] and { } data type notations and subject to later changes/fixes.


    Dictionary-type System Attributes

    Built-in attributes of the date data type are listed below:

    Email-Type Attributes

    [First introduced in v9.6.0]

    Email

    An Email attribute data type is offered to address activities related to parsing/sorting email data.

    An email address string, e.g. jdoe@example.com. If no default value is specified, an Email type defaults to an empty string. Emails are not delimited (i.e. quotes are not required).

    Email attributes behave like string attributes, but with a special behaviour when displayed in a note's displayed attributes table. There, Email-type attributes show an envelope icon before the attribute value. Pressing the icon opens a draft email to that address using the default email client using the notes text as the draft content.

    More precisely, pressing the button composes a message, whose body is the $Text of the note, and opens that message in the default email client (e.g., Apple Mail), from which it might be sent to the address that appears in $Email. There is no validation that the value in $Email is correctly formed.

    Default/Empty value

    An empty string.

    Sorting order

    As for String Data Type.

    Email-type System Attributes

    Built-in attributes of the Email data type are listed below:

    File-Type Attributes

    [First introduced in v1.0.0]

    File

    A path to a file. When setting this type of attribute a file selection dialog is shown instead of a text box. The selected file is entered as the attribute value for that note. If no default value is specified, a File type defaults to an empty string.

    The path stored is in POSIX form (forward slash delimited) and is the full local path to the file or folder.

    When files from the user's directory are dropped into Tinderbox or into a file attribute, Tinderbox uses the tilde (~) abbreviation to represent the path to the user's directory. This should make it easier to share one Tinderbox document across several machines, each of which share files in common locations (e.g. Dropbox) but which have different user names.

    When displayed in a note's displayed attributes table, Find-type attributes show a folder icon before the attribute value. Pressing the icon opens that attribute's stored OS file path (if any) for a file, using the in the default app as determined by Finder, or for a folder it opens Finder.

    Default/Empty value

    An empty string.

    Sorting order

    As for String Data Type.

    File-type System Attributes

    Built-in attributes of the file data type are listed below:

    Font-Type Attributes

    [First introduced in v6.0.0]

    Font

    The attribute data type of 'font' represents a string defining a font name.

    Some pre-existing system attributes, such as $NameFont have been re-classed from 'string' to 'action' type.

    This data type is not available for user attributes.

    Default/Empty value

    An empty string.

    Sorting order

    As for String Data Type.

    Font-type System Attributes

    Built-in attributes of the file data type are listed below:

    Font-type System Attributes set via Document Settings

    A number of Document Settings controls set the defaults for Font-type system attributes, directly or indirectly:

    Interval-Type Attributes

    [First introduced in v7.0.0]

    Interval

    The attribute type, Interval, represents time intervals and durations. The general designed/expected usage is for durations shorter than an hour, but intervals of hours or even days are possible—see below.

    Reflecting the basic expectation, the default value is a string "00:00" representing zero minutes and zero seconds. For example, the interval value

    01:30 

    represents one minute and thirty seconds whilst

    02:01:00 

    represents two hours, one minute and zero seconds. Note the need to include the seconds element (in both input and output) to differentiate the NN:NN form as mm:ss and not hh:mm.

    Creating Interval-type data

    This is achieved using the interval() operator. The input is a string (see interval(dataStr)). Note that minute and second values do not need zero-padding, inputting "4:2" results in a displayed/exported value of "04:02".

    If a time element is supplied is larger than its normal count (e.g. more than 59 minutes or seconds, the input is re-parsed into normally sized units. So "90:70" mm:ss will get parsed as "01:31:10". This effect is useful if creating inputs from dynamic values and avoids the need to re-parse number before input. This applies to hours, minute and seconds inputs.

    When reading/copying Interval type data, it is always in String form, i.e. "22:09", even though the Interval data is stored internally (in the running app) in a different form. As a result, an Interval can be passed directly to a string attribute without needing modification. So, adding an interval to a string:

    "The answer is:" + $MyInterval returns a string.

    Creating an Interval from Dates

    A variant of interval() enables returning the time between two Date-type objects as an Interval: see interval(startDate,endDate).

    Using intervals of an hour or more

    Although originally intended for short (sub 1 hour) durations, Intervals can accept hour or day inputs. For long intervals note that hours and days are accepted units: year or month scope inputs are not understood by the interval parser.

    Thus the duration

    01:01:00 

    represents a duration of one hour, one minute, and thirty seconds. The seconds cannot be omitted, even if '00' as the above written as "01:01" would be parsed as one minute and one second. Only "01:01:00" ensures the hour element is detected correctly.

    Days are defined using the word 'day(s)':

    2 days 01:00:00 represents 49 hours

    Duration components larger than a day (of 24 hours), e.g. months or years, are not supported, though is is possible to use large day values:

    62 days 01:30:10

    representing an interval of over two months' duration. The maximum length of an interval but it is not advised to exceed 1 year (but specified in days, i.e. 365 days) but ideally intervals are used for a few days or less. If the duration of the interval is desired in whole days only, use normal Date-type arithmetic and store the duration as a Number-type.

    Formatting Interval data

    Using, Interval.format() only accepts a limited range—two choices—of formatting string options, i.e. not the full range of Date formats. The displayed format of Intervals, in Displayed Attributes and Get Info cannot be modified. If passing the data for use elsewhere, e.g. for export, the string representation can be modified using normal String manipulation operators.

    Negative values

    An interval may have negative duration, "-05:30":

    -05:30 

    represents a negative duration of 5 minutes and 30 seconds. This can be useful when doing short duration date arithmetic (as below).

    Use in Date arithmetic

    Intervals may be added or subtracted from Date-type attributes or variables. They may multiplied or divided by constants or numeric attributes, and may be compared for equality using == and != or for magnitude using < and >.

    For directly altering a Date's time element, the time() operator is normally a simpler and more convenient choice.

    Note: subtracting two dates does not currently return an interval; rather, it returns the number of days between the two dates in accordance with pre-existing Date-type attribute behaviour. To get the interval between two Dates, use the interval(startDate,endDate) operator syntax. Thus to get the interval between the $StartDate of note "Session 1' and $StarDate of "Session 2":

    $MyInterval = interval($StartDate("Session 1"),$StartDate("Session 2")); 

    Intervals can be added to/subtracted from Dates. If $MyInterval is "-05:30" and $MyDate is 24/10/2022 12:00:00 (midday on 24 October 2022):

    $MyDate = $MyDate + $MyInterval; 

    results in $MyDate being 24/10/2022 11:54:30. By accepting negative intervals the same action code can deal with positive and negative durations. So to find the number of (whole) minutes in the interval:

    $MyNumberOfMinutes = minutes($MyDate,$MyDate+$MyInterval); 

    A more generalised approach to the last:

    $MyNumberOfMinutes = minutes(date("now"),date("now")+$MyInterval); 

    Here minutes are tested but the method could test days, hours or seconds (not bigger units as Interval data is usually a few days at biggest and generally less than a whole day).

    Alternative syntax

    Some alternative syntax is supported, including an 'h' suffix/separator for hours and 'd' for days. Thus the duration

    1h30 

    represents one hour and thirty minutes, whilst:

    1 day 01:00:00 represents 25 hours
    2d2h30 represents two days, two hours and 30 minutes

    whilst:

    2d5 

    is treated as 2 days, 5 hours, as hours is the next smaller duration measure than days.

    The 'd' marker is always resaved/displayed as 'day(s)':

    2d5 is resaved as "2 days 05:00:00
    1d5 is resaved as "1 day 05:00:00

    Note that whilst 'm' and 's' suffixes are understood for minutes and seconds; the 's' is superfluous anyway as it is always the last segment if used. If a duration is entered as "3m20" Tinderbox will re-save the value in the default format of "03:20" so use of 'm' is deprecated. Thus a duration entered as follows will be understood:

    1h30m10s 

    but it is treated as one hour, thirty minutes and 10 seconds but will be re-saved as:

    1:30:10 

    Note slight variations in accepted abbreviations compared to pre-existing Date-type attribute date arithmetic usage.

    Use of floating point (decimal) numbers

    Assigning a floating point (i.e. 'decimal') number to an interval is supported, and interpreted as a number in seconds; the numbers after the decimal point are discarded—no rounding up/down occurs. This can be useful as time codes, e.g. as in offsets within audio or video files, may be given with a decimal element: '45.3' vs. '45'. Thus:

    $MyInterval = 5406; 

    gives in interval of "01:30:06". Note however that

    $MyInterval = 5406.8;

    gives the same result of "01:30:06". The '0.8' of a second in the input value does not cause the seconds element of the interval to round up to ':07'. This latter is the equivalent of a floor() operation where a decimal number is always rounds down the the existing whole integer:

    $MyInterval = floor(5406.8); (returns integer '5406')

    Default/Empty value

    The string "00:00" (zero hours:minutes).

    Sorting order

    Increasing duration, so unset ("00:00") values list first.

    Coercing interval data

    Interval-type System attributes

    Built-in attributes of the file data type are listed below:

    List-Type Attributes

    [First introduced in v5.6.0]

    List

    A semi-colon delimited list of string values. In terms of stored data Sets and Lists are the same: a string containing one or more semi-colon delimited items. The difference is in the way Tinderbox handles the two data types, as lists may contain duplicate items. Although the Set-type pre-dates List-type in Tinderbox, Lists should be thought of as the underlying form and Sets as a type of List with special features (de-duplicated, always sorted, etc.).

    List items can be read/set via their list order number (see below) but note that this is zero-based, i.e. list item #1 has address value zero (0).

    A List, even a list of numbers or boolean values, is stored as a semi-colon delimited string, i.e. list items are not stored with an explicit data type, though multi-value value can be list or dictionaries.

    In actions, + adds an item to a List if it is not already present, and -- removes it if it is present. These are now generally replaced by the += increment and -= (minus) decrement operators. Values should be enclosed in square brackets (previous, and still supported is to use enclosing double quotes).

    Declaring a new List

    If setting a List's literal values via action code use the square bracket [ ] List definition:

    $MyList=[Frogs;Dogs;Logs]; 

    Importantly, the bracket notation replaces the older now-deprecated legacy method of using enclosing quotes:

    $MyList="Frogs;Dogs;Logs"; NOTE: do not use this for new code!

    Whilst both methods work and the latter, older, method will be found in many demos and tutorials, the bracketed notation is now the preferred method.

    Importantly, when typing/pasting a List's values into a UI input box such as the Inspector, Get Info, or Displayed Attributes, the enclosing brackets or quotes (as used above) should be omitted, i.e. using planes;trains;automobiles not [planes;trains;automobiles]. If brackets are used by mistake, the Tinderbox parser should ignore an outmost pair (as it would quotes) abut still honour brackets within the overall list value as implying a nested list. If Tinderbox reads from a List via code and reports (logs) a value with enclosing brackets, Tinderbox knows—in code—to ignore those as simply being list delimiters.

    Adding new list items to the end of the List

    With a List you can add/remove individual or multiple values and test its contents. A value added is inserted at the end of the existing list. Unlike a set-type, no deduplication occurs so adding a value a second time will create two entries. If $PetTypes' value is "cats;dogs", then:

    $PetTypes+=[rabbits];

    adds the new value to the end of the list, i.e. 'cats;dogs;rabbits', after which repeating the call

    $PetTypes+=[rabbits];

    this adds a second instance of "dogs" to the end of the List, i.e. 'cats;dogs;rabbits;rabbits'. This unlike a Set, were the second instance would be discarded as being a duplicate.

    Adding new list items to the beginning of the List

    To add new—not replacement—item(s) to the beginning of a list, add the existing value to the new list items:

    $PetTypes=[rabbits;hamsters]+$PetTypes; 
    Legacy code note: the last fails if using to old quote-enclosed format instead of square brackets.

    Adding an list item that is itself a list

    To add a new item that is itself a list, note the extra set of brackets needed. The following adds a new list item whose value is a two-item list.

    $PetTypes=$PetTypes+[[rabbits;bunnies]];

    Adding items at a specific list position

    To insert a new list at a specified location, i.e. adding a list item as opposed to replacing an existing value, iterate the list using List.each() with a custom counter. Store existing items in a new list and add the term when the loop reaches the desired place in the list. At the end of the loop write the new list back over the original List.

    Deleting items

    In actions using a - (minus) removes the supplied value(s) if present. Importantly, this removes all occurrences if the deleted item. If the List is 'cats;dogs;frogs':

    $PetTypes=$PetTypes-[cats;frogs]; this leaves only 'dogs' as a value.

    If there are multiple instances of the target item the first, by list order, is deleted. If the List is 'cats;dogs;cats;frogs':

    $PetTypes=$PetTypes-[cats;frogs]; this leaves only 'dogs' as a value.

    Replacing a list item's value

    The List[N] notation addresses any single List item using a zero-based address. Thus List[1] addresses item #2, whilst List[0] addresses the first. To replace item #3 in a list (assuming a big enough list):

    $MyList=[Frogs;Dogs;Logs]; 
    $MyList[2]=[Pogs]; results in a list of "Frogs;Dogs;Pogs"

    Additional list definition mark-up

    Lists and Sets may be written by enclosing them in square brackets, rather than inside quotes, as in the past. The newer form is more declarative of intent to the user and the app, so is recommended. Lists may be nested; for example, the list

    [ 1; [2;3]; 4] 

    contains a 3 elements — 1, the nested list 2;3, and 4.

    Long Tinderbox precedent holds that list addition adds each element of the two lists. For example

    $MyList = [1] + [2;3] 

    or

    $MyList += [2;3] 

    both result in the list 1;2;3 and not 1;[2;3]. To add a sublist to a list, use the operator list.extend(). Thus:

    $MyList = [1].extend( [2;3]) 

    results in the list [1;[2;3]].

    Offset assignment to a list of notes recognises bracket-enclosed lists correctly, for example:

    $Status([this;parent])="urgent"; 

    Implicit evaluation is no longer performed in bracketed lists. Thus,

    $DisplayedAttributes=[MyList;MyString]; 

    is now equivalent to

    $DisplayedAttributes="MyList;MyString"; 

    If new List terms need evaluation, use list() instead.

    Accessing nested lists

    Consider the following:

    $MyTestList = [1;[a;b];3]; 

    To retrieve the nested list:

    $MyString = $MyTestList[1]; results in '[a;b]'

    Note the square brackets are retrieved too, so for further use of the list this might be better:

    $MyString = $MyTestList[1].substr(1,-1); results in '[a;b]'

    To retrieve a value from that list:

    $MyString = $MyTestList[1][1]; results in 'b'

    De-duplicating a List: List vs. Sets

    Lists, unlike Sets, allow duplicate values. To de-dupe a List, use the .unique dot-operator:

    $MyList=$MyList.unique; 

    An older alternate method, which may be found in old demos is simply put its contents into a Set-type attribute:

    $MySet=$MyList; (deprecated in favour of the method above)

    If $MySet and $MyList both have the value [cats;dogs]: the following have different outcomes:

    $MySet=$MySet + [dogs]; gives 'cats;dogs'
    $MyList=$MyList + [dogs]; gives 'cats;dogs;dogs'

    The Set attribute does not add the duplicate value but the List attribute does. List data values are stored in the order added.

    Testing (querying) Sets & Lists

    To test a set or list, use the .contains() operator, syntax AttributeName.contains("tested_value"), returns true if any Set/List discrete value exactly matches the designated tested_value; if case sensitivity is irrelevant for the query use .icontains(). If a user attribute $PetTypes has a value of 'dogs;cats' then

    $PetTypes.contains("dogs") is true,

    but

    $PetTypes.contains("dog") is false 

    This is because Let/List matching does not allow partial matches, as via regex, unlike with String-type data.

    Other variants:

    $PetTypes.contains("Dogs").lowercase is true 
    $PetTypes.icontains("DOGS") is true 

    It can be useful to use a stored value as the search term, for instance using the name of an agent as the search term:

    $PetTypes.contains($MyString) is true 

    A query can test a single item from a list. For instance, if $MyList for note A is [3;4;5] and for note B is [1;5;10], then query:

    $MyList[1]==$MyNumber(agent) 

    will match B but not A. This is because only B has the number 5 as the second list item ('1' in a zero-based list).

    Escaping literal semi-colons

    If a list item must contain a semi-colon, it must be escaped, using a backslash, '\;'. Once the backslash is entered, it disappears and the list item containing the semi-colon is enclosed in double-quotes. Do not try to escape a value by adding the quotes directly, use the backslash method. Action code methods to make lists will treat a '\;' in an input string as an escape and act accordingly. Consider using String.replace() as a method for escaping backslashes (though only where intended!).

    Listing and Exporting sets

    The format() action operator and more recent .format() dot operator offer ways to turn sets into HTML lists for export. See Exporting Set-type data for more.

    System Attributes: Sets vs. Lists

    Most group-scope operators can work with lists or sets, as well as the find() operator (whose own output is a list) and literal list-based group designators; exceptions include $DisplayedAttributes where duplicates would not be helpful. It is the declared data type of the attribute being collected that informs the operator to return a list or set.

    Default/Empty value

    An empty string.

    Empty values in lists

    From v11.6.0, lists now allow blank (empty) list items when using the [ ] list notation. As a result, a trailing semi-colon will imply the intent of a last list item that is empty.

    Sorting order

    Lists are not sorted, so retain the order in which items were passed into the list, most recent being at the end. Lists can be sorted using action code sort operators or by setting the sort attributes of containers.

    List-type System Attributes

    Built-in attributes of the List data type are listed below:

    Number-Type Attributes

    [First introduced in v1.0.0]

    Number

    A numerical value. If no default value is specified, a Number type defaults to the value 0 (zero). User attributes of Number type may be configured, at first creation, as 'sequential'.

    A sequential number attribute is like a database counter field, where the next unused number is issued and values no longer used are not re-issued; i.e. the next number is always higher than the last. Sequential numbers start at 1. When a new sequential attribute is added to an existing document, the already-created notes are initialised with sequential values of the new attribute, starting with the first notes in $OutlineOrder sequence. Thereafter notes are numbered in the order added, regardless of $OutlineOrder.

    Very large or small numbers may be displayed (and set) in exponential notation:

    0.000001 = 1e-06 
    $MyNumber = 1.2e+3 sets '1200'

    When very large or small number strings are typed into a Displayed Attributes box the result may be '0', in which case use exponential notation.

    The Displayed Attributes display will also truncate the number of decimal places shown. The display limits seem to be:

    • Whole (non decimal) numbers will display up to 9 digits, i.e. between -999999999 and 999999999.
    • Numbers over 1, positive or negative, will display 6 digits e.g. 150.123 or 1.12346.
    • Numbers over 1, positive or negative, will display 6 decimal places e.g. 0.012345.

    When typing/pasting in number values to a KA box the input value is stored and not the rounded/truncated visible value. To see the decimal places in full coerce the value to a string, e.g. set a string attribute to the value of the number attribute. Beware that values copied from a Displayed Attributes display box use the visible value and not the real underlying value, so passing the number to a string and reading the latter is useful if data fidelity is required.

    Default/Empty value

    The value 0 (zero).

    Sorting order

    Ascending value in numeric sort order; default (0) thus lists first.

    Formatting number information

    See Formatting operators: Number.format(), Number.precision(). There are some format strings only used for Number-type data:

    • "l" (lowercase letter 'L') gives Number as a string using (OS) locale-dependent group and decimal delimiters. For instance, 1000.00 as seen on a UK system would show as '1,000.00' but as '1.000,00' on a German system.
    • "$" formats Number to a string in the local currency to two decimal points.
    • "$0" formats Number to a string in the local currency rounded to the nearest whole major unit (i.e. whole dollars only not dollars.cents.)
    • "X" converts Number to a string in Roman numerals. So 4 would give string "IV" .
    • "o" (lowercase letter 'O') converts Number to a string in the localised ordinal

    Number-type System Attributes

    Built-in attributes of the number data type are listed below:

    Number-type System Attributes set via Document Settings

    A number of Document Settings controls set the defaults for Number-type system attributes, directly or indirectly:

    Set-Type Attributes

    [First introduced in v1.0.0]

    Set

    A Set date type is a special type of string, within which discrete values are delimited by semicolons. When defining a Set in code, use the conventions are described for the List data type.

    In terms of stored data the Set and List lists are the same: a string containing one or more semi-colon delimited items. The difference is in the way Tinderbox handles the two data types, as lists may contain duplicate items. Although the Set-type pre-dates List-type in Tinderbox, Lists should be thought of as the underlying form and Sets as a refined (de-duplicated) form of List.

    A Set is useful for lists of topics, categories, and tags where duplication of listed items is not wanted:

    [astronomy;marine biology;chemistry] 
    [dogs;cats] 
    [3;9;15] 

    Note that the Set is always a string even if the values happen to be numbers: item values in a Set do not have explicit data types. A Set can have a single value, e.g. the third example above. With a single value there is no need to add a final semicolon and the same holds for the last of multiple values. Tinderbox will not mind if you supply a semicolon there (or after the last of multiple values), it will just strip it off as it processes the data. The default Set value is an empty string. A Set-type differs from a List-type in that duplicate values are not allowed, and the list of values is always A–Z lexically sorted.

    To apply values directly to a Set-type attribute via the Displayed Attributes or via Info view or via the Inspector's Quickstamp, simply type the values as seen into the data box. In all these methods, you do not need to add enclosing quotes, but each discrete value should be separated with a semi-colon.

    Legacy: Sets and auto-sorting. Prior to v9, sets did not always re-sort. Sets were then reimplemented to improve performance with large sets, which makes a Set more aggressive in asserting its control of the sequence of their elements. Compared to previous use, the stored order of items in the Set's value list are much more likely to change from the order as originally entered into case-sensitive lexical sort order. This may catch out long term users being used to Sets generally retaining their as-created item order. If the latter is needed, it may make more sense to use a List type instead.

    Declaring a new Set

    If setting a Set's literal values via action code use the square bracket [ ] Set definition:

    $MySet=[Frogs;Dogs;Logs]; 

    Importantly, the bracket notation replaces the older now-deprecated legacy method of using enclosing quotes:

    $MySet="Frogs;Dogs;Logs"; NOTE: do not use this for new code!

    Whilst both methods work and the latter, older, method will be found in many demos and tutorials, the bracketed notation is now the preferred method and old code should be updated is re-suing it.

    Importantly, when typing/pasting a Set's values into a UI input box such as the Inspector, Get Info, or Displayed Attributes, the enclosing brackets or quotes (as used above) should be omitted, i.e. using planes;trains;automobiles not [planes;trains;automobiles]. If brackets are used by mistake, the Tinderbox parser should ignore an outmost pair (as it would quotes) abut still honour brackets within the overall list value as implying a nested list. If Tinderbox reads from a Set via code and reports (logs) a value with enclosing brackets, Tinderbox knows—in code—to ignore those as simply being list delimiters.

    In actions, + adds an item to a Set if it is not already present, and -- removes it if it is present. These are now generally replaced by the += increment and -= (minus) decrement operators.

    Adding values

    With a Set you can add/remove individual or multiple values and test its contents. In actions, + adds an item to a set if it is not already present, and -- removes it if it is present. Values must be enclosed in double quotes.

    If $PetTypes' value is 'cats;dogs':

    $PetTypes=$PetTypes+[owls;dogs]; the Set is 'cats;dogs;frogs;owls'.

    Deleting values

    To delete a value, if $PetTypes' value is 'cats;dogs;frogs':

    $PetTypes=$PetTypes-[cats;frogs]; this leaves only 'dogs' as a value.

    Testing (querying) Sets & Lists

    To test a Set or List, use the .contains() operator, syntax AttributeName.contains("tested_value"), returns true if any set/list discrete value exactly matches the designated tested_value; if case sensitivity is irrelevant for the query use .icontains(). If a user attribute $PetTypes has a value of 'dogs;cats' then

    $PetTypes.contains("dogs"); istrue,

    but

    $PetTypes.contains("dog"); is false 

    This is because Set/List matching does not allow partial matches, as via regex, unlike with String-type data.

    Other variants:

    $PetTypes.contains("Dogs").lowercase() is true 
    $PetTypes.icontains("DOGS") is true 

    It can be useful to use a stored value as the search term, for instance using the name of an agent as the search term:

    $PetTypes.contains($MyString) is true 

    A query can test a single item from a list. For instance, if $MyList for note A is [3;4;5] and for note B is [1;5;10], then query:

    $MyList[1]==$MyNumber(agent) 

    will match B but not A. This is because only B has the number 5 as the second list item ('1' in a zero-based list).

    Listing and exporting Sets

    The format() action operator, and newer .format() dot operator offer ways to turn sets into HTML lists for export. See Exporting Set-type data for more.

    Set data vs. List data

    List-type attributes came to Tinderbox after Sets. Lists, unlike Sets, allow duplicate values and Sets can better be thought of as de-duped versions of Lists, i.e. lists with no duplicate entries.

    To de-dupe a List, simply put its contents into a Set-type attribute:

    $MySet=$MyList; 

    Escaping literal semi-colons

    If a list item must contain a semi-colon, it must be escaped, using a backslash, '\;'. Once the backslash is entered, it disappears and the list item containing the semi-colon is enclosed in double-quotes. Do not try to escape a value by adding the quotes directly, use the backslash method. Action code methods to make lists will treat a '\;' in an input string as an escape and act accordingly. Consider using String.replace() as a method for escaping backslashes (though only where intended!).

    Default/Empty value

    An empty string.

    Empty values in lists

    Whilst, from v11.6.0, lists now allow blank (empty) list items when using the [ ] list notation. However, the Set-type behaviour of weeding duplicates and re-sorting also removes all empty items in a list (e.g. from a List-type attribute) passed to a set.

    Sorting order

    As for a String Data Type, using the literal string values of the Set in case-sensitive lexical sort order. For example, the 5-item of values 'Ant', 'ant', 'bee', 'Cow', 'cow' when passed to a set would store as "Ant;Cow;ant;bee;cow".

    Set-type System Attributes

    Built-in attributes of the set data type are listed below:

    String-Type Attributes

    [First introduced in v1.0.0]

    String

    A sequence of characters, most often as words and sentences. If no default value is specified, a String type defaults to an empty string.

    Strings are not delimited (i.e. quotes are not required).

    The set and action data types effectively special forms of the string data type.

    Default/Empty value

    An empty string.

    Sorting order

    Ascending order using literal string value in lexical sort order.

    String-type System Attributes

    Built-in attributes of the string data type are listed below:

    String-type System Attributes set via Document Settings

    A number of Document Settings controls set the defaults for String-type system attributes, directly or indirectly:

    URL-Type Attributes

    [First introduced in v5.0.0]

    URL

    A URL string. If no default value is specified, a URL type defaults to an empty string. URLs are not delimited (i.e. quotes are not required).

    URL attributes behave like string attributes. When displayed in a note's displayed attributes table, URL-type attributes show a globe icon before the attribute value. Pressing the icon opens that attribute's stored URL (if any) in the default web browser.

    Links dropped on a URL-type Displayed Attribute populate that attribute; links dropped on any other data type Displayed Attributes populate the system $URL.

    If using a local path to a file, e.g. to enable AutoFetch use, you must use the file:// protocol rather than a bare file path.

    Default/Empty value

    An empty string.

    Sorting order

    As for String Data Type.

    URL-type System Attributes

    Built-in attributes of the URL data type are listed below:

    Determining the data type of an attribute

    All attributes in Tinderbox, System or User, are one of a number of different Data Types (String, Boolean, etc.). The type of an attribute is important in Tinderbox action code as it has some affect on how you may use the attribute and the under-the-hood assumptions Tinderbox makes when using it. How then to tell the data type for any given attribute?

    User or System? If uncertain, look at the User Attributes list first, as there are usually only a few of these. If the attribute is a User one, click in the left column and look at (but do not change!) the 'type' pop-up at the top of the right side of the dialog.

    If the attribute is not on the User list, it must be a System attribute. The quickest way to then find its data type is to use aTbRef's System Attribute listing, which lists all system attributes in alphabetical order.

    If you do not have access to aTbRef, use the Document Inspector's System tab listing to find the attribute. Once the attribute is selected, the data type is shown on the tab.

    Default values for attribute Data Types

    If no value has been defined via a preference or otherwise inherited or manually set, the following are the value of 'no value' for each attribute data type.

    • Boolean: false
    • Date: "never" (a string)
    • Number: 0
    • Interval: "00:00" (a string representing zero hours:minutes)
    • String & String-type: "" (an empty string, no data).
    • List: [].
    • Set: [].
    • Dictionary: {}.

    All the remaining Tinderbox data types are essentially special forms of a String-based data type and so use the same default value, of an empty string:

    • Action.
    • Color.
    • File.
    • Font.
    • URL.

    †. Multi-value types. Only 3 types, out of all the data types above, allow the storage of multiple values (i.e. 'lists' of discrete values), two of which are themselves specialised versions of the first:

    • List. A list of values.
    • Set. A list where any case-sensitive duplicate values are automatically removed (so strings 'Cat' and 'cat' are still treated discrete values). Sets also use a lexical auto-sort so cannot be relied upon to retain user-set listing order (e.g. such as by setting $Sort).
    • Dictionary. Holds a list of 'key:value' pair values. Keys must be unique, as this is how the list data is queried/altered (i.e. asked for or edited). Currently, key values that are themselves lists are allowed but cannot be accessed via action code. Again sorting the list is of little value as data is accessed via the key for any discrete 'key:value' list value.

    Set vs. List

    A historical note for long-time users. Originally, the Set data type was the only multi-value data type, with List and Dictionary being added later on. The original Set only auto-sorted occasionally, if at all. Since changes in v8 Sets now are always auto-sorted, for performance reasons. That change may catch out long-term users of Tinderbox as previously Sets re-sorted so rarely that the made sense as de-duplicated Lists. Now that affordance has gone, use List type to preserve order and List.unique if de-duplication is needed.

    However, the List data type is best understood as the basic (multi-value) listing type—it records what is entered in the order entered and does not alter it.

    Document versus Application: system attributes and defaults

    When Tinderbox generates a new TBX document, all current system attributes are added to the document. Each such attributes also stores the (then current) default for that attribute.

    But, over time, new versions of Tinderbox are released. Occasionally, an existing system attribute may change its default. An example is the default font used in text ($TextFont). Separately, new system attribute may appear. Less often, old system attributes are no longer added to new files.

    So, what happens to existing TBX files in these situations?

    A new default value for an existing system attribute

    This has no effect on existing documents as they retain their originally defined default value. By comparison, new documents will define the same attribute use the newer, now current default. If the user wishes to use the newer value, then they edit the attribute's default—see the 'review actions' section below. This avoids nasty surprises where the new default to be auto adopted and where the existing document behaviour assumed the old default value, such as might affect automation within the document.

    A new app version gains a new system attribute

    On first use in the new version of the app, the new system attribute(s) will be added to the documents existing system attribute, using the current default values.

    An existing system attribute is dropped from the schema in a new app version

    No change occurs—existing apps retain their pre-existing system attributes, even if some are now moribund. There is no way for the user to delete these now obsolete or un-needed attributes but they should simply be ignored. Any new documents will lack these attributes completely. A point to bear in mind is that occasionally a new attribute replaces an old one, but both are supported. Thus $AccentColor replaced $Color2. Whilst, newer TBXs will lack $Color2, older documents will likely have both and both will store the same values. This ensures old document's action code does not just break. Ideally, if such a 'replacement' occurs, users should review code and replace any use of to the old attribute name with the new name.

    Review actions for the user to consider

    If any of the above happen:

    • Consider if a new default value for a system attribute is appropriate for existing document(s). For those documents where change is appropriate, manually change the default value in the System Inspector or, for attributes whose value is set via Document Settings, in the appropriate tab of Document Settings.
    • Where new attributes are added, deprecating older ones, review documents for use of the older attribute. The two key places to check:
      • Displayed Attributes. Those using prototypes will find this easier than where Displayed Attributes are set per note. Do not forget, a note's list of Displayed Attributes is stored in $DisplayedAttributes. Thus, using $Color2 as an example a query like hasLocalValue("DisplayedAttributes")&$DisplayedAttributes.contains("Color2") will find all notes that have Displayed Attributes set and which not inherited (e.g. not using a prototype) AND where the Displayed Attributes table includes the 'Color2' attribute.
      • Action code. For attribute based code such as rules, edicts, OnAdd etc. ,the same sort of query as above can be used, e.g. for edicts: hasLocalValue("Edict")&$DisplayedAttributes.contains("Edict"). For stamps and functions, add the built-in Hints (if not already in the document) and test the $Text of Stamp and Library notes.

    Keywords for Date-Type Attributes

    Note: both 'keyword' and 'designator' have long been used interchangeably for the terms described below. Other types of designator are described here.

    When defining Date-type data Tinderbox's code parser accepts the following strings as placeholders for calculated dates:

    • yesterday
    • today
    • now
    • tomorrow

    Duration keywords

    All provide a date/time, to seconds-level granularity. today and now return exactly the same value, with yesterday being 24 hours previous to now and tomorrow 24 hrs later. These alternate keywords can make for more intuitive contextual use in code.

    The following designators can be used to modify the above. However, if simply used on their own, rather than as a modifier they do not return a valid date/time:

    • day(s)
    • week(s)
    • month(s)
    • year(s)
    • hour(s)
    • minute(s)
    • second(s)

    No value keyword

    There is a further special case:

    • never. No date, and regarded as earlier or later than any real date. This is also the default/empty value for Date-type attributes.

    Case-sensitivity of keywords

    Treat usage for the above placeholders as case sensitive.

    Day-of-the-week keywords

    Day placeholders, such as Sunday, Monday, etc., may also be used. Tinderbox recognises the day of the week and interprets it as the day after today with that week day. Thus on Sunday June 1, the date "Sunday" refers to Sunday, June 8. These keywords are locale-observant.

    • The date parser recognises the day of the week in the current (macOS) locale. Recognised forms include the full day (Sunday), the short day (Sun), and the very short day (S). Note though, that the very short day is ambiguous in many languages, including English.

    In other respects, days of the week act like the core keywords, e.g. today, in that they can be modified similarly, e.g. "Monday - 1" week is the previous Monday.

    Dates may be modified by adding and subtracting "minutes", 'hours", "days", "weeks" and "years":

    date("today+65 minutes") 

    Explicit (24-hour clock) time can be used, in which case it comes at the end of the string:

    date("today+7 days 00:00") 

    The latter is useful to ensure that a base like 'today' or 'now' that take system clock time are set to an exact known time, as may be needed for accurate date comparison.

    Normally time is input is the form consistent with the users short date(/time) form such as "09:30" or "9:30 AM"but more flexibility is offered for import making it easier to set times as part of date/time designators, such as:

    *"today 0930"

    *"today 930pm"

    *"today 11"

    The first two before half-past nine in the morning, The latter will be interpreted as 11 AM (11:00): the lack of minutes implies to set them as 00.

    Note that the date(string) operator arguments are written as quoted strings which may include addition/subtraction signs. This format is deprecated:

    date("today" +" 65 minutes") INCORRECT!

    for this form, noting all string inputs are in one string:

    date("today + 65 minutes") 

    If using Attribute values in a date action code expression simply use the $-prefixed attribute name outside the quoted string:

    $MyDate = date($Modified+"5 minutes") 

    If modifying a date and the code part cannot be evaluated as a valid date, the original unmodified date is returned, i.e. $MyDate is unaltered. This avoids unintentional creation of undefined ('never') dates.

    Date parsing: the date "tomorrow 8" is treated as 8 o'clock tomorrow. Note in that older versions it was interpreted as 8 days from tomorrow. "Tomorrow+8" continues to denote 8 days from tomorrow.

    Beware that any Date-type attributes initialised using year, month & day without a time element will use current system time as opposed to a 00:00:00 which might otherwise be assumed.

    What are Displayed Attributes?

    [First introduced in v8.8.0, replacing KeyAttributes from v1.0.0]

    Any note or agent may optionally display a table of user selected attributes. The point is to enable the user to view those attributes' values in the note text pane instead of having to open the Get Info pop-over or use the Properties Inspector's Quickstamp method.

    Importantly, there is nothing special about these attributes compared to other attributes: new user often assume these are the only available attribute—wrong!.

    A note's Displayed Attributes, i.e. the contents of its Displayed Attributes table, is simply a user-chosen list of attributes considered worthy of display for a given note. Indeed, this listing is stored, and inherited as the value for attribute $DisplayedAttributes.

    Reasons for using Displayed Attributes so can include:

    • Making it easy to see or edit certain attributes.
    • Using the Displayed Attributes table as a form of dashboard.
    • In demos and tutorials, it can help the learner view and edit pertinent attributes without having to use other (unfamiliar) parts of the program to do so.

    As new users often first come across Displayed Attributes or reference to the feature, this can cause confusion. To be clear: adding an attribute to the Displayed Attributes table has no effect on the displayed attribute(s)' value or upon those attribute(s)' inheritance. However, such editing of the Displayed Attributes table does break inheritance of $DisplayedAttributes itself. Therefore a 'displayed' attribute is merely more easily viewed/edited in the context of the selected note.

    Legacy: the old term 'Key Attributes' was replaced by the more descriptive 'Displayed Attributes'

    Pre-populating Displayed Attributes pop-up lists

    When string-based attributes (String, List, Set) are shown as Displayed Attributes, once discrete values are added to the attribute these are all shown via a pop-up list via the triangular icon at the right end of the attribute value edit box. For fast entry, autocompletion using matched list items is also possible. However, do bear in mind limitations on the length of and number of entries in these lists.

    It is possible to set suggested value lists. These can be set manually via the Inspector for user attributes (and some system attributes) or by using action code. Consider an attribute $MyStatus that will hold the status of bids. To pre-set 3 suggested values 'won', 'pending' and 'lost':

    attribute("MyStatus")[suggested]=[won;pending;lost]; 

    But, what if that list needed to change, e.g. if a new status 'cancelled' was added,? The above list could be stored in a list attribute that could be edited as a Displayed Attributes avoiding having to set the value in code. Thus a note, in this example called "TbxConfig", could store the suggested values in a List or Set (the latter so as to avoid accidental duplicates). So, its $MyList could be [won;pending;lost;cancelled].

    Now, a stamp 'Set Suggested Status" could have this code:

    attribute("MyStatus")[suggested]=$MyList("TbxConfig"); 

    If the list needs to be altered, simply run the stamp after doing the edit.

    Legacy method

    The following is deprecated for the above method of using suggested values. Another way can be used is there is a note for each potential value. Thus a container 'Bid States' might hold child notes 'won', 'pending', 'lost'. This code can be used to set the $MyStatus suggested values from the children of the 'Bid States' container:

    attribute("Bid States")[suggested]=collect(children(/Status),$Name); 

    If that code is run as a rule or edict, whenever a new note is added to, deleted from or renamed in that container, the suggested values will get updated.

    Attribute inheritance of preferences and settings

    Settings controlling the look or behaviour can be set at various levels. Consider something controlled at note level via an attribute. Working back up the inheritance chain, this is how the value may be derived, if not explicitly set at a given level. The lowest level (and the higher in the list below) at which a value is set dictates the value used at note level:

    - within the TBX:

    • Attribute value for this note
    • (Attribute) value inherited from a prototype
    • (Attribute) value inherited from a doc-level user-set default.
    • Value from Document Settings (i.e. this TBX only)

    - at the TBX creation

    • Value set via a user config.xml file
    • Value from Tinderbox built-in document defaults
    • macOS derived values (e.g. locale-based settings)

    The latter can, in some cases, be also be modified by the user editing configuration files, or at the extreme by modifying the app package's configuration files though this is not suggested!

    This inheritance model is explained in more detail under the Inheritance Cascade section.

    Intrinsic attributes

    Attributes that are intrinsic to all objects and thus not inherited, or shared, by aliases.

    While most attributes are inherited from prototypes, a few attributes are intrinsic, i.e. their values apply to specific notes and are not inherited via prototypes or aliases. For example, $Xpos and $Ypos are not inherited (because moving a prototype should not move notes that happen to use the prototype!). $Width and $Height are also not inherited, but note changes allowing one-time setting of height and width on first applying a prototype. If they were, then resizing a prototype might in turn resize notes that inherit from that prototype—perhaps covering other notes or disrupting a complex map. A separate case is an attribute like $RuleDisabled for prototypes, for controlling scope of action code execution as explained under disabling action inheritance.

    There are few examples:

    See a full listing of intrinsic attributes: be aware that many read-only system attributes are also intrinsic. Whether a note is intrinsic or not is also noted on the Document Inspector's System tab. It can also be verified in the TBX document's XML.

    User attributes are never intrinsic and cannot be made so.

    Aliases can show a discrete $DisplayName but it can only be set via conditional Display Expression code. Simply using the Text Inspector's Title sub-tab's $DisplayExpression input box with non-conditional code always sets both the original's and all aliases' $DisplayName to the same value.

    For an alias to use a different $DisplayName from its original or other aliases (in different containers), the conditional code needs to identify the context of the note in scope. This is most easily done by looking at an attribute of the note's parent as this is always discrete to the individual original or alias. Using data stored in the parent's attribute(s) is also a neat way for the conditional code to insert different values in different branches of the display expression's code.

    Intrinsic attributes are also significant if setting attribute values of a note via an alias, such as in an agent's action. If it is necessary to use values from the original note and not the alias, then code should use 'original' designator. Thus, in an agent action:

    $Xpos = 4; 

    …sets the $Xpos of the alias currently being processed. To make the action set the attribute in the original of the alias, use:

    $Xpos(original) = 4; 

    You might want to set both the alias and original values, in which case, this also works:

    $Xpos = 4;$Xpos(original) = $Xpos; 

    Of course, for all non-intrinsic attributes, setting the attribute in the alias also sets it for the original and using the original designator is not required (though it would still work if you used it by mistake).

    The intrinsic status of an attribute is not inheritable.

    Action-based attributes

    Several system attributes use the 'Action' data type. Note: this data-type is not used or available for user-defined attributes.

    Action-type attributes further divide into two discrete groups, as the action code they contain is used slightly differently by Tinderbox:

    Although both an action and an expression are parts of Action code, the scope of what they (may) do differs. How they differ is explained in Expressions vs. Actions in Action code.

    All system attributes that store action code to support actions/expressions or of the 'Action' data type and are listed under Action-Type Attributes. User attributes may not use the Action data type.

    Action-storing attributes

    These attributes store the complete code of actions such as a note's OnAdd or Rule. They are:

    There are a few more miscellaneous Action-type attributes:

    See also

    ghjgh

    Expression-storing attributes

    A small number of Action-based attributes store action code expressions, rather than complete actions:

    The above attributes' purpose/use is discrete articles below:

    See also:

    Display Expressions

    Tinderbox can use calculated screen titles, based on the $DisplayExpression attribute. The output of this (single) expression is displayed as $DisplayName. For each note, Tinderbox evaluates that note's $DisplayExpression to create the note's name. The stored expression it assumed to be action code, though it may be just a literal text string.

    Note: what is an expression?

    Be aware that if $DisplayExpression is empty, or not a valid action syntax expression, or the expression returns no value (such as an an empty string ""), then Tinderbox will instead display the note's $Name value as it will assume you want some form of title displayed.

    Although the display expression may include conditional logic (see below) generally it is a good idea to avoid complex calculation within the expression. See 'Performance Considerations', below.

    Example rule:

    $Name +" (" + $WordCount + ")" 

    …will display the note's word count in brackets at the end of the note. Thus, "Trip Report" becomes "Trip Report (579)". $Name will continue to return "Trip Report".

    This attribute is of the 'action' data type. It takes a string argument which must be valid action syntax.

    Subtracting two dates returns the number of days between two times, even if the result is a string such as $DisplayExpression. For example:

     $Name+": "+($DueDate-date("today"))

    will generate strings like: "Buy groceries: 7"

    Note the parenthesis around the second part of the expression; if omitted, the expression would be interpreted as an attempt to subtract two strings:

     ($Name+": "+$DueDate)-(date("today") 

    If just including a date attribute in an expression it is possible to confuse Tinderbox's parser. Assume $DemoDate for note "Project X" is 28/07/2009 17:57 (on a system using day/month order dates). Consider the following display expressions:

    $DemoDate 

    gives the string: '28/07/2009 17:57'

    $Name + " : " + $DemoDate 

    gives the number string: '3313478996'. This is because Tinderbox assumes the user is trying to do some form of date arithmetic. The way around this is to use the format(data, formatString) operator. The latter emits a string, telling Tinderbox that all it has to do is concatenate the strings. Thus:

    $Name + " : " + $DemoDate.format("D/M0/y h:mm") 

    gives the string: 'Project X : 28/07/2009 17:57'.

    Setting $DisplayExpression's code via action code

    Another context where care is needed is if setting the $DisplayExpression of another note, e.g. via an $OnAdd action. In this cases it is important to ensure the application understands the result is a string. A good example is when the code returns something that might be a sum, like a date in "20/5/2010" form: The following is not good $OnAdd code:

    $DisplayExpression=$Created WRONG
    $DisplayExpression=$Created.format("l") WRONG

    Although both the above right side values can safely be added into a Text Inspector Title sub-tab's Display Expression box, they do not work for code-based assignments. Instead, it is necessary to force a string:

    $DisplayExpression='""+$Created+'"'GOOD
    $DisplayExpression='$Created.format("l")'GOOD

    Notice, in both how single quotes are needed. In the first case they enclose each instance single instance of a double quote (quote characters cannot be escaped in Tinderbox). In the second case they enclose the whole string as it already contains double-quotes surrounding the date format string.

    A Display Expression can use conditional if/else conditions but there can only be *one* top-level condition in the $DisplayExpression code. More complex code needs a slightly different approach as discussed in the sections below.

    Performance Considerations

    If the display expression needs to use pre-calculated values that are not provided by system attributes, then a rule (or other such action method) should be used to calculate the value and place it in a user attribute which the display expression can then evaluate, as the following sections explain.

    Conditional Expressions in $DisplayExpression

    Display expressions also accept conditional expressions, i.e. using 'if()' statements. For example, in a TBX listing books there might be agents listing & sorting by ISBN and by Author. It would be useful if in each of the latter cases the matched note's alias showed the relevant attribute as part of the alias' screen title whilst using $Name in all other cases. Note that with a conditional expression it is still necessary to define something for the 'no match' branch or else notes matching that condition get a display expression of nothing, which results in 'untitled' being shown on screen. Here's the expression:

    if($Name(parent)=="ISBN"){$ISBN+" - "+$Name}else{if($Name(parent)=="Author"){$Author+" - "+$Name}else{$Name}} 

    That is quite a long and complicated piece of code, due to the nesting and that is for only 3 conditions (match 'ISBN', match 'Author, no match). To avoid complex nesting of conditional statements, it can be easier to assemble the desired output outside $DisplayExpression, as explored in the next section.

    Using an attribute to store pre-evaluated Display Expressions

    For longer pieces of code it can be useful to put the expression's code in an action such as a rule or edict and store the result in a user attribute. Conveniently, this makes it easier to split apart the various clauses in the expression to check nesting, etc. Assume the expression above has been placed in the edict of a prototype called 'Book' (and a user String attribute 'DisplayString' added), the nested if()s can be avoided:

    	$DisplayString=;
    	if($Name(parent)=="ISBN"){
    		$DisplayString=$ISBN+" - "+$Name;
    	}else{
    		if($Name(parent)=="Author"){
    			$DisplayString=$Author+" - "+$Name;
    		}else{
    			$Name
    		}
    	}

    Now, for tour book notes (using the 'Book' prototype) use this Display Expression:

    $DisplayString 

    Now the Display Expression simply reads a precompiled string with no in-Display Expression evaluation needed. The result is the same as putting the initial code into each note's $DisplayExpression except that now it is easier to maintain and edit. Plus, the full code evaluation effort occurs outside the Display Expression evaluation.

    Hover Expressions

    Hover Expressions are action code expressions, like Display Expressions, but which are displayed in a tooltip-like floating pane to the right of a map icon when the icon is moused over. The same hover display method is also used in Outline, Chart and Timeline views, with the hover panel displayed below the hovered-on item.

    Note: what is an expression?

    The hover expression allows extra information to be viewed without having to open the note. A trivial example might be to show the word count for a note's $Text. This feature is not intended to preview very large amounts of $Text but rather to do things like expose extra contextual information, much in the way Displayed Attributes and Display Expressions are used.

    The expression's action code is stored in attribute $HoverExpression and is a string of action code. It might be an attribute reference:

    $WordCount 

    or a simple literal string:

    "Do not forget to review this!" 

    or an action code expression:

    "Word count: " + $WordCount 
    $Price * $NumUnits 

    Line breaks are allowed in strings using a the '\n' construct:

    "Word count: " + $WordCount + "\n\n" +$Text 

    The displayed hover panel draws text in $HoverFont, with the font size controlled by $MapTextSize. The panel is always a translucent dark panel with white text. The panel is drawn 350 pixels wide with height never exceeding half the Map view's window height. The hover expression box uses rounded corners and is suppressed if the expression's code only returns white space (i.e. no visible text); also, the box is offset further right so as not to obscure $Name data.

    Images in Hover Expressions

    The hover panel can also include an image.

    If a note has both a hover image and a hover expression, the hover expression is now displayed even if the hover image doesn’t exist (i.e. the image source cannot be resolved or the image file is missing).

    Table Expressions

    In map view, containers and agents (and their aliases), but not ordinary notes, can display tabular summaries of their contents using code stored in $TableExpression and $TableHeading which can be set in the attributes or via the UI using the container's Summary Table Properties pop-over dialog.

    Note: what is an expression?

    Tables are drawn only if there is adequate space in the title bar area. The number of rows displayed in the table is limited by the available space; increasing the size of the note (and its $TitleHeight) will increase the size of the table, i.e. the number of rows displayed. Note that the container's sort order is reflected in the table. See more on a container's title height.

    The displayed data is for the container's child notes; descendants are not included. For example, if $TableExpression is

     $Name+"|"+$WordCount
    Note: The '|' character (vertical bar or 'pipe') delimits code defining data for the separate columns of the table.

    For the above code, Tinderbox will draw a two-column table containing the $Name and $WordCount of the first few children of the container (for why only some children may be listed drawn see above).

    The expression's action code may be conditional. This lists all children with $Name and $Sibling order data displayed:

    if($Prototype != "Attributes"){$Name+"|"+$SiblingOrder} 

    This conditional version ignores any children that are agents:

    if(!$AgentQuery){$Name+"|"+$SiblingOrder} 

    This version only lists items of prototype type "Event":

    if($Prototype += "Event"){$Name+"|"+$SiblingOrder} 

    Amount of table data displayed

    If no $TableExpression is specified but space is available in the title bar, Tinderbox displays an excerpt of the $Text of the container or agent, as it does for notes. If a Table Expression is defined, display of $Text is suppressed, regardless of the height of $TitleHeight. In other words, it is possible to display either a table of child data or $Text but not both at the same time.

    Table headings

    Optional column headings may be specified in the string attribute $TableHeading. Again, columns should be separated by a '|' but note that if referring to attribute names in $TableHeading, a $ prefix is not used as the name is used as a literal string.

    So, the heading may be any one of:

    • a text label: "Note title|Word count"
    • an attribute's name: "Name|WordCount"
    • a mix of the two: "Name|Count of WordCount"

    Note the lack of $-prefixes in the latter two examples where an attribute's name (as opposed to its value) is used literally in the heading.

    Delimiting columns

    In bother the heading and the data (expression), the '|' characters to delimit columns is simply inserted inline in the name string, no explicit padding with space characters is required. Nor is there a need to se a '+'Any of the following could be used for the above table expression example:

    Other presentational points

    The left column (table and heading) is always left-aligned with all other columns being right-aligned.

    For agents, the table is shown beneath the title whilst the viewport remains above.

    The table uses various other attributes for its styling:

    *Text font: the table is drawn in $NameFont

    *Colour: the table default to use $NameColor but will use $MapBodyTextColor if set differently from $NameColor.

    *Text size: uses $MapBodyTextSize. Note setting the value to 1 will suppress display of table & text data.

    • The table heading and content have the same font/colour/size and cannot differ from each other.

    Attribute Listings

    Attributes are the building blocks of a Tinderbox note. This section contains listings of Tinderbox's system attributes in 3 different forms:

    Also in this section:

    Remember that the attribute value actually used at note level is subject to inheritance. As well as setting a new value to an attribute Tinderbox offers ways to:

    Links to child articles:

    System Attribute List

    System Attributes tell the System how to display, handle and export Notes and links. System Attributes are defined for every note, agent and adornment (though in the latter two cases not all attributes are used/applied).

    Occasionally, Tinderbox releases may add some attributes not described here in aTbRef. These attributes are generally experimental and not intended for use by ordinary users. Such attributes will either disappear again or be formally adopted and only then described in aTbRef.

    In documents used across many successive versions of the app be aware that system attribute may retain old system attributes no longer generated in new documents; these legacy items will cause no harm.

    As current versions of the app do not normally define legacy-supported attributes in new TBX documents, the count of system attributes here may be c.10–15 items more than the count seen for a new Tinderbox document.

    The attributes are broken into several groups and when listed in $DisplayedAttributes or the Note Info window, attributes are listed alphabetically within the groups. The groups are as follow, and are shown in the order they are listed in the UI:

    • System Attributes:
      • Agent. Information pertaining to agents.
      • AI. Attributes related to Natural Language Processing (NLP) and Artificial Intelligence (AI).
      • Appearance. Attributes controlling the appearance of view icons.
      • Composites. Attribute relating to use of composites.
      • Events. Attributes relating to event date/times.
      • General. Generic information about notes. Many of these attributes are calculated read-only values.
      • Grid. Setting relating to (map view) adornment grids.
      • HTML. Settings related to HTML export.
      • Iris. Experimental (currently not used).
      • Map. Information relating to visual display of notes, agents and adornments in Map view (and other Views).
      • Net. For data derived from the Net, e.g. RSS, etc.
      • Outline. Attributes controlling Outline view related features.
      • People. For data about people and their contact info.
      • Places. For data about location.
      • Posters. For data configuring map posters.
      • References. For import of reference data.
      • Sandbox. For easy testing of action code.
      • Scrivener. For Scrivener import.
      • Sorting. Flags for sorting container content.
      • Storyspace. Data used by Tinderbox's sister app Storyspace (both use a common file format)
      • TextFormat. Information pertaining to visual display of a note's data in Note windows.
      • Textual. Text export settings and general text-related data.
      • Watch. This group holds a series of attributes to support the exchange of information with the web (and via that the iPhone/iPad) using DEVONThink, Apple Notes, and Finder folders. (The group used to be called 'Simplenote'. No longer supported apps: Simplenote, Evernote).
      • Weblog. Data for configuring Weblog export.
    • User (created) Attributes. Any attributes created by the user, none are created by default. These user attributes are limited to the current document and cannot be transferred except by copying the document or using an OS Stationary document.

    This is a list of all System attributes:

    Abstract

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     string   [other string-type attributes]

     (not set - empty string)

     References   [other References Group attributes]

     Data synch

     No

     No

     No

     No

     v7.2.2

     Baseline

     As at baseline


    Holds the abstract from reference imports.

    Previously this data was imported to $Text.

    AccentColor

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     color   [other color-type attributes]

     dark warm gray dark

     Appearance   [other Appearance Group attributes]

     Map item general configuration

     No

     Yes

     No

     No

     v7.2.0

     Baseline

     As at baseline


    Specifies the note's accent colour (replaces $Color2)

    It is used for the alternate colour of the $Pattern drawn on the (background) $Color of a note in a map view.

    It is also used for the accent colour in bar() and vbar() map progress bar patterns, as well as container plots.

    The default is 'dark warm gray dark'.

    The colour can be set via the Appearance Inspector ▸ Interior tab.

    Retained for backwards compatibility, $Color2 is deprecated in favour of $AccentColor which fulfils the same role but with a more descriptive name. Both set the same colour.

    AccessDate

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     string   [other string-type attributes]

     (not set - empty string)

     References   [other References Group attributes]

     Data synch

     No

     No

     No

     No

     v5.11.0

     Baseline

     As at baseline


    Used for Bookends reference import. Maps to RIS data tag 'Y2'.

    Address

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     string   [other string-type attributes]

     (not set - empty string)

     Places   [other Places Group attributes]

     Locational data

     No

     No

     No

     No

     v3.5.1

     Baseline

     As at baseline


    Intended for storing a person's address.

    If populated, Tinderbox will attempt automatic geolocation and to populate $Latitude and $Longitude.

    AdornmentCount

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     number   [other number-type attributes]

     (calculated)

     General   [other General Group attributes]

     Calculated data

     No

     No

     Yes   [other read-only attributes]

     No

     v6.0.0

     Baseline

     As at baseline


    The number of adornments that are immediate children of this agent or container.

    Adornments are not included in $ChildCount.

    AdornmentFont

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     font   [other font-type attributes]

     RingsideCondensedSSm-Light

     Map   [other Map Group attributes]

     Map configuration

     No

     No

     No

     No

     v7.0.0

     Baseline

     As at baseline


    This determines the title font used by adornments.

    If $AdornmentFont is empty at document default level, i.e. there is no value set, then the value of $NameFont is used for adornment titles. The default value of $AdornmentFont is RingsideCondensedSSm-Light.

    AgentAction

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     action   [other action-type attributes]

     (not set - empty string)

     Agent   [other Agent Group attributes]

     Action code

     No

     Yes

     No

     No

     v1.0.0

     Baseline

     As at baseline


    Action code that an agent applies to each of its matching aliased notes, i.e. its children.

    The agent's actions are applied to aliases though the exact object referenced be modified by use of the 'original' (especially for intrinsic attributes) or 'agent2' designators.

    The contents of $AgentAction are shown in the Action Inspector ▸ Action sub-tab, allowing review and manual editing of its value. This attribute is the equivalent of $OnAdd for a normal container note. The agent's actual $OnAdd attribute is ignored for action purposes. $AgentAction can also be set via the ▸ agent tab.

    AgentCaseSensitive

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     boolean   [other boolean-type attributes]

     false

     Agent   [other Agent Group attributes]

     Agent configuration

     No

     No

     No

     No

     v1.0.0

     Baseline

     As at baseline


    Control case-sensitivity of the agent query (pre-v6+).

    Used for agents and (smart) adornments only. It can only modify the String.contains() operator (and older deprecated precursors) and not list.contains().

    Though not itself formally deprecated, $AgentCaseSensitive is really only of use if using now-deprecated very old early action code syntax which some long-standing documents may contain.

    From v11.6.0 this attribute is deprecated as it only has meaningful use in the older version of the app, pre v6.

    AgentPriority

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     number   [other number-type attributes]

     1

     Agent   [other Agent Group attributes]

     Agent configuration

     No

     Yes

     No

     No

     v2.5.0

     Baseline

     As at baseline


    Allows agent to run less frequently than normal, or be turned off.

    A pop-up menu in the agent's Action Inspector ▸ Query sub-tab, or Get Info ▸ agent tab, allows manual change of agent priority. Regardless of the setting, every agent is updated before export and when updating manually, except for agents that have been turned off.

    Unless an agent is turned off before creating a query, an agent query will always run at least once as soon as the agent is first created.

    The mapping of number values to the text names used in the Priority pop-up menu on the Get Info agent tab and the Action Inspector Query sub-tab is as follows:

    • Highest = 0. Runs every few seconds.
    • Normal = 1 (default). Runs roughly every ten seconds.
    • Low = 4. Runs roughly every minute.
    • Lowest = 10. Runs roughly every five minutes'
    • Occasional = 20. Runs roughly every thirty minutes.
    • Off = -1. Does not run (retains any existing aliases)

    The $AgentPriority can only be set as a number. Do not use text values or you get an error. Any other number value than those listed above causes the dialog pop-up to show 'highest'. Whether this is the real result, i.e. that setting '9' results in the same as setting '0' is not clear.

    All agents that are not 'off' run once on document load or a force refresh of agents.

    The default value of $AgentPriority is 1, which will cause the agent to be checked at roughly ten second intervals. Higher values of $AgentPriority cause the agent to be checked less frequently.

    Setting $AgentPriority to 0 asks Tinderbox to check the agent as frequently as possible.

    Setting $AgentPriority to -1 asks Tinderbox to retain existing matches but never update, effectively turning the agent off whilst retaining the last set of data and is excluded from Export and 'manual' update agent updates. Thus the current results can be 'frozen' and persist between sessions. However, if an agent is being turned off just to drop it out of regular cycles it will need to manually be set to a value or zero or greater before it can be used/updated and manually reset to 'off' after use if it desired to 'freeze' it again. When an agent is off:

    • Query does not run
    • Agent actions ($AgentAction, $OnRemove) do not run.
    • Agent rules and edicts still run, i.e. in the agent itself
    • Child aliases' rules and edicts still run.
    AgentQuery

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     string   [other string-type attributes]

     (not set - empty string)

     Agent   [other Agent Group attributes]

     Action code

     No

     Yes

     No

     No

     v1.0.0

     Baseline

     As at baseline


    Query in action code used by agent to match and gather notes.

    Shown as an input box in the Action Inspector ▸ Query sub-tab of agents and smart adornments.

    Aliases

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     list   [other list-type attributes]

     (not set - empty string)

     General   [other General Group attributes]

     Calculated data

     No

     No

     Yes   [other read-only attributes]

     No

     v8.0.0

     Baseline

     As at baseline


    Returns a list of paths to each alias of the original of this note.

    This information is seldom necessary for normal use. If you need to rely on $Aliases, consider whether a different approach might be better. For where this approach is needed see more on finding/counting aliases (see the heading there 'Finding and counting aliases').

    ArticleTitle

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     string   [other string-type attributes]

     (not set - empty string)

     References   [other References Group attributes]

     Data synch

     No

     No

     No

     No

     v5.11.0

     Baseline

     As at baseline


    Used for Bookends reference import. Maps to RIS data tag 'T1', but only for reference type CHAP (Chapter).

    Associates

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     set   [other set-type attributes]

     (not set - empty string)

     Composites   [other Composites Group attributes]

     Composite configuration

     No

     No

     Yes   [other read-only attributes]

     Yes   [other intrinsic attributes]

     v7.0.0

     Baseline

     As at baseline


    A set holding the $Name strings of the (titled) items in the current composite.

    For new composites, or where some notes do not yet have titles set, those notes return their $Role value instead of $Name.

    Author2

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     string   [other string-type attributes]

     (not set - empty string)

     References   [other References Group attributes]

     Data synch

     No

     No

     No

     No

     v5.11.0

     Baseline

     As at baseline


    Used for Bookends reference import. Maps to RIS data tag 'A2'.

    Author3

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     string   [other string-type attributes]

     (not set - empty string)

     References   [other References Group attributes]

     Data synch

     No

     No

     No

     No

     v5.11.0

     Baseline

     As at baseline


    Used for Bookends reference import. Maps to RIS data tag 'A3'.

    Author4

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     string   [other string-type attributes]

     (not set - empty string)

     References   [other References Group attributes]

     Data synch

     No

     No

     No

     No

     v5.11.0

     Baseline

     As at baseline


    Used for Bookends reference import. Maps to RIS data tag 'A4'.

    Authors

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     list   [other list-type attributes]

     (not set - empty string)

     References   [other References Group attributes]

     Data synch

     No

     No

     No

     No

     v5.11.0

     Baseline

     As at baseline


    Used for Bookends reference import. Maps to RIS data tag 'AU'.

    $Authors is a List-type attribute (it was a Set in older releases). This is to avoid the listing being re-ordered alphabetically, now that the sorting of Set-type attributes is more aggressive in v9+. That is unhelpful if the authors of academic papers have been listed in order of appearance of the paper. If author names are entered in first name(s) then last name order, default (Set) alphabetical listing will use first name.

    To purge possible duplicates now $Authors is a List, consider a stamp using the list.unique operator:

    $Authors = $Authors.unique; 

    But, be aware this will impose an alphabetical sort.

    AutoFetch

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     boolean   [other boolean-type attributes]

     false

     Net   [other Net Group attributes]

     Import configuration

     No

     No

     No

     No

     v1.0.0

     Baseline

     As at baseline


    Set the note's $Text to data fetched automatically from the URL in $URL.

    If true the content is automatically fetched when the note is opened. See more.

    See also, $AutoFetchCommand.

    AutoFetchCommand

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     action   [other action-type attributes]

     (not set - empty string)

     Net   [other Net Group attributes]

     Import configuration

     No

     No

     No

     No

     v3.6.0

     Baseline

     As at baseline


    Action code used for post-import processing of $AutoFetch content.

    The purpose and functioning of $AutoFetchCommand is described in AutoFetch commands.

    AutomaticIndent

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     boolean   [other boolean-type attributes]

     true

     TextFormat   [other TextFormat Group attributes]

     Note text

     Yes

     No

     No

     No

     v5.0.0

     Baseline

     As at baseline


    Controls automatic indentation of lists in pre-v6 text windows.

    DEPRECATED: This feature is superseded by v6+'s standard list formatting and the attribute is not present in any TBX created using v6.0+. It is retained for v5 & older compatibility only. The information below applies only to pre-v6 versions.

    It defaults to true as inherited from the Text preference "Auto-indent lists".

    If a note's $AutomaticIndent is false Tinderbox will not automatically indent paragraphs starting with *, •, and #. This effectively disables quick lists without needing to turn off all export formatting to do so. This is useful, for example, in notes that contain CSS stylesheets that can have lines starting with a # for ID style declarations. However, it does not affect list creation during HTML export (see $HTMLMarkupText).

    NOTE: If $AutomaticIndent is turned off in an open note that contains lists in existing $Text, the lists will retain their former indentation. You can undo this by left-indent them with the Shift Left command in the Style menu (cmd-shift=[ ). This is because the attribute tries to respect the user's intent and so does not remove existing indents, it merely prevents (or not) new ones being created automatically. If altering this attribute for an existing note, you should close the note text window before altering the value.

    Badge

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     string   [other string-type attributes]

     (not set - empty string)

     Appearance   [other Appearance Group attributes]

     Map item badge configuration

     No

     Yes

     No

     No

     v4.0.0

     Baseline

     As at baseline


    Name of the badge icon set for the note.

    The names used in $Badge are case-sensitive. The stored value is the icon name minus the extension, e.g. "ok" instead of "ok.png". UI elements that list badges omit the icon file's extension in their roll-over tooltip.

    The badge's name is listed alongside the icon in the Badges pop-up menu. Badges are optionally displayed in Map and Outline Views.

    The list of default badge names is given on the Badges pop-up menu page and can also be set via the Appearance Inspector ▸ Interior tab, 'Badge' control.

    Emoji and other unicode characters may be used as badges. In place of the badge name, set $Badge to the unicode character to be displayed in the badge area. Best results will generally be obtained with $BadgeSize of 32 or greater.

    BadgeMonochrome

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     boolean   [other boolean-type attributes]

     false

     Appearance   [other Appearance Group attributes]

     Map item badge configuration

     No

     No

     No

     No

     v6.1.1

     Baseline

     As at baseline


    Causes monochrome badges to be rendered better against a dark background.

    When true and $Color is dark, the badge artwork will be drawn in sourceOut mode instead of sourceOver. This is useful when using black badges on a dark map background.

    BadgeSize

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     number   [other number-type attributes]

     (not set - 0)

     Appearance   [other Appearance Group attributes]

     Map item badge configuration

     No

     Yes

     No

     No

     v6.1.1

     Baseline

     As at baseline


    Sets the size of the badge in map view.

    If zero (default), the default badge size is used. When setting a value, the number used should be the pixel count aong the badge's edge. Badge icons are square and the default set are 32x32 pixels. Thus setting a value of 16 would show a 32x32 pixel badge at half normal size (16px).

    The Badge Picker pop-over automatically sets $BadgeSize to 32 when selecting badges from the Avatar family; an even-larger badge may sometimes be desirable.

    The 'Large' tick-box on the Appearance Inspector ▸ Interior tab, sets this attribute to a value of 64.

    Base

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     number   [other number-type attributes]

     0.5

     Map   [other Map Group attributes]

     Map item general configuration

     No

     Yes

     No

     No

     v6.0.0

     Baseline

     As at baseline


    This controls the shape of arrow and leaf shapes.

    It replaces the deprecated $LeafBase.

    The valid range is 0-1.

    For notes whose $Shape employs this setting, the $Base value for the selected note can be altered using the grey dot control to the bottom of the note, in a left-right direction.

    BeforeVisit

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     action   [other action-type attributes]

     (not set - empty string)

     Storyspace   [other Storyspace Group attributes]

     Storyspace compatibility

     No

     No

     No

     No

     v6.3.2

     Baseline

     As at baseline


    In Storyspace, an action performed before the reader visits the note.

    This allows Storyspace, in read mode, this action is evaluated, will be executed before the OnVisit action. If the note has any $Requirements, it will be executed before Requirements are checked. The BeforeVisit action can be convenient for actions required to prepare for Requirement checks.

    This logic is not tested in Tinderbox.

    Bend

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     number   [other number-type attributes]

     0

     Map   [other Map Group attributes]

     Map item general configuration

     No

     Yes

     No

     No

     v6.2.0

     Baseline

     As at baseline


    This control the degree of bend in the 'leaf' and 'banner' shapes.

    It replaces $LeafBend which is deprecated.

    The valid range is -1 to 1.

    For notes whose $Shape employs this setting, the $Bend value for the selected note can be altered using the black dot control to the right of the note.

    BookTitle

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     string   [other string-type attributes]

     (not set - empty string)

     References   [other References Group attributes]

     Data synch

     No

     No

     No

     No

     v5.11.0

     Baseline

     As at baseline


    Used for Bookends reference import. Maps to RIS data tag 'T2'.

    Border

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     number   [other number-type attributes]

     1

     Appearance   [other Appearance Group attributes]

     Map item border configuration

     No

     Yes

     No

     No

     v2.3.0

     Baseline

     As at baseline


    The size (width) of the border drawn around adornments, notes, agents and containers.

    If $Border is 0 (zero), no border is drawn, regardless of the $BorderBevel type.

    $Border can be set—to a limited number of preset values—via the Appearance Inspector ▸ Border tabs's 'Width' control.

    BorderBevel

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     string   [other string-type attributes]

     plain

     Appearance   [other Appearance Group attributes]

     Map item border configuration

     No

     Yes

     No

     No

     v2.3.0

     Baseline

     As at baseline


    Styles the corder around map icons.

    For adornments and items (notes, agents, containers), if $Border is greater than zero, a border is drawn around the object in a style depending on this attribute's value.

    In adornments, if $BorderBevel is raised, the border is bevelled. If automatic or plain the border is drawn as a simple outline. If $BorderBevel is none, the border is not drawn; note, though, that if $Border is greater than zero, space the width of $Border is left around the main part of the icon.

    In notes, if $BorderBevel is raised or automatic the border is bevelled. If plain, it is a simple outline. If $BorderBevel is none, the border is not drawn.

    $BorderBevel can be set via the Appearance Inspector ▸ Border tab's 'Style' control.

    BorderColor

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     color   [other color-type attributes]

     automatic

     Appearance   [other Appearance Group attributes]

     Map item border configuration

     No

     Yes

     No

     No

     v2.3.0

     Baseline

     As at baseline


    If $Border is greater than zero, a border is drawn around the adornment in this colour.

    The special value, "automatic", draws an opaque border in the adornment's natural colour; adornments are otherwise translucent.

    If $BorderColor is "automatic" and $BorderBevel is "plain", the colour is a mixture of the note's $Color and its $NameColor. In older versions, the border was drawn in the note's $Color, and so was invisible. $NameColor was chosen because it typically contrasts with $Color, where $AccentColor, the accent colour, might be very close in value to $Color.

    $BorderColor can be set via the Appearance Inspector ▸ Border tab's 'Color' control.

    BorderDash

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     number   [other number-type attributes]

     (not set - 0)

     Appearance   [other Appearance Group attributes]

     Map item border configuration

     No

     Yes

     No

     No

     v5.0.0

     Baseline

     As at baseline


    Display borders of map icons as a dashed line.

    Only dawn if the $BorderBevel type is 'plain'. This attribute holds the pixel length of the dash; the width of the dashed line is the $Border width.

    A $BorderDash value of 5 means a pattern of a 5-pixel long section of border then a 5-pixel section with no border, i.e. a 10-pixel repeating pattern.

    $BorderBevel can be set via the Appearance Inspector ▸ Border tab's 'Dash' control to a single preset value.

    CallNumber

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     string   [other string-type attributes]

     (not set - empty string)

     References   [other References Group attributes]

     Data synch

     No

     No

     No

     No

     v5.11.0

     Baseline

     As at baseline


    Used for Bookends reference import. Maps to RIS data tag 'CN'.

    Caption

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     string   [other string-type attributes]

     (not set - empty string)

     General   [other General Group attributes]

     Map item caption configuration

     No

     Yes

     No

     No

     v6.0.0

     Baseline

     As at baseline


    The optional caption text drawn beneath map note icons.

    $Caption can be set via the Text Inspector ▸ Caption tab, 'Caption' text box.

    CaptionAlignment

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     string   [other string-type attributes]

     left

     Appearance   [other Appearance Group attributes]

     Map item caption configuration

     No

     Yes

     No

     No

     v6.0.0

     Baseline

     As at baseline


    The alignment of $Caption text.

    $CaptionAlignment can be set via the Text Inspector ▸ Caption tab, 'Alignment' control.

    CaptionColor

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     color   [other color-type attributes]

     blue

     Appearance   [other Appearance Group attributes]

     Map item caption configuration

     No

     Yes

     No

     No

     v6.0.0

     Baseline

     As at baseline


    The colour used to drawn the $Caption.

    $CaptionAlignment can be set via the Text Inspector ▸ Caption tab, 'Color' controls.

    CaptionFont

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     font   [other font-type attributes]

     SketchnoteSquare

     Appearance   [other Appearance Group attributes]

     Map item caption configuration

     No

     Yes

     No

     No

     v6.0.0

     Baseline

     As at baseline


    Font used to draw $Caption text.

    $CaptionFont can be set via Get Info ▸ attributes tab, Appearance group. Click the 'A' symbol to open the OS Fonts palette and select the desired font.

    CaptionOpacity

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     number   [other number-type attributes]

     1

     Appearance   [other Appearance Group attributes]

     Map item caption configuration

     No

     Yes

     No

     No

     v6.0.0

     Baseline

     As at baseline


    The opacity used to draw the $Caption.

    $CaptionAlignment can be set via the Text Inspector ▸ Caption tab, 'Opacity' control.

    The allowed range of values is 0–1. Prior to v9.7.0, the range was 0–100 but this was changed—see more.

    CaptionSize

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     number   [other number-type attributes]

     100

     Appearance   [other Appearance Group attributes]

     Map item caption configuration

     No

     Yes

     No

     No

     v6.0.0

     Baseline

     As at baseline


    $Caption size is set as a relative percentage of $TextFontSize.

    Default is 100 (%).

    $CaptionSize can be set via the Text Inspector ▸ Caption tab, 'Size' slider control

    Checked

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     boolean   [other boolean-type attributes]

     false

     General   [other General Group attributes]

     General data

     No

     Yes

     No

     No

     v5.0.0

     Baseline

     As at baseline


    Tick state of the optional Outline view checkbox.

    Changing the attribute will add/remove a tick from the note's checkbox; a tick is shown when the value is true.

    If displayed in Outline view, via View menu ▸ 'Use Checkboxes'

    ChildCount

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     number   [other number-type attributes]

     (calculated)

     General   [other General Group attributes]

     Calculated data

     No

     No

     Yes   [other read-only attributes]

     No

     v1.0.0

     Baseline

     As at baseline


    Number of children belonging to the current note (read-only).

    This returns the count of direct children (i.e. one level down) and not all descendants. For a count (usually larger) of all notes below this see $DescendantCount.

    The count excludes adornments, which are counted in $AdornmentCount.

    Usually, rules and queries to test whether a note has children will test $ChildCount. But for export if you want the code to be false if the note has children but none of the children are exported, then using ^if(^childLinks^)^ …is better.

    ChosenWord

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     string   [other string-type attributes]

     (not set - empty string)

     Storyspace   [other Storyspace Group attributes]

     Storyspace compatibility

     No

     No

     No

     No

     v6.3.1

     Baseline

     As at baseline


    In Storyspace, stores the word the reader last clicked on when viewing this note.

    Note: this is not set/used by Tinderbox.

    The value stored is the link anchor text of the text link that was clicked to leave the note, when in read mode.

    Citations

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     dictionary   [other dictionary-type attributes]

     (not set - empty string)

     References   [other References Group attributes]

     Data synch

     No

     No

     No

     No

     v11.5.0

     11.5.0

     As at baseline


    A dictionary that matches Zotero mnemonic tags with citations generated in the current Zotero style.

    The default is an empty string, no value being set.

    More on use of Zotero.

    CiteKey

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     string   [other string-type attributes]

     (not set - empty string)

     References   [other References Group attributes]

     Data synch

     No

     No

     No

     No

     v11.0.0

     11.0.0

     As at baseline


    A unique citation key, used by BibTeX and some reference managers.

    Used with reference import from Reference Managers or textual formatted reference data.

    City

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     string   [other string-type attributes]

     (not set - empty string)

     Places   [other Places Group attributes]

     Locational data

     No

     No

     No

     No

     v6.0.0

     Baseline

     As at baseline


    The City field of an address.

    The automatic geocoding tries to supply these fields automatically when looking up the supplied $Address.

    CityData

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     dictionary   [other dictionary-type attributes]

     (not set - empty string)

     InformationCity   [other InformationCity Group attributes]

     InformationCity view configuration

     No

     No

     No

     No

     v11.0.0

     11.0.0

     As at baseline


    Holds per-building customisations in Information City view.

    A dictionary of building customisations.

    See Information City view.

    CityHidden

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     boolean   [other boolean-type attributes]

     false

     InformationCity   [other InformationCity Group attributes]

     InformationCity view configuration

     No

     No

     No

     Yes   [other intrinsic attributes]

     v11.0.0

     11.0.0

     As at baseline


    Toggles building visibility in Information City view.

    Default value: false.

    Toggling the boolean value shows/hides the note when the city view is used.

    See Information City view.

    CityKind

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     string   [other string-type attributes]

     (not set - empty string)

     InformationCity   [other InformationCity Group attributes]

     InformationCity view configuration

     No

     No

     No

     No

     v11.0.0

     11.0.0

     As at baseline


    A building's design type in Information City view.

    Allowed types: Beacon Hill, Dome, Pub, Rowhouse, Shophouse, Street, Vendor, Welsh.

    See Information City view.

    CityRotate

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     number   [other number-type attributes]

     (not set - 0)

     InformationCity   [other InformationCity Group attributes]

     InformationCity view configuration

     No

     No

     No

     No

     v11.0.0

     11.0.0

     As at baseline


    Building's orientation in Information City view.

    Allows number values between 0 and 359.

    Rotation via the view context menu cycles values: 0, 90, 180, and 270.

    See Information City view.

    CityX

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     number   [other number-type attributes]

     (not set - 0)

     InformationCity   [other InformationCity Group attributes]

     InformationCity view configuration

     No

     No

     No

     Yes   [other intrinsic attributes]

     v11.0.0

     11.0.0

     As at baseline


    Building's X-axis location in Information City view.

    This is the X-axis location based on the position of the rotational pivot, which is typically the centre of the city view.

    See Information City view.

    CityY

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     number   [other number-type attributes]

     (not set - 0)

     InformationCity   [other InformationCity Group attributes]

     InformationCity view configuration

     No

     No

     No

     Yes   [other intrinsic attributes]

     v11.0.0

     11.0.0

     As at baseline


    Building's Y-axis location in Information City view.

    This is the Y-axis location based on the position of the rotational pivot, which is typically the centre of the city view.

    See Information City view.

    CleanupAction

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     string   [other string-type attributes]

     grid

     Agent   [other Agent Group attributes]

     Agent configuration

     No

     No

     No

     Yes   [other intrinsic attributes]

     v5.5.0

     Baseline

     As at baseline


    Controls the way in which maps of agent containers are organised.

    See Re-arrangeable Agent Maps.

    ClusterTerms

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     set   [other set-type attributes]

     (not set - empty string)

     General   [other General Group attributes]

     Map configuration

     No

     No

     No

     No

     v7.5.0

     Baseline

     As at baseline


    A set of text terms to cluster onto an adornment during force-directed layout.

    CodeFont

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     font   [other font-type attributes]

     Courier New

     TextFormat   [other TextFormat Group attributes]

     Note text

     No

     No

     No

     No

     v8.7.1

     Baseline

     As at baseline


    The font type to be used for 'code' sections of $Text.

    Default: Courier New

    This setting is intended for sections of code where a monospace font aids clarity. This can be set via the Font sub-menu of the Format menu.

    Color

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     color   [other color-type attributes]

     7

     Appearance   [other Appearance Group attributes]

     Map item general configuration

     No

     Yes

     No

     No

     v1.0.0

     Baseline

     As at baseline


    Specifies the colour of a note in map view.

    The same colour is used in the outline of note icons in Outline/Explorer views and element outlines in TreeMap/Chart views.

    The default is '7'.

    Adornments have a different default: 'blue'. Adornments also have the extra option of setting 'transparent' such that neither body or border colour are drawn.

    There is no way to seed this value at app level, e.g. via user configuration files. Tinderbox saved colour schemes also do not save or set the $Color attribute.

    Accent colour is provided by $AccentColor.

    $Color can be set via the Appearance Inspector ▸ Interior tab, 'Color' controls.

    Color2

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     color   [other color-type attributes]

     dark warm gray dark

     Appearance   [other Appearance Group attributes]

     Map item general configuration

     No

     Yes

     No

     No

     v2.3.1

     Baseline

     As at baseline


    The note's accent colour (use $AccentColor instead).

    Retained for backwards compatibility, $Color2 is deprecated in favour of $AccentColor which fulfils the same role but with a more descriptive name. Both set the same colour.

    It is used for the alternate colour of the $Pattern drawn on the (background) $Color of a note in a map view.

    It is also used for the accent colour in bar() and vbar() map progress bar patterns, as well as container plots.

    The default is 'dark warm gray dark'.

    $Color2 can be set via the Appearance Inspector ▸ Interior tab, 'Color' controls.

    Container

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     string   [other string-type attributes]

     (preset to parent's path)

     General   [other General Group attributes]

     General data

     No

     No

     No

     Yes   [other intrinsic attributes]

     v4.1.0

     Baseline

     As at baseline


    Lets Tinderbox actions and rules change the parent of a note, moving it to a a new place within the document.

    It is the parent's $Path plus a '/'. For any item, $Path is the equivalent of $Container + $Name. More on moving notes.

    The underlying default value of $Container an empty string, but this is never seen as at note creation Tinderbox always inserts the path to the note's parent, with ancestor note names delimited with a '/' (forward slash) and the $Container of any root-level note is "/". If the user omits the terminal "/" when setting $Container, Tinderbox will auto-insert it to give the correct value.

    Originally, a key use is to enable automatic onward routing of notes created via emails sent to Tinderbox (a feature currently suspended).

    A more useful example would be for children of a document's 'Mail' note, used for collecting inbound email. Using monthly archives might result in a structure like '/Mail/Dec 07/', i.e. note 'Dec 07' found inside the note 'Mail'. An action in Mail might be to set the added note's container to 'Dec 07'. Thus:

    $Container="/Mail/Dec 07/"; 

    …will move the inbound email note from 'Mail' to 'Dec 07' inside 'Mail'.

    Note that the value passed in the action is a quoted string (now the recommended method for string literals).

    An alternative to a quoted string is an attribute value:

    $Container = $MyPathAttr; 

    A neat feature of this process is that any notes/containers in the path that do not currently exist will be created. Note: the latter is an exception to the general rule that Tinderbox will not automatically create or delete notes. Thus for more advanced users, the 'Dec 07' note name could be a value computed from the current date allowing the document to add a new folder each month without the user having to bother with this task.

    If the destination container has an $OnAdd action, that action is performed immediately on the newly added note(s). Note that if the action tries to move a note into the container in which it currently resides the $OnAdd action is not run; this makes sense as such an action will have already been run when the note was first added.

    If a note cannot be moved, either because it is being moved inside its own descendant or because the destination is not a (valid) container (e.g. an adornment or some other special note type), no action occurs.

    If using an agent to set a new container, it is important to consider whether the aim is to move the original of the note or merely the note's alias within the agent. Thus an $AgentAction like:

    $Container(original)="/Some Note/"; 

    …moves the original of the note matched by the agent to a new location. Conversely:

    $Container="/Some Note/"; 

    …moves the currently-processed agent alias.

    Important: moving the agent's alias will cause the agent's current cycle to cease, so ensure that the processed note no longer meets the agent query or only the first matched item will move its alias. Otherwise, the agent action will move one alias per cycle.

    Although Tinderbox does not allow code-deletion notes, you might consider setting a 'Trash' note and using a $Container="/Trash"; action. The Trash container could then be reviewed for manual deletions, or retrieval of erroneously trashed notes.

    One other important consideration when using $Container is inheritance and the effect of moving on existing inherited values. If using a lot of prototypes/inheritance it is certainly worth taking extra care with use of $Container.

    Email to Tinderbox allows the same $Container-setting action to be specified within an email.

    Country

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     string   [other string-type attributes]

     (not set - empty string)

     Places   [other Places Group attributes]

     Locational data

     No

     No

     No

     No

     v6.0.0

     Baseline

     As at baseline


    The Country field of an address.

    The automatic geocoding tries to supply these fields automatically when looking up the supplied $Address.

    Created

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     date   [other date-type attributes]

     (calculated)

     General   [other General Group attributes]

     Calculated data

     No

     No

     Yes   [other read-only attributes]

     Yes   [other intrinsic attributes]

     v1.0.0

     Baseline

     As at baseline


    The date a note was originally created (read-only).

    If edited subsequently, the note's $Modified attribute will changed; at outset both are the same.

    CreatedFrom

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     string   [other string-type attributes]

     (not set - empty string)

     General   [other General Group attributes]

     Action code

     No

     No

     No

     Yes   [other intrinsic attributes]

     v8.8.0

     Baseline

     As at baseline


    Used by the ziplinks text link method to store the full path of the note that created the new note.

    $CreatedFrom is not inherited from prototypes.

    Creator

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     string   [other string-type attributes]

     system

     General   [other General Group attributes]

     Calculated data

     Yes

     No

     Yes   [other read-only attributes]

     No

     v1.0.0

     Baseline

     As at baseline


    Creator of a note. The 'creator' name is taken from the User Name in Document Settings (read-only).

    If the latter preference is not personalised, the default value given to new notes is "system".

    Deck

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     set   [other set-type attributes]

     (not set - empty string)

     Storyspace   [other Storyspace Group attributes]

     Storyspace compatibility

     No

     No

     No

     No

     v6.3.2

     Baseline

     As at baseline


    In Storyspace, the card deck(s) to which this writing space optionally belongs.

    A Storyspace writing space (note) will belong to one or more decks if using the sculptural hypertext formalism. Otherwise the writing space does not need to have any $Deck value.

    Tinderbox can read/set this value but does not enact Storyspace's hypertext reading space.

    DescendantCount

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     number   [other number-type attributes]

     (calculated)

     General   [other General Group attributes]

     Calculated data

     No

     No

     Yes   [other read-only attributes]

     No

     v2.3.0

     Baseline

     As at baseline


    Number of descendants of a note (read-only).

    By comparison, $ChildCount will only show the number of direct child notes to the current notes (normally a smaller figure).

    Note that the count excludes adornments.

    DEVONthinkGroup

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     string   [other string-type attributes]

     (not set - empty string)

     Watch   [other Watch Group attributes]

     Data synch

     No

     No

     No

     No

     v7.3.0

     Baseline

     As at baseline


    The name of a DEVONthink group being fetched by this note as a watched group.

    This is the long alphanumeric ID string obtained from the "Copy Item Link"

    DEVONthinkLabel

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     string   [other string-type attributes]

     (not set - empty string)

     Watch   [other Watch Group attributes]

     Data synch

     No

     No

     No

     No

     v8.0.0

     Baseline

     As at baseline


    Stores the DEVONthink label for a DEVONthink-imported item

    Direction

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     boolean   [other boolean-type attributes]

     false

     Map   [other Map Group attributes]

     Map item general configuration

     No

     Yes

     No

     No

     v6.0.0

     Baseline

     As at baseline


    The direction in which a shape should point.

    This replaces the deprecated $LeafDirection.

    For notes whose $Shape employs this setting, the $Direction value for the selected note can be altered using the paired arrow control to the top left of the note.

    DisplayedAttributes

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     list   [other list-type attributes]

     (not set - empty string)

     TextFormat   [other TextFormat Group attributes]

     Note DA

     No

     No

     No

     No

     v8.8.0

     Baseline

     As at baseline


    A List holding the attribute names used in the note's Displayed Attributes table.

    Note that this is a list of attribute names and not references so do not use a $-prefix if editing the list by hand or via action code.

    The Displayed Attributes table is drawn in $DisplayedAttributeFont (by default the same as $NameFont).

    Displayed Attributes have no special status beyond the ability to display a user-selected table of 'key' attributes in a note's text pane.

    This replaces the deprecated KeyAttributes attribute.

    In pre-v.9, this attribute was a Set. However, new improvements to Set processing mean the listing order cannot be relied upon not to change, thus the move to List-type even though creates the potential for duplicated entries.

    DisplayedAttributesDateFormat

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     string   [other string-type attributes]

     (not set - empty string)

     TextFormat   [other TextFormat Group attributes]

     Note DA

     No

     No

     No

     No

     v8.8.0

     Baseline

     As at baseline


    Sets a custom date format string for the note's Displayed Attributes.

    By default, both the date and time are shown using the system's short formats for the current locale. Other formats may be chosen by changing the value of $DisplayedAttributesDateFormat. Suggested values include "L" and "l" to display only the date in long and short format respectively. This value will override the default set in the Text tab of Document Settings, though this attribute does not inherit directly from Document Settings.

    This format applies to all Date-type attributes. So, different Date attributes cannot have different attributes. As well as Displayed Attributes table it also controls the formatting of Date-type attributes in the Get Info/attributes dialog.

    This replaces the deprecated $KeyAttributeDateFormat attribute.

    DisplayedAttributesFont

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     font   [other font-type attributes]

     IdealSansSSm-Book

     TextFormat   [other TextFormat Group attributes]

     Note DA

     No

     No

     No

     No

     v8.8.0

     Baseline

     As at baseline


    Name of the font used for drawing Displayed Attributes.

    The font is used for both title and value columns of the Displayed Attributes table.

    By default, it is the same as $NameFont.

    This replaces the deprecated $KeyAttributeFont attribute.

    DisplayedAttributesFontSize

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     number   [other number-type attributes]

     11

     TextFormat   [other TextFormat Group attributes]

     Note DA

     No

     No

     No

     No

     v8.8.0

     Baseline

     As at baseline


    Sets the font size used to draw the Displayed Attributes table.

    The stored value is the numerical value in points. The default value is 11 (point).

    This replaces the deprecated $KeyAttributeFontSize attribute.

    DisplayExpression

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     action   [other action-type attributes]

     (not set - empty string)

     General   [other General Group attributes]

     Expression code

     No

     Yes

     No

     No

     v4.1.0

     Baseline

     As at baseline


    Action code expression to customise the way a note's name is displayed in Tinderbox views via $DisplayName.

    $DisplayName holds the evaluated result of $DisplayExpression' code. If $DisplayName has a value if is used instead of $Name in many views within Tinderbox; $Name is unaffected.

    Some users find it helpful to use actions and rules to append information to not names, e.g. word count, number of children or the value of some attribute. However, this does change the actual name of the note and can cause problems with other actions which do not expect note names to change.

    See a further description of display expressions.

    $DisplayExpression can be set via the Text Inspector ▸ Title tab, 'Display Expression' input box.

    DisplayExpressionDisabled

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     boolean   [other boolean-type attributes]

     false

     General   [other General Group attributes]

     Expression code

     No

     Yes

     No

     Yes   [other intrinsic attributes]

     v5.8.0

     Baseline

     As at baseline


    Allows the $DisplayExpression for a specific note to be disabled. It is intrinsic and thus not inherited.

    A primary use is suppressing code from be run in prototypes.

    $DisplayExpressionDisabled is convenient when a display expression is shared by all the children of a prototype, but it is not desirable that it be applied to the prototype itself. Thus it can be useful to suppress $DisplayExpression activation in prototypes. Previously, it was necessary include an 'if($Prototype)' test which was cumbersome and meant every inheriting note had to run the additional if test adding load to the action code cycle. That workaround can be discarded and the attribute set to false in the Prototype. Because, atypically, this attribute is not inherited from a prototype, the prototype's setting does not affect the Display Expression in notes using the prototype.

    For example, the intention may be for books to be displayed with their price:

    DisplayExpression: $Name+" $"+$Price 

    but the prototype for books, "Book Prototype" could inhibit this $DisplayExpression to display its name without a meaningless price tag.

    A similar control is supplied for rules: $RuleDisabled.

    $DisplayExpressionDisabled can be set via the Text Inspector ▸ Title tab, 'Display Expression Enabled' input box. Be aware the latter label describes the 'opposite' state compared to the underlying attribute.

    DisplayName

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     string   [other string-type attributes]

     (calculated)

     General   [other General Group attributes]

     Calculated data

     No

     No

     Yes   [other read-only attributes]

     No

     v4.1.0

     Baseline

     As at baseline


    Evaluated result of a Display Expression, used inside Tinderbox views instead of $Name.

    Being the result of $DisplayExpression, it is read-only.

    Because $DisplayExpression is evaluated contextually for the original and each alias, the resulting value can vary making $DisplayName essentially intrinsic.

    See Display Expressions for how to pass complex code evaluated results into $DisplayName.

    District

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     string   [other string-type attributes]

     (not set - empty string)

     Places   [other Places Group attributes]

     Locational data

     No

     No

     No

     No

     v6.0.0

     Baseline

     As at baseline


    The District field of an address.

    The automatic geocoding tries to supply these fields automatically when looking up the supplied $Address.

    'District' equates to the 'county' for US addresses.

    DOI

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     string   [other string-type attributes]

     (not set - empty string)

     References   [other References Group attributes]

     Data synch

     No

     No

     No

     No

     v5.11.0

     Baseline

     As at baseline


    Used for Bookends reference import. Maps to RIS data tag 'DO'.

    DominantLanguage

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     string   [other string-type attributes]

     (not set - empty string)

     AI   [other AI Group attributes]

     Natural Language Processing

     No

     No

     No

     No

     v8.0.4

     Baseline

     As at baseline


    Records Tinderbox's guess at the primary language used in the text of each note.

    Languages appear as two-letter ISO-639-1 codes such as “en” for English, “de” for German, and “zh” for Chinese.

    DoNotDelete

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     boolean   [other boolean-type attributes]

     false

     General   [other General Group attributes]

     General data

     No

     No

     No

     No

     v10.2.0

     Baseline

     As at baseline


    Protects this note against accidental deletion.

    Default is false.

    IMPORTANT: this setting does not protect notes from being deleted by actions.

    Here, the accidental deletion is being considered in terms of inattentive use of the Backspace key, etc.

    Behaviour of this, and the associated $Lock and $ReadOnly attributes are discussed under Non-editable notes.

    DueDate

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     date   [other date-type attributes]

     (not set - never)

     Events   [other Events Group attributes]

     Timeline event configuration

     No

     No

     No

     No

     v5.0.0

     Baseline

     As at baseline


    A date attribute provided to facilitate organisation of tasks.

    See also $StartDate and $EndDate.

    Edict

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     action   [other action-type attributes]

     (not set - empty string)

     General   [other General Group attributes]

     Action code

     No

     No

     No

     No

     v6.1.3

     Baseline

     As at baseline


    Sets an edict (action code) to be run on the note, but infrequently.

    In effect this is a low priority rule ($Rule) for tasks that do require to run more than once but not with great frequency. Execution of the edict can be suppressed via $EditDisabled. This allows the edict code to remain stored in the attribute but for it to have no effect.

    $Edict can be set via the Action Inspector ▸ Edict tab's input box.

    EdictDisabled

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     boolean   [other boolean-type attributes]

     false

     General   [other General Group attributes]

     Action code

     No

     Yes

     No

     Yes   [other intrinsic attributes]

     v6.1.3

     Baseline

     As at baseline


    This enables a note's $Edict to be disabled. It is intrinsic and thus not inherited via prototypes.

    A primary use is suppressing code from be run in prototypes.

    $EdictDisabled can be set via the Action Inspector ▸ Edict tab's 'Enabled' tick-box. Be aware the latter label describes the 'opposite' state compared to the underlying attribute.

    Edition

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     string   [other string-type attributes]

     (not set - empty string)

     References   [other References Group attributes]

     Data synch

     No

     No

     No

     No

     v5.11.0

     Baseline

     As at baseline


    Used for Bookends reference import. Maps to RIS data tag 'ET'.

    Email

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     email   [other email-type attributes]

     (not set - empty string)

     People   [other People Group attributes]

     Person detail

     No

     No

     No

     No

     v3.5.1

     Baseline

     9.6.0


    Intended for storing a person's email address.

    $Email is of data type Email (prior to v9.6.0 it had been of data type String).

    EmailSubject

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     string   [other string-type attributes]

     (not set - empty string)

     People   [other People Group attributes]

     HTML export file configuration

     No

     No

     No

     No

     v9.6.0

     Baseline

     As at baseline


    Sets the subject of a Tinderbox generated email

    New to v9.6.0, used with the create draft email feature.

    EmailTemplate

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     string   [other string-type attributes]

     (not set - empty string)

     People   [other People Group attributes]

     HTML export file configuration

     No

     No

     No

     No

     v9.6.0

     Baseline

     As at baseline


    A template for formatting draft emails

    This set the (export) template used for creating draft emails where more that the current notes styled $Text is needed as the message body text.

    EnabledWhen

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     action   [other action-type attributes]

     (not set - empty string)

     General   [other General Group attributes]

     Expression code

     No

     No

     No

     No

     v11.7.0

     11.7.0

     As at baseline


    Allows exclusion of items from Command Bar listings.

    Default: empty string.

    This is used for Command Bar searches.

    A query in $EnabledWhen, allows optional inclusion or exclusion of as a matched item. if $EnabledWhen is not empty, the item can be selected only if the query is satisfied. For example, this could offer an item to 'Install Dashboard' only if that dashboard was not already installed.

    EndDate

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     date   [other date-type attributes]

     (not set - never)

     Events   [other Events Group attributes]

     Timeline event configuration

     No

     No

     No

     No

     v5.0.0

     Baseline

     As at baseline


    A date attribute provided to facilitate organisation of tasks.

    See also $StartDate and $DueDate.

    For Timeline views, events with only $EndDate or an $EndDate before $StartDate will not plot correctly. Thus if $EndDate is used, a $StartDate should be supplied. An alternate Date-type attribute to use can be supplied via $TimelineEndAttribute.

    EstimatedNoteSize

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     number   [other number-type attributes]

     0

     Textual   [other Textual Group attributes]

     Calculated data

     No

     No

     Yes   [other read-only attributes]

     No

     v8.1.1

     Baseline

     As at baseline


    This provides a rough estimate of the space in bytes that the note will require on disk.

    This attribute provides a means to help with maintenance of large—in terms of file size—TBX documents as the user can track down the largest notes to review content. Although embedded images are a driver of file size, there are other factors such as: many attributes with local (i.e. note-level) values set, much text, or text with a lot of styling features.

    However, embedded images/documents are the likeliest cause of very large notes, and this is the primary purpose of this attribute.

    EvernoteNotebook

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     string   [other string-type attributes]

     (not set - empty string)

     Watch   [other Watch Group attributes]

     Data synch

     No

     No

     No

     No

     v7.3.0

     Baseline

     As at baseline


    The name of an Evernote notebook used by a watched folder.

    See more on Evernote use. Now unused/deprecated, as Evernote sync is not longer supported.

    File

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     file   [other file-type attributes]

     (not set - empty file string)

     General   [other General Group attributes]

     General data

     No

     No

     No

     No

     v1.0.0

     Baseline

     As at baseline


    Specifies the OS path to the object (in POSIX form).

    The object can be either a file or a folder. Only one file may be attached per note; to attach several files drop a folder containing the desired files. This linked asset may also be an OS alias to a file or folder.

    Adding a new note to $File replaces the existing reference. $File can also be set by dropping a file on the folder icon of $File when displayed in a note's displayed attribute's table.

    When opened via the Displayed Attributes table icon, $File's contents is passed to Finder which opens a finder window (for folders) or opens the file according to the files OS-associated application.

    Fill

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     file   [other file-type attributes]

     (not set - empty file string)

     Map   [other Map Group attributes]

     Map item general configuration

     No

     No

     No

     No

     v4.7.0

     Baseline

     As at baseline


    Designates a source image for background textures for map notes and adornments.

    The $Fill is normally set via the Appearance/Interior Inspector's Texture setting.

    The opacity of the fill texture can be controlled by the $FillOpacity attribute.

    Additional images may be placed in the custom fills folder of the Application Support folder.

    A file name may be used with or without an extension. If the user file folder contains the file "TestFill.png", then setting $Fill to "TestFill" or to "TestFill.png" is equivalent.

    Originally the attribute type was a string but this changed to file type. That made it easier to change fill to an arbitrary image file in the Displayed Attributes table. The value of $Fill is thus file path, e.g. ~/Pictures/Projects/logo.jpg.

    FillOffsetY

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     number   [other number-type attributes]

     (not set - 0)

     Map   [other Map Group attributes]

     Map item general configuration

     No

     No

     No

     No

     v9.1.0

     Baseline

     As at baseline


    This moves the centre of the fill image vertically.

    The value is set in map units (for Y, minus is up). See map note icon image fills.

    Note: there is not a 'FillOffsetX' attribute.

    FillOpacity

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     number   [other number-type attributes]

     0.75

     Map   [other Map Group attributes]

     Map item general configuration

     No

     No

     No

     No

     v4.7.0

     Baseline

     As at baseline


    Opacity of the map icon $Fill texture, or the icon's fill colours ($Color, $AccentColor) to be varied.

    A value of 1 makes the fill opaque, while 0 makes the fill invisible. The default value is 0.75.

    Flags

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     list   [other list-type attributes]

     (not set - empty string)

     Appearance   [other Appearance Group attributes]

     Map item general configuration

     No

     No

     No

     Yes   [other intrinsic attributes]

     v7.5.0

     Baseline

     As at baseline


    Holds a list of strings defining one or more flags.

    FormattedAddress

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     string   [other string-type attributes]

     (not set - empty string)

     Places   [other Places Group attributes]

     Locational data

     No

     No

     No

     No

     v6.0.0

     Baseline

     As at baseline


    Data from automatic geocoding of $Address.

    This attribute is retained for compatibility purposes but is deprecated: use $GeocodedAddress instead

    This address may include zip code and additional information absent from the supplied $Address.

    FullName

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     string   [other string-type attributes]

     (not set - empty string)

     People   [other People Group attributes]

     Person detail

     No

     No

     No

     No

     v3.5.1

     Baseline

     As at baseline


    Intended for storing the name of a person.

    GaudiHidden

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     boolean   [other boolean-type attributes]

     false

     Gaudi   [other Gaudi Group attributes]

     Gaudi view configuration

     No

     No

     No

     Yes   [other intrinsic attributes]

     v10.0.0

     Baseline

     As at baseline


    Indicates if a note is shown in Gaudi views.

    If set to true the note is not plotted in Gaudi views where it is otherwise in-scope of the view

    Default value is false (i.e. shown).

    GeocodedAddress

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     string   [other string-type attributes]

     (not set - empty string)

     Places   [other Places Group attributes]

     Locational data

     No

     No

     No

     No

     v6.0.0

     Baseline

     As at baseline


    Retrieved address look-up data as passed to automatic geocoding process.

    The stored address may include zip code and additional information absent from the supplied $Address.

    This attribute replaces $FormattedAddress.

    GridColor

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     color   [other color-type attributes]

     #ffffff

     Grid   [other Grid Group attributes]

     Map item grid configuration

     No

     Yes

     No

     No

     v6.0.0

     Baseline

     As at baseline


    The colour used to draw an adornment's grid.

    Set via the Grid Properties pop-over.

    GridColumns

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     number   [other number-type attributes]

     (not set - 0)

     Grid   [other Grid Group attributes]

     Map item grid configuration

     No

     Yes

     No

     No

     v6.0.0

     Baseline

     As at baseline


    The number of columns used to draw an adornment's grid.

    Set via the Grid Properties pop-over.

    GridLabelFont

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     font   [other font-type attributes]

     IdealSansSSm-Book

     Grid   [other Grid Group attributes]

     Map item grid configuration

     No

     Yes

     No

     No

     v6.0.0

     Baseline

     As at baseline


    Font used for adornment grid labels.

    Set via the Grid Properties pop-over.

    GridLabels

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     list   [other list-type attributes]

     (not set - empty string)

     Grid   [other Grid Group attributes]

     Map item grid configuration

     No

     Yes

     No

     No

     v6.0.0

     Baseline

     As at baseline


    The set of labels used for an adornment's grid.

    Set via the Grid Properties pop-over.

    GridLabelSize

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     number   [other number-type attributes]

     10

     Grid   [other Grid Group attributes]

     Map item grid configuration

     No

     Yes

     No

     No

     v6.0.0

     Baseline

     As at baseline


    The point size used for drawing labels on an adornment's grid.

    The default value is 10 (pt).

    Set via the Grid Properties pop-over.

    GridOpacity

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     number   [other number-type attributes]

     0.75

     Grid   [other Grid Group attributes]

     Map item grid configuration

     No

     Yes

     No

     No

     v6.0.0

     Baseline

     As at baseline


    The opacity applied to an adornment's grid.

    Set via the Grid Properties pop-over.

    The allowed range of values is 0–1. Prior to v9.7.0, the range was 0–100 but this was changed—see more.

    GridRows

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     number   [other number-type attributes]

     (not set - 0)

     Grid   [other Grid Group attributes]

     Map item grid configuration

     No

     Yes

     No

     No

     v6.0.0

     Baseline

     As at baseline


    The number of rows used to draw an adornment's grid.

    Set via the Grid Properties pop-over.

    Height

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     number   [other number-type attributes]

     2.48

     Map   [other Map Group attributes]

     Map item general configuration

     No

     No

     No

     Yes   [other intrinsic attributes]

     v1.0.0

     Baseline

     As at baseline


    The height of a note icon in the Map view, in map units.

    See also $Width.

    Aliases do not inherit this property from their original but have their own value (i.e. it is an intrinsic attribute).

    The default value is 2.48. Previously it was 1.86.

    HideDisplayedAttributes

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     boolean   [other boolean-type attributes]

     false

     TextFormat   [other TextFormat Group attributes]

     Note DA

     No

     No

     No

     No

     v8.8.0

     Baseline

     As at baseline


    Toggles visibility of the Displayed Attributes table (if any are set).

    This replaces the deprecated $HideKeyAttributes attribute.

    HideKeyAttributes

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     boolean   [other boolean-type attributes]

     false

     TextFormat   [other TextFormat Group attributes]

     Note KA

     No

     No

     No

     No

     v6.0.0

     Baseline

     As at baseline


    Deprecated: Hides key attributes table, even if defined for this note.

    Deprecated in favour of the $HideDisplayedAttributes attribute.

    In v6+, this replaces the $TextSidebar feature.

    HideTitle

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     boolean   [other boolean-type attributes]

     false

     TextFormat   [other TextFormat Group attributes]

     Note title

     No

     Yes

     No

     No

     v9.0.0

     Baseline

     As at baseline


    Toggles display of a note's title and subtitle in map view.

    Hiding the title allows more space for text display on the note's map icon.

    This attribute is not related to the older $ShowTitle that was used only for Tinderbox pre-v6 UI purposes.

    HoverBackgroundColor

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     color   [other color-type attributes]

     black

     General   [other General Group attributes]

     Map item general configuration

     No

     No

     No

     No

     v9.6.0

     Baseline

     As at baseline


    Controls the background colour of Hover Expressions.

    This controls the background of the pop-up used by Hover Expressions.

    HoverExpression

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     action   [other action-type attributes]

     (not set - empty string)

     General   [other General Group attributes]

     Expression code

     No

     Yes

     No

     No

     v5.9.0

     Baseline

     As at baseline


    Holds an expression forming the Hover Expression code for a note.

    This combines with Hover Image, if any. Text is rendered in $HoverFont.

    $HoverExpression can be set via the Text Inspector ▸ Hover tab, 'Hover Expression' text box.

    HoverFont

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     font   [other font-type attributes]

     RingsideCondensedSSm-Med

     Map   [other Map Group attributes]

     Map item general configuration

     No

     No

     No

     No

     v7.0.0

     Baseline

     As at baseline


    The font used to draw $HoverExpression.

    HoverImage

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     file   [other file-type attributes]

     (not set - empty file string)

     General   [other General Group attributes]

     Map item general configuration

     No

     Yes

     No

     No

     v7.0.0

     Baseline

     As at baseline


    Allows pop-up display of an image when hovering over a note.

    This combines with the Hover Expression, if any.

    $HoverImage can be set via the Text Inspector ▸ Hover tab, 'image file' drop-target box.

    HoverOpacity

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     number   [other number-type attributes]

     0.5

     General   [other General Group attributes]

     Map item general configuration

     No

     Yes

     No

     No

     v6.5.0

     Baseline

     As at baseline


    Specifies the opacity of the note's $HoverExpression panel when visible.

    Allows specification of the opacity of hover expressions on a scale of zero (invisible) to 1 (opaque). The Hover pane of the Text Inspector has a slider to control opacity.

    $HoverOpacity can be set via the Text Inspector ▸ Hover tab, 'Opacity' control.

    HTMLBoldEnd

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     string   [other string-type attributes]

     </b>

     HTML   [other HTML Group attributes]

     HTML export mark-up

     No

     Yes

     No

     No

     v2.0.0

     Baseline

     As at baseline


    Ending tag to use for closing bold passages of the current note's text being exported to HTML.

    The opening tag is set via $HTMLBoldStart.

    $HTMLBoldEnd can be set via the Export Inspector's ▸ Style tab, 'Bold' 'end' input box.

    HTMLBoldStart

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     string   [other string-type attributes]

     <b>

     HTML   [other HTML Group attributes]

     HTML export mark-up

     No

     Yes

     No

     No

     v2.0.0

     Baseline

     As at baseline


    Starting tag to use for opening bold passages of the current note's text being exported to HTML.

    The closing tag is set via $HTMLBoldEnd.

    $HTMLBoldStart can be set via the Export Inspector's ▸ Style tab, 'Bold' 'start' input box.

    HTMLCloud1End

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     string   [other string-type attributes]

     </span>

     HTML   [other HTML Group attributes]

     HTML export mark-up

     No

     No

     No

     No

     v3.5.0

     Baseline

     As at baseline


    Ending mark-up used to set the font size on words exported via the ^cloud, ^sectionCloud^ and ^documentCloud^ codes.

    There are five different ranges of words that can have sizes set; 1 = worst match and 5 = best match.

    HTMLCloud1Start

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     string   [other string-type attributes]

     <span style="font-size: 0.75em">

     HTML   [other HTML Group attributes]

     HTML export mark-up

     No

     No

     No

     No

     v3.5.0

     Baseline

     As at baseline


    Starting mark-up used to set the font size of words exported via the ^cloud^, ^sectionCloud^ and ^documentCloud^ codes.

    There are five different ranges of words that can have sizes set; 1 = worst match and 5 = best match.

    HTMLCloud2End

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     string   [other string-type attributes]

     </span>

     HTML   [other HTML Group attributes]

     HTML export mark-up

     No

     No

     No

     No

     v3.5.0

     Baseline

     As at baseline


    Ending mark-up used to set the font size on words exported via the ^cloud^, ^sectionCloud^ and ^documentCloud^ codes.

    There are five different ranges of words that can have sizes set; 1 = worst match and 5 = best match.

    HTMLCloud2Start

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     string   [other string-type attributes]

     <span style="font-size: 1em">

     HTML   [other HTML Group attributes]

     HTML export mark-up

     No

     No

     No

     No

     v3.5.0

     Baseline

     As at baseline


    Starting mark-up used to set the font size of words exported via the ^cloud^, ^sectionCloud^ and ^documentCloud^ codes.

    There are five different ranges of words that can have sizes set; 1 = worst match and 5 = best match.

    HTMLCloud3End

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     string   [other string-type attributes]

     </span>

     HTML   [other HTML Group attributes]

     HTML export mark-up

     No

     No

     No

     No

     v3.5.0

     Baseline

     As at baseline


    Ending mark-up used to set the font size on words exported via the ^cloud^, ^sectionCloud^ and ^documentCloud^ codes.

    There are five different ranges of words that can have sizes set; 1 = worst match and 5 = best match.

    HTMLCloud3Start

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     string   [other string-type attributes]

     <span style="font-size: 1.4em">

     HTML   [other HTML Group attributes]

     HTML export mark-up

     No

     No

     No

     No

     v3.5.0

     Baseline

     As at baseline


    Starting mark-up used to set the font size of words exported via the ^cloud^, ^sectionCloud^ and ^documentCloud^ codes.

    There are five different ranges of words that can have sizes set; 1 = worst match and 5 = best match.

    HTMLCloud4End

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     string   [other string-type attributes]

     </span>

     HTML   [other HTML Group attributes]

     HTML export mark-up

     No

     No

     No

     No

     v3.5.0

     Baseline

     As at baseline


    Ending mark-up used to set the font size on words exported via the ^cloud^, ^sectionCloud^ and ^documentCloud^ codes.

    There are five different ranges of words that can have sizes set; 1 = worst match and 5 = best match.

    HTMLCloud4Start

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     string   [other string-type attributes]

     <span style="font-size: 2em">

     HTML   [other HTML Group attributes]

     HTML export mark-up

     No

     No

     No

     No

     v3.5.0

     Baseline

     As at baseline


    Starting mark-up used to set the font size of words exported via the ^cloud^, ^sectionCloud^ and ^documentCloud^ codes.

    There are five different ranges of words that can have sizes set; 1 = worst match and 5 = best match.

    HTMLCloud5End

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     string   [other string-type attributes]

     </span>

     HTML   [other HTML Group attributes]

     HTML export mark-up

     No

     No

     No

     No

     v3.5.0

     Baseline

     As at baseline


    Ending mark-up used to set the font size on words exported via the ^cloud^, ^sectionCloud^ and ^documentCloud^ codes.

    There are five different ranges of words that can have sizes set; 1 = worst match and 5 = best match.

    HTMLCloud5Start

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     string   [other string-type attributes]

     <span style="font-size: 2.8em">

     HTML   [other HTML Group attributes]

     HTML export mark-up

     No

     No

     No

     No

     v3.5.0

     Baseline

     As at baseline


    Starting mark-up used to set the font size of words exported via the ^cloud^, ^sectionCloud^ and ^documentCloud^ codes.

    There are five different ranges of words that can have sizes set; 1 = worst match and 5 = best match.

    HTMLCodeEnd

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     string   [other string-type attributes]

     </code>

     HTML   [other HTML Group attributes]

     HTML export encoding

     No

     Yes

     No

     No

     v9.0.0

     Baseline

     As at baseline


    HTML code to insert at the end of code-format $Text.

    Can be edited via the Style pane of the Export Inspector.

    HTMLCodeStart

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     string   [other string-type attributes]

     <code>

     HTML   [other HTML Group attributes]

     HTML export encoding

     No

     Yes

     No

     No

     v9.0.0

     Baseline

     As at baseline


    HTML code to insert at the beginning of code-format $Text.

    Can be edited via the Style pane of the Export Inspector.

    HTMLDontExport

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     boolean   [other boolean-type attributes]

     false

     HTML   [other HTML Group attributes]

     HTML export scope

     No

     Yes

     No

     No

     v1.0.0

     Baseline

     As at baseline


    Specifies whether the content of the note will export or not during export to HTML, either as a page or as an inclusion in a page.

    This attribute is the setting for the 'Export' tick-box in the HTML page view. The default for pages is to Export (ticked) so this attribute's default, in keeping with its titling is false, i.e. avoiding a double negative "do not $HTMLDontExport".

    Tinderbox does not ignore paths that include containers that are not exported. For example

    ^include(/documentation/details/note)^ 

    …previously would have included nothing if documentation or details were had HTMLDontExport set to true, even if note had $HTMLDontExport set to false.

    Tinderbox does not create links to notes whose $HTMLDontExport value is true. The same holds for links where any ancestor has $HTMLExportChildren set to false.

    $HTMLDontExport can be set via the Export Inspector's ▸ Export tab, 'Export' tick box.

    HTMLEntities

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     boolean   [other boolean-type attributes]

     false

     HTML   [other HTML Group attributes]

     HTML export encoding

     No

     No

     No

     No

     v2.2.0

     Baseline

     As at baseline


    Indicates that non-basic characters like ampersands are converted into HTML entities

    The move to UTF-8 encoded export since version 5 has lessened the need to this setting. The default is false.

    Note: until v8 the default value of $HTMLEntities was true; the current should reduce confusion for those accustomed to using utf-8 in HTML.

    If true an ampersand '&' is exported as &amp;.

    Added the degree symbol to the characters turned into entities. Swiss, French and German quote styles are automatically detected and 'entified' without needing to resort to this setting.

    Export markup elements, e.g. ^value()^, check this attribute before encoding values.

    English typographic quotation marks “ ” and ‘ ’ are exported as HTML entities rather than straight quotes, e.g. &#147; for “ left curly double quotes.

    The symbol € is exported as &euro;.

    Δ is exported as &Delta;, δ as &delta;, μ as &mu; and ∑ as &sum;.

    HTMLExportAfter

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     string   [other string-type attributes]

     (not set - empty string)

     HTML   [other HTML Group attributes]

     HTML export mark-up

     No

     Yes

     No

     No

     v2.0.0

     Baseline

     As at baseline


    Ending tag immediately after the end of the current note's text and/or includes.

    Effectively, this is the 'footer' for each exported note's HTML page; q.v. $HTMLExportBefore.

    $HTMLExportAfter can be set via the Export Inspector's ▸ Markup tab, 'Before/After' 'end' box.

    HTMLExportBefore

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     string   [other string-type attributes]

     (not set - empty string)

     HTML   [other HTML Group attributes]

     HTML export mark-up

     No

     Yes

     No

     No

     v2.0.0

     Baseline

     As at baseline


    Starting tag immediately before the current note's text and/or includes.

    Effectively, this is the 'header' for each exported note's HTML page; q.v. $HTMLExportAfter.

    $HTMLExportBefore can be set via the Export Inspector's ▸ Markup tab, 'Before/After' 'start' box.

    HTMLExportChildren

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     boolean   [other boolean-type attributes]

     true

     HTML   [other HTML Group attributes]

     HTML export scope

     No

     Yes

     No

     No

     v1.0.0

     Baseline

     As at baseline


    An attribute controlling export of the current note's children.

    The interpretation of $HTMLDontExport and $HTMLExportChildren has been simplified.

    $HTMLExportChildren can be set via the Export Inspector's ▸ Export tab, 'Export Children' tick-box.

    If Export As Page is checked, Tinderbox will create an HTML file for the note. If it is not checked (true), no file will be created. The note's contents might appear on another HTML page, of course, by being ^include^-d by name or as one of another node's ^descendants^.

    If Export Children is checked, Tinderbox will attempt to export the node's children (if any). Each child, of course, may have an Export As Page attribute.

    Both Export Children and Export as Page are consulted when exporting, and the two settings are completely independent. We can export a page but not its children; we can export the children but not export any HTML for a note, or we can create both an HTML page and a directory of child pages.

    Remember that if this attribute is false, Tinderbox never even examines the child notes when exporting to HTML. So individual child notes may have $HTMLDontExport set either true or false, and will not be exported in either case.

    The easiest way to set this attribute is with the "Export children as pages" checkbox on the HTML view window for the note.

    Some existing Tinderbox documents might generate some extra files or directories, because these settings formerly interacted in a complex way. The new rules are much simpler to understand, and are much more consistent.

    Tinderbox does not create links to notes where any ancestor has $HTMLExportChildren set to false. The same holds for creating links to notes whose $HTMLDontExport value is false.

    HTMLExportCommand

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     string   [other string-type attributes]

     (not set - empty string)

     HTML   [other HTML Group attributes]

     HTML export post-processing

     No

     No

     No

     No

     v2.5.0

     Baseline

     As at baseline


    Run a program or script on the contents of the exported HTML file. Where is the working directory location assumed for executing scripts?

    If $HTMLExportCommand is empty, no special action is performed.

    Otherwise, the exported file is piped to the standard input of the command line in $HTMLExportCommand, and the file is replaced by command line's standard output. In other words, any action carried out by the linked command is carried out on the exported page after the normal page export.

    This attribute needs to be actual command line code: it cannot use code stored in another note as runCommand() can.

    HTMLExportExtension

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     string   [other string-type attributes]

     .html

     HTML   [other HTML Group attributes]

     HTML export file configuration

     Yes

     Yes

     No

     No

     v1.0.0

     Baseline

     As at baseline


    File extension to use for exported HTML pages (includes preceding full stop).

    The default value is '.html'. A new note inherits the default but the value can be altered at note level by editing the note's Get Info or via a stamp. Editing allows for other extensions, such as ASP/PHP/etc., to be specified as well as other forms like '.txt', '.js' or '.md'.

    $HTMLExportExtension can be set via the Export Inspector's ▸ Export tab, 'Extension' box.

    If the note's default is altered it is saved as the note's $HTMLExportExtension value.

    HTMLExportFileName

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     string   [other string-type attributes]

     (not set - empty string)

     HTML   [other HTML Group attributes]

     HTML export file configuration

     No

     Yes

     No

     No

     v1.0.0

     Baseline

     As at baseline


    Specific filename to be used for the note's exported HTML page instead of default calculated name.

    If left empty, Tinderbox automatically generates a filename based on the note's title.

    Note that a string set for this attribute should be the desired filename without its extension, i.e. 'index' not index.html'.

    Automatic filenames strip unsafe (see below) characters from the note title and truncate the resulting string to the number of characters set in $HTMLFileNameMaxLength (where, the default is 100). The case of characters in the exported name will be as per the note title except if $HTMLFileNameLowerCase is true.

    Default: (not set: empty string)

    $HTMLExportFileName can be set via the Export Inspector's ▸ Export tab, 'File Name' box.

    To avoid filename naming collisions, Tinderbox has to check if the intended export name already exists in the currently exported-to folder. If a duplicate name might arise, a suffix will be added. Simplistically, if file "abc.html" is already being exported to the current folder, another note that would export with that name will be exported as "abc_1.html" (and -@, _3, etc.).

    Punctuation characters in $Name other than a forward slash, period, and tilde (/.~) are also allowed in export filenames.

    Any caret (^) characters in $Name are omitted from the exported filename as this caused issues re export code parsing (carets themselves are not illegal in a URL, but not generally meaningful).

    Because the filename might change on export, Tinderbox does not return a value for eval($HTMLExportFileName); an exception is if this attribute already has an explicitly set value. The workaround is to use ^file()^, noting that the latter returns both file name and extension rather than just the name portion.

    As Windows-OS web servers support fewer characters in file paths/names that other OSs, the following characters are suppressed when generating filenames from $Name:

    [space] / \ ? % * : | ' " < > . & + ( ) ! # 

    Further manipulation is available via $HTMLExportFileNameSpacer.

    $HTMLExportPath evaluates the likely exported filename and path.

    HTMLExportFileNameSpacer

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     string   [other string-type attributes]

     space

     HTML   [other HTML Group attributes]

     HTML export file configuration

     No

     No

     No

     No

     v5.9.0

     Baseline

     As at baseline


    Character used to replace any character normally suppressed on export.

    Default value: a space (i.e. " ").

    It allows more flexibility with the construction of filenames created via HTML Export.

    Reflecting the fact that long-term Tinderbox-created websites might be affected, the default value is an empty string, thus maintaining the status quo.

    If used, it is most likely needed for all exported pages and thus should be set by changing the attribute default (i.e. at document level) rather than by setting the attribute at note level.

    The default is now a space " " character rather than previous default of an underscore ( _ ) character or not character at all.

    Punctuation characters other than a forward slash, period, and tilde ( /.~ ) are also allowed in export filenames.

    HTMLExportPath

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     string   [other string-type attributes]

     (calculated)

     HTML   [other HTML Group attributes]

     HTML export file configuration

     No

     No

     Yes   [other read-only attributes]

     No

     v5.10.2

     Baseline

     As at baseline


    The calculated export folder/filename path for the note (read-only)

    The folders and file from export root that would be created if the file were exported at that time. It thus show the names of the folders & file with any characters omitted or substituted as part of the export process.

    This can be extremely useful in more complex export scenarios where there is a need to reference in code an exported note's OS filename or path without being forced to hard-set $HTMLExportFileName. If not set, the latter cannot be queried within Tinderbox.

    To get just the exported filename from the path:

    $MyString = $HTMLExportPath.split("/").at(-1) 

    So: HTMLExportPath.html

    For this note:

    $Path: "/A Tinderbox Reference File/Automating Tinderbox/Coding/Use of Attributes/Attribute Listings/System Attribute List/HTMLExportPath"
    $HTMLExportPath: "/index/Automating_Tinderbox/Coding/Use_of_Attributes/Attribute_Listings/System_Attribute_List/HTMLExportPath.html"

    Note the spaces being lost or altered in the latter. The export version will also show $HTMLExportFileNameSpacer changes, if the latter is set. Here, spaces are replaced with underscores.

    HTMLExportTemplate

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     string   [other string-type attributes]

     (not set - empty string)

     HTML   [other HTML Group attributes]

     HTML export encoding

     Yes

     Yes

     No

     No

     v1.0.0

     Baseline

     As at baseline


    Name of the external template file or internal template to be used in exporting this note to HTML.

    $HTMLExportTemplate can be set via the Export Inspector's ▸ Export tab, 'Template' control or by using the Template pop-up menu on the note's text pane's HTML tab will also set this attribute for the note. The attribute value is the template note's $Path.

    To set a value via the UI, at least one valid export template must be defined in the current document. If at least one valid template is defined, the first (by date of addition) is taken as the default and shown in the Export tab of the HTML Inspector.

    HTMLFileNameLowerCase

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     boolean   [other boolean-type attributes]

     false

     HTML   [other HTML Group attributes]

     HTML export file configuration

     No

     No

     No

     No

     v1.1.4

     Baseline

     As at baseline


    Letter case used for the HTML export filename for the note.

    If set to 'true', this forces the exported HTML filenames to be all lowercase. This is useful if exporting to a server whose OS is case sensitive.

    The default is false.

    HTMLFileNameMaxLength

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     number   [other number-type attributes]

     100

     HTML   [other HTML Group attributes]

     HTML export file configuration

     No

     No

     No

     No

     v1.1.4

     Baseline

     As at baseline


    Specifies the maximum number of characters allowed in exported filenames.

    The default value is 100.

    This change is an increase up from 8 characters in Tinderbox v1, raised to 24 characters in v3.0.5. Previous values reflected erstwhile OS filename and Web URL constraints.

    HTMLFirstParagraphEnd

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     string   [other string-type attributes]

     </p>

     HTML   [other HTML Group attributes]

     HTML export mark-up

     No

     Yes

     No

     No

     v1.0.0

     Baseline

     As at baseline


    Ending tag for the current note's first paragraph (and only the first paragraph).

    The opening value is set via $HTMLFirstParagraphStart.

    Export mark-up for all paragraphs succeeding the first are controlled by $HTMLParagraphStart and $HTMLParagraphEnd. Export mark-up for all paragraphs starting with a tab are controlled by $HTMLIndentedParagraphStart and $HTMLIndentedParagraphEnd.

    $HTMLFirstParagraphEnd can be set via the Export Inspector's ▸ Markup tab, 'First paragraph' 'end' box.

    HTMLFirstParagraphStart

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     string   [other string-type attributes]

     <p>

     HTML   [other HTML Group attributes]

     HTML export mark-up

     No

     Yes

     No

     No

     v1.0.0

     Baseline

     As at baseline


    Starting tag for the note's first paragraph (and only the first paragraph).

    The closing value is set via $HTMLFirstParagraphEnd.

    Values for all paragraphs succeeding the first are controlled by $HTMLParagraphStart and $HTMLParagraphEnd. Export mark-up for all paragraphs starting with a tab are controlled by $HTMLIndentedParagraphStart and $HTMLIndentedParagraphEnd.

    $HTMLFirstParagraphStart can be set via the Export Inspector's ▸ Markup tab, 'First paragraph' 'start' box.

    HTMLFont

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     font   [other font-type attributes]

     Andale Mono

     HTML   [other HTML Group attributes]

     General data

     No

     No

     No

     No

     v7.0.0

     Baseline

     As at baseline


    Sets the font used in the HTML (view) sub-tab of the Text pane.

    Defaults to Andale Mono.

    HTMLFontSize

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     number   [other number-type attributes]

     13

     HTML   [other HTML Group attributes]

     General data

     No

     No

     No

     No

     v7.0.0

     Baseline

     As at baseline


    Sets the size of font used in the HTML (view) sub-tab of the Text pane.

    Defaults to 13 point.

    HTMLImageEnd

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     string   [other string-type attributes]

     >

     HTML   [other HTML Group attributes]

     HTML export mark-up

     No

     No

     No

     No

     v2.5.0

     Baseline

     As at baseline


    Ending tag for images embedded in notes.

    The default value is > but for XHTML use alter the value to />. The paired attribute is $HTMLImageStart.

    This, and its pair attribute $HTMLIMageStart, allow for insertion of extra HTML tag attributes, e.g. CSS information.

    HTMLImageStart

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     string   [other string-type attributes]

     <img

     HTML   [other HTML Group attributes]

     HTML export mark-up

     No

     No

     No

     No

     v2.5.0

     Baseline

     As at baseline


    Start tag for images embedded in notes.

    The paired attribute is $HTMLImageEnd.

    This, and its pair attribute $HTMLIMageEnd, allow for insertion of extra HTML tag attributes, e.g. CSS information.

    HTMLIndentedParagraphEnd

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     string   [other string-type attributes]

     </blockquote>

     HTML   [other HTML Group attributes]

     HTML export mark-up

     No

     Yes

     No

     No

     v4.0.0

     Baseline

     As at baseline


    Ending tag for any paragraph that begins with a tab character, will use this attribute rather than $HTMLFirstParagraphEnd or $HTMLParagraphEnd.

    The opening export mark-up for such paragraphs is supplied by $HTMLIndentedParagraphStart.

    The default is </blockquote> though for files created pre-v5, the old default of </p> will be retained so as not to upset existing output.

    This default may be changed, or overridden, to generate a different indentation, to change the margins, etc.

    See also $HTMLParagraphEnd and $HTMLFirstParagraphEnd.

    $HTMLIndentedParagraphEnd can be set via the Export Inspector's ▸ Markup tab, 'Indented' 'end' box.

    HTMLIndentedParagraphStart

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     string   [other string-type attributes]

     <blockquote>

     HTML   [other HTML Group attributes]

     HTML export mark-up

     No

     Yes

     No

     No

     v4.0.0

     Baseline

     As at baseline


    Starting tag for any paragraph that begins with a tab character (used instead of $HTMLFirstParagraphStart or $HTMLParagraphStart).

    The closing mark-up for such paragraphs is supplied by $HTMLIndentedParagraphEnd.

    The default is <blockquote> though for files created pre-v5, the old default of <p style="text-indent: 3em;"> will be retained so as not to upset existing output.

    This default may be changed, or overridden, to generate a different indentation, to change the margins, etc.

    See also $HTMLParagraphStart and $HTMLFirstParagraphStart.

    $HTMLIndentedParagraphStart can be set via the Export Inspector's ▸ Markup tab, 'Indented' 'start' box.

    HTMLItalicEnd

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     string   [other string-type attributes]

     </i>

     HTML   [other HTML Group attributes]

     HTML export mark-up

     No

     Yes

     No

     No

     v2.0.0

     Baseline

     As at baseline


    Ending tag to use for closing italic passages of the current note's text being exported to HTML.

    The code can also be set via the HTML Inspector's Style sub-tab. The opening tag is set via $HTMLItalicStart.

    $HTMLItalicEnd can be set via the Export Inspector's ▸ Style tab, 'Italic' 'end' input box.

    HTMLItalicStart

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     string   [other string-type attributes]

     <i>

     HTML   [other HTML Group attributes]

     HTML export mark-up

     No

     Yes

     No

     No

     v2.0.0

     Baseline

     As at baseline


    Starting tag to use for opening italic passages of the current note's text being exported to HTML.

    The code can also be set via the HTML views Style pane. The closing tag is set via $HTMLItalicEnd.

    $HTMLItalicStart can be set via the Export Inspector's ▸ Style tab, 'Italic' 'start' input box.

    HTMLLinkExtension

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     string   [other string-type attributes]

     (not set - empty string)

     HTML   [other HTML Group attributes]

     HTML export post-processing

     No

     No

     No

     No

     v7.0.0

     Baseline

     As at baseline


    If post-processing used, this indicates the extension used when generating inter-file links.

    Necessary as the extension may differ from $HTMLExportExtension if the latter is set for post-processing needs, e.g. to '.md' as opposed to '.html'. In such a case $HTMLLinkExtension would be set to '.html' if that were the file extension used as the result of post processing.

    HTMLListEnd

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     string   [other string-type attributes]

     </ul>

     HTML   [other HTML Group attributes]

     HTML export mark-up

     No

     Yes

     No

     No

     v2.2.0

     Baseline

     As at baseline


    Ending tag to use for closing bulleted (unordered) lists in the current note's text being exported to HTML.

    The opening tag is set via $HTMLListStart.

    If the $HTMLListItemStart and $HTMLListItemEnd attributes are empty, all quick lists, as defined by lines starting with an * or a #, are disabled.

    $HTMLListEnd can be set via the Export Inspector's ▸ List tab, 'Unordered' 'end' box.

    HTMLListItemEnd

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     string   [other string-type attributes]

     </li>

     HTML   [other HTML Group attributes]

     HTML export mark-up

     No

     Yes

     No

     No

     v2.2.0

     Baseline

     As at baseline


    Ending tag to use for closing list items in the current note's text being exported to HTML.

    The opening tag is set via $HTMLListItemStart.

    If $HTMLListItemStart and $HTMLListItemEnd are empty, quick lists, as defined by lines starting with an * or a #, are disabled.

    $HTMLListItemEnd can be set via the Export Inspector's ▸ List tab, 'List item' 'end' box.

    HTMLListItemStart

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     string   [other string-type attributes]

     <li>

     HTML   [other HTML Group attributes]

     HTML export mark-up

     No

     Yes

     No

     No

     v2.2.0

     Baseline

     As at baseline


    Starting tag to use for opening list items in the current note's text being exported to HTML.

    The closing tag is set via $HTMLListItemEnd.

    If $HTMLListItemStart and $HTMLListItemEnd are empty, quick lists, as defined by lines starting with an * or a #, are disabled.

    $HTMLListItemStart can be set via the Export Inspector's ▸ List tab, 'List item' 'start' box.

    HTMLListStart

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     string   [other string-type attributes]

     <ul>

     HTML   [other HTML Group attributes]

     HTML export mark-up

     No

     Yes

     No

     No

     v2.2.0

     Baseline

     As at baseline


    Starting tag to use for opening bulleted (unordered) lists in the current note's text being exported to HTML.

    The closing tag is set via $HTMLListEnd.

    Changing this attribute's tag to <ul type="circle"> with allowable type values of circle, square or disc lets you alter the bullet type.

    If the $HTMLListItemStart and $HTMLListItemEnd attributes are empty, all quick lists, as defined by lines starting with an * or a #, are disabled.

    $HTMLListStart can be set via the Export Inspector's ▸ List tab, 'Unordered' 'start' box.

    HTMLMarkdown

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     boolean   [other boolean-type attributes]

     false

     HTML   [other HTML Group attributes]

     HTML export post-processing

     No

     No

     No

     No

     v9.0.0

     Baseline

     As at baseline


    Allows note using Markdown to also process Export code.

    $HTMLMarkdown is only used if $HTMLPreviewCommand has a value, i.e. that note us using Markdown processing.

    The main use is processing ^value^ code inline in $Text for notes using Markdown. An important exception is that Markdown headings are not misinterpreted as quicklists.

    Replaces the older and now deprecated $HTMLMarkDown.

    HTMLMarkDown

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     boolean   [other boolean-type attributes]

     false

     HTML   [other HTML Group attributes]

     HTML export post-processing

     No

     No

     No

     No

     v8.0.0

     Baseline

     As at baseline


    OBSOLETE: do not use, see HTMLMarkdown.

    No longer processed and function taken over by $HTMLMarkdown.

    Old name variant only found in older TBXs.

    HTMLMarkupText

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     boolean   [other boolean-type attributes]

     true

     HTML   [other HTML Group attributes]

     HTML export encoding

     No

     Yes

     No

     No

     v1.0.0

     Baseline

     As at baseline


    Ensures any HTML code (e.g. code examples) within the note text export as HTML entities rather than literal HTML code.

    Thus a > character is exported as &gt; so as to show as > on screen and not be parsed as HTML code.

    You would use a non-default value of false for any note where you have included HTML mark-up that has already been HTML 'entified' in the note text (and so a &gt; character in text is exported unchanged as &gt; thus rendering as source code, etc.).

    $HTMLMarkupText can be set via the Export Inspector's ▸ Export tab, 'Markup text' box.

    Whereas HTMLQuoteHTML just looks at mark-up code such as HTML/XML/PHP/etc. in the note's source text, HTMLMarkupText considers other aspects of the note. For example, if you set HTMLMarkupText to false macros are not expanded, styles are ignored, quick links are not created and so forth. As the attribute title implies you have turned mark-up off and you're just passing out raw text into the HTML export template. Depending on the latter's mark-up you may or may not see un-marked-up text in your browser.

    Thus the default setting of true is almost invariably the correct setting for this attribute.

    The attribute also controls, or has a part in, several display-related export functions (quick lists, auto-headings, etc.).

    HTMLOrderedListEnd

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     string   [other string-type attributes]

     </ol>

     HTML   [other HTML Group attributes]

     HTML export mark-up

     No

     Yes

     No

     No

     v2.5.0

     Baseline

     As at baseline


    Ending tag markup for ordered list generated by quick lists.

    HTML ordered lists may be created by beginning new paragraphs with the '#' symbol. Ordered and regular (unordered) quick lists should not be mixed.

    The starting tag is set via $HTMLOrderedListStart.

    If the $HTMLListItemStart and $HTMLListItemEnd attributes are empty, all quick lists, as defined by lines starting with an * or a #, are disabled.

    $HTMLOrderedListEnd can be set via the Export Inspector's ▸ List tab, 'Ordered' 'end' box.

    HTMLOrderedListItemEnd

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     string   [other string-type attributes]

     </li>

     HTML   [other HTML Group attributes]

     HTML export mark-up

     No

     No

     No

     No

     v2.5.0

     Baseline

     As at baseline


    Ending tag to use for closing ordered list items in the current note's text being exported to HTML.

    The opeing tag is set via $HTMLOrderedListItemStart.

    If $HTMLOrderedListItemStart and $HTMLOrderedListItemEnd are empty, quick lists, as defined by lines starting with an * or a #, are disabled.

    HTMLOrderedListItemStart

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     string   [other string-type attributes]

     <li>

     HTML   [other HTML Group attributes]

     HTML export mark-up

     No

     No

     No

     No

     v2.5.0

     Baseline

     As at baseline


    Starting tag to use for opening ordered list items in the current note's text being exported to HTML.

    The closing tag is set via $HTMLOrderedListItemEnd.

    If $HTMLOrderedListItemStart and $HTMLOrderedListItemEnd are empty, quick lists, as defined by lines starting with an * or a #, are disabled.

    HTMLOrderedListStart

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     string   [other string-type attributes]

     <ol>

     HTML   [other HTML Group attributes]

     HTML export mark-up

     No

     Yes

     No

     No

     v2.5.0

     Baseline

     As at baseline


    Opening tag markup for ordered list generated by quick lists.

    HTML ordered lists may be created by beginning new paragraphs with the '#' symbol. Ordered and regular (unordered) quick lists should not be mixed.

    The closing tag is set via $HTMLOrderedListEnd. Changing this to the syntax <ol type="a"> lets you alter the list item's 'bullet' type. The allowed values of type are:

    • A capital letters: A, B, C, D, etc.
    • a lower case letters: a, b, c, d, etc.
    • I Capital Roman numerals: I, II, III, IV, etc.
    • i Lower case roman numerals: i, ii, iii, iv, etc.
    • 1 Arabic numerals: 1, 2, 3, 4, etc.

    If the $HTMLListItemStart and $HTMLListItemEnd attributes are empty, all quick lists, as defined by lines starting with an * or a #, are disabled.

    $HTMLOrderedListStart can be set via the Export Inspector's ▸ List tab, 'Ordered' 'start' box.

    HTMLOverwriteImages

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     boolean   [other boolean-type attributes]

     false

     HTML   [other HTML Group attributes]

     HTML export post-processing

     No

     No

     No

     No

     v2.5.0

     Baseline

     As at baseline


    Deprecated: Legacy support for per-v6 use.

    Instructs Tinderbox not to overwrite existing images when exporting.

    In some circumstances, exporting the compressed image from Tinderbox might be undesirable, e.g. when a more detailed, uncompressed image is wanted in the actual export. By setting $HTMLOverwriteImages and placing the uncompressed image file in the export folder, Tinderbox will avoid replacing the uncompressed file.

    HTMLParagraphEnd

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     string   [other string-type attributes]

     </p>

     HTML   [other HTML Group attributes]

     HTML export mark-up

     No

     Yes

     No

     No

     v1.0.0

     Baseline

     As at baseline


    Text and/or ending HTML mark-up to be included immediately after the end of all of the current note's paragraphs, except the first.

    The opening value is set via $HTMLParagraphStart.

    Export mark-up for all paragraphs succeeding the first are controlled by $HTMLFirstParagraphStart and $HTMLFirstParagraphEnd. Export mark-up for all paragraphs starting with a tab are controlled by $HTMLIndentedParagraphStart and $HTMLIndentedParagraphEnd.

    $HTMLParagraphEnd can be set via the Export Inspector's ▸ Markup tab, 'Paragraph' 'end' box.

    HTMLParagraphStart

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     string   [other string-type attributes]

     <p>

     HTML   [other HTML Group attributes]

     HTML export mark-up

     No

     Yes

     No

     No

     v1.0.0

     Baseline

     As at baseline


    Text and/or starting HTML mark-up to be included immediately before all of the current note's paragraphs, except the first.

    The closing value is set via $HTMLParagraphEnd.

    Export mark-up for all paragraphs succeeding the first are controlled by $HTMLFirstParagraphStart and $HTMLFirstParagraphEnd. Export mark-up for all paragraphs starting with a tab are controlled by $HTMLIndentedParagraphStart and $HTMLIndentedParagraphEnd.

    $HTMLParagraphStart can be set via the Export Inspector's ▸ Markup tab, 'Paragraph' 'start' box.

    HTMLPreviewCommand

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     string   [other string-type attributes]

     (not set - empty string)

     HTML   [other HTML Group attributes]

     HTML export post-processing

     No

     No

     No

     No

     v7.2.0

     Baseline

     As at baseline


    Stores path to an alternate export processor (e.g. Markdown)

    If a path is specified, the stated application is used instead of the usual HTML mark-up generation when processing the (preview) output of ^text^.

    See more on Markdown use in export and Markdown preview rendering (latter includes possible in-app values for this attribute).

    HTMLQuoteHTML

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     boolean   [other boolean-type attributes]

     false

     HTML   [other HTML Group attributes]

     HTML export encoding

     No

     Yes

     No

     No

     v2.0.0

     Baseline

     As at baseline


    Indicates that any valid HTML mark-up in the source text of the of the current note will be rendered as text (i.e. exported as HTML entities) instead of as HTML code.

    $HTML can be set via the Export Inspector's ▸ Export tab,

    For 'HTML mark-up' you can read any code using mark-up tag's written within in <> angle brackets, e.g. XML, PHP, etc. Thus, a true setting exports a '<br>' in the source text as '&lt;br&gt;' that shows as screen text whereas a false setting exports it as '<br>', i.e. HTML source code for a (visible) line break.

    Values exported via ^value()^ and such will be parsed for HTML entities in addition to note text.

    When set to true, where sections of mark-up include line breaks in the Tinderbox note, it does not output the line returns after each line of code, i.e. they form continuous text in the HTML output, unless the there is at least one character at the beginning or end of the line outside the code within the outermost < > characters.

    For formatting discrete paragraphs/blocks of code, see the note on Exporting code samples.

    HTMLStrikeEnd

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     string   [other string-type attributes]

     </strike>

     HTML   [other HTML Group attributes]

     HTML export mark-up

     No

     Yes

     No

     No

     v5.0.0

     Baseline

     As at baseline


    Ending tag to use for opening strikethrough passages of the current note's text being exported to HTML.

    The closing tag is set via $HTMLStrikeStart.

    $HTMLStrikeEnd can be set via the Export Inspector's ▸ Style tab, 'Strike through' 'end' input box.

    HTMLStrikeStart

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     string   [other string-type attributes]

     <strike>

     HTML   [other HTML Group attributes]

     HTML export mark-up

     No

     Yes

     No

     No

     v5.0.0

     Baseline

     As at baseline


    Starting tag to use for opening strikethrough passages of the current note's text being exported to HTML.

    The closing tag is set via $HTMLStrikeEnd.

    $HTMLStrikeStart can be set via the Export Inspector's ▸ Style tab, 'Strike through' 'start' input box.

    HTMLSubscriptEnd

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     string   [other string-type attributes]

     </sub>

     HTML   [other HTML Group attributes]

     HTML export mark-up

     No

     No

     No

     No

     v9.5.2

     Baseline

     As at baseline


    Ending tag for exported HTML markup for subscript text in notes.

    The paired attribute is $HTMLSubscriptStart.

    HTMLSubscriptStart

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     string   [other string-type attributes]

     <sub>

     HTML   [other HTML Group attributes]

     HTML export mark-up

     No

     No

     No

     No

     v9.5.2

     Baseline

     As at baseline


    Starting tag for exported HTML markup for subscript text in notes.

    The paired attribute is $HTMLSubscriptEnd.

    HTMLSuperscriptEnd

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     string   [other string-type attributes]

     </sup>

     HTML   [other HTML Group attributes]

     HTML export mark-up

     No

     No

     No

     No

     v9.5.2

     Baseline

     As at baseline


    Ending tag for exported HTML markup for superscript text in notes.

    The paired attribute is $HTMLSuperscriptStart.

    HTMLSuperscriptStart

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     string   [other string-type attributes]

     <sup>

     HTML   [other HTML Group attributes]

     HTML export mark-up

     No

     No

     No

     No

     v9.5.2

     Baseline

     As at baseline


    Starting tag for exported HTML markup for superscript text in notes.

    The paired attribute is $HTMLSuperscriptEnd.

    HTMLUnderlineEnd

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     string   [other string-type attributes]

     </u>

     HTML   [other HTML Group attributes]

     HTML export mark-up

     No

     Yes

     No

     No

     v2.5.0

     Baseline

     As at baseline


    Ending tag for exported HTML mark-up for underlined text in notes.

    The paired attribute is $HTMLUnderlineStart.

    $HTMLUnderlineEnd can be set via the Export Inspector's ▸ Style tab, 'Underline' 'end' input box.

    HTMLUnderlineStart

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     string   [other string-type attributes]

     <u>

     HTML   [other HTML Group attributes]

     HTML export mark-up

     No

     Yes

     No

     No

     v2.5.0

     Baseline

     As at baseline


    Starting tag for exported HTML markup for underlined text in notes.

    The paired attribute is $HTMLUnderlineEnd.

    $HTMLUnderlineStart can be set via the Export Inspector's ▸ Style tab, 'Underline' 'start' input box.

    ID

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     number   [other number-type attributes]

     (calculated)

     General   [other General Group attributes]

     Calculated data

     No

     No

     Yes   [other read-only attributes]

     Yes   [other intrinsic attributes]

     v5.6.0

     Baseline

     As at baseline


    The internal unique ID of the item and is a large arbitrary whole number (read-only, not sequential numbers).

    Although set to no value (0) by default it is immediately populated with the items UID. The $ID UID number is unique within a TBX.

    $ID opens a number of possibilities for export, including making HTML anchors for linking to includes in exported pages but note the newer $IDString offers a more robust alternative for new code.

    An object dragged or copy/pasted to a different TB acquires a new $ID, as this ensures the UID is unique in the new location (i.e. its existing source $ID might already be allocated in the receiving document).

    As the newer $IDString may be used interchangeably with $ID, $IDString is suggested as the more robust choice when referring to IDs. Few users, except those using much/complex action code need to work with IDs. It is suggested to use $IDString for new code, but do not rush to update all existing code from $ID to $IDString unless there is an indication it is needed.

    Alaises and IDs

    IDs of aliases do not persist between sessions. In other words, if a note X has an $ID of "3219936174" today, it will have the same ID next week, but aliases of X might have different IDs. Aliases created by agents may change IDs at any time. However, aliases inside inactive agents do retain their ID value, unless/until the agent is re-activated. As $IDString is calculated from $ID, the same limitations apply.

    IDString

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     string   [other string-type attributes]

     (calculated)

     General   [other General Group attributes]

     Calculated data

     No

     No

     Yes   [other read-only attributes]

     Yes   [other intrinsic attributes]

     v9.5.0

     Baseline

     As at baseline


    A more compact, string, alternative to $ID

    $IDString, provides a more compact alternative to $ID. It is auto-calculated from $ID and thus is not seen in the saved XML source code of TBX files As a String it is less liable to accidental mathematical transformation when used in action code expressions.

    For example, a typical value of $ID might be1666143079, and its corresponding $IDString is tbx:BjT1Nn.

    As $IDString may be used interchangeably with $ID, $IDString is suggested as the more robust choice when referring to IDs. Few users, except those using much/complex action code need to work with IDs. It is suggested to use $IDString for new code, but do not rush to update all existing code from $ID to $IDString unless there is an indication it is needed.

    ImageCount

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     number   [other number-type attributes]

     (calculated)

     Textual   [other Textual Group attributes]

     Calculated data

     No

     No

     Yes   [other read-only attributes]

     No

     v6.2.0

     Baseline

     As at baseline


    The number of images embedded in the note's text.

    This can be useful to know when exporting notes with embedded images.

    ImageSizeLimit

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     number   [other number-type attributes]

     1600

     TextFormat   [other TextFormat Group attributes]

     Note text

     No

     No

     No

     No

     v9.5.0

     Baseline

     As at baseline


    The maximum image width for images placed in $Text.

    Default value is 1600 (pixels).

    InboundLinkCount

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     number   [other number-type attributes]

     (calculated)

     General   [other General Group attributes]

     Calculated data

     No

     No

     Yes   [other read-only attributes]

     Yes   [other intrinsic attributes]

     v3.0.0

     Baseline

     As at baseline


    Number of inbound links terminating at the current note (read-only).

    See also $OutboundLinkCount.

    The link count excludes any links of type "Prototype".

    InteriorScale

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     number   [other number-type attributes]

     1.5

     Map   [other Map Group attributes]

     Map configuration

     Yes

     No

     No

     No

     v3.0.3

     Baseline

     As at baseline


    Factor by which notes inside a container's viewport are smaller than notes elsewhere in the current map.

    The default value is 1.5, so if $InteriorScale is set to 2, then interior (child) notes are half their normal map size. $InteriorScale is inherited via a Map Preference: Map interior scale.

    Larger magnifications (values) give somewhat more detail of interior notes, i.e. greater number of lower level notes visible within the 'viewport' area of container notes in Map View. Thus, to increase the number of lower level note icons seen, for a given container viewport size, increase the value of $InteriorScale.

    IrisAngle

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     number   [other number-type attributes]

     0

     Iris   [other Iris Group attributes]

     Experimental

     No

     No

     No

     No

     v5.0.0

     Baseline

     As at baseline


    Experimental attribute, not currently used.

    IrisRadius

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     number   [other number-type attributes]

     1

     Iris   [other Iris Group attributes]

     Experimental

     No

     No

     No

     No

     v5.0.0

     Baseline

     As at baseline


    Experimental attribute, not currently used.

    IsAction

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     boolean   [other boolean-type attributes]

     false

     General   [other General Group attributes]

     Action code

     No

     No

     No

     No

     v9.1.0

     Baseline

     As at baseline


    This identifies notes that contain action code.

    These notes receive auto-completion support and action code syntax colouring.

    This attribute is most likely to be set via the Action prototype, especially for internal stamp notes.

    IsAdornment

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     boolean   [other boolean-type attributes]

     false

     General   [other General Group attributes]

     Calculated data

     No

     No

     Yes   [other read-only attributes]

     No

     v5.8.0

     Baseline

     As at baseline


    Indicates that an object is an adornment.

    IsAgent

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     boolean   [other boolean-type attributes]

     false

     Textual   [other Textual Group attributes]

     Calculated data

     No

     No

     Yes   [other read-only attributes]

     No

     v9.3.0

     Baseline

     As at baseline


    Indicates if the object is an agent.

    $IsAgent is true for agents and false for all other notes.

    This attribute makes it easier to simply find—or exclude—agents when constructing an agent or conditional query.

    Note: $IsAgent is not true for smart adornments as queries can't match adornments.

    IsAlias

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     boolean   [other boolean-type attributes]

     false

     General   [other General Group attributes]

     Calculated data

     No

     No

     Yes   [other read-only attributes]

     No

     v5.0.2

     Baseline

     As at baseline


    Indicates that an item is an alias (read-only)

    The attribute can help when trying to find originals as distinct from their aliases. It also helps when querying for aliases.

    It is likely this reads the state of the internal Boolean attribute $Alias.

    ISBN

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     string   [other string-type attributes]

     (not set - empty string)

     References   [other References Group attributes]

     Data synch

     No

     No

     No

     No

     v5.11.0

     Baseline

     As at baseline


    Used for Bookends reference import. Maps to RIS data tag 'SN'.

    IsComposite

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     boolean   [other boolean-type attributes]

     false

     Composites   [other Composites Group attributes]

     Composite configuration

     No

     No

     Yes   [other read-only attributes]

     Yes   [other intrinsic attributes]

     v7.0.0

     Baseline

     As at baseline


    Defines if a note is part of a composite.

    If true the note is currently part of a composite.

    IsMultiple

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     boolean   [other boolean-type attributes]

     false

     Composites   [other Composites Group attributes]

     Composite configuration

     No

     No

     No

     No

     v7.0.0

     Baseline

     As at baseline


    Indicates if a composite item's role may have multiple notes.

    If true that role may occur more than once in the composite.

    If $IsMultiple is true, when a note is moved into the composite touching that note, the moved note inherits the note's role.

    IsPrototype

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     boolean   [other boolean-type attributes]

     false

     General   [other General Group attributes]

     Special note type designator

     No

     Yes

     No

     Yes   [other intrinsic attributes]

     v1.0.0

     Baseline

     As at baseline


    Indicates this note is a prototype and can be used as such for by other notes.

    A true value implies the note is available as a prototype.

    Prototype values are inherited when the prototype is applied, normally at note creation. Subsequent editing of a prototype is not reflected through to notes based on that prototype; other methods must be used to update existing notes based on older prototype values.

    $IsPrototype can be set via the Properties Inspector ▸ Prototype tab, 'Prototype' tick-box.

    IsSeparator

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     boolean   [other boolean-type attributes]

     false

     Outline   [other Outline Group attributes]

     Outline configuration

     No

     Yes

     No

     No

     v9.6.0

     Baseline

     As at baseline


    Controls whether a note or agent is rendered as a separator in Outline view.

    $IsSeparator replaces $Separator, which is now deprecated, but continues to work.

    If notes are given no name, i.e. shown just as a line, a duplicate name warning is not issued even if reporting of such is turned on as a Warning Preference. The text of the separator is centred if it is smaller than the width of the separator label box.

    $IsSeparator can be set via the Properties Inspector ▸ Prototype tab, 'Separator' tick-box.

    Issue

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     string   [other string-type attributes]

     (not set - empty string)

     References   [other References Group attributes]

     Data synch

     No

     No

     No

     No

     v5.11.0

     Baseline

     As at baseline


    Used for Bookends reference import. Maps to RIS data tag 'IS'.

    IsTemplate

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     boolean   [other boolean-type attributes]

     false

     HTML   [other HTML Group attributes]

     Special note type designator

     No

     Yes

     No

     No

     v1.0.0

     Baseline

     As at baseline


    Defines a note for use as an export template.

    The attribute may also be set via the tick-box on the Properties Inspector's Prototype sub-tab or via action/rule code.

    $IsTemplate can be set via the Properties Inspector ▸ Prototype tab, 'Template' tick-box.

    Journal

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     string   [other string-type attributes]

     (not set - empty string)

     References   [other References Group attributes]

     Data synch

     No

     No

     No

     No

     v5.11.0

     Baseline

     As at baseline


    Used for Bookends reference import. Maps to RIS data tag 'JA'.

    KeyAttributeDateFormat

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     string   [other string-type attributes]

     (not set - empty string)

     TextFormat   [other TextFormat Group attributes]

     Note KA

     No

     No

     No

     No

     v6.3.1

     Baseline

     As at baseline


    Deprecated: Sets a custom date format string for the note's Key Attributes.

    Deprecated in favour of the $DisplayedAttributesDateFormat attribute.

    By default, both the date and time are shown using the system's short formats for the current locale. Other formats may be chosen by changing the value of $KeyAttributeDateFormat. Suggested values include "L" and "l" to display only the date in long and short format respectively. This value will override the default set in the Text tab of Document Settings.

    KeyAttributeFont

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     font   [other font-type attributes]

     IdealSansSSm-Book

     TextFormat   [other TextFormat Group attributes]

     Note KA

     No

     No

     No

     No

     v5.9.1

     Baseline

     As at baseline


    Deprecated: Name of the font used for drawing Key Attributes.

    Deprecated in favour of the DisplayedAttributesFont attribute.

    The font is used for both title and value columns of the key attributes table.

    By default, it is the same as $NameFont.

    KeyAttributeFontSize

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     number   [other number-type attributes]

     11

     TextFormat   [other TextFormat Group attributes]

     Note KA

     No

     No

     No

     No

     v7.5.0

     Baseline

     As at baseline


    Deprecated: Sets the font size used to draw the Displayed Attributes table.

    Deprecated in favour of the $DisplayedAttributesFontSize attribute.

    The stored value is the numerical value in points. The default value is 11 (point).

    KeyAttributes

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     set   [other set-type attributes]

     (not set - empty string)

     TextFormat   [other TextFormat Group attributes]

     Note KA

     No

     No

     No

     No

     v1.0.0

     Baseline

     As at baseline


    Deprecated: A Set of attribute names of those attributes to be displayed at the top of the current note's text pane. Replaced by DisplayedAttributes.

    Note that this is a list of attribute names and not references so do not use a $-prefix if editing the list by hand or via action code.

    The key attributes table is drawn in $KeyAttributeFont (by default the same as $NameFont).

    Deprecated in favour of the $DisplayedAttributes attribute. Displayed Attributes have replaced Key Attributes.

    Key Attributes have no special status beyond the ability to display a user-selected table of 'key' attributes in a note's text pane.

    LastFetched

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     date   [other date-type attributes]

     (calculated)

     Net   [other Net Group attributes]

     Calculated data

     No

     No

     Yes   [other read-only attributes]

     Yes   [other intrinsic attributes]

     v1.0.0

     Baseline

     As at baseline


    Date when the current note was last updated via auto-fetch from the web (read-only).

    Latitude

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     number   [other number-type attributes]

     (not set - 0)

     Places   [other Places Group attributes]

     Locational data

     No

     No

     No

     No

     v6.0.0

     Baseline

     As at baseline


    This holds the latitude of the $Address sourced via Automatic Geocoding.

    Also see $Longitude.

    LeafBase

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     number   [other number-type attributes]

     0.5

     Map   [other Map Group attributes]

     Experimental

     No

     No

     No

     No

     v5.0.0

     Baseline

     As at baseline


    Deprecated: Use $Base instead.

    Sets visual style of the base 'leaf' and 'banner' shapes.

    The valid range is 0-1.

    Now deprecated in favour of $Base.

    LeafBend

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     number   [other number-type attributes]

     0

     Map   [other Map Group attributes]

     Experimental

     No

     No

     No

     No

     v5.0.0

     Baseline

     As at baseline


    Deprecated: Use $Bend instead.

    Sets visual style of the bend on 'leaf' and 'banner' shapes.

    The valid range is -1 to 1.

    Now deprecated in favour of $Bend.

    LeafDirection

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     boolean   [other boolean-type attributes]

     false

     Map   [other Map Group attributes]

     Experimental

     No

     No

     No

     No

     v5.0.0

     Baseline

     As at baseline


    Deprecated: Use $Direction instead.

    Sets the orientation of some shapes.

    Now deprecated in favour of $Direction.

    LeafTip

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     number   [other number-type attributes]

     0.5

     Map   [other Map Group attributes]

     Experimental

     No

     No

     No

     No

     v5.0.0

     Baseline

     As at baseline


    Deprecated: Use $Tip instead.

    Sets visual style of the tip 'leaf' and 'banner' shapes.

    The valid range is 0–1.

    Now deprecated in favour of $Tip.

    LeftMargin

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     number   [other number-type attributes]

     2

     TextFormat   [other TextFormat Group attributes]

     Note text

     No

     No

     No

     No

     v3.0.0

     Baseline

     As at baseline


    Legacy-only feature to set left margin.

    $LeftMargin and $RightMargin are legacy features for pre-v6 and allow the user to set margins for individual notes.

    Below is for legacy reference only…

    Margins are set in multiples of 9 pixels; a left margin of 4 is equivalent to 36 pixels (0.5" or about 12.5mm). The default may be set in the System Attribute Inspector.

    When copying and pasting note text between TBX files with different margin settings, the pasted text takes the receiving note's margin settings but the note window must be closed and re-opened for this fact to be correctly displayed on screen. See also Pasting and Text Margins.

    The left and right margins are always the same.

    LineSpacing

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     number   [other number-type attributes]

     100

     TextFormat   [other TextFormat Group attributes]

     Note text

     No

     Yes

     No

     No

     v3.0.3

     Baseline

     As at baseline


    Space between lines within a paragraph of a note.

    To adjust the space between paragraphs, see $ParagraphSpacing.

    $LineSpacing is expressed as a percentage of the line's nominal or recommended spacing. The default value of 100 gives "standard" line space, while a value of 200 results in "double spacing", i.e. "x2".

    Dense text blocks may prove more readable with a $LineSpacing of 125 or 150 than with the familiar setting of 100.

    $LineSpacing can be set via the Text Inspector ▸ Text tab, 'Line spacing' control.

    LocalAttributes

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     set   [other set-type attributes]

     (not set - empty string)

     General   [other General Group attributes]

     Calculated data

     No

     No

     Yes   [other read-only attributes]

     Yes   [other intrinsic attributes]

     v8.8.0

     Baseline

     As at baseline


    A set of the attributes for this note which have a local value—a value that is not inherited to taken from the default. Attributes that are computed (like $WordCount) or intrinsic (like $Xpos) are never local attributes.

    To find all notes using a local value of a given attribute, see hasLocalValue().

    Lock

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     boolean   [other boolean-type attributes]

     false

     Map   [other Map Group attributes]

     Map configuration

     No

     Yes

     No

     No

     v2.4.0

     Baseline

     As at baseline


    Locks a note or (more usually) an adornment to the Map to avoid being moved inadvertently.

    Behaviour of this, and the associated $ReadOnly and $DoNotDelete attributes are discussed under Non-editable notes.

    Longitude

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     number   [other number-type attributes]

     (not set - 0)

     Places   [other Places Group attributes]

     Locational data

     No

     No

     No

     No

     v6.0.0

     Baseline

     As at baseline


    This holds the longitude of $Address sourced via Automatic Geocoding.

    MapBackgroundAccentColor

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     color   [other color-type attributes]

     gray

     Map   [other Map Group attributes]

     Map configuration

     Yes

     Yes

     No

     No

     v7.1.1

     Baseline

     As at baseline


    Accent colour used for Map view background patterns.

    This replaces (and maps old values of) $MapBackgroundColor2; the latter is deprecated.

    The attribute's default is not set but it inherits the default of map background colour gray from the Preferences Maps pane; the default is he same as that for $MapBackgroundColor.

    $MapBackgroundAccentColor can be set via a map view tab's Map Settings pop-over, 'Accent' colour controls.

    MapBackgroundColor

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     color   [other color-type attributes]

     #f2f2ed

     Map   [other Map Group attributes]

     Map configuration

     Yes

     Yes

     No

     No

     v1.0.0

     Baseline

     As at baseline


    Colour of the background in Map views.

    This colour is in fact used for the background of a number of other view—see more.

    The attribute's default is not set but it inherits the default of map background colour gray from the Preferences Maps pane.

    A number of utility views also use $MapBackgroundColor (the document-level value, not the current note's) to draw the background of their list panes.

    In Map views it is also used as the primary colour for background patterns.

    $MapBackgroundColor can be set via a map view tab's Map Settings pop-over, 'Color' colour controls.

    MapBackgroundColor2

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     color   [other color-type attributes]

     #f2f2ed

     Map   [other Map Group attributes]

     Map configuration

     Yes

     Yes

     No

     No

     v5.9.2

     Baseline

     As at baseline


    Accent colour used for Map view background patterns (now called MapBackgroundAccentColor).

    This attribute maps to $MapBackgroundAccentColor, and is deprecated in favour of the latter.

    The attribute's default is not set but it inherits the default of map background colour gray from the Preferences Maps pane; the default is he same as that for $MapBackgroundColor.

    $MapBackgroundColor2 can be set via a map view tab's Map Settings pop-over, 'Accent' colour controls.

    MapBackgroundFill

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     string   [other string-type attributes]

     (not set - empty string)

     Map   [other Map Group attributes]

     Map configuration

     No

     Yes

     No

     No

     v6.0.0

     Baseline

     As at baseline


    The optional fill for the Map view's background.

    $MapBackgroundFill can be set via a map view tab's Map Settings pop-over, 'Fill' pop-up control.

    Default fill options are listed in the Fills pop-up menu, along with any custom fills.

    MapBackgroundFillOpacity

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     number   [other number-type attributes]

     0.1

     Map   [other Map Group attributes]

     Map configuration

     No

     Yes

     No

     No

     v6.0.0

     Baseline

     As at baseline


    Controls opacity used to draw the fill for the Map view's background.

    The fill is set via $MapBackgroundFill

    $MapBackgroundFillOpacity can be set via a map view tab's Map Settings pop-over, 'Opacity' slider control.

    MapBackgroundPattern

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     string   [other string-type attributes]

     plain

     Map   [other Map Group attributes]

     Map configuration

     Yes

     Yes

     No

     No

     v5.9.0

     Baseline

     As at baseline


    This holds the pattern type for Map view background patterns.

    The default "plain", is inherited from a Preference on the Maps pane.

    $MapBackgroundPattern can be set via a map view tab's Map Settings pop-over.

    MapBackgroundShadow

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     boolean   [other boolean-type attributes]

     true

     Map   [other Map Group attributes]

     Map configuration

     No

     No

     No

     No

     v6.1.1

     Baseline

     As at baseline


    Controls whether map and outline views have a slight left margin shadow.

    If true the shadow is drawn.

    MapBodyTextColor

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     color   [other color-type attributes]

     automatic

     Map   [other Map Group attributes]

     Map item text configuration

     No

     No

     No

     No

     v4.6.0

     Baseline

     As at baseline


    Colour of the note's body text when displayed in a map view's note icon.

    The colour can be specified as a named Tinderbox colour or as a hex colour, i.e. 'black' or '#000000'.

    Default: automatic. This results in either a black or white colour depending on the value of $Color.

    The note's map icon's title colour is set via $NameColor.

    MapBodyTextSize

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     number   [other number-type attributes]

     0

     Map   [other Map Group attributes]

     Map item text configuration

     No

     No

     No

     No

     v4.0.0

     Baseline

     As at baseline


    Specific font size for the body text displayed within map icons (rectangular icons only).

    From v8, the default is about 20% larger than in previous versions.

    Some values have specific meanings:

    • 0 (zero). The default value. The app chooses the text size automatically, based on scale vs. the size of the title.
    • 1. This value suppresses display of body text, even if present.

    For all other values, i.e. 2 or greater, use a point size value to choose an explicit font size, i.e. value of 12 will render the body text as 12 point.

    Body text is never displayed in:

    Any negative value also suppresses display of $Text in the map icon.

    MapNameSize

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     number   [other number-type attributes]

     100

     Map   [other Map Group attributes]

     Map item text configuration

     No

     Yes

     No

     No

     v8.2.2

     Baseline

     As at baseline


    Adjust the relative size of note title ($Name) text in the Map view.

    The default is 100 (%).

    The base font size of outline items (usually 14pt) is set in the Maps tab of Document Settings, or via the Text Inspector's Title tab (allowed values are described there)

    This is a rename/replacement of $MapTextSize, as map view icons feature several different text sources.

    Similarly, $OutlineTextSize has been renamed $OutlineNameSize.

    The old attribute names are deprecated but will continue to function.

    MapPrototypeColor

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     color   [other color-type attributes]

     #cceecc

     Outline   [other Outline Group attributes]

     Outline configuration

     Yes

     No

     No

     No

     v2.5.0

     Baseline

     As at baseline


    Deprecated: see $PrototypeHighlightColor

    Not used in v6, retained for legacy compatibility.

    Colour of the circle shown behind the Outline view note icons of prototype notes. Deprecated in favour of $PrototypeHighlightColor which is a clearer description of purpose.

    The default is very light: if prototypes do not show a mark behind them try a darker value for this attribute. To avoid the mark showing, set the attribute the same as $MapBackgroundColor.

    The default value of #cceecc is inherited from the Document Settings Outlines tab's Prototype highlight colour.

    MapScrollX

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     number   [other number-type attributes]

     0

     Map   [other Map Group attributes]

     Map configuration

     No

     No

     No

     Yes   [other intrinsic attributes]

     v4.5.0

     Baseline

     As at baseline


    The X-axis scroll position of child map in a container viewport.

    The value is in map units. These co-ordinates are floating-point numbers, and use the same relative co-ordinates as $Xpos and $Ypos.

    For $MapScrollX, position '0' is when the scroll bar is in the middle of the view's vertical window scroller.

    In the parent's viewport $MapScrollX is drawn halfway across the interior of the container's icon (i.e. $Width/2) though depending on $TitleHeight the position itself may be obscured.

    If $MapScrollX/Y are {0,0}, then a note where $Xpos=0;$Ypos=0 will be around the middle of the screen.

    This attribute works in conjunction with $MapScrollY.

    The attribute can be set via actions so it is possible to pre-set a particular area of the parent map to be set to be onscreen when opened.

    MapScrollY

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     number   [other number-type attributes]

     0

     Map   [other Map Group attributes]

     Map configuration

     No

     No

     No

     Yes   [other intrinsic attributes]

     v4.5.0

     Baseline

     As at baseline


    The Y-axis scroll position of the child map in a container viewport.

    The value is in map units. These co-ordinates are floating-point numbers, and use the same relative co-ordinates as $Xpos and $Ypos.

    For $MapScrollY, position '0' is when the scroll bar is in the middle of the view's horizontal window scroller.

    In the parent's viewport $MapScrollY is drawn halfway down the interior of the container's icon (i.e. $Height/2) though depending on $TitleHeight the position itself may be obscured.

    If $MapScrollX/Y are {0,0}, then a note where $Xpos=0;$Ypos=0 will be around the middle of the screen.

    This attribute works in conjunction with $MapScrollX.

    The attribute can be set via actions so it is possible to pre-set a particular area of the parent map to be set to be onscreen when opened.

    MapTextSize

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     number   [other number-type attributes]

     100

     Map   [other Map Group attributes]

     Map item text configuration

     No

     No

     No

     No

     v3.5.0

     Baseline

     As at baseline


    Deprecated: use $MapNameSize instead.

    The default is 100 (%).

    Adjust the relative size of note title ($Name) text in the Map view.

    The base font size of outline items (usually 14pt) is set in the Maps tab of Document Settings, or via the Text Inspector's Title tab (allowed values are described there)

    Markd2

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     boolean   [other boolean-type attributes]

     true

     HTML   [other HTML Group attributes]

     HTML export post-processing

     No

     No

     No

     No

     v10.1.1

     Baseline

     As at baseline


    Affects preview via the Marked2 app.

    If the Marked2 app is installed, setting the attribute to false disables the streaming of export preview data to Marked2.

    Modified

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     date   [other date-type attributes]

     (calculated)

     General   [other General Group attributes]

     Calculated data

     No

     No

     Yes   [other read-only attributes]

     Yes   [other intrinsic attributes]

     v1.0.0

     Baseline

     As at baseline


    Returns the time a note's text was last modified (read-only).

    See also the $Created attribute: at first creation of the note both are the same.

    This attribute tracks changes to:

    … with such changes updating $Modified.

    Be aware that changing $Text or an attribute value in a stamp (including Quickstamp) or other form of action does not update $Modified.

    mt_allow_comments

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     number   [other number-type attributes]

     1

     Weblog   [other Weblog Group attributes]

     Weblog configuration

     No

     No

     No

     No

     v1.0.0

     Baseline

     As at baseline


    Deprecated: retained for pre-v6 use only.

    Not used in v6+. Specifies, if1, that MovableType weblogs allow comments.

    Legacy

    Re-typed from the defunct binary type to number type c.v3.0.0

    mt_allow_pings

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     number   [other number-type attributes]

     1

     Weblog   [other Weblog Group attributes]

     Weblog configuration

     No

     No

     No

     No

     v1.0.0

     Baseline

     As at baseline


    Deprecated: retained for pre-v6 use only.

    Not used in v6+. Specifies, if1, that MovableType weblogs allow pings to weblogs.com.

    Legacy

    Re-typed from the defunct binary type to number type c.v3.0.0

    mt_convert_breaks

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     string   [other string-type attributes]

     (not set - empty string)

     Weblog   [other Weblog Group attributes]

     Weblog configuration

     No

     No

     No

     No

     v1.0.0

     Baseline

     As at baseline


    Deprecated: retained for pre-v6 use only.

    Not used in v6+. Specifies, if1, that MovableType adds its own markup to discover paragraph breaks.

    Legacy

    Re-typed from the defunct binary type to string type c.v3.0.0

    mt_keywords

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     string   [other string-type attributes]

     (not set - empty string)

     Weblog   [other Weblog Group attributes]

     Weblog configuration

     No

     No

     No

     No

     v1.0.0

     Baseline

     As at baseline


    Deprecated: retained for pre-v6 use only.

    Not used in v6+. Allows the user to specify one or more categories for the current note for use in MoveableType and related weblogs.

    MyBoolean

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     boolean   [other boolean-type attributes]

     false

     Sandbox   [other Sandbox Group attributes]

     Testing

     No

     No

     No

     No

     v6.0.0

     Baseline

     As at baseline


    Sample Boolean-type attribute for experimentation with Action code.

    More on Boolean-type attributes.

    MyColor

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     color   [other color-type attributes]

     (not set - coerced to #000000)

     Sandbox   [other Sandbox Group attributes]

     Testing

     No

     No

     No

     No

     v6.0.0

     Baseline

     As at baseline


    Sample Color-type attribute for experimentation with Action code.

    More on Color-type attributes.

    MyDate

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     date   [other date-type attributes]

     (not set - never)

     Sandbox   [other Sandbox Group attributes]

     Testing

     No

     No

     No

     No

     v6.0.0

     Baseline

     As at baseline


    Sample Date-type attribute for experimentation with Action code.

    More on Date-type attributes.

    MyDictionary

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     dictionary   [other dictionary-type attributes]

     (not set - empty string)

     Sandbox   [other Sandbox Group attributes]

     Testing

     No

     No

     No

     No

     v9.0.0

     Baseline

     As at baseline


    Sample Dictionary-type attribute for experimentation with Action code.

    More on Dictionary-type attributes.

    MyInterval

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     interval   [other interval-type attributes]

     00:00

     Sandbox   [other Sandbox Group attributes]

     Testing

     No

     No

     No

     No

     v6.0.0

     Baseline

     As at baseline


    Sample Interval-type attribute for experimentation with Action code.

    More on Interval-type attributes.

    MyList

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     list   [other list-type attributes]

     (not set - empty string)

     Sandbox   [other Sandbox Group attributes]

     Testing

     No

     No

     No

     No

     v6.0.0

     Baseline

     As at baseline


    Sample List-type attribute for experimentation with Action code.

    More on List-type attributes.

    MyNumber

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     number   [other number-type attributes]

     (not set - 0)

     Sandbox   [other Sandbox Group attributes]

     Testing

     No

     No

     No

     No

     v6.0.0

     Baseline

     As at baseline


    Sample Number-type attribute for experimentation with Action code.

    More on Number-type attributes.

    MySet

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     set   [other set-type attributes]

     (not set - empty string)

     Sandbox   [other Sandbox Group attributes]

     Testing

     No

     No

     No

     No

     v6.0.0

     Baseline

     As at baseline


    Sample Set-type attribute for experimentation with Action code.

    More on Set-type attributes.

    MyString

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     string   [other string-type attributes]

     (not set - empty string)

     Sandbox   [other Sandbox Group attributes]

     Testing

     No

     No

     No

     No

     v6.0.0

     Baseline

     As at baseline


    Sample String-type attribute for experimentation with Action code.

    More on String-type attributes.

    Name

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     string   [other string-type attributes]

     untitled

     General   [other General Group attributes]

     Note title

     No

     Yes

     No

     Yes   [other intrinsic attributes]

     v1.0.0

     Baseline

     As at baseline


    Specifies the title of the note.

    $Name is equivalent to the ^title^ export code in the context of exporting data. The $Name string can be one word or more and can include symbols etc., though the latter are not suggested for use if you're going to export to HTML as you may/will have issues to resolve with HTML entities in the output.

    $Name of a selected object can easily be set/edited via the title box at the top of the text pane, or in some views by left-click-hold on the title text of the icon in the view pane.

    Because Tinderbox recognises operators such as + and -, notes whose names begin with characters other than letters and numbers may sometimes be interpreted in unexpected ways.

    For example, if a note is named "6*7", rules like

    $Prototype=6*7 

    might be parsed as a multiplication with the result of 42.

    $Prototype="6*7" 

    should have the expected effect.

    The attributes $DisplayExpression and (read-only) $DisplayName allow the user the option of showing the original name or as a manipulated version, e.g. with some information such as a word count concatenated on the end. Use of the new features is non-intrusive to existing use such as in actions & rules as $Name is always retained discretely from $DisplayName.

    Does a note name need to be unique?

    No, and $Path or in the case of both same-titled notes being in the same container, $ID can be used to reference discretely each duplicate-named note.

    Is $Name really intrinsic?

    If the intrinsic setting of $Name seems egregious, recall that intrinsic status reflects the XML setting 'canInherit'. When a note acts as prototype, it is generally desirable that the inheriting note has a different title, thus $Name is intrinsic.

    However, $Name differs from general intrinsic behaviour in that it is always the same for the original note and all its aliases. In other words, it is not possible to set a different $Name for an alias, whereas it is possible to have a different $Height or $Width. As $DisplayExpression is evaluated in the current context which may differ for an original and alias (e.g. if in different containers) offering and opportunity for discrete $DisplayName labels using contextual inputs.

    NameAlignment

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     string   [other string-type attributes]

     left

     Map   [other Map Group attributes]

     Map item text configuration

     No

     Yes

     No

     No

     v1.0.0

     Baseline

     As at baseline


    Specifies the justification of the (title and subtitle) in notes and adornments.

    Allowed values are:

    • left
    • center
    • right

    The attribute default is 'left'.

    $NameAlignment can be set via the Text Inspector ▸ Title tab, 'Alignment' pop-up control.

    Subtitles have no separate alignment control but instead inherit this setting.

    NameBold

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     boolean   [other boolean-type attributes]

     false

     Map   [other Map Group attributes]

     Map item text configuration

     No

     Yes

     No

     No

     v3.0.3

     Baseline

     As at baseline


    Controls use of bold type for the note name in views.

    Changing the default value of $NameBold is convenient for bolding all note names.

    $NameBold can be set via the Text Inspector ▸ Title tab, 'Bold' tick-box control.

    NameColor

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     color   [other color-type attributes]

     automatic

     Map   [other Map Group attributes]

     Map item text configuration

     No

     Yes

     No

     No

     v1.0.0

     Baseline

     As at baseline


    Colour used for the title of the note in Map views.

    The colour can be specified as a named Tinderbox colour or as a hex colour, i.e. 'black' or '#000000'.

    Default: automatic. This results in either a black or white colour depending on the value of $Color.

    The colour of body text displayed in a map note icon is set via $MapBodyTextColor.

    This colour may also 'transparent'. This option is intended to help those wishing to use images to form a note icon's contents in Map view. If the note title is transparent, when the note is selected, the note title will still be visible in the text pane.

    $NameColor can be set via the Text Inspector ▸ Title tab, 'Color' colour controls.

    NameFont

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     font   [other font-type attributes]

     IdealSansSSm-Book

     Map   [other Map Group attributes]

     Map item text configuration

     Yes

     No

     No

     No

     v1.0.0

     Baseline

     As at baseline


    Font used for rendering the $Name of a note in the Map view.

    It is also used to render the note name in most views: e.g. Outline, Chart, Treemap, Roadmap, Find, Path, Common Words, etc. Here, 'note' implies a note, a container note or an agent. Be aware that adornments may optionally use $AdornmentFont for the same purpose, enabling all adornments to use a different font as opposed to notes/agents.

    The attribute's default is not set but is inherited as IdealSansSSM-Book (was Helvetica Neue pre-v7, Lucida Grande pre-v6, Geneva pre-v2.3.0) from the Preferences Maps pane's 'Note label font' option.

    NameLeading

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     number   [other number-type attributes]

     0

     Map   [other Map Group attributes]

     Map item text configuration

     No

     No

     No

     No

     v5.0.2

     Baseline

     As at baseline


    Controls leading between lines of a multi-line title display

    This is pertinent where the title is long and my wrap.

    Possible values:

    • -1. Specifies that the space between lines should be chosen by the font ($NameFont). Negative values also affect leading in titles of Map view icons.
    • 0. Specifies that the lines of the name should be set as tightly as possible.
    • Any other value (greater than zero) adds additional space between lines. Positive values of $NameLeading represent a multiple of the natural line height. For example, $NameLeading of 1.5 adds a half-line of extra space between lines of the title, and $NameLeading of 0.9 sets the title 10% tighter than normal.

    In outlines, the space between different titles is controlled by a Map Preference.

    NameOpacity

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     number   [other number-type attributes]

     1

     Map   [other Map Group attributes]

     Map item text configuration

     No

     No

     No

     No

     v9.7.0

     Baseline

     As at baseline


    Controls the opacity of the name in map view.

    This replaces $TitleOpacity with is retained but deprecated.

    The allowed range of values is 0–1. Prior to v9.7.0, the range was 0–100 but this was changed—see more.

    If $NameOpacity is zero, no space in map view is reserved for the title (which would then be invisible) and the text 'thumbnail' (i.e. rendered image of the note's $Text) is now drawn. This allows title and text to have discrete opacity (title) or visibility (text, via $MapBodyTextSize). Formerly text matched the title in opacity as well as colour.

    NameStrike

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     boolean   [other boolean-type attributes]

     false

     Map   [other Map Group attributes]

     Map item text configuration

     No

     Yes

     No

     No

     v5.5.0

     Baseline

     As at baseline


    Render note title in strike-through.

    If true the title is struck through.

    More detail.

    $NameStrike can be set via the Text Inspector ▸ Title tab, 'Strikethrough' tick-box control.

    NameVerticalAlignment

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     string   [other string-type attributes]

     (not set - empty string)

     Map   [other Map Group attributes]

     Map item text configuration

     No

     No

     No

     No

     v9.7.3

     Baseline

     As at baseline


    Controls vertical positioning of map icon's title.

    Possible values include:

    • "" (i.e. no value): Title ($Name) is centred if there is no subtitle, top-aligned if there is a subtitle
    • center: Title is centred, even if there is a subtitle
    • top: Title is top-aligned
    • bottom: Title is bottom-aligned, allowing space as needed by subtitle
    NeverComposite

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     boolean   [other boolean-type attributes]

     true

     Composites   [other Composites Group attributes]

     Composite configuration

     No

     No

     No

     Yes   [other intrinsic attributes]

     v7.0.0

     Baseline

     As at baseline


    Exclude a note from all composites.

    By setting the default value of $NeverComposite to true, composites can be turned off throughout a document.

    In new documents, the default value of $NeverComposite is initially true. Prior to v9 the default was false. Pre-existing documents will retain their current default.

    NLNames

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     set   [other set-type attributes]

     (not set - empty string)

     AI   [other AI Group attributes]

     Natural Language Processing

     No

     No

     No

     No

     v7.5.0

     Baseline

     As at baseline


    A set of personal names found in the text using Natural Language Processing.

    NLOrganizations

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     set   [other set-type attributes]

     (not set - empty string)

     AI   [other AI Group attributes]

     Natural Language Processing

     No

     No

     No

     No

     v7.5.0

     Baseline

     As at baseline


    A set of the names of organisations found in the text using Natural Language Processing.

    NLPlaces

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     set   [other set-type attributes]

     (not set - empty string)

     AI   [other AI Group attributes]

     Natural Language Processing

     No

     No

     No

     No

     v7.5.0

     Baseline

     As at baseline


    A set of place names found in the text using Natural Language Processing.

    NLTags

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     set   [other set-type attributes]

     (not set - empty string)

     AI   [other AI Group attributes]

     Natural Language Processing

     No

     No

     No

     No

     v8.0.5

     Baseline

     As at baseline


    A set-type attribute to hold annotations automatically generated using Natural Language Processing.

    The first such annotation adds the tag 'plan' to notes that Tinderbox believes might represent a planning note, such as "remember to deposit the cheque" or "remind the freshers to begin planning their module essays".

    NoSpellling

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     boolean   [other boolean-type attributes]

     false

     TextFormat   [other TextFormat Group attributes]

     Note text

     No

     Yes

     No

     No

     v5.10.1

     Baseline

     As at baseline


    Allows notes to be ignored during spell checks.

    if a document is set to 'check spelling as you type', setting $NoSpelling to true will cause that note to be ignored.

    Default is 'false', i.e. the note is included in spell checks to maintain previous behaviour.

    $NoSpelling can be set for the current note via the Text Inspector ▸ Text tab, 'Bold' tick-box control.

    NotesFolder

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     string   [other string-type attributes]

     (not set - empty string)

     Watch   [other Watch Group attributes]

     Data synch

     No

     No

     No

     No

     v7.3.0

     Baseline

     As at baseline


    The name of an Apple Notes folder used by a watched folder.

    Individual synced Notes within the watched folder use $NotesID and $NotesModified.

    NotesID

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     string   [other string-type attributes]

     (not set - empty string)

     Watch   [other Watch Group attributes]

     Data synch

     No

     No

     No

     No

     v7.3.0

     Baseline

     As at baseline


    A unique source ID of Notes imported via a Notes watched folder.

    The source Notes folder is held in $NotesFolder.

    NotesModified

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     date   [other date-type attributes]

     (not set - never)

     Watch   [other Watch Group attributes]

     Data synch

     No

     No

     No

     No

     v7.3.0

     Baseline

     As at baseline


    The latest modification date/time of a Note imported/synced via a Notes or Finder watched folder.

    The source Notes folder is held in $NotesFolder.

    NoteURL

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     string   [other string-type attributes]

     (calculated)

     Net   [other Net Group attributes]

     Data synch

     No

     No

     Yes   [other read-only attributes]

     No

     v6.4.0

     Baseline

     As at baseline


    Pseudo-url (tinderbox://) URL for current note.

    A read-only attribute exposing the pseudo-url tinderbox:// allowing access the current note from other programs.

    This attribute is transferred when pasting notes to DEVONThink v2.8.8+.

    OnAdd

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     action   [other action-type attributes]

     (not set - empty string)

     General   [other General Group attributes]

     Action code

     No

     Yes

     No

     No

     v1.0.0

     Baseline

     As at baseline


    Action code expression executed when a note becomes child of the current note, be it new or moved there by dragging.

    Adornments also offer 'OnAdd' action support. Although it takes a string argument, the string must be valid action syntax.

    $OnAdd actions are applied to each item of a multiple-item drag, even if the dragged notes originate in a different file. The $OnAdd action is applied only once, when a note is created inside a container, or is moved into a container from some other container. This stops $OnAdd being re-applied for actions like moving a note on a Map and where $OnAdd may have iterative effects on a note if re-applied. Pasting a note into a container runs the $OnAdd action.

    The container's $OnAdd action acts on both newly-made notes and agents.

    For agents, $OnAdd is replaced by $AgentAction (though not in smart adornments)

    Adornments show a slightly different behaviour. Here, the $OnAdd is re-triggered if a note is moved manually within the adornment, i.e. never leaves it, as the move effectively takes the note out of the adornment (start of move) and adds it back at the end of the move. However, if notes are moved automatically within an adornment due to adornment sorting, or by an external action altering $Xpos/$Ypos, the adornment's $OnAdd is not run again.

    $OnAdd (or $AgentAction for agents) for the current note can be set via the Action Inspector ▸ Action tab, code input box.

    OnJoin

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     action   [other action-type attributes]

     (not set - empty string)

     Composites   [other Composites Group attributes]

     Composite configuration

     No

     No

     No

     No

     v7.0.0

     Baseline

     As at baseline


    An action performed when new composite members first touch existing members.

    Notes may have an $OnJoin action. When a note that was not previously a member of a composite is dragged to touch a note with an $OnJoin action, the $OnJoin action is performed on the dragged note. If a note touches more than one note in the composite, each $OnJoin action is performed in turn.

    In the context of an $OnJoin action, designator 'this' references the note joining the composite whilst 'that' references the note within composite to which it is now adjacent.

    OnMouseDown

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     action   [other action-type attributes]

     (not set - empty string)

     General   [other General Group attributes]

     Action code

     No

     No

     No

     No

     v11.6.0

     11.6.0

     As at baseline


    Action performed in map view when mouse cursor is pressed.

    From v11.6.0, this attribute is associated with mouse actions.

    OnMouseDrag

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     action   [other action-type attributes]

     (not set - empty string)

     General   [other General Group attributes]

     Action code

     No

     No

     No

     No

     v11.6.0

     11.6.0

     As at baseline


    Action invoked while the mouse is down if the mouse is moved and the note is locked.

    From v11.6.0, this attribute is associated with mouse actions.

    OnMouseUp

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     action   [other action-type attributes]

     (not set - empty string)

     General   [other General Group attributes]

     Action code

     No

     No

     No

     No

     v11.6.0

     11.6.0

     As at baseline


    Action performed in map view when mouse cursor is released.

    From v11.6.0, this attribute is associated with mouse actions.

    OnPaste

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     action   [other action-type attributes]

     (not set - empty string)

     General   [other General Group attributes]

     Action code

     No

     No

     No

     No

     v10.1.2

     Baseline

     As at baseline


    Action code expression executed when performed when a note is into a document.

    An OnPaste action is performed when a note is pasted, either into the same document or into a new document. If more than one note was copied, OnPaste is called after this note has been created, but may be called before other notes have been created.

    OnPaste might help when creating an "INSTALL ME" stamp when copying a self-installing library to a new document.

    OnRemove

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     action   [other action-type attributes]

     (not set - empty string)

     General   [other General Group attributes]

     Action code

     No

     No

     No

     No

     v7.0.0

     Baseline

     As at baseline


    Action code expression executed when performed when a note is removed from this container.

    The OnRemove action for agents is applied to the original note, since the alias will be deleted. Note, too, that agents may remove notes and add them again at any time.

    When cutting a note, the OnRemove action of its container is applied before the note is copied to the pasteboard.

    $OnRemove for the current note can be set via the Action Inspector ▸ Remove tab, code input box.

    OnVisit

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     action   [other action-type attributes]

     (not set - empty string)

     Storyspace   [other Storyspace Group attributes]

     Storyspace compatibility

     No

     No

     No

     No

     v6.3.1

     Baseline

     As at baseline


    In Storyspace, an action performed when the reader visits the note.

    This is honoured in Tinderbox and can be used as an 'OnSelection' event trigger.

    Opacity

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     number   [other number-type attributes]

     1

     Appearance   [other Appearance Group attributes]

     Map item general configuration

     No

     No

     No

     No

     v5.0.0

     Baseline

     As at baseline


    Opacity of a note icon in map view.

    The default opacity value of 1 leaves notes opaque, while an opacity of zero allows the note interior to be transparent.

    The allowed range of values is 0–1. Prior to v9.7.0, the range was 0–100 but this was changed—see more.

    Translucency may be useful in some maps with complex link networks, and also permits interesting visual effects.

    N.B. Borders are not translucent.

    Containers and agents are never translucent. If a note was translucent, later becomes a container, and later yet becomes a simple note once more, the note's $Opacity will again control its opacity.

    Notes using some shapes—"cloud" and "bubble"—are drawn without borders when translucent.

    The Interior inspector's, Pattern ▸ translucent option toggles an Opacity value of 0.5.

    Both $TitleOpacity and $SubtitleOpacity are independent of $Opacity. However, the if higher than the value of $Opacity, the latter value is used when drawing the note.

    Organization

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     string   [other string-type attributes]

     (not set - empty string)

     People   [other People Group attributes]

     Person detail

     No

     No

     No

     No

     v3.5.1

     Baseline

     As at baseline


    Intended for storing the a person's company or organisation name.

    OutboundLinkCount

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     number   [other number-type attributes]

     (calculated)

     General   [other General Group attributes]

     Calculated data

     No

     No

     Yes   [other read-only attributes]

     Yes   [other intrinsic attributes]

     v3.0.0

     Baseline

     As at baseline


    Number of outbound links originating from the current note (read-only).

    The count includes both outbound basic and text links. Discrete totals are also calculated for outbound basic links ($PlainLinkCount) and for outbound text links ($TextLinkCount). However, any Web links are counted completely separately in $WebLinkCount.

    See also $InboundLinkCount.

    The link count always excludes any links of type "Prototype".

    OutlineBackgroundColor

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     color   [other color-type attributes]

     automatic

     Outline   [other Outline Group attributes]

     Outline configuration

     No

     No

     No

     No

     v5.5.0

     Baseline

     As at baseline


    Colour used as background colour of the selected note(s) listing in Outline view.

    The colour is carried across the width of the view including checkbox and column display areas.

    With the default value of "automatic" the colour used is simply the same as $MapBackgroundColor; the inside is outline checkboxes is always shown in grey.

    OutlineColorSwatch

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     boolean   [other boolean-type attributes]

     false

     Outline   [other Outline Group attributes]

     Outline configuration

     No

     No

     No

     No

     v4.0.0

     Baseline

     As at baseline


    Use a colour swatch in Outline view instead of a badge.

    Controls whether a note in Outline View shows a colour swatch between the note icon and its title. If true the swatch is drawn in $Color.

    It occupies the same space as a badge and is suppressed if a $Badge is set

    This attribute enables outlines to show simple progress bars. If the latter pattern is used, the swatch is drawn in $Color and $AccentColor.

    This feature is deprecated, in favour of using flags in outlines.

    OutlineDepth

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     number   [other number-type attributes]

     (calculated)

     General   [other General Group attributes]

     Calculated data

     No

     No

     Yes   [other read-only attributes]

     Yes   [other intrinsic attributes]

     v2.1.0

     Baseline

     As at baseline


    Number of outline levels between a note and the document root (read-only).

    Actually, it is 1 + the number as 'top-level' notes have $OutlineDepth of 1, notes inside a top-level container have $OutlineDepth of 2, and so forth.

    Aliases do not inherit this property from their original but have their own intrinsic value.

    OutlineNameSize

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     number   [other number-type attributes]

     100

     Outline   [other Outline Group attributes]

     Outline configuration

     No

     Yes

     No

     No

     v8.2.2

     Baseline

     As at baseline


    Adjust the relative size of note title ($Name) text in Outline/Chart/Timeline views.

    The default is 100 (%).

    The base font size of outline items (usually 14pt) is set in the Maps tab of Document Settings, or via the Text Inspector's Title tab (allowed values are described there).

    This setting does not affect the line weight of separators, only the text height of the line they occupy (to allow for a text label even if not used).

    This is a rename/replacement of $OutlineTextSize.

    The rename mirrors the renaming of $MapTextSize to $MapNameSize.

    The old names are deprecated but will continue to function.

    OutlineOrder

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     number   [other number-type attributes]

     (calculated)

     General   [other General Group attributes]

     Calculated data

     No

     No

     Yes   [other read-only attributes]

     Yes   [other intrinsic attributes]

     v1.2.0

     Baseline

     As at baseline


    Sequential position in the overall document hierarchy (read-only).

    It can be used by agents to judge the position of a note within the document. Note that some items not displayed in the Outline view, such as adornments, are still included in the $OutlineOrder. This should be borne in mind if doing calculations based on comparing sibling $OutlineOrder values as the 'next' item may not be a note (and there is no way to test this fact).

    The order of notes within the current container is shown by $SiblingOrder.

    The lowest number is drawn at the front in a map. If notes with outline orders #1 and #5 overlap, part of #5 will be behind the icon for #1.

    The note menu command to move a note forward/backward or all the way to the back/front will alter both $OutlineOrder and $SiblingOrder for the affected note(s).

    Aliases do not inherit this property from their original but have their own value.

    OutlineTextSize

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     number   [other number-type attributes]

     100

     Outline   [other Outline Group attributes]

     Outline configuration

     No

     No

     No

     No

     v3.5.0

     Baseline

     As at baseline


    Deprecated: use $OutlineNameSize instead.

    The default is 100 (%).

    Adjust the relative size of note title ($Name) text in Outline/Chart/Timeline views.

    The base font size of outline items (usually 14pt) is set in the Maps tab of Document Settings, or via the Text Inspector's Title tab (allowed values are described there).

    This setting does not affect the line weight of separators, only the text height of the line they occupy (to allow for a text label even if not used).

    Pages

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     string   [other string-type attributes]

     (not set - empty string)

     References   [other References Group attributes]

     Data synch

     No

     No

     No

     No

     v5.11.0

     Baseline

     As at baseline


    Used for Bookends reference import. Maps to RIS data tag 'SP'.

    ParagraphSpacing

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     number   [other number-type attributes]

     8

     TextFormat   [other TextFormat Group attributes]

     Note text

     Yes

     Yes

     No

     No

     v3.0.0

     Baseline

     As at baseline


    Sets paragraph spacing for individual notes.

    The default value of $ParagraphSpacing is set in the Text pane of Document Settings.

    $ParagraphSpacing can be set for the current note via the Text Inspector ▸ Text tab, 'Paragraph Spacing' control.

    Participants

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     set   [other set-type attributes]

     (not set - empty string)

     Events   [other Events Group attributes]

     

     No

     No

     No

     No

     v9.5.2

     Baseline

     As at baseline


    A listing of an event's participants.

    See Calendar event drag-drop.

    Path

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     string   [other string-type attributes]

     (calculated)

     General   [other General Group attributes]

     Calculated data

     No

     No

     Yes   [other read-only attributes]

     Yes   [other intrinsic attributes]

     v4.6.0

     Baseline

     As at baseline


    Contains the path from the root of the document to the note (read-only).

    For example, if the document contains the following notes:

    To Do
        Bank
        Post Office
        Garden
            Weeding
    Done
        Tax

    then the $Path of note 'Weeding' would be:

    /To Do/Garden/Weeding 

    Note that this is the full path, including the current notes name. A full path always starts with a '/' character.

    $Path is identified as intrinsic.

    Pattern

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     string   [other string-type attributes]

     plain

     Appearance   [other Appearance Group attributes]

     Map item general configuration

     No

     Yes

     No

     No

     v2.3.1

     Baseline

     As at baseline


    Optional pattern to be drawn on the face of icons in Map view.

    $Pattern may be set for the current note via the Appearance Inspector ▸ Interior tab, 'Pattern' control: for plot-style $Pattern values us the Appearance Inspector ▸ Plot tab, 'Pattern' control instead.

    These patterns look best when the two colours are similar but not identical. The keywords are case-sensitive. The current default is 'plain'.

    If $Pattern is plain no pattern is applied and the note face is drawn in solid $Color.

    If $Pattern is lines, the face of the note is filled with alternative horizontal lines of $Color and $AccentColor.

    If $Pattern is gradient, the face of the note is filled with a linear colour gradient, top to bottom, from $Color to $AccentColor.

    If $Pattern is diagonal, the face of the note is filled with a linear colour gradient, running from upper-left to lower-right corner, from $Color to $AccentColor.

    If $Pattern is cylinder, the face of the note is filled with a cylindrical gradient, running from $Color at the top through $AccentColor at the midpoint, and then to $Color again at the bottom.

    If $Pattern is radial, the face of the note is a graduation from $Color at 1/3 in from top-left through $AccentColor toward all edges.

    If $Pattern is not set (empty string), no pattern is applied and equating to plain.

    The remaining seven patterns cannot be set via the Pattern menu. Rather they are set via manual editing of this attribute (Info view, Displayed Attributes) or via actions, rules, stampstc., acting upon it. These patterns are:

    PlainLinkCount

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     number   [other number-type attributes]

     (calculated)

     General   [other General Group attributes]

     Calculated data

     No

     No

     Yes   [other read-only attributes]

     Yes   [other intrinsic attributes]

     v5.12.1

     Baseline

     As at baseline


    Holds the number of outbound basic links.

    Also see $TextLinkCount, $WebLinkCount, $OutboundLinkCount.

    PlotBackgroundColor

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     color   [other color-type attributes]

     white

     Map   [other Map Group attributes]

     Map configuration

     No

     Yes

     No

     No

     v5.10.2

     Baseline

     As at baseline


    Colour of the plot background when a map container plot is configured.

    If the container has a pattern such as plot/bargraph/xyplot), before the graph is drawn the space behind the plot is filled with the colour $PlotBackgroundColor with opacity of $PlotBackgroundOpacity. Previously the background was that of the child map.

    $PlotBackgroundColor for the current note may be set via the Appearance Inspector ▸ Plot tab, 'Background' colour controls.

    PlotBackgroundOpacity

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     number   [other number-type attributes]

     0.5

     Map   [other Map Group attributes]

     Map configuration

     No

     Yes

     No

     No

     v5.10.2

     Baseline

     As at baseline


    Opacity of background colour to the plot when a map container plot is configured.

    The allowed range of values is 0–1. Prior to v9.7.0, the range was 0–100 but this was changed—see more.

    If the container has a pattern such as plot/bargraph/xyplot), before the graph is drawn, the space behind the plot is filled with the colour $PlotBackgroundColor with opacity of $PlotBackgroundOpacity. Previously the background was that of the child map.

    $PlotBackgroundOpacity for the current note may be set via the Appearance Inspector ▸ Plot tab, 'Background' slider control.

    PlotColor

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     color   [other color-type attributes]

     light green

     Appearance   [other Appearance Group attributes]

     Map item general configuration

     No

     Yes

     No

     No

     v4.5.0

     Baseline

     As at baseline


    Colour used to draw plots in containers.

    $PlotColor for the current note may be set via the Appearance Inspector ▸ Plot tab, 'Plot Color' colour controls.

    PlotColorList

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     list   [other list-type attributes]

     2;7;3;8;4;9;0;5;1;6

     Map   [other Map Group attributes]

     Map item general configuration

     No

     No

     No

     No

     v6.2.1

     Baseline

     As at baseline


    A list of colours to be used in this note's pie charts.

    The default value is the list [2;7;3;8;4;9;0;5;1;6], using the default built-in numbered greyscale colours. The first colour designates the colour of the first segment, and remaining colours in the list are used in rotation until all segments have been drawn. If the list contains fewer than two colours, the list [black;white] is used instead.

    As a List-type attribute, this can take a list of values of any defined system/user colour names, such as might be generated by collect(children,$Color).

    PostalCode

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     string   [other string-type attributes]

     (not set - empty string)

     Places   [other Places Group attributes]

     Locational data

     No

     No

     No

     No

     v6.0.0

     Baseline

     As at baseline


    The Postal Code field of an address.

    The automatic geocoding tries to supply these fields automatically when looking up the supplied $Address.

    The date type is a string as not all countries use number-only postal/zip codes.

    PosterCSS

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     string   [other string-type attributes]

     (not set - empty string)

     Poster   [other Poster Group attributes]

     Poster configuration

     No

     No

     No

     No

     v9.6.0

     Baseline

     As at baseline


    Holds CSS rules to apply to the poster.

    This holds CSS rules that are applied to the note's poster, whether generated via a template or called via a URL.

    PosterLabels

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     list   [other list-type attributes]

     (not set - empty string)

     Poster   [other Poster Group attributes]

     Poster configuration

     No

     No

     No

     No

     v9.6.0

     Baseline

     As at baseline


    A utility attribute for passing information to a poster's visualisation tool.

    New to v9.6.0, this is an assistive option for poster configuration and has no special significance to Tinderbox.

    PosterSettings

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     string   [other string-type attributes]

     (not set - empty string)

     Poster   [other Poster Group attributes]

     Poster configuration

     No

     No

     No

     No

     v9.6.0

     Baseline

     As at baseline


    A utility attribute for passing information to a poster's visualisation tool.

    This is an assistive option for poster configuration and has no special significance to Tinderbox.

    PosterTemplate

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     string   [other string-type attributes]

     (not set - empty string)

     Poster   [other Poster Group attributes]

     Poster configuration

     No

     No

     No

     No

     v9.6.0

     Baseline

     As at baseline


    The template note used to define a poster.

    $PosterTemplate specifies a template note, much as $HTMLExportTemplate does. This template is applied to the note, and the result is displayed on the poster affixed to the note.

    PosterURL

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     URL   [other URL-type attributes]

     (not set - empty string)

     Poster   [other Poster Group attributes]

     Poster configuration

     No

     No

     No

     No

     v9.6.0

     Baseline

     As at baseline


    The URL used to call a poster visualisation

    $PosterURL specifies a URL to be displayed in the current note's poster.

    The expectation is that $PosterURL will be much less common than $PosterTemplate. If a note has both a $PosterTemplate and a $PosterURL, the $PosterURL is ignored.

    PosterX

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     list   [other list-type attributes]

     (not set - empty string)

     Poster   [other Poster Group attributes]

     Poster configuration

     No

     No

     No

     No

     v9.6.0

     Baseline

     As at baseline


    A utility attribute for passing information to a poster's visualisation tool.

    This is an assistive option for poster configuration and has no special significance to Tinderbox.

    PosterY

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     list   [other list-type attributes]

     (not set - empty string)

     Poster   [other Poster Group attributes]

     Poster configuration

     No

     No

     No

     No

     v9.6.0

     Baseline

     As at baseline


    A utility attribute for passing information to a poster's visualisation tool.

    This is an assistive option for poster configuration and has no special significance to Tinderbox.

    PosterZoom

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     number   [other number-type attributes]

     1.0

     Poster   [other Poster Group attributes]

     Poster configuration

     No

     No

     No

     No

     v9.6.0

     Baseline

     As at baseline


    A zoom value applied to posters sourced via a URL

    Default value is 1.0.

    $PosterZoom is a numeric attribute representing the magnification applied to posters loaded through $PosterURL. Its default value is 1.0, representing the page's normal size. A $PosterZoom of 0.5 would display the source page at half original screen size.

    Private

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     boolean   [other boolean-type attributes]

     false

     General   [other General Group attributes]

     Special note type designator

     No

     No

     No

     No

     v4.0.2

     Baseline

     As at baseline


    Controls whether a prototype appears in the Map view prototype tab menu or the Outline view pop-up list.

    When set as Private, the note is removed from the popup menu of the Properties Inspector's Prototype sub-tab. This lets TBX document authors reserve some prototypes for special or internal use.

    Other uses of "private" may be added in the future.

    Prototype

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     string   [other string-type attributes]

     (not set - empty string)

     General   [other General Group attributes]

     General data

     No

     Yes

     No

     No

     v1.0.0

     Baseline

     As at baseline


    The name of the current note's prototype note (if there is one).

    The value may be the name of another prototype.

    $Prototype for the current note may be set via the Properties Inspector ▸ Prototype tab, 'Prototype' pop-up control.

    PrototypeBequeathsChildren

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     boolean   [other boolean-type attributes]

     true

     General   [other General Group attributes]

     Special note type designator

     No

     No

     No

     No

     v4.0.1

     Baseline

     As at baseline


    Controls whether a prototype's children are inherited by notes using that prototype.

    Thus this attribute only has meaning for notes for which $IsPrototype is also set to true.

    Children created by this method are not removed from inheriting notes if they subsequently cease to use the prototype.

    By default (true ) all new prototypes will bequeath children and all descendants.

    For prototypes that do not/will not have children this attribute has no effect on general function. However, if you like to nest your prototypes, do set this attribute to false.

    Do not bequeath children that are themselves prototypes. Instead, create separate prototypes outside the bequeathed layout and set the source notes in the latter to use a prototype.

    More on prototypes and prototype bequeathal.

    PrototypeHighlightColor

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     color   [other color-type attributes]

     #cceecc

     Outline   [other Outline Group attributes]

     Outline configuration

     No

     Yes

     No

     No

     v6.0.0

     Baseline

     As at baseline


    Colour of the circle shown behind the Outline view note icons of prototype notes.

    The default is very light: if prototypes do not show a mark behind them try a darker value for this attribute. To avoid the mark showing, set the attribute the same as $MapBackgroundColor.

    The default value of #cceecc is inherited from the Document Setting's Outline tab's Prototype highlight colour setting.

    This attribute is a direct replacement for the older $MapPrototypeColor attribute.

    PublicationCity

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     string   [other string-type attributes]

     (not set - empty string)

     References   [other References Group attributes]

     Data synch

     No

     No

     No

     No

     v5.11.0

     Baseline

     As at baseline


    Used for Bookends reference import. Maps to RIS data tag 'CY'.

    PublicationYear

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     string   [other string-type attributes]

     (not set - empty string)

     References   [other References Group attributes]

     Data synch

     No

     No

     No

     No

     v5.11.0

     Baseline

     As at baseline


    Used for Bookends reference import. Maps to RIS data tag 'PY'.

    Publisher

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     string   [other string-type attributes]

     (not set - empty string)

     References   [other References Group attributes]

     Data synch

     No

     No

     No

     No

     v5.11.0

     Baseline

     As at baseline


    Used for Bookends reference import. Maps to RIS data tag 'PB'.

    QuickListHangingIndent

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     number   [other number-type attributes]

     12

     TextFormat   [other TextFormat Group attributes]

     HTML export encoding

     No

     No

     No

     No

     v10.0.0

     Baseline

     As at baseline


    The desired indentation of second and later lines in quick lists items in $Text.

    The indent is set in pixels, default value is 12.

    This attribute allows all lines after the first line of an item to be further indented, giving prominence to the first line. The indent for the first quick list item is set in $QuickListIndent.

    All quick lists within the note's $Text—if more than one—use the same indent settings.

    QuickListIndent

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     number   [other number-type attributes]

     24

     TextFormat   [other TextFormat Group attributes]

     HTML export encoding

     No

     No

     No

     No

     v10.0.0

     Baseline

     As at baseline


    The desired indentation of quick lists items in $Text.

    The indent is set in pixels, default value is 24.

    The indent for quick list items' second and subsequent lines of text is set in $QuickListHangingIndent.

    All quick lists within the note's $Text—if more than one—use the same indent settings.

    Range

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     number   [other number-type attributes]

     (not set - 0)

     Places   [other Places Group attributes]

     Locational data

     No

     No

     No

     No

     v8.0.4

     Baseline

     As at baseline


    This represents the approximate range of a geographic adornment in kilometres.

    Number-type attribute, in the Places group.

    RawData

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     string   [other string-type attributes]

     (not set - empty string)

     Net   [other Net Group attributes]

     Import configuration

     No

     No

     No

     No

     v3.6.0

     Baseline

     As at baseline


    An experimental attribute. It should be treated as an internal field for Tinderbox's private use.

    It is listed here simply to discourage inquisitive tinkering. As an experimental attribute it may disappear, be renamed or take on a new purpose in later versions.

    Purpose is experimental in support of RSS and AutoFetch to hold the raw data should the planned fetch fail.

    ReadCount

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     number   [other number-type attributes]

     (calculated)

     General   [other General Group attributes]

     Calculated data

     No

     No

     Yes   [other read-only attributes]

     No

     v4.5.0

     Baseline

     As at baseline


    Tracks the number of times that a note is opened (read-only).

    The count is cumulative from the creation of the note.

    This attribute is now deprecated and not created in v6+; if already present from use in older version, it is no longer updated. In older versions, it tracked the opening of a note's text window.

    ReadOnly

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     boolean   [other boolean-type attributes]

     false

     Textual   [other Textual Group attributes]

     Note text

     No

     No

     No

     No

     v1.0.0

     Baseline

     As at baseline


    Controls UI-based editing of the text of a note ($Text) or any contents of the displayed attributes table.

    Behaviour of this, and the associated $Lock and $DoNotDelete attributes are discussed under Non-editable notes.

    ReadwiseDate

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     date   [other date-type attributes]

     (not set - never)

     References   [other References Group attributes]

     Data synch

     No

     No

     No

     No

     v11.5.0

     11.5.0

     As at baseline


    The last date/time this note was updated from Readwise.

    ReadwiseID

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     number   [other number-type attributes]

     (not set - 0)

     References   [other References Group attributes]

     Data synch

     No

     No

     No

     No

     v11.5.0

     11.5.0

     As at baseline


    An ID number that helps Readwise locate items.

    ReadwiseToken

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     string   [other string-type attributes]

     (not set - empty string)

     References   [other References Group attributes]

     Data synch

     Yes

     No

     No

     No

     v11.5.0

     11.5.0

     As at baseline


    The token used with the Readwise API.

    This number is inherited from the Document Settings:Accounts tab's Readwise setting.

    ReferenceData

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     string   [other string-type attributes]

     (not set - empty string)

     References   [other References Group attributes]

     Data synch

     No

     No

     No

     No

     v11.0.1

     11.0.1

     As at baseline


    Used for Bookends reference import. Holds to full RIS data supplied.

    The is a renaming of and replacement for he now deprecated $ReferenceRIS.

    This is populated for dragged RIS files or for a reference dragged from Bookends and possible other reference manager apps.

    See RIS import.

    ReferenceDictionary

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     dictionary   [other dictionary-type attributes]

     (not set - empty string)

     References   [other References Group attributes]

     Data synch

     No

     No

     No

     No

     v9.0.0

     Baseline

     As at baseline


    Provides a dictionary of RIS information from imported references.

    ReferenceRIS

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     string   [other string-type attributes]

     (not set - empty string)

     References   [other References Group attributes]

     Data synch

     No

     No

     No

     No

     v5.11.0

     Baseline

     11.0.1


    Deprecated, use ReferenceData instead.

    Used for Bookends reference import. Holds to full RIS data supplied.

    This is populated for dragged RIS files or for a reference dragged from Bookends and possible other reference manager apps.

    Deprecated in favour of $ReferenceData.

    See RIS import.

    ReferenceTitle

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     string   [other string-type attributes]

     (not set - empty string)

     References   [other References Group attributes]

     Data synch

     No

     No

     No

     No

     v5.11.0

     Baseline

     As at baseline


    Used for Bookends reference import. Maps to RIS data tag 'T1'

    Note: maps 'T1' except for CHAP (Chapter) type references.

    ReferenceURL

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     URL   [other URL-type attributes]

     (not set - empty string)

     References   [other References Group attributes]

     Data synch

     No

     No

     No

     No

     v5.11.0

     Baseline

     As at baseline


    Used for Bookends reference import. Maps to RIS data tag 'UR'.

    RefFormat

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     string   [other string-type attributes]

     (not set - empty string)

     References   [other References Group attributes]

     Data synch

     No

     No

     No

     No

     v5.11.0

     Baseline

     As at baseline


    Used for Bookends reference import.

    RefKeywords

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     set   [other set-type attributes]

     (not set - empty string)

     References   [other References Group attributes]

     Data synch

     No

     No

     No

     No

     v5.11.0

     Baseline

     As at baseline


    Used for Bookends reference import. Maps to RIS data tag 'KW'.

    RefType

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     string   [other string-type attributes]

     (not set - empty string)

     References   [other References Group attributes]

     Data synch

     No

     No

     No

     No

     v5.11.0

     Baseline

     As at baseline


    Used for Bookends reference import. Maps to value of RIS data tag 'TY'.

    See RIS import.

    Requirements

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     action   [other action-type attributes]

     (not set - empty string)

     Storyspace   [other Storyspace Group attributes]

     Storyspace compatibility

     No

     No

     No

     No

     v6.3.2

     Baseline

     As at baseline


    Storyspace: writing space entry logic

    In Storyspace, this holds the requirement logic to be met before a writing space can be visited in read mode.

    Evaluating $Requirements tests if the desired linked space can be accessed. If the test is evaluates false, the link is not followed, even if the links guard field is satisfied.

    This logic is not tested in Tinderbox.

    ResetAction

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     action   [other action-type attributes]

     (not set - empty string)

     Storyspace   [other Storyspace Group attributes]

     Storyspace compatibility

     No

     No

     No

     No

     v6.3.2

     Baseline

     As at baseline


    Storyspace: reset action.

    In Storyspace, the action to be evaluated if the user selects the cover sheet in read mode.

    This logic is not tested in Tinderbox.

    RightMargin

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     number   [other number-type attributes]

     2

     TextFormat   [other TextFormat Group attributes]

     Note text

     No

     No

     No

     No

     v3.0.0

     Baseline

     As at baseline


    Legacy-only feature to set left margin.

    $RightMargin and $LeftMargin are legacy features to allow the user to set margins for individual notes.

    Note that the margins are set in multiples of 9 pixels; a left margin of 4 is equivalent to 36 pixels (0.5" or about 12.5mm).

    Below is for legacy reference only…

    As left and right margins are now the same and $RightMargin is ignored and retained only for legacy compatibility purposes.

    Prior to v6.6.0, the default is set in the Text pane of the Preferences.

    When copying and pasting note text between TBX files with different margin settings, the pasted text takes the receiving note's margin settings but the note window must be closed and re-opened for this fact to be correctly displayed on screen. See also Pasting and Text Margins.

    Role

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     string   [other string-type attributes]

     (not set - empty string)

     Composites   [other Composites Group attributes]

     Composite configuration

     No

     No

     No

     No

     v7.0.0

     Baseline

     As at baseline


    The (optional) role within the composite of an individual note.

    If a note has a $Role but not $Subtitle, the Role is displayed where the Subtitle would normally appear.

    RSSChannelTemplate

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     file   [other file-type attributes]

     RSSChannel

     Net   [other Net Group attributes]

     Import configuration

     No

     No

     No

     No

     v1.0.0

     Baseline

     As at baseline


    Specifies the name of the template used for RSS channels when importing ('AutoFetching') as RSS feed.

    Not present in new documents, but it may be present in documents created on older application versions; its use, if present is deprecated.

    The default template is stored in the Tinderbox application package (though not in its templates folder) and is:

        ^title^
        ^link^
        ^subtitle^
        ^description^
    RSSItemLimit

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     number   [other number-type attributes]

     (not set - 0)

     Net   [other Net Group attributes]

     Import configuration

     No

     No

     No

     No

     v1.0.0

     Baseline

     As at baseline


    Restrict the size of any feed being read into Tinderbox.

    Not present in new documents, but it may be present in documents created on older application versions; its use, if present is deprecated.

    Some news feeds syndicated a large number of items, and your design might have space for only a few.

    The default value, zero, imposes no limit on the number of items imported.

    RSSItemTemplate

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     file   [other file-type attributes]

     RSSItem

     Net   [other Net Group attributes]

     Import configuration

     No

     No

     No

     No

     v1.0.0

     Baseline

     As at baseline


    Specifies the template used for RSS items with importing ('AutoFetching') an RSS feed.

    Not present in new documents, but it may be present in documents created on older application versions; its use, if present is deprecated.

    The default template is stored in the Tinderbox application package (though not in its templates folder) and is:

        ^title^
        ^link^
        ^description^
    Rule

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     action   [other action-type attributes]

     (not set - empty string)

     General   [other General Group attributes]

     Action code

     No

     Yes

     No

     No

     v2.4.0

     Baseline

     As at baseline


    The rule code that the note executes.

    The string must be valid action syntax.

    The rule can be overridden in the current note (i.e. still stored but not executed) by setting $RuleDisabled.

    $Rule for the current note can be set via the Action Inspector ▸ Rule tab, code box.

    RuleDisabled

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     boolean   [other boolean-type attributes]

     false

     General   [other General Group attributes]

     Action code

     No

     Yes

     No

     Yes   [other intrinsic attributes]

     v5.8.0

     Baseline

     As at baseline


    Allows the $Rule for a specific note to be disabled. It is intrinsic and thus not inherited.

    Atypically for inheritance in Tinderbox, it is not inherited from a note's prototype (unlike most other attributes), partly because a primary use is suppressing code running in prototypes.

    $RuleDisabled is convenient when a rule may make significant changes to the note (or other parts of the document). Setting such a rule via a prototype can be problematic as the intent is only to rule to rule in notes inheriting the rule. Thus it can be useful to suppress $Rule activation in prototypes. Previously, this meant placing the Rule in an 'if($Prototype)' test which was cumbersome and meant every inheriting note had to run the addition if test adding load to the action code cycle. That workaround can be discarded and the attribute set to true in the Prototype. Because, atypically, this attribute is not inherited from a prototype, the prototype's setting does not affect the Display Expression in notes using the prototype.

    A similar control is supplied for display expressions: $DisplayExpressionDisabled.

    $RuleDisabled for the current note can be set via the Action Inspector ▸ Rule tab, 'enabled' tick-box.

    RunCommandShell

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     string   [other string-type attributes]

     /bin/sh

     General   [other General Group attributes]

     General data

     No

     No

     No

     No

     v11.0.0

     11.0.0

     As at baseline


    Holds the path of the shell to be used for runCommand() actions.

    The default value is /bin/sh, which in the past was invariably the OS default.

    ScreenHeight

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     number   [other number-type attributes]

     (not set - 0)

     Poster   [other Poster Group attributes]

     Poster configuration

     No

     No

     Yes   [other read-only attributes]

     No

     v9.6.0

     Baseline

     11.0.0


    Records the poster's height in pixels to aid template configuration

    The default value is 0, and is read-only.

    This attribute aids in configuring the HTML in poster templates. The pixel value is for map view at the magnification currently in use.

    From v11.0.0, $ScreenHeight and $ScreenWidth are now set only using map view. This enables posters to be previewed in the text pane when the tab's view type is other than Map view.

    ScreenWidth

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     number   [other number-type attributes]

     (not set - 0)

     Poster   [other Poster Group attributes]

     Poster configuration

     No

     No

     Yes   [other read-only attributes]

     No

     v9.6.0

     Baseline

     11.0.0


    Records the poster's width in pixels to aid template configuration

    The default value is 0, and is read-only.

    This attribute aids in configuring the HTML in poster templates. The pixel value is for map view at the magnification currently in use.

    From v11.0.0, $ScreenHeight and $ScreenWidth are now set only using map view. This enables posters to be previewed in the text pane when the tab's view type is other than Map view.

    ScrivenerID

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     string   [other string-type attributes]

     (not set - empty string)

     Scrivener   [other Scrivener Group attributes]

     Data synch

     No

     No

     No

     No

     v5.11.0

     Baseline

     As at baseline


    Used for Scrivener Import.

    ScrivenerKeywords

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     set   [other set-type attributes]

     (not set - empty string)

     Scrivener   [other Scrivener Group attributes]

     Data synch

     No

     No

     No

     No

     v5.11.0

     Baseline

     As at baseline


    Used for Scrivener Import.

    ScrivenerLabel

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     string   [other string-type attributes]

     (not set - empty string)

     Scrivener   [other Scrivener Group attributes]

     Data synch

     No

     No

     No

     No

     v5.11.0

     Baseline

     As at baseline


    Used for Scrivener Import.

    ScrivenerLabelID

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     number   [other number-type attributes]

     (not set - 0)

     Scrivener   [other Scrivener Group attributes]

     Data synch

     No

     No

     No

     No

     v5.11.0

     Baseline

     As at baseline


    Used for Scrivener Import.

    ScrivenerNote

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     string   [other string-type attributes]

     (not set - empty string)

     Scrivener   [other Scrivener Group attributes]

     Data synch

     No

     No

     No

     No

     v5.11.0

     Baseline

     As at baseline


    Used for Scrivener Import.

    ScrivenerStatus

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     string   [other string-type attributes]

     (not set - empty string)

     Scrivener   [other Scrivener Group attributes]

     Data synch

     No

     No

     No

     No

     v5.11.0

     Baseline

     As at baseline


    Used for Scrivener Import.

    ScrivenerStatusID

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     number   [other number-type attributes]

     (not set - 0)

     Scrivener   [other Scrivener Group attributes]

     Data synch

     No

     No

     No

     No

     v5.11.0

     Baseline

     As at baseline


    Used for Scrivener Import.

    ScrivenerType

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     string   [other string-type attributes]

     (not set - empty string)

     Scrivener   [other Scrivener Group attributes]

     Data synch

     No

     No

     No

     No

     v5.11.0

     Baseline

     As at baseline


    Used for Scrivener Import.

    Searchable

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     boolean   [other boolean-type attributes]

     true

     General   [other General Group attributes]

     Agent configuration

     No

     No

     No

     Yes   [other intrinsic attributes]

     v5.11.0

     Baseline

     As at baseline


    This allows fine-tuning of searches.

    The default value is true; for adornments is it always false. The attribute is intrinsic.

    SelectionCount

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     number   [other number-type attributes]

     (calculated)

     General   [other General Group attributes]

     Calculated data

     No

     No

     Yes   [other read-only attributes]

     Yes   [other intrinsic attributes]

     v4.5.0

     Baseline

     11.0.0


    Tracks the number of times that a note is selected in a view window (read-only).

    The count is cumulative from the creation of the note.

    The count is incremented regardless of the view type. Moving a note on a map will involve a selection. Thus the count may not reflect the number of times the user selected the note in order to engage with its contents.

    From v11.0.0, $SelectionCount is no longer incremented automatically on selection. The count has proved to be less use than imagined whilst imposing an overhead to monitor/save the values.

    Sentiment

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     number   [other number-type attributes]

     (not set - 0)

     AI   [other AI Group attributes]

     Natural Language Processing

     No

     No

     No

     No

     v9.0.0

     Baseline

     As at baseline


    The average sentiment score set via analysis of $Text.

    Sentiment analysis is part of the Tagger process.

    The average is derived from the per-paragraph values stored in $Sentiments.

    Sentiments

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     list   [other list-type attributes]

     0

     AI   [other AI Group attributes]

     Natural Language Processing

     No

     No

     No

     No

     v9.0.0

     Baseline

     As at baseline


    A list of the sentiment score analysed of each paragraph of $Text.

    Sentiment analysis is part of the Tagger process.

    The average sentiment for the entire note is stored in $Sentiment.

    Separator

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     boolean   [other boolean-type attributes]

     false

     Outline   [other Outline Group attributes]

     Outline configuration

     No

     Yes

     No

     No

     v3.5.0

     Baseline

     As at baseline


    Deprecated: controls whether a note or agent is rendered as a separator in Outline view.

    This is replaced by the more explicit $IsSeparator.

    If notes are given no name, i.e. shown just as a line, a duplicate name warning is not issued even if reporting of such is turned on as a Warning Preference. The text of the separator is centred if it is smaller than the width of the separator label box.

    $Separator can be set via the Properties Inspector ▸ Prototype tab, 'Separator' tick-box.

    Shadow

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     boolean   [other boolean-type attributes]

     false

     Appearance   [other Appearance Group attributes]

     Map item shadow configuration

     No

     Yes

     No

     No

     v4.5.0

     Baseline

     As at baseline


    Controls whether an object uses drop shadows when rendered in maps.

    When Shadow is false, the following attributes are ignored: $ShadowBlur, $ShadowColor, $ShadowDistance.

    $Shadow for the current note can be set via the Appearance Inspector ▸ Shadow tab, 'Shadow' tick-box.

    ShadowBlur

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     number   [other number-type attributes]

     10

     Appearance   [other Appearance Group attributes]

     Map item shadow configuration

     No

     Yes

     No

     No

     v4.5.0

     Baseline

     As at baseline


    Blurriness of the object's map icon shadow as a numeric value.

    The allowed range is 0-100.

    This attribute is ignored if $Shadow is false.

    $ShadowBlur for the current note can be set via the Appearance Inspector ▸ Shadow tab, 'Blur' control.

    ShadowColor

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     color   [other color-type attributes]

     black

     Appearance   [other Appearance Group attributes]

     Map item shadow configuration

     No

     Yes

     No

     No

     v4.5.0

     Baseline

     As at baseline


    Hue of the shadow drawn for the object's map icon.

    This attribute is ignored if $Shadow is false.

    $ShadowColor for the current note can be set via the Appearance Inspector ▸ Shadow tab, 'Color' colour controls.

    ShadowDistance

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     number   [other number-type attributes]

     5

     Appearance   [other Appearance Group attributes]

     Map item shadow configuration

     No

     Yes

     No

     No

     v4.5.0

     Baseline

     As at baseline


    The numerical offset of the map icons drop-shadow (in pixels?).

    The allowed range of values is 0-100.

    This attribute is ignored if $Shadow is false.

    $ShadowDistance for the current note can be set via the Appearance Inspector ▸ Shadow tab, 'Distance' control.

    Shape

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     string   [other string-type attributes]

     (not set - empty string)

     Appearance   [other Appearance Group attributes]

     Map item general configuration

     No

     Yes

     No

     No

     v1.0.0

     Baseline

     As at baseline


    Stores the shape used to draw the note's icon in Map view.

    The value is normally set via the Shape sub-menu of the Note menu (which lists allowed values) though it can always be set directly via the attribute. The attribute default of [no value] equates to 'rectangle' in terms of the shape displayed in Map view.

    $Shape name values are case-sensitive.

    $Shape for the current note can be set via the Appearance Inspector ▸ Interior tab, 'Shape' control.

    ShowTitle

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     boolean   [other boolean-type attributes]

     false

     TextFormat   [other TextFormat Group attributes]

     Note text

     Yes

     No

     No

     No

     v1.0.0

     Baseline

     As at baseline


    Deprecated: retained for pre-v6 use only.

    Specifies pre-v6 whether the $DisplayName of the note is displayed at the top of note text windows.

    Now deprecated.

    Note: this attribute is unrelated to a later $HideTitle attribute used in v6+ for configuring map note icons.

    SiblingOrder

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     number   [other number-type attributes]

     (calculated)

     General   [other General Group attributes]

     Calculated data

     No

     No

     No

     Yes   [other intrinsic attributes]

     v3.0.0

     Baseline

     As at baseline


    Sequential sibling order number (1-based).

    The $SiblingOrder of the first child in a container is '1'. The $SiblingOrder of the next child is '2', and so on.

    The sibling order is effectively the $OutlineOrder but only (numbered) for the current container.

    The lowest number is drawn at the front in a map. If notes with sibling orders #1 and #5 overlap, part of #5 will be behind the icon for #1.

    The note menu command to move a note forward/backward or all the way to the back/front will alter both $OutlineOrder and $SiblingOrder for the affected note(s).

    Separators and adornments are included in sibling order. Note that some early versions of tinderbox, adornments used not to be included in sibling order.

    Regardless of $SiblingOrder values, in map view all adornments are drawn behind all notes/container/agents. It may be easier to think of the two sets of data as if being drawn on separate map overlays

    Aliases do not inherit this property from their original but have their own intrinsic value.

    $SiblingOrder is editable allowing actions to re-organise sibling items Previously it was read only). Of course, if a $Sort value is set for the container, the latter will re-organise any custom sibling ordering. To set first/last sibling:

    • First. Set to any number 1 or less and the note will become the eldest, i.e. first, sibling.
    • Last. Set to any number $ChildCount(parent) or greater and, the note will become the youngest, i.e. last, sibling.
    SimplenoteKey

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     string   [other string-type attributes]

     (not set - empty string)

     Watch   [other Watch Group attributes]

     Data synch

     No

     No

     No

     No

     v5.5.0

     Baseline

     As at baseline


    Used to support for Simplenote synchronisation.

    For synched notes this attribute holds the Simplenote UID for the note.

    This is legacy feature as support for Simplenote sync was discontinued from v8.8.0.

    SimplenoteModified

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     date   [other date-type attributes]

     (not set - never)

     Watch   [other Watch Group attributes]

     Data synch

     No

     No

     No

     No

     v5.5.0

     Baseline

     As at baseline


    Used to support Simplenote synchronisation.

    The attribute keeps track of the effective modification date according to the Simplenote server.

    This is legacy feature as support for Simplenote sync was discontinued from v8.8.0.

    SimplenoteSync

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     number   [other number-type attributes]

     (not set - 0)

     Watch   [other Watch Group attributes]

     Data synch

     No

     No

     No

     No

     v5.5.0

     Baseline

     As at baseline


    Used internally by Tinderbox and should not be altered by users.

    This is legacy feature as support for Simplenote sync was discontinued from v8.8.0.

    SimplenoteTags

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     set   [other set-type attributes]

     (not set - empty string)

     Watch   [other Watch Group attributes]

     Data synch

     No

     No

     No

     No

     v5.5.0

     Baseline

     As at baseline


    Holds the Simplenote [sic] tags associated with a Simplenote-synced note (i.e. one in the /Simplenote container).

    This is legacy feature as support for Simplenote sync was discontinued from v8.8.0.

    SimplenoteVersion

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     number   [other number-type attributes]

     (not set - 0)

     Watch   [other Watch Group attributes]

     Data synch

     No

     No

     No

     No

     v5.5.0

     Baseline

     As at baseline


    Used internally by Tinderbox and should not be altered by users.

    This is legacy feature as support for Simplenote sync was discontinued from v8.8.0.

    SmartQuotes

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     boolean   [other boolean-type attributes]

     true

     TextFormat   [other TextFormat Group attributes]

     Note text

     Yes

     Yes

     No

     No

     v6.0.0

     Baseline

     As at baseline


    Allow note-level setting of use of automatic smart quotes.

    Controls automatic setting (via the Apple Styled Text frameworks) of styling of 'smart quotes' and 'smart dashes'.

    This can also be set at document level via the Document Settings Text tab. As $SmartQuotes default inherits from the latter it allows for an easy document-wide toggle for the effect.

    $SmartQuotes can be set via the Text Inspector ▸ Text tab, 'Smart Quotes' tick-box control. It can also be set via Format menu ▸ Text ▸ Smart Quotes

    Sort

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     string   [other string-type attributes]

     (not set - empty string)

     Sorting   [other Sorting Group attributes]

     Sort configuration

     No

     Yes

     No

     No

     v1.0.0

     Baseline

     As at baseline


    Specifies the primary sorting order for notes within containers, agents and smart adornments.

    The order is based on the name of an existing system or user attribute. The name is cited without a $-prefix as this attribute stores the desired attribute's name, not its value:

    CORRECT: $Sort = "SomeAttribute" (case-sensitive)
    FAIL: $Sort = $SomeAttribute

    Default sorting uses lexical sort, i.e. A-Z precedes a-z, thus the sort order Aardvark, Boy, aardvark [sic], though this can be altered by $SortTransform which offers other choices of sort logic.

    A secondary sort is also allowed, such as where two notes have equal values under the main sort criterion. The secondary sort is set via $SortAlso.

    On the Action Inspector's Sort sub-tab, the list of available choices is shown in a $Sort pop-up menu in the upper set of controls

    If unsure of allowed attributes on which to sort, the best place to set a sort is via the note's naming panel (Enter key). If exposed via $DisplayedAttributes, the value pop-up will only show values already sorted on within the document.

    To reverse the sort order based on the given attribute, use $SortBackward.

    SortAlso

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     string   [other string-type attributes]

     (not set - empty string)

     Sorting   [other Sorting Group attributes]

     Sort configuration

     No

     Yes

     No

     No

     v1.0.0

     Baseline

     As at baseline


    Specifies the secondary sorting order for notes within containers, agents and smart adornments.

    The order is based on the name of an existing system or user attribute. The name is cited without a $-prefix as this attribute stores the desired attribute's name, not its value:

    CORRECT: $SortAlso = "SomeAttribute" (case-sensitive)
    FAIL: $SortAlso = $SomeAttribute

    In fact, the latter will work if the value $ SomeAttribute(this) is a valid attribute name.

    Default sorting uses lexical sort A-Z precedes a-z, thus the sort order Aardvark, Boy, aardvark [sic], though this can be altered by $SortAlsoTransform which offers other choices of sort logic.

    A secondary sort is useful where two notes have equal values under the main sort criterion. The primary sort is set via $Sort.

    On the Action Inspector's Sort sub-tab, the list of available choices is shown in a $Sort pop-up menu in the lower set of controls.

    If unsure of allowed attributes on which to sort, the best place to set a sort is via the note's naming panel (Enter key). If exposed via $DisplayedAttributes, the value pop-up will only show values already sorted on within the document.

    To reverse the sort order based on the given attribute, use $SortBackwardAlso.

    SortAlsoTransform

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     string   [other string-type attributes]

     case-sensitive

     Sorting   [other Sorting Group attributes]

     Sort configuration

     No

     Yes

     No

     No

     v3.5.0

     Baseline

     As at baseline


    Holds the sort transform value for secondary sorts of containers and agents.

    The primary sort transform is stored in $SortTransform.

    On the Action Inspector's Sort sub-tab, the list of available choices is shown in a Sort Transform pop-up menu.

    SortBackward

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     boolean   [other boolean-type attributes]

     false

     Sorting   [other Sorting Group attributes]

     Sort configuration

     No

     Yes

     No

     No

     v1.0.0

     Baseline

     As at baseline


    Specifies whether the sorting order for $Sort is backwards.

    If true the $Sort order is reversed.

    For example, Z → A instead of A → Z, etc.; thus the sort order aardvark, Boy, Aardvark [sic].

    $SortBackward can be set for the current note using the Action Inspector ▸ Sort tab, 'reverse' tick-box, for the upper set of controls.

    SortBackwardAlso

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     boolean   [other boolean-type attributes]

     false

     Sorting   [other Sorting Group attributes]

     Sort configuration

     No

     Yes

     No

     No

     v1.0.0

     Baseline

     As at baseline


    Specifies whether the sorting order for $SortAlso is backwards.

    If true the $SortAlso order is reversed.

    For example, Z → A instead of A → Z, etc.; thus the sort order aardvark, Boy, Aardvark [sic].

    $SortBackwardAlso can be set for the current note using the Action Inspector ▸ Sort tab, 'reverse' tick-box, for the lower set of controls.

    SortTransform

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     string   [other string-type attributes]

     case-sensitive

     Sorting   [other Sorting Group attributes]

     Sort configuration

     No

     Yes

     No

     No

     v3.5.0

     Baseline

     As at baseline


    Holds the sort transform value for sorts of containers and agents.

    The secondary sort transform is stored in $SortAlsoTransform.

    On the Action Inspector's Sort sub-tab, the list of available choices is shown in a Sort Transform pop-up menu.

    SourceCreated

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     date   [other date-type attributes]

     (not set - never)

     References   [other References Group attributes]

     Data synch

     No

     No

     No

     No

     v7.2.0

     Baseline

     As at baseline


    Used to hold creation date of DEVONthink imports.

    SourceModifed

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     date   [other date-type attributes]

     (not set - never)

     References   [other References Group attributes]

     Data synch

     No

     No

     No

     No

     v7.2.0

     Baseline

     As at baseline


    Used to hold the modification date of DEVONthink imports.

    SourceURL

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     URL   [other URL-type attributes]

     (not set - empty string)

     Watch   [other Watch Group attributes]

     Data synch

     No

     No

     No

     No

     v7.3.0

     Baseline

     As at baseline


    Holds the source URL (if any) of an imported DEVONthink item.

    See more on Tinderbox use with DEVONthink.

    Legacy:

    Originally, it held the source URL (if any) of an item imported via an Evernote watched folder.

    The watched Evernote object's data is defined in the watched folder's $EvernoteNotebook.

    StartDate

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     date   [other date-type attributes]

     (not set - never)

     Events   [other Events Group attributes]

     Timeline event configuration

     No

     No

     No

     No

     v5.0.0

     Baseline

     As at baseline


    A date attribute provided to facilitate organisation of tasks.

    See also $DueDate and $EndDate.

    For Timeline views, events with only $EndDate or an $EndDate before $StartDate will not plot correctly. If using an $EndDate, a $StartDate must be supplied. An alternate Date-type attribute to use can be supplied via $TimelineStartAttribute.

    State

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     string   [other string-type attributes]

     (not set - empty string)

     Places   [other Places Group attributes]

     Locational data

     No

     No

     No

     No

     v6.0.0

     Baseline

     As at baseline


    The State field of an address.

    The automatic geocoding tries to supply these fields automatically when looking up the supplied $Address.

    Sticky

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     boolean   [other boolean-type attributes]

     false

     Map   [other Map Group attributes]

     Map configuration

     No

     Yes

     No

     No

     v2.4.0

     Baseline

     As at baseline


    Controls whether moving an adornment also drags any notes wholly or partially on top of it.

    This attribute only affects adornments, setting it in other objects such as notes has no effect.

    If an adornment is sticky, objects (including other adornments, notes, agents, and containers) that overlap the adornment will move when the adornment is repositioned. This makes it much easier to work with moving sections of very large, complex maps.

    Note that, while moving a sticky adornment moves notes on top of it, items on a 'sticky' adornment can still be moved independently, either on the adornment or to move them off it. In the latter case the object is no longer 'stuck' to the adornment. Moving an item off a sticky adornment has no effect on the adornment itself.

    The icons used for $Sticky state can be customised.

    $Sticky can be (re-)set several ways:

    • Document Inspector ▸ More tab, 'Sticky' tick-box.
    • Clicking the push-pin item on a selected adornment. This icon is only displayed by adornment and only when selected. The default state is false (i.e. not ticked) in which state the pushpin is greyed-out. When the icon is clicked (or set via other means) the icon turns blue. The sticky icon is not seen if the adornment is part of a multiple selection.
    • Get Info ▸ attributes ▸ Map group: set $Sticky.
    • Set $Sticky via action code.
    Stripe

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     number   [other number-type attributes]

     0

     Map   [other Map Group attributes]

     Map item general configuration

     No

     No

     No

     No

     v9.7.3

     Baseline

     As at baseline


    Sets visibility and width of a map icon stripe decoration.

    Default value: 0 (no stripe).

    Stripes are drawn on the right edge of the note. A stripe can be shown for all values of $Shape, but makes most sense with the 'rectangular' or 'rounded' shapes.

    If $Stripe has no value, no stripe is drawn. Otherwise, the value set is the width of the coloured stripe in pixels.

    StripeColor

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     color   [other color-type attributes]

     (not set - coerced to #000000)

     Map   [other Map Group attributes]

     Map item general configuration

     No

     No

     No

     No

     v9.7.3

     Baseline

     As at baseline


    Sets the colour of a map icon stripe decoration.

    This can be used to set a custom colour for a note's stripe.

    Subtitle

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     string   [other string-type attributes]

     (not set - empty string)

     General   [other General Group attributes]

     Map item subtitle configuration

     No

     Yes

     No

     No

     v5.10.0

     Baseline

     As at baseline


    Holds the optional subtitle text that is displayed beneath the note title in map view.

    This subtitle, typically drawn in smaller type, provides means to give additional information about the note. The subtitle can be set or changed through the $Subtitle attribute.

    The subtitle may most easily be set in the Inspector's name pane or directly into the attribute via code or Info view. Subtitles may also be set or edited by clicking and holding an existing subtitle, or by clicking and holding beneath the note's name even if there is no current subtitle. The mechanism is the same as Edit-in-Place.

    Subtitles only appear in maps, and appear only if the note affords sufficient space. However, the subtitle is displayed on hover in outlines if the note has no Hover Expression (feature is currently withdrawn). In a map both $Subtitle and $HoverExpression can be displayed (assuming they both have a value).

    Other attributes allow fine tuning of the look of subtitles:

    $Subtitle can be set for the current note via the Text Inspector ▸ Subtitle tab, 'Subtitle' text box.

    SubtitleColor

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     color   [other color-type attributes]

     automatic

     Map   [other Map Group attributes]

     Map item subtitle configuration

     No

     Yes

     No

     No

     v5.10.0

     Baseline

     As at baseline


    Sets the colour of $Subtitle text.

    The default setting is automatic which is the same as the $NameColor default.

    $SubtitleColor can be set for the current note via the Text Inspector ▸ Subtitle tab, 'Color' colour controls.

    SubtitleOpacity

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     number   [other number-type attributes]

     0.5

     Map   [other Map Group attributes]

     Map item subtitle configuration

     No

     Yes

     No

     No

     v5.10.0

     Baseline

     As at baseline


    Controls the opacity with which the text of $Subtitle is drawn.

    The allowed range of values is 0–1. Prior to v9.7.0, the range was 0–100 but this was changed—see more.

    Both $TitleOpacity and $SubtitleOpacity are independent of $Opacity. However, the if higher than the value of $Opacity, the latter value is used when drawing the note.

    $Subtitle can be set for the current note via the Text Inspector ▸ Subtitle tab, 'Opacity' slider control.

    SubtitleSize

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     number   [other number-type attributes]

     75

     Map   [other Map Group attributes]

     Map item subtitle configuration

     No

     Yes

     No

     No

     v5.10.0

     Baseline

     As at baseline


    The size of $Subtitle text in Map view.

    The default is 75 (%).

    The number is a percentage of the text size of the $Name label.

    $SubtitleSize can be set for the current note via the Text Inspector ▸ Subtitle tab, 'Size' control.

    SullivanAngle

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     number   [other number-type attributes]

     0

     Sullivan   [other Sullivan Group attributes]

     

     No

     No

     No

     Yes   [other intrinsic attributes]

     v11.8.0

     11.8.0

     As at baseline


    Added in v11.8.0, for the Sullivan view which is not yet fully implemented/documented.

    SullivanData

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     dictionary   [other dictionary-type attributes]

     (not set - empty string)

     Sullivan   [other Sullivan Group attributes]

     

     No

     No

     No

     No

     v11.8.0

     11.8.0

     As at baseline


    Added in v11.8.0, for the Sullivan view which is not yet fully implemented/documented.

    SullivanElaboration

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     string   [other string-type attributes]

     (not set - empty string)

     Sullivan   [other Sullivan Group attributes]

     

     No

     No

     No

     No

     v11.8.0

     11.8.0

     As at baseline


    Added in v11.8.0, for the Sullivan view which is not yet fully implemented/documented.

    SullivanRadius

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     number   [other number-type attributes]

     10

     Sullivan   [other Sullivan Group attributes]

     

     No

     No

     No

     Yes   [other intrinsic attributes]

     v11.8.0

     11.8.0

     As at baseline


    Added in v11.8.0, for the Sullivan view which is not yet fully implemented/documented.

    SullivanShape

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     string   [other string-type attributes]

     (not set - empty string)

     Sullivan   [other Sullivan Group attributes]

     

     No

     No

     No

     No

     v11.8.0

     11.8.0

     As at baseline


    Added in v11.8.0, for the Sullivan view which is not yet fully implemented/documented.

    SullivanSymmetry

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     string   [other string-type attributes]

     (not set - empty string)

     Sullivan   [other Sullivan Group attributes]

     

     No

     No

     No

     No

     v11.8.0

     11.8.0

     As at baseline


    Added in v11.8.0, for the Sullivan view which is not yet fully implemented/documented.

    SyntaxHighlighting

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     string   [other string-type attributes]

     (not set - empty string)

     TextFormat   [other TextFormat Group attributes]

     Note text

     No

     No

     No

     No

     v9.0.0

     Baseline

     As at baseline


    Stores the note's desired highlighter type.

    TableAttributes

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     list   [other list-type attributes]

     (not set - empty string)

     Table   [other Table Group attributes]

     Table view configuration

     No

     No

     No

     No

     v9.7.0

     Baseline

     As at baseline


    A list of the note's table column source attributes.

    Default value is an empty string—no list.

    If $TableAttributes is empty and the Table view uses the container note's Displayed Attributes ($DisplayedAttributes) as columns. As Column #1 is always $Name, it is not stored So, list item #1 is for Table column #2.

    A Table view's column data is stored in $TableAttributes of the view's parent note.

    TableExpression

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     action   [other action-type attributes]

     (not set - empty string)

     Map   [other Map Group attributes]

     Expression code

     No

     Yes

     No

     No

     v4.5.0

     Baseline

     As at baseline


    Action code expression for display of summary displays in map container icons.

    TableFormat

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     dictionary   [other dictionary-type attributes]

     (not set - empty string)

     Table   [other Table Group attributes]

     Table view configuration

     No

     No

     No

     No

     v9.7.0

     Baseline

     As at baseline


    A dictionary of customisation to the current table.

    Customisations of a table are stored in the view's parent (container) note.

    See Table view configuration for details of the dictionary's content.

    TableHeading

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     string   [other string-type attributes]

     (not set - empty string)

     Map   [other Map Group attributes]

     Map item general configuration

     No

     Yes

     No

     No

     v4.5.0

     Baseline

     As at baseline


    Optional column headings for $TableExpression summary displays in containers.

    Columns should be separated by a "|". Thus:

     $TableHeading="Word Count|Value"

    would be used as heading for a list of $WordCount values.

    Tinderbox uses the pipe (|) character to parse out the individual column titles from the overall string. Remember that if using attribute names as column titles, you want to refer to the actual name and not a reference to it, so do not use a $-prefix.

    The data for such tables is specified via TableExpression.

    N.B. when entering such a value via Info view, do not include the enclosing quotes.

    $TableHeading can be set for the current container via the Summary Table Properties pop-over.

    TableHidden

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     boolean   [other boolean-type attributes]

     false

     Table   [other Table Group attributes]

     Table view configuration

     No

     No

     No

     Yes   [other intrinsic attributes]

     v9.7.0

     Baseline

     As at baseline


    Controls whether the note is included in a parent's Table view.

    The default is false, i.e. that child is shown in the table.

    Setting a value of true causes the Table view to not display that child and its data as a row in the table.

    Tabs

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     string   [other string-type attributes]

     0.25;0.25;0.25;0.25;

     TextFormat   [other TextFormat Group attributes]

     Note text

     No

     No

     No

     No

     v3.0.0

     Baseline

     As at baseline


    A semi-colon delimited list of intervals between tab stops, measured in inches.

    Tab stops are thus adjustable. For example, if $Tabs is

    1;3;0.5 

    …the first tab stop will be one inch from the left edge. The second tab stop will be three inches to the right of the first, four inches from the edge. The third tab stops will be placed at intervals of 0.5".

    Note that this is a simple form of setting tabs, inherited from the per-vapp re-design. The tabs set are the basic left-to-right form of tab. More advanced ruler settings like hanging indents must be set via the text pane ruler.

    Although stored in the form of a List, the attribute is String-type.

    In older files the default tabs settings may vary.

    Tab stops are measured from the left margin of the text.

    The document $Tabs value (i.e. as in the System Inspector) defines the tab stops for the document's default text paragraph style.

    Tags

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     set   [other set-type attributes]

     (not set - empty string)

     References   [other References Group attributes]

     General data

     No

     No

     No

     No

     v6.3.2

     Baseline

     As at baseline


    A set of free-form tags that you can use to describe note topics, context, or other useful attributes.

    When notes are copied/pasted to DEVONThink v2.8.8+, the $Tags values will be imported and applied as DevonThink tags.

    Telephone

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     string   [other string-type attributes]

     (not set - empty string)

     People   [other People Group attributes]

     Person detail

     No

     No

     No

     No

     v3.5.1

     Baseline

     As at baseline


    Intended for storing a person's phone number.

    Tinderbox extracts the first phone number found in the $Text and automatically stores it in $Telephone.

    Text

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     string   [other string-type attributes]

     (not set - empty string)

     Textual   [other Textual Group attributes]

     Note text

     No

     Yes

     No

     No

     v1.0.0

     Baseline

     As at baseline


    The text, i.e. body copy, of any note or other object.

    The word count of $Text is given by $WordCount and the character count of $Text is given by $TextLength.

    The contents of $Text can be altered both by typing into the $Text area of the text pane (with a note selected) or via action code methods. If using the latter method, novice users should be very careful about appending to $Text as repeating actions can unintentionally rapidly lead to very large amounts of data. Setting $Text via an action code results in new text using the $TextFont font.

    If a note is set to use $AutoFetch its $ReadOnly attribute is set to true, rendering the text un-editable (either turn off auto-fetch or alter $ReadOnly's value to edit $Text again).

    $Text for the current note can be set or edited via the $Text area of the Text tab of the Text pane.

    TextAlign

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     string   [other string-type attributes]

     (not set - empty string)

     TextFormat   [other TextFormat Group attributes]

     Note text

     Yes

     No

     No

     No

     v4.6.0

     Baseline

     As at baseline


    Deprecated: retained for pre-v6 use only.

    In pre-v6…

    Justification style for $Text display on map icons.

    The underlying default value is an empty string. The Text Preferences default is left and thus the inherited default. Values allowed: "left", "center", "right".

    This alignment is also reflected in note text displayed in map note icons.

    TextBackgroundColor

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     color   [other color-type attributes]

     #ffffff

     TextFormat   [other TextFormat Group attributes]

     Note text

     Yes

     No

     No

     No

     v1.0.0

     Baseline

     As at baseline


    Background colour for $Text displayed in map icons.

    The attribute default is not set but inherits #ffffff (white) from the Preferences Text pane's Background colour option.

    TextCheckboxes

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     list   [other list-type attributes]

     (not set - empty string)

     Textual   [other Textual Group attributes]

     General data

     No

     No

     No

     No

     v10.0.0

     Baseline

     As at baseline


    Records the state of each checkbox in a note.

    The Nth element is true if the Nth in-text checkbox is checked, and false otherwise. The count of items in $TextCheckboxes updates to reflect the number of current checkboxes in a note's text.

    TextColor

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     color   [other color-type attributes]

     #000000

     TextFormat   [other TextFormat Group attributes]

     Note text

     Yes

     Yes

     No

     No

     v1.0.0

     Baseline

     As at baseline


    Default display colour of $Text.

    This colour may be modified by further text editing; it is the 'default' colour for new text in that note.

    IMPORTANT: Changes to this attribute affect only those notes with no current $Text. Once anything has been added to $Text, inheritance is broken. Thereafter $Text uses the relevant attribute settings as at the time the text was added; they are effectively 'baked' into the $Text. The only way to 'reset' text with the wrong $TextColor value is to select the text and apply plain text formatting (Style menu). WARNING: setting plain text resets all $Text styling attributes. Is is not possible to 'reset' only font but not colour, text size, bolding, etc., as might be otherwise intuited.

    A color-type attribute. The attribute default is not set but inherits #000000 (black) from the Document Settings' Text pane's Text color option.

    $TextColor for the selected note can be set via the Text Inspector ▸ Text tab, 'Color' colour controls.

    TextColorBlue

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     color   [other color-type attributes]

     bright blue

     TextFormat   [other TextFormat Group attributes]

     Note text

     No

     No

     No

     No

     v9.1.0

     Baseline

     As at baseline


    Controls the exact colour applied via Format ▸ Style ▸ Blue.

    Changing this attributes does not change text colours previously applied, but affects future applications of this style.

    TextColorGray

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     color   [other color-type attributes]

     warm gray

     TextFormat   [other TextFormat Group attributes]

     Note text

     No

     No

     No

     No

     v9.1.0

     Baseline

     As at baseline


    Controls the exact colour applied via Format ▸ Style ▸ Gray.

    Changing this attributes does not change text colours previously applied, but affects future applications of this style.

    TextColorGreen

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     color   [other color-type attributes]

     bright green

     TextFormat   [other TextFormat Group attributes]

     Note text

     No

     No

     No

     No

     v9.1.0

     Baseline

     As at baseline


    the exact colour applied via Format ▸ Style ▸ Green.

    Changing this attributes does not change text colours previously applied, but affects future applications of this style.

    TextColorRed

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     color   [other color-type attributes]

     bright red

     TextFormat   [other TextFormat Group attributes]

     Note text

     No

     No

     No

     No

     v9.1.0

     Baseline

     As at baseline


    the exact colour applied via Format ▸ Style ▸ Red.

    Changing this attributes does not change text colours previously applied, but affects future applications of this style.

    TextExportTemplate

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     string   [other string-type attributes]

     (not set - empty file string)

     Textual   [other Textual Group attributes]

     Text export file configuration

     Yes

     No

     No

     No

     v1.0.0

     Baseline

     As at baseline


    Deprecated: retained for pre-v6 use only.

    Specifies the name of the template to be used for text export (as opposed to HTML export).

    TextFont

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     font   [other font-type attributes]

     MercurySSm-Book

     TextFormat   [other TextFormat Group attributes]

     Note text

     Yes

     Yes

     No

     No

     v1.0.0

     Baseline

     As at baseline


    Default display font for new notes

    The default value is inherited from Preferences, Text, Font. The default is MercurySSm-Book (at 16pt).

    This attribute allows a class of notes (e.g. via a prototype) to inherit a specific body text font via a prototype.

    $TextFont is easily overridden simply by selecting a font from the Font palette.

    IMPORTANT: Changes to this attribute affect only those notes with no current $Text. Once anything has been added to $Text, inheritance is broken. Thereafter $Text uses the relevant attribute settings as at the time the text was added; they are effectively 'baked' into the $Text. The only way to 'reset' text with the wrong $TextFont value is to select the text and apply plain text formatting (Style menu). WARNING: setting plain text resets all $Text styling attributes. It is not possible to 'reset' only font but not colour, text size, bolding, etc., as might be otherwise intuited.

    $TextFont is used for any Text set via an action or rule.

    The $TextFont for the current note—or $Text selection therein, can be set using Format menu ▸ Font menu ▸ Show Fonts and using the OS Fonts palette to select the desired font name/face/size.

    TextFontSize

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     number   [other number-type attributes]

     16

     TextFormat   [other TextFormat Group attributes]

     Note text

     Yes

     Yes

     No

     No

     v4.0.0

     Baseline

     As at baseline


    Sets the default text font size for new notes.

    The, in points, value is inherited from Document settings, Text font.

    This attribute allows a set of notes (e.g. Code Examples or Shopping List) to inherit a specific body text font size via a prototype.

    $TextFontSize is easily overridden simply by selecting a font size from the Font palette.

    IMPORTANT: Changes to this attribute affect only those notes with no current $Text. Once anything has been added to $Text, inheritance is broken. Thereafter $Text uses the relevant attribute settings as at the time the text was added; they are effectively 'baked' into the $Text. The only way to 'reset' text with the wrong $TextFontSize value is to select the text and use menu Format ▸ Style ▸ Standard Size.

    The $TextFontSize for the current note - or $Text selection therein, can be set using Format menu ▸ Font menu ▸ Show Fonts and using the OS Fonts palette to select the desired font size.

    TextHighlightBlue

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     color   [other color-type attributes]

     #3399FF

     TextFormat   [other TextFormat Group attributes]

     Note text

     No

     No

     No

     No

     v9.1.0

     Baseline

     As at baseline


    The colour applied by Format ▸ Style ▸ Highlight ▸ blue highlight.

    Changing this attribute does not change any text highlights previously applied, but only affects future applications of this style.

    TextHighlightGreen

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     color   [other color-type attributes]

     #33FF66

     TextFormat   [other TextFormat Group attributes]

     Note text

     No

     No

     No

     No

     v9.1.0

     Baseline

     As at baseline


    The colour applied by Format ▸ Style ▸ Highlight ▸ green highlight.

    Changing this attribute does not change any text highlights previously applied, but only affects future applications of this style.

    TextHighlightMagenta

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     color   [other color-type attributes]

     #ff66ff

     TextFormat   [other TextFormat Group attributes]

     Note text

     No

     No

     No

     No

     v9.1.0

     Baseline

     As at baseline


    The colour applied by Format ▸ Style ▸ Highlight ▸ magenta highlight.

    Changing this attribute does not change any text highlights previously applied, but only affects future applications of this style.

    TextHighlightRed

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     color   [other color-type attributes]

     #FF5533

     TextFormat   [other TextFormat Group attributes]

     Note text

     No

     No

     No

     No

     v9.1.0

     Baseline

     As at baseline


    Format ▸ Style ▸ Highlight ▸ red highlight.

    Changing this attribute does not change any text highlights previously applied, but only affects future applications of this style.

    TextHighlightYellow

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     color   [other color-type attributes]

     #ffff00

     TextFormat   [other TextFormat Group attributes]

     Note text

     No

     No

     No

     No

     v9.1.0

     Baseline

     As at baseline


    Format ▸ Style ▸ Highlight ▸ yellow highlight.

    Changing this attribute does not change any text highlights previously applied, but only affects future applications of this style.

    TextHTML

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     string   [other string-type attributes]

     (calculated)

     Textual   [other Textual Group attributes]

     HTML export encoding

     No

     No

     No

     No

     v11.7.0

     11.7.0

     As at baseline


    The note's styled text converted to an HTML code fragment.

    Default: empty string.

    The attribute is read-only, as the content is created on-the-fly and not permanently stored (to avoid multiple stored copies of $Text.

    This returns any supported export styling in $Text converted to HTML tags. Thus, italicised passages in the text appear between tags.

    This is akin to ^text^ output but inline export code in $Text is not evaluated.

    TextLength

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     number   [other number-type attributes]

     (calculated)

     Textual   [other Textual Group attributes]

     Calculated data

     No

     No

     Yes   [other read-only attributes]

     No

     v1.0.0

     Baseline

     As at baseline


    The number of characters (character count) of the current note (read-only).

    See also $WordCount for a count of discrete words in the note's text.

    More detail on how character counts are made.

    TextLinkCount

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     number   [other number-type attributes]

     (calculated)

     General   [other General Group attributes]

     Calculated data

     No

     No

     Yes   [other read-only attributes]

     Yes   [other intrinsic attributes]

     v5.12.1

     Baseline

     As at baseline


    Holds the number of outbound text links (i.e. within $Text).

    The value is (internal) text links plus (external) web links. Thus if you need the count of only text-type links, use action code like $TextInternalLinkCount = $TextLinkCount-$WebLinkCount. Thus, if a note has two text links and one web link, the note's $TextLinkCount value would be 3 but user attribute $TextInternalLinkCount would have a value of 2.

    Also see $PlainLinkCount, $WebLinkCount, $OutboundLinkCount.

    TextMarkdown

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     string   [other string-type attributes]

     (calculated)

     Textual   [other Textual Group attributes]

     HTML export encoding

     No

     No

     No

     No

     v11.7.0

     11.7.0

     As at baseline


    The note's styled text converted to Markdown format.

    Default: empty string.

    The attribute is read-only, as the content is created on-the-fly and not permanently stored (to avoid multiple stored copies of $Text.

    This returns any supported export styling in $Text converted to standard Markdown markup. Thus, italicised passages in the text appear between underscores.

    TextPaneRatio

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     number   [other number-type attributes]

     0.5

     TextFormat   [other TextFormat Group attributes]

     General data

     No

     No

     No

     No

     v6.0.0

     Baseline

     As at baseline


    Deprecated: unused retained for v6 use only.

    Custom ratio of view pane to text pane for the current note.

    Default value is 0.5, i.e. 50% split. Value range is 0-100.

    If a custom $TextPaneWidth is set, the latter overrides this setting.

    Currently, the splitter pane location is stored in the per-tab XML metadata of the document window, and is not exposed via an attribute.

    TextPaneWidth

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     number   [other number-type attributes]

     -1

     TextFormat   [other TextFormat Group attributes]

     General data

     No

     No

     No

     No

     v6.0.0

     Baseline

     As at baseline


    Deprecated: unused retained for v6 use only.

    Stores a custom width for the note's text pane.

    A value of -1 leaves the text pane unmoved, and inheriting the split set/inherited via $TextPaneRatio. Dragging the document window's vertical splitter pane automatically sets $TextPaneWidth.

    The splitter pane location is stored in the per-tab XML metadata of the document window, and is not exposed via an attribute.

    TextSidebar

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     boolean   [other boolean-type attributes]

     true

     TextFormat   [other TextFormat Group attributes]

     Note text

     Yes

     No

     No

     No

     v3.5.0

     Baseline

     As at baseline


    Deprecated: retained for pre-v6 use only.

    Stores the pre-v6 display state (shown/hidden) of a note's text window sidebar. In the current application, the old sidebar is replaced by the displayed attributes table, and this attribute's feature is replaced by $HideDisplayedAttributes.

    TextWindowHeight

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     number   [other number-type attributes]

     250

     TextFormat   [other TextFormat Group attributes]

     Note window configuration

     No

     No

     No

     No

     v7.5.0

     Baseline

     As at baseline


    Last-used height of note's stand-alone window.

    Resizing the note's text window automatically sets this attribute, so that the text window for each note remembers its last-used height. The new value is saved when the window is closed or document is closed with the text window still open.

    TextWindowWidth

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     number   [other number-type attributes]

     475

     TextFormat   [other TextFormat Group attributes]

     Note window configuration

     No

     No

     No

     No

     v7.5.0

     Baseline

     As at baseline


    Last-used width of note's stand-alone window.

    Resizing the note's text window automatically sets this attribute, so that the text window for each note remembers its last-used width. The new value is saved when the window is closed or document is closed with the text window still open.

    TimelineAliases

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     boolean   [other boolean-type attributes]

     true

     Events   [other Events Group attributes]

     Timeline configuration

     No

     Yes

     No

     No

     v6.0.0

     Baseline

     As at baseline


    Control plotting of in-scope aliases in the timeline.

    Default is true, in which case in-scope aliases are included in the timeline.

    $TimelineAliases for the current timeline (tab) view can be set via the Timeline Settings pop-over, 'Alaises' tick-box.

    TimelineBand

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     number   [other number-type attributes]

     0

     Events   [other Events Group attributes]

     Timeline event configuration

     No

     No

     No

     Yes   [other intrinsic attributes]

     v5.6.0

     Baseline

     As at baseline


    Assigns an event to a specific vertical band in Timeline view.

    By default all events are in band 0, but can be set to another band by drag-drop or via action code.

    Although the attribute accepts any number, the valid range is whole numbers 0–1300. 1300 is not a hard limit and that many bands should not be needed, but above that number timeline band labels are clipped or not drawn at all.

    This attribute is intrinsic for aliases, allowing aliases to be paced in a different timeline band to their original.

    TimelineBandLabelColor

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     color   [other color-type attributes]

     black

     Events   [other Events Group attributes]

     Timeline configuration

     No

     Yes

     No

     No

     v5.10.1

     Baseline

     As at baseline


    Holds the colour used to draw band labels in a timeline.

    When set locally it applies to the current container's Timeline view.

    $TimelineBandLabelColor for the current timeline (tab) view can be set via the Timeline Settings pop-over, 'Label Color' colour controls.

    TimelineBandLabelOpacity

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     number   [other number-type attributes]

     0.25

     Events   [other Events Group attributes]

     Timeline configuration

     No

     Yes

     No

     No

     v5.10.1

     Baseline

     As at baseline


    Stores an opacity value for drawing band labels in the current container's Timeline view.

    The allowed range of values is 0–1. Prior to v9.7.0, the range was 0–100 but this was changed—see more.

    $Timeline for the current timeline (tab) view can be set via the Timeline Settings pop-over, '' control.

    TimelineBandLabels

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     list   [other list-type attributes]

     (not set - empty string)

     Events   [other Events Group attributes]

     Timeline configuration

     No

     Yes

     No

     No

     v5.6.0

     Baseline

     As at baseline


    Holds the assigned labels for different Timeline view bands and is a semicolon-delimited string.

    For example, the string "Paris;London;Madrid" would label three bands, "Paris", "London", and "Madrid". Labels are drawn onto the timeline in the order stored; in the example band number 0 will be labelled "Paris".

    $TimelineBandLabels for the current timeline (tab) view can be set via the Timeline Settings pop-over, 'Labels' input box.

    TimelineColor

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     color   [other color-type attributes]

     lighter warm gray

     Events   [other Events Group attributes]

     Timeline configuration

     No

     Yes

     No

     No

     v5.6.0

     Baseline

     As at baseline


    Used to colour every other (even-numbered) timeline band within a Timeline view.

    A desaturated tint of the colour, rather than the exact colour name/value specified, is used to avoid undue contrast.

    $TimelineColor for the current timeline (tab) view can be set via the Timeline Settings pop-over, 'Band Color' colour controls.

    TimelineDescendants

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     boolean   [other boolean-type attributes]

     true

     Events   [other Events Group attributes]

     Timeline configuration

     No

     Yes

     No

     No

     v6.0.0

     Baseline

     As at baseline


    Control scope to direct children in the timeline.

    Default is true, which results in all descendants being plotted.

    $TimelineDescendants for the current timeline (tab) view can be set via the Timeline Settings pop-over, 'Descendants' tick-box.

    TimelineEnd

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     date   [other date-type attributes]

     (not set - never)

     Events   [other Events Group attributes]

     Timeline configuration

     No

     Yes

     No

     No

     v5.6.0

     Baseline

     As at baseline


    Optional end date for container's Timeline.

    Notes with a $EndDate later than this are listed in the "Out of Range" section of the view. By default, this attribute is not set.

    The setting works at container level, thus different containers can have different plotted date ranges.

    $Timeline for the current timeline (tab) view can be set via the Timeline Settings pop-over, 'End' date input box.

    TimelineEndAttribute

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     string   [other string-type attributes]

     (not set - empty string)

     Events   [other Events Group attributes]

     Timeline configuration

     No

     Yes

     No

     No

     v6.0.0

     Baseline

     As at baseline


    Alternative Date-type attribute of Timeline's event $EndDate.

    Use the attribute name, without a $-prefix.

    $TimelineEndAttribute for the current timeline (tab) view can be set via the Timeline Settings pop-over, 'Attributes: End' pop-up control.

    TimelineGridColor

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     color   [other color-type attributes]

     #009090

     Events   [other Events Group attributes]

     Timeline configuration

     No

     No

     No

     No

     v5.6.0

     Baseline

     As at baseline


    Colour of timeline vertical guidelines for selected note in Timeline view.

    TimelineMarker

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     boolean   [other boolean-type attributes]

     false

     Events   [other Events Group attributes]

     Timeline configuration

     No

     No

     No

     No

     v5.6.0

     Baseline

     As at baseline


    Draw persistent note vertical markers in Timeline view.

    Controls whether marker lines, in a tint of $AccentColor, are drawn from events to the Timeline view's scale persist when a note is not currently selected.

    The marker lines are drawn from the left edge of events. The default is false, with lines only shown for selected items.

    TimelineScaleColor

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     color   [other color-type attributes]

     cool gray

     Events   [other Events Group attributes]

     Timeline configuration

     No

     Yes

     No

     No

     v5.6.0

     Baseline

     As at baseline


    Primary colour in the gradient used for time scale of Timeline view.

    The default is 'cool gray'. The scale uses a gradient to fade to $TimelineScaleColor2.

    $TimelineScaleColor for the current timeline (tab) view can be set via the Timeline Settings pop-over, 'Scale Color' colour controls.

    TimelineScaleColor2

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     color   [other color-type attributes]

     inherits from $MapBackgroundAccentColor

     Events   [other Events Group attributes]

     Timeline configuration

     No

     No

     No

     No

     v5.6.0

     Baseline

     As at baseline


    Primary colour in the gradient used for time scale of Timeline view.

    The default is inherited from the note's $MapBackgroundAccentColor (which is in turn inherited from the Map Preference for background colour) which results in 'gray'. The scale uses a gradient to fade from $TimelineScaleColor. The default means the top edge of the scale bar is the same as the background of the main content portion of the map.

    TimelineStart

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     date   [other date-type attributes]

     (not set - never)

     Events   [other Events Group attributes]

     Timeline configuration

     No

     Yes

     No

     No

     v5.6.0

     Baseline

     As at baseline


    Optional start date for container's Timeline.

    Notes with a $StartDate earlier than this are listed in the "out of Range" section of the view.

    By default, this attribute is not set.

    The setting works at container level, thus different containers can have different plotted date ranges.

    $TimelineStart for the current timeline (tab) view can be set via the Timeline Settings pop-over, 'Start' date input box.

    TimelineStartAttribute

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     string   [other string-type attributes]

     (not set - empty string)

     Events   [other Events Group attributes]

     Timeline configuration

     No

     Yes

     No

     No

     v6.0.0

     Baseline

     As at baseline


    Alternative Date-type attribute of Timeline's event $StartDate.

    Use the attribute name, without a $-prefix.

    $TimelineStartAttribute for the current timeline (tab) view can be set via the Timeline Settings pop-over, 'Attributes: Start' pop-up control.

    Tip

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     number   [other number-type attributes]

     0.5

     Map   [other Map Group attributes]

     Map item general configuration

     No

     Yes

     No

     No

     v6.0.0

     Baseline

     As at baseline


    Controls the shape of arrow and leaf shapes.

    The valid range is 0–1.

    Replaces the deprecated $LeafTip.

    For notes whose $Shape employs this setting, the $Tip value for the selected note can be altered using the grey dot control to the bottom of the note, in an up-down direction.

    TitleBackgroundColor

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     color   [other color-type attributes]

     #000000

     TextFormat   [other TextFormat Group attributes]

     Note title

     Yes

     No

     No

     No

     v1.0.0

     Baseline

     As at baseline


    Deprecated: retained for pre-v6 use only.

    Specifies the background colour for the title pane in text windows (not used in v6+).

    TitleFont

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     font   [other font-type attributes]

     LucidaGrande

     TextFormat   [other TextFormat Group attributes]

     Note title

     Yes

     No

     No

     No

     v1.0.0

     Baseline

     As at baseline


    Deprecated: retained for pre-v6 use only.

    Specifies the name of the font used for displaying the current note's title in the title pane of the note's text window (ignored in v6+).

    TitleForegroundColor

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     color   [other color-type attributes]

     #ffffff

     TextFormat   [other TextFormat Group attributes]

     Note title

     Yes

     No

     No

     No

     v1.0.0

     Baseline

     As at baseline


    Deprecated: retained for pre-v6 use only.

    Specifies the foreground colour for the title pane in text windows (not used in v6+).

    TitleHeight

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     number   [other number-type attributes]

     0

     Map   [other Map Group attributes]

     Map item text configuration

     No

     No

     No

     No

     v4.5.0

     Baseline

     As at baseline


    Sets height of the title bar in a map container/agent map icon, in map units.

    $TitleHeight is only used by agents and container notes and ignored by other objects. It is expressed in relative map units, as for $Height and $Width.

    For a (selected) container, a note or agent, a splitter resize mouse icon is shown when the mouse is over the boundary of the title area and the map viewport; click and drag (hand icon) the mouse up or down to alter the height of the title area.

    The default value of 0 (or a set value of 0) allows the icon to use Tinderbox's normal auto-resizing where the title area grows as the overall icon area does.

    If $TitleHeight is set to other than zero, then resizing the overall size of the container has no effect on the height of the title area.

    To 'hide' the viewport area of a container, set the $TitleHeight to equal $Height. This makes the map icon look like a normal note except the two bottom corners (note) or top corners (agent) are rounded. While the viewport is hidden, it is not possible to double-click drill down but its shortcut (Cmd+Opt+Return) will work.

    TitleOpacity

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     number   [other number-type attributes]

     1

     Map   [other Map Group attributes]

     Map item text configuration

     No

     No

     No

     No

     v5.10.0

     Baseline

     As at baseline


    Deprecated: controls the opacity used when drawing the $Name onto a map icon.

    The default is 1, totally opaque.

    The allowed range of values is 0–1. Prior to v9.7.0, the range was 0–100 but this was changed—see more.

    $TitleOpacity is now deprecated in favour of $NameOpacity.

    Both $TitleOpacity and $SubtitleOpacity are independent of $Opacity. However, the if higher than the value of $Opacity, the latter value is used when drawing the note.

    Tot

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     set   [other set-type attributes]

     (not set - empty string)

     Watch   [other Watch Group attributes]

     Data synch

     No

     No

     No

     No

     v8.6.0

     Baseline

     As at baseline


    A Set indicating which Tot notes are watched.

    The default value is an empty string.

    Twitter

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     string   [other string-type attributes]

     (not set - empty string)

     People   [other People Group attributes]

     Person detail

     No

     No

     No

     No

     v5.0.0

     Baseline

     As at baseline


    Holds a person's Twitter account name.

    UpdateTextLinksAfterRename

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     boolean   [other boolean-type attributes]

     true

     Textual   [other Textual Group attributes]

     Data synch

     No

     No

     No

     No

     v8.9.0

     Baseline

     As at baseline


    Optionally disable automatic update to text link anchors edits.

    Default: true

    After a note is renamed, the app automatically updates text links if (a) the text link's destination is the renamed note, and (b) the text link's anchor text is the old name of the renamed note. Though this is often the desired behaviour, but may in some instances not be desirable.

    Thus, an option to disable automatic renaming is available in Document Settings: Text: Update after renaming. But automatic renaming may also be disabled by setting this attribute.

    In large, well-linked document that do not use note titles as link anchor text, this option is of less use as it is essentially unneeded so nugatory background work for Tinderbox to be doing.

    URL

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     URL   [other URL-type attributes]

     (not set - empty string)

     Net   [other Net Group attributes]

     Import configuration

     No

     No

     No

     No

     v1.0.0

     Baseline

     As at baseline


    URL to be called if the current notes fetches its text content from the web.

    As well as 'http' URLs, 'mailto' addresses and other such protocols can be used, including pseudo protocols used by some desktop app. The $ViewInBrowser attribute controls whether the fetched content is shown in the note or in a web browser window.

    If using a local path to a file, e.g. to enable AutoFetch use, you must use the file:// protocol rather than a bare file path.

    Prior to v5 this was a string data type attribute.

    UUID

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     string   [other string-type attributes]

     (not set - empty string)

     Watch   [other Watch Group attributes]

     Data synch

     No

     No

     No

     No

     v7.3.0

     Baseline

     As at baseline


    Unique ID of a DEVONThink item imported via a DEVONThink watched folder.

    ViewInBrowser

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     boolean   [other boolean-type attributes]

     false

     Net   [other Net Group attributes]

     Import configuration

     No

     No

     No

     No

     v1.0.0

     Baseline

     As at baseline


    Opening the note also opens the note's $URL in a web browser.

    If true, and if $URL is a valid network or file URL, then Tinderbox will automatically open that URL when the note is selected.

    Visits

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     number   [other number-type attributes]

     (not set - 0)

     Storyspace   [other Storyspace Group attributes]

     Storyspace compatibility

     No

     No

     No

     No

     v6.3.1

     Baseline

     As at baseline


    In Storyspace, the number of times the reader has visited this note.

    One story method is to ensure a writing space has been visited at least N before some outcomes (new links) are enabled).

    Volume

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     string   [other string-type attributes]

     (not set - empty string)

     References   [other References Group attributes]

     Data synch

     No

     No

     No

     No

     v5.11.0

     Baseline

     As at baseline


    Used for Bookends reference import. Maps to RIS data tag 'VL'.

    WatchFolder

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     file   [other file-type attributes]

     (not set - empty file string)

     Watch   [other Watch Group attributes]

     Data synch

     No

     No

     No

     No

     v7.3.0

     Baseline

     As at baseline


    The local file path to a Finder watched folder.

    WebLinkCount

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     number   [other number-type attributes]

     (calculated)

     General   [other General Group attributes]

     Calculated data

     No

     No

     Yes   [other read-only attributes]

     Yes   [other intrinsic attributes]

     v3.5.0

     Baseline

     As at baseline


    Holds the number of outbound links originating from the current note (read-only).

    Formerly, these were lumped into $OutboundLinkCount.

    Also see $TextLinkCount, $PlainLinkCount.

    WeblogPostID

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     string   [other string-type attributes]

     (not set - empty string)

     Weblog   [other Weblog Group attributes]

     Weblog configuration

     No

     No

     No

     No

     v1.0.0

     Baseline

     As at baseline


    Deprecated: retained for pre-v6 use only.

    Specifies the ID for weblog APIs such as MovableType, Blogger and Radio Userland.

    Width

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     number   [other number-type attributes]

     4

     Map   [other Map Group attributes]

     Map item general configuration

     No

     No

     No

     Yes   [other intrinsic attributes]

     v1.0.0

     Baseline

     As at baseline


    The width of a note icon in the Map view, in map units.

    See also $Height.

    Aliases do not inherit this property from their original but have their own value.

    The default value is 4, previously it was 3.

    WordCount

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     number   [other number-type attributes]

     (calculated)

     Textual   [other Textual Group attributes]

     Calculated data

     No

     No

     Yes   [other read-only attributes]

     No

     v1.0.0

     Baseline

     As at baseline


    The number of discrete words in the current note's $Text (read-only).

    See $TextLength for the total character count).

    $WordCount is not language aware. Essentially it is tuned for the heuristics of English language. Therefore it may not work well with languages that use word-spacing conventions drastically unlike English.

    For those needing a word count in a non-English language/script/locale, one approach is to consider String.split(regex), populating the regex with word break characters that may differ from English. Note, in this context punctuation doesn't matter only the alternatives to spaces/non-breaking spaces that a given language may use.

    Word count is as much science as art. For instance, is 'UNESCO' one word, six words—or seven if you include the 'and' omitted from the acronym. Within a single country or a single language tradition there may be consensus on such points but it may not hold true more widely.

    However, for English text, $WordCount should be considered accurate.

    $WordCount has been given improved behaviour for Chinese and several other languages. Word count, even in English still remains something of an art. For some languages, such as Chinese, $TextLength—the character count of $Text—may be more useful, if only one type of (language) script is being used in the note. The word count for mixed-script text is always likely to have some inaccuracy as language typing to sub-string level, e.g. discrete parts of $Text, does not occur.

    If $WordCount is a displayed attribute, editing the text pane periodically updates the displayed word count

    Legacy note

    In very early versions the attribute name was 'Wordcount' and the program allows either spelling. However, the old version is deprecated.

    Xg

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     number   [other number-type attributes]

     0

     Gaudi   [other Gaudi Group attributes]

     Gaudi view configuration

     No

     No

     No

     Yes   [other intrinsic attributes]

     v10.0.0

     Baseline

     As at baseline


    Holds X-axis position in Gaudi view.

    This represents a fraction of the Gaudí view's width, and approximates to the centre of the plotted note.

    The default value is 0 (zero).

    Xpos

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     number   [other number-type attributes]

     0

     Map   [other Map Group attributes]

     Map configuration

     No

     No

     No

     Yes   [other intrinsic attributes]

     v1.0.0

     Baseline

     As at baseline


    Note's X-axis map co-ordinates (in map units).

    $Xpos = 0 is the middle of the X-axis of the map, with negative values moving left, positive values moving right. See Map Co-ordinates.

    See also $Ypos.

    Aliases do not inherit this property from their original but have their own value.

    Yg

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     number   [other number-type attributes]

     0

     Gaudi   [other Gaudi Group attributes]

     Gaudi view configuration

     No

     No

     No

     Yes   [other intrinsic attributes]

     v10.0.0

     Baseline

     As at baseline


    Holds Y-axis position in Gaudi view.

    This represents a fraction of the Gaudí view's height, and approximates to the centre of the plotted note.

    The default value is 0 (zero).

    Ypos

    Attribute Data Type: 

    Attribute Default Value: 

    Attribute Group: 

    Attribute Purpose: 

    Attribute Inherited from Preferences:   

    Attribute UI-configurable: 

    Attribute Read-Only: 

    Attribute Intrinsic: 

    Attribute First Added: 

    Attribute in Current Baseline: 

    Attribute Altered Since Baseline: 

     number   [other number-type attributes]

     0

     Map   [other Map Group attributes]

     Map configuration

     No

     No

     No

     Yes   [other intrinsic attributes]

     v1.0.0

     Baseline

     As at baseline


    Note's Y-axis map co-ordinates (in map units).

    $Ypos = 0 is the middle of the Y-axis of the map, with negative values moving up [sic], positive values moving down. Note the Y-axis value orientation is the reverse of normal Cartesian Y co-ordinates, but does makes sense in the context of a visual top-left-to-bottom-right visual layout. See Map Co-ordinates.

    See also $Xpos.

    Aliases do not inherit this property from their original but have their own value.

    System Attribute Groups within Tinderbox

    A Tinderbox documents's pre-defined System Attributes are organised in various groups; being pre-defined, they are always available from outset in a new TBX document. The groupings have grown unequally over time, but broadly they describe attributes with a common context or purpose:

    One further group is hidden in the UI but visible in the documents source XML:

    Agent Attributes

    These store data related to Agent function: the query string, action code, etc.

    AI Attributes

    These store data related to the Artificial Intelligence (AI) and Neural-Linguistic Programming (NLP) function: the query string, action code, etc.

    Composites Attributes

    These store data related to a note functioning as a composite in Map (and some other views).

    Grid Attributes

    Settings to customise map view adornment grids.

    Gaudi Attributes

    Settings to customise map view adornment grids.

    Internal Attributes (4)

    The 'Internal' group of attributes is hidden from the user and is only encountered if working with the XML source of a saved TBX file. This group cannot be accessed via the UI, such as via the documents Inspector/System tab. Do note attempt to export or use action script on these items. The group is comprised of following known attributes:

    • $Alias. Unsigned type (only used by this attribute). The Alias is used by aliases only and holds $ID of the alias' original note.
    • $EntryScript. String type. Purpose undocumented. At some point the app may have allowed action code to be run at doc open/close and the attribute may be for this (legacy support?).
    • $ExitScript. String type. Purpose undocumented. See the previous bullet.
    • $WindowPlace. [Unknown] type. Purpose undocumented, but may be used to seed values for individual window position/state stored in the TBX.

    The purpose of the other attributes is unknown.

    Iris Attributes

    Experimental attributes. Not currently used. Ignore.

    InformationCity Attributes

    These attributes store data related to configuring notes' appearance in the experimental Information city view.

    Net Attributes

    For data derived from the Net, e.g. RSS, notes drawing content from web pages, etc.

    People Attributes

    This group offers a series of attributes to support the storage of information about people.

    If an existing document already uses these names as user attributes, the attributes will be moved from the User attribute pane to the People group of System attributes.

    Some items were moved to the new Places group in v8.0.4.

    Places Attributes

    This group offers a series of attributes related to geographical location data in notes. Previously, these attributes were in the People group:

    Poster Attributes

    This group offers a series of attributes to support the storage of information about use of posters.

    Sandbox Attributes

    This contains a set of 9 text attributes of varying data types (Boolean, Color, Date, List, Number, Set, String). The attribute names use a common prefix 'My', e.g. $MyString. These attributes are very useful for initial testing and incremental formalisation of projects. For pre-v6 documents which may have same-named/typed attributes already defined as user attributes, these will still work as before but said attributes will be accessed via the Sandbox group of system attributes.

    Scrivener Attributes

    This group holds a series of attributes to support the exchange of information with Scrivener.

    Sorting Attributes

    Flags for sorting container content. Although the document is not a visible object in Maps or Outlines it can be selected, to allow sorting top-level notes. In the top level of the view deselect all items and then open the Info view dialog (Cmd+Opt+I, or Note menu, Get Info) and setting the sort attributes for the document itself.

    Storyspace Attributes

    This group holds a series of attributes to support the exchange of information with Storyspace v3.

    Sullivan Attributes

    From 11.8.0, this group holds a series of attributes to support the experimental Sullivan view (not yet fully documented/implemented).

    Table Attributes

    This group holds a series of attributes to support the configuration of Table views.

    Textual Attributes

    Relating to body text, text export settings and general text-related data. For legacy compatibility reasons, the group contains a hidden $Wordcount which maps to the current $WordCount attribute.

    Watch Attributes

    This group holds a series of attributes to support the exchange of information with the web (and via that the iPhone/iPad) using Simplenote, DEVONThink, Evernote, Apple Notes, and Finder folders. In older versions, this group was called 'Simplenote' but was renamed to better reflect its scope of use.

    This group also contains 12 hidden Scrivener-related attributes which are needed for under-the-hood synch requirements. Their exact roles are not documented and should not be of concern to most users. In TBX source XML they can be identified by the code string visibleInEditor="0".

    Weblog Attributes

    Data for configuring Weblog use.

    User Attributes

    Any attributes added to a TBX by a user are added to the 'User' group, which is empty by default.

    Unusual attributes

    These listings describe attributes whose behaviour may be unusual compared to the norm:

    (What is does 'intrinsic' imply?)

    There is also a full listing of all system attributes, although it omits the internal group (see above) as these are essentially off-limits to the user.

    Read-only system attributes

    N.B. This is not a grouping within Info view.

    Attribute definition-level defaults for read/only attributes are not revealed by the Attributes window. However, the defaults can be revealed by double clicking the Attribute name, not value, in a note's information window.

    A listing of system (built-in) attributes that may be read but not altered is given below. All other system attributes may be edited by the user.

    Attributes inherited from Document Settings

    N.B. This is not a grouping within Info view.

    A number of attributes are not defined with a default within the attributes dialog but instead draw their default from program or document level preferences. Attributes of this type are listed below.

    Attributes which are intrinsic

    Attributes that are intrinsic to all objects and thus not inherited, or shared, by aliases.

    This list is created by a setting in the source XML of canInherit="0", as explained in the section on TBX structure. That is not a formal identification; if in doubt about a prototype's intrinsic status check with Tech Support (not the forum - this is internal program information).

    Attributes of this type are listed below.

    Attributes grouped by purpose

    This section groups attributes based on their purpose within Tinderbox. These grouping are as made by aTbRef as opposed to the app itself:

    Agent configuration attributes

    These attributes are used to configure agents:

    Composite configuration attributes

    These attributes relate to the configuration of composites:

    Experimental attributes

    These are attributes adjudged by Eastgate to be 'experimental' in nature. Their purpose may change and they may not be retained in future versions:

    Gaudi view configuration attributes

    These attribute relate to miscellaneous general data about a note:

    General data attributes

    These attribute relate to miscellaneous general data about a note:

    Export purposes

    There are a number of export-related purposes:

    HTML export encoding attributes

    These attributes control the general processing of note data during HTML export, when using the ^text^ export code.

    HTML export file configuration attributes

    These attributes control the nature of the exported filename for a note.

    HTML export post-processing attributes

    These attributes control post-processing applied to exported notes.

    HTML export scope attributes

    These attributes control whether a given note, or its children, are exported

    Text export file configuration attributes

    Not used post v5, these attributes control legacy plain text export.

    Import configuration attributes

    These attributes relate to AutoFetch and RSS use:

    Locational data attributes

    These attributes relate to the geographical location of notes:

    Map item purposes

    There are a large number of attributes relating to the look and layout of map items. Be aware that some of these, e.g. badges apply to other view types as well as map view:

    Map item badge configuration attributes

    These attributes control the configuration of an item's badge in a map view.

    Map item border configuration attributes

    These attributes control the configuration of an item's border in a map view.

    Map item caption configuration attributes

    These attributes control the configuration of an item's caption in a map view.

    Map item general configuration attributes

    These attributes control the general visual configuration of an item in a map view such a shape, colour, tables and plots.

    Map item grid configuration attributes

    These attributes control the configuration of an adornment item's grid in a map view.

    Map item shadow configuration attributes

    These attributes control the configuration of an item's drop shadow in a map view.

    Map item subtitle configuration attributes

    These attributes control the configuration of an item's subtitle in a map view.

    Map item text configuration attributes

    These attributes control the configuration of the look of an item's title and text in a map view.

    Natural Language Processing attributes

    These attributes hold data extracted using Natural Language Processing:

    Note Displayed Attributes attributes

    These attributes relate to configuring note Displayed Attributes:

    Note Key Attributes attributes - replaced by Displayed Attributes

    These attributes are deprecated as they are now totally replaced by the Displayed Attributes attributes with the same purpose.

    These attributes relate to configuring note key attributes:

    Note title attributes

    Attributes referring to the note title. Most of these only have legacy use.

    Note window configuration attributes

    Attributes referring to configuration of the pre-v6 note's text window. Most of these only have legacy use.

    Outline configuration attributes

    These attributes control the general configuration of an outline view:

    Person detail attributes

    These attributes store details relating to a person or organisation:

    Poster configuration attributes

    These attributes store details relating to configuring posters. LINK TO POSTERS ARTICLE

    These attributes are:

    Sort configuration attributes

    These attributes are used to configure container and agent sorting:

    Special note type designator attributes

    These attributes store data indicating a note is to be used in a non-typical way:

    Storyspace compatibility attributes

    These attributes store data indicating a note is to be used in a non-typical way:

    Table view Attributes

    These attributes, from the system 'Table' group provide attributes of varying type for configuring of Table views:

    Test Attributes

    These attributes, from the system 'Sandbox' group provide attributes of varying type for rapid testing of code:

    Timeline event configuration attributes

    These attributes control the general configuration of event items in a timeline view:

    Weblog configuration attributes

    Not used post v5, these attributes are retained for legacy purposes:

    Attributes settable via the UI

    These attributes can be set/edited via UI elements such as the Inspector, Document Settings or view settings:

    Editing attribute values

    A Tinderbox note consists of a large number of attributes. Every note possesses every attribute—both built-in (system) and user-created (user) attributes—even if not using it.

    Every system attribute starts with the built-in default which becomes the default for the document for that attribute. Unless pre-configured otherwise, each attribute data has its own default value (0 for Number, 'never' for Date, 'false' for Boolean, etc.).

    For user-created attributes, the default is set at creation time and will start with the data-type default unless changed by the user.

    The easiest place to review all attribute values for a note is the attributes tab of the Get Info pop-over. This allows the user to select an attribute group and then scroll through a table of attribute names and values.

    To edit attribute values, for the currently selected note, i.e. only one note, use any of:

    • the Get Info/attributes tab. The edit mechanism is as described for the Displayed Attributes table (next bullet below).
    • the note's Displayed Attributes table.
    • the Quickstamp Inspector.
    • any Action code via rules, edicts, stamps, agents, etc.

    To edit attribute values, for selections of multiple items use any of:

    • the Quickstamp Inspector.
    • any Action code via rules, edicts, stamps, agents, etc.

    Get Info & Displayed Attributes vs. Quickstamp vs. Actions

    The first two (functionally the same table) make it easier to see/edit multiple attributes. Quickstamp show one attribute ate a time, though can still set any attribute but it has the upside of being able to act on the selection, thus one, or more notes.

    Action code generally addresses a different context but can set as many attributes as required and any scope, depending on the code the user writes.

    Stamps and Quickstamp have a link beyond the name as a stamp can be thought of as a pre-configured Quickstamp. Like a Quickstamp it acts on the current selection and is run once only per use (unlike a rule or edict).

    Setting or resetting an attribute's document-level default value

    What if the document's default value assigned to an attribute—either system or user—is not what is desired? Can it be changed globally across the current TBX document so that all notes inheriting that attribute use a different value? Yes, it is possible by using the Document Inspector's System or User tab.

    Setting a new value. Select any note, it does not matter which, and open the Document Inspector's System tab. Locate the attribute and type in the new value.

    Re-setting the app-derived default value. If you have already altered the default and do not recall the original value, you will first need to check the for the value to reapply. Either use aTbRef's listings or open a new document and via the same location in the Inspector, see the as-new default value. This can then be noted and used in the original document.

    CAUTION: take special care when editing system attribute defaults that you set a valid and sensible value, lest you cause the application and/or document to become unstable. The same holds true for altering the defaults for user attributes after first use; ensure no existing code depends on the original default value for correct function. If an unsuitable value has been set, a further corrective option is direct editing of the XML code outside Tinderbox using a text editor: find the element for the attribute and edit the value of the default element attribute.

    It is also possible to set an attribute's document-level default via the action code, using the attribute() operator.

    Attributes - $ prefix notation

    $Attribute notation

    Although legacy syntax may still be supported, all calls to attributes—i.e. to their values—in Action code should use a '$' prefix to the attribute name.

    $AttributeName=value 
    $AttributeName=$AttributeName 
    $AttributeName=$AttributeName(where) 
    $AttributeName(where)=$AttributeName(where) 

    Long term users must note that either/both the left or right-hand expressions within the action must begin with a '$'.

    Legacy issues

    Since v4.6.0, Tinderbox has attempted to support legacy code usage alongside the new forms, but do not expect such support to continue. It is thus worth coming to an understanding of the different implications of $Attribute(path) and AttributeName(regex). Indeed, AttributeName(regex) is deprecated: use the current String/List/Set.contains("regexStr").

    Examples of $Attribute(path) usage:

    $Name(parent)="archives" 
    if($ChildCount(parent)>6) 

    Change to Number-based opacity attributes

    In v9.7.0 , several attributes that control opacity formerly were percentages, with a range of 0–100.

    This was inconsistent with other attributes that use a range of 0–1.0. Tinderbox now prefers the range 0–1.0. On loading, the opacity attributes above will be automatically adjusted to fall in the range 0–1.

    Ideally user actions using the old value range should be updated accordingly, i.e. a hard-coded value of 75 should be updated to 0.75.

    Testing for local attribute values

    Sometimes, especially in a larger document it can become necessary to check for locally set attribute values, i.e. a value set in a given note/agent, as opposed to inherited via a default or the document default for that attribute.

    This can be done two ways:

    • For a given note, get all attributes with local values: see $LocalAttributes.
    • For a given attribute, get all notes with a local value: see hasLocalValue().

    Use of Agents

    An agent is a persistent search query; it can also be thought of as a more powerful version of the Find view. The maximum scope of a query is every note (and agent, etc.) in the current TBX document. This holds true even if more than one TBX is open in Tinderbox. The query's arguments then restrict the scope of matches within the overall document scope. Tinderbox has no mechanism for searching across multiple TBX documents.

    An agent is a special note: it can have text, links, attributes, etc., per a normal note but its children can only ever be aliases. These aliases are those of anything meeting the criteria of a query stored in the special $AgentQuery attribute. Thus an agent normally acts as a container for aliases. Agent queries can match notes, (including containers), separator notes, aliases, other agents but not map adornments. Adornments are the one exception to an agent's ability to query any object in the document.

    As well as gathering aliases, an Agent can act upon the aliased notes via the code stored in its $AgentAction attribute. As the query is run continuously, agents are also dynamic in their filtering. As notes alter they may change their match to the query and be added to or removed from the agent's child aliases. Whilst the agent's action code may cause a matched note's original to move within the underlying outline (e.g. to a new container), an agent can neither delete notes entirely nor create new. The latter is a deliberate safeguard against unintentional data loss.

    Normally, attribute changes made to an alias changes the alias' original note. But, be aware that some attributes are 'intrinsic', meaning the original note may hold a different value for the attribute than that in any of its alias(es). With such attributes it may be necessary to use the 'original' designator to ensure the original note's value rather than the value of alias inside the agent is altered.

    The 'agent' designator is also useful as it can be used in both the agent query and agent action to use a value stored in an attribute of agent. The allows either/both the query or action to be altered simply by editing attribute(s) in the agent itself. A useful manner of doing this is to make those attributes 'Displayed Attributes' in the agent.

    Agents may have regularity of their update cycle varied, including the ability to turn an agent off entirely. In the latter case, this means that when turned off the agent retains whatever children (aliases) it had at the last update cycle before it was turned off. The agent's action is not run when an agent is switched off.

    Agents may not be turned into notes, nor notes into agents: both must initially be created as the type of object desired. Agents may not have children other than aliases created by the agent query. An exception is that adornments may be added to agent maps.

    An agent may be a separator ($IsSeparator). This option is set via the Properties Inspector's Prototype sub-tab. As a separator, an agent is not visible in Map view but is visible in all other major views (Chart, etc.).

    Meanwhile, an agent can have note text, Displayed Attributes and other note features although an agent may be used simply as a filter to gather—and act upon—aliases.

    As an agent's output is primarily the effect of its action on aliases, it does not matter where in a document the agent is placed. This is something new users often misunderstand. The choice of whether an agent is better placed amongst the 'content' of the document or hidden away in a separate branch of the outline will depend on the agent's role in the document. Viewing the source of this TBX, it will be seen some agents are within the main content—e.g. those re-stating the attribute listings via data type, etc.—and others which are hidden away in a separate branch of the outline. Indeed, when structuring a new TBX, it is often useful to place all 'content'—the data being worked on—as descendant from a single root level container, making it easy to hide away 'back-of-house' aspects like utility agents, export templates, prototypes, etc.

    On export, agent aliases are exported as discrete files, albeit sharing their original's text and most attributes (except intrinsic ones).

    Like a note, an agent can also use the $Rule and $Edict attributes allowing it to apply changes to itself as well as its contained aliases.

    Queries match both actual notes as well as their aliases. A note satisfies a query if:

    • the note itself satisfies the query

    or

    • any alias of the note satisfies the query

    Regardless of whether the note or one of its aliases satisfies the query, the agent makes a new alias of the original note.

    The agent's child map (i.e. the aliases) is auto-updated and laid out. The default use of a grids can be altered or turned off - see re-arrangeable agent maps.

    Aspects of agent and query use

    See:

    Agent & Queries

    Queries are action code expressions in a conditional form that must resolving to true/false statements. Agent queries result in the agent creating a list of aliases that will include each matching item once. Thus even if the original and/or one or more of its aliases are all within the scope of the query, that item will create a single alias in the agent. An exception is allowed, where it is needed to locate an original and all its aliases, by using a contains() query based on the item's name as this will match all containers of both that note and all of its alias(es).

    Agents, including smart adornments, can match notes (including container notes), separator notes, aliases, other agents but can not match map adornments. Adornments are the one exception to an agent's ability to query any object in the document.

    References in this section to "BooleanAttribute", "DateAttribute", etc., refer to any system or user attribute of the data type specified. Thus "BooleanAttribute" implies any attribute of the data type "Boolean".

    Note that an agent's query only controls which notes are matched and whose aliases are added as children of the agent. Anything done to the (aliases of) matching notes is controlled via the code stored in the AgentAction attribute. Action code can also be viewed and edited via the Action Inspector.

    Queries are written in action code. In the very early days of Tinderbox there was a discrete syntax for queries, using operators with a # prefix. If such code is seen in old files or code examples, it should be re-written in existing action code before use.

    Unlike action code expressions, queries do not and should not use a terminating semi-colon. As this may easily be done by mistake, Tinderbox will ignore a terminating semi-colon if found in a query.

    Query Syntax

    Queries are used by:

    • agents
    • action code conditional statements
    • action find() operators (most normally for scoping arguments)

    Queries are written in action code syntax but with some differences:

    • Queries never use semi-colon terminators unlike in rules, etc.
    • Equality tests (are two things the same?) always use a == operator (two equals signs).
      • Note: very old code examples may use a single '=' and if using copy paste do not forget to double the = to ==.
    • If a query has multiple parts, these are joined using & (and) or | (or) join characters.

    If it is desired to control the order in which different parts of a multi-term query are evaluated, each query term—or sub-groups of query—can be enclosed in parentheses, i.e. round brackets '(' and ')'. As with parentheses in a spreadsheet formula, Tinderbox will evaluate the inner-most (most deeply nested) parentheses before working outwards until the whole query is evaluated.

    Action code offset addresses can be used, i.e. referencing values in another note $Color versus $Color("Some other note"). In the special case of wanting to reference attribute values in the agent itself, use the 'agent' designator to refer to the attributes of the current agent, whilst smart adornments can similarly use the 'adornment' designator. For example:

    Query: $Status=="Important"
    Action: $Color=$Color(agent);

    This agent gathers all "Important" notes and sets their colour to match the colour of the agent. Note that this is different from

    Action: $Color=$Color(this);

    since "this" refers to the note being gathered, and is also different from

    Action: $Color=$Color(parent);

    since "parent" is the parent of the original note, not the parent of the newly-made alias. The latter is a case where, for intrinsic attributes, it may be necessary to use the 'original' designator to avoid using the aliases value for the attribute. Thus:

    Action: $Color=$Color(parent(original));

    More on Queries

    See:

    Simple Queries - equality and inequality

    A very common desire when starting out with agent queries test is a given attribute does—or does not—match a specific value. Here, 'match' implies equality, i.e. the two are exactly the same. The exactitude relates to subtleties like the fact that 'Ant' and 'ant' are not the same as one starts with an uppercase character. If new to using code and queries, take a moment to familiarise yourself with Tinderbox's comparison operators.

    Thus to match all notes that have a colour of 'red', the query is:

    $Color=="red" 

    Do not use this form:

    $Color="red" 

    IMPORTANT: Tinderbox will accept a single '=' but only to stop code breaking in very old TBX documents some point this support will cease, so do not use the '=' form in queries and update old code.

    Inequality is tested using '!=" (exclamation mark + equals sign):

    $Color!="red" 

    Note the inequality test only used a single equals sign, i.e. do not use '!=='.

    If woking with Date-type attributes and testing a specific date, it is best to use the date() operator to enclose the actual date string. This ensures Tinderbox turns the string into a Date-type object before doing the equality test:

    • GOOD: $StartDate==date("today")
    • GOOD: $StartDate==date("24/11/1987")
    • BAD: $StartDate=="today"
    • BAD: $StartDate=="24/11/1987"
    String Attributes - comparison operators & case sensitivity

    Comparison Operators

    The comparison operators available are <, <=, ==, !=, >=, and >. The == and != operators always work as a case-sensitive comparison. Examples:

    $Name > $AttribName 
    $AttribName > $AttribName(path) 
    $Created > $Created(parent) 
    $Name < $Text  
    $BorderColor == $Color 

    For case-sensitive matches, use String.contains("regex"), e.g. $MyString.contains("dog"), where the regex is a string literal or regular expression. Using String.icontains("regex") forces a case-insensitive match. The same applies to Lists and Sets, see also Querying Lists and Sets.

    Regex matches (via both old and new style contains) are case-sensitive by default, but when used in the context of an agent this can be modified. This is done by setting the agent's $AgentCaseSensistive attribute to false.

    Thus, a case-insensitive 'dog' regex could match all case variants of 'dog' (dog, Dog, DOG, etc.). However, as this would also match a value of 'big dog', the degree of match of the regex can be restricted further by regular expression string delimiters, e.g. $MyString.contains("^dog$"). The caret (^) forces matching to start at the beginning of the string; note that it has to be doubled so as to escape it for Tinderbox, i.e. tell the program the symbol is not, in this context, export mark-up code. Similarly, the $ forces the match to run all the way to the end of a value string. This therefore excludes longer strings that might contain the word in question. The use of the $ in a regular expression should not be confused with the $AttributeName usage, which simply references an attribute's value.

    Querying Lists and Sets

    Testing (querying) containment in lists

    Testing List and Set type attribute, the contains() or list.contains() operators, return true if a List-type—or Set-type—list contains an exact match for the the designated regex. The test is case-sensitive regardless of agent query case sensitivity settings; regex matches are not supported. If user attribute PetTypes has a value of [dogs;cats] then

    $PetTypes.contains("dogs") is true,

    but

    $PetTypes.contains("dog") is false 

    as 'dog' is an incomplete value match.

    It can be useful to use a stored value as the search regex, for instance using the name of an agent as the search term. However, the following will not work or an agent named 'dogs':

    $PetTypes.contains($Name) WRONG!

    Instead, use the evaluated result of the above via a rule or some other action code. Thus, in an agent's Rule box, enter:

    $AgentQuery='$PetTypes.contains("'+$Name+'")' 

    …which results in a query of:

    $PetTypes.contains("dogs") 

    Querying list items

    A query can test a single item from a list. For instance, if $MyList for note A is [3;4;5] and for note B is [1;5;10], then query:

    $MyList[1]==$MyNumber(agent) 

    will match B but not A. This is because only B has the number 5 as the second list item ('1' in a zero-based list).

    Further information

    See Set Attributes and List Attributes for more on list-based attributes.

    Regular Expressions in queries

    Tinderbox regular expressions ('regex') recognise a number of patterns containing the backslash character. Some common examples are:

    \s matches any whitespace character
    \S matches anything EXCEPT a whitespace character
    \w matches a word character, such as a letter
    \W matches any non-word character, such as punctuation

    Otherwise Tinderbox uses normal regular expression escaping (i.e. to double-escaped backslashes). For example:

    "this\sthat" 

    recognises

    "this&[tab char]&that" 

    as well as

    "this   that" 
    Legacy Query Code for agents

    NOTE: This note is for legacy reference only.

    The #-prefixed Query Code for writing agent queries were replaced and deprecated from v4.6.0 (March 2009).

    Essentially, in early Tinderbox versions some operators were written in a different code style, using a #-prefix. All such codes since have action code replacements (e.g. #inside()inside()) so are unlikely to be found except in very old code examples or old TBX documents.

    From v11.5.0, all the previously deprecated #-prefix codes will no longer work: #inside, #descendedFrom, #first, #last, #linkedTo, #linkedFrom, #indented, #similarTo, #word, #between. Any legacy code still running under deprecated support will now need to be replaced with the correct action code. The latter operator will be the older code but without the '#' character. But be aware that the syntax—number/order of arguments—may have changed so if updating old code check the syntax is correct before running the corrected code.

    An easy way to find most old query code, is run the query $AgentQuery.contains("#").

    Old query code might also occur in if(condition) and statements.

    Legacy reference (link)

    The syntax of these older codes is available at https://atbref.com/atbref46/index/AgentQueries/Legacyquerycode/SpecialQueryArgumentsdep.html. The linked article explains the mapping of old #-prefix syntax to new operator() syntax.

    Query back-references in agents

    Not all queries use regex, therefore not all queries can generate back-references. The only difference, relating to an agent, is the context of where the regular expression (regex) is input.

    The more general issue of back-references is discussed under using regular expression back-references.

    Querying for aliases - agents

    Although the parent of an alias is its (outline) parent, as the image shows, it is not always interpreted as such. In addition, queries like inside() and descendedFrom() find aliases in 'other' containers besides their original's because the original note lies within scope of the query.

    Note that use of the 'parent' designator can be used to filter queries rendering apparent false positives. The $Name(parent) for alias and original will differ unless both are in the same container, as is often the case when an alias is freshly created and not yet moved to its intended location. Be aware though that alias and original share the same $DisplayExpression so this is not a good a good way to investigate the difference.

    All children of an agent are aliases regardless of whether they point to an original or an alias.

    System attribute $IsAlias cannot be used on its own, but can help find only original notes:

    inside(Some Container) & !$IsAlias 

    To find aliases as opposed to originals, it may be insufficient to use the reverse:

    inside(Some Container) & $IsAlias 

    Why? Because an agent's children are also aliases, although not user-created ones. In order to filter out aliases within agents an extra query term is required:

    inside(someContainer) & $IsAlias & !$AgentQuery(parent) 

    As agents de-dupe listings, the above methods cannot be used to locate multiple aliases of the same note. However, it is possible to locate their containers as long as the latter are themselves not all named the same. Use:

    !$AgentQuery & any(child,$IsAlias) 

    Clause one discards any containers that are agents (because they will have a query value). The second clause matches any container where one or more children are aliases. To filter this for just aliases of a known note title, try:

    !$AgentQuery & any(children,$IsAlias) & any(children,$Name=="Other Attribute types") 

    There is no 'IsAgent' test but only agent will have a value for $AgentQuery so it works in this context. Whilst it is possible to make an agent and not give it a query, such an agent cannot have any children (no query to match against) and so would not affect the above query.

    It may be easier to use find() for tracking down aliases.

    Querying for aliases - find()

    The find(scope) operator can be used to produces a list of matching paths, i.e. the $Path of matched objects. The operator's scope argument is supplied in the form of a query. Notes matching the query form the output list. The latter being List-type data it is thus not de-duped like an agent's results. The background to the find() operator was as a custom designator, allowing an ad hoc query where a fixed designator (e.g. 'children') might normally be used.

    It is important to note this method does not use agents directly, as find() is intended to run in actio code. Where an agent's query populates the agent container with aliases, a find(scope) returns a path for any note matching the scope argument's query. Thus matches cannot be seen in a Map or Outline view as with an agent - a point to bear in mind if seeing matches in the UI is important to the user.

    A key difference of using find() vs. $AgentQuery to query is that find() returns originals and all aliases that match whereas an agent returns only one match per original object favouring an original over aliases. Thus if note "Project X" has two aliases, an agent will match one item (the original) whereas find() will return a list of three items (the original and each alias).

    The $IsAlias boolean system attribute lets find() return only aliases or only originals. Thus for note 'Test', this will return a list of the paths to each alias of Test but exclude the original:

    find($Name=="Test" & $IsAlias==true) 

    In contrast, this returns only the original:

    find($Name=="Test" & $IsAlias==false) 

    Note that the boolean tests for $IsAlais can also be written in short for. True: $IsAlais. False: !$IsAlais.

    Want to find all the aliases of all notes whose name contains the string "Test"?

    find($Name.contains("Test") & $IsAlias) 

    The above will match names like "Test", "My Test" as well a "Tester" but not "Intestate". By using .icontains() for case insensitive matching, "intestate" would be found.

    find($Name.icontains("Test") & $IsAlias) 

    Want to exclude aliases that have 'Exam' in their path?

    find(!$Path.contains("Exam") & $IsAlias & $Name.contains("Test")) 

    Want the original find to exclude aliases that are agents' contents?

    find($Name.contains("Test") & $IsAlias & !$AgentQuery(parent)) 

    Want to display the resulting list as line-by-line entries in $Text?

    $Text = find($Name.contains("Test") & $IsAlias).format("\n") 

    Notice how the $IsAlias term in the scope query is used to filter out either original or alias.

    Fine-tuning query search results using $Searchable

    It is possible to exclude individual notes (and agents) by setting an item-scope Boolean $Searchable.

    By setting a false value for $Searchable, that item is excluded from searches even if otherwise matching search criteria. This makes it easier to exclude behind-the-scenes notes like templates, prototypes, and general framework containers for normal searches whist allowing content to be intermingled. Previously, such items were excluded by storing them away from primary content in a different outline branch or map.

    Features using $Searchable

    The following honour the $Searchable setting:

    • agent queries
    • action code find()
    • action codes using query-based arguments, e.g. if(), collect_if, etc.
    • view filter bar
    • views with (optional) query-based scope, e.g. Attribute Browser view.

    Search features that ignore the $Searchable setting:

    • View Find (Cmd+F) either as in-view Find bar or as stand-alone Find window.

    In summary, all search methods except view pane Find use $Searchable.

    Scope of objects affected

    The following types of object use $Searchable settings:

    The attribute affects notes, containers, agents and aliases (see below).

    The following types of object do not use $Searchable settings (i.e. setting the attribute has no effect):

    • Adornments are always excluded, regardless of the $Searchable setting.

    Scope of setting

    The attribute is intrinsic so may be set separately for aliases, for instance ensuring a particular alias is matched rather than its original.

    Unparse-able queries

    If the query string does not parse the agent's query will be disabled and an item added to the error list. Once the query if fixed (or deleted) the item will clear from the list.

    Date Comparisons - Date vs. Date-time

    All Tinderbox Date-type data includes a time component in hours and minutes (no seconds or smaller). The time can be a confusing factor when comparing dates as often in the mind of the user whole days are being compared. Also, when using date designators, like "today" or "tomorrow + 1 month", the Date object created takes the OS' current clock time.

    Thus at local time 13:00 on 28 November 2012, 'today' will return a value of 28 November 2012 13:00. A minute later it will return a value of 28 November 2012 13:01.

    The time element is often overlooked when doing date-based arithmetic, especially for jobs like agents designed to find something like "all unfinished tasks in the next week". The natural tendency is to use a date (part of the) query like so:

    $DueDate > date("today + 7 days") & $DueDate < date("today + 14 days")

    However, for > and < the time element is counted. Thus, if 'today' was 28 November 2012 12:00, any items with a $DueDate before 12:00 on that day would not match the query. This is likely not what a new user would intend. To avoid the time issue with > and < comparisons where the time element is to be ignored there are two strategies:

    • adjust the number of offset days and use >= or <= instead.
    • ensure the reference date ('today' or whatever) has its time element correctly set.

    Alternatively, to find past (or future dates) that only coincide (or not!) with the current calendar day, a two-part query is needed. Equality test operators (== and !=) and those including an equality test component (>= and <=) ignore the time element and test only for the whole calendar day. The latter effectively combine the less/greater test and an equality test, e.g. ((A > B) | (A ==)), the first of which is time sensitive and latter not. So, if the tested date time is 12:00 on 15 Jan 2013, >= will find all date-times before 00:00 on 16 Jan 2013; <= will find all dates after 00: on 15 Jan 2013. Neither of these is likely what the user intended. To find overdue $DueDate that are only on the current calendar day:

    $DueDate < date("today") & $DueDate == date("today ")

    Conversely to get the same but where the overdue notes are not on the current calendar day:

    $DueDate < date("today") & $DueDate != date("today ")

    Setting the time element of a date is discussed in more detail here.

    Agents and intrinsic attributes

    Some attributes are intrinsic to aliases. For instance, this allows an alias to have a different $Xpos and $Ypos from its original and thus a different location on the agent's map to that of the aliases' original.

    In an agent action, it may sometimes be necessary to use the 'original' designator to set the original note's attribute and not the value of the same which is intrinsic to the alias. In an agent action:

    $MyString = "hello" 

    …sets $MyString both original and alias as the user attribute is not intrinsic. But:

    $Xpos = 4; 

    …would set only the $Xpos of the alias, whilst this would set only the original's value:

    $Xpos(original) = 4; 

    Either of the following would set both:

    $Xpos = 4;$Xpos(original) = 4; 
    $Xpos = 4;$Xpos(original) = $Xpos; 

    See a list of intrinsic attributes.

    Self-referring agents

    It can be useful for an agent's query or action to refer to the agent itself. This is especially helpful if creating generic agents where the same query/action needs to be applied many times in different contexts.

    The key to reining this process is the 'agent1' designator can be used within the agent to refer to its own attributes. The 'agent' designator is understood only by agents. Note: smart adornments must use the 'adornment' designator instead of 'agent' but otherwise in the same fashion.

    The designator allows things like:

    Query: $Tags.contains($Name(agent))

    This will match all notes where the $Tags attribute matches the $Name of the agent. For Lists/Sets the match is to a whole exact list value. For a String, the match could be to a sub-string. For an exact match in either case, but especially String attributes:

    Query: $Tag == $Name(agent)

    Now, if the agent's title is changed the query is automatically adjusted. The same trick can be used in the agent's action or rule. Here the $LessonNumber in a matched note is set to the value of the same attribute in the agent:

    Action: $LessonNumber = $LessonNumber(agent)

    The designator can be used on the left side of an action. Here the matched notes $Author2 value is added to the agent's $Authors Set attribute:

    Action: $Authors(agent) = $Authors(agent) + $Author2

    In actions and rule, as with the query, the 'agent' designator passes the current value of the cited attribute so changing the source attribute value will automatically affect the result of the agent. Often the need is to run the agent action only once, e.g. once per newly added note. In that case, consider altering action and/or query such that the action causes the acted on notes to no longer match the query. There are some other techniques.

    If the agent queries are going to use inside(), descendedFrom() or test note $Name, then it may be better not using use $Name(agent) to see the process and instead add a user attribute to hold the customisable value. This avoids the scenario for value A seeing the agent for value B and so on, with unexpected consequences.

    Indeed, the more clever the automation is made here, the more it makes sense to test the process on a copy of your date before committing it to the master unless you overlooked a flaw in your logic. Writing a badly thought-out agent can do a lot of edits very fast that can take much longer to unwind as there is no simple 'undo' for agent actions (unless the action's code logic allows for this)

    Using a prototype

    As well as a re-configurable single agent, the 'agent' designator also offers a useful way to make a prototype agent that can be set up quickly. Creating and using prototypes with agents is the same as with notes, though care needs to be taken not to run code in the prototype or to start altering a new agent's setting before the prototype is applied. Side note: Tinderbox actions cannot create new agents (nor notes) and there is no shortcut to create an agent: use the menus or context menus.

    Thus:

    Query: descendedFrom($Name(agent))

    To avoid the agent miscuing, it is better to avoid the apparent convenience of $Name and to use a user attribute, which is then accessed and edited via a Displayed Attribute. Thus:

    Query: descendedFrom($TargetValue(agent))

    In the latter, the prototype agent's $TargetValue is deliberately left blank, to ensure noting is matched and no actions occur by mistake. The prototype has $TargetValue set as a Displayed Attribute. To use the system make a new agent, apply the prototype, select the agent and in the text pane set its $TargetValue to the name of the container you wish to analyse. This way a generic agent with many attributes/actions can be pre-made and re-used many times.

    For prototype smart adornments, do the same except use the 'adornment' designator in the same way as agents use the 'agent' designator.

    Another approach to avoid premature execution in the prototype is first set $RuleDisabled to true. Leave the query blank. Then set this rule in the prototype:

    Rule: $AgentQuery|="descendedFrom("+$Name+")";$Rule="";

    This time we do not need the 'agent' designator the current note context is already the agent. It is important that $RuleDisabled is set before adding the prototype's rule as the latter must not fire except in agents using the prototype. In this example the $Rule also sets itself to nothing—if it was fully reset—it would, of course, re-inherit the prototype's code each cycle. The point of the rule re-writing itself is so the query is set just the once, just as a simple exercise in avoiding running code more than needed, if the query was set anew each cycle it would not really matter. This technique no use if the intent is to use a Displayed Attribute rather than $Name for the source value as by the time the attribute is set the query is already set. The above rule also uses a "|=" assignment so the rule runs just once to set the query. Otherwise every agent cycle the query would get re-set and never get to run as the query gets used the next cycle after being set, before which the rule would reset it.

    However, the latter approach does allow for a more complex setting where the query regex must be derived from an action code expression using several attributes:

    Rule: if(!$IsPrototype){$AgentQuery|="descendedFrom("+$TargetValue+" - " $TargetValue(Other note)+")"}

    If wanting to set OnAdd code that uses a literal value of an agent's attribute, then the prototype method is needed.

    If wanting to set the query/action just the once, besides using |=, you may consider using a self-cancelling code. However, you are better using a "" (empty string ) reset than resetting inheritance. Otherwise, the note re-inherits from its prototype in a never-ending loop. In the latter case the process will not run away but code will re-run each agent cycle.

    As noted above, the more inventive the customisation used the more important it becomes, especially for less experienced, to test before letting the process on a real data file. Better to discover any mistakes in test!

    Aliases, children and descendants

    Although aliases do not have children or descendants of their own, an alias in action code (such as queries) can act as a proxy reference to such descendants. Previously, is was necessary to write every(descendant(original),$Checked whereas now the same can be queried, via an alias in scope by using every(descendant(,$Checked).

    In an agent query, we may want to search for notes whose children or descendants share a property:

    Query: $ChildCount>0 & every(descendant,$Checked)

    This will find all notes that have a child, for which every descendant is checked.

    In previous versions, it was necessary to reference the original of the alias, since the query applies to an alias, and aliases have no children. An alias' children are, for the purposes of actions, the children of its original note, and its descendants are the descendants of the original note. By contrast, this does not mean that aliases can have their own discrete children/descendants.

    Controlling Agent Update Cycle Time

    To check your current agent cycle time and number of agents use the Tinderbox Inspector, Agents & Rules tab.

    Controlling Agent Priority

    The $AgentPriority attribute, allows the user to set the periodicity with which agents are run. This attribute can be set via;

    This attribute allows agents with queries tracking low rate of change to be run less often, reducing the overall agent cycle time.

    Although $AgentPriority can be set (via code) to a chosen number, a subset of values map to labels used in pop-up menus in the UI:

    • Highest = 0 . Runs every few seconds.
    • Normal = 1 (default). Runs roughly every ten seconds.
    • Low = 4. Runs roughly every minute.
    • Lowest = 10. Runs roughly every five minutes'
    • Occasional = 20. Runs roughly every thirty minutes.
    • Off = -1. Does not run (retains any existing aliases)

    When set to 'Off' (-1), Tinderbox 'freezes' the contents of an agent and it does not run again; this reduces the overall cycle time. It means that when turned off, the agent retains whatever children (i.e. child aliases) it had at the last update cycle before it was turned off. Agents switched 'off' do not get updated via the file menu's 'Update now' command. It is thus not possible to have an agent that is only 'manually' updated. When an agent's query is 'off' (-1):

    • Query does not run
    • Agent add/remove actions ($AgentAction, $OnRemove) do not run.
    • Agent rules and edicts still run, i.e. in the agent itself
    • Child aliases' rules and edicts still run.

    This means that agents can be used to harvest sets of aliases and then turned off to 'fix' the content. Alternatively, such agents' priority can be turned on/up to update content before an export and then turned off/downTbRef uses this method for agents used to do tasks such as representing the main attribute list in alternate forms such as by data type or TBX system attribute group.

    All agents that are not 'off' run once on document load or a force refresh of agents.

    To avoid having to change each agent by hand, they are located by an 'utility' agent '@attributes_agents_frequency' with this query:

    inside(Attribute Data Types) | inside(Attribute Groups) 

    An action sets priority for the matches found (which here will be agents):

    $AgentPriority=10 

    Note the $AgentPriority must be set using a numerical value. Using 'Low' instead of '10' results in—due to type coercion—a value of 'Highest' and not quite what's wanted. In turn, this utility agent is turned off when not in use. When enabled, it allows 18 agents to be controlled via one setting.

    Although the Agents & Rules Inspector tab will tell you how many agents you have, you may be sure where they are in your TBX. An agent can help using this query:

    $AgentQuery!="" 

    Notes, adornments, etc., will not have an $AgentPriority value. More precisely, adornments may have an $AgentPriority but only if they are 'smart' adornments.

    Now you have all the agents you can use the Show Original command to locate the agent. To aid more granular control of separate groups of agents, consider their location in the TBX. For example, in aTbRef the exported content, with the exception of the RSS feeds is all in one note hierarchy 9outline branch). A separate root-level note 'UTILS' contains, sets of prototypes and utility agents. Meanwhile both the Attribute and Export Code section use agents to present their lists in different splits; because the agents are within a containing (note) the #inside() query syntax can be used to easily locate them.

    If your agents are more scattered in the TBX consider using a user-set attribute to flag agents so an agent may easily find them. However location based queries (as above) are more efficient, for reason discussed further below.

    Altering Content of Disabled Agents

    When switched off, an agent retains the aliases it had at that point. You can also do several things you cannot do when the agent is active:

    • Re-order the aliases, e.g. alter the outline order or map location
    • Delete aliases without them being recreated (N.B. you cannot add new notes aliases)

    Note that re-enabling the agent may undo some of the above order/location changes and may add back deleted aliases.

    If you need to alter the layout of an active agent, make sure to set $CleanupAction to any non-default value.

    Making Agents More Efficient

    In small TBXs you will not notice your agent settings affecting update time but as a TBX grows in size and complexity, ideally your agents should match as few notes as possible, or at least where that is possible to do so, in order to keep performance snappy. In this context, think about using inside() and descendedFrom() as part of your queries. The former allows you specify only the immediate children of a given note whilst the latter matches any descendant of a given note. For example, if searching for text in children of a note called 'The Library', it is much faster to run:

    inside("The Library)" & $Text.contains("When.+April") 

    …than…

    $Text.contains("When.+April") & inside("The Library") 

    …because the inside() part of the query cuts the number of notes searched. The second example does a regular expression search against all notes in the TBX before the results are then filtered to only children of 'The Library).

    It is much faster, in performance terms, to factor out very complex queries into separate agents, and then use inside() to leverage those agents, than it is to repeat the queries. Complex regular expressions are also comparatively heavy users of TB thinking time so consider if there is not an easier way to find the same match. For example, if using such a regular expression to find misspellings, you might delete the agent when done or at least turn it off between major editing sessions.

    As a general point, regex (regular expression) based queries like .contains(0 and .icontains() are far more CPU-intensive than many other actions.

    Check That Results Make Sense

    Finally, beware of broken agents. Sometimes, a syntax error can create an agent that finds nothing (or the wrong things), but takes an age to do so.

    Disabling Automatic Updates

    Trying to do text editing and getting disturbed by the hourglass? In a big TBX with many agents this can happen. In such circumstances it can help to disable the "Update Agents Automatically" option (via the File menu), just do not forget to enable it again if your document relies on ongoing use of live agents.

    Flushing All Agents

    File menu ▸ Update Agents Now runs all 'on' agents once. It also forces the process in front of other task, like running rules. This can be useful if a document has many agents and rules and you wish to update agents more quickly, e.g. to reflect a change you know you have made. But…

    Cascading Agents

    If you either do not use (or have temporarily turned off) automatic agent updates, you can use the same (File) menu to force a one-off update via "Update now" (cmd+ctrl+=). However, if you use a lot of agents and have different priorities set it can be a wise idea to use this update call several times in succession to ensure all agents are fired, as those agents with lower priority settings are omitted from some firing cycles (i.e. update); the lower the priority setting, the more often an agent is omitted from the cycle. For instance, for the aTbRef TBX it can take 3 or 4 successive "Update now" calls to ensure all the low priority agents are run. Failure to do so means that sections like the listings of attributes by data type do not get populated, given that the HTML output expects each alias to be exported as a separate HTML file. If the TBX is not properly updated after being opened, some sections (agent containers) my be empty until enough update cycles has completed to populate even the lowest priority ones.

    However, Tinderbox is aware of the latter issue and when doing an HTML export, Tinderbox should update all agents regardless of priority before export (including agents set to 'Off') but it is still worth checking output to ensure that output depending on several agent's actions has actually been generated. Once happy the process is working as expected, you can ease back on such checks.

    Put another way, when you get creative with agents and start to create more complex TBXs, do not just check for the obvious output but look for unintended consequences: either of your query/action/rule coding or simply the inheritances and agent activities you have put in place.

    Sorting Agent Results

    By default, agents have no specific sort order for their matches.

    The user may impose a deliberate single or two-level sort using criteria set via the Sorting group of system attributes, most easily accessed via the Action Inspector's Sort tab. Other options include the agent's Get Info or by setting the attributes via action code.

    There is no document-level setting for agent sort order. If it is desired to use a sort order across the TBX, there are several possible solutions:

    • Make an agent:
      • Query: $AgentQuery & !$Sort
      • Action: $Sort="OutlineOrder"; or "Name", etc.
    • Make an agent, set just the sort order and make it a prototype.
    • Use the action from above as a stamp, and use the stamp on any agent as required.

    When sorting by $OutlineOrder, the original note's value is used, regardless of whether the match is to an original or an alias. This gives speedier response whilst generally giving an acceptable sort order.

    Sorting the contents of agents poses an extra problem to that of normal containers. This is because agents collect aliases of notes and in some cases the alias does not share attribute values with its original note, e.g. for $Width and $Height, the intrinsic attributes of an alias.

    Thus setting $Sort (and $SortAlso) for a given attribute may not always have the intended consequences. The sort transform pop-up menu has the option 'original note'. Setting this transform tells Tinderbox to use the original note's value instead of the aliases, should the two differ. The 'original note' transform is useful if you want the aliases to sort in the outline order of their original notes.

    Manually triggering agent updates

    By default, new Tinderbox documents are set to update all agents automatically. In the vast majority of cases this is what the user wants. All agents run all the time, unless they have had their $AgentPriority altered via the agent's Action Inspector Query sub-tab or directly in action code.

    In addition, you can trigger an immediate 'Update now' from the File menu. This runs all agents once, regardless of $AgentPriority except for any agents expressly turned 'off'' ($AgentPriority set to -1).

    In addition, when Exporting to HTML or Exporting to Text (File menu), this invokes a once-only update of all running agents.

    Detecting when manual 'Update now' is complete. In a very large or complex document with a lot of data and agents, where agent cycle time is a bit longer, it can be difficult to know when the full cycle is complete. A giveaway is that when the File menu's 'Update now' option is clicked, the menu clears but the 'File' caption remains highlighted in the main menu bar. Once the process is complete, the highlight disappears.

    Considerations when using agents that query other agents. If you have a complex set-up with agents looking at the contents of another agents, it may take several manual 'Update now' calls to flush a change through all the agents involved. How many calls is down to the user knowing how they constructed their code. For the same reason, when exporting, it may be expedient to either leave the document for a while to update fully or make several manual updates before starting as the full export process only updates agents once.

    Action Code

    Action code is Tinderbox's method for automation of internal tasks.

    Originally, Tinderbox had 'actions' that notes applied to themselves or their children. These were written in 'Action Code' though at the time what is now 'Export Code' was generally used for internal macros (actions). In v4 and v5 this mix was clarified: Export Code moved to being for export only whilst all internal 'coding' was done using 'Action Code', i.e. the style of code used for writing actions.

    Action code is now the most likely, indeed only, form of automation users are likely to meet unless they use export features to pass information out of Tinderbox.

    Action Code is not a formal coding language (programmers, take note!), and being artisanal software has grown as needed: it has what it needs or its users has asked for. It may lack some features that those with a programming background might assume are 'standard'.

    An action is an automatic way of setting a certain attribute to a certain value (with the exception of system read-only attributes which cannot be altered).

    Meanings of Action vs. Action code

    The differing occurrence of the word 'action' can be confusing.

    What is an action? As originally achieved it was essentially the functionality of agent actions, rules and the OnAdd. These allowed notes to alter attribute values in themselves or their children. These were written in action code, which differed from the primary macro, i.e. internal scripting, code of the app—what is now termed export code. Note that macro also has a discrete meaning in both export code ( via ^do^) and action code (via do()).

    The older form of 'action' is reflected isn a number of (Action-type) system attribute

    Since action code's role expanded, an action generally refers to any complete internal macro. Generally, they way the form:

    [left side] assignment [right side]

    For example, at simplest:

    $Color = "blue" 

    Or, with a degree of evaluation or either side:

    $MyString("Some note") = $Color.hue 

    Multiple discrete (complete actions) are delimited/terminated by a semi-colon):

    $Color = "blue";$AccentColor = "red"; 

    or as a semi-colon is optional after the last/only action:

    $Color = "blue";$AccentColor = "red";$Badge="ok" 

    Note too, that whitespace around the assignment is ignored when the app parses )'reads') action code.

    All the code above is action code.

    Action code syntax

    For long time users of Tinderbox, action code replaces all older #-prefix query code and many ^export^ codes. Indeed, use of ^export^ code inline in actions is now discouraged (any support is only for legacy code).

    Action code parsing and line ends—a change (from v11.8.0)

    In actions, statements are terminated by a semicolon or by the end of the action. This could lead to confusion if the semicolon were accidentally omitted.

    $Name="Lincoln" $Subtitle="President";

    Because the first line lacks a semicolon, the second line was skipped as a syntax error. Moving forward, this case will be handled more gracefully; the newline is treated as implicitly ending the statement. Line breaks inside parenthetical, quote strings, {…} blocks, and […] blocks continue to be treated as always. Statements such as

    $Name =
    "Vortigern";

    were previously acceptable but will now fail, but these are (a) exceedingly rare and (b) likely to be a bad idea anyway.

    (Agent) queries are also written in Action Code

    Thus a query, in action code, might be:

    $Name == "Foo" (is this note's title the exact string 'Foo'?)

    Or, with multiple terms:

    $Name == "Foo" | $Name == "Bar" (is this note's title the exact string 'Foo' OR 'Bar'?)

    As well as in agents queries, are use in a number of places such as smart adornments, find() and in action operators with conditional arguments. Be aware that many operators that have a scope of action (i.e. objects read from and/or acted upon) may also define thet scope via a query.

    Case sensitivity

    All action code operators are always case-sensitive (unlike export codes).

    Making/deleting notes: See create(), createAgent() and delete().

    Action code Syntax

    This is expanded upon under basic action code syntax. Note the point above re case-sensitivity.

    Further discussion of use of actions:

    Actions

    Actions, in the old attribute-stored sense, include:

    *An OnAdd action is performed by a container upon a note added to it, or by an adornment to a note placed upon it. A note's OnAdd action code is stored in its $OnAdd attribute. It can also be easily be viewed or edited via the Action tab of the Action Inspector. An OnAdd applies only to direct new children and thus not their children (i.e. other descendants).

    *An Agent Action is performed by an agent upon any alias of a note it creates as a result of a match to its query. An agent's AgentAction action code is stored in its $AgentAction attribute. It can also be easily be viewed or edited via the Action tab of the Action Inspector. Note: agents have no OnAdd and conversely notes have no Agent Action, thus the Action Inspector can show both in the same UI.

    *An OnRemove action is performed by a container upon a note removed from it, or by an adornment on a note moved off it. This can be seen as the opposite of an OnAdd action. A note's OnRemove action code is stored in its $OnRemove attribute. It can also easily be viewed or edited via the Remove tab of the Action Inspector.

    *An OnJoin action is performed by a member of a composite, once, upon any item joining the composite (or being moved within it) so as to touch the item with the OnJoin action. A note's OnJoin action code is stored in its $OnJoin attribute.

    *A Rule is performed by a note or agent upon itself its Rule is run; this happens from time to time, typically every few seconds. A note's Rule action code is stored in its $Rule attribute. It can also easily be viewed or edited via the Rule tab of the Action Inspector.

    *An Edict is performed by a note or agent upon itself its Edict is run; this happens from time to time, typically about once an hour. A note's Edict action code is stored in its $Edict attribute. It can also easily be viewed or edited via the Edict tab of the Action Inspector.

    *A series of mouse input state-related actions are stored in attributes. See Mouse actions.

    Pre-stored actions or ac hoc action code can be invoked:

    *A Stamp is a pre-saved action that is run once on each selected note or agent when selected from the Stamps menu or applied via the Stamps Inspector. Stamps are saved in a Tinderbox document and edited via the Stamps Inspector. A stamp may also be invoked in action code via the stamp() operator.

    • A function is a pre-saved set of actions that can be called from any action, allowing a complex process to be reused without having to duplicate a lot of code. Unlike a stamp, a function can take input values that are used by the function to generate its output.

    *A Quickstamp is a UI method for applying an (unsaved) action, and is run once on each selected note or agent applied via the Quickstamp Inspector. Quickstamps are ad hoc use of code and not saved after use. For re-usable code use a Stamp (above) instead.

    *An action can be invoked in ad hoc code in a call to action(), or via ^action()^ in an export context.

    *An ^action(some_code)^ export code allows inclusion of action code in an export template. The action code input some_code is executed when the template is evaluated.

    *A link action, set for all links of a given link type, is invoked when a link of that type is created (manually or via code). Essentially this is an 'OnLink' action. Note: there is no unlink action for when a link is deleted.

    OnAdd & Agent actions

    All containers and adornments apply an 'OnAdd' action (stored in $OnAdd) to items added to them. The action fires once only, on addition. If a note is removed from a container and then added back again, the OnAdd would fire again.

    Agents have the same mechanism for their child aliases, except is it is terms the agent action and stored in $AgentAction. Thus agents do not use $OnAdd, any code stored there is never used by the agent.

    The action can be one or more valid action code expression(s). Multiple actions need a semi-colon delimiter between them.

    The Action Inspector's Action tab's code is automatically stored in $AgentAction for agents and $OnAdd for all other types of note object.

    Rules

    A Rule is an action, much like an agent action, but while agents act on other notes a Rule acts on it own note (and only that note). If a rule is desired that only runs occasionally, consider using an edict instead

    Rules are actions attached to notes and containers. Agents may have rules.

    A note or agent's rule is stored in $Rule.

    Rules are run periodically, and change the note's attributes. For example, suppose we have a Boolean attribute called $Urgent. A note might have a rule

    $Urgent=any(children,$Urgent) 

    …meaning, "this note is urgent if any of its immediate children are urgent."

    Another rule might be

    $Urgent=$Urgent(parent) 

    …meaning, "this note is urgent if its parent is urgent."

    Given that rules run periodically, Tinderbox will eventually enforce each rule, although there may be a delay between a change made to one note and its impact throughout the document depending on the agent update (cycle) time, i.e. in complex TBXs the update time may be a little slower.

    Notice, too, that contradictory rules can be written; this may lead to constant changes in the document and should be avoided.

    Agents can have rules and this is especially useful for highlighting agents under specified circumstances (e.g. if $UrgentTasks is not empty, or if $ThingsToDo find more than seven tasks in your inbox).

    Like actions, rules may use simple arithmetic and logical expressions as well as action code functions.

    If there are a lot of rules running, especially if complex ones, it is a good idea to use a logical OR (|=) rather than a normal assignment (=). The |= method ensures the rule is only run if the left side equates as empty. An alternate solution is to use a Boolean 'guard' attribute and an if() test to ensure the running of the rule is controlled. This is a specimen such Rule:

    if($ShouldRun){$SomeAttribute=eval([some expression]);$ShouldRun=false} 

    Note how the rule only runs if $ShouldRun is true and that once the run is run, $ShouldRun is set to false. This allows for some other action or rule to reset $ShouldRun and allow the rule to run one more time.

    Rules can be disabled locally in a note using $RuleDisabled. The most common application of this is with prototypes where it is desired to run a rule in inheriting notes but not in the prototype itself.

    Editing $Text or Displayed Attribute values will cause the note's rule to be run.

    Edicts

    An edict is essentially a rule—in terms of scope—but one which is run very occasionally. It is akin to an agent set to a low priority. There is no priority control for edicts. They are designed for background work, i.e. housekeeping tasks that need to run occasionally but not often enough to have impact in the more pressing rules.

    A note or agent's edict is stored in $Edict.

    Edicts may be overridden locally in a note by using $EdictDisabled.

    A note's edict runs once when it is:

    • first created.
    • edited (practically, this means when selected).

    All edicts run once when:

    • a Tinderbox document is first opened.
    • roughly once an hour for the rest of the session (i.e. while the document remains open).
    • when File menu, Update Agents Now is clicked (i.e. both agents and edicts are refreshed once).
    • when the Run Now button on the Edict Inspector is pressed.
    • when the note's $Text or Displayed Attributes' values are changed. N.B. this misses a number of changes the user might assume are a trigger, but are not, although a little code review might offer a solution:
      • changes to attributes that are not Displayed Attributes. Consider: make the attribute a Displayed Attributes.
      • changes in other notes' attributes that this note might be checking/listing. Consider: shifting the action to the note being changed. Instead of a parent checking its children for changes, make the children update the parent if they change.
      • dynamic changes to in-doc links (i.e. auto-creation/deletion of links).

    Stamps

    Stamps were originally a method for storing action code to be invoked manually via the app UI (see below), the code being run on the currently selected item(s) in the view pane of the front document. If multiple items are selected, every item in the selection discretely has the same action code run upon it. As action code usage expanded, stamps could also be invoked via other actions, but the resulting action still only runs once per invocation.

    Stamps are stored as stamp notes within the built-in Hints container (the latter is not default content in a new TBX document). Each stamp note holds a single stamp's code. The title of the stamp note is the name of the stamp. Stamp names are case-sensitive.

    If there pre-existing stamps before the built-in Hints container is added, these stamps are automatically added as stamp notes. Stamps may be managed/edited either in stamp notes or in the Stamps Inspector. since the Hints container became available, this is the preferred mathod of adding/editing stamps.

    Stamps comprise one or more complete action(s) to be carried out when the code is called. The concept of a stamp allows easy (manual) application and re-use of such code.

    Stamps can be called by:

    • The Stamps menu.
    • The Stamps tab of the Document Inspector (use the 'Apply' button).
    • In action code via the stamp() operator.

    If stamps are just being used to easily apply a consistent look and layout to notes, consider using prototypes instead for the greater flexibility they offer when you subsequently need to make changes.

    If invoking a stamp via action code, the name of the stamp is used; the name is case-sensitive. Do not enclose it in quotes or Tinderbox will read it as a literal string (i.e. actual text). It must be terminated with a semicolon is followed by another action. However, it is a good idea in this particular case of always using s semi-colon to help indicate your intent to the app.

    Defined stamps with no code (a rare edge case when setting up a large document) will show in the Stamps Inspector but not in the Stamps menu.

    The stamp name may be enclosed in quotes; unquoted and quoted forms both work. For a stamp called 'A test', the action would be be:

    A test; 

    or

    "A test"; 

    The same stamp called, but here as one of 3 discrete expressions within an action:

    $Color="blue";A test;$Width=4; 

    Unlike editing attributes via a note's Displayed Attributes table or Get Info's attributes tab, altering an attribute via a stamp (or Quickstamp) does not alter $Modified.

    If a stamp changes the text, Tinderbox will immediately expand any ziplinks mark-up found in the revised text.

    When applying a stamp to a note that is on exactly one adornment, the designator 'adornment' implies that adornment. If the note is on several adornments, the designator 'adornment' reflects only one of those adornments (the front-most?).

    Stamps run from the Stamps menu (but not those run from the Inspector’s Apply button) show a progress bar when invoked. When using extremely slow stamps, this can help ensure that the stamp is completed before it is invoked again.

    Stamp Groups

    The Stamps menu supports hierarchical organisation of stamps. To group stamps, include a colon in the stamps title:

    Colour:red border 

    This will cause the Stamps menu to add a group named 'Colour' and with submenu for the groups members, e.g. 'red border'. This method allows organising groupings of related stamps without creating unwieldy menus. Stamps cannot be nested more deeply than in groups, i.e. 1 level of nesting. Use of more than one colon in the name causes the stamp to not list as part of a Group. Names are case-sensitive, so 'Colour Map:blue' and 'Colour map:green' would list in separate groups.

    Note that pre-existing stamp names containing colons will form their own group, with the second part of the original name as a sub-menu, but they otherwise work the same way.

    Stamps menu order

    The Stamps menu lists stamps in the order shown in the Stamps Inspector. Where a group occurs, it is listed where the first group member occurs in the Inspector List and within the sub-menu, the items are listed as in Inspector listing order. Grouped items do not need to be contiguous in the Inspector listing.

    Currently, although Inspector-created stamps are replicated in the /Hints/Stamps container, the ordering of both is independent; re-ordering in one location does not update it in the other. If differing, the order in the Stamps menu is that of the Inspector and not the Stamps container.

    Mouse actions

    From v11.6.0, map view (only) gains new mouse-based actions, each with an associated action-type attribute. 'Mouse' refers to ma view input via mouse or trackpad:

    • OnMouseDown ($OnMouseDown). OnMouseDown is invoked when the mouse is left-clicked in the body of a note.
    • OnMouseUp ($OnMouseUp). OnMouseUp is invoked when the mouse button is released.
    • OnMouseDrag ($OnMouseDrag). OnMouseDrag is invoked while the mouse is down if the mouse is moved and the note is locked. If $Lock is false, the note is repositioned in the normal way and OnMouseDrag is not invoked.

    These mouse actions bind two local variables when invoked.

    • The List-type variable modifierKeys contains a list of keys that were pressed when the mouse of clicked.
    • The Dictionary-type variable UI holds information about the click and its environment.

    Coloured syntax highlighting in Action code

    UI input boxes for action code fields can use syntax highlighting. This includes link actions (Links Inspector) and notes using the built-in 'Action' prototype.

    Coloured highlighting assist in spotting simple coding mistakes:

    • Double-quoted strings are red.
    • Single-quoted strings are orange.
    • Attribute references are purple.
    • Operators appear in light blue. The function operator is coloured blue but function names are not.
    • Comments appear in grey.
    • The variable 'var' command (and optional var type) in green. Note that variable names, including function inputs and loop variables are not coloured.
    • Conditional colour the 'if' light blue and the (optional) 'else' green.
    • Unmatched parentheses, brackets and braces are highlighted in yellow.

    Notes:

    • Nesting unmatched quotes, i.e. 2 doubles around a single or vice versa, will (may) cause part of that code expression within the overall action to be wrongly coloured. If correctly coded, this glitch (due to regex limitations) will not affect the functioning of the code.This does not affect
    • Code syntax highlighting of Action Code cannot be set by the user (i.e. by using custom highlighters). However, applying the Action prototype will enable code colouring in any note using that prototype.
    • Syntax highlighting will remove any pre-existing text colouring/highlighting. Font/font size are not affected.
    • Syntax highlighting should not be used at the same time as highlighters. If both are used, the outcome will be unpredictable. As the highlighter feature is intended for marking up general text, its use is inappropriate for action code syntax marking.

    Code notes and use of the action prototype

    For large sections of code, it has long been practice to store such code in a note using the built-in 'Code' prototype. However, if the code being stored is action code, e.g. a long/complex Rule, then using the Action prototype may be a better choice.

    If applying the 'Action' prototype to a pre-existing note and the $Text is not in already in a Monospaced font, it is a good idea to re-set the note font. Select the note and use menu Format ▸ Style ▸ Standard Font.

    Basic action code syntax

    Case sensitivity: Action code operators are always case-sensitive (unlike export codes).

    Delimiters. Each discrete code action (explained further below), must be terminated with a semi-colon. This acts like a full stop (or period) in normal text writing. Tinderbox, will run the first action up to the first-semi-colon, before moving on to the next and so on. An agent query (see below) is always a single code expression and never uses a closing delimiter.

    In action code, the delimiter can be omitted in two cases.

    Firstly, the code contains a single one action. Both these are valid code for the same action:

    $Color="red" 
    $Color="red"; 

    Secondly, and action is the last action in a multi-action piece of action code. Both these are valid code for the same action:

    $Color="red";$AccentColor="blue";$StartDate=date("now") 
    $Color="red";$AccentColor="blue";$StartDate=date("now"); 

    Note, in this second context, how all actions except the last one must have a semi-colon delimiter.

    Where multi-action code includes if() conditional sections, a delimiter must be placed after the closing '}' sholud other actions follow it. For instance:

    if($Prototype=="Event"){$StartDate=date("today")} 

    But:

    if($Prototype=="Event"){$StartDate=date("today")};$Color="red" 

    Note that the code inside the curly brackets does not need a delimiter as there is only one action. But, a further action follows the if() test so a delimiter is needed after the '}' that closes the if() action. Where there is an else branch, e.g. if(){}else{}, the delimiter goes after the '}' at the end of the else branch code inside the {} sections obeys the rules above and only needs delimiters between multiple actions.

    However, if in doubt, use a delimiter after each action!

    Agent Queries. These use action code, but use slightly different syntax that creates a single action code expression (see below) and queries never use a terminating delimiter. Tinderbox will generally not error if a trailing semicolon is used. But, a multi-expression query, with an inline semicolon, will likely not work correctly.

    Expression: this is a term for a section of action code that is not a complete action, as described further here.

    Coding conventions in Tinderbox. See more.

    Review old code: Longtime users of Tinderbox should revisit code to ensure all string literals are quoted as current support for non-quoted string usage is for legacy purposes and will be withdrawn; by convention paths and designators are not quoted but there is no harm if they are and quoting all strings may be an easier approach for new users to take. Likewise, new users trying old code samples should be aware that the code may use legacy syntax.

    Expressions vs. Actions in Action code

    Action code

    'Action code' is the overall name given to the use of actions, e.g. in automating Tinderbox, and to syntax rules defining valid actions. In use an 'action' may comprise one or more discrete actions, each one delimited by a semi-colon.

    An expression in Action code

    An 'expression' used in Action code is a combination of data and operators that tells Tinderbox how to compute a value. It is a way of calculating something or deriving a value based on existing information.

    Generally an expression can be evaluated to give a value.

    Scope of expressions vs. actions

    These examples show the relative scope of an expression vs. an action

    • An expression: 5+2; 
    • An action: $Width=5+2; 

    Note the difference. Whilst the expression generates a result, an action does something with the value. The implications of that are explored below.

    Using expressions in Action code

    Expressions are used within Tinderbox to define values, conditions, or other computations.

    5 + 2 
    2 * ($MyNumber + 3) 
    $Height(parent) * 1.5 
    ($Overdue |$ Essential) 
    $Width(/$Configuration) + 1) * $Scale 

    The result of an evaluation any of these, returns a value that can be used in current action code. At its simplest, even a literal string of text "Hello world" as it evaluates as the text value 'Hello world'.

    An action in Action code

    An 'action' in Tinderbox is a piece of code that performs a task. Actions are commands that tell Tinderbox to do something, such as setting the value of an attribute, changing the colour of a note, or creating links between notes. Here are the expressions above as complete actions.

    $MyNumber = 5 + 2; 
    $MyNumber = 2 * ($MyNumber + 3); 
    $MyNumber = $Height(parent) * 1.5; 
    $myDate = ($Overdue | $Essential); 
    $Width(/$Configuration)+1)*$Scale; 
    $MyString = "Hello world"; 

    More detail is given on the nuances of action code and expression in th the section below 'Actions and Expressions in more detail'.

    Choosing between eval() vs. action() operator use within actions

    In general use of action code it may not be possible to explicitly state or reference all values as they may be being created by the current code. Tinderbox thus offers two operators to assist with this challenge: eval() and action().

    eval(). Whilst most action operators evaluate their argument/inputs, complex expressions may need to the evaluated into a single value before they are usable via the calling operator. This is where eval() can be useful, in ensuring a value (rather than expression code) is passed to the next part of the code. Thus the point of eval() is to generate a value from an expression.

    action(). In contrast, there are occasions where the need it to run an action where part of the code need to be generated on the fly. For instance, having a list of attribute names but wishing to iterate the list and generate $-references to each attribute and assign it a value. Here is where action() is useful, but note that the code used must evaluate to a complete action().

    Although action() post-dates eval() as an operator by some years, and some old code examples may use eval() because that was all that was available at he time. Indeed, if trying to choose between the two, it is more likely the action() is the correct—or more easily used—choice, albeit each requiring a slightly different argument.

    A key point re use of action() is the it must contain the code text of a complete action—or code text plus variables that evaluate to such.

    In basic form, and assuming variable vText holds the string 'ReferenceTitle' and the value of $ReferenceTitle is 'Now We Are Six', the following might seem be the same:

    $Text = eval("$" + vText); → sets 'Now We Are Six'
    action($Text = "$" + vText); → fails

    when in fact the necessary syntax for the latter is

    action("$Text = $" + vText); → sets 'Now We Are Six'

    Why the difference? In the eval() case, '$'+vText' is literally '$'+'ReferenceTitle', and the eval returns the value of $ReferenceTitle. For the action() example, the evaluation occurs in two stages: first the value of vText is retrieved and then the overall string is executed as an action.

    If eval() fails where it feels it ought to work (i.e. there are no input errors, just a fail in context), using action() instead will likely work. But note that when swapping between eval() and action() use the argument needs to be altered to use an expression (for eval()) vs. an an action (for action()).

    Actions and expressions in more detail

    Normally, actions and stamps require an action: an assignment, or an if(), each(), or var() statement.

    Note than a stored action, e.g. a Stamp or Rule may comprise more than one action, is which case they are stored with a semi-colon after each action to enable the action code parser to detect each individual action in turn. The first action is completed before the next one is run, etc. These are both actions, they simply vary in the number of actions they contain:

    • A single action: $MyString = "Hello world"; 
    • A multiple action: $MyNumber = 4 * 2; $MyString = "Hello"; 

    White space or line breaks between multiple actions are ignored by the parser. Thus in practice, multiple actions are often written with each action on a separate line of code for the clarity to the human reader/user of the code.

    However, actions may be expression-like, in having no overt assignment which are evaluated for their side-effects. For example, "frogs".speak() is technically an expression, not an action, but if run (evaluated) in an action, the macOS will say the word "frogs".

    Most often, actions tend use simple arithmetic and logical expressions that are then passed to a left-side assignment. Operators in action code evaluate the arguments passed to them. Thus:

    $Text = capitalize("hello world"); 

    fetches the argument, here a literal string—which evaluates as itself—before capitalising it. Or, if we encode:

    capitalize("hello" + " " + "world"); the capitalize() operator first assembled the expression in the argument (i.e. to make 'hello world') before returning the capitalised version of the string. If $MyString contains "hello world", then:
    $Text = capitalize($MyString); 

    evaluates $MyString, capitalises that value and returns the result to $Text. Most action operator arguments are evaluated: cases where this is not so are generally explicitly documented.

    Dot operators use the output of the operator to which they are chained. If addition evaluation is needed, i.e. a previous output needs to be crystallised into a value before further use, the preceding operators can be placed in parentheses and the next dot operator chained to the closing parenthesis.

    Note the latter examples above the right-side involves more complex evaluation where extra parentheses are added to make explicit the evaluation order, as discussed further here.

    Single action, e.g. a rule, can have multiple expressions:

    $Color= "blue";$Badge="ok"; 

    Multiple expressions must be delimited by semi-colons. Line breaks between expressions are optional. They may aid legibility of code but have no effect on how the code is parsed.

    Because Tinderbox recognises operators such as + and -, notes whose names begin with characters other than letters and numbers may sometimes be interpreted in unexpected ways. For example, if a note is named "6*7", rules like

    $Prototype=6*7; 

    …might be parsed as a multiplication with the result of 42.

    $Prototype="6*7"; 

    …should have the expected effect. Quoting characters will always cause Tinderbox to treat such content as literal text.

    Actions and rules may use computation with data attributes, including attribute values from other notes. For example:

    $DueDate=date($DueDate(parent)+"7 days"); 
    $DueDate=date($ExpiryDate(parent)-"10 days"); 

    Date attribute values can also be computed with literal dates and date designators:

    $DueDate=date("November 15, 2004"+"7 weeks"); 

    This older style is deprecated (but works) as it is introduces scope for ambiguity in the evaluation of the code and the user's intent:

    $DueDate="November 15, 2004"+"7 weeks" Not recommended!

    In the previous examples note that the actual and partial date strings use quotes.

    Expressions in attributes

    To understand the role of expressions stored as attribute values, see Expression-storing attributes.

    Additional information

    See further discussion of expressions:

    Expressions in attribute offset addresses

    Many action code expressions designate a note, either by name, by path, or by object designators such as parent or prevSibling.

    An extension to the path mechanism allows you to replace the normal string literal used for note designation with an expression:

    $Color(7*6); ← the colour of the note named "42"
    $Color($Path); ← the colour of the note whose name is stored in the attribute "Path"

    In the case of ambiguity, expression evaluation has the lowest precedence. For example, if a note happens to be named "7*6", the reference will be resolved to that note, not to the note named "42".

    In actions, offset addresses in which the inner values is an expression are now supported. For example, where variable 'vMagicKey' holds he name of a dictionary key:

    $MyString = $Name(nextSibling($MyDictionary[vMagicKey]))

    The way nested designator expressions are handled might conceivably change the behaviour of previously-working code. A good refactoring is to unpack the nesting. Thus instead of:

    $Result = $Name(nextSibling(fComplexFunction($MyString))); 

    consider:

    	var:string vPath=fComplexFunction($MyString); 
    	$Result=$Name(vPath);
    
    
    Stand-alone action code expressions

    Actions may include stand-alone expressions, that is expressions without an assignment (to a 'left side' object) or if() clause. A stand-alone expression cannot change any attributes but a few expressions have useful side-effects, including use of the runCommand, linkTo, linkFrom, unlinkTo, and unlinkFrom operators.

    In fact, such operators do return a value but it is a true/false success report boolean. As such output is generally of no practical use, this saves the need for adding a user attribute simply to run this type of operator. But, should the success state be necessary for a following action, the result can be assigned to a left-side boolean attribute:

    $MyBoolean = runCommand(.... 

    or, encapsulate the to-be-tested code in an if() operator.

    User functions are another case. An action expression may simply be a call to a function. The evaluated expression (action code) results in the function running. The overall effects of that reflect the code in the function, but are unrelated to the calling action save for the fact that if the overall action has multiple actions, later actions will not be run until the function has completed.

    The action() function makes it easier to execute standalone code expressions.

    Left side expressions

    Group designators may be used to assign a value to the attributes of several notes at once. For example, the $Rule:

    $Color(children)="red"; 

    turns all the current note's children to red.

    In fact, the simplest self assignment:

    $Color="red"; 

    is a short form of:

    $Color(thisn)="red"; 

    So left side expressions should not seem unusual, although they were not supported in very early versions of Tinderbox.

    Designators may also be lists of notes, either explicit literal string list:

    $Color(/config/one;/config/two)="red"; 

    or implicitly computed via a find():

    $Color(find($Price>5))="red"; 
    $Color(find($Color=="red"))="red"; 

    or implicitly computed by an expression enclosed in quotation marks:

    $Color("collect_if(all, $Price > 5, $Path)")="red"; 
    $Color("collect_if(all, Color == 'red', $Path)")="blue"; 

    In the last example note the need for nested single and double quotes.

    Basic Comparison Operators

    Queries are used by agents, and as conditional action code expressions in some action code operators. They support 6 basic boolean comparison operators:

    • ==. Equals. (See below re == and comparing dates.
      • Note: a single '=' usage is supported for legacy code purposes but is strongly deprecated in v4.6+.
    • !=. Does not equal. The macOS-specific ≠ symbol may be used interchangeably with !=.
    • >. Greater than.
    • <. Less than.
    • <=. Less than or equal to. The macOS-specific ≤ symbol may be used interchangeably with <=.
    • >=. Greater than or equal to. The macOS-specific ≥ symbol may be used interchangeably with >=.

    Comparing Date-type data

    When working specifically with Date-type values, some special variations of outcome occur.

    Using the == and != operators. Queries regard two dates as being equal if they share the same year, month, and day, regardless of the time of day. This allows for useful agent queries that use the == equality operator.

    (Legacy note: in early app releases, equality looked only for identical time stamps, which was rarely what users expected).

    For all other comparison types. Here the time element of date-time attribute's value is taken into account. Where no explicit time is set, the time defaults to '00:00' (hh:mm). Seconds are not displayed in Displayed Attributes or Get Info. Seconds are '00' in most cases unless specifically set otherwise (via action code or use of designators link 'now').

    To test the exact equivalence of date-time attribute values use interval() where an exact match returns the string "00:00".

    if(interval($DateA,$DateB)=="00:00"){… 

    Note that the comparison operators >, >=, < and <= continue to compare both date and time. It is possible, for example, for the same note to be discovered by two agents with different query operators, one that locates $TheDate < today and another that searches for $TheDate == today. If the $TheDate has a time of 14:30 and today has a time of 11:00 then both queries will match; the first matches simple on a time agnostic whole-day basis, the second matches because 14:40 is later (greater) than 11:00.

    The date parser accepts the following terms as placeholders for calculated dates (within quoted string literals):

    • yesterday
    • today
    • now
    • tomorrow
    • day
    • week
    • month
    • year

    There is a further special case:

    • never. No date, and treated as earlier or later than any real date.

    Day placeholders Sunday, Monday, etc., may be used. Tinderbox recognises the day of the week (in English, currently) and interprets it as the day after today with that week day. Thus, on Sunday June 1, the date placeholder "Sunday" refers to Sunday, June 8.

    In other respects, days of the week act like today and can be modified similarly, e.g. "Monday - 1 week" evaluates as the previous Monday.

    Parentheses (rounded brackets) can be used to indicate a hierarchy of resolution:

    ($Cost > (450 * $Margin)) & ($Priority == "High") 

    The code in parentheses is resolved before the '&' join is made.

    Query comparison operations will accept action code expressions on their right-hand side. This is legal syntax: $Width > ($Height * 2) 

    Equals (is the EXACT equivalent of)

    $Attribute == $OtherAttribute

    The double-equals (==) usage for tests of equality replace older use of a single equals sign.

    Legacy use of single '=' for comparison

    Previously, a single equals sign acted as either an assignment of the right side to the left or as an equality operator, Tinderbox deciding which form to use depending on context. A single equals sign is used for assigning values only and not for testing equality.


    $BooleanAttribute == true

    Matches notes whose $BooleanAttribute value is true.

    For other data types, testing for the presence of a value can be considered a boolean test. This is useful as queries and if() clauses use a 'condition' which must resolve as true or false.


    $ColorAttribute == color("data")

    The data needs to be a string that matches $ColorAttribute case-sensitively.

    Named colours matching hex values will be match and the case of hex values is ignored. Thus color("#0000ff") matches color("#0000FF") and color("bright blue"). But none of those would match color("Bright Blue"), unless of course it too had been defined with the same hex equivalent of #0000ff.

    Note that Tinderbox's pre-defined named colours are all-lowercase, and that hexadecimal colour codes created via the colour picker use lower case for any letter characters.


    $DateAttribute == date("aDate")

    $DateAttribute == "aDate" <— Deprecated, do not use

    In tests of date equality, the time element of a date/time is ignored. In other words the granularity of test is for the dates being on the same calendar day.

    $DateAttribute == date("aDate")

    $DateAttributeA == $DateAttributeB

    true where $DateAttribute date matches the given aDate's calendar day

    $DateAttribute == date("today"). true where $DateAttribute date is today's date (same calendar day).

    $DateAttribute == date("yesterday"). true where $DateAttribute date is yesterday's calendar day.

    $DateAttribute == date("tomorrow"). true where $DateAttribute date is tomorrow's calendar day.

    $DateAttribute == date("never"). true if there is no date. Note, 'never' is not < any date, nor is it > than any date, but it is equal to 'never'. Atypically, this null value is both older than the oldest set date and newer than the most recent set date; thus 'never' is earlier or later than any real date. When agents search for a specified time range, the comparison operators < and > treat the value 'never' specially.

    To search for a note with a valid date/time, it might seem logical to use $DateAttributeA > "never". No! The correct test is $DateAttributeA != "never".

    The operators '<=' and '>=':

    $DateAttributeA >= $DateAttributeB

    $DateAttributeA <= $DateAttributeB

    also return true if the dates are on the same calendar day (because the '=' part of these operators are a '==' equality test).


    $NumberAttribute == number

    This is true where $NumberAttribute value equals the given number. Note the number value is not quoted.


    $ListAttribute == "data"

    Note: Tinderbox does not perform meaningful equality comparisons on List-type attributes.

    A match only occurs if data matches all values in the list. Thus if the list value is [dog;cat] and the data string is "dog", the result is false. If the string is "dog:cat" the result is true; a successful match also occurs for "cat;dog".

    It can be seen that data is parsed for all values but that a true result is only achieved if all values match, whereas the likely intention of the user is to see if data matches one, or more, list values.

    Lists are best compared for a pattern—either a literal string or regular expression—using:

    • for matching only complete individual list values: the List.contains("regex") action operator.
    • for regex partial matches: coerce the Set values to a String, and use String.contains("regex").

    $SetAttribute == "data"

    Note: Tinderbox does not perform meaningful equality comparisons on Set-type attributes.

    A match only occurs if data matches all values in the set. Thus if the set value is [dog;cat] and the data string is "dog", the result is false. If the string is "dog:cat" the result is true; a successful match also occurs for "cat;dog".

    It can be seen that data is parsed for all values but that a true result is only achieved if all values match, whereas the likely intention of the user is to see if data matches one, or more, set values.

    Sets are best compared for a patterneither a literal string or regular expression—using:

    • for matching only complete individual list values: the Set.contains("regex") action operator.
    • for regex partial matches: coerce the Set values to a String, and use String.contains("regex").

    $StringAttribute == "data"

    True where $StringAttribute value is identical to the data string. For instance:

    $Text == "Hello" 

    …would be true if the note's text consisted only of the word "Hello".

    Note the data string is must be quoted (it may work without quotes but do not rely on that!).

    Does Not Equal

    $Attribute != $OtherAttribute

    $Attribute ≠ $OtherAttribute

    This uses the negative equivalent test to the double-equals (==) usage for tests of equality.

    Note that, when parsing queries, the template is evaluated in the agent's context. In particular, attribute references on the right side of the test are made to the agent and this refers to the agent. Conversely, in actions, on the other hand, the action is evaluated in the context of the note to which it is applied.

    Using the '!=' syntax rather than '≠' is recommended if content is to exported to the web as not all fonts include the latter special character; the Unicode address simply says where a glyph is stored in the font, it does not dictate whether it exists in a given font.


    $BooleanAttribute != false

    (!$BooleanAttribute) == false

    !$BooleanAttribute == false (do not use this form)

    Matches notes whose BooleanAttribute value is true.

    For other data types, testing for the presence of a value can be considered a boolean test. This is useful as queries and if() clauses use a 'condition' which must resolve as true or false.

    Note the alternative (!action) syntax in the second example above and its use of parentheses. Omitting these and simply pre-pending an exclamation mark to the attribute being tested may work but is deprecated in favour of use of parentheses as this helps Tinderbox to parse correctly the user's intent.


    $ColorAttribute != color("data")

    The data needs to be a string that matches $ColorAttribute case-sensitively.

    Named colours matching hex values will be match and the case of hex values is ignored. Thus color("#0000ff") matches color("#0000FF") and color("bright blue"). But none of those would match color("Bright Blue"), unless of course it too had been defined with the same hex equivalent of #0000ff.

    Note that Tinderbox's pre-defined named colours are all-lowercase, and that hexadecimal colour codes created via the colour picker use lower case for any letter characters.


    $DateAttribute != "aDate"

    In tests of date inequality, the time element of a date/time is ignored. In other words the granularity of test is for the dates not being on the same calendar day.

    $DateAttribute != date("aDate")

    True where $DateAttribute date does not match the given aDate's calendar day.

    $DateAttribute != date("today"). true where $DateAttribute date is not today's date (same calendar day).

    $DateAttribute != date("yesterday"). true where $DateAttribute date is not yesterday's calendar day.

    $DateAttribute != date("tomorrow"). true where $DateAttribute date is not tomorrow's calendar day.

    $DateAttribute != "never". As never is 'no date', this is effectively a test that a value exists for the attribute. Note, 'never' is not < any date, nor is it > than any date, but it is equal to 'never'.


    NumberAttribute != number

    or

    Gathers all notes whose NumberAttribute value do not equal the given number.

    Using the '!=' syntax rather than '≠' is recommended if content is to exported to the web as not all fonts include the latter special character; the Unicode address simply says where a glyph is stored in the font, it does not dictate whether it exists in a given font.

    Note that the usage '<>' is not a valid method in Tinderbox for asserting inequality.


    $ListAttribute != "data"

    Note: Tinderbox does not perform meaningful equality comparisons on List-type attributes.

    A match only occurs if data matches all values in the list. Thus if the list value is [dog;cat] and the data string is "dog", the result is false. If the string is "dog:cat" the result is true; a successful match also occurs for "cat;dog".

    It can be seen that data is parsed for all values but that a true result is only achieved if all values match, whereas the likely intention of the user is to see if data matches one, or more, list values.

    Lists are best compared for a patterneither a literal string or regular expression—using:

    • for matching only complete individual list values: the List.contains("regex") action operator.
    • for regex partial matches: coerce the Set values to a String, and use String.contains("regex").

    $SetAttribute != "data"

    Note: Tinderbox does not perform meaningful equality comparisons on Set-type attributes.

    A match only occurs if data matches all values in the set. Thus if the set value is [dog;cat] and the data string is "dog", the result is false. If the string is "dog:cat" the result is true; a successful match also occurs for "cat;dog".

    It can be seen that data is parsed for all values but that a true result is only achieved if all values match, whereas the likely intention of the user is to see if data matches one, or more, set values.

    Sets are best compared for a patterneither a literal string or regular expression—using:

    • for matching only complete individual list values: the Set.contains("regex") action operator.
    • for regex partial matches: coerce the Set values to a String, and use String.contains("regex").

    $StringAttribute != "data"

    This is true where StringAttribute value is identical to the data string. For instance:

    $Text != "Hello" 

    …would be true if the note's text consisted of something other than just the word "Hello".

    Note the data string is must be quoted (it may work without quotes but do not rely on that!).

    Greater Than

    $DateAttribute > "date"

    Gathers all notes whose $DateAttribute value is after the given date. The left-side date cannot be more than 'never'.

    WARNING: unlike an equals comparison the time element of the date/time is used. If $DateA is 28 November 2012 21:00:00 and $DateB is 28 November 2012 12:00:00 then:

    $DateA < $DateB is false 

    whilst

    $DateA == $DateB is true 

    This is because the former takes time into account and the latter does not. Also:

    $DateA <= $DateB is true 

    Here the implicit equality test (ignoring time) will trump the time-sensitive < test. In <=, it is effectively doing an OR join, i.e. the result is true if:

    $DateA < $DateB is false 

    $NumberAttribute > number

    Gathers all notes whose $NumberAttribute value is greater than the given number.


    Other data types…

    Boolean. A true is always greater than true (reflecting the fact the coerce to the values '1' and '0' respectively).

    Color. Tinderbox does not perform greater/less than comparisons on Color-type attributes.

    Sets/Lists. Tinderbox does not perform greater/less than comparisons on Set-type and List-type attributes.

    String. A lexical comparison is done of each string character by character, i.e. the ASCII value of each first character, then each second character, etc. Uppercase characters < lowercase < numbers. For other characters, accents, etc., comparisons are likely to not meet linguistic expectation as the values will be based on Unicode sort order. Thus:

    "dog" > "cat"
    "dog" > "Dog"
    "dogs" > "dog"
    "dogs" > "dogma"
    "dogs" < "døg" <-- NOTE!
    Greater Than Or Equal To

    $DateAttribute >= "date"

    $DateAttribute ≥ "date"

    Gathers all notes whose $DateAttribute value is on or after the given date. The left-side date cannot be more than 'never'.

    Because this test is effectively ((A > B) | (A ==)), the equality test means the time part of the date time is ignored, unlike with a plain 'greater than' test.

    Using the '>=' syntax rather than '≥' is recommended if content is to exported to the web as not all fonts include the latter special character; the Unicode address simply says where a glyph is stored in the font, it does not dictate whether it exists in a given font.

    Depending on the granularity required, it may be necessary to use a two-term query for date comparisons.


    $NumberAttribute >= number

    $NumberAttribute ≥ number

    Gathers all notes whose $NumberAttribute value is greater than or equal the given number.

    Using the '>=' syntax rather than '≥' is recommended if content is to exported to the web as not all fonts include the latter special character; the Unicode address simply says where a glyph is stored in the font, it does not dictate whether it exists in a given font.


    Other data types…

    Boolean. A true is always greater than true (reflecting the fact the coerce to the values '1' and '0' respectively).

    Color. Tinderbox does not perform greater/less than comparisons on Color-type attributes.

    Sets/Lists. Tinderbox does not perform greater/less than comparisons on Set-type and List-type attributes.

    String. A lexical comparison is done of each string character by character, i.e. the ASCII value of each first character, then each second character, etc. Uppercase characters < lowercase < numbers. For other characters, accents, etc., comparisons are likely to not meet linguistic expectation as the values will be based on Unicode sort order. Thus:

    "dog" > "cat"
    "dog" > "Dog"
    "dogs" > "dog"
    "dogs" > "dogma"
    "dogs" < "døg" <-- NOTE!
    Less Than

    $DateAttribute < "date"

    Gathers all notes whose $DateAttribute value is before the given date. The left-side date cannot be less than 'never'.

    WARNING: unlike an equals comparison the time element of the date/time is used. If $DateA is 28 November 2012 09:00:00 and $DateB is 28 November 2012 12:00:00 then:

    $DateA < $DateB is true 

    whilst also

    $DateA == $DateB is true 

    This is because the former takes time into account and the latter does not.


    $NumberAttribute < number

    Gathers all notes whose $NumberAttribute value is smaller than the given number.


    Other data types…

    Boolean. A true is always greater than true (reflecting the fact the coerce to the values '1' and '0' respectively).

    Color. Tinderbox does not perform greater/less than comparisons on Color-type attributes.

    Sets/Lists. Tinderbox does not perform greater/less than comparisons on Set-type and List-type attributes.

    String. A lexical comparison is done of each string character by character, i.e. the ASCII value of each first character, then each second character, etc. Uppercase characters < lowercase < numbers. For other characters, accents, etc., comparisons are likely to not meet linguistic expectation as the values will be based on Unicode sort order. Thus:

    "dog" > "cat"
    "dog" > "Dog"
    "dogs" > "dog"
    "dogs" > "dogma"
    "dogs" < "døg" <-- NOTE!
    Less Than Or Equal To

    $DateAttribute <= "date"

    $DateAttribute ≤ "date"

    Gathers all notes whose $DateAttribute value is before or on the given date. The left-side date cannot be less than 'never'.

    Because this test is effectively ((A < B) | (A ==)), the equality test means the time part of the date time is ignored, unlike with a plain 'less than' test.

    Using the '<=' syntax rather than '≤' is recommended if content is to exported to the web as not all fonts include the latter special character; the Unicode address simply says where a glyph is stored in the font, it does not dictate whether it exists in a given font.

    Depending on the granularity required, it may be necessary to use a two-term query for date comparisons.


    $NumberAttribute <= number

    $NumberAttribute ≤ number

    Gathers all notes whose $NumberAttribute value is smaller than or equal to the given number.

    Using the '<=' syntax rather than '≤' is recommended if content is to exported to the web as not all fonts include the latter special character; the Unicode address simply says where a glyph is stored in the font, it does not dictate whether it exists in a given font.


    Other data types…

    Boolean. A true is always greater than true (reflecting the fact the coerce to the values '1' and '0' respectively).

    Color. Tinderbox does not perform greater/less than comparisons on Color-type attributes.

    Sets/Lists. Tinderbox does not perform greater/less than comparisons on Set-type and List-type attributes.

    String. A lexical comparison is done of each string character by character, i.e. the ASCII value of each first character, then each second character, etc. Uppercase characters < lowercase < numbers. For other characters, accents, etc., comparisons are likely to not meet linguistic expectation as the values will be based on Unicode sort order. Thus:

    "dog" > "cat"
    "dog" > "Dog"
    "dogs" > "dog"
    "dogs" > "dogma"
    "dogs" < "døg" <-- NOTE!

    Compound Actions

    Compound actions are just like simple actions but each action is separated by a semicolon:

    Action: $Color="red";$Priority="high" 

    Sometimes, this leads to complications. Suppose, for example, you want an action to set the $OnAdd action. (Perhaps you have an agent that's looking for containers of $UrgentTasks, and wants to set the $OnAdd action for those containers). The simplest way of writing this is:

    Action: $OnAdd=$Color="red";$Priority="high" 

    …which will do two things: set the $OnAdd action to "$Color=Red" and set the $Priority to high.

    If you want the $OnAdd action to be set to the action code and ont its, enclose it in quotes:

    Action: $OnAdd="$Color=red;$Priority=high"

    The square bracketed style is also required if setting multiple $DisplayedAttributes values (or any List or Set-type attribute).

    Action: $DisplayedAttributes=[Color;Name;Rule]
    Action: $DisplayedAttributes= $DisplayedAttributes(parent) + [Border;AccentColor]

    Previously, the latter used quoted strings but this is now deprecated.

    Conditional statements using multiple arguments

    If() conditional statements and queries may use more than one argument using logical joins. See AND and OR join syntax.


    ( A & B )

    Reads: if condition A AND condition B are true, then this compound query is true.

    Contrast this with the &= operator (below).


    ( A &= B )

    Reads: result is true if condition A is currently true and, if so, if condition B is also true.

    Thus, if condition A is false, condition B is not checked and the overall result is false. Thus in some cases only condition A is evaluated.

    By comparison, with a ( A & B ) query both condition A and condition B are always evaluated.


    ( A | B )

    Reads: if condition A OR condition B is true, then this compound query is true.

    Contrast this with the |= operator (below).


    ( A |= B )

    Reads: result is true if condition A is currently true or, if so if condition B is true.

    Thus, if condition A is false, condition B is not checked and the overall result is false. Thus in some cases only condition A is evaluated.

    By comparison, with a ( A | B ) query both condition A and condition B are always evaluated.


    (A | B) & ( C | ( D | E ) )

    This is a more complex example of logical joins. Reads: if (condition A OR condition B is true) AND (condition C OR (either condition D OR condition E are true)), then this compound query is true.

    Defining an 'item' object—a single item—in action code

    The term 'item' is not a Tinderbox definition but is useful in the context of discussing action code and documenting action code usage.

    Where an argument is defined as item scope this means it returns one and only one object (as compared to a group scope). If more than one item is returned where only one is desired, e.g. from a find() query) Tinderbox will use only the first item of the list, by ascending $OutlineOrder, as the specified item; the same holds for an action code expression that evaluates with an ambiguous result. It thus makes sense to avoid such ambiguity and ensure the query is sufficiently scoped to return only one match. The overall point is that whether using a string literal value (i.e. just stating a name) or using an action code expression, the outcome must evaluate to provide Tinderbox with a reference to a single note.

    A single note 'item' can be referenced as:

    • A note's title (its value for $Name).
    • A notes's path (its value for $Path). This is useful if the note's name is not unique.
    • (less commonly) A note's ID ($ID). This is less usual but can be useful if there are problematic characters in the title or path, especially if using (un)linking actions.
    • An item-scope note designator, e.g. 'parent' or 'firstSibling'. Designators return, $Path data for the matching object.
    • A query function, e.g. find(), collect(), collect_if(), links(). The query must resolve to a single note item. Query functions return $Path data for the matching object.
    • An action code expression, i.e. that evaluates as any of the above. Complex expressions may require use of parentheses and/or use of eval() to help Tinderbox understand the order of evaluation and to deal with encapsulated evaluations.
    • A string attribute value that is an action code expression or a literal title/path.
    • A discrete value in a list attribute that is an action code expression or a literal title/path.
    • A literal string, e.g. "This note".

    Defining 'group' list objects—one or more items—in action code

    The term 'group' is not a Tinderbox definition but is useful in the context of discussing action code and documenting action code usage.

    A group is a list of one or more Tinderbox note items (q.v.). A group can be referenced as:

    • A list of note titles ($Name).
    • A list of note paths ($Path). This is useful if any note's $Name value is is not unique.
    • (less commonly) A list of note IDs ($ID). This is less usual but can be useful if there are problematic characters in the title or path, especially if using (un)linking actions.
    • A group-scope note designator, e.g. 'all' or 'children'. Designators return $Path data for the matching objects.
    • A query function, e.g. find(), collect(), collect_if(), links(). The query must resolve to a list of one or more note items. Query functions return $Path data for the matching objects.
    • An action code expression, i.e. that evaluates as any of the above.
    • A string attribute value that is an action code expression or a literal title/path.
    • A discrete value in a list attribute that is an action code expression or a literal title/path.
    • A literal list, e.g. [This note;That note]. (Previously, and now deprecated, was to use a quote-enclosed list)

    See also the article on items.

    Note: In the linkedTo() and linkedFrom() query terms the "*" designator replaces the "all", presumably for legacy purposes.

    Why is a text 'line' in action code actually a paragraph?

    To the lay person, a 'line of text' is a line as seen on the page or screen, i.e. from the left margin to where the text stops at the right margin. Thus a long sentence may 'wrap' onto a new, different, line so as to remain visible to the reader.

    For instance, as currently drafted in the author's TBX file, the text above comprises two sentences wrapped onto three lines (for display purposes). It is also only one paragraph of text.

    Importantly, it is the latter definition of a 'line'—i.e what we more normally think of as a discrete 'paragraph'—that must be understood as 'line' when using action code text operations. To clarify, from a code perspective the discrete lines within a String of textual data are most easily understood as:

    • the run of characters from the text's start to the first line break character,
    • then each run of characters between a pair of successive line break characters within the text,
    • plus the run of characters after the last line break character up to the text's end.

    Therefore for action code use, this article is seven 'lines' of text (each bullet is effectively a paragraph), even though it may display as many more lines when read in the TBX file or ints output web pages.

    Explicit declaration of lists using square brackets

    NOTE: in this article 'list' refers to use in both List and Set type data.

    The List (or Set) operator: declaring lists using literal values

    This explicitly converts a String to a List. That used to be important, but the introduction of typed local variables makes these unnecessary in many cases.

    The preferred usage is for declaring lists (List or Set) is [… ]

    A List or Set is declared using enclosing square brackets and without enclosing quotes:

    var:list vList = [peach;orange;apple]; 

    Deprecated: in the past, defining literal list values involved using a quote-enclosed semicolon delimited list:

    var:list vList = "peach;orange;apple"; 

    N.B. Both forms work equally well—at least for now.

    However, the bracket-enclosed method is now the preferred syntax for writing list in new code. In due course aTbRef will update most examples to the newer format.

    Declaring Nested lists

    The new form of list definition also allows declaration of nested lists:

    	var:list vMatrix = [[0;1;2];[3;4;5];[6;7;8];[9;10;11]];
    	$Text = vMatrix[1];

    This returns the result, [3;4;5], i.e. a List-type value containing a 3-item list.

    Nested lists and Zip-method linking

    Typing the syntax for nested links can involve character sequences like [[ and ]] which are other wise use with the 'zip' method of making Tinderbox links. the latter can be suppressed for the current note by altering the $Ziplinks system attribute.

    Strings In Lists

    Take caution mixing quotes and square brackets:

    var:list vList = ["peach;orange;apple"]; → single item list

    This creates a list with one element: the string "peach;orange;apple". This is needed very occasionally, e.g. for a string value legitimately needing to hold a semi-colon, such as might occur when doing manipulation of $Text content. If inspecting the list value in Displayed Attributes or Get Info/attributes, such a string list value is easily spotted as it is enclosed in the 'raw' list value using double quotes. This is a four-item list with a single 'string' item value as the third list item.

    [rock;eel;"peach;orange;apple";monkey] 

    By comparison:

    var:list vList = "[peach;orange;apple]"; → three item list, but see next example...

    In fact, the latter is a redundant form of the new bracketed declaration:

    var:list vList = [peach;orange;apple]; 

    but which might be typed in error by someone more used to the original from of defining a list.

    The list() operator

    Occasionally, it may be necessary to declare a list from evaluated action code expressions. The list() operator is used for that task.

    Evaluation of [] list terms

    Implicit evaluation is no longer performed in bracketed lists. For example,

    $DisplayedAttributes=[MyList;MyString]; 

    is now equivalent to

    $DisplayedAttributes="MyList;MyString"; 

    If list terms need evaluation, use list() instead.

    Explicit declaration of dictionaries using curly braces

    The Dictionary operator

    This explicitly converts a String to a Dictionary. That used to be important, but the introduction of typed local variables makes these unnecessary in many cases.

    The preferred usage is for declaring Dictionaries is using {… } rather than the previous dictionary() operator. Thus:

    var:dictionary vDict = {English:I; Latin: ego}; 

    replaces both these existing methods—though they still work (the quoted string version already bing deprecated):

    var:dictionary vDict="English:I; Latin: ego"; 
    var:dictionary vDict=dictionary("English:I; Latin: ego"); 

    Nested Lists in Dictionaries

    The square-bracket List declaration can be used to define multi-item key values

    var:dictionary vDict = {Apple:[red;green];Lemon:yellow}; 

    Calling Dictionary keys

    By preference, dictionary keys should not be quoted though for legacy reasons either form will still work:

    	$MyDictionary = {Latin: "ego"; English: "I"};
    	// Preferred form
    	$MyValue = $MyDictionary[Latin];
    	// and not
    	$MyValue = $MyDictionary["Latin"];
    	// though *both* forms work is only for legacy support

    The Order Of [Dictionary].keys

    Tinderbox dictionaries currently depend on AppKit’s NSDictionary, which appears to use a hash to order its keys. So, the (number) order is arbitrary, i.e. calling a value using $MyDictionary[N] is not recommended.

    Punctuation and special characters in definitions, actions and expressions

    In short, what is the meaning of brackets (parentheses, square or curly)? What to they do and what are they called. These are explained in the articles below.

    This is a topic that is difficult to describe easily for all readers as the perspective and vocabulary used by different users will vary. Notably, those who have formal programming training may differ from most others. This note is written with the latter in mind, as they do not have any formal grounding upon which to fall back. Thus for some readers, terminology may vary from that they might otherwise use, but here it is consistent within aTBRef and in Tinderbox use.

    A number of non-letter characters described here can have varying names depending on locale (even amongst English speakers) and field of study or experience. There are 4 types of brackets and in the listing below the name used in this section of the documentation is the one in italics:

    • ( ). Variously: brackets, round brackets or parentheses.
    • [ ]. Variously: brackets, square brackets, crochets.
    • { }. Variously: curly brackets, braces.
    • < >. Angle brackets. These are not used in action code. However, the same characters are used individually as mathematical operators for 'less-than' and 'more-than'.

    Also be aware that the meaning of a 'line' of text is different in action code to the convention of the printed page.

    More on specific usages of differing types of non-letter characters in code:

    Semicolon: action delimiter, code line end

    Semicolons are used in action code to separate discrete actions, i.e. discrete whole tasks (as opposed to expressions). A desired outcome may use one such action or several.

    $Color = "blue'; $Badge = "ok"; 

    General practice is to place each action on a new line within the overall action code , so semicolons are most often seen as line-ends in code.

    $Color = "blue'; 
    $Badge = "ok"; 

    The last action in code comprising multiple actions doesn't require a semicolon end but no harm comes from doing so.

    $Color = "blue'; $Badge = "ok"; 

    Thus for the novice a good rule of them is to always end lines of code with a semicolon.

    An exception is code lines ending with an opening curly bracket—see why.

    Failure to use a semicolon where needed will result in a silent failure of all or part of the action.

    Semicolon: list and dictionary item delimiter

    Where attribute values can have multiple values, a semi-colon is used as a 'delimiter' between each item and optionally after the last item. Multi-value data types include:

    List:

    $MyList = [car;train;boat;plane;boat]; 

    Set:

    $MySet = [car;train;boat;plane;boat]; (here value boat will be de-duplicated and the list sorted in the resulting Set), i.e. [boat;car;plane;train].

    Dictionary:

    $MyDictionary = {car:weels;truck:wheels;train:rails}; 

    Note in the case of a dictionary, the list is one of key:value pairs.

    Colon: dictionary key-value pair delimiter

    In a Dictionary type, data, consists of a semicolon delimited list of keys and their values. For each such list item, the key and its value are separated by a colon. Generically:

    dictionary("key:value; key:value"); 

    Thus, in current form:

    $MyDictionary = {apple:fruit;pear:fruit;pea:vegetable}; 

    and old form (both forms work):

    $MyDictionary = dictionary("apple:fruit;pear:fruit;pea:vegetable"); 

    Noting that whitespace in the dictionary data either side of colons and semicolons is ignored, but not within a key name or value. Keys ideally should be a single word:

    Colon: ad hoc delimiter in some action operators

    In a small number of operators, a colon is used instead of other more normal delimiters and joins.

    In some of the operators relating to composites, a colon is used where a dot-operator type of dot-join might be expected:

    In the stream processing group of operators, Stream.eachLine(loopVar[:condition]){actions} uses a colon where a comma argument delimiter might normally be expected.

    Dollar-sign prefix: attribute references

    When reading from/writing to attributes in action code the desired attribute is 'referenced' by using a $-prefix to the attribute name thus:

    $MyString 

    and not

    MyString 

    Why so? Adding the $-prefix helps signal to Tinderbox that the user is referring to a specific attribute and not literal text, or an action code operator, or a user function, or a user variable of the same name.

    Note on legacy use

    The above holds true except for in the very early Tinderbox days, when the application would figure it out. But as action code has grown in complexity over the years it makes sense to signal user intent to the action code parser and so whilst omitting the $-prefix may still work it is formally deprecated since version 4.5.0.

    Dollar-sign prefixed numbers: query back-references

    Regular expressions used in queries can create up to 10 back-references expressed as $9 through $9. Such codes are discussed in detail here.

    Dollar-sign prefixed numbers: macro arguments

    Macros can be used in both action and export code. Within the macro's stored code, calling argument values are inserted using a $-number that reflects the sequence number of the argument supplied in calling code.

    Consider a macro named "Hello" that has this stored code:

    "Hello $1!" 

    When using the 'Hello' macro in code, it is called like this:

    $MyString = do("Hello","Cubert")); 

    which inserts the argument value 'Cubert' into the macro code at the position $1. The result is the output of the macro passed to $MyString is "Hello Cubert!".

    See more on macros and do().

    Parentheses: attribute 'offset' references (offset addressing)

    Referring to attributes of the current note

    In action code, when calling the value of an attribute the value returned is for the current note. In most normal cases this is the note currently selected in the view (or the first item in the selection for a selection of notes). Getting the colour of the current note is coded like so:

    $Color 

    So it could also be written as:

    $Color(this) 

    as in specifying 'this' note. But, here the explicit use of the this designator is redundant, as is coding the action as:

    $Color() 

    All the above 'mean the same thing to the Tinderbox action code parser, but the first example is the normal usage. The value returned is the value set for that note, or an inherited value. Inheritance of attribute is discussed separately, here. The syntax above is used for both reading and setting values:

    $MyColor = $Color; 
    $Color = "blue"; 

    Addressing (referring to) attributes of the current note

    But what if there is a need to fetch a value of the same attribute, but from a different note? That is where those trailing parentheses come into play. To fetch the value of $Path for a note called "Prospects", the note title of target source note for the value—its $Name—is given as an argument inside the parentheses:

    $Color("Prospects") 

    Note it is the same as for the current note but extra information is now supplied in parentheses directly after the attribute name:

    $Color("Prospects") Correct

    Do not use white space between the name and opening parenthesis:

    $Color ("Prospects") WRONG

    The same method applies whether or getting a value in another note:

    $MyColor = $Color("Prospects"); 

    or setting a value in another note:

    $Color("Prospects") = "blue"; 

    For offset addressing there is only ever one argument inside the parentheses.

    The basic syntax for an offset addressing is as basic as that.

    Other ways to specify the argument for offset addressing (i.e. to a different note)

    The two methods above are the most common form of specifying the source/target. Occasionally, such as when two notes in the same container (or map) have the same $Name, this means their path is the same. In this case, the note's ID can be used via $IDString (which supplants older use of $ID for this purpose). In this example note 'Prospects' has an $IDString value of "tbx:BktGvS":

    $MyColor = $Color("tbx:BktGvS"); 
    $Color("tbx:BktGvS") = "blue"; 

    Also see the operator listing for $AttributeName[(scope)], which covers this topic from the perspective of action code operators.

    What if the offset value needs to be variable value?

    For instance, finding the $Color of the first child of the current note.

    Designators. In this case a designator is used (for more about designator use in actions: see here). Here, the correct choice would be the 'child' designator:

    $MyColor = $Color(child); 
    $Color(child) = "blue"; 

    Note that designators are not enclosed in quotes. This helps signal to Tinderbox that the argument is not a note title or path.

    Attribute values. Another way to use a variable argument is to use a value stored in another attribute. If a Color-type attribute 'SomeColor' holds a colour value, then:

    $Color = $MyColor; 

    or putting together some lessons above

    $Color("tbx:BktGvS") = $MyColor("Prospects"); 

    Note that when reading or setting an attribute values, the attribute name must be prefixed with a '$' character.

    Action code variables. Action code also allow creation of variable and these to can be used in an offset. Assume a variable 'vColor' has been defined and stored a colour value, then:

    $Color = vColor; 

    Evaluating arguments

    In more complex situations it might appear there is a need to use an action code expression as an argument. Better practice is to evaluate that code and store the result in an attribute or a variable and use the latter as the argument describing the offset.

    Offset address arguments: when to quote or not?

    Standard practice is to enclose literal text and titles ($Name) used as arguments within (straight) quotes but not quote note paths ($Path). The norm is to use double straight quotes but single straight quotes may be used instead. Doing the opposite generally gives the same result. But, users new to action code and/or without programming experience are advised to use the standard practice described. In addition, variables or attribute $-references are never enclosed in quotes. So:

    $Color = "blue"; 
    $Color = $Color("Prospects"); 
    $Color = $Color(/the/path/to/Prospects); 
    $Color = $Color($MyString); where $MyString holds a path or title value
    $Color = $Color(vString); where vString holds a path or title value
    Parentheses: arguments for action code operators and user functions

    Although historically user functions came the Tinderbox much later than action code operators, both use the same syntax:

    • Operator or function name. Names are case-sensitive.
      • User function names are set by the user by defining the function.
    • The trailing parentheses must follow immediately after the operator name , i.e. without any white space between the name and the opeing parenthesis. Otherwise the operator will not be evaluated correctly
    • Trailing parentheses containing argument(s)
      • arguments are always comma-delimited. Whitespace before after the commas is ignored by the code parser.
      • where there are no arguments or all arguments are optional and not being used, the parentheses may be omitted, e.g. .sort() vs. .sort. If in doubt, e.g if new to action code, use the empty parentheses. If unsure if parts of the syntax may safely be omitted, do not guess—use the full syntax.
      • operators may have optional arguments. Optional arguments are indicated in the main operator listing.
      • non-optional arguments must have a value, even if only an empty/default value, e.g. "".
        • all user function arguments are always mandatory.
    • some operators, and user functions also use a curly-bracket enclosed code block.

    Examples

    A simple query term:

    inside("Projects") 

    or basic operator use:

    $MyNumber = sin(45) 

    Parentheses may be omitted is no arguments, so either:

    $MyString = "uncle".capitalize(); 

    or

    $MyString = "uncle".capitalize; 

    But some operators , e.g. return, never allow trailing parentheses (per-operator documentation explains this). So if $SomeNumber is '4', then in a function:

    return (2*$SomeNumber); 

    returns '8', but

    return 2*$SomeNumber); 

    returns nothing. In the latter case, the action code parser assumes the execution order parentheses are arguments—invalid for return—and no value is returned.

    The syntax for a conditional operation with branching outcomes (depending whether the condition evaluates true or (else) false:

    if(condition){actions}[else{actions}] 

    In aTbRef documentation presence of '[ ]' indicate that one or more of the of the arguments is optional:

    stamp([scope, ]stampName) 

    thus implying both these usages are valid:

    stamp("Do Stuff");  
    stamp("SomeNote","Do Stuff");  

    In most cases, optional arguments come at the end of the argument list. In a few case both argument and parentheses may be optional if there are no arguments and all arguments are optional. Thus:

    $MyNewList = $MyList.sort;  
    $MyNewList = $MyList.sort();  
    $MyNewList = $MyList.sort($SomeString);  

    A user function (following aTbRef general naming conventions):

    myFunction(iArg1,iArg2){ } 

    In the last example, as a user-defined panel, all arguments must be populated even if only with an empty value, thus:

    $SomeResult = myFunction("hello",24){ } Correct
    $SomeResult = myFunction("",24){ } Correct
    $SomeResult = myFunction(,24){ } WRONG
    Parentheses: controlling parsing of code

    By adding parentheses into action code, including queries, the oder of evaluation can be altered. When evaluating the most deeply nested terms are evaluated first.

    Order of evaluating mathematical operators

    Just as is the case in formal coding or formulas in an ordinary spread sheet, when it comes to carrying out mathematical operations there is an 'Order of Operations' (see more on Wikipedia).

    Thus '1 + 2 × 3' can be considered ambiguous depending on whether the addition or the multiplication is done first. Thus the convention is

    1 + (2 × 3) = 7 

    but alternatively:

    (1 + 2) × 3 = 9 

    As is evident from the use of parentheses in these examples, by adding parentheses the user can indicate to Tinderbox their desired order of evaluation. Generally, additional parentheses are needed if the desired outcome is know to be the normal order of evaluation.

    Order of evaluation in queries

    Queries are used in agents, if(condition) tests and in find(query) operations. Queries are evaluated as read, i.e. left to right (start to finish), but in some cases additional hinting via parentheses can help both the parser and the user to understand their intent (especially when re-reading complex queries weeks or months later). Consider the outcome of this 5-term query, with terms A to E:

    A | B & C | D | E 

    compared to:

    (A | B) & ( C | ( D | E ) ) 

    Regardless of whether both evaluate the same way, the latter is much more easily understood in terms of the order things are done.

    Query syntax is discussed in more detail here, and here.

    Possible issues when using parentheses in a note title ($Name)

    Because parentheses are used to indicate how to parse data, this is why it is a good idea—if possible—to avoid using a forward slash character within a note name as it can prove problematic for some Tinderbox automation operations.

    Square brackets: lists and nested lists

    Square brackets in action code were originally added to deal with the problem of nested lists, i.e. where a list item is itself a list. This first became an issue when the Dictionary data type was added and users wished to have keys with multiple values. As a dictionary is a semicolon delimited list of key;value paired terms, if a value were also a list where does the key:value pair end.

    To overcome this a list item value in a List or Set that is a list, or a Dictionary key value that is itself a list, i.e. a nested list, can be marked with [ ] brackets:

    $MyList = [places;[apples;oranges];plants]; 

    Furthermore, the [ ] is used to define a complete list:

    $MyList = [places;plants]; 
    $MyList = [places;[apples;oranges];plants]; 

    this replaces the older, and still working—but deprecated— quote enclosed form:

    $MyList = "places;plants"; 

    Importantly, note how in the first examples above the brackets replace the use of quotes as seen in the last example.

    Note that, being new, at present very few code examples use this notation although it is now to be considered best practice new code when defining lists. Especially for those used to using quotes the old form still works but avoid these mixed forms, which may not work or have unexpected outcomes:

    $MyList = "[places;plants]"; WRONG
    $MyList = ["places;plants"]; WRONG

    If it is necessary to define a list where the list item(s) need to first be evaluated, use the list() operator.

    Here is a further example using Dictionary-type data where a key's value needs to be a list First in the new { } dictionary notation:

    $MyDictionary = {dog:terrier;boat:yawl;fruit:[apple;pear]};

    and now in the older (still working) format:

    $MyDictionary = dictionary("dog:terrier;boat:yawl;fruit:[apple;pair]");
    Square brackets: dictionary data keys

    A different use of square brackets from list identification is that of addressing a key in a Dictionary. Doing so causes the value of the address key to be returned. So:

    $MyDictionary = {car:hatchback;ship:ketch;plane:cargo}; 
    $MyValue = $MyDictionary[ship]; gives 'ketch'

    In the past, string quoting rules are interpreted as meaning key terms with quoted but this is no longer best practice—see the article on {} Dictionary definition.

    Square brackets: list indexes

    A list comprises a a number of different items. Often it is useful to address (call for) a list item by its number within the list. For example, historically this was done using .at():

    $MyItem = $MyList.at(2); 

    This returns item number three in the list, as the count used is 'zero-based', i.e. it starts at zero rather than one.

    Another, and a more current way, is to use [N] directly after the object addressed. Thus—and functionally the same as above:

    $MyItem = $MyList[2]; 

    This also makes it easier to address values in nested lists. Thus in this list:

    $MyList = [4;5;[6;2;4];9;7]; 

    the third list item is itself a list. To address a value within that nested lest, append another set of [] brackets like so:

    $MyItem = $MyList[2][1]; 

    returns '2', the first [2] is item #3 in the main list (i.e. 6;2;4) and then [1] calls the second item in that nested list, returning 2.

    Square brackets: dictionary keys with multiple values

    Another case where a nested list might be used is where a dictionary key's value is a list:

    $MyDictionary = {dog:terrier;boat:yawl;fruit:[apple;pear]};
    $MyFruit = $MyDictionary[fruit][1]; 

    returns 'pear', the second item in the (zero-indexed) list that is the value of key 'fruit'.

    Square brackets: in documentation, optional arguments

    In documentation of code, as opposed to code itself, the common technical writing convention is followed whereby something used optionally, i.e. that which may be omitted, is placed inside [ ] brackets. In this case the [ ] are not part of the syntax used in code, but they simply indicate the optional omissions

    An obvious place to see examples of this is in aTbRef's full list of operators.

    As an example, the if() conditional test:

    if(condition){...actions...}[else{...actions...}] 

    Note the second part starting else is inside [ ] square brackets. This implies that both these are valid syntax:

    if(condition){...actions...}else{...actions...}; 

    or

    if(condition){...actions...}; 
    Curly brackets: dictionaries and nested dictionaries

    The newer { } notation allow Dictionary data type objects to be defined, or to define dictionary-type data as an item in a list. This is similar to the newer to the [ ] method for defining List or Set types, or nested list values,Thus:

    $MyDictionary = {dog:terrier;boat:yawl;fruit:apple};

    which replaces the older (still working) syntax:

    $MyDictionary = dictionary("dog:terrier;boat:yawl;fruit:apple");

    Just as a list can be used as a dictionary key value (see), a { } object can be used as a list item or a key value:

    MyDictionary = {boat:yawl;plant:{fruit:apple;veg:tomato};dog:terrier}; 
    $MyValue = $MyDictionary[plant][veg]; gives 'tomato'

    Here a list is nested in a dictionary:

    MyDictionary = {boat:yawl;fruit:[apple;pear];dog:terrier}; 
    $MyValue = $MyDictionary[fruit][1]; gives 'pear'

    Caution is advised in nesting deeply. So far only a single level of nesting has been well tested. Deeper nesting might result in unexpected outcomes.

    Note that Dictionary keys have no notion of a sort order so a [N] numbered address must not be used in place of a [keyname] named address.

    Curly brackets: defining code blocks

    Action code operators that generates loops and branches enclose such section of code in { } brackets. Examples are below:

    Conditional

    	if($Text.contains("Project"){
    		// code if query evaluates true
    	}else{
    		// code if query evaluates false
    	};

    Loops

    	$MyList.each(aPath){
    		create(aPath);
    	};

    Note that inside a loop, the loop variable—here aPath—only holds a value within the loop code enclosed by the { }. For each iteration of the loop, the value of aPath is the value of the item in the source list. So, for the first loop aPath is the value of first item of $MyList.

    Caret delimiters: export code operators

    The caret ^ character is used with export code operators only. A caret is used to start the operator and (optionally) a closing caret. In the latter is omitted Tinderbox will output export correctly. Thus:

    The value is: ^value($MyString). 

    or

    The value is: ^value($MyString)^. 

    For the novice, it is safer to always use a caret as start and end of the operator. aTbRef uses the latter convention for code examples. If reading this note in the aTbRef, all carets used in examples will be doubled, so that there don't get evaluated as actual export code when the note is exported for the website.

    Note that use of export code in action code is strongly deprecated. It was allowed in very early Tinderbox so may still work. But such mixing should not be used for new code.

    Export code does allow use of action code in export templates via the ^action()^export operator.

    Forward slash: folder delimiter in paths

    When describing the path of a note in Tinderbox, each container (folder) within which the note is nested is delimited (separated) in the path text by a forward slash.

    So if 'Project A' is a child of 'Projects' which in turn is a child of root-level container 'Work', the path (as also found via $Path) is:

    /Work/Projects/Project A 

    Note: this is why it is a good idea—if possible—to avoid using a forward slash character within a note name as it can prove problematic for some Tinderbox automation operations. Thus titles like "Project A/B" or "Project A (Part 1)" are not generally recommended if the title can be written a different way to avoid these characters: e.g. "Project A-B" or "Project A, B" and "Project A [Part 1]".

    Double forward slash: action code comments

    Action code allows commenting in code, by using a // double forward slash. Here the second line of code is a comment and ignored when the action is run. Only lines #1 and #3 are evaluated as actions.

    	$MyList = [ant;bee;cow];
    	// now set MyString to the second item in MyList
    	$MyString = $MyList[1];
    Backslash: escape character

    The backslash character \ is used in literal strings in action code to 'escape' the character. This is necessary where some characters have a special meaning. So a '(' can open a parenthesis in a text string, i.e. indicate to a human reader a side-note in brackets. But if that string is evaluate for regular expressions, both '(' and ')' have a special meaning and so must be escaped). Thus the literal text string:

    "Do this (only) before that" 

    if it will be evaluated for regular expressions, e.g. when used with String.contains(), might be seen written as:

    $Text.contains("Do this \(only\) before that") 

    These are also a few cases where (borrowing from regular expressions methods) escaped letters are used in general action code. The two most common are to indicate a line break or a tab character:

    • Line break: \n creates a single non-printing (i.e. invisible) line break character.
    • Tab: \t creates a single non-printing (i.e. invisible) tab character.
    Full stop: dot-operators

    The full stop, or period, or point, or dot is normally used to mark a sentence end in text.

    A full stop is also seen used in one special context in action code: chaining operators together. Operators that can do this are referred to in Tinderbox as 'dot operators. For instance in this:

    $MyList = $MyList.unique().sort(); 

    The list stored in attribute called 'MyList' ($MyList) has been de-duplicated (.unique()) and A–Z sorted (.sort()) and written back over the original value.

    A listing of dot-operators is available.

    Comma: function argument delimiter

    For arguments (i.e. the input parameters) of action code operators and user functions, if more than one argument, each is separated by a comma.

    Some operators take no arguments.:

    version(); 

    Some take a single argument:

    tan(radiansNum); 

    But many take two or more arguments:

    time(aDate, hoursNum, minutesNum, secondsNum) 

    and here each argument is separated by a comma. White space either side of the comma is ignored.

    Note that this differs from other lists in action code where semicolon is used.

    If no arguments exist or are all optional, they may be omitted. If in doubt, supply the empty parentheses. These examples both work and are functional similar:

    $MyList = $MyList.unique().sort(); 
    $MyList = $MyList.unique.sort; 

    The .unique() operator never takes an argument, but .sort can, so another pair of alternates are:

    $MyList = $MyList.unique().sort($Year); 
    $MyList = $MyList.unique.sort($Year); 
    Symbols used in Mathematical and Logical operations

    A number of non-letter characters are used in mathematical operations ( note this isn't exhaustive, and doesn't list uncommon mathematical operators):

    • Addition: + 'plus', 'plus sign'. See here. Note the different use from action code concatenation.
    • Subtraction: - 'minus', 'minus sign' or 'hyphen'. Note this is discrete from the typographic en-dash '–' (⌥+-) and em-dash '—' (⌥+⇧+-). See here.
    • Multiplication: * 'asterisk'. See here. Note that in note $Text the asterisk is also used for generating (export) 'quick lists'.
    • Division: / 'forward slash' or 'solidus'. See here. Note the separate use in Tinderbox path values.
    • Equals: = 'equals sign'. Note this is also used for assigning values in action code expressions.
    • Less than: < 'less than', 'left angle bracket'. See here.
    • Less than or equal to: <=. See here.
    • Greater than: > 'greater than', 'more than', 'right angle bracket'. See here.
    • Greater than or equal to: >=. See here.
    • Increment: +=. See here.
    • Decrement: -=. See here.

    In addition there are logical operators using single or double characters:

    Symbols used in Regular Expressions

    A number of non-letter characters are used in regular expressions where they have special meanings: ^$\()[]{}+*=?. If using regular expressions do take some time to read about them: the subject is too large to address here.

    Designators in actions

    Both item and group scoped designators are allowed in attribute references. For example:

    $MyList=$Color(children); 

    finds a list of the colours ($Color) of each child of this note, and

    $MyList=$Color(children).unique; 

    finds the same list but without duplicates. N.B. lists can hold duplicate values.

    Working with numerical values:

    $MyNumber=$Width(children).max; 

    will find the maximum width of the container's children.

    When the same designator is applied to the attribute $Text

    $Text=$Text(children); 

    the texts of each child are placed in this note's $Text, separated by paragraph breaks. To append the same child text to existing text:

    $Text=$Text+"\n"+$Text(children); 

    Designators

    Tinderbox supplies a number of 'designator' terms, use of which instead of a note's $Name or path which may infer an individual note, or in a few cases a group of notes. Item designators are generally hierarchical in their references. Designators ignore map adornments, so cannot be used to match adornments.

    Designators are generally used with attribute value references ($Name(parent)), as action or export code arguments (linkTo(grandparent), linkFrom(grandparent(original))). In some cases they are specific to certain operators, as with links() and the link direction designators.

    Most item and group designators can use paths (or note names—if unique) to refer to data from a different note from the current context. For instance:

    child(/path/to/note) (using $Path, not in quotes)
    descendants("Projects") (using $Name, in quotes)
    grandparent(original) (using multiple designators, no quotes used)

    This optional expanded syntax makes designators even more flexible in use.

    Operators can be nested. In the following example an alias sets its (agent) parent's $Text to the $Name of the outline great-grandfather of the original of the alias:

    $Text(agent)= $Name(parent(grandparent(original))) 

    So an alias of note "ee" at original path "/aa/bb/cc/dd/ee/", the agent's $Text would hold "bb". Note that the nesting combines parent and grandparent, to reach a great- grandparent, whilst also using original to start the path traversal from the original and not the alias being acted upon.

    However, designators may not nest the find() designator inside another designator.

    Both item and group scoped designators are allowed in attribute references. For example:

    $MyList=$Color(children); 

    finds a list of the colours ($Color) of each child of this note, and

    $MyList=$Color(children).unique; 

    finds the same list but without duplicates. N.B. lists can hold duplicate values.

    Working with numerical values:

    $MyNumber=$Width(children).max; 

    will find the maximum width of the container's children.

    When the same designator is applied to the attribute $Text

    $Text=$Text(children); 

    the texts of each child are placed in this note's $Text, separated by paragraph breaks. To append the same child text to existing text:

    $Text=$Text+"\n"+$Text(children); 

    There are also separate series of designators designed to help date creation/calculation and the polarity of links.

    Designators are generally used with attribute value references ($Name(parent)), as action or export code arguments (linkTo(grandparent), linkFrom(grandparent(original))). In some cases they are specific to certain operators, as with links() and the link direction designators.

    Designators and root-level properties

    Tinderbox allows action code expressions that interrogate properties of the root note—the parent of top-level notes. For example, a top-level note can now get the value of $MapBackgroundColor(parent) if it wants to know the background colour of the top-level map.

    Using note titles that are designator designator names

    Tinderbox does not regard designators as 'reserved' values. It is perfectly possible to have a note called "children". However, in action or export code, if referring to such a note via code always use the full path ($Path) of the note rather than its title ($Name) to avoid ambiguity as to the intended object of the reference.

    Quoting designators vs. note paths or titles

    By convention, designators are normally not quote-enclosed in action code (i.e. queries and actions (and most export code)). Although designators are strings, not using quotes helps Tinderbox's parser to identify them as designators as opposed to notes of the same name. Designators used as path proxies, e.g. $Name(parent), may safely be quoted. Historically, path arguments were not quoted but since v5 there has been a move to explicitly quoting all string values. Ideally do not use notes with a $Name matching a designator nor using such non-unique designators in that TBX's actions (using explicit paths can route around such name collisions).

    Designators for Date data construction

    Designators, or rather 'keywords', for use defining date/time elements in Date-type data are described separately.

    A listing of designators

    Designators are listed via their scope:

    Item Note Designators

    You sometimes need to specify a reference to a note relative to something else, like the current note. Item Objects are a set of generic relative references to, or placeholders for, another single [sic] note whose actual identity is context sensitive. Item designators are written with lower case starting letters and inter-capitalised if multiword; e.g. child, prevSibling. Usage is case sensitive.

    The 'order' of notes, where referred to, relates to their sequence within the overall Tinderbox file. To see this order, expand all levels of an Outline, Explorer or Chart view. The order is the top-to-bottom ordering of the notes on a line by line basis; so the first child's children are ordered before the second child, etc. (Outline order is also exposed via the read-only System attribute $OutlineOrder).

    For convenience in export, several designators skip notes that are not exported, or usually considered outside the document outline. These include:

    • adornments
    • separators
    • other notes which do not export

    Such designators include next, previous, nextSibling, previousSibling. To designate a note that might be an adornment, separator, or unexported item, use the corresponding item designators: nextItem, previousItem, nextSiblingItem, previousSiblingItem.

    Group-scope designators may return only a single item if the evaluated group only contains a single item. This is not the same as the expectation that an item-scope designator must return a reference to only a single item.

    $ID value

    The $ID value of an item may be used as a special designator for single items or groups.

    For example:

    $Name(1524673590) locates the $Name of the note whose $ID is 1524673590.
    $Name(1524673590;1524673572) locates the $Name of the two notes whose $IDs are listed.

    Note that this particular designator usage—with literal ID values—should be avoided whenever possible, as it is hard to read and thus confusing for the occasional user. However it is made available because in some circumstances it may be the only practical way to reference item(s) where relying on unique paths are impractical.

    Indeed in complex code use, where lists of references to notes are passed around often (including in List or Set type variables), ID codes are much more robust to title or path mis-parsing due to the presences of slashes or parentheses in not names.

    adornment

    The designator adornment allows notes on an adornment to refer to the adornment's attributes. Only available in an adornment's $OnAdd action and in no other contexts. This is similar to the 'Link type honouring operators' designator.

    In this context, using parent would result in the value being taken from the parent of the current map view.

    In all other contexts than the above, the adornment refers to the map view adornment(s) on which the current note rests. If the note overlaps two or more adornments, adornment designates the uppermost (front-most) adornment.

    If the note overlaps no adornment, then adornment is bound to this. For example, the rule

    $Color=$Color(adornment); 

    will change the note's colour to match the colour of an adornment, but leaves the colour unchanged if the note does not overlap an adornment. This latter usage, with an inherent 'if on adornment' switch makes for more flexible coding in maps.

    agent

    The designator agent allows the children of an agent (always aliases) to refer to the agent's attributes. N.B. this is only available in agent queries and actions (i.e. $AgentQuery and $AgentAction) and no other contexts. This is similar to the 'adornment' designator.

    In this context, using parent would result in the value being taken from the parent of the original note to which the alias refers.

    child[N]

    child

    The designator child represents the oldest child (note) of the note currently in focus, thus the first as listed in Outline view. Mention in various references of 'oldest' deriving from creation/modification date are erroneous. 'Oldest' equates to the note whose $OutlineOrder attribute value is 1 greater than the current note's OutlineOrder value.

    The logical opposite of this (first) child designator is lastChild; there is no firstChild designator.

    child[N]

    The designator can take an optional numbered offset N, in square brackets. N numbers up from zero and down from -1. Thus:

    child[0] is the same as child

    whilst:

    child[1] is the second child
    child[-1] is the last child (i.e. lastChild)
    child[-2] is the last but one child

    Legacy code issue

    To avoid ambiguity, the old group-scope 'child' designator is deprecated in favour of 'children'.

    cover

    The designator cover represents the top level note in the hierarchy, or the first listed if there is more than one at this level. It will be the first listed in an outline window that shows the whole document. It has an $OutlineOrder value of '1'. The cover note will be the first listed root note if there is more than one note at the highest Outline level.

    current

    The designator current refers to the note which Tinderbox is currently exporting. Where a note is exported to its own page, current is the same as this.

    However, if a note includes children or other notes, current differs from this in the included notes reflecting the note actually being processed (and not the note that initiated the export). It is extremely useful for boilerplate-style includes that need to use attribute values from the calling note.

    For instance, if 'Note X' is calling an ^include^ of the text of 'Note Y' and the latter makes a code reference to the note title then, in the include's code:

    ^value($Name)^ gives Note Y.
    ^value($Name(current))^ gives Note X.

    Note that, when it appears outside an export template (e.g. in an agent or container action), current is synonymous with this.

    find(condition)

    Using a suitable query, find() can be used as a special item or group designator. The function returns a List of the $Path value for every matching note. The likely order of the returned items is $OutlineOrder ascending but it cannot be assumed. If sort order matters apply and explicit sort operation before further use.

    In an item-scope context, care should be taken in constructing the query so that only one note is matched.

    firstSibling

    The designator firstSibling refers to the first sibling of this note, in outline order. Note that, if a note has no siblings, firstSibling, this, and lastSibling refer to the same note.

    grandparent

    The designator grandparent describes the parent note of the current note's parent, i.e. its grandparent.

    It is especially useful for representing the relationship of an exploded note to its source note as the former do not automatically inherit the latter's attributes.

    lastChild

    The designator lastChild refers to the last immediate child of the current note. For example:

                       I. A note

                                        Ia. Another Note

                                        Ib. Yet Another Note

                       II. Some Note

                                        IIc. Subsidiary stuff

                       III. Different stuff

                       IV. More Stuff

    The lastChild of I is Ib. The lastChild of II is IIc. III has no lastChild.

    The logical opposite of lastChild, i.e. the first child, is child [sic].

    Using the optional child[N] notation, the equivalent of lastChild is child[-1]

    lastSibling

    The designator lastSibling refers to the last sibling of this note, in outline order. Note that, if a note has no siblings, firstSibling, this, and lastSibling refer to the same note.

    library

    In a function call the designator library binds to, i.e. calls data from, the (library) note holding the function. this allows a function to have 'internal' attribute settings to assist with configuration of function process or to store global values.

    The designator meaning has no value outside a function call. So in a note:

    $MyResult = fDoSomething($ID,$MakeLists(designator)); 

    would return data from the calling note (accessed via $ID) and with the function's code modified by it reading the value of its $MakeLists attribute (in this case likely a boolean: do/do not make lists.

    Otherwise:

    $MyResult = $MakeLists(designator); Dont' do this!

    returns nothing. To read fDoSomething()'s $MakeList value externally, requires giving the name/path/ID of the library note whose $text contains the function. Thus if fDoSomething() is in the $Text of library note 'Test Library', $MakeList can be read thus:

    $MyResult = $MakeLists("Test Library"); 

    NOTE: function 'designator' attribute values are thus shared by all functions in the same note. this may affect whether a single library note is used for multiple values or functions are store in discrete note or as groups of functions.

    nextItem

    The designator nextItem describes the next note in $OutlineOrder following current note.

    nextItem differs from next in that it will match an adornment, separator, or item set to not export.

    nextSibling

    The designator nextSibling describes the sibling note in $OutlineOrder after the note in current focus; the next note on the same level, i.e. excluding children.

    nextSibling is a more closely designed test than next as the latter may be at a different outline depth.

    nextSibling will not match an adornment, separator, or item set to not export, but see nextSiblingItem.

    nextSiblingItem

    The designator nextSiblingItem describes the sibling note in $OutlineOrder after the note in current focus; the next note on the same level, i.e. excluding children.

    nextSiblingItem differs from nextSibling in that it will match an adornment, separator, or item set to not export.

    original

    The designator original is synonymous with this for all notes except alias. In the context of an alias, original is the alias's original note.

    This designator is most useful in the context of an agent's action. For instance:

    $Container="/Bin"; 

    will move any matching aliases to the root-level note 'Bin' but the query will spawn a new alias next cycle; unless stopped, 'Bin' will fill with aliases as new ones are added each agent cycle. However:

    $Container(original)="/Bin"; 

    will move the original not of the alias to 'Bin' causing the original to be out of scope of the agent query and thus having the expected effect.

    parent

    The designator parent describes the note containing the note currently in focus. In Tinderbox there is only one parent note per child or set of sibling children.

    Testing the 'parent' of an alias

    The parent of an alias is the alias' own container (note or agent), not that of its original note. However, in more complex scenarios care needs to be taken to establish which alias/original note the user intends to reference. Where multiple aliases exist whether inside agents or elsewhere, there is scope for ambiguity if the user is not careful with their code. When using parent with aliases there are several useful considerations

    • The original designator, as in parent(original), will unambiguously indicate that it is the parent of the alias' original note that is being referenced
    • Only in agents, the Link type honouring operators designator can be used to allow agent aliases to refer to their 'parent' rather than the parent of the original note on which the alias is based.
    • The $Container attribute is intrinsic to an alias and potentially less ambiguous than $Name(parent) if trying to establish an aliases parentage within code.

    OnRemove

    As a note is removed before a container's OnRemove code is run on the removed note, parent cannot be used as it would in an OnAdd. Instead use that for the same task—see more.

    previousItem

    The designator previousItem describes the note in $OutlineOrder preceding current note.

    previousItem differs from previous in that it will match an adornment, separator, or item set to not export.

    previousSiblingItem

    The designator prevSiblingItem describes the sibling note in $OutlineOrder before the note in current focus; the previous note on the same outline level with the same parent, i.e. excluding children.

    prevSiblingItem differs from prevSibling in that it will match an adornment, separator, or item set to not export.

    prevSibling

    The designator prevSibling describes the sibling note in $OutlineOrder before the note in current focus; the previous note on the same outline level with the same parent, i.e. excluding children.

    Note that whilst prevSibling is the normal assumed spelling, the alternate of previousSibling is supported, though deprecated.

    prevSibling is a more closely designed test than previous as the latter may be at a different outline depth.

    prevSibling will not match an adornment, separator, or item set to not export but see previousSiblingItem.

    randomChild

    The designator randomChild returns a randomly-chosen child of the current note (i.e. this note). If the current note has no children, randomChild returns the name of the current note. For example:

    $MyString = $Name(randomChild) 
    selection

    The group designator selection designates notes that are selected at the time the action is run. Thus:

    $Color(selected)="red";

    turns the selected note(s) red.

    that

    With find()

    The designator 'that' refers to note running a query within find() code. As operators like find() change the meaning of 'this', that provides access to the original value of this. that is evaluated in stamps.

    For instance, it makes it possible to use an attribute value from the calling notes within a find() query within an enclosing action code expression. In such contexts, 'this' would apply to the note being queried by find() rather than the note calling find().

    For example if Note A, has 'Note B' stored in $MyString and runs a rule (or some other action code) the following would fail to test each note in find() for a $MyString value of Note B:

    find($MyString(this)=="Note B") Fail!

    But:

    find($MyString(that)=="Note B") 

    will test each note in scope of the find() query for the $MyString value stored in the calling note, i.e. Note A.

    OnRemove actions

    From v11.5.1. The OnRemove of a container runs on the removed note after removal. This means that unlike during OnAdd actions, the removed note cannot use parent, as the old container is not longer the actual parent. To allow for this scenario, that may be used to reference attribute values in the ex-container (instead of parent).

    Note that if the OnRemove action also includes a find(), then within the operators query that still binds to the note running the code (i.e. as above).

    this

    The designator this describes the current note (i.e.the note currently in focus). The focus of this can vary slightly by context:

    • in $Rule & $Edict: the note whose rule is running
    • in $OnAdd/OnRemove: the note that is being added/removed. In context, an attribute with no designator thus refers to the note running the action
    • in $AgentQuery: the note that is being examined
    • in $AgentAction: the alias that is being examined
    • in find(), collect(), etc.: the note that is being examined

    Beware of nesting changing the context. Consider the following rule:

    $Text=find($MyString==$Name(this)) 

    Although the overall context is a rule, the rule contains a find, which in turn holds the 'this' designator. Therefore in the above example 'this' is evaluated in the context of the nested find() and not as in a simple $Rule. The problem is resolved by using a different designator: see 'that'.

    Group Note Designators

    You sometimes need to specify a reference to a note relative to something else, like the current note. Group designators are a set of generic relative references to, or placeholders for, a group [sic] of notes whose actual identity is context sensitive. Group designators are written with lower case starting letters and inter-capitalised if multiword; e.g. sibling. Usage is case sensitive.

    Unlike item designators, group designators may not be use for specifying attribute path references.

    Thus, for a word count of the current note's children you use:

    $MyCount=sum(descendants,WordCount) 

    In older versions this would have required using an export code:

    $MyCount=^sum(descendants,WordCount)^ 

    Some action operators and export codes work on groups of notes. These can use group designators in place of literal lists (or attribute-stored lists).

    If a group is empty, e.g. the current note has no children, the group operator returns the equivalent value/boolean for the current note instead.

    It is perfectly valid for a group designator to return a single item, if only one item meets the criteria of the designator. A container with only one child note with return list containing only item reference for its 'children'. Conversely, (single) item-scope designators must return a single item reference.

    [literal group assignment lists]

    Group designators may also be lists of notes, either explicitly

    $Color(/config/one;/config/two)="red" 

    or implicitly computed by an action code expression equating to a list enclosed in double-quotes:

    $Color("collect_if(all,$Path,$Price>5)")="red" 
    $Color("collect_if(all,Color='red',$Path)")="blue" 

    Note in the latter example how string literals within the action code expression use single-quotes to avoid premature closures.

    Another new option is a list implicitly computed by a find() query: $Color(find($Price>5))="red" 

    $Color(find($Color="red"))="red" 

    Note that find() queries do not need to be double-quoted, unlike the earlier examples above.

    $ID value

    The $ID value of an item may be used as a special designator for single items or groups.

    For example:

    $Name(1524673590) locates the $Name of the note whose $ID is 1524673590.
    $Name(1524673590;1524673572) locates the $Name of the two notes whose $IDs are listed.

    Note that this particular designator usage—with literal ID values—should be avoided whenever possible, as it is hard to read and thus confusing for the occasional user. However it is made available because in some circumstances it may be the only practical way to reference item(s) where relying on unique paths are impractical.

    Indeed in complex code use, where lists of references to notes are passed around often (including in List or Set type variables), ID codes are much more robust to title or path mis-parsing due to the presences of slashes or parentheses in not names.

    adorments

    The designator adornments returns all the adornments that are contained inside the current note, i.e. this container's child map. The data is returned as a List of the adornments' in ascending $OutlineOrder.

    Siblings vs. children

    For any given map, in terms of $OutlineDepth/$OutlineOrder, notes on the map are siblings of the maps' adornment(s). However, for adornments any adornments are for the addressed item's child map. If the logic seems odd, bear in mind that a map (timeline, etc.) is normally addressed in terms of its enclosing—and thus parent–container.

    Thus, for an item on a map to get its sibling adornments use either of these relative references, use either:

    $MyList = $Name(adornments(parent)) 
    $MyList = $Name(adornments(..)) 

    noting that .. is the unix term for the parent folder. For most Tinderbox users, who aren't familiar with Unix structures, the parent designator as the offset address argument is the most sensible to use.

    Title vs. ID and action code

    When using a large number of adornments, e.g. to set out a time or date grid, many of the individual adornments may not have a unique $Name. For instance if there is an adornment '10' mapping the first 10 minutes of an hour, there may be multiple adornments on the same map with the same $Name and $Path. Recall that when accessing a note via a not unique title/path, Tinderbox always matches the first match by $OutlineOrder, even when processing a list. In other words, processing a list of $Name values with multiple '10' values, the action will act on the same, first match target, every time.

    $ID offers a sensible workaround, not least because within the action code context the use of item titles ($Name) is a convenience. If you want to process a list of adornments for whatever ever reason it may therefore make sense to use their $ID instead as this will always be unique. For example:

    $MyList = $ID(adornments) → a list of child adornment IDs
    $MyList = $Name(adornments(parent)) → a list of sibling adornment IDs
    all

    The designator all describes all notes in the current TBX. 'all' is assumed as a value by some group-based operators if no explicit group name is supplied. The returned List is all items ordered by ascending $OutlineOrder value.

    It appears all is explicitly supported for group-based work in actions & rules, but not for group-based export codes.

    ancestors

    The designator ancestors returns a List of all notes in a direct line of ascent from the current note to its root-level container and so the List is returned in descending $OutlineOrder.

    As the list of ancestors is returned in reverse order, i.e. deepest nested first and root item last. So:

    $MyString = collect(ancestors,$Path)[-1]; is the root-level container for this note
    $MyString = collect(ancestors,$Path)[0]; is the parent container for this note
    children

    The designator children describes any direct child of the current note. The List returned gives all immediate children sorted in ascending $OutlineOrder.

    This designator removes the contextual ambiguity of older usage of 'child' for both group and item scope usage. By comparison the child designator is always assumed to apply to item scope (i.e. one referenced container only).

    As designators ignore map adornments, a container note with just adornments on it but child notes with evaluate as having a $ChildCount (the number of adornments) but no children (the number of notes).

    descendants

    The designator descendants describes all direct and indirect children of the current note, i.e. all those for whom the current note is an ancestor.

    The list returned is all descendants is in ascending $OutlineOrder, i.e. as you would see in Outline view with all containers expanded and then reading the order vertically

    find(condition)

    Using a suitable query, find() can be used as a special item or group designator. The function returns a List of the $Path value for every matching note. The likely order of the returned items is $OutlineOrder ascending but it cannot be assumed. If sort order matters apply and explicit sort operation before further use.

    In an item-scope context, care should be taken in constructing the query so that only one note is matched.

    siblings

    The designator siblings describes all notes at the same outline level as the current note that share a common parent. This includes the current note. The returned List is in ascending $OutlineOrder.

    Thus for a note with three sibling notes, siblings will be a list of four items (i.e. this note and all its siblings).

    Miscellaneous Designators

    The are a few designators that are used in particular contexts:

    asterisk ("*")

    The linkedTo() and linkedFrom() action code query operators can use a wildcard designator which has whole-doc scope, akin to the 'all' group designator. This designator must always be quote-enclosed. Note that these operators are otherwise item-scope.

    document

    The document designator refers to the overall TBX document. Used with word cloud exports.

    my

    The my designator is used in action code in the context of composites, specifically when referring to the composite containing the note using the code, i.e. this note.

    my can be used as a short form of compositeFor(this) when using with colon-operators used (only) with composites. For example, the pair of examples below have the same functional effect:

    compositeFor(this):role("someRole") 
    my:role("someRole") 

    Thus the use of 'my' makes for more compact code; it has no effect on performance.

    If using compositeFor() in an any other context, e.g. a composite of which the current note is not a member then the 'my' designator can not be used.

    root

    N.B. THIS IS NOT A VALD DESIGNATOR TERM!

    The root describes a note that has no parent, i.e. at the highest level in outline view. If a root note has no siblings then it is also the cover note. Otherwise the first listed top level note is the cover note.

    Action code cannot use 'root' but the concept is relevant in the use of path references to notes.

    In export codes, there is a ^root^ code.

    this, that, agent, adornment, original and current

    A core part of designator use is the initial context. The default context is the current selection, otherwise referred to as this. When referring to attribute values, this is implicit in the short form seen below. the following are equivalent:

    $Name
    $Name(this) (more explicit but generally redundant)

    When addressing a value in a parent note, again note the same implicit this, as these are equivalent:

    $Xpos(parent); 
    $Xpos(this(parent)); (more explicit but generally redundant)

    A number of special designators are supplied for less usual contexts. With agents, their children are aliases of matched notes. Thus the parent of the alias is the agent, but to address the parent of the alias' original note use. For instance:

    $MyString(agent) = $Name(parent(original));

    Adornments and smart adornments offer a similar contextual quirk. For a note on top of (in front of) an adornment, the adornment designator sets its $MyString to the adornment's $Name:

    $MyString = $Name(adornment);

    The find() operator has the problem the often it is necessary for the query to reference a value in the calling note, as opposed to the note tested. The that operator is used to allow such a reference and it is used only in a find() query. Here, the query matches any note whose $MyString value matches the $Name of the note running the find():

    find($Name==$MyString(that); 

    Note that find() is itself both and operator and a designator and most often used with operators like collect() where the scope of the operator can only be defined by a query rather than a simple group designator like children.

    Because an OnRemove runs after a note is considered removed from its old container, unlike in an OnAdd, the parent designator cannot be used. To allow the ex-container to be referenced, the that operator or used. Note: its use in the latter role does not affect the more general use of that within a find() query.

    The current designator is used for export template operation using ^include()^ type operations and where nested calls may make the meaning of this ambiguous.

    Comments in Action code

    Action code may contain comments. A comment is part of the overall code but which is not executed when the code is run. This allows annotation within code. Such comments should be brief, and usually indicate something about the intent of the code before or after it (depending on comment placement).

    Comments are useful. The working of some complex code may be obvious now, but will it be when re-visited several years later?

    A comment begins with two slashes, and ends either with a second pair of slashes or at the end of the line. To write a multi-line comment simple start each line of the comment with a double forward slash. For example:

    
    	// this is a comment that
    	// continues onto
    	// several lines
    	$Color = "blue";
    

    In spaces using action code in the Inspector and in notes using the build-in Action prototype (e.g. Stamp and Library (function) notes in the /Hints container) commented lines are rendered in grey. this can be a useful tell-back

    The above shows comments on a discrete line or continued on successive lines by simply starting the next line of comment with the same marker. The next example shows the two other forms. The first line of code shows a to-end-of current-line comment and the second line a fulling inline comment with valid code before/after the comment. Example, of line end and inline comments

    
    	if($Prototype=="Task") { // special handling for tasks
    		$Width= // 5 // 7;
    	}

    To recap, the three forms of comment are, in order of reading:

    • a multi-line comment. Essentially, from a code perspective, this is a series of successive whole line comments.
    • a line-end comment. Here, the comment continues to the end of the line, but does not affect the running of the code on the beginning of that line.
    • an inline comment, i.e. within the content of a single line. The comment on the last line skips over the "5", starting before that figure and closing after it. This means that when run, $Width is set to 7 rather than 5.

    Some considerations for effective use of comments

    If you add comments to working code and it stops working, it may be gremlins in the parsing of the code causing the issue. What's clear to the human eye, may be less so to code trying to parse the code text. If adding comments causes a problem, don't overlook making a copy or your current code elsewhere and then deleting all the comments; doing so can save hours of frustration chasing wrong causes. If this type of problem occurs it may be one of the issues below. Meanwhile work is ongoing to resolve these edge-cases.

    Avoid: soft line-wrap

    Action code has no explicit multi-line comment (although colouring may imply this. Avoid guesswork, and so do not rely on the text area's styled text ruler's soft-line-wrap. Best practice is to put explicit line breaks after a suitable width of code in the $Text and then start a new comment line (as above) with the continuing comment text.

    Avoid: double forward slashes inside a string (false code colouring results)

    This can occur if something like a web url is contained in a string. consider this:

    $Text = "https://example.com"; 

    In a code input box, everything from the '//' will colour as a comment, but the action actually works—setting a $Text value. This is an edge case for the code-colouring syntax as the differing intent of '//' is not obvious to the code-parsing regular expression.

    If the problem faced is trying to see the syntax (colouring) is the now-comment-coloured part of the code, temporarily delete one of the two slashes and de-dub the test of the action before re-inserting the slash.

    Another workaround is to move the slashes into a variable:

    var:string vSlashes = "//"; 
    $Text = "https:"+vSlashes+"example.com"; 

    Although needing an extra line of code, this has the same outcome as the previous example but should make the main section of code colour correctly.

    Avoid: unmatched quotes

    Within a single comment (or single comment line in multi-line) always pair quotes. Assume an odd number of single or double straight quotes may and likely will cause a silent failure. The code parser and the code colouring processes work slightly differently. So either pair quotes or use 'curly' quotes . Thus, Opt+Shift+] will give a single right curly quote for an apostrophe (or, avoid speech-like contractions).

    Examples of what to avoid

    1. Unpaired single quotes.

    BAD. Unpaired straight quote:

    // don't do this. 

    GOOD. Uses curly quote for apostrophe:

    // don’t do this. 

    GOOD. Avoid speech-style contraction:

    // do not do this. 

    2. Unpaired double quotes

    BAD. Unpaired double quote in wrapped comment text.

    	// Here is "Some
    	//  wrapped quoted text". Etc...

    GOOD. Wrapped partial quote is fully quote-enclosed:

    	// Here is "Some…"
    	//  "...wrapped quoted text". Etc...

    GOOD. Uses curly double quotes for quoted text:

    	// Here is “Some
    	//   wrapped quoted text”. Etc...

    Avoiding contractions is also likely kinder to translation used by those whose first language differs from our own.

    Action code operator terminology explained

    NOTE: This article (and its children) discusses a several potentially confusing or ambiguous aspects of action code operators and aTbRef's own conventions adopted to try and reduce that effect.

    Tinderbox includes a numerous action code features called a 'operators' or simply 'codes'. 'operator' is the most used term and the one used here.

    In aTbRef, operators are classified into 3 main functional groups:

    • mathematical and logic operators, e.g. '+' (addition) '==' (equality test), '&' ('AND' query join), etc. See a listing of operator-type operators.
    • property operators. These generally allow the reading and/or writing of an aspect of something, for instance separately addressing a colour's hue, saturation and brilliance. See a listing of property-type operators.
    • function-type operators. These allow the manipulation of information in the TBX file, similar to—but not the same as—action code functions. See a listing of function-type operators.
    Action Operator Arguments

    What is the difference in meaning between a function's 'argument', 'parameter' or 'input'?

    In this context 'parameter' and 'input' are just alternative terms for 'argument'. The latter is the terminology upon which aTbRef is now standardising in order to try and make the documentation as a whole more consistent. An argument will always have a value, e.g. '12' or  "Green eggs and ham", and it is the value supplied by the argument upon which

    What is an 'argument'?

    It can be said that an operator 'takes' one or more 'arguments '(inputs), does something (i.e. 'operates') with the value of the arguments, and 'returns' a result. In most cases, operators have at least once argument but a small number of Function-type operators might confuse they may have no arguments or all their arguments are optional (their being optional will be covered further below).

    So then, what is an 'argument'? When an action code operator such as a function-type operator needs information to work correctly, that information is passed to the function in an 'argument'. For example, the operator abs() is described as abs(number), indicating the abs() operator takes a single argument that is a number. Other operators can take multiple arguments. For instance, any(scope,testValue) takes two arguments: a scoped argument for the group of notes the function examines, and the type of test the operator should perform.

    Generally, if any of the specified arguments are not supplied, the operator will either fail to give an outcome; or if arguments are supplied but in an incorrect form, the operator will either fail or give an unexpected wrong outcome. The documentation of the operator will explain the arguments.

    What do arguments do?

    Above, the description has centred on how arguments are written, literally, in action code. However, is it possible to ask important questions about an argument, especially when encountering a new operator for the first time or one whose purpose is not self-evident from its name. These aspects are:

    • What is the scope of the argument—e.g. is a single note affected or are multiple notes affected?
    • What data type does Tinderbox expect—i.e. what information must Tinderbox receive to operate the function?
    • What is the purpose of the argument—i.e. what does the operator do with the information in the argument?
    • Is the argument evaluated—i.e. how does Tinderbox interpret the information in the argument?

    Argument order

    In action code arguments must always be supplied in the order they are documented. This also applies to arguments for user-defined functions. If an (optional) argument is omitted, and other arguments follow it, a comma+space placeholder should be inserted for example, in pseudocode:

    someOperator(arg1, optArg2, optArg3) 
    someOperator(arg1, , optArg3) 

    Argument delimiters and whitespace

    A comma must be placed between each argument in function operator. Without the commas, Tinderbox is unable to correctly process the instructions. It is acceptable to type a comma followed by a space, for readability purposes, but that space is not required by Tinderbox and is ignored by the parser. Thus Tinderbox parses both the following examples to the same outcome:

    any(children,$Checked) 
    any(children, $Checked) 

    Quoting argument content

    The literal string parts of action code expressions are quoted as in normal action code, in straight quotes, e.g. "Name of some note". Single or double quotes may be used as long as correctly paired. If the literal value of a complete path (i.e. starting with a '/') is used in code the quotes may be omitted. If in doubt, use quotes!

    By contrast, attribute references, e.g. $MyString or action code variables, e.g. vSomeVar, are not quoted.

    Further Aspects of Argument Use

    Programming and action coding can at times follow 'rules' that are not obvious in 'the real world'. This can be daunting at first, but careful reading of the documentation and personal experimentation with Tinderbox may quickly lead to mastery of the 'rules'. Meanwhile, those with prior coding/programming expertise will see where these 'rules' can be altered or ignored.

    In the notes below, additional aspects of argument use are described:

    Optional Arguments

    What is an optional argument?

    For some operators, there may be optional arguments which, if supplied, allow the operator's output to be given differently. In the main documentation listing of operators, square brackets indicate optional argument(s). For instance, with the indented(N[,"item"]) operator it takes two arguments the second of which is optional. Thus, using intended(N) works with only a single argument (N) supplied but indented(N[,item]) can be coded with two arguments (N and item)to give a more nuanced output.

    In almost all cases, the optional arguments are supplied last, after any mandatory arguments, but be aware there are a few where the optional argument comes first, e.g. values([group,]attribute).

    Arguments may be optional because:

    • A default value is assumed unless a (non-default) value is passed, thus saving having to 'state the obvious' by passing in a value that is already presumed.
    • The optional argument signals the function to alter its default behaviour, e.g. giving a different form of returned output.
    Argument scope

    Scope: how widely in a Tinderbox document is the target operator applied?

    Some arguments are designed to pass the identity of a single note or a group of notes upon which the operator then acts, thus affecting the scope of the work carried out.

    The identifying data collected is usually the $Path of the note(s) but can be the title ($Name) of the note(s). In this latter case, Tinderbox will assume the $Name value is unique in the document, silently matching the first such $Name as detected in ascending $OutlineOrder and acting only on the first match. A more recent option is to use note $ID values, the only downside being that, read by eye, 10-digit numbers mean little although they are unambiguous to Tinderbox.

    Not all arguments are scoping. Scoping arguments are most common in operators that collect or work on lists, including making or removing links.

    $ID for notes with problematic characters in $Path or Name

    As documented, some characters—such as parentheses '( )' or forward slashes '/'—can in some circumstances confuse Tinderbox's code parser. The most likely context is when using (un)linkTo/From operators. Such usage is a good candidate for using $ID data instead of paths is the current document is known to contain 'difficult' paths or titles (bearing in mind that a path is effectively a list of ancestor note's titles).

    Argument expected data type

    Data type: what Tinderbox 'data type' is needed by an argument or its target operator?

    Whether explicit in the argument name or not, most argument will have a documented or implicit data type. This worth bearing in mind especially when passing attribute values or variables as the argument value.

    If the source data type is incorrect, it might be necessary for Tinderbox to 'coerce' the data from one form to another at which result in an unexpected outcome. In programming, when software makes one kind of data into another, e.g. makes a string of digits into a number, that precess is called 'coercion'.

    Experienced users will likely know where this might occur and act accordingly. New users are advised to avoid coercion, which might have unexpected results, by first formatting their data to the desired type and only then pass the result as the argument. For example, if a function is looking to receive a numerical argument do not give it a quoted string of digits such as "12345" but the numerical value 12345. Practice and experience will soon help this become clear.

    Another aspect to this is knowing the data type upon which the operators work (without implied coercion). For instance, there are a suite of dot-operators that work only on Color data-type, or only on Date data-type, etc. Thus, even if the arguments do not stipulate a data type, be aware of the data type being passed into, or literally written as, the argument' value.

    Another aspect of the data type is the likely range of acceptable vales, which may not be explicitly stated. For example, a number of opacity-related system attributes use a number representing a percentage between 0% (value: 0) and 100% (value: 1). Using 10 (100%) instead of 0.1 (10%) when intending to indicate '10%' may confuse Tinderbox. Even if it treats a value of greater than 1 as 1, that will result in an opacity 10 times that expected. Where value range limits are known, they will be documented.

    Failure to take account of data type when passing argument values is likely to result in unexpected results or silent failure—no results and no explanation or indication as to why. Should he latter occur, checking the argument values is a good place to start looking for an explanation.

    Argument purpose

    Purpose: what does this argument do, with relation to its target operator?

    It may not always be obvious from the syntax example name of the argument as to its purpose when used. For a simple task like getting a square root of a number it should be obvious that the operator will need to know the number from which to obtain a square root. Sure enough, the sqrt() operator takes one argument 'number'. By comparison, the pow() operator for raising a number to a power;; it takes two number type arguments. Although the purpose of the two can be guessed, it is still necessary to know which argument is the number acted upon and which argument is the desired order to which it is to be raised.

    Arguments are documented as part of articles describing discrete operators. Where possible, aTbRef will attempt to indicate an argument's purpose within a given operator, though the name used in short syntax examples may not give all detail about that argument. If unsure, the user may need to consult the full documentation article on the relevant operator.

    At present there is no clear, unambiguous method for naming arguments that works across the whole set of operators, so if new to use of an operator, do read the note (and where necessary its linked notes) before first use.

    Argument evaluation

    Evaluation: does this argument allow evaluation of its action code expressions(s)?

    An argument's value can be defined in a few ways:

    • A literal value: 2, "bar", "2 February 2022, 22:22:22", etc.
    • A designator—only for some argument types—such as scoping arguments, dates, etc.
    • An action code expression
      • A simple expression, e.g. simple string concatenation like "Hello"+" world".
      • A complex expression where some calculation is required to generate the equivalent of a literal value.
    • An attribute or variable value holding either a literal value or an action code expression.

    Note that few operators mandate only use of literal argument values. However, Tinderbox's own documentation does not generally address (degree of) argument evaluation. This can mean that at times a use may need to experiment before applying complex argument values to operators in a working document.

    Simple evaluations are generally not problematic and, in most cases, no extra preparations are needed.

    Complex action code expressions can arise, often unintentionally, because operator X's argument needs a value being calculated by process Y elsewhere in the document. Thus, an attribute's value might be a call to a user function. To get the literal value of the argument, Tinderbox must read the argument, finding it is an attribute reference, fetch the attribute's value to find that is a function call, call the function, receive the function output … and hope that result is a suitable literal value.

    Another aspect is that the scope and capability of Tinderbox action code has changed significantly over the application's 20+ year lifespan. The range of possible interactions between operators can create scenarios where deeply nested evaluations (i.e., evaluation within evaluation within … etc.) arise, and importantly occurring without the user being aware of that. Insufficiently deep evaluation can occur. If it does this should be reported directly to Tinderbox tech support as it will be unintentional unless the limitation is formally documented. Generally, such limitations are resolved, but if encountering them be aware that any fix will require a new app built/release, so in the short term another approach to the problem is required.

    aTbRef will document evaluation limits where known, but as stated this aspect of the action code toolbox's interactions is least understood or documented. Be prepared to do small/limited tests if in doubt.

    Conditional arguments

    Some operators may take a argument which is evaluate to test a true/false condition. These arguments normally have a string value in the form of an action code query (such as might otherwise be used in an agent).

    Loop variable arguments

    Loop variables

    A small number of operators (see a listing) employ a user-named 'loop variable'.

    Loop variables, or 'loopVar', are a special form of input. Though not strictly an argument, a loop variable is most easily understood in the usage for list.each(loopVar){} operator.

    The important point to understand, and which confuses new users, is that the 'name' if the loop variable is whatever the user chooses. So, if coding an .each() loop like this:

    $MyList.each(anItem){...} 

    the variable's name inside the { } code block is 'anItem' or if coded:

    $MyList.each(x){...} 

    it is 'x', or:

    $MyList.each(foobar){...} 

    is it 'foobar', etc.

    A key point is using the loop variable's name anywhere inside the loop (i.e. within the { } curly braces) the current value of the loop variable is the value of the source list item currently being processed. In the first example above, on the first iteration of the loop 'anItem' has the value of the first item in $MyList, in the second loop the second $MyList item, etc.

    The implication of square brackets in operator descriptions, regex, and literal strings

    Potential confusion over the implication of [ ] characters in operator descriptions vs. other uses e.g. regex and literal strings

    Operator Syntax. Square brackets [ ] are used when documenting the optional parts of operator syntax, but are not (normally) used when employing the operator in actual action code. Otherwise, except for special cases listed below, do not type square brackets when creating code. Thus the example of the indented(N[,"item"]) operator, if using both operators the code entered would be like indented(4,"Project X"), noting that absence of square brackets.

    For special cases where square brackets are used in literal operator syntax see:

    Therefore if square brackets appear in code syntax examples—as opposed to general syntax code example descriptions—it will imply one of the above uses.

    Square brackets can of course occur in values within the code, include code examples for using operators:

    • as literal strings: "This string contains [square brackets] because it can".
    • in regular expressions ('regex') as part of the matching pattern definition: $Text.contains("[^ b|d]").
    Are operator parentheses needed if there are no arguments?

    Are operator parentheses, i.e. trailing ( ), needed if there are no arguments?

    Some operators have no arguments and others have only optional arguments. When there are no arguments in use, it is permitted to omit the parentheses. Both these are acceptable:

    $MyList = $MyList.sort; 
    $MyList = $MyList.sort(); 

    Exceptions

    Most strict transactional operators (see listing) such as '+' or '==' never use trailing parentheses, as in—hypothetically—coding '+()' would be wrong.

    Statement-type operators never take parentheses, but are used as a keyword that precedes some code defining the operator's task:

    Conversely, a user-defined function defined via function must always have trailing parentheses or the parser will not detect it. Thus a user defined function 'fSomeTask' that has no defined arguments is nonetheless always coded as fSomeTask() with tailing parentheses.

    Summary

    Though optional in some cases, it is considered 'good practice' with Tinderbox action code and other programming languages to use the parentheses when using operators even then they are not strictly required. Not least, it helps remind the user that the code object is a an operator.

    So, if in doubt, use empty trailing parentheses.

    Export Operator Arguments

    Export code operators also use arguments. Action code and export code are discrete code systems in Tinderbox with disparate tasks: one internal to the app and the other related to exporting Tinderbox data. However, export code uses the same broad conventions for arguments as action code, so the nature and usage of arguments is covered under description of action code arguments.

    Variables

    Action code allow for the use of user-defined variable within action code. A primary use of these is to avoid the need for a lot of user attributes just to hold interim values during more complex actions or for re-use of a value within loops and the like.

    Variables are declared in an action and cease to exist at the end of the action. To hold the value further, the existing value would need to be stored in an attribute.

    Variables are created using the var() operator.

    A declared variable can be passed into action code operators as arguments and as arguments to user-defined functions. In export template, a variable declared in an ^action()^ code block can be addressed anywhere in the rest of the template (following/below the point of declaration) and inserted into the exported code using ^value()^ just as if inserting an attribute value. Thus ^value(vSomeValue)^ inserts the value of variable 'vSomeValue' into the exported code stream (note: unlike an attribute there is no $-prefix used).

    Also see:

    Choosing to use variables or attributes in code

    This is not a binary, either/or question, not least because using (user) attributes to hold values during the course of an action long pre-dates the arrival of the var operator for variables (which was only added in v5.10.0). Data-typed variables (e.g. var:string) arrived in v9.1.0, as did the function operator. Data-typed function arguments, a type of variable, arrived in v9.5.0. The later version also added the ability in templates for ^value()^ to inset a variable set in an ^action()^ section further up in the template.

    Thus a lot of longstanding code examples in the Tinderbox community were written before the current range of variable uses were added.

    When must an attribute be used?

    If the document needs to retain a value form session to session, i.e. persisting when the document is closed, that an attribute is required. This is because variables (and any value) are lost/deleted once an action is run. But, if such a value can be calculated from available information at document start, then storing a value in an attribute may be an advantage rather than a necessity.

    When must a variable be used?

    Never, but in all cases except that above, using a variable can make for shorter, clearer, action code. Additionally, as variable (values) are lost when an action completes, there is no need to clean up after. By comparison, passing an attribute a list of the paths of 1,000 items, so the list can then be iterated means that value remains forever unless the attribute is reset to an empty value.

    Simulating global variables

    When programming, it is sometime useful to have an arbitrary value for a something that is available anywhere in the code, regardless of the current scope; essentially a default value. Here, setting an attribute value, does the same. The exact attribute name or the location if the note storing the value isn't important, as long as having made a choice the user refers to the name/location consistently.

    Since the advent of the attribute() operator in v9.5.0+, another method is simply to make a user attribute per desired global variable and set its default, altering if needs be via attribute("AttributeName")["default"].

    More common practice is designate a single note, often at the outline root as a configuration or 'config' note and store/alter global values there. By the same token, it is possible to use one attribute for several globals using a different note, but the same attribute, to hold each value.

    There is no correct way. With the advent of attribute() adding a suitably named/typed attribute is the cleanest method as there are not locations to remember for getting/setting the attribute. In contrast, if globals might need to be copied from one TBX document to another, e.g. to set up a particular workflow, then a config note(s) is possibly an easier approach. This aspect of Tinderbox is still evolving so what is best/safest/least effort may change over time.

    Functions

    Tinderbox allows user-defined operators, also called 'functions'. Such operators are typically defined in notes inside the Library container in the document's built-in Hints container (if not present this should be added to the document) though they may be defined in other contexts too.

    Notes in that container which have names enclosed in parentheses, such as /Hints/Library/(What’s This) are treated as documentation; all other notes are executed at document startup and after they are edited.

    Why use functions?

    Functions provide a 'define once / use multiple times' feature in documents, and allow:

    • storing a process so that it can be used repeatedly throughout the document;
    • defining that process once and using it from many different locations, i.e. not needing a copy of the same code in each, rule/agent/etc.;
    • storing a long complex action that can be hard to read in the Inspector but more easily read as the $Text of a note (see storing function code)
    • allowing a process that takes inputs, which is a limitation of stamps;
    • allowing a process that can return results, another limitation of stamps;
    • transportable function or libraries of functions that can be copied to and re-used in other document and by other users.
      • Note: any (user) attributes called in a function need to pre-exist before use—Tinderbox will not auto-create them, e.g. when copying a function from one document to another.

    What sort of things can functions do?

    Functions comprise a set of action code instructions that perform a specific set of operations to achieve a specific outcome. In most cases, this will include acting upon optional input arguments provided to the function at the point where it is called (a.k.a., invoked) and optionally return results to the code that called (called) the function. A simple case is as shown in the example below (explained in more detail here):

    function fAddTax(iPrice){return(1.18*iPrice);}; 

    It is still possible to define a useful function that takes no input and returns no value but acts on the document based on the functions code, e.g. setting a selection of attribute values. In this mode the function is akin to calling a stamp, though calling a function may seem a more intuitive usage.

    Functions fall into broad categories of use:

    • Mathematical/logical. Probably the simplest use. A function can easily implement mathematical and statistical calculation tasks. Generally a number in, a number out.
    • String manipulation. Slightly more complex due to the ad hoc nature of the inputs. Whilst new stream parsing methods improve basic action code capability a function allows for larger processes.
    • Encapsulate complex processes. In more complex documents, workflow may involve a complex series of transformations to support ingests of data or for formatted export using structure beyond normal export code offerings.

    More about functions

    The following sections should be read through completely on first encounter but are structured as small articles to assist cross-referencing and later reference for refreshing understanding or syntax.

    Important note: all examples follow aTbRef naming conventions. These may seem verbose or over-descriptive to experienced programmers but are provided to help the learner, not the expert.

    Aspects of using functions:

    Storing function code

    Important note: all examples follow aTbRef naming conventions.


    Functions can be defined in any action code space:

    • Library notes (notes under /Hints/Library). Do not store code in the Library container note itself
    • Action attributes: Rule, Edict, AgentAction, OnAdd, OnRemove, etc. (see all).
    • Stamps (note or Inspector).
    • A note with the 'Action' prototype set (edge case, arbitrary use is not generally recommended unless the above don't suffice)

    Given their re-useable nature, Library notes are probably the most logical place for storage, but is not a requirement. But a strong recommendation as a first a choice.

    Regardless of where stored, any user function, defined in any valid location (see above) in the current document, can be called from any action code in that document.

    Therefore, for novice users, the last option—a Library note (first in list above), is the best place to start.

    New users might choose to add only one function per note until comfortable with the process, noting the section below on naming library notes and note's $Name vs function name(s) in their $Text.

    What goes in a Library note

    A library note can contain:

    • one, or more, discrete functions.
    • other arbitrary action code expressions, e.g. rules, agent actions.

    In combination, the above two an allow Library notes to act as a way to store and share 'libraries' of code between different Tinderbox documents and/or users.

    If storing non-function action code such as rules in a Library note, it may be useful to enclose such code in an inert function, thus:

    function fDoNotUse(){..code ...} 

    i.e. one with no inputs and no return and with a name unlikely to be called in code.

    Naming Library notes

    The titles ($Name) of Library notes are not used to call a function, and should not be the actual name of a function so should simply be indicative of purpose. Do not use the exact name of a user-defined function lest it confuse Tinderbox, i.e. $Name should not match a function's name.

    Thus, if a Library note contains a single user function 'fDoMyTask()', do not call the note "fDoTask()". Better would be "Do MyTask". For a library note with several functions, especially if grouped for easy copying between TBXs, a descriptive title like "Workflow Set-up" is a good approach.

    Be aware how this differs from stamp notes, where the note's $Name is the name of the stamp is called from code


    Next: Naming functions
    Naming functions

    Important note: all examples follow aTbRef naming conventions.


    Naming Functions

    Functions should not use names reserved for built-in operators. Names are case-sensitive. Function names should begin with a letter, and may contain letters, digits, or the underscore character, i.e. A-Z, a-z, 0-9 or _ (but not a hyphen!).

    Functions must not share names with attributes or erroneous outcomes will occur.

    The convention here in aTbRef is to use the CamelCase naming as for attributes with a lowercase 'f' prefix.

    Note that parentheses are always used regardless of whether the function has input arguments—that being a difference from action code operators in general where trailing parentheses may often be omitted if that are no input arguments The naming of arguments is discussed separately, here.

    Function arguments are user-named and have no specified limitations but are most sensibly named using letters only (in Latin or other supported scripts).


    Next: Defining a function
    Defining a function

    Important note: all examples follow aTbRef naming conventions.


    Defining functions

    Functions are defined by the function statement:

    function name(arguments){actions}

    The basic syntax is comprises four parts:

    • the function action code. This tells Tinderbox that a function is about to be defined.
    • the function's name. For function naming rules/constraints, see naming functions. The function name must be separated from the function code by a single space.
    • parentheses () containing the function's input arguments, i.e. (arguments). The parentheses must be used even if there are no arguments—that is, use (). See more on setting arguments. Also:
      • There must be no white space before the parentheses. White space between the parentheses and the opening { of the action code is allowed, but is deprecated so as to give an easier rule to follow: no white space before or after the obligatory parentheses.
      • A value must be passed for every argument defined in the function. To simulate an optional argument, pass a null value (empty string "", zero 0, false, etc.) and test that input within the function's code.
      • The need for parentheses when there are no arguments is a slight exception to action code operator syntax where Tinderbox is generally happy for parentheses to be omitted if there are no arguments being required/used. Thus, functions are an exception to that principle.
    • curly braces {actions} enclosing the function's complete action code, i.e. one or more discrete action code expressions. These curly braces must be used. There is no space between the preceding parentheses and the curly braces. Though Tinderbox appears to cope with white space in these positions, such use is not recommended: assume no white space is allowed here. Unless other code follows the function code, there should be no need to place a semi-colon after the closing curly brace.

    A function is essentially an encapsulated set of action(s) which may take inputs—arguments—similar to the way some action code operators take input arguments. The terms 'argument', 'input' and 'argument' may be used interchangeably, as the implied meaning is the same.

    Storage of function code is discussed here.

    A function can be called from anywhere, as explained here.

    Examples of function syntax are given here.

    Can a function code contain another complete function?


    Next: Function arguments
    Function arguments

    Important note: all examples follow aTbRef naming conventions.


    Function arguments

    A function's arguments are the terms—zero or more—that are defined within the parentheses following a function's name. Thus function fSomeTask(iNumber, iString){... defines two discrete arguments: 'iNumber' and 'iString'. A function with no arguments function fReset(){... is perfectly allowable, noting that parentheses must be included even if empty. This latter form, though valid, is less commonly used because in general the aim of the function's code is to manipulate one or more values passed to that function.

    A function may, or may not, have one or more arguments. Multiple arguments are entered separated by commas (with optional whitespace after).

    A value must be passed for every argument defined in the function, i.e. the action code calling the function must be written so as to supply a value for each argument defined by the function.

    Functions with no input arguments must have parentheses

    A user-defined function with no (zero) arguments is still required to be defined with empty trailing parentheses. For instance, this simple function that has no arguments and which simply returns a string value:

    function fTestMessage(){return "Hello world."} 

    Similarly, those empty parentheses must be used when calling the function in action code:

    $Text = fTestMessage(); 
    $Text = fTestMessage; WRONG

    Importantly this is a variation from general action code syntax where some action, especially dot-operators, where all arguments are optional and trailing parentheses may be omitted (e.g. .isort vs .isort()).

    By comparison, the example function can not be called as fTestMessage and must be called as fTestMessage() despite there being no use of arguments. One reason is that the action code parser might mistake the 'bare' call as being just a literal string, due to support for legacy syntax where quoting strings was just an option.

    Add an extra argument or make a new function?

    Creation a use of a function can show that it might be useful if some conditional choice of process or return value were supported, e.g. returning a string in title case or all-lowercase. One way to do this is to add an extra boolean-type input. But, remember that all defined inputs must be used when calling a function. If not coding often for such functions it is easy to forget.

    So, it is a matter of personal preference as to whether a better choice might be to make a copy of the original function, give it a new name, and alter the logic within. The reverse issue if you find something (a bug or possible improvement) on one of the functions it will be necessary to edit all of them. Also if versioning functions this way it can help future self if the function name indicated the altered behaviour from the original. So rather than copying fMakeString() as fMakeString2(), if the new version is to make an all-lowercase return value, fMakeStringLowercase() or fMakeString LC(), etc. might be more self-explanatory.

    Naming arguments

    Each input argument must have a discrete name. The argument's name must not be an attribute reference, e.g. "$MyString", or an attribute's literal name, e.g. "MyString". Within this restriction, the exact naming of the argument is the user's choice.

    The argument name is essentially declaring/naming an internal variable for use (only) within the function, as explained further below: see 'Argument names as internal variables'.

    In aTbRef documentation any function arguments in the parentheses use the same CamelCase convention as for attribute names but with an 'i' prefix. For example, this function definition code:

    function fMakeTable(iSomeList){ ..code ...}

    'iSomeList' will be a variable available within the scope of the function, i.e. in the function but not outside it. Calling the above function like so:

    fMakeTable($CategoryList);

    will result in iSomeList within the function holding a list containing the value of the calling note's CategoryList attribute.

    An argument's name vs. the value name used in action code calling a function

    It is important to understand that a function argument's defined name and the string defining the input for that argument as used in the code calling the function code are usually different. Thus, in the above example, the function is called supplying an argument value that is a reference to $CategoryList. But, inside the function for this execution of the function, the value of the first argument iSomeList will be tread from the $CategoryList attribute value in the calling note.

    But, elsewhere other action code might call the same function but using code fMakeTable($MyList);. For that execution, iSomeList within the function will hold the value of $MyList in the calling note. Or the calling code might pass a literal list, e.g. fMakeTable([ant;bee;cow]);, with iSomeList now being the list passed into the function, i.e. as a list [ant;bee;cow] .

    Despite describing calling the function 'fMakeTable' with three differently described input, in every case, the supplied argument value is used internally via the argument's name, i.e. were 'iSomeList'.

    So:

    • Inside: inside the function the argument name is always are defined in the function code (e.g. $SomeList in the example).
    • Outside: in code calling the function, a value is substituted where the argument is defined. These may be literal values (20, "Hello", false, etc.) or attribute references ($MyString).

    Argument names as internal variables

    When writing a function's code and including argument(s), an argument's name is implicitly defined as an internal variable. Using the example above, if a function's argument were defined as 'iSortList' then that exact name (i.e. the argument's user-defined name) can be used anywhere in the function's code as a variable that will have that value passed to the function via that argument input.

    If the argument were instead named 'x' or 'abracadabra', the same applies, the argument name as defined in the function code is the name of the internal variable for that argument's input.

    Therefore, the argument/variable name is set by the user by the action of writing the function code.

    Note, that when copying another user's function code, as personal styles differ, a user may decide to use argument names more to their own style. If doing so it is important to change not only the argument name in the function's argument list but any occurrences of the argument name in the whole code of the function. In this simplistic example, function 'fGetListItem' takes a list as an argument and returns the value of the third item in that list (not second, as .at[] is zero-based):

    	function fGetListItem(iSomeList){
    		return iSomeList.at[2];
    	}

    If having copied this code it was preferred to have an attribute 'L', then two substitutions are needed, one in the argument declaration and the second where it is used within the function:

    	function fGetListItem(L){
    		return L.at[2];
    	}

    Externally, the call is still the same, e.g.:

    $MyString = fGetListItem($SomeThings); 

    as it is only the internal name of the argument that has changed (from 'iSomeList' to 'L').

    Argument data types

    A function's arguments can be given an explicit data type, i.e. when used within the function the stated data type will be used

    For example,

    	function fAppendFoo(iList:list){
    		return (iList+"foo");
    	}

    Now 'iList' will be treated as a list without any type coercion needed. The argument's type is set in the function definition and in the above example the function would expect one argument and that it would be List-type date (attribute, literal list-string, etc. The range of data types, and how they are used is described in the article on variables, var().

    Whilst it is not a requirement to give a type to any/all arguments, it is strongly recommended users do so—especially if new to function use. Why? Because previously, all inputs arrived as a string and if a definite type was needed inside a function, the input argument had to be passed to a type variable (or attribute) before use. For example,

    	function fAppendFoo(iList){
    		vr:list vList
    		return (vList+"foo");
    	}

    By using explicit argument types, doing explicit type coercion within the function is avoided. So, less and clearer code.

    Using argument input values within the function

    Arguments are a received as a String data type (regardless of the source data in the calling code). Note that may change in future version, to allow enforced date-typing of arguments. But, at present assume type coercion occurs. That means most inputs will be assumed to be a String, List or Dictionary.

    In the example above, calling the argument 'iSomeList' may indicate the term is a function argument and is intended to be List-type data, but it doesn't affect Tinderbox normal type coercion. A string with no semi-colons in it will be assumed to be a string. If semi-colons are found a list (essentially a List type) will be assumed.

    To avoid incorrect parsing of inputs, it may be necessary to pass the input to a data-typed variable. Re-using the above example:

    	function fMakeTable(iSomeList:list){
    		var:list vList = iSomeList;
    		// ..tc.
    	}

    Variable use is discussed further here.

    It is equally possible to pass the argument to an attribute of the desired data type in order to assert data type for further use within the function.

    Evaluation of input arguments

    An argument may be an action code expression as well as an attribute value, variable or literal string/number. For instance:

    $Result=fLastThreeWordsOf(fBestParagraphOf($Text)); 

    Here, the actual value passed to function fLastThreeWordsOf() is the evaluated result of fBestParagraphOf($Text), with $Text being the text of the calling note.

    Simulating optional arguments

    As stated above, every argument defined in the function's code, must receive an import or the function will not run correctly. To simulate an optional argument, pass a placeholder string ("none") and test that input within the function's code before using the argument, i.e. if "none" do nothing or else carry out some action using the argument's value. Here "none" is not a defined term. The value used in this context is up to the user. The point is that if using 'no value' value, the the input value must match whatever 'no value' string the user has defined in their function.


    Next: Returning function values
    Returning function values

    Important note: all examples follow aTbRef naming conventions.


    Returning function values

    return

    The return statement returns a value from a function to the calling action code object (which can even be another function). The return operator is used only inside a function. Execution of the function's code stops once an action code expression containing a return (i.e. up to the next semi-colon) is processed. Thus if function fTest returns a string:

    	function fTest(){
    		return "Hello";
    	}

    The returned value is passed back to the calling code:

    $MyString = fTest(); 

    with the result that $MyString would be "Hello", i.e. the value of the function's return statement. By contrast, simply calling the function without a left-side recipient:

    fTest(); 

    would still cause the fTest() function to be run. However, the function's returned value would be inaccessible to the calling code context.

    Using the return operator in a function

    Thus, when return is inserted in a function, the action code/expression to the end of the line (or first semi-colon) is evaluated and returned. Note that as the return statement is closed by a semicolon, it is essentially a single line of action code/expression started by the word 'return' (case-sensitive), a space, and then following action code code. For example:

    return "Process complete"; returns a single literal string
    return true; returns a boolean value
    return $MyNumber; returns an attribute's value
    return vMyValue; returns a variable's value

    However, if the to-be-returned value is not coded a single term, but rather as an action code expression whose output is returned, it may be enclosed in parentheses but does not require to be so. The use of parentheses helps indicate, if only to the user, that some evaluation is required before the single result is used as the return value

    The first example shows an evaluated result without parentheses, the other with parentheses:

    return 2 + 2; 
    return ("Hello " + vName"); 
    return (iPrice * $Tax); 

    Can return occur anywhere in the function?

    In theory Yes, but in practice, No. This is because the function process completes after the return value is evaluated and passed back out. So extra code may occur after the return but is not evaluated.

    One possible use for content in a function after a return statement is to add comments about a function placed at the end, after code so available for user reference but not pushing the actual code down the (viewable) screen so aiding usability.

    Can a function return multiple discrete values?

    The output of the return statement is a single value, but that single value can use a multi-item data type. Thus, if it is desired to pass multiple discrete values in the same return event, store the function's returned data as a List, Set or Dictionary type. Of course, the code receiving the output needs to understand how the multiple values are accessed, i.e. the order of the list or the Dictionary's keys.

    Does there have to be a return statement?

    No, it is not a requirement. For instance a logging function might take an input string and append it to the end of a specific note. In such a circumstance there is nothing for the function to return to the calling code.

    Can there be more than one return statement in a function?

    Yes. The function ceases running when a return statement is encountered but if the function has conditional branching code, each branch that represents a final result can have its own return statement. In such a case, the intent is to allow a different returned value depending on the result of conditional tests.

    So, whilst multiple return statements may exist overall, the code evaluates so only one return is ever processed (as the function stops at that point). For instance, for those unused to programming, initially this may be more easily understood using a single return statement to pass back one of 3 possible values:

    	function fTestLength(iString){
    		var:string vOutput = "";
    		if(iString){
    			if(iString.size<=5){
    				vOutput = "Small string";
    			}else{
    				vOutput = "Large string";
    			}
    		}
    		if(vOutput=="")
    			vOutput = "No string";
    		}
    		return vOutput
    	}

    However, the above example can also be written as:

    	function fTestLength(iString){
    		if(iString){
    			if(iString.size<=5){
    				return "Small string";
    			}else{
    				return "Large string";
    		}
    		return "No string";
    	}

    In this case, there are three discrete possible return values but each closes and returns for a different single branch of the code. As in the first example, the logic could as easily set a single variable in each branch and then use a single return at the end of the function.

    As the function quits once a return is reached, using multiple return statements can avoid the function having to evaluate unnecessary extra code. Such efficiency measure are unlikely to affect most Tinderbox use but can act as way to help understand use of functions with conditional outcomes. Both examples evaluate to a similar outcome; use whichever form makes the most sense.

    If using multiple return statements, take care to avoid exiting the function too early, i.e. that each return statement is truly a final point in the function's logic.


    Next: Calling functions
    Calling functions

    Important note: all examples follow aTbRef naming conventions.


    Calling functions from action code

    Regardless of where stored, every function in the current document can be called from any action.

    If a function has arguments, the caller must supply values for each argument, even if only as an empty string (or other default data-type value. Extra arguments are ignored. If a function is redefined, the most recent definition replaces any existing definitions.

    If the called function returns a value, then the calling code needs to use an attribute or variable to receive that value.

    Examples—with a return value

    Calling a single literal value for an argument:

    $MyNumber = fAddTax(500); 

    Calling a function with a single argument:

    $Text = fMakeTable($CategoryList); 

    Calling a function with multiple arguments, that returns List-type data (see here for multi-value returns):

    $MyList = fAlterList($CategoryList,$SomeString,"alternate"); 

    A function with no arguments:

    $MyNumber = fCheckSum(); 

    Notice how in every case the function is called as the right side of an '=' (i.e. value assignment) operation so the return value can be stored and further used.

    Example—with no return value

    A function with no return value:

    fReset(); 

    Note in this case that whilst no left-side recipient is needed but function parentheses must be included.

    Can a function call another function?

    Yes. A function can call itself. This is called 'self-reference', and is an advanced technique that should be used with caution and tested in a test document before use at scale. This process is also known as recursion.


    Next: Variable use in functions
    Variable use in functions

    Important note: all examples follow aTbRef naming conventions.


    Uses of variables in functions

    There are three ways that a variable are used in functions:

    • as a local variable, just like any other use of variables in Action code;
    • as an "argument" variables used to receive the data passed from the calling code;
    • as "loop" variables that will be local to the loop code, just like any other use of loop variables.

    Defining a variable in a function

    A function variable is defined exactly the same way as in other action code:

    var vThing; 

    As the basic assumed data type, if not set, is a String, it can be more helpful to use explicit typing, whether or not a value is applied straightway. The point is that the variable has a notified data type from the outset, rather than one coerced by Tinderbox based on context of use:

    	var:string vThing;
    	var:number vCount;
    	var:date vNow = date("today");
    	var:boolean vBoolean = true;

    A variable needs to be defined before first use, as with attributes. It makes good sense to define variables at the start of the function, noting that loop variables are defined in the loop operator. Do consider also adding comments about the variable's purpose, as once written the code may only be re-read occasionally and the code's intent may get forgotten over time.)

    Using variables to set data type of inputs

    The data type of input arguments can be specified making the usage below obsolete. See Function arguments.

    Legacy. Previously, as from v9.1.0, the function's arguments when accessed from within the function supply String-type data (this is regardless of the data type supplied in the action calling the function). Thus, to avoid unexpected type coercion, e.g. Date being misread as a String, it can be useful to pass an argument into a typed variable before using the argument value in the functions action code:

    	function fMakeTable(iSomeList){
    		var:list vList = iSomeList;
    		vList.each(anItem){
    			// ..tc.
    	}

    Variable duration

    Variables created in a function are destroyed when the function execution completes. If a variables value is needed, other than as a return value, the value will need to be passed to an attribute for more persistent storage.

    Variables only exist while the function is being executed after having been called. Whilst variables are most often used to temporarily keep intermediate results while the function is executing, if a variable holds some value that is needed elsewhere, it should either be passed back to the calling code via the return operator or an attribute should be assigned to the variable's value. Some examples of assigning attributes to function variables are:

    	// ...
    	$MyString = vString;
    	$SomeNumber ("config-note") = vCount;
    	// ...

    In the first case, $MyString in the calling note is set. In the latter case, $SomeNumber in note "config-note" is set. The choice of where a stored value is saved is dependent on the wider context of use, i.e. there is no single 'correct' choice.

    A variable may be used as an input argument for a call to another function:

    	// ...
    	var:string vString = "Testing!";
    	fAnotherFunction(vString){
    	 // ...

    Variable scope

    A variable created in a function is only accessible from within that same function. For experienced programmers this may seem unexpected (see more) and may change in the future. At present, a variable should only be used within the function in which it is defined.


    Next: Attributes vs. variables in functions
    Attributes vs. variables in functions

    Important note: all examples follow aTbRef naming conventions.


    In brief pre-summary, attributes are heavy-weight: persistent, accessible through the document, must be cleaned up if used for storing intermediate states during an action. Variables are light-weight: they can be defined as needed, they are destroyed (cleaned-up once the function has run) but only accessible within the current function.

    Attributes

    In a function, any attribute reference, e.g. $MyString, refers to an attribute in the calling note (i.e. the current item in a selection). It is still possible to refer to the same attribute in another note via an offset address, e.g. $MyString("SomeNote"). Or, designators may be used $MyString(parent) gets the MyString value of the current item; in an alias, it is the alias' parent, or $MyString(parent(original)) will get the value of the same attribute but from the parent of the alias.

    If the function needs to store a lot of interim values, as in some string manipulation tasks, this can involve using quite a few attributes. It is no problem for Tinderbox to create additional user attributes, even if only for this task, buy if many are needed do consider variables as an alternative. Note that these attributes need to be created before the function is used. Attributes can be created via the Add Displayed Attributes configuration panel (attribute name and data type only), or the Document Inspector's User tab. Only the Inspector allows configuration of all aspects of a user attribute.

    If using attributes consider:

    • Attributes have global scope vs. local scope for variables. This means that once saved in an attribute, a value is available from any action in the document (albeit you may need to use an offset address, where the code references $AttributeName(name or path of target note)). So:
      • Attributes have permanence—they are integral to the document, and saved with it.
    • Functions that reference attributes can interact with multiple notes located anywhere within the current document (via offset addressing).
    • Attributes must be defined outside of the context of Action code and they must already exist in a document before they can be used.
    • Using attributes causes the function to be dependent on the document and its structure, whereas variables are self-contained within the function.

    To minimise the build up of forgotten data consider:

    • clear attributes, once they have used, with a reset at the end of the function (though before the return, if used).
    • use attributes within a single note, or perhaps a note per function if complex, so as to compartmentalise where stored data is generated.

    Alternatively, consider action code variables, as described below

    (Action code) Variables

    Using action code variables within functions can help their use without needing to use any attributes, other than explicitly storing output results. Variables are created when defined and cease to exist (i.e. including the data they store) when the action containing them, such as a function, has finished being run. So if a function declares a variable and stores data in it, that value is only accessible within the function _and_ once the function is run the values are lost forever.

    Such use makes a function more self-contained, especially if planning to use the same function (or library of functions) in different Tinderbox documents. This is because the function creates/destroys variables as needed and there is no need for user attributes (see above) which might not (yet) have been created in the current document. Using variables avoids that extra set-up of configuring attributes.

    Variables created within a function only work within the scope of that function, as discussed here.

    Which approach is better?

    …is the wrong question to ask! It is perfectly fine to use either, or a mix of both. Use whichever appeals and makes sense for the user's style of work. The choice will likely depend on a mix of personal style and the nature of use of the functions.


    Next: Additional examples
    Additional examples

    Important note: all examples follow aTbRef naming conventions.


    If you are starting here for cut-'n-paste samples, do take time to read this whole section. If new to action code functions, it will help to have a basic understanding of what functions do.

    Basic example

    A simple function might be written to return a number with an 18% tax uplift applied to the input number:

    function fAddTax(iPrice){return(1.18*iPrice);}; 

    or, split out only lines for clarity:

    	function fAddTax(iPrice){
    		return(1.18*iPrice);
    	};
    	

    Arguments arrive as String type data and Tinderbox coerces them as best it can. So here iPrice is a string value containing a number. However Tinderbox knows that if a number, e.g. 1.18 is multiplied by a String (containing a number) the String-type should be coerced to a Number-type before use and the resulting value will be Number data type.

    Though more verbose, a safer approach—especially if unclear as to Tinderbox's coercion logic—is to be more specific, and insert comments, as shown below :

    	function fAddTax(iPrice){
    		// Arguments: iPrice - a number, the starting price
    		//
    		// make a variable (expected type of Number) and set it to argument #1
    		var:number vNum = iPrice;
    		// multiply variable by tax rate
    		vNum = 1.18 * vNum;
    		//return the tax-adjusted price
    		return vNum;
    	};

    This defines a new function named 'fAddTax' that can be used in any action or action code expression (including ^action()^ in templates) to apply 18% tax to to the input figure, i.e. $1.00 → $1.18. It has one input argument, and returns a single value. Thus:

    $MyNumber = fAddTax(500); 

    would set MyNumber's value to 1.18*500, i.e. 590. If we assume this is money, a $500.00 input becomes $590.00 including tax (be it US Dollars or any currency).

    But hard-coding (i.e. 1.18) values like tax rates is generally considered bad practice as values can (will!) change. A better function might be this, comments, line breaks for for clarity:

    	function fAddTax(iPrice){
    		// Arguments: iPrice - a number, the starting price
    		//
    		// var:number vTaxRate = 1.18;
    		// make a variable (expected type of Number) and set it to argument #1
    		var:number vNum = iPrice;
    		// multiply variable by tax rate
    		vNum = vTaxRate * vNum;
    		//return the tax-adjusted price
    		return vNum;
    	};

    But, supposedly fixed values like tax rates can change when governments change. So…

    Adding an additional function argument

    What if the tax rate changes? This can be accommodated by adding a second argument for the tax rate. Extra comments, line breaks for for clarity:

    	function fAddVarTax(iPrice,iTaxRate){
    		// Arguments: 
    		// iPrice - a number, the starting price
    		//  iTaxRate - tax rate percentage as a number (15 not 0.15)
    		// --------------
    		
    		// make a variable (expected type of Number) and set it to argument #1
    		var:number vNum = iPrice;
    		// multiply variable by tax rate, assuming the tax rate input is a decimal percent, e.g. '0.18' for 18%
    		var:number vTax = iTaxRate;
    		vNum = (1 + vTax) * vNum;
    		//return the tax-adjusted price
    		return vNum;
    	};

    Thus:

    $MyNumber = fAddVarTax(500,20); 

    would pass a 20% tax rate, set MyNumber's value to 1.20*500, i.e. 600.

    Further examples:

    	function fAnswer() {
    		return 42;
    	}

    always returns 42. Or:

    	function fFibonacci(iNum){
    		if(iNum<2){
    			return (iNum);
    		};
    		return fFibonacci(iNum-1)+fFibonacci(iNum-2);
    	}

    returns the iNumth Fibonacci number. This is a more advanced example showing the concept of recursion, whereby a function calls itself.

    Using more concise code

    For the experts who understand the flow of the code, the function defined above could equally well be defined in a terser form:

    	function fVarTax2(N,T){
    		return ((1+(T/100))*N);
    	};

    Those with coding expertise may prefer this form. However, aTbRef code examples here are written assuming a reader with little or no coding expertise, thus the use of a more explicit and verbose format.


    Next: Comments in functions
    Comments in functions

    Important note: all examples follow aTbRef naming conventions.


    As Mark Bernstein's book The Tinderbox Way notes (p.33): "...the primary audience of a note is almost always our future self.". Thus, out comments are notes to our future debugging self (unless constructing demos/examples for others).

    Action code allows commenting and adding comments to a function is a good idea. Comments may be placed within function code or outside it (e.g. before or after the functions/code. As the Tinderbox action code parser ignores comments their position, and the scope and depth of notes is a matter of personal taste. However, if making a library of functions for other people, it is a good idea to explain:

    • the purpose of the function
    • the purpose and (intended) data types of the argument(s)
    • the return value(s).
    • the logic if multiple return statements are used within conditional code

    For example:

    	function fAddTax(iPrice){
    		// Arguments: iPrice - a number, the starting price
    		//
    		// make a variable (expected type of Number) and set it to argument #1
    		var:number vNum = iPrice;
    		// multiply variable by tax rate
    		vNum = 1.18 * vNum;
    		//return the tax-adjusted price
    		return vNum;
    	};

    To make it easier to see the function code without scrolling, one approach is to put a comment at the start of the function indicating the main detail is at the bottom of the function.

    For example, re-using the example above:

    	function fAddTax(iPrice){
    		// Comments at end
    
    		var:number vNum = iPrice;
    		vNum = 1.18 * vNum;
    		return vNum;
    
    		// Arguments: iPrice - a number, the starting price
    		// make a variable of 'number' type and set it to argument #1 to enforce data type
    		// multiply variable by tax rate
    		// return the tax-adjusted price
    	};

    This latter form yields little benefit in a small function like above, but as functions grown in length and number of arguments or return(s) values, coding becomes a big help to future self.

    The need for comments really reflects two factors:

    • Sharing. If this function will be shared with others, will your logic be self-evident to another user?
    • Complexity. Will you—or another user—remember later on the original intent or logic in a large function? What was clear when writing the function may not be so months later if there is next a need to look at the code, e.g. to enhance or correct it, or simply understand how it functions!

    Next: Nesting functions
    Nesting functions

    Important note: all examples follow aTbRef naming conventions.


    NOTE: this subject is only pertinent for more expert users

    Can a function code contain another complete function?

    In principle, Yes, this is possible. Those with a programming background may be used to techniques like nesting one function inside another. However, there is no difference in use by doing so and it is currently not recommended. Why:

    • Tinderbox may harden scoping rules in the future, which would break existing code.
    • It is confusing, and likely to give a headache when trying, a month from now, to figure out what the code is doing.

    Variables in the outer function are (likely) accessible to the nested function but again, this is currently not recommended.


    Next: Re-using variables from other functions
    Re-using variables from other functions

    Important note: all examples follow aTbRef naming conventions.


    NOTE: this subject is only pertinent for more expert users

    Those with a programming background my be used to techniques like re-using variables.

    Can a function use variables from another function?

    In theory, yes, as the example below shows. However, this is not recommended. Consider this code

    	function fTest(iVal) {
    		var:number vFactor=3;
    		return fDoIt(iVal);
    	};
    
    	function fDoIt(iVal2) { 
    		return vFactor*iVal2;
    	};
    
    	$MyNumber=fTest(7); // returns 21

    As stated above, this usage—whilst possible—is not recommended.

    If a variable needs to be shared in a wider scope, using a (user) attribute—either in the calling note i=or a specified note—is a perfectly practical alternative.


    Next: Private functions
    Private functions

    A private function is a function that can only be called within the note in which it is defined. That note will usually be a library note.

    The point of a private function is it allows for the scenario where two (or more) functions might have the same name as might arise if using library notes created by different people. Thus two (or more) library notes can each define private functions with identical names; each library note will use its own version of the private function. As long as functions are labelled private, they will only be callable from their containing note and not from other (library) notes. Be aware that if a note only contains one function it should not be made private—as nothing outside the note can call it.

    A function is designated private by inserting the word private between the function's argument parentheses and the curly brace starting the function's code:

    function fFunctionName(Args) private { ...code... }

    White space(s) before/after the private is optional.

    Operators

    More complex actions than simple value assignments are effected via action 'operators'. There are 329 built-in operators of varying complexity and purpose as described in the various listings below:

    Full Operator List

    NOTE: action code operator names are camelCase case-sensitive, e.g. firstWord() not Firstword() or firstword(). A few deprecated action codes/usages are listed separately here. Optional operator arguments are shown in [square] brackets.

    Note: meaning of square brackets in code syntax.

    A list of all current action operator codes:

    - (i.e. subtraction)

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

     Operator  [other Operator type actions]

     Item  [operators of similar scope]

     Mathematical  [other Mathematical operators]

     Number [about Number data type]

     v1.0.0

     Baseline

     As at baseline


    - (i.e. subtraction)

    The subtraction operator, - (minus sign character), returns the remainder of the argument before it when the argument after it is subtracted.

    $MyNumber = 3-4; 

    When mixing data types (a '-' might be intended as a hyphen) or if working with lists—i.e. List & Set types—see notes under concatenation.

    -= (i.e. decrement)

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

     Operator  [other Operator type actions]

     Item  [operators of similar scope]

     Mathematical  [other Mathematical operators]

     Number [about Number data type]

     v9.1.0

     Baseline

     As at baseline


    -= (i.e. decrement)

    This assignment operator is a convenient shorthand for decrementing an attribute. For example, the two following statements are equivalent:

    $MyNumber -= 3; 

    $MyNumber = $MyNumber - 3; 

    This operator may also be used with Lists and Sets.

    != (i.e. value inequality)

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

     Operator  [other Operator type actions]

     Query  [operators of similar scope]

     Query Boolean  [other Query Boolean operators]

     boolean test

     v4.6.0

     Baseline

     As at baseline


    != (i.e. inequality test)

    The operator to test inequality (i.e. 'is not the same as') is '!=', an exclamation mark followed by an equals sign.

    This operator is used either in agent queries or in the conditional part of an if(condition){action} code. It is the functional opposite of the '==' equality test.

    This test cannot be meaningfully applied to Set or List type attribute data, as the entire attribute value is matched, rather than individual values as might otherwise be assumed. For these data types use the .contains() or .icontains() operators instead, noting the scope for ambiguous matching due to stemming of words ("car" with match "car", "cars" and "carrot").

    Because equality comparisons of Date-type data match at day scope, rather than full date/time values (for legacy reasons), use interval() to compare Date-type inequality.

    Equality testing can be negated, i.e. nested for a non-match, or combined with greater/less than for a range of tests as further explored in Basic Comparison Codes.

    For a case-insensitive lexical equality test, use a lowercase on-the-fly transform:

    "Absquatulate".lowercase != "Absquatulate" 

    If we set $MyString to "Absquatulate", then:

    $MyString.lowercase != "Absquatulate" 

    If $MyOtherString(Some note) has the value "Absquatulate", then:

    $MyString.lowercase != $MyOtherString(Some note) 

    Note the stored left-side value is not altered, but its transformed version is used in the test giving a case-insensitive comparison. This method only works for upper/lower case comparisons; accented characters are lexically different characters regardless of case.

    ... (i.e. range)

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

     Operator  [other Operator type actions]

     Item  [operators of similar scope]

     Mathematical  [other Mathematical operators]

     List [about List data type]

     v9.1.0

     Baseline

     As at baseline


    ... (i.e. range)

    The range operator constructs a list of numbers from a specified starting point to a specified end point. Note: the range operator is written as 3 dots and not an ellipsis character. White space immediately before or after the operator is ignored as with other mathematical operators. For example:

    1…3 → "1;2;3"
    3 … 1 → "3;2;1"

    Note do not use enclosing quotes or square brackets with the range operator as the operator will not be correctly evaluated, resulting in the wrong outcome.

    [1…3] → "1 ... 3" WRONG!
    "1…3" → "1 ... 3" WRONG!

    The range operator binds more tightly than arithmetic operators. Thus

    1...3 * 2 → "2;4;6"

    and is the is the same as

    (1..3) * 2 → "2;4;6" 

    i.e. the parentheses in the second example are not needed.

    The range operator can be useful for performing a task a specific number of times using the List.each() operator:

    1...10.each(x){var vPath="/container/item "+x; create(vPath);} 

    and in that example the value of the loop variable x is the value for the source list generated by the range operator, i.e. it is the same as would occur in this literal example:

    "1;2;3;4;5;6;7;8;9;10".each(x){var vPath="/container/item "+x; create(vPath);} 

    In both cases, on the second iteration of the .each() loop, the loop variable x would have the value 2.

    Using non-literal range specifiers

    It may be useful to define one or both range limits. For example, if $MyNumber is 3:

    $MyList = [1 ... $MyNumber]; gives "1;2;3"

    or if variable vNum is 4:

    $MyList = 1 ..vNum; gives "1;2;3;5"

    But for more complex action code expressions using chained operators, parentheses my be needed to hint intent to Tinderbox. Thus, if $MySet has 4 items:

    $MyList = 1 ... $MySet.size; gives "1" WRONG

    so add parentheses around the expression:

    $MyList = 1 ... ($MySet.size); gives "1;2;3;4" CORRECT

    If chaining operators to a range specified using an expression, consider using parentheses around the whole range definition:

    (1 ... ($MySet.size)).each(x){$Text+= x+"\n";}; 

    The last example actually works without the parentheses but illustrates the concept.

    Using range to supply a loop counter

    When working with List.each(), it can be useful to know which source list item is being currently in scope. It is possible to use a variable (see here), but the range operator offers another method. In this method a range-generated list is iterated and in-loop the list being processed is called via List.at(). It in important to note that as .at() numbers from zero, either the range must start from zero, or the range item used with at must be adjusted by -1.

    In the following example, $MyList holds the data of interest, and a zero-based range with be generated:

    	(0 ... ($MyList.count)).each(N){
    		$MyList.at(N) ..tc.
    	}

    Thus for loop #3, the value of N will be 2 (recall the range code is making a zero based list of numbers). Thus in-loop, $MyList.at(N) will be the same as $MyList.at(2), i.e. addressing the the third item in $MyList.

    (!$AttributeName) (i.e. a short form test for no value)

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

     Operator  [other Operator type actions]

     Item  [operators of similar scope]

     Query Boolean  [other Query Boolean operators]

     boolean test

     v4.6.0

     Baseline

     As at baseline


    (!$AttributeName)

    In queries and conditional action code expressions, preceding a '$'-prefixed attribute name with an exclamation mark functions as a shortened form of the Boolean test for a false value. Due to limitations in the underlying parser, an inequality test in action code must be enclosed in parentheses.Thus the following are functional equivalents:

    $MyBoolean==false 
    (!$MyBoolean) 

    Do not use this form or you may get unexpected results:

    !$MyBoolean Do not use this format, without parentheses!

    In both cases the result is false if the value of $MyBoolean is false.

    Usefully Tinderbox also useful supports such short-form !$AttributeName tests for all the other attribute data types, returning true if the attribute has a default value. Per data type, this equates to long form tests like:

    $MyBoolean==false 
    $MyColor=="" 
    $MyDate=="never" 
    $MyDictionary=="" 
    $MyFile=="" 
    $MyInterval=="00:00" 
    $MyList==[] (or (deprecated) $MyList==""
    $MyNumber==0 
    $MySet==[] (or (deprecated) $MyList==""
    $MyString=="" 
    $MyURL=="" 

    This also holds for system-only data types:

    $MyAction=="" 
    $MyFont=="" 

    In all these cases a short-form test returns true if the attribute value is the default for that data type.

    This test is the logical opposite of the $AttributeName test.

    * (i.e. multiplication)

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

     Operator  [other Operator type actions]

     Item  [operators of similar scope]

     Mathematical  [other Mathematical operators]

     Number [about Number data type]

     v4.6.0

     Baseline

     As at baseline


    • (i.e. multiplication)

    The multiplication operator, * (asterisk character), returns the multiplication of the arguments before and after it.

    $MyNumber = 3*4; 

    Both arguments are normally Number-type data.

    Multiplying Strings

    Sometimes there is a need to expand or repeat a String. For this, the multiplication operator * may be used. Due to Tinderbox's internal type coercion effects, the number argument must be used as the first argument; placing it after the * will cause a silent fail with no resulting output. Thus, the code:

    $MyString = 3*"xyz "; 

    evaluates to a string "xyz xyz xyz". But this:

    $MyString = "xyz "*3; WRONG!

    will return nothing.

    Multiplying Lists and Sets

    Lists and Sets of numbers may be multiplied by a number. Two lists of numbers may be multiplied if they have the same length, in which case their elements are multiplied.

    [1;2;3;4] * [1;2;3;4];[1;4;9;12] 

    or, using the range operator:

    1...4 * 1...4 ➛ 1;4;9;12
    / (i.e. division)

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

     Operator  [other Operator type actions]

     Item  [operators of similar scope]

     Mathematical  [other Mathematical operators]

     Number [about Number data type]

     v4.6.0

     Baseline

     As at baseline


    / (i.e. division)

    The division operator, / (forward slash character), returns the argument before it divided by the argument after it.

    $MyNumber = 3/4; 

    By default, up to 5 decimal places are returned, so:

    $MyNumber = 10/3; 

    results in $MyNumber having a value of 3.33333.

    Be aware the forward slash character has many other symbolic meanings (POSIX folder delimiter, linguistic use e.g. 'and/or', date component delimiters, etc.). Be careful to ensure to quote or escape the / character where you do not want Tinderbox to assume a division.

    & (i.e. query logical AND join)

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

     Operator  [other Operator type actions]

     Query  [operators of similar scope]

     Query Boolean  [other Query Boolean operators]

     boolean test

     v4.6.0

     Baseline

     As at baseline


    & (i.e. query logical AND join)

    The ampersand, &, is used in queries and conditional statements as a logical AND join. Thus:

    if ($HasStock == true & $Price > 20) {$Badge="ok";} 

    The note's $Badge is only set if both the first and the second argument are true.

    See also the OR join and conditional statements using multiple arguments.

    &= (i.e. logical AND assignment)

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

     Operator  [other Operator type actions]

     Item  [operators of similar scope]

     Assignment  [other Assignment operators]

     assignment

     v4.6.0

     Baseline

     As at baseline


    &= (i.e. logical AND assignment)

    To make it easier to write rules succinctly, you can use the assignment:

    $TheAttribute &= [some code]; 

    …which sets $TheAttribute to the value of some code only if it is currently evaluated as true AND some code also evaluates as true. Thus, if $TheAttribute is false, the right-side code expression is still evaluated. An attribute that has no value set (or inherited) is evaluated as false.

    For most attributes, especially new user attributes, the default value will evaluate as false. But, $TheAttribute's data type does not have to be Boolean.

    For new String-type attributes (and string-based Action/Color/File/Font/Interval/List/Set/URL types) the default is an empty string "". For Number-type, is it 0 (zero). For Date-type, it is the string "never". For Boolean-type, is it 'false' (with no quotes, and shown as un-ticked if displayed via a tick-box). The "", 0 and "never" values—for the appropriate data types—evaluate as false. But, be aware that not all system attributes follow this assumption. For instance, the $Color default is preset to use a named Tinderbox colour, so its default value (even if inherited) would evaluate as true .

    Prototypes have no direct effect as the outcome, as it initially depends on the evaluation of the left-side attribute value regardless of whether document default, prototype inherited or locally set.

    For example, for the Boolean-type attribute $Urgent:

    $Urgent &= any(children,$Urgent); 

    Thus a project is considered urgent if it has been declared to be urgent itself and if any child is urgent.

    See also the logical OR assignment.

    Errors to the function logic were corrected.

    %matches (query back-references)

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

     Property  [other Property type actions]

     Query  [operators of similar scope]

     Data manipulation  [other Data manipulation operators]

     List [about List data type]

     v9.6.0

     Baseline

     As at baseline


    Syntax note: Operators without any defined mandatory arguments may omit their empty closing parentheses


    %matches

    The operator %matches represents a list that contains all available back-references to regular expression matches. This is equivalent to the list of back reference values [$0;$1;$2….$N], where N is the count of available regular expression matches.

    If $MyString is "I do not like green eggs and ham.", then for this code:

    	if($MyString.contains("like (((green) (eggs)) and ham)")){
    		$MyList = %matches;
    	};

    $MyList now holds 5 back-references:

    • $0: like green eggs and ham
    • $1 green eggs and ham
    • $2 green eggs
    • $3 green
    • $4 eggs

    Query back-references are discussed in fuller detail here.

    + (i.e. addition)

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

     Operator  [other Operator type actions]

     Item  [operators of similar scope]

     Mathematical  [other Mathematical operators]

     Number [about Number data type]

     v1.0.0

     Baseline

     As at baseline


    + (i.e. addition)

    The addition operator, + (plus sign character), returns the sum of the arguments before and after it.

    $MyNumber = 3+4; 

    The + sign is also used for string concatenation. Depending on context, Tinderbox will decide which operation is intended by the + sign. This is a very good reason to always enclose literal text strings in quotes.

    + (i.e. string concatenation)

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

     Operator  [other Operator type actions]

     Item  [operators of similar scope]

     Mathematical  [other Mathematical operators]

     Number [about Number data type]

     v1.0.0

     Baseline

     As at baseline


    + (i.e. string concatenation)

    The concatenation operator, + (plus sign character), joins the strings/references/code before and after it. Thus, the code:

    $FullName = $FirstName+" "+$LastName; 

    evaluates a first name "Jane" and last name "Doe" to give a string value "Jane Doe" for the FullName attribute. If the right-side code is more complex, consider adding parentheses to help signal user intent to Tinderbox.

    Mixing data types

    If the right side inputs mix text and numbers—they need treating as numbers (even if stored in strings)—see more on concatenation versus addition.

    The + (plus sign) character is also used for numerical addition. Depending on context, Tinderbox will decided which operation is intended by the + sign. This is a very good reason to always enclose literal text strings in quotes.

    Concatenating Lists (List & Set type data)

    Note that here both List-type and Set-type attributes can be considered the same as data sources, i.e. right-side inputs.

    To concatenate lists, it might appear logical to do this:

    $MyList = $SomeList+$SomeSet; WRONG!

    The result is no value is passed to $MyList. When adding lists to lists there are a variety of approaches. Note that depending on the nature of the task, and the method below that is used, it may first be necessary to reset the receiving list to the default (empty) value.

    Use the '+=' increment operator:

    $MyList += $SomeList+$SomeSet;

    Add to the existing list (older older style—use the above method):

    $MyList = $MyList + $SomeList+$SomeSet;

    Or, if if intentionally replacing current $MyList values with new ones, this may be used:

    $MyList = ($SomeList+$SomeSet);

    The additional parentheses help Tinderbox to understand all the right-side lists need to be made into one list before being passed to the left-side.

    += (i.e. increment)

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

     Operator  [other Operator type actions]

     Item  [operators of similar scope]

     Mathematical  [other Mathematical operators]

     Number [about Number data type]

     v9.1.0

     Baseline

     As at baseline


    += (i.e. increment)

    This assignment operator is a convenient shorthand for incrementing an attribute. For example, the two following statements are equivalent:

    $MyNumber += 3; 

    $MyNumber = $MyNumber + 3; 

    This operator may also be used with Lists and Sets, and += may be used to append strings:

    $MyString += "!" 

    < (i.e. less than)

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

     Operator  [other Operator type actions]

     Query  [operators of similar scope]

     Query Boolean  [other Query Boolean operators]

     boolean test

     v4.6.0

     Baseline

     As at baseline


    < (i.e. less than)

    The operator used to test if the left side of an action is less than the right side. This operator is used either in agent queries or in the conditional part of an if(condition){action} code. If $MyNumber is 3:

    $MyNumber < 4 is true 
    $MyNumber < 2 is false 

    Further explored in Basic Comparison Codes.

    <= (i.e. less than or equal to)

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

     Operator  [other Operator type actions]

     Query  [operators of similar scope]

     Query Boolean  [other Query Boolean operators]

     boolean test

     v4.6.0

     Baseline

     As at baseline


    <= (i.e. less than or equal to)

    The operator used to test if the left side of an action is less than or equal to the right side. This operator is used either in agent queries or in the conditional part of an if(condition){action} code. If $MyNumber is 3:

    $MyNumber <= 4 is true 
    $MyNumber <= 3 is true 
    $MyNumber <= 2 is false 

    Further explored in Basic Comparison Codes; in some date comparison cases, a two term query may be needed instead.

    = (i.e. value assignment)

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

     Operator  [other Operator type actions]

     Item  [operators of similar scope]

     Assignment  [other Assignment operators]

     assignment

     v1.0.0

     Baseline

     As at baseline


    = (i.e. value assignment)

    A single = symbol is used only as a method of assignment. In contrast, for tests of equivalence use a double equals sign e.g. == ):

    $AttributeA = $AttributeB; (attribute value)
    $AttributeA = data; (literal data)
    $AttributeA = 4 * ($Price / 2); (action code expression)

    The assignment is always from right to left; the left-side attribute takes the value of the right side attribute/code. It is more usual for the right side to be evaluated (as action code) than the left, though the latter can occur.

    Thus assignment sets the value of the specified left-side attribute the given right-side evaluated result; most often this is simply an attribute value. Where the right-side value is an attribute name, the $-prefix must be used. Take a note that has a $Color value of "red" and the $Rule:

    $MyUserColor = "Color"; 

    The result is not the text value red but rather it is a text value "Color". Most likely there is no defined named colour named "Color" so some other colour value, not the intended one, stored in $MyUserColor. If you want the value of an attribute, i.e. the $Color value of 'red' in this example, then your $Rule should be:

    $MyUserColor = $Color; 

    You must use the $-prefix: see further detail below.

    Actions and rules are allowed to specify a different referenced note, just as they can with a source attribute reference:

    $AttribName(parent)="theValue"; 
    $AttribName(/path/to/note)="theValue";
    $AttribName(/path/to/note)=$MyValue(parent); 
    $AttribName($AnotherAttribute)="theValue"; 

    In the last case the secondary attribute will hold a note name or path. Complex use of left-side expressions is allowed.

    Do not mix $Attribute and Attribute(regexStr) syntax in a single call, i.e. $Attribute(regex), as this will cause expected results. Use one syntax or the other. This possible conflict should only ever occur in the context of queries or operations that allow query-style code.

    If a value only needs to be assigned once, consider using a logical OR join.

    Using Paths (offset addressing)

    $AttributeA = $AttributeB( note/item/path )

    This sets the value of the $AttributeA to that of the $AttributeB of the same note (i.e. this or current), if no argument is specified, or of a note specified through name, item or path. (See more on paths). Paths may also be used on the left side of the overall action:

    $AttributeA( note/item/path ) = $AttributeB
    $AttributeA( note/item/path ) = $AttributeB( note/item/path )

    Using query back-references

    NOTE: the following syntax can only be used in the context of a query. In a query (an agent's query or an if() condition in an action) it is possible to combine a regular expression query with an action that uses the value of the found regular expression:

    query: $Text.contains("email: <(.+)>")
    action: $TheAddress=$1;

    …will set TheAddress attribute value to the regular expression found in text. It is assumed that back-references $1-$9 may be used, assuming the regular expression generates more than one such references.

    == (i.e. value equality)

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

     Operator  [other Operator type actions]

     Query  [operators of similar scope]

     Query Boolean  [other Query Boolean operators]

     boolean test

     v4.6.0

     Baseline

     As at baseline


    == (i.e. value equality)

    The operator to test equality (i.e. 'is the same as') is '==', two equals signs. Note that this replaces older syntax where a single equals sign was used contextually for both assignment and equality tests.

    This operator is used either in agent queries or in the conditional part of an if(condition){action} code. It is the functional opposite of the '!=' inequality test.

    This test cannot be meaningfully applied to Set or List type attribute data, as the entire attribute value is matched, rather than individual values as might otherwise be assumed. For these data types use the .contains() or .icontains() operators instead, noting the scope for ambiguous matching due to stemming of words ("car" will match "car", "cars" and "carrot").

    Because equality comparisons of Date-type data match at day scope, rather than full date/time values (for legacy reasons), use interval() to compare Date-type equality.

    Equality testing can be negated, i.e. tested for a non-match, or combined with greater/less than for a range of tests as further explored in Basic Comparison Codes.

    For a case-insensitive lexical equality test, use a lowercase on-the-fly transform:

    "Absquatulate".lowercase == "absquatulate" 

    If we set $MyString to "Absquatulate", then:

    $MyString.lowercase == "absquatulate" 

    If $MyOtherString(Some note) has the value "absquatulate", then:

    $MyString.lowercase == $MyOtherString(Some note) 

    Note the stored left-side value is not altered, but its transformed version is used in the test giving a case-insensitive comparison. This method only works for upper/lower case comparisons; accented characters are lexically different characters regardless of case.

    Equality and List or Sets

    Using == (and !=) with Lists & Sets means you are checking the entire literal contents, i.e. string like "ant;bee;cow" rather than by individual sub-value: "ant" and "bee" and "cow". Thus the equality test cannot be used to check if the attribute contains a discrete value, use .contains() instead (or .icontains() for case-insensitive matches). Importantly, when testing a string (or action code expression resolving to a string) equivalence against a list, it is the list that must be tested using .contains(). This is best shown using string literals representing a String type and a List type:

    "cow".contains("ant;bee;cow") (does not work as expected)
    "ant;bee;cow".contains("cow") 
    "ant;bee;Cow".contains("cow") 

    The first, testing the string, resolves to false but the second, testing the list, gives true. The third is false but would be true if using an .icontains() test. Thus when equivalence testing a string against a list, always run the .contains() on the list and not the string.

    To test two lists hold the same values (and only those values), in the same case, in the same order, the == equivalence operator can be used as this tests the stored concatenated value lists in each case. To check common items shared by two lists use list.intersect().

    Testing a List vs. a Set, it would be sensible to apply a .sort() or .isort() to each, reflecting that the sort state of a list is unknown and a == test compares the stored concatenated value string: the test would fail if the lists held the same values but stored in different orders. This shows up a difference between lists and sets. Although the literal value of a set may hold values in any order, when tested in code, they are being tested after sorting into (some**) order. Incidentally, this is why you cannot set a sort order as you can with a list as internally your given sort order is ignored. Consider $MySetA and $MyListA both with the values [ant;bee;cow]. $MySetB and $MyListB both have the value [bee;ant]. So:

    $MySetA == $MySetB gives false 
    $MyListA == $MyListB gives false 

    both are expected. Now, make both the B attributes value "bee;ant;cow"

    $MySetA == $MySetB gives true 
    $MyListA == $MyListB gives false 

    This is because the Set compares the literal result of sorted values, whereas the List

    does not. But:

    $MyListA == $MyListB.sort gives true 

    This is in effect what's happening with the sets, as in:

    $MyListA.sort == $MyListB.sort 

    whereas in our last example above, $MyListA was already in default sort order so no applied sort was required. From experiment, this seems to be a (case-sensitive) computer lexical sort, i.e. [Bee;ant;bee] with capitals preceding lowercase letters in the sort.

    > (i.e. greater than)

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

     Operator  [other Operator type actions]

     Query  [operators of similar scope]

     Query Boolean  [other Query Boolean operators]

     boolean test

     v4.6.0

     Baseline

     As at baseline


    > (i.e. greater than)

    The operator used to test if the left side of an action is greater than the right side. This operator is used either in agent queries or in the conditional part of an if(condition){action} code. If $MyNumber is 3:

    $MyNumber > 2 is true 
    $MyNumber > 4 is false 

    Further explored in Basic Comparison Codes.

    >= (i.e. greater than or equal to)

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

     Operator  [other Operator type actions]

     Query  [operators of similar scope]

     Query Boolean  [other Query Boolean operators]

     boolean test

     v4.6.0

     Baseline

     As at baseline


    >= (i.e. greater than or equal to)

    The operator used to test if the left side of an action is greater than or equal to the right side. This operator is used either in agent queries or in the conditional part of an if(condition){action} code. If $MyNumber is 3:

    $MyNumber >= 2 is true 
    $MyNumber >= 3 is true 
    $MyNumber >= 4 is false 

    Further explored in Basic Comparison Codes; in some date comparison cases, a two term query may be needed instead.

    | (i.e. query logical OR join)

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

     Operator  [other Operator type actions]

     Query  [operators of similar scope]

     Query Boolean  [other Query Boolean operators]

     boolean test

     v4.6.0

     Baseline

     As at baseline


    | (i.e. query logical OR join)

    The pipe, |, is used in queries and conditional statements as a logical OR join. Thus:

    if ($HasStock == true | $Price > 20) {$Badge="ok";} 

    The note's $Badge is only set if either the first or the second argument are true.

    See also the AND join and conditional statements using multiple arguments.

    |= (i.e. logical OR assignment)

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

     Operator  [other Operator type actions]

     Item  [operators of similar scope]

     Assignment  [other Assignment operators]

     assignment

     v4.6.0

     Baseline

     As at baseline


    |= (i.e. logical OR assignment)

    To make it easier to write rules succinctly, you may use the assignment:

    $TheAttribute |= [some code]; 

    …which sets $TheAttribute to the value of some code if it is already true OR if some code is true. An attribute that has no locally set (or inherited) value is evaluated as false. Thus there are two possible outcomes:

    • if $TheAttribute is set to a value that evaluates (the left side of the code) as true. Therefore, regardless of the state of some code, the right side of the code (some code) is not evaluated and $TheAttribute retains its current value.
    • if $TheAttribute is set to a value evaluates (the left side of the code) as false. Therefore some code (the right side of the code) is evaluated. If some code evaluates as true $TheAttribute takes the value of some code. On subsequent iteration of the code $TheAttribute thus evaluates as true. But, if some code evaluated to false, both it and the overall action evaluate as false, i.e. $TheAttribute's value remains unchanged.

    A more verbose (and less efficient at scale) way to write the same test without the |= operator is

    if((!$TheAttribute)){ ... some code;} 

    where '(!$TheAttribute)' is a short-form test meaning "if the value of attribute named 'TheAttribute' tests as false". A false value arises differently for for different attribute data types, but for for a string, the above can be further unpacked as:

    if($TheAttribute!=""){ ... some code;} 

    In practical terms this means the left side, usually an attribute, is set to the right side value only if it is not already set locally at note level. This is because for most attributes, especially new user attributes, the default value will evaluate as false. But, $TheAttribute's data type does not have to be Boolean.

    For new String-type attributes (and string-based Action/Color/File/Font/Interval/List/Set/URL types) the default is an empty string "". For Number-type, is it 0 (zero). For Date-type, it is the string "never". For Boolean-type, is it ' false' (with no enclosing quotes, and shown as un-ticked if displayed via a tick-box). The "", 0 and "never" values—for the appropriate data types—evaluate as false. But, be aware that not all system attributes follow this assumption. For instance, the $Color default is preset to use a named Tinderbox colour, so its default value (even if inherited) would evaluate as true .

    Prototypes have no direct effect as the outcome, as it initially depends on the evaluation of the left-side attribute value regardless of whether document default, prototype inherited or locally set.

    This operator's behaviour makes the |= usage very useful for doing tasks like making code run only once; on the second pass the left side already has a value so no change occurs. This avoids scenarios like successive applications of a rule causing multiple concatenation of strings (one extra each iteration).

    For example, for the Boolean-type attribute $Urgent:

    $Urgent |= any(children,$Urgent); 

    A project is urgent if it has been declared to be urgent itself, or if any child is urgent.

    If using |= assignments, it can be useful to have a means to reset an attribute to default to re-enable |= value assignment.

    See also the logical AND assignment (which is likely used less often).

    $AttributeName (i.e. a short form test for value)

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

     Operator  [other Operator type actions]

     Item  [operators of similar scope]

     Query Boolean  [other Query Boolean operators]

     boolean test

     v4.6.0

     Baseline

     As at baseline


    $AttributeName

    In queries and conditional action code expressions, using just an attribute name preceded by a $ character functions as a shortened form of the Boolean test for a true value. Thus the following are functional equivalents:

    $MyBoolean==true 
    $MyBoolean 

    In both cases the result is true if the value of $MyBoolean is true.

    In all other contexts, the $AttributeName syntax implies a reference to that attribute.

    Usefully Tinderbox also useful supports such short-form $AttributeName tests for all the other attribute data types, returning true if the attribute has a non-default value. Per data type, this equates to long form tests like:

    $MyAction!="" 
    $MyColor!="" 
    $MyDate!=never 
    $MyFile!="" 
    $MyInterval!="00:00" 
    $MyList!=[] or $MyList!="" 
    $MyNumber!=0 
    $MySet!=[] or $MySet!="" 
    $MyString!="" 
    $MyURL!="" 

    In all these cases a short-form test returns true if the attribute value is not the default for that data type.

    A reverse short form test is also offered by (!$AttributeName), i.e. the same syntax with a preceding exclamation mark and enclosing parentheses. In theory, the latter parentheses are not necessary, but in practice it helps Tinderbox when parsing a query.

    $AttributeName([scope])

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

    Operator Uses Scoped Arguments: 

    Operator Has Optional Arguments: 

     Property  [other Property type actions]

     Item  [operators of similar scope]

     Assignment  [other Assignment operators]

     source context dependent

     v4.6.0

     Baseline

     As at baseline

     [More on scoped arguments in Action Code]

     [More on optional operator arguments]


    Syntax note: Operators without any defined mandatory arguments may omit their empty closing parentheses


    $AttributeName

    $AttributeName()

    In action code contexts, an attribute's name prefixed with a $-character implies a reference to that attribute, thus a placeholder for that attribute's value. In a coding context is acts as a variable name where the variable name must be that of an existing attribute and the variable's value is got from or set to that attribute.

    A reference on the right side of an action fetches the attribute's value. A reference on the left side of an action has its value set to the result of the right side. The following example combines these uses whereby in the current object (a note, agent, adornment, etc.), the user attribute $MyNumber is being set to the value of system attribute $ChildCount:

    $MyNumber = $ChildCount; 

    In queries and conditional operators, an attribute reference implies a shortened Boolean test.

    The test can be turned in a negative (i.e. that no value is set) by using a '!' prefix: see !$AttributeName, occasionally if the !-prefix does not work, try enclosing the expression in parentheses (!$AttributeName) to help signal intent to Tinderbox's action code parser.

    $AttributeName(scope)

    Besides the basic form above, which is essentially $AttributeName(this), an offset address can also be made to the value of an attribute in another object— i.e. other than the one in current focus, by using an extended syntax where the scope argument (defining scope) to refer to one or more note(s).

    Importantly, here the scope argument is not evaluated for possible action code expressions unlike in some action code operators. This means that here, scope cannot be a complex code expression. However, where that need arises eval() may offer a workaround or consider using a user attribute to hold the output of the expression and then use that attribute's value (i.e. in the manner of bullet #4 above).

    The extended syntax form may be used on the left or right side of an action code expression. In other words, you can use this syntax to fetch (right side) or set (left side) an attribute value from some other object. Generally, offset addresses are used on the right side to fetch data from another object.

    Examples, right side:

    $MyString = $MyString("Some other note"); 
    $MyNumber = $MyNumber("A root container/Some Container/Some other note"); 
    $MyString = $MyString(agent); (this designator only works in agents)
    $MyString = $MyString(adornment); (this designator only works in adornments)
    $MyList = $MyString("Some other note;Another note;Different note"); 

    Examples, left-side:

    $MyString("Another note") = $MyString("A note"); 
    $MyDate(parent) = $MyDate; 

    In fact, an offset can even be used on both sides of the action. For instance, the rule in a note "Some note" might use the following code to refer to attributes in two other notes:

    $MyColor("A note") = $MyColor("Another note"); 
    $N (query back-reference)

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

     Property  [other Property type actions]

     Query  [operators of similar scope]

     Data manipulation  [other Data manipulation operators]

     String [about String data type]

     v9.5.0

     Baseline

     As at baseline


    Syntax note: Operators without any defined mandatory arguments may omit their empty closing parentheses


    $N

    The value of the numbered back-reference for the current query (agent or if() conditional).

    The valid range for N is from 0 (zero) to 9.

    The back-reference $0 always refers to the the whole matched string (or sub-string) for the stated query regular expression, i.e. it may match all or part of the target string. $1 to $9 refer to any further defined back-references within the overall regular expression, i.e. sub-strings within $0.

    Back-references are numbered in the order created. The order is usually left-to right in order the parentheses open, noting that this allows for nesting of back-references.

    Query back-references are discussed in fuller detail here.

    abs(sourceNum)

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

     Function  [other Function type actions]

     Item  [operators of similar scope]

     Mathematical  [other Mathematical operators]

     Number [about Number data type]

     v4.0.0

     Baseline

     As at baseline


    abs(sourceNum)

    abs() computes the absolute value of its sourceNum argument. This is the non-negative value of sourceNum without regard to its sign. Thus both these result in a $MyNumber value of 3.5:

    $MyNumber = abs(3.5); 
    $MyNumber = abs(-3.5); 

    The operator can also evaluate a numerical attribute:

    $MyNumber = abs($SomeNumber); 

    A numerical string attribute will be parsed to a number. If $MyString is a value of "-5", $MyNumber will be 5:

    $MyNumber = abs($MyString); 
    action([scope,]codeStr)

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

    Operator Has Optional Arguments: 

     Function  [other Function type actions]

     Item  [operators of similar scope]

     Data manipulation  [other Data manipulation operators]

     success boolean

     v5.8.0

     Baseline

     9.5.0

     [More on optional operator arguments]


    action([scope, ]codeStr)

    action(codeStr)

    This function allows execution of the codeStr without the need for a return value. This allows an action be set within an attribute, and perform that action as part of a rule or agent action. The optional scope argument allows the action to be run on a note other than the current note

    For example,

    action('$Color= "bright red"');

    will set the current note's primary colour ($Color).

    In its simplest form, an action() call is a quote-enclosed string. As action codes tend to use double-quoted strings, it may often be necessary to use single quotes for the outer enclosure, as in the example above.

    The action() function returns the evaluated result of the codeStr within it. In the above case if $MyString were set to store the result, the value would be true—because the action completed successfully. So, in most cases, there is no requirement for a left-side attribute to accept any output. By comparison, the related eval(expression) function evaluates an expression (a partial action) and returns a value. Whereas eval() is designed to intentionally return an output, action() performs an action such as an assignment.

    An action() call can be used with a do(macro) call to create a form of function as macros allow input arguments (its arguments): see do().

    The action() call is particularly useful during export where it is desirable to run some action code in the context of the template during template rendering (evaluation)—see more below.

    On-the-fly Attribute references using action()

    Occasionally it is necessary to make at attribute value reference string from a variable, i.e. if the variable holds 'Path' the result being '$Path' as opposed to the value of $Path. Whilst $MyString refers to the value of attribute MyString, what if the attribute name is itself the value of a variable in the current code? Here action() solves the problem. For instance, if vAnAttr holds as its value the name of an attribute, e.g. "SomeAttribute" then the following does not work:

    $MyString = "$" + vAnAttr; WRONG ($MyString is the value of $SomeAtttribute)

    as $MyString is not set to the value of $SomeAttr. Instead use action():

    action('$MyString = "$" + vAnAttr'); CORRECT ($MyString is the string '$SomeAtttribute')

    To build a series of $-prefixed attribute references in a loop, use action() instead of eval(), as described in more detail here.

    action(scope, code)

    If an optional first scope argument is provided, the code is not run on the current note but on that defined by scope (defining scope). Thus:

    action("Some note","$Color = 'blue';"); 

    will set the colour of note "Some note" to blue.

    This option can avoid needing to use offset references in code, especially if the offset address is being defined by a variable.

    Legacy

    The following information is now superseded by both the advent of stamp notes (in the Hints container) and the stamp() operator.

    Calling stamp code via action()

    If a stamp's code is long/complex it can be convenient to store it in a code note. Thus if a code note 'Test-stamp' held the action code $Colour="red";, then a stamp with the code:

    action($Text("Test-stamp")); 

    when run would result in the stamped note(s) turning red. The example is trivial but shows the technique. Note the offset address in the stamp to the code note is case sensitive and should use a unique $Name (or else cite the full $Path to the code note). Local attribute references, i.e. $Color or $ChildCount, are bound to the note being stamped: it is not possible to reference values in the code note using a designator.

    any(scope, condition)

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

    Operator Uses Regular Expressions: 

    Operator Uses Scoped Arguments: 

    Operator Has Conditional Arguments: 


    any(scope, condition)

    This Boolean operator examines notes at scope (defining scope) and determines whether any note(s) in the defined group evaluates condition as true.

    scope may be any group designator, or group defined by find().

    The overall condition must not be enclosed in quotes, though a literal string value within the query will need to be quoted. For example:

    any(children,$Status=="Important") 
    any(children,$Overdue==true) 
    any(children,$Overdue) (using short form test)
    any(children,$Overdue==false) 
    any(children,!$Overdue) (using short form test)

    If trying to resolve contains() for multiple matches, use any(children,$Name=="string"). Thus of it is desired for an agent to list the parent containers of all notes titled 'foo', the agent query would be:

    any(children,$Name=="foo") 

    If agents are present, it may be sensible to filter for aliases:

    any(children,$Name=="foo") & !$IsAlias 

    See also: every().

    atan(radiansNum)

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

     Function  [other Function type actions]

     Item  [operators of similar scope]

     Mathematical  [other Mathematical operators]

     Number [about Number data type]

     v4.0.0

     Baseline

     As at baseline


    atan(radiansNum)

    atan() converts its radiansNum, in radians, to the arctangent of that value.

    $MyNumber = atan(6); 

    returns 1.405647649 for an input of 6 radians.

    attribute(attributeNameStr).keys

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

     Function  [other Function type actions]

     Document  [operators of similar scope]

     Document configuration  [other Document configuration operators]

     List [about List data type]

     v9.5.0

     Baseline

     As at baseline


    attribute(attributeNameStr).keys

    This returns a List of the attribute dictionary keys for the attribute named in the attributeNameStr argument. Keys are returned in the order listed for attribute(), and not in alphabetical order—as might be intuited. Being a Dictionary operator, it is possible to retrieve all the above as a list of key:value pairs. Note that any attribute name (any valid name) must be supplied as first argument:

    $MyList = attribute("Width").keys; 

    returns the entire contents of the Dictionary key:value pairs for the attribute Width.

    From v10.1.1, attributeNameStr may be a variable or attribute value instead of a literal string. As the attribute name may thus be a variable, a more useful method is to iterate the list of keys:

    
    var:list vKeys;
    var:string vOutput;
    vKeys = attribute(anAttribute).keys;
    vKeys.each(aKey){
    	vOutput += aKey + ": " + attribute(anAttribute)[aKey] + "\n";
    };
    $Text = vOutput;

    By combining with document(), it is possible to make a stamp that creates a listing of all user attributes in the current document, iterate each one, report only keys with a value and place the resulting data in the $Text of the stamped note the stamp code is;

    
    var:list vKeys;
    var:string vOutput;
    var:list vAttributes = document["user-attributes"];
    vOutput += "TBX filename " + document[name] + "\n";
    vOutput += "Number of  user attributes: " + vAttributes.count + "\n--------------------\n";
    vAttributes.each(anAttribute){
    	vOutput += "--------------------\n" + anAttribute + "\n" +"----------\n";
    	vKeys = attribute(anAttribute).keys;
    	vKeys.each(aKey){
    		if(attribute(anAttribute)[aKey] != "" & aKey != "category"){
    			vOutput += aKey + ": " + attribute(anAttribute)[aKey] + "\n";
    		};
    	};
    };
    $Text = vOutput;
    attribute(attributeNameStr)[keyStr]

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

     Function  [other Function type actions]

     Document  [operators of similar scope]

     Document configuration  [other Document configuration operators]

     Dictionary [about Dictionary data type]

     v9.0.0

     Baseline

     As at baseline


    attribute(attributeNameStr)[keyStr]

    The attribute() operator, for the specified attribute attributeNameStr, returns a Dictionary of key values that describe that attribute. attributeNameStr may also be a variable or attribute value instead of a literal string. Keys names are all-lowercase and case-sensitive. The current keys are listed below. Keys are editable value attribute

    • category (read-only): the category (group) in which the attribute appears.
    • default: the attribute default value.
    • description: a short description the the attribute. For user attributes, this needs to be set by the user (either here via the Inspector).
    • lines: the number of lines used for display of values in Displayed Attributes and Get Info tables. Only used for data types Dictionary, List, Set, String.
    • readonly (read-only): is true for read-only attributes, else no value. This setting is explained under non-editable notes.
    • sequential (read-only): only used by Number data types. A string value YES if true, else no value.
    • suggested: the attribute's suggested values. Empty unless set by the user. Only used by data types Dictionary, List, Set, and String.
    • type (read-only): a string describing the Data type of the attribute.

    Some read-only properties may be modified via the User Attributes Inspector, but not via action code.

    Key values

    If any key is not set, e.g. there are no 'suggested' values, then an empty string is returned for that key.

    All keys return a value called via keyStr. The most appropriate attribute type is shown as the recipient of the data:

    $MyString = attribute("Width")["category"] 
    $MyList = attribute("Width")["default"] 
    $MyString = attribute("Width")["description"] 
    $MyNumber = attribute("Width")["lines"] 
    $MyBoolean = attribute("Width")["readonly"] 
    $MyBoolean = attribute("Width")["sequential"] (as 'YES' coerces to true)
    $MyList = attribute("Width")["suggested"] 
    $MyString = attribute("Width")["type"] 

    Note that when using literal (i.e. actual) attribute name or keys it is recommended the word(s) are quote enclosed as above. If using variables, as in the earlier code examples, quotes are not used as this aids the Tinderbox parser detecting literal vs. variable usage.

    Attribute categories

    All attributes belong to an organisation group, and this is stored in the category property. Note that whilst system attributes comprise a series of groups, all user attributes are in group 'user'.

    Editing key values

    Some keys can be modified via action code, all others are read-only. Actions may modify the default, description, lines, or suggested values of an attribute:

    attribute("attributeName")["suggested"]="value 1; value 2"; 

    sets two values for the attribute's suggested values list. Likewise a default value can be set:

    attribute("attributeName")["default"]="value 1"; 

    Or a description:

    attribute("Price")["description"]="The price of the item."; 

    Thus, for instance, action code might find the discrete values for an attributes (use values() or collect(), etc.) and use that list to set/update the attributes suggested values (i.e. the suggested key value).

    Setting property values

    Both the attribute name and/or the facet to be set may be enclosed in quotation marks (previously, use of quotes caused a failure):

    attribute(AttributeName)[facet]="testing"; 

    or

    attribute("AttributeName")["facet"]="testing"; 
    attributeEncode(dataStr)

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

     Function  [other Function type actions]

     Item  [operators of similar scope]

     Formatting  [other Formatting operators]

     String [about String data type]

     v4.6.0

     Baseline

     As at baseline


    attributeEncode(dataStr)

    This function encodes all instances of the following in the argument string dataStr to numeric HTML entities . Thus:

    • left angle bracket → &lt; 
    • right angle bracket → &gt; 
    • ampersand → &amp; 
    • (straight) double quote → &quot; 
    • (straight) apostrophe → &apos; 
    • line feed character (ASCII #10) → &#10; 

    **This assists with OPML work as paragraph breaks are not allowed within XML attribute values.

    For example, if the source dataStr is "this & that":

    $MyString = attributeEncode("this & that") outputs "this &amp; that".

    An older export code equivalent was ^opmlEncode()^; the latter is deprecated in favour of the form ^value(attributeEncode(…))^.

    XML export

    As attributeEncode() encodes all the unsafe XML characters, this operator can be thought of as 'xmlEncode()', so can even be used to encode $Text.

    For website XML sitemaps, e.g. for indexing/SEO purposes, that need to report page URLs in XML (as opposed to HTML) avoid ^path^ but instead use ^value(attributeEncode($HTMLExportPath))^.

    avg_if(scope, condition, actionStr)

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

    Operator Uses Scoped Arguments: 

    Operator Has Conditional Arguments: 

     Function  [other Function type actions]

     Conditional Group  [operators of similar scope]

     Mathematical  [other Mathematical operators]

     Number [about Number data type]

     v4.6.0

     Baseline

     As at baseline

     [More on scoped arguments in Action Code]

     [More on conditional operator arguments]


    avg_if(scope, condition, actionStr)

    The function avg_if() computes the arithmetic mean of a list of the values of scope items, and returns a List-type data. Each of the items in scope (defining scope) is tested and ignored it if it fails to meet condition, otherwise items supply a value to then adding the value of each list item evaluated using the designated actionStr expression. Be aware that the per-item value might be a literal value, an attribute value, or a value/string of content based on that item's actionStr.

    For a related, less focused, operator see avg().

    This computes the arithmetic mean of the value of a actionStr in a group, as filtered by a condition expression. See avg() for a for a related non-conditional operator.

    scope describes the note(s) to be examined and may be any group designator including a find() query.

    condition is action code forming a valid conditional query test, i.e. it equates to true when matched. Some query-style operators terms may allow use of regular expressions.

    actionStr may be any valid action code expression, but will usually be a reference to an attribute; short form Boolean attribute expressions are acceptable.

    For example:

    $MyNumber = avg_if(children(/Catalog),$Price!=0,$Price); 

    sets $MyNumber to the average price of all the items in Catalog, ignoring any items that have a price of 0.

    avg(scope, actionStr)

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

    Operator Uses Scoped Arguments: 

    Operator Has Newer Dot-Operator Variant: 

     Function  [other Function type actions]

     Group  [operators of similar scope]

     Mathematical  [other Mathematical operators]

     Number [about Number data type]

     v4.6.0

     Baseline

     As at baseline

     [More on scoped arguments in Action Code]

    Yes


    avg(scope, actionStr)

    This computes the arithmetic mean of the value of a actionStr expression in a scope. See avg_if() for a for a related conditional operator.

    scope describes the notes to be examined and may be any group designator including a find() query.

    actionStr may be any valid action code expression, but will usually be a reference to an attribute; short form Boolean attribute expressions are acceptable.

    For example:

    $MyNumber = avg(children(/Catalog),$Price); 

    returns the average price of all the items in Catalog.

    See list.avg() for a dot-operator using a list for scope.

    between(valueNum, minNum, maxNum)

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

     Function  [other Function type actions]

     Item  [operators of similar scope]

     Query Boolean  [other Query Boolean operators]

     boolean test

     v5.0.0

     Baseline

     As at baseline


    between(valueNum, minNum, maxNum)

    Returns Boolean true if the valueNum is greater or equal to minNum and less than maxNum. The comparison method is based on the type of valueNum; numerical, lexical, string and set comparisons are chosen as needed.

    The logic is:

    ((valueNum >= minNum) & (valueNum < maxNum))

    Thus between() is true if valueNum==minNum but false if valueNum==maxNum.

    If $MyNumber is 7, then:

    $MyBoolean = between($MyNumber, 1, 5); is false 
    $MyBoolean = between($MyNumber, 1, 9); is true 

    More realistically the operator would be used in a query or a conditional expression:

    if(between($MyNumber, 1, 5)){…}else{…}; would test as true and execute the code in the first conditional branch.

    Do not use this operator for testing Date-type attributes directly. Either use days() instead or use between() with format() or Date.format() to create a suitable string values for testing.

    In the query creation pop-ups of agent and Find dialogs this function is listed as "is between".

    Legacy issues

    This operator replaces the legacy #between query operator.

    capitalize(dataStr)

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

    Operator Has Newer Dot-Operator Variant: 

     Function  [other Function type actions]

     Item  [operators of similar scope]

     Formatting  [other Formatting operators]

     String [about String data type]

     v4.6.0

     Baseline

     As at baseline

    Yes


    capitalize(dataStr)

    The contents of text string dataStr is returned with the first letter of each word in upper case.

    Functionally equivalent to String.capitalize.

    if $MyString is "hello world":

    $MyString = $MyString.capitalize(); 

    sets it to "Hello World".

    ceil(sourceNum)

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

    Operator Has Newer Dot-Operator Variant: 

     Function  [other Function type actions]

     Item  [operators of similar scope]

     Mathematical  [other Mathematical operators]

     Number [about Number data type]

     v6.0.0

     Baseline

     As at baseline

    Yes


    ceil(sourceNum)

    rounds the number value of sourceNum up to next whole integer. Alternative version is Number.ceil().

    See also floor() and round().

    If $MyNumber is 3.2 then:

    $MyNumber = ceil($MyNumber); 

    sets $MyNumber to 4. Note unlike normal rounding the value is set upwards to the next integer (i.e. whole number).

    changed([scope])

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

    Operator Uses Scoped Arguments: 

    Operator Has Optional Arguments: 

     Operator  [other Operator type actions]

     Item  [operators of similar scope]

     Data manipulation  [other Data manipulation operators]

     success boolean

     v9.6.0

     Baseline

     As at baseline

     [More on scoped arguments in Action Code]

     [More on optional operator arguments]


    changed()

    changed([scope])

    The changed() operator tells the current item to update itself. A likely use for the operator is to refresh Poster notes. There is an optional scope argument, indicating which note(s) need updating. If no scope argument is passed, the target is assumed to be the currently selected note.

    The operator needs no left-side argument, so may be called as a simple action code expression:

    changed(); 

    or, more specifically:

    changed("Some poster note"); 
    collect_if(scope, condition, actionStr)

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

    Operator Uses Regular Expressions: 

    Operator Uses Scoped Arguments: 

    Operator Has Conditional Arguments: 

    Operator Has Newer Dot-Operator Variant: 

     Function  [other Function type actions]

     Conditional Group  [operators of similar scope]

     Dictionary, Set & List operations  [other Dictionary, Set & List operations operators]

     List [about List data type]

     v4.0.0

     Baseline

     As at baseline

     [More on regular expressions in Tinderbox]

     [More on scoped arguments in Action Code]

     [More on conditional operator arguments]

    Yes


    collect_if(group, condition, actionStr)

    The function collect_if() returns a List by collecting all the notes in scope (defining scope), testing each note in scope and ignoring it if it fails to meet condition, then adding the value of each list item evaluated using the designated actionStr. Be aware that the per-item value might be a literal value, an attribute value, or a value/string of content based on that item's actionStr.

    For a related, less focussed, operator see collect().

    scope may be any group designator, or group defined by find(). In addition, scope may be argument that designates a particular (single) note other than 'this' collect() omits notes for which $Searchable is false.

    condition is action code forming a valid conditional test, i.e. it equates to true when matched.

    actionStr can be any action code expression, but is typically an attribute's name. If the collected per-item value type is multi-value, i.e. Set or a List type data , collect() adds its elements to the returned list. Thus if an item's evaluated value is a list of 3 terms, that item contributes 3 items to the operator's returned list rather than 1 item.

    If the collected actionStr's evaluated result is not a Set or List type attribute, but contains a semicolon, quotation mark, or parentheses, the value will be added to the result as a quoted string. This behaviour is designed correct a variety of confusing edge cases.

    For example,

    $MyList = collect_if(children,$Status=="Important",$Name); 

    will construct a List of the names of all of this note's important children.

    Note that collect_if's function is related to agents; many tasks you might perform with collect_if could be done as well, or better, with an agent. 

    If a list of unique values is required, i.e. set rather than a list, simply pass the output to a Set attribute. Thus if:

    $MyList = collect_if(children,$Age>6,$FavFruit); $MyList is [Apples;Oranges;Pears;Apples]
    $MySet = collect(children,$Age>6,$FavFruit); $MySet is [Apples;Oranges;Pears] 

    If the collected attribute is a Set or a List, collect() adds its elements to the result. If the collected attribute is not a Set or a List, but contains a semicolon, quotation mark, or parentheses, the value will be added to the result as a quoted string. This should avoid a variety of confusing edge case outcomes.

    collect_if() resets its regular expression match list for each note it tests. Thus, $1 will be the first matched subexpression for this note, rather than the first matched subexpression for the entire collect_if() statement.

    collect_if() vs. list.collect_if()

    For working with Lists or Sets of actual values, also see list.collect_if().

    collect(scope, actionStr)

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

    Operator Uses Scoped Arguments: 

    Operator Has Newer Dot-Operator Variant: 

     Function  [other Function type actions]

     Group  [operators of similar scope]

     Dictionary, Set & List operations  [other Dictionary, Set & List operations operators]

     List [about List data type]

     v4.0.0

     Baseline

     As at baseline

     [More on scoped arguments in Action Code]

    Yes


    collect(scope, actionStr)

    The function collect returns a List by collecting all the notes in scope (defining scope), and adding the value of each list item evaluated using the designated actionStr expression. Be aware that the per-item value might be a literal value, an attribute value, or a value/string of content based on that item's actionStr.

    For a related, more focussed, operator see collect_if().

    scope may be any group designator, or group defined by find(). In addition, scope may be argument that designates a particular (single) note other than 'this'. collect() omits notes for which $Searchable is false.

    actionStr can be any expression, but is typically an attribute's name. If the collected per-item value type is multi-value, i.e. Set or a List type data , collect() adds its elements to the returned list. Thus if an item's evaluated value is a list of 3 terms, that item contributes 3 items to the operator's returned list rather than 1 item.

    If the collected actionStr is not a Set or List type attribute, but contains a semicolon, quotation mark, or parentheses, the value will be added to the result as a quoted string. This behaviour is designed correct a variety of confusing edge cases.

    For example,

    $MyList = collect(children,$Name); 

    constructs a set with the name of each child of the note.

    For example,

    $MyList = collect(children(/agents/books),$Name); 

    does the same for children of the note 'books' inside 'agents'.

    $MyList = collect(children,$Width * $Height); 

    collects a series of numerical values of each child's map icon height/width in Tinderbox map units. Thus if a child had a $Width of 4 and $Height of 2, the collect() result for that item would be 8.

    If a list of unique values is required, i.e. set rather than a list, simply pass the output to a Set attribute. Thus if:

    $MyList = collect(children,$FavFruit); $MyList is [Apples;Oranges;Pears;Apples]
    $MySet = collect(children,$FavFruit); $MySet is [Apples;Oranges;Pears]

    collect() vs. list.collect()

    For working with Lists or Sets of actual values, also see list.collect().

    Color.blue()

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

     Property  [other Property type actions]

     Item  [operators of similar scope]

     Color  [other Color operators]

     Number [about Number data type]

     v5.7.0

     Baseline

     As at baseline


    Syntax note: Operators without any defined mandatory arguments may omit their empty closing parentheses


    Color.blue()

    Color.blue

    This property sets or returns the value of the blue channel of an RGB colour. The value may be set with a number (0–255) or hex number (#00–#ff). The return value (if coerced to a string or number) is always a number, i.e. 255 and not #ff. By comparison the rgb() operator requires that the values for all three colour channels be set. Examples:

    $MyColor.blue = 255; 
    $MyColor.blue = "#ff"; 
    $MyOtherColor.green = $MyColor.blue; (value of $MyOtherColor green channel is that of $MyColor blue channel)
    $MyNumber = $MyColor.blue;  (gives 255)
    $MyString = $MyColor.blue;  (gives "255")
    Color.brightness()

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

     Property  [other Property type actions]

     Item  [operators of similar scope]

     Color  [other Color operators]

     Number [about Number data type]

     v5.7.0

     Baseline

     As at baseline


    Syntax note: Operators without any defined mandatory arguments may omit their empty closing parentheses


    Color.brightness()

    Color.brightness

    This property sets or returns the brightness value of the associated Color-type attribute. The value is a number in the range 0-100. This operator is intended to replace the now-deprecated brightness() operator. Examples:

    $MyColor.brightness = 50; (sets 50% brightness)
    $MyColor2.brightness = $MyColor.brightness; (matches brightness levels) 
    $MyNumber = $MyColor.brightness; (returns 50, from above example)
    Color.format()

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

     Function  [other Function type actions]

     Item  [operators of similar scope]

     Formatting  [other Formatting operators]

     String [about String data type]

     v5.8.0

     Baseline

     As at baseline


    Color.format()

    Returns Color as a hex-string, regardless of source data is a hex value or named color.

    Thus if $MyColor is "bright red":

    $MyString = $MyColor.format(); gives "#ff0000"
    $MyString = $MyColor; gives "bright red"

    Whilst if $MyColor is "#330099":

    $MyColor.format(); gives "#330099"
    $MyString = $MyColor; gives "#330099"

    Therefore for a Color-type attribute set to a named colour, to get that name string simply pass the attribute's value to a string. So if $MyColor is "bright blue", this:

    $MyString = $MyColor; 

    …gives "bright blue" and this:

    $MyString = $MyColor + " ("+$MyColor.format()+")";

    …gives "bright blue (#0000ff)".

    This supplements the existing format() function.

    Color.green()

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

     Property  [other Property type actions]

     Item  [operators of similar scope]

     Color  [other Color operators]

     Number [about Number data type]

     v5.7.0

     Baseline

     As at baseline


    Syntax note: Operators without any defined mandatory arguments may omit their empty closing parentheses


    Color.green()

    Color.green

    This property sets or returns the value of the green channel of an RGB colour. The value may be set with a number (0–255) or hex number (#00–#ff). The return value (if coerced to a string or number) is always a number, i.e. 255 and not #ff. By comparison the rgb() operator requires that the values for all three colour channels be set. Examples:

    $MyColor.green = 255; 
    $MyColor.green = "#ff"; 
    $MyOtherColor.red = $MyColor.green; (value of $MyOtherColor red channel is that of $MyColor green channel)
    $MyNumber = $MyColor.green;  (gives 255)
    $MyString = $MyColor.green;  (gives "255")
    Color.hue()

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

     Property  [other Property type actions]

     Item  [operators of similar scope]

     Color  [other Color operators]

     Number [about Number data type]

     v5.7.0

     Baseline

     As at baseline


    Syntax note: Operators without any defined mandatory arguments may omit their empty closing parentheses


    Color.hue()

    Color.hue

    This property sets or returns the hue value of the associated Color-type attribute. The value is a number in the range 0-360. This operator is intended to replace the now-deprecated hue() operator. Examples:

    $MyColor.hue = 270; (sets hue of 270 degrees)
    $MyColor2 = $MyColor.hue; (matches hues) 
    $MyNumber = $MyColor.hue; (returns 270, from above example)
    Color.red()

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

     Property  [other Property type actions]

     Item  [operators of similar scope]

     Color  [other Color operators]

     Number [about Number data type]

     v5.7.0

     Baseline

     As at baseline


    Syntax note: Operators without any defined mandatory arguments may omit their empty closing parentheses


    Color.red()

    Color.red

    This property sets or returns the value of the blue channel of an RGB colour. The value may be set with a number (0–255) or hex number (#00–#ff). The return value (if coerced to a string or number) is always a number, i.e. 255 and not #ff. By comparison the rgb() operator requires that the values for all three colour channels be set. Examples:

    $MyColor.red = 255; 
    $MyColor.red = "#ff"; 
    $MyOtherColor.blue = $MyColor.red;  (value of $MyOtherColor blue channel is that of $MyColor red channel)
    $MyNumber = $MyColor.red;  (gives 255)
    $MyString = $MyColor.red;  (gives "255")
    Color.saturation()

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

     Property  [other Property type actions]

     Item  [operators of similar scope]

     Color  [other Color operators]

     Number [about Number data type]

     v5.7.0

     Baseline

     As at baseline


    Syntax note: Operators without any defined mandatory arguments may omit their empty closing parentheses


    Color.saturation()

    Color.saturation

    This property sets or returns the saturation value of the associated Color-type attribute. The value is a number in the range 0-100. This operator is intended to replace the now-deprecated saturation() operator. Examples:

    $MyColor.saturation = 50; (sets 50% saturation)
    $MyColor2.saturation = $MyColor.saturation; (matches saturation levels) 
    $MyNumber = $MyColor.saturation; (returns 50, from above example)
    compositeFor(nameStr)

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

     Function  [other Function type actions]

     Composite  [operators of similar scope]

     Composite  [other Composite operators]

     List [about List data type]

     v7.0.0

     Baseline

     As at baseline


    compositeFor(nameStr)

    returns a List-type list of paths of all notes in the composite containing note nameStr.

    $MyList = compositeFor("Total"); 

    By using designator this for item, any note in the composite can refer to its containing composite.

    $MyList = compositeFor(this); 

    If the name of a composite is known, but not the note name(s) or any of its constituents, use compositeWithName().

    compositeFor(nameStr):count

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

     Property  [other Property type actions]

     Composite  [operators of similar scope]

     Composite  [other Composite operators]

     Number [about Number data type]

     v7.0.0

     Baseline

     As at baseline


    compositeFor(nameStr):count

    returns the Number of notes in the composite containing note nameStr.

    This code can also use the 'my' designator to give a shorter form. These are functional equivalents:

    $MyNumber = compositeFor(this):count; 
    $MyNumber = my:count; 
    compositeFor(nameStr):kind

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

     Property  [other Property type actions]

     Composite  [operators of similar scope]

     Composite  [other Composite operators]

     String [about String data type]

     v7.0.0

     Baseline

     As at baseline


    compositeFor(nameStr):kind

    returns the String name of the composite from which the composite containing note nameStr was instantiated.

    For example, if a composite was created from the built-in 'list' composite, this function will return "list". The query:

    $MyString = compositeFor(this):kind=="book"; 

    would locate all notes that participate in composites instantiated from "book" – all books.

    This code can also use the 'my' designator to give a shorter form. These are functional equivalents:

    $MyString = compositeFor(this):kind; 
    $MyString = my:kind; 
    compositeFor(nameStr):name

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

     Property  [other Property type actions]

     Composite  [operators of similar scope]

     Composite  [other Composite operators]

     String [about String data type]

     v7.0.0

     Baseline

     As at baseline


    compositeFor(nameStr):name

    returns the String name of the composite containing note nameStr. This operator is read/write:

    $MyString = compositeFor(this):name="example"; 

    renames the composite containing the note running this code to 'example'.

    This code can also use the 'my' designator to give a shorter form. These are functional equivalents:

    $MyString = compositeFor(this):name; 
    $MyString = my:name; 
    compositeFor(nameStr):role(roleStr)

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

     Property  [other Property type actions]

     Composite  [operators of similar scope]

     Composite  [other Composite operators]

     List [about List data type]

     v7.0.0

     Baseline

     As at baseline


    compositeFor(nameStr):role(roleStr)

    returns a List-type list of paths of all notes in the composite containing note nameStr, but including only the note or notes with the designated role roleStr. For example, to set the color of all notes with the role "author":

    $MyList = $Color(compositeFor("great books"):role("author"))="red"; 

    This code can also use the 'my' designator to give a shorter form. These are functional equivalents:

    $MyList = compositeFor(this):role("some role"); 
    $MyList = my:role("some role"); 
    compositeFor(nameStr):roles

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

     Property  [other Property type actions]

     Composite  [operators of similar scope]

     Composite  [other Composite operators]

     Set [about Set data type]

     v7.0.0

     Baseline

     As at baseline


    compositeFor(nameStr):roles

    returns a Set-type list of roles that appear in the composite containing note nameStr.

    This code can also use the 'my' designator to give a shorter form. These are functional equivalents:

    $MySet = compositeFor(this):roles; 
    $MySet = my:roles; 
    compositeWithName(compositeNameStr)

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

     Function  [other Function type actions]

     Composite  [operators of similar scope]

     Composite  [other Composite operators]

     List [about List data type]

     v7.0.0

     Baseline

     As at baseline


    compositeWithName(compositeNameStr)

    returns a List-type list of paths of all notes within the composite with the name compositeNameStr. If several composites have the same name, data for only one of those composites is returned (first match by $OutlineOrder).

    $MyList = compositeWithName("Lecture 16");t

    If working in the context of a note already in a composite, compositeFor(this) will also return an appropriate list of paths.

    contains(item)

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

    Operator Uses Regular Expressions: 

    Operator Has Newer Dot-Operator Variant: 

     Function  [other Function type actions]

     Item  [operators of similar scope]

     Query Boolean  [other Query Boolean operators]

     boolean test

     v4.6.0

     Baseline

     As at baseline

     [More on regular expressions in Tinderbox]

    Yes


    contains(item)

    Returns Boolean true if the note evaluated from a single item is a direct child of the current note or, put conversely, if the note is the parent of item. Thus it can be thought of as an "is parent of" operator and, as such, a counterpart to the "is a child of" operator inside().

    The item argument must be quoted unless an attribute reference. Ways to define item.

    Examples:

    contains("/foo") 

    This is a full path so can match only the root-level note 'foo'. But:

    contains("bar") 

    could match any note with the name 'bar' of which there may be more than one. If there is more that one, Tinderbox chooses one. This is fine if one match was desired but if there are known to be multiple 'bar' notes and it is desired to locate parent container of every one, then a different approach is needed, using any(): the process is described under any().

    NOTE: Checking attribute values, as opposed to object containment

    There are a range of other tools to check if a String-, List- or Set-type attribute's value contains a desired search string/regular expression.

    • For String attributes there are String.contains() and String.icontains().
    • List and Set date type attributes also support .contains() and .icontains() though in this context the scope of regular expression matches is slightly different from that with a String-type attribute (see the linked articles).
    • Single words alone can be checked using word(), which works across $Name, $Text and all String-type attributes.

    Legacy issues

    This operator replaces the legacy #contains query operator. The latter should not be used for new code.

    cos(radiansNum)

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

     Function  [other Function type actions]

     Item  [operators of similar scope]

     Mathematical  [other Mathematical operators]

     Number [about Number data type]

     v4.0.0

     Baseline

     As at baseline


    cos(radiansNum)

    cos() converts its radiansNum, in radians, to the cosine of that value.

    $MyNumber = cos(6); 

    returns 0.9601702867 for an input of 6 radians.

    count_if(scope, condition)

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

    Operator Uses Regular Expressions: 

    Operator Uses Scoped Arguments: 

    Operator Has Conditional Arguments: 

    Operator Has Newer Dot-Operator Variant: 

     Function  [other Function type actions]

     Group  [operators of similar scope]

     Data manipulation  [other Data manipulation operators]

     Number [about Number data type]

     v4.6.0

     Baseline

     As at baseline

     [More on regular expressions in Tinderbox]

     [More on scoped arguments in Action Code]

     [More on conditional operator arguments]

    Yes


    count_if(scope, condition)

    Counts the number of notes in the list derived from scope that satisfy the evaluated query expression condition.

    NOTE: where scope is a known List or Set type attribute reference, it is recommended and generally easier, and recommended, to use list.count_if().

    scope describes the notes to be examined (defining scope).

    condition is action code forming a valid conditional query test, i.e. it equates to true when matched. Some query-style operators terms may allow use of regular expressions.

    This equivalent to use of sum_if(), as the next two code examples have the same result:

    sum_if(group, condition,1)

    but this is perhaps more easily understood as:

    count_if(group, condition)
    count(scope)

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

    Operator Uses Scoped Arguments: 

    Operator Has Newer Dot-Operator Variant: 

     Function  [other Function type actions]

     List  [operators of similar scope]

     Data manipulation  [other Data manipulation operators]

     Number [about Number data type]

     v4.0.0

     Baseline

     As at baseline

     [More on scoped arguments in Action Code]

    Yes


    count(scope)

    The function count() counts the Number of discrete items in the specified list, scope, which is defined as a group of items—i.e. one or more items.

    Most often, list may be a reference to a List or Set typed data. The list argument is evaluated so can use more than literal lists, including offset addresses like $Attribute(note) or more complex action code expressions to get data as long as the result is a list-based attribute (List or Set data types).

    NOTE: where scope is a known List or Set type attribute reference, it is recommended and generally easier, and recommended, to use list.count() (or alternatively the older less intuitive list.size()); both the latter give the same outcome.

    count(scope)

    For example if $DisplayAttributes for the current note is [Color;AccentColor;NameFont] then the code

    $MyNumber = count($DisplayAttributes); 

    is effectively

    $MyNumber = count([Color;AccentColor;NameFont]); 

    and not surprisingly returns 3. Note that the count is not all unique values for the attribute across the whole TBX, scope is restricted to 'this' note or another nominated note. Specimen usage:

    $MyNumber = count($DisplayAttributes); 
    $MyNumber = count($DisplayAttributes("some other note")); 

    To use count() with a list of items that are attributes or action code expressions, use list():

    Works: $MyNumber = count(list(4+2,9+6)); (output: 2)

    For more complex examples, where list items are action code expressions, it may be necessary to use eval() to wrap each list item expression e.g. list(eval(expressionA),eval(expressionB)).

    Examples

    The following is a trivial example (given we could use $ChildCount instead) but shows how count can be used in a more subtle way:

    $MyNumber = count(collect(children,$Name)); 

    The result of collect is List-type data, in this case a number of note titles count(list) will return the number of values in the list (including duplicates). To get a de-duped count, chain the .unique operator to the list reference, inside the count() operator so the .unique filter is applied before the count is taken:

    $MyNumber = count(collect(children,$Name).unique); 
    covid([stateStr, countryStr|zipCodeStr], aDate, keywordStr)

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

    Operator Has Optional Arguments: 

     Function  [other Function type actions]

     Item  [operators of similar scope]

     Data manipulation  [other Data manipulation operators]

     Number [about Number data type]

     v8.7.0

     Baseline

     As at baseline

     [More on optional operator arguments]


    covid(zipCodeStr, dateStr, keywordStr)

    covid(stateStr, countryStr, aDate, keywordStr)

    The operator covid() returns information about the 2020 pandemic of the COVID-19 virus.

    covid(zipCodeStr, aDate, keywordStr)

    Returns the number of cases, deaths, and recoveries reported that day in the US country that contains this zip code. For example

    $MyNumber = covid("02148", date(2020,1,4), "cases"); 

    This returns the number of cases reported in Middlesex County, Massachusetts for 4 January 2020. The keywordStr argument may be a quoted string with any of the following values:

    • cases
    • deaths
    • recoveries
    • name (the name of the county)

    covid(stateStr, countryStr, aDate, keywordStr)

    A four-argument variant allows you to query results by US state:

    $MyNumber = covid("MA","US",date(2020,1,4),"recoveries"); 

    This returns the number of recoveries reported for the date 4 January 2020, from Massachusetts.

    Data Source

    Data are as reported by the Johns Hopkins Center For Systems Science and Engineering, and are provided by CovidNearMe.org and are provided strictly for educational and academic research purposes. Please note: data are copyright 2020 Johns Hopkins University.

    create([containerStr, ]nameStr)

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

    Operator Has Optional Arguments: 

     Function  [other Function type actions]

     Item  [operators of similar scope]

     Document configuration  [other Document configuration operators]

     String [about String data type]

     v8.0.0

     Baseline

     As at baseline

     [More on optional operator arguments]


    create(name)

    This creates a new note called nameStr at the designated location, and returns the full path to that note. If the designated note already exists, no new note is created and the operator returns the empty string.

    The create() operator always returns the path to the new (or pre-existing) note.

    This function needs no action left-side, i.e. '$SomeAttribute=', to invoke it.

    nameStr is typically actually a complete path:

    create("/hardware/taps"); 

    but if nameStr is a unique note $Name, a new note is created as a new (last) child of the current note, but only if nameStr does not already exist. For example:

    create("taps"); 

    Importantly, if nameStr is only a $Name and not a $Path, the note title nameStr it must be unique to the whole the current document. But, if nameStr is a $Path then it need only be unique within the current container.

    create(containerStr, nameStr)

    A two-argument variant is also offered that allows the container for a new item to be specified, and the new item's $Name. The containerStr argument can be a path, an $ID, or an $IDString. This may be useful if you need to create several notes in the same container, for example is iterating a list with .each(). For example:

    create("/hardware","taps"); 

    Or, more pertinently, using a loop variable 'aPlace':

    	$SomeList.each(aPlace){
    		create(aPlace,"urgentTasks");
    	};

    Essentially, the two-input form allows 3 forms of variation:

    • different path, different name (via two nested loops—one for paths, one for names)
    • different path, same name (loop with path variants)
    • same path, different name (loop with name variants)

    Designators and evaluation

    Paths like that below, which mix literal and computed values are not evaluated, nor are inline designators:

    create(/Resources/Test/$MyString) 

    Instead use code like this:

    	var path="/Resources/Test/"+$MyString;
    	create(path);

    Testing for pre-existing notes

    Although create() will not re-create a note that already exists, a scenario in a big/complex document occurs where it may be necessary to run a number of action once only on newly created notes. How to test for a note already existing? Here is one possible solution:

    	var:string vTestPath = "/foo/bar/baz";
    	var:string vTest = $IDString(vTestPath);
    	if(vTest==""){
    		$Text = create(vTestPath);
    		// do tasks only needed once, for new notes
    	};

    A non-existent note cannot have an $IDString value. So by testing the $IDString(path) for the path of the note to be created before calling create(path), it is possible to ensure create() is only called if needed and in context all the code desired to be run, once, at new note creation.

    createAdornment([containerStr, ] nameStr)

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

    Operator Has Optional Arguments: 

     Function  [other Function type actions]

     Item  [operators of similar scope]

     Document configuration  [other Document configuration operators]

     String [about String data type]

     v9.5.0

     Baseline

     As at baseline

     [More on optional operator arguments]


    createAdornment([containerStr, ] nameStr)

    The operator createAdornment(), creates an adornment at the designated path. If an adornment already exists with that path, no new adornment is created.

    createAdornment(nameStr)

    This creates a new adornment called nameStr at the designated location, and returns the full path to that adornment. If the designated adornment already exists, no new adornment is created and the operator returns the empty string.

    The createAdornment() operator always returns the path to the new (or pre-existing) adornment. Previously, if the adornment already existed, the operator returned false.

    This function needs no action left-side, i.e. '$SomeAttribute=', to invoke it.

    nameStr is typically actually a complete path (if a path is used it is not quote-enclosed):

    createAdornment("/hardware/taps"); 

    but if nameStr is a unique note $Name, a new adornment is created as a child of the current note. For example:

    createAdornment("taps"); 

    createAdornment(containerStr, nameStr)

    A two-argument variant is also offered that allows the container for a new item to be specified, and the new item's $Name. The containerStr argument can be a path, an $ID, or an $IDString. This may be useful if you need to create several adornments in the same container, for example is iterating a list with .each(). For example:

    createAdornment("/hardware","taps"); 

    Or, more pertinently, using a loop variable 'aPlace':

    	$SomeList.each(aPlace){
    		createAdornment(aPlace,"urgentTasks");
    	};

    Essentially, the two-input form allows 3 forms of variation:

    • different path, different name (via two nested loops—one for paths, one for names)
    • different path, same name (loop with path variants)
    • same path, different name (loop with name variants)

    The createAdornment() operator evaluates its first argument, permitting use of an expression to compute a value. Note that this means that paths should be quoted: createAdornment("/Containers/People/Mark") , as otherwise parts of paths may be evaluated as expressions.

    Designators and evaluation

    Paths like that below, which mix literal and computed values are not evaluated, nor are inline designators:

    createAdornment(/Resources/Test/$MyString) 

    Instead use code like this:

    	var path="/Resources/Test/"+$MyString;
    	createAdornment(path);
    createAgent([containerStr, ]nameStr)

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

    Operator Has Optional Arguments: 

     Function  [other Function type actions]

     Item  [operators of similar scope]

     Document configuration  [other Document configuration operators]

     String [about String data type]

     v8.0.0

     Baseline

     As at baseline

     [More on optional operator arguments]


    createAgent(nameStr)

    This creates a new agent called nameStr at the designated location, and returns the full path to that agent. If the designated agent already exists, no new agent is created and the operator returns the empty string.

    The create() operator always returns the path to the new (or pre-existing) agent.

    This function needs no action left-side, i.e. '$SomeAttribute=', to invoke it.

    nameStr is typically actually a complete path:

    createAgent("/agents/urgentTasks"); 

    but if name is a unique agent $Name, a new agent is created as a child of the current note. Be aware though that cannot be used if the current object is an agent rather than a note. For example:

    createAgent("urgentTasks"); 

    create(containerStr, nameStr)

    A two-argument variant is also offered that allows the container for a new item to be specified, and the new item's $Name. The containerStr argument can be a path, an $ID, or an $IDString. This may be useful if you need to create several agents in the same container, for example is iterating a list with .each(). For example:

    createAgent("/agents","urgentTasks"); 

    Or, more pertinently, using a loop variable 'aPlace':

    	$SomeList.each(aPlace){
    		createAgent(aPlace,"urgentTasks");
    	};

    Essentially, the two-input form allows 3 forms of variation:

    • different path, different name (via two nested loops—one for paths, one for names)
    • different path, same name (loop with path variants)
    • same path, different name (loop with name variants)

    Designators and evaluation

    Paths like that below, which mix literal and computed values are not evaluated, nor are inline designators:

    createAgent("Resources/Test/$MyString) 

    Instead use code like this:

    	var:string vPath="/Resources/Test/"+$MyString;
    	createAgent(vPath);
    createAlias(containerStr, originalNote)

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

     Function  [other Function type actions]

     Item  [operators of similar scope]

     Document configuration  [other Document configuration operators]

     String [about String data type]

     v11.5.0

     11.5.0

     As at baseline


    createAlias(containerStr, nameStr)

    This creates a new alias of nameStr in the designated container at path containerStr. If successful, the operator returns the path of the newly created alias. If a unique, nameStr can be a $Name but will more likely be a $Path value.

    Important. Note that the alias must be created in a container other than the container that holds the original note.

    Example:

    var:string vNewAlias = createAlias(/path/to/Acontainer,"Foo"); 

    The result is that an alias of the note 'Foo' is generated at path /path/to/Acontainer/Foo.

    createAttribute(nameStr[, dataType])

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

    Operator Has Optional Arguments: 

     Function  [other Function type actions]

     Item  [operators of similar scope]

     Document configuration  [other Document configuration operators]

     n/a - no return

     v9.2.0

     Baseline

     As at baseline

     [More on optional operator arguments]


    createAttribute(nameStr[, dataType])

    The operator createAttribute(name[, type]) can create a new user attributes. If an attribute of the same nameStr already exists, the operator has no effect and returns false. Otherwise, a new user attribute is created. The nameStr argument is case-sensitive and should use the capitalisation as for the desired attribute. Thus nameStr values of Test and test result in different attributes called 'Test' and 'test'.

    Optionally, a dataType argument may be supplied to determine the data type of the new attribute. Recognised values for dataType include: string, number, boolean, date, color, interval, file, list, set, url, email, and dictionary. If no dataType valued is supplied, Tinderbox creates a String-type attribute. The dataType argument is case-sensitive: number produces a number type attribute, but Number would result in a (default) string type attribute.

    A basic example using just the nameStr argument, results in a new String-type attribute called 'SomeList':

    $MyBoolean = createAttribute("SomeList"); 

    But, in the example above, the chosen name for the new attribute indicates the intended data-type should be of List data type. Therefore, use of the optional dataType argument would make more sense to signal user intent to Tinderbox more clearly:

    $MyBoolean = createAttribute("SomeList", "list"); 

    Again, the action results in a new String-type attribute called 'SomeList'.

    Note that action code cannot alter the new attribute's name or type, nor delete the attribute. This can be done but only via the User attribute inspector.

    Some other aspects of the attribute, e.g. default value) can be changed after the attribute is created, using attribute(). Here below, a number-type attribute is created, its default is set and then a value is applied:

    createAttribute("Tester","number"); 
    attribute("Tester")["default"] = 10; 
    $Tester = 1000; 
    Date.day()

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

     Property  [other Property type actions]

     Item  [operators of similar scope]

     Date-time  [other Date-time operators]

     Number [about Number data type]

     v5.7.0

     Baseline

     As at baseline


    Syntax note: Operators without any defined mandatory arguments may omit their empty closing parentheses


    Date.day()

    Date.day

    Returns the 1 or 2 digit day for the Date-type attribute specified. Valid range 1-31.

    If $MyDate is 25 Oct 1415 16:20 then:

    $MyNumber = $MyDate.day; sets $MyNumber to 25

    The operator may also be used to set the attribute's day, using a valid figure

    $MyDate.day = 20; sets the day of $MyDate to 20th of the month
    Date.format(formatStr)

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

     Function  [other Function type actions]

     Item  [operators of similar scope]

     Formatting  [other Formatting operators]

     String [about String data type]

     v5.8.0

     Baseline

     As at baseline


    Date.format(formatStr)

    Returns Date as a String, formatted as per the quoted date format string formatStr.

    This supplements the existing format() function.

    For example:

    $MyString = $MyDate.format("L") 

    gets the note's creation date and formats it as a "long local date" such as "Sunday, 23 March, 2007" and sets that as the value of $MyString.

    If data is a date, the format string is the same as the format used by Tinderbox's date format codes.

    Date.hour()

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

     Property  [other Property type actions]

     Item  [operators of similar scope]

     Date-time  [other Date-time operators]

     Number [about Number data type]

     v5.7.0

     Baseline

     As at baseline


    Syntax note: Operators without any defined mandatory arguments may omit their empty closing parentheses


    Date.hour()

    Date.hour

    Returns the 1 or 2 digit hour for the Date-type attribute specified. Valid range 0-23.

    If $MyDate is 25 Oct 1415 16:20 then:

    $MyNumber = $MyDate.hour; returns 16

    The operator may also be used to set the attribute's hour, using a valid figure

    $MyDate.hour = 20; sets the hour to 20 (8 PM)

    Setting time

    If wanting to alter the hours element of a Date's time—or multiple time elements in one action, consider using time().

    Date.minute()

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

     Property  [other Property type actions]

     Item  [operators of similar scope]

     Date-time  [other Date-time operators]

     Number [about Number data type]

     v5.7.0

     Baseline

     As at baseline


    Syntax note: Operators without any defined mandatory arguments may omit their empty closing parentheses


    Date.minute()

    Date.minute

    Returns the 1 or 2 digit minute for the Date-type attribute specified. Valid range 0-59.

    If $MyDate is 25 Oct 1415 15:20 then:

    $MyNumber = $MyDate.minute; returns 20

    The operator may also be used to set the attribute's minute, using a valid figure

    $MyDate.minute = 36; sets the minute to 36th of the hour

    Setting time

    If wanting to alter the minutes element of a Date's time—or multiple time elements in one action, consider using time().

    Date.month()

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

     Property  [other Property type actions]

     Item  [operators of similar scope]

     Date-time  [other Date-time operators]

     Number [about Number data type]

     v5.7.0

     Baseline

     As at baseline


    Syntax note: Operators without any defined mandatory arguments may omit their empty closing parentheses


    Date.month()

    Date.month

    Returns the 1 or 2 digit month for the Date-type attribute specified. Valid range 1-12.

    If $MyDate is 25 Oct 1415 15:20 then:

    $MyNumber = $MyDate.month returns 10

    The operator may also be used to set the attribute's month, using a valid figure.

    $MyDate.month = 6; sets the month to 6 (June)
    Date.second()

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

     Property  [other Property type actions]

     Item  [operators of similar scope]

     Date-time  [other Date-time operators]

     Number [about Number data type]

     v6.0.0

     Baseline

     As at baseline


    Syntax note: Operators without any defined mandatory arguments may omit their empty closing parentheses


    Date.second()

    Date.second

    Returns the 1 or 2 digit seconds for the Date-type attribute specified. Valid range 0-59.

    If $MyDate is 25 Oct 1415 15:20:06 then:

    $MyNumber = $MyDate.second returns 6

    The operator may also be used to set the attribute's month, using a valid figure

    $MyDate.second = 24; sets the seconds element of the time to 24.

    Setting time

    If wanting to alter the seconds element of a Date's time—or multiple time elements in one action, consider using time().

    Date.week()

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

     Property  [other Property type actions]

     Item  [operators of similar scope]

     Date-time  [other Date-time operators]

     Number [about Number data type]

     v7.5.0

     Baseline

     As at baseline


    Syntax note: Operators without any defined mandatory arguments may omit their empty closing parentheses


    Date.week()

    Date.week

    The Date operator .week() returns the number of the week in the current year. For example, January 1 is in week 1.

    Be aware that to allow for the fact the calendar year and week start are only aligned every seventh year, in some years days that the very end of the year may report as week #53.

    Date.week() is read-only.

    $MyNumber = $MyDate.week(); 

    Thus is $MyDate is 4 January, $MyNumber would be 1.

    Date.weekday()

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

     Property  [other Property type actions]

     Item  [operators of similar scope]

     Date-time  [other Date-time operators]

     Number [about Number data type]

     v5.7.0

     Baseline

     As at baseline


    Syntax note: Operators without any defined mandatory arguments may omit their empty closing parentheses


    Date.weekday()

    Date.weekday

    Returns the day number for the Date-type attribute specified. Value range is 1-7. Days number from 1 (Monday) to 7 (Sunday). This numbering allows easy testing for weekday (#1-5) vs. weekend (#6-7).

    This operator is read-only and cannot be used to change a Date attributes value.

    $MyNumber = $MyDate.weekday; 

    Thus if the day of $MyDate is Tuesday, $MyNumber would be 2.

    Date.year()

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

     Property  [other Property type actions]

     Item  [operators of similar scope]

     Date-time  [other Date-time operators]

     Number [about Number data type]

     v5.7.0

     Baseline

     As at baseline


    Syntax note: Operators without any defined mandatory arguments may omit their empty closing parentheses


    Date.year()

    Date.year

    Returns the 1 to 4 digit year for the Date-type attribute specified.

    If $MyDate is 25 Oct 1415 16:20 then:

    $MyNumber = $MyDate.year; returns 1415

    The operator may also be used to set the attribute's day, using a valid figure

    $MyDate.year = 1805; sets the year to 1805
    date(dateStr)

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

     Function  [other Function type actions]

     Item  [operators of similar scope]

     Date-time  [other Date-time operators]

     Date [about Date data type]

     v4.0.0

     Baseline

     As at baseline


    date(dateStr)

    This constructs a Date-type object from a quoted string or string action code expression. Note there is an alternate method for specifying a date using the discrete elements (year, month, etc.), see here.

    Originally, this is not necessary and Tinderbox would coerce the bare dateStr to a Date-type automatically. This can still happen but best practice, now action code is more complex, is to be more explicit as to intent by using the date() operator. (See format() and .format() to convert dates into strings).

    Note that in the examples below, whilst the date() operator creates Date-type data, the examples below are actually coercing it back into a string. As formatting is locale dependent and as aTbRef is written using a UK locale (en-GB), the examples below use day-month order. Thus should be correct for most of the world except the USA and the Philippines where moth-day order is used and where readers will need to transpose the month and day segments of the example output. The action code shown is being exported via ^value()^.

    Note that the seconds element of stored Date data is ignored (from v5 onwards). Thus, if present in the Date, seconds are not used and instead are coerced to '00'.

    Default: using $MyDate = date("24/10/2009"); will set $MyDate to a "24 Oct 2009 at 09:49:26" (24 October 2009). If no time is supplied hh:mm:ss are set at current system time when $MyDate is set. In the example here, the equivalent date is set on the fly via ^value()^ so the time is the system time as at exporting the note to HTML. The resulting string is the same as you see for a date displayed as a Displayed Attribute. The exact format will depend on the users international settings—also see Document Settings ▸ Displayed Attributes date format.

    Now, as above but providing an explicit time element, omitting seconds: $MyDate = date("24/10/2009 01:30:22") gives $MyDate a value of "24 Oct 2009 at 01:30:00"; the specified time gets used, with the seconds added in as per the system clock. If providing a full hh:mm:ss string this is honoured.

    But, if you use a date formatting string, you get a formatted string of the date:

    $MyString = date("24/10/2009 01:30:00").format("l"); gives $MyString a value of "24/10/2009"

    or:

    $MyString = date("24/10/2009 01:30:00").format("*"); gives $MyString a value of "Sat, 24 Oct 2009 01:30:00 +0100"

    The two methods are equivalent, note also the change of format due to use of a date format string.

    An attribute can also provide part of the input:

    $EndDate = date($StartDate+"7 days"); 

    With care this can be extended. In the following, $MyString is "7 days" and $MyNumber is 7. The outcome is that $MyDateA/B/C are all set to the same date:

    $MyDateA = date($MyDate+"7 days"); 
    $MyDateB = date($MyDate+$MyString); 
    $MyDateC = date($MyDate+($MyNumber+" days")); note the extra parentheses here are optional but suggested
    date(yearNum, monthNum, dayNum[, hourNum, minNum])

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

    Operator Has Optional Arguments: 

     Function  [other Function type actions]

     Item  [operators of similar scope]

     Date-time  [other Date-time operators]

     Date [about Date data type]

     v4.0.0

     Baseline

     As at baseline

     [More on optional operator arguments]


    date(yearNum, monthNum, dayNum[, hourNum, minNum])

    constructs a Date from individual numeric elements. This is useful, for example, if you need to assemble a date from separate attributes. Note an alternate method for specifying dates using a String representation of the whole date (or date/time), see here.

    year is the 4-digit year

    month is a number from 1–12

    day is a number from 1 to 31

    The time arguments are optional, and are specified in a 24-hour clock.

    hour is a number from 0 to 23

    minute is a number from 0 to 59

    Using this operator, do not quote the whole argument list: these should be left as individual numbers.

    Wrong: $MyDate = date("2004,7,23,16,45"); 

    Right: $MyDate = date(2004,7,23,16,45); 

    Examples:

    $MyDate = date(2004,7,23,16,45); …sets 23 July 2004 16:45 
    day(aDate[, dayNum)

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

     Function  [other Function type actions]

     Item  [operators of similar scope]

     Date-time  [other Date-time operators]

     Date [about Date data type]

     v4.0.0

     Baseline

     As at baseline


    day(aDate)

    returns, as a Number, the day of the month from the aDate action code expression, which may simply be a date-type attribute value.

    $MyNumber = day($MyDate); 

    Alternatively, use Date.day.

    day(theDate, dayNum)

    creates a new Date based on the aDate action code expression, but in which the day of the month is dayNum. theDate is not changed unless theDate is an attribute and the attribute is re-setting itself:

    $MyDateA = day($MyDate,14); $MyDate is unaltered
    $MyDate = day($MyDate,14); $MyDate is changed

    Examples. If $MyDate is July 4, 2009 then

    $MyNumber = day($MyDate); …is 4

    If $MyDate is July 4,2009, then

    $MyDate = day($MyDate,5); 

    will change $MyDate to July 5, 2009.

    days(firstDate, lastDate)

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

     Function  [other Function type actions]

     Item  [operators of similar scope]

     Date-time  [other Date-time operators]

     Number [about Number data type]

     v4.0.0

     Baseline

     As at baseline


    days(firstDate, lastDate)

    returns the Number of 'days' (as defined below) that elapsed between firstDate and lastDate. If lastDate is earlier than firstDate then the result is negative.

    The operator returns the number of 24-hour blocks [sic] between two dates, rounded toward zero. So if days() measures the difference between a date/time of 09:30 today and 08:30 tomorrow, the result is 0 (zero) as the difference is only 23 hours. If the times are same a whole day increment is recorded.

    Thus days does not return a simplistic calendar day difference as some users might intuit it would. If times vary between firstDate and lastDate, the returned difference figure may thus be one day high or low of an expected calendar day-based value.

    If $DateA is 3 January 2016 and $DateB is 9 January 2016, then:

    $MyNumber = days($DateA,$DateB); 

    sets $MyNumber to 6.

    Also see minutes(date1,date2).

    degrees(radiansNum)

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

     Function  [other Function type actions]

     Item  [operators of similar scope]

     Mathematical  [other Mathematical operators]

     Number [about Number data type]

     v6.0.0

     Baseline

     As at baseline


    degrees(radiansNum)

    Takes an angle argument, radiansNum, specified in radians and return the angle in degrees.

    $MyNumber = degrees(6); 

    returns 343.7746771 for an input of 6 radians.

    See also radians() which converts an angle in degrees to radians.

    delete(scope)

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

    Operator Uses Scoped Arguments: 

     Function  [other Function type actions]

     Group  [operators of similar scope]

     Data manipulation  [other Data manipulation operators]

     success boolean

     v8.7.0

     Baseline

     As at baseline

     [More on scoped arguments in Action Code]


    delete(scope)

    Deletes the note(s) designated by scope; defining scope. If a designated note does not exist, the operator has no effect and returns false, i.e. nothing happens: no deletion, no message of no deletion. If the designated note exists, it will be deleted and the operator returns its former path.

    delete("Some note"); 

    However, it is strongly suggesting using a path ($Path) for scope and not just the note's title ($Name), thus:

    delete("/The/path/to/Some note"); 

    Avoid using this operator when possible. It can automatically delete notes you intended to create, and it can potentially saw off the branch you are standing on. In almost all circumstances, it is better to move the unwanted note to a container, and then to delete the note manually if you really need to delete it at all.

    The delete() operator returns true if at least one note was deleted, and false otherwise.

    descendedFrom(item)

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

     Function  [other Function type actions]

     Item  [operators of similar scope]

     Query Boolean  [other Query Boolean operators]

     boolean test

     v4.6.0

     Baseline

     As at baseline


    descendedFrom(item)

    Returns Boolean true if item is an ancestor of the current note, i.e. it matches all descendants of item however deep the outline branch beneath it.

    The item argument must be quoted unless an attribute reference. Ways to define item.

    To return a Set of all items descended from container at path '/foo/bar' use the query:

    descendedFrom(/foo/bar) 

    Or if 'bar' is a unique title in the document, $Name alone can be used:

    descendedFrom("bar") 

    the latter being the form most usually encountered.

    Unlike the paring of contains() and inside(), there is no converse operator that looks for notes that are ancestors of item.

    Legacy issues

    This operator replaces the legacy #descendedFrom query operator.

    Dictionary.add(itemDict)

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

     Function  [other Function type actions]

     Item  [operators of similar scope]

     Dictionary, Set & List operations  [other Dictionary, Set & List operations operators]

     Dictionary [about Dictionary data type]

     v9.1.0

     Baseline

     9.5.0


    Dictionary.add(itemDict)

    This reads a Dictionary-type argument itemDict from which a key and a value are parsed.

    $MyDictionary = $MyDictionary.add({apple:green}); 

    Note that quotes are not needed around the key and value.

    If key does not exist, that key is created with a value of value.

    If key exists, key is given a value of value. This replaces any/all existing values for this key.

    Assume $MyDictionary has no 'apple' key. Example:

    $MyDictionary = $MyDictionary.add({apple:fruit}); 

    The key 'apple' is added and now has value 'fruit'

    $MyDictionary = $MyDictionary.add({apple:green}); 

    The key 'apple' now has a new value 'green'. Now assume the 'apple' key has multiple values of 'fruit;green;red':

    $MyDictionary = $MyDictionary.add({apple:pie}); 

    Now the value is just 'pie' because an .add() operator replaces all existing value(s).

    This operator is also equivalent to:

    Dictionary["key"] = "value"; 

    To add an additional value(s) to existing value(s), see Dictionary.extend().

    To remove a key—and any value(s) it has—from the Dictionary, there is no operator but instead the key string is deleted using a minus operator: see 'Deleting key:value pairs' here.

    The .add() operator accepts quoted strings. The following action code expressions are equivalent:

    $MyDictionary = $MyDictionary.add({1:able}) 
    $MyDictionary = $MyDictionary.add("{1:able}") 

    But do not use either of the following example syntax:

    $MyDictionary = $MyDictionary.add({"1:able"}) WRONG!
    $MyDictionary = $MyDictionary.add({"1":"able"}) WRONG!

    Adding multiple keys using chaining

    The .add() operator can be chained:

    $MyDictionary = $MyDictionary.add("{1:able}").add("{2:bloom}") 

    Deleting a key

    Although the .add() operator can effectively set ket to no value, it cannot remove a key. That requires a different approach as described here.

    Using offset addresses within itemDict

    Either the keyStr or the valueStr may need to be calculated variable, for instance the valueStr might need to be the value of an offset attribute reference, e.g. $MyString("Some note"), or inside a loop e.g. $MyString(loopVar). These expressions cannot be resolved within the .add() operator but itemDict can be a variable. Thus, in a loop, rather than:

    vDict = vDict.add({$Name(aState)+":"+$Color(aState)}); WRONG!

    use:

    	vList.each(aState){
    		var:string vPair = $Name(aState)+":"+$Color(aState);
    		vDict = vDict.add({vPair});
    	};

    DEPRECATED legacy syntax (pre-v9.5.0)


    Dictionary.add(keyStr, valueStr)

    This sets a keyStr to the valueStr.

    If keyStr does not exist, that key is created with a value of valueStr.

    If keyStr exists, keyStr is given value valueStr. This replaces any/all existing values for this key.

    Assume $MyDictionary has no 'apple' keyStr. Example:

    $MyDictionary = $MyDictionary.add("apple","fruit"); 

    The keyStr 'apple' is added and now has valueStr 'fruit'

    $MyDictionary = $MyDictionary.add("apple","green"); 

    The keyStr 'apple' now has a new value 'green'. Now assume the 'apple' key has multiple values of 'fruit;green;red':

    $MyDictionary = $MyDictionary.add("apple","pie"); 

    Now the value is just 'pie' because an .add() operator replaces all existing valueStr(s).

    Dictionary.contains(keyStr)

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

     Function  [other Function type actions]

     Item  [operators of similar scope]

     Query Boolean  [other Query Boolean operators]

     boolean test

     v9.0.0

     Baseline

     As at baseline


    Dictionary.contains(keyStr)

    The code:

    $MyDictionary.contains(key) 

    is true if the dictionary contains the designated key.

    Note that keyStr is literal string and not a regular expression pattern (unlike the operator's use chained with some other data types).

    Dictionaries are case-sensitive, but Dictionary.icontains(key) is available for case-insensitive matching.

    Dictionary.count()

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

     Property  [other Property type actions]

     Item  [operators of similar scope]

     Dictionary, Set & List operations  [other Dictionary, Set & List operations operators]

     Number [about Number data type]

     v9.0.0

     Baseline

     As at baseline


    Syntax note: Operators without any defined mandatory arguments may omit their empty closing parentheses


    Dictionary.count()

    Dictionary.count

    A Number-type property. Returns the number of keys in the dictionary (by their nature all keys are discrete so there is not potential of duplication in the count). If:

    $MyDictionary = {cat:animal; dog:animal; rock: mineral}; 
    $MyNumber = $MyDictionary.count; 

    MyNumber is now 3.

    Dictionary.count and Dictionary.size are interchangeable. Use which ever seems more intuitive.

    Dictionary.empty()

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

     Property  [other Property type actions]

     Item  [operators of similar scope]

     Dictionary, Set & List operations  [other Dictionary, Set & List operations operators]

     boolean test

     v9.0.0

     Baseline

     As at baseline


    Syntax note: Operators without any defined mandatory arguments may omit their empty closing parentheses


    Dictionary.empty()

    Dictionary.empty

    A Boolean-type property. Returns true if the dictionary has no keys, and is false otherwise.

    $MyDictionary = {cat:animal; dog:animal; rock: mineral}; 
    $MyBoolean = $MyDictionary.empty; 

    MyBoolean is now false

    $MyDictionary = ; (or $MyDictionary = {};)
    $MyBoolean = $MyDictionary.empty; 

    MyBoolean is now true

    Dictionary.extend(itemDict)

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

     Function  [other Function type actions]

     Item  [operators of similar scope]

     Dictionary, Set & List operations  [other Dictionary, Set & List operations operators]

     Dictionary [about Dictionary data type]

     v9.1.0

     Baseline

     9.5.0, 9.5.2


    Dictionary.extend(itemDict)

    This reads a Dictionary-type argument itemDict from which a key and a value are parsed. It adds the value string to the value(s) of a key.

    If key does not exist, that key is created with a value of value (also see Dictionary.add()).

    If key exists, value is appended to key's existing value(s).

    Assume $MyDictionary has no 'pear' key. Example:

    $MyDictionary = $MyDictionary.extend({pear:fruit}); 

    The key 'pear' is added and now has value 'fruit'. Next:

    $MyDictionary = $MyDictionary.extend({pear:green}); 

    The key 'pear' now has an additional new value 'green', but the overall value is now a list and the key:value pair is pear:fruit;green.

    To set the new valueStr so it replaces all existing value(s) see Dictionary.add().

    Note that quotes are not used around either/both the keyStr and valueStr. The .extend() operator accepts quoted strings. The following action code expressions are equivalent:

    $MyDictionary = $MyDictionary.extend({1:able}) 
    $MyDictionary = $MyDictionary.extend("{1:able}") 

    But do not use either of the following example syntax:

    $MyDictionary = $MyDictionary.extend({"1:able"}) WRONG!
    $MyDictionary = $MyDictionary.extend({"1":"able"}) WRONG!

    Multiple .extend() calls can be used in a single expression by chaining the calls:

    $MyDictionary = $MyDictionary.extend({"1:able"}).extend({"3":"table"}) 

    Dictionary.extend(keyStr, valueStr)

    This adds the valueStr string to the value(s) of a keyStr.

    If keyStr does not exist, that key is created with a value of valueStr.

    If keyStr exists, valueStr is appended to keyStr's existing value(s).

    Assume $MyDictionary has no 'pear' keyStr. Example:

    $MyDictionary = $MyDictionary.extend("pear","fruit"); 

    The keyStr 'pear' is added and now has valueStr 'fruit'. Next:

    $MyDictionary = $MyDictionary.extend("pear","green"); 

    The keyStr 'pear' now has an additional new valueStr 'green', but the overall value is now a list and the key:value air is pear:fruit;green.

    To set the new valueStr so it replaces all existing value(s) see Dictionary.add().

    Dictionary.extend(dictStr)

    The Dictionary.extend() operator takes a single argument, a dictionary—using the new {} syntax of key:pair elements which will extend the current elements.

    $MyDictionary = $MyDictionary.extend({pear:green}); 

    Note that quotes may be used around either/both the keyStr and valueStr. The following expressions are equivalent:

    $MyDictionary = $MyDictionary.extend({1:able}}; 
    $MyDictionary = $MyDictionary.extend("{1:able}"}; 

    But do not use either of the following example syntax:

    $MyDictionary = $MyDictionary.extend({"1:able"}}; WRONG!
    $MyDictionary = $MyDictionary.extend({"1":"able"}}; WRONG!

    Using offset addresses within itemDict

    Either the keyStr or the valueStr may need to be calculated variable, for instance the valueStr might need to be the value of an offset attribute reference, e.g. $MyString("Some note"), or inside a loop e.g. $MyString(loopVar). These expressions cannot be resolved within the .extend() operator but itemDict can be a variable. Thus, in a loop, rather than:

    vDict = vDict.extend({$Name(aState)+":"+$Color(aState)}); WRONG!

    use:

    	vList.each(aState){
    		var:string vPair = $Name(aState)+":"+$Color(aState);
    		vDict = vDict.extend({vPair});
    	};

    DEPRECATED legacy syntax (pre-v9.5.0)


    Dictionary.extend(keyStr, valueStr)

    This adds the valueStr to the existing value(s) of a keyStr.

    If keyStr does not exist, that key is created with a value of valueStr.

    If keyStr exists, keyStr's value(s) add the value valueStr. This extends existing values for this key.

    Dictionary.icontains(keyStr)

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

     Function  [other Function type actions]

     Item  [operators of similar scope]

     Query Boolean  [other Query Boolean operators]

     boolean test

     v9.0.0

     Baseline

     As at baseline


    Dictionary.icontains(keyStr)

    The code:

    $MyDictionary.icontains(key) 

    is true if the dictionary contains the designated key or case variations of it.

    Note that keyStr is literal string and not a regular expression pattern (unlike the operator's use chained with some other data types).

    Dictionaries are case-sensitive, and Dictionary.contains(key) is available for case-sensitive matching.

    Dictionary.keys()

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

     Property  [other Property type actions]

     Item  [operators of similar scope]

     Dictionary, Set & List operations  [other Dictionary, Set & List operations operators]

     List [about List data type]

     v9.0.0

     Baseline

     As at baseline


    Syntax note: Operators without any defined mandatory arguments may omit their empty closing parentheses


    Dictionary.keys()

    Dictionary.keys

    A List-type property. Returns a list of unsorted key names (i.e. only the keys' strings and not those of values) for this note. Unlike a List or Set, the Dictionary cannot be iterated directly using .each(). Instead, Dictionary.keys provides an iter-able list. So:

    $MyDictionary.keys.each(x){
    	if($MyDictionary[x] == "Whoops"){
    		 ...
    	}
    }

    Therefore do not try: $MyDictionary.each(x)

    A dictionary cannot be sorted but as above Dictionary.keys can be sorted. This is the previous example above, but with an added .sort operator inserted after .keys:

    $MyDictionary.keys.sort.each(x){
    	if($MyDictionary[x] == "Whoops"){
    		 ...
    	}
    }

    Note that when iterating a dictionary with .each(X) the loop variable X is the String value of the key.

    Depending on your needs you might prefer to pass the dictionary explicitly to a list attribute before doing further work:

    $MyList = $MyDictionary.keys; // then work with MyList 
    Dictionary.size()

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

     Property  [other Property type actions]

     Item  [operators of similar scope]

     Dictionary, Set & List operations  [other Dictionary, Set & List operations operators]

     Number [about Number data type]

     v9.0.0

     Baseline

     As at baseline


    Syntax note: Operators without any defined mandatory arguments may omit their empty closing parentheses


    Dictionary.size()

    Dictionary.size

    A Number-type property. Returns the number of keys in the dictionary (by their nature all keys are discrete so there is not potential of duplication in the count). If:

    $MyDictionary = {cat:animal; dog:animal; rock: mineral}; 
    $MyNumber = $MyDictionary.size; 

    MyNumber is now 3.

    Dictionary.size and Dictionary.count are interchangeable. Use which ever seems more intuitive.

    dictionary(dictionaryStr)

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

     Function  [other Function type actions]

     Document  [operators of similar scope]

     Dictionary, Set & List operations  [other Dictionary, Set & List operations operators]

     Dictionary [about Dictionary data type]

     v9.0.0

     Baseline

     As at baseline


    dictionary(dictionaryStr)

    This operator constructs a new dictionary from a dictionaryStr. The dictionaryStr must contain pairs of keys and values separated by a colon; each key/value pair is separated by a semicolon. For example:

    $MyDictionary=dictionary("cat:animal; dog:animal; rock: mineral"); 

    The key "cat" has the value "animal", while the key "rock" has the value "mineral".

    Normally the output will be passed to a Dictionary attribute, but if passed to an action code variable the latter should function as if a dictionary.

    The operator's input string will be in the form of semi-colon delimited set of key:value pairs, i.e.

    $MyDictionary = dictionary("cat:animal; dog:animal; rock:mineral"); 

    Or

    $MyString = "cat:animal; dog:animal; rock:mineral"; 
    $MyDictionary = dictionary($MyString); 

    dictionary({dictionaryStr})

    Using the newer {}-defined declaratory method for dictionary data:

    $MyDictionary = dictionary({cat:animal; dog:animal; rock:mineral}); 

    Or

    $MyString = "cat:animal; dog:animal; rock:mineral"; 
    $MyDictionary = dictionary({$MyString}); 

    Here the braces (curly brackets) replace the need for quotes enclosing strings.

    Direct creation from a string (deprecated)

    It is possible that a dictionary can be made by passing an appropriately structured string to a Dictionary type attribute, thus:

    $MyDictionary = "cat:animal; dog:animal; rock:mineral"; 

    This latter usage is deprecated and the more explicit dictionary() operator should be used in its place.

    Dictionary[keyStr]

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

     Function  [other Function type actions]

     Item  [operators of similar scope]

     Dictionary, Set & List operations  [other Dictionary, Set & List operations operators]

     source context dependent

     v9.0.0

     Baseline

     As at baseline


    Dictionary[keyStr]

    returns the Dictionary's value for the submitted keyStr string. For example, make a dictionary:

    $MyDictionary={cat:animal; dog:animal; rock: mineral}; 

    or (now deprecated):

    $MyDictionary="cat:animal; dog:animal; rock: mineral"; 

    then test like so:

    $MyString = $MyDictionary["dog"]; 

    sets MyString to the string "animal".

    It is not required to use quotes around keyStr.

    The keyStr may also be a (loop) variable, or an attribute value. The latter are evaluated before use:

    $MyList.each(anItem){$MyString = $MyString + ", " + $MyDictionary[anItem];} 
    $MyString = $MyDictionary[$SomeAttribute];} 

    This has the same effect as .at( ), but may be more convenient. Note that in both the square-bracket syntax and .at() syntax a numerical key value is interpreted as a key and not a list item number, unlike list.at().

    distance(startItem, endItem)

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

     Function  [other Function type actions]

     Item  [operators of similar scope]

     Data manipulation  [other Data manipulation operators]

     Number [about Number data type]

     v7.0.0

     Baseline

     As at baseline


    distance(startItem, endItem)

    returns a Number, the map distance (in map units) between the centres of two notes. startItem and endItem are a name, path, attribute value or action code expression returning a unique reference to a single note.

    To find the distance between note 'AA' and note 'BB':

    $MyNumber = distance("AA,"BB"); 
    distanceTo(startItem, endItem)

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

     Function  [other Function type actions]

     Item  [operators of similar scope]

     Data manipulation  [other Data manipulation operators]

     Number [about Number data type]

     v8.0.4

     Baseline

     As at baseline


    distanceTo(startItem, endItem)

    distanceTo computes the approximate distance in kilometres between two notes for which a $Latitude and $Longitude are known. startItem and endItem are a name, path, attribute value or action code expression returning a unique reference to a single note.

    For example, if note startItem 'Boston' has the latitude and longitude of Boston and note endItem 'Paris' has the latitude a longitude of Paris, then for

    $MyNumber = distanceTo("Boston","Paris"); 

    $MyNumber is about 5582 (km).

    Long distances should use a great circle route.

    Note the measurement is approximate and not intended for precise navigation.

    do(macroStr[,argumentsList])

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

    Operator Has Optional Arguments: 

     Function  [other Function type actions]

     Item  [operators of similar scope]

     Data manipulation  [other Data manipulation operators]

     String [about String data type]

     v4.0.0

     Baseline

     As at baseline

     [More on optional operator arguments]


    do(macroStr[, argumentsList])

    The do() operator do lets rules and actions use macros. Action code macros cannot, generally, evaluate action (or export) code within the macro itself and so might best be thought of sections of boilerplate text with configurable text inputs.

    do() always returns an output (string) and so will expect a left side attribute. To do something useful with the output consider wrapping the it in an eval() call. Assume macro "Hello world" has the code: "Hello $1!". Then:

    $ReturnString = eval(do("Hello world","Nibbler")); 

    would set a $ReturnString value of "Hello Nibbler!".

    Alternatively, if the macro is written so the left side is included, action() can be used. Macro "Hello world2" has the code: $ReturnString = "Hello $1!". Using the macro thus:

    action(do("Hello world2","Cubert")); 

    which would set a $ReturnString value of the current note to "Hello Cubert!". Notice how action() requires no left-side receiving attribute as there is no direct output. The assignment to $ReturnString occurs within the macro; the assigned attribute being whatever system/user attribute the user decides, it is not a fixed output assignment.

    An offset within an action call is also possible. Macro "Hello world3":

    $ReturnString('$2') = "Here's $1!"; 

    Use the macro thus:

    action(do("Hello world3","Calculon", "All My Circuits")); 

    which would set a $ReturnString("All My Circuits") to "Here's Calculon!".

    Note that if an argument is itself an action code expression, it may prove beneficial to evaluate it before insertion into the macro. Why? It may affect outcome if the context of the input evaluation and the output evaluation differ, e.g. where the reference 'this' might refer to a different note in each context.

    do(macro[,arg1,arg2,arg3] )

    The first argument is the name of the macro. Subsequent argumentsList (comma delimited) arguments are optional and are passed to the macro, which can refer to them as $1, $2, $3, and so forth.

    After the macro is evaluated, its result string is returned and is parsed again as a rule, action, or action code expression. For example:

    $Name|=do(computeName,$Name,$Name(parent)); 

    sets name to the result of a macro called computeName. This if the macro code were:

    $2: $1 

    Then, if $Name were "mammal" and $Name(parent) were "horse", the result on the above call would be a new $Name of "mammal: horse"

    do(Instructions); 

    simply returns whatever text is stored in a macro called Instructions.

    Macros cannot be used in agent queries (this was supported in early versions).

    Macros called in action code via do() do not evaluate any embedded export codes. This is because such behaviour is reserved for export use.

    document.keys()

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

     Function  [other Function type actions]

     Document  [operators of similar scope]

     Document configuration  [other Document configuration operators]

     List [about List data type]

     v9.5.0

     Baseline

     As at baseline


    Syntax note: Operators without any defined mandatory arguments may omit their empty closing parentheses


    document.keys()

    document.keys

    returns a List of the document() dictionary's keys of useful properties of the current document. The operator returns the document Dictionary object as a single string, noting that no operator trailing parentheses are needed:

    $MyList = document.keys; 

    The returned list is in the dictionary's stored order as listed for document().

    The document.keys operator can assist in getting a readable output of all the keys and their values

    	$Text =;
    	document.keys.each(aKey){
    		var:list vKey = document[aKey];
    		$Text += aKey + ": " + vKey.format(", ") +"\n\n";
    	};

    which will list in $Text of the current note each key name and then its value with a blank line in between. For multi-item values like user-attributes and link-types list formatting applies a ', ' delimiter for legibility.

    document()

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

     Function  [other Function type actions]

     Document  [operators of similar scope]

     Document configuration  [other Document configuration operators]

     Dictionary [about Dictionary data type]

     v9.6.0

     Baseline

     11.0.0


    Syntax note: Operators without any defined mandatory arguments may omit their empty closing parentheses


    document()

    document

    document() or document returns a Dictionary of useful properties of the current document. The properties of the document are exposed this way (in this order in the dictionary):

    • path: the POSIX file path of the current TBX file
    • id: the TBX file's internal UUID.
    • user-attributes: a list of all the user attributes currently defined in the document
    • url: the local file:// URL of the current TBX file.
    • name: the full name of the current TBX including the file extension.
    • link-types: a list of discrete link types currently defined in the document.
    • file-size: the size (in bytes) of the saved Tinderbox file (from v11.0.0)

    Importantly, The document() Dictionary object is read-only.

    The operator returns the document Dictionary object as a single string:

    $Text = document(); 

    Although trailing parentheses are not needed, when calling the 'bare' operator, add parentheses—i.e. document()— may help the user and parse not mistake the operator document for the literal string "document".

    As reading the Dictionary data as a single string can be hard, a neater and more easily understood method is use the document.keys() method.

    It is possible to address the document() Dictionary directly for a specific key value using the document[keyStr] method.

    However, calling document() with no other handling, returns the entire, unformatted Dictionary contents. To split the items onto separate lines as discrete key:value pairs, chain the .format() operator:

    $MyString = document.format("\n"); 

    To get the values (without their keys) on separate lines in the current note's $Text:

    	$Text=;
    	document().keys.each(aKey){
    		$Text+= aKey + ": " + document()[aKey] + "\n";
    	};
    document[keyStr]

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

     Function  [other Function type actions]

     Document  [operators of similar scope]

     Document configuration  [other Document configuration operators]

     source context dependent

     v9.0.0

     Baseline

     11.0.0


    Syntax note: Operators without any defined mandatory arguments may omit their empty closing parentheses


    document[keyStr]

    To address the document() Dictionary to access a particular key use a keyStr argument. The values for the Dictionary's available properties can be accessed individually by supplying the relevant key. Quotes around the key are optional, both forms are illustrated below:

    $MyFile = document["path"]; 
    $MyString = document["id"]; 
    $MyList = document["user-attributes"]; 
    $MyURL = document["url"]; 
    $MyString = document["name"]; 
    $MyList = document[link-types]; 
    $MyNumber = document[file-size]; 

    All property keyStr above return a string value. However, the values are more usable when passed to attributes (or variables) of the precise data types shown in the examples above.

    drivingTimeTo(item)

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

     Function  [other Function type actions]

     Item  [operators of similar scope]

     Data manipulation  [other Data manipulation operators]

     Interval

     v8.0.4

     Baseline

     As at baseline


    drivingTimeTo(item)

    drivingTimeTo estimates the driving time between the location specified by the selected (current) note and the location specified by the item path.

    Location essentially means explicit $Latitude and $Longitude values for both notes—i.e. start and destination, or data such as $GeocodedAddress that can be examined to retrieve suitable Lat/Long data.

    The result is a time interval (interval data type) estimating the approximate driving time, based on traffic conditions prevailing when the action was invoked. For example to find the time to drive from the current location's

    if ($MyInterval==0) {
       $MyInterval = drivingTimeTo(/places/faves/Swarthmore);
    }

    There is no result, i.e. estimated driving time is zero (interval of 00:00) if:

    • a location for either note cannot be determined
    • no route can be found between the two locations (or the locale is not mapped for driving time)
    • the internet is not accessible.

    Avoid excessive use

    Note that this function can be slow and relies on the underlying macOS. Therefore consider using an edict rather than a rule, and avoid recalculating the driving time if you already know it. Code as in the example above should stop unneeded calls. Which such code, if there is a driving time, delete it, and the conditional guard query will allow a fresh call to drivingTimeTo().

    escapeHTML(dataStr)

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

     Function  [other Function type actions]

     Item  [operators of similar scope]

     Formatting  [other Formatting operators]

     String [about String data type]

     v4.0.0

     Baseline

     As at baseline


    escapeHTML(dataStr)

    escapeHTML converts HTML and XML special characters in string dataStr to HTML/XML entities. For example, '<' is replaced by '&lt;' and '&' is replaced by '&amp;'.

    For example, if the source dataStr is "this & that":

    $MyString = escapeHTML("this & that") outputs "this &amp; that".

    See also attributeEncode(), especially if working with XML strings.

    eval([item], expressionStr)

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

    Operator Has Optional Arguments: 

     Function  [other Function type actions]

     Item  [operators of similar scope]

     Data manipulation  [other Data manipulation operators]

     source context dependent

     v4.0.0

     Baseline

     As at baseline

     [More on optional operator arguments]


    eval([item,] expressionStr)

    The item argument must be quoted unless an attribute reference.

    The eval() function takes two quoted evaluated (as string) arguments. The first argument, item, is optional. Ways to define item.

    The second argument, expressionStr, holds string holding an action code expression to be evaluated. Thus, in basic form:

    if($MyBool){$AttribX = "$Name(parent)+' XYZ'";}else{$AttribX = "$Name(grandparent) + 'ABC'";}; $AttribY = eval($AttribX); 

    will set AttribY to the name of the current note's parent's title plus string "XYZ" or that of its grandparent plus string "ABC", depending on the value of attribute MyBool by evaluating attribute AttribX. Thus eval() gives the action code result of an attribute rather than its literal value. As such eval is normally applied to string-based attributes.

    If trying to construct an attribute reference from "$" and a literal string or variable, use action() instead.

    Further examples

    The eval() function can be useful for inserting a local attribute value in an expression that will be evaluated in a different context. Consider this find() in an a rule:

    $ArtistCount = find($ArtistName==$Name & !$IsAlias).size; 

    For each note evaluated, the note's $Name is compared to ArtistName. However, what if the intent was to use this in a note with an artist's name where it is necessary to come the calling note's $Name, not that of the in-scope note. There is no designator for that relationship, but eval() offers a way around:

    $ArtistCount = eval('(find($ArtistName=="'+$Name+'" & !$IsAlias).size)'); 

    This first of all makes a string using the correct find code but also inserting the value of the calling note's $Name, and then the whole is evaluated as if it were the original verbatim find() call above.

    The process can be made clearer by splitting it into two steps by first using a placeholder $TempString attribute:

    $TempString = '(find($ArtistName=="'+$Name+'" & !$IsAlias).size)'; 

    The outer parentheses are simply to ensure the .size() call chained on the end of the find is evaluated with the find(). For a note called "Jacques Brel", $TempString would be the string: (find($ArtistName=="Jacques Brel" & !$IsAlias).size). Now, to use eval():

    $ArtistCount = eval($TempString); 

    Side note: the actual scenario above can also be solved using the 'that' designator, although the example holds true as an exploration of how eval() works.

    A more complex example, using nested eval() calls is described under 'using long sections of code'.

    Macros: eval() can be combined with do(macro). As macros take input arguments, an evaluated macro can work a bit like a code function, taking inputs and returning output that once passed through eval() gives an evaluated result. See the do() operator.

    The eval() operator also allows access to two Tinderbox properties that are not available via action syntax or attribute value. There are the current TBX document's filename (sans extension) and the app version of the currently used Tinderbox on the user's Mac:

    eval(^docTitle^) gives a value of "aTbRef-11" (note no '.tbx' extension)
    eval(^version^) gives "11.8.1" (note that you might want to prefix the return string with 'v' or 'v.' thus: "v.11.8.1").

    In full syntax form, an additional first argument is added that is an expression string evaluating as a note name, path or note name. Where specified, this indicates the note from which attribute values in the second argument should be drawn.

    To create an attribute reference, $-prefixed as in '$Name' not 'Name', use action() instead of eval().

    Example using both inputs

    A different example, using the optional path argument. Take two root-level notes, AA and BB.

    $Text("AA") is: 1+1
    $Text("BB") is: ""(i.e. nothing)
    $Rule("BB") is: $Text=eval("AA",$Text) 

    …after a brief delay, the text of note BB becomes 2, i.e. the sum of the expression stored in aa's text. The item argument "AA" simply indicates that the source of the expressionStr is the note AA.

    Now change AA's text:

    $Text("AA") is: if(1){42}else{1000}

    …after a brief delay, the text of note BB becomes 42. How? Any if(condition) is a Boolean test trying to get a true/false result. If the condition does not result in an actual Boolean value (e.g. testing the value of a Boolean attribute) a Boolean is coerced from the result. Thus an empty string or set or the number zero equate to false, all other values to true. Thus in AA's text above, the condition (1) equates to true so the result is 42.

    Again, replace the $Text of note 'AA' with

    $Text("AA"): $Color=="red"

    This is less obvious. When the expression is evaluated, the result will be true if AA is red, and false otherwise. So, $Text("BB") will be empty unless AA is red; if AA's $Color is red,

    $Text("BB"): true 
    every(scope, condition)

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

    Operator Uses Regular Expressions: 

    Operator Uses Scoped Arguments: 

    Operator Has Conditional Arguments: 


    every(scope, condition)

    This Boolean operator examines notes at scope (defining scope) and determines whether all note(s), i.e. every note, in the defined group evaluate condition as true.

    scope is the notes to be examined and may be any group designator including a find() query. If group evaluates to contain no items, see the edge case described below.

    condition may be any valid query (or action code evaluating as a query), but will usually be a reference to an attribute; short form Boolean attribute expressions are acceptable.

    condition must not be enclosed in quotes.

    For example:

    every(child,$Status=="Important") 
    every(children,$Overdue==true) 
    every(children,$Overdue) (using short from test)
    every(children,$Overdue==false) 
    every(children,!$Overdue) (using short from test)

    Be aware that a counter-intuitive edge case occurs if the scope is empty. Thus, every() is false if condition is false for any designated note. If there are no designated notes at all, i.e. scope is empty, every() is therefore true, whereas the user might have assumed no outcome and thus no true result. If problematic to the user's intent, this condition can be worked around by first ensuring that scope contains something. In the above example, that uses the scope 'children', a modification can be used, like this:

    $ChildCount>0 & every(children,$Overdue==true) 

    See also: any().

    exp(powerNum)

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

     Function  [other Function type actions]

     Item  [operators of similar scope]

     Mathematical  [other Mathematical operators]

     Number [about Number data type]

     v5.10.0

     Baseline

     As at baseline


    exp(powerNum)

    Returns the exponential value of powerNum as e to the power of powerNum.

    $MyNumber = exp(3); 

    returns 20.08553692 for an input of 3.

    expand(scope,methodStr)

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

    Operator Uses Scoped Arguments: 

     Function  [other Function type actions]

     Group  [operators of similar scope]

     Formatting  [other Formatting operators]

     success boolean

     v9.7.0

     Baseline

     As at baseline

     [More on scoped arguments in Action Code]


    expand(scope,methodStr)

    For Map view, this operator alters notes at scope and alters their $Width and/or $Height to fit the $Name string, according to the method given in methodStr. This operator does not require a left-side recipient, although it does return a true/false value if it is desired to check.

    There are three valid choices for methodStr. Given in parentheses below are the equivalent settings from Document Settings ▸ Maps ▸ If note name is too long: see the latter link for an explanation of the resulting change. The options are:

    • horizontally (same as Expand horizontally)
    • vertically (same as Expand vertically)
    • proportionately (same as Expand proportionately)

    This function allows scoped resetting of map view note icon sizes. For example, to reset all child map notes using the proportional option, run this code on the maps' parent container:

    expand(children, proportional); 

    To do similar but for an ad hoc selection on the current map, use a stamp with code:

    expand(this, proportional); 

    recalling that a stamp is run individually on each selected item, so the code only needs a scope of the currently addressed item, i.e. this.

    exportedString(item[, templateStr])

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

    Operator Has Optional Arguments: 

     Function  [other Function type actions]

     Item  [operators of similar scope]

     Formatting  [other Formatting operators]

     String [about String data type]

     v4.0.0

     Baseline

     As at baseline

     [More on optional operator arguments]


    exportedString(item[, templateStr])

    The operator exportedString() applies an export template to a note, returning the result as a String.

    item designates the note to be exported; and is a note name, path or item designator. An attribute may not be used as a placeholder for such information. By default, the note used is the current note, i.e. 'this'. exportedString() also binds 'current' designator to 'this' when resolving item.

    The second argument, templateStr, has three forms.

    • an HTML export template name; this argument is evaluated allowing use of attribute values and action code expressions. Full template paths should not be quotes, but enclose template names ($Name) in double-quotes.
    • the name of an attribute or variable whose value is a string of actual template code (i.e. what would normally be the contents of a template), which is then applied to the referenced note. The attribute reference cannot use a path extension to refer to a different note, $ExportCode is OK but an offset address like $ExportCode(Another note) will fail.
    • a literal string of export code. The most usual use of this is as '^text^', i.e. the export encoded $Text of the note. This form is suggested only for very short code strings. For longer code, place it in a discrete template and use it via the two-argument form.

    In the short, single argument, usage the template to evaluate is not supplied as the target note's inherited or locally assigned template is used. In long-lived projects, it can be useful to use the two-argument form (assuming the template assignment will not change!). Doing this makes it easier to see in code which template will be used rather than have to go and look up that value. Making such a change has no performance input.

    The exportedString() operator is especially useful in conjunction with the runCommand() operator. You can use exportedString() to assemble the input an external program will require, and then pass that input to the external program.

    If you simply wish to transform a string or attribute value (e.g. $Name) into a 'safe' value for use as an HTML/XML element 'id' value, a possible alternative is to use idEncode().

    Examples

    exportedString(item)

    Use of exportedString with just the target item. If using only the (unique) note $Name, it should be quote-enclosed.

    $MyString = exportedString("Some Note"); 

    or using a full $Path for the template, do not use quotes:

    $MyString = exportedString(/Projects/X/Some Note); 

    exportedString(item, templateStr) 

    The first form using templateStr takes a reference to a note and the name of a template note and returns the result of applying the template to the note. If item is a path or title, the value requires quotes:

    $MyString = exportedString(this,"tSome_Template"); 
    $MyString = exportedString("Some note","tSome_Template"); 

    or use the unquoted full $Path for the template:

    $MyString = exportedString(this,/Templates/tSome_Template); 

    The second form using templateStr requires as its second argument is the template string itself which may be a reference to an attribute or action code variable:

    $MyString = exportedString(this,$MyTemplateCode); 
    $MyString = exportedString(this,vTemplate); 

    The third form using templateStr requires as its second argument some literal code:

    $MyString = exportedString("/Path/To/Some note","^text^"); 
    $MyString = exportedString("/Path/To/Some note","^value($Name(parent))^"); 
    fail()

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

     Function  [other Function type actions]

     Item  [operators of similar scope]

     Stream parsing  [other Stream parsing operators]

     success boolean

     v9.1.0

     Baseline

     As at baseline


    Syntax note: Operators without any defined mandatory arguments may omit their empty closing parentheses


    fail()

    fail

    The fail operator makes an explicit declaration of a failure, and if invoked only ever returns false.

    Often, in stream processing a failure occurs implicitly, for example because the end of the processed string is reached without finding the desired data. However, sometimes, there is a definite need to signal failure; for example, because the parsed data are invalid.

    For example:

    	$MyString.try{
    	   $MyString.skipTo(":").captureWord("TheWord");
    	   if($TheWord.contains("None")) {
    	      fail();
    	   }
    	}

    The above skips through $MyString to the first colon and then captures the next discrete word after the colon into $TheWord. The action fails if:

    • if there is no colon
    • if there is no word after the colon
    • if $TheWord contains "None" as a case-sensitive exact full match or substring match.
    fetch(urlStr,headersDict,attrNameStr,cmdStr[,httpMethod,POSTbody])

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

    Operator Has Optional Arguments: 

     Function  [other Function type actions]

     Item  [operators of similar scope]

     Document configuration  [other Document configuration operators]

     String [about String data type]

     v9.6.0

     Baseline

     As at baseline

     [More on optional operator arguments]


    fetch(urlStr,headersDict,attrNameStr,cmdStr[,httpMethod,POSTbody])

    The fetch() operator enables collecting data from a server when greater flexibility than when using AutoFetch. For most purposes, AutoFetch should be the primary choice;> If uncertain use AutoFetch unless it proves not to work; fetch() is an advanced operator for the few who need it.

    urlStr is the URL source to be called into Tinderbox.

    headersDict is a dictionary of HTTP(S) headers. This must be an empty dictionary {} (no enclosing quotes) if you do not need custom headers.

    attrNameStr is the name of (not a reference to) an attribute or local variable in which the output of the fetch process is stored. Note the difference from AutoFetch which places the output directly into $Text. Here, the data from the remote server will be fetched asynchronously, and stored in this attribute or local variable. Note that this argument is not evaluated, i.e. "MyString" not $MyString, unless attribute MyString hold the name of an attribute. This attribute cannot be left empty and must be a literal quoted string, an attribute reference or a variable.

    cmdStr is a Tinderbox action code expression (or semi-colon delimited sequence of actions) to be performed after the data is fetched; i.e. the value is action code. Be aware that the latter may be some time after the fetch operator returns; do not assume full processing happens immediately. It may be an empty string "" if no transform is needed on the recovered data (this in unlikely to be the case).

    httpMethod is an optional argument, indicating the HTTP request method to be used. HTTP 1.1. defined methods (per RFC 9110) are GET, HEAD, POST , PUT (including PATCH), DELETE, CONNECT, OPTIONS, and TRACE. If httpMethod is not specified, fetch() defaults to using a GET request. The methods allowed are as per the HTP protocol in use at the server, rather than a restriction by Tinderbox. Also be aware that support for a given method may also be a constraint at the server end of the request.

    POSTbody is an optional argument. If the httpMethod is POST, POSTbody specifies a message body to be sent to the designated server.

    Note that the server might take several seconds or more before supplying a response. fetch() returns immediately without waiting for the server, and arranges for the command to be evaluated when the data arrive; Tinderbox will continue to try for c.30 seconds before giving up. Why? Because Tinderbox has no control over the time the source at urlStr takes to return the requested data.

    Given this possible delay between calling fetch() and the completion of the full process, it may be necessary to take steps to avoid repeating the fetch() call before the previous operation has completed. For example, this can be done by setting a $MyBoolean(/In Progress) to true immediately before starting the fetch, and setting it to false when all is complete. Note: the choice of an "In Progress" note to hold the boolean is just one approach—where the boolean value is stored and in which attribute are choices for the user to make.

    fetch() processes its command on a serial queue. So, if several fetch() requests are outstanding, they will not interfere: that queue is the sequence in which they will be evaluated.

    The show() operator can be used as part of the cmdStr, as a way of giving feedback.

    Examples

    Suppose there is a need to interact with an API. Typically, that means:

    • Passing a GET or POST message to a designated URL.
      • Possibly doing this using some custom headers for authentication or other reasons.
    • Wait for the server to respond.
    • When the server does respond, take what is returned and process it.

    Note how this is more complex than previous AutoFetch. But, custom headers may be needed or it may be necessary to process the results right away. For example, the result might say: "Here are the first ten results; and here is a magic token to send to get the next ten." Such tokens are typically good for a short time only. AutoFetch was not designed for such complications.

    In the following example, notice the fetch() argument #2 uses the newer {} style of dictionary declaration:

     var string aServerULR = "https://yourserver.com";
    	var string myPayload = "?status=publish";
    	
    	fetch(aServerULR + myPayload,{Content-Type: application/json},"aTempVariable","doProcessCallback(aTempVariable);",POST)
    	
    	function doProcessCallback(returnValue:string) {
       		show(returnValue);
    	};

    Here is a fuller example of a Readwise data importer function as an example. Be aware that the code refers to user fuctions, e.g. 'rwHeaders()' that are not included in the example code:

    
    function getHighlights(auth:string,page:string) {
    	rwSetup();
    	if(rwIsInProgress()) {
    		show("Readwise already in progress");
    		return;
    		}
    
    	show("Readwise starting import");
    	rwMarkInProgress();
    
    	var:string theLog=create("/log");
    	fetch(rwURL(page),rwHeaders(auth),"temp","rwParse(temp,/log,0)");
    
    	}

    Note: everything in the above example with an 'rw' prefix is a function.

    find(query)

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

    Operator Uses Scoped Arguments: 

     Function  [other Function type actions]

     Query  [operators of similar scope]

     Dictionary, Set & List operations  [other Dictionary, Set & List operations operators]

     List [about List data type]

     v5.6.0

     Baseline

     As at baseline

     [More on scoped arguments in Action Code]


    find(query)

    The find() operator returns List-type data of the $Path of all items matching the query argument scope (defining scope). Note that find(), unlike agent queries, does not de-duplicate its matches so any aliases in scope with be matched: to avoid the latter see section 'Filtering out aliases' below.

    To return a list of paths for notes with prototype of 'pRef' and fro which boolean $HasRef is false use:

    find($Prototype=="pRef" & $HasRef==false) 

    Conceptually find() is intended for where no item or group designator exists for use inline in action code (note: such designators were the only scoping terms in early version of Tinderbox). In most cases an agent is the likely and better alternative, noting that agents can also use the results of other agents. find() can also be thought of as a short way of writing:

    $MyList = collect_if(all, anExpression, $Path); 

    where anExpression evaluates as scope.

    The find() operator omits notes for which $Searchable is false.

    Filtering out aliases

    The find() operator does not de-dupe results in the way an agent does. As find() collects $Path data, aliases both inside and outside agents may also match the query. Adding !$IsAlias as a query term will scrub any aliases from matching a search.

    Thus if getting unexpected results via find(), consider whether it is because some de-duping was (incorrectly) assumed and be prepared to sharpen the query terms accordingly.

    In the above example, to additionally filter out possible alias matches add an extra query term:

    find($Prototype=="pRef" & $HasRef==false & $IsAlias==false) 

    See also: querying for aliases.

    first(item[, childrenNum])

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

    Operator Has Optional Arguments: 

    Operator Has Newer Dot-Operator Variant: 

     Function  [other Function type actions]

     Item  [operators of similar scope]

     Query Boolean  [other Query Boolean operators]

     boolean test

     v4.6.0

     Baseline

     As at baseline

     [More on optional operator arguments]

    Yes


    first(item[, childrenNum])

    Returns Boolean true if the current note is among the first itemsNum of children of item. If itemsNum is missing, a value of 1 is assumed. The item argument must be quoted unless an attribute reference. Ways to define item. For list-based work consider list.first().

    Both arguments are evaluated and can be a literal string/number, an attribute value or an action code expression evaluating to that same.

    If the current note has a $SiblingOrder value of 2, then if first() is run on its parent container:

    first("Note A", 5) returns true 

    but if 'it has a $SiblingOrder value of 7:

    first("Note A", 5) returns false

    first() also has a logical opposite in last().

    Legacy issues

    This operator replaces the legacy #first query operator.

    firstWord(dataStr)

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

     Function  [other Function type actions]

     Item  [operators of similar scope]

     Data manipulation  [other Data manipulation operators]

     String [about String data type]

     v4.6.0

     Baseline

     As at baseline


    firstWord(dataStr)

    The firstWord() operator has one argument, dataStr (a quoted string), and it returns the first word of dataStr (as a String). The delimiter used to define words is one or more spaces (possibly also line break(s)?).

    The dataStr argument is evaluated so could be an action code expression. For example, if the note 'First Line' has the body text "Winter is coming.", then

    $MyString = firstWord($Text("First Line")); 

    should give a result of "Winter".

    floor(sourceNum)

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

    Operator Has Newer Dot-Operator Variant: 

     Function  [other Function type actions]

     Item  [operators of similar scope]

     Mathematical  [other Mathematical operators]

     Number [about Number data type]

     v6.0.0

     Baseline

     As at baseline

    Yes


    floor(sourceNum)

    rounds the number value of sourceNum down to next whole integer. See also Number.floor().

    See also ceil() and round().

    If $MyNumber is 3.9 then:

    $MyNumber = ceil($MyNumber); 

    sets $MyNumber to 3. Note unlike normal rounding the value is set downwards to the next integer (i.e. whole number).

    format(dataStr, formatStr[, additionalArguments])

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

    Operator Has Optional Arguments: 

    Operator Has Newer Dot-Operator Variant: 

     Function  [other Function type actions]

     Item  [operators of similar scope]

     Formatting  [other Formatting operators]

     String [about String data type]

     v4.0.0

     Baseline

     As at baseline

     [More on optional operator arguments]

    Yes


    format(dataStr, formatStr[,additionalArguments])

    Note: in most cases it is better to use newer .format() dot-operator for this task.

    The operator format() converts various Tinderbox objects to strings. In quoted (") string arguments a \" is converted into a quotation mark (a.k.a. double quote), \n to a carriage return and \t to a tab.

    The argument dataStr is evaluated, and is usually an attribute reference or action code expression. An attribute reference can take both short and long forms:

    $MySet (i.e. the current note's $MySet)
    $MySet(Test) (i.e. set $MySet data from note 'Test')

    The meaning of formatStr depends on the type of object represented by what. Additionally, number of additionalArguments may be supplied depending on the dataStr data type. Tinderbox data types Date, Set and Number are handled using different sets of arguments as described below.

    This function is being supplemented by per-data-type .format() dot operators which are usually more flexible when writing non-trivial code: links to per-data-type dot operators are added below.

    DATE-Type Data

    If dataStr is a date, the format string is the same as the format used by Tinderbox's date export codes.

    format(dataStr, formatStr)

    For example:

    $MyString = format($Created,"L"); 

    gets the note's creation date and formats it as a "long local date" such as "Sunday, 23 March, 2007".

    Also use Date.format("formatString").

    SET/LIST-Type Data

    If data is a Set or a List, the format string is the delimiter used to separate set elements:

    format(data, formatStr)

    The process preserves original data; duplicate values in lists are maintained. For example

    $MyString = format($DisplayedAttributes,", "); 

    converts Displayed Attributes to a comma+space-separated list. To put each item on a separate line use this:

    $MyString = format($DisplayedAttributes,"\n"); 

    Thus $Text may be created from concatenation of other texts:

    $Text = format(collect(children, $Text),"\n"); 

    To strip duplicates from a List, do not use format(). Instead, simply set a Set attribute to the contents of the List attribute (or any function/action code expression returning List-type data).

    Also use List.format("formatString").

    Optionally, you may supply formatStr as four discrete arguments to format a list, for example as an HTML list:

    format(data,list-prefix,item-prefix,item-suffix,list-suffix)

    For example

    $MyString = format($Classes,"<ul>","<li>","</li>","</ul>"); 

    will return HTML code for a bulleted list with each set member marked up as a list item. Note that the tags must be in double quotes. To have each element on a separate line and indent the items add tabs and line breaks:

    $MyString = format($Classes,"<ul>\n","\t<li>","</li>\n","</ul>\n"); 

    To make this easier to use in a code export context, you might pass the output of format into another attribute and call the latter within the template with a ^value()^ code. By a repeat call to format it is possible to export lists of links.

    Also use List.format("listPrefix","itemPrefix","itemSuffix","listSuffix")

    NUMBER-Type Data

    Use of format() with number data is deprecated in favour of either the Number.precision() or Number.format() operators.

    If dataStr is a number, then the arguments are numeric and interpreted as follows:

    format(dataStr,precisionNum[, widthNum][,padStr])

    The precisionNum argument controls the number of decimal places returned. The optional widthNum argument allows the returned value to be a string left padded with spaces, e.g. to return a string with the same number of characters as submitted.

    For example, if $MyNumber is 3.1415927, then

    $MyString = format($MyNumber,2,7); is "   3.14" (3 spaces + number + period + 3 numbers = 7)
    $MyString = format($MyNumber,2); is 3.14
    $MyString = format($MyNumber,0); is 3
    $MyString = format($MyNumber,0,2); is '  3' (two left-padding spaces) 
    $MyString = format(5.1415927,2); is 5.14

    Note that with widthNum, decimal character is not counted as part of the number.

    If the optional padStr is given, this specifies the character used for padding. The default is a space:

    $MyString = format(7,0,3); gives " 7"
    $MyString = 7.format(7,0,3,"0"); gives "007"
    $MyString = format(7,0,3,"#"); gives "##7"

    An alternate number format is offered using a quoted format string:

    Number.format( formatStr)

    Currently only one such string is supported "L". This will return a string of the number formatted with (OS) locale-dependent group & decimal delimiters. For example, for the US locale these are a comma and a period; in other locales they may vary.

    Also use Number.format(decimalsN,widthN).

    COLOR-Type Data

    If dataStr is color type, format strings are ignored:

    format(colorStr)

    The operator returns the colour colorStr in hex form, e.g. "#ff00ff", regardless of whether the stored value is hex or a named Tinderbox colour.

    $MyString = format($MyColor) 

    is "#ff00ff" if $MyColor is "purple"

    Also use Color.format().

    INTERVAL-Type Data

    If data is interval-type, format strings can use date-type format strings. An interval of 00:00 (hours:minutes) is always displayed as an empty string.

    Also use Interval.format().

    function

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

    Operator Uses Loop Variable Argument: 

     Statement  [other Statement type actions]

     Document  [operators of similar scope]

     Data manipulation  [other Data manipulation operators]

     declaration

     v9.1.0

     Baseline

     As at baseline

     [More on loop variable arguments]


    function

    The function statement defines a user-defined function. Unusually as an operator function is used as a statement which is then followed by the definition of a user-named function fName. Atypically, trailing empty parentheses must not used by function. Thus:

    function fName([argumentsList]){code}

    Once defined a function is called in action code using the user-defined function name (here fName), as described here. Any function may several arguments or none at all. These are defined via a comma-delimited argumentsList. All arguments defined in the list are mandatory, unlike some action code operators which define some arguments as optional. In use, all defined arguments must be supplied, even if only as a default value, e.g. 0 for a number, etc.

    All input arguments (the argumentsList) are available to use in code within the function. Thus by using the argument name as defined in the argumentsList, each argument's supplied value is retrievable anywhere within the function. Just as with a loop variable, the defined argument name is the code used to retrieve that argument's value.

    As functions are more complex than other operators, their complete syntax and use is described in detail in the article on Functions and its sub-articles.

    Function declarations may optionally specify the date type of their input arguments, as passed via argumentsList.

    Private functions

    A private function is a function that can only be called within the note in which it is defined. That note will usually be a library note.

    The point of a private function is it allows for the scenario where two (or more) functions might have the same name as might arise if using library notes created by different people. Thus two (or more) library notes can each define private functions with identical names; each library note will use its own version of the private function. As long as functions are labelled private, they will only be callable from their containing note and not from other (library) notes. Be aware that if a note only contains one function it should not be made private—as nothing outside the note can call it.

    A function is designated private by inserting the word private between the function's argument parentheses and the curly brace starting the function's code:

    function fFunctionName(Args) private { ...code... }

    White space(s) before/after the private is optional.

    hasLocalValue(attributeNameStr[, item])

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

    Operator Has Optional Arguments: 

     Function  [other Function type actions]

     Item  [operators of similar scope]

     Data manipulation  [other Data manipulation operators]

     success boolean

     v7.0.0

     Baseline

     As at baseline

     [More on optional operator arguments]


    hasLocalValue(attributeNameStr[,item])

    For the current note this tests if an attribute name attributeNameStr has a locally set value (returning a Boolean true), or whether that value is inherited from a prototype or document default (false). The main input is a quote-enclosed system or currently defined user attribute (without a $ prefix):

    $MyBoolean = hasLocalValue("Rule") 

    The arguments are evaluated, so

    $MyBoolean = hasLocalValue($MyString) 

    returns information about the attribute whose name is currently saved as the current note's value of $MyString.

    The note evaluated is the current note. The 'item' input allows for offset addressing. For example:

    $MyBoolean = hasLocalValue("Rule","Some Note") 

    checks the local value status of $Rule not for the current note but for the note called "Some Note"

    As the operator returns a boolean, it can be used in a query in agents or find(), like so:

    $MyBoolean = hasLocalValue("Edict") 

    in this case matching any note with a locally-set $Edict value.

    Note: most users will not have need of this but it is useful in very large document to find the odd note with a local setting, when visual review would take too long. It is also useful where (re-)inheritance of attribute values appears broken or is not reset as expected.

    To find all local values for a given note, see its $LocalAttributes.

    hour(aDate, hoursNum)

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

    Operator Has Newer Dot-Operator Variant: 

     Function  [other Function type actions]

     Item  [operators of similar scope]

     Date-time  [other Date-time operators]

     Date [about Date data type]

     v5.7.0

     Baseline

     As at baseline

    Yes


    hour(theDate, hoursNum)

    creates a new Date based on the aDate action code expression, but in which the hour is hoursNumDate is not changed unless theDate is an attribute and the attribute is re-setting itself:

    $MyDateA = hour($MyDate,14); $MyDate is unaltered
    $MyDate = hour($MyDate,14); $MyDate is changed

    Examples. If $MyDate is July 4,2009 09:30, then

    $MyDate=hour($MyDate,19); 

    will change $MyDate to July 4, 2009 19:30.

    The single-argument form that reads the hour value is documented separately: see hour(aDate).

    hour(aDate)

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

    Operator Has Newer Dot-Operator Variant: 

     Function  [other Function type actions]

     Item  [operators of similar scope]

     Date-time  [other Date-time operators]

     Number [about Number data type]

     v5.7.0

     Baseline

     As at baseline

    Yes


    hour(aDate)

    returns the hour element from the aDate date/time action code expression, which may simply be a date-type attribute value.

    Alternatively, use Date.hour.

    The two-argument merthod used to set Dates is documented separately: see hour(aDate, hoursNum).

    hours(startDate, endDate)

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

     Function  [other Function type actions]

     Item  [operators of similar scope]

     Date-time  [other Date-time operators]

     Number [about Number data type]

     v6.0.0

     Baseline

     As at baseline


    hours(startDate, endDate)

    returns the Number of whole hours that elapsed between startDate and endDate. If endDate is earlier than startDate then the result is negative.

    If $DateA has time 12:30 and $DateB has time 15:00, then:

    $MyNumber = hours($DateA,$DateB); 

    sets $MyNumber to 2.

    hsv(hueNum,satNum,brightNum)

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

     Function  [other Function type actions]

     Item  [operators of similar scope]

     Color  [other Color operators]

     String [about String data type]

     v4.0.0

     Baseline

     As at baseline


    Syntax note: Operators without any defined mandatory arguments may omit their empty closing parentheses


    hsv(hueNum,satNum,brightNum)

    Creates a Color-type value, using 3 number arguments for hue (hueNum), saturation (satNum), and brightness—'value'—(brightNum). Hue varies between 0 and 360. Saturation and brightness vary between 0 and 100. The value set is in hex form. For example:

    $MyColor = hsv(120,100,100); sets a value of "#00ff00" or bright green

    Note that Color-type attributes can use dot operators to set or read HSV arguments separately: see Color.hue(), Color.saturation(), Color.brightness().

    Setting named colours

    hsv() and rgb() can be used in the Colors Inspector.

    idEncode(dataStr)

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

     Function  [other Function type actions]

     Item  [operators of similar scope]

     Formatting  [other Formatting operators]

     String [about String data type]

     v4.0.0

     Baseline

     As at baseline


    idEncode(data)

    Returns input argument string data in a form suitable for use an id attribute value in HTML and XML. This addresses the problem of using general text strings such as note names as 'id' attributes in output for marked up languages like HTML and XML.

    idEncode("stringValue")

    idEncode($AttributeName)

    Using idEncode() ensures the result begins with a letter or underscore, and contains only letters, digits, and the underscore character. Multiple underscores are collapsed to a single character. For example:

    idEncode(string) result string
    frogsfrogs 
    frogs dogsfrogs_dogs 
    War And PeaceWar_And_Peace 
    3 blind mice_3_blind_mice 
    Wow!!! LookWow_Look 

    Notice that leading numbers (not legal for 'id' initial characters) are preceded by underscores to maintain legibility vs. the source string.

    Note too (see syntax examples at top) that string literal values are "quoted" whereas attribute names are not, the latter's status being indicated by their $ prefix.

    In code, the last example above can be expressed:

    $MyString = idEncode("Wow!!! Look") 

    which gives a value "Wow_Look".

    if(condition){actionCode}[else{actionStr}]

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

    Operator Uses Regular Expressions: 

    Operator Has Optional Arguments: 

    Operator Has Conditional Arguments: 

     Function  [other Function type actions]

     Conditional Group  [operators of similar scope]

     Data manipulation  [other Data manipulation operators]

     boolean test

     v1.0.0

     Baseline

     As at baseline

     [More on regular expressions in Tinderbox]

     [More on optional operator arguments]

     [More on conditional operator arguments]


    if(condition){actionStr}[else{actionStr}]

    In rules and (agent) actions, Tinderbox uses this conditional action syntax:

    if(condition){ actionStr }
    if (condition){ actionStr }else{ actionStr }

    Where:

    • condition is any action code involving an evaluation to a conditional test that resolves to a Boolean true (if the condition is as expected), i.e. a query encoded in action code. If the query expression is in the form of an $Attribute.[i]contains(regex) query, regular expression back-references can be used in the code of the actionStr. A condition can also be a more complex query, such as find(), where matching zero results is false and otherwise true is returned.)
    • actionStr is a list of one or more action code expressions, separated by semicolons.

    Example:

    if($ChildCount > 5){$Color = "red";$Width = 3.5;}else{$Color = "blue";} 

    A condition can have multiple tests. And (&) or Or (I) joins are allowed as is parenthesis-enclosed nesting of actions:

    if($ChildCount > 5 | $Badge = "ok"){$Color="red";$Width=3.5;} 
    if(($ChildCount > 5 & $Badge = "ok") | $WordCount >= 450){$Color = "red";$Width = 3.5;} 

    If the expression is a complex set of condition clauses it may make sense to calculate the conditions, store the value in an attribute and test that in the if(). This form of re-writing the test is a normal part of incremental formalisation such as may occur as a document gets bigger and more complex.

    Negative tests

    The testing for negatives, the absence of a value (or being in default condition), may be done in several ways. For an attribute value test, the attribute name may simply be prefixed with an exclamation mark, using the short form Boolean test:

    if(!$MyString){…etc. 

    Otherwise the != operator is used:

    if($MyString != "some value"){…etc. 

    Closing statements

    It is not necessary to close the (last) actionStr in an action list, i.e. put a semi-colon before the closing '}'. However, a semi-colon closure is required after the last closing '}' if other action code follows within the same rule or action:

    if($ChildCount > 5){$Color = "red";$Width = 3.5;}else{$Color = "blue";}; $Badge = "ok"; 
    	if(!$MyString){
    		$Color = "red";
    	}else{
    		$Color = "blue";
    	};
    	$WordCount(parent) = $WordCount(parent)+$WordCount;

    Testing multiple conditions

    Whilst a single if() test can use a complex query expression to form its conditional test, it may be necessary to run a set of linked tests. However, there is no 'else if' construct as found in many programming languages. To handle more than two branches to a condition test, nest an additional if() in either action-list of the first test. Thus:

    	if(!$MyString){
    		…
    	}else{
    		if($MyBoolean){
    			…
    		}else{
    			if($MyNumber > 2){
    				…
    			}else{
    				…
    			}
    		}
    	}

    In the example above there are two nested if tests within the original if(). Note how nesting is achieved. It is probably more normal that the additional if goes in the 'else' branch of the preceding condition but that is not a requirement. It can be in either branch according to the needs of the scenario. Indeed, both branches of an if could in theory hold another if().

    However, this form of coding can quickly get complex and care should be taken with placing appropriate '}' closures. In complex branching, consider using additional queries to hold some initial levels of test, rather than do everything in a complex nested call.

    Back-references

    Back-references found by regular expression matches in operators like .contains() are available in if() clauses. For example, the rule:

    if($Name.contains("a(..)") ){$MyString = $1;}

    will set $MyString to "pp" if $Name is "apple", or to "rs" if $Name is "pears". Note that the $0 back-reference contains the full matched expression.

    Within an overall action, any existing back-references generated by at if() persist until another if(0 statement is met. Note:

    • back-references created by an if() statement persist beyond its {}-enclosed code. They last to the end of the action or a new if() statement.
    • an if() statement re-sets all previous back-references even if it does not populate them. Thus if the first if() set a $1 and $2, and a second if sets only $1, $2 is now empty—the previous $2 value does not persist.
    • even a nested if() resets all back-references for all the rest of the action.
    • back-references are not accessible within an ‘else’ branch. An if() nested under the else branch is only evaluated (and thus sets back-references) if the original if() test fails. In other words, if the opening if is true, the code in the else { ... } scope is never evaluated. But if the opening test fails, only the else scope is evaluated.

    Inline use of if() statements

    Assignment to an inline if() action code expression value is permitted. For example:

    $Color = if($MyBoolean){"red"}else{"blue"}; 

    However, when practical, the more conventional and idiomatic style using complete action is preferred:

    if($MyBoolean){$Color="red";}else{$Color="blue";}; 

    Note that both the above are functionally equivalent.

    indented(depthNum[, item])

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

    Operator Has Optional Arguments: 

     Function  [other Function type actions]

     Item  [operators of similar scope]

     Query Boolean  [other Query Boolean operators]

     boolean test

     v4.6.0

     Baseline

     As at baseline

     [More on optional operator arguments]


    indented(depthNum[, item])

    Returns Boolean true if the current note is depthNum levels below the root (i.e. target $OutlineDepth minus one). Where item is supplied, depthNum is instead tested against the number of outline levels between the current note and item (as opposed to root). This is essentially a way to test the $OutlineDepth of a note. Query:

    indented(3) 

    is true for any notes whose $OutlineDepth value is 4.

    The item argument must be quoted unless an attribute reference. Ways to define item.

    Legacy issues

    This operator replaces the legacy #indented query operator.

    inheritsFrom([item, ]prototypeStr)

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

    Operator Has Optional Arguments: 

     Function  [other Function type actions]

     Item  [operators of similar scope]

     Query Boolean  [other Query Boolean operators]

     boolean test

     v6.6.0

     Baseline

     As at baseline

     [More on optional operator arguments]


    inheritsFrom([item, ]prototypeStr)

    inheritsFrom(), is Boolean true if a specific prototypeStr (note) is used by a note, either directly or through other prototypes. For a direct inheritance, the value of $Prototype can be checked but inheritsFrom() allows checking of inheritance via multiple prototypes. Where a note X inherits from a prototype A but the latter itself uses a prototype B, inheritsFrom() allows testing if X inherits indirectly from B. As such inheritance occurs via A, it is otherwise difficult to test such inheritance. This is a specialist operator unlikely to be used except where prototypes themselves use other prototypes.

    In a query, or find(), all notes are tested. In an action context (rule, edict, agent action, OnAdd, action code expression, etc.) only the current note (this) is evaluated. To query the document for notes inheriting from prototype 'pEvent', use the query term:

    inheritsFrom("pEvent") 

    It is possible to test, via an action, the inheritance of a different note using the optional second scoping argument item. Thus to test if 'Note B' inherits from prototype 'pTask':

    inheritsFrom("Note B","pTask") 

    For example, suppose prototype 'pFlower' has the prototype 'pPlant', and note 'Rose' uses the prototype 'pFlower'. Then

    inheritsFrom("pPlant") 

    is true for both pFlower and pPlant.

    inheritsFrom("pFlower") 

    is true for Rose, but false for pPlant.

    N.B. note that the stated prototype is also included in the items testing true. This makes sense if actual notes in the document are prototypes, as opposed to using only deliberate 'non-content' prototypes. To filter the latter, and exclude all prototype notes, use a query like:

    inheritsFrom("pFlower") & $IsPrototype==false 

    You can also write an offset test so note 'Rose' can test if note 'Camelia' uses prototype 'pFlower':

    inheritsFrom("Camelia","pFlower") 

    This returns true if 'Camelia' inherits from that prototype. Or, 'Rose' might want to check if its parent uses that prototype:

    inheritsFrom("parent,"pFlower") 
    inside(item)

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

     Function  [other Function type actions]

     Item  [operators of similar scope]

     Query Boolean  [other Query Boolean operators]

     boolean test

     v4.6.0

     Baseline

     As at baseline


    inside(item)

    Returns Boolean true if the current note is a direct child of item or, put conversely, if item is the parent of the note. Thus it can be thought of as an "is a child of" operator and as such a counterpart to the "is parent of" operator contains(). Note that aliases can be matched by inside(), which may appear counter-intuitive at first encounter: if only wanting to match original notes, see section 'Filtering out aliases' below.

    The item argument must be quoted unless an attribute reference. Ways to define item.

    Pertinent to map view, inside() and adornments:

    • inside(item) is true for a note that is a child of the map's container item.
    • inside(item) is true for a map note that is on top of (within or overlapping) the adornment item.
    • inside(item) for a map container item does not match any child adornments.

    In a more general context inside("X") is true for note A if any of the following are true:

    • original A is inside X
    • an alias of A is inside X
    • A is an alias elsewhere, but its original is inside X

    The last of these, if overlooked, can give unexpected results. The more expansive matching above is necessary to do things like looking inside agents.

    If more than one container matching item is present, inside() returns items matching the first such container as listed in $OutlineOrder. If deliberately wanting to match notes inside any of several same-named containers, e.g. "exploded notes", then use $Name(parent)=="container name" instead.

    Filtering out aliases

    To match only originals, i.e. just the first of the three conditions in the previous list above, use inside("X") & $IsAlias==false.

    Legacy issues

    This operator replaces the legacy #inside query operator.

    Interval.day()

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

     Property  [other Property type actions]

     Item  [operators of similar scope]

     Date-time  [other Date-time operators]

     Number [about Number data type]

     v6.5.0

     Baseline

     As at baseline


    Syntax note: Operators without any defined mandatory arguments may omit their empty closing parentheses


    Interval.day()

    Interval.day

    Returns the Interval expressed as a Number of whole days. Thus, if $MyInterval is 1day 12 hours 30 minutes then:

    $MyNumber = $MyInterval.day; 

    returns 1.

    If the interval is less than 1 day ( i.e. less than 24 hours), the operator returns a zero value.

    This operator is read-only and cannot be used to set/edit an Intervals' day part.

    Intervals can also be tested at hour, minute or second scope.

    Interval.format(formatStr)

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

     Function  [other Function type actions]

     Item  [operators of similar scope]

     Formatting  [other Formatting operators]

     String [about String data type]

     v6.6.0

     Baseline

     As at baseline


    Interval.format(formatStr)

    For this data type formatStr strings can use date-type format strings. The function returns Interval as a String formatted as per the quoted date/interval format string formatStr.

    This supplements the existing format() function.

    When used with Interval-type data, .format() expects the interval to be less than one hour and thus comprising only minutes and seconds data (i.e. 'mm:ss'). Note that the default short Interval form is 'hh:mm' so there is scope for confusion. If passing 'hh:mm' data to .format(), it makes sense to add a blank seconds segment, i.e. 'hh:mm:ss' so the segments of the interval are parsed correctly.

    Furthermore, only two date format strings are accepted for formatStr: Interval.format ("l") and Interval.format ("L"), both of which format the hours and minutes of the Interval date the current locale's style. The lower-case "l" format uses the locale's abbreviated form, while "L" gives the interval in a phrase customised to local usage.

    If $MyInterval is "12:55:23:"

    $MyString = $MyInterval.format("l"); gives "12:55"
    $MyString = $MyInterval.format("L"); gives "12 hours, 55 minutes"

    An Interval value of "00:00" (minutes:seconds)—i.e. that data type's default—always returns an empty string. This if $MyInterval the default 00:00 then:

    $MyString = $MyInterval.format("l"); 

    results in "", i.e. no value is set in $MyString.

    Formatting Intervals of over one hour

    The expectation of input as being only mm:ss only can cause confusion when using .format(). If the value of $MyInterval is "12:55:40" (12 hours, 55 minutes and 14 seconds):

    $MyString = $MyInterval.format("l") 

    The resulting $MyString value is "12:56", i.e. the seconds are rounded (up or down accordingly) and an hours:minutes string is returned.

    As Interval maximum scope is days/hours/minutes/seconds, if the aim is to get the entire interval duration, simply pass the Interval data direct to a string. This if $MyInterval is "1 day 12:55:23":

    $MyString = $MyInterval; 

    sets $MyString to "1 day 12:55:23". If only part of the source is needed, a different approach is needed. Thus, if $MyInterval is "1 day 12:55:23" and only the number of whole minutes is needed, some string manipulation is required:

    $MyString = $MyInterval.extract("(\d{2}):\d{2}$"); 

    setting $MyString to "55". Note that regular expressions are very specific. If the closing '$' is omitted from the regular expression pattern, this results in a $MyString value of "12" instead of "55". Why? Because the latter pattern returns the first pair of digits followed explicitly by a colon and two more digits. Adding the '$' tells the regular expression that the literal sequence must come at the end of the source string, resulting in "55" being extracted.

    Interval.hour()

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

     Property  [other Property type actions]

     Item  [operators of similar scope]

     Date-time  [other Date-time operators]

     Number [about Number data type]

     v6.5.0

     Baseline

     As at baseline


    Syntax note: Operators without any defined mandatory arguments may omit their empty closing parentheses


    Interval.hour()

    Interval.hour

    Returns the Interval expressed as a Number of whole or partial hours within the current day (ignoring whole days). Thus, if $MyInterval is 12 hours 30 minutes then:

    $MyNumber = $MyInterval.hour; 

    returns 12.

    This operator is read-only and cannot be used to set/edit an Intervals' hour part.

    Intervals can also be tested at day, minute or second scope.

    Interval.minute()

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

     Property  [other Property type actions]

     Item  [operators of similar scope]

     Date-time  [other Date-time operators]

     Number [about Number data type]

     v6.5.0

     Baseline

     As at baseline


    Syntax note: Operators without any defined mandatory arguments may omit their empty closing parentheses


    Interval.minute()

    Interval.minute

    Returns the Interval expressed as a Number of whole or partial minutes within the current hour (ignoring whole hours). Thus, if $MyInterval is 1 hour, 30 minutes and 15 seconds then:

    $MyNumber = $MyInterval.minute; 

    returns 30.

    This operator is read-only and cannot be used to set/edit an Intervals' minute part.

    Intervals can also be tested at day, hour or second scope.

    Interval.second()

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

     Property  [other Property type actions]

     Item  [operators of similar scope]

     Date-time  [other Date-time operators]

     Number [about Number data type]

     v7.0.0

     Baseline

     As at baseline


    Syntax note: Operators without any defined mandatory arguments may omit their empty closing parentheses


    Interval.second()

    Interval.second

    Returns the Interval expressed as a Number of whole seconds within the current minute (ignoring whole minutes). Thus, if $MyInterval is 1 hour, 30 minutes and 15 seconds then:

    $MyNumber = $MyInterval.second; 

    returns 15

    Although date-time units are stored as milliseconds under the hood, Tinderbox does not return increments smaller than one second.

    This operator is read-only and cannot be used to set/edit an Intervals' seconds part.

    Intervals can also be tested at day, hour or minute scope.

    interval(dataStr)

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

     Function  [other Function type actions]

     Item  [operators of similar scope]

     Date-time  [other Date-time operators]

     Interval

     v9.5.0

     Baseline

     As at baseline


    interval(dataStr)

    The operator interval(dataStr) converts a string to an interval. For example:

    $MyInterval = interval("00:30:00") 

    is an interval of thirty minutes.

    The dataStr can be a literal string, String-type attribute value or a string variable. The string must be in Interval, for which see the 'Alternative syntax' section of the Interval data type.) For instance:

    	var:number vHr = 21;
    	var:number vMin = 14;
    	var:string vInterval = vHr+":"+vMin;
    	$MyInterval = interval(vInterval);

    The two Date-type argument version of interval() is documented separately, see interval(start,end): it continues to return the Interval between two Date-type arguments.

    If any time element is larger than expected, it is parsed to increment the next larger time element. Thus:

    $MyInterval = interval("00:90:00") 

    evaluates as if:

    $MyInterval = interval("01:30:00") 

    This can be helpful, especially if using calculated variables (as above) and where the calculated value may be more than expected if setting values manually.

    interval(startDate, endDate)

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

     Function  [other Function type actions]

     Item  [operators of similar scope]

     Date-time  [other Date-time operators]

     Interval

     v6.3.1

     Baseline

     As at baseline


    interval(startDate, endDate)

    The function interval(startDate,endDate) returns, in Interval data-type form, the time interval between two Date-type dates. For example, to test the interval between a note's initial creation and its most recent modification and to then store it in an Interval-type attribute:

    $MyInterval = interval($Created,$Modified); 

    The interval() function can be used to test the exact equivalence of two Date-type attribute values, using the full Date and time. Thus:

    if(interval($DateA,$DateB)=="00:00"){… 

    The latter gets around the fact that == and != operators match Date-type attributes only at day scope rather than the actual date-time values.

    If needing the duration expressed in whole time units of a particular time element (or hours, etc.), see days(), hours(), minutes() or seconds().

    The single argument method of interval(), used to create Interval-type data is documented separately—see interval(dataStr).

    isbn10(dataStr)

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

     Function  [other Function type actions]

     Item  [operators of similar scope]

     Data manipulation  [other Data manipulation operators]

     String [about String data type]

     v6.0.0

     Baseline

     As at baseline


    isbn10(dataStr)

    takes quoted an ISBN-13 format code as the dataStr input and returns is in ISBN-10 format. Any dashes or other punctuation will be ignored. If the argument is not a valid ISBN code, the function returns an empty string. If such characters as in the source string and quotes are omitted, hyphen may be mis-parsed as minus signs giving a wrong result.

    Consider a book with the ISBN-10 '1472268997' and the ISBN-13 '978-1472268990':

    $MyString = isbn10("978-1472268990") gives the correct '1472268997' but note, without any hyphens.

    be aware that if dataStr is not in quotes, the input is treated as an arithmetical expression:

    $MyString = isbn10("978-1472268990") gives the incorrect value '1472268012'.
    isbn13(dataStr)

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

     Function  [other Function type actions]

     Item  [operators of similar scope]

     Data manipulation  [other Data manipulation operators]

     String [about String data type]

     v6.0.0

     Baseline

     As at baseline


    isbn13(data)

    takes an ISBN-10 format code as the quoted string dataStr and returns it in ISBN-13 format. Any dashes or other punctuation will be ignored. If the argument is not a valid ISBN code, the function returns an empty string. If such characters as in the source string and quotes are omitted, hyphen may be mis-parsed as minus signs giving a wrong result.

    Consider a book with the ISBN-10 '1472268997' and the ISBN-13 '978-1472268990':

    $MyString = isbn13("1472268997") gives the correct '9781472268990' but note, without any hyphens.

    be aware that if dataStr is not in quotes, result is the same.

    isDuplicateName()

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

     Property  [other Property type actions]

     Item  [operators of similar scope]

     Non-query Boolean  [other Non-query Boolean operators]

     boolean test

     v8.0.0

     Baseline

     As at baseline


    Syntax note: Operators without any defined mandatory arguments may omit their empty closing parentheses


    isDuplicateName

    isDuplicateName()

    This is true if another note in the document has the same $Name as the current note. isDuplicateName() ignores all aliases. The parentheses may be omitted. In an action, the current note might be tested:

    $MyBoolean = isDuplicateName(); 

    If the current note has any duplicate-named notes, $MyBoolean is true.

    In an agent, all instances of notes with duplicates are listed. Thus, the query:

    isDuplicateName() 

    lists all instances of any note with duplicates.

    This can be useful if trying to find/resolve notes with duplicate names within a document. If expecting to use action code to work with notes, it helps if a note's title ($Name) is unique.

    JSON.each([pathStr]){actionStr}

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

    Operator Has Optional Arguments: 

     Function  [other Function type actions]

     List  [operators of similar scope]

     Stream parsing  [other Stream parsing operators]

     iterator

     v9.6.0

     Baseline

     As at baseline

     [More on optional operator arguments]


    JSON.each([pathStr]){actionStr}

    JSON.each{actionStr}

    If the top-level element is an array, rebinds the JSON object in turn to each array element. After calling the actionStr block for each element, the JSON object is restored.

    For example, if the value of $MyString is [{"price":1}, {"price":2}], then

    	$MyList=[];
    	$MyString.json.each{$MyList += json["price"]*3;}

    would set $MyList to "3;6".

    JSON.each(pathStr){actionStr}

    In .json.each(){…}, an optional path argument, pathStr, supplies a path to the array to be iterated. For example, if $Text is:

    {  
       "person": { "firstName": "Thomas",  lastName: "Roe"},
       "coordinates" : [-90,41] 
    }

    then $Text.captureJson().json.each(coordinates){…} would iterate through the array of coordinates.

    If String.json.each begins a statement,

    $Text.json.each(coordinates){...} 

    .json.each(){} reuses the current JSON object. This can be much faster than repeatedly re-parsing a complex json package.

    As a result, the older syntax $Text.json[coordinates].each(x){…}, that chained of JSON.json[keyStr] is no longer supported.

    Loading a dictionary of dictionaries from JSON and looking up items

    Let $Text be:

    { "French":{ "child":"enfant"; "cat":"chat"}; "Swedish":{"child":"barn";"cat":"katt"} } 

    Now:

    $Text.json[French][cat] is "chat"

    $Text.json["Swedish"]["cat"] is "katt"

    $Text.json.keys is "French; Swedish"

    $Text.json.keys.each(x){ 
    	$MyList=$MyList+$Text.json[x][cat];
    };

    $MyList is [chat;katt].

    Loading a list of dictionaries from JSON a and looking up items

    Let $Text be:

    [ { "child":"enfant"; "cat":"chat"} , {"child":"barn";"cat":"katt"} ] 

    Now:

    $Text.json[0][cat] is chat

    $Text.json[0]['cat'] is katt

    $Text.json.count is 2

    $Text.json.each(x){
    	$MyList += x[child];
    }

    $MyList is now [enfant;barn].

    JSON.json[itemNum]

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

     Function  [other Function type actions]

     Item  [operators of similar scope]

     Stream parsing  [other Stream parsing operators]

     source context dependent

     v9.5.0

     Baseline

     As at baseline


    JSON.json[itemNum]

    If there is no current JSON object, attempts to parse the string as JSON and fails if unsuccessful. If there is a current JSON object, that object will be reused. See JSON.json[keyStr], for more information as to when String.captureJson() might need to be used before applying this operator.

    If the top-level element is an array, JSON.json[N] returns the itemNum object. Note that [ ] square brackets, not ( ) parentheses must be used to pass N. If the top-level element is an object, see JSON.json[keyStr].

    For example, if the $Text is:

    { [1,4,9,16,25] } 

    Then $Text.json[1] is 4.

    This usage follows the existing list[N] convention.

    JSON.json[keyStr]

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

     Function  [other Function type actions]

     Item  [operators of similar scope]

     Stream parsing  [other Stream parsing operators]

     source context dependent

     v9.6.0

     Baseline

     As at baseline


    JSON.json[keyStr]

    If there is no current JSON object, attempts to parse the string as JSON and fails if unsuccessful. If there is a current JSON object, that object will be reused. keyStr is a quoted key name and [ ] square brackets, not ( ) parentheses must be used to pass keyStr. Be aware of possible operator name confusion as described in the Notes section further below.

    If the top-level element is an object, Stream.json[key] returns a dictionary for that object. If the top-level element is an array, see JSON.json[itemNum].

    For example if $Text is:

    { "title":"Becket", "price": 9.95 } 

    and $Subtitle is set to "title", then:

    $Text.json["title"]; is "Becket".

    $Text.json[title]; is "Becket".

    $Text.json["price"]; is "9.95".

    $Text.json['$Subtitle']; no such field.

    $Text.json[$Subtitle]; is "Becket".

    Though multiple bracketed arguments can be used to address a JSON path, consider use of .jsonValue(pathStr) instead. For example:

    Text:  {
      "person": { "firstName": "Thomas", "lastName": "Roe" }, 
      "coordinates": [-90,41]
    }
    MyString: "person.lastName"

    Then:

    $Text.json['person']['lastName'] gives 'Roe'

    But, easier:

    $Text.json.jsonValue(person.lastName) gives 'Roe'

    $Text.json.jsonValue($MyString) gives 'Roe'

    Again, using the same JSON as above:

    $MyString="coordinates"; 

    Now

    $Text.json['coordinates'][0] gives -90 $Text.json[$MyString][1] gives 41

    Notes

    Be aware:

    • If the source is $Text containing a mix of text and JSON first use .captureJson() to extract only the JSON code: see String.captureJson().
    • Do not confuse this operator .json[] (note trailing square brackets) with the deprecated/legacy operator .json() (note trailing parentheses).
      • The latter was used for export but is now replaced by String.jsonEncode().
      • However, .json() does still work (legacy support) but is not the same as .json[] for reading JSON data as is described in this article.
    JSON.jsonValue()

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

     Function  [other Function type actions]

     Item  [operators of similar scope]

     Stream parsing  [other Stream parsing operators]

     source context dependent

     v9.6.0

     Baseline

     As at baseline


    Syntax note: Operators without any defined mandatory arguments may omit their empty closing parentheses


    JSON.jsonValue()

    JSON.jsonValue

    The .jsonValue() operator returns a json object, from the cursor position to the end of the current code. In an attribute, e.g. $Text, containing only JSON code, the operator returns that whole code segment. If, via stream parsing the input cursor has advanced to the start of a code segment, the complete code segment starting at that point is returned (though other discrete code samples may exist further on the source string—these are ignored)

    For example, if $Text is :

    Some text.
    {
      "person": { "firstName": "Thomas", "lastName": "Roe" }, 
      "coordinates": [-90,41]
    }

    Then:

    $MyString = $Text.skipline.captureJson.jsonValue(); 

    sets $MyString to the JSON code found at the second paragraph of Text. So, the opening text paragraphs (here paragraph #1, Some text in the above example) are ignored and the first encountered section of JSON, here paragraph #1 is returned.

    Important Note: the captured JSON is always, and only, the first discrete section of code in text.

    Thus, if $Text (or other source string) is all JSON code, the use of .captureJson() is moot But, if the $Text (or other source string) contains more than one JSON code section, use stream parsing to detect the desired JSON section and .jsonValue()to capture the desired section of code. For example, if $Text is :

    Some text.
    {
      "person": { "firstName": "Thomas", "lastName": "Roe" }, 
      "coordinates": [-90,41]
    }
    Another paragraph here.
    {
      "person": { "firstName": "Martin", "lastName": "Brown" }, 
      "coordinates": [-80,61]
    }
    Some more text.
    

    In this case the second discrete section of embedded JSON cannot be accessed via .jsonValue().

    JSON.jsonValue(pathStr)

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

     Function  [other Function type actions]

     Item  [operators of similar scope]

     Stream parsing  [other Stream parsing operators]

     source context dependent

     v9.6.0

     Baseline

     As at baseline


    JSON.jsonValue(pathStr)

    The .jsonValue() operator allows a json object to be addressed by its JSON path. By comparison .json[keyStr] must use a key name. For example:

    Text value:  {
      "person": { "firstName": "Thomas", "lastName": "Roe" }, 
      "coordinates": [-90,41]
    }
    MyString value: "person.lastName"

    Then:

    $Text.json['person']['lastName'] gives 'Roe'

    But, easier:

    $Text.json.jsonValue(person.lastName) gives 'Roe'

    Or if $MyString holds "person.lastName", then:

    $Text.json.jsonValue($MyString) gives 'Roe'

    jsonEncode(dataStr)

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

    Operator Has Newer Dot-Operator Variant: 

     Function  [other Function type actions]

     Item  [operators of similar scope]

     Formatting  [other Formatting operators]

     String [about String data type]

     v5.7.0

     Baseline

     As at baseline

    Yes


    jsonEncode(dataStr)

    This operator returns a JSON-encoded UTF-8 version of the dataStr string. The straight double quote, solidus (forward slash) and backslash characters are all escaped by a preceding backslash character. The control characters backspace, form feed, new line, carriage return, horizontal tab are encoded as standard JavaScript escapes (\b, \f, \n, \r\, \t ). Unicode addresses are also escaped: \u2345.

    Note: the single apostrophe (straight quote) is not escaped as this can cause some Ajax functions to fail.

    If dataStr holds the words 'hello world' separated by a Tab not a space character, then:

    jsonEncode("hello world") 

    gives output of 'hello\tworld'.

    For string-type data, see also the '.jsonEncode()' operator.

    last(item[, childrenNum])

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

    Operator Has Optional Arguments: 

    Operator Has Newer Dot-Operator Variant: 

     Function  [other Function type actions]

     Item  [operators of similar scope]

     Query Boolean  [other Query Boolean operators]

     boolean test

     v4.6.0

     Baseline

     As at baseline

     [More on optional operator arguments]

    Yes


    last(item[item[, childrenNum])

    Returns Boolean true if the current note is among the last childrenNum of children of item. If childrenNum is missing, a value of 1 is assumed.For list-based work consider list.last().

    The item argument must be quoted unless an attribute reference. Ways to define item.

    Both arguments are evaluated and can be a literal string/number, an attribute value or an action code expression evaluating to that same.

    If the current note has a $SiblingOrder value of 7, then if first() is run on its parent container with 10 children:

    first("Note A", 5) returns true 

    but if it has a $SiblingOrder value of 2:

    first("Note A", 5) returns false 

    last() also has a logical opposite in first().

    Legacy issues

    This operator replaces the legacy #last query operator.

    lastWord(dataStr)

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

     Function  [other Function type actions]

     Item  [operators of similar scope]

     Data manipulation  [other Data manipulation operators]

     String [about String data type]

     v4.6.0

     Baseline

     As at baseline


    lastword("data")

    The lastWord() operator has one argument, dataStr (a quoted a string), and it returns the final word of the data string. The delimiter used to define words is one or more spaces (possibly also line break(s)?).

    The dataStr argument is evaluated so could be an action code expression. For example, if the note 'First Line' has the body text "Winter is coming.", then

    $MyString = lastWord($Text("First Line")); 

    should give a result of "coming".

    linkedFrom(scope[, linkTypeStr])

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

    Operator Uses Scoped Arguments: 

    Operator Has Optional Arguments: 

     Function  [other Function type actions]

     Item  [operators of similar scope]

     Query Boolean  [other Query Boolean operators]

     boolean test

     v4.6.0

     Baseline

     As at baseline

     [More on scoped arguments in Action Code]

     [More on optional operator arguments]


    linkedFrom(scope[, linkTypeStr])

    A test for inbound links. This boolean test at returns true if the current note has a least one link from any of the note(s) defined by scope; this is optionally filtered to only links of type linkTypeStr. Put another way:

    • "Does an inbound link exist to the current note from any of scope's item(s)?".

    or

    • "Do any of scope's item(s) have an outbound link to the current note?".

    As this is effectively only a query term, (with a Boolean result), if trying to collect data about the linked note(s), use links() instead.

    scope defines a group of items in a number of ways. An additional option to normal group descriptors is a wildcard designator * that matches all notes in the document and replaces the normal "all" group designator.

    For linkTypeStr, links of type 'prototype' are ignored. Used in an agent, 'this' note is the alias in the agent and not its original, making this action unsuitable for testing in an agent action. If using linkTypeStr, you must use the value "*untitled" to match an 'untitled' type link (rather than an empty string, "", or "untitled").

    Thus, to test if any note using the 'Event' prototype has an inbound link of the 'untitled' link type the agent query would be:

    $Prototype=="Event" & linkedFrom("*", "*untitled") 

    The logical opposite of this test is linkedTo().

    This function can match a link from an alias as opposed to an original (if the logical choice).

    Working with aliases

    If testing links using aliases (e.g. those created by an agent query) be aware that, for basic type links only, the original and alias can and may have differing numbers of basic links. Thus if wishing to check, unambiguously, the original's links from the context of one of its aliases, use originalLinkedFrom() instead.

    Legacy issues

    This replaces the legacy #linkedFrom query operator (deprecated since v4.6).

    Counting links (of a type)

    To know how many inbound links there are, use links() and .count() the resulting list.

    linkedTo(scope[, linkTypeStr])

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

    Operator Uses Scoped Arguments: 

    Operator Has Optional Arguments: 

     Function  [other Function type actions]

     Item  [operators of similar scope]

     Query Boolean  [other Query Boolean operators]

     boolean test

     v4.6.0

     Baseline

     As at baseline

     [More on scoped arguments in Action Code]

     [More on optional operator arguments]


    linkedTo(scope[, linkTypeStr])

    A test for outbound links. This boolean test at returns true if the current note has a least one link to any of the note(s) defined by scope; this is optionally filtered to only links of type linkTypeStr. Put another way:

    • "Does an outbound link exist from the current note to any of scope's item(s)?".

    or

    • "Do any of scope's item(s) have an inbound link from the current note?".

    As this is effectively only a query term, (with a Boolean result), if trying to collect data about the linked note(s), use links() instead.

    scope defines a group of items in a number of ways. An additional option to normal group descriptors wildcard designator * that matches all notes in the document and replaces the normal "all" group designator.

    For linkTypeStr, links of type 'prototype' are ignored. Used in an agent, 'this' note is the alias in the agent and not its original, making this action unsuitable for testing in an agent action. If using linkTypeStr, you must use the value "*untitled" to match an 'untitled' type link (rather than an empty string, "", or "untitled").

    Thus, to test if any note using the 'Event' prototype has an outbound link of the 'untitled' link type the agent query would be:

    $Prototype=="Event" & linkedTo("*", "*untitled"); 

    The logical opposite of this test is linkedFrom().

    This function can match a link from an alias as opposed to an original (if the logical choice).

    Working with aliases

    If testing links using aliases (e.g. those created by an agent query) be aware that, for basic type links only, the original and alias can and may have differing numbers of basic links. Thus if wishing to check, unambiguously, the original's links from the context of one of its aliases, use originalLinkedTo() instead.

    Legacy issues

    This replaces the legacy #linkedTo query operator (deprecated since v4.6).

    Counting links (of a type)

    To know how many outbound links there are, use links() and .count() the resulting list.

    linkFrom(scope[, linkTypeStr])

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

    Operator Uses Scoped Arguments: 

    Operator Has Optional Arguments: 

     Function  [other Function type actions]

     Group  [operators of similar scope]

     Linking  [other Linking operators]

     success boolean

     v4.6.0

     Baseline

     As at baseline

     [More on scoped arguments in Action Code]

     [More on optional operator arguments]


    linkFrom("item|group"[,"linkType"])

    This creates an untitled type basic link from scope to the current note (i.e. an inbound link).

    The scope argument must be quoted unless an attribute reference, e.g. "Some note" vs. $MyString. Ways to define scope.

    The scope can be group scoped including use of group designators and operators like find,() collect() and links().

    linkTypeStr (string). Optionally, instead of an 'untitled' link the link can be of linkTypeStr type. An untitled type link can be explicitly specified using the string "*untitled". Unlike unlinking, this argument may only contain a single link type value.

    Both arguments are evaluated. This operator does not require a left-side argument, simply calling effects a result. A new link will not be created if a link of the stated type already exists.

    Examples

    Linking from a note "Some note":

    No link type: linkFrom("Some note") 
    Link type 'agree': linkFrom("Some note","agree"); 

    Linking from the first child (via a designator):

    linkFrom(child); 
    linkFrom(child,"agree"); 

    Relevant similar operators: linkTo, unlinkTo, unlinkFrom.

    Use of this action does not shift note focus; in addition if scope contains operators (brackets, plus, minus, etc.) Tinderbox will first look for a match to the literal item string and only if there is no match will the app try evaluating to operators and testing the resulting string. For example:

    linkFrom("Example 1 (a test)"); 

    will link from the note named 'Example 1 (a test)'. If no note matches this string, Tinderbox will attempt to evaluate the string. Thus for:

    linkFrom("2+2") 

    will link from the note named '2+2' but if no match will look for a note named '4'.

    This function can link from an alias as opposed to an original (if the logical choice) and can accept a group scope.

    Use in agents

    Beware that the action is working on an alias of the current note and note the current note itself. As originals and aliases support discrete basic links this function should not generally be used in an agent. The best way to use the function is by using a prototype and apply a $Rule to it thus running the code in all notes using the prototype.

    An alternative linkFromOriginal() code will ensure any link created is between two original notes regardless of whether an alias is the context of execution of the code.

    linkFromOriginal(scope[, linkTypeStr])

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

    Operator Uses Scoped Arguments: 

    Operator Has Optional Arguments: 

     Function  [other Function type actions]

     Group  [operators of similar scope]

     Linking  [other Linking operators]

     success boolean

     v6.4.0

     Baseline

     As at baseline

     [More on scoped arguments in Action Code]

     [More on optional operator arguments]


    linkFromOriginal(scope[, linkTypeStr])

    This function works exactly as the same as linkFrom(), except for one important difference that the link created is always between two originals even if either/both the evaluated source or destination are an alias.

    For more detail of use, see linkFrom().

    Examples

    Linking from the original note "Some note" (and not an alias of it):

    No link type: linkFromOriginal("Some note") 
    Link type 'agree': linkFromOriginal("Some note","agree"); 

    See also linkToOriginal(), unlinkFromOriginal(), unlinkToOriginal().

    linkPath(pathNameStr[, startStr, endStr])

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

    Operator Has Optional Arguments: 

     Function  [other Function type actions]

     Item  [operators of similar scope]

     Linking  [other Linking operators]

     List [about List data type]

     v9.0.0

     Baseline

     As at baseline

     [More on optional operator arguments]


    linkPath(pathNameStr)

    linkPath(pathNameStr[, startStr, endStr])

    These functions return a list of notes that are on a designated path. The pathNameStr input must be supplied but can use a value "*" designates any path, regardless of path name—i.e. all notes that have at least one inbound or outbound link. This operator in many ways mirrors the visual function of the Hyperbolic view.

    If startStr is provided, that path starts at the designated note and ends on reaching the endStr note or when all links on the path reachable from start are exhausted. If only the pathName is provided, all notes on the path are listed, whether or not they all form one contiguous network.

    For example, to collect all notes on the path "example":

    $MyList = linkPath("example"); 

    Or, to return all notes connected by links of any type:

    $MyList = linkPath("*"); 

    To find notes linked by the link type "Project A", starting at "RFC" :

    $MyList = linkPath("Project A", "RFC"); 

    To find notes linked by the link type "Project A", starting at "RFC" and ending at "Archive":

    $MyList = linkPath("Project A", "RFC", "Archive"); 

    If several possible paths exist from startStr to endStr, Tinderbox will return the shortest path, or at least a path which is not longer than any other path. Bear in mind that in richly interlinked documents, there may be no 'obvious' single path between the specified notes.

    If only endStr is supplied, still include the argument delimiter for the unused startStr:

    $MyList = linkPath("Project A", , "Archive"); 

    The underlying graph may contain cycles (i.e. have looping paths).

    linkTo(scope[, linkTypeStr])

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

    Operator Uses Scoped Arguments: 

    Operator Has Optional Arguments: 

     Function  [other Function type actions]

     Group  [operators of similar scope]

     Linking  [other Linking operators]

     success boolean

     v4.6.0

     Baseline

     As at baseline

     [More on scoped arguments in Action Code]

     [More on optional operator arguments]


    linkTo(scope[, linkTypeStr])

    This creates an untitled type basic link to scope from the current note (i.e. an outbound link).

    The scope argument must be quoted unless an attribute reference, e.g. "Some note" vs. $MyString. Ways to define scope.

    scope can be group scoped including use of group designators and operators like find,() collect() and links().

    linkType (string). Optionally, instead of an 'untitled' link the link can be of linkTypeStr type. An untitled type link can be explicitly specified using the string "*untitled". Unlike unlinking, this argument may only contain a single link type value.

    Both arguments are evaluated. This operator does not require a left-side argument, simply calling effects a result. A new link will not be created if a link of the stated type already exists.

    Examples

    Linking to a note "Some note":

    No link type: linkTo("Some note"); 
    Link type 'agree': linkTo("Some note","agree"); 

    Linking to the first child (via a designator):

    linkTo(child); 
    linkTo(child,"agree"); 

    Relevant similar operators: linkFrom, unlinkTo, unlinkFrom.

    Use of this action does not shift note focus; in addition if scope contains operators (brackets, plus, minus, etc.) Tinderbox will first look for a match to the literal item string and only if there is no match will the app try evaluating to operators and testing the resulting string. For example:

    linkTo("Example 1 (a test)") 

    will link to the note named 'Example 1 (a test)'. If no note matches this string, Tinderbox will attempt to evaluate the string. Thus for:

    linkTo("2+2"); 

    will link to the note named '2+2' but if no match will look for a note named '4'.

    This function can link to an alias as opposed to an original (if the logical choice) and can accept a group scope.

    Use in agents

    Beware that the action is working on an alias of the current note and note the current note itself. As originals and aliases support discrete basic links this function should not generally be used in an agent. The best way to use the function is by using a prototype and apply a $Rule to it thus running the code in all notes using the prototype.

    An alternative linkFromOriginal() code will ensure any link created is between two original notes regardless of whether an alias is the context of execution of the code.

    linkToOriginal(scope[, linkTypeStr])

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

    Operator Uses Scoped Arguments: 

    Operator Has Optional Arguments: 

     Function  [other Function type actions]

     Group  [operators of similar scope]

     Linking  [other Linking operators]

     success boolean

     v6.4.0

     Baseline

     As at baseline

     [More on scoped arguments in Action Code]

     [More on optional operator arguments]


    linkToOriginal(scope[, linkType])

    This function works exactly as the same as linkTo(), except for one important difference that the link created is always between two originals even if either/both the evaluated source or destination are an alias.

    For more detail of use, see linkTo().

    Examples

    Linking to the original note "Some note" (and not an alias of it):

    No link type: linkToOriginal("Some note"); 
    Link type 'agree': linkToOriginal("Some note","agree"); 

    See also linkFromOriginal(), unlinkFromOriginal(), unlinkToOriginal().

    list.any(loopVar, actionStr)

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

    Operator Uses Loop Variable Argument: 

     Function  [other Function type actions]

     List  [operators of similar scope]

     Query Boolean  [other Query Boolean operators]

     boolean test

     v8.1.0

     Baseline

     As at baseline

     [More on loop variable arguments]


    list.any(loopVar, actionStr)

    This is true if any loopVar in the List- or Set-type list matches the evaluated value of actionStr, as action expression.

    $MyBoolean = $MyList.any(x,x>5) 

    is true if any loopVar in $MyList is greater than 5.

    The comparison may also be applied to literal lists:

    "apple; pear; plum".any(x, x=="plum") 

    is true because at least one element has the value "plum".

    If the target list or set is empty, .any() always returns false, and .every() always returns true.

    The loopVar is a user-set case-sensitive string. "x", "anItem", etc., are equally applicable. Similar to a loop variable in .each(x){}, the point of the loopVar value, is to set a reference variable for each list element. This can then be used in the code provided by the actionStr argument. Using a number for loopVar, e.g. '1' or '42' is not recommended. Choose a value that makes sense for your own style of work

    The actionStr is any action code expression that is a test resolving to a Boolean true/false answer.

    For example, to test if any item exactly matches the value stored in the $MyString of 'Some note':

    $MyBoolean = $MyList.any(anItem, anItem == $MyString("Some Note")); 

    Or, any list value that starts with the string 'Large':

    $MyBoolean = $MyList.any(Z, Z.contains("^ large")); 
    list.asString()

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

     Function  [other Function type actions]

     Item  [operators of similar scope]

     Data manipulation  [other Data manipulation operators]

     String [about String data type]

     v9.5.0

     Baseline

     As at baseline


    Syntax note: Operators without any defined mandatory arguments may omit their empty closing parentheses


    list.asString()

    list.asString

    The dot-operator .asString(), converts a List- or Set-type list to a String-type representation. This addresses an issue where much-used operators .contains() and .icontains() behave differently for Strings (where it searches for a regular expression match) compared to Lists and Sets (where it tests for set membership). Occasionally, is desirable to perform a regular expression test on a list or set—for example, to ask if any of the members of $MyList begin with the letter "a":

    $MyBoolean = $MyList.asString().contains(^ a"); 

    Note there are no arguments for this operator so the trailing parentheses optionally may be omitted:

    $MyBoolean = $MyList.asString.contains(^ a"); 

    The role of .asString() is simple:

         $MyList = [winken;blinken;nod];
         $MyString = $MyList.asString();

    The value of MyString is now "winken;blinken;nod", still the literal stored value of my list complete with semicolon delimiters, but—importantly—Tinderbox now treats this is a literal String, despite the semicolons, and not as List or Set type data. That allows the .contains() example above to do a regular expression (String behaviour) match on what is otherwise treated as a 3-item list.

    list.at(itemNum)

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

     Function  [other Function type actions]

     Item  [operators of similar scope]

     Data manipulation  [other Data manipulation operators]

     source context dependent

     v5.7.1

     Baseline

     As at baseline


    list.at(itemNum)

    This returns the value of item itemNum of the List- or Set-type list as a string. List can be either Set or List type attributes (or string literal, regular expressi, or action code expression equivalents thereof). This operator is read-only: list values can be read, but not set.

    Note: for accessing look-up tables, use list.lookup().

    The operator is zero-based, i.e. an itemNum value of 0 returns the first list item, an itemNum of 1 returns value #2, etc. If the value of N exceeds the number of items in the list an empty string (blank value) is returned. A negative number returns an item numbering in reverse, but one-based not zero-based, so '-1' returns the last item on the list, '-2' the last but one item, etc.

    Examples (where $MyList is "ant;bee;cow"):

    $MyString = $MyList.at(0); returns "ant"
    $MyString = "XX;YY;ZZ".at(2); returns "ZZ"
    $MyString = $MyList.at(5); returns "" (nothing) 
    $MyString = $MyList.at(-2); returns "bee"

    See also the more recent list[N] usage.

    To address particular locations in a list, also see list.first(), list.last() and list.randomItem().


    Legacy use (pre-v8)

    list.at("key")

    This usage is deprecated, use list.lookup("key") instead. The remainder of this section is for explanation of legacy code use only.

    The .at() function is also useful for accessing values from look-up tables by providing the relevant key. Consider a look-up list:

    $RegionList="AL:South;AK:NorthWest;default:North"; 

    This allows actions like:

    $Region=$RegionList.at("AL"); 

    or

    $Region=$RegionList.at($State); 
    list.avg()

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

     Function  [other Function type actions]

     List  [operators of similar scope]

     Dictionary, Set & List operations  [other Dictionary, Set & List operations operators]

     Number [about Number data type]

     v9.0.0

     Baseline

     As at baseline


    Syntax note: Operators without any defined mandatory arguments may omit their empty closing parentheses


    list.avg()

    list.avg

    Returns the mean value of a List- or Set-type list of numbers. For example, if MyList is a list of numerical values '3;4;8;3;9;2;12':

    $MyNumber = $MyList.avg; returns 5.85714

    To get only two decimal places:

    $MyNumber = $MyList.avg.format("2"); returns 5.86
    list.collect_if(loopVar, condition, actionStr)

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

    Operator Has Conditional Arguments: 

    Operator Uses Loop Variable Argument: 

     Function  [other Function type actions]

     List  [operators of similar scope]

     Dictionary, Set & List operations  [other Dictionary, Set & List operations operators]

     List [about List data type]

     v9.0.0

     Baseline

     As at baseline

     [More on conditional operator arguments]

     [More on loop variable arguments]


    list.collect_if(loopVar, condition, actionStr)

    The dot-operator .collect_if() collects the members of a List- or Set-type list that satisfy a condition. Each item in the list is bound in turn to loopVar, and then the actionStr is evaluated and applied to it.

    loopVar is essentially the same as the loop variable used by the List.each() operator. In the examples below, for clarity the loopVar value "anItem" is used, but as with any loop variable a shorter less expressive values such a "x" can be used (e.g. by more expert users).

    The condition argument is a conditional action code expression for which each tested item must return true or false.

    The operator applies the actionStr code to only those list items for which condition is true. For such items, the result of using actionStr on list item loopVar is returned as List-type data. Unlike list.collect(), the returned list may well contain fewer items than the source list, unless all source items match condition.

    If $MyList is "1;2;3;4;5", anItem, is 1, then 2, etc. For example:

    $MyListA = $MyList.collect_if(anItem, anItem <3, anItem); returns 1;2 (only 2 of 5 source items match condition)
    $MyListA = $MyList.collect_if(anItem, mod(anItem,2), anItem); returns 1;3;5 (only 3 of 5 source items match condition)
    $MyListA = $MyList.collect_if(anItem, mod(anItem,2), anItem* anItem); returns 1;9;25 (only 3 of 5 source items match condition)
    $MyListA = $MyList.collect_if(anItem, anItem>0, anItem* anItem); returns 1;4;9;16;25 (all 5 source items match condition)

    In the first three examples above note how only some of the original 5 source list items are returned as some input items fail the condition test. In the last example, as all 5 items are greater than zero (the condition) to the actionStr is applied to every one of them and all are returned.

    If $MyList is "Winken;Blinken;Nod", then:

    $MyListA = $MyList.collect_if(anItem, anItem.contains('i'),anItem.lowercase); returns "winken;blinken" (only 2 items are returned)

    In the last example note how only 2 of the original 3 source list items are returned as the item "Nod" does not contain the letter 'i' and so fails the condition test.

    list.collect_if() vs. collect_if()

    Although the two appear similar. This operator works directly on the source list values, whereas collect_if() creates a list of $Path values and returns on an attribute value from each of those paths (where the item at the $Path meets the condition).

    list.collect(loopVar, actionStr)

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

    Operator Uses Loop Variable Argument: 

     Function  [other Function type actions]

     List  [operators of similar scope]

     Dictionary, Set & List operations  [other Dictionary, Set & List operations operators]

     List [about List data type]

     v9.0.0

     Baseline

     As at baseline

     [More on loop variable arguments]


    list.collect(loopVar, actionStr)

    Each item in the List- or Set-type list is bound in turn to loopVar, and then the actionStr is evaluated and applied to it.

    loopVar is essentially the same as the loop variable used by the List.each() operator. In the examples below, for clarity the loopVar value "anItem" is used, but as with any loop variable a shorter less expressive values such a "x" can be used (e.g. by more expert users).

    The operator applies the action code actionStr to each list item in turn. The result of applying actionStr's code to loopVar is returned as List-type data. The operator always returns a list of all the results, i.e. the size of the input and output lists are the same. By comparison, this may not be the case with the similar list.collect_if() operator.

    If $MyList is "1;2;3;4;5", anItem, is 1, then 2, etc. For example:

    $MyListA = $MyList.collect(anItem,anItem+1); returns 2;3;4;5;6
    $MyListA = $MyList.collect(anItem, anItem* anItem); returns 1;4;9;16;25

    If $MyList is "Winken;Blinken;Nod", then:

    $MyListA = $MyList.collect(anItem, anItem.lowercase); returns "winken;blinken;nod"

    list.collect() vs. collect()

    Although the two appear similar. This operator works directly on the source list values, whereas collect() creates a list of $Path values and returns on an attribute value from each of those paths.

    list.contains(matchStr)

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

     Function  [other Function type actions]

     Item  [operators of similar scope]

     Query Boolean  [other Query Boolean operators]

     boolean test

     v5.7.0

     Baseline

     As at baseline


    list.contains(matchStr)

    This operator tests whether the string matchStr matches a whole discrete value string within a the referenced List- or Set-type list value. Unlike when used with a String, e.g. String.contains, there is no regular expression functionality. With lists the function behaves as if the chained list were being iterated and an equality (==) test was being run on each list item.

    Matches are always case-sensitive, unlike list.icontains() where the matches are always case-insensitive.

    Used with a list (List or Set data types), .contains() cannot match to granularity less than a single whole item in the chained list. Importantly, this differs from the operator's use with String data, e.g. String.contains(), where regular expression matching is applied. If regular expression parsing is needed, e.g. to match a partial list value, coerce the list to a string and use to operator on that string—see below.

    A match gives a numerical result which is the 1-based matched list position. That number coerces to the boolean result needed for use in queries: ) to false and 1 or more to true.

    matchStr is one of:

    • an action code expression (which includes just referencing a single attribute name)
    • a quoted literal string (i.e. actual text). Important: do not omit the enclosing quotes. If omitted, Tinderbox will try to evaluate the string as an expression. Doing this may result in the expected result but this is actually a false positive. So, remember to enclose your literals in quotes.

    $MyList.contains(matchStr)

    The contains operator may also be used with both sets and lists, in which case it tests for set membership, i.e. matching to complete individual values rather than part of values. Thus:

    $MyList.contains("Tuesday") 
    $MyList(parent).contains("Tuesday") 

    are both true if $MyList contains "Monday;Tuesday;Friday". A match can use an attribute value as the matchStr. Consider a single-value String-type attribute 'MyDay':

    $MyList.contains($MyDay) 

    is true if the value of $MyDay for a given note is any of "Monday", "Tuesday or "Friday". Thus in an agent or find query, the regular expression varies by the source value in the currently-tested note.

    The chained list may also be a literal list:

    "Saturday;Sunday".contains("Sunday") 
    "Saturday;Sunday".contains($MyDay) 

    If the matchStr is found the function returns a number which is the 1-based matched list position. In the last example above the returned value will be 2, because 'Sunday' is the second item in the list.

    Testing a negative: "does not contain"

    Use a ! prefix to the query argument:

    !$MyList.contains("Tuesday") 

    Use of parentheses around the negated query term, can assist Tinderbox's parsing:

    (!$MyList.contains("Tuesday")) 

    Matching partial list values

    As changing to list suppresses the normal string regular expression parsing, interposing the .asString() operator allows the list to be treated as string so as to behave like a String.contains() test. See the .asString() operator listing for more detail. This is a more elegant replacement for the old workaround of using List.format("#").contains("some match) as may be seen in some older code samples.

    list.containsAnyOf(regexList)

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

    Operator Uses Regular Expressions: 

     Function  [other Function type actions]

     Item  [operators of similar scope]

     Query Boolean  [other Query Boolean operators]

     boolean test

     v8.8.0

     Baseline

     As at baseline

     [More on regular expressions in Tinderbox]


    list.containsAnyOf(regexList)

    The operator .containsAnyOf(regexList) is true if any of the words in a set of words (i.e. a List- or Set-type list) is contained in the chained-to target regexList. As shown below, the list may have only one entry, but regardless of the list size all item(s) are evaluated as regular expressions. The test is case-sensitive (previously it was case-insensitive). For example:

    $MyBoolean = $MyList.containsAnyOf("emulate"); 

    Will be true if the tested note's $Text contains the word "emulate"; unlike with .contains() or .icontains() a partial value may be matched in the target list. If $MyList holds the values 'emulate', 'mimic' and 'simulate', the list is tested as if a literal string, i.e. with the semi-colon delimiters present:

    $MyBoolean = "emulate;mimic;simulate".containsAnyOf("emulate"); 

    A more applied example:

    $MyBoolean = $MyList.containsAnyOf(wordsRelatedTo("emulate")); 

    Will be true if the tested note's $MyList contains the word "emulate".

    regexList implies using a list of values (ideally with no dupes). This can be a literal list of 1 or more values—as in the example above, or an attribute reference holding a list of values, for instance:

    $MyBoolean = $MyList.containsAnyOf($MySet); 

    It is important to note that .containsAnyOf() is always a case-sensitive test. Thus in the first example above, it will match "emulate" but not "Emulate" or any other case variant of the word.

    Although the examples above use whole words the list in regexList is actually processed assuming they are regular expressions (which may of course be literal strings). Thus in the first example above, it will match both "emulate" and "emulated" but not "emulating". The test value "emulate\b", expecting a word break after the final 'e' would this match "emulate" but not "emulated".

    For a case-insensitive version if this operator see list.icontainsAnyOf().

    Note the slightly different behaviour from that when chaining a String.

    list.count_if(loopVar, condition)

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

    Operator Has Conditional Arguments: 

    Operator Uses Loop Variable Argument: 

     Function  [other Function type actions]

     Group  [operators of similar scope]

     Data manipulation  [other Data manipulation operators]

     Number [about Number data type]

     v9.5.0

     Baseline

     As at baseline

     [More on conditional operator arguments]

     [More on loop variable arguments]


    list.count_if(loopVar, condition)

    The dot-operator .count_if() counts the members of a List- or Set-type list that satisfy a condition. Each item in the list is bound in turn to loopVar, and if condition is met, then that item is added to the returned count.

    loopVar is essentially the same as the loop variable used by the List.each() operator. In the examples below, for clarity the loopVar value "anItem" is used, but as with any loop variable a shorter less expressive values such a "x" can be used (e.g. by more expert users).

    The condition argument is a conditional query expression for which each tested item must return true or false.

    For example if $MyList is "1;2;3;4;5", then:

    $MyListA =- $MyList.count_if(anItem, anItem>3) 

    returns 2, being the number of items in $MyList whose value is greater than 3. If $MyList is "1;1;2;2;3;3;4;4;5;5", then:

    $MyListA =- $MyList.count_if(anItem, anItem>3) 

    returns 4, being the number of items in $MyList whose value is greater than 3 and values '4' and '5' each occur twice.

    list.count_if() vs. .count_if()

    Although the two appear similar. This operator works directly on the source list values, whereas count_if() creates a list of $Path values and returns on an attribute value from each of those paths (where the item at the $Path meets the condition).

    list.count()

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

     Property  [other Property type actions]

     List  [operators of similar scope]

     Data manipulation  [other Data manipulation operators]

     Number [about Number data type]

     v7.0.0

     Baseline

     As at baseline


    Syntax note: Operators without any defined mandatory arguments may omit their empty closing parentheses


    list.count()

    list.count

    The property .count counts the Number of discrete items in the specified List- or Set-type list.

    This is better used instead of count(list) or list.size.

    The subject list is evaluated so can use a literal list or $attribute(note). It can also use more complex action code expressions to get data as long as the result is an attribute of the List or Set data type.

    For example if $DisplayedAttributes for the current note is "Color;AccentColor;NameFont" then the code

    $MyNumber = $DisplayedAttributes.count; 

    is effectively

    $MyNumber = ("Color;AccentColor;NameFont").count; 

    and not surprisingly returns 3. Note that the count is not all unique values for the attribute across the whole TBX; scope is restricted to 'this' note or another nominated note. Specimen usage:

    $MyNumber = $DisplayedAttributes.count; 
    $MyNumber = $DisplayedAttributes("some other note").count; 

    To use .count with a list of items that are attributes or action code expressions, use list() to pre-create a list:

    Works: $MyNumber = list(4+2,9+6).count; (output: 2)

    For more complex examples, where list items are action code expressions, it may be necessary to use eval() to wrap each list item expression e.g. list(eval(expressionA),eval(expressionB)).

    Examples

    The following is a trivial example (given you could use $ChildCount instead) but shows how count can be used in a more subtle way:

    $MyNumber = collect(children,$Name).count; 

    The result of collect() is a List, in this case a number of note titles. List.count will return the number of values in the list (including duplicates). To get a de-duped count, chain the .unique function before the .count:

    $MyNumber = collect(children,$Name).unique.count; 

    Similarly, find() returns a List but note that find() does not de-dupe for aliases. Thus test $IsAlias in the query to weed alias results from the returned list:

    $MyNumber = find($Prototype=="pProject"&$IsAlias==false&$ChildCount>1).count; 
    list.countOccurrencesOf(literalStr)

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

     Function  [other Function type actions]

     List  [operators of similar scope]

     Data manipulation  [other Data manipulation operators]

     Number [about Number data type]

     v9.1.0

     Baseline

     As at baseline


    list.countOccurrencesOf(literalStr)

    This function returns the Number of times that the literal string literalStr appears in the source List- or Set-type list. A string of the attribute's raw concatenated list values (i.e. with semicolon delimiters) is tested.

    If $MyList contains "ant;bee;ant;cow;ant", then:

    $MyNumber = $MyList.countOccurrencesOf("ant"); returns 3

    Sets de-duplicate, but partial matches of Sets do not. If $MySet contains "cat;cut;hat;hit;hut;pat;sat", then

    $MyNumber = $MySet.countOccurrencesOf("at"); returns 4

    literalStr is literal and must not be a regular expression. If the latter is needed use list.contains() or list.icontains().

    list.each(loopVar){actionStr}

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

    Operator Uses Loop Variable Argument: 

     Function  [other Function type actions]

     Item  [operators of similar scope]

     Data manipulation  [other Data manipulation operators]

     iterator

     v5.10.0

     Baseline

     As at baseline

     [More on loop variable arguments]


    list.each(loopVar){ actionStr }

    This allows you to operate in turn on each item in a List- or Set-type list. Put another way you 'iterate;' or loop though, every item in the list evaluating any actionStr code inside the { } brackets. The user-defined (i..e. named by the user) loopVar can be used inside the loop to refer to the value of the current list item value being iterated. If the list is a list of path info (or $IDString, $ID, or unique $Name) then in-loop loopVar can be used for offset addressing the note at that path via an attribute offset argument, i.e. $SomeAttribute(loopVar).

    What is a loop variable?

    For example, for a note with a list of values in $MyList:

    $MyList.each(x){$Result=$Result +x+"\n" ;} 

    will replace the current note's value of $Result with a list of every value from $MyList, but each on its own line. The loopVar, here the in-loop variable 'x', is simply the string defined in .each(), and is case-sensitive and a '$' prefix is not required for in-loop references to the loop variable. For most Tinderbox users, a more readable/understandable version of the above is this:

    	$MyList.each(aString){
    		$Result=$Result +aString+"\n" ;
    	}

    What has changed? Firstly, the loop has been broken out onto speaker lines and in-loop code indented. Tinderbox ignores line breaks and white space between operators and values so both the above seems the same to the parser. Secondly, the obfuscatory 'x' loopVar name has been changed to a more descriptive 'aString' based on the presumption that $Result is a String (it cannot be a Number because Number-type data cannot have line breaks within a single value) and, for the calling note, we are compiling a string the list $Result values.

    Thus .each(loopVar) would iterate using references to loopVar, and thus .each(Y) would iterate using references to 'Y', whilst .each(Abracadabra) would iterate using references to 'Abracadabra', and so forth. Consider making the loop variable something clear to both the user and to Tinderbox. In the trivial example above, 'x' seems pretty clear but might be misread by the users—in a mathematical context—as a multiplication symbol; Tinderbox will not be confused as it uses * for multiplication but consider how something like 'LoopVar' might be clearer. By the same token make sure the loop variable name does not clash with existing attribute names or attribute string values of the same name that might be used as part of the data being processed.

    A variable declared using var() may be altered from within the scope of an .each() loop.

    If $Total is a numeric attribute and $MyList is a list of numbers:

    	$TotalNumber=0;
    	$MyList.each(aNumber){
    		$TotalNumber += aNumber*aNumber; // parentheses not required but can be useful if calculation is not simple
    	}

     

    computes the sum of the squares of the values in $MyList and stored it in $TotalNumber. As the list is a list of numbers, the user-chosen loopVar name used is 'aNumber'.

    Note: remember that you, the user, choose the actual name of loopVar in your own code. It can vary per use, as in the examples on this page.

    The loopVar can be a path and this can be used as a variable designator for attribute offset addressing inside the loop:

    	$Text="";
    	collect(children,$Path).each(aPath){ 
    		$Text += "\n"+$Text(aPath);
    	}

    In the above, a list is created on the fly of the current note's children. Then the current note's $Text is appended, for each child, with a line and the child's $Text. As the list is a list of paths, the user-chosen loopVar name used is 'aPath'. Thus for each iteration of the loop aPath's value is being used to provide the offset address in the loop to $Text(loopVar).

    If it is desired to iterate a list a particular number of times, another approach to the above is to use the range '...' operator which can be used to provide a numbered loop variable (see).

    After each iteration of an each(){} loop, accumulated back-references are cleared. Formerly, back-references from each iteration were retained for the lifetime of the loop, making it very difficult to retrieve the desired reference.

    To test for position in a loop, i.e. detecting if processing the first or last items, see list.first() and list.last().

    To get a random item from a list without needing to use a loop, see list.randomItem().

    A worked example of looping is here.

    Examples of using action() within a loop to create attribute references is given here.

    list.empty()

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

     Property  [other Property type actions]

     Item  [operators of similar scope]

     Non-query Boolean  [other Non-query Boolean operators]

     boolean test

     v5.7.0

     Baseline

     As at baseline


    Syntax note: Operators without any defined mandatory arguments may omit their empty closing parentheses


    list.empty()

    list.empty

    This returns a Boolean depending on whether the List- or Set-type list is empty. If empty, the return value is true, if the attribute has content then false is returned.

    $MyList = [hello;world]; $MyBoolean = $MyList.empty; 

    $MyBoolean is set to false as content is found. But

    $MyList = []; $MyBoolean = $MyList.empty; 

    $MyBoolean is set to true as no content is found.

    list.every(loopVar, actionStr)

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

    Operator Uses Loop Variable Argument: 

     Function  [other Function type actions]

     List  [operators of similar scope]

     Query Boolean  [other Query Boolean operators]

     boolean test

     v8.1.0

     Baseline

     As at baseline

     [More on loop variable arguments]


    list.every(loopVar, actionStr)

    This is true if every loopVar in the List- or Set-type list meets the query in actionStr. Thus:

    $MyList.every(x,x>5) 

    is true if every loopVar in $MyList is greater than 5.

    The comparison may also be applied to literal lists:

    "apple; pear; plum".every(x, x>"aardvark") 

    is true because every element follows "aardvark" in alphabetical (lexical sort) order.

    If the target list or set is empty, .any() always returns false, and .every() always returns true.

    The loopVar is a user-set case-sensitive string. "x", "anItem", etc., are equally applicable. Similar to a loop variable in .each(x){}, the point of the loopVar value, is to set a reference variable for each list element. This can then be used in the code provided by the actionStr argument. Using a number for loopVar, e.g. '1' or '42' is not recommended. Choose a value that makes sense for your own style of work

    The actionStr code is a query, i.e. an action code expression that if tested resolves to a Boolean true/false answer (i.e. a query). For example, to test if every item exactly matches the value stored in the $MyString of 'Some note':

    $MyBoolean = $MyList.every(anItem, anItem == $MyString("Some Note")); 

    Or, every list value starts with the string 'Large':

    $MyBoolean = $MyList.every(Z, Z.contains("^ large")); 
    list.extend(aList)

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

     Function  [other Function type actions]

     List  [operators of similar scope]

     Data manipulation  [other Data manipulation operators]

     List [about List data type]

     v9.5.0

     Baseline

     As at baseline


    list.extend(aList)

    for a List- or Set-type list, a nested list item is inserted as a new item at the end of the returned List. If passed back into a List, the order is maintained. If passed to a Set, the order of values may change.

    The += increment operator, if passed a list as an argument, adds the arguments values to the existing list. By comparison, in the same scenario, list.extend() inserts the argument value as a nested list.

    Long Tinderbox precedent holds that list addition adds each element of the two lists. For example

    $MyList = [1] + [2;3] 

    results in the list 1;2;3 and not 1;[2;3]. So, to add a sublist to a list, use the list.extend() operator. Thus:

    $MyList = [1].extend( [2;3]) 

    results in the list [1;[2;3]].

    list.first()

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

     Property  [other Property type actions]

     List  [operators of similar scope]

     Dictionary, Set & List operations  [other Dictionary, Set & List operations operators]

     source context dependent

     v9.0.0

     Baseline

     As at baseline


    Syntax note: Operators without any defined mandatory arguments may omit their empty closing parentheses


    list.first()

    list.first

    Returns the first item of a List- or Set-type list. If MyList is a 5-item list "ant;bee;cow;dog;eel":

    $MyString = $MyList.first; returns "ant"

    This is also the equivalent of $MyList[0] or $MyList.at(0).

    list.first(N)

    Returns a list of the first N items of a list. With the same list as above:

    $MyList2 = $MyList.first(2); returns "ant;bee"

    Testing for loop position

    This operator can be used to test the current loop state, i.e. whether the currently processed item is the first in the list. Here the code in the commented section is run only when the first list item in $MyList is being processed:

    	$MyList.each(anItem){
    		if(anItem==$MyList.first){
    			// some code here ...
    		};
    	};

    Note that '$MyList.first' is not a test in itself. Rather, it supplies the value of the first list item which can be tested against the currently processed item.

    See also list.last.

    list.format(formatStr)

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

     Function  [other Function type actions]

     Item  [operators of similar scope]

     Formatting  [other Formatting operators]

     String [about String data type]

     v5.8.0

     Baseline

     As at baseline


    list.format(formatStr)

    For a List- or Set-type list, returns the list as a String, with formatStr inserted between each discrete list element (so not after the last item. The process preserves original data; duplicate values in lists are maintained. For example:

    $MyString = $DisplayedAttributes.format(", "); 

    converts Displayed Attributes to a comma+space-separated list. To put each item on a separate line use this:

    $MyString = $DisplayedAttributes.format("\n"); 

    Doing the same for HTML export, you might want the rendered text to have each value on a new line so use:

    $MyString = $DisplayedAttributes.format("<br>"); 

    Thus $Text may be created from concatenation of other texts:

    $Text = (collect(children, $Text)).format("\n"); 

    Optionally, you may supply four arguments to format the list or set as an HTML list:

    $MyString = list.format("listPrefix","itemPrefix","itemSuffix","listSuffix"); 

    For example:

    $MyString = $Classes.format("<ul>","<li>","</li>","</ul>"); 

    will return HTML code for a bulleted list with each set member marked up as a list item. Note that the tags must be in double quotes. To have each element on a separate line and indent the items add tabs and line breaks:

    $MyString = $Classes.format("<ul>\n","\t<li>","</li>\n","</ul>\n"); 

    To make this easier to use in a code export context, you might pass the output of format into another attribute and call the latter within the template with a ^value()^ code. By a repeated use of format it is possible to export lists of links.

    Other form of list-to-string join

    In some data export contexts, tit may be necessary to add a join string while generating a string from an iterated list. See adding joins in loops.

    Similar functions

    This supplements the existing format() function.

    list.icontains(matchStr)

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

    Operator Uses Regular Expressions: 

     Function  [other Function type actions]

     Item  [operators of similar scope]

     Query Boolean  [other Query Boolean operators]

     boolean test

     v5.7.1

     Baseline

     As at baseline

     [More on regular expressions in Tinderbox]


    list.icontains(matchStr)

    This operator tests whether the string matchStr matches a whole discrete value string within the referenced List- or Set-type list. Unlike when used with a String, e.g. String.contains, there is no regular expression functionality. With lists the function behaves as if the chained list were being iterated and an equality (==) test was being run on each list item.

    Matches are always case-insensitive, unlike list.contains() where the matches are always case-sensitive.

    Used with a list (List or Set data types), .icontains() cannot match to granularity less than a single whole list item in the chained list. Importantly, this differs from the operator's use with String data, e.g. String.icontains(), where regular expression matching is applied. If regular expression parsing is needed, e.g. to match a partial list value, coerce the list to a string and use to operator on that string—see below.

    A match gives a numerical result which is the 1-based matched list position. That number coerces to the boolean result needed for use in queries: ) to false and 1 or more to true.

    matchStr is one of:

    • an action code expression (which includes just referencing a single attribute name')
    • a quoted literal string (i.e. actual text). Important: do not omit the enclosing quotes. If omitted, Tinderbox will try to evaluate the string as an action code expression. Doing this may result in the expected result but this is actually a false positive. So, remember to enclose your literals in quotes.

    N.B. Unlike with String-type attributes, regular expressions cannot be used.

    $MyList.icontains(matchStr)

    The contains operator may also be used with both sets and lists, in which case it tests for set membership, i.e. matching to complete individual values rather than part of values. Thus:

    $MyList.icontains("Tuesday") 
    $MyList(parent).icontains("Tuesday") 

    are both true if $MyList contains "Monday;Tuesday;Friday". A match can use an attribute value as the regexStr. Consider a single-value String-type attribute 'MyDay':

    $MyList.icontains($MyDay) 

    is true if the value of $MyDay for a given note is any of "Monday", "Tuesday or "Friday". Thus in an agent or find query, the regular expression varies by the source value in the currently-tested note.

    The chained list may also be a literal list:

    "Saturday;Sunday".icontains("Sunday") 
    "Saturday;Sunday".icontains($MyDay) 

    If the matchStr is found the function returns a number which is the 1-based matched list position. In the last example above the returned value will be 2, because 'Sunday' is the second item in the list.

    Testing a negative: "does not contain"

    Use a ! prefix to the query argument:

    !$MyList.icontains("Tuesday") 

    Use of parentheses around the negated query term, can assist Tinderbox's parsing:

    (!$MyList.icontains("Tuesday")) 

    Matching partial list values

    As changing to list suppresses the normal string regular expression parsing, interposing the .asString() operator allows the list to be treated as a string so as to behave like a String.icontains() test. See the .asString() operator listing for more detail. This is a more elegant replacement for the old workaround of using List.format("#").icontains("some match) as may be seen in some older code samples.

    list.icontainsAnyOf(regexList)

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

    Operator Uses Regular Expressions: 

     Function  [other Function type actions]

     Item  [operators of similar scope]

     Query Boolean  [other Query Boolean operators]

     boolean test

     v8.9.0

     Baseline

     As at baseline

     [More on regular expressions in Tinderbox]


    list.icontainsAnyOf(regexList)

    The operator .icontainsAnyOf(regexList) is true if any of the words in a List- or Set-type list of words is contained in the chained-to target regexList. As shown below, the list may have only one entry, but regardless of the list size all item(s) are evaluated as regular expressions. The test is case-insensitive. For example:

    $MyBoolean = $MyList.containsAnyOf("emulate"); 

    Will be true if the tested note's $Text contains the word "emulate"; unlike with .contains() or .icontains() a partial value may be matched in the target list. If $MyList holds the values 'emulate', 'mimic' and 'simulate', the list is tested as if a literal string, i.e. with the semi-colon delimiters present:

    $MyBoolean = "emulate;mimic;simulate".icontainsAnyOf("emulate"); 

    A more applied example:

    $MyBoolean = $MyList.icontainsAnyOf(wordsRelatedTo("emulate")); 

    Will be true if the tested note's $MyList contains the word "emulate".

    regexList implies using a list of values (ideally with no dupes). This can be a literal list of 1 or more values—as in the example above, or an attribute reference holding a list of values, for instance:

    $MyBoolean = $MyList.containsAnyOf($MySet); 

    It is important to note that .containsAnyOf() is always a case-insensitive test. Thus in the first example above, it will match both "emulate" and "Emulate" or any other case variant of the word.

    Although the examples above use whole words the list in regexList is actually processed assuming they are regular expressions (which may of course be literal strings). Thus in the first example above, it will match both "emulate" and "emulated" but not "emulating". The test value "emulate\b", expecting a word break after the final 'e' would this match "emulate" but not "emulated".

    For a case-sensitive version of this, see list.containsAnyOf().

    Note the slightly different behaviour from that when chaining a String.

    list.intersect(aSet)

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

     Function  [other Function type actions]

     List  [operators of similar scope]

     Data manipulation  [other Data manipulation operators]

     Set [about Set data type]

     v5.10.2

     Baseline

     As at baseline


    list.intersect(aSet)

    This calculates the intersection of two List- or Set-type lists, the chained list and the Set in the aSet argument. The .intersect() test is generally intended for use with Set-type data but will work with Lists, though the output result is always Set-type, even if then passed to be stored in a List:

    $MySet = $MySetA.intersect($MySetB); 
    $MySet = $MyList1.intersect($MyList2); 

    The result is a Set of all items in both $MySetA and $MySetB, or in the second example in both $MyList1 and $MyList2. As the result is always a set, any source list items are de-duped in the output.

    Non-intersect

    No special code is needed to find items in one set but not the other:

    $MySetC = $MySetA - $MySetB; gives items only in $MySetA
    $MySetC = $MySetB - $MySetA; gives items only in $MySetB

    Use with Lists

    Subtracting a Set from a List results in only one instance of each Set item being removed. Subtracting a List from a List each instance of a value in the second list is removed so multiple source List entries may be removed.

    List.isort([attributeRef])

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

    Operator Has Optional Arguments: 

     Function  [other Function type actions]

     Item  [operators of similar scope]

     Data manipulation  [other Data manipulation operators]

     List [about List data type]

     v5.0.0

     Baseline

     As at baseline

     [More on optional operator arguments]


    Syntax note: Operators without any defined mandatory arguments may omit their empty closing parentheses


    List.isort([attributeRef])

    List.isort()

    For List-type list data, the basic form

    $MyList = $MyList.isort(); 

    re-sorts the referenced list's values in lexical, case-insensitive order. This means sorting letters in alphabetical order "a,b,c'" with all upper case instances sorting after any lower case ones as in "ant;Ant;bee;Bee;cow;Cow". Lexical sort of numbers means '1,11,2' not 1,2,11' as might be expected.

    Alternative sorts are a lexical case-sensitive List.sort(), and a numeric List.nsort() (the latter giving '1,2,11' not '1,11,2'). Or, if using $Name or $Path data, use the optional long from (below) and let the nominated attribute's data type set the form of sort, e.g. for date sorting, sort on a Date-type attribute.

    The resulting sort order can be reversed overall by chaining the List.isort() and List.reverse() functions:

    $MyList = $MyList.isort().reverse(); 

    List.sort(attributeRef)

    Here the referenced List must be a list of note names or paths, i.e. a list of $Name data or $Path data (but not a mix of the two). If note names are not unique within the document, path values must be used to achieve correct sort. This is because the stipulated

    The attributeRef argument is a $-prefixed attribute reference and indicates the attribute supplying the sorted value in each list item. As a result, this form of sort cannot be used with any other date type of list and cannot be applied to a literal list of values (as they have no attributes!), unlike the short un-argumented form above.

    Thus, the sort order is based on the value of the stipulated attributeRef and that value is derived from the $Name or $Path of the list item being evaluated: $MyList = $collect(children, $Name).isort($StartDate); 

    $MyList = $collect_if(find($Prototype=="pArticle"), $Fruit!="",$Path).isort($Fruit); 

    So, in the latter case, $MyList is a list of paths, but the paths are sorted in the order of each item's $Year value rather than the default $OutlineOrder of the source objects. Consider notes 'A', 'B', and 'C' in that existing on that $OutlineOrder. Without the sort, $MyList created above is the paths [/A;/B;/C]. If the notes' respective $Fruit values are "Apple","apple","Pear", then a $Year-based sort make the $MyList to be [/C;/A;/B] —whereas a normal .sort($Fruit) would result in [/A;/C;/B].

    In this argument-based usage, the sort ordering is based on the data type of AttributeRef:

    • Number-type: and Interval-type: numerical sort
    • Date-type: sort on date (implied numerical)
    • All other types lexical

    But if attributeRef is Number-type, List.nsort() could be used instead.

    With .isort() lexical sorts are always case-insensitive.

    Legacy: Use of sorting with Set-type data

    This operator does not apply to Set-type lists because, as from v9.0.0, Sets now auto-sort A–Z and cannot be (reliably) user-sorted to a different order. However, is passing the result to a List-type or to some other process—i.e. passing the sorted result, not the source Set—then sorted content is possible.

    list.last()

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

     Property  [other Property type actions]

     List  [operators of similar scope]

     Dictionary, Set & List operations  [other Dictionary, Set & List operations operators]

     source context dependent

     v9.0.0

     Baseline

     As at baseline


    Syntax note: Operators without any defined mandatory arguments may omit their empty closing parentheses


    list.last()

    list.last

    Returns the last item of a List- or Set-type list. If MyList is a 5-item list "ant;bee;cow;dog;eel":

    $MyString = $MyList.last; returns "eel"

    This is also the equivalent of $MyList[-1] or $MyList.at(-1).

    list.last(N)

    Returns a list of the last N items of a list. With the same list as above:

    $MyList2 = $MyList.last(2); returns "dog;eel"

    Testing for loop position

    This operator can be used to test the current loop state, i.e. whether the currently processed item is the last in the list. Here the code in the commented section is run only when the last list item in $MyList is being processed:

    	$MyList.each(anItem){
    		if(anItem==$MyList.last){
    			// some code here ...
    		};
    	};

    Note that '$MyList.last' is not a test in itself. Rather, it supplies the value of the last list item which can be tested against the currently processed item.

    See also list.first.

    list.lookup(keyStr)

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

     Function  [other Function type actions]

     List  [operators of similar scope]

     Dictionary, Set & List operations  [other Dictionary, Set & List operations operators]

     source context dependent

     v8.0.0

     Baseline

     As at baseline


    list.lookup(keyStr)

    The command .lookup() is intended for look-up tables (i.e. single dimension arrays) using a List- or Set-type list. For the key keyStr value is supplied, the matched key's value is return. We can set up an example listing, using a List-type attribute:

    $MyList = [ant:Wood ant;bee:Carder bee;cow:Jersey;dog:Labrador]; 

    This creates a 4 item look-up list. The first list item has two parts - the key 'ant' and its paired value 'Wood ant'. Passing a key via .lookup, returns its key:

    $MyString = $MyList.lookup("cow"); → "Jersey", as list item 3's key is matched.

    If a key value with no match is passed, the result is an empty string

    $MyString = $MyList.lookup("pig"); → ""

    But if we add a 'default' key/value pair (anywhere in the list):

    $MyList = [ant:Wood ant;bee:Carder bee;cow:Jersey;dog:Labrador;default:animal]; 

    and re-run the last example:

    $MyString = $MyList.lookup("pig"); → "animal"

    There is still no match but as a default is defined, the default value of "animal" is returned.

    More complex and nuanced use of .lookup() is described in the discussion of look-up tables.

    Dictionary vs. Lookup

    The newer Dictionary data-type offers a more efficient and feature rich way of working with lookup lists.

    Legacy use (pre v8)

    For look-up tables .lookup() is preferred to the older .at() for clarity, and to avoid ambiguity when the argument is numeric. Using the example list as above:

    $MyString = $MyList.at(3); → "dog:Labrador", the whole fourth element of the list (do not forget N is counted from zero).
    $MyString = $MyList.lookup(3) → "animal", the lookup result for key value 5 which doesn't exist, so we get the default.
    list.max()

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

     Property  [other Property type actions]

     List  [operators of similar scope]

     Data manipulation  [other Data manipulation operators]

     source context dependent

     v6.4.0

     Baseline

     As at baseline


    Syntax note: Operators without any defined mandatory arguments may omit their empty closing parentheses


    list.max()

    list.max

    The list.max() operator returns the largest item in a List- or Set-type list.

    This is a replacement for/alternative to the max() operator.

    Both the operators list.max() and list.min() use lexical comparison in most cases, but numeric comparison if the context is numeric (i.e. the reference is a Number-type attribute) and/or all list items are numbers. Thus:

    $Width=("1;100;2").max; 

    Since "Width" is numeric, max() will be return 100.

    $Name=("1;100;2").max; 

    Since the attribute "Name" is a string, max() will return 2.

    If without a list, create one on the fly:

    $MyMax = collect(all,$MyNumber).max; 
    $MyMax = collect(descendants,$Modified).max; 

    This allows export via ^value^:

    ^value(collect(descendants,$Modified).max)^ 

    To use max() with a list of items that are attributes or action code expressions, use list():

    Works: $MyNumber = list(4+2,9+6).max; (output: 15)

    For more complex examples, where list items are action code expressions, it may be necessary to use eval() to wrap each list item expression e.g. list(eval(expressionA),eval(expressionB)).

    Using lists of dates

    When using Date-type data bear in mind that the defaults for an unset Date attribute is "never" and that "never" is treated as sorting always before (i.e. less than) any set date. So to use .min with dates, filter out the unset values, whereas with .max it is not needed:

    $MyMax = collect_if(descendants,$Modified).max; 
    $MyMin = collect_if(descendants,($Modified!="never"),$Modified).min; 
    list.min()

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

     Property  [other Property type actions]

     List  [operators of similar scope]

     Data manipulation  [other Data manipulation operators]

     source context dependent

     v6.4.0

     Baseline

     As at baseline


    Syntax note: Operators without any defined mandatory arguments may omit their empty closing parentheses


    list.min()

    list.min

    The list.min() operator returns the smallest item in a List- or Set-type list.

    This is a replacement for/alternative to the min() operator.

    Both the operators list.min() and list.max() use lexical comparison in most cases, but numeric comparison if the context is numeric (i.e. the reference is a Number-type attribute) and/or all list items are numbers. Thus:

    $Width=("100;2;70").min; 

    Since "Width" is numeric, min() will be return 2.

    $Name=("100;2;70").min; 

    Since the attribute "Name" is a string, .min will return 100.

    If without a list, create one on the fly:

    $MyMin = collect_if(all,$MyNum>0,$MyNum).min; 
    $MyMin = collect(descendants,$Modified).min; 

    This allows export via ^value^:

    ^value(collect(descendants,$Modified).min)^ 

    To use count() with a list of items that are attributes or action code expressions, use list():

    Works: $MyNumber = list(4+2,9+6).min; (output: 6)

    For more complex examples, where list items are action code expressions, it may be necessary to use eval() to wrap each list item expression e.g. list(eval(expressionA),eval(expressionB)).

    Using lists of dates

    When using Date-type data bear in mind that the defaults for an unset Date attribute is "never" and that "never" is treated as sorting always before (i.e. less than) any set date. So to use .min with dates, filter out the unset values, whereas with .max it is not needed:

    $MyMax = collect_if(descendants,$Modified).max; 
    $MyMin = collect_if(descendants,($Modified!="never"),$Modified).min; 
    List.nsort([attributeRef])

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

    Operator Has Optional Arguments: 

     Function  [other Function type actions]

     Item  [operators of similar scope]

     Data manipulation  [other Data manipulation operators]

     List [about List data type]

     v5.8.0

     Baseline

     As at baseline

     [More on optional operator arguments]


    Syntax note: Operators without any defined mandatory arguments may omit their empty closing parentheses


    List.nsort([attributeRefStr])

    List.nsort()

    For List-type list data, the basic form

    $MyList = $MyList.nsort(); 
    $MyList = $MyList.nsort().reverse(); 

    re-sorts the referenced list's values in ascending numerical sort order. This means sorting '1,2,11' not 1,11,2' such as occurs with sort() and a lexical sort. A numerical sort is really only useful for numerical data. This implies:

    • Numbers or Interval-type (but not Date-type data)
    • Strings that begin with numbers

    For most string (text) values and Date-type date, consider List.sort() or List.isort(), both of which give lexical sorts of differing case sensitivity. The resulting sort order can be reversed overall by chaining the List.nsort() and List.reverse() functions:

    $MyList = $MyList.nsort().reverse(); 

    List.nsort(attributeRef)

    Here the referenced list must be a list of note names or paths, i.e. list $Name data or $Path data (but not a mix of the two). If note names are not unique within the document, path values must be used to achieve correct sort. This form of sort cannot be used with any other sort of value list. This operator cannot be applied to any list of values, unlike the short form above.

    In this form, the sort order can be based on the value of the stipulated attributeRef (a $-prefixed attribute name). The attribute's value is derived from the item identified by the $Name or $Path of the list item being evaluated:

    $MyList = $collect(children, $Name).nsort($PageNumber); 
    $MyList = $collect_if(find($Prototype=="pProduct"), $Price>0,$Path).nsort($Price); 

    In this argument-based usage, .nsort() assumes the target attribute is Number-type. This the source list must comprise titles of paths but attributeRef must be a Number-type attribute.

    Legacy: Use of sorting with Set-type data

    This operator does not apply to Set-type lists because, as from v9.0.0, Sets now auto-sort A–Z and cannot be (reliably) user-sorted to a different order. However, is passing the result to a List-type or to some other process—i.e. passing the sorted result, not the source Set—then sorted content is possible.

    list.randomItem()

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

     Function  [other Function type actions]

     List  [operators of similar scope]

     Dictionary, Set & List operations  [other Dictionary, Set & List operations operators]

     source context dependent

     v9.5.2

     Baseline

     As at baseline


    Syntax note: Operators without any defined mandatory arguments may omit their empty closing parentheses


    list.randomItem()

    The .randomItem() returns a randomly-selected item from a List- or Set-type list:

    $MyString = $MyList.randomItem(); 

    This replaces the extra coding needed for such a task if using rand().

    This operator can be used not only on attributes but also literal lists using list():

    $MyString = list("ant;bee;cow;dog").randomItem(); 

    list-based variables:

    var:list vList = "ant;bee;cow;dog"; $MyString = vList.randomItem(); 

    and list-creating operators:

    $MyString = collect(find($SomeAttribute=="xyz"),$Path).randomItem(); 
    list.remove(matchValue)

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

     Function  [other Function type actions]

     List  [operators of similar scope]

     Data manipulation  [other Data manipulation operators]

     source context dependent

     v8.1.0

     Baseline

     As at baseline


    list.remove(matchValue)

    This removes items from a List- or Set-type list. The argument matchValue may be of the desired data type for matching. For example,

    $MyList = $MyList.remove(0); 

    returns a new list from which all elements equal to zero have been removed, and

    $MyList = $MyList.remove("cat"); 

    returns a new list from which call elements equal to "cat" have been removed.

    $MyList = $MyList.remove("cat; dog; badger"); 

    removes "cats", "dogs", and "badgers".

    list.replace(regexMatchStr, replacementStr)

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

    Operator Uses Regular Expressions: 

     Function  [other Function type actions]

     Item  [operators of similar scope]

     Data manipulation  [other Data manipulation operators]

     source context dependent

     v5.7.0

     Baseline

     As at baseline

     [More on regular expressions in Tinderbox]


    list.replace(regexMatchStr, replacementStr)

    This operator allows simple text transformations of List- or Set-type list data. The result remains a List or Set as per the list of references supplied. Unlike in contains() type operators, some regular expressions are not supported for either argument; regular expression use is discussed in more detail below.

    Very often, a replace output is passed back to the calling list value, updating the source:

    $MyList = $MyList.replace("Eggs","Ham); 

    note how the output of the .replace() operator has to explicitly be passed back to the source list to overwrite its data (if this is thew desired intent!).

    regexMatchStr and replacement are one of:

    • an action code expression (which includes just referencing a single attribute name')
    • a quoted string, which may be either:
      • a literal string (i.e. actual text)
      • a regular expression ('regex') (only for regexMatchStr)

    list.replace(regexMatchStr, replacementStr)

    List and set type attributes can use replace, though the scope of replacement is more limited than with strings. With listings, the match with and replacement of can only be for a complete list value and not part of a value.

    A Replace action does not alter the original source

    Using .replace() does not affect the source string unless the replacement output is used to overwrite the original source value. Thus if $MyString holds "Hello World" then:

    $MyStringA = $MyString.replace(" World"); 

    $MyString remains "Hello Word" and $MyStringA has value "Hello". The source is unchanged. But, if we set the source to the output

    $MyString = $MyString.replace(" World"); 

    Now $MyString becomes "Hello" and the original value is lost (overwritten by the new one.

    Using regex (regular expressions)

    Most basic regular expressions should work but string start (^) and string end ($) matches work in an unexpected way. When .replace() is run it looks at the internal string value of the Set or List.

    Thus a list of values, like ant/bee/cow/dog/eel, is stored and matched as a single semi-colon delimited string "ant;bee;cow;dog;eel". Note Tinderbox does not create a final semi-colon after the last value, but will not complain if the user adds one, e.g. via manual input. Thus a ^ regular expression matches only before the 'a' of 'ant' and not the start of other list values. Similarly, $ matches after the 'g' of dog and not the end of other list values. It might be thought of as '^ant;bee;cow;dog;eel$' as opposed to '^ant$;^bee$;^cow$;^dog$;^eel$'.

    So, in-list value boundaries still exist for regular expression matching but only as literal semicolons. Thus to change 'ee' to 'eet' in the above list but only for 'bee' and not 'eel':

    $MyListA = $MyList.replace("ee;","eet;").replace("ee$","eet"); 

    Note how two chained .replace() calls are needed, not one. The first is for inter-value boundaries and the second for the overall string end (had the data had a closing semi-colon the first match catches it so that scenario's still covered. To reverse the scenario and match the 'ee' at the start of a value:

    $MyListA = $MyList.replace(";ee","ree;").replace("^ee","ree"); 

    That changes 'eel' to 'reel' but leaves 'bee' unaltered.

    It is possible to write back to the same attribute:

    $MyList = $MyList.replace("ee;","eet;").replace("ee$","eet"); 

    but, the former is a good idea whilst developing/testing code for this technique, only switching out latter once sure of the result.

    Regular Expressions and Back-references

    Regular expressions can be used to set back-references in the regexMatchStr input string, as in an agent query, that can then be used in the replacementStr string. This is described in more detail here.

    Trimming leading/trailing whitespace

    $MyList = $MyList.replace("+","").replace(" +$","").replace(" *; *",";"); 

    The ' +' means one or more space characters. The first replace finds such a sub-string immediately following the start of the whole string ^), whilst the second does the same for a sub-string immediately before the end of the string ($). The third replace finds zero or more space characters either side of a semi-colon (the per-item list delimiter). The latter also matches a normal ';' delimiter but the test save writing separate regular expressions for space before and after the delimiter (e.g. " +;" and "; +") so the zero-or-more test (*) is used here instead of the one-or-more (+) used for the start/end of the overall string. Thus, using the code above, a lists like these with items having undesired leading/trailing space:

    " ant ; bee ; cow ; dog " 
    " ant ;bee ;cow ; dog" 

    …both become…

    "ant;bee;cow;dog" 

    Dealing with inline quote characters

    Because regexMatchStr is parsed for regular expressions, it may be possible to use the '\dnn' form described here to work around the lack of escaping from single double quotes within strings.

    list.reverse()

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

     Function  [other Function type actions]

     Item  [operators of similar scope]

     Data manipulation  [other Data manipulation operators]

     List [about List data type]

     v5.8.0

     Baseline

     As at baseline


    Syntax note: Operators without any defined mandatory arguments may omit their empty closing parentheses


    list.reverse()

    list.reverse

    This function reverses the order of the referenced List-type list. The function does not reverse the individual list values, but rather reverses the exact order of the individual values. Trailing parentheses are optional for this function.

    $MyList = $MyList.reverse(); 
    $MyList = [ant;bee;cow].reverse(); 

    The function may be chained with the list.sort() and list.isort() functions, noting that sorting can only be used with List-type and not Set-type data:

    $MyList = $MyList.sort().reverse(); 
    $MyList = $MyList.isort().reverse(); 

    Reversing Set-type lists

    As set-type lists are auto-sorted, this operator only makes sense to use when passing to that function/operator/type other that set data.

    list.select()

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

    Operator Uses Scoped Arguments: 

     Function  [other Function type actions]

     Group  [operators of similar scope]

     Data manipulation  [other Data manipulation operators]

     source context dependent

     v9.6.0

     Baseline

     As at baseline

     [More on scoped arguments in Action Code]


    list.select()

    The list.select() operator allows the document's current (UI) focus to be shifted, to use the item(s)m defined in a List- or Set-type list. The list may be a literal string, or the value of an attribute or variable.

    [/Note A;/Note B].select(); 
    $MyList.select(); 
    vItems.select(); 

    This specialist operator assist in the scenario where, whilst running action code, it is necessary to change the selection such that the locus of 'this' changes. Some action code operators only address the currently selected item(s). The select(scope) operator allows the selection to be changed on the fly without the user having to do so via the UI.

    Because using select without arguments has a distinct and different function is it listed separately: select().

    list.size()

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

     Property  [other Property type actions]

     Item  [operators of similar scope]

     Data manipulation  [other Data manipulation operators]

     Number [about Number data type]

     v5.7.0

     Baseline

     As at baseline


    Syntax note: Operators without any defined mandatory arguments may omit their empty closing parentheses


    list.size()

    list.size

    This returns the Number of discrete values in a List- or Set-type list. The returned number can be coerced to a string. Trailing parentheses are optional for this property. Examples:

    $MyList = [hello;world]; $MyStringA = $MyList.size; 

    $MyStringA is set to "2".

    This property is the same evaluation as list.count or count(list).

    This operator can also be used on other attribute data types that are string-like, URL, File, etc.

    List.sort([attributeRef])

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

    Operator Has Optional Arguments: 

     Function  [other Function type actions]

     Item  [operators of similar scope]

     Data manipulation  [other Data manipulation operators]

     List [about List data type]

     v5.8.0

     Baseline

     As at baseline

     [More on optional operator arguments]


    Syntax note: Operators without any defined mandatory arguments may omit their empty closing parentheses


    List.sort([attributeRef])

    List.sort()

    The basic form

    $MyList = $MyList.sort(); 

    This function re-sorts the referenced list's values in lexical, case-sensitive order. This means sorting all upper case letters before any lower case ones as in "Ant;Bee;Cow;ant;bee;cow". Users of non-accented languages (for the content of their notes) will likely find the case-insensitive List.isort() of more practical use.

    A forced numerical sort (1,2,11 not 1,11,2) can be achieved by using List.nsort(). Or, if using $Name or $Path data, use the optional long from (below) and let the nominated attribute's data type set the form of sort, e.g. for date sorting, sort on a Date-type attribute.

    The resulting sort order can be reversed overall by chaining the List.sort() and List.reverse() functions:

    $MyList = $MyList.sort().reverse(); 

    Sets can be sorted, on the fly, so a sorted output can be passed to a List. Passing the sorted output of a Set to another Set has an unknown outcome, in terms of stored sort order.

    List sorting can be used to process group designators. For example:

    $MyList=$Colors(children); 

    finds a list of the colours of each child of the current note, and:

    $MyNumber=$Width(children).max;

    will find the maximum width of the current container's children. When applied to the attribute $Text:

    $Text=$Text(children);

    the texts of each child are appended, separated by paragraph breaks.

    List.sort(attributeRef)

    Here the referenced List must be a list of note names or paths, i.e. a list of $Name data or $Path data (but not a mix of the two). If note names are not unique within the document, path values must be used to achieve correct sort. This is because the stipulated

    The attributeRef argument is a $-prefixed attribute reference and indicates the attribute supplying the sorted value in each list item. As a result, this form of sort cannot be used with any other date type of list and cannot be applied to a literal list of values (as they have no attributes!), unlike the short un-argumented form above.

    Thus, the sort order is based on the value of the stipulated attributeRef and that value is derived from the $Name or $Path of the list item being evaluated:

    $MyList = collect(children, $Name).sort($StartDate); 
    $MyList = collect_if(find($Prototype=="pArticle"), $Year!="",$Path).sort($Year); 

    So, in the latter case, $MyList is a list of paths, but the paths are sorted in the order of each item's $Year value rather than the default $OutlineOrder of the source objects. Consider notes 'A', 'B', and 'C' in that existing on that $OutlineOrder. Without the sort, $MyList created above is the paths [/A;/B;/C]. If the notes' respective $Year values are "1965","2010","1980", then a $Year-based sort make the $MyList to be [/A;/C;/B] (i.e. by increasing year value).

    In this argument-based usage, the sort ordering is based on the data type of attributeRef:

    • Number-type: and Interval-type: numerical sort
    • Date-type: sort on date (implied numerical)
    • All other types lexical

    But if attributeRef is Number-type, List.nsort() could be used instead.

    With .sort() lexical sorts are always case-insensitive.

    Group designators are allowed in attribute references. For example:

    $MyList=$Colors(children); 

    finds a list of the colours of each child of this note, and:

    $MyNumber=$Width(children).max; 

    will find the maximum width of the container's children. When applied to the attribute $Text:

    $Text=$Text(children); 

    the texts of each child are appended, separated by paragraph breaks.

    Legacy: Use of sorting with Set-type data

    This operator does not apply to Set-type lists because, as from v9.0.0, Sets now auto-sort A–Z and cannot be (reliably) user-sorted to a different order. However, is passing the result to a List-type or to some other process—i.e. passing the sorted result, not the source Set—then sorted content is possible.

    list.sum_if(loopVar, condition[, actionCtrode])

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

    Operator Has Optional Arguments: 

    Operator Has Conditional Arguments: 

    Operator Uses Loop Variable Argument: 

     Function  [other Function type actions]

     Group  [operators of similar scope]

     Mathematical  [other Mathematical operators]

     Number [about Number data type]

     v9.5.0

     Baseline

     As at baseline

     [More on optional operator arguments]

     [More on conditional operator arguments]

     [More on loop variable arguments]


    list.sum_if(loopVar, condition[, actionStr])

    The dot-operator .sum_if() sums the values of members of a List- or Set-type list that satisfy a condition.

    Implicit assumption: list contains numerical values. String item values (i.e. non-digit characters) are ignored.

    Each item in the list is bound in turn to loopVar, and if condition is met, the items value is added to the returned sum. Note that the actionStr is evaluated, allowing a transform to be carried out on a matched list member's value before it is added to the overall returned sum.

    loopVar is essentially the same as the loop variable used by the list.each() operator. In the examples below, for clarity the loopVar value "anItem" is used, but as with any loop variable a shorter less expressive values such a "x" can be used (e.g. by more expert users).

    The condition argument is a conditional query expression for which each tested item must return true or false.

    The operator applies the actionStr to only those list items for which condition is true. For only list items meeting condition, the result of actionStr on loopVar is returned as List-type data.

    For example, if $MyList is "1;2;3;4;5", then:

    $MyListA = $MyList.sum_if(aValue, aValue>3) 

    returns the sum of all the members of $MyList that are greater than 3, i.e. 9.

    Non-numeric list values are ignored. Were $MyList to be "1;2;foo;3;4;5", then

    $MyListA = $MyList.sum_if(aValue, aValue>3) 

    returns the sum of all the numeric members of $MyList that are greater than 3, i.e. 9.

    An optional third argument actionStr allows a matched values to be transformed before they are added to the sum. So, if $MyList is "1;2;3;4;5", then:

    $MyListA = $MyList.sum_if(aValue, aValue>3, aValue*aValue) 

    returns the sum of the squares of each member that is greater than 3, i.e. 4 and 5 squared, 41.

    list.sum_if() vs. sum_if()

    Although the two appear similar. The .sum_if() operator works directly on the source list values, whereas sum_if() creates a list of $Path values and returns an attribute value from each of those paths (where the item at the $Path meets the 'if' condition).

    list.sum()

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

     Function  [other Function type actions]

     Item  [operators of similar scope]

     Mathematical  [other Mathematical operators]

     Number [about Number data type]

     v8.0.0

     Baseline

     As at baseline


    Syntax note: Operators without any defined mandatory arguments may omit their empty closing parentheses


    list.sum()

    list.sum

    For a list of List- or Set-type data, this adds up lists of numbers. If $MyList is 1;2;3;4, then for:

    $MyNumber = $MyList.sum; 

    $MyNumber is 10, i.e. 1+2+3+4.

    Non-numerical items

    The general expectation is this operator is used for number-only lists. Non-numerical list items are ignored:

    "2; 4; 6; 12".sum gives 24 
    "2; 8bees; 4; bee; 6; bee5; 12; bee2bee" also gives 24 

    However, be aware of note this edge case;

    2; 8 bees; 4; bee; 6; bee 5; 12; bee 2 bee gives 32 

    Here, the original result of 24 is supplemented by the opening 8 from '8 bees' and the trailing 5 from 'bee5' to give 32. But, the 2 entirely within 'bee 2 bee' is not counted.

    list.tr(inStr, outStr)

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

     Function  [other Function type actions]

     Item  [operators of similar scope]

     Data manipulation  [other Data manipulation operators]

     source context dependent

     v5.7.0

     Baseline

     As at baseline


    list.tr(inStr, outStr)

    This operator allows simple single character string manipulation on a List- or Set-type list. It computes a new list, copying each character of the source list but converting any characters in inStr to the corresponding characters in outStr. For example:

    $MyList = $MyList.tr("a","A"); 

    returns a copy of $MyList in which every "a" is converted to "A".

    Backslash characters must be quoted and escaped:

    $MyList = $MyList("c","\\r"); 

    converts every "c" to a Macintosh newline characters (\r) . Note the need in this context for an extra backslash escape (so Tinderbox knows the intended swap value is "\r" and not "r").

    For further information, see the macOS X man page for the UNIX tr command.

    List.unique()

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

     Function  [other Function type actions]

     Item  [operators of similar scope]

     Data manipulation  [other Data manipulation operators]

     List [about List data type]

     v5.8.0

     Baseline

     As at baseline


    Syntax note: Operators without any defined mandatory arguments may omit their empty closing parentheses


    List.unique()

    List.unique

    This returns List-type data of the unique values in the list, as a sorted but de-duped list. Hitherto, de-duping required passing data into a Set-type attribute and back. For the same reason this operator really only makes sense to use on List-type lists as a Set cannot support duplicate items. Trailing parentheses are optional for this function.

    Be aware that this function results in a case insensitive A-Z sort, thus not 'bee;ant;cow' as might otherwise be assumed (to get such an outcome see further below). For example, if $MyList is 'bee;ant;cow;bee':

    $MyList = $MyList.unique; 

    results in a list value 'ant;bee;cow'.

    The function can be chained with .sort-type actions and .reverse.

    $MyList = $MyList("Another note").unique; 
    $SomeList = collect(children, $MyNumberList).unique.nsort; 
    $MyList = collect(children, $MyList).unique.reverse; 

    The last above sets $MyList to a list of all the unique, discrete, values to be found in $MyList in every child of the current note. Use with collect() or collect_if() to act on a particular attribute across a group of notes. If a collect() with query scope is the designator 'all' the result will be every discrete value for the referenced list attribute across the whole document.

    This function does not apply to Set-type lists because Sets automatically de-duplicate items so are always a list of unique values.

    De-duping a list whilst retaining original sort order

    The basic method is this:

       $MyList.each(anItem){
          if(!$MyList2.contains(anItem)){
             $MyList2+=anItem;
          }
       };

    If is it desired to de-dupe $MyList back to itself, use a list-type variable:

       var:list vList;
       $MyList.each(anItem){
          if(!vList.contains(anItem)){
             vList+=anItem;
          }
       };
       $MyList = vList;

    A further consideration is whether the tested list's items are in varying case ('ant' vs. 'Ant' vs. 'ANT' etc.). For instance, to take a mixed case list with duplicates and end up with a de-duped all-lowercase version, use:

       var:list vList;
       $MyList.lowercase.each(anItem){
          if(!vList.contains(anItem)){
             vList+=anItem;
          }
       };
       $MyList = vList;

    Resulting order

    .unique() preserves the order of elements in a list. Originally, this operator forced an A-Z order, but this was not ideal as one feature of List-type lists is that they allow duplicates do not auto-sort—unlike Set-type lists). Thus now:

    "C:A;A;B".unique; 

    now returns "C;A;B" (previously it would have been "A;B;C", destroying the original ordering). The output retains the first-occurring item, by list order, of any list value. The underlying assumptions is dupes gat added to the end of the list so the first occurrence is the desired item.

    list(actionStr)

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

     Function  [other Function type actions]

     Item  [operators of similar scope]

     Data manipulation  [other Data manipulation operators]

     List [about List data type]

     v5.10.0

     Baseline

     As at baseline


    list(actionStr)

    This function returns a List as the evaluated format of each of its comma-delimited argument list of actionStr expressions.

    Implicit assumption: list contains numerical values. String item values (i.e. non-digit characters) are ignored.

    The actionStr arguments can be:

    • Literal values: Fred though there is little point in using these unless the list is subsequently to be concatenated to a String.
    • Basic literal operations "Fred"+" " +Smith".
    • Arithmetic operations: 6/2.
    • Attributes (values) both system e.g. $Name and user attributes e.g. $MyNumber.
    • Action operators sqrt(2).
    • Action code expressions, e.g. "Date: "+date("today").format("*").

    The function is also useful as a method of assembling lists of attributes or expressions for action functions using lists such as count(), max() and min():

    FAILS: $MyDate = max($MyDateA,$MyDateB,$MyDateC);

    The latter fails as max() interprets the list as 3 literal strings "$MyDateA", etc., and does a lexical sort on those values. However:

    WORKS: $MyDate = max(list($MyDateA,$MyDateB,$MyDateC));

    Functions creating lists (sum(), links(), collect(), etc.) do not have the same problems with the likes of max as the former output a valid list that can be used directly. For instance:

    WORKS: $MyDate = max(links.outbound.attended.$MyDate);

    For more complex examples, where list items are action code expressions, it may be necessary to use eval() to wrap each list item's actionStr, e.g. list(eval(expressionA),eval(expressionB)).

    Examples

    This returns a list of numbers resulting from simple evaluations:

    Code: list(4+5,9-3,100/2.5)
    Output value, a list: 9;6;40

    This example, this makes a single evaluated string out of a list using an actionStr expression:

    Code: list("This note 's $Width is "+$Width, "the $Xpos is "+$Xpos).format(" and ")+"!")
    Output value, a string: This note's $Width is 3 and the $Xpos is 90.041081!

    This example is not overly complex but points to how list() can be used in constructing output strings/lists that are otherwise difficult to create. The more complex the actionStr passed to list() the greater the likelihood of getting no output, or an unexpected one. If complex inputs do not work consider using more parentheses to help TB figure the order of sub-task execution or else put the result of actionStr into new attributes and then pass the value of the latter into list() as an argument.

    list[itemNum]

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

     Function  [other Function type actions]

     List  [operators of similar scope]

     Dictionary, Set & List operations  [other Dictionary, Set & List operations operators]

     source context dependent

     v9.0.0

     Baseline

     As at baseline


    list[itemNum]

    sourceNum is the zero-based item number in the referenced List- or Set-type list.

    Elements in lists, sets, may be extracted (referenced) with the bracket operator:

    $MyList[1] 

    This has the same effect as list.at( ), but may be more convenient. Both

    $MyList[1] 
    $MyList.at(1) 

    Returns the second list item (as list item addresses are zero-based).

    This syntax can also assign values to specific elements of lists. For example,

    $MyList=[apple; pear; plum; cherry]; 
    $MyList[1]="persimmon"; 

    Will replace "pear" with "persimmon".

    Nested lists

    MyList = [cow;bee;[fish;whale];ant] 
    $MyList[2][1] gives "whale"
    locale([localeCodeStr])

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

    Operator Has Optional Arguments: 

     Function  [other Function type actions]

     Document  [operators of similar scope]

     Date-time  [other Date-time operators]

     success boolean

     v6.0.0

     Baseline

     As at baseline

     [More on optional operator arguments]


    Syntax note: Operators without any defined mandatory arguments may omit their empty closing parentheses


    locale(localeCodeStr)

    locale(), allows changing of the locale used to translate dates. The same date can be written in a different format in different parts of the world. For example, in the USA a date is written 12/1/2006 to denote December 1, whereas in UK the same date is written 1/12/2006 and so on for variations around the world.

    To read the current host OS' locale, call the operator with no argument:

    $MyString = locale(); 

    To set a locale, e.g. here for 'British English', pass the desired locale's code value as localeCodeStr;

    locale("en_GB") 

    Locale codes begin with a two-letter language code, followed by and underscore and a two-letter region code. These are ISO standards ISO-639 and ISO-3166 respectively. Code combinations are available for any language supported by macOS.

    To read, or return to, the user's preferred locale, i.e. is derived from their Mac's OS account, use

    $MyString = locale(); 

    You may also save the old locale in an attribute for subsequent use. For example:

    $OldLocale=locale("en_GB"); 
    …do various things, and then reset the original locale…
    locale($OldLocale); 
    … if simple call locale() with no argument if the host OS locale had remained unchanged.

    Note that changing the locale() can be fairly time-consuming, as lots of machinery must be torn down and rebuilt for each change.

    log(sourceNum)

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

     Function  [other Function type actions]

     Item  [operators of similar scope]

     Mathematical  [other Mathematical operators]

     Number [about Number data type]

     v4.0.0

     Baseline

     As at baseline


    log(sourceNum)

    The operator log() computes the natural logarithm of its sourceNum number, which should be a number, a numeric attribute, or an action code expression that can be interpreted as a number.

    $MyNumber = log(3); 

    returns '1.098612289' for an input of 3.

    lowercase(dataStr)

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

    Operator Has Newer Dot-Operator Variant: 

     Function  [other Function type actions]

     Item  [operators of similar scope]

     Formatting  [other Formatting operators]

     String [about String data type]

     v4.6.0

     Baseline

     As at baseline

    Yes


    lowercase(dataStr)

    The contents of text dataStr are returned entirely in lower case.

    If $MyString is "Hello World":

    $MyString = lowercase($MyString); 

    would set $MyString to "hello world".

    Functionally equivalent to String.lowercase().

    max(numberList)

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

    Operator Has Newer Dot-Operator Variant: 

     Function  [other Function type actions]

     List  [operators of similar scope]

     Mathematical  [other Mathematical operators]

     Number [about Number data type]

     v4.0.0

     Baseline

     As at baseline

    Yes


    max(numberList)

    The max() operator returns the largest item in a list or the values or a List or Set data type attribute. As it operates off a list it may be more convenient to use the newer list.max() chained operator.

    Both the operators max() and min() use lexical comparison in most cases, but numeric comparison if the context is numeric (i.e. the reference is a Number-type attribute) and/or all list items are numbers. Thus:

    $Width=max("1;100;2"); 

    Since "Width" is numeric, max() will be return 100.

    $Name=max("1;100;2"); 

    Since the attribute "Name" is a string, max() will return 2.

    If without a list, create one on the fly using list(), collect() or collect_if():

    $MyMax = max(list($DateA,$DateB,$DateC)); 
    $MyMax = max(collect(descendants,$Modified)); 
    $MyMax = max(collect_if(all,$MyNum>0,$MyNum)); 

    This allows export via ^value^:

    ^value(max(collect(descendants,$Modified)))^ 

    To use max() with a list of action code expressions, use list():

    Works: $MyNumber = max(list(4+2,9+6)); (output: 15)

    For more complex examples, where list items are action code expressions, it may be necessary to use eval() to wrap each list item expression e.g. list(eval(expressionA),eval(expressionB)).

    Using lists of dates

    When using Date-type data bear in mind that the defaults for an unset Date attribute is "never" and that "never" is treated as sorting always before (i.e. less than) any set date. So to use min() with dates, filter out the unset values, whereas with max() it is not needed:

    $MyMax = max(collect_if(descendants,$Modified)); 
    $MyMin = min(collect_if(descendants,($Modified!="never"),$Modified)); 
    mcp()

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

     Operator  [other Operator type actions]

     Document  [operators of similar scope]

     Document configuration  [other Document configuration operators]

     Dictionary [about Dictionary data type]

     v11.8.0

     11.8.0

     As at baseline


    mcp()

    From v11.8.0, the mcp() operator returns a Dictionary with useful information about the current state of the document’s MCP connection. Keys are:

    • status: one of [active, broken, disallowed, disabled, none]
    • protocol: the version string of the MCP protocol in use
    • connected: one of [true, false]
    • client: the client AI, a string such as "claude-code" or "gemini"
    • version: the client's version string, such as "2.1.138"

    Example:

    $MyDictionary = mcp(); 
    min(numberList)

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

    Operator Has Newer Dot-Operator Variant: 

     Function  [other Function type actions]

     List  [operators of similar scope]

     Mathematical  [other Mathematical operators]

     Number [about Number data type]

     v4.0.0

     Baseline

     As at baseline

    Yes


    min(numberList)

    The min() operator returns the smallest item in a list or the values of a List or Set data type attribute. As it operates off a list it may be more convenient to use the newer list.min() chained operator.

    Both the operators max() and min() use lexical comparison in most cases, but numeric comparison if the context is numeric (i.e. the reference is a Number-type attribute) and/or all list items are numbers. Thus:

    $Width=min("100;2;70"); 

    Since "Width" is numeric, min() will be return 2.

    $Name=min("100;2;70"); 

    Since the attribute "Name" is a string, min() will return 100.

    If without a list, create one on the fly using list(), collect() or collect_if():

    $FistDate = min(list($DateA,$DateB,$DateC)); 
    $MyMin = min(collect(descendants, $Modified)); 
    $MyMin = min(collect_if(all,$MyNum>0,$MyNum)); 

    This allows export via ^value^:

    ^value(min(collect(descendants,$Modified)))^ 

    To use min() with a list of items that are attributes or action code expressions, use list():

    Works: $MyNumber = min(list(4+2,9+6)); (output: 6)

    For more complex examples, where list items are action code expressions, it may be necessary to use eval() to wrap each list item expression e.g. list(eval(expressionA),eval(expressionB)).

    Using lists of dates

    When using Date-type data bear in mind that the defaults for an unset Date attribute is "never" and that "never" is treated as sorting always before (i.e. less than) any set date. So to use min() with dates, filter out the unset values, whereas with max() it is not needed:

    $MyMax = max(collect_if(descendants,$Modified)); 
    $MyMin = min(collect_if(descendants,($Modified!="never"),$Modified)); 
    minute(aDate, minutesNum)

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

    Operator Has Newer Dot-Operator Variant: 

     Function  [other Function type actions]

     Item  [operators of similar scope]

     Date-time  [other Date-time operators]

     Date [about Date data type]

     v5.7.0

     Baseline

     As at baseline

    Yes


    minute(aDate, minutesNum)

    creates a new date based on the aDate action code expression, but in which the minute is minutesNum. The source Date is not changed unless aDate is an attribute and the attribute is re-setting itself:

    $MyDateA = minute($MyDate,14); $MyDate is not changed
    $MyDate = minute($MyDate,14); $MyDate is changed

    Examples. If $MyDate is 4 July 2009 09:30, then

    $MyDateA=minute($MyDate,5); 

    will change $MyDate to 4 July 2009 19:05 whilst leaving $MyDate as 4 July 2009 09:30. However, if the code is self-referring:

    $MyDate=minute($MyDate,5); 

    will change $MyDate to 4 July 2009 19:05.

    Take care using the later self-referring form in a $Rule or agent as it fires every agent update cycle adding 5 minutes each time! Make sure you use a guard agent or conditional query to make the action out of scope after the first application. Or, consider using a Stamp, which only fires once per (manual) application.

    The single-argument method that reads the minutes value is documented separately: see minute(Date).

    minute(aDate)

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

    Operator Has Newer Dot-Operator Variant: 

     Function  [other Function type actions]

     Item  [operators of similar scope]

     Date-time  [other Date-time operators]

     Number [about Number data type]

     v5.7.0

     Baseline

     As at baseline

    Yes


    minute(aDate)

    returns the hour element from the aDate date/time action code expression, which may simply be a date-type attribute value.

    Alternatively, use Date.minute.

    The two-argument method used to set Dates is documented separately: see minute(aDate, minutesNum).

    minutes(startDate, endDate)

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

     Function  [other Function type actions]

     Item  [operators of similar scope]

     Date-time  [other Date-time operators]

     Number [about Number data type]

     v5.0.0

     Baseline

     As at baseline


    minutes(startDate, endDate)

    returns the Number of whole minutes that elapsed between startDate and endDate. If endDate is earlier than startDate then the result is negative.

    If $DateA has time 12:30 and $DateB has time 14:00, then:

    $MyNumber = minutes($DateA,$DateB); 

    sets $MyNumber to 90.

    Also see days(date1,date2).

    mod(sourceNum, modulusNum)

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

     Function  [other Function type actions]

     Item  [operators of similar scope]

     Mathematical  [other Mathematical operators]

     Number [about Number data type]

     v4.0.1

     Baseline

     As at baseline


    mod(sourceNum, moduloNum)

    mod() returns modulo of a number sourceNum as set by number modulusNum, i.e. the integer remainder of sourceNum divided by modulusNum. Thus:

    $MyNumber = mod(11,3); 

    sets $MyNumber to 2.

    modifierKeys

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

     Variable  [other Variable type actions]

     Item  [operators of similar scope]

     Data manipulation  [other Data manipulation operators]

     List [about List data type]

     v11.5.0

     11.5.0

     11.6.0


    Syntax note: Operators without any defined mandatory arguments may omit their empty closing parentheses


    modifierKeys

    When processing a stamp, the local List-type variable modifierKeys is set to a list of strings representing the modifier keys the user was pressing when the stamp is executed. For example, a value of [control;option] indicates that the control and option keys were pressed, and that neither the shift nor the command keys were pressed.

    Component values include: command, option, shift, and control.

    From v11.6.0, this variable is associated with (map-only) mouse actions.

    month(aDate[, monthsNum])

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

    Operator Has Optional Arguments: 

    Operator Has Newer Dot-Operator Variant: 

     Function  [other Function type actions]

     Item  [operators of similar scope]

     Date-time  [other Date-time operators]

     Date [about Date data type]

     v4.0.0

     Baseline

     As at baseline

     [More on optional operator arguments]

    Yes


    month(aDate[, monthsNum])

    Alternatively, use Date.month.

    month(aDate)

    returns the 1 or 2 digit month from the aDate date/time action code expression, which may simply be a date-type attribute value.

    month(aDate,monthsNum)

    creates a new date based on the aDate date/time expression, but in which the month is monthsNum (January = 1, through to December = 12). The source Date is not changed unless theDate is an attribute and the attribute is re-setting itself:

    $MyDateA = month($MyDate,10); 

    $MyDate is unaltered

    $MyDate = month($MyDate,10); 

    $MyDate is changed

    Examples. If $MyDate is July 4,2009, then

    $MyDate=month($MyDate,5); 

    will change $MyDate to May 4, 2009.

    months(startDate, endDate)

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

     Function  [other Function type actions]

     Item  [operators of similar scope]

     Date-time  [other Date-time operators]

     Number [about Number data type]

     v6.0.0

     Baseline

     As at baseline


    months(startDate, endDate)

    returns the Number of whole months that have elapsed between startDate and endDate. If endDate is earlier than startDate then the result is negative.

    If $DateA is 3 January 2016 and $DateB is 9 April 2016, then:

    $MyNumber = months($DateA,$DateB); 

    sets $MyNumber to 4.

    Also see days(date1,date2).

    neighbors(scope, distanceNum[, linkTypeStr])

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

    Operator Uses Scoped Arguments: 

    Operator Has Optional Arguments: 

     Function  [other Function type actions]

     Group  [operators of similar scope]

     Data manipulation  [other Data manipulation operators]

     List [about List data type]

     v9.0.0

     Baseline

     As at baseline

     [More on scoped arguments in Action Code]

     [More on optional operator arguments]


    neighbors(scope, distanceNum)

    Returns a list of the path(s) of all those notes that can be reached by following exactly distanceNum links outward from the designated note or notes. Only the shortest possible path between two notes is considered. The operator will report links from the source node to itself, i.e. self-links. Prototype-type links are ignored. For example:

    $MyList = neighbors(this, 3); 

    Returns the set of notes that are connected from this note by exactly three (outbound) links.

    neighbors(scope, distanceNum, linkTypeStr)

    Returns the set of notes that are connected by exactly distanceNum links outward from the designated note or notes, but within those links considering only links of the specified link type linkTypeStr to filter on unnamed links use the type "*untitled".For example:

    $MyList = neighbors(children, 2, "example"); 

    Returns the set of notes that are connected from any of this note's children by exactly two (outbound) links of the link type "example".

    Different variations of 'neighbor' operators

    There are essentially two different subtypes within the 4 operators:

    • Direction. If the operator name includes a '2' the direction of connecting links are ignored. Otherwise, only outbound links are assessed.
    • Distance. If the operator name includes 'Within' then all notes at distances between 1 and distanceNum are considered. Otherwise, only notes at exactly distanceNum are considered.
    neighbors2(scope, distanceNum[, linkTypeStr])

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

    Operator Uses Scoped Arguments: 

    Operator Has Optional Arguments: 

     Function  [other Function type actions]

     Group  [operators of similar scope]

     Data manipulation  [other Data manipulation operators]

     List [about List data type]

     v9.0.0

     Baseline

     As at baseline

     [More on scoped arguments in Action Code]

     [More on optional operator arguments]


    neighbors2(scope, distanceNum)

    Returns a list of the path(s) of all those notes that can be reached by following exactly distanceNum links from the designated note or notes, regardless of the direction of those links (i.e. whether inbound or outbound). Only the shortest possible path between two notes is considered. The operator will report links from the source node to itself, i.e. self-links. Prototype-type links are ignored. For example:

    $MyList = neighbors2(this, 3); 

    Returns the set of notes that are connected from this note by exactly three links of either direction.

    neighbors2(scope, distanceNum, linkTypeStr)

    Returns the set of notes that are connected by exactly distanceNum links from the designated note or notes, regardless of the direction of a link (i.e. whether inbound or outbound) and within those links considering only links of the specified link type linkTypeStr. Unnamed links are specified as the type "*untitled". For example:

    $MyList = neighbors2(children, 2, "example"); 

    Returns the set of notes that are connected from any of this note's children by exactly two links of any direction but also of the link type "example".

    Different variations of 'neighbor' operators

    There are essentially two different subtypes within the 4 operators:

    • Direction. If the operator name includes a '2' the direction of connecting links are ignored. Otherwise, only outbound links are assessed.
    • Distance. If the operator name includes 'Within' then all notes at distances between 1 and distanceNum are considered. Otherwise, only notes at exactly distanceNum are considered.
    neighbors2Within(scope, distanceNum[, linkTypeStr])

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

    Operator Uses Scoped Arguments: 

    Operator Has Optional Arguments: 

     Function  [other Function type actions]

     Group  [operators of similar scope]

     Data manipulation  [other Data manipulation operators]

     List [about List data type]

     v9.0.0

     Baseline

     As at baseline

     [More on scoped arguments in Action Code]

     [More on optional operator arguments]


    neighbors2Within(scope, distanceNum)

    Returns a list of the path(s) of all those notes that can be reached by following between 1 and distanceNum links from the designated note or notes, regardless of the direction of those links (i.e. whether inbound or outbound). Only the shortest possible path between two notes is considered. The operator will report links from the source node to itself, i.e. self-links. Prototype-type links are ignored.

    The starting note or notes are considered to be connected to themselves.

    For example:

    $MyList = neighbors2Within(this, 3); 

    Returns the set of notes that are connected from this note by between 1–3 (outbound) links.

    neighbors2Within(scope, distanceNum, linkType)

    Returns the set of notes that are connected by following between 1 and distanceNum links from the designated note or notes, regardless of the direction of those links (i.e. whether inbound or outbound), but within those links considering only links of the specified link type linkTypeStr.

    The starting note or notes are considered to be connected to themselves. To filter on unnamed links use the type "*untitled". For example:

    $MyList = neighbors2Within(children, 2, "example"); 

    Returns the set of notes that are connected from any of this note's children by between 1–2 (outbound) links of the link type "example".

    Different variations of 'neighbor' operators

    There are essentially two different subtypes within the 4 operators:

    • Direction. If the operator name includes a '2' the direction of connecting links are ignored. Otherwise, only outbound links are assessed.
    • Distance. If the operator name includes 'Within' then all notes at distances between 1 and distanceNum are considered. Otherwise, only notes at exactly distanceNum are considered.
    neighborsWithin(scope, distanceNum[, linkTypeStr])

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

    Operator Uses Scoped Arguments: 

    Operator Has Optional Arguments: 

     Function  [other Function type actions]

     Group  [operators of similar scope]

     Data manipulation  [other Data manipulation operators]

     List [about List data type]

     v9.0.0

     Baseline

     As at baseline

     [More on scoped arguments in Action Code]

     [More on optional operator arguments]


    neighborsWithin(scope, distanceNum)

    Returns a list of the path(s) of all those notes that can be reached by following between 1 and distanceNum links outward from the designated note or notes. Only the shortest possible path between two notes is considered. The operator will report links from the source node to itself, i.e. self-links. Prototype-type links are ignored.

    The starting note or notes are considered to be connected to themselves.

    For example:

    $MyList = neighborsWithin(this, 3); 

    Returns the set of notes that are connected from this note by between 1–3 (outbound) links.

    neighborsWithin(scope, distanceNum, linkTypeSTr)

    Returns the set of notes that are connected by following between 1 and distanceNum links outward from the designated note or notes, but considering only links of the specified link type linkTypeStr.

    The starting note or notes are considered to be connected to themselves. To filter on unnamed links use the type "*untitled". For example:

    $MyList = neighborsWithin(children, 2, "example"); 

    Returns the set of notes that are connected from any of this note's children by between 1–2 (outbound) links of the link type "example".

    Different variations of 'neighbor' operators

    There are essentially two different subtypes within the 4 operators:

    • Direction. If the operator name includes a '2' the direction of connecting links are ignored. Otherwise, only outbound links are assessed.
    • Distance. If the operator name includes 'Within' then all notes at distances between 1 and distanceNum are considered. Otherwise, only notes at exactly distanceNum are considered.
    notify(headlineStr[, detailsStr, deliveryDateTime ])

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

    Operator Has Optional Arguments: 

     Function  [other Function type actions]

     Item  [operators of similar scope]

     Data manipulation  [other Data manipulation operators]

     success boolean

     v6.0.0

     Baseline

     As at baseline

     [More on optional operator arguments]


    notify(headlineStr[, details, deliveryTime ])

    notify() lets notes post notifications to the host Mac's User Notification Center.

    headlineStr is a string or action code expression, and will be the headline of the notification.

    notify("Hello world"); 

    The optional detailsStr is another string or action code expression, and provides an explanation of the notification.

    notify("Hello world", "Some descriptive text"); 

    The optional deliveryDateTime is a date or date expression that represents a delivery time in the future; if this argument is omitted or the time has already passed, the notification is shown immediately.

    notify("Hello world", "Some descriptive text",date("now + 1 hour")); 
    Number.ceil()

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

     Function  [other Function type actions]

     Item  [operators of similar scope]

     Mathematical  [other Mathematical operators]

     Number [about Number data type]

     v9.5.2

     Baseline

     As at baseline


    Syntax note: Operators without any defined mandatory arguments may omit their empty closing parentheses


    Number.ceil()

    Number.ceil() rounds the source number value of sourceNum up to next whole integer.

    Number.floor()

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

     Function  [other Function type actions]

     Item  [operators of similar scope]

     Mathematical  [other Mathematical operators]

     Number [about Number data type]

     v9.5.2

     Baseline

     As at baseline


    Syntax note: Operators without any defined mandatory arguments may omit their empty closing parentheses


    Number.floor()

    Number.floor() rounds the source number value of sourceNum down to previous whole integer. This is a dot-operator

    See also Number.ceil() and Number.round().

    If $MyNumber is 3.9 then:

    $MyNumber = $MyNumber.floor(); 

    sets $MyNumber to 3. Note unlike normal rounding the value is set downwards to the next integer (i.e. whole number).

    Number.format(decimalsNum[, widthNum, padStr]|formatStr)

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

    Operator Has Optional Arguments: 

     Function  [other Function type actions]

     Item  [operators of similar scope]

     Formatting  [other Formatting operators]

     String [about String data type]

     v5.8.0

     Baseline

     As at baseline

     [More on optional operator arguments]


    Number.format(decimalsNum[, widthNum, padStr]|formatStr)

    Number.format(decimalsNum, widthNum, padStr)

    Returns Number as a String, formatted to decimalsN decimal places.

    If widthNum is supplied, Number returned additionally left padded with spaces so that widthNum equals the sum of: [padding spaces]+[minus sign]+integer number(s)+decimal point+[decimal numbers]. Note that with widthNum, decimal character is not counted as part of the number. The presence of a minus sign is allowed for.

    This function supplements the existing format() and Number.precision() functions.

    For example, if $MyNumber is 3.1415927, then

    $MyString = $MyNumber.format(2); is "3.14"
    $MyString = $MyNumber.format(0); is "3"
    $MyString = $MyNumber.format(2,7); is "   3.14" (3 left padding spaces + 1 integer number + decimal point + 3 decimal numbers = 7)

    But if $MyNumber is negative, e.g. -3.1415927, then

    $MyString = $MyNumber.format(2,7) is "  -3.14" (2 left padding spaces + minus sign + 1 integer number + decimal point + 3 decimal numbers = 7)

    Literal numbers, e.g. 3.1415927, can also be worked with:

    $MyString = 5.1415927.format(2); is "5.14"

    The above works but the following syntax may seem less ambiguous by using parentheses to delimit the literal number:

    $MyString = (5.1415927).format(2); is "5.14"
    $MyString = (5.1415927).format(1,5); is '  5.1' (two left padding spaces + 1 integer number + decimal point + 1 decimal number = 5)

    If a group of numbers are being formatted so as to vertically decimal-point align as a column figures, e.g. financial data, it is necessary to know the widthN of 'longest' number to be used, remembering that a negative number adds one to its width count; 45 is width 2, -45 is width 3. In the example below the longest (widthNum) number in a set of currency figures has been worked out stored in a user Number attribute $MaxNumLen. Being currency, 2 decimal places will be enforced, and each number can be evaluated by a common formatting:

    [the number].format(2,$MaxLenNum) 

    If the widthN for a set of numbers cannot easily be assessed, an alternate option is simply to use a number known to be bigger than all likely width valid. Thus every number, including the longest, gets left-padded but all end up correctly aligned. In the latter example if all numbers are always likely to be less than 20, then $MaxLenNumber could be set to 20, or simply used directly:

    [the number].format(2,$MaxLenNum) 

    There is no easy way to sort a list of numbers on size (i.e. their widthNum), other than by looping the list via List.each() transforming each to a string (using zero decimal places!), saving the String.size of each of these as a number in a new list, then List.nsort and take the last item, .at(-1). As .nsort() sorts on ascending numerical order, the latter will be the size of the longest string (including negative numbers) in the original list. Assuming $MySizeList has all the size strings:

    $MaxLenNumber = ($MySizeList.nsort).at(-); 

    Why leave out decimal places when coercing the numbers to strings? 1234.56 is a bigger number than 12.34567, but the latter is the bigger size. However, 1234 is both bigger and 'wider' than 12.

    As can be seen, just setting a large arbitrary widthNum might save a lot of messing about!

    If the optional padStr is given, this specifies the character used for padding: use of a widthNum argument is expected. The default is a space:

    $MyString = 7.format(0,3); gives " 7"
    $MyString = 7.format(0,3,"0"); gives "007"
    $MyString = 7.format(0,3,"#"); gives "##7"

    Number.format("formatString")

    An alternate usage is to supply a quoted formatString argument that is always enclosed in double quotes.

    Supported formatString values (described in more detail further below) are:

    • "l" (lowercase letter 'L') gives Number as a string using (OS) locale-dependent group and decimal delimiters. For instance, 1000.00 as seen on a UK system would show as '1,000.00' but as '1.000,00' on a German system.
    • "$" formats Number to a string in the local currency to two decimal points.
    • "$0" formats Number to a string in the local currency rounded to the nearest whole major unit (i.e. whole dollars only not dollars.cents.)
    • "X" converts Number to a string in Roman numerals. So 4 would give string "IV" .
    • "o" (lowercase letter 'O') converts Number to a string in the localised ordinal

    Localised, locale-dependent, numbers. Using formatString "l" (lowercase letter 'L') will return a string of the source Number formatted with (OS) locale-dependent group & decimal delimiters. For example, for the US locale these are a comma and a period; in other locales they may vary. For example, if $MyNumber is 4562781.4, and it is desired to display it as a string with thousands delimited:

    $MyString = $MyNumber.format("l"); gives "4,562,781.4"

    Of course, depending on the users local, the delimiter may be something else. For instance in a German locale setting, it would be "4.562.781,4". For more on such difference see Wikipedia's article on 'Decimal Separators'.

    Currency formatting. Two currency-related format strings that can be used, again locale-based, to turn a Number into number string with a currency symbol prefix. Using formatString "$" formats the number to the local currency to two decimal points. Thus if $MyNumber is 1246.878:

    $MyString = $MyNumber.format("$"); 

    sets $MyString to "$1,246.88" isn the US, "£1,246.88" in UK, "€1,246.88" in France, etc. Note how the format also respects the local thousands separate, adding a comma after the initial digit.

    Use format string "$0" if the currency string is needed rounded to the neared whole major unit, e.g. whole dollars and not dollars.cents, :

    $MyString = $MyNumber.format("$0"); 

    which sets $MyString to "$1,247" isn the US, "£1,247" in UK, "€1,247" in France, etc.

    Roman Numerals. formatString "X" converts Number to a string in Roman numerals. For example, if $MyNumber is 3:

    $MyString = $MyNumber.format("X") 

    gives a $MyString value of "III".

    Ordinals. formatString "o" (lowercase letter 'O') converts Number to a string of localised ordinal value. For example, if $MyNumber is 3:

    $MyString = $MyNumber.format("o") 

    gives a $MyString value of "3rd" in English but "3e" in French, etc.

    Number.precision(decimalsNum)

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

     Function  [other Function type actions]

     Item  [operators of similar scope]

     Formatting  [other Formatting operators]

     Number [about Number data type]

     v5.7.0

     Baseline

     As at baseline


    Number.precision(decimalsNum)

    This function makes it easier to format numbers. The function returns the associated Number-type attributes value rounded to decimalsNum decimal places as Number-type data. If $MyNumber is 268.3289 then:

    $MyNumber.precision(2); 

    …sets $MyNumber to 268.33, whilst:

    $SomeNumber = $MyNumber.precision(2); 

    …sets $OtherNumber to 268.33. The above examples are the equivalent of the older syntax using format():

    format($MyNumber,2); 

    Literal numbers, e.g. 3.1415927, can also be worked with:

    $MyNumber = 5.1415927.precision(2); is 5.14

    The above works but the following syntax may seem less ambiguous by using parentheses to delimit the literal number:

    $MyNumber =(5.1415927).precision(2); is 5.14

    Since Number.precision() was added, format() has been supplemented by a Number.format(). The latter, in single input version equates to Number.precision(). However that Number.format() outputs a String-type, even if that can be coerced back to a number .

    The .precision() function can be used to add trailing zeroes to a decimal. If $MyNumber is 214.40, it will display as 214.4 which can be unhelpful if this actually represents £214.40. $MyNumber.precision(2) will return 214.40 but be careful about under-the-hood number/string coercion such as can happen in contexts like $DisplayExpression.

    $MyOtherNumber = $MyNumber.precision(2); gives 214.4
    $MyString = $MyNumber.precision(2); gives "214.40"

    In a $DisplayExpression:

    $MyNumber.precision(2); gives "214.40"
    $Name+" : "+$MyNumber.precision(2); gives "214.40"
    $Name+ " : " + sum(children,$MyNumber).precision(2); 

    It may still be easier to use format() as no extra parentheses are required:

    $Name+ " : " + format(sum(children,$MyNumber),2); 
    Number.round()

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

     Function  [other Function type actions]

     Item  [operators of similar scope]

     Mathematical  [other Mathematical operators]

     Number [about Number data type]

     v9.5.2

     Baseline

     As at baseline


    Syntax note: Operators without any defined mandatory arguments may omit their empty closing parentheses


    Number.round()

    Number.round() rounds the value of its chained source number argument to the nearest integer. A partial integer over .50 always round up, everything else rounds down.

    See round() for a fuller explanation of the logic and possible usage.

    See also Number.ceil() and Number.floor().

    originalLinkedFrom(scope[, linkTypeStr])

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

    Operator Uses Scoped Arguments: 

    Operator Has Optional Arguments: 

     Function  [other Function type actions]

     Item  [operators of similar scope]

     Query Boolean  [other Query Boolean operators]

     boolean test

     v8.0.0

     Baseline

     As at baseline

     [More on scoped arguments in Action Code]

     [More on optional operator arguments]


    originalLinkedFrom(scope[,linkTypeStr])

    A test for inbound links. This returns true if the current note corresponding to this is linked from the designated scope, i.e. an item or group of items (defining scope); this is optionally filtered to only links of type linkTypeStr. Put another way, "Does an inbound link exist to the original current note from item(s)?". This is especially useful in agents, where this is bound to an alias owned by the agent but the user is interested in links to the original note.

    This is effectively only a query term, it returns a Boolean. If you are trying to collect data about the linked note(s), use links() instead.

    Ways to define item. The item argument must be quoted unless an attribute reference, e.g. "Some note" vs. $MyString.

    Ways to define group. In group scope, a wildcard "*" designator matches all notes and replaces the normal "all" group designator.

    Links of type 'prototype' are ignored. If using linkType, you must use the value "*untitled" to match an 'untitled' type link (rather than "" or "untitled").

    Thus, to test if any original note using the 'Event' prototype has an inbound link of the 'untitled' link type the agent query would be:

    $Prototype=="Event" & originalLinkedFrom("*", "*untitled"); 

    The logical opposite of this test is originalLinkedTo().

    originalLinkedTo(scope[, linkTypeStr])

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

    Operator Uses Scoped Arguments: 

    Operator Has Optional Arguments: 

     Function  [other Function type actions]

     Item  [operators of similar scope]

     Query Boolean  [other Query Boolean operators]

     boolean test

     v8.0.0

     Baseline

     As at baseline

     [More on scoped arguments in Action Code]

     [More on optional operator arguments]


    originalLinkedTo(scope[,linkTypeStr])

    A test for outbound links. This returns true if the current note corresponding to this is linked from the designated scope, i.e. an item or group of items (defining scope); this is optionally filtered to only links of type linkTypeStr. Put another way, "Does an outbound link exist from the original current note to item(s)?". This is especially useful in agents, where this is bound to an alias owned by the agent but the user is interested in links to the original note.

    This is effectively only a query term, it returns a Boolean. If you are trying to collect data about the linked note(s), use links() instead.

    Ways to define item. The item argument must be quoted unless an attribute reference, e.g. "Some note" vs. $MyString.

    Ways to define group. In group scope, a wildcard "*" designator matches all notes and replaces the normal "all" group designator.

    Links of type 'prototype' are ignored. If using linkType, you must use the value "*untitled" to match an 'untitled' type link (rather than "" or "untitled").

    Thus, to test if any original note using the 'Event' prototype has an outbound link of the 'untitled' link type the agent query would be:

    $Prototype=="Event" & originalLinkedTo("*", "*untitled"); 

    The logical opposite of this test is originalLinkedFrom().

    paste()

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

     Function  [other Function type actions]

     Document  [operators of similar scope]

     Data manipulation  [other Data manipulation operators]

     String [about String data type]

     v11.5.0

     11.5.0

     As at baseline


    Syntax note: Operators without any defined mandatory arguments may omit their empty closing parentheses


    paste()

    The operator paste() returns the String contents of the OS' clipboard.

    For example:

    $MyString = paste();
    play(soundNameStr)

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

     Function  [other Function type actions]

     Item  [operators of similar scope]

     Data manipulation  [other Data manipulation operators]

     success boolean

     v7.0.0

     Baseline

     As at baseline


    play(soundNameStr)

    This causes the stated OS alert sound to be played, the sound name being supplied as soundNameStr. To play the default error sound:

    play("Basso"); 

    The soundNameStr name is case-sensitive.

    pow(sourceNum, powerNum)

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

     Function  [other Function type actions]

     Item  [operators of similar scope]

     Mathematical  [other Mathematical operators]

     Number [about Number data type]

     v5.10.0

     Baseline

     As at baseline


    pow(sourceNum, powerNum)

    pow() returns the sourceNum raised to the powerNum.

    $MyNumber = pow(3,4); 

    returns 81.

    radians(degreesNum)

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

     Function  [other Function type actions]

     Item  [operators of similar scope]

     Mathematical  [other Mathematical operators]

     Number [about Number data type]

     v4.0.0

     Baseline

     As at baseline


    radians(degreesNum)

    radians() converts its degreesNum, in degrees, to radians.

    See also degrees() which converts an angle in radians to degrees.

    $MyNumber = radians(90); 

    returns '1.570796327' for an input of 90.

    rand([maxNumber])

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

    Operator Has Optional Arguments: 

     Function  [other Function type actions]

     Item  [operators of similar scope]

     Mathematical  [other Mathematical operators]

     Number [about Number data type]

     v4.0.0

     Baseline

     9.5.2

     [More on optional operator arguments]


    Syntax note: Operators without any defined mandatory arguments may omit their empty closing parentheses


    rand([maxNumber])

    rand()

    rand

    rand() returns a pseudo-random 3-digit decimal number between 0 and 1, e.g. 0.307. No argument is required.

    rand([maxNumber])

    Supplying an optional argument maxNumber, which must be an integer, returns a random integer between 0 and maxNumber-1. This can be useful when wanting random list items, noting that list items are addressed using zero-based integers.

    N.B. if working with list-based items, consider the list.randomItem() operator, which abstracts away the need to know the size of the list. Essentially it encapsulates calling list.at(rand(list.count)), so much easier to write/use

    Getting 1-based ranges vs. zero-based ranges of values

    Consider the original round() method:

    $MyNumber=round(rand()*10); 

    $MyNumber will be set to one of eleven integers in the range 0 through to 10. But, what if the '10' argument about is actually a child count:

    $MyNumber=round(rand()*$ChildCount); 

    If the $ChildCount was 10 and $MyNumber were used to fetch a random child using $SiblingOrder($MyNum) the process would fail if $MyNumber were zero as $SiblingOrder numbers from 1. Indeed, in this case the need is for ten integers, one through to ten.

    Previously, 1-based range can be achieved:

    $MyNumber=round(rand()*(10-1))+1; 
    $MyNumber=round(rand()*($ChildCount-1))+1; 

    If the main input is 10, by subtracting 1 the process returns a randomised integer in in the range 0-9 (ten numbers) and then adding back 1 shifts the value range to 1-10.

    Using the newer rand(maxNumber) method the above becomes:

    $MyNumber=round(rand($ChildCount-1))+1; 

    This is why the list.randomItem() may be an easier clear approach.

    regular expression

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

       [other type actions]

       [operators of similar scope]

       [other operators]

     

     v

     

     As at baseline


    Syntax note: Operators without any defined mandatory arguments may omit their empty closing parentheses


    regular expression

    require(featureName)

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

     Function  [other Function type actions]

     Document  [operators of similar scope]

     Document configuration  [other Document configuration operators]

     success boolean

     v9.6.0

     Baseline

     As at baseline


    require(featureName)

    The require() operator adds the /Hints container and its subsidiary containers. It is equivalent to selecting Built In Hints from the File menu. If any of the containers already exists, that container is left unchanged. For example:

    require("Hints"); 

    featureName is a mandatory argument. It is a literal string and case-sensitive.

    "Hints" is currently the only featureName value recognised by require(). But, this method allows for other values to be added in the future as need arises.

    require() accepts four case-sensitive arguments:

    • require("Templates") adds the built-in configuration /Templates container. It is equivalent to the container created when first adding a built-in template from the File menu.
    • require("Prototypes") adds the /Prototypes container. It is equivalent to the container created when first adding a built-in prototype from the File menu.
    • require("Preview") displays the text pane sub-tab selector above the text pane (the new document default is to hide the selector).
    • require("NoPreview") hides the text pane selector, i.e. the reverse of the above and the default for a new TBX document.
    return

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

     Statement  [other Statement type actions]

     Document  [operators of similar scope]

     Data manipulation  [other Data manipulation operators]

     declaration

     v9.1.0

     Baseline

     As at baseline


    return

    return() never use trailing parentheses with this operator!

    The return statement is only used inside a function, and indicates the value to be passed back to the code calling the function at which point the function stops. Atypically, trailing empty parentheses must not used with return. The value passed by return is defined by the rest of code line following the return statement

    See further explanation of the use of return within functions, including how the returned value is coded.

    rgb(redNum, greenNum, blueNum)

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

     Function  [other Function type actions]

     Item  [operators of similar scope]

     Color  [other Color operators]

     String [about String data type]

     v4.0.0

     Baseline

     As at baseline


    rgb(redNum, greenNum, blueNum)

    Creates a Color type: its arguments are integers ranging from 0 to 255 or an action code expression or attribute reference resolving to a number in this range. The value set is in hex form. For example:

    $MyColor = rgb(255,0,0); sets a value of "#ff0000", i.e. bright red

    The individual channels of an RGB colour can be set or read using the '.red', '.green' and '.blue' Color-type data operators.

    Setting named colours

    hsv() and rgb() can be used in the Colors Inspector.

    round(sourceNum)

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

    Operator Has Newer Dot-Operator Variant: 

     Function  [other Function type actions]

     Item  [operators of similar scope]

     Mathematical  [other Mathematical operators]

     Number [about Number data type]

     v4.0.0

     Baseline

     As at baseline

    Yes


    round(sourceNum)

    round() rounds the value of its sourceNum argument to the nearest integer. Note that there is now a dot-operator version (with the same behaviour) Number.round().

    The Number.format, Number.precision and format() functions all round numbers in this manner when shortening numbers during formatting. A partial integer over .50 always round up, everything else rounds down. Thus:

    $MyNumber = round(4.0); gives 4
    $MyNumber = round(4.2); gives 4
    $MyNumber = round(4.5); gives 5
    $MyNumber = round(4.7); gives 5

    The round function with work on string literal or String attribute values that are just numbers:

    $MyNumber = round("4.2"); gives 4
    $MyNumber = round("4.7"); gives 5
    $MyString = round(4.2); gives "4"
    $MyString = round(4.7); gives "5"
    $MyString = round("4.2"); gives "4"
    $MyString = round("4.7"); gives "5"

    There are also functions to always force rounding upwards (ceiling)—see ceil(), or to force rounding downwards (floor)—see floor().

    For a practical example, assume you would like to round you calculation (upward) to the nearest 100, so if the calculation output is 167 it should be 200, for a result of 540 a result of 600, and so on. This can be done like so:

    $MyNumber = 100*ceil($MyNumber/100); 

    whereas if you used round(), as in:

    $MyNumber = 100*round($MyNumber/100); 

    the result would vary depending on whether $MyNumber started above or below the nearest 50. An opposite of the first example, i.e. where everything rounds downwards to the nearest 100 can be done using floor():

    $MyNumber = 100*floor($MyNumber/100); 
    runCommand(commandStr[, inputsStr, dirStr])

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

    Operator Uses Regular Expressions: 

    Operator Has Optional Arguments: 

     Function  [other Function type actions]

     Item  [operators of similar scope]

     Data manipulation  [other Data manipulation operators]

     source context dependent

     v4.0.0

     Baseline

     As at baseline

     [More on regular expressions in Tinderbox]

     [More on optional operator arguments]


    runCommand(commandStr, inputStr)

    runCommand(commandStr, inputStr, dirStr) /runCommand(commandStr, , dirStr)

    The operator, runCommand(), lets rules and actions use the command line with an assumed working directory of the users OS home folder: see below for using dirStr for setting a different context of execution. The full detail of command line is out of scope for aTbRef and should be researched online. For novices, a good approach is to make a command line work in the macOS Terminal and only then try to use it via runCommand(). Similarly, leave customising the input via attribute/variable values until after a fixed string is working as this makes it much easier to troubleshoot the correct issue.

    Understanding the latter can help avoid trying to echo data into a command within the 'commandStr' string. See the 'quotify' example further below.

    runCommand(commandStr)

    The operator passes commandStr to the OS's Unix shell. The new shell processes commandStr. The process's standard output (stdout) is returned as the result of calling runCommand(). However, there is no requirement for a left-side argument if the output of runCommand() is needed, e.g. if it is just a true/false success/fail message.

    For example, to set the $Text of a note to a listing of all files/folders in the users home directory ~, run this code as a stamp:

    $Text = runCommand("ls -a"); 

    Whereas a stamp:

    runCommand("ls -a"); 

    would run the same code but the listing would not be used. Not useful in this example but if the need it just to run a script where the reult is not of interest, runCommand() can called on its own.

    runCommand(commandStr, inputStr)

    The operator passes commandStr to the OS's Unix shell. The new shell process receives inputsStr, if any, as its standard input stdin. The process's standard output (stdout) is returned as the result of calling runCommand(). The above syntax, in one-line command line usage, can also be thought of as: runCommand(command, stdIn).

    For example, the wc (word count) command can take a file or literal string as an input. On the command line, an echo command would be needed to pipe the literal string to wc, like so:

    echo "hello world" | wc -w 

    to get the result '2' (two words in the input string) in Terminal. To do this via runCommand():

    runCommand("wc -w","hello world"); 

    But, you don't see the returned value unless you pass the output of the command to something. a number is expected here so $MyNumber is sensible start:

    $MyNumber = runCommand("wc -w","hello world"); 

    and $MyNumber will now have the value '2'.

    Or, if using attributes or variables to pass in the data:

    	var:string vCmd = "wc -w";
    	var:string vArgs= $MyString; // which has the text whose word count we want
    	$MyNumber = runCommand(vCmd, vArgs);

    Whether the desired command line tool accepts inputs on stdIn is something the user needs to understand before using this command.

    IMPORTANT: Note that if using inputsStr, to pass arguments otherwise normally passed as part of commandStr, it is necessary to prefix the command used in commandStr with 'xargs' so that the arguments passed via stdin are correctly handled. Thus if using the command "mv" in commandStr with arguments in inputStr, the commandStr needs to be "xargs mv". This is shown in examples further below under heading "Working around using literal strings as inputs".

    Setting the working directory using dirStr

    runCommand(commandStr, inputStr, dirStr)

    Where is the working directory location assumed for executing scripts?

    If the optional dirStr is specified as a POSIX path, it sets the working directory in which commandStr is executed. Otherwise, by default, the working directory is the user's home folder , i.e. ~ or /Users/[shortusername] or in full form.

    If using dirStr, an inputStr must be provided even if only an empty string: runCommand(commandStr, "", dirStr).

    dirStr can be passed either as a full path from drive root or using the tilde (~) notation. dirStr should not include a forward slash at the end: e.g. "~/test" not "~/test/". The last part of the supplied path should be the folder which is to be the context of execution. Thus "~/test" implies a folder test that is a child folder of the users home folder.

    Working around using literal strings as inputs

    Any or all of commandStr, inputsStr, or dirStr may use attribute or variable values in place of literal strings. Thus:

    runCommand("xargs mv", '"x/tb 1.png" "y/tb 1.png"', "~/test") 

    will move file 'tb 1.png' from sub-folder 'x' at path '~/test' to sub-folder 'y'. (Note: the source and target paths need quoting because the file 'tb 1.png' has a space in its name and the paths would otherwise be mis-parsed by the shell. If the various strings.). Placing the start and end relative paths into $SourcePath and $TargetPath, the command above could also be written clearly/verbosely as:

    	var:string vCmd = "mv";
    	var:string vCmd += '"'+$SourcePath+'" "'+$TargetPath+'"';
    	vFolder = "~/test";
    	runCommand(vCmd, "", vFolder);

    or, the same but passing some of the arguments as inputs using the xargs method:

    	var:string vCmd = "xargs mv";
    	var:string vArgs = '"'+$SourcePath+'" "'+$TargetPath+'"';
    	vFolder = "~/test";
    	runCommand(vCmd, vArgs, vFolder);

    Further examples

    If a note called "Jane Doe" is dropped on a container with this OnAdd action:

    $MyResult = runCommand("sendmail -f "+$Email+" "+$Email(parent), "Subject:"+$Name+"\nHello\n.") 

    This assumes both dropped and container notes have a valid email address in Email. If so, Jane Doe will get an email with subject line "Jane Doe" and body text "Hello"; the email will be from the dropped note's $Email address and to the container's $Email address. In the above example:

    commandStr: sendmail - f jade@doe.com someone@other.com' 
    inputsStr (i.e. via stdin): "Subject: Jane Doe\nHello\n." 

    User attribute 'MyResult' will receive any message back from standard output.

    The runCommand() operator does not require a left-side to the action where the result of the command line is not needed by Tinderbox. Thus the same example as above can run as:

    runCommand("sendmail -f "+$Email+" "+$Email(parent), "Subject:"+$Name+"\nHello\n.") 

    Bear in mind that in this latter case there is no way of knowing if the command executed successfully.

    To use external commands like above you may need to check the encoding of the strings you extract from your TBX attributes. Do not forget to allow for characters like spaces/quotes/apostrophes in attribute values; these will invariably need escaping for safe use in a command line using operators like urlEncode():

    $MyResult=runCommand("/usr/bin/curl -d 'status="+urlEncode($Name)+"' -u myusername:mypassword https://twitter.com/statuses/update.atom"); 

    In the above, if the value of $Name were "Mark's project", the use of urlEncode() will ensure the string passed to the command line is actually "Mark%27s%20project".

    exportedString() can also help with ensuring the necessary encoding, allowing a template to be used to help with formatting the string passed into the command.

    Exactly where you do/do not need to encode attribute values will depend on the syntax of the particular operation you are performing.

    To help get around issues of quoting, a note's text (or other string attribute) can be used for either or both arguments. Consider a note called 'quotify' holding this command line:

    sed 's:"\([^"]*\)":“\1”:g' 

    A stamp might then hold this code:

    $Text = runCommand($Text("quotify"),$Text); 

    This effectively adds a menu item to the Stamps to change ordinary double quotes to their 'smart form', allowing the process to be run once, on demand, avoiding repeat use every agent cycle as would happen if using a rule or agent action.

    Dealing with inline quote characters

    Because input arguments are parsed for regular expressions (by the OS, not Tinderbox), it may be possible to use the '\dnn' form described here to work around the lack of escaping from single double quotes within strings.

    Slow running target processes

    This operator was designed for rapid call+response, not as a call-and-wait process so should not be used for process that are slow to return data. There is no fixed timeout but it is probably c.30 seconds. Slow to complete processes should be set to write to disk and the data subsequently read from disk, using two separate actions.

    Debugging runCommand() calls

    See the dubugging section article on Use of the Command Line.

    Legacy only

    Using just command on its own is akin to using the back-tick action syntax.

    seconds(startDate, endDate)

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

     Function  [other Function type actions]

     Item  [operators of similar scope]

     Date-time  [other Date-time operators]

     Number [about Number data type]

     v6.0.0

     Baseline

     As at baseline


    seconds(startDate, endDate)

    returns the Number of whole seconds that elapsed between startDate and endDate. If endDate is earlier than startDate then the result is negative.

    If $DateA has time 12:30:00 and $DateB has time 12:31:30, then:

    $MyNumber = seconds($DateA,$DateB); 

    sets $MyNumber to 90.

    select()

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

     Function  [other Function type actions]

     Group  [operators of similar scope]

     Data manipulation  [other Data manipulation operators]

     n/a - no return

     v9.6.0

     Baseline

     As at baseline


    select()

    The select() operator de-selects all items currently selected in the document. The usage is simple:

    select(); 

    Because using select with arguments has a distinct and different function is it listed separately: select(scope).

    select(scope)

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

    Operator Uses Scoped Arguments: 

    Operator Has Newer Dot-Operator Variant: 

     Function  [other Function type actions]

     Group  [operators of similar scope]

     Data manipulation  [other Data manipulation operators]

     List [about List data type]

     v9.6.0

     Baseline

     As at baseline

     [More on scoped arguments in Action Code]

    Yes


    select(scope)

    The select(scope) operator allows the document's current (UI) focus to be shifted. The scope argument defines a list of one or more notes. The argument may be a literal string, or the value of an attribute or variable.

    select([/Note A;/Note B]); 
    select($MyList); 
    select(vItems); 

    This specialist operator assist in the scenario where, whilst running action code, it is necessary to change the selection such that the locus of 'this' changes. Some action code operators only address the currently selected item(s). The select(scope) operator allows the selection to be changed on the fly without the user having to do so via the UI.

    For list-based work consider list.select().

    Because using select without arguments has a distinct and different function is it listed separately: select().

    show(msgString[, backgroundColor[, colorString, [durationNum]]])

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

    Operator Has Optional Arguments: 

    Operator Has Newer Dot-Operator Variant: 

     Function  [other Function type actions]

     Item  [operators of similar scope]

     Data manipulation  [other Data manipulation operators]

     success boolean

     v9.5.2

     Baseline

     As at baseline

     [More on optional operator arguments]

    Yes


    show(msgString)

    show(msgString, backgroundColor)

    show(msgString, backgroundColor, colorString)

    show(message[ foreground, background, duration)

    The show(msgString) function allows a plain-text message to be shown in the front window's message placard. The source text, msgString, may be a literal string, variable or a String-type attribute value.

    show() allows 3 further optional arguments.

    The optional backgroundColor argument may be used on its own with or without the optional third colorString argument. But if the colorString argument is used, then the backgroundColor argument must be given as well. The same holds for the optional durationNum argument. If passed, durationNum specifies the number of seconds for which to display the message. Setting a duration can be useful if wanted to show a series of short messages, each in a discrete manner.

    The full features and limitations of messages sent to the placard are described separately under the Message placards article.

    The String.show() operator offers a dot-operator alternative.

    similarTo(item[, notesNum])

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

    Operator Has Optional Arguments: 

     Function  [other Function type actions]

     Item  [operators of similar scope]

     Query Boolean  [other Query Boolean operators]

     boolean test

     v4.6.0

     Baseline

     As at baseline

     [More on optional operator arguments]


    similarTo(item[,notesNum])

    Returns Boolean true if item is amongst the (optionally notesNum notes) most similar to the current note.

    The item argument must be quoted unless an attribute reference. Ways to define item.

    Similarity is based on several factors, including:

    • the text of the note
    • the note title
    • any text contained in user attributes

    In addition, weighting is applied for:

    • notes having the same prototype
    • notes having roughly similar amounts of text

    This data replicates that seen in the similar tab of Get Info and in the export code ^similarTo()^.

    Legacy issues

    This operator replaces the legacy #similarTo query operator and what in old version's agent query creation pop-ups and Find dialogs was listed as "is similar to".

    sin(sourceNum)

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

     Function  [other Function type actions]

     Item  [operators of similar scope]

     Mathematical  [other Mathematical operators]

     Number [about Number data type]

     v4.0.0

     Baseline

     As at baseline


    sin(sourceNum)

    sin() converts its sourceNum, in radians, to the sine of that value.

    $MyNumber = sin(3) 

    returns '0.1411200081' for an input of 3 radians.

    speak(MessageStr[, voiceNameStr])

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

    Operator Has Optional Arguments: 

    Operator Has Newer Dot-Operator Variant: 

     Function  [other Function type actions]

     Item  [operators of similar scope]

     Data manipulation  [other Data manipulation operators]

     success boolean

     v9.5.0

     Baseline

     As at baseline

     [More on optional operator arguments]

    Yes


    speak(MessageStr[, voiceNameStr])

    speaks a MessageStr string using Mac text-to-speech. If another string is being spoken, the new phrase is spoken after the current phrase is complete:

    speak("Hello"); 

    MessageStr can be a variable or attribute reference:

    speak($Text); 

    An optional second argument voiceNameStr identifies the voice the speech synthesiser should use. If the nominated voiceNameStr is not present no sound is played. The closing parentheses are only needed if the extra argument is being passed:

    speak($Text.,"Tessa"); 

    See also String.speak().

    sqrt(sourceNum)

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

     Function  [other Function type actions]

     Item  [operators of similar scope]

     Mathematical  [other Mathematical operators]

     Number [about Number data type]

     v4.0.0

     Baseline

     As at baseline


    sqrt(sourceNum)

    sqrt() computes the square root of its sourceNum.

    $MyNumber = sqrt(9); 

    sets $MyNumber to 3.

    stamp([scope, ]stampName)

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

    Operator Has Optional Arguments: 

     Function  [other Function type actions]

     Group  [operators of similar scope]

     Data manipulation  [other Data manipulation operators]

     success boolean

     v8.1.0

     Baseline

     9.0.0

     [More on optional operator arguments]


    stamp([scope, ]stampName)

    stamp(stampName)

    This operator applies the stamp stampName is applied to the this note, i.e. the current note. So:

    stamp("Do Stuff"); 

    runs the stamp called "Do Stuff" on the current note.

    stamp(scope, stampName)

    scope is an optional argument that can be a single note or a group or designator defined in any of the normal methods (literal, designator, action code expression).

    If a scope argument is supplied the stamp named stampName is applied discretely to each of scope items (defining scope). So:

    stamp("SomeNote","Do Stuff"); 

    runs the stamp called "Do Stuff" on the note with the unique $Name "Some Note". Or:

    stamp($MyList,"Do Stuff"); 

    runs the stamp called "Do Stuff" on every note described by an item in the list stored in the value of $MyList for this note.

    String.beginsWith(matchStr)

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

     Function  [other Function type actions]

     Item  [operators of similar scope]

     Data manipulation  [other Data manipulation operators]

     boolean test

     v6.4.0

     Baseline

     As at baseline


    String.beginsWith(matchStr)

    String.beginsWith() returns Boolean true if the chained string begins with the literal string matchStr. Note that matchStr cannot be a regular expression, only literal string values are allowed.

    For example, if $MyString is "I do not like green eggs and ham":

    $MyString.beginsWith("I do") returns true 
    $MyString.beginsWith("Hello") returns false 

    Also, with string literals:

    ("There are gentlemen now abed.").beginsWith("There are") returns true 
    ("There are gentlemen now abed.").beginsWith("Hello") returns false 

    This operator searches for literal strings, not regular expressions. Matches are case sensitive

    ("There are gentlemen now abed.").beginsWith("there are") returns false 

    See also String.endsWith(). If you need to search a String for a regular expression, use String.contains().

    String.capitalize()

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

     Function  [other Function type actions]

     Item  [operators of similar scope]

     Formatting  [other Formatting operators]

     String [about String data type]

     v5.9.0

     Baseline

     As at baseline


    Syntax note: Operators without any defined mandatory arguments may omit their empty closing parentheses


    String.capitalize()

    String.capitalize

    Returns the referenced string, transforming the initial letter of each word to a capital letter and leaving all other characters unchanged.

    The function can be chained both to string data and to string literals:

    $MyString.capitalize() 
    "my new title".capitalize() 

    The latter gives "My New Title".

    The trailing parentheses may be omitted:

    $MyString.capitalize 

    If 'title case' is required from a mixed case string, chain with .lowercase():

    $MyString = "my nEW title".lowercase.capitalize; 

    sets $MyString to "My New Title".

    Bear in mind the latter will not deal with all capital acronyms (UPS, UNHCR) or CamelCase words (AstroTurf, FedEx).

    Functionally equivalent to capitalize().

    The .capitalize() method may also be used on Lists or Sets. Consider the list [Ant;BEE;Cow] when stored in $MyList:

    $MyList = $MyList.capitalize; 

    … giving [Ant;Bee;Cow].

    String.captureJson()

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

     Function  [other Function type actions]

     Item  [operators of similar scope]

     Stream parsing  [other Stream parsing operators]

     String [about String data type]

     v9.1.0

     Baseline

     11.5.0


    Syntax note: Operators without any defined mandatory arguments may omit their empty closing parentheses


    String.captureJson()

    String.captureJson

    From v11.5.0, the .captureJson() operator is deprecated. That proved to be a wrong step; embedding json in $Text (or within other text) is not useful and better solutions are available.


    Attempts to parse the string as fully/partially JSON and fails if unsuccessful. The parsed JSON is saved as the current JSON (stream) object.

    Essentially, this re-scopes the current stream so that it contains only the contents of the first section of JSON detected within the original stream. The focus of the stream parsing is set to the beginning of the extracted JSON code.

    Only one JSON object may be current at any time. If the source stream contains multiple discrete JSON code sections, only the first is detected/used.

    To actually work with the JSON data's values, use JSON.json[] and its sibling operators.

    In the most likely scenario, working on $Text, .captureJson() is needed only if $Text contains both JSON and other text:

    $MyResult = $Text.captureJson().json["somekey"]; 

    But, if the whole of $Text is a single block of (complete) JSON, use .json[] directly. So:

    $MyResult = $Text.json["somekey"]; 

    Legacy usage

    Prior to v10.0.2, the operator used the casing .captureJSON(). This version is still silently supported (and is coloured in supported input boxes). However, .captureJson() is not the approved casing and existing code should be updated to this as legacy support may stop at any time.

    String.captureLine([targetAttributeStr])

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

    Operator Has Optional Arguments: 

     Function  [other Function type actions]

     Item  [operators of similar scope]

     Stream parsing  [other Stream parsing operators]

     String [about String data type]

     v9.1.0

     Baseline

     As at baseline

     [More on optional operator arguments]


    Syntax note: Operators without any defined mandatory arguments may omit their empty closing parentheses


    String.captureLine(targetAttributeStr)

    String.captureLine()

    String.captureLine

    Optionally stores the rest of the line (paragraph) in the specified targetAttributeStr, a quoted name of an attribute, and returns the string that follows this line and the String moves forwards to the end of the current line.

    If the targetAttributeStr is omitted the String is advanced to the next line without any data being saved.

    The value given for targetAttributeSt can be:

    • a quoted literal string, e.g. ("Text") for $Text.
    • an unquoted variable/loopVariable, e.g. (vString) for a variable 'vString'.

    For example, if the stream is three paragraphs "Goodbye cruel world.\nHello again.\nFinal text." (the \n is a line break):

    $MyString = $Text.captureLine("SomeAttribute").captureLine(vString); 

    results in attribute $SomeAttribute holding the value "Goodbye cruel world." and the variable vString holding the value "Hello again.". $MyString holds "Final text.", it being the remainder of the unconsumed stream.

    String.captureNumber([targetAttributeStr])

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

    Operator Has Optional Arguments: 

     Function  [other Function type actions]

     Item  [operators of similar scope]

     Stream parsing  [other Stream parsing operators]

     String [about String data type]

     v9.1.0

     Baseline

     As at baseline

     [More on optional operator arguments]


    Syntax note: Operators without any defined mandatory arguments may omit their empty closing parentheses


    String.captureNumber("targetAttribute")

    String.captureNumber()

    String.captureNumber

    Searches forward from the start of String and matches the a detected number up to the first non-number character, optionally storing that number in the attribute specified targetAttributeStr, a quoted name of an attribute. It then returns the string that follows that number (to any left side recipient) whilst the String is advanced to a position after the number. The operator fails if the match is empty or entirely white space, with no result.

    A number is assumed to be any character continuous sequence of one or more number characters between 0–9 (zero through nine). Formatted numbers will not be fully matched. Any further text after the number is ignored, both for the capture and advancing the String.

    If the targetAttributeStr is omitted the String is advanced to after the number without any data being saved.

    The value given for targetAttributeSt can be:

    • a quoted literal string, e.g. ("Text") for $Text.
    • an unquoted variable/loopVariable, e.g. (vString) for a variable 'vString'.

    For example, if the string is "1234 items":

    $Result = $Result=$Text.captureNumber("SomeAttribute");

    The value of $SomeAttribute is "1234" $Result holds " items". But if the stream is "1,234 items", $Result holds "1" and $SomeAttribute holds ",234 items" as the comma means the first detected number stops at '1'.

    String.captureRest([targetAttributeStr])

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

    Operator Has Optional Arguments: 

     Function  [other Function type actions]

     Item  [operators of similar scope]

     Stream parsing  [other Stream parsing operators]

     String [about String data type]

     v9.1.0

     Baseline

     As at baseline

     [More on optional operator arguments]


    Syntax note: Operators without any defined mandatory arguments may omit their empty closing parentheses


    String.captureRest(targetAttributeStr)

    String.captureRest()

    String.captureRest

    Stores all of the String from the current position to its end into the specified targetAttributeStr, which is a quoted name of an attribute, and returns an empty string.

    If the targetAttributeStr is omitted the String is advanced to the end so processing ceases.

    The value given for targetAttributeSt can be:

    • a quoted literal string, e.g. ("Text") for $Text.
    • an unquoted variable/loopVariable, e.g. (vString) for a variable 'vString'.

    For example, if the stream is "Goodbye cruel world.\nHello again.":

    vString = $Text.captureWord("SomeAttribute").captureRest(vRest); 

    results in attribute $SomeAttribute holding the value "Goodbye" and the variable vRest holding the value " cruel world.\nHello again".

    String.captureTo(matchStr[, targetAttributeStr])

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

    Operator Uses Regular Expressions: 

    Operator Has Optional Arguments: 

     Function  [other Function type actions]

     Item  [operators of similar scope]

     Stream parsing  [other Stream parsing operators]

     String [about String data type]

     v9.1.0

     Baseline

     As at baseline

     [More on regular expressions in Tinderbox]

     [More on optional operator arguments]


    String.captureTo(matchStr, targetAttributeStr)

    String.captureTo(matchStr)

    Stores the source text string up to, but not including, the designated literal matchStr into the specified targetAttributeStr, a quoted name of an attribute, and returns the string that follows matchStr. Note that matchStr is not a regular expression and can only be a literal string.

    If the targetAttributeStr is omitted the String is advanced to the end so processing ceases.

    The value given for targetAttributeSt can be:

    • a quoted literal string, e.g. ("Text") for $Text.
    • an unquoted variable/loopVariable, e.g. (vString) for a variable 'vString'.

    For example, if the stream is "Piglet, a friend of Pooh" and if wishing to capture only the name 'Piglet' into $SomeAttribute:

    $Result = $Text.captureTo(", ","SomeAttribute"); 

    Now, the value of $Result is "a friend of Pooh" and that of $SomeAttribute is "Piglet".

    String.captureToken([targetAttributeStr])

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

    Operator Has Optional Arguments: 

     Function  [other Function type actions]

     Item  [operators of similar scope]

     Stream parsing  [other Stream parsing operators]

     String [about String data type]

     v9.1.0

     Baseline

     As at baseline

     [More on optional operator arguments]


    Syntax note: Operators without any defined mandatory arguments may omit their empty closing parentheses


    String.captureToken(targetAttributeStr)

    String.captureToken()

    String.captureToken

    Captures a sequence of non-whitespace characters ('tokens'), the matched token string is passed to the specified targetAttributeStr, a quoted name of an attribute. The String stream is not advanced and any chained parsing continues from the same point. Punctuation (notably @) is part of a token but *not* part of a word.

    If the targetAttributeStr is omitted the String is advanced to the end so processing ceases.

    The value given for targetAttributeSt can be:

    • a quoted literal string, e.g. ("Text") for $Text.
    • an unquoted variable/loopVariable, e.g. (vString) for a variable 'vString'.

    For example, with a source a stream of "5. Hello world":

    vString = $Text.captureToken("SomeAttribute"); 

    results in attribute $SomeAttribute holding "5." and the variable vText hosing the value " Hello world"—note the space after the full stop is passed to the text stream as it is not a captured 'token'.

    Iif the source stream is "John Doe<johndoe@example.com>":

    vText = $Text.captureToken(vString) 

    results in variable vText holding " Doe<johndoe@example.com>" whilst variable vString holds "John".

    Thus .captureToken() might be considered akin to a more permissive form of String.captureWord() where the first 'word' in the stream contains non-normal word characters (as long as not a space).

    String.captureWord([targetAttributeStr])

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

    Operator Has Optional Arguments: 

     Function  [other Function type actions]

     Item  [operators of similar scope]

     Stream parsing  [other Stream parsing operators]

     String [about String data type]

     v9.1.0

     Baseline

     As at baseline

     [More on optional operator arguments]


    Syntax note: Operators without any defined mandatory arguments may omit their empty closing parentheses


    String.captureWord(targetAttributeStr)

    String.captureWord()

    String.captureWord

    Matches a word character at the start of String up to the first non-word character and stores the word in the specified targetAttributeStr, a quoted name of an attribute, and returns the string that follows this word. Fails if the string is empty or entirely white space.

    What constitutes a word? This operator captures text from the current position up to (but not including) the next character that is a digit, whitespace, or punctuation.

    If the targetAttributeStr is omitted the String is advanced to the end so processing ceases.

    The value given for targetAttributeSt can be:

    • a quoted literal string, e.g. ("Text") for $Text.
    • an unquoted variable/loopVariable, e.g. (vString) for a variable 'vString'.

    For example, if the stream is "Hello world":

    vString = $Text.captureWord("SomeAttribute"); 

    results in attribute $SomeAttribute holding the value "Hello" and the variable vText holding the value " world". If the stream does not start with a word, the operator fails. So, for a stream of "5. Hello world":

    vString = $Text.captureWord("SomeAttribute"); 

    results in attribute $SomeAttribute holding no value and the variable vString hosing the value "5. Hello world".

    String.captureXML()

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

     Operator  [other Operator type actions]

     Item  [operators of similar scope]

     Stream parsing  [other Stream parsing operators]

     String [about String data type]

     v9.1.0

     Baseline

     As at baseline


    String.captureXML()

    String.captureXML

    Attempts to parse the string as fully/partially XML and fails if unsuccessful. The parsed XML is saved as the current XML (stream) object.

    Essentially, this re-scopes the current stream so that it contains only the contents of the first section of XML detected within the original stream. The focus of the stream parsing is set to the beginning of the extracted XML code.

    Only one XML object may be current at any time. If the source stream contains multiple discrete XML code sections, only the first is detected/used.

    String.contains(regexStr)

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

    Operator Uses Regular Expressions: 

     Function  [other Function type actions]

     Item  [operators of similar scope]

     Query Boolean  [other Query Boolean operators]

     boolean test

     v5.7.0

     Baseline

     As at baseline

     [More on regular expressions in Tinderbox]


    String.contains(regexStr)

    This operator tests whether regular expression pattern regexStr matches the referenced string attribute's value in whole or part. Matches are always case-sensitive, unlike String.icontains(). The match gives a coerced boolean result: if regexStr is matched (literally or via regular expression) the function returns the match offset+1 in the source string, where offset is the distance from the start of the string to the start of the matched regular expression. No match, coerces to false. The +1 works around the fact the match is zero-based, so a match at position 0 (the start of the string), returns as 1 (0+1) and a value of 1 or more coerces to a boolean true. The boolean allows queries' normal true/false to evaluate as normal.

    If concerned over unwanted case-sensitivity, use String.icontains() which is always case-insensitive.

    regexStr is one of:

    • an unquoted action code expression, which includes just referencing a single attribute name e.g. MyString
    • a quoted string; quoted strings may be either:

    Important: do not omit the enclosing quotes for literal strings or regular expression. If omitted, Tinderbox will try to evaluate the string as an action code expression. Doing this may result in the expected result but this is actually a false positive. So, remember to enclose your regular expression or literals in quotes.

    For example:

    $MyString.contains("regex") 

    is true if $MyString matches regexStr's pattern. Other more complex usage:

    $MyString.contains($MyMatchText) 
    $MyString.contains($MyString(agent)) 
    $MyString(parent).contains("Tuesday") 
    "Any day like Saturday is good".contains($MyDay) 
    "Any day like Saturday is good".contains("Saturday") 

    Note that regular expression/literal strings are quoted whilst action code expressions are not.

    Getting the offset of the (first) regular expression match

    If the regular expression regexStr is found the function returns the match offset+1, where offset is the distance from the start of the string to the start of the matched regular expression. If there is more than one match, the offset of the first match is returned. Formerly, .contains() returned true if the regular expression was found. The '+1' modifier ensures that a match at position zero return a number higher than zero which would otherwise coerce tofalse. Since 1+offset is always true, no changes are required in existing documents but the function also gives usable offset information. Thus, if $MyString is "abcdefgehEi":

    $MyNumber = $MyString.contains("e"); returns 5.
    $MyNumber = $MyString.contains("E"); returns 10.
    $MyNumber = $MyString.contains("eh"); returns 8.

    Testing "does not contain"

    Use a ! prefix to the query argument:

    !$MyString.contains("Tuesday") 

    Use of parentheses around the negated query term, can assist Tinderbox's parsing:

    (!$MyString.contains("Tuesday")) 

    Using back-references

    In an agent query or if() conditions the function can return back-references to matches of (sub-)strings.

    String.contains() clears the list of back references from previous processes, so $0 and $1 correspond to its own results, not those from prior regular expression expressions.

    Dealing with inline quote characters

    Because regexStr is parsed for regular expressions, it may be possible to use the '\xNN' form described here to work around the lack of escaping from single double quotes within strings.

    Legacy format

    This operator is the replacement of the older form of AttributeName(regexStr) which is deprecated and should not be used in new work (legacy support may fall away). Apart from anything else, the current syntax should remove the confusion over whether/when to use the $ prefix with attribute names in queries.

    String.containsAnyOf(regexList)

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

    Operator Uses Regular Expressions: 

     Function  [other Function type actions]

     List  [operators of similar scope]

     Query Boolean  [other Query Boolean operators]

     boolean test

     v8.9.0

     Baseline

     As at baseline

     [More on regular expressions in Tinderbox]


    String.containsAnyOf(regexList)

    The operator .containsAnyOf(regexList) is true if any of the words in a set of words (i.e. list) is contained in the chained-to target string. As shown below, the list may have only one entry. The test is case-sensitive (previously it was case-insensitive). For example:

    $MyBoolean = $Text.containsAnyOf("emulate"); 

    Will be true if the tested note's $Text contains the word "emulate". A more applied example:

    $MyBoolean = $Text.containsAnyOf(wordsRelatedTo("emulate")); 

    Will be true if the tested note's $Text contains the word "aspire".

    regexList implies using a list of values (ideally with no dupes) that is parsed as a regular expression. This can be a literal list of 1 or more values—as in the example above, or an attribute reference holding a list of values, for instance:

    $MyBoolean = $Text.containsAnyOf($MySet); 

    It is important to note that .containsAnyOf() is always a case-insensitive test. Thus in the first example above, it will match "emulate" but not "Emulate" or any other case variant of the word.

    Although the examples above use whole words the list in regexList is actually processed assuming they are regular expressions (which may of course be literal strings). Thus in the first example above, it will match both "emulate" and "emulated" but not "emulating". The test value "emulate\b", expecting a word break after the final 'e' would this match "emulate" but not "emulated".

    For a case-insensitive version of this operator see String.icontainsAnyOf().

    If wishing to test a List or Set, chain to list.asString():

    $MyBoolean = $MyList.asString.containsAnyOf(wordsRelatedTo("emulate")); 
    String.countOccurrencesOf(literalStr)

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

     Function  [other Function type actions]

     Item  [operators of similar scope]

     Data manipulation  [other Data manipulation operators]

     Number [about Number data type]

     v6.5.0

     Baseline

     As at baseline


    String.countOccurrencesOf(literalStr)

    This function returns the Number of times that the literal argument 'literalStr' appears in the String. If $MyString contains the word "aardvark", then:

    $MyNumber = $MyString.countOccurrencesOf("a"); returns 3
    $MyNumber = $MyString.countOccurrencesOf("aa"); returns 1
    $MyNumber = $MyString.countOccurrencesOf("r"); returns 2

    literalStr is literal and must not be a regular expression. If the latter is needed use String.contains() or String.icontains().

    String.deleteCharacters(characterSet)

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

     Function  [other Function type actions]

     Item  [operators of similar scope]

     Data manipulation  [other Data manipulation operators]

     String [about String data type]

     v9.0.0

     Baseline

     As at baseline


    String.deleteCharacters(characterSet)

    Returns a copy of the string from which all instances of every discrete character in the quoted literal string-based set characterSet have been removed. For example:, if $MyString is "1Hello1 2world3";

    $MyStringA = $MyString.deleteCharacters("1234567890"); 

    would remove any digits from the target string, thus $MyStringA will be "Hello world", having removed two instances of '1', and a single instance of '2' and of '3'.

    But were $MyString "Hello world: 45";

    $MyStringA = $MyString.deleteCharacters("1234567890"); 

    the result would be "Hello world: ". Importantly, note the trailing space as only the digits (i.e. characters in characterSet) have been removed.

    String.eachLine(loopVar[:condition]){actionStr}

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

    Operator Has Optional Arguments: 

    Operator Has Conditional Arguments: 

    Operator Uses Loop Variable Argument: 


    String.eachLine(loopVar[:condition]){ actionStr }

    The .eachLine() operator, iterates through each line of a steam, where a line is one or more characters ending in a carriage return, line feed, unicode paragraph separator, or the end of the string (so in $Text, it means discrete paragraphs).

    Each line, in turn, is bound to a temporary variable loopVar, and the actionStr code is then evaluated. The name of the variable is set by the user when writing the code, i.e. it is whatever string is entered where loopVar is shown above. Something like 'aLine' might be a more useful variable name.

    If the optional condition is specified, only lines that satisfy the condition have their actionStr processed using the action.

    For example:

    $MyNumber=0;
    $Text.eachLine(aLine){
       $MyNumber=$MyNumber+1;
    };

    will set $MyNumber to the number of lines (paragraphs!) in the $Text of this note.

    $MyNumber=0;
    $Text.eachLine(aLine:aLine.contains("@")){
       $MyNumber=$MyNumber+1;
    };

    will set $MyNumber to the number of lines in the $Text that contain the "@" symbol.

    When parsing text paragraphs, this operator can substitute for the older method of chaining .paragraphList.each(){}.

    String.empty()

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

     Property  [other Property type actions]

     Item  [operators of similar scope]

     Non-query Boolean  [other Non-query Boolean operators]

     boolean test

     v5.7.0

     Baseline

     As at baseline


    Syntax note: Operators without any defined mandatory arguments may omit their empty closing parentheses


    String.empty()

    String.empty

    This returns a Boolean depending on whether the string is empty. If empty, the return value is true, if the attribute has content then false is returned.

    $MyString = ""; $MyBoolean = $MyString.empty; $MyBoolean is set to true.
    $MyString = "hello"; $MyBoolean = $MyString.empty; $MyBoolean is set to true.

    This operator can also be used on other attribute data types that are string-like, URL, File, Action, Color, etc., and which have no value at all by default. However, for a Number or Date, the default values of 0 or never, coerce to a literal string of "0" or "never" so the .empty() test does not work the same way. For the latter types, use the short Boolean test form, !AttributeName.

    String.endsWith(matchStr)

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

     Function  [other Function type actions]

     Item  [operators of similar scope]

     Data manipulation  [other Data manipulation operators]

     boolean test

     v6.4.0

     Baseline

     As at baseline


    String.endsWith(matchStr)

    String.endsWith() returns Boolean true if the chained string ends with the literal string matchStr. Note that matchStr cannot be a regular expression, only literal string values are allowed.

    For example, if $MyString is "I do not like green eggs and ham":

    $MyString.endsWith("ham") returns true
    $MyString.endsWith("eggs") returns false

    Also, with string literals:

    ("There are gentlemen now abed.").endsWith("abed") returns true 
    ("There are gentlemen now abed.").endsWith("night") returns false 

    This operator searches for literal strings, not regular expressions. Matches are case sensitive:

    ("There are gentlemen now abed.").endsWith("Abed") returns false 

    See also String.beginsWith(). If you need to search a String for a regular expression, use String.contains().

    String.expect(matchStr)

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

     Function  [other Function type actions]

     Item  [operators of similar scope]

     Stream parsing  [other Stream parsing operators]

     String [about String data type]

     v9.1.0

     Baseline

     As at baseline


    String.expect(matchStr)

    The operator tests if the String begins with the matchStr string with the following results:

    • success: operator returns the rest of string that follows matchStr.
    • failure: nothing is returned

    Note that matchStr is not a regular expression and can only be a literal string.

    For example:

    vText = $Text.expect("abc"); 

    Tests that the next characters in the stream read from $Text is the sequence abc, and advances the stream beyond "abc". Otherwise, it fails and the cursor does not advance. Either way, variable vText receives the resulting text stream as would any operator chained to .expect() unless a failure occurs in which case chained operators are not processed.

    The presumption for use of this operator is as an assist to help ensure to-be-captured content is correctly detected. Essentially, this is a 'if' style test: if the test is correct proceed, else the cursor remains where it is for any possible chained stream parsing operators.

    String.expectNumber()

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

     Function  [other Function type actions]

     Item  [operators of similar scope]

     Stream parsing  [other Stream parsing operators]

     String [about String data type]

     v9.1.0

     Baseline

     As at baseline


    Syntax note: Operators without any defined mandatory arguments may omit their empty closing parentheses


    String.expectNumber()

    String.expectNumber

    If the string begins with one or more contiguous character(s) that could be interpreted as a number, the String stream cursor skips to the end of that number sequence and parsing continues.

    For example:

    vText = $Text.expectNumber(); 

    Tests that the next characters in the stream read from $Text is a sequence of digits, and advances the stream past a continuous runs of digits. Otherwise, it fails and the cursor does not advance. Either way, variable vText receives the resulting text stream as would any operator chained to .expectNumber() unless a failure occurs in which case chained operators are not processed.

    If the input stream passes in "1234 items" the cursor advances past '1234' such that the remaining stream is " items".

    If the input stream passes in "1,234 items" the cursor advances past '1' such that the remaining stream is "234 items". Notice how number formatting delimiters like a comma (or other locale-specific delimiters) used in string representations of numbers may confuse this operator is used without care.

    The presumption for use of this operator is as an assist to help ensure to-be-captured content is correctly detected. Essentially, this is a 'if' style test: if the test is correct proceed, else the cursor remains where it is for any possible chained stream parsing operators.

    String.expectWhitespace()

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

     Function  [other Function type actions]

     Item  [operators of similar scope]

     Stream parsing  [other Stream parsing operators]

     String [about String data type]

     v9.1.0

     Baseline

     As at baseline


    Syntax note: Operators without any defined mandatory arguments may omit their empty closing parentheses


    String.expectWhitespace()

    String.expectWhitespace

    If the string begins the whitespace, skips the whitespace and succeeds. Otherwise, it fails.

    For example:

    vText = $Text.expectWhitespace(); 

    Tests that the next characters in the stream are non-word, and advances the stream beyond the detected whitespaces characters. Otherwise, it fails and the cursor does not advance. Either way, the variable vText receives the resulting text stream as would any operator chained to .expectWhitespace() unless a failure occurs in which case chained operators are not processed.

    If the stream passed in is " Hello world" (note the leading spaces) then the spaces are detected and the cursor returns "Hello world". But if the stream passed in is "Hello world" a word is detected and the cursor does not advance.

    The presumption for use of this operator is as an assist to help ensure to-be-captured content is correctly detected. Essentially, this is a 'if' style test: if the test is correct proceed, else the cursor remains where it is for any possible chained stream parsing operators.

    String.expectWord()

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

     Function  [other Function type actions]

     Item  [operators of similar scope]

     Stream parsing  [other Stream parsing operators]

     String [about String data type]

     v9.1.0

     Baseline

     As at baseline


    Syntax note: Operators without any defined mandatory arguments may omit their empty closing parentheses


    String.expectWord()

    String.expectWord

    If the string begins with one or more contiguous character(s) that could be interpreted as a word the String stream cursor skips to the end of that sequence and parsing continues.

    What constitutes a word? This operator captures text from the current position up to (but not including) the next character that is a digit, whitespace, or punctuation.

    For example:

    vText = $Text.expectWord(); 

    Tests that the next characters in the stream are not non-word, and advances the stream beyond the detected word. Otherwise, it fails and the cursor does not advance. Either way, variable vText receives the resulting text stream as would any operator chained to .expectWord() unless a failure occurs in which case chained operators are not processed.

    If the stream passed in is "Hello world" then 'Hello' is detected and the cursor returns " world" (note the leading space). But if the stream passed in is " Hello world" (note the leading space), no word is detected and the cursor does not advance.

    The presumption for use of this operator is as an assist to help ensure to-be-captured content is correctly detected. Essentially, this is a 'if' style test: if the test is correct proceed, else the cursor remains where it is for any possible chained stream parsing operators.

    String.extract(regexStr[, caseInsensitiveBln])

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

    Operator Uses Regular Expressions: 

    Operator Has Optional Arguments: 

     Function  [other Function type actions]

     Item  [operators of similar scope]

     Data manipulation  [other Data manipulation operators]

     String [about String data type]

     v9.1.0

     Baseline

     As at baseline

     [More on regular expressions in Tinderbox]

     [More on optional operator arguments]


    String.extract(regexStr)

    The operator returns the first matched subexpression of a quote-enclosed regular expression regexStr in the source String. If the regular expression has no subexpressions, the entire match is returned up to the end of the current line/paragraph, i.e. the first line break character encountered.

    For example, take a String which is the $Text "We are very tired, Harrison! #things #Memes #August":

    $MyString = $Text.extract("[A-Z][A-Za-z+]"); 

    this returns "We" as that is the first match (although there are others). This sort of use is the presumed most likely used of this operator.

    If we amend the regular expression

    $MyString = $Text.extract("#([A-Z][A-Za-z+])"); 

    it now returns "Memes" (the first hash tag starts with a lowercase letter does not match).

    If multiple matches are expected/wanted, see String.extractAll().

    String.extract(regexStr[, caseInsensitiveBln])

    String.extract() now accepts an optional boolean second argument caseInsensitiveBln. If that argument is true, the regexStr argument's regular expression search is case-insensitive. The default value is false respecting the pre-existing behaviour.

    String.extract() recognises ^ and $ regular expression codes as applying to the start and end of a line within a multiline string. Therefore, ^ and $ can apply to line boundaries within a multiline string.

    String.extractAll(regexStr[, caseInsensitiveBln])

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

    Operator Uses Regular Expressions: 

    Operator Has Optional Arguments: 

     Function  [other Function type actions]

     Item  [operators of similar scope]

     Data manipulation  [other Data manipulation operators]

     List [about List data type]

     v9.1.0

     Baseline

     As at baseline

     [More on regular expressions in Tinderbox]

     [More on optional operator arguments]


    String.extractAll(regexStr)

    The operator returns a (semi-colon delimited) list of all matches for a quote-enclosed regexStr found in the source String.

    For example:

    $MyList = $Text.extractAll("#[A-Za-z]+"); 

    would return a list of all discrete tag instances in the source String such as: "#Tinderbox;#Stuff;#Thing;#tinderbox;#Tinderbox;#Cars".

    To get a de-duped list, without the hashes we can chain other operators:

    $MyList = $Text.extractAll("#[A-Za-z]+").unique.replace("#",""); 

    That refines the returned list: "Cars;Stuff;Thing;Tinderbox;tinderbox". Note the extra operators also sort the list too.

    String.extractAll(regexStr[, caseInsensitiveBln])

    String.extractAll() now accepts an optional boolean second argument caseInsensitiveBln. If that argument is true, the regexStr argument's regular expression search is case-insensitive. The default value is false respecting the pre-existing behaviour.

    String.failed()

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

     Function  [other Function type actions]

     Item  [operators of similar scope]

     Stream parsing  [other Stream parsing operators]

     boolean test

     v9.1.0

     Baseline

     As at baseline


    Syntax note: Operators without any defined mandatory arguments may omit their empty closing parentheses


    String.failed()

    String.failed

    .failed tests for a failed Stream processing action String.try{}, including an explicit fail() call. It returns true if the current operation has failed, and false otherwise.

    When processing a string, it may be that the string is not what was expected. Thus the .failed operator raises a flag to say this process did not work.

    A .failed flag is reset to false when the current try{} expires, or when the current action is complete.

    For example, to test if a 'try' sequence has failed:

    	if ( $MyString.try{ … }.failed() ) {
    		$Color="bright red";
    	}
    
    String.find(matchStr)

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

     Function  [other Function type actions]

     Item  [operators of similar scope]

     Data manipulation  [other Data manipulation operators]

     Number [about Number data type]

     v6.5.0

     Baseline

     As at baseline


    String.find(matchStr)

    This operator returns a Number with the location of the first occurrence of a literal (not regular expression) substring matchStr within the source string. Thus, the operator searches for literal strings, not regular expressions. Matches are case sensitive. The offset is zero-based (position 1 is zero). If the string is not found, String.find(matchStr) returns -1.

    For example, if $MyString is "I do not like green eggs and ham":

    $MyNumber = $MyString.find("not"); returns 5
    $MyNumber = $MyString.find("blue"); returns -1 (not found in match string)
    $MyNumber = $MyString.find("Not"); returns -1 (not found, due to case-sensitive matching)
    String.following(matchStr)

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

     Function  [other Function type actions]

     Item  [operators of similar scope]

     Data manipulation  [other Data manipulation operators]

     String [about String data type]

     v9.0.0

     Baseline

     As at baseline


    String.following(matchStr)

    The .following( ) operator extracts information from one or more paragraphs of a string using a literal quoted string as the match (i.e. no regular expression support). If matchStr appears in a line, then whatever follows after the matchStr is the result. If matchStr appears in more than one line, the return value is a list of results.

    For example, if the text of a note is:

    	From: Mark
    	To: Clotilde
    	Subject: Mignardise

    Then:

    $MyString = $Text.following("To:"); 

    would return "Clotilde".

    $MyString = $Text.following(":"); 

    would return "Mark;Clotilde:Mignardise".

    In addition, the .following() operator binds any text that precedes the matchStr string to $0. If the matchStr appears several times, the first prefix is bound to $0, the second to $1, and so forth.

    The .following() operator's argument is interpreted as a sequence of characters, not a regular expression. If the flexibility of regular expressions is needed, use .find() instead.

    The .following() operator is useful for extracting formal and semi-formal data from free text and simple interchange formats like email and RIS.

    The .following() operator does not skip Tinderbox action code comments starting with // as this confounds working with URLs.

    String.highlights([aColor])

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

    Operator Has Optional Arguments: 

     Property  [other Property type actions]

     Item  [operators of similar scope]

     Data manipulation  [other Data manipulation operators]

     List [about List data type]

     v9.1.0

     Baseline

     As at baseline

     [More on optional operator arguments]


    Syntax note: Operators without any defined mandatory arguments may omit their empty closing parentheses


    String.highlights(aColor)

    String.highlights

    The operator returns a list of strings that have been highlighted in the $Text using Format ▸ Highlight.

    $MyList = $Text.highlights; 

    Note: aColor can only be the value of a named colour as listing in the menu Format ▸ Style ▸ Highlight.

    String.highlights(aColor)

    The result may be limited to strings highlighted in a specific colour by supplying aColor as an argument. aColor may be any of the currently supported highlight colours: "red", "green", "blue", "yellow", or "magenta". Thus:

    $MyList = $Text.highlights("red");

    would return only those highlighted $Text portions using a red highlight colour.

    String.icontains(regexStr)

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

    Operator Uses Regular Expressions: 

     Function  [other Function type actions]

     Item  [operators of similar scope]

     Query Boolean  [other Query Boolean operators]

     boolean test

     v5.7.1

     Baseline

     9.0.0

     [More on regular expressions in Tinderbox]


    String.icontains(regexStr)

    This operator tests whether regular expression pattern regexStr matches the referenced string attribute's value in whole or part. Matches are always case-insensitive, unlike String.contains(). The match gives a coerced boolean result: if regexStr is matched (literally or via a regular expression) the function returns the match offset+1 in the source string, where offset is the distance from the start of the string to the start of the matched regular expression. No match, coerces to false. The +1 works around the fact the match is zero-based, so a match at position 0 (the start of the string), returns as 1 (0+1) and a value of 1 or more coerces to a boolean true. The boolean allows queries' normal true/false to evaluate as normal.

    If needing case-sensitivity, use String.contains() which is always case-sensitive

    regexStr is one of:

    • an unquoted action code expression, which includes just referencing a single attribute name e.g. MyString
    • a quoted string; quoted strings may be either:

    Important: do not omit the enclosing quotes for literal strings or regular expression. If omitted, Tinderbox will try to evaluate the string as an action code expression. Doing this may result in the expected result but this is actually a false positive. So, remember to enclose your regular expression or literals in quotes.

    For example:

    $MyString.icontains("regex") 

    is true if $MyString matches the regexStr's pattern. Other more complex usage:

    $MyString.icontains($MyMatchText) 
    $MyString.icontains($MyString(agent)) 
    $MyString(parent).icontains("Tuesday") 
    "Any day like Saturday is good".icontains($MyDay) 
    "Any day like Saturday is good".icontains("Saturday") 

    Note that regular expression/literal strings are quoted whilst action code expressions are not.

    Getting the offset of the (first) regular expression match

    If the regular expression regexStr is found the function returns the match offset+1, where offset is the distance from the start of the string to the start of the matched regular expression. If there is more than one match, the offset of the first match is returned. Formerly, .contains() returned true if the regular expression was found. The '+1' modifier ensures that a match at position zero return a number higher than zero which would otherwise coerce to false. Since 1+offset is always true, no changes are required in existing documents but the function also gives usable offset information. Thus, if $MyString is "abcdefgehEi":

    $MyNumber = $MyString.icontains("e"); returns 5.
    $MyNumber = $MyString.icontains("E"); returns 5.
    $MyNumber = $MyString.icontains("eh"); returns 8.

    Testing "does not contain"

    Use a ! prefix to the query argument:

    !$MyString.icontains("Tuesday") 

    Use of parentheses around the negated query term, can assist Tinderbox's parsing:

    (!$MyString.icontains("Tuesday")) 

    Using back-references

    In an agent query or if() conditions the function can return back-references to matches of (sub-)strings.

    String.icontains() clears the list of back references from previous processes, so $0 and $1 correspond to its own results, not those from prior expressions.

    Dealing with inline quote characters

    Because regexStr is parsed for regular expressions, it may be possible to use the '\xNN' form described here to work around the lack of escaping from single double quotes within strings.

    Legacy format

    This operator is the replacement of the older form of AttributeName(regexStr) which is deprecated and should not be used in new work (legacy support may fall away). Apart from anything else, the current syntax should remove the confusion over whether/when to use the $ prefix with attribute names in queries.

    String.icontainsAnyOf(regexList)

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

    Operator Uses Regular Expressions: 

     Function  [other Function type actions]

     List  [operators of similar scope]

     Query Boolean  [other Query Boolean operators]

     boolean test

     v8.9.0

     Baseline

     As at baseline

     [More on regular expressions in Tinderbox]


    String.icontainsAnyOf(regexList")

    The operator .icontainsAnyOf("regexList) is true if any of the words in a set of words (i.e. list) is contained in the chained-to target string. As shown below, the list may have only one entry. The test is case-insensitive. For example:

    $MyBoolean = $Text.icontainsAnyOf("emulate"); 

    Will be true if the tested note's $Text contains the word "emulate". A more applied example:

    $MyBoolean = $Text.icontainsAnyOf(wordsRelatedTo("emulate")); 

    Will be true if the tested note's $Text contains the word "aspire".

    regexList implies using a list of values (ideally with no dupes). This can be a literal list of 1 or more values—as in the example above, or an attribute reference holding a list of values, for instance:

    $MyBoolean = $Text.icontainsAnyOf($MySet); 

    It is important to note that .containsAnyOf() is always a case-insensitive test. Thus in the first example above, it will match both "emulate" and "Emulate" or any other case variant of the word.

    Use of regular expressions

    Although the examples above use whole words the list in regexList is actually processed assuming they are regular expressions (which may of course be literal strings). Thus in the first example above, it will match both "emulate" and "emulated" but not "emulating". The test value "emulate\b", expecting a word break after the final 'e' would this match "emulate" but not "emulated".

    For a case-sensitive version of this operator see String.containsAnyOf().

    If wishing to test a List or Set, chain to list.asString():

    $MyBoolean = $MyList.asString.icontainsAnyOf(wordsRelatedTo("emulate")); 
    String.json()

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

     Function  [other Function type actions]

     Item  [operators of similar scope]

     Formatting  [other Formatting operators]

     String [about String data type]

     v5.7.0

     Baseline

     v9.1.0


    Syntax note: Operators without any defined mandatory arguments may omit their empty closing parentheses




    IMPORTANT: if looking for reading JSON see JSON.json[] and associated operators




    LEGACY ONLY

    Operator Deprecated in v9.1.0+ - use String.jsonEncode() instead

    String.json()

    String.json

    This operator returns a JSON-encoded UTF-8 version of a string attribute's value. The apostrophe (straight single quote), straight double quote, solidus (forward slash) and backslash characters are all escaped by a preceding backslash character.

    Now, use jsonEncode().

    String.jsonEncode()

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

     Function  [other Function type actions]

     Item  [operators of similar scope]

     Formatting  [other Formatting operators]

     String [about String data type]

     v9.1.0

     Baseline

     As at baseline


    Syntax note: Operators without any defined mandatory arguments may omit their empty closing parentheses


    String.jsonEncode()

    String.jsonEncode

    The .jsonEncode() operator returns a JSON-encoded UTF-8 version of the chained source String's value. Forbidden characters such as the apostrophe (straight single quote), straight double quote, solidus (forward slash) and backslash characters are all escaped by a preceding backslash character.

    The general expectation is String will be a quoted literal string or a String-type attribute or variable, e.g. $Text:

    var:string vEncoded = $Text.jsonEncode() 
    ^value("Apostrophe's are often wrongly used".jsonEncode())^ 

    This operator was formerly know as .json, and is effectively a replacement for that operator. The naming also better reflects the non dot-operator jsonEncode().

    Using the latter, the same outcome can be encoded as:

    var:string vEncoded = jsonEncode($Text) 
    ^value(jsonEncode("Apostrophe's are often wrongly used"))^ 

    For attributes, variables and very long literal string, the chained dot-operator seems more helpful when coding, whereas the older form may be more intuitive with short literal strings (as shown in the last example above.)

    String.lowercase()

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

     Function  [other Function type actions]

     Item  [operators of similar scope]

     Formatting  [other Formatting operators]

     String [about String data type]

     v5.9.0

     Baseline

     As at baseline


    Syntax note: Operators without any defined mandatory arguments may omit their empty closing parentheses


    String.lowercase()

    String.lowercase

    Returns the referenced string, transforming all uppercase letters to lowercase.

    The function can be chained to both string data and to string literals:

    $MyString.lowercase() 
    "My NEW Title".lowercase() 

    The latter results in "my new title".

    The trailing parentheses may be omitted:

    $MyString.lowercase 

    Functionally equivalent to lowercase().

    If $MyString is "Hello World":

    $MyString = $MyString.lowercase; 

    $MyString is set to "hello world".

    The .lowercase() method may also be used on Lists or Sets. Consider [Ant;BEE;Cow] stored in $MyList:

    $MyList = $MyList.lowercase; 

    … giving [ant;bee;cow].

    String.next()

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

     Function  [other Function type actions]

     Item  [operators of similar scope]

     Data manipulation  [other Data manipulation operators]

     String [about String data type]

     v9.1.0

     Baseline

     As at baseline


    Syntax note: Operators without any defined mandatory arguments may omit their empty closing parentheses


    String.next()

    String.next

    The operator .next generates convenient note names and other strings in a sequence. For example:

    $MyString = "footnote".next ; → "footnote 1"
    $MyString = "footnote 1".next; → "footnote 2"

    Specifically, .next searches a string for its last run of digits. If no digits are found, .next returns the string followed by " 1". Otherwise, the number is increments and placed in the same position in the string.

    $MyString = "Agent 007 (active)".next; → "Agent 008 (active)"
    String.nounList()

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

     Property  [other Property type actions]

     Item  [operators of similar scope]

     Data manipulation  [other Data manipulation operators]

     List [about List data type]

     v9.0.0

     Baseline

     As at baseline


    Syntax note: Operators without any defined mandatory arguments may omit their empty closing parentheses


    String.nounList()

    String.nounList

    This returns a list of each noun in the supplied string, excepting those recognised as pronouns and proper names. Note that the output list is all lowercase, regardless of source case. This operator requires running on macOS 10.14 and later.

    $MyList = "I am the very model of a modern Major-General.".nounList; 

    then MyList holds "model;major;general".

    String.paragraph(paraNum)

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

     Function  [other Function type actions]

     Item  [operators of similar scope]

     Data manipulation  [other Data manipulation operators]

     String [about String data type]

     v7.5.0

     Baseline

     As at baseline


    String.paragraph(paraNum)

    returns the text of the paraNum paragraph in the source string. paraNum is zero-based, i.e. the first paragraph is .paragraph(0); empty paragraphs are ignored. If the string does not contain paraNum paragraphs, the result is an empty string.

    If paraNum is negative, Tinderbox counts from the last paragraph. Thus, $Text.paragraph(-1) is the last paragraph in the text.

    For example:

    $MyString = $Text.paragraph(2); 

    sets $MyString the the contents of the third paragraph of $Text—recall at N is zero-based, so counting 0/1/2 means 2 is #3 in the sequence.

    String.paragraphCount()

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

     Property  [other Property type actions]

     Item  [operators of similar scope]

     Data manipulation  [other Data manipulation operators]

     Number [about Number data type]

     v7.5.0

     Baseline

     As at baseline


    Syntax note: Operators without any defined mandatory arguments may omit their empty closing parentheses


    String.paragraphCount()

    String.paragraphCount

    returns the Number of paragraphs in a string; empty paragraphs are ignored. Thus, $Text.paragraphCount is the number of paragraphs in the text of the currently selected note.

    $MyNumber = $Text.paragraphCount; 

    sets $MyNumber to the number of discrete paragraphs within $Text.

    String.paragraphList()

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

     Property  [other Property type actions]

     Item  [operators of similar scope]

     Data manipulation  [other Data manipulation operators]

     List [about List data type]

     v9.0.0

     Baseline

     As at baseline


    Syntax note: Operators without any defined mandatory arguments may omit their empty closing parentheses


    String.paragraphList()

    String.paragraphList

    The .paragraphList operator returns a list of paragraphs contained in a string. This operator requires running on macOS 10.14 and later. For example, to get a list of the discrete paragraphs in $Text:

    $MyList = $Text.paragraphList; 

    To set a string to the third paragraph of $Text (recall the .at(N) operator is zero-based):

    $MyString = $Text.paragraphList.at(2); 

    If wanting to iterate and test paragraphs, rather than chain $Text.paragraphList.each(){}, use the newer stream parsing method $Text.eachLine(){}. In both instances a line—or paragraph—is a substring—delimited by one of more successive line breaks.

    Getting a random paragraph

    To set a string to a random paragraph of $Text:

    $MyString = $Text.paragraphList.randomItem; 

    The latter uses list.randomItem and avoids using rand() and further manipulation of the returned number.

    Source paragraphs containing semicolons

    As .paragraphList returns a List, if any source paragraph containing a semicolon it will create more than one item in the returned list. In such circumstances, in may be better to use .eachLine() instead. Or, if encountered, a technique is to first sanitise the source by changing semicolons to another string and then back:

        var:string vSource = $Text.replace(";","@@@");
        $MyList = vSource.paragraphList;
        $MyString = $MyList.at(4)replace("@@@",";");
    String.paragraphs(parasNum)

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

     Function  [other Function type actions]

     Item  [operators of similar scope]

     Data manipulation  [other Data manipulation operators]

     String [about String data type]

     v5.8.0

     Baseline

     As at baseline


    String.paragraphs(parasNum)

    This function extracts the first parasNum paragraphs of the referenced string or String-type attribute. Examples:

    $MyString = "Paragraph 1\nParagraph 2".paragraphs(1); 

    In the example the "\n" simulates a line break. The code would set $MyString to the string "Paragraph 1". A more real example:

    $Text = $Text("Some note").paragraphs(2); 

    In the second example the current note's $Text would be set to the first 2 paragraphs of note "Some note".

    To get a single given paragraph of a multi line/paragraph string, such as $Text, see String.split() (beware of semicolons in the source string being misinterpreted as list item delimiters, as discussed in that article).

    This function respects existing rich text styling.

    To get all paragraphs as a list, e.g. in order to iterate against them using list.each(), then use string.split(), e.g.:

    $MyList = $Text.split("\n+"); 

    Or from a different note, e.g. 'another note':

    $MyList = $Text("another note").split("\n+"); 

    The \n+ implies to split on and remove sub-strings of one or more consecutive line breaks, thus avoiding the creation of unwanted creating blank list items in the output where there are several line breaks between paragraphs.

    Working with styled text

    This operator is capable of worthing with StyledString operators: StyledString.bold, StyledString.fontSize(), StyledString.italic and StyledString.strike.

    String.replace(regexMatchStr, replacementStr)

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

    Operator Uses Regular Expressions: 

     Function  [other Function type actions]

     Item  [operators of similar scope]

     Data manipulation  [other Data manipulation operators]

     String [about String data type]

     v5.7.0

     Baseline

     As at baseline

     [More on regular expressions in Tinderbox]


    String/List.replace(regexMatchStr, replacementStr)

    This operator allows simple text transformations without use of runCommand as was hitherto required.

    regexMatchStr and replacementStr are one of:

    • an action code expression (which includes just referencing a single attribute or variable name)
    • a quoted string, which may be either:
      • a literal string (i.e. actual text)
      • a regular expression ('regex') (only for regexMatchStr)

    $MyString.replace(regexMatchStr, replacementStr)

    In its simplest form, the operator creates a new string in which each occurrence of the regular expression patternn is replaced by the string replacement, i.e. global replacement. The source string is not changed by replace; if you wish to change the string itself, write back over the source attribute:

    $MyString = $MyString.replace("Hello","Goodbye"); 

    transforms a $MyString value of "Hello World" to "Goodbye World".

    Where regexMatchStr is a regular expression, and may contain wildcard characters such as "." (which matches any character) or "*" (which matches 0 or more occurrences of the preceding character). Thus ".*" matches zero or more instances of any character.

    Where parentheses in regexMatchStr create multiple back-references, replacementStr strings can include $1, $2, etc., to insert the relevant back-reference matched string ($1 through $9 allowed, and with $0 being the entire match).

    The replacement replacementStr preserves styles in the source String.

    Examples:

    $MyString.replace("Spenser","Spencer"); 

    changes all instance of "Spenser" to "Spencer".

    $MyString.replace("(a|e|i|o|u)",""); 

    deletes all vowels

    $MyString = "I do not like green eggs".replace("(green) (eggs)","$2 $1"); 

    returns "I do not like eggs green". Or:

    $Text=$Text.replace("From: (.+)@(.*)","——$1——\n$2"); 

    Will replace

    From: mark@example.com 

    with

    	——mark——
    	example.com

    Note that if the source text is part of a larger text, e.g. a whole email's plain text, consider using stream parsing methods.

    A replace action does not alter the original source

    Using .replace() does not affect the source string unless the replacement output is used to overwrite the original source value. Thus if $MyString holds "Hello World" then:

    $MyStringA = $MyString.replace(" World"); 

    $MyString remains "Hello Word" and $MyStringA has value "Hello". The source is unchanged. But, if we set the source to the output

    $MyString = $MyString.replace(" World"); 

    Now $MyString becomes "Hello" and the original value is lost (overwritten by the new one). This distinction is one to bear in mind when using .replace() with $Text.

    Using .replace() with $Text and formatting operators

    When applied to $Text, .replace() allows style operators to be applied to the replacement argument. For example,

    replace("^ from: .*",$0.bold) 

    will embolden all lines beginning with “From:”.

    If using style operators, do not place operator-modified back-reference within quotes. To re-use the example from above, consider $Text containing "I do not like green eggs and ham":

    $Text = "$Text.replace("(green) (eggs)",$2.bold+" "+ $1.strike); 

    gives "I do not like eggs green and ham".

    Multiple, but differing replacements

    Although multiple matches can be replaced with the same string, to replace multiple matches with different strings requires chained .replace() calls. Consider formatting a large number to Continental style. This means inserting spaces as the group delimiter and a comma for the decimal delimiter. Assume $MyNumber's value is 1234567.89:

    $MyString = $MyNumber.replace("(\d)(?=(?:\d{3})+([^\d]))","$1 ").replace("\.",","); 

    Now, 1234567.89 becomes "1 234 567,89".

    Some comma-delimited formats use straight double quotes for all/some values and demand that if this character appears in a value that is it escaped by doubling the character. If $Text is

    He shouted "Hello!" at the top of his voice. 

    Then it could be escaped for CSV export like so:

    …,"^value($Text.replace('"','""'))^",… 

    That exports:

    …,"He shouted ""Hello!"" at the top of his voice.",… 

    Note that in this instance using a single straight quote (instead of the more normal straight double quote) to contain the find and replace regular expressions works just fine. Also, there is no need to escape typographic double quotes, i.e. 'smart' or 'curly' quotes in this context.

    This function respects existing rich text styling.

    Short form for deletions

    If the replacement string is omitted, the one-argument form $MyString.replace(regex) returns a copy of $MyString in which every occurrence of the regular expression is removed.

    Trimming leading/trailing whitespace

    $MyString = $MyString.replace("^ +","").replace(" +$",""); 

    The ' +' means one or more space characters. The first replace finds such a sub-string immediately following the start of the whole string ^), whilst the second does the same for a sub-string immediately before the end of the string ($). If applied to multi-paragraph string, e.g. with line breaks such as in $Text, every paragraph is trimmed. Likely this is what is desired, but care is needed in more specialist situations. So, testing sample strings/texts is a good idea before changing actual data of value. If working with List or Sets a slightly different code is needed.

    Trimming leading/trailing quotes

    Because Tinderbox cannot escape quote characters (i.e. \" or \' do not escape the quote), use String.substr() to trim enclosing quotes on a string. Note that the latter, working on location in the string and not character type, cannot work on paragraphs within a string, such as in the example above.

    Dealing with inline quote characters

    Because regexMatchStr is parsed for regular expressions, it may be possible to use the '\xNN' form of character encoding described here to work around the lack of escaping from single double quotes within strings.

    Handling changes to $Text including link anchors

    When using .replace is used on a note's $Text, the replaced text also updates the position of pre-existing text link anchor text.

    Working with styled text

    This operator is capable of worthing with StyledString operators: StyledString.bold, StyledString.fontSize(), StyledString.italic and StyledString.strike.

    String.reverse()

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

     Function  [other Function type actions]

     Item  [operators of similar scope]

     Data manipulation  [other Data manipulation operators]

     String [about String data type]

     v5.8.0

     Baseline

     As at baseline


    Syntax note: Operators without any defined mandatory arguments may omit their empty closing parentheses


    String.reverse()

    String.reverse

    This function reverses the order of the referenced string or string literal. Trailing parentheses are optional for this function.

    $MyString = $MyString.reverse(); 
    $MyString = $MyString.reverse; 
    $MyString = "man bites dog".reverse(); 

    The latter gives "god setib nam" not "dog bites man". It is the order of characters that is reversed, not words within it.

    String.sentence([sentenceNum])

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

    Operator Has Optional Arguments: 

     Function  [other Function type actions]

     Item  [operators of similar scope]

     Data manipulation  [other Data manipulation operators]

     String [about String data type]

     v9.5.0

     Baseline

     As at baseline

     [More on optional operator arguments]


    Syntax note: Operators without any defined mandatory arguments may omit their empty closing parentheses


    String.sentence([sentenceNum])

    String.sentence()

    String.sentence

    The dot-operator .sentence(sentenceNum) extracts the sentenceNumth sentence from the source String, which most likely will be $Text. For example, if $Text contains the passage "Mr. Smith went to Washington. He shook hands. He kissed babies.", then"

    $MyString = $Text.sentence(0); 

    returns 'Mr. Smith went to Washington.' and

    $Text.sentence(2) 

    returns "He kissed babies."

    If the sentenceNum argument is omitted, the initial sentence is returned. This is sentence 0 (zero) as sentenceNum is a zero-based index.

    The definition of a 'sentence' is heuristic, and varies depending on the locale. In the example above, notice Tinderbox (in en-US locale) recognises that the period following "Mr." ends an abbreviation, not a sentence. The locale is derived from the users macOS settings but can also be set contextually using locale().

    String.sentences()

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

     Operator  [other Operator type actions]

     Item  [operators of similar scope]

     Data manipulation  [other Data manipulation operators]

     List [about List data type]

     v9.7.3

     Baseline

     As at baseline


    String.sentences()

    String.sentences() returns a list of sentences in the source String. Sentences are formed by natural language analysis of the text, which reduces the likelihood of errors cause by abbreviations, decimals, and quoted interjections.

    The operator takes no arguments so the trailing parentheses may be omitted if desired.

    Note:

    • any/every semicolon in the sentences are replaced by an underscore character (_). This is because list-based Tinderbox attributes use semicolons to delimit the list's items.
    • any leading/trailing whitespace (including tabs, line breaks, etc.) is trimmed from the sentence.

    Example:

    $MyList = $Text.sentences(); -
    String.show([backgroundColor[, colorString, [durationNum]]])

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

    Operator Has Optional Arguments: 

     Function  [other Function type actions]

     Item  [operators of similar scope]

     Data manipulation  [other Data manipulation operators]

     success boolean

     v9.5.2

     Baseline

     As at baseline

     [More on optional operator arguments]


    Syntax note: Operators without any defined mandatory arguments may omit their empty closing parentheses


    String.show([backgroundColor[,colorString]])

    String.show()

    String.show

    The String.show() function allows a plain-text message to be shown in the front window's message placard. The source text may be a literal string, variable or a String-type attribute value. The trailing parentheses are optional.

    String.show() allows a further three optional arguments.

    The optional backgroundColor argument may be used on its own with or without the optional third colorString argument. But if the colorString argument is used, then the backgroundColor argument must be given as well. The same holds for the optional durationNum argument. If passed, durationNum specifies the number of seconds for which to display the message. Setting a duration can be useful if wanted to show a series of short messages, each in a discrete manner.

    The features and limitations of messages sent to the placard are described separately under the Message placards article.

    The show(MsgString) operator offers a non-dot-operator alternative.

    From v10.1.1, .show() takes an additional optional Number argument duration:

    String.show(foreground, background, duration])

    If passed, duration specifies the number of seconds for which to display the message. If not specified, the display duration is 3 seconds. Setting a duration can be useful if wanted to show a series of short messages, each in a discrete manner.

    String.size()

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

     Property  [other Property type actions]

     Item  [operators of similar scope]

     Data manipulation  [other Data manipulation operators]

     Number [about Number data type]

     v5.7.0

     Baseline

     As at baseline


    Syntax note: Operators without any defined mandatory arguments may omit their empty closing parentheses


    String.size()

    String.size

    This returns the Number of characters in a string value. The returned number can be coerced to a string. Examples:

    $MyString = "hello world"; $MyNumber = $MyString.size; $MyStringA = $MyString.size; 

    The value of $MyNumber will be the number 11, $MyStringA will be the string "11".

    This operator can also be used on other attribute data types that are string-like, URL, File, etc.

    The 'size' of $Text is pre-computed and accessed via the read-only system attribute $TextLength.

    More detail on how character counts are made.

    String.skip(charsNum)

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

     Function  [other Function type actions]

     Item  [operators of similar scope]

     Stream parsing  [other Stream parsing operators]

     String [about String data type]

     v9.1.0

     Baseline

     As at baseline


    String.skip(charsNum)

    Moves the current stream position charsNum characters forward (right). A failure occurs if charsNum reaches past the end of the String stream.

    For example, for stream "It was the best of times, it was the worst of times":

    vText = $Text.skip(20); 

    Advances the cursor forward 20 characters, returning the stream "imes, it was the worst of times". Otherwise, if the end of the string is detected, it fails and the cursor does not advance. Either way, variable vText receives the resulting text stream as would any operator chained to .expect() unless a failure occurs in which case chained operators are not processed.

    The presumption for use of this operator is as an assist to help ensure to-be-captured content is correctly detected. Essentially, this is a 'if' style test: if the test is correct proceed, else the cursor remains where it is for any possible chained stream parsing operators.

    String.skipLine()

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

     Function  [other Function type actions]

     Item  [operators of similar scope]

     Stream parsing  [other Stream parsing operators]

     String [about String data type]

     v9.5.0

     Baseline

     As at baseline


    Syntax note: Operators without any defined mandatory arguments may omit their empty closing parentheses


    String.skipLine()

    String.skipLine

    The dot-operator String.skipLine skips forward to the next carriage return or to the end of the String stream. String.skipLine fails if the string is exhausted, i.e. the stream cursor remains where it was before the call.

    The sort of scenario with which this helps is where the desired line(s) has no identifiable label but is preceded by a separate area of the stream that can be found. Thus in a raw email transcript the content includes labels like 'To:' and 'Subject:' but has nothing for the main body copy, which simply forms all content after the Subject line.

    Most stream operators work up to the end of the current line but exclude the line break characters (\n) that separates each line. In the above scenario, where the needed line cannot be detected but the preceding line can be, .skipLine allows code like this:

    $Source.captureTo("Subject:").skipLine.captureRest("Text") 
    String.skipTo(matchStr)

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

    Operator Uses Regular Expressions: 

     Function  [other Function type actions]

     Item  [operators of similar scope]

     Stream parsing  [other Stream parsing operators]

     String [about String data type]

     v9.1.0

     Baseline

     As at baseline

     [More on regular expressions in Tinderbox]


    String.skipTo(matchStr)

    Looks for the matchStr (N.B. this is not a regular expression) in the source String stream. If not found, it returns nothing. If found, it returns the string that follows matchStr.

    For example:

    vText = $Text.skipTo("abc"); 

    Tests that the next characters in the stream read from $Text is the sequence abc, and advances the stream beyond "abc". Otherwise, it fails and the cursor does not advance. Either way, variable vText receives the resulting text stream as would any operator chained to .skipTo() unless a failure occurs in which case chained operators are not processed.

    The presumption for use of this operator is as an assist to help ensure to-be-captured content is correctly detected. Essentially, this is a 'if' style test: if the test is correct proceed, else the cursor remains where it is for any possible chained stream parsing operators.

    String.skipToNumber()

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

     Function  [other Function type actions]

     Item  [operators of similar scope]

     Stream parsing  [other Stream parsing operators]

     String [about String data type]

     v9.1.0

     Baseline

     As at baseline


    Syntax note: Operators without any defined mandatory arguments may omit their empty closing parentheses


    String.skipToNumber()

    String.skipToNumber

    Advances the String stream to the next number (i.e. one of more continuous number characters). A failure occurs if the stream is exhausted.

    For example:

    vText = $Text.skipToNumber(); 

    Tests that the next characters in the stream read from $Text is a sequence of digits, and advances the stream past a continuous runs of digits. Otherwise, it fails and the cursor does not advance. Either way, variable vText receives the resulting text stream (as would any operator chained to .skipToNumber() unless a failure occurs in which case chained operators are not processed.

    If the input stream passes in "1234 items" the cursor advances past '1234' such that the remaining stream is " items".

    If the input stream passes in "1,234 items" the cursor advances past '1' such that the remaining stream is "234 items". Notice how number formatting delimiters like a comma (or other locale-specific delimiters) used in string representations of numbers may confuse this operator is used without care.

    The presumption for use of this operator is as an assist to help ensure to-be-captured content is correctly detected. Essentially, this is a 'if' style test: if the test is correct proceed, else the cursor remains where it is for any possible chained stream parsing operators.

    String.skipWhitespace()

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

     Function  [other Function type actions]

     Item  [operators of similar scope]

     Stream parsing  [other Stream parsing operators]

     String [about String data type]

     v9.1.0

     Baseline

     As at baseline


    Syntax note: Operators without any defined mandatory arguments may omit their empty closing parentheses


    String.skipWhitespace()

    String.skipWhitespace

    Advances the String stream to the first character that is not whitespace. A failure occurs if the stream is exhausted.

    For example:

    vText = $Text.skipWhitespace(); 

    Tests that the next characters in the stream are non-word, and advances the stream beyond the detected whitespaces characters. Otherwise, it fails and the cursor does not advance. Either way, the variable vText receives the resulting text stream as would any operator chained to .skipWhitespace() unless a failure occurs in which case chained operators are not processed.

    If the stream passed in is " Hello world" (note the leading spaces) then the spaces are detected and the cursor returns "Hello world". But if the stream passed in is "Hello world" a word is detected and the cursor does not advance.

    The presumption for use of this operator is as an assist to help ensure to-be-captured content is correctly detected. Essentially, this is a 'if' style test: if the test is correct proceed, else the cursor remains where it is for any possible chained stream parsing operators.

    String.speak([voiceNameStr])

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

    Operator Has Optional Arguments: 

     Function  [other Function type actions]

     Item  [operators of similar scope]

     Data manipulation  [other Data manipulation operators]

     success boolean

     v6.0.0

     Baseline

     As at baseline

     [More on optional operator arguments]


    Syntax note: Operators without any defined mandatory arguments may omit their empty closing parentheses


    String.speak([voiceNameStr])

    speaks a string using Mac text-to-speech. If another string is being spoken, the new phrase is spoken after the current phrase is complete.

    $Text.speak(); 

    An optional second argument voiceNameStr identifies the voice the speech synthesiser should use. If the nominated voiceNameStr is not present no sound is played. The closing parentheses are only needed if the extra argument is being passed:

    $Text.speak("Tessa"); 

    Quoted literal strings can be chained to .speak():

    "Look on my Works, ye Mighty, and despair".speak(); 
    'Look on my Works, ye Mighty, and despair'.speak(); 

    See also speak().

    String.split(regexStr)

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

    Operator Uses Regular Expressions: 

     Function  [other Function type actions]

     Item  [operators of similar scope]

     Data manipulation  [other Data manipulation operators]

     List [about List data type]

     v5.7.1

     Baseline

     11.7.0

     [More on regular expressions in Tinderbox]


    String.split(regexStr)

    This operator splits a string into a List, as divided by instances of regular expression pattern regexStr in the original string. Source characters matched by regexStr are not passed to the list. The source string itself is not affected.

    regexStr is one of:

    • an action code expression (which includes just referencing a single attribute name')
    • a quoted string; quoted strings may be either:

    Useful regexStr values are:

    • "\W+". This splits the source at word boundaries removing spaces and punctuation.
    • "\n". This divides the string into discrete paragraphs, ignoring blank lines and/or lines/paragraphs with only spaces but no textual content.
    • "\.". This divides on sentences ending with a period. It will strip the terminating punctuation.
    • "[\.\?\!]". As above but the sentence may end with any of full stop, question mark or exclamation mark.

    The result of the operator is a List-type attribute value, i.e. the data should be passed to a list. Passing the output to a Set-type attribute will de-dupe any list values in the output with the first instance of any duplicates forming its set entry.

    For example:

    $MyList = "ant bee ant cow".split(" "); gives list [ant;bee;ant;cow]
    $MySet = "ant bee ant cow".split(" "); gives list [ant;bee;cow]
    $MyList = "ant, bee, cow".split("\W+ "); gives list [ant;bee;cow]
    $MyList = "ant, bee, cow".split(" "); gives list [ant,;bee,;cow]
    $MyList = $MyString.split($MyString(agent)); 
    $MyList = $MyString(parent).split("and"); 

    If the string, stored in $MyString, is multi-line:

    ant
    bee
    cow

    …then:

    $MyList = $MyString.split("\n"); 

    gives list [ant;bee;cow].

    This approach can be useful if trying to retrieve a specific paragraph of $Text, perhaps from notes exploded from a larger consistently formatted text source. To get a string holding just paragraph #3 of the source $Text (or other multi-line string data):

    $MyString = $Text.split("\n").at(2); 

    Do not overlook the fact that that List.at() is zero-based. That means the first list item is .at(0) and so the third list item is '2' and not '3' as might otherwise be assumed the last item is '-1':

    $MyString = $Text.split("\n").at(-1); 

    There is one limitation of this approach to working with $Text or multi-line strings. The issue is that blank lines or lines with only spaces, are ignored; lists do not hold 'empty' items. So if the string $MyString is multi-line and contains blank lines, like so:

    ant
      
    bee
    cow

    …then:

    $MyList = $MyString.split("\n"); 

    still gives [ant;bee;cow].

    It does not matter if the blank is just two successive line returns or actually contains some white space, no list item is created for it.

    Luckily there is a simple workaround is to seed empty lines with a single hyphen (or whatever placeholder you prefer, e.g. "N/A" or such). Thus:

    $MyList = $Text.replace("\n\n","\n-\n").split("\n"); 

    …now gives $MyList [ant;-;bee;cow] such that "bee" is still paragraph #3 of the new list, as in the original text. If you wanted to make a deliberate review of such data you might use a more distinctive marker string:

    $MyList = $Text.replace("\n\n","\n#####\n").split("\n"); 

    You could then query for $MyList.contains("#####").

    Dealing with inline quote characters

    Because regexStr is parsed for regular expressions, it may be possible to use the '\dnn' form described here to work around the lack of escaping from single double quotes within strings.

    Dealing with inline semi-colons

    As this function outputs a list, where values are semi-colon delimited, if the source string—such as $Text—has semicolons in it they act as extra (unexpected!) splits when viewing the outcome. To get around this, escape the semicolons on the fly:

    $MyList = $Text.replace(";","\\;").split("\n"); 

    However, the surviving inline semicolons in the resulting List items will get misread, when interrogating the List, as item delimiters. In such cases, first replace inline semicolons with another character(s) before using the split-generated list and then reverse the replacement before actual use of the text. For example:

        var:string vSource = $Text.replace(";","@@@");
        $MyList = vSource.paragraphList;
        $MyString = $MyList.at(4)replace("@@@",";");

    Semicolon issues

    From v11.7.0, if an element in the list returned by [String].split() contains a semicolon, that element will be enclosed in single quotes. This works around a longstanding problem when processing text that contains semicolons. A problem edge case remains because the result still fails if an element contains both a semicolon and a single quote.

    String.substr(startNum[, lengthNum])

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

    Operator Has Optional Arguments: 

     Function  [other Function type actions]

     Item  [operators of similar scope]

     Data manipulation  [other Data manipulation operators]

     String [about String data type]

     v5.7.0

     Baseline

     As at baseline

     [More on optional operator arguments]


    String.substr(startNum[, lengthNum])

    This operator allows extraction of a substring from a string attribute. The source string is not affected.

    $MyString.substr(startN) 

    returns the substring of $MyString beginning startNum characters from the beginning. The numbers for startN and lengthN are 0-based, i.e. zero is character position #1. A negative startNum value counts back from the end of the string .Negative values are 1-based, i.e. the -1 represents the last character in the string.

    In the examples below assume $MyString's value is "Hello World". Examples:

    $MyString = "abcde".substr(2); returns "cde"
    $MyString = "abcde".substr(-2); returns "de"
    $MyString = $MyString.substr(6); returns "World"

    If the string does not contain at least startNum characters, the empty string is returned.

    A second argument lengthNum specifies the length of the returned string. If unspecified, the entire remaining string is returned.

    $MyString = "abcde".substr(2,2); returns "cd"
    $MyString = "abcde".substr(-3,2); returns "cd"
    $MyString = $MyString.substr(0,5); returns "Hello"

    If the length of the substring is negative, it is treated as an offset from the end of the string.

    $MyString = "Hello".substr(1,-1); → "ell"

    Besides strings and string literals, this operator can also be used on other attribute data types that are string-like, URL, File, etc. Although the operator also works on lists/sets, the source data is all the values as a single semi-colon-joined string literal so there is less point in its use in this context.

    This function respects existing rich text styling.

    Incorrect argument values

    If .substr() is asked to address parts of the string before its start or after its end, .substr() returns the empty string. This can arise through poor selection of input argument values. For instance, if $MyString is 5 characters long, $MyString.substr(0-7) is impossible, so this returns an empty string.

    Trimming leading/trailing quotes

    See String.trim().

    Working with styled text

    This operator is capable of worthing with StyledString operators: StyledString.bold, StyledString.fontSize(), StyledString.italic and StyledString.strike.

    String.toNumber()

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

     Function  [other Function type actions]

     Item  [operators of similar scope]

     Data manipulation  [other Data manipulation operators]

     Number [about Number data type]

     v5.8.0

     Baseline

     As at baseline


    Syntax note: Operators without any defined mandatory arguments may omit their empty closing parentheses


    String.toNumber()

    String.toNumber

    Used for explicit coercion of numbers in strings to Number type data. Examples:

    $MyNumber = $MyString.toNumber; 
    $MyNumberA = "40".toNumber; 

    This can be useful if default type coercion is not working as expected.

    String.tr(inStr[, outStr])

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

    Operator Has Optional Arguments: 

     Function  [other Function type actions]

     Item  [operators of similar scope]

     Data manipulation  [other Data manipulation operators]

     String [about String data type]

     v5.7.0

     Baseline

     As at baseline

     [More on optional operator arguments]


    String.tr(inStr[, outStr])

    $MyString.tr(inStr, outStr)

    This operator allows simple single character string manipulation. It computes a new string, copying each character of $MyString but converting any characters in inStr to the corresponding characters in dataOut. For example:

    $MyString = $MyString.tr("a","A"); 

    returns a copy of MyString in which every "a" is converted to "A".

    Backslash characters must be quoted and escaped:

    $MyString = $MyString.tr("c","\\r"); 

    converts every "c" to a Macintosh newline characters (\r). Note the need in this context for an extra backslash escape (so Tinderbox knows the intended swap value is "\r" and not "r").

    Multiple characters can be replaced:

    $MyString = "Hello, world".tr("aeiou","AEIOU"); gives "HEllO, wOrld"

    Note that in the later example the number of characters in inStr and outStr must match and pairs must list in order, otherwise unmatched characters will act as for the syntax below.

    $MyString.tr(inStr)

    If outStr is omitted or left empty, any matches to inStr are deleted from the referenced string.

    $MyString = "Hello, world".tr("aeiou"); 

    gives "Hll, wrld"

    For further information, see the macOS man page for the UNIX tr command.

    Performance

    If using actions with a lot of .tr() calls, based on some testing in large complex docs, it may—counter-intuitively—be faster using .replace() instead.

    String.trim([filterStr])

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

    Operator Has Optional Arguments: 

     Function  [other Function type actions]

     Item  [operators of similar scope]

     Data manipulation  [other Data manipulation operators]

     String [about String data type]

     v9.0.0

     Baseline

     As at baseline

     [More on optional operator arguments]


    Syntax note: Operators without any defined mandatory arguments may omit their empty closing parentheses


    String.trim([filterStr])

    String.trim()

    String.trim

    The .trim operator removes unwanted characters from the start and end of a string. With no arguments, .trim() removes whitespace and end of line characters.

    "Hello world ".trim; → "Hello world"

    It may also be used with a literal string argument filterStr. The only accepted value for filterStr is "punctuation", in which case the operator also removes punctuation marks.

    "[tab] Hello world?! ".trim("punctuation") → "Hello world"

    The resulting string retains any stying in the source string.

    String.try{actionCode}[.thenTry{actionStr}]

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

    Operator Has Optional Arguments: 

     Function  [other Function type actions]

     Item  [operators of similar scope]

     Stream parsing  [other Stream parsing operators]

     boolean test

     v9.1.0

     Baseline

     As at baseline

     [More on optional operator arguments]


    String.try{ actionStr }[.thenTry{ actionStr }]

    This saves the value of a (String-type) attribute (the stream source) and evaluates .try{actionStr}. It the evaluation fails, the app restores the string and allows it to processed it a different way in the chained .thenTry{actionStr} operation. If all evaluations fail, the original value of String stream source is restored.

    A .try{} may be followed by one or more .thenTry{} clauses. If the original .try{} succeeds the evaluated result is returned and all subsequent .thenTry{} clauses are ignored. If the original .try{} fails, then each .thenTry{} is attempted in turn, until a result is returned. If all expression evaluations fail, the original value of String is returned.

    The current success/failure state can be tested using the .failed() operator.

    For example:

    $MyString.try{
       $MyString=$MyString.skipToWord("To:").captureWord;
    }.thenTry{
       fail(); //signal an explicit failure and return a 'false' value to a calling action
    };
    

    looks for strings such as "To:John Doe"

    If the string "To:" is not found, $MyString will be unchanged. If found, $MyString's value is set to the word that follows, up to the next whitespace character or the end of the string, i.e. "John".

    String.uppercase()

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

     Function  [other Function type actions]

     Item  [operators of similar scope]

     Formatting  [other Formatting operators]

     String [about String data type]

     v5.9.0

     Baseline

     As at baseline


    Syntax note: Operators without any defined mandatory arguments may omit their empty closing parentheses


    String.uppercase()

    String.uppercase

    Returns the referenced String, transforming all uppercase letters to lowercase.

    The function can be chained to both string data and to string literals:

    $MyString.uppercase() 
    "my new title".uppercase() 

    The latter gives "MY NEW TITLE".

    The trailing parentheses may be omitted:

    $MyString.uppercase 

    Functionally equivalent to uppercase().

    If $MyString is "hello world":

    $MyString = $MyString.uppercase; 

    $MyString is set to "HELLO WORLD".

    The .uppercase() method may also be used on Lists or Sets. Consider [Ant;BEE;Cow] stored in $MyList:

    $MyList = $MyList.uppercase; 

    … giving [ANT;BEE;COW].

    String.wordCount()

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

     Property  [other Property type actions]

     Item  [operators of similar scope]

     Data manipulation  [other Data manipulation operators]

     Number [about Number data type]

     v9.5.2

     Baseline

     As at baseline


    Syntax note: Operators without any defined mandatory arguments may omit their empty closing parentheses


    String.wordCount()

    String.wordCount

    String.wordCount returns the number of words in a string. The string is first scanned to determine its dominant language, and the word count is based on the conventions of that language (q.v. $WordCount). If the language cannot be determined or if it is not known to macOS, the conventions of English are used.

    String.wordList()

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

     Property  [other Property type actions]

     Item  [operators of similar scope]

     Data manipulation  [other Data manipulation operators]

     List [about List data type]

     v9.0.0

     Baseline

     As at baseline


    Syntax note: Operators without any defined mandatory arguments may omit their empty closing parentheses


    String.wordList()

    String.wordList

    This returns a list of every discrete word in the supplied string. Note that the output list is all lowercase, regardless of source case. This operator requires running on macOS 10.14 and later.

    $MyList = "I am the very model of a modern Major-General.".wordList; 

    then MyList holds "i;am;the;very;model;of;a;modern;major;general".

    String.words(wordsNum)

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

     Function  [other Function type actions]

     Item  [operators of similar scope]

     Data manipulation  [other Data manipulation operators]

     String [about String data type]

     v6.0.0

     Baseline

     As at baseline


    String.words(wordsNum)

    returns the first number words of a string. If the string has fewer than wordsNum words, returns the entire string. If wordsNum is negative, it returns a negative -wordsNum words from the end of the string. If $MyString is "Romans, they go house?".

    $MyString = $MyString.words(2); 

    returns "Romans, they".

    $MyString = $MyString.words(-1); 

    returns "house?". Note that punctuation contiguous to words gets passed through as part of the returned word(s).

    string(argStr)

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

     Function  [other Function type actions]

     Item  [operators of similar scope]

     Data manipulation  [other Data manipulation operators]

     String [about String data type]

     v11.5.0

     11.5.0

     As at baseline


    string(argStr)

    The operator string(argStr) returns its argument as explicitly String-type data. This is useful when neither single nor double quotes will achieve the desired result. The string result must not contain a closing parenthesis, i.e. a ')' character.

    StyledString.bold()

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

     Function  [other Function type actions]

     Item  [operators of similar scope]

     Formatting  [other Formatting operators]

     String [about String data type]

     v9.0.0

     Baseline

     As at baseline


    Syntax note: Operators without any defined mandatory arguments may omit their empty closing parentheses


    StyledString.bold()

    StyledString.bold

    The function sets the referenced string's styled text to bold text.

    $Text = $Text + "This is " + "some".bold + " text".plain; 

    adds "this is some text" to the end of $Text. The '.plain' command reasserts no style is to be applied.

    Note that $Text is currently the only attribute capable of holding styled text. String attributes and action code variables, i.e. var, cannot store styled text. If passed styled text the latter will store the unstyled version of the text being passed. See a more detailed explanation.

    String operators respecting StyledString operators

    String.paragraphs(), String.replace() and String.substr().

    StyledString.fontSize(pointSizeNum)

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

     Function  [other Function type actions]

     Item  [operators of similar scope]

     Formatting  [other Formatting operators]

     String [about String data type]

     v9.0.0

     Baseline

     As at baseline


    StyledString.fontSize(pointSizeNum)

    The function sets the referenced string's styled text to font size pointSizeNum, where pointSizeNum is the desired font size in points.

    $Text = $Text + "some bigger text".fontSize(N); 

    adds test "some bigger text" in 24pt to the end of $Text.

    It is also a good automatic way to reset $Text containing old (or accidental) size-based auto-headings. Code like this can be used as a stamp or other action to reset multiple selected notes:

    $Text = $Text.fontSize($TextFontSize); 

    This will make each (selected) note use it's own $TextFontSize (which might differ) to reset the size of the entire $Text of the note.

    Note that $Text is currently the only attribute capable of holding styled text. String attributes and action code variables, i.e. var, cannot store styled text. If passed styled text the latter will store the unstyled version of the text being passed. See a more detailed explanation.

    String operators respecting StyledString operators

    String.paragraphs(), String.replace() and String.substr().

    StyledString.italic()

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

     Function  [other Function type actions]

     Item  [operators of similar scope]

     Formatting  [other Formatting operators]

     String [about String data type]

     v9.0.0

     Baseline

     As at baseline


    Syntax note: Operators without any defined mandatory arguments may omit their empty closing parentheses


    StyledString.italic()

    StyledString.italic

    The function sets the referenced string's styled text to italic.

    $Text = $Text + "This is " + "some".italic + " text".plain; 

    adds "this is some text" to the end of $Text. The '.plain' command reasserts no style is to be applied.

    Note that $Text is currently the only attribute capable of holding styled text. String attributes and action code variables, i.e. var, cannot store styled text. If passed styled text the latter will store the unstyled version of the text being passed. See a more detailed explanation.

    String operators respecting StyledString operators

    String.paragraphs(), String.replace() and String.substr().

    StyledString.plain()

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

     Function  [other Function type actions]

     Item  [operators of similar scope]

     Formatting  [other Formatting operators]

     String [about String data type]

     v9.0.0

     Baseline

     As at baseline


    Syntax note: Operators without any defined mandatory arguments may omit their empty closing parentheses


    StyledString.plain()

    StyledString.plain

    The function (re-)sets the referenced string's styled text to the default face.

    $Text = $Text + "This is " + "some".italic + " text".plain; 

    adds "this is some text" to the end of $Text. The '.plain' command reasserts no style is to be applied.

    Note that $Text is currently the only attribute capable of holding styled text. String attributes and action code variables, i.e. var, cannot store styled text. If passed styled text the latter will store the unstyled version of the text being passed. See a more detailed explanation.

    Re-setting a note's $Text styling to defaults via code or stamp

    The Format ▸ Style menu allows the user to reset the default $TextFont/$TextSize and (ruler) styles. To replicate all those defaults for all the existing $Text, use:

    $Text = $Text.plain;

    String operators respecting StyledString operators

    String.paragraphs(), String.replace() and String.substr().

    StyledString.strike()

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

     Function  [other Function type actions]

     Item  [operators of similar scope]

     Formatting  [other Formatting operators]

     String [about String data type]

     v9.0.0

     Baseline

     As at baseline


    Syntax note: Operators without any defined mandatory arguments may omit their empty closing parentheses


    StyledString.strike()

    StyledString.strike

    The function sets the referenced string's styled text to stuck-through text.

    $Text = $Text + "This is " + "some".strike + " text".plain; 

    adds "this is some text" to the end of $Text. The '.plain' command reasserts no style is to be applied.

    Note that $Text is currently the only attribute capable of holding styled text. String attributes and action code variables, i.e. var, cannot store styled text. If passed styled text the latter will store the unstyled version of the text being passed. See a more detailed explanation.

    String operators respecting StyledString operators

    String.paragraphs(), String.replace() and String.substr().

    StyledString.textColor(aColor)

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

     Function  [other Function type actions]

     Item  [operators of similar scope]

     Data manipulation  [other Data manipulation operators]

     String [about String data type]

     v9.0.0

     Baseline

     As at baseline


    StyledString.textColor(aColor)

    The operator .textColor(aColor), when applied to styled text, sets the foreground colour of the text. The color argument can be either a named colour or a hexadecimal string. For example, both of these examples add 'example' in bright red text to the current note's $Text.

    $Text = $Text + "example".textColor("#FF0000") 

    Note that $Text is currently the only attribute capable of holding styled text. String attributes and action code variables, i.e. var, cannot store styled text. If passed styled text the latter will store the unstyled version of the text being passed. See a more detailed explanation.

    .textColor() respects the current text font, e.g. if set to a non-default colour.

    substr(dataStr, startNum[, lengthNum])

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

    Operator Has Optional Arguments: 

    Operator Has Newer Dot-Operator Variant: 

     Function  [other Function type actions]

     Item  [operators of similar scope]

     Data manipulation  [other Data manipulation operators]

     String [about String data type]

     v5.0.0

     Baseline

     As at baseline

     [More on optional operator arguments]

    Yes


    substr(dataStr, startNum, lengthNum)

    Where dataStr is a string literal, string attribute or action code expression evaluating to a string.

    Where startNum is the zero-based position to start the substring. Negative startNum values are not supported, though String.substr() does so and may be used instead.

    Where lengthNum is the length of the returned string. If not specified, the entire string from (or back from) startNum is returned.

    Extracts a substring of data. For example:

    $MyString = substr("test",0,1); 

    returns "t", while

    $MyString = substr("test",1,2); 

    returns "es". All arguments are evaluated; if the designated characters do not exist, an empty string is returned.

    If the length of the substring is negative, it is treated as an offset from the end of the string.

    $MyString = substr("Hello",1,-1); → "ell"

    Note that in action code expressions like

    $Initial=substr($Name,0,1); 

    the value of $Name is not changed.

    sum_if(scope, condition, actionStr)

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

    Operator Uses Regular Expressions: 

    Operator Uses Scoped Arguments: 

    Operator Has Conditional Arguments: 

    Operator Has Newer Dot-Operator Variant: 

     Function  [other Function type actions]

     Conditional Group  [operators of similar scope]

     Mathematical  [other Mathematical operators]

     Number [about Number data type]

     v4.0.0

     Baseline

     As at baseline

     [More on regular expressions in Tinderbox]

     [More on scoped arguments in Action Code]

     [More on conditional operator arguments]

    Yes


    sum_if(scope, condition, actionStr)

    This computes the Number sum of every actionStr value in each scope item (defining scope), as filtered by a condition query. See sum() for a related non-conditional operator. See also list.sum_if().

    scope describes the notes to be examined and may be any group designator including a find() query. sum_if() omits notes for which $Searchable is false.

    In addition, where may be argument that designates a particular (single) note other than this.

    condition is action code forming a valid conditional query test, i.e. it equates to true when matched. Some query-style operators terms may allow use of regular expressions.

    actionStr can be a complex action code expression, but is typically a Number-attribute value or a List or Set holding a list of numbers. It can also be a literal number 1, i.e. if the test is true from that item then add one to the retuned value of sum_if().

    For example,

    $MyNumber = sum_if(children,$Prototype=="p_Problem",1); 

    sums the number of children of the current note whose prototype is 'p_Prototype'. If tested value is a string with spaces, e.g. "p Prototype" vs. "p_Prototype" then use double quotes around the value.

    The newer count_if() offers a more intuitive method of counting matches rather than the value of matched items.

    sum(scope, actionStr)

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

    Operator Uses Scoped Arguments: 

    Operator Has Newer Dot-Operator Variant: 

     Function  [other Function type actions]

     Group  [operators of similar scope]

     Mathematical  [other Mathematical operators]

     Number [about Number data type]

     v4.0.0

     Baseline

     As at baseline

     [More on scoped arguments in Action Code]

    Yes


    sum(scope, actionStr)

    This computes the arithmetic Number of every actionStr value in each in-scope item (defining scope). See sum_if() for a related conditional operator.See also list.sum().

    The sum() operator omits notes for which $Searchable is false.

    actionStr can be a complex action code expression, but is typically a Number-attribute value or a List or Set holding a list of numbers. It can also be a literal number 1, i.e. if the test is true from that item then add one to the retuned value of sum(). The latter is less likely than with the sibling operator sum_if().

    For example,

    $MyNumber = sum(children,$WordCount); 

    constructs the current word count of the children of the note.

    tan(radiansNum)

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

     Function  [other Function type actions]

     Item  [operators of similar scope]

     Mathematical  [other Mathematical operators]

     Number [about Number data type]

     v4.0.0

     Baseline

     As at baseline


    tan(radiansNum)

    tan() converts its radiansNum, in radians, to the tangent of that value.

    $MyNumber = tan(3) 

    returns '-0.1425465431' for an input of 3 radians.

    time(aDate, hoursNum, minutesNum[, secondsNum])

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

    Operator Has Optional Arguments: 

     Function  [other Function type actions]

     Item  [operators of similar scope]

     Date-time  [other Date-time operators]

     Date [about Date data type]

     v4.0.0

     Baseline

     As at baseline

     [More on optional operator arguments]


    time(aDate, hoursNum, minutesNum[, secondsNum])

    creates a new Date based on the aDate action code expression, but in which the time is set by hoursNum, minutesNum, and secondsNumDate is not changed. Only positive values are allowed. If needing to alter a Date's time towards or backwards by a certain amount, consider using interval(dataStr).

    time() accepts an optional fourth argument secondsNum, representing the seconds component of the time.

    For example, to make a stamp or rule that sets the time element of all event start/end dates in a timeline to 12:00:00 AM (midday) use this code:

       $StartDate=time($StartDate,12,0,0);
       if($EndDate){
          $EndDate=time($EndDate,12,0,0)
       };

    Parsing of time inputs

    When any/all of hoursNum, minutesNum, and secondsNumDate are provided in a value larger then their normal limit, Tinderbox adjusts the containing limit accordingly. Thus > 60 seconds adds minute to aDate, > 60 minutes adds an hour, >24 hours adds a day. Therefore:

    $StartDate=time($StartDate,12,30,0); 

    results in a time of 12:30:00, but:

    $StartDate=time($StartDate,12,90,0); 

    results in a time of 13:30:00, as 90 minutes is parsed as being 1 hour + 30 minutes and as if this code were being used:

    $StartDate=time($StartDate,13,30,0); 
    time(aDate)

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

     Function  [other Function type actions]

     Item  [operators of similar scope]

     Date-time  [other Date-time operators]

     String [about String data type]

     v4.0.0

     Baseline

     As at baseline


    time(aDate)

    returns a string of the hours/minutes/seconds time part the aDate date/time action code expression, which may simply be a date-type attribute value. For instance:

    $MyString = time($StartDate); 

    If the time of $StartTime is 14:20:30 then $MyString will be "14:20:30". Passing to a string will elide leading zeroes, so a time of 05:08 will return "5:08".

    twitter(usernameStr, statusStr)

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

     Function  [other Function type actions]

     Item  [operators of similar scope]

     Data manipulation  [other Data manipulation operators]

     source context dependent

     v6.0.0

     Baseline

     As at baseline


    twitter(usernameStr,statusStr)

    NOW DEPRECATED and no longer working - for info only

    allows posting to the user's twitter account (usernameStr) of a tweet (statusStr).

    Tinderbox will request permission to use your Twitter account, and will send the tweet to that account.

    twitter("myusername","my test tweet") 

    The twitter() action is no longer supported (reflecting changes to Twitter API).

    type(attributeNameStr)

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

     Function  [other Function type actions]

     Document  [operators of similar scope]

     Document configuration  [other Document configuration operators]

     String [about String data type]

     v9.0.0

     Baseline

     As at baseline


    type(attributeNameStr)

    This operator may be replaced by the more flexible attribute() operator.

    The operator type(attributeNameStr) returns a string representing the type of the designated attribute. The attribute may simply be the attribute name (without quotes or a preceding "$") or an action code expression that, when evaluated, yields an attribute name.

    $MyString = type(Width); → "number"
    $MyString = type("AccentColor"); → "color"
    $MyString="Modified"; type($MyString); → "date"

    Note that type($MyString) returns the type of the attribute who name is stored in $MyString, while type("MyString") or type(MyString) returns the type of the attribute MyString.

    If no such attribute exists in the document, the operator returns the empty string.

    UI

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

     Variable  [other Variable type actions]

     Item  [operators of similar scope]

     Data manipulation  [other Data manipulation operators]

     Dictionary [about Dictionary data type]

     v11.6.0

     11.6.0

     As at baseline


    Syntax note: Operators without any defined mandatory arguments may omit their empty closing parentheses


    From v11.6.0, mouse actions are associated with a local-scope Dictionary-type variable UI. This holds information about a mouse-click and its environment:

    • x: the mouse horizontal position in map coordinates, relative to the top left of the note.
    • y: the mouse vertical position in map coordinates, relative to the top left of the note.
    • height: the height of the note
    • width: the width of the note
    • hit: a boolean, true if the mouse is inside the note, false otherwise.
    • view: a string representing the type of view, such as map.
    unlinkFrom(scope[, linkTypeStr])

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

    Operator Uses Scoped Arguments: 

    Operator Has Optional Arguments: 

     Function  [other Function type actions]

     Group  [operators of similar scope]

     Linking  [other Linking operators]

     success boolean

     v4.6.0

     Baseline

     As at baseline

     [More on scoped arguments in Action Code]

     [More on optional operator arguments]


    unlinkFrom(scope[, linkTypeStr])

    This removes all basic links from scope to the current note (i.e. inbound links). unlinkFrom() does not delete prototype links.

    Both arguments are evaluated. This operator does not require a left-side argument, simply calling effects a result. No change occurs if the described link does not exist.

    scope argument

    The scope argument must be quoted unless an attribute reference, e.g. "Some note" vs. $MyString. Ways to define scope. Note that here, unlike other scope uses, $Path can not be used.

    scope may be group scoped including use of group designators and operators like find,() collect and links().

    linkTypeStr argument

    linkTypeStr (string). Optionally, link deletion can be constrained to one type supplied as literal string value for linkTypeStr:

    • If no linkTypeStr argument is supplied, only untitled (i.e. no link type) links are deleted.
    • If a valid link type name, e.g. "agree", is supplied only links of the specified type are deleted.
    • To delete all links of any type or none use the wildcard value "*" (an asterisk). Also note:
      • This method does not affect prototype links.
      • This wildcard linkTypeStr option only applies to unlinking, and not to linking).

    linkTypeStr is evaluated as a literal string (previously a pattern match was undertaken).

    Examples

    Unlinking from a note "Some note":

    all link types: unlinkFrom("Some note"); 
    only link type 'agree': unlinkFrom("Some note","agree"); 
    either of 2 link types: unlinkFrom("Some note", "example|disagree"); 

    Unlinking the first child (via a designator):

    unlinkFrom(child); 
    unlinkFrom(child,"agree"); 

    See further below for group-scope references.

    Relevant similar operators: linkTo, linkFrom, unlinkTo.

    Use of this action does not shift note focus; in addition if scope contains operators (brackets, plus, minus, etc.) Tinderbox will first look for a match to the literal scope string and only if there is no match will the app try evaluating to operators and testing the resulting string. For example:

    unlinkFrom("Example 1 (a test)"); 

    will unlink the note named 'Example 1 (a test)'. If no note matches this string, Tinderbox will attempt to evaluate the string. Thus for:

    unlinkFrom("2+2"); 

    will unlink the note named '2+2' but if there is no match Tinderbox will look for a note named '4'.

    This function can unlink an alias as opposed to an original (if the logical choice) and can also accept a group scope. An example of group scope is the following code that could be used in a rule or stamp to remove in/bound footnote links from one or more selected notes. Use of the 'all' designator removes the need to know the name of the notes for which the selection are footnotes:

    unlinkFrom(all,"note");unlinkTo(all,"note+"); 

    Use in agents

    Beware that the action is working on an alias of the current note and note the current note itself. As originals and aliases support discrete basic links this function should not generally be used in an agent. The best way to use the function is by using a prototype and apply a $Rule to it thus running the code in all notes using the prototype.

    An alternative unlinkFromOriginal() code will ensure any link deleted is between two original notes regardless of whether an alias is the context of execution of the code.

    unlinkFromOriginal(scope[, linkTypeStr])

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

    Operator Uses Scoped Arguments: 

    Operator Has Optional Arguments: 

     Function  [other Function type actions]

     Group  [operators of similar scope]

     Linking  [other Linking operators]

     success boolean

     v6.4.0

     Baseline

     As at baseline

     [More on scoped arguments in Action Code]

     [More on optional operator arguments]


    unlinkFromOriginal(scope[, linkTypeStr])

    This function works exactly as the same as unlinkFrom(), except for one important difference that the link deleted is always between two originals even if either/both the evaluated source or destination are an alias. unlinkFromOriginal() does not delete prototype links.

    For more detail of use, see unlinkFrom().

    Unlinking from an original note "Some note" (and not an alias of it):

    all link types: unlinkFromOriginal("Some note"); 
    only link type 'agree': unlinkFromOriginal("Some note","agree"); 
    either of 2 link types: unlinkFromOriginal("Some note", "example|disagree"); 

    See also linkFromOriginal(), linkToOriginal(), unlinkToOriginal().

    unlinkTo(scope[, linkTypeStr])

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

    Operator Uses Scoped Arguments: 

    Operator Has Optional Arguments: 

     Function  [other Function type actions]

     Group  [operators of similar scope]

     Linking  [other Linking operators]

     success boolean

     v4.6.0

     Baseline

     As at baseline

     [More on scoped arguments in Action Code]

     [More on optional operator arguments]


    unlinkTo(scope[, linkTypeStr])

    This removes all basic links to scope from the current note (i.e. outbound links). unlinkTo() does not delete prototype links.

    Both arguments are evaluated. This operator does not require a left-side argument, simply calling effects a result. No change occurs if the described link does not exist.

    scope argument

    The scope argument must be quoted unless an attribute reference, e.g. "Some note" vs. $MyString. Ways to define scope. Note that here, unlike other scope uses, $Path may not be used.

    The scope may be group scoped including use of group designators and operators like find,() collect() and links().

    linkTypeStr argument

    linkTypeStr (string). Optionally, link deletion can be constrained to one type supplied as literal string value for linkTypeStr:

    • If no linkTypeStr argument is supplied, only untitled (i.e. no link type) links are deleted.
    • If a valid link type name, e.g. "agree", is supplied only links of the specified type are deleted.
    • To delete all links of any type or none use the wildcard value "*" (an asterisk). Also note:
      • This method does not affect prototype links.

    linkTypeStr is evaluated as a literal string (previously a pattern match was undertaken).

    Examples

    Unlinking to a note "Some note":

    all link types: unlinkTo("Some note"); 
    only link type 'agree': unlinkTo("Some note","agree"); 
    either of 2 link types: unlinkTo("Some note", "agree|disagree"); 

    Matching the first child (via a designator):

    unlinkTo(child); 
    unlinkTo(child,"agree"); 

    See further below for group-scope references.

    Relevant similar operators: linkTo, linkFrom, unlinkFrom.

    Use of this action does not shift note focus; in addition if scope contains operators (brackets, plus, minus, etc.) Tinderbox will first look for a match to the literal scope string and only if there is no match will the app try evaluating to operators and testing the resulting string. For example:

    unlinkTo("Example 1 (a test)"); 

    will unlink the note named 'Example 1 (a test)'. If no note matches this string, Tinderbox will attempt to evaluate the string. Thus for:

    unlinkTo("2+2"); 

    will unlink the note named '2+2' but if there is no match Tinderbox will look for a note named '4'.

    This function can unlink an alias as opposed to an original (if the logical choice) and can also accept a group scope. An example of group scope is the following code that could be used in a rule or stamp to remove in/bound footnote links from one or more selected notes. Use of the 'all' designator removes the need to know the name of the notes for which the selection are footnotes:

    unlinkFrom(all,"note");unlinkTo(all,"note+"); 

    Use in agents

    Beware that the action is working on an alias of the current note and note the current note itself. As originals and aliases support discrete basic links this function should not generally be used in an agent. The best way to use the function is by using a prototype and apply a $Rule to it thus running the code in all notes using the prototype.

    An alternative unlinkToOriginal() code will ensure any link deleted is between two original notes regardless of whether an alias is the context of execution of the code.

    unlinkToOriginal(scope[, linkTypeStr])

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

    Operator Uses Scoped Arguments: 

    Operator Has Optional Arguments: 

     Function  [other Function type actions]

     Group  [operators of similar scope]

     Linking  [other Linking operators]

     success boolean

     v6.4.0

     Baseline

     As at baseline

     [More on scoped arguments in Action Code]

     [More on optional operator arguments]


    unlinkToOriginal(scope[, linkTypeStr])

    This function works exactly as the same as unlinkTo(), except for one important important difference that the link deleted is always between two originals even if either/both the evaluated source or destination are an alias. unlinkToOriginal() does not delete prototype links.

    For more detail of use, see unlinkTo().

    Unlinking to an original note "Some note" (and not an alias of it):

    all link types: unlinkToOriginal("Some note"); 
    only link type 'agree': unlinkToOriginal("Some note","agree"); 
    either of 2 link types: unlinkToOriginal("Some note", "agree|disagree"); 

    See also linkFromOriginal(), linkToOriginal(), unlinkFromOriginal().

    update()

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

     Function  [other Function type actions]

     List  [operators of similar scope]

     Data manipulation  [other Data manipulation operators]

     List [about List data type]

     v9.1.0

     Baseline

     11.0.0


    Syntax note: Operators without any defined mandatory arguments may omit their empty closing parentheses


    update()

    This returns a list of updated notes. This allow the user, to check, if necessary, which notes have actually been updated.

    Note also that we can use update() at the start of an action to be sure we are ready to work, and we can also use update() after an action if we know some other note will want to respond to our new values.

    On the whole, update() is envisaged an esoteric command for unusual cases, but may prove popular for some users with demanding applications. For light/occasional use, a need to use update() is likely an indication that some review of current code use is needed.

    The method of update() using an argument is documented separately: see update(scope).

    From v11.0.0 update() updates smart adornments as well as agents.

    update(scope)

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

    Operator Uses Scoped Arguments: 

     Function  [other Function type actions]

     List  [operators of similar scope]

     Data manipulation  [other Data manipulation operators]

     success boolean

     v9.1.0

     Baseline

     11.0.0

     [More on scoped arguments in Action Code]


    update(scope)

    The action update(scope) asks Tinderbox to update one or more notes defined in the list scope by evaluating both their rule and edict of each listed note (defining scope). If the note has been evaluated recently, Tinderbox will not evaluate it again.

    For example, suppose there is a note 'INSTALL DISHWASHER', which has a rule saying that the dishwasher cannot start to be installed until the task of note 'FLOOR' is finished.

    if($StartDate < $EndDate("FLOOR")) {
    	$StartDate = $EndDate("FLOOR"); 
    	$EndDate = $StartDate+$MyInterval; 
    }

    This rule works best if the 'FLOOR' note is up to date. So, before doing anything else, the 'FLOOR' note is updated:

    update("FLOOR");
    if($StartDate < $EndDate("FLOOR")) {
    	$StartDate = $EndDate("FLOOR");
    	$EndDate - $StartDate + $MyInterval;
    }

    Note that, if note 'FLOOR' has been updated recently (a duration as decided by the app), it will not be updated again; the prevents Tinderbox from doing lots of unwanted and unnecessary work.

    On the whole, update(scope) is envisaged an esoteric command for unusual cases, but may prove popular for some users with demanding applications. For light/occasional use, a need to use update() is likely an indication that some review of current code use is needed.

    The non-argument form of update() is documented separately: see update().

    If update() is called on a note inside /Hints/Library, any functions in the text of that note will be recompiled and the actions in the text of the note will be performed.

    When applied to an agent, update() updates the agent as well as performing its rule and edict.

    From v11.0.0 update() updates smart adornments as well as agents.

    uppercase(dataStr)

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

    Operator Has Newer Dot-Operator Variant: 

     Function  [other Function type actions]

     Item  [operators of similar scope]

     Formatting  [other Formatting operators]

     String [about String data type]

     v4.6.0

     Baseline

     As at baseline

    Yes


    uppercase(dataStr)

    The contents of dataStr are returned entirely in upper case.

    If $MyString is "hello world":

    $MyString = uppercase($MyString); 

    $MyString is set to "HELLO WORLD".

    Functionally equivalent to String.uppercase().

    urlEncode(dataStr)

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

     Function  [other Function type actions]

     Item  [operators of similar scope]

     Formatting  [other Formatting operators]

     String [about String data type]

     v4.0.0

     Baseline

     As at baseline


    urlEncode(dataStr)

    urlEncode() converts a dataStr string to 'urlEncoded' form for the web, in accordance with RFC1738. URLs should not contain spaces, control characters, or non-ASCII characters. Characters that are illegal in URLs are encoded as '%' followed by the corresponding hexadecimal character code, e.g. space = %20.

    Thus:

    $MyString = urlEncode("Hello world"); 

    sets $MyString to 'Hello%20world'.

    dataStr should be a quoted literal string or a reference to a string value.

    The characters ? and / are percent-encoded by urlEncode(), e.g. as %3F and %2F. Even though these are now permitted in the query portion of URLs, the Apple NSURL used by Tinderbox balks at their presence.

    values([scope, ]attributeNameStr)

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

    Operator Uses Scoped Arguments: 

    Operator Has Optional Arguments: 

     Function  [other Function type actions]

     Group  [operators of similar scope]

     Dictionary, Set & List operations  [other Dictionary, Set & List operations operators]

     List [about List data type]

     v5.10.1

     Baseline

     As at baseline

     [More on scoped arguments in Action Code]

     [More on optional operator arguments]


    values([scope, ]attributeNameStr)

    values(attributeNameStr)

    This returns a Set of unique values for the attribute attributeNameStr. As the output is a of Set data type, the list of possible values is de-duped thus giving a list of unique values, and should be sorted. Any suggested values not actually used by at least one note are omitted from the list return by values().

    If the named attributeNameStr is a set or list, values() returns a list of all the unique discrete list item values that occur. If the named attribute is a string, values() returns all the unique strings.

    attributeNameStr is evaluated in case it is something like a variable holding the desired target attribute name. The change is that, if the argument is not an attribute name, and if the argument trimmed of its $ is still not an attribute name, we now see if the evaluated action code expression turns out to be an attribute name.

    Important: unlike other operators, be aware that values($MyString) returns a list of values found for $MyString, not a list of the values of the attribute whose name is stored in $MyString. This is unique to values(), and arises because writing values($MyString) instead of values("MyString") was a very common mistake. If needing to pass a value holding an attribute name, use an action code variable and not as a value stored in another attribute.

    The returned set is sorted in lexical order.

    If a document has a user List-Type attribute $SomeList, then to get a a list of all the unique values for $SomeList in the whole document:

    $MyList = values("SomeList"); 

    The attributeNameStr argument is evaluated so may be:

    • A quoted attribute name without $-prefix: values("MyList").
    • A string attribute name, whose current value is the name of an attribute (without a dollar prefix). If $MyString has the value "MyList", then values($MyString) will evaluate the unique values for $MyList (and output the same result as values("MyList") above).
    • An action code expression resolving to an attribute name.

    Thus if the document has a user List-Type attribute $SomeList and $MyString has the value "SomeList", then these are functionally equivalent:

    $MyList = values("SomeList"); 
    $MyList = values($MyString); 

    It is envisaged that the first method (the quoted, un-prefixed, attribute name) will be the most usual method of using values().

    Sorting. The data is returned in case-sensitive lexical sort order (i.e. all capitals sort before lower case letters, and numbers sorting textually not numerically) so chaining .isort() may often be the desired 'default', or use .nsort() if the list is entirely composed of numbers. Assume, the intention is to get a note whose $Text has one value per line. It could be coded thus:

    $Text=values("MyList").format("\n"); 

    This is a very useful way of making a set of per-value notes. Use values() to collect the values, pass them to a note's $Text as a one-value-per-line string and then explode the $Text.

    However, a value list of [aardvark;amber;Ant] would actually list in this order: [Ant;aardvark;amber]. That is due to the Set's auto-sort using case-sensitive lexical sorting, whereas a case-insensitive sort would be more appropriate. Thus:

    $Text=values("MyList").isort.format("\n"); 

    Similarly the default sort would order 1/2/10 and 1/10/2, so a numerical sort would be more sensible:

    $Text=values("MyList").isort.format("\n"); 

    De-duplication. values() differs from collect() in that values() returns Set-type data and collect() returns List-type data. For a list $MyList, the following are functionally equivalent in output:

    $MyList = collect(all,$SomeList).unique; 
    $MyList = values("SomeList"); 
    $MyList = values($MyString); (where $MyString has the value "SomeList")

    values(scope, attributeNameStr)

    If an optional first scope argument is provided, the value(s) returned are drawn only from notes in that scope (defining scope). If no first argument is supplied, as in the short form above, the default scope-defined group is assumed as 'all' and thus at whole document scope.The reference point for groups like 'children' or 'siblings' is this note. Thus:

    $MyList = values(children,"Subtitle"); 

    will return all the discrete subtitles (i.e. values of $Subtitle) for children of this note, i.e. the note in which context the action is being evaluated.

    var

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

     Statement  [other Statement type actions]

     Item  [operators of similar scope]

     Data manipulation  [other Data manipulation operators]

     declaration

     v5.10.0

     Baseline

     As at baseline


    var

    var:type

    The var statement declares the local variable. No trailing parentheses are used. Occasionally, an action may find it convenient to declare a local variable in which to save intermediate results. In the past, the only choice was to use a user attribute as a temporary store, with the attendant issues of deciding if it is necessary to reset the attribute at the end of the action code expression.

    Depending on how the operator is being used it may be used without parentheses.

    Try to use variable names that will not be mistaken for something else. Avoid using a 'var' prefix for variable names, such as 'varX', as this will confuse Tinderbox's parser. In such a case 'vX' might be a better choice and a 'v' prefix is the convention adopted in aTbRef (though there is no requirement to use such naming as it is used for explanatory reasons only).

    A local variable acts in most ways like a user attribute. Local variables exist for the duration of the action or, when they are declared inside curly brackets { … }, e.g. an an .each() loop, their scope is the rest of the clause, i.e. the remaining individual statements within the {}.

    Locally set Set-type variables, e.g. var:set s=[a;b;a;c]; remove duplicates at initialisation.

    String variables cannot store styles text (i.e. 'rich' text).

    Declaring a variable

    So, the var statement declares the local variable:

    var x; declares a variable 'x', but with no value

    More sensible is to use a name indicating purpose:

    var vNum; declares a variable 'vNum' with no value.
    var vNum(5); declares a variable 'vNum' and gives it an initial value of 5.
    var vText("this is note "+$Name); declares a variable 'vText' and gives it a calculated string value.

    A variable can also be declared and assigned a value is a single action code expression:

    var vCost = 5; 

    … defines a temporary variable 'vCost' and then assigns it the value '5'. It is equivalent to the following original syntax, note the explicit use of operator argument parentheses in this case:

    var vCost(5); 

    In effect, the first form collapses the older two-step method of declaring an empty var before then giving it a value:

    var vCost; 
    vCost=5; 

    Local variables must be declared before first use. If not explicitly initialised, their initial value is the empty string "". Within scope, a variable maybe reset in the same manner as an attribute. Thus, YY=; resets variable 'YY' to no value.

    Setting a variable's data type

    A var can optionally be given a data type on creation, by colon-appending the data-type to the var operator. Thus:

    var:number vCost(5); 

    This generates a variable 'vCost' of (expected) data type Number and sets an initial value of '5'.

    Available data types include

    • boolean
    • color
    • date
    • dictionary
    • interval
    • number
    • list
    • set
    • string

    Note that data type labels are all-lowercase. Other existing attribute data types that are not listed here will be provisioned as a string, as they are strings with a special, contextually different, form of use. Important: defining a date type without an initial value does not set that types value:

    var:number vNum; → values is undefined (i.e. "")
    var:number vNum = 0; → values is zero (0)

    Providing an explicit type helps Tinderbox to understand the user's intent, especially if a default value is applied (though for string-based attributes it is moot). For example, the same numerical value number might react to subsequent operations in various ways:

    var:number vCost(5); vCost = vCost + 5; $MyString= vCost; gives '10'
    var:list vCost((5); vCost =vCost + 5; $MyString = vCost; gives a 2-member list, '5;5'
    var:string x(5); vCost =vCost + 5; $MyString = vCost; gives '55'

    Further usage Examples

    $MyNumber = 0; var vNum = 2; $MyNumber = vNum; 
    $MyNumber = 0; var vNum; vNum = 2; $MyNumber = vNum; 
    $MyNumber = 0; var vNum(2); $MyNumber = vNum; 

    In all cases $MyNumber is set to 2. In the second example the variable is defined and given a value using a single action code expression. Here is a scoped example within a single action the { and } marking the scope:

    	$MyNumber = 0;
    	{
    		var vNum = 2;
    		$MyNumber = vNum;
    		vNum = 6;
    	};
    	$MyNumber = vNum;

    $MyNumber is set to 0 (nothing) as 'vNum' has no meaning outside the code inside the braces {}. By analogy a variable created inside a loop or function, (i.e. within { } sections of code) cannot be read outside that scope, but variables created outside such scope can be read/set within a loop or function.

    Using variable values declared outside loops or functions

    A variable declared using var may be altered from within the scope of a list.each() loop or a function. This includes nested loops or functions. The reverse does not hold. In-loop a new value would be to be stored in an attribute or variable declared outside the loop. In a function, this value could be (part of) the return data.

    Passing variables into export code

    ^value()^ can be used, within the context a single template, to insert a var() variable declared within an ^action()^ code. Note that the variable must be declared before use, i.e. before as in reading template code top to bottom.

    Beware name collisions

    Assume for a moment you have an actual attribute $vNum, then:

    	$MyNumber = 0;
    	{
    		var vNum(2);
    		$MyNumber = vNum;
    		vNum = 6;
    	};
    	vNum = 4;
    	$MyNumber = vNum;

    $MyNumber is 4, rather than 0, because the vNum = 4 is interpreted as the deprecated legacy syntax of $vNum = 4. So, be careful that a local variable's name does not match existing attributes, note names or string literals that you use in your project.

    Remember the local variable does not take a $ prefix. It is a value reference but not to an attribute.

    version()

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

     Property  [other Property type actions]

     Document  [operators of similar scope]

     Data manipulation  [other Data manipulation operators]

     String [about String data type]

     v8.8.0

     Baseline

     As at baseline


    Syntax note: Operators without any defined mandatory arguments may omit their empty closing parentheses


    version()

    version

    The action operator version() returns information about the version of Tinderbox. With no argument, it returns a complete version string such as "8.7.2b472".

    version("part") An optional single argument can be supplied. Possible values are: major, minor, fix, and build, each returning a specific part of the overall version.

    For example, in Tinderbox 8.7.2b472:

    version() returns: 8.7.2b472 
    version(major) returns: 8 
    version(minor) returns: 7 
    version(fix) returns: 2 
    version(build) returns: b472 

    These arguments may be used with or without enclosing quotes. Thus, usage:

    $MyString = version(major); 

    or

    $MyString = version("fix"); 
    weeks(startDate, endDate)

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

     Function  [other Function type actions]

     Item  [operators of similar scope]

     Date-time  [other Date-time operators]

     Number [about Number data type]

     v7.5.0

     Baseline

     As at baseline


    weeks(startDate, endDate)

    This returns the Number of (7-day weeks) weeks between two dates, startDate and endDate. If the dates are within seven days of each other, the result is zero.

    If $DateA is 3 January 2016 and $DateB is 20 January 2016, then:

    $MyNumber = weeks($DateA,$DateB); 

    sets $MyNumber to 2.

    If endDate is before startDate the result is negative.

    while(condition){}

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

    Operator Has Conditional Arguments: 

     Operator  [other Operator type actions]

     Conditional Group  [operators of similar scope]

     Data manipulation  [other Data manipulation operators]

     boolean test

     v9.5.0

     Baseline

     As at baseline

     [More on conditional operator arguments]


    The operator while(condition){…} performs an action repeatedly until the condition query expression evaluates as false. Put another way, the code in the curly brackets will continue to be run again and again, until condition query expression evaluates as false. This operator addresses the scenario where:

    - it is known a task needs to be done multiple times but,

    _ the exact number of times to repeat the task is not known

    Using while() it is possible to define the a test (condition) to ascertain when the task is done and the repeating/looping action can stop.

    For those less used to coding, consider a generalised analogy—the task of filling a bucket with water. Before adding anything to the bucket we might sensibly ask if the bucket is full and only if it is not, do we add another scoop of water. But if the bucket is full, we stop adding water. It can be summarised thus:

    • Is the bucket full?
      • No? We add another scoop of water and start over with the original check (i.e. continue the loop).
      • Yes? We're done—exit and finish.

    Examples

    Consider the case where it is desired to process a note's $Text, of unknown size, one sentence at a time. Thus (code commenting is for explanation only, and is not needed in actual code):

    	// make a variable holding $Text, so $Text itself is not affected
    	var:str vText = $Text;
    	// start the loop using vText
    	while(vText!=""){
    		// get the first sentence in vText
    		var:string vStr = $Text.sentence(0);
    		// pass that sentence to function fProcessText() to do whatever task with it ...
    		fProcessText(vStr);
    		// remove the sentence vStr from vText *before* the loop runs again
    		// so that vStr is different in the next loop, i.e. each sentence is used only once
    		vText = vText.substr(vStr.size).trim();
    	};

    This will read $Text and process it to call the user-defined function fProcessText() passing it one sentence at a time. Each loop removes the just-processed sentence, so the text considered in the next loop is one sentence shorter, until eventually vText is empty at which point the while() operator completes and the next action after it, if any, is read.

    A programmer might write the same as above more tersely:

    var vt=$Text;while(vt){var:string s=vt.sentence;vt=vt.substr(s.size).trim(); process(s);} 

    But, importantly, both do the same thing and the different code has no effect on Tinderbox performance. As long as the code is valid, users are free to choose their style.

    Prior to this, it would be necessary to first count the number of discrete sentences and store that in a variable, then make a list of discrete sentences, then iterate this list using a loop counter and checking in each loop to see if the counter figure was below the stored count before taking any per-item action; while() wraps all that up into a simple operator.

    Preventing against infinite loops

    An infinite loop occurs when condition always remains false and thus the code loop never stops running. To guard against this unintended scenario while() loops are limited to 10,000 iterations, i.e. if the loop has run 10,000 time it automatically stops regardless of the state of condition.

    word(dataStr)

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

     Function  [other Function type actions]

     Item  [operators of similar scope]

     Query Boolean  [other Query Boolean operators]

     boolean test

     v4.6.0

     Baseline

     As at baseline


    word(dataStr)

    Returns Boolean true if the string dataStr (of for or more characters) is contained in the current note's text or title. This operator is quicker for matching whole words than using a regular expression. The function matches all notes that contain a single word matching (case-insensitively) any complete word in:

    • the title OR
    • the text OR
    • any user String data-type attribute(s). This does not include other data types based on strings (List, URL, Set, File, Action, etc.)

    The matching is case-insensitive. Note that word() is stricter in its matching than the .contains() function as it looks only for entire words and does not match regular expressions. Although word() examines several different fields, the result is that word() is much faster than .contains().

    The word dataStr must be a quoted string containing:

    • a single word (no hyphenated words)
    • contain only upper or lower case letters, so no white space, digits, or punctuation
    • 4 characters or more (values less than 4 characters or fewer are ignored by Tinderbox).

    In the query creation pop-ups of agent and Find dialogs this function is listed as "contains word".

    Example

    This query finds any note where the word 'confusion' occurs (in any case variant) in either $Text or $Name :

    word("Confusion") 

    Note how dataStr is case-insensitive.

    Legacy issues

    This operator replaces the legacy #word query operator.

    wordsRelatedTo(dataStr[, wordsNum])

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

    Operator Has Optional Arguments: 

     Function  [other Function type actions]

     Item  [operators of similar scope]

     Data manipulation  [other Data manipulation operators]

     Set [about Set data type]

     v8.8.0

     Baseline

     As at baseline

     [More on optional operator arguments]


    wordsRelatedTo(dataStr[, wordsNum])

    NOTE: This feature needs macOS 10.15.0 or later. If used on older OSs, the function returns no data; i.e. not all users of v8.x maybe able to use this feature as it is macOS version dependent.

    The operator tries to return a list (Set) of up to wordsNum (discrete) words related to its dataStr argument. Fewer words may be returned, or no words may be returned if the argument is unusual, or if the current language is not supported.

    An optional second argument wordsNum, allows the returned number of related terms to be limited to a specific number of items. wordsNum is 1 or more (integer value), but Tinderbox will only return as many 'related' terms as it can find, i.e. it may return fewer than wordsNum items.

    Practically, an wordsNum value of more than 10 items is unlikely to render useful results. Be aware this draws on features still under development in the underlying OS, so there are no certainties.

    $MySet = wordsRelatedTo("hubris"); 

    or to get only 5 (or fewer) values:

    $MySet = wordsRelatedTo("aspirational",5); 

    It is not certain, but likely, that results returned are ordered by proximity of the relationship in the vector space of the dataStr (bear in mind this is a black-box OS procedure).

    Though the product is essentially a Set, i.e. a list without duplicates, Sets may change the order of items during other processes whilst List attributes do not. So if concerned about retaining order exactly as originally returned by the function, it makes would pass the process to an explicit list

    $MyList = wordsRelatedTo("expectation",8); 
    XML.each(pathStr){actionStr}

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

     Function  [other Function type actions]

     Item  [operators of similar scope]

     Stream parsing  [other Stream parsing operators]

     iterator

     v9.1.0

     Baseline

     As at baseline


    XML.each(pathStr){ actionStr }

    This operator locates the xml object for each object at the pathStr (within the XML), generating a loop upon it. The .each(pathStr) invokes the actionStr with the xml item bound in turn to each book element. On completion, it restores the XML object to its previous state.

    Consider a note "Source note" with this $Text:

    <shelf>
    	<book price="9.95">War and Peace</book>
    	<book price="4.95">No et Moi</book>
    	<audio price="14.95">Born To Run</audio>
    </shelf>

    Example usage of path:

    $MyList("test") = "";
    $Text("Source note").xml.each("/shelf/book"){
    	$MyList("test2")+=xml["book"]+"\n";
    };

    which sets $MyList of note "test" to a list of children of the <shelf> element that are <book> elements, [War and Peace;No et Moi].

    $MyList("test2") = "";
    $Text("Source note").xml.each("/shelf/book"){
    	$MyList("test2")+=xml["book[2]"]+"\n";
    };

    which sets $MyList of note "test" to the value of child element of the <shelf> element that represents the second book, "No et Moi". Other iterated elements return a blank. See 'Notes' below.

    $MyList("test2") = "";
    $Text("Source note").xml.each("/shelf/book"){
    	$MyList("test2")+=xml["book@price"]+"\n";
    };

    witch sets $MyList of note "test" to a list of the price attribute of each book element, [9.95;4.95].

    Notes:

    • Acceptable path content is a subset of the XPath standard (see https://www.w3.org/TR/2017/REC-xpath-31-20170321/).
    • To accord with standard XML and XPath usage, the first child of an XML node is child [1], not [0].
    • XML attributes are not related to Tinderbox attributes.

    Consider this source XML string stream:

    <shelf>
    <book price="9.95">War and Peace</book>
    <book price="4.95">No et Moi</book>
    <audio price="14.95">Born To Run</book>
    </shelf>

    Examples

    Stream.xml.each("/shelf/book") {actionStr} 

    returns every 'book' object in the 'shelf' object and iterates over them, i.e. for each (path-matched) item it invokes the actionStr block with the xml item bound in turn to each book element. In the example above this means the action is run 3 times, once for each of the 3 <book> elements under <shelf>.

    Inside the actionStr, action code can refer to the value of the iterated item as elementName[], book[]. Any attribute of that item can be addressed as elementName[@attribute] book[@price], i.e. here the 'price' attribute of the XML object in focus.

    On completion, it restores the xml object to its previous state.

    XML.xml(pathStr)

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

     Function  [other Function type actions]

     Item  [operators of similar scope]

     Stream parsing  [other Stream parsing operators]

     source context dependent

     v9.1.0

     Baseline

     As at baseline


    XML.xml(pathStr)

    If there is no current XML object, attempts to parse the string as XML and fails if unsuccessful. If there is a current XML object, it will be reused.

    Returns a specific piece of data from the XML object, determined by the pathStr should be an action code expression or a quoted string.

    Consider a note "Source note" with this $Text:

    <shelf>
    	<book price="9.95">War and Peace</book>
    	<book price="4.95">No et Moi</book>
    	<audio price="14.95">Born To Run</audio>
    </shelf>

    Example usage of path:

    $Text("test") = $Text("Source note").xml("/shelf/book"); 

    sets $Text of note "test" to a list of children of the <shelf> element that are <book> elements. "War and Peace;No et Moi"

    $Text("test") = $Text("Source note").$Text.xml("/shelf/book[2]") 

    sets $Text of note "test" to the value of child element of the <shelf> element that represents the second book, "No et Moi". See 'Notes' below.

    $Text("test") = $Text("Source note").$Text.xml("/shelf/book@price") 

    sets $Text of note "test" to the price attribute of each book, "9.954.95"

    Notes:

    • Acceptable path content is a subset of the XPath standard (see https://www.w3.org/TR/2017/REC-xpath-31-20170321/). This explains the 'book@price' usage above to get the 'price' attribute value from a 'book' element. Explanation of XPath is out of scope for aTbRef.
    • To accord with standard XML and XPath usage, the first child of an XML node is child [1], not [0].
    • XML attributes are not related to Tinderbox attributes.
    year(aDate[, yearsNum])

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

    Operator Has Newer Dot-Operator Variant: 

     Function  [other Function type actions]

     Item  [operators of similar scope]

     Date-time  [other Date-time operators]

     Date [about Date data type]

     v5.0.0

     Baseline

     As at baseline

    Yes


    year(aDate)

    returns the year from the theDate date/time action code expression:

    $MyNumber = year($MyDate); 

    Alternatively, use Date.year.

    year(aDate,yearsNum)

    creates a new Date based on the theDate date/time action code expression, but in which the year is set by yearsNum:. For example, if $MyDate is July 4,2009, then

    $MyDate=hour($MyDate,2011); 

    will change $MyDate to July 4, 2011.

    If the output is passed back to theDate, its year element is changed

    $MyDate = year($MyDate,2011); $MyDate is changed

    but if passed to a different Date object, theDate is not altered:

    $MyDateA = year($MyDate,2011); $MyDate is unaltered
    years(startDate, endDate)

    Operator Type: 

    Operator Scope of Action: 

    Operator Purpose: 

    Operator Data Type Returned: 

    Operator First Added: 

    Operator in Current Baseline: 

    Operator Altered Since Baseline: 

     Function  [other Function type actions]

     Item  [operators of similar scope]

     Date-time  [other Date-time operators]

     Number [about Number data type]

     v6.0.0

     Baseline

     As at baseline


    years(startDate, endDate)

    returns the Number of whole years that elapsed between startDate and endDate. If endDate is earlier than startDate then the result is negative.

    If $DateA is 3 January 2016 and $DateB is 9 January 2018, then:

    $MyNumber = years($DateA,$DateB); 

    sets $MyNumber to 2.

    Action Operator Types

    Here the actions operators are listed by functional type though these are not values set by Tinderbox, simply groupings of similar action codes:

    Assignment operators

    These operators the value of the right side of action codes be applied to the left side and are the means by which attribute values are altered via code (as opposed to manual edit). They include:

    For example

    $Color = "bright red" 
    $Color = $AccentColor 
    $ResultText = $Label + " copy" 
    Color operators

    These operators let rules and actions manipulate Color-type attribute values. It can often convenient to tie the colour of a note to its properties. For example, you can make overdue notes red, with a brightness proportional to how overdue they are.

    Note that when setting a shade of a named colour in a string the shade value (lighter, darkest, etc.) comes before the colour, unlike listings in Get Info's attributes tab and the Inspector (e.g. Appearance Inspector, Interior sub-tab); thus "dark warm gray" not "warm gray dark", "light cyan" not "cyan light".

    For example:

    rgb($MyRed,255,255) 
    $Color = brightness(hue(RGB(255,0,0),120),75) 
    Data manipulation operators

    This group of operators perform utility functions enabling manipulation of text and values:

    Date-time operators

    Date accessors and manipulator operators are available for rules and actions:

    The action code method to create a date string is to call the various date-related operators.

    Date examples:

    date(2004,7,23,16,45) …is 23 July 2004 16:45 

    If $Date is July 4, 2009 then

    day($Date) …is 4

    If $Date is July 4,2009, then

    $Date=day($Date,5) 

    will change $Date to July 5, 2009.

    If $Date is July 4, 2009 then

    month($Date) …is 7

    If $Date is July 4,2009, then

    $Date=month($Date,5) 

    will change $Date to May 4, 2009.

    Note that using format() or .format() with Date or Interval data generates a String. Interval data is also expressed as a String. So, if needing a duration in days or or minutes, consider the suite of difference measuring operators: years(), months(), weeks(), days(), hours(), minutes(), seconds(). Each of these takes two Date objects and returns the difference in the type of unit in the operator name. So hours() gives the Number of hours. The number is rounded down to give the count of whole hours, days—i.e. the calling time measure).

    To get a similar unit-based measure of an Interval, use date("now") for the Date inputs but add the interval to one of them. the difference in the dates is now the interval and this can be tested with the above method. If $MyInterval is "-05:30" and $MyDate is "24/10/2022 12:00:00" (midday on 24 October 2022):

    $MyDate = $MyDate + $MyInterval; 

    results in $MyDate being 24/10/2022 11:54:30.

    $MyNumberOfMinutes = minutes($MyDate,$MyDate+$MyInterval); 

    By accepting negative intervals the same action code can deal with positive and negative durations. A more generalised approach to the last:

    $MyNumberOfMinutes = minutes(date("now"),date("now")+$MyInterval); 

    Here minutes are used but the method could test days, hours or seconds (not bigger units as Interval data is usually a few days at biggest and generally less than a whole day).

    Non-query Boolean operators

    These operators return a Boolean true/false:

    Action Operator Scope

    Action codes can also be grouped via their scope of action:

    Conditional Group-based operators

    These operators use a scope based on a group. They can work with sets or lists, retaining data type, or may use action code expressions evaluating as lists or sets.

    The group may be any designator from:

    • any designator from {children,descendants,sibling,ancestor,all}
    • a find()
    • a list-based group designator

    Such operators are:

    Document-based operators

    These operators use a scope based on the whole document which could be consider 'all' group-scope.

    Such operators are:

    Item-based operators

    These operators use a scope based on a N-item (note/path) goup or item designator:

    List-based operators

    A range of operators use a List or Set as their scope. They can work with either attribute type, retaining data type, and may use list-based group designators or find().

    The group may be any designator from:

    • any designator from {children,descendants,sibling,ancestor,all}
    • a find()
    • a list-based group designator

    Such operators are:

    Action Operator Functional Types

    Action codes can also be grouped via their functional type:

    Function actions

    These action codes operate like functions. They take one or more inputs and returns an output. Normally the latter is passed to an attribute but in a few cases, e.g. action() or runCommand(), the function may simply be called.

    Such operators are:

    Statement actions

    These actions are a small sub-set of functions where there are no arguments. Instead the operator acts as a keyword indicating code of a particular purpose will follow.

    Such operators are:

    Variable actions

    These actions are a small sub-set of system-defined variables.

    Such operators are:

    Action Operator Returned Data Types

    Action code operators generally return a value of a specific data type. In some cases the data type depends on condition at the source location and so the single type cannot consistently be predicted. A further group evaluate/return a Boolean but testing this directly is rarely the user's intent. A few others have special purposes like controlling loops, defining functions, etc:

    There groups are:

    Interval-type data

    Action codes returning Interval-type data:

    Number-type data

    Action codes returning Number-type data:

    Set-type data

    Action codes returning Set-type data:

    String-type data

    Action codes returning String-type data:

    Assignment operator

    Operators used to assign action code expression right-side values to left-side objects:

    Declaration operator

    Operators used to declare special operational terms:

    Listing of dot-operators

    'dot' operators in action code can be recognised because they:

    • start with a period character
    • are always dot-joined to an attribute or literal value (String or Number)
    • apply to a specified range of data types

    Be aware that not all dot operators work meaningfully with all data types. For instance, property operators for Color-type data (Color.red) will not return data if attached to other data types.

    The majority of dot operators relate to use of text-type data, i.e. String, List, or Set. In some cases, whilst the operator applies to more than one attribute data type, it works differently depending on the data type. A prime example is .format(), which has many data-type dependent behaviours.

    As a result where a dot operator behaves differently per chained data type it is documented separately. Thus an operator chained to a particular type, for example Date.day, will not return data if chained to other types, unless documented otherwise.

    An odd exception, that mimics dot operator behaviour but isn't a dot operator is links(). The latter using dot chained arguments, a usage that pre-dates the introduction of the dot operator behaviour.

    In aTbRef listings, dot operators will be referred to with the data type before the dot, e.g. Color.blue, so that inline dots in text do not get misread as punctuation. In practice, Color.blue would be used with any Color-type attribute:

    $MyColor.red = "#ff" 

    A Date.minute would attach to a date attribute:

    $MyNumber = $MyDate.minute 

    With text-based dot operators a wider range of use is possible:

    $MyNumber = $MyString.size() 
    $MyNumber = "Firewood, iron-ware, and cheap tin trays.".size() 
    $MyNumber = $MyList.size() 
    $MyNumber = $MySet.size() 
    $MyNumber = "Euryalus;Galatea;Hermione".size() 

    Multiple dot operators can be 'chained' to connect a series of tasks.

    The listing below shows the existing dot operators. As each is listed after the data type(s) with which it may be chained, this means some operators may be listed several times, once for each appropriate data type. The operators are:

    Listing of operators emitting styled text

    The listing below shows those operators that emit styled, not plain text (see explanation):

    Listing of operators that can use regular expressions

    The listing below shows those operators that are able to use regular expressions ('regex'). Not all require use of regex, but rather regex are allowed in some contexts. For instance, a .replace() operator's regex argument that defines what to match could be a literal string such a a particular word. Or, it can be a regex.

    For link and unlink commands the regex use only applies to selection of link types. For runCommand() it relates to parsing of the input string.

    For query efficiency in larger documents, it is generally beneficial if a first—or previous—term(s) are used to reduce the number of matches before regex operations are applied. Regex operations are potentially more CPU-intensive task (i.e. take longer than simpler tasks); very complex regex will also take more time than simple ones. The burden is individually small, but in a large document with many agents running, the sum might become noticeable. By writing efficient queries, e.g. putting regex-based operator as the last term—where the query allows, it is possible to pre-empt any such slow-down occurring.

    Regardless, the latter issues applies to large and or heavily queried documents. A new user is very unlikely to need to worry about such issue in their initial exploration of use of agents.

    Listing of operators with scoping arguments

    The listing below shows those operators where one or more arguments are scoping in nature. This means the argument is trying to pass one or more note item(s) using $Name or $Path data (Lees usual, but supported, is $ID)) or a list of items. The aim of a scoping argument is to set the scope of the action, i.e. limit as to which note(s) are affected by the action.

    Some operators support deeper evaluation than others—think of that in terms of how many nested levels of offset address arguments are included, or the number of implicit nested levels of evaluation. The variation might be from an explicit literal string for $Name or $Path, through data stored in an attribute, data stored in an attribute is a different note, to complex action code expressions. This aspect of operators is not well documented. The more complex the intended argument value, the better it is to do a small rest file first to ensure the argument is evaluated correctly before using the same in a large document.

    List of such operators:

    Listing of operators with optional arguments

    The listing below shows those operators where one or more arguments are optional. This means the these argument are not required for the operator to execute correctly. Without the optional argument(s) the operator will function correctly but will assume some defaults. These defaults may be altered by providing the optional argumet (s).

    Some operators support deeper evaluation than others—think of that in terms of how many nested levels of offset address arguments are included, or the number of implicit nested levels of evaluation. The variation might be from an explicit literal string for $Name or $Path, through data stored in an attribute, data stored in an attribute is a different note, to complex action code expressions. This aspect of operators is not well documented. The more complex the intended argument value, the better it is to do a small rest file first to ensure the argument is evaluated correctly before using the same in a large document.

    List of such operators:

    Listing of operators with conditional arguments

    The listing below shows those operators where one or more arguments are conditional. This means the argument, apart from the case of if(), acts as a further filter to a scoping argument, as items evaluating false are dropped from the the source listing (in the case of dot-operators) or scope-derived list of item processed by the action.

    Why the need for such a two-part approach of scope+condition? Early in the life of the app, the only scoping values allowed were designators which at that time did not include the ad hoc find(query) designator. Thus conditional tests allow fine tuning of a designator's scope. In many cases a find(query) used as the scope argument may obviate the need to use a conditional qualifier, but often the two part approach can be easier to write; either way the outcome can be the same.

    Some operators support deeper evaluation than others—think of that in terms of how many nested levels of offset address arguments are included, or the number of implicit nested levels of evaluation. The variation might be from an explicit literal string for $Name or $Path, through data stored in an attribute, data stored in an attribute is a different note, to complex action code expressions. This aspect of operators is not well documented. The more complex the intended argument value, the better it is to do a small rest file first to ensure the argument is evaluated correctly before using the same in a large document.

    List of such operators:

    Listing of operators with loop variables

    The listing below shows those operators that employ a user-named loop variable or loopVar. This is an in-loop placeholder for the literal value of the source list item currently being iterated upon. This when iterating through item #2 of a list, the loopVar's value is the literal value of item #2 in the source list.

    Functions are included here as, in-function, the calling arguments are accessible in the same manner as seen with a loop variable.

    Some operators support deeper evaluation than others—think of that in terms of how many nested levels of offset address arguments are included, or the number of implicit nested levels of evaluation. The variation might be from an explicit literal string for $Name or $Path, through data stored in an attribute, data stored in an attribute is a different note, to complex action code expressions. This aspect of operators is not well documented. The more complex the intended argument value, the better it is to do a small rest file first to ensure the argument is evaluated correctly before using the same in a large document.

    List of such operators:

    Problematic Characters for Action code in $Name and $Path

    If intending to do action code based creation/deletion/traversal of links in the document, it is advisable to avoid the following characters when titling notes (N.B. this list is not exhaustive):

    • / forward slash. Used as the folder delimiter in paths.
    • \ backward slash. Used as an escape character in strings.
    • ( opening and ) closing parentheses. Indicates nested expressions in action code.
    • [ opening and [ closing parentheses. Indicates list data in action code.
    • { opening and } closing parentheses. Indicates dictionary data in action code.
    • : colon. Key:Value delimiter in look-up tables and dictionaries
    • ; semi-colon. The item delimiter in lists.

    Using the above in note titles has no effect on non-action code activities.

    If a path contains slashes or parentheses, Tinderbox checks for note names that exactly match the path. For example, if the input path value is S/Z, this matches either the note Z inside container S or the note named S/Z.

    Paths containing Parentheses

    Paths containing $Names including parentheses, e.g. "Fred Smith (Jr.)", will handle correctly during concatenation. In older pre-v6 versions, parentheses caused the new string to terminate at the first parenthesis. For a note with $Name "Fred Smith (Jr.)" setting a new path:

    "/Some/Path/"+ $Name 

    …gives "/Some/Path/Fred Smith (Jr.)" unlike the old (and incorrect) "/Some/Path/Fred Smith ".

    Improved parsing

    When handling unquoted paths, as in

    create(/Sources/People/Jefferson); 

    a path with an initial "/" is recognised and treated as if it were a literal string. However, as literal paths containing commas, semicolons, or parentheses can confuse the parser. Therefore if it is necessary to include commas and semicolons and parentheses in your path names, enclose the path in quotes or store the name in a string attribute.

    create("/Sources/Martin Luther King, Jr./Speeches"); 

    More normally paths are not quoted:

    create(/Sources/Journals/Nature); 

    The same holds for attribute references

    create($MyString); 

    Use of # and @ in $Name

    By default, Tinderbox scans all note name titles on creation/edit for these characters being used as shorthand mark-up for assigning prototype and location data. This behaviour is controlled by a toggle in Document Settings ▸ General and so may be disabled if mis-detection of literal use of # and @ is occurring.

    Conditional Actions (if clauses)

    This note has been updated and moved to the action code operator list: see if().

    Counting characters in strings

    String.size and $TextLength (i.e. $Text.size) report the length of the UTF-16 representation of the text of the notes. Unicode can represent more than a million distinct characters. Most such characters count as a single character, i.e. count of +1 in String.size and $TextLength. These characters in the 'base multilingual plane 'which include most modern languages and many common symbols. They include 'invisible' characters such as spaces, line returns and tabs. This also includes:

    • Western or Eastern European languages based on Latin characters.
    • Most Central European languages and Turkish.
    • Russian (and related Cyrillic scripts), Greek, Thai, Arabic, and Hebrew.

    However, some other literal characters need more data to describe them, so-called 'double-byte' characters. Each of these counts as two characters for the purposes of String.size and $TextLength. Examples are:

    • Emoji.
    • Asian language scripts such as Chinese, Japanese, and Korean.

    Getting and setting attribute values and inheritance

    There are some things to bear in mind when setting attribute values, relating to inheritance of values:

    See also, setting document-level attribute defaults.

    Setting an attribute to (no value) via code

    You can remove an attribute value by setting it to nothing (a longer explanation is below)

    $MyAttr=; 

    Note the semicolon is not quoted, even for attribute type like strings. You can also use a empty string for string types:

    $MyString=""; 

    Only the first of the syntaxes above also allows attributes that use prototype or preference settings to re-inherit these again. So, do not use an empty string as a reset value unless that is your definite need. See about resetting inheritance for more detail.

    To explain the syntax further, you are effectively doing this to 'reset' an attribute to default inherited value:

    $MyAttr= 

    …and then explicitly then adding a semi-colon to close the action, thus…

    $MyAttr=; 

    Note that the semi-colon is not part of the reset action. So the last-but-one code above, even if used as a rule on its own, will work but is not recommended. The additional semi-colon makes sure Tinderbox does not have to guess your intent and also avoids you having to later remember to add a semi-colon if you add more code on the end of the original unclosed action code expression.

    Setting an attribute to re-enable inheritance via code

    Once an attribute has been explicitly set (i.e. not via inheritance) to a non-default value, Tinderbox inheritance no longer occurs. This is deliberate, the rationale being that the user wants that note's attribute to retain the value; maintaining inheritance might cause the user-set value to be unintentionally over-written.

    This can catch out the new user when prototypes are in use. One of the strengths of prototypes is that a change to the prototype is instantly imposed on all notes using that prototype except where a note's attribute has been explicitly changed.

    A very simplistic example might be where a prototype sets note $Color, e.g. 'blue'. If the user sets a note using the prototype to $Color 'green', if the prototype's $Color is then changed to 'red' all the other note's using the prototype will go red, but not the one explicitly changed to green. Many new users would expect them all to go red.

    So, fine if the user wanted to take an attribute out of the inheritance stream. But, what if it was a mistake? In the above scenario, if the user reset the changed note's $Color back to 'blue' would inheritance re-occur? No. That is because whilst the inherited colour is 'green', an explicitly set value is still seen as an explicitly set (i.e. non-inherited) value even if the same as the notional inherited value.

    An easy way to confirm if an attribute value for a particular note is inherited or not is to view the attribute either as a Displayed Attribute or in the note's Get Info/Attributes tab (Cmd+Opt+i). Attributes being inherited are listed in normal weight text and those locally set in the note are shown in bold text.

    How is inheritance re-enabled?

    The trick is to set the attribute value to no value, something you cannot do by typing directly into a value input box (e.g. as in Displayed Attributes or Get Info tables). There are several approaches that can be used and which may appeal to different users' styles of work. The resetting process can be done in a number of ways:

    • Use the Quickstamp Inspector. Select the note(s) and use Method 1 below.
    • Use Get Info's (Cmd+Opt+i). Select the note and use Method 2 below.
    • In an action or rule, using method 3 below.
    • Menu 'normal' option in some pop-ups, see method 4 below.

    Method 1: Use the Inspector (works for all currently selected items)

    To change a single attribute for all selected note(s):

    *Open the Properties Inspector, Quickstamp tab

    *Do either of:

    **Choose the Attribute Group from the top pop-up and then the desired attribute from the second-pop-up.

    **Use the Search box and select the desired attribute from this of matches.

    • Click the left button above the value box.

    To change a multiple attributes, repeat the above process for each attribute in turn.

    Method 2: Use Info view (works for current single item only)

    To change a single attribute for a single note:

    *Open Get Info, attributes tab (Cmd+Opt+i)

    *Do either of:

    **Choose the Attribute Group from the top pop-up and then the desired attribute from the second-pop-up.

    **Use the Search box and select the desired attribute from this of matches.

    *Select the line of the table for the desired attribute.

    *Right-click and select the 'Use Inherited Value' menu item. The attribute name and value will revert from bold text to normal text.

    To change a multiple attributes, repeat the above process for each attribute in turn.

    Method 3: Use Code (in an attribute or stamp)

    Code can be run as a $Rule or $AgentAction or within a stamp.

    To set any data-type of attribute to its inherited value:

    $MyAttribute=; 

    Note that no quotes are used around the semicolon. The above is not the same as simply setting a string to empty or a number to zero. Why? Because the latter is simply setting that value locally and thus still blocking inheritance.

    If needing to reset a long list of attributes, consider using a list and loop.

    Method 4: Use menu 'normal' options

    A number of menus, pop-ups and context menus for setting values have a 'normal' item at the top of their value listing. For example, this can be seen with menus for setting $Color or $Badge. In any of these, clicking the 'normal' option will reset the local attribute to re-inherit values.

    Short Boolean form for testing attribute values

    It is possible to cite attribute tests in both a long form:

    if($MyBoolean == true) 
    if($MyBoolean != true) 

    or a simple short form:

    if($MyBoolean) 
    if(!$MyBoolean) 

    Note in the negative version the '!' moves in front of the attribute name (and the $-prefix). Thus !$MyString means $MyString has no value set whilst !$Name(Test) causes a reverse query where all note's whose title does not include the string "Test" are matched.

    Though the short form is primarily for Boolean attributes, where another data type can be coerced to a true/false equivalent the short form may be tried. The coercion being tested depends on the attribute type's default value. Any value other than the default, results in a coercion of true. $ChildCount is a number type attribute so the default is zero. Both the code examples below equate to the same test but the latter is shorter, thus useful in longer, more complex action code expressions.

    if($ChildCount > 0) {… if($ChildCount) {…

    The converse would be:

    if($ChildCount < 1) {… if(!$ChildCount) {…

    Note that the short Boolean form, whilst coercing non-Boolean type values to a true/false occurs it is not testing whether the default value is inherited or was explicitly set; see also use of the |= operator.

    Delaying code execution in prototypes and notes using prototypes

    When using pre-planned structural prototypes, i.e. those stored apart from actual content and with no purpose other than as a means to configure other content notes, consideration should be given to whether action code such as found in in Action-type attributes is run in the prototype itself, or should be suppressed there and only run in a note inheriting from the prototype. This scenario affects code placed in the Action-type attributes (e.g. via their create/rename dialog boxes):

    • $OnAdd
    • $Rule
    • $AgentAction (agents only)
    • $DisplayExpression
    • $TableExpression

    In large or complex documents, it is possible to end up with many notes using the same prototype. If the later has a complex $Rule or $DisplayExpression, this can place quite a loading on the speed with which the cycle of running action code is completed. These two action attributes attributes have additional special system attributes specifically to suppress prototype-based executions a result the attributes $RuleDisabled or $DisplayExpressionDisabled are intrinsic: setting them in the prototype has no effect as these attributes are inherent and not inherited by notes using the prototype.

    Controlling use of inherited complex actions

    Thus, in some cases it is desirable to delay code execution as the code is written with the intention of running in an inherited context, using actual data from the inheriting note, but only when intended. This scenario requires a different approach. One method is to make the action in inheriting notes check the disablement state in their prototype. This example is for a rule:

        if($RuleDisabled($Prototype)){
            if($MyNum>0){
                $Color="bright red"
            }else{
                $Color=;
            };
        }

    However, be aware the rule still exists and the outer if() condition is still evaluated, so this approach does not remove the rule entirely. For actions with no disablement attribute, consider the same but using a user Boolean attribute set in the prototype.

    Another example:

        if(!$IsPrototype){
            $AgentQuery="Topics("+$Name+")";
        }

    The above ensures that, in a prototype agent, the agent's query is not set within the prototype whereas in all agents inheriting from the prototype the query will be set. The need for a wrapping if() conditional test becomes clearer with this rule:

        if(!$IsPrototype){
            $AgentQuery="Topics("+$Name+")";
            $Rule="";
    }

    Without the if() test, the latter rule would run and delete itself within the prototype and never set anything in the inheriting agents.

    Note too, that if using self-deleting rules via a prototype the act of clearing the rule breaks inheritance for the $Rule attribute.

    Using multiple prototypes

    Another method for switching complex actions on/off is to use prototypes for the existing prototype. For instance, in the example of a complex rule, keep the existing prototype but cut the rule code and move it to a new, otherwise un-customised prototype. Now, to turn the rule on, set the $Prototype of the existing prototype to the name of the new one; this causes it to inherit the rule. Resetting the $Prototype value to the default (nothing) causes the main prototype to inherit the default $Rule, i.e. nothing. Be aware that this method only really works for turning one attribute (i.e. rule or edict) on or off, or if multiple actions (e.g. both rule and edict) are to always enabled/disabled at the same time.

    Stream Processing and parsing

    Tinderbox's string processing operators are intended to help extract information from structured and semi-structured text. Such text may be hand-typed, for copied from sources like email. Often, it may be imported from other programs or downloaded from web services into a Tinderbox attribute. The need is to extract needed information from this text.

    Tinderbox does not handle true streams, i.e. continuously reading an API output in real time. But in its 'stream processing' Tinderbox is behaving in the same manner. A key point is the stream is read by moving forward, never backwards—the process essentially forgets the already precessed parts of the stream. While the overall process can be run again on the same source, e.g. a note's $Text, within a running stream parse, it cannot move/look backwards in the source ('stream').

    'Stream' parsing uses 'lines' of text. Importantly this isn't a line as seen on screen but content between the start, each line break and end. In lay terms, a paragraph of text is a 'line'. Understanding this is important to following how stream parsing goes about its task.

    Regular expressions. Be aware that stream processing operators do not use regular expressions (regex), except in clearly marked exceptions. If regex are needed to complete the task, either use ordinary String processing operators or insert appropriate delimiters into the text before processing.

    Processing a text as if it were a stream

    Broadly speaking, the parsing approach is to begin at the start of the string and proceed, step by step, following a recipe (of chained dot-operators). For example, such a 'recipe' might say:

    • Read until you find a line that begins with "To:", "From:", or "Subject:"
    • If you find a "To:", copy everything character following that up to the first space character encountered and save the copy in at the current note's $Email.
    • If you find a "From:", copy everything character following that up to the first space character encountered and save the copy in at the current note's $EmailFrom.
    • If you find a "Subject:", get the rest of the current line and use that for the $Name of the current note.
    • Having found a "Subject:, delete all the headers you have processed and leave the rest of the text.
    • If you never find a "Subject:", do not delete anything.

    All functional string processing operators accept a string, in this documentation called the stream, of text being processed. In the majority of, but not all, cases this is likely to be a note's $Text, or an attribute/variable value based on some of $Text.

    Stream processors act in some way on the stream possibly saving some data into an attribute or simply moving further forward (left-to-right) and returning the unprocessed remainder (right-most portion of the stream) which may be passed to another operators such as further chained dot-operators. For example, $MyString holds string "We think there may be 1234 items":

    $MyString.skip(22).captureNumber("MyNumber"); 

    takes the value of MyString, skips exactly 22 characters, and extracts a number—and only Number-type data— to be stored in $MyNumber. For instance, :

    $MyString.skip(22).captureNumber("MyNumber"); 

    $MyNumber is 1234. But if MyString holds string "We think there may be 1,234 items" then $MyNumber is 1 as a comma follows the first number (after the skip operator consumes the first 22 characters.).

    The parsing operators can best be understood as a series of discrete roles:

    Expect operators

    The expect family of operators looks at the current place in the text stream to ensure that the text is what you expect it to be.

    String.expect("matchString")

    Tests that the next characters in the stream are a literal string "matchString", and advances the stream beyond "matchString". Otherwise, a failure occurs and parsing ceases.

    String.expectWhitespace

    Tests that the next characters in the stream are whitespace, such as spaces, tabs, and carriage returns (i.e. 'whitespace' as in regular expression terms). It advances the stream to the first non-whitespace character. A failure occurs if the next character is not whitespace.

    String.expectNumber

    Tests that the next characters in the stream can be interpreted as a number. Numbers include "0", "5.7", and "-13". Skips over the number. A failure occurs if the next character is not part of a number.

    String.expectWord

    Tests that the next character is not whitespace, punctuation, or a digit. Skips to the next whitespace, punctuation, or digit. Otherwise, a failure occurs and parsing ceases.

    Skip operators

    The skip operators advance the current position of the stream.

    String.skip(N)

    Skips the stream forward exactly n characters. A failure occurs if N reaches past the end of the stream.

    String.skipTo("match string")

    Advances the stream to the first occurrence of the target match string (which is not a regular expression regex), skipping over the target string so the stream parsing position now sits after the match. A failure occurs if the target is not found. An alternative, that supports regex is String.extract().

    String.skipWhitespace

    Advances the stream to the first character that is not whitespace. A failure occurs if the stream is exhausted.

    String.skipToNumber

    Advances the stream to the next number (i.e. one of more continuous number characters). A failure occurs if the stream is exhausted.

    String.skipLine

    Skips forward to the next carriage return or to the end of the stream.

    Capture operators

    The capture family of operators extract a chunk of information from the stream and store them in a target attribute. The target attribute may be the source of the stream, in which case the parse will cease at the first capture.

    String.captureLine[("targetAttribute")]

    Captures text from the current stream position, up to the next line ending or the end of the stream. The text is stored in the designated targetAttribute, and the stream advances to the character following the line break.

    String.captureNumber[("targetAttribute")]

    Captures a number from the current steam position, up to the next character that cannot be considered part of a number; the capture is passed targetAttribute. Advances the stream to that character. A failure occurs if the stream cannot be interpreted as a number.

    String.captureWord[("targetAttribute")]

    Captures text from the current stream position up to the next character that is a digit, whitespace, or punctuation; the capture is passed targetAttribute. Fails if the stream is empty or begins with a digit, whitespace, or punctuation.

    String.captureTo[("string","targetAttribute")]

    Stores the string up to but not including the designated literal string (it is not a regular expression) in the designated attribute, and returns the string that follows string. An alternative, that supports regex is String.extract().

    String.captureToken[("targetAttribute")]

    If the string contains a token specified by a prior parsing operator, the token itself is passed to targetAttribute. The stream is not advanced and any chained parsing continues from the same point.

    String.captureRest[("targetAttribute")]

    Captures the rest of the stream in as the value of targetAttribute, and returns the empty string.

    String.captureXML

    Attempts to parse the string as fully/partially XML and fails if unsuccessful. The parsed XML is saved as the current XML (stream) object. Essentially, this re-scopes the current stream so that it contains only the contents of the first section of XML detected within the original stream. The focus of the stream parsing is set to the beginning of the extracted XML code. Only one XML object may be current at any time. If the source stream contains multiple discrete XML code sections, only the first is detected/used.

    String.captureJson()

    Attempts to parse the string as fully/partially JSON and fails if unsuccessful. The parsed JSON is saved as the current JSON (stream) object. Essentially, this re-scopes the current stream so that it contains only the contents of the first section of JSON detected within the original stream. The focus of the stream parsing is set to the beginning of the extracted JSON code. Only one JSON object may be current at any time. If the source stream contains multiple discrete JSON code sections, only the first is detected/used.

    Functional control structure operators

    Functional control structure

    These control structures are used with functional stream processing.

    String.eachLine(x[:condition]){action}

    The .eachLine(){} operator allows iteration through each line of a string, performing an action on each. For attributes like $Text, a line equates to a paragraph as the delimiter is a line break character.

    String.try{action}[.thenTry{action}]

    Saves the value of an attribute and attempts an action. If the action fails because one of its operators fails or the fail() operator is performed, the value of the attribute used as a stream source

    A .try{} may be followed by one or more .thenTry{} clauses. If the original .try{} succeeded, all subsequent .thenTry{} clauses are ignored. If the original .try{} failed, then each .thenTry{} is attempted in turn. Once a .thenTry{} clause succeeds, subsequent .thenTry{} clauses are ignored.

    String.failed()

    tests for a failed stream processing action, e.g. using Stream.try{}. Its use include an explicit fail() call.

    Processing a stream for JSON

    If a string contains only JSON, or has a single JSON code section which start the string, it can be autodetected so specific stream parsing is not needed. Initial stream parsing is needed if:

    • the JSON does not start the string, but has other non-JSON content before it.
    • the there are several discrete sections of JSON code embedded in the string and a specific section is needed.

    In these scenarios, normal string parsing operators can be used to advance the stream parsing cursor to the start of the desired code and then use String.captureJson(), to capture the whole JSON code segment detected at that point. Note the code is only ever of one continuous section of JSON code even if others lie further along in the stream after other sections of non-code text.

    See more on JSON processing.

    Processing a stream for XML

    If a string contains only XML, or has a single XML code section which start the string, it can be autodetected so specific stream parsing is not needed. Initial stream parsing is needed if:

    • the XML does not start the string, but has other non-XML content before it.
    • the there are several discrete sections of XML code embedded in the string and a specific section is needed.

    In these scenarios, normal string parsing operators can be used to advance the stream parsing cursor to the start of the desired code and then use String.captureXML() to capture the whole XML code segment detected at that point. Note the code captured is only ever from one continuous section of XML code even if others lie further along in the stream after other sections of non-code text.

    See more on XML processing.

    JSON processing

    Tinderbox can process JSON stored in any string attribute, including $Text, or String-type variable. JSON dot-operators are expecting the whole contents of the stream to be a valid JSON object.

    JSON.json[key]

    If there is no current JSON object, attempts to parse the string as JSON and fails if unsuccessful. If there is a current JSON object, that object will be reused. If the top-level element is an object, JSON.json[key] returns a dictionary for that object.

    JSON.json[N]

    If there is no current JSON object, attempts to parse the string as JSON and fails if unsuccessful. If there is a current JSON object, that object will be reused. If the top-level element is an array, JSON.json[N] returns the Nth object.

    JSON.json.each{action}

    If the top-level element is an array, rebinds the JSON object in turn to each array element. After calling the action block for each element, the JSON object is restored.

    JSON.jsonValue().

    String.captureJson()

    Attempts to parse the Stream's string and re-scope it as the full contents of (only the first) JSON code detected within the text. It fails if unsuccessful.

    JSON property chaining

    JSON doesn't have a formal pathing method like XPath in XML, but JSON properties can be chained to allow navigation to nested objects. For example, consider:

    
    {
      "person": { "firstName": "Thomas", lastName: "Roe"},
      "coordinates" : [-90,41]
    }

    Thomas’s latitude can be addressed via

    $Text.json["coordinates"][0] 

    And his family name via

    $Text.json["person.lastName"]

    XML processing

    Tinderbox can process XML stored in any attribute, including $Text. XML element attributes are not related to Tinderbox attributes. XML stream operators are expecting the whole contents of the stream to be a valid XML object.

    XML.xml(path)

    Returns the value of the object at path.

    XML.each(path){action}

    Iterates the child objects at the path using an action.

    String.captureXML()

    Attempts to parse the Stream's string and re-scope it as only the (first) XML code detected within the text. It fails if unsuccessful.

    Using attributes as global variables or constants

    It may be useful to store a snippet of information, such as the local sales tax percentage or the name of a certain project in a manner such as lets any note read or set that value. In programming this method is often known a a constant or global variable.

    This is slightly different to setting an attribute default value whereby all attributes start with the same value. Using the local sales tax example above, it might be necessary to have a value of 0.05 (5%) that can then be used by any action code trying to figure a true sales total.

    This simplest method to do this is to simply place the value in an attribute (of suitable data type) in a note outside the main content. Because it is an attribute you can both fetch the value and (re-)set it. Things to consider:

    • place such value placeholder notes away from your main content so they do not accidentally get edited, e.g. in a separate branch of the root.
    • for map users, place variable notes off away on the side of the map.
    • give the notes unique names, allowing them to referred to by $Name alone. Otherwise, you will need to cite their $Path instead. In the case of the latter, consider keeping the path short
    • a note can hold one 'variable' or several, assuming each is kept in a separate attribute. Which makes most sense is mainly down to personal choice.
    • you do not need to make a $SalesTax attribute just to hold the sales tax variable. Again whether you do so is a matter of personal style; there is no right or wrong way.
    • if you have, a lot of number variables, it probably makes less sense to gives them each an attribute. Rather, use something like $NumberVariable, and store each variable in that attribute within a suitably named notes, allowing you to reference things in a manner like $NumberVariable(varLocal_Sales_Tax)
    • if you are worried about user accident or code error changing an important constant value, set the note's $ReadOnly attribute to true as this stops the note's attributes changing.

    Chaining 'dot' operators

    Where pertinent, 'dot' operators (operators prefaced with a period—see listing), like String.split(), can be chained together. If an operator's parentheses are normally optional, they be omitted if that operator has another operator chained to its right. Thus:

    $MyList.sort().reverse() GOOD
    $MyList.sort().reverse GOOD
    $MyList.sort.reverse() GOOD
    $MyList.sort.reverse GOOD

    The observation "where pertinent" points to the fact that the dot operators used must act on compatible data types:

    $MyList.sort().reverse() GOOD
    $MyColor.red().empty() BAD

    It is most likely that opportunities for chaining only occur in relation to text data functions though do be aware that some text dot operators are only for lists/sets and some only for string even though others cover both types of data.

    Chaining to parentheses

    It is possible to chain to parentheses and indeed is sometimes necessary. The parentheses ensure Tinderbox evaluates contents of parentheses before the dot-chained actions are applied. In this example, three strings are concatenated to a single string before its size (number of characters) is calculated:

    (Hello" +" "+"world").size 

    The above example is trivial but shows the general principle. In practice, the technique can become useful if the action code expression is complex and requires Tinderbox to fully evaluate it before processing the chained function. For instance, the links() operator already uses dot-chained arguments and so to find the number of links found using .size, it is necessary to place the whole links() expression in parentheses:

    (links(children).inbound..$StartDate).size 

    Look-up tables

    (NOTE: The prefix 'list' may be used interchangeably here with 'table'. Thus, 'look-up list' and 'look-up table' are describing the same thing.)

    Look-up tables, are listings of key:value pair items allowing simple value arrays (more formally called a one-dimensional array).

    See also: Dictionary-type attributes

    Since look-up tables were added, Tinderbox added the Dictionary data type. It too holds key:value pairs but Dictionary-type attribute offer extra affordances for creating/editing data via action code.

    In many cases, if starting from new, a Dictionary may well be a better choice than a List for this purpose.

    Look-up table functional example

    For those without a coding background, this is more easily understood by use of a simple example. Thus, suppose some notes record the US state (in attribute $State) in which each customer resides. Each state is also assigned to on of a number of a regions and it is useful to know the sales region ($Region) for given customer's home $State. Before support for look-up tables, a usual approach—to avoid hard coding each note's $Region—would be via use of conditional if() statements:

    if($State=="AL") { $Region = "South";} 

    However, this is a tedious process if there are many states as it needs a lot of if() statements, at least 50 in this case!

    To use a look-up table for mapping $State to $Region, we make just one listing of colon-joined key:value pairs, separated by colons, thus: Key1:Value1;Key2:Value2. For example:

    $RegionList=[AL:South;AK:NorthWest] 

    Several data types can be used to store look-up tables, and that aspect of use is discussed further below

    Limitations on key and value definition

    A key is:

    • case-sensitive
    • must be unique to the listing
    • ought not to consist of numbers only as this may confuse Tinderbox (is it a key value or the item number in the list?)
      • should there be a need to use numbered keys, e.g. if generating the look-up key based on a computed value, place a letter before the number. So, use 'x1' rather than just '1'.

    A value may be the same as values for different keys within the current listing.

    Accessing look-up table values

    Look-up tables are interrogated using the .lookup("key") operator like so:

    $RegionListing=[AL:South;AK:NorthWest]; 
    $Region=$RegionListing.lookup("AL"); 

    sets a $Region value of "South".

    Optional default value for missing keys

    If the look-up table does not contain the supplied key value, .lookup() then looks for an optional special default key (default, case-sensitive) and returns that key's value or if none is found, an empty string is returned (if the 'default' key exists but has no value, an empty string is returned). So:

    $RegionListing=[AL:South;AK:NorthWest]; 
    $Region=$RegionList.lookup("CT"); 

    gives a nil value of "" as there is no matching key 'CT'. If the option 'default' key is added to the look-up table:

    $RegionList=[AL:South;AK:NorthWest;default:Unknown]; 

    Then

    $Region=$RegionList.lookup("CT"); 

    sets $Region to "Unknown".

    The key input argument can be evaluated. Thus if attribute $State has a value "AL", then:

    $Region=$RegionList.lookup($State); 

    sets a $Region value of "South".

    Alternate keys, same value

    Lookup tables are able to specify several keys that map to a common value. This is done by separating each key with the pipe character '|'. For example:

    [Oliver|Micawber|Pip:Dickens;Tess:Hardy;Palliser|Finn:Trollope;default:anon] 

    A structural representation of the above example is as follows, with each key:value pairing on a separate line for clarity.

    Key1-1|Key1-2|Key1-3:Value1;
    Key2-1:Value2;
    Key3-1|Key3-2:Value3;
    default:anon

    The number of keys in each Key/Value set is discrete from other sets in the list: 3 keys map to Value1, one to Value2, two to Value 3 and default has one value..

    Keys are matched on exact, case-sensitive, strings. In the above example "Tess" will return "Hardy" but "tess", "Tes" or "Tessa" would return "anon". If no default had been defined, an empty string "" would be returned instead for the non-matching values.

    Lexical and numerical ranges for keys, same value

    Lookup tables also permit ranges (based on case-sensitive lexical sort based matching). For example, suppose the value of $MyList is:

    [Alaska-Connecticut: 1; Delaware-Nebraska: 2; default: 3] 

    Then $MyList.lookup("Alabama") would return string "1", and $MyList.at("Illinois") would return "2". However, $MyList.lookup("alabama") returns "3" due to the way Tinderbox lexical sort works, as would. Note too, that in this case $MyList.lookup("Manitoba") would return "2" as "Manitoba" lexically sorts between "Delaware" and "Nebraska": Tinderbox has no way to know Manitoba is a Canadian province rather than a US state.

    Lookup tables can also work with numeric ranges. If $MyList is:

    [0-10: red; 10-20: blue; default: green] 

    Then $MyList.lookup(5.0) returns 'red'. Note that $MyList.lookup(5) (N.B. an integer without a decimal point matches the key "5". Thus if the actual key is "5" use "5.0" to trigger the first behaviour.

    What data type to use for storing look-up tables?

    When the feature of look-up tables was first added, the Dictionary data type did not exist, so a List or Set was suggested. Sets, make more sense than lists are they avoid unintentional duplicates. Legacy: not that prev9.5.0 using List.unique() to de-duplicate a list re-sorts that list. As a result either a Set or Dictionary type attribute is suggested for holding a look-up table. List type may also be used, but attention should be given to accidental key duplication.

    For Dictionary type, as long as used with .lookup() rather than the normal Dictionary["key"] access methods, a Dictionary supports all the above advanced look-up table behaviours (alternate keys, key ranges).

    Storing the look-up table in one location

    In the first above example, the look-up table listing is stored in the note being tested, for simplicity of explanation and learning. But, in reality, this same list may need to be used in hundreds of different notes. Luckily this is easily done by defining the look-up list as a global value, once, in a single note and then referenced from all others by an offset attribute reference, i.e. using $AttributeName(name) or $AttributeName(path). If using this technique chose a unique note $Name, you will need to use the full $Path on the offset.

    Thus these examples are more representative of real-world use:

    $Region=$RegionListing("config").lookup("AL") 
    $Region=$RegionListing("config").lookup($State) 

    Noting the point about the name of the note, it may make more sense to use a deliberately unique name that also implies the note's purpose. So:

    $Region=$RegionList("lt_States").lookup("AL") 

    A note called 'lt_States' ('lt' for 'look-up table'), will stand out in action code and imply a look-up table is being referenced and when revisited months later the note's $Name may remind us as to its purpose.

    Actions, Stamps and Quickstamps

    A Tinderbox document has a number of ways to change attribute values. First it is useful to draw a distinction between the following:

    • a literal value. This is the actual stored value of an attribute and as seen when displayed in contexts like a note's Displayed Attributes table.
    • an evaluated value based on action code. Here it is code that is stored and then evaluated when applied so as to render a literal (above) stored value.

    Attribute value changes can happen in various contexts:

    • via action code (also allows literal value input)
      • container-based:
        • OnAdd action
        • OnRemove
        • Agent action.
      • selection-based (note: selected items do not need to be in the same container):
        • Stamp.
    • via literal value of an attribute:
      • selection-based (note: selected items do not need to be in the same container):
        • Quickstamp.
      • single item only:
        • Get Info/attributes.
        • Displayed Attributes.

    OnAdd

    This an action applied once to each note that is added to, or created in, a container note. The OnAdd action also takes effect when the note containing the on-add code is converted into a container: that is, when another note (or notes) is dragged onto it, creating new child notes. In the latter case the OnAdd is applied to the newly added/created note after it has been moved in situ; this is important so code evaluating things like the parent note's title are resolved correctly.

    If a selection of multiple notes are moved into a container, the same action is run once on each discrete note. Removing a note from a container does not trigger this action but see the OnRemove action below. Map adornments also have an OnAdd that is run when note(s) are moved onto an adornment.

    The OnAdd action is stored in a note's $OnAdd attribute. The action can be manually set via the Action Inspector's Action tab, Get Info's attributes/General tab, or by displaying $OnAdd as a displayed attribute. Otherwise, the attribute can be set via any action code method, such as stamps or quickstamp.

    OnRemove

    The action is the mirror opposite of OnAdd and is an action applied once to each note that is removed from, or deleted from, a container. Map adornments also have an OnRemove action.

    Agents also have an OnRemove action but note that it is applied to an alias of a note, so pay attention if altering intrinsic attributes.

    Note: As this action is a much more recent feature than OnAdd, older articles & tutorials on actions my (now) incorrectly state that the is no remove action.

    The OnRemove action is stored in a note's $OnRemove attribute. The action can be manually set via the Action Inspector's Remove tab, Get Info's attributes/General tab, or by displaying $OnRemove as a displayed attribute. Otherwise, the attribute can be set via any action code method, such as stamps or quickstamp.

    OnJoin

    This action is evaluated when a note is first added to a composite. If an existing composite note is touched by the drag and it has $OnJoin code, it is run upon the newly joined note.

    OnVisit

    The $OnVisit action is primarily for Storyspace compatibility but may be used as an 'Upon Selection' event trigger.

    Agent action

    Agents have no OnAdd action, but instead an agent 'action' and this also functions slightly differently. The agent action is run on each discrete child alias in an agent, but is run every cycle of the agent update.

    The agent action is stored in a note's $AgentAction attribute. The action can be manually set via the Action Inspector's Action tab, the AgentAction box of Get Info's agent1 tab Get Info's attributes/Agent tab, or by displaying $AgentAction as a Displayed Attributes. Otherwise, the attribute can be set via any action code method, such as stamps or quickstamp.

    Note: although an agent can ostensibly have an $OnAdd attribute value, it is never used. If a selection includes both notes and agents and the Action Inspector's Action tab has code added, Tinderbox will apply the code to $OnAdd or $AgentAction as appropriate.

    Stamp

    A stamp is one or more complete action code expressions (i.e. complete actions) stored for ad hoc use. Stamps are created and saved via the Document Inspector's Stamps. Once created, a stamp can be applied from this Inspector, by clicking the stamp's name in the Stamps menu, or can be called via action code. All the stamps for a document are stored in the document's TBX file

    When used a stamp is applied once only to each selected item. This can be a useful alternative to an agent if the code is needed only occasionally. By applying a stamp to an alias inside an agent, the stamp can be used to simulate/test a possible agent action whilst acting on a single item.

    Quickstamp

    A Quickstamp is a fast method to (re-)set the value once for a single attribute for every note currently selected. Unlike the methods above, Quickstamp can only change the literal value of an attribute, i.e. the input cannot be action code but must be the actual final value itself. Also, unlike a stamp, the applied value is not saved, e.g. for later re-use, and cannot act on more than one selected attribute at a time. Quickstamp can only be used via the Properties Inspector's Quickstamp tab.

    One small exception to the literal value rule in Quickstamp is that if the selected attribute is Date-type, date designators are evaluated when entered (i.e. 'now' will become a date/time string in the Quickstamp value input box when return is entered, the latter string then being applied when the Apply button is pressed. However, this is a niche exception to the general fact that Quickstamp is intended for inserting literal values.

    Get Info/attributes & Displayed Attributes

    These offer different UI routes to the same interaction by changing the literal value of a single attribute in a single selected item. In each case the user selects the desired attribute and manually edits the actual value. UI: Get Info/attributes, Displayed Attributes.

    Unlike Quickstamp, the context menu in these input UIs does offer an 'evaluate' method which will evaluate action code in the input box and replace it with a literal value. Although this allows use of (simple) code on an ad hoc basis, the primary edit means of these UIs is attribute literal values.

    Self-Cancelling Rules & Actions

    By setting an action or rule to nothing as the last of a set of chained tasks, it can be self-cancelling. This can be done as part of the rule/action itself and can help to avoid unwanted repetition/looping. It is more normally needed with rules than actions as rules run every agent update cycle.

    Consider this rule code:

    $Color="blue";$Rule=""; 

    When the rule is run, the note's $Color is set to 'blue' and the $Rule is set to nothing. Thus the $Color assignment is run once-only before the rule ceases to exist. However, the above only sets the Rule to no value, it does not re-enable inheritance. For that a slightly different syntax is needed:

    $Color="blue";$Rule=; 

    Using regular expression back-references

    Using parentheses within a regular expression regex, it is possible to set up to nine back-references from within the overall regex. These discrete sub-matches can then be used in the action connected with the query. The most normal means of setting a regex with back-references is by using the operators String.contains() or String.icontains().

    Back-references can be used in actions in several contexts:

    • Most obvious is within an agent's action (referencing the agent's query).
    • Within general action code:
      • with the if(query){actions} conditional action, back-references for the conditional query can be used within any action(s) enclosed within the operators' {} brackets—in both the 'if' and 'else' branches.
      • although not formally queries, the action String.replace(regex,replacement) can set back-references in the first (regex) input argument. The regex can be a literal string or a regular expression and, if so, then the back-references it creates can then be used within operator's second (replacement) argument.

    Exceptions:

    • Although Macros use the same back-reference style of notation for inserting content, in that case the values are drawn from the macro's input arguments rather than from a regex.
    • Whilst the find() action operator uses queries, the operator uses this to return the paths of matching notes and therefore does not support regex back-references.

    if(){…} and if(){…} else {…} restore regular expression back-references ($1, $2…) to their state prior to the next if() statement.

    IMPORTANT: The examples below are not intended to teach how regex work but simply to illustrate how back-references are used once created.

    Referring to a back-reference

    The method of referring to a back-reference is via a $-prefixed number, $0 through $9. The back-reference $0 always refers to the the whole matched string (or sub-string) for the stated query regex, i.e. it may match all or part of the target string. $1 to $9 refer to any defined back-references within the overall regex, as discussed in examples below.

    Back-references are returned (i.e. number-referenced) in the order created. The order is usually left-to right in order the parentheses open (note this allows for nesting) but to understand that process better, read up on regular expression back-references.

    Do back-references need quoting? No, if $MyString is "This or that", all the following result in a value of "This and that":

    $MyString=$MyString.replace("(^.+)or(.+$)","$1and$2"); 
    $MyString=$MyString.replace("(^.+)or(.+$)","$1"+"and"+"$2"); 
    $MyString=$MyString.replace("(^.+)or(.+$)", $1+"and"+$2); 

    Back-references 1: in an agent context

    This is an example of an agent query designed to create back-references that can then be used in the agent's query:

    query: $Text.contains("email: (\w+([,| |-]*\w*)*)\<([^>]+)\>, on (\d+/\d+/\d+)")

    action: $FullName=$1; $Email=$3

    The action will set the value of attributes $FullName and $Email using the back-references to regex found in the currently focused notes $Text (well strictly, the note's alias as this is an agent). So, for a worked example, if the $Text was:

    	Project X
    	Brief discussion to finalise resources allocation
    	Source email: John Doe<johndoe@example.com>, on 24/03/2010
    	Follow up actions: Bob, Mary.

    …then the above query would give the following back-references:

    • $0: email: John Doe, on 24/03/2010 (i.e. the full matched sub-string within the source text—i.e. not necessarily all of that text).
    • $1: John Doe i.e. the contents of the first parentheses-delimited code \w+([,| |-]*\w*)* (note the nested parentheses to deal with names of two or more words.
    • $2: Empty, nested inside $1 it serves to capture second and subsequent words in $1. See below for more on nesting back-reference groups.
    • $3: johndoe@example.com i.e. the contents of the third parentheses-delimited section of code [^>]+ 
    • $4: 24/03/2010 i.e. the contents of the fourth parentheses-delimited section of code \d+/\d+/\d+
    • ($5 through $9: returns nothing, as they have no source match defined.)

    Back-references 2: using if(){}

    Using the same examples as above, an if() usage might look like this (the line breaks are not significant and only for clarity of reading here):

    	if($Text.contains("Emailed by: (\w+([,| |-]*\w*)*)<([^>]+)>, on (\d+/\d+/\d+)")){
    		$MyString=$0;
    		$FullName=$1;
    		$Email=$3;
    		$StartDate=date($4);
    	};

    In this method the if() operator holds the query and generates the back-references. These can be used anywhere within, but only within the operators { } curly braces enclosing the action code. The back-reference could be used in the else { } branch, but the nature of the overall usage (i.e. for back-reference generation) means this is unlikely.

    See if() for further back-reference usage examples.

    Back-references 3: using string.replace()

    The use of string.replace() is to replace part of an existing current string attribute value. The operator can be thought of in terms of $SourceDataString("query","return string") where the "return string" might be one or more back references form the query and may include string literals.

    For example, assume $MyString has the value of "AABBCC", from which it is desired to make a value of "BB". Essentially this means deleting all the non-'B' characters. This can be done by capturing the 'B's in a back-reference and using that to replace the original value. Thus to replace the original $MyString value:

    $MyString = $MyString.replace(".*(BB).*","$1"); 

    Note the $1 back-reference must be inside quotes for the second argument to work. Alternatively, the altered string can be saved to a different attribute, leaving $MyString unchanged

    $AnotherString = $MyString.replace(".*(BB).*","$1"); 

    The back-references created here cannot be used except in the second input ('replacement') argument. Clearly, the applications for using string.replace() are far more limited than when using an if() statement.

    See String.replace() for further examples of use of back-references within an action context.

    Nesting back-references

    Back-references may be nested is side one another (as seen in the opening example above):

    Query: $Name.contains("(a(ard))v(ark)")
    Action: $MyString =$1; $MyStringA = $2; $MyStringB = $3;

    For the matched note the 3 attributes set by the action will hold, in order, "aard", "ard" and "ark". This shows back-references are numbered in the order encountered running left to right and not by some other system such as the level of nesting.

    Literal parentheses

    Literal parentheses in regexs must be escaped by a backslash. To match "this (that) other", use:

    $Text.contains("this \(that\) other") 

    To capture "(that)" as back-reference $1:

    $Text.contains("this (\(that\)) other") 

    Sometimes parentheses are needed, e.g. in the agent example shown earlier above, in order to achieve the right match, but which do not match anything meaningful to back-reference use. Do not worry about that, you do not need to use every back-reference created.

    What is the role of $0?

    $0 is always the whole matched (sub-)string for the stated attribute value but if the regex regex creates additional back-references within the query then $1 through $9 may be used to access those additional match sub-strings.

    In this case above, $0 is not all of the current note's $Text, the overall source for the query, but rather it is all the text matched within $Text by the regex code in the '.contains("regex")' operator's regex.

    Often, the regex matches the entire source so $0 returns the whole source text. The structure of the example above is deliberate, so as show that $0 attaches to the regex's match rather than simply being the entire text being passed to the regular expression.

    Do not worry too much about getting the right number. If new to this sort of work and using a regex with several back references, you are strongly advised to try it in a small test file first. This makes it easier to make sure:

    • that the overall regex matches the right notes
    • that the back references return the right content
    • which $-number refers to which extracted content

    Fetching all back-references

    The %matches operator returns a list of all populated references in order $0 to $9. Thus if a query populates 3 back-references within the overall match, then %matches returns a List of $0, $1, $2, and $3.

    Returning the match offset position (dot operators only)

    If the regular expression regex used with the contains() family of dot-operators (e.g. String.contains()) is found the function returns the match's offset+1, where offset is the distance from the start of the string to the start of the matched regex. Formerly, .contains() returned true if the regex was found. The '+1' modifier ensures that a match at position zero returns a number higher than zero which would otherwise coerce to false. Since the offset+1 is always true, no changes are required in existing documents but the function also gives usable offset information, albeit requiring adjustment for use with zero-based indices such as List.at() or String.substr().

    Using long sections of code—code notes

    NOTE: this concept pre-dates newer features like functions, and stamp notes in Built-in Hints. The concept of a note for holding code, such as export boilerplate code—i.e. not formal templates but used in generating export code, still holds true.


    In code input boxes, using opt+Return will insert a line break into the code whereas Return executes the change.

    The 'code note' concept

    If long pieces of action code are needed, such as do not easily fit into a dialog's input box, then another note's $Text can be used to store the code. This approach is generally described as a 'code note' but note this is not a formal Tinderbox concept. A new note is created and its text is used to just hold the code. This offers:

    • More overall editing space for code.
    • Using the affordance of some built-in prototypes (see below).
    • Line (paragraph) breaks are ignored when code is run so each statement can be on a different line.
    • They can be re-used by numerous notes.

    Use the 'Code' or 'Action' prototype

    If using code notes, first add the 'Code' prototype from the built-in prototypes to the TBX and then assign the prototype to your code note(s). If using several such notes, make a codes container and set the "code" prototype via its $OnAdd. The code note sets a monospace font, removes paragraph (line break) spacing, turns off auto-lists, etc. All this makes setting and testing code much easier.

    An important consideration with these 'code repository' notes is that generally it is not required to export such notes or have them appear in the content part of a document (e.g. in agents). If using a top-level split of content and utility notes, these code repository notes should definitely go into the utility.

    The code being stored is only action code, then use of the 'Action' built-in prototype may be more useful as this employs syntax colouring of action code and detection of unbalanced brackets.

    Using a code note's code

    The best way to deploy code in the code note is to use its rule (or edict if preferred) to set the rule/OnAdd/etc. of another note. Therefore a self-focussed action, i.e. rule or edict, in the note will set an action in another note, for example:

    $Rule("Some note")=$Text; 

    Assuming the $Name "some note" is unique, this will set that's note's $Rule's code to be the current note's $Text. If the $Name is not unique, consider using the $Path:

    $Rule("/Stuff/examples/Some note")=$Text; 

    This approach allows use of the $RuleEnabled (or $EdictEnabled) to act as a cut-off and stop propagation of code if the code in the note's $Text is being worked on, e.g. to extend or correct existing code. Once the edit is complete, re-enable and the new code will be passed to the relevant note(s). Although, it is more instinctive to use a rule in this role, unless the code will change often, an edict is a more sensible choice as it runs less often (edict execution). If using these 'enable' attributes, consider adding either/both as additional Displayed Attributes to the Code prototype.

    If the reference is to more than one note, a list of offsets is possible:

    $Rule("Some note;Another note")=$Text; 

    But, if more than two or three matches are desired, a better approach is to use a prototype name as the match. Then, all notes using the prototype are updated.

    Storing stamps

    Older methods were rendered obsolete by the v9+ feature of the optional Hints container. If this is feature used every stamp (including older pre-existing stamps) is represented by a discrete notes using the 'Action' prototype which offers syntax colouring and $Text customisations pertinent writing action code.

    A further useful affordance of using Hints is per-stamp notes can be opened as stand-alone note windows with action code syntax and parenthesis completion warnings.

    Storing stamps - without a Hints container (legacy only)

    Consider using the hints container (above), before using this legacy approach.

    If a stamp's code is long, it may be more convenient to write the code in a code note and then make the actual stamp an action() task that executes the $Text of the code note. Thus if a code note 'Test-stamp' held the action code $Colour="red";, then a stamp with the code:

    action($Text("Test-stamp")); 

    when run would result in the stamped note(s) turning red. The example is trivial but shows the technique. Note the offset addressing in the stamp to the code note is case sensitive and should use a unique $Name (or else cite the full, unquoted, $Path to the code note). Local attribute references, i.e. $Color or $ChildCount, are bound to the note being stamped: it is not possible to reference values in the code note using a designator.

    Usage Tips

    Avoid the temptation to make the code note affect itself, e.g. set its own $Rule by copying pasting code from the note's $Text into a $Rule displayed as a Displayed Attribute. Use the code note simply to store/edit the code, then use its $rule to set an attribute in a different note.

    The limitation of the above is the result is to overwrite the note's own $Rule, or other action attribute, with the code from the referenced note's $Text. However, if the latter is updated, the changed code is not reflected as the note needing the code is no longer referencing it, as the $Rule has a literal copy of the old code. The fix is to reverse the reference, so the note with the code sets the attribute of note needing to use it. If note "Complex Test" needs to use the code in $Text of "code sample 1", then in "code sample 1" this $Rule is added:

    $Rule("Complex Test") = $Text 

    The "Complex Test" note's $Rule, if one, makes no reference to "code sample 1". If the code-holding note's $Text is edited, on the next update cycle the $Rule of "Complex Test" is updated. Another variant on this is to use the same technique to set a complex conditional $Rule or $DisplayExpression for a prototype note. Editing the 'source' code will update the prototype and the new code will be inherited by all notes using that prototype.

    The context of this process does not just have to be a rule. Other examples:

    $OnAdd(some note)=$Text(code sample 2); 
    $AgentQuery(some agent)=$Text(code sample 3); 

    Using eval() and action()

    The eval() action can be used to further extend the complexity of what may be done, where an operator does not exist for the task at hand. For example, assume a code note of the above type has written, into another note's $TempString, a literal string value of:

    "collect_if(all,$MyDate== '"+$MyDate+"',$Name)" 

    See how the attribute value, though a string, includes enclosing quotes. This means that it is possible to delay the evaluation of $MyDate. In the note using the code, a single eval() call on $TempString, eval($TempString), returns the same string in different form. The literal string value of the current note's $MyDate is inserted into it (this example is on a system using day/month date order) and stripped of enclosing quotes:

    collect_if(all,$MyDate== '23/7/2011 10:02',$Name) 

    The latter is important as the value of eval($TempString) becomes a string of valid action code. To actually get the result of the collect_if(), it is still necessary to evaluate that code. Thus by nesting a second eval() call, the output of the first call is evaluated afresh. Using eval(eval($TempString)) gives:

    Note A;Note C;Note_X 

    which is the output of the collect_if(). As a side note, observe how in the initial string it was necessary to added enclosing single quotes around where the code reference to $MyDate occurred, ensuring the literal value, when inserted, was a properly quoted string literal. Single quotes were used as the overall initial string already used double quotes.

    Sometimes the Tinderbox code parser is unclear as to user intent and over-evaluates returning a boolean true/false value (N.B. this underlies queries which under the hood resolve query terms to a boolean value). In such cases, the action() operator generally works but note a significant difference between action() and eval(): action() evaluates a complete action—both left and right sides of the '=' assignment—as a mix of concatenated strings and and literal values. By comparison, eval() evaluates part of an action code expression.

    Using .each() for loops

    The list.each() function can be used to iterate lists. It works like a 'for each' method commonly used in programming and scripting whereby each and every item in the source list is processed using the in-loop code.

    Using a list item more than once per loop

    Assume your data is in a List or Set type attribute. In this case $MyList contains the values cow/dog/eel. Assume it is necessary to turn that into an HTML select list like this:

    	<select>
    	<option value="cow">cow</option>
    	<option value="dog">dog</option>
    	<option value="eel">eel</option>
    	</select>

    Notice how in the output above each source list item is used more than once. However, using format() or List.format() you can only wrap each list item once. So other than doing iterative list formatting, which can get complex, .each() offers a way around this. Use the following $Rule, line breaks and indentation are just for clarity:

    	$MyList =;
    	$MyList.each(X) {
    		$MyString = '<option value="'+X+'">'+X+'</option>';
    		$MyList = $MyList + $MyString;
    	};
    	$Text = "<select>\n"+$MyList.format("\n")+"\n</select>";

    Shorter version, without the in-loop caching of the concatenated per-item string (see bullet #3 below for the rationale):

    	$MyList =;
    	$MyList.each(X) {
    		$MyList = $MyList + ("<option>"+X+"</option>");
    	};
    	$Text = "<select>\n"+$MyList.format("\n")+"\n</select>";

    Notes:

    *$MyList must be reset (to an empty list) before the loop otherwise each time the Rule fire the loop adds to existing $MyList data rather than build a new set.

    *Everything between the { } is runs as the loop. Here the closing } has a semi-colon after it as another discrete section of code follows it.

    *Ordinarily, one could simply put parentheses around the string literals to concatenate them before passing a single string into $MyList. This works as long as the string literals to concatenate do not contain single or double quotes, or, if double quoted enclosed strings contain single quotes. But, an edge case occurs where single-quote-enclosed strings contain any double-quotes; in such cases an 'interim' string attribute is needed to ensure the sub-strings are correctly concatenated before the data is passed to $MyList.

    *As a string attribute only contains one value, adding a new one replaces the old. Thus $MyString does not need to be reset before the loop unlike a set or list such as $MyList.

    *Note that for the final concatenation .format() can be used as each list item is used only once in the resulting output. The closing select tag must be preceded with a '\n' line break as the .format()'s join only adds the concatenation string between each item in $MyList and a lone break is needed after the last option close tag.

    Detecting first or last loop items

    This is discussed separately in detecting first or last item context in loops. Also see: list.first and list.last.

    Adding output joins in-loop

    See adding joins in loops.

    Adding a loop counter

    By default .each() processes every list item. But what if you only want do something with the Nth item or perhaps only even numbered ones? In that case it is necessary to create a loop counter, and iterate in-loop. For instance, the following sums the value of odd-numbered items of $MyList onto the existing value of $MyNumber:

    	$MyCountNum = 0;
    	$MyList.each(ListItem) {
    		if(mod($MyCountNum,2)==0) {
    			$MyNumber = MyNumber + ListItem;
    		};
    		$MyCountNum = $MyCountNum + 1;
    	};

    Notes:

    • Set the counter ($MyCountNum) to zero (or just reset the attribute) before starting the loop.
    • Tinderbox list values number upwards from zero (e.g. as seen if accessing data via the List.at() function). Here, think of list item #1 being 1, then set $MyCountNum to 1 before the loop and test for mod($MyCountNum,2)!=0.
    • Note that list.at() is read-only so you cannot use code like $MyList.at($MyCountNum) = ListItem; 

    An alternate method is to use the range operator (see example).

    Using a path variable

    The loop variable can itself be a path and this be used as a variable designator allowing attribute offset addressing inside the loop:

    	$Text=""; collect($Overdue,$Path).each(x){ 
    		$Text = $Text+":"+$Text(x);
    	};

    In the above, the 'x' variable is a $Path value and is being used to provide the offset address argument in the loop.

    Using a variable within a loop

    A variable created by var can be altered from within an .each() loop, as shown here.

    Creating an $AttributeReference within a loop

    Described here.

    Constructing $Attribute references in loops

    Tinderbox's loop mechanism using .each() is helpful but one task can be problematic. This where the task is to loop a list of attribute title values and then act upon each attribute in turn.

    The basic problem is that if the loop variable is, for example 'X' and current loop value is 'MyString', how to construct the reference $MyString, so as to act on the MyString attribute.

    The answer is to use a nested action() call inside the loop, even if that seems counter-intuitive at first sight. For example, consider the task of resetting every attribute in a note's displayed attributes table. The contents of the table are stored in the Set-type system attribute $DisplayedAttributes, which can be iterated with .each():

    $DisplayedAttributes.each(X){...}; 

    Now the task is to set X, in each loop, to address the attribute named in the current value using action():

    
    $DisplayedAttributes.each(X){
    	action("$"+X+"=;")
    };
    

    In other words, if X is value 'MyString' the action() is both concatenating some strings:

    "$"+"MyString"+"=;" 

    and then evaluating the resulting action code expression:

    $MyString=; 

    Note that:

    • eval() will not work in this context.
    • the contents of the action() must concatenate to form a complete action code expression.

    It may be necessary to nest quotes. Consider a list of String-type values. To set each one to a value of 'test':

    $MyList.each(X){
       action("$"+X+"='test';");
    };

    Note that the target value needs to be enclosed in quotes. As the main expression string already uses double quotes, the string needs to use single quotes. It does not matter if you reverse the nesting. The action would work just as well in the form:

    action('$'+X+'="test";'); 

    But, do ensure the sets of single/double quotes nest correctly.

    The action can use loop variable more than once. Take the last scenario, but this time where all the attributes are Set or List type. Here the code is:

    $DisplayedAttributes.each(X){
    	action("$"+X+"=$"+X+"+'test';");
    };

    …i.e. creating an action expression, in-loop, like this for X value 'MyList':

    $MyList=$MyList+'test'; 

    White space in the expression does not matter, as in normal action expressions, but is omitted above for brevity/clarity. The expression could also be:

    $MyList = $MyList + 'test'; 

    …and still work.

    Constructing references to values in other notes

    The task gets more complex when one or both of the left/right side attributes is not this note. Consider this task:

    $MyString("Some note")=$MyString("Other note"); 

    … but in a loop where 'MyString ' is a loop variable value. action() is still the approach. However, to avoid confusing the action code parser with too many sets of quotes—whether on one or both sides of the expression—is to pass the offset agument via a variable. This avoids normal consideration of quoting (paths) or not quoting (anything other than paths) the offset values.

    For example, consider the task of iterating Displayed Attributes to set the value of each such attribute in "Some note" into those of "Other note":

    	var:string vSource = "Source Note";
    	var:string vDest = "Destination Note";
    	var:string vCmd;
    	$DisplayedAttributes(vSource).each(anAttrib){
    		vCmd = '$'+anAttrib+'('+vSource+')=$'+anAttrib+'('+vDest+')');
    		action(vCmd);
    	};

    Or, in function form:

    	function copyDA(iSource:string,iDest:string) {
    		var:string vCmd;
    		$DisplayedAttributes(source).each(anAttrib) {
    			if(dest==""){
    				vCmd ="$"+ anAttrib +"=$"+ anAttrib +"("+iSource+");";
    			}else{
    				vCmd ="$"+anAttrib+"("+iDest+")=$"+anAttrib+"("+iSource+");";
    			};
    			action(vCmd);
    		}
    	};
    	// called via code
    	copyDA("/Notes/Source Note","/Notes/Destination Note");
    	// or
    	copyDA("/Notes/Source Note","");
    

    In the code calling the function, the source/destination string might themselves be attribute values or variables:

    copyDA($Name(parent),""); 

    Testing constructed code strings

    If encountering errors, it may be useful to incorporate a show() command, which can then be commented out or deleted when all is working. For example:

    	var:string vSource = "Source Note";
    	var:string vDest = "Destination Note";
    	var:string vCmd;
    	$DisplayedAttributes(vSource).each(anAttrib){
    		vCmd = '$'+anAttrib+'('+vSource+')=$'+anAttrib+'('+vDest+')');
    		action(vCmd);
    		show(vCmd);
    	};

    That will display, in turn, the literal value of vCmd string for each attribute in Displayed Attributes in turn.

    A similar but different approach is to log the data by writing it to the $Text of another note, in this case a note 'log' at root level:

    	var:string vSource = "Source Note";
    	var:string vDest = "Destination Note";
    	var:string vCmd;
    	// clear the log of old data
    	$Text(/log) =;
    	$DisplayedAttributes(vSource).each(anAttrib){
    		vCmd = '$'+anAttrib+'('+vSource+')=$'+anAttrib+'('+vDest+')');
    		action(vCmd);
    		$Text(/log) += vCmd;
    	};

    Detecting first or last item context in loops

    Operators like are .each() automatically aware if all items in a list have been processed. But there are two other reasons it is useful to now if the first or last item is being handled:

    • adding a prefix (for first item) or suffix (to last item) to the output of the loop.
    • detecting if a join is needed, between list items, in the output.

    Detecting first or last position

    This is most easily done using list.first or list.last. Note that .first and .last are not operators, but simply return the value of that item in the source list.

    In a case where the loop is being used to create a string, a prefix can be added to the overall output by testing .first. The code setting the prefix needs to be the very first code inside the loop so the suffix is added to the output before the first item's data:

    	$MyList.each(anItem){
    		if(anItem==$MyList.first){
    			// code for prefix here
    		};
    		// other in-loop per item code
    	};

    For a suffix, do the same but test .last and put the suffix code at the end of the in-loop code so the suffix comes after the output of the last loop item's data:

    	$MyList.each(anItem){
    		// other in-loop per item code
    		if(anItem==$MyList.last){
    			// code for suffix here
    		};
    	};

    Adding join data between list items is explored in adding joins in loops.

    Adding joins in loops

    Adding inter-item join data to a loop output

    The simplest way, if the end output is a string, is to make a list from the loop and use List.format("formatStr") to make a string from this list inserting formatStr between each list item (and not before /after the ends).

    However, as explored below, it may be desirable to add the item-joining string whilst iterating the loop.

    Adding join data: add at loop start or finish of an item?

    As a general point, and perhaps counter-intuitively, it is better to test at start "am I second or later?" and prepend the join, rather than test "am I last?" and append the join. this is because it is easier to know definitely that a process has started as opposed to if/when it will end.

    Examples of loop Detection of loop start or end are shown under detecting first or last item context in loops.

    Adding join data in-loop

    An example is making a list of { } enclosed JSON data objects where each {object} has a comma character as a join but there must not be a trailing comma after the last item. Thus a comma must be added either:

    • before every item, for all except the first item
    • after every item for all except the last item

    Which approach is used is a matter of personal choice.

    Concatenation versus addition

    In Tinderbox, the plus symbol (+) is used both to concatenate (join) strings of text and to sum figures. Thus

    $MyString = "My favourite colour is " + $FavouriteColour 
    $MyNumber = 4 + 3 

    Nothing untoward there, not least as the resulting data type (as implied here by the left side attribute name) helps Tinderbox guess the user's intent. But what about:

    $MyString = "6" + 4 

    Is it "64", 64, "10" or 10? As the stated attribute is String-type, the result is a string. As one of the right side arguments is a string, then a concatenation is used. If both (all) arguments are numbers, then an addition occurs before being saved as a string:

    $MyString = "6" + 4 gives "64"
    $MyString = 6 + 4 gives "10"
    $MyString = 6 + "4" gives "64"
    $MyString = "6" + "4" gives "64"

    In earlier versions of Tinderbox, there was no need to quote strings and Tinderbox guessed string/number by context. Since then, as the action code has got richer, it has become harder to divine the user's intent, thus the move to expecting text to be placed in double quotes. Incidentally it also makes it easier to indicate intent with regard to leading/trailing white space.

    Thus, when using the '+' operator try to ensure Tinderbox is not having to guess too hard as to the desired outcome.

    If necessary use parentheses to help indicate intended operator precedence to Tinderbox if it is getting things wrong.

    Dates and Strings

    Action code expressions in which a date is added to a string. In the following the value of $Name is "Created"

    $String=$Name + $Created <- a string "Created08/07/2010 08:27"
    $String=$Name + " " + $Created <- a string "Created 08/07/2010 08:27"

    In the above example the date time format is the user's host OS short date/time format so will vary by locale. The date shown equates to format($Date,"l t"), i.e. local short date space local time (see format(), date formats). Use format() with the date attribute if some other date/time formatting is required.

    Note also above how a joining space needs to be provided. Note also that adding a string to a date continues to return a date, adding a date to a string returns a string:

    $Date+"3 days" <- a date: 3/29/10
    "3 Days "+$Date <- a string: 3 Days 3/26/10
    "3 Days"+" "+$Date <- a string: 3 Days 3/26/10

    The first above assumes the string being added contains logical date-related content.

    Parentheses as a guide to code execution

    Although the order in which code is executed might seem intuitive to the user but this may not necessarily be how Tinderbox sees and interprets it. In such situations, parentheses (normal brackets) can be used to indicate 'sub-expressions'. Execution order of things like this

    $AttrA($Num1) = $AttrB($Num1) + 1; 

    can be less obvious to Tinderbox than to the user writing them. This is especially true where, like above, attribute expressions are being used as these require evaluating themselves before the main action code expression is evaluated.

    In such circumstances, especially if tests appear to give the wrong answer, consider adding parenthesis as a guide to Tinderbox as to the order of the process. For instance:

    $AttrA($Num1) = ($AttrB($Num1) + 1); 

    tells Tinderbox to evaluate the whole of the right side before attempting the overall action code expression.

    Parentheses can also be useful in stopping mis-interpretation of multi-term queries including the short-form no-value attribute test, e.g. !$AttributeName. Using (!$AttributeName) instead of !$AttributeName) can help.

    Beware too of data types and lack of clarity of whether a '+' is a (string) concatenation or a (number) addition; see more.

    Updates and cascading actions

    A configuration can arise where one or more agents look at (query) another agent. Alternatively, an action might trigger a note to be moved, in turn triggering an $OnAdd and so on.

    When using 'Update now' from the File menu, all agents are fired once (in $OutlineOrder sequence) as are any action events dependent on the update cycle. In a cascading scenario, it may thus be necessary to call 'Update now' several times to flush an action through to completion, especially if using linked agents where the order of dependence does not follow $OutlineOrder. For instance, if agent C looks at agent B which looks at agent A, a change in A will need 2 updates to flush through to C.

    Therefore, if using documents with cascading effects, be aware that a single forced update may not always 'complete' all actions as the user might intuit would occur from a single invocation.

    Forced invocation of updates runs all running agents, i.e. regardless of priority setting unless the agent is turned off.

    Optimising code for performance

    In small TBX files there is rarely a need to consider code optimisation, but as your files grow in note count and complexity and acquire more agents you may see the time-to update increase, i.e. how quickly code changes are effected. In such circumstances, or just as best practice, it is worth reviewing and applying a few optimisation techniques.

    General practices

    These do not directly affect code execution (other than by bad syntax) but help make everything else easier.

    Prototypes

    Using prototypes to set up and/or locate discrete sets of note(s) is a big productivity gain. Editing code (or code notes) once can then affect many notes. Consider using $RuleDisabled and $DisplayExpressionDisabled in the prototype so as to suppress execution of such code in the prototype. If applying prototypes as part of incremental formalisation, do not forget to reset the inheritance of any prototype-using note's attributes that may have previously had a local value set.

    Check your syntax

    Make sure your code does not include deprecated syntax. At some point in the future the code may not work at all and in the meantime you're making Tinderbox guess your real intent. Tinderbox does not warn about the existence deprecated code (it can't know what things are that the parser doesn't 'understand'), so updating code is an exercise left to the user.

    Act on the right subject: originals vs. aliases

    Be aware that if using actions in agents, you are acting on the original, so values of intrinsic attributes

    Optimisation

    These techniques can help with tuning performance once the size and complexity of your TBX grows:

    • Narrow the scope of agent search. Review and rewrite queries so each successive query terms tests fewer items. The fewer tests, in aggregate that Tinderbox has to make the faster the results. This is especially true if the (final) tests is based on a complex regular expression such as in .contains(). If the desired matching group of notes is not easily defined in narrow scope, consider giving them all the same prototype.
    • Querying existing agents. Rather than have numerous agent all querying the same overall scope, consider making one agent to to that first selection and then have other agents query that agent's results using different queries. So rather than have 5 agents querying descendedFrom("X"), make a single agent, e.g. 'agent A', do the latter and the the other use inside("agent A") as their first query term. Do note though that this means it may take several agent cycles for a change to cycle through.
    • Agent Priority ($AgentPriority). Not every agent needs to run every cycle. The agent's priority can be set via the agent's Action Inspector's Query sub-tab or directly in code via $AgentPriority. Also consider an agent to find all agents allowing you to easily adjust their $AgentPriority via its action. Or make a stamp to toggle $AgentPriority on/off.
    • Re-use agents as part of queries. Queries can match aliases in other agents. If using multiple agents all with the same query start and differing final filter, it is more efficient to use one agent to find the initial query scope and then make the other agents query that one agent for the extra term. Consider an 10 agents testing the whole TBX of 1,000 notes, to match the same 100 notes then testing those to get the actual full matches. That is 1,000+100 x 10, i.e. 11,000 test in total. Now if one agent does the first match (1,000 tests) and 10 agents test its 100 aliases, we get 1,000 + (100 x 10) to give 2,000 test—just 18% of the original number of tests per agent cycle. This isn't apparent in small files, but the effects pile up as a document grows especially if the user is keen on using agents for everything. If employing this chaining, be aware of the possibility of cascade effects for which to allow.
    • Caching expression results in a user attribute. Expressions like Display Expressions and Hover Expressions are, slower to run than rules or agent actions; this is especially so if the expression is anything but a simple attribute value call. As a result, if such expressions are complex, it is better to use a rule or agent action to run the code and store the expression's result in a user attribute and then have the display/hover expression simply read that stored value. Adding an extra attribute has negligible impact on the TBX.
    • Use $Searchable to exclude notes. The $Searchable attribute provides an ad hoc way to exclude some notes from all searches.
    • Make the action remove acted on notes from query scope. Consider making the action's outcome make changes such that the altered note no longer meets the initial query. This is a good method for making an agent effectively act once only on a note. If it is not possible to alter an attribute value being matched, e.g. it is $Text that must not be changed, consider either moving the note (via $Container), or making a user Boolean as a 'guard' field to be tested in the query for the action to set (e.g. an $IsCorrected).

    Checking and setting Time correctly in Date data

    Tinderbox Date-type data always includes a time element (hours:minutes:seconds), even if not explicitly set by the user. If not supplied when first set, the current OS system clock time is used for the item element, even if the date element is for a different day.

    Use of seconds in time. Seconds are set (previously, in older releases, seconds were not set); if not set explicitly seconds are assumed to be '00'. Even if seconds are not of direct interest (but consider rounding to minutes) and not normally displayed in Displayed Attributes, it is it advisable to set a seconds value of '00' when defining time for Date-type data: that should avoid unexpected effects.

    The time element of dates makes some date comparisons work in unexpected ways.

    Methods to see/check a Date's time:

    To set or change the time element of a date:

    When working with date designators, and explicit (24-hour clock) time can be added stated. At 14:23:00 on 28 November 2012:

    date("today") gives 28 November 2012 14:23:00
    date("today - 2 days") gives 26 November 2012 14:23:00

    But

    date("today 23:59:00") gives 28 November 2012 23:59:00
    date("today - 2 days 08:00:00") gives 26 November 2012 08:00:00

    If wanting to use greater than or less than date comparisons, it can be helpful to explicitly set a time value like 00:00:00 or 23:59:00 if wanting to test for a full day midnight-to-midnight.

    Another context where (re-)setting a fixed time can be useful is with timelines and historical dates, for instance setting all times to 08:00:00 or some other common time, if only to avoid effectively random times set automatically when creating dates by supplying on the date and no time. Tidying up existing dates is not hard. Make an agent to find the notes needing tidying, and that add an action like:

    $StartDate = time($StartDate,08,00) 

    Note that as the code force-changes just the hours/minutes the actual date cannot be affected. For existing data, you can run the above and delete the agent. However, if you have processes creating new events it is worth checking date designator offsets—like the examples above—also use an explicit time before you delete or turn off the agent.

    Debugging user-written Action code

    Remember that output of any action code is normally to set/alter one or more attributes. Here are a few things learned from testing complex action & export code…

    Tiny steps save time in the end—especially when things are not going as they ought.

    If an initial attempt at a piece of code does not work then consider the following:

    Use small deliberate test documents

    If adding code into a current working document (i.e. with lots of content) doesn't work as expected, and having checked for obvious errors like typos or wrong literal path values, a sensible approach is to make test document.

    If the code features being tried are new it is a good idea to make as simple a test as possible to give confidence. Don't overlook using methods available to show interim values. Use as little test data as possible to start with and validate the basic method works. Then, especially if agent queries or find() are involved, add extra content to test false positive/negatives.

    Once confident the basic process works, code can be moved back into the min working document with confidence that it ought to work. If it still fails, this would suggest code/processes in the existing document may be interfering. The Tinderbox Inspector's tabs ca help get an overview as to how many active rules/edicts there are and as to running. It can help to turn off or disable some of these whilst looking for a cause of interference.

    In a large mature document with a lot of code, a seeming failure may not be the code as such but the fact it runs less quickly/often than expected. In such a case the work shifts from de-bugging to tuning performance.

    Tuning performance

    This is not de-bugging as such but involves getting a clear view of how much code is running, where, and with what priority. consider that actions can be turned off (they retain their last used child aliases) and rules/edicts can be disabled. Rule code can move to edicts, that run less frequently, or even moved into a stamp.

    Again, it may help to make a small test document of your general workflow just to look for possible optimisations.

    Be ready to delete test documents

    When done, it is often a good idea to delete the test document straight away or soon after the code works in the main document. In other words, make test documents with the intent of deleting them once the problem is resolved unless you have a clear need. If you do keep a test document it is worth adding a note explaining what it was for and what parts of the bigger context it did/did not test.

    Break the code into discrete steps

    An action can be as simple as setting a new $Color value, but in reality it may involve multiple action code expressions (think discrete actions in the same stored bit of code. Also remember that dot-operators condense a whole series of tasks into one action code expression.

    Test as the smallest scope you can. Once confident the values resulting are as expected, all the parts can be joined back together. A common mis-step when debugging a failing action is not to tear down far enough and in so doing miss the step where a failure is occurring.

    Chained operators

    So, an action code expression might get a list of data via a collect using a custom find() query, .sort() it and de-duplicate it via .unique() and then format it as a custom string via .format(). Essentially, there are five activities there any of which can be tested separately:

    • the find()'s query. This could be tested using an agent. Does the agent find the expected items.
    • what collect() is collecting. This could be tested via an agent action.
    • the remaining 3 tasks can be split into new action code expressions. By using a variable or attribute to inspect interim values (or displaying them) the other tasks can be broken into discrete action code expressions.

    Agents

    If using agents with an agent action, it is a good idea first to check that the agent is finding (aliasing) the correct notes before then adding the action code. Also consider turning the agent off whilst actively editing the action/rule/edict.

    Rules and edicts

    If editing code, disable rules and edicts so that half-written code is not run. Important to note is that if editing a prototype's rule or edict, it is better to remove all the code, edit it in a code note and re-insert when done. This is because $RuleDisabled and $EdictDisabled are intrinsic and not inherited. with long/complex actions especially, this increases the chances of large numbers of notes trying to run incomplete code.

    A common issue with prototype use is that during test/tune of a rule/edict the code gets edited in an inheriting note (wrong!) rather than in the source prototype. A query for use of the prototype (in $Prototype) & hasLocalValue() can help. For notes using prototype "Person" this query will match all notes with that prototype which have locally set $Rule value:

    $Prototype=="Person" & hasLocalValue("Rule") 

    This ought to match no notes but if it does match any, those notes need their rule reset ($Rule=;). Edicts—indeed, any attribute—can be checked for broken inheritance.

    Be aware of context of execution and addressing

    Often, as a document grows, action code moves beyond code acting on the current note and it either/both calls or sets attribute values in other notes, via offset addressing.

    When addressing an offset by $Name be aware that the title might not be unique or even use the same names as a designator or operator. Using $Path addressing is better in most simple cases, with advanced users benefitting for using $IDString (replacing previous use of $ID) for unambiguous addressing—even if $IDString is hard to use by 'eye' when debugging. But, if using logging, it is easy to log an $IDString and its associated $Path.

    As agent actions act on aliases, it is important to under stand the differing contextual meaning of parent vs. agent or adornment. Similarly, be aware of the notion of intrinsic attribute values when reading/setting values.

    When using queries in find() operations be aware of the differing implications of this vs that.

    Re-check documentation

    Be aware not all operators evaluate all arguments, or to the same depth—i.e. if the arguments included nested evaluations. Argument evaluation is not formally annotated for all operators, the full operator listing probably has the most useful collection of knowledge on this aspect.

    If evaluation is an issue, consider tear-down testing starting with literal values and slowly changing to evaluated arguments.

    Using code notes for large code sections.

    For long section of code, consider storing the code in a code note, so that it is easier to review and work upon.

    Store interim code values in variables or attributes

    Historically, this was done by storing data in attributes. That works but if, for instance, this involves storing lots of really large lists, it is easy for unneeded stored data to accumulate unless the attribute values are reset.

    Better is to use variables unless there is a genuine need to persistently store such data. Very occasionally, and less encountered today, it may prove necessary to 'crystallise' a calculated value before using it in another action code expression. Typed variables generally remove that older requirement.

    Variables have the advantage of clearing themselves up. They are created when needed during a a complex action, where there may be all sorts of different interim values being created. At the end pf the code running the variables are destroyed.

    To record a variable's value for review after running the code, logging is the best approach.

    Store constant values in a note

    If there are values, e.g. the path to a particular note or a lookup list, that code in multiple notes may use, consider storing such values in attributes of a single note. Some users refer to this as a configuration or 'config' note. Its only purpose is to be a consistent place (path) to store information likely needed for regular reference by code.

    Viewing interim values via placards

    An alternative to using a log is to show logging massages in the Tinderbox UI, is via message placards. As each message shows for a few seconds and all are shown sequentially, if using a lot of logging, saving the messages to a log note makes more sense. Both methods can be mixed. For instance a placard might report passing key stages in the process whilst logging might capture for more fine-grained detail.

    Using a log file to review interim code outputs

    Tinderbox has no fixed logging system but this is easily set up in a way that suits the user simply by writing code values to the $Text of a log, i.e. another note. Thus

    Make a note. 'log' is a simple default name. Ideally put is somewhere easy to find and avoid a complex name and/or pat that might make addressing the note difficult. Placing it at root of the outline is a good initial choice, i.e. $Name 'log', $Path '/log'.

    In the code to be tested write to the log by altering $Text(/log):

    $Text(/log) = "Current value of vPath is: "+vPath+"\n"; 

    Be aware using '=' overwrites existing log text, so an increment '+=' makes more sense, as does an opening call at top of the code to 'reset' the log removing old content. so at start of the code being tested:

    $Text(/log) =; 

    Then later in the code:

    $Text(/log) = "Current value of vPath is: "+vPath+"\n"; 

    In this case, after the code is run, the log should record the value of variable 'vPath'. A mix of literal string and a value is useful for indicating the code ran. For instance, you may see the literal text but no value indicating the code at least executed up to the logging point but the value assumed to be in the variable vPath has in fact not been set.

    In a long-lived document is it easy to go a stage further and make user functions to reset to log or to write to it. For writing , that takes care of remembering to forma the input, add a line break, etc.

    If using logging in code it is a good idea to comment out the log call or remove it when done and to check the log file and delete accidentally accrued content.

    Comment code and attribute descriptions

    Don't overlook that action code supports comments, as what makes sense today might not do so tomorrow or in a year's time.

    Similarly all user attributes allow a free text description in the Inspector to record the purpose of attribute. Note that existing controls show the data type, default value, etc. so the description is more useful for capturing why the attribute was needed—even if only for ad hoc testing purposes.

    For user attribute, take a moment to give them names that are self-explanatory. Clarity of naming is subjective. There is no single right way, so that actual names are a choice for the individual.

    Annotate your process if not simple

    As a document grows over time and in scale, code accumulates, as does process (such as import from other apps).

    Whilst actual action code can hold comments, it is also worthwhile making some notes about overall process. Ideally store these notes away from the document working content, and capture enough detail to inform future self or collaborators as the the overall intent if the automation in the process: why code/functions were added, the steps to do certain processes, etc.

    Making these notes will repay future self in any later debugging in the note.

    Do update the notes as the document ensures, so that they are not out of date when/if needed for future reference. It is much easier to capture this information at the time the process is implemented than trying to remember detail later.

    Use the Tinderbox Inspector's tabs

    Most useful is the second tab, Agents & Rules. This is particularly helpful when looking at performance-like issues

    Abstract re-used patterns to functions

    More for advanced users, but be open to using user functions. for instance is a code, or codes in several different notes (or prototypes) are calling the same sequence of actions, consider abstracting the task into a function.

    By using a function, the process is written and tested once, with the only varying element being the inputs passed to the function. The more steps to the common process, the more the pay-off as any changes only need to be made tested in the function code and not in all the notes using the function (or the code in the note that function replaced).

    Is it really a bug?

    If trying to move code tested in a small file into a mature file and hitting issues, it can be useful to restart the application or just close and re-open the current document. Odd as it may seem it pays not to overlook the 'turn it off and on again' advice.

    An easy hole into which to fall is to appear to have a repeatable bug or glitch that occurs consistently in the current document, only for a document re-open to magically clear the issue. The latter is not at all common but a point to bear in mind before writing in for support.

    If after testing the code there is still an unexpected outcome, next try to replicate it in a new file with only as much content, if any, as it needed to re-create the criteria to produce the outcome. If still reproducible, please email Tinderbox Tech Support (tinderbox@eastgate.com) with:

    • A description of the problem.
    • Exact steps to recreate the problem.
    • What was expected.
    • What actually occurred.
    • If possible a test document that can be tested using the described steps to show the issue. Note that TBXs zip-compress well for email transfer.
    There was a crash or hang

    Crashes are self-evident—the app closes immediately and a crash log is recorded by the OS (occasionally, and extremely unusually, no log may get made). An alternate scenario is the app hangs and is 'unresponsive'. After waiting a bit the general resource is to Force Quit that app, which generates a h'ang' log. Inconveniently, macOS stores the two types of logs in different places: how to find crash and hang logs.

    Crashes are not expected and remarkably rare in Tinderbox. However, once having tripped over a crash condition, repeating the cause of the crash will reliably repeat the crash. Importantly, repeating the scenario does not mean the app is now 'more crashy' but the same crash condition is being reliably completed.

    Given the large toolbox that is Tinderbox, it is remarkably stable. Given the possible number of combinations of tool, task and context, it is vey possible that a user is the first person to use that combination. The fact a problem is repeatable after it is found does not imply the context is common, even if intuition makes us think otherwise.

    Encountering a crash, after restart take a back-up of your active TBX. Normally a crash, if it occurs, the document might loose the last few seconds of unsaved input but generally there is no widespread harm to data. So either use the current document as a back-up or restore a recent file as a last, good reference. Do this before testing further.

    At this point either pass the crash log to Tinderbox technical support (email tinderbox@eastgate.com) or continue with diagnosis.

    Note that the user-to-user forum cannot diagnose crashes. Given that crashes are contextual, the fact that other users my not see the same problem is not unusual.

    Useful things to investigate—if sufficient time/expertise:

    • is the problem repeatable:
      • does it re-occur if the app/doc are restarted?
      • does it occur in all documents or only some, or just one?
      • describe the steps to recreate he problem (either in a new/text document or in the affected document(s).
      • if possible share a copy of the/an affected document (TBX files compress well if zipped).

    Meanwhile…

    Avoid doing whatever causes the crash (if the trigger is clear). Depending on the feasibility of doing so, and if the crash arises from a new release, consider rolling back to a previous version. Providing clear information to Eastgate will increase the chances of early resolution.

    Export code

    With regard to Export code:

    • as with action code be aware of context. From which note's attributes is the code reading?
    • includes (^include()^) cannot draw data from a note that is set to not export itself. Learn to understand the nuances of $HTMLDontExport and $HTMLExportChildren.

    *links in exported pages cannot be created to the content of notes exported as an inline include within another note (i.e. a composite()).

    Use of the Command Line

    Tinderbox can pass commands to, and receive output from, the OS Command Line using the action operator runCommand(). This enables access not only to simple Unix tools like sed or ls, but to more complex tools like pandoc or programming languages like python. Data can be passed to extrenal tools or scripts and the evaluated data returned and passed to a Tinderbox attribute:

    $Text = runCommand("ls -a"); 
    $MyNumber = runCommand(vCmd, vArgs);

    But what happens when the return value is missing or incomplete. Some notes follow on testing and debugging runCommand().

    Testing output from Tinderbox

    A useful check to make is that what is received by the Command Line is as intended. A first check is to run the expected output on the command Line in Terminal. Assuming that works, the next check is to confirm the output from action code is as expected/intended.

    In the first example above, the output is a simple literal string,"ls -a", so can be seen and checked in situ in action code. In the second example, the output sent by runCommand() is created by two variables. To test the actual output, remove the enclosing run command() and pass the output—in the same originating context—to a String attribute or a note $Text for inspection:

    $MyString = vCmd+", "+vArgs);

    Note the inclusion of the joining comma+space, as the intent is to see exactly what is emitted by runCommand(). If the command involves setting/completing quotes, it can be useful to add enclosing (non-quote!) characters so it is clear exactly where the output starts and ends and that enclosing quotes aren't stripped when passed to the target attribute (as is normally expected behaviour. Thus:

    $MyString = "#"+vCmd+", "+vArgs)+"#";

    This the first test might export:

    red", "blue 

    but the second gives:

    #"red", "blue"# 

    It is difficult to generalise further, but the general point is to ensure the Command Line receives a command that is known to work

    Testing returned output to Tinderbox

    Here the reverse applies. Test in Terminal that the command sent generates a reply and the output is as expected. This can be done writing to a text file or direct to the Terminal.

    Assuming the returned output appears correct outside Tinderbox, reverse the test above, passing the returned data to a String attribute or $Text. Bear in minds the point above about checking for possible missing enclosing quotes.

    Incomplete Returns

    If the returned data is complete at the Command Line and incomplete in Tinderbox look for possible issues in the data that may cause it to be misread in Tinderbox (e.g. unbalanced quotes, poorly formatted CSV data, etc.). Another possibility is slow/intermittent return.

    Hangs and waits

    The issue may be that the target process is slow to return data. There is no documented timeout but an assumption of c 30 seconds is sensible. If the target process has not completed within that time, runCommand() will stop waiting and the action will complete. Bear in mind the original concept of runCommand() was to call small/fast Command Line utilities, not as a call-and-wait process.

    If a delay is expected in completion, use two calls, one that writes the data to a text file and a second action, to be run later, to read from that file. Tinderbox has no 'wait' process: it is up to the user to initiate the actions.

    Getting section numbering via Action code

    Export code includes a code ^sectionNumber^ which gives output like this 2.6.2.3.51. It is effectively a chaining all the $SiblingOrder values for ancestors and that of the current note.

    This can be achieved in action code but is somewhat inelegant as root level notes require a different handling and action code conditionals require a full action code expression inside the branch. This code sets $MyString to the section number of the current object:

    $MyString = if($OutlineDepth >1){
       collect(ancestor,$SiblingOrder).reverse.format(".")+"."+$SiblingOrder;
    }else{
       $SiblingOrder
    };

    Or, in one-line form:

    $MyString = if($OutlineDepth >1){collect(ancestor,$SiblingOrder).reverse.format(".")+"."+$SiblingOrder;}else{$SiblingOrder};

    Other approaches

    There are several ways to number (parts of) a document whether internally or (only) for export. These techniques use one or both of two user attributes:

    The technique uses two user attributes:

    • $Section. String-type.
    • $IsTop. Boolean-type. Regardless of where in the outline the 'top' or root note of the numbered sections needs to have $IsTop set to true.

    The techniques are:

    Bottom-up

    In this action based approach, notes look upward for seeding section numbering.

    Code

    
    if($IsTop) {
       $Section="";
    } else {
       $Section = $Section(parent);
       if ($Section) {$Section+=". ";}
        $Section += $SiblingOrder;
    }; 

    Logic

    • If you are the top, you do not have a $Section number.
    • Otherwise:
      • Start by getting the parent’s $Section value
      • If that value is not empty, add a period
      • Then add your sibling number and set as $Section

    Pros and Cons

    • GOOD:
      • Stays up to date as the TBX is reorganised
      • Simple
      • Individual notes can choose to behave differently
    • BAD:
      • Can fall a few seconds behind setting $Section in big/complex TBXs.
      • Might be a bad choice for huge outlines (thousands of elements)
      • If individual notes behave differently today, that might not be wanted tomorrow.
    Top-down

    A recursing function using no user attributes. Start at the top, then name all children and so on down.

    Code

        function fSectionName(iNote, iSectionValue){
            $Section(iNote) = iSectionValue;
            var:string vName = iSectionValue;
            if (vName != ""){
                vName = vName + ":";
            };
            $Path(children(iNote)).each(aNote){
                fSectionName(aNote, (vName+$SiblingOrder(aNote)));
            };
        };

    Logic

    • If the top, section value is already known.
    • Then, tell each child:
      • This is your name.
      • Now name your own children

    Pros and Cons

    • GOOD:
      • Parent may know best how to name its children
    • BAD:
      • Then again, maybe not.
    Just in time

    A recursing function. Figure out the section name only when actually needed.

    Code

        function fAsk(iName){
            if($IsTop(iName)){
                return "";
            };
            if($IsTop(parent(iName))){
                return $SiblingOrder;
            }
        return fAsk($Path(parent(iName)))+"."+$SiblingOrder;
        };

    Logic

    • If the top, $IsTop should be true 
    • If parent is the top, return $SiblingOrder
    • Otherwise,
      • ask the parent for their name,
      • and then add "." and own $SiblingOrder.

    Pros and Cons

    • GOOD:
      • Only computes the section numbers when needed
      • Recursion is elegant
    • BAD:
      • Recursion can be tricky

    Moving notes by setting $Container

    $Container holds the '/' terminated path to the current note. The attribute can be set by the user and in doing so the note is moved to a new parent container. Such an approach is useful if processing notes that then can be archived away from still-current content.

    Using $Container with agent actions. Care needs to be taken as agents act on aliases. Therefore an agent action seeking to move a note must act on the original of the note, i.e. via $Container(original).

    Tinderbox is forgiving if a $Container is set with no trailing "/". For example, this agent action will work:

    $Container="/work/projects";

    However, this is the correct way:

    $Container="/work/projects/";

    The error (in the first example above) if the last container in the target path is a variable. For example:

    $Container="/work/"+$MyString(agent);

    Luckily that does work but should really be :

    $Container="/work/projects/"+$MyString(agent)+"/";

    Strings vs. StyledStrings in operator documentation

    Many dot-operators are intended to work on a literal string, the value of a String-type attribute or an action code expression resolving to a string. There are a small number of exceptions to this where the operator applies styled text styles to its output.

    Closing styles

    If this code is used:

    $Text = "This is " + "some".bold + " text."; 

    The result is "This is some text." This occurs because as with normal typing in $Text if a style is turned on the user must also turn it off. Thus the whole of the end of $Text is bolded, any new text added is also bolded. The way to avoid run on is to apply '.plain' to the next added segment.

    $Text = "This is " + "some".strike + " text.".plain; 

    The result is "This is some text." There is currently no way to add a plain 'closure' without applying it to at least one character. But adding a period to punctuation, e.g. ".".plain, or invisible characters , e.g. "\n".plain is possible.

    Passing styled text

    At present, $Text is the only attribute capable of holding such styled text. String attributes and action code variables, i.e. var, cannot store styled text. If passed styled text the latter will store the un-styled version of the text being passed.

    Thus, if we create a styled string and pass it direct to a styled text-capable String type, it works:

    $Text = "This is " + "some".strike + " text".plain; 

    The result is a $Text value of a "This is some text". Also if $MyString is "some":

    $Text = "This is " + $MyString.strike + " text".plain; 

    But if we try this:

    $MyString = "This is " + "some".strike + " text".plain; $Text = $MyString; 

    …the result is a $Text value of an un-styled "This is some text". So, a String-type attribute cannot hold styled text. The same is true if a variable is use for hold the result:

    var vStr = "This is " + "some".strike + " text".plain; $Text = vStr; 

    …again, the result is a $Text value of an un-styled “This is some text”.

    Type coercion, strings and numbers

    When attempting to reason about the type of the result of an action code expression in ambiguous situations, Tinderbox examines the values passed to binary operators like "+". If a value is interpretable as a number, Tinderbox prefers the numeric interpretation to a string. The rules for “interpretable as a number” were, however, too lax, and action code expressions such as

    "1883 – " + "1964" 

    were treated as numeric because (the opening) part of the first string is a number.

    Now, the string is regarded as a numeric value only if the entire string can be parsed as a number.

    If ambiguity is obvious to the user, it is preferable to use intermediate attributes or typed variables in order to avoid the ambiguity entirely and to signal user intent clearly to Tinderbox.

    Sorting Date-type data

    For detail on sorting a view using Date-types via Sort-group attributes, see Sorting Dates.

    Sorting (lists) in action code requires knowing the differing implications of lexical vs. numerical sorting. If not familiar, read that article to better understand the rest of this article. The relevant issue is the two sort types sort the "never" Date-type value differently:

    • Lexical sort: "never" comes last, as strings starting with numbers sorts after strings starting with letters. Reversing lexical sort places said items first.
    • Numerical sort: "never" comes first, as non-numbers (strings) coerce to no number, i.e. zero (0). Reversing numerical sort places said items last.

    Does this list position matter?

    No—except if we make assumptions that the "never" value is always in the same position. As, it turns out, it may be sorted first or last, some care is needed when working with sorted date lists.

    Sort operators

    A small number of action code operators perform sorts explicitly. That is their primary function, sorting lists (List and Sets:

    • .sort(). Lexical sort ("never" comes last).
    • .isort(). Case insensitive lexical sort ("never" comes last).
    • .nsort(). Numerical sort ("never" comes first).

    Sets: Self-sorting lists

    Be aware to that when placing Date-type data in a list, date is stored in a textual (string) for. The two attribute types behave differently:

    • List type. The list items are stored in the order they were created/added to the list. Thus a "never"remains where it was entered. The presence of such values is best found by sorting the List, taking care to remember whether a lexical or numerical sort is being applied.
    • Set type. As sets automatically de-duplicate values, is involves an implicit lexical sort. This means if any Date-type input is a default, the Set will have a list item of "never".

    List-creating operators

    The collect(), collect_if(), and list() all return List-type content. The data is normally list of notes (as $Name/$Path/$ID/$IDString data) but can collect Date values directly if so coded by the user.

    Operators with implied sort

    The max(), min(), List.max(), and List.min(), implicitly sort data. They are intended for Number-type data, so if used—arguably incorrectly—on a list of Date values, this implies doing a numerical sort on a list of string values, albeit strings starting with numbers. As such any "never" value present will sort at the beginning of the list.

    Beware .first and .last

    Do not mistake List.first() and List.last() as implying earliest/latest date. They simply return the first item in the list or the last, the same as using list[0] or List.at(-1).

    Other sort-related tasks

    Dates and filtering non-dates

    A Date-type attribute always has a value. The default value is "never", which when views as string isn't what would normally be considered an actual date. Taxes aren't paid on the date of "never" but on an actual day.

    However, the default value is useful, as it allows detection of dates that should have a valid date value but do not (yet!). But, in contrast, what if the need is to address only valid dates within lists of Date-type values? This is were some understanding of sorting dates is necessary (see parent article).

    There is no currently no 'first date' or last date' operator that auto-ignores default "never".

    Avoiding lists with default values

    One approach is plan ahead when collecting lists of dates and to avoid any default values. Thus:

    $MyList = collect(children,$StartDate) 

    might include values of never. But the latter can be avoided by instead using either of:

    $MyList = collect_if(children, $StartDate!="never",$StartDate) 
    $MyList = collect_if(children, $StartDate,$StartDate)  (shorter less obviously explicit form)

    Now $MyList cannot contain a non-date as the collecting process filters out all "never" values.

    But what if another process results in a list of dates that might contain a date? It might be templating to do this:

    $MyDates = $MyList - "never"; WRONG!

    This only works if $MyList contains zero or one occurrences of "never" as it removes the value only once. If two or more $MyList still contains unwanted values. Better is to iterate the list into a new list only retaining valid' dates. If the list is of date string (date values):

    	$MyList.each(anItem){
    		if(anItem != "never"){
    			$MyList2 += anItem
    		}
    	};

    Here two List-type attributes are used, but these could as easily be list-type variables. That holds to the next example as well.

    If the list is path/ID date for notes, the non-dates can be filtered like this (assuming the dates are in attribute $StartDate:

    	$MyList.each(aNote){
    		if($StartDate(anItem) != "never"){
    			$MyList2 += $StartDate(anItem)
    		}
    	};

    If used often these tests could be used in a user function for easy re-use.

    Macros

    Macros are encapsulated sections of text that may be used to insert larger or more complex sections of text back into the document or into exported pages. They are used in conjunction with the ^do()^ export code or do() action code. The former allows the user to insert the macro's output directly into exported text or HTML (as does do() if enclosed in ^value^. By contrast, internally do() is best used to populate string attributes values via actions and rules.

    Macros cannot, generally, evaluate export or action code, so might best be thought of sections of boilerplate text with configurable text inputs. An exception is that ^do()^ may use export code, but only within the context of export from Tinderbox. There is thus a subtle difference in the behaviour of export code vs. action code invoked macros with regard to how inline code is treated.

    Macros are managed via the Macro tab of the HTML Inspector.

    Macro utility can be used in both queries and actions.

    Within macros, the character $ prefixing a number has a special meaning which will be familiar to those who have used regular expressions before. $1 means "the first argument to the macro". This is actually the second argument in do(): the first is always the macro name (same applies to action and export versions). There is no limit to the number of arguments applied, though practicality precludes using excessive numbers; point being that unlike with regular expression back-references you may have more than 9 references, e.g. a $10.

    These are applied recursively, so that if we have a macro called "Petshop" whose value is simply: $1

    Then calling the macro…

    ^do("Petshop","This parrot is $2","dead!")^ 

    …will give us…

    This parrot is dead! 

    …whilst…

    ^do("Petshop","This parrot is $2","just sleeping.")^ 

    …will give us…

    This parrot is just sleeping. 

    In the above example note the need to allow for white space at string joins, so either a space between 'is' and '$2' or at the beginning of the second string.

    Another example, take a macro named 'dot' whose value is:

    <img src="anImage.gif" height="16" width="16" alt=""> 

    …is called as…

    ^do("dot")^ 

    …and results in…

    <img src="anImage.gif" height="16" width="16" alt=""> 

    As written, this is effectively just boilerplate insertion. To make this a more useful macro and allow it to set the image tag attribute's for name, height, width, and also set the alt to the image name then change the macro's value to:

    <img src="$1" height="$2" width="$3" alt="$1"> 

    …is called as…

    ^do("dot","pic.gif",20,30)^ 

    …that results in…

    <img src="pic.gif" height="20" width="30" alt="pic.gif"> 

    Or, if the code is

    <img src="$1" height="$2" width="$3" alt="$4"> 

    …called as…

    ^do("dot","pic.gif",20,30,"caption")^ 

    …that results in…

    <img src="pic.gif" height="20" width="30" alt="caption"> 

    If there is no caption, but no width/height, commas indicating a blank input should still be supplied:

    ^do("dot","pic.gif",,,"caption")^ 

    …that results in…

    <img src="pic.gif" height="" width="" alt="caption"> 

    Trailing omissions should still be observed, as below where $4 is not supplied:

    ^do("dot","pic.gif",20,30,)^ 

    …that results in…

    <img src="pic.gif" height="20" width="30" alt=""> 

    Whereas, a missed alt tag is not a show stopper, providing height/width tags with no value might be mistaken by a browser for a zero value. Better would be this macro code

    <img src="$1"^if($2)^ height="$2"^endIf^^if($3)^ width="$3"^endIf^ alt="$1"> 

    Escaping special macro characters. If you want to remove the special meaning from $ in a macro argument, precede it with a backslash \$. Commas in text strings should also be escaped lest they be parsed as argument delimiters, this . Similarly, any literal backslash \ must become \\. To insert a string like "Prices, $6 \ $16.", change the above macro to:

    <img src="$1" height="$2" width="$3" alt="$4"> 

    …and run as…

    ^do("dot","pic.gif",20,30,"Prices\, \$6 \\ \$16.")^ 

    …to get…

    <img src="pic.gif" height="20" width="30" alt="Prices, $6 \ $16."> 

    Export vs. internal use. In an export context the inline export code in the macro can only be accessed using the ^do()^ export code. Otherwise, all export/action code in the macro or input arguments is treated as literal text (but see the next paragraph below). For in-document actions, use the action code do() operator instead; export code should not be used inline in $Text except for actual export purposes.

    Export Code

    This section cover code specifically used in formatted export. Historically, export code was used both for formatted export of HTML. Whilst some export codes are closely tied to HTML use, most can be used for generating all sorts of formats, or even things as simple as plain-text CSV or tab-limited files.

    Use of export is discussed in the Export section of aTbRef. Also see the Export Inspector and export-related system attributes.

    Below is a list of specific 'export codes' using in export template notes:

    Export Codes - Full Listing

    The full list of Export Codes is split. Much of export code is now done using action code wrapped in a ^value()^ code. Older deprecated codes are not longer listed, and should not now be used, although they may still work (in old files for legacy purposes).

    Note: meaning of square brackets in code syntax.

    Valid Export Codes still in use:

    ^action( action )^

    Export Code Type: 

    Export Code Scope of Action: 

    Export Code First Added: 

    Export Code in Current Baseline: 

    Export Code Altered Since Baseline: 

     Calculation   [other codes of this type]

     n/a   [codes with similar scope]

     v4.0.0

     Baseline

     As at baseline


    ^action( action )^

    This code performs any action, or list of actions, that could be performed by an agent or rule. For simplicity, consider it as if it were a rule that is only run when a note is exported using the template holding the ^action()^ code.

    The action code in the action parameter is performed immediately. ^action()^ does not export anything itself. For example, to make a note with $Color of 'blue' change to 'red' if exported:

    ^action($Color="red")^ 

    will change the colour of the exported note to red. Note that the change of $Color made by the code above is permanent, i.e. it is now 'red' until changed otherwise.

    However, this operator allows manipulations for export use without needing, for instance, to hold the value in a user attribute first. Since action code added variables, a common use of ^action()^ if to read an attribute value and store a changed value in a variable that is then used in the exported 'text' of the output page.

    Also see, action(), ^value( expression )^.

    The internal equivalent is a normal action/rule statement, i.e. where is no point in using ^action^ internally. However, if you want some logic during export to change an internal attribute value (e.g. exported notes having a new colour), then use ^action^ in the context of your export codes.

    IMPORTANT: if using ^action()^ in the text of an exporting note (i.e. in $Text), remove all line breaks in the enclosed action code. Otherwise a mis-evaluation will occur as each code line will be treated as an HTML paragraph enclosed in <p></p> tags.

    ^ancestors( [start, list-item-prefix, list-item-suffix, end ])^

    Export Code Type: 

    Export Code Scope of Action: 

    Export Code First Added: 

    Export Code in Current Baseline: 

    Export Code Altered Since Baseline: 

     Creation of Links   [other codes of this type]

     Item   [codes with similar scope]

     v1.0.0

     Baseline

     11.0.0


    ^ancestors([ "start", "list-item-prefix", "list-item-suffix", "end"] )^

    returns links to all of the ancestors of this note (if any). Unlike the pre-v.4.6 format of links in a single line, with colons between the elements, this defaults to an HTML unordered list like other list-generating codes.

    If the optional start, list-item-prefix, list-item-suffix, end arguments are omitted then the default values of <ul>, <li>, </li>, </ul> are used.

    This allows you to format the group of links as an HTML list or table in the exact format you want, where "start" is quote-enclosed text that will be inserted before all of the links, "end" is text that will be inserted after all of the links, "list-item-prefix" is text that will be inserted before each link, and "list-item-suffix" is text that will be inserted after each link. See more on altering list type or other HTML output.

    If "Hierarchical lists" in the HTML pane of the preferences is unchecked, this will not work.

    Mark-up (export code) elements embedded in ^ancestors^ are evaluated.

    To get the pre-v.4.6 format use:

    ^ancestors("",""," : ","")^ 

    Exported links use the CSS class and target based on their underlying Tinderbox link values, if one is specified; the link type value is not picked up as a class name.

    Aliases export as discrete notes (if the alias' container is set to ExportChildren) with content of the original but was any contextual hierarchical inks appropriate to the aliases' location. The ^ancestors^ for an alias also export as the ancestors of the alias, not the ancestors of the source note.

    Any ancestor set to $HTMLDontExport=true is skipped.

    Item objects source and destination may be used in action code expressions to indicate from where data used within the operator's arguments is drawn.

    The export is relative to current rather than this, facilitating work with included files.

    From v11.0.0, the operator's list output omits notes that are not exported.

    ^backslashEncode( data )^

    Export Code Type: 

    Export Code Scope of Action: 

    Export Code First Added: 

    Export Code in Current Baseline: 

    Export Code Altered Since Baseline: 

     Export Mark-up   [other codes of this type]

     n/a   [codes with similar scope]

     v3.6.0

     Baseline

     As at baseline


    ^backslashEncode( data )^

    The ^backslashEncode^ code has been added for the convenience of exporting to JSON and JavaScript. ^backslashEncode^ prefaces single and double quotation marks with a single backslash.

    The action code equivalent is jsonEncode(). For example:

    ^value(jsonEncode("data"))^ 
    ^children( [template][,N] )^

    Export Code Type: 

    Export Code Scope of Action: 

    Export Code First Added: 

    Export Code in Current Baseline: 

    Export Code Altered Since Baseline: 

     Data Include   [other codes of this type]

     Item   [codes with similar scope]

     v1.0.0

     Baseline

     As at baseline


    ^children^

    Tells Tinderbox to include the immediate children of the current note (or agent) in the current web page using their default template file.

    ^children( template )^

    Tells Tinderbox to include the descendants of the current note (or agent) in the current Web page using the specified template file.

    ^children( template,N )^

    Tells Tinderbox to include only the first N immediate children of the current note (or agent) with the specified template file. If N is used without a template, a comma must be placed before N.

    This replaces the deprecated ^justChildren( template )^. The original ^children^ code was replaced by ^descendants^.

    ^children^ evaluates its template argument, allowing agents and containers to use action code expressions like

    ^children(^value($MyTemplate)^)^ 

    The HTMLDontExport settings of children are respected.

    IMPORTANT: If you build templates where the exported (HTML) documents where one document includes content from child/other Tinderbox notes, links to the included content from other documents will not get created. Tinderbox is not able to convert those links to #in-page-addresses within the overall target document. The same limitation applies to ^include()^.

    ^cloud( item, count] )^

    Export Code Type: 

    Export Code Scope of Action: 

    Export Code First Added: 

    Export Code in Current Baseline: 

    Export Code Altered Since Baseline: 

     Export Mark-up   [other codes of this type]

     Item   [codes with similar scope]

     v3.5.0

     Baseline

     As at baseline


    ^cloud( [item, count] )^

    This provides an HTML interface to the information displayed in the Get Info dialog's words tab. It displays the 100 most common words in the note, omitting stop words (there may be fewer words if there are fewer valid words in scope). The words are wrapped in tags to permit the most common words to be displayed in a larger font; the tags used may be customised through the new attributes HTMLCloud1Start/End, HTMLCloud2Start/End, etc.

    ^cloud^ takes two optional arguments:

    • item. This refers to a specific note by name, path, or by an item object keyword such as parent. If document is used or item is omitted, the scope is the whole whole document.
    • count. This specifies the maximum number of common words to be displayed.

    Examples:

    ^cloud^ 
    ^cloud(this,25)^ 
    ^cloud(/this/that/other/note)^ 
    ^cloud(Interesting Note, 75)^ 

    See also ^sectionCloud^, ^documentCloud^

    ^comment( data )^

    Export Code Type: 

    Export Code Scope of Action: 

    Export Code First Added: 

    Export Code in Current Baseline: 

    Export Code Altered Since Baseline: 

     Data Include   [other codes of this type]

     Item   [codes with similar scope]

     v1.0.0

     Baseline

     As at baseline


    ^comment( data )^

    All of the data within the parentheses of the ^comment^ is exported as an HTML comment. Thus:

    ^comment(This is a comment)^ 

    exports as an unseen HTML code comment as in:

    <-- This is a comment -->
    ^descendants( [template][,N] )^

    Export Code Type: 

    Export Code Scope of Action: 

    Export Code First Added: 

    Export Code in Current Baseline: 

    Export Code Altered Since Baseline: 

     Data Include   [other codes of this type]

     Item   [codes with similar scope]

     v1.0.0

     Baseline

     As at baseline


    ^descendants^

    Tells Tinderbox to include the descendants of the current note (or agent) in the current web page using their default template file.

    ^descendants( template )^

    Tells Tinderbox to include the descendants of the current note (or agent) in the current Web page using the specified template file.

    ^descendants( template,N )^

    Tells Tinderbox to include only the first N descendants of the current note (or agent) with the specified template file. If N is used without a template, a comma must be placed before N. In finding N matches, the first branch is to its tip, then all siblings then recursing up branch #1's sub-branches before starting branch #2.

    To export immediate children but not the children's descendants, see ^children( template )^. This replaces the old usage of ^children^.

    ^descendants^ evaluates its template argument, allowing agents and containers to use action code expressions like

    ^descendants(^value($MyTemplate)^)^ 

    The HTMLDontExport settings of children are respected.

    ^directory( item )^

    Export Code Type: 

    Export Code Scope of Action: 

    Export Code First Added: 

    Export Code in Current Baseline: 

    Export Code Altered Since Baseline: 

     Data Include   [other codes of this type]

     Item   [codes with similar scope]

     v1.0.0

     Baseline

     As at baseline


    ^directory^

    Exports the relative path for this web page's file from the top-level directory you selected for storing HTML files to this file (excluding the filename). This equates to $Container in HTML-exported name form.

    Example:

    For the note exporting to "/archives/May.html", ^directory(this)^ generates "archives/".

    The directory for this note is: "index/Automating_Tinderbox/Coding/Export_Code/Export_Codes_-_Full_Listing/"

    The location of the folder is described in the ^path^ article.

    ^do( theMacro [,argument, anotherArgument, etc.] )^

    Export Code Type: 

    Export Code Scope of Action: 

    Export Code First Added: 

    Export Code in Current Baseline: 

    Export Code Altered Since Baseline: 

     Data Include   [other codes of this type]

     Item   [codes with similar scope]

     v1.0.0

     Baseline

     As at baseline


    ^do(theMacro)^

    Allows you to use macros in HTML (and XML) export, where theMacro is a macro you have defined in Tinderbox.

    ^do(theMacro [,argument, anotherArgument])^

    Allows you to use macros in HTML (and XML) export, where theMacro is a macro you have defined in Tinderbox; and argument and anotherArgument are additional arguments that can be passed to the macro.

    There are no limits, within sensible reason, to the number of arguments that may be supplied.

    Read about macros for usage details.

    Internally, the do() operator may be used. For example

    ^value(do("macro, "arg1", ...))^ 

    Unlike do(), and specifically in the context of export, ^do^ will evaluate inline export code within the macro's code.

    ^do^ accepts the theMacro argument as a quoted string (to meet current action code usage for string data).

    ^docTitle^

    Export Code Type: 

    Export Code Scope of Action: 

    Export Code First Added: 

    Export Code in Current Baseline: 

    Export Code Altered Since Baseline: 

     Data Property   [other codes of this type]

     Document   [codes with similar scope]

     v3.0.3

     Baseline

     As at baseline


    ^docTitle^

    The name of the Tinderbox document (i.e. the OS filename). The '.tbx' file extension is omitted if present.

    Note that this data cannot be retrieved using action code.

    The ^docTitle^ of this TBX file is: "aTbRef-11".

    Via action code, use document["name"]. For example:

    ^value(document["name"])^ 
    ^documentCloud( [count] )^

    Export Code Type: 

    Export Code Scope of Action: 

    Export Code First Added: 

    Export Code in Current Baseline: 

    Export Code Altered Since Baseline: 

     Export Mark-up   [other codes of this type]

     Document   [codes with similar scope]

     v3.5.0

     Baseline

     As at baseline


    ^documentCloud( [count] )^

    This provides an HTML interface to the information displayed in the Get Info dialog's words tab. Here the scope is the whole TBX document. It displays the 100 most common words in the note, omitting stop words (there may be fewer words if there are fewer valid words in scope). The words are wrapped in tags to permit the most common words to be displayed in a larger font; the tags used may be customised through the new attributes HTMLCloud1Start/End, HTMLCloud2Start/End, etc.

    ^documentCloud^ takes one optional arguments:

    • count. This specifies the maximum number of common words to be displayed.

    Examples:

    ^documentCloud^ 
    ^documentCloud(50)^ 

    See also ^cloud^, ^sectionCloud^ 

    Below is the output from ^documentCloud(25)^. Note that ideally it should be placed in some form of HTML container rather than be allowed to spread across the page otherwise the visual impact is lost. Here anyway is the ^documentCloud(25)^ 'raw' output:

    action attribute attributes baseline code current data default item list may name note notes set string text tinderbox type used using value via view weekly  

    ^else^

    Export Code Type: 

    Export Code Scope of Action: 

    Export Code First Added: 

    Export Code in Current Baseline: 

    Export Code Altered Since Baseline: 

     Conditional Mark-up   [other codes of this type]

     n/a   [codes with similar scope]

     v1.0.0

     Baseline

     As at baseline


    ^else^

    If the condition specified in ^if( condition )^ is not true, then export everything from the ^else^ statement to the ^endif^.

    Thus:

    ^if($Width>5)^The $Width is greater than 5.^else^The $Width is 5.0 or less.^endIf^ 

    …which, depending on the outcome exports out either the string "The $Width is greater than 5." or the string "The $Width is 5.0 or less."

    Note there is no extended branching form, such as an 'else if' method. For that, nest further ^if()^ tests in the negative result branch (i.e. after the ^else^).

    ^endIf^

    Export Code Type: 

    Export Code Scope of Action: 

    Export Code First Added: 

    Export Code in Current Baseline: 

    Export Code Altered Since Baseline: 

     Conditional Mark-up   [other codes of this type]

     n/a   [codes with similar scope]

     v1.0.0

     Baseline

     As at baseline


    ^endIf^

    Indicates the end of the alternatives indicated by the ^if( condition)^ statement. This closing statement is not mandatory if there is no ^else^ branch to the resulting actions. Thus the following are acceptable alternatives:

    ^if(condition)^do stuff[end of template line auto-closes code] 
    ^if(condition)^do stuff^endIf^ 

    For the next test a closing ^endIf^ is mandatory:

    ^if(condition)^do stuff^else^do other stuff^endIf^ 
    ^file( item )^

    Export Code Type: 

    Export Code Scope of Action: 

    Export Code First Added: 

    Export Code in Current Baseline: 

    Export Code Altered Since Baseline: 

     Data Property   [other codes of this type]

     Item   [codes with similar scope]

     v1.0.0

     Baseline

     As at baseline


    ^file( item )^

    The filename of the file for the web page for an item (i.e. note). This is the combination of $HTMLExportFileName plus $HTMLExportExtension. If no item is supplied, it defaults to value of 'this'. If HTMLExportFileName is not manually set it is created dynamically at export from $Name, with the filename varying according to the length set in $HTMLFileNameMaxLength (for aTbRef it is currently set to: 100).

    The export filename of this note (^file^) is: 'file_item.html'.

    Via action code, use:

    ^value($HTMLExportPath.split("/").at(-1))^

    which gives: 'file_item.html'.

    Legacy

    The export filename of note "HTMLExportBefore" (^file(HTMLExportBefore)^) is: "HTMLExportBefore.html".

    But see that '^value($HTMLExportFileName+" + "+$HTMLExportExtension)^' gives: ' + .html' ← note the missing filename! The latter problem occurs as $HTMLExportFileName is not evaluated until export.

    ^host^

    Export Code Type: 

    Export Code Scope of Action: 

    Export Code First Added: 

    Export Code in Current Baseline: 

    Export Code Altered Since Baseline: 

     Data Property   [other codes of this type]

     Document   [codes with similar scope]

     v1.0.0

     Baseline

     As at baseline


    ^host^

    The host of the site of this web page. This is derived from the URL (Web server) setting in the HTML pane of document Preferences.

    The ^host^ value for this TBX file is: "" (i.e. nothing). In this document it is not defined but were it defined for the site's normal domain it would return "https://atbref.com"

    ^if( condition )^

    Export Code Type: 

    Export Code Scope of Action: 

    Export Code First Added: 

    Export Code in Current Baseline: 

    Export Code Altered Since Baseline: 

     Conditional Mark-up   [other codes of this type]

     n/a   [codes with similar scope]

     v1.0.0

     Baseline

     As at baseline


    ^if( condition )^

    ^if( condition )^ ^endIf^

    ^if( condition )^ ^else^ ^endIf^

    Test the condition, resolving to a true or false result:

    • if the condition is true, then include everything from the ^if()^ statement to the next ^else^ or the next ^endif^.
    • if the condition is false, then include nothing, or if an ^else^ branch is offered, include everything after the next ^else^ statement up to the next ^end^.

    Though an ^endIf^ closing marker is not mandatory, users—especially if new to export code—are advised to add one as it gives more clarity as to the end of the output of a true match to condition. If the ^else^/^endIf^ mark-up is omitted the text following the closing )^ of the if tag of the condition is returned up to the end of the current line/paragraph (i.e. up to the next line break in the template source code).

    Unlike in very early versions of the app—e.g. in old examples, the condition statement is a query written in action code (essentially the same syntax as if writing an if() action test. For example,

    ^if($Name.contains("tbx"))^Matched 'tbx' string.^endIf^ 

    …is true if the note's title contains the string "tbx", and exports the string "Matched 'tbx' string.". For a reversed test:

    ^if(!$Name.contains("tbx"))^No matched 'tbx' string.^endIf^ 

    …is true if the note's title does not contain the string "tbx", and exports the string "No matched 'tbx' string.". For a numerical test:

    ^if($Width>5)^The $Width is greater than 5.^endIf^ 

    …is true if the note's width exceeds 5.0 and exports out the string "The $Width is greater than 5."

    For the first two examples above the value matched can be an actual string or a regular expression.

    Using an ^else^ logic branch, different information can be exported for true and for false condition matches. Thus:

    ^if($Width>5)^The $Width is greater than 5.^else^The $Width is 5.0 or less.^endIf^ 

    …which, depending on the outcome exports out either the string "The $Width is greater than 5." or the string "The $Width is 5.0 or less."

    In the ^if^ condition, the condition query is always evaluated in the context of this note.

    Note there is no extended branching form, such as an 'else if' method. For that, nest further ^if()^ tests in the negative result branch (i.e. after the ^else^).

    ^include( ^value(item|group)^[, ^value(template)^] )^

    Export Code Type: 

    Export Code Scope of Action: 

    Export Code First Added: 

    Export Code in Current Baseline: 

    Export Code Altered Since Baseline: 

     Data Include   [other codes of this type]

     Group   [codes with similar scope]

     v1.0.0

     Baseline

     As at baseline


    ^include( ^value(item|group)^ )^

    A more generalised way to understand this operator is:

    ^include( which note(s), optionally using which template )^

    The first argument resolves to telling Tinderbox where it should look for the note(s) to process. The second argument uses that note's assigned export template or the optionally suppled template is used instead. It thus allows a different export template to be used to render the data returned via ^include^.

    This can be a useful method to export (parts of) a note in different ways via different template - but all from the same source note.

    ^include( ^value(item|group)^ )^

    Includes a single item or a group (i.e. list) of notes, using their default export template(s), in the web page for the current note. Note the requirement for the argument to be placed within a ^value()^ code, or else only incorrect.

    The item or group scope may also be set from an attribute holding a list of paths, a list-based variable or the returned value of a function.

    ^include( ^value(item)^, ^value(template)^ )^

    The item behaviour is as above but now Tinderbox uses the specified export template passed via template rather than each item's assigned/inherited export template.

    ^include( ^value(group)^, ^value(template)^ )^

    The same applies for group scope, but the same template is applied separately to each group list item.

    An example of using a template argument is given further below.

    Syntax for single item

    A quoted string literal can be used to specify a single item:

    ^include(^value("a note")^)^ 

    If the item is being assembled via a simple action code expressions such as string concatenation, an additional ^value()^ wrapper is needed to ensure the value passed to ^include()^ is an actual string or list:

    ^include(^value("Some"+" note")^)^ → include calls the note "Some note"

    If a stored attribute value is used :

    ^include(^value($MyString)^)^ 
    ^include^value(($MyString("Some note"))^)^ 

    In both cases above, $MyString must hold a single note's $Name or its full $Path value, oo $IDString (a Number-type could hold an $ID). Or else, here using a string-type variable 'vString':

    ^include(^value(vString)^)^ 

    Syntax for multi-item group

    A literal group reference via a literal list:

    ^include(^value([a note;another note])^)^ 

    If using an attribute with group scope:

    ^include(^value($MyList)^)^ 
    ^include(^value($MyList("Another note"))^)^ 

    Action code expressions that resolve to either item or group scope must also use a ^value()^ wrapper. The most common use with a query expression is a find():

    ^include(^value(find(inside(Some note)))^)^ 
    ^include(^value(find($Text.contains("Nelson")))^)^ 

    Using the Template optional argument

    The optional second argument specifies the export template to use when including is evaluated. Why might this be needed? In the basic form above, the operator tells the HTML export process to include data from other note(s) into the data being created for the currently-processed note.

    By default the nature of the included data is set via the target's export template (or the Tinderbox document's default export template). However, the most common use of an include is that only some data, e.g. just a few attributes or the text, are actually required. The template argument allows the user to specify a different, specific template for the inclusion task. template must be a valid template note in the current TBX document.

    The template argument is evaluated. So, as with the item/group input, template can be specified as a literal string, a string value stored in an attribute or an action code expression that resolves to a literal string holding a template $Name or $Path. For example:

    ^include(/colophon,^value($MyTemplate)^)^ 

    would export the top-level note named "colophon" using the template named in $MyTemplate for the note currently being processed. (not 'colophon'!). In other words, $MyTemplate is referenced for the context of the note calling the ^include()^ and not the note referenced by item (i.e. the note at path '/colophon').

    Thus it is possible to have both arguments parameterised, as in the following:

    ^include(^value($StringAttribute(ItemNameOrPath))^,^value($TemplateName)^)^ 

    Examples of template use

    An example to include attribute data: to get and include values of 3 attributes for 'a note', the process could call:

    ^include("a note", "3_attributes")^ 

    Where the template "3_attributes" has the template code:

    ^value($FirstName)^ ^value($LastName)^. Tel: ^value($Phone)^ 

    Of course, the same values could also be called as ^value($FirstName("a note"))^, etc., instead of using ^include()^. Choosing between the methods is a matter of style and the nature of the task.

    An example of embedding only a note's text. If the TBX's default export template generates a complete HTML page for note, then this code in Note A's text:

    ^include(^value("Note B"))^)^ WRONG!

    …would nest a complete HTML page's coding inside the <body> content of note A. A browser might cope, but this in not valid HTML use! Instead, it is necessary to specify a template that simply returns the relevant inline content markup: in this case ^text^ in a template called 'text-only'. The corrected include is:

    ^include(^value("Note B"))^,^value("text-only")^)^

    Note: the value of template must resolve to a single template note. template may note be 'raw' export code (as some other operators may allow):

    WRONG! ^include(^value("Note B"))^,^value("^text^")^)^

    Export and links into included (transcluded) content

    In is important to understand that Tinderbox will not generate HTML links for internal links that point to notes that are only exported via the ^include()^ method; consider linking to the note's (exported) parent note instead. The same implies to other forms of transclusive operator: e.g. ^children()^. Such links will not generate #in-page-anchor URLs. In other words, it is not possible, for exported pages to link to include-embedded content in other pages.

    Legacy Usage

    Although above it stipulates use of ^value()^ for both arguments in all cases, this is not strictly needed. The documentation is like this as it is very difficult for the novice or occasional user to guess if such an argument wrapper is truly needed. The default above will work regardless. Existing code that does not use ^value()^ will continue to work. Expert users who know where ^value()^ is not strictly necessary may continue to omit it. But canonical use is for ^value()^ enclosing each argument.

    ^indent( [data][, N] )^

    Export Code Type: 

    Export Code Scope of Action: 

    Export Code First Added: 

    Export Code in Current Baseline: 

    Export Code Altered Since Baseline: 

     Export Mark-up   [other codes of this type]

     Item   [codes with similar scope]

     v1.0.0

     Baseline

     As at baseline


    ^indent( [data][, N] )^

    Exports the data as a string, repeated once for each ancestor of the currently exported note (i.e. the equivalent of $OutlineDepth-1 times), or N times if the latter is specified.

    ^indent^

    Exports a tab character for each ancestor of the currently exported note except root level, i.e. tab is the default indent if no data argument is supplied.

    data. The number of times data or a tab is emitted is ($OutlineDepth-1); for aliases this is the alias' value and not that of the original.

    By original intent, this code applied to the (HTML) source of the exported note, but depending on string used for data, this might affect the visual render. Whereas the default \t only affects the HTML, a data value of &nbsp;&nbsp; would insert two non-breaking spaced per tab that would render in the output.

    N. The default can be superseded by supplying an optional second argument N. N is evaluated so may either be a number or an action code expression, e.g. $OutlineDepth+3. This kind of thing is useful if trying to correctly indent source code and when the export 'base' is at a level other than the root of the TBX.

    If the N argument is used, the data argument must also be supplied. To explicitly specify a tab, as in the normal default, use "\t", e.g. ^indent("\t",6)^.

    For web use, tabs are ignored for white space so consider using one or more "&nbsp;" space HTML entities as the data value.

    Examples

    In the source TBX document this note is at Outline Depth 6, so ^indent(data)^ will emit the data value 5 times. Thus, if we use a hyphen as the indent's data value, you see:

    -----Text indented with ^indent(-)^.

    In the next example the on-screen text should be visibly indented three (non-proportional) spaces:

         Text indented with ^indent(&nbsp;)^.

    Note how the visual HTML output of the next two examples is not visibly indented as tabs are not interpreted as white space mark-up in HTML, but are present in the HTML source:

    Text indented with ^indent^ (i.e. tab).

    Text indented with tabs to outline level plus 4 (i.e. ^value(eval($OutlineDepth+4))^ tabs, thus 10 tabs)

    Thus, if you view the HTML source for the page, you will see first of the two examples immediately above has output 6 tabs. For the example following it, you will see 10 tabs have been output; depending on the program viewing the source you may be able to 'see' these as tabs by moving the cursor through the source code with the arrow keys: you will see it jump from tab to tab.

    Root level notes are not indented.

    ^linkTo( item [, data] [,css class] )^

    Export Code Type: 

    Export Code Scope of Action: 

    Export Code First Added: 

    Export Code in Current Baseline: 

    Export Code Altered Since Baseline: 

     Creation of Links   [other codes of this type]

     Item   [codes with similar scope]

     v

     Baseline

     11.0.0


    ^linkTo( item [, data] [,css class] )^

    Exports the data as the anchor text of a link to the web page corresponding to the designated item (or note). The data can be simply some text or another export function's result and may include HTML mark-up code. The data argument is optional, and if not used the name of the destination note is used. The item can be a named note, an item object or a path (e.g. /headlines/latest/).

    If included, the css class element causes the HTML link output to include a class attribute.

    ^linkTo()^ exports links from included files relative to the current page.

    Example link to "Colophon": ^linkTo(Colophon)^ outputs 'Colophon'

    Same but with a data argument: ^linkTo(Colophon,Read the Colophon)^ outputs 'Read the Colophon'

    Same but with a data and css class argument: ^linkTo(Colophon,Read the Colophon,xref)^ outputs 'Read the Colophon'

    To get the relative URL of a note, use ^url()^.

    From v11.0.0, the operator's list output omits notes that are not exported.

    ^nextSibling^

    Export Code Type: 

    Export Code Scope of Action: 

    Export Code First Added: 

    Export Code in Current Baseline: 

    Export Code Altered Since Baseline: 

     Boolean Comparison   [other codes of this type]

     Item   [codes with similar scope]

     v5.0.0

     Baseline

     As at baseline


    ^nextSibling^

    A simple Boolean test for whether the currently processed note has a next sibling (N.B. not always the original's next sibling) and that the sibling is exportable. This is useful for export context where differing output is required when the current note is the last sibling. The test of export state allows for siblings that may exist yet be set to not export: not testing this could otherwise give a false indication that there is more exportable sibling content.

    This test also solves the problem of testing for siblings when exporting agent aliases or a sibling mix of originals and aliases.

    Example:

    ^if(^nextSibling^)^… 

    The test is analogous to testing nextSibling or lastSibling in an action code context.

    ^not(condition)^

    Export Code Type: 

    Export Code Scope of Action: 

    Export Code First Added: 

    Export Code in Current Baseline: 

    Export Code Altered Since Baseline: 

     Conditional Mark-up   [other codes of this type]

     n/a   [codes with similar scope]

     v

     Baseline

     As at baseline


    ^not(condition)^

    If the condition is true, ^not(condition)^ is false. This has limited usage, inside an ^if(condition)^ statement to reverse the boolean result of the test.

    As conditional queries are now written in action code, negatives can be expressed in the action lessening (removing?) the need for ^not^.

    For example:

    ^if(^nextSibling^)^Yes^endIf^ 

    will insert the text 'Yes' if there is a next, exportable, sibling. To reverse this it is possible to reverse the test and place the insertion in the logical 'else' branch:

    ^if(^nextSibling^)^^else^Yes^endIf^ 

    But use of ^not()^ can give more easily understandable code:

    ^if(^not(^nextSibling^)^)^Yes^endIf^ 

    If using action code query usage:

    ^if(nextSibling==false)^)^Yes^endIf^ 

    Note how the code wraps the condition inside the ^if()^.

    The ^not()^ code should not be used for negating condition queries written fully in action code syntax. So do not use a mix like:

    ^if(^not($MyString=="")^)^Yes^endIf^ 

    Instead, use:

    ^if($MyString!="")^Yes^endIf^ 

    In summary, this is a niche code that you should not expect to need except with export codes that are fixed boolean assessments and are being used in export code form in a condition argument. Most likely use is with testing ^previousSibling^ and ^nextSibling^ state.

    ^paragraphs( [item,] N )^

    Export Code Type: 

    Export Code Scope of Action: 

    Export Code First Added: 

    Export Code in Current Baseline: 

    Export Code Altered Since Baseline: 

     Data Include   [other codes of this type]

     Item   [codes with similar scope]

     v1.0.0

     Baseline

     As at baseline


    ^paragraphs( [item,] N )^

    Exports the first N paragraphs of the text of specified item (note). If item is not specified, ^paragraphs( N )^ equates to ^paragraphs( this, N )^.

    This method effectively allows insertion of only part of ^text^ whilst using the same inline evaluations for mark-up.

    Alternatively, for unevaluated $Text excerpts (no inline ^code evaluation) use ^value($Text.paragraphs(N))^. See ^value^, String.paragraphs.

    ^path[( item )]^

    Export Code Type: 

    Export Code Scope of Action: 

    Export Code First Added: 

    Export Code in Current Baseline: 

    Export Code Altered Since Baseline: 

     Export Mark-up   [other codes of this type]

     Document   [codes with similar scope]

     v1.0.0

     Baseline

     As at baseline


    ^path[( item )]^

    Exports the relative path for this web page's file from the top-level directory you selected for storing HTML files to this file (including the filename). This equates to $Path in HTML-exported name form. Optionally, item may be supplied, such as a note name^path(some note)^ or a designator ^path(original)^.

    This note's ^path^ is: 'index/Automating_Tinderbox/Coding/Export_Code/Export_Codes_-_Full_Listing/path_item.html'.

    This note's ^path(nextSibling)^ is: 'index/Automating_Tinderbox/Coding/Export_Code/Export_Codes_-_Full_Listing/previousSibling.html'.

    How is the (HTML) export directory set?

    This is done via the Export To button on the Export Inspector.

    Where is the export directory stored?

    The folder's path is stored in the <Preferences> part of the TBX's XML and is not accessible via action or export code. It can be (re-)set via the Export Inspector (as above).

    ^previousSibling^

    Export Code Type: 

    Export Code Scope of Action: 

    Export Code First Added: 

    Export Code in Current Baseline: 

    Export Code Altered Since Baseline: 

     Boolean Comparison   [other codes of this type]

     Item   [codes with similar scope]

     v5.0.0

     Baseline

     As at baseline


    ^previousSibling^

    A simple Boolean test for whether the currently processed note has a previous sibling (N.B. not always the original's previous sibling) and that the sibling is exportable. This is useful for export context where differing output is required when the current note is the first sibling. The test of export state allows for siblings that may exist yet be set to not export: not testing this could otherwise give a false indication that there is more exportable sibling content.

    This test also solves the problem of testing for siblings when exporting agent aliases or a sibling mix of originals and aliases.

    Example:

    ^if(^previousSibling^)^… 

    The test is analogous to testing prevSibling or firstSibling in an action code context.

    ^randomChildOf( item )^

    Export Code Type: 

    Export Code Scope of Action: 

    Export Code First Added: 

    Export Code in Current Baseline: 

    Export Code Altered Since Baseline: 

     Data Include   [other codes of this type]

     Item   [codes with similar scope]

     v1.0.0

     Baseline

     As at baseline


    ^randomChildOf( item, template )^

    Includes an export of a random child of the specified item or note through its default/specified template.

    Internally, the randomChild item object may be used, for unevaluated text (i.e. no inline ^code evaluation). For example:

    ^value($ID(randomChild))^ 

    In this example the retrieved $ID would then be used as a the target itim in an ^include()^. The ^randomChildOf^ abstracts this into a singe code

    ^randomLine( item )^

    Export Code Type: 

    Export Code Scope of Action: 

    Export Code First Added: 

    Export Code in Current Baseline: 

    Export Code Altered Since Baseline: 

     Data Include   [other codes of this type]

     Item   [codes with similar scope]

     v2.0.0

     Baseline

     As at baseline


    ^randomLine( item )^

    Scans the text of a designated item or note (or, if no argument is supplied, the current note). The text is split at paragraph breaks (e.g. carriage returns), and one line (i.e. paragraph) is chosen at random.

    Here is a random line from note "Specimen text for test":-

    This is a sentence. And another. Yet more. The first paragraph ends now. Now paragraph two follows. It has sentences too. Note very many, and it stops here. The third paragraph is not different. It too has sentences. It then finishes. ^do(Check)^ The fourth is the last paragraph. It completes here.

    Via action code, for unevaluated text (i.e. no inline ^code evaluation):

    ^value($Text.paragraphList.at(rand($Text.paragraphCount)))^ 

    See String.paragraphList and rand().

    ^root^

    Export Code Type: 

    Export Code Scope of Action: 

    Export Code First Added: 

    Export Code in Current Baseline: 

    Export Code Altered Since Baseline: 

     Export Mark-up   [other codes of this type]

     Document   [codes with similar scope]

     v

     Baseline

     As at baseline


    ^root^

    Returns the relative path from the current notes's exported file to the directory that contains the cover page. The relative paths generated will still work during internal preview (i.e. without any export being generated).

    When concatenating ^root^ with a path, do not add a trailing (folder) slash as this is created as part of the ^root^ output. Thus use:

    ^root^images/icon.gif 

    …and not…

    ^root^/images/icon.gif WRONG!

    Note that this is not necessarily the same as ^root(this)^, used in the case where a note (this) is embedded inside another note that is included in a page.

    The ^root^ of this file's source note is: (see your web browser's URL bar to see how this resolves in overall URL terms.).

    For additional finer control of relative path calculation, consider use of ^setRoot()^.

    ^sectionCloud( [item, count] )^

    Export Code Type: 

    Export Code Scope of Action: 

    Export Code First Added: 

    Export Code in Current Baseline: 

    Export Code Altered Since Baseline: 

     Export Mark-up   [other codes of this type]

     Group   [codes with similar scope]

     v3.5.0

     Baseline

     As at baseline


    ^sectionCloud( [item, count] )^

    This provides an HTML interface to the information displayed in the Get Info dialog's words tab. In this case the scope is 'section' (parent as indicated by item). It displays the 100 most common words in the note, omitting stop words (there may be fewer words if there are fewer valid words in scope). The words are wrapped in tags to permit the most common words to be displayed in a larger font; the tags used may be customised through the new attributes HTMLCloud1Start/End, HTMLCloud2Start/End, etc.

    Aliases are treated correctly—originally, aliases were ignored.

    ^sectionCloud^ takes two optional arguments:

    • item. This refers to a specific note by name, path, or by an object keyword such as parent.
    • count. This specifies the maximum number of common words to be displayed.

    Examples:

    ^sectionCloud^ 
    ^ sectionCloud(this,60)^ 
    ^ sectionCloud(/this/that/other/note)^ 
    ^ sectionCloud(Interesting Note, 40)^ 

    See also ^cloud^, ^documentCloud^

    ^sectionNumber( item )^

    Export Code Type: 

    Export Code Scope of Action: 

    Export Code First Added: 

    Export Code in Current Baseline: 

    Export Code Altered Since Baseline: 

     Data Property   [other codes of this type]

     Item   [codes with similar scope]

     v1.0.0

     Baseline

     As at baseline


    ^sectionNumber( item )^

    The hierarchical number of the item (note) based on the present hierarchy and outline sort order (i.e. it changes if the source Tinderbox file layout is altered); a number such as 1.3.2 is the second grandchild of the third child of the first top level note. It is the $SiblingOrder number of each ancestor joined by periods.

    If item is omitted, e.g. used as ^sectionNumber^, the number exported is that of the current note and is equivalent to ^sectionNumber(this)^

    If trying to do calculations based on this data, bear in mind that adornments, although not shown outside Map view, number as the last sibling in the level on whose Map they appear.

    The ^sectionNumber^ of this page's source note is: "2.6.2.6.1.38".

    Or, via action code use ^value(if($OutlineDepth >1){collect(ancestor,$SiblingOrder).reverse.format(".")+"."+$SiblingOrder;}else{$SiblingOrder};)^ giving: 2.6.2.6.1.38. In practice this code would be reduced by placing the action code logic in a custom function.

    ^setRoot( [newRoot] )^

    Export Code Type: 

    Export Code Scope of Action: 

    Export Code First Added: 

    Export Code in Current Baseline: 

    Export Code Altered Since Baseline: 

     Export Mark-up   [other codes of this type]

     Document   [codes with similar scope]

     v4.0.0

     Baseline

     As at baseline


    ^setRoot( [newRoot] )^

    The ^root^ code (see) normally exports the relative path from a note to the top level of the Tinderbox document. This is valuable for defining relative paths, especially in macros. But in some cases you may want a relative path in one page (an HTML page, say) and an absolute link in another (an RSS feed, where relative links may be forbidden).

    Thus, the export element

    ^setRoot(newRoot)^

    tells Tinderbox to use its first argument (newRoot) as the value of ^root^ until either

    • another ^setRoot^ is found.
    • the current file being exported is complete.

    To restore relative URLs, use ^setRoot()^ with no arguments.

    For example:

    ^setRoot(https://example.com/)^ 

    Using ^setRoot()^ to set the logical host or root path for a page affects not only ^root^ but also ^url^, ^childLinks^, and ^basicLinks^.

    ^siblings( [start, list-item-prefix, list-item-suffix, end] )^

    Export Code Type: 

    Export Code Scope of Action: 

    Export Code First Added: 

    Export Code in Current Baseline: 

    Export Code Altered Since Baseline: 

     Creation of Links   [other codes of this type]

     Item   [codes with similar scope]

     v2.1.0

     Baseline

     11.0.0


    ^siblings( ["start", "list-item-prefix", "list-item-suffix", "end"] )^

    returns links to all the siblings of this note, i.e. the other children of the note's parent. Output is formatted in a single line, with colons between the elements.

    If the optional start, list-item-prefix, list-item-suffix, end arguments are omitted then the default values of <ul>, <li>, </li>, </ul> are used. See more on altering list type or other HTML output.

    This allows you to format the group of links as an HTML list or table in the exact format you want, where "start" is text that will be inserted before all of the links, "end" is text that will be inserted after all of the links, "list-item-prefix" is text that will be inserted before each link, and "list-item-suffix" is text that will be inserted after each link.

    The $HTMLDontExport settings of siblings are respected.

    Mark-up elements embedded in ^siblings^ are evaluated.

    Exported links use the CSS class and target based on their underlying Tinderbox link values, if one is specified; the link type value is not picked up as a class name.

    Item objects source and destination may be used in action code expressions to indicate from where data used within the operator's arguments is drawn.

    The export is relative to current rather than this, facilitating work with included files.

    From v11.0.0, the operator's list output omits notes that are not exported.

    ^similarTo( item, count[, start, list-item-prefix, list-item-suffix, end] )^

    Export Code Type: 

    Export Code Scope of Action: 

    Export Code First Added: 

    Export Code in Current Baseline: 

    Export Code Altered Since Baseline: 

     Creation of Links   [other codes of this type]

     Item   [codes with similar scope]

     v3.5.0

     Baseline

     11.0.0


    ^similarTo( "item", count[, "start", "list-item-prefix", "list-item-suffix", "end"] )^

    The HTML Export element ^similarTo^ locates notes that appear similar to a given note.

    The query will find up to count notes, but may find fewer, and exports a list of notes it finds. The count argument is not evaluated so must be stated as a literal value and not an action code expression.

    Basic form, returning links to the 10 most similar notes:

    ^similarTo("this",10)^ 

    The longer form is only needed if it is desired to use non-default list HTML mark-up or include extra per-item captioning. If one of the option input is specified, all the others must also be, even if only as the default value(s).

    If the optional start, list-item-prefix, list-item-suffix, end arguments are omitted then the default values of <ul>, <li>, </li>, </ul> are used. See more on altering list type or other HTML output.

    The code must be used in $Text or directly in a template. If used in a code include to a template, the links generated will have incorrect relative paths.

    Similarity is based on several factors, including:

    • the text of the note
    • the note title
    • any text contained in user attributes

    In addition, weighting is applied for:

    • notes having the same prototype
    • notes having roughly similar amounts of text

    The results are based on the same logic as the similar tab of the Get Info dialog. The same matching is also available as an action similarTo().

    New item objects source and destination may be used with list/item inputs to indicate from where data used within such inputs are drawn.

    The export is relative to current rather than this, facilitating work with included files.

    From v11.0.0, the operator's list output omits notes that are not exported.

    ^text( [item, N, plain] )^

    Export Code Type: 

    Export Code Scope of Action: 

    Export Code First Added: 

    Export Code in Current Baseline: 

    Export Code Altered Since Baseline: 

     Data Include   [other codes of this type]

     Item   [codes with similar scope]

     v1.0.0

     Baseline

     As at baseline


    ^text( [item][, N] [, plain])^

    The body (text and graphics) of the item or note, i.e. includes any existing mark-up. If a note name is not specified, 'this' is assumed as the focus. The parentheses my be omitted if no arguments are supplied.

    ^text^ exports the current note

    ^text(this)^ exports the current note

    ^text(/Tasks/Task1)^ exports the $Text of note at path '/Tasks/Task1'

    ^text("Task2")^ exports the $Text of note 'Task2'

    Item can also be a string attribute holding a path or title of a note. Thus if $MyString has the value "Task2"

    ^text($MyString")^ exports the $Text of note 'Task2'

    If the note only contains an image, the image's tag (<img>) is exported.

    Alternative usages…

    N words of $Text

    The first N words of the text of the item or note, where N is a number (N.B. item must be specified too). Here the first 5 words of the current note's HTML-rendered $Text are inserted:

    ^text(this, 5)^ 

    Alternatively, the first N words of the text of the item or note, without added HTML mark-up and where N is a number (again note that item must be supplied). Here the first 10 words of the current note's un-rendered $Text are inserted:

    ^text(this, 10, plain )^ 

    Plain text export

    If no HTML text mark-up is required. This inserts the $Text of the current note without any added HTML mark-up codes

    ^text(this, plain )^ 

    N.B. The 'plain' option is still subject to the effects of $HTMLQuoteHTML and $HTMLMarkupText. For instance, if the latter is true, then the phrase "This & that." will get exported as "This &amp; that." which might not be as intended, e.g. if exporting via runCommand().

    Alternatively, to get the text of the note, totally untouched by other processes (such as $HTMLQuoteHTML), use ^value($Text)^ which is effectively the same as ^text(this, plain)^.

    ^title( [item] )^

    Export Code Type: 

    Export Code Scope of Action: 

    Export Code First Added: 

    Export Code in Current Baseline: 

    Export Code Altered Since Baseline: 

     Data Include   [other codes of this type]

     Item   [codes with similar scope]

     v1.0.0

     Baseline

     As at baseline


    ^title( [item] )^

    The title of the item or the current note if not specified note. The value is the same as the Name attribute, but using HTML entities where appropriate (see below for plain text export). The parentheses my be omitted if no arguments are supplied.

    The ^title^ of this page is: "^title( [item] )^".

    The ^title^ of note "Conditional Mark-up" (using code ^title("Conditional Mark-up")^) is: "Conditional Mark-up".

    Export and HTML entities

    To avoid the use of HTML entities when exporting a note's title use the ^value()^ code:

    ^value($Name)^ 

    which for this note renders as: "^title( [item] )^".

    ^url( item )^

    Export Code Type: 

    Export Code Scope of Action: 

    Export Code First Added: 

    Export Code in Current Baseline: 

    Export Code Altered Since Baseline: 

     Creation of Links   [other codes of this type]

     Item   [codes with similar scope]

     v1.0.0

     Baseline

     11.0.0


    ^url( item )^

    The relative URL of the exported HTML web page for the item. The URL of an alias to a note is the URL attribute of that note's original. It is effectively ^host^ + ^path^ + ^file(note)^.

    Do not confuse this with ^value($URL)^ which will return the content of the note's URL field.

    ^url(this)^ will return the relative path from the current page to the page the included note creates when it is exported. If the note is not exported, but only appears on included pages, ^url(this)^ is undefined.

    As ^url()^ only supplies the 'href' argument value for an HTML link, if you want to customise your link, e.g. by setting a CSS class argument, you can do that in the template rather than needing to do so in the TB code itself.

    ^url(this)^ gives a relative path from the current page to the note; by comparison, ^path(this) gives the path from the top level of the site to the note. Thus:

    ^url(BorderBevel)^ gives: "index/Automating_Tinderbox/Coding/Use_of_Attributes/Attribute_Listings/System_Attribute_List/BorderBevel.html".
    ^path(BorderBevel)^ gives: "index/Automating_Tinderbox/Coding/Use_of_Attributes/Attribute_Listings/System_Attribute_List/BorderBevel.html".
    ^url(this)^ gives: "index/Automating_Tinderbox/Coding/Export_Code/Export_Codes_-_Full_Listing/url_item.html".
    ^path(this)^ gives: "index/Automating_Tinderbox/Coding/Export_Code/Export_Codes_-_Full_Listing/url_item.html".

    To make a deliberate 'manual' HTML link to another note see ^linkTo()^.

    From v11.0.0, the operator's list output omits notes that are not exported.

    ^value(actionStr)^

    Export Code Type: 

    Export Code Scope of Action: 

    Export Code First Added: 

    Export Code in Current Baseline: 

    Export Code Altered Since Baseline: 

     Data Include   [other codes of this type]

     n/a   [codes with similar scope]

     v4.0.0

     Baseline

     As at baseline


    ^value(actionStr)^

    The argument to ^value^ is evaluated actionStr code, such as returns a value that could be assigned to an attribute. ^value^ evaluates the code and exports the result, as a string (some data types may also require the format() operator too). This allows manipulations for export use without needing to, for instance, hold the value in a user attribute first.

    ^value^ is a more flexible replacement version of the deprecated codes ^get^ and ^getFor^ but which still allows the called attribute's value to be manipulated. For example:

    ^value($Width)^ 

    exports the width of the current note. To export that attribute value for a different note (than in current scope) use action code style offset addressing. So, to call the value of $Width for "Some Other Note" rather than from the currently-processed note, use:

    ^value($Width("Some Other Note"))^ 

    Examples

    Number-type data:

    ^value(sqrt($Width))^ gives: "1.732050807568877".
    ^value(sqrt($Width).format(2))^ gives: "1.73".

    String-type data:

    ^value("$Name: "+$Name(parent))^ gives: "$Name: Export Codes - Full Listing".
    ^value($Name(parent)+":"+$Name)^ gives: "Export Codes - Full Listing:^value(actionStr)^".

    Note that ^value($Text)^ equates to ^text(plain)^.

    Color-type data:

    ^value($AccentColor)^ gives: "dark warm gray dark".
    ^value(format($AccentColor))^ gives: "#403a35".
    ^value($AccentColor.format())^ gives: "#403a35".

    Date-type data:

    ^value($Created)^ gives: "2007-07-06T02:54:36+01:00".
    ^value(format($Created,"l h:mm"))^ gives: "06/07/2007 02:54".
    ^value($Created.format("l h:mm"))^ gives: "06/07/2007 02:54".
    ^value(format($Created,"l"))^ gives: "06/07/2007".
    ^value($Created.format("l"))^ gives: "06/07/2007".
    ^value(format($Created,"*"))^ gives: "Fri, 6 Jul 2007 02:54:36 +0100".
    ^value($Created.format("*"))^ gives: "Fri, 6 Jul 2007 02:54:36 +0100".

    N.B. Unformatted Date-type data returns the host OS' local "short date" format plus time (in hh:mm form). For the aTbRef author's UK-locale OS that equates to a format string of "l h:mm" but it may vary for other OS locales. However, a date format string must be given if format() is used, whilst .format() at least gives some output:

    ^value(format($Created))^ gives: "" (no date format string supplied!).
    ^value($Created.format())^ gives: "06/07/2007, 02:54" (no date format string supplied!).

    See also ^action ( action )^ usage which allows action code to be run during export.

    Another useful aspect of ^value^ is that it gives access during export to 'raw' attribute data without any process. That is why there is the reference above to some data types needing use of format(). The upside of this raw state is attributes like HTMLMarkupText and HTMLQuoteHTML have no effect; unlike older versions non-ASCII are not encoded. If using the HTML Export process to generate/export formats other than HTML or if accessing the command line it is often necessary to use different forms of escaping. These different outputs can be achieved by using the action code formatting operators within the ^value()^ call. For exporting $Text, in HTML format, ^text^ will give a better result but for other export formats ^value($Text)^ may suffice.

    Passing variables into export code

    ^value()^ can be used, within the context a single template, to insert a var() variable declared within an ^action()^ code. Note that the variable must be declared before use, i.e. before as in reading template code top to bottom.

    Replacing deprecated export codes

    ^value()^ replaces both the deprecated ^get()^ and ^getFor()^ codes. ^get()^ maps to ^value($SomeAttribute)^ and ^getFor()^ maps to offset use ^value($SomeAttribute("Some Other Note))^. If existing documents use the older codes they will work for the present but it is highly recommended updating them to use ^value()^ instead.

    ^version^

    Export Code Type: 

    Export Code Scope of Action: 

    Export Code First Added: 

    Export Code in Current Baseline: 

    Export Code Altered Since Baseline: 

     Data Property   [other codes of this type]

     Document   [codes with similar scope]

     v1.0.0

     Baseline

     As at baseline


    ^version^

    The version number of Tinderbox used to create this web page. The number is exported as a string without a prefix, i.e. "4.6.0" not "v4.6.0".

    The ^version^ for this file is: "11.8.1".

    The action code equivalent is version(). For example:

    ^value(jsonEncode("data"))^ 

    Export Code Types

    Export codes can perform various sorts of roles:

    Boolean Comparison

    These codes all result in a Boolean true/false.

    Calculation

    These codes calculate values which are then added to the output data.

    Conditional Mark-up

    These codes create the framework for assessing Boolean conditions. The basic structure is:

    if ( [not] (condition) ) result1 else if ( [not] (condition) ) result2 else result3 endif.

    The optional 'not' argument reverses the conditional check to matching false instead of true.

    Data Include

    These codes add data to the exported content.

    When including children that are aliases using the codes listed here, children that happen to be aliases are included as aliases. Previously, the original was included.

    Since for most purposes the alias and its original are interchangeable, this change will seldom affect export. The nuance here is that intrinsic properties of the alias ($Xpos, $Ypos, $Height, $Width, $SiblingOrder, and so forth) are exportable.

    Data Property

    These codes return various properties, some from attributes, preferences or just with information about the document or the program itself (e.g. the version number). These are similar to the Data Includes in that they add data to the export but are more focused in their scope.

    Export Code Scope

    A fair percentage of Export Codes reference either a group (e.g. the children group designator) or an item (either a note by name or via an item designator). In some cases the object or group may be derived from an action code expression but do not assume arguments are evaluated unless this is documented so for the given code. The various scopes are listed below:

    Document-based

    Export codes that operate at document scope:

    Group-based

    A family of HTML Export mark-up elements operates on groups of notes. For example:

    ^every(child, attribute)^ 

    returns true if every child of the note has an attribute value of true, and false otherwise.

    If the group is empty, the group operator returns the value of the attribute for the current note.

    For example, ^any(child,$Urgent)^ returns the note's current value of $Urgent for notes that have no children. This makes it easier to construct rules, reducing the need for |= and complex ^if^ constructions.

    The possible referenced groups include:

    The codes are:

    Item-based

    These code work in the context of a single item:

    Using Export Code

    Tinderbox has 46 built-in 'export codes' associated with HTML and text export, including export macros. Although they may be used in actions, queries and rules such use outside an export context is strongly deprecated and likely to less well supported, or not supported at all, in forthcoming versions. Action code has been developed for 'internal' use, i.e. in queries/action/rules as opposed for actual export from Tinderbox and thus internal use of export codes is strongly deprecated (though often still legacy-supported) in favour of the new syntax.

    Export codes can be used anywhere in the template HTML (or other format) file, though bear in mind the above developments and guidance. Export codes are marked with a caret (^) symbol, entered by typing Shift+6. All export codes start with a caret and—optionally—also end with one. In many cases the closing caret can be omitted, e.g. for brevity in complex ^if()^ statements. However, to ensure Tinderbox emits 'clean' HTML (with proper tag nesting) always include the the closing caret if a code comes at the end of a paragraph or note and the is no whitespace after it. The advice here to new users is to always include the closing caret, regardless.

    A typical scenario is putting ^childLinks at the end of a note; the HTML output will render but it is better to put ^childLinks^ to ensure correct nesting of HTML tags. Without the closing ^ mark-up Tinderbox has to make a guess and will wrap the link list in

    tags creating code that will not validate (if meeting such a criterion is required). Although Tinderbox generally guesses export code closures correctly, it is better practice for the user expressly to close their codes to avoid any ambiguity during processing.

    Arguments. Export codes usually have one or more arguments; there is a separate listing explaining the meaning of code arguments such as 'item', 'data', etc.

    Evaluation of arguments. Individual code arguments may be evaluated, i.e. allowing substitution of export code or regular expressions, date placeholders, etc., for explicit argument values. However, at present there is no way to tell if a given code's arguments are evaluated (unless it says so here in aTbRef) other than by trial and error (or asking Eastgate directly). One, all or no arguments may be evaluated for any given code. It is safest to assume an argument is not evaluated unless there is clear evidence in the notes to the contrary. Unlike in action code where attributes references are marked by using a $ prefix with the attribute name, this is not done in export code, though such syntax may work if used.

    Tinderbox uses ^ as a delimiter for export elements such as

    ^title^ 
    ^value($Name(parent))^ 

    It is not a requirement to provide a closing caret at the end of the code, though not doing so leaves Tinderbox to have to guess the users intent. The guess is normally right, but for the sake of an extra character you can avoid the guesswork. New users, especially, are advised to always close their export codes with a caret, thus:

    ^title ← works but deprecated for new users 
    ^title^  ← safer usage

    Sometimes, however, a caret is simply a caret. Two common cases appear:

    *errors, where we specify an export element that does not exist because we have mistyped the name: ^tite^, ^value($Name(parant))^

    • uses of carets that are not intended for Tinderbox, such a regular expressions in JavaScript scripts.

    Tinderbox exports a space after an caret in an unrecognised export element, because expressions like

    $MyName=^Name^ ← WRONG

    could loop infinitely. (The user doubtless meant to write either $Name or ^title^; there is no export element ^Name^). Thus on saving the note or dialog, Tinderbox would insert a space, thus:

    $MyName=^ Name^ 

    Exporting the extra space works well in some contexts, but not when the caret is part of a regular expression in, for example, JavaScript. The additional space is exported only if the name could be a mark-up element:

    ^Name^ → ^[space]Name^ 
    ^Title^ → ^[space]Title^ 

    but

    ^[a-z] ^ → ^[a-z]^ 

    In post-v4 use there is also a de facto move to expect explicit quoting of all string literals (with double-quotes, ""), a significant exception being path arguments (e.g. path, partial path or note name) and designators which by convention are not quoted. Doing this will tend to pre-empt unexpected failures of user code.

    There are syntax considerations for colour and date type attributes when read:

    *^value($ColorAttribute/format())^. In HTML Export, named colours are exported as hex code strings which include the # prefix character, e.g. "#99ff00".

    *^value($DateAttribute.format("formatString"))^. The format string is optional. Tinderbox offers numerous date formats.

    Altering mark-up for Export Code generated lists

    There are a number of export codes that generate lists of links. By default, they generate an unordered (bulleted) HTML list, i.e.

       <ul>
          <li> … </li>
       </ul>

    Those 4 HTML tags can be modified by supplying 4 optional arguments:

    ^basicLinks( "start", "list-item-prefix", "list-item-suffix", "end" )^ 

    Thus using:

    ^basicLinks( )^ 

    is functionally the equivalent of a more explicit:

    ^basicLinks( "<ul>", "<li>", "</li>", "</ul>" )^ 

    Using any one of these optional arguments, i.e. changing the HTML tag for one, requires all four inputs to be explicitly stated. Thus:

    Incorrect: ^basicLinks( , '<li class="xlist">', , )^ 
    Correct: ^basicLinks( "<ul>", '<li class="xlist">', "</li>", "</ul>" )^ 

    Setting a numbered list style

    To change a bulleted list to a numbered list, give all four inputs, but change the first and last inputs (re-specifying the defaults for the other tow), thus:

    ^basicLinks( "<ol>", "<li>", "</li>", "</ol>" )^ 

    Export Codes with link type filtering

    A subset of list-generating codes that allow filtering by link type use a fifth option input giving the link type(s) to be included in the list:

    ^inboundBasicLinks("start", "list-item-prefix", "list-item-suffix", "end", "type" )^ 

    For these codes, if the 'type' argument is supplied, all other arguments must be supplied even if not customised, e.g.

    ^inboundBasicLinks()^ 

    or

    ^inboundBasicLinks( "<ul>", "<li>", "</li>", "</ul>", "(example|untitled)" )^ 

    Debugging user Export code

    In additions to the techniques suggested for Action code debugging, consider:

    • Using ^action()^ to record template-only calculations back into user attributes for later inspection. This is useful with complex exports. Once the export process is validated, instead of using attribute values, action code variables can be used instead. If using variables to store sections of pre-evaluated code, it is a good idea to purge the attributes after use. By comparison variables are non-persistent and so purge themselves.
    • Using the text pane's HTML and Preview tabs to check export code before actual export.
    • Full HTML export looks at whether source attributes have changed, thus changes in templates code are not 'seen' and the process can become obfuscated in complex include exports. One way around this is simply to delete (or move) previously exported files as full export will export a note if it is not found at the export location.
    • The File menu ▸ Export Selected Note option can 'force' export a single note, though note the offered filename may not be that used in full export if the note's automatically derived filename is not unique within the scope of its present container. If exporting over a previous full export, select the old filename in the export location dialog so the name is re-used and the new file overwrites the old one.
    • The effects of $HTMLDontExport and $HTMLExportChildren on the use of ^include^. The latter cannot return data from a note that is configured to not export.
    • For $Text export using ^text^ remember the effects of $HTMLMarkupText and $HTMLQuoteHTML.
    • The slightly different effects of ^title^ vs. ^value($Name)^ and ^text^ vs. ^value($Text)^.

    Export Code Arguments

    The argument action refers to a statement that can be evaluated as if an Action or Rule.

    The arguments argument and anotherArgument refer to text or code supplied as macro arguments.

    The argument attribute refers to an explicit attribute name.

    The argument count refers to a number, in figures, e.g. 5 not five.

    The argument css class is the (text) name of a CSS mark up class.

    The argument data (data1, data2, etc.) refer to either:

    • an explicitly entered value.
    • an attribute's value.
    • a regex (i.e. regular expression)

    The argument date refers to either:

    • an explicit date "2 Feb 2007".
    • a date object, e.g. today, yesterday - 5.
    • a date attribute, ^value($MyDate("some other note").format("formatString"))^.

    The argument's action code expression refers to a statement that can be evaluated and assigned to an attribute.

    The argument format refers to either:

    The argument group is either:

    • a relative reference to a group of notes or agents, like in ^any([group], AttributeName)^.
    • another export code that gets evaluated in to a group, like in ^value(expression)^.
    • a predefined group designator (e.g. descendants, etc.,).

    The argument item is either:

    • a note or agent's name, like in ^value($Name)^.
    • a relative reference to a note or agent, like in ^value(AttributeName([item])^.
    • another export code that gets evaluated into a note or agent's name, like in ^value(expression)^.
    • a predefined item designator (e.g. child, etc.,).

    The argument N refers to a number, in figures, e.g. 5 not five.

    The argument precision refers to the number of decimal points that are exported.

    The argument path refers to the path to a note or agent (including the latter's Name).

    The arguments start, list-item-prefix, list-item-suffix, end refer to optional alternate HTML mark up and text for a list of links.

    The argument target refers to either:

    • a (text) string value to be matched against. Number and other value types are effectively treated as strings for comparative purposes.
    • an attribute value.

    The argument template refers to a template file name either:

    • stated as a string.
    • stored in a named attribute.
    • inherited as a default from Preferences.

    Export argument values may be enclosed in double quotes, especially if doing so can help avoid parsing difficulties; the enclosing quotes will be ignored by the parser. Use of quotes for string values is recommended. This is because many new operators have been added and the scope for misinterpretation of string literals as code has increased. For example, if a note is named…

    she/he 

    …the comma would confused the parser in expressions like:

    ^linkTo(she/he)^ <- will not work

    …so this may (optionally) be written with double quotes:

    ^linkTo("she/he")^ 

    Characters warranting explicit quoting are those that may be mistaken for simple maths or equality operators: so, + - * / = ! | & > < |= &= != >= <= etc!

    Link lists can use two new references in their optional mark-up arguments:

    • source: refers to the note that is the source of the link.
    • destination: refers to the note that is the destination of the link.

    Tinderbox URL schema

    Tinderbox has its own private pseudo-protocol URL scheme. Entering a Tinderbox URL in a browser or similar program will launch Tinderbox (if installed!) and request specific actions.

    The schema is as follows:

    tinderbox://document/path?action 

    The protocol handler for tinderbox:// URLs will automatically open and bring to focus documents in the Recent Files list as well as documents that are already open.

    A Tinderbox URL pointing at (selecting) the current note in the current view type can be copied to the clipboard using the Note menu or the view pane selection's context menu. This URL is also exposed for any note via the read-only $NoteURL attribute. The desired selection is cited by that note's $ID. If there is a multiple selection the discrete $IDs are a semi-colon delimited list.

    document is the name of an open document, without the '.tbx' file extension.

    path is a conventional Tinderbox path within the document to a specific note (or container).

    actions, which may be multiple, joined with an ampersand.

    Schema Actions

    pane, which opens an inspector to the designated pane (there is no documentation of valid pane values):

    ?inspect=pane 

    view, selects a tab with the designated parent and view type, or creates a new tab in no existing tab can be found. Allowed values for viewType include {map, outline, chart, attributeBrowser}.

    ?view=viewType 

    select, which selects the desired note(s) when the target document takes focus:

    ?select=ID 

    Thus:

    tinderbox://Notes/Issues?select=1429560859 
    tinderbox://Notes/Issues?select=1429560859;1429458942 
    tinderbox://Notes/Issues?select=1429560859&view=map 

    Coding conventions

    How many discrete code syntaxes does Tinderbox use? Two: action and export. The former is used internally and is Tinderbox's scripting 'language'. Export code is used only for 'HTML' export purposes, enabling the insertion of mark-up and links int the exported text. In both types of code arguments are supplied as a comma-delimited list within parentheses (i.e. normal brackets), being comma-delimited if there is more than one.

    Whitespace in codes. For codes using parentheses to hold inputs, there must be no whitespace between the last character of the code and the opening parenthesis. Within the parentheses, additional whitespace—e.g. between arguments or in action code expressions—is ignored.

    Action code syntax. Used within Tinderbox documents for use with rules, agents, $OnAdd and the like. Action code operators are case sensitive. More on Action code syntax.

    Export code syntax. The original Tinderbox automation syntax was 'export code', used for exporting code to web(log) pages; such code is always started and ended with a caret symbol (^, typed via shift+6). Expert users may optionally omit the closing carets though this leaves Tinderbox to infer where a code ends. Originally, Export code could also be used internally in actions and queries but this is now deprecated. As most export task-specific codes can be replicated using an action code enclosed in the ^value()^ export tag and so many of the export codes are now deprecated in current use.

    Query codes. All now deprecated as there are direct action code replacements. You might still see query codes in agent queries in old files. Such codes start with a hash (#) and all have direct action code replacements.

    Case-sensitivity

    Attributes and action codes are always case-sensitive, both for system and user attributes. The convention is to use 'CamelCase', i.e. initial capital and capitals for concatenated words; thus the convention would suggest MyString as a user attribute name but alternates such as mystring, Mystring would also work but—importantly—as different attributes from MyString.

    Unlike attribute names, export codes are case insensitive but convention when using them is to capitalise internal word joins but not the initial letter; thus 'correct' usage takes forms like ^endIf^, urlEncode but you will find URLEncode, UrlEncode, UrLeNcOdE, etc., will all work just as well.

    Documentation will tend to follow the conventions, but feel free to use different casing if it works for you. More on case sensitivity.

    Attribute name limitations

    This is discussed under Attribute Naming.

    Use of parentheses in export code

    In export code where no arguments are required, parentheses can usually safely be omitted. With codes whose only argument is 'item', the parentheses can usually be omitted is the desired scope is 'this'. Thus ^title^ is equivalent to ^title(this)^.

    Delimiting arguments

    A comma is used as the delimiter between arguments. Some arguments may be optional. Any syntax examples in the manual or Release Notes where argument(s) are listed in square brackets (e.g. [data]) are optional.

    A notable exception to the comma as a delimiter is the links() operator where a dot (period character) notation is used.

    Where arguments allow non-quoted text strings, if the string includes a comma the whole string should be quoted.

    Legacy constraints:

    *General code conventions from v5.0.0:

    • all action references to attributes, both left and right side of operations now take a '$' prefix. A significant exception is that the AttributeName(regex) operator does not take a $ prefix.
    • all action code literal strings are now double-quote enclosed.
    • export codes use a mix of quoted/non-quoted on a code-by-code basis (i.e.see notes on the individual codes).
    • where possible export code is now deprecated in favour of action code, i.e. everywhere except in an export context. Support for internal use of export code is likely to be dropped in the future so existing code should be updated to reflect this.
    • hanges as from v5.7.0

    A new subs-set of dot-operators were introduced, in the form (data-typed-object or literal value).operator, e.g. $MyString.contains("ant"), "Advice for Defendants".contains("ant"). In this type of operator, the first part is an action code expression, an attribute reference or a literal (number, quoted string, etc.). After the dot, the operator name follows post v4.6 conventions; some operators require no inputs and trailing empty parentheses are not required. More advanced users can thus chain operators as long as they know the data type of the object to which they are dot-attaching additional operators.

    More on coding conventions:

    Case-sensitivity

    Tinderbox's host OS is case-sensitive as is the app in the majority of cases. Notable exceptions are export codes and agent query special arguments. In both cases there is a general TB usage convention to intercapitalise such words with a lower case start and capitals at concatenated word boundaries. Inter-capitalisation helps distinguish different Tinderbox code types.

    Conversely, attributes are case-sensitive: IsInside, Isinside, isInside and isinside would all be treated as different attributes by Tinderbox if forced to guess. Of the four styling the first is recommended, the second less so and the last two are deprecated to avoid user or app confusion as to purpose when using in code.

    To help illustrate this, consider a fictional 'insideness' state—'is inside'—as expressed through the major code types, noting that:

    • ^isInside(arg)^. An export code: inter-capitalised plus the carets indicate this is export code. (This is also a real export code). Export codes are case-insensitive.
    • IsInside. An attribute: opening capital plus inter-capitalisation. The styling of the words would also tend to imply in Tinderbox usage that this would be a Boolean type, true/false attribute. (This is not a real system attribute). Attributes are case-sensitive.
    • isinside(arg). An action operator, all lowercase. This would likely be the internal analogue of ^isInside^, though the case insensitivity of the later codes means export and action codes tend not to share a name. (This is not a real action operator). Action codes are case-sensitive.
    • Deprecated/defunct:
      • #isInside(arg). A special query argument. The opening hash characters is a give-away plus inter-capitalised styling. Note: this is not a real argument, though #inside(arg) does this function. (#codes are deprecated since v4.6 for action codes). Old #codes were case-insensitive; new query codes, being action code, are case-sensitive.

    As Attribute and Action codes are case-sensitive it is a good working model to pretend Export codes are also case-sensitive, and thus stick to a consistent case for the latterTbRef follows this model using lowercase with uppercase letter for word boundaries, as in '^ descendedfrom^'.

    Other areas where case sensitivity has an impact are in searching (queries & find dialog) and sorting (containers). By default:

    • new (agent) queries are case-insensitive but that state can be toggled by a tick-box on the agent's Action Inspector's Query sub-tab and via the AgentCaseSensitive attribute.
    • the Find dialog opens with case-sensitivity set 'on' but this can be toggled via a tick-box on the dialog.
    • containers sort case-sensitively by default, i.e. letters sort by character number with A-Z sorting before a-z. Container sort has controls both via note/agent Action Inspector's Sort sub-tab and via the Sorting group of system attributes.

    Sorting is discussed in more detail separately.

    White space in code

    Here the term 'white space' most generally applies to use of the space character.

    Within action and export code operators

    White space may not be used between the operator name and the parentheses used to hold input arguments:

    collect(children,$Name) Good
    collect(children, $Name) Good
    collect (children,$Name) ERROR
    ^comment(data)^ Good
    ^comment (data()^ ERROR

    No space allowed between the operator name and the parentheses, but spaces may be used between input arguments inside the parentheses. If the operator does not require trailing parenthreses, then normal general white space rules apply.

    In action code operators using curly braces

    A number of operators enclose code after the operator in curly braces, for instance the conditional 'if' test:

    if(){...}else{...} 

    Space before or in the parentheses is as in the section above. However, spacesafter the closing parentheses or before opening braces or after closing braces are allowed. Line breaks are also allowed in this position but by convention are generally only used inside the braces so that any code enclosed is placed on a discrete line, for clarity of human reading.

    if() {...} else {...} 

    is good as is

    	if(){
    	...
    	}else{
    	...
    	} 

    In queries (agents and conditional operators)

    White space around comparison operators is allowed. All these work:

    $Name == "test" 
    $Name== "test" 
    $Name=="test" 
    $MyNumber > 4 & $Created==date("today") 
    $MyNumber<=6 

    Around assignment (=) or arithmetical operators

    As with queries white space is ignored. All these work:

    $Name="foo"; 
    $Name = "foo"; 
    $MyNumber = 2 * 6; 
    $MyNumber=2*6; 

    It also applies to the 'reset' usage to (re-)apply an attribute default value:

    $MyString =; 
    $MyString = ; 

    The latter works but is less seen as it might imply a right side argument has mistakenly been omitted.

    It is not necessary to use spaces paired before and after. These both work:

    $Name ="foo"; 
    $Name= "foo"; 

    though generally balanced use of white space helps the human readers

    Inside quoted literal strings

    These are considered different strings as the white space has semantic purtpose:

    "Hello world" 
    "Helloworld" 

    Be are that when concatenating (joining) strings, or setting attribute values, any trailing/leading space may be elided. If uncertain, test and this:

    $Name = "Hello" + " world"; 

    can always be re-written as:

    $Name = "Hello" + " " + "world"; 

    Lexical vs. numerical sorting

    Tinderbox containers can sort their contents, as can agents. In addition action code offers methods for sorting lists. Sorting generally occurs in one of two forms, lexical or numerical.

    Sorting can be set via action code or more normally via the Sort tab of the Action Inspector.

    Lexical sort. A lexical sorts characters in broadly alphanumeric order, for unaccented Roman alphabet languages like English. In fact such sorts look at the underlying ASCII/Unicode character number and sort from lowest to highest for each character, in turn of a word or string of characters. Thus numbers always sort before uppercase letters and upper case before lower case letters. Accented characters come after that. This unusual order reflects the numerical sequence of codes used indicate different letters symbols and numbers. This order has several odd effects:

    • numbers sort out of arithmetical sequence: 1, 10, 11, 120, 13, 2 instead of 1,2,10,11,13,120.
    • instances of the same word in different letter case do not sort together: Ant, Bee, ant not Ant, ant, Bee.
    • words with accents may sot out of sequence.
    • sequential numbers in word strings do not sort sequentially: Chapter 1, Chapter 11, Chapter 2 not Chapter 1, Chapter 2, Chapter 11.

    Numerical sort. Only used for number sequences. Here the numerical values of the whole number string is computed and these values sorted in ascending numerical sequence order. Thus the order 1,2,10,11,13,120 not the lexical order of 1, 10, 11, 120, 13, 2.

    Dates. Date sort, in date order naturally. The exact form is neither strictly lexical or numerical but Tinderbox takes care of date sort correctly.

    Transforms

    To work around some of the limitations of basic lexical sorts, as seen from a human perspective, Tinderbox also offers some 'transforms' which tweak the way sorting occurs:

    *case-sensitive. Sorts upper and lower case sort in separate sequences, not alphabetically (a 'computer' sort). This is the default.

    *case-insensitive. Converts elements to lower case before comparing them, resulting in a more normal 'human sort' where similar letter sort together alphabetically regardless of letter case.

    *last word. Sorts on the last word of the value, using a case-insensitive sort (see above). This is useful when the specified attribute values are personal names, as often occurs in bibliographies and blog rolls. The last 'word', is the substring of characters between the last space in the string and the

    *original note. Instructs the sort routine to sort any (alias) note based on the properties of the original note, not on the intrinsic property of the alias. When applied to attributes that are not intrinsic, the transformer has no effect. This setting is useful in agents when the source of the alias is itself an alias as opposed to an original notes where sorting on $OutlineOrder would not necessarily give the expected outcome (see the Release Notes for fine detail as to why).

    *library sorting. This permits notes to be sorted as they might be filed in a library. By default, library sorting ignore initial words "a", "an", and "the". See more detail on the library sorting feature.

    Sorting in accented/non-roman text languages

    This may likely not be as expected due to the limitations of lexical sorts which are not, without further manipulation ('collation'), aware of per-language sorting nuances. This area of the application is noted as having scope for improvement and likely more locale-specific collation will become available in due course.

    So for other characters, accents, etc., sorts may not meet linguistic expectation as the values will be based on Unicode sort order. Thus:

    "dog" > "cat"
    "dog" > "Dog"
    "dogs" > "dog"
    "dogs" > "dogma"
    "dogs" < "døg" <-- NOTE!

    The prevailing locale's sorting rules for handling diacritics and accents.

    Tinderbox will use the OS' localisation settings to determine what rules apply for the sorting of accented and other characters such as a ß. If it is desirable to sort using a different localisation, consider use of locale() to alter the local Tinderbox environment.

    Sorting and Lists/Sets

    The discrete values are sorted such they are listed in lexical sort order.

    Quoting and escaping strings in Tinderbox coding

    From version 4 onwards Tinderbox has moved towards a convention of using double quotes to enclose string literals (i.e. text) when used in Tinderbox codes. An example for ambiguity is where we wish to clarify that we mean 'yesterday' as the word yesterday as opposed to the Tinderbox date placeholder 'yesterday' that is used to subtract one day in doing date calculations. In such a scenario with want to ensure the first instance is quoted and the later is not, thus:

    $DisplayExpression = "Yesterday is: " + date(yesterday) 

    In many contexts the app will still guess—usually correctly—if quotes are not used. The reason for the change in convention is the increase in the scope of coding that Tinderbox offers and with it the scope for unintended consequences if the app must figure out what is text and what is not. As a plus sign may be either a potential string concatenator (joiner) or an addition sign and a dash be a minus sign or hyphen, then quoting strings also helps when the app must coerce numbers to strings and vice versa.

    Although the advised norm for enclosing string literals is to use double quotes, Tinderbox can handle balanced single or double quotes as text string delimiters. This can be helpful when trying to handle strings that must use double quotes, e.g. the quotes surrounding HTML attributes:

    $MyString = '<div width="' + $ItemWidth + '">'; 

    Code: Straight vs. Typographic 'curly' quote characters

    IMPORTANT: Both Action Code and Export Code do not treat straight and typographic quote characters as equivalents.

    The issue of unseen character auto-substitution for OS or app

    Only straight single/double quotes have keys on the Mac keyword, whilst the typographic or 'curly' style of quote—more conventionally using in printed text—require use of keyboard shortcuts unfamiliar to many users (see table below). As a result, the macOS frameworks used by Tinderbox often default to auto-substitution of straight quotes into their typographic equivalents. this is true for the $Text area of the Tinderbox text pane.

    This auto-substitution of straight quotes with typographic ones can be controlled via the $SmartQuotes boolean system attribute. See more on Smart Quotes, and further below in the section on use of built-in prototypes.

    Quotes and Tinderbox Code

    In both Action Code and Export Code, only straight quotes, single or double, are treated as valid string delimiters in code. Thus:

    WRONG $Color = “red”;
    WRONG $Color = ‘red’;
    CORRECT $Color = "red";
    CORRECT $Color = 'red';

    Either form can be used inside a correctly quoted-enclosed string:

    CORRECT $MyString = "He said “It’s ‘just’ an example”, then left"; 

    But, take care if using straight quotes inside a string. The next example will not work as expected:

    WRONG $MyString = 'He said "It's 'just' an example", then left';

    The outer single straight quotes happily enclose the double straight quotes in the string. But, the string also contains straight single quotes, the first of which closes the string, i.e. 'He said "It'. If using typographic quotes in the string is not possible, defining a string that contains both types of straight quotes requires defining the whole text as several discrete stings such that no single string contains a quote of the type used to define the string. For instance:

    CORRECT $MyString = 'He said "'+"It's 'just' an "+'example", then left';

    Notice how the second string switches to double quotes around the string which contains straight single quotes.

    Setting up a TBX file for code work

    Because coding in Tinderbox uses the $Text area, auto-substitution of quotes can be problematic. Reflecting this, a number of Tinderbox's built-in prototypes are pre-configured with their $SmartQuotes set to false thus suppressing quote substitution. These prototypes include:

    The different quote types defined

    Character Description Unicode macOS HTML
    ' straight single quote U+0027 (APOSTROPHE) ' ' (or &apos;)
    " straight double quote U+0022 (QUOTATION MARK) " " (or &quot;)
    opening single quote U+2018 (LEFT SINGLE QUOTATION MARK) option + ] &lsquo;
    closing single quote U+2019 (RIGHT SINGLE QUOTATION MARK) option + shift + ] &rsquo;
    opening double quote U+201C (LEFT DOUBLE QUOTATION MARK) option + [ &ldquo;
    closing double quote U+201D (RIGHT DOUBLE QUOTATION MARK) option + shift + [ &rdquo;

    Attribute references: quoting of literal strings vs. paths

    Faced with an unquoted string as an attribute argument referring to another note, if the string starts with a forward slash Tinderbox will assume the string is a Tinderbox paths.

    Unquoted strings as arguments:

    $MyString(Some note) 

    will be tested for matches to paths or designator syntax before looking for a more localised match such as a $Name value.

    In contrast, a quoted string argument will be assumed to be a $Name value.

    $MyString("Some note") 

    Quoting Regular Expressions

    As action code syntax eclipses older syntaxes there is some scope for confusion where regular expressions (regex) are used. With 'dot' operators, e.g. String.contains(regex), one of the options for the 'regex' input argument is a regular expression which needs to be quoted, i.e. enclosed in double quotes. This conforms to a general rule of thumb that anything that is a string (literal, template name, regex, etc.) should be quoted. This helps Tinderbox to detect where the argument is actually an action code expression.

    The exception to this is the long standing, but now deprecated, AttributeName(regex) operator originally introduced as part of the query language; with this do not quote your regular expression. This operator should new be considered deprecated in favour of the $Attribute.contains(regex) operator. Thus:

    Old usage: $MyString(\W+) (now deprecated)
    Current usage: $MyString.contains("\W+")

    Regular Expression usage

    Tinderbox regular expressions follow the norms of PCRE (Perl Compatible Regular Expresion) usage. If consulting general references on regular expressions, be sure to look for PCRE is there is a choice of 'flavours' of usage being described.

    Note that an input that takes regular expression can take either:

    • a literal string, e.g. "Hello"
    • an entirely regular expression encoded string, e.g. "\d{2,3}"
    • a mix of the two, e.g. "Hello.+".

    The operators .contains() and .containsAnyOf() use Apple's regular expression engine.

    In action codes (or other operators) that are described as using regular expression patterns for their input arguments (i.e. 'patterns'), it is possible to use the \uNNNN method to use the 4-digit Unicode code point number for a character to test for a particular character, especially those that cannot easily be typed. Thus a non-breaking space, which looks like a normal space when querying text, is encoded as \u00A0, whilst a normal space is \u0020:

    $Text = $Text.replace("\u00A0","\u0020"); 

    …replaces every instance of a non-breaking space with a normal space character.

    An alternative, if the character is in the ASCII range, is to use the ASCII decimal number in the form \xNN. Thus:

    $Text = $Text.replace("XXX","\x22"); 

    …replaces every instance of 'XXX' with a straight double quote character.

    Some reference links:

    • Syntax for regular expressions using the Apple Regular Expression engine.
    • Wikipedia ASCII codes. IMPORTANT: use the values in the 'Hex' column. Thus a straight double quote is 22, a straight single quote is 27.
    • The ICU Regular Expression library documentation. This library is used internally in Tinderbox and replaces the previous Boost library (see below). ICU Regular Expressions conform to version 19 of the Unicode Technical Standard #18, Unicode Regular Expressions, level 1, and in addition include Default Word boundaries and Name Properties from level 2.

    Historical note re pre-v6 Tinderbox

    Originally, regular expressions in Tinderbox used Perl language conventions as further defined in documentation for the Boost regex code library: https://www.boost.org/doc/libs/1_34_1/libs/regex/doc/syntax_perl.html.

    Tinderbox stopped using the older Boost regex library from v10.0.2.

    Using $ and quotes in Export code

    Much of older export code has been eclipsed by newer codes like ^value(…action code…)^ allowing access to action code operators the better to define the target object.

    Legacy information

    Although historically export code did not need, or sometimes did not like, $-prefixes or quoted strings the ^codes have been reviewed in v5.7+ and should behave correctly if you use action code type conventions.

    All more reason to review old code and adopt current syntax for all new work.

    Single and double quotes

    When referring to quoting values such as strings, double quotes should be assumed. In edge cases where a string needs to enclose a double quote, for instance a complex command line string, paired single quotes may also be used.

    Within quoted text a backslash (\) escapes a character and a double backslash sequence (\\) allows a literal backslash (\) to be used. Besides escaping non-pairing quotes, standard escape codes like \n indicating a new line character or \t for a tab may be used.

    However, a backslash cannot be used to escape literal single or double quote characters. This effectively limits the nesting of different types of quotes to one set inside another.

    Whilst the mechanism should work for other characters, it is generally only single & double quotes which cause difficulties when used unmatched (or nested) within string literals (including regular expressions) in Tinderbox. The latter arises as quotes are used as delimiters for inputs and current parsing does not support a quote escape mechanism at initial-parse level. The above method 'hides' the quotes from that initial parse.

    aTbRef's naming conventions

    Tinderbox users can create action code, export code, user-defined attributes, rules, edicts, stamps, functions, prototypes, templates, etc. This is a bit like programming, and for good documentation and readability, a common technique is to use "standard" conventions. The following discussion suggests some conventions that are most commonly used by Tinderbox users which will be found in aTbRef.

    Thus the document will appear to assert as rules, constraints which are not actually so. Expert users can apply their own, less consistent naming and it is assumed they are expert enough to know where it is safe to do so. Otherwise, qualifying all the above 'rules' will be undervalued. However, it is understood expert users may (within Tinderbox's actual limits) with to use naming styles with which they are more familiar in other areas of their works (other apps, coding languages, etc.).

    A few terms are used in the discussion:

    • 'CamelCase'. A typographical convention in which an either an initial capital, or an initial lower case letter, is used for the first letter of a word forming the elements of a closed compound, e.g. PayPal, iPhone, MasterCard. Camel case is seen in two forms in Tinderbox: with capital initial letter, e.g. AgentQuery, and with lower-case initial, e.g. wordsRelatedTo().

    What things in code can the user name? Individual items lists are discussed in more detail further detail below:

    • User Attributes
    • Stamp names
    • Action code functions
    • Action code variables

    In addition, some things like the action and export code operators have strict formatting so must be typed correctly. In the case of action code, some code input location support auto-completion, so helping with typing operator names correctly.

    Attributes

    Attribute names. User attributes (only) can be named by the user and should follow the CamelCase convention seen with system attributes. Attributes are always a single word (no spaces). At simplest: start with a capital, Roman letter (i.e. A–Z), accents and non-Roman scripts are allowed, then capitalise each compounded word, i.e. 'Price' or 'LastName'. Acronym styling is a choice for the user: 'SourceURL' or 'SourceUrl' are both valid attribute names. However, note that Tinderbox will consider 'SourceURL' and 'SourceUrl' as two different user attributes.

    Although there is some support for other scripts, beginners are advised to use unaccented Roman characters whilst getting to know how Tinderbox works.

    Abiding by these guideline will avoid surprises. More nuanced aspects are discussed under Attribute Naming below.

    System attributes always use the CamelCase beginning with an initial and cannot be renamed by the user.

    Reference to attribute values. In action code (see below), referring to the value of an attribute to get or set its value is done using a '$' prefix. Thus, $ChildCount refers to the value of the attribute named 'ChildCount'. However, within aTbRef and much general Tinderbox documentation, inline references in general text which refer to Tinderbox attributes names generally use a $-prefix as a marker that it is an attribute name being cited. The latter is a slight variance with in-app usage but does aid clarity in the articles. In actual action code, the $-prefix always indicates a reference to a value.

    For example, consider a user creating an attribute named BookCategory, and assigns it a value "Non-Fiction". Then, then the action code in a stamp that accesses BookCategory's value in the selected note would refer to it via the code $BookCategory.

    Code example attribute naming. A convention, adopted before the Sandbox group of system attributes for testing were added, is to use a left-side attribute name that indicates the type of data to be expected from the right side. This 'MyString' indicates receipt of String (textual) data, 'MyList' a list of values, 'MyDate' a date-object, etc. The reader is not required to use the exact left-side attribute stated but rather to understand the data type they should use for their own attributes

    Export codes

    Tinderbox export codes are case-sensitive and use the CamelCase convention with a lowercase initial letter. Export codes cannot be renamed. They must be indicated with a caret '^' before and (optionally) after the code, i.e. ^children("t_item")^. If the optional closing caret is omitted, Tinderbox guesses where the code ends. For this reason, and to help signal intent, aTbRef always uses a closing caret and suggests the same a standard best practice.

    Action code operator codes

    Action codes are case-sensitive and use the CamelCase convention with a lowercase initial letter. Action codes cannot be renamed. Queries, either for agents or for query-based operators use action code, albeit with special query operators. Basic actions take a syntax of 'left-side is set to the value of right-side where either may be as simple as an attribute value or a complex action code expression resulting in such a value. At simplest, an example is: $MyColor = "red";. A left-side Color-type attribute is being set to a literal string value of 'red'. Note that in this context the attribute name in the action code is prefaced with "$" as it is setting a value for the attribute.

    Action code 'dot' operators

    In aTbRef listings, dot operators will be referred to with the data type before the dot, e.g. Color.blue, so that inline dots in text do not get misread as punctuation. In practice, Color.blue would be used with any Color-type attribute:

    $MyColor.red = "#ff" 

    A Date.minute would attach to a date attribute:

    $MyNumber = $MyDate.minute 

    Export and Action code arguments (inputs)

    In code examples in Tinderbox Help and in aTbRef, or in descriptions, there is a convention where arguments (i.e. inputs or parameters) are named to show data type (string vs. number) or purpose to indicate that input is used. Optional inputs are enclosed with square brackets (i.e. […]) and may be omitted when using that operator. If no inputs are used and there is no clear statement stating trailing empty parentheses may be omitted, include them, i.e. 'code()' not 'c ode()'. This way, the intent of the code is clear. In Tinderbox documentation, inputs use the CamelCase convention with a lower-case initial letter, as with the codes themselves.

    Designators

    Designators are case-sensitive and follow the Camelcase convention using a lowercase initial letter. Designators cannot be renamed. Care should be taken not to use input values that are the same are designator names. As a result, the convention is that designators used as input are not quote-enclosed even though they are strings. By comparison, a string value that is the same as a designator must be quote-enclosed to make clear to Tinderbox that it is not a designator.

    For example, grandparent is a note designator. The code

    $MyString = grandparent; 

    has a completely different meaning to Tinderbox than

    $MyString = "grandparent";

    Action code Functions & Variables

    Functions and Variables have no stipulated limits on naming but should not use a name already used by any Tinderbox system attributes, export, action code, or designator. A function name is always followed by opening and closing parentheses after the name, even if the function has no arguments defined.

    aTbRef naming prefixes

    Again, for consistency and to aid learning, aTbRef is (moving to) a system of using prefix letters to refer to other objects in action and export code. These are for guidance: users are not required to use these conventions in their own work. If nothing else prefixes both indicate intent and avoid naming-collisions with other codes or note names. If writing code to share with other users (who may have less expertise also consider adopting all or part of these suggestions.

    These prefixes are suggested to make reading one's code easier and for distinguishing among different elements of a document. It is suggested that single, initial lower-case prefixes can help indicate what kind of element is being defined. The recommended prefixes are all single-letter and lower case (assuming use in a case-sensitive context):

    • 'p' for prototype names. Examples: pCharacter, pStudent.
    • 't' for export template names. Examples: tMain_Report, tSummary.
    • 'f' for function names. Example: fSetColorRed().
    • 'i' for function arguments (i.e. inputs). Note, these effectively define a variable of that name within the scope of the function. Example: fSetColorRed(iNoteList), fProcessFeatures(iProductName).
    • v for variable names. Examples: vDessert, vLinkList.
    • 'a' (or 'an' for readability) for loop variables, such as with .each(). Examples: aProduct, anItem.

    For the last three (all types of variable) it can—depending on complexity/context—be useful for the name to indicate the purpose and/or data type of the variable. Examples: 'iProductName', 'vLinkList', 'aProduct'.

    Code examples using attributes with a 'My' prefix

    In documenting action code, examples are given where pertinent. In order to help learners, where a left side attribute is appropriate, an attribute is used whose name indicates the type of data returned by the right side of the example.

    In the majority of cases the returned value is is an explicit or implied string:

    $MyNumber = $MyDate.hour; 
    $MyString = $MyString.words(-1); 

    But other types do occur:

    $MyInterval = interval($Created,$Modified); 

    Processes returning a list are shown as returning a List:

    $MyList = $MyList.unique; 

    But you can chose a different approach, if you have a different result in mind

    $MyList = collect(children,$FavFruit); $MyList is [Apples;Oranges;Pears;Apples]
    $MySet = collect(children,$FavFruit); $MySet is [Apples;Oranges;Pears]
    $MyString = collect(children,$FavFruit); $MyString is [Apples;Oranges;Pears;Apples]

    Above the first case is the best generalised example. But if the source has duplicates, you can de-dupe it if desired simply by passing a List (i.e. a multi-value attributr) to a Set-type attribute as shown in the second example. Possible, but of less use is passing the list to a String where you receive a single string of all the list value, separated by semi-colons (essentially, a list in its raw form).

    This same choice of left-side attribute can work in other contexts:

    $MyNumber = $MyColor.blue;  (gives 255)
    $MyString = $MyColor.blue;  (gives "255")

    In a few cases an action operator requires no left-side attribute as the process returns nothing, but instead carries out the specified action:

    action($Text("Test-stamp")); 
    stamp("Do Stuff"); 
    $Text.speak("Tessa"); 

    Two more conventions worthy of note. Designators are by convention not quoted, in this case the 'children' forming the first input argument:

    $MyList = collect(children,$Name);

    Also when using note titles as offset addresses for an attribute reference, a $Name value is quoted:

    $MyInterval = drivingTimeTo("Swarthmore"); 

    but a $Path values is not:

    $MyInterval = drivingTimeTo(/places/faves/Swarthmore); 

    Those designator and title path quoting 'rules' are not hard-and-fast, but unless experienced enough with code to understand possible edge cases, most users would do well to treat them as actual rules, in order to avoid unexpected outcomes.

    Examples are also deliberately pedantic over end-of-action markers. These all work:

    	$MyString = "Hello world.";
    	$MyString = "Hello world."
    	$MyString = "Hello world"; $MyNumber = 2;
    	$MyString = "Hello world"; $MyNumber = 2

    as do actions if split onto different lines:

    	$MyString = "Hello world"; 
    	$MyNumber = 2;

    But, if the attribute or stamp holding the code has more than one action, you must place a semicolon between actions. So, this is wrong:

    $MyString = "Hello world" $MyNumber = 2 

    Tinderbox might correctly guess you are using two discrete actions, or not. Better to close your expressions with a semi-colon, even if only to remind yourself

    In, turn this leads to another confusion. Semicolon action delimiters are not used in queries. This is not so confusing as at first sight as queries are used in very few contents:

    • agent queries.
    • the condition in a if(condition)
    • find(query)

    Semi-colons turn up in one more place, in literal lists:

    $MyList = [ant;bee;cow]; 

    Results in adding three discrete value to $MyList.

    Tinderbox ignores white space within/between actions. These all work the same:

    	$MyString = "Hello world"; $MyNumber = 2; 
    	$MyString = "Hello world";$MyNumber = 2; 
    	$MyString="Hello world";$MyNumber=2;

    The same holds for white space in input arguments:

    	$MyList = collect(children,$FavFruit);
    	$MyList = collect(children, $FavFruit);

    However, within a string, the same does not hold true, these set different values:

    $MyString = "Hello" + " " + "world."; → "Hello world."
    $MyString = "Hello " + " " + " world." → "Hello   world."

    Of course, the latter is in Tinderbox. To simulate that here in HTML , non-breaking spaces have to be used in the TBX as web browsers collapse strings of space to a single one. Thus string "Hello   world." in Tinderbox exports as "Hello   world." but renders online as "Hello world."

    Square Brackets in code operator explanations

    In the names and text of notes describing action code and export operators, square brackets may be seen. For instance: linkTo(scope[, linkTypeStr]). Generally, these apply to (some) of an operator's arguments.

    This notion follows general conventions for documentation of computer code, so should already be familiar to those with some exposure to code documentation.

    Optional Use

    What the [ ] imply is that the enclosed item(s) are used optionally. Thus in the above example the linkTypeStr does not have to be supplied for the code to work.

    The syntax can be though of as a composite of two forms:

    linkTo(scope)
    linkTo(scope, linkTypeStr)

    Lest it seem odd not just to write out both forms, some operators have multiple optional operators so writing out all possible forms would lead to long lists and make articles less easy to read.

    Literal [ ] in code

    There are some operators where square brackets are intentional and necessary, e.g. attribute(attributeNameStr)[keyStr] where the [ ] enclose and indicate the name of the dictionary key keyStr being referenced.

    A further and very recent use is for nested lists.

    Which is which usage: optional or literal?

    The key is to read the article if unsure; with experience it will be easier to judge by context. For new users, read the whole article and not just browse the title. Optional content/usage is always described as such.

    Deprecated Usage

    This section covers notes relating to deprecated usage, i.e. such use is not recommended as it it has been replaced by some newer method. In other words, these notes describe things you may be still able to do successfully but which you are advised not to. This could be for one of more of these reasons:

    • The feature has been removed, i.e. no longer supported at all.
    • The feature has been replaced. Legacy support may continue but should not be assumed, so update code to the new syntax.
    • The feature does not work properly or in contexts deprecated may not give expected outcome.

    Many deprecated action and export codes are no longer listed, although they remain in older versions of aTbRef.

    References to deprecated aspects of Tinderbox

    This is a listing of notes referring to deprecated usage. Specific deprecated codes have separate discrete listings for export and action code. Deprecated usage:

    Windows

    All TBX documents will show at minimum of one document window. Other ancillary windows, like the Inspector or secondary windows from 'torn-off' pop-overs may also be open.

    Document tab bar (OS-level feature)

    NOTE: in general documentation the term 'tab' generally refers to per-window tabs and not this tab bar.

    Default state: hidden.

    From OS 10 Sierra, a document-level tab-bar can be shown, the default is to be hidden. If displayed it shows one tab per open TBX window (N.B. one per window and not one per document). Each tab shows the TBX document's name. It is placed below the toolbar and above the normal (internal) tab bar. The tab bar's visibility is toggled via the Window menu.

    This bar allows document windows to be 'docked' to a single tab bar. Discrete document windows within a single document can be docked here.

    Any document tab can be dragged off the tab bar to form a discrete document window.

    Although document windows from different documents can be docked together, this does not mean in-document tabs can be dragged to different document.

    The Window menu has a command to merge all windows which will create one document window with all existing windows/documents as tabs within it.

    The tab bar has a '+' symbol at the right side. If clicked, a new un-saved document is created as a new tab on the current windows tab bar.

    If a document with docked windows (document tabs) is opened in a pre-Sierra OS, each tab will open as discrete window.

    Additional grouping of non-document windows

    By using some non-default OS-level settings is is also possible to group additional windows like stand-alone text windows. To do this, the key requirement is:

    • in the macOS OS System SettingsDesktop & DockWindows (labels as at macOS 26). Set Prefer tabs when opening documents to Always. The OS default for this is Full Screen.

    Without this, only document windows can be docked in the toolbar.

    Why use this toolbar?

    As noted, it is off (hidden) by default. This is because most users likely have no immediate need. however, it is built-in to current Apple frameworks so it is useful for a number of scenarios:

    • Some users dislike have a large number of discrete windows for a single app. This tool bar—and the optional OS setting (above)—allows such windows to be collected together.
    • On a single/small screen, it may be impractical to display multiple windows at the same time, so grouping this way may make it easier to switch between open Tinderbox windows.

    There is no presumption of a 'best' setting here. It is whatever best suits a user's equipment and style of work.

    Document Window

    At the top of the window, the caption bar contains the document's filename and standard OS controls (via the pop-up) to rename/move the file. The file icon if Cmd-clicked shows the path to the file's stored location from root.

    Below the caption bar, and hidden by default is the toolbar.

    Below the toolbar, also hidden by default, is the OS-level document tab bar.

    Beneath these, and visible by default, is the main toolbar and link park. A Tinderbox document window will always contain a minimum of one (view) tab. By default new blank windows open with two tabs; the second tab may then be closed or additional tabs opened as required.

    Beneath the tab bar the window is split into 2 halves by a (moveable) splitter bar. The position of the bar is stored by the tab. Each tab can have a different splitter position.

    The left side forms the 'View pane', holding a view such as a Map or Outline. This pane equates to a major view type window in pre-v6 Tinderbox.

    The right side of the window is used for the 'Text pane' and which equates to a text window in pre-v6 Tinderbox.

    The View pane, Text pane and window Tab bar, can all take 'first' focus, i.e. when switching focus into into the app form a different app or switching back from the Inspector to the document window. Note: clicking in the Displayed Attributes area of the Text pane should be avoided as it does not set focus in a meaningful location.

    Toolbar

    Default state: hidden.

    Document windows can optionally show a toolbar in the caption bar at the top of the document window. There are three controls:

    • Colors. Clicking this shows/hides the OS colour picker dialog.
    • Fonts. Clicking this shows/hides the OS fonts dialog.
    • Views. This button bar allows the view type to be changed for the current window tab. The selected view type's button is showed as pressed-in. The 'Links' button is for Hyperbolic view.

    Tinderbox remembers whether the toolbar was visible when a document was saved, and if so makes it visible when the document is again loaded.

    The show state of the document window toolbar is based on the user's current setting. Previously, the app looked at toolbar setting in the most recently opened document's. When using documents made by others this change stops the user's choice being subverted by the last-opened document's settings.

    In-document window tabs and the tab bar

    Default state: shown.

    NOTE: in some OS versions the selected tab is highlighted in the OS selection colour (default: light blue). In the illustrating screen-grab there is no highlight and the selected tab is second from left.

    The window tabs are placed at the top of the document window. A Tinderbox document window will always contain a minimum of one (view) tab. By default, new blank windows open with two tabs; the second tab may then be closed or additional tabs opened as required. The tab bar is visible by default but may be hidden (see below). The tab bar also contains the main link park. The view type can be changed view the tab's pop-up context menu.

    The selected tab is tinted with the accent colour from the user's macOS account.

    Link park. The circle at the left end of the tab is the link park. If dragging a link from a note in either of the view panes and the destination is not visible, drag the link to the parking circle. The circle will then show a green fill. More on link parking.

    Tab(s). The man part of the bar is taken up with one or more tabs. The selected tab is differentiated by making it sit in front of the tabs either side of it. The tabs will expand or contract in width so they fill the tab bar width. If the window is narrow or there are many tabs and the full title cannot fit on the tab the title is clipped and closed with an ellipsis. The tab can be closed by the 'x' icon at its top left. When the active tab, all types except Attribute Browser, show an 'i' icon top right which opens the views properties pop-over.

    • Tab icon the left of each tab is an icon. As illustrated, each view pane view type (as in the left window pane) uses a slightly different icon. The symbols in the icon use a tint of $Color of the current container (Map uses the $Color of the first item on the map). The icons seen in the picture are in order: Map, Outline, Chart, Attribute Browser, Timeline and Treemap.
    • Tab title. The title uses a consistent format of the current view type, a colon, a space and the name of the current container, e.g. "Outline: Something", is the current TBX viewed as an Outline rooted at container "Something". If the title is the same as the TBX document name, the view is rooted at document root (which is the default for a new document's view)If the tab is narrow the view type prefix is omitted. Note the view type can distinguished by the icon. From v11.7.0, tabs in the tab bar have a tool tip with the tab’s full title. This is because the full title may need to be shortened or elided in a crowded tab bar.
    • New Tab. At the right end of the bar a '+' symbol opens a new tab if clicked.

    Tab Info Widgets

    Tab, with the exception of attribute Browser, have an 'i' icon on the top right of the tab. For Map/Chart/Outline views this opens the Edit Background properties pop-over. For Treemap view, it opens the Treemap Properties pop-over. For Timeline view, it opens the Timeline Settings properties pop-over.

    Refreshing/Re-drawing the view and Text pane contents

    If for any reason the pane contents appear to be out of date or drawn incorrectly, click the tab area of the active tap. this will force a refresh. If the tab's label text briefly goes red it means the tab is still working on the refresh—this is only seen with large/complex views on less powerful Macs. As soon as the label is normal colour the work is done and the view refreshes.

    Auto-hiding the Tab bar

    The tab bar may be hidden (View ▸ Tab ▸ Show Tabs). When hidden, tab bar is "spring loaded" such that when the mouse cursor moves near the top of the window the tab bar will be revealed and remain until the mouse moves away.

    Dragging Tabs

    Tabs can be dragged horizontally to re-order them in the tab bar. Tabs cannot be dragged between document windows (even of the same parent document).

    Dragging a tab vertically up or down from the tab bar copies only the dragged tab a new window with (only) that tab, though the source tab retains its copy of the tab. This is similar to the tab context menu's New Window option.

    Opening and Closing Tabs

    New tabs are added using the button at the right end of the tab bar. A new tab created this way always re-uses the current tabs's context (i.e. the container on which the tab's view pane is focused. The new tab is always added at the right end of the existing tabs.

    To close a tab place the cursor over the top left of a tab's icon and a small 'x' button will appear in its top corner. Click this to close the tab. On closing, the rightmost remaining tab will take focus.

    The tab bar may be hidden (View ▸ Tab ▸ Show Tabs). The hidden tab bar is "spring loaded": when the mouse moves near the top of the window the tab bar will be revealed and remain until the mouse moves away. Moving away hides the tab bar again, but only after a brief delay; this delay lets you use the breadcrumb bar if you wish.

    Saving tabs

    See the Gallery pane for saving tabs. This can be accessed from the tab's right-click context menu or via View menu ▸ Tab sub-menu.

    Background Tabs

    These tabs consume little or no CPU time unless or until they are selected. Thus their memory demands are trivial and so the number of tabs in a document should not affect performance and so this is not a reason to avoid adding tabs.

    Multiple document windows

    Although all documents show a single window by default, it is possible to open additional windows using the File menu.

    When a new window is created, it replicates the current window. This includes all current tabs with their view type (and current selected tab), tab view's current scope and note selection.

    If the OS-level toolbar is in use, the parent tab in that toolbar shows the source document for the window.

    Document Windows, Tabs and selection state

    Document windows and tabs within windows treat current note selections in different ways:

    • Use windows to view the same note in different views - but be aware the current selection is common to all windows, even if other windows do not have a current view with that note in scope (this can be confusing at first encounter).
    • Use tabs to use the same view with different selected notes - selection is discrete to the tab

    Windows. All windows from the same document share a selection. If one window changes selection the current tab of all other windows changes to the selection, although the scope of the view does not change, i.e. the tab in other windows may show note text data for a note not currently visible in that tab's view.

    Tabs. Each window tab supports its own selection. However, if there are multiple windows , another window may change its selection unexpectedly.

    Although new windows replicate all source window tabs it is a good idea to delete all tabs except the desired view type for more predictable selection change caused by window/tab focus changes.

    If a tab's view type is changed, the view scrolls to show the selected item.

    Command Bar

    The command bar gives you keyboard access to many Tinderbox commands and lots of Tinderbox information. Its initial placement is tied to the (frontmost) main document window.

    The Command Bar displays only fairly good matches, instead of displaying every match sorted by quality of the match. From v11.7.0 , the Command Bar uses a much better fuzzy pattern matcher based on algorithms for genomic search. For example, "ComBar" matches "CommandBar".

    Searches are case-insensitive.

    From v11.7.0, the Command Bar remembers previous commands. When typing in the command bar, up-arrow navigates backwards to the previous command's string. A second up-arrow recalls the command string prior to that. Down-arrow moves forward through the history. The Return key restores the conventional meaning of down-arrow and allows keyboard selection from the results table.

    To open the command bar, select menu Help Commands Bar (⌘⇧-U)

    Type any word or phrase to see available topics as a list. Scroll the list to see more matches. Either click an item to perform the selected item. Or use arrow ↑ and ↓ keys move through the list and press Return to perform the selected item. Home and End keys move to the first and last items, respectively. Esc dismisses the command bar, as does clicking outside the command bar.

    Various commands can be used:

    • Open… Lets you open any Tinderbox document you have recently used, or any Inspector pane. Type "Open " followed by part of the document name. Or, type "Open Border Inspector" to open a particular Inspector sub-pane.
    • Select… Lets you select any note in the current document; if possible, Tinderbox will scroll to make the note visible. Type "Select" and the note's path or name (if the note's title is unique in this document).
    • Explain… Provides instant access to some key places in aTbRef, e.g. to explain Tinderbox actions and their usage. For example "Explain Menus". To access more specific topic like an operator, simply type its name, e.g. "collect_if".
    • View… Access some notable Tinderbox tutorial videos.
    • Attribute values. Type the attribute name. Clicking on a command bar item that describes an attribute opens the Quickstamp Inspector for that attribute, allowing quick setting or reading of that attribute value for the current note.
    • Check update status.g. "Can I update"

    From v11.7.0, a number of improvements were added.

    Understanding terminology for the Command Bar

    Contextually, some of these might all be the same:

    • item. An 'item' is generally referring to anything that may be listed in the Command Bar as the result of typing in a search string (or 'prompt')
    • article. Some matches (i.e. items) may be generated by notes. These may display their $Text as a preview window or result in some generic action or command.
    • commands. These are generally notes configured to do something if selected in the Command Bar as opposed to merely previewing their $Text. For instance they might open a URL or another application on the user's Mac.
    • action. Some notes, for example custom commands, may be configured to run action code if clicking in the search match list.
    • document. Matched notes and the target of actions are in the scope of the current active TBX document.

    Further detail:


    Legacy

    Prior to v11.7.0, this was called Commands & Info….

    Command Bar Slash commands

    From v11.7.0, the Command Bar offers a number of 'slash commands', that use a slash prefix. The scope of any implicit search is always limited to the current document:

    • Current tab's view pane selection based:
      • /do $Color="red" will perform an action on each selected note
      • /eval $Path will evaluate the action code expression for the first selected note (if more than one).
    • Global:
      • /find [searchString] will display any sources that match searchString, using a fuzzy match algorithm.
    • Current document:
      • /query [expression] will display any notes that satisfy a Tinderbox query.

    Matching Tabs

    From v11.7.0, the Command Bar is able to list each of the current document's tab names, such as "Tab Outline: What's New". The match need only be part of the tabs full title string. Clicking on the item, or highlighting it and pressing [Return], selects the tab.

    Stamps

    From v11.7.0, the Command Bar lists each stamp in the current document. If you click a stamp item, the stamp's code is applied to the notes selected in the current tab's view.

    Command Bar sources

    From v11.7.0, the Command Bar searches draw, case-insensitively, on a number of sources. Note that where searching inside documents the scope is always the current document only, and not all open documents if more than one.

    These are the sources:

    • Known Files: filenames of the most-recently Tinderbox documents (up to 30 TBXs in the MRU menu).
    • Tabs: tab names of the current document.
    • Stamps: names of stamps defined in the current document.
    • Hints: all custom command notes in /Hints/Command Bar.
    • Notes: the notes in the current document.
    • aTbRef: article titles from the aTbRef at time of app release (matches link to the online aTbRef article).
    • Video: various video-based Tinderbox learning resources.
    • Inspector: Inspector features.
    • Help: a few key pages inside the app's Tinderbox Help file.
    • Menus: items in the app's main menu bar.
    • Attributes: all current System Attributes.
    • Actions: all current action code operators.
    • Miscellany: various information sources not fitting in other categories. It including some built-in articles for prompts like "I'm stuck", and such (there will be no listing for the latter).
    • Slash Commands: Slash commands in the current document.

    Custom commands and articles

    From v11.7.0, notes stored in /Hints/Command Bar (see) are used as custom Command Bar articles.

    Several possible things may happen when such a note item is selected from the list of matches, though typically only one of the following will take place (the attribute tested in in the matched article's note):

    • If $IsAction is:
      • true, the $Text of the listed article holds an action to be performed.
      • false, the article's $Text text is displayed in a temporary preview window.
    • If $URL holds a value (i.e. is not empty), the stored URL is opened in the default browser.
    • If $File holds a local path (i.e. is not empty), the file path is opened in its default application (as per OS/Finder). This can also be used to switch to other applications, to show a folder in Finder, or to run a script.

    If a Command Bar note has $HTMLMarkdown set to true and the note has an $HTMLPreviewCommand set, then that note is assumed to contain markdown text and the processed markdown is displayed in the preview window. The stylesheet in /Hints/Preview/styles is used for this display, if that note exists.

    Using the pane splitter

    The two panes in a window's tab are divided by a vertical splitter bar that can be dragged to give more space to either the view or the text pane. By default a tab opens with a 50:50 split between the two halves. The splitter can be moved manually to give a desired ratio of the two panes. The current splitter position is saved and remembered between sessions. When the input cursor is over the draggable part of the splitter bar

    Resizing the document window by dragging its left/right edges or any corner retains the split ratio. If the view pane to text pane ratio is 2:1, dragging the window wider will retain a 2:1 balance between the panes.

    A Cmd+drag of the window will re-size it so as to retain the current text pane width, i.e. all extra pane width is added to/removed from the (left) view pane only.

    Three shortcuts are offered to toggle one of 3 states:

    • Cmd+4 / Text Only. The splitter is moved all the way to the left of the window so the text pane fills the whole window.
    • Cmd+5 / View and Text. The splitter is placed so there is an equal division between the left (view) and right (text) panes.
    • Cmd+6 / View Only. The splitter is moved all the way to the right of the window so the view pane fills the whole window.

    The Cmd+5 shortcut always gives a 50:50 equal pane width allocation and so overrides any pre-existing split ratio. There is no current mechanism to remember and return to a custom pane split ratio after using Cmd+4or Cmd+6.

    Tinderbox remembers the state of the text pane selector between sessions.

    Refreshing the current window's view and text panes

    If the current window (view and text panes) appears to not reflect recent changes made by the user, the UI can be force-refreshed by clicking the window's currently selected tab. In default macOS settings, this tab will be highlighted in light blue. Or, if the user has customised their host Mac's OS, the highlight colour chosen in the OS.

    By design intent of the app, this should not be needed, but this feature works around the occasional issue were a change in one part of the document (either the UI or underlying data) does not cause the UI to change as expected.

    On clicking the tab, both view and text panes are completely re-drawn. When clicking avoid the 'x' and 'i' icons but otherwise anywhere in the tab, including the tab's textual label is fine.

    If the text label of the tab briefly shows in red text, this simply implies the refresh work is ongoing. Such may occur, for instance if refreshing a very complex map with lots of links or images.

    View pane

    The View pane, the left side of any document window tab, shows one of 8 possible views. Some views have settings that are view-specific and can only be set via a Setting dialog (e.g. Map Settings) accesses via the 'i' icon on the active tab label

    Historically Map/Chart/Outline/Treemap were the original v1.0.0.views. Then followed: Timeline (v5.6.0), Attribute Browser (v6.0.0), Hyperbolic view (v7.0.0), Crosstabs (v8.0.0), Table (v9.7.0), Gaudí (v10.0.0) and Information city (v11.0.0).

    Generally the Attribute Browser and later view store the view configuration in the TBX file as part of their current tab; some newer aspects of older vies are also not saved as attributes. To be able to close a tab without losing its stored view configurations, save the tab in the tab-gallery.

    The background colour of most views is set using $MapBackgroundColor (N.B. despite the attribute's name), but some views do not, see here for more detail (or under the articles for specific view).

    These are the current views available:

    Attribute Browser view

    [First introduced in v6.0.0]

    The Attribute Browser shows you the contents of any container in the current document, categorised by the values of a chosen attribute. By default the scope is whole-document. The scope is shown in the right-hand pop-up in the top row of controls in the view's toolbar. By default, all except the first row of controls are hidden. The remainder of the controls can be revealed/re-hidden via a disclosure triangle on the control panel.

    The scope and appearance of the view are set via the Attribute Browser controls at the top of the view pane, which includes a search pane for looking up attributes. If a tab using another view type is switched to Attribute Browser view, the scope remains the same. See more detail about all the Attribute Browser controls.

    The first column, is labelled $Name but always shows $DisplayName (except during editing).

    The view's header (the settings area) displays the count of notes in the scope of the current view. If the same note appears in multiple groups, the note is counted separately in each group.

    View font. The name column uses the same font ($NameFont) and type size ($OutlineNameSize) as used in the outline view at standard magnification.

    The Attribute Browser will not display notes that are (currently) separators.

    The view accepts View menu Magnify and Shrink commands (and shortcuts) and scales rows appropriately.

    Selected notes may be copied, regardless of whether the selection is an individual note or more than one note.

    Display of rows and columns

    Items listed are drawn in $Color and show $Name. Badges are shown, and a link-drag widget is shown after the item name. The icon used for each item is as per Outline view, indicating the degree of text, recentness of edit and in/outbound links.

    A link widget for dragging links is drawn at the right side of the selection highlight in the view pane.

    From v11.7.0, rows can use $OutlineBackgroundColor to tint their row's background, consistent with Outline View.

    In addition to the selected attribute, additional columns may be added to display other system or user attribute values for that note.

    From v11.7.0, Tab/Shift-Tab navigates between columns in the selected row.

    From v11.7.0, text-based attribute values may be elided in narrow columns. Hovering the cursor over the field shows the full value as a tooltip.

    From v11.7.0, Column widths can be auto re-sized. Double-click at the right edge of a column header to set the column width to the width required by the current data.

    From v11.8.0, columns now remember their widths, even if the list of columns is edited or the tab is changed.

    Category Summaries

    For attribute data types that support multiple values, e.g. Set and List, notes are grouped for every unique list value present. Thus a note with more than one value may list several times, once under every discrete value in that note's list. Formerly, this behaviour applied to Sets but not to Lists.

    Optionally, value groupings can show a count of the number of the items (configured via the view's controls). By default, this is the per-group count for the view's chosen attribute. It can also be for any of the attributes additionally displayed via column view. If the count is enabled, this summary figure is shown at the right end of the category bar.

    Items can be assigned new category (attribute) values by dragging them into different categories. The attribute changed is the one being categorised in the view pane. For single value attributes, a drag replaces the existing value. For list-based attributes the new vale is added to existing values. Notes can also be dragged into empty categories (i.e. with no current items listed, and into no value categories. In the latter case the existing value(s) are deleted.

    From v11.7.0, when the table is wider than the display area, summary values are now drawn at the right edge of the display area, and not the right edge of the table. This ensures category counts remain visible if many columns are used in the view.

    The colour of the per-category banners uses a tint of the OS's colour choice (i.e. as used for selected controls). For a default, light mode, system that colour is blue.

    Editing titles

    From v11.7.0, attribute values are editable. The view recategorises and reloads itself after editing the value of an attribute. Undo is available when editing column data in the attribute browser.

    When editing the first column, the edited string switches to $Name. The $DisplayName is again shown after the edit is confirmed or cancelled. Some attribute data types show a modified display:

    • Boolean attributes show as an (editable) tick box.
    • URL attributes show a URL button (to open the URL in a web browser)
    • Colour attributes show a colour well indicating the actual colour that is set.

    Multiple records can be selected at a time, aiding use of stamps and quickstamp in this context.

    Formatting: see Attribute Bowser controls for formatting of attribute values in the table, and per data type options.

    Dragging a note to a new category changes the note's value for that listed attribute to that of the category. For multi-value attributes, regardless of the category the dropped note receives all of the values for the attribute for the note listing after the dropped note. In such circumstances it can be useful to list the attribute as a column view item to see the full range of values allotted.

    More information:

    Attribute Browser controls

    This control panel is shown at the of any view pane Attribute Browser view. By default, all bar the first row of controls are hidden, accessed via a standard disclosure triangle to the left of the top set of controls. The labels in the top row refer to the controls in the second row of the panel.

    attribute. XML setting: attribute. The primary attribute to display is selected by a pair of pop-ups and a search box (the latter to the right of the label):

    • Attribute group pop-up. The left hand pop-up selects a system or user attribute group.
    • Attribute pop-up. The right-hand pop-up is populated based on the selection in the group pop-up. The attribute selected here is the attribute whose values are then summarised in the main part of the Attribute Browser view. Selecting an attribute here is the primary configuration task with this view.

    [Search]. Placed in row #1 of the controls, to the right of the label. The search box autocompletes attribute names and clicking Return will auto-select both the above pop-ups for the attribute name matched in the search box.

    container. XML setting: container. More accurately this describes the scope of the view, being all descendants of the selected container, further modified by :

    • container selection pop-up. By default a view is 'entire document' (or current container if the view is created by altering the tab view type of an existing tab not at root level. The items listed are both immediate children and any descendants of the chosen container.
    • (container sort order). The button with a downwards-pointing chevron label controls the view sort order, in terms of sorting of the view's categories. Clicking the button toggles the sort order. When the sort order is reversed, the button label changes to an upwards-pointing chevron. The 'empty' category—no value assigned for the inspected attribute—is listed last in the default order (its position toggles to first in reversed sort). The sort order of value categories depends on data type:
      • String-based (all types—including list-based—except: Number, Interval, Boolean, Date types). Alphabetical lexical order, case-insensitively. Numbers sort first, i.e. : 1, 10, 2, aardvark, ant, Ant, bee, etc. Note that numerical text values do not sort numerically.
      • Number-type. Ascending numerical for Number-type (negative numbers first). However, see the section below on numerical value 'bins' as numbers are categorised slightly differently to textual values.
      • Boolean-type. Default is false then true. Note that there is no unassigned group as a Boolean attribute can only be true or false.
      • Interval-type. Ascending based on duration.
      • Date-type. Earliest to latest. The 'no date' value, i.e. "never", list lasts as for other types' defaults. By default dates are formatted using the OS' medium system date format (i.e. format "n"), as is inherited as the document default for $DisplayedAttributesDateFormat. The latter attribute may be set to a different format for the view either via prototype inheritance or by setting a local value in the container used to display this view.
    • Omit default values. (default: not ticked) If ticked the view's listing omits any in-scope notes with the selected attribute's default value. In most cases this is no value. This makes it easier to view only those items with an actual value set.

    Notes. A number indicating the total count of unique notes listed in the view. For Lists or Sets the row count may be higher as some note will match multiple categories

    summary. The controls are for per-category summaries. By default there is no summary. The first pop-up lists the $Name (default) plus any other attributes currently shown in column view. The second control offers a choice of operation to apply to the choice. The default is no choice. The choices offered are:

    • non-Number type attribute selected:
      • none. (default)
      • Count. This sums the number of items in that category with a value for the attribute. Thus in the basic Name/Count configuration the summary is a count of items in that category, as each note has a (single!) title.
      • Count Fraction. For each category, this shows the category count as well as the total count (i.e. the total number of items in scope).
    • Number-type attribute selected offers a larger range of summary types:
      • none. (default)
      • Count. (only option for non-Number type attributes)
      • Total. The total value of all the category's items for the selected attribute.
      • Mean. The mean value of all the category's items for the selected attribute.
      • Minimum. The smallest value of amongst all the category's items for the selected attribute.
      • Maximum. The largest value of amongst all the category's items for the selected attribute.

    sort. Within a category, the items can be sorted on a chosen attribute. The default is $DisplayName. Attribute Browser categories are sorted by locale; thus, diacritical marks should not create unexpected sort orders. When categories are sorted by the summary, ties are sorted by the category name. A pair of group/attribute pop-ups allow the sort attribute to be selected. XML setting: sortAttribute.

    • Attribute group pop-up. The left hand pop-up selects a system or user attribute group.
    • Attribute pop-up. The right-hand pop-up is populated based on the selection in the group pop-up.

    query. A query can be added to further refine the overall choice of included items. The query applies within the current container scope as set via the container controls (above). Clicking in the input box opens a query pop-up. The description entered in the pop-up is used as a label in this box.

    action. Akin to an agent action this optional action code is applied to all items listed in the view. Clicking in the input box opens an action pop-up. The description entered in the pop-up is used as a label in this box.

    bins. (Default: 0). XML setting: bins. Only displayed/used where the attribute analysed is of Number, Date or String-based data types (all types, except Boolean and Color); before v11.7.0 it was only used for Number-type).

    • pre v11.7.0. If a figure is entered the view divides the difference of the lowest and highest attribute value to the desired number of equally-sized bins. It is not possible to Set a floor or ceiling for the lowest/highest bins. There is no stated limit for the number of bins that may be defined.
    • from v11.7.0. When clicked a bin configuration pop-over shows, its content depending on whether the views analysed attribute is of Number, Date or String-based type. On closing the configurator, the chosen bin type is applied to the view. When a new String-type attribute is selected, each distinct value initially receives a separate bin (i.e. categories count == bin count).
    Attribute Browser column pop-up

    This pop-up is shown by right-clicking the title bar of the view pane of an Attribute Browser view.

    To add an attribute, as a column either:

    • Type the desired name in the box in the upper section of the pop-over. Autocomplete is offered for all currently defined system and user attributes. The box is blank if no Displayed Attributes have yet been defined. If large numbers of attributes are added, the box will auto-expand to keep existing attribute choices on view.
    • use the two bottom lists. First, select the attribute group in the left pane then tick the appropriate attribute in the right pane (un-ticking will also remove an existing item).

    To delete a current Displayed Attribute, click to select the item in the top list and delete it. Or, use the lower two panes to find the item and un-tick it. The first column remains $Name. If only one column is set and it is another attribute, it will be automatically changed to $Name.

    To re-order columns, click on an item in the upper list box and drag it to the correct location in the list. The first column must be $Name, if altered to something else, on close the dialog will reset that column to $Name.

    To close the pop-over click outside it or press Escape. On closing, the changes made (above) are effected.

    The meaning of the styling of different rows (bold, strikethrough, etc.) is explained here.

    bin configurator for String-type

    A slider is shown with three numbers:

    • At left is the minimum number of bins. Normally 2, items with no value and those with a value.
    • Middle. The currently selected number of bins. To avoid binning, drag the selector all the way to the right.
    • Right, the number of discrete values.
    bin configurator for Date-type

    A slider is shown with three numbers:

    • At left is the minimum number of bins. Normally 2, items with no value and those with a value.
    • Middle. The currently selected number of bins. To avoid binning, drag the selector all the way to the right.
    • Right, the number of discrete values.

    Beneath this a pop-up offers three scoping choices:

    • Day (default)
    • Month
    • Year
    bin configurator for Number-type

    A slider is shown with three numbers:

    • At left is the minimum number of bins. Normally 2, items with no value and those with a value.
    • Middle. The currently selected number of bins. To avoid binning, drag the selector all the way to the right.
    • Right, the number of discrete values.

    Beneath this a second slider showing the size (number spread) of each bin:

    • Left, smallest possible size.
    • Middle, current setting.
    • Right, largest possible setting.

    The two sliders are interconnected so either slider can be used to decide the bin size/number.

    Chart view

    [First introduced in v1.0.0]

    A chart view shows the hierarchical structure of the document very clearly, as a tree chart. A chart is also handy for seeing many notes in one window. It is easy to re-structure the hierarchy of the document in a chart window, by dragging parts of the hierarchy to other parts of the hierarchy. The scope of the chart depends on the selection when the chart view is called. If in root view and nothing is selected, the chart represents the entire outline, otherwise it is of the selected item and all its descendants.

    Subtitles appear in chart view. Chart View has a Chart options popover, accessible by clicking the Info button on the chart view's tab. The popover allows change the chart style and to adjust the width and spacing of chart items. A choice is offered of either a left-to-right (as previously) or top-to-bottom arrangement of the chart.

    A note icon with a pointed right end is a container. By default a new chart is drawn with all branches expanded. However, any container note can be collapsed (like with an Outline) by clicking the triangular area at the right edge of container icons. Collapsed containers show a number, e.g. "+17", indicating the total number of descendants (i.e. children, grandchildren, etc.) that are in the hidden branch. The count includes agents and aliases but excludes separators and adornments as neither of these types of object is drawn in Chart view.

    A chart view does not show any of the links in the document. A chart view does not differentiate between notes and agents as in outline or map view (through if a container holds only aliases, it is most likely an agent). Chart view dog-ears do not show the ageing colour (as in outline view, etc.).

    Charts can wrap their titles to multiple lines and editing-in-place is supported.

    The note's badge is shown to the left of the title. Right-clicking in this area opens the badge menu.

    The note or agent icon is the same as that used in Outline view and shows the presence/amount of text, and links, and can be used to select prototypes.

    The link icon for dragging links is shown, for the selected note, between the note icon and the badge.

    Item icons and titles are drawn in $Color.

    Chart view is not suitable for very large outlines, e.g. the whole of a document such as aTbRef, so avoid using this view for very large numbers of notes. This is because Tinderbox runs out of virtual space in which to draw the overall outline (i.e. it is an internal limit within the app). Reserve chart use for small files or just sections of larger files. Large charts can take a long time to render and may not scroll smoothly due to their sheer size (N.B. outlines are more compact). The conventional left-to-right Chart View is somewhat more efficient in its layout.

    Chart tabs remember and restore the expansion state of their view.

    Chart Settings controls

    This is the control panel for the current Chart view:

    • Border. Default: un-ticked. If ticked a thin border is drawn around each item on the chart. XML setting. XML setting: hasBorder.
    • Vertical. Default: un-ticked. If tick-ed, the chart is drawn from top-to-bottom of the screen as opposed to the default left-to-right layout. XML setting: isVertical.
    • Centered. Default: ticked. If un-ticked, the item top aligns (default layout) or left aligns (vertical layout) with the line from the parent item. XML setting: isCentered.
    • Item Width. Scrubber control sets the width (pixels) of chart items, including icon, title and elements in between. XML setting: itemWidth.
    • Vertical Spacing. Scrubber control sets the amount of vertical y-axis spacing (pixels) between chart items. XML setting: yspace.
    • Horizontal Spacing. Scrubber control sets the amount of horizontal x-axis spacing (pixels) between chart items. XML setting: xspace.
    • Connecting Lines. XML setting: lineType. A pop-up with possible values:
      • Orthogonal. (Default) Lines interconnecting items are drawn using horizontal and vertical sections.
      • Straight. Lines interconnecting items are drawn using straight lines.
      • Curved. Lines interconnecting items are drawn using bezier curves.

    Crosstabs view

    [First introduced in v8.0.0]

    The Crosstabs view allows exploration of the values of two selected attributes in the current document, or a limited scope within the document. The view displays a table in which one attribute's values are listed horizontally and the second attribute's values are displayed vertically. The following attribute types are supported: Number, String, Date, Boolean, List, and Set.

    By default, the scope of the view is of the whole document. This, and the attributes to be tabulated, can be set using the view's control panel.

    At the bottom of each cell that is not empty, Tinderbox shows a display attribute of one note in the cell. The Display attribute is typically $DisplayName, but may be any attribute.

    In the centre of each crosstabs cell is a bar that shows the relative location of each note in the cell in the document's outline. The left edge of the bar corresponds to the first descendant of the chosen container, and the right edge corresponds to the last descendant of the chosen container. A vertical line representing each note appears in the note's outline colour.

    Hover the mouse over a crosstabs cell to browse through other notes in that cell. The first note in outline order is viewed by placing the mouse at the left edge of the cell and the last note in outline order is viewed by placing the mouse at the right edge of the cell. Click to select the current note and to see its text and Displayed Attributes. The ↑ and ↓ keys can also be used to select the next and previous notes in the cross tabs cell, and is a more practical way to navigate the cell contents if there are many items.

    It is possible to make an agent that collects the items corresponding to interesting cells of the table, see the 'Copy Agent For This Cell' in the content menu for a selected cell. Via that menu it is also possible to apply an action or a stamp to all the notes in a cell.

    Crosstabs controls

    The attributes to be viewed are displayed in the two buttons at the top of the view. Pressing the Rows or Columns button to change the target attributes. The resulting popover window also lets you set the maximum number of rows or columns to use; setting the limit to the upper bound (25 rows or columns) asks Tinderbox to display a separate row or column for each unique value. For Boolean attributes, there are only ever two bins. Set and List attributes always have unlimited bins, allowing each tag or element its own bin. For Date attributes, the date "never", if present, is always placed in its own bin. Configuration is via a configuration pop-over.

    At the bottom of each cell that is not empty, Tinderbox shows a display attribute of one note in the cell. The Display attribute is typically $DisplayName, but may be any attribute, use the button to set the desired attribute. Configuration is via a configuration pop-over.

    The gear-wheel icon opens a pop-up menu offering a number of ways to export data from the view:

    • Export As CSV. This exports the table including column/row labels and totals to a comma-separated variable (CSV) file; an OS file same dialog is shown for saving the file.
    • Export As TSV. As above but in Tab-delimited text (TSV) format.
    • Copy TSV To Clipboard. The table in TSV format (see above) is copied to the clipboard.

    In the second row of controls, the Container pop-up control allows the view's default scope of 'entire document' to be changed to any container in the current document. XML setting: xcontainer.

    The Style popup lets you choose, using a pop-up menu, to display either (XML setting: xReportStyle):

    • the count of notes in each cell
    • the percentage of in-scope notes in the cell.

    The Bar shows, by default the relative location of each note in the cell in the document's outline (using $OutlineOrder). The left edge of the bar corresponds to the first descendant of the chosen container, and the right edge corresponds to the last descendant of the chosen container. A vertical line representing each note appears in the note's outline colour. Configuration is via a configuration pop-over.

    Query allows the container choice to be (further) constrain using a query added in the box. The query is applied to the container, thus possibly reducing the numer of items shown. XML setting; xquery.

    A tick-box offers the optional of a Heatmap that will colour cells in proportion to the number of notes they contain, using the system accent colour ($AccentColor) for sparsely-populated cells and the complement of that colour for heavily-populated cells. XML setting: xheatmap.

    The notes viewed in the crosstabs view may be all the notes in the document, or may be restricted to those inside a specific container. Select the desired container from the Container popup menu.

    Gaudi view

    [First introduced in v10.0.0]

    The intent of the view is to cluster child notes of a similar type together using efficient space packing—resulting in the odd-shaped notes seen in the view. The layout draws on spatial packing as seen in Voronoi diagrams. The view's name is inspired by the art and design of the Catalan architect and designer Antoni Gaudí (in places within the app this is anglicised without the accent as 'Gaudi').

    The cause of attraction is set by a query-based expression in the Force box—see link below for the view controls. If the Force field is empty, no notes attract other notes. But everything else in the view still happens: notes are attracted to the centroid of their hulls, friction is applied, and a new Voronoi diagram is computed.

    What the table shows

    All children (but not further descendants) of the container selected when choosing this view type. Adornments, separators, and notes with $GaudiHidden set to true are not shown.

    Press [Return] to create a note to the right of the selected note. Double-click to create a note at any point. The new note ought to be created somewhere near the click point. Of course, forces and the pressure of adjacent notes can cause it to be inserted go somewhere else in the view.

    The Badge widget and Link widget operate as in other views.

    Option-drag performs marquee select on notes within the chosen rectangle. In contrast to map view, where any note that partially overlaps the marquee rectangle is selected, in Gaudí view only notes whose centre—technically their centroid—lies within the marquee rectangle created when they are selected.

    To edit a note, select that note, then click and hold over the title. When finished, press [Return] or click elsewhere.

    Even though Tinderbox can fit plenty of notes into the map, eventually it will run out of space and computational power. 40–80 notes is probably the sweet spot, and less than 200 is recommended as a maximum.

    Note that prototypes are drawn in Gaudí view with a double border. Links are drawn among notes if both source and destination are visible in the view.

    At low roundness levels, an inter-node boundary is drawn between notes borders.

    As well as using the attribute based filtering (see Controls, below), Gaudi view supports use of the view pane Filter bar, allowing dynamic examination of a query-based subset of the container's notes, temporarily simplifying the view.

    Right-clicking in the view opens a context menu.

    Notes use $NameFont (i.e. as in map view titles)—see also Document Settings ▸ Map.

    The contextual menu offers to Hide notes rather than Omit them. Also, the prototype submenu of the contextual menu now sets the prototype to the original note, even if that original note has prototypes (this relates to the selected item being an alias).

    Gaudi view controls

    In Gaudí view a number of controls are shown at the top of the view:

    • Anneal (button). When pressed, it jostles the view, permitting trapped notes to get unstuck and thus better reflect their attractant forces, in terms of better clustering
    • Force [expression] (input box). A Boolean (query) expression that expresses which notes attract other notes. This is bound in turn to each note, and that to its counterpart. It is best if not every note attracts lots of notes, since that prevents much motion. For example: $Prototype == $Prototype(that) & $Prototype!="" will cluster together notes that share a common prototype, i.e. have the same $Prototype value. $Color == $Color(that) & $Color!="normal" will cluster together notes of the same colour. XML setting: force.
    • View Size (slider). This adjusts the size of the canvas, allowing you to magnify an area of interest and scroll through the view. Pinch-zoom on a trackpad will also adjust the view size. It maps to normal view magnify/shrink zoom menu options and shortcuts. XML setting: gaudiSize.
    • [Title font size] (buttons). Buttons are provided to decrease or increase the size of the title text. This can help with better wrapping of note titles within the note area. XML setting: gaudiFontSize.
    • Roundness (slider). The affects the rounding of the note boundaries. At minimum (left) notes are angular and with straight edges. At maximum (right) notes are more rounded, organic and which may overlap slightly in some cases. At minimum, a boundary line is drawn in the space between notes to clarify the separation of discrete notes. XML setting: roundness.
    • Grout (slider). This adjust the width of the space separating individual notes. XML setting: grout.

    Information City view

    [First introduced in v11.0.0]

    NOTE: this is an experimental view. As an experimental view, it is not necessarily finished in all aspects individuals users might want.

    The view's purpose is to allow users interested in Dieberger's 'Information City' ideas to explore them within Tinderbox as explained here.

    Essentially, in the Information City view notes are represented by buildings. It shows only the contents of a single container within the document (tin that sense, akin to Map view). The styling of a building can represent other metadata. The resulting city is shown in a 3D render allowing the human visitor to walk around it. The location and juxtaposition of buildings is intended to aid navigation, recall and serendipitous discovery.

    What is the scope of the view?

    The view's scope is the children of the container used to hold the view. Depending on the building type chosen for a child notes, its children (i.e. grandchildren of the container/view) may be rendered. There is an option to hide child notes in the view if not pertinent to such display. Thus a an empty container (a note!) will contain only an empty city with no buildings. it is the container's child notes that populate the city.

    The contents of the view is discussed in more detail here.

    Configuring the view

    This is achieved via the views context menu, supported by a small number of system attributes in a new 'InformationCity' group.

    More information on configuration and use of this view:

    Context menu controls

    The view's menu allows access to most view configuration features via a context (right-click) menu:

    • Convert To. Changes a building to one of the other available building/non-building types (below). The menu is greyed out if the cursor is not over a building or other note object.
    • Make. Creates a new note at this location, using one of the building or non-building types listed below. Can only be used on an unoccupied part of the plane (ground). The type of building or other feature created is stored in $CityKind.
    • Modify. A series of menus allow configuration of buildings. The implications of the customisations are left to the user and are not stored. The actual customisation values (of style, etc.0 are stored as Dictionary-type data in $CityData.
      • Add New Floor. Only for some building types (see list below). The new floor is a new note, in the outline added as a child of the ground floor note. For third floor (second extra level) and above the new note is a new last sibling of existing children. New floors (notes) added this way have a hyphen placeholder name '-'; this stops untitled new notes being auto-deleted.
      • Flipped. Flips the font elevation design left/right, on the vertical axis.
      • Lights. Toggles a lighting effect in the building's windows on/off.
      • Badge. Sets the notes $Badge, whose artwork is drawn on the front of (the ground floor of) the building.
      • Transom (BrE equivalent: Fanlight). Show/hide a window above the front door: none/square/fan/triple/pediment.
      • Door. Front door style: square/rounded.
      • Window. Style of windows (other than the Transom, q.v. above). Styles: plain/sash/casement/Queen Anne. Additional menu choices:
        • Shape. Window shape: plain/rounded/arc/gothic.
        • Shutters: Styles: none/open/ajar/closed.
        • Awning. Toggles show/hide an awning over the ground floor main window, but only for some building types e.g. 'shophouse'. The sub-menu is greyed out for other building types.
      • Main window. The appearance of the ground floor main window: plain/lattice. Only available for some building types. The sub-menu is greyed out for other building types.
      • Accessories. Placed out front. Options: Signpost (Pub, Vendor), Table (Vendor).
    • Rotate. Rotate the orientation of the building 90 degrees: Counter Clockwise/Clockwise. A building's degree of rotation values is stored in $CityRotate (Number-type). Menu rotation results in values of 0/90/180/270, but any value 0–359 may be used.
    • Prototype. Sets the associated note's prototype ($Prototype).
    • Hide. Hide this building in this type of view. Boolean state stored in $CityHidden.
    • Delete. This deletes the associated note from the document.

    Building Notes

    There are a range of building types. Only those in italics may have multiple floors:

    *Welsh

    • Pub
    • Rowhouse
    • Beacon Hill
    • Vendor
    • Dome
    • Shophouse

    Non-building Notes

    There are some non-building objects that may be created in the city:

    • Fountain
    • Street. Adds a house-sized section of paved street.

    Signposts

    If the building has a signpost and has an image that the very start of $Text, that image is drawn onto the signpost.

    Relationship to other views

    Like a Map view, an Information City view corresponds to a single container within the overall document Outline.

    For building types that allows additional floors, a note can show its children as additional floor. The containing note is the ground floor, its first child child note is the first floor (BrE, second floor in AmE), etc., with the last child as the top floor of the building as rendered in the view.

    If a building type does not allow multiple floors the presence of children is not indicated in the City view. In either case, further descendants (i.e. grandchild notes, etc.) are never rendered.

    The cartesian co-ordinates of a house's location on the plane are stored in $CityX and $CityY. An orientation of the building ($CityRotate) of 0 may be considered as facing North (although no compass is shown and there are no time-of-day lighting changes). If directly editing $CityRotate, rather than using the rotation controls on the view's context menu, the view needs refreshing to update the render: click the current tab (the areas of blue highlight fill) to refresh.

    Child notes not pertinent to use (rendering) in this view can be excluded via the boolean $CityHidden. Hiding a note in this view has no effect on its behaviour in other views.

    Background to the Information City view

    Information City view is experiment intended to explore Andreas Dieberger's Information City concept from the 1990s. As an experimental view, it is not necessarily finished in all aspects individuals users might want. Its purpose is to allow users interested in Dieberger's ideas to explore them within Tinderbox and to aid discussion as to whether such an approach makes a meaningful addition to the exploration of information.

    This is from the abstract to Dieberger's 1997 A City Metaphor to Support Navigation in Complex Information Spaces:

    A major problem for users of modern information systems is the retrieval of new and previously viewed information from the system. Systems like the Word-Wide Web are heavily interlinked but do not communicate structure that helps users to navigate the information it contains. The use of appropriate navigation metaphors can help to make the structure of modern information systems easier to understand, and therefore, easier to use.
    We propose a conceptual user interface metaphor based on the structure of a city. Cities are very complex spatial environments and yet, people are used to navigating within cities. They know how to get information, how to reach particular destinations, and how to make use of the infrastructure. Furthermore, cities possess a unique set of navigational tools that lend themselves to creating sub-metaphors. A city metaphor makes this existing knowledge about a structured environment available to the user of a computerised information system.

    Essentially, in the Information City view notes are represented by buildings.

    InformationCity Attributes

    These attributes store data related to configuring notes' appearance in the experimental Information city view.

    Hyperbolic view

    [First introduced in v7.0.0]

    The hyperbolic view shows notes that are linked to or from a specific note—the 'focus' note—which is initially the selected note. This is the pivot around which the view is generated. The focus note is identified by a thin red border.

    To build the hyperbolic view, Tinderbox constructs a spanning tree that starts at the focus note, at view centre. It examines outbound links from that note; if they lead to a note not already in the tree (i.e. the view), it adds that link and the destination note to the tree. After checking all the links in the focus note, it now repeats the procedure with each unvisited note added to the tree, continuing until it has either (a) exhausted the list of unevaluated notes, or (b) exhausted the list of unevaluated outbound links. From, v11.5.0 the tree is traversed out to a maximum of c.50 links closest to the from the source: this is for pragmatic reasons of processing load and complexity. As you drag the view, notes that approach the centre appear and very distant notes disappear.Finally, this tree is projected onto a hyperbolic plane; notes near the centre are large, and notes further from the centre are progressively smaller. In that resulting spanning tree, all links that connect notes in the tree to other notes in the tree, but which are not part of the spanning tree, are considered 'cross links'. There is a view settings option to hide these cross links, which is off by default.

    For new views, the '*untitled' link type is used for initial tree display construction, unless only typed links exit the focus note, in which case the first type by A–Z order is used. Cross-links are disabled on first presentation: these make the tree more complex and so slower to load and are not always needed.

    Selecting—clicking on— a note item the view, populates the text pane but, importantly, does not alter the view focus. Double-clicking a note item will shift the focus and as a result the tree is re-drawn, and the red border shifts to the new focus note. Given that the view only shows a maximum of 5 links out from the source, fully exploring the graph of a given link type may involve several focus shifts.

    Hovering the mouse over a note will reveal its full name as a tooltip. This is often useful out near the rim of the view where note's appears smaller.

    Web Links (to outside Tinderbox) and Prototype links are ignored in hyperbolic view (and cannot be enabled).

    Navigating the Hyperbolic view.

    Some controls for altering the view's setting are shown in the view toolbar.

    Note shape and link colour are retained. Note that the normal map shapes map be distorted slightly reflecting the way they are drawn on the hyperbolic surface. Lines that represent links in the spanning tree are drawn as arcs, conforming to the underlying hyperbolic geometry.

    The view supports mouse-wheel and two-finger swipe scrolling. Holding down the option key (⌥) when using the mouse-wheel or two-finger swipe scrolling changes the magnification.

    A context menu for the selected allows traversal from the selected note using any outbound basic or text link. The destination note is selected but does not take focus. The context note also allows the selected note to be deleted.

    It is possible click-drag from any note to another note and create a new link. Or, by dragging a link to a blank part of the view and releasing the cursor, a new linked note is created. The Link creation dialog opens allowing the new note to be named, before the other dialog controls are configured. If not named the note is called 'untitled'. If you change your mind and do not name the new note, the newly-created note and its link are automatically deleted.

    Existing links, for the selected note, can be reviewed/edited using the Browse Links dialog.

    The contextual menu of the focus note (i.e. with red outline) omits a 'Delete option, since deleting the focus would leave nothing in the view.

    The prototype submenu of the contextual menu sets the prototype to the selected items' original note, even if that original note has prototypes (i.e. if the selected item is an alias, the $Prototype is correctly set—and then inherited back from—the aliases' original note.

    See also:

    Hyperbolic view controls

    In hyperbolic view a number of controls are shown at the top of the view:

    • Refresh: tell the view to restart the force directed layout.
    • Highlight: emboldens a selected path. XML setting: path.
    • Aspect Ratio: changes the ratio between the height and width of the notes. Again, this is in hyperbolic geometry; notes not near the centre are not rectangles. XML setting: aspect.
    • Scale (zoom level): At small scale, i.e fully to the left, the entire with of the hyperbolic tree is shown. If the view is wider than it is high, the regions near the north and south poles will be offscreen. At larger scale, more of the edges are moved offscreen, so you see only near the centre of the view. Pinch-zoom adjusts scale, too, as does "smart magnify" (two-finger double-tap). XML setting: hyperbolicScale.
    • link type: drag to reorder: a list of all link types in use in the document (except 'prototype'). Dragging a link type higher in the list increases its priority; high-priority links will be included in the spanning tree in preference to lower-priority links. Each individual can be selected both/either for whether it is used to build the view pane's tree, and/or whether it is presented as a crosslink (from v11.8.0 there is selector for all tree or all croos links):
      • tree. If ticked, this link type is plotted in the hyperbolic (link tree) in the view pane. XML setting: treepaths.
      • cross. If ticked, this link type is used to plot crosslinks between notes in the main 'tree' graph, i.e. between branches of the tree. XML setting: crosslinkpaths.
    • > disclosure control : this allows vertical expansion of the control panel, making more of the link type list visible.

    Map view

    [First introduced in v1.0.0]

    The map view is the primary view type used in the View pane of a window tab. It offers the opportunity to record data in an unbounded map, leaving the structure of the layout entirely to the user.

    For articles about the map view interface, scroll to the end of the article.

    A map view shows notes as rectangular icons. You can move these icons around in the map however you like and drag links lines between them. A map view shows one level of the document's hierarchy, by showing the children of a note as contained within its box. A map only shows immediate siblings, not other notes at the same outline level but with a different parent note.

    You can re-structure the hierarchy of the document in a map window by dragging the icon representing a note (and any icons it contains) into/onto another note's in the window. If the recipient note is not already a container it becomes one.

    If notes were not originally created via the map window they may appear overlapped, or even obscuring one another, or offset some distance from the centre of the map; you may have to look around to find all the notes when first using a given map view. Over time Tinderbox has improved auto-placement of map icons.

    For any container there is only ever one map, even if it is opened in two different tab view panes.

    Tip: when developing a big document do not use the root level for your map. Instead, first make a container at root level and start your big map inside this. The approach offers several practical benefits:

    • Non-map content like prototype containers, export templates, general utility agents and such can be placed under different root level containers and thus not appear on the map.
    • Addressing notes via action code is less ambiguous (easier!).
    • Action code can use note names rather than paths, i.e. values for note 'NoteB' can be addressed via $WordCount("NoteB") rather than $WordCount(/NoteB).

    Display of links

    A map view also shows many of the links between notes. If both the source and destination of the link are in the map, the link is drawn as an arrow between the boxes, with the link name at the midpoint of the arrow. By default the arrow is curved but straight arrows can be used instead (setting link types). If the source or the destination of the link is outside the map, the link is drawn as a short arrow departing from or arriving at a box.

    The map view is the pre-eminent view type that shows actual link lines in the view—but also see Timeline and Hyperbolic view. However, links are only drawn completely if both source and target are on the current map. Otherwise, inbound or outbound link 'stubs' are drawn.

    Moving notes in the Map

    To move a note within a map, click the note with the arrow tool and drag it to another part of the map. If you move a note to the very edge of the map, Tinderbox creates 'more' map. This makes sure that a note is never hanging off the edge; you can always move the map far enough to see all of every note. Drag a note inside another note to make it a child of that note in the hierarchy. A careful hand on the mouse can drag a tiny note out of its parent in the map. New notes and dragged notes may snap to the map grid. Shift-drag constrains the drag to vertical or horizontal movement.

    Map items (other than adornments are drawn in outline order. This ensure that where items overlap, the most recent item (or that highest in outline order) is drawn last.

    The map cleanup feature allows for resetting some or all of the map icons to one of a number of layout patterns.

    The map view offers a large number of ways to improve visualisation of data.

    More on the map view interface:

    Adding notes to an existing map

    Historically, adding new notes to an existing map made the note the youngest sibling of the current container, i.e. it listed last in order when viewed in outline view. Behaviour is as follows:

    *For notes added via a double-click on the map background, the new note is added as youngest sibling in the (map) container, i.e. last in $OutlineOrder.

    *If a note is already selected, and a note is created other than via double-click, the new note is added as as next younger sibling to the previously selected note (i.e. $OutlineOrder + 1 to the selected note). If there is room the new note is placed to the right of its previous sibling

    *If a note is moved into a collapsed outline container or onto a subordinate map (by dragging it, in map view, onto another note or an existing container), it is added as the first sibling.

    *If a note is added to a map via an expanded container it is inserted into the map with the sibling order value appropriate for its new outline view order ($OutlineOrder) position.

    *For multiple sibling notes added via drag drop, the first item in the selection conforms to either of the last two conditions above. The other items in the selection are inserted in existing their sibling or parent/child relationship within the source selection.

    *A pasted note/selection is added as first sibling unless a note on the map is selected, in which case it becomes the first sibling on the map (first child of the container).

    *A dropped/moved container acts as for a single note in positioning terms whilst retaining its descendants.

    Note that subsequently moving the new notes around on the map has no effect on outline order ($OutlineOrder), only on X/Y co-ordinates ($Xpos/$Ypos) as was previous behaviour.

    When adding notes via a keyboard shortcut:

    • Return () creates a new note to the right of the selected note, if space is available.
    • Control+Return (+) creates a note to the left of the selected note.
    • Control+Option+Return (++) creates a note below the selected note.

    If the initially-chosen location is occupied, a different location will be chosen.

    Adornments

    Adornments are a map view only feature (though they may appear in Timeline views if dates are set). They are used to provide a means of adding visual elements to the background of the Map view. Some general points about adornments are also described under general concepts.

    Adornments can:

    Adornments can not:

    Creating adornments

    Created via the Create Adornment menu item in the Note menu or the map's context menu. A map may have one, many or no adornments. Different types of adornments—normal, smart, etc.—can be used on the same map. Additional setting are used to make a normal adornment into a smart, geographic or image type of adornment.

    Positioning and stacking

    New adornments are placed on top of existing adornments. This is the reverse of existing behaviour for notes but should be more intuitive for use. The change is achieved by always adding new adornments in $OutlineOrder in front of existing ones rather than at the end, as the lowest outline order item is always drawn on top.

    Note that adornments do get counted in the $OutlineOrder, even if not shown; the are counted as the last sibling(s) child(ren) of the note on whose Map view they appear but they do not affect the normal hierarchy or the links of any notes. However, adornments do not affect $SiblingOrder, and are not included in $ChildCount and $DescendantCount. Containers have a separate $AdornmentCount for the number of adornments on their child map.

    Adornments & searches

    Adornments are always excluded from agent query matches, i.e. they are not treated as notes when matching, as well as by group designators including find(), plus the view pane's Find toolbar. Altering $Searchable for an adornment will not make it appear in searches.

    Queries can test the inside() operator using an adornment's name to see if any notes lie on top of that adornment.

    The boolean $IsAdornment is true for adornments.

    Use of $Text

    Adornments have a Text pane, and can have $Text. However, unlike normal notes, $Text—even when present—is never displayed in the map icon. Altering $MapBodyTextSize has no effect on this..

    Adornments and export

    Adornments cannot be exported. As they are excluded from child/descendant counts, normal export tests for the presence of children in a container, etc., will work properly even if there are adornments present.

    Styling adornments

    Adornments set to zero width or height can be used to make 'divider' lines on maps (see more).

    If $Color is set to 'transparent' the adornment's icon is hidden and only the title shows on the map, although the adornment still works as usual for things like $OnAdd actions. Adornments fully respect $Opacity enabling them to be fully translucent. It is possible to have a visible border for a transparent adornment, but to do this $BorderColor must be set to a value other than 'automatic': styled borders (e.g. dashed) can be used with adornments.

    Adornments can have drop shadows like note icons. The $Shadow will always default to false for an adornment regardless of the app/doc setting for notes, i.e. such defaults only apply to the latter. For that reason, making a prototype adornment with a shadow and then inheriting that is an easy way to use drop-shadowed adornments. Adornments show a small inner shadow (inside the border line).

    Adornment actions

    Use of an $OnAdd/$OnRemove action

    When a note is created on top of an adornment, the adornment's $OnAdd action is run; prior to this, the adornment action ran only when the note was moved onto the adornment. The adornment's $OnAdd is also run on other adornments placed in or overlapping the adornment if the former is in front; if behind no $OnAdd fires.

    $OnAdd also affects adornments created or pasted into containers and the adornment's $OnRemove action is performed if a note atop it is removed or deleted.

    Adornment grids

    Adornment grids allow an optional gridded framework to be drawn into an adornment as background markup to any notes being arranged atop the adornment. The grid is most easily configured by clicking the 2x3 grid icon which opens the Grid Properties pop-over.

    The number of cells in the gird are controlled via $GridRows and $GridColumns. The cells can each be given a label via $GridLabels, which are drawn in $GridLabelFont at $GridLabelSize. The overall grid and labels are drawn in $GridColor and with $GridOpacity.

    All these adjustments can be accessed via the Grid Properties pop-over which is accessed by the grid icon on any currently selected adornment.

    The image shows a 2 row, 2 column grid with labelled cells; all other settings are default. Transparent adornments may draw a border and grids.

    The use of a grid does not affect the OnAdd action of the adornment, which applies to a note regardless of where on the grid it is placed.

    The placement of notes by a smart adornment is not aware of a grid. The smart process will use the adornment as a whole, ignoring grid assignments. Therefore grids are not ideally used with smart adornments.

    The grid icon is not displayed when the adornment is part of a multiple selection.

    From v10.2.0, adornments using an "oval" shape ($Shape) use a different layou—see below.

    Grids on oval shaped adorments

    Oval adornments show a sector grid layout. This is best for circular adornments, i.e. where $Shape is "oval" and $Width and $Height are the same.

    When a grid is applied to an oval-based adornment, the grid is drawn as a series of concentric rings (for rows) subdivided into sections (for columns).

    The grid is oriented off a line at the 90-degree (three o'clock) position.

    If labels are used, they begin at the innermost ring in the sector below the originating line and proceed clockwise, and then stepping outward to the next ring. In the illustration there are 15 segments but only 11 eleven labels defined. so, both the inner rings are fully labelled, but only one segment in the outer ring has a label.

    As with other girds, smart adornments cannot place items in cells in the grid.

    Adornments as map dividers

    It is possible to set zero width or height for an adornment allowing it to server as a rule or linear divider on a map. Note that such dividers can only be of horizontal or vertical alignment, i.e. not at just any angle. It is possible to set both height and width to make a small dot.

    The colour of the resulting line is the adornment $BorderColor. If that is left as the default 'automatic' value, then setting $Color for the adornment will give the intended value and may be a more intuitive way of setting it.

    The height and or width of a divider is set via its $Border attribute (default =2). Thus, a zero-width adornment will draw as unit wide vertical line of height $Height with a width as if there were a persistent border of $Border value 1. Conversely, setting a wide border value, e.g. 10, causes a 10 wide block of colour. In contrast, a default adornment set 10 units wide would show 6 units width of inner colour and two 2 unit wide borders. Thus a wide border on a zero-width/depth adornment sets a band of solid single colour. If the $Border is set to 0, the adornment renders with an overall width and/or height of 1 pixel in $Border colour.

    Geographic Adornments

    A map adornment becomes a geographic adornment if all of the following evaluate as true:

    The latitude and longitude may be set directly, or may be computed indirectly because $Address has been set. The scale of the map is determined by the adornment's $Range attribute, which represents the approximate size of the map in kilometres The scale of a geographic adornment’s map fill is fixed, and in relationship to the adornment's $Height & $Width.

    Thus, dragging the adornment bigger will show more detail—i.e. appear to zoom in—as there is now more space within the adornment to plot the same $Range. The reverse applies for making the adornment size smaller. For a given adornment size, increasing $Range zooms the map out, decreasing it zooms in.

    If a note that sits atop a geographic adornment has a latitude and longitude that lies within the adornment, it is moved so the note's centre lies on the corresponding place in the map. If the position is not on the map, the note is moved to the edge of the adornment. If a geographic adornment moves a note to a position that is already occupied, it will try to find a nearby place that is not occupied.

    Geographic adornments can only draw maps up to about 8,000 pixels in size, which should be ample for most purposes.

    If an adornment has a non-zero $Latitude or $Longitude (which it typically gains automatically if the adornment has an $Address), it becomes a geographic adornment and displays a map of the area surrounding that place. The extent of the map displayed is determined roughly by the attribute $Range, in kilometres; if not specified, the $Range is approximately 1km.

    Data source for maps

    Currently geographical adornments use Apple MapKit, via Tinderbox, to source the map's information.

    Image Adornments

    Pictures may be inserted into the background of a map view as image adornments. This is done in one of two ways:

    • Copy and paste from a bitmap editor (including Preview). Open the image in the editor. Select the whole image and copy. Switch focus to a document tab using view and paste to the view pane.
    • Drag-and-drop from Finder. If dragging from the Desktop, ensure the image is selected before starting the drag otherwise the image may not be imported. Drag and drop onto the map view.

    Like other adornments, image adornments do not show up in any other views, and do not affect the hierarchy or the links of any notes. Locked picture adornments are ignored from drag-selections of notes.

    The image format must be a bitmap image (PNG/JPG/JPEG/GIF/BMP) and not vector-based (i.e. not CAD, AI or EPS). Regardless of source format, image adornments store image data as JPEGs, in Base 64 form.

    Just as normal adornments are not exported in HTML Export, neither are picture adornments.

    Picture adornments respect $Opacity and may have non rectangular shapes, just like normal adornments.

    Image size. Images are inserted and displayed at 'actual size' (i.e. for current desktop resolution). Resizing the picture's 'frame' vertically will scale the image. However, dragging the frame horizontally has no effect. But, if the frame dragged narrower (horizontally) than the image it will visibly crop it, working in from the right margin (i.e. the left side is always retained. The picture adornment does scale if the whole map is zoomed in or out.

    Resizing picture adornment in aspect ratio. There is no mechanism for this, but if making regular use of picture adornments, stamps can help along with a couple of user attributes. This workaround works on storing the original pixel width and height in Number type attributes. Suggested names are $ImgWidth and $ImgHeight.The original pixel count can be obtained by opening the image in Preview and using the Inspector window to check width and height. Add 3 stamps:

    Name: "Resize by Width". Code:$Height = $Width*($ImgHeight/$ImgWidth);

    Name: "Resize by Height". Code:$Width = $Height*($ImgWidth/$ImgHeight);

    Name: "Resize as original". Code:$Width=$ImgWidth/35.3;$Height= $ImgHeight/35.3;

    The first two stamps work off the ratio of the original pixel height width. The first stamp keeps current $Width an adjusts $Height accordingly. The second stamp does the reverse, maintaining $Height and adjusting $Width.

    The third stamp is an approximation as Tinderbox's mapping of pixels to map units varies slightly in scale. Ostensibly 32 pixels per unit, at normal map zoom scale a factor of 35.3 seems to work best; note that this may not work as well at different zoom scales, so change to normal zoom to use this stamp.

    Locked and Sticky Adornments

    Locked adornments

    Locked adornments are locked ($Lock) onto the map background to avoid accidental movement. The lock state can be toggled on/off using the icons top right of the adornment; if desired the icon can be substituted with a custom icon. Locked adornments are ignored from drag-selections of notes. An adornment can be selected whilst locked but to re-size it (or drag it) is must be unlocked.

    Locks a note or (more usually) an adornment to the Map to avoid being moved inadvertently.

    Primarily used in Map view (indeed, intended primarily for adornments), if $Lock is true the adornment can be selected but not repositioned, i.e. $Xpos and$Ypos are locked. Nor can the item be re-sized (i.e. changing $Height or $Width).

    Sticky adornments

    Sticky adornments ($Sticky) ensure any notes within or overlapping them move with the adornment when the latter is moved. This makes it much easier to work with moving sections of very large, complex maps.

    Overlapping adornments are also moved if they lie above the sticky adornment in outline order, i.e. adornments that lie partially over (above) the sticky adornment but under (behind) it. The sticky state can be toggled on/off using the icons top right of the adornment; if desired the icon can be substituted with a custom icon.

    Note that, while moving a sticky adornment moves notes on top of it, items on a 'sticky' adornment can still be moved independently, either on the adornment or to move them off it. In the latter case the object is no longer 'stuck' to the adornment. Moving an item off a sticky adornment has no effect on the adornment itself.

    Custom icons for locked/sticky state

    The icon (ICNS-type) files for the above can be customised.

    Shaped and Patterned Adornments

    Adornments can use shapes. Note that due to the shapes it may be necessary to use a $NameColor setting other than 'automatic'. Adornments may also use patterns and badges. Shaped adornments are allowed, with the exception of 'cloud' and 'bubble' can be transparent and have borders; 'cloud' and 'bubble' have no border if made transparent.

    Smart Adornments

    Any adornment is made into a smart adornment simply by giving it a query (stored in $AgentQuery) using agent query syntax, i.e. action code. Importantly, the scope of the query in a smart adornment is always the current map, the map on which the adornment lies. All other notes are automatically out of scope. The following facts apply:

    • Notes within the current map matching the query are moved onto the adornment. Unlike an agent, the smart adornment does not create an alias of the matched note but rather moves the original note itself onto the adornment, which is why the scope of the query is limited to the current map. In this context, 'original note' could also be a container, agent or an alias.
    • Notes moved onto the adornment as a result of the query fire the adornments's $OnAdd code.
    • Adornments do not auto-expand to encompass notes. In some cases where there are so many matching notes that they fill the adornment, some notes may be placed around the adornment.
    • Matched notes are sorted as per the adornment's sort attributes.
    • Matching obeys the smart adornment's $AgentQuery.
    • Smart adornment ignore $AgentPriority setting. In this they are unlike normal agents. In the Query Inspector, for a smart adornment, the Priority pop-up is disabled as a result.
    • Matched notes have their $Xpos/$Ypos altered as the original is being moved.
    • The outline order of matched notes is not affected.
    • Matched notes are laid out in a grid (sort) order on the adornment until the available areas is filled. Thereafter notes may be stacked on top of one another or alongside the adornment until the latter is manually resized to accommodate all matched notes.
    • $CleanupAction is ignored. When a query is set the user cannot re-arrange items on the adornment. In the Query Inspector, for a smart adornment, the Cleanup pop-up is disabled as a result.
    • Notes no longer matching the query are moved off the adornment and placed alongside it. They are not restored to their location when first moved by the adornment.
    • Notes/containers/agents that are locked are ignored.
    • Other attributes are ignored. Notes 'in' other adornment will be moved (even if the original adornment's sticky flag is set).
    • To read or set adornment attributes via $OnAdd actions, use the 'adornment' designator (it operates analogously to the 'agent' designator used in agents).
    • A note on the map can only move onto one smart adornment. In the case of conflict, where two or more smart adornments match a given note, the adornment with the highest $OutlineOrder will match the note. An adornment's $OutlineOrder can be looked up via its Get Info pop-over (attributes tab: General section). Normally, a duplication conflict resolves to the lowest outline order but in adornments the z-order and thus outline ordering is reversed (further explanation).

    If a smart adornment is made larger (manually or via an action) and in doing so overlaps non-matching notes then the latter are displaced to one side so as to remain outside the adornment. Re-sizing a normal adornment the notes would simply lie inside the new adornment boundary.

    Smart adornments cannot be used to move or act on notes outside the current map. So, for instance, it can not move a note into a (container's) subordinate map or promote it to a parent map, or indeed pull it from another map. Put another way, it can only act on its siblings.

    Smart adornments allow space for multi-line subtitles ($Subtitle), assuming that the adornment is drawn at or near standard magnification.

    Background patterns

    A Map view's background can use the same range of basic patterns as are available to map icons. The feature is set via a series of preferences on the Maps tab of Document Settings and settings are stored in $MapBackgroundColor, $MapBackgroundAccentColor, $MapBackgroundPattern.

    The same settings can easily be customised for a given map via the Map Properties pop-over

    Containers

    Notes (or agents) that have child objects are termed containers.

    Note that containers (notes or agent) do not support shapes. If a $Shape value is set for a note, and it becomes a container the shape setting is ignored.

    Aliases of Containers

    It is possible to zoom into the sub map of an alias of a container. However note that:

    • This is equivalent to zooming into the child map of the original.
    • Unlike the original container, the original's child notes are not drawn in the viewport of the alias of the container.
    • The alias container shows any table expression or container plot used by the original, which can be useful for dashboards.
    • Aliases of agent containers are drawn the same way as normal containers, i.e. with the title bar at the top. It is thus not possible to distinguish from icon layout alone whether the original is an agent or a normal container.

    It is possible to zoom into an alias of a container by double-clicking its body or by selecting the alias container and pressing the down-arrow key (). The map then displayed is always the map of the original container. Using the up-arrow key () or the breadcrumb bar to navigate upwards will always result in the original container being selected. Note also, that if the alias originally drilled into was on a different map, the map shown will now be a different one.

    Container plots

    A pattern that applies only to containers (notes & agents), is plot(). It evaluates an action code expression using data from each child of the containers to produce a graph; i.e. the scope is always a group, specifically 'child'.

    The graph, in the forms of a sparkline-type plot is drawn across the viewport area of the container. The graph is drawn in colour $PlotColor. The container viewport is still accessible for drag/drop, etc., as if the plot were not there: think of the plot as an overlay.

    For example, to graph the word count of each child note in the container, see the container's map Pattern attribute to use plot():

     plot($WordCount)

    An alternate plot type is bargraph(), which draws a bar graph of each child item's value.

     bargraph($WordCount)

    A further option is xyplot(), which offers a double variable plot:

    xyplot($Date,$Price) 

    The pie() plot gives a pie graph based on an attribute (or action code expression):

    pie($EditsMade) 

    The ring() plot displays an arc representing 70% of a complete circle. The circle is always drawn centred on a 9-o'clock position; a 50% completion would fill from 6 through 9 to 12.

    ring(70) 

    All plot operators accept optional minimum & maximum values, e.g. plot($Attribute,min_num,max_num). Thus:

     bargraph($WordCount,0)

    graphs the word count of each note whilst ensuring the Y-axis is based at zero, with all attribute values including the maximum being plotted. Note that while zero is the default value of an 'blank' number type attribute, the type allows minus values. The above example would treat all of them as if their value were zero. If a negative min value is supplied, negative item values above that threshold are plotted. The above example would treat all of them as if their value were zero. For:

     plot($WordCount,10,900)

    the plot graphs the data from a baseline of 10 to a maximum value of 900. Values outside these are plotted appropriately as the min or max values.

    Container plot-type patterns are ignored if applied to non-container notes.

    A container can also apply the bar() & vbar() progress bar patterns as used with note icons; these are applied to the containers title bar area. However, as both types of visualisation use the $Pattern attribute it is not possible to use a progress bar and plot at the same time.

    Where a container plot is applied, Before the graph is drawn, the space behind the plot is filled with the colour $PlotBackgroundColor with opacity of $PlotBackgroundOpacity. Previously the background was that of the child map.

    Table Expressions

    In map view, containers and agents (and their aliases), but not ordinary notes, can display tabular summaries of their contents using code stored in $TableExpression and $TableHeading which can be set in the attributes or via the UI using the container's Summary Table Properties pop-over dialog.

    Note: what is an expression?

    Tables are drawn only if there is adequate space in the title bar area. The number of rows displayed in the table is limited by the available space; increasing the size of the note (and its $TitleHeight) will increase the size of the table, i.e. the number of rows displayed. Note that the container's sort order is reflected in the table. See more on a container's title height.

    The displayed data is for the container's child notes; descendants are not included. For example, if $TableExpression is

     $Name+"|"+$WordCount
    Note: The '|' character (vertical bar or 'pipe') delimits code defining data for the separate columns of the table.

    For the above code, Tinderbox will draw a two-column table containing the $Name and $WordCount of the first few children of the container (for why only some children may be listed drawn see above).

    The expression's action code may be conditional. This lists all children with $Name and $Sibling order data displayed:

    if($Prototype != "Attributes"){$Name+"|"+$SiblingOrder} 

    This conditional version ignores any children that are agents:

    if(!$AgentQuery){$Name+"|"+$SiblingOrder} 

    This version only lists items of prototype type "Event":

    if($Prototype += "Event"){$Name+"|"+$SiblingOrder} 

    Amount of table data displayed

    If no $TableExpression is specified but space is available in the title bar, Tinderbox displays an excerpt of the $Text of the container or agent, as it does for notes. If a Table Expression is defined, display of $Text is suppressed, regardless of the height of $TitleHeight. In other words, it is possible to display either a table of child data or $Text but not both at the same time.

    Table headings

    Optional column headings may be specified in the string attribute $TableHeading. Again, columns should be separated by a '|' but note that if referring to attribute names in $TableHeading, a $ prefix is not used as the name is used as a literal string.

    So, the heading may be any one of:

    • a text label: "Note title|Word count"
    • an attribute's name: "Name|WordCount"
    • a mix of the two: "Name|Count of WordCount"

    Note the lack of $-prefixes in the latter two examples where an attribute's name (as opposed to its value) is used literally in the heading.

    Delimiting columns

    In bother the heading and the data (expression), the '|' characters to delimit columns is simply inserted inline in the name string, no explicit padding with space characters is required. Nor is there a need to se a '+'Any of the following could be used for the above table expression example:

    Other presentational points

    The left column (table and heading) is always left-aligned with all other columns being right-aligned.

    For agents, the table is shown beneath the title whilst the viewport remains above.

    The table uses various other attributes for its styling:

    *Text font: the table is drawn in $NameFont

    *Colour: the table default to use $NameColor but will use $MapBodyTextColor if set differently from $NameColor.

    *Text size: uses $MapBodyTextSize. Note setting the value to 1 will suppress display of table & text data.

    • The table heading and content have the same font/colour/size and cannot differ from each other.
    Container title height

    Containers and agents have adjustable height title bars.

    The height of the title bar may be changed by dragging the bottom of the (selected) container's title bar, or the top of the agent's title bar, to make the title area taller or shorter. Within the exposed 'title' area, subtitles, body text or table data is also drawn if there is room, as on a normal note icon.

    The height of the title bar may also be changed by setting the $TitleHeight attribute. The attribute uses Tinderbox map units for its value.

    To 'hide' the viewport area of a container, set the $TitleHeight to equal $Height (or for agents, $Height-0.1). This makes the map icon look like a normal not except the 2 bottom (note) or top (agent) corners are rounded. While the viewport hidden, it is not possible to double-click drill down but its shortcut (Cmd+Opt+Return) will work.

    Container viewport is scrollable

    In map views, the view inside a container (the 'viewport') reflects the container's current scroll position. So, dragging the background of the interior of a container scrolls the inside of that container and also updates the opening co-ordinates of the child map opened via that viewport ($MapScrollX and $MapScrollY). Adornments seen on a viewport map cannot be dragged.

    Conversely, scrolling in a map view of the children will result in scrolling of the parent container's viewport contents.

    Note that dragging a note in a container viewport outside the viewport drags that note out of the container (i.e. promotes it from child to sibling). To drag the container icon on the map, drag its title bar. If an interior note is locked, clicking on it will not begin a drag.

    Layout, container vs. agent

    Map containers can be one of of two forms:

    • notes containing other notes
    • agent that contain aliases to any note matching the agent query.

    To help differentiate these two different types of containers, they are given a different visual render:

    • normal containers show their title area at the top of the icon above the viewport of the container's contents.
    • agents show their title area below the viewport.

    This difference is replicated in Outline view icons whereby containers have a thick bar at the top if the icon and agents have it at the bottom of the icon.

    Viewport detail in containers & agents

    A number of attributes make it easier to show detail within containers, be they notes or agents:

    $InteriorScale, which allows setting of a scaling factor used when drawing the viewport contents. This allows more note detail to be shown or conversely a larger amount of the child map contents. Changing $InteriorScale forces a re-draw of the viewport.

    • $MapScrollX and $MapScrollY. These control the X/Y co-ordinates of the child map that will be displayed at the horizontal/vertical centre of the container icon. Whether that actual point is visible in the viewport will depend on the $TitleHeight of the container.

    The order/location of aliases seen in an agent can be moved and seen in more detail in an agent's viewport.

    By clicking and dragging the map background within the viewport, the child map can be 'scrolled' within the viewport. Such a change updates the $MapScrollX/$MapScrollY for the container in question. Adornments cannot be drag-moved on a viewport map, drill down to do this.

    Details maintained in container viewport display: Shapes, Progress bar mark-up (bar/vbar), map background colour, adornments, icon shadows. In fact it shows pretty much everything except:

    • the display of body text.
    • table expression data.
    • viewport data within containers, though containers on the viewport map that have container plots will still show these.

    Notes being drawn in the interior of agents and containers respect both their own opacity and the opacity of their container. Thus, if a container is translucent, the notes inside it are also drawn translucently.

    Container and displayed $Text

    If the title area ($TitleHeight allows) the title bar may display note $Text.

    However, if the note defines a table display this is shown in place of any $Text.

    Dashboard concept

    [The image here is courtesy Mark Bernstein, reproduced with permission.]

    In TBX 'dashboards' leverage the map view, though there is no built-in dashboard feature as such. To make a dashboard simply plan an additional map view in your TBX whose layout is set up to illustrate key data about your project. The layout, styling and choice of data to display will vary by the needs of the TBX's subject matter.

    Some attributes needed for dashboard-style display are shared with source notes, others are not, involving slightly more careful planning. Remember too, that alias titles are always italicised and that cannot be overridden.

    A dashboard can use any combination of notes, aliases and containers/agents to shows its data. By making a container off the TBX root to hold your dashboard, you can more easily do things like change the $MapBackgroundColor without concerns about this colour being used in your main content where it may be less appropriate. If using agents in your dashboard do give thought to their scope and $AgentPriorty. Be prepared to adjust the latter if a first attempt results in significant increase in agent update cycle time.

    Editing note titles in Map view

    When editing a note name, pressing Return (↩) closes the edit, with focus remaining on the current note.

    From v11.0.0, previous methods to split a note whilst in this edit state have been removed as they proved problematic for general use.

    A note can still be split from within $Text, i.e. with focus in the Text pane and the cursor in the $Text area. This feature is accessed from the Note menu.

    Force Directed Layout: 'Dance'

    Note: this feature is experimental and the result is not undoable.

    In map view, View ▸ Arrange ▸ Dance (⇧⌘-D) initiates an automated layout of the view based on a physical simulation. Each link among notes in the map is treated as a spring that pulls linked notes together. The effects of Dance are undo-able (but if trying this it is best to do so immediately after the Dance, so its top of the undo stack).

    The behaviour of Dance is controlled by a pop-up shown when then the feature is invoked

    All notes exert a gravitation attraction for other notes. Notes that overlap repel each other. Notes that are textually similar to each other attract each other. At the beginning of the simulation, each note is subject to a random force, much as if it were heated. The force is reduced progressively over time. This process, known as simulated annealing, helps the simulation from getting tangled up in local minima.

    Each adornment that has one or more values of $ClusterTerms attracts notes in which those terms appear in the text. Adornments are otherwise ignored in the simulation.

    Not all maps will benefit from automatic layout; for example, the famous (Storyspace) map of Mary-Kim Arnold's "Lust" does not due to its many inter-connections. Performance may be unsatisfactory in maps with more than a few dozen notes.

    Dancing automatically stops when any note is dragged. Otherwise, the effect of the drag can impart a vast, unwanted acceleration to the dragged item.

    If more than one note is selected, only the selected notes will be moved by the Dance command; this is very convenient when arranging a cluster of related notes in a large map.

    If no note is selected, or only a single note it selected, then all unlocked notes are moved by the Dance command.

    Map Composites

    Only seen in map view, composites offer a means of treating a group of notes as a consolidated collection.

    Map Coordinates

    Any object on a map will have a position defined by the location of the top left corner of the item, stored as $Xpos and $Ypos; the icon is then drawn to $Width and $Height from that location.

    Tinderbox map co-ordinates differ slightly from normal X/Y graphing. The X axis is the same: positive to the right of zero, negative values to the left. However, the Y axis is flipped with values up the page from zero being negative and downwards being positive. Why the change?

    It makes sense if you take into account the fact that Tinderbox starts a new map by setting the top left corner of the map window to {0,0} adding noted into the bottom right quadrant of the map, populate it right-wards and downwards. In Tinderbox's co-ordinates this quadrant uses positive X and Y values rather than positive X and negative Y in a more conventional graphing method.

    Thus the first items on any map are using positive values for $Xpos and $Ypos. The accompanying image is thus a bit misleading as Tinderbox map will, without any manual user intervention, fill the bottom right quadrant of the map. A slight exception to this is that if a note is dropped onto a (non-container) note this first child item is placed at {-2,-0.5} on the new child map. However subsequent content is added down and right, i.e. in the bottom right quadrant of the map.

    In general use, Tinderbox's 'reverse' polarity of the Y axis will be hidden from the user. The facts are only really important if the document is being scripted and items need to be precisely positioned. This co-ordinate system also allows for potentially infinite maps. Tinderbox can 'add' more map in any direction as needs be without having to reset the frame of reference.

    Map co-ordinates are also referred to as map units, which are used by a number of attributes to store portion or size related data.

    As illustrated, the (right-click) content menu when clicking on the map background (as opposed to over a map item) will give the {X,Y} co-ordinates of the click in Tinderbox map units for the current map.

    At normal zoom level 1 map unit equates to approximately 32 pixels (this may vary on more modern systems).

    Map grid & guides

    When moving objects on a map, their boundaries 'snap' to the nearest 0.5 unit of map measurement. In addition alignment guides are shown to enable grid-like placement if so desired. The guides can be turned off if they are distracting, via View menu, Guides.

    Map view guides have been simplified and improved. Additional guides help to:

    • align the vertical and horizontal centres of notes
    • maintain uniform spacing between adjacent notes or place notes next to each other
    • align the edges of notes
    • maintain spacing between notes and the edges of the adornment that contains them
    • place a note symmetrically between two horizontally-adjacent notes
    • create square notes and notes using the golden ratio. These aspect ratio guides show as additional on-screen guide label when a relevant ratio is achieved.
    • align left or right edges of notes to the midpoint of notes above or below them.

    Guides look for equal spacing between adjacent sets of notes. If there are two adjacent notes, A and B, and C is then moved next to B, the guide will make the space between B and C the same as the space between A and B.

    Guides examine the neighbourhood around notes with a circular shape, looking for other notes that are nearly the same distance from the circular note as the note being dragged.

    The guide for centring a note between two other notes formerly considered only the notes closest to the dragged note. It looks for matches among all pairs in the vicinity of the dragged note.

    If the shift key (⇧) is depressed while dragging this also disables guides, which are drawn in grey rather than the usual blue-green to show that they are inactive.

    Whilst dragging a composite various guides including the aspect-ratio guide, that affect properties internal to the composite, are not displayed.

    Map View endeavours to be smart about which guides it displays. For example, no amount of dragging an object can change its aspect ratio, so aspect ratio guides appear only when resizing an object.

    A new map guide notices when a note or adornment is approximate the same size as one of its neighbours, and snaps the note size to match the neighbour. If no nearby note is approximately the same size, the guide looks for notes with approximately the same height or width.

    A new map guide looks for 45° diagonal alignments between nearby notes.

    The edge alignment guides examine notes within a radius based on the size of the dragged note, rather than based on a fixed radius. Diagonal alignment guides have a smaller range.

    Grids and close-vs.-far objects

    Guides can only assume so much. Sometimes it is desirable to align two items whose relationship is obvious to the eye but less so to the guide logic. For example, aligning the left edges of two important notes that are separated by many other notes. By comparison, guide logic is invoked on the relationship of the closest objects. If guides do not show the desired alignment prompt, use the explicit commands on the Arrange menu.

    Automatic gridded arrangements

    These grids are for manual positioning use. To alter the default layout behaviour of maps inside agents (i.e. their aliases) see re-arrangeable agent maps.

    Map overview mode

    To see an overview of the entire map, press and hold the Control, Option, and Command keys (^+⌘+⌥) simultaneously.

    To zoom to a different part of the map from the overview, move the mouse cursor to the area of the map in which you are interested before you release the ^+⌘+⌥ keys.

    From v11.6.0, when using the zoomed-out overview mode, the portion of the map that is normally visible is now highlighted. In addition, the zoomOut:/zoomBack animation is skipped for complex maps, as it is too slow to be helpful.

    Map object icons
    Auto-coloured note titles

    The titles of map view note icons are rendered in $NameColor, whose default value is "automatic". This means that in most cases the note's title is rendered in black (#000) or white (#fff) according to which offers the best contrast. In some cases, where neither black nor white may offer good contrast, titles use a yellow colour.

    These automatic colours cannot be redefined, though $NameColor can be set to user-defined colour though this does mean the title colour will not change if $Color changes in a manner lessening contrast.

    Automatic colouring was defined before more recent inclusion of new colour schemes, i.e. the 3 default 'automatic' choices were not optimised for all colour schemes.

    Badges on icons

    Notes may be decorated with a 'badge', a small icon that appears to the left of the note name in outline view and in the upper right hand corner of the note in map view (or lower right corner for containers/agents).

    Badges are displayed in a slightly different location according to the type of icon (as illustrated):

    • Note: top right of icon
    • Note container: bottom right of icon
    • Agent: top right of icon

    The reason for this is that in the case of the containers, the part of the icon holding the title is comparatively small and a badge could intrude on that.

    Badges are not shown on icons displayed in the viewport of note and agent containers.

    Badges may be selected from the badge picker pop-over by clicking on the area where a badge is displayed (see list above).

    The note's badge is controlled by a string attribute $Badge, which holds the name of the badge. The value of $Badge may be set through inheritance, rules, or actions as well as well as manually via the pop-up list. Additional attributes control monochrome display ($BadgeMonochrome) and the exact size ($BadgeSize).

    When a note is selected in map view, a subtle "+" is drawn where the badge would appear if the note had a badge. This helps users discover the location of the contextual badge menu.

    Large badges with $BadgeSize > 32 respect the shape of the note and are clipped to its border. Small badges, as before, may extend outside the drawn region of the note.

    From v11.0.0, badges may be dragged from notes to other notes in map and outline views.

    Captions

    A new text field, $Caption, can appear beneath a note or an adornment, in map view only. Captions are intended to be additional annotations or comments about a note.

    Caption appearance is controlled by $CaptionFont, $CaptionOpacity, $CaptionSize, and $CaptionColor.

    Captions be edited by selecting the note and then clicking on the caption. Captions may also be edited in the Caption pane of the Name inspector, or by setting $Caption via action code.

    The caption's font may be changed using the font palette (by default the bundled Sketchnote font is used). Note that the font selected is used for the entire caption (no mixing of fonts).

    Captions are based on 16pt type (in older versions this was 12pt.

    Content Dogears

    In Map views, Tinderbox uses a 'dog-ear' (like the folded page corner) to denote the presence of content; Outline view uses a different method, with content-related variable note icons.

    The dog dog-ear is not interactive, it simply indicates that a note has content. In Map and Treemap views, the dog-ear is bottom right of the note icon, in Charts it is at bottom left of the note icon.

    The background colour of the dog-ears is the same variable colour used for outline icons to indicates the age of the note (since last edit). Originally, the background colour of the dog-ear was the view's background colour.

    Drag resizing notes

    To assist in resizing notes, a number of keyboard modifiers may be employed. Importantly, the modifier key(s) must be pressed before commencing a drag. During the drag snap-to-guide is ignored. The modifiers are

    • [drag]+[Shift]: constrain to horizontal/vertical movement ignoring guides. Dragging from a corner essentially lock both axes so the note grows/shrinks in current width/height proportion.
    • [drag]+[Option]: resize around current object centre (from v11.5.1)
    • [drag]+[Option]+[Shift]: constrain to horizontal/vertical movement whilst resizing around current object centre (from v11.5.1)
    Icon dashed borders

    Map note icons may display dashed borders if:

    • The icon is simple note and not an agent, container or adornment.
    • The $BorderBevel type is 'plain' (N.B. not the default setting).
    • The $BorderDash has a value greater than 0.

    The $BorderDash controls the length of each dash; the Border inspector sets the dashes to 5 pixels (use actions or Info view to set other values). The width of the dash is drawn as per the $Border value.

    Icon drop-shadows

    Notes may cast a shadow when drawn on maps.

    The following new attributes control the appearance of shadows:

    On very large maps (and/or less powerful computers) it can help with performance of Map view is shadows are disabled by setting Shadow to false. There is no preference to do this app/TBX-wide but stamps to agents can help. With agents consider use of the inside() and descendedFrom() queries with $OnAdd action of $Shadow=false. To reverse the setting use the same query but with $Shadow=true. Or write a toggle action:

    if($Shadow){$Shadow=false;}else{$Shadow=true;} 

    Of course, being a toggle, a stamp like above would only be useful if all notes selected had the same $Shadow state!

    Icon fill textures

    Map icons can use texture fills, for containers and agents the fill is used within the caption area of the icon but not the viewport. These textures are set via the $Fill attribute and the opacity of the fill texture can be further controlled by the $FillOpacity attribute.

    If $NameColor (the colour of the title text) is set to the default of 'automatic') then the icon's title will be black or white text depending on the colour value of $Color and not the colour of the fill texture image. Thus if using fills it may be necessary to also set an explicit $NameColor value in order that there is sufficient contrast to read the title.

    The texture is used to fill the whole face of notes and adornments. For containers and agents, the texture fills the part above/below the viewport as used for the title & text/table.

    Built-in textures have the following name values:

    • linen
    • sandstone
    • steel
    • wood
    • water

    Users can supply additional custom fill artwork; only JPEG format files are supported.

    When setting $Fill, Tinderbox accepts a file name with or without an extension. If the user file folder contains the file "TestFill.png", then setting $Fill to "TestFill" or to "TestFill.png" is equivalent.

    If a note has a fill, ⌘⇧-drag inside the note to move the fill image. Such a the fill image is scaled to fill the width of the note, and the centre of the image coincides with the centre of the note. $FillOffsetY moves the image vertical centre up or down from the note vertical centre.

    Icon stripes

    A map icon has the option to draw a stripe of solid colour at the right edge of the note. The edge coloured is only ever at right and not subject to user choice.

    $Stripe determines the width of the stripe, in pixels at standard scale; if $Stripe has no value (the default) no stripe is drawn.

    The colour of the stripe defaults to $AccentColor, but may be set to any colour by changing $StripeColor.

    Note Flags

    Map view allows optional 'flags' to assist in qualitative analysis and coding. One common Tinderbox task is qualitative analysis of existing materials, such as letters, surveys, diaries, and personal papers. An important preliminary step in this work is coding—identifying occurrences of special interest for the study. For example, if we were analysing a collection of nineteenth-century diaries to study what people recorded about food and drink, we might want to code where the food was consumed. We might mark every passage that discussed eating at home with the code P1, eating at the residence of another family member with the code P2, eating at a pub with P3, and so forth. We might also note places where money is discussed: C1 might indicate that the writer paid for their meal, C2 that someone else explicitly paid for the writer's meal, and so forth.

    Flags offer a convenient and flexible way to foreground selected codes in map view. Flags are defined via $Flags, a List-type attribute. When not empty, small "flags" are displayed above the note in map view. (N.B. flags do not appear in other views). Note that as $Flags is a List-type attribute, actions can add new flags with "+" or remove flags with "-". Adding a flag to a note that already possesses that flag has no effect.

    $Flags is an intrinsic attribute; it is not inherited from prototypes and an alias may have different flags from its original note.

    For simple coding tasks, using $Badge may be adequate. Flags provide a wider range of visual cues, and new flags can be improvised quickly when coding needs change.

    Defining Flags

    Any individual flag is define as a text string, using a concise textual shorthand, and are illustrated in the screen-grab. The base definition is a colour. Whilst it is generally easier to use named Tinderbox colours, hexadecimal values can be used to define flag colours as in the first example below. At minimum, a flag must a define a colour. This forms the fill colour or the backgrounds colour if a pattern is overlaid. If a colour is missing or misspelt, a red-orange colour will be seen which is Tinderbox's signal of an undefined colour.

    Optional text labels (of up to 3 characters) are also possible.

    The basic syntax is the base colour with either/both a text-related prefix or a pattern-related suffix:

    [text-color:text.]fill-color[pattern-info]

    Setting text is detailed below—see 'Using Text in Flags'. The syntax above offers a range of possible design variations. The examples listed below are shown in the page's illustration. Note, too, the possibility of combining styles to make more complex colours:

    • Single solid colour. A red flag: red, or #00ff00, or #00f
    • Horizontal stripes. List the stripe colours separated by hyphens: red-white-blue
    • Vertical stripes. List the stripe colours separated by the vertical bar character: blue|white|red, or green|white|blue|white|green
    • Diagonal stripes. List the stripe colours separated by the '/' symbol: yellow/black, or green/yellow/blue
    • Chequered flag. List the two colours separated by the '$' symbol: black$white
    • Cross symbol. List the cross colour, a '+' sign and then background colours: white+red, or white+yellow/black
    • Saltire symbol. List the cross colour, an asterisk '*' and then background colours: white*light blue
    • Diagonal line. The '%' sign adds a diagonal line: green%white, or white%light blue/red
    • Chevron. The '>' symbol adds a chevron: green>red
    • Pall. The '}' character adds a pall: white}red
    • Pall and Chevron. The pall and chevron work together: white}green>blue, or yellow}red>blue-green
    • Test. See the next section.

    Using Text in Flags

    • Text caption. This is placed before the fill colour, joined via a period (. ). This allows for a short textual annotation (1-3 characters) on top of any other colour/pattern: A1.red, or 42.green>red, or BZ.yellow$light green to overlay a pattern. In the latter case beware of contrast/legibility.
    • Text colour. Though the default text colour is white, a colour may be specified for better contrast. The text colour is prefixed to the text with a colon join: e.g. black:C.lighter blue (black text on a blue ground), or #ffd700:F14.black (yellow text on a black ground.
    • Using emoji. The text may be an emoji: ⚾️.green 
    • Reserved characters in text. The characters >*+.$%} are treated as literal characters if they are used the first three characters of flag code using the period marker, so +.red draws a plus sign on a red flag. Further, do not use using colon, semi-colon or period (:;, ) as these get interpreted respectively as a dictionary key delimiter, a list delimiter and the flag text/fill-colour delimiter. So, if wanting to use label '3.1' consider '3-1' instead. Also, the default colour for the text is white, so do consider defining a text colour. So not 3.1 or 3-1.green, but 3-1.green.
    • Text label length. Don't forget text is limited to only 3 characters or fewer. If more are supplied, the result is only the first two characters are displayed plus an ellipsis character. Thus there is little point in using long labels. In the previous example, label '3-1' is considered to be 3 characters, as the hyphen still counts as one.

    Progress bars in Flags

    Flags permit several additional action code expressions, useful for showing progress bars.

    • bar(value[,min,max]). Draws a horizontal progress bar, using the note's $Color and $AccentColor values. If the minimum and maximum values are not specified, they are assumed to be 0 and 100. More on the bar() pattern.
    • vbar(value[,min,max]). Draws the a progress bar vertically, using the note's $Color and $AccentColor values. If the minimum and maximum values are not specified, they are assumed to be 0 and 100. More on the vbar() pattern.
    • pie(value[,min,max])). Draws a pie chart, using the note's $Color and $AccentColor values. More on the pie() pattern.

    When drawing flags using bar() or vbar(), Tinderbox draws the flag outline in $AccentColor. This should be helpful when $Color contrasts poorly with the view's background. Flags using the pie-chart progress indicator draw their outline in $Color, making them easier to read.

    Defining multiple flags for a note

    As $Flags is a List-type attribute, if defining multiple flags for a note, use a semicolon between each flag's code. Thus, this code '[white}green>blue;yellow}red>blue-green]' defines two discrete flags for a single note.

    Defining flags via code

    The string or list passed to $Flags is not evaluated further—$Flags being an attribute not an action code operator. But action code can be used to assemble data from variables or other attribute values to generate a valid string that is then set as the value of $Flags. For example, showing a mix of literal, variable and attribute sourced text:

    	var:string vText;
    	var:string vTextColor = "blue";
    	vText = vTextColor+":"+$MyString +"."+$MyColor;
    	$Flags=(vText);

    Multiple Flags and icon width

    The default map icon will display up to four flags. By dragging the note wider, all defined flags can be displayed (as illustrated). The display does not indicate that more flags are defined than can currently be displayed. If planning to regularly use more than 4 flags, give consideration to changing the document's default $Width of notes.

    Colours and Tinderbox Colour Schemes

    As Tinderbox colour schemes files allow a named colour to be any value, it may be safer to use use colour values (e.g. #00ff00) rather than named colours (e.g. red) if you are not using the Tinderbox v7 standard scheme (as used to illustrate here) or consider switching between colour schemes. Another approach is to make new 'new' colours for use in flags. So, if your favourite colour scheme renders the colour named 'green' not as green, you could make a new colour 'fgreen' and set the desired (visual) value of green and then use 'fgreen' instead of 'green' when setting $Flags. The exact name of the colour doesn't matter as long as it is not the same as an existing named colour.

    If adding such extra named colours, be aware that they only existing in the current TBX document. Applying a different colour scheme to the document should not affect such custom colours (unless the new scheme includes a same-named colour with a different defined colour value). Thus a good idea, after adding extra colours, is to save the documents current colours as a colour scheme file ensuring it is possible to re-assert the colours if something changes their value in the current document and have the possibility to apply the same scheme to other TBX documents.

    Flags in Outline view too

    In Outline view notes can display their first flag (only) instead of a colour swatch: see more detail.

    Opacity & Transparency

    Map note icons and adornments but not the title part of containers/agents can use transparency. The transparency allows background items to show through where notes overlap.

    If a note has an $Opacity of zero, it does not a drop shadow, flags, or a badge. However, when the note is selected the badge is drawn, as are the link widget and the resize handles.

    Note transparency is set via the $Opacity attribute, with 100 (default) being opaque and 0 being totally transparent. Unless the $Border is also set to 0, a note always retains a border regardless of transparency.

    An alternate and easier way to get a transparent (invisible) map icon for a note or adornment is to set $Color to 'transparent'. Doing this suppresses borders and drop shadows, but the title is left visible.

    However, if $BorderStyle is set to 'automatic' Tinderbox is clever enough to suppress borders if $Opacity is set to 0 (transparent).

    Transparency is effected within the normal stacking order of a map. Thus if transparent note A overlaps opaque B, if B has the higher $OutlineOrder, B will simply overlap A. If the $OutlineOrder is reversed A will both overlap B and B will be visible within the overlap.

    Adornments, by default, already have a built-in fixed level of transparency. This is because adornments are often used in overlapping layout and the semi-transparency enables the areas of overlap to be seen more clearly. If fully opaque adornments are desired, an option on the Maps tab of Document Settings allows this, but note that it is a global setting affecting all adornments and overriding $Opacity settings. If it is desired to leave the default document setting for (semi-)opaque adornments, then for adornments desired fully opaque it will be necessary to set their $Opacity value to greater than 100 (a value of over 260 may be needed).

    The opacity of a note's title and subtitle can be set separately from overall note opacity via $TitleOpacity and $SubtitleOpacity. Be aware that $Opacity still trumps the latter two attributes, if their values are greater than that of $Opacity, the latter value is used for all. Thus if $Opacity is 100, $TitleOpacity may be 50, half that of the overall note. But, if $Opacity is 50, and $TitleOpacity is 100 the title is drawn at 50% opacity.

    In short, the latter ends up being generally what might be expected. It does preclude having a 'invisible' note with a visible title. To do the latter, set $Border to zero and $Pattern to "none" and $Color to the parent container's $MapBackgroundColor.

    Automatic colours, such as are used in note titles, obey $Opacity settings.

    Note progress bars

    Notes and containers in map view can make use of patterns that simulate horizontal (bar) or vertical (vbar) progress bars. As the patterns can use evaluated arguments as well as fixed numerical values this form of mark-up allows the progress of tasks to be monitored and displayed in the background.

    Containers (including agents) can use progress bars too though the progress bar is drawn across both title bar and icon, not just the title bar. Use of progress bars is not compatible with use of container plots as both features use the Pattern attribute to store their value.

    This progress bar can also be displayed in outline view using swatches.

    Progress Bars accept an optional fourth argument, a target value, casing a thin line to be drawn at the target position.

    Note, Container and Agent icon layout

    In Map view, notes and agents are differentiated similarly to an outline, where note containers have the title bar at the top and for agents it is at the bottom. However, whereas agents always show up as a container, regardless of whether they contain anything, a note only shows as a container if it has children.

    Unlike Outline view, Map view agent icons do not give an indication of $AgentPriority status.

    Notes within agent maps are always aliases. Setting $CleanupAction allows re-arrangeable agent maps.

    Notes accommodate titles

    Note windows can be resized easily in order to accommodate the full title of the note. This is most useful in Map view when taking notes in Map view using the titles only to capture content (e.g. rough notes during a talk).

    The feature is accessed via the Note menu. There are two options:

    • Expand Horizontally (Map view only, otherwise greyed out). Tells Tinderbox to attempt to widen the note's map icon ($Width) to display the whole note title ($Name). The selected note's icon is expanded at the right side, maintaining existing height and X/Y origin. May be used in conjunction with Expand Vertically (below). The revised map note width ($Width) is saved. Keyboard shortcut.
    • Expand Vertically (Map view only, otherwise greyed out). Tells Tinderbox to attempt to increase the depth ($Height) of the note's map icon to display the whole note title ($Name). The selected note's icon is expanded downward, maintaining existing width and X/Y origin. May be used in conjunction with Expand Horizontally (above). The revised map note height ($Height) is saved. Keyboard shortcut.
    • Expand proportionally. (Map view only, otherwise greyed out). Tells Tinderbox to attempt to balance an increase both the width ($Width) and depth ($Height) of the note's map icon to display the whole note title ($Name). This option has no keyboard shortcut.

    All these act without altering the default text size of the title's label ($Name). If the desire is to adjust the label text size to better fit the existing icon width/height—i.e. by shrinking or increasing the font size used, then adjust the note's $MapNameSize attribute.

    Also consider the feature to display a note's body copy.

    A preference is available to automatically apply one of the above (or none) as a default for new notes.

    Containers and agents also display multi-line titles (and even body text), if sufficient space is available.

    Note titles

    The font used to render the title ($Name) is set via the Maps document setting Map Font but can be overridden at note level by setting $NameFont to a different value.

    The alignment of the title is controlled via $NameAlignment. This is separate from the alignment of displayed $Text, with left aligned being the default for both.

    A container's title bar does not allow for displaying both $Text and a Table Expression. A table expression is drawn in the same part of the map icon used to display a note's $Text, therefore both cannot be shown in the same map icon. If $TableExpression or $TableHeading are set, $Text will not be displayed. More on container summary display tables.

    Be aware that adornments have the option of using a different font for their titles: $AdornmentFont. If the latter is not set at document level, adornment labels default to using $NameFont. Also, with app default settings, the font size (in points) of as adornment title (32pt) is twice that of a note (16pt).

    Notes displaying body text

    In map views, large notes display (a portion of) the note's body copy text ($Text) as well as the title. The note's text only appears if:

    • The note has some text.
    • The note icon is sufficiently large more than the title and (option subtitle).
    • For containers, including agents, the title height ($TitleHeight) area is sufficiently large.
    • The note is not an adornment or picture adornment. Adornments do not have text. More strictly, they do have $Text but even if it has a value it cannot be displayed like note text.
    • The note does not use a shape for display. Text thumbnails are drawn in rounded (shaped) notes as well as normal rectangular notes.
    • The note has no $TableHeading or $TableExpression set. See below re table expressions.
    • $MapBodyTextSize is not set to '1', so as to suppress table/text display.
    • Notes with no title will display body text if present; previously body text display was suppressed in such notes.

    $Text Style

    Do note that the text that is displayed is not styled; think of it as a $Text 'preview'. Thus whilst text colour is not honoured, the

    $Text Size

    An attribute $MapBodyTextSize allows setting a size for all displayed $Text. It also allows a value that suppresses display of any body text: in such a cases case the vertical alignment of $Name re-applies.

    $Text displayed colour vs. in-$Text colour

    $MapBodyTextColor sets the colour used to display such text. Be mindful that colour settings within $Text is not reflected in $Text display in the note icon.

    $Text Fonts

    The font used to render the text ($Text) is set via the Text document setting Text Font but can be overridden at note level by setting the $TextFont to a different value. Thus the displayed text for a given icon can show text in a variety of fonts.

    Images in $Text

    (not illustrated)

    There are two possible renders depending upon whether an image starts $Text, i.e. is a $Text character position zero.

    *Otherwise the image is shown in its $Text location if space allows.

    Note icon size and prototypes

    When a note adopts a prototype, the note's $Height and $Width are initially changed to match those of the prototype. However, this is a one-time effect $Height and $Width are not inherited; the change affects only the initial dimensions of the note.

    The default size for notes is w 4 × h 2.48 (an increase of 33% from an older default of w 3 x h 1.86).

    When assigning a note to a new prototype, the note's initial $Height and $Width are set to match the prototype's height and width provided that the note's dimensions have not already been changed from the default. If the note has been resized, those dimensions are preserved.

    Notes with images in text

    If a note's $Text begins with an image, that image is drawn on the face of the note, as if it were a fill. 'begins with' implies that the image data is the first character of $Text. Thus there can be no text, whitespace, line break, etc., before (above) the image in the $Text area.

    If the note's $NameColor is automatic, the colour of the note is changed based on a colour sampled from the image, so that a contrasting title colour may be chosen automatically. If the title is still an annoyance set the $NameColor to 'transparent'. This is most easily done using the 'Color' control on Text Inspector's Title tab.

    This 'fill' display process will not occur if there is any text (including spaces) before the first image in the text. If such exists, normal rendering of note text/images will occur.

    When the text of a container begins with an image, that image is used to fill the title bar section of the map icon, just as it does with a note without children.

    Shaped Map notes

    Notes and adornments may be set to use differently shape icons in Map view, i.e. other than the normal rectangle. Whilst adornments can use shapes, if using shapes it may be necessary to use a $NameColor setting other than 'automatic'.

    The shape of a note is determined by its $Shape attribute, and is inherited from its prototype (shape name values are case-sensitive). The $Shape submenu of the Note menu lets you change the note's shape conveniently.

    The shape of agents and containers is fixed; they ignore the $Shape attribute if it is set by the user. Thus a visible shape can only be set for a note with no children. Notes displayed in the viewport of an agent or container use shapes.

    With the exception of 'cloud' and 'bubble' shapes can be transparent and have borders; 'cloud' and bubble' have no border if made transparent.

    Shapes are probably best reserved for special occasions/purposes, in order to emphasise exceptional or unusual notes. Otherwise, maps may become a little busy.

    Notes with non-rectangular shapes may use the bar, vbar, pie, and ring progress-bar patterns.

    Note subtitles

    Map icons, including adornments, can show a subtitle ($Subtitle) below the main title ($Name) and above any displayed $Text. Further attributes control the colour ($SubtitleColor), opacity ($SubtitleOpacity) and text size ($SubtitleSize) of the subtitle. The alignment of subtitles is linked to that of the note's title, i.e. $NameAlignment controls both title and subtitle.

    Even if a subtitle is set, it is only drawn if the map icon affords enough (vertical) space to draw it.

    Subtitles ($Subtitle) can be edited in place:

    • If the there is an existing subtitle, double-click it or click-hold it to ender edit-in-place mode. Press Return to complete the edit.
    • If there is no current subtitle, click-hold just below the title to ender edit-in-place mode.

    The subtitle's text is not part of the $Text. However, it could be. For instance, by using action code to set $Subtitle as the first sentence or paragraph of $Text or by setting $Subtitle to be extracted first paragraph of $Text.

    Map Units

    Tinderbox uses the same units for a number of Map view related attributes:

    When used for position, attributes use two unit values to give Map co-ordinates.

    Whereas co-ordinate values may be positive of negative, for basic sizing positive values should always be specified.

    Note: the following applies to v5.x or earlier and will likely not be accurate with 4k displays. To map Tinderbox units to pixels use this formula: (N*36)-4 where N is the map unit figure. Thus 3 map unit = (3*36)-4 = 104 pixels. The '-4' adjustment is because Tinderbox allows a 2 pixel 'outer' buffer all round. As this buffer area never overlaps during automatic spacing of notes, it ensures at least a minimum 4 pixels gap between map icons.

    Positioning newly created notes

    When Tinderbox needs to choose a map position for a note (e.g. in an outline when the note is created, or dragged into a new container), it is careful to avoid colliding with existing notes. Notes created outside Map view are automatically assigned plausible map positions.

    [Ctrl]+[Opt]+Return (^⌥-Return) creates a note below the selected note. Return creates a note to the right of the selected note, and [Ctrl]+Return (^-Return) creates a note to the left of the selected note. If there is already a note where Tinderbox would place the new note, Tinderbox seeks a suitable location.

    Note: in earlier versions of Tinderbox, the app would sometimes give up the search for a plausible position and place all new notes at {0,0} (in map co-ordinates). This should no longer occur but the issue may be seen in old TBX files created using older versions of Tinderbox.

    Map Posters

    Posters let Tinderbox incorporate all sorts of visualisation tools into the map view. Consider posters as a way to use powerful visualisation libraries inside Tinderbox, opening up a powerful canvas on which to draw. It is a mistake to think of this web view as an intended way to view web pages—although that is possible.

    Any note can have a poster, or more precisely, be a poster. Notes that have a poster display a small web view in front of the note icon. The poster cannot be moved so as to show the normal map icon. In a map, any note is either a normal note icon or a poster.

    Be aware that:

    • posters are displayed only in map view. (They behave normally in other views.)
    • a note's poster obscure its normal map icon.
      • a note is either a normal map icon or a poster. If wanting a poster relating to a note that needs to remain visible at the same time as the main note itself, make a sibling (poster) note as this allows both to be visible at the same time.
    • a note that has a poster takes responsibility for drawing and updating itself.
    • a note or adornment used for a poster should not set HTML export mark-up for paragraphs.
    • to avoid confusion is is suggested Markdown not be used simply to format the note text—use the apps' default HTML export settings along with the 'Poster' built-in prototype (see below).

    Supporting system attributes

    The poster feature is supported by the 'Poster' group of system attributes. See Creating new posters for why this

    Supporting built-in prototype

    The built-in 'Poster' prototype is designed to preconfigure poster using notes by altering some system attribute default values.

    Template-based posters vs. posters of line URLs

    A poster can be defined either via a Tinderbox template or by supplying a URL, though the latter is primarily there for less common cases where the template method cannot be used. If, by mistake, the user specifies both a template and a URL, the template approach is used.

    From whence comes the poster data?

    In the most simple example the post note holds any necessary data, at least as regards data held in the TBX as opposed to being drawn from the web or local disk resources.

    Javascript or other languages?

    This has some nuance. As a poster essentially shows what might be seen in a web browser. So all, or at least some of the code needed with be JavaScript. But, in principle, anything a browser can show (e.g a Java applet) might possibly work. The more the envelope is pushed in terms of types of code in use, the more the user should start by testing a web browser before migrating the code to a poster note. The more complex/exotic the mix of code the greater the likelihood of meeting unexpected issues, especially relating to (OS) security—i.e. the poster code trying to access information outside the TBX that the OS believes should not be accessible for safety reasons.

    Poster of a note vs. note as a poster

    An easy misconception is to think of a poster as the visualisation of a note and assume that the poster can be moved to also show the 'normal 'map' icon. This is not so! In such a case, it is necessary to make a new note to 'host' the poster as the two are now discrete entities that can be positioned independently on the map.

    Other notes about posters:

    Poster attributes

    A number of system attributes assists in the creation of posters.

    PosterTemplate

    $PosterTemplate, a string-type attribute, defines the template note to be used to render the poster.

    PosterURL

    $PosterURL, a URL-type attribute specifies a URL to be displayed in the poster. The developer's expectation (assumption) is that $PosterURL will be much less common that $PosterTemplate. This is reflected in the scenario whereby if a note has values for both $PosterTemplates and $PosterURL, the $PosterURL is ignored in favour of $PosterTemplate.

    PosterCSS

    $PosterCSS, a string, contains additional style rules that will be applied to a poster. $PosterCSS is used for supplying actual rules. This can be useful when restyling a web site's content for use as a poster.

    PosterX, PosterY, PosterLabels, and PosterSettings

    $PosterX, $PosterY, and $PosterLabels are list-type attributes whilst $PosterSettings is a string-type attribute. Any/all of these may be useful for passing information into a visualisation tool, depending on the needs/complexity of the tool in use. As with sandbox attributes like $MyList, these attributes have no special significance to Tinderbox.

    $PosterX and $PosterY will typically be used to supply a list of X and Y values for a poster. However, not all posters need X/Y values and posters can use these attributes for whatever purposed they choose as with the other two. Tinderbox simply uses these four attributes' data as provided by the user's code.

    PosterZoom

    $PosterZoom is a numeric attribute representing the magnification applied to posters loaded through $PosterURL (but not those created via $PosterTemplate). Its default value is 1.0, representing the page’s normal size. A $PosterZoom of 0.5 would display the page at half size.

    ScreenWidth and ScreenHeight

    $ScreenWidth and $ScreenHeight are read-only attributes that reflect the pixel width and height of the poster at the current view magnification. Knowing these values can be useful for fine-tuning inputs to set the size of the (poster) visualisation, if it allows such an option.

    Creating new posters

    Importantly, the user is responsible for understanding how the visualisation works and is configured. Tinderbox is merely providing a means to display a correctly configured visualisation within a Tinderbox map view.

    If making a poster from scratch, as a opposed to adding new data to a pre-made poster, there are some points to consider:

    • A poster is essentially a webpage shown as the (face) content of note's map view icon. Therefore making a functioning web page version of the poster and validating its use before making a poster of the page is an necessary step. Why? This will:
      • allow de-bugging of the web page functionality before use as a poster. If the page doesn't work in a web browser, it will not work in a poster. It is worth making local copy of the page and validating ti to ensure any calls to CSS, JS, etc. do not break. The HTML calls to the latter might need to be updated to call directly to the Web via a full URL rather than assuming a local relative path (such as exisis on the original web server).
      • identify any libraries, e.g. JavaScript files, with unexpected further dependencies. As long as the host Mac has internet access a poster, like any web page, can user resources such a JavaScript libraries that are read 'live' from the Web.
      • identify how the page draws its data and the form of that data. Beware focussing on the visual (surface) alone. Work may be required to ensure the host TBX has suitable content to proved the poster's needed data.
    • If copying from an existing example, make the simplest version of the page as will run locally. Avoid unneeded extra dependencies, e.g. CSS or JS not actually used by the live
    • $PosterTemplate is independent of the note's $HTMLExportTemplate. The former affects only the in-app poster, the latter the export of the note. Thus a note can still export even if it has a poster.
      • For debugging, it may be handy to set the $HTMLExportTemplate (temporarily) to be the same as the poster template. Doing this enables use of the Text/Export pane to review and correct the HTML being passed to the poster.
    • Generally, set the template such that the plot area fills the entire page )i.e. the whole poster)
    • A likely problem on first use is the appearance of unwanted <p> elements in the middle of Tinderbox data, e.g. ^text^ passed into the poster's Javascript code. Do not forget to use either the built-In Poster prototype for notes using posters, or otherwise turn off paragraph markup.
    Updating posters

    Posters reload themselves:

    • when the map view is laid out
    • when the poster is selected
    • when a note scrolls into view.
    • Posters loading via $PosterURL update if $PosterCSS is changed

    Thus, changes to the poster’s data might not be reflected immediately.

    The action changed(), allows the designated note—default is the current note—to update itself, allowing a stamp to call the poster to update itself. That is useful if some calculation needs to be done before the poster is displayed.

    Changing the $PosterURL or the $PosterTemplate of a poster immediately redraws the poster.

    Posters and performance

    Posters in general do not pose an issue, but there are two aspects of use of which to be aware

    • some visualisations may either/both use a lot of computational effort or call on very large datasets. Tinderbox can use lots of processing power; a more likely limit may occur in terms of the overall CPU power/RAM of the host Mac and the demands of other currently running programs.
    • posters can make significant demands inside the map view, which is already quite demanding. Some performance optimisations are already in place, but it may be good to understand them. If a note is well off-screen, i.e. outside the currently visible area of the map, it loses its poster (i.e. the poster is not calculated/drawn) and regains the poster only as the note approaches the viewport (i.e. so it is drawn ready when the poster note is scrolled into view).
    • any visible poster is refreshed when the map is laid out or refreshed.
    • to reload a poster, click the tab label area of the current tab, which asks Tinderbox to re-draw the current map. Additionally, if a poster is asked to reload its data, it will wait a minimum of five seconds from the most recent reload—this avoids unnecessary re-calculation due to rapid multiple clicks, e.g. double-clicking the tab rather than single-clicking it.

    In summary, when planning poster use consider both the effect of each individual poster and the number of posters in use within a map—or at least the number visible on screen at the same time.

    Re-arrangeable Agent Maps

    By default, a map of an agent cannot be re-arranged. This is because at each agent update cycle, the aliases are refreshed adding/deleting aliases as their originals match, or cease to match, the agent query.

    However, if the agent is turned off ($AgentPriority or Action Inspector Query sub-tab or Get Info agent tab.) It is possible to then manipulate the map's contents. When 'off' the agent ceases updating but it still retains its contents from the last active agent cycle. If the agent is turned on again, the map is re-arranged to the normal agent-organised layout.

    Maps within an active agent can be rearranged by the user, which attempts to get around the above problem. Note that this flexibility applies to the agent-created aliases on the map; the user cannot add additional items. If the user deletes an alias it will be re-created next agent cycle. Also, like normal aliases, it is not possible for the agent's aliases to contain other notes so no nesting is possible.

    The feature is controlled by the agent's $CleanupAction. In the default mode, the agent's contents in map view will be organised in a grid, as was previously the case (see above); the order of items in the grid being set again, as before, via the sort attributes for the agent container. A number of cleanup layouts are supported (seen in the Cleanup Action pop-up list), with items being ordered via outline order ($OutlineOrder) unless the parent container has no sort ($Sort) set:

    • grid (default). Aliases are arranged in a grid layout, left-right/top-bottom in sibling order.
    • row. Aliases are arranged in a single row, left-right in sibling order.
    • column. Aliases are arranged in a single column, top-bottom in sibling order.
    • box. Aliases are arranged in a an open box (square) arrangement, clock-wise in sibling order from top-left.
    • none. Auto-layout is suspended, the user is free to arrange the items within the agent containers as they would any other map. Whilst in this freeform mode the normal Map view Cleanup pop-up menu items may also be used. In "none" mode Tinderbox adds new aliases to the agent map by the logic used for a normal map so it should avoid overlapping/hidden icons, etc.

    Changing the Clean-up order

    By default, items are arranged ordered via outline order ($OutlineOrder) unless the parent container has no sort ($Sort) set. If a sort is set, the items are listed in ascending sort order. This will vary by data type e.g. number-type: lowest first, date-type: earliest first). This can be reversed by setting the $SortBackward attribute or ticking the 'reverse' box on the Sort Inspector.

    Adornments

    User-added adornments are allowed in agent maps—an exception to the only aliases forming the child objects of an agent. If the agent sort is enabled, i.e. $CleanupAction is "grid", this trumps the effect of smart adornments; smart adornments themselves ignore $CleanupAction completely. Adornments can be dragged or pasted into agent maps.

    If an adornment is added inside an agent, the agent's $CleanupAction is set to "none".

    Agents

    Agents do not force a default cleanup on file load. Thus agent maps using "none" correctly maintain their layout across different sessions.

    Should the agent be re-enabled, the custom icon positions will be lost as the agent rearranges the icons.

    Regardless of whether an agent is enabled it is always possible to link to/from aliases on the map of the agent's contents.

    Scrolling newly opened maps

    Container maps record their map scroll position in two attributes, $MapScrollX and $MapScrollY. (Very early versions automatically scrolled new map views to place the first child in view.)

    These co-ordinates are floating-point numbers, and use the same relative co-ordinates as $Xpos and $Ypos. If a map view of a note is closed and later reopened, it will scroll to that map's most recently viewed position.

    The scroll position is also reflected in the interior view of a note container viewport (as before an agent's contents are fixed). For a note container, data at $MapScrollX and $MapScrollY is drawn in the vertical/horizontal centre of the container viewport.

    The viewport within a container can be moved via click-drag within the viewport area. Dragging the child map background scrolls the child map, dragging an icon moves that icon on its own map.

    Selecting a prototype in Map view

    In TBX documents with prototypes already defined, when a map icon (note, container, agent but not adornment) is selected a tab in $Color is shown bottom right of the icon. The prototype tab is shown regardless of whether any prototypes are defined, and a small triangle indicates that the tab may be clicked to reveal a menu. In older versions, the prototype tab was not drawn on (selected) Map icons if no prototypes were defined in the document.

    If a prototype is set for the currently selected note, the tab shows the prototype name or else the tab is blank. Map adornments do not show a prototype tab when selected.

    For a selected note click-holding or right-clicking on the icon's prototype tab gives a pop-up list of all prototypes available in the current TBX allowing the user to set, change or clear the note's $Prototype value. Such a menu is only displayed if there are prototypes defined in the TBX. Setting a prototype on an alias sets the original note's Prototype value.

    If multiple notes are selected, using the above method on any one of the selected items' prototype tab will result in all items changing their prototype assignments.

    This is just one method of setting a note's prototype.

    The text colour used in prototype tabs is normally the background colour of the map ($MapBackgroundColor). This usually works well, but can be difficult to read in low-contrast colour schemes where the note colour is close to the background colour. In the latter scenario, if the two colours have similar luma, Tinderbox instead chooses either black or white for the prototype tab text.

    Stacking and overlapping items

    When two map note items overlap, the item with the lower $OutlineOrder value will stack on top of the other item and obscure it (unless note transparency is used).

    Adornments follow the same principle between adornments but all adornments are drawn behind all notes/containers on the map.

    If working in map view and the order of items in outline view is not important, the Note menu offers a number of functions (all with shortcuts too) to alter the $OutlineOrder of a not so as to affect its stacking order:

    • Move to Front. Sets $OutlineOrder lower than any other note/container on the map.
    • Move Note Up. Sets $OutlineOrder one number lower.
    • Move Note Down. Sets $OutlineOrder one number higher.
    • Send To Back. Sets $OutlineOrder higher than any other note/container on the map.

    N.B. $OutlineOrder is read-only. The user cannot make the above adjustments using action code directly on $OutlineOrder.

    Also see a more detailed discussion of Outline vs. Map view for further discussion of stacking.

    Map Settings pop-over

    This is the configuration pop-up for the current Map view:

    • Color. Colour controls to set the parent object's $MapBackgroundColor.
    • Pattern. Uses Pattern pop-up to set the parent object's $MapBackgroundPattern.
    • Accent. Colour controls to set the parent object's $MapBackgroundAccentColor.
    • Fill. Uses Fills pop-up menu to set the parent object's $MapBackgroundFill.
    • Opacity. Slider control to set the parent object's $MapBackgroundFillOpacity.
    • Hide breadcrumbs. Toggles view's breadcrumb bar (default: un-ticked).
    • Display Link Stubs. Toggles the visibility of link stubs (default: ticked)
    • Animate Links. Toggles link animation of outbound links of the selected note(s).
    • Hide link controls. Toggles the visibility of link configuration controls (default: un-ticked).
    • Use Inherited Settings. A button to reset all the above attributes to current document's default values.
    • Save Settings As Default. A button to set all the above attributes as the current document's default values.

    Outline view

    [First introduced in v1.0.0]

    An outline view shows the hierarchical structure of the entire document as an outline. An outline is useful for seeing many notes in one window. It is easy to restructure the hierarchy of the document in an outline window, by dragging parts of the hierarchy to other parts of the hierarchy. It is generally the most useful view to use when laying out notes for export.

    Containers (and agents), notes containing other notes, can be expanded or collapsed to show child notes (and there are shortcuts to assist with this).

    Note titles can be double-clicked and edited in situ. Use Return [↩] to close the edit, or click off the edited note: use Escape [⎋] to abandon an edit. Long titles will wrap to a second line.

    Using the Tab (⇥) key with or immediately after the Return (↩) key will result in a new, indented, 'untitled' note.

    As with a normal new note, the indented note is presented with the note's title in edit mode.

    An indented (i.e. child note, can be promoted as sibling of its parent (as next item in outline order) using Shift+Tab (Tab). It is not possible to outdent the parent note of a hoisted outline (as some early releases allowed). If the hoisted parent note is selected, ⇧Tab is ignored.

    The right-arrow key (→) expands the selected note

    The left-arrow key (←) collapses the selected note if it is expanded. If not, it selects the parent of the selected note if the parent is visible in the view.

    Note icons

    Notes and containers have icons which illustrate:

    • the degree of content (i.e. amount of $Text)
    • the type of note, e.g. note/alias/agent
    • the age of the content (time since $Text or Displayed Attributes were last $Modified)
    • the presence of in- or out-bound links: see below
    • the note's colour ($Color). Like the note title, the icon is drawn in $Color

    Note title

    The icon and the note title ($Name) are drawn in the objects' $Color attribute (i.e. the face colour of the object's map view icon. The font used in $NameFont and the title size can be varied using $OutlineNameSize.

    To help with legibility, there is also a 'Darker colors' option in The Outlines tab in Document Settings that, as it implies, slightly darkens the colours used in the Outline view from their defined $Color value. The feature is 'on' by default, but is best turned off if using Outline as the main working view and using a wide range of colours for $Color.

    Separators add the ability to delimit sets of sibling notes and are not drawn in Map and Chart views. In the outline they are similar, in a visual sense, organiser device in the way adornments are used in a map (and only seen in a map view).

    Links

    An outline view does not show any link lines (such as are seen in a map), but the note icon will show an inbound and/or outbound stub link if the note has one or more such links in the given direction; web links count as outbound links.

    The icon symbol does now show an outbound link if the note has only Web links.

    Untitled notes (within Outline views) are not auto-deleted if they have outbound links, or if they have inbound links other than prototype links.

    Other features

    Outline view can be enhanced by the optional display of item checkboxes and column display of attribute data. Here is a list of other features:

    In outlines:

    • the right-arrow key (→) expands the selected note
    • the left-arrow key (←) collapses the selected note if it is expanded. If not, it selects the parent of the selected note if the parent is visible in the view.

    Auto-scrolling:

    • View ▸ Arrange ▸ Move Note Up (⌘-↑) and View ▸ Arrange ▸ Move Note Down (⌘-↓) now scroll the view pane if necessary to ensure that the moved note remains visible.
    • If you use the arrow keys, fn+arrow keys, or create a note that is not visible in the window, Tinderbox scrolls the view pane to make the selected note visible.
    Outline Settings pop-over

    This is the configuration pop-up for the current Outline view:

    Altering Scope of Outline views

    Just as in a Map view it is possible to alter the focus (scope) of an Outline view. By default, a new TBX opens as an Outline view with every note in scope (even if folded away from view within a container).

    Note: the commands here can also be applied to Treemap and Chart views. Map views have a few slight navigational differences.

    Can I have an outline of just a part of my document?

    Yes. Select the note to take focus and View menu ▸ Focus view (⌘+⇧+↓). If you'd prefer the new outline to be a separate window, instead use View menu ▸ Tab sub-menu ▸ New tab to make a new tab. This new tab opens in the current view (which will thus be another outline).

    Can I shift focus up/down one container level, as with a map?

    Yes. To move up a level there are 2 methods:

    • View menu ▸ Expand View (⌘+⇧+↑).
    • Click the parent container of the desired new scope in the breadcrumb bar.

    To move ('drill') down, there is one option only. Select the note to act as the new focus, then use View menu ▸ Focus view (⌘+⇧+↓)f you use the opposite shortcut to that for Expand View (i.e. 'drill down' shortcut) is merely expands the current container in the view without shifting focus. This makes sense as there may be more than one child container and via the shortcut Tinderbox has no way to tell which sub-container is the users desired new focus.

    How do I quickly get back to whole-document outline focus?

    • Click the left-most segment of the view pane breadcrumb bar.
    • Use View menu ▸ Expand view (⌘+⇧+↑) repeatedly until at root level (view does not change focus).

    How can I tell if my current outline view has whole-document focus?

    The view pane breadcrumb bar is not displayed. Below root level is shows the ancestor containers of the current scope.

    Checkboxes

    Outline views have a (non-default) option to display check-boxes for each item. This is enabled via the View menu. There is no document level preference for this setting as each discrete Outline view window has its own checkbox visibility state. Ticked boxes show a red-coloured tick.

    Checkboxes are drawn to the immediate left of a note's icon, at the indentation level of note, i.e. the boxes are not drawn in a single vertical column but rather follow the indenting of the outline.

    The ticked/un-ticked state of a box is stored in the Boolean the system attribute 'Checked'. The action of changing the tick state of the box via code or the UI has no direct effect other than that which is seen. However, Tinderbox code can be used to test and act on the $Checked values of notes.

    XML setting: usingCheckboxes.

    Colour Swatches

    Legacy use

    Swatches are discontinued in favour of showing the first (if any) of a notes defined flags ($Flags), as described here. Swatches can not be used in current Tinderbox. This feature and its associated system attribute are now essentially non-functional.

    Outlines can show a square colour swatch, including border and pattern information, in the area reserved for the link widget between the note's icon and its badge. Because of the swatch's positioning, when a note with a swatch is selected, the link widget temporarily replaces the swatch.

    The main aim of this feature is to allow the display of progress using the 'bar' and 'vbar' patterns that display a progress bar in map note icons.

    Swatches are activated via the $OutlineColorSwatch attribute.

    This feature can be toggled on/off via the Appearance Inspector's Outline tab.

    Coloured Backgrounds and Selections

    Outline items can have a solid coloured background. The attribute $OutlineBackgroundColor lets the user specify a colour (named colour or hex value). The colour then forms the background colour of that note's listing in Outline view; it does not run full width (rather like Finder item colouring) but does include check-boxes and column display if those features are turned on.

    Outline layout has been revised to use $Color more attractively. If a note uses a $Color other than the document's default colour, the entire area of the note is tinted translucently with that colour. $OutlineBackgroundColor to tint the background behind the note. The tint is also varied in opacity so the degree of colour decreases from top to bottom of the selection highlight.

    A selected item focus highlight uses a tint of $Color. The highlight is drawn on top of the outline background colour if any. These aspects are shown in the image where the first two and last items are selected.

    The image also shows that thought needs to be given to contrast between $Color and $OutlineBackgroundColor or titles may become hard to read.

    In documents that use 'Darker colors' in outlines, the selection highlight also uses the darkened colour.

    To help identify selected item(s), a selected item's highlight has a solid vertical bar of the tint colour of the highlight $OutlineBackgroundColor.

    Column view: displaying and editing column data

    Outline views have a (non-default) option to display user-chosen attribute data in columns to the right of the note titles. This feature is enabled via the View menu. There is no document level preference for this setting as each discrete Outline view has its own column visibility state. As with $Name, any editable attribute value can be edited via Edit-in-Place.

    Column data is drawn in the source note's $Color, and the current row of data is highlighted (as with the actual note title). With Edit-inPlace turned on (the default) column data—for any non read-only (i.e. most) attributes—can be edited in place. As with the normal note title edit, click and hold to enter edit mode.

    When the columns option is turned on, a column header row is displayed. At the left end are two controls:

    • 'X' button. This turns off column view (the View menu can do the same). Any currently defined columns are remembered.
    • '+' button. This adds a new column, to the right of any existing columns. The default name is 'Attribute'; as this is not a valid attribute name no data is displayed.

    To configure a column, click on the column head for the appropriate column and use the column format pop-up. The pop-up also allows a given column to be deleted. A deliberate exception to attribute type-based formatting is $ID which is presented as a string of numbers (its normal use).

    Deleting a column has no effect on the data it was displaying. There is no set limit to the number of columns that can be displayed. The view will support columns displayed off-screen in which case the view pane will show a horizontal scroll bar. If all columns are deleted, Column view is turned off.

    Separators still draw normally and therefore do not display column data.

    Adding more columns will shrink the width of existing columns rather than grow the view window. Dragging the view window wider after adding columns does not re-expand the columns, so if planning to use multiple columns it is a good idea to re-size the view window first.

    Each tab with an Outline view will remember the columns used (such data is stored per view). Customisation details are stored internally in the TBX file. Any tab showing Outline view with columns that is open when a TBX is saved & closed will be remembered and restored when the file is next opened.

    Column widths may also be altered by manually dragging the right-side divider bar of the column's header. The left-right order of columns can be altered by clicking on a column heading (away from its edges) and dragging left or right. There are some limitations to column manipulation. Column data does not wrap if wider than the current column, the data is simply only shown in part (with nothing to indicate more text).

    Boolean attributes are displayed as tick-boxes.

    Double-clicking a displayed column value allows a value to be edited (or entered into a blank 'cell'). If editing a value in an outline column, clicking inside the edit field places the insertion point is placed appropriately.

    When a selection is copied, displayed columns values are copied in addition to the title and text in tab-delimited form to assist with export.

    XML settings: showColumns, columnString.

    Copying column view data as tabular data

    When copying from an outline view with columns, Tinderbox copies all the column data in tabular form. This allows easy and simple sharing with spreadsheets and other programs that use tab-separated values.

    To copy just note titles, turn off column view, copy items and re-enable column view.

    Double-clicking Outline background

    Double-clicking an Outline view background creates a new note at the end of the outline, even when a title is in edit. This makes it easy to set up new separators.

    Drag re-arranging notes in Outline view

    A note, or selection of notes, can be re-arranged in Outline view by dragging the selection to the desired location. Keeping the cursor over the right part of other note names in the view, the user will see a green rule between existing notes indicating where the dropped item will be placed. The degree of indentation to the left edge of the rule will indicate where in the hierarchy the dropped note will be placed (i.e. as a sibling or a child of the note above it).

    Note that dragging a hierarchical selection will flatten it at point of re-insertion in the outline; the selection collapses into outline order sequence.

    Dragging note(s) will alter their $OutlineOrder and other outline-position related attributes.

    Editing note titles in Outline view

    When editing a note name in outline view certain key inputs and input cursor positions offer additional features.

    Note: focus must be in the view pane. Editing the selected note's title in the text pane does not invoke the behaviours below.

    Delete key + input cursor at start of title

    Note: here the delete key implies only backwards delete key, i.e. the backspace key (⌫). The forwards delete key (⌦) does not invoke this behaviour.

    If the current input cursor position at the start of a note, delete merges the note with the preceding note in the outline. The title of this note is appended to its predecessor (space-padded), and its text ($Text) is appended to the text of its predecessor (adding a line break if necessary).

    If there is no previous item in view, the note is deleted as normal (i.e. deleting when not in title edit mode).

    If the insertion point at the start of the note and no title text is selected, the key functions normally.

    If the forwards delete key (⌦) is used the character to the right of the insertion point is deleted. In this context, this is likely the first character of the existing title—i.e. not what was intended.

    Return key + input cursor anywhere title

    Pressing Return (↩) exits the edit, leaving focus on the current note.

    From v11.0.0, the previous method of splitting the note title to make a new note has been removed.

    A note can still be split from within $Text, i.e. with focus in the Text pane and the cursor in the $Text area. This feature is accessed from the Note menu.

    Down-arrow key + input cursor at end of title

    If the current selection is at the end of the title, down-arrow key (↓) completes the editing session, selects the next (visible) note in the outline, and puts its title in edit mode with the whole title selected.

    If the down-arrow key (↓) is used either with a selection within the title or if the selection point is not at the start, the insertion point moves to the start of the title. A second press of the down-arrow key (↓) invokes the above behaviour.

    Up-arrow key + input cursor at start of title

    If the current selection is at the start of the title, up-arrow key (↑) completes the editing session, selects the previous (visible) note in the outline, and puts its title in edit mode with the whole title selected.

    If the up-arrow key (↑ is used either with a selection within the title or if the selection point is not at the start, the insertion point moves to the start of the title. A second press of the up-arrow key (↑) invokes the above behaviour.

    Flags in outlines

    In place of seldom-used colour swatches, outlines can instead draw the first (only) element from $Flags to the right of the outline icon of notes that are not selected and have a value for $Flags.

    When a note with flags is selected, the flag is replaced by the link widget.

    The syntax for setting flags, and the styles available are described in detail under their use as note flags in map view.

    Horizontal scolling

    If Outline column view uses more columns than can be displayed within the current width of the view pane, the view can be scrolled horizontally.

    Note: whilst this allows more columns to be displayed care should be taken not to overload the view by displaying very large numbers of columns. There is not limit, but if the view becomes sluggish it may indicate that it is sensible to remove a few columns from the view.

    Note icons and controls in Outline view

    Outline, and some other views such as Chart and Attribute Browser, show an icon to the left of the selected note.

    There are a number of easily observed differences:

    • $Text content. If the note, or agent, has any text content ($Text) the icon is taller. In addition, lines inside the box indicate the amount of content (see more detail here).
    • Note vs agent. If the object is an agent, the thicker bar is at the bottom, as with Map view container title position. For notes and container notes, the thinker bar is at the top. Again this accords with Map view container styling.
    • Item vs. container. If an item in the outline has has child notes, it shows a 'disclosure triangle'. Clicking on that latter expands/collapses the container's contents. Agents also use a 'disclosure triangle', if they have any matches. As an agent can only contain aliases (whose titles are in italics), an agent container only has children. By comparison, as illustrated, a normal container can contain other containers—i.e. further descendants.
      • Clicking a disclosure triable does not affect the current selection. This allows investigation of an outline without losing the current (selected) context.
      • Nested containers can be expanded and collapsed separately from each other. Containers store their own last expansion state, regardless of whether they are currently within collapsed containers higher in outline level. thus if the shown 'A container note' collapsed, 'A child note' still knows its own container should be expanded if its parent is re-expanded.
    • Links. If a note has either or both inbound and outbound links, that is indicated by stub arrows. One or more inbound links result in right-pointing arrow on the left side of the icon. One or more such outbound links result in a right-pointing arrow on the right of the icon
    • Link widget (selected item only). Clicking this and dragging to another note or a link parking space creates a basic link.
    • Badges. An optional badge ($Badge) is displayed if set. For selected items with no badge set a plus sign in a circle is displayed. Clicking this opens the Badge picker pop-over.
    • Separators (outline only). These never show an icon, link widget or badge, regardless of selection state.
    Outline filter

    Outline view can be filtered using a query, as defined via the filter toolbar. Shortcut: +++F). This allows dynamic examination of a query-based subset of the container's notes, temporarily simplifying the view.

    XML setting.

    Selecting Prototype via Outline icon

    Right-clicking on a note's icon in outline views opens a pop-up menu for selecting a prototype for the note (setting the note's $Prototype). Such a menu is only displayed if there are prototypes defined in the TBX.

    If multiple notes are selected, using this method on any one item will update the prototype assignment of the whole selection (including any separators.

    Although separators have no visible note icon, right-clicking a selected separator at the left-most end, where the icon would otherwise be, will show the prototype pop-up menu.

    Setting a prototype on an alias sets the original note's Prototype value.

    This method also works in Chart, Attribute Browser and Timeline views.

    This is just one method for setting a note's prototype.

    Separators

    A note may be designated as a separator. A separator is drawn in outline view as a horizontal line. The note's name, if any, is shown centred in a box-out in the middle of the separator line. If the note has no Name value or it is "untitled' the separator shows as a solid line. For separators no duplicate name warning is given if the Name value is left blank. A note's status as a separator is held in $IsSeparator.

    Just as adornments are only visible in Map view, separators are only shown as separators in Outline view (and exceptionally in Treemaps). However, in all other views except Map view, a separator is visible as if a normal note. By the same token children of a separator are hidden in Map view, as their parent container is not drawn on the map. The latter can be a useful way to 'hide' content, either notes or containers, in a map without removing the content from the overall document.

    Note that separators were not originally designed to be able to be containers but rather like a (non-smart) adornment for separating groups of siblings in outline views. However, they can be containers; even agents may be a separator. Because of their possible container role, treemap views always show separators (as if they are normal notes). No note icon is shown for a separator note so the age/level of content/age cannot be judged although the separator is a fully functional note. In major views other than Outline and Map views, a separator is shown as a normal note.

    A separator can still have normal note features like a Rule and OnAdd action and become a container by having notes added to it.

    If data columns are enabled for the Outline view, separators still draw normally. Thus the data columns are not displayed for separator notes, unlike all other items in the outline.

    Even if not needed as a separator for Outline purposes, making a Map item into a separator can be a way of hiding it (temporarily) from Map view; note that when hidden like this it cannot be selected from the Map either. To make the item visible to the map it is necessary to find and select it in a view other than map and remove the separator status.

    Separators, but not adornments, are included in $SiblingOrder wheres both are included in $OutlineOrder. This makes sense when considering export is where SiblingOrder values are most regularly used and where adornments do not appear. See more on separators in a map vs. outline context.

    A separator can have inbound and outbound links. It can also have note text; in such cases Treemap views will show a 'dogear' symbol denoting text content.

    To designate a note as a separator, check the Separator checkbox in the Prototype sub-tab of the Properties Inspector set the value of $IsSeparator to true.

    Separator notes default to exporting as HTML (only) if either:

    • they contain both a title and have note text (i.e. have $Name and $Text values)

    …OR…

    • they contain child notes

    If exporting Separator notes with no text (i.e. with children) ensure either the template will link through to the child content or add a ^childLinks^ into the $Text of the separator note.

    Making a note into a separator does not alter any of its font-size related attributes but when drawing an outline view Tinderbox draws separator titles very slightly smaller than for normal notes. Likely this is done so as not to expand line height, i.e. allowing for the box around the separator title. This effect is more noticeable as zoom level is decreased.

    Duplicated separators retain their original name rather than receive the name suffix " copy" making it easier to clone unnamed separators.

    Separators do not appear in hyperbolic view or in the attribute browser.

    Table view

    [First introduced in v9.7.0]

    Table view allows the children of a container note—or the aliases of an agent—can be viewed in tabular form. Part of the design intent is:

    • People today use spreadsheets to make simple lists and tables. It can be nice to make it easier to go back and forth between Tinderbox and spreadsheets. Importing from spreadsheets is already possible. However, tabular export involves engaging with export templates, which some find too complex or abstract.
    • Outline with columns is useful, but it can be slow for large containers (with 000s of notes) as the outline needs to measure the height of each item whenever the layout is updated: Table view involves less work for Tinderbox. This can be especially helpful when browsing and cleaning imported data.
    • Table view is another way to examine agents, especially when key material is in attribute rather than the $Name or $Text.

    A Table view is opened by selecting a container and then choosing View Table from the main menu. Alternatively, use the pop-up menu for the current tab's label or the app toolbar. The selected container's XML setting: tableParent.

    Altering Displayed Attributes for the selected row item updates the relevant Table view cell.

    From v11.0.1, the font size used for the view can be altered, via the views's Settings pop-up

    What the table shows

    The Table view shows (only) the immediate children of the selected note. If the selected note has no children, the table shows the selected note and its siblings. If there is no selected note, the table shows the children of the parent of the current view.

    Fields in Table View offer their entire text as a tooltip, which is useful if the text is significantly longer than the available width.

    See also:

    Table Settings pop-over

    This is the configuration pop-up for the current Table view:

    • Font Size: 12pt (default) / 16pt / 24pt. The font size in points, used for drawing the Table view's contents. XML setting: tablefontsize.
    Table rows

    Each line in the table represents one note. Initially, all items are shown but Adornments, Separators, and notes with $TableHidden set to true are omitted. The view displays each included note on one line, i.e. a note per row.

    Right-click the left column, or in any row, to apply styles to rows: see the menu article for how the current selection affects the outcome of the menu options. Right-clicking a row does not select that note or alter the existing row selection.

    A selected row shows its corresponding note in the text pane: selecting multiple rows selects all the corresponding notes. For multiple selections, the text pane shows the title+text of all the selected notes. Deselecting all rows now correctly deselects all notes.

    Stamping a selection applies to stamp to every note in the selection.

    Blind typing in the table will select the next row containing the typed text.

    Copying rows: Copy ( +C) copies the selected rows of the table. If no rows are selected, it copies the entire table.

    In this view, the Delete (Backspace) deletes the row, i.e. its source note.

    Table columns

    The left-most part of the table is actually labels and not a column as such. It shows the number of each row: the column's rows number from 1. The lozenge in which the row number appears is sufficiently wide to allow for four digits. These labels cannot be edited. It is there to help when working on the tables's data to give a quick visual reference to that row. A right-click (or +click) the column header opens a pop-over to edit the list of columns or to apply styles to the column.

    The first actual data column is always the note's title ($Name). Essentially, column #1 is fixed, in terms of content.

    By default, a new table view shows the labels and 3 columns: the fixed $Name columns (and) and 2 data columns for ($SubTitle and $Created). If the container has any Displayed Attributes these are used as the views defaults. Also, if the container's $TableAttributes has a value, the listed attributes are used to populates column #2, etc.

    Table view expects a minimum of 2 columns: the $Name data and one or more user-definable column(s). Unlike other user-defined columns, #2's source attribute can be changed, but the column itself cannot be deleted. Columns #3 and above can both have their source changed and be deleted.

    Tables may be sorted using a chosen column. Left click on a column header to sort by that attribute; left click again to reverse the sort direction. Sort order for a column depends on the attribute type; numbers are sorted numerically, strings are sorted lexically. Sorting on a column affects the patent container's $Sort.

    Dragging a column header left or right change the order of the columns.

    The alignment of column headers follows the alignment of the column.

    Table cells

    The content of table cells—except for the left-most row number column—can be edited. Either click-hold on the cell or right click it. In edit mode a discrete context menu is shown.

    Blind typing in the table will select the next row containing the typed text.

    The tooltip for table view cells is the full text of the information, which might not be fully visible in the cell.

    Exporting Table View data

    See Copy in the Table view's Row context menu for more detail.

    A choice of export format is offered: CSV, tab-delimited, Markdown and HTML.

    Table view configuration

    The format of each cell (element) in the table is determined the dictionary attribute $TableFormat. Special formatting may be applied to rows or columns (but not, at present, to individual cells).

    Most people will not need to change the table format in an action. $TableFormat is a deeply nested dictionary, which makes changes in actions a bit tricky. Still, it can be done, and this avoids the need to create perhaps a dozen additional attributes.

    Note that the column/row

    The definable keys in $TableFormat are:

    • TextColor. The colour used to draw the text. The default is the system text colour.
    • BackgroundColor. The background colour of the table, row or column. The default is the system text background colour.
    • Font. The font used to draw the text. The default is the system font. This cannot be altered via the variable's context menus.
    • Align. One of "left", "center", or "right". The default is left.
    • Bold. Either true or false. The default is false.
    • ColumnWidth. The width of the column, in pixels.
    • RowHeight. The height of the row, in pixels.
    • Format. Special formatting to be applied to numbers or dates.
    • Column. A dictionary describing formats to be applied to a column, in which keys are attributes and values are dictionaries of formats.
    • Row. A dictionary describing formats to be applied to a row, in which keys are IDs and values are dictionaries of formats.

    Examples of $TableFormat code

    A customised Table view:

    {Column:{MyDate:{Format:t;ColumnWidth:192};Badge:{Bold:true;ColumnWidth:146.5};Name:{ColumnWidth:100};MyNumber:{Format:$}};Row:{tbx_Ble4Lq:{BackgroundColor:yellow};tbx_Ble4Lp:{TextColor:bright red}}} 

    This can be read more easily as:

    {
      Column:{
        MyDate:{Format:t;ColumnWidth:192};
        Badge:{Bold:true;ColumnWidth:146.5};
        Name:{ColumnWidth:100};
        MyNumber:{Format:$}
      };
      Row:{
        tbx_Ble4Lq:{BackgroundColor:yellow};
        tbx_Ble4Lp:{TextColor:bright red}
      }
    }

    The overall dictionary contains one or two (either/both Column or/and Row) objects. The Column has an item for each customised column, with the column attribute's name as the key and a dictionary of customised settings. For the Row, only customised rows are recorded. The per-row key is the row's $IDString and the value is a dictionary of customised features.

    Timeline view

    [First introduced in v5.6.0]

    Timeline view displays the notes inside a container as a horizontal timeline. Each note is positioned along the timeline based on its $StartDate. The note's width is based on the value of $EndDate, if specified. There is limited support for negative (BCE) dates.

    Most of the configuration controls for the view's controlling attributes are accessible via the Timeline Settings pop-up. This can be accessed from the 'i' icon on the tab's label or via the 'Change settings' in the view's context menu.

    Double-clicking in the timeline creates a new note. The note will automatically be assigned a StartDate corresponding to the timeline date of the clicked location.

    Events may be assigned to distinct horizontal bands in the timeline. For example, one band might describe political developments and a second might describe artistic landmarks, or one band might specify development milestones while another would involve documentation or marketing. The band for an event is specified by the attribute $TimelineBand; notes may be dragged between bands which will reset the attribute accordingly. Dragging a note beneath the bottom-most band creates a new band; empty bands are automatically deleted or not drawn if higher-numbered bands exists (i.e. only bands with data are drawn).

    If notes have no start date, they do not appear in the timeline. Instead, they appear in a section labelled "No Date" to the left of the timeline. If notes do have a date, but that date lies outside the boundaries of the timeline, they appear in a section labelled "Out of Range" to the left of the timeline.

    Labels for each band are taken from the container's attribute $TimelineBandLabels, a semicolon-delimited string. For example, the string "Paris;London;Madrid" would label three bands, "Paris", "London", and "Madrid".

    Resizing or moving events in the timeline will change their start and/or end dates.

    Links can be dragged, from the selected note, in the view pane via the link widget drawn to the right of the selected note's title.

    Opening a timeline on a note with no children opens that note's container as this is the more likely intent.

    More detail on the Timeline view:

    Adding, deleting or moving events

    Timeline view is not a 'view-only' format. Items shown in the main panel or either of the sidebars (no date, out of range) can be editing and items either added or deleted.

    To edit a note (or notes) simply select the item(s). This becomes the scope of the Inspector, quickstamp, stamps, and all other controls and populates the text pane.

    Dragging a note horizontally within the view pane will update the $StartDate (and $EndDate if one) according to the moved-to position.

    Dragging the event's title wider than the default width will alter the duration by updating $EndDate. If no $EndDate was set previously, an appropriate $EndDate will get added and set.

    Dragging an event vertically, will move it to a new timeline band (if present) or dragging to the bottom of the current view will create a new band. Note that bands use alternate colour backgrounds to make them easier to tell apart.

    Dragging an event vertically within a band is not possible. To alter the listing order, open an outline view.

    Shift-dragging vertically will ensure the $StartDate does not change, e.g. whilst moving a note into a new band.

    Deleting a selected note in the timeline, deletes as normal, i.e. from the TBX and not just the current view.

    See dragging undated and out-of-scope items to/from the timeline.

    Alternative Date attributes

    Sometimes a note may hold significant dates in Date-type attributes other than $StartDate and $EndDate, or may thus may store several pairs of dates.

    It is possible to specify an alternate pair of Date-type attributes for plotting timeline events, instead of using the default $StartDate and $EndDate. The desired start and end attribute names are specified via $TimelineStart and $TimelineEnd.

    Colouring the Timeline's view pane

    The main background colour is $MapBackgroundColor, whilst alternate even-numbered timeline bands, where present, will use tints of $TimelineColor. Vertical grid lines indicating major time periods (varies by scale in use) are shown in $TimelineGridColor. If used, timeline band labels are coloured automatically using tints of $TimelineColor for all odd-numbered bands. The even numbered bands (including band zero) use $MapBackgroundColor.

    Dragging event notes

    Dragging an event within a Timeline view changes the $StartDate to the reflect the date indicated by the new; if $EndDate was also set, that too will update, i.e. the whole duration will move. This effect applies to selections of notes as well as individual notes.

    Notes can be dragged from/to the "NO DATE" sidebar. Dragging onto the main timeline sets both $StartDate and $EndDate to the same data/time; dragging to the sidebar sets both to 'never'. However, be aware that the "NO DATE" sidebar is only shown if there are any descendant notes with no $StartDate value.

    Notes can be dragged from, but not into, the "OUT OF RANGE" sidebar. Dragging onto the main timeline sets both $StartDate and $EndDate to the same data/time.

    Event drags are undo-able.

    Dragging note(s) between existing timeline bands will move the note(s) into that band. Holding the Shift key (⇧) down during a vertical drag will ensure dates are not changed.

    Dragging note(s) below the bottom existing timeline band will move the note(s) into that band.

    Item styling, markers & duration

    An item in the timeline is drawn with the left edge of the icon vertically above the exact date and time [sic] of the item's $StartDate. This left edge is drawn as a line in $AccentColor. Alternatively, if an item has both $StartDate and $EndDate, a duration bar, scaled to the duration between the dates is drawn along the bottom edge of the icon from the left corner, in colour $AccentColor and the upright left-edge line is omitted.

    For very expanded scales, it may be desirable to use some action code to set events with no relevant time component to a consistent time so same-day events list vertically in line.

    When item(s) are selected a 'marker' line is drawn down from the left edge of each selected item to the scale bar at the bottom of the view. This marker is drawn in a tint of $AccentColor. The $TimelineMarker boolean can be used to make marker lines persistent, i.e. even when items are not selected.

    Link visualisation.

    If the note is read-only no resize handles appear when the note is selected and the note cannot be moved.

    If an item has a $Badge it is displayed at left between the marker line and the $Name. $Name may be styled via normal attributes. The $Name text is drawn in $Color.

    The notes are drawn reflecting $Opacity.

    Items undated or outside current date range

    Items descended from the Timeline View note that have not $StartDate are placed in a column at the left side titled "NO DATE". Notes can be dragged to and from the timeline, in doing so setting or deleting their $StartDate.

    If the Timeline note has $TimelineStart and/or $TimelineEnd set then any items in scope but with dates earlier or later than these limits are placed in a separate left-side column called "OUT OF RANGE". Events can be dragged from, but not to, this column.

    These sidebar columns are only drawn if events of that type are present, otherwise they are not drawn.

    If both columns are in use, the "NO DATE" column is drawn first (furthest left).

    Within the columns, notes are placed within their respective timeline bands, if bands are in use.

    Scope of inclusion for notes

    Opening a Timeline view plots data of all descendants that have a $StartDate defined. For instance, if a container has child containers—without dates set—titled to represent years, and these contain notes with $StartDates then the view will show the events for all years whilst the year containers will be listed in the 'No Date' sidebar. This is a powerful feature as the non-plotted year containers can help with data/note management without affecting the actual timeline visualisation. If a note also has an $EndDate the note will plot as having a duration in the timeline. An event's $DueDate is not acknowledged by timelines.

    It is possible to specify different non-default Date-type attributes for plotting events in a timeline.

    It is not possible to define any other attribute than $StartDate as the inclusion criteria for the timeline, or to use numerical or other sequence data (as opposed to Date-type data).

    Items without dates are placed in a "No Date" column at the side of the view.

    Remember Tinderbox's built-in prototypes as these include an 'Event' prototype that is ideal for timeline data items.

    By default, the timeline will encompass all dates in scope but it is possible to set $TimelineStart and/or $TimelineEnd in the container note to set a specific duration within which data is displayed. If these boundaries are set, outlier data is placed in a "Out of Range" column at the left side of the view (and to the right of a 'No Date' column, if present).

    Dates with an $EndDate only or where $EndDate is before $StartDate will plot, but incorrectly, as such configurations are effectively invalid.

    By default, timelines show all descendant notes and in-scope aliases with qualifying dates. Either of these categories can be excluded via $TimelineDescendants and $TimelineAliases being set to the timeline's container note.

    Timeline adornments

    Timelines can display adornments, if the adornment has both a $StartDate and $EndDate or both dates as defined by $TimelineStart and $TimelineEnd. These adornments are in fact shared with the map view of the same container, and use their colour, border, etc., values. The 'smart' elements of any such shared adornments (querying, etc.) only work in map view and so are ignored in timeline view. Adornments in maps of child/descendant containers are not shown. Thus a given map will always show all its adornments but the timeline of the same item will only show adornments with start/end dates.

    Adornments are drawn from the top of the timeline view to the bottom of the bottom timeline band. Adornment staking order (if overlapping) is as per map view), though this can be still be adjusted in timeline view using the same controls as for map view.

    Adornments draw in their map colour (i.e. $Color) and draw vertically across all bands on top of any band colour. The width of the adornment is controlled by its start/end dates as with notes.

    Dragging a selected adornment right or left will move it and adjust $StartDate/$EndDate. Dragging the left of right drag-handle of a selected adornment allow separate adjustment of $StartDate/$EndDate.

    As the Create Adornment dialog has no way to set $StartDate or $EndDate, it is advisable to create new timeline adornments in the map view of the timeline's container, even if said map view is not used for any other purpose.

    Although the timeline view context menu allows you to add an adornment, it is better to create adornments in map view, then use their Info view to set $StartDate and $EndDate. Setting the latter will then make the adornment show in timeline view.

    Timeline bands

    By default, all events are shown in a single band. However, notes may be dragged down to create a second, or even more bands, by dragging to the bottom of the view pane area. The timeline band to which an (event) note belongs is stored in $TimelineBand, noting that bands number from zero, not 1.

    Timeline bands may have a label, drawn at left end of the band, that is stored as a list in the $TimelineBandLabels attribute of the container holding the timeline. In the simplest scenario, of a container holding event children (and not grandchildren), $TimelineBandLabels is set in the container and $TimelineBand in the children. In other words, the band labels are set in the parent or some other ancestor of the events being shown and never in the events themselves (unless an event note is itself used as a source of a timeline view. Using excessively high values for $TimelineBand (as might occur through data entry errors) may result in timeline band labels being suppressed due to the sheer number of bands to be drawn. In the latter event, query for the largest $TimelineBand value in use and adjust it if necessary.

    Bands are drawn down as far as the lowest with data or lowest named label defined. Empty bands are drawn at a fixed height as long as there is at least one higher-numbered band (i.e. drawn lower down in the view) with data. This behaviour makes it easier to show data like lecture theatre or operating room scheduling, where it is expected that at times a given band (e.g. given room) may have no events (bookings). Empty bands below the last band with data are not drawn, to reduce the vertical height of the view.

    All even-numbered bands, with numbers starting from zero, are drawn in $MapBackgroundColor; all odd-numbered bands are drawn in a tint of $TimelineColor. For a given view these colours are those of the view's container, i.e. the same place (note) as with $TimelineBands described above.

    $TimelineBandLabelColor and $TimelineBandLabelOpacity allow control over the colour and opacity of timeline band labels.

    $TimelineBand is intrinsic for aliases, allowing aliases to be placed in a different timeline band to their original.

    Timeline customisations: items vs. view level

    Some aspects of the timeline view are altered per item and some in the container used as the view source.

    Item (note) level:

    Container (view) level:

    Adornments: these use map view colour, border, etc., but smart (query) elements of adornments are ignored. Where they overlap, adornments follow map view stacking order, though this can still be adjusted in timeline view using the same controls as for map view.

    Overall background colour is the container's $MapBackgroundColor, and thus is common to the container view across all major view types. The optional alternate colouring & pattern settings used for maps are ignored in timeline view.

    Any aliases in scope, i.e. descended from the container (unless aliases and/or descendant display is disabled), are drawn like normal notes except that an italic font is used for the title. The note $Name/$DisplayName is drawn in $Color and the marker in $AccentColor with the marker line to the scale using a tint of $AccentColor. Timeline view uses display expressions for items but does not show their subtitles or hover expressions.

    Timeline scalebar

    At the bottom of the view is a scale bar whose graduation at labelling will vary as the view scale is changed using the scale scrubber control at top left of the view. The bar uses a graduated colour fill from $TimelineScaleColor at the bottom to $TimelineScaleColor2 at the top. The latter defaults to the same colour as $MapBackgroundColor to give a smooth transition into the main part of the view. Thus if the latter is changed, it is probably a good idea to set $TimelineScaleColor2 to the same value.

    The periodicity and exact scale bar positioning of scale captions are set by Tinderbox and vary with the scale as set via the scrubber. The user cannot modify these labels.

    From every major scale marker (normally those with labels) a vertical grid line is drawn vertically up across the timeline, in $TimelineGridColor.

    BCE dates show in the time scale bar of Timeline view (originally this was not the case).

    Timeline Settings pop-over

    This pop-over gives a visual method for setting a number of timeline-related settings for the current Timeline view:

    • Width. This adjusts the scale of the bottom scale, i.e. how much horizontal distance there is between days or months, etc.
    • Scale Color. A trio of standard colour controls set the main colour used in the scale bar at the bottom of the timeline. $TimelineScaleColor.
    • Band Color. A trio of standard colour controls set the colour a tint of which is used to draw alternate timeline bands ($TimelineColor). The actual colour set is a 'lighter' shade of the colour set in the controls.
    • Label Color. A trio of standard colour controls set the colour used to draw timeline band labels ($TimelineBandLabelColor).
    • Label Opacity. Sets the opacity with which timeline band labels are drawn ($TimelineBandLabelOpacity).
    • Links. (Default: ticked). If ticked, links starting/ending within the view are drawn. If not ticked no links at all are drawn in the view. ($TimelineDrawLinks).
    • Labels. Sets the labels used for timeline bands ($TimelineBandLabels).
    • Start. Sets $TimelineStart.
    • End. Sets $TimelineEnd.
    • Include:
    • Attributes:
      • Start. Choose an alternative Date-type attribute for plotting event start instead of $StartDate.
      • End. Choose an alternative Date-type attribute for plotting event end instead of $EndDate.

    Treemap view

    [First introduced in v1.0.0]

    Treemap view enables more notes to be visible even in comparatively small spaces and to reveal quantitative relationships between them.

    Treemap Properties may be adjusted by clicking the "i" button in the Treemap tab. These controls weighting of items such that the area used to draw the items represents some value. By default no weighting is applied and all sibling notes draw at the same area within their parent; note their shape may vary to allow the map algorithm to fit everything within the parent. In addition notes are drawn with a border in $Color and a fill of the Treemap 'start' colour.

    As well as an action code expression to set weighting, the Treemap Properties also allow a separate weighting to be set such that the fill of an item uses a a shade between customisable start/end colours. A custom border colour can also be set to override use of $Color.

    The Actions and Dashboards tutorial PDF contains a useful section on configuring treemap view.

    Treemaps do not support the dragging of links from the view pane. Use the link widget on the text pane to drag links from the selected note.

    Links can be dragged from the link parking spaces onto notes in the treemap to create links. To create a link from a treemap note, use the text pane link tool making sure there is no $Text selected; this creates a basic link from the selected note.

    Treemap Settings pop-over

    This is the configuration pop-up for the current Treemap view. Note that none of these settings are saved as attributes but they are saved as part of the Tab's data.

    *Treemap Expression. Enter an attribute name or action code expression. Used to derive a number used to set each item's area. Items with a value of zero are not drawn at all. Non-Number attributes return a value of 1 if they have a set/inherited value: i.e. string-based are not empty, booleans are true. The default is empty (i.e. no action code expression code). XML setting: treemapExpression.

    *Color Expression. An action code expression use to colour each note. The colour used is a shade between the start/end colours set below. The minimum value uses the start colour, the maximum the end colour with other values using a shade between the two. The default is empty (i.e. no action code expression code). XML setting: treemapColorExpression.

    *Start. The starting colour used of shading treemap items. The colour chip opens a standard OS colour palette. The default is an off-white #FFFEF9. XML setting: treemapColorStart.

    *End. The ending colour used of shading treemap items. The colour chip opens a standard OS colour palette. The default is a muted light green #CCD4C0. XML setting: treemapColorEnd.

    *Border Color. Enter the Tinderbox colour (named or hex value) used to draw the border of each item. Or use an action code expression resolving to a named or hex colour value. If not specified, items draw with a border of $Color. The default is no value. (i.e. it uses $Color). XML setting: treemapBorderColorExpression.

    *Maximum Depth. Allows display of only the N upper levels of the treemap. This can sometimes improve clarity of presentation. XML setting: treemapDepth.

    Find toolbar (view pane)

    The Find toolbar appears after you press ⌘-F with focus in the view pane. This adds a toobar isside, and acroos the top of the view pane.

    If the Find toolbar is already visible, ⌘-F moves the keyboard focus to the Find toolbar's search field. [Esc] dismisses the Find toolbar. The width of the search term input box of the find bar grows larger if the window is sufficiently wide. To dismiss (hide) the toolbar click the toolbar's Done button.

    Main controls

    Three independent buttons allow setting per-note search scope to use data from a User (attribute) and/or Text ($Text) and/or Name (note's title: $Name), or both. By default only Text and Name are pre-selected.

    Click the User button to additionally search a single user attribute, select from a pop-up list of all user attribute for the current document. Dismiss the popover and the label of the User button becomes that of the chosen attribute and operates as a toggle like the other two buttons. for instance if 'SomeAttribute' is selected, User becomes SomeAttribute. As only one user attribute selection is allowed, selecting a new user attribute will replace the existing choice. The feature is reset to 'User' (i.e. no selection) at the beginning of each session, i.e. each time the TBX is (re-)opened..

    Additional controls

    A prototype-based filter control is offered, essentially adding a fourth query term for an exact string match on the selected prototype's $Name. The pop-up list displays all the document's currently defined prototypes. Selecting a prototype, filters the Find results to only those items using the selected prototype.

    The pop-up menu in the search term input box has 3 tick-option items. These are for case-sensitive search, disabling parsing for regular expression use, and an option to use whole document (default) search or only search in selected container(s). From v11.60, a new menu option on the Find bar's search menu allows query-based search.

    Entering a search term

    Enter a search term in the box and press Return () to see a pop-up list of matches. Click the 'x' button in the input box to clear the search. Click on the magnifying glass icon to see a pop-up list of previous searches (up to 10 are stored); that list can be cleared via the same menu's options. Dragging the view pane wider will increase the width if the search term input box.

    Autocomplete suggestions. In macOS 10.14+ (but only in supported languages), Find offers suggested related words as possible autocompletions in the Find bar and in torn-off Find windows. Otherwise, the Find Bar does not display a menu of related words as autocomplete suggestions, such a suggestions list may be requested by pressing the F5 key.

    Double-clicking the chosen user attribute's UI button is a convenient shortcut to searching for the currently entered find string in that attribute.

    View filter toolbar

    This feature is currently only implemented in Outline and Gaudi views.

    The view filter toolbar is hidden by default, but can be opened from the View menu, or via a shortcut.

    Filter expressions are queries, and are saved with the tab.

    When the filter bar is active, outlines do not draw collapse widgets and all containers are implicitly expanded. Closing the filter bar disables the filter and restores the previous expansion state

    The filter list is alphabetised.

    The filter bar displays the number of items that match the filter's query. Note that this is not identical to the number of items displayed in the outline, since an item appears in a filtered outline if it matches the query or if one of its descendants matches the query.

    The Query field of the filter bar grows larger if the window is sufficiently wide.

    From v11.7.0, Find's search results now match plain letter characters diacritics and accented characters. A search for 'Dvorak' will match instances of both "Dvorak" and "Dvorák", as with a search for 'Dvorák'.

    Text pane

    The Text pane forms the right side the right side of any document window tab, i.e. everything to the right of the vertical spitter bar. By default the pane only shows the Text tab of the text pane (more on the content of the Text tab).

    In fact, the Text pane has three tabs: Text, Preview and HTML, with the latter two hidden by default, as mentioned above.

    As many Tinderbox projects do not need to export HTML (or any kind of marked-up text) at all, the selectors for these three tabs are hidden by default. In a new TBX document, the (empty) Text pane temporarily shows the pane selectors. The default hidden state it is deferred slightly to allow seeing the panel sliding away, helping to confirm that it is deliberately hidden (and suggesting that there is a way to recover it). Once the first note is added or the view switched, the default (hidden) state is used. The selectors then remain hidden until visibility is toggled.

    The show/hide toggle for the selectors in in the Window menu ▸ Shown/Hide Text Pane Selector.

    Printing is possible from all 3 sub-panes.

    The a document has no installed templates, showing the text pane selectors will add the built-in Templates container and the internal 'Preview'. If the built-in Hints container is already present, the Templates are not added as Hints already contains a copy of the 'Preview' template. The point of this behaviour is to ensure there is a template available for the generation of the temporary files needed by the Preview sub-tab.

    In all three tabs, the text pane's title offers a tooltip containing the path of the note.

    The sub-tabs are:

    Text tab

    This is the default tab of the Text pane and shows the selected note's $Text and, optionally, its Displayed Attributes. By default the text area is empty and there is no Displayed Attributes table displayed.

    Title bar

    The top grey section of the tab contains a number of controls:

    • Link Widget. Displays a white 'T' when there is a selection of $Text. See more on the use of the link widget.
    • Error warning indicator. Shown only if errors are found. Click to display the Error list. See more on the error list. The error flag has a text title to make the meaning more obvious.
    • Title. The note title ($Name). The string is always $Name and not $DisplayName such as will be seen in the View pane at left. The title is drawn in $Color using $NameFont. The title is always editable as soon as the control takes focus. Using the Return key to complete the edit will close title edit mode and set focus in the View (left) window pane. The title is rendered in $Color unless the colour is "transparent" in which case black is used. Notes using lighter colours for $Color may render the title in black as opposed to $Color in order to give sufficient contrast. The colour used to render the title obeys the Document Settings, Outlines tab's for darker colours or always using black or white titles.
    • Add Displayed Attributes button. This opens the Add Displayed Attributes pop-over, allowing addition and editing of the Displayed Attributes table.
    • (disclosure triangle). This can be clicked to show/hide the Displayed Attributes table. The triangle is not shown if the current note has no Displayed Attributes configured. The show/hide state is stored in $HideDisplayedAttributes.

    If multiple items are selected in the View pane the lower part of the text pane, below the title bar, is replaced with a grey fill and a caption showing the number of notes selected.

    Displayed Attributes

    This table is only shown if Displayed Attributes ($DisplayedAttributes) are set for the current note. The table's listing and wording or listing is controlled via the Add Displayed Attributes pop-over accessed from the button in the title bar.

    See more detail on configuration and use of the Displayed Attributes table.

    Text area

    The Text area is the main section of the tab and holds the text ($Text) of the note. The text is rendered as styled text, though note that not all styled text features export to HTML. A ruler (tab bar) for the text area can optionally be toggled on/off (see the Text sub-menu of the Format menu).

    Editing text updates the current note's rule and edict (if present).

    More on the Text pane:

    Displayed Attributes table

    NOTE: 'Displayed Attributes' replace the old now-deprecated 'Key Attributes'—see explanation. Displayed Attributes are sometimes referred to with the shorthand abbreviation 'DA' in help forums, etc.

    A note's 'Displayed Attributes' are an optional display of a user-defined tabular layout of attribute title/value cells. A Displayed Attribute is a display feature and has no effect on inheritance and does not accord an attribute any special status other than being easily viewed/edited for a note's text pane.

    A note's title ($Name) can be edited directly via the title bar above the Displayed Attributes table so there is no need to add it to the table.

    Table layout

    The table has 3 columns:

    • Left column. The listed attribute's name. From v11.5.1, this column auto-resizes to the length of the longest attribute name in the table, to allow for more width in the third (value) column.
      • The width of the first column adjusts itself to accommodate the longest listed attribute name.
      • If a user attribute is renamed, its new name is applied to any Displayed Attributes table using that attribute.
      • Hovering the input cursor over this column will cause the attribute's Description (if any) to be displayed as a tooltip.
      • From v11.5.1, the column has a light grey fill to give more contrast to the other columns. This tint adjusts automatically for OS light and dark modes.
    • Middle column. This allows some attribute data types to place a special control widget in the middle column.
      • Attribute data types using configuration widgets: Color, Date, Email, File, Font, URL (see more in section Data-type variations in displayed information below).
      • This column is left blank if the attribute data type has no widget.
      • This column is always drawn even in none of the currently displayed attributes use a widget.
    • Right column. The listed attribute's value (if any). Selecting the cell allows manual editing of the value or pasting in a new value
      • When the value cell has input focus, and the data type is String, List or Set, the extreme the right of row shows a > icon. if clicked this shows a pop-up list of values, allowing quick setting of any value already in use for that attribute (including its suggested values, if defined).
      • The table displays an ellipsis (…) if the text value extends to multiple lines, even if the visible line is not truncated.
      • Also see the Editing Displayed Attributes values section below.

    Right clicking on any column gives a pop-up menu, allowing copy, re-initialising or evaluating the attribute's value.

    Revising table layout

    A table row is added by:

    • using the 'Add Displayed Attributes' button in the note's text pane's title bar (button, to right of the title), and then using the Add Displayed Attributes pop-over the contents and order of the table; pre-v8.9.0 the button icon was a '+' sign. As well adding/removing existing attributes, new attributes names can be typed here and on dismissing the pop-up the user will be asked to confirm this is a new attribute and its data type (default type: string). This pop-up can also be called via the View menu's Edit Displayed Attributes... .
    • setting the note's $DisplayedAttributes.
    • altering the note's prototype's Displayed Attributes (if a prototype is used).

    A table row is deleted by:

    • selecting the row and using the delete (backspace) key.
    • using the 'Add Displayed Attributes' button in the note's text pane's title bar (see detail above).
    • setting the note's $DisplayedAttributes.
    • altering the note's prototype's Displayed Attributes (if a prototype is used).

    The row listing can be re-ordered. The vertical order of displayed (key) attributes can be altered by:

    • via drag-drop of the attribute name label (left column)
    • altering the order of the list stored in $DisplayedAttributes.
    • using the 'Add Displayed Attributes' button in the note's text pane's title bar and re-ordering items in the pop-over dialog.

    Variable row height for values

    Attributes of String, Set, List, Dictionary and Action data types (only) can have a bigger line height (i.e. use multiple lines/rows in the table). The default row hight for String-type attributes remains one line, but this can be extended to a maximum of seven lines. Within that space line breaks in the String's value are honoured but any overflow is clipped (i.e. more content cannot be scrolled). Line height is set per-attribute using The Document Inspector's System and User tabs.

    Row styling

    The font style indicates information about the nature of the attribute data:

    • bold indicates a value set locally for this note, i.e. not inherited.
    • lighter colour rows indicate data is read-only. These are normally system attributes using dynamically calculated values like $ChildCount; in the app pre v6 these were in italics. For instance, if $WordCount is a displayed attribute, editing the text pane periodically updates the displayed word count.
      • The attribute $ReadOnly is exempted from being read-only, even when set to true. This allows you to turn off ReadOnly from the displayed attributes table or from Get Info ▸ attributes tab.
    • normal text indicates a default or inherited value.

    The full meaning of the styling of different rows (bold, strikethrough, etc.) is explained here.

    Data-type variations in displayed information

    Some per-data-type specific points to note, types using special widgets are marked with an §:

    • Boolean-type data. Displayed Attributes are always shown as a tick-box; ticked equates to true, un-ticked to false.
    • Number-type data. Very large or small numbers can be entered/shown using exponential form, e.g. 0.000001 can be entered as 1e-06.
    • § Color-type data. The data is shown both as a colour chip (showing the currently set colour) and a string showing the value set with is either a Tinderbox named colour or otherwise a hexadecimal value string ("#330099").
    • § Date-type data. Shows the data and time, with the date/time format in the host OS' short date format, so this will vary by the user's locale and their choice of OS settings. Document Settings offer a small selection of variations on the OS format. An alternative date-time string format can be used for all Date-type attributes in KA by setting $DisplayedAttributeDateFormat at document or note level using a date format string. On entering a date, if no time is specified, the time element of the attribute value defaults to current system time. A date-picker control is offered to the left of the value box. When editing dates in the Displayed Attributes table, the date string is changed before editing to its value in normal format (medium date, short time). This avoids ambiguity in short dates, where the default US style uses 2-digit years: i.e. does 12/7/41 represent a date in 1941 or 2041?
      • Note: the format set by $DisplayedAttributeDateFormat applies to all Date-type attributes in the note's Displayed Attributes table (and in its Get Info attribute listings).
    • String-type data. Although generally intended to hold short text values, String attributes can hold larger amounts of text and including line/paragraph breaks. When not selected for edit, all text paragraphs run together. In edit more, the value edit box will only show the first paragraph of text. Use the right arrow to reach first paragraph text overflowing the edit box; use the down arrow key to access paragraph #2, etc. It is not possible to type a line break character in the edit box but it is possible to copy/paste one into it.
    • Dictionary-type data. A specially formatted form of string. The value shows the 'raw' form of the dictionary consisting of key:value; pairs.
    • § URL-type data. A form of string attribute, URL attributes show a globe icon to the left of the data value edit box. Clicking the button will open the URL, stored in the value box, in the user's default web browser. Files can be dropped onto a URL-type attribute (e.g. to give a file:/// type of URL). The URL button remains enabled even if the note is read-only.
    • § File-type data. A form of string attribute, File attributes show a folder icon to the left of the data value edit box. Clicking the button will open the file (or folder) path set in the value via Finder. Folders will open in Finder and other file formats in whichever app is registered as the default app for that file type. The File button remains enabled even if the note is read-only. The Browse File… menu option is not available for read-only notes.
    • § Font-type data. Font-type attributes (which are only ever system attributes) show an 'A' button which opens the OS' Font dialog, making it easier to set the correct font name for a font. N.B. altering the text font size does not alter the font size attribute (where pertinent) in Tinderbox.
    • List-type data. All discrete list values are shown, as a single string of semicolon-delimited values. This data types can be set to use multiple lines for the value box.
    • Set-type data. All discrete list values are shown, as a single string of semicolon-delimited values. This data types can be set to use multiple lines for the value box.
    • § Email-type data. Email-type attributes such as $Email, show an icon which allow the creation of email from inside Tinderbox. If a note has no $EmailTemplate, the 'email' icon/button in the Displayed Attributes table sets the body of the new email to the styled text of the note (i.e. ^text^).
    • Action-type data. This data type can be set to use multiple lines for the value box.
    • Interval-type. Value default to an 'hh:mm' string although the range can extend up to days and down to seconds.

    Editing displayed attribute values

    Once a row in the table has focus (either via keyboard, as above)or by a direct trackpad/mouse-click the value box in the right column can be edited:

    • Enter edit mode. Either double-click (mouse/trackpad) or use the Return key (keyboard). The value box contents can be edited. To tick/un-tick a Boolean attribute via the keyboard use the spacebar. For data types offering it, the pop-up value list of existing/suggested values (see above) can be used to set a new value without typing.
    • Complete the edit and save the new value. Click out of the table cell (mouse/trackpad) or use the Return key to toggle out of edit mode.
    • Use the Escape key (⎋) to abandon an incorrect edit.

    Displayed Attribute characteristics such as enabling or disabling the URL and File buttons are updated after editing the Displayed Attribute's textual value.

    Changing the text of a Displayed Attribute immediately updates that Displayed Attribute's pulldown value menu.

    When a Boolean attribute is selected in the Displayed Attributes table, pressing the spacebar will toggle its value.

    The menu commands Format ▸ Text ▸ Insert Date/Time/Date and Time now insert the requested text at the insertion point, rather than replacing the current value with the requested text.

    Resetting default/inherited values

    For displayed String/Set/List data typed attributes only, the default value can be reset by using their pop-up value lists, by selecting the value 'normal'. For all other data types, to repair inheritance select the note in question and do either one of:

    • click on the line with the attribute to reset, right click and use the 'Use Inherited Value' option in the pop-up menu.
    • open the Quickstamp Inspector, select the desired attribute and use the reset buttons.

    Evaluating an attribute value

    The current value of the Displayed Attributes can be evaluated (as action code) and written back as the attribute's value. The Evaluate function is accessed via the table's pop-up context menu.

    Font/font size for the displayed attributes table

    The Displayed Attributes table can be set to a user specified font, for attribute names and their values, via $DisplayedAttributesFont.

    The font size used to render the current note's table can be altered via the Displayed Attributes replace Displayed Attributes sub-menu of the Window menu. The latter offers a small range of suggested sizes (default is 11pt). The actual size is stored is the point size number, i.e. 11 for the default in $DisplayedAttributesFontSize. It is possible to set values not available in the menu by editing the attribute value directly. To change the value for the entire document, use the Document Inspector General tab to alter the default value for $DisplayedAttributesFontSize.

    Show/Hide displayed attributes table

    A chevron icon > below the Add Displayed Attributes button toggles the visibility Displayed Attributes table e.g. to allow more space for showing $Text. The control is not shown if there are no Displayed Attributes for the current note., but the Add Displayed Attributes button still remains available. The table's show/hide state is stored in $HideDisplayedAttributes.

    Cycling/editing displayed attributes via keyboard

    To cycle through Displayed Attributes, use the Return key (↩). Using the Return key on a selected row sets that item in edit mode. Clicking Return again closes the edit and selects the next item in the table (looping to the top when the bottom is reached). When a boolean item is selected and in edit mode, use the Spacebar key to toggle the true/false setting, otherwise other data types are editing via normal keyboard input.

    If the Return key has not yet been used since the note was selected, the Up-Arrow (↑) and Down-Arrow (↓)keys can be used to move the selection in the table (but the selection does not loop at top bottom). If Return key has been used the Up/Down arrow keys simply select the table row above or below and set it in edit mode.

    To cycle between the Displayed Attributes table, the $Text are and the View pane, use the Opt+Tab keys (⌥+ ⇥).

    In Outline/Chart/Treemap view, to move the View pane selection (i.e. change the contents of the text pane) up or down one item in $OutlineOrder use Cmd+Opt+Up-Arrow ( ⌘+⌥+↑) or Cmd+Opt+Down-Arrow ( ⌘+⌥+↓).

    Changes to displayed attribute values: effects on $Modified and edicts

    Changing an attribute value in the displayed attributes table or in Get Info's attributes tab updates $Modified. Changing an attribute value in a stamp (including Quickstamp) or an action does not update $Modified. Changes (direct edits to the selected note's Displayed Attributes table's values will automatically trigger the note edict, if any, regardless of when next due to run.

    Maximum number of rows shown for displayed attributes

    The height of the Displayed Attributes table can grow as rows are added reducing the need to scroll long lists of Displayed Attributes if using a sufficiently-large display. The maximum length of the visible Displayed Attributes table is 16 items., scroll bars are ordered if the are more than 16 rows.

    Note that the visibility of scroll bars when the table is not in focus is OS defined, currently the scroll bars only show once scrolling is initiated in the table. The OS does not allow that behaviour to be modified

    Needing to show even more displayed aAttributes?

    The maximum number of table items equates to c.50% of the $Text area's height, so dragging a taller overall document window can help. Other approaches to consider:

    • set Displayed Attributes via prototypes. That means that it is easy in such notes to add new display items and delete others, e.g. to debug and immediate problem and easily reset them ('reset' button on the Displayed Attributes configuration pop-up) to the prototype-inherited list. Forget to reset at the time? The reset button still works at a later time. Or, simply make an agent to find all notes using that prototype and hasLocalValue(), e.g. `hasLocalValue("DisplayedAttributes")`. Then reset $DisplayedAttributes via the agent action.
    • Have the prototype store one or more alternative lists of attributes, e.g. normal set, a debug set, a set for a specific process, etc.
    Experimental $Text features

    The features in this section are experimental and subject to change or withdrawal.

    In-text check-boxes

    Note: this is an experimental feature, subject to change or withdrawal.

    In the text pane, Edit ▸ Insert ▸ Checkbox adds a checkbox to the text. Clicking on the checkbox checks and unchecks it. The list attribute $TextCheckboxes reflects the state of each checkbox in a note; the nth element is true if the checkbox is checked, and false otherwise.

    Note also:

    • After the Return ( ↩) key has been pressed, Tinderbox automatically inserts a checkbox if the previous line started with a checkbox. This simplifies making list of checkboxes in the text pane, which makes using them much nicer.
    • Checkboxes are unchecked at creation; previously, they were checked.
    • Checkboxes are update immediately after a copy/paste.
    • Checkbox size is based on the prevailing font setting, and is set to allow the checkmark top to align, at least approximately, with current font ascenders.

    For the present, action codeexpressions and checkboxes embedded in the text are ignored on export.

    In-text expressions

    Note: this is an experimental feature, subject to change or withdrawal.

    Edit ▸ Insert ▸ Expression adds an action code expression to the text, enclosed in a rounded rectangle. Clicking on the expression code displays a popover which allows you to edit the expression. The initial value of the action code expression is now the selected text, which the evaluated expression replaces. For example, if text '8*8' is selected inserting an Expression results in an expression element holding the code 8*8 but which in $Text displays as '64' (the action code evaluated result). If $Price is '1' and $SalesTax('tbxconfig') '0.2' (20%), then selecting '$Price+($Price*$SalesPrice)' will show as '1.2', i.e. the price paid at the counter. If either of those attributes changes the price seen in $Text will adjust accordingly.

    Contrast this with Edit ▸ Insert ▸ Evaluate Selected Text, which replaces '8*8' with '64' but without an underlying stored expression. Thus in the last example above, if $Price or $SalesTax changed subsequently, the $Text would not.

    For the present, expressions and checkboxes embedded in the text are ignored on export.

    The action code expressions expected are simple ones, as in an attribute's value or some simple maths. If the expression is complicated or the desired value needs more than one actuon to run, it is suggested to wrap such code in a function. An in-text expression can call the function and use the simple value it returns.

    Evaluate Selected Text

    Evaluate Text Selection replaces the selected text in the text pane with the result of evaluating the selection as if action code. For example, selecting the text $Color will replace the attribute reference with the value of $Color for the current note, ie. its colour such as 'blue' or '#ff0000'. Selecting '8*8" and evaluating would replace the selection with '64'.

    Essentially this is a one-time evaluation. If the note above changes $Color value, the note is unchanged as the evaluated value replace the original text and the means of evaluation if not stored. For dynamic evaluation see In-text expressions.

    When multiple notes are selected, EditInsertEvaluate Text evaluates the selected text in the context of the note from which the selected text was drawn.

    Text pane multi-item selection

    When selecting a composite or multiple notes in the view pane, the text pane shows the concatenated $Text of all the selected (or composite) items. From v11.7.0, when multiple notes are selected, Tinderbox concatenates their texts in the text pane. When the selection exceeds a fixed limit, no texts are displayed: from v11.8.0 the limit is 300 notes, previously it was 30. When exceeding the limit, the text pane is greyed out and a label 'N selected notes' is shown, where N is the count of selected notes.

    Text pane title area

    This shows the title of the first (by $OutlineOrder) in the title bar

    Delimiting of individual selection items in the display

    The texts appear in outline order ($OutlineOrder) with a grey rule drawn beneath each note's text (i.e. at the end of its $Text). Each note (except the first) is headed by its title drawn in the same light grey, immediately below the preceding rule and in a small font size. Despite the layout, the rule is the end of the previous note in the selection and the title the beginning of the next note. These dividers help the user understand from which source note that section of the concatenated text is drawn.

    Note titles cannot be edited

    The individual note titles ($Name) within the main display cannot be selected or edited. The title of the first selected note, shown in the main title bar, remains editable

    Editing $Text content

    Editing of $Text's text content is only permitted inside the scope of a single any note. To start editing a different note's $Text, move the insertion cursor location into that note's content in the text pane. Arrow key cursor movement only works within the scope of a single note's text ($Text).

    From v11.8.0, during text editing with multiple notes selected, Tinderbox draws each segment with its own $TextColor and $TextBackgroundColor.

    Selection for Copy/Paste/Cut

    • Copy. Selections that cross note boundaries, as well as only within single notes may be made to copy content and pasting can only occur within a single note's content.
    • Cut. Cut operations are not permitted in the display mode, regardless of scope of selection.
    • Paste. Pasting of new content can only be made within a single notes, whether at an insertion point or to replace a selection.

    Selection for text formatting

    Counter to the above, the style/formatting of text be modified in selections either within single note's content or across note boundaries. This facilitated changes in font or type size, etc., across an extended range of text.

    Images embedded in $Text

    If images are present in the $Text of selected items, these are included in the concatenated view.


    Legacy notes

    • This display feature was first added in v7.0.0, alongside composites, so that the full text of the composite could be read together. The concatenated text display was also available for ad hoc multiple-note selections.
    • v9.5.0 introduced the ability to edit the $Text of notes in this display form and also to edit text styles.

    Previously, every selected note was rendered into the list. Large selections are often used by people with no interest in this text display mode, so a default to 'all' could be tiresome, especially if some notes had very large text and were not intended for display in this style.

    Text area

    This is the main working part of a note and where is body copy ($Text) is edited and displayed. The text is styled text and supports Apple styled text frameworks' styles. The available text area customisations and controls are a sub-set of those that will be familiar from Apple's TextEdit app.

    Altering the look of note text

    A number of text area functions are controlled by/stored as attributes. These are system attributes mostly in the TextFormat and Textual groups. It is important to note that all text is styled. Thus these note-scoped attribute values controlling the text font and size have no further effect once the text area is first edited. However, the Format ▸ Style submenu has option for resetting selected text back to the attribute stored values.

    To set non-inherited font face (the 'name' of the font) or size or colour use the OS Fonts dialog. Styling like bold, italic, or underline use normal macOS shortcuts and can also be accessed via the Format menus, as can things like sub-/super-script, and enabling rulers and tab-bars. Colour and highlights colour values may also be set via attributes.

    Some further options are available via the right-click context menu with options varying depending on whether there is text selected or no selection.

    The Text Inspector's 'Text' tab controls a number of note-level text settings so in not the place to look for in-text style controls.

    Displaying note text in map view icons

    This aspect of text display is described under Map view, see here.

    Text Selection

    Text selection methods:

    • Select the adjacent line: click in the left margin of the text pane.
    • Select the adjacent paragraph: double-click in the left margin of the text pane.
    • Extend the existing selection: shift-clicking and shift-double-clicking extends the current selection to encompass the adjacent line or paragraph.

    Rules and Edicts are updated when the text of a note is edited.

    Sorting lines (paragraphs) in $Text

    When editing text in the text pane, it is sometimes useful to sort lists. Menu Edit ▸ Transformations ▸ Sort now sorts the selected lines in the text pane, using the local standard sort comparator.

    Find & Replace

    The text area has its own discrete Find and Replace features including highlighting of Find results. A ruler can be displayed for the text area.

    Exporting Styled Text

    Though only a subset of the full range of styled text is supported for HTML export, fully styled text export is supported via text export (note the latter only supports a limited range of export codes).

    Text Font, Size and Colour

    When $Text is first edited it uses its inherited of set $TextFont, $TextFontSize and $TextColor, i.e. the defaults. Importantly, this results in styled text saved using those values. As a result, changing those defaults has no effect on existing text in the $Text. To restyle (selections of) the existing $Text or to re-impose the defaults see the Format ▸ Style or Format ▸ Font menus.

    Avoid Importing Source Text Style

    When importing test, to avoid source styles carrying across (e.g. copying from a web page) rather than use the Paste (⌘+V) command use Paste and Match Style ( ⌘+⌥+⇧+V). This will retain bold and italic styles but lose any font type/size/colour inherited from the source .

    Thus when importing test from outside Tinderbox it is generally best to use Paste and Match Style unless it is certain that external formatting is needed.

    Action Code and Styled Text

    Several string operations can be applied to styled text from $Text, or to text destined for $Text, in order to modify the (rich) text styling. Note that while any string may have its style set, this styling only has an effect when viewed in $Text.

    When an action assigns the $Text of one note to another, Tinderbox preserves styling.

    $Text = $Text("/configuration/example") 

    When the text of two notes are appended, Tinderbox preserves styling.

    $Text = $Text(/a)+$Text(/b) 

    A string may be emboldened or italicised:

    $Text=$DisplayName.bold 
    $Text=$MyString.italic 

    The font size of a string may be changed:

    $Text=$MyString.fontSize(36) 

    The following operators also respect style information:

    • String.replace()
    • String.substr()
    • String.paragraphs()
    Text area ruler

    A ruler can be displayed for the text area showing margins and tab stops and also including a set of styled text style controls.

    The ruler is hidden by default at the start of every session and turned on/off globally for the document; i.e. if shown they are shown for every note. The ruler is shown either via the Format ▸ Text sub-menu or a shortcut.

    The ruler allows the setting/editing of margins, hanging indents and tab stops.

    Controls above the ruler allow the setting of stored styles. These apply at paragraph rather than note level, so are best applied to text selection. There are further controls for text alignment, line spacing, and list styling.

    Styling of lists and other ruler-set styles

    The Tinderbox area (i.e. where $Text appears) uses Apple's Rich Text engine. As result is that built-in styles use a default font of Helvetica 16pt. Although a note has a $TextFont (and $TextFontSize) it is not applied to $Text until a given note's $Text is first edited. At that point the current $Text font becomes the 'base' font for that note's text.

    If inserting styles from the ruler, such as a list, and $Text has not yet been edited, the style may apply its (Helvetica) default, as $TextFont is not yet set in the stored styled text data. If this occurs, either use the Format ▸ Style menu's, Standard Font command ( ⌃⌥⌘+T) to reset to font. Or, before using any style in a new note, type a few characters in the note to 'set' the base font (the characters can then be deleted). Thus:

    • Make a new note, place the cursor in $Text and then add a numerical list. The font of the list numbering will be Helvetica (the stored format). Not desired! So,

    *Do the same but first add at last one character before adding the list and the font used is $TextFont.

    Find toolbar (text pane)

    The text pane supports a discrete Find bar. Opened via the Edit ▸ Find menu or a shortcut, this adds a one-row toolbar to the top of the text pane (and beneath any Displayed Attributes). If Find & Replace is required, the bar expands to 2 rows.

    Matches to the find string are case-insensitive and regular expressions are not supported.

    The results if a find in $Text will highlight all matches in the current text and lists the total count of matches (if any) at the right-hand end of the search string input box. The two chevron button allows the cursor to be cycled through the matches in the $Text.

    Ticking the Replace box toggles additional find & replace controls.

    The Done button closes (hides) the Find toolbar. Note that the current find string is remembered during the current session so can easily be re-used.

    Find results toolbar (text pane)

    With the focus in the text pane, running a find opens the text Find bar. Enter the search text into the find box. Matches are case-insensitive and regular expressions are not supported.

    Once a Find has been run on the text ($Text), the Find input box shows a match count at its right-hand end. The $Text is greyed over and all matches are highlighted. The chevron buttons to the right of the Find search box can be used to cycle through each of the matches in turn.

    Find & Replace toolbar (text pane)

    The text pane supports Find & Replace for $Text. Opened via the Edit ▸ Find menu or a shortcut, this adds a two-row toolbar to the top pf the text pane (and beneath any Displayed Attributes).

    Existing text Find controls can be used to cycle through the current note's Find matches and replace them (Replace button) with the Replace text. Or, use the All button to replace all current matches.

    In the Text pane, Edit ▸ Find ▸ Use Selection for Find loads the find string for both the text pane search bar and the view pane search bar.

    Preview tab

    The preview tab gives a live web-browser style preview of the current note as it will appear when exported. If the export code uses style sheets, images, etc., these will work in preview if such assets are already exported/stored in the appropriate location within the document's export folder.

    The Preview tab can also be used simply for viewing a note in rendered form even if there is no intent to export, e.g. when using Markdown in the actual note $Text.

    The Preview pane, in order to offer greater functionality than in the past, writes temporary files to disk. This is because the view renders a web page, using the built-in 'Preview[' template is there is no previously set document export template. The temporary files are written to one of two locations:

    • By default, if no document export folder is set, the temporary files are written to a hidden temporary folder, and which Tinderbox clears out when necessary.
    • If a document (HTML) export location has been set (as viewed/set via the Export Inspector) then the previewing a note results in the file being exported. In this case any nesting folders are generated as necessary so the (temp) export is in the correct whole-document export location.

    Also:

    • $Text-embedded images appear in previews.
    • Images are automatically exported when a note with images is previewed.
    • JavaScript is enabled in the Preview pane.

    External links

    From v11.7.0, external links now open in the default web browser rather than the Preview pane.

    Export tab

    This alternative view for the Text pane shows the current note's data as marked up for HTML Export. Although 'HTML' is described, this method of export can be adapted for use with other favours of markup.

    Different colours represent different sources:

    • Blue: text, i.e. $Text via ^text^.
    • Red: includes of children's data.
    • Blue-green: includes of data from other notes, e.g. via ^include()^.
    • Grey: code from (export) template.
    • Black: anything else.

    For some bespoke mark-up tasks it is not necessary to do a full page export; simply swap in the desired export template and select/copy the code from the HTML tab.

    The code in this view is rendered in $HTMLFont at $HTMLFontSize. These attribute can be set by invoking the OS Fonts dialog via the view's context menu and setting the font typeface and/or size.

    If the document currently has no HTML template set, this sub-tab will show the Template pop-up menu to allow selection of an export template to use (assuming one or more templates are defined in the document).

    The Export tab displays the selected note's $HTMLPreviewCommand, if it has one. A checkbox allows temporarily disablement of the preview command and Markdown processing. This makes it possible also to see the exported content as it is before it is post-processed by the preview command. The toggle is only used within the view, i.e. viewing the export code 'live', and thus has no background setting fro the tick-box.

    Secondary windows

    These are primarily 'torn-off' windows. The term is a hold-over from the original app design which split views in into 'main' views (now the view pane's views) or 'secondary' , i.e. stand-alone view windows.

    Find results stand-alone dialog

    Note: some features requires macOS v.14.

    This is the torn-off version of the view pane Find results pop-over. The torn-off Find window retains its selection when clicking on a note. Its title reflects the number of notes found in the document, and the number in the scope of the current view. Selecting a note in the torn-off find window will select that notes in the view, if the note is available.

    Tinderbox remembers the detached dialog's preferred width and uses that width for the Find results popover in the future, i.e. it persists after the document is closed.

    [list of matching notes]. The list are shows notes matching the Find criteria. Results are listed by note title ($Name) sorted in the default, lexical, sort order. A lexical sort is used means that instances of the same word in different letter case do not sort together: Ant, Bee, ant and not Ant, ant, Bee as a non-coder might assume. To have greater control over the sorting of results or to get a count of matches, use an agent instead of Find.

    For notes where the match is in $Text, the (first) match context is sown in a second line of listing with the match highlighted. Matches for note title or user attribute value use a single line listing.

    Clicking on a list item makes that note the context of the front window's text pane. Listed notes are rendered in using $Color. Text for notes not in the current view scope are shown as a preview - see 'Preview windows' below.

    The pop-over has a series of controls:

    • search input box (from which a new search can be run). The input box expands/contracts if the dialog is width is drag-altered.
      • The box's pop-up menu offers an option for case-sensitive search, and an option to turn off regular expression search.
      • An 'x' button deletes the current search term.
    • a tick-box to alter the case-sensitivity of searches (this is the same as the setting on the input box pop-up menu).
    • a tick-box to allow inclusion of aliases (by default they are filtered out).
    • sort order pop-up with the following choices:
      • outline order (default). Uses value of list item's $OutlineOrder.
      • Creation date. Uses value of list item's $Created.
      • last modified. Uses value of list item's $Modified.
      • name. Uses value of list item's $Name.
    • Apply.

    The controls work live on the current search results (both in pop-over and tear-off form) without the need to re-run the Find.

    Found items are grouped into two groups:

    *The first grouping shows items within context of the current tab's view. Such items might not necessarily immediately be seen within the current view area, e.g. because they are outside the display part of a current Map or inside a collapsed container within a current Outline, etc.

    • The second group lists all other matches that cannot be seen in the view pane without changing the context of the current view, i.e. setting its scope differently from the current settings. Clicking these out of scope list items invokes a preview window (see below).

    The Find window can match outline separators and map adornments.

    A contextual menu in the listing of matches lets the right-clicked list item be opened in a new stand-alone text window or in a new tab. Shift-double-click on a listed item will also open the result in a new tab.

    Find offers up to 7 suggested related words as possible autocompletions in the Find bar and in torn-off Find windows. Note: the related text feature only works on macOS 10.14 or later.

    Text replacement: this feature is only available in the pop-over mode of Find results.

    From v11.7.0, the stand-alone results show more context than the op-up pane.

    Preview windows

    After selecting a note in the Find window, if the note cannot be selected and previewed in the current view, Tinderbox displays a preview of the note's text.

    Once displayed, either click the preview to close it, or drag it to tear it off as a stand-alone text preview window. Preview closing instructions are shown briefly, at the bottom of the preview pane, on first opening.

    Closing the dialog

    Click the dialog window's 'close' (red) button. This will close the dialog and any preview windows open.

    Dragging aliases

    Results dragged into the view pane generate an alias of the dragged result's source note.

    Dragging text links

    Results from the Find results pop-over can be dragged into the text pane. The display name of the dragged item will be inserted into the text and used as the anchor of a text link to the corresponding note.

    Get Info stand-alone dialog

    This is the torn-off mode of the Get Info pop-over provides a series of tabs showing information about the currently selected note. This allows the Get Info information to be viewed and used when the source note is no longer selected. It is possible to have multiple Get Info dialogs open at the same time.

    The sub-tab selected on first opening will generally default to the last one used in the current session.

    The dialog has the following tabs:

    agent tab

    Scope: source (selected) agent. (Agents only!)

    This tab controls basic agent functions. This replicates information found on the sub-subs of the Action Inspector. Edits made on the this dialog are live as soon as the Return key (↩) is pressed or focus shifts from the current input box on the pop-over.

    This popover is shown by default as soon as a new agent is defined.

    Agent title (only shown if the current object is an agent). The $DisplayName for the agent is displayed above the input boxes.

    Query. The agent's query (stored in $AgentQuery). Auto-complete is offered for action code terms and system/user defined attributes (if starting with a '$' prefix, as is best practice). Editing this code is the same as if editing the Action Inspector's Query tab.

    Action. The action to be applied to each child alias (stored in $AgentAction). Auto-complete is offered for some input, as described above. Editing this code is the same as if editing the Action Inspector's Action tab.

    Priority. This opens the Agent Priority pop-up list, allowing the agent to be turn on, off or to a non-default working state (e.g. on, but at lower priority). Setting is stored in $AgentPriority. Using this is the same as using the Action Inspector's Query tab's Priority pop-up.

    Result count (only shown if the current object is an agent). The count of matches to the current query is shown in grey text bottom right of the pop-over.

    Dragging the pop-over will result in a tear-off window that will persist until the end of the current session (i.e. the document and/or app are closed). A torn-off window may be closed during the current session if no longer needed.

    Code syntax colouring. The agent's query and action code boxes receive action code syntax colouring.

    attributes tab

    Scope: source (selected) note.

    This tab shows attribute data and is the most direct successor to the Get Info dialog in previous versions of Tinderbox. The tab has 3 sections.

    Search. This works as per the Document Inspector, System tab, in seeking to auto-match any input to a currently defined attribute (here for system or user). If multiple matches are found, these are displayed in a pop-up listing allowing the user to select the preferred match. If a match is found, the correct attribute group is selected in the listing and its contents loaded. From this the matched attribute is also selected. Here, $BorderColor has been searched for and matched.

    Attribute Group listing. A list of all the defined groups of System attributes and any defined User attributes.

    Attribute data table. A list of attributes within the currently selected group. The left column shows the attribute name. The right column shows the current local or inherited value. Display and editing of attribute values is as described for the Displayed Attributes table. String, Number, Set and List type attribute will display a pop-up menu showing values currently applied to that attribute elsewhere in the document.

    Row height in the table. Attributes of String, set and List types (only) can have a bigger line height (i.e. use multiple table tows). The default row hight for String-type attributes remains one line, but this can be extended to a maximum of seven lines. Within that space line breaks in the String's value are honoured but any overflow is clipped (i.e. additional content cannot be scrolled). Line height is set per-attribute using The Document Inspector's System and User tabs.

    Some attribute data types show an icon between the attribute name and value cells. The function of these is described under the notes on the Text pane's Displayed Attributes table.

    The meaning of the styling of different rows (bold, strikethrough, etc.) is explained here.

    Dragging the pop-over will result in a tear-off window that will persist until the end of the current session (i.e. the document and/or app are closed). A torn-off window may be closed during the current session if no longer needed.

    Editing the $Prototype value in this dialog is just one way of setting a note's prototype.

    The attribute $ReadOnly is exempted from being read-only, even if set to true. This allows you to turn off ReadOnly from the Displayed Attributes table or from Get Info ▸ Attributes.

    Date-type Attribute formatting

    In the table of attribute values, Date-type attributes use the value formatting set via Doc Settings/Text and inherited via $DisplayedAttributesDateFormat. As the latter attribute's name suggests, this means Displayed Attributes and this dialog's tables use the same date for formats. Note that whilst the format can be set from document down to per-notre scope, for any note all Date-type attributes values are listed using the same format.

    Changes to Displayed Attributes affect $Modified

    Changing an attribute value in the displayed attributes table or in Get Info's attributes tab updates $Modified. Changing an attribute value in a stamp (including Quickstamp) or an action does not update $Modified.

    Showing an Attributes's Description

    Hovering the input cursor over the left column of the table—the attribute's name, will cause the attribute's Description to be displayed as a tooltip. This works for both system and user attributes. Note that user attributes have no Description unless the user adds one (occasionally new system attributes may

    book tab

    Scope: source (selected) note.

    The book tab shows book-related data. For notes with an $ISBN value, Tinderbox will assume the note is about some from of book and the book tab will:

    • look up author and title, if not already known, from ISBNDB.com
    • look up the cover image from amazon.com
    • provide useful links to Amazon, Goodreads, LibraryThing, and WorldCat for this book.

    The ISBN box shows $ISBN data or allows it to be set directly by editing in the box.

    Dragging the pop-over will result in a tear-off window that will persist until the end of the current session (i.e. the document and/or app are closed). A torn-off window may be closed during the current session if no longer needed.

    info tab

    Scope: source (selected) note.

    The info tab holds basic metrics about the current note, mostly relating to attributes:

    Dragging the pop-over will result in a tear-off window that will persist until the end of the current session (i.e. the document and/or app are closed). A torn-off window may be closed during the current session if no longer needed.

    map tab

    Scope: source (selected) note.

    The map tab checks to see if $Address is populated and if it is will attempt to resolve the address into Google Maps, populating $Latitude, $Longitude and $GeocodedAddress.

    The top input box shows data in $Address, or adding data to the box will set there attribute.

    If a map location is found, the map can be zoomed via the slider control to the right of the map.

    Dragging the pop-over will result in a tear-off window that will persist until the end of the current session (i.e. the document and/or app are closed). A torn-off window may be closed during the current session if no longer needed.

    The map tab has an Open In Maps button that opens the (macOS Apple) Maps application.

    paths tab

    Scope: whole document.

    The paths panel displays the number of distinct link types defined within the current document. These are listed in a pop-up control, at top centre of the dialog. These discrete link types added/edited in the Links Inspector.

    Here, 'path' has a slightly different meaning to that used in the context of a note's address ($Path) in the document outline. In this context, a link type's path as all the notes with one or more inbound or outbound links is the selected link type. Be aware that a document may contain more than one discontinuous such network, i.e. clusters of links of the select type but with no interconnecting link.

    The information is whole-document-scope and can be accessed from any note's Get Info, even if that note does not use the link type of interest.

    A pop-up list shows all the links types defined in the document that have one or more links of that type in use. Selecting a link type from the pop-up, the list panel will reports(remember—for all such paths in the whole document):

    • Paths in use (in this document). The overall number of discrete link types being used with links in the current document—so, not a count of discrete links within the document. This list may not include every link type defined in the current document (i.e. as seen in the Links Inspector) because some types may not yet be used for linking.
    • Notes on this path (i.e. for the selected link type). The count of notes (including agents, etc.) with an inbound or outbound link of this type (i.e. 'in' the path). As that list includes both the source and destination of such links, the list will thus show more notes than the discrete number of links.
    • A scrollable listing (beneath the popup) of the titles ($Name) of all notes in the selected path (i.e. all the notes in the count in the above bullet). A tooltip for each item shows its full location path ($Path) in the document. Double-clicking the item will select that item. If in pop-over mode, the pop-over now attaches to the newly selected note.

    To see the count of overall internal links (i.e. both basic and text) in the document see the Info Inspector. To see every link type defined in the current document, whether used or not, see the Links Inspector. To see the number of links starting in the current note (and by basic/text/web breakdown, see the source note's Browse Links.

    Using the paths dialog for link triage

    Given that the information is whole document, start from any note but 'tear off' the op-over to be a standalone dialog as this makes for easier working.

    If intending to add new link types, add these to the document via the Links Inspector before trying to use the new values. A link type can be renamed by editing in the Link Inspector: all links using that link type immediately use the new name (some open views might need refreshing). If stopping use of a link type, i.e. where no links use the link type, it still remains defined and available. To remove the link type entirely, do so in the Links Inspector. Deleting a link type also deletes any current links using the link type, so work with care. If merging or retiring a link type, use the Get Info:paths to ensure no links still use the unwanted type, by checking it is not listed in the dialog's pop-up list. If still listed, select that item and then work through the remaining links either setting a new link type or deleting the links. Only then, when there are no links needing edit is it appropriate to delete the link type, unless all links of that type are unneeded. In the latter case the link type and all the links using that type can be deleted at the same time.

    repetition tab

    Scope: variable scope.

    The left list-box shows the repetition count of each repeated word. The right listbox shows the context of occurrence of the currently selected repetition (i.e. left list-box selection) with the text excerpt highlighting the repeated word. Clicking on an item in the right list-box opens that note in the text pane of the front document window. The data in the list-boxes can not be copied.

    The Scope of inspection is variable, selected by a pop-up menu with the following choices (the last option is the default):

    • document (whole current/front document). Use this option with caution in a very large document, it may take a little while to complete scanning the existing text.
    • parent & descendants
    • note & descendants
    • selected notes (default)

    The Copy data as clipboard button copies the word/count list data to the clipboard as a tab-delim list.

    A table of results shows the discrete words and the count of said words. The occurrence list can be sorted on any of the columns (default is 'word' in alphabetical order).

    The repetition tab thus offers insight into words that are used repeatedly in the selected notes, sections, or in the entire document. Consistent usage may be needful or desirable, of course, but noting repetition can call attention to opportunities to adopt more precise language.

    The pane lists words that occur two or more times except:

    • words with fewer than four characters
    • words that appear in the built-in 'stoplist' of 100 common English words
    • words that appear in an option customised stoplist.txt in Tinderbox's Application Settings.
    • words that appear in a note in the current document named 'stoplist', if one exists. The note title is case sensitive, but the note can be placed anywhere in the document (most likely away from the primary content).

    The repetition indexing process tries to treat words derived from a common stem as repetitions, so plurals and verb conjugations are often handled intelligently.

    similar tab

    Scope: (matches to) source (selected) note.

    The similar tab uses Tinderbox's 'similar to' function to list (up to) 10 items it adjudges most similar to the current note. It replaces the stand-alone minor view in older Tinderbox versions. Similarity is based on several factors, including:

    • the text ($Text) of the note
    • the note title ($Name)
    • any text contained in user attributes (i.e. attributes of String type or which are string-based)

    In addition, weighting is applied for:

    • notes having the same prototype
    • notes having roughly similar amounts of text

    Similar notes are listed in order from top to bottom, starting with the most similar note at the top.

    Double-clicking any list item sets the clicked note as the focus of the document window's text pane and dismisses the pop-over.

    Dragging the pop-over will result in a tear-off window that will persist until the end of the current session (i.e. the document and/or app are closed). A torn-off window may be closed during the current session if no longer needed.

    This information can also be accessed as an action code similarTo() and an export code ^similarTo()^.

    text tab

    Scope: source (selected) note.

    The text tab shows the $Text space of the current note. Dragging the pop-over will result in a 'tear-off' stand-alone window that will persist until the end of the current session (i.e. the document and/or app are closed). A torn-off window may be closed during the current session if no longer needed.

    This feature is offered in a richer form by opening a stand-alone text window for a note. Links in $Text are non-functional in this display.

    From v11.6.0, Text pane in Get Info has been removed, having been found to be not very useful. This reflects the fact that note text is now often longer and more complex than in the early days of Tinderbox.

    url tab

    Scope: source (selected) note.

    If the note's $URL is populated, the url tab will preview the linked webpage. The web content in the preview is live and links can be followed (but it is not intended for general web browsing).

    Dragging the pop-over will result in a tear-off window that will persist until the end of the current session (i.e. the document and/or app are closed). A torn-off window may be closed during the current session if no longer needed.

    words tab

    Scope: variable scope.

    This tab visualises the most common words in the $Text and $Name of in-scope notes. The word cloud acknowledges both the built-in stoplist and document's own stoplist.txt list, if present.

    Word clouds and aliases: If viewing the word cloud of a note and its descendants, and if the selected note is an agent, the word cloud indexes each alias found by the agent.

    The tabs controls are:

    'scope' pop-up. The scope of examination within the (current) document can be set to one of:

    • document: whole document (default)
    • parent & descendants: parent note of the current note and all the parent's descendants
    • note & descendants: current note and all its descendants
    • selected note: currently selected note

    The scope shown in the pane is equivalent to the export output of ^documentCloud^.

    'Scale' slider. The view can be magnified or reduced by dragging the dragging the slider.

    Image. A word cloud of the most common words found in the current scope. The words are drawn in $NameFont. Re-sizing the pane causes the layout of the contents to be re-arranged.

    Image copy. Right-clicking on the word cloud allows it to be copied to the clipboard as an image. The data is actually in vector format, so if pasted into an image editor capable of vector-based editing the individual word elements are accessible (Mac Preview has limited such support). If passed to a normal bitmap editor an image the size of the image in Get Info is created.

    Search. Click on any word and a Find pop-up based on that word is opened. The find is always whole-document scoped.

    For note and section, each distinct occurrence of a word is counted. For the document level view, Tinderbox counts the number of notes that contain a word 1 or more times. The display contains up to 100 words - less if there are fewer valid words in scope.

    Unlike the 'similar' notes tab, only $Text and $Name are interrogated. Other sources of words such as textual user attributes are thus ignored.

    If the dialog is torn-off as a discrete window, subsequent changes to in-scope $Text are not reflected; re-select the window sub-tab to refresh the view. Similarly, the 'selected only' scope only maps the note selected at the time the view was opened, and does not track changes in selection while the tab is active.

    This tab replaces the 'Common Words' view in very early versions of Tinderbox.

    Roadmap stand-alone dialog

    The Roadmap dialog is created by 'tearing off' a Roadmap pop-over. The Roadmap lets you see all of the internal links leading to or from a selected space—the local area of a complex hypertext (web links out of the document are not included. Aliases have their own Roadmap, not that of their original. The Roadmap not only gives an overview of inbound and outbound links but also allows exploration of the local hypertext (i.e. the TBX's content). Links out of the current document, e.g. web links, are not visualised in the Roadmap. Styled-text-based 'Smart' links are also omitted from the listing.

    The left column lists all notes that link into the current note; the column header lists a count of the inbound links. The right column lists all the note's outbound links, again with a count in the column header. To change the focus of a Roadmap, double-click any item in either column. The Roadmap will change to focus on the selected note, with links leading in and out of it in the two columns. The current window's view pane will update to the selected note, if it is in scope; note that if the pop-up is torn off the text pane stops following focus of the view.

    Roadmap opens with the initial focus on the outbound links list if there are any outbound links. Otherwise, the inbound links list gains the initial focus.

    Roadmap allows editing of the properties of the selected link. At the top of the Roadmap, Tinderbox additionally shows the display name of the note for which inbound and outbound links are currently being shown. The tooltip of this label is the full path of that note (which will include the name of the note.

    Pressing the Delete key (⌫) will delete the selected link.

    Tab (⇥) cycles from first listed inbound link → first listed outbound link → link type → first listed inbound link, etc. Use spacebar or Return ( ↩) to follow a link and set window focus on the currently selected list item. Use blind type to select a source or destination.

    Note: if the view pane view type is a map, selection/focus can move to other items on the current map but not to notes on other maps. In the latter case, only the Roadmap updates.

    The Roadmap title shows the $DisplayName of the notes whose data is being displayed. Each listed link item shows:

    • Line one. The $DisplayName of the linked note (in $Color) and at right its $Badge (if one is set).
    • Line two. The link type of the link and, for text links only, that link's anchor text.
    • Roll-over tooltip for either line: the full path of the linked note.

    If the Outline Document Settings for 'Darker colors' is ticked, the item is rendered in a darker tint of their $Color.

    Link Comment box. Below the in-/out-bound columns a box shows the link comment (if any) of the selected link; the comment can be edited. This box is not shown when the dialog is a pop-over,

    Include Prototype Links. A tick-box (ticked by default) at bottom left allows prototype-type links to be filtered out. Prototype assignments are stored as links, in the TBX's data, but are not normally used in maps and excluded from link count attributes. However, leaving such links in the last can help tracing prototype-based relationships in a document.

    Button focus on [title of calling note]. Located at middle-bottom of the dialog, this refocuses the dialog back onto the note from which the dialog was first opened. Or, if the user has shifted the selection of the current tab's view, the dialog updates to show the links for the currently selected note.

    As stand-alone dialogs the Roadmap dialogs last only until the end of the current session; they cannot be saved to last across sessions.

    Text window

    Any note (but not agents, etc.) can be opened as a 'tear-off' stand-alone window. The window display the note's $Text and Displayed Attributes table. Both are editable and will update the source note in the main window. There is no title bar or HTML/Preview tab. Note that drag-drop or link-dragging between windows is not supported.

    When a document is reopened, any 'tear-off' text windows that were open when the document was saved are also reopened. These text windows are moved in front of other windows lest they be hidden and forgotten.

    A standalone window can be created via the View menu or a shortcut (⌘⌥X).

    The meaning of the styling of different rows in the Displayed Attributes table (bold, strikethrough, etc.) is explained here.

    Text preview window

    In some cases it is useful for Tinderbox to be able to preview the text, e.g. to confirm the note's $Text content. In such circumstances, a number of Tinderbox features (listed below) will generate a preview window.

    Such preview windows are a form of pop-over. They show only the $Text of the target note (i.e. no Displayed Attributes or links panel). Clicking either on or outside the preview will dismiss it, but clicking+dragging the preview will result in creating a stand-alone Text window.

    The following features use text preview windows:

    Inspector

    The inspector dialog has TBX document scope, i.e. you can open one for each open TB document. Its outcome works on the current selection (of the parent document). By default it opens with the Quickstamp pane selected.

    In keeping with Inspector-type windows in other apps the Inspector always sits in front of any other Tinderbox window. The Inspector is invisible when the Tinderbox app loses focus; it does not close but is simply not drawn on screen when another app is in use.

    An Inspector's window title will show the name of the parent TB document, a colon, and either the $DisplayName of a single selected or the count number of notes in a multiple selection.

    The Inspector may be resized. Code fields, in particular, may thus be expanded at will to accommodate more complex logic when needed.

    In general documentation and community usage, the tab name or full name ate used interchangeably. Thus the 'Links Inspector' is the same as the 'Document Inspector's Links tab', etc. Likewise, the main Inspector name is assumed to refer to its default (first) tab: thus, 'Appearance Inspector' may be assumed to mean the Appearance Inspector's Interior tab unless a different tab name is given.

    From v11.6.0, the default size of the Inspector has ben revised to make it a little slimmer—better for small screens. The Inspector can still be resized. If this occurs the revised size is used for the rest of the current app session. Whether there are colour configuration controls, the colour wells have been moved from below to sit at the right of the other controls.

    Editing note $Name via the Inspector

    When the inspector displays the name of a single selected note at the top of the current pane, the name may now be edited by clicking on it. Editing is disabled when:

    • multiple notes are selected.
    • the Tinderbox or Document Inspector is selected. This is because these Inspectors always apply to the whole document and never to a single note.

    Tinderbox Inspector

    The Tinderbox Inspector data is document-scoped, and displays the file name document for the current (frontmost) document if more than one is open.

    The Tinderbox Inspector has these sub-tabs:

    Info Inspector

    The Hypertext Status view gives an overview of the current documents contents. It lists:

    • Notes. The number of notes in the current document (containers count as notes, as do separators).
    • Agents. The number of agents in the current document.
    • Aliases. The number of aliases in the current document.
    • Adornments. The number of adornments in the current document.
    • Total. Sum of notes, agents, aliases and adornments.
    • File Size. The approximate (saved) size of the current Tinderbox TBX file.
    • AI Status. (From v11.7.0) see below.
    • Words. The total word count for all notes.
    • Links. The number of links in the current document (excluding 'prototype' type links).
    • Attributes. The number of attributes defined in the current document:
      • System. The number of System (built-in) attributes. Hidden System attributes are not counted since the user cannot see them.
      • User. The number of user-defined attributes.
    • Prototypes. The number of prototypes defined in the current document.
    • Templates. The number of export templates defined in the current document.

    AI Status

    From v11.7.0, the AI Status indicationreflects the status of the AI MCP connection. There are a number of icons:

    • The in icon reflects AI calling Tinderbox
    • The out icon Tinderbox calling back to the to the AI.
    • From v11.8.0, the http icon is used for experimental MCP status use (still under developement)

    Possible states include disabled (grey), active (green), disconnected (red) or disabled in this TBX (lock symbol, for out only). This status indicator is intended to help diagnose issues when connecting to AI clients as an issue might occur at either/both sides of the connection. Also note:

    *If multiple AI MCPs are in use a red indicator will indicate one or more MCPs are malfunctioning.

    *If MCP is allowed by TinderboxEnable AI Integration but disallowed in the current document, the Tinderbox Inspector’s MCP status shows a lock icon for "output". This more accurately reflects the situation: MCP is allowed but won’t disclose information about this document.

    Agents & Rules Inspector

    This shows the total number of agents and rules defined in the document. This includes currently disabled agents and rules. An alias of a note with a rule adds to the rule count as the rule is evaluated in the agent context as well as the original.

    Progress bars

    The agent and rule 'progress bars' show a moving green line. This indicates the where in the agent or rule cycle execution is currently occurring. The horizontal position relates to the $OutlineOrder position of the item in question, as opposed to a proportional place in context of the number of rules or agents. If, for example, all rules are in notes in the middle of the outline order, the rule line will cycle but only through the middle part of the progress bar. The speed of progress indicates how fast or slow the cycle is running. If no defined items are active, the line for that bar will be static otherwise no movement may imply an agent or rule that has hung.

    The agent progress bar list the number of agents and in parentheses the number of agents currently active. The latter is useful in fine tuning performance in complex documents. Note: the rule count is the total of notes with rules and all of their aliases: a note with a rule that has three aliases adds four rules to the overall rule count.

    Each progress bar shows the title ($Name) of the currently executing item to help give an indication as to the scope of execution.

    If automatic agent updates have been disabled, the agent bar shows the caption 'manual updates only'.

    Pending Tasks. This shows how many pending operations are currently waiting on the agent task queue. This may be useful to know in very complex documents. Note that the exact nature of the 'tasks' is not described but the list number of tasks can indicate unseen load on the app created by the current active document.

    [Grey text. This applies to the agents and rules progress bars rather than Pending Tasks.]

    Tagging. This displays the name of the current note that is being tagged.

    Network. The control to the right of the caption shows synching is in use and its status. This process covers AutoFetch, watched folders, DEVONThink watched groups, geocaching updates, Bookends import updates, and other periodic maintenance (Note: Simplenote synch was discontinued in v8). The processes described start to (re-)run as the progress reaches the 12:00 position (top centre). One cycle means all affected processes will have run once. The more processes, the longer the overall time to complete the cycle. Within this display it is not possible to reveal the exact processes running, e.g. to differentiate AutoFetch calls from geocaching updates, etc.

    Edicts. To the right of the Network control a label indicates the number of edicts in use. If any edicts are present it shows beneath how recently they were updated.

    Document Inspector

    The Document Inspector data is document-scoped, and displays the file name document for the current (frontmost) document if more than one is open.

    The Document Inspector has these sub-tabs:

    System Inspector

    This allows the user to view the current document's pre-defined system attributes, which are added to any new TBX document (and added to automatically as new app versions introduce new system attributes). This Inspector allows the user to view and change their data type and default values.

    Search box. This allows the user to start typing an attribute name that Tinderbox will attempt to auto-match, suggesting completions. If an item is matched (or clicked from the suggested match list), the tab will select the appropriate Group and Attribute names to populate the other controls.

    Group. This allows the user to select a name from a list of any of the defined groups of Tinderbox pre-defined System attributes. By default, this loads the 'General' group, but within a current session will remember the last-selected group. In older releases, this was labelled 'Category'.

    Attribute. This allows the user to select an individual attribute's data from the currently selected group (above). By default, this loads the 'AdornmentCount' attribute, but within a current session will remember the last-selected attribute. Any attribute shown in strike-through text is deprecated, though normally still present for legacy issues. The meaning of the styling of different listed attributes (bold, strikethrough, etc.) is explained here.

    Intrinsic. If the attribute is intrinsic, a label 'intrinsic' in grey text is shown above the left end of the default value box. Otherwise this area is blank

    Data type. The data type for the selected attribute is shown in grey text above and to the right of the default value box.

    Default. This box shows the program default for the attribute in one of a number of forms:

    • Grey text. These are inherited defaults, normally from Document settings, and can not be edited (at Document level) via the Inspector interface. Inherited defaults may be qualified with a suffix in one of two ways, to give an indication as to why they can not be edited here:
      • ' (preference)'. This attribute's default can only be set via a control in Document Preferences. An example is $TextFont. Use the appropriate Document Settings control to change the default.
      • ' (read only)'. This is a calculated total, e.g. $ChildCount. It is calculated on the fly and whilst it has the notional unset default of its data type it invariably seen as a current calculated value.
    • Black text.This is a default that may be modified by the user. Changing defaults is not recommended until the user has some experience of Tinderbox. Enter a new value and press the Return key (↩) to commit the change.

    Suggested. Enter an optional list (semi-colon delimited) of suggested attribute values.

    Lines (shown for String/Set/List/Dictionary types only). A slider control allows a variable number of lines to be used to display String-type attribute values in the display tables of Displayed Attributes and Get Info/attributes. The default value is 1. The slider has seven stop positions running from left (1) to right (7).

    Displayed attribute for selected notes. Ticking this box will add the attribute as a displayed attribute to all currently selected items. In general this is a less useful way of adding Displayed Attributes than using the control at the top of the text pane. As changing the value here changes the note's $DisplayedAttributes, it is not the best method to set/manage Displayed Attributes if using prototypes as the edit may break inheritance of the attribute (more on Displayed Attributes). If some selected items do not use this Displayed Attribute and some do, the box remains un-ticked. Ticking it sets this for the whole selection.

    Description. This is a short description of the purpose of the selected attribute. Occasionally, this may be blank (though it implies nothing other than a missing label!). This description is shown as a tooltip when hovering over the attribute name (left) column of a Displayed Attributes table or the table in Get Info attributes sub-pane. The Description can also be accessed/exported via the attribute() action operator. Descriptions for system attributes cannot be edited by the user

    User Inspector

    This allows the user to view the current document's user-defined (i.e. custom) attributes. This Inspector allows the user to view and change their data type and default values.

    Attribute. This pop-up menu lists all User attributes already defined (otherwise the list is empty). Selecting a list item loads it into the Name box below the pop-up. The list is sorted case insensitively (i.e. A–Z, before a–z, before 0–9).

    Gear wheel button (right):

    • Delete user attribute. Press this option to delete the attribute currently shown in the Name box. See more detail below.
    • New user attribute. Press this option to add a new user attribute. See more detail below.

    Name. Shows the name of the selected Attribute. Also used for setting the name of a new attribute. This input rejects attempts to create an attribute name that contains operators like + or punctuation like ";".

    Type. The data type for the selected attribute. Open the pop-up to change the data type. The change is saved as soon as this control loses focus. The selected value (as a zero-based number) is recorded the document's XML attribute type definition for this attribute.

    Default. This box shows the program's default for the attribute's selected Type (more on data types). The value may be left as the default or set to a desired initial value.

    Suggested. Enter an optional list (semi-colon delimited) of suggested attribute values.

    sequential (tick-box). An option only for Number-type attributes. When ticked all notes, including existing notes are allocated a sequential number. Unused numbers, e.g. from deleted notes, are not re-used making the number also a unique identifier. Notes duplicated or copied/pasted are allocated a new number. Aliases use the original's value.

    Displayed attribute for selected notes. Ticking this box will add the attribute as a Displayed Attribute to all currently selected items (adding to existing Displayed Attributes if found). In general this is a less useful way of adding Displayed Attributes than using the control at the top of the text pane. As changing the value here changes the note's $DisplayedAttributes, it is not the best method to set/manage Displayed Attributes if using prototypes as the edit may break inheritance of the attribute (more on Displayed Attributes). If some selected items do not use this Displayed Attribute and some do, the box remains un-ticked. Ticking it sets this for the whole selection.

    Lines (shown for String/Set/List/Dictionary types only). A slider control allows a variable number of lines to be used to display String-type attribute values in the display tables of Displayed Attributes and Get Info/attributes. The default value is 1. The slider has seven stop positions running from left (1) to right (7).

    Description. This holds an optional user's description of the intent and/or usage of the attribute. This description is shown as a tooltip when hovering over the attribute name (left) column of a Displayed Attributes table or the table in Get Info attributes sub-pane. The Description can also be accessed/exported via the attribute() action operator.

    Creating a New User Attribute

    On selecting the option to make a new attribute, the Attribute pop-up will change to show 'NewAttribute'. The Name box is not refreshed; any previously shown attribute name is retained deliberately, in case it is to be used as part of the new attribute. Edit or delete the existing text to add the desired new value. The new attribute is created as soon as focus shifts away from the Name box. The default data type is 'string' and the default value is no value, i.e. an empty string. Optionally, a description of the attribute, e.g. its purpose, may be added. The latter description is only seen in this Inspector and when this attribute is selected.

    When a new attribute is created, the default value of that attribute is set to a conventional value. For example, the default value for a new numerical attribute is 0, and the default value for a new Boolean attribute is false.

    When a 'new attribute' is selected in a document where user attributes already exist, the existing selected attribute name is retained but all other value input boxes are reset to default.

    Altering an existing attribute

    Note: there is no undo for this operation.

    Select the attribute from the Attribute list. Name, Type, Default, Description and tick-box settings can all be changed. The changes take effect once focus moves off the edited input box. When a user attribute is renamed, the values of the old attribute are moved to the new attribute, and Displayed Attributes referring to the new attribute are updated to use the new attribute. But, before changing data type, do consider the effects: it may make more sense to make a new attribute of the desired type and use an agent to copy values across with whatever additional changes are needed over and above basic type coercion. Changes to the attribute name will update Displayed Attributes but do not update attribute names in action code (e.g. roles, edicts, etc.). If using action code in a TBX, consider this aspect before altering an existing attribute.

    When the type of an existing attribute is changed, the default value of that attribute is reset to a conventional value. For example, the default value for a new numerical attribute is 0, and the default value for a new Boolean attribute is false. When a 'new attribute' is selected, the existing selected attribute name is retained but all other value input boxes are reset to default.

    Deleting a User Attribute

    Select the attribute to be deleted sing the Attribute list. Once selected, choose the Delete user attribute option. The selected item is deleted immediately. Note: there is no undo for this operation.

    Colors Inspector

    This tab allows inspection and editing of the current documents defined colours, also termed named colours. By default all new Tinderbox documents have 29 defined colours. These comprise 10 greyscale colours named '0' though '9' (from light to dark) and 19 colours named for the actual colour ('green', bright red', etc.). The colours may be added to or deleted or the colour represented by the name may be changed. The named colours are listed here and their actual colours can be seen here, displayed using the built-in 'Tinderbox 7' scheme. That scheme is not the default scheme but give colours truest to the names used.

    Color. The pop-up menu shows the 28 defined colours in alphabetical order (0-9 then a-z). Any new user-added colours are listed at an appropriate place in this list. The list also includes the special system colour 'transparent'.

    Gear wheel button (right):

    • Delete color. Deletes the currently displayed named colour.
    • New color. Adds a new colour to the list. The default name is 'new colour' and the default colour is #999999. Both the name and colour value can be edited.
    • [rule]
    • Save Color Scheme… Opens a macOS file save dialog for saving the current colour scheme as a Tinderbox colour scheme (.tbc) file. The file is saved to the app's current folder. Note the 'color schemes' folder for making schemes available to all files via the app itself.

    Colour controls. There are two controls:

    • the colour chip shows the current colour defined. Clicking on the chip opens the OS' Colors dialog. Any picker on the dialog may be used to define a colour which is used to update the colour chip and the hexadecimal code for that colour.
    • the colour's defined value as a hexadecimal code (a hash (#) followed by six characters (0–9,A–F). A named colour cannot be defined using a variant of another named colour. Thus 'my red' cannot be given a named description like 'muted red'—it must be a hexadecimal value. Colour value may also be set be adding a valid hsv() or rgb() action code expression; once saved a hexadecimal value will replace the expression's code.

    Name box. This box shows the name stored for a defined colour. The name can be edited if desired. Note colours are case-sensitive - 'blue' and 'Blue' are treated as separate colours.

    Hidden tick-box (default un-ticked). Unwanted system colours can be omitted from colour menus and lists. To hide a colour, select it and tick the "Hidden" box. Hidden colours can still be used in rules and actions, and their definition can be changed in this Inspector. However, the hidden colours will not be shown in menus and pop-up colour lists.

    See more about Colours in Tinderbox.

    Stamps Inspector

    The top list box holds a list of all those Stamps configured for the current document. Clicking on an item makes its values appear in the other boxes on the form. The stamps are also listed in the Stamps menu for easy use.

    If the current document has the Built-in Hints folder with the Stamps container added, this tab can still be used to manage Stamps also viewable via the Stamps container. Code fields do not select the entire text after when gaining focus or after pressing the Return key (↩) to update (save changes). This lessens the chance of accidental deletion of existing code.

    Stamp list. This lists the names of all currently defined stamp. Any list items can be dragged to re-order them. Altering the listing order (see below) also updates the Stamps menu's listing order.

    - (minus) button. This deletes the currently selected stamp in the list

    + (plus) button. This adds a new stamp. The initial stamp name defaults to an unused name rather than previous "stamp name", making it easier to create short-lived, temporary stamps. If a stamp is selected when a new stamp is created, the new stamp is inserted immediately below the selected stamp and its initial name is derived from the selected stamp.

    Name. This shows the name of the currently selected Stamp. It is the also the name as seen listed in the Stamps Menu. The name can be changed by editing this box. Such change only affects the listing's title for the stamp, the action code is unaffected.

    Action. This holds the action code expression(s) to be applied by the Stamp. Typing in the box triggers auto-complete for action codes and (if using a $ prefix) any system or user attributes. The action code can be (e-)edited; the change is applied if the Return key (↩) is pressed or the box loses focus. Any subsequent use of the stamp will use the altered code. The code panel supports action code syntax highlighting.

    Apply. This button applies the currently loaded stamp to the view pane selection (of one or more items). The button label shows the $Name of the selected note or if a multiple selection, the number of items in the selection. When a single note is selected, the Apply button reflects the note's $DisplayName rather than its $Name, and the name is correctly encoded.

    Re-ordering the stamp list

    Any list items can be dragged to re-order them. Altering the listing order (see below) also updates the Stamps menu's listing order.

    Note that the listing order in the Inspector's list is not synched with the Hints' Stamps container, so the list order in the two may differ over time. The Stamps menu uses the Inspector's listing.

    Exporting & Importing Stamps

    Stamps can be dragged from the Stamps to Finder windows or the desktop. To import a stamp drag/drop a stamp file (.tbxstamp) from a Finder onto the view pane of a TBX document. To copy a stamp between TBX documents, export to Finder from the source document and then drag the stamp file into the target document.

    Properties Inspector

    The Properties Inspector data is selection-scoped, and displays note $DisplayName for the currently selected item; if more than one item is selected it shows the number of items in the selection (e.g. 'Visual Styling' for a single note of that name, but 3 notes selected shows '3 Notes').

    The Properties Inspector has these sub-tabs:

    Prototype Inspector

    This tab defines a number of special purpose tasks for notes. This can be opened directly via the shortcut [Cmd]+3.

    Prototype (list). This holds a list of prototypes defined for the current document. The current selection's prototype is pre-selected; default is 'none'. A prototype cannot use itself, but can use another prototype. So if a prototype is selected, it will be greyed out in the pop-up list.

    Prototype (tick-box). Ticking this makes the selected note into a prototype. This is just one means of setting a note's prototype. This sets This sets $IsPrototype.

    Template. Ticking this defines the note as being used to store code for an export template. This sets $IsTemplate.

    Separator. Ticking this defines the note as a separator and thus is visible only in Outline view. This sets $IsSeparator.

    Quickstamp Inspector

    The Quickstamp tab allows you to set a single attribute's value on one or more currently selected notes. It remembers the last used settings during the current session (i.e. until the TBX is next closed). Instructions for using this tab are below the description of the controls.

    Search box. This allows the user to start typing an attribute name that Tinderbox will attempt to auto-match, suggesting completions. If an item is matched (or clicked in the suggested match list), the tab will select the appropriate Group and Attribute names to populate the other controls. This box has focus when the dialog is opened via keyboard shortcut (Cmd+2).

    Group. This allows the user to select a name from a list of any of the defined groups of Tinderbox pre-defined System attributes, or the 'User' group of user-created attributes (if any).

    Attribute. This allows the user to select an individual attribute's data from the currently selected group (above). Read-only attributes as shown in italics. They can be selected, so their values can be viewed, but the cannot be edited. The meaning of the styling of different listed attributes (bold, strikethrough, etc.) is explained here.

    Default/value states. These are two bent-arrow (↴) buttons each with a label above it and to its left a value text:

    • Inherited value (left button). The value shown is the value to be inherited if different from the local value. Click the button to apply this value/inheritance to the current selection, and (re-)set inheritance. Labels for this button are either of:
      • default. Labels the value that is (or can be) inherited from the doc preference or doc's default for that attribute.
      • inherited. If the current note has a prototype (or all notes in a selection use the same prototype) this labels the value that is (or can be) inherited from that prototype.
    • Value assigned to this note (right button).The value shown is the inherited value (i.e. same as the above) or a local value particular to this note (and thus breaking inheritance). Click the button to re-apply this value to the current selection, e.g. if editing a complex experiment and making a mistake. Generally, if re-setting inheritance, use the left button. The label for this (right-hand) button is any of:
      • default value. This value is inherited from the doc preference or doc attribute default.
      • inherited from xxxx. This note (or selection uses the prototype named xxxx. The value shown is the prototype's value for that attribute.
      • assigned to this note. The value is set locally, breaking any inheritance of both doc defaults and prototype values. Setting an attribute value locally to the same as a prototype/default value does not restore inheritance. To do the latter use the left-hand assignment button above the input box.

    Value edit box. An input box for reviewing/changing the current value of the selected attribute for the current note. Altering the value and using the Apply button will set a local value for the selected attribute, for the current note selection. When Quickstamp is editing a Boolean attribute, it displays a checkbox in place of the value text field, which should make editing boolean attributes a bit easier.

    Existing value pop-up list. If the selected attribute is of String, List or Set data type, this pop-up shows existing unique values for the attribute (up to a maximum of 199 values; if more only the first 199 are shown). Clicking on a value in the list inserts it into the Input box.

    Apply button. Applies the Value box value to the selected item(s). With very large selections this may take a few seconds. Using the Return key (↩) acts as if clicking this button. The Apply button is disabled when editing Boolean attributes, since clicking on the Value checkbox applies the change immediately.

    Note: using this Inspector to set the value of $Prototype is just one way of setting a note's prototype.

    How to use the Quickstamp

    The Quickstamp acts on every selected item, be it one note/agent/adornment or several. The Quickstamp can be used in several ways:

    • Step 1. Setting the target attribute: First use the top three controls to select a particular system or user attribute. If the attribute name is known, type it in the Search box and select the attribute from the auto-complete list. This will configure the next two pop-ups—Group and Attribute. Or, use the latter manually, in turn to set an attribute Group (top) and Attribute within the selected group (bottom). In the illustration, a User (group) attribute 'WebImage' has been selected.
    • Step 2. Editing the attribute value. There are a number of different actions than can be taken:
      • Entering or editing a local value. This is done using the input box on the left side immediately above the Apply button. If no local (i.e. per-note) value is set, the inherited value is shown. If the latter is 'no value' (i.e. an empty string) the box shows a prompt text of 'value'. Enter the desired local value here; if the note already has a local value, simply change the entry to the desired new value. When ready, click the Apply button to save the change.
      • Using existing or suggested attribute values. When editing or entering a local value, it can be useful to simply use a value used for this attribute by other note(s) in the document, or to use suggested values if these are defined. In such a case, the Existing Value pop-up to the right of the value input box (i.e. right side above the Apply button) can be opened. Selecting a value from the pop-up list sets that as the text of the value box to its left. Any change made is not saved until the Apply button is saved.
      • Re-setting the inherited value. If a local value has been set, it is possible to re-enable inheritance of the document default or a prototype-set value by using the left-hand of the two bent-arrow (↴) buttons above the value editing box. Use the document button to save the change. The right-hand arrow button can used to reset the pre-existing local value, but only until the Apply button has been used, after which it functions like the left-hand button.

    Unlike editing attributes via a note's Displayed Attributes table or Get Info's attributes tab, altering an attribute via a Quickstamp (or stamp) does not alter $Modified.

    More Inspector

    This tab holds two setting associated with Map view use.

    Locked. A locked note or adornment is 'locked' to the map background. Moving the note moves the whole map. The locked state is stored in $Lock.

    Sticky. A sticky note or adornment means that when another note overlaps (on top of) it the latter is moved when the underlying note is moved. Sticky adornments are useful so that if the adornment is moved all the notes on it remain in place on the adornment and move with it. The stickiness state is stored in $Sticky. This control is disabled (greyed out) when the selected note is not an adornment.

    Appearance Inspector

    The Appearance Inspector data is selection-scoped, and displays note $DisplayName for the currently selected item; if more than one item is selected it shows the number of items in the selection (e.g. 'Visual Styling' for a single note of that name, but 3 notes selected shows '3 Notes').

    The Appearance Inspector has these sub-tabs:

    Interior Inspector

    This gives easy access for setting a number of appearance-related attributes of notes. The results are applied to all selected note(s).

    Color. There are 3 'standard' colour controls that set $Color:

    • Defined colour list pop-up menu.
    • Colour shade pop-up menu.
    • Custom colour picker dialog.

    Pattern. Sets $Pattern. Note that the inspector can only set static patterns and not dynamic patterns like bar()/vbar()

    • Pattern pop-up menu.
    • translucent option. Sets $Opacity to 50(%).

    Accent. There are 3 'standard' colour controls that set $AccentColor:

    • Defined colour list pop-up menu.
    • Colour shade pop-up menu.
    • Custom colour picker dialog.

    Shape. This sets $Shape to render the note's map icon in one of a number of shapes. Some shapes (such as tag or leaf) have addition attributes controlling the actual shape. These additional settings are stored in other attributes but can all be set manual via controls on the selected note when in map view. The list includes outlines of the basic shapes alongside the actual name, to aid correct selection.

    Badge. This sets the $Badge value via the Badge pop-up menu. The pop-up list only shows the default set of icons, showing the badge's icon and the name. Additional user sets can only be (visually) accessed via the badge widget on the selected item in the view pane. This control is wide enough such that the badge's name can be read.

    Large (tick box). When ticked a display box of 64x64 pixels is used instead of the default 32x32.

    Texture. This sets the $Fill value via the Fills pop-up menu. The list shows both default and user added textures.

    Add Badge. An image well accepts a drag-drop of a bitmap image as a custom badge.

    Border Inspector

    This gives easy access for setting a number of border appearance-related attributes of notes. The results are applied to all selected note(s).

    Color. There are 3 'standard' colour controls that set $BorderColor:

    • Defined colour list pop-up menu.
    • Colour shade pop-up menu.
    • Custom colour picker dialog.

    Style. Defines the border's style:

    • Border Style pop-up menu: sets $BorderBevel.
    • Dashed option: toggles $BorderDash between 0 if un-ticked and 5 if ticked.

    Width. Sets $Border to preset widths via Border Width pop-up menu (1/2/4). Default is medium (2).

    To set no border, select 'none' for the style. Note, that this is not exactly the same as setting both $Border and $BorderBevel.

    Shadow Inspector

    This Inspector pane, give easy access for setting a number of border appearance-related attributes of notes. The results are applied to all selected note(s).

    Shadow. Options for setting $Shadow to show/hide a shadow.

    • Distance. Sets $ShadowDistance.
    • Blur. Sets $ShadowBlur.
    • Color. There are 3 'standard' colour controls that set $ShadowColor:
      • Defined colour list pop-up menu.
      • Colour shade pop-up menu.
      • Custom colour picker dialog.

    Outline Inspector

    This tab controls aspects of the view of Outline view selected items. It as a single control:

    Color. There are 3 'standard' colour controls that set $OutlineBackgroundColor:

    • Defined colour list pop-up menu.
    • Colour shade pop-up menu.
    • Custom colour picker dialog.

    Color Swatch. This checkbox shows/hides the note's outline colour swatch. Feature discontinued and removed/deprecated in v9.5.2+ in favour of using $Flags (the outline shows (the first) defined flag in $Flags.

    Plot Inspector

    This tab gives controls for setting calculated patterns, such as for container plots.

    Pattern. The type of container plot expression. A pop-up list shows the options available. Static patterns are listed but should be ignored as they are not pertinent here.

    Expression. The container plot action code expression, i.e. the input argument used by the plot type. The input box and label are hidden if the selected pattern type does not support action code expressions.

    X axis. Only visible if xyplot() is the selected plot type. Second input argument for the xyplot() expression.

    Minimum. Optional maximum value for the Y axis. Only shown if a dynamic plot type is selected.

    Maximum. Optional maximum value for the Y axis. Only shown if a dynamic plot type is selected.

    Target. Optional value at which dotted line is drawn in $PlotColor. Only shown if the plot type is bar() or vbar(). Shown for all plot types except pie().

    Plot Color. Tinderbox colour controls to set the colour of the plotted data in a container plot ($PlotColor).

    Background. Tinderbox colour controls to set the colour of the container plot background for this note's Map ($PlotBackgroundColor). The slider is used to set the opacity of the plot's background; if transparent, the child map shows through ($PlotBackgroundOpacity).

    Defined plot pattern value. Grey text caption with the current contents of $Pattern, as defined by the settings above. If no plot type is set the value is given as the incomplete value 'bargraph()' and the preview winodw (below) remains blank.

    Preview window. A preview image of the above settings as a plot.

    Text Inspector

    The Text Inspector data is selection-scoped, and displays note $DisplayName for the currently selected item; if more than one item is selected it shows the number of items in the selection (e.g. 'Visual Styling' for a single note of that name, but 3 notes selected shows '3 Notes').

    The Text Inspector has these sub-tabs:

    Title Inspector

    This tab gives easy access for setting a number of view pane title-related attributes of notes. The results are applied to all selected note(s).

    Color. There are 3 'standard' colour controls that set $NameColor:

    • Defined colour list pop-up menu.
    • Colour shade pop-up menu.
    • Custom colour picker dialog.

    Alignment. Map icon tile alignment options; sets $NameAlignment.

    Size. The pop-up shows type point size which sets an underlying attribute value (in brackets). Two similar pop-up lists set notes' title size for Map view ($MapTextSize) and separately for Outline/Chart/Timeline views ($OutlineTextSize). The default is derived from the size being set in the Map Font control Maps pane of Document Settings: 14 point by app default. The stored attribute value is a percentage of magnification used to draw note titles, so 14pt maps to 100(%). Thus, if a note's $MapTextSize is 200, it will be twice as large as normally-sized items (e.g. 28pt vs. 14pt). If the underlying attribute is set to any other value than those below, the title's size is scaled accordingly but the pop-up list shows a blank selected value, though the others remain available:

    • 9 (stored value = 64, i.e. 64% of default base size)
    • 10 (71)
    • 12 (86)
    • 14 (100) default (set via Doc Settings: see above).
    • 16 (114)
    • 18 (129)
    • 24 (171)
    • 32 (229)
    • 48 (343)

    Bold. This option bolds the title ($NameBold).

    Strikethrough. This option set strike-through on the title toggles ($NameStrike).

    DisplayExpression. Displays/sets $DisplayExpression.

    Display Expression Enabled. Toggles $DisplayExpressionEnabled.

    Subtitle Inspector

    This tab controls settings for Subtitles, used in Map view only.

    Color. There are 3 'standard' colour controls that set the colour of the subtitle ($SubtitleColor):

    • Defined colour list pop-up menu.
    • Colour shade pop-up menu.
    • Custom colour picker dialog.

    Opacity. The slider sets the opacity of the subtitle ($SubtitleOpacity).

    Size. The slider sets the text size of the subtitle ($SubtitleSize).

    Subtitle. Displays/sets the subtitle text ($Subtitle).

    Caption Inspector

    This tab controls settings for Captions, used in Map view only.

    Color. There are 3 'standard' colour controls that set colour of the caption ($CaptionColor):

    • Defined colour list pop-up menu.
    • Colour shade pop-up menu.
    • Custom colour picker dialog.

    Opacity. The slider sets the opacity of the caption ($CaptionOpacity).

    Size. The slider sets the text size of the caption ($CaptionSize) as a relative percentage of map title size ($MapNameSize).

    Alignment. Sets the alignment of the caption ($CaptionAlignment).

    Subtitle. Displays/sets the caption text ($Caption).

    Caption. The text to be shown as the caption. Note: this is not an action code expression. To use the latter, evaluate the action code expression in some action and use it to set the value of $Caption.

    Hover Inspector

    This tab controls settings for Hover Expressions.

    Hover Expression displays/sets $HoverExpression.

    Color. There are 3 'standard' colour controls that set $HoverBackgroundColor:

    • Defined colour list pop-up menu.
    • Colour shade pop-up menu.
    • Custom colour picker dialog.

    Opacity. Alters the note's $HoverOpacity.

    [image file]. Drop a bitmap image here to set $HoverImage. When an image is set, the blue bar shows the path to the image asset.

    Clear. Button is only enabled if a $HoverImage is set. Click to clear the existing image.

    Text Inspector

    This tab controls settings for note text ($Text). The primary role of the Text pane of the Text Inspector is to change the default text style of new notes. In addition, using this pane to change the text colour, line spacing, or paragraph spacing immediately changes the text ($Text) of currently-selected notes.

    Color. There are 3 'standard' colour controls that set the colour of the note's default text ($TextColor):

    • Defined colour list pop-up menu.
    • Colour shade pop-up menu.
    • Custom colour picker dialog.

    If trying to set text colour for pre-existing $Text content, note that above colour controls only configure the note's default text colour. To colour all or a selected part of already-existing $Text use either the Format ▸ Style or Format ▸ Font menus.

    Paragraph Spacing. Pop-up menu controls $ParagraphSpacing. Default is 8pt (set via preferences).

    Line Spacing. Pop-up menu controls $LineSpacing. Default is 100%. Set larger percentage values to increase line spacing and vice versa.

    Don’t check spelling. Toggles $NoSpelling for selected notes.

    Smart Quotes. Overrides default substitution settings for straight-to-curly quote correction ($SmartQuotes).

    Read Only. Toggles the note's read-only state (default: un-ticked, read/write), stored in $ReadOnly.

    Ziplinks. Toggles the note's ability to create Text link creation via the Ziplinks method (default: ticked, on), stored in $Ziplinks.

    Searchable. Toggles the note's searchable status (default: ticked, on), stored in $Searchable.

    Export Inspector

    The Export Inspector data is selection-scoped, and displays note $DisplayName for the currently selected item; if more than one item is selected it shows the number of items in the selection (e.g. 'Visual Styling' for a single note of that name, but 3 notes selected shows '3 Notes'). A minor exception is that the 'Export to' control on the Export sub-tab which works at document scope. In older versions, this Inspector was called the HTML Inspector.

    The HTML Inspector has these sub-tabs:

    Export Inspector tab

    The settings in the Export tab control whether notes export, their templates and the export location. All are selection-scope except 'Export to' that applies to all notes in the document.

    Export. Controls whether the current note is exported when a file level 'Export as HTML…' operation is invoked. If this box is checked, this note will be exported to HTML when you export the document. Having this box ticked is equivalent to setting the $HTMLDontExport attribute to false.

    Export Children. Controls whether the current note's children are exported when a file level 'Export as HTML…' operation is invoked. If this box is checked, this note's children will be exported to HTML when you export the document. This box being ticked is equivalent to setting $HTMLExportChildren to true.

    Markup Text. If this box is checked (true), Tinderbox's export to HTML attempts to translate text styles, such as italics, boldface, and relative size, as well as elements that look like headings or lists, to similar text styles using HTML mark-up. If this box is unchecked, Tinderbox exports the text of the note without any added HTML mark-up codes. This box being ticked is equivalent to setting $HTMLMarkupText to true.

    Quote HTML. If ticked (true), any HTML markup detected in the note is converted to HTML entities on export so it is seen on screen as code instead of being rendered as HTML code. This box being ticked is equivalent to setting the $HTMLQuoteHTML attribute to true.

    File Name. When Tinderbox exports a note to HTML, it automatically generates a name for the HTML file base on the note's title. If you want a note's file to have a specific name—so that you can know what name to link to from another web site, for instance—enter a name here. An entry here is equivalent to setting an $HTMLExportFileName attribute value; if no name is pre-set, the name is generated on the fly when exporting, based on the note name, $HTMLFileNameLowerCase, $HTMLFileNameMaxLength and $HTMLExportExtension attribute settings (if not modified on the HTML view itself).

    Extension. The file extension suffix that should be added to the filename for the HTML file: the default is normally '.html'. Setting a non-default value is equivalent to setting the $HTMLExportExtension attribute. Note the value should include a period as the first character.

    Template. The Template pop-up list shows the available templates within the document. The default is 'none' but as soon as a single template is added, thus becomes the default. The chosen value is stored in $HTMLExportTemplate.

    Export to. The default configuration is for external export, with the top button label (the export location) unset. On first use of the Export (HTML) menu, the user will be prompted to set the export folder location. This feature uses two buttons:

    • Export folder location. If clicked this opens a folder chooser dialog and to allow setting the export folder to be used when exporting the whole document—see the Export menu). If the document has been set to use an internal location, e.g. for internal preview only, the button caption is '(temporary folder)'.
    • A second, button allows (re-)selection of the hidden internal location used for zero-configuration internal preview.

    Markup Inspector

    These settings in the Paragraph tab control the markup of HTML text paragraphs:

    • First paragraph. These fields specify what HTML markup should surround the first paragraph of text when the text of this note is exported to HTML. They default to <p> and </p>. Stored in $HTMLFirstParagraphStart and $HTMLFirstParagraphEnd attributes.
    • Subsequent paragraphs. Defaults are as above, but for all other paragraphs of text in the text of the note. Stored in $HTMLParagraphStart and $HTMLParagraphEnd attributes.
    • Indented. As above but for all paragraphs beginning with a tab character; such paragraphs will use <blockquote>. Stored in $HTMLIndentedParagraphStart and $HTMLIndentedParagraphEnd.
    • Before and after note. Empty by default, this is what is exported immediately before a note's opening paragraph mark-up and after a note's final paragraph market, respectively. In effect, mark-up to enclose ^text^. Can be useful in connection with CSS stylesheets, such as setting before and after to <div> and <div>. Stored in $HTMLExportBefore and $HTMLExportAfter attributes.

    Style Inspector

    The settings in the Style tab control styling of HTML text.

    Bold. The start and end fields hold the opening and closing tags for bold text and default to <b> and </b>. Stored in $HTMLBoldStart and $HTMLBoldEnd.

    Italic. The start and end fields hold the opening and closing tags for italic text and default to <i> and </i>. Stored in $HTMLItalicStart and $HTMLItalicEnd.

    Underline. The start and end fields hold the opening and closing tags for underlined text and default to <u> and </u>. Stored in $HTMLUnderlineStart and $HTMLUnderlineEnd.

    Strike through. The start and end fields hold the opening and closing tags for struck-through text and default to <strike> and </strike>. (Equivalent to setting the $HTMLStrikeStart and $HTMLStrikeEnd).

    Code. The start and end fields hold the opening and closing tags for $Text using the 'Code' font style. They default to <code> and </code>. Stored in $HTMLCodeStart & $HTMLCodeEnd.

    List Inspector

    The settings in the List tab control styling of lists in HTML text.

    Unordered. The before and after fields hold the opening and closing tags for unordered (bulleted) lists and default to <ul> and </ul>. Stored in $HTMLListStart and $HTMLListEnd.

    Ordered. The before and after fields hold the opening and closing tags for ordered (numbered) lists and default to <ol> and </ol>. Stored in $HTMLOrderedListStart and $HTMLOrderedListEnd.

    List item. The before and after fields hold the opening and closing tags for an italic passage and default to <li> and </li>. Stored in $HTMLListItemStart and $HTMLListItemEnd.

    Macro Inspector

    The settings in the Macro tab control the creation and storage of macros both for HTML export and for use within the current document for the current document.

    Gear wheel button (at left):

    • Delete macro. Deletes the currently selected macro. There is no undo for this option.
    • New user attribute. Press this option to add a new macro. A new macro 'newMacro' is added to the macro list and selected ready for editing.

    Macro list. A pop-up menu lists all currently defined macros. Select an item to load its details for review or edit. The name of the selected macro is shown in the Macro name box (below). The code inserted by the selected macro is shown in the Macro code box (below)

    Macro name. The name of the currently selected macro.

    Macro code. Holds the code to be evaluated when the Macro is invoked. See the article on macros to explain the process.

    Action Inspector

    The Action Inspector data is selection-scoped, and displays note $DisplayName for the currently selected item; if more than one item is selected it shows the number of items in the selection (e.g. 'Visual Styling' for a single note of that name, but 3 notes selected shows '3 Notes').

    The Action Inspector has these sub-tabs:

    Query Inspector

    The Query tab is used for agents (and smart adornments) only.

    The main input box is used for adding or editing a query ($AgentQuery). Pressing the Return key (↩) commits any changes made and runs (or updates) the query. The code box has auto-completion for action code and attribute names (based on using a $-prefix). The code box supports syntax colouring.

    Code fields do not select the entire text after when gaining focus or after pressing the Return key (↩) to update (save changes). This lessens the chance of accidental deletion of existing code.

    The number of items currently matching the query, i.e. the child count of the agent is show at top right.

    Priority. This pop-up menu controls whether the agent is 'on' or not. Sets $AgentPriority. See more on controlling agent priority.

    Cleanup. This pop-up menu sets the agent's cleanup action ($CleanupAction).

    Smart adornments use neither a Priority or Cleanup actions so both these pop-ups are greyed out if a smart adornment is selected.

    Note that an agent's query, action and priority can also be set from the agent tab of the Get Info pop-over.

    Action Inspector tab

    The Action tab is used to set the OnAdd ($OnAdd) action of notes and adornments or the agent action ($AgentAction) of agents.

    The main input box is used for adding or editing the action code. Pressing the Return key (↩) commits any changes made and runs (or updates) the query. The code box has auto-completion for action code and attribute names (based on using a $-prefix). The code box supports syntax colouring.

    Code fields do not select the entire text after when gaining focus or after pressing the Return key (↩) to update (save changes). This lessens the chance of accidental deletion of existing code.

    Note that an agent's query, action and priority can also be set from the agent tab of the Get Info pop-over.

    OnAdd also affects adornments created or pasted into containers.

    Rule Inspector

    The Rule tab is used to set the rule ($Rule) action of notes, adornments and agents.

    The main input box is used for adding or editing the action code. Pressing the Return key (↩) commits any changes made and runs (or updates) the query. The code box has auto-completion for action code and attribute names (based on using a $-prefix). The code box supports syntax colouring.

    Code fields do not select the entire text after when gaining focus or after pressing the Return key (↩) to update (save changes). This lessens the chance of accidental deletion of existing code.

    Inheritance state. A caption above and right of the code box indicates the inheritance state of the rule. Captions are:

    • default. Uses document default.
    • inherited. Uses an inherited (prototype) value.
    • (no caption). The rule is set locally in the note.

    Enabled. This toggles disabling of the rule ($RuleDisabled). When un-ticked the rule's code is not evaluated as part of the rule cycle.

    Run Now button. This runs the rule immediately, once: the rule is added as a single task to the pending work queue. If the rule is disabled, this button is disabled. The button also updates the Displayed Attributes table.

    Remove Inspector

    From v11.7.0, this is replaced by the Action Inspector Other pane.

    The Action tab is used to set the On Remove ($OnRemove) action of notes and adornments. For agents, this action is performed on the original of the agent alias.

    The main input box is used for adding or editing the action code. Pressing the Return key (↩) commits any changes made and runs (or updates) the query. The code box has auto-completion for action code and attribute names (based on using a $-prefix). The code box supports syntax colouring.

    Code fields do not select the entire text after when gaining focus or after pressing the Return key (↩) to update (save changes). This lessens the chance of accidental deletion of existing code.

    Note that for agents this action cannot be set from the 'agent' pane of the Get Info pop-over.

    Immediately before a note is deleted, the OnRemove action of its parent container is performed. If the note lay on an adornment, the adornment's OnRemove action is performed. In the actions, the effect is bound to the note that will be removed.

    The that designator is bound to the container from which this note was removed. The change improves dealing with actions referencing other notes (including the ex-parent container) during action run by the event.

    Other Inspector

    From v11.7.0, the Remove pane is replaced by the Other pane, which lists all the other actions in a popup menu button, listing a series of less frequently used actions. The actions listed are:

    • OnRemove. See $OnRemove. Immediately before a note is deleted, the OnRemove action of its parent container is performed. The OnRemove action for agents is applied to the original note, since the alias will be deleted. If the note lay on an adornment, the adornment's OnRemove action is performed. In the action, the effect is bound to the note that will be removed.
      • The that designator is bound to the container from which this note was removed. The change improves dealing with actions referencing other notes (including the ex-parent container) during action run by the event.
    • OnMouseDown. ($OnMouseDown). The action performed in map view when mouse cursor is pressed: see mouse actions.
    • OnMouseDrag. ($OnMouseDrag). The action invoked while the mouse is down if the mouse is moved and the note is locked: see mouse actions.
    • OnMouseUp. ($OnMouseUp). The action performed in map view when mouse cursor is released: see mouse actions.
    • OnPaste. See $OnPaste. The OnPaste action is performed when a note is pasted, either into the same document or into a new document. If more than one note was copied, OnPaste is called after this note has been created, but may be called before other notes have been created.
    • OnVisit. See $OnVisit. In Storyspace, an action performed when the reader visits the note. This is honoured in Tinderbox and can be used as an 'OnSelection' event trigger.

    For agents, note that:

    • these actions are performed on the original of the agent alias.
    • these actions cannot be set from the 'agent' pane of the Get Info pop-over.

    The main input box is used for adding or editing the action code. Pressing the Return key (↩) commits any changes made and runs (or updates) the query. The code box has auto-completion for action code and attribute names (based on using a $-prefix). The code box supports syntax colouring.

    Code fields do not select the entire text when gaining focus or after pressing the Return key (↩) to update (save changes). This lessens the chance of accidental deletion of existing code.

    Edict Inspector

    The Edict tab is used to set the edict ($Edict) action of notes, adornments and agents.

    The main input box is used for adding or editing the action code. Pressing the Return key (↩) commits any changes made and runs (or updates) the query. The code box has auto-completion for action code and attribute names (based on using a $-prefix). The code box supports syntax colouring.

    Code fields do not select the entire text after when gaining focus or after pressing the Return key (↩) to update (save changes). This lessens the chance of accidental deletion of existing code.

    Inheritance state. A caption above and right of the code box indicates the inheritance state of the edict. Captions are:

    • default. Uses document default.
    • inherited. Uses an inherited (prototype) value.
    • (no caption). The edict is set locally in the note.

    Enabled. This toggles disabling of the edict ($EdictDisabled). When un-ticked the edict's code is not evaluated as part of the rule cycle.

    Run Now button. This runs the edict immediately, once: the edict is added as a single task to the pending work queue. If the edict is disabled, this button is disabled. The button also updates the Displayed Attributes table.

    Sort Inspector

    The sort tab is used to control the sorting of containers, adornments and agents.

    Sort by / (transform type) / reverse. Optionally, sets a sort order on any attribute value (pop-up menu), a transform on the order (pop-up menu), with the sub-option of reversing that order (tick-box). Values are persisted in the agent's $Sort, $SortTransform and $SortBackward attributes. This may be edited.

    and by / (transform type) / reverse. Optionally, sets a sort order on any attribute value (pop-up menu), a transform on the order (pop-up menu), with the sub-option of reversing that order (tick-box). Values are persisted in the agent's $SortAlso, $SortAlsoTransform and $SortBackwardAlso attributes. This may be edited.

    Important: note that the (also)transform is only applied if an (also)sort target attribute is set. Only setting a transform has no effect.

    Both sets of selector controls offer a Search box to assist in quickly locating the desired attribute on which to sort. Entering "none" in the search field, or clearing the search field and pressing the Return key (↩), will remove any local value for the $Sort attribute thus restoring the inherited or default value if any.

    Sort order depends on the data type of the attribute being used for sort, e.g. lexical vs. numerical vs. date, etc. In languages using accented characters, relative lexical sort order of accented characters may vary by locale.

    Once set, Tinderbox continues to sort new items to reflect that setting. However, it is often the case that contents are not under constant change and all that is needed is a one-off sort. To do this, select the desired sort attribute, wait a few moment for the sort to occur and then return the setting to do not sort.

    Sorting agents to reflect the relative outline location of original notes: to do this set the agent's transform type to 'original note' and leave sort as 'don’t sort'.

    When a container’s sort method is don’t sort, the reverse sort flag is ignored.

    A change to sort order ($Sort, $SortAlso) in a number of contexts triggers a container to re-sort.

    The meaning of the styling of different listed attributes (bold, strikethrough, etc.) is explained here.

    Dialogs

    The Preference dialog panes are described here. View windows are described here. All other dialogs are described below.

    To close pop-over dialogs, either click outside the dialog or use the Escape key (⎋ or 'Esc').

    When clicking outside the dialog, do not click on the calling object. Thus, if opening a pop-over from the text pane, click in the view pane. For a pop-over in the view pane click the text pane or—for some pop-overs—anywhere in the view except the currently selected note.

    About Tinderbox dialog

    This dialog shows the application's 'About' dialog and information about the application.

    Add Displayed Attributes pop-over

    This pop-over allows the Displayed Attributes table for the current note to be defined (or re-edited; attributes can be added to or deleted from the table and their order changed. The pop-over is invoked either from the head of the text pane's text tab or via the View menu.

    To add an attribute, either:

    • Type the desired name in the box in the upper section of the pop-over. Autocomplete is offered for all currently defined system and user attributes. The box is blank if no Displayed Attributes have yet been defined. If large numbers of attributes are added, the box will auto-expand to keep existing attribute choices on view.
    • use the two bottom lists. First select the attribute group in the left pane then tick the appropriate attribute in the right pane (un-ticking will also remove an existing item).

    To delete a current Displayed Attribute, click to select the item in the top list and delete it. Or, use the lower two panes to find the item and un-tick it.

    To re-order Displayed Attributes, click on an item in the upper list box and drag it to the correct location in the list.

    To remove all current Displayed Attributes (and reset inheritance of $DisplayedAttributes) click the Reset button. The Reset button removes the viewed note's immediate Displayed Attributes settings, so that the inherited or default Displayed Attributes will be used. (Formerly, it could copy those Displayed Attributes as an immediate value, temporarily interfering with inherited changes to the prototype or default.)

    To close the pop-over click outside it or press Escape. On closing, the changes made (above) are effected. If the top box contains a name that does not match a currently defined attribute, the Define new Displayed Attributes pop-over will then open.

    The Displayed Attribute picker ignores proposed Displayed Attribute names that cannot refer to attributes, such as "3cats" and "My sprocket" that may result from mistyping attribute names.

    The meaning of the styling of different rows (bold, strikethrough, etc.) is explained here.

    The Displayed Attributes picker is not limited to characters in the Roman alphabet.

    Attribute Browser Action pop-up

    Called from the Attribute Browser controls, this pop-up is used to configure an optional query.

    Description: The description entered here is used as a label on the main control panel.

    Action: Enter any action code expression, as with a rule or agent action.

    Attribute Browser Export

    A standard OS folder dialog called when exporting an Attribute Browser view.

    Attribute Browser Query pop-up

    Called from the Attribute Browser controls, this pop-up is used to configure an optional query.

    Description: The description entered here is used as a label on the main control panel.

    Query. Enter a valid query such as for an agent.

    Badge pop-up picker

    Called from the badge control of main pane note icons, this picker gives a visual picker for available badges. The badge selection is stored, via its string name, in $Badge.

    The Badge Picker offers a Search field. When using the search field, Tinderbox displays badges from any family that match the string typed in the search field. Clear the search field to view badges by family. In addition to matching the name of the badge, the picker also searches for words semantically related to the searched-for (English) word. Thus, searching for "flight" will locate the badge "airplane".

    The range of badges shown depends on the built-in sets and any added by the user. The pickers tabs are (left to right):

    • User. Any custom badge artwork placed directly into the 'badges' folder within Tinderbox's application support folder.
    • Classic. The primary set of badges (default tab selection)

    *User folders… The folder names—if any—of each discrete folder of custom badges placed into the 'badges' folder within Tinderbox's application support folder. Each per-folder tab's name is the folder name (case-sensitive labels).

    • Avatars. Built-in set.
    • Icons. Built-in set.
    • Symbols. Built-in set.
    • Recent. From v11.7.0, displays the most recently used badges in this document up to a maximum of 14 items.

    To close the pop-over click anywhere outside it.

    The Badge Picker adopts the prevailing background colour in dark mode. Monochrome icon families are drawn in white over a dark background, and in black over a light background; colour families are drawn normally.

    Setting a badge

    Click on any badge to set the note's $Badge.

    Removing a badge

    Clicking the first (blank) tile, top left in any set, deletes the badge by resetting $Badge to the default inherited state (of no badge).

    Changing the existing badge

    Clicking another badge when one is already set simply replaces the existing badge with the new choice.

    Finding the text name of a badge

    Place the mouse cursor over any icon, without clicking, and after a brief pause the icon's name is shown as a tool-tip. Names are case-sensitive and all built-in badges use all-lowercase.

    Using system font symbols

    If built-in or custom selections of badges do not suffice, it is possible to use Badges from the macOS 'SF Symbols' font. The latter has been part of macOS since OS 11, and subsequent releases have added to the range of symbols In the font. The overall symbol set is so large that they cannot all be easily displayed in the Badge picker, but if searching for icons, items matched from SF Symbols are displayed in the 'Symbols' sub-pane (see above) of the badge-picker pop-over.

    These system symbols often use a dot chained naming syntax. For instance, the 'star.leadinghalf.filled' is a star shape, with its left side having a solid fill. So when searching, using 'star.' might be a better scoping of the search than 'star' (without the trailing period).

    To use an SF Symbols icon either:

    • click the desired badge in the Badge picker pop-over after doing a search
    • set the desired icon name applying the prefix 'sf-', thus SF Symbols icon 'star.leadinghalf.filled' is set as a $Badge value (e.g. via action code or paste) as sf-star.leadinghalf.filled.

    Chart Settings controls

    This is the control panel for the current Chart view:

    • Border. Default: un-ticked. If ticked a thin border is drawn around each item on the chart. XML setting. XML setting: hasBorder.
    • Vertical. Default: un-ticked. If tick-ed, the chart is drawn from top-to-bottom of the screen as opposed to the default left-to-right layout. XML setting: isVertical.
    • Centered. Default: ticked. If un-ticked, the item top aligns (default layout) or left aligns (vertical layout) with the line from the parent item. XML setting: isCentered.
    • Item Width. Scrubber control sets the width (pixels) of chart items, including icon, title and elements in between. XML setting: itemWidth.
    • Vertical Spacing. Scrubber control sets the amount of vertical y-axis spacing (pixels) between chart items. XML setting: yspace.
    • Horizontal Spacing. Scrubber control sets the amount of horizontal x-axis spacing (pixels) between chart items. XML setting: xspace.
    • Connecting Lines. XML setting: lineType. A pop-up with possible values:
      • Orthogonal. (Default) Lines interconnecting items are drawn using horizontal and vertical sections.
      • Straight. Lines interconnecting items are drawn using straight lines.
      • Curved. Lines interconnecting items are drawn using bezier curves.

    Cleanup view tab

    A view tab called from the Arrange menu. The cleanup is effected on the map view selection, if 2 or more notes are selected, otherwise the whole map is cleaned up. Use Undo (Cmd+Z) if you make a mistake. The clean-up layout is anchored on the map position of the note with the lowest $OutlineOrder value. Options are:

    • Method. This opens a pop-up:
      • To Grid. (default) Rearranges all the notes in the map into a rectangular grid.
      • To Row. Arranges all icons in a single horizontal row.
      • To Column. Arranges all icons in a single vertical column.
      • To Box. Arranges all notes in an open rectangle. Best with more than 8 notes.
    • Spacing. (default: 1) This is the spacing in map units between the nearest edges of items. Thus, in a row layout, the left edge of the second item with be 1 map unit to the right edge of the first item.
    • Staggered. (default: not ticked) Ticking this box produces a staggered layout if 'to grid' is selected above. It has no effect with other layout methods. Tthis control is only enabled when the grid layout method is selected.

    On completion of a cleanup operation the map will be scrolled, if necessary so that some notes are in view. If the whole map is being re-arranged, this will normally be the top left corner of the map.

    Column view, column format pop-up

    This pop-up is displayed when a column head in Column view is clicked. There are 4 controls:

    *Attribute. Default value: 'Attribute'. Edit this to the name of any existing attribute, but do not use a $-prefix. Auto-complete is provide to aid completion. It is possible to enter a value for an attribute that does not currently exist, as with the default value, in which case no data will be displayed.

    *Width. Default: 100. Width of the column (in pixels).

    *Decimals / Format (if attribute is Date-type). Default: 2. The number of decimal places to use. For Date-type attributes, date format strings can be used. By default, date attributes show the user's locale's short-form date only. Booleans are shown as tick boxes. A deliberate exception is $ID which is presented as a string of numbers (its normal use).

    *Delete. Click to delete the current column.

    Crosstabs view axis configuration pop-over

    This pop-over dialog is shown when clicking either the button to the right of either the Rows or Columns labels on the Crosstabs view toolbar. The default Row attribute is $Name, and for columns it is $Height. XML settings: xattribute, xattribute2.

    Search box. Type the name of an attribute (with auto-completion) to locate the group/name of the desired attributes. Pressing Return with a valid attribute name will correctly configure the group and name pop-ups below.

    Maximum Bins. Either type a number in the box (between 1 and 24) or use the up/down control to set the desired number of bins for distribution of the results in the Crosstabs matrix. This control and its label are hidden if/when the control below is ticked. XML settings: xbins, xbins2.

    Unlimited Bins. Tick this to override the above control and to show as many bins as there are discrete values (e.g. for String-based attributes). Ticking this control temporarily hides the Maximum Bins control. XML settings: xunlimited, xunlimited2.

    Numbers of bins. For some data types there are additional default behaviours:

    • Boolean attributes always have exactly two bins.
    • Set and List attributes always have unlimited bins, allowing each tag or element its own bin.
    • Date attributes: if the date "never" is present, it is always placed in its own bin.

    Crosstabs view secondary configuration pop-over

    This pop-over dialog is shown when clicking either the button to the right of either the Display or Bar labels on the Crosstabs view toolbar. The default Display attribute is $DisplayName, and for Bar it is $OutlineOrder. The Bar attribute must always be numeric: the Bar selection offers autocompletions only for numeric attributes. XML settings: xdisplayattribute, xbarattribute.

    Search box. Type the name of an attribute (with auto-completion) to locate the group/name of the desired attributes. Pressing Return with a valid attribute name will correctly configure the group and name pop-ups below.

    Custom Color colour picker dialog

    Most colour menus provide a clickable colour swatch which both displays the chosen colour and, when clicked, lets you select any colour you wish. If no colour is set the colour chip defaults to a mid-grey.

    Customize Toolbar panel

    A self-explanatory panel used for customising the toolbar on document windows.

    Dance pop-up

    Called from the View > Arrange menu. This control panel provides controls over the "dancing" force-directed layout algorithm.

    • Stop/Start toggle buttons. This turns the dance on/off, using the current settings as set below.
    • Link Length. This controls the distance between linked notes.
    • Stiffness. This controls the tension of the spring between linked notes.
    • Compactness. This controls the distance at which unlinked notes neither attract nor repel each other. Even unlinked notes attract each other at long distances. Notes also repel each other at short distances.
    • Jostle. This adds some random motion to each note, and continues to add decreasing amounts of random motion for the next several seconds. The magnitude of the random motion can be adjusted from gentle to firm.
    • Finish. This button closes the dialog. It does not cause the current setting to be re-applied, i.e. it closes the dialog without further 'dance' actions.

    Date picker pop-over

    If an attribute of the 'Date' data type shown in Displayed Attributes, the Displayed Attributes picker and the Get Info attributes tab will show a date-picker widget that opens a date-picker pop-over.

    The pop-over shows the days of the current month (as per the user's OS locale), with today marked in red. Clicking any day will set that day, with current system time, for the attribute. The top control allows the dates shown to be shifted earlier (left) or later (right) in one month increments. Special buttons are provided to allow quick setting of today or tomorrow as the attribute's value.

    Define new Displayed Attributes pop-over

    If an unidentified attribute is specified in the Add Displayed Attributes pop-over, this pop-over is shown. For each undefined item if it is a valid attribute name it is listed with a pair of controls, or else it is ignored.

    For each listed item 2 controls are shown:

    • Create. If ticked, a new attribute of this name is created when the pop-over is dismissed and added to the current note's Displayed Attributes. If left un-ticked (default) a new attribute is not created.
    • pop-up list. This lets the user choose the data type of attribute to create. The default is to create a String data type.

    Clicking outside the pop-over or pressing Escape will close the pop-over and create any ticked items. Leave all items unticked if no new attributes are desired.

    Edit Background dialog

    This pop-over aids customisation of main pane backgrounds. Used by Outline, Chart, Map, and Treemap views. Controls are (some are used only in Map view—revised for v11.7.0):

    • Color. A standard trio of colour controls allow setting of $MapBackgroundColor. This forms the main background colour of views in the view pane.
    • Pattern. A list of static patterns is used to set $MapBackgroundPattern.
    • Color. A standard trio of colour controls allow setting of $MapBackgroundAccentColor. This is used as the accent colour in the background if a pattern is set.
    • Fill. A texture list allows setting of $MapBackgroundFill, using a fill texture instead of a pattern or plain background.
    • Opacity. Sets the fill opacity ($MapBackgroundFillOpacity).
    • Hide breadcrumbs. Toggles view's breadcrumb bar (default: un-ticked).
    • [Shown in Map view only]:
      • Display Link Stubs. Toggles the visibility of link stubs (default: ticked).
      • Animate Links. Toggles link animation of outbound links of the selected note(s) (default: ticked).
      • Hide link controls. Toggles the visibility of link configuration controls (default: un-ticked).
    • Use Inherited settings. Restore the current background to document default settings.
    • Save Settings As Default. This does the reverse of the above and uses the current background settings to set them as the document default settings.

    Emoji & Symbols pop-over

    This pop-over (called 'Special Characters', pre-Yosemite) gives easy access to a visual picker for emoji symbols and special non-letter characters.

    Error List pop-over

    When action code errors occur that Tinderbox wants to bring to your attention, an orange marker is shown in the top left corner of the Text pane's title bar.

    There is no exact listing of what triggers a listing, but primarily the feature exists to flag up un-parsable agent queries and action or similar rules and edicts.

    The pop-over shows a list of error items. Each item describes and error and then path of the note to which it refers.

    If an error is resolved, e.g. a broken query is fixed, it is removed from the list. If the entire error queue is emptied the orange marker is removed.

    Double-clicking on an item causes it to clear from the list, which is useful if there are several entries or if the user wishes to ignore the error and not be reminded.

    Explode pop-over

    This dialog is called from the Note menu. It allows you to split a large text file into several smaller text notes and to specify both where Tinderbox should make the divisions and how the notes should be titled. Make sure to also read the note on Exploding Notes for more detail of the overall process and options available.

    The choices for splitting content are:

    • Break at paragraphs. Breaks each paragraph into a new note (default option).
    • Delimiter. Break on a delimiter. A box for entering the delimiter and the delete delimiter tick-box are hidden when this option is not selected.
      • Custom delimiter string: see below.
      • Delete delimiter. Only available if the 'Delimiter' option is set (default = not ticked). Tick this to remove the specified delimiter from the new exploded notes. When the delimiter is a complete line/paragraph, ensure the string used includes the line return character at the end or some output notes will have text starting with a blank line. Tinderbox remembers the last-used custom delimiter until the end of the current session
    • Title. This controls what text is placed into the title of each newly split note. Text is still truncated with an ellipsis if greater than c.512 characters (in older version pre-v5 it was c.64 characters). Within this overall limit, the title can based on sentences or paragraphs in the exploded note's $Text. A 'sentence' is delimited by the occurrence of a terminating period, exclamation mark or question mark, a paragraph is delimited by a line return (line break). Sentence/paragraph detection is discussed in more detail under the main article on Exploding Notes.
      • first sentence. Only the first sentence forms the new title.
      • first two sentences. Only the two sentences form the new title.
      • first paragraph. Only the first paragraph is used for the new title.
    • [Text options]:
      • Remove title from text. If selected the text used for the above choice is deleted from the new note's body text.
      • Omit text. This results in only a $Name being set for new notes and no $Text.
    • Action. Allows a simple action to be inserted that is applied to each newly exploded note by setting an $OnAdd for the 'exploded notes' container created by the process. It is useful for tasks like applying a prototype to all new exploded notes. See the main Exploding Notes article for use of the 'Exploded Notes' built-in prototype if using large amounts of code here.
    • Example. Gives a preview of the $Text of the first exploded note. A control below the preview allows cycling through a preview of successive exploded notes.
    • Explode button. Click to start the Explode process using the choices set above. The Return key (↩) will also start the Explode process.

    Export as Outline panel

    On selecting Outline as the export type in the Export sub-menu, a configuration panel is shown. The format choices available are:

    • RTF (i.e. styled text)
    • text
    • doc

    When exporting to RTF or doc formats, list styles are used. A pop-up offers a choice of list styles:

    • I. A. 1. (Harvard).
    • (bullet)
    • 1. (numbered)

    After selection, click OK, and the Export folder dialog is shown.

    Export as Text panel

    On selecting Text as the export type in the Export sub-menu, a configuration panel is shown. The default format for export is RTF, but other formats are available:

    • RTF. (styled text)
    • Word® (older versions used doc).
    • text. (plain, un styled, text)
    • OPML. Exports the selected scope in OPML format. If necessary, the relevant built-in templates and prototype are added to the document to facilitate the export before it occurs.
    • Scrivener. Exports the selected scope in Scrivener (OPML) format. If necessary, the relevant built-in templates and prototype are added to the document to facilitate the export before it occurs.

    The controls are:

    • list of formats. Choices as above.
    • include titles (styled text, Word, and text formats only). This includes the note titles ($DisplayName) as well as their $Text. If this is not ticked, the following title-related controls are hidden:
      • Title Size (Styled text and Word formats only). The point size used for titles in the exported text.
      • Subsections Smaller By. Subsection heads to be reduced in size for each level of indenting, providing finer control over export styling.
    • Scope list. A choice of:
      • Entire Document.
      • Selected Notes.

    Export HTML progress bar

    This shows the current progress of the HTML export process. Note that pressing Escape can be used to cancel the export.

    The progress bar label shows the full path of the note being exported.

    Find results pop-over

    The Find results for view pane searches are shown in a pop-over. The pop-over can be torn off as a stand-alone dialog to give a more persistent record of the search results. The torn-off Find window retains its selection when clicking on a note. Its title reflects the number of notes found in the document, and the number in the scope of the current view. Selecting a note in the torn-off find window will select that notes in the view, if the note is available.

    [list of matching notes]. The list are shows notes matching the Find criteria. Results are listed by note title ($Name) sorted in the default, lexical, sort order. A lexical sort is used means that instances of the same word in different letter case do not sort together: Ant, Bee, ant and not Ant, ant, Bee as a non-coder might assume. To have greater control over the sorting of results or to get a count of matches, use an agent instead of Find.

    For notes where the match is in $Text, the (first) match context is sown in a second line of listing with the match highlighted. Matches for note title or user attribute value use a single line listing.

    Clicking on a list item makes that note the context of the front window's text pane. Listed notes are rendered in using $Color. Text for notes not in the current view scope are shown as a preview - see 'Preview windows' below.

    The pop-over has a series of controls:

    • search input box (from which a new search can be run). The input box expands/contracts if the dialog is width is drag-altered.
      • The box's pop-up menu offers an option for case-sensitive search, and an option to turn off regular expression search.
      • An 'x' button deletes the current search term.
    • a tick-box to alter the case-sensitivity of searches (this is the same as the setting on the input box pop-up menu).
    • a tick-box to allow inclusion of aliases (by default they are filtered out).
    • sort order pop-up with the following choices:
      • outline order (default). Uses value of list item's $OutlineOrder.
      • Creation date. Uses value of list item's $Created.
      • last modified. Uses value of list item's $Modified.
      • name. Uses value of list item's $Name.
    • Replace In Text With:. Replaces all occurrences of a regular expression with a designated string. These replacements apply to $Text only; $Name or the (optionally) selected user attribute are not checked/altered. Note:
      • this is not undoable.
      • this feature is not included in the stand-alone dialog version of the Find results.
    • Apply.

    The controls work live on the current search results (both in pop-over and stand-alone form) without the need to re-run the Find.

    Found items are grouped into two groups:

    *The first grouping shows items within context of the current tab's view. Such items might not necessarily immediately be seen within the current view area, e.g. because they are outside the display part of a current Map or inside a collapsed container within a current Outline, etc.

    • The second group lists all other matches that cannot be seen in the view pane without changing the context of the current view, i.e. setting its scope differently from the current settings. Clicking these out of scope list items invokes a preview window (see below).

    The Find window can match outline separators and map adornments. In each case the matched items can only be seen if the current view is of the appropriate type/scope.

    A contextual menu in the listing of matches lets the right-clicked list item be opened in a new stand-alone text window or in a new tab. Shift-double-click on a listed item will also open the result in a new tab.

    Find offers up to seven suggested related words as possible autocompletions in the Find bar and in torn-off Find windows. Note: the related text feature only works on macOS 10.14 or later.

    Preview windows

    After selecting a note in the Find window, if the note cannot be selected and previewed in the current view, Tinderbox displays a preview of the note's text.

    Once displayed, either click the preview to close it, or drag it to tear it off as a stand-alone text preview window. Preview closing instructions are shown briefly, at the bottom of the preview pane, on first opening.

    Closing the pop-up

    Use Escape (⎋) or click outside the pop-up. However, if a preview window is also open, the preview must be closed before the Find Results pop-up can be closed. Either tear off the preview to a stand-alone note window, which auto-closes the results pop-up, or click the preview to close it, then use Escape or a click outside the pop-up to close.

    Dragging aliases

    Results dragged into the view pane generate an alias of the dragged result's source note.

    Dragging text links

    Results from the Find results pop-over can be dragged into the text pane. The display name of the dragged item will be inserted into the text and used as the anchor of a text link to the corresponding note.

    Find results stand-alone dialog

    Note: some features requires macOS v.14.

    This is the torn-off version of the view pane Find results pop-over. The torn-off Find window retains its selection when clicking on a note. Its title reflects the number of notes found in the document, and the number in the scope of the current view. Selecting a note in the torn-off find window will select that notes in the view, if the note is available.

    Tinderbox remembers the detached dialog's preferred width and uses that width for the Find results popover in the future, i.e. it persists after the document is closed.

    [list of matching notes]. The list are shows notes matching the Find criteria. Results are listed by note title ($Name) sorted in the default, lexical, sort order. A lexical sort is used means that instances of the same word in different letter case do not sort together: Ant, Bee, ant and not Ant, ant, Bee as a non-coder might assume. To have greater control over the sorting of results or to get a count of matches, use an agent instead of Find.

    For notes where the match is in $Text, the (first) match context is sown in a second line of listing with the match highlighted. Matches for note title or user attribute value use a single line listing.

    Clicking on a list item makes that note the context of the front window's text pane. Listed notes are rendered in using $Color. Text for notes not in the current view scope are shown as a preview - see 'Preview windows' below.

    The pop-over has a series of controls:

    • search input box (from which a new search can be run). The input box expands/contracts if the dialog is width is drag-altered.
      • The box's pop-up menu offers an option for case-sensitive search, and an option to turn off regular expression search.
      • An 'x' button deletes the current search term.
    • a tick-box to alter the case-sensitivity of searches (this is the same as the setting on the input box pop-up menu).
    • a tick-box to allow inclusion of aliases (by default they are filtered out).
    • sort order pop-up with the following choices:
      • outline order (default). Uses value of list item's $OutlineOrder.
      • Creation date. Uses value of list item's $Created.
      • last modified. Uses value of list item's $Modified.
      • name. Uses value of list item's $Name.
    • Apply.

    The controls work live on the current search results (both in pop-over and tear-off form) without the need to re-run the Find.

    Found items are grouped into two groups:

    *The first grouping shows items within context of the current tab's view. Such items might not necessarily immediately be seen within the current view area, e.g. because they are outside the display part of a current Map or inside a collapsed container within a current Outline, etc.

    • The second group lists all other matches that cannot be seen in the view pane without changing the context of the current view, i.e. setting its scope differently from the current settings. Clicking these out of scope list items invokes a preview window (see below).

    The Find window can match outline separators and map adornments.

    A contextual menu in the listing of matches lets the right-clicked list item be opened in a new stand-alone text window or in a new tab. Shift-double-click on a listed item will also open the result in a new tab.

    Find offers up to 7 suggested related words as possible autocompletions in the Find bar and in torn-off Find windows. Note: the related text feature only works on macOS 10.14 or later.

    Text replacement: this feature is only available in the pop-over mode of Find results.

    From v11.7.0, the stand-alone results show more context than the op-up pane.

    Preview windows

    After selecting a note in the Find window, if the note cannot be selected and previewed in the current view, Tinderbox displays a preview of the note's text.

    Once displayed, either click the preview to close it, or drag it to tear it off as a stand-alone text preview window. Preview closing instructions are shown briefly, at the bottom of the preview pane, on first opening.

    Closing the dialog

    Click the dialog window's 'close' (red) button. This will close the dialog and any preview windows open.

    Dragging aliases

    Results dragged into the view pane generate an alias of the dragged result's source note.

    Dragging text links

    Results from the Find results pop-over can be dragged into the text pane. The display name of the dragged item will be inserted into the text and used as the anchor of a text link to the corresponding note.

    Fonts dialog

    The macOS font palette can be shown either via the Note menu or a shortcut (Cmd+T).

    This palette can be used to set only the typeface and size. Other controls such a text colour have no result on text within Tinderbox notes. Bold and italic text are created by using the bold and italic font variants of the regular font in use.

    The palette can also be used to set Outline and Map view title font typeface and size, etc.

    Get Info pop-over

    The Get Info pop-over provides a series of tabs showing information about the currently selected note. Dismiss the pop-over by clicking anywhere outside it. The pop-over will position over the non-active pane of the main window, i.e. the view or text pane.

    Dragging the pop-over will result in a stand-along dialog. This allows the Get Info information to be viewed and used when the source note is no longer selected. It is possible to have multiple Get Info dialogs open at the same time.

    The sub-tab selected on first opening will generally default to the last one used in the current session.

    Be aware that the scope of the information shown varies by tab from just the selected source note to the whole document. Per-tab articles describe the scope of their information.

    The pop-over has the following tabs:

    agent tab

    Scope: source (selected) agent. (Agents only!)

    This tab controls basic agent functions. This replicates information found on the sub-subs of the Action Inspector. Edits made on the this dialog are live as soon as the Return key (↩) is pressed or focus shifts from the current input box on the pop-over.

    This popover is shown by default as soon as a new agent is defined.

    Agent title (only shown if the current object is an agent). The $DisplayName for the agent is displayed above the input boxes.

    Query. The agent's query (stored in $AgentQuery). Auto-complete is offered for action code terms and system/user defined attributes (if starting with a '$' prefix, as is best practice). Editing this code is the same as if editing the Action Inspector's Query tab.

    Action. The action to be applied to each child alias (stored in $AgentAction). Auto-complete is offered for some input, as described above. Editing this code is the same as if editing the Action Inspector's Action tab.

    Priority. This opens the Agent Priority pop-up list, allowing the agent to be turn on, off or to a non-default working state (e.g. on, but at lower priority). Setting is stored in $AgentPriority. Using this is the same as using the Action Inspector's Query tab's Priority pop-up.

    Result count (only shown if the current object is an agent). The count of matches to the current query is shown in grey text bottom right of the pop-over.

    Dragging the pop-over will result in a tear-off window that will persist until the end of the current session (i.e. the document and/or app are closed). A torn-off window may be closed during the current session if no longer needed.

    Code syntax colouring. The agent's query and action code boxes receive action code syntax colouring.

    attributes tab

    Scope: source (selected) note.

    This tab shows attribute data and is the most direct successor to the Get Info dialog in previous versions of Tinderbox. The tab has 3 sections.

    Search. This works as per the Document Inspector, System tab, in seeking to auto-match any input to a currently defined attribute (here for system or user). If multiple matches are found, these are displayed in a pop-up listing allowing the user to select the preferred match. If a match is found, the correct attribute group is selected in the listing and its contents loaded. From this the matched attribute is also selected. Here, $BorderColor has been searched for and matched.

    Attribute Group listing. A list of all the defined groups of System attributes and any defined User attributes.

    Attribute data table. A list of attributes within the currently selected group. The left column shows the attribute name. The right column shows the current local or inherited value. Display and editing of attribute values is as described for the Displayed Attributes table. String, Number, Set and List type attribute will display a pop-up menu showing values currently applied to that attribute elsewhere in the document.

    Row height in the table. Attributes of String, set and List types (only) can have a bigger line height (i.e. use multiple table tows). The default row hight for String-type attributes remains one line, but this can be extended to a maximum of seven lines. Within that space line breaks in the String's value are honoured but any overflow is clipped (i.e. additional content cannot be scrolled). Line height is set per-attribute using The Document Inspector's System and User tabs.

    Some attribute data types show an icon between the attribute name and value cells. The function of these is described under the notes on the Text pane's Displayed Attributes table.

    The meaning of the styling of different rows (bold, strikethrough, etc.) is explained here.

    Dragging the pop-over will result in a tear-off window that will persist until the end of the current session (i.e. the document and/or app are closed). A torn-off window may be closed during the current session if no longer needed.

    Editing the $Prototype value in this dialog is just one way of setting a note's prototype.

    The attribute $ReadOnly is exempted from being read-only, even if set to true. This allows you to turn off ReadOnly from the Displayed Attributes table or from Get Info ▸ Attributes.

    Date-type Attribute formatting

    In the table of attribute values, Date-type attributes use the value formatting set via Doc Settings/Text and inherited via $DisplayedAttributesDateFormat. As the latter attribute's name suggests, this means Displayed Attributes and this dialog's tables use the same date for formats. Note that whilst the format can be set from document down to per-notre scope, for any note all Date-type attributes values are listed using the same format.

    Changes to Displayed Attributes affect $Modified

    Changing an attribute value in the displayed attributes table or in Get Info's attributes tab updates $Modified. Changing an attribute value in a stamp (including Quickstamp) or an action does not update $Modified.

    Showing an Attributes's Description

    Hovering the input cursor over the left column of the table—the attribute's name, will cause the attribute's Description to be displayed as a tooltip. This works for both system and user attributes. Note that user attributes have no Description unless the user adds one (occasionally new system attributes may

    book tab

    Scope: source (selected) note.

    The book tab shows book-related data. For notes with an $ISBN value, Tinderbox will assume the note is about some from of book and the book tab will:

    • look up author and title, if not already known, from ISBNDB.com
    • look up the cover image from amazon.com
    • provide useful links to Amazon, Goodreads, LibraryThing, and WorldCat for this book.

    The ISBN box shows $ISBN data or allows it to be set directly by editing in the box.

    Dragging the pop-over will result in a tear-off window that will persist until the end of the current session (i.e. the document and/or app are closed). A torn-off window may be closed during the current session if no longer needed.

    info tab

    Scope: source (selected) note.

    The info tab holds basic metrics about the current note, mostly relating to attributes:

    Dragging the pop-over will result in a tear-off window that will persist until the end of the current session (i.e. the document and/or app are closed). A torn-off window may be closed during the current session if no longer needed.

    map tab

    Scope: source (selected) note.

    The map tab checks to see if $Address is populated and if it is will attempt to resolve the address into Google Maps, populating $Latitude, $Longitude and $GeocodedAddress.

    The top input box shows data in $Address, or adding data to the box will set there attribute.

    If a map location is found, the map can be zoomed via the slider control to the right of the map.

    Dragging the pop-over will result in a tear-off window that will persist until the end of the current session (i.e. the document and/or app are closed). A torn-off window may be closed during the current session if no longer needed.

    The map tab has an Open In Maps button that opens the (macOS Apple) Maps application.

    paths tab

    Scope: whole document.

    The paths panel displays the number of distinct link types defined within the current document. These are listed in a pop-up control, at top centre of the dialog. These discrete link types added/edited in the Links Inspector.

    Here, 'path' has a slightly different meaning to that used in the context of a note's address ($Path) in the document outline. In this context, a link type's path as all the notes with one or more inbound or outbound links is the selected link type. Be aware that a document may contain more than one discontinuous such network, i.e. clusters of links of the select type but with no interconnecting link.

    The information is whole-document-scope and can be accessed from any note's Get Info, even if that note does not use the link type of interest.

    A pop-up list shows all the links types defined in the document that have one or more links of that type in use. Selecting a link type from the pop-up, the list panel will reports(remember—for all such paths in the whole document):

    • Paths in use (in this document). The overall number of discrete link types being used with links in the current document—so, not a count of discrete links within the document. This list may not include every link type defined in the current document (i.e. as seen in the Links Inspector) because some types may not yet be used for linking.
    • Notes on this path (i.e. for the selected link type). The count of notes (including agents, etc.) with an inbound or outbound link of this type (i.e. 'in' the path). As that list includes both the source and destination of such links, the list will thus show more notes than the discrete number of links.
    • A scrollable listing (beneath the popup) of the titles ($Name) of all notes in the selected path (i.e. all the notes in the count in the above bullet). A tooltip for each item shows its full location path ($Path) in the document. Double-clicking the item will select that item. If in pop-over mode, the pop-over now attaches to the newly selected note.

    To see the count of overall internal links (i.e. both basic and text) in the document see the Info Inspector. To see every link type defined in the current document, whether used or not, see the Links Inspector. To see the number of links starting in the current note (and by basic/text/web breakdown, see the source note's Browse Links.

    Using the paths dialog for link triage

    Given that the information is whole document, start from any note but 'tear off' the op-over to be a standalone dialog as this makes for easier working.

    If intending to add new link types, add these to the document via the Links Inspector before trying to use the new values. A link type can be renamed by editing in the Link Inspector: all links using that link type immediately use the new name (some open views might need refreshing). If stopping use of a link type, i.e. where no links use the link type, it still remains defined and available. To remove the link type entirely, do so in the Links Inspector. Deleting a link type also deletes any current links using the link type, so work with care. If merging or retiring a link type, use the Get Info:paths to ensure no links still use the unwanted type, by checking it is not listed in the dialog's pop-up list. If still listed, select that item and then work through the remaining links either setting a new link type or deleting the links. Only then, when there are no links needing edit is it appropriate to delete the link type, unless all links of that type are unneeded. In the latter case the link type and all the links using that type can be deleted at the same time.

    repetition tab

    Scope: variable scope.

    The left list-box shows the repetition count of each repeated word. The right listbox shows the context of occurrence of the currently selected repetition (i.e. left list-box selection) with the text excerpt highlighting the repeated word. Clicking on an item in the right list-box opens that note in the text pane of the front document window. The data in the list-boxes can not be copied.

    The Scope of inspection is variable, selected by a pop-up menu with the following choices (the last option is the default):

    • document (whole current/front document). Use this option with caution in a very large document, it may take a little while to complete scanning the existing text.
    • parent & descendants
    • note & descendants
    • selected notes (default)

    The Copy data as clipboard button copies the word/count list data to the clipboard as a tab-delim list.

    A table of results shows the discrete words and the count of said words. The occurrence list can be sorted on any of the columns (default is 'word' in alphabetical order).

    The repetition tab thus offers insight into words that are used repeatedly in the selected notes, sections, or in the entire document. Consistent usage may be needful or desirable, of course, but noting repetition can call attention to opportunities to adopt more precise language.

    The pane lists words that occur two or more times except:

    • words with fewer than four characters
    • words that appear in the built-in 'stoplist' of 100 common English words
    • words that appear in an option customised stoplist.txt in Tinderbox's Application Settings.
    • words that appear in a note in the current document named 'stoplist', if one exists. The note title is case sensitive, but the note can be placed anywhere in the document (most likely away from the primary content).

    The repetition indexing process tries to treat words derived from a common stem as repetitions, so plurals and verb conjugations are often handled intelligently.

    similar tab

    Scope: (matches to) source (selected) note.

    The similar tab uses Tinderbox's 'similar to' function to list (up to) 10 items it adjudges most similar to the current note. It replaces the stand-alone minor view in older Tinderbox versions. Similarity is based on several factors, including:

    • the text ($Text) of the note
    • the note title ($Name)
    • any text contained in user attributes (i.e. attributes of String type or which are string-based)

    In addition, weighting is applied for:

    • notes having the same prototype
    • notes having roughly similar amounts of text

    Similar notes are listed in order from top to bottom, starting with the most similar note at the top.

    Double-clicking any list item sets the clicked note as the focus of the document window's text pane and dismisses the pop-over.

    Dragging the pop-over will result in a tear-off window that will persist until the end of the current session (i.e. the document and/or app are closed). A torn-off window may be closed during the current session if no longer needed.

    This information can also be accessed as an action code similarTo() and an export code ^similarTo()^.

    text tab

    Scope: source (selected) note.

    The text tab shows the $Text space of the current note. Dragging the pop-over will result in a 'tear-off' stand-alone window that will persist until the end of the current session (i.e. the document and/or app are closed). A torn-off window may be closed during the current session if no longer needed.

    This feature is offered in a richer form by opening a stand-alone text window for a note. Links in $Text are non-functional in this display.

    From v11.6.0, Text pane in Get Info has been removed, having been found to be not very useful. This reflects the fact that note text is now often longer and more complex than in the early days of Tinderbox.

    url tab

    Scope: source (selected) note.

    If the note's $URL is populated, the url tab will preview the linked webpage. The web content in the preview is live and links can be followed (but it is not intended for general web browsing).

    Dragging the pop-over will result in a tear-off window that will persist until the end of the current session (i.e. the document and/or app are closed). A torn-off window may be closed during the current session if no longer needed.

    words tab

    Scope: variable scope.

    This tab visualises the most common words in the $Text and $Name of in-scope notes. The word cloud acknowledges both the built-in stoplist and document's own stoplist.txt list, if present.

    Word clouds and aliases: If viewing the word cloud of a note and its descendants, and if the selected note is an agent, the word cloud indexes each alias found by the agent.

    The tabs controls are:

    'scope' pop-up. The scope of examination within the (current) document can be set to one of:

    • document: whole document (default)
    • parent & descendants: parent note of the current note and all the parent's descendants
    • note & descendants: current note and all its descendants
    • selected note: currently selected note

    The scope shown in the pane is equivalent to the export output of ^documentCloud^.

    'Scale' slider. The view can be magnified or reduced by dragging the dragging the slider.

    Image. A word cloud of the most common words found in the current scope. The words are drawn in $NameFont. Re-sizing the pane causes the layout of the contents to be re-arranged.

    Image copy. Right-clicking on the word cloud allows it to be copied to the clipboard as an image. The data is actually in vector format, so if pasted into an image editor capable of vector-based editing the individual word elements are accessible (Mac Preview has limited such support). If passed to a normal bitmap editor an image the size of the image in Get Info is created.

    Search. Click on any word and a Find pop-up based on that word is opened. The find is always whole-document scoped.

    For note and section, each distinct occurrence of a word is counted. For the document level view, Tinderbox counts the number of notes that contain a word 1 or more times. The display contains up to 100 words - less if there are fewer valid words in scope.

    Unlike the 'similar' notes tab, only $Text and $Name are interrogated. Other sources of words such as textual user attributes are thus ignored.

    If the dialog is torn-off as a discrete window, subsequent changes to in-scope $Text are not reflected; re-select the window sub-tab to refresh the view. Similarly, the 'selected only' scope only maps the note selected at the time the view was opened, and does not track changes in selection while the tab is active.

    This tab replaces the 'Common Words' view in very early versions of Tinderbox.

    Get Info stand-alone dialog

    This is the torn-off mode of the Get Info pop-over provides a series of tabs showing information about the currently selected note. This allows the Get Info information to be viewed and used when the source note is no longer selected. It is possible to have multiple Get Info dialogs open at the same time.

    The sub-tab selected on first opening will generally default to the last one used in the current session.

    For detail about the Get Info sub-tabs, see here.

    Grid Properties pop-over

    This pop-over is used to set up an optional grid layout on map adornments. It is opened by clicking the 2x3 grid icon on a selected adornment.

    • Rows. The desired number of grid rows. Stored in $GridRows.
    • Columns. The desired number of grid columns. Stored in $GridColumns.
    • colour controls. Sets the colour used to draw the grid and its optional labels. Stored in $GridColor.
    • Opacity. Controls the opacity used to drawn the grid. Stored in $GridOpacity.
    • font control. Sets the font used to draw grid labels. Stored in $GridLabelFont.
    • Labels. A list-type list of row and column labels. Stored in $GridLabels.
    • Label size. Sets the (point) size at which labels are drawn. Stored in $GridLabelSize.

    Labels are drawn, centred, at the bottom of each grid cell. Labels are read by row, then column. Thus in a 2-row 3-column grid, the first 3 labels in the list are the labels for all 3 columns of row #1, and so on. By entering an empty list item using 2 consecutive semi-colons in the list, i.e. ';;', specific cells may be left un-labelled.

    If only rows or columns are set and the other value is left at zero a single row or column is drawn, i.e. a value of 1 is assumed and drawn though not set in the relevant attribute (which remains at '0').

    HTML Export folder dialog

    On calling an HTML Export or Outline Export or Export of Selected Note (via the File menu) a OS-style folder selection dialog is shown. Select an existing folder or create a new one. The selected folder is the location to which export will occur. This location is remembered in the TBX so it should not normally be required to reset it after first use unless deliberately choosing a new location.

    Depending on the size and complexity of your TBX, there may appear to be some delay before the dialog opens. This is because before doing a full HTML export, all agents are updated to ensure output is correct, especially where automatic updating of agents is turned off.

    Once HTML export starts a progress bar appears above the view pane showing the progress of the export process.

    Outline export. Outline export results in a single plain text file with the title of each note in the document indented one tab stop per outline depth level. Thus root level notes are not indented, their children are indented one tab, etc. See more on Outline Export.

    Selected Note(s). The selected items are exported to the same folder, regardless of hierarchy location. Do not use this option for re-exporting a single note to its location within a whole document export context.

    List panel

    This panel uses standard List configuration controls to inset a list into $Text.

    Map Settings pop-over

    This is the configuration pop-up for the current Map view:

    • Color. Colour controls to set the parent object's $MapBackgroundColor.
    • Pattern. Uses Pattern pop-up to set the parent object's $MapBackgroundPattern.
    • Accent. Colour controls to set the parent object's $MapBackgroundAccentColor.
    • Fill. Uses Fills pop-up menu to set the parent object's $MapBackgroundFill.
    • Opacity. Slider control to set the parent object's $MapBackgroundFillOpacity.
    • Hide breadcrumbs. Toggles view's breadcrumb bar (default: un-ticked).
    • Display Link Stubs. Toggles the visibility of link stubs (default: ticked)
    • Animate Links. Toggles link animation of outbound links of the selected note(s).
    • Hide link controls. Toggles the visibility of link configuration controls (default: un-ticked).
    • Use Inherited Settings. A button to reset all the above attributes to current document's default values.
    • Save Settings As Default. A button to set all the above attributes as the current document's default values.

    Multi-window close confirmation pane

    A sheet is displayed when closing one window in a document with multiple main windows open, asking for confirmation of intent to close. This warning is shown because closing a window (other than the last one open) causes the current tab choices to be lost. The options are:

    • Close Entire Document. This closes and retains all (persistable) windows.
    • Cancel. Cancels the close action and closes the dialog.
    • Close. (default selection) Closes only the selected window. This windows tab arrangement is not saved so cannot be re-opened.

    Outline Settings pop-over

    This is the configuration pop-up for the current Outline view:

    Roadmap pop-over

    The Roadmap pop-over is called from the View menu or from the view pane selected note's pop-up menu. The Roadmap lets you see all of the internal links leading to or from a selected space—the local area of a complex hypertext (web links out of the document are not included. Aliases have their own Roadmap, not that of their original. The Roadmap not only gives an overview of inbound and outbound links but also allows exploration of the local hypertext (i.e. the TBX's content). Links out of the current document, e.g. web links, are not visualised in the Roadmap. Styled-text-based 'Smart' links are also omitted from the listing.

    The left column lists all notes that link into the current note; the column header lists a count of the inbound links. The right column lists all the note's outbound links, again with a count in the column header. To change the focus of a Roadmap, double-click any item in either column. The Roadmap will change to focus on the selected note, with links leading in and out of it in the two columns. The current window's view pane will update to the selected note, if it is in scope; note that if the pop-up is torn off the text pane stops following focus of the view.

    Roadmap opens with the initial focus on the outbound links list if there are any outbound links. Otherwise, the inbound links list gains the initial focus.

    Roadmap allows editing of the properties of the selected link. At the top of the Roadmap, Tinderbox additionally shows the display name of the note for which inbound and outbound links are currently being shown. The tooltip of this label is the full path of that note (which will include the name of the note.

    Pressing the Delete key (⌫) will delete the selected link.

    Tab (⇥) cycles from first listed inbound link → first listed outbound link → link type → first listed inbound link, etc. Use spacebar or Return ( ↩) to follow a link and set window focus on the currently selected list item. Use blind type to select a source or destination.

    Note: if the view pane is a map, selection/focus can move to other items on the current map but not to notes on other maps. In the latter case, only the Roadmap updates.

    The Roadmap title shows the $DisplayName of the notes whose data is being displayed. Each listed link item shows:

    • Line one. The $DisplayName of the linked note (in $Color) and at right its $Badge (if one is set).
    • Line two. The link type of the link and, for text links only, that link's anchor text.
    • Roll-over tooltip for either line: the full path of the linked note.

    If the Outline Document Settings for 'Darker colors' is ticked, the item is rendered in a darker tint of their $Color.

    Include Prototype Links. A tick-box (ticked by default) at bottom left allows prototype-type links to be filtered out. Prototype assignments are stored, in the TBX, as links but are not normally used in maps and excluded from link count attributes. However, leaving such links in the last can help tracing prototype-based relationships in a document.

    Button focus of [title of calling note] pop-over. Located at middle-bottom of the pop-over, this refocuses the pop-over on the note from which the pop-over was opened.

    If double-clicking to follow a link and if the destination is not visible in the current view, Tinderbox will refocus the view so as to make it visible. This makes it easier to follow link-based trails around a document.

    The Roadmap pop-up can be torn off into a stand-alone window. Such windows last until the end of the current session but cannot be saved to last across sessions. Tear-off Roadmaps can be useful triaging links: when torn-off, the Roadmap dialog has a button to allow you to refocus the roadmap on the selected note and the ability to see link comments.

    Roadmap stand-alone dialog

    The Roadmap dialog is created by 'tearing off' a Roadmap pop-over. The Roadmap lets you see all of the internal links leading to or from a selected space—the local area of a complex hypertext (web links out of the document are not included. Aliases have their own Roadmap, not that of their original. The Roadmap not only gives an overview of inbound and outbound links but also allows exploration of the local hypertext (i.e. the TBX's content). Links out of the current document, e.g. web links, are not visualised in the Roadmap. Styled-text-based 'Smart' links are also omitted from the listing.

    The left column lists all notes that link into the current note; the column header lists a count of the inbound links. The right column lists all the note's outbound links, again with a count in the column header. To change the focus of a Roadmap, double-click any item in either column. The Roadmap will change to focus on the selected note, with links leading in and out of it in the two columns. The current window's view pane will update to the selected note, if it is in scope; note that if the pop-up is torn off the text pane stops following focus of the view.

    Roadmap opens with the initial focus on the outbound links list if there are any outbound links. Otherwise, the inbound links list gains the initial focus.

    Roadmap allows editing of the properties of the selected link. At the top of the Roadmap, Tinderbox additionally shows the display name of the note for which inbound and outbound links are currently being shown. The tooltip of this label is the full path of that note (which will include the name of the note.

    Pressing the Delete key (⌫) will delete the selected link.

    Tab (⇥) cycles from first listed inbound link → first listed outbound link → link type → first listed inbound link, etc. Use spacebar or Return ( ↩) to follow a link and set window focus on the currently selected list item. Use blind type to select a source or destination.

    Note: if the view pane view type is a map, selection/focus can move to other items on the current map but not to notes on other maps. In the latter case, only the Roadmap updates.

    The Roadmap title shows the $DisplayName of the notes whose data is being displayed. Each listed link item shows:

    • Line one. The $DisplayName of the linked note (in $Color) and at right its $Badge (if one is set).
    • Line two. The link type of the link and, for text links only, that link's anchor text.
    • Roll-over tooltip for either line: the full path of the linked note.

    If the Outline Document Settings for 'Darker colors' is ticked, the item is rendered in a darker tint of their $Color.

    Link Comment box. Below the in-/out-bound columns a box shows the link comment (if any) of the selected link; the comment can be edited. This box is not shown when the dialog is a pop-over,

    Include Prototype Links. A tick-box (ticked by default) at bottom left allows prototype-type links to be filtered out. Prototype assignments are stored as links, in the TBX's data, but are not normally used in maps and excluded from link count attributes. However, leaving such links in the last can help tracing prototype-based relationships in a document.

    Button focus on [title of calling note]. Located at middle-bottom of the dialog, this refocuses the dialog back onto the note from which the dialog was first opened. Or, if the user has shifted the selection of the current tab's view, the dialog updates to show the links for the currently selected note.

    As stand-alone dialogs the Roadmap dialogs last only until the end of the current session; they cannot be saved to last across sessions.

    Spelling and Grammar dialog

    This is an OS standard dialog allowing review and correction of presumed spelling errors.

    Substitutions dialog

    This is an OS standard dialog allowing setting of various smart (on-the-fly) substitutions of input text.

    Summary Display Properties pop-over

    Used only in Map view, this pop-over is opened via icon displayed to the left of container notes (including agents) when selected. This approach makes it easier to correctly set the two attributes controlling container summary display tables.

    The properties table has two columns, one for the $TableHeading component and one for $TableExpression. Each row in the properties table represents a column in the actual table display. Add as many rows as the table needs columns, using the +/- buttons to add/remove rows.

    Use Headings. If un-ticked, the Headings column is suppressed and only $TableExpression components are defined.

    $TableHeading is set to the aggregate of the rows in the first column, and $TableExpression uses those from the second.

    To alter the order of display columns, click-hold-drag the relevant row up or down in the Properties table into the correct new location.

    Entering edit mode for cells in the table

    This can be done via keystroke:

    • using the Return key or Tab key.
      • The Tab key moves the active edit one cell right. The Tab loops through all cell in the row, then out of edit mode, then back to edit mode of column one of the selected row.
    • Cursor right-click on a cell. Note the click must be on existing text in the cell. Clicking elsewhere in the cell has no effect.
    • From v11.5.1, double-clicking a cell opens that cell for editing.

    Selecting a row in the table

    Either click on a row with the mouse cursor, or use the up and down arrow keys (↑↓). If no row is selected, pressing down-arrow auto-selects the first row and pressing the up-arrow auto-selects the last row.

    Table dialog

    This dialog contains standard controls for defining tables inserted into $Text. These tables cannot be directly exported to HTML and are intended for styled text use.

    Table view Edit columns pop-over dialog

    This is opened from the Table view column pop-up menu. It is used to select the attributes to be displayed in Table view.

    The functioning of this pop-over is as for that used for Displayed Attributes, except that the selection of attributes is stored in $TableAttributes. See the Add Displayed Attributes pop-over for details.

    Timeline Settings pop-over

    This pop-over gives a visual method for setting a number of timeline-related settings for the current Timeline view:

    • Width. This adjusts the scale of the bottom scale, i.e. how much horizontal distance there is between days or months, etc.
    • Scale Color. A trio of standard colour controls set the main colour used in the scale bar at the bottom of the timeline. $TimelineScaleColor.
    • Band Color. A trio of standard colour controls set the colour a tint of which is used to draw alternate timeline bands ($TimelineColor). The actual colour set is a 'lighter' shade of the colour set in the controls.
    • Label Color. A trio of standard colour controls set the colour used to draw timeline band labels ($TimelineBandLabelColor).
    • Label Opacity. Sets the opacity with which timeline band labels are drawn ($TimelineBandLabelOpacity).
    • Links. (Default: ticked). If ticked, links starting/ending within the view are drawn. If not ticked no links at all are drawn in the view. ($TimelineDrawLinks).
    • Labels. Sets the labels used for timeline bands ($TimelineBandLabels).
    • Start. Sets $TimelineStart.
    • End. Sets $TimelineEnd.
    • Include:
    • Attributes:
      • Start. Choose an alternative Date-type attribute for plotting event start instead of $StartDate.
      • End. Choose an alternative Date-type attribute for plotting event end instead of $EndDate.

    Tinderbox Help dialog

    This is a standard Apple Help type of window. This contains the main Tinderbox manual.

    Tinderbox News dialog

    At startup, Tinderbox checks with an Eastgate server to see if there is a news item the user has not yet seen. If so, the news is displayed in a separate window at app start. News will only be auto-shown once, but the most recent news item can always reviewed by choosing Tinderbox News from the Tinderbox menu.

    Treemap Settings pop-over

    This is the configuration pop-up for the current Treemap view. Note that none of these settings are saved as attributes but they are saved as part of the Tab's data.

    *Treemap Expression. Enter an attribute name or action code expression. Used to derive a number used to set each item's area. Items with a value of zero are not drawn at all. Non-Number attributes return a value of 1 if they have a set/inherited value: i.e. string-based are not empty, booleans are true. The default is empty (i.e. no action code expression code). XML setting: treemapExpression.

    *Color Expression. An action code expression use to colour each note. The colour used is a shade between the start/end colours set below. The minimum value uses the start colour, the maximum the end colour with other values using a shade between the two. The default is empty (i.e. no action code expression code). XML setting: treemapColorExpression.

    *Start. The starting colour used of shading treemap items. The colour chip opens a standard OS colour palette. The default is an off-white #FFFEF9. XML setting: treemapColorStart.

    *End. The ending colour used of shading treemap items. The colour chip opens a standard OS colour palette. The default is a muted light green #CCD4C0. XML setting: treemapColorEnd.

    *Border Color. Enter the Tinderbox colour (named or hex value) used to draw the border of each item. Or use an action code expression resolving to a named or hex colour value. If not specified, items draw with a border of $Color. The default is no value. (i.e. it uses $Color). XML setting: treemapBorderColorExpression.

    *Maximum Depth. Allows display of only the N upper levels of the treemap. This can sometimes improve clarity of presentation. XML setting: treemapDepth.

    What's New dialog

    This dialog opens with each new Tinderbox session. It indicates the current version, and a few headline changes for that version.

    Clicking the button at the bottom opens the Apple Help for Tinderbox.

    Visual Styling

    Text Markups


    This is bold text.


    This is italic text.


    This is underlined text.


    This is strikethrough text.


    This is subscript text. (This effect does not export to HTML).


    This is superscript text. (This effect does not export to HTML).


    This is highlight text. (This does not export to HTML).


    This is a bullet:

    • bullet text

    Tinderbox supports simple HTML unordered list generation by placing an asterisk at the start of a line. Two asterisks is a second level list item, etc. Thus:

    * This is a list item

    ** This is a sub-item of the first list item

    *** This is a sub-item of the above sub-item and so on

    * This is another list item

    ** This is its sub-item

    * Another list item…

    Use hash (#) symbols in the above scenario to create numbered lists:

    # This is a list item

    ## This is a sub-item of the first list item

    ### This is a sub-item of the above sub-item and so on

    # This is another list item

    ## This is its sub-item

    # Another list item…

    Colouring $Text

    A series of four Color-type attributes $TextColorRed, $TextColorBlue. $TextColorGreen, and $TextColorGray let you control the colour applied via Format ▸ Style ▸ Red and related commands. Changing these attributes does not change text colours previously applied, but affects future applications of these styles.

    Higlighting $Text

    A series of five Color-type attributes $TextHighlightRed, $TextHighlightBlue, $TextHighlightGreen, $TextHighlightMagenta, and $TextHighlightYellow let you control the colour applied by Format ▸ Style ▸ Highlight. Changing these attributes does not change text highlights previously applied, but affects future applications of these styles.

    Shapes, borders, patterns and fills

    Look at the content of this note in Map view for a better display of the various effects or view the map as an image. In either form, layout is a useful visual reference to the descriptions below. These are examples of a number of the ways the look and feel of note icons can be altered.

    rectangle or normal

    This is default note $Shape.

    Pattern: lines

    Horizontal lines in $Color/$AccentColor.

    Pattern: gradient

    A gradient fill from $Color (top) to $AccentColor (bottom).

    Pattern: diagonal

    A graduated fill from $Color (top left) to $AccentColor (bottom right).

    This is the default for $Pattern.

    Pattern: cylinder

    Graduation from $Color (top) through $AccentColor (middle) and back to $Color (bottom).

    Pattern: radial

    A graduation from $Color (1/3 from top/left) through $AccentColor (edges). Added to Inspector's $Pattern pop-up menu.

    Pattern: bar(30)

    Note that this pattern cannot be set via the Interior Inspector, use the Plot Inspector. The pattern requires configuration via its arguments. This pattern can be used in shaped notes.

    bar(value,[min],[max][,target])

    This draws as a horizontal 'progress bar', using $Color and $AccentColor. The 'progress' block is drawn in $AccentColor. These colours are set via the Interior Inspector.

    The arguments work this way:

    • value. If used alone it is a percentage, otherwise it is a value between min and max with the bar being set using value as a percentage of max-min (which must thus be specified). Thus bar(25) is the same as bar(37.5,25,75).
    • min & max. Numerical minimum and maximum values for computing the degree of 'progress' represented in $AccentColor by value. Both arguments may be negative numbers; if min is not supplied, a value of 0 is assumed and negative attribute values are plotted as if zero.
    • target. The target represents a nominal or desired result. For example, if normally writing between 0 and 4000 words on any given day, it might be useful to set a target at 1500 words/day. If setting a target, a min and max must also be set. The target line is drawn in a dashed link alternating $PlotColor and either $Color or $AccentColor) whichever is the current background colour in the position of the target line.

    The arguments in the brackets may be numbers or action code expressions that can be evaluated as numbers. As $Pattern is a string argument, remember to enclose the statement in quotes so the program coerces the output to a string. If a note's $Width is 3.0, then

    $Pattern="bar(15*$Width)" 

    is the same as writing

    $Pattern="bar(45)" 

    Note that if the value to be use is an action code variable, a slightly different encoding is needed to ensure the value and not the name of the variable is used. Here, our progress percentage is in a variable 'vPercent':

    $Pattern="bar("+vPercent+")" 

    or more accurately:

    $Pattern="'bar('+vPercent+')'" 

    … though both forms seem to work - use which ever feels more intuitive.

    If the pattern is written without arguments or brackets, it evaluates as if at 50%, e.g. bar() and bar are the same as bar(50).

    The same pattern can be rendered on a vertical access using the vbar() pattern.

    Use in Note flags

    The pattern action code expression can also be using in $Flags to make progress bar note flags in Map and Outline views.

    Pattern: vbar(70)

    Note that this pattern cannot be set via the Interior Inspector, use the Plot Inspector. The pattern requires configuration via its arguments. This pattern can be used in shaped notes.

    vbar(value,[min],[max])

    This draws as a vertical 'progress bar', using $Color and $AccentColor. The 'progress' block is drawn in $AccentColor. These colours are set via the Interior Inspector.

    The arguments work this:

    • value. If used alone it is a percentage, otherwise it is a value between min and max with the vbar being set using value as a percentage of max-min (which must thus be specified). Thus vbar(25) is the same as bar(37.5,25,75).
    • min & max. Numerical minimum and maximum values for computing the degree of 'progress' represented in $AccentColor by value. Both arguments may be negative numbers; if min is not supplied, a value of 0 is assumed and negative attribute values are plotted as if zero.
    • target. The target represents a nominal or desired result. For example, if normally writing between 0 and 4000 words on any given day, it might be useful to set a target at 1500 words/day. If setting a target, a min and max must also be set. The target line is drawn in a dashed link alternating $PlotColor and either $Color or $AccentColor) whichever is the current background colour in the position of the target line.

    The arguments in the brackets may be numbers or action code expressions that can be evaluated as numbers. As $Pattern is a string argument, remember to enclose the statement in quotes so the program coerces the output to a string. If a note's $Width is 3.0, then

    $Pattern="vbar(15*$Width)" 

    is the same as writing

    $Pattern="vbar(45)" 

    Note that if the value to be use is an action code variable, a slightly different encoding is needed to ensure the value and not the name of the variable is used. Here, our progress percentage is in a variable 'vPercent':

    $Pattern="vbar("+vPercent+")" 

    or more accurately:

    $Pattern="'vbar('+vPercent+')'" 

    … though both forms seem to work - use which ever feels more intuitive.

    If the pattern is written without arguments or brackets, it evaluates as if at 50%, e.g. vbar() and vbar are the same as vbar(50).

    The same pattern can be rendered on a horizontal access using the bar() pattern.

    Use in Note flags

    This pattern action code expression can also be using in $Flags to make progress bar note flags in Map and Outline views.

    Pattern: bargraph() (for container plot only)

    bargraph($ValuesSource[,min,max,target])

    Note that this pattern cannot be set via the Interior Inspector, use the Plot Inspector. The pattern requires configuration via its arguments. This pattern can be used in shaped notes. This pattern is only available for use in container plots and has no visual effect if applied to other objects.

    The graph is drawn in the form of a bar graph plot across the viewport area of the container. The graph is drawn in colour $PlotColor. The container viewport is still accessible for drag/drop, etc., as if the plot were not there. Think of the plot as an overlay.

    For example, to graph the word count of each child note in the container in bar graph form, set the container's map Pattern attribute to:

     $Pattern = "bargraph($WordCount)";

    sp that the Y-axis of the graph will run from the minimum value of the specified attribute, for the notes being plotted, to the largest value.

    Note the overall $Pattern value is a single quoted string if set via code. Otherwise, if setting directly in Displayed Attributes or Get Info, insert the contents of the quoted string:

     bargraph($WordCount)

    The pattern accepts optional argument minimum (min) and maximum (max):

    bargraph($ValuesSource,min,max)

    Thus:

     $Pattern = "bargraph($WordCount,0)";

    graphs the word count of each note whilst ensuring the Y-axis is based at zero, with all attribute values including the maximum being plotted. If using these arguments, both min and max values must be supplied. Note that while zero is the default value of an 'blank' number type attribute, the type allows minus values. The above example would treat all of them as if their value were zero. If a negative min value is supplied, negative item values above that threshold are plotted. For:

     $Pattern = "bargraph($WordCount,10,900)';

    the plot graphs the data from a baseline of 10 to a maximum value of 900. Values outside these are plotted appropriately as the min or max values.

    From v11.7.0, target (no default) is a desired target value (for value) between min and max and which may be smaller or greater than value.

    bargraph($ValuesSource,min,max,target)

    If a target is desired, min and max must also be specified. target is plotted as a narrow black line.

    Example with all inputs

    $Pattern = "bargraph(70, 0, 100, 50)"; 

    where the progress is 70%, exceeding the 50% target. The same could be computed:

    $Pattern = "bargraph($MyValueNumber, $MyMinNumber, $MyMaxNumber, $MyTargetNumber)"; 

    An alternate container plot type is plot() which draws a sparkline-type plot of each child item's value or xyplot() which draws a similar sparkline-type plot but where data can be specified for both axes.

    The background of the plot is set via $PlotBackgroundColor with opacity of $PlotBackgroundOpacity.

    Pattern: plot() (for container plot only)

    plot($ValuesSource[,min,max,target])

    Note that this pattern cannot be set via the Interior Inspector, use the Plot Inspector. The pattern requires configuration via its arguments. This pattern can be used in shaped notes. This pattern is only available for use in container plots and has no visual effect if applied to other objects.

    The graph is drawn in the form of a sparkline-type plot across the viewport area of the container. The graph is drawn in colour $PlotColor. The container viewport is still accessible for drag/drop, etc., as if the plot were not there. Think of the plot as an overlay.

    For example, to graph the word count of each child note in the container, see the container's map $Pattern attribute to:

     $Pattern = "plot($WordCount)";

    The Y-axis of the graph will run from the minimum value of the specified attribute, for the notes being plotted, to the largest value.

    Note the overall $Pattern value is a single quoted string if set via code. Otherwise, if setting directly in Displayed Attributes or Get Info, insert the contents of the quoted string:

     plot($WordCount)

    The pattern accepts optional minimum and maximum values:

    plot($ValuesSource,min,max)

    Thus:

     $Pattern = "plot($WordCount,0)";

    graphs the word count of each note whilst ensuring the Y-axis is based at zero, with all attribute values including the maximum being plotted. Note that while zero is the default value of an 'blank' number type attribute, the type allows minus values. The above example would treat all of them as if their value were zero. The above example would treat all of them as if their value were zero. If a negative min value is supplied, negative item values above that threshold are plotted. For:

     $Pattern = "plot($WordCount,10,900)";

    the plot graphs the data from a baseline of 10 to a maximum value of 900. Values outside these are plotted appropriately as the min or max values.

    From v11.7.0, target (no default) is a desired target value (for value) between min and max and which may be smaller or greater than value.

    plot($ValuesSource,min,max,target)

    If a target is desired, min and max must also be specified. target is plotted as a narrow black line.

    Example with all inputs

    $Pattern = "plot(70, 0, 100, 50)"; 

    where the progress is 70%, exceeding the 50% target. The same could be computed:

    $Pattern = "plot($MyValueNumber, $MyMinNumber, $MyMaxNumber, $MyTargetNumber)"; 

    An alternate plot type is bargraph(), which draws a bar graph of each child item's value or xyplot() which draws a sparkline-type plot but where data can be specified for both axes.

    The background of the plot is set via $PlotBackgroundColor with opacity of $PlotBackgroundOpacity.

    Pattern: xyplot() (for container plot only)

    xyplot( $XValuesSource, $YValuesSource, yMin, yMax, Target)

    Note that this pattern cannot be set via the Interior Inspector, use the Plot Inspector. The pattern requires configuration via its arguments. This pattern can be used in shaped notes. This pattern is only available for use in container plots and has no visual effect if applied to other objects.

    xyplot( $XValuesSource, $YValuesSource [,yMin,yMax,Target] )

    The graph is drawn in the form of a Cartesian graph of the container's immediate children. $XValuesSource and $YValuesSource are action code expressions, evaluated in turn of each child and are normally attribute values in the simplest forma of use. Thus:

    $Pattern = "xyplot($Date,$Price)"; 

    will plot $Date (ascending Date type order) on the X-axis of the container plot and $Price (ascending Number data type) on the Y-axis.

    Note the overall $Pattern value is a single quoted string if set via code. Otherwise, if setting directly in Displayed Attributes or Get Info, insert the contents of the quoted string:

    xyplot($Date,$Price) 

    By comparison with plot():

    $Pattern = "plot($Price)";

    is equivalent to

    $Pattern = "xyplot($SiblingOrder,$Price)";

    Thus if using an non-outline order related attribute for xValuesSource, consider either showing $XValuesSource and $YValuesSource as a $TableExpression or sorting the plot's container on $XValuesSource.

    Optionally, a yMin and/or a yMax arguments may be specified to lessen expansion of the Y-axis; otherwise, the Y-axis plots from the lowest value of $YValuesSource for the container's child notes, to the highest value. The X-axis automatically starts at the lowest $XValueSource and runs to the highest $XValueSource.

    The optional target represents a nominal or desired result. For example, if normally writing between 0 and 4000 words on any given day, it might be useful to set a target at 1500 words/day. If setting a target, a min and max must also be set. target is plotted as a narrow black line.

    Alternate container plots are: bargraph() and plot().

    The background of the plot is set via $PlotBackgroundColor with opacity of $PlotBackgroundOpacity.

    Pattern: ring() (for container plot only)

    Note that this pattern cannot be set via the Interior Inspector, use the Plot Inspector. The pattern requires configuration via its arguments. This pattern can be used in shaped notes.

    ring(value[,min,max,target])

    In the simplest usage

    $Pattern = "ring(70)"; 

    displays an arc representing 70% of a complete circle. The circle is always drawn centred on a 9-o'clock position; a 50% completion would fill from 6 through 9 to 12.

    Note the overall $Pattern value is a single quoted string if set via code. Otherwise, if setting directly in Displayed Attributes or Get Info, insert the contents of the quoted string:

    ring(70) 

    Additional optional arguments allow specification of a minimum value, a maximum value, and a target value.

    All four inputs may be a literal number, an attribute's value or the result of a simple action code expression.

    value is a number (between min and max). Progress, as shown by value, is plotted in $PlotColor.

    min is the minimum value number (default: 0).

    max is the maximum value number (default: 100).

    target (no default) is a desired target value (for value) between min and max and which may be smaller or greater than value. If a target is desired, min and max must also be specified. Target is plotted as two narrow black lines, centred as per the progress bar. target is always drawn in $PlotBackgroundColor.

    Example with all inputs

    $Pattern = "ring(70, 0, 100, 50)"; 

    where the progress is 70%, exceeding the 50% target. The same could be computed:

    $Pattern = "ring($MyValueNumber, $MyMinNumber, $MyMaxNumber, $MyTargetNumber)"; 

    Pattern: pie() (for container plot only)

    Note that this pattern cannot be set via the Interior Inspector, use the Plot Inspector. The pattern requires configuration via its arguments. This pattern can be used in shaped notes.

    The pie() plot can be used in normal map note icons including shaped notes. Originally, this pattern was only available for use in container plots.

    pie( ValuesSourceAttribute )

    The graph is drawn in the form of a pie graph of the container's immediate children. ValueSource can be an attribute, or an action code expression yielding a number, reflecting the container's children. Thus:

    $Pattern = "pie($EditsMade)"; 

    will plot $EditsMade for each child in $OutlineOrder plotting anti-clockwise from the 90-degree position.

    Note the overall $Pattern value is a single quoted string if set via code. Otherwise, if setting directly in Displayed Attributes or Get Info, insert the contents of the quoted string:

    pie($EditsMade) 

    If using a non-outline order related attribute for ValuesSourceAttribute, consider either showing it as a $TableExpression or sorting the plot's container on ValuesSourceAttribute.

    pie( ValuesSourceAttribute, Min, Max )

    For non-container use of the pattern, pie() uses the additional arguments, Min and Max. Min defaults to 0 and Max to 100. If only one range limit is provided the other is used at default value. Thus:

    $Pattern = "pie(65,0,100)"; 

    plots a 65% competed circle. The pie plots as a circular progress bar, anti-clockwise from the 90-degree position.

    Other aspects of the pattern's display:

    • Labels are drawn atop pie chart segments (avoiding segments overlying each other's labels).

    *The colours for each segment of the pie chart are taken from the attribute $PlotColorList (default list value: [2;7;3;8;4;9;0;5;1;6], using system numbered colours). The first colour designates the colour of the first segment, and remaining colours in the list are used in rotation until all segments have been drawn. If the list contains fewer than two colours, "black;white" are used inside.

    *If the container is sufficiently wide, a legend is drawn to the right of the pie chart. Otherwise, pie segments are labeled in the pie chart (where the slice is big enough to fit a label) smaller slices are left unlabelled.

    *If $Direction is false ( the default), the first segment begins at the top of the pie (0º) and subsequent segments are added clockwise, as is customary in geography. If $Direction is set to true, the first segment begins at the right edge of the circle (90º) and segments are added counter-clockwise, as customary in mathematics.

    *Pie segments are separated by a dark grey line.

    *If a container or agent has a pie chart, then the alias of that container or agent will also display the same pie chart, if space allows.

    The pie() plot does not use the 'target' value of other container plots.

    Tinderbox built-in fonts

    Tinderbox includes a number of built-in fonts, i.e. not provided by the under-lying macOS but available in all Tinderbox documents. These fonts are as below (some are used system attribute defaults):

    Chart of Tinderbox's predefined colours

    This chart uses the standard 'normal' colours as seen in the built-in colour scheme 'Tinderbox 7'. Note the default palette selection for new TBX documents in v8+ is 'modern' for OS light mode and 'dark coral' for OS dark mode, these are explained further under the Document Settings ▸ 'Colors' tab.

    Chart of example shapes, borders and patterns

    Named Colours

    By default, new Tinderbox files are created with 29 predefined 'named' colours:

    • 10 shades of grey with numerical names 0 through 9.
    • 19 colours with colour names: black, blue, bright blue, bright green, bright red, cool gray, cool gray dark, cyan, gray, green, magenta, orange, poppy, red, violet, warm gray, warm gray dark, white, and yellow.
      • Note that 'gray' appears to be added by the default colour scheme ('Modern') and is not defined by the core Tinderbox named colour set ('colors.xml').

    Names add since Tinderbox launch

    Most of the basic named colours were added in v1.0.0. Later additions:

    • v2.1.0: 'poppy'
    • v6.0.0: 'violet' and '0' through '9'

    Case-sensitive names

    When used in code, colour names are case-sensitive - 'blue' and 'Blue' are treated as separate colours. Tinderbox-defined named are always lowercase-only.

    What do the named colours look like?

    The named colours actual displayed colour can be seen here, displayed using the built-in 'Tinderbox 7' scheme which does not alter original colour values and includes all the 29 post-v6 defined named colours. That scheme is no longer the default scheme for new TBXs but does give colours truest to the names used. The image used (a screen grab of a map view in the aTbRef source TBX) includes all the built-in shade variants of the named colours.

    These names are used in pop-up lists in the Colors Inspector and in other Inspector panes for Color-type attributes. These pop-ups show a small circle filled with the rendered value of that colour. There is no preview of colour shade variations except by setting that variant as a colour value.

    Despite the implication of their name, these colours can have their actual colour value set to something else. So whilst named colour 'red' may logically be some shade of red, there is nothing to stop the user setting a different red value—or any valid colour value—for that named colour. See below for setting/altering named colour values.

    This seems odd at first sight. But the method of a fixed name but varying values allows for Tinderbox's method of implementing different colour schemes. by simply adding a files that redefines colour values (see more).

    Do all TBXs have the same named colours?

    Named colours seen in a Tinderbox file (TBX) apply only to the current TBX document. However, as all TBXs are created with a default set of named colours, these are generally consistent across all TBXs of the s006666`ame user..

    Can a different default set of named colours be used?

    In short: No. However, once a document is created, a saved custom colour scheme can be applied.

    [Not recommended for non-expert users] Those wanting a customised set of colours available by default in all their TBXs should investigate use of Configuration files, specifically a colors.xml file; such changes will affect all TBXs created after the custom colors.xml file has been created and the app re-started. This method does not allow the user to customise the colour of 'normal' either at app or TBX level.

    User defined named colours

    It is possible to add new, user-defined, named colours via the Inspector, see below.

    Adding, deleting or amending named colour values

    This is all done via the Colors Inspector, which see. The actual value of any defined named colour is set/altered via the Inspector.

    New, user-defined colours may be added. this change is restricted to the current TBX document.

    User defined or default built-in named colours can be deleted. There is no undo for this. To re-assert a deleted built-in colour it must either be manually redefined or apply a suitable built-in colour scheme. Be aware the latter re-asserts all its defined colour, so the manual method is likely better for a single colour needing attention.

    Reverting to base defaults after experimenting with colour schemes

    There is no 'reset' for colours but applying the 'Tinderbox 7' colour scheme is the best way to revert to colours that reflect their actual name. If wanting to rest to 'as new' start for post v8 TBXs, use 'Modern'.

    Note Colours and variations

    There are 29 defined 'named' colours plus 3 'magic' colours (s of v6+): see more on named colours, whilst 'magic' named colours are described further below .

    Named colours are used in all pop-up colour menus, e.g. in the Appearance Inspector's Interior sub-tab, as are used for setting Color-type attributes. The pop-ups list all the named colours and such 'magic' colours are contextually appropriate. When used in code, colour names are case-sensitive - 'blue' and 'Blue' are treated as separate colours.

    Each primary colour can be assigned 3 darker or 3 lighter shades: dark, darker, darkest and light, lighter, lightest. There are 3 further shades: muted, warmer, cooler. Thus warmer creates an analogous colour that moves counter-clockwise on the colour wheel, "warmer yellow" is a reddish yellow; cooler creates an analogous colour that moves clockwise on the colour wheel, "cooler yellow" is a greenish yellow; muted creates an analogous colour that is less saturated than the original colour. The latter 3 shades are not included in the colour swatch displayed on the Colors pane of the Attributes dialog.

    Thus for each defined colour there are 9 predefined shades of created dynamically from the base primary colour value, all of whose hexadecimal RGB values are listed in this section. Note that when setting a shade of a named colour in a string, e.g. via action code, the shade value (lighter, darkest, etc.) comes before the colour, whereas in the Inspector, the shade pop-up lists shades after the colour being modified. Thus action code would use "dark warm gray" as opposed to a supposed "warm gray dark" listing as suggested by the Inspector UI layout, "light cyan" not "cyan light", etc.

    If using the TBX file, look at the content of note 'Tinderbox named colour map' in Map view for a better display of the colours (if reading the website, look here). Colours illustrated in this section list one colour per line with the shades listing from left as per the top-to-bottom order on colour pop-up selectors. The modifier is listed before the 'primary' colour as per usage in action code. The map can also be viewed as an image. This layout is a useful reference to the descriptions below. The list shows examples of border and pattern types as shown in the picture followed by the hex values of all the named Tinderbox colour and their 10 default shades (set automatically). In HTML view use the above linked graphic to see the colour listings.

    The most normal application of a colours is to set the on-screen colour of Outline view list items and Map note icons. This is done by setting the selected note's $Color attribute. Incidentally, the colour of note text on Map icons is set automatically for black or white so as to give best contrast with the chosen $Color setting; this can be over-ridden by setting an explicit $NameColor value.

    The user can alter a primary colour's actual value or add new primary colours by means of the Attributes dialog's Colors pane. As you add or edit a colour Tinderbox shows you a swatch with the primary colour and its six automatically generated shades. To add a new primary colour you simply give it a new colour name and a hexadecimal colour value and then click the 'change' button. Users wanting a customised set of colours available by default in all their TBXs should investigate use of Configuration files, specifically a colors.xml file; such changes will affect any TBXs created after the custom colors.xml file has been created and the app re-started. This method does not allow the user to customise the colour of 'normal' either at app or TBX level.

    Custom colour schemes are also possible; this allows a custom colour set to be shared from one TBX to another and even with other users.

    When exported to HTML, literal (named) colours are exported as Hex RGB strings, i.e. 'red' exports as '#FF0000'. Hex values are case insensitive in TBXs, i.e. "#ff0000" is the same as "#FF0000".

    British English (BrE) vs. American English (AmE) spelling. Note that the colour 'gray' must use the American English spelling with an 'a'. A colour with the normal English spelling of 'grey' will be treated as a different colour (colour!). Also, when referring to colour Tinderbox in UI captions, code, etc., use the American English spelling variant 'color'. The author of aTbRef is English so it uses BrE spelling except in explicit reference to AME named controls, features, etc.

    The current default colour schemes used for new TBXs are described here (the given choice has changed over the Tinderbox's existence. To reset the colour value of 'named colours' apply the appropriate build-in template (or build a custom scheme for this purpose)

    The special colours listed below are named as per Action code usage:

    Magic colours

    Special 'magic' defined colours that may hold varying colour values: normal, transparent and automatic.

    'normal'

    The colour listed as 'normal' (without the quotes) is not a colour per se but rather it corresponds to the default or inherited colour. Note the lowercase initial letter, normal, as the spelling is case-sensitive.

    In fresh Tinderbox installations, normal defaults to 'warm gray dark' (#605850).

    This value cannot be customised by the user, unlike other named colours.

    'transparent'

    The colour listed as 'transparent' is specific to the $Color attribute of Map adornments alone; note the lowercase initial letter, transparent, as the spelling is case-sensitive.

    Setting a value of transparent makes the body and border of the adornment colourless (i.e. transparent). If the $NameColor attribute ('Text color' on dialog) is still set to automatic then it will use the container's background colour as that against which the appropriate black/white colour will be used for the adornment title (if any).

    'automatic'

    The colour listed as 'automatic' is used by the $NameColor and $BorderColor attributes; note the lowercase initial letter, automatic, as the spelling is case-sensitive. Importantly to note is this colour value cannot be customised by the user, unlike other named colours.

    *For $NameColor, Tinderbox toggles the map title colour from black (#000) to white (#fff) and vice-versa depending on the colour value in 'Color'. If neither black nor white offers sufficient contrast, a yellow colour is used.

    • For $BorderColor, the bevel colours used are lighter and darker gradations of the value specified for $Color so as to not contrast unduly with the main 'face' colour ($Color/$AccentColor) of the note (especially in Map view).

    If automatic is displayed as one of a note's Displayed Attributes, the colour chip for 'automatic' always shows as a dark red (#dc490b) regardless of the colour actually used, e.g. $NameColor may show as white in Map view but as dark red in the note's colour chip. If Color-type attributes that do not support the 'automatic' token are set to the value 'automatic' the resulting colour actually used is #dc490b. Essentially, this is the 'undedfined' colour.

    Undefined named colours

    If a named colour is used for a Color-type attribute but that name is not defined in the current TBX, then a default value is shown: #dc490b. This can be considered the 'undefined' colour. The 'automatic' magic colour may use this value if there is no clear value to apply—automatically.

    This undefined colour value is not user-definable.

    Using Colour Scheme TBC files

    The app's base default colours are never seen today as on creation of a new TBX document a color scheme is applied automatically. As of v8.0.0+ this is the scheme 'Modern'.

    Applying a new colour scheme

    A scheme can be applied one of two ways:

    • Use the Document Settings:Colors tab, select the desired scheme and click apply. Once applied there is no indication as to the current scheme, i.e the last scheme applied. This settings tab lists both built-in schemes and, at the end of the list any custom colour scheme TBC files in the app's Application Support/color schemes folder.
    • Drag/drop a TBC file from any finder folder onto the view pane of the current

    There is no reset!

    Colour schemes can only add new colour definitions or set new colour values for pre-exiting named colours. However, A scheme closest to the original )v6+) Tinderbox named colours is 'Tinderbox 7'.

    Deleting unwanted named colours

    Removing unwanted custom (or even built-in) named colours must be done using the Colors Inspector: select the desired colour to remove and then click the button to the left of the colour chip.

    Hiding colours

    It may be desired to have named colours defined but for them not to show in colour pop-up menus. Note that the Colors Inspector's colours menu always lists all current named colours. A colour can be hidden by:

    • adding the code ' hidden="1"' to a colour's definition in a colour scheme file's code.
    • ticking the Hidden tickbox on the Colors Inspector. This control is a toggle so can be used to hide or reveal a defined colour.

    Other scheme file code

    In addition to named colours, scheme files can set (or reset defaults for) a number of application and view preferences, and separately of Color-type attributes. The range of allowed items in each of these two groups is not formally documented.

    View backgrounds

    Originally, all views shared a common background colour to the view pane. The colour is set in Document Settings → Maps → Background Main Color. That colour that acts as the document default value for system attribute $MapBackgroundColor:

    • Views making prominent use of $MapBackgroundColor: Map, Outline, Chart, Hyperbolic.
    • Views making limited use of $MapBackgroundColor:
      • Timeline. Only for the main part of the view. The no value and out of scope sidebars have a fixed colour assigned. The bottom scale tint colour can be customised.
      • Treemap. The background is only seen as thin band around the root object.

    *Views that make no use of $MapBackgroundColor: Attribute Browser, Crosstabs, Gaudí, Table, Information City.

    Views that incorporate a visible control panel (AB view, Crosstabs, Gaudí, Hyperbolic, and Table) use OS-style controls and use similar colours for selection highlights, etc. The OS's UI colour choices for controls and general UI are set via Apple's System Settings app, Appearance tab (at least as at macOS 26).

    Report style views (AB view, Crosstabs, Table) have no controls for background colours in the main text area.

    Misc. User Interface Aspects

    Age Colouring of Notes

    The background colour of Outline view note icons, or dogears in other views, changes according to the age of the note.

    The colour reflects the time passed since the note's date of creation (or subsequent latest edit); it is initially light blue, "dries" after about a day to white, and then gradually yellows over the course of a year. The duration since creation/edit for triggering colour ageing transitions is not documented.

    In the illustration, note 'Badges' has just been created. 'Badge pop-up picker was edited within the last day or so, 'Browse' less recently than that but more recently than 'Agent Queries', etc. 'Attribute Browser Query pop-up' shows the fully aged colour.

    Agent's AgentPriority Status shown in Icon

    The on/off $AgentPriorty status of an agent's query is shown in its view icon, for all views except Maps.

    Disabled (frozen) agents are distinguished by a hollow bar (the screen grab's compression makes it less clear than it actually is on screen!). Note that a frozen agent retains any existing aliases as the time of being disabled, those these may subsequently be deleted if so desired.

    Outline, Chart and Attribute Browser are the only views to offer this visual tell-back of $AgentPriority status.

    Anonymised Data Sharing

    Tinderbox anonymously reports some simple usage statistics to help Eastgate make features easier to discover, and to understand what languages and which versions of macOS are actually used by Tinderbox users. This is controlled via the Tinderbox Preferences/Register dialog.

    Eastgate collect only very general features, such as what kinds of views are being used or how frequently tabs are deleted. Such indications about how users use the app, and which parts they use (few use every feature).

    As a long-lived app (born 2001) and as a multi-purpose tool there are a lot of small features added because someone had a real need for it. Often these become obsolete (or simply unused). It can be helpful for a small company like Eastgate to understand how best to prioritise limited resources to best serve its users.

    No identifying personal information and no information about the content of a document's notes is transferred. Care has been taken to ensure that this will not impede work when offline or when the server is busy.

    The default setting (In Preferences/Register) is set to opt in (un-ticked). Tick the box if you do not want information to be shared. This might be a generic personal privacy point of view, or because of use on a network whose organisation's rules dislike or ban such background features.

    However, aTbRef's author strongly advises allowing sharing unless you have a specific reason not to. It can only help make Tinderbox better.

    Attribute name styles in listings

    Where attributes are displayed (tables) or listed (pop-up menus) a number of conventions are used to help explain aspects of the attribute:

    • Active, defined attribute. Normal text label colour/weight
    • Calculated (read-only value). Italic in pop-up menus, but a grey label in tables
    • Deprecated (do not continue to use!). Strikethrough label: black line in pop-ups, red line in tables.
    • In tables only:
      • a label in bold indicates an attribute with a local value (i.e. discrete value set in this note, vs. default/inherited).
      • (Displayed Attributes) a label in grey indicates a table item defined for a non-existent attribute, e.g. occurring when a note with Displayed Attributes is imported form another TBX document

    Locations of listings:

    Auto-deletion of untitled notes

    Automatic deletion of new 'untitled' notes occurs in both Outline and Map views. Closing title edit (e.g. clicking outside the $Name edit box) that has not been named, results in that note being deleted. This copes with the easy mistake of hitting Return by mistake and unintentionally creating a new note.

    Note, however, that automatic deletion is deferred briefly after focus leaves title edit, allowing the user to click onto the text pane and begin typing without choosing a note name (or editing Displayed Attributes). If the note is given $Text or customised in any way, the automatic deletion is suppressed, so container OnAdd actions may suppress this feature inside the container.

    In map view, dragging a link to the background creates a new note and completes the link. In this case, the untitled note is no longer automatically deleted.

    Autocompletion of input

    Tinderbox offers a number of auto-completion methods:

    Displayed Attributes value autocompletion

    Some String-based attributes' values in the Displayed Attributes table offer autocompletion when edited in the Displayed Attributes table of a tab's text pane. Supported attribute types are:

    • List
    • Set
    • String

    The auto-complete is quite flexible and does not just match possible matching values from the start of current input. For example, if typing "kin", autocompletion will offer matches such as "Laurie R. King" as well as "kingdom".

    Use the up-arrow (↑) and down-arrow (↓) keys to select alternative autocompletion possibilities.

    To not use the currently suggested auto-complete value, or to use a value that is a substring of the suggested value, use the backspace key (⌫). The edit box shows only the characters actually typed by the user.

    This list is separate from the attribute table row's pop-up list of used values for that attribute

    NOTE: this value auto-complete is also used it the Get Info::attributes tab.

    Maximum list length for matches

    From v11.6.0, the maximum list of matches was increased from 199, to 399. In fact, a value count above that will still be listed but at the trade of of a slightly slower refresh rate for the list.

    Length of matched values in the list

    Individual listed matches are truncated at 31 characters. Values longer than that must be entered manually.

    Values starting with digits, decimals or a minus

    If the value being typed begins with a digit, a decimal point, or a - sign, then autocomplete is inhibited for that value. Thus, autocomplete is inconvenient when used with string attributes that happen to have numeric forms, such as Dewey Decimal numbers or numeric IP addresses or social security numbers. Previously in this case, Tinderbox eagerly made suggestions, but they were unlikely to be very helpful.

    '@ ' in List and Set-type attributes only

    These offer autocompletion based on discrete list values (as opposed to a string of all list values stored for a given note). In List and Set types only, value autocompletion regards the character '@' as starting a word; this is to support GTD-style tag values with an '@' prefix.

    Diacriticals (accents)

    Autocompletion supports values with diacriticals allowing matches beyond the basic ASCII character set. Auto-completion is also used with edit-in-place of Outline view column data.

    Attribute name autocompletion

    Where attribute names need to be entered, for instance in the Displayed Attributes selector, setting up new columns in column view or picking an attribute in the system or User Inspector tabs, Tinderbox will offer autocompletions from existing defined attributes.

    If the part-typed string only has one possible auto-match, that match is used to complete the current string. If this completion is not wanted, e.g. due to a typo, use the Escape key (not the Backspace) to roll back the auto-complete after which other keys such as Backspace will work as expected to edit the user-typed part of the string.

    When searching for attributes in the Get Info/attributes popover, Tinderbox looks for the search string at any position in the note. Thus, 'URL' offers potential completions of $URL, $ReferenceURL, $SourceURL, and $NoteURL.

    The token field of the Displayed Attributes picker offers autocompletion options for all attributes that contain the current string, not only those beginning with that string.

    Action and query code

    Code boxes in Tinderbox will autocomplete action and query code. This occurs in relevant Inspector and Get Info tabs. Dot-operators are offered after a period is typed after an operator or attribute name.

    Only in the Action Inspector 'query' tab and the 'query' box of the Get Info 'agent' tab, '==' is offered as an auto-complete for '=' to help users apply the correct syntax. There is legacy support for '=' in queries but its use is deprecated.

    If '=' is typed after $Prototype, auto-completions are offered for existing defined prototypes. As the process covers both query and action use, care should be taken to use '==' in a query context, or in a find(), and '=' elsewhere. Note that a find() contains a query so this, for instance, in a $Rule's action a '==' may still be pertinent.

    Auto-complete will not try to complete '!=" (not incorrectly as '!==').

    When autocompleting a dot operator, the autocompletions offered for the first character include only operators that begin for character. For example, typing '$MyString.c' will offer completions of "contains" and "count" but not "icontains". However, if the operator being autocompleted has 2 or more characters, such as "$myString.co", all operators that contain that substring will be offered thus including "icontains".

    Code editor fields will provide autocompletion for designators in many contexts that accept a designator.

    OS text auto-complete

    Most input boxes support the Option+Escape (⌥+⎋) shortcut to invoke OS level autocomplete of word in text input boxes. The completions offered are discrete from those offered by the app for things like attribute name or value completion.

    The main text ($Text) pane also supports this feature.

    Automatic Geocoding

    Tinderbox will automatically attempt to find the location of notes where an $Address is set and both $Latitude and $Longitude are 0 (zero, i.e. not set). This is done using Google's geocoding service. If a value for latitude or longitude has already been entered no further lookup occurs. Thus if $Address changes, the user must reset $Latitude and $Longitude to zero to update them. The checking of values is done as part of the agent/Rule update cycle.

    • Latitude: positive values are North, negative are South
    • Longitude: positive values are East, negative are West.

    The geocoding service is more likely to work for addresses in the more developed parts of the globe. For such areas including national zip/post codes in addresses will certainly help improve accuracy (or getting response at all).

    It is important to note that Tinderbox has no control over the results offered, it simply uses the result—if any—returned by Google's service. Thus Tinderbox must poll Google with $Address data but this does not guarantee $Latitude or $Longitude values or their accuracy. Google also rate limit geocoding accesses, normally suspending service access for a day or so if over-used. Thus this feature should not be relied on for bulk geocoding.

    If a geocode action is successful, the resolved address is stored in $GeocodedAddress.

    Automatic re-open of last-used TBX

    There is no Tinderbox setting for this. However, in the mac OS System Preferences ▸ Desktop & Dock, there is an option 'Close windows when quitting an application'. That options label sub-text states:

    "When enabled, open documents and windows will not be restored when you reopen an application."

    If left un-ticked (OS default), Tinderbox will re-open any documents open when the app was last closed.

    Note, however, that this option applies for all applications on the users's Mac.

    Automatic Saving

    From version 6, Tinderbox uses the OS's build-in versioning capabilities. Past versions are accessed via the File menu ▸ Revert To option. Recent versions in the current session may be listed otherwise past version can be accessed via time-Machine-like interface. Note that this does not require the user to be running Time Machine.

    The past versions are stored by the OS and are not designed to be readily accessible to the user. Either make use of the 'revert to' option if seeking past versions or use Time Machine if available.

    The document autosaves in the background whenever a semantic change occurs. In practice this means that should a (thankfully rare!) crash occur very little recent data is lost. Even unsaved document, if open for a short while, will get saved/recovered after a crash.

    Badges

    Notes viewed in any of Outline, Map, Chart or Timeline view may be decorated with an optional 'badge'. This is a small image that appears in the upper right hand corner of the note in map view and to the left of the note name in other supported views. Badges in Map view are described in more detail elsewhere.

    Badges may be selected from a badge picker pop-over by clicking on the '+' symbol at top right of a map icon or to the right of the note icon in other view types.

    The note's badge is controlled by a string attribute $Badge, which holds the name of the badge (app-installed badges use all-lowercase names). The value of Badge may be set through inheritance, rules, or actions.

    Users can alter/extend the range of badges by adding user-created badges, placing suitable PNG files (with the .png extension) in the support folder described. Badges are usually 32 x 32 pixel PNG format files. Square icons are expected but different sizes can be used (e.g. they were created by some third party and cannot easily be re-edited). In such case, consider use of $BadgeSize to control the size at which the icon is drawn at normal view zoom level. $BadgeMonochrome is used to indicate use of monochrome icon sets.

    In Chart view, the maximum display size of badges is limited to 16px.

    To use a macOS system font icon, see section 'Using system font symbols' here.

    Blind typing in view window

    View pane has no existing notes

    When you type 'blind' into a new document window or view pane that contains no notes, Tinderbox will create a new note. This occurs Outline and Map views only as other views always include the document as a top level note so a view of that type is never empty.

    View pane has existing notes

    If the view pane already contains notes, in all view pane view types except Attribute Browser, and Crosstabs. Tinderbox will attempt to select the first note matching the blind-typed string and scroll it into view. In all cases, potential matches must be 'visible' even if in a currently off-screen part of the view. In the case of Outline and Chart views, items in collapsed branches are not matched.

    Tinderbox has slight delay in scrolling the view in response to the blind-typed value as the scrolling could inhibit further input; this should aid using the feature where there are many items with a common stem to their $Name.

    Thus, simply typing will cause Tinderbox to select the note—if in the current view—that matches the typed string. Note that:

    • where a $DisplayName is set, typeahead matches $DisplayName instead of $Name.
    • pressing [Esc] clears the typeahead buffer
    • waiting 1.5 seconds before blind typing again also allows the typeahead buffer to clear.
    • typeahead accepts flexible abbreviations. For example, "Saf4" will match a note named "Safari 4". When typing an abbreviation, Tinderbox tries to find the best available match if no exact partial match to $Name/$DisplayName is available.
    • matching is triggered when 2 letters or more are blind typed into the view.

    While blind-typing to locate notes in the view pane, the (backwards) Delete key deletes the most recently-typed character, not the selected note. The Escape key cancels blind typing.

    Built-in composites

    The File menu allows the addition to the current document of pre-defined composites. The first time a built-in composite is added a root-level 'Composites' container is created. Any subsequent addition go in the same container.

    If a built-in composite is added to a document in which the default value of $NeverComposite is true, the components of the built-in composite have $NeverComposite set to false, ensuring the newly added composite works correctly. If Tinderbox needs to create the 'Composites' container, it sets the OnAdd action to $NeverComposite=false to ensure any user-created composites work correctly when added there.

    The OnAdd actions for the built-in containers for Prototypes and Templates set $NeverComposite=true. This reduces the likelihood of unwanted accidental composites.

    The built-in Composites container is set to export neither itself ($HTMLDontExport) nor its children ($HTMLEXportChilren). This can be verified in the Export Inspector.

    The built-in composite types are:

    List composite

    The built-in composite for lists has a single dark header, followed by one or more items. When a new item is dragged to the bottom of the list, its colour, size, and position are set automatically by the list item's $OnJoin action.

    The composite contains 2 items:

    • (header).
    • (item).

    Expense composite

    The built-in composite for expenses is useful for tracking costs and purchases, e.g. for work, research, holiday or household.

    The composite contains 5 items:

    • where.
    • what.
    • amount. The amount is stored in $MyNumber and set with a currency prefix (default is "$") via the notes $DisplayExpression
    • who.
    • notes.

    Lecture composite

    The built-in composite for lectures is useful for conferences and syllabus planners. It is typical of a number of situations where it is desired to capture various facets about an event.

    The composite contains 7 items:

    • where.
    • title.
    • author.
    • author 2.
    • abstract.
    • note.
    • question.

    Task composite

    The built-in task composite is good for tracking a task that combines dates with people and resources.

    The composite contains 5 items:

    • goal.
    • who.
    • due date.
    • prerequisites.
    • facilities.
    • task.

    Built-in export Templates

    A method for quickly adding export templates follows that for built-in Prototypes. A File menu item displays a sub-menu of built-in export templates that can be added to the current document.

    If no export templates already exist, a root-level container 'Templates' is added. The 'Templates' container's $OnAdd is set to $IsTemplate = true;. Also the built-in prototype 'HTML' ('HTML Template' in older versions) is added to the existing built-in Prototypes container or the latter container is also added. If a 'Templates' and/or 'Prototypes' container exists these are used for any newly added notes instead of creating new containers.

    From v8, the built-in Templates container is required to be a top-level note; an interior note names "templates" or "Templates" will not be adopted as the document's built-in templates container.

    When a document is loaded, Tinderbox checks all notes that are used as (a) an HTMLExportTemplate, (b) an EmailTemplate, or (c) a PosterTemplate. If a note is in use as a template, it is marked so $IsTemplate is true. Notes that are not currently in use as templates are not marked with $IsTemplate as false; a note may advertise its willingness to serve as a template even if it is not in use.

    The offered built-in templates are:

    • HTML. HTML5 page export, with includes for all descendants. This inserts two templates in the form of a wrapper template, which is applied to the main note to export and which then recursively calls a per-item template to include all the main page's descendants. The item template is inserted as a child of the wrapper, emphasising the usage. To export only the current note's content use the new HTML Single note template.
    • HTML Single note. HTML5 page export, but exports only the current note.
    • OPML. OPML export, with includes. This inserts two templates in the form of a wrapper template which is applied to the main note to export and which then recursively calls a per-item template to include all the main page's descendants. The item template is inserted as a child of the wrapper, emphasising the usage.
    • Scrivener. OPML export, with includes. This is actually the same code as for OPML, but offered to aid non-technical Scrivener users and to allow easy branching for any possible Scrivener-only variations.
    • Preview. This is the template auto-inserted for zero-configuration internal preview, but can be imported from the Templates menu as it may be desirable to configure the template before use. This replaces the 'preview' note in /Hints. This is the default template for Markdown notes. The template automatically includes the CSS styles defined in the Preview style note. The Preview template can be customised to add headers, footers, or other elements for more structured internal preview use.

    Once templates are added the user can modify the template code.

    In addition to the above, the users own selection of templates stored in the application support 'templates' folder are also available.

    Note that a prototype that is also an export template (e.g. 'HTML Template', below) will not be listed in the Template pop-up menu. This is so that a note can inherit template status via a template without cluttering the template listing with prototypes.

    Storing templates for re-use in multiple documents

    See the Application Support 'templates' folder.

    Templates container

    If no export templates already exist, a root-level container 'Templates' is added. The 'Templates' container's $OnAdd is set to $IsTemplate = true;. Also the built-in prototype 'HTML' ('HTML Template' in older versions) is added to the existing built-in Prototypes container or the latter container is also added. If a 'Templates' and/or 'Prototypes' container exists these are used for any newly added notes instead of creating new containers.

    Built-in Hints container

    An optional built-in set of containers can be added to a document from the File menu. The container is added at document root and usually at the end of the outline:

    /Hints

    The hints container holds a number of notes and containers that customise Tinderbox to specific tasks and problem domains. Hints will allow Tinderbox to automatically control:

    • the document's stoplist.
    • the library sorting term list.
    • configuration for template-less styled preview of (Markdown-formatted) pages.
    • configuration and addition of highlighters.
    • configuration and addition of taggers.
    • configuration and addition of stamps.
    • configuration and addition external AI integration.

    All features controlled via Hints are optional. Some features may require macOS 10.15 or later.

    The stoplist note

    /Hints/stoplist

    The stoplist note created by Built-In Hints takes precedence over any other stop list notes in the document. Therefore, if Hints are added to the document, pre-existing stop lists should be merged with the Hints-based version.

    Stoplists may contain comments: any lines that begin with # or // will be ignored.

    The library sorting note

    /Hints/library sorting

    This container sort transform 'library sorting' permits notes to be sorted as they might be filed in a library. By default, library sorting ignore initial words "a", "an", and "the".

    The 'library sorting' option for $SortTransform and $SortAlsoTransform is usually set via the pop-up menu of the Sort Inspector.

    The sorting note at /Hints/library sorting, if present and not empty, has $Text containing a list of words that will be ignored for library sorting. This note can be customised for different languages and filing practices.

    Library sorting also respects some locale-specific rules for handling diphthongs and diacritics, and is always case insensitive.

    Preview container

    /Hints/Preview

    This container within the built-in Hints container holds notes that help configure the documents template-less preview using Markdown notes. When previewing Markdown, Tinderbox shows internal text links to other notes as well as web links.

    The container holds one item:

    Preview style sheet

    /Hints/Markdown/style

    Styles for Markdown previews are now taken from this note is created as part of the built in Hints.

    If a stylesheet already exists in the Markdown support folder, it will be imported automatically; if not, a simple starting set of styles will be created.

    Highlighters container

    /Hints/Highlighters

    This container holds notes that describe ways to highlight the text of a note. A highlighter note may contain multiple style declarations reflecting the fact that any given note can only apply a single highlighter.

    Adding the built-in Hints container to a document, generates two specimen highlighter notes in the /Hints/Highlighters container:

    • Markdown. This is intended for users of Markdown.
    • Syntax. A specimen file to show syntax styling in action, rather than represent any particular syntax.

    Any note can opt in to highlighting by setting the $SyntaxHighlighting value to the $Name of a highlighter note. For example, setting $SyntaxHighlighting to markdown would tell Tinderbox to use the highlight methods found in /Hints/Highlighters/markdown.

    The highlighting methods are a list of regular expressions and formats and are described below.

    Defining a highlighter rule

    Each rule is defined by a line starting with the word pattern:. The first line of a highlighting rule must not be indented. For example:

    pattern:parent|grandparent|nextSibling|previousSibling

    Each highlighter note can contain one or more rules. A subsequent line starting pattern: is sufficient to start a new rule within the same note (i.e. its $Text), e.g.

    pattern:parent|grandparent|nextSibling|previousSibling

    pattern:project x

    … but for ease of reading/maintenance of the rule's source code, it is sensible to place a blank line in $Text between each new highlighter rule.

    The pattern statement tells the rule what $Text to match and 'highlight'. The colouring/styling of the rule's matches are defined in by lines following the rule.

    Defining a rule's style

    Any rule can have one or more visual styling codes; allowed codes are listed in the syntax section below. Each styling code for a rule must be on a discrete new line immediately following the rule's pattern: declaration and must be indented using at least one space or tab characters. The amount of indentation is a user choice, as long as the styling code does not start the line.

    For example:

    pattern:parent|grandparent|nextSibling|previousSibling

    color: red

    would locate any of the four defined words and colour them red.

    Comments

    Action code style comments are allowed. Comments are preceded by // and continue for the rest of the line, thus:

    // this rule colours the word 'parent' to red.

    pattern:parent

    color: red // perhaps dark red is better?

    Highlighter styling syntax

    Highlighter rule codes are all-lowercase and should be treated as case sensitive.

    Highlighters allow setting of line-spacing as a multiple of the normal line spacing (see line-spacing below).

    Highlighters allow setting the indenting of the paragraph, as well as the indentation of the paragraph's first line (see indent and first-indent below).

    Highlighters can use any of the following styling codes:

    • color: the text colour, a named colour or hex code value, e.g. color: green or color: #00ff00
    • background: the text background colour (highlight), a named colour or hex code value, e.g. background: #ffff00 or background: yellow
    • size: text size in points, e.g. size: 14
    • line-spacing: line-spacing as a multiple of the normal line spacing, e.g. line-spacing 2
    • indent: indent the paragraph in points, e.g. indent: 32
    • first-indent: indent the first line of a paragraph in points, e.g. first-indent: 16
    • bold: text bolded as a yes/no boolean, e.g. bold: yes
    • italic: text italicised as a yes/no boolean, e.g. italic: yes
    • strike: text struck-through as a yes/no boolean, e.g. strike: yes
    • underline: text underlined as a yes/no boolean, e.g. underline: yes
    • wildcards: yes/no boolean instructs the pattern to ignore regular expression meta-characters such as "*" and "+", e.g. wildcards: no
    • case-sensitive: yes/no boolean instructs the pattern to regard upper- and lower-case letters as equivalent, e.g. case-sensitive: no
    • font: (from v11.5.1) argument is the PostScript name of the font (case-sensitive). The name can be found in the OS FontBook, for example, ArcherSSm-Medium, or as a value found in Font-type attributes.
      • If setting both typeface and size, the font: command should precede the size: command.

    Highlighter style changes alter $Text

    Highlighters set the base colour of notes to their $TextColor rather than to "black" (#000000). Any styling is applied to styled text layer $Text (i.e the XML data and not its data). This is of note as not all styled-text styling, e.g. text colour, can be exported via (HTML) Export.

    Highlighting is NOT a toggle

    Styling is not a toggle effect. Rules affect the stored style of any matched text.

    Deleting a rule does not 'un-set' the visual style previously set by that rule.

    Combining rules

    Although a note can only apply one highlighter, that later can contain multiple rules. If multiple rules potentially match the same text, be aware the styling rules are applied in the order defined in the highlighter note's $Text. Thus, so styles written by the earliest rules may be overwritten by styles set by subsequent rules if both use differing values of the same styling code (e.g. different values of color).

    Possible conflicts with other features

    Do not use this feature on notes using the built-in 'Action' prototype for action code syntax highlighting. Use one or the other.

    As highlighters alter the styling of $Text, existing styling including highlighted passages, may be altered (see above). Combine the two with care.

    Taggers container

    This container within Hints holds notes that provide hints to Tinderbox's AI to help tag notes.

    /Hints/Taggers 

    The name of each built-in note within the Taggers container corresponds to a Set-type attribute.

    The syntax and function of taggers is described under the section on AI features.

    Stamps container

    If the default Hints folder set is added to the document., existing stamps are now also stored and edited as notes within the Stamps Container of the built-in Hints container. The container sets the built-in "Action" prototype as an OnAdd (also adding the prototype to the document if not already present.

    Re-adding the File ▸ Built-In Hints will create the default Stamps container, even if the TBX already a Hints container. Any pre-existing/modified Hints content is not altered by this action.

    Once the Stamps container is added, the Stamps Inspector can still be used for managing stamps.

    Note: use of the new mechanism can be reversed, by deleting the Stamps container, though this is not envisaged as a regular task. Some of the newer features are ignored in the old style of management, e.g. comment and unlisted stamps (see below) function as

    The default container includes a comment note '(What’s This?)'—see Comment stamps below.

    Individual stamps

    Within the /Hints/Stamps container, each Stamp is stored as an individual "Action"-prototyped note; the stamp code is still stored in the TBX as a stamp rather than a note.

    Nesting of stamp notes. Individual stamp notes must not be nested if they are to function correctly via both Inspector and the stamps menu. But note the next below…

    Nesting stamps in Stamps menu. To make stamps that appear as a Stamps menu submenu, continue to name them using the format 'sub-menuName:stampName'. This nesting behaviour applies only to the stamps menu, and not the Inspector or the actual storage of stamp notes.

    Separators in the Stamps Container

    When building the Stamps menu, separators in the Stamps container now become separator menu items (if not named) or disabled menu items (if the separator has a name).

    Stamp name. The name of the note is the name of the stamp, as seen in the stamps menu. If a legacy stamp and a new stamp note have the same name, the stamp note's action will be performed. This stamps should have a unique $Name, at least within the Stamps container.

    Stamp Action code. The stamp note's $Text hold's the stamp's action code. Use of the Action prototype ensure notes use action code syntax colouring and offer auto-completion of operator and attribute names.

    Comment stamps. Any notes in the Stamps container with the name in parentheses are treated as commentary rather than active stamps. For example, the default note '(What's This?)' explains the container and contains no stamp. Stamps may still contain inline action code comments.

    Unlisted stamps. Notes in the Stamps container with a name beginning with a period are not listed in the Stamps menu, but may still be used with the stamp("stampName") action.

    Note: although the stamp notes reflect the Stamps Inspector's stamps, the two lists' ordering is not synchronisedote that the Stamps menu uses the Inspector's order and not that using in this folder, if different.

    Library container

    User functions written in action code may be defined in notes placed in the /Hints/Library container (more on storing function code).

    The Library container's $OnAdd sets new child notes to use the built-in Action prototype. The container does not use this prototype itself and should not be used to store function code.

    Notes here, i.e. descended from /Hints/Library, can contain one or more discrete action code function(s). The names of the notes are not the function so may simply be indicative of purpose. Note how this differs from stamp notes.

    Tinderbox examines all library notes for function(s) and runs an action code in the note when the note $Text is edited (i.e. when the $Text is altered, not just when the note takes focus). This means Library notes can be a useful method for testing code. So if the contents of a Library note is:

    $Color = "green"; 

    … on selecting the note noting happens, the note's color is 'lightest black' as inherited via the 'Action' built-in prototype. If the note's $Text is edited, even just adding a space or line return, the note's colour turns to 'green'.

    As this evaluation includes functions beware functions that alter other notes, as accidental changes may occur is a function is triggered by accidental 'evaluation of the note.

    If wanting to store action code without it being evaluated (e.g. a complex rule's code) make a note elsewhere in the document using either the 'Code' or 'Action' built-in prototypes

    Library notes can be nested with no implication other than for convenience of organisation and storage. Notes can be copied between documents, though it is left as an exercise for the user to ensure any referenced attributes are present in the new document. It is recommended the if planning to share library notes between files that any needed user attributes (and their type, etc.) are noted as a comment in the function.

    AI container

    Note: this feature requires macOS v.15.1.

    This container within Hints holds notes that provide information to support Tinderbox's interaction with external AIs via an MCP bridge.

    /Hints/AI 

    The name of each built-in note within the AI container corresponds to an (enabled) AI. Initially, this is only Claude Desktop, but other AIs may be added later.

    The use of MCP AI integration is described under the section on AI features.

    Command Bar

    From v11.7.0, each note inside /Hints/Command Bar becomes a Command Bar item. The container's $OnAdd sets the prototype 'A Command Bar Item'. That prototype is added to the documents Prototypes container as part of adding/updating the Hints container.

    Command Bar items are intended to hold action code.

    The note's $Name is the name of the item, typed by the user.

    The note's $Subtitle is the description of the item, which is also displayed as part of the command bar item in map view.

    An optional query, $EnabledWhen, allows optional inclusion or exclusion of as a matched item. If $EnabledWhen is not empty (i.e. has a query), that item can be selected only if the query is satisfied. Otherwise the custom command is always available for a match. For example, this could offer an item to 'Install Dashboard' only if that dashboard was not already installed.

    Built-in Prototypes

    The File menu has a sub-menu listing built-in prototypes. These are a series of prototypes pre-configured for quick use. On first addition of one or more of these predefined prototypes to a TBX, Tinderbox adds a root-level container called 'Prototypes'. After the first addition, any other built-in prototypes added are put in the same container.

    The built-in types only use system attributes for their customisations, though the user can further customise the basic prototype with user attribute once added to a TBX. The sub-menu is disabled in read-only documents.

    Note that a prototype that is also an export template (e.g. 'HTML Template', below) will not be listed in the Template pop-up menu. This is so that a note can inherit template status via a template without cluttering the template listing with prototypes.

    Some built-in templates are not listed in the normal menu listing and these are denoted in the list below with a '†' suffix. Such prototypes are added by Tinderbox on first use of the associated feature. Once so added to a document they can be viewed and edited as with any other built-in prototype. Below is a listing of built-in prototypes:

    The prototypes of watched features (except Tot) specify that watched notes are imported with a $TextBackgroundColor of white, even if using dark styles in Tinderbox, since external documents are most likely compatible with light background colours.

    There is nothing stopping the user from further modifying these prototypes once they are in a TBX, for instance by adding user attributes to the Displayed Attributes, etc.

    The default 'Prototypes' container

    Adding any built-in prototypes generates the built-in /Prototypes container - see more. For most users/scenarios, it is good practice to store all prototypes—including user-created prototypes—in this container.

    Storing prototypes for re-use in multiple documents

    See Shared prototypes and the Application Support 'prototypes' folder.

    The Prototypes Container

    The default 'Prototypes' container

    The TB-default-created "Prototypes" container is set with $OnAdd of $IsPrototype=true; to ensure that any child notes added by the user as automatically set as prototypes. The container is also set with $HTMLDontExport as true and $HTMLExportChildren as false. That change ensures that neither the container or its content get exported as this is usually the desired condition. Adding a built-in Template will cause this container to be added, in order to hold the HTML Template prototype needed for the templates.

    Adding just the container

    There is no direct method to do this, but simply adding any built-in prototype will generate the container after which the unneeded prototype may be deleted.

    Prototype: Action

    Action

    This marks the note as holding action code, as opposed to other types of code. Its primary intended use is for support of internal stamp notes and functions. The most obvious use is its auto-application to child notes of the built-in Hints containers 'Stamps' and 'Library' sub-containers. (It may also be given to notes used to store functions outside the Library but this is a not generally recommended purpose.)

    Based on the Code prototype, this also sets $IsAction for a note, enabling Tinderbox to offer auto-complete for action code operators and syntax colouring of code. Note this highlighting latter does not use the general syntax highlighting methods but uses a separate in-app colouring previously reserved for code input boxes.

    So this uses broadly the same settings as the Code prototypes except that $IsAction is set to true. Use for things like storing long actions such as deeply nested if() statements, or for command line code for use with runCommand().

    For notes using this prototype and which with be exported, e.g. CSS code, boilerplate text, the prototype-inherited default for $HTMLDontExport (as seen below) should be reversed locally in the code note itself.

    This prototype's non-default customisations other than $IsPrototype, $Name, and intrinsic map features (height, width, etc.) are listed below.

    $Badge: "design".

    $Color: "lightest black".

    $OnAdd: $NeverComposite=true;

    $IsAction: true (ticked).

    $HTMLDontExport: true (ticked).

    $HTMLFirstParagraphEnd: "" (empty string).

    $HTMLFirstParagraphStart: "" (empty string).

    $HTMLIndentedParagraphEnd: "" (empty string).

    $HTMLIndentedParagraphStart: "" (empty string).

    $HTMLParagraphEnd: "" (empty string).

    $HTMLParagraphStart: "" (empty string).

    $NoSpelling: true (ticked).

    $SmartLinks: false (un-ticked). Prototypes in old TBXs need updating manually.

    $SmartQuotes: false (un-ticked).

    $ParagraphSpacing: 0.

    $Tabs: "0.375;0.375;0.375;0.375;0.375;0.375;0.375;0.375;".

    $TextFont: "Andale Mono".

    $Ziplinks: false (un-ticked).

    Prototype: Code

    Code

    Broadly the setting same as the HTML prototype except that $IsTemplate remains as the default false. Use for things like storing long actions such as deeply nested if() statements, or for command line code for use with runCommand().

    For notes using this prototype and which with be exported, e.g. CSS code, boilerplate text, the prototype-inherited default for $HTMLDontExport (as seen below) should be reversed locally in the code note itself.

    This prototype's non-default customisations other than $IsPrototype, $Name, and intrinsic map features (height, width, etc.) are listed below.

    $Badge: "design".

    $Color: "lightest black".

    $OnAdd: $NeverComposite=true;

    $HTMLDontExport: true (ticked).

    $HTMLFirstParagraphEnd: "" (empty string).

    $HTMLFirstParagraphStart: "" (empty string).

    $HTMLIndentedParagraphEnd: "" (empty string).

    $HTMLIndentedParagraphStart: "" (empty string).

    $HTMLParagraphEnd: "" (empty string).

    $HTMLParagraphStart: "" (empty string).

    $NoSpelling: true (ticked).

    $ParagraphSpacing: 0.

    $SmartLinks: false (un-ticked). Prototypes in old TBXs need updating manually.

    $SmartQuotes: false (un-ticked).

    $Tabs: "0.375;0.375;0.375;0.375;0.375;0.375;0.375;0.375;0.375;0.375;0.375;0.375;" (see note).

    $TextFont: "AndaleMono".

    $Ziplinks: false (un-ticked).

    Note: newly added Code prototype notes offer a dozen tab stops; existing older Code prototypes are not affected, so $Tabs may need to be updated manually if desired.

    Prototype: Dashboard

    Dashboard

    Preconfigured for map dashboard use.

    This prototype's non-default customisations other than $IsPrototype, $Name, and intrinsic map features (height, width, etc.) are listed below.

    $DisplayedAttributes: "SubtitleColor;Subtitle".

    $DominantLanguage: "en".

    $Subtitle: "42". (This specimen value of '42' to aid initial subtitle display/configuration.)

    $NameAlignment: "center".

    $NameFont: "RingsideCondensedSSm-Book".

    $SubtitleColor: "light green".

    $SubtitleOpacity: 100.

    $SubtitleSize: 250.

    $TitleOpacity: 50

    Prototype: Event

    Event

    Intended for use with calendar/timeline related notes.

    This prototype's non-default customisations other than $IsPrototype, $Name, and intrinsic map features (height, width, etc.) are listed below.

    $DisplayedAttributes: "StartDate;EndDate;DueDate;TimelineBand".

    $Badge: "clock".

    $AccentColor: "dark red".

    $Color: "muted red".

    $HoverExpression. If a $StartDate is set, show $StartDate, and $EndDate (if set) else no expression data is generated:

    if($StartDate){$StartDate.format('l')+if($EndDate){' - '+$EndDate.format('l')}} 

    $Participants: empty string.

    Prototype: HTML

    HTML

    This used for correctly configuring notes used as export templates. Historically those were, and most often still are used for exporting HTML but can be used for formatting any export template. Here, normal writing affordances like changing straight quotes to typographic quotes are harmful so are disabled.

    In older versions, this prototype was called HTML Template: existing files are unaffected. The change is in name only and not function.

    Although this prototype has the $IsTemplate flag set, app dialogs (correctly) do not list it as an available template.

    This prototype's non-default customisations other than $IsPrototype, $Name, and intrinsic map features (height, width, etc.) are listed below.

    $DominantLanguage: "en".

    $Badge: "tools".

    $Color: "lighter black".

    $OnAdd: $Prototype="HTML";.

    $HTMLDontExport: true (ticked).

    $HTMLFirstParagraphEnd: "" (empty string).

    $HTMLFirstParagraphStart: "" (empty string).

    $HTMLIndentedParagraphEnd: "" (empty string).

    $HTMLIndentedParagraphStart: "" (empty string).

    $HTMLParagraphEnd: "" (empty string).

    $HTMLParagraphStart: "" (empty string).

    $IsTemplate: true (ticked).

    $NoSpelling: true (ticked).

    $ParagraphSpacing: 0.

    $SmartQuotes: false (un-ticked).

    $Tabs: "0.375;0.375;0.375;0.375;0.375;0.375;0.375;0.375;0.375;0.375;0.375;0.375;" (see note).

    $Text: "<!-- Tinderbox: Prototype: HTML -->" (pus two trailing line breaks)

    $TextFont: "Andale Mono".

    $Ziplinks: false (un-ticked).

    The aim of the default $Text is to help indicate, when exporting pages composed from several notes, from which note content has been drawn. The prototype's default $Text is only inherited _once_ from the prototype, if deleted in the inheriting note, it is not re-applied. If the default text is not of help to a user, it can also be deleted at source, i.e. in the prototype itself.

    Note: newly added HTML prototype notes now offer a dozen tab stops; existing older HTML prototypes are not affected, so $Tabs may need to be updated manually if desired.

    Prototype: Markdown

    Markdown

    Allows notes to use Markdown, for local preview or export, without further fiddling with scripts post-export. The prototype presets $HTMLPreviewCommand to use a Markdown distribution inside the Tinderbox app although other builds or different render scrips can be user-configured. $HTMLParagraphStart and $HTMLParagraphEnd to "" (i.e. no code string) in order to eliminate unwanted paragraph markup tags. $Ziplinks is set to false.

    This prototype's non-default customisations other than $IsPrototype, $Name, and intrinsic map features (height, width, etc.) are listed below.

    $Color: "lighter black".

    $HTMLBoldEnd: "" (empty string).

    $HTMLBoldStart: "" (empty string).

    $HTMLItalicEnd: "" (empty string).

    $HTMLItalicStart: "" (empty string).

    $HTMLMarkdown: true (ticked).

    $HTMLMarkupText: false (un-ticked).

    $HTMLParagraphEnd: "" (empty string).

    $HTMLParagraphStart: "" (empty string).

    $HTMLPreviewCommand: "CommonMark".

    $LineSpacing: 120.

    $ParagraphSpacing: 4.

    $Tabs: "0.375;0.375;0.375;0.375;0.375;0.375;0.375;0.375;".

    $TextFont: "IdealSansSSm-Book".

    Prototype: Person

    Person

    The main items here are to add some of the 'People' group of system attributes as Displayed Attributes.

    This prototype's non-default customisations other than $IsPrototype, $Name, and intrinsic map features (height, width, etc.) are listed below.

    $DisplayedAttributes: "FullName;Organization;Address;Email;Telephone;Twitter;URL;NLNames". (pre-v7 versions also included the now defunct $AIM).

    $Badge: "person".

    $Color: "green".

    $Pattern: "" (empty string).

    $Shape: "lozenge".

    $HoverExpression: $Organization+"\r"+$Email+" "+$Telephone

    Prototype: Place

    Place

    Useful for notes holding geographical location data.

    This prototype's non-default customisations other than $IsPrototype, $Name, and intrinsic map features (height, width, etc.) are listed below.

    $Badge = "pin"

    $DisplayedAttributes: "Address;NLPlaces;Latitude;Longitude".

    $Color: "5".

    $Opacity: 65.

    $Shape: "oval".

    Prototype: Poster

    Poster

    Useful for notes that will be used as a map view poster, especially adding poster-related attribute as Displayed Attributes.

    This prototype's non-default customisations other than $IsPrototype, $Name, and intrinsic map features (height, width, etc.) are listed below.

    $Color: "green".

    $DisplayedAttributes: "PosterTemplate;PosterURL;"

    $HTMLDontExport: true (ticked).

    $HTMLFirstParagraphEnd: "" (empty string).

    $HTMLFirstParagraphStart: "" (empty string).

    $HTMLIndentedParagraphEnd: "" (empty string).

    $HTMLIndentedParagraphStart: "" (empty string).

    $HTMLParagraphEnd: "" (empty string).

    $HTMLParagraphStart: "" (empty string).

    $NoSpelling: true (ticked).

    $ParagraphSpacing: 0.

    $Pattern: "" (blank - no value)

    $ScreenHeight: 23

    $ScreenWidth: 606

    $SmartQuotes: false (un-ticked).

    $Tabs: "0.375;0.375;0.375;0.375;0.375;0.375;0.375;0.375;".

    $Width: 4 (note $Height remains default

    $Ziplinks: false (un-ticked).

    Prototype: Reference

    Reference

    If not already present this prototype is auto-set via the app when dragging in reference data to Tinderbox.

    Initially implemented to support Bookends integration. Useful when adding structured reference data, e.g. via RIS data import. The includes $URL as well as $ReferenceURL. $URL holds a the URL to the reference in the reference manager (e.g. local pseudo-protocol bookends://…), whilst $ReferenceURL holds the reference URL for the reference source (if it has one).

    This prototype's non-default customisations other than $IsPrototype, $Name, and intrinsic map features (height, width, etc.) are listed below.

    $DisplayedAttributes (mainly from the References group of system attributes): "Authors;ArticleTitle;BookTitle;Journal;Publisher;PublicationCity;PublicationYear;RefKeywords;Abstract;URL;ReferenceURL".

    $DominantLanguage: "en".

    $Color: "muted green".

    $AccentColor: "dark green".

    $Pattern: "gradient".

    Prototype: Task

    Task

    Useful for notes in to-do workflows and the like.

    This prototype's non-default customisations other than $IsPrototype, $Name, and intrinsic map features (height, width, etc.) are listed below.

    $DisplayedAttributes: "DueDate;StartDate;EndDate;Checked.

    $Badge: "calendar".

    $Color: "cool gray".

    $AccentColor: "dark cool gray".

    $Border: "dark cool gray".

    $Shape: "tag".

    $DisplayExpression displays the number of child items (if any):

    if($ChildCount){$Name+" ("+$ChildCount+")"}else{$Name} 

    $OnAdd: Prototype|="Task"

    Auto-set Prototype: A Command Bar Item

    A Command Bar Item

    From v11.7.0, this prototype is automatically added to the document when the Hints container is added or updated. The purpose of the prototype is to help configure Command Bar items added to the Command Bar sub-container of the Hints. The expected content is action code.

    There are three Displayed Attributes:

    • $Subtitle. (Default: no value). This is used, along with the $Name in Command Bear search result as descriptive text about the item.
    • $IsAction. (Default: ticked).
    • $EnabledWhen. (Default: no value).

    There is default $Text inserted:

    // action to perform when the item is selected

    This prototype's non-default customisations other than $IsPrototype, $Name, and intrinsic map features (height, width, etc.) are listed below.

    $Badge: "design".

    $Color: "lightest black".

    $OnAdd: $NeverComposite=true;

    $IsAction: true (ticked).

    $HTMLDontExport: true (ticked).

    $HTMLFirstParagraphEnd: "" (empty string).

    $HTMLFirstParagraphStart: "" (empty string).

    $HTMLIndentedParagraphEnd: "" (empty string).

    $HTMLIndentedParagraphStart: "" (empty string).

    $HTMLParagraphEnd: "" (empty string).

    $HTMLParagraphStart: "" (empty string).

    $NoSpelling: true (ticked).

    $SmartLinks: false (un-ticked). Prototypes in old TBXs need updating manually.

    $SmartQuotes: false (un-ticked).

    $ParagraphSpacing: 0.

    $Tabs: "0.375;0.375;0.375;0.375;0.375;0.375;0.375;0.375;".

    $TextFont: "Andale Mono".

    $Ziplinks: false (un-ticked).

    Auto-set Prototype: An AI Prompt

    An AI Prompt

    From v11.8.0, this prototype is automatically added to the document when the Hints container is added or updated. The purpose of the prototype is to help configure stored AI prompts. The expected content is text. The $Subtitle is used for an optional textual description of what the prompt does, e.g. if complex or not self-explanatory.

    There is one Displayed Attribute:

    This prototype has no non-default customisations other than $IsPrototype, $Name, and intrinsic map features (height, width, etc.).

    Auto-set Prototype: Exploded Notes

    Exploded Notes

    This is added automatically to the child container of an exploded note. In order to allow customisation before first use, this prototype can be added to a document from this menu without first invoking an Explode operation.

    Note that the prototype's capitalisation is deliberate. This ensures it is not matched by queries looking for, and acting on, the 'exploded notes' container that is generated by all 'Explode' operations.

    This prototype's non-default customisations other than $IsPrototype, $Name, and intrinsic map features (height, width, etc.) are listed below.

    $DisplayedAttributes: "ChildCount".

    Auto-set Prototype: Imported from DEVONthink

    Imported from DEVONthink

    Applied to any note generated by a DEVONthink watched group. DEVONthink import uses a dedicated built-in prototype (as with watched DEVONthink folders), rather than setting Displayed Attributes directly. This allows customisation of Tinderbox's behaviour when importing from DEVONthink v3.

    This prototype's non-default customisations other than $IsPrototype, $Name, and intrinsic map features (height, width, etc.) are listed below.

    $DisplayedAttributes: "URL;SourceURL;SourceCreated;NotesModified;Tags;ReadOnly". These use the following system prototypes:

    $Color: "lighter warm gray dark".

    $LineSpacing: 120.

    $ReadOnly: true (ticked).

    $TextBackgroundColor: "white".

    The use of a $TextBackgroundColor of white is because even if using dark styles in Tinderbox, external documents' styling is most likely compatible with light background colours.

    Auto-set Prototype: Imported from Finder

    Imported from Finder

    Applied to any note generated by a Finder watched folder.

    This prototype's non-default customisations other than $IsPrototype, $Name, and intrinsic map features (height, width, etc.) are listed below.

    $DisplayedAttributes: "File;NotesModified;LastFetched;ReadOnly;Tags". These use the following system prototypes:

    $Color: "lighter warm gray dark".

    $TextFont: "IdealSansSSm-Book".

    $LineSpacing: 120.

    $ReadOnly: true (ticked).

    $TextBackgroundColor: "white".

    The use of a $TextBackgroundColor of white is because even if using dark styles in Tinderbox, external documents' styling is most likely compatible with light background colours.

    Auto-set Prototype: Imported from Notes

    Imported from Notes

    Applied to any note generated by a Notes watched folder.

    This prototype's non-default customisations other than $IsPrototype, $Name, and intrinsic map features (height, width, etc.) are listed below.

    $DisplayedAttributes: "NotesID;NotesModified;LastFetched;ReadOnly". These use the following system prototypes:

    $Color: "lighter warm gray dark".

    $TextFont: "IdealSansSSm-Book".

    $LineSpacing: 120.

    $ReadOnly: true (ticked).

    $TextBackgroundColor: "white".

    The use of a $TextBackgroundColor of white is because even if using dark styles in Tinderbox, external documents' styling is most likely compatible with light background colours.

    Auto-set Prototype: Imported from Tot

    Imported from Tot

    Applied to any note generated by watching the Tot application. This sets $Tot and $ReadOnly as Displayed Attributes.

    This prototype's non-default customisations other than $IsPrototype, $Name, and intrinsic map features (height, width, etc.) are listed below.

    $DisplayedAttributes: "Tags;ReadOnly". These use the following system prototypes:

    $Color: "lighter warm gray dark".

    $TextFont: "RingsideCondensedSSm-Book".

    $LineSpacing: 120.

    $ReadOnly: true (ticked)

    Closing pop-overs

    Many of the UI elements that were previously dialogs are shown as pop-overs with no obvious close mechanism. The expected close method is for the user to click anywhere outside the pop-over. For pop-over's based on a selection, e.g. Get Info, do not click on the source selection, but rather anywhere else outside the pop-over.

    A pop-over can also be closed using the Escape key (⎋) but, depending on the task at hand, this may also revert the last edit on the pop-over so use with caution—unless that is the intent!

    Composites

    A composite is a group of Tinderbox notes that work together to describe something larger than themselves. For example, when taking notes (in Map view) in a conference, an individual talk might be a composite of notes for the title, the speaker, the content of the talk, and action items requiring follow-up action. Each note has its own text and attributes, but it may sometimes be useful to treat the composite as an object – for example, to move all the notes in the composite to a new map location. Further examples of usage, as envisaged by Eastgate, include the following (giving in parentheses the items the composite might contain):

    • shopping lists (a store, followed by one or more things you want to buy)
    • books (author, title, reading notes, editorial notes on the review we will write)
    • lesson plans (date, topic, assignment, homework, special requirements)
    • restaurant visits for a reviewer (name, phone, hours, credit card info, who dined with you, what you ate, when the review is due)

    Composites are a feature primarily intended for map view use and Tinderbox notes form a composite when their map icon touches another note. Composites make it possible to make compound notes which have individual identities but also are linked to their collaborators in a new (visual) way.

    Some built-in composites can be created from the File menu. This creates a root level 'Composites' container. User-created composites can be added to the container (see instructions). Any composite in this container can be used to create a new copy by choosing Create Composite from the Note menu or the map background's contextual menu.

    When selected, composites are outlined with a darker and thicker bounding box. The composite name and edit widget (a little pen icon at top left of the bounding box) are also displayed when the composite is selected. To (re-)name the composite, click the pen symbol: a pop-up naming box appears over the windows text pane. Enter the desired name for the composite and press the Return key to set and save the new name.

    Clicking on any note within a composite selects the composite; clicking on non-note space within the composite's bounding box does not select the composite. Cmd+click to select individual note(s) within a composite. To edit an individual note, or to see only its text and Displayed Attributes, the note must be individually selected. When a composite is selected the resize handles are not drawn on the individual constituent notes.

    Edit ▸ Break Composite can be used to break up a composite into individual components. Individual notes can be removed from a composite by (Cmd+click) selecting it and dragging it away from the other notes. When using ⌘-drag to remove a note from a composite, the note is removed from the composite immediately. (Previously, it was removed from the composite at mouse-up. The new approach makes the effect of ⌘-drag more clear.)

    When a composite is selected, the text pane displays the text from each member of the composite, as for multiple selections. Composites may have a name. When any item in a composite is selected, the name of the composite is shown above the composite, along with a control widget that allows you to rename the composite.

    When a note joins a composite, its moves in the outline to become the younger sibling of the last member of the composite. Thus, all members of a composite are adjacent in outline order. The relative order of items within a composite should remain unchanged.

    Further composite features:

    Composite masters

    Adding any built-in composite creates a root level 'Composites' container. User-created blank composites can also be added to the container. Any composite in this container can be used as a 'master' to create a new copy.

    To create a copy from a master, use the Create Composite option from the Note menu or the map view background's contextual menu. Note that composites with no composite name are not included in the pop-up lists of possible available composites.

    Roles for composite items

    Items in a composite may have a $Role, which indicates what part they play in a composite. For example, a composite that describes a research paper might include notes with roles like Author, Abstract, and References. If a note has a $Role but no $Subtitle, the Role is displayed where the Subtitle would normally appear.

    Some kinds of composites may have multiple notes with the same role. For example, a list with a header would have one note with the role Header, but might have any number of notes with the role ListItem. The boolean attribute $IsMultiple indicates that a note with that role may occur more than once in a given composite. If $IsMultiple is true, when a note is moved into the composite touching that note, the moved note inherits the note's role. Thus, items moved into a composite and touching a ListItem will themselves become a ListItem.

    Join actions

    An optional action may be performed when new composite members first touch existing members. This action is stored in the $OnJoin action. When a note that was not previously a member of a composite is dragged to touch a note with an $OnJoin action, the $OnJoin action is performed on the dragged note. If a note touches more than one note in the composite, each $OnJoin action is performed in turn. When an $OnJoin action is run, the 'this' designator is bound (refers to) to the note newly joining the composite and 'that' is bound to the existing composite note running the $OnJoin action.

    Suppressing formation of composites

    A $NeverComposite Boolean can be used to mark a note that should never be added to composites. By default false, if set to true at document level, a document will suppress composite behaviour in maps altogether.

    When opening legacy files created in previous versions, Tinderbox scans the file in search of overlapping notes that will be interpreted as composites. This situation most often arises in documents that are seldom if ever used with maps. If Tinderbox finds apparently accidental composites, it marks the notes in the container as $NeverComposite.

    Composite action codes

    Actions and queries can use information about composites (see a listing of such actions). All such date is assumed to be read-only unless specified. Documentation references to 'theNode' mean the note in focus. The path list returned by compositeFor() or compositeWithName() may be used as a designator, or to obtain additional information about the composite.

    Making a new composite

    The is no menu option to simply make a new 'user' composite, but it is possible via the following steps:

    • Switch the current view to Map view and display the document's root-level map (or make a new tab, so configured)
    • Add any of the build-in composites to generate a correctly configured /Composites container.
    • Drill down into the 'Composites' container.
    • Add and name at least two new notes and move them together until they form a composite. When this happens a visible bounding line is drawn around the space containing all of the composited notes.
    • Click on any note within the composite's bounding box (i.e. not in blank space inside the box). Notice a pen icon will appear top left of the composite box.
    • Click the icon, and in the pop-over that appears, give the Composite a title.
    • Now alter the number of notes, their titles ($Name), and do any other configuration needed
    • The new composite is now ready to use.

    To use the composite apply it to the current (map) view via any of the following:

    • View context (right-click) menu 'Create Composite', then click the appropriate composite from the Composites sub-menu.
    • Note menu, 'Add Composite', then click the appropriate composite from the Composites sub-menu.

    Container Sorting and Transforms

    Containers, agents and smart adornments may be sorted on an attribute's value, i.e. other than in default order, and additionally apply a transform before sorting string attributes. In a normal container the default order will be static and the order in which its children were created (or subsequently manually re-ordered). For agents and smart adornments, the default is less obvious as it depends on the complexity of the query; for trivial examples it usually equates to outline order.

    The sort attribute and transform type are selected from pop-up menus on the Sort sub-tab of the Action Inspector. Be aware that that the transform effect is only applied if a sort target attribute is set. Only setting a transform has no effect.

    Containers (which include argents and smart adornments) also re-sort after:

    • changing a Displayed Attribute's value
    • changing an attribute value in Quickstamp
    • changing an attribute value in the attributes pane of the Get Info popover
    • editing a column value will update sorting
    • changing the sort criteria in the Action Inspector
    • expanding (or collapsing/re-expanding) a container in Outline or Chart view
    • agents and smart adornments: the query is changed

    This re-sort trigger matters most when automatic agent updates are disabled. Agents (and smart adornments) may have additional triggers related to their query functioning.

    Content and Type Dependent Icons

    Depending on the presence and amount of content in a note, the outline view (and views with the same icon) will show a slightly different icon (and in Attribute Browser, chart and Timeline views).

    • No note text. A simple half-height rectangle.
    • Zero to 7 characters. A vertical rectangle with no horizontal bar inside.
    • More than 7 characters. A vertical rectangle with a single horizontal bar inside.
    • More than about 60 characters. A vertical rectangle with two horizontal bars inside.
    • More than about 500 characters. A vertical rectangle with three horizontal bars inside.
    • More than about 4080 characters of text. A a vertical rectangle with four horizontal bars inside.

    In Map view (and views with the same icon), the presence of note content is shown by a 'dog-ear' icon on the note; the above granularity of content is not represented.

    Agent icons are similar except the thick bar is at the bottom, not the top. Disabled agent ('frozen' via $AgentPriority) have an empty bar at the bottom of the icon.

    The varying agent/note icon is not immediately obvious to the eye in Outline view, but once you realise it is there the difference it becomes more intuitive as a way to tell apart Notes and Agents. Maps have a different, but similar, visual layout to differentiate note vs. agent containers.

    The fill colour of the icon, indicates the age of its content.

    Prototype notes also show a light green coloured circle behind the icon (here darkened slightly from default value for better contrast). The colour used is set in the Map Preferences.

    Copying or Moving notes within Tinderbox

    Working within a single view

    • Drag. Always moves the selected note(s). There is no key override to force a copy. Retains all formatting except links, though link mark-up (coloured text) is retained. Option+drag of a single object duplicates the object and drags the duplicate. Option+Shift+drag of a single object makes an alias of the object and drags the alias.
    • Copy/paste. Retains all formatting and links
    • Cut/paste. Retains all formatting except links/link mark-up.

    Working within a single TBX file

    • Copy/paste. Retains all formatting and links
    • Cut/paste. Retains all formatting except links/link mark-up. Thus, to move text and retaining its links you must copy/paste before returning to delete the source text.
    • Drag. There is no support for dragging objects between document windows.
    • See notes below about intrinsic attributes and prototypes.

    Working across different TBX files

    • Copy/paste or cut/paste. Retains all local formatting except for links: only those links between notes in the pasted selection are retained.
      • Copied aliases are not pasted. Only original items (notes, agent, adornments, etc.) are pasted to the target document.
    • Drag. There is no support for dragging objects between documents.
    • See notes below about user and intrinsic attributes, and prototypes.

    Intrinsic attribute values

    The values of intrinsic attributes are not maintained when copied within or between documents, because the value is intrinsic to the source note. If it is important to capture and copy the source note's exact value for an intrinsic attribute, consider caching the value in a user attribute (or one of the System's 'Sandbox' group).

    $Created, $Modified and $ID

    The $Created, $Modified values are zero-ed to the date tome of arrival in the new document). $ID is reset to avoid the edge case of two. See also.

    User Attributes

    User attribute values in the pasted/dragged notes are only retained if those attributes existing in the target TBX at time of adding the notes: otherwise it is lost. Action code offers methods to list (source) TBX user attribute configuration info and allows this to be used to set up attributes in the new TBX.

    Aliases

    Only original items can be copy/pasted into a different TBX file, any copied aliases are ignored. Aliases can be copy/pasted within or to different views of the same TBX.

    Copying between documents and User attributes (and their values)

    If a note is copied and pasted to a new document, only those attributes existing in both documents are fully transferred. Thus it is important to implement any necessary user attributes in the destination TBX before the actual copying of notes. N.B. $DisplayedAttributes holds the names of notes as text strings so a pasted note's Displayed Attributes may continue to list attributes from the source document even though they do not (yet) exist in the current document. Thus merely copying a note where Displayed Attributes include user attributes does not auto-define them in the receiving document.

    Duplication and links

    If a note with links is duplicated, any outbound links are duplicated, none of the inbound links. All inbound links remain linked only to the source of the duplicate note.

    Prototypes

    Duplicating prototype notes. (see also) Duplicated notes retain the source note's prototype ($Prototype). For notes that are prototypes themselves, if Note A is a prototype for note B, then duplicating A makes a new prototype note but the duplicate no longer has a prototype link to B (i.e. B retains inheritance from A). The duplicate does have copies of other non-prototype outbound links for A, it is only A's prototype links that are not duplicated. Copying and pasting a container within a document results in the notes in the pasted container using the same prototypes as notes in the source container.

    Prototypes between documents. If a note or agent is copied and pasted to a different TBX document, the new item does not inherit its source's $Prototype value, unless the source note's source prototype is included in the selection. This is a defensive assumption by Tinderbox as it cannot be sure pasted notes are from the current TBX and thus that all source prototypes exist. If it is intended some/all pasted notes will use prototypes from within the destination document, these assignment must be made manually (or via agents, etc.) after the notes have been pasted into the destination document.

    Copying or Moving text within Tinderbox

    Working within a single note window

    • Drag. Always moves selection. There is no key override to force a copy. Retains all formatting except links, though link mark-up (coloured text) is retained. If drag appears not to work, press and hold for a short pause before beginning the drag.
    • Copy/paste. Retains all formatting including links.
    • Cut/paste. Retains all formatting including links.

    Working within a single TBX file

    • Drag. Retains all formatting except links.
    • Copy/paste. Retains all formatting including links.
    • Cut/paste. Retains all formatting including links.

    Working across different TBX files

    • Drag. Retains all formatting except links.
    • Copy/paste. Retains all formatting and links.
    • Cut/paste. Retains all formatting except links.

    Creating draft emails

    Email-type attributes show an envelope icon button in Displayed Attribute tables and Get Info/attributes. Pressing this button creates a new draft email message using the host Mac's current email client

    The email message is created and opened (but not sent) with the following already filled in:

    • 'To' addressee.
    • 'Subject' is optionally set via $EmailSubject.
    • Styled $Text is added as the body copy of the message.

    Adding a subject and any CC addressees, etc., is left for the user to edit before they send the email.

    This feature is not design to auto-send complete messages but to pre-populate predictable parts of a draft email to make it easier to generate email from Tinderbox data.

    Using an email Template

    It is possible to generate more complex email content using an email export template ($EmailTemplate). The latter uses standard export template code so can use not only $Text but content from other attributes (and/or from other note(s).

    If the current note's $EmailTemplate specifies a valid template, that template is applied to the current note and the result of that export is used to set the body copy of the draft email message.

    Creating Footnote notes

    The Footnote sub-menu of the Note menu provides method to create a new note from a selected word or phrase, with the intent that it acts as a reference to the source text. In one combined action, Footnote creation:

    • creates a new note
    • creates a text link, of link type "note", from the selected text to the new note
    • creates a link, of link type "Note +", from the new note back to the selected text
    • the current selected text becomes the name of the new footnote.

    Depending on which footnote creation option is chosen the location of the new note is either as a:

    • sibling: next sibling to the source note
    • child: a new sibling container 'Notes' is created and the footnote is a child of this container. All child footnotes of sibling notes share the same 'Notes' container. Different containers use discrete 'Notes' containers for their footnotes.

    It might seem odd to have this placement choice and 'child' might seem the generally logical choice. In an outline, a container can easily be expanded/collapsed to show footnotes. However, if working in map view and desiring to keep everything in view on the same map, the 'sibling' option avoids having to find child footnotes and drag them up to their parent's level just so they show up on the map.

    The different link types used for links to/from the footnote make it easier to identify notes with footnotes or footnotes themselves.

    Although a possible end point for Tinderbox footnotes are article footnotes when data is exported to other formats, there is no method for collecting and inserting them at the end of an article; this must be done by the user's export template design. Using the 'child' option does however place all footnote from sibling notes into a single container, aiding export.

    An alternative way to create new notes from source text is to simply drag a text selection to an Outline or Map view.

    Current attribute: shared by Quickstamp and Get Info

    The current attribute group and current attribute are remembered (and shared) by Quickstamp and Get Info.

    Default note colours & patterns

    Defaults are:

    *$Color: '7'

    *$AccentColor (was $Color2): 'dark warm gray dark'

    *$Pattern: 'plain'.

    Note that for adornments, $Colour is 'normal' as adornment use as their fill colour a tint of the normal default $Color value.

    Displayed Attributes replace Key Attributes

    The term 'Key Attributes' has been superseded by the term 'Displayed Attributes' as this better reflects their purpose. For longtime users, the change occurred in v8.8.0.

    All system attributes containing the string 'KeyAttributes' are deprecated in favour of new system attributes using the term 'DisplayedAttributes'.

    Thus, attribute $KeyAttributes has been renamed $DisplayedAttributes. Related changes include $DisplayedAttributesFont, $DisplayedAttributesFontSize, $DisplayedAttributesDateFormat $HideDisplayedAttributes.

    Existing documents may continue to refer to $KeyAttributes and will continue to operate this is so as not to break code in existing documents.

    Dragging notes between TBXs

    A highly-experimental facility allows you to drag notes from a Tinderbox map, outline or chart view to Tinderbox map views in other Tinderbox windows. The destination document need not be in the same document as the source.

    When dragging to a new window, Tinderbox will make a copy of the dragged note and will copy the dragged note's attributes to the copy.

    Attributes not defined in the destination document will be ignored. If a note is dragged to another application, the note's text and styled text are available to that application.

    Embedded image fills

    If a note's $Text begins with an embedded image, the note's map icon image is drawn to fill the bounds of the note. This applies to all note shapes.

    Any character, even just a space, will revert to the normal render; note the latter is only used in rectangular notes (i.e. the default shape).

    Features needing more recent OS versions

    Although this version of Tinderbox needs a minimum of macOS 12, some new features may require a more recent OS version in order to function. These include the following, whose articles will state any above baseline OS requirment:

    Finder Quicklook

    Finder's quicklook feature shows a preview of the view pane of the current tab, as last saved. Older documents will need to be re-saved once using Tinderbox v8+ in order to generate a quicklook image.

    Focus View, Expand View

    Views are, by default, shown at root level. However, focus can be shifted to focus, (root) at a different level. In map view, the focused element forms the map background (its container); in other views the focused item is the root of the view.

    Focus View ('hoist')

    In Outline, Chart or Treemap views, Focus View focuses the view on the currently selected note and its descendants. A focused view is subtly like a map except that in a map you cannot access the contents of the parent container. Conversely, in a focus view you can see/edit the container but you cannot add siblings to it; this is because the view's scope for adding/removing notes restricted entirely within the root notes descendants.

    Thus, in a focused view, siblings cannot be added to the root (top) note, only children/descendants.

    Expand View ('drill down')

    Expand View moves the current view 'up' one level. Although there is no menu item, the opposite keyboard short cut to this method achieves a 'drill down' one level if the current note is a container.

    Navigating view focus

    To navigate from a focused view you can move scope:

    • Up (expand/hoist)
      • Click the desired item in the view pane breadcrumb bar (moves directly to that scope).
      • Map view: Up-arrow key (↑). Expand view one outline level.
      • View menu ▸ Expand View. Expand view one outline level.
      • Expand View shortcut.
    • Down (focus/drill-down)
      • Treemap: Select and double-click a descendant. Focus view one outline level down.
      • Outline/Chart: double click a note's icon. Focus view one outline level down.
      • Map: double-click a container's viewport area (Map). Focus view one outline level down.
      • Map: 'Drill-down' shortcut. This is a useful trick in that it can drill down a level even if a container has its viewport hidden by expanding the title area.

    Full Screen mode

    Hovering over the green 'expand' button on any document window (but not secondary/stand-alone windows), shows the full screen toggle. Click when this is showing to enter the normal macOS full screen mode. It is not possible to use this for tear-off pop-up windows (e.g. Get Info, etc.) or for note text windows.

    Full screen split view is supported. In normal (non-full) screen mode press and hold the green "full screen" button in the main window's upper left-hand corner; the window will shrink to permit the user to select the right or the left half of the screen.

    Hoisting view on childless containers

    It is possible to hoist focus to a childless container (or drill to the map of a childless note). This can be useful if the user needs to create a container and to then add notes to that container.

    If a note is 'outdented' in a hoisted outline (i.e. raised in $OutlineDepth), so that it no longer falls inside the section of the outline being viewed, Tinderbox removes the note's view from the outline.

    Hover Images

    It is possible to display an image when hovering over a note. $HoverImage contains the path to an image file. The easiest way to set $HoverImage is to drag the file into the image area in the Hover inspector.

    If a note has both Hover Expression and an image set, the text value of the $HoverExpression is displayed in large type at top of, and in front of the hover image.

    In-place title editing

    Note: this is otherwise sometimes referred to as 'Edit-in-Place' ('E-I-P' of 'EIP' for short).

    In any view pane view click-hold (aka click-pause) on an already selected note's title to enable editing of the title; a double-click on the note title has the same result. This makes in-place editing feel natural, at the cost of a slight delay before the editor actually appears. The delay before the edit is invoked is the same as that used by Finder when invoking edit mode on filenames. Edit invoked this way places the edit input cursor at the click point.

    Once in title edit mode, to finish do any one of:

    • click the note's icon
    • select another note (i.e. click anywhere outside the title edit box, including the text pane))
    • press the Return key

    Cmd+Shift+Return enters edit mode for title of currently selected note, with the whole title selected.

    Esc finishes editing and restores the title to its initial state.

    Cmd+Z (Undo) finishes editing and restores the title to its initial state.

    When adding a new note in edit-in-place mode, if the edit mode is exited without a title being created the new note is not created. There are two exceptions to this—adornments and separators—where no name might be a desirable and deliberate choice.

    Up-Arrow. If the edited title has several lines, up-arrow moves the selection to the previous line. If the selection is at the beginning of the text, up-arrow selected the previous note.

    Down-Arrow. If the edited title has several lines, down-arrow moves the selection to the next line. If the selection is at the end of the text, down-arrow selects the next note.

    Tab. In map view tabbing from the title ($Name) field selects the subtitle ($Subtitle) field. Tabbing from the subtitle selects the caption ($Caption field. Tabbing from the caption selects the title field.

    If the 'check spelling as your type' option is selected the title text is also checked for spelling, although to improve performance the check excludes words in the user's dictionary.

    Data pasted into an edit-in-place box is treated as unformatted.

    Entering title Edit-in-Place mode in Outline or Map view will cancel Hover displays and, in Map only, also Subtitles.

    Editing titles of notes with Display Expressions

    A note with a Display Expression, displays the result ($DisplayName) of the expression ($DisplayExpression) on the title ($Name). When entering edit-in-place mode, the text show is the title ($Name) and not the expression result ($DisplayName). The latter is re-shown once the edit is complete. Note that the text pane always display the title ($Name value)—see below).

    Editing a title via the Text pane

    The title of a selected note can also be directly edited via the title display at the top of the Text pane. The latter does not invoke edit mode in the view pane. This approach can also be useful if the note has a Display Expression as the text pane title always shows the $Name value (the title as stored) and not $DisplayName (the Display Expression result).

    Support for Column view Editing

    Clicking directly on a column other than the title ($Name) of the note promptly opens the in-place editor.

    Double-clicking on a column other than the title ($Name) of the note also promptly opens the in-place editor.

    In Outline view, when editing in place:

    • Tab moves the focus to edit the next column, if that column can be edited.
    • If columns are not in use, Tab moves the focus to the name of the following note.

    When not editing in place, Tab continues to indent the note.

    Similarly:

    • Shift+Tab moves the focus to edit the previous column, if that column can be edited.
    • If columns are not in use, Shift+Tab moves the focus to the name of the preceding note.

    macOS Dark or Light modes

    The main UI supports the macOS' toggled light/dark modes, introduced in macOS 10.14 (Mojave).

    Changing OS mode should not affect colours set via the app, but simply the main UI (windows, tabs, dialogs, etc.).

    New documents created in OS Dark mode will default to using a use a dark Tinderbox built-in colour scheme 'Dark Coral'. The default colour scheme for documents created in OS Light Mode is the built-in scheme 'Modern', from v8.0.0. For documents created before v8, the colour scheme will approximate to

    These built-in schemes are listed on, and can applied via, the Colors tab of Document Settings (Edit menu or [Cmd]+8 shortcut).

    Therefore when changing mode and desiring app colours suiting the mode, the user must set a new colour scheme of their choice. Two built-in colour schemes have a light/dark pair of schemes: Coral/Dark Coral, and Sunny/Sunny Dark. Changing the document colour scheme is a manual user task and is not automated.

    If it is desired to have a 'light' general background to the view pane and $Text area whilst in OS Dark Mode, apply the 'Tinderbox 7' scheme. The KA table and general screen 'chrome' (tabs, etc.) of the app will remain dark but these two key parts of the window will take a light-on-dark colour style.

    Likewise, if opening documents that were made in older OS versions or older Tinderbox versions (pre v8) and the colours look wrong, simply apply 'Tinderbox 7': this the document is post v8.0.0, use 'Modern'. Doing this will update the document's colour scheme to reflect the additional colour settings controlled by current colour scheme.

    When changing to dark mode or light mode with Tinderbox open, the text colour of the tabs is updated immediately.

    Message placards

    Action code operators show() and String.show() allow the user to display a simple textual message in the front document window.

    The message placard

    The message is displayed in a placard that rises from the bottom of the window and stretches across both panes. The area shown makes the message harder to miss but does not imply it is designed for large amounts of text.

    Messages are unformatted text characters only

    Although a message can be passed as an attribute value or a variable, the message must consist of text characters. Images cannot be displayed, nor can the message—once passed—be code that needs further evaluating. In the latter case evaluate the action code expression before passing the message.

    The 'text' is unicode, so it does allow for use of non-Roman scripts (e.g. Cyrillic, Japanese, Chinese, etc.—assuming suitable fonts are present), as well as emoji and character-encoded symbols.

    As text is rendered plain, any source text styling (bolding, etc.) is not retained in the message rendering.

    (Maximum) amount of text shown

    This feature is designed for simple short messages. Text will flow across the whole width of the placard. Line breaks are honoured. The placard will show up to 4 lines of text, and the message cannot be scrolled to show additional content. Messages should thus be designed with this in mind.

    Message duration

    A message sent to the placard will be displayed for 5 seconds after which the placard closes.

    Message queue

    If a new message is sent while a message is already being displayed, the new message will be shown after the previous message is hidden. Thus there is an implicit queue, with each queue item being shown for 5 seconds until the queue is empty. The placard is lowered between successive messages which helps signal the change of message (even if the colours are not changed).

    Placard background and text colour

    Both message methods have a pair of optional arguments, backgroundColor and textColor to set either/both the colour of the placard and the message's text colour. The text default colour is black but this may provide insufficient contrast if a custom background colour is applied. Either colour can be specified as a string conforming to allowed colour specification methods.

    The backgroundColor argument may be used on its own, with default black text:

    show("Hello World","blue"); 

    but if textColor is specified, a backgroundColor value must be passed:

    show("Hello World","blue"); 
    show("Hello World","blue", "#FFF'); 

    Do not try this

    show("Hello World",,"blue"); WRONG! Do not use

    as the result is an undefined background colour (which is normally a shade of orange brown)

    Considerations for use vs. logging messages

    An alternative method of feedback is to use a note's $Text, as a log, and append to the content there. Bear in mind:

    • placard messages are not saved. After 5 seconds of display any message is gone and not retrievable.
    • if a message is long, consider if the fixed duration of 5 seconds is enough to read the message before it clears.

    Naming of duplicated notes

    Originally, duplication of a note such as 'Note A' resulted in names like 'Note A copy', 'Note A copy 2', etc. The current note duplication is somewhat more considerate in choosing a name for the duplicated note. In particular, if the note name already ends in a number, that number is incremented rather than appending the word 'copy'. Thus duplicating 'Note 1', creates 'Note 2', 'Note 3', etc.

    New note name parsing for prototypes and locations

    When naming new notes it is possible to auto-add prototypes and locational data, borrowing from additional syntax for the zip-method of text link creation.

    Parsing for this special markup can be disabled in Document Settings ▸ General as in some cases use of # and @ are deliberate and literal, and not mark-up for the features below.

    When the setting is active parsing occurs when a new note is made or a title is modified.

    Setting a prototype

    Use a hash character and a prototype name after the new note name to set a prototype for the new note. For example, typing a new note title:

    John Brown#Person 

    makes a new note with $Name "John Brown" and sets its prototype ($Prototype) to "Person". If the named prototype exists in the document it is used automatically. If the prototype doesn't name a new, un-customised note of the specified name is add to the /Prototypes container. Thus:

    John Brown#Team X 

    would generate and set a new prototype called "Team X".

    When creating a new prototype, Tinderbox will set the Displayed Attributes to $Tags and add the prototype's name to $Tags. This aids rapidly finding notes after fast data entry.

    Setting a (place) location

    Use an '@' character and a location name after the new note name to set a location for the new note. For example, typing a new note title:

    John Brown@BigCo 

    makes a new note with $Name "John Brown" and links to the note named "BigCo", creating the latter if it doesn't exist. The new note is linked to the (new) location note using the (new) link type 'place'. If a now location note is created it sets the built-in prototype 'Place', adding the latter if not already present in the document.

    Be aware that for new locations, the address and latitude/longitude will need to be added manually by the user.

    In map view, if using @place with or without #prototype notation in the root-level map (i.e. the default map in a new TBX) Tinderbox may to first create the 'Prototypes' container. If so, this is placed above the current note to leave space for the place note; normally new notes are created to the right of the current note but as the Prototypes container is more of a structural folder is is helpful that it is not inserted between actual notes. If the container already exists (i.e. there are already prototypes) or the map is at any other level than root, no difference is seen.

    Using both options together

    Make a new note and include both the #-based and @-based modifiers described above. The effect is as shown in the screen grab here, at top of the page.

    Improved Parsing

    The parsing of tags and prototypes for brainstorming is smarter about a variety of special cases. Notably, if the first character after a # is a digit, Tinderbox assumes it is an action code expression like "Activity #3" and does not create a prototype. Also, email addresses in titles (mark@example.com) are not treated as introducing a new place (location).

    Non-editable notes

    To avoid accidental editing it may be desired to make a note 'read-only', i.e. non-editable, but there is no single setting that allows this.

    However there are two system attributes that cover aspects of this. Both date from the early days of Tinderbox before current heavier use of action code and so address only UI interactions.

    Here, 'note' applies also to adornments, aliases, and agents.

    There are three system attributes, with slightly differing purposes , of which to be aware:

    ReadOnly attribute

    The $ReadOnly system attribute affects only UI, i.e. manual, editing of the text pane, excepting the title bar. Thus it controls manual edit of:

    • in the text pane:
      • the $Text area.
      • the Displayed Attributes table (if used by the note). If $ReadOnly is included in the table it is always editable.
    • aliases of a note will honour the original note's setting (i.e. $ReadOnly is not intrinsic)
    • use of Get Info, as a pop-up or as a stand-alone window

    The original conception for $ReadOnly was to 'lock' the $Text of notes using AutoFetch to avoid the auto-imported $Text fighting against user manual edits. Later, scope was added to include Displayed Attributes. This explains the manual/UI-only nature of the setting.

    A note's $ReadOnly has no effect on:

    • $ReadOnly is always editable via any means
    • manual editing in the UI of the view pane
    • matching queries
    • action code (including stamps and the Quickstamp Inspector).
    • AppleScript or other inter-app/OS scripting

    Though action code may be set to check a note's $ReadOnly state, this would need to be applied individually to every affected action. There is no centralised switch for such behaviour (beyond using prototype-inherited code).

    $ReadOnly can be set via:

    Lock attribute

    The $Lock system attribute affects only the view pane and is was originally conceived for Map view use. It controls several view pane:

    • Map position, i.e. $Xpos and $Ypos
    • Map icon size, i.e. $Width and $Height
    • Selecting locked notes:

    **Locked items cannot be drag-selected (i.e. dragged marquee/band-box selection)—locked items are always omitted from such selections.

    • Locked items can be selected by manual click. In map view (only) selected locked items show no icon resize handles. The only indication of a selected locked item is the presence of the link-drag arrow (in views that use that), and even then the arrow is only shown if a single item is selected.
    • oving locked notes:
    • a locked note cannot be drag-repositioned in the view. This includes in other views, Outline, etc.
    • reflecting the fact $Lock was really designed for map use, the Note menu's Move Note Up/Down controls can be used to affect map icon stacking order.
    • similarly, the View ▸ Arrange menu and shortcuts do work. Alignment menu commands will override the $Lock status without changing the actual $Lock value and thus may alter note width, height and X/Y position values.

    A note's $Lock has no effect on:

    • manually editing title ($Name) subtitle ($Subtitle) or badge ($Badge) via the note icon in the view pane
    • manual editing in the UI the text pane
    • matching queries
    • action code
    • AppleScript or other inter-app/OS scripting

    $Lock can be set via:

    • for adornments only, when selected, via clicking the padlock icon. Note that the icon used for $Lock state can be customised.
    • Get Info ▸ Attributes
    • Properties Inspector, More text sub-tab.
    • the Displayed Attributes table (if used as a Displayed Attribute, but only if $ReadOnly is false)
    • action code or external scripting

    DoNotDelete attribute

    The purpose of $DoNotDelete is simpler.

    Outline vs. Map Interface

    Context

    Newer users often get confused trying to compare Outlines with Maps. This is not entirely surprising as Tinderbox always starts a new document with tabs with blank Map view and blank Outline view, the Map view tab being selected. The two blank view may look similar at this point, but they differ. This set of articles attempts to answer some of the functional side of the similarities/differences of the two view types. Note: words in this article with a $ before them indicate reference to a TB attribute, e.g. $Name is the title of a note. Here, we consider the outline and map views of the same TBX's content.

    So, "What's the point?" you may ask. If you set up a simple TBX like this you can see the effect of:

    *moving an item in the map: $Xpos & $Ypos change, but $OutlineOrder & $SiblingOrder are not affected.

    *using bring forward or send back on a map item: $OutlineOrder & $SiblingOrder change (and the item moves in the outline) but $Xpos & $Ypos are unaffected.

    *moving an item in the outline: $OutlineOrder & $SiblingOrder change but $Xpos & $Ypos are unaffected.

    How the TBX illustrated above was created

    On the left is the outline view, on the right the map view. The notes all have a short two-l or three-letter $Name like 'bb', 'ag' or 'rrr' and the rest of the title you see is a $DisplayExpression enabling you to see the $OutlineOrder on screen. Names where the two letters are the same are notes/containers (including separators); two different letters denote an agent; three similar letters denotes an adornment. In addition, in the map, the $Xpos and $Ypos X/Y location co-ordinates are shown; in notes/containers this is by displaying body text ($Text) and for adornments, which have no (visible) $Text, the $DisplayExpression has been further amended.

    How was the mark-up done? Prototype note '*Display' (in /Prototypes) has the following Rule:

    $Text = "Xpos: " + $Xpos + " / Ypos: " + $Ypos 

    …and DisplayExpression:

    $Name + " / OutlineOrder: " + $OutlineOrder 

    As we cannot display text in adornments, prototype adornment '*Adornment' (seen on the map of /Prototypes) uses a different $DisplayExpression, which has to be set via the adornment's Info view (General panel). Thus $DisplayExpression:

    $Name + " / OutlineOrder: " + $OutlineOrder + " / Xpos: " + $Xpos + " / Ypos: " + $Ypos

    You will notice that you will need to set icons a bit wider than the default and on notes/containers drag the title section down a bit to see all the captioning. Notice too that a map view container icon's viewport map shows $DisplayExpression but note text is not drawn as in a normal icon; see the icon for container note 'ii' inside the viewport of container note 'jj' at left of the map.

    Next

    Things seen in only one type of view

    What's only seen/used in one view or the other?

    Siblings. A Map view is the map of the contents of a single container. As such all items on the map are siblings. Items at the same $OutlineDepth but inside different parent containers cannot be seen in the same map. Thus, no matter how big the map view window is expanded or zoomed, it will never show notes like 'Context' and 'How this TBX was created'. This is because whilst the latter are the same $OutlineDepth as note 'aa' they are children of a different parent container and thus not siblings of 'aa'.

    Separators. These are only seen in Outlines. They are not drawn on a map. Separators may have a title (as here) if the note is given a name, otherwise the separator is simply a line drawn in the outline where a note would otherwise appear. A separator is in fact a fully functional note. The separator display mode can be toggled off/on via the 'Separator' tick box on the note's Properties Inspector's Prototype sub-tab. Incidentally, if a separator is toggled back to a normal note, it will appear on the map as well! A separator can also act as a container. Making a map container a separator can be a way to hide map content, removing the separator flag (via outline view) will return the content to the map.

    Adornments. These are map-only objects (but note they can display in Timelines too). On a map, adornments always show up behind all notes..

    Container viewports (Notes inside containers, nested child notes). Containers (and agents) show a small part of their nested contents via their 'viewport'. In general, any descendant notes/containers (i.e. at a lower $OutlineDepth than the current one) are invisible to maps unless within the scope of a viewport.

    Link lines. Not shown in the illustration, Tinderbox links are only shown in map views (assuming a link type has not had visibility toggled off).

    Otherwise we have notes, containers (notes containing notes) and agents (in this context consider agents as just another sort of container); all these objects are shown on both outlines and maps.

    NextWhat is OutlineOrder?

    What is OutlineOrder?

    What is OutlineOrder?

    It is a number value that indicates where, in the overall outline of the whole document, a note is to be placed. If you start a new outline and add 3 notes, they would have $OutlineOrder numbers 1, 2 and 3; the parent TBX document itself is always number 0 (zero). If you then dragged item 3 above item 2 and inspected $OutlineOrder (do this via Info view, General group) you would find old item 3 now has $OutlineOrder 2, as it is new the second item in the outline. If you nest notes and expand all the nesting, the outline numbering runs from top-to-bottom. The descendants of top level item 1 all number before top level item 2, etc. $OutlineOrder is found in the General group of system attributes.

    As the name implies $OutlineOrder does affect the outline. The attribute is read-only and cannot be changed directly via action code but alter $OutlineOrder by any other means and the outline ordering will change to reflect this. For instance, add a new note higher in the outline order and an all notes below will have their $OutlineOrder recalculated and increase by one. However, and importantly for this article, $OutlineOrder is not used for controlling placement of objects on a map view. That said, $OutlineOrder does have an affect on stacking/overlapping on maps but more on that later. The lower the $OutlineOrder, the higher up the outline view that item will be drawn.

    Note that the outline's separator ('gg') is not shown in the map, and not because it is just elsewhere on the map. Also notice how although note 'kk' is the next sibling to 'jj', it is not the next in $OutlineOrder as all the descendants of 'jj' are numbered in between 'jj' and 'nn'.

    Aliases have their own 'intrinsic' $Xpos/$Ypos/$Height/$Width/$OutlineOrder/$SiblingOrder values. Note how the alias of 'bb' is in a different map location and has a different size (but not $Shape) from its original note It also has its own number in the outline order.

    In the outline part of the picture, notice the 'READ ME' note has an $OutlineOrder of #22, whereas the last item listed before it, the alias of 'dd', is numbered #19. The missing numbers are the map adornments (#20 & #21), which of course are not visible in the outline. This is because adornments always list after all other items in the same container's map, i.e. including such items as separators.

    NextWhat is SiblingOrder?

    What is SiblingOrder?

    $SiblingOrder

    The $SiblingOrder is the top-to-bottom order, as seen in an outline, of siblings with a common container (including root level notes. The siblings number from one and the $SiblingOrder is a read-only calculated number. Within a set of siblings with no descendants, the sequence of $SiblingOrder will match the notes' $OutlineOrderSequence. However, if any note has descendants, all the latter list in $OutlineOrder before the next sibling note of their ancestor (see the previous article on $OutlineOrder for more).

    In export contexts, the outline view is normally used which does not show adornments. Thus the last note in a container may not be the last outline order item in the container although it is the last exportable item. To help avoid the latter problem, the $SiblingOrder system attribute ignores adornments making it easier to detect unambiguously the first/last item in the container during export.

    Whilst in Outline, $SiblingOrder is easily intuited

    NextMap co-ordinates

    Map co-ordinates

    Map co-ordinates

    Tinderbox uses Cartesian X/Y co-ordinates (basic graph style) to record the position of items on maps, but with one small difference; the polarity of the Y axis is reversed. So going downwards on a Tinderbox map is positive Y and up is negative Y. Why so? Tinderbox starts a new, unused, map by putting {0,0} at the top left of the map window (whether the map is visible or not) and starts drawing items down and right from {0,0}, i.e. the map is populated from the top left corner. By flipping the traditional Y polarity, new items are normally drawn with both X and Y co-ordinates as positive values. Understanding the positive/negative alignments is pertinent if using code to move items around on a map but for general use the is no need to worry about co-ordinates.

    Position on a map is controlled by (stored in) the system attributes $Xpos & $Ypos for a given note (in the Map group of system attributes). These co-ordinates have no effect on the outline view, or any other view type than map.

    NextMaps, stacking and overlapping

    Maps, stacking and overlapping

    Maps. Stacking and overlapping

    $OutlineOrder does have an indirect effect on your map, insofar as it sets the z-order (stacking order) that is applied when map icons overlap. When two container or note icons overlap, the item with the lowest $OutlineOrder is shown in front of the other icon. Thus, in the early stages of a map or outline, the$OutlineOrder tends to reflect the order in which the notes were added. In such a circumstance, in a map you can work on the principle that older notes will stack on top of newest notes (this can be slightly counter-intuitive at first encounter as we tend to think of putting the newest item on top of an older one). Tinderbox's Note menu does have 'move to front/back' and 'move up/down' controls (and associated shortcuts) which change this stacking order but do be aware that such an action also affects outline view. How? As these commands change in the map z-order, the map's overlapping order, they also change the selected note's $OutlineOrder. In turn, this moves the selected note(s) higher or lower in outline view. If there is more than one adornment on a map the same rules as above apply if adornments overlap, though this can be hard to see due to the opacity of adornments.

    In the screen grab, map icons have been arranged with some overlapping to give visible proof of how $OutlineOrder affects this. Looking in the top right corner 'ee' sits over 'cc' but under 'bb'. Described in $OutlineOrder terms it is clearer: #6 sits over #7 but under #4; the lower the $OutlineOrder, the more siblings in front of which it will sit if overlapping of icons occurs.

    Adornments. A new adornment is always dawn at the top of the adornment z-order (i.e. the opposite of behaviour with notes). To achieve this, a new adornment takes the $OutlineOrder of the current lowest z-ordered adornment and all others are bumped up one in the outline order. In other words, they take an initial $OutlineOrder in reverse sequence of creation within the current container, starting above the highest outline order numbered note. Thus adding a note also increments by one the $OutlineOrder of any existing adornments. Witness the highest $OutlineOrder on our map is #19 (given to an alias of note 'dd') but adornment 'ppp' has an $OutlineOrder of #20. The newest adornment always has the lowest $OutlineOrder of all adornments on the map (here 'ppp' was actually added after 'rrr', despite the order of naming).

    A small difference with default adornments is that they are slightly translucent so the background items border shows through. This is deliberate as it allows more creative use of adornments: for instance, to create zones to place icons that are relevant to two or more different adornment-denoted ideas. Thus, something that was pertinent to both 'rrr' and 'ppp' might be placed on the darker blue rectangle where the two adornments overlap.

    Smart adornments. If a note matches more than one smart adornment on a given map, the note is moved on top of the smart adornment with the highest $OutlineOrder as this represents the firs created/oldest of the matching adornments.

    New adornments are placed on top of existing adornments, i.e. added as the first adornment in outline/sibling order. This is the reverse of past behaviour (and continuing behaviour for notes) but should be more intuitive for users as generally a new adornment would wish to lie atop an existing one. The effect is achieved by the new adornment being inserted in $OutlineOrder before all existing adornments in the map, as opposed to after them as in the past.

    NextAdding or Moving Items

    Adding or Moving Items

    Adding/Moving items

    In outline view, a new note is added after the selected note, or at the end of the outline if none is selected. In a map, a new note icon is added to the right of the currently selected item, to the right of the top-right-most map icon if no note is selected, or if making the note via a right click it is at the mouse cursor position. So far, so good. New items added in the map simply take the $OutlineOrder one higher than the last listed note for that container (all notes below that have their value bumped up one) so we know where it will appear.

    However, notes added in Map view via a double-click on the map background are treated differently; Tinderbox will try and add the note in outline order one higher than the note to the left and/or above it on the map. This helps if adding notes into a sequence that are later overlapped or viewed as a group in a different view. (See more on adding notes to maps).

    For a note added in outline, TB will try to place it to the right of the preceding ($OutlineOrder) item on the map or close to it if the new icon would overlap other existing map note/container icons.

    The above may all seem rather complex but just go experiment and you will see the 'rules' for order and placement are pretty simple once you have tried them out. Rules are less clear for map placement for items demoted/dropped into containers (via any view type window), but generally selection moved this way will retain their relative positions. Even if created in outline, a new note gets a $Xpos/$Ypos value pertinent to that container. If such a note is dropped into another container, it appears to try to maintain those co-ordinates unless that conflicts with those of a note already occupying that location in the destination container('s map); if such a clash occurs then TB uses its logic for new items placement to de-conflict the icon positions. Very occasionally, two items of the same height/width will overlap exactly; in such circumstances switching to an outline view can be useful in locating any inadvertently 'hidden' items.

    If you start adding data in outline view, the map when first opened can look a bit messy. Conversely, you may find the outline's order looks a bit incoherent with differing topics intermingled. Remember the above $OutlineOrder vs.$Xpos/$Ypos description. Re-ordering the outline via drag drop will not move map icon but may affect stacking order if icons overlap. Re-ordering the map by moving around icons will not affect the outline view (unless you alter overlapping priorities).

    Adornments and moving. Select an adornment and at top right it will show padlock and push-pin icons. Click these and the icons change. The change reflects the state of two Boolean attributes, $Lock and $Sticky (these can also be set via action code, rules, etc.). Normally, when an adornment is selected and moved, it moves independently of both the map background and any notes or other adornments. When an adornment's $Lock is true, it is locked to the map background. Selecting and moving a locked adornment simply scrolls the map; any items on the adornment move too but only because the whole map is moving. When an adornment's $Sticky is true, if moved it 'holds onto' any notes (or adornments) that are on top of it or partially overlap it. The adornment moves relative to the map background and any 'stuck' items move relative to the adornment. The latter makes it possible to easily move whole sections of a map around without complex selections. An adornment may be both locked and sticky in which case selecting and dragging the adornment scrolls the map whilst also bringing along any items stuck to it. Where adornments overlap, stickiness only applies to adornments (partially) on top of the sticky adornment, i.e. those with a lower $OutlineOrder value. It is worth noting that notes (and agents) have and can set $Lock and $Sticky attributes though doing so is generally not of great value compared to such use with adornments.

    NextHiding the map icon viewport in containers and agents

    Hiding the map icon viewport in containers and agents

    Hiding the map icon viewport in containers & agents

    One last trick, not really related to the above but useful for tidying up a map. In the outline, notice note 'nn' is a container but in the map, its icon (bottom left) has no viewport. How's that done? It is actually quite simple. We set $TitleHeight = $Height, effectively hiding the viewport. $TitleHeight controls the vertical depth of the icon caption area. Notice that the bottom corners of the 'nn' icon are still rounded so the sharp-eyed should still be able to spot the container-masquerading-as-note on their map. If you lose track of 'hidden' containers, just open the map as an outline and look for any item with a disclosure ('flippy') triangle to the left of the note name.

    Fine, but now we have hidden the viewport in 'nn' we cannot drill down as we cannot double-click the viewport area. Another little trick: select 'nn' and then use shortcut [Cmd]+[Opt]+[down-arrow]. Boom! The 'nn' container opens and we see the 'oo' icon. Go back up a level and 'nn' is unchanged and still hiding its content.

    The agent 'ag' illustrates the same viewport hiding trick as shown with note container 'nn'. Notice how the agent retains the rounded corners at the top of its icon (for a container the rounded corners are at the bottom of the icon). I also found with the agent that if we set $TitleHeight = $Height, then the (display) name is written a bit too close to the top margin of the icon. Happily, if instead we set $TitleHeight = $Height - 0.1, it looks fine. As that also looks good with containers, using the latter action code expression is a better one-size-fits-all code for viewport 'hiding'. Note that as borders are drawn inside the width/height of the icon, if you set big borders you may need to reset the $TitleHeight—at least for agents.

    Pane focus indicator

    When the text pane or the view pane acquire the keyboard focus, either by being clicked or by Option+Tab (Tab) shortcut, a focus ring briefly appears at its boundary. If a pane ceases to hold focus during the animation, the animation is cancelled.

    The focus ring is drawn in the macOS current focus colour (default: a light blue)

    Pasting notes: creation and modification dates

    When a note is copied and pasted, the newly-created note has $Created and $Modified set to the time it was created. Formerly, the pasted note retained the $Created and $Modified values of the original note.

    Pictures in notes

    Pictures (bitmap images) can be added to Tinderbox in one of two ways:

    Embedding pictures in notes

    To add an image to a note, select a supported image format file in Finder and drag it into a Map view (but not other major views), or copy/paste from Finder. A new adornment note will be created with the image embedded in the $Text of the note. The note is otherwise a normal note and can be moved around, renamed and have additional text added to $Text without affecting the image.

    Once imported in this fashion, the image can then be selected/copied from the new note and pasted into other note(s). To create a note with multiple images, import each image as a separate note and copy/cut paste the data as necessary.

    Images embedded in note $Text cannot be cropped, scaled or otherwise resized (thus unlike image adornments). Select the desired image size before adding the image file to Tinderbox.

    If an image pasted into the text is wider than available space, it will automatically be scaled.

    Export

    Notes with images in $Text will export those images during HTML Export (but not text export)

    Embedded image size control

    The maximum width of the stored image based on an image added to $Text, is controlled by $ImageSizeLimit. If the added image width, in pixels, is greater than $ImageMaxSize (default 1600 px) the embedded image created is scaled to the maximum allowed size; the height is scaled, if needed, in proportion the change in width. Image added below the maximum are added at their actual size.

    Images and document size

    If the TBX is primarily intended for export, like this document, it may make more sense to store the images outside the TBX and link the exported pages to the external assets. Given that embedded images do not export )at least not in v5.x) then it is possible for a note to have both an embedded image for viewing within Tinderbox and alongside it export code that links to an externally stored coy of the image for use in HTML.

    Tinderbox compresses images; this substantially decreases the size of Tinderbox files with embedded images. Tinderbox currently uses JPEG compression, and compresses fairly aggressively; this significantly diminishes the size and loading time of Tinderbox files at the cost of some image degradation. Images are stored in the TBX file's XML using Base64 encoding.

    Previewing and exporting note content

    Tinderbox takes a new approach to export preview, since v9.5.0. The guiding principle is that Preview should now be readily available for any note, without configuration and without understanding templates. Where in the past this happened behind the scenes, Tinderbox now creates—adds if needed—templates that operate normally and that can be extended and modified.

    In overview, Preview is now much simpler to use. If there is not already an export template, Tinderbox will add a built-in simple template into /Templates/Preview (and its container if not present). That template can be customised if desired but this is not a requirement for use of Preview. Similarly, if the document does not yet have an export folder set, Tinderbox makes a temporary folder for the preview, and cleans up after preview is no longer in use. This process is explored in more detail below, including considerations for those with documents set to export but previewing non-exporting notes.

    Template (and CSS styling) assignment

    If a note is previewed and it has an assigned export template, Tinderbox continues to use that template. This is essentially the original use, that of checking (HTML) files before export.

    If a note is previewed but has no assigned export template, Tinderbox adds a built-in template 'Preview' to /Templates/Preview. If the latter does not already exist, Tinderbox does the following:

    • if not present, the Hints container is added to the document.
    • at /Hints/Preview/style is makes a new note, which contains a style sheet that is automatically included in the preview template.
    • assigns the newly-created 'preview' template to the previewed note. If either or both of these notes exists ('preview', and or 'style', the pre-existing note is used.

    Both the template and the CSS styles can be altered by the user. To reset to the original would involved deleting either file and re-invoking its addition. Hint: perhaps keep a copy of the original alongside the edited version using a different $Name for the note with the original data.

    Note: in older versions the preview template was stored under Hints at /Hints/Preview/preview.

    Support for legacy markdown stylesheets, stored in the application support Markdown folder, has been discontinued. Copy any preferred style definitions to /Hints/Preview/style.

    Preview character encoding

    if a previewed note's template has no character encoding tag (e.g. ), Tinderbox adds a preview-only framework to ensure that the preview pane uses the expected character encoding. This stops non-ASCII characters appearing corrupted in the preview.

    Files generated via use of preview

    When previewing HTML for a document that has an export folder, Preview now exports (a) the current page, and (b) any pages to which the current page has text links, if those pages are not currently already exported to disk. If the current page is already present on disk, the current version is saved and exported later (i.e. reverting back over the preview file.This stops preview of possible changes from overwriting a previous 'good' copy of the export file.

    If there is no pre-existing export the new preview file is left in the export location. In addition, previewing any note will generate and file at the export location.

    If there is no export folder defined for the document, Tinderbox uses a hidden temporary folder to hold the exported files and cleans up afterwards.

    Why do this? This arcane waltz is necessitated by ill-documented macOS security measures which appear to offer little if any benefit to security, but which consumes time and resources that might do someone, somewhere, some good. So, not ideal, but forced by macOS limitations.

    Considerations for users of both preview and export

    Because preview activity must result in files in the export location that are not the result of deliberate export, users are advised to delete any current exported files before doing a full export of a document. Given the speed of export now, re-exporting all files takes negligible time.

    Selecting notes

    Select. Click on an item (note, agent, adornment, etc.) to select it.

    Adjust selection. Cmd+click on a note to add/remove from the current selection. Cmd+click on the background does not clear the selection. This makes it easier to do non-contiguous selection on busy/small-scale maps and where the chance of accidentally clicking the background by mistake is greater.

    Adjust selection (Outline or Chart view only). Shift+Click on a note to extend the existing selection up/down from the last selected note.

    Band-select. Option+drag to band-select notes.

    Select All. Cmd+A (A) selects all items in the current view (excluding non-displayed child/descendant notes).

    Deselect all. Cmd+Opt+Ctrl+A (⌘⌥⌃A) deselects all of the current selection. Also, click on the view pane background to clear the current selection.

    Multiple-item selection. Bear in mind the effect on any nested descendants (i.e. in collapsed containers). The contents of collapsed containers are ignored, i.e. only visible items are selected. This allows a set of containers to selected and acted upon without affecting their descendants. However, if such a selection is:

    • copied, the result will take into account any descendants.
    • option+dragged, only the visible selected items as copied.

    Setting a prototype

    Once some prototypes have been added to a document, they can be applied to a note in a variety of ways. There is no one 'correct' way as the method chosen depends on the type of view in use and the task being undertaken. Amongst the ways to set a note, adornment or agent to use a prototype are:

    *In Map view, right-click the prototype tab and select from the pop-up list of prototypes; applies to for notes, agents and adornments.

    *In Outline or Chart view, right-click the item's icon and select from the pop-up list of prototypes.

    *In any view, select the note, open the Prototype sub-tab of the Properties Inspector, and select from the pop-up list of prototypes.

    *In any view, select the note and use the Quickstamp sub-tab of the Properties Inspector to set that item's $Prototype attribute using action code: e.g. using this code $Prototype="X" as the quickstamp will set the prototype called 'X' for all currently selected items.

    *If you frequently need to set a particular prototype, make a stamp whose action code sets a $Prototype value. Then (re-)use the stamp, either from the Stamps menu or the Stamps sub-tab of the Document Inspector.

    *If most or all the notes in a container use the same prototype, use the container's $OnAdd action to set a $Prototype, saving you the bother of doing it yourself.

    *If all the notes that meet some criterion need to use the same prototype, create an agent whose agent action sets that prototype. In this case, the action code in the agent's action will set a value for $Prototype.

    Spell Checking scope

    To improve support, spell checking is enabled by default in the title field of the main window text pane, and some other text fields—such as that for note titles (i.e. $Name). Previously the checking was limited to the $Text area.

    It may be toggled by choosing menu Edit ▸ Spelling and Grammar ▸ Check Spelling While Typing. This state is saved with the document.

    Suggest Attribute value lists

    This is a means of pre-populating attribute value pop-up lists with values that may not yet be in use by any note. Suggested values apply to String/Set/List data types only. If the list of likely values is known in full (or part) before the such data is added to the document, it is easy to pre-populate the attributes value list via the 'Suggested' box on the relevant Inspector for User and (some) System attributes.

    Suggested values always appear in the value menu of Displayed Attributes, and are always offered for autocompletion, even if no notes currently use them. Suggested values may be added to attributes

    Pop-up value lists do not indicate which are suggested values. Thus it is not possible to tell apart currently used values solely by inspecting a pop-up that includes suggested values.

    Suggested values are always per-attribute, at whole-document scope. this means it is not possible to set different suggested values of the same attribute for different notes.

    Defining suggested values

    In the relevant Inspector, enter the list of suggested values as a semi-colon delimited list without any enclosing quotes; this follows the normal Tinderbox convention for defining a list in action code. Thus, to pre-populate an attribute with values 'Ant', 'Bee' and 'Cow' the unquoted string to enter into the Inspector's suggested box is Ant;Bee;Cow. A terminating semi-colon may be used but is not required. It can be helpful to prepare the list in the text of another note if it is long and will extend beyond the visible portion of the suggested box; copy the text and then delete the note.

    If adding a list to a document that already has values, it may be useful to first test the new list in a new document to ensure the correct values show up in a Displayed Attributes pop-up. Indeed, this method does not prevent new values (i.e. those not in the suggested list) being used. If trying to assert a fixed list of values and new values are seen in the pop-up list, note the new value(s) and use an agent to find and correct the notes with the unwanted values.

    Automatically setting suggested value lists via action

    See Pre-populating Displayed Attributes pop-up lists.

    values() and suggested values

    The values() operator only returns used values and thus omits any unused suggested item action. This can be used a a method to test if any suggested values are currently unused.

    Legacy

    A note for long-time users: this method replaces an older approach of making 'seed' notes as placeholders for desired prepared values.

    Tear-off windows

    Some pop-over dialogs, listed under Secondary windows, can be turned into stand-alone windows and are sometimes described as 'tear-off' windows. Pop-overs supporting tear-off advertise this possibility with an icon in the top right corner of the pop-over.

    Tearing-off is done by clicking-and-dragging on the margin of a pop-up (any margin of any edge). After a small distance of drag, the pop-up will change to discrete window.

    Tear-off windows have normal window controls and can be closed or minimised like other windows.

    The torn-off state does not persist beyond the end of a document session, i.e. when the parent document is closed. This different from actual notes opened as stand-alone windows.

    Currently, the pop-overs offering a tear-off option are:

    Text for multiple selections

    When selecting a composite or multiple notes, the text pane shows the concatenated $Text of all the selected (or composite) items. See Text pane multi-item selection for more detail.

    Title Strike-Through

    In most major views, titles can be rendered with a strike-through. This can be triggered a number of ways:

    • Directly setting the $NameStrike attribute via code
    • Format ▸ Font sub-menu
    • Shortcut [Cmd]+[Shift]+[-] (⌘⇧-)

    This can be useful for applications like 'To Do' lists to help indicate completed or actioned items.

    View filters

    View filters are currently implemented in Outline view only.

    Wrapping of long titles

    In most views, long titles wrap to successive lines, as illustrated in Outline view. In occasional cases, if all titles do not wrap as expected, re-size the view window slightly to force a re-draw of the window and wrapping should be correct.

    In map view, there is a preference to auto-expand notes horizontally or vertically. The same commands can be called via menu or shortcut if the preference is not set.

    Formatting

    Command Line

    Tinderbox allows users to extend its capabilities by giving users access to the command line (CL) in a number of ways:

    The above actions and attributes enable execution of stored command lines or action code expressions. For the attributes above, the command line is run on the post-processed of HTML output or AutoFetch input.

    The most flexible method is runCommand(). See the referenced note for more detail. The runCommand() operator can also be used to call external scripts, i.e. script files stored in the OS outside the TBX document, using an POSIX-style path (i.e. slash-delimited, not colon-delimited); paths can be absolute or relative.

    Scripts used without a path are assumed to be in the shells current working directory ('pwd'). Tinderbox's default directory is working directory is the user's home folder (i.e. /users/[shortusername] or in short form ~); each new runCommand call thus starts at even if it was altered in a previous call.

    CL code can also be stored in string attributes, such as $Text, but only when using runCommand(); the other methods above require literal CL code. Referenced CL code is called thus:

    runCommand($Text("CL example")) 

    Using a note's $Text to hold code can be very useful for CLs too long or complex to work on easily in a $Rule or $OnAdd box. In the $Text area you can use a monospace font, crank up the font size, etc., Tinderbox provides an easy method via the built-in prototype 'Code'.

    Because of the external calls involved, CLs used in action code such as agent actions, can have significant impact on agent cycle time. This is especially so if using CL code to process text. In an agent context, consider turning the agent off (via $AgentPriority) when processing is not needed.

    It is worth noting Tinderbox's support for single-quote and double-quote string quoting but bear in mind that there is no method for escaping a double quote character.

    Working directory location

    When accessing the command line this way the targeted location is the host Mac's home directory. Regardless of other Terminal sessions that may be active, the current directory for Tinderbox access is the root of the current volume, i.e. '~'. Thus, if calling scripts or programs elsewhere on the host system, such as in the user's account's 'Documents' folder, remember to prefix an appropriate path to the script/program (or set a new directory via the method described below).

    If the working directory is changed as part of the runCommand call from Tinderbox, that change will hold for the remainder of the call. For instance, a runCommand() string "cd ~/Documents; pwd" with return the full path to the user's Documents folder (e.g. '/Users/jdoe/Documents') and will become the working directory for all subsequent commands passed in that string, but not for calls from other notes. Observe the trailing semi-colon after the cd command, this tells the command line that the first command is complete allowing a follow-on command to added with is executed after the previous one. In the example given, a follow-on command would execute within a non-default current working directory.

    Setting the working directory

    runCommand(command[,input(s),directory])

    If the optional directory is specified as a POSIX path, it sets the working directory in which command is executed. Otherwise, by default, the working directory is the user's home folder (i.e. /users/[shortusername] or in short form~).

    Script Permissions

    External script files also need to be executable. It is not enough to make a new file in something like TextEdit and save code into it, extra permissions are needed. By default a file is 644, a script needs to be 755. Assuming a script in your home folder, and a root working directory, this can be done with a runCommand() call:

    runCommand("cd ~; chmod 755 somescript.pl") 

    Of if the script name is stored in a notes $MyString:

    runCommand("cd ~; chmod 755 "+$MyString) 

    Copy to Clipboard

    When note(s) selected in a major view and copied to the OS clipboard, Tinderbox adds a textual list of the note names with one note name per line (paragraph) when pasted back outside Tinderbox. This should be handy for copying to word processors and email.

    Within Tinderbox different results apply.

    Date Formats

    IMPORTANT: an explanatory note re formats. The examples here are for US & UK system settings so as to illustrate day/month and month days variations. The exact styled out any user sees on their own Mac from the same format string may differ depending on their computer's OS' local settings (macOS, see System Settings ▸ General ▸ Language & Region—also see Locale (below). For reference, this TBX was authored on a system using UK settings, so generally expect to see example dates use day/month order where only one example is given.

    Example date/time for this article. An example date Tue, 29 Apr 2003 14:32:18 +0500 is used to show the following various format strings below.

    OS Date/Time variants. Although no longer explicitly labelled in macOS System Settings app's UI, short/medium/long variants still exist.

    Tinderbox offers numerous date formats, for some internationally recognised standard formats, e.g. ISO 8601, and codes do allow assembly of custom date format from individual date and/or time elements. The latter codes are thus like placeholders in a literal string:

    $MyString = Today is " + date("today").format("W, d MM y") 

    On 29 February 2012 on a UK-locale system this makes $MyString:

    Today is Wednesday, 29 February 2012

    Note above how the spaces and comma within the format string are retained.

    Below, the colons after each (bolded) code are not part of that format code but just a divider from the text that follows it; codes are all one or two characters. In places, clarification is given, e.g. number zero versus letter o. Dates before 1 January 1904 (start of the macOS calendar) are supported: see more.

    Locale. Date display and formatting is aware of locale and by default this is the locale set in the host macOS. For most users this means date layout, month/day order, etc. will look as they would expect. Occasionally, some user may need to see data date as for a different locale and this can be effected via the locale() action code operator.

    Time offset calculation: the time offset is always applied for the current time in the current locale as derived from the host macOS. If using this TBX with different locale settings to the author's Mac, expect differences in the offsets reported.

    Keywords used in specifying dates

    Although not related to formatting dates, there also date/time-specific keywords, e.g. now, yesterday, etc., that can be used when setting Date-type attributes.

    Escaping date/time code characters as literals

    Prefacing any character with a backslash, \, includes that character literally, even if it otherwise has a special meaning in the above list. Thus a format string of "\dd \mm \yY" gives the output d29 m4 y03. Any other character includes the character.


    Date/Time formatting codes

    Specific complete formats:-

    L  : local date/time, as in the 'long' format of the host system format settings. Examples:

    US: April 29, 2003 
    UK: 29 April 2003

    l  : local date, in short format, using the system format settings (l is lowercase L, not numeral one). Examples:

    US: 4-29-03 
    UK: 29/01/03

    *  : date/time in RFC 822 format. Example: Tue, Apr 29 2003 14:32:00 +0500 (see note above on time offsets)

    =  : date in ISO 8601 format. Example: 2023-04-29T14:32:18+05:00 (see note above on time offsets)

    ==  : date in ISO 8601 format but with date only and no time element. Example: 2023-04-29 (see note above on time offsets).

    U  : formats the data in Unix epoch time, i.e. the number of seconds before or since the beginning of 1 January 1970.

    n for ('normal') : displays the system 'medium' date string and 'short' time string. Example; 21 Jan 2020 at 17:12.


    Formatting code for specific parts of date/time, combine as required for custom format strings:-

    Formatting codes for the day part of a date:-

    d  : day of the month, not zero-padded. Example: 9 (note, not '09')

    D  : formats the date of the month as a two digit number, with a leading zero as required (01-31). Example: 29

    o  : day of the month as an ordinal (lowercase 'o'). Example: 2nd, 10th, but conversion respects the current locale's abbreviations.

    w  : abbreviation of weekday. Example: Tue 

    W  : name of weekday. Example: Tuesday 

    Formatting codes for the month part of a date:-

    m  : number of month, not zero-padded. Example: 4 (note, not '04')

    M0  : formats the month as a two digit number, with a leading zero as required: 01-12. Example: 04. Note the second format character is zero, i.e. the format code is 'em-zero' not 'em-oh'.

    M  : abbreviation of month. Example: Apr 

    MM  : name of month. Example: April 

    Formatting codes for the year part of a date:-

    y  : 4 digit year. Example: 2003. (On some countries' settings this may still be 2 digits.)

    Y  : 2 digit year (last 2 digits of year). Example: 03 

    Formatting codes for time:-

    t  : time, in local format. Examples:

    US: 2:32 PM 
    UK: 00:32

    a  : accepted as an input abbreviation for "am".

    p  : accepted as an input abbreviation for "pm".

    Formatting codes for the hour part of a time:-

    h  : hour of the day on a 24-hour clock, zero-padded for single digits. Examples: 14 from 14:32/2:32 PM, 05 from 05:32/5:32 AM.

    H  : hour of the day on a 12-hour clock. Example: 2 from 14:32/2:32 PM, 5 from 05:32/5:32 AM. Use with 'p' to show AM or PM suffix, e.g. "H:mm p" gives 2:32 PM.

    p  : the AM/PM of the hour, always uppercase, with no periods. Example: AM 

    Formatting codes for the minutes part of a time:-

    mm  : minute of the hour, zero-padded for single digits. Examples: 32 for 32 past or 05 for five minutes after the hour.

    Formatting codes for the seconds part of a time:-

    s  : second of minute, always zero-padded for single digits. Examples: 02, 18.

    Dragging text within $Text

    Within the text pane you can drag a $Text selection containing text links and move the links along with the text.

    Number Currency Formats

    Number-type data can be formatted using the format() or .format() operators:

    $ for local currency. When formatting numbers format("$") and .format("$") apply conventional formatting for your local currency – for example, "$1,063.52" from number 1063.52. Usage:

    $MyString = $MyPrice.format("$") 

    $0 for rounded local currency. The second character is a zero and not letter 'o'. When formatting numbers format("$0") and .format("$0") apply conventional formatting for your local currency, rounding to the nearest currency unit – for example, "$1,064" from number "1064.32".

    The above currency format converters will use explicitly-set locales, rather than be fixed the user's default system locale.

    Duplicating items

    Duplicating and note, separator, container, agent or adornment should create a new copy of the item appending the word "copy" to the note title. If a note's name contained characters other than digits but ends in a digit, the number is incremented. For example, duplicating "42" creates "42 copy", while duplicating "Catch 22" creates "Catch 23".

    However, note that a container's contents are not duplicated if only the container is selected (regardless of whether its contents are displayed or not).

    If more than one item is selected, each item creates a copy of itself, alongside its sibling and preceding it in sibling order (i.e. one lower in $OutlineOrder). Nested items, which must be visible and selected, are created at same outline depth as their source note, and as siblings of their source note, not children of their duped parent. Selections need not be a continuous block of items but can be non-contiguous selections and from one or more outline levels though they all need to be visible in the current view (so as to make the selection).

    Links. Outbound basic and text links (including web links) are created in the copy. However inbound links to the original note are not and need to be recreated for the duplicate, if such are needed. Thus if splitting a note by duplicating and then deleting different parts of its text, consider reviewing inbound and outbound basic links as these will need some manual triage.

    Option+dragging a selection adds all the new items in a single contiguous sequence although any nested items are created at the outline depth of the top-most item in the selection. For instance if a root level note and one of its children and grandchildren are selected, and Option+drag will result in three sibling notes at root level. There is no way to drag+copy and maintain relative outline structure.

    Formatting attribute values for display

    Per-date-type information: attribute data types.

    Action code: formatting operators.

    Last-used OS folder

    Be aware the Tinderbox uses the same stored folder name for:

    • opening new files
    • saving files
    • doing a 'save as'
    • HTML export
    • text export

    If unaware, this sharing of one location can easily confuse the user as export location(s) are usually different from these used for file open/save operations.

    Linking to local files (File-type attributes)

    The System attribute $File and File-type User attributes can link to a single file or folder per attribute. When displayed in the Displayed Attribute table, this attribute type has a folder icon to the left of the value box. Clicking the button allows setting a target folder or file. Or, if set, files are opened using Finder and folder are shown in Finder.

    If the destination document may move around on the user's system, it may prove more useful to make an alias for the destination document, place the alias in a location where it will not get moved and link the alias to the Tinderbox attribute. If the alias method is used for many notes/files, it can prove useful to create a single Finder folder for all these aliases and thus stop the aliases themselves from being moved and so breaking the Tinderbox attribute's link.

    As stated, the link can be to a folder. Using the latter allows a single note/attribute to link to a collection of files, for instance a folder containing all files relating to a particular project.

    Markdown preview rendering

    Note: Markdown is not a core feature of Tinderbox, although it supports its use as detailed below. Thus, problems using Markdown syntax to get the correct HTML output are best researched in the Markdown community. Or, if asking in the Tinderbox user forum be mindful that not all Tinderbox users know about or understand Markdown.


    How does Tinderbox know to parse a note for Markdown markup?

    This is done if $HTMLMarkdown is set to true for a note. This occurs in a number of ways:

    • zero-configuration use of the text pane 'Preview' tab. Doing this in a document with no export templates, adds the Hints folder (and its preview-related content. This includes setting the note's $HTMLMarkdown to true.
    • setting a note to use the built-in 'Markdown' prototype (which sets $HTMLMarkdown to true).
    • setting $HTMLMarkdown to true either manually or via action code.

    As well as parsing for Markdown syntax such notes also evaluate the $Text as ^text^, including any inline ^export^ code within the $Text. Any inline explicit HTML code is treated as deliberate code (as opposed to literal text) and so is not escaped.

    Details of how Markdown and its various flavours work is out of scope for aTbRef and should be researched in Markdown resources such as markdownguide.org.

    If no export template is defined for the note, the built-in default of ^text^ is used for selecting the content shown in the preview.

    Tags embedded in the text such as ^value()^ are evaluated before being passed to Markdown.

    Do not use place Markdown style marking around Tinderbox links in $Text (neither text nor web types of links) or the Markdown parser will double-encode the web link; it will look like a link but not work. In such a scenario, always check the source HTML of the exported page, or if working in the in-app Preview tab, look at the HTML code in the text Export tab.

    From v11.7.0, many changes and improvements address the scenario in which the Tinderbox user has written styled text in a note, but would like a Markdown representation of the text. AI tools, for example, like Markdown. As a result, Markdown export now correctly interprets styled text like bold, italic, superscript, subscript, strikeout, and code font within $Text.

    From v11.7.0, Markdown export honours Markdown mark-up for inline code (back-tick before and after) and fenced code blocks (three back-ticks on a discrete line before and after code). For code blocks a space plus a text label indicating the type of code (and styling to use) may be added to the opening line's back-ticks.

    From v11.7.0, if a note is using Markdown (i.e. $HTMLMarkdown is true), $TextMarkdown simply copies $Text since it is already Markdown.

    Markdown variants available

    Unlike HTML, evolution in the Markdown community means there are a number of 'flavours' of Markdown available. Each shares core Markdown feature support but then adds additional syntax/features some or none of which are compatible with other Markdown flavours.

    The Tinderbox app ships with three flavours including:

    • 'CommonMark'. This is an internal pointer to the bundled copy of the newer and faster rendering fork of the original Markdown. Details of CommonMark features and how they work are at commonmark.org. CommonMark preview permits embedded HTML.
    • 'Markdown'. This is an internal pointer to the bundled copy of the original Markdown processor. Details of CommonMark features and how they work are at daringfireball.net.
    • From v11.6.0, 'MultiMarkdown'. If HTMLPreviewCommand is "MultiMarkdown", a built-in MultiMarkdown processor will be used.
    • OS path to some other Markdown script. This allows Tinderbox to use a specified Markdown variant (e.g. one to which the user has added extra plug-ins) stored in the host macOS system.

    In all the choice can be altered by setting the $HTMLPreviewCommand. If the latter is left blank (the default) 'markdown' is the assumed variant to use.

    When using export, the text pane's Export tab displays the current note's $HTMLExportPreviewCommand value and allows the Markdown processing to be toggled on/off to help with troubleshooting its use.

    Details of Markdown syntax and its various flavours work is out of scope for aTbRef and should be researched in Markdown resources such as markdownguide.org.

    Preview streaming to other apps. When a Markdown-prototyped note in Tinderbox is selected or edited, its export and Markdown code-evaluated contents will be sent to apps that support preview streaming. Markdown apps currently known to use preview streaming with Tinderbox:

    Negative Dates for years BCE or BC

    Tinderbox has the ability to handle negative dates, i.e. those years BCE (or BC). Negative integers from -1 to -2500, when coerced to Dates, are interpreted as years BCE (or BC). This is particularly useful for timeline view. Negative dates must be entered as just years. Do not use day/month data or the process, i.e. '-0145' not '-1/12/0145'. Also, take care to always supply a four-digit year, i.e. '-0045' not '-45'.

    However, it is important to note that default date settings (macOS System Preferences:Language & Text:Formats) do not display AD/BC in dates. As the OS' 'short' date format is used for the display in the Displayed Attributes data table, if desiring to see negative dates correctly displayed, it may require customising the OS short date format in order to distinguish eras. Do bear in mind such changes may impact other applications that also use the system 'short' date and which may not expect/handle a non-default setting.

    If Tinderbox is open when the system settings are changed, close and re-start the application to see the new date formatting.

    OS Services

    The normal macOS services are available from all windows. Use the Services sub-menu under the Tinderbox menu.

    Quick Lists

    The term 'quick list' describes Tinderbox's ability to recognise certain characters—as the first characters in paragraphs—in $Text as indicating an HTML list when exported.

    Making unordered (bullet) lists

    Unordered, i.e. bulleted, HTML lists can be indicated using either an asterisk (*) or a bullet (•). Thus Tinderbox recognises as unordered lists paragraphs that begin with one or more asterisks or bullets:

       * like this example

          ** use two or more asterisks to embed lists within lists

    The above gives this sort of HTML output :

    • like this example
      • use two or more asterisks to embed lists within lists
    • like this example
      • use two or more asterisks to embed lists within lists

    Making ordered (numbered) lists

    Ordered, i.e. numbered, HTML lists can be indicated by using a hash symbol (#). So, those paragraphs that begin with one or more hash marks:

       # like this example

          ## use two or more hashes to embed lists within lists

    The above gives this sort of HTML output:

    1. like this example
      1. use two or more hashes to embed lists within lists.

    List types can be mixed. For instance:

       * like this example

          ## use hashes to get numbered lists

          ## numbered lists can be in bulleted lists

       * and so on

    That gives:

    • like this example
      1. use hashes to get numbered lists
      2. numbered lists can be in bulleted lists
    • and so on

    Configuring quick lists

    Tinderbox will indent whole paragraphs beginning with an asterisk or hash, by one tab-width per quick list symbol. A quick list item starting with 3 asterisks will show in TB as a paragraph indented 3 tab-widths.

    Several attributes and preferences control quick list handling in note windows and at export:

    • If the $HTMLListItemStart and $HTMLListItemEnd attributes are empty, all quick lists, as defined by lines starting with an * or a #, are disabled and content is exported verbatim (i.e. including the * or # markers).
    • Outputting text using ^value($Text)^ ignores quick list markup at the source notes $Text is exported verbatim, without HTML processing.
    • If $HTMLMarkupText is set to false (the non-default setting), all list indenting is turned off and all mark-up for export, including quick lists, is disabled e.g. paragraph tags, HTML entities, etc. This choice is useful if exporting notes holding code (CS, JavaScript) which must be exported verbatim; the export template would still just use ^text^ but the note's $Text would be inserted into the output verbatim, without any modification.
      • Note that in Tinderbox v6+ there is rarely the need to alter $HTMLMarkupText given the possibility of ^value($Text)^ as described above
    • If $IsTemplate is true, the effect is the same as setting $HTMLMarkupText to false, effectively overwriting the latter's current setting to ensure templates perform as expected.

    HTML export supports Quick Lists: paragraphs that start with an asterisk or bullet are exported as unordered lists.

    Styling Quick Lists in $Text

    Quick Lists are detected and auto indented within $Text. Note that this styling has not effect in display in the Preview or Export text panes, as they only control the style (layout) of $Text. For longtime users, this returns auto list indenting as seen in the original pre-v6 app.

    Two system attributes control the degree of indentation (in pixels) applied to list items:

    Nested lists are supported, each level using the same indent, added to that of its parent list. Edits within lists (level change of item, adding/removing asterisks/hash markers, etc.) are auto-detected/updated. If in doubt that changes are reflected, click the tab label of the current tab as this forces the content of both panes to refresh.

    Suppressing default quick list behaviour

    To stop a quick list character at the start of a line from being interpreted as quick list markup, either:

    • Place an Option+space character at the start of the line.
    • Use the HTML encoded symbol for that character, e.g. replace '#' with '&#035;', or '*' with '&#042;' etc.

    Reset $Text formatting

    $Text is a styled text writing space, reformatting entire note texts is more complex than in early Tinderbox, not least as discrete fonts are used for setting bold and italic text—albeit from the same font family. Indeed, if the font family of the $TextFont used in the note (or current selection) lacks a bold or italic variant, then those forms of styling cannot be applied unless a different $TextFont is selected. (A historical note. The Lucida Grande used in v5 had this problem: default Mac fonts included a bold font face but no italic).

    Text-space formatting is controlled via three options on the Style sub-menu of the Format menu:

    • Standard Size. (Cmd+Shift+T). Sets the selection to the default font size ($TextFontSize). If selected from View pane, the styling is applied to the whole text of the current note. A text selection is not required so a note with no $Text can be reset.
    • Standard Font. (Cmd+Opt+Ctrl+T). Sets the selection to the default font ($TextFont). Note that this destroys any bolding or italics as these are set using variant font faces. However, the process does try to respect passages that are bold or italic; it changes the font family to the note's default font family, using the note's $TextFontSize size. If selected from View pane the styling is applied to the whole text of the current note. Standard Font is more aggressive in removing indentation, background colours, text colours, embedded tables and list formatting. This is often what one wants when pasting from formatted sources such as Web pages. A text selection is not required so a note with no $Text can be reset. As this option often also changes embedded rules, it is often necessary to also use the next option below when 'resetting' a note's text.
    • Reset Margins. This resets paragraphs in the selected range to use the standard margins and line spacing. There is no keyboard shortcut.

    Document-level changes are also possible. In Document Settings/Text, when the default Text Font is changed, Tinderbox scans the text of every note in the document and changes each usage of the former text font to adopt the new font family while retaining the current size. As long as only one font family is in use for the $Text any bold and italic sections of text should adopt the new font (do note the need for the new font's font family to include installed bold and italic variants). Note text using other fonts are ignored. For instance, it would be unwelcome if such an update changed the monospace fonts used in Template- and Code-prototyped notes.

    Spotlight support

    Spotlight should catalogue Tinderbox document files that have extensions ".tbx" or ".xml"

    Smart Dashes

    Tinderbox uses underlying Apple frameworks to automatically substitute a pair of successive dashes -- (as via keyboard minus key) with a long en-dash –, or 3 dashes --- with an em dash —. Note: for historical and practical reasons this feature is not used in aTbRef.

    Smart Dashes are also controlled via $SmartQuotes. This makes it easier for those with more precise quote/dash control to disable these smart features which are on by default

    Either change $SmartQuotes for the note or use the Substitutions menu either via the Edit menu or the text area's right-click menu. Warning: this menu change only lasts until the note is de-selected, on re-selecting the note the default value is re-applied.

    Smart Quotes

    Tinderbox uses underlying Apple frameworks to automatically substitute typographic ('curly') curly single or double quotes instead of straight ones where they are found in $Text. Note: for historical and practical reasons this feature is not used in aTbRef.

    Thus if a quoted word 'funny' is typed with straight quotes, the 'smart' mechanism will change it to ‘funny’. Similarly "funny" becomes “funny”. The effect is not retro-active. Changing the setting has no effect on pre-existing existing $Text in notes.

    This feature can be controlled at Document Level or at note level. Use either of these methods (both are interconnected):

    • Document. See Document Settings, Text tab, Smart quotes. Toggling this both sets Smart Quotes for the whole document and the default value of $SmartQuotes.
    • Note. Either change $SmartQuotes for the note or use the Substitutions menu either via the Edit menu or the text area's right-click menu. Warning: this menu change only lasts until the note is de-selected, on re-selecting the note the default value is re-applied.

    Smart Dashes are also controlled via $SmartQuotes. This makes it easier for those with more precise quote/dash control to disable these smart features which are 'on' by default. Note that if using the menu (option #2 above), then Smart Dashes and Smart Quotes must toggled separately via their own discrete menu items.

    Sorting Dates using $Sort

    When using the 'Sort' Group of user attributes ($Sort, $SortAlso) to sort on any Date-type attribute, any default not-yet-set "never" dates are listed last. This the same for both note and agent based container sorting.

    If the sort is reversed (suing ($SortBackward and $SortBackwardAlso), the "never" dates list first.

    This indicates Tinderbox is using a lexical sort—sorting the dates as if literal text strings as opposed to using their implied date numbering. The linked page explains the logic of lexical sort.

    A separate article covers sorting Date-type data using Action code.

    Legacy note: In older versions of Tinderbox, the "never" dates always listed first regardless of the sort/reverse order. That reflected user requests to make non-set dates easier to find. It appears this older behaviour no longer occurs. However, if encountered, that it the reason for the difference form the above.

    Support for other app-specific formats

    BibDesk

    Dragging BibDesk files (RIS data) to Tinderbox will create new notes.

    BibTeX files

    BibTeX, a common reference format, is now recognised as such when pasted into the view pane, or when dragging .bib files into Tinderbox.

    Information discovered is parsed into the Reference group and other mapped system attributes as with drag/dropped references.

    Bookends

    Tinderbox supports import of data from Sonny Software's Bookends reference and citation manager.

    IMPORTANT: dragging from Bookends has varying results depending on the modifier keys depressed. A constraint at the Bookends end of the process (i.e. starting the drag) is that for the modifiers (e.g. Option key, etc.) to be recognised and modify the Bookends behaviour the modifier keys must be depressed before clicking on the selected record(s) to start the drag.

    Use with Bookends v11.2.9+. Used with Bookends v12.8+ there is support for dragging selections of multiple Bookends records.

    Be aware that a number of aspects of the data passed into Tinderbox depend upon the currently selected export format in Bookends. Thus, selecting 'MLA' vs. 'IEEE' will give a differently styled result in Tinderbox. The options for this should looked up in the Bookends manual (or its support forum).

    Drag result options

    Note, the last-listed is the one likely of most interest to Tinderbox users:

    • Drag with no modifiers. Creates a new note and copies 'temporary' citation to both $Name and $Text, such as is used in word processing apps to mark where bibliographic links with be inserted. This is the equivalent of Edit ▸ Copy Citation within Bookends.
    • Option+Drag (+Drag). Creates a new note and copies a formatted citation to both $Name and $Text, essentially this is the equivalent of Edit ▸ Copy Formatted within Bookends.
    • Cmd+Option+Drag (+Drag). Creates a new note and copies a Bookends pseudo-protocol link (i.e. a bookends://...etc. URL) into the Tinderbox note's $URL field. This process is lightly covered in the Bookends manual under "Copying Formatted Citations by drag and drop". The process is described in more detail in the next section below.

    Auto-importing reference data from Bookends using a dragged link

    By using a Cmd+Opt+Drag from Bookends, a note is created and the Bookends pseudo-protocol URL is inserted to the new Tinderbox note's URL. This special URL content is detected and the following occurs, noting that as the drop is detected the note the user then sees has already had these changes applied:

    • Tinderbox polls the Bookends URL for data, which is as defined by the Bookends' built-in 'RIS' export format. See Bookends's Formats Manager (menu Biblio ▸ Formats Manager…) for more detail of what is contained. The default Bookends format has slightly differing RIS fields for 4 different types of references (books, journal, etc.) with 'journal' being used for any undefined reference type,By editing that export format, in Bookends, the contents of what is passed to Tinderbox can be varied. For most users/purposes such customisation is not needed.
    • The RIS data is placed in $ReferenceRIS should the user wish to copy addition details in addition to that auto-extracted.
    • If found in the RIS data:
      • RIS abstract field 'AB' is copied to $Abstract.
      • RIS primary title field 'T1' is copied to $Name.
      • RIS journal abbreviation field 'JA' is copied to $Journal.
      • RIS publication year field 'PY' is copied to $Publication.

    Drag imports from Bookends are coerced to $TextColor, which improves interoperability in dark mode.

    From Tinderbox v9.1.0, Bookends-imported date placed in $Authors retains the original author ordering as is needed for referencing. Prior to this $Authors was a Set type but changes in Tinderbox meant source data was being A-Z sorted.

    IMPORTANT: the Bookends data import requires a modified drag (explained below). This means doing a Cmd+Opt+Drag (++Drag) and also ensuring the Cmd+Opt keys are depressed before the drag starts. Failure to press the modifier keys first results in different data being loaded). The modified drag will result in:

    • creating a new note.
    • setting the note's $URL to a Bookends reference URI
    • set the $Text of the note to formatted Bookends reference. The styling/layout used will depend on the user's settings in Bookends. In most cases the result is the reference source data formatted for citation in that reference format (e.g. ACM, IEEE, etc.). With some references export format choices, like BibTeX, the $Text appears to be a form of code but this is the correct export for that format. Notes created by ⌘+⌥-drag from Bookends display the imported citation in the $TextFont, not Helvetica.
      • WARNING: this will replace any existing $Text in the note.
    • apply the 'Reference' built-in Prototype (adding the latter to the TBX if necessary). Note this process is linked to the Network feature, so multiple newly added reference notes my appear to set their prototype one at a time, i.e. there may be a short delay before all new notes are prototyped correctly.
    • set a variety of reference-related attributes to Bookends-derived values (mainly attributes from the References group).
    • if an imported reference from Bookends is not valid unicode, Tinderbox rejects the import rather than risk a corrupt value of $ReferenceData (prior to v11.0.1, $ReferenceRIS).

    From v11.5.0 there is Bookends citation marker scanning and integration, via the Edit ▸ Insert menu

    Calendar

    Tinderbox accepts drags from the Calendar. If the document has an Event prototype, the newly-created note is assigned that prototype. $StartDate and $EndDate will be populated; the name of the note is the event title and the subtitle of the note is the event location.

    Delicious Library

    Selections copied from Delicious Monster's library application, Delicious Library, are pasted as reference item. Pertinent attributes are automatically filled.

    Note: the Delicious Library was shuttered by its developer in November 2024.

    DEVONthink

    Tinderbox supports a number of methods to interchange data with and inter-connect to DEVONthink.

    • Importing item(s):
      • '.tsv' file format. These behave like text '.txt' files when dragged to Tinderbox, using the tab-delimited data method.
      • '.opml' file format. This follows normal OPML import methods.
      • Single or multiple notes can be pasted or dragged from DEVONthink Pro whilst retaining their tags (as $Tags). The created note's $URL is set to source item's DEVONthink URI.
      • A Tinderbox note can be set to auto-fetch a DEVONthink note. Set $AutoFetch to true and $URL to the DEVONthink URI of the desired note. When Tinderbox routinely fetches Web data, it will also reimport the text and name of the DEVONthink note.
      • Improvements to imported text styling:
        • The source styled text instead of plain text. This does require DEVONthink Pro Office v2.9.11+.
        • Items with only plain source text import plain text.
        • Plain text and markdown items imported from DEVONthink respect the (Tinderbox) note's default $TextFont and $TextFontSize.
      • Using DEVONthink Office Pro 2.9.15+, the note created imports the DEVONthink Creation time as $SourceCreated and the DEVONthink Modification time as $SourceModified.
      • Tags from items watched in DEVONthink folders are imprted into $Tags.
      • Watched (see below) DEVONthink items populate $URL with the item's DEVONthink URL (previously it was DEVONthink's Note ID). From v11.5.0, when dragging an item from DEVONthink, Tinderbox replaces the x-devonthink-item:// URL in $URL with the URL stored in DEVONthink. However, if the URL field of the DEVONthink item is empty, Tinderbox will retain the x-devonthink-item:// URL in $URL.
      • Dragging image items from DEVONthink to Tinderbox creates a note containing the image.
      • DEVONthink text items that exceed ~10,000 words are not automatically imported.
      • Dragging Freemind (.mm) items from DEVONthink to Tinderbox imports the Freemind maps. Previously, the DEVONthink item, had to be dropped onto the desktop first, in order to create a file.
      • also see Dragging content from DEVONthink to Tinderbox.
    • Using A Watched Group. A DEVONthink watched group allows for the import of a single group of DEVONthink records. The group's items are generated as child notes of the watched group container in Tinderbox. Multiple watched groups are allowed though be mindful heavy use of this feature may affect overall performance, i.e. the feature is not designed as a fully-synced system but rather for importing/updating some DEVONthink data. Notes created via this method are read-only, inheriting $ReadOnly state from their 'Imported From DEVONthink' built-in prototype.
    • Export. Tinderbox notes can be copied/pasted to DEVONthink. Copy the note(s) in Tinderbox. In DEVONthink use Data menu, New ▸ from clipboard (Cmd+N). The following Tinderbox data maps to DEVONthink:
      • $Name: a new styled text item title.
      • $Text: text of the new item.
      • $Tags: the item's tags
      • $NoteURL (source note's Tinderbox pseudo-protocol URL): the item's URL
    • The DEVONthink Item ID.
    • The DEVONthink URL pseudo-protocol.

    DEVONthink items dragged into Tinderbox import their DEVONthink label string into the attribute, $DEVONthinkLabel.

    DEVONthink import uses a dedicated built-in prototype (as with watched DEVONthink folders). This allows customisation of Tinderbox's behaviour when importing from DEVONthink v3.

    When dragging an item from DEVONthink, Tinderbox will populate the new note's $SourceURL with the URL of the dragged resource.

    More on DEVONthink integration

    DEVONthink Item ID

    A DEVONthink 'item link', which uses the x-devonthink-item:// pseudo-protocol, can be used to obtain the source item's ID. The item link looks like this:

    x-devonthink-item://5349A993-377B-4F63-9E43-74317939529B 

    The long code string is a DEVONThink unique ID for that asset. Thus the actual item ID is:

    5349A993-377B-4F63-9E43-74317939529B 

    This is the ID needed to use in a DEVONThink watched group.

    DEVONthink URL pseudo-protocol

    DEVONthink's 'item link' use the protocol x-devonthink-item:// which allows other apps on the same Mac to open the item in DEVONthink from a URI held in another app, e.g. Tinderbox note's $URL. It could be any URL-type attribute but $URL should be used if it is intended to auto-fetch the DEVONthink item's content.

    The basic link looks like this:

    x-devonthink-item://5349A993-377B-4F63-9E43-74317939529B 

    The long code string is a DEVONThink unique ID for the source asset, whether stored within DEVONthink or just indexed by it.

    Customised URLs

    The item link URL format also allows several optional forms of suffix to these URLs to further customise the data returned.

    'page='. ?page=4. This will open (paginated) documents scrolled to the indicated page. Note however that the index in the URL is zero-based, so page #1 is '0', etc. Thus ?page=4 will open the fifth page of the document (i.e. 0->1->2->3->4). Example:

    x-devonthink-item://5349A993-377B-4F63-9E43-74317939529B?page=4 

    'search='. ?search=Albert Einstein. For text documents, DEVONthink will search the document, highlight all the matches and scroll to the first one. Note that the example given may not work as it is not URL Encoded, better would be to use ?search=Albert%20Einstein. For PDF documents, they must have a text layer, e.g. scans saved as PDFs but not OCR-ed will not work with this method. Example:

    x-devonthink-item://5349A993-377B-4F63-9E43-74317939529B?search=Albert%20Einstein 

    'time='. ?time=80.4. For movies files such as MOV, MP4, this will open the movie at the time code, in seconds, as given. Thus to open a movie at 1 minute 20 seconds, use 80 seconds. Decimals of seconds are allowed. Apparently the method does not work for audio files like MP3, but this may change in due course. Example:

    x-devonthink-item://5349A993-377B-4F63-9E43-74317939529B?time=80.65 

    Whilst the Edit menu and right-click in file listing in DEVONthink will copy a 'bare' item link (i.e. with no special suffix as above), right clicking on display of a partially played movie will add a ?time suffix. Similarly, right clicking the scrolled display of a paginated document will append a ?page suffix.

    Mapping Tinderbox and DEVONthink URLs

    Both Tinderbox and DEVONthink can store external URLs, i.e. links to external sources, and offer pseudo-protocols (usable on the same Mac) to call the app's record from another app or process.

    The image illustrates the relationship of these URLs and how they map between the two applications.

    Evernote

    [This support was suspended in v9.0+ due to changes in the way the Evernote app works.]

    It is possible to import small amounts of Evernote data via a watched folder looking at a particular notebook.

    Finder

    Tinderbox can automatically import selected notes from any Finder folder via a Watched Folder, including folders in Dropbox or on other remote servers.

    FreeMind

    Tinderbox opens FreeMind ".mm" files and will accept FreeMind files dragged into a map.

    If a FreeMind item has an associated note, that note is imported as styled text in the Tinderbox text field.

    IAWriter

    Import from IAWriter is handled correctly.

    Marked2

    Tinderbox automatically communicates with the streaming preview of the application Marked2. When you select or edit a note using the Markdown prototype in Tinderbox, it will automatically be sent to the Marked2 streaming preview window.

    Note it is a $Prototype value of 'Markdown', not the prototype's attribute customisations that trigger preview streaming.

    Export code operators in the note $Text, e.g. ^value()^, are evaluated in the data passed to Marked 2.

    More on Markdown use in Tinderbox.

    A new Boolean attribute $Marked2 allows the streaming to Marked2 preview in notes to be disabled where is it undesirable.

    Microsoft Word

    Microsoft Word® files (.doc) and Word XML files (.docx) may be dragged into Tinderbox preserving source text and tabular styles in Rich Text form. Documents with complex styling or much embedded content may not import all source information; images embedded in Word documents are not imported. If in doubt, first test with simple text documents.

    If the source document is the much older DOC format, re-save in word as a DOCX format before attempting copy/paste.

    Note that some text styles cannot be exported.

    Notes

    Data can be imported from the Apple Notes application (installed on all Macs) via a watched folder. Using iCloud sync on macOS and iOS Notes, this allows for import of data from iOS devices as well as Macs.

    OmniFocus

    Date imported from OmniFocus includes the notes' URLs ( to $URL) and sets the notes prototypes to the built-in 'Task'. The import uses the OmniFocus' task's key dates: Defer Until becomes $StartDate, Due becomes $DueDate, and Completed becomes $EndDate. Any mapped Date attributes unspecified in the imported data are set to a value of "never". If a task was completed before the present time, the note is marked as $Checked. If the task has a note, the text of the note is placed in the Tinderbox note's text.

    OmniOutliner

    Tinderbox supports drag-drop importing of OPML exported from OmniOutliner. Sadly, Omni neglect to document their export format in any detail. A scant description can be found here.

    Column-to-Attribute mapping

    The first column of an OmniOutliner file (default column title 'Topic') will export as OPML attribute 'text' (regardless of the columns title). An OPML 'outline' tag (i.e. row/note) 'text' attribute always maps on import to the Tinderbox $Name attribute of a note (i.e. its title).

    If the OmniOutliner column #1 content contains more than one paragraph, the only first paragraph only is exported as as the 'text' attribute, with the rest of the text exporting as the OPML '_note' attribute. Tinderbox always maps '_note' to a note's $Text attribute. For more deliberate export it is possible to put only the row/note title in column #1 and make a column #2 with the column name '_note' and place the intended Tinderbox note text in that column.

    All other columns are exported with a custom OPML attribute that matches the column header name. Thus if targeting import to Tinderbox, these columns should use the case-sensitive name of the intended mapped Tinderbox attribute. Thus if aiming to map a column to $SomeAttribute, the OmniOutliner column name should be 'SomeAttribute', and so on.

    In summary Tinderbox always maps OPML 'text' to $Name' and '_note' to $Text while any other attribute names (as derived from OmniOutliner column headers) are case-sensitively mapped to an existing Tinderbox attribute or a new user attribute of that name is created.

    Regardless of the OmniOutliner source file's column data type, Tinderbox OPML import will always create new Tinderbox attributes as a String type. Thus it is advisable, where possible to define any desired mapped attribute in the TBX file before import, setting the desired.

    Pasting an outline from OmniOutliner understands notes associated with OmniOutliner items and saves them in the new note's text.

    Data Types

    OmniOutliner and Tinderbox data types do not match exactly. The default column type is 'rich text' which is exported to OPML without any styling. The 'number' type in OmniOutliner allows for various formats but is best exported unformatted whether targeting a Tinderbox String or Number type attribute.

    Use of the 'checkbox' column type is not recommended as whilst it renders in OmniOutliner like a Tinderbox Boolean attribute the values are exported as 'checked' and 'unchecked' both of which parse into a value of true (ticked) if mapped to a Tinderbox Boolean. Thus it is better to use a 'rich text' type column and 'true' and 'false' values as these will pass correctly into a Tinderbox Boolean attribute.

    The 'date' column type displays/exports the short date form 'dd/mm/yyyy' or 'mm/dd/yyyy' the day/month order depending on your OS' locale. Further the delimiter may be other than a '/' depending on your OS' locale. Mapped to a Tinderbox Date attribute this will work fine as long as both OmniOutliner and Tinderbox are running on the same OS locale. If the source OmniOutliner OPML and the Tinderbox app are on different locales (e.g. US vs. non-US) you may need to format the OmniOutliner date column to use the day/month order and delimiter of the recipient OS with the Tinderbox. Note OmniOutliner 'date' columns allow some locale based formatting: see the OmniOutliner manual.

    Other OmniOutliner column types are not recommended if creating data intended for export to Tinderbox via OPML.

    For multi-value, i.e. list, data values, use a 'rich text' OmniOutliner column and format the text so each value is delimited with a semi-colon, i.e. 'value 1, value 2' should be saved before export as 'value 1;value 2'. On import to a Set or List type Tinderbox attribute this will separate into discrete list values. If imported to a String attribute with is then changed to a Set or List, again it will parse into discrete values.

    With appropriate data values, number/boolean/date/list type data imported to Tinderbox as a new string-type attribute should translate correctly if the new attribute is then changed into the correct Tinderbox data type via the Inspector.

    QuickCursor

    Tinderbox is compatible with QuickCursor, an inexpensive accessory available in the Mac App Store. Written by Hog Bay Software, QuickCursor lets keyboard-centric users switch easily from the Tinderbox $Text area to edit text, or selected passages of text, in BBEdit, TextMate, WriteRoom, or a variety of other plain text editors.

    Readwise

    From v11.5.0, integration is provided for the Readwise app. Readwise is a commercial service that can share Kindle and PDF highlights and annotations with applications like Tinderbox. https://readwise.io.

    Before attempting to import Readwise highlights, a Readwise Authorisation Token is required. Readwise users can obtain this from https://readwise.io/access_token. The token should be pasted into the Readwise box in Document Settings:Accounts. The token needs to be added to every TBX documents that will use Readwise integration. Thus integration is at per-document and not application level.

    Choose menu File ▸ Import ▸ Readwise to import your highlights. This creates a root-level container note at path /Readwise which will hold the imported notes. One note will be created for each source book. Individual annotations are copied to the note's text, separated by two carriage returns.

    Three system attributes support Readwise integration:

    • $ReadwiseToken is the token for the Readwise API (see above).
    • $ReadwiseID is an ID number that helps Readwise locate items.
    • $ReadwiseDate is the last time this note was updated from Readwise.

    RIS files

    Files with the extension '.ris' are understood to contain RIS bibliographic data, which can be parsed to appropriate system attributes in the References group. This improves the handling of references to journal articles and conference proceedings imported from Bookends, Zotero, and other sources of RIS data.

    Dragged references hold this information in $ReferenceData (prior to v11.0.1, $ReferenceRIS).

    The references type (article, journal, book, etc.) is extracted from the 'TY' field and placed in $RefType. See more on the allowed values for RIS code 'TY'.

    Author import: $Authors respects the order of the received source list (previously it was re-sorted in alphabetical order,).

    TY type codes for RIS

    The RIS code 'TY' values can be found in the table at Wikipedia. Note that Tinderbox extracts the TY value but doesn't convert the encoded value to its more human readable version. The allowed values for RIS code 'TY' are as below:

    Abbreviation Reference Type

    ABST Abstract

    ADVS Audiovisual material

    AGGR Aggregated Database

    ANCIENT Ancient Text

    ART Art Work

    BILL Bill

    BLOG Blog

    BOOK Whole book

    CASE Case

    CHAP Book chapter

    CHART Chart

    CLSWK Classical Work

    COMP Computer program

    CONF Conference proceeding

    CPAPER Conference paper

    CTLG Catalog

    DATA Data file

    DBASE Online Database

    DICT Dictionary

    EBOOK Electronic Book

    ECHAP Electronic Book Section

    EDBOOK Edited Book

    EJOUR Electronic Article

    WEB Web Page

    ENCYC Encyclopedia

    EQUA Equation

    FIGURE Figure

    GEN Generic

    GOVDOC Government Document

    GRANT Grant

    HEAR Hearing

    ICOMM Internet Communication

    INPR In Press

    JFULL Journal (full)

    JOUR Journal

    LEGAL Legal Rule or Regulation

    MANSCPT Manuscript

    MAP Map

    MGZN Magazine article

    MPCT Motion picture

    MULTI Online Multimedia

    MUSIC Music score

    NEWS Newspaper

    PAMP Pamphlet

    PAT Patent

    PCOMM Personal communication

    RPRT Report

    SER Serial publication

    SLIDE Slide

    SOUND Sound recording

    STAND Standard

    STAT Statute

    THES Thesis/Dissertation

    UNBILL Unenacted Bill

    UNPB Unpublished work

    VIDEO Video recording

    Scrivener

    A pair of built-in (OPML) export templates specifically marked for Scrivener use were added. The templates are effectively the same as those for general OPML export but labelled so as to assist the more tech-averse Tinderbox/Scrivener user looking to export data from one to the other.

    A File menu option allows direct import of Scrivener file data to create a new Tinderbox document:

    • Each text scrivening and folder becomes a Tinderbox note; v2 Scrivener files only. Text of v3 files is currently not extracted to a Tinderbox note.
    • Image, pdf, and Web scrivenings are currently ignored.
    • Scrivener keywords are imported to a set attribute $ScrivenerKeywords, and the corresponding label colours become the note $Color.
    • Scrivener statuses are imported to $ScrivenerStatus.
    • Scrivener freeform corkboard positions are imported to $Xpos and $Ypos. If Scrivener is not using freeform corkboard positions, Tinderbox uses its own layout.
    • Scrivener custom metadata is mapped to Tinderbox attributes. Because Scrivener custom metadata labels may not be valid Tinderbox attribute names, Tinderbox uses 'legal' version of Scrivener's internal metadata names; the attributes are found in the Scrivener system attribute group.
    • The Scrivener synopsis, if present, becomes the note's $Subtitle.
    • Because Scrivener values result in many items' $Color value being set to light colours, the new TBX's Map preference is set for Outlines to have "Darker colors".
    • Scrivener internal references are loaded as basic links. The default link type "[InternalLink]" is mapped to "*untitled".
    • If an external reference link is found, its URL is placed in the note's $URL attribute. (If several external references are found, only one URL will be imported.

    Simplenote support

    [NOTE: Simplenote sync support was discontinued from v8.8.0]

    Notes below are for legacy purposes only

    Synchronising notes with Simplenote, a note-taking app for iPhone/iPad with web synchronisation. Tinderbox synchronises with the web app and the web app with iPhone/iPad. The web app is free and device apps have free (with unobtrusive ads) and pay-for versions. Integration uses the Simplenote v2.0 API giving support for tags and improving reliability.

    Simplenote sync, and the account details to use are set in the Document-level Preferences' Simplenote tab.

    If Simplenote syncing is enabled for a document, Tinderbox syncs when the document is opened and saved. Notes synched to/from the web are placed in a root-level container called 'Simplenote'. Do not move this container whilst synching is activated as the synch process will see no notes where the container should be and will delete all Simplenote notes.

    Simplenote support is added to a Tinderbox document by opening Document Preferences, Simplenote pane. Tick the 'Check Simplenote' box and enter the Simplenote account name (typically an email address) and password. It is also possible to filter the notes that will sync by nominating one or more Simplenote tags in the preferences.

    Tinderbox will download copies of that Simplenote account's notes to a root-level container named 'Simplenote' (case sensitive) whenever the document is reopened or saved; the container is made if not already present. On-demand synching from TB is achieved only by saving the host TBX.

    New notes and notes that have changed on an iPhone or iPad and been web-synched will be added as needed. Notes deleted from an iPhone or iPad and web-synched are removed from Tinderbox's Simplenote container.

    Simplenote notes do not have separate titles, as do Tinderbox notes. Tinderbox attempts to propose a useful title from the Simplenote text.

    • If the note received from Simplenote is short, TB puts the Simplenote text in both $Text and $Name.
    • For longer notes, the full text goes into $Text, and the first sentence or line goes into Title. When syncing, TB syncs (only) the text.
    • If a note is made in the TB Simplenote container and it has no Text, Tinderbox uploads the $Name as if it were the note text.
    • For notes first created in Tinderbox do not use any punctuation symbols in $Name. Doing so results in a Simplenote using only $Text (if any) or, if no $Text, the $Name up to the first punctuation character.
    • Aliases in the Simplenote container are not synched.

    Only immediate children within the Tinderbox Simplenote container are treated as potential Simplenotes when synching. In other words, any grandchildren (or deeper) notes in '/Simplenote' are ignored for synching. If a note with children is deleted via synching, the note and all its descendants are deleted.

    As part of the process, two attributes are used. $SimplenoteModified keeps track of the effective modification date according to the Simplenotes server. $SimplenoteKey is used to store the internal key that identifies a note to the Simplenote server. If a note deleted in Tinderbox is in the 'Simplenote' container and has a $SimplenoteKey, Tinderbox will ask the server to delete the note.

    A Simplenote Preference 'Required Tags' (a semi-colon delimited list of tag names) adds an over-riding filter so that only those Simplenote notes with tags included in the list are imported to Tinderbox box and subsequently synced ( all other notes are ignored by Tinderbox.

    $SimlpenoteTags stores a synched note's Simplenote tags. Two further attributes, $SimplenoteSync and $SimplenoteVersion are added for internal Tinderbox use: users should not edit them.

    The Simplenote synchronisation dialog shows the overall number of notes being synched, plus a breakdown of the number to upload, download and delete; a progress bar is also shown.

    If a note that is synched with Simplenote is deleted, its Simplenote key is cleared. If the deletion is undone, a new note corresponding to the Tinderbox note will be uploaded, so the deletion is effectively undone.

    Aliases. Tinderbox handles the scenario where making an alias of a note inside the Simplenote container could cause both the alias and its original to be deleted from both Simplenote and Tinderbox at the next sync.

    Tinderbox is alert to the possibility of Simplenote notes containing control characters (other than Carriage Return, Line Feed and Tab). Previously, syncing such notes to Tinderbox could create files that cannot be reloaded. It is not clear that Simplenote notes should contain control characters, but the app is playing safe.

    Added better support for synching notes containing accented characters and other Unicode issues as well as using improved synch code.

    Storyspace

    The System attribute group 'Storyspace' accommodates interchange use of Storyspace v3 files. For more on the inter-relation of Tinderbox and Tinderbox see Tinderbox's pre-history.

    The Storyspace product page; http://www.eastgate.com/storyspace/.

    Storyspace Guard Fields

    In Storyspace a basic or text link may, optionally, include a 'guard field'. This is condition, written as an action code expression that must be met before the user may follow the link.

    Tinderbox files will store Guard field data but cannot use it—or read it.

    TaskPaper

    TaskPaper files may be dragged into Tinderbox. Tinderbox automatically recognises TaskPaper tags and copies them to $Tags. The @done() tag also sets $Checked and $NameStrike; if the @done tag has a completion date, it is copied to $StartDate and $EndDate.

    Recognises and maps @due (to $DueDate), @start (to $StartDate) and @done (to $EndDate)

    Tot

    Tinderbox can watch and automatically import notes from the Tot application, which can installed in macOS and iOS devices.

    Watching Tot will import text from Tot, but does not sync to Tot.

    Zotero

    From v11.5.0, Zotero is a popular (free) reference manager. It can be used online or via a native macOS client. See: https://www.zotero.org.

    Zotero integration requires a Zotero ID and Key. These are not available if only using the macOS Desktop client app and can only be obtained by (creating a free account and) logging into Zotero on the Web, then visiting the account’s Security page, https://www.zotero.org/settings/security . The ZoteroID is a seven-digit account number.

    The menu EditInsert has three Zotero-related options (see explanations):

    • Lookup in Zotero (⌘+Y).
    • Zotero Scan.
    • Zotero Unscan.

    Text line endings

    This topic likely will not affect users unless they are doing multi-line edit scripting or using the Explode feature.

    Not all line breaks are equal. 2 different characters get used for line endings:

    • Line feed. ASCII character #10. The designator for Explode, regular expressions, etc., is \n.
    • Carriage return. ASCII character #13. The designator for Explode, regular expressions, etc., is \r.

    To muddy the waters, different OSs have used different line end encodings:

    *Classic Mac OS: carriage return (\r).

    *Unix, including macOS: (\n). (So, some longstanding Mac apps may still use \r as originally in Classic Mac OS.

    *Windows uses a 2 character method: carriage return + line feed (\r\n).

    Text generated in Tinderbox (except perhaps very early versions running pre-macOS) uses the Unix/macOS style line offered style of line end, \n.

    When including a line end as part of an Explode delimiter, \r and r generally have the same effect so using \n as a 'default' is probably good working practice.

    However, depending on the source of text brought into Tinderbox, e.g. text file dragged in for exploding, the designator used for line end may have to be adjusted.

    Time - Displaying and Setting Seconds

    In v5+ Tinderbox date/times effectively have, but do not use, a seconds elements:

    *If formatted for string use, seconds always show as '00'.*

    *Date/time creation operators omit a seconds input or ignore it if used.

    *Date/time comparisons cannot be made to seconds' granularity as all date/times have the same (00) seconds value.

    *There is no method to return just the seconds of a date/time (QV hours or minutes)

    *Displayed Attributes date/time values do not show the seconds element (unless the user has her system set to use a format that includes seconds.

    The rest of the article refers to Tinderbox before version 5


    Do Date attributes have seconds?

    All Date (i.e. Date/Time) attributes inherently include a time down to seconds level, even if it is not always displayed. However, confusion arises as the Displayed Attributes table cannot be made to display the seconds for a Date attribute; instead they always show the OS short date with hours and minutes only. In addition, some process default to using seconds of '00' whilst others use the seconds as at time of execution. Or, edit $DisplayedAttributesDateFormat to use a custom format.

    Which operators do not use seconds in comparisons?

    When comparing dates or doing date arithmetic, be aware of the seconds unless using days() or minutes() which compare in whole days or whole minutes respectively. Also a positive or negative equals query (== or !=) will ignore time completely and match on whole days, like the days() operator.

    Can I display a Date attribute in Displayed Attributes and see its seconds?

    No. At least, no without altering your OS settings: see below.

    Which date designators use the second of execution?

    The designators yesterday, today, now, and tomorrow, plus any dates based on modifications of those designators will set the seconds as measured at time of setting the attribute.

    Once a date/time has a non-00 seconds time, any modification to the value will preserve the seconds unless the modification expressly sets the seconds.

    What time is set if a date is typed into a Displayed Attribute box?

    Unlike the above, the hh:mm are taken from current time but the seconds are set at 00.

    Can I type in a date and set seconds?

    Yes, you will need to set your OS Time 'short' setting to show hh:mm:ss; otherwise, when you provide a seconds the data is ignored at seconds are set at 00. "20 January 2010", at 17:45 local time will set "20/01/2010 17:45:00." For the same time "20 January 2010 17:45:25" will set "20/01/2010 17:45:25".

    Import

    AutoFetch

    If a note's $AutoFetch value is true, Tinderbox automatically updates the note's $Text to use data drawn from the source stored in the note's $URL. The latter may be any of:

    • URLs accessible via the Web.
    • locally installed app pseudo-protocol URLs, e.g. "devonthink://…", "bookends://…", etc.
    • local URLs, e.g. "file:///…".

    The AutoFetch process facilitates automatically updating note $Text from other text sources. As well as the more obvious sources such as web pages or RSS feeds, AutoFetch works with a range of file types, including text, srtyled text, Microsoft Word®(.doc and .docx), pdf, and markdown (.md) files.

    Once AutoFetch has run, the note containing the retrieved data also has its $ReadOnly attribute automatically set to true. This avoids the user trying to edit text that will get automatically overwritten when AutoFetch next runs.

    Including the first setting of the process, when does AutoFetch run on a note and alter its $Text:

    • on (re-)setting $AutoFetch to true.
    • on document load, all existing AutoFetches run once.
    • on (HTML-type) Export, all existing AutoFetches run once to refresh the exported content.
    • while the document is open, no more than once every 5 minutes as part of the general agent & rules cycle. The time to the next cycle is shown in the circular 'Network' display on the Agents & Rules tab of the Tinderbox Inspector.

    For deeper, more complex, be aware of the experimental attribute $RawData, which holds existing raw data (not post-processed) should the next planned fetch fail.

    Post-processing AutoFetched data

    It is possible to process imported data, before it is added to the note's $Text. This is done by setting valid action code in the same note's $AutoFetchCommand, whose operation is described separately in AutoFetch commands.

    AutoFetch commands

    To assist in manipulation of AutoFetched data it is possible to set an action to run on the raw output of the data before it is set as the note's $Text. It can be thought of as if it were an 'OnAutoFetch' action. Such actions are set in an Action-type attribute $AutoFetchCommand, and thus use the same syntax as agent actions and rules.

    If $AutoFetchCommand is empty (the default), $AutoFetch behaves as normal; the contents of the specified URL are stored in the note's text.

    $AutoFetchCommand has code set, that code is run on this note (i.e. the same note holding this code) immediately after a network AutoFetch event has been performed (event triggers are described under AutoFetch).

    Historically, these actions have been command line calls but as Tinderbox's range of text-manipulation operators in action code has expanded, pure action code may suffice. For instance, if pulling stock ticker information, it is possible to look for a line like "AAPL: 145.64 USD" and set the price to a Number-type attribute $StockPrice. This could be done like so:

    $StockPrice = $Text.following("AAPL: ").replace(" USD",""); 

    An AutoFetch command might invoke an outside program, perhaps fetching some information from the user's hard disk or network, using the runCommand() operator. For example:

    $Text = runCommand("echo | ls ~"/Documents); 

    will replace the $Text of the note with a list of all the files currently in the user's Documents folder (the latter syntax is the recommended choice).

    $Delivered = runCommand("myDatabaseQuery $TrackingID"); 

    which will run the shell script 'myDatabaseQuery' in the user's OS home folder, passing it the value of the note's $TrackingID attribute as an argument.

    When accessing the command line this way the current working directory is '/', i.e. the root of the current volume (more on the assumed working directory). Thus if calling scripts elsewhere (e.g. in a user account's 'Documents") remember to prefix an appropriate path to the script.

    Drag from $Text or $Name in text pane into view pane to create a note

    Dragging a text selection in $Text pane from the text pane (or stand-alone window) and dropping it onto the view pane results in a new note being created:

    • The dropped text selection is used as both $Name and $Text of the new note. The source text remains unaffected, e.g. the dragged text is not removed, re-styled, or linked.
    • Application focus remains on the source note.
    • No links are created (unlike when to making footnotes).
    • The major view's focus shifts to the newly created note.
    • Dropping on a Map view:
      • The note is created at the drop point
      • Dropping onto (into) a map icon viewport results in no note being created (not a note being created on the child map as might be supposed).
    • Dropping on an Outline or Chart view:
      • Onto the general background, the note is added as first sibling of the current root level notes.
      • If dropped over the right part of a note title the black position arrow will indicated whether the new item will be created before, after or as a child of the item under the cursor, i.e. the same behaviour as drag re-arranging notes in Outline view.
    • Dropping onto an Treemap view:
      • Onto the general background, the note is added as first sibling of the current root level notes.
    • Other view types may or may not support this feature.

    Using text from $Name

    It is also possible to drag a text selection from the $Name value displayed at the top of the text pane. The result is the same as described above for a drag from $Text.

    Note: it is not possible to attempt this dragging a selection from a note title in edit mode in the view pane. Use the text pane instead.

    Also consider using Tinderbox footnotes

    If a link to/from the source text in $Text (only—not for $Name text), consider using Tinderbox's built-in footnote creation feature.

    Dragging a URL from web browser

    What selections can be dragged from a web browser?

    Whether Tinderbox receives both URL and a link title/anchor text is depends on the browser, Tinderbox will use both if passed, otherwise a bare URL is received.

    Browsers do not allow dragging of a selection webpage content unless it includes at least one link (a visible URL or a link anchor text).

    Clicking in the location bar of a browser, where the (partial) URL is shown will select it and allow it to be dragged.

    Note that if dragged page content contains HTML such as lists of links, Tinderbox may try to parse these into a container holding two or more discrete notes. However, this article is intended to cover dragging content with a single URL into either the view pane (to make a new note) or into a note's text area.

    Dragging a URL onto a view background

    Drag a URL from Safari or other web browser onto a view window background makes a new note (in all view types except Attribute Browser, Crosstabs and Hyperbolic). The location of the new note varies by view type:

    • Outline, Chart. By default the new note is the last top-level sibling (i.e. child of root or a hoisted root scope). By hovering the cursor close to a note, the new note can be a previous/next sibling or child of an existing note at any level at root or in a branch.
    • Timeline. Always the last child of the root of the view. The new note will appear in the 'No Date' sidebar as it will have no $StartDate at this point.
    • Treemap. By default the new note is a top-level sibling (i.e. child of root or a hoisted root scope). Essentially as for Outline but without the fine positioning option.
    • Map. Creates a new note at the drop point. If the drop is onto an existing note, the new note is created as a child of that note.
    • Attribute Browser, Crosstabs, Hyperbolic view. Drop data is not accepted, so nothing happens.

    What note content is added for drag-to-view created notes?

    If the drag is from the browsers location (URL) bar the dragged data is usually only the (full https://...etc.)

    The drop action always sets $URL value, adds $URL as a Displayed Attributes, sets the note's title and its text. There can be some variations depending on the data supplied with :

    • $URL is set to the dropped URL.
    • The Displayed Attributes ($DisplayedAttributes) of the new note is set to "URL". Note that if the container of the new note has an OnAdd setting Displayed Attributes directly or via an attribute, this setting is overwritten to show $URL. Reset $DisplayedAttributes to restore the inherited value.
    • The new note's $Name is set to the value of the source URL, unless a title (e.g. the source page's anchor text) is parsed out in which case the title is used in preference.
    • The new note's $Text is set to the value of the source URL, unless a title (e.g. the source page's anchor text) is parsed out in which case the title is added as a weblink, pointing to the URL. in preference. If only the URL is added, no weblink results.

    Dragging a link from a webpage onto a note's text

    At the drop position, the receiving note's $Text is set to the value of the source URL, unless a title (e.g. the source page's anchor text) is parsed out in which case the title is added as a weblink, pointing to the URL. in preference. If only the URL is added, no weblink results.

    The drop also sets window sets the note's $URL value (but will not overwrite any pre-existing $URL value).

    See also results of pasting webpage data to $Text.

    Dragging a link from a webpage onto a note's Displayed Attributes table

    If the URL is dragged onto the Displayed Attributes and the drop target is a URL-type attribute, then that attribute rather than $URL receives the dropped URL as its value.

    Resolving the link title

    If the browser does not supply enough data, a drag to the $Text area results in the just the URL string being added to the note as text.

    If the dragged object is a browser bookmark the note name will be taken from the bookmark. If the dragged object is a bare URL, Tinderbox will attempt to fetch the title from the URL and set the note name accordingly.

    Dragging images from Safari

    Dragging an image from Safari to a note window imports the referenced image as opposed to setting the URL attribute.

    Dragging Address info into Tinderbox

    Tinderbox accepts drags of vCards (vcf) from Apple Address Book and other vCard-compatible sources. A new note is created.

    If a vCard is dropped on an existing note (icon) the data is added to the note and an enactment (of the text 'vCard') is shown. Dropping a vCard onto a Map or Outline view background makes a new note as in previous versions; dropping a new vCard note does not trigger an enactment helping clarify which process is occurring. The process (re-)populates the following attributes in the People attribute group (if suitable data is detected):

    • $AIM
    • $Address
    • $Email
    • $FullName
    • $Organization
    • $Telephone
    • $Twitter

    Also, the $URL of the (new) note will be (re-)set to the corresponding AddressBook entry. It uses a special URL of the form "addressbook://AB8F8A3E-B4F2-4DE6-9D7B-C8C511B8CC1A:ABPerson"; opening the the URL opens Address Book at that item.

    The vCard's raw data is added to $Text. If dropping on an existing note, the raw data is only added if there is no $Text, thus preserving any pre-existing text is not lost. The raw vCard data is also stored in the note's $RawData for that note, unless/until AutoFetch is also used by the note (N.B. AutoFetch cannot be used to refresh vCard data).

    Dropping a vCard on a note sets the prototype 'Person' if a prototype of that exact (case-sensitive) name exists. If no prototype match occurs, none is applied. When dropping on an existing note, if a "Person" prototype is found, it is set and in doing so will replace any existing $Prototype setting to a different prototype.

    The telephone number chosen by Tinderbox will be the source data's preferred telephone number.

    To drag-drop add vCard data or refresh existing note data, the data must be dropped thus:

    • Map. Drop onto a note icon. That is the title/text part, but not onto a data table, or—for containers/agents—the viewport map or plot area.
    • Outline. Drop as if placing as a new, or first, child of the receiving note, i.e. so the triangular drop position indicator triangle is over the correct drop-target and points to the right.
    • Chart. Drop onto any note (whether a leaf or branch of the chart).
    • Timeline. Drop onto a note.
    • Treemap. Drop onto a note.

    In each case if the drop is correct, you will see an enactment: the view clears and the caption 'vCard' appears and disappears as the view re-draws.

    Dragging content from DEVONthink to Tinderbox

    When dragging an item from DEVONthink, $URL is set to the DEVONthink item URL if it has once. For example, if the item is a web page, $URL is set to the URL of that page. If the item doesn’t have a URL, Tinderbox sets $URL to the DEVONthink internal URL to allow prompt reference to the item.

    More on interactions with DEVONthink.

    Dragging emails to Tinderbox

    Dragging an email from an email client such as Apple's Mail.app, MS Entourage or MS Outlook will result in a new note. The email's subject becomes the note's $Name and the body copy becomes the note's $Text. Be aware that message headers, including to/from addresses, etc., are not imported.

    Additionally, but only when dragging from the Mail.app:

    • The new note's $URL attribute is set to the source email's Mail.app pseudo-URL (as 'message:< … >'). Note that the URL's characters on the < and > are actually stored in url-encoded form as %3C and %3E respectively; thus for example 'message:%3CE7B7A670-A8E3-4EEB-8921-3596825A334C@me.com%3E'. Using the URL button in the Displayed Attributes table will open the source email in Mail.app.
    • The imported $Text is also parsed for any Ziplinks method-style mark-up which is then evaluated and new internal text links are created if valid.

    On first use of drag from Mail.app, newer OS versions will require the user to allow inter-app access (a once-only task). This presumably to enable verification of the email's source pseudo-URL.

    Dragging HTML files to Tinderbox

    When HTML files are dragged into Tinderbox, the $Text of the note created uses the HTML source's style information for formatting as styled text.

    Dragging in Apple Calendar events

    If an event from the Apple Calendar app is dragged or pasted into a Tinderbox view has invitees, the names of the invited people are listed in a system attribute, $Participants.

    Whether individual participants are retrieved as the person's name or as their email address relates to the data passed by Calendar and is not due to actions by Tinderbox.

    Imported calendar events are assigned the prototype Event if the prototype exists, but only if the newly-created note wasn't already assigned a prototype by the OnAdd action.

    Dragging TextClipping files to View pane

    TextClipping-type files may be dragged to the view pane.

    Dragging URLs into Tinderbox views

    When dragging a URL into a Tinderbox view, the value of $DisplayedAttributes is set to 'URL' only if the OnAdd action of the parent container has not already assigned a value. This prevents the default action overwriting a specific or prototype-inherited Displayed Attributes choice.

    Dropping plain text files into Tinderbox

    This describes use of plain text files (e.g. '.txt.'). Drag drop of styled text files is described here.

    Dragging onto an Outline, Map view

    Dragging a file onto a major view window creates a new note whose $Name is the filename of the dropped file. The new file is added at the top of the outline; i.e. $OutlineOrder position '1', or first in sibling order if the view focus is a container. Chart view does not support a general drop, but also see below. When a text file is dropped, Tinderbox will try and find embedded formats: see 'other types of data' below.

    Dragging onto a note icon in Outline or Chart view

    Dragging a file onto a note icon in a view window creates a new note whose $Name is the filename of the dropped file. Use the normal note-positioning tell-back to see if a note is added as a sibling or child of the note under the drop. Note that Map view does not support this degree of placement.

    In Outline view, dropping onto a note icon is just that: the icon at left and not its badge or title.

    Dragging into the $Text area of the text pane

    Copy the note's contents and paste instead, otherwise the dropped note is embedded in $Text—as opposed to extracting and adding the text therein.

    Other types of text data

    Be aware Tinderbox handles drops of other textual data in particular ways:

    • Browser URLs (including local pseudo-protocols used by DEVONThink, Bookends, Yojimbo and other apps).
    • Address Book info & vcards.
    • Emails.
    • Tab-delimited or CSV tabular data. ('spreadsheet' import)
    • HTML: this is teated as plain text, i.e. the resulting $Text shows the source code and not as rendered HTML.
    • OPML files.
    • Old version of the app supported drag-drop of tab-indented outlines but this is not supported in current v5 releases.
    • Bookends selections.
    • FreeMind '.mm' files.
    • tabbed outlines (tab per outline level). Produces nested notes as per tabbed outline.
    • iCal calendar events.

    Text formats not supported

    These formats not supported for drag/drop:

    • Word-processing app-specific documents, e.g. for Word, Pages, etc.
    • Scrivener project files, although they can be opened directly from the File menu.

    Styled text, including such as word processor text and rendered HTML can be imported by copy/paste to the $Text of a selected note; there is no automated method for multiple imports of such data.

    Dropping styled text files into Tinderbox

    Tinderbox does support drag/drop of direct import of styled text (.rtf) text files into the view pane.

    Styled text can be pasted into note $Text, supported style and weblinks are retained. Use Paste-and-Match-Style (⌘+⌥+⇧+V) to paste a plain text version of the source text.

    Styled text can be copied from $Text.

    There is no bulk import method, i.e. for one or more discrete files. Note that bulk text import is supported for plain text.

    Exploding Notes

    A single note's text ($Text) can be 'exploded' (split) into a container holding a number of discrete smaller notes by specifying where Tinderbox should divide the current text. The newly created notes contain an appropriate segment of the original note, using part of the same text as the note title. The basic default behaviour is to split the source by paragraph, using the paragraph of text as the note's text and the first sentence of the paragraph as the note's title. However, there are a number of option, described below that control the title and content of the new notes. There will (should!) be no empty notes, such as those that might arise where two hard line returns are used as faux paragraph breaks, as these unwanted 'empty' outputs are automatically deleted as part of the Explode process. Empty notes will not be emitted for sequences of multiple paragraph breaks, i.e. sequences of greater than two breaks.

    This process can be used to help with the import of data as well as for existing notes. For imports, drag, a plain text format file into an Outline or Map view, so as to create a new note. Note with that, or with a large existing note, selected in the view pane, choose Explode… from the Note menu. The option is available regardless of which pane has focus (prior to this, be aware that the Explode menu option is disabled if the input cursor is in the text pane).

    Calling Note ▸ Explode presents the Explode pop-over. There are essentially three discrete sets of options to set before committing the explode:

    • Defining how/where the source is split. This is defined by the top two radio buttons:
      • Break at paragraphs. Breaks each paragraph into a new note (default option).
      • Break at delimiter. Break on a (custom) delimiter. The input box for the delimiter is hidden when this option is not selected. The delimiter is a string of character(s) that is a regular expression that immediately precedes the break point. Tinderbox assumes each section of the source note that will form a new note starts with the delimiter. If there is source text before the first occurrence of the delimiter, Tinderbox behaves as if there were a starting delimiter and makes a new note use the content between source start and the first occurrence of the delimiter. Tinderbox remembers the last-used custom delimiter until the end of the current session. Use of delimiter regular expressions is described in more detail further below.
        • Delete Delimiter. If the custom option is chosen, there is a further option to delete the delimiter string, otherwise it is retained as the end of each new note's text (as the end of the delimiter string is the per-note break). When importing date for explode and using a deliberate string for delimiter purposes it is usually best to use this sub-option to avoid importing unnecessary data.
    • Selecting source of new note $Name and $Text. The Title panel settings give control of what part of each newly split note's $Text is used to form the note's title ($Name). This is done at sentence or paragraph scope. A 'sentence' is delimited by a terminating period, exclamation mark or question mark. A 'paragraph' is delimited by a line break. By default, an explode-generated note uses the whole exploded section of the source note as its own $Text and that text's first sentence as the note title. Explode removes any leading or trailing whitespace from titles of exploded notes.
      • The scope of a new note's title can be altered:
        • First Sentence. Only the first sentence of the note text forms the new title (default). When running under macOS 10.14.x or later, Explode is substantially smarter about recognising sentences. It understands, for example, that "Dr. Perkins paid $10.00 to the U.S. Treasury." is one sentence, not five. However, if the user's current language locale does not support the new sentence-detection neural net, Tinderbox falls back to use the older sentence-end detection logic.
        • First Two Sentences. The first two sentences form the new title.
        • First Paragraph. Only the first paragraph is used for the new title. When importing custom data, such as lists of papers that often contain punctuation marks, this is usually the best option to choose.
      • When Explode constructs a note title, the title may extend up to 512 characters, and will include either the first line or the first $Text sentence of the new note—whichever is the best fit. If still over 512 characters the title is truncated at that point with an ellipsis.
      • Two tick boxes give additional control the $Text of the newly created notes. By default, both are un-ticked:
        • Remove title from text. If ticked, the text used for the above choice is deleted from the new note's body text.
        • Omit text. If ticked, this results in only a $Name being set for new notes and no $Text. If importing a list of data consisting only of data to form the title of new notes, this box should be ticked.
    • Actions to apply to newly created notes. The Action box allows action code to be inserted that is applied to each newly exploded note by setting an $OnAdd for the 'exploded notes' container created by the process. If it is desired to apply a prototype other than the default (see below the section 'Exploded Notes' prototype for more detail), simply set the action to set the desired prototype's name. Essentially, the default OnAdd action of the 'exploded notes' container is the OnAdd action (if any is set) for the 'Exploded Notes' prototype unless the user adds code to the Action box; depending on the inputs, this may result code from Action and from the prototype being applied to newly-exploded notes.
    • Example preview. This panel Gives a preview of the $Name and $Text of the first exploded note. A control below the preview allows cycling through a preview of successive exploded notes.

    Finally, the Explode button closes the pop-over and starts the Explode process using the choices set above. Focus remains on the exploded note. The Return keypress will act like a button press and start the Explode.

    Custom delimiters

    This is a regular expression ('regex') but may be a literal string (i.e. the actual characters to match). Any regex-based text matching is case-sensitive. For single character matches, the matched character forms the end of the first/preceding note. For instance:

    • \n A newly exploded note will begin after new line feed character. This is also the default for this option, it is essentially the same as 'break at paragraphs' overall explode default. [More on line-end character codes.]
    • \r A newly exploded note will begin after each carriage return or hard line break.
    • \t A newly exploded note will begin after each tab, e.g. for tab-delimited content pasted into a note.
    • \, A newly exploded note will begin after each comma, e.g. use for CSV content pasted into a note. In this case it might make sense to delete the demiyied as a trailing comm might suggest missing content.

    For multi-character matches, the new note starts at the beginning of the matched string, and is thus included in the new note. Therefore in this case it is usual to use the Delete delimiter option (see below), so the detected delimiter string is removed from the start of each new note's text. For example:

    • \d{1,4}\ ?. A newly exploded note will begin at the beginning of line starting with a sequence of between 1 and 4 numerical characters followed by zero or 1 space characters.
    • #### (delimiter deleted). A newly exploded note will begin after the end of each occurrence of the string '####'. After, because the delimiter has been deleted.
      • Often text is generated/edited elsewhere, adding characters as a deliberate explode delimiter for Tinderbox use. In the above case a better approach might be to add the '####' on a discrete line as this is easy to spot when visually scanning text. If so, the custom delimiter to find/remove becomes ####\n. Of course the '####' part of the delimiter can be whatever the user chooses, the key point here is to include the trailing '\n' if the delimiter is on its own line in the source text.
    • action: (delimiter deleted). with match 'action: ' but not 'Action: ' as the regex test is case-sensitive.
    • Line start/end: the regex special characters ^ (start of string) and $ (end of string) apply to the start/end of the note text and not, as is sometimes assumed, to the start/end of individual lines of text (i.e. paragraphs of $Text). The delimiter regex is applied sequentially to each line in the source so the start of the regex pattern is always the start of the line. The end of the line will be the first line break, i.e. \n.

    Delete delimiter option. This is only visible/available if the 'Break at delimiter' option is selected (default = not ticked). Tick ing this option removes the specified delimiter character(s) from the new exploded notes. When the delimiter is a complete line/paragraph, ensure the string used includes the line return character at the end or some output notes will have text starting with a blank line.

    Escaping characters for regex use

    If struggling with understanding regex, assume that any space or non-alphanumeric character in a custom delimiter needs escaping by preceding it with a backslash \, e.g. a\+b rather than a+b. Without the escape '+' is interpreted as 'a+', i.e. a sequence one or more 'a' characters and thus the literal '+' in the delimiter would not be matched.

    What results from an Explode?

    The exploded (source) note itself remains unchanged and a new child container of the selected note is created, called 'exploded notes', and which contains the resulting new notes (i.e. the individual exploded notes are grandchildren of the source note). Each note contains as its text a section of the original text with the notes being titled according to the choices (described above) made before exploding. Using a secondary container for the notes might seem odd until realising this allows for the fact, more so for exploding existing notes than for new import, that the note being exploded might already have children; thus the new notes are separated from existing children of the exploded note.

    Also notice that the 'exploded notes' container is added to the outline order after any pre-existing child notes for the exploded note, i.e. it is the last child (and thus easily accessible via the lastChild designator, amongst others).

    The 'exploded notes' container does not inherit anything from the source note. However, the Action box allows the $OnAdd for the 'exploded notes' container to be set afresh for each explode. However, the 'Exploded Notes' prototype (see below) is added to the 'exploded notes' child container of the exploded source note.

    If there is code in the Action box and the Exploded Notes prototype's $OnAdd, both actions are run with the Action code running last. So if the prototype set $Color and $Badge, and Action set $Color (to a different colour), after the explode, the new notes would have the $Badge set via the prototype but its $Color setting would be overridden by the $Color value set by the Action code.

    'Exploded Notes' prototype

    When a note is exploded the 'exploded notes' container has a built-in prototype 'Exploded Notes' applied. Note the different letter case from the 'exploded notes' container; this is deliberate to stop name collision in queries. If the prototype of the /Prototypes container does not yet exist, Tinderbox automatically created the container and adds the prototype to the document before applying it.

    Note the case sensitive spelling of the post explode container's title vs. that of the prototype; this is deliberate to avoid name collisions, e.g. he prototype does not want to be matched by a query looking for 'exploded notes' container(s).

    By default, the only customisation of this prototype is to add $ChildCount as a Displayed Attribute. The prototype makes it easy to set up things like counts or a specific set of OnAdd actions (rather than set an action in the dialog: this can be useful if there are a number of actions to be set. The ability to customise this prototype becomes useful if doing regular/repeated Explodes.

    For the reason explained above, do not use Action box code as well an $OnAdd in this prototype. At least do not do so if both pieces of code set the same attribute to different values. Carefully considered use of both input does, however, allow for document-wide consistent settings via the prototype alongside per-Explode settings using the Action box.

    This prototype can be added manually, via the File ▸ Built-in Prototypes menu, for instance to customise it before using an explode. To 're-install' the default version, simply delete the any existing version of the prototype and re-add it via the Built-in Prototypes menu.

    Working with exploded notes

    Of course, the constant name of the container holding the new notes ('exploded notes') makes it easy for agents to find and work on the new notes' actions. Be aware that unless the 'exploded notes' is cleaned up or renamed after an explode, there may be more than one container of that name. A benison of this is that it is possible to write a generic agent to act on the contents of all explode results using an $AgentQuery:

    $Name(parent)=="exploded notes" 

    By adding a preceding descendedFrom() query argument to the above query, the scope of action can be reduced to items descended from a given container.

    descendedFrom(To Do) & ($Name(parent)=="exploded notes") 

    This might be done because of the nature of the resulting agent action to be applied or simply to reduce agent update cycle time.

    In summary:

    • 'exploded notes' receives all the source note's attribute values except $Rule and $OnAdd. If the 'Exploded Notes' prototype has been altered to locally set attribute values these will be used in preference.
    • Individual exploded notes do not inherit attribute values.
    • Agents or manual editing of 'Exploded Text' actions should be used to apply attribute values to exploded text.

    The explode action is applied after the text of the newly-created note is set, allowing the action to modify or depend on the exploded text. Explode also remembers the most recently-used delimiter, which can be convenient when using complicated regular expression delimiters.

    Formatting dates for import to Tinderbox

    Tinderbox handles import, generally via drag drop onto a major view, in a variety of ways. In some cases, such as tab-delimited text (also called TSV or 'spreadsheet' format), Tinderbox will scan the text and map some data to Tinderbox date attributes.

    In order for source text to map correctly to a Date-type attribute, bear in mind that Tinderbox will look for dates in your source data that match your Mac's System 'short' date and time format. Be aware that such formats will vary by locale and may be further customised by the OS account user. Tinderbox will also happily parse dates input in any of you locale's Short, Medium, Long or Full formats.

    If in doubt if in doubt as you your Mac's preferences check 'System Preferences'. Currently it is under 'Language & Region'.

    The OS preferences list date and time formats separately. If your import source date includes both date and time, ensure it leaves a single space character between the date and the time segments.

    When the import source data is passed to a Date attribute, if the result is wrong the resulting Date value will be 'never' or some incorrect date; the later generally occurs if part of the date is in the wrong format and coerces to an unexpected value. There may be no source data still in the TBX file to tell you what text string caused the wrong date to be created. Therefore it makes sense to ensure import data is in the correct format before import.

    That said, Tinderbox—via undocumented internal logic—may detect other common date formats. You can test raw data input and if it works, then that's fine, though you would be wise to check a range of specimen days months and years. However, for more than the occasional import, by such means it will repay you to ensure the import using the formats described above.

    A special exception is OPML import. The OPML standard stipulates that dates, used to define the note's creation date/time, should use the RFC 822 format. Tinderbox will make the same assumption for date formats for the 'created' tag attribute. Tinderbox does not attempt to parse dates in the note's title or text.

    RFC 822 and year format. Note that RFC 822 actually specifies 2-digit years whereas 4-digit is more appropriate (indeed the later RFC 1123 makes it so). Tinderbox's own RFC 822 format string ("*") uses 4 digit years and most OPML capable tools will likely use 4-digit years too. If dates import incorrectly via OPML, check you see if they are using 2 digit years and if necessary correct the source.

    Time. If a date is supplied with no time, Tinderbox will append the current system time in hours:minutes:seconds (although the seconds element is usually suppressed in the Tinderbox display). An exception is if the supplied data is in the OS locale's 'Full' format and has no time, in which case the time is set at 12:00:00.

    Importing from other file types and applications

    Tinderbox supports import of general text formats like plain text, styled text, HTML, etc. Formats specific to particular applications, e.g. citation information, may be supported: see the section on support for other app-specific formats.

    Importing Markdown files

    Files with extension .md, .mmd, and .markdown that are dragged into a Tinderbox view are now converted to styled text using Markdown conventions.

    To avoid Markdown to styled text style conversion occurring, set the file extension to '.txt'

    Inserting images into note $Text

    An image (see below for types) can be dragged or pasted into a note's $Text.

    To add an image to a note, select the note so it is shown in the text pane. If inserting into existing $Text, create some vertical space between paragraphs so as to make a clear insertion point.

    In Finder either:

    • copy the image and paste where desired into $Text
    • select the image and then drag the selected image to the desired insertion point in $Text.

    If an image pasted into the text is wider than available space, it will automatically be scaled.

    If dragging from the Desktop, ensure the image is selected before starting the drag otherwise the image may not be imported.

    To align the image, for instance to centre it, it is necessary to select the 'text' surrounding the image and use the Format, Text menu to set the alignment.

    Supported image formats

    The best form of image is to use are bitmap formats such as PNG or JPG (JPEG). Images embedded in PDF can be used.

    Animated formats such a GIF or MP4 can be inserted; GIFs will auto-play whilst MP4s will show player controls when moused over.

    JSON import

    From v11.8.0, when working with json, if you attempt to store a list or scalar value into a dictionary, Tinderbox sets the dictionary to a value with one key, error, with an error message as its value. Formerly, Tinderbox stored "", which was not informative.

    OPML Import

    Tinderbox imports OPML files dropped onto Tinderbox views, and also reads OPML outlines. Note that Omnigroup's apps, e.g. OmniOutliner, popularised OPML use but did so using non-standard additions. So when using OPML, do not assume all OPML is the same: read the OPML specification.

    When Tinderbox parses a pasted or drag-dropped OPML, the source OPML filename is used as the name of the container holding the tree of notes parsed from the HTML. The OPML source code is not retained in the TBX document as the data is now imported and the OPML code would simply constitute unwanted file bloat. If the user also witness to store the OPML code, that would need to be pasted into a new note's $Text to avoid triggering the parser.

    If an OPML file has extended outline attributes, and if the extensions do not conflict with Tinderbox attributes, then Tinderbox will make a user attribute for each of the extended attributes. The default 'text' attribute is mapped to $Name [sic]. The non-standard '_note' attribute popularised by OmniOutliner is, if found, mapped to $Text with '&#10;' being parsed as paragraph breaks.

    The user attributes will initially be defined as Displayed Attributes as well, allowing for easier inspection of the extended data.

    OPML support includes Projekt extensions.

    The non-standard but generally used OPML '_status' attribute data is mapped to $Checked which of course can be displayed in outline view as a tick box (good for 'to do' lists).

    OmniOutliner exported OPML: see further detail.

    Note that the OPML <expansionState> element is not supported. By default, any new container notes created from the imported OPML data are all collapsed in Outline view.

    Tinderbox will expect dates to be in RFC 822 form in accordance with the OPML spec: see more.

    Pasting a child to childless notes

    This mainly affects work in Outline and Chart views. When pasting notes, either within or between TBXs, it may often be the case that the paste location needs to be as the child of existing note the currently has no children. With paste, as opposed to drag/drop, there is no way to indicate via the cursor whether the incoming note(s) are to be added as sibling(s) or child(ren). There are two possible approaches. In both cases select the to-be-parent note before:

    • Pasting, to create siblings. Then select pasted notes and hit Tab to indent them within the previous sibling (making it the parent).
    • Add a new (temporary) child note, with any name, to the to-be-parent note. Select this new note this new note and do the paste. Delete the temporary note.

    There is a subtle difference between the two methods. The second only invokes the $OnAdd of the intended new container. The first method invokes the latter and the $OnAdd of that container's parent as the pasted content is initially pasted in as a sibling of the containers and so gets the $OnAdd action of their mutual parent.

    If $OnAdd actions are being used or the code used is trivial, then both methods are equally good. If there are significant location-dependent $OnAdd actions, the second method is the best one to use.

    Pasting and Text Margins

    When pasting text between Tinderbox documents with different margins, the newly pasted section of text may show a different margin. This difference will remain, even if the selection if re-formatted as 'plain'. Re-formatting is not needed; to re-align everything simply close and re-open the note and the margins will be correctly aligned.

    Pasting into Tinderbox and line ends

    Tinderbox uses the data on the clipboard. Users are sometimes confused when pasting text from other sources to get fewer or (usually) more line ends in the resulting text than they expected.

    The most common reason is that some source formats, PDF being a good example, store lines of text as just that—separate runs of text. This means that although a paragraph of text at source can be selected and copied in a tool like Preview, the data pasted is a set of lines of text not a single run of paragraph. In the same scenario a copy of multiple paragraphs will still be a set of text lines with no obvious paragraph delimiter. This is a 'fault' of the source format, not Tinderbox as some assume: there is no paragraph ending information for the application to use.

    When pasting in text, it is generally a good thing to use 'Paste and Match Style' ([Cmd]+[Opt]+[Shift]+V]) instead of a normal paste. This will retain bold/italic mark-up and tabs but strip things like font typeface. It should also normalise line endings to the macOS form (more on line endings in text).

    Pasting into views

    The result depends on the view type of the current view into which the paste occurs:

    • Outline, Chart. By default the new note is the last top-level sibling (i.e. child of root or a hoisted root scope). By hovering the cursor close to a note, the new note can be a previous/next sibling or child of an existing note at any level at root or in a branch.
    • Timeline. Always the last child of the root of the view. The new note will appear in the 'No Date' sidebar as it will have no $StartDate at this point.
    • Map. Creates a new note at the last-clicked point. If an existing note is selected, the new note is created to the right of that note in the first available space.
    • Attribute Browser, Crosstabs, Hyperbolic, Treemap view. Drop data is not accepted, so nothing happens.

    The result of the paste, where a note is created is that:

    • the title ($Name) is the text of the note (or the initial part with terminating ellipsis if very long).
    • the text ($Text) is set to the plain text of the source data , i.e. all styling, links, etc. are not retained. If such styling is needed, first make a note, set focus in the text are and paste as this will retain (supported) source styling and HTML links.

    Pasting notes to a different TBX: $Created and $Modified

    When a note is pasted into a document, its $Created and $Modified dates retain their values. Previously, both $Created and $Modified were set to the date on which the note was pasted.

    $ID is also reset to avoid the possibility of two notes having the same ID value.

    See more on copying or moving notes between TBXs.

    Pasting tab-indented outlines into a view

    The simplest forms of outliner often use a line/paragraph of text per 'note' and outline position is indicated by tabs(s) at the start of the line.

    Such basic outlines can copied and pasted directly—as an outline—into Tinderbox. If a paste into a Tinderbox view (most sensibly Outline view) is detected as containing a tab-indented outline, the outline is recreated at the pasted location.

    Pasted-in outlines are inserted collapsed inside a single new container which is always called 'imported outline'.

    The 'imported outline' container's $Text is the whole, as-pasted, text. So, if the text is large and the container is to be retained, it can be sensible to delete the container's $Text.

    Each new note created uses the source outline entries text as the $Name and as its $Text. This apparent duplication is to help bridge the fact that simple outliners have no notion of a discrete title vs. text, as was the case with the very earliest outliners. Some try to do both, e.g. OmniOutliner treats the second and subsequent paragraph of the note label as 'text' in contexts like import/export of OMPL. Bottom line, there is no 'norm' though the user's personal past experience might trick them into thinking so.

    Pasting web browser text into $Text

    Copy/Pasting web content into $Text is akin to pasting styled text content into $Text. Weblinks and any supported style features (text colour, font, weight, emphasis) is retained. If SmartLinks are enabled (the default) any weblinks in the source data should be detected and adopted as functional Tinderbox weblinks.

    Using Paste-and-Match-Style (⌘+⌥+⇧+V) plain text is inserted. Note that any links are lost as only the anchor text is retained. Actual URLs in text will be retained but will not be active links.

    Pasting webpage content into a note also sets the receiving note's $URL to the URL of the source web-age unless the note already a $URL value. Thus if pasting from multiple sources, only the source URL of the first page is stored, or none if the note already has a $URL value for some other reason.

    See also: dragging web content into view panes.

    Setting up for Tab-Delimited Import

    Originally, data table import was only for tab-delimited data (TSV), but both CSV and TSV are supported. The same rules (below) apply to how the data is handled. CSV formatting is only assumed if the file has a '.csv' extension. For '.txt' or '.tsv' files, tab-delimited format is assumed.

    For simple data, the auto-generation of attributes from column heads and the data-types assumed are generally correct but for more complexed or nuanced tasks there are some points to bear in mind.

    Tinderbox assumes the data will contain a first row of column headers which it can use to map data to existing attributes or generate new ones.

    The first column always maps to $Name unless a column header value of 'Name' is found.

    Headers are assumed, so if none are suppled, Tinderbox will assume the first data row is the header row, which may result in some strange attribute titles!

    Mapping source column headers to existing Tinderbox attributes

    Mapping is automatic, based on the Header (first) row of the data. Tinderbox will match a column header, case-sensitively, to any existing system or user attribute. Special cases:

    *If a column other than the first one has the header 'Name' (but not 'name'), that column maps to $Name. If no $Name match is found, the first column is used for $Name, regardless of the header value (and that value is not made into an attribute).

    *'Text' but not 'text' maps to $Text. If $Text is supplied from source it is not set as a Displayed Attribute (more below) but a 'text' (i.e. an attribute called 'text') would be.

    Thus header 'my var' will create a new (String-type) '$my_var' following the naming rules below.

    Auto-generated (user) attribute names

    If a column-header (other than if column #1) does not match an existing system or user attribute name, then a new user attribute will be created. The new attribute will use the exact (case-sensitive) insofar as the source value matches. 'Illegal' characters for attributes are substituted with a underscore per such character. Thus, source heading 'my / stuff' creates $my___stuff (3 underscores for space+slash+space). Note how the case of legal text is maintained and only each illegal character is substituted by an underscore. Underscores, common in some database tables are thus maintained during import.

    Date type coercion on import

    These appear to be the 'rules' for coercion, that result is one of only 3 data types being created:

    *Boolean. '0', '1', 'true' and 'false' result in a Boolean-type attribute. Any value other than '0' or 'false' passed to an existing Boolean attribute will coerce to a Boolean true value.

    *Number. Any positive or negative integer or decimal number, barring '0' and '1' will create a Number-type attribute, including '0.0' and '1.0'.

    *String. All other data maps default to creating String-type data. Lists, i.e. semi-colon-delimited strings, are still coerced to Strings.

    Empty Cells

    Empty cells (i.e. content-tab-tab-content) and line breaks in cell content are allowed. If having import problems due to empty cells, try adding a dummy last column of source data with a value in each row and then delete that attribute (and data) once the import is complete. Cells may contain line break characters (e.g. text intended for $Text) if it is enclosed by (straight) double-quotes.

    Line Breaks

    Tab-delimited. Line breaks are not supported in call values (even for $Text).

    CSV. Line breaks are supported, as long as (at least) that cell's value is enclosed with double-quotes.

    Quote Characters

    Both tab-delimited and CSV ignore single straight quotes and single/double typographic ('curly') quotes. Double-straight quotes:

    • Tab-delimited: ignores whether pairs or odd numbers.
    • CSV. May only be used as balanced pairs to enclose whole cell values. Do not place further odd or paired double-quotes within cell content, even if the cell is quote enclosed.

    Importing Lists

    As even Tinderbox-formatted lists import by default as strings, to avoid getting the wrong data type, a little extra planning is needed.

    Source list data has semi-colon delimited values. Add any needed List or set type attributes (correctly type-configured) to the TBX document before import. If the data is semi-colon delimited it will be correctly parsed as multiple list items.

    Source list data does not have semi-colon delimited values. For this you need a two-stage process: ingest the list as a string, then correct the delimiters passing the result to a List or Set attribute. First, ensure the header does not use the attribute name actually desired for your List or Set attribute. Make the latter attributes of the necessary type(s). Add a stamp with 2 actions (i.e. with a semi-colon between them. For example, assume the source list uses a '##' string to delimit values in the 'somelist' column that you want to end up in $SomeSet. The stamp might look like this:

    $SomeSet = $somelist.replace("##",";"); 

    Stamp the ingested notes, check the data. If the list data looks correct, you can delete the source attribute (here $somelist). If using auto-generated Displayed Attributes, you may also need to update those to show the correct (list) attributes.

    Forcing a non-default data type mapping

    As shown above lists cannot be detected and '0' / '1' may be misconstrued as booleans. There are two ways to avoid this:

    *Include a dummy first row of data (i.e. after the header row) with values that will force the correct data type. After import delete the note created for the first (dummy) record. However, note this method does not help for data types other than String, Number and Boolean.

    *Pre-create the attributes and set the desired type. There are two ways to do this:

    **Import the first 2 rows of source and correct the data types of the auto-generated attributes (and check mapping to system attributes). Any user attributes with the wrong data type can have these reset via the Document Inspector, User tab.Then delete the imported date container and notes before importing the full data set. If using copy-paste from another app rather than from a stored data file, you might need to import all data and delete, then reimport after the attributes have been corrected. This method will also show up any attribute naming issues that may arise and which may need correcting at source.

    **Manually create the new user attributes from scratch in Tinderbox. If there are a lot of such attributes, or the same process needs to be done many times in new documents, the method above may prove quicker.

    Import fixes Displayed Attributes in created notes

    The import process sets each new per-row note's $DisplayedAttributes. If you are going to apply a prototype to these notes you may first wish to reset the new notes' Displayed Attributes.

    Spreadsheet Import: CSV and Tab-Delimited Text

    There is no menu option for initiating tabular data import. For tabular data two formats are supported, tab-delimited (TSV) or comma-separated (CSV):

    • Tab-delimited: supported for file drag drop and copy/paste of table data. For files use '.txt' or '.tsv' file extensions.
    • CSV: supported for file drag drop (CSV copy/paste is not supported). For files use the '.csv' file extension.

    Tab-delimited tables are imported intelligently when dragged or pasted into Tinderbox, involving some mapping of table data into existing or new attributes. Mapping is based on a header row which is expected as row 1 of the data.

    For example, selecting a table in a spreadsheet and pasting it into Tinderbox will create a useful set of notes:

    • The first row is treated as a set of headings, which map to attributes. New user attributes will be created for attributes that do not already exist.
    • Any column with the heading 'Name' will map to $Name (early documentation requiring 'Name' to be the first data column can be ignored).
    • A new container will be created to hold the table's rows. Unlike early versions of this feature source data is never placed in the import container's $Text. If such data is needed for review or re-import, it should be retained as an external file (or link to it via a File-type attribute).
    • Each row of the table becomes a note. The table's fields are Displayed Attributes, and these attributes are populated from the table.
    • For date-based data: see date formatting for import.
    • If there is a 'Prototype' column in the input data and appropriately (case-sensitively) named prototypes pre-exist in the document, the record(s) will have the relevant prototype set for them (i.e. the app sets each new note's $Prototype). Note the necessary prototypes must exist in the receiving Tinderbox document before import occurs: Tinderbox will not create named prototypes found only in the data.

    More on attribute creation and data types: mapping to existing attributes, detecting data types, line breaks in cell values, empty cells, etc.

    The tabular feature works beyond formal spreadsheets, any tab-delimited text sample should import. This allows other material such as vcf address card data to be dragged into Tinderbox. Tinderbox will attempt auto-detection of dates, non-ASCII characters and to handle clipboard data from Numbers '09.

    Also, Tinderbox will generally deal with characters in column headers that are not normally supported in attribute names. For instance, an underscore is often used as a substitute character in field names. Whilst a user cannot deliberately make an attribute named "Some_Field" via the User Attribute Inspector, because it contains an underscore, data import may do so in order to retain fidelity with source.

    From v11.7.0, reflecting the increasing size of data files, the container holds only the start of the imported data. The implicit character count is not documented, so source data files should be retained post export should the raw data need revisiting.

    Prior to v11.8.0, tab-separated-value (TSV) imports failed if quoted strings contained newline or tab characters. Ideally, these ought to be escaped as \n and \t but, regardless, Tinderbox now handles the case correctly.

    File Extensions. For Tinderbox to correctly handle tabular data added use and appropriate (case-insensitive) file extensions. For tab-delimited data use '.txt' or '.tsv'. For comma-separated data use '.csv'. Only tab-delimited data can be pasted directly from the clipboard and still be parsed into new notes.

    Displayed Attributes. The import process sets the $DisplayedAttributes locally for all notes it creates. Thus if you apply a prototype using Displayed Attributes to the newly created notes, the Displayed Attributes will not show in the inheriting notes as the local values unless/until you reset the $DisplayedAttributes for these notes.

    Prototypes. Data from a 'Prototypes' column will be used to set $Prototype for the newly imported notes, but only if the prototypes are defined in the document before the import occurs. Otherwise even if there is data, $Prototype will remain empty.

    Existing notes vs. New notes. The tab-delimited import method only creates new notes; there is no automated data merge for existing notes. Thus, tabular import cannot be used to set attribute values in pre-existing notes. This means a new note with a title ($Name) of an existing note will get created on import as a duplicate, rather than changing attributes of the existing note. However, this does offer scope for updating existing notes. Action code can search in a given location, for notes whose $Name matches a note elsewhere. Having identified the link, further action code could then copy across the necessary attribute values to the older pre-existing note. The newly imported note could then be moved to a new container outside the scope of the original query (i.e. so the update action only occurs once).

    CSV content detection

    CSV import of dropped/pasted data into the view pane is abandoned if more than two fields are missing. The challenge for auto-detecting CSV is that if the first paragraph/line of the received test has commas these might either be CSV markers or normal punctuation.

    The revised CSV-detection logic is:

    • If there is only one record (i.e. input row or line), this is not CSV data.
    • Does the first record have at least 2 columns? If not, this is not CSV data.
      • Note that successive commas, with or without intervening spaces, are detected as empty (valid) columns
      • Is this the first record? If so, 'EXPECTED' is set as the expected number of columns in other rows.
    • If this is not the first record, and this line has more columns than EXPECTED, this is not CSV data.
    • If this is not the first record, and this line has 2 or more fewer columns than EXPECTED, this is not CSV data.
    • Repeat for each record.
    • If no record has failed CSV detection, the data is CSV.

    If CSV is not detected, normal paste/drop-to-view behaviour applies. The filename (or first sentence, if not a file) is used as the new note $Name and the entire content is placed in $Text.

    vcard import

    When importing a vcard by dragging from Contacts or elsewhere, Tinderbox places a copy of the vcard text in $Text to allow you to extract specialised fields unique to your work. In some cases, however, the vcard includes a base-64-encoded image, which is not useful in the text. That data is removed from the imported text.

    Watched folders

    A set of options in the File ▸ Watch allows the creation of various types of watched folders linked to external applications. The result is a form of AutoFetch operation.

    Multiple watched folders of the same source type (e.g. more than one Notes folder) are allowed though be mindful heavy use of this feature may affect overall performance, i.e. he feature is not designed as a fully-synced system but rather for importing/updating some external data.

    A watched folder is always added at root level in a document (and should not be moved elsewhere). This is for necessary design considerations re performance. Likewise the watched destination is envisaged as a single item or small collection of items and not a large hierarchy of folders/files.

    The prototypes of watched notes specify that watched notes are imported with a $TextBackgroundColor of white, even if dark styles, since external documents are most likely compatible with light background colours.

    Notes imported from watch folders respect ziplinks-style '[[' markup. To disable ziplinks in a watched folder note, set $Ziplinks to false. To disable ziplinks throughout a watch folder, set $Ziplinks for the folder to false.

    Legacy support note: watched folder support for Evernote was discontinued in v9.0+ due to internal changes in Evernote.

    Refresh timing: all watched folders are refreshed when the TBX document is opened. Then, while the document remains open, the folders are refreshed periodically on their own cycle. The frequency of that cycle is not documented and no force refresh mechanism is known.

    Further notes

    Be aware that

    • When watching a folder in Finder, notes that correspond to deleted (or moved) files are now shown with their names struck through by automatically setting $NameStrike to true.
    • Watched folders of all kinds are checked more frequently.
    • When a file in a watched folder is checked, its $LastFetched is now updated even if the note is unchanged. The note's $NotesModified attribute continues to reflect the modification date of the file.
    • Notes in watched folders should update to reflect changes in the remote document, even if $ReadOnly remains set.
    • Watched folders update documents if they have been modified since they were previously fetched.
    • When watching or importing a folder, the names of imported notes are derived from the file name after removing the extension. For example, the file 'garden.md' is imported to a note named 'garden'.

    There are currently 3 forms of watched folder:

    Finder

    Tinderbox can automatically import selected notes from the any Finder folder, including folders in Dropbox or other remote servers. This is set up via the File menu.

    Multiple watched folders are supported, i.e. more than one (root level) watched Finder folder.

    To connect Tinderbox to a folder, create a root level container (and it can only be at root level) to hold the imported notes and set its $WatchFolder attribute to the name of the Finder folder you want to import. The watched file may be only local to the host Mac drives or may be a shared file via iCloud or Dropbox. Tinderbox will automatically import to or update that container (for supported format files) whenever the TBX document is reopened, and periodically thereafter as part of the AutoFetch cycle.

    The new container created in Tinderbox uses the same name as the source OS folder in Finder and as, as a Displayed Attribute, $WatchFolder. The latter\s value is the POSix local path to the watched folder. Reseting the $WatchFolder to the default (i.e. no value) will cause the Watch function to cease operating.

    The imported notes inherit from a built-in prototype named 'Imported From Finder', making it easy to common Displayed Attributes or visual appearance. Finder tags are imported into $Tags.

    New items

    On detecting a new source file, Tinderbox will add a note with the complete source filename (including extension) with the above prototype auto-assigned. The new notes Displayed Attributes table shows (via the prototype):

    • File holds the OS path of the source file.
    • $NotesModified shows when the item was first added.
    • $LastFetched shows when the source note was last detected as changed (as opposed to when the resource was last checked).
    • $ReadOnly, though this can be toggled off by the user.
    • $Tags, any imported Finder tags.

    If the user chooses, additional Displayed Attributes can b e added via the prototype (or individual note's $DisplayedAttributes) though such displayed attributes cannot be editing in the Displayed Attributes table whilst $ReadOnly is ticked (true).

    Changed Items

    When, during autofetch, a source note is detected as changed (i.e. as a different macOS modification date/time) the affected note is updated:

    • the $Text value is replaced by the current source text.
    • the $Tags value is replaced by the current source finder tags.
    • $LastFetched is updated to the time of this (Tinderbox) edit (not the source file's OS modified date/time).
    • if a source file is now missing (e.g. deleted or moved) Tinderbox retains the note, but the user may delete it without the note being later regenerated.

    Note that the 'update' overwrites existing $Text and $Tags. In the case of $Tags the inputs are not merged so any tags set in Tinderbox would be lost. Apart from the 3 attributes above, no other change occurs so things like user attributes set for the note will not be affected.

    Limitations:

    • Changes to the imported notes will not be propagated back to the source application (i.e. Finder) or to other devices: the source data is watched, not two-way synchronised.
    • Notes created by watching Finder are read-only by default, inheriting $ReadOnly from their prototype.
    • Changing Finder tags, e.g. via File Info, does not necessarily trigger a change to the file's OS modified date/time so Tinderbox does not detect a change. Therefore it may be necessary to alter the files OS modification date/time by other means if it is desired that Tinderbox detects a change only to tag data.
    • there is no way to know when the AutoFetch last ran, though the Tinderbox Inspector's Agents & Rules tab gives some idea (the circular progress meter). As no change happens if no change is detected as source, the only way to be sure the watch has run, e.g. if an expected source change does not appear in Tinderbox, is to close both the TBX and the Tinderbox app, then re-open both. Note the point above that simple changes to (Finder) tags in Finder File Info does not mark the file as changed.

    Factors to consider when using watched Finder folders

    If intending to use menu File ▸ Watch ▸ Folder from Finder, be aware the target folder may contain a mix of documents some of which Tinderbox cannot read/view (i.e. make meaningful use of).

    If this is the case consider separating non-compatible

    Notes

    Tinderbox can automatically import notes from a folder the Notes application, which is installed in all macOS and iOS devices. This is set up via the File menu.

    Multiple watched folders are supported, i.e. more than one (root level) watched Notes folder. When watching a new folder from Notes, the menu of folders is sorted alphabetically.

    To connect Tinderbox to a Notes folder, create a root level container (and it can only be at root level) to hold the imported notes and set its $NotesFolder attribute to the name of the Notes folder to import. The Notes application's main 'Notes' folder cannot be used as an import destination. Tinderbox will automatically import or update that container whenever the TBX document is reopened, and periodically thereafter as part of the AutoFetch cycle.

    The imported notes inherit from a built-in prototype named 'Imported From Notes', making it easy to set common Displayed Attributes or visual appearance.

    From v11.0.0, when importing from Notes, Tinderbox retains the original note text size and styles.

    Limitations:

    • Changes to the imported notes will not be propagated back to the source application (i.e. Notes) or to other devices: the source data is watched, not two-way synchronised.
    • The import process is comparatively time-consuming; it may be preferable to limit import to folders with no more than a few dozen notes.
    • Notes created by watching Notes are read-only by default, inheriting $ReadOnly from their prototype.

    Tot

    Tinderbox can watch and automatically import notes from the Tot application. This is set up via the File menu.

    Watching Tot creates a top-level container 'Tot' with 7 numbered child notes, 1–7, one for each Tot note. Watching Tot will import text from Tot, but does not sync to Tot. Thus, watched Tot notes are set as read-only as each refresh replaces existing $Text with the source Tot note's text.

    The watch process also adds the 'Imported From Tot' built-in prototype, to the notes. The prototype sets $Tot and $ReadOnly as Displayed Attributes.

    The 'Tot' container sets the $Tot attribute to "1;2;3;4;5;6;7". Removing any list item stops that Tot note being monitored, but the relevant Tinderbox note is not deleted. If a note for an unwatched Tot note is deleted, it is not recreated.

    Limitations:

    • Changes to the imported notes will not be propagated back to the source application (i.e. Tot) or to other devices: the source data is watched, not two-way synchronised.
    • Notes created by watching Tot are read-only by default, inheriting $ReadOnly from their prototype.

    Watched Groups

    Content can be auto-fetched for groups of records from some other applications. This is not a sync mechanism.

    Multiple watched groups are allowed though be mindful heavy use of this feature may affect overall performance, i.e. the feature is not designed as a fully-synced system but rather for importing/updating some DEVONthink data.

    A receiving container for the group's data is always added at root level in a document (and should not be moved elsewhere). This is for necessary design considerations re performance.

    Refresh timing: all watched folders are refreshed when the TBX document is opened. Then, while the document remains open, the folders are refreshed periodically on their own cycle. The frequency of that cycle is not documented and no force refresh mechanism is known.

    There is currently one form of watched group:

    DEVONthink

    Tinderbox can automatically import selected groups of records from DEVONthink Pro (and DEVONthink Pro Office).

    To connect Tinderbox to a DEVONthink group, create a root level container (and it can only be at root level) to hold the imported notes. Set the container's $DEVONthinkGroup attribute to the unique DEVONthink ID of the group to be imported (this is the group's Item ID). Pay close attention to any macOS request fro permissions—see further below.

    Multiple groups are supported, i.e. more than one (root level) watched DEVONThink group, but be mindful that excessive such mapping may affect performance.

    The Watch set-up uses the DEVONthink group picker.

    NOTE: the watched group(s) feature is not a sync mechanism, but a method to pull current DEVONthink data into Tinderbox

    The DEVONthink reference must be a group and not an individual item (if necessary, place a single item in its own group). Tinderbox will automatically import or update that container whenever the TBX document is reopened, and periodically thereafter as part of the AutoFetch cycle.

    The resulting imported notes inherit from a built-in prototype named 'Imported From DEVONthink', making it easy to set common Displayed Attributes or visual appearance.

    Limitations:

    • Groups nested within the referenced group are not currently imported.
    • Changes to the imported notes will not (yet) be propagated back to the to the DEVONthink application or to other devices.
    • Notes created by watching DEVONthink are read-only by default, inheriting $ReadOnly state from their 'Imported From DEVONthink' built-in prototype.

    PDF documents dragged from DEVONthink are imported as styled text if possible. Previously, they were imported as images.

    Ziplinks are interpreted when text is pasted in the view pane, or when files or DEVONthink items are imported by dragging them into a view. Ziplinks are not interpreted when $Ziplinks of the imported note is false. (Note that the built-in Imported from DEVONthink prototype in previous releases defaults to setting $Ziplinks false; if wanting want to import ziplinks from DEVONthink into older documents, check $Ziplinks is set to true. DEVONthink watch folders should interpret [[ziplinks]] found in source (i.e. DEVONthink) text files.

    Factors to consider when using watched DEVONthink groups

    If intending to use menu File ▸ Watch ▸ Group from DEVONthink, be aware the target DEVONthink group may contain a mix of documents some of which Tinderbox cannot read/view (i.e. make meaningful use of).

    However, DEVONthink users should recall that DEVONthink supports 'replicants' (similar, but not exactly the same as, Tinderbox aliases). If a new group is created in the source DEVONthink database, then Tinderbox-viewable document formats such as Markdown (.md) or styled text (.rtf) can be replicated into it; this new group can then be the group designated for use with Tinderbox's watch group feature. Tinderbox can then be configured to “watch” that DEVONthink group holding the replicants.

    This replicate-to-target group approach can also be used to gather documents from across a DEVONthink database to a single group that Tinderbox watches.

    BEWARE - potential macOS permissions issue

    When you choose Watch ▸ Group from DEVONthink, macOS displays a window asking for permission to control DEVONthink. This is typically straightforward but can cause trouble in several ways. These include any one these:

    • Another window might be on top of this one. This ought not to be possible, but has been known to happen.
    • The window opens on a different screen, unnoticed by the user.
    • Worst of all, not expecting this window, the user dismisses it by denying permission. In that case, the system may refuse even to ask in the future, and resetting can be quite difficult and involves mysterious command-line invocations. This is a macOS bug, but it appears Apple is shy of solving it because this is also a line of attack for spyware.

    So, pay attention to OS permission requests!

    Working with $Text: support for styled text

    Styled text, whether just basic bolding/italicising/underlining or more complex styled text formatting is supported only when working in a selected note's $Text area in the text pane. Thus:

    *Full styled text:

    • Typing into the $Text area & use of app menus on $Text selections.
    • Copy/paste from styled text source in other notes or outside Tinderbox.

    *Un-styled text (no mark up at all):

    • Inspector setting $Text
    • Info view setting $Text
    • Action code setting $Text. This has been changed by some new action code allowing the setting of $Text size and colour.
    • Drag-drop text file import (only supports plain/UTF-8 text)
    • Menu: Edit ▸ Paste and Match Style (only characters, whitespace and line breaks are preserved)

    Tip: If pasting styled text, it is often much faster to use Paste and Match Style and then re-apply any needed styles, rather than trying to wrangle styled text paragraph styles. Rich pastes often bring their own page width, i.e. different from Tinderbox defaults, with fixed widths/margins which can be problematic for hassle-free printing. Remember that by default text pane rules are hidden so these rogue paragraph settings may be hard to spot. There is no paste option that preserved some formatting, e.g. bolding, but drops margin and tab settings.

    Export

    This section covers various forms of export of notes from Tinderbox, both via formatted (e.g. HTML) marked-up text and also using styled text or plain text.

    Also see the Export Inspector, export codes, and export-related system attributes.

    More above export from Tinderbox.

    Aliases in HTML Export

    When using the HTML Export method, whether for HTML or other formats, aliases are exported as separate pages in the appropriate location within the output. This makes it easier to use web links to alias content that point to the right place. It also helps when web output uses a hierarchical navigation system as with aTbRef.

    Aliases share their original's text and web links but can have their own basic links (if none the original's are used on export).

    Attribute Browser Export

    When the current tab is an Attribute Browser and focus is in the view pane it is possible to Export the view to a styled text document.

    Per-attribute value headings (and their summaries if present) are exported as a row.

    Each note listed is exported as a row of text, using $DisplayName. If column view is used, column data is included tab-delimited.

    Although all discrete entries are tab-delimited, the styled text itself is not in tabular form.

    Built-in Export Templates

    Tinderbox includes a number of specimen template notes to export using HTML, or other formats such as OPML. These are accessed from the File menu. Any necessary (root level) containers and/or prototypes these notes need are added along with the template. See more on templates.

    The built-in template listing also includes templates from the application support 'templates' folder.

    Templates that are also prototypes are not shown in the various pop-up template menus (such as in HTML view).

    Copying from Column view

    When copying selected item(s) from an Outline view that has column view enabled, Tinderbox also copies the displayed columns' data is tab-delimited form. This allows simple sharing by pasting data into spreadsheets and other programs that use tab-delimited data.

    Default Export Location

    If not already given a location for export, Tinderbox defaults to using the current user's Desktop folder.

    The export location is set via the Export Inspector's Export tab.

    Default export template

    If no export template is defined for a note, a default of ^text^, is used instead. This is not a formal template, but a fall-back to ensure the user sees something even if they have not tried export or do not wish to export data.

    Dragging from Tinderbox

    A "text receiver" is a program that expects to receive text drags, such as a word processor or a Tinderbox window.

    When dragging multiple notes to a text receiver, Tinderbox supplies a list of all the note titles.

    When dragging a single note, Tinderbox supplies the styled text of the note if the note's text is not empty. If the note's text is empty, Tinderbox supplies the note title.

    Email from Tinderbox

    The runCommand() action syntax operator allows Tinderbox to access the command line and send email. In most versions of macOS, the user will have to make some adjustments to their system to be able to send email via the command line. As the adjustments vary from OS version to version, the detailed process should be researched in more appropriate fora.

    Export code - default formatting for attribute data types

    When exporting attribute values using ^value()^, intuition may not match output. A String is likely unchanged, but what about a Boolean, or a Date? This note aims to clarify those possible discrepancies.

    Single-value attributes

    • String (and string-based: Action, Color, File, Font, URL). There are no effects here. White space in the source value is retained in the output value.
    • Number. These are exported as seen. This includes numbers that Tinderbox has stored in exponential notation (see here). The Number.format() operator can be useful in setting maximum decimal places or padding characters so all items values export with the same number of characters.
    • Boolean. These export in the form true or false.
    • Date. Dates export in ISO 8601 format (see here), so it is likely a Date.format() transform will be desired.
    • Interval. Intervals are exported as a string, the same as seen when editing an interval's value.

    Multi-value attributes

    • Dictionary, List and Set. These are exported as the literal strings storing the attribute value. Any white space in and between terms is preserved. It is most likely a list .format() transform will need to be applied.

    Export - managing source code white space

    When ^export^ code is evaluated, it inserts the necessary code into the output—or none—as pertinent. In the case of ^if()^ clauses this can lead to blank lines in the output source code as although the unmatched branch emits nothing, the line return after ^endIf^ is still emitted.

    The trick is to place the line return inside the if clause. This is achieved by placing the ^endIf^ on the next line. Originally you might have had this:

    	^value($Name)^
    	^if(ChildCount)^
    	There are ^value($ChildCount)^ children
    	^endIf^
    	^text^

    Which would either emit a blank source line before/after the number of children, or a blank lines if there are no children. To resolve this, use:

    	^value($Name)^
    	^if(ChildCount)^There are ^value($ChildCount)^ children
    	^endIf^^text^

    If using an ^else^ branch apply the same principle, i.e. ensure all line breaks belonging to the result of if clause are inside the if statement:

    	^value($Name)^
    	^if(ChildCount)^There are ^value($ChildCount)^ children
    	^else^There are no children
    	^endIf^^text^

    If source code is indented with tabs or spaces, do not forget the ^endIf^, precedes such indentation rather than coming before the first on-screen output.

    Export - name collision for created files

    When exporting, if two files exported to the same folder location would have the same name, Tinderbox creates a synthetic name to avoid the collision.

    For example, if two notes in the same container are both named "1", the first will be exported as "1.html" and the second as "1_1.html". A third note will be exported as "1_2.html".

    For this reason, Tinderbox will not return a value if testing $HTMLExportFileName, except if it has a value set explicitly. Even in the case of the latter, the stored name value will be modified according to the above rules should a naming collision occur.

    However, a filename can be derived via $HTMLExportPath, which holds the calculated export folder/filename path for the note (read-only). This uses the as-exported folder and file names from export root that would be created if the file were exported at that time. It thus show the names of the folders & file with any characters omitted or substituted as part of the export process.

    This can be extremely useful in more complex export scenarios where there is a need to reference in code an exported note's OS filename or path without being forced to hard-set $HTMLExportFileName. If not set, the latter cannot be queried within Tinderbox.

    To get just the exported filename from the path:

    $MyString = $HTMLExportPath.split("/").at(-1) 

    For this note:

    $Path is: "/A Tinderbox Reference File/Export/Export - name collision for created files"
    $HTMLExportPath is: "/index/Export/Export_-_name_collision_for_created_files.html"

    Note the spaces being lost in the latter. The export version will also show $HTMLExportFileNameSpacer changes, if the latter is set.

    Export - RSS and Atom feeds

    Tinderbox's HTML Export can export all sorts of formats, including Atom and RSS feeds. Indeed, this TBX exports valid Atom and RSS 2.0 feeds. Ideally you should read the format docs for your desired formats as you may wish/need to tweak the templates used by aTbRef to support better you own data needs. The primary references are:

    The format specs can be intimidating for the ordinary person, but hopefully the example templates used by aTbRef should meet most everyday needs.

    In each case the process uses an agent to gather the notes to be referenced in the feed and then exports using an envelope (agent) & letter (agent's child aliases) technique.

    Notes for re-using aTbRefs' method & templates:

    • The feed-generating agent goes at the end of the outline. This is deliberate, so as to ensure all other agents have updated in the last cycle so the query results are as up-to-date as possible. This becomes more important in a document like aTbRefs where there may be agents querying other agents, etc.
    • aTbRef's feed simply looks for descendedFrom("A Tinderbox Reference File")&($Modified=="today").
      • The first query term ensures non-content notes are ignored. This is also why all the content is descended from a single Root-level note, as it makes it easier to keep back-of-house stuff separate in TBXs where you intend to export the data.
      • The second term looks for items changed today. As creating a note sets both $Created and $Modified, the query finds both new and updated notes. Be aware that $Modified only reflects changes to $Text (possibly $Name also). If this is insufficient for your needs, alter the existing query as required.
    • The feed agent should be set to use the 'news_atom' or 'news-rss' template according to the type of feed being generated. You will find the templates needed in the /Templates container of the aTbRef TBX document. Each of these templates is set to call a child template for per-item content (newsitem_atom, newsitem_rss).
    • All text in orange in the aTbRef versions of the template will need to be reviewed and updated as necessary for use elsewhere, e.g. the feed author/title/source URL/etc.

    Export - splitting content and utility notes

    As can be seen by looking at the source TBX of aTbRef, it can be useful to place all 'content' i.e. the data you are working on and wish to export, inside one container. This also makes it easy for that container to form the index page of an HTML export or root element for XML export, etc. Thus "A Tinderbox Reference File" is the index.html file for this website. All notes used in the visible web content are descended from this note.

    So what else might there be outside that? Looking at aTbRef's outline root you will find:

    • /UTILS. A variety of utility agents.
    • /Prototypes. Uses the built-in version which sets the container's $OnAdd to $IsPrototype=true;.
    • /Boilerplate. This holds some code-type notes with sections of code to be included in export templates. This makes the individual templates easier to maintain as boilerplate can be updated once for several different templates. Tinderbox's built-in 'Code' prototype is often used for this type of note as usually it is important that the code's text is not modified by the export process, e.g. inserting HTML paragraph tags, etc., using the prototype saves the user setting lots of attributes to non-default settings in 'code' notes.
    • /Templates. All the export templates needed are stored here: HTML, RSS, etc. Tip, set the container's $OnAdd to $IsTemplate=true;. In aTbRef's case it is $Prototype="_template";, as that sets a prototype for which $IsTemplate is already correctly set.
    • /CSS. All CSS used by the website is exported from the TBX. If needed, the same method can be used for Javascript and the like. Look at HTML view for the CSS container. Note how it does not export but exports its children; also it uses $HTMLExportFileName to change the case (it could be the name) of the exported folder name. View the child's HTML view to see how the CSS filename is constructed. Having this data in a root container means it exports to a sub-folder of the exported web-site. Were the CSS notes nested more deeply in the outline, it would create a nest of folders. Thus having a root level container makes sense, especially if a root level content container is also used.
    • an HTML site map. An HTML nested listing of the entire content outline. Clearly, placing this inside the content section would not be a good fit, and opens issues of unintended recursion, so it lives outside the content.
    • Version checkers. These export small code pages used to allow users who prefer to consume aTbRef in TBX form to check their local document is up to date. See more here and here.
    • Atom and RSS feeds. See more.
    • Zippers. These use command line code to create separate Zip files of the TBX and the exported site's /images folder (all images have always lived outside the TBX). The latter is needed if running out an HTML site locally and without web access. See more here and here.

    Export selected note or notes

    The File menu option to export a selected note also allows a multiple selection:

    • Single or multiple note selection. This method can export each note from a selection of multiple notes. Otherwise behaviour is as for exporting a single selected note, as if this were a succession of individual exports.
    • Embedded images. If a selected note has embedded images these are exported alongside the (HTML) file generated. For each note in the selection the images are exported alongside its source note (i.e. paired images and file, per exported note in the selection).
    • Creation of Destination folder(s). If the destination directory does not yet exist inside the export folder, it will be created. For example, if the exported note is at path /People/Lincoln, a folder "People" will be created inside the export folder if that folder does not already exist, and Lincoln.html will then be created inside this folder.

    To where do notes/images export?

    The export folder for the document is set via the Export Inspector. However, the need to support both internal-only presentation preview and pre-export-preview has introduced some complication, especially for existing Tinderbox users, as is explained further below. The export folder may be set internally (for in-app presentation) or externally (for actual export). The default is an internal location.

    Legacy note: Pre-existing documents with no export folder explicitly set used to default to ~/Desktop will now default to "none", i.e. the new internal location (see next section).

    Therefore the user with older documents needs to be much more careful to check the Export Folder location before export.

    What happens if the OS Export Folder is not defined?

    By default, a new document defaults to using an OS system internal temporary folder for export, so as to allow zero-configuration preview. If single note export is called in this context, the OS chooser dialog will default to the users Documents folder (~/Documents). Note that once a full export has been used in a document, it is likely to have the Export Folder set to an external location.

    Changes from previous single-note export behaviour

    The fact the export can be one or more notes requires a slightly different approach than in older versions, albeit to the same end. An effect of multiple note selection is that the selected notes may not all be in the same container, yet we still wish them to go where they should go in the overall exported website. Thus the only common folder to which to point Tinderbox's export is the root Export folder, such as is used for full document export. From that Tinderbox works out (and creates if necessary) the folders to the notes actual location … for each note in the selection.

    Previously, in older versions, when exporting a note from a document with a previous export folder (and having exported), the export OS chooser dialog opened at the location of the previous file. If the note as new, the OS choose opened to the folder where the note would previously have exported. In other words, on export the user was shown the folder into which the note had/would be exported.

    So the outcome is the same as when only a single selected notes was exported, but done a different way.

    Legacy: notes for long-time users

    What this means for long term users of this feature:

    • Exporting new pages into an existing set of exported pages. Select the TBX's export folder and not the folder where the actual note/file lives. Doing the latter will create the whole outline-derived OS path all over again. At the beginning of a Tinderbox session the default OS folder offered is the main Export Folder and for the new behaviour this is the correct folder to use.
    • Exporting ad hoc items, e.g. data tables, compiled reports. Select the desired OS folder. Again, the session default is the full export folder.
      • Because the export now always writes the in-doc path, it is effectively impossible to export a selected note directly to the folder specified unless the note being exported is at document root (otherwise the outline path is inserted to the OS folder).
    • If using both the above methods in one session, when using the re-export of existing files (case #1 above) ensure the document's Export Folder is set to the OS external root folder for whole-document export.

    Export: 'envelope and letter' technique

    For export of multi-level listings such as section indexes, OPML or full HTML site maps, it is usual to use a pair of templates. The 'Envelope' is the actual full page, in the appropriate export format. This template includes in its body an include call to a second, recursing 'letter' template. A recursing template is one which calls itself. In effect is say "do something and if there are any children include each of them using this template. Thus the children of the original include call their children and so on down to the lowest outline level descendants of every branch of the starting container note. The 'letter' template should be designed so that each included note's output data is a legitimate piece of code within the overall exported page, e.g. in HTML <li> list element or an OPML <outline> item element

    This technique is the mechanism used to provide aTbRef's site map of every page in the exported HTML site. The 'envelope' is created and a 'letter' of however many sheets as needed is placed within. For those with aTbRef's source TBX, the source code for the envelope and letter templates may be viewed.

    Another issue with recursing template export is that a given note can only export itself once, other than as an include. However, it may be desirable to export date in more than one configuration or format. A note's alias shares the same template attributes, although the alias is exported as a discrete copy (into its outline location). Thus an alias, for reasons cited, cannot be used to help in this context. The solution is to anchor the export from another note.

    Again as an example, consider aTbRef's site map. The root note of this TBX is already exported as an HTML page but it is also needed as the seed of the site map page. So, instead, another note is used to export the 'envelope' template. In the case of the site map, the template is used only the one across the site, so in this case the include for the root note is in the envelope template. If the envelope/letter templates were needed for several different exports from the same TBX, the envelope template's include code could be replaced by ^text^ and the include code be moved into the $Text of the note exporting the 'envelope'.

    Although perhaps intimidating at first side to those without any coding experience, the principle is very simple once understood and solves a lot of export-related problems.

    Exporting code samples

    Normally, Tinderbox lets you embed html in your notes, and exports that embedded HTML without change.

    Spans of $Text using the note's 'Code' font (as in $CodeFont) are now exported with <code> tags. The markup applied is determined by $HTMLCodeStart and $HTMLCodeEnd. The Style tab of the Export Inspector lets you edit these.

    Inline code examples

    Sometimes, though, you want to show an example of your HTML (or some other programming language) on a web page. That means you want the HTML tags to appear as you see them in Tinderbox, i.e. you see the character sequence "<b>", not the effect of bolding some text.

    Originally, setting $HTMLQuoteHTML to false let you export HTML examples in an entire note. But, sometimes, you want the example to be handled differently than the rest of the note so $HTMLQuoteHTML is deprecated in favour of the following usages:

    *Tinderbox respects the tags <code> and </code> when they appear within notes. HTML between these tags is always encoded during export so it appears as you see it, instead of being passed unchanged to the browser with the exception that within <code> sections, the opening angle brackets of all tags must be encoded (see section below) in the source text.

    *Tinderbox also respects the tags <pre> and </pre> when they appear within notes. Inside these tags, Tinderbox adds no paragraph formatting and leaves whitespace unchanged; since the intent of the <pre> tag is to allow manual line breaks, adding paragraph markup in this context defeats its purpose. Generally, text inside <pre> is also further enclosed in <code> tags. The <pre> controlling the line breaks and layout, the <code> the use of a monospace font.

    **If combining use of <code> and <pre>, the <pre> tags should go outside the <code> tags, enclosing them. Either way, enclosed code needs all opening angle brackets encoded (see below).

    Setting $HTMLQuoteHTML to true will override this feature, so do not mix the two!

    Opening angle brackets of tags with in <code> and/or <pre> sections

    Although a single left angle bracket < can be typed literally in text, e.g. used as a less than sign, in all other cases it must be entered into the $Text as an encoded entity '&lt;'. So, a < followed immediately by anything other than a space or number character must be entered as '&lt;' or it may be exported incorrectly. For this reason, nearly all of the many < in the source $Text of this article required the character to be HTML-encoded in the $Text so as to render correctly in the exported text.

    Therefore, '&lt;' encoding of a tag opening must be used even inside sections of text enclosed by <code> and/or <pre> tags. Why should this matter inside code samples? Consider these two examples where the sample includes HTML styling tags <b> and </b>:

    • This is some text. → here the < of the bold tags were not encoded and bolding is applied
    • This is <b>some</b> text.→ here the < of the bold tags were encoded as '&lt;' and so the code is seen as intended

    Using the newer $Text 'Code' font option does not remove the need to check < characters inside the code-styled text.

    This requirement to encode < characters opening tags holds not just for HTML code samples but any code where < and > are use to indicate inline tags, eg., XML, OPML, etc.

    Code samples and paragraph spacing

    Note that if you use <code> for a single line sample, you will not emit a wrapping <p> tag as Tinderbox does not emit an 'auto-paragraph' if:

    *The line beings with a < character

    • The line beings with a < character preceded by whitespace (space, tab, etc.)

    So, if you want such a single line code example emitted as a separate paragraph, place an option+space at the end of the line after the </code> tag. Tinderbox will detect this and add the <p> tags Also, if such a line also starts with a tab it will use your TBX's defined indented-paragraph styling.

    Whole note code samples

    Alternatively, you may have a note consisting entirely of code (HTML, XML, etc.) that needs to be exported verbatim, e.g. as is a boilerplate include to a larger exported page. In this case the best approach is to turn off $HTMLMarkupText (i.e. set to false). This should ensure the pages characters are exported untouched. However, characters outside the low ASCII set, such as a • may get transposed to a Unicode-style HTML entity.

    Exporting files and OS case-sensitivity

    Tinderbox happily supports notes with titles varying in case, e.g. "Some Note" vs. "Some note". It also supports case sensitive export in file naming, e.g. "Some Note.html" vs. "Some note.html".

    But, by default, macOS is case-insensitive (i.e. host users' host OS). This creates a problem if Tinderbox exports "Some Note.html" vs. "Some note.html" to the same OS folder. What happens is the filename of second to be exported is coerced to the filename of the case-insensitively matched file and the first-exported file is silently over-written.

    Workarounds (if there is a need to export notes) are:

    • avoid same-name/different case notes in the same Tinderbox container
    • set specific, non-clashing export filenames for one of both/all such notes, e.g. "Some Note1.html" vs. "Some Note2.html".
    • use Mac with the OS set to be case-sensitive. This drastic and not suggested, as it involves re-installing the OS and is thus not a trivial task.

    Export Folder OS Location

    When setting the default folder used for exporting files (primarily 'HTML' export):

    • New documents open with the default export folder not set —the folder button label is empty. On first use of Export, if no folder is set, the user will be invited, via a Chooser dialog, to select a folder. Preview will use this folder for generating any preview files—previewing is essentially doing the same as exporting the viewed note.
    • Older documents will continue to use the previous default of ~/Desktop, unless a user-chosen location has been set.

    The export folder may be changed by either:

    • using the Export inspector's Export Folder button
      • a button in the Export Inspector allows selecting to the temporary folder location (as the OS normally hides this from users), but note this is intended for internal-only previewing (i.e. zero export output)
    • choosing File ▸ Export ▸ HTML and selecting an different export folder.

    If the current choice of export folder is the temporary folder, choosing menu File ▸ Export HTML will invite the user to select a new export folder, rather than defaulting to the (hidden and thus confusing) temporary folder.

    Exporting to the temporary folder is not a useful thing to do, but is a boon when using internal preview/presentation.

    A hidden factor underlying the changes from older behaviour are changes by Apple in internal security required for previewing Web(-type) content. As a result, notes need to be exported before they may be previewed. For a user doing internal preview, exporting files would require clear-up afterwards. By exporting to hidden temporary files, the zero-configuration of internal preview is maintained. Conversely normal file export is able to work as before.

    Exporting Folders

    In some circumstances it is desirable to get Tinderbox to emit a folder but no note when exporting a container; for instance aTbRef's CSS file is in a folder /css/ but there is no 'css.html' note.

    The method to doing this is simple and relates to use of $HTMLDontExport and $HTMLExportChildren, the two tick boxes top left of the HTML views' Export pane.

    To export a folder, un-tick the top box ($HTMLDontExport) and leave the second box ticked ($HTMLExportChildren). As long as there is at least one descendant note that does export, a folder will be created. Indeed, all folders in the path will be created if the only exported note is several outline levels down.

    Folder name. The folder created uses the same name as would be used for the note's exported file ($HTMLExportFileName), without the extension ($HTMLExportExtension).

    In scenarios needing specific folders for content that names can often be ones that are cryptic is used as the container note's $Name. This too need no be a problem. Simply set $HTMLExportFileName, or type in a name into the 'Filename' box in HTML view. The latter will be the exported name, e.g. "refs" whereas the $Name seen on Tinderbox might be "'refs' folder". If doing this in a context where the TBX may be shared with others, consider using a $DisplayExpression to add a warning about not editing. For instance this code:

    $Name+" (DO NOT EDIT/MOVE!)" 

    Thus the user might see a screen caption in Tinderbox like so:

    'refs' folder (DO NOT EDIT/MOVE!)

    Meanwhile the actual exported folder would simply be "refs".

    When using 'folder export' do not delete $HTMLExportExtension. During export this is attribute is not used. However, if deleted (i.e. it has no value) then the child/descendant data is exported as siblings of the exported folder.

    Exporting images

    HTML Export exports images embedded in notes. Note that the images are exported into the same directory as the note's HTML file. Prior to v6, notes were exported to a subdirectory of the note's folder. The exported images are JPG, and take the host page's name. If note 'About' has 2 images, export with create 'About.html' alongside 'About.jpg' and 'About1.jpg'. Note the image numbering is essentially zero-based but the zero is not applied, i.e. if a note only has one image, as it most likely, the image will have/need to number.

    The number of images embedded in a note is stored in $ImageCount. Any note with an $ImageCount of more than zero will have images embedded in its $Text.

    If previewing HTML pages and the document has not been exported, i.e. no export folder is set, and images needed for preview purposes will be generated and placed in the same folder as the TBX. Therefore It is a good idea to set an export folder, at minimum before using HTML preview if using inline images.

    Text images are not exported via text export.

    Picture adornments are not exportable (but are included if copying an image of the whole map).

    Export: loops and joins

    When exporting Tinderbox notes, the final document may be constructed from multiple notes. When the export is in the form of structured data, it is often necessary to place joining code between the output of individual being added to the overall export.

    For example, in JSON data, lists of objects (i.e. per-note-derived data) require a comma between objects. The most obvious approach to do this is to use the export template append the joining character(s) at the end of each note's output. But that results a an extra unwanted (and possible non-format compliant) join after the last note's output.

    So, in such a loop—in an export context—is it possible to test that there is not just another note yet to be export and, importantly, that said note is to be exported? Yes, using ^nextSibling^ (note too its counterpart ^previousSibling^).

    As a general point, and perhaps counter-intuitively, it is better to test at start "am I second or more?" and prepend the join data, rather than test "am I last?" and append it. This is because it is easier to know definitely that a process has started as opposed to if/when it will end.

    Still, export code lack the means for such a test. But an ^if()^ test's query can call a user function, so testing the state of first/last exportable note can be tested via a user function, and the work done in action code where things like contextual export state are more easily worked out.

    See detecting first or last item context in loops and adding joins in loops for discussion of how to do such tests in action code.

    Exporting Set-type data

    Set-type attributes can hold multi-value data, e.g. a set of tags. Some action operators can create sets, most notably the links() operator. Having created a set it can be useful to make it into an HTML list. This is easily done using the format() operator. For instance, if $MySet has values 'cow', 'dog' and 'eel':

    format($MySet"<ul>\n","\t<li>","</li>\n","</ul>\n"); 

    This gives:

    <ul>
    	<li>cow</li>
    	<li>dog</li>
    	<li>eel</li>
    </ul>

    It is more convenient is to use the newer .format() command:

    $MySet.format("<ul>\n","\t<li>","</li>\n","</ul>\n"); 

    If the above were a list of notes' $Name values it is also possible to make the list items into links. This is possible using a two-step process. First the existing set's data is copied to a new set with each value enclosed by link export code:

    $MySetB = $MySet.format("","^linkTo(",")^;",""); 

    The format() operator is then called a second time to make an HTML list using a String attribute $FormattedList to hold the output:

    $FormattedList = $MySetB.format("<ul>\n","\t<li>","</li>\n","</ul>\n"); 

    On export, the ^linkTo()^ codes are expanded:

    <ul>
    	<li><a href="Data/cow.html">cow</a></li>
    	<li><a href="Data/dog.html">dog</a></li>
    	<li><a href="Data/eel.html">eel</a></li>
    </ul>

    The $FormattedList attribute is simply a placeholder to store the fully formatted list ready for use in an export template, thus:

    ^value($FormattedList)^.

    The overall process can be done without needing a second set attribute if link() can be used to make the source set of values. Note the need to use the eval() operator to capture the link() output, on the fly, in Set data form to pass into format():

    $MySet = eval(links(Data).outbound.example.$Name).format("","^linkTo(",")^;",""); 

    The second step remains the same:

    $FormattedList = $MySet.format("<ul>\n","\t<li>","</li>\n","</ul>\n"); 

    Exporting Tabular data as Tab-delim or CSV

    The are three ways to export data tables from Tinderbox without any use of export code:

    • Attribute Browser view. See the File ▸ Export sub-menu
    • Crosstabs view. See the controls for Crosstabs view.
    • Table view. Exports the current selection as CSV (including column head titles):
      • All rows, or none, selected exports the whole table
      • a selection of rows, exports the headers and only the selected rows's data.

    Otherwise, Tinderbox is perfectly capable of exporting data tables in either Tab-delimited (TSV) or Commas Separated (CSV formats) via export templates. Indeed, it is possible to use the same methods to export in formats like JSON It basically boils down to two aspects:

    • Tinderbox data structure allowing export of per-note data as output rows.
    • suitable templates.

    Structure

    The best way to achieve this is to export a container using its chid notes as the source of the data rows. Less usually, descendant notes can be used to provide part of the per-row data. Depending on the nature of the task and the layout of the document, it is possible to use either a standard container note, or an agent to provide the data source.

    Templates

    This process needs two templates. The first, used by the source container, sets the column headings for the table. These headings are generally set as literal strings. Thus for TSV ('[Tab] implies an otherwise invisible tab character, and [Return] a line return):

    Part[Tab]Cost[Tab]Number[Tab]Total[Return] 

    ^children("tsv-item")^ 

    or as CSV:

    "Part","Cost","Number","Total"[Return] 

    ^children("csv-item")^ 

    In either case the template exports a set of 4 literal headers and than includes each of it's children in turn using the same template (which is different to this one)

    For the children, assume the following. The 'Part' is the title of the note (thus, data from $Name). The 'Cost' will be from a user Number-type attribute ($Cost) and will need formatting as a number with two decimal places. The 'Number' will be taken from a user attribute 'Ordered' (so $Ordered). Lastly the line's 'Total' will be calculated as a number with two decimal places and based on the two preceding values.

    First, in TSV form:

    ^value($Name)^[tab]^value($Cost.format(2))^[tab]^value($Ordered)^[tab]^value(($Cost*$Ordered).format(2))^[Return] 

    and in CSV form

    "^value($Name)^","^value($Cost.format(2))^","^value($Ordered)^","^value(($Cost*$Ordered).format(2))^[Return] 

    Export templates are notes

    Export templates are stored as a specialised from of Tinderbox note.

    A note's availability as a template is stored in attribute $IsTemplate. An easy way to set this is via the document's Properties Inspector Prototype sub-tab has a check-box, Template. If this is checked, $IsTemplate is set to true, the note's path appears in the template menu, and the note may be used as an export template. Note that an agent cannot also be a template.

    Template notes appear in selection menus by their complete path. For example, if the template Book Template is a note inside the root-level container named "Templates", it appears in the menu as

    /Templates/Book Template 

    and would be used in code thus:

    ^include("/Templates/Book Template")^ 

    If a note's name (or path/name) is identical to the name of a template file, the note template will be used rather than the file.

    Although a note anywhere in the document can be template (and may be in some long-lived TBXs), currently it is strongly advised to use the default location /Templates. As the latter is not created by default (as not everyone uses/needs export) the easiest way to make this is to use File menu ▸ Templates and select any of the built-in templates. This creates the /Templates folder and other configuration setting (e.g. an OnAdd making all new child notes a template, etc. You can always delete the built-in template used to create the container if not wanted.

    As Tinderbox does not require $Name to be unique, it is possible to have other containers' called 'Templates'. But, if using the default root-level container for storing templates, avoid creating a same-named container that document root. Or, if such a duplicate is needed, ensure the container holding the templates is listed first by outline order ($OutlineOrder). Why? Because when resolving a duplicate $Name or $Path—in action code reference, agent queries/Finds, etc.—Tinderbox always uses the first match by outline order.

    Note templates can be selected from text pane's HTML tab (only if no template has been initially set) or via the Export Inspector's Export tab.

    Template notes (that use the 'HTML' built-in prototype) are configured to use settings like a monospace $TextFont and disabling smart quotes, and more.

    Exported files and changes to file naming

    Relaxing historic constraints on exported file names, t The default replacement character in export file names, $HTMLExportFileNameSpacer, is a space " " character rather than the previous underscore (_) character.

    The default value of $HTMLFileNameMaxLength becomes 100 characters. (Historical note: this is increased from 8 characters in Tinderbox v1.0.0 and 24 characters in v3.0.5.)

    Experiments with supporting more punctuation characters showed that between restrictions for OS filenames, URIs, URLs, web servers, browsers, etc., there is no clear rule for what is punctuation that is safe to use when exporting a Tinderbox note title as a filename. For instance, a colon is allowed in a URL, but not in a macOS filename. Thus, allowing punctuation characters other than a forward slash period and tilde (/.~) are allowed in export filenames proved to cause problems at OS and web level.

    Punctuation—with the exception of "-" (hyphen) and "_" (underscore)—is replaced with $HTMLExportFileNameSpacer. Runs of punctuation characters are reduced to a single occurrence of $HTMLExportFileNameSpacer. If the filename begins or ends with punctuation, the punctuation is ignored.

    Effect of changes on pre-existing Tinderbox documents export

    Note that these changes to attribute default do not affect setting is pre-existing documents, where the new values must be set manually is so desired.

    HTML Entities

    Some source text entities/characters are automatically translated to HTML entities without needing to resort to use of the $HTMLEntities attribute:

    • ellipsis (…)
    • degree (°)
    • French/Swiss style quotes (»Quote« or «Quote»)
    • German style quotation marks („Quote”)
    • mdash (—)
    • English typographic quotation marks “ ” and ‘ ’

    Characters already entered in the text as HTML entities are detected and exported as expected.

    Since version 6 and full support for Unicode UTF-8 in export, the need for using entities has diminished. Indeed, most of the above examples are exported verbatim.

    Tinderbox recognises macros embedded in text. If a paragraph contains only a macro, Tinderbox does not add paragraph mark-up to that paragraph—it assumes that the macro will do this. If you want Tinderbox to add paragraph mark-up, just add some space characters before or after the macro.

    Tinderbox recognises any paragraph that contains only export code expressions (notably ^include(…)^ and ^children(…)^ ). Tinderbox will not add paragraph mark-up to the result of such code. Again, adding space characters before or after the mark-up will cause Tinderbox to add paragraph mark-up. If an export code is on a line of its own before the end of the note, do ensure you add closing ^ or the output HTML may not be as you suspect.

    Tinderbox ships with specimen templates stored internally within the application package (see built-in export templates). This means you can add a few basic templates in a new TBX to see how code work, without writing your own.

    HTML Export & Unicode non-UTF-8 characters

    If $HTMLEntities is true, non-UTF-8 characters are encoded as numeric HTML entities (e.g. © as '&#169;'). If $HTMLEntities is false, non-UTF-8 characters are exported as UTF-8 characters.

    HTML Export - exporting folders

    Sometimes it may be necessary to export content in sub-folders. For example, CSS files might go in a /css folder. In such cases, place the files in container off the root (or nest as many 'dummy' containers as needed).

    Source container has no $Text

    If the container has no $Text content, then a folder is exported with a name based on $Name and containing any exportable child notes.

    A different folder name from $Name

    What if the container name is not correct? It may be the case is wrong or the necessary folder name needs to differ from the source container. If so, set $HTMLExportFileName to the appropriate name using the case desired.

    $Text present but no export desired

    What is there is text in the container note but it is not to be exported, e.g. because it is instructions about what lives in the container? In this case set $HTMLDontExport to true or open the container's HTML view and un-tick the top left box. $HTMLDontExport is a little confusing as the value is the opposite of the HTML view tick-box, i.e. ticked equates to false, this is the reverse of the way most booleans work.

    Do not edit the export extension!

    Regardless of the above, even if the container is exported only as a folder do not be tempted delete the export extension ($HTMLExportExtension) or you get an unexpected result: the folder is created but child notes are created as its siblings. There is an arcane reason for this logic, but remember, TB wants a file extension for a container even if it is only ever exported as a folder.

    Containers children are only boilerplate/includes

    A reverse scenario occurs where you want to use notes in a container but not have the notes or the container export, such as when the child notes are only ever used as includes in other exported files. In this case, open the HTML View of the container and un-tick the first two boxed top left, for 'Export' and 'Export Children' (setting $HTMLDontExport and $HTMLExportChildren respectively). Meanwhile, ensure the child notes (i.e. the include(d) content), have their 'Export' box ticked in HTML view. This is slightly counter-intuitive at first meeting, but to be exported as an include, the source of the include content must be an exportable note. By placing the note in a parent container that is set to not export its children, the correct conditions are met.

    HTML Export - page(s) based on multiple notes

    There are some additional considerations if exporting a page derived from multiple notes:

    Where source pages also export as discrete pages

    Linkage issues. To do.

    Planning a many-note-to-single HTML page

    To do!

    Setting in-page HTML anchors

    W3C syntax rules for the destinations of in-page jump links are thus:

    HTML tag id and name tokens must begin with a letter ([A-Za-z]) and may be followed by any number of letters, digits ([0-9]), hyphens ("-"), underscores ("_"), colons (":"), and periods ("."). [W3C source reference]

    This means that the most obvious built-in solution for a unique ID for an object, that of using $ID, is not valid as it is all digits. Likely most browsers will cope, but it is building on sand.

    Another possible source is a user attribute of the Number type using the 'sequential' option, though note such attributes are not intrinsic.

    If using either of the above, a simple workaround is to simply put a letter prefix before the numerical value. For instance:

    id="x^value($ID)^" 

    A separate design issue is to ensure the calling link is able to use the desired destination anchor value. As the user has no control over links generated via ^text^, it can mean explicitly setting the $HTMLExportFileName for all notes so as to seed the href path of calling links so these can be post-processed to the desired version.

    Considerations for aliases

    Be aware that aliases can have their own basic links (inbound and outbound), and export into their equivalent outline location. Aliases always share text links (i.e. those from $Text) with their original.

    Traversing non-exporting notes

    Occasionally it may be needed to access data from descendant notes that are descended via notes that do not export. The latter might exist only as internal structuring of the internal document outline. Consider this layout:

    2015 Articles
         January
              Article A
              Article B
         February
              Article C
              Article D

    You might want the 2015 articles pages to list all articles with month heading but do not need any per-month pages. Thus the root note might export:

    Traversing non-exporting notes
    

    The latter template might have code like:

    Traversing non-exporting notes
    

    As per-month pages are not needed, it might seem logical to set $HTMLDontExport to true for the month containers. However, that means the 'month' template above is never evaluated and so the main note is missing some data. Conversely, leaving the export on generates unwanted pages for the month container notes

    The secret here is to let the per-month container notes still export but to use a blank template, i.e. template with no code or even HTML comments, i.e. no $Text at all. As Tinderbox will not generate an empty file, no HTML exported file is emitted during export but the above templates can still work.

    This scenario is an edge case that shows the flexibility offered by Tinderbox's export methods.

    HTML Export - points to consider

    If you regularly export a changing TBX to HTML (or other formats) there are some pointers to bear in mind:

    • If you change export template code but a note using it is unchanged, the note will not be re-exported. When exporting HTML files, Tinderbox compares the contents of any existing file with the source it is about to export. If both match no export occurs. This means Tinderbox checks for changes in any attribute being exported (not just $Text) and in the template code, e.g. where the note is unchanged but the template has been modified or swapped for a different one. Changes occurring in includes will be detected.
    • If a note's exported filename changes (e.g. as a result of a change of note tile) the newly exported file does not result in the previous, differently-named file, being deleted. You will need to tidy up the old files in Finder. If hierarchical links are used consider the link from the parent as well as immediate siblings when working out the files affected. Roadmap view helpfully indicates incoming links allowing you to asses files elsewhere in the export that might be affected.
    • Also consider the effects of $HTMLDontExport and $HTMLExportChildren; special attention is needed for notes only ever used as includes.
    • The degree to which Tinderbox encodes or 'entifies' characters in the text is controlled by three primary attributes: $HTMLEntities, $HTMLMarkupText and $HTMLQuoteHTML.
    • Consider the effects of Tinderbox quick lists, font size auto-headings, etc. See more

    *If you change all or a significant number of notes' export template(s) it is advisable to do a full export, especially if the changes alter how navigational links set up.

    • Notes with no $Text, or if $Text contains only whitespace, are considered empty and no exported file is generated, even if the note is set to export.

    It is thus often a good idea to trash an existing exported set of pages before doing a full export. The export process is pretty speedy so, especially if on a local or LAN location, the loss of pages is very short-lived. If the final location is online, it can be useful to do a local export and then use FTP synching to update the online version to reflect the new output.

    When exporting a single page via HTML view, also consider:

    • If exporting a page that has includes, only the 'host' note's data is updated to the latest change. It is necessary to explicitly click the 'Update' button to re-compile included content from other notes.
    • If exporting a single note whose exported filename has changed, see bullet point 2 above.
    • If exporting a single note with exportable aliases, the aliases are not exported. A full HTML export is required to achieve this.
    • an alias' HTML view exports the alias to the alias' context, including appropriate basic links and template related previous/next HTML links.

    Tinderbox will export embedded images (suspended since v5, but intended to return). These are exported as JPG or PNG (set via HTML Preferences, 'Link images as'), using the host note's exported filename. If more than one image is in the note, the second image uses the filename suffix '-1' (before the extension), image #3 uses the suffix' '-2', etc. The images export to the same folder as the host note. If the host note is an include, the images are placed in the including note's exported folder but the image filenames are unchanged. See also.

    If the document uses a lot of images it can be useful to store them outside the TBX and link to them via the export template (or possibly) inline code). This can help reduce TBX file size and allow for better quality web images. Do bear in mind that if images are stored externally they cannot be seen directly in Tinderbox, though they could be added as file attribute links (harder to do if there is more than one image per note).

    All attribute values allow for non-ASCII Unicode characters.

    Aliases

    Aliases export as separate files in their own outline-based place in the overall export. As such, they use their own basic links (in/out) and their original's text links (as $Text is the same). If an alias has no outbound basic links, it uses those of its original.

    Aliases can be exported via HTML view, as with full HTML export, the aliases location/links are reflected in the output page.

    Whilst aliases within Tinderbox cannot have children, aliases assume their original's children during export either for inclusion or separate export at the alias' location. (in effect as implied aliases themselves). This can affect recursing templates as output from an agent's aliases may recurse the original's descendants. In such conditions, it may be necessary to ad an alias detection argument. Originally a template might have the condition:

    ^if($ChildCount)^… 

    But, it may (depending on the user's intent) need to be altered to:

    ^if(!$IsAlias & $ChildCount)^

    The new clause ensures the inclusion of child notes (and, if recursing, thus all descendants) does not occur if the current item is an alias.

    HTML Export - exporting only as an include

    It may be that a TBX has notes that need to be exported but whose content is only ever used as an include to another note. How to stop the source note being exported as a note in its own right (and creating a containing folder, etc.)?

    To achieve this, the note needs to be inside a container, i.e. not at root level. The container should be set to not export its children. So, do either of:

    • Set $HTMLExportChildren to false 
    • On the HTML view, un-tick the second box in the top left corner.

    If the include note's container is literally that, i.e. it exists simply to hold the includes, then set the container not to export by doing either of:

    • Set $HTMLDontExport to true 
    • On the HTML view, un-tick the top box in the top left corner.

    As a side issue, do remember that any Tinderbox links going into an included note are not exported.

    HTML Export: ^^value^^ vs. ^^get^^

    Since v4 guidance is to shift to export attribute values using ^value($Attribute)^ rather than ^get(Attribute)^ and ^value($Attribute(Some note))^ rather than ^getFor(Some note, Attribute)^. The previous ^get^ and ^getFor^ are deprecated.

    Do be aware that to get the expected value in the exported data some attribute data types, especially Date and Color require the attribute value to be enclosed in a format call:

    ^value($AccentColor)^: dark warm gray dark
    ^value($AccentColor.format())^: #403a35
    ^value($Created,"*")^: 2010-01-06T09:46:17+01:00
    ^value($Created.format("*"))^: Wed, 6 Jan 2010 09:46:17 +0100

    An added advantage of the ^value^ method is that the exported value is an evaluated action code expression so it is possible to manipulate attribute data. If $MyNumber is 5:

    ^value($MyNumber)^: 5
    ^value($MyNumber*3)^: 15

    Note that the evaluated result is only seen in the exported code; the source attribute(s) are not affected.

    Compared to old methods like ^text^ and ^title^, ^value^ does not evaluate any inline ^ export code in $Text or $Name; for instance macros, linkTo and include codes. In such context, trying ^value(eval($Text))^ does not help as eval() evaluates action code rather than export code.

    Referencing a template's attributes. Unlike all other notes, in an export template (i.e. $IsTemplate is true), referencing an attribute refers to the note being processed and not the template. To refer to the template is its path or name, thus $AttrName(template-name) not $AttrName.

    HTML Export - alternate mark-up processor

    Specifying the path to an HTML mark-up processor in $HTMLPreviewCommand results in the ^text^ command (only) being processed for HTML mark-up using the alternate processor. This allows the user to choose a Markdown or any other markup processor. The output is used both in the text Preview pane and HTML export.

    A simple example is to specify the path to an installation of Markdown. This then allows Markdown-Style mark-up to be used in $Text and interpreted as such during evaluation of ^text^ for HTML export. Whereas normally italic text in $Text would be exported as <i>italic text</i>, a Markdown user would use '_italic text_' in their $Text instead.

    See Markdown preview rendering for available values for $HTMLPreviewCommand.

    If not empty, ^text^ passes the unprocessed text of the note to the script in $HTMLPreviewCommand instead of processing the text itself.

    The 'Markdown' built-in prototype, presets notes to use Tinderbox's built-in copy of the Markdown script for easy configuration. More expert users may chose to edit this to point to their own copies of Markdown, or other such scripts.

    Moving Stamps

    Stamps may be moved between documents by dragging them out of the Stamps tab of the Document Inspector and dropping them into the new document's view pane. If the document receiving the stamp already has a stamp of the same name, the drag will be ignored. If the stamp refers to user attributes not present in the new document, actions involving those attributes will have no effect.

    Stamps may also be dragged from the inspector list to the Finder, where they become files with the extension .tbxstamp. Dragging a .tbxstamp to a new Tinderbox document's view pane will add that stamp to the document, provided that a stamp does not already have that name.

    OPML Export

    Tinderbox content can be exported in OPML using appropriate templates, taking care to encode for XML standards and to encode paragraph breaks in $Text.

    Zero-configuration OPML Export

    Use File menu ▸ Export ▸ as Text and on the resulting dialog select the OPML option, offering a choice of scope. If not already present in the document, using this export for the first time will add the necessary built-in templates (and their required prototypes) to the document. If document scope is selected, root level back-of-house containers such as Prototypes will not be exported as per their default settings.

    IMPORTANT: be aware that many apps offering OPML input/output use customised variants of the main standard. Thus it is simply not safe to assume that OPML will 'just work' in all cases. It may be necessary make adjustments to the OPML templates to generate OPML output that reflects the (usually undocumented) non-standard OPML aspects of some apps expected OPML input.

    See also OPML Import.

    Zero-configuration Scrivener (OPML) Export

    To assist Scrivener users not confident with export, a similar methods as above is offered. At the Export as Text dialog, select 'Scrivener' and set the scope. As above Template and Prototypes are added as needed.

    OPML standard and variations

    The formal OPML (v2.0) standard is still quite loose allowing for variations. The following is a list of mappings of TB attributes to standard and common non-standard OPML attributes (non-standard tags in italics):

    • $Name → text
    • $Text → _note
    • $Checked → _status

    Note that the OPML <expansionState> element is not supported. Tinderbox's outline branch expand/collapse state is not accessible as an attribute to populate this OPML tag. However, for data validation's sake, do include the empty tag (<expansionState>) in any export templates.

    Dates in OPML. If the user wishes to use the optional 'created' OPML attribute, then RFC 822 formatted dates should be used. For example:

    created="^value($Created.format("*"))^" 

    outputs (on aTbRef's author's system)

    created="Wed, 13 Jan 2010 08:58:47 +0100" 

    For considerations relating to import, see OPML Import.

    OPML Templates

    Tinderbox supplies built-in OPML templates that can be added to a document from the File menu. In addition, the following code operators are provided to assist with OPML export:

    A pair of wrapper/item templates, similar to those below, were added to the built-in templates. Scrivener users get similar (OPML-based) template for export for ingest Scrivener.

    Below are specimen templates for OPML export. Use the 'OPML-wrapper' template with a container note containing all the top level note(s) forming the actual OPML items. The 'OPML-wrapper' calls the 'OPML-item' template which then recursively calls itself to build out the OPML outline:

    Scrivener OPML

    The build-in templates for Scrivener are actually exactly the same as those for OPML. The duplication reflects the fact that many Scrivener users may not be well versed on the 'code' aspect of export.

    Setting the correct file type on export

    If exporting OPML, the $HTMLExportExtension should be set to '.opml'. If using the built-in templates, this is done automatically via this code:

    ^action($HTMLExportExtension=".opml")^ 

    If the same note/container is normally used for HTML export, consider removing the above code and setting the extension manually on save. Or make a note for OPML export but which uses an ^include()^ call to export the content whose default export is HTML.

    OPML-wrapper

    Template code. Line layout is to create correct OPML source layout. Note that you may need to adjust the name/location of the OPML-item template where it is referred to in the code; the default assumes a root/level container called 'TEMPLATES'. The ^action()^ code run in the template ensures offered filename for saving the generated data has the necessary '.opml' extension. Copy/paste code in the monospaced font:

    <?xml version="1.0" encoding="UTF-8"?>
    ^action($HTMLExportExtension=".opml")^
    <opml version="1.0">
    <head>
    <title>^value(attributeEncode($Name))^</title>
    <expansionState>0</expansionState>
    </head>
    <body>
    ^children("OPML-item")^
    </body>
    </opml>

    OPML-item

    Template code. Line layout is to create correct OPML source layout. Note that you may need to adjust the name/location of the OPML-item template where it is referred to in the code; the default assumes a root/level container called 'TEMPLATES'. Copy/paste code in monospaced font:

    [code starts]

    ^if($ChildCount)^^indent("\t",$OutlineDepth(parent)-1)^<outline^if($Text)^ text="^value(attributeEncode($Name))^" _note="^value(attributeEncode($Text))^"^else^ text="^value(attributeEncode($Name))^"^endIf^^if($Checked)^ _status="^value(attributeEncode($Checked))^"^endIf^>
    ^children("OPML-item")^^indent("\t",$OutlineDepth(parent)-1)^
    ^else^^indent("\t",$OutlineDepth(parent)-1)^<outline^if($Text)^ text="^value(attributeEncode($Name))^" _note="^value(attributeEncode($Text))^"^else^ text="^value(attributeEncode($Name))^"^endIf^^if($Checked)^ _status="^value(attributeEncode($Checked))^"^endIf^ />
    ^endIf^ 
    

    [code ends: ensure to copy the line return after the last ^endIf^].

    This version does not export $Checked:

    ^if($ChildCount)^^indent("\t",$OutlineDepth(parent)-1)^<outline^if($Text)^ text="^value(attributeEncode($Name))^" _note="^value(attributeEncode($Text))^"^else^ text="^value(attributeEncode($Name))^"^endIf^>
    ^children("OPML-item")^^indent("\t",$OutlineDepth(parent)-1)^
    ^else^^indent("\t",$OutlineDepth(parent)-1)^<outline^if($Text)^ text="^value(attributeEncode($Name))^" _note="^value(attributeEncode($Text))^"^else^ text="^value(attributeEncode($Name))^"^endIf^ />
    ^endIf^ 
    

    Outline Export

    The Export ▸ Outline option exports the whole document's note titles to a plain text document.

    The title string used is $DisplayName (or $Name if no Display Expression is set). Attributes controlling export are honoured ($HTMLDontExport, $HTMLExportChildren) allowing non-content notes and containers like prototypes to be excluded from export.

    The resulting text file has the (display) title of each exporting note indented one tab stop per outline depth level, actually $OutlineDepth-1 tab stops. Thus root level notes are not indented, their children are indented one tab, etc.

    Printing from Tinderbox

    Printing from the text pane when multiple notes are selected is temporarily disabled. Print notes one at a time or export the selected notes to a single document and then print that.

    Stored Web Export

    From v11.8.0, Tinderbox files are now saved with additional text information for the used of the experimental Tinderbox Web Reader. File sizes will increase noticeably, perhaps ~25%. It is likely that some or all of the additional space will eventually be reclaimed. Document saving may appear slower; this also will improve presently.

    Styled text export

    Styled text $Text can be exported from the File ▸ Export sub-menu. Further options are set via the Export as Text panel. Styled text export supports inline use (i.e. in $Text) of a limited range of export codes. When exporting plain or styled text, Tinderbox interprets several export markup elements.

    • ^include(item)^ is replaced by the styled text of the designated note.
    • ^value(expression)^ is replaced by the value of tht action code expression, though most often that is simply citing an attribute reference. For example, ^value($WordCount)^ will be replaced with the value of the word count of the exported note.
    • ^if(expression)^text^endIf^ and ^if(expression)^text^else^text^endIf^ permit conditional export. The text between the if and endIf or the if and else codes will be exported only if the query expression is true, otherwise the text between the (optional) else and endIf codes is exported.

    Support for other app-specific formats

    See here.

    Tabs, Quick Lists, Fonts and Export

    Normal paragraph markup is taken from $HTMLParagraphStart and $HTMLParagraphEnd.

    However, for the first paragraph, $HTMLFirstParagraphStart and $HTMLFirstParagraphEnd are used. The defaults may be set to the same as above but the mechanism allows for different first paragraph styling. For instance, a house writing style might be to indent all paragraphs save the one after a heading, and so on.

    Any paragraph indented with a tab is exported using $HTMLIndentedParagraphStart and $HTMLIndentedParagraphEnd.

    The default value for $HTMLIndentedParagraphStart is <code><blockquote></code>.

    Quick lists. Adding markers at the start of a paragraph automatically trigger HTML lists (see more detail):

    *An asterisk (*) or bullet (•) results in the paragraph exporting a <code>&lt;ul></code> bulleted list. Each successive paragraph with the same starting character is another list item in the same list.

    *A hash symbol (#) results in the paragraph exporting an <code><ol></code> numbered list. Each successive paragraph with the same starting character is another list item in the same list.

    Auto-headings. Increases in body text size of whole paragraphs causes ^text^ to export those paragraphs as headings. Thus:

    • 2-3 points larger is exported to HTML as <code><h3></code>
    • 4-5 points gives <code><h2></code>
    • 6 or more points above body copy is exported as <code><h1></code>

    Generally this is a useful enhancement but it can be problematic if the text size has been enlarged only for clarity within Tinderbox itself. If the intent is for all text in a note to be the same size, but just bigger than the norm, e.g. in a 'readme' note, set the $TextFontSize for the note to the same as the display size in the note window. As the text is now the base size (for that note) auto-headings are not invoked during HTML export.

    Controlling auto-markup. All these automatic features are controlled via $HTMLMarkupText with ^text^ used to export $Text. If instead ^value($Text)^ or ^text(plain)^ are used to export $Text, the above effects are by-passed but there is no automatically generated HTML. In the latter case, the user would have to manually insert any desired HTML mark-up, e.g. paragraph tags, directly into the $Text.

    Text styling that does not export

    Since Tinderbox's move to supporting a fuller RTF feature set, a number of styling enhancements were added that cannot be automatically exported via either type of export:

    *Text highlighting.

    *Superscript

    *Subscript

    Other general text styling can be HTML exported at per-note scope using CSS. However, changes to the following within a single $Text would require placing actual HTML markup (e.g. span elements) in source $Text:

    *Text colour.

    *Fonts.

    *Font size. There is limited support for marking paragraphs in $Text as heading levels based on variation form the note's current $TextFontSize.

    *Paragraph indentation (e.g. insert paragraphs). Partial support via $HTMLParagraphStart & End, but note that fully indented paragraphs receive no such special markup (slightly confusing).

    See also Quick Lists.

    Tinderbox metadata in pasted Tinderbox data

    Developer addition. RTF and RTFD flavours added to the com.eastgate.tinderbox.metadata pasteboard flavour.

    For Developers: when one or more notes are copied to the pasteboard, Tinderbox adds a new flavour com.eastgate.tinderbox.metadata for the convenience of other applications. The new flavour is a list of dictionaries, one for each selected note, which may have the following keys:

    • Name: the note's $DisplayName (NSString)
    • Tags: an array of NSStrings, possibly empty, containing the NSString values of each element of the note's $Tags attribute
    • Created: the note's creation date $Created (NSDate)
    • Text: the note's text $Text in plain-text form(NSString)
    • RTF: the note's styled text RTF data, if available; this key may be absent if styled text is not available (NSData)
    • RTFD: the note's styled text RTFD data , if available; this key may be absent if styled text is not available (NSData)

    Tinderbox Web Reader

    From, v11.8.0, this new feature is under test at the moment but it not yet available for general use. Documentation awaits completion of testing and a stable feature set

    UTF-8 Export

    HTML Export generates files in UTF-8 format using Unix-style line endings (line feed character, '\n'). The data excludes a BOM (Byte Order Marker). Although using a BOM is supposedly the correct standards-based approach few apps have adopted it correctly resulting in some processes mishandling the file.

    HTML export can export all manner of mark-up (HTML, MMD, XML, JSON, etc.) but for actual HTML it is advisable to add the following for the section of the exported page's source:

    <meta http-equiv="content-type" content="text/html; charset=utf-8"> 

    That meta element makes it even easier for ensure a web browser to understand unambiguously the encoding to expect within web page it is opening.

    Working with LaTeX

    Tinderbox can export, via custom templates and HTML Export, data that includes LaTeX mark-up. The limitations discussed below reflect the fact that alternate mark-up types are a by-product of the export design rather than a deliberate feature. Tinderbox does not claim, as a standard feature, to export LaTeX.

    Obtaining LaTeX output involves consideration of the template used and per-note attribute values:

    *Template. This tells Tinderbox what data from the current note (or other transcluded notes) to place into the exported file. It is thus a good place to put LaTeX code such as that needed to mark the beginning or end of a file. Exactly what then gets output from ^title^ and ^text^, etc., is controlled at note level.

    *Note-level attributes. By default, when exporting marked-up data, HTML is the presumed mark-up type. To use an alternate mark-up, many note-level system attributes from the HTML group need customisation, as listed below, to generate LaTeX output. It is important to note that not all HTML export features can be customised for LaTeX use.

    Given the number of attributes that may require customisation, it may prove useful to employ prototypes to set up for this process. Thus, just as HTML and LaTeX export templates can be swapped over with ease, so too can LaTeX mark-up customisations be swapped by setting a prototype and letting the customisations inherit to the note(s).

    Tinderbox's ^text^ export operator can manage the following $Text features as LaTeX mark-up

    • bold
    • italic
    • underline
    • strikethrough
    • paragraphs (all except 'first paragraph', as explained below)
    • indented paragraph (blockquote)
    • lists: unordered (bulleted) and ordered (numbered) quicklists

    But, do be aware that some $Text features are not suitable for LaTeX export. This is because the user does not have full control of the mark-up generation for some features:

    • links, both internal and web links
    • font size ▸ heading mapping (you cannot control this even for HTML)
    • inline images.
    • other styled text styling such as inline font changes, text colour, highlighting, sub/superscript are completely ignored for HTML/formatted mark-up export purposes.
    • Tinderbox footnotes

    Do not be tempted to turn off $HTMLMarkup as that then disables all $Text mark-up generation.

    ^text^ auto-markup you can re-set for LaTeX use

    LaTeX coding for Underline & Strikethrough require presence of the non-default 'ulem' package and header declaration: \usepackage[normalem]{ulem}. If planning to export underlined or struck-through text, remember to add this declaration in your template(s). Further detail is beyond the scope of aTbRef and should be research in LaTeX documentation.

    As the changes below are set in attributes, these need only be altered only for those notes exporting to LaTeX thus allowing it to mix with default HTML export (or other export formats). If the same note may need to export to different format depending on need, it would make sense to set the attribute customisations and switch in the LaTeX values by setting the exporting note(s) to use the prototype and thus inherit its customisations.

    Edit the following HTML export attributes, noting that:

    • the quotes are not part of the code value
    • \n indicates an actual line return is needed in the value
    • "} " values must include a space after the closing brace
    • "\begin{..." and "\end{..." need a literal line break both before and after the actual code, i.e. the command needs to be on a line of its own

    Text Styles

    $HTMLBoldStart: "\textbf{"

    $HTMLBoldEnd: "} "

    $HTMLItalicStart: "\textit{"

    $HTMLItalicEnd: "} "

    $HTMLUnderlineStart: "\uline{"

    $HTMLUnderlineEnd: "} "

    $HTMLStrikeStart: "\sout{"

    $HTMLStrikeEnd: "} "

    $HTMLSubscriptStart: "\textsubscript{"

    $HTMLSubscriptEnd: "} "

    $HTMLSuperscriptStart: "\textsuperscript{"

    $HTMLSuperscriptEnd: "} "

    $HTMLCodeStart: "\texttt{"

    $HTMLCodeEnd: "} "

    Lists

    $HTMLIndentedParagraphStart: "\n\begin{quote}\n"

    $HTMLIndentedParagraphEnd: "\n\end{quote}\n"

    $HTMLListStart: "\begin{itemize} "

    $HTMLListEnd: "\end{itemize} "

    $HTMLOrderedListStart: "\n\begin{enumerate}\n

    $HTMLOrderedListEnd: "\n\end{enumerate}n\ "

    $HTMLListItemStart: "\item "

    $HTMLListItemEnd: " "

    $HTMLOrderedListItemStart: "\item "

    $HTMLOrderedListItemEnd: " "

    Paragraphs

    Paragraph initial indenting, and first-vs.-subsequent differences is handled in general LaTeX setup (i.e. in the in-LaTeX template) so no paragraph start tag is needed. So set the following to no value: $HTMLParagraphStart, $HTMLFirstParagraphStart, and $HTMLIndentedParagraphStart.

    A paragraph is indicated by one (or more) blank lines. However, $Text should use normal paragraphs and $HTMLParagraphEnd, $HTMLFirstParagraphEnd, and $HTMLIndentedParagraphEnd and should use a literal line break character as the closing tag. Do not use a literal string "\n", but copy the line return from some $Text and paste this invisibly character into the appropriate input boxes.

    Images

    Including images should be done via LaTeX codes in the text and not via Tinderbox's HTML export as images inclusion is not as simple as a single LaTeX code Therefore set both the following to no value (remove any existing value): $HTMLImageStart, $HTMLImageEnd.

    Tag clouds

    The text size chosen is left to the user but these are suggested values:

    $HTMLCloud1Start: "{\scriptsize"

    $HTMLCloud1End: "} "

    $HTMLCloud2Start: "{\normal"

    $HTMLCloud2End: "} "

    $HTMLCloud3Start: "{\Large"

    $HTMLCloud3End: "} "

    $HTMLCloud4Start: "{\huge"

    $HTMLCloud4End: "} "

    $HTMLCloud5Start: "{\Huge"

    $HTMLCloud5End: "} "

    Other HTML group attributes

    Any other attributes containing HTML code should be set to an empty string.

    $HTMLEntities: false (un-ticked) - this ensures no further HTML is generated, as it with confuse the LaTeX parser. It will also suppress HTML links for both internal and web links.

    $HTMLExportExtension: might best be set to ".tex"

    Footnotes

    LaTeX footnotes use a \footnote{} code in the $Text position of the footnote marker, with the footnote content within the braces. An ^include()^ call could be used to insert the text of Tinderbox footnote notes.

    Citations

    Citation anchors (BibTeX citekeys) can be inserted inline in $Text as \cite{citekeyValue}. For LaTeX use pre-supposes an associated Reference Manager app will generate the BibTeX citekey for insertion in the $Text. The Reference Manager app also generates the '.bib' bibliography file needed for LaTeX-render citekey → citation formatting and creating the styled bibliography in the LaTeX output document.

    Minimum Viable Document (from a single note)

    At the beginning of $Text add:

    \documentclass{article}
    \usepackage{ulem} % used for strikethrough 
    \begin{document}

    ... text content, then

    \end{document}

    Minimum Viable Tinderbox Template

    \documentclass{article}
    \usepackage{ulem} % used for strikethrough 
    \begin{document}
    ^text(Working with LaTeX,ai-source-item):: text tries to include itself 
    \end{document}

    Use of AI

    Tinderbox can currently use AI in two ways:

    Apple Intelligence

    Note: this feature requires macOS v.15.1.

    Apple introduced 'Apple Intelligence'—essentially AI built into the OS—gradually with macOS 15 (Sequoia). From macOS 15.3+ Apple AI is on (enabled) by default. Although further features will emerge, macOS 15.1 is considered the baseline OS for this feature. In addition, the feature requires an Apple Silicon ('M') CPU chip as opposed to the prior Intel CPU.

    As Tinderbox is built off Apple frameworks, this means some Apple Intelligence features may work within Tinderbox: there is no exact list as yet.

    Description of the functioning of Apple Intelligence is outside the scope of aTbRef. Overall control of Apple Intelligence (dis-/enabling it) is found in macOS System Settings ▸ Apple Intelligence & Siri, Apple Intelligence control. That preference tab also has a link to macOS Help articles on the subject.

    Some Tinderbox features build upon Apple AI:

    Natural Language Processing

    Note: this feature requires macOS v.15.1.

    The text ($Text) of notes is scanned to extract information that might be useful for agents. These results include:

    • $NLNames: a set of personal names found in the text.
    • $NLOrganizations: a set of the names of organisations found in the text.
    • $NLPlaces: a set of place names found in the text.
    • $NLTags: a set to hold annotations automatically generated using Natural Language Processing. The first such annotation adds the tag 'plan' to notes that Tinderbox believes might represent a planning note, such as "remember to deposit the cheque" or "remind the freshers to begin planning their module essays". At present this process is not enabled.
    • $DominantLanguage: Tinderbox's guess at the primary language used in the text of each note; stored as two-letter ISO-639-1 codes such as “en” for English, “de” for German, and “zh” for Chinese.

    Note that these result values are extracted automatically and are thus subject to a variety of extraction errors.

    Results are extracted from the $Text of:

    • New notes.
    • Re-edited notes, including pre-existing notes in old TBXs that have be re-edited.

    Values are not extracted from pre-existing notes, such as in files created, unless they are subsequently re-edited.

    This process may store some working files in the application support 'analytics' folder. Such files should not be edited by users.

    Taggers

    This container within Hints holds notes that provide hints to Tinderbox's AI to help tag notes.

    /Hints/Taggers 

    The name of each built-in note within the Taggers container corresponds to a Set-type attribute. See below for the additional set-up needed for user-created tagger notes.

    Taggers, tags, and terms

    A tagger note defines one or more 'tag' items that the tagger will add to/remove from the associated attribute.

    Each 'tag' is defined by one of more 'term' items. At simplest a tag can be self defined as the tag name. The detail of the syntax for defining tags and terms is addressed further below.

    For information about use of multiword tags and terms see detail under Tagger file syntax.

    Scope of Analysis

    A tagger looks at the content of a notes title ($Name) and text ($Text). Thus, it is important to understand that tag detection occurs only in the $Text and $Name of a note and not in any other attribute.

    Built-in Taggers

    There are the tagger notes added by default when the 'Hints' container is first added to the document. These tagger notes, all use 'NL' name prefixes, and have system attributes already in the document.

    Three of built-in taggers, NLPlaces, NLNames, and NLOrganizations use underlying Apple NLP (see more on Natural Language Processing) features to match terms. Thus, for NLPlaces, Apple NLP is leveraged to detect any $Text content that appears—to the NLP algorithm—to be a location or place-name (indeed, exactly what those are is undefined), placing that term in the note's $NLPlaces attribute. As a result there is no tell-back as to why a term is auto-populated to the associated attribute.

    Although 'NLTags' has an associated system attribute, it does not use any NLP and is essentially a quick stubs for using user-created tags without undue extra set-up. For this and user-defined taggers, the relationship is more simple. A tag addition/removal is linked to a case-insensitive match to any term defined for a tag.

    Detection is dynamic: a match to a term in a note's $Text or $Name adds the relevant term to associated attribute for that tagger, removal (of all instances) of the term from $Text or $Name removes the tag from the associated attribute.

    Attributes used by taggers

    A tagger works with an associated Set-type attribute. Once assigned a tagger, Tinderbox makes the note read-only and this cannot be undone—manually or automatically—short of editing the raw XML of a document. The reason the attribute is marked as read-only is to ensure only the tagger may add or delete values in the course of its work.

    As well as adding a tag if a term is matched, if a tagger formerly applied a tag but source term(s) are no longer detected, the tagger will remove that tag from the note's attribute. In effect the attribute keeps a dynamic reference of current matched terms in a note's $Text or $Name.

    Naming of taggers

    Every discrete note in the 'Taggers' container is a distinct tagger. Each tagger works with s set-type attribute of exactly the same (case-sensitive name). Thus the tagger names should be one that meets attribute naming rules.

    Built-in taggers are provided for $NLPlaces, $NLNames, $NLOrganizations, and $NLTags. Thus, the built-in tagger note 'NLTags' maps to system attribute $NLTags.

    A note will be flagged for tagging after its $Text or $Name is edited, and the tagging will be performed when the note is visited by the rule manager (i.e. the same cycle of operations that runs note rules).

    Setting up for first run

    There is some internal work associated with setting up a tagger, regardless of the size of the document. So, depending on the speed of the host Mac, it may take up to 30 seconds before the initial use of a new tagger (i.e. results are seen in the associated attribute). Once set up, performance—i.e. as in term detection—is essentially instant.

    How often does tag detection run?

    Tag detection runs all the time, but is throttled in large complex documents for pragmatic performance reasons. Despite this, taggers are not a full-on, always-updating service as with a rule. This reflects that they are a form of advisor and they need to run (using AI routines in the OS) in harmony with other Tinderbox processes.

    If in doubt about tagger output being up to date, close and re-open the current document as all Taggers run at document start. As this feature settles into its place in the app, the control of tagger operations (without affecting other task) will doubtless be improved. See more about performance and update time.

    The tagger mechanism also runs the sentiment analysis process and dominant language detection.

    Editing taggers for 'NL' system attributes

    When adding the Hints container to a document, the Taggers sub-container includes blank (i.e. no $Text) tagger notes for each of the NL-prefixed system attributes in the 'AI' group. Adding tags (see below).

    Users should not create new taggers for any other built-in attributes. Instead, create a custom tagger as described below.

    Adding custom taggers

    Further taggers may be created for any user Set-type attributes. New taggers are placed in the same container as built-in ones. To add a totally new tagger involves 2 tasks (these can be done in any order):

    • add a user Set-type attribute (it must be a Set) using the same name as will be used for the tagger. Pick a name not already used for an attribute or note name.
    • create the tagger note with the same name as the attribute.

    Tinderbox will now make the attribute read-only (this can't be undone) and will populate that attribute in any notes where the new tagger finds a match. Be aware that creating the tagger file alone does not auto-generate attributes, so user attributes must exist if they are to use taggers.

    Customising built-in taggers

    The built-in NL-prefix taggers may also be customised, if desired, using the same syntax (see below) as used for custom taggers.

    Tagger file syntax

    Described here.

    Term matching and case

    A tagger's defined terms are matched case-intensively in any note's $Text. Thus a term Tinderbox with match both "Tinderbox", "tinderbox" or any other case variant of the word.

    Terms and NLP

    Unlike user-defined taggers, the NL taggers may add tags the NLP process considers a match but will be unable to explain why. This is a current limitation and weakness of such NLP tools: they cannot explain their decisions, so triaging the cause of false positive (things that should not be matched) or false negative (things that should be matched and aren't) is difficult. Note that the NLP frameworks are Apple's and so any such errors are not caused by Tinderbox, but the underlying Apple code.

    The tagger matches in the $Text are not marked or indicated in any way. In the case of custom taggers, or custom additions to built-in NL taggers, it is assumed the user knows the terms they have defined. For the built-in NL taggers additional Apple NLP frameworks are addressed.

    Regular Expressions

    Taggers do not support regular expressions. Why? Because taggers work with the OS' NLP libraries and those do not understand regex.

    Taggers and agents

    Described separately here.

    Technical requirement

    Taggers are require macOS 10.14 or later.

    Other aspects of Tagger use:

    Tagger file syntax

    This information applies both to user-created taggers and customisation of built-in taggers.

    Each line of a tagger note's $Text describes one possible 'tag' (i.e. term to be added) followed by one or more 'term't is term terms that are being searched for in $Text by the tagger process.

    The general syntax is

    tag: term 1; term 2; term 3; 

    The first term is the 'tag' separated by a colon from the trigger 'term(s)'. Each discrete term is delimited from others by a semi-colon (in the convention of Tinderbox list delimiters) but unlike other lists in Tinderbox, there must be a semi-colon after the last item: if a terminating semi-colon is omitted the last listed term may not get evaluated (without any error waring).

    White space. Space after colons and before/after semicolons is ignored. The layouts below are thus functionally equivalent:

    tag:termX;termY;termZ; 
    tag: termX; termY; termZ; 

    Shorthand definition method. If the only term defined matches the tag, as in:

    Eastgate:Eastgate; 

    …then a shorthand form may be used, i.e. just the word, alone, on a single line (note no line terminator colon/semicolon is used):

    Eastgate 

    Tags should be single word. Although a multi-word ('price-sensitive') or multiple word ('price sensitive') tags can be defined they are not recommended/supported. Tags should thus be defined as a single word.

    Terms and multiple words. Unlike a tag, a term may be a multi-word string (e.g. 'first-name last-name'). Note, however, that this style of term is not intended for matching long texts (there is no fixed limit, just use multi-word terms sparingly)

    Definition ending markers. Lines forming tag definitions must end with a semi-colon. The latter does not apply to comment lines (code comments are described below).

    Line wrap. Although the tagger file's $Text may wrap in the text pane, a single definition runs from the start of a line to the first line break encountered regardless of soft wrapping.

    Line breaks line break character is treated a a break between tag definition (noting the need to mark the end of definition string (above).

    Blank lines. Any blank lines in the tagger note are ignored so may be used to separate the definition strings for clarity of reading.

    Comments in taggers. Any line starting with a hash (#) symbol is treated as a comment and is not evaluated for tags/terms.

    Summary

    The format is thus 'tag:term1;term2;etc…' or simply 'tag'. Note the short form uses no end marker but must be followed by a line break.

    Therefore, if the NLTags tagger file contains the line:

    Eastgate:Eastgate;Tinderbox;Storyspace;Mark Bernstein; 

    … then $NLTags will add the tag "Eastgate" if the text or title of the note mentions any one or more of the words "Eastgate", "Tinderbox", "Storyspace", or "Mark Bernstein".

    Thus each discrete tag configuration forms a single line, i.e. line through to the first following line break character. Note that lines with tag definitions must end with a semi-colon.

    Each tagger note can define one or more discrete 'tags'—values to add to/remove from the associated Set-type attribute if matched, one tag per line. In turn, each tag may be defined by a semicolon-delimited/terminated list of one or more 'terms'.

    Taggers and agents

    Taggers are particularly useful to agents. Often, an agent needs to look for significant or interesting terms in the text:

    query: $Text.icontains("Caesar") | $Text.icontains("Cato") … 

    In projects that have lots of text, these agents have a difficult task: each clause might need to search all the text in the document, and each clause needs to build a regular expression matcher. The tagger is more restricted—it searches only for entire words, not for regular expressions—but it is significantly faster and it runs only when the text of the notes changes. In the example above, we could replace the query with the simpler query

    query: $NLTags.contains("Rome") 

    and add a single line to the $Text of the /Hints/Taggers/NLTags note:

    Rome: Caesar; Cato; Cicero; Aggripa; Brutus; Decius; Catullus 

    Now, the agent needs only to examine set $NLTags, which requires far less work than searching all the text of a large document.

    Tagger performance and update time

    This a new feature and Tinderbox is, at present, very conservative about the frequency at which Taggers run. It may be too conservative. A concern is that not all Macs have dedicated neural engine cores, and setting up a tagging scan requires a certain amount of prep work. The general idea here is that you want rules and agents to run now, but taggers are a sort of background discovery task.

    The original notion for taggers is that they are slowly mining data and marking down relevant things they discover. They are envisioned like good research assistants; they may not get things done right away, but eventually they will get answers that are interesting and usually useful.

    As taggers all run on document open, saving and re-opening the document is a reliable way to force the process to update on demand, at least until this feature evolves further control methods. Editing a note's text ($Text) will also update the tagger. However, it will not update the displayed note. So, to see the effect—e.g. in the Displayed Attributes table—it will be necessary to re-select the note (or click the current tab's label to refresh the whole tab display).

    Another way to force everything to be retagged is to edit the $Text of the tagger-defining note. However, tagging tasks and indexing tasks might be delayed in large documents when lots of things are going on, e.g. complex actions in rule or edicts using a lot of regex tasks, or very complex find() queries.

    Editing a tagger note marks the tagger as needing to be reloaded when the index is next revised.

    Sentiment Analysis

    Tinderbox's tagger mechanism also attempts to analyse the general tenor or sentiment of each note. Sentiment is measured on a scale from +1 to -1; an enthusiastic note like :

    "This cheese is tasty, wholesome, and creamy. It is a delight!"

    is scored near 1, whereas a critical note like:

    "This cheese is rotten, slimy, and stale. It tastes terrible and should be thrown away."

    is scored near -1.

    The average sentiment for the entire note is stored in $Sentiment, and the score for each paragraph of the note is stored in $Sentiments.

    Sentiment analysis is available in seven major languages using macOS 10.15 and later.

    Why use this? What is it for?

    One example would be a set of notes, gathered from magazines and newspapers, describing a performance or a social event in some past historical era. For this set of sources, tt would be interesting to know whether the writers were sympathetic or hostile to the event being commented upon.

    For ancient sources, where there may at most four or five source, this can easily done 'manually (by reading/assessing the source texts). By comparison for a 19th century event, there might be dozens or hundreds of sources and automated assist could be helpful.

    As ever with machine analysis of text it may miss, or misconstrue, nuances a trained human eye would catch. No matter, the automated assessment can still be a helpful 'serving' suggestion to inform more deliberate human assessment,

    MCP for AI

    Note: this feature requires macOS v.15.1.

    The Model Context Protocol (MCP) was created by Anthropic to allow local AI agents to interact with apps on one's Mac, such as Tinderbox. The detailed functioning of MCP is outside the scope of aTbRef but can be researched online. A basic point to understand is that MCP-supporting apps appear in the local AI client.

    Currently, MCP integration is only available for two AIs, Anthropic's Claude, and google Gemini, but other options may be added as the AI ecosystem matures, including support for use of local models for data privacy. Some options may have a Desktop app or Command Line (only) access. Claude supports both but Gemini is currently CL-only.

    Data Privacy

    By allowing MCP-based integration you are allowing the specified AI(s) to read from and write to your TBX documents.

    IMPORTANT. Although the MCP bridge is to a local AI client, the AI work *is not happening on the local Mac*, i.e. data may pass from the local Mac to [unknown] service in [unknown] country during AI work.

    Therefore be cautious about working on documents with sensitive personal, client or patient data. For practitioners such as doctors, such work maybe illegal (e.g. US HIPAA laws). It is the users responsibility to use AI connections only where appropriate. Local-only AI working may become possible in the future but do not assume local-only unless it is clearly stated as possible

    Which documents are accessed?

    As at v11.0.0, access means the current TBX document and generally assumes a single document is open. Currently, multiple document concurrent access is not supported but this might change in the future. AI integration is also controlled per-document, via its Document Settings/general pane.

    General Set-up (v11.8.0+)

    From v11.8.0, AI Integration should be far more reliable as MCP can connect to Tinderbox while Tinderbox is running, and Tinderbox can handle multiple MCP connections at once.

    To ensure proper setup of the new MCP bridge, open Tinderbox and choose Tinderbox ▸ Disable AI Integration. Then, choose Tinderbox ▸ Enable AI Integration to install the new MCP service and then start a session with the AI tool of choice. The previous necessity to allow AI models to launch Tinderbox is removed.

    The MCP service has been tested with Claude Desktop, Claude Code in Desktop, Claude Code CLI, Claude Desktop Cowork, Devin CLI, and Gemini CLI.

    Setting up (for Claude, pre11.8.0)

    Before first use, MCP has to be enabled in Tinderbox, then the app closed and the target AI agent (e.g. Claude Desktop) must be (re-)started. This is necessary as enabling MCP use in Tinderbox requires writing some data into the target AI agent before both apps are re-started. This the order is:

    • Close Claude (if open)
    • Open Tinderbox, and from the Tinderbox menu, select Enable All AI Integration (the menu label with toggle to 'Disable All...').
    • Close Tinderbox.
    • Open Claude.
    • Open Tinderbox. When using Claude, Tinderbox needs to be closed when Claude is opened. Reopeing Tinderbox at this point does not suffice.

    Once enabled, per-TBX document MCP access is controlled via that document's Documents Settings::General. The MCP server has a set_document tool that allows it to switch among several open Tinderbox documents (assuming they are AI-allowed), by name. It cannot current load Tinderbox documents.

    • Globally, all MCP interaction may be disabled by choosing menu Tinderbox 11 ▸ Disable AI Integration. This stops the MCP server and also uninstalls Tinderbox from Claude’s configuration.
      • When enabled, File ▸ Enable AI Integration installs Tinderbox in Claude’s configuration and starts MCP service.
      • Tinderbox also automatically modifies the Claude Desktop configuration file, ~/Library/Application Support/Claude/claude_desktop_config.json, to install Tinderbox support.
    • After using menu Tinderbox 11 ▸ Enable AI Integration, quit Tinderbox and Claude Desktop. Then open Claude Desktop and allow Claude to open Tinderbox.
    • Individual documents may be withheld from sharing information in Document Settings: General.

    By default, e.g. in a new Tinderbox app install, AI MCP integration is off. This avoids accidental attachment to external AI resources. The master switch for AI enablement is in the Tinderbox menu.

    If AI Integration is not yet enabled, or subsequently disabled, the Document Settings:General dialog disables the checkbox for AI Integration in this document.

    Starting AI integration will add the Built-in Hints container, if not already present, including AI-specific content.

    Further MCP related notes:

    AI Additions to the Hints container

    Note: this feature requires macOS v.15.1.

    The built-in Hints container has a new AI-related new content as of v11.0.0.

    Re-adding the built-in Hints to a TBX document with a pre-existing /Hints container will cause any newer, missing, default content to be added. Existing customisations are not affected.

    From v11.5.0 the built-in Hints container adds a new branch /Hints/AI/Gemini. Re-adding the Build-in Hints to an existing file will add the new container and its contents.

    From v11.6.0 a separate Readings and Hints area for Claude Code may be added using File ▸ Built In Hints (if hints is already present only this new content gets added. It is also possible to the AI to create a Claude Code section in existing TBX files.

    From v11.6.0, text of the built-in AI notes containers was revised to adopt a hierarchical note structure. For a new session, Claude is directed to read only the top-level notes which summarise the topic, and such additional notes as may become useful.

    From v11.6.0, Tinderbox’s AI Integration offers an additional tool, permitting AIs to obtain an image of the current view. This is primarily intended for map view, but can also be used with Outline, Chart, Gaudí and Hyperbolic views.

    Claude Integration

    Note: this feature requires macOS v.15.1.

    Anthropic's Claude AI is integrated via the Claude Desktop app 'Claude.app', usually installed in the /Applications folder of the host Mac.

    If a new Tinderbox version is installed, the pre-existing enablement/disablement state of AI Integration should be honoured. If not, the correct state may need to be reset from the Tinderbox menu. This situation is not totally under Tinderbox's control; a failure to update being as likely due to Claude Desktop. Worst case, repeat the AI bridge initialisation process as if for the first time.

    Using Claude Desktop with Tinderbox

    After correctly installing the MCP bridge, if using Claude and Tinderbox together the apps must be opened in a strict order:

    • Check both apps are closed
    • Open Claude Desktop, only once fully open,
    • Open Tinderbox and any needed TBX files

    Simply re-opening an already-open Tinderbox after opening Claude is not sufficient to initialise everything. This correct order of opening should be the first thing to check if Claude reports a problem with the Tinderbox MCP connection.

    Further information

    Teaching Claude about Tinderbox

    Select menu File ▸ Built-In Hints to install the Hints container, which includes some notes for AI use. If the TBX already has a Hints container but doos not have AI hints, re-calling File ▸ Built-In Hints will install the new notes without disturbing any existing notes. The notes and containers in /Hints/AI do not have meaningful special behaviour; feel free to copy them from other documents or to revise them.

    The container /Hints/AI/Claude/Readings holds notes that introduce Claude to Tinderbox. The intent is that Claude should review these notes at the start of each conversation. Indeed, my Claude profile (in Claude Desktop, Claude ▸ Settings:Profile) reads as follows:

    I’m using MCP with Tinderbox, a note-taking tool. When you start an MCP session with a Tinderbox document, look at the note /Hints/AI/Claude/Readings for more information. You may also review notes you might have left for your later use in /Hints/AI/Claude/Notes, though only notes in the "Important" container are required. Scan the titles of others and retrieve if they bear on the discussion.

    Include the above, or something like it, in your own user profile in the Claude Desktop app.

    /Hints/AI/Claude/Readings/Using Tinderbox is a concise one-page introduction to Tinderbox from Claude's point of view. Keep in mind that Claude's view of Tinderbox is exclusively through its tools, and those tools are textual. Claude understands that there is something called a Map View, but it cannot "see" the map.

    Without this introduction, Claude "invents" actions that it thinks Tinderbox ought to implement. This is, generally speaking, hopeless. Yet a very brief introduction gives Claude Desktop remarkable capabilities.

    /Hints/AI/Claude/Readings/Posters explains poster notes in map view. Tinderbox users have sometimes found posters daunting, but this 150-word explanation has often sufficed to let Claude create posters on the fly.

    Feel free to add extra notes that describe aspects of personal Tinderbox that Claude fails to understand.

    /Hints/AI/Claude/Notes is an empty container that is intended for Claude’s own notes. Tinderbox is a powerful tool for making and analysing notes; why not let Claude benefit from the tool?

    Claude interacts with Tinderbox via its set of MCP tools.

    The design of MCP dictates that MCP tools are used at the AI’s discretion. For example, it can be useful to begin a new session by asking the AI to review its readings and notes. When Claude Desktop uses an MCP tool, it shows the user it plans to send Tinderbox and to approve it. The user can can also tell Claude to assume that approval is granted for all uses of some or all tools.)

    In addition to tools, MCP allows a server to supply prompts and resources on the server’is initiative. Tinderbox provides support for these, but the note-taking and readings facilities appear to be better solutions for this role.

    Claude-Tinderbox MCP tools

    Note: this feature requires macOS v.15.1.

    The following are defined inside the Tinderbox 'connector' in the Claude Desktop, if Tinderbox is configured as an MCP server. They are not meant for direct use by the user but the tools may get mentioned in some prompts or Cluade's internal Tinderbox notes to itself.

    Tools

    get_notes. Get information about notes from the current Tinderbox document, including their parent, children, prototype, and the values of any attributes of interest, such as Path or Text.

    set _value. Change the value of an attribute of one or more notes from the current Tinderbox document.

    create_note. Create a new note in Tinderbox.

    create_link. Link two related Tinderbox notes, a source and destination.

    get_document. Get information on the current document.

    set_document. Use a specific document that the user has opened.

    do. Perform a Tinderbox action on a Tinderbox note.

    evaluate. Evaluate a Tinderbox action code expression in the context of a Tinderbox note.

    Resources

    Current Document. The currently open Tinderbox document.

    Claude app MCP error messages

    At Claude Desktop (i.e. the 'Claude' app) startup:

    • the app may report that an MCP server shut down unexpectedly. This is a bug in Claude Desktop the Tinderbox cannot code around. Until resolved, simply close the error messages and proceed as normal.

    During a Claude Desktop session:

    • closing an (AI-enabled) TBX document may cause Claude to report the loss of an MCP server. This is to be expected (the user just closed the document) so the error can be dismissed without further action. If the Claude session needs to continue with that document, it needs to be re-opened before making Claude input.

    Claude Code

    From v11.6.0, Claude Code can use Tinderbox MCP, both via Claude Code embedded in the desktop app and accessed via the command line.

    Claude Code is built into the Claude Desktop app but not revealed in the top button bar unless the user has a paid subscription. Using the free tier, the buttons are hidden

    Claude Code in the desktop app is able to install Claude Code for the command line.

    Gemini CLI

    From v11.5.0, MCP support for Gemini-CLI is available.

    Google's Gemini CLI (Command Line Interface) is a large language model that is run from the Terminal window and has access to files in the terminals current directory.

    (Eastgate's summary on Gemini) Its forté is software development, and it is quite proficient at manipulating text files of various kinds. Its general knowledge (e.g. of cooking) is quite good, though it is less adept than Claude at finding good scholarly sources.

    Instructions for installing Gemini-CLI may be found here: https://github.com/google-gemini/gemini-cli.

    Gemini, like Claude, must launch Tinderbox when it starts up. It cannot connect to a running instance to Tinderbox. Once launched, you are free to use Tinderbox alongside Gemini.

    The menu Tinderbox 11 ▸ Enable/Disable AI Integration enables and disables both Claude and Gemini. When adding Gemini to Tinderbox where Claude has been enabled, disable AI Integration and then re-enable it again to install Tinderbox/Gemini integration as well. Important: then Quit Tinderbox and allow Gemini to launch it before trying to use Gemini CLI with Tinderbox.

    The built-in Hints container adds a new branch /Hints/AI/Gemini. Re-adding the Build-in Hints to an existing file will add the new container and its contents.

    Gemini uses a file GEMINI.md to define the parameters of the user's project. The OS file ~/.gemini/GEMINI.md applies to all Gemini projects; each directory may also have its own GEMINI.md, which is appended to the master instructions. For further detail and examples, see Hands-on with Gemini CLI (at Google Codelabs).

    MCP Status

    The MCP link has two communications paths: stdio and http:

    *The stdio link was implemented first, and receives requests from the AI client through stdin and sends responses to stdout. This requires two “LEDs” because either stdin or stdout might fails.

    *The http link (in v11.8.0+) listens on a designated internet port. It cannot detect an input failure, input is either present or not as a web site cannot really distinguish between "Mark Bernstein is not on the internet right now” and “Mark Bernstein is not asking me to do anything right now.”

    AI Prompts

    From v11.8.0, prompts are messages or instructions to be sent to an AI such as Claude or Gemini. Prompts are part of the Model Context Protocol (MCP) systems.

    Typically, you use a prompt in the AI client by typing the command /tinderbox: followed by the prompt name. For example:

    /tinderbox:translate 

    would invoke the prompt named "translate".

    Tinderbox prompts are stored in the Tinderbox document in the container /Hints/AI/Prompts. They use the built-in prototype "An AI Prompt". A prompt has three components:

    • Name: taken from the $Name of the prompt note. Names may contain spaces. Prompt names should not contain parentheses or forward slash '/'.
    • Description: optional, taken from the $Subtitle of the prompt note. A brief description of the prompt, used to remind you what it does.
    • Prompt: taken from the $Text of the prompt note. Describes what you want the AI to do.

    Prompts may have optional arguments. These appear in the prompt enclosed by {{double curly braces}}. For example, a prompt named “translate”might be:

    Show me a translation of the note {{note}} into language {{language}}, or into French is no language is specified. Do not change the note.

    Then, after you select /tinderbox: translate the system shows a reminder "(arguments: note, language)". You might then complete the command:

    /tinderbox:translate "first draft" French 

    and the AI would be asked to find a note named "first draft" and to show you its French translation.

    Some examples of prompts might include:

    • Summarize — condense each note in a container into 2–3 sentences , showing you the summaries
    • Critique — provide feedback on the argument in a note
    • Questions — list questions the note raises but does not answer
    • Additional Reading — suggest the best books or research papers related to a note
    • Gaps — review the notes in a container, and identify notes that might be missing
    • Write agent — given a plain-English description ({{description}}), generate a Tinderbox agent query
    • Explain agent — given a note containing an agent query, explain what it does in plain language
    • Suggest connections — given a note, suggest other notes it might be linked to
    • Extract action items — pull out TODOs and next steps from meeting notes or journals
    • Daily review — summarise all notes that have been modified today into a digest

    AI Resources

    From v11.8.0, the Tinderbox Readings notes stored in the /Hints/AI/[client]/Readings container are exposed as MCP Resources. Resources, like prompts, are available on request. Type @tinderbox: in the client to see a list of available resources.

    Resources are known to the AI and it can consult those resources if it thinks them pertinent to a problem. For the present, Claude Code is of the opinion that, while it can spontaneously use resources, it’s not very likely to do that unless instructed to do so.

    Resources may be limited to Claude Code.

    Keyboard Shortcuts

    The following abbreviations are used in this section:

    A fuller listing of keyboard names and symbols is listed separately below.

    Tinderbox also supports most system-wide shortcuts, some but not all of which are included here.

    Keyboard shortcuts: keys and symbols

    The following abbreviations are used in this section:

    • The Command key (Cmd) is located either side of the space bar. In menus this is indicated by the 4-looped symbol shown on the keyboard key (). On very early keyboards this key had an Apple logo and the loop symbol and so long-term Mac users sometimes still refer to it as the 'Apple', 'cloverleaf' or 'loop' key.

    *The Option (Opt)—or Alt key on PCs—is located to the left of the left-hand Command key (and right-hand on extended keyboards. In menus this key is indicated by the stepped line symbol shown on the 'option' keyboard key ().

    • The Control key (Ctrl), located to the left of the Option key. In menus this is indicated by a caret-type symbol (). Note, this symbol is not always shown on the keyboard's 'ctrl' key.

    Other keys shown by symbol rather than name are:

    • Shift key (large up-arrow: ).
    • Return key (horizontal u-shaped arrow: .). This key is the double height key to the right of the top two rows of letter keys and is commonly called the 'Enter' key. Elsewhere, in other apps/references, the Return key may also be indicated by this alternate symbol: . Thus and are the same. Neither should be confused with the formal 'Enter' key as described next, below.
    • Enter key (line over caret symbol: or ). Do not confuse this with the separate Return key, above, which is often referred to colloquially as the 'Enter' key. This key is found to the bottom right of the number pad on extended keywords and, on old laptops, to the right of the right-hand Command key. Modern laptops or wireless keyboards have no Enter key, you must use Function+Return (fn).
    • Arrow keys. Up/down/left/right (///).
    • Tab key ().
    • Escape key ().
    • Eject key ().
    • Function (fn) , now Globe (🌐) key

    The format for describing shortcuts is [key1]+[key2]+[etc.]; an exception is the notes on menus where shortcuts are cited using the style shown on the menu. Where letter keys are cited they are usually shown as capitals as in the menus but it is not necessary to use the (shifted) uppercase letter, the lowercase suffices.

    Individual Shortcuts

    This is a listing of individual shortcuts, listed by function:

    Align Center

    [Cmd]+[|]

    Align Left

    [Cmd]+[{]

    Align Right

    [Cmd]+[}]

    Bold

    [Cmd]+[B]

    Cancel Export

    [Cmd]+[.]

    Use during HTML or text export only.

    Check Document Now

    [Cmd]+[;]

    (semi-colon)

    (check now for spelling)

    Clear Typeahead buffer

    [Esc]

    Close [current TBX file's name]

    [Cmd]+[Shift]+[W]

    (hold Shift key ⇧ to see in menu)

    Close Window

    [Cmd]+[W]

    Collapse

    [Cmd]+[Opt]+[Left arrow]

    Command Bar

    [Cmd]+[Shift]+U

    Copy

    [Cmd]+[C]

    Copy Style

    [Cmd]+[Opt]+C

    Copy View As Image

    [Cmd]+[Shift]+[C]

    Create Agent

    [Cmd]+[Shift]+[A]

    Create Child Note—as first sibling

    [Shift]+[Opt]+[Return]

    Create Child Note—as last sibling

    [Shift]+[Return]

    Create Note

    [Cmd]+[K]

    or

    [Return]

    or

    [Double-click] **

    ** In Map, Outline or Chart view only, and with no note selected. On maps you may double-click on the background or on adornments.

    Note is created as next sibling. In Maps it appears to the right of the current selected note.

    Create Note above selected note (Map)

    [Ctrl]+[Opt]+[Return]

    Create Note below selected note (Map)

    [Ctrl]+[Opt]+[Return]

    Create Note to left of selected note (Map)

    [Ctrl]+[Return]

    Create Note—as previous sibling

    [Ctrl]+[Return]

    Cut

    [Cmd]+[X]

    Cycle Tab selection

    [Ctrl]+I

    Character i not numeral 1.

    Cycle Tab selection (reverse)

    [Ctrl]+[Shift]+I

    Character i not numeral 1.

    Dance

    [Cmd]+[Shift]+D

    Start/Stop force directed layout of map view.

    Delete current item (Outline)

    Backspace (Delete) key (⌫)

    or

    (Forwards) Delete key (⌦) (use [fn]+⌫ on laptop/wireless keyboards)

    Note that the key used affects the subsequent selection. In both cases the current item is deleted but:

    • Backspace: the previous ($OutlineOrder) item is selected
    • Forward delete: the next ($OutlineOrder) item is selected

    Delete entire word

    [Opt]+[Delete]

    or

    [Opt]+[Forward delete]

    deletes part or whole word back or forwards from the current cursor position, i.e. from cursor to next word boundary in direction of delete action.

    Delete to line end

    [Cmd]+[Delete]

    or

    [Cmd]+[Forward delete]

    deletes part or whole line back or forwards from the current cursor position, i.e. from cursor to line start or end. In the case of line end it is to the $Text area's soft line break and not the next hard line/paragraph break.

    Deselect All

    [Cmd]+[Opt]+[Ctrl]+[A]

    Includes Text pane

    Displayed Attributes table - toggle display

    [Cmd]+[Shift]+K

    Show/Hide a note's Displayed Attributes table (if any)

    Document Settings

    [Cmd]+[8]

    (number 8)

    Drag-as-last-child

    [Cmd]+[shift]+[drag]

    Drag-create note aliases

    [Cmd]+[Opt]+[drag] selected note(s)

    Drag-create note copies

    [Opt]+[drag] selected note(s)

    Drill Down (Map)

    [Down arrow]+[Selected note]

    [Cmd]+[Opt]+[Down arrow]+[Selected note]

    [Double-click]+[viewport part of containers and agents]

    Same action as Focus view, and logical opposite of Expand View. Acts like a 'Down Arrow' for Map views. Only works if a note has active focus. There is no menu reference to this shortcut.

    All map shortcuts work even if a container has its viewport hidden by expanding the title area.

    Duplicate

    [Cmd]+[D]

    or

    [Opt]+drag or click

    Expand

    [Cmd]+[Opt]+[Right arrow]

    Expand All Descendants

    [Option]+[click] on Outline view expand widget

    This expands the container (note) clicked on and does so for any other container notes amongst the clicked note's descendants.

    Expand Horizontally

    [Cmd]+[Ctrl]+[Right arrow]

    Expand Vertically

    [Cmd]+[Ctrl]+[Down arrow]

    Expand View (Map)

    [Up arrow]

    [Cmd]+[Up arrow]

    For opposing command, see Drill Down.

    Explode

    [Cmd]+[Shift]+[E]

    Explode current note

    Original shortcut ([Cmd]+[Opt]+[E]) was re-assigned to text sub-pane toggling

    Extend Outline selection downwards

    [Shift]+[down arrow]

    Extend Outline selection upwards

    [Shift]+[up arrow]

    Find and Replace

    [Cmd]+[Opt]+[F]

    Find Next

    [Cmd]+[G]

    Find Previous

    [Cmd]+[Shift]+[G]

    Find text

    [Cmd]+[F]

    Find using $Text selection

    [Cmd]+E

    Uses $Text selection, sets Find string to current selected text for both view and text pane Find (regardless of whether Find toolbar(s) are currently shown).

    Focus view (other views)

    [Double-click]+[Outline/chart note icon]

    [Double-click]+[Treemap item]

    For maps, see Drill Down.

    Only works for notes with children. Double-click must occur on the note icon, not the badge or note title.

    Force Toggle Select tool

    Press and hold [Cmd] key (⌘).

    In maps, charts and outline views, press and hold the command key to force to use the grabby hand cursor, even when pointing to an adornment or a note.

    Full Screen mode (toggle)

    [Ctrl]+[Cmd]+F

    Toggles enter/leave full screen mode

    Get Info

    [Cmd]+[Opt]+[I]

    (letter i not number 1)

    Go Back

    Cmd+'

    (single quote)

    Hide others

    [Cmd]+[Opt]+[H]

    Hide Tinderbox

    [Cmd]+[H]

    Horizontal Map Scroll

    [Mouse wheel]+[Shift]

    Indent

    [Cmd]+[]]

    i.e. ']'

    In Outline and Chart views this makes the note a child of its previous sibling.

    From v6.4.0, if the cursor is in the text pane the current $Text paragraph is indented.

    Insert Regex Pattern

    [Cmd]+[Opt]+[Ctrl]+[P]

    (only when (a) text pane has focus and (b) find toolbar is displayed.

    Italic

    [Cmd]+[I]

    (letter i not figure 1)

    Jump to Selection

    [Cmd]+[J]

    Lookup in Bookends

    [Cmd]+[Shift]+[B]

    Lookup the text selection (of $Text) in Bookends.

    Lookup in Zotero

    [Cmd]+[Y]

    Lookup the text selection (of $Text) in Zotero.

    Magnify

    [Cmd]+[=]

    (equals)

    Make Alias

    [Cmd]+[L]

    or

    [Opt]+[Shift]+drag or click

    Minimize

    [Cmd]+[M]

    Move Note Down

    [Cmd]+[Down arrow]

    Move Note Up

    [Cmd]+[Up arrow]

    Move To First (Outline, Chart)

    [Cmd]+[Shift]+[Up arrow]

    Move To Front (Map)

    [Cmd]+[Shift]+[Up arrow]

    Move To Last (Outline, Chart)

    [Cmd]+[Shift]+[Down arrow]

    Move view pane selection down

    [Cmd]+[Opt]+[Down arrow]

    (focus in text pane)

    Move view pane selection up

    [Cmd]+[Opt]+[Up arrow]

    (focus in text pane)

    New (child Note)

    [Shift]+[Return]

    (the new note created will be a child of the currently selected note)

    New (Note)

    [Cmd]+[N]

    or

    [Return]

    or

    [double-click]

    New TBX document

    [Cmd]+[N]

    New Window

    [Cmd]+[Shift]+[N]

    Next Document Tab

    [Ctrl]+[Tab]

    Selects the next (right) document in the document tab bar.

    Next Tab

    [Cmd]+[Opt]+[]]

    Open (TBX file)

    [Cmd]+[O]

    (letter o not number zero)

    Open Help menu

    [Cmd]+[Shift]+[/]

    (i.e. [Cmd]+[?])

    OS-wide Shortcut may vary on non-English language keyboards.

    Outline - Collapse or Expand All

    [Cmd]+[Opt]+[click]+[disclosure triangle]

    The disclosure triangle must be at root level for this to work, otherwise the current note and siblings, i.e. the whole current 'branch' is expanded/collapsed.

    Outline - Demote Selection

    [Tab]

    Works with a single or multiple selections.

    Outline - Hoist

    Hoist == Focus view

    [Outline note icon]+[Double-click]

    Outline - Promote Selection

    [Shift]+[Tab]

    Works with a single or multiple selections.

    Outline - Show or Hide siblings

    [Cmd]+[click]+disclosure triangle

    Expands/collapses all siblings one level. Siblings (same level) of other parents are not affected nor are grandchildren exposed.

    Page Setup

    [Cmd]+[Shift]+[P]

    Paste

    [Cmd]+[V]

    Paste and Match Style

    [Cmd]+[Opt]+[Shift]+[V]

    Paste Style

    [Cmd]+[Opt]+[V]

    Previous Document Tab

    [Ctrl]+[Shift]+[Tab]

    Selects the previous (left) document in the document tab bar.

    Previous Tab

    [Cmd]+[Opt]+[[]

    Print

    [Cmd]+[P]

    Prototype

    [Cmd]+[3]

    (Document Inspector, Prototype tab)

    Quickstamp

    [Cmd]+[2]

    (Document Inspector, Quickstamp tab)

    Quit (Tinderbox) and Keep Windows

    [Cmd]+[Opt]+[Q]

    (hold Opt to see in menu)

    Quit Tinderbox

    [Cmd]+[Q]

    Redo (last edit or event)

    [Cmd]+[Shift]+[Z]

    Rename

    [Enter] **

    [Fn]+[Return] (newer laptops with no Enter key)

    [Cmd]+[Shift]+[Return]

    ** The Enter key (⌤) is different from the Return key (↩) [sic]. On a full Mac keyboard with a right-side numeric keypad, the Enter key is the bottom right corner of the numeric keypad. On older Mac laptops the Enter key is two keys right of the spacebar (i.e. there the right-hand Ctrl key is on a full keyboard).

    On current Macs most external keyboards have no numeric keypad and laptops omit the Enter key (⌤). In these contexts either of the latter two shortcuts above can substitute for the Enter key alone. Even with an Enter key available any of the shortcuts may be used.

    Resize Window retaining text pane width

    [Cmd]+drag window edge

    Roadmap

    [Cmd]+[Opt]+[Shift]+[R]

    Save

    [Cmd]+[S]

    Save As…

    [Cmd]+[Opt]+[Shift]+[S]

    (hold Opt to see in menu)

    Scroll Page Down

    [Ctrl]+[Down Arrow]

    (text pane)

    Scroll Page Up

    [Ctrl]+[Up Arrow]

    (text pane)

    Scroll to bottom (End)

    [Ctrl]+[D]

    Scroll to end of line

    [Ctrl]+[Right Arrow]

    Scroll to start of line

    [Ctrl]+[Left Arrow]

    Scroll to top (Home)

    [Ctrl]+[A]

    Select All

    [Cmd]+[A]

    Selection - Add or Remove Item

    [Cmd]+[click]

    The clicked item is added to the selection. If already selected, the item clicked is removed from the selection. Selecting a container does not select/de-select its contents.

    Selection - drag select

    [Opt]+[drag]

    On maps, a drag select cannot be initiated within an adornment (including pictures) and locked adornments are not selected.

    To select text in read-only notes, use [Cmd]+[drag]

    To select text in the output pane of HTML/Text Export views, use [Opt]+[drag]

    Selection - Expand

    [Shift]+[click]

    In Outline view extends selection from existing selection to clicked note and all in between (excluding hidden children/descendants).

    In all other views, the click adds to from the current selection (whilst also deselecting the last shift+click added item).

    Selection of Read-Only Text

    [Cmd]+[drag-select]

    Send Behind - Reversed (Cycle Open Windows)

    [Cmd]+[Shift]+[`]

    (backtick / grave accent key, left of 'Z' key)

    Reverses normal order of cycle.

    Repeat use cycles through all open windows, back sending the current window to the back of the (Tinderbox) window stack.

    Send Behind (Cycle Open Windows)

    [Cmd]+[`]

    (backtick / grave accent key, left of 'Z' key)

    Addition of Shift key (⇧) reverses cycle order.

    Repeat use cycles through all open windows, back sending the current window to the back of the (Tinderbox) window stack.

    Send To Back (Map)

    [Cmd]+[Shift]+[Down arrow]

    Set cursor focus in text pane

    [Spacebar]

    (View pane only)

    Short Date

    [Cmd]+[/]

    (forward slash)

    Short Date and Time

    [Cmd]+[Opt]+[/]

    (forward slash)

    Show Emoji and Symbols

    [Ctrl]+[Cmd]+Spacebar

    Show the OS 'Emoji & Symbols' palette. (Palette is closed manually)

    Show macOS Dictionary pop-up

    [Cmd]+[Ctrl]+D+selection in $Text

    Show macOS Dictionary pop-up

    Show or Hide (text) Ruler

    [Cmd]+[Ctrl]+R

    Show or Hide Displayed Attributes

    [Cmd]+[Shift]+[K]

    (selected item in view pane)

    Show or Hide Fonts

    [Cmd]+[T]

    Toggles OS X Fonts palette.

    Show or Hide Inspector

    [Cmd]+[1]

    (figure 1 not letter i)

    Show or Hide Prototypes

    [Cmd]+3

    (Document Inspector, Prototype tab)

    Show or Hide Quickstamp

    [Cmd]+2

    (Document Inspector, Quickstamp tab; focus goes into attribute search box)

    Show Original

    [Cmd]+[R]

    Show Original in New Tab

    [Cmd]+[Shift]+[R]

    Show Ruler

    [Cmd]+[Ctrl]+[R]

    Show Spelling and Grammar

    [Cmd]+[:]

    (colon)

    Shrink

    [Cmd]+[-]

    (minus)

    Special Characters

    [Cmd]+[Ctrl]+[spacebar]

    Split Note

    [Cmd]+[Opt]+[Ctrl]+Return

    (focus must be in $Text area of text pane)

    Standard Scale

    [Cmd]+[0]

    (zero)

    Standard Size

    [Cmd]+[Shift]+[T]

    Start Dictation

    [fn],[fn]

    Tap fn key twice

    Strikethrough

    [Cmd]+[Shift]+[minus]

    The hyphen key can be used instead of the number pad minus key, especially on laptop keyboard with no number pad.

    Text - set Black ($TextFont) text

    [Cmd]+[Ctrl]+[5]

    …when cursor is in $Text. Works on selected text. If $TextFont is not black, $TextFont colour is applied.

    Text - set Blue text

    [Cmd]+[Ctrl]+[3]

    …when cursor is in $Text. Works on selected text.

    Text - set Green text

    [Cmd]+[Ctrl]+[2]

    …when cursor is in $Text. Works on selected text.

    Text - set normal colour text

    [Cmd]+[Ctrl]+[0]

    …when cursor is in $Text. Works on selected text.

    Text - set Red text

    [Cmd]+[Ctrl]+[1]

    …when cursor is in $Text. Works on selected text.

    Text - set Warm Gray text

    [Cmd]+[Ctrl]+[3]

    …when cursor is in $Text. Works on selected text.

    Text (pane) Only

    [Cmd]+[4]

    (hide main pane only)

    Text pane - select next $OutlineOrder item

    [Cmd]+[Opt]+[Down Arrow]

    With focus in text pane, select next ($OutlineOrder) item in the view pane. Active focus remains in $Text area.

    (Outline/Chart/Treemap view only)

    Text pane - select previous $OutlineOrder item

    [Cmd]+[Opt]+[Up Arrow]

    With focus in text pane, select previous ($OutlineOrder) item in the view pane. Active focus remains in $Text area.

    (Outline/Chart/Treemap view only)

    Text pane - toggle focus

    [Opt]+[Tab]

    Toggles focus from the note text pane to the first listed Displayed Attribute (if any). This shortcut toggles between attributes, text and the view pane. To toggle out of the Displayed Attributes, an attribute value box must not be in edit mode.

    Text Window

    [Cmd]+[Opt]+[X]

    Tinderbox Preferences

    [Cmd]+[comma]

    Title edit-in-place: abandon title edit

    [Esc]

    Title edit-in-place: enter mode

    [Enter] (⌤)

    [Fn]+[Return] (sends Enter keycode)

    [Ctrl]+C

    (with selected note in view pane)

    Note: use of Enter key assumes default option for this Document Setting.

    Title edit-in-Place: exit mode

    [Enter]

    or

    [Return]

    Note: use of Enter key assumes default option for this Document Setting.

    Toggle Displayed Attributes boolean

    [spacebar]

    selected boolean is toggled to opposite state.

    Toggle Select Area tool

    [Opt]+drag

    (Map view only)

    Toggle Text Pane sub-tabs

    [Cmd]+[Opt]+[E]

    Cycles focus of Text panes(even if sub-tab selector row is hidden)

    Previously this opened Explode (now [Cmd]+[Shift]+[E]

    Toggle window focus

    [Opt]+[Tab]

    (cycles $Text → Displayed Attributes (if present) → view pane → $Text)

    Toggle zoomed map view

    [Cmd]+[Opt]+[Ctrl]

    (zooms map to show all items)

    Underline

    [Cmd]+[U]

    Undo (last edit or event)

    [Cmd]+[Z]

    Only available for some events, such as text editing.

    Unindent

    [Cmd]+[[]

    i.e. '['

    In Outline and Chart views this makes the note the next sibling of its existing parent.

    If the cursor is in the text pane the current $Text paragraph is unindented.

    Update now (Agents)

    [Cmd]+[Ctrl]+[=]

    (equals)

    Updates agents (and edicts, once)

    Use Filter

    Toggle view pane filter

    [Cmd]+[Opt]+[Shift]+F

    Vertical Map Scroll

    [Mouse wheel]

    View - change to Attribute Browser view

    [Cmd]+[Opt]+[A]

    Change current view type to Attribute Browser view

    View - change to Chart view

    [Cmd]+[Opt]+[R]

    Change current view type to Chart view

    View - change to Crosstabs view

    [Cmd]+[Opt]+[B]

    Change current view type to Crosstabs view

    View - change to Gaudi view

    [Cmd]+[Opt]+[U]

    Change current view type to Gaudi view

    View - change to Hyperbolic view

    [Cmd]+[Opt]+[W]

    Change current view type to Hyerbolic view

    View - change to Information City view

    [Cmd]+[Opt]+[Y]

    Change current view type to Information City view

    View - change to Map view

    [Cmd]+[Opt]+[M]

    Change current view type to Map view

    View - change to Outline view

    [Cmd]+[Opt]+[O]

    (letter o not number zero)

    Change current view type to Outline view

    View - change to Table view

    [Cmd]+[Ctrl]+[T]

    Change current view type to Table view

    View - change to Timeline view

    [Cmd]+[Opt]+[Ctrl]+[T]

    Change current view type to Timeline view

    View - Collapse All

    [^]+[⌘]+[0]

    View - Expand All

    [^]+[⌘]+[9]

    View (pane) Only

    [Cmd]+[6]

    (hide text pane)

    View and Text (show both panes)

    [Cmd]+[5]

    (show view pane and text)

    Reverse Look-up Map

    This page lists all Tinderbox keyboard shortcuts ordered by the action key used with all variants (Cmd, Opt, etc.) grouped together.

    Abbreviations used:

    • Cmd: Command (⌘)
    • Opt: Option (Alt) (⌥)
    • Ctrl: Control (⌃)
    • Esc: Escape (⎋)
    • Fn: Function (fn)
    • Globe (🌐)

    Shortcuts - Reverse Listing:

    ----

    A+[Cmd]: Select All

    A+[Cmd]+[Shift]: Create Agent

    A+[Cmd]+[Opt]: Attribute Browser view (change current tab's view pane view type)

    A+[Cmd]+[Opt]+[Ctrl]: Deselect All. View and text panes (hold down all 3 modifiers to see in Edit menu)

    ----

    B+[Cmd]: Bold

    B+[Cmd]+[Opt]: Crosstabs view (change current tab's view pane view type)

    B+[Cmd]+[Shift]: (focus in $Text) Look up selected $Text in Bookends (from v11.5.0)

    ----

    C+[Cmd]: Copy

    C+[Cmd]+[Opt]: Copy Style

    C+[Cmd]+[Shift]: Copy View As Image

    C+[Ctrl]+[Globe]: Centre (window in screen)

    ---

    D+[Cmd]: Duplicate

    D+[Cmd]+Shift]: Dance (map view only)

    D+[Cmd]+[Ctrl]+Selection: show Dictionary pop-up (selected $Text)

    ----

    E+[Cmd]: Use current selection for Find

    E+[Cmd]+[Opt]: Cycle Text pane sub-tab selection (Text→Preview→Export→etc.) even if tab selectors are hidden

    E+[Cmd]+[Shift]: Explode

    ----

    F+[Cmd]: Find

    F+[Globe]: Enter Full Screen mode

    F+[Cmd]+[Opt]: Find and Replace

    F+[Cmd]+[Ctrl]: Enter/Leave Full Screen mode (toggle)

    F+[Cmd]+[Opt]+[Shift]: View pane, toggle Filter bar (Outline)

    F+[Ctrl]+[Globe]: Fill (window in screen)

    ----

    G+[Cmd]: Find Next

    G+[Cmd]+[Shift]: Find Previous

    ----

    H+[Cmd]: Hide Tinderbox

    H+[Cmd]+[Opt]: Hide Others (all other open apps)

    ----

    I+[Cmd]: Italic

    I+[Cmd]+[Opt]: Get Info

    ----

    J+[Cmd]: Jump to Selection

    ----

    K+[Cmd]+[Shift]: Show/Hide Displayed Attributes (selected item in view pane)

    ----

    L+[Cmd]: Make Alias

    L+[Cmd]+[Opt]: Browse Links

    L+[Cmd]+[Shift]: Park Link (from current $Text selection)

    L+[Cmd]+[Ctrl]: Link to Selection (untyped link from current $Text selection to note with case-sensitive $Name match)

    L+[Cmd]+[Opt]+[Ctrl]: Make Web Link ($Text selection only)

    ----

    M+[Cmd]:Minimize

    M +[Cmd]+[Opt]: Map view (change current tab's view pane view type)

    ----

    N+[Cmd]: New (TBX Document)

    N+[Cmd]+[Shift]: New Window (for current document)

    ----

    O+[Cmd]: Open (TBX Document)

    O+[Cmd]+[Opt]: Outline view (change current tab's view pane view type)

    ----

    P+[Cmd]: Print

    P+[Cmd]+[Shift]: Page Setup

    P +[Cmd]+[Opt]+[Ctrl]: Insert Regex Pattern. NOTE: Text pane, only if find toolbar displayed.

    ----

    Q+[Cmd]: Quit Tinderbox

    Q+[Cmd]+[Opt]: Quit and Keep windows (hold Opt key to see in menu)

    ----

    R+[Cmd]: Show Original

    R+[Cmd]+[Shift]: Show Original in New Tab

    R+[Cmd]+[Opt]: Chart view (change current tab's view pane view type)

    R+[Cmd]+[Ctrl]: Show Ruler (if focus in text pane)

    R+[Ctrl]+[Globe]: Move & resize: return to previous size

    R+[Cmd]+[Opt]+[Shift]: Roadmap

    ----

    S+[Cmd]: Save

    S+[Cmd]+[Shift]: Duplicate (File menu)

    S+[Cmd]+[Opt]+[Shift]: Save As (File menu - hold Opt key to see in menu)

    ----

    T+[Cmd]: Show/Hide Fonts

    T+[Cmd]+[Opt]: Show/Hide Toolbar (for current window)

    T+[Cmd]+[Shift]: Standard Size (set selection to default $TextFontSize)

    T+[Cmd]+[Ctrl]: Table view (change current tab's view pane view type)

    T+[Cmd]+[Opt]+[Ctrl]: Standard Font (set selection to default $TextFont)

    ----

    U+[Cmd]: Underline

    U+[Cmd]+[Opt]: Gaudi view (change current tab's view pane view type)

    U+[Cmd]+[Shift]: Open Command Bar (use Esc to close)

    ----

    V+[Cmd]: Paste

    V+[Cmd]+[Opt]: Paste Style

    V+[Cmd]+[Opt]+[Shift]: Paste and Match Style

    ----

    W+[Cmd]: Close Window

    W+[Cmd]+[Opt]: Hyperbolic view

    W+[Cmd]+[Shift]: Close current TBX file (hold Shift key to see in menu)

    ----

    X+[Cmd]: Cut

    X+[Cmd]+[Opt]: Text Window (open current note text pane as tear-off stand-alone window)

    ----

    Y+[Cmd]: (focus in $Text) Look up selected $Text in Zotero (from v11.5.0)

    Y+[Cmd]+[Opt]: Information city view (change current tab's view pane view type)

    ----

    Z+[Cmd]: Undo (last event)

    Z+[Cmd]+[Shift]: Redo (last event)

    ----

    1+[Cmd]: Show/Hide Inspector

    1+[Cmd]+[Ctrl]: $Text pane - Set selected text Red

    ----

    2+[Cmd]: Show/Hide Quickstamp (Document Inspector, Quickstamp tab - focus goes to search box)

    2+[Cmd]+[Ctrl]: $Text pane - Set selected text Green

    ----

    3+[Cmd]: Show/Hide Prototypes (Document Inspector, Prototype tab)

    3+[Cmd]+[Ctrl]: $Text pane - Set selected text Blue

    ----

    4+[Cmd]: Text Only (hide view pane). Focus switches to text pane.

    4+[Cmd]+[Ctrl]: $Text pane - Set selected text Gray/Grey

    ----

    5+[Cmd]: View and Text (show both view and text panes)

    5+[Cmd]+[Ctrl]: $Text pane - Set selected text Black (or $TextFont if not black)

    ----

    6+[Cmd]: View Only (hide text pane). Focus switches to view pane if it was in the text pane

    ----

    7

    ----

    8+[Cmd]: Document Settings

    ----

    9+[Cmd]+[Ctrl]: View ▸ Expand All

    ----

    0+[Cmd]: Standard Scale

    0+[Cmd]+[Ctrl]: View ▸ Collapse All

    ----

    \

    ----

    /+[Cmd]: Insert Short Date (in Note text)

    /+[Cmd]+[Opt]: Insert Short Date and Time (in Note text)

    /+[Cmd]+[Shift]: Open Help Menu (= [Cmd]+[?]) - view pane only

    ----

    :+[Cmd]: Show Spelling and Grammar

    ----

    ;+[Cmd]: Check Document Now (for spelling)

    ----

    ,+[Cmd]: Tinderbox Preferences

    ----

    `+[Cmd]: Send Behind (Cycle Open Windows)

    `+[Cmd]+[Shift]: Send Behind, reverse order (Cycle Open Windows)

    ----

    ' (single quote)

    '+[Cmd]: Go Back. Navigate back along last traversed link.

    ----

    - (use hyphen/minus key or number pad minus key)

    -+[Cmd]: Shrink

    -+[Cmd]+[Shift]: Strikethrough

    ----

    .+[Cmd]: Cancel Export (during HTML or text export)

    ----

    ?+[Cmd]: Open Help menu (= [Cmd]+[Shift]+[/])

    ----

    =+[Cmd]: Magnify

    =+[Cmd]+[Ctrl]: Update Now (Agents). Also updates all edicts, once.

    ----

    [+[Cmd]+[Opt]: Previous Tab

    ----

    ]+[Cmd]+[Opt]: Next Tab

    ----

    {+[Cmd]: Align Left

    ----

    }+[Cmd]: Align Right

    ----

    |+[Cmd]: Align Center

    ----

    Spacebar - View pane: Set cursor focus in text pane

    Spacebar+[Cmd]+[Ctrl]: Show the system Special Characters dialog ('Emoji & symbols')

    Spacebar - Displayed Attributes table or Get Info/attributes: Toggle state of boolean attribute

    ----

    Left Arrow: Select Previous Sibling Note - Outline Order (Map)

    Left Arrow: Select Parent (Chart).

    Left Arrow: Collapses the selected note if expanded. Otherwise, it selects the parent of the selected note if the parent is visible in the view (Outline).

    Left Arrow+[Cmd]: Move cursor to start of line (in $Text pane)

    Left Arrow+[Cmd]+[Shift]: Extend selection to start of line (in $Text pane)

    Left Arrow+[Opt]: Move cursor to start of current word, then start of previous word (in $Text pane)

    Left Arrow+[Fn]: Outline view, go to Home (top)

    ----

    Right Arrow: Select Next Sibling Note - Outline Order (Map)

    Right Arrow: Select First Child (Outline & Chart) - or collapse container if no child; expands the selected container note

    Right Arrow+[Cmd]: Move cursor to end of line (in $Text pane)

    Right Arrow+[Cmd]+[Shift]: Extend selection to end of line (in $Text pane)

    Right Arrow+[Cmd]+[Ctrl]: Expand Horizontally

    Right Arrow+[Opt]: Move cursor to end of current word, then end of next word (in $Text pane)

    Right Arrow+[Fn]: Outline view, go to End (bottom)

    ----

    Up Arrow: Expand View (Map)

    Up Arrow: Select Previous (Visible) Note (Outline & Chart)

    Up Arrow: Select First (Visible) Note (Outline, if no note selected)

    Up Arrow+[Cmd]: Move Note Up (Chart/Outline)

    Up Arrow+[Cmd]: Expand View (Map)

    Up Arrow+[Cmd]+[selection]: Expand View (other view types)

    Up Arrow+[Ctrl]: Scroll Page Up

    Up Arrow+[Shift]: Extend Outline view selection upwards by one note

    Up Arrow+[Cmd]+[Opt]: Text pane focus: select previous $OutlineOrder item in view pane (Outline/Chart/Treemap view—possibly some other views)

    Up Arrow+[Cmd]+[Opt]: Expand view (Map view)

    Up Arrow+[Cmd]+[Shift]: Move To Front

    Up Arrow+[Cmd]: Move cursor to start of $Text (in $Text pane)

    Up Arrow+[Cmd]+[Shift]: Extend selection to start of $Text (in $Text pane)

    Up Arrow+[Opt]: Move cursor to beginning of current paragraph, then beginning of previous paragraph (in $Text pane)

    Up Arrow+[Fn]: Outline view, scroll one page (screen) up

    ----

    Down Arrow: Drill Down (Map - with a note icon selected)

    Down Arrow: Select Next (Visible) Note (Outline & Chart)

    Down Arrow: Select First (Visible) Note (Outline, if no note selected)

    Down Arrow+[Cmd]: Move Note Down (Chart/Outline)

    Down Arrow+[Cmd]: Map view + selection: Drill Down

    Down Arrow+[Ctrl]: Scroll Page Down

    Down Arrow+[Shift]: Extend Outline view selection downwards by one note

    Down Arrow+[Cmd]+[Opt]: Text pane focus: select next $OutlineOrder item in view pane (Outline/Chart/Treemap view—possibly some other views)

    Down Arrow+[Cmd]+[Opt]: Drill Down (Map)

    Down Arrow+[Cmd]+[Ctrl]: Expand Vertically

    Down Arrow+[Cmd]+[Shift]: Send To Back

    Down Arrow+[Cmd]: Move cursor to end of $Text (in $Text pane)

    Down Arrow+[Cmd]+[Shift]: Extend selection to end of $Text (in $Text pane)

    Down Arrow+[Opt]: Move cursor to end of current paragraph, then end of next paragraph (in $Text pane)

    Down Arrow+[Fn]: Outline view, scroll one page (screen) down

    ----

    Delete Back: Backspace key

    Delete Back - Outline: Delete current item and select next item

    Delete Back+[Cmd]: $Text area - Delete to beginning of line (from cursor)

    Delete Back+[Opt]: $Text area - Delete to beginning of word (from cursor) or delete previous word

    ----

    Delete Forward: if no key, use Delete key ( extended keyboard) or [Fn]+Backspace on laptop or wireless keyboards

    Delete Forward - Outline: Delete current item and select next item

    Delete Forward+[Cmd]: $Text area - Delete to end of line (from cursor)

    Delete Forward+[Opt]: $Text area - Delete to end of word (from cursor) or delete next word

    ----

    Return: Create Note (as next sibling)

    Return: Edit-in-place mode: Exit mode

    Return: Map view: create new note to right of current selection

    Return: Roadmap: follow and set focus on selected link

    Return+[Cmd]: Navigate (forwards). Follow the first listed link in Browse Links

    Return+[Shift]: Create child note as last sibling

    Return+[Shift]: Edit-in-place mode: exit and create a new note

    Return+[Opt]+[Ctrl]: Create new note below selected note (Map view)

    Return+[Ctrl]: Create new note to left of selected note (Map view)

    Return+[Ctrl]: Create note as previous sibling (Outline, Chart view)

    Return+[Cmd]+[Shift]: Rename selected note (enter edit mode)

    Return+[Opt]+[Shift]: Create child note as first sibling

    Return+[Cmd]+[Opt]+[Ctrl]: Split the current note at the insertion cursor position (focus in $Text area of text pane)

    Return+[Fn]: Rename selected note (enter edit mode)

    ----

    Double-click: Create Note (in Outline/Map/Chart when no note selected)

    Double-click: Edit note's title (in Outline/Map/Chart when a note selected. Also, note a different result if an Outline icon is double-clicked as the view is hoisted)

    Double-click+[Outline Note icon]: Focus view ('Hoist' in older versions)

    Double-click+Roadmap (clicking in in/outbound link lists): shift view focus to destination note

    Double-click+[selected Map container icon]: Drill down (double click must be in viewport area of icon)

    ----

    Tab - Outline: Demote current selection

    Tab: Roadmap: cycles from first inbound link → first outbound link → link type → etc.

    Tab+[Opt]: Toggle focus: $Text → first Displayed Attribute → View pane → $Text

    Tab+[Shift]: Outline - Promote current selection

    Tab+[Ctrl]: Select next document tab

    Tab+[Ctrl]+[Shift]: Select previous document tab

    ----

    Enter: Rename selected note (enter edit mode)

    Enter: Enter/Leave Edit-in-place mode (selected note in view pane)

    ----

    Esc: Stop creating a link (when link drag is active)

    Esc: Clear typeahead buffer (major/minor views using typeahead)

    Esc: Edit-in-place mode: exit edit mode, ignore current edits

    Esc: Exit Full Screen mode

    Esc+[Opt]: invoke OS text autocomplete (view and text pane)

    ----

    Home: Scroll $Text to start of note $Text without moving insertion point (in $Text pane)

    ----

    End: Scroll $Text to end of note $Text without moving insertion point (in $Text pane)

    ----

    Page Up: Scroll $Text up one page, by $Text pane size, without moving insertion point (in $Text pane)

    ----

    Page Down: Scroll $Text up down page, by $Text pane size, without moving insertion point (in $Text pane)

    ----

    [Cmd]: Force toggle Select tool

    [Cmd]+drag-select: Select text in read-only notes.

    [Cmd]+drag window edge: resize document window retaining text pane width.

    [Cmd]+[Opt]: Underline links (Note $Text area only)

    [Cmd]+[Shift]+drag: add to container as last ($OutlineOrder) sibling(s); default is to be added as first sibling

    [Cmd]+[Opt]+[click]: (in link anchor text) follow link, i.e. open destination note

    [Cmd]+[Opt]+[Ctrl]: Toggle zoomed-out overview mode (map view only)

    ----

    [Option]: Toggle Select Area tool

    [Option]+[click]: Text pane, click inside $Text link anchor without following link

    [Option]+[drag or click]: View pane, duplicate clicked note (Map, Outline, possibly other views)

    [Option]+[Shift]+[drag or click]: View pane, make alias of clicked note (Map, Outline, possibly other views)

    ----

    [Ctrl]+[click]: Open content menu (OS feature)

    ----

    Outline disclosure triangle+[click]+[Cmd]: Show/hide children of this and all sibling containers after this in $OutlineOrder (toggle)

    Outline disclosure triangle+[click]+[Cmd]+[Opt]: Expand/Collapse All Containers (toggle)

    Outline disclosure triangle+[click]+[Opt]: Expand All Descendants (toggle)

    ----

    View selection+[click]+[Cmd]: Add/remove item

    View selection+[click]+[Shift]: Expand selection

    ----

    Mouse wheel - Vertical Map Scroll

    Mouse wheel+[Shift]: Horizontal Map scroll

    Mouse wheel+[Ctrl]: zoom screen (OS feature: System Prefs ▸ Accessibility)

    ----

    [Outline icon]+[Double-click]: Focus view ('Hoist' in older versions)

    ----

    Trackpad+[drag]: scroll view

    ----

    [drag]+[Shift]: Timeline view maintain date (horizontal position) dragging between time-bands (Shift must be pressed before commencing drag)

    [drag]+[Shift]: Map view - constrain to horizontal/vertical movement ignoring guides (Shift must be pressed before commencing drag)

    [drag]+[Option]: Map view - resize around current object centre ignoring guides (Option must be pressed before commencing drag) (from v11.5.1)

    [drag]+[Option]+[Shift]: Map view - constrain to horizontal/vertical movement whilst resizing around current object centre (Option and Shift must both be pressed before commencing drag) (from v11.5.1)

    ----

    [fn]: Show/hide OS Emoji & Symbols palette

    ----

    [f5]: Start Dictation (tap key twice for OS Dictation function)

    [f5]: View pane find bar: show suggested autocompletions

    ----

    [Globe]: Show/hide OS Emoji & Symbols palette

    [Globe]+[Ctrl]+← : Move & resize: left

    [Globe]+[Ctrl]+→ : Move & resize: right

    [Globe]+[Ctrl]+↑ : Move & resize: top

    [Globe]+[Ctrl]+↓ : Move & resize: bottom

    [Globe]+[Ctrl]+[Shift]+← : Move & resize: arrange left & right

    [Globe]+[Ctrl]+[Shift]+→ : Move & resize: arrange right & left

    [Globe]+[Ctrl]+[Shift]+↑ : Move & resize: arrange top & bottom

    [Globe]+[Ctrl]+[Shift]+↓ : Move & resize: arrange bottom & top

    ----

    [microphone symbol]: (also F5) Start Dictation (tap key twice for OS Dictation function)

    Unicode Codes for Keyboard symbols

    Illustrated are the correct Unicode code numbers for a variety of Mac keyboard related symbols.

    The easiest way to use these via a keyboard is to open System Preferences' International/Language section (name varies with OS version) and in the Input sources list tick the option for "Unicode Hex input"). Then with that input mode selected, type Opt+[number].

    For example: Opt+2318 gives (the Cmd key symbol). Or, to write them a HTML entity codes: .

    When switching input methods, do not forget when done to switch back to your normal language!

    In more recent macOS versions, a triangle icon is replacing the arrow in shortcut renderings

    Examples:

    ⌘ Command (Cmd) U+2318

    ⌥ Option (Opt or Alt) U+2325

    ⌃ Control (Ctrl) U+2303

    ⇧ Shift U+21E7

    ⇪ Caps Lock U+21EA

    ↩ Return U+21A9

    ⌤ Enter U+2324 (laptop keyboards have no Enter key, use Fn+Return)

    ⌫ Delete (Backspace) U+232B

    ⌦ Forward Delete U+2326

    ⎋ Escape (Esc) U+238B

    ⏏ Eject U+23CF

    ⌽ Power U+2333D

    ⇥ Tab U+21E5

    ⇞ Page Up U+21DE

    ⇟ Page Down U+21DF

    ↖ Home U+2196

    ↘ End U+2198

    ← Left Arrow U+2190

    → Right Arrow U+2192

    ↑ Up Arrow U+2191

    ↓ Down Arrow U+2193 

    ▸ Black right pointing small triangle U+25B8 (used for menu ▸ sub-menu indicators)

    fn Function (Fn key): type letters 'fn' U+0066 and U+006E.

    In more recent macOS, the Function and arrow keys are replaced with newer symbols in menus, etc.:

    🌐 Globe Function (old Fn key) U+1F310 (normally rendered in black and white)

    ◀ Left Arrow U+25C0

    ▶ Right Arrow U+25B6

    ▲ Up Arrow U+25C2

    ▼ Down Arrow U+25BC 

    Footnote: in most Mac fonts, Opt+Shift+K will insert the Apple logo, e.g. .

    Shortcuts for typing footnote marker symbols

    The traditional sequences (though inevitably there are different 'traditions' are that footnote marker symbols run, in sequence *, †, ‡, §, ¶, # then loop **, ††, etc. The symbols are normally used in superscript inline in the body text, and the footnote on the normal baseline but in a smaller type size.

    But how do you type these on a Mac? The key presses below are for an en-gb (UK layout) and so may differ, but to check, use the macOS Keyboard Viewer—see below for how to open it. Also note some of these symbols can vary in appearance a lot depending on the font in use. So, to make the above symbols:

    • asterisk: * (Shift+8)
    • dagger: (Option+t)
    • double dagger: (Shift+Option+7)
    • section marker, or 'silcrow': § ('§' key , left of the '1' key)
    • paragraph marker, or 'blind P', or 'pilcrow: (Option+7)
    • hash or pound or number-sign or 'octothorpe': # (Option+3)

    Different languages/areas have different key assignments. The easiest way to see the characters available to be typed when using the Command/Option/Control/Shift keys as modifiers is to open the macOS's Keyboard viewer.

    macOS 'Keyboard viewer' palette. If unsure how to do this, see Apple's instructions: what you need to do so open it depends on the current customisation of your Mac. Once the Keyboard viewer is open, the display of keys update as the modifier keys are pressed to show whet symbol a keypress with output.

    Footnote markers and Markdown. If using footnote symbols in text that also used markdown, do not use the asterisk or hash symbols as these get mis-read as Markdown codes. At the beginning of a line * (bullet item) and # (numbered bullet item) and an asterisk inline in treat indicated the beginning or end of italics. However † through ¶ are safe in this context

    Typing unicode-only symbols. If the desired symbol can't be seen (typed) via the Keyboard viewer, try the Emoji & Symbols palette (Ctrl+Cmd+space), find the desired unicode character and double-click the symbol to type it into your text. See also a list of Unicode values for Apple keyboard symbols such as ⌥ for Option, as listed here.

    Footnotes in Tinderbox. The symbols above are for general typographic use. Tinderbox's system for generating (internal) footnote notes does not use footnote marker symbols.

    Conflicts with other apps

    Occasionally, some users find a Tinderbox keyboard shortcut will fail to work. This may be because other apps running already have control of that shortcut. A good diagnostic start is to close all other apps and try again, as if the shortcut now works then the conflict is with one of those apps. Custom shortcuts can get added to the system so check System Preferences ▸ Keyboard ▸ Shortcuts and scan the list for conflicting assignments.

    Harder to diagnose are conflicts with utilities that run in the background. If they have any visible presence it is often just an icon in the main menu bar, so easily overlooked. A good check for what background apps might be running is found via System Preferences ▸ Users & Groups ▸ [your username] in user list ▸ Login Items.

    Known conflicts are with some of the default settings for 1Password's 'mini' applet. Because of how the latter operates it appears to trump Tinderbox's shortcuts for Note ▸ Make Web Link. If both apps are installed, depending on the users needs, either edit the shortcuts for 1Password Mini (in 1Password's Preferences) or use Tinderbox's menu items instead of the shortcut.

    Tinderbox Application Support folders

    When first run, Tinderbox creates a support folder at ~/Library/Application Support/Tinderbox. This folder can be opened in Finder from within Tinderbox via the Help menu. Since OS 10.8, Apple has hidden the user's Library folder (~/Library) in Finder. To make it easier for the general Mac user to access Tinderbox's support folders, the Help menu's 'Reveal Support Folder in Finder' option will open the folder in a new finder window.

    The folder contains a number of sub-folders. If, for any reason, a sub-folder is missing it can be created manually in Finder, noting that the names are case-sensitive. The default sub-folders are:

    The following legacy sub-folder may exist on older systems/installs:

    The following sub-folder can be added manually:

    Legacy: In v5, deeper nesting of folders is not supported. For instance, all custom badges must be in /badges and not sub folders within that.

    analytics folder

    This folder holds files used by Tinderbox in support of Artificial Intelligence (AI) and Neural-Linguistic Programming (NLP) functions.

    The files are not designed for access by the user and this folder should treated as a read-only space for the application's use only.

    backups folder

    This is not used /created by the current app version.

    Users who have had/still have installed older versions of Tinderbox may have this support folder:

    ~/Library/Application Support/Tinderbox/backups/ 

    If not using older versions this folder and its contents may be deleted. It is effectively deprecated. The task is taken over by versioning built into the app (and do not overlook time Machine as another form of recovery back-up).

    To make it easier for the general Mac user to access Tinderbox's support folders, the Help menu's 'Reveal Support Folder in Finder' option will open the folder in a new finder window.

    badges folder

    To make it easier for the general Mac user to access Tinderbox's support folders, the Help menu's 'Reveal Support Folder in Finder' option will open the folder in a new finder window.

    Custom Badge artwork

    The internally packaged image files used by the $Badge attribute for icon badges may be supplemented by adding icon files to the folder:

    ~/Library/Application Support/Tinderbox/badges 

    This folder is automatically created. In older versions, if the /badges/ directory is not automatically created by Tinderbox on installation, so simply create it manually (note that all the folder names in the path are case-sensitive). Tinderbox polls the '/badges/' folder whenever the Badges menu is called so newly added files will be seen immediately.

    To separate out separate sets of artwork, e.g. for different projects, collections of badge files can be placed in discrete sub-folders inside the 'badges' folder. In such cases, the folder shows as a new tab on the badge picker pop-over.

    Badges are square PNG format files (transparency is supported). The app's default sets use 32 x 32 pixel artwork which is displayed in most views at 16x16px. $BadgeSize can be used to override this.

    The name of a custom badge shown in the Badges menu is name of the custom badge icon file minus the extension, and is case-sensitive. So, the custom badge file 'car.png' will have the badge name 'car'. The naming convention of the built-in badge names is single lowercase words. It appears that if setting $Badge via action code the name string is case-insensitive.

    If a custom and built-in badge name clash, the first listed (the custom one) will be used.

    color schemes folder

    This folder is at:

    ~/Library/Application Support/Tinderbox/color schemes 

    This folder is used to hold custom colour scheme (TBC) files that are then available for use in any Tinderbox file via the Document Settings' Colors tab. The name of the colour scheme will be the name of the TBC file.

    If a TBC is added while a document is open, it is necessary to re-open the app in order that the Document Settings' Colors tab lists the new scheme.

    To make it easier for the general Mac user to access Tinderbox's support folders, the Help menu's 'Reveal Support Folder in Finder' option will open the folder in a new finder window.

    config folder

    Used for holding custom config.xml file (the folder is empty by default) or other custom configuration files.

    To make it easier for the general Mac user to access Tinderbox's support folders, the Help menu's 'Reveal Support Folder in Finder' option will open the folder in a new finder window.

    favorites folder

    Changing from earlier use, the 'favorites' folder is used to provide a stationery file (see below) type of service for any file in that folder.

    The 'favorites' folder name is case sensitive and is found at

    ~/Library/Application Support/Tinderbox/favorites/ 

    TBX files or aliases of TBX files placed in the folder are automatically added to the File menu's 'Open Favorites…' sub-menu. Items remain listed in the menu until removed from the folder. This ensures such files are always available whether recently used or not.

    Files opened directly from this folder, or indirectly via an alias, are opened as unsaved copies of the source file and given the name 'untitled.tbx'. This simulates the old Mac stationery file behaviour.

    To make it easier for the general Mac user to access Tinderbox's support folders, the Help menu's 'Reveal Support Folder in Finder' option will open the folder in a new finder window.

    What are stationery files and why the change in Tinderbox behaviour?

    The Mac's notion of a 'stationery file' is one that acts like a stationery pad: for a fresh copy you take the top item, i.e. the file acts as a template. Thus files that are set in the OS as stationery files (via a tick box on the their Finder/Get Info dialog), will open an unsaved copy of the file with an 'untitled' filename.

    This OS behaviour exists (as at macOS 10.15.1) when manually opening such a file in Finder. However, the API allowing programatic creation of a copy a stationery file has been deprecated and cannot be relied upon its use.

    Thus current Tinderbox behaviour is to treat all files in the folder as if they were stationery files regardless of the actual OS setting.

    So how is a stationery file edited?

    IMPORTANT: do not use the File ▸ Favorites menu for this task or you will edit a copy of the original!

    First check whether the TBX is itself flagged to the OS as a stationery file. Longtime users are more likely to have TBX set as stationery file. To check status:

    • use the menu Help ▸ Reveal support Folder In Finder.
    • in the window that opens select the 'favorites' sub-folder. This should show all the files you normally see in you File ▸ Favorites menu.
    • in the finder window select the file you wish to edit and then Get Info (⌘+⌥+I).
      • if the desired file is an alias, first find the original of the alias in its true Finder location
    • in the 'General' section of the Finder's Get Info dialog (expand the section if collapsed), there are two tick-boxes, one titled 'Stationery pad'.
    • if the box is ticked, you will need to un-tick it before you can edit.

    Once assured the original TBX is not set in the OS as a stationery file—something only likely for longer term users—it can be edited:

    • open the TBX in situ directly from Finder.
    • make any edits, save and close.
    • open the same file but via the Favorites menu and ensure the new unsaved file created shows the recent edits.

    Is it necessary to re-apply the OS stationery flag if it was originally set (above)? For this 'favorite' file use within Tinderbox, no, but the user may have it so set for other reasons so act accordingly.

    Legacy only(!): use of aliases

    Unlike in older versions (pre v6?) of Tinderbox, the 'favorites' folder cannot be used to store (or alias) files you wish to edit directly. Previously, aliases files were handled differently. By placing aliases in this folder rather than the TBX file itself, the TBX can be kept in a more obvious location (such as within the ~/Documents/ folder hierarchy). A Mac alias can even track the file if moved around the same disk.

    fill folder

    The 'fill' folder name is case sensitive' and it found at:

    ~/Library/Application Support/Tinderbox/fill/ 

    The folder holds any custom fill files (see below) used for map view backgrounds or map note icons.

    The Fill folder and its subfolders may contain aliases of image files as well as the images themselves.

    To make it easier for the general Mac user to access Tinderbox's support folders, the Help menu's 'Reveal Support Folder in Finder' option will open the folder in a new Finder window.

    Custom Fill artwork

    The internally packaged image files used for $Fill textures for map icons and map backgrounds ($MapBackgroundFill) may be supplemented by adding RGB colour bitmap image files in JPG (.jpeg, .jpg) or PNG (.png) format to the fills folder ~/Library/Application Support/Tinderbox/fill (create the folder if it does not already exist). It is not necessary to re-start Tinderbox to use a newly added fill. The User Fill folder may also contain folders of image files, e.g. a folder per project.

    Custom fill files will be listed in the Fills pop-up menu.

    Custom fills should be referred to within Tinderbox by their filename minus extension (case-sensitive). Thus a custom fill 'Droplets.jpg' would be set by using a $Fill value of "Droplets" (though the actual name string seems to be case insensitive).

    Markdown folder

    THIS FEATURE IS DISCONTINUED

    Support for legacy markdown stylesheets, stored in this application support sub-folder, was discontinued from v9.5.0 onwards. Any existing such preferred style notes should be moved to /Hints/Preview/style (if necessary, first add the built-in Hints container).


    Legacy info only

    The 'Markdown' folder name is case sensitive' and it found at:

    ~/Library/Application Support/Tinderbox/Markdown/ 

    The folder holds a file style.css which is used to help rendering the in-app preview of Markdown-based notes. The CSS style can be user-edit to customise the otherwise generic HTML styling used in the text Preview mode.

    To make it easier for the general Mac user to access Tinderbox's support folders, the Help menu's 'Reveal Support Folder in Finder' option will open the folder in a new finder window.

    prototypes folder

    This allows for locally shared prototypes are stored as top-level notes in a Tinderbox document named Prototypes.tbx in subfolder "prototypes" of the Tinderbox support folder.

    ~/Library/Application Support/Tinderbox/prototypes/Prototypes.tbx 

    Important points to note:

    • only root-level items are read to the Tinderbox File ▸ Built-In Prototypes menu.
      • items are listed in the menu using the source TBX's $OutlineOrder.
    • all root items are listed whether they are prototypes or not. So only use this document to store prototype notes.
      • if wanting to use the default /Prototypes container when making prototypes, use another TBX and then copy the finished prototype into the root of the Prototypes.tbx file.
    • the Prototypes.tbx file is read at session start. If the Prototypes.tbx file is edited, Tinderbox need to be re-started in order for the changes to be reflected in the Built-In Prototypes menu.

    templates folder

    This can be used to hold export templates for use with any open Tinderbox document. Shared templates are stored as (plain) text files in this folder, and may be added to any document by selecting the file from File ▸ Built-In Templates.

    If a template with that name already exists, the template's text is replaced with the text of the external template file (without any warning).

    Tinderbox File Types

    Tinderbox program icon

    The current Tinderbox application icon was introduced in v11.0.0.

    Data (TBX) Files

    These are the normal Tinderbox data files in which a document's data is kept.

    Filename Extension: '.tbx'

    Icon: White page with the flame from the Tinderbox program icon and 'TBX' beneath it.

    It is to be presumed the '.TBX' extension will also be used as the program's data filename extension for the Windows version, when it arrives.

    Colour Scheme (TBC) Files

    Colour scheme files allow the user to choose a colour scheme from the Document Setting' Colors tab. Colour scheme files also record the text font and map font preferences. Often, choice of font and font size is connected to the choice of colour scheme. Saving additional information helps makes colour schemes more useful.

    Filename Extension: '.tbc'

    Icon: a white page with a wheel of colour chips and the title 'tbc'. Previously, it was a white page with the old Tinderbox program symbol and colour chips down the left side.

    To use/import a colour scheme file simply drag it onto an open Tinderbox document's view pane.

    To save a colour scheme, open the Document Inspector's Colors tab.

    Colour schemes are saved with the current text background colour; previously, this was omitted. Colour schemes also save and restore the current text colour, and the default value of $Color.

    Colour scheme files are normally intended to be dropped into view windows. If a colour scheme file is double-clicked, Tinderbox displays a dialog suggesting that you drop the file in a view window.

    Any TBC files correctly placed within the 'color schemes' folder of Tinderbox application support folder is accessible to open Tinderbox documents via the Document Settings Colors tab. Note TBC added there are not shown for open documents. These must be re-opened to refresh the scheme listing.

    Another, more pervasive way to set custom schemes is to customise the colors.xml configuration file. In this case these custom colour definitions becomes the default TBX colour scheme for any subsequent new TBX files; existing TBXs are unaffected but could be updated by dragging on a similarly defined colour scheme file.

    Creating and saving colour schemes

    Note: It might be good to use a new document for this task

    Alter the existing document so the colours are as you wish. Then use the Colors Inspector to create a colour scheme file.

    What is saved when creating a custom TBC?

    The 29 normally defined named colours, saving both their colour value and hidden state as in the current document. In addition, the following preferences are defined (and by inference the defaults for some Color-type system attributes. these are (values are as for an unmodified new v11.5.0 TBX):

    • mapfont: IdealSansSSm-Book ($NameFont)
    • mapfontsize: 16 ($MapNameSize)
    • textfont: MercurySSm-Book ($TextFont)
    • textsizenew: 16 ($TextFontSize)
    • paragraphspacing: 4 ($ParagraphSpacing)
    • mapbackgroundcolor: #f8fafa ($MapBackgroundColor)
    • mapbackgroundcolor2: #f8fafa ($MapBackgroundAccentColor)
    • mapbackgroundpattern: plain ($MapBackgroundPattern)
    • textbackgroundcolor: white ($TextBackgroundColor)
    • textcolor: black ($TextColor)
    • defaultcolor: 7 (possibly $Color)

    Resetting to defaults

    See Using Colour Scheme TBC files.

    Tinderbox Preferences

    These are the special XML files used to help with the default configuration of new Tinderbox files.

    Filename Extension: n/a

    Icon: A switch alongside the old Tinderbox program icon.

    You are unlikely to encounter this file type directly unless you are creating packages for deploying example projects.

    The normal location for the Preferences file is:

    ~/Library/Preferences/Tinderbox™ Preferences 

    Users wanting to share Preferences between several users of the same Mac may elect to copy/move their Preferences file to:

    /Library/Preferences/Tinderbox™ Preferences 

    Tinderbox checks the latter folder for a Preferences file and if found, uses it in preference to any local version.

    Stamp files

    These are small text files containing one or more discrete action code expressions. The filename is used as the stamp name when importing a file and vice versa for exporting from the Stamps Inspector.

    Filename Extension: '.tbxstamp'

    Icon: an ink stamp with a yellow handle.

    Configuration Files

    These are the special XML files used to help with the configuration of the Tinderbox program.

    Filename Extension: '.xml'

    You are unlikely to encounter this file type directly unless you are trying to alter the program's set-up.

    As an alternate to the files packaged in the Tinderbox application, user-edited versions may be placed at:

    ~/Library/Application Support/Tinderbox/ 

    If the folder does not exist, just create it. If using custom Badges, add a further subfolder to /Tinderbox/ called /badges/.

    This mechanism lets the user override the built-in application configuration settings on a per-user basis. If a configuration file is found in the Application Support file, that version is used in preference to the version stored inside the application bundle. It also saves the user having to make edits inside the application bundle and possibly damaging the application installation as a whole.

    Remember: if you do create local copies of these files and upgrade the program to a new version you are advised to check for changes to the defaults and revise your user-set versions accordingly.

    Tinderbox currently ships with a number of configuration files:

    colors.xml

    This file defines/lists the named colours as seen in a default Tinderbox file. It appears colour values may be defined using any of the supported colour declaration methods: (HTML) name, RGB, hex, HSV. Most of the defaults use hex format declarations. The 'screen' name given to the file is for UI use so, 'red' could be defined as a green!

    Note: if using the Colors Inspector, then the existing value is reported as, and should be altered using, only a hexadecimal value.

    The (inclusion of and) order of colours seen in UI listings is in bit-wise alphabetical order, i.e. all initial uppercase words come first (i.e. 'Yellow' sorts before 'blue'). This is regardless of the order as defined in XML. But if coding such a custom file by hand, it makes common sense to list the colours in the order they will sort in the UI.

    The application should be re-started after editing these files to ensure changes are detected. At minimum, the document(s) needing to show the change should be re-opened, should an app re-start be inconvenient at that time.

    The source (app internal) copy of colors.xml defines these colours:

    <colors version="1">
    <color name="normal" />
    <color name="black" color="#000000"/>
    <color name="white" color="#FFFFFF"/>
    <color name="poppy" color="hsv(40,60,100)"/>
    <color name="blue" color="#003366"/>
    <color name="bright blue" color="#0000FF"/>
    <color name="cyan" color="#006666"/>
    <color name="green" color="#009900"/>
    <color name="bright green" color="#00FF00"/>
    <color name="magenta" color="#660066"/>
    <color name="red" color="#990000"/>
    <color name="bright red" color="#FF0000"/>
    <color name="orange" color="#FF8800"/>
    <color name="yellow" color="#CCCC00"/>
    <color name="violet" color="#330099"/>
    <color name="warm gray" color="#807060"/>
    <color name="warm gray dark" color="#605850"/> 
    <color name="cool gray" color="#607080"/>
    <color name="cool gray dark" color="#505860"/>
    
    <color name="0" color="hsv(30, 2, 48)"/>
    <color name="1" color="hsv(30, 2, 63)"/>
    <color name="2" color="hsv(30, 2, 72)"/>
    <color name="3" color="hsv(30, 2, 78)"/>
    <color name="4" color="hsv(30, 2, 83)"/>
    <color name="5" color="hsv(30, 2, 87)"/>
    <color name="6" color="hsv(30, 2, 90)"/>
    <color name="7" color="hsv(30, 2, 93)"/>
    <color name="8" color="hsv(30, 2, 95.6)"/>
    <color name="9" color="hsv(30, 2, 98)"/>
    
    </colors>

    Notes:

    • the named colour 'gray' appears to have never been added to this core listing. This is like due to the fact that the default-applied colour scheme for ucrrent new TBXs ('Modern') define this named colour, so adding it to the basic set of named colours.
    • colour 'poppy' and those named '0' through '9' are defined using the hsv() operator. Poppy appears to have been added to the named colors after inital release, possibly c. v2.1.0.
    • colours 'violet' and those named '0' through '9' were added in v6.0.0.
    • although the Tinderbox UI uses lowercase letters in hexadecimal code value, the codes are case-insensitive and this older data uses uppercase letters in colour values.

    config.xml

    Use of this feature by non-expert users is not advised.

    By default, there is no config.xml file, but a user may create a one so as to override:

    • a small number of configuration settings currently not included in the document's Document Settings as well a limited range. Most settings relate to weblogs (now moribund) and RSS but two are for general use:
      • RecentFileLimit. The number of recently used files to list. Default is 7.
      • UniqueValueLimit. The maximum allowable number of discrete values for string-based attribute value lists. The current default is 999. If the limit is exceeded the attribute pop-up list is not shown.
    • a limited range of options available in Document Settings (the supported items are not documented).

    The default content config.xml (as in the app package):

    <config version="2">
    	<RecentPostLimit> 25 </RecentPostLimit>
    	<RecentFileLimit> 7 </RecentFileLimit>
    	<UniqueValueLimit> 999 </UniqueValueLimit>
    	<TechnoratiServer>http://rpc.technorati.com/rpc/ping</TechnoratiServer>
    	<TechnoratiMethod>weblogUpdates.ping</TechnoratiMethod>
    	<WeblogsComServer>http://rpc.weblogs.com/RPC2</WeblogsComServer>
    	<WeblogsComMethod>weblogUpdates.ping</WeblogsComMethod>
    	<FeedsterServer>http://api.feedster.com/ping</FeedsterServer>
    	<FeedsterMethod>weblogUpdates.ping</FeedsterMethod>
    	<GoogleServer>http://blogsearch.google.com/ping/RPC2</GoogleServer>
    	<GoogleMethod>weblogUpdates.extendedPing</GoogleMethod>
    </config>

    If created, a custom config.xml file is stored in the config sub-folder of the Tinderbox Support folder. Tinderbox should be re-started after editing this file to ensure changes are detected.

    When Tinderbox reads a custom config.xml from the application support folder, it first initialises the configuration to the built-in config.xml. Formerly, configurations left unspecified in the custom file used undocumented defaults.

    Two further elements may be overridden in config.xml. The default font name sets the default $TextFont for newly-created documents, and the text size (in points) sets the relative $TextFontSize. For instance:

    <TextFont>Helvetica Neue</TextFont>
    <NewTextSize>20</NewTextSize>

    The Outline view 'Darker colors' Document Settings option may be overridden at app level by adding this to the config.xml:

    <DarkenOutlineColors> 0</DarkenOutlineColors> 

    Legacy issues

    The older <TextSize> which used numbered codes for size was superseded by—and trumped by, if both are found—the <NewTextSize> specified in point size, i.e. '16' for 16-point text.

    html_helpers.xml

    This file is a list of programs that can be configured in HTML Preferences as the associated applications for editing HTML files output by Tinderbox. The file is a list of application names and their macOS 'creator' strings.

    Thus, to add a new HTML Editor/Viewer as a 'helper' you need to know its macOS 'creator' string and decide on the text you want for the on-screen name. The files will look something like this (without the XML comment):

    <helper> 
       <!-- a list of helpers -->
       <helper name="Firefox" signature="MOZB" />
    </helpers>

    The second line above defines 'Firefox' as a helper and this is the name you see in pop-up lists on the program. Under the hood, the creator type of 'MOZB' is passed to the macOS. It shows the syntax of the line you should follow when adding new helpers. In the following example, the Mac Browser Camino is added as a new helper, by inserting a new 'helper name' XML entity anywhere inside the tags. The helper apps are listed in HTML preferences the order used in the file:

    <helpers> 
       <helper name="Firefox" signature="MOZB" />
       <helper name="Camino" signature="MOZC" />
    </helpers>

    The order in which the 'helper name' entities are listed in the XML is the order in which the helpers are listed in Tinderbox's helper pop-ups.

    The application should be re-started after editing these files to ensure changes are detected.

    linkTypes.xml

    This file describes/defines the default set of link types for use in Tinderbox files. A colour may also be defined: the default is black (#000000). Visibility of individual types in map views may not be set here but should be done via the Link Types pane of the Attributes dialog.

    Do not forget you can save your customised files outside the application, rather than overwriting the application's default file inside the package.

    The application should be re-started after editing these files to ensure changes are detected.

    Hierarchy of inheritance

    The link types included in a new TBX file are defined by the 'linkTypes.xml' file. This file resides inside the Tinderbox application package (i.e. most users will never see it). To assist the user Tinderbox also checks this location:

    ~/Library/Application Support/Tinderbox/ 

    …and if a copy of the file is found there, then it takes precedence over the application's default version of the file. Note: if the folder does not exist, just make one of the appropriate name. As Tinderbox offers is this 'external' location, more safely accessible to the user, you are advised to use the latter for customisation of link types. This avoids the possibility of a mistaken edit inside the application package that might upset Tinderbox as a whole.

    File syntax

    This is the default set of link types:

    <linkTypes version="1">
       <link name="*untitled" label="" color="#000000" required="true" />
       <link name="prototype" color="#993333" required="true" />
       <link name="note" color="#666666" required="true" />
       <link name="note+" color="#444444" required="true" />
       <link name="agree" color="#000000" />
       <link name="disagree" color="#000000" />
       <link name="clarify" color="#000000" />
       <
       <
       <link name="exception" color="#000000" />
       <link name="response" color="#000000" />
    </linkTypes>

    The full allowable <link> syntax is this:

    <linkType name="*untitled" label="" visible="1" showLabel="0" color="#000000" style="0" required="true" /> 

    The 'showLabel' and 'style' arguments were added after the original configuration. So, although the application defaults (above) do not use these additions you may safely use them in custom link files.

    Note that 'internal' links such as basic links and text links can have 'target', 'title' and 'class' info set via the create/browse links dialogs just you would with an 'external' (web) link. This is pertinent if the data is to be exported as HTML.

    Syntax for linkTypes.xml file:

    linkTypes

    <linkTypes> … </linkTypes>

    Occurs: Once

    Multiple instances: No.

    Has attributes: No.

    Is container: Yes.

    Self-closing: No.

    This element acts as a wrapper for all file content.

    Example:

    <linkTypes version="1">
       <linkType name="*untitled" label="" visible="1" showLabel="0" color="#000000" style="0" />
      <link name="note" visible="1" showLabel="1" color="#666666" style="0" />
    </linkTypes>

    stoplist.txt

    The list of common English words used by the Common Words view for exclusions is found in Contents/Resources/config/stoplist.txt within the Tinderbox app package. It can be overridden at app level by a customised user version in:

    ~/Library/Application Support/Tinderbox/stoplist.txt 

    Note this feature is essentially replaced by the use of the stoplist in the Built-in Hints container, if the latter is used.

    The file is a plain text file, one word per line, all lower-case. The reason the word doesn't seems to appears twice is to allow for straight and typographic ('curly') variants of the apostrophe character. This is the default list:

    about

    after

    also

    because

    been

    corp

    could

    does

    doesn

    doesn't

    doesn’t

    each

    even

    from

    have

    here

    indent

    into

    it's

    it’s

    just

    last

    like

    many

    might

    more

    most

    much

    only

    other

    over

    perhaps

    says

    seem

    seems

    should

    some

    still

    such

    than

    that

    their

    them

    then

    there

    these

    they

    those

    this

    though

    through

    very

    well

    were

    what

    when

    where

    which

    while

    will

    with

    would

    year

    years

    your

    of

    to

    in

    it

    is

    be

    as

    at

    so

    we

    he

    by

    or

    on

    do

    if

    me

    my

    up

    an

    go

    no

    us

    am

    the

    and

    for

    are

    but

    not

    you

    all

    any

    can

    had

    her

    was

    one

    our

    out

    day

    get

    has

    him

    his

    how

    man

    new

    now

    old

    see

    two

    way

    who

    boy

    did

    its

    let

    put

    say

    she

    too

    use

    don

    ve

    re

    jpg

    gif

    htm

    html

    Other Support Files

    Eastgate have made a few other assets such as icon artwork accessible for those users who may wish to change them:

    Lock and sticky icon artwork

    The $Sticky attribute pushpin and $Lock attribute adornment icons are packaged separately in the application bundle, making it easier to customise them. These files are stored at:

    /Applications/Tinderbox 11.app/Contents/Resources/elements/ 

    The files are of type '.icns', i.e. macOS icon files:

    • locked.icns
    • sticky.icns
    • unlocked.icns
    • unsticky.icns

    RSS Import Templates

    Two RSS templates are included, one for the overall (channel) feed and one for each item. These are for RSS import purposes and ought not to require user edits, but it is understood they are allowed.

    Channel template:-

    ^title^
    ^link
    ^subtitle
    ^description
        <-- blank line here
    

    Item template:-

    ^title
    ^link
    ^description
    

    It appears that user created templates, as placed in the user configuration files folder, are not supported. If editing is required, it is thus necessary to edit the actual templates in the application package.

    The mark-up is like HTML export codes but syntax is slightly different. Although the built-in examples do not use closing ^ carets, if editing it is suggested you do so.

    From the above example, known RSS import compatible codes are:

    ^title^

    ^subtitle^

    ^link^

    ^description^

    Exactly how these codes map to RSS/Atom feed codes is not documented.

    Syntax Library

    Note: most users are unlikely to need to read this section. Also, an understanding of XML syntax is assumed.

    Tinderbox has several features that may be of interest to those trying to produce for and support other Tinderbox users:

    The XML TBX format

    This section describes the XML source data in a TBX file.

    WARNING. This is not formal vendor documentation of the format. Always work with back-ups. If doing significant interchange to from TBX files via some other workflow you may well need to contact technical support at some point. However, this section should still give you a good overview of the TBX file as used with Tinderbox v6+: the structure illustrated is as at v11.5.0.

    Changes to the XML data written occur unannounced (reflecting new/updated features) so this part of aTbRef is likely to lag the XML seen in new TBX.

    A TBX file can be opened and read in any competent text.code editing app. The file's data is valid XML in UTF-8 encoding and using Unix-style (line feed character) line endings. Thus much of the data can be read 'by eye' in source from. The only real exception to this is the RTFD versions of notes' text. An un-styled plain text version of the $Text is stored so can still be read, albeit without stylistic markup.

    However, to keep the data file slim, inherited values are not stored for every note. Rather, notes only store intrinsic attributes and those set locally in that note.

    This section is structured to read like the TBX data structure with similar nesting of notes. When reading this, it is useful to also open a TBX in your code editor for reference.

    Note that in general, tags write their internal tag attributes in the same order in each case (not the case in early versions of the app), though you may still discover otherwise, so treat that assumption as tentative.

    The top level objects of the XML (TBX) file:

    XML tag

    The first object is the XML descriptor:

    <?xml version="1.0" encoding="UTF-8" ?> 

    The xml tag is a standard tag identifying the XML version and encoding type (UTF-8).

    The only other root level tag is the tinderbox tag, which encloses the file data.

    tinderbox tag

    The 'tinderbox' tag wraps the overall data:

    <tinderbox version="2" revision="15" savedBy="version 9.6.0 b627" uuid="5FD9193F-D2E3-4849-B7DE-C4D759536C01" >
    [data]
    </tinderbox>

    version. The (presumed) structural version of the TBX file: a number. Version '1' represnted the p

    revision. The (presumed) revision version of file version: a number

    savedBy. The Tinderbox release (version number) that created or last saved the current file. So, on creation it is the creating app version. Then, each subsequent save updates the value if a more recent release is used. Originally just the version number, e.g. 5.11.1, and currently version number and build number as well , e.g. version 9.6.0 b627.

    uuid. A unique identifying number for this file to assist with external access/identification: an alphanumeric hash string. Be aware that copying/duplicating a TBX in Finder does not cause a new UUID to be generated. Using File ▸ Save As within Tinderbox will cause the saved file to have a new discrete UUID. This feature was originally introduced to assist experiments with linking between TBX files, in v9.6.0.

    The 'tinderbox' object contains a number of standard child tags:

    attrib tag

    The <attrib> tag is a direct child of the tinderbox tag.

    It holds a set of nested <attrib> tags representing the hierarchy of both System attributes and, if any, User(-created) attributes.

    <attrib Name="anything" editable="0" visibleInEditor="1" default="" >[nested <attrib> tags or empty]</attrib> 

    The hierarchy nests thus:

    • all attributes
      • System Attributes
        • System Attribute Groups (one or more)
          • Individual System attribute (one or more)
      • User attributes
        • Individual User attribute (one or more, when created by user)

    There are no attribute groups within the User attributes.

    The <attrib> tag attributes are fully described here.

    This has two nested child tags, representing:

    attrib - system

    A child of the main attrib <attrib> tag object.

    <attrib Name="System" parent="anything" editable="0" visibleInEditor="1" default="" ></attrib> 

    There are 27 groups visible to the user in the UI. There is one totally hidden group, "Internal", containing 4 attributes.

    The object contains a list of all the groups (the Internal group is described separately here).

    attrib - [groupname]

    A child of the System <attrib> tag object. For example, for the 'Agent' group:

    <attrib Name="Agent" parent="System" editable="0" visibleInEditor="1" type="4" default="false" ></attrib> 

    This object contains a list of attributes defined within the group.

    attrib - attribute

    Each Tinderbox attribute, both internal-only and those exposed to the user, are defined by a single attribute tag, which is a leaf object with no children. All Tinderbox data objects have all attribute's even if they cannot make use of them, e.g. $AgentQuery can be set to a note but does nothing. Attributes are all defined with a standard set of tag attributes. For example:

    <attrib Name="OutboundLinkCount" parent="General" editable="0" visibleInEditor="1" type="2" canInherit="0" default="0" >
    </attrib>
    

    Name. The (screen/action code) name of the attribute. "anything " reserved for the root <attrib> tag.

    parent. All <attrib> tags except the root one have a parent value which is the Name of its parent <attrib> tag.

    editable. Number: zero or one. A '0' implies the attribute is calculated and thus read-only so cannot be set via UI or action code. A '1' implies the user can edit the attribute's value

    visibleInEditor. Number: zero or one. Is this attribute visible in the program's UI? A '0' implies no, a '1' implies yes.

    kind. A number. Purpose uncertain but appears to indicate the attribute inherits from a preference; the number is not the order of the preference in source. Note: these mappings have varied over time. Attributes using kind are:

    type. A number: the Tinderbox data type. If the value is zero the attribute is not saved, i.e. if this attribute is missing its value must be assumed to be zero; string is this the default type. These numbers are a 0-based count of the ordering seen in the data-type popup list in the 'User' tab of the Document Inspector. Values:

    • 0 string (the XML attribute 'type' is omitted if the value is 0, i.e. the default)
    • 1 color
    • 2 number
    • 3 file
    • 4 boolean
    • 5 date
    • 6 unsigned (only used for unseen internal system attribute 'Alias')
    • 7 action (action-type only available for system attributes)
    • 8 set
    • 9 url

    *10 list

    canInherit. Number: zero or one. Only present if value is '0'. If missing, assume a value of '1'. Presumably a zero value implies the attribute is intrinsic. Only used for System attributes.

    description. Only used for User attributes (v6+). String: default empty. The optional text description about a user attribute. Entered/edited via the Document Inspector's User tab.

    default. A specific value, otherwise that data-type's normal application-default value.


    The Internal attribute group

    The Internal group defines 4 hidden attributes: $Alias, $EntryScript, $ExitScript, $WindowPlace. None are seen in the UI and the user should not attempt to script them via action code. $Alias is only used in item or agent objects that are aliases. Thus in the XML, the presence of the $Alias attribute in an object indicates the object is an alias rather than a normal note. In such contexts, the value of $Alias will be the $ID of its original note.

    System Attributes: 'Internal' group

    The System attributes' groups, as defined in a default TBX, include an 'Internal' group. This group of attributes are not exposed via the Tinderbox user interface but appear to be a standard part of the TBX document defaults for internal use via the app. The exact purpose of all the following is unknown and users should not attempt to use or alter these:

    • $Alias.
    • $EntryScript.
    • $ExitScript.
    • $WindowPlace. Likely used in v5 but not since v6.
    attrib - user

    A child of the main attrib <attrib> tag object.

    <attrib Name="User" parent="anything" editable="0" visibleInEditor="1" default="" ></attrib> 

    Unlike the System attributes, there are no subgroups, just a list of individual user-created attributes. Non-exhaustive test would suggest, the Tinderbox will allow groups within User attributes but that they can only be created in the TBX source and not via the UI. However, if created, they work, except in the Inspector (quickstamp pane).

    attrib - attribute

    Each Tinderbox attribute, both internal-only and those exposed to the user, are defined by a single attribute tag, which is a leaf object with no children. All Tinderbox data objects have all attribute's even if they cannot make use of them, e.g. $AgentQuery can be set to a note but does nothing. Attributes are all defined with a standard set of tag attributes. For example:

    <attrib Name="OutboundLinkCount" parent="General" editable="0" visibleInEditor="1" type="2" canInherit="0" default="0" >
    </attrib>
    

    Name. The (screen/action code) name of the attribute. "anything " reserved for the root <attrib> tag.

    parent. All <attrib> tags except the root one have a parent value which is the Name of its parent <attrib> tag.

    editable. Number: zero or one. A '0' implies the attribute is calculated and thus read-only so cannot be set via UI or action code. A '1' implies the user can edit the attribute's value

    visibleInEditor. Number: zero or one. Is this attribute visible in the program's UI? A '0' implies no, a '1' implies yes.

    kind. A number. Purpose uncertain but appears to indicate the attribute inherits from a preference; the number is not the order of the preference in source. Note: these mappings have varied over time. Attributes using kind are:

    type. A number: the Tinderbox data type. If the value is zero the attribute is not saved, i.e. if this attribute is missing its value must be assumed to be zero; string is this the default type. These numbers are a 0-based count of the ordering seen in the data-type popup list in the 'User' tab of the Document Inspector. Values:

    • 0 string (the XML attribute 'type' is omitted if the value is 0, i.e. the default)
    • 1 color
    • 2 number
    • 3 file
    • 4 boolean
    • 5 date
    • 6 unsigned (only used for unseen internal system attribute 'Alias')
    • 7 action (action-type only available for system attributes)
    • 8 set
    • 9 url

    *10 list

    canInherit. Number: zero or one. Only present if value is '0'. If missing, assume a value of '1'. Presumably a zero value implies the attribute is intrinsic. Only used for System attributes.

    description. Only used for User attributes (v6+). String: default empty. The optional text description about a user attribute. Entered/edited via the Document Inspector's User tab.

    default. A specific value, otherwise that data-type's normal application-default value.


    The Internal attribute group

    The Internal group defines 4 hidden attributes: $Alias, $EntryScript, $ExitScript, $WindowPlace. None are seen in the UI and the user should not attempt to script them via action code. $Alias is only used in item or agent objects that are aliases. Thus in the XML, the presence of the $Alias attribute in an object indicates the object is an alias rather than a normal note. In such contexts, the value of $Alias will be the $ID of its original note.

    colors tag

    The colors tag is a direct child of the tinderbox tag.

    <colors>[nested <color> tags or empty]</colors> 

    The tag takes no attributes and acts as a container for color tags, i.e. list of defined (named) colours for the current TBX. The list always includes a set of built-in colours. The user may delete or edit these from within the Tinderbox UI as well as save their own new colours.

    color tag

    All defined colours, whether built-in or user-defined have two attributes:

    <color name="cool gray" color="#607080" /> 

    name. A string. The 'name' of the colour: can be anything.

    color. The actual colour used. Stored as a hash-prefixed six-digit hex code.

    linkTypes tag

    The linkTypes tag is a direct child of the tinderbox tag.

    <linkTypes>[nested <linkType> tags or empty]</linkTypes> 

    The tag takes no attributes and acts as a container for linkType tags.

    linkType tag

    A linkType type tag is included for every built-in link type and any user-created ones. If a link type has a link action, then the action's code is stored in an optional child <onLink> tag.

    For example:

    <linkType name="*untitled" label="" visible="1" showLabel="0" color="#000000" colorString="#000000" style="0" /> 

    name. The name used for the linkType in code and type listings.

    label. The name use when a link label is shown in maps.

    visible. Number, zero or one. '1' is visible, '0' means the link is not drawn on screen.

    showLabel. Number, zero or one. '1' is visible, '0' means the link is not drawn on screen.

    color. The colour used to draw link lines. Stored as a hash-prefixed six-digit hex code.

    colorString. A text string, which must be for a defined named color. Otherwise the value of 'color' (above) is used.

    style. A number. This is a binary value representing the various options for line style (dot, dash, broad, etc.) that are UI tickboxes in the Links Inspector. By observation, always 0, zero. Values are additive for options ticked: bold = 128, linear = 64, dashed = 16, dotted = 8, broad = 256 . Thus dashed+broad = 272.

    Child tags:

    (root) item tag

    The item tag is a direct child of the tinderbox tag.

    The top level 'item' tag represents the whole of the user data in the TBX's visible Outline. This 'root' tag has a $Name value of the TBX filename (without the extension). Apart from being the background to root-level major views and thus possibly customised for attributes like $MapBackgroundColour this tag does not behave as source of a normal note. It cannot be displayed via the text pane.

    <item>[nested tags or empty]</item> 

    The tag's own attributes and text tag types are listed in the section below, under the item tag. Links—basic, text and web—are stored separately in the <links> section. In this part of aTbRef an item object refers to item-scoped data which may relate to a note item, an agent, an adornment or an alias.

    Nested in the tag are tags of several types:

    item tag

    The item tag is used to contain a single note (or similar object) of data:

    <item ID="3444070141" Creator="John Doe">[nested outline objects or current item attribute tags]</item> 

    The item tag has two permanent and one optional attributes:

    • ID. The $ID of the object.
    • Creator. The user name set in preferences (and as passed into $Creator).
    • proto. Optional: only set if the note uses a prototype. If it does, the prototype's name (i.e. $Prototype value) is stored here, and not as a child attribute tag.

    Example:

    <item ID="3444070141" Creator="John Doe" proto="Person" ></item> 

    If the note has $Text is stored in discrete nested tags in both plain text and encoded RTFD form.

    Besides nested outline objects, the item may enclose the following per-item attribute-related tags:

    Attributes (default and locally-valued) and composites (if any) precede the two $Text-related tags (if any text). Thus nested objects are the last elements in the item element before its closing tag.

    Attributes, other than the defaults listed below are only written to file if they hold locally set values. Attributes that use preference-default or prototype-inherited values are not stored as these values are calculated on the fly during use. For an item, the following default (intrinsic) attributes are always stored:

    • Name
    • Created
    • Modified
    • Xpos
    • Ypos
    attribute tag

    For any locally-set attribute (i.e. not inherited), any item object stores the value in individual attribute tag(s):

    <attribute name="Created" >2013-02-18T22:09:00+00:00</attribute>
    <attribute name="Modified" >2013-02-18T22:09:00+00:00</attribute>
    <attribute name="Name" >A grandchild</attribute>
    <attribute name="ReadCount" >61</attribute>
    <attribute name="SelectionCount" >45</attribute>

    The example above shows data of several attribute data-types as stored in TBX form. The sole exception to this method of storage is $Text, which is handled in a discrete method of its own.

    $Prototype is an exception and if set is not stored here. Instead it is stored in the optional 'proto' tag attribute in the note's <item> tag.

    An <attribute > tag has one internal attribute: name. This is the 'Name' value defined in an 'attrib' tag elsewhere in the document.

    The value of the attribute is stored as nested content inside the attribute opening/closing tags.

    composites tag

    The composite tag is a direct child of an item tag.

    <composites>[nested <composite> tags or empty]</composites> 

    The tag takes no attributes and acts as a container for tags, if any.

    By default there are no composites in a document. These container elements are created/removed as needed.

    composite tag

    The composite tag is used to contain a single composite object:

    <composite nodes="1481542875 1481542879 " name="Things" instantiates="" > 

    The tag has three attributes:

    • nodes. This is a space delimited list of the IDs of the notes making up the composite.
    • name. The (optional) screen name of the composite.
    • instantiates. Purpose is unknown. An empty string. If manipulating TBX XML directly, still include this attribute.

    Example

    <composite nodes="1481542875 1481542879 " name="Things" instantiates="" > 

    There is no apparent different between 'master' composites and those formed elsewhere. It appears this it is the fact of being stored in the /Composites container is what makes them available for replication.

    text tag

    If $Text is populated, this tag stores the the plain text (0only) of the overall styled text.

    Embedded images in $Text are stored only in the <rtfd> tag's content—image data is not included in this tag.

    Example:

    <text >Hello world.</text>
    <rtfd >cnRmZAAAAAADAAAAAgAAAAcAAABUWFQucnRmAQAAAC7hAAAAKwAAAAEAAADZAAAAe1xydGYxXGFu
    c2lcYW5zaWNwZzEyNTJcY29jb2FydGYxMzQ3XGNvY29hc3VicnRmNTcwCntcZm9udHRibFxmMFxm
    bmlsXGZjaGFyc2V0MCBIZWx2ZXRpY2FOZXVlO30Ke1xjb2xvcnRibDtccmVkMjU1XGdyZWVuMjU1
    XGJsdWUyNTU7XHJlZDBcZ3JlZW4wXGJsdWUwO30KXHBhcmRcdHgzNjBcc2I4MFxzYTgwXHBhcmRp
    cm5hdHVyYWwKClxmMFxmczMyIFxjZjIgSGVsbG8gd29ybGQufQEAAAAjAAAAAQAAAAcAAABUWFQu
    cnRmEAAAAIhdgFW2AQAAAAAAAAAAAAA=
    </rtfd>
    <html><p>Hello world.</p></html>

    Note that the plain text and RTFD versions are always both saved if the note has any $Text.

    rtfd tag

    If text has been set via a rich text view, i.e. the $Text area, the text tag is also stored in RTFD form, even if there is no apparent styling. This example shows a single paragraph of unstyled text "Hello world."(below its plain text stored version):

    <text >Hello world.</text>
    <rtfd >cnRmZAAAAAADAAAAAgAAAAcAAABUWFQucnRmAQAAAC7hAAAAKwAAAAEAAADZAAAAe1xydGYxXGFu
    c2lcYW5zaWNwZzEyNTJcY29jb2FydGYxMzQ3XGNvY29hc3VicnRmNTcwCntcZm9udHRibFxmMFxm
    bmlsXGZjaGFyc2V0MCBIZWx2ZXRpY2FOZXVlO30Ke1xjb2xvcnRibDtccmVkMjU1XGdyZWVuMjU1
    XGJsdWUyNTU7XHJlZDBcZ3JlZW4wXGJsdWUwO30KXHBhcmRcdHgzNjBcc2I4MFxzYTgwXHBhcmRp
    cm5hdHVyYWwKClxmMFxmczMyIFxjZjIgSGVsbG8gd29ybGQufQEAAAAjAAAAAQAAAAcAAABUWFQu
    cnRmEAAAAIhdgFW2AQAAAAAAAAAAAAA=
    </rtfd>
    <html><p>Hello world.</p></html>

    Any inline images are included in the RTFD stream, as base64 encoded data, where they occur in the run of text.

    The <rtfd> tag is always deleted if its associated <text> tag is deleted.

    html tag

    From v11.8.0, Tinderbox files are now saved with additional text information for the used of the experimental Tinderbox Web Reader.

    This example shows a single paragraph of unstyled text "Hello world." with text, rtfd, and html tag content:

    <text >Hello world.</text>
    <rtfd >cnRmZAAAAAADAAAAAgAAAAcAAABUWFQucnRmAQAAAC7hAAAAKwAAAAEAAADZAAAAe1xydGYxXGFu
    c2lcYW5zaWNwZzEyNTJcY29jb2FydGYxMzQ3XGNvY29hc3VicnRmNTcwCntcZm9udHRibFxmMFxm
    bmlsXGZjaGFyc2V0MCBIZWx2ZXRpY2FOZXVlO30Ke1xjb2xvcnRibDtccmVkMjU1XGdyZWVuMjU1
    XGJsdWUyNTU7XHJlZDBcZ3JlZW4wXGJsdWUwO30KXHBhcmRcdHgzNjBcc2I4MFxzYTgwXHBhcmRp
    cm5hdHVyYWwKClxmMFxmczMyIFxjZjIgSGVsbG8gd29ybGQufQEAAAAjAAAAAQAAAAcAAABUWFQu
    cnRmEAAAAIhdgFW2AQAAAAAAAAAAAAA=
    </rtfd>
    <html><p>Hello world.</p></html>

    The html tag is deleted if the note's $Text is deleted.

    adornment tag

    The adornment tag is used to contain a single adornment object:

    <adornment ID="3444053947" Creator="John Doe">[current item attribute tags]</adornment> 

    The adornment tag has two permanent and one optional attributes:

    • ID. The $ID of the object.
    • Creator. The user name set in preferences (and as passed into $Creator).
    • proto. Optional: only set if the note uses a prototype. If it does, the value (the prototype's name) is stored here, and not as a child attribute tag.

    Example:

    <adornment ID="3444053947" Creator="John Doe" >…</adornment> 

    Unlike items or agent tags, adornments never nest other outline objects within themselves.

    See the item tag description for the general range of attributes used.

    Note that adornments cannot display $Text, although they may store a text; the $Text can be read via the text pane as with a normal note.

    Attributes, other than the defaults listed below are only written to file if they hold locally set values. These differ from those of the item tag:

    • Name
    • Created
    • Modified
    • Xpos
    • Ypos
    • Height
    • Width
    • Searchable

    Other elements. Besides the and elements, if $Text is used, there is one other optional element included if the adornment is an image adornment:

    image tag

    The ... element is included in adornments that are image adornments.

    The contents of this element is the image data stored as a JPEG, in Base 64 form (regardless of original source format).

    agent tag

    The agent tag is used to contain a single adornment object:

    <agent ID="3444053947" Creator="John Doe">[current item attribute tags]</agent> 

    The item tag has two permanent and one optional attributes:

    • ID. The $ID of the object.
    • Creator. The user name set in preferences (and as passed into $Creator).
    • proto. Optional: only set if the note uses a prototype. If it does, the value (the prototype's name) is stored here, and not as a child attribute tag.

    Example:

    <agent ID="3444053464" Creator="john Doe" >…</agent> 

    Unlike items or adornments, agents only nest alias objects within themselves, those of the notes matching their query.

    See the item tag description for the general range of attributes used.

    Agents use one special (internal, hidden) attribute: Agent. Since v9.3.0 this now equates to the $IsAgent system attribute. An agent will always include these in its default listing, over and above normal item attributes:

    <attribute name="Agent" >true</attribute> 

    <attribute name="AgentQuery" >[value]</attribute> 

    <attribute name="HTMLExportChildren >false</attribute> 

    <attribute name="IsPrototype" >false</attribute> 

    Attributes, other than the defaults listed below are only written to file if they hold locally set values. These differ from those of the item tag:

    • Name
    • Created
    • Modified
    • Xpos
    • Ypos
    • Agent
    • AgentQuery (even if empty)
    • HTMLExportChildren (uses non-default value: false)
    • IsPrototype (uses default: false, presumably to override possibly inheriting true)
    item (alias)

    Aliases are stored as a normal item tag:

    <item ID="3444054848" Creator="">[current item attribute tags]</item> 

    The item tag has two attributes:

    • ID. The $ID of the object.
    • Creator. As $Creator is intrinsic, this is left blank so as not to conflict with the value of the original).

    Note that unlike a normal note the 'proto' tag attribute is not set, even if a prototyped is used, presumably because $Prototype is not intrinsic (though nor is $Creator).

    Example:

    <item ID="3444054848" Creator="" >…</item> 

    However, unlike normal item or agent tags, aliases never nest other outline objects within themselves. Aliases use, but do not store, their original's prototype.

    Alias status is indicated by the presence of one special (internal, hidden) attribute: Alias. An alias will always include these in its default listing, over and above normal item attributes:

    <attribute name="Alias" >3444070141</attribute> 

    <attribute name="Name" ></attribute> 

    The 'alias' value is the $ID of the original of the alias. The $Name is left blank as this is intrinsic. Instead, the alias inherits the original's name.

    See the item tag description for the general range of attributes used.

    Attributes, other than the defaults listed below are only written to file if they hold locally set values, which in the case of aliases will only ever be intrinsic attributes. For an alias item, the following default (intrinsic) attributes are always stored:

    • Alias
    • Name (set to [no value])
    • Created
    • Modified
    • Xpos
    • Ypos

    macros tag

    The windows tag is a direct child of the tinderbox tag.

    <macros>[nested <macro> tags or empty]</macros> 

    The tag takes no attributes and acts as a container for macro tags, if any. By default there are no macros.

    macro tag

    By default there are no macros. Each macro is a separate tag.

    <macro name="Codify" ><code>$1</code></macro> 

    name. The screen name of the macro.

    [value]. The macro's action code, XML-encoded.

    preferences tag

    The windows tag is a direct child of the tinderbox tag.

    <preferences>[nested preference-name tags or empty]</preferences>

    The tag takes no attributes and acts as a container for individual preference values.

    [preference name] tag

    Each preference's name is used as a tag enclosing its value:

    <ParagraphSpacing > 2</ParagraphSpacing>

    In some cases the data is multi-line:

    <RecentFiles > <files  > <file>Macintosh HD:Users:mwra:TBX:aTbRef24</file> </files></RecentFiles>

    Preference 'Fontmap' data is also stored in multi-line form.

    Colours are stored using 16-bit values (0-65535).

    Some tags will be retained for compatibility with older versions of Tinderbox.

    windows tag

    The windows tag is a direct child of the tinderbox tag.

    <windows>[nested one or more <window> tags]</windows> 

    The tag takes no attributes and acts as a container for window tags, of which there should always be at least one. The tag covers document windows. Stand-alone text windows are stored under the utilityWindows tag. Non-note secondary windows are not fully recorded as these close at session end, though the last used Inspector and Find window X/Y locations are stored under the preferences tag.

    The individual open document windows are listed in front-to-back order, i.e. the first listed is the frontmost in the UI.

    window tag

    The window tag is direct child of the windows tag. It stores all the tabs currently defined for that window:

    Example:

    < bounds="Rect[ 503 243 1403 843]" ruler="0" toolbar="0" > 

    <tabs>[one or more <tab> tags]</tabs> 

    </window>

    bounds. A space delimited array of 4 numbers being the screen pixel {x,y} co-ordinates of the top-left and bottom-right corners of the window.

    ruler. Show/hide state of the ruler in the text pane's $Text area. A value '0' (default) means hidden, '1' means shown.

    toolbar. Show/hide state of the toolbar at the top of the window. A value '0' (default) means hidden, '1' means shown.

    Note that unlike for utility windows, no ID argument is needed.

    tabs tag

    The tabs tag is a direct child of the window tag.

    <tabs>[nested one or more <tab> tags]</tabs> 

    The tag takes no attributes and acts as a container for tab tags, of which there should always be at least one (by default new windows have 2 tabs). The tag holds a set of tags representing each of the tabs in the parent window.

    tab tag

    The <tab> tag is used to define a discrete tab used within a (document) window.

    Note: this file format is not formally published and the tag attributes are subject to ongoing change. The code sample is taken from an actual tab's data but the order of the attributes cannot be assumed to be constant. As such this does not constitute an official specification of the tag.

    <tab selected="0" name="" subtitle="" viewType="0" usingRoadmap="0" hideBreadcrumbs="0" scale="32" ID="1639525654" scrollX="448" scrollY="398" selection="1639406348 " expanded="" textTab="0" splitRatio="0.5" xattribute="Name" xattribute2="Height" xdisplayattribute="DisplayName" xbarattribute="OutlineOrder" xcontainer="" xquery="" xqueryLabel="" xbins="5" xunlimited="0" xbins2="5" xunlimited2="0" xheatmap="0" xReportStyle="0" spacing="0.35" aspect="2" hyperbolicScale="1" path="" focus="1639510536" crosslinks="0" spread="0.5" treepaths="" crosslinkpaths="" hasBorder="0" isVertical="0" isCentered="1" lineType="0" itemWidth="220" xspace="10" yspace="10" showColumns="0" usingCheckboxes="0" columnString="_(218);MyNumber(100;2);MyDate(100;l);" treemapExpression="" treemapColorExpression="" treemapBorderColorExpression="$Color" treemapColorStart="#fffef9100" treemapColorEnd="#ccd5bf100" treemapDepth="0" attribute="" container="" bins="10" sortAttribute="" sortDirections="0" summaryAttribute="" summaryMethod="" query="" tableparent="" tablefontsize="12" queryLabel="" action="" actionLabel="" fontSize="12" omitDefaultValues="0" showFilter="0" filterString="" filterName="" force="0" gaudiSize="0" gaudiFontSize="16" roundness="10" grout="10" cameraPosition="0 0 0" cameraDirection="0 0 0" focalLength="0" />

    selected. Selection state of the tab. A value of 1 indicated the tab is selected. All other tabs have a value of 0.

    name. An optional title string (set/edited via the tab gallery). Default is "", in which case the normal tab label of '[view type]: [root container name]' is used.

    subtitle. An optional descriptive string that is set using the tab gallery feature, and can only be seen in the Gallery listing.

    viewType. The view pane's current view type:

    A newly-added tab uses the viewType (and root $ID) of the currently selected tab. Newly generated blank TBX documents are created with a two tabs, a Map view and an Outline view: the Map view tab is selected.

    usingRoadmap. Show/hide state of the text pane links panel. Default value is "0" (hidden)

    hideBreadcrumbs. View state of the view pane breadcrumb bar. Values are 0 (shown - default) or 1(hidden). The breadcrumb bar is used only by these views: Chart, Map, Outline, Timeline, Treemap.

    scale. View pane's zoom state. Default value is 32. Zoomed in (larger text) views have higher values, zoomed out views a smaller value.

    ID. The note $ID of the root item for the view. By default, document views start at document root. A newly-added tab uses the root $ID (and viewType) of the currently selected tab.

    scrollX. Horizontal scroll position of the view, when last saved. Default is 0 (in Tinderbox map units).

    scrollY. Vertical scroll position of the view, when last saved. Default is 0 (in Tinderbox map units).

    selection. The $ID number(s) of the view pane's selected item(s) as a space-delimited list.

    expanded. Used by Outline and Chart. A space-delimited list of $IDs in scope in the view that are expanded.

    textTab. The currently selected tab in the text pane. The default is 0 (Text). Other values 1 (Export) and 2 (Preview). Note: the visual order of button, left to right is Text, Preview, Export. The numbering order arises as Preview was a later addition to the original par of tabs

    splitRatio. The current split ratio of the view and text panes. Default is 0.5, each pane using 50% of the window. A value of 1.0 equates to all text pane, a value of 0 to all View pane.

    xattribute, xattribute2, xdisplayattribute, xbarattribute, xcontainer, xquery, xqueryLabel, xbins, xunlimited, xbins2, xunlimited2, xheatmap, xReportStyle. Data relating specifically to the Crosstabs view, see detail:

    spacing, aspect, hyperbolicScale, path, focus, crosslinks, spread, treepaths, crosslinkpaths. Data relating specifically to Hyperbolic view, see detail.

    hasBorder, isVertical, isCentered, lineType, itemWidth, xspace, yspace. Data relating specifically to Chart view, see detail.

    showColumns, usingCheckboxes, columnString, showFilter, filterName, filterString. Data relating specifically to Outline view, see detail.

    treemapExpression, treemapColorExpression, treemapBorderColorExpression, treemapColorStart, treemapColorEnd, treemapDepth. Data relating specifically to Treemap view, see detail.

    attribute, container, bins, sortAttribute, sortDirections, summaryAttribute, summaryMethod, query, queryLabel, action, actionLabel, fontSize, omitDefaultValues. Data relating specifically to Attribute Browser view, see detail.

    tableParent, tablefontsize. Data relating to Table view, see detail. (changed in v11.0.1)

    force, gaudiSize, gaudiFontSize, roundness, grout. Data relating to Gaudi view, see detail.

    cameraPosition, cameraDirection, focalLength. Date relating to Information City view, see detail.

    The difference in the degree of differing view types' use of XML data reflects how some already store much or all of their view configuration data in attribute values.

    See also:

    Tab level-specific data
    selected

    selected

    Selection state of the tab. A value of 1 indicated the tab is selected. All other tabs have a value of 0.

    name

    name

    An optional title string (set/edited via the tab gallery). Default is "" (an empty string), in which case the normal tab label of '[view type]: [root container name]' is used.

    subtitle

    subtitle

    An optional descriptive string that is set using the tab gallery feature, and can only be seen in the Gallery listing. This can give extra detail as to why a tab has been saved in the gallery.

    splitRatio

    splitRatio

    The current split ratio of the view and text panes. Default is 0.5, each pane using 50% of the window. A value of 1.0 equates to all text pane, a value of 0 to all View pane.

    View pane-specific data
    viewType

    viewType

    The tab view pane's current view type:

    • 0 = map
    • 1 = outline
    • 2 = chart
    • 3 = attribute browser
    • 4 = timeline
    • 5 = treemap
    • 6 = hyperbolic
    • 7 = crosstabs
    • 8 = table
    • 9 = gaudi
    • 10 = information city

    As at v11.7.0 there are 11 view types. This is the only listing mapping number to view name. It should be assumed any new view type would a new vale 12, 13, etc.

    A newly-added tab uses the viewType (and root $ID) of the currently selected tab.

    Newly generated blank TBX documents are created with a two tabs, a Map view and an Outline view: the Map view tab is selected.

    hideBreadcrumbs

    hideBreadcrumbs

    View state of the view pane breadcrumb bar. Values are 0 (shown - default) or 1(hidden). The breadcrumb bar is used only by these views:

    • Chart
    • Map
    • Outline
    • Timeline
    • Treemap
    scale

    scale

    View pane's zoom state. Default value is 32. Zoomed-in (larger text) views have higher values, zoomed-out views a smaller value.

    ID

    ID

    The note $ID of the root item for the view. By default, document views start at document root. A newly-added tab uses the root $ID (and viewType) of the currently selected tab.

    selection

    selection.

    The $ID number(s) of the view pane's selected item(s) as a space-delimited list.

    Text pane-specific data
    UsingRoadmap

    usingRoadmap

    Show/hide state of the text pane links panel. Default value is "0" (hidden).

    textTab

    textTab

    The currently selected tab in the text pane. The default is 0 (Text). Allowed values

    • 0 Text
    • 1 Export
    • 2 Preview

    Note: the visual order of button, left to right is Text, Preview, Export. The numbering order arises as Preview was a later addition to the original par of tabs

    Attribute Browser view-specific data

    The following <tab> tag attributes refer specifically to Attribute Browser view:

    • attribute. Selected attribute for review.
    • container. Path value for the optional scoping container. Default value "".
    • bins. Number of bins to use for numerical values. Default is 10.
    • sortAttribute. Selected [attribute name] for sorting the view. Default value "".
    • sortDirections. Toggle sort direction. Default is ascending (0). Also allowed descending (1).
    • summaryAttribute. Selected [attribute name] used to summarise each value. Default value "".
    • summaryMethod. Text value of the selected summary type. Default value "".
    • query. Optional query code applied by the query. Default value "".
    • queryLabel. Text label for the query. Default value "".
    • action. Optional action code applied by the query. Default value "".
    • actionLabel. Text label for the action. Default value "".
    • fontSize. View's font size. Default is 12 (pt).
    • omitDefaultValues. Ignore items with a default value for the selected attribute. Default value 0 (not ticked). Also allowed 1 (ticked).

    Note that Attribute Browser view shares the Outline's columnString attribute, changing the columns in either alters the shared setting at tab level. Thus switching the tab's displayed view type between Outline and Attribute Browser view will retain strings. Outline view (only) can show/hide the columns; unless all extra columns are deleted the tab stores the most recently used settings.

    There are individually described below:

    attribute

    attribute

    Selected attribute for review.

    UI control.

    container

    container

    Path value for the optional scoping container. Default value "".

    UI control.

    bins

    bins

    Number of bins to use for numerical values. Default is 10.

    UI control.

    sortAttribute

    sortAttribute

    Selected [attribute name] for sorting the view. Default value "".

    UI control.

    sortDirections

    sortDirections

    Toggle sort direction. Default is ascending (0). Also allowed descending (1).

    UI control.

    summaryAttribute

    summaryAttribute

    Selected [attribute name] used to summarise each value. Default value "". The value used must also be a list item in columnString.

    UI control.

    summaryMethod

    summaryMethod

    Text value of the selected summary type. Default value "".

    UI control.

    query

    query

    Optional query code applied by the query. Default value "".

    UI control.

    queryLabel

    queryLabel

    Text label for the query. Default value "".

    UI control.

    action

    action

    Optional action code applied by the query. Default value "".

    UI control.

    actionLabel

    actionLabel

    Text label for the action. Default value "".

    UI control.

    fontSize

    fontSize

    View's font size. Default is 12 (pt).

    omitDefaultValues

    omitDefaultValues

    Ignore items with a default value for the selected attribute. Default value 0 (not ticked). Also allowed 1 (ticked).

    UI control.

    columnString

    columnString

    A string list of displayed column name/width/format. Default is an empty string "". Example: "_(218);MyNumber(100;2);MyDate(100;l);" The three possible parts are:

    • Column name, an attribute title. In this example "_' is column #1 which is always the $Name but which is never titled.
    • Column width (pixels). Stored in parentheses. Default is 100 (pixels?)
    • Optional formatting data string. This is omitted where not pertinent. Where used it is placed after a semicolon after the column width inside the latter's parentheses.

    Note that Attribute Browser shares the Outline's columnString XML attribute, changing the columns in either alters the shared setting at tab level. Thus switching the tab's displayed view type between Outline and Attribute Browser view will retain strings. Outline view (only) can show/hide the columns; unless all extra columns are deleted the tab stores the most recently used settings.

    Note that only attributes stored here (i.e. displayed in-view) are valid values for the summaryAttribute setting.

    UI control.

    Chart view-specific data

    The following <tab> tag attributes refer specifically to Chart view:

    • hasBorder. Bordered item boolean option. Default is un-ticked/no border (0), 1 is ticked/show border.
    • isVertical. Vertical layout boolean option. Default is off/horizontal layout (0), 1 is on/vertical.
    • isCentered. Boolean option for centred positioning on parent item. Default is ticked (1), 0 is off.
    • lineType. 'Connecting Lines' style. Default is 0 (Orthogonal), also 1 (Straight) or 2 (Curved).
    • itemWidth. Normal item width. Default value is 220. This is pixel width of the bounding box from the item icon to the right side of the title display box.
    • xspace. Horizontal spacing value. Default is 10. In screen pixels?
    • yspace. Vertical spacing value. Default is 10. In screen pixels?

    These are individually described as linked below:

    hasBorder

    hasBorder

    Bordered item boolean option. Default is un-ticked/no border (0), 1 is ticked/show border.

    UI control.

    isVertical

    isVertical

    Vertical layout boolean option. Default is off/horizontal layout (0), 1 is on/vertical.

    UI control.

    isCentered

    isCentered

    Boolean option for centred positioning on parent item. Default is ticked (1), 0 is off.

    UI control.

    lineType

    lineType

    'Connecting Lines' style. Default is 0 (Orthogonal), also 1 (Straight) or 2 (Curved).

    UI control.

    itemWidth

    itemWidth

    Normal item width. Default value is 220. This is pixel width of the bounding box from the item icon to the right side of the title display box.

    UI control.

    xspace

    xspace

    Horizontal spacing value. Default is 10. In screen pixels?

    UI control.

    yspace

    yspace

    Vertical spacing value. Default is 10. In screen pixels?

    UI control.

    Crosstabs view-specific data

    The following <tab> tag attributes refer specifically to Crosstabs view:

    • xattribute. Row selected attribute [attribute name].
    • xattribute2. Column selected attribute [attribute name].
    • xdisplayattribute. Per-cell label [attribute name].
    • xbarattribute. Attribute used for bar value within cells [attribute name].
    • xcontainer. Source container of view [path].
    • xquery. Optional agent query. Holds query string, if any.
    • xqueryLabel. Label string for optional query.
    • xbins. Rows: maximum number of bins to use. Default is 5.
    • xunlimited. Rows: boolean to have a bin per value. Default (0) if not enabled, else 1.
    • xbins2. Columns, maximum number of bins to use. Default is 5.
    • xunlimited2. Columns, boolean to have a bin per value. Default (0) if not enabled, else 1.
    • xheatmap. Heatmap show/hide state. Off is 0 (default), 1 is on.
    • xReportStyle. Not currently used. Default is 0.

    These are individually described as linked below:

    xattribute

    xattribute

    Row selected attribute [attribute name].

    UI control.

    xattribute2

    xattribute2

    Column selected attribute [attribute name].

    UI control.

    xdisplayattribute

    xdisplayattribute

    Per-cell label [attribute name].

    UI control.

    xbarattribute

    xbarattribute

    Attribute used for bar value within cells [attribute name].

    UI control.

    xcontainer

    xcontainer

    Source container of view [path].

    UI control.

    xquery

    xquery

    Optional agent query. Holds query string, if any.

    UI control.

    xqueryLabel

    xqueryLabel

    Label string for optional query. Use unclear.

    UI control.

    xbins

    xbins

    Rows: maximum number of bins to use. Default is 5.

    UI control.

    xunlimited

    xunlimited

    Rows: boolean to have a bin per value. Default (0) if not enabled, else 1.

    UI control.

    xbins2

    xbins2

    Columns, maximum number of bins to use. Default is 5.

    UI control.

    xunlimited2

    xunlimited2

    Columns, boolean to have a bin per value. Default (0) if not enabled, else 1.

    UI control.

    xheatmap

    xheatmap

    Heatmap show/hide state. Off is 0 (default), 1 is on.

    UI control.

    xReportStyle

    xReportStyle

    Form of text to use for export. Default is 0.

    UI control.

    Gaudi view-specific data

    The following <tab> tag attributes refer specifically to Gaudi view:

    • force. The query that sets the attractant force in the view. Default value is an empty string "".
    • gaudiSize. View Size slider. Default value is 0 (zero).
    • gaudiFontSize. Set via 'A' font buttons (smaller/larger). Default value is 16.
    • roundness. Roundness slider. Default value is 10.
    • grout. Width of the padding space between notes. Default value is 10.

    These are individually described as linked below:

    force

    force

    The query that sets the attractant force in the view. Default value is an empty string "".

    UI control.

    gaudiSize

    gaudiSize

    View Size slider. Default value is 0 (zero).

    UI control.

    gaudiFontSize

    gaudiFontSize

    Set via 'A' font buttons (smaller/larger). Default value is 16.

    UI control.

    roundness

    roundness

    Roundness slider. Default value is 10.

    UI control.

    grout

    grout

    Width of the padding space between notes. Default value is 10.

    UI control.

    Hyperbolic view-specific data

    The following <tab> tag attributes refer specifically to Hyperbolic view:

    • spacing. Item spacing. Default is 0.35.
    • aspect. Aspect ratio. Default value is 2.
    • hyperbolicScale. Scale. Default value is 1.
    • path. Optional highlighted (link type) path. Default is an empty string "".
    • focus. $ID value of note with current central focus.
    • crosslinks. Show cross links or not. Default value: 1.
    • spread. Spread factor. Default is 0.5.
    • treepaths. A list of link-type names for which to show links. Default is an empty string, "".
    • crosslinkpaths. A list of link-type names for which to show cross-links. Default is an empty string, "".

    These are individually described as linked below:

    spacing

    spacing

    Item spacing. Default is 0.35.

    Not used?

    aspect

    aspect

    Aspect ratio. Default value is 2.

    UI control.

    hyperbolicScale

    hyperbolicScale

    Scale. Default value is 1.

    UI control.

    path

    path

    Optional highlighted (link type) path. Default is an empty string "".

    UI control.

    focus

    focus

    $ID value of note with current central focus.

    Not used?

    spread

    spread

    Spread factor. Default is 0.5.

    Not used?

    treepaths

    treepaths

    A list of link-type names for which to show links. Default is an empty string, "".

    UI control.

    crosslinkpaths

    crosslinkpaths

    A list of link-type names for which to show cross-links. Default is an empty string, "".

    UI control.

    Map view-specific data
    scrollX

    scrollX.

    Horizontal scroll position of the view, when last saved. Default is 0 (in Tinderbox map units).

    scrollY

    scrollY

    Vertical scroll position of the view, when last saved. Default is 0 (in Tinderbox map units).

    Outline view-specific data

    The following <tab> tag attributes refer specifically to Outline view:

    • showColumns. Column view state. Default is 0 (no columns) Other allowed value, 1 (columns shown). Note: this value appears to be discrete to that of Attribute Browser use of column view.
    • usingCheckboxes. Checkbox state. Default is 0 (no checkboxes). Other allowed value, 1 (checkboxes shown).
    • columnString. A string list of displayed column name/width/format. Default is an empty string "". Example: "_(218);MyNumber(100;2);MyDate(100;l);" The three possible parts are:
      • Column name, an attribute title. In this example "_' is column #1 which is always the $Name but which is never titled.
      • Column width (pixels). Stored in parentheses. Default is 100 (pixels?)
      • Optional formatting data string. This is omitted where not pertinent. Where used it is placed after a semicolon after the column width inside the latter's parentheses.
    • showFilter. Show/hide Outline filter bar. Boolean as number. Default is 0 (hidden).
    • filterName. The saved name—if any—of the last-used Filter query. Default value is an empty string, "".
    • filterString. The last-used Filter query—if any. Default value is an empty string, "".

    Note that Attribute Browser view shares the Outline's columnString attribute, changing the columns in either alters the shared setting at tab level. Thus switching the tab's displayed view type between Outline and Attribute Browser view will retain strings. Outline view (only) can show/hide the columns; unless all extra columns are deleted the tab stores the most recently used settings.

    These are individually described as linked below:

    showColumns

    showColumns

    Column view state. Default is 0 (no columns) Other allowed value, 1 (columns shown). Note: this value appears to be discrete to that of Attribute Browser use of column view.

    UI control.

    usingCheckboxes

    usingCheckboxes

    Checkbox state. Default is 0 (no checkboxes). Other allowed value, 1 (checkboxes shown).

    UI control.

    columnString

    columnString

    A string list of displayed column name/width/format. Default is an empty string "". Example: "_(218);MyNumber(100;2);MyDate(100;l);" The three possible parts are:

    • Column name, an attribute title. In this example "_' is column #1 which is always the $Name but which is never titled.
    • Column width (pixels). Stored in parentheses. Default is 100 (pixels?)
    • Optional formatting data string. This is omitted where not pertinent. Where used it is placed after a semicolon after the column width inside the latter's parentheses.

    Note that Attribute Browser shares the Outline's columnString XML attribute, changing the columns in either alters the shared setting at tab level. Thus switching the tab's displayed view type between Outline and Attribute Browser view will retain strings. Outline view (only) can show/hide the columns; unless all extra columns are deleted the tab stores the most recently used settings.

    UI control (Outline).

    showFilter

    showFilter

    Show/hide the view's Filter panel. Boolean as number. Default is 0 (hidden).

    UI control.

    filterName

    filterName

    The last-used Filter's saved name—if any. Default value is an empty string, "".

    Saved filters are stored in the <filters> element—XML setting.

    filterString

    filterString

    The last-used Filter's saved query—if any, for the filterName saved filter. Default value is an empty string, "".

    Information City specific data

    The following <tab> tag attributes refer specifically to Information City view:

    • cameraPosition. Default: 0 0 0. The X/Y/Z position of the camera within in the view, relative to the view plane's origin. Here Z is the height above the plain. Units: c.1 unit per 3m.
    • cameraDirection. Default: 0 0 0. The X/Y/Z orientation of the camera within the view. Units: c.1 unit per 3m.
    • focalLength. Default: 0. The apparent distance of the observer from the buildings. The camera's focal length in millimetres.

    There are no direct UI controls for these settings. Rather, they reflect the current perspective within the city.

    These are individually described as linked below:

    cameraPosition

    cameraPosition

    Default: 0 0 0. The X/Y/Z position of the camera within in the view, relative to the view plane's origin. Here Z is the height above the plain. Units: c.1 unit per 3m.

    cameraDirection

    cameraDirection

    Default: 0 0 0. The X/Y/Z orientation of the camera within the view. Units: c.1 unit per 3m.

    focalLength

    focalLength

    Default: 0. The apparent distance of the observer from the buildings. The camera's focal length in millimetres.

    Table view-specific data

    The following <tab> tag attributes refer specifically to Table view:

    • tableParent. The $ID number of the last-used parent container. Default is undefined, then an ID value after tab's use for table view.
    • tablefontsize. (from v11.0.1) The font size used for the view. Default is 12.

    These are individually described as linked below:

    tableParent

    tableParent

    The $ID number of the last-used parent container. Default is undefined, then an ID value after tab's use for table view.

    UI control: none, view context is user selected

    tablefontsize

    tablefontsize

    (from v11.0.1) The font size used for the view. Default is 12.

    UI-control.

    Treemap view-specific data

    The following <tab> tag attributes refer specifically to Treemap view:

    • treemapExpression. Action code expression used for mapping item area. Default value is "".
    • treemapColorExpression. Action code expression used for item fill colour value. Default value is "".
    • treemapBorderColorExpression. Action code expression used for item border colour value. Default value is the container's current $Color value.
    • treemapColorStart. Shading start colour. Default value: #fffef9100". The first 6 digits are the hex colour code, the last 3 are an opacity setting.
    • treemapColorEnd. Shading end colour. Default value: "#ccd5bf100". The first 6 digits are the hex colour code, the last 3 are an opacity setting.
    • treemapDepth. Number of descendant levels to display. Default value (0) sets no limit.

    These are individually described as linked below:

    treemapExpression

    treemapExpression

    Action code expression used for mapping item area. Default value is "".

    UI control.

    treemapColorExpression

    treemapColorExpression

    Action code expression used for item fill colour value. Default value is "".

    UI control.

    treemapBorderColorExpression

    treemapBorderColorExpression

    Action code expression used for item border colour value. Default value is the container's current $Color value.

    UI control.

    treemapColorStart

    treemapColorStart

    Shading start colour. Default value: #fffef9100". The first 6 digits are the hex colour code, the last 3 are an opacity setting.

    UI control.

    treemapColorEnd

    treemapColorEnd

    Shading end colour. Default value: "#ccd5bf100". The first 6 digits are the hex colour code, the last 3 are an opacity setting.

    UI control.

    treemapDepth

    treemapDepth

    Number of descendant levels to display. Default value (0) sets no limit.

    UI control.

    utilityWindows tag

    The utilityWindows tag is a direct child of the tinderbox tag.

    <utilityWindows>[nested <window> tags or empty]</utilityWindows>

    This tag holds a listing of open stand-alone text windows, using the window tag. The element will be empty if no stand-alone windows are currently open.

    window tag

    This window tag is direct child of the utilityWindows tag. The windows are those of stand-alone note text spaces. The individual windows are listed in front-to-back order, i.e. the first listed is the frontmost in the UI. Non-note secondary windows are not recorded as these close at session end.

    Stand-alone text windows have no tabs so there are no child tags for these window tags.

    Example:

    <window bounds="Rect[ 184 512 658 866]" ID="3471500281" />

    bounds. A space-delimited array of 4 numbers being the screen pixel {x,y} co-ordinates of the top-left and bottom-right corners of the window.

    ID. The $ID of the source item for the view.

    searches tag

    The searches tag is a direct child of the tinderbox tag.

    <searches>[list of <search> tags or empty]</searches>

    This is a listing of search strings used recent Find queries used in the View pane. Up to 10 recent values are saved using search tags.

    The element is present but empty until first use of the feature.

    search tag

    This tag stores the string value of an individual recent search term in the View pane's Find toolbar.

    <search>Task</search>

    filters tag

    The filters tag is a direct child of the tinderbox tag.

    <filters>[list of <filter> tags or empty]</filters>

    This is a listing of any saved filter queries used in the (Outline) View pane. Up to 10 recent values are saved using filter tags.

    The element is present but empty until first use of the feature.

    filter tag

    This tag stores the string value of an individual recent search term in the View pane's Find toolbar.

    <filter name="Car" filter="$Name.contains("car")" />

    The filter holds the screen name of filter and the filter's query string.

    badges tag

    The badges tag is a direct child of the tinderbox tag.

    <badges limit="14">[list of up to 14 badge names]</gallery>

    The tag stores the names of (up to) the last 14 badges applied in the current document as a Tinderbox semicolon-delimited list, e.g. "flag yellow;flag blue;ok". The first value is the oldest use, the last the most recent.

    The element is present but empty until first use of the feature.

    When first implemented, the limit value was 7. This is an internal setting and not user editable (via the app).

    preview tag — suspended

    The preview tag is a direct child of the tinderbox tag.

    <preview>[Base64-encoded string of image]</preview>

    The image is a thumbnail of the current tab's view, encoded in Base64 so as to be valid XML.

    The non-printing character in the stream is a carriage return (#13).

    The element is present but empty until first use of the feature.

    Feature Suspended

    This feature has been suspended as of 11.5.0 as macOS Tahoe does not support the current mechanism, and which also causes some performance issues with git. Opening in newer app versions will delete the element if found.

    Applescript

    Tinderbox offers limited AppleScript support, making it easier to automate workflows with other applications. Explaining general AppleScript functionality is outside the scope of aTbRef.

    NOTES:

    *scripts can do very bad things to a document; there is no undo for scripting changes so keep good backups.

    • this section is not an AppleScript primer. Those new to AppleScript should familiarise themselves with the basics of AppleScript before using code shown here. The AppleScript scripting language is well supported with learning resources both online and in book form.
    This section of aTbRef has been much enhanced by contributions of the Tinderbox community. Special thanks go to Sumner Gerard and Paul Walters for detailed contribution/explanation of AppleScript coding methods.

    Below are some sample AppleScript expressions that Tinderbox AppleScripting supports:

    Case sensitivity differs in Tinderbox vs. AppleScript

    IMPORTANT!

    AppleScript case sensitivity when resolving note name matches differs from action code.

    Whereas Tinderbox note name values ($Name) are matched case-sensitively, some AppleScript commands are case-insensitive and AppleScript’s case-insensitivity cannot be over-ridden. Unfortunately, AppleScript's named is one such case-insensitive operator (note that it is consistent with Finder's behaviour). Also, be aware that AppleScript code

    note "project" 

    is only a short way to write

    note named "project" 

    … i.e. both examples use named, even if it is only explicit in the latter. This means the code acts case-insensitively to match the first ($OutlineOrder-based) match to notes named 'project' or 'Project' which otherwise would be discrete matches in Tinderbox action code. By contrast, Tinderbox action code can distinguish note 'X' from note 'x' although if matching returns two notes called 'x', it would pick the first by outline order ($OutlineOrder value) as the returned matched item.

    If affected by this consider resolving correct identity based on $Path or $IDString data instead and see the find note in example. If needing to do multiple operations on a note (or in scope of a note) use a more precise method to set a reference to the note and then re-use the reference as needed.

    Calling the Tinderbox application

    Many of the code examples in this section assume the example will be run inside a call to the Tinderbox explanation, as is explained below.

    Addressing the Tinderbox app

    In order to tell AppleScript to address Tinderbox, a tell call (or outer tell block) should refer to the application. Most specific is to use the names of the current (or desired) app version. This calls the installed Tinderbox v.10.x:

    tell application "Tinderbox 10"

    To save having to specify the version number, the name can be shortened:

    tell application "Tinderbox"

    this maps via a partial match-from-start on app's name. This means scripts do not have to be updated every time a new Tinderbox major version is released, e.g. going from v10 to v11, etc.

    An older method, that bypasses use of the app name is to use the AppleScript 4-character AppleScript application id:

    tell application id "Cere"

    calls the installed Tinderbox version.

    Thus the latter suggested as the best option because the bundle identifier—here Cere— can only be changed by the developer. On the other hand, anyone can change the name of the app in from 'Tinderbox 10.app' to 'Tinderbox.app' or vice-versa, with the risk of making scripts not work since tell application searches for a package with that name in the OS' Applications folder.

    Multiple installed versions

    This can happen easily, especially for beta testers and Backstage members, e.g. having the current public release and the latest beta installed. Or, when a new major version comes out with significant changes, keeping the last public release installed for a bit. Note however, that AppleScript searches the OS Applications folder for the app so as long as only one version of the app is installed there no conflict should occur.

    If keeping the last version installed in the Applications folder during the early days of a new version, e.g. 'Tinderbox 9.app' and'Tinderbox 10.app' and wanting to target a particular version, it may be necessary to use the first method with the full application name.

    Properties of the application object

    The application object has four read-only string properties:

    • build: build number of the app, e.g. "b717".
    • frontmost: a boolean that is only true when/if the Tinderbox app is the active/frontmost app.
    • name: the app's name as seen in Finder, e.g. "Tinderbox 10".
    • version: the app's current version, e.g. "10.2.0".

    For instance to read the version build number of the current install:

    	tell application id "Cere"
    		set theVersion to version
    	end tell

    or

    tell application id "Cere" to set theVersion to version

    These properties must be called directly from the application and not within a document tell.

    Address Tinderbox documents, not windows

    The general metaphor is to address app by full name, and then the document directly (see Calling Tinderbox), like so

    tell application "Tinderbox 10"
    	-- add code here
    end tell

    Although it might make familiar sense to start addressing a general context in Tinderbox, e.g. to make a note, like so:

    tell front window of front document (WRONG!)

    this generally does no work, as the Tinderbox AppleScript app Dictionary addresses notes, attributes, etc. via the host (TBX) document rather than via a specific window.

    Correct is to use:

    tell front document

    or if multiple documents are open, address it by name:

    tell document "Workspace.tbx"

    Making a new note

    Creating a new item: note, agent, or adornment

    This (in an application tell block) is the basic call to create a new root-level object, using any one of these depending on the type of item needed:

    make new note

    or

    make new agent

    or

    make new adornment

    Remember: without further qualifying code any new objects are always created at the root of the target document.

    The default $Name string value for a note made using make new is "new note", for an agent it is "agent", and for an adornment is it "adornment".

    Here, a new note is made at the root of document "Workspace.tbx" and then creates an agent (with)in that note:

    	set myNote to make new note in document "Workspace.tbx" 
    	set myAgent to make new agent in myNote 

    or a new note as a single inline tell call:

    tell front document of application "Tinderbox 10" to make new note

    Setting the name for new item

    (Re-)naming an item involves setting its name property. Be aware that it is not possible to apply a note name until the note has been created, i.e. the two tasks cannot occur in the same line of code.

    	set myNote to make new note in document "Workspace.tbx" 
    	set name of myNote to "inbox" 

    To work around this same-line usage issue, use the properties command

    set myNote to make new note in document "Workspace.tbx" with properties {name:"inbox"}

    When using the make new command, note that the returned designator it gives is based on the current outline ($OutlineOrder) position of the newly created item, and subsequent calls that make or delete items might render that reference invalid. If so, use the find note in command (see more)to re-set the variable's stored location:

    set myNote to find note in it with name "inbox" 

    Just as with $Name other attributes can be set (see also Attribute values):

    set value of attribute "Width" of myNote to 5

    Creating new notes other than at root

    Whilst the most trivial example inserts a new note at the root of the TBX's outline, a more likely scenario is needing to generate something new at a particular location, e.g. inside an existing container.

    There is no method to create a path-type AppleScript object from a literal path string value, so a rather roundabout method is needed. This uses the find note in method to create the location (path) object. The latter can then be used to make a new note, like so:

    	tell front document
    		set newPath to find note in it with path "/Z/Y"
    		set newNote to make new note at newPath
    		set name of newNote to "X"
    	end tell

    The it in line #2 above is not strictly necessary but '...find note in with...' reads like an error in the code.

    A shorter version of the above is:

    	tell front document
    		make new note at (find note in it with path "/Z/Y") with properties {name:"X"}
    	end tell

    So the sequence is: a) find the note by path setting a variable, b) make a note using the variable as the path data, and lastly c) name the note. The latter can be skipped by using a note's properties—as above.

    Capturing addressed objects

    When making or finding or moving a note (agent, etc.), the command returns a reference to that object and if needing to work further this that object it is best to capture the object in a variable.

    So, rather than use:

    make new note

    this is a better approach:

    set myNote to make new note

    Commands available for a note object

    A number of commands can be run on addressable items (notes/agent/adornments):

    Running an action on a note

    Performing actions

    To perform an action on the designated note:

    act on theNote with "…action…" 

    An 'action' is typically one or more assignment or conditional statements (query expressions), such as

    $Color="red";$Badge="ok";

    Within an 'act on' code, = means a value assignment;

    Thus an act on is akin to stamping a note (altering the note via the effect of the action code), or using the action() operator. Like action(), an act on does not return a value.

    Accessing system and user attribute values

    Attribute values

    Set the value of an attribute, here $Width:

    set value of attribute "Width" of myNote to 5

    Note the AppleScript limitation of the (implicit use of the) named operator and its case-insensitivity matching names. For setting a note's $Name, see here.

    To get the value of a designated attribute:

    get value of attribute "Width" of myNote

    Or, for an offset address:

    get value of attribute "Width" of (lastChild of MyNote) 

    Attributes with local values can be reported:

    get the localattributes of MyNote 

    … returns a list of attributes for a note where (both):

    • the note has an immediate value for that attribute, rather than inheriting a value from a prototype or the attribute default.
    • the attribute is not intrinsic, hidden, or deprecated.

    Getting and setting attribute values

    This involves addressing the value of the attribute. To get (read) $Width

    get value of attribute "Width" of myNote

    or set it

    set value of attribute "Width" of myNote to 5 

    If a value for an Number type is passed as a string, or vice versa, consider issues of auto-coercion.

    Reading (or altering) attribute default values

    The default value of an attribute can be read or set from the note [sic] context:

    get defaultValue of attribute "Width" of myNote

    or

    set defaultValue of attribute "Width" of myNote to "5" 

    Resetting an attribute to its default

    To remove any local value assigned to the designated attribute, restoring the inherited or default value:

    delete value of attribute "Width" of myNote 

    This is akin to the action $Width=;.

    Remember to refresh the UI!

    If operating on a document actually being viewed it can be useful to refresh the UI (see refresh) to ensure the Tinderbox window reflects the changes made via scripting.

    Properties of an attribute object

    System and user attributes expose a number of properties

    • category. Read-only text string. The attribute's category ('user' for all user attributes).
    • defaultValue. Read/write text. The attribute's default value. Not writeable for calculated (read-only) system attributes.
    • name. Text string, read-only for system attributes, read/write for user attributes. The name of the attribute.
    • type. Text string, read-only for system attributes, read/write for user attributes. The data type of the attribute.
    • value. Text string, read-only for system attributes, read/write for user attributes. The attribute's current value.

    Deleting notes

    Use the note name (N.B. not case-sensitive):

    delete note named "Hello World"

    so it deletes e"Hello World" and/or, "Hollo world", "Hello world", etc.

    Or set a reference to the note and then call:

    delete myNote 

    Evaluating expressions

    Tinderbox allows AppleScript to evaluate action code expressions and is akin to using the action operator eval(). The generic form of evaluating of an expression:

    evaluate note with expression 

    The first argument note is an AppleScript specifier for the note, which will be bound to this for the evaluation. The evaluate command may be issued to either the document or to a specific note.

    Performing evaluation

    This returns the result of evaluating an action code expression:

    set myResult to evaluate theNote with "…expression…" 

    Within an evaluate, = means a value comparison (although use of the less ambiguous operator == is preferred). An 'evaluate' operation presumes the content of the note is action code whose evaluated result is to be returned.

    Verifying if an item exits

    The exists command returns a boolean if the referenced item exists:

    set myBoolean to exists note named "Hello World"

    Or set a reference to the note and then call:

    set myBoolean to exists myNote 

    Finding and referencing notes

    Finding a specific note

    To return a reference to the designated note the generic code form is:

    find note in [note or document] with path "/path/to/note" 

    If the target is a document, the path should be an absolute path. If the target is a note, the path can be an absolute path or a relative path with respect to that note.

    Paths

    Unlike Tinderbox, here a note $Name and $Path are not interchangeable. For use paths, a find note in operation is required.

    Finding a specific note

    To return a reference to the designated note the generic code form is:

    find note in [note or document] with path "/path/to/note" 

    If the target is:

    • a document, the path should be an absolute path (the $Path of the target).
    • a note, the path can be an absolute path or a relative path with respect to that note.

    If inside a tell block, an 'it' reference is useful even if only for the human reader of the code

    	tell front document
    		find note in it with path "/path/to/note"
    	end tell

    Returning an offset reference to a found note

    To return a reference to myNote's container, i.e. its 'parent' property (see note properties):

    set theContainer to find note in myNote with path "parent" 

    Getting references to notes

    To get a list of all the note inside the referenced 'myNote':

    get notes in myNote 

    Or, the agents in 'myNote':

    get agents in myNote 

    Or, the adornments in 'myNote':

    get adornments in myNote 

    To return the name of the third ($OutlineOrder) top-level note in the specified document:

    set myName to name of note 3 of document "Workspace.tbx" 

    Moving notes

    Just as moving a note via action code involves setting a new $Container for that note, moving a note via AppleScript involves specifying the new container. It thus makes sense to first set a reference to the new container and then move the item. In this example, a reference is made to the parent property (the containing note) of the note referenced by myNote), then note 'X' is moved into that container:

    To return a reference to myNote's container, i.e.

    	set theContainer to find note in myNote with path "parent" 
    	move note named "X" to theContainer

    Note in the first line, the new container is being referenced via the myNote's note properties.

    Refreshing the Tinderbox UI

    The code:

    refresh theNote 

    … informs Tinderbox that changes have been made to a note and the user interface may require updating.

    Thus, if a script alters the note's render in the view pane or its $Text or Displayed Attributes, a refresh call ensures the UI reflects the changes just made via AppleScript.

    It will also update agents, and from v11.0.0 it will update smart adornments as well

    Properties of a note object

    Each note object has a number of AppleScript properties in addition to accessing an objects system/user attributes:

    • child (action code designator 'child' or 'child[0]'). Read-only note object
    • color (i.e. $Color). Read/write text.
    • lastChild (action code designator 'lastChild'). Read-only note object.
    • name (i.e. $Name). Read/write text.
    • nextSibling (action code designator 'nextSibling'). Read-only note object.
    • parent (action code designator parent). Read-only note object.
    • previousSibling (action code designator 'prevSibling'). Read-only note object.
    • text (i.e. $Text). Read/write plain text string of $Text.

    In a few cases the property is an alternate way to access a specific system attribute for the note, but for most these properties are the equivalent of calculated item designators in action code.

    Selections

    Selections are an element of the document object.

    Setting a selection

    To select a named note:

    set selected note of front document to "Test note" 

    … selects a note. N.B. presently, selecting more than one note is not supported.

    Working with selections

    The current selection:

    set mySelection to selection of front document 

    … returns a list of a selected note(s). If several notes are selected, to code returns one of those notes, typically the first selected note. If no notes are selected, this returns 'missing value'.

    To ensure all of the currently selected note(s) are captured:

    set mySelection to every selection of front document 

    Note that selection is an element of a document object, so must be used with a specified document as above, or the code will not compile. But that form cannot be used if already inside a document tell block (code errors). Instead use selected note as shown below, to get a reference to a selected note:

    set mySelection to selected note of front document 

    … returns the selected note. If already inside a document tell use :

    set mySelection to selected note 

    If several notes are selected, the selection code returns one of those notes, typically the first selected note. If no notes are selected, this returns 'missing value'.

    To put a list of $Name (or other attributes) of all selected notes into an AppleScript list called 'theNames':

    tell selection of front document to set the theNames to value of attribute "Name"

    selected note or item(s) of selection offer the same properties as for a note object.

    Acting on each item in a selection of notes

    A way to act on all selected notes (a common operation):

    	repeat with anItem in selection of front document
    		set value of attribute "Color" of anItem to "red"
    	end repeat

    Creating and editing user attributes

    Attributes are an element of the document object, though they may hold/inherit a value at the scope of a note object.

    User Attributes

    Scripts can create new user attributes:

       tell application "Tinderbox 10"
          set doc to document "xtest.tbx"
          set newAttr to make attribute in doc
          set the type of newAttr to "date"
          set the name of newAttr to "myNewAttribute"
       end tell

    Or, to test for an attribute before use, and make it if not found:

    	tell front document
    		-- check URL type attribute $HookURL exists or make one
    		try
    			set hookTest to attribute named "HookURL"
    		on error errMsg number errNum
    			set newAttr to make attribute
    			set the type of newAttr to "url"
    			set the name of newAttr to "HookURL"
    			set hookTest to attribute named "HookURL"
    		end try
    	end tell

    Be aware that when using make new attribute, if a user attribute already exists with the designated name, the existing attribute is modified. If a system attribute already exists with the same name, no changes are made and no attribute is created. Therefore it is best to test for an attribute's existence before (re-)making it.

    user attributes may be accessed as a list:

    set userList to user attributes of front document 

    User attributes may be renamed. Note that references to attributes specify attributes by name, and so existing references are invalidated after the attribute is renamed. You can get a new reference to the renamed attribute thus:

    	tell front document
    		set attrRef to attribute named "OldName"
    		set name of attribute "OldName" to "NewName"
    		set attrRef to attribute named "NewName"
    	end tell

    The type of attribute (kind pre-v8.0.4) determines the attribute type, and may be any of the following case-sensitive values: action, boolean, color (N.B. US spelling), date, dictionary, email, file, font, interval, list, number, set, string, URL (N.B. case)—i.e. any of the currently defined Tinderbox attribute data types.

    Attributes have a read-only property, category, that groups related attributes to their attribute Group as seen in Get Info. The category of renamed and deprecated attributes is returned as the category of their replacement.

    Aliases are not supported

    The Tinderbox AppleScript dictionary does not recognise aliases as a type of object. Aliases may still be referenced and their attributes read/altered. Note that the $IsAlias system attribute differentiates an original object from its alias(es).

    Accessing app menu items

    There are often features only accessible via menus in-app and which have no direct command in the app's AppleScript dictionary. Happily the generic AppleScript System Events command allows 'remote control' operation of menus without needing to use extra utilities.

    Below are a pair of AppleScripts sub-routines (akin to action code functions), one to press main menu items (e.g. File →Built-In Hints) and one to press sub-menu items (such as Format → Font → Bold). The examples should indicate how to extended the method to access more deeply nested menus.

    Top-level menus

    This is for items in main menus like 'File', Note'. The sub-routing takes three arguments, all are required (see code comments for examples:

    -- call example 1: my do_menu("Tinderbox 10", "Stamps", "Turn red")
    -- call example 2: my do_menu("Tinderbox 10", "Edit", "Duplicate")
    
    on do_menu(app_name, menu_name, menu_item)
    	try
    		tell application app_name to activate --must bring to front		
    		tell application "System Events"
    			tell process app_name
    				tell menu bar 1
    					tell menu bar item menu_name
    						tell menu menu_name
    							click menu item menu_item
    						end tell
    					end tell
    				end tell
    			end tell
    		end tell
    		return true
    	on error error_message
    		return false
    	end try
    end do_menu
    

    Sub-menus

    This is for items in sub-menus like 'File→Built-In Prototypes''. The sub-routing takes four arguments, all are required (see code comments for examples:

    -- call example: my do_menu("Tinderbox 10", "Format", "Font", "Bold")
    
    on do_menu(app_name, menu_name, menu_item, sub_item)
    	try
    		tell application app_name to activate --must bring to front		
    		tell application "System Events"
    			tell process app_name
    				tell menu bar 1
    					tell menu bar item menu_name
    						tell menu menu_name
    							tell menu item menu_item
    								tell menu menu_item
    									click menu item sub_item
    								end tell
    							end tell
    						end tell
    					end tell
    				end tell
    			end tell
    		end tell
    		return true
    	on error error_message
    		return false
    	end try
    end do_menu
    

    More deeply nested menus

    Adapt the last example above to nest extra menu(s). Each extra menu level will require an extra input argument (the name of the lowest level (most-nested) sub-menu.

    About aTbRef

    aTbRef is a free public resource and has been online continuously since April 2005.

    As a reference file, aTbRef is explicitly and deliberately not a 'how-to' resource, i.e. it explains how parts of the app work rather than how to employ those app features in the context of a user's personal work tasks. The latter are questions that can be addressed by tutorials or in the user-to-user forums (more on other Tinderbox help resources).

    This current version of the aTbRef11 resource is baselined on v11.0.0b733 (released 12 September 2025) and includes changes up to and including v11.8.0b808 (7 Jul 2026). The web site of c.2,500 discrete static HTML webpages is created from 3,128 discrete notes and a further 520 aliases within the source Tinderbox document.

    The overall document comprises 10,869 items: 10,869 notes, 176 agents, 7,356 aliases and 4 adornments

    These items contain 468,540 words, and use 7,024 internal (i.e. in-document) link and well as 648 outbound weblinks.

    The document uses 82 user attributes, 26 prototypes, and 76 export templates.

    Further notes about aTbRef:

    Updates to aTbRef

    This document is under near constant revision. Generally, only affected pages are altered and changes since the baseline version are annotated with the version in which the change occurred. This means the 'last updated' time on the home page may not always be correct, but it is a pragmatic trade-off in terms of maintenance load.

    A full site re-upload is done for all new releases, i.e. during version X, for every X.N or X.N.n release for as long as major version X is current.

    Those users who always update to the current version can generally just ignore the text's references to version numbers (apart from checking the most recent changes) whereas users of older versions or without current update support can easily see whether their installed version includes certain improvements or not.

    Some legacy syntax is no longer documented. Those needing to use legacy syntax should refer to older versions of aTbRef.

    To assist TBX-based users watching the version and build checkers, a full local export is done when feasible even if only a few affected pages are uploaded. In such circumstances this will include the RSS/Atom feeds, the zipped TBX and the index page (so the latter's updated time will be correct). Discontinued.

    Obtaining the aTbRef source TBX file

    NOTE: if you are using the source TBX file version of aTbRef, bear in mind nearly all of the caret (^) symbols will be written doubled in note $Text in order that they do not get interpreted as export codes when outputting the HTML pages. A further benefit from using—or just viewing—the source TBX is that it contains all the export templates needed to produce this site and which can be instructive if learning the HTML export aspects of Tinderbox.

    A recent version of this file (including all needed HTML export templates) may be downloaded from the root folder of this HTML website:

    https://atbref.com/atbref11/aTbRef11.zip

    The ZIP archive will extract to copy of the aTbRef.tbx file. You can move this anywhere you like and open it like any other TBX file.

    The images used in the website are not stored in the TBX for a variety of reasons by primarily to reduce the size of the TBX file. For use with HTML export, the images are available as a separate zip:

    https://atbref.com/atbref11/images.zip

    The above unpacks to a folder "images" that should be placed inside the folder to which you exported your HTML from aTbRef.tbx, i.e. alongside the "index.html".

    Using a local HTML version of aTbRef:

    • Open the aTbRef.tbx:
    • Use the File menu, Export as HTML.
    • You will be asked to select a folder for export or make a new one. Tinderbox will remember this location for subsequent re-export of the TBX.
    • Once the export process is complete, open the export location in Finder.
    • Drag the 'images' folder unpacked from the separate ZIP download into the HTML export folder.
    • In the export folder double-click 'index.html' to open the Home page of the site. If you want you can make an alias for the file and place the alias elsewhere, or make a bookmark in your browser.
    • The exported website runs entirely from within its own folder, so if desired it can be moved on your Mac or even to another computer/server on your LAN.
    • For those in organisations with official controls on publication on their LAN, a Creative Commons licence is included which should allow you to use this resource locally.
    • If you wish to stop your local exports trying to make new zips, before exporting locally, open the notes 'Zipper-images' and 'Zipper' in HTML view and untick the 'Export' box.

    To be able to view images used by the HTML site from within the TBX, even if you do not use the HTML export:

    • Download and unpack the images ZIP.
    • Place the resulting 'images' folder where you need it, either for HTML use (see above) or just for use with the TBX.
    • Find that folder in Finder, select the Finder and leave the Finder window open.
    • Open the TBX and find the Image Linker agent in the UTILS section.
    • Select the agent's in the view pane so it loads in the text pane.
    • Switch back to finder and drag the 'images' folder onto the 'File' button in the agent's displayed attributes table.
    • This populates the agent's $File.
    • The agent's query finds all notes with a $WebImage (i.e. which use a screengrab in the HTML) and combines the agent's $File data with the note's $WebImage to set the note's $File to the correct local path to the image.

    The online HTML version of the above TBX's output will be found at:

    https://atbref.com/atbref11/index.html 

    Screengrabs

    The original grabs here were originally made using Tinderbox v2.3.4 and v2.4.0 and have been added to as new versions have changed the UI or new features have been added. Grabs are created with Monosnap with post-editing if required in GraphicConverter, ImageOptim or PNGCompressor. Originally in JPG format, all newer grabs are in PNG format for better quality/compression.

    The images are not stored in this TBX but are online at:

    https://atbref.com/atbref11/images/

    or in the /images/ sub folder of earlier aTbRef versions still online. The image folder can be downloaded for local use with an export of aTbRef. Should you wish to download the images for local use, please do so. I would ask though that, for bandwidth conservation, you do not hot-link to the online images apart from occasional references (e.g. blog items, etc.).

    There is no index (as a web page) of the files in the above folder. The intent has to provide images of every dialog menu and window/view in the application and illustrate some of the more visual UI features.

    aTbRef's HTML export templates

    All the templates used to export this file to HTML are stored in the aTbRef TBX file inside the top level container called "TEMPLATES".

    HTML5 Templates

    In Feb 2013, the templates were updated top use an HTML5 DOCTYPE and to lose all the old tables. The first method duplicated a number of templates and includes (those with a 5 prefix or suffix). As a result of this it became apparent that the 4 main templates could be merged into one, using more conditional compilation. Thus all the main content individual pages are created by: 5-basic_all.

    A boolean $WebImageLandscape indicates whether the image should be placed above/before text, or (for most, portrait oriented, images) are floated right in the main text. As the preferences section uses aliases for the Doc-level preference notes, but needs different screen grabs, $WebImageA holds the alternate image and another conditional is used to figure this out.

    Old templates are marked with a strike-through in the TBX to help identify those still in use.

    Shortly after the move to HTML5, it was discovered that the ^similarTo^ links did not evaluate correctly when placed in an include. The first 5-basic_all was thus saved as an archive copy (named5-basic_all (changes for similarTo links)) and 5-basic_all was updated to place the ^similarTo^ code back in a main template. As a result the on/off boolean attribute for the old include was moved into the main template: this allows suppression of the similar-to links and a circa 20-fold increase in the time taken to export (useful when testing!).

    As it happens, the need for boilerplate includes becomes less with the move to one main template, although it does segment out the code slightly, making it easier to find the right part for re-editing. So, for now most of the includes remain.

    The 5-basic_all template contains 4 booleans to turn off features that slow export or require web (WAN) access:

    • $UseGoogleTracking. If false, omits host domain Google Analytics tracking. Needs web access and not pertinent if run locally.
    • $UseGoogleTranslate. If false, the template omits the Google Translate widget (top right of page) which loads from the web.
    • $UseSimilarTo. If false export is much faster (as explained above).
    • $UseGoogleIndexing. If false this omits the Google-based site search which requires web access.

    Original HTML4 templates

    Originally, the site exported all content via 4 templates:

    • basic: the default & used for most pages.
    • basic_grabs: for pages with portrait oriented images.
    • basic_menu_bars: originally for menu bars and then all pages with landscape oriented images.
    • basic_change: only used for change log agent pages.

    In turn these used/included:

    • basic_child_item: used for the Basic Comparison Operator listings and some deprecated listings.
    • basic_item_attribute: used for a Displayed Attribute like table for notes about attributes.
    • basic_item_code: used for a Displayed Attribute like table for notes about action codes.
    • basic_item_operator: used for a Displayed Attribute like table for notes about action codes.
    • change_item: used for change log items.

    The HTML sitemap uses:

    • sitemap: the 'envelope'.
    • sitemap_titles: the iterating 'letter' template.

    The XML sitemap uses:

    • xml_sitemap: the 'envelope'.
    • xml_sitemap_item: the iterating 'letter' template.

    The Atom feed uses:

    • news_atom: the 'envelope'.
    • newsitem_atom: the iterating 'letter' template.

    The RSS feed uses:

    • news_rss: the 'envelope'.
    • newsitem_rss: the iterating 'letter' template.

    The version checker uses: version-check.

    The build-version check uses: version-build-check.

    The CSS styles page uses: body_text_only.

    The image zipper uses: zipper-images-code.

    The TBX zipper uses: zipper-code.

    The BOILERPLATE includes all use: body_text_only.

    A 'redirect' template is included for later use when the current baseline is superseded, diverting users to what will be the new URL.

    A few other basic templates are also included for general test/admin purposes.

    What is the 'Zipper'

    To make sense of the build checking feature, it is necessary for aTbRef's author to remember to upload a ZIP of the current aTbRef's TBX. Although saving the TBX before full HTML output remains a manual task, the 'Zipper' note uses as its export template a runCommand() action to use a command line to zip the current TBX and place it in the root of the aTbRef export folder ready for FTP upload; nothing is actually exported in terms of HTML for the Zipper note.

    As the working directory for Command Line calls called from Tinderbox is '/' (i.e. volume root) it is necessary to encode the path to from there to the TBX: it is in $MyString for the Zipper note.

    Unless anyone shares the same path on their Mac for storing their local aTbRef TBX this mechanism is unlikely to affect users wishing to make local HTML exports. At worst you will acquire an extra zipped copy of the TBX.

    What is the 'Zipper-images'

    This process makes a separate zip of the images folder for download by those wanting the image for local use.

    You can safely delete the note if exporting locally.

    Turning off Google tracking

    As of late August 2011, Google analytics tracking code has been added to the pages. The code is only intended to track pages running on the 'atbref.com' domain, but those using the the TBX to create their own local sites may wish to remove this code: details for this follow further below.

    The tracking code is google-supplied JavaScript inserted in the head of the 5 HTML page templates (basic, basic_change, basic_grabs, basic_menu_bars and sitemap). The code is inserted via a conditional include ($UseGoogleTracking) and is stored in the note /Boilerplate/google-tracking.

    The conditional include has been used to allow those using their own local export and uses this code:

    ^if($UseGoogleTracking)^^include(google-tracking)^
    ^endIf^

    The line break is placed deliberately inside the if statement to avoid a blank line being emitted should the if condition evaluate as false. The controlling user attribute is a Boolean, making disabling the include very easy:

    • Open the Attributes palette at the User pane.
    • Find and select the user attribute UseGoogleTracking.
    • In the 'Default value' box, delete true and replace it with false.
    • Click the 'Change' button. This step is important as it saves the change made in the last step.
    • Done!

    Older aTbRef baselines

    As new Tinderbox versions can bring significant change, a new sub-sites is created for new major version (since v5). Older versions are retained, but not updated and may be found here:

    Current baseline:

    The atbref.com root address auto-redirects to the current baseline's home page.

    The previous versions have been left online at their original URLs above both to aid those using old versions and to honour the many inbound links. Web pages in the old versions have a header indicating the location of the (next) most recent site.

    Colophon

    This file & website were produced using the following tools:

    Searching aTbRef

    All pages now contain a link, in the quick links at top and bottom of the page, to a fuzzy search of the aTbRef corpus.

    If reading the TBX source file, ignore the UTILS section which contains agents, prototypes, etc., used to create and maintain this file.

    Legacy - Web search

    The HTML pages include a Google search box in the footer. Note that if using a local copy you must be online to use the search; Google will search the online pages—that might possibly be more recent than your own—and the search result links will likewise be to the online pages. If you have downloaded the TBX source, simply use Tinderbox's own Find tool to look for things.

    Web engine search was discontinued as we have no control over search engine crawlers and they are often slow to update small sites like this.

    Translating aTbRef

    Not all Tinderbox users are English speakers. So, to try and help with that all pages include an in-page Google Translate feature (below). The feature offers automatic translation of page content into any of the languages supported by the Translate service. Doubtless the translation it gives is not fluent, especially as there will be many technical terms, but it may help non-English speakers get more out of this resource.

    Generating webpages from aTbRef's TBX

    EXPORTING aTbRef

    aTbRef is a document intended, by design, to be exported to HTML.

    The TBX of this file includes the necessary templates to enable that process.

    Origin of aTbRef and acknowledgements

    This TBX and website was created by Mark Anderson, and is essentially expanded documentation of the Tinderbox app. Originally a private resource, experimentation with HTML Export showed how easy it was to make it a web resource. In the spirit of sharing online, the website is offered as a public resource. As the source TBX holds all the export templates and shows a few interesting code techniques, it too is offered as a downloadable resource.

    The current document is baselined on version 11.0.0. As not all users have the latest release, ongoing changes are recorded with the version where they first appear (since the benchmark version), which should aid those who do not upgrade regularly. Any per-release references to incremental changes since the previous baseline have been deleted (with a few deliberate exceptions).

    The first version of this document 'aTbRef.tbx' and associated website was written in April 2005 to reflect a baseline of Tinderbox v2.4 features and has been regularly updated to encompass all version changes since. The original baseline and subsequent versions online are listed here. The previous versions have, for the while, been left online at their original URLs above both to aid those using old versions and to honour the many inbound links. Web pages in the old versions have a header indicating the location of the (next) most recent site.

    Although there are probably no original notes left, the original document was based on a TBX originally created by Benoit Pointet; that document was called 'aTbRef' and the name lives on herein. The original document I inherited looked very different—see images here and here. From that source (c. February 2005) the document was greatly enlarged before first being published as a website.

    Special mention must be made of Eastgate's Mark Bernstein who has been extremely helpful along the way in answering all sorts of obscure questions and has shown a lot of patience in his explanations.

    Much of the update data is drawn from the Release Notes kindly provided by Eastgate as part of the Tinderbox downloads. Parts of this document that directly quote copyright materials from Eastgate Systems Inc., e.g. the manual, release notes, etc., and do so with permission from Eastgate Systems Inc.

    This document, in its public form is not meant to replace or supplant the manual or the wiki as references. Instead it is simply a way of sharing what I have learned from the kindness of others about Tinderbox.

    Thanks/kudos to:

    • Mark Bernstein & Eastgate Systems, Inc. for answering so many questions, for all the release notes and their permission to use Eastgate materials here.
    • Benoit Pointet for the TBX that became the seed of this file and which gave it its name. (no current link, but here, via Internet Archive).
    • Matt Neuburg for his article (here, via Web Archive) on writing Mac Online Help files in Tinderbox (for Affrus) which got me started on structured HTML export and specifically the hierarchical site navigation used in the website pages.
    • Fellow Tinderbox users. Most recently in the user-to-user forum, but also previously in the old forum (now dark) and its predecessor the Tinderbox wiki (now dark). Their questions have contributed to the depth, scope, and heavily interlinked nature of this resource. Their errata have also helped keep things correct. So, 'Yes', errata are genuinely welcomed!

    Creative Commons Licence

    This Tinderbox and the web pages created from it are written and published as a public resource for users. In case anyone would like to use the work in locations where there may be a requirement to prove permission for use of a third party's work, a Creative Commons licence has been applied to aTbRef:

    Attribution-NonCommercial-ShareAlike 4.0 International (CC BY-NC-SA 4.0)

    By this licence, you are free to:

    • Share: to copy, distribute and transmit the work
    • Remix: to adapt the work

    …under the following conditions:

    • Attribution. You must attribute the work in the manner specified by the author or licensor (but not in any way that suggests that they endorse you or your use of the work). Please use this Attribution.
    • Non-commercial. You may not use this work for commercial purposes. The following Waivers are already granted.
    • Share Alike. If you alter, transform, or build upon this work, you may distribute the resulting work only under the same or similar license to this one.

    Please note that any of the above conditions can be waived if you get permission from the copyright holder.

    Nothing in this license impairs or restricts the author's moral rights.

    The full licence may be viewed here: https://creativecommons.org/licenses/by-nc-sa/4.0/ 

    Attribution

    Mark Anderson should be acknowledged as the creator of this Tinderbox document (plus associated images, HTML export templates, etc.) and website produced from it.

    Parts of this document that directly quote copyright materials from Eastgate Systems Inc., e.g. the manual, release notes, etc., and do so with permission from Eastgate Systems Inc.

    The input of the following (as further explained at 'Origin of aTbRef') should be acknowledged: Mark Bernstein & Eastgate Systems Inc., Benoit Pointet, and Matt Neuburg.

    Waivers

    Eastgate Systems Inc., the creators of Tinderbox, are granted a non-expiring waiver to use the content here in part or whole in any commercial endeavours of Eastgate Systems Inc.

    Mark Bernstein, the designer of Tinderbox, is granted a non-expiring waiver to use the content here in part or whole in any personal or commercial endeavours.

    Errata and contacting the author

    This is effectively a continual work in progress. Please send any errata for this file & website to the author Mark Anderson: mwra@mac.com.

    Techniques & demos hidden in the TBX

    Although aTbRef originally evolved as a way to share extra information about Tinderbox and to explore what could be achieved using HTML export, the project has continued to explore methods of using features, even if they are not exported. If you have the TBX look at (note that many of this page's links only work in the TBX as their destination notes do not export):

    • Splitting content from the back-of-house notes. Visible data of the web site is created by exporting the first root note "A Tinderbox Reference File" and its contents. Everything else—prototypes, templates, boilerplate code, etc.—is stored outside the 'content' area. The two pools of data rarely need to be worked on together via agents so splitting the two out makes for more efficient maintenance and upkeep. There are a number of items at root level as this reflects the needs of export. Be aware that Tinderbox cannot export a note to a relative position other than in its relative (TBX) outline location. Thus if you want all notes to reference a single CSS file it is best to place that at the TBX root level, etc.
    • A map view of note colours. All the predefined Tinderbox colours and their shades. Also used to create an online image. The listing shows the hex values for all the defined colours/shades.
    • A map view of shapes, borders and patterns. A map showing various map visualisation aspects. Also used to create an online image.
    • Agents to restate major listings. Look at each of the listings of action code, attributes and export codes. Notice how there is a main listing and then this is re-started divided up by scope, purpose, etc. The agent in some cases use colour to make the main list (within the TBX) more visually descriptive as to purpose. Look at $AgentPriority setting which have in some cases been reduced to ease loading of the main update cycle time.
    • Controlling agents. In the root-level UTILS section are various upkeep agents, mostly set to 'off' when not needed. An 'all agents' agent allows all such agents to be found and controlled from one location, whether in the content or back-of-house.
    • Timelines. Although aTbRef does not output timelines, both the Change Log and Previous Versions containers can be viewed as Timelines and will show relevant data. The Previous Versions uses child notes that are not exported.
    • Prototypes. These are used mainly for the notes in the 3 big lists, which use a number of special-to-context attributes for their Displayed Attributes. An agent-based prototype is used for the per-version change log entries. Setting just the new version number initialises a number of other features.
    • Boilerplate code. The export template code is kept less complex as certain common-to-all-pages code is stored as 'boilerplate' and used in templates via ^include()^ code. In the original HTML$ templates this made more sense as there were 5 primary page templates for content, each reflecting some different layouts.
    • Images. Whilst image support has varied over Tinderbox versions, aTbRef has deliberately not used embedded images. This both gives more export control (formatting, compression, naming) and allows for a smaller overall TBX. All images are placed in a root level folder and simply the filename is stored in the note, the template figuring out the path. This also allows for the images themselves to be linked to from elsewhere are reference material. Having only one image per note (if any) was a deliberate design choice originally to facilitate template design and may be reviewed in later versions as image support is improved.
    • Image Linking. An agent 'Image Linker' has its $File set to the local location of the 'images' folder used to store the images used by webpages (you can adjust it if using your own local TBX copy of aTbRef). All notes using a web image store the image filename in $WebImage. The agent finds these notes and sets their $File to the agent's $File + a / + the note's $WebImage. This correctly sets $File for the note allowing the linked image to be viewed (via Finder) from the TBX. This assumes you have downloaded the images. One small exception is where the Doc-level preferences that repeat App-level ones are alias notes but use a different screen grab (stored in a separate attribute). The latter notes will open their original's image but in the circumstances that does not really matter.
    • Images and templates. Originally there was a template for 'wide' images, which needed to sit above $Text as opposed to most that could mix with text. In the HTML5 versions this is removed as image inclusion is based on the image attribute and a Boolean landscape/portrait attribute.
    • HTML export. All templates used are stored in the TBX in the Templates container. Originally the export was in HTML4 and used tables. This has been replaced by HTML5, and a resulting reduction in the overall number of page templates. The older set are retained, for comparison, and can still be used for local export. Template and boilerplate code notes with a '5' in their title are for HTML5 use. Compare the old and new versions to see how improvements have been made.
    • Conditional includes. The ^similarTo^ code involves more computation for export: with such links included it takes 20 times longer to export the whole site. Thus the boilerplate note used to generate this output has a Boolean to enable/disable the include. Try exporting in each condition and note the difference. The Switch for this has moved to the calling template.
    • HTML sitemap. This is a simple envelope/letter technique to map the whole site as a single HTML outline. Far too large an HTML page for real use, this is really just a demo.
    • XML sitemap. Use to help Google spider your site more efficiently. The XML is very verbose and creates an 8+MB file. For this reason export of the XML sitemap is turned off by default (use HTML view on that item to enable it). The note calling the export has $HTMLDontExport shown as a Displayed Attribute as toggling the 'Export' box on HTML causes the view to re-preview the code which can be slow. This export alone generates a c.8 MB XML page, so do not turn it on unless you really want to see it at work!
    • RSS & Atom feeds. These are basically two different flavours of the same form of syndication, and especially useful for those who use newsreaders. Both feeds use an envelope/letter method of export. As the agents making the feeds look for changed items, these are deliberately placed at the end of the root so they process at the end of each agent update cycle (which proceeds in outline order across the file).
    • CSS. The file uses a Code prototype for the note holding CSS code to avoid things like hash characters being misinterpreted as quicklist items. The is no specific benefit to maintaining the CSS this way. At the time it was just another test of what was possible. It also helps keep everything needed in one place. Indeed, except the images the whole site uses only data stored in the one TBX.
    • The Zipper-images and Zipper notes are used to make up-to-date Zips of the images folder (as this is not part of the TBX) and a Zip of the TBX itself. Although Tinderbox runs all agents before starting a full export, there is no easy means to trigger a save, so if using this technique it is best to run a forced update ('Update now', via the File menu) and save manually (again via the File menu) before running a full HTML export.
    • See more.

    Tinderbox Documentation And Other Resources

    The primary form of official documentation for Tinderbox is the Tinderbox Manual (the app's macOS HTML Help). This also includes the Release Notes (pre-v6 these were a separate TBX file). The Manual is accessed from the Help menu.

    Eastgate offers user-to-user help via the Tinderbox forum (https://forum.eastgate.com). This resource, 'aTbRef' also available online at https://atbref.com/atbref11/index.html, although it should be noted it is not an official Eastgate resource.

    Other Eastgate resources:

    Third-party resources:

    If it is necessary to obtain downloads of Tinderbox versions other than the current one, e.g. because the user has not extended their licence, then use https://www.eastgate.com/download/ and select the DMG file for the appropriate version.

    Tinderbox Tutorials: aTbRef's author has a Tinderbox tutorial web page linking to a number of tutorials.

    Further Resources

    The Tinderbox Manual

    The Tinderbox Manual is provided in Mac HTML Help format and is accessed via the programs Help menu.

    Also contains the Release Notes.

    From time to time, a PDF generated from the app Help is made available from Eastgate's Tinderbox download webpage.

    Release Notes

    The Release Notes are provided as part of Tinderbox's built-in Help. Additional notes about new features, enhancements and fixes are added for each public release.

    Open the Release Notes from the Help menu, select 'Tinderbox Help'. When the Help window opens, choose 'Release Notes' from the listing on the opening page.

    Shoantel's Tinderbox Tutorials

    aTbRef's author has created a number of Tinderbox tutorial webpages which are listed here: https://www.atbref.com/tb_clarify/index.html.

    Some Tinderbox pre-history

    This article it may help some users get a better understanding of some of the ideas and experience that fed into Tinderbox's design.

    By current standards, Tinderbox is a long-lived app. Work began on a project called 'Ceres' after the launch of Storyspace v2.0 on 24 January 2001 http://www.eastgate.com/Development/40.html and https://web.archive.org/web/20010202192100/http://www.eastgate.com/Storyspace2.html and continued through 2001 with active use in making several blogs, including Mark Bernstein's own blog, e.g. https://www.markbernstein.org/November01.html. Indeed, in his blog, the day after release, Bernstein notes https://www.markbernstein.org/Feb0201.html#note_6210 that Tinderbox v1 and Storyspace v2 share a common underlying framework on which work started 15 August 1999. Meanwhile, work on Ceres started on April 20, 2001. By 14 May 2002 work on a version for the newer Mac OS X was already underway, with v1.1.0 supporting OS X being released on 1 June 2002.

    In late 2002, the 'development peekhole' site mentioned work on Tinderbox for Windows, but that project was eventually abandoned. Probably usefully so as maintaining close integration with two very different OSs whilst trying to keep feature parity would need a bigger team. Mentioned 10 Feb 2004 (https://web.archive.org/web/20040607115854/http://www.eastgate.com/Development/).

    In July 2003, the Tinderbox wiki opened at http://www.eastgate.com/bin/wiki.cgi (now dark) and was the first user forum.

    Ceres was used to publish its first weblog on 1 June 2001 https://web.archive.org/web/20010603192437/http://www.eastgate.com/Development/. Also see https://www.eastgate.com/Ceres/index.html.

    Shortly before launch, the program's name was changed from Ceres to Tinderbox in January 2002 (https://web.archive.org/web/20020201200841/http://www.eastgate.com/Development/ note for 23 January 2002), though the rationale for this change was not given. Tinderbox launched on 18 February 2002 after around a year of development under the working name 'Ceres'. At launch, system requirements for Tinderbox stated :

    "Tinderbox runs superbly on all modern Macintosh computers. We recommend a G3 or G4 and MacOS 8.5 or later. Tinderbox runs beautifully on iMacs and iBooks. Tinderbox takes up about 5M on your hard disk (less if you don't need the manual). It likes to have 16M of memory, but can cope with much less if you're short of space." (https://web.archive.org/web/20020212070749/http://www.eastgate.com/Tinderbox/download.html).

    The Ceres/Tinderbox Development Peekhole which blogged ongoing development last posted in 28 April 2007 (https://web.archive.org/web/20070527181023/http://www.eastgate.com/Development/).

    During 2013-14, the Tinderbox codebase was completely overhauled and re-written on current Apple development frameworks in Xcode, launching as v6.0.0 in May 2014. At the same time the UI was completely changed, reflecting changed user expectation and the change of underlying frameworks. Lost in the new frameworks was the old ability to drag links between windows. Indeed, the zeitgeist as the time was for single window apps that such a model proved not a good fit for all Tinderbox users and multiple document windows and a small number of independent report windows soon returns to the app.

    An upside of the move to Xcode has been coherent Unicode support throughout the app, noting that not all users are using English or languages using roman script. The latter feeds through into support for locale based sorting, time and date formatting, etc. Recently, Tinderbox has also begun to experiment with some of the AI aspects in newer frameworks (thus OS requirements above baseline) to detect major language and possible key terms.

    Storyspace

    As noted, Tinderbox reflects some features and concepts in its older sibling program, Storyspace (http://www.eastgate.com/storyspace/). Storyspace is notable for being about the (only?) early hypertext system still in active development and use and is an import milestone in the area of literary hypertexts. Much of the canon of the latter was/is still published by Eastgate using Storyspace: http://www.eastgate.com/catalog/Fiction.html. More on Storyspace's place in the hypertext story is documented in Chapter 6 of Belinda Barnett's book Memory Machines (https://www.anthempress.com/memory-machines-pb).

    Storyspace was developed as a tool for writing—and reading—'literary' hypertextual works, although its users found other uses for the application. Storyspace's design reaches back to initial work by Bolter & Joyce in the mid 1980s, written in C and available on Mac And Windows. Eastgate took on the 'publishing' of the Storyspace app from its originators in December 1990 and has maintained the system since, re-coding it twice in the process. Firstly it was done in Pascal, upon Eastgate taking over in the code base (for Mac and Windows). Then in 2015, for Storyspace v3, the app was re-coded to share elements of the code structure used in the v6+ Tinderbox re-build. As this employs Apple Xcode, Storyspace v3+ only supports macOS only.

    The Storyspace app is occasionally updated to reflect changes and improvements in the Tinderbox code base. This unification of the code bases for Storyspace and Tinderbox means they now share many UI elements and a common XML data file format.

    Reflecting its roots in early hypertext literature, Storyspace v3 can still open early Mac & Windows files in the app's original formats.

    Hypergate

    Eastgate was also involved in early hypertext systems, creating the Hypergate app in the late 1980s and Web Squirrel (for making link collections in the early days of the Web) in the 1990s. Hypergate is notable in terms of being the first use of a 'breadcrumb' notion of showing where you are, such as seen at the top of aTbref webpages or the in-app view breadcrumb bar. Interestingly, the original concept was a means to tell the user they had visited a page before, noting that in those days, hypertext navigation was new and confusing to most people.

    Academic Record

    Both Tinderbox and Storyspace have been regularly cited (since 1987) and used in papers published in a number of journals and proceeding, most notably the ACM Hypertext Conference (https://dl.acm.org/conference/ht) where Mark Bernstein is the more prolific contributor and author or the most in-conference cited paper Patterns of Hypertext (https://dl.acm.org/doi/10.1145/276627.276630). A good number of Tinderbox users employ Tinderbox in their research so Tinderbox also has an (un)credited part on a good number of other academic papers and PhD theses (all the research analysis for aTbRef author's PhD was done using Tinderbox as the primary tool).

    Some other Tinderbox-related Eastgate products

    Books

    Mark Bernstein has written/ or edited a number of books on or related to Tinderbox, and Storyspace. All are published by Eastgate Systems. Some of the books are only obtainable as e-books:

    • The Tinderbox Way. 2006. This discusses the some of the design philosophy behind Tinderbox. It has been updated several times and is currently in its third edition. Print and ebook version, see: https://www.eastgate.com/Tinderbox/TinderboxWay.html.
    • Thinking in Tinderbox. 2025. The focus of this book is the remarkable practice of using things — paper, notecards, but especially computer software such as Tinderbox — to assist thinking. The author is also interested, in turn, in the ways that ideas in art, literature, and philosophical thought shape the systems we use. See: https://eastgate.com/Tinderbox/ThinkingWithTinderbox.html.
    • Getting Started With Hypertext Narrative. 2015. Published, in PDF form as part of Storyspace v3 app (https://www.eastgate.com/storyspace/).

    Books on hypertext more generally:

    • Reading Hypertext. 2009. Various authors, edited by Mark Bernstein and Diane Greco. A collection of articles/essays relating to research and criticism of hypertext. See: https://www.eastgate.com/catalog/ReadingHypertext.html.
    • A Festival of Narrative Automata. 2017. A e-booklet produced to accompany Mark Bernstein's workshop "Festival Of Narrative Automata: Critical Theory for Fun" at the 28th ACM Hypertext Conference at Charles University, Prague CZ (2017).
    • Interwingled. 2019. A book produced alongside Mark Bernstein's 48-hour Hypertext Challenge and panel session at the 30th ACM Hypertext Conference at Hof University, Hof, DE (2019). Limited availability.

    Academic Papers

    Below are a few published papers about, or about using, Tinderbox and Storyspace. Note that it is not an exhaustive list).

    Tinderbox:

    • Kolb, David A. 2002. Aristotelian Spatial Hypertext. Second Workshop on Spatial Hypertext, College Park, Maryland, 12 June 2002. http://www.csdl.tamu.edu/~shipman/SpatialHypertext/SH2/. Discsses Tinderbox and hypertext
    • Mark Bernstein. 2003. Collage, Composites, Construction. In Proceedings of the Fourteenth ACM Conference on Hypertext and Hypermedia (Nottingham, UK) (HYPERTEXT’03). Association for Computing Machinery, New York, NY, USA, 122–123. https://doi.org/10.1145/900051.900077. First paper on Tinderbox.
    • David A. Kolb. 2004. Twin Media: Hypertext Structure Under Pressure. In Proceedings of the Fifteenth ACM Conference on Hypertext and Hypermedia ((Santa Cruz, California, USA) (HYPERTEXT’04), 26–27. https://doi.org/10.1145/1012807.1012817 and longer essay at https://www.researchgate.net/publication/221267282_Twin_media_Hypertext_structure_under_pressure.
    • Bernstein, Mark 2009. Shadows in The Cave: Hypertext Transformations. Journal of Digital Information (JoDI). 10, 3, 1–8. PD, via CiteSeer https://citeseerx.ist.psu.edu/document?repid=rep1&type=pdf&doi=808b53c908492841abf33fb8ded74bc16f7b3eea. Re Tinderbox export. Note: An inattentive librarian archived the JoDI, which accepted hypertext articles assuming they were PDFs so the images are now lost in the JoDI archive.
    • David A. Kolb. 2009. Other Spaces for Spatial Hypertext. Journal of Digital Information (JoDI). 10, 3.
    • Mark Bernstein. 2011. Can We Talk about Spatial Hypertext?. In Proceedings of the 22nd ACM Conference on Hypertext and Hypermedia (Eindhoven, NL) (HT’11). Association for Computing Machinery, New York, NY, USA, 103–112. https://doi.org/10.1145/1995966.1995983. Re the visual grammar of maps.
    • Mark Bernstein. 2019. 48 Hour Hypertext Challenge. In Proceedings of the 30th ACM Conference on Hypertext and Social Media: Tear Down The Wall (Hof, DE) (HT’19). Association for Computing Machinery, New York, NY, USA, 299–300. https://doi.org/10.1145/3342220.3345458. q.v. book Interwingled.
    • Mark W. R. Anderson and David Millard. 2022. Hypertext’s meta-history: Documenting in-conference citations, authors and keyword data, 1987-2021. In Proceedings of the 33rd ACM Conference on Hypertext and Social Media (Barcelona, Spain) (HT’22). Association for Computing Machinery, New York, NY, USA, 96–106. https://doi.org/10.1145/3511095.3531271. Re using Tinderbox for research.
    • Mark Bernstein. 2024. A New View: A hypertext view without boxes and arrows. In Proceedings of 35th ACM Conference on Hypertext and Social Media: Creative Intelligence (Poznań, PL) (HT’24). Association for Computing Machinery, New York, NY, USA, 65–69. https://doi.org/10.1145/3648188.3678214. Re Gaudi view.
    • Mark Bernstein. 2024. A Novel Architecture for Classical Hypertext. In Proceedings of 35th ACM Conference on Hypertext and Social Media: Creative Intelligence (Poznań, PL)(HT’24).Association for Computing Machinery, New York, NY, USA, 302–308. https://doi.org/10.1145/3648188.3675147. Re Map posters.

    Storyspace:

    • Jay David Bolter and Michael Joyce. 1987. Hypertext and Creative Writing. In Proceedings of the ACM Conference on Hypertext (Chapel Hill, North Carolina, USA) (HYPERTEXT’87). Association for Computing Machinery, New York, NY, USA, 41–50. https://doi.org/10.1145/317426.317431. Note: Bolter and Joyce were the original creators of Storyspace, before Eastgate Systems later took over development of the app.
    • Michael Joyce. 1991. Storyspace As a Hypertext System for Writers and Readers of Varying Ability. In Proceedings of the Third Annual ACM Conference on Hypertext (San Antonio, Texas, USA) (HYPERTEXT ’91). Association for Computing Machinery, New York, NY, USA, 381–387. https://doi.org/10.1145/122974.125110.
    • Mark Bernstein. 2002. Storyspace 1. In Proceedings of the Thirteenth ACM Conference on Hypertext and Hypermedia (College Park, Maryland, USA) (HYPERTEXT ’02). Association for Computing Machinery, New York, NY, USA, 172–181. https://doi.org/10.1145/513338.513383.
    • Mark Bernstein. 2016. Storyspace 3. In Proceedings of the 27th ACM Conference on Hypertext and Hypermedia (Halifax, Nova Scotia, CA) (HT ’16). Association for Computing Machinery, New York, NY, USA, 201–206. https://doi.org/10.1145/2914586.2914624.

    Change Log

    This section logs changes since v11.0.0b733 release (12 September 2025) which was the baseline for this updated issue of 'aTbRef'. Tinderbox Help also contains a listing recent changes that includes bug fixes which are only of direct relevance to some users.

    The links below summarise changes in each version and link through to things that have been added or changed in that version. There is also a separate list of release dates of older versions.

    Versions from—and including—the v11.0.0b733 baseline:

    v11.8.0b808 (7 Jul 2026)

    Released 7 Jul 2026. Build number is 808.

    Minor changes not necessarily warranting explicit mention in an aTbRef note:

    • AI/Natural Language Processing:
      • MCP: if AI Integration is disabled, Claude and Gemini config files are no longer created if they do not already exist.

    **Updated MCP protocol version in hope that this will please LM Studio.

    • Attribute Browser view:
      • Restored logic for short title in the tab bar.
      • View now updates after Quickstamp is used.
    • Export:
      • HTML Export of notes with numerous paragraphs is now significantly faster.
      • Control characters embedded in styled text could cause trouble when we generate HTML from the text: fix.
      • Fixed an infinite recursion created by requesting $MarkupText of a note which is already exported at markup.
    • Gaudí View:
      • Fixed two race conditions in Gaudí View, in which Tinderbox was excessively aggressive in keeping computation off the main thread.
    • Help:
      • Updated release notes.
    • Import:
      • Solved an unwanted exception when exploding notes by paragraph and setting the title from the first paragraph, if the final note does not end in a carriage return.
    • Map view:
      • Extensive rewrite to the system that draws and animate links in map view. This has been a trouble spot over the years because managing the link layout objects has been a challenge, and it is a good test-case for some more ambitious refactoring. In complex map views in documents with numerous links, performance during drags should be significantly improved.
      • Improved the placement of link arrows in map view, allowing them to deviate from strict orthogonality when the link curvature is significant near the end of the link.
      • A recent fix in Map View caused a new crash when moving notes into a container. That is now handled correctly.
      • Plots: bargraphs now draw the target line, if Target is specified.
    • Miscellaneous:
      • Prevent a crash with making the text thumbnail of a note, if the note has no styled text and its $Text is not valid utf8.
      • Corrected a layout error that cut off the checkbox text of "White Outlines" in Document Settings:Outlines.
      • Handling of tinderbox:// urls should no longer be satisfied with switching to an existing tab of a map view of any ancestor of the desired note.
      • Tab-separated-value (TSV) imports failed if quoted strings contained newline or tab characters. I believe these ought to be escaped as \n and \t, but Tinderbox now handles the case correctly.
      • Addressed a crash in LayoutMap::Remove on heavily loaded systems.
      • Fixed a crash when starting a new thumbnail while a previous thumbnail was still being generated.
      • Tried to address file drag issues in Tahoe.
      • The shape menu in the inspector failed when Tinderbox was localised to German or French.
      • Resolved a pair of potential crashes when changing views or when updating a view layout while the view is being drawn.
      • Resolved an export crash in old files that retain Latin-1 note names.
      • Fixed another shutdown crash, as we need to hold a reference to TbxMap until all the LayoutMap structures have been deleted.
      • Fixed a crash when editing agents. A race condition could occur when updating the agent state and the user interface simultaneously.
      • Added fresh protection against control characters embedded in styled text (see especially Microsoft Word) being copied into HTML CDATA, where they can prevent documents from opening.
    • Table view:
      • When the parent of a table view is the root document, the table was not correctly initialised when the document was reopened.
    • Text pane:
      • A selection of up to 300 notes may be edited in the text pane. A larger selection displays the text pane shader and the count of selected notes.

    v11.7.0b797 (30 Apr 2026)

    Released 30 Apr 2026. Build number is 797.

    Minor changes not necessarily warranting explicit mention in an aTbRef note:

    • Action Code:
      • The List.size() operator failed to count empty elements in lists.
      • Code colouring: when editing code, var declarations such as var:number x=5; are coloured green. However, if the type of the variable was string, the word 'string' was coloured blue because there is also a string() operator. Variables of type 'date' and 'list' suffered a related issue. This has been corrected.
      • Code colouring: in code fields, illegal var expressions are no longer highlighted as keywords. For example, 'var:tensor' is ignored because 'tensor' is not a valid data type.
      • Code colouring: in code fields, the "if" in operators such as sum_if() is no longer coloured as if it were an if() statement.
      • Compound designators that refer to notes which have parentheses in their names are now handled correctly. For example, $Color(nextSibling(/Romans/Cato (the younger))) is now handled correctly.
      • When evaluating an expression with a conditional that lacks an else clause, Tinderbox parsed the token following the if statement incorrectly.
      • Evaluating $DisplayName could easily deadlock or crash if the DisplayExpression referred to $DisplayName. Tinderbox catches this in the most common case: $DisplayName(this). There remain problems when referring to the $DisplayName of other notes if those notes themselves refer back to this note's $DisplayName, but that is likely to be less common.
      • Some actions, like .substr(), anticipate numeric arguments. In the past, these were unable to extract their numeric values from list variables. These operators should now work as expected.
      • .extract() could crash if the text string could not be represented in utf8 or if the pattern was invalid regex.
      • collect(…) allows more indirection. For example, collect(siblings($MyString),$Name) is now supported. (Issue #4543 fixed)
    • AI/Natural Language Processing:
      • Revised the AI Built-In Hints text as well as the tool descriptions visible to AI clients in order to provide more useful information to AI users.
      • Improved MCP detection that an instance of Tinderbox is already running, and improved error messages in MCP-tinderbox logs.
      • MCP could disconnect if its output pipe filled up. That will not happen again.
      • MCP: Tinderbox now adopts protocol version 2025-03-26 rather than 2024-11-05.
    • Attribute Browser view:
      • Standard system colours (for light or dark modes) are used for drawing the Attribute Browser; the view should behave better in Dark Mode.
      • The view maintains an index of its rows, significantly improving performance.
      • Selecting notes for the browser is once again performed in the background.
      • When using the Font Picker in attribute browser, the picker’s font size reflects the actual size in use.
      • The text field in Attribute Browser is better aligned with the URL button.
      • When using tabs to switch from Attribute Browser to a conventional view, if the slider position is moved in the tab switch, the clicked tab could be converted to become an attribute browser. This should no longer occur.
      • The TbxBinPopover for attribute browser now adjusts its height to avoid obscuring more of the window than is necessary.
    • Command Bar:
    • Export:
      • Revisions to HTML Export to clean up handling of unicode characters in templates. With this, Tinderbox bids farewell to class UnicodeString, a compatibility shim that from 2009-2026 helped us navigate from MacRoman to utf-8.
      • Corrected a spurious space emitted after links when exporting Markdown.
      • Corrected an additional export problem when using an $HTMLPreviewCommand.
      • Markdown: exported links are now %encoded, as Markdown requires.
      • ^file^ now exports only the filename and extension of the exported file. Formerly is exported the entire path.
    • Find:
      • The Find Bar now reports context for text-based searches as well as regular expression searches. Previously only regex and expression searches showed context.
      • Mistakes in the FindBar's handling of prototype search have been corrected.
      • The FindBar's prototype menu is now rebuilt dynamically and should remain up to date.
      • The text preview used by Find results elsewhere now respects $TextBackgroundColor.
    • Help:
      • Tinderbox Help indexing should now be working properly. This has never been entirely satisfactory.
    • Import:
      • Exploder: now industrial strength. Much faster and far more reliable when exploding thousands of notes.
    • Inspector:
      • Corrected the vertical constraint for the Action label in the Links pane of the Document Inspector.
      • The Quickstamp Inspector suffered from a layout issue when opened from the Command Bar.
      • Added optional 'target' argument for bargraph() and plot() container plot types.
    • Map view:
      • Dragging a locked note or adornment outside the map pane had the effect of dragging it despite the lock.
      • Links did not always refresh after link creation or changes to map scale.
      • View refreshes should now be significantly faster in very large maps.
      • In map view with sufficiently large and complex maps, links could be drawn in the wrong position after vigorous scrolling.
      • The View Background Editor has been adjusted to be easier to understand. In addition, controls that are only pertinent to maps are hidden in other views (sued by Outline, Chart, Treemap.
    • Miscellaneous:
      • Corrected a crash in MCP after closing a document.
      • Problems in JSON parsing of strings ending in escaped quotation marks have been cured.
      • Rewrote the typeahead mechanism in views in order to provide better support for non-English note names.
      • The Command Bar's knowledge of aTbRef has been updated.
      • Extensive work revising the plumbing that connects different views to the text pane and the rest of the main window.
      • TbxSyntaxHighlighter failed to recognise matches where the regex metacharacter $ should match the end of the text.
      • TbxSyntaxHighlighter revised to eliminate some edge cases and for tidiness.
      • Tinderbox documents with active actions now autosave less frequently when Tinderbox is in the background.
      • Fixed a deadlock between computing $TextMarkdown in the background and the progress indicator.
      • Prevented a deadlock that could occur when hoisting a view while editing the name of a note.
      • Rewrote PropertyList to move responsibility for concurrency safety from Node to PropertyList. This simplifies Node.
      • Simplified the communication channel between the text pane and the view pane.
      • Refactored paste and inter-window dragging to avoid code duplication.
      • Extensive refactoring to improve MultipleMoveAction and to prefer MapPoint to SPoint in NodePosition.
      • Revised Undo to use a TbxUndoContext.
      • Addressed a reported crash when drawing image thumbnails, apparently caused by undocumented complications in threading in macOS imageAt:.
      • The Badge Picker no longer clears the current badge on opening.
    • Outline view:
      • Outline Layout has been revised for correctness at small text sizes, and to remove unnecessary complexity.
      • In outlines, notes with $NameAlignment of centered were drawn (as they should be) left-aligned, but when editing the name they were centred. All Outline item titles, other than separators, are always left-aligned.
    • Text pane:
      • The preview pane no longer caches images, and should now reflect any changes in externally-edited images.
      • Fixed extraneous error beeps when moving the pane splitter in outline view, when the text pane had the focus.
      • Revised Preview navigation policy to open links in the default browser but not to open iFrames in the browser.
      • In circumstances not well understood, a series of copy/pastes in the text pane could confuse the text pane into thinking some paragraphs were right-to-left when they were not.
      • The text pane was ignoring strikethrough.
    • Windows:
      • The WindowText Only and WindowView Only commands remember the previous position of the pane splitter. Invoking them a second time restores the splitter to its former position.This version is cited in the following notes:

    v11.6.0b779 (26 Feb 2026)

    Released 26 Feb 2026. Build number is 779.

    Minor changes not necessarily warranting explicit mention in an aTbRef note:

    • Action Code:
      • The List.size() operator failed to count empty elements in lists.
      • Lists (List, Set and Dictionary) now allow blank (empty) list items when using the new [ ] list notation. As a result, a trailing semi-colon will imply the intent of a last list item that is empty.
    • Inspector:
      • The Inspector should more reliably reflect the current document.
      • The layout of the appearance inspector has been modified. If this layout is palatable, it may be used elsewhere.
      • Rewrote the mechanism through which Tinderbox lets you choose colours.
    • Map view:
      • Zoom-out (⌘-⌥-^) and zoom-back were miscalculating their scale factors and needed to force a new layout in order to get the new portRect. Both zoom-out and zoom-back have a new animation.
      • The tendency of Map View to shift when changing performing zoom-in/zoom-out cycles should now be ameliorated. Errors in link placement after changing the view focus should also be reduced.
      • Map view scaling has been rewritten with better animation.
    • Miscellaneous:
      • Fixed a crash in complex hyperbolic views when dragging the view during animation.
      • Fixed a loading crash arising because RTF parsing is not thread safe.
      • Addressed a rare hang when resetting the map layout while changing a note’s title or subtitle.
      • Extensive revisions to internal map view infrastructure to clarify coordinate systems.
      • Map view scaling has been rewritten with better animation.
      • Fixed a shutdown crash when a document is closed while a watch process is in progress.
      • View splitter: A cause for the view pane splitter to sometimes "snap back" after the user has moved it has been identified and rectified. Several small glitches in pane splitter management have been corrected.
      • Added many recent operators to the command-bar’s repertoire.
      • Revised management of the Recent Documents List. It should now be more robust when changing Tinderbox versions.
      • Fixed a crash in the Plot Inspector that could occur when switching between documents.
      • Fix a TbxWindowController crash in b778.
      • Several popovers could be awkward to dismiss, requiring clicking in the text pane or in the view pane. This has been corrected. Some popovers affected include Get Info, Link View, Key Attribute Picker, Explode, Map Background, Parking Space, and Summary Table.
      • When switching views, the selected note is now scrolled into view.
      • When using the breadcrumb bar to set focus, the target note is now scrolled into view.

    This version is cited in the following notes:

    v11.5.2b771 (21 Jan 2026)

    Released 21 Jan 2026. Build number is 771.

    Minor changes not necessarily warranting explicit mention in an aTbRef note:

    • Miscellaneous:
      • Removed unwanted and spurious animation in chart view.

    This version is cited in the following notes:

    v11.5.1b770 (20 Jan 2026)

    Released 20 Jan 2026. Build number is 770.

    Minor changes not necessarily warranting explicit mention in an aTbRef note:

    • AI/Natural Language Processing:
      • Notes with long texts pasted from Claude Desktop were slow, because they can contain thousands of paragraphs, each needing to be scanned for quick lists. We now avoid this scan in more cases.
    • Hyperbolic view:
      • Corrected an error in force-directed layout of Hyperbolic view, is which crosslinks could recurse without limit.
    • Inspector:
      • The Inspector window is hidden when Tinderbox is running in the background.
      • Improved the layout of HTML Inspector Markup, Style, and List panes.
    • Map view:
      • Major revisions to map view with regard to animation management.
      • The scroll position of maps and outlines should be recorded more consistently, and honoured more effectively when switching tabs.
    • Miscellaneous:
      • The recent fix of the crash observed when auto fetching DEVONthink files failed to fix the crash. I believe this update will do a better job.
      • Corrected a crash in NodeNetworkUpdate, caused when asynchronous tasks called back to a NodeNetworkUpdate that no longer existed.
      • The cache for inbound links in the Roadmap window inadvertently cached outbound links.
      • Large documents are loaded and saved more quickly.
      • Corrected several typos in Tinderbox Help.
      • Renamed the prototype "LaTeX" to "A LaTeX page", and made its DisplayedAttributes more sensible.
      • Renamed the template "LaTeX" to "LaTeX Document'
      • Revised the LaTeX prototype.
      • Resolved a crash in TbxIconView, which stored obsolete Node pointers in notes slated for recycling. Awakening Tinderbox from the background could briefly display table rows with stale node pointers.
      • More work on ensuring that the Change manager responds appropriately to stressful situations, especially on fast machines.
      • Addressed a crash when an agent action modified a stamp while we are saving the file.
      • Fixed a thread leak when running HTMLPreviewCommand.
      • Fixed a crash if the MCP server was closed while a tool was in use.
      • Fixed a crash when cmd-opt-dragging a reference from Bookends, which now updates asynchronously (and much faster).
      • Adding the option-modifier to resize handles was much harder than it ought to have been. Created a new TbxResizeHandle object to isolate and simplify the complex logic involved in resizing.
      • Addressed a crash when closing TbxExportProgressIndicator; we should not attempt this close asynchronously.
      • Addressed (again) a crash in Breadcrumb Bar, which continued to try to display its tabs while the document was being closed.
      • Tinderbox should now be more willing to save tabs in which the view window is completely collapsed.
      • Moving to a new, faster version of Base64 caused problems when reading old documents. We now fallback to the older version if problems arise, and save documents using the newer version.
      • A small loophole may have been able to delete style information intermittently in the previous beta. It should now be closed.
    • OS Dark/Light modes:
      • Displayed Attributes table. Added a light tint to the attribute column to further set it off, now that it is smaller; this tint adapts automatically in dark mode, and is only available in macOS 14 (Sonoma) and later.
    • Text pane:
      • Tinderbox is more aggressive in applying $LineSpacing changes to note text. A change in line spacing is applied throughout the text, overriding the previous setting.
      • Modified the Displayed Attributes table to more aggressively reclaim space that is not actually required for attribute names, allowing more space for value display.
      • Syntax Highlighting rules now accept a font: command. Its argument is the PostScript name of the font, which can be found in FontBook; for example, ArcherSSm-Medium. The font: command should precede a size: command if you wish to set both typeface and size.

    This version is cited in the following notes:

    v11.5.0b759 (18 Dec 2025)

    Released 18 Dec 2025. Build number is 759.

    Minor changes not necessarily warranting explicit mention in an aTbRef note:

    • Action Code:
      • The JSON parser has been replaced. The new parser is more strict with respect to acceptable JSON, but this should seldom cause significant problems.
      • Protected the create() operator from requests to create a note with an unreasonably long name.
      • In dictionaries, the key is always treated as a string, and need not be quoted. If the value of that key is a string, it should be quoted. It must be quoted if the string value contains any of the following: {}():// or quotation marks.
    • AI/Natural Language Processing:
      • MCP: The fix in error reporting claimed for b737 was ineffective. MCP errors have been reworked to confirm to the specification. The results are significantly improved; for example, if you ask Claude to set the value of an attribute "37Hike!", Claude will now understand that this is not a valid attribute name.
      • MCP: the create_note tool can now create multiple notes in the same container. This should make tasks like "Create 72 notes" significantly faster.
      • New, unnamed documents continued to give Claude fits, because an unnamed document was considered to match any document name. This should now be clarified.
      • The get_notes tool did not distinguish aliases from original notes. Now, names of aliases are italicised, and aliases are explained in the tool summary.
      • If get_notes is asked to retrieve a note by path, and the note is not found, Tinderbox returns a tool error rather than a successful retrieval of 0 notes.
      • The get_notes tool returns the $Name rather than the $DisplayName of a note. $DisplayName confuses Claude, as it tries to use the DisplayName to construct a note path. There is scant offsetting benefit.
      • MCP: Gemini was unable to use the set_value tool, because it requires explicit assurance that isError is false. This should now be corrected.
    • Attribute Browser view:
      • Attribute Browser can be sluggish in large documents because finding all the unique values of an attribute requires examining every note. We now do this in parallel on up to eight processors, if available, for better performance.
      • Addressed a crash when categorising notes in Attribute Browser.
    • Get Info:
      • The scale slider allows more range to accommodate larger windows, e.g. if the tab is dragged larger when a torn-off window.
    • Hyperbolic view:
      • Substantial improvements in internal computations in Hyperbolic view.
      • Additional revisions to Hyperbolic View for better layout and improved numerical stability.
      • Hyperbolic view’s layout works poorly if it has too many notes to deal with. In any case, visualising notes near the centre is more useful than trying to reposition small specks near the edge. To improve performance, hyperbolic view now shows only the ~50 notes closest to the centre of the view. As you drag the view, notes that approach the centre appear and very distant notes disappear.
    • Import:
      • Revised the File ▸ Watch mechanisms for DEVONthink, Tot, Notes, and Finder to use a more modern asynchronous design and to avoid a variety of concurrency issues.
      • DEVONthink watch folders could crash if the document was closed or a note was deleted as the asynchronous operation was pending.
      • Revised Bookends import to use asynchronous scripts, which also increases import speed significantly.
      • Revise TbxScriptingImporter to handle asynchronous scripts properly.
      • Corrected a crash in Tot importer.
    • Map view:
      • Map View: adornments of zero width are now drawn as separators — lines that might be used to separate groups of notes. (This is the behaviour last seen in v50
    • Miscellaneous:
      • AutoFetch formerly declined to auto fetch resources that had been checked in the last 5 minutes. This limit is reduced to five seconds for file and x-devonthink resources.
      • Auto fetching a DEVONthink item with an x-devonthink-item URL failed when Tinderbox was launched by Claude. This is an entitlement problem which Anthropic will need to tackle eventually, but for the present we do fetch the text from the $SourceURL file if it can be found.
      • Corrected a very old and very intermittent crash on close, which turned out to involve links from a note to one of its children, or vice versa.
      • Corrected a crash after quitting, caused when the Inspector receives a periodic notification as nodes are being deleted. We now cancel observers before deleting nodes.
      • Corrected a remaining crash in TbxTextAttachment, arising when a weak variable was released within a very short window.
      • Addressed a crash in AgentManager::NotifyObservers. This has a dispatch_async that was using a stack-based object that no longer existed when the dispatch block ran. Also addressed a similar issue in RuleManager.
      • SDiamondShape leaked a path.
      • InformationCity leaked a font reference.
      • Fixed a very tricky race condition in TbxNoteWriter’s prepare method, which partitions its work among many processors. An ill-documented lazy evaluation caused great headaches.
      • Addressed a crash when writing Tinderbox documents.
      • Addressed a crash when sorting notes while running rules.
      • Addressed several distinct reported crashes during quit.
      • Addressed a crash in code field autocompletion when closing a document.
      • Added more localisations: Crosstabs, Hyperbolic, Gaudi, City, Table, Chart, Treemap, Attribute pickers. French and German ought to be roughly complete.
      • Revised Tinderbox’s approach to synchronization of access to attribute values in different threads. This should ultimately improve performance while reducing the likelihood of hangs.
      • Modified TbxTextView updateText: to avoid infinite recursion when trying to set text that won’t fit.
      • Support for QuickLook—the mechanism by which Finder displays a preview of a Tinderbox document when you select it and press the spacebar—has been suspended. Tahoe doesn’t support the current mechanism, which also causes some performance issues with git.
      • Watching a DEVONthink group could block Tinderbox if DEVONthink failed to respond. This can happen, for example, if permissions are not forthcoming. This should no longer block Tinderbox.
      • Updated Tinderbox Help.
      • Extensive changes to Tinderbox's indexing system, which is used for similarity measurement, link suggestions, and the word() operator. The concurrency model of this system was flawed, making Tinderbox slower than necessary.
      • Revised the link manager for thread safety.
      • Revised TbxRoadmapController, which manages the Links panes in the text pane, to improve thread safety during shutdown and eliminate deadlocks in tests.
      • Revised the Change Manager, which coordinates screen updates in views when the underlying data change.
      • Revised LayoutMap, which manages data for Map, Outline, Chart, and Treemap views.
      • A major refactoring effort has clarified the action language parser.
      • Further efforts have been made to rectify an intermittent crash in the TbxTextAttachment queue.
      • Various fixes for handling complex strings in dictionaries, such as strings that contain BOM markers and those that contain empty strings (e.g. <a href="..." alt="">)
    • Roadmap view:
      • Roadmap view consumed lots of processing power when the current note had numerous inbound or outbound links. This has been substantially reduced.
    • Text pane:
      • HTML View now syntax colours HTML tags.
      • Text did not reflow after the width of the text pane (or text window) changed. This was a side-effect of changes to prevent recursive text layout when pasting complex tables and related formats into narrow windows. Text now reflows correctly.

    This version is cited in the following notes:

    v11.0.1b737 (29 Sep 2025)

    Released 29 Sep 2025. Build number is 737.

    Minor changes not necessarily warranting explicit mention in an aTbRef note:

    • Action Code:
      • The .split() operator always split at emoji, which is not correct behaviour. Now fixed.
    • AI/Natural Language Processing:
      • In MCP, at attempt to set the value of an attribute that does not exist is now an error. The error message (to Claude) suggests creating the attribute and explains how to do that.
    • Miscellaneous:
      • Addressed a crash when switching map views with open auto delete timers.
      • Addressed a formatting error in Tinderbox News.
      • Modified document closing to remove an ugly delayed-execution block. This should reduce crashes on quit.
      • Tinderbox Help had the wrong path for claude_desktop_config.json

    This version is cited in the following notes:

    v11.0.0b733 (12 Sep 2025)

    Released 12 Sep 2025. Build number is 733.

    Minor changes not necessarily warranting explicit mention in an aTbRef note:

    • Action Code:
      • Corrected a parsing error that affected operators of exactly 5 letters that take multiple arguments, notably fetch().
    • AI/Natural Language Processing:
      • MCP: Extended the create_note tool to help LLMs make adornments and agents.
      • Corrected a muddle that could disable MCP tools when they ought to have been enabled.
      • Updated Claude’s Readings and Notes in Built In Hints to give Claude a little more Tinderbox savvy. In particular, the Notes now tells Claude to scan the note titles at the start of a session and to retrieve the full text of only notes that pertain to the discussion.
      • Also, added a note on posters to facilitate using Claude to design poster notes.
    • Attributes:
      • $SelectionCount is no longer incremented automatically on selection. This feature was intended to facilitate experiments on read wear (Hill, W.C., Hollan, J.D., Wroblewski, D., and McCandless, T. (1992). “Edit wear and read wear.” In Proceedings of CHI’92 Human Factors in Computing Systems, ACM/SIGCHI, 3-9. https://dl.acm.org/doi/10.1145/142750.142751). That hasn’t happened, and the changing selection counts are a burden on version control.
      • $Container now returns "/" for top-level notes. Formerly, it returned "".
      • Changing the value of $MapBodyTextSize redraws the map view and allows the new value to take effect. Previously, the change took effect only when the view was forced to refresh.
    • Attribute Browser view:
      • Corrected misbehaviour in the URL button in columns of attribute browser.
    • Help:
      • Updated Tinderbox Help with release notes, new sections on AI and Information City, and some proofreading.
    • Map view:
      • In map view, double-clicking the alias of a container now zooms in to the original container.
    • Miscellaneous:
      • Revised TbxTextAttachment’s imageAt: method (again) to prevent a very intermittent but annoying crash.
      • In map view, double-clicking the alias of a container now zooms in to the original container.
      • Chased down an apparent memory leak involving failure to release TbxMap on closing a window. This turned out to be a defective test.
      • Corrected (again) a long-standing but very intermittent crash in the change update system, typically encountered when Tinderbox returns from sleep or a period in the background.
      • Addressed a crash in the highlighter, apparently triggered when the match ran to the end of the text.
      • Highlighter could crash if the regular expression matched the end-of-line meta character $ — for example, if using the pattern .* .

    This version is cited in the following notes:

    Previous Versions To Current Baseline

    Since first publishing, up to and including the current baseline Tinderbox has had 173 public releases up to the current baseline v11.0.0b733 released 12 September 2025. Below are their dates, where known, along with the release dates of Apple OS major versions (listed in italics). Notes:

    Previous Tinderbox releases prior to current baseline:

    Earlier version releases, before aTbRef author's use of Tinderbox. As there is no formal record of the actual release dates of these older versions, some dates have been estimated from available data:

    Endnotes:

    1. During early development, the Tinderbox app was also known as 'Ceres'.
    2. Ceres/Tinderbox design also drew on ideas developed for its elder sister Storyspace. The latter is a hypertext authoring/reading program and which has design routes back to the mid-1980s. Since Tinderbox v6 / Storyspace v3 the two applications use a common file format although amazingly Storyspace will still open Storyspace v1 format files.
    3. Current build number in releases data from the complete new codebase developed for v6+. Up to v5.x development used MetroWerks's CodeWarrior and older frameworks and had limited Unicode support. For v6, the entire code was ported to Xcode and refactored/rebuilt to offer better use of Apple frameworks. A by-product was the loss of older Tinderbox's rich multi-window UI and the ability to drag links between discrete app windows. Needing to embrace the newer single app window design ethic of the time, other affordances have been added to replace those lose and the single window limitation has been relaxed (though inter-window drag remains impossible due to underlying framework limitations).

    Version release vendor URLs

    Note: not all versions had (or still have) a per-version vendor page).

    Original app: https://www.eastgate.com/Ceres/ (N.B. Ceres was the original app name pre-release)

    v2.0.0: https://www.eastgate.com/Tinderbox/updates/Tinderbox2.html

    v2.3.0: https://www.eastgate.com/Tinderbox/updates/Tinderbox23.html

    v2.4.0: https://www.eastgate.com/Tinderbox/updates/Tinderbox240.html

    v2.5.0: https://www.eastgate.com/Tinderbox/updates/Tinderbox250.html

    v3.0.0: https://www.eastgate.com/Tinderbox/updates/Tinderbox300.html

    v3.5.0: https://www.eastgate.com/Tinderbox/updates/Tinderbox350.html

    v3.6.0: https://www.eastgate.com/Tinderbox/updates/Tinderbox36.html

    v4.0.0: https://www.eastgate.com/Tinderbox/updates/Tinderbox400.html

    v4.1.0: https://www.eastgate.com/Tinderbox/updates/Tinderbox410.html

    v4.4.0: https://www.eastgate.com/Tinderbox/updates/Tinderbox450.html

    v4.6.0: https://www.eastgate.com/Tinderbox/updates/Tinderbox46.html

    v4.7.0: https://www.eastgate.com/Tinderbox/updates/Tinderbox47.html

    v5.0.0: https://www.eastgate.com/Tinderbox/updates/Tinderbox5.html

    v5.5.0: https://www.eastgate.com/Tinderbox/updates/Tinderbox55.html

    v5.6.0: https://www.eastgate.com/Tinderbox/updates/Tinderbox56.html

    v5.7.0: https://www.eastgate.com/Tinderbox/updates/Tinderbox57.html

    v5.8.0: https://www.eastgate.com/Tinderbox/updates/Tinderbox58.html

    v5.9.0: https://www.eastgate.com/Tinderbox/updates/Tinderbox59.html

    v5.10.0: https://www.eastgate.com/Tinderbox/updates/Tinderbox510.html

    v5.11.0: https://www.eastgate.com/Tinderbox/updates/Tinderbox511.html

    v6.0.0: https://www.eastgate.com/Tinderbox/updates/Tinderbox600.html

    v6.1.0: https://www.eastgate.com/Tinderbox/updates/Tinderbox611.html (v6.1)

    v6.2.0: https://www.eastgate.com/Tinderbox/updates/Tinderbox62.html

    v6.3.0: https://www.eastgate.com/Tinderbox/updates/Tinderbox63.html

    v6.3.1: https://www.eastgate.com/Tinderbox/updates/Tinderbox631.html

    v6.3.2: https://www.eastgate.com/Tinderbox/updates/Tinderbox632.html

    v6.4.0: https://www.eastgate.com/Tinderbox/updates/Tinderbox64.html

    v6.5.0: https://www.eastgate.com/Tinderbox/updates/Tinderbox65.html

    v6.6.0: https://www.eastgate.com/Tinderbox/updates/Tinderbox66.html

    v6.6.2: https://www.eastgate.com/Tinderbox/updates/Tinderbox662.html

    v6.6.3: https://www.eastgate.com/Tinderbox/updates/Tinderbox663.html

    v6.6.4: https://www.eastgate.com/Tinderbox/updates/Tinderbox664.html

    v6.6.5: https://www.eastgate.com/Tinderbox/updates/Tinderbox665.html

    v7.0.0: https://www.eastgate.com/Tinderbox/updates/Tinderbox7.html

    v7.2.0: https://www.eastgate.com/Tinderbox/updates/Tinderbox72.html

    v7.3.0: https://www.eastgate.com/Tinderbox/updates/Tinderbox73.html

    v7.5.0: https://www.eastgate.com/Tinderbox/updates/Tinderbox75.html

    v8.0.0: https://www.eastgate.com/Tinderbox/updates/Tinderbox8.html

    v8.5.0: https://www.eastgate.com/Tinderbox/updates/Tinderbox85.html

    v8.6.0: https://www.eastgate.com/Tinderbox/updates/Tinderbox86.html

    v8.7.0: https://www.eastgate.com/Tinderbox/updates/Tinderbox87.html

    v8.8.0: https://www.eastgate.com/Tinderbox/updates/Tinderbox88.html

    v9.0.0: https://www.eastgate.com/Tinderbox/updates/Tinderbox9.html

    v9.1.0: https://www.eastgate.com/Tinderbox/updates/Tinderbox91.html

    v9.5.0: https://www.eastgate.com/Tinderbox/updates/Tinderbox95.html

    v9.6.0: https://www.eastgate.com/Tinderbox/updates/Tinderbox96.html overwritten with v9.7.0 content. Original v9.6.0 content viewable via the Internet Archive: https://web.archive.org/web/20231004110922/https://www.eastgate.com/Tinderbox/updates/Tinderbox96.html

    v9.7.0: https://www.eastgate.com/Tinderbox/updates/Tinderbox97.html

    v10.0.0: https://www.eastgate.com/Tinderbox/updates/Tinderbox10.html

    v11.0.0: https://www.eastgate.com/Tinderbox/updates/Tinderbox11.html

    v11.5.0: https://www.eastgate.com/Tinderbox/updates/Tinderbox115.html

    v11.6.0: https://www.eastgate.com/Tinderbox/updates/Tinderbox116.html

    v11.7.0: https://www.eastgate.com/Tinderbox/updates/Tinderbox117.html

    v11.8.0: https://www.eastgate.com/Tinderbox/updates/Tinderbox118.html

    Understanding the layout of aTbRef webpages

    If new to aTbRef, it can be useful to become familiar with the standard elements of the page layout used by every page in the site (except the site map).

    The yellow banner holds the note title and is styled, for those who go back that far, in the manner of older Mac OS app Help files.

    Sections with a grey background are areas devoted to navigational links.

    1. 'Quick' links

    This is a set of links to allow you quickly jump from any page to some of the key listing pages on the site: list of system attributes, list of action code operators, list of export codes, list of designators and a list of date formatting codes. There is also a link to the overall site map, and to site search. Lastly, the 'here' link allows quick copying of the current page's URL (with rich text anchor text 'here'). The latter is useful for copying the location to use in email; it is also useful forgetting the current page's URL when working inside a chrome-less window as when using an SSB (Site-specific browser). The label 'quick links' has no relevance to use of similar terms in the body of aTbRef when discussing link creation.

    This set of links occurs twice on pages. Firstly, at the very top of the page. Secondly at the foot of the page, after any content and navigation controls.

    Searching aTbRef

    The current site search feature was added in v10. aTbRef v11 dropped Web search (via Google, etc.), as it never really delivered: that feature is covered in the Legacy section below. Apart from following links you from the home page there are now two main search methods:

    2. Breadcrumb trail

    Tinderbox exports to HTML as a static website based on the source TBX file's outline view, as it reflected by the listing on the site map page. As nested pages are generally sub-topics of their parent page, the breadcrumb trails can help orient the reader. The trail is a list of colon-delimited page names starting at the site root page and going down to the current page. All trail items to the left of the current page are clickable navigation links to that page.

    The breadcrumb trail is listed twice as indicated in the image. Once above the page title and once below the main navigation bar.

    3. Title ($Name) & app icon

    This part shows the title (generated from $Name) of the current page and displays the app icon for the described version of Tinderbox.

    4. The article's text ($Text)

    For reason's of compactness, the note illustrated here has very little text. Nonetheless, this part of the page is where the body text of the article is displayed. Articles may have an image (only one per article) and if present this is shown at the top of the page.

    5. & 6. Navigation bar

    The top level (#5) shows a link to the (parent)article above the current one (the same as seen in the bread crumb trail (#2 above) immediately to the left of the current note title. On the second row, there are links to the previous and next sibling articles (if such exist) under the same parent.

    7. Translate the page in Google Translate

    Use this widget to access a machine-translated version of the current page using Google's translate.google service. Being a machine translate, some aspects may be very poor, but this service is offered with best intent to help the many Tinderbox users whose first language is not English to gain more use from aTbRef.

    8. Last Exported

    This entry will indicate the last time this page was exported from its source Tinderbox document. A recent date may indicate a change, e.g. fixed typo. If changes occur reflecting new/changed features, the that fact is normally explicitly noted in the text, e.g. "From vX.x.x, there is a…". At each baseline change, i.e. change of major version number, any reference to the last version's subversion releases are removed. Thus, for v9, all in-text references to changes in v8.x are removed but changes to v9.cx.xill be added as they occur.

    Do not worry if the version number seems newer than the current release, or has a number never publicly releasedTbRef's author is generally working in the current beta, thus the differing number from the current public release.

    9. Footer - provenance information

    This simply notes how this content was created and by whom.

    10. Donation button

    Change in circumstances means voluntary contributions towards supporting aTbRef are welcome: aTbRef remains free to use, for everyone. Any donations will go towards hosting aTbRef, time spent testing the app and writing the results up for aTbRef and into the apps needed to test their close inter-app integration with Tinderbox. The donations are taken via PayPal and the button links to a single-page process at the PayPal site. Again, it important to stress that the aTbRef site is free for all to use and any donations are strictly voluntary.

    11. Creative Commons Licence

    This section states the CC-BY-NC-SA Creative Commons Licence under which this information is released (with Eastgate's, Inc.'s blessing), and described here. This is of little relevance to most users, but may prove useful in two circumstances. Firstly, if reusing or formally quoting the content the licence gives you a fairly clear aim as to what you may do without having to ask the to the author. The second is less common now Internet access is less of a novelty. Iy you wish to use aTbRef as a web resource but need to do so on an Intranet, the licence may assist with discussions with local IT staff over whether the resource can be thus used (it can!).

    …and finally…

    If still confused, please visit the Tinderbox user-to-user forum (N.B. that is not formal Tinderbox tech support) at https://forum.eastgate.com.


    Legacy

    Web Search

    [dropped as from v10+]

    Search inputs to use two different search engines are offered: DuckDuckGo and Google. Sadly trying to use major search engines to search changing web content is an exercise in frustration. The search engines index when they like and, despite following the instructions aimed to help their spidering, usually to sub-par effect. Any complaints about this should this be emailed to the search engine company and not to aTbRef's author. Generally, the site map page is the best search resource there is. It should not be so, but complain to the Web Search companies, please!