Simplest form of inheritance for citation


(Lew Friedland) #1

In taking notes on a single source, I want to make notes within that source that inherit the prototype (journal article) and author-title-information already filled in. So all of the children of the reference would contain its information. What’s the simplest way to do this?


(Lew Friedland) #3

Thanks Paul. They are children of a filled in note. I did create an on-add prototype, but how assign the values of the master note automatically? I can’t remember that step.


(Mark Anderson) #5

I’d do it like this in the parent reference note’s $OnAdd:

$Prototype=$Prototype(parent);
$Authors=$Author(parent);
$ReferenceTitle=$ReferenceTitle(parent);
... i.e. any attributes you wish to use the parent's values)

This approach avoids hard-coding any per-reference values. Do note that the reference note’s OnAdd fires once per child added. If you correct the $Authors data, for example, that correction will note update existing child note’s but will be reflected in all new child notes. You could make children inherit by making each reference note into a discrete prototype but i think that’s overkill and, if you’ve a lot of reference notes, doesn’t scale well as a solution. Better is do add either both of these:

  • A stamp using the attribute setting part of the OnAdd above, e.g. $Authors=$Author(parent);, etc.
  • Use the same code in a edict in the child notes. Thus within an hour, at worst, any edits to the reference not will percolate to its children. Note, too that you can do an on-demand one-pass update of all edits by manually refreshing agents (File menu); the latter’s a bit counter-intuitive at first read but easily remembered after first use.

(Lew Friedland) #6

Thank you Mark. Makes perfect sense and works. Could you explain the logic of the second option, particularly the one-pass update of all edits by refreshing agents?


(Mark Anderson) #7

OK, the first action sets the new (reference) child note to use the same prototype as the parent (i.e. article) note. Most commonly a prototype sets a note’s Key Attributes (KAs), i.e. what is listed in the KA table. However, as values inherit from the prototype and not via the parent we need additional code to set local values in the new note so that some attributes reflect those of the parent. This is what the second and third lines of the quoted code are doing. Exactly which and how many attributes are altered will vary according to the project, i.e. it is an exercise for the user.

‘refreshing agents’. This may have been misread as suggesting use of agents. Actually, I was referring to edicts and how they me be refreshed manually, on demand. I suggest reading this article on edicts and how they work. The idea of using an edict is that if you change a value in an article note that were set in child notes when they were created, the child notes will need updating as the parent’s OnAdd only runs when a new child is created.

If you’re not bothered about the speed of such updates but rather that they do occur at all and without your intervention, you could set an edict in child notes that resets the desired attribute values to those of the parent. If going this route, it might make sense to make a new prototype based on the one for article notes but with the additional edit defined. If so, don’t forget to change the OnAdd code of the article prototype to set the the new prototype.


(Lew Friedland) #8

Have implemented this system thanks to all of you. Now am having a glitch. Perhaps someone can see what’s wrong.

I have a book reference prototype with complete information.

In that prototype there is on-add code for a book note:
$Prototype=Book Note; $Authors=$Authors(parent); $BookTitle=$BookTitle(parent); $Publisher=Publisher(parent);$Theme=Theme(parent);

The note inherits authors and publisher properly (so the book note prototype is working), but not the book title.

The field names are identical as far as I can see. Can anyone see a glitch here? Thank you.


(Mark Anderson) #9

Just checking, was the parent $BookTitle was populated before the reference note was added? $OnAdd only fires once. Updates to the parent don’t inherit. It may well be something else, but this aspect of OnAdd behaviour crops up often enough to warrant mention.


(Lew Friedland) #10

Mark, yes, all of the information that you see in the “Dark Money” book note was there before the note was added. The only thing I can think of is that even after I add the note (a new note under the book prototype) when I indent it (to add) I still have to manually set the prototype. So maybe that is firing twice?


(Paul Walters) #11

The book title has a colon in it. I wonder if that’s affecting the outcome?


(Mark Anderson) #12

The specimen data works for me. DSo there must be another factor. @lfriedla, can you post a minimal TBX showing the issue occurring so we can check for other factors.

As a side note, and though I believe not a factor here, it is best practice to quote literal string values. Thus:

$Prototype="Book Note"; 

(Lew Friedland) #13

Thanks Mark. Here is the reduced file with prototypes, some bib entries, and notes. TestBib.tbx (100.7 KB)
Also, thanks for best practice note.


(Mark Anderson) #14

OK. Incidental note - in making the demo prototype “Book Note” gained an extra space, i.e. “Book Note”. Once fixed the OnAdd prototype assignment works correctly.

The “Book Note” - as with some other prototypes has this $Rule (I’ve added line breaks for clarity):

if($ReferenceRIS.contains("AB  -")){
$ReferenceRIS.contains("AB  - ([^\n]*)\n");
$Abstract=$1.replace("AB  - ","").replace("\n","")
} else {
$Abstract=""
};
$BookTitle=ArticleTitle;
$KeyAttributes=
$KeyAttributes-"Journal"; 
$KeyAttributes=
$KeyAttributes-"ArticleTitle";

The error is here:

$BookTitle=ArticleTitle;

I believe you want to set $BookTitle to the note’s value of $ArticleTitle rather than the literal string “ArticleTitle”:

$BookTitle=$ArticleTitle;

[edit corrected the above code example]

rather than:

$BookTitle="ArticleTitle";

Side note: this is actually a good practical example of why it doesn’t help to make Tinderbox guess whether an assignment is a string literal for an attribute value reference. Anyway…
But as the “Book Note” prototype’s $OnAdd doesn’t set the new note’s $ArticleTitle, the result is after adding, the new child note’s rule sets $BootTitle to the (empty value) of $ArticleTitle.

This is a familiar story of (accidental) garbage-in-garbage-out. I’m not sure of the intent/scope of the rule which i suspect is being inherited incorrectly or perhaps wasn’t even mean for this prototype bu got cloned via basing it on a prototype that used the rule.

But, if you sort out your rule and make sure it runs where needed, then make sure the OnAdd applies the necessary values to reflect the rule, you should be good to go! :slight_smile:


(James Fallows) #15

Mark, I wonder whether there is a typo or something missing in this quoted part of your very useful explanation. Or (more likely) whether there’s something I’m not understanding correctly.

As far as I can tell, the two versions of the code you mention – $BookTitle=ArticleTitle; – appear to be the same, though it looks like one is meant to illustrate a coding error and one is meant to be the fix.

Is the fixed version meant to be $BookTitle=$ArticleTitle; (adding the $ marker)? Or, eg, $BookTitle=$ArticleTitle(this); (adding a specific reference)? Genuine question, based on my not understanding this part of the answer. As always thanks for your quick and generous help to all of us.


(Lew Friedland) #16

Thanks as always to Mark A and the generous community.
Just so folks know, the $BookTitle=ArticleTitle" problem entered because when importing the RIS from Zotero, the fields are switched and I had to flip them in importing into TBX. That appears to be where the confusion has entered, but I’ll need to go back through the code, and also figure a more parsimonious way of making the TBX fields concord with the Zotero RIS import.

Jim, the intention is $ArticleTitle, or at least to the generic reference, not to a specific article title. I’ll go thorough all the code again and see if I can clean it up. As an aside, thanks so much for the contribution on using the attribute browser, which I have incorporated into my own workflow, and also for Our Towns, a great book.


(Mark Anderson) #17

Profuse apologies - you are right. Typo fixed up-thread. Essentially if I write:

$BookTitle=ArticleTitle;

Tinderbox has to guess if I actually meant to specify mean:

$BookTitle=$ArticleTitle;

or

$BookTitle="ArticleTitle";

If I recall, Tinderbox tries the first context (i.e. using an attribute value)and failing that assigns a string literal.

Indeed, this is what happens here, the failure is that a rule is setting $ArticleTitle to no value and that empty string is then passed to $BookTitle.

This is probably an instance where it makes sense to use a stamp or OnAdd rather than a rule/edict. If you need a one-off process, a rule/edict/agent action needs some sort of conditional test to ensure the action runs only once and in the right conditions.


(James Fallows) #18

Thanks to @mwra for the explanation, and to @lfriedla for the example and the gracious words. I did indeed use Tinderbox for note-taking and planning of all sorts in the scheduling, the travel-planning, the article- and book-organizing, and other related info-wrangling tasks for the Our Towns book.


(Lew Friedland) #19

Still having one final bit of trouble. Inheritance is working fine now, but when I actually add a note to book reference, which has the following on add code:

$Prototype=$BookNote; $Authors=$Authors(parent); $BookTitle=$BookTitle(parent); $Publisher=Publisher(parent);$Theme=Theme(parent);

I get a message “This note’s $OnAdd cannot be parsed: [code].”

I believe the space has been removed (that is the exact code, copied from my OnAdd field).

It’s possible that the conflict is with the rule itself? The original reason for the rule was to properly inherit and reassign the RIS fields from Zotero. Is it possible that once a book reference has been imported once from Zotero the rule is no longer needed?

Thank you.


(Mark Anderson) #20

This looks odd:

$Prototype=$BookNote

Given early discussion up-thread, I assume you’re actually trying to set:

$Prototype="Book Note";

conversely I think ‘Publisher’ and ‘Theme’ are attribute references not strings. Thus:

$Publisher=$Publisher(parent);$Theme=$Theme(parent);

So, I think the OnAdd action you meant to write is:

$Prototype="BookNote"; $Authors=$Authors(parent); $BookTitle=$BookTitle(parent); $Publisher=$Publisher(parent);$Theme=$Theme(parent);

(Lew Friedland) #21

Mark, thank you, that was, indeed the problem. I learn slowly.
Appreciate all your help.


(Mark Anderson) #22

Don’t worry, the $-prefix-or-not is confusing at first use. Essentially:

="BookNote" sets a literal text (‘string’) value

=$BookNote sets the value of an attribute called BookNote

=BookNote leaves Tinderbox to guess. My understanding is the app first tries to match an attribute name (i.e. example #2) and if no match it assumes the value is a literal string (example #1). I find it useful to not use this method as it helps me consider and understand what I’m trying to do.

More on action code syntax: