How can I move an internal folder to a specific location

I want to place the Inbox_spare folder under the Inbox folder.
In the current AppleScript code, the Inbox_spare folder is only placed at the top level of the Tinderbox file.
Add this as a child folder of The Zettelkasten Separator.
I would like to add a command to move it.

The AppleScript description is as follows.

SequentialNumbering3.scpt

tell application "Terminal"
	activate
	set currentTab to do script "cd ~/Tinderbox2023/"
	do script "Do Shell Script" in currentTab
	delay 0.3
end tell
set containerName to "Inbox_spare"
set attributeName to "MyAttribute"

set isoDateStr to (current date) as «class isot» as string --> 2021-06-29T23:31:58
set formattedDate to text 1 thru 10 of isoDateStr & " - " & text 12 thru -1 of isoDateStr

tell front document of application "Tinderbox 9"
	if not (exists note containerName) then
		make new note with properties {name:containerName}
	end if
	if not (exists attribute attributeName) then
		set newAttribute to make new attribute with properties {name:attributeName, type:"number"}
	end if
	repeat with i from 1 to 5
		set newNote to make new note at note containerName with properties {name:"Note_" & i & "-" & formattedDate}
		tell newNote
			set value of attribute "Width" to 5
			set value of attribute attributeName to i
		end tell
	end repeat
end tell

I am issuing commands from the stamp using runCommand.
Yours, WAKAMATSU
Inbox_spare

P.S
I was able to create the following stamp and move the folder to the specified location.
Stamp
Move Inbox_space

$Container="/The Zettelkasten/";

If possible,
Using stamps from Run Sequential numbering 2

$Text(log 1) = runCommand("Osascript /Users/kuni33/Tinderbox2023/SequentialNumbering3.scpt");

I would like to move it to the above location using the same command.

Apologies for the edit, but otherwise the script, when copied has typographic quotes due to the forum Markdown. To post a code sample in the forum, the best way is:

new line, 3 backticks (```), new line, your code, new line, 3 backticks (```) new line. Key point is the 3 backticks (```) must both be on their own line of the post before/after the code.

Having fixed that, what isn’t clear is why the Terminal section is included as it isn’t used by Tinderbox. Also, why do you want to use AppleScript or OSAScript to move a folder than can more easily be moved using action code?

To move a note or container (and its descendants) in the document simply set its $Container: see $Container and Moving notes by setting $Container.

This action code (used in a stamp, edict, etc.) does the job:

$Container("Inbox_spare") = "/Inbox";

This assumes ‘Inbox’ is a root-level container (or correct the code accordingly).

So, absolutely no need for any of the runCommand()+AppleScript approach which is much less efficient to ‘just’ move a container in the current document.

To have the script place Inbox_spare under The Zettelkasten divider you can make two small changes, so that your script looks like this:

set containerName to "Inbox_spare"
set attributeName to "MyAttribute"

set isoDateStr to (current date) as «class isot» as string --> 2021-06-29T23:31:58
set formattedDate to text 1 thru 10 of isoDateStr & " - " & text 12 thru -1 of isoDateStr

tell front document of application "Tinderbox 9"
	if not (exists note containerName) then
		set theContainer to make new note with properties {name:containerName}
	end if
	if not (exists attribute attributeName) then
		set newAttribute to make new attribute with properties {name:attributeName, type:"number"}
	end if
	repeat with i from 1 to 5
		set newNote to make new note at note containerName with properties {name:"Note_" & i & "-" & formattedDate}
		tell newNote
			set value of attribute "Width" to 5
			set value of attribute attributeName to i
		end tell
	end repeat
	set value of attribute "Container" of theContainer to "The Zettelkasten"
end tell

The changes were:

  1. Assign a theContainer variable when creating the container.
  2. Set the value of the “Container” attribute for theContainer (second to last line).

I would run a script not from a stamp but pinned to the menu in a Shortcut set up via the Shortcuts app. That way it can be used with any Tinderbox document and you are less likely to run into “escaping” problems for the shell.

@mwra external scripting can be efficient for setting up test documents, for example a set of sequentially numbered notes like this. Also, as noted, external scripts can be “reused” on new Tinderbox documents with no new setup required. IMO, Tinderbox scripting support is robust; documentation of the scripting support is nascent.

1 Like

@sumnerg, yes—this is not a binary right/wrong choice (i.e. use runCommand() vs. action code).

I’m definitely not suggesting Tinderbox scripting via AppleScript, etc., doesn’t work (my apologies if the last reads as such!), but it was not apparent in the above case that it was necessary yo use the command line for such a simple task. So we’re comparing ‘apples nad pears’.

If the task can be done internally via action code, I think using runCommand() is wasteful (thinking of working at scale in a long-lived document). However, it can be necessary because one wishes—as you rightly point out—to do more fine grained where the OSAScript bridge to Tinderbox’s AppleScript can be really helpful.

So, for later readers, I think we’re in agreement—lest it appear otherwise. :slight_smile:

Sorry, am I missing something? Would an action code be more suited for this effort? You could use action code to change the container, no?

$Container="/The Zettelkasten/Inbox/Inbox_spare";

Dear Mr.Sumner Gerard,
Thanks a lot for your instructions on where to change the detailed settings.
I am using your script conveniently.
Since I have your script in my hands, I can take notes on multiple things at the same time.
(The previous writing page was a long time ago, so I post a new one here.)
Sincerely, WAKAMATSU

P.S
Last night, I discovered
In Tinderbox v.9.6.0 Manual AppleScript(P.110)
…returns a list of the agents and adornments inside myNote.
set value of (attribute of myNote named “Width”) to 5

Add [set value of attribute …] at the end of the script. I got an idea.
However, I could not understand the details.

Dear Dr.Mark Anderson,
Thank you for letting me know what you think about posting.
I was copying a “script” that I rarely write, apologize for any inconvenience caused.

This experiment is a review to ensure that I can use the runCommand that I learned.
Also, since I was able to make AppleScript work with Quarto, I am also learning how to write it.
I still do not fully understand ActionCode, so I will continue to use it through trial and error.
I plan to learn how to use simple and effective methods.
Yours, WAKAMATSU

I agree with @mwra that runCommand, while good for running shell scripts, is inefficient for AppleScript. Among other things, that can create “escaping” headaches. Running an AppleScript from Script Editor or, even better, from a Shortcut (AppleScript action in a Shortcut created in the Shortcuts App) pinned to the menu, is almost always better.

Note that you can run Tinderbox action code from an AppleScript using ‘tell myNote to evaluate it with’. That way you can have the best of both worlds, using AppleScript where you want while easily incorporating action code for things that are hard to do in AppleScript. Among other things you can install a “reusable” stamp in the Mac menu bar that can be applied to selected notes in any Tinderbox document. No need to set up a stamp for each document.

If you are trying to learn some AppleScript, note that some of the AppleScript examples in the Tinderbox manual differ from what many people might write:

The example you quoted from the manual:

set value of (attribute of myNote named "Width") to 5

might more commonly be written:

set value of attribute "Width" of myNote to 5

hence,

set value of attribute "Container" of theContainer to "The Zettelkasten"

1 Like

BTW, I’ve just revisited revised what’s covered on AppleScript in aTbRef: aTbRef - AppleScript nottes revised/restructured.

Reports of errors or suggestions for better generic examples are welcomed. :slight_smile:

That is helpful. Thanks!

I would replace the named in all the examples with the simpler, more common syntax. (I see that was changed in a few of the examples).

I can’t get set selection to myNote to work here. Maybe I’m doing it wrong.

Possible useful generic examples for scripters:

To put a list of names (also works for other attributes) of all selected notes into an AppleScript list (theNames):

tell selection of front document to set the theNames to value of attribute "Name"

One 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

Not for basic documentation, of course, but here’s a script that illustrates a few of the many things that can be done: run Tinderbox action code for trig functions that AppleScript doesn’t have to position notes on the canvas in a circle, create links using act on, etc.

Click triangle to see script
-- have a Tinderbox document open, then run; create a "Circular" container at root

property containerName : "Circular" -- name of empty container at root level
property noteSpace : 8 -- spacing between notes on circle --  vary as wanted
property offsetOnPerim : 140 -- vary to adjust position of starting note in circle perimiter
property noteWidth : 4.25 -- width of each note on circle
property linkLabel : "" -- label of links (if any)

set perimNoteNames to {"the mentally unfit don't have to fly", "but don't claim you're unfit!", "combat missions are dangerous", "and fear is a rational response to danger", "so the fearful and traumatized are not unfit"}
set centerNoteName to "Unfitness is fitness!"

-- alternative demo - uncomment following two lines to see
-- set perimNoteNames to {"Tinderbox is a toolbox", "toolboxes have many tools", "many tools require more skills", "more skills require training", "training limits flexibility"}
-- set centerNoteName to "many tools lead to rigidity!"


set noteCount to length of perimNoteNames --  number of notes to place in circle

-- calculate length of perimeter needed for that spacing, number of seats
set cPerim to noteCount * noteSpace

-- derive the radius from perimiter
set cRadius to cPerim / (2 * pi)

-- set the origin (intersection of x & y axes on Tinderbox map)
set {xOrigin, yOrigin} to {0, 0}

-- make center of circle 1 radius to the right and 1 radius down (TB y-axis is inverted; positive is down)
set {xCircleCenter, yCircleCenter} to {xOrigin + cRadius, yOrigin + cRadius}

set noteRecords to {} --  an associative list to hold information that will be used to create notes 
repeat with i from 1 to noteCount
	
	-- calculate the angle for that note
	set cAngle to (i * (360 / noteCount))
	
	--adjust position of first note on the perimeter
	set cAngle to cAngle + offsetOnPerim
	
	-- convert degrees to radians
	set cRadians to cAngle * (2 * pi) / 360
	
	-- calculate offsets from center of circle with basic trigonometry formulas	
	set hOffset to cRadius * (my cos:cRadians) -- cosine is adjacent/hypoteneuse
	set vOffset to cRadius * (my sin:cRadians) -- sine is opposite/hypoteneuse
	
	
	-- apply offsets to derive map coordinates
	set {xPosition, yPosition} to {xCircleCenter + hOffset, yCircleCenter + vOffset}
	
	-- give note a dummy name in sequence
	set noteName to item i of perimNoteNames
	
	-- place name and coordinates into AppleScript record and add record to the associative list
	set end of noteRecords to {thename:noteName, x:xPosition, y:yPosition}
	
end repeat

-- noteRecords -->{{thename:"Note 1", x:10, y:10}, {thename:"Note 2", x:6.4, y:12.7}...}

tell front document of application "Tinderbox 9"
	
	-- create the container if it doesn't already exist
	if not (exists note containerName) then make new note with properties {name:containerName}
	
	-- stop script if the container already contains notes
	if notes of note containerName is not {} then error "Make sure container is empty and run again"
	
	-- loop through the associative list and tell TB to create a note for each record there
	repeat with aRecord in noteRecords
		
		-- make new note in specified container at coordinates in that record
		set newNote to (my makeNewNote:(thename of aRecord) inContainer:containerName xCoord:(x of aRecord) yCoord:(y of aRecord))
		
		-- add any desired customization to the note
		tell newNote
			set value of attribute "MapTextSize" to 90
			set value of attribute "Width" to noteWidth
			set value of attribute "NameAlignment" to "center"
		end tell
		
		-- use Tinderbox action code to link new note to its previous sibling - TB just ignores if no previous sibling
		act on newNote with "linkFrom(prevSibling," & linkLabel & ")"
		
	end repeat
	
	-- complete the circularity by linking last note to first note
	act on newNote with "linkTo(firstSibling," & linkLabel & ")"
	
	-- add a note in center of circle (if wanted)	with large font
	set centerNote to my makeNewNote:centerNoteName inContainer:containerName xCoord:xCircleCenter yCoord:yCircleCenter
	tell centerNote
		set value of attribute "MapTextSize" to 110
		set value of attribute "Width" to 5
		set value of attribute "NameAlignment" to "center"
		set value of attribute "Shape" to "oval"
	end tell
	
end tell

-------------------------- handlers / subroutines ---------------------------------

-- handler to make a new note at a specified location in front Tinderbox document
on makeNewNote:thename inContainer:containerName xCoord:xPosition yCoord:yPosition
	tell front document of application "Tinderbox 9"
		set newNote to make new note at note containerName with properties {name:thename}
		set value of attribute "Xpos" of newNote to xPosition
		set value of attribute "Ypos" of newNote to yPosition
		return newNote
	end tell
end makeNewNote:inContainer:xCoord:yCoord:

-- AppleScript doesn't have native sin and cos functions -- so just borrow them from Tinderbox!
on sin:cRadians
	tell front document of application "Tinderbox 9" to evaluate it with "sin(" & cRadians & ")"
end sin:

on cos:cRadians
	tell front document of application "Tinderbox 9" to evaluate it with "cos(" & cRadians & ")"
end cos:

I’ve forgotten how I figured out all that trig. But aside from its demo value this is good at creating circular arguments! … Or Catch 22.

1 Like

I think it is meant to be:

set selected note to myNote
-- or
set selected note to note "Test note"

That seems to work.

I’ve fixed the ‘named’ examples but haven’t had time yet add any new content. Still, progress of sorts. Edited pages and TBX updated.

1 Like

I think it is meant to be:

Yes, that seems to be the answer to that part of the puzzle.

I tried:

set selected note to myNote

and,

set selected note to note "MyNoteName"

(where the note named “MyNoteName” is at root level)

They place the cursor as expected when in Outline view (and presumable other views as well).

Yes, indeed. So, I’ve updated my AppleScript pages further, clarifying:

  • AppleScript named matches case-insensitively (unlike Tinderbox itself). Be aware that code note "X" still implicitly uses named as it is only a short way of writing note named "X".
  • properties of the note object
  • making references to notes
  • selections

I’m reminded that, if not used regularly enough to remember usage and object structures, AppleScript’s ‘natural language’ method of coding is very confusing. Happily we have a few folk here who are good with AppleScript to put us back on track!

†. Even using the wonderful AppleScript Debugger app I’m regularly left completely lost as to how to address things.