Tinderbox User-to-User Forum (for formal tech support please email: info@eastgate.com)
http://www.eastgate.com/Tinderbox/forum//YaBB.cgi
Tinderbox Users >> Exporting from Tinderbox >> Export BibTex using $KeyAttibutes
http://www.eastgate.com/Tinderbox/forum//YaBB.cgi?num=1315400558

Message started by Sebastian Stephenson on Sep 7th, 2011, 9:02am

Title: Export BibTex using $KeyAttibutes
Post by Sebastian Stephenson on Sep 7th, 2011, 9:02am

I am looking to export a BibTex file. I have created attributes for each field that will be made for each citation in the final BibTex exported file. Each of those attributes has been put into $KeyAttributes.

I then have created a BibTex citation template that so far looks like this.


Code:
@^value($citetype)^{^value($nickname)^,
^comment(if a attribtue's string in key attributes is not empty enter here)^
^if(^value($KeyAttributes.empty)^)^
^endif^
^value($KeyAttributes.format("= {^value($KeyAttributes.at(*))^},\n"))^
}


This is the result I have got so far(with a test entry)


Quote:
@InCollection{sep-dualism,
<!-- if a attribtue's string in key attributes is not empty enter here -->

citeinessay= {^value($KeyAttributes.at(*))^},
citetype= {^value($KeyAttributes.at(*))^},
nickname= {^value($KeyAttributes.at(*))^},
author= {^value($KeyAttributes.at(*))^},
editor= {^value($KeyAttributes.at(*))^},
booktitle= {^value($KeyAttributes.at(*))^},
title= {^value($KeyAttributes.at(*))^},
edition= {^value($KeyAttributes.at(*))^},
series= {^value($KeyAttributes.at(*))^},
pages= {^value($KeyAttributes.at(*))^},
month= {^value($KeyAttributes.at(*))^},
year= {^value($KeyAttributes.at(*))^},
URL= {^value($KeyAttributes.at(*))^},
publisher= {^value($KeyAttributes.at(*))^},
address= {^value($KeyAttributes.at(*))^},
note
}


It is nearly there but I can't get the actual attribute values for the attributes listed, in $KeyAttributes. So I need to find a way to get the listed attribute values and have them in the right field. I also need to exclude the three $citeinessay, $citetype and $nickname attributes, as they are for internal Tinderbox use.

NB: The ^if^ statement is for not exporting attributes that have no data. I will get that done as soon as getting the attributes values in the template is done.

Title: Re: Export BibTex using $KeyAttibutes
Post by Mark Anderson on Sep 7th, 2011, 1:49pm

OK, add a String $MyExportString and a Set $MyExportSet. Add a macro "export-list", and give it this code - note deliberate line break before ^endIf^:


Code:
^if(\$$1)^$1= {^value(\$$1)^},
^endIf^

Now add a template 'list-export' with this code:


Code:
@^value($citetype)^{^value($nickname)^,
^comment(if an attribute's string in $KeyAttributes is not empty enter here)^
^if($KeyAttributes)^^value($MyExportString)^
^endif^note
}

In the exporting container/agent, open HTML view and select the new export template and untick 'Markup text' (or code-set $HTMLMarkupText to false). Add the $Rule (line breaks for clarity here only):

$MyExportSet=$KeyAttributes.replace("citeinessay|citetype|nickname","");
$MyExportString=eval($MyExportSet.format('','eval(do("export-list","','"))+',''));


N.B. $MyExportSet and $MyExportString should not be key attributes in any exported notes.

Output:

@InCollection{sep-dualism,
<!-- if an attribute's string in $KeyAttributes is not empty enter here -->
MyStringA= {Hello mother dear},MyNum= {5},MyNumA= {25},MySet= {ant;frog;dog},
note
}


The only bit not achieved is the line breaks after each attribute's entry which seems to be a problem in the evaluation of do() or the resolution of ^if()^. Still, I hope this moves things forward. I'm off on the road for a few days so can't progress this further just now.

Title: Re: Export BibTex using $KeyAttibutes
Post by Sebastian Stephenson on Sep 13th, 2011, 8:11am

Hi mark

thank you so much, hope you are having/had a good trip.

I added as you requested but the result I get is this


Quote:
@{,
<!-- if a attribtue's string in key attributes is not empty enter here -->

}


:-?

Help! :)

Title: Re: Export BibTex using $KeyAttibutes
Post by Mark Anderson on Sep 13th, 2011, 8:30am

Can you post a link to your test file?  It looks like the note being exported has no key attributes. My post used code copied from a working test. Not sure I kept the latter so it would help to see your file.

In your last example, I notice the output implies the note used to create it has no $citetype or $nickname. Are you exporting the right note?

Title: Re: Export BibTex using $KeyAttibutes
Post by Sebastian Stephenson on Sep 13th, 2011, 11:10am

Sure no problem.

The only thing I can think off is that the note used to test has $HTMLDontExport on but I have an action that set's it to false.

I changed the document default to true, for not getting hundreds of files exporting by pressing Command-Shift-H. This may be the issue but I did that long before I was thinking about BibTex.

Title: Re: Export BibTex using $KeyAttibutes
Post by Mark Anderson on Sep 13th, 2011, 1:13pm

Link says 'file no longer shared'.

BTW, you can preview the export by selecting just the export container and then Cmd+Opt+H.

Title: Re: Export BibTex using $KeyAttibutes
Post by Sebastian Stephenson on Sep 14th, 2011, 3:40am

Sorry about that here is the link http://files.me.com/sebey/mvnfyo

Title: Re: Export BibTex using $KeyAttibutes
Post by Mark Anderson on Sep 14th, 2011, 5:36am

Ah, I see (this is why having a reference file helps!). In your "References" agent, move the Rule's code to the 'Action" box, so it's applied to the agent's children (i.e. the matched reference notes).

Your 'BiBtex' export template is set, sensibly, in the 'Reference' prototype. so when you open 'test-reference' in HTML view you should see the data as I do. I don't have/use BibTeX so can't advise on the layout of the export file.

To do:
  • Getting the per-attribute data to have line breaks after each item has defeated me. However, it may not matter to BibTeX. Unless Eastgate can point out an angle I've missed, getting line breaks may require tweaks the TB app.
  • I see $note' is a key attribute but also possibly intended to be hard coded as the last entry in the export. So you may need to add 'note' to the list of deletions from $MyExportSet and then amend the export template accordingly.

Title: Re: Export BibTex using $KeyAttibutes
Post by Sebastian Stephenson on Sep 16th, 2011, 7:33am

Mark thank you so much for your help! I just have a few questions about what the code does.


Quote:
^if(\$$1)^$1= {^value(\$$1)^},
^endIf^

What do those mean?


Code:
$MyExportSet=$KeyAttributes.replace("citeinessay|citetype|nickname","");
$MyExportString=eval($MyExportSet.format('','eval(do("export-list","','"))+','')
);

Can you explain what this is doing?


Title: Re: Export BibTex using $KeyAttibutes
Post by Mark Anderson on Sep 16th, 2011, 9:48am

Note - do ensure to read the linked articles in this reply as they hold much of the fine detail of the answers you seek.


Quote:
^if(\$$1)^$1= {^value(\$$1)^},
^endIf^


Using do() or ^do()^call, the first parameter given is the name of the macro. The second and subsequent parameters form the first and subsequent data inputs passed the specified macro.

Within the macro, the inputs are referred to as $1, $@, etc. Wherever a $N is inserted the literal value of the input (i.e. the do() input value), thus above the $1 is inserting an attribute name passed to the macro. But, we need the overall result to be an attribute
reference (i.e. a $-prefixed name). In a macro a $ already has a special meaning, so to insert an actual dollar-sign character we 'escape' it with a back-slash (the red code above). So is input one is "SomeName" the macro code \$$1 returns the string "$SomeName". White space matters in this context; if the macro code were \$ $1 the string returned becomes "$ SomeName" - which isn't, of course, a valid attribute reference!


Quote:
$MyExportSet=$KeyAttributes.replace("citeinessay|citetype|nickname","");

$KeyAttributes is a Set. We are using the Set.replace() to create set that excludes the 3 attribute names before passing the result to $MyExportSet.  The replace string is a regular expression - description of the fine workings of these is a subject on its own; if you're new to regex, I'd read up the general subject via Google.

We need $MyExportSet as if we try to do the next step by nesting code (inserting the right side of the above where $MyExportSet is in the code below) it doesn't work. There are limits to how deeply TB will drill down into  code in terms of evaluating things.  There's no hard as fast limit - before you ask, you just need to experiment. Plus, when designing this sort of code, it's useful to have interim attribute values so you can check the result of each step is what you assumed it to be.


Quote:
$MyExportString=eval($MyExportSet.format('','eval(do("export-list","','"))+','')
);

This is a hack to get around the fact that action and export code lack a loop function, e.g. for(x, x < y; x=x+1) sort of thing. We need to turn every item in $MyExportSet into a discrete string.  OK, Set.format(), in its 4-argument syntax, lets us supply list-prefix/item-prefix/item-suffix/list-suffix for each item in the set. In fact, we only need list prefix/suffix but there's another road-block that I address with a macro. Each Set item's output needs to use the current list item value more than once. So, in the format() code's argument #2 and #3 we wrap the item name in an eval(do()) call, split between [2] and [3] like so: [eval(do(] and  [))]. For Set item "SomeAttribute" we pass in

eval(do("export-list","SomeName"))+

…representing #2[Set item value]#3, and receiving back:

eval(^if($SomeName)^SomeName= {^value($SomeName)^},
^endIf^)+


Great, we've now tricked format() into inserting each set item value not once, but three times, into the per-item output.

The outer wrapper takes the string+string+string+ output from format() and turns it into a single string.

Footnote. Why use ^code^ in the macro and not action code and evaluate before export. Well, it seems that's pushing eval() and macros further than they're currently (v5.9.3) designed to go - ergo the outstanding problem with TB no letting me get line returns where I want them in $ExportString. AS you may guess I explored a lot of blind alleys in getting to the above code (as the edges of action code aren't documented  - aTbRef is effectively what we know, or believe, is true).

Sorry for the long post. This stuff isn't simple (in execution) so please don't shoot the messenger if it's hard to follow! As said previously, try breaking the task into steps and check at each one that progress thus far is what you expect.

Title: Re: Export BibTex using $KeyAttibutes
Post by Sebastian Stephenson on Sep 17th, 2011, 6:20am

Well I certainly was not expecting a one liner ;)

Mark this is fantastic, thank you.

I may try and see if could create an applescript that adds line breaks but maybe I should file a bug report or feature request to support line breaks in macros?

I only read it once and understand about 3/4 of it. So I will reread again to see if I can help in anyway. Regardless, this is huge step in the right direction, thank you.

Title: Re: Export BibTex using $KeyAttibutes
Post by Stéphane R on Sep 17th, 2011, 9:02am

Sebastian,

Mark A.'s code looks very elaborate, and I would most likely understand it better if I saw it implemented.
Plus, I'm very interested in exporting BibTeX as well (to avoid redundancies with other bibliography programs).
Do you have a more recent version of your sample file that we could look at?

Thanks a bunch,
Stephane

Title: Re: Export BibTex using $KeyAttibutes
Post by Mark Anderson on Sep 17th, 2011, 10:55am

@Stéphane, my test TBX is here (zipped TBX).

@Sebastian. 3/4? You're doing well :), as it's not exactly shallow-end TB use. I've tried to avoid classing the missing line return issue as a 'bug' because it's only my assumption that it ought to be possible - I've not seen a definitive statement that it should work. Whatever, past experience is that these sort of edge cases get fixed in subsequent releases.

Title: Re: Export BibTex using $KeyAttibutes
Post by Stéphane R on Sep 17th, 2011, 12:02pm

Thanks very much Mark, but the link doesn't work for me

Title: Re: Export BibTex using $KeyAttibutes
Post by Mark Anderson on Sep 17th, 2011, 12:58pm

Bother, a typo in the URL. Now fixed.

Title: Re: Export BibTex using $KeyAttibutes
Post by Sumner Gerard on Sep 19th, 2011, 6:02pm

Amazing wizardry with format(), a do() and .replace()!

I've attached a demo tbx showing a much less elegant and more verbose (but, for me, easier to replicate and in some ways possibly more flexible, e.g. can get a line break where needed) "loop" method, similar to that described here.

Three code notes do the work:

'cLoopInit' sets things up and uses MarkA's nifty method to exclude certain key attributes with replace().


Code:
$MyTempString=;$MyTempList=;$LoopCtr=0;
$MyExportSet=$KeyAttributes.replace("citeinessay|citetype|nickname","");
$LoopSize=$MyExportSet.size;
action($Text("cLoop"));


'cLoop' uses the .at() operator with the loop counter attribute to cycle through the items in list of key attributes. For each key attribute that has a value in that note (the if(eval()) is testing to make sure it is not empty) a temporary string is populated with the attribute name and attribute value.  Then this temporary string is added to a temporary list.


Code:
if($LoopCtr<$LoopSize) {
$CurrListItem=$MyExportSet.at($LoopCtr);
if(eval('$'+$CurrListItem)){$MyTempString=$CurrListItem+"={"+eval('$'+$CurrListItem)+"}"}else{$MyTempString=;};
$MyTempList=$MyTempList+$MyTempString;
$LoopCtr=$LoopCtr+1;
action($Text("cLoop"));
}
else {
action($Text("cMakeReport"))
}


'cMakeReport' formats the temporary list with line breaks, adds some stuff before and after that I understand BibTex needs, replaces some values, and places the result in $Text, from where it can be viewed and exported.  The effects can be seen dynamically by opening the 'test-reference' and inserting/changing values for the key attributes. (The text updates immediately if one File/Saves without closing the note.)


Code:
$Text="@"+$citetype+"{"+$nickname+",
";
$Text=$Text+$MyTempList.format(",\n");
$Text=$Text.replace("URL","howpublished");
$Text=$Text+"
}";


In practice one would probably want to add a "guard attribute" with conditional or some other mechanism so that the loop doesn't continually run. Here, I've got a stamp that can turn off the rule.

Some complications/questions:

1) Should TB always evaluate 'year' and 'month' as -1 and 6?  (see the eval() in 'cLoop') That's what I got for the values when I had the attribute names as 'year' and 'month' even when no values had been entered for those two attributes in the current note. I got around the problem by renaming the attributes 'byear' and 'bmonth' but then had to add the .replace() to 'cMakeReport' to change the names to what (presumably...I haven't used it) BibTex expects. (Am thinking problem may be because there should be an escaped $ within the second eval() but not sure how to do that).
[edit]Adding '$'+ within eval() seems to work. Changed attribute names back to $year and $month.[/edit] 

2) If had attributes 'byear' and 'bmonth' could these be replaced by 'year' and 'month' in one replace()?  I see aTbRef mentions multiple back-references with .replace() but don't know how that might work in this case.

As always, interested in suggestions/critique.

Title: Re: Export BibTex using $KeyAttibutes
Post by Mark Anderson on Sep 20th, 2011, 4:06am

without the pre-cghange version, I'm note 100% sure but if you changed code like
  eval($CurrListItem)
to
  eval("$"+$CurrListItem)
it would make sense.

The reason is $CurrListItem holds the string literal name of an attribute ("year") and not a reference ("$year"). If you use the first example above with "year") TB is likely trying to figure what you meant by supplying the year() action operator with no parameters. Incidentally, I realise Sumner is only following Sebastian's original attribute naming. This is another good reason why I try to persuade people to follow TB conventions with attribute naming as it avoids such predictable code ambiguities. If $String's value is "Year" or "YearDate", $String.lowercase() gives "year" or "yeardate" so needing lowercase names in export isn't a reason to use all-lowercase TB attribute names.

I realise Sebastian used $URL in his original TBX but with it unnecessary. Easier would be to make a custom URL-type attribute $howpublished. Of course, given the above, more sensible naming would be $HowPublished.

Not ignoring the other stuff but not time now to explore. I'm going try and merge my demo with Sumner's and use sensible attribute names, but it may take a while and i'm busy just now.

Title: Re: Export BibTex using $KeyAttibutes
Post by Sumner Gerard on Sep 20th, 2011, 11:58am


Quote:
eval("$"+$CurrListItem) ... would make sense

Ah, hadn't thought of confusion with year() and month() action operators! Without parameters perhaps they default to -1 and 6.  Can now see need to prefix '$' in the expression.  Ended up using single quotes because double quotes were already used.


Quote:
I'm going try and merge my demo with Sumner's and use sensible attribute names

That would be great!  Finally see a practical application for lowercase().

Title: Re: Export BibTex using $KeyAttibutes
Post by Mark Anderson on Sep 21st, 2011, 5:44am

Some progress at last. First the preps. Attribute names are now:
  • Key attributes: CiteInEssay (Boolean), CiteType (String), NickName (String), Author (String), Editor (String), BookTitle (String), Title (String), Edition (String), Series (String), Pages (String), Month (String), Year (String), HowPublished (URL), Publisher (String), Address (use existing System String attribute: $Address), Note (String).
  • For export process: LoopCtr (Number), LoopSize (Number), MyExportSet (Set), MyExportString (String), MyTempList (List), MyTempString (String).
A prototype (BibTeX-Ref) is used to set up both the key attributes and the export template (export-ref). The prototype also has $HTMLExportExtension changed from '.html' to '.txt' as this is a more likely useful extension of what will be a UTF-8 plain text format export. The names of either of those can be easily changed for your own use/naming conventions.

Using Sumner's model (thanks!) there are still 3 code notes.

cLoopInit:

Code:
$MyTempString=;$MyTempList=;$LoopCtr=0;$MyExportString=;
$MyExportSet=$KeyAttributes.replace("CiteInEssay|CiteType|NickName","");
$LoopSize=$MyExportSet.size;
action($Text("cLoop"));

cLoop:

Code:
if($LoopCtr<$LoopSize) {
     $CurrListItem=$MyExportSet.at($LoopCtr);
     if(eval('$'+$CurrListItem)){
           $MyTempString=$CurrListItem.lowercase()+"={"+eval('$'+$CurrListItem)+"}"
     } else {
           $MyTempString=;
     };
     $MyTempList=$MyTempList+$MyTempString;
     $LoopCtr=$LoopCtr+1;
     action($Text("cLoop"));
} else {
     action($Text("cMakeReport"))
}

cMakeReport:

Code:
$MyExportString="@"+$CiteType+"{"+$NickName+",
";
$MyExportString=$MyExportString+$MyTempList.format(",\n");
$MyExportString=$MyExportString+"
}";

Meanwhile the export template now calls the export process - initialing the loop and zero-ing out all the variables after use - storing each full exported reference value strikes me as file bloat as it's recreated on next export. Template export-ref:

Code:
^action(action($Text("cLoopInit")))^^value($MyExportString)^
^action($MyExportString=;$MyTempList=;$MyExportSet=;$MyTempString=;$LoopCtr=;$LoopSize=;)^


I think the looping has been discussed elsewhere - noting the added use of .lowercase() to lowercase the attribute names. Apart from laying out the if() structures in the loop to show the branching (the extra whitespace has no effect on export) the process is as Sumner's concept.

The main difference is now the export template calls the first action.  Note how to call an action from a template we needs 'double' call ^action(action(...))^. This might seem counter-intuitive but ^action()^ simple runs action code without returning anything (to the template. Of course action() is itself action code, thus the apparent 'doubling' of the word action in the call. The ^value()^ call is not on its own line as otherwise the end of the action line emits a line return causing the export file to have a blank first line. as some importers are very specific this might cause an import failure, so we put the two codes on the same line. The second line simply resets all the export variables now we're done.  Most don't really matter, but $MyExportString could certainly be holding a lot of data, bloating the TBX. Anyway, it seems sensible to clear out the export-only attributes now we're done exporting.

Demo file of above code: BibTeX2.zip

Title: Re: Export BibTex using $KeyAttibutes
Post by Mark Anderson on Sep 22nd, 2011, 1:02pm

To make a few less moving parts, we can merge the 'make report' code with the loop, like so:


Code:
if($LoopCtr<$LoopSize) {
     $CurrListItem=$MyExportSet.at($LoopCtr);
     if(eval('$'+$CurrListItem)){
           $MyTempString=$CurrListItem.lowercase()+"={"+eval('$'+$CurrListItem)+"}"
     } else {
           $MyTempString=;
     };
     $MyTempList=$MyTempList+$MyTempString;
     $LoopCtr=$LoopCtr+1;
     action($Text("cLoop"));
} else {
     $MyExportString="@"+$CiteType+"{"+$NickName+",
";
     $MyExportString=$MyExportString+$MyTempList.format(",\n");
     $MyExportString=$MyExportString+"
}";
}
$MyExportString=;
$MyTempList=;
$MyExportSet=;
$MyTempString=;
$LoopCtr=;
$LoopSize=;

Now we've reset the in-loop and loop control variables at the end. We can't remove the last ^action^ call from the export template, as we can reset $MyExportString before we use it. The template is now:


Code:
^action(action($Text("cLoopInit")))^^value($MyExportString)^
^action($MyExportString=;)^

[edit]The last line above, pre-edit, included unnecessary items now in cLoop[/edit]
The outcome is exactly the same as in the last post, but we've one less code note, which I feel is a little tidier. As ever, there's more than one way...

Title: Re: Export BibTex using $KeyAttibutes
Post by Sumner Gerard on Sep 22nd, 2011, 4:38pm

Very instructive. Thanks!

In the 'export-ref' template it seems you no longer need the second line that clears the variables.  Perhaps a typo, since the template appears unchanged from earlier post?

Very basic question, stemming from lingering export anxiety: what are the main advantages of calling the action code from an export template rather than a rule?  

In this case it seems more "natural", because this is, after all, export to another application. And it avoids cluttering up notes with rules.  

Is there also a performance advantage in that, unlike rules, export templates (presumably) don't run the code automatically each cycle, only when needed in an export context? I noticed when a new HTML View is opened on 'Test Ref" and I make changes to the values in any of the key attributes there, the output in the HTML View window updates immediately after I click on the window, but not before.

Title: Re: Export BibTex using $KeyAttibutes
Post by Mark Anderson on Sep 22nd, 2011, 4:59pm

Oops, edit made above!


Quote:
Very basic question, stemming from lingering export anxiety: what are the main advantages of calling the action code from an export template rather than a rule?  

In this case it seems more "natural", because this is, after all, export to another application. And it avoids cluttering up notes with rules.  


I think you answered the question. In this case, as we're doing export, it makes more sense to only run the code during export (open HTML view does the same). By the same token, there's no point in storing  temporary values used for the export process.  Were the data being used internally, it might be a different deal.  Also consider an agent action vs. per-note rules. Why? An agent can be turned off. Inefficiencies that won't show with a one or two note test may, with thousands of notes, slow up operations; there are no hard-and-fast metrics lest someone lask. Ergo it's best to make code as efficient as possible so scaling doesn't have undue effect. One good rule of thumb is to limit scope; don't apply a rule to 50 notes when only one really needs to use the code (e.g. prototypes). Conditional if() tests can also help block inappropriate running of longer sections of code - i.e. 100s of notes might run the test but only few meet the condition and run the main branch of code. The same concept applies to queries:

Worse:   $Color=="blue" & descendedFrom("Test")

Better:   descendedFrom("Test") & $Color=="blue"

Why is the latter better? The first test finds only those notes descended from a given container and only those notes are tested with the rest of the query. The first example tests $Color for every note. Inefficient!


Quote:
I noticed when a new HTML View is opened on 'Test Ref" and I make changes to the values in any of the key attributes there, the output in the HTML View window updates immediately after I click on the window, but not before.


I think that speed/frequency is a pragmatic choice - the same CPU is providing cycles to run UI updates as doing code, etc.  There's a balance of application of effort. nothing sinister, I believe.

Title: Re: Export BibTex using $KeyAttibutes
Post by Sumner Gerard on Sep 22nd, 2011, 6:12pm

Great practical tips on agent use and limiting scope.


Quote:
makes more sense to only run the code during export (open HTML view does the same)

So the export "angsted" question I was trying to articulate is whether opening HTML View and subsequently clicking on that view after an update to an attribute value in the note is basically the same (in terms of triggering action code called by an export template) as actually doing an export. Or, put another way, if I had not opened HTML View and clicked on it, then is it correct to say that the code called by the export template would not run each cycle (as it does when called by a rule as I originally had it above) but instead would run only when triggered by an actual export?  If true, then of course that is a very desirable thing in this context.

Title: Re: Export BibTex using $KeyAttibutes
Post by Mark Anderson on Sep 23rd, 2011, 4:25am

In my revised version, cLoopInit is called from the template.  The template is only evaluated if Export as HTML (full doc export) is called or a note's HTML view is opened. In the latter case this is necessary as it needs to show you the output code - i.e. the processed result of the template. In full export the call will be once per template, in HTML view it may occur repetitively whilst the view is open - changes affecting the output are detected. An exception in this context is that HTML view does not show the full result of $HTMLExportCommand as that command line is run on the output file from export - i.e. run on the code as seen in HTML view. In HTML view if that note is set to use an $HTMLExportCommand and if either the Preview or Export buttons are pushed then the code as seen in the code pane would be post-processed and thus different from the actual exported code.

By comparison, triggering this whole loop process in a Rule means it's firing every update cycle for every note using the Rule.  I think you'll agree that's more activity overall. Clearly, in a small test we won't see much impact but on a big file a Rule is probably a wasteful method if the loop is only needed for export purposes.

For non-export use, you could 'gate' the call to the looping code behind a Boolean as in: if($DoLoop){… That way, cLoopInit only gets called if $DoLoop is true. so the Rule might get run in many places but with little impact as $DoLoop would in most cases be false meaning the loop call code would not run.

Incidentally, if you wanted to use both internal and export method, then a further boolean could control, in the loop code 'else' branch whether $MyExportString is just send to export or whether it is also sent to $Text or some other String attribute for internal use.

There's no single right way - it depends what you're trying to do. The only central tenet is thinking about not running more code than needed more often than needed. The more complex the code the more getting it wrong may affect general performance.

Footnote - FWIW I'd still like to see TB get a List.loop() function that makes this more accessible to the general user who doesn't code and to whom loop counters, etc., mean nothing.

[edit]Fix typos, clarify first paragraph.[/edit]

Title: Re: Export BibTex using $KeyAttibutes
Post by Sumner Gerard on Sep 23rd, 2011, 12:43pm

I now see the performance advantages of triggering the action code from an export template rather than a rule that fires each update cycle.

Hope ^action(action())^ isn't scheduled to be retired as seems to be suggested could happen here.

It seems ^value()^ in export code is roughly equivalent to eval() in action code, while ^action()^ is equivalent to action().  Both are useful. At times one needs a value returned. At times one wants a block of code to run.

Wonder how a loop() function (or whatever it would be called) would look.  Looping through members of a list or set does seem to be a common problem.

Title: Re: Export BibTex using $KeyAttibutes
Post by Mark Anderson on Sep 23rd, 2011, 4:08pm

Deprecation of ^action()^ has actually been removed as the difference in function from ^value()^ has become clearer - for the reasons you describe.  I'd already changed that but the old page was still on the website - I've checked and corrected the page.

How might a loop() look -assuming there is one? I think that's still an open field. I'm sure input is welcome.

Tinderbox User-to-User Forum (for formal tech support please email: info@eastgate.com) » Powered by YaBB 2.2.1!
YaBB © 2000-2008. All Rights Reserved.