Tinderbox Forum

Building a structure outline in Tinderbox

@moudheus and I are playing around with the idea of being able to build a structured outline in Tinderbox. We found this forum post that got us started (
thank you community).

Now, what we’d like to be able to do is mix up the numbering scheme, i.e. chapter numbers represented in roman numerals, sub-chapters in letters, and paragraphs in numbers.

We’ll then use display expression to visually display this.

The orange arrows are what we get with the outlining tutorial. What we want is to have them all format as illustrated with the red arrow.

Does anyone have a clue how to do this? Is it possible?

1 Like

There is no such built-in mechanism. Past experience is the people doing this would either use an outline-specific app, e.g. OmniOutliner, or add the formatting on export. More recently Tinderbox preview mechanism means this long-form mark-up can be viewed within the app.

SoMe question arise (by way of unpacking adjustments, not critique!):

  1. How many different formats are proposed and based on what standard.

  2. Is the level mark-up tied to current position (i.e. changes if the base container is moved), or does it inhere from a designated root container?

  3. How is this handled in export? As literal characters or in a form that might assist other outliners to ingest it?

I’ve done things like this in the past, but they’re a bit of a kludge and normally end up not being suitable because one or more of the above the points was added as a requirement after the work was done.

Another ui/human factors issue occurred to me and that is are we doing this simply because it gives us the comfort of looking like the UI of some other tool. For instance, if I write such a list in Word, I need to see the styling as it’s a WYSIWYG tool - you are (in default view) looking at the ‘printed’ form of the work. But what if, as becoming more common, I write in a styling agnostic fashion such as mark-up.

On reflection, I think the latter helps makes sense of the questions above. I note that having admittedly fallen down just such “wouldn’t it be cool if” paths myself, in the past, and finding that after finishing some byzantine code that it wasn’t clear what/which problem I’d solved.

That said, I’ll address some potential moving parts of a solution in a separate reply.

Given there is no built-in specialist outliner styling, i.e. for print-style listings, you have several issues to resolve:

  • Where am I? [$OutlineDepth] will tell you how deep you are in the outline (https://www.acrobatfaq.com/atbref8/index/Attributes/SystemAttributeList/OutlineDepth.html). The latter is important in the context of my point #2 above. You may need to calculate the depth-in-outline value based on the depth of a different ‘root’ container (‘root’ as in root of our styled outline branch and not the TBX document root). $SiblingOrder (1-based) will tell an object where it is in the outline order of its parent container, as for some style sequences we can’t simply use a number
  • What style do I apply? If each level of the outline uses a slightly different marker (number, letter, etc.), how and where is this defined. A look-up table for each discretely styled level might help (see linked article).
    *From where do I call the needed style? Again, look-up tables might help as if you know sibling number and style series (see bullet #1 in this list).
  • How do I apply the style?*
    • Edit the $Name*. Possible but impractical… If you move the note the $Name has to be changed and no code acting on the outline can use $Name directly, e.g. in queries.
      Use a Display Expression. A Display Expression can be calculated and shown on the fly but:
      • Consider scale. c.50 notes calculating updating their $DisplayName every agent/rule cycle might be fine for 20 notes but may (depending on the complexity of your naming style) not scale well to 200 or 2,000 notes in the outline. (Don’t fall for the solecism of “it will never get that big”; in the same way no PC has ever needed more than 64k of RAM—things change).
      • Cache calculated style markers. To ease the load on calculating within the Display Expression render, you can calculate the custom outline label, store that in a User string attribute and have the Display Expression simply concatenate that before the $Name (very little calculation)
      • If exporting make sure your templates use $DisplayName and not $Name.
    • Use Export templates. Calculate the custom item styling and apply that when exported or previewed within the doc. This is also useful if you write in a form like markdown rather than in styled text.
    • Use CSS, XSLT, etc, as part of 'HTML (or other formatted) export. This might save you figuring out all the style for yourself.

Lastly, all this assumes you are styling note $Name and not thinking about outlines in $Text (a fair idea if not knowing otherwise). If $Text is in the picture, everything just got more complex.

So, that gives some useful ideas for @satikusala and @moudheus’ project.

Ya, that is what I guessed, but wanted to confirm and not bias the answer through my question.

The method outlined in the original forum post works. To you list below, it allows for market-up to current position and can be easily handled in export codes leveraging outline values. As for formats, there are only three that currently come to mind: roman numeral, letter, number. Clearly there could be capitalization qualifiers on the the first two.

I wonder if a dot.operator feature request is warranted, e.g. outline.format(), with parameters like ® and ® for roman numerals, (a) and (A) for letters. There is not one needed for numbers as that is default.

As for your not of kludging a solution, I agree that to does not feel like it is worth the effort. Once you get to that point let other programs do the job.

1 Like

Amen. For a practical solution without undue work, I’d consider using ‘layered’ prototypes and use colour or badge to denote where things are in the outline. Also, for formatted export/preview I’d go with CSS formatting of lists: see here.

It’s not clear what ‘outline’ is in this context, given that dot.operators attach to data types in literal, attribute value or expression output. The ‘outline’ isn’t a Tinderbox data type as such, so would stretch the existing meaning of a dot-operator. It could be taken to be a list of $Names, but I think it would be doing a far more complex formatting task than List.format(0 currently does, so would better be given a different name.

Also, as it is an action, how is the transform applied? (see my second post above). I think this is where the difference between an outline app (OmniOutliner is closest to mind but is only one of many such apps) where everything is the outline, and Tinderbox where the outline view somewhat more and just one view of the data. This begs the question, how/if the numbering shows up in other views.

1 Like

All great idea.

Elegant. LOVE Tinderbox and how it stretches my rutted pathways of thinking. Paragraphing what I’ve learned from you “if you focus on the outcome and not the process/path one can realize many routes towards the outcomes, some more direct than others, that what may be previously envisioned.”

BTW, LOVE, serendipity. In my effort to help @moudheus we uncovered a capability, lookups, that I actually need right now in another project. A perfect example of you “give to get.” :slight_smile:

I do have a question though. I got the Lookup working from an attribute, but this entry has cofounded me:

Realistically, if using lookup tables the lookup value list will be defined in one note and then referenced by all others. Thus the last example above is more likely:


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:


I’ve not been able to get it to work. Do you have a handy example? I’m assuming what this means is “Put the pipe array in the $Text of another note and call that note…” But alas, I’ve failed, fo now.

Ok, the latter is suggesting that rather than storing the (same) look-up data in the same attribute in Notes A, B and C, it be stored in that attribute in one note. In the example this is in a note with the unique $Name ‘config’.

See this demo look-up test.tbx (76.6 KB)

In the demo, select note ‘config’ and view the look-up list. Now select note ‘NY’ and open its edict in the Inspector and verify the correct $Region has been set. Now select AK and note a not default match has been found. Now, select the ‘AL’ note and enable its edict and then run it and see the $Region is set.

1 Like

Glorious, stupendous, perfection!!! :bowing_man: :bowing_man: :bowing_man: :pray: :pray: :pray:

1 Like

Good, what I take from that is my article is under-specific as to usage. I’ll expand it a bit.

Ya…it was not clear if the array should be in the new note’s attribute or $Text field.

Interesting. I’d never have guessed that if you hadn’t made that point.

In return I’d ask, what line of thought would make you think one would use $Text? The question is genuine and without snark—I want to understand why I’m missing this aspect as it seems to point to a deeper, wider gap in explaining the app.

Although a note’s title and body text are attributes—respectively $Name and $Text—they are not normally used as attributes (other than for storing a title and body text!). IOW, if you need to store list of things why would intuit using a free-form $Text, rather than a list-based data type of attribute, i.e. a Set or List type?

This leads to further wider questions that perhaps impact on your tutorial video projects, so I’ll post a separate message here to keep the two separate.

Actually there are two (perhaps three) exceptions to this:

  1. Code notes – where $Text is used to store action code, input to runCommand(), CSS, etc.
  2. Templates – where $Text is used to store export code
  3. Prototypes (perhaps) – where $Text is used to store inheritable content. This one is a grey area in my mind: whether it belongs to the category that Code notes and Templates belongs to or not.

I very frequently use Code notes, especially, as a place to spell out longish content to load into an attribute.

Like everything else in Tinderbox, one’s understanding of these things depends on one’s mental image of what Tinderbox is and does. Precise definition or consensus is not always possible.

:slight_smile: Questions of inquiry are never (IMO) are NEVER snark - it’s like when you’re walking and you see something out of the corner of your eye, “is it a snake or a stick?” Until you have give your mind to perceive, it could be either. We all come from a different place, so asking qualification questions, for me, is actually a sign of respect and not judgment. :wink: Often, however, especially when we are tired or busy or feeling insecure, it is easy to not see it this way. We’ll, enough philosophizing.

It is because you pull the code from $Text in code notes. That is the first way I learned to pull from other notes, so my mind naturally went there and expected it. This makes me think of an article I recently red on how baby’s develop preferences based on random choice - https://www.sciencedaily.com/releases/2020/10/201002091027.htm. Seems relevant.

I feel like I’ve been able to put on my big-boy pants finally, after so many years. Tinderbox has opened up a whole new world to me in the lat few months. I am grateful to Mark, you, and the others in the community. Thank you!

I did wonder if I should have explicitly mentioned code notes in my earlier reply; these have a history which is perhaps pertinent here. They were a user initiative back in v4.x days, and also before there was a ‘Code’ prototype. At the same time, the input box for action’s like a Rule was much smaller. So, how to write a longer action, especially if using if() branching and be able to see the code. But essentially a code note started as one who’s text was formatted in code style (monospace fonts, no curly quotes and other stylistic auto-coercions.

The ‘code note’ notion also drew on the fact that at the same time (HTML/text export) templates were beginning to be stored in TBXs. Hitherto they were external plain text files but that made it harder to write demos or share files as those most in need of help struggled with the new-to-them task of pointing the doc at the right external file. (If you want to see the app evolving, go look at past versions of aTbRef covering v2.3.4 through to v7.x).

But ‘guilty as charged’ :slight_smile: . These aspects need explaining for those who didn’t live through their genesis. I now see that ‘code’ in notes—templates, code-notes, etc.—is not properly explained (at least not in currently in aTbRef). The cause, though not excuse, is incremental addition. there’s an interesting meta-reflection there for those describing/documenting things. How often do you re-write/refactor your hypertext. After all people just explore links? The latter proves to be perhaps not as intuited—blame applying to neither author nor reader. Plus, _even in Tinderbox_refactoring a hypertext is hard. Hyperbolic view, if developed beyond experimental status should help but we’re not there now. As I’ve learned in my recent studies/research, links are a janitorial (blue-collar authorial) job which we leave to “someone else”.

Sore for drift into things more hypertextual but it is pertinent to describing things for others. I think I’ll start a new thread for the other notes I was going to post.


I found these reflections on the history and the present helpful. Thank you.

I can also see there’s a need to describe somewhere (on my to-do list) the difference between three forms of note where, atypically action or export code is stored in $Text:

  1. (Export) Templates
    These in current versions of the app must live in container /Templates and has $IsTemplate set to true (i.e. ticked in tick-box controls). These are used for storing export code, primarily for formatted (HTML) export. Templates normally have the built-in ‘HTML’ prototype set to turn off unwanted RTF functions. Legacy note: in very early app versions templates were used for text export but this is no longer the case.

  2. ‘Code Notes’
    These are where large sections of code are stored in a note’s $Text. The built-in ‘Code’ prototype is intended for use such as this (though applied by the user, and before first editing the note’s text). Notes of this type are used in two main contexts:

    • Export code ‘boilerplate’. These are notes holding small includes of code or pre-formatted HTML content use as boilerplate in code export. This type of use can be seen in the source TBX of aTbRef.
    • Storing long sections of action code. These can be used to store code that is then used to set Action-data-type attributes (see list) via a rule. The note’s rule sets the target note’s attribute to the value of the code note’s text.
  3. Ad hoc code editing
    Here the note is just used to give a larger (more visible space) editing area for working on action or export code, not least as UI input boxes for such code do not provide scrolling support. Again, the built-in ‘Code’ prototype is intended for use such as this (though applied by the user, and before first editing the note’s text).

Otherwise, export code beling in templates and action code in action-type system attributes or stamps. Note: a stamp cannot be created/edited/deleted via action code, though one can be applied via action code.

[The above will likely end up somewhere in aTbRef in due course]

1 Like