Assorted Newb Questions


(David) #1

I’m learning Tinderbox and before I use it for the purpose I intend–a large number of research notes–I’m building a couple of simple, but serious, documents to learn how it works. I have some questions so far for which I have not found answers.

Can I change the typeface (font) of the Summary displayed on an agent in map view?

How do people debug actions? Are there any tricks for displaying intermediate values so one can see what is going on? Ideally, I’d like to be able to “print” values to a text file or console. E.g. could I use $HoverExpression as a console?

Is there a way to make Regex arguments to string operators like .replace() case insensitive? E.g. /sold/i versus [sS][oO][lL][dD].

What is the most efficient code for removing a string from the $Text of a note (or from any attribute)? Let me explain by saying I imported about 65 records in TSV after munging it in a text editor. Some of the fields in the records which are now in attributes are not as I would like. So, for example, I have:

$nib whose value is “Delrin, M Ti nib, stubbed”

Eventually I want to append the ‘Delrin’ to $Text and make ‘Ti’ the value of $nibMaterial and I’d like to end up with $nib as ‘M stubbed’

I have an agent with a $Query that gets me the records I want. I have an $Action to do the bulk manipulations. At the moment I’m using .replace with one argument to delete substrings. What I want to do in as few steps as possible is a sequence in which I a) grab ‘Ti’ b) assign it to $nibMaterial c) purge it from $nib. In effect, I want an operator like this:

$nib.excise(“pattern”)=$attribute

If the pattern is found, $nib is set to the remnants of the string with “pattern” removed, and $attribute is set to the value of what pattern actually matched. Obviously, I want pattern matching so the Action is flexible.

I suspect either there is an obvious way to do this or that I am making bad choices about how to structure my notes, e.g. by relying on attributes too much.

I appreciate any suggestions or answers.


(Mark Anderson) #2

Hi. From the questions, I assume your frame of reference is some form of programming or scripting language IDE. Tinderbox action code has grown, asymmetrically, in accordance to users’ needs. It isn’t a programming IDE and does represent the full set of operator a coder might expect. There is no code commenting and there are no - well very few error messages.

The way to debug actions is indeed to catch intermediate states. The whole ‘Sandbox’ group of system attributes grew out of a user habit of using type-named ($MyString, $MyNumber, etc.) attributes for testing. So if an action goes through several states, e.g. returning a List of Paths, then sorting it and de-duping it, all those stages can be passed to and captured in a series of user attributes.

The main regex test of string-type attributes is .contains() which has an .icontains() case-insensitive alternative. The .replaces() operator is case-sensitive so I guess a baed-in-case-insensitive version would be a feature request at this point (at as v7.0.3). Note: I’m not pushing back on the idea, just describing the status quo.

FWIW, whilst attribute names in Tinderbox are case-sensitive (so attribute ‘nibMaterial’ is a different attribute to ‘NibMaterial’) the general style is to use CamelCase. Thus: $Thing, $MyThing. Less usual: $myThing, $MYTHING, $mything, $mYtHing, etc. I shouldn’t matter as long as you follow your own naming conventions but be aware most examples follow the camel case style. I quite appreciate you’re likely pulling names from a different programming environment and fidelity to that may be important.

Escaping quotes is one thing that is hard to do in Tinderbox, but is you’re replacing regex-pattern within a string that happens to include quotes it should work (noting that .replace()z` case no case sensitivity flag).

Dinner guest arriving so no time for a test, but look at back-references as these might help.

Note though that the logic of your action code your pseudocode example is the wrong way about:

output = (result of action code expression)

So your pseudocode would be - in Tinderbox vernacular:

$AttributeName=$nib.excise("pattern"); (white space around operators is ignored)

Must dash, but I hope that help a bit.


(David) #3

Thank you, those are very helpful answers.

The idea of dumping intermediate values into user attributes is a really good one. I suppose I could create a root note called Debug and stock it full of user attributes that I could then use for intermediate values as I try to work out why things do not work.

I can see that back references may be the way to go. Mercifully, the strings in my attributes do not actually have quotation marks, that was an artefact of trying to represent values of strings in my message. But I think I could use some patterns that bypass what I don’t need into one capture, what I do need into the next, and what is left into the third. My new attribute would get $2 and the old attribute would get $1+$3. If this were a language with user-defined functions I could probably just write my excise operator.

I’ll noodle around with these tips for now as I try to achieve my current aims. Thanks again, the speed and thoroughness of response is much appreciated.

Two comments:

I’m a bit surprised that the coding conventions are as you describe. I agree CamelCase is useful, but I deliberately use a lower case beginning because it gives me an immediate clue that it is one of my attributes and not a system attribute.

I do think that it would be useful to have a case insensitive option in every regex pattern–rather than distinct operators. It would be flexible and I think it would be cleaner because it puts the flag in the pattern where, as it were, you can see it more directly.

I should say that I’m having great fun with Tinderbox and the Action Code. The total experience reminds me of when I first met Hypercard.

I hope you had a good dinner.


(Paul Walters) #4

Just note that user attributes (like all attributes in a given document) belong to all notes – although values are usually local to this note. If you use a Debug note (a workable idea, by the way) you’ll want to expose those attributes in Debug’s Key Attributes so that are immediately obvious. Another, less elegant method of tracking intermediate results would be something like

$Color="red";$Text(Debug)=$Text(Debug) + "$Color Result: " + $Color

you can break down your complex code into chunks, create a series of stamps structured like this (silly) example, and apply the stamps one, by one, by one, while tracing the results in the $Text of Debug.

I violate the convention constantly – almost always my attributes are $myAttributes. Nothing has ever broken. :smile:


(Mark Anderson) #5

Amen to the last. For clarity, I’m not suggesting you must use a certain naming convention but that:

  • Don’t be surprised that most examples you’ll find use the CamelCase suggestions.
  • As a result, occasional users of the app trying to help you here or in other forums may—though genuine confusion—suggest that mistyped (i.e. non-CamelCase) names are the cause of the problem under discussion, i.e. false positive scenario.

You shouldn’t be. If you read Mark Bernstein’s blog or his book “The tinderbox Way”, you’ll see the design ethic here is ‘artisanal’. A glass-half-empty interpretation reads that as ‘incomplete in some corners’, others see it as ‘only does things actual users want’—even if at expense of things others might expect. Thus my earlier point about action code not being designed to be a complete programming language.

The author is receptive to well-reasoned arguments. My mention of a ‘feature suggestion’ wasn’t being snarky. If you need such a feature write in and explain. Here, this is a user-to-user space and so by convention suggestions made here aren’t formal requests. Suggestions may get seen and taken up by the app’s author but if you really want something currently missing self-interest suggests it’s worth raising with formal support (info@eastgate.com).

Like Paul, I regularly attempt to do things we didn’t hitherto think might be done. Some things prove easy - others less so - but with an open-ended tool you don’t know until you try!

Like many long-term Tinderbox users here the app is central to my daily work, which would be harder using other tools. I particularly like its support for incremental formalisation - ideal for exploring a problem space (data) whose form you don’t yet know. Also, there is very strong inheritance/prototyping for which you don’t need a programming background to build nuanced and complex structures (me!).

Good luck with your exploration of the app and do ask here if stuck. There are no ‘stupid’ questions - we all know different things . :grinning:


(David) #6

Thank you both, I will put your suggestions to work.

Thank you for this forum, which I have already mined for various answers, and, to you, Mark, for your TB reference, without which I’d’ve probably not even attempted to use Tinderbox.


(Paul Walters) #7

I don’t think this question got answered

Select the agent on a map and use a Quickstamp to change $NameFont for that agent. If you want all your agents to have this setting, create a prototype, change the $NameFont setting, and apply the prototype to the relevant agents.


(David) #8

Thank you for spotting that Paul. I had assumed it could not be changed when no one answered.

OK, I noodled around with that and it led to one or two more questions.

  1. Can one specify a typeface size? For example, say I set $NameFont to “RingsideCondensedSSm-Light”. Can I somehow set it to 18 point or as a scale from normal, e.g. 1.5 times? I tried things like “RingsideCondensedSSm-Light 18” and I found intermittently that the text would change a little, but it appeared just to be kerning changes.

Since atbref says the underlying datatype of a font is action, I’m not sure how those are represented.

  1. Is there anyway to find out what typefaces Tinderbox supports? For example is there a system attribute that is a set of typeface strings internal to the app? I presume that any typeface installed on the Mac can be used, but Tinderbox has some of its own fonts stored here:

/Applications/Tinderbox 7.app/Contents/Resources/fonts/RingsideCondensedSSm-MediumItalic.otf

I’d rather not look in there and they might change.

Thanks again. No good turn goes unpunished.


(Mark Anderson) #9

(edit: this is in answer to David, not Paul less the forum indicate otherwise. I’ve also added a link I forgot to make to the updated aTbRef page mentioned).

Ha - I was just updating aTbRef’s page on container table display to reflect this as the thread prompted me to check those settings. I’ve updated the page: ‘container table display’ to reflect the attribute aspects of what’s belw (thuogh not more arcane font discussion).

Font & font colour. Table Containers, by default are drawn in $NameFont and $NameColor, but if $MapBodyTextColor is set that trumps $NameColor. So the table can’t be a different font from the title but can be a different colour.

Font size. This is a little more complex. It defaults to the default title size (currently 14pt in v7.0.3) but doesn’t change if the title size is altered via $MapTextSize. Instead it is altered via the attribute set to size inline $Text display, i.e. $MapBodyTextSize. IF the attribute names seem confusing, bear in mind, neither $Text nor container summaries were possible in early versions of Tinderbox. So, $MapBodyText size might better be thought of as $NameFontSize - except confusingly it used a magnification factor rather than a point size—again this reflects early app design choices and hasn’t changed so as not to break older documents, a constant headache for long-liver apps (Tinderbox was first released in 2001).

Note the heading and table contents can’t use a different font/size/colour from each other.

So the answer to you first Q1 is to set $MapBodyText, which uses a point size number as its value.

Tinderbox uses the OS font dialog to set fonts. If setting values manually, you may trip up on the fact that fonts real ‘under-the-hood’ name and the screen name used in dialogs etc. You should be able to use any font** correctly installed on your MAc. If unsure of the name to set manually, e.g. in a QuickStamp (as opposed to via the OS font dialog) I’d suggest making a new file, using the font dialog to set the attribute and then looking at the result in Get Info/attributes, i.e. the text string that is stored in that attribute.

** I’m not sure about TrueType vs. OpenType vs. PostScript, etc. If you’re into that sort of nuance I’d email support as some types might not be supported.

Looking at my Macs, the fonts in Tinderbox seem to have been installed onto the Mac so i guess Tinderbox installs the font on first use if not found. That may vary if you’re a pro graphics designer with complex specialist font management software (in that case I’d email support).

I hope that covers your second Q!. If not, just ask!

Indeed. :grinning:


(Paul Walters) #10

It does, except when it doesn’t. E.g., when setting a font in a Quickstamp, Tinderbox does not use the macOS font dialog. An alternate approach to @mwra’s method for getting around the screen name vs. real name issue is using the macOS Font Book application instead of the Fonts dialog that is opened with T. View Font Info in Font Book and copy the “Full name”.


(Mark Anderson) #11

Absolutely agree. This is the point I was getting at in my last re using a test file to see the internal stored string.


(David) #12

I’m fairly sure that Tinderbox does not copy the font files out of its package directory. That would be unusual behaviour and unnecessary given that the macOS “binds” the Resources folder to the lookup path for resources. Also, the font files had not been copied to any of my directories.

Thank you for $MapBodyTextSize which is certainly what I sought.

I confess that it is solely now that I re-read what you said about the Sandbox family of attributes with which every note is endowed. That is a great convenience and, suddenly, dozens of prior posts I have read make a little bit more sense. It had not occurred to me that there would be “convenience” attributes. I’ve also now found the var declaration which I can see will be useful.