Updated scripts for stack, stacklink, and tagger (V4)

About ten months ago, I followed the footsteps of Frederiko’s work and created the script . I “tried” to enrich the functionality, flexibility, and DT3 compatibility of his concept. The result is probably a mix.

The earlier version of “stack” script is my first long script, and it was complexed. I am hesitated to post an updated version. It is difficult(almost impossible) to debug this sort of script when users encounter problem/s unless they have a reasonably good knowledge of AppleScript and DT3, with good patience, and probably need Script Debugger.

This is a minor update (but a major work for me) that either will work smoothly or still be problematic (please don’t use it in such case). I am posting the script even though I won’t be able to provide support because I hope that in one day, some advance user/s may see the value of the underlying workflow, and is willing to write a better and more robust version. I even “dream” about DT to provide a standard script within the next few years. From DT’s aspect, they can produce similar outcomes by adding a few steps following the “summarise highlights” function (I think…).

To me, “Stack” is a workflow of knowledge management. The script creates a linked info-container for each focal document and allows users to extract and take note on a small segment of literature by creating a “card”. All cards from the same focal document are stored in the document’s stack. As each card only contains a portion of the literature, tagging can be more precise, and more accurate tags facilitate targeted retrieval of notes. Also, a supplementary script “stacklink” can create a two-way linkage between different documents(or cards) by replicating themselves into each others’ stack.

This post shows what the scripts do. I will find some time tomorrow to explain the configuration process and the scripts themselves. Noted that there are many options available, and those options can be configured without needing to know and change the script.

(1) I highlight a segment in a paper.

(2) I activate the script. The script asks for a name (can be configured to ask for adding comment, too).

(3.1 ) A card in MD format is created (can be configured to create rtf format). The selected text is also underlined or highlighted according to the user’s configuration.

(3.2) A list of tags is shown, including (1) suggested tags based on keywords matching (if another script “Tagger” is used together with “Stack” in DT3), and (2) the tags of the source socument, and (3) a list of constrained tags groups that is chosen by the user during the setup process.

(4) I activate “openstack” script (a supplement script). All cards within the document are shown.

(5) The paper use Kraatz and Block (2008) as one of its key citation. I want to read that paper later, too. I remember I have that paper and want to link it as the key citation of this paper. I activate the “stacklink” script.

The script asks for which document to link, and I search for it (in same DT databse only).


(6) A list of possible hits and choose the one I need.

(7) I open the stack of Kodieh and Greenwood (2013) and Kraatz and Block (2008) is in its stack, I open the stack of Kraatz and Block (2008) and Kodieh and Greenwood (2013) is in its stack.

Once again, I’m sure that there are 3rd party apps that that do that. But I like DIY.

1 Like

Neat. Looks like a scripted implementation of mesh links between records, similar to Hook.

I wonder if there’s better ways of displaying the “stacks” than the text box modal…

IMHO, the stack script is merely a different implementation of Frederiko’s work with a focus on tagging and more configurable (I hope). The utility script “stacklink” is probably a poor man and DT-only interpretation of Hook. I’m sure that Hook is way more powerful for those who need the capability (e.g. cross-application implementation).

Many people mentioned graphically implementation of links and perhaps two-way links in DT. I honestly have no opinion on that topic.

1 Like

NOTE: Run the script with a test database first. The script doesn’t delete or change any current items in the database, but it is best practice to back up the database before testing the script.

You need to set up five custom meta fields and one tag group (under /Tags) before running the script.

--(1) location to be created or specified and cmd fields to be created -------------
property topTagGpLocation : "/Tags" -- the tag group that contains all tags
property theNewTagsLocation : "/Tags/New Tags/" -- for gathering new tags created when using the script
property mdCardNum : "cardnum" -- data type is "Integer", used by the source document to keep the numbering of cards created in each doc-stack 
property mdStackLink : "stacklink" -- data type is "URL",  used by the source document to hold the link to the doc-stack
property mdSourceLink : "sourcelink" -- data type is "URL",  used by cards and main annotation file to hold the link to theDoc
property mdHasStack : "hasstack" -- data type is boolean, value=1 if a document has as stack 
property mdIsCard : "iscard" -- data type is boolean, value=1 if a doument is the card of a document
--End of (1) -------------

This is how a document holds its stack info: the “stacklink” cmd points to the stack, the “cardnum” cmd keep track of the number of cards created in the stack, and the “hasstack” cmd indicates that the document has a stack.

For a card: the “sourcelink” points to the source document of the card.

WHY “iscard” is needed. I can create a smart group to consolidate all cards of all documents with a simple filter.

WHY “sourcelink” is needed. That cmd is more an experiment of mine. In theory, each card can have one parent (the source) and its many children (the stack of cards of a card). Don’t go there for multi-level stack …

The “/Tags/New Tags” must be created to hold the newly created tags during the tagging process. When “Add New Tags” is chosen together with the other tags, the script will ask for the names of the new tags. “Recently Created Tags” shows the tags in the group “/Tags/New Tags”.

NOTED: you do not “have to” create new tags by this manner but must create this group for the functioning of Stack. I use this function to manage the ad hoc creation of new tags and compare their necessity with the existing tags. I usually move the newly created tags from the group “New Tags” into the relevant tags group at the end of each day.

Configuration for the “Stack”.
(1) This update consolidates the setup script and the main script. To configure(re-configure) the stack, make sure that (1) you are in a viewer window, and the current database is where you need to set up the stack, and (2) DO NOT select any item in the window. Each database has its own topstack, and each topstack has its own configuration. So u’ll need to run configuration for each database for which you want to use stack.
NOTED: a file “StackAndTaggerV4.plist” will be created under the DT’s script menu when the configuration is finished. Just leave it there. The file is used by both the Stack and the Tagger scripts.

(2) Activate the configuration function of “Stack” script. When no item is selected and the script is activated, the script will enter into configuration mode. User should choose “Use a New TopStack” even they have used the previous script - the existing topstack and document stacks will remain the same after the configuration.
NOTE: Check the description of the list box, make sure that the database is the one you need. Don’t worry, the script won’t mess up your database even you have chosen the wrong one.

(3) Choose a location for the TopStack. The gorup “TopStack” is used for holding all document stacks.
NOTED: you cab pick any name for the stack or change its name later. It is because the script only save the uuid of the group that is used as the topStack.

(4) Choose the option to create the card in rich text format (RT) or markdown format (MD).

(5) Choose the option to display backlink in full filename (LF) or just showing the page/paragraph info (LS). If u have other idea on naming, pass it on to me.

(6) Choose how to mark the cited text by the last used highlight colour (MH) or underline the text (MU). If a custom highlight colour is wanted, pick the colour in DT3 preference and setup shortcut key for that colour in macOS preference, the shortcut key must be “shift-control-7”. If no marking is needed, choose (MC), but don’t define the shortcut key “shift-control-7” in macOS.

(7) Choose the option to add a comment to the card (or not) at the time of its creation.

(8) Choose which font to use in the card. If Markdown format (MD) is used, choose any font coz markdown is plain text.

(9) Options for tagging. Choose (TN) for no tagging(tag later). Choose (TP) to show the tags of the source document at the time of a card’s creation. (9.1) You can only use (TT) when “Tagger” script is also used. I will post the “Tagger” script in the near future. (9.2) if (TC) or (TT) are picked, the script will ask the user to update the tag list when they run the script for the first time in each day.

If you choose (TC):

The script will ask for which current tags group under “/Tags” are to be used for choosing the tags when a card is created. However, if there are more than two to three hundred tags under the tags group, it will take a while to load and display the tags after a card is created.
NOTED: I don’t use (TC) coz it’s too slow. I have a powerful iMac and it still takes 6-8 secs to pull a list of 300 tags. It’s better to use (TN) and (TP), or try using (TT). I will post the script in the next few days (it takes time to write).

(10) If you are like me and always have many windows on the screen, you may want to specify a fixed location to place the card when it is created. Else you can pick “none” to let DT deciding where to place the newly created card.

(11) You need to input the resolution of your main screen.

The main script “Stack”.

StackV4b5 (public)____Shift-Ctrl-Alt-K.scpt.zip (239.3 KB)

I will post the info and supplement scripts of “openstack” and “stacklink” tomorrow.

Script “openstack”.

If you do not use “openstack”, you can use the DT’s “Launch” function from the dropdown list of the cmd field “stacklink”, and the whole document stack will be opened in a new viewer window.


I think the supplement script “openscript” brings me more flexibility in opening the document-stack.

(1) The script can be activated when you are reading the literature in a document window, or when you select an item in the viewer window. When the document has no stack, nothing will happen when u run the script. When there a document-stack for the focal document, you will see this:

(2) You can pick one or many cards, and other items that you put into the stack via the script “stacklink”.

NOTE: you don’t need “stacklink” script to place items in the document-stack. But “stacklink” creates a virtual two-way linkage by replicating the related documents into each other’s stack - and will create a new stack for the document that doesn’t have a stack already.

(3) The selected cards/item will be opened in a cascaded manner.

(4) If no item is selected and u click OK, a new viewer window will open for the whole stack.

(5) If you are reading a card, you can also run the “openstack” and the source document will be opened. This is just a minor convenient for myself and probably is useless for the others.

Setup for the “openstack” script"

When a card is created, a card number will be created in the aliases of each card. e.g. “C-0009”. The way the cards/items is displayed in the list box, the position the cards/items/stack is opened, has to be specified in the script. You’ll also need to enter the resolution of the main screen in the script again.

NOTE: The format of “C-0009” is more for sorting purpose and isn’t a unique identifier that can be used for a wiki-style link. For my personal version, the first word in a filename is unique, and my script will add a unique identifier (e.g. P.633-C.0001) for a wiki-style link. I can’t add this function to the public version coz the method for literature identification is different to each user.

-- Sort items in stack by Aliases, else by name
property sortListByAliases : true -- if sortListByAliases=false sort the items in document stack by Aliases
-- How to display the cards and stack on the screen
set {screenWidth, screenHeight} to {3840, 2160} -- resolution of the main display
-- |  1/3 screen vertical : LV/CV/RV  |  1/4 screen horizontal : LU/LD/RU/RD  |  1/9 screen: UL/ML/LL/UM/MM/LM/UR/MR/LR |
set theStackPos to "LD" -- placement of viewer window if the whole stack is opened. 
set theCardPos to "MM" -- placement of an item that is a card
set theDocPos to "RV" -- placement for an item that is a document

The script “openstack”

oStackV2b4(Public)____Shift-Ctrl-Alt-O.scpt.zip (40.3 KB)

Script “stacklink”.

As it is mentioned in the earlier post, “stacklink” is kind of a DT-centric interpretation of Hook. DT has backlink only, and it doesn’t seem like the DT’s architecture is ready for 2-way linkage. So I make use of stack to create a virtual two-way link by placing related documents into each others’ stacks.

NOTES: Stack link is a bare-bone experimental script (I only spend very little time on this script in the last 10 months).


I am reading a paper and there is a key citation mentioned. I activate the script.
I suggest using “d” as the prefix if you need to search for a document or use “o” if you have already opened the other document.

If I need to search for a document, the query string is the DT’s query string except that u need to enter a prefix and a space before entering the string.

The default setting in the script is to use fuzzy search. But wildcard is not supported. Select the item you want to create the link, and replicants will be created
The script only allows the creation of one two-way-link each time to prevent any major screw up that may result in the cleaning up of many replicants!

If the document you want to link is already open, you can use “o” and hit enter.

A list of all opened documents for u to select and link.
NOTE: a document can’t link with itself else DT will enter into an infinite loop. Don’t worry, the script won’t allow that even when the same document is in the list. BUT, just to play safe, make sure that u don’t accidentally choose the document itself to link.

The setup:

The only option is whether to use fuzzy search.

Custom scope: If you are like me, who put all literature in a single group, you can create a custom scope and give the group a prefix. The script will search in that custom group when the prefix is entered.

NOTE: This option is set to “false” in this public version, because the custom scope only supports one database (which is enough for my case).

-- (1) How to search for items to link
-- Standard search includes | d: DB | g: Select a Group | c: Current Group | o: Opened Documents |
-- use does not need to setup (1) if custom scope is not needed
property addCustomScope : false
property theItemSearchInput : ""
property useFuzzyForItemSearch : true
property theCustomScope : {"p"} -- example only, choose a prefix to the custom group
property theCustomNm : {"Papers"} -- example only, choose a name for diaplay in dialog box
property theCustomScopeUUID : {"82DB1186-ECFE-4D1A-9E1E-6079113C52A4"} -- example only, input the uuid of the custom group
-- End of (1)

The script

SLinkV1b4(Public)____Shift-Ctrl-Alt-L.scpt.zip (38.3 KB)