PS

>
> recently I've stumbled upon a bug with the parametric transclusion and I'd 
> like to share it and the fix (hope this will go to the core as well).
>
> this was written before I realized that escape/unescape is a bad 
solution, so nothing to include into the core yet.
 

> *The bug.*
> The usecase is the following: a template tiddler contains some listing 
> stuff, a newTiddler button etc, one of the parameters is meant to be a 
> filter. If you're interested, the whole thing looks like this ($1 is for 
> filter):
>
> <<fet *filter '$1'* sortableBy '"$2"' script 'var wrapTitle = 
> function(text,tid){
>   return tid.tags.contains("emphasis") ? 
> "@@font-weight:bold;font-size:inherit;"+text+"@@" : text;
> };
> var wrapText = function(tiddler){
>   var text = "{{ti{<<tiddler [["+tiddler.title+"]]>"+">}}}";
>   var showWrap = tiddler.text ? (
> " "+(tiddler.tags.contains("showInline") ? text : 
> ((tiddler.tags.contains("show") ? "+" : "") + 
> ("+++{{linkAsText{[>][:]}}}"+text+"==="))
> )) : "";
>   return showWrap;
> }' writeToList 
> 'wrapTitle(tiddler.title,tiddler)+wrapText(tiddler)'>><<newTiddler $3 
> label:"add" text:"" title:"">> [[T|SListTemplate]]
>
> The symptom is the following: as the whole thing is transcluded and 
> wikified (<<tiddler [[SListTemplate##main]] 
> *with:"[tag[current]]"*with:"orderCurrent" with:'tag:"current" 
> tag:"steps"'>>), 
> it works as expected; but on refreshing I get a list of two tiddlers: tagand 
> current (the parts of the [tag[current]] filter).
>
> *The explanation.*
> The reason is in how config.macros.tiddler.handler and 
> config.macros.tiddler.transclude work:
>
> the former sets an args attribute like this [1]:
>
> wrapper.setAttribute("args","[["+args.join("]] [[")+"]]");
>
> while args contain square brackets; and the latter reads it like this [2] 
> (typeof args == "string" case is the refreshing case):
>
> args = args.readBracketedList();
>
> Obviously, we get ("[["+args.join("]] [[")+"]]").readBracketedList()instead 
> of just args, which is not the same in the case when args[i] contain a 
> square bracket.
>
> *Possible fixes.*
> To get rid of such a bug, we have to do smth with the square brackets. 
> Actually, not only with them, but with everything that parseParams [3] 
> considers special symbols. The first idea that came to me was to use 
> encodeURIComponent/decodeURIComponent, but they don't fit as some 
> characters are forbidden [4]. Ok, that's actually not URI, let's try 
> escape/unescape. Although they helped in my case [*], they are deprecated 
> and are not expected to work consistently with non-ASCII characters [5]. 
> Right, there's a solution proposed at [6], but it's not explained in 
> details and I'm not sure if it will work in every case.
>
> May be you know some good and reliable way to "escape/unescape" the pesky 
> symbols for any line? May be it's worse to list all symbols considered 
> "special" by parseParams and just substitute them with \uXXXX stuff? Any 
> better ideas?
>
> Best regards,
> Yakov.
>
> [1] https://github.com/TiddlyWiki/tiddlywiki/blob/master/js/Macros.js#L213
> [2] https://github.com/TiddlyWiki/tiddlywiki/blob/master/js/Macros.js#L228
> [3] https://github.com/TiddlyWiki/tiddlywiki/blob/master/js/Strings.js#L96
> [4] 
> https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/encodeURIComponent?redirectlocale=en-US&redirectslug=JavaScript%2FReference%2FGlobal_Objects%2FencodeURIComponent(see
>  the first code block in description)
> [5] 
> https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Functions?redirectlocale=en-US&redirectslug=JavaScript%2FGuide%2FFunctions#escape_and_unescape_functions(Obsoleted_above_JavaScript_1.5)
> [6] 
> http://stackoverflow.com/questions/7499473/need-to-escape-non-ascii-characters-in-javascript
>
> [*] the code was the following (no good way to hijack in a shorter way); 
> this is just to show what was changed:
> config.macros.tiddler.handler = 
> function(place,macroName,params,wikifier,paramString,tiddler) {
>
>     var allowEval = true;
>     var stack = config.macros.tiddler.tiddlerStack;
>     if(stack.length > 0 && config.evaluateMacroParameters == "system") {
>         // included tiddler and "system" evaluation required, so check 
> tiddler tagged appropriately
>         var title = stack[stack.length-1];
>         var pos = title.indexOf(config.textPrimitives.sectionSeparator);
>         if(pos != -1)
>             title = title.substr(0,pos); // get the base tiddler title
>         var t = store.getTiddler(title);
>         if(!t || t.tags.indexOf("systemAllowEval") == -1)
>             allowEval = false;
>     }
>     params = paramString.parseParams("name",null,allowEval,false,true);
>     var names = params[0]["name"];
>     var tiddlerName = names[0];
>     var className = names[1] || null;
>     var args = params[0]["with"];
>     var wrapper = createTiddlyElement(place,"span",null,className,null,{
>         refresh: "content", tiddler: tiddlerName
>     });
>
> *    var escapedArgs = []*    if(args!==undefined) {
>
>
>
>
> *        for(var i = 0; i < args.length; i++)            
> escapedArgs.push(escape(args[i]));        
> wrapper.setAttribute("args","[["+escapedArgs.join("]] [[")+"]]");        
> wrapper.setAttribute("readableArgs","[["+args.join("]] [[")+"]]"); // 
> useful for DOM inspection, not necessary*    }
>     this.transclude(wrapper,tiddlerName,args);
> };
>
> config.macros.tiddler.transclude = function(wrapper,tiddlerName,args) {
>
>     var text = store.getTiddlerText(tiddlerName);
>     if(!text)
>         return;
>     var stack = config.macros.tiddler.tiddlerStack;
>     if(stack.indexOf(tiddlerName) !== -1)
>         return;
>     stack.push(tiddlerName);
>     try {
>   *      var i;*
>         if(typeof args == "string") {
>             args = args.readBracketedList();
>
>
> *            for(i = 0; i < args.length; i++)                args[i] = 
> unescape(args[i]);*        }
>         var n = args ? Math.min(args.length,9) : 0;
>         for(i = 0; i < n; i++) {
>             var placeholderRE = new RegExp("\\$" + (i + 1),"mg");
>             text = text.replace(placeholderRE,args[i]);
>         }
>         config.macros.tiddler.renderText(wrapper,text,tiddlerName);
>     } finally {
>         stack.pop();
>     }
> };
>

-- 
You received this message because you are subscribed to the Google Groups 
"TiddlyWikiDev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To post to this group, send email to [email protected].
Visit this group at http://groups.google.com/group/tiddlywikidev.
For more options, visit https://groups.google.com/groups/opt_out.

Reply via email to