Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p><strong>Write simple parser.</strong></p> <p>Solving this kind of problem by regexp is not right. It's the same as matching brackets - difficult to do with regexp. Regexps are not suitable for nested expressions in general.</p> <p>Try something like that:</p> <pre><code>var parts = src.split(/(\{\{|\}\})/); for (var i in parts) { if (parts[i] == '{{') // starting new (sub) template else if (parts[i] == '}}') // ending (sub) template else // content (or outside) } </code></pre> <p>This is just pseudo code, as I'm in rush now, will update this code to be working...</p> <p><strong>UPDATE (9th August 2011)</strong></p> <pre><code>var NO_TPL = 0, // outside any tpl - ignoring... IN_TPL = 1, // inside tpl IN_LIST = 3; // inside list of arguments function parseWiki(src) { var tokens = src.split(/(\{\{|\}\}|\||=|\[\[|\]\])/), i = -1, end = tokens.length - 1, token, next, state = NO_TPL, work = [], workChain = [], stateChain = []; function trim(value) { return value.replace(/^\s*/, '').replace(/\s*$/, ''); } // get next non empty token function getNext(next) { while (!next &amp;&amp; i &lt; end) next = trim(tokens[++i]); return next; } // go into tpl / list of arguments function goDown(newState, newWork, newWorkKey) { stateChain.push(state); workChain.push(work); if (newWorkKey) { work[newWorkKey] = newWork; } else { work.push(newWork); } work = newWork; state = newState; } // jump up from tpl / list of arguments function goUp() { work = workChain.pop(); state = stateChain.pop(); } // state machine while ((token = getNext())) { switch(state) { case IN_TPL: switch(token) { case '}}': goUp(); break; case '|': break; default: next = getNext(); if (next != '=') throw "invalid"; next = getNext(); if (next == '[[') { goDown(IN_LIST, [], token); } else if (next == '{{') { goDown(IN_TPL, {id: getNext()}, token); } else { work[token] = next; } } break; case IN_LIST: switch(token) { case ']]': goUp(); break; case '|': break; default: work.push(token); } break; case NO_TPL: if (token == '{{') { next = getNext(); goDown(IN_TPL, {id: next}); } break; } } return work; } </code></pre> <p><strong>UNIT TESTS</strong></p> <pre><code>describe('wikiTpl', function() { it('should do empty tpl', function() { expect(parseWiki('{{name}}')) .toEqual([{id: 'name'}]); }); it('should ignore text outside from tpl', function() { expect(parseWiki(' abc {{name}} x y')) .toEqual([{id: 'name'}]); }); it('should do simple param', function() { expect(parseWiki('{{tpl | p1= 2}}')) .toEqual([{id: 'tpl', p1: '2'}]); }); it('should do list of arguments', function() { expect(parseWiki('{{name | a= [[1|two]]}}')) .toEqual([{id: 'name', a: ['1', 'two']}]); }); it('should do param after list', function() { expect(parseWiki('{{name | a= [[1|two|3]] | p2= true}}')) .toEqual([{id: 'name', a: ['1', 'two', '3'], p2: 'true'}]); }); it('should do more tpls', function() { expect(parseWiki('{{first | a= [[1|two|3]] }} odd test {{second | b= 2}}')) .toEqual([{id: 'first', a: ['1', 'two', '3']}, {id: 'second', b: '2'}]); }); it('should allow nested tpl', function() { expect(parseWiki('{{name | a= {{nested | p1= 1}} }}')) .toEqual([{id: 'name', a: {id: 'nested', p1: '1'}}]); }); }); </code></pre> <p>Note: I'm using Jasmine's syntax for these unit tests. You can easily run it using AngularJS which contains whole testing environment - check it out at <a href="http://angularjs.org" rel="noreferrer">http://angularjs.org</a></p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload