summaryrefslogtreecommitdiff
path: root/node_modules/twig/docs
diff options
context:
space:
mode:
Diffstat (limited to 'node_modules/twig/docs')
-rw-r--r--node_modules/twig/docs/docco.css518
-rw-r--r--node_modules/twig/docs/licenses.md177
-rw-r--r--node_modules/twig/docs/public/fonts/aller-bold.eotbin29804 -> 0 bytes
-rw-r--r--node_modules/twig/docs/public/fonts/aller-bold.ttfbin66836 -> 0 bytes
-rw-r--r--node_modules/twig/docs/public/fonts/aller-bold.woffbin33244 -> 0 bytes
-rw-r--r--node_modules/twig/docs/public/fonts/aller-light.eotbin29509 -> 0 bytes
-rw-r--r--node_modules/twig/docs/public/fonts/aller-light.ttfbin68620 -> 0 bytes
-rw-r--r--node_modules/twig/docs/public/fonts/aller-light.woffbin33124 -> 0 bytes
-rw-r--r--node_modules/twig/docs/public/fonts/novecento-bold.eotbin18190 -> 0 bytes
-rw-r--r--node_modules/twig/docs/public/fonts/novecento-bold.ttfbin48136 -> 0 bytes
-rw-r--r--node_modules/twig/docs/public/fonts/novecento-bold.woffbin20576 -> 0 bytes
-rw-r--r--node_modules/twig/docs/public/stylesheets/normalize.css375
-rw-r--r--node_modules/twig/docs/release checklist.md20
-rw-r--r--node_modules/twig/docs/tests.md3567
-rw-r--r--node_modules/twig/docs/twig.html11250
15 files changed, 0 insertions, 15907 deletions
diff --git a/node_modules/twig/docs/docco.css b/node_modules/twig/docs/docco.css
deleted file mode 100644
index b60f6fa..0000000
--- a/node_modules/twig/docs/docco.css
+++ /dev/null
@@ -1,518 +0,0 @@
-/*--------------------- Typography ----------------------------*/
-
-@font-face {
- font-family: 'aller-light';
- src: url('public/fonts/aller-light.eot');
- src: url('public/fonts/aller-light.eot?#iefix') format('embedded-opentype'),
- url('public/fonts/aller-light.woff') format('woff'),
- url('public/fonts/aller-light.ttf') format('truetype');
- font-weight: normal;
- font-style: normal;
-}
-
-@font-face {
- font-family: 'aller-bold';
- src: url('public/fonts/aller-bold.eot');
- src: url('public/fonts/aller-bold.eot?#iefix') format('embedded-opentype'),
- url('public/fonts/aller-bold.woff') format('woff'),
- url('public/fonts/aller-bold.ttf') format('truetype');
- font-weight: normal;
- font-style: normal;
-}
-
-@font-face {
- font-family: 'roboto-black';
- src: url('public/fonts/roboto-black.eot');
- src: url('public/fonts/roboto-black.eot?#iefix') format('embedded-opentype'),
- url('public/fonts/roboto-black.woff') format('woff'),
- url('public/fonts/roboto-black.ttf') format('truetype');
- font-weight: normal;
- font-style: normal;
-}
-
-/*--------------------- Layout ----------------------------*/
-html { height: 100%; }
-body {
- font-family: "aller-light";
- font-size: 14px;
- line-height: 18px;
- color: #30404f;
- margin: 0; padding: 0;
- height:100%;
-}
-#container { min-height: 100%; }
-
-a {
- color: #000;
-}
-
-b, strong {
- font-weight: normal;
- font-family: "aller-bold";
-}
-
-p {
- margin: 15px 0 0px;
-}
- .annotation ul, .annotation ol {
- margin: 25px 0;
- }
- .annotation ul li, .annotation ol li {
- font-size: 14px;
- line-height: 18px;
- margin: 10px 0;
- }
-
-h1, h2, h3, h4, h5, h6 {
- color: #112233;
- line-height: 1em;
- font-weight: normal;
- font-family: "roboto-black";
- text-transform: uppercase;
- margin: 30px 0 15px 0;
-}
-
-h1 {
- margin-top: 40px;
-}
-h2 {
- font-size: 1.26em;
-}
-
-hr {
- border: 0;
- background: 1px #ddd;
- height: 1px;
- margin: 20px 0;
-}
-
-pre, tt, code {
- font-size: 12px; line-height: 16px;
- font-family: Menlo, Monaco, Consolas, "Lucida Console", monospace;
- margin: 0; padding: 0;
-}
- .annotation pre {
- display: block;
- margin: 0;
- padding: 7px 10px;
- background: #fcfcfc;
- -moz-box-shadow: inset 0 0 10px rgba(0,0,0,0.1);
- -webkit-box-shadow: inset 0 0 10px rgba(0,0,0,0.1);
- box-shadow: inset 0 0 10px rgba(0,0,0,0.1);
- overflow-x: auto;
- }
- .annotation pre code {
- border: 0;
- padding: 0;
- background: transparent;
- }
-
-
-blockquote {
- border-left: 5px solid #ccc;
- margin: 0;
- padding: 1px 0 1px 1em;
-}
- .sections blockquote p {
- font-family: Menlo, Consolas, Monaco, monospace;
- font-size: 12px; line-height: 16px;
- color: #999;
- margin: 10px 0 0;
- white-space: pre-wrap;
- }
-
-ul.sections {
- list-style: none;
- padding:0 0 5px 0;;
- margin:0;
-}
-
-/*
- Force border-box so that % widths fit the parent
- container without overlap because of margin/padding.
-
- More Info : http://www.quirksmode.org/css/box.html
-*/
-ul.sections > li > div {
- -moz-box-sizing: border-box; /* firefox */
- -ms-box-sizing: border-box; /* ie */
- -webkit-box-sizing: border-box; /* webkit */
- -khtml-box-sizing: border-box; /* konqueror */
- box-sizing: border-box; /* css3 */
-}
-
-
-/*---------------------- Jump Page -----------------------------*/
-#jump_to, #jump_page {
- margin: 0;
- background: white;
- -webkit-box-shadow: 0 0 25px #777; -moz-box-shadow: 0 0 25px #777;
- -webkit-border-bottom-left-radius: 5px; -moz-border-radius-bottomleft: 5px;
- font: 16px Arial;
- cursor: pointer;
- text-align: right;
- list-style: none;
-}
-
-#jump_to a {
- text-decoration: none;
-}
-
-#jump_to a.large {
- display: none;
-}
-#jump_to a.small {
- font-size: 22px;
- font-weight: bold;
- color: #676767;
-}
-
-#jump_to, #jump_wrapper {
- position: fixed;
- right: 0; top: 0;
- padding: 10px 15px;
- margin:0;
-}
-
-#jump_wrapper {
- display: none;
- padding:0;
-}
-
-#jump_to:hover #jump_wrapper {
- display: block;
-}
-
-#jump_page_wrapper{
- position: fixed;
- right: 0;
- top: 0;
- bottom: 0;
-}
-
-#jump_page {
- padding: 5px 0 3px;
- margin: 0 0 25px 25px;
- max-height: 100%;
- overflow: auto;
-}
-
-#jump_page .source {
- display: block;
- padding: 15px;
- text-decoration: none;
- border-top: 1px solid #eee;
-}
-
-#jump_page .source:hover {
- background: #f5f5ff;
-}
-
-#jump_page .source:first-child {
-}
-
-/*---------------------- Low resolutions (> 320px) ---------------------*/
-@media only screen and (min-width: 320px) {
- .pilwrap { display: none; }
-
- ul.sections > li > div {
- display: block;
- padding:5px 10px 0 10px;
- }
-
- ul.sections > li > div.annotation ul, ul.sections > li > div.annotation ol {
- padding-left: 30px;
- }
-
- ul.sections > li > div.content {
- overflow-x:auto;
- -webkit-box-shadow: inset 0 0 5px #e5e5ee;
- box-shadow: inset 0 0 5px #e5e5ee;
- border: 1px solid #dedede;
- margin:5px 10px 5px 10px;
- padding-bottom: 5px;
- }
-
- ul.sections > li > div.annotation pre {
- margin: 7px 0 7px;
- padding-left: 15px;
- }
-
- ul.sections > li > div.annotation p tt, .annotation code {
- background: #f8f8ff;
- border: 1px solid #dedede;
- font-size: 12px;
- padding: 0 0.2em;
- }
-}
-
-/*---------------------- (> 481px) ---------------------*/
-@media only screen and (min-width: 481px) {
- #container {
- position: relative;
- }
- body {
- background-color: #F5F5FF;
- font-size: 15px;
- line-height: 21px;
- }
- pre, tt, code {
- line-height: 18px;
- }
- p, ul, ol {
- margin: 0 0 15px;
- }
-
-
- #jump_to {
- padding: 5px 10px;
- }
- #jump_wrapper {
- padding: 0;
- }
- #jump_to, #jump_page {
- font: 10px Arial;
- text-transform: uppercase;
- }
- #jump_page .source {
- padding: 5px 10px;
- }
- #jump_to a.large {
- display: inline-block;
- }
- #jump_to a.small {
- display: none;
- }
-
-
-
- #background {
- position: absolute;
- top: 0; bottom: 0;
- width: 350px;
- background: #fff;
- border-right: 1px solid #e5e5ee;
- z-index: -1;
- }
-
- ul.sections > li > div.annotation ul, ul.sections > li > div.annotation ol {
- padding-left: 40px;
- }
-
- ul.sections > li {
- white-space: nowrap;
- }
-
- ul.sections > li > div {
- display: inline-block;
- }
-
- ul.sections > li > div.annotation {
- max-width: 350px;
- min-width: 350px;
- min-height: 5px;
- padding: 13px;
- overflow-x: hidden;
- white-space: normal;
- vertical-align: top;
- text-align: left;
- }
- ul.sections > li > div.annotation pre {
- margin: 15px 0 15px;
- padding-left: 15px;
- }
-
- ul.sections > li > div.content {
- padding: 13px;
- vertical-align: top;
- border: none;
- -webkit-box-shadow: none;
- box-shadow: none;
- }
-
- .pilwrap {
- position: relative;
- display: inline;
- }
-
- .pilcrow {
- font: 12px Arial;
- text-decoration: none;
- color: #454545;
- position: absolute;
- top: 3px; left: -20px;
- padding: 1px 2px;
- opacity: 0;
- -webkit-transition: opacity 0.2s linear;
- }
- .for-h1 .pilcrow {
- top: 47px;
- }
- .for-h2 .pilcrow, .for-h3 .pilcrow, .for-h4 .pilcrow {
- top: 35px;
- }
-
- ul.sections > li > div.annotation:hover .pilcrow {
- opacity: 1;
- }
-}
-
-/*---------------------- (> 1025px) ---------------------*/
-@media only screen and (min-width: 1025px) {
-
- body {
- font-size: 16px;
- line-height: 24px;
- }
-
- #background {
- width: 525px;
- }
- ul.sections > li > div.annotation {
- max-width: 525px;
- min-width: 525px;
- padding: 10px 25px 1px 50px;
- }
- ul.sections > li > div.content {
- padding: 9px 15px 16px 25px;
- }
-}
-
-/*---------------------- Syntax Highlighting -----------------------------*/
-
-td.linenos { background-color: #f0f0f0; padding-right: 10px; }
-span.lineno { background-color: #f0f0f0; padding: 0 5px 0 5px; }
-/*
-
-github.com style (c) Vasily Polovnyov <vast@whiteants.net>
-
-*/
-
-pre code {
- display: block; padding: 0.5em;
- color: #000;
- background: #f8f8ff
-}
-
-pre .hljs-comment,
-pre .hljs-template_comment,
-pre .hljs-diff .hljs-header,
-pre .hljs-javadoc {
- color: #408080;
- font-style: italic
-}
-
-pre .hljs-keyword,
-pre .hljs-assignment,
-pre .hljs-literal,
-pre .hljs-css .hljs-rule .hljs-keyword,
-pre .hljs-winutils,
-pre .hljs-javascript .hljs-title,
-pre .hljs-lisp .hljs-title,
-pre .hljs-subst {
- color: #954121;
- /*font-weight: bold*/
-}
-
-pre .hljs-number,
-pre .hljs-hexcolor {
- color: #40a070
-}
-
-pre .hljs-string,
-pre .hljs-tag .hljs-value,
-pre .hljs-phpdoc,
-pre .hljs-tex .hljs-formula {
- color: #219161;
-}
-
-pre .hljs-title,
-pre .hljs-id {
- color: #19469D;
-}
-pre .hljs-params {
- color: #00F;
-}
-
-pre .hljs-javascript .hljs-title,
-pre .hljs-lisp .hljs-title,
-pre .hljs-subst {
- font-weight: normal
-}
-
-pre .hljs-class .hljs-title,
-pre .hljs-haskell .hljs-label,
-pre .hljs-tex .hljs-command {
- color: #458;
- font-weight: bold
-}
-
-pre .hljs-tag,
-pre .hljs-tag .hljs-title,
-pre .hljs-rules .hljs-property,
-pre .hljs-django .hljs-tag .hljs-keyword {
- color: #000080;
- font-weight: normal
-}
-
-pre .hljs-attribute,
-pre .hljs-variable,
-pre .hljs-instancevar,
-pre .hljs-lisp .hljs-body {
- color: #008080
-}
-
-pre .hljs-regexp {
- color: #B68
-}
-
-pre .hljs-class {
- color: #458;
- font-weight: bold
-}
-
-pre .hljs-symbol,
-pre .hljs-ruby .hljs-symbol .hljs-string,
-pre .hljs-ruby .hljs-symbol .hljs-keyword,
-pre .hljs-ruby .hljs-symbol .hljs-keymethods,
-pre .hljs-lisp .hljs-keyword,
-pre .hljs-tex .hljs-special,
-pre .hljs-input_number {
- color: #990073
-}
-
-pre .hljs-builtin,
-pre .hljs-constructor,
-pre .hljs-built_in,
-pre .hljs-lisp .hljs-title {
- color: #0086b3
-}
-
-pre .hljs-preprocessor,
-pre .hljs-pi,
-pre .hljs-doctype,
-pre .hljs-shebang,
-pre .hljs-cdata {
- color: #999;
- font-weight: bold
-}
-
-pre .hljs-deletion {
- background: #fdd
-}
-
-pre .hljs-addition {
- background: #dfd
-}
-
-pre .hljs-diff .hljs-change {
- background: #0086b3
-}
-
-pre .hljs-chunk {
- color: #aaa
-}
-
-pre .hljs-tex .hljs-formula {
- opacity: 0.5;
-}
diff --git a/node_modules/twig/docs/licenses.md b/node_modules/twig/docs/licenses.md
deleted file mode 100644
index 949a254..0000000
--- a/node_modules/twig/docs/licenses.md
+++ /dev/null
@@ -1,177 +0,0 @@
-## LICENSE for the sprintf and vsprintf functions is src/lib/twig.lib.js
-
-
- Copyright (c) Alexandru Marasteanu <alexaholic [at) gmail (dot] com>
- All rights reserved.
-
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions are met:
- * Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
- * Neither the name of sprintf() for JavaScript nor the
- names of its contributors may be used to endorse or promote products
- derived from this software without specific prior written permission.
-
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- DISCLAIMED. IN NO EVENT SHALL Alexandru Marasteanu BE LIABLE FOR ANY
- DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-
-## LICENSE for the Date.format function is src/lib/twig.lib.js
-
- Copyright (c) 2010 Christopher West
-
- Permission is hereby granted, free of charge, to any person obtaining a copy
- of this software and associated documentation files (the "Software"), to deal
- in the Software without restriction, including without limitation the rights
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- copies of the Software, and to permit persons to whom the Software is
- furnished to do so, subject to the following conditions:
-
- The above copyright notice and this permission notice shall be included in
- all copies or substantial portions of the Software.
-
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- THE SOFTWARE.
-
-
-## LICENSE for the strip_tags function in src/twig.lib.js and range function
-## in src/twig.functions.js
-
- This is version: 3.26
- php.js is copyright 2011 Kevin van Zonneveld.
-
- Portions copyright Brett Zamir (http://brett-zamir.me), Kevin van Zonneveld
- (http://kevin.vanzonneveld.net), Onno Marsman, Theriault, Michael White
- (http://getsprink.com), Waldo Malqui Silva, Paulo Freitas, Jack, Jonas
- Raoni Soares Silva (http://www.jsfromhell.com), Philip Peterson, Legaev
- Andrey, Ates Goral (http://magnetiq.com), Alex, Ratheous, Martijn Wieringa,
- Rafał Kukawski (http://blog.kukawski.pl), lmeyrick
- (https://sourceforge.net/projects/bcmath-js/), Nate, Philippe Baumann,
- Enrique Gonzalez, Webtoolkit.info (http://www.webtoolkit.info/), Carlos R.
- L. Rodrigues (http://www.jsfromhell.com), Ash Searle
- (http://hexmen.com/blog/), Jani Hartikainen, travc, Ole Vrijenhoek,
- Erkekjetter, Michael Grier, Rafał Kukawski (http://kukawski.pl), Johnny
- Mast (http://www.phpvrouwen.nl), T.Wild, d3x,
- http://stackoverflow.com/questions/57803/how-to-convert-decimal-to-hex-in-javascript,
- Rafał Kukawski (http://blog.kukawski.pl/), stag019, pilus, WebDevHobo
- (http://webdevhobo.blogspot.com/), marrtins, GeekFG
- (http://geekfg.blogspot.com), Andrea Giammarchi
- (http://webreflection.blogspot.com), Arpad Ray (mailto:arpad@php.net),
- gorthaur, Paul Smith, Tim de Koning (http://www.kingsquare.nl), Joris, Oleg
- Eremeev, Steve Hilder, majak, gettimeofday, KELAN, Josh Fraser
- (http://onlineaspect.com/2007/06/08/auto-detect-a-time-zone-with-javascript/),
- Marc Palau, Kevin van Zonneveld (http://kevin.vanzonneveld.net/), Martin
- (http://www.erlenwiese.de/), Breaking Par Consulting Inc
- (http://www.breakingpar.com/bkp/home.nsf/0/87256B280015193F87256CFB006C45F7),
- Chris, Mirek Slugen, saulius, Alfonso Jimenez
- (http://www.alfonsojimenez.com), Diplom@t (http://difane.com/), felix,
- Mailfaker (http://www.weedem.fr/), Tyler Akins (http://rumkin.com), Caio
- Ariede (http://caioariede.com), Robin, Kankrelune
- (http://www.webfaktory.info/), Karol Kowalski, Imgen Tata
- (http://www.myipdf.com/), mdsjack (http://www.mdsjack.bo.it), Dreamer,
- Felix Geisendoerfer (http://www.debuggable.com/felix), Lars Fischer, AJ,
- David, Aman Gupta, Michael White, Public Domain
- (http://www.json.org/json2.js), Steven Levithan
- (http://blog.stevenlevithan.com), Sakimori, Pellentesque Malesuada,
- Thunder.m, Dj (http://phpjs.org/functions/htmlentities:425#comment_134018),
- Steve Clay, David James, Francois, class_exists, nobbler, T. Wild, Itsacon
- (http://www.itsacon.net/), date, Ole Vrijenhoek (http://www.nervous.nl/),
- Fox, Raphael (Ao RUDLER), Marco, noname, Mateusz "loonquawl" Zalega, Frank
- Forte, Arno, ger, mktime, john (http://www.jd-tech.net), Nick Kolosov
- (http://sammy.ru), marc andreu, Scott Cariss, Douglas Crockford
- (http://javascript.crockford.com), madipta, Slawomir Kaniecki,
- ReverseSyntax, Nathan, Alex Wilson, kenneth, Bayron Guevara, Adam Wallner
- (http://web2.bitbaro.hu/), paulo kuong, jmweb, Lincoln Ramsay, djmix,
- Pyerre, Jon Hohle, Thiago Mata (http://thiagomata.blog.com), lmeyrick
- (https://sourceforge.net/projects/bcmath-js/this.), Linuxworld, duncan,
- Gilbert, Sanjoy Roy, Shingo, sankai, Oskar Larsson Högfeldt
- (http://oskar-lh.name/), Denny Wardhana, 0m3r, Everlasto, Subhasis Deb,
- josh, jd, Pier Paolo Ramon (http://www.mastersoup.com/), P, merabi, Soren
- Hansen, Eugene Bulkin (http://doubleaw.com/), Der Simon
- (http://innerdom.sourceforge.net/), echo is bad, Ozh, XoraX
- (http://www.xorax.info), EdorFaus, JB, J A R, Marc Jansen, Francesco, LH,
- Stoyan Kyosev (http://www.svest.org/), nord_ua, omid
- (http://phpjs.org/functions/380:380#comment_137122), Brad Touesnard, MeEtc
- (http://yass.meetcweb.com), Peter-Paul Koch
- (http://www.quirksmode.org/js/beat.html), Olivier Louvignes
- (http://mg-crea.com/), T0bsn, Tim Wiel, Bryan Elliott, Jalal Berrami,
- Martin, JT, David Randall, Thomas Beaucourt (http://www.webapp.fr), taith,
- vlado houba, Pierre-Luc Paour, Kristof Coomans (SCK-CEN Belgian Nucleair
- Research Centre), Martin Pool, Kirk Strobeck, Rick Waldron, Brant Messenger
- (http://www.brantmessenger.com/), Devan Penner-Woelk, Saulo Vallory, Wagner
- B. Soares, Artur Tchernychev, Valentina De Rosa, Jason Wong
- (http://carrot.org/), Christoph, Daniel Esteban, strftime, Mick@el, rezna,
- Simon Willison (http://simonwillison.net), Anton Ongson, Gabriel Paderni,
- Marco van Oort, penutbutterjelly, Philipp Lenssen, Bjorn Roesbeke
- (http://www.bjornroesbeke.be/), Bug?, Eric Nagel, Tomasz Wesolowski,
- Evertjan Garretsen, Bobby Drake, Blues (http://tech.bluesmoon.info/), Luke
- Godfrey, Pul, uestla, Alan C, Ulrich, Rafal Kukawski, Yves Sucaet,
- sowberry, Norman "zEh" Fuchs, hitwork, Zahlii, johnrembo, Nick Callen,
- Steven Levithan (stevenlevithan.com), ejsanders, Scott Baker, Brian Tafoya
- (http://www.premasolutions.com/), Philippe Jausions
- (http://pear.php.net/user/jausions), Aidan Lister
- (http://aidanlister.com/), Rob, e-mike, HKM, ChaosNo1, metjay, strcasecmp,
- strcmp, Taras Bogach, jpfle, Alexander Ermolaev
- (http://snippets.dzone.com/user/AlexanderErmolaev), DxGx, kilops, Orlando,
- dptr1988, Le Torbi, James (http://www.james-bell.co.uk/), Pedro Tainha
- (http://www.pedrotainha.com), James, Arnout Kazemier
- (http://www.3rd-Eden.com), Chris McMacken, gabriel paderni, Yannoo,
- FGFEmperor, baris ozdil, Tod Gentille, Greg Frazier, jakes, 3D-GRAF, Allan
- Jensen (http://www.winternet.no), Howard Yeend, Benjamin Lupton, davook,
- daniel airton wermann (http://wermann.com.br), Atli Þór, Maximusya, Ryan
- W Tenney (http://ryan.10e.us), Alexander M Beedie, fearphage
- (http://http/my.opera.com/fearphage/), Nathan Sepulveda, Victor, Matteo,
- Billy, stensi, Cord, Manish, T.J. Leahy, Riddler
- (http://www.frontierwebdev.com/), Rafał Kukawski, FremyCompany, Matt
- Bradley, Tim de Koning, Luis Salazar (http://www.freaky-media.com/), Diogo
- Resende, Rival, Andrej Pavlovic, Garagoth, Le Torbi
- (http://www.letorbi.de/), Dino, Josep Sanz (http://www.ws3.es/), rem,
- Russell Walker (http://www.nbill.co.uk/), Jamie Beck
- (http://www.terabit.ca/), setcookie, Michael, YUI Library:
- http://developer.yahoo.com/yui/docs/YAHOO.util.DateLocale.html, Blues at
- http://hacks.bluesmoon.info/strftime/strftime.js, Ben
- (http://benblume.co.uk/), DtTvB
- (http://dt.in.th/2008-09-16.string-length-in-bytes.html), Andreas, William,
- meo, incidence, Cagri Ekin, Amirouche, Amir Habibi
- (http://www.residence-mixte.com/), Luke Smith (http://lucassmith.name),
- Kheang Hok Chin (http://www.distantia.ca/), Jay Klehr, Lorenzo Pisani,
- Tony, Yen-Wei Liu, Greenseed, mk.keck, Leslie Hoare, dude, booeyOH, Ben
- Bryan
-
- Dual licensed under the MIT (MIT-LICENSE.txt)
- and GPL (GPL-LICENSE.txt) licenses.
-
- Permission is hereby granted, free of charge, to any person obtaining a
- copy of this software and associated documentation files (the
- "Software"), to deal in the Software without restriction, including
- without limitation the rights to use, copy, modify, merge, publish,
- distribute, sublicense, and/or sell copies of the Software, and to
- permit persons to whom the Software is furnished to do so, subject to
- the following conditions:
-
- The above copyright notice and this permission notice shall be included
- in all copies or substantial portions of the Software.
-
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
- IN NO EVENT SHALL KEVIN VAN ZONNEVELD BE LIABLE FOR ANY CLAIM, DAMAGES
- OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- OTHER DEALINGS IN THE SOFTWARE.
diff --git a/node_modules/twig/docs/public/fonts/aller-bold.eot b/node_modules/twig/docs/public/fonts/aller-bold.eot
deleted file mode 100644
index 1b32532..0000000
--- a/node_modules/twig/docs/public/fonts/aller-bold.eot
+++ /dev/null
Binary files differ
diff --git a/node_modules/twig/docs/public/fonts/aller-bold.ttf b/node_modules/twig/docs/public/fonts/aller-bold.ttf
deleted file mode 100644
index dc4cc9c..0000000
--- a/node_modules/twig/docs/public/fonts/aller-bold.ttf
+++ /dev/null
Binary files differ
diff --git a/node_modules/twig/docs/public/fonts/aller-bold.woff b/node_modules/twig/docs/public/fonts/aller-bold.woff
deleted file mode 100644
index fa16fd0..0000000
--- a/node_modules/twig/docs/public/fonts/aller-bold.woff
+++ /dev/null
Binary files differ
diff --git a/node_modules/twig/docs/public/fonts/aller-light.eot b/node_modules/twig/docs/public/fonts/aller-light.eot
deleted file mode 100644
index 40bd654..0000000
--- a/node_modules/twig/docs/public/fonts/aller-light.eot
+++ /dev/null
Binary files differ
diff --git a/node_modules/twig/docs/public/fonts/aller-light.ttf b/node_modules/twig/docs/public/fonts/aller-light.ttf
deleted file mode 100644
index c2c7290..0000000
--- a/node_modules/twig/docs/public/fonts/aller-light.ttf
+++ /dev/null
Binary files differ
diff --git a/node_modules/twig/docs/public/fonts/aller-light.woff b/node_modules/twig/docs/public/fonts/aller-light.woff
deleted file mode 100644
index 81a09d1..0000000
--- a/node_modules/twig/docs/public/fonts/aller-light.woff
+++ /dev/null
Binary files differ
diff --git a/node_modules/twig/docs/public/fonts/novecento-bold.eot b/node_modules/twig/docs/public/fonts/novecento-bold.eot
deleted file mode 100644
index 98a9a7f..0000000
--- a/node_modules/twig/docs/public/fonts/novecento-bold.eot
+++ /dev/null
Binary files differ
diff --git a/node_modules/twig/docs/public/fonts/novecento-bold.ttf b/node_modules/twig/docs/public/fonts/novecento-bold.ttf
deleted file mode 100644
index 2af39b0..0000000
--- a/node_modules/twig/docs/public/fonts/novecento-bold.ttf
+++ /dev/null
Binary files differ
diff --git a/node_modules/twig/docs/public/fonts/novecento-bold.woff b/node_modules/twig/docs/public/fonts/novecento-bold.woff
deleted file mode 100644
index de558b5..0000000
--- a/node_modules/twig/docs/public/fonts/novecento-bold.woff
+++ /dev/null
Binary files differ
diff --git a/node_modules/twig/docs/public/stylesheets/normalize.css b/node_modules/twig/docs/public/stylesheets/normalize.css
deleted file mode 100644
index 73abb76..0000000
--- a/node_modules/twig/docs/public/stylesheets/normalize.css
+++ /dev/null
@@ -1,375 +0,0 @@
-/*! normalize.css v2.0.1 | MIT License | git.io/normalize */
-
-/* ==========================================================================
- HTML5 display definitions
- ========================================================================== */
-
-/*
- * Corrects `block` display not defined in IE 8/9.
- */
-
-article,
-aside,
-details,
-figcaption,
-figure,
-footer,
-header,
-hgroup,
-nav,
-section,
-summary {
- display: block;
-}
-
-/*
- * Corrects `inline-block` display not defined in IE 8/9.
- */
-
-audio,
-canvas,
-video {
- display: inline-block;
-}
-
-/*
- * Prevents modern browsers from displaying `audio` without controls.
- * Remove excess height in iOS 5 devices.
- */
-
-audio:not([controls]) {
- display: none;
- height: 0;
-}
-
-/*
- * Addresses styling for `hidden` attribute not present in IE 8/9.
- */
-
-[hidden] {
- display: none;
-}
-
-/* ==========================================================================
- Base
- ========================================================================== */
-
-/*
- * 1. Sets default font family to sans-serif.
- * 2. Prevents iOS text size adjust after orientation change, without disabling
- * user zoom.
- */
-
-html {
- font-family: sans-serif; /* 1 */
- -webkit-text-size-adjust: 100%; /* 2 */
- -ms-text-size-adjust: 100%; /* 2 */
-}
-
-/*
- * Removes default margin.
- */
-
-body {
- margin: 0;
-}
-
-/* ==========================================================================
- Links
- ========================================================================== */
-
-/*
- * Addresses `outline` inconsistency between Chrome and other browsers.
- */
-
-a:focus {
- outline: thin dotted;
-}
-
-/*
- * Improves readability when focused and also mouse hovered in all browsers.
- */
-
-a:active,
-a:hover {
- outline: 0;
-}
-
-/* ==========================================================================
- Typography
- ========================================================================== */
-
-/*
- * Addresses `h1` font sizes within `section` and `article` in Firefox 4+,
- * Safari 5, and Chrome.
- */
-
-h1 {
- font-size: 2em;
-}
-
-/*
- * Addresses styling not present in IE 8/9, Safari 5, and Chrome.
- */
-
-abbr[title] {
- border-bottom: 1px dotted;
-}
-
-/*
- * Addresses style set to `bolder` in Firefox 4+, Safari 5, and Chrome.
- */
-
-b,
-strong {
- font-weight: bold;
-}
-
-/*
- * Addresses styling not present in Safari 5 and Chrome.
- */
-
-dfn {
- font-style: italic;
-}
-
-/*
- * Addresses styling not present in IE 8/9.
- */
-
-mark {
- background: #ff0;
- color: #000;
-}
-
-
-/*
- * Corrects font family set oddly in Safari 5 and Chrome.
- */
-
-code,
-kbd,
-pre,
-samp {
- font-family: monospace, serif;
- font-size: 1em;
-}
-
-/*
- * Improves readability of pre-formatted text in all browsers.
- */
-
-pre {
- white-space: pre;
- white-space: pre-wrap;
- word-wrap: break-word;
-}
-
-/*
- * Sets consistent quote types.
- */
-
-q {
- quotes: "\201C" "\201D" "\2018" "\2019";
-}
-
-/*
- * Addresses inconsistent and variable font size in all browsers.
- */
-
-small {
- font-size: 80%;
-}
-
-/*
- * Prevents `sub` and `sup` affecting `line-height` in all browsers.
- */
-
-sub,
-sup {
- font-size: 75%;
- line-height: 0;
- position: relative;
- vertical-align: baseline;
-}
-
-sup {
- top: -0.5em;
-}
-
-sub {
- bottom: -0.25em;
-}
-
-/* ==========================================================================
- Embedded content
- ========================================================================== */
-
-/*
- * Removes border when inside `a` element in IE 8/9.
- */
-
-img {
- border: 0;
-}
-
-/*
- * Corrects overflow displayed oddly in IE 9.
- */
-
-svg:not(:root) {
- overflow: hidden;
-}
-
-/* ==========================================================================
- Figures
- ========================================================================== */
-
-/*
- * Addresses margin not present in IE 8/9 and Safari 5.
- */
-
-figure {
- margin: 0;
-}
-
-/* ==========================================================================
- Forms
- ========================================================================== */
-
-/*
- * Define consistent border, margin, and padding.
- */
-
-fieldset {
- border: 1px solid #c0c0c0;
- margin: 0 2px;
- padding: 0.35em 0.625em 0.75em;
-}
-
-/*
- * 1. Corrects color not being inherited in IE 8/9.
- * 2. Remove padding so people aren't caught out if they zero out fieldsets.
- */
-
-legend {
- border: 0; /* 1 */
- padding: 0; /* 2 */
-}
-
-/*
- * 1. Corrects font family not being inherited in all browsers.
- * 2. Corrects font size not being inherited in all browsers.
- * 3. Addresses margins set differently in Firefox 4+, Safari 5, and Chrome
- */
-
-button,
-input,
-select,
-textarea {
- font-family: inherit; /* 1 */
- font-size: 100%; /* 2 */
- margin: 0; /* 3 */
-}
-
-/*
- * Addresses Firefox 4+ setting `line-height` on `input` using `!important` in
- * the UA stylesheet.
- */
-
-button,
-input {
- line-height: normal;
-}
-
-/*
- * 1. Avoid the WebKit bug in Android 4.0.* where (2) destroys native `audio`
- * and `video` controls.
- * 2. Corrects inability to style clickable `input` types in iOS.
- * 3. Improves usability and consistency of cursor style between image-type
- * `input` and others.
- */
-
-button,
-html input[type="button"], /* 1 */
-input[type="reset"],
-input[type="submit"] {
- -webkit-appearance: button; /* 2 */
- cursor: pointer; /* 3 */
-}
-
-/*
- * Re-set default cursor for disabled elements.
- */
-
-button[disabled],
-input[disabled] {
- cursor: default;
-}
-
-/*
- * 1. Addresses box sizing set to `content-box` in IE 8/9.
- * 2. Removes excess padding in IE 8/9.
- */
-
-input[type="checkbox"],
-input[type="radio"] {
- box-sizing: border-box; /* 1 */
- padding: 0; /* 2 */
-}
-
-/*
- * 1. Addresses `appearance` set to `searchfield` in Safari 5 and Chrome.
- * 2. Addresses `box-sizing` set to `border-box` in Safari 5 and Chrome
- * (include `-moz` to future-proof).
- */
-
-input[type="search"] {
- -webkit-appearance: textfield; /* 1 */
- -moz-box-sizing: content-box;
- -webkit-box-sizing: content-box; /* 2 */
- box-sizing: content-box;
-}
-
-/*
- * Removes inner padding and search cancel button in Safari 5 and Chrome
- * on OS X.
- */
-
-input[type="search"]::-webkit-search-cancel-button,
-input[type="search"]::-webkit-search-decoration {
- -webkit-appearance: none;
-}
-
-/*
- * Removes inner padding and border in Firefox 4+.
- */
-
-button::-moz-focus-inner,
-input::-moz-focus-inner {
- border: 0;
- padding: 0;
-}
-
-/*
- * 1. Removes default vertical scrollbar in IE 8/9.
- * 2. Improves readability and alignment in all browsers.
- */
-
-textarea {
- overflow: auto; /* 1 */
- vertical-align: top; /* 2 */
-}
-
-/* ==========================================================================
- Tables
- ========================================================================== */
-
-/*
- * Remove most spacing between table cells.
- */
-
-table {
- border-collapse: collapse;
- border-spacing: 0;
-} \ No newline at end of file
diff --git a/node_modules/twig/docs/release checklist.md b/node_modules/twig/docs/release checklist.md
deleted file mode 100644
index 1718c0d..0000000
--- a/node_modules/twig/docs/release checklist.md
+++ /dev/null
@@ -1,20 +0,0 @@
-Steps to release twig.js
-
-## repository
-
-1. Compile list of changes in CHANGELOG.md
-2. Update version in package.json
-3. Update version in bower.json
-4. Update version in src/twig.header.js
-5. `make`, `make docs`, `make test` and commit the changes.
-6. `git tag` new version
-
-## bower
-
-Bower will pick up the new version in bower.json and use the associated git tag.
-
-## npm
-
-To publish the latest version to npmjs.org run this command from the twig.js directory:
-
- npm publish
diff --git a/node_modules/twig/docs/tests.md b/node_modules/twig/docs/tests.md
deleted file mode 100644
index 5afa1b7..0000000
--- a/node_modules/twig/docs/tests.md
+++ /dev/null
@@ -1,3567 +0,0 @@
-# TOC
- - [Twig.js Blocks ->](#twigjs-blocks--)
- - [block function ->](#twigjs-blocks---block-function--)
- - [block shorthand ->](#twigjs-blocks---block-shorthand--)
- - [Twig.js Control Structures ->](#twigjs-control-structures--)
- - [if tag ->](#twigjs-control-structures---if-tag--)
- - [for tag ->](#twigjs-control-structures---for-tag--)
- - [set tag ->](#twigjs-control-structures---set-tag--)
- - [Twig.js Core ->](#twigjs-core--)
- - [Key Notation ->](#twigjs-core---key-notation--)
- - [Context ->](#twigjs-core---context--)
- - [Twig.js Embed ->](#twigjs-embed--)
- - [Twig.js Expressions ->](#twigjs-expressions--)
- - [Basic Operators ->](#twigjs-expressions---basic-operators--)
- - [Comparison Operators ->](#twigjs-expressions---comparison-operators--)
- - [Other Operators ->](#twigjs-expressions---other-operators--)
- - [Twig.js Extensions ->](#twigjs-extensions--)
- - [Twig.js Filters ->](#twigjs-filters--)
- - [url_encode ->](#twigjs-filters---url_encode--)
- - [json_encode ->](#twigjs-filters---json_encode--)
- - [upper ->](#twigjs-filters---upper--)
- - [lower ->](#twigjs-filters---lower--)
- - [capitalize ->](#twigjs-filters---capitalize--)
- - [title ->](#twigjs-filters---title--)
- - [length ->](#twigjs-filters---length--)
- - [sort ->](#twigjs-filters---sort--)
- - [reverse ->](#twigjs-filters---reverse--)
- - [keys ->](#twigjs-filters---keys--)
- - [merge ->](#twigjs-filters---merge--)
- - [join ->](#twigjs-filters---join--)
- - [default ->](#twigjs-filters---default--)
- - [date ->](#twigjs-filters---date--)
- - [replace ->](#twigjs-filters---replace--)
- - [format ->](#twigjs-filters---format--)
- - [striptags ->](#twigjs-filters---striptags--)
- - [escape ->](#twigjs-filters---escape--)
- - [e ->](#twigjs-filters---e--)
- - [nl2br ->](#twigjs-filters---nl2br--)
- - [truncate ->](#twigjs-filters---truncate--)
- - [trim ->](#twigjs-filters---trim--)
- - [number_format ->](#twigjs-filters---number_format--)
- - [slice ->](#twigjs-filters---slice--)
- - [abs ->](#twigjs-filters---abs--)
- - [first ->](#twigjs-filters---first--)
- - [split ->](#twigjs-filters---split--)
- - [batch ->](#twigjs-filters---batch--)
- - [last ->](#twigjs-filters---last--)
- - [raw ->](#twigjs-filters---raw--)
- - [round ->](#twigjs-filters---round--)
- - [Twig.js Loader ->](#twigjs-loader--)
- - [source ->](#twigjs-loader---source--)
- - [Twig.js Include ->](#twigjs-include--)
- - [Twig.js Functions ->](#twigjs-functions--)
- - [Built-in Functions ->](#twigjs-functions---built-in-functions--)
- - [range ->](#twigjs-functions---built-in-functions---range--)
- - [cycle ->](#twigjs-functions---built-in-functions---cycle--)
- - [date ->](#twigjs-functions---built-in-functions---date--)
- - [dump ->](#twigjs-functions---built-in-functions---dump--)
- - [block ->](#twigjs-functions---built-in-functions---block--)
- - [attribute ->](#twigjs-functions---built-in-functions---attribute--)
- - [template_from_string ->](#twigjs-functions---built-in-functions---template_from_string--)
- - [random ->](#twigjs-functions---built-in-functions---random--)
- - [min, max ->](#twigjs-functions---built-in-functions---min-max--)
- - [Twig.js Loaders ->](#twigjs-loaders--)
- - [custom loader ->](#twigjs-loaders---custom-loader--)
- - [Twig.js Macro ->](#twigjs-macro--)
- - [Twig.js Namespaces ->](#twigjs-namespaces--)
- - [Twig.js Optional Functionality ->](#twigjs-optional-functionality--)
- - [Twig.js Parsers ->](#twigjs-parsers--)
- - [custom parser ->](#twigjs-parsers---custom-parser--)
- - [Twig.js Path ->](#twigjs-path--)
- - [relativePath ->](#twigjs-path---relativepath--)
- - [url ->](#twigjs-path---relativepath---url--)
- - [path ->](#twigjs-path---relativepath---path--)
- - [parsePath ->](#twigjs-path---parsepath--)
- - [Twig.js Regression Tests ->](#twigjs-regression-tests--)
- - [Twig.js Tags ->](#twigjs-tags--)
- - [Twig.js Tests ->](#twigjs-tests--)
- - [empty test ->](#twigjs-tests---empty-test--)
- - [odd test ->](#twigjs-tests---odd-test--)
- - [even test ->](#twigjs-tests---even-test--)
- - [divisibleby test ->](#twigjs-tests---divisibleby-test--)
- - [defined test ->](#twigjs-tests---defined-test--)
- - [none test ->](#twigjs-tests---none-test--)
- - [sameas test ->](#twigjs-tests---sameas-test--)
- - [iterable test ->](#twigjs-tests---iterable-test--)
-<a name=""></a>
-
-<a name="twigjs-blocks--"></a>
-# Twig.js Blocks ->
-should load a parent template and render the default values.
-
-```js
-twig({
- id: 'remote-no-extends',
- path: 'test/templates/template.twig',
- async: false
-});
-// Load the template
-twig({ref: 'remote-no-extends'}).render({ }).should.equal( "Default Title - body" );
-```
-
-should understand {% endblock title %} syntax.
-
-```js
-twig({
- id: 'endblock-extended-syntax',
- path: 'test/templates/blocks-extended-syntax.twig',
- async: false
-});
-// Load the template
-twig({ref: 'endblock-extended-syntax'}).render({ }).should.equal( "This is the only thing." );
-```
-
-should load a child template and replace the parent block's content.
-
-```js
-// Test loading a template from a remote endpoint
-twig({
- id: 'child-extends',
- path: 'test/templates/child.twig',
- load: function(template) {
- template.render({ base: "template.twig" }).should.equal( "Other Title - child" );
- done();
- }
-});
-```
-
-should have access to a parent block content.
-
-```js
-// Test loading a template from a remote endpoint
-twig({
- id: 'child-parent',
- path: 'test/templates/child-parent.twig',
- load: function(template) {
- template.render({
- base: "template.twig",
- inner: ':value'
- }).should.equal( "Other Title - body:value:child" );
- done();
- }
-});
-```
-
-should include blocks from another template for horizontal reuse.
-
-```js
-// Test horizontal reuse
-twig({
- id: 'use',
- path: 'test/templates/use.twig',
- load: function(template) {
- // Load the template
- template.render({ place: "diner" }).should.equal("Coming soon to a diner near you!" );
- done();
- }
-});
-```
-
-should allow overriding of included blocks.
-
-```js
-// Test overriding of included blocks
-twig({
- id: 'use-override-block',
- path: 'test/templates/use-override-block.twig',
- load: function(template) {
- // Load the template
- template.render({ place: "diner" }).should.equal("Sorry, can't come to a diner today." );
- done();
- }
-});
-```
-
-should allow overriding of included nested blocks.
-
-```js
-// Test overriding of included blocks
-twig({
- id: 'use-override-nested-block',
- path: 'test/templates/use-override-nested-block.twig',
- load: function(template) {
- // Load the template
- template.render().should.equal("parent:new-child1:new-child2");
- done();
- }
-});
-```
-
-should make the contents of blocks available after they're rendered.
-
-```js
-// Test rendering and loading one block
-twig({
- id: 'blocks',
- path: 'test/templates/blocks.twig',
- load: function(template) {
- // Render the template with the blocks parameter
- template.render({ place: "block" }, {output: 'blocks'}).msg.should.equal("Coming soon to a block near you!" );
- done();
- }
-});
-```
-
-should render nested blocks.
-
-```js
-// Test rendering of blocks within blocks
-twig({
- id: 'blocks-nested',
- path: 'test/templates/blocks-nested.twig',
- load: function(template) {
- template.render({ }).should.equal( "parent:child" )
- done();
- }
-})
-```
-
-should render extended nested blocks.
-
-```js
-// Test rendering of blocks within blocks
-twig({
- id: 'child-blocks-nested',
- path: 'test/templates/child-blocks-nested.twig',
- load: function(template) {
- template.render({ base: "template.twig" }).should.equal( "Default Title - parent:child" );
- done();
- }
-})
-```
-
-should be able to extend to a absolute template path.
-
-```js
-// Test loading a template from a remote endpoint
-twig({
- base: 'test/templates',
- path: 'test/templates/a/child.twig',
- load: function(template) {
- template.render({ base: "b/template.twig" }).should.equal( "Other Title - child" );
- done();
- }
-});
-```
-
-should extends blocks inline.
-
-```js
-twig({
- id: 'inline-parent-template',
- data: 'Title: {% block title %}parent{% endblock %}'
-});
-twig({
- allowInlineIncludes: true,
- data: '{% extends "inline-parent-template" %}{% block title %}child{% endblock %}'
-}).render().should.equal("Title: child");
-```
-
-<a name="twigjs-blocks---block-function--"></a>
-## block function ->
-should render block content from an included block.
-
-```js
-twig({
- path: 'test/templates/block-function.twig',
- load: function(template) {
- template.render({
- base: "block-function-parent.twig",
- val: "abcd"
- })
- .should.equal( "Child content = abcd / Result: Child content = abcd" );
- done();
- }
-})
-```
-
-should render block content from a parent block.
-
-```js
-twig({
- path: 'test/templates/block-parent.twig',
- load: function(template) {
- template.render({
- base: "block-function-parent.twig"
- })
- .should.equal( "parent block / Result: parent block" );
- done();
- }
-})
-```
-
-should render block content with outer context.
-
-```js
-twig({
- path: 'test/templates/block-outer-context.twig',
- load: function(template) {
- template.render({
- base: "block-outer-context.twig",
- items: ["twig", "js", "rocks"]
- })
- .should.equal( "Hello twig!Hello js!Hello rocks!twigjsrocks" );
- done();
- }
-})
-```
-
-should respect changes of the context made before calling the function.
-
-```js
-twig({
- data: '{% set foo = "original" %}{% block test %}{{ foo }}{% endblock %} {% set foo = "changed" %}{{ block("test") }}'
-}).render()
-.should.equal("original changed");
-```
-
-<a name="twigjs-blocks---block-shorthand--"></a>
-## block shorthand ->
-should render block content using shorthand syntax.
-
-```js
-twig({
- data: '{% set prefix = "shorthand" %}{% block title (prefix ~ " - " ~ block_value)|title %}'
-})
-.render({block_value: 'test succeeded'})
-.should.equal('Shorthand - Test Succeeded');
-```
-
-should overload blocks from an extended template using shorthand syntax.
-
-```js
-twig({
- allowInlineIncludes: true,
- data: '{% extends "child-extends" %}{% block title "New Title" %}{% block body "new body uses the " ~ base ~ " template" %}'
-})
-.render({ base: "template.twig" })
-.should.equal( "New Title - new body uses the template.twig template" );
-```
-
-<a name="twigjs-control-structures--"></a>
-# Twig.js Control Structures ->
-<a name="twigjs-control-structures---if-tag--"></a>
-## if tag ->
-should parse the contents of the if block if the expression is true.
-
-```js
-var test_template = twig({data: '{% if test %}true{% endif%}'});
-test_template.render({test: true}).should.equal("true" );
-test_template.render({test: false}).should.equal("" );
-```
-
-should call the if or else blocks based on the expression result.
-
-```js
-var test_template = twig({data: '{% if test %}true{% endif%}'});
-test_template.render({test: true}).should.equal("true" );
-test_template.render({test: false}).should.equal("" );
-```
-
-should support elseif.
-
-```js
-var test_template = twig({data: '{% if test %}1{% elseif other %}2{%else%}3{% endif%}'});
-test_template.render({test: true, other:false}).should.equal("1" );
-test_template.render({test: true, other:true}).should.equal("1" );
-test_template.render({test: false, other:true}).should.equal("2" );
-test_template.render({test: false, other:false}).should.equal("3" );
-```
-
-should be able to nest.
-
-```js
-var test_template = twig({data: '{% if test %}{% if test2 %}true{% else %}false{% endif%}{% else %}not{% endif%}'});
-test_template.render({test: true, test2: true}).should.equal("true" );
-test_template.render({test: true, test2: false}).should.equal("false" );
-test_template.render({test: false, test2: true}).should.equal("not" );
-test_template.render({test: false, test2: false}).should.equal("not" );
-```
-
-should support newlines in if statement.
-
-```js
-var test_template = twig({data: '{% if test or\r\nother %}true{% endif%}'});
-test_template.render({test: true, other: false}).should.equal("true" );
-test_template.render({test: false, other: false}).should.equal("" );
-```
-
-<a name="twigjs-control-structures---for-tag--"></a>
-## for tag ->
-should provide value only for array input.
-
-```js
-var test_template = twig({data: '{% for value in test %}{{ value }}{% endfor %}'});
-test_template.render({test: [1,2,3,4]}).should.equal("1234" );
-test_template.render({test: []}).should.equal("" );
-```
-
-should provide both key and value for array input.
-
-```js
-var test_template = twig({data: '{% for key,value in test %}{{key}}:{{ value }}{% endfor %}'});
-test_template.render({test: [1,2,3,4]}).should.equal("0:11:22:33:4" );
-test_template.render({test: []}).should.equal("" );
-```
-
-should provide value only for object input.
-
-```js
-var test_template = twig({data: '{% for value in test %}{{ value }}{% endfor %}'});
-test_template.render({test: {one: 1, two: 2, three: 3}}).should.equal("123" );
-test_template.render({test: {}}).should.equal("" );
-```
-
-should provide both key and value for object input.
-
-```js
-var test_template = twig({data: '{% for key, value in test %}{{key}}:{{ value }}{% endfor %}'});
-test_template.render({test: {one: 1, two: 2, three: 3}}).should.equal("one:1two:2three:3" );
-test_template.render({test: {}}).should.equal("" );
-```
-
-should support else if the input is empty.
-
-```js
-var test_template = twig({data: '{% for key,value in test %}{{ value }}{% else %}else{% endfor %}'});
-test_template.render({test: [1,2,3,4]}).should.equal("1234" );
-test_template.render({test: []}).should.equal("else" );
-```
-
-should be able to nest.
-
-```js
-var test_template = twig({data: '{% for key,list in test %}{% for val in list %}{{ val }}{%endfor %}.{% else %}else{% endfor %}'});
-test_template.render({test: [[1,2],[3,4],[5,6]]}).should.equal("12.34.56." );
-test_template.render({test: []}).should.equal("else" );
-```
-
-should have a loop context item available for arrays.
-
-```js
-var test_template = twig({data: '{% for key,value in test %}{{ loop.index }}{% endfor %}'});
-test_template.render({test: [1,2,3,4]}).should.equal("1234" );
-test_template = twig({data: '{% for key,value in test %}{{ loop.index0 }}{% endfor %}'});
-test_template.render({test: [1,2,3,4]}).should.equal("0123" );
-test_template = twig({data: '{% for key,value in test %}{{ loop.revindex }}{% endfor %}'});
-test_template.render({test: [1,2,3,4]}).should.equal("4321" );
-test_template = twig({data: '{% for key,value in test %}{{ loop.revindex0 }}{% endfor %}'});
-test_template.render({test: [1,2,3,4]}).should.equal("3210" );
-test_template = twig({data: '{% for key,value in test %}{{ loop.length }}{% endfor %}'});
-test_template.render({test: [1,2,3,4]}).should.equal("4444" );
-test_template = twig({data: '{% for key,value in test %}{{ loop.first }}{% endfor %}'});
-test_template.render({test: [1,2,3,4]}).should.equal("truefalsefalsefalse" );
-test_template = twig({data: '{% for key,value in test %}{{ loop.last }}{% endfor %}'});
-test_template.render({test: [1,2,3,4]}).should.equal("falsefalsefalsetrue" );
-```
-
-should have a loop context item available for objects.
-
-```js
-var test_template = twig({data: '{% for key,value in test %}{{ loop.index }}{% endfor %}'});
-test_template.render({test: {a:1,b:2,c:3,d:4}}).should.equal("1234" );
-test_template = twig({data: '{% for key,value in test %}{{ loop.index0 }}{% endfor %}'});
-test_template.render({test: {a:1,b:2,c:3,d:4}}).should.equal("0123" );
-test_template = twig({data: '{% for key,value in test %}{{ loop.revindex }}{% endfor %}'});
-test_template.render({test: {a:1,b:2,c:3,d:4}}).should.equal("4321" );
-test_template = twig({data: '{% for key,value in test %}{{ loop.revindex0 }}{% endfor %}'});
-test_template.render({test: {a:1,b:2,c:3,d:4}}).should.equal("3210" );
-test_template = twig({data: '{% for key,value in test %}{{ loop.length }}{% endfor %}'});
-test_template.render({test: {a:1,b:2,c:3,d:4}}).should.equal("4444" );
-test_template = twig({data: '{% for key,value in test %}{{ loop.first }}{% endfor %}'});
-test_template.render({test: {a:1,b:2,c:3,d:4}}).should.equal("truefalsefalsefalse" );
-test_template = twig({data: '{% for key,value in test %}{{ loop.last }}{% endfor %}'});
-test_template.render({test: {a:1,b:2,c:3,d:4}}).should.equal("falsefalsefalsetrue" );
-```
-
-should have a loop context item available in child loops objects.
-
-```js
-var test_template = twig({data: '{% for value in test %}{% for value in inner %}({{ loop.parent.loop.index }},{{ loop.index }}){% endfor %}{% endfor %}'});
-test_template.render({test: {a:1,b:2}, inner:[1,2,3]}).should.equal("(1,1)(1,2)(1,3)(2,1)(2,2)(2,3)");
-```
-
-should support conditionals on for loops.
-
-```js
-var test_template = twig({data: '{% for value in test if false %}{{ value }},{% endfor %}'});
-test_template.render({test: ["one", "two", "a", "b", "other"]}).should.equal("");
-test_template = twig({data: '{% for value in test if true %}{{ value }}{% endfor %}'});
-test_template.render({test: ["a", "s", "d", "f"]}).should.equal("asdf");
-test_template = twig({data: '{% for value in test if value|length > 2 %}{{ value }},{% endfor %}'});
-test_template.render({test: ["one", "two", "a", "b", "other"]}).should.equal("one,two,other,");
-test_template = twig({data: '{% for key,item in test if item.show %}{{key}}:{{ item.value }},{% endfor %}'});
-test_template.render({test: {
- a: {show:true, value: "one"},
- b: {show:false, value: "two"},
- c: {show:true, value: "three"}}}).should.equal("a:one,c:three,");
-```
-
-<a name="twigjs-control-structures---set-tag--"></a>
-## set tag ->
-should not set the global context from within a for loop.
-
-```js
-var test_template = twig({data: '{% for value in [1] %}{% set foo="right" %}{% endfor %}{{ foo }}'});
-test_template.render().should.equal("");
-```
-
-should set the global context from within a for loop when the variable is initialized outside of the loop.
-
-```js
-var test_template = twig({data: '{% set foo="wrong" %}{% for value in [1] %}{% set foo="right" %}{% endfor %}{{ foo }}'});
-test_template.render().should.equal("right");
-```
-
-should set the global context from within a nested for loop when the variable is initialized outside of the loop.
-
-```js
-var test_template = twig({data: '{% set k = 0 %}{% for i in 0..2 %}{% for j in 0..2 %}{{ k }}{% set k = k + 1 %}{% endfor %}{% endfor %}'});
-test_template.render().should.equal("012345678");
-```
-
-<a name="twigjs-core--"></a>
-# Twig.js Core ->
-should save and load a template by reference.
-
-```js
-// Define and save a template
- twig({
- id: 'test',
- data: '{{ "test" }}'
- });
- // Load and render the template
- twig({ref: 'test'}).render()
- .should.equal("test");
-```
-
-should ignore comments.
-
-```js
-twig({data: 'good {# comment #}morning'}).render().should.equal("good morning");
-twig({data: 'good{#comment#}morning'}).render().should.equal("goodmorning");
-```
-
-should ignore output tags within comments.
-
-```js
-twig({data: 'good {# {{ "Hello" }} #}morning'}).render().should.equal("good morning");
-twig({data: 'good{#c}}om{{m{{ent#}morning'}).render().should.equal("goodmorning");
-```
-
-should ignore logic tags within comments.
-
-```js
-twig({data: 'test {# {% bad syntax if not in comment %} #}test'}).render().should.equal("test test");
-twig({data: '{##}{##}test{# %}}}%}%{%{{% #}pass'}).render().should.equal("testpass");
-```
-
-should ignore quotation marks within comments.
-
-```js
-twig({data: "good {# don't stop #}morning"}).render().should.equal("good morning");
-twig({data: 'good{#"dont stop"#}morning'}).render().should.equal("goodmorning");
-twig({data: 'good {# "don\'t stop" #}morning'}).render().should.equal("good morning");
-twig({data: 'good{#"\'#}morning'}).render().should.equal("goodmorning");
-twig({data: 'good {#"\'"\'"\'#} day'}).render().should.equal("good day");
-twig({data: "a {# ' #}b{# ' #} c"}).render().should.equal("a b c");
-```
-
-should be able to parse output tags with tag ends in strings.
-
-```js
-// Really all we care about here is not throwing exceptions.
-twig({data: '{{ "test" }}'}).render().should.equal("test");
-twig({data: '{{ " }} " }}'}).render().should.equal(" }} ");
-twig({data: '{{ " \\"}} " }}'}).render().should.equal(' "}} ');
-twig({data: "{{ ' }} ' }}"}).render().should.equal(" }} ");
-twig({data: "{{ ' \\'}} ' }}"}).render().should.equal(" '}} ");
-twig({data: '{{ " \'}} " }}'}).render().should.equal(" '}} ");
-twig({data: "{{ ' \"}} ' }}"}).render().should.equal(' "}} ');
-```
-
-should be able to parse whitespace control output tags.
-
-```js
-twig({data: ' {{- "test" -}}'}).render().should.equal("test");
-twig({data: ' {{- "test" -}} '}).render().should.equal("test");
-twig({data: '\n{{- "test" -}}'}).render().should.equal("test");
-twig({data: '{{- "test" -}}\n'}).render().should.equal("test");
-twig({data: '\n{{- "test" -}}\n'}).render().should.equal("test");
-twig({data: '\t{{- "test" -}}\t'}).render().should.equal("test");
-twig({data: '\n\t{{- "test" -}}\n\t'}).render().should.equal("test");
-twig({data: '123\n\t{{- "test" -}}\n\t456'}).render().should.equal("123test456");
-twig({data: '\n{{- orp -}}\n'}).render({ orp: "test"}).should.equal("test");
-twig({data: '\n{{- [1,2 ,1+2 ] -}}\n'}).render().should.equal("1,2,3");
-twig({data: ' {{- "test" -}} {{- "test" -}}'}).render().should.equal("testtest");
-twig({data: '{{ "test" }} {{- "test" -}}'}).render().should.equal("testtest");
-twig({data: '{{- "test" -}} {{ "test" }}'}).render().should.equal("testtest");
-twig({data: '<>{{- "test" -}}<>'}).render().should.equal("<>test<>");
-```
-
-should be able to parse mismatched opening whitespace control output tags.
-
-```js
-twig({data: ' {{- "test" }}'}).render().should.equal("test");
-twig({data: '{{- "test" }}\n'}).render().should.equal("test\n");
-twig({data: '\t{{- "test" }}\t'}).render().should.equal("test\t");
-twig({data: '123\n\t{{- "test" }}\n\t456'}).render().should.equal("123test\n\t456");
-twig({data: '\n{{- [1,2 ,1+2 ] }}\n'}).render().should.equal("1,2,3\n");
-twig({data: ' {{- "test" }} {{- "test" }}'}).render().should.equal("testtest");
-twig({data: '{{ "test" }} {{- "test" }}'}).render().should.equal("testtest");
-twig({data: ' {{- "test" }} {{ "test" }}'}).render().should.equal("test test");
-twig({data: ' {{- "test" }} {{- "test" -}}'}).render().should.equal("testtest");
-twig({data: '<>{{- "test" }}'}).render().should.equal("<>test");
-```
-
-should be able to parse mismatched closing whitespace control output tags.
-
-```js
-twig({data: ' {{ "test" -}}'}).render().should.equal(" test");
-twig({data: '\n{{ "test" -}}\n'}).render().should.equal("\ntest");
-twig({data: '\t{{ "test" -}}\t'}).render().should.equal("\ttest");
-twig({data: '123\n\t{{ "test" -}}\n\t456'}).render().should.equal("123\n\ttest456");
-twig({data: '\n{{ [1,2 ,1+2 ] -}}\n'}).render().should.equal("\n1,2,3");
-twig({data: ' {{ "test" -}} {{ "test" -}}'}).render().should.equal(" testtest");
-twig({data: '{{ "test" }} {{ "test" -}} '}).render().should.equal("test test");
-twig({data: ' {{ "test" -}} {{ "test" }} '}).render().should.equal(" testtest ");
-twig({data: ' {{ "test" -}} {{- "test" -}}'}).render().should.equal(" testtest");
-twig({data: '{{ "test" -}}<>'}).render().should.equal("test<>");
-```
-
-should be able to parse whitespace control logic tags.
-
-```js
-// Newlines directly after logic tokens are ignored
-// So use double newlines
-twig({data: '{%- if true -%}{{ "test" }}{% endif %}'}).render().should.equal("test");
-twig({data: '{%- if true -%}{{ "test" }}{%- endif -%}'}).render().should.equal("test");
-twig({data: ' {%- if true -%} {{ "test" }}{% endif %}'}).render().should.equal("test");
-twig({data: '\n{%- if true -%}\n\n{{ "test" }}{% endif %}'}).render().should.equal("test");
-twig({data: '\n\t{%- if true -%}\n\n\t{{ "test" }}{% endif %}'}).render().should.equal("test");
-twig({data: '123\n\t{%- if true -%}\n\n\t{{ "test" }}{% endif %}456'}).render().should.equal("123test456");
-twig({data: '\n\t{%- if true -%}\n\n\t{{ [1,2 ,1+2 ] }}{% endif %}'}).render().should.equal("1,2,3");
-twig({data: '<>{%- if true -%}test{% endif %}<>'}).render().should.equal("<>test<>");
-```
-
-should be able to parse mismatched opening whitespace control logic tags.
-
-```js
-twig({data: '{%- if true %}{{ "test" }}{% endif %}'}).render().should.equal("test");
-twig({data: '{%- if true %}{{ "test" }}{% endif %}'}).render().should.equal("test");
-twig({data: ' {% if true %} {{ "test" }}{% endif %}'}).render().should.equal(" test");
-twig({data: ' {%- if true %} {{ "test" }}{% endif %}'}).render().should.equal(" test");
-twig({data: '\n{% if true %}\n\n{{ "test" }}{% endif %}'}).render().should.equal("\n\ntest");
-twig({data: '\n{%- if true %}\n\n{{ "test" }}{% endif %}'}).render().should.equal("\ntest");
-twig({data: '\n\t{%- if true %}\n\n\t{{ "test" }}{% endif %}'}).render().should.equal("\n\ttest");
-twig({data: '123\n\t{%- if true %}\n\n\t{{ "test" }}{% endif %}456'}).render().should.equal("123\n\ttest456");
-twig({data: '\n\t{%- if true %}\n\n\t{{ [1,2 ,1+2 ] }}{% endif %}'}).render().should.equal("\n\t1,2,3");
-twig({data: '<>{%- if true %}test{% endif %}'}).render().should.equal("<>test");
-```
-
-should be able to parse mismatched closing whitespace control logic tags.
-
-```js
-twig({data: '{% if true %}{{ "test" }}{% endif %}'}).render().should.equal("test");
-twig({data: '{% if true -%} {{ "test" }}{% endif %}'}).render().should.equal("test");
-twig({data: ' {% if true -%} {{ "test" }}{% endif %}'}).render().should.equal(" test");
-twig({data: ' {% if true -%} {{ "test" }}{% endif %}'}).render().should.equal(" test");
-twig({data: '\n{% if true %}\n\n{{ "test" }}{% endif %}'}).render().should.equal("\n\ntest");
-twig({data: '\n{% if true -%}\n\n{{ "test" }}{% endif %}'}).render().should.equal("\ntest");
-twig({data: '\n\t{% if true -%}\n\n\t{{ "test" }}{% endif %}'}).render().should.equal("\n\ttest");
-twig({data: '123\n\t{% if true -%}\n\n\t{{ "test" }}{% endif %}456'}).render().should.equal("123\n\ttest456");
-twig({data: '\n\t{% if true -%}\n\n\t{{ [1,2 ,1+2 ] }}{% endif %}'}).render().should.equal("\n\t1,2,3");
-twig({data: '{% if true -%}<>test{% endif %}'}).render().should.equal("<>test");
-```
-
-should be able to output numbers.
-
-```js
-twig({data: '{{ 12 }}'}).render().should.equal( "12" );
-twig({data: '{{ 12.64 }}'}).render().should.equal( "12.64" );
-twig({data: '{{ 0.64 }}'}).render().should.equal("0.64" );
-```
-
-should be able to output booleans.
-
-```js
-twig({data: '{{ true }}'}).render().should.equal( "true" );
-twig({data: '{{ false }}'}).render().should.equal( "false" );
-```
-
-should be able to output strings.
-
-```js
-twig({data: '{{ "double" }}'}).render().should.equal("double");
-twig({data: "{{ 'single' }}"}).render().should.equal('single');
-twig({data: '{{ "dou\'ble" }}'}).render().should.equal("dou'ble");
-twig({data: "{{ 'sin\"gle' }}"}).render().should.equal('sin"gle');
-twig({data: '{{ "dou\\"ble" }}'}).render().should.equal("dou\"ble");
-twig({data: "{{ 'sin\\'gle' }}"}).render().should.equal("sin'gle");
-```
-
-should be able to output strings with newlines.
-
-```js
-twig({data: "{{ 'a\nb\rc\r\nd' }}"}).render().should.equal("a\nb\rc\r\nd");
-```
-
-should be able to output arrays.
-
-```js
-twig({data: '{{ [1] }}'}).render().should.equal("1" );
-twig({data: '{{ [1,2 ,3 ] }}'}).render().should.equal("1,2,3" );
-twig({data: '{{ [1,2 ,3 , val ] }}'}).render({val: 4}).should.equal("1,2,3,4" );
-twig({data: '{{ ["[to",\'the\' ,"string]" ] }}'}).render().should.equal('[to,the,string]' );
-twig({data: '{{ ["[to",\'the\' ,"str\\"ing]" ] }}'}).render().should.equal('[to,the,str"ing]' );
-```
-
-should be able to output parse expressions in an array.
-
-```js
-twig({data: '{{ [1,2 ,1+2 ] }}'}).render().should.equal("1,2,3" );
-twig({data: '{{ [1,2 ,3 , "-", [4,5, 6] ] }}'}).render({val: 4}).should.equal("1,2,3,-,4,5,6" );
-twig({data: '{{ [a,b ,(1+2) * a ] }}'}).render({a:1,b:2}).should.equal("1,2,3" );
-```
-
-should be able to output variables.
-
-```js
-twig({data: '{{ orp }}'}).render({ orp: "test"}).should.equal("test");
-twig({data: '{{ val }}'}).render({ val: function() {
- return "test"
- }}).should.equal("test");
-```
-
-should recognize null.
-
-```js
-twig({data: '{{ null == val }}'}).render({val: null}).should.equal( "true" );
-twig({data: '{{ null == val }}'}).render({val: undefined}).should.equal( "true" );
-twig({data: '{{ null == val }}'}).render({val: "test"}).should.equal( "false" );
-twig({data: '{{ null == val }}'}).render({val: 0}).should.equal( "false" );
-twig({data: '{{ null == val }}'}).render({val: false}).should.equal( "false" );
-```
-
-should recognize object literals.
-
-```js
-twig({data: '{% set at = {"foo": "test", bar: "other", 1:"zip"} %}{{ at.foo ~ at.bar ~ at.1 }}'}).render().should.equal( "testotherzip" );
-```
-
-should allow newlines in object literals.
-
-```js
-twig({data: '{% set at = {\n"foo": "test",\rbar: "other",\r\n1:"zip"\n} %}{{ at.foo ~ at.bar ~ at.1 }}'}).render().should.equal( "testotherzip" );
-```
-
-should recognize null in an object.
-
-```js
-twig({data: '{% set at = {"foo": null} %}{{ at.foo == val }}'}).render({val: null}).should.equal( "true" );
-```
-
-should allow int 0 as a key in an object.
-
-```js
-twig({data: '{% set at = {0: "value"} %}{{ at.0 }}'}).render().should.equal( "value" );
-```
-
-should support set capture.
-
-```js
-twig({data: '{% set foo %}bar{% endset %}{{foo}}'}).render().should.equal( "bar" );
-```
-
-should support raw data.
-
-```js
-twig({
- data: "before {% raw %}{{ test }} {% test2 %} {{{% endraw %} after"
-}).render().should.equal(
- "before {{ test }} {% test2 %} {{ after"
-);
-```
-
-should support raw data using 'verbatim' tag.
-
-```js
-twig({
- data: "before {% verbatim %}{{ test }} {% test2 %} {{{% endverbatim %} after"
-}).render().should.equal(
- "before {{ test }} {% test2 %} {{ after"
-);
-```
-
-<a name="twigjs-core---key-notation--"></a>
-## Key Notation ->
-should support dot key notation.
-
-```js
-twig({data: '{{ key.value }} {{ key.sub.test }}'}).render({
- key: {
- value: "test",
- sub: {
- test: "value"
- }
- }
-}).should.equal("test value");
-```
-
-should support square bracket key notation.
-
-```js
-twig({data: '{{ key["value"] }} {{ key[\'sub\']["test"] }}'}).render({
- key: {
- value: "test",
- sub: {
- test: "value"
- }
- }
-}).should.equal("test value");
-```
-
-should support mixed dot and bracket key notation.
-
-```js
-twig({data: '{{ key["value"] }} {{ key.sub[key.value] }} {{ s.t["u"].v["w"] }}'}).render({
- key: {
- value: "test",
- sub: {
- test: "value"
- }
- },
- s: { t: { u: { v: { w: 'x' } } } }
-}).should.equal("test value x" );
-```
-
-should support dot key notation after a function.
-
-```js
-var test_template = twig({data: '{{ key.fn().value }}'});
-var output = test_template.render({
- key: {
- fn: function() {
- return {
- value: "test"
- }
- }
- }
-});
-output.should.equal("test");
-```
-
-should support bracket key notation after a function.
-
-```js
-var test_template = twig({data: '{{ key.fn()["value"] }}'});
-var output = test_template.render({
- key: {
- fn: function() {
- return {
- value: "test 2"
- }
- }
- }
-});
-output.should.equal("test 2");
-```
-
-should check for getKey methods if a key doesn't exist..
-
-```js
-twig({data: '{{ obj.value }}'}).render({
- obj: {
- getValue: function() {
- return "val";
- },
- isValue: function() {
- return "not val";
- }
- }
-}).should.equal("val");
-```
-
-should check for isKey methods if a key doesn't exist..
-
-```js
-twig({data: '{{ obj.value }}'}).render({
- obj: {
- isValue: function() {
- return "val";
- }
- }
-}).should.equal("val");
-```
-
-should check for getKey methods on prototype objects..
-
-```js
-var object = {
- getValue: function() {
- return "val";
- }
- };
-function Subobj() {};
-Subobj.prototype = object;
-var subobj = new Subobj();
-
- twig({data: '{{ obj.value }}'}).render({
- obj: subobj
- }).should.equal("val");
-```
-
-should return null if a period key doesn't exist..
-
-```js
-twig({data: '{{ obj.value == null }}'}).render({
- obj: {}
-}).should.equal("true");
-```
-
-should return null if a bracket key doesn't exist..
-
-```js
-twig({data: '{{ obj["value"] == null }}'}).render({
- obj: {}
-}).should.equal("true");
-```
-
-<a name="twigjs-core---context--"></a>
-## Context ->
-should be supported.
-
-```js
-twig({data: '{{ _context.value }}'}).render({
- value: "test"
-}).should.equal("test");
-```
-
-should be an object even if it's not passed.
-
-```js
-twig({data: '{{ _context|json_encode }}'}).render().should.equal("{}");
-```
-
-should support {% set %} tag.
-
-```js
-twig({data: '{% set value = "test" %}{{ _context.value }}'}).render().should.equal("test");
-```
-
-should work correctly with properties named dynamically.
-
-```js
-twig({data: '{{ _context[key] }}'}).render({
- key: "value",
- value: "test"
-}).should.equal("test");
-```
-
-should not allow to override context using {% set %}.
-
-```js
-twig({data: '{% set _context = "test" %}{{ _context|json_encode }}'}).render().should.equal('{"_context":"test"}');
-twig({data: '{% set _context = "test" %}{{ _context._context }}'}).render().should.equal("test");
-```
-
-should support autoescape option.
-
-```js
-twig({
- autoescape: true,
- data: '{{ value }}'
-}).render({
- value: "<test>&</test>"
-}).should.equal('&lt;test&gt;&amp;&lt;/test&gt;');
-```
-
-should support autoescape option with alternative strategy.
-
-```js
-twig({
- autoescape: 'js',
- data: '{{ value }}'
-}).render({
- value: "<test>&</test>"
-}).should.equal('\\x3Ctest\\x3E\\x26\\x3C\\x2Ftest\\x3E');
-```
-
-should autoescape parent() output correctly.
-
-```js
-twig({id: 'parent1', data: '{% block body %}<p>{{ value }}</p>{% endblock body %}'});
-twig({
- allowInlineIncludes: true,
- autoescape: true,
- data: '{% extends "parent1" %}{% block body %}{{ parent() }}{% endblock %}'
-}).render({
- value: "<test>&</test>"
-}).should.equal('<p>&lt;test&gt;&amp;&lt;/test&gt;</p>');
-```
-
-should use a correct context in the extended template.
-
-```js
-twig({id: 'parent', data: '{% block body %}{{ value }}{% endblock body %}'});
-twig({
- allowInlineIncludes: true,
- data: '{% extends "parent" %}{% set value = "test" %}{% block body %}{{ parent() }}{% endblock %}'
-}).render().should.equal("test");
-```
-
-should use a correct context in the included template.
-
-```js
-twig({id: 'included', data: '{{ value }}\n{% set value = "inc" %}{{ value }}\n'});
-twig({
- allowInlineIncludes: true,
- data: '{% set value = "test" %}{% for i in [0, 1] %}{% include "included" %}{% endfor %}{{ value }}'
-}).render().should.equal("test\ninc\ntest\ninc\ntest");
-```
-
-<a name="twigjs-embed--"></a>
-# Twig.js Embed ->
-it should load embed and render.
-
-```js
-twig({
- id: 'embed',
- path: 'test/templates/embed-simple.twig',
- async: false
-});
-// Load the template
-twig({ref: 'embed'}).render({ }).trim().should.equal( ['START',
- 'A',
- 'new header',
- 'base footer',
- 'B',
- '',
- 'A',
- 'base header',
- 'base footer',
- 'extended',
- 'B',
- '',
- 'A',
- 'base header',
- 'extended',
- 'base footer',
- 'extended',
- 'B',
- '',
- 'A',
- 'Super cool new header',
- 'Cool footer',
- 'B',
- 'END'].join('\n') );
-```
-
-<a name="twigjs-expressions--"></a>
-# Twig.js Expressions ->
-<a name="twigjs-expressions---basic-operators--"></a>
-## Basic Operators ->
-should parse parenthesis.
-
-```js
-var test_template = twig({data: '{{ a - (b + c) }}'}),
- d = {a: 10, b: 4, c: 2},
- output = test_template.render(d);
-output.should.equal( (d.a - (d.b + d.c)).toString() );
-```
-
-should parse nested parenthesis.
-
-```js
-var test_template = twig({data: '{{ a - ((b) + (1 + c)) }}'}),
- d = {a: 10, b: 4, c: 2},
- output = test_template.render(d);
-output.should.equal( (d.a - (d.b + 1 + d.c)).toString() );
-```
-
-should add numbers.
-
-```js
-var test_template = twig({data: '{{ a + b }}'});
-numeric_test_data.forEach(function(pair) {
- var output = test_template.render(pair);
- output.should.equal( (pair.a + pair.b).toString() );
-});
-```
-
-should subtract numbers.
-
-```js
-var test_template = twig({data: '{{ a - b }}'});
-numeric_test_data.forEach(function(pair) {
- var output = test_template.render(pair);
- output.should.equal( (pair.a - pair.b).toString() );
-});
-```
-
-should multiply numbers.
-
-```js
-var test_template = twig({data: '{{ a * b }}'});
-numeric_test_data.forEach(function(pair) {
- var output = test_template.render(pair);
- output.should.equal((pair.a * pair.b).toString() );
-});
-```
-
-should divide numbers.
-
-```js
-var test_template = twig({data: '{{ a / b }}'});
-numeric_test_data.forEach(function(pair) {
- var output = test_template.render(pair);
- output.should.equal((pair.a / pair.b).toString() );
-});
-```
-
-should divide numbers and return an int result.
-
-```js
-var test_template = twig({data: '{{ a // b }}'});
-numeric_test_data.forEach(function(pair) {
- var output = test_template.render(pair);
- // Get expected truncated result
- var c = parseInt(pair.a/pair.b);
- output.should.equal(c.toString() );
-});
-```
-
-should raise numbers to a power.
-
-```js
-var test_template = twig({data: '{{ a ** b }}'});
-var pow_test_data = [
- {a: 2, b:3, c: 8}
- , {a: 4, b:.5, c: 2}
- , {a: 5, b: 1, c: 5}
-];
-pow_test_data.forEach(function(pair) {
- var output = test_template.render(pair);
- output.should.equal(pair.c.toString() );
-});
-```
-
-should concatanate values.
-
-```js
-twig({data: '{{ "test" ~ a }}'}).render({a:1234}).should.equal("test1234");
-twig({data: '{{ a ~ "test" ~ a }}'}).render({a:1234}).should.equal("1234test1234");
-twig({data: '{{ "this" ~ "test" }}'}).render({a:1234}).should.equal("thistest");
-// Test numbers
-var test_template = twig({data: '{{ a ~ b }}'});
-numeric_test_data.forEach(function(pair) {
- var output = test_template.render(pair);
- output.should.equal(pair.a.toString() + pair.b.toString());
-});
-// Test strings
-test_template = twig({data: '{{ a ~ b }}'});
-string_data.forEach(function(pair) {
- var output = test_template.render(pair);
- output.should.equal(pair.a.toString() + pair.b.toString());
-});
-```
-
-should concatenate null and undefined values and not throw an exception.
-
-```js
-twig({data: '{{ a ~ b }}'}).render().should.equal("");
-twig({data: '{{ a ~ b }}'}).render({
- a: null,
- b: null
-}).should.equal("");
-```
-
-should handle multiple chained operations.
-
-```js
-var data = {a: 4.5, b: 10, c: 12, d: -0.25, e:0, f: 65, g: 21, h: -0.0002};
-var test_template = twig({data: '{{a/b+c*d-e+f/g*h}}'});
-var output = test_template.render(data);
-var expected = data.a / data.b + data.c * data.d - data.e + data.f / data.g * data.h;
-output.should.equal(expected.toString());
-```
-
-should handle parenthesis in chained operations.
-
-```js
-var data = {a: 4.5, b: 10, c: 12, d: -0.25, e:0, f: 65, g: 21, h: -0.0002};
-var test_template = twig({data: '{{a /(b+c )*d-(e+f)/(g*h)}}'});
-var output = test_template.render(data);
-var expected = data.a / (data.b + data.c) * data.d - (data.e + data.f) / (data.g * data.h);
-output.should.equal(expected.toString());
-```
-
-<a name="twigjs-expressions---comparison-operators--"></a>
-## Comparison Operators ->
-should support less then.
-
-```js
-var test_template = twig({data: '{{ a < b }}'});
-numeric_test_data.forEach(function(pair) {
- var output = test_template.render(pair);
- output.should.equal((pair.a < pair.b).toString() );
-});
-```
-
-should support less then or equal.
-
-```js
-var test_template = twig({data: '{{ a <= b }}'});
-numeric_test_data.forEach(function(pair) {
- var output = test_template.render(pair);
- output.should.equal((pair.a <= pair.b).toString() );
-});
-```
-
-should support greater then.
-
-```js
-var test_template = twig({data: '{{ a > b }}'});
-numeric_test_data.forEach(function(pair) {
- var output = test_template.render(pair);
- output.should.equal((pair.a > pair.b).toString() );
-});
-```
-
-should support greater then or equal.
-
-```js
-var test_template = twig({data: '{{ a >= b }}'});
-numeric_test_data.forEach(function(pair) {
- var output = test_template.render(pair);
- output.should.equal((pair.a >= pair.b).toString() );
-});
-```
-
-should support equals.
-
-```js
-var test_template = twig({data: '{{ a == b }}'});
-boolean_data.forEach(function(pair) {
- var output = test_template.render(pair);
- output.should.equal((pair.a == pair.b).toString() );
-});
-equality_data.forEach(function(pair) {
- var output = test_template.render(pair);
- output.should.equal((pair.a == pair.b).toString() );
-});
-```
-
-should support not equals.
-
-```js
-var test_template = twig({data: '{{ a != b }}'});
-boolean_data.forEach(function(pair) {
- var output = test_template.render(pair);
- output.should.equal((pair.a != pair.b).toString() );
-});
-equality_data.forEach(function(pair) {
- var output = test_template.render(pair);
- output.should.equal((pair.a != pair.b).toString() );
-});
-```
-
-should support boolean or.
-
-```js
-var test_template = twig({data: '{{ a or b }}'});
-boolean_data.forEach(function(pair) {
- var output = test_template.render(pair);
- output.should.equal((pair.a || pair.b).toString() );
-});
-```
-
-should support boolean and.
-
-```js
-var test_template = twig({data: '{{ a and b }}'});
-boolean_data.forEach(function(pair) {
- var output = test_template.render(pair);
- output.should.equal((pair.a && pair.b).toString() );
-});
-```
-
-should support boolean not.
-
-```js
-var test_template = twig({data: '{{ not a }}'});
-test_template.render({a:false}).should.equal(true.toString());
-test_template.render({a:true}).should.equal(false.toString());
-```
-
-<a name="twigjs-expressions---other-operators--"></a>
-## Other Operators ->
-should support the ternary operator.
-
-```js
-var test_template = twig({data: '{{ a ? b:c }}'})
- , output_t = test_template.render({a: true, b: "one", c: "two"})
- , output_f = test_template.render({a: false, b: "one", c: "two"});
-output_t.should.equal( "one" );
-output_f.should.equal( "two" );
-```
-
-should support the ternary operator with objects in it.
-
-```js
-var test_template2 = twig({data: '{{ (a ? {"a":e+f}:{"a":1}).a }}'})
- , output2 = test_template2.render({a: true, b: false, e: 1, f: 2});
-output2.should.equal( "3" );
-```
-
-should support the ternary operator inside objects.
-
-```js
-var test_template2 = twig({data: '{{ {"b" : a or b ? {"a":e+f}:{"a":1} }.b.a }}'})
- , output2 = test_template2.render({a: false, b: false, e: 1, f: 2});
-output2.should.equal( "1" );
-```
-
-should support in/containment functionality for arrays.
-
-```js
-var test_template = twig({data: '{{ "a" in ["a", "b", "c"] }}'});
-test_template.render().should.equal(true.toString());
-var test_template = twig({data: '{{ "d" in ["a", "b", "c"] }}'});
-test_template.render().should.equal(false.toString());
-```
-
-should support not in/containment functionality for arrays.
-
-```js
-var test_template = twig({data: '{{ "a" not in ["a", "b", "c"] }}'});
-test_template.render().should.equal(false.toString());
-var test_template = twig({data: '{{ "d" not in ["a", "b", "c"] }}'});
-test_template.render().should.equal(true.toString());
-```
-
-should support in/containment functionality for strings.
-
-```js
-var test_template = twig({data: '{{ "at" in "hat" }}'});
-test_template.render().should.equal(true.toString());
-var test_template = twig({data: '{{ "d" in "not" }}'});
-test_template.render().should.equal(false.toString());
-```
-
-should support not in/containment functionality for strings.
-
-```js
-var test_template = twig({data: '{{ "at" not in "hat" }}'});
-test_template.render().should.equal(false.toString());
-var test_template = twig({data: '{{ "d" not in "not" }}'});
-test_template.render().should.equal(true.toString());
-```
-
-should support in/containment functionality for objects.
-
-```js
-var test_template = twig({data: '{{ "value" in {"key" : "value", "2": "other"} }}'});
-test_template.render().should.equal(true.toString());
-var test_template = twig({data: '{{ "d" in {"key_a" : "no"} }}'});
-test_template.render().should.equal(false.toString());
-```
-
-should support not in/containment functionality for objects.
-
-```js
-var test_template = twig({data: '{{ "value" not in {"key" : "value", "2": "other"} }}'});
-test_template.render().should.equal(false.toString());
-var test_template = twig({data: '{{ "d" not in {"key_a" : "no"} }}'});
-test_template.render().should.equal(true.toString());
-```
-
-should support undefined and null for the in operator.
-
-```js
-var test_template = twig({data: '{{ 0 in undefined }} {{ 0 in null }}'});
-test_template.render().should.equal(' ');
-```
-
-should support expressions as object keys.
-
-```js
-var test_template;
-test_template = twig({data: '{% set a = {(foo): "value"} %}{{ a.bar }}'});
-test_template.render({foo: 'bar'}).should.equal('value');
-test_template = twig({data: '{{ {(foo): "value"}.bar }}'});
-test_template.render({foo: 'bar'}).should.equal('value');
-```
-
-<a name="twigjs-extensions--"></a>
-# Twig.js Extensions ->
-should be able to extend a meta-type tag.
-
-```js
-var flags = {};
- Twig.extend(function(Twig) {
- Twig.exports.extendTag({
- type: "flag",
- regex: /^flag\s+(.+)$/,
- next: [ ],
- open: true,
- compile: function (token) {
- var expression = token.match[1];
-
- // Compile the expression.
- token.stack = Twig.expression.compile.apply(this, [{
- type: Twig.expression.type.expression,
- value: expression
- }]).stack;
-
- delete token.match;
- return token;
- },
- parse: function (token, context, chain) {
- var name = Twig.expression.parse.apply(this, [token.stack, context]),
- output = '';
-
- flags[name] = true;
-
- return {
- chain: false,
- output: output
- };
- }
- });
- });
- var template = twig({data:"{% flag 'enabled' %}"}).render();
- flags.enabled.should.equal(true);
-```
-
-should be able to extend paired tags.
-
-```js
-// demo data
- var App = {
- user: "john",
- users: {
- john: {level: "admin"},
- tom: {level: "user"}
- }
- };
- Twig.extend(function(Twig) {
- // example of extending a tag type that would
- // restrict content to the specified "level"
- Twig.exports.extendTag({
- type: "auth",
- regex: /^auth\s+(.+)$/,
- next: ["endauth"], // match the type of the end tag
- open: true,
- compile: function (token) {
- var expression = token.match[1];
-
- // turn the string expression into tokens.
- token.stack = Twig.expression.compile.apply(this, [{
- type: Twig.expression.type.expression,
- value: expression
- }]).stack;
-
- delete token.match;
- return token;
- },
- parse: function (token, context, chain) {
- var level = Twig.expression.parse.apply(this, [token.stack, context]),
- output = "";
-
- if (App.users[App.currentUser].level == level)
- {
- output = Twig.parse.apply(this, [token.output, context]);
- }
-
- return {
- chain: chain,
- output: output
- };
- }
- });
- Twig.exports.extendTag({
- type: "endauth",
- regex: /^endauth$/,
- next: [ ],
- open: false
- });
- });
- var template = twig({data:"Welcome{% auth 'admin' %} ADMIN{% endauth %}!"});
-
- App.currentUser = "john";
- template.render().should.equal("Welcome ADMIN!");
-
- App.currentUser = "tom";
- template.render().should.equal("Welcome!");
-```
-
-should be able to extend the same tag twice, replacing it.
-
-```js
-var flags = {};
-Twig.extend(function(Twig) {
- Twig.exports.extendTag({
- type: "noop",
- regex: /^noop$/,
- next: [ ],
- open: true,
- parse: function (token, context, chain) {
- return {
- chain: false,
- output: "noop1"
- };
- }
- });
-});
-var result = twig({data:"{% noop %}"}).render();
-result.should.equal("noop1");
-Twig.extend(function(Twig) {
- Twig.exports.extendTag({
- type: "noop",
- regex: /^noop$/,
- next: [ ],
- open: true,
- parse: function (token, context, chain) {
- return {
- chain: false,
- output: "noop2"
- };
- }
- });
-});
-var result = twig({data:"{% noop %}"}).render();
-result.should.equal("noop2");
-```
-
-<a name="twigjs-filters--"></a>
-# Twig.js Filters ->
-should chain.
-
-```js
-var test_template = twig({data: '{{ ["a", "b", "c"]|keys|reverse }}' });
-test_template.render().should.equal("2,1,0");
-```
-
-<a name="twigjs-filters---url_encode--"></a>
-## url_encode ->
-should encode URLs.
-
-```js
-var test_template = twig({data: '{{ "http://google.com/?q=twig.js"|url_encode() }}' });
-test_template.render().should.equal("http%3A%2F%2Fgoogle.com%2F%3Fq%3Dtwig.js" );
-```
-
-should handle undefined.
-
-```js
-var test_template = twig({data: '{{ undef|url_encode() }}' });
-test_template.render().should.equal("" );
-```
-
-should handle special characters.
-
-```js
-var data = { "foo": "<foo> \\&\"'.,-_?/Ķä€台北[]{}\t\r\n\b\x80" };
-var test_template = twig({data: '{{ foo|url_encode() }}' });
-test_template.render(data).should.equal("%3Cfoo%3E%20%5C%26%22%27.%2C-_%3F%2F%C4%B6%C3%A4%E2%82%AC%E5%8F%B0%E5%8C%97%5B%5D%7B%7D%09%0D%0A%08%C2%80" );
-```
-
-<a name="twigjs-filters---json_encode--"></a>
-## json_encode ->
-should encode strings to json.
-
-```js
-var test_template = twig({data: '{{ test|json_encode }}' });
-test_template.render({test:'value'}).should.equal('"value"' );
-```
-
-should encode numbers to json.
-
-```js
-var test_template = twig({data: '{{ test|json_encode }}' });
-test_template.render({test:21}).should.equal('21' );
-```
-
-should encode arrays to json.
-
-```js
-var test_template = twig({data: '{{ [1,"b",3]|json_encode }}' });
-test_template.render().should.equal('[1,"b",3]' );
-```
-
-should encode objects to json.
-
-```js
-var test_template = twig({data: '{{ {"a":[1,"b",3]}|json_encode }}' });
-test_template.render().should.equal('{"a":[1,"b",3]}' );
-```
-
-should retain key order in an object.
-
-```js
-twig({data: '{{ { "foo": 1, "bar": 2, "baz": 3 }|json_encode }}'}).render().should.equal( '{"foo":1,"bar":2,"baz":3}' );
-```
-
-should not add additional information to objects.
-
-```js
-twig({data: '{{ { "foo": 1, "bar": [1, 2, 3], "baz": { "a": "a", "b": "b" } }|json_encode }}'}).render().should.equal( '{"foo":1,"bar":[1,2,3],"baz":{"a":"a","b":"b"}}' );
-```
-
-should handle undefined.
-
-```js
-var test_template = twig({data: '{{ undef|json_encode }}' });
-test_template.render().should.equal("null" );
-```
-
-<a name="twigjs-filters---upper--"></a>
-## upper ->
-should convert text to uppercase.
-
-```js
-var test_template = twig({data: '{{ "hello"|upper }}' });
-test_template.render().should.equal("HELLO" );
-```
-
-should handle undefined.
-
-```js
-var test_template = twig({data: '{{ undef|upper }}' });
-test_template.render().should.equal("" );
-```
-
-<a name="twigjs-filters---lower--"></a>
-## lower ->
-should convert text to lowercase.
-
-```js
-var test_template = twig({data: '{{ "HELLO"|lower }}' });
-test_template.render().should.equal("hello" );
-```
-
-should handle undefined.
-
-```js
-var test_template = twig({data: '{{ undef|lower }}' });
-test_template.render().should.equal("" );
-```
-
-<a name="twigjs-filters---capitalize--"></a>
-## capitalize ->
-should capitalize the first word in a string.
-
-```js
-var test_template = twig({data: '{{ "hello world"|capitalize }}' });
-test_template.render().should.equal("Hello world" );
-var test_template2 = twig({data: '{{ "HELLO WORLD"|capitalize }}' });
-test_template2.render().should.equal("Hello world" );
-```
-
-should handle undefined.
-
-```js
-var test_template = twig({data: '{{ undef|capitalize }}' });
-test_template.render().should.equal("" );
-```
-
-<a name="twigjs-filters---title--"></a>
-## title ->
-should capitalize all the words in a string.
-
-```js
-var test_template = twig({data: '{{ "hello world"|title }}' });
-test_template.render().should.equal("Hello World" );
-var test_template2 = twig({data: '{{ "HELLO WORLD"|title }}' });
-test_template2.render().should.equal("Hello World" );
-```
-
-should handle undefined.
-
-```js
-var test_template = twig({data: '{{ undef|title }}' });
-test_template.render().should.equal("" );
-```
-
-<a name="twigjs-filters---length--"></a>
-## length ->
-should determine the length of a string.
-
-```js
-var test_template = twig({data: '{{ "test"|length }}' });
-test_template.render().should.equal("4");
-```
-
-should determine the length of an array.
-
-```js
-var test_template = twig({data: '{{ [1,2,4,76,"tesrt"]|length }}' });
-test_template.render().should.equal("5");
-```
-
-should determine the length of an object.
-
-```js
-var test_template = twig({data: '{{ {"a": "b", "c": "1", "test": "test"}|length }}' });
-test_template.render().should.equal("3");
-```
-
-should handle undefined.
-
-```js
-var test_template = twig({data: '{{ undef|length }}' });
-test_template.render().should.equal("0" );
-```
-
-<a name="twigjs-filters---sort--"></a>
-## sort ->
-should sort an array.
-
-```js
-var test_template = twig({data: '{{ [1,5,2,7]|sort }}' });
-test_template.render().should.equal("1,2,5,7" );
-test_template = twig({data: '{{ ["test","abc",2,7]|sort }}' });
-test_template.render().should.equal("2,7,abc,test" );
-```
-
-should sort an object.
-
-```js
-var test_template = twig({data: "{% set obj = {'c': 1,'d': 5,'t': 2,'e':7}|sort %}{% for key,value in obj|sort %}{{key}}:{{value}} {%endfor %}" });
-test_template.render().should.equal("c:1 t:2 d:5 e:7 " );
-test_template = twig({data: "{% set obj = {'m':'test','z':'abc','a':2,'y':7} %}{% for key,value in obj|sort %}{{key}}:{{value}} {%endfor %}" });
-test_template.render().should.equal("a:2 y:7 z:abc m:test " );
-test_template = twig({data: "{% set obj = {'z':'abc','a':2,'y':7,'m':'test'} %}{% for key,value in obj|sort %}{{key}}:{{value}} {%endfor %}" });
-test_template.render().should.equal("a:2 y:7 z:abc m:test " );
-```
-
-should handle undefined.
-
-```js
-var test_template = twig({data: '{% set obj = undef|sort %}{% for key, value in obj|sort %}{{key}}:{{value}}{%endfor%}' });
-test_template.render().should.equal("" );
-```
-
-<a name="twigjs-filters---reverse--"></a>
-## reverse ->
-should reverse an array.
-
-```js
-var test_template = twig({data: '{{ ["a", "b", "c"]|reverse }}' });
-test_template.render().should.equal("c,b,a" );
-```
-
-should reverse an object.
-
-```js
-
-```
-
-should handle undefined.
-
-```js
-var test_template = twig({data: '{{ undef|reverse }}' });
-test_template.render().should.equal("" );
-```
-
-<a name="twigjs-filters---keys--"></a>
-## keys ->
-should return the keys of an array.
-
-```js
-var test_template = twig({data: '{{ ["a", "b", "c"]|keys }}' });
-test_template.render().should.equal("0,1,2" );
-```
-
-should return the keys of an object.
-
-```js
-var test_template = twig({data: '{{ {"a": 1, "b": 4, "c": 5}|keys }}' });
-test_template.render().should.equal("a,b,c" );
-test_template = twig({data: '{{ {"0":"a", "1":"b", "2":"c"}|keys }}' });
-test_template.render().should.equal("0,1,2" );
-```
-
-should handle undefined.
-
-```js
-var test_template = twig({data: '{{ undef|keys }}' });
-test_template.render().should.equal("" );
-```
-
-<a name="twigjs-filters---merge--"></a>
-## merge ->
-should merge two objects into an object.
-
-```js
-// Object merging
-var test_template = twig({data: '{% set obj= {"a":"test", "b":"1"}|merge({"b":2,"c":3}) %}{% for key in obj|keys|sort %}{{key}}:{{obj[key]}} {%endfor %}' });
-test_template.render().should.equal('a:test b:2 c:3 ' );
-```
-
-should merge two arrays into and array.
-
-```js
-// Array merging
-var test_template = twig({data: '{% set obj= ["a", "b"]|merge(["c", "d"]) %}{% for key in obj|keys|sort %}{{key}}:{{obj[key]}} {%endfor %}' });
-test_template.render().should.equal('0:a 1:b 2:c 3:d ' );
-```
-
-should merge an object and an array into an object.
-
-```js
-// Mixed merging
-var test_template = twig({data: '{% set obj= ["a", "b"]|merge({"a": "c", "3":4}, ["c", "d"]) %}{% for key in obj|keys|sort %}{{key}}:{{obj[key]}} {%endfor %}' });
-test_template.render().should.equal('0:a 1:b 3:4 4:c 5:d a:c ' );
-// Mixed merging(2)
-test_template = twig({data: '{% set obj= {"1":"a", "a":"b"}|merge(["c", "d"]) %}{% for key in obj|keys %}{{key}}:{{obj[key]}} {%endfor %}' });
-test_template.render().should.equal('1:a a:b 2:c 3:d ' );
-```
-
-<a name="twigjs-filters---join--"></a>
-## join ->
-should join all values in an object.
-
-```js
-var test_template = twig({data: '{{ {"a":"1", "b": "b", "c":test}|join("-") }}' });
-test_template.render({"test": "t"}).should.equal("1-b-t" );
-```
-
-should joing all values in an array.
-
-```js
-var test_template = twig({data: '{{ [1,2,4,76]|join }}' });
-test_template.render().should.equal("12476" );
-test_template = twig({data: '{{ [1+ 5,2,4,76]|join("-" ~ ".") }}' });
-test_template.render().should.equal("6-.2-.4-.76" );
-```
-
-should handle undefined.
-
-```js
-var test_template = twig({data: '{{ undef|join }}' });
-test_template.render().should.equal("" );
-```
-
-<a name="twigjs-filters---default--"></a>
-## default ->
-should not provide the default value if a key is defined and not empty.
-
-```js
-var test_template = twig({data: '{{ var|default("Not Defined") }}' });
-test_template.render({"var":"value"}).should.equal("value" );
-```
-
-should provide a default value if a key is not defined.
-
-```js
-var test_template = twig({data: '{{ var|default("Not Defined") }}' });
-test_template.render().should.equal("Not Defined" );
-```
-
-should provide a default value if a value is empty.
-
-```js
-var test_template = twig({data: '{{ ""|default("Empty String") }}' });
-test_template.render().should.equal("Empty String" );
-test_template = twig({data: '{{ var.key|default("Empty Key") }}' });
-test_template.render({'var':{}}).should.equal("Empty Key" );
-```
-
-should provide a default value of '' if no parameters are passed and a default key is not defined.
-
-```js
-var test_template = twig({data: '{{ var|default }}' });
-test_template.render().should.equal("");
-```
-
-should provide a default value of '' if no parameters are passed and a value is empty.
-
-```js
-var test_template = twig({data: '{{ ""|default }}' });
-test_template.render().should.equal("");
-test_template = twig({data: '{{ var.key|default }}' });
-test_template.render({'var':{}}).should.equal("");
-```
-
-<a name="twigjs-filters---date--"></a>
-## date ->
-should recognize timestamps.
-
-```js
-var template = twig({data: '{{ 27571323556|date("d/m/Y @ H:i:s") }}'})
- , date = new Date(27571323556000); // 13/09/2843 @ 08:59:16 EST
-template.render().should.equal( stringDate(date) );
-```
-
-should recognize timestamps, when they are passed as string.
-
-```js
-var template = twig({data: '{{ "27571323556"|date("d/m/Y @ H:i:s") }}'})
- , date = new Date(27571323556000); // 13/09/2843 @ 08:59:16 EST
-template.render().should.equal( stringDate(date) );
-```
-
-should recognize string date formats.
-
-```js
-var template = twig({data: '{{ "Tue Aug 14 08:52:15 +0000 2007"|date("d/m/Y @ H:i:s") }}'})
- , date = new Date(1187081535000); // 14/08/2007 @ 04:52:15 EST
-template.render().should.equal( stringDate(date) );
-```
-
-should handle undefined.
-
-```js
-var test_template = twig({data: '{{ undef|date("d/m/Y @ H:i:s") }}' });
-var date = new Date();
-test_template.render().should.equal(stringDate(date));
-```
-
-should work with no parameters.
-
-```js
-var test_template = twig({data: '{{ 27571323556|date }}' });
-test_template.render().should.equal(twig({data: '{{ 27571323556|date("F j, Y H:i") }}'}).render());
-```
-
-<a name="twigjs-filters---replace--"></a>
-## replace ->
-should replace strings provided in a map.
-
-```js
-var template = twig({data: '{{ "I like %this% and %that%. Seriously, I like %this% and %that%."|replace({"%this%": foo, "%that%": "bar"}) }}'});
-template.render({foo: "foo"}).should.equal("I like foo and bar. Seriously, I like foo and bar." );
-```
-
-should handle undefined.
-
-```js
-var test_template = twig({data: '{{ undef|replace }}' });
-test_template.render().should.equal("" );
-```
-
-<a name="twigjs-filters---format--"></a>
-## format ->
-should replace formatting tags with parameters.
-
-```js
-var template = twig({data: '{{ "I like %s and %s."|format(foo, "bar") }}'});
-template.render({foo: "foo"}).should.equal("I like foo and bar." );
-```
-
-should handle undefined.
-
-```js
-var test_template = twig({data: '{{ undef|format }}' });
-test_template.render().should.equal("" );
-```
-
-should handle positive leading sign without padding.
-
-```js
-var template = twig({data: '{{ "I like positive numbers like %+d."|format(123) }}'});
-template.render({foo: "foo"}).should.equal("I like positive numbers like +123." );
-```
-
-should handle negative leading sign without padding.
-
-```js
-var template = twig({data: '{{ "I like negative numbers like %+d."|format(-123) }}'});
-template.render({foo: "foo"}).should.equal("I like negative numbers like -123." );
-```
-
-should handle positive leading sign with padding zero.
-
-```js
-var template = twig({data: '{{ "I like positive numbers like %+05d."|format(123) }}'});
-template.render({foo: "foo"}).should.equal("I like positive numbers like +0123." );
-```
-
-should handle negative leading sign with padding zero.
-
-```js
-var template = twig({data: '{{ "I like negative numbers like %+05d."|format(-123) }}'});
-template.render({foo: "foo"}).should.equal("I like negative numbers like -0123." );
-```
-
-should handle positive leading sign with padding space.
-
-```js
-var template = twig({data: '{{ "I like positive numbers like %+5d."|format(123) }}'});
-template.render({foo: "foo"}).should.equal("I like positive numbers like +123." );
-```
-
-should handle negative leading sign with padding space.
-
-```js
-var template = twig({data: '{{ "I like negative numbers like %+5d."|format(-123) }}'});
-template.render({foo: "foo"}).should.equal("I like negative numbers like -123." );
-```
-
-<a name="twigjs-filters---striptags--"></a>
-## striptags ->
-should remove tags from a value.
-
-```js
-var template = twig({data: '{{ "<p>Test paragraph.</p><!-- Comment --> <a href=\\"#fragment\\">Other text</a>"|striptags }}'});
-template.render().should.equal("Test paragraph. Other text" );
-```
-
-should handle undefined.
-
-```js
-var test_template = twig({data: '{{ undef|striptags }}' });
-test_template.render().should.equal("" );
-```
-
-<a name="twigjs-filters---escape--"></a>
-## escape ->
-should convert unsafe characters to HTML entities.
-
-```js
-var template = twig({data: '{{ "<p>Test paragraph.</p><!-- Comment --> <a href=\'#fragment\'>Other text</a>"|escape }}'});
-template.render().should.equal("&lt;p&gt;Test paragraph.&lt;/p&gt;&lt;!-- Comment --&gt; &lt;a href=&#039;#fragment\&#039;&gt;Other text&lt;/a&gt;" );
-```
-
-should handle undefined.
-
-```js
-var test_template = twig({data: '{{ undef|escape }}' });
-test_template.render().should.equal("" );
-```
-
-should not escape twice if autoescape is on.
-
-```js
-twig({
- autoescape: true,
- data: '{{ value|escape }}'
-}).render({
- value: "<test>&</test>"
-}).should.equal('&lt;test&gt;&amp;&lt;/test&gt;');
-```
-
-should handle the strategy parameter.
-
-```js
-var data = { "foo": "<foo> \\&\"'.,-_?/Ķä€台北[]{}\t\r\n\b\x80" };
-var test_template = twig({data: 'Default: {{ foo|escape }}' });
-test_template.render(data).should.equal("Default: &lt;foo&gt; \\&amp;&quot;&#039;.,-_?/Ķä€台北[]{}\t\r\n\b\x80" );
-var test_template = twig({data: 'html: {{ foo|escape("html") }}' });
-test_template.render(data).should.equal("html: &lt;foo&gt; \\&amp;&quot;&#039;.,-_?/Ķä€台北[]{}\t\r\n\b\x80" );
-var test_template = twig({data: 'js: {{ foo|escape("js") }}' });
-test_template.render(data).should.equal("js: \\x3Cfoo\\x3E\\x20\\x5C\\x26\\x22\\x27.,\\x2D_\\x3F\\x2F\\u0136\\u00E4\\u20AC\\u53F0\\u5317\\x5B\\x5D\\x7B\\x7D\\x9\\xD\\xA\\x8\\u0080" );
-var test_template = twig({data: 'css: {{ foo|escape("css") }}' });
-test_template.render(data).should.equal("css: \\3C foo\\3E \\20 \\5C \\26 \\22 \\27 \\2E \\2C \\2D \\5F \\3F \\2F \\136 \\E4 \\20AC \\53F0 \\5317 \\5B \\5D \\7B \\7D \\9 \\D \\A \\8 \\80 " );
-var test_template = twig({data: 'url: {{ foo|escape("url") }}' });
-test_template.render(data).should.equal("url: %3Cfoo%3E%20%5C%26%22%27.%2C-_%3F%2F%C4%B6%C3%A4%E2%82%AC%E5%8F%B0%E5%8C%97%5B%5D%7B%7D%09%0D%0A%08%C2%80" );
-var test_template = twig({data: 'html_attr: {{ foo|escape("html_attr") }}' });
-test_template.render(data).should.equal("html_attr: &lt;foo&gt;&#x20;&#x5C;&amp;&quot;&#x27;.,-_&#x3F;&#x2F;&#x0136;&#x00E4;&#x20AC;&#x53F0;&#x5317;&#x5B;&#x5D;&#x7B;&#x7D;&#x09;&#x0D;&#x0A;&#xFFFD;&#x0080;" );
-```
-
-should escape strategy != 'html' if autoescape is on.
-
-```js
-twig({
- autoescape: true,
- data: '{{ value|escape("js") }}'
-}).render({
- value: "<test>&</test>"
-}).should.equal('\\x3Ctest\\x3E\\x26\\x3C\\x2Ftest\\x3E');
-```
-
-should not escape twice if autoescape is not html.
-
-```js
-twig({
- autoescape: 'js',
- data: '{{ value|escape("js") }}'
-}).render({
- value: "<test>&</test>"
-}).should.equal('\\x3Ctest\\x3E\\x26\\x3C\\x2Ftest\\x3E');
-```
-
-should escape twice if escape strategy is different from autoescape option.
-
-```js
-twig({
- autoescape: 'css',
- data: '{{ value|escape("js") }}\n{{ value|escape }}'
-}).render({
- value: "<test>&</test>"
-}).should.equal('\\5C x3Ctest\\5C x3E\\5C x26\\5C x3C\\5C x2Ftest\\5C x3E\n\\26 lt\\3B test\\26 gt\\3B \\26 amp\\3B \\26 lt\\3B \\2F test\\26 gt\\3B ');
-```
-
-<a name="twigjs-filters---e--"></a>
-## e ->
-should alias escape function with e.
-
-```js
-var template = twig({data: '{{ "<p>Test paragraph.</p><!-- Comment --> <a href=\'#fragment\'>Other text</a>"|e }}'});
-template.render().should.equal("&lt;p&gt;Test paragraph.&lt;/p&gt;&lt;!-- Comment --&gt; &lt;a href=&#039;#fragment\&#039;&gt;Other text&lt;/a&gt;" );
-```
-
-should handle undefined.
-
-```js
-var test_template = twig({data: '{{ undef|e }}' });
-test_template.render().should.equal("" );
-```
-
-should not escape twice if autoescape is on.
-
-```js
-var template = twig({
- autoescape: true,
- data: '{{ value|e }}'
-});
-template.render({
- value: "<test>&</test>"
-}).should.equal('&lt;test&gt;&amp;&lt;/test&gt;');
-```
-
-<a name="twigjs-filters---nl2br--"></a>
-## nl2br ->
-should convert newlines into html breaks.
-
-```js
-var template = twig({data: '{{ test|nl2br }}'});
-template.render({ test: 'Line 1\r\nLine 2\nLine 3\rLine 4\n\n' })
- .should.equal("Line 1<br />\nLine 2<br />\nLine 3<br />\nLine 4<br />\n<br />\n");
-```
-
-should handle undefined.
-
-```js
-var test_template = twig({data: '{{ undef|nl2br }}' });
-test_template.render().should.equal("" );
-```
-
-should not escape br tags if autoescape is on.
-
-```js
-twig({
- autoescape: true,
- data: '{{ test|nl2br }}'
-}).render({
- test: '<test>Line 1\nLine2</test>'
-}).should.equal("&lt;test&gt;Line 1<br />\nLine2&lt;/test&gt;");
-```
-
-<a name="twigjs-filters---truncate--"></a>
-## truncate ->
-should truncate string to default size(20) and add default separator.
-
-```js
-var template = twig({data: '{{ test|truncate }}'});
-template.render({test: '01234567890123456789012345678901234567890123456789'}).should.equal("012345678901234567890123456789...");
-```
-
-should truncate string to custom size(10) and add default separator.
-
-```js
-var template = twig({data: '{{ test|truncate(10) }}'});
-template.render({test: '01234567890123456789012345678901234567890123456789'}).should.equal("0123456789...");
-```
-
-should truncate string to custom size(15) with preserve and add default separator.
-
-```js
-var template = twig({data: '{{ test|truncate(15, true) }}'});
-template.render({test: '0123456789 0123456789 0123456789 0123456789 0123456789'}).should.equal("0123456789 0123456789...");
-```
-
-should truncate string to custom size(15) with preserve and add custom(*) separator.
-
-```js
-var template = twig({data: '{{ test|truncate(15, true, "*") }}'});
-template.render({test: '0123456789 0123456789 0123456789 0123456789 0123456789'}).should.equal("0123456789 0123456789*");
-```
-
-<a name="twigjs-filters---trim--"></a>
-## trim ->
-should trim whitespace from strings.
-
-```js
-var template = twig({data: '{{ test|trim }}'});
-template.render({ test: '\r\n Test\n ' }).should.equal("Test");
-```
-
-should handle undefined.
-
-```js
-var test_template = twig({data: '{{ undef|trim }}' });
-test_template.render().should.equal("" );
-```
-
-<a name="twigjs-filters---number_format--"></a>
-## number_format ->
-should round to nearest integer if no parameters.
-
-```js
-var template = twig({data: '{{ 1234.56|number_format }}'});
-template.render().should.equal("1,235");
-```
-
-should have customizable precision.
-
-```js
-var template = twig({data: '{{ 1234.567890123|number_format(4) }}'});
-template.render().should.equal("1,234.5679");
-```
-
-should have a customizable decimal seperator.
-
-```js
-var template = twig({data: '{{ 1234.567890123|number_format(2,",") }}'});
-template.render().should.equal("1,234,57");
-```
-
-should have a customizable thousands seperator.
-
-```js
-var template = twig({data: '{{ 1234.5678|number_format(2,","," ") }}'});
-template.render().should.equal("1 234,57");
-```
-
-should handle blank seperators.
-
-```js
-var template = twig({data: '{{ 1234.5678|number_format(2,"","") }}'});
-template.render().should.equal("123457");
-```
-
-should handle undefined.
-
-```js
-var test_template = twig({data: '{{ undef|number_format }}' });
-test_template.render().should.equal("0");
-```
-
-<a name="twigjs-filters---slice--"></a>
-## slice ->
-should slice a string.
-
-```js
-var test_template = twig({data: "{{ '12345'|slice(1, 2) }}" });
-test_template.render().should.equal("23");
-```
-
-should slice a string to the end.
-
-```js
-var test_template = twig({data: "{{ '12345'|slice(2) }}" });
-test_template.render().should.equal("345");
-```
-
-should slice a string from the start.
-
-```js
-var test_template = twig({data: "{{ '12345'|slice(null, 2) }}" });
-test_template.render().should.equal("12");
-```
-
-should slice a string from a negative offset.
-
-```js
-var test_template = twig({data: "{{ '12345'|slice(-2, 1) }}" });
-test_template.render().should.equal("4");
-```
-
-should slice a string from a negative offset to end of string.
-
-```js
-var test_template = twig({data: "{{ '12345'|slice(-2) }}" });
-test_template.render().should.equal("45");
-```
-
-should slice an array.
-
-```js
-var test_template = twig({data: "{{ [1, 2, 3, 4, 5]|slice(1, 2)|join(',') }}" });
-test_template.render().should.equal("2,3");
-```
-
-should slice an array to the end.
-
-```js
-var test_template = twig({data: "{{ [1, 2, 3, 4, 5]|slice(2)|join(',') }}" });
-test_template.render().should.equal("3,4,5");
-```
-
-should slice an array from the start.
-
-```js
-var test_template = twig({data: "{{ [1, 2, 3, 4, 5]|slice(null, 2)|join(',') }}" });
-test_template.render().should.equal("1,2");
-```
-
-should slice an array from a negative offset.
-
-```js
-var test_template = twig({data: "{{ [1, 2, 3, 4, 5]|slice(-2, 1)|join(',') }}" });
-test_template.render().should.equal("4");
-```
-
-should slice an array from a negative offset to the end of the array.
-
-```js
-var test_template = twig({data: "{{ [1, 2, 3, 4, 5]|slice(-4)|join(',') }}" });
-test_template.render().should.equal("2,3,4,5");
-```
-
-<a name="twigjs-filters---abs--"></a>
-## abs ->
-should convert negative numbers to its absolute value.
-
-```js
-var test_template = twig({data: "{{ '-7.365'|abs }}"});
-test_template.render().should.equal("7.365");
-```
-
-should not alter absolute numbers.
-
-```js
-var test_template = twig({data: "{{ 95|abs }}"});
-test_template.render().should.equal("95");
-```
-
-<a name="twigjs-filters---first--"></a>
-## first ->
-should return first item in array.
-
-```js
-var test_template = twig({data: "{{ ['a', 'b', 'c', 'd']|first }}"});
-test_template.render().should.equal("a");
-```
-
-should return first member of object.
-
-```js
-var test_template = twig({data: "{{ { item1: 'a', item2: 'b', item3: 'c', item4: 'd'}|first }}"});
-test_template.render().should.equal("a");
-```
-
-should not fail when passed empty obj, arr or str.
-
-```js
-var test_template = twig({data: "{{ {}|first }}"});
-test_template.render().should.equal("");
-var test_template = twig({data: "{{ []|first }}"});
-test_template.render().should.equal("");
-var test_template = twig({data: "{{ myemptystr|first }}"});
-test_template.render({myemptystr: ""}).should.equal("");
-```
-
-should return first character in string.
-
-```js
-var test_template = twig({data: "{{ 'abcde'|first }}"});
-test_template.render().should.equal("a");
-```
-
-<a name="twigjs-filters---split--"></a>
-## split ->
-should split string with a separator.
-
-```js
-var test_template = twig({data: "{{ 'one-two-three'|split('-') }}"});
-test_template.render().should.equal("one,two,three");
-```
-
-should split string with a separator and positive limit.
-
-```js
-var test_template = twig({data: "{{ 'one-two-three-four-five'|split('-', 3) }}"});
-test_template.render().should.equal("one,two,three-four-five");
-```
-
-should split string with a separator and negative limit.
-
-```js
-var test_template = twig({data: "{{ 'one-two-three-four-five'|split('-', -2) }}"});
-test_template.render().should.equal("one,two,three");
-```
-
-should split with empty separator.
-
-```js
-var test_template = twig({data: "{{ '123'|split('') }}"});
-test_template.render().should.equal("1,2,3");
-```
-
-should split with empty separator and limit.
-
-```js
-var test_template = twig({data: "{{ 'aabbcc'|split('', 2) }}"});
-test_template.render().should.equal("aa,bb,cc");
-```
-
-<a name="twigjs-filters---batch--"></a>
-## batch ->
-should work with arrays that require filling (with fill specified).
-
-```js
-var test_template = twig({data: "{{ ['a', 'b', 'c', 'd', 'e', 'f', 'g']|batch(3, 'x') }}"});
-test_template.render().should.equal("a,b,c,d,e,f,g,x,x");
-```
-
-should work with arrays that require filling (without fill specified).
-
-```js
-var test_template = twig({data: "{{ ['a', 'b', 'c', 'd', 'e', 'f', 'g']|batch(3) }}"});
-test_template.render().should.equal("a,b,c,d,e,f,g");
-```
-
-should work with arrays that do not require filling (with fill specified).
-
-```js
-var test_template = twig({data: "{{ ['a', 'b', 'c', 'd', 'e', 'f']|batch(3, 'x') }}"});
-test_template.render().should.equal("a,b,c,d,e,f");
-```
-
-should work with arrays that do not require filling (without fill specified).
-
-```js
-var test_template = twig({data: "{{ ['a', 'b', 'c', 'd', 'e', 'f']|batch(3) }}"});
-test_template.render().should.equal("a,b,c,d,e,f");
-```
-
-should return an empty result for an empty array.
-
-```js
-var test_template = twig({data: "{{ []|batch(3, 'x') }}"});
-test_template.render().should.equal("");
-```
-
-<a name="twigjs-filters---last--"></a>
-## last ->
-should return last character in string.
-
-```js
-var test_template = twig({data: "{{ 'abcd'|last }}"});
-test_template.render().should.equal("d");
-```
-
-should return last item in array.
-
-```js
-var test_template = twig({data: "{{ ['a', 'b', 'c', 'd']|last }}"});
-test_template.render().should.equal("d");
-```
-
-should return last item in a sorted object.
-
-```js
-var test_template = twig({data: "{{ {'m':1, 'z':5, 'a':3}|sort|last }}" });
-test_template.render().should.equal("5");
-```
-
-<a name="twigjs-filters---raw--"></a>
-## raw ->
-should output the raw value if autoescape is on.
-
-```js
-var template = twig({
- autoescape: true,
- data: '{{ value|raw }}'
-});
-template.render({
- value: "<test>&</test>"
-}).should.equal('<test>&</test>');
-```
-
-should output the raw value if autoescape is off.
-
-```js
-var template = twig({
- autoescape: false,
- data: '{{ value|raw }}'
-});
-template.render({
- value: "<test>&</test>"
-}).should.equal('<test>&</test>');
-```
-
-<a name="twigjs-filters---round--"></a>
-## round ->
-should round up (common).
-
-```js
-var test_template = twig({data: "{{ 2.7|round }}"});
-test_template.render().should.equal("3");
-```
-
-should round down (common).
-
-```js
-var test_template = twig({data: "{{ 2.1|round }}"});
-test_template.render().should.equal("2");
-```
-
-should truncate input when input decimal places exceeds precision (floor).
-
-```js
-var test_template = twig({data: "{{ 2.1234|round(3, 'floor') }}" });
-test_template.render().should.equal("2.123");
-```
-
-should round up (ceil).
-
-```js
-var test_template = twig({data: "{{ 2.1|round(0, 'ceil') }}" });
-test_template.render().should.equal("3");
-```
-
-should truncate precision when a negative precision is passed (common).
-
-```js
-var test_template = twig({data: "{{ 21.3|round(-1)}}" });
-test_template.render().should.equal("20");
-```
-
-should round up and truncate precision when a negative precision is passed (ceil).
-
-```js
-var test_template = twig({data: "{{ 21.3|round(-1, 'ceil')}}" });
-test_template.render().should.equal("30");
-```
-
-should round down and truncate precision when a negative precision is passed (floor).
-
-```js
-var test_template = twig({data: "{{ 21.3|round(-1, 'ceil')}}" });
-test_template.render().should.equal("30");
-```
-
-<a name="twigjs-loader--"></a>
-# Twig.js Loader ->
-should load a template from the filesystem asynchronously.
-
-```js
-twig({
- id: 'fs-node-async',
- path: 'test/templates/test.twig',
- load: function(template) {
- // Render the template
- template.render({
- test: "yes",
- flag: true
- }).should.equal("Test template = yes\n\nFlag set!");
- done();
- }
-});
-```
-
-should load a template from the filesystem synchronously.
-
-```js
-var template = twig({
- id: 'fs-node-sync',
- path: 'test/templates/test.twig',
- async: false
-});
-// Render the template
-template.render({
- test: "yes",
- flag: true
-}).should.equal("Test template = yes\n\nFlag set!");
-```
-
-<a name="twigjs-loader---source--"></a>
-## source ->
-should load the non-compiled template source code.
-
-```js
-twig({data: '{{ source("test/templates/source.twig") }}'})
- .render()
- .should
- .equal('{% if isUserNew == true %}\n Hello {{ name }}\n{% else %}\n Welcome back {{ name }}\n{% endif %}\n')
-;
-```
-
-should indicate if there was a problem loading the template if 'ignore_missing' is false.
-
-```js
-twig({data: '{{ source("test/templates/non-existing-source.twig", false) }}'})
- .render()
- .should
- .equal('Template "test/templates/non-existing-source.twig" is not defined.')
-;
-```
-
-should NOT indicate if there was a problem loading the template if 'ignore_missing' is true.
-
-```js
-twig({data: '{{ source("test/templates/non-existing-source.twig", true) }}'})
- .render()
- .should
- .equal('')
-;
-```
-
-<a name="twigjs-include--"></a>
-# Twig.js Include ->
-should load an included template with no context.
-
-```js
-twig({
- id: 'include',
- path: 'test/templates/include.twig',
- async: false
-});
-// Load the template
-twig({ref: 'include'}).render({test: 'tst'}).should.equal( "BeforeTest template = tst\n\nAfter" );
-```
-
-should load an included template with additional context.
-
-```js
-twig({
- id: 'include-with',
- path: 'test/templates/include-with.twig',
- async: false
-});
-// Load the template
-twig({ref: 'include-with'}).render({test: 'tst'}).should.equal( "template: before,tst-mid-template: after,tst" );
-```
-
-should load an included template with only additional context.
-
-```js
-twig({
- id: 'include-only',
- path: 'test/templates/include-only.twig',
- async: false
-});
-// Load the template
-twig({ref: 'include-only'}).render({test: 'tst'}).should.equal( "template: before,-mid-template: after," );
-```
-
-<a name="twigjs-functions--"></a>
-# Twig.js Functions ->
-should allow you to define a function.
-
-```js
-twig({data: '{{ square(a) }}'}).render({a:4}).should.equal("16");
-```
-
-should chain with other expressions.
-
-```js
-twig({data: '{{ square(a) + 4 }}'}).render({a:4}).should.equal("20");
-```
-
-should chain with filters.
-
-```js
-twig({data: '{{ echo(a)|default("foo") }}'}).render().should.equal("foo");
-```
-
-should work in for loop expressions.
-
-```js
-twig({data: '{% for i in list(1, 2, 3) %}{{ i }},{% endfor %}'}).render().should.equal("1,2,3,");
-```
-
-should be able to differentiate between a function and a variable.
-
-```js
-twig({data: '{{ square ( square ) + square }}'}).render({square: 2}).should.equal("6");
-```
-
-should work with boolean operations.
-
-```js
-twig({data: '{% if echo(true) or echo(false) %}yes{% endif %}'}).render().should.equal("yes");
-```
-
-should execute functions passed as context values.
-
-```js
-twig({
- data: '{{ value }}'
-}).render({
- value: function() {
- return "test";
- }
-}).should.equal("test");
-```
-
-should execute functions passed as context values with this mapped to the context.
-
-```js
-twig({
- data: '{{ value }}'
-}).render({
- test: "value",
- value: function() {
- return this.test;
- }
-}).should.equal("value");
-```
-
-should execute functions passed as context values with arguments.
-
-```js
-twig({
- data: '{{ value(1, "test") }}'
-}).render({
- value: function(a, b, c) {
- return a + "-" + b + "-" + (c===undefined?"true":"false");
- }
-}).should.equal("1-test-true");
-```
-
-should execute functions passed as context value parameters with this mapped to the context.
-
-```js
-twig({
- data: '{{ value }}'
-}).render({
- test: "value",
- value: function() {
- return this.test;
- }
-}).should.equal("value");
-```
-
-should execute functions passed as context object parameters.
-
-```js
-twig({
- data: '{{ obj.value }}'
-}).render({
- obj: {
- value: function() {
- return "test";
- }
- }
-}).should.equal("test");
-```
-
-should execute functions passed as context object parameters with arguments.
-
-```js
-twig({
- data: '{{ obj.value(1, "test") }}'
-}).render({
- obj: {
- value: function(a, b, c) {
- return a + "-" + b + "-" + (c===undefined?"true":"false");
- }
- }
-}).should.equal("1-test-true");
-```
-
-should execute functions passed as context object parameters.
-
-```js
-twig({
- data: '{{ obj["value"] }}'
-}).render({
- obj: {
- value: function() {
- return "test";
- }
- }
-}).should.equal("test");
-```
-
-should execute functions passed as context object parameters with arguments.
-
-```js
-twig({
- data: '{{ obj["value"](1, "test") }}'
-}).render({
- obj: {
- value: function(a, b, c) {
- return a + "-" + b + "-" + (c===undefined?"true":"false");
- }
- }
-}).should.equal("1-test-true");
-```
-
-<a name="twigjs-functions---built-in-functions--"></a>
-## Built-in Functions ->
-<a name="twigjs-functions---built-in-functions---range--"></a>
-### range ->
-should work over a range of numbers.
-
-```js
-twig({data: '{% for i in range(0, 3) %}{{ i }},{% endfor %}'}).render().should.equal("0,1,2,3,");
-```
-
-should work over a range of letters.
-
-```js
-twig({data: '{% for i in range("a", "c") %}{{ i }},{% endfor %}'}).render().should.equal("a,b,c,");
-```
-
-should work with an interval.
-
-```js
-twig({data: '{% for i in range(1, 15, 3) %}{{ i }},{% endfor %}'}).render().should.equal("1,4,7,10,13,");
-```
-
-should work with .. invocation.
-
-```js
-twig({data: '{% for i in 0..3 %}{{ i }},{% endfor %}'}).render().should.equal("0,1,2,3,");
-twig({data: '{% for i in "a" .. "c" %}{{ i }},{% endfor %}'}).render().should.equal("a,b,c,");
-```
-
-<a name="twigjs-functions---built-in-functions---cycle--"></a>
-### cycle ->
-should cycle through an array of values.
-
-```js
-twig({data: '{% for i in range(0, 3) %}{{ cycle(["odd", "even"], i) }};{% endfor %}'}).render().should.equal("odd;even;odd;even;");
-```
-
-<a name="twigjs-functions---built-in-functions---date--"></a>
-### date ->
-should understand timestamps.
-
-```js
-var date = new Date(946706400 * 1000);
-twig({data: '{{ date(946706400)|date("d/m/Y @ H:i:s") }}'}).render().should.equal(stringDate(date));
-```
-
-should understand relative dates.
-
-```js
-twig({data: '{{ date("+1 day") > date() }}'}).render().should.equal("true");
-twig({data: '{{ date("-1 day") > date() }}'}).render().should.equal("false");
-```
-
-should support 'now' as a date parameter.
-
-```js
-twig({data: '{{ date("now") }}' }).render().should.equal(new Date().toString());
-```
-
-should understand exact dates.
-
-```js
-var date = new Date("June 20, 2010 UTC");
-
-twig({data: '{{ date("June 20, 2010 UTC")|date("d/m/Y @ H:i:s") }}'}).render().should.equal(stringDate(date));
-```
-
-<a name="twigjs-functions---built-in-functions---dump--"></a>
-### dump ->
-should output formatted number.
-
-```js
-twig({data: '{{ dump(test) }}' }).render({ test: 5 }).should.equal('number(5)' + EOL);
-```
-
-should output formatted string.
-
-```js
-twig({data: '{{ dump(test) }}' }).render({ test: "String" }).should.equal('string(6) "String"' + EOL);
-```
-
-should output formatted boolean.
-
-```js
-twig({data: '{{ dump(test) }}' }).render({ test: true }).should.equal('bool(true)' + EOL);
-```
-
-should output formatted null.
-
-```js
-twig({data: '{{ dump(test) }}' }).render({ test: null }).should.equal('NULL' + EOL);
-```
-
-should output formatted object.
-
-```js
-twig({data: '{{ dump(test) }}' }).render({ test: {} }).should.equal('object(0) {' + EOL + '}' + EOL);
-```
-
-should output formatted array.
-
-```js
-twig({data: '{{ dump(test) }}' }).render({ test: [] }).should.equal('object(0) {' + EOL + '}' + EOL);
-```
-
-should output formatted undefined.
-
-```js
-twig({data: '{{ dump(test) }}' }).render({ test: undefined }).should.equal('undefined' + EOL);
-```
-
-<a name="twigjs-functions---built-in-functions---block--"></a>
-### block ->
-should render the content of blocks.
-
-```js
-twig({data: '{% block title %}Content - {{ val }}{% endblock %} Title: {{ block("title") }}'}).render({ val: "test" })
- .should.equal("Content - test Title: Content - test");
-```
-
-shouldn't escape the content of blocks twice.
-
-```js
-twig({
- autoescape: true,
- data: '{% block test %}{{ val }}{% endblock %} {{ block("test") }}'
-}).render({
- val: "te&st"
-}).should.equal("te&amp;st te&amp;st");
-```
-
-<a name="twigjs-functions---built-in-functions---attribute--"></a>
-### attribute ->
-should access attribute of an object.
-
-```js
-twig({data: '{{ attribute(obj, key) }}' }).render({
- obj: { name: "Twig.js"},
- key: "name"
-})
-.should.equal("Twig.js");
-```
-
-should call function of attribute of an object.
-
-```js
-twig({data: '{{ attribute(obj, key, params) }}' }).render({
- obj: {
- name: function(first, last) {
- return first+'.'+last;
- }
- },
- key: "name",
- params: ['Twig', 'js']
- })
- .should.equal("Twig.js");
-```
-
-should return undefined for missing attribute of an object.
-
-```js
-twig({data: '{{ attribute(obj, key, params) }}' }).render({
- obj: {
- name: function(first, last) {
- return first+'.'+last;
- }
- },
- key: "missing",
- params: ['Twig', 'js']
- })
- .should.equal("");
-```
-
-should return element of an array.
-
-```js
-twig({data: '{{ attribute(arr, 0) }}' }).render({
- arr: ['Twig', 'js']
- })
- .should.equal("Twig");
-```
-
-should return undef for array beyond index size.
-
-```js
-twig({data: '{{ attribute(arr, 100) }}' }).render({
- arr: ['Twig', 'js']
- })
- .should.equal("");
-```
-
-<a name="twigjs-functions---built-in-functions---template_from_string--"></a>
-### template_from_string ->
-should load a template from a string.
-
-```js
-twig({data: '{% include template_from_string("{{ value }}") %}'}).render({
- value: 'test'
-})
-.should.equal('test');
-```
-
-should load a template from a variable.
-
-```js
-twig({data: '{% include template_from_string(template) %}'}).render({
- template: '{{ value }}',
- value: 'test'
-})
-.should.equal('test');
-```
-
-<a name="twigjs-functions---built-in-functions---random--"></a>
-### random ->
-should return a random item from a traversable or array.
-
-```js
-var arr = "bcdefghij".split("");
-for (var i = 1; i <= 1000; i++) {
- arr.should.containEql(twig({data: '{{ random(arr) }}'}).render({arr: arr}));
-}
-```
-
-should return a random character from a string.
-
-```js
-var str = "abcdefghij";
-for (var i = 1; i <= 1000; i++) {
- str.should.containEql(twig({data: '{{ random(str) }}'}).render({str: str}));
-}
-```
-
-should return a random integer between 0 and the integer parameter.
-
-```js
-for (var i = 1; i <= 1000; i++) {
- twig({data: '{{ random(10) }}'}).render().should.be.within(0, 10);
-}
-```
-
-should return a random integer between 0 and 2147483647 when no parameters are passed.
-
-```js
-for (var i = 1; i <= 1000; i++) {
- twig({data: '{{ random() }}'}).render().should.be.within(0, 2147483647);
-}
-```
-
-<a name="twigjs-functions---built-in-functions---min-max--"></a>
-### min, max ->
-should support the 'min' function.
-
-```js
-twig({data: '{{ min(2, 1, 3, 5, 4) }}'}).render().should.equal('1');
-twig({data: '{{ min([2, 1, 3, 5, 4]) }}'}).render().should.equal('1');
-twig({data: '{{ min({2:"two", 1:"one", 3:"three", 5:"five", 4:"four"}) }}'}).render().should.equal('five');
-```
-
-should support the 'max' function.
-
-```js
-twig({data: '{{ max([2, 1, 3, 5, 4]) }}'}).render().should.equal('5');
-twig({data: '{{ max(2, 1, 3, 5, 4) }}'}).render().should.equal('5');
-twig({data: '{{ max({2:"two", 1:"one", 3:"three", 5:"five", 4:"four"}) }}'}).render().should.equal('two');
-```
-
-<a name="twigjs-loaders--"></a>
-# Twig.js Loaders ->
-<a name="twigjs-loaders---custom-loader--"></a>
-## custom loader ->
-should define a custom loader.
-
-```js
-Twig.extend(function(Twig) {
- var obj = {
- templates: {
- 'custom_loader_block': '{% block main %}This lets you {% block data %}use blocks{% endblock data %}{% endblock main %}',
- 'custom_loader_simple': 'the value is: {{ value }}',
- 'custom_loader_include': 'include others from the same loader method - {% include "custom_loader_simple" %}',
- 'custom_loader_complex': '{% extends "custom_loader_block" %} {% block data %}extend other templates and {% include "custom_loader_include" %}{% endblock data %}'
- },
- loader: function(location, params, callback, error_callback) {
- params.data = this.templates[location];
- params.allowInlineIncludes = true;
- var template = new Twig.Template(params);
- if (typeof callback === 'function') {
- callback(template);
- }
- return template;
- }
- };
- Twig.Templates.registerLoader('custom', obj.loader, obj);
- Twig.Templates.loaders.should.have.property('custom');
-});
-```
-
-should load a simple template from a custom loader.
-
-```js
-twig({
- method: 'custom',
- name: 'custom_loader_simple'
-}).render({value: 'test succeeded'}).should.equal('the value is: test succeeded');
-```
-
-should load a template that includes another from a custom loader.
-
-```js
-twig({
- method: 'custom',
- name: 'custom_loader_include'
-}).render({value: 'test succeeded'}).should.equal('include others from the same loader method - the value is: test succeeded');
-```
-
-should load a template that extends another from a custom loader.
-
-```js
-twig({
- method: 'custom',
- name: 'custom_loader_complex'
-}).render({value: 'test succeeded'}).should.equal('This lets you extend other templates and include others from the same loader method - the value is: test succeeded');
-```
-
-should remove a registered loader.
-
-```js
-Twig.extend(function(Twig) {
- Twig.Templates.unRegisterLoader('custom');
- Twig.Templates.loaders.should.not.have.property('custom');
-});
-```
-
-<a name="twigjs-macro--"></a>
-# Twig.js Macro ->
-it should load macro.
-
-```js
-twig({
- id: 'macro',
- path: 'test/templates/macro.twig',
- async: false
-});
-// Load the template
-twig({ref: 'macro'}).render({ }).should.equal( '' );
-```
-
-it should import macro.
-
-```js
-twig({
- id: 'import-macro',
- path: 'test/templates/import.twig',
- async: false
-});
-// Load the template
-twig({ref: 'import-macro'}).render({ }).trim().should.equal( "Hello World" );
-```
-
-it should run macro with self reference.
-
-```js
-twig({
- id: 'import-macro-self',
- path: 'test/templates/macro-self.twig',
- async: false
-});
-// Load the template
-twig({ref: 'import-macro-self'}).render({ }).trim().should.equal( '<p><input type="text" name="username" value="" size="20" /></p>' );
-```
-
-it should run wrapped macro with self reference.
-
-```js
-twig({
- id: 'import-wrapped-macro-self',
- path: 'test/templates/macro-wrapped.twig',
- async: false
-});
-// Load the template
-twig({ref: 'import-wrapped-macro-self'}).render({ }).trim().should.equal( '<p><div class="field"><input type="text" name="username" value="" size="20" /></div></p>' );
-```
-
-it should run wrapped macro with context and self reference.
-
-```js
-twig({
- id: 'import-macro-context-self',
- path: 'test/templates/macro-context.twig',
- async: false
-});
-// Load the template
-twig({ref: 'import-macro-context-self'}).render({ 'greetings': 'Howdy' }).trim().should.equal( 'Howdy Twigjs' );
-```
-
-it should run wrapped macro inside blocks.
-
-```js
-twig({
- id: 'import-macro-inside-block',
- path: 'test/templates/macro-blocks.twig',
- async: false
-});
-// Load the template
-twig({ref: 'import-macro-inside-block'}).render({ }).trim().should.equal( 'Welcome <div class="name">Twig Js</div>' );
-```
-
-it should import selected macros from template.
-
-```js
-twig({
- id: 'from-macro-import',
- path: 'test/templates/from.twig',
- async: false
-});
-// Load the template
-twig({ref: 'from-macro-import'}).render({ }).trim().should.equal( 'Twig.js<div class="field"><input type="text" name="text" value="" size="20" /></div><div class="field red"><input type="text" name="password" value="" size="20" /></div>' );
-```
-
-should support inline includes by ID.
-
-```js
-twig({
- id: 'hello',
- data: '{% macro echo(name) %}Hello {{ name }}{% endmacro %}'
-});
-var template = twig({
- allowInlineIncludes: true,
- data: 'template with {% from "hello" import echo %}{{ echo("Twig.js") }}'
- }),
- output = template.render()
-output.should.equal("template with Twig.js");
-```
-
-<a name="twigjs-namespaces--"></a>
-# Twig.js Namespaces ->
-should support namespaces defined with ::.
-
-```js
-twig({
- namespaces: { 'test': 'test/templates/namespaces/' },
- path: 'test/templates/namespaces_::.twig',
- load: function(template) {
- // Render the template
- template.render({
- test: "yes",
- flag: true
- }).should.equal("namespaces");
-
- done();
- }
- });
-```
-
-should support namespaces defined with @.
-
-```js
-twig({
- namespaces: { 'test': 'test/templates/namespaces/' },
- path: 'test/templates/namespaces_@.twig',
- load: function(template) {
- // Render the template
- template.render({
- test: "yes",
- flag: true
- }).should.equal("namespaces");
-
- done();
- }
- });
-```
-
-<a name="twigjs-optional-functionality--"></a>
-# Twig.js Optional Functionality ->
-should support inline includes by ID.
-
-```js
-twig({
- id: 'other',
- data: 'another template'
-});
-var template = twig({
- allowInlineIncludes: true,
- data: 'template with {% include "other" %}'
- }),
- output = template.render()
-output.should.equal("template with another template");
-```
-
-<a name="twigjs-parsers--"></a>
-# Twig.js Parsers ->
-<a name="twigjs-parsers---custom-parser--"></a>
-## custom parser ->
-should define a custom parser.
-
-```js
-Twig.extend(function(Twig) {
- var parser = function(params) {
- return '[CUSTOM PARSER] ' + params.data;
- };
- Twig.Templates.registerParser('custom', parser);
- Twig.Templates.parsers.should.have.property('custom');
-});
-```
-
-should run the data through the custom parser.
-
-```js
-Twig.extend(function(Twig) {
- var params = {
- data: 'This is a test template.'
- };
- var template = Twig.Templates.parsers.custom(params);
- template.should.equal('[CUSTOM PARSER] This is a test template.');
-});
-```
-
-should remove a registered parser.
-
-```js
-Twig.extend(function(Twig) {
- Twig.Templates.unRegisterParser('custom');
- Twig.Templates.parsers.should.not.have.property('custom');
-});
-```
-
-<a name="twigjs-path--"></a>
-# Twig.js Path ->
-<a name="twigjs-path---relativepath--"></a>
-## relativePath ->
-should throw an error if trying to get a relative path in an inline template.
-
-```js
-(function () {
- relativePath({});
-}).should.throw("Cannot extend an inline template.");
-```
-
-should give the full path to a file when file is passed.
-
-```js
-relativePath({ url: "http://www.test.com/test.twig"}, "templates/myFile.twig").should.equal("http://www.test.com/templates/myFile.twig");
-relativePath({ path: "test/test.twig"}, "templates/myFile.twig").should.equal("test/templates/myFile.twig");
-```
-
-should ascend directories.
-
-```js
-relativePath({ url: "http://www.test.com/templates/../test.twig"}, "myFile.twig").should.equal("http://www.test.com/myFile.twig");
-relativePath({ path: "test/templates/../test.twig"}, "myFile.twig").should.equal("test/myFile.twig");
-```
-
-should respect relative directories.
-
-```js
-relativePath({ url: "http://www.test.com/templates/./test.twig"}, "myFile.twig").should.equal("http://www.test.com/templates/myFile.twig");
-relativePath({ path: "test/templates/./test.twig"}, "myFile.twig").should.equal("test/templates/myFile.twig");
-```
-
-<a name="twigjs-path---relativepath---url--"></a>
-### url ->
-should use the url if no base is specified.
-
-```js
-relativePath({ url: "http://www.test.com/test.twig"}).should.equal("http://www.test.com/");
-```
-
-should use the base if base is specified.
-
-```js
-relativePath({ url: "http://www.test.com/test.twig", base: "myTest" }).should.equal("myTest/");
-```
-
-<a name="twigjs-path---relativepath---path--"></a>
-### path ->
-should use the path if no base is specified.
-
-```js
-relativePath({ path: "test/test.twig"}).should.equal("test/");
-```
-
-should use the base if base is specified.
-
-```js
-relativePath({ path: "test/test.twig", base: "myTest" }).should.equal("myTest/");
-```
-
-<a name="twigjs-path---parsepath--"></a>
-## parsePath ->
-should fall back to relativePath if the template has no namespaces defined.
-
-```js
-var relativePathStub = sinon.stub(Twig.path, "relativePath");
-parsePath({ options: {} });
-relativePathStub.should.have.been.called;
-```
-
-<a name="twigjs-regression-tests--"></a>
-# Twig.js Regression Tests ->
-#47 should not match variables starting with not.
-
-```js
-// Define and save a template
-twig({data: '{% for note in notes %}{{note}}{% endfor %}'}).render({notes:['a', 'b', 'c']}).should.equal("abc");
-```
-
-#56 functions work inside parentheses.
-
-```js
-// Define and save a template
-Twig.extendFunction('custom', function(value) {
- return true;
-});
-twig({data: '{% if (custom("val") and custom("val")) %}out{% endif %}'}).render({}).should.equal("out");
-```
-
-#83 Support for trailing commas in arrays.
-
-```js
-twig({data: '{{ [1,2,3,4,] }}'}).render().should.equal("1,2,3,4");
-```
-
-#83 Support for trailing commas in objects.
-
-```js
-twig({data: '{{ {a:1, b:2, c:3, } }}'}).render();
-```
-
-#283 should support quotes between raw tags.
-
-```js
-twig({data: '{% raw %}\n"\n{% endraw %}'}).render().should.equal('"');
-twig({data: "{% raw %}\n'\n{% endraw %}"}).render().should.equal("'");
-```
-
-<a name="twigjs-tags--"></a>
-# Twig.js Tags ->
-should support spaceless.
-
-```js
-twig({
- data: "{% spaceless %}<div>\n <b>b</b> <i>i</i>\n</div>{% endspaceless %}"
-}).render().should.equal(
- "<div><b>b</b><i>i</i></div>"
-);
-```
-
-<a name="twigjs-tests--"></a>
-# Twig.js Tests ->
-<a name="twigjs-tests---empty-test--"></a>
-## empty test ->
-should identify numbers as not empty.
-
-```js
-// number
-twig({data: '{{ 1 is empty }}'}).render().should.equal("false" );
-twig({data: '{{ 0 is empty }}'}).render().should.equal("false" );
-```
-
-should identify empty strings.
-
-```js
-// String
-twig({data: '{{ "" is empty }}'}).render().should.equal("true" );
-twig({data: '{{ "test" is empty }}'}).render().should.equal("false" );
-```
-
-should identify empty arrays.
-
-```js
-// Array
-twig({data: '{{ [] is empty }}'}).render().should.equal("true" );
-twig({data: '{{ ["1"] is empty }}'}).render().should.equal("false" );
-```
-
-should identify empty objects.
-
-```js
-// Object
-twig({data: '{{ {} is empty }}'}).render().should.equal("true" );
-twig({data: '{{ {"a":"b"} is empty }}'}).render().should.equal("false" );
-twig({data: '{{ {"a":"b"} is not empty }}'}).render().should.equal("true" );
-```
-
-<a name="twigjs-tests---odd-test--"></a>
-## odd test ->
-should identify a number as odd.
-
-```js
-twig({data: '{{ (1 + 4) is odd }}'}).render().should.equal("true" );
-twig({data: '{{ 6 is odd }}'}).render().should.equal("false" );
-```
-
-<a name="twigjs-tests---even-test--"></a>
-## even test ->
-should identify a number as even.
-
-```js
-twig({data: '{{ (1 + 4) is even }}'}).render().should.equal("false" );
-twig({data: '{{ 6 is even }}'}).render().should.equal("true" );
-```
-
-<a name="twigjs-tests---divisibleby-test--"></a>
-## divisibleby test ->
-should determine if a number is divisible by the given number.
-
-```js
-twig({data: '{{ 5 is divisibleby(3) }}'}).render().should.equal("false" );
-twig({data: '{{ 6 is divisibleby(3) }}'}).render().should.equal("true" );
-```
-
-<a name="twigjs-tests---defined-test--"></a>
-## defined test ->
-should identify a key as defined if it exists in the render context.
-
-```js
-twig({data: '{{ key is defined }}'}).render().should.equal("false" );
-twig({data: '{{ key is defined }}'}).render({key: "test"}).should.equal( "true" );
-var context = {
- key: {
- foo: "bar",
- nothing: null
- },
- nothing: null
-};
-twig({data: '{{ key.foo is defined }}'}).render(context).should.equal( "true" );
-twig({data: '{{ key.bar is defined }}'}).render(context).should.equal( "false" );
-twig({data: '{{ key.foo.bar is defined }}'}).render(context).should.equal( "false" );
-twig({data: '{{ foo.bar is defined }}'}).render(context).should.equal( "false" );
-twig({data: '{{ nothing is defined }}'}).render(context).should.equal( "true" );
-twig({data: '{{ key.nothing is defined }}'}).render(context).should.equal( "true" );
-```
-
-<a name="twigjs-tests---none-test--"></a>
-## none test ->
-should identify a key as none if it exists in the render context and is null.
-
-```js
-twig({data: '{{ key is none }}'}).render().should.equal("false");
-twig({data: '{{ key is none }}'}).render({key: "test"}).should.equal("false");
-twig({data: '{{ key is none }}'}).render({key: null}).should.equal("true");
-twig({data: '{{ key is null }}'}).render({key: null}).should.equal("true");
-```
-
-<a name="twigjs-tests---sameas-test--"></a>
-## sameas test ->
-should identify the exact same type as true.
-
-```js
-twig({data: '{{ true is sameas(true) }}'}).render().should.equal("true");
-twig({data: '{{ a is sameas(1) }}'}).render({a: 1}).should.equal("true");
-twig({data: '{{ a is sameas("test") }}'}).render({a: "test"}).should.equal("true");
-twig({data: '{{ a is sameas(true) }}'}).render({a: true}).should.equal("true");
-```
-
-should identify the different types as false.
-
-```js
-twig({data: '{{ false is sameas(true) }}'}).render().should.equal("false");
-twig({data: '{{ true is sameas(1) }}'}).render().should.equal("false");
-twig({data: '{{ false is sameas("") }}'}).render().should.equal("false");
-twig({data: '{{ a is sameas(1) }}'}).render({a: "1"}).should.equal("false");
-```
-
-<a name="twigjs-tests---iterable-test--"></a>
-## iterable test ->
-should fail on non-iterable data types.
-
-```js
-twig({data: "{{ val is iterable ? 'ok' : 'ko' }}"}).render(data).should.equal("ko");
-twig({data: "{{ val is iterable ? 'ok' : 'ko' }}"}).render({val: null}).should.equal("ko");
-twig({data: "{{ val is iterable ? 'ok' : 'ko' }}"}).render({}).should.equal("ko");
-```
-
-should pass on iterable data types.
-
-```js
-twig({data: "{{ foo is iterable ? 'ok' : 'ko' }}"}).render(data).should.equal("ok");
-twig({data: "{{ obj is iterable ? 'ok' : 'ko' }}"}).render(data).should.equal("ok");
-```
-
diff --git a/node_modules/twig/docs/twig.html b/node_modules/twig/docs/twig.html
deleted file mode 100644
index 687abbd..0000000
--- a/node_modules/twig/docs/twig.html
+++ /dev/null
@@ -1,11250 +0,0 @@
-<!DOCTYPE html>
-
-<html>
-<head>
- <title>twig.js</title>
- <meta http-equiv="content-type" content="text/html; charset=UTF-8">
- <meta name="viewport" content="width=device-width, target-densitydpi=160dpi, initial-scale=1.0; maximum-scale=1.0; user-scalable=0;">
- <link rel="stylesheet" media="all" href="docco.css" />
-</head>
-<body>
- <div id="container">
- <div id="background"></div>
-
- <ul class="sections">
-
- <li id="title">
- <div class="annotation">
- <h1>twig.js</h1>
- </div>
- </li>
-
-
-
- <li id="section-1">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-1">&#182;</a>
- </div>
-
- </div>
-
- <div class="content"><div class='highlight'><pre><span class="hljs-comment">/**
- * Twig.js 0.8.9
- *
- * @copyright 2011-2015 John Roepke and the Twig.js Contributors
- * @license Available under the BSD 2-Clause License
- * @link https://github.com/justjohn/twig.js
- */</span>
-
-<span class="hljs-keyword">var</span> Twig = (<span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">Twig</span>) </span>{
-
- Twig.VERSION = <span class="hljs-string">"0.8.9"</span>;
-
- <span class="hljs-keyword">return</span> Twig;
-})(Twig || {});</pre></div></div>
-
- </li>
-
-
- <li id="section-2">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-2">&#182;</a>
- </div>
- <pre><code>Twig.js
-Available under the BSD <span class="hljs-number">2</span>-Clause License
-https:<span class="hljs-comment">//github.com/justjohn/twig.js</span>
-</code></pre>
- </div>
-
- <div class="content"><div class='highlight'><pre>
-<span class="hljs-keyword">var</span> Twig = (<span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">Twig</span>) </span>{
-<span class="hljs-meta"> "use strict"</span>;</pre></div></div>
-
- </li>
-
-
- <li id="section-3">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-3">&#182;</a>
- </div>
- <h2 id="twig-core-js">twig.core.js</h2>
-<p>This file handles template level tokenizing, compiling and parsing.</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre>
- Twig.trace = <span class="hljs-literal">false</span>;
- Twig.debug = <span class="hljs-literal">false</span>;</pre></div></div>
-
- </li>
-
-
- <li id="section-4">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-4">&#182;</a>
- </div>
- <p>Default caching to true for the improved performance it offers</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> Twig.cache = <span class="hljs-literal">true</span>;
-
- Twig.placeholders = {
- parent: <span class="hljs-string">"{{|PARENT|}}"</span>
- };
-
- <span class="hljs-comment">/**
- * Fallback for Array.indexOf for IE8 et al
- */</span>
- Twig.indexOf = <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">arr, searchElement <span class="hljs-comment">/*, fromIndex */</span> </span>) </span>{
- <span class="hljs-keyword">if</span> (<span class="hljs-built_in">Array</span>.prototype.hasOwnProperty(<span class="hljs-string">"indexOf"</span>)) {
- <span class="hljs-keyword">return</span> arr.indexOf(searchElement);
- }
- <span class="hljs-keyword">if</span> (arr === <span class="hljs-keyword">void</span> <span class="hljs-number">0</span> || arr === <span class="hljs-literal">null</span>) {
- <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">TypeError</span>();
- }
- <span class="hljs-keyword">var</span> t = <span class="hljs-built_in">Object</span>(arr);
- <span class="hljs-keyword">var</span> len = t.length &gt;&gt;&gt; <span class="hljs-number">0</span>;
- <span class="hljs-keyword">if</span> (len === <span class="hljs-number">0</span>) {
- <span class="hljs-keyword">return</span> <span class="hljs-number">-1</span>;
- }
- <span class="hljs-keyword">var</span> n = <span class="hljs-number">0</span>;
- <span class="hljs-keyword">if</span> (<span class="hljs-built_in">arguments</span>.length &gt; <span class="hljs-number">0</span>) {
- n = <span class="hljs-built_in">Number</span>(<span class="hljs-built_in">arguments</span>[<span class="hljs-number">1</span>]);
- <span class="hljs-keyword">if</span> (n !== n) { <span class="hljs-comment">// shortcut for verifying if it's NaN</span>
- n = <span class="hljs-number">0</span>;
- } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (n !== <span class="hljs-number">0</span> &amp;&amp; n !== <span class="hljs-literal">Infinity</span> &amp;&amp; n !== -<span class="hljs-literal">Infinity</span>) {
- n = (n &gt; <span class="hljs-number">0</span> || <span class="hljs-number">-1</span>) * <span class="hljs-built_in">Math</span>.floor(<span class="hljs-built_in">Math</span>.abs(n));
- }
- }
- <span class="hljs-keyword">if</span> (n &gt;= len) {</pre></div></div>
-
- </li>
-
-
- <li id="section-5">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-5">&#182;</a>
- </div>
- <p>console.log(“indexOf not found1 “, JSON.stringify(searchElement), JSON.stringify(arr));</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">return</span> <span class="hljs-number">-1</span>;
- }
- <span class="hljs-keyword">var</span> k = n &gt;= <span class="hljs-number">0</span> ? n : <span class="hljs-built_in">Math</span>.max(len - <span class="hljs-built_in">Math</span>.abs(n), <span class="hljs-number">0</span>);
- <span class="hljs-keyword">for</span> (; k &lt; len; k++) {
- <span class="hljs-keyword">if</span> (k <span class="hljs-keyword">in</span> t &amp;&amp; t[k] === searchElement) {
- <span class="hljs-keyword">return</span> k;
- }
- }
- <span class="hljs-keyword">if</span> (arr == searchElement) {
- <span class="hljs-keyword">return</span> <span class="hljs-number">0</span>;
- }</pre></div></div>
-
- </li>
-
-
- <li id="section-6">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-6">&#182;</a>
- </div>
- <p>console.log(“indexOf not found2 “, JSON.stringify(searchElement), JSON.stringify(arr));</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre>
- <span class="hljs-keyword">return</span> <span class="hljs-number">-1</span>;
- }
-
- Twig.forEach = <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">arr, callback, thisArg</span>) </span>{
- <span class="hljs-keyword">if</span> (<span class="hljs-built_in">Array</span>.prototype.forEach ) {
- <span class="hljs-keyword">return</span> arr.forEach(callback, thisArg);
- }
-
- <span class="hljs-keyword">var</span> T, k;
-
- <span class="hljs-keyword">if</span> ( arr == <span class="hljs-literal">null</span> ) {
- <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">TypeError</span>( <span class="hljs-string">" this is null or not defined"</span> );
- }</pre></div></div>
-
- </li>
-
-
- <li id="section-7">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-7">&#182;</a>
- </div>
- <ol>
-<li>Let O be the result of calling ToObject passing the |this| value as the argument.</li>
-</ol>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">var</span> O = <span class="hljs-built_in">Object</span>(arr);</pre></div></div>
-
- </li>
-
-
- <li id="section-8">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-8">&#182;</a>
- </div>
- <ol>
-<li>Let lenValue be the result of calling the Get internal method of O with the argument “length”.</li>
-<li>Let len be ToUint32(lenValue).</li>
-</ol>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">var</span> len = O.length &gt;&gt;&gt; <span class="hljs-number">0</span>; <span class="hljs-comment">// Hack to convert O.length to a UInt32</span></pre></div></div>
-
- </li>
-
-
- <li id="section-9">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-9">&#182;</a>
- </div>
- <ol>
-<li>If IsCallable(callback) is false, throw a TypeError exception.
-See: <a href="http://es5.github.com/#x9.11">http://es5.github.com/#x9.11</a></li>
-</ol>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> ( {}.toString.call(callback) != <span class="hljs-string">"[object Function]"</span> ) {
- <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">TypeError</span>( callback + <span class="hljs-string">" is not a function"</span> );
- }</pre></div></div>
-
- </li>
-
-
- <li id="section-10">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-10">&#182;</a>
- </div>
- <ol>
-<li>If thisArg was supplied, let T be thisArg; else let T be undefined.</li>
-</ol>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> ( thisArg ) {
- T = thisArg;
- }</pre></div></div>
-
- </li>
-
-
- <li id="section-11">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-11">&#182;</a>
- </div>
- <ol>
-<li>Let k be 0</li>
-</ol>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> k = <span class="hljs-number">0</span>;</pre></div></div>
-
- </li>
-
-
- <li id="section-12">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-12">&#182;</a>
- </div>
- <ol>
-<li>Repeat, while k &lt; len</li>
-</ol>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">while</span>( k &lt; len ) {
-
- <span class="hljs-keyword">var</span> kValue;</pre></div></div>
-
- </li>
-
-
- <li id="section-13">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-13">&#182;</a>
- </div>
- <p>a. Let Pk be ToString(k).
- This is implicit for LHS operands of the in operator
-b. Let kPresent be the result of calling the HasProperty internal method of O with argument Pk.
- This step can be combined with c
-c. If kPresent is true, then</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> ( k <span class="hljs-keyword">in</span> O ) {</pre></div></div>
-
- </li>
-
-
- <li id="section-14">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-14">&#182;</a>
- </div>
- <p>i. Let kValue be the result of calling the Get internal method of O with argument Pk.</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> kValue = O[ k ];</pre></div></div>
-
- </li>
-
-
- <li id="section-15">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-15">&#182;</a>
- </div>
- <p>ii. Call the Call internal method of callback with T as the this value and
-argument list containing kValue, k, and O.</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> callback.call( T, kValue, k, O );
- }</pre></div></div>
-
- </li>
-
-
- <li id="section-16">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-16">&#182;</a>
- </div>
- <p>d. Increase k by 1.</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> k++;
- }</pre></div></div>
-
- </li>
-
-
- <li id="section-17">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-17">&#182;</a>
- </div>
- <ol>
-<li>return undefined</li>
-</ol>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> };
-
- Twig.merge = <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">target, source, onlyChanged</span>) </span>{
- Twig.forEach(<span class="hljs-built_in">Object</span>.keys(source), <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">key</span>) </span>{
- <span class="hljs-keyword">if</span> (onlyChanged &amp;&amp; !(key <span class="hljs-keyword">in</span> target)) {
- <span class="hljs-keyword">return</span>;
- }
-
- target[key] = source[key]
- });
-
- <span class="hljs-keyword">return</span> target;
- };
-
- <span class="hljs-comment">/**
- * Exception thrown by twig.js.
- */</span>
- Twig.Error = <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">message</span>) </span>{
- <span class="hljs-keyword">this</span>.message = message;
- <span class="hljs-keyword">this</span>.name = <span class="hljs-string">"TwigException"</span>;
- <span class="hljs-keyword">this</span>.type = <span class="hljs-string">"TwigException"</span>;
- };
-
- <span class="hljs-comment">/**
- * Get the string representation of a Twig error.
- */</span>
- Twig.Error.prototype.toString = <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) </span>{
- <span class="hljs-keyword">var</span> output = <span class="hljs-keyword">this</span>.name + <span class="hljs-string">": "</span> + <span class="hljs-keyword">this</span>.message;
-
- <span class="hljs-keyword">return</span> output;
- };
-
- <span class="hljs-comment">/**
- * Wrapper for logging to the console.
- */</span>
- Twig.log = {
- trace: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) </span>{<span class="hljs-keyword">if</span> (Twig.trace &amp;&amp; <span class="hljs-built_in">console</span>) {<span class="hljs-built_in">console</span>.log(<span class="hljs-built_in">Array</span>.prototype.slice.call(<span class="hljs-built_in">arguments</span>));}},
- debug: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) </span>{<span class="hljs-keyword">if</span> (Twig.debug &amp;&amp; <span class="hljs-built_in">console</span>) {<span class="hljs-built_in">console</span>.log(<span class="hljs-built_in">Array</span>.prototype.slice.call(<span class="hljs-built_in">arguments</span>));}}
- };
-
-
- <span class="hljs-keyword">if</span> (<span class="hljs-keyword">typeof</span> <span class="hljs-built_in">console</span> !== <span class="hljs-string">"undefined"</span>) {
- <span class="hljs-keyword">if</span> (<span class="hljs-keyword">typeof</span> <span class="hljs-built_in">console</span>.error !== <span class="hljs-string">"undefined"</span>) {
- Twig.log.error = <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) </span>{
- <span class="hljs-built_in">console</span>.error.apply(<span class="hljs-built_in">console</span>, <span class="hljs-built_in">arguments</span>);
- }
- } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (<span class="hljs-keyword">typeof</span> <span class="hljs-built_in">console</span>.log !== <span class="hljs-string">"undefined"</span>) {
- Twig.log.error = <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) </span>{
- <span class="hljs-built_in">console</span>.log.apply(<span class="hljs-built_in">console</span>, <span class="hljs-built_in">arguments</span>);
- }
- }
- } <span class="hljs-keyword">else</span> {
- Twig.log.error = <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>)</span>{};
- }
-
- <span class="hljs-comment">/**
- * Wrapper for child context objects in Twig.
- *
- * @param {Object} context Values to initialize the context with.
- */</span>
- Twig.ChildContext = <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">context</span>) </span>{
- <span class="hljs-keyword">var</span> ChildContext = <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">ChildContext</span>(<span class="hljs-params"></span>) </span>{};
- ChildContext.prototype = context;
- <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> ChildContext();
- };
-
- <span class="hljs-comment">/**
- * Container for methods related to handling high level template tokens
- * (for example: {{ expression }}, {% logic %}, {# comment #}, raw data)
- */</span>
- Twig.token = {};
-
- <span class="hljs-comment">/**
- * Token types.
- */</span>
- Twig.token.type = {
- output: <span class="hljs-string">'output'</span>,
- logic: <span class="hljs-string">'logic'</span>,
- comment: <span class="hljs-string">'comment'</span>,
- raw: <span class="hljs-string">'raw'</span>,
- output_whitespace_pre: <span class="hljs-string">'output_whitespace_pre'</span>,
- output_whitespace_post: <span class="hljs-string">'output_whitespace_post'</span>,
- output_whitespace_both: <span class="hljs-string">'output_whitespace_both'</span>,
- logic_whitespace_pre: <span class="hljs-string">'logic_whitespace_pre'</span>,
- logic_whitespace_post: <span class="hljs-string">'logic_whitespace_post'</span>,
- logic_whitespace_both: <span class="hljs-string">'logic_whitespace_both'</span>
- };
-
- <span class="hljs-comment">/**
- * Token syntax definitions.
- */</span>
- Twig.token.definitions = [
- {
- type: Twig.token.type.raw,
- open: <span class="hljs-string">'{% raw %}'</span>,
- close: <span class="hljs-string">'{% endraw %}'</span>
- },
- {
- type: Twig.token.type.raw,
- open: <span class="hljs-string">'{% verbatim %}'</span>,
- close: <span class="hljs-string">'{% endverbatim %}'</span>
- },</pre></div></div>
-
- </li>
-
-
- <li id="section-18">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-18">&#182;</a>
- </div>
- <p><em>Whitespace type tokens</em></p>
-<p>These typically take the form <code>{{- expression -}}</code> or <code>{{- expression }}</code> or <code>{{ expression -}}</code>.</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> {
- type: Twig.token.type.output_whitespace_pre,
- open: <span class="hljs-string">'{{-'</span>,
- close: <span class="hljs-string">'}}'</span>
- },
- {
- type: Twig.token.type.output_whitespace_post,
- open: <span class="hljs-string">'{{'</span>,
- close: <span class="hljs-string">'-}}'</span>
- },
- {
- type: Twig.token.type.output_whitespace_both,
- open: <span class="hljs-string">'{{-'</span>,
- close: <span class="hljs-string">'-}}'</span>
- },
- {
- type: Twig.token.type.logic_whitespace_pre,
- open: <span class="hljs-string">'{%-'</span>,
- close: <span class="hljs-string">'%}'</span>
- },
- {
- type: Twig.token.type.logic_whitespace_post,
- open: <span class="hljs-string">'{%'</span>,
- close: <span class="hljs-string">'-%}'</span>
- },
- {
- type: Twig.token.type.logic_whitespace_both,
- open: <span class="hljs-string">'{%-'</span>,
- close: <span class="hljs-string">'-%}'</span>
- },</pre></div></div>
-
- </li>
-
-
- <li id="section-19">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-19">&#182;</a>
- </div>
- <p><em>Output type tokens</em></p>
-<p>These typically take the form <code>{{ expression }}</code>.</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> {
- type: Twig.token.type.output,
- open: <span class="hljs-string">'{{'</span>,
- close: <span class="hljs-string">'}}'</span>
- },</pre></div></div>
-
- </li>
-
-
- <li id="section-20">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-20">&#182;</a>
- </div>
- <p><em>Logic type tokens</em></p>
-<p>These typically take a form like <code>{% if expression %}</code> or <code>{% endif %}</code></p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> {
- type: Twig.token.type.logic,
- open: <span class="hljs-string">'{%'</span>,
- close: <span class="hljs-string">'%}'</span>
- },</pre></div></div>
-
- </li>
-
-
- <li id="section-21">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-21">&#182;</a>
- </div>
- <p><em>Comment type tokens</em></p>
-<p>These take the form <code>{# anything #}</code></p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> {
- type: Twig.token.type.comment,
- open: <span class="hljs-string">'{#'</span>,
- close: <span class="hljs-string">'#}'</span>
- }
- ];
-
-
- <span class="hljs-comment">/**
- * What characters start "strings" in token definitions. We need this to ignore token close
- * strings inside an expression.
- */</span>
- Twig.token.strings = [<span class="hljs-string">'"'</span>, <span class="hljs-string">"'"</span>];
-
- Twig.token.findStart = <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">template</span>) </span>{
- <span class="hljs-keyword">var</span> output = {
- position: <span class="hljs-literal">null</span>,
- close_position: <span class="hljs-literal">null</span>,
- def: <span class="hljs-literal">null</span>
- },
- i,
- token_template,
- first_key_position,
- close_key_position;
-
- <span class="hljs-keyword">for</span> (i=<span class="hljs-number">0</span>;i&lt;Twig.token.definitions.length;i++) {
- token_template = Twig.token.definitions[i];
- first_key_position = template.indexOf(token_template.open);
- close_key_position = template.indexOf(token_template.close);
-
- Twig.log.trace(<span class="hljs-string">"Twig.token.findStart: "</span>, <span class="hljs-string">"Searching for "</span>, token_template.open, <span class="hljs-string">" found at "</span>, first_key_position);</pre></div></div>
-
- </li>
-
-
- <li id="section-22">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-22">&#182;</a>
- </div>
- <p>Special handling for mismatched tokens</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> (first_key_position &gt;= <span class="hljs-number">0</span>) {</pre></div></div>
-
- </li>
-
-
- <li id="section-23">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-23">&#182;</a>
- </div>
- <p>This token matches the template</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> (token_template.open.length !== token_template.close.length) {</pre></div></div>
-
- </li>
-
-
- <li id="section-24">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-24">&#182;</a>
- </div>
- <p>This token has mismatched closing and opening tags</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> (close_key_position &lt; <span class="hljs-number">0</span>) {</pre></div></div>
-
- </li>
-
-
- <li id="section-25">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-25">&#182;</a>
- </div>
- <p>This token’s closing tag does not match the template</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">continue</span>;
- }
- }
- }</pre></div></div>
-
- </li>
-
-
- <li id="section-26">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-26">&#182;</a>
- </div>
- <p>Does this token occur before any other types?</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> (first_key_position &gt;= <span class="hljs-number">0</span> &amp;&amp; (output.position === <span class="hljs-literal">null</span> || first_key_position &lt; output.position)) {
- output.position = first_key_position;
- output.def = token_template;
- output.close_position = close_key_position;
- } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (first_key_position &gt;= <span class="hljs-number">0</span> &amp;&amp; output.position !== <span class="hljs-literal">null</span> &amp;&amp; first_key_position === output.position) {
- <span class="hljs-comment">/*This token exactly matches another token,
- greedily match to check if this token has a greater specificity*/</span>
- <span class="hljs-keyword">if</span> (token_template.open.length &gt; output.def.open.length) {</pre></div></div>
-
- </li>
-
-
- <li id="section-27">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-27">&#182;</a>
- </div>
- <p>This token’s opening tag is more specific than the previous match</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> output.position = first_key_position;
- output.def = token_template;
- output.close_position = close_key_position;
- } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (token_template.open.length === output.def.open.length) {
- <span class="hljs-keyword">if</span> (token_template.close.length &gt; output.def.close.length) {</pre></div></div>
-
- </li>
-
-
- <li id="section-28">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-28">&#182;</a>
- </div>
- <p>This token’s opening tag is as specific as the previous match,
-but the closing tag has greater specificity</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> (close_key_position &gt;= <span class="hljs-number">0</span> &amp;&amp; close_key_position &lt; output.close_position) {</pre></div></div>
-
- </li>
-
-
- <li id="section-29">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-29">&#182;</a>
- </div>
- <p>This token’s closing tag exists in the template,
-and it occurs sooner than the previous match</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> output.position = first_key_position;
- output.def = token_template;
- output.close_position = close_key_position;
- }
- } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (close_key_position &gt;= <span class="hljs-number">0</span> &amp;&amp; close_key_position &lt; output.close_position) {</pre></div></div>
-
- </li>
-
-
- <li id="section-30">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-30">&#182;</a>
- </div>
- <p>This token’s closing tag is not more specific than the previous match,
-but it occurs sooner than the previous match</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> output.position = first_key_position;
- output.def = token_template;
- output.close_position = close_key_position;
- }
- }
- }
- }
-
- <span class="hljs-keyword">delete</span> output[<span class="hljs-string">'close_position'</span>];
-
- <span class="hljs-keyword">return</span> output;
- };
-
- Twig.token.findEnd = <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">template, token_def, start</span>) </span>{
- <span class="hljs-keyword">var</span> end = <span class="hljs-literal">null</span>,
- found = <span class="hljs-literal">false</span>,
- offset = <span class="hljs-number">0</span>,</pre></div></div>
-
- </li>
-
-
- <li id="section-31">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-31">&#182;</a>
- </div>
- <p>String position variables</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> str_pos = <span class="hljs-literal">null</span>,
- str_found = <span class="hljs-literal">null</span>,
- pos = <span class="hljs-literal">null</span>,
- end_offset = <span class="hljs-literal">null</span>,
- this_str_pos = <span class="hljs-literal">null</span>,
- end_str_pos = <span class="hljs-literal">null</span>,</pre></div></div>
-
- </li>
-
-
- <li id="section-32">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-32">&#182;</a>
- </div>
- <p>For loop variables</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> i,
- l;
-
- <span class="hljs-keyword">while</span> (!found) {
- str_pos = <span class="hljs-literal">null</span>;
- str_found = <span class="hljs-literal">null</span>;
- pos = template.indexOf(token_def.close, offset);
-
- <span class="hljs-keyword">if</span> (pos &gt;= <span class="hljs-number">0</span>) {
- end = pos;
- found = <span class="hljs-literal">true</span>;
- } <span class="hljs-keyword">else</span> {</pre></div></div>
-
- </li>
-
-
- <li id="section-33">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-33">&#182;</a>
- </div>
- <p>throw an exception</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> Twig.Error(<span class="hljs-string">"Unable to find closing bracket '"</span> + token_def.close +
- <span class="hljs-string">"'"</span> + <span class="hljs-string">" opened near template position "</span> + start);
- }</pre></div></div>
-
- </li>
-
-
- <li id="section-34">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-34">&#182;</a>
- </div>
- <p>Ignore quotes within comments; just look for the next comment close sequence,
-regardless of what comes before it. <a href="https://github.com/justjohn/twig.js/issues/95">https://github.com/justjohn/twig.js/issues/95</a></p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> (token_def.type === Twig.token.type.comment) {
- <span class="hljs-keyword">break</span>;
- }</pre></div></div>
-
- </li>
-
-
- <li id="section-35">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-35">&#182;</a>
- </div>
- <p>Ignore quotes within raw tag
-Fixes #283</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> (token_def.type === Twig.token.type.raw) {
- <span class="hljs-keyword">break</span>;
- }
-
- l = Twig.token.strings.length;
- <span class="hljs-keyword">for</span> (i = <span class="hljs-number">0</span>; i &lt; l; i += <span class="hljs-number">1</span>) {
- this_str_pos = template.indexOf(Twig.token.strings[i], offset);
-
- <span class="hljs-keyword">if</span> (this_str_pos &gt; <span class="hljs-number">0</span> &amp;&amp; this_str_pos &lt; pos &amp;&amp;
- (str_pos === <span class="hljs-literal">null</span> || this_str_pos &lt; str_pos)) {
- str_pos = this_str_pos;
- str_found = Twig.token.strings[i];
- }
- }</pre></div></div>
-
- </li>
-
-
- <li id="section-36">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-36">&#182;</a>
- </div>
- <p>We found a string before the end of the token, now find the string’s end and set the search offset to it</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> (str_pos !== <span class="hljs-literal">null</span>) {
- end_offset = str_pos + <span class="hljs-number">1</span>;
- end = <span class="hljs-literal">null</span>;
- found = <span class="hljs-literal">false</span>;
- <span class="hljs-keyword">while</span> (<span class="hljs-literal">true</span>) {
- end_str_pos = template.indexOf(str_found, end_offset);
- <span class="hljs-keyword">if</span> (end_str_pos &lt; <span class="hljs-number">0</span>) {
- <span class="hljs-keyword">throw</span> <span class="hljs-string">"Unclosed string in template"</span>;
- }</pre></div></div>
-
- </li>
-
-
- <li id="section-37">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-37">&#182;</a>
- </div>
- <p>Ignore escaped quotes</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> (template.substr(end_str_pos - <span class="hljs-number">1</span>, <span class="hljs-number">1</span>) !== <span class="hljs-string">"\\"</span>) {
- offset = end_str_pos + <span class="hljs-number">1</span>;
- <span class="hljs-keyword">break</span>;
- } <span class="hljs-keyword">else</span> {
- end_offset = end_str_pos + <span class="hljs-number">1</span>;
- }
- }
- }
- }
- <span class="hljs-keyword">return</span> end;
- };
-
- <span class="hljs-comment">/**
- * Convert a template into high-level tokens.
- */</span>
- Twig.tokenize = <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">template</span>) </span>{
- <span class="hljs-keyword">var</span> tokens = [],</pre></div></div>
-
- </li>
-
-
- <li id="section-38">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-38">&#182;</a>
- </div>
- <p>An offset for reporting errors locations in the template.</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> error_offset = <span class="hljs-number">0</span>,</pre></div></div>
-
- </li>
-
-
- <li id="section-39">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-39">&#182;</a>
- </div>
- <p>The start and type of the first token found in the template.</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> found_token = <span class="hljs-literal">null</span>,</pre></div></div>
-
- </li>
-
-
- <li id="section-40">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-40">&#182;</a>
- </div>
- <p>The end position of the matched token.</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> end = <span class="hljs-literal">null</span>;
-
- <span class="hljs-keyword">while</span> (template.length &gt; <span class="hljs-number">0</span>) {</pre></div></div>
-
- </li>
-
-
- <li id="section-41">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-41">&#182;</a>
- </div>
- <p>Find the first occurance of any token type in the template</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> found_token = Twig.token.findStart(template);
-
- Twig.log.trace(<span class="hljs-string">"Twig.tokenize: "</span>, <span class="hljs-string">"Found token: "</span>, found_token);
-
- <span class="hljs-keyword">if</span> (found_token.position !== <span class="hljs-literal">null</span>) {</pre></div></div>
-
- </li>
-
-
- <li id="section-42">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-42">&#182;</a>
- </div>
- <p>Add a raw type token for anything before the start of the token</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> (found_token.position &gt; <span class="hljs-number">0</span>) {
- tokens.push({
- type: Twig.token.type.raw,
- value: template.substring(<span class="hljs-number">0</span>, found_token.position)
- });
- }
- template = template.substr(found_token.position + found_token.def.open.length);
- error_offset += found_token.position + found_token.def.open.length;</pre></div></div>
-
- </li>
-
-
- <li id="section-43">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-43">&#182;</a>
- </div>
- <p>Find the end of the token</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> end = Twig.token.findEnd(template, found_token.def, error_offset);
-
- Twig.log.trace(<span class="hljs-string">"Twig.tokenize: "</span>, <span class="hljs-string">"Token ends at "</span>, end);
-
- tokens.push({
- type: found_token.def.type,
- value: template.substring(<span class="hljs-number">0</span>, end).trim()
- });
-
- <span class="hljs-keyword">if</span> (template.substr( end + found_token.def.close.length, <span class="hljs-number">1</span> ) === <span class="hljs-string">"\n"</span>) {
- <span class="hljs-keyword">switch</span> (found_token.def.type) {
- <span class="hljs-keyword">case</span> <span class="hljs-string">"logic_whitespace_pre"</span>:
- <span class="hljs-keyword">case</span> <span class="hljs-string">"logic_whitespace_post"</span>:
- <span class="hljs-keyword">case</span> <span class="hljs-string">"logic_whitespace_both"</span>:
- <span class="hljs-keyword">case</span> <span class="hljs-string">"logic"</span>:</pre></div></div>
-
- </li>
-
-
- <li id="section-44">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-44">&#182;</a>
- </div>
- <p>Newlines directly after logic tokens are ignored</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> end += <span class="hljs-number">1</span>;
- <span class="hljs-keyword">break</span>;
- }
- }
-
- template = template.substr(end + found_token.def.close.length);</pre></div></div>
-
- </li>
-
-
- <li id="section-45">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-45">&#182;</a>
- </div>
- <p>Increment the position in the template</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> error_offset += end + found_token.def.close.length;
-
- } <span class="hljs-keyword">else</span> {</pre></div></div>
-
- </li>
-
-
- <li id="section-46">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-46">&#182;</a>
- </div>
- <p>No more tokens -&gt; add the rest of the template as a raw-type token</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> tokens.push({
- type: Twig.token.type.raw,
- value: template
- });
- template = <span class="hljs-string">''</span>;
- }
- }
-
- <span class="hljs-keyword">return</span> tokens;
- };
-
-
- Twig.compile = <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">tokens</span>) </span>{
- <span class="hljs-keyword">try</span> {</pre></div></div>
-
- </li>
-
-
- <li id="section-47">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-47">&#182;</a>
- </div>
- <p>Output and intermediate stacks</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">var</span> output = [],
- stack = [],</pre></div></div>
-
- </li>
-
-
- <li id="section-48">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-48">&#182;</a>
- </div>
- <p>The tokens between open and close tags</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> intermediate_output = [],
-
- token = <span class="hljs-literal">null</span>,
- logic_token = <span class="hljs-literal">null</span>,
- unclosed_token = <span class="hljs-literal">null</span>,</pre></div></div>
-
- </li>
-
-
- <li id="section-49">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-49">&#182;</a>
- </div>
- <p>Temporary previous token.</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> prev_token = <span class="hljs-literal">null</span>,</pre></div></div>
-
- </li>
-
-
- <li id="section-50">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-50">&#182;</a>
- </div>
- <p>Temporary previous output.</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> prev_output = <span class="hljs-literal">null</span>,</pre></div></div>
-
- </li>
-
-
- <li id="section-51">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-51">&#182;</a>
- </div>
- <p>Temporary previous intermediate output.</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> prev_intermediate_output = <span class="hljs-literal">null</span>,</pre></div></div>
-
- </li>
-
-
- <li id="section-52">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-52">&#182;</a>
- </div>
- <p>The previous token’s template</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> prev_template = <span class="hljs-literal">null</span>,</pre></div></div>
-
- </li>
-
-
- <li id="section-53">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-53">&#182;</a>
- </div>
- <p>Token lookahead</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> next_token = <span class="hljs-literal">null</span>,</pre></div></div>
-
- </li>
-
-
- <li id="section-54">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-54">&#182;</a>
- </div>
- <p>The output token</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> tok_output = <span class="hljs-literal">null</span>,</pre></div></div>
-
- </li>
-
-
- <li id="section-55">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-55">&#182;</a>
- </div>
- <p>Logic Token values</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> type = <span class="hljs-literal">null</span>,
- open = <span class="hljs-literal">null</span>,
- next = <span class="hljs-literal">null</span>;
-
- <span class="hljs-keyword">var</span> compile_output = <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">token</span>) </span>{
- Twig.expression.compile.apply(<span class="hljs-keyword">this</span>, [token]);
- <span class="hljs-keyword">if</span> (stack.length &gt; <span class="hljs-number">0</span>) {
- intermediate_output.push(token);
- } <span class="hljs-keyword">else</span> {
- output.push(token);
- }
- };
-
- <span class="hljs-keyword">var</span> compile_logic = <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">token</span>) </span>{</pre></div></div>
-
- </li>
-
-
- <li id="section-56">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-56">&#182;</a>
- </div>
- <p>Compile the logic token</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> logic_token = Twig.logic.compile.apply(<span class="hljs-keyword">this</span>, [token]);
-
- type = logic_token.type;
- open = Twig.logic.handler[type].open;
- next = Twig.logic.handler[type].next;
-
- Twig.log.trace(<span class="hljs-string">"Twig.compile: "</span>, <span class="hljs-string">"Compiled logic token to "</span>, logic_token,
- <span class="hljs-string">" next is: "</span>, next, <span class="hljs-string">" open is : "</span>, open);</pre></div></div>
-
- </li>
-
-
- <li id="section-57">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-57">&#182;</a>
- </div>
- <p>Not a standalone token, check logic stack to see if this is expected</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> (open !== <span class="hljs-literal">undefined</span> &amp;&amp; !open) {
- prev_token = stack.pop();
- prev_template = Twig.logic.handler[prev_token.type];
-
- <span class="hljs-keyword">if</span> (Twig.indexOf(prev_template.next, type) &lt; <span class="hljs-number">0</span>) {
- <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Error</span>(type + <span class="hljs-string">" not expected after a "</span> + prev_token.type);
- }
-
- prev_token.output = prev_token.output || [];
-
- prev_token.output = prev_token.output.concat(intermediate_output);
- intermediate_output = [];
-
- tok_output = {
- type: Twig.token.type.logic,
- token: prev_token
- };
- <span class="hljs-keyword">if</span> (stack.length &gt; <span class="hljs-number">0</span>) {
- intermediate_output.push(tok_output);
- } <span class="hljs-keyword">else</span> {
- output.push(tok_output);
- }
- }</pre></div></div>
-
- </li>
-
-
- <li id="section-58">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-58">&#182;</a>
- </div>
- <p>This token requires additional tokens to complete the logic structure.</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> (next !== <span class="hljs-literal">undefined</span> &amp;&amp; next.length &gt; <span class="hljs-number">0</span>) {
- Twig.log.trace(<span class="hljs-string">"Twig.compile: "</span>, <span class="hljs-string">"Pushing "</span>, logic_token, <span class="hljs-string">" to logic stack."</span>);
-
- <span class="hljs-keyword">if</span> (stack.length &gt; <span class="hljs-number">0</span>) {</pre></div></div>
-
- </li>
-
-
- <li id="section-59">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-59">&#182;</a>
- </div>
- <p>Put any currently held output into the output list of the logic operator
-currently at the head of the stack before we push a new one on.</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> prev_token = stack.pop();
- prev_token.output = prev_token.output || [];
- prev_token.output = prev_token.output.concat(intermediate_output);
- stack.push(prev_token);
- intermediate_output = [];
- }</pre></div></div>
-
- </li>
-
-
- <li id="section-60">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-60">&#182;</a>
- </div>
- <p>Push the new logic token onto the logic stack</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> stack.push(logic_token);
-
- } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (open !== <span class="hljs-literal">undefined</span> &amp;&amp; open) {
- tok_output = {
- type: Twig.token.type.logic,
- token: logic_token
- };</pre></div></div>
-
- </li>
-
-
- <li id="section-61">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-61">&#182;</a>
- </div>
- <p>Standalone token (like {% set … %}</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> (stack.length &gt; <span class="hljs-number">0</span>) {
- intermediate_output.push(tok_output);
- } <span class="hljs-keyword">else</span> {
- output.push(tok_output);
- }
- }
- };
-
- <span class="hljs-keyword">while</span> (tokens.length &gt; <span class="hljs-number">0</span>) {
- token = tokens.shift();
- prev_output = output[output.length - <span class="hljs-number">1</span>];
- prev_intermediate_output = intermediate_output[intermediate_output.length - <span class="hljs-number">1</span>];
- next_token = tokens[<span class="hljs-number">0</span>];
- Twig.log.trace(<span class="hljs-string">"Compiling token "</span>, token);
- <span class="hljs-keyword">switch</span> (token.type) {
- <span class="hljs-keyword">case</span> Twig.token.type.raw:
- <span class="hljs-keyword">if</span> (stack.length &gt; <span class="hljs-number">0</span>) {
- intermediate_output.push(token);
- } <span class="hljs-keyword">else</span> {
- output.push(token);
- }
- <span class="hljs-keyword">break</span>;
-
- <span class="hljs-keyword">case</span> Twig.token.type.logic:
- compile_logic.call(<span class="hljs-keyword">this</span>, token);
- <span class="hljs-keyword">break</span>;</pre></div></div>
-
- </li>
-
-
- <li id="section-62">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-62">&#182;</a>
- </div>
- <p>Do nothing, comments should be ignored</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">case</span> Twig.token.type.comment:
- <span class="hljs-keyword">break</span>;
-
- <span class="hljs-keyword">case</span> Twig.token.type.output:
- compile_output.call(<span class="hljs-keyword">this</span>, token);
- <span class="hljs-keyword">break</span>;</pre></div></div>
-
- </li>
-
-
- <li id="section-63">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-63">&#182;</a>
- </div>
- <p>Kill whitespace ahead and behind this token</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">case</span> Twig.token.type.logic_whitespace_pre:
- <span class="hljs-keyword">case</span> Twig.token.type.logic_whitespace_post:
- <span class="hljs-keyword">case</span> Twig.token.type.logic_whitespace_both:
- <span class="hljs-keyword">case</span> Twig.token.type.output_whitespace_pre:
- <span class="hljs-keyword">case</span> Twig.token.type.output_whitespace_post:
- <span class="hljs-keyword">case</span> Twig.token.type.output_whitespace_both:
- <span class="hljs-keyword">if</span> (token.type !== Twig.token.type.output_whitespace_post &amp;&amp; token.type !== Twig.token.type.logic_whitespace_post) {
- <span class="hljs-keyword">if</span> (prev_output) {</pre></div></div>
-
- </li>
-
-
- <li id="section-64">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-64">&#182;</a>
- </div>
- <p>If the previous output is raw, pop it off</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> (prev_output.type === Twig.token.type.raw) {
- output.pop();</pre></div></div>
-
- </li>
-
-
- <li id="section-65">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-65">&#182;</a>
- </div>
- <p>If the previous output is not just whitespace, trim it</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> (prev_output.value.match(<span class="hljs-regexp">/^\s*$/</span>) === <span class="hljs-literal">null</span>) {
- prev_output.value = prev_output.value.trim();</pre></div></div>
-
- </li>
-
-
- <li id="section-66">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-66">&#182;</a>
- </div>
- <p>Repush the previous output</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> output.push(prev_output);
- }
- }
- }
-
- <span class="hljs-keyword">if</span> (prev_intermediate_output) {</pre></div></div>
-
- </li>
-
-
- <li id="section-67">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-67">&#182;</a>
- </div>
- <p>If the previous intermediate output is raw, pop it off</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> (prev_intermediate_output.type === Twig.token.type.raw) {
- intermediate_output.pop();</pre></div></div>
-
- </li>
-
-
- <li id="section-68">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-68">&#182;</a>
- </div>
- <p>If the previous output is not just whitespace, trim it</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> (prev_intermediate_output.value.match(<span class="hljs-regexp">/^\s*$/</span>) === <span class="hljs-literal">null</span>) {
- prev_intermediate_output.value = prev_intermediate_output.value.trim();</pre></div></div>
-
- </li>
-
-
- <li id="section-69">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-69">&#182;</a>
- </div>
- <p>Repush the previous intermediate output</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> intermediate_output.push(prev_intermediate_output);
- }
- }
- }
- }</pre></div></div>
-
- </li>
-
-
- <li id="section-70">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-70">&#182;</a>
- </div>
- <p>Compile this token</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">switch</span> (token.type) {
- <span class="hljs-keyword">case</span> Twig.token.type.output_whitespace_pre:
- <span class="hljs-keyword">case</span> Twig.token.type.output_whitespace_post:
- <span class="hljs-keyword">case</span> Twig.token.type.output_whitespace_both:
- compile_output.call(<span class="hljs-keyword">this</span>, token);
- <span class="hljs-keyword">break</span>;
- <span class="hljs-keyword">case</span> Twig.token.type.logic_whitespace_pre:
- <span class="hljs-keyword">case</span> Twig.token.type.logic_whitespace_post:
- <span class="hljs-keyword">case</span> Twig.token.type.logic_whitespace_both:
- compile_logic.call(<span class="hljs-keyword">this</span>, token);
- <span class="hljs-keyword">break</span>;
- }
-
- <span class="hljs-keyword">if</span> (token.type !== Twig.token.type.output_whitespace_pre &amp;&amp; token.type !== Twig.token.type.logic_whitespace_pre) {
- <span class="hljs-keyword">if</span> (next_token) {</pre></div></div>
-
- </li>
-
-
- <li id="section-71">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-71">&#182;</a>
- </div>
- <p>If the next token is raw, shift it out</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> (next_token.type === Twig.token.type.raw) {
- tokens.shift();</pre></div></div>
-
- </li>
-
-
- <li id="section-72">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-72">&#182;</a>
- </div>
- <p>If the next token is not just whitespace, trim it</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> (next_token.value.match(<span class="hljs-regexp">/^\s*$/</span>) === <span class="hljs-literal">null</span>) {
- next_token.value = next_token.value.trim();</pre></div></div>
-
- </li>
-
-
- <li id="section-73">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-73">&#182;</a>
- </div>
- <p>Unshift the next token</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> tokens.unshift(next_token);
- }
- }
- }
- }
-
- <span class="hljs-keyword">break</span>;
- }
-
- Twig.log.trace(<span class="hljs-string">"Twig.compile: "</span>, <span class="hljs-string">" Output: "</span>, output,
- <span class="hljs-string">" Logic Stack: "</span>, stack,
- <span class="hljs-string">" Pending Output: "</span>, intermediate_output );
- }</pre></div></div>
-
- </li>
-
-
- <li id="section-74">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-74">&#182;</a>
- </div>
- <p>Verify that there are no logic tokens left in the stack.</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> (stack.length &gt; <span class="hljs-number">0</span>) {
- unclosed_token = stack.pop();
- <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Error</span>(<span class="hljs-string">"Unable to find an end tag for "</span> + unclosed_token.type +
- <span class="hljs-string">", expecting one of "</span> + unclosed_token.next);
- }
- <span class="hljs-keyword">return</span> output;
- } <span class="hljs-keyword">catch</span> (ex) {
- Twig.log.error(<span class="hljs-string">"Error compiling twig template "</span> + <span class="hljs-keyword">this</span>.id + <span class="hljs-string">": "</span>);
- <span class="hljs-keyword">if</span> (ex.stack) {
- Twig.log.error(ex.stack);
- } <span class="hljs-keyword">else</span> {
- Twig.log.error(ex.toString());
- }
-
- <span class="hljs-keyword">if</span> (<span class="hljs-keyword">this</span>.options.rethrow) <span class="hljs-keyword">throw</span> ex;
- }
- };
-
- <span class="hljs-comment">/**
- * Parse a compiled template.
- *
- * @param {Array} tokens The compiled tokens.
- * @param {Object} context The render context.
- *
- * @return {string} The parsed template.
- */</span>
- Twig.parse = <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">tokens, context</span>) </span>{
- <span class="hljs-keyword">try</span> {
- <span class="hljs-keyword">var</span> output = [],</pre></div></div>
-
- </li>
-
-
- <li id="section-75">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-75">&#182;</a>
- </div>
- <p>Track logic chains</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> chain = <span class="hljs-literal">true</span>,
- that = <span class="hljs-keyword">this</span>;
-
- Twig.forEach(tokens, <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">parseToken</span>(<span class="hljs-params">token</span>) </span>{
- Twig.log.debug(<span class="hljs-string">"Twig.parse: "</span>, <span class="hljs-string">"Parsing token: "</span>, token);
-
- <span class="hljs-keyword">switch</span> (token.type) {
- <span class="hljs-keyword">case</span> Twig.token.type.raw:
- output.push(Twig.filters.raw(token.value));
- <span class="hljs-keyword">break</span>;
-
- <span class="hljs-keyword">case</span> Twig.token.type.logic:
- <span class="hljs-keyword">var</span> logic_token = token.token,
- logic = Twig.logic.parse.apply(that, [logic_token, context, chain]);
-
- <span class="hljs-keyword">if</span> (logic.chain !== <span class="hljs-literal">undefined</span>) {
- chain = logic.chain;
- }
- <span class="hljs-keyword">if</span> (logic.context !== <span class="hljs-literal">undefined</span>) {
- context = logic.context;
- }
- <span class="hljs-keyword">if</span> (logic.output !== <span class="hljs-literal">undefined</span>) {
- output.push(logic.output);
- }
- <span class="hljs-keyword">break</span>;
-
- <span class="hljs-keyword">case</span> Twig.token.type.comment:</pre></div></div>
-
- </li>
-
-
- <li id="section-76">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-76">&#182;</a>
- </div>
- <p>Do nothing, comments should be ignored</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">break</span>;</pre></div></div>
-
- </li>
-
-
- <li id="section-77">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-77">&#182;</a>
- </div>
- <p>Fall through whitespace to output</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">case</span> Twig.token.type.output_whitespace_pre:
- <span class="hljs-keyword">case</span> Twig.token.type.output_whitespace_post:
- <span class="hljs-keyword">case</span> Twig.token.type.output_whitespace_both:
- <span class="hljs-keyword">case</span> Twig.token.type.output:
- Twig.log.debug(<span class="hljs-string">"Twig.parse: "</span>, <span class="hljs-string">"Output token: "</span>, token.stack);</pre></div></div>
-
- </li>
-
-
- <li id="section-78">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-78">&#182;</a>
- </div>
- <p>Parse the given expression in the given context</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> output.push(Twig.expression.parse.apply(that, [token.stack, context]));
- <span class="hljs-keyword">break</span>;
- }
- });
- <span class="hljs-keyword">return</span> Twig.output.apply(<span class="hljs-keyword">this</span>, [output]);
- } <span class="hljs-keyword">catch</span> (ex) {
- Twig.log.error(<span class="hljs-string">"Error parsing twig template "</span> + <span class="hljs-keyword">this</span>.id + <span class="hljs-string">": "</span>);
- <span class="hljs-keyword">if</span> (ex.stack) {
- Twig.log.error(ex.stack);
- } <span class="hljs-keyword">else</span> {
- Twig.log.error(ex.toString());
- }
-
- <span class="hljs-keyword">if</span> (<span class="hljs-keyword">this</span>.options.rethrow) <span class="hljs-keyword">throw</span> ex;
-
- <span class="hljs-keyword">if</span> (Twig.debug) {
- <span class="hljs-keyword">return</span> ex.toString();
- }
- }
- };
-
- <span class="hljs-comment">/**
- * Tokenize and compile a string template.
- *
- * @param {string} data The template.
- *
- * @return {Array} The compiled tokens.
- */</span>
- Twig.prepare = <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">data</span>) </span>{
- <span class="hljs-keyword">var</span> tokens, raw_tokens;</pre></div></div>
-
- </li>
-
-
- <li id="section-79">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-79">&#182;</a>
- </div>
- <p>Tokenize</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> Twig.log.debug(<span class="hljs-string">"Twig.prepare: "</span>, <span class="hljs-string">"Tokenizing "</span>, data);
- raw_tokens = Twig.tokenize.apply(<span class="hljs-keyword">this</span>, [data]);</pre></div></div>
-
- </li>
-
-
- <li id="section-80">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-80">&#182;</a>
- </div>
- <p>Compile</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> Twig.log.debug(<span class="hljs-string">"Twig.prepare: "</span>, <span class="hljs-string">"Compiling "</span>, raw_tokens);
- tokens = Twig.compile.apply(<span class="hljs-keyword">this</span>, [raw_tokens]);
-
- Twig.log.debug(<span class="hljs-string">"Twig.prepare: "</span>, <span class="hljs-string">"Compiled "</span>, tokens);
-
- <span class="hljs-keyword">return</span> tokens;
- };
-
- <span class="hljs-comment">/**
- * Join the output token's stack and escape it if needed
- *
- * @param {Array} Output token's stack
- *
- * @return {string|String} Autoescaped output
- */</span>
- Twig.output = <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">output</span>) </span>{
- <span class="hljs-keyword">if</span> (!<span class="hljs-keyword">this</span>.options.autoescape) {
- <span class="hljs-keyword">return</span> output.join(<span class="hljs-string">""</span>);
- }
-
- <span class="hljs-keyword">var</span> strategy = <span class="hljs-string">'html'</span>;
- <span class="hljs-keyword">if</span>(<span class="hljs-keyword">typeof</span> <span class="hljs-keyword">this</span>.options.autoescape == <span class="hljs-string">'string'</span>)
- strategy = <span class="hljs-keyword">this</span>.options.autoescape;</pre></div></div>
-
- </li>
-
-
- <li id="section-81">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-81">&#182;</a>
- </div>
- <p>[].map would be better but it’s not supported by IE8-</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">var</span> escaped_output = [];
- Twig.forEach(output, <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">str</span>) </span>{
- <span class="hljs-keyword">if</span> (str &amp;&amp; (str.twig_markup !== <span class="hljs-literal">true</span> &amp;&amp; str.twig_markup != strategy)) {
- str = Twig.filters.escape(str, [ strategy ]);
- }
- escaped_output.push(str);
- });
- <span class="hljs-keyword">return</span> Twig.Markup(escaped_output.join(<span class="hljs-string">""</span>));
- }</pre></div></div>
-
- </li>
-
-
- <li id="section-82">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-82">&#182;</a>
- </div>
- <p>Namespace for template storage and retrieval</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> Twig.Templates = {
- <span class="hljs-comment">/**
- * Registered template loaders - use Twig.Templates.registerLoader to add supported loaders
- * @type {Object}
- */</span>
- loaders: {},
-
- <span class="hljs-comment">/**
- * Registered template parsers - use Twig.Templates.registerParser to add supported parsers
- * @type {Object}
- */</span>
- parsers: {},
-
- <span class="hljs-comment">/**
- * Cached / loaded templates
- * @type {Object}
- */</span>
- registry: {}
- };
-
- <span class="hljs-comment">/**
- * Is this id valid for a twig template?
- *
- * @param {string} id The ID to check.
- *
- * @throws {Twig.Error} If the ID is invalid or used.
- * @return {boolean} True if the ID is valid.
- */</span>
- Twig.validateId = <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">id</span>) </span>{
- <span class="hljs-keyword">if</span> (id === <span class="hljs-string">"prototype"</span>) {
- <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> Twig.Error(id + <span class="hljs-string">" is not a valid twig identifier"</span>);
- } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (Twig.cache &amp;&amp; Twig.Templates.registry.hasOwnProperty(id)) {
- <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> Twig.Error(<span class="hljs-string">"There is already a template with the ID "</span> + id);
- }
- <span class="hljs-keyword">return</span> <span class="hljs-literal">true</span>;
- }
-
- <span class="hljs-comment">/**
- * Register a template loader
- *
- * @example
- * Twig.extend(function(Twig) {
- * Twig.Templates.registerLoader('custom_loader', function(location, params, callback, error_callback) {
- * // ... load the template ...
- * params.data = loadedTemplateData;
- * // create and return the template
- * var template = new Twig.Template(params);
- * if (typeof callback === 'function') {
- * callback(template);
- * }
- * return template;
- * });
- * });
- *
- * @param {String} method_name The method this loader is intended for (ajax, fs)
- * @param {Function} func The function to execute when loading the template
- * @param {Object|undefined} scope Optional scope parameter to bind func to
- *
- * @throws Twig.Error
- *
- * @return {void}
- */</span>
- Twig.Templates.registerLoader = <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">method_name, func, scope</span>) </span>{
- <span class="hljs-keyword">if</span> (<span class="hljs-keyword">typeof</span> func !== <span class="hljs-string">'function'</span>) {
- <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> Twig.Error(<span class="hljs-string">'Unable to add loader for '</span> + method_name + <span class="hljs-string">': Invalid function reference given.'</span>);
- }
- <span class="hljs-keyword">if</span> (scope) {
- func = func.bind(scope);
- }
- <span class="hljs-keyword">this</span>.loaders[method_name] = func;
- };
-
- <span class="hljs-comment">/**
- * Remove a registered loader
- *
- * @param {String} method_name The method name for the loader you wish to remove
- *
- * @return {void}
- */</span>
- Twig.Templates.unRegisterLoader = <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">method_name</span>) </span>{
- <span class="hljs-keyword">if</span> (<span class="hljs-keyword">this</span>.isRegisteredLoader(method_name)) {
- <span class="hljs-keyword">delete</span> <span class="hljs-keyword">this</span>.loaders[method_name];
- }
- };
-
- <span class="hljs-comment">/**
- * See if a loader is registered by its method name
- *
- * @param {String} method_name The name of the loader you are looking for
- *
- * @return {boolean}
- */</span>
- Twig.Templates.isRegisteredLoader = <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">method_name</span>) </span>{
- <span class="hljs-keyword">return</span> <span class="hljs-keyword">this</span>.loaders.hasOwnProperty(method_name);
- };
-
- <span class="hljs-comment">/**
- * Register a template parser
- *
- * @example
- * Twig.extend(function(Twig) {
- * Twig.Templates.registerParser('custom_parser', function(params) {
- * // this template source can be accessed in params.data
- * var template = params.data
- *
- * // ... custom process that modifies the template
- *
- * // return the parsed template
- * return template;
- * });
- * });
- *
- * @param {String} method_name The method this parser is intended for (twig, source)
- * @param {Function} func The function to execute when parsing the template
- * @param {Object|undefined} scope Optional scope parameter to bind func to
- *
- * @throws Twig.Error
- *
- * @return {void}
- */</span>
- Twig.Templates.registerParser = <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">method_name, func, scope</span>) </span>{
- <span class="hljs-keyword">if</span> (<span class="hljs-keyword">typeof</span> func !== <span class="hljs-string">'function'</span>) {
- <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> Twig.Error(<span class="hljs-string">'Unable to add parser for '</span> + method_name + <span class="hljs-string">': Invalid function regerence given.'</span>);
- }
-
- <span class="hljs-keyword">if</span> (scope) {
- func = func.bind(scope);
- }
-
- <span class="hljs-keyword">this</span>.parsers[method_name] = func;
- };
-
- <span class="hljs-comment">/**
- * Remove a registered parser
- *
- * @param {String} method_name The method name for the parser you wish to remove
- *
- * @return {void}
- */</span>
- Twig.Templates.unRegisterParser = <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">method_name</span>) </span>{
- <span class="hljs-keyword">if</span> (<span class="hljs-keyword">this</span>.isRegisteredParser(method_name)) {
- <span class="hljs-keyword">delete</span> <span class="hljs-keyword">this</span>.parsers[method_name];
- }
- };
-
- <span class="hljs-comment">/**
- * See if a parser is registered by its method name
- *
- * @param {String} method_name The name of the parser you are looking for
- *
- * @return {boolean}
- */</span>
- Twig.Templates.isRegisteredParser = <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">method_name</span>) </span>{
- <span class="hljs-keyword">return</span> <span class="hljs-keyword">this</span>.parsers.hasOwnProperty(method_name);
- };
-
- <span class="hljs-comment">/**
- * Save a template object to the store.
- *
- * @param {Twig.Template} template The twig.js template to store.
- */</span>
- Twig.Templates.save = <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">template</span>) </span>{
- <span class="hljs-keyword">if</span> (template.id === <span class="hljs-literal">undefined</span>) {
- <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> Twig.Error(<span class="hljs-string">"Unable to save template with no id"</span>);
- }
- Twig.Templates.registry[template.id] = template;
- };
-
- <span class="hljs-comment">/**
- * Load a previously saved template from the store.
- *
- * @param {string} id The ID of the template to load.
- *
- * @return {Twig.Template} A twig.js template stored with the provided ID.
- */</span>
- Twig.Templates.load = <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">id</span>) </span>{
- <span class="hljs-keyword">if</span> (!Twig.Templates.registry.hasOwnProperty(id)) {
- <span class="hljs-keyword">return</span> <span class="hljs-literal">null</span>;
- }
- <span class="hljs-keyword">return</span> Twig.Templates.registry[id];
- };
-
- <span class="hljs-comment">/**
- * Load a template from a remote location using AJAX and saves in with the given ID.
- *
- * Available parameters:
- *
- * async: Should the HTTP request be performed asynchronously.
- * Defaults to true.
- * method: What method should be used to load the template
- * (fs or ajax)
- * parser: What method should be used to parse the template
- * (twig or source)
- * precompiled: Has the template already been compiled.
- *
- * @param {string} location The remote URL to load as a template.
- * @param {Object} params The template parameters.
- * @param {function} callback A callback triggered when the template finishes loading.
- * @param {function} error_callback A callback triggered if an error occurs loading the template.
- *
- *
- */</span>
- Twig.Templates.loadRemote = <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">location, params, callback, error_callback</span>) </span>{
- <span class="hljs-keyword">var</span> loader;</pre></div></div>
-
- </li>
-
-
- <li id="section-83">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-83">&#182;</a>
- </div>
- <p>Default to async</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> (params.async === <span class="hljs-literal">undefined</span>) {
- params.async = <span class="hljs-literal">true</span>;
- }</pre></div></div>
-
- </li>
-
-
- <li id="section-84">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-84">&#182;</a>
- </div>
- <p>Default to the URL so the template is cached.</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> (params.id === <span class="hljs-literal">undefined</span>) {
- params.id = location;
- }</pre></div></div>
-
- </li>
-
-
- <li id="section-85">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-85">&#182;</a>
- </div>
- <p>Check for existing template</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> (Twig.cache &amp;&amp; Twig.Templates.registry.hasOwnProperty(params.id)) {</pre></div></div>
-
- </li>
-
-
- <li id="section-86">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-86">&#182;</a>
- </div>
- <p>A template is already saved with the given id.</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> (<span class="hljs-keyword">typeof</span> callback === <span class="hljs-string">'function'</span>) {
- callback(Twig.Templates.registry[params.id]);
- }</pre></div></div>
-
- </li>
-
-
- <li id="section-87">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-87">&#182;</a>
- </div>
- <p>TODO: if async, return deferred promise</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">return</span> Twig.Templates.registry[params.id];
- }</pre></div></div>
-
- </li>
-
-
- <li id="section-88">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-88">&#182;</a>
- </div>
- <p>if the parser name hasn’t been set, default it to twig</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> params.parser = params.parser || <span class="hljs-string">'twig'</span>;</pre></div></div>
-
- </li>
-
-
- <li id="section-89">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-89">&#182;</a>
- </div>
- <p>Assume ‘fs’ if the loader is not defined</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> loader = <span class="hljs-keyword">this</span>.loaders[params.method] || <span class="hljs-keyword">this</span>.loaders.fs;
- <span class="hljs-keyword">return</span> loader.apply(<span class="hljs-keyword">this</span>, <span class="hljs-built_in">arguments</span>);
- };</pre></div></div>
-
- </li>
-
-
- <li id="section-90">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-90">&#182;</a>
- </div>
- <p>Determine object type</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">is</span>(<span class="hljs-params">type, obj</span>) </span>{
- <span class="hljs-keyword">var</span> clas = <span class="hljs-built_in">Object</span>.prototype.toString.call(obj).slice(<span class="hljs-number">8</span>, <span class="hljs-number">-1</span>);
- <span class="hljs-keyword">return</span> obj !== <span class="hljs-literal">undefined</span> &amp;&amp; obj !== <span class="hljs-literal">null</span> &amp;&amp; clas === type;
- }
-
- <span class="hljs-comment">/**
- * Create a new twig.js template.
- *
- * Parameters: {
- * data: The template, either pre-compiled tokens or a string template
- * id: The name of this template
- * blocks: Any pre-existing block from a child template
- * }
- *
- * @param {Object} params The template parameters.
- */</span>
- Twig.Template = <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params"> params </span>) </span>{
- <span class="hljs-keyword">var</span> data = params.data,
- id = params.id,
- blocks = params.blocks,
- macros = params.macros || {},
- base = params.base,
- path = params.path,
- url = params.url,
- name = params.name,
- method = params.method,</pre></div></div>
-
- </li>
-
-
- <li id="section-91">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-91">&#182;</a>
- </div>
- <p>parser options</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> options = params.options;</pre></div></div>
-
- </li>
-
-
- <li id="section-92">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-92">&#182;</a>
- </div>
- <h1 id="what-is-stored-in-a-twig-template">What is stored in a Twig.Template</h1>
-<p>The Twig Template hold several chucks of data.</p>
-<pre><code>{
- id: The token ID (<span class="hljs-keyword">if</span> any)
- tokens: The list <span class="hljs-keyword">of</span> tokens that makes up <span class="hljs-keyword">this</span> template.
- blocks: The list <span class="hljs-keyword">of</span> block <span class="hljs-keyword">this</span> template contains.
- base: The base template (<span class="hljs-keyword">if</span> any)
- options: {
- Compiler/parser options
-
- strict_variables: <span class="hljs-literal">true</span>/<span class="hljs-literal">false</span>
- Should missing variable/keys emit an error message. If <span class="hljs-literal">false</span>, they <span class="hljs-keyword">default</span> to <span class="hljs-literal">null</span>.
- }
-}
-</code></pre>
- </div>
-
- <div class="content"><div class='highlight'><pre>
- <span class="hljs-keyword">this</span>.id = id;
- <span class="hljs-keyword">this</span>.method = method;
- <span class="hljs-keyword">this</span>.base = base;
- <span class="hljs-keyword">this</span>.path = path;
- <span class="hljs-keyword">this</span>.url = url;
- <span class="hljs-keyword">this</span>.name = name;
- <span class="hljs-keyword">this</span>.macros = macros;
- <span class="hljs-keyword">this</span>.options = options;
-
- <span class="hljs-keyword">this</span>.reset(blocks);
-
- <span class="hljs-keyword">if</span> (is(<span class="hljs-string">'String'</span>, data)) {
- <span class="hljs-keyword">this</span>.tokens = Twig.prepare.apply(<span class="hljs-keyword">this</span>, [data]);
- } <span class="hljs-keyword">else</span> {
- <span class="hljs-keyword">this</span>.tokens = data;
- }
-
- <span class="hljs-keyword">if</span> (id !== <span class="hljs-literal">undefined</span>) {
- Twig.Templates.save(<span class="hljs-keyword">this</span>);
- }
- };
-
- Twig.Template.prototype.reset = <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">blocks</span>) </span>{
- Twig.log.debug(<span class="hljs-string">"Twig.Template.reset"</span>, <span class="hljs-string">"Reseting template "</span> + <span class="hljs-keyword">this</span>.id);
- <span class="hljs-keyword">this</span>.blocks = {};
- <span class="hljs-keyword">this</span>.importedBlocks = [];
- <span class="hljs-keyword">this</span>.originalBlockTokens = {};
- <span class="hljs-keyword">this</span>.child = {
- blocks: blocks || {}
- };
- <span class="hljs-keyword">this</span>.extend = <span class="hljs-literal">null</span>;
- };
-
- Twig.Template.prototype.render = <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">context, params</span>) </span>{
- params = params || {};
-
- <span class="hljs-keyword">var</span> output,
- url;
-
- <span class="hljs-keyword">this</span>.context = context || {};</pre></div></div>
-
- </li>
-
-
- <li id="section-93">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-93">&#182;</a>
- </div>
- <p>Clear any previous state</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">this</span>.reset();
- <span class="hljs-keyword">if</span> (params.blocks) {
- <span class="hljs-keyword">this</span>.blocks = params.blocks;
- }
- <span class="hljs-keyword">if</span> (params.macros) {
- <span class="hljs-keyword">this</span>.macros = params.macros;
- }
-
- output = Twig.parse.apply(<span class="hljs-keyword">this</span>, [<span class="hljs-keyword">this</span>.tokens, <span class="hljs-keyword">this</span>.context]);</pre></div></div>
-
- </li>
-
-
- <li id="section-94">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-94">&#182;</a>
- </div>
- <p>Does this template extend another</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> (<span class="hljs-keyword">this</span>.extend) {
- <span class="hljs-keyword">var</span> ext_template;</pre></div></div>
-
- </li>
-
-
- <li id="section-95">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-95">&#182;</a>
- </div>
- <p>check if the template is provided inline</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> ( <span class="hljs-keyword">this</span>.options.allowInlineIncludes ) {
- ext_template = Twig.Templates.load(<span class="hljs-keyword">this</span>.extend);
- <span class="hljs-keyword">if</span> ( ext_template ) {
- ext_template.options = <span class="hljs-keyword">this</span>.options;
- }
- }</pre></div></div>
-
- </li>
-
-
- <li id="section-96">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-96">&#182;</a>
- </div>
- <p>check for the template file via include</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> (!ext_template) {
- url = Twig.path.parsePath(<span class="hljs-keyword">this</span>, <span class="hljs-keyword">this</span>.extend);
-
- ext_template = Twig.Templates.loadRemote(url, {
- method: <span class="hljs-keyword">this</span>.getLoaderMethod(),
- base: <span class="hljs-keyword">this</span>.base,
- <span class="hljs-keyword">async</span>: <span class="hljs-literal">false</span>,
- id: url,
- options: <span class="hljs-keyword">this</span>.options
- });
- }
-
- <span class="hljs-keyword">this</span>.parent = ext_template;
-
- <span class="hljs-keyword">return</span> <span class="hljs-keyword">this</span>.parent.render(<span class="hljs-keyword">this</span>.context, {
- blocks: <span class="hljs-keyword">this</span>.blocks
- });
- }
-
- <span class="hljs-keyword">if</span> (params.output == <span class="hljs-string">'blocks'</span>) {
- <span class="hljs-keyword">return</span> <span class="hljs-keyword">this</span>.blocks;
- } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (params.output == <span class="hljs-string">'macros'</span>) {
- <span class="hljs-keyword">return</span> <span class="hljs-keyword">this</span>.macros;
- } <span class="hljs-keyword">else</span> {
- <span class="hljs-keyword">return</span> output;
- }
- };
-
- Twig.Template.prototype.importFile = <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">file</span>) </span>{
- <span class="hljs-keyword">var</span> url, sub_template;
- <span class="hljs-keyword">if</span> (!<span class="hljs-keyword">this</span>.url &amp;&amp; <span class="hljs-keyword">this</span>.options.allowInlineIncludes) {
- file = <span class="hljs-keyword">this</span>.path ? <span class="hljs-keyword">this</span>.path + <span class="hljs-string">'/'</span> + file : file;
- sub_template = Twig.Templates.load(file);
-
- <span class="hljs-keyword">if</span> (!sub_template) {
- sub_template = Twig.Templates.loadRemote(url, {
- id: file,
- method: <span class="hljs-keyword">this</span>.getLoaderMethod(),
- <span class="hljs-keyword">async</span>: <span class="hljs-literal">false</span>,
- options: <span class="hljs-keyword">this</span>.options
- });
-
- <span class="hljs-keyword">if</span> (!sub_template) {
- <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> Twig.Error(<span class="hljs-string">"Unable to find the template "</span> + file);
- }
- }
-
- sub_template.options = <span class="hljs-keyword">this</span>.options;
-
- <span class="hljs-keyword">return</span> sub_template;
- }
-
- url = Twig.path.parsePath(<span class="hljs-keyword">this</span>, file);</pre></div></div>
-
- </li>
-
-
- <li id="section-97">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-97">&#182;</a>
- </div>
- <p>Load blocks from an external file</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> sub_template = Twig.Templates.loadRemote(url, {
- method: <span class="hljs-keyword">this</span>.getLoaderMethod(),
- base: <span class="hljs-keyword">this</span>.base,
- <span class="hljs-keyword">async</span>: <span class="hljs-literal">false</span>,
- options: <span class="hljs-keyword">this</span>.options,
- id: url
- });
-
- <span class="hljs-keyword">return</span> sub_template;
- };
-
- Twig.Template.prototype.importBlocks = <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">file, override</span>) </span>{
- <span class="hljs-keyword">var</span> sub_template = <span class="hljs-keyword">this</span>.importFile(file),
- context = <span class="hljs-keyword">this</span>.context,
- that = <span class="hljs-keyword">this</span>,
- key;
-
- override = override || <span class="hljs-literal">false</span>;
-
- sub_template.render(context);</pre></div></div>
-
- </li>
-
-
- <li id="section-98">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-98">&#182;</a>
- </div>
- <p>Mixin blocks</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> Twig.forEach(<span class="hljs-built_in">Object</span>.keys(sub_template.blocks), <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">key</span>) </span>{
- <span class="hljs-keyword">if</span> (override || that.blocks[key] === <span class="hljs-literal">undefined</span>) {
- that.blocks[key] = sub_template.blocks[key];
- that.importedBlocks.push(key);
- }
- });
- };
-
- Twig.Template.prototype.importMacros = <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">file</span>) </span>{
- <span class="hljs-keyword">var</span> url = Twig.path.parsePath(<span class="hljs-keyword">this</span>, file);</pre></div></div>
-
- </li>
-
-
- <li id="section-99">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-99">&#182;</a>
- </div>
- <p>load remote template</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">var</span> remoteTemplate = Twig.Templates.loadRemote(url, {
- method: <span class="hljs-keyword">this</span>.getLoaderMethod(),
- <span class="hljs-keyword">async</span>: <span class="hljs-literal">false</span>,
- id: url
- });
-
- <span class="hljs-keyword">return</span> remoteTemplate;
- };
-
- Twig.Template.prototype.getLoaderMethod = <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) </span>{
- <span class="hljs-keyword">if</span> (<span class="hljs-keyword">this</span>.path) {
- <span class="hljs-keyword">return</span> <span class="hljs-string">'fs'</span>;
- }
- <span class="hljs-keyword">if</span> (<span class="hljs-keyword">this</span>.url) {
- <span class="hljs-keyword">return</span> <span class="hljs-string">'ajax'</span>;
- }
- <span class="hljs-keyword">return</span> <span class="hljs-keyword">this</span>.method || <span class="hljs-string">'fs'</span>;
- };
-
- Twig.Template.prototype.compile = <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">options</span>) </span>{</pre></div></div>
-
- </li>
-
-
- <li id="section-100">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-100">&#182;</a>
- </div>
- <p>compile the template into raw JS</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">return</span> Twig.compiler.compile(<span class="hljs-keyword">this</span>, options);
- };
-
- <span class="hljs-comment">/**
- * Create safe output
- *
- * @param {string} Content safe to output
- *
- * @return {String} Content wrapped into a String
- */</span>
-
- Twig.Markup = <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">content, strategy</span>) </span>{
- <span class="hljs-keyword">if</span>(<span class="hljs-keyword">typeof</span> strategy == <span class="hljs-string">'undefined'</span>) {
- strategy = <span class="hljs-literal">true</span>;
- }
-
- <span class="hljs-keyword">if</span> (<span class="hljs-keyword">typeof</span> content === <span class="hljs-string">'string'</span> &amp;&amp; content.length &gt; <span class="hljs-number">0</span>) {
- content = <span class="hljs-keyword">new</span> <span class="hljs-built_in">String</span>(content);
- content.twig_markup = strategy;
- }
- <span class="hljs-keyword">return</span> content;
- };
-
- <span class="hljs-keyword">return</span> Twig;
-
-}) (Twig || { });
-
-(<span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">Twig</span>) </span>{
-<span class="hljs-meta">
- 'use strict'</span>;
-
- Twig.Templates.registerLoader(<span class="hljs-string">'ajax'</span>, <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">location, params, callback, error_callback</span>) </span>{
- <span class="hljs-keyword">var</span> template,
- xmlhttp,
- precompiled = params.precompiled,
- parser = <span class="hljs-keyword">this</span>.parsers[params.parser] || <span class="hljs-keyword">this</span>.parser.twig;
-
- <span class="hljs-keyword">if</span> (<span class="hljs-keyword">typeof</span> XMLHttpRequest === <span class="hljs-string">"undefined"</span>) {
- <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> Twig.Error(<span class="hljs-string">'Unsupported platform: Unable to do ajax requests '</span> +
- <span class="hljs-string">'because there is no "XMLHTTPRequest" implementation'</span>);
- }
-
- xmlhttp = <span class="hljs-keyword">new</span> XMLHttpRequest();
- xmlhttp.onreadystatechange = <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) </span>{
- <span class="hljs-keyword">var</span> data = <span class="hljs-literal">null</span>;
-
- <span class="hljs-keyword">if</span>(xmlhttp.readyState === <span class="hljs-number">4</span>) {
- <span class="hljs-keyword">if</span> (xmlhttp.status === <span class="hljs-number">200</span> || (<span class="hljs-built_in">window</span>.cordova &amp;&amp; xmlhttp.status == <span class="hljs-number">0</span>)) {
- Twig.log.debug(<span class="hljs-string">"Got template "</span>, xmlhttp.responseText);
-
- <span class="hljs-keyword">if</span> (precompiled === <span class="hljs-literal">true</span>) {
- data = <span class="hljs-built_in">JSON</span>.parse(xmlhttp.responseText);
- } <span class="hljs-keyword">else</span> {
- data = xmlhttp.responseText;
- }
-
- params.url = location;
- params.data = data;
-
- template = parser.call(<span class="hljs-keyword">this</span>, params);
-
- <span class="hljs-keyword">if</span> (<span class="hljs-keyword">typeof</span> callback === <span class="hljs-string">'function'</span>) {
- callback(template);
- }
- } <span class="hljs-keyword">else</span> {
- <span class="hljs-keyword">if</span> (<span class="hljs-keyword">typeof</span> error_callback === <span class="hljs-string">'function'</span>) {
- error_callback(xmlhttp);
- }
- }
- }
- };
- xmlhttp.open(<span class="hljs-string">"GET"</span>, location, !!params.async);
- xmlhttp.send();
-
- <span class="hljs-keyword">if</span> (params.async) {</pre></div></div>
-
- </li>
-
-
- <li id="section-101">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-101">&#182;</a>
- </div>
- <p>TODO: return deferred promise</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">return</span> <span class="hljs-literal">true</span>;
- } <span class="hljs-keyword">else</span> {
- <span class="hljs-keyword">return</span> template;
- }
- });
-
-}(Twig));(<span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">Twig</span>) </span>{
-<span class="hljs-meta"> 'use strict'</span>;
-
- <span class="hljs-keyword">var</span> fs, path;
-
- <span class="hljs-keyword">try</span> {</pre></div></div>
-
- </li>
-
-
- <li id="section-102">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-102">&#182;</a>
- </div>
- <p>require lib dependencies at runtime</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> fs = <span class="hljs-built_in">require</span>(<span class="hljs-string">'fs'</span>);
- path = <span class="hljs-built_in">require</span>(<span class="hljs-string">'path'</span>);
- } <span class="hljs-keyword">catch</span> (e) {</pre></div></div>
-
- </li>
-
-
- <li id="section-103">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-103">&#182;</a>
- </div>
- <p>NOTE: this is in a try/catch to avoid errors cross platform</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> }
-
- Twig.Templates.registerLoader(<span class="hljs-string">'fs'</span>, <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">location, params, callback, error_callback</span>) </span>{
- <span class="hljs-keyword">var</span> template,
- data = <span class="hljs-literal">null</span>,
- precompiled = params.precompiled,
- parser = <span class="hljs-keyword">this</span>.parsers[params.parser] || <span class="hljs-keyword">this</span>.parser.twig;
-
- <span class="hljs-keyword">if</span> (!fs || !path) {
- <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> Twig.Error(<span class="hljs-string">'Unsupported platform: Unable to load from file '</span> +
- <span class="hljs-string">'because there is no "fs" or "path" implementation'</span>);
- }
-
- <span class="hljs-keyword">var</span> loadTemplateFn = <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">err, data</span>) </span>{
- <span class="hljs-keyword">if</span> (err) {
- <span class="hljs-keyword">if</span> (<span class="hljs-keyword">typeof</span> error_callback === <span class="hljs-string">'function'</span>) {
- error_callback(err);
- }
- <span class="hljs-keyword">return</span>;
- }
-
- <span class="hljs-keyword">if</span> (precompiled === <span class="hljs-literal">true</span>) {
- data = <span class="hljs-built_in">JSON</span>.parse(data);
- }
-
- params.data = data;
- params.path = params.path || location;</pre></div></div>
-
- </li>
-
-
- <li id="section-104">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-104">&#182;</a>
- </div>
- <p>template is in data</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> template = parser.call(<span class="hljs-keyword">this</span>, params);
-
- <span class="hljs-keyword">if</span> (<span class="hljs-keyword">typeof</span> callback === <span class="hljs-string">'function'</span>) {
- callback(template);
- }
- };
- params.path = params.path || location;
-
- <span class="hljs-keyword">if</span> (params.async) {
- fs.stat(params.path, <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">err, stats</span>) </span>{
- <span class="hljs-keyword">if</span> (err || !stats.isFile()) {
- <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> Twig.Error(<span class="hljs-string">'Unable to find template file '</span> + location);
- }
- fs.readFile(params.path, <span class="hljs-string">'utf8'</span>, loadTemplateFn);
- });</pre></div></div>
-
- </li>
-
-
- <li id="section-105">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-105">&#182;</a>
- </div>
- <p>TODO: return deferred promise</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">return</span> <span class="hljs-literal">true</span>;
- } <span class="hljs-keyword">else</span> {
- <span class="hljs-keyword">if</span> (!fs.statSync(params.path).isFile()) {
- <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> Twig.Error(<span class="hljs-string">'Unable to find template file '</span> + location);
- }
- data = fs.readFileSync(params.path, <span class="hljs-string">'utf8'</span>);
- loadTemplateFn(<span class="hljs-literal">undefined</span>, data);
- <span class="hljs-keyword">return</span> template
- }
- });
-
-}(Twig));(<span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">Twig</span>)</span>{
-<span class="hljs-meta"> 'use strict'</span>;
-
- Twig.Templates.registerParser(<span class="hljs-string">'source'</span>, <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">params</span>) </span>{
- <span class="hljs-keyword">return</span> params.data || <span class="hljs-string">''</span>;
- });
-})(Twig);
-(<span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">Twig</span>)</span>{
-<span class="hljs-meta"> 'use strict'</span>;
-
- Twig.Templates.registerParser(<span class="hljs-string">'twig'</span>, <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">params</span>) </span>{
- <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> Twig.Template(params);
- });
-})(Twig);</pre></div></div>
-
- </li>
-
-
- <li id="section-106">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-106">&#182;</a>
- </div>
- <p>The following methods are from MDN and are available under a
-<a href="http://www.opensource.org/licenses/mit-license.php">MIT License</a> or are
-<a href="https://developer.mozilla.org/Project:Copyrights">Public Domain</a>.</p>
-<p>See:</p>
-<ul>
-<li><a href="https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Object/keys">Object.keys - MDN</a></li>
-</ul>
-
- </div>
-
- </li>
-
-
- <li id="section-107">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-107">&#182;</a>
- </div>
- <h2 id="twig-fills-js">twig.fills.js</h2>
-<p>This file contains fills for backwards compatability.</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre>(<span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) </span>{
-<span class="hljs-meta"> "use strict"</span>;</pre></div></div>
-
- </li>
-
-
- <li id="section-108">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-108">&#182;</a>
- </div>
- <p>Handle methods that don’t yet exist in every browser</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre>
- <span class="hljs-keyword">if</span> (!<span class="hljs-built_in">String</span>.prototype.trim) {
- <span class="hljs-built_in">String</span>.prototype.trim = <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) </span>{
- <span class="hljs-keyword">return</span> <span class="hljs-keyword">this</span>.replace(<span class="hljs-regexp">/^\s+|\s+$/g</span>,<span class="hljs-string">''</span>);
- }
- };
-
- <span class="hljs-keyword">if</span>(!<span class="hljs-built_in">Object</span>.keys) <span class="hljs-built_in">Object</span>.keys = <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">o</span>)</span>{
- <span class="hljs-keyword">if</span> (o !== <span class="hljs-built_in">Object</span>(o)) {
- <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">TypeError</span>(<span class="hljs-string">'Object.keys called on non-object'</span>);
- }
- <span class="hljs-keyword">var</span> ret = [], p;
- <span class="hljs-keyword">for</span> (p <span class="hljs-keyword">in</span> o) <span class="hljs-keyword">if</span> (<span class="hljs-built_in">Object</span>.prototype.hasOwnProperty.call(o, p)) ret.push(p);
- <span class="hljs-keyword">return</span> ret;
- }
-
-})();</pre></div></div>
-
- </li>
-
-
- <li id="section-109">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-109">&#182;</a>
- </div>
- <h2 id="twig-lib-js">twig.lib.js</h2>
-<p>This file contains 3rd party libraries used within twig.</p>
-<p>Copies of the licenses for the code included here can be found in the
-LICENSES.md file.</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre>
-<span class="hljs-keyword">var</span> Twig = (<span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">Twig</span>) </span>{</pre></div></div>
-
- </li>
-
-
- <li id="section-110">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-110">&#182;</a>
- </div>
- <p>Namespace for libraries</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> Twig.lib = { };
-
- <span class="hljs-comment">/**
- sprintf() for JavaScript 1.0.3
- https://github.com/alexei/sprintf.js
- **/</span>
- <span class="hljs-keyword">var</span> sprintfLib = (<span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) </span>{
- <span class="hljs-keyword">var</span> re = {
- not_string: <span class="hljs-regexp">/[^s]/</span>,
- number: <span class="hljs-regexp">/[diefg]/</span>,
- json: <span class="hljs-regexp">/[j]/</span>,
- not_json: <span class="hljs-regexp">/[^j]/</span>,
- text: <span class="hljs-regexp">/^[^\x25]+/</span>,
- modulo: <span class="hljs-regexp">/^\x25{2}/</span>,
- placeholder: <span class="hljs-regexp">/^\x25(?:([1-9]\d*)\$|\(([^\)]+)\))?(\+)?(0|'[^$])?(-)?(\d+)?(?:\.(\d+))?([b-gijosuxX])/</span>,
- key: <span class="hljs-regexp">/^([a-z_][a-z_\d]*)/i</span>,
- key_access: <span class="hljs-regexp">/^\.([a-z_][a-z_\d]*)/i</span>,
- index_access: <span class="hljs-regexp">/^\[(\d+)\]/</span>,
- sign: <span class="hljs-regexp">/^[\+\-]/</span>
- }
-
- <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">sprintf</span>(<span class="hljs-params"></span>) </span>{
- <span class="hljs-keyword">var</span> key = <span class="hljs-built_in">arguments</span>[<span class="hljs-number">0</span>], cache = sprintf.cache
- <span class="hljs-keyword">if</span> (!(cache[key] &amp;&amp; cache.hasOwnProperty(key))) {
- cache[key] = sprintf.parse(key)
- }
- <span class="hljs-keyword">return</span> sprintf.format.call(<span class="hljs-literal">null</span>, cache[key], <span class="hljs-built_in">arguments</span>)
- }
-
- sprintf.format = <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">parse_tree, argv</span>) </span>{
- <span class="hljs-keyword">var</span> cursor = <span class="hljs-number">1</span>, tree_length = parse_tree.length, node_type = <span class="hljs-string">""</span>, arg, output = [], i, k, match, pad, pad_character, pad_length, is_positive = <span class="hljs-literal">true</span>, sign = <span class="hljs-string">""</span>
- <span class="hljs-keyword">for</span> (i = <span class="hljs-number">0</span>; i &lt; tree_length; i++) {
- node_type = get_type(parse_tree[i])
- <span class="hljs-keyword">if</span> (node_type === <span class="hljs-string">"string"</span>) {
- output[output.length] = parse_tree[i]
- }
- <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (node_type === <span class="hljs-string">"array"</span>) {
- match = parse_tree[i] <span class="hljs-comment">// convenience purposes only</span>
- <span class="hljs-keyword">if</span> (match[<span class="hljs-number">2</span>]) { <span class="hljs-comment">// keyword argument</span>
- arg = argv[cursor]
- <span class="hljs-keyword">for</span> (k = <span class="hljs-number">0</span>; k &lt; match[<span class="hljs-number">2</span>].length; k++) {
- <span class="hljs-keyword">if</span> (!arg.hasOwnProperty(match[<span class="hljs-number">2</span>][k])) {
- <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Error</span>(sprintf(<span class="hljs-string">"[sprintf] property '%s' does not exist"</span>, match[<span class="hljs-number">2</span>][k]))
- }
- arg = arg[match[<span class="hljs-number">2</span>][k]]
- }
- }
- <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (match[<span class="hljs-number">1</span>]) { <span class="hljs-comment">// positional argument (explicit)</span>
- arg = argv[match[<span class="hljs-number">1</span>]]
- }
- <span class="hljs-keyword">else</span> { <span class="hljs-comment">// positional argument (implicit)</span>
- arg = argv[cursor++]
- }
-
- <span class="hljs-keyword">if</span> (get_type(arg) == <span class="hljs-string">"function"</span>) {
- arg = arg()
- }
-
- <span class="hljs-keyword">if</span> (re.not_string.test(match[<span class="hljs-number">8</span>]) &amp;&amp; re.not_json.test(match[<span class="hljs-number">8</span>]) &amp;&amp; (get_type(arg) != <span class="hljs-string">"number"</span> &amp;&amp; <span class="hljs-built_in">isNaN</span>(arg))) {
- <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">TypeError</span>(sprintf(<span class="hljs-string">"[sprintf] expecting number but found %s"</span>, get_type(arg)))
- }
-
- <span class="hljs-keyword">if</span> (re.number.test(match[<span class="hljs-number">8</span>])) {
- is_positive = arg &gt;= <span class="hljs-number">0</span>
- }
-
- <span class="hljs-keyword">switch</span> (match[<span class="hljs-number">8</span>]) {
- <span class="hljs-keyword">case</span> <span class="hljs-string">"b"</span>:
- arg = arg.toString(<span class="hljs-number">2</span>)
- <span class="hljs-keyword">break</span>
- <span class="hljs-keyword">case</span> <span class="hljs-string">"c"</span>:
- arg = <span class="hljs-built_in">String</span>.fromCharCode(arg)
- <span class="hljs-keyword">break</span>
- <span class="hljs-keyword">case</span> <span class="hljs-string">"d"</span>:
- <span class="hljs-keyword">case</span> <span class="hljs-string">"i"</span>:
- arg = <span class="hljs-built_in">parseInt</span>(arg, <span class="hljs-number">10</span>)
- <span class="hljs-keyword">break</span>
- <span class="hljs-keyword">case</span> <span class="hljs-string">"j"</span>:
- arg = <span class="hljs-built_in">JSON</span>.stringify(arg, <span class="hljs-literal">null</span>, match[<span class="hljs-number">6</span>] ? <span class="hljs-built_in">parseInt</span>(match[<span class="hljs-number">6</span>]) : <span class="hljs-number">0</span>)
- <span class="hljs-keyword">break</span>
- <span class="hljs-keyword">case</span> <span class="hljs-string">"e"</span>:
- arg = match[<span class="hljs-number">7</span>] ? arg.toExponential(match[<span class="hljs-number">7</span>]) : arg.toExponential()
- <span class="hljs-keyword">break</span>
- <span class="hljs-keyword">case</span> <span class="hljs-string">"f"</span>:
- arg = match[<span class="hljs-number">7</span>] ? <span class="hljs-built_in">parseFloat</span>(arg).toFixed(match[<span class="hljs-number">7</span>]) : <span class="hljs-built_in">parseFloat</span>(arg)
- <span class="hljs-keyword">break</span>
- <span class="hljs-keyword">case</span> <span class="hljs-string">"g"</span>:
- arg = match[<span class="hljs-number">7</span>] ? <span class="hljs-built_in">parseFloat</span>(arg).toPrecision(match[<span class="hljs-number">7</span>]) : <span class="hljs-built_in">parseFloat</span>(arg)
- <span class="hljs-keyword">break</span>
- <span class="hljs-keyword">case</span> <span class="hljs-string">"o"</span>:
- arg = arg.toString(<span class="hljs-number">8</span>)
- <span class="hljs-keyword">break</span>
- <span class="hljs-keyword">case</span> <span class="hljs-string">"s"</span>:
- arg = ((arg = <span class="hljs-built_in">String</span>(arg)) &amp;&amp; match[<span class="hljs-number">7</span>] ? arg.substring(<span class="hljs-number">0</span>, match[<span class="hljs-number">7</span>]) : arg)
- <span class="hljs-keyword">break</span>
- <span class="hljs-keyword">case</span> <span class="hljs-string">"u"</span>:
- arg = arg &gt;&gt;&gt; <span class="hljs-number">0</span>
- <span class="hljs-keyword">break</span>
- <span class="hljs-keyword">case</span> <span class="hljs-string">"x"</span>:
- arg = arg.toString(<span class="hljs-number">16</span>)
- <span class="hljs-keyword">break</span>
- <span class="hljs-keyword">case</span> <span class="hljs-string">"X"</span>:
- arg = arg.toString(<span class="hljs-number">16</span>).toUpperCase()
- <span class="hljs-keyword">break</span>
- }
- <span class="hljs-keyword">if</span> (re.json.test(match[<span class="hljs-number">8</span>])) {
- output[output.length] = arg
- }
- <span class="hljs-keyword">else</span> {
- <span class="hljs-keyword">if</span> (re.number.test(match[<span class="hljs-number">8</span>]) &amp;&amp; (!is_positive || match[<span class="hljs-number">3</span>])) {
- sign = is_positive ? <span class="hljs-string">"+"</span> : <span class="hljs-string">"-"</span>
- arg = arg.toString().replace(re.sign, <span class="hljs-string">""</span>)
- }
- <span class="hljs-keyword">else</span> {
- sign = <span class="hljs-string">""</span>
- }
- pad_character = match[<span class="hljs-number">4</span>] ? match[<span class="hljs-number">4</span>] === <span class="hljs-string">"0"</span> ? <span class="hljs-string">"0"</span> : match[<span class="hljs-number">4</span>].charAt(<span class="hljs-number">1</span>) : <span class="hljs-string">" "</span>
- pad_length = match[<span class="hljs-number">6</span>] - (sign + arg).length
- pad = match[<span class="hljs-number">6</span>] ? (pad_length &gt; <span class="hljs-number">0</span> ? str_repeat(pad_character, pad_length) : <span class="hljs-string">""</span>) : <span class="hljs-string">""</span>
- output[output.length] = match[<span class="hljs-number">5</span>] ? sign + arg + pad : (pad_character === <span class="hljs-string">"0"</span> ? sign + pad + arg : pad + sign + arg)
- }
- }
- }
- <span class="hljs-keyword">return</span> output.join(<span class="hljs-string">""</span>)
- }
-
- sprintf.cache = {}
-
- sprintf.parse = <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">fmt</span>) </span>{
- <span class="hljs-keyword">var</span> _fmt = fmt, match = [], parse_tree = [], arg_names = <span class="hljs-number">0</span>
- <span class="hljs-keyword">while</span> (_fmt) {
- <span class="hljs-keyword">if</span> ((match = re.text.exec(_fmt)) !== <span class="hljs-literal">null</span>) {
- parse_tree[parse_tree.length] = match[<span class="hljs-number">0</span>]
- }
- <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> ((match = re.modulo.exec(_fmt)) !== <span class="hljs-literal">null</span>) {
- parse_tree[parse_tree.length] = <span class="hljs-string">"%"</span>
- }
- <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> ((match = re.placeholder.exec(_fmt)) !== <span class="hljs-literal">null</span>) {
- <span class="hljs-keyword">if</span> (match[<span class="hljs-number">2</span>]) {
- arg_names |= <span class="hljs-number">1</span>
- <span class="hljs-keyword">var</span> field_list = [], replacement_field = match[<span class="hljs-number">2</span>], field_match = []
- <span class="hljs-keyword">if</span> ((field_match = re.key.exec(replacement_field)) !== <span class="hljs-literal">null</span>) {
- field_list[field_list.length] = field_match[<span class="hljs-number">1</span>]
- <span class="hljs-keyword">while</span> ((replacement_field = replacement_field.substring(field_match[<span class="hljs-number">0</span>].length)) !== <span class="hljs-string">""</span>) {
- <span class="hljs-keyword">if</span> ((field_match = re.key_access.exec(replacement_field)) !== <span class="hljs-literal">null</span>) {
- field_list[field_list.length] = field_match[<span class="hljs-number">1</span>]
- }
- <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> ((field_match = re.index_access.exec(replacement_field)) !== <span class="hljs-literal">null</span>) {
- field_list[field_list.length] = field_match[<span class="hljs-number">1</span>]
- }
- <span class="hljs-keyword">else</span> {
- <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">SyntaxError</span>(<span class="hljs-string">"[sprintf] failed to parse named argument key"</span>)
- }
- }
- }
- <span class="hljs-keyword">else</span> {
- <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">SyntaxError</span>(<span class="hljs-string">"[sprintf] failed to parse named argument key"</span>)
- }
- match[<span class="hljs-number">2</span>] = field_list
- }
- <span class="hljs-keyword">else</span> {
- arg_names |= <span class="hljs-number">2</span>
- }
- <span class="hljs-keyword">if</span> (arg_names === <span class="hljs-number">3</span>) {
- <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Error</span>(<span class="hljs-string">"[sprintf] mixing positional and named placeholders is not (yet) supported"</span>)
- }
- parse_tree[parse_tree.length] = match
- }
- <span class="hljs-keyword">else</span> {
- <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">SyntaxError</span>(<span class="hljs-string">"[sprintf] unexpected placeholder"</span>)
- }
- _fmt = _fmt.substring(match[<span class="hljs-number">0</span>].length)
- }
- <span class="hljs-keyword">return</span> parse_tree
- }
-
- <span class="hljs-keyword">var</span> vsprintf = <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">fmt, argv, _argv</span>) </span>{
- _argv = (argv || []).slice(<span class="hljs-number">0</span>)
- _argv.splice(<span class="hljs-number">0</span>, <span class="hljs-number">0</span>, fmt)
- <span class="hljs-keyword">return</span> sprintf.apply(<span class="hljs-literal">null</span>, _argv)
- }
-
- <span class="hljs-comment">/**
- * helpers
- */</span>
- <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">get_type</span>(<span class="hljs-params">variable</span>) </span>{
- <span class="hljs-keyword">return</span> <span class="hljs-built_in">Object</span>.prototype.toString.call(variable).slice(<span class="hljs-number">8</span>, <span class="hljs-number">-1</span>).toLowerCase()
- }
-
- <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">str_repeat</span>(<span class="hljs-params">input, multiplier</span>) </span>{
- <span class="hljs-keyword">return</span> <span class="hljs-built_in">Array</span>(multiplier + <span class="hljs-number">1</span>).join(input)
- }
-
- <span class="hljs-comment">/**
- * export
- */</span>
- <span class="hljs-keyword">return</span> {
- sprintf: sprintf,
- vsprintf: vsprintf
- }
- })();
-
- <span class="hljs-keyword">var</span> sprintf = sprintfLib.sprintf;
- <span class="hljs-keyword">var</span> vsprintf = sprintfLib.vsprintf;</pre></div></div>
-
- </li>
-
-
- <li id="section-111">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-111">&#182;</a>
- </div>
- <p>Expose to Twig</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> Twig.lib.sprintf = sprintf;
- Twig.lib.vsprintf = vsprintf;
-
-
- <span class="hljs-comment">/**
- * jPaq - A fully customizable JavaScript/JScript library
- * http://jpaq.org/
- *
- * Copyright (c) 2011 Christopher West
- * Licensed under the MIT license.
- * http://jpaq.org/license/
- *
- * Version: 1.0.6.0000W
- * Revised: April 6, 2011
- */</span>
- ; (<span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) </span>{
- <span class="hljs-keyword">var</span> shortDays = <span class="hljs-string">"Sun,Mon,Tue,Wed,Thu,Fri,Sat"</span>.split(<span class="hljs-string">","</span>);
- <span class="hljs-keyword">var</span> fullDays = <span class="hljs-string">"Sunday,Monday,Tuesday,Wednesday,Thursday,Friday,Saturday"</span>.split(<span class="hljs-string">","</span>);
- <span class="hljs-keyword">var</span> shortMonths = <span class="hljs-string">"Jan,Feb,Mar,Apr,May,Jun,Jul,Aug,Sep,Oct,Nov,Dec"</span>.split(<span class="hljs-string">","</span>);
- <span class="hljs-keyword">var</span> fullMonths = <span class="hljs-string">"January,February,March,April,May,June,July,August,September,October,November,December"</span>.split(<span class="hljs-string">","</span>);
- <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">getOrdinalFor</span>(<span class="hljs-params">intNum</span>) </span>{
- <span class="hljs-keyword">return</span> (((intNum = <span class="hljs-built_in">Math</span>.abs(intNum) % <span class="hljs-number">100</span>) % <span class="hljs-number">10</span> == <span class="hljs-number">1</span> &amp;&amp; intNum != <span class="hljs-number">11</span>) ? <span class="hljs-string">"st"</span>
- : (intNum % <span class="hljs-number">10</span> == <span class="hljs-number">2</span> &amp;&amp; intNum != <span class="hljs-number">12</span>) ? <span class="hljs-string">"nd"</span> : (intNum % <span class="hljs-number">10</span> == <span class="hljs-number">3</span>
- &amp;&amp; intNum != <span class="hljs-number">13</span>) ? <span class="hljs-string">"rd"</span> : <span class="hljs-string">"th"</span>);
- }
- <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">getISO8601Year</span>(<span class="hljs-params">aDate</span>) </span>{
- <span class="hljs-keyword">var</span> d = <span class="hljs-keyword">new</span> <span class="hljs-built_in">Date</span>(aDate.getFullYear() + <span class="hljs-number">1</span>, <span class="hljs-number">0</span>, <span class="hljs-number">4</span>);
- <span class="hljs-keyword">if</span>((d - aDate) / <span class="hljs-number">86400000</span> &lt; <span class="hljs-number">7</span> &amp;&amp; (aDate.getDay() + <span class="hljs-number">6</span>) % <span class="hljs-number">7</span> &lt; (d.getDay() + <span class="hljs-number">6</span>) % <span class="hljs-number">7</span>)
- <span class="hljs-keyword">return</span> d.getFullYear();
- <span class="hljs-keyword">if</span>(aDate.getMonth() &gt; <span class="hljs-number">0</span> || aDate.getDate() &gt;= <span class="hljs-number">4</span>)
- <span class="hljs-keyword">return</span> aDate.getFullYear();
- <span class="hljs-keyword">return</span> aDate.getFullYear() - (((aDate.getDay() + <span class="hljs-number">6</span>) % <span class="hljs-number">7</span> - aDate.getDate() &gt; <span class="hljs-number">2</span>) ? <span class="hljs-number">1</span> : <span class="hljs-number">0</span>);
- }
- <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">getISO8601Week</span>(<span class="hljs-params">aDate</span>) </span>{</pre></div></div>
-
- </li>
-
-
- <li id="section-112">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-112">&#182;</a>
- </div>
- <p>Get a day during the first week of the year.</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">var</span> d = <span class="hljs-keyword">new</span> <span class="hljs-built_in">Date</span>(getISO8601Year(aDate), <span class="hljs-number">0</span>, <span class="hljs-number">4</span>);</pre></div></div>
-
- </li>
-
-
- <li id="section-113">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-113">&#182;</a>
- </div>
- <p>Get the first monday of the year.</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> d.setDate(d.getDate() - (d.getDay() + <span class="hljs-number">6</span>) % <span class="hljs-number">7</span>);
- <span class="hljs-keyword">return</span> <span class="hljs-built_in">parseInt</span>((aDate - d) / <span class="hljs-number">604800000</span>) + <span class="hljs-number">1</span>;
- }
- Twig.lib.formatDate = <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">date, format</span>) </span>{</pre></div></div>
-
- </li>
-
-
- <li id="section-114">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-114">&#182;</a>
- </div>
- <p>/ <summary>
-/ Gets a string for this date, formatted according to the given format
-/ string.
-/ </summary>
-/ <param name="format" type="String">
-/ The format of the output date string. The format string works in a
-/ nearly identical way to the PHP date function which is highlighted here:
-/ <a href="http://php.net/manual/en/function.date.php">http://php.net/manual/en/function.date.php</a>.
-/ The only difference is the fact that “u” signifies milliseconds
-/ instead of microseconds. The following characters are recognized in
-/ the format parameter string:
-/ d - Day of the month, 2 digits with leading zeros
-/ D - A textual representation of a day, three letters
-/ j - Day of the month without leading zeros
-/ l (lowercase ‘L’) - A full textual representation of the day of the week
-/ N - ISO-8601 numeric representation of the day of the week (starting from 1)
-/ S - English ordinal suffix for the day of the month, 2 characters st,
-/ nd, rd or th. Works well with j.
-/ w - Numeric representation of the day of the week (starting from 0)
-/ z - The day of the year (starting from 0)
-/ W - ISO-8601 week number of year, weeks starting on Monday
-/ F - A full textual representation of a month, such as January or March
-/ m - Numeric representation of a month, with leading zeros
-/ M - A short textual representation of a month, three letters
-/ n - Numeric representation of a month, without leading zeros
-/ t - Number of days in the given month
-/ L - Whether it’s a leap year
-/ o - ISO-8601 year number. This has the same value as Y, except that if
-/ the ISO week number (W) belongs to the previous or next year, that
-/ year is used instead.
-/ Y - A full numeric representation of a year, 4 digits
-/ y - A two digit representation of a year
-/ a - Lowercase Ante meridiem and Post meridiem
-/ A - Uppercase Ante meridiem and Post meridiem
-/ B - Swatch Internet time
-/ g - 12-hour format of an hour without leading zeros
-/ G - 24-hour format of an hour without leading zeros
-/ h - 12-hour format of an hour with leading zeros
-/ H - 24-hour format of an hour with leading zeros
-/ i - Minutes with leading zeros
-/ s - Seconds, with leading zeros
-/ u - Milliseconds
-/ U - Seconds since the Unix Epoch (January 1 1970 00:00:00 GMT)
-/ </param>
-/ <returns type="String">
-/ Returns the string for this date, formatted according to the given
-/ format string.
-/ </returns>
-If the format was not passed, use the default toString method.</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span>(<span class="hljs-keyword">typeof</span> format !== <span class="hljs-string">"string"</span> || <span class="hljs-regexp">/^\s*$/</span>.test(format))
- <span class="hljs-keyword">return</span> date + <span class="hljs-string">""</span>;
- <span class="hljs-keyword">var</span> jan1st = <span class="hljs-keyword">new</span> <span class="hljs-built_in">Date</span>(date.getFullYear(), <span class="hljs-number">0</span>, <span class="hljs-number">1</span>);
- <span class="hljs-keyword">var</span> me = date;
- <span class="hljs-keyword">return</span> format.replace(<span class="hljs-regexp">/[dDjlNSwzWFmMntLoYyaABgGhHisuU]/g</span>, <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">option</span>) </span>{
- <span class="hljs-keyword">switch</span>(option) {</pre></div></div>
-
- </li>
-
-
- <li id="section-115">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-115">&#182;</a>
- </div>
- <p>Day of the month, 2 digits with leading zeros</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">case</span> <span class="hljs-string">"d"</span>: <span class="hljs-keyword">return</span> (<span class="hljs-string">"0"</span> + me.getDate()).replace(<span class="hljs-regexp">/^.+(..)$/</span>, <span class="hljs-string">"$1"</span>);</pre></div></div>
-
- </li>
-
-
- <li id="section-116">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-116">&#182;</a>
- </div>
- <p>A textual representation of a day, three letters</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">case</span> <span class="hljs-string">"D"</span>: <span class="hljs-keyword">return</span> shortDays[me.getDay()];</pre></div></div>
-
- </li>
-
-
- <li id="section-117">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-117">&#182;</a>
- </div>
- <p>Day of the month without leading zeros</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">case</span> <span class="hljs-string">"j"</span>: <span class="hljs-keyword">return</span> me.getDate();</pre></div></div>
-
- </li>
-
-
- <li id="section-118">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-118">&#182;</a>
- </div>
- <p>A full textual representation of the day of the week</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">case</span> <span class="hljs-string">"l"</span>: <span class="hljs-keyword">return</span> fullDays[me.getDay()];</pre></div></div>
-
- </li>
-
-
- <li id="section-119">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-119">&#182;</a>
- </div>
- <p>ISO-8601 numeric representation of the day of the week</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">case</span> <span class="hljs-string">"N"</span>: <span class="hljs-keyword">return</span> (me.getDay() + <span class="hljs-number">6</span>) % <span class="hljs-number">7</span> + <span class="hljs-number">1</span>;</pre></div></div>
-
- </li>
-
-
- <li id="section-120">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-120">&#182;</a>
- </div>
- <p>English ordinal suffix for the day of the month, 2 characters</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">case</span> <span class="hljs-string">"S"</span>: <span class="hljs-keyword">return</span> getOrdinalFor(me.getDate());</pre></div></div>
-
- </li>
-
-
- <li id="section-121">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-121">&#182;</a>
- </div>
- <p>Numeric representation of the day of the week</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">case</span> <span class="hljs-string">"w"</span>: <span class="hljs-keyword">return</span> me.getDay();</pre></div></div>
-
- </li>
-
-
- <li id="section-122">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-122">&#182;</a>
- </div>
- <p>The day of the year (starting from 0)</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">case</span> <span class="hljs-string">"z"</span>: <span class="hljs-keyword">return</span> <span class="hljs-built_in">Math</span>.ceil((jan1st - me) / <span class="hljs-number">86400000</span>);</pre></div></div>
-
- </li>
-
-
- <li id="section-123">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-123">&#182;</a>
- </div>
- <p>ISO-8601 week number of year, weeks starting on Monday</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">case</span> <span class="hljs-string">"W"</span>: <span class="hljs-keyword">return</span> (<span class="hljs-string">"0"</span> + getISO8601Week(me)).replace(<span class="hljs-regexp">/^.(..)$/</span>, <span class="hljs-string">"$1"</span>);</pre></div></div>
-
- </li>
-
-
- <li id="section-124">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-124">&#182;</a>
- </div>
- <p>A full textual representation of a month, such as January or March</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">case</span> <span class="hljs-string">"F"</span>: <span class="hljs-keyword">return</span> fullMonths[me.getMonth()];</pre></div></div>
-
- </li>
-
-
- <li id="section-125">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-125">&#182;</a>
- </div>
- <p>Numeric representation of a month, with leading zeros</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">case</span> <span class="hljs-string">"m"</span>: <span class="hljs-keyword">return</span> (<span class="hljs-string">"0"</span> + (me.getMonth() + <span class="hljs-number">1</span>)).replace(<span class="hljs-regexp">/^.+(..)$/</span>, <span class="hljs-string">"$1"</span>);</pre></div></div>
-
- </li>
-
-
- <li id="section-126">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-126">&#182;</a>
- </div>
- <p>A short textual representation of a month, three letters</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">case</span> <span class="hljs-string">"M"</span>: <span class="hljs-keyword">return</span> shortMonths[me.getMonth()];</pre></div></div>
-
- </li>
-
-
- <li id="section-127">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-127">&#182;</a>
- </div>
- <p>Numeric representation of a month, without leading zeros</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">case</span> <span class="hljs-string">"n"</span>: <span class="hljs-keyword">return</span> me.getMonth() + <span class="hljs-number">1</span>;</pre></div></div>
-
- </li>
-
-
- <li id="section-128">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-128">&#182;</a>
- </div>
- <p>Number of days in the given month</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">case</span> <span class="hljs-string">"t"</span>: <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Date</span>(me.getFullYear(), me.getMonth() + <span class="hljs-number">1</span>, <span class="hljs-number">-1</span>).getDate();</pre></div></div>
-
- </li>
-
-
- <li id="section-129">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-129">&#182;</a>
- </div>
- <p>Whether it’s a leap year</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">case</span> <span class="hljs-string">"L"</span>: <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Date</span>(me.getFullYear(), <span class="hljs-number">1</span>, <span class="hljs-number">29</span>).getDate() == <span class="hljs-number">29</span> ? <span class="hljs-number">1</span> : <span class="hljs-number">0</span>;</pre></div></div>
-
- </li>
-
-
- <li id="section-130">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-130">&#182;</a>
- </div>
- <p>ISO-8601 year number. This has the same value as Y, except that if the
-ISO week number (W) belongs to the previous or next year, that year is
-used instead.</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">case</span> <span class="hljs-string">"o"</span>: <span class="hljs-keyword">return</span> getISO8601Year(me);</pre></div></div>
-
- </li>
-
-
- <li id="section-131">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-131">&#182;</a>
- </div>
- <p>A full numeric representation of a year, 4 digits</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">case</span> <span class="hljs-string">"Y"</span>: <span class="hljs-keyword">return</span> me.getFullYear();</pre></div></div>
-
- </li>
-
-
- <li id="section-132">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-132">&#182;</a>
- </div>
- <p>A two digit representation of a year</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">case</span> <span class="hljs-string">"y"</span>: <span class="hljs-keyword">return</span> (me.getFullYear() + <span class="hljs-string">""</span>).replace(<span class="hljs-regexp">/^.+(..)$/</span>, <span class="hljs-string">"$1"</span>);</pre></div></div>
-
- </li>
-
-
- <li id="section-133">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-133">&#182;</a>
- </div>
- <p>Lowercase Ante meridiem and Post meridiem</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">case</span> <span class="hljs-string">"a"</span>: <span class="hljs-keyword">return</span> me.getHours() &lt; <span class="hljs-number">12</span> ? <span class="hljs-string">"am"</span> : <span class="hljs-string">"pm"</span>;</pre></div></div>
-
- </li>
-
-
- <li id="section-134">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-134">&#182;</a>
- </div>
- <p>Uppercase Ante meridiem and Post meridiem</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">case</span> <span class="hljs-string">"A"</span>: <span class="hljs-keyword">return</span> me.getHours() &lt; <span class="hljs-number">12</span> ? <span class="hljs-string">"AM"</span> : <span class="hljs-string">"PM"</span>;</pre></div></div>
-
- </li>
-
-
- <li id="section-135">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-135">&#182;</a>
- </div>
- <p>Swatch Internet time</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">case</span> <span class="hljs-string">"B"</span>: <span class="hljs-keyword">return</span> <span class="hljs-built_in">Math</span>.floor((((me.getUTCHours() + <span class="hljs-number">1</span>) % <span class="hljs-number">24</span>) + me.getUTCMinutes() / <span class="hljs-number">60</span> + me.getUTCSeconds() / <span class="hljs-number">3600</span>) * <span class="hljs-number">1000</span> / <span class="hljs-number">24</span>);</pre></div></div>
-
- </li>
-
-
- <li id="section-136">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-136">&#182;</a>
- </div>
- <p>12-hour format of an hour without leading zeros</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">case</span> <span class="hljs-string">"g"</span>: <span class="hljs-keyword">return</span> me.getHours() % <span class="hljs-number">12</span> != <span class="hljs-number">0</span> ? me.getHours() % <span class="hljs-number">12</span> : <span class="hljs-number">12</span>;</pre></div></div>
-
- </li>
-
-
- <li id="section-137">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-137">&#182;</a>
- </div>
- <p>24-hour format of an hour without leading zeros</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">case</span> <span class="hljs-string">"G"</span>: <span class="hljs-keyword">return</span> me.getHours();</pre></div></div>
-
- </li>
-
-
- <li id="section-138">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-138">&#182;</a>
- </div>
- <p>12-hour format of an hour with leading zeros</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">case</span> <span class="hljs-string">"h"</span>: <span class="hljs-keyword">return</span> (<span class="hljs-string">"0"</span> + (me.getHours() % <span class="hljs-number">12</span> != <span class="hljs-number">0</span> ? me.getHours() % <span class="hljs-number">12</span> : <span class="hljs-number">12</span>)).replace(<span class="hljs-regexp">/^.+(..)$/</span>, <span class="hljs-string">"$1"</span>);</pre></div></div>
-
- </li>
-
-
- <li id="section-139">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-139">&#182;</a>
- </div>
- <p>24-hour format of an hour with leading zeros</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">case</span> <span class="hljs-string">"H"</span>: <span class="hljs-keyword">return</span> (<span class="hljs-string">"0"</span> + me.getHours()).replace(<span class="hljs-regexp">/^.+(..)$/</span>, <span class="hljs-string">"$1"</span>);</pre></div></div>
-
- </li>
-
-
- <li id="section-140">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-140">&#182;</a>
- </div>
- <p>Minutes with leading zeros</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">case</span> <span class="hljs-string">"i"</span>: <span class="hljs-keyword">return</span> (<span class="hljs-string">"0"</span> + me.getMinutes()).replace(<span class="hljs-regexp">/^.+(..)$/</span>, <span class="hljs-string">"$1"</span>);</pre></div></div>
-
- </li>
-
-
- <li id="section-141">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-141">&#182;</a>
- </div>
- <p>Seconds, with leading zeros</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">case</span> <span class="hljs-string">"s"</span>: <span class="hljs-keyword">return</span> (<span class="hljs-string">"0"</span> + me.getSeconds()).replace(<span class="hljs-regexp">/^.+(..)$/</span>, <span class="hljs-string">"$1"</span>);</pre></div></div>
-
- </li>
-
-
- <li id="section-142">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-142">&#182;</a>
- </div>
- <p>Milliseconds</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">case</span> <span class="hljs-string">"u"</span>: <span class="hljs-keyword">return</span> me.getMilliseconds();</pre></div></div>
-
- </li>
-
-
- <li id="section-143">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-143">&#182;</a>
- </div>
- <p>Seconds since the Unix Epoch (January 1 1970 00:00:00 GMT)</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">case</span> <span class="hljs-string">"U"</span>: <span class="hljs-keyword">return</span> me.getTime() / <span class="hljs-number">1000</span>;
- }
- });
- };
- })();
-
- Twig.lib.strip_tags = <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">input, allowed</span>) </span>{</pre></div></div>
-
- </li>
-
-
- <li id="section-144">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-144">&#182;</a>
- </div>
- <p>Strips HTML and PHP tags from a string</p>
-<p>version: 1109.2015
-discuss at: <a href="http://phpjs.org/functions/strip_tags">http://phpjs.org/functions/strip_tags</a></p>
-<ul>
-<li>original by: Kevin van Zonneveld (<a href="http://kevin.vanzonneveld.net">http://kevin.vanzonneveld.net</a>)</li>
-<li>improved by: Luke Godfrey</li>
-<li>input by: Pul</li>
-<li>bugfixed by: Kevin van Zonneveld (<a href="http://kevin.vanzonneveld.net">http://kevin.vanzonneveld.net</a>)</li>
-<li>bugfixed by: Onno Marsman</li>
-<li>input by: Alex</li>
-<li>bugfixed by: Kevin van Zonneveld (<a href="http://kevin.vanzonneveld.net">http://kevin.vanzonneveld.net</a>)</li>
-<li>input by: Marc Palau</li>
-<li>improved by: Kevin van Zonneveld (<a href="http://kevin.vanzonneveld.net">http://kevin.vanzonneveld.net</a>)</li>
-<li>input by: Brett Zamir (<a href="http://brett-zamir.me">http://brett-zamir.me</a>)</li>
-<li>bugfixed by: Kevin van Zonneveld (<a href="http://kevin.vanzonneveld.net">http://kevin.vanzonneveld.net</a>)</li>
-<li>bugfixed by: Eric Nagel</li>
-<li>input by: Bobby Drake</li>
-<li>bugfixed by: Kevin van Zonneveld (<a href="http://kevin.vanzonneveld.net">http://kevin.vanzonneveld.net</a>)</li>
-<li>bugfixed by: Tomasz Wesolowski</li>
-<li>input by: Evertjan Garretsen</li>
-<li>revised by: Rafał Kukawski (<a href="http://blog.kukawski.pl/">http://blog.kukawski.pl/</a>)</li>
-<li>example 1: strip_tags(‘<p>Kevin</p> <b>van</b> <i>Zonneveld</i>‘, ‘<i><b>‘);</li>
-<li>returns 1: ‘Kevin <b>van</b> <i>Zonneveld</i>‘</li>
-<li>example 2: strip_tags(‘<p>Kevin <img src="someimage.png" onmouseover="someFunction()">van <i>Zonneveld</i></p>‘, ‘<p>‘);</li>
-<li>returns 2: ‘<p>Kevin van Zonneveld</p>‘</li>
-<li>example 3: strip_tags(“<a href='http://kevin.vanzonneveld.net'>Kevin van Zonneveld</a>“, “<a>“);</li>
-<li>returns 3: ‘<a href='http://kevin.vanzonneveld.net'>Kevin van Zonneveld</a>‘</li>
-<li>example 4: strip_tags(‘1 &lt; 5 5 &gt; 1’);</li>
-<li>returns 4: ‘1 &lt; 5 5 &gt; 1’</li>
-<li>example 5: strip_tags(‘1 <br/> 1’);</li>
-<li>returns 5: ‘1 1’</li>
-<li>example 6: strip_tags(‘1 <br/> 1’, ‘<br>‘);</li>
-<li>returns 6: ‘1 1’</li>
-<li>example 7: strip_tags(‘1 <br/> 1’, ‘<br><br/>‘);</li>
-<li>returns 7: ‘1 <br/> 1’</li>
-</ul>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> allowed = (((allowed || <span class="hljs-string">""</span>) + <span class="hljs-string">""</span>).toLowerCase().match(<span class="hljs-regexp">/&lt;[a-z][a-z0-9]*&gt;/g</span>) || []).join(<span class="hljs-string">''</span>); <span class="hljs-comment">// making sure the allowed arg is a string containing only tags in lowercase (&lt;a&gt;&lt;b&gt;&lt;c&gt;)</span>
- <span class="hljs-keyword">var</span> tags = <span class="hljs-regexp">/&lt;\/?([a-z][a-z0-9]*)\b[^&gt;]*&gt;/gi</span>,
- commentsAndPhpTags = <span class="hljs-regexp">/&lt;!--[\s\S]*?--&gt;|&lt;\?(?:php)?[\s\S]*?\?&gt;/gi</span>;
- <span class="hljs-keyword">return</span> input.replace(commentsAndPhpTags, <span class="hljs-string">''</span>).replace(tags, <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">$0, $1</span>) </span>{
- <span class="hljs-keyword">return</span> allowed.indexOf(<span class="hljs-string">'&lt;'</span> + $<span class="hljs-number">1.</span>toLowerCase() + <span class="hljs-string">'&gt;'</span>) &gt; <span class="hljs-number">-1</span> ? $<span class="hljs-number">0</span> : <span class="hljs-string">''</span>;
- });
- }
-
- Twig.lib.parseISO8601Date = <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">s</span>)</span>{</pre></div></div>
-
- </li>
-
-
- <li id="section-145">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-145">&#182;</a>
- </div>
- <p>Taken from <a href="http://n8v.enteuxis.org/2010/12/parsing-iso-8601-dates-in-javascript/">http://n8v.enteuxis.org/2010/12/parsing-iso-8601-dates-in-javascript/</a>
-parenthese matches:
-year month day hours minutes seconds<br>dotmilliseconds
-tzstring plusminus hours minutes</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">var</span> re = <span class="hljs-regexp">/(\d{4})-(\d\d)-(\d\d)T(\d\d):(\d\d):(\d\d)(\.\d+)?(Z|([+-])(\d\d):(\d\d))/</span>;
-
- <span class="hljs-keyword">var</span> d = [];
- d = s.match(re);</pre></div></div>
-
- </li>
-
-
- <li id="section-146">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-146">&#182;</a>
- </div>
- <p>“2010-12-07T11:00:00.000-09:00” parses to:
- [“2010-12-07T11:00:00.000-09:00”, “2010”, “12”, “07”, “11”,
- “00”, “00”, “.000”, “-09:00”, “-“, “09”, “00”]
-“2010-12-07T11:00:00.000Z” parses to:
- [“2010-12-07T11:00:00.000Z”, “2010”, “12”, “07”, “11”,
- “00”, “00”, “.000”, “Z”, undefined, undefined, undefined]</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre>
- <span class="hljs-keyword">if</span> (! d) {
- <span class="hljs-keyword">throw</span> <span class="hljs-string">"Couldn't parse ISO 8601 date string '"</span> + s + <span class="hljs-string">"'"</span>;
- }</pre></div></div>
-
- </li>
-
-
- <li id="section-147">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-147">&#182;</a>
- </div>
- <p>parse strings, leading zeros into proper ints</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">var</span> a = [<span class="hljs-number">1</span>,<span class="hljs-number">2</span>,<span class="hljs-number">3</span>,<span class="hljs-number">4</span>,<span class="hljs-number">5</span>,<span class="hljs-number">6</span>,<span class="hljs-number">10</span>,<span class="hljs-number">11</span>];
- <span class="hljs-keyword">for</span> (<span class="hljs-keyword">var</span> i <span class="hljs-keyword">in</span> a) {
- d[a[i]] = <span class="hljs-built_in">parseInt</span>(d[a[i]], <span class="hljs-number">10</span>);
- }
- d[<span class="hljs-number">7</span>] = <span class="hljs-built_in">parseFloat</span>(d[<span class="hljs-number">7</span>]);</pre></div></div>
-
- </li>
-
-
- <li id="section-148">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-148">&#182;</a>
- </div>
- <p>Date.UTC(year, month[, date[, hrs[, min[, sec[, ms]]]]])
-note that month is 0-11, not 1-12
-see <a href="https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Date/UTC">https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Date/UTC</a></p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">var</span> ms = <span class="hljs-built_in">Date</span>.UTC(d[<span class="hljs-number">1</span>], d[<span class="hljs-number">2</span>] - <span class="hljs-number">1</span>, d[<span class="hljs-number">3</span>], d[<span class="hljs-number">4</span>], d[<span class="hljs-number">5</span>], d[<span class="hljs-number">6</span>]);</pre></div></div>
-
- </li>
-
-
- <li id="section-149">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-149">&#182;</a>
- </div>
- <p>if there are milliseconds, add them</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> (d[<span class="hljs-number">7</span>] &gt; <span class="hljs-number">0</span>) {
- ms += <span class="hljs-built_in">Math</span>.round(d[<span class="hljs-number">7</span>] * <span class="hljs-number">1000</span>);
- }</pre></div></div>
-
- </li>
-
-
- <li id="section-150">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-150">&#182;</a>
- </div>
- <p>if there’s a timezone, calculate it</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> (d[<span class="hljs-number">8</span>] != <span class="hljs-string">"Z"</span> &amp;&amp; d[<span class="hljs-number">10</span>]) {
- <span class="hljs-keyword">var</span> offset = d[<span class="hljs-number">10</span>] * <span class="hljs-number">60</span> * <span class="hljs-number">60</span> * <span class="hljs-number">1000</span>;
- <span class="hljs-keyword">if</span> (d[<span class="hljs-number">11</span>]) {
- offset += d[<span class="hljs-number">11</span>] * <span class="hljs-number">60</span> * <span class="hljs-number">1000</span>;
- }
- <span class="hljs-keyword">if</span> (d[<span class="hljs-number">9</span>] == <span class="hljs-string">"-"</span>) {
- ms -= offset;
- }
- <span class="hljs-keyword">else</span> {
- ms += offset;
- }
- }
-
- <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Date</span>(ms);
- };
-
- Twig.lib.strtotime = <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">text, now</span>) </span>{</pre></div></div>
-
- </li>
-
-
- <li id="section-151">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-151">&#182;</a>
- </div>
- <p> discuss at: <a href="http://phpjs.org/functions/strtotime/">http://phpjs.org/functions/strtotime/</a>
- version: 1109.2016
-original by: Caio Ariede (<a href="http://caioariede.com">http://caioariede.com</a>)
-improved by: Kevin van Zonneveld (<a href="http://kevin.vanzonneveld.net">http://kevin.vanzonneveld.net</a>)
-improved by: Caio Ariede (<a href="http://caioariede.com">http://caioariede.com</a>)
-improved by: A. Matías Quezada (<a href="http://amatiasq.com">http://amatiasq.com</a>)
-improved by: preuter
-improved by: Brett Zamir (<a href="http://brett-zamir.me">http://brett-zamir.me</a>)
-improved by: Mirko Faber
- input by: David
-bugfixed by: Wagner B. Soares
-bugfixed by: Artur Tchernychev
-bugfixed by: Stephan Bösch-Plepelits (<a href="http://github.com/plepe">http://github.com/plepe</a>)
- note: Examples all have a fixed timestamp to prevent tests to fail because of variable time(zones)
- example 1: strtotime(‘+1 day’, 1129633200);
- returns 1: 1129719600
- example 2: strtotime(‘+1 week 2 days 4 hours 2 seconds’, 1129633200);
- returns 2: 1130425202
- example 3: strtotime(‘last month’, 1129633200);
- returns 3: 1127041200
- example 4: strtotime(‘2009-05-04 08:30:00 GMT’);
- returns 4: 1241425800
- example 5: strtotime(‘2009-05-04 08:30:00+00’);
- returns 5: 1241425800
- example 6: strtotime(‘2009-05-04 08:30:00+02:00’);
- returns 6: 1241418600
- example 7: strtotime(‘2009-05-04T08:30:00Z’);
- returns 7: 1241425800</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre>
- <span class="hljs-keyword">var</span> parsed, match, today, year, date, days, ranges, len, times, regex, i, fail = <span class="hljs-literal">false</span>;
-
- <span class="hljs-keyword">if</span> (!text) {
- <span class="hljs-keyword">return</span> fail;
- }</pre></div></div>
-
- </li>
-
-
- <li id="section-152">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-152">&#182;</a>
- </div>
- <p>Unecessary spaces</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> text = text.replace(<span class="hljs-regexp">/^\s+|\s+$/g</span>, <span class="hljs-string">''</span>)
- .replace(<span class="hljs-regexp">/\s{2,}/g</span>, <span class="hljs-string">' '</span>)
- .replace(<span class="hljs-regexp">/[\t\r\n]/g</span>, <span class="hljs-string">''</span>)
- .toLowerCase();</pre></div></div>
-
- </li>
-
-
- <li id="section-153">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-153">&#182;</a>
- </div>
- <p>in contrast to php, js Date.parse function interprets:
-dates given as yyyy-mm-dd as in timezone: UTC,
-dates with “.” or “-“ as MDY instead of DMY
-dates with two-digit years differently
-etc…etc…
-…therefore we manually parse lots of common date formats</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> match = text.match(
- <span class="hljs-regexp">/^(\d{1,4})([\-\.\/\:])(\d{1,2})([\-\.\/\:])(\d{1,4})(?:\s(\d{1,2}):(\d{2})?:?(\d{2})?)?(?:\s([A-Z]+)?)?$/</span>);
-
- <span class="hljs-keyword">if</span> (match &amp;&amp; match[<span class="hljs-number">2</span>] === match[<span class="hljs-number">4</span>]) {
- <span class="hljs-keyword">if</span> (match[<span class="hljs-number">1</span>] &gt; <span class="hljs-number">1901</span>) {
- <span class="hljs-keyword">switch</span> (match[<span class="hljs-number">2</span>]) {
- <span class="hljs-keyword">case</span> <span class="hljs-string">'-'</span>:
- {</pre></div></div>
-
- </li>
-
-
- <li id="section-154">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-154">&#182;</a>
- </div>
- <p>YYYY-M-D</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> (match[<span class="hljs-number">3</span>] &gt; <span class="hljs-number">12</span> || match[<span class="hljs-number">5</span>] &gt; <span class="hljs-number">31</span>) {
- <span class="hljs-keyword">return</span> fail;
- }
-
- <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Date</span>(match[<span class="hljs-number">1</span>], <span class="hljs-built_in">parseInt</span>(match[<span class="hljs-number">3</span>], <span class="hljs-number">10</span>) - <span class="hljs-number">1</span>, match[<span class="hljs-number">5</span>],
- match[<span class="hljs-number">6</span>] || <span class="hljs-number">0</span>, match[<span class="hljs-number">7</span>] || <span class="hljs-number">0</span>, match[<span class="hljs-number">8</span>] || <span class="hljs-number">0</span>, match[<span class="hljs-number">9</span>] || <span class="hljs-number">0</span>) / <span class="hljs-number">1000</span>;
- }
- <span class="hljs-keyword">case</span> <span class="hljs-string">'.'</span>:
- {</pre></div></div>
-
- </li>
-
-
- <li id="section-155">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-155">&#182;</a>
- </div>
- <p>YYYY.M.D is not parsed by strtotime()</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">return</span> fail;
- }
- <span class="hljs-keyword">case</span> <span class="hljs-string">'/'</span>:
- {</pre></div></div>
-
- </li>
-
-
- <li id="section-156">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-156">&#182;</a>
- </div>
- <p>YYYY/M/D</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> (match[<span class="hljs-number">3</span>] &gt; <span class="hljs-number">12</span> || match[<span class="hljs-number">5</span>] &gt; <span class="hljs-number">31</span>) {
- <span class="hljs-keyword">return</span> fail;
- }
-
- <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Date</span>(match[<span class="hljs-number">1</span>], <span class="hljs-built_in">parseInt</span>(match[<span class="hljs-number">3</span>], <span class="hljs-number">10</span>) - <span class="hljs-number">1</span>, match[<span class="hljs-number">5</span>],
- match[<span class="hljs-number">6</span>] || <span class="hljs-number">0</span>, match[<span class="hljs-number">7</span>] || <span class="hljs-number">0</span>, match[<span class="hljs-number">8</span>] || <span class="hljs-number">0</span>, match[<span class="hljs-number">9</span>] || <span class="hljs-number">0</span>) / <span class="hljs-number">1000</span>;
- }
- }
- } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (match[<span class="hljs-number">5</span>] &gt; <span class="hljs-number">1901</span>) {
- <span class="hljs-keyword">switch</span> (match[<span class="hljs-number">2</span>]) {
- <span class="hljs-keyword">case</span> <span class="hljs-string">'-'</span>:
- {</pre></div></div>
-
- </li>
-
-
- <li id="section-157">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-157">&#182;</a>
- </div>
- <p>D-M-YYYY</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> (match[<span class="hljs-number">3</span>] &gt; <span class="hljs-number">12</span> || match[<span class="hljs-number">1</span>] &gt; <span class="hljs-number">31</span>) {
- <span class="hljs-keyword">return</span> fail;
- }
-
- <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Date</span>(match[<span class="hljs-number">5</span>], <span class="hljs-built_in">parseInt</span>(match[<span class="hljs-number">3</span>], <span class="hljs-number">10</span>) - <span class="hljs-number">1</span>, match[<span class="hljs-number">1</span>],
- match[<span class="hljs-number">6</span>] || <span class="hljs-number">0</span>, match[<span class="hljs-number">7</span>] || <span class="hljs-number">0</span>, match[<span class="hljs-number">8</span>] || <span class="hljs-number">0</span>, match[<span class="hljs-number">9</span>] || <span class="hljs-number">0</span>) / <span class="hljs-number">1000</span>;
- }
- <span class="hljs-keyword">case</span> <span class="hljs-string">'.'</span>:
- {</pre></div></div>
-
- </li>
-
-
- <li id="section-158">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-158">&#182;</a>
- </div>
- <p>D.M.YYYY</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> (match[<span class="hljs-number">3</span>] &gt; <span class="hljs-number">12</span> || match[<span class="hljs-number">1</span>] &gt; <span class="hljs-number">31</span>) {
- <span class="hljs-keyword">return</span> fail;
- }
-
- <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Date</span>(match[<span class="hljs-number">5</span>], <span class="hljs-built_in">parseInt</span>(match[<span class="hljs-number">3</span>], <span class="hljs-number">10</span>) - <span class="hljs-number">1</span>, match[<span class="hljs-number">1</span>],
- match[<span class="hljs-number">6</span>] || <span class="hljs-number">0</span>, match[<span class="hljs-number">7</span>] || <span class="hljs-number">0</span>, match[<span class="hljs-number">8</span>] || <span class="hljs-number">0</span>, match[<span class="hljs-number">9</span>] || <span class="hljs-number">0</span>) / <span class="hljs-number">1000</span>;
- }
- <span class="hljs-keyword">case</span> <span class="hljs-string">'/'</span>:
- {</pre></div></div>
-
- </li>
-
-
- <li id="section-159">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-159">&#182;</a>
- </div>
- <p>M/D/YYYY</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> (match[<span class="hljs-number">1</span>] &gt; <span class="hljs-number">12</span> || match[<span class="hljs-number">3</span>] &gt; <span class="hljs-number">31</span>) {
- <span class="hljs-keyword">return</span> fail;
- }
-
- <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Date</span>(match[<span class="hljs-number">5</span>], <span class="hljs-built_in">parseInt</span>(match[<span class="hljs-number">1</span>], <span class="hljs-number">10</span>) - <span class="hljs-number">1</span>, match[<span class="hljs-number">3</span>],
- match[<span class="hljs-number">6</span>] || <span class="hljs-number">0</span>, match[<span class="hljs-number">7</span>] || <span class="hljs-number">0</span>, match[<span class="hljs-number">8</span>] || <span class="hljs-number">0</span>, match[<span class="hljs-number">9</span>] || <span class="hljs-number">0</span>) / <span class="hljs-number">1000</span>;
- }
- }
- } <span class="hljs-keyword">else</span> {
- <span class="hljs-keyword">switch</span> (match[<span class="hljs-number">2</span>]) {
- <span class="hljs-keyword">case</span> <span class="hljs-string">'-'</span>:
- {</pre></div></div>
-
- </li>
-
-
- <li id="section-160">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-160">&#182;</a>
- </div>
- <p>YY-M-D</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> (match[<span class="hljs-number">3</span>] &gt; <span class="hljs-number">12</span> || match[<span class="hljs-number">5</span>] &gt; <span class="hljs-number">31</span> || (match[<span class="hljs-number">1</span>] &lt; <span class="hljs-number">70</span> &amp;&amp; match[<span class="hljs-number">1</span>] &gt; <span class="hljs-number">38</span>)) {
- <span class="hljs-keyword">return</span> fail;
- }
-
- year = match[<span class="hljs-number">1</span>] &gt;= <span class="hljs-number">0</span> &amp;&amp; match[<span class="hljs-number">1</span>] &lt;= <span class="hljs-number">38</span> ? +match[<span class="hljs-number">1</span>] + <span class="hljs-number">2000</span> : match[<span class="hljs-number">1</span>];
- <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Date</span>(year, <span class="hljs-built_in">parseInt</span>(match[<span class="hljs-number">3</span>], <span class="hljs-number">10</span>) - <span class="hljs-number">1</span>, match[<span class="hljs-number">5</span>],
- match[<span class="hljs-number">6</span>] || <span class="hljs-number">0</span>, match[<span class="hljs-number">7</span>] || <span class="hljs-number">0</span>, match[<span class="hljs-number">8</span>] || <span class="hljs-number">0</span>, match[<span class="hljs-number">9</span>] || <span class="hljs-number">0</span>) / <span class="hljs-number">1000</span>;
- }
- <span class="hljs-keyword">case</span> <span class="hljs-string">'.'</span>:
- {</pre></div></div>
-
- </li>
-
-
- <li id="section-161">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-161">&#182;</a>
- </div>
- <p>D.M.YY or H.MM.SS</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> (match[<span class="hljs-number">5</span>] &gt;= <span class="hljs-number">70</span>) {</pre></div></div>
-
- </li>
-
-
- <li id="section-162">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-162">&#182;</a>
- </div>
- <p>D.M.YY</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> (match[<span class="hljs-number">3</span>] &gt; <span class="hljs-number">12</span> || match[<span class="hljs-number">1</span>] &gt; <span class="hljs-number">31</span>) {
- <span class="hljs-keyword">return</span> fail;
- }
-
- <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Date</span>(match[<span class="hljs-number">5</span>], <span class="hljs-built_in">parseInt</span>(match[<span class="hljs-number">3</span>], <span class="hljs-number">10</span>) - <span class="hljs-number">1</span>, match[<span class="hljs-number">1</span>],
- match[<span class="hljs-number">6</span>] || <span class="hljs-number">0</span>, match[<span class="hljs-number">7</span>] || <span class="hljs-number">0</span>, match[<span class="hljs-number">8</span>] || <span class="hljs-number">0</span>, match[<span class="hljs-number">9</span>] || <span class="hljs-number">0</span>) / <span class="hljs-number">1000</span>;
- }
- <span class="hljs-keyword">if</span> (match[<span class="hljs-number">5</span>] &lt; <span class="hljs-number">60</span> &amp;&amp; !match[<span class="hljs-number">6</span>]) {</pre></div></div>
-
- </li>
-
-
- <li id="section-163">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-163">&#182;</a>
- </div>
- <p>H.MM.SS</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> (match[<span class="hljs-number">1</span>] &gt; <span class="hljs-number">23</span> || match[<span class="hljs-number">3</span>] &gt; <span class="hljs-number">59</span>) {
- <span class="hljs-keyword">return</span> fail;
- }
-
- today = <span class="hljs-keyword">new</span> <span class="hljs-built_in">Date</span>();
- <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Date</span>(today.getFullYear(), today.getMonth(), today.getDate(),
- match[<span class="hljs-number">1</span>] || <span class="hljs-number">0</span>, match[<span class="hljs-number">3</span>] || <span class="hljs-number">0</span>, match[<span class="hljs-number">5</span>] || <span class="hljs-number">0</span>, match[<span class="hljs-number">9</span>] || <span class="hljs-number">0</span>) / <span class="hljs-number">1000</span>;
- }</pre></div></div>
-
- </li>
-
-
- <li id="section-164">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-164">&#182;</a>
- </div>
- <p>invalid format, cannot be parsed</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">return</span> fail;
- }
- <span class="hljs-keyword">case</span> <span class="hljs-string">'/'</span>:
- {</pre></div></div>
-
- </li>
-
-
- <li id="section-165">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-165">&#182;</a>
- </div>
- <p>M/D/YY</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> (match[<span class="hljs-number">1</span>] &gt; <span class="hljs-number">12</span> || match[<span class="hljs-number">3</span>] &gt; <span class="hljs-number">31</span> || (match[<span class="hljs-number">5</span>] &lt; <span class="hljs-number">70</span> &amp;&amp; match[<span class="hljs-number">5</span>] &gt; <span class="hljs-number">38</span>)) {
- <span class="hljs-keyword">return</span> fail;
- }
-
- year = match[<span class="hljs-number">5</span>] &gt;= <span class="hljs-number">0</span> &amp;&amp; match[<span class="hljs-number">5</span>] &lt;= <span class="hljs-number">38</span> ? +match[<span class="hljs-number">5</span>] + <span class="hljs-number">2000</span> : match[<span class="hljs-number">5</span>];
- <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Date</span>(year, <span class="hljs-built_in">parseInt</span>(match[<span class="hljs-number">1</span>], <span class="hljs-number">10</span>) - <span class="hljs-number">1</span>, match[<span class="hljs-number">3</span>],
- match[<span class="hljs-number">6</span>] || <span class="hljs-number">0</span>, match[<span class="hljs-number">7</span>] || <span class="hljs-number">0</span>, match[<span class="hljs-number">8</span>] || <span class="hljs-number">0</span>, match[<span class="hljs-number">9</span>] || <span class="hljs-number">0</span>) / <span class="hljs-number">1000</span>;
- }
- <span class="hljs-keyword">case</span> <span class="hljs-string">':'</span>:
- {</pre></div></div>
-
- </li>
-
-
- <li id="section-166">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-166">&#182;</a>
- </div>
- <p>HH:MM:SS</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> (match[<span class="hljs-number">1</span>] &gt; <span class="hljs-number">23</span> || match[<span class="hljs-number">3</span>] &gt; <span class="hljs-number">59</span> || match[<span class="hljs-number">5</span>] &gt; <span class="hljs-number">59</span>) {
- <span class="hljs-keyword">return</span> fail;
- }
-
- today = <span class="hljs-keyword">new</span> <span class="hljs-built_in">Date</span>();
- <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Date</span>(today.getFullYear(), today.getMonth(), today.getDate(),
- match[<span class="hljs-number">1</span>] || <span class="hljs-number">0</span>, match[<span class="hljs-number">3</span>] || <span class="hljs-number">0</span>, match[<span class="hljs-number">5</span>] || <span class="hljs-number">0</span>) / <span class="hljs-number">1000</span>;
- }
- }
- }
- }</pre></div></div>
-
- </li>
-
-
- <li id="section-167">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-167">&#182;</a>
- </div>
- <p>other formats and “now” should be parsed by Date.parse()</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> (text === <span class="hljs-string">'now'</span>) {
- <span class="hljs-keyword">return</span> now === <span class="hljs-literal">null</span> || <span class="hljs-built_in">isNaN</span>(now) ? <span class="hljs-keyword">new</span> <span class="hljs-built_in">Date</span>()
- .getTime() / <span class="hljs-number">1000</span> | <span class="hljs-number">0</span> : now | <span class="hljs-number">0</span>;
- }
- <span class="hljs-keyword">if</span> (!<span class="hljs-built_in">isNaN</span>(parsed = <span class="hljs-built_in">Date</span>.parse(text))) {
- <span class="hljs-keyword">return</span> parsed / <span class="hljs-number">1000</span> | <span class="hljs-number">0</span>;
- }</pre></div></div>
-
- </li>
-
-
- <li id="section-168">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-168">&#182;</a>
- </div>
- <p>Browsers != Chrome have problems parsing ISO 8601 date strings, as they do
-not accept lower case characters, space, or shortened time zones.
-Therefore, fix these problems and try again.
-Examples:
- 2015-04-15 20:33:59+02
- 2015-04-15 20:33:59z
- 2015-04-15t20:33:59+02:00</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> (match = text.match(<span class="hljs-regexp">/^([0-9]{4}-[0-9]{2}-[0-9]{2})[ t]([0-9]{2}:[0-9]{2}:[0-9]{2}(\.[0-9]+)?)([\+-][0-9]{2}(:[0-9]{2})?|z)/</span>)) {</pre></div></div>
-
- </li>
-
-
- <li id="section-169">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-169">&#182;</a>
- </div>
- <p>fix time zone information</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> (match[<span class="hljs-number">4</span>] == <span class="hljs-string">'z'</span>) {
- match[<span class="hljs-number">4</span>] = <span class="hljs-string">'Z'</span>;
- }
- <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (match[<span class="hljs-number">4</span>].match(<span class="hljs-regexp">/^([\+-][0-9]{2})$/</span>)) {
- match[<span class="hljs-number">4</span>] = match[<span class="hljs-number">4</span>] + <span class="hljs-string">':00'</span>;
- }
-
- <span class="hljs-keyword">if</span> (!<span class="hljs-built_in">isNaN</span>(parsed = <span class="hljs-built_in">Date</span>.parse(match[<span class="hljs-number">1</span>] + <span class="hljs-string">'T'</span> + match[<span class="hljs-number">2</span>] + match[<span class="hljs-number">4</span>]))) {
- <span class="hljs-keyword">return</span> parsed / <span class="hljs-number">1000</span> | <span class="hljs-number">0</span>;
- }
- }
-
- date = now ? <span class="hljs-keyword">new</span> <span class="hljs-built_in">Date</span>(now * <span class="hljs-number">1000</span>) : <span class="hljs-keyword">new</span> <span class="hljs-built_in">Date</span>();
- days = {
- <span class="hljs-string">'sun'</span>: <span class="hljs-number">0</span>,
- <span class="hljs-string">'mon'</span>: <span class="hljs-number">1</span>,
- <span class="hljs-string">'tue'</span>: <span class="hljs-number">2</span>,
- <span class="hljs-string">'wed'</span>: <span class="hljs-number">3</span>,
- <span class="hljs-string">'thu'</span>: <span class="hljs-number">4</span>,
- <span class="hljs-string">'fri'</span>: <span class="hljs-number">5</span>,
- <span class="hljs-string">'sat'</span>: <span class="hljs-number">6</span>
- };
- ranges = {
- <span class="hljs-string">'yea'</span>: <span class="hljs-string">'FullYear'</span>,
- <span class="hljs-string">'mon'</span>: <span class="hljs-string">'Month'</span>,
- <span class="hljs-string">'day'</span>: <span class="hljs-string">'Date'</span>,
- <span class="hljs-string">'hou'</span>: <span class="hljs-string">'Hours'</span>,
- <span class="hljs-string">'min'</span>: <span class="hljs-string">'Minutes'</span>,
- <span class="hljs-string">'sec'</span>: <span class="hljs-string">'Seconds'</span>
- };
-
- <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">lastNext</span>(<span class="hljs-params">type, range, modifier</span>) </span>{
- <span class="hljs-keyword">var</span> diff, day = days[range];
-
- <span class="hljs-keyword">if</span> (<span class="hljs-keyword">typeof</span> day !== <span class="hljs-string">'undefined'</span>) {
- diff = day - date.getDay();
-
- <span class="hljs-keyword">if</span> (diff === <span class="hljs-number">0</span>) {
- diff = <span class="hljs-number">7</span> * modifier;
- } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (diff &gt; <span class="hljs-number">0</span> &amp;&amp; type === <span class="hljs-string">'last'</span>) {
- diff -= <span class="hljs-number">7</span>;
- } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (diff &lt; <span class="hljs-number">0</span> &amp;&amp; type === <span class="hljs-string">'next'</span>) {
- diff += <span class="hljs-number">7</span>;
- }
-
- date.setDate(date.getDate() + diff);
- }
- }
-
- <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">process</span>(<span class="hljs-params">val</span>) </span>{
- <span class="hljs-keyword">var</span> splt = val.split(<span class="hljs-string">' '</span>), <span class="hljs-comment">// Todo: Reconcile this with regex using \s, taking into account browser issues with split and regexes</span>
- type = splt[<span class="hljs-number">0</span>],
- range = splt[<span class="hljs-number">1</span>].substring(<span class="hljs-number">0</span>, <span class="hljs-number">3</span>),
- typeIsNumber = <span class="hljs-regexp">/\d+/</span>.test(type),
- ago = splt[<span class="hljs-number">2</span>] === <span class="hljs-string">'ago'</span>,
- num = (type === <span class="hljs-string">'last'</span> ? <span class="hljs-number">-1</span> : <span class="hljs-number">1</span>) * (ago ? <span class="hljs-number">-1</span> : <span class="hljs-number">1</span>);
-
- <span class="hljs-keyword">if</span> (typeIsNumber) {
- num *= <span class="hljs-built_in">parseInt</span>(type, <span class="hljs-number">10</span>);
- }
-
- <span class="hljs-keyword">if</span> (ranges.hasOwnProperty(range) &amp;&amp; !splt[<span class="hljs-number">1</span>].match(<span class="hljs-regexp">/^mon(day|\.)?$/i</span>)) {
- <span class="hljs-keyword">return</span> date[<span class="hljs-string">'set'</span> + ranges[range]](date[<span class="hljs-string">'get'</span> + ranges[range]]() + num);
- }
-
- <span class="hljs-keyword">if</span> (range === <span class="hljs-string">'wee'</span>) {
- <span class="hljs-keyword">return</span> date.setDate(date.getDate() + (num * <span class="hljs-number">7</span>));
- }
-
- <span class="hljs-keyword">if</span> (type === <span class="hljs-string">'next'</span> || type === <span class="hljs-string">'last'</span>) {
- lastNext(type, range, num);
- } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (!typeIsNumber) {
- <span class="hljs-keyword">return</span> <span class="hljs-literal">false</span>;
- }
-
- <span class="hljs-keyword">return</span> <span class="hljs-literal">true</span>;
- }
-
- times = <span class="hljs-string">'(years?|months?|weeks?|days?|hours?|minutes?|min|seconds?|sec'</span> +
- <span class="hljs-string">'|sunday|sun\\.?|monday|mon\\.?|tuesday|tue\\.?|wednesday|wed\\.?'</span> +
- <span class="hljs-string">'|thursday|thu\\.?|friday|fri\\.?|saturday|sat\\.?)'</span>;
- regex = <span class="hljs-string">'([+-]?\\d+\\s'</span> + times + <span class="hljs-string">'|'</span> + <span class="hljs-string">'(last|next)\\s'</span> + times + <span class="hljs-string">')(\\sago)?'</span>;
-
- match = text.match(<span class="hljs-keyword">new</span> <span class="hljs-built_in">RegExp</span>(regex, <span class="hljs-string">'gi'</span>));
- <span class="hljs-keyword">if</span> (!match) {
- <span class="hljs-keyword">return</span> fail;
- }
-
- <span class="hljs-keyword">for</span> (i = <span class="hljs-number">0</span>, len = match.length; i &lt; len; i++) {
- <span class="hljs-keyword">if</span> (!process(match[i])) {
- <span class="hljs-keyword">return</span> fail;
- }
- }</pre></div></div>
-
- </li>
-
-
- <li id="section-170">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-170">&#182;</a>
- </div>
- <p>ECMAScript 5 only
-if (!match.every(process))
- return false;</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre>
- <span class="hljs-keyword">return</span> (date.getTime() / <span class="hljs-number">1000</span>);
- };
-
- Twig.lib.is = <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">type, obj</span>) </span>{
- <span class="hljs-keyword">var</span> clas = <span class="hljs-built_in">Object</span>.prototype.toString.call(obj).slice(<span class="hljs-number">8</span>, <span class="hljs-number">-1</span>);
- <span class="hljs-keyword">return</span> obj !== <span class="hljs-literal">undefined</span> &amp;&amp; obj !== <span class="hljs-literal">null</span> &amp;&amp; clas === type;
- };</pre></div></div>
-
- </li>
-
-
- <li id="section-171">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-171">&#182;</a>
- </div>
- <p>shallow-copy an object</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> Twig.lib.copy = <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">src</span>) </span>{
- <span class="hljs-keyword">var</span> target = {},
- key;
- <span class="hljs-keyword">for</span> (key <span class="hljs-keyword">in</span> src)
- target[key] = src[key];
-
- <span class="hljs-keyword">return</span> target;
- };
-
- Twig.lib.replaceAll = <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">string, search, replace</span>) </span>{
- <span class="hljs-keyword">return</span> string.split(search).join(replace);
- };</pre></div></div>
-
- </li>
-
-
- <li id="section-172">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-172">&#182;</a>
- </div>
- <p>chunk an array (arr) into arrays of (size) items, returns an array of arrays, or an empty array on invalid input</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> Twig.lib.chunkArray = <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">arr, size</span>) </span>{
- <span class="hljs-keyword">var</span> returnVal = [],
- x = <span class="hljs-number">0</span>,
- len = arr.length;
-
- <span class="hljs-keyword">if</span> (size &lt; <span class="hljs-number">1</span> || !Twig.lib.is(<span class="hljs-string">"Array"</span>, arr)) {
- <span class="hljs-keyword">return</span> [];
- }
-
- <span class="hljs-keyword">while</span> (x &lt; len) {
- returnVal.push(arr.slice(x, x += size));
- }
-
- <span class="hljs-keyword">return</span> returnVal;
- };
-
- Twig.lib.round = <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">round</span>(<span class="hljs-params">value, precision, mode</span>) </span>{</pre></div></div>
-
- </li>
-
-
- <li id="section-173">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-173">&#182;</a>
- </div>
- <p> discuss at: <a href="http://phpjs.org/functions/round/">http://phpjs.org/functions/round/</a>
-original by: Philip Peterson
- revised by: Onno Marsman
- revised by: T.Wild
- revised by: Rafał Kukawski (<a href="http://blog.kukawski.pl/">http://blog.kukawski.pl/</a>)
- input by: Greenseed
- input by: meo
- input by: William
- input by: Josep Sanz (<a href="http://www.ws3.es/">http://www.ws3.es/</a>)
-bugfixed by: Brett Zamir (<a href="http://brett-zamir.me">http://brett-zamir.me</a>)
- note: Great work. Ideas for improvement:
- note: - code more compliant with developer guidelines
- note: - for implementing PHP constant arguments look at
- note: the pathinfo() function, it offers the greatest
- note: flexibility &amp; compatibility possible
- example 1: round(1241757, -3);
- returns 1: 1242000
- example 2: round(3.6);
- returns 2: 4
- example 3: round(2.835, 2);
- returns 3: 2.84
- example 4: round(1.1749999999999, 2);
- returns 4: 1.17
- example 5: round(58551.799999999996, 2);
- returns 5: 58551.8</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre>
- <span class="hljs-keyword">var</span> m, f, isHalf, sgn; <span class="hljs-comment">// helper variables</span>
- precision |= <span class="hljs-number">0</span>; <span class="hljs-comment">// making sure precision is integer</span>
- m = <span class="hljs-built_in">Math</span>.pow(<span class="hljs-number">10</span>, precision);
- value *= m;
- sgn = (value &gt; <span class="hljs-number">0</span>) | -(value &lt; <span class="hljs-number">0</span>); <span class="hljs-comment">// sign of the number</span>
- isHalf = value % <span class="hljs-number">1</span> === <span class="hljs-number">0.5</span> * sgn;
- f = <span class="hljs-built_in">Math</span>.floor(value);
-
- <span class="hljs-keyword">if</span> (isHalf) {
- <span class="hljs-keyword">switch</span> (mode) {
- <span class="hljs-keyword">case</span> <span class="hljs-string">'PHP_ROUND_HALF_DOWN'</span>:
- value = f + (sgn &lt; <span class="hljs-number">0</span>); <span class="hljs-comment">// rounds .5 toward zero</span>
- <span class="hljs-keyword">break</span>;
- <span class="hljs-keyword">case</span> <span class="hljs-string">'PHP_ROUND_HALF_EVEN'</span>:
- value = f + (f % <span class="hljs-number">2</span> * sgn); <span class="hljs-comment">// rouds .5 towards the next even integer</span>
- <span class="hljs-keyword">break</span>;
- <span class="hljs-keyword">case</span> <span class="hljs-string">'PHP_ROUND_HALF_ODD'</span>:
- value = f + !(f % <span class="hljs-number">2</span>); <span class="hljs-comment">// rounds .5 towards the next odd integer</span>
- <span class="hljs-keyword">break</span>;
- <span class="hljs-keyword">default</span>:
- value = f + (sgn &gt; <span class="hljs-number">0</span>); <span class="hljs-comment">// rounds .5 away from zero</span>
- }
- }
-
- <span class="hljs-keyword">return</span> (isHalf ? value : <span class="hljs-built_in">Math</span>.round(value)) / m;
- };
-
- Twig.lib.max = <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">max</span>(<span class="hljs-params"></span>) </span>{</pre></div></div>
-
- </li>
-
-
- <li id="section-174">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-174">&#182;</a>
- </div>
- <p> discuss at: <a href="http://phpjs.org/functions/max/">http://phpjs.org/functions/max/</a>
-original by: Onno Marsman
- revised by: Onno Marsman
-improved by: Jack
- note: Long code cause we’re aiming for maximum PHP compatibility
- example 1: max(1, 3, 5, 6, 7);
- returns 1: 7
- example 2: max([2, 4, 5]);
- returns 2: 5
- example 3: max(0, ‘hello’);
- returns 3: 0
- example 4: max(‘hello’, 0);
- returns 4: ‘hello’
- example 5: max(-1, ‘hello’);
- returns 5: ‘hello’
- example 6: max([2, 4, 8], [2, 5, 7]);
- returns 6: [2, 5, 7]</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre>
- <span class="hljs-keyword">var</span> ar, retVal, i = <span class="hljs-number">0</span>,
- n = <span class="hljs-number">0</span>,
- argv = <span class="hljs-built_in">arguments</span>,
- argc = argv.length,
- _obj2Array = <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">obj</span>) </span>{
- <span class="hljs-keyword">if</span> (<span class="hljs-built_in">Object</span>.prototype.toString.call(obj) === <span class="hljs-string">'[object Array]'</span>) {
- <span class="hljs-keyword">return</span> obj;
- } <span class="hljs-keyword">else</span> {
- <span class="hljs-keyword">var</span> ar = [];
- <span class="hljs-keyword">for</span> (<span class="hljs-keyword">var</span> i <span class="hljs-keyword">in</span> obj) {
- <span class="hljs-keyword">if</span> (obj.hasOwnProperty(i)) {
- ar.push(obj[i]);
- }
- }
- <span class="hljs-keyword">return</span> ar;
- }
- }, <span class="hljs-comment">//function _obj2Array</span>
- _compare = <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">current, next</span>) </span>{
- <span class="hljs-keyword">var</span> i = <span class="hljs-number">0</span>,
- n = <span class="hljs-number">0</span>,
- tmp = <span class="hljs-number">0</span>,
- nl = <span class="hljs-number">0</span>,
- cl = <span class="hljs-number">0</span>;
-
- <span class="hljs-keyword">if</span> (current === next) {
- <span class="hljs-keyword">return</span> <span class="hljs-number">0</span>;
- } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (<span class="hljs-keyword">typeof</span> current === <span class="hljs-string">'object'</span>) {
- <span class="hljs-keyword">if</span> (<span class="hljs-keyword">typeof</span> next === <span class="hljs-string">'object'</span>) {
- current = _obj2Array(current);
- next = _obj2Array(next);
- cl = current.length;
- nl = next.length;
- <span class="hljs-keyword">if</span> (nl &gt; cl) {
- <span class="hljs-keyword">return</span> <span class="hljs-number">1</span>;
- } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (nl &lt; cl) {
- <span class="hljs-keyword">return</span> <span class="hljs-number">-1</span>;
- }
- <span class="hljs-keyword">for</span> (i = <span class="hljs-number">0</span>, n = cl; i &lt; n; ++i) {
- tmp = _compare(current[i], next[i]);
- <span class="hljs-keyword">if</span> (tmp == <span class="hljs-number">1</span>) {
- <span class="hljs-keyword">return</span> <span class="hljs-number">1</span>;
- } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (tmp == <span class="hljs-number">-1</span>) {
- <span class="hljs-keyword">return</span> <span class="hljs-number">-1</span>;
- }
- }
- <span class="hljs-keyword">return</span> <span class="hljs-number">0</span>;
- }
- <span class="hljs-keyword">return</span> <span class="hljs-number">-1</span>;
- } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (<span class="hljs-keyword">typeof</span> next === <span class="hljs-string">'object'</span>) {
- <span class="hljs-keyword">return</span> <span class="hljs-number">1</span>;
- } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (<span class="hljs-built_in">isNaN</span>(next) &amp;&amp; !<span class="hljs-built_in">isNaN</span>(current)) {
- <span class="hljs-keyword">if</span> (current == <span class="hljs-number">0</span>) {
- <span class="hljs-keyword">return</span> <span class="hljs-number">0</span>;
- }
- <span class="hljs-keyword">return</span> (current &lt; <span class="hljs-number">0</span> ? <span class="hljs-number">1</span> : <span class="hljs-number">-1</span>);
- } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (<span class="hljs-built_in">isNaN</span>(current) &amp;&amp; !<span class="hljs-built_in">isNaN</span>(next)) {
- <span class="hljs-keyword">if</span> (next == <span class="hljs-number">0</span>) {
- <span class="hljs-keyword">return</span> <span class="hljs-number">0</span>;
- }
- <span class="hljs-keyword">return</span> (next &gt; <span class="hljs-number">0</span> ? <span class="hljs-number">1</span> : <span class="hljs-number">-1</span>);
- }
-
- <span class="hljs-keyword">if</span> (next == current) {
- <span class="hljs-keyword">return</span> <span class="hljs-number">0</span>;
- }
- <span class="hljs-keyword">return</span> (next &gt; current ? <span class="hljs-number">1</span> : <span class="hljs-number">-1</span>);
- }; <span class="hljs-comment">//function _compare</span>
- <span class="hljs-keyword">if</span> (argc === <span class="hljs-number">0</span>) {
- <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Error</span>(<span class="hljs-string">'At least one value should be passed to max()'</span>);
- } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (argc === <span class="hljs-number">1</span>) {
- <span class="hljs-keyword">if</span> (<span class="hljs-keyword">typeof</span> argv[<span class="hljs-number">0</span>] === <span class="hljs-string">'object'</span>) {
- ar = _obj2Array(argv[<span class="hljs-number">0</span>]);
- } <span class="hljs-keyword">else</span> {
- <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Error</span>(<span class="hljs-string">'Wrong parameter count for max()'</span>);
- }
- <span class="hljs-keyword">if</span> (ar.length === <span class="hljs-number">0</span>) {
- <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Error</span>(<span class="hljs-string">'Array must contain at least one element for max()'</span>);
- }
- } <span class="hljs-keyword">else</span> {
- ar = argv;
- }
-
- retVal = ar[<span class="hljs-number">0</span>];
- <span class="hljs-keyword">for</span> (i = <span class="hljs-number">1</span>, n = ar.length; i &lt; n; ++i) {
- <span class="hljs-keyword">if</span> (_compare(retVal, ar[i]) == <span class="hljs-number">1</span>) {
- retVal = ar[i];
- }
- }
-
- <span class="hljs-keyword">return</span> retVal;
- };
-
- Twig.lib.min = <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">min</span>(<span class="hljs-params"></span>) </span>{</pre></div></div>
-
- </li>
-
-
- <li id="section-175">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-175">&#182;</a>
- </div>
- <p> discuss at: <a href="http://phpjs.org/functions/min/">http://phpjs.org/functions/min/</a>
-original by: Onno Marsman
- revised by: Onno Marsman
-improved by: Jack
- note: Long code cause we’re aiming for maximum PHP compatibility
- example 1: min(1, 3, 5, 6, 7);
- returns 1: 1
- example 2: min([2, 4, 5]);
- returns 2: 2
- example 3: min(0, ‘hello’);
- returns 3: 0
- example 4: min(‘hello’, 0);
- returns 4: ‘hello’
- example 5: min(-1, ‘hello’);
- returns 5: -1
- example 6: min([2, 4, 8], [2, 5, 7]);
- returns 6: [2, 4, 8]</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre>
- <span class="hljs-keyword">var</span> ar, retVal, i = <span class="hljs-number">0</span>,
- n = <span class="hljs-number">0</span>,
- argv = <span class="hljs-built_in">arguments</span>,
- argc = argv.length,
- _obj2Array = <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">obj</span>) </span>{
- <span class="hljs-keyword">if</span> (<span class="hljs-built_in">Object</span>.prototype.toString.call(obj) === <span class="hljs-string">'[object Array]'</span>) {
- <span class="hljs-keyword">return</span> obj;
- }
- <span class="hljs-keyword">var</span> ar = [];
- <span class="hljs-keyword">for</span> (<span class="hljs-keyword">var</span> i <span class="hljs-keyword">in</span> obj) {
- <span class="hljs-keyword">if</span> (obj.hasOwnProperty(i)) {
- ar.push(obj[i]);
- }
- }
- <span class="hljs-keyword">return</span> ar;
- }, <span class="hljs-comment">//function _obj2Array</span>
- _compare = <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">current, next</span>) </span>{
- <span class="hljs-keyword">var</span> i = <span class="hljs-number">0</span>,
- n = <span class="hljs-number">0</span>,
- tmp = <span class="hljs-number">0</span>,
- nl = <span class="hljs-number">0</span>,
- cl = <span class="hljs-number">0</span>;
-
- <span class="hljs-keyword">if</span> (current === next) {
- <span class="hljs-keyword">return</span> <span class="hljs-number">0</span>;
- } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (<span class="hljs-keyword">typeof</span> current === <span class="hljs-string">'object'</span>) {
- <span class="hljs-keyword">if</span> (<span class="hljs-keyword">typeof</span> next === <span class="hljs-string">'object'</span>) {
- current = _obj2Array(current);
- next = _obj2Array(next);
- cl = current.length;
- nl = next.length;
- <span class="hljs-keyword">if</span> (nl &gt; cl) {
- <span class="hljs-keyword">return</span> <span class="hljs-number">1</span>;
- } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (nl &lt; cl) {
- <span class="hljs-keyword">return</span> <span class="hljs-number">-1</span>;
- }
- <span class="hljs-keyword">for</span> (i = <span class="hljs-number">0</span>, n = cl; i &lt; n; ++i) {
- tmp = _compare(current[i], next[i]);
- <span class="hljs-keyword">if</span> (tmp == <span class="hljs-number">1</span>) {
- <span class="hljs-keyword">return</span> <span class="hljs-number">1</span>;
- } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (tmp == <span class="hljs-number">-1</span>) {
- <span class="hljs-keyword">return</span> <span class="hljs-number">-1</span>;
- }
- }
- <span class="hljs-keyword">return</span> <span class="hljs-number">0</span>;
- }
- <span class="hljs-keyword">return</span> <span class="hljs-number">-1</span>;
- } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (<span class="hljs-keyword">typeof</span> next === <span class="hljs-string">'object'</span>) {
- <span class="hljs-keyword">return</span> <span class="hljs-number">1</span>;
- } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (<span class="hljs-built_in">isNaN</span>(next) &amp;&amp; !<span class="hljs-built_in">isNaN</span>(current)) {
- <span class="hljs-keyword">if</span> (current == <span class="hljs-number">0</span>) {
- <span class="hljs-keyword">return</span> <span class="hljs-number">0</span>;
- }
- <span class="hljs-keyword">return</span> (current &lt; <span class="hljs-number">0</span> ? <span class="hljs-number">1</span> : <span class="hljs-number">-1</span>);
- } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (<span class="hljs-built_in">isNaN</span>(current) &amp;&amp; !<span class="hljs-built_in">isNaN</span>(next)) {
- <span class="hljs-keyword">if</span> (next == <span class="hljs-number">0</span>) {
- <span class="hljs-keyword">return</span> <span class="hljs-number">0</span>;
- }
- <span class="hljs-keyword">return</span> (next &gt; <span class="hljs-number">0</span> ? <span class="hljs-number">1</span> : <span class="hljs-number">-1</span>);
- }
-
- <span class="hljs-keyword">if</span> (next == current) {
- <span class="hljs-keyword">return</span> <span class="hljs-number">0</span>;
- }
- <span class="hljs-keyword">return</span> (next &gt; current ? <span class="hljs-number">1</span> : <span class="hljs-number">-1</span>);
- }; <span class="hljs-comment">//function _compare</span>
-
- <span class="hljs-keyword">if</span> (argc === <span class="hljs-number">0</span>) {
- <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Error</span>(<span class="hljs-string">'At least one value should be passed to min()'</span>);
- } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (argc === <span class="hljs-number">1</span>) {
- <span class="hljs-keyword">if</span> (<span class="hljs-keyword">typeof</span> argv[<span class="hljs-number">0</span>] === <span class="hljs-string">'object'</span>) {
- ar = _obj2Array(argv[<span class="hljs-number">0</span>]);
- } <span class="hljs-keyword">else</span> {
- <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Error</span>(<span class="hljs-string">'Wrong parameter count for min()'</span>);
- }
-
- <span class="hljs-keyword">if</span> (ar.length === <span class="hljs-number">0</span>) {
- <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Error</span>(<span class="hljs-string">'Array must contain at least one element for min()'</span>);
- }
- } <span class="hljs-keyword">else</span> {
- ar = argv;
- }
-
- retVal = ar[<span class="hljs-number">0</span>];
-
- <span class="hljs-keyword">for</span> (i = <span class="hljs-number">1</span>, n = ar.length; i &lt; n; ++i) {
- <span class="hljs-keyword">if</span> (_compare(retVal, ar[i]) == <span class="hljs-number">-1</span>) {
- retVal = ar[i];
- }
- }
-
- <span class="hljs-keyword">return</span> retVal;
- };
-
- <span class="hljs-keyword">return</span> Twig;
-
-})(Twig || { });</pre></div></div>
-
- </li>
-
-
- <li id="section-176">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-176">&#182;</a>
- </div>
- <pre><code>Twig.js
-Available under the BSD <span class="hljs-number">2</span>-Clause License
-https:<span class="hljs-comment">//github.com/justjohn/twig.js</span>
-</code></pre>
- </div>
-
- </li>
-
-
- <li id="section-177">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-177">&#182;</a>
- </div>
- <h2 id="twig-logic-js">twig.logic.js</h2>
-<p>This file handles tokenizing, compiling and parsing logic tokens. {% … %}</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre><span class="hljs-keyword">var</span> Twig = (<span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">Twig</span>) </span>{
-<span class="hljs-meta"> "use strict"</span>;
-
- <span class="hljs-comment">/**
- * Namespace for logic handling.
- */</span>
- Twig.logic = {};
-
- <span class="hljs-comment">/**
- * Logic token types.
- */</span>
- Twig.logic.type = {
- if_: <span class="hljs-string">'Twig.logic.type.if'</span>,
- endif: <span class="hljs-string">'Twig.logic.type.endif'</span>,
- for_: <span class="hljs-string">'Twig.logic.type.for'</span>,
- endfor: <span class="hljs-string">'Twig.logic.type.endfor'</span>,
- else_: <span class="hljs-string">'Twig.logic.type.else'</span>,
- elseif: <span class="hljs-string">'Twig.logic.type.elseif'</span>,
- set: <span class="hljs-string">'Twig.logic.type.set'</span>,
- setcapture:<span class="hljs-string">'Twig.logic.type.setcapture'</span>,
- endset: <span class="hljs-string">'Twig.logic.type.endset'</span>,
- filter: <span class="hljs-string">'Twig.logic.type.filter'</span>,
- endfilter: <span class="hljs-string">'Twig.logic.type.endfilter'</span>,
- shortblock: <span class="hljs-string">'Twig.logic.type.shortblock'</span>,
- block: <span class="hljs-string">'Twig.logic.type.block'</span>,
- endblock: <span class="hljs-string">'Twig.logic.type.endblock'</span>,
- extends_: <span class="hljs-string">'Twig.logic.type.extends'</span>,
- use: <span class="hljs-string">'Twig.logic.type.use'</span>,
- include: <span class="hljs-string">'Twig.logic.type.include'</span>,
- spaceless: <span class="hljs-string">'Twig.logic.type.spaceless'</span>,
- endspaceless: <span class="hljs-string">'Twig.logic.type.endspaceless'</span>,
- macro: <span class="hljs-string">'Twig.logic.type.macro'</span>,
- endmacro: <span class="hljs-string">'Twig.logic.type.endmacro'</span>,
- import_: <span class="hljs-string">'Twig.logic.type.import'</span>,
- <span class="hljs-keyword">from</span>: <span class="hljs-string">'Twig.logic.type.from'</span>,
- embed: <span class="hljs-string">'Twig.logic.type.embed'</span>,
- endembed: <span class="hljs-string">'Twig.logic.type.endembed'</span>
- };</pre></div></div>
-
- </li>
-
-
- <li id="section-178">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-178">&#182;</a>
- </div>
- <p>Regular expressions for handling logic tokens.</p>
-<p>Properties:</p>
-<pre><code> type: The type of expression this matches
-
- regex: A regular expression that matches the format of the token
-
- next: What logic tokens (if any) pop this token off the logic stack. If empty, the
- logic token is assumed to not require an end tag and isn&#39;t push onto the stack.
-
- open: Does this tag open a logic expression or is it standalone. For example,
- {% endif %} cannot exist without an opening {% if ... %} tag, so open = false.
-</code></pre><p> Functions:</p>
-<pre><code> compile: A <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">that</span> <span class="hljs-title">handles</span> <span class="hljs-title">compiling</span> <span class="hljs-title">the</span> <span class="hljs-title">token</span> <span class="hljs-title">into</span> <span class="hljs-title">an</span> <span class="hljs-title">output</span> <span class="hljs-title">token</span> <span class="hljs-title">ready</span> <span class="hljs-title">for</span>
- <span class="hljs-title">parsing</span> <span class="hljs-title">with</span> <span class="hljs-title">the</span> <span class="hljs-title">parse</span> <span class="hljs-title">function</span>.
-
- <span class="hljs-title">parse</span>: <span class="hljs-title">A</span> <span class="hljs-title">function</span> <span class="hljs-title">that</span> <span class="hljs-title">parses</span> <span class="hljs-title">the</span> <span class="hljs-title">compiled</span> <span class="hljs-title">token</span> <span class="hljs-title">into</span> <span class="hljs-title">output</span> (<span class="hljs-params">HTML / whatever the
- template represents</span>).</span>
-</code></pre>
- </div>
-
- <div class="content"><div class='highlight'><pre> Twig.logic.definitions = [
- {
- <span class="hljs-comment">/**
- * If type logic tokens.
- *
- * Format: {% if expression %}
- */</span>
- type: Twig.logic.type.if_,
- regex: <span class="hljs-regexp">/^if\s+([\s\S]+)$/</span>,
- next: [
- Twig.logic.type.else_,
- Twig.logic.type.elseif,
- Twig.logic.type.endif
- ],
- open: <span class="hljs-literal">true</span>,
- compile: <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">token</span>) </span>{
- <span class="hljs-keyword">var</span> expression = token.match[<span class="hljs-number">1</span>];</pre></div></div>
-
- </li>
-
-
- <li id="section-179">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-179">&#182;</a>
- </div>
- <p>Compile the expression.</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> token.stack = Twig.expression.compile.apply(<span class="hljs-keyword">this</span>, [{
- type: Twig.expression.type.expression,
- value: expression
- }]).stack;
- <span class="hljs-keyword">delete</span> token.match;
- <span class="hljs-keyword">return</span> token;
- },
- parse: <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">token, context, chain</span>) </span>{
- <span class="hljs-keyword">var</span> output = <span class="hljs-string">''</span>,</pre></div></div>
-
- </li>
-
-
- <li id="section-180">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-180">&#182;</a>
- </div>
- <p>Parse the expression</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> result = Twig.expression.parse.apply(<span class="hljs-keyword">this</span>, [token.stack, context]);</pre></div></div>
-
- </li>
-
-
- <li id="section-181">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-181">&#182;</a>
- </div>
- <p>Start a new logic chain</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> chain = <span class="hljs-literal">true</span>;
-
- <span class="hljs-keyword">if</span> (result) {
- chain = <span class="hljs-literal">false</span>;</pre></div></div>
-
- </li>
-
-
- <li id="section-182">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-182">&#182;</a>
- </div>
- <p>parse if output</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> output = Twig.parse.apply(<span class="hljs-keyword">this</span>, [token.output, context]);
- }
- <span class="hljs-keyword">return</span> {
- chain: chain,
- output: output
- };
- }
- },
- {
- <span class="hljs-comment">/**
- * Else if type logic tokens.
- *
- * Format: {% elseif expression %}
- */</span>
- type: Twig.logic.type.elseif,
- regex: <span class="hljs-regexp">/^elseif\s+([^\s].*)$/</span>,
- next: [
- Twig.logic.type.else_,
- Twig.logic.type.elseif,
- Twig.logic.type.endif
- ],
- open: <span class="hljs-literal">false</span>,
- compile: <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">token</span>) </span>{
- <span class="hljs-keyword">var</span> expression = token.match[<span class="hljs-number">1</span>];</pre></div></div>
-
- </li>
-
-
- <li id="section-183">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-183">&#182;</a>
- </div>
- <p>Compile the expression.</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> token.stack = Twig.expression.compile.apply(<span class="hljs-keyword">this</span>, [{
- type: Twig.expression.type.expression,
- value: expression
- }]).stack;
- <span class="hljs-keyword">delete</span> token.match;
- <span class="hljs-keyword">return</span> token;
- },
- parse: <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">token, context, chain</span>) </span>{
- <span class="hljs-keyword">var</span> output = <span class="hljs-string">''</span>;
-
- <span class="hljs-keyword">if</span> (chain &amp;&amp; Twig.expression.parse.apply(<span class="hljs-keyword">this</span>, [token.stack, context]) === <span class="hljs-literal">true</span>) {
- chain = <span class="hljs-literal">false</span>;</pre></div></div>
-
- </li>
-
-
- <li id="section-184">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-184">&#182;</a>
- </div>
- <p>parse if output</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> output = Twig.parse.apply(<span class="hljs-keyword">this</span>, [token.output, context]);
- }
-
- <span class="hljs-keyword">return</span> {
- chain: chain,
- output: output
- };
- }
- },
- {
- <span class="hljs-comment">/**
- * Else if type logic tokens.
- *
- * Format: {% elseif expression %}
- */</span>
- type: Twig.logic.type.else_,
- regex: <span class="hljs-regexp">/^else$/</span>,
- next: [
- Twig.logic.type.endif,
- Twig.logic.type.endfor
- ],
- open: <span class="hljs-literal">false</span>,
- parse: <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">token, context, chain</span>) </span>{
- <span class="hljs-keyword">var</span> output = <span class="hljs-string">''</span>;
- <span class="hljs-keyword">if</span> (chain) {
- output = Twig.parse.apply(<span class="hljs-keyword">this</span>, [token.output, context]);
- }
- <span class="hljs-keyword">return</span> {
- chain: chain,
- output: output
- };
- }
- },
- {
- <span class="hljs-comment">/**
- * End if type logic tokens.
- *
- * Format: {% endif %}
- */</span>
- type: Twig.logic.type.endif,
- regex: <span class="hljs-regexp">/^endif$/</span>,
- next: [ ],
- open: <span class="hljs-literal">false</span>
- },
- {
- <span class="hljs-comment">/**
- * For type logic tokens.
- *
- * Format: {% for expression %}
- */</span>
- type: Twig.logic.type.for_,
- regex: <span class="hljs-regexp">/^for\s+([a-zA-Z0-9_,\s]+)\s+in\s+([^\s].*?)(?:\s+if\s+([^\s].*))?$/</span>,
- next: [
- Twig.logic.type.else_,
- Twig.logic.type.endfor
- ],
- open: <span class="hljs-literal">true</span>,
- compile: <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">token</span>) </span>{
- <span class="hljs-keyword">var</span> key_value = token.match[<span class="hljs-number">1</span>],
- expression = token.match[<span class="hljs-number">2</span>],
- conditional = token.match[<span class="hljs-number">3</span>],
- kv_split = <span class="hljs-literal">null</span>;
-
- token.key_var = <span class="hljs-literal">null</span>;
- token.value_var = <span class="hljs-literal">null</span>;
-
- <span class="hljs-keyword">if</span> (key_value.indexOf(<span class="hljs-string">","</span>) &gt;= <span class="hljs-number">0</span>) {
- kv_split = key_value.split(<span class="hljs-string">','</span>);
- <span class="hljs-keyword">if</span> (kv_split.length === <span class="hljs-number">2</span>) {
- token.key_var = kv_split[<span class="hljs-number">0</span>].trim();
- token.value_var = kv_split[<span class="hljs-number">1</span>].trim();
- } <span class="hljs-keyword">else</span> {
- <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> Twig.Error(<span class="hljs-string">"Invalid expression in for loop: "</span> + key_value);
- }
- } <span class="hljs-keyword">else</span> {
- token.value_var = key_value;
- }</pre></div></div>
-
- </li>
-
-
- <li id="section-185">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-185">&#182;</a>
- </div>
- <p>Valid expressions for a for loop
- for item in expression
- for key,item in expression</p>
-
- </div>
-
- </li>
-
-
- <li id="section-186">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-186">&#182;</a>
- </div>
- <p>Compile the expression.</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> token.expression = Twig.expression.compile.apply(<span class="hljs-keyword">this</span>, [{
- type: Twig.expression.type.expression,
- value: expression
- }]).stack;</pre></div></div>
-
- </li>
-
-
- <li id="section-187">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-187">&#182;</a>
- </div>
- <p>Compile the conditional (if available)</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> (conditional) {
- token.conditional = Twig.expression.compile.apply(<span class="hljs-keyword">this</span>, [{
- type: Twig.expression.type.expression,
- value: conditional
- }]).stack;
- }
-
- <span class="hljs-keyword">delete</span> token.match;
- <span class="hljs-keyword">return</span> token;
- },
- parse: <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">token, context, continue_chain</span>) </span>{</pre></div></div>
-
- </li>
-
-
- <li id="section-188">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-188">&#182;</a>
- </div>
- <p>Parse expression</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">var</span> result = Twig.expression.parse.apply(<span class="hljs-keyword">this</span>, [token.expression, context]),
- output = [],
- len,
- index = <span class="hljs-number">0</span>,
- keyset,
- that = <span class="hljs-keyword">this</span>,
- conditional = token.conditional,
- buildLoop = <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">index, len</span>) </span>{
- <span class="hljs-keyword">var</span> isConditional = conditional !== <span class="hljs-literal">undefined</span>;
- <span class="hljs-keyword">return</span> {
- index: index+<span class="hljs-number">1</span>,
- index0: index,
- revindex: isConditional?<span class="hljs-literal">undefined</span>:len-index,
- revindex0: isConditional?<span class="hljs-literal">undefined</span>:len-index<span class="hljs-number">-1</span>,
- first: (index === <span class="hljs-number">0</span>),
- last: isConditional?<span class="hljs-literal">undefined</span>:(index === len<span class="hljs-number">-1</span>),
- length: isConditional?<span class="hljs-literal">undefined</span>:len,
- parent: context
- };
- },</pre></div></div>
-
- </li>
-
-
- <li id="section-189">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-189">&#182;</a>
- </div>
- <p>run once for each iteration of the loop</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> loop = <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">key, value</span>) </span>{
- <span class="hljs-keyword">var</span> inner_context = Twig.ChildContext(context);
-
- inner_context[token.value_var] = value;
-
- <span class="hljs-keyword">if</span> (token.key_var) {
- inner_context[token.key_var] = key;
- }</pre></div></div>
-
- </li>
-
-
- <li id="section-190">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-190">&#182;</a>
- </div>
- <p>Loop object</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> inner_context.loop = buildLoop(index, len);
-
- <span class="hljs-keyword">if</span> (conditional === <span class="hljs-literal">undefined</span> ||
- Twig.expression.parse.apply(that, [conditional, inner_context]))
- {
- output.push(Twig.parse.apply(that, [token.output, inner_context]));
- index += <span class="hljs-number">1</span>;
- }</pre></div></div>
-
- </li>
-
-
- <li id="section-191">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-191">&#182;</a>
- </div>
- <p>Delete loop-related variables from the context</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">delete</span> inner_context[<span class="hljs-string">'loop'</span>];
- <span class="hljs-keyword">delete</span> inner_context[token.value_var];
- <span class="hljs-keyword">delete</span> inner_context[token.key_var];</pre></div></div>
-
- </li>
-
-
- <li id="section-192">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-192">&#182;</a>
- </div>
- <p>Merge in values that exist in context but have changed
-in inner_context.</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> Twig.merge(context, inner_context, <span class="hljs-literal">true</span>);
- };
-
-
- <span class="hljs-keyword">if</span> (Twig.lib.is(<span class="hljs-string">'Array'</span>, result)) {
- len = result.length;
- Twig.forEach(result, <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">value</span>) </span>{
- <span class="hljs-keyword">var</span> key = index;
-
- loop(key, value);
- });
- } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (Twig.lib.is(<span class="hljs-string">'Object'</span>, result)) {
- <span class="hljs-keyword">if</span> (result._keys !== <span class="hljs-literal">undefined</span>) {
- keyset = result._keys;
- } <span class="hljs-keyword">else</span> {
- keyset = <span class="hljs-built_in">Object</span>.keys(result);
- }
- len = keyset.length;
- Twig.forEach(keyset, <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">key</span>) </span>{</pre></div></div>
-
- </li>
-
-
- <li id="section-193">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-193">&#182;</a>
- </div>
- <p>Ignore the _keys property, it’s internal to twig.js</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> (key === <span class="hljs-string">"_keys"</span>) <span class="hljs-keyword">return</span>;
-
- loop(key, result[key]);
- });
- }</pre></div></div>
-
- </li>
-
-
- <li id="section-194">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-194">&#182;</a>
- </div>
- <p>Only allow else statements if no output was generated</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> continue_chain = (output.length === <span class="hljs-number">0</span>);
-
- <span class="hljs-keyword">return</span> {
- chain: continue_chain,
- output: Twig.output.apply(<span class="hljs-keyword">this</span>, [output])
- };
- }
- },
- {
- <span class="hljs-comment">/**
- * End if type logic tokens.
- *
- * Format: {% endif %}
- */</span>
- type: Twig.logic.type.endfor,
- regex: <span class="hljs-regexp">/^endfor$/</span>,
- next: [ ],
- open: <span class="hljs-literal">false</span>
- },
- {
- <span class="hljs-comment">/**
- * Set type logic tokens.
- *
- * Format: {% set key = expression %}
- */</span>
- type: Twig.logic.type.set,
- regex: <span class="hljs-regexp">/^set\s+([a-zA-Z0-9_,\s]+)\s*=\s*([\s\S]+)$/</span>,
- next: [ ],
- open: <span class="hljs-literal">true</span>,
- compile: <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">token</span>) </span>{
- <span class="hljs-keyword">var</span> key = token.match[<span class="hljs-number">1</span>].trim(),
- expression = token.match[<span class="hljs-number">2</span>],</pre></div></div>
-
- </li>
-
-
- <li id="section-195">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-195">&#182;</a>
- </div>
- <p>Compile the expression.</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> expression_stack = Twig.expression.compile.apply(<span class="hljs-keyword">this</span>, [{
- type: Twig.expression.type.expression,
- value: expression
- }]).stack;
-
- token.key = key;
- token.expression = expression_stack;
-
- <span class="hljs-keyword">delete</span> token.match;
- <span class="hljs-keyword">return</span> token;
- },
- parse: <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">token, context, continue_chain</span>) </span>{
- <span class="hljs-keyword">var</span> value = Twig.expression.parse.apply(<span class="hljs-keyword">this</span>, [token.expression, context]),
- key = token.key;
-
- context[key] = value;
-
- <span class="hljs-keyword">return</span> {
- chain: continue_chain,
- context: context
- };
- }
- },
- {
- <span class="hljs-comment">/**
- * Set capture type logic tokens.
- *
- * Format: {% set key %}
- */</span>
- type: Twig.logic.type.setcapture,
- regex: <span class="hljs-regexp">/^set\s+([a-zA-Z0-9_,\s]+)$/</span>,
- next: [
- Twig.logic.type.endset
- ],
- open: <span class="hljs-literal">true</span>,
- compile: <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">token</span>) </span>{
- <span class="hljs-keyword">var</span> key = token.match[<span class="hljs-number">1</span>].trim();
-
- token.key = key;
-
- <span class="hljs-keyword">delete</span> token.match;
- <span class="hljs-keyword">return</span> token;
- },
- parse: <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">token, context, continue_chain</span>) </span>{
-
- <span class="hljs-keyword">var</span> value = Twig.parse.apply(<span class="hljs-keyword">this</span>, [token.output, context]),
- key = token.key;</pre></div></div>
-
- </li>
-
-
- <li id="section-196">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-196">&#182;</a>
- </div>
- <p>set on both the global and local context</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">this</span>.context[key] = value;
- context[key] = value;
-
- <span class="hljs-keyword">return</span> {
- chain: continue_chain,
- context: context
- };
- }
- },
- {
- <span class="hljs-comment">/**
- * End set type block logic tokens.
- *
- * Format: {% endset %}
- */</span>
- type: Twig.logic.type.endset,
- regex: <span class="hljs-regexp">/^endset$/</span>,
- next: [ ],
- open: <span class="hljs-literal">false</span>
- },
- {
- <span class="hljs-comment">/**
- * Filter logic tokens.
- *
- * Format: {% filter upper %} or {% filter lower|escape %}
- */</span>
- type: Twig.logic.type.filter,
- regex: <span class="hljs-regexp">/^filter\s+(.+)$/</span>,
- next: [
- Twig.logic.type.endfilter
- ],
- open: <span class="hljs-literal">true</span>,
- compile: <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">token</span>) </span>{
- <span class="hljs-keyword">var</span> expression = <span class="hljs-string">"|"</span> + token.match[<span class="hljs-number">1</span>].trim();</pre></div></div>
-
- </li>
-
-
- <li id="section-197">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-197">&#182;</a>
- </div>
- <p>Compile the expression.</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> token.stack = Twig.expression.compile.apply(<span class="hljs-keyword">this</span>, [{
- type: Twig.expression.type.expression,
- value: expression
- }]).stack;
- <span class="hljs-keyword">delete</span> token.match;
- <span class="hljs-keyword">return</span> token;
- },
- parse: <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">token, context, chain</span>) </span>{
- <span class="hljs-keyword">var</span> unfiltered = Twig.parse.apply(<span class="hljs-keyword">this</span>, [token.output, context]),
- stack = [{
- type: Twig.expression.type.string,
- value: unfiltered
- }].concat(token.stack);
-
- <span class="hljs-keyword">var</span> output = Twig.expression.parse.apply(<span class="hljs-keyword">this</span>, [stack, context]);
-
- <span class="hljs-keyword">return</span> {
- chain: chain,
- output: output
- };
- }
- },
- {
- <span class="hljs-comment">/**
- * End filter logic tokens.
- *
- * Format: {% endfilter %}
- */</span>
- type: Twig.logic.type.endfilter,
- regex: <span class="hljs-regexp">/^endfilter$/</span>,
- next: [ ],
- open: <span class="hljs-literal">false</span>
- },
- {
- <span class="hljs-comment">/**
- * Block logic tokens.
- *
- * Format: {% block title %}
- */</span>
- type: Twig.logic.type.block,
- regex: <span class="hljs-regexp">/^block\s+([a-zA-Z0-9_]+)$/</span>,
- next: [
- Twig.logic.type.endblock
- ],
- open: <span class="hljs-literal">true</span>,
- compile: <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">token</span>) </span>{
- token.block = token.match[<span class="hljs-number">1</span>].trim();
- <span class="hljs-keyword">delete</span> token.match;
- <span class="hljs-keyword">return</span> token;
- },
- parse: <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">token, context, chain</span>) </span>{
- <span class="hljs-keyword">var</span> block_output,
- output,
- isImported = Twig.indexOf(<span class="hljs-keyword">this</span>.importedBlocks, token.block) &gt; <span class="hljs-number">-1</span>,
- hasParent = <span class="hljs-keyword">this</span>.blocks[token.block] &amp;&amp; Twig.indexOf(<span class="hljs-keyword">this</span>.blocks[token.block], Twig.placeholders.parent) &gt; <span class="hljs-number">-1</span>;</pre></div></div>
-
- </li>
-
-
- <li id="section-198">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-198">&#182;</a>
- </div>
- <p>Don’t override previous blocks unless they’re imported with “use”
-Loops should be exempted as well.</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> (<span class="hljs-keyword">this</span>.blocks[token.block] === <span class="hljs-literal">undefined</span> || isImported || hasParent || context.loop || token.overwrite) {
- <span class="hljs-keyword">if</span> (token.expression) {</pre></div></div>
-
- </li>
-
-
- <li id="section-199">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-199">&#182;</a>
- </div>
- <p>Short blocks have output as an expression on the open tag (no body)</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> block_output = Twig.expression.parse.apply(<span class="hljs-keyword">this</span>, [{
- type: Twig.expression.type.string,
- value: Twig.expression.parse.apply(<span class="hljs-keyword">this</span>, [token.output, context])
- }, context]);
- } <span class="hljs-keyword">else</span> {
- block_output = Twig.expression.parse.apply(<span class="hljs-keyword">this</span>, [{
- type: Twig.expression.type.string,
- value: Twig.parse.apply(<span class="hljs-keyword">this</span>, [token.output, context])
- }, context]);
- }
-
- <span class="hljs-keyword">if</span> (isImported) {</pre></div></div>
-
- </li>
-
-
- <li id="section-200">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-200">&#182;</a>
- </div>
- <p>once the block is overridden, remove it from the list of imported blocks</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">this</span>.importedBlocks.splice(<span class="hljs-keyword">this</span>.importedBlocks.indexOf(token.block), <span class="hljs-number">1</span>);
- }
-
- <span class="hljs-keyword">if</span> (hasParent) {
- <span class="hljs-keyword">this</span>.blocks[token.block] = Twig.Markup(<span class="hljs-keyword">this</span>.blocks[token.block].replace(Twig.placeholders.parent, block_output));
- } <span class="hljs-keyword">else</span> {
- <span class="hljs-keyword">this</span>.blocks[token.block] = block_output;
- }
-
- <span class="hljs-keyword">this</span>.originalBlockTokens[token.block] = {
- type: token.type,
- block: token.block,
- output: token.output,
- overwrite: <span class="hljs-literal">true</span>
- };
- }</pre></div></div>
-
- </li>
-
-
- <li id="section-201">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-201">&#182;</a>
- </div>
- <p>Check if a child block has been set from a template extending this one.</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> (<span class="hljs-keyword">this</span>.child.blocks[token.block]) {
- output = <span class="hljs-keyword">this</span>.child.blocks[token.block];
- } <span class="hljs-keyword">else</span> {
- output = <span class="hljs-keyword">this</span>.blocks[token.block];
- }
-
- <span class="hljs-keyword">return</span> {
- chain: chain,
- output: output
- };
- }
- },
- {
- <span class="hljs-comment">/**
- * Block shorthand logic tokens.
- *
- * Format: {% block title expression %}
- */</span>
- type: Twig.logic.type.shortblock,
- regex: <span class="hljs-regexp">/^block\s+([a-zA-Z0-9_]+)\s+(.+)$/</span>,
- next: [ ],
- open: <span class="hljs-literal">true</span>,
- compile: <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">token</span>) </span>{
- token.expression = token.match[<span class="hljs-number">2</span>].trim();
-
- token.output = Twig.expression.compile({
- type: Twig.expression.type.expression,
- value: token.expression
- }).stack;
-
- token.block = token.match[<span class="hljs-number">1</span>].trim();
- <span class="hljs-keyword">delete</span> token.match;
- <span class="hljs-keyword">return</span> token;
- },
- parse: <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">token, context, chain</span>) </span>{
- <span class="hljs-keyword">return</span> Twig.logic.handler[Twig.logic.type.block].parse.apply(<span class="hljs-keyword">this</span>, <span class="hljs-built_in">arguments</span>);
- }
- },
- {
- <span class="hljs-comment">/**
- * End block logic tokens.
- *
- * Format: {% endblock %}
- */</span>
- type: Twig.logic.type.endblock,
- regex: <span class="hljs-regexp">/^endblock(?:\s+([a-zA-Z0-9_]+))?$/</span>,
- next: [ ],
- open: <span class="hljs-literal">false</span>
- },
- {
- <span class="hljs-comment">/**
- * Block logic tokens.
- *
- * Format: {% extends "template.twig" %}
- */</span>
- type: Twig.logic.type.extends_,
- regex: <span class="hljs-regexp">/^extends\s+(.+)$/</span>,
- next: [ ],
- open: <span class="hljs-literal">true</span>,
- compile: <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">token</span>) </span>{
- <span class="hljs-keyword">var</span> expression = token.match[<span class="hljs-number">1</span>].trim();
- <span class="hljs-keyword">delete</span> token.match;
-
- token.stack = Twig.expression.compile.apply(<span class="hljs-keyword">this</span>, [{
- type: Twig.expression.type.expression,
- value: expression
- }]).stack;
-
- <span class="hljs-keyword">return</span> token;
- },
- parse: <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">token, context, chain</span>) </span>{</pre></div></div>
-
- </li>
-
-
- <li id="section-202">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-202">&#182;</a>
- </div>
- <p>Resolve filename</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">var</span> file = Twig.expression.parse.apply(<span class="hljs-keyword">this</span>, [token.stack, context]);</pre></div></div>
-
- </li>
-
-
- <li id="section-203">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-203">&#182;</a>
- </div>
- <p>Set parent template</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">this</span>.extend = file;
-
- <span class="hljs-keyword">return</span> {
- chain: chain,
- output: <span class="hljs-string">''</span>
- };
- }
- },
- {
- <span class="hljs-comment">/**
- * Block logic tokens.
- *
- * Format: {% use "template.twig" %}
- */</span>
- type: Twig.logic.type.use,
- regex: <span class="hljs-regexp">/^use\s+(.+)$/</span>,
- next: [ ],
- open: <span class="hljs-literal">true</span>,
- compile: <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">token</span>) </span>{
- <span class="hljs-keyword">var</span> expression = token.match[<span class="hljs-number">1</span>].trim();
- <span class="hljs-keyword">delete</span> token.match;
-
- token.stack = Twig.expression.compile.apply(<span class="hljs-keyword">this</span>, [{
- type: Twig.expression.type.expression,
- value: expression
- }]).stack;
-
- <span class="hljs-keyword">return</span> token;
- },
- parse: <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">token, context, chain</span>) </span>{</pre></div></div>
-
- </li>
-
-
- <li id="section-204">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-204">&#182;</a>
- </div>
- <p>Resolve filename</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">var</span> file = Twig.expression.parse.apply(<span class="hljs-keyword">this</span>, [token.stack, context]);</pre></div></div>
-
- </li>
-
-
- <li id="section-205">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-205">&#182;</a>
- </div>
- <p>Import blocks</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">this</span>.importBlocks(file);
-
- <span class="hljs-keyword">return</span> {
- chain: chain,
- output: <span class="hljs-string">''</span>
- };
- }
- },
- {
- <span class="hljs-comment">/**
- * Block logic tokens.
- *
- * Format: {% includes "template.twig" [with {some: 'values'} only] %}
- */</span>
- type: Twig.logic.type.include,
- regex: <span class="hljs-regexp">/^include\s+(ignore missing\s+)?(.+?)\s*(?:with\s+([\S\s]+?))?\s*(only)?$/</span>,
- next: [ ],
- open: <span class="hljs-literal">true</span>,
- compile: <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">token</span>) </span>{
- <span class="hljs-keyword">var</span> match = token.match,
- includeMissing = match[<span class="hljs-number">1</span>] !== <span class="hljs-literal">undefined</span>,
- expression = match[<span class="hljs-number">2</span>].trim(),
- withContext = match[<span class="hljs-number">3</span>],
- only = ((match[<span class="hljs-number">4</span>] !== <span class="hljs-literal">undefined</span>) &amp;&amp; match[<span class="hljs-number">4</span>].length);
-
- <span class="hljs-keyword">delete</span> token.match;
-
- token.only = only;
- token.includeMissing = includeMissing;
-
- token.stack = Twig.expression.compile.apply(<span class="hljs-keyword">this</span>, [{
- type: Twig.expression.type.expression,
- value: expression
- }]).stack;
-
- <span class="hljs-keyword">if</span> (withContext !== <span class="hljs-literal">undefined</span>) {
- token.withStack = Twig.expression.compile.apply(<span class="hljs-keyword">this</span>, [{
- type: Twig.expression.type.expression,
- value: withContext.trim()
- }]).stack;
- }
-
- <span class="hljs-keyword">return</span> token;
- },
- parse: <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">token, context, chain</span>) </span>{</pre></div></div>
-
- </li>
-
-
- <li id="section-206">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-206">&#182;</a>
- </div>
- <p>Resolve filename</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">var</span> innerContext = {},
- withContext,
- i,
- template;
-
- <span class="hljs-keyword">if</span> (!token.only) {
- innerContext = Twig.ChildContext(context);
- }
-
- <span class="hljs-keyword">if</span> (token.withStack !== <span class="hljs-literal">undefined</span>) {
- withContext = Twig.expression.parse.apply(<span class="hljs-keyword">this</span>, [token.withStack, context]);
-
- <span class="hljs-keyword">for</span> (i <span class="hljs-keyword">in</span> withContext) {
- <span class="hljs-keyword">if</span> (withContext.hasOwnProperty(i))
- innerContext[i] = withContext[i];
- }
- }
-
- <span class="hljs-keyword">var</span> file = Twig.expression.parse.apply(<span class="hljs-keyword">this</span>, [token.stack, innerContext]);
-
- <span class="hljs-keyword">if</span> (file <span class="hljs-keyword">instanceof</span> Twig.Template) {
- template = file;
- } <span class="hljs-keyword">else</span> {</pre></div></div>
-
- </li>
-
-
- <li id="section-207">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-207">&#182;</a>
- </div>
- <p>Import file</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> template = <span class="hljs-keyword">this</span>.importFile(file);
- }
-
- <span class="hljs-keyword">return</span> {
- chain: chain,
- output: template.render(innerContext)
- };
- }
- },
- {
- type: Twig.logic.type.spaceless,
- regex: <span class="hljs-regexp">/^spaceless$/</span>,
- next: [
- Twig.logic.type.endspaceless
- ],
- open: <span class="hljs-literal">true</span>,</pre></div></div>
-
- </li>
-
-
- <li id="section-208">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-208">&#182;</a>
- </div>
- <p>Parse the html and return it without any spaces between tags</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> parse: <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">token, context, chain</span>) </span>{
- <span class="hljs-keyword">var</span> <span class="hljs-comment">// Parse the output without any filter</span>
- unfiltered = Twig.parse.apply(<span class="hljs-keyword">this</span>, [token.output, context]),</pre></div></div>
-
- </li>
-
-
- <li id="section-209">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-209">&#182;</a>
- </div>
- <p>A regular expression to find closing and opening tags with spaces between them</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> rBetweenTagSpaces = <span class="hljs-regexp">/&gt;\s+&lt;/g</span>,</pre></div></div>
-
- </li>
-
-
- <li id="section-210">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-210">&#182;</a>
- </div>
- <p>Replace all space between closing and opening html tags</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> output = unfiltered.replace(rBetweenTagSpaces,<span class="hljs-string">'&gt;&lt;'</span>).trim();
-
- <span class="hljs-keyword">return</span> {
- chain: chain,
- output: output
- };
- }
- },</pre></div></div>
-
- </li>
-
-
- <li id="section-211">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-211">&#182;</a>
- </div>
- <p>Add the {% endspaceless %} token</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> {
- type: Twig.logic.type.endspaceless,
- regex: <span class="hljs-regexp">/^endspaceless$/</span>,
- next: [ ],
- open: <span class="hljs-literal">false</span>
- },
- {
- <span class="hljs-comment">/**
- * Macro logic tokens.
- *
- * Format: {% maro input(name, value, type, size) %}
- *
- */</span>
- type: Twig.logic.type.macro,
- regex: <span class="hljs-regexp">/^macro\s+([a-zA-Z0-9_]+)\s*\(\s*((?:[a-zA-Z0-9_]+(?:,\s*)?)*)\s*\)$/</span>,
- next: [
- Twig.logic.type.endmacro
- ],
- open: <span class="hljs-literal">true</span>,
- compile: <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">token</span>) </span>{
- <span class="hljs-keyword">var</span> macroName = token.match[<span class="hljs-number">1</span>],
- parameters = token.match[<span class="hljs-number">2</span>].split(<span class="hljs-regexp">/[\s,]+/</span>);</pre></div></div>
-
- </li>
-
-
- <li id="section-212">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-212">&#182;</a>
- </div>
- <p>TODO: Clean up duplicate check</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">for</span> (<span class="hljs-keyword">var</span> i=<span class="hljs-number">0</span>; i&lt;parameters.length; i++) {
- <span class="hljs-keyword">for</span> (<span class="hljs-keyword">var</span> j=<span class="hljs-number">0</span>; j&lt;parameters.length; j++){
- <span class="hljs-keyword">if</span> (parameters[i] === parameters[j] &amp;&amp; i !== j) {
- <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> Twig.Error(<span class="hljs-string">"Duplicate arguments for parameter: "</span>+ parameters[i]);
- }
- }
- }
-
- token.macroName = macroName;
- token.parameters = parameters;
-
- <span class="hljs-keyword">delete</span> token.match;
- <span class="hljs-keyword">return</span> token;
- },
- parse: <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">token, context, chain</span>) </span>{
- <span class="hljs-keyword">var</span> template = <span class="hljs-keyword">this</span>;
- <span class="hljs-keyword">this</span>.macros[token.macroName] = <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) </span>{</pre></div></div>
-
- </li>
-
-
- <li id="section-213">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-213">&#182;</a>
- </div>
- <p>Pass global context and other macros</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">var</span> macroContext = {
- _self: template.macros
- }</pre></div></div>
-
- </li>
-
-
- <li id="section-214">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-214">&#182;</a>
- </div>
- <p>Add parameters from context to macroContext</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">for</span> (<span class="hljs-keyword">var</span> i=<span class="hljs-number">0</span>; i&lt;token.parameters.length; i++) {
- <span class="hljs-keyword">var</span> prop = token.parameters[i];
- <span class="hljs-keyword">if</span>(<span class="hljs-keyword">typeof</span> <span class="hljs-built_in">arguments</span>[i] !== <span class="hljs-string">'undefined'</span>) {
- macroContext[prop] = <span class="hljs-built_in">arguments</span>[i];
- } <span class="hljs-keyword">else</span> {
- macroContext[prop] = <span class="hljs-literal">undefined</span>;
- }
- }</pre></div></div>
-
- </li>
-
-
- <li id="section-215">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-215">&#182;</a>
- </div>
- <p>Render</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">return</span> Twig.parse.apply(template, [token.output, macroContext])
- };
-
- <span class="hljs-keyword">return</span> {
- chain: chain,
- output: <span class="hljs-string">''</span>
- };
-
- }
- },
- {
- <span class="hljs-comment">/**
- * End macro logic tokens.
- *
- * Format: {% endmacro %}
- */</span>
- type: Twig.logic.type.endmacro,
- regex: <span class="hljs-regexp">/^endmacro$/</span>,
- next: [ ],
- open: <span class="hljs-literal">false</span>
- },
- {
- <span class="hljs-comment">/*
- * import logic tokens.
- *
- * Format: {% import "template.twig" as form %}
- */</span>
- type: Twig.logic.type.import_,
- regex: <span class="hljs-regexp">/^import\s+(.+)\s+as\s+([a-zA-Z0-9_]+)$/</span>,
- next: [ ],
- open: <span class="hljs-literal">true</span>,
- compile: <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">token</span>) </span>{
- <span class="hljs-keyword">var</span> expression = token.match[<span class="hljs-number">1</span>].trim(),
- contextName = token.match[<span class="hljs-number">2</span>].trim();
- <span class="hljs-keyword">delete</span> token.match;
-
- token.expression = expression;
- token.contextName = contextName;
-
- token.stack = Twig.expression.compile.apply(<span class="hljs-keyword">this</span>, [{
- type: Twig.expression.type.expression,
- value: expression
- }]).stack;
-
- <span class="hljs-keyword">return</span> token;
- },
- parse: <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">token, context, chain</span>) </span>{
- <span class="hljs-keyword">if</span> (token.expression !== <span class="hljs-string">"_self"</span>) {
- <span class="hljs-keyword">var</span> file = Twig.expression.parse.apply(<span class="hljs-keyword">this</span>, [token.stack, context]);
- <span class="hljs-keyword">var</span> template = <span class="hljs-keyword">this</span>.importFile(file || token.expression);
- context[token.contextName] = template.render({}, {output: <span class="hljs-string">'macros'</span>});
- }
- <span class="hljs-keyword">else</span> {
- context[token.contextName] = <span class="hljs-keyword">this</span>.macros;
- }
-
- <span class="hljs-keyword">return</span> {
- chain: chain,
- output: <span class="hljs-string">''</span>
- }
-
- }
- },
- {
- <span class="hljs-comment">/*
- * from logic tokens.
- *
- * Format: {% from "template.twig" import func as form %}
- */</span>
- type: Twig.logic.type.from,
- regex: <span class="hljs-regexp">/^from\s+(.+)\s+import\s+([a-zA-Z0-9_, ]+)$/</span>,
- next: [ ],
- open: <span class="hljs-literal">true</span>,
- compile: <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">token</span>) </span>{
- <span class="hljs-keyword">var</span> expression = token.match[<span class="hljs-number">1</span>].trim(),
- macroExpressions = token.match[<span class="hljs-number">2</span>].trim().split(<span class="hljs-regexp">/[ ,]+/</span>),
- macroNames = {};
-
- <span class="hljs-keyword">for</span> (<span class="hljs-keyword">var</span> i=<span class="hljs-number">0</span>; i&lt;macroExpressions.length; i++) {
- <span class="hljs-keyword">var</span> res = macroExpressions[i];</pre></div></div>
-
- </li>
-
-
- <li id="section-216">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-216">&#182;</a>
- </div>
- <p>match function as variable</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">var</span> macroMatch = res.match(<span class="hljs-regexp">/^([a-zA-Z0-9_]+)\s+(.+)\s+as\s+([a-zA-Z0-9_]+)$/</span>);
- <span class="hljs-keyword">if</span> (macroMatch) {
- macroNames[macroMatch[<span class="hljs-number">1</span>].trim()] = macroMatch[<span class="hljs-number">2</span>].trim();
- }
- <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (res.match(<span class="hljs-regexp">/^([a-zA-Z0-9_]+)$/</span>)) {
- macroNames[res] = res;
- }
- <span class="hljs-keyword">else</span> {</pre></div></div>
-
- </li>
-
-
- <li id="section-217">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-217">&#182;</a>
- </div>
- <p>ignore import</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> }
-
- }
-
- <span class="hljs-keyword">delete</span> token.match;
-
- token.expression = expression;
- token.macroNames = macroNames;
-
- token.stack = Twig.expression.compile.apply(<span class="hljs-keyword">this</span>, [{
- type: Twig.expression.type.expression,
- value: expression
- }]).stack;
-
- <span class="hljs-keyword">return</span> token;
- },
- parse: <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">token, context, chain</span>) </span>{
- <span class="hljs-keyword">var</span> macros;
-
- <span class="hljs-keyword">if</span> (token.expression !== <span class="hljs-string">"_self"</span>) {
- <span class="hljs-keyword">var</span> file = Twig.expression.parse.apply(<span class="hljs-keyword">this</span>, [token.stack, context]);
- <span class="hljs-keyword">var</span> template = <span class="hljs-keyword">this</span>.importFile(file || token.expression);
- macros = template.render({}, {output: <span class="hljs-string">'macros'</span>});
- }
- <span class="hljs-keyword">else</span> {
- macros = <span class="hljs-keyword">this</span>.macros;
- }
-
- <span class="hljs-keyword">for</span> (<span class="hljs-keyword">var</span> macroName <span class="hljs-keyword">in</span> token.macroNames) {
- <span class="hljs-keyword">if</span> (macros.hasOwnProperty(macroName)) {
- context[token.macroNames[macroName]] = macros[macroName];
- }
- }
-
- <span class="hljs-keyword">return</span> {
- chain: chain,
- output: <span class="hljs-string">''</span>
- }
-
- }
- },
- {
- <span class="hljs-comment">/**
- * The embed tag combines the behaviour of include and extends.
- * It allows you to include another template's contents, just like include does.
- *
- * Format: {% embed "template.twig" [with {some: 'values'} only] %}
- */</span>
- type: Twig.logic.type.embed,
- regex: <span class="hljs-regexp">/^embed\s+(ignore missing\s+)?(.+?)\s*(?:with\s+(.+?))?\s*(only)?$/</span>,
- next: [
- Twig.logic.type.endembed
- ],
- open: <span class="hljs-literal">true</span>,
- compile: <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">token</span>) </span>{
- <span class="hljs-keyword">var</span> match = token.match,
- includeMissing = match[<span class="hljs-number">1</span>] !== <span class="hljs-literal">undefined</span>,
- expression = match[<span class="hljs-number">2</span>].trim(),
- withContext = match[<span class="hljs-number">3</span>],
- only = ((match[<span class="hljs-number">4</span>] !== <span class="hljs-literal">undefined</span>) &amp;&amp; match[<span class="hljs-number">4</span>].length);
-
- <span class="hljs-keyword">delete</span> token.match;
-
- token.only = only;
- token.includeMissing = includeMissing;
-
- token.stack = Twig.expression.compile.apply(<span class="hljs-keyword">this</span>, [{
- type: Twig.expression.type.expression,
- value: expression
- }]).stack;
-
- <span class="hljs-keyword">if</span> (withContext !== <span class="hljs-literal">undefined</span>) {
- token.withStack = Twig.expression.compile.apply(<span class="hljs-keyword">this</span>, [{
- type: Twig.expression.type.expression,
- value: withContext.trim()
- }]).stack;
- }
-
- <span class="hljs-keyword">return</span> token;
- },
- parse: <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">token, context, chain</span>) </span>{</pre></div></div>
-
- </li>
-
-
- <li id="section-218">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-218">&#182;</a>
- </div>
- <p>Resolve filename</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">var</span> innerContext = {},
- withContext,
- i,
- template;
-
- <span class="hljs-keyword">if</span> (!token.only) {
- <span class="hljs-keyword">for</span> (i <span class="hljs-keyword">in</span> context) {
- <span class="hljs-keyword">if</span> (context.hasOwnProperty(i))
- innerContext[i] = context[i];
- }
- }
-
- <span class="hljs-keyword">if</span> (token.withStack !== <span class="hljs-literal">undefined</span>) {
- withContext = Twig.expression.parse.apply(<span class="hljs-keyword">this</span>, [token.withStack, context]);
-
- <span class="hljs-keyword">for</span> (i <span class="hljs-keyword">in</span> withContext) {
- <span class="hljs-keyword">if</span> (withContext.hasOwnProperty(i))
- innerContext[i] = withContext[i];
- }
- }
-
- <span class="hljs-keyword">var</span> file = Twig.expression.parse.apply(<span class="hljs-keyword">this</span>, [token.stack, innerContext]);
-
- <span class="hljs-keyword">if</span> (file <span class="hljs-keyword">instanceof</span> Twig.Template) {
- template = file;
- } <span class="hljs-keyword">else</span> {</pre></div></div>
-
- </li>
-
-
- <li id="section-219">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-219">&#182;</a>
- </div>
- <p>Import file</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> template = <span class="hljs-keyword">this</span>.importFile(file);
- }</pre></div></div>
-
- </li>
-
-
- <li id="section-220">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-220">&#182;</a>
- </div>
- <p>reset previous blocks</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">this</span>.blocks = {};</pre></div></div>
-
- </li>
-
-
- <li id="section-221">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-221">&#182;</a>
- </div>
- <p>parse tokens. output will be not used</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">var</span> output = Twig.parse.apply(<span class="hljs-keyword">this</span>, [token.output, innerContext]);</pre></div></div>
-
- </li>
-
-
- <li id="section-222">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-222">&#182;</a>
- </div>
- <p>render tempalte with blocks defined in embed block</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">return</span> {
- chain: chain,
- output: template.render(innerContext, {<span class="hljs-string">'blocks'</span>:<span class="hljs-keyword">this</span>.blocks})
- };
- }
- },
- <span class="hljs-comment">/* Add the {% endembed %} token
- *
- */</span>
- {
- type: Twig.logic.type.endembed,
- regex: <span class="hljs-regexp">/^endembed$/</span>,
- next: [ ],
- open: <span class="hljs-literal">false</span>
- }
-
- ];
-
-
- <span class="hljs-comment">/**
- * Registry for logic handlers.
- */</span>
- Twig.logic.handler = {};
-
- <span class="hljs-comment">/**
- * Define a new token type, available at Twig.logic.type.{type}
- */</span>
- Twig.logic.extendType = <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">type, value</span>) </span>{
- value = value || (<span class="hljs-string">"Twig.logic.type"</span> + type);
- Twig.logic.type[type] = value;
- };
-
- <span class="hljs-comment">/**
- * Extend the logic parsing functionality with a new token definition.
- *
- * // Define a new tag
- * Twig.logic.extend({
- * type: Twig.logic.type.{type},
- * // The pattern to match for this token
- * regex: ...,
- * // What token types can follow this token, leave blank if any.
- * next: [ ... ]
- * // Create and return compiled version of the token
- * compile: function(token) { ... }
- * // Parse the compiled token with the context provided by the render call
- * // and whether this token chain is complete.
- * parse: function(token, context, chain) { ... }
- * });
- *
- * @param {Object} definition The new logic expression.
- */</span>
- Twig.logic.extend = <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">definition</span>) </span>{
-
- <span class="hljs-keyword">if</span> (!definition.type) {
- <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> Twig.Error(<span class="hljs-string">"Unable to extend logic definition. No type provided for "</span> + definition);
- } <span class="hljs-keyword">else</span> {
- Twig.logic.extendType(definition.type);
- }
- Twig.logic.handler[definition.type] = definition;
- };</pre></div></div>
-
- </li>
-
-
- <li id="section-223">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-223">&#182;</a>
- </div>
- <p>Extend with built-in expressions</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">while</span> (Twig.logic.definitions.length &gt; <span class="hljs-number">0</span>) {
- Twig.logic.extend(Twig.logic.definitions.shift());
- }
-
- <span class="hljs-comment">/**
- * Compile a logic token into an object ready for parsing.
- *
- * @param {Object} raw_token An uncompiled logic token.
- *
- * @return {Object} A compiled logic token, ready for parsing.
- */</span>
- Twig.logic.compile = <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">raw_token</span>) </span>{
- <span class="hljs-keyword">var</span> expression = raw_token.value.trim(),
- token = Twig.logic.tokenize.apply(<span class="hljs-keyword">this</span>, [expression]),
- token_template = Twig.logic.handler[token.type];</pre></div></div>
-
- </li>
-
-
- <li id="section-224">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-224">&#182;</a>
- </div>
- <p>Check if the token needs compiling</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> (token_template.compile) {
- token = token_template.compile.apply(<span class="hljs-keyword">this</span>, [token]);
- Twig.log.trace(<span class="hljs-string">"Twig.logic.compile: "</span>, <span class="hljs-string">"Compiled logic token to "</span>, token);
- }
-
- <span class="hljs-keyword">return</span> token;
- };
-
- <span class="hljs-comment">/**
- * Tokenize logic expressions. This function matches token expressions against regular
- * expressions provided in token definitions provided with Twig.logic.extend.
- *
- * @param {string} expression the logic token expression to tokenize
- * (i.e. what's between {% and %})
- *
- * @return {Object} The matched token with type set to the token type and match to the regex match.
- */</span>
- Twig.logic.tokenize = <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">expression</span>) </span>{
- <span class="hljs-keyword">var</span> token = {},
- token_template_type = <span class="hljs-literal">null</span>,
- token_type = <span class="hljs-literal">null</span>,
- token_regex = <span class="hljs-literal">null</span>,
- regex_array = <span class="hljs-literal">null</span>,
- regex = <span class="hljs-literal">null</span>,
- match = <span class="hljs-literal">null</span>;</pre></div></div>
-
- </li>
-
-
- <li id="section-225">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-225">&#182;</a>
- </div>
- <p>Ignore whitespace around expressions.</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> expression = expression.trim();
-
- <span class="hljs-keyword">for</span> (token_template_type <span class="hljs-keyword">in</span> Twig.logic.handler) {
- <span class="hljs-keyword">if</span> (Twig.logic.handler.hasOwnProperty(token_template_type)) {</pre></div></div>
-
- </li>
-
-
- <li id="section-226">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-226">&#182;</a>
- </div>
- <p>Get the type and regex for this template type</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> token_type = Twig.logic.handler[token_template_type].type;
- token_regex = Twig.logic.handler[token_template_type].regex;</pre></div></div>
-
- </li>
-
-
- <li id="section-227">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-227">&#182;</a>
- </div>
- <p>Handle multiple regular expressions per type.</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> regex_array = [];
- <span class="hljs-keyword">if</span> (token_regex <span class="hljs-keyword">instanceof</span> <span class="hljs-built_in">Array</span>) {
- regex_array = token_regex;
- } <span class="hljs-keyword">else</span> {
- regex_array.push(token_regex);
- }</pre></div></div>
-
- </li>
-
-
- <li id="section-228">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-228">&#182;</a>
- </div>
- <p>Check regular expressions in the order they were specified in the definition.</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">while</span> (regex_array.length &gt; <span class="hljs-number">0</span>) {
- regex = regex_array.shift();
- match = regex.exec(expression.trim());
- <span class="hljs-keyword">if</span> (match !== <span class="hljs-literal">null</span>) {
- token.type = token_type;
- token.match = match;
- Twig.log.trace(<span class="hljs-string">"Twig.logic.tokenize: "</span>, <span class="hljs-string">"Matched a "</span>, token_type, <span class="hljs-string">" regular expression of "</span>, match);
- <span class="hljs-keyword">return</span> token;
- }
- }
- }
- }</pre></div></div>
-
- </li>
-
-
- <li id="section-229">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-229">&#182;</a>
- </div>
- <p>No regex matches</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> Twig.Error(<span class="hljs-string">"Unable to parse '"</span> + expression.trim() + <span class="hljs-string">"'"</span>);
- };
-
- <span class="hljs-comment">/**
- * Parse a logic token within a given context.
- *
- * What are logic chains?
- * Logic chains represent a series of tokens that are connected,
- * for example:
- * {% if ... %} {% else %} {% endif %}
- *
- * The chain parameter is used to signify if a chain is open of closed.
- * open:
- * More tokens in this chain should be parsed.
- * closed:
- * This token chain has completed parsing and any additional
- * tokens (else, elseif, etc...) should be ignored.
- *
- * @param {Object} token The compiled token.
- * @param {Object} context The render context.
- * @param {boolean} chain Is this an open logic chain. If false, that means a
- * chain is closed and no further cases should be parsed.
- */</span>
- Twig.logic.parse = <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">token, context, chain</span>) </span>{
- <span class="hljs-keyword">var</span> output = <span class="hljs-string">''</span>,
- token_template;
-
- context = context || { };
-
- Twig.log.debug(<span class="hljs-string">"Twig.logic.parse: "</span>, <span class="hljs-string">"Parsing logic token "</span>, token);
-
- token_template = Twig.logic.handler[token.type];
-
- <span class="hljs-keyword">if</span> (token_template.parse) {
- output = token_template.parse.apply(<span class="hljs-keyword">this</span>, [token, context, chain]);
- }
- <span class="hljs-keyword">return</span> output;
- };
-
- <span class="hljs-keyword">return</span> Twig;
-
-})(Twig || { });</pre></div></div>
-
- </li>
-
-
- <li id="section-230">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-230">&#182;</a>
- </div>
- <pre><code>Twig.js
-Available under the BSD <span class="hljs-number">2</span>-Clause License
-https:<span class="hljs-comment">//github.com/justjohn/twig.js</span>
-</code></pre>
- </div>
-
- </li>
-
-
- <li id="section-231">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-231">&#182;</a>
- </div>
- <h2 id="twig-expression-js">twig.expression.js</h2>
-<p>This file handles tokenizing, compiling and parsing expressions.</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre><span class="hljs-keyword">var</span> Twig = (<span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">Twig</span>) </span>{
-<span class="hljs-meta"> "use strict"</span>;
-
- <span class="hljs-comment">/**
- * Namespace for expression handling.
- */</span>
- Twig.expression = { };
-
- <span class="hljs-comment">/**
- * Reserved word that can't be used as variable names.
- */</span>
- Twig.expression.reservedWords = [
- <span class="hljs-string">"true"</span>, <span class="hljs-string">"false"</span>, <span class="hljs-string">"null"</span>, <span class="hljs-string">"TRUE"</span>, <span class="hljs-string">"FALSE"</span>, <span class="hljs-string">"NULL"</span>, <span class="hljs-string">"_context"</span>
- ];
-
- <span class="hljs-comment">/**
- * The type of tokens used in expressions.
- */</span>
- Twig.expression.type = {
- comma: <span class="hljs-string">'Twig.expression.type.comma'</span>,
- operator: {
- unary: <span class="hljs-string">'Twig.expression.type.operator.unary'</span>,
- binary: <span class="hljs-string">'Twig.expression.type.operator.binary'</span>
- },
- string: <span class="hljs-string">'Twig.expression.type.string'</span>,
- bool: <span class="hljs-string">'Twig.expression.type.bool'</span>,
- array: {
- start: <span class="hljs-string">'Twig.expression.type.array.start'</span>,
- end: <span class="hljs-string">'Twig.expression.type.array.end'</span>
- },
- object: {
- start: <span class="hljs-string">'Twig.expression.type.object.start'</span>,
- end: <span class="hljs-string">'Twig.expression.type.object.end'</span>
- },
- parameter: {
- start: <span class="hljs-string">'Twig.expression.type.parameter.start'</span>,
- end: <span class="hljs-string">'Twig.expression.type.parameter.end'</span>
- },
- key: {
- period: <span class="hljs-string">'Twig.expression.type.key.period'</span>,
- brackets: <span class="hljs-string">'Twig.expression.type.key.brackets'</span>
- },
- filter: <span class="hljs-string">'Twig.expression.type.filter'</span>,
- _function: <span class="hljs-string">'Twig.expression.type._function'</span>,
- variable: <span class="hljs-string">'Twig.expression.type.variable'</span>,
- number: <span class="hljs-string">'Twig.expression.type.number'</span>,
- _null: <span class="hljs-string">'Twig.expression.type.null'</span>,
- context: <span class="hljs-string">'Twig.expression.type.context'</span>,
- test: <span class="hljs-string">'Twig.expression.type.test'</span>
- };
-
- Twig.expression.set = {</pre></div></div>
-
- </li>
-
-
- <li id="section-232">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-232">&#182;</a>
- </div>
- <p>What can follow an expression (in general)</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> operations: [
- Twig.expression.type.filter,
- Twig.expression.type.operator.unary,
- Twig.expression.type.operator.binary,
- Twig.expression.type.array.end,
- Twig.expression.type.object.end,
- Twig.expression.type.parameter.end,
- Twig.expression.type.comma,
- Twig.expression.type.test
- ],
- expressions: [
- Twig.expression.type._function,
- Twig.expression.type.bool,
- Twig.expression.type.string,
- Twig.expression.type.variable,
- Twig.expression.type.number,
- Twig.expression.type._null,
- Twig.expression.type.context,
- Twig.expression.type.parameter.start,
- Twig.expression.type.array.start,
- Twig.expression.type.object.start
- ]
- };</pre></div></div>
-
- </li>
-
-
- <li id="section-233">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-233">&#182;</a>
- </div>
- <p>Most expressions allow a ‘.’ or ‘[‘ after them, so we provide a convenience set</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> Twig.expression.set.operations_extended = Twig.expression.set.operations.concat([
- Twig.expression.type.key.period,
- Twig.expression.type.key.brackets]);</pre></div></div>
-
- </li>
-
-
- <li id="section-234">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-234">&#182;</a>
- </div>
- <p>Some commonly used compile and parse functions.</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> Twig.expression.fn = {
- compile: {
- push: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">token, stack, output</span>) </span>{
- output.push(token);
- },
- push_both: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">token, stack, output</span>) </span>{
- output.push(token);
- stack.push(token);
- }
- },
- parse: {
- push: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">token, stack, context</span>) </span>{
- stack.push(token);
- },
- push_value: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">token, stack, context</span>) </span>{
- stack.push(token.value);
- }
- }
- };</pre></div></div>
-
- </li>
-
-
- <li id="section-235">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-235">&#182;</a>
- </div>
- <p>The regular expressions and compile/parse logic used to match tokens in expressions.</p>
-<p>Properties:</p>
-<pre><code> type: The type <span class="hljs-keyword">of</span> expression <span class="hljs-keyword">this</span> matches
-
- regex: One or more regular expressions that matche the format <span class="hljs-keyword">of</span> the token.
-
- next: Valid tokens that can occur next <span class="hljs-keyword">in</span> the expression.
-</code></pre><p>Functions:</p>
-<pre><code> compile: A <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">that</span> <span class="hljs-title">compiles</span> <span class="hljs-title">the</span> <span class="hljs-title">raw</span> <span class="hljs-title">regular</span> <span class="hljs-title">expression</span> <span class="hljs-title">match</span> <span class="hljs-title">into</span> <span class="hljs-title">a</span> <span class="hljs-title">token</span>.
-
- <span class="hljs-title">parse</span>: <span class="hljs-title">A</span> <span class="hljs-title">function</span> <span class="hljs-title">that</span> <span class="hljs-title">parses</span> <span class="hljs-title">the</span> <span class="hljs-title">compiled</span> <span class="hljs-title">token</span> <span class="hljs-title">into</span> <span class="hljs-title">output</span>.</span>
-</code></pre>
- </div>
-
- <div class="content"><div class='highlight'><pre> Twig.expression.definitions = [
- {
- type: Twig.expression.type.test,
- regex: <span class="hljs-regexp">/^is\s+(not)?\s*([a-zA-Z_][a-zA-Z0-9_]*)/</span>,
- next: Twig.expression.set.operations.concat([Twig.expression.type.parameter.start]),
- compile: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">token, stack, output</span>) </span>{
- token.filter = token.match[<span class="hljs-number">2</span>];
- token.modifier = token.match[<span class="hljs-number">1</span>];
- <span class="hljs-keyword">delete</span> token.match;
- <span class="hljs-keyword">delete</span> token.value;
- output.push(token);
- },
- parse: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">token, stack, context</span>) </span>{
- <span class="hljs-keyword">var</span> value = stack.pop(),
- params = token.params &amp;&amp; Twig.expression.parse.apply(<span class="hljs-keyword">this</span>, [token.params, context]),
- result = Twig.test(token.filter, value, params);
-
- <span class="hljs-keyword">if</span> (token.modifier == <span class="hljs-string">'not'</span>) {
- stack.push(!result);
- } <span class="hljs-keyword">else</span> {
- stack.push(result);
- }
- }
- },
- {
- type: Twig.expression.type.comma,</pre></div></div>
-
- </li>
-
-
- <li id="section-236">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-236">&#182;</a>
- </div>
- <p>Match a comma</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> regex: <span class="hljs-regexp">/^,/</span>,
- next: Twig.expression.set.expressions.concat([Twig.expression.type.array.end, Twig.expression.type.object.end]),
- compile: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">token, stack, output</span>) </span>{
- <span class="hljs-keyword">var</span> i = stack.length - <span class="hljs-number">1</span>,
- stack_token;
-
- <span class="hljs-keyword">delete</span> token.match;
- <span class="hljs-keyword">delete</span> token.value;</pre></div></div>
-
- </li>
-
-
- <li id="section-237">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-237">&#182;</a>
- </div>
- <p>pop tokens off the stack until the start of the object</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">for</span>(;i &gt;= <span class="hljs-number">0</span>; i--) {
- stack_token = stack.pop();
- <span class="hljs-keyword">if</span> (stack_token.type === Twig.expression.type.object.start
- || stack_token.type === Twig.expression.type.parameter.start
- || stack_token.type === Twig.expression.type.array.start) {
- stack.push(stack_token);
- <span class="hljs-keyword">break</span>;
- }
- output.push(stack_token);
- }
- output.push(token);
- }
- },
- {
- type: Twig.expression.type.operator.binary,</pre></div></div>
-
- </li>
-
-
- <li id="section-238">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-238">&#182;</a>
- </div>
- <p>Match any of +, <em>, /, -, %, ~, &lt;, &lt;=, &gt;, &gt;=, !=, ==, *</em>, ?, :, and, or, not</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> regex: <span class="hljs-regexp">/(^[\+\-~%\?\:]|^[!=]==?|^[!&lt;&gt;]=?|^\*\*?|^\/\/?|^and\s+|^or\s+|^in\s+|^not in\s+|^\.\.)/</span>,
- next: Twig.expression.set.expressions.concat([Twig.expression.type.operator.unary]),
- compile: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">token, stack, output</span>) </span>{
- <span class="hljs-keyword">delete</span> token.match;
-
- token.value = token.value.trim();
- <span class="hljs-keyword">var</span> value = token.value,
- operator = Twig.expression.operator.lookup(value, token);
-
- Twig.log.trace(<span class="hljs-string">"Twig.expression.compile: "</span>, <span class="hljs-string">"Operator: "</span>, operator, <span class="hljs-string">" from "</span>, value);
-
- <span class="hljs-keyword">while</span> (stack.length &gt; <span class="hljs-number">0</span> &amp;&amp;
- (stack[stack.length<span class="hljs-number">-1</span>].type == Twig.expression.type.operator.unary || stack[stack.length<span class="hljs-number">-1</span>].type == Twig.expression.type.operator.binary) &amp;&amp;
- (
- (operator.associativity === Twig.expression.operator.leftToRight &amp;&amp;
- operator.precidence &gt;= stack[stack.length<span class="hljs-number">-1</span>].precidence) ||
-
- (operator.associativity === Twig.expression.operator.rightToLeft &amp;&amp;
- operator.precidence &gt; stack[stack.length<span class="hljs-number">-1</span>].precidence)
- )
- ) {
- <span class="hljs-keyword">var</span> temp = stack.pop();
- output.push(temp);
- }
-
- <span class="hljs-keyword">if</span> (value === <span class="hljs-string">":"</span>) {</pre></div></div>
-
- </li>
-
-
- <li id="section-239">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-239">&#182;</a>
- </div>
- <p>Check if this is a ternary or object key being set</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> (stack[stack.length - <span class="hljs-number">1</span>] &amp;&amp; stack[stack.length<span class="hljs-number">-1</span>].value === <span class="hljs-string">"?"</span>) {</pre></div></div>
-
- </li>
-
-
- <li id="section-240">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-240">&#182;</a>
- </div>
- <p>Continue as normal for a ternary</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> } <span class="hljs-keyword">else</span> {</pre></div></div>
-
- </li>
-
-
- <li id="section-241">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-241">&#182;</a>
- </div>
- <p>This is not a ternary so we push the token to the output where it can be handled
- when the assocated object is closed.</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">var</span> key_token = output.pop();
-
- <span class="hljs-keyword">if</span> (key_token.type === Twig.expression.type.string ||
- key_token.type === Twig.expression.type.variable) {
- token.key = key_token.value;
- } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (key_token.type === Twig.expression.type.number) {</pre></div></div>
-
- </li>
-
-
- <li id="section-242">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-242">&#182;</a>
- </div>
- <p>Convert integer keys into string keys</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> token.key = key_token.value.toString();
- } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (key_token.type === Twig.expression.type.parameter.end &amp;&amp;
- key_token.expression) {
- token.params = key_token.params;
- } <span class="hljs-keyword">else</span> {
- <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> Twig.Error(<span class="hljs-string">"Unexpected value before ':' of "</span> + key_token.type + <span class="hljs-string">" = "</span> + key_token.value);
- }
-
- output.push(token);
- <span class="hljs-keyword">return</span>;
- }
- } <span class="hljs-keyword">else</span> {
- stack.push(operator);
- }
- },
- parse: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">token, stack, context</span>) </span>{
- <span class="hljs-keyword">if</span> (token.key) {</pre></div></div>
-
- </li>
-
-
- <li id="section-243">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-243">&#182;</a>
- </div>
- <p>handle ternary ‘:’ operator</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> stack.push(token);
- } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (token.params) {</pre></div></div>
-
- </li>
-
-
- <li id="section-244">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-244">&#182;</a>
- </div>
- <p>handle “{(expression):value}”</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> token.key = Twig.expression.parse.apply(<span class="hljs-keyword">this</span>, [token.params, context]);
- stack.push(token);
- <span class="hljs-keyword">delete</span>(token.params);
- } <span class="hljs-keyword">else</span> {
- Twig.expression.operator.parse(token.value, stack);
- }
- }
- },
- {
- type: Twig.expression.type.operator.unary,</pre></div></div>
-
- </li>
-
-
- <li id="section-245">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-245">&#182;</a>
- </div>
- <p>Match any of not</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> regex: <span class="hljs-regexp">/(^not\s+)/</span>,
- next: Twig.expression.set.expressions,
- compile: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">token, stack, output</span>) </span>{
- <span class="hljs-keyword">delete</span> token.match;
-
- token.value = token.value.trim();
- <span class="hljs-keyword">var</span> value = token.value,
- operator = Twig.expression.operator.lookup(value, token);
-
- Twig.log.trace(<span class="hljs-string">"Twig.expression.compile: "</span>, <span class="hljs-string">"Operator: "</span>, operator, <span class="hljs-string">" from "</span>, value);
-
- <span class="hljs-keyword">while</span> (stack.length &gt; <span class="hljs-number">0</span> &amp;&amp;
- (stack[stack.length<span class="hljs-number">-1</span>].type == Twig.expression.type.operator.unary || stack[stack.length<span class="hljs-number">-1</span>].type == Twig.expression.type.operator.binary) &amp;&amp;
- (
- (operator.associativity === Twig.expression.operator.leftToRight &amp;&amp;
- operator.precidence &gt;= stack[stack.length<span class="hljs-number">-1</span>].precidence) ||
-
- (operator.associativity === Twig.expression.operator.rightToLeft &amp;&amp;
- operator.precidence &gt; stack[stack.length<span class="hljs-number">-1</span>].precidence)
- )
- ) {
- <span class="hljs-keyword">var</span> temp = stack.pop();
- output.push(temp);
- }
-
- stack.push(operator);
- },
- parse: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">token, stack, context</span>) </span>{
- Twig.expression.operator.parse(token.value, stack);
- }
- },
- {
- <span class="hljs-comment">/**
- * Match a string. This is anything between a pair of single or double quotes.
- */</span>
- type: Twig.expression.type.string,</pre></div></div>
-
- </li>
-
-
- <li id="section-246">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-246">&#182;</a>
- </div>
- <p>See: <a href="http://blog.stevenlevithan.com/archives/match-quoted-string">http://blog.stevenlevithan.com/archives/match-quoted-string</a></p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> regex: <span class="hljs-regexp">/^(["'])(?:(?=(\\?))\2[\s\S])*?\1/</span>,
- next: Twig.expression.set.operations,
- compile: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">token, stack, output</span>) </span>{
- <span class="hljs-keyword">var</span> value = token.value;
- <span class="hljs-keyword">delete</span> token.match</pre></div></div>
-
- </li>
-
-
- <li id="section-247">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-247">&#182;</a>
- </div>
- <p>Remove the quotes from the string</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> (value.substring(<span class="hljs-number">0</span>, <span class="hljs-number">1</span>) === <span class="hljs-string">'"'</span>) {
- value = value.replace(<span class="hljs-string">'\\"'</span>, <span class="hljs-string">'"'</span>);
- } <span class="hljs-keyword">else</span> {
- value = value.replace(<span class="hljs-string">"\\'"</span>, <span class="hljs-string">"'"</span>);
- }
- token.value = value.substring(<span class="hljs-number">1</span>, value.length<span class="hljs-number">-1</span>).replace( <span class="hljs-regexp">/\\n/g</span>, <span class="hljs-string">"\n"</span> ).replace( <span class="hljs-regexp">/\\r/g</span>, <span class="hljs-string">"\r"</span> );
- Twig.log.trace(<span class="hljs-string">"Twig.expression.compile: "</span>, <span class="hljs-string">"String value: "</span>, token.value);
- output.push(token);
- },
- parse: Twig.expression.fn.parse.push_value
- },
- {
- <span class="hljs-comment">/**
- * Match a parameter set start.
- */</span>
- type: Twig.expression.type.parameter.start,
- regex: <span class="hljs-regexp">/^\(/</span>,
- next: Twig.expression.set.expressions.concat([Twig.expression.type.parameter.end]),
- compile: Twig.expression.fn.compile.push_both,
- parse: Twig.expression.fn.parse.push
- },
- {
- <span class="hljs-comment">/**
- * Match a parameter set end.
- */</span>
- type: Twig.expression.type.parameter.end,
- regex: <span class="hljs-regexp">/^\)/</span>,
- next: Twig.expression.set.operations_extended,
- compile: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">token, stack, output</span>) </span>{
- <span class="hljs-keyword">var</span> stack_token,
- end_token = token;
-
- stack_token = stack.pop();
- <span class="hljs-keyword">while</span>(stack.length &gt; <span class="hljs-number">0</span> &amp;&amp; stack_token.type != Twig.expression.type.parameter.start) {
- output.push(stack_token);
- stack_token = stack.pop();
- }</pre></div></div>
-
- </li>
-
-
- <li id="section-248">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-248">&#182;</a>
- </div>
- <p>Move contents of parens into preceding filter</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">var</span> param_stack = [];
- <span class="hljs-keyword">while</span>(token.type !== Twig.expression.type.parameter.start) {</pre></div></div>
-
- </li>
-
-
- <li id="section-249">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-249">&#182;</a>
- </div>
- <p>Add token to arguments stack</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> param_stack.unshift(token);
- token = output.pop();
- }
- param_stack.unshift(token);
-
- <span class="hljs-keyword">var</span> is_expression = <span class="hljs-literal">false</span>;</pre></div></div>
-
- </li>
-
-
- <li id="section-250">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-250">&#182;</a>
- </div>
- <p>Get the token preceding the parameters</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> token = output[output.length<span class="hljs-number">-1</span>];
-
- <span class="hljs-keyword">if</span> (token === <span class="hljs-literal">undefined</span> ||
- (token.type !== Twig.expression.type._function &amp;&amp;
- token.type !== Twig.expression.type.filter &amp;&amp;
- token.type !== Twig.expression.type.test &amp;&amp;
- token.type !== Twig.expression.type.key.brackets &amp;&amp;
- token.type !== Twig.expression.type.key.period)) {
-
- end_token.expression = <span class="hljs-literal">true</span>;</pre></div></div>
-
- </li>
-
-
- <li id="section-251">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-251">&#182;</a>
- </div>
- <p>remove start and end token from stack</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> param_stack.pop();
- param_stack.shift();
-
- end_token.params = param_stack;
-
- output.push(end_token);
-
- } <span class="hljs-keyword">else</span> {
- end_token.expression = <span class="hljs-literal">false</span>;
- token.params = param_stack;
- }
- },
- parse: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">token, stack, context</span>) </span>{
- <span class="hljs-keyword">var</span> new_array = [],
- array_ended = <span class="hljs-literal">false</span>,
- value = <span class="hljs-literal">null</span>;
-
- <span class="hljs-keyword">if</span> (token.expression) {
- value = Twig.expression.parse.apply(<span class="hljs-keyword">this</span>, [token.params, context])
- stack.push(value);
-
- } <span class="hljs-keyword">else</span> {
-
- <span class="hljs-keyword">while</span> (stack.length &gt; <span class="hljs-number">0</span>) {
- value = stack.pop();</pre></div></div>
-
- </li>
-
-
- <li id="section-252">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-252">&#182;</a>
- </div>
- <p>Push values into the array until the start of the array</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> (value &amp;&amp; value.type &amp;&amp; value.type == Twig.expression.type.parameter.start) {
- array_ended = <span class="hljs-literal">true</span>;
- <span class="hljs-keyword">break</span>;
- }
- new_array.unshift(value);
- }
-
- <span class="hljs-keyword">if</span> (!array_ended) {
- <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> Twig.Error(<span class="hljs-string">"Expected end of parameter set."</span>);
- }
-
- stack.push(new_array);
- }
- }
- },
- {
- <span class="hljs-comment">/**
- * Match an array start.
- */</span>
- type: Twig.expression.type.array.start,
- regex: <span class="hljs-regexp">/^\[/</span>,
- next: Twig.expression.set.expressions.concat([Twig.expression.type.array.end]),
- compile: Twig.expression.fn.compile.push_both,
- parse: Twig.expression.fn.parse.push
- },
- {
- <span class="hljs-comment">/**
- * Match an array end.
- */</span>
- type: Twig.expression.type.array.end,
- regex: <span class="hljs-regexp">/^\]/</span>,
- next: Twig.expression.set.operations_extended,
- compile: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">token, stack, output</span>) </span>{
- <span class="hljs-keyword">var</span> i = stack.length - <span class="hljs-number">1</span>,
- stack_token;</pre></div></div>
-
- </li>
-
-
- <li id="section-253">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-253">&#182;</a>
- </div>
- <p>pop tokens off the stack until the start of the object</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">for</span>(;i &gt;= <span class="hljs-number">0</span>; i--) {
- stack_token = stack.pop();
- <span class="hljs-keyword">if</span> (stack_token.type === Twig.expression.type.array.start) {
- <span class="hljs-keyword">break</span>;
- }
- output.push(stack_token);
- }
- output.push(token);
- },
- parse: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">token, stack, context</span>) </span>{
- <span class="hljs-keyword">var</span> new_array = [],
- array_ended = <span class="hljs-literal">false</span>,
- value = <span class="hljs-literal">null</span>;
-
- <span class="hljs-keyword">while</span> (stack.length &gt; <span class="hljs-number">0</span>) {
- value = stack.pop();</pre></div></div>
-
- </li>
-
-
- <li id="section-254">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-254">&#182;</a>
- </div>
- <p>Push values into the array until the start of the array</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> (value.type &amp;&amp; value.type == Twig.expression.type.array.start) {
- array_ended = <span class="hljs-literal">true</span>;
- <span class="hljs-keyword">break</span>;
- }
- new_array.unshift(value);
- }
- <span class="hljs-keyword">if</span> (!array_ended) {
- <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> Twig.Error(<span class="hljs-string">"Expected end of array."</span>);
- }
-
- stack.push(new_array);
- }
- },</pre></div></div>
-
- </li>
-
-
- <li id="section-255">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-255">&#182;</a>
- </div>
- <p>Token that represents the start of a hash map ‘}’</p>
-<p>Hash maps take the form:
- { “key”: ‘value’, “another_key”: item }</p>
-<p>Keys must be quoted (either single or double) and values can be any expression.</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> {
- type: Twig.expression.type.object.start,
- regex: <span class="hljs-regexp">/^\{/</span>,
- next: Twig.expression.set.expressions.concat([Twig.expression.type.object.end]),
- compile: Twig.expression.fn.compile.push_both,
- parse: Twig.expression.fn.parse.push
- },</pre></div></div>
-
- </li>
-
-
- <li id="section-256">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-256">&#182;</a>
- </div>
- <p>Token that represents the end of a Hash Map ‘}’</p>
-<p>This is where the logic for building the internal
-representation of a hash map is defined.</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> {
- type: Twig.expression.type.object.end,
- regex: <span class="hljs-regexp">/^\}/</span>,
- next: Twig.expression.set.operations_extended,
- compile: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">token, stack, output</span>) </span>{
- <span class="hljs-keyword">var</span> i = stack.length<span class="hljs-number">-1</span>,
- stack_token;</pre></div></div>
-
- </li>
-
-
- <li id="section-257">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-257">&#182;</a>
- </div>
- <p>pop tokens off the stack until the start of the object</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">for</span>(;i &gt;= <span class="hljs-number">0</span>; i--) {
- stack_token = stack.pop();
- <span class="hljs-keyword">if</span> (stack_token &amp;&amp; stack_token.type === Twig.expression.type.object.start) {
- <span class="hljs-keyword">break</span>;
- }
- output.push(stack_token);
- }
- output.push(token);
- },
- parse: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">end_token, stack, context</span>) </span>{
- <span class="hljs-keyword">var</span> new_object = {},
- object_ended = <span class="hljs-literal">false</span>,
- token = <span class="hljs-literal">null</span>,
- token_key = <span class="hljs-literal">null</span>,
- has_value = <span class="hljs-literal">false</span>,
- value = <span class="hljs-literal">null</span>;
-
- <span class="hljs-keyword">while</span> (stack.length &gt; <span class="hljs-number">0</span>) {
- token = stack.pop();</pre></div></div>
-
- </li>
-
-
- <li id="section-258">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-258">&#182;</a>
- </div>
- <p>Push values into the array until the start of the object</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> (token &amp;&amp; token.type &amp;&amp; token.type === Twig.expression.type.object.start) {
- object_ended = <span class="hljs-literal">true</span>;
- <span class="hljs-keyword">break</span>;
- }
- <span class="hljs-keyword">if</span> (token &amp;&amp; token.type &amp;&amp; (token.type === Twig.expression.type.operator.binary || token.type === Twig.expression.type.operator.unary) &amp;&amp; token.key) {
- <span class="hljs-keyword">if</span> (!has_value) {
- <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> Twig.Error(<span class="hljs-string">"Missing value for key '"</span> + token.key + <span class="hljs-string">"' in object definition."</span>);
- }
- new_object[token.key] = value;</pre></div></div>
-
- </li>
-
-
- <li id="section-259">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-259">&#182;</a>
- </div>
- <p>Preserve the order that elements are added to the map
-This is necessary since JavaScript objects don’t
-guarantee the order of keys</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> (new_object._keys === <span class="hljs-literal">undefined</span>) new_object._keys = [];
- new_object._keys.unshift(token.key);</pre></div></div>
-
- </li>
-
-
- <li id="section-260">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-260">&#182;</a>
- </div>
- <p>reset value check</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> value = <span class="hljs-literal">null</span>;
- has_value = <span class="hljs-literal">false</span>;
-
- } <span class="hljs-keyword">else</span> {
- has_value = <span class="hljs-literal">true</span>;
- value = token;
- }
- }
- <span class="hljs-keyword">if</span> (!object_ended) {
- <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> Twig.Error(<span class="hljs-string">"Unexpected end of object."</span>);
- }
-
- stack.push(new_object);
- }
- },</pre></div></div>
-
- </li>
-
-
- <li id="section-261">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-261">&#182;</a>
- </div>
- <p>Token representing a filter</p>
-<p>Filters can follow any expression and take the form:
- expression|filter(optional, args)</p>
-<p>Filter parsing is done in the Twig.filters namespace.</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> {
- type: Twig.expression.type.filter,</pre></div></div>
-
- </li>
-
-
- <li id="section-262">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-262">&#182;</a>
- </div>
- <p>match a | then a letter or <em>, then any number of letters, numbers, </em> or -</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> regex: <span class="hljs-regexp">/^\|\s?([a-zA-Z_][a-zA-Z0-9_\-]*)/</span>,
- next: Twig.expression.set.operations_extended.concat([
- Twig.expression.type.parameter.start]),
- compile: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">token, stack, output</span>) </span>{
- token.value = token.match[<span class="hljs-number">1</span>];
- output.push(token);
- },
- parse: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">token, stack, context</span>) </span>{
- <span class="hljs-keyword">var</span> input = stack.pop(),
- params = token.params &amp;&amp; Twig.expression.parse.apply(<span class="hljs-keyword">this</span>, [token.params, context]);
-
- stack.push(Twig.filter.apply(<span class="hljs-keyword">this</span>, [token.value, input, params]));
- }
- },
- {
- type: Twig.expression.type._function,</pre></div></div>
-
- </li>
-
-
- <li id="section-263">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-263">&#182;</a>
- </div>
- <p>match any letter or <em>, then any number of letters, numbers, </em> or - followed by (</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> regex: <span class="hljs-regexp">/^([a-zA-Z_][a-zA-Z0-9_]*)\s*\(/</span>,
- next: Twig.expression.type.parameter.start,
- transform: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">match, tokens</span>) </span>{
- <span class="hljs-keyword">return</span> <span class="hljs-string">'('</span>;
- },
- compile: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">token, stack, output</span>) </span>{
- <span class="hljs-keyword">var</span> fn = token.match[<span class="hljs-number">1</span>];
- token.fn = fn;</pre></div></div>
-
- </li>
-
-
- <li id="section-264">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-264">&#182;</a>
- </div>
- <p>cleanup token</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">delete</span> token.match;
- <span class="hljs-keyword">delete</span> token.value;
-
- output.push(token);
- },
- parse: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">token, stack, context</span>) </span>{
- <span class="hljs-keyword">var</span> params = token.params &amp;&amp; Twig.expression.parse.apply(<span class="hljs-keyword">this</span>, [token.params, context]),
- fn = token.fn,
- value;
-
- <span class="hljs-keyword">if</span> (Twig.functions[fn]) {</pre></div></div>
-
- </li>
-
-
- <li id="section-265">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-265">&#182;</a>
- </div>
- <p>Get the function from the built-in functions</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> value = Twig.functions[fn].apply(<span class="hljs-keyword">this</span>, params);
-
- } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (<span class="hljs-keyword">typeof</span> context[fn] == <span class="hljs-string">'function'</span>) {</pre></div></div>
-
- </li>
-
-
- <li id="section-266">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-266">&#182;</a>
- </div>
- <p>Get the function from the user/context defined functions</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> value = context[fn].apply(context, params);
-
- } <span class="hljs-keyword">else</span> {
- <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> Twig.Error(fn + <span class="hljs-string">' function does not exist and is not defined in the context'</span>);
- }
-
- stack.push(value);
- }
- },</pre></div></div>
-
- </li>
-
-
- <li id="section-267">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-267">&#182;</a>
- </div>
- <p>Token representing a variable.</p>
-<p>Variables can contain letters, numbers, underscores and
-dashes, but must start with a letter or underscore.</p>
-<p>Variables are retrieved from the render context and take
-the value of ‘undefined’ if the given variable doesn’t
-exist in the context.</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> {
- type: Twig.expression.type.variable,</pre></div></div>
-
- </li>
-
-
- <li id="section-268">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-268">&#182;</a>
- </div>
- <p>match any letter or <em>, then any number of letters, numbers, </em> or -</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> regex: <span class="hljs-regexp">/^[a-zA-Z_][a-zA-Z0-9_]*/</span>,
- next: Twig.expression.set.operations_extended.concat([
- Twig.expression.type.parameter.start]),
- compile: Twig.expression.fn.compile.push,
- validate: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">match, tokens</span>) </span>{
- <span class="hljs-keyword">return</span> (Twig.indexOf(Twig.expression.reservedWords, match[<span class="hljs-number">0</span>]) &lt; <span class="hljs-number">0</span>);
- },
- parse: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">token, stack, context</span>) </span>{</pre></div></div>
-
- </li>
-
-
- <li id="section-269">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-269">&#182;</a>
- </div>
- <p>Get the variable from the context</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">var</span> value = Twig.expression.resolve(context[token.value], context);
- stack.push(value);
- }
- },
- {
- type: Twig.expression.type.key.period,
- regex: <span class="hljs-regexp">/^\.([a-zA-Z0-9_]+)/</span>,
- next: Twig.expression.set.operations_extended.concat([
- Twig.expression.type.parameter.start]),
- compile: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">token, stack, output</span>) </span>{
- token.key = token.match[<span class="hljs-number">1</span>];
- <span class="hljs-keyword">delete</span> token.match;
- <span class="hljs-keyword">delete</span> token.value;
-
- output.push(token);
- },
- parse: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">token, stack, context</span>) </span>{
- <span class="hljs-keyword">var</span> params = token.params &amp;&amp; Twig.expression.parse.apply(<span class="hljs-keyword">this</span>, [token.params, context]),
- key = token.key,
- object = stack.pop(),
- value;
-
- <span class="hljs-keyword">if</span> (object === <span class="hljs-literal">null</span> || object === <span class="hljs-literal">undefined</span>) {
- <span class="hljs-keyword">if</span> (<span class="hljs-keyword">this</span>.options.strict_variables) {
- <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> Twig.Error(<span class="hljs-string">"Can't access a key "</span> + key + <span class="hljs-string">" on an null or undefined object."</span>);
- } <span class="hljs-keyword">else</span> {
- <span class="hljs-keyword">return</span> <span class="hljs-literal">null</span>;
- }
- }
-
- <span class="hljs-keyword">var</span> capitalize = <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">value</span>) </span>{<span class="hljs-keyword">return</span> value.substr(<span class="hljs-number">0</span>, <span class="hljs-number">1</span>).toUpperCase() + value.substr(<span class="hljs-number">1</span>);};</pre></div></div>
-
- </li>
-
-
- <li id="section-270">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-270">&#182;</a>
- </div>
- <p>Get the variable from the context</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> (<span class="hljs-keyword">typeof</span> object === <span class="hljs-string">'object'</span> &amp;&amp; key <span class="hljs-keyword">in</span> object) {
- value = object[key];
- } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (object[<span class="hljs-string">"get"</span>+capitalize(key)] !== <span class="hljs-literal">undefined</span>) {
- value = object[<span class="hljs-string">"get"</span>+capitalize(key)];
- } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (object[<span class="hljs-string">"is"</span>+capitalize(key)] !== <span class="hljs-literal">undefined</span>) {
- value = object[<span class="hljs-string">"is"</span>+capitalize(key)];
- } <span class="hljs-keyword">else</span> {
- value = <span class="hljs-literal">undefined</span>;
- }
- stack.push(Twig.expression.resolve(value, object, params));
- }
- },
- {
- type: Twig.expression.type.key.brackets,
- regex: <span class="hljs-regexp">/^\[([^\]]*)\]/</span>,
- next: Twig.expression.set.operations_extended.concat([
- Twig.expression.type.parameter.start]),
- compile: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">token, stack, output</span>) </span>{
- <span class="hljs-keyword">var</span> match = token.match[<span class="hljs-number">1</span>];
- <span class="hljs-keyword">delete</span> token.value;
- <span class="hljs-keyword">delete</span> token.match;</pre></div></div>
-
- </li>
-
-
- <li id="section-271">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-271">&#182;</a>
- </div>
- <p>The expression stack for the key</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> token.stack = Twig.expression.compile({
- value: match
- }).stack;
-
- output.push(token);
- },
- parse: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">token, stack, context</span>) </span>{</pre></div></div>
-
- </li>
-
-
- <li id="section-272">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-272">&#182;</a>
- </div>
- <p>Evaluate key</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">var</span> params = token.params &amp;&amp; Twig.expression.parse.apply(<span class="hljs-keyword">this</span>, [token.params, context]),
- key = Twig.expression.parse.apply(<span class="hljs-keyword">this</span>, [token.stack, context]),
- object = stack.pop(),
- value;
-
- <span class="hljs-keyword">if</span> (object === <span class="hljs-literal">null</span> || object === <span class="hljs-literal">undefined</span>) {
- <span class="hljs-keyword">if</span> (<span class="hljs-keyword">this</span>.options.strict_variables) {
- <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> Twig.Error(<span class="hljs-string">"Can't access a key "</span> + key + <span class="hljs-string">" on an null or undefined object."</span>);
- } <span class="hljs-keyword">else</span> {
- <span class="hljs-keyword">return</span> <span class="hljs-literal">null</span>;
- }
- }</pre></div></div>
-
- </li>
-
-
- <li id="section-273">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-273">&#182;</a>
- </div>
- <p>Get the variable from the context</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> (<span class="hljs-keyword">typeof</span> object === <span class="hljs-string">'object'</span> &amp;&amp; key <span class="hljs-keyword">in</span> object) {
- value = object[key];
- } <span class="hljs-keyword">else</span> {
- value = <span class="hljs-literal">null</span>;
- }
- stack.push(Twig.expression.resolve(value, object, params));
- }
- },
- {
- <span class="hljs-comment">/**
- * Match a null value.
- */</span>
- type: Twig.expression.type._null,</pre></div></div>
-
- </li>
-
-
- <li id="section-274">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-274">&#182;</a>
- </div>
- <p>match a number</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> regex: <span class="hljs-regexp">/^(null|NULL|none|NONE)/</span>,
- next: Twig.expression.set.operations,
- compile: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">token, stack, output</span>) </span>{
- <span class="hljs-keyword">delete</span> token.match;
- token.value = <span class="hljs-literal">null</span>;
- output.push(token);
- },
- parse: Twig.expression.fn.parse.push_value
- },
- {
- <span class="hljs-comment">/**
- * Match the context
- */</span>
- type: Twig.expression.type.context,
- regex: <span class="hljs-regexp">/^_context/</span>,
- next: Twig.expression.set.operations_extended.concat([
- Twig.expression.type.parameter.start]),
- compile: Twig.expression.fn.compile.push,
- parse: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">token, stack, context</span>) </span>{
- stack.push(context);
- }
- },
- {
- <span class="hljs-comment">/**
- * Match a number (integer or decimal)
- */</span>
- type: Twig.expression.type.number,</pre></div></div>
-
- </li>
-
-
- <li id="section-275">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-275">&#182;</a>
- </div>
- <p>match a number</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> regex: <span class="hljs-regexp">/^\-?\d+(\.\d+)?/</span>,
- next: Twig.expression.set.operations,
- compile: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">token, stack, output</span>) </span>{
- token.value = <span class="hljs-built_in">Number</span>(token.value);
- output.push(token);
- },
- parse: Twig.expression.fn.parse.push_value
- },
- {
- <span class="hljs-comment">/**
- * Match a boolean
- */</span>
- type: Twig.expression.type.bool,
- regex: <span class="hljs-regexp">/^(true|TRUE|false|FALSE)/</span>,
- next: Twig.expression.set.operations,
- compile: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">token, stack, output</span>) </span>{
- token.value = (token.match[<span class="hljs-number">0</span>].toLowerCase( ) === <span class="hljs-string">"true"</span>);
- <span class="hljs-keyword">delete</span> token.match;
- output.push(token);
- },
- parse: Twig.expression.fn.parse.push_value
- }
- ];
-
- <span class="hljs-comment">/**
- * Resolve a context value.
- *
- * If the value is a function, it is executed with a context parameter.
- *
- * @param {string} key The context object key.
- * @param {Object} context The render context.
- */</span>
- Twig.expression.resolve = <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">value, context, params</span>) </span>{
- <span class="hljs-keyword">if</span> (<span class="hljs-keyword">typeof</span> value == <span class="hljs-string">'function'</span>) {
- <span class="hljs-keyword">return</span> value.apply(context, params || []);
- } <span class="hljs-keyword">else</span> {
- <span class="hljs-keyword">return</span> value;
- }
- };
-
- <span class="hljs-comment">/**
- * Registry for logic handlers.
- */</span>
- Twig.expression.handler = {};
-
- <span class="hljs-comment">/**
- * Define a new expression type, available at Twig.logic.type.{type}
- *
- * @param {string} type The name of the new type.
- */</span>
- Twig.expression.extendType = <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">type</span>) </span>{
- Twig.expression.type[type] = <span class="hljs-string">"Twig.expression.type."</span> + type;
- };
-
- <span class="hljs-comment">/**
- * Extend the expression parsing functionality with a new definition.
- *
- * Token definitions follow this format:
- * {
- * type: One of Twig.expression.type.[type], either pre-defined or added using
- * Twig.expression.extendType
- *
- * next: Array of types from Twig.expression.type that can follow this token,
- *
- * regex: A regex or array of regex's that should match the token.
- *
- * compile: function(token, stack, output) called when this token is being compiled.
- * Should return an object with stack and output set.
- *
- * parse: function(token, stack, context) called when this token is being parsed.
- * Should return an object with stack and context set.
- * }
- *
- * @param {Object} definition A token definition.
- */</span>
- Twig.expression.extend = <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">definition</span>) </span>{
- <span class="hljs-keyword">if</span> (!definition.type) {
- <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> Twig.Error(<span class="hljs-string">"Unable to extend logic definition. No type provided for "</span> + definition);
- }
- Twig.expression.handler[definition.type] = definition;
- };</pre></div></div>
-
- </li>
-
-
- <li id="section-276">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-276">&#182;</a>
- </div>
- <p>Extend with built-in expressions</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">while</span> (Twig.expression.definitions.length &gt; <span class="hljs-number">0</span>) {
- Twig.expression.extend(Twig.expression.definitions.shift());
- }
-
- <span class="hljs-comment">/**
- * Break an expression into tokens defined in Twig.expression.definitions.
- *
- * @param {string} expression The string to tokenize.
- *
- * @return {Array} An array of tokens.
- */</span>
- Twig.expression.tokenize = <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">expression</span>) </span>{
- <span class="hljs-keyword">var</span> tokens = [],</pre></div></div>
-
- </li>
-
-
- <li id="section-277">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-277">&#182;</a>
- </div>
- <p>Keep an offset of the location in the expression for error messages.</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> exp_offset = <span class="hljs-number">0</span>,</pre></div></div>
-
- </li>
-
-
- <li id="section-278">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-278">&#182;</a>
- </div>
- <p>The valid next tokens of the previous token</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> next = <span class="hljs-literal">null</span>,</pre></div></div>
-
- </li>
-
-
- <li id="section-279">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-279">&#182;</a>
- </div>
- <p>Match information</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> type, regex, regex_array,</pre></div></div>
-
- </li>
-
-
- <li id="section-280">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-280">&#182;</a>
- </div>
- <p>The possible next token for the match</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> token_next,</pre></div></div>
-
- </li>
-
-
- <li id="section-281">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-281">&#182;</a>
- </div>
- <p>Has a match been found from the definitions</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> match_found, invalid_matches = [], match_function;
-
- match_function = <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) </span>{
- <span class="hljs-keyword">var</span> match = <span class="hljs-built_in">Array</span>.prototype.slice.apply(<span class="hljs-built_in">arguments</span>),
- string = match.pop(),
- offset = match.pop();
-
- Twig.log.trace(<span class="hljs-string">"Twig.expression.tokenize"</span>,
- <span class="hljs-string">"Matched a "</span>, type, <span class="hljs-string">" regular expression of "</span>, match);
-
- <span class="hljs-keyword">if</span> (next &amp;&amp; Twig.indexOf(next, type) &lt; <span class="hljs-number">0</span>) {
- invalid_matches.push(
- type + <span class="hljs-string">" cannot follow a "</span> + tokens[tokens.length - <span class="hljs-number">1</span>].type +
- <span class="hljs-string">" at template:"</span> + exp_offset + <span class="hljs-string">" near '"</span> + match[<span class="hljs-number">0</span>].substring(<span class="hljs-number">0</span>, <span class="hljs-number">20</span>) +
- <span class="hljs-string">"...'"</span>
- );</pre></div></div>
-
- </li>
-
-
- <li id="section-282">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-282">&#182;</a>
- </div>
- <p>Not a match, don’t change the expression</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">return</span> match[<span class="hljs-number">0</span>];
- }</pre></div></div>
-
- </li>
-
-
- <li id="section-283">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-283">&#182;</a>
- </div>
- <p>Validate the token if a validation function is provided</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> (Twig.expression.handler[type].validate &amp;&amp;
- !Twig.expression.handler[type].validate(match, tokens)) {
- <span class="hljs-keyword">return</span> match[<span class="hljs-number">0</span>];
- }
-
- invalid_matches = [];
-
- tokens.push({
- type: type,
- value: match[<span class="hljs-number">0</span>],
- match: match
- });
-
- match_found = <span class="hljs-literal">true</span>;
- next = token_next;
- exp_offset += match[<span class="hljs-number">0</span>].length;</pre></div></div>
-
- </li>
-
-
- <li id="section-284">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-284">&#182;</a>
- </div>
- <p>Does the token need to return output back to the expression string
-e.g. a function match of cycle( might return the ‘(‘ back to the expression
-This allows look-ahead to differentiate between token types (e.g. functions and variable names)</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> (Twig.expression.handler[type].transform) {
- <span class="hljs-keyword">return</span> Twig.expression.handler[type].transform(match, tokens);
- }
- <span class="hljs-keyword">return</span> <span class="hljs-string">''</span>;
- };
-
- Twig.log.debug(<span class="hljs-string">"Twig.expression.tokenize"</span>, <span class="hljs-string">"Tokenizing expression "</span>, expression);
-
- <span class="hljs-keyword">while</span> (expression.length &gt; <span class="hljs-number">0</span>) {
- expression = expression.trim();
- <span class="hljs-keyword">for</span> (type <span class="hljs-keyword">in</span> Twig.expression.handler) {
- <span class="hljs-keyword">if</span> (Twig.expression.handler.hasOwnProperty(type)) {
- token_next = Twig.expression.handler[type].next;
- regex = Twig.expression.handler[type].regex;</pre></div></div>
-
- </li>
-
-
- <li id="section-285">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-285">&#182;</a>
- </div>
- <p>Twig.log.trace(“Checking type “, type, “ on “, expression);</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> (regex <span class="hljs-keyword">instanceof</span> <span class="hljs-built_in">Array</span>) {
- regex_array = regex;
- } <span class="hljs-keyword">else</span> {
- regex_array = [regex];
- }
-
- match_found = <span class="hljs-literal">false</span>;
- <span class="hljs-keyword">while</span> (regex_array.length &gt; <span class="hljs-number">0</span>) {
- regex = regex_array.pop();
- expression = expression.replace(regex, match_function);
- }</pre></div></div>
-
- </li>
-
-
- <li id="section-286">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-286">&#182;</a>
- </div>
- <p>An expression token has been matched. Break the for loop and start trying to
- match the next template (if expression isn’t empty.)</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> (match_found) {
- <span class="hljs-keyword">break</span>;
- }
- }
- }
- <span class="hljs-keyword">if</span> (!match_found) {
- <span class="hljs-keyword">if</span> (invalid_matches.length &gt; <span class="hljs-number">0</span>) {
- <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> Twig.Error(invalid_matches.join(<span class="hljs-string">" OR "</span>));
- } <span class="hljs-keyword">else</span> {
- <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> Twig.Error(<span class="hljs-string">"Unable to parse '"</span> + expression + <span class="hljs-string">"' at template position"</span> + exp_offset);
- }
- }
- }
-
- Twig.log.trace(<span class="hljs-string">"Twig.expression.tokenize"</span>, <span class="hljs-string">"Tokenized to "</span>, tokens);
- <span class="hljs-keyword">return</span> tokens;
- };
-
- <span class="hljs-comment">/**
- * Compile an expression token.
- *
- * @param {Object} raw_token The uncompiled token.
- *
- * @return {Object} The compiled token.
- */</span>
- Twig.expression.compile = <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">raw_token</span>) </span>{
- <span class="hljs-keyword">var</span> expression = raw_token.value,</pre></div></div>
-
- </li>
-
-
- <li id="section-287">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-287">&#182;</a>
- </div>
- <p>Tokenize expression</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> tokens = Twig.expression.tokenize(expression),
- token = <span class="hljs-literal">null</span>,
- output = [],
- stack = [],
- token_template = <span class="hljs-literal">null</span>;
-
- Twig.log.trace(<span class="hljs-string">"Twig.expression.compile: "</span>, <span class="hljs-string">"Compiling "</span>, expression);</pre></div></div>
-
- </li>
-
-
- <li id="section-288">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-288">&#182;</a>
- </div>
- <p>Push tokens into RPN stack using the Sunting-yard algorithm
-See <a href="http://en.wikipedia.org/wiki/Shunting_yard_algorithm">http://en.wikipedia.org/wiki/Shunting_yard_algorithm</a></p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre>
- <span class="hljs-keyword">while</span> (tokens.length &gt; <span class="hljs-number">0</span>) {
- token = tokens.shift();
- token_template = Twig.expression.handler[token.type];
-
- Twig.log.trace(<span class="hljs-string">"Twig.expression.compile: "</span>, <span class="hljs-string">"Compiling "</span>, token);</pre></div></div>
-
- </li>
-
-
- <li id="section-289">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-289">&#182;</a>
- </div>
- <p>Compile the template</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> token_template.compile &amp;&amp; token_template.compile(token, stack, output);
-
- Twig.log.trace(<span class="hljs-string">"Twig.expression.compile: "</span>, <span class="hljs-string">"Stack is"</span>, stack);
- Twig.log.trace(<span class="hljs-string">"Twig.expression.compile: "</span>, <span class="hljs-string">"Output is"</span>, output);
- }
-
- <span class="hljs-keyword">while</span>(stack.length &gt; <span class="hljs-number">0</span>) {
- output.push(stack.pop());
- }
-
- Twig.log.trace(<span class="hljs-string">"Twig.expression.compile: "</span>, <span class="hljs-string">"Final output is"</span>, output);
-
- raw_token.stack = output;
- <span class="hljs-keyword">delete</span> raw_token.value;
-
- <span class="hljs-keyword">return</span> raw_token;
- };
-
-
- <span class="hljs-comment">/**
- * Parse an RPN expression stack within a context.
- *
- * @param {Array} tokens An array of compiled expression tokens.
- * @param {Object} context The render context to parse the tokens with.
- *
- * @return {Object} The result of parsing all the tokens. The result
- * can be anything, String, Array, Object, etc... based on
- * the given expression.
- */</span>
- Twig.expression.parse = <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">tokens, context</span>) </span>{
- <span class="hljs-keyword">var</span> that = <span class="hljs-keyword">this</span>;</pre></div></div>
-
- </li>
-
-
- <li id="section-290">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-290">&#182;</a>
- </div>
- <p>If the token isn’t an array, make it one.</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> (!(tokens <span class="hljs-keyword">instanceof</span> <span class="hljs-built_in">Array</span>)) {
- tokens = [tokens];
- }</pre></div></div>
-
- </li>
-
-
- <li id="section-291">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-291">&#182;</a>
- </div>
- <p>The output stack</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">var</span> stack = [],
- token_template = <span class="hljs-literal">null</span>;
-
- Twig.forEach(tokens, <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">token</span>) </span>{
- token_template = Twig.expression.handler[token.type];
-
- token_template.parse &amp;&amp; token_template.parse.apply(that, [token, stack, context]);
- });</pre></div></div>
-
- </li>
-
-
- <li id="section-292">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-292">&#182;</a>
- </div>
- <p>Pop the final value off the stack</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">return</span> stack.pop();
- };
-
- <span class="hljs-keyword">return</span> Twig;
-
-})( Twig || { } );</pre></div></div>
-
- </li>
-
-
- <li id="section-293">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-293">&#182;</a>
- </div>
- <pre><code>Twig.js
-Available under the BSD <span class="hljs-number">2</span>-Clause License
-https:<span class="hljs-comment">//github.com/justjohn/twig.js</span>
-</code></pre>
- </div>
-
- </li>
-
-
- <li id="section-294">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-294">&#182;</a>
- </div>
- <h2 id="twig-expression-operator-js">twig.expression.operator.js</h2>
-<p>This file handles operator lookups and parsing.</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre><span class="hljs-keyword">var</span> Twig = (<span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">Twig</span>) </span>{
-<span class="hljs-meta"> "use strict"</span>;
-
- <span class="hljs-comment">/**
- * Operator associativity constants.
- */</span>
- Twig.expression.operator = {
- leftToRight: <span class="hljs-string">'leftToRight'</span>,
- rightToLeft: <span class="hljs-string">'rightToLeft'</span>
- };
-
- <span class="hljs-keyword">var</span> containment = <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">a, b</span>) </span>{
- <span class="hljs-keyword">if</span> (b === <span class="hljs-literal">undefined</span> || b === <span class="hljs-literal">null</span>) {
- <span class="hljs-keyword">return</span> <span class="hljs-literal">null</span>;
- } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (b.indexOf !== <span class="hljs-literal">undefined</span>) {</pre></div></div>
-
- </li>
-
-
- <li id="section-295">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-295">&#182;</a>
- </div>
- <p>String</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">return</span> a === b || a !== <span class="hljs-string">''</span> &amp;&amp; b.indexOf(a) &gt; <span class="hljs-number">-1</span>;
- } <span class="hljs-keyword">else</span> {
- <span class="hljs-keyword">var</span> el;
- <span class="hljs-keyword">for</span> (el <span class="hljs-keyword">in</span> b) {
- <span class="hljs-keyword">if</span> (b.hasOwnProperty(el) &amp;&amp; b[el] === a) {
- <span class="hljs-keyword">return</span> <span class="hljs-literal">true</span>;
- }
- }
- <span class="hljs-keyword">return</span> <span class="hljs-literal">false</span>;
- }
- };
-
- <span class="hljs-comment">/**
- * Get the precidence and associativity of an operator. These follow the order that C/C++ use.
- * See http://en.wikipedia.org/wiki/Operators_in_C_and_C++ for the table of values.
- */</span>
- Twig.expression.operator.lookup = <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">operator, token</span>) </span>{
- <span class="hljs-keyword">switch</span> (operator) {
- <span class="hljs-keyword">case</span> <span class="hljs-string">".."</span>:
- <span class="hljs-keyword">case</span> <span class="hljs-string">'not in'</span>:
- <span class="hljs-keyword">case</span> <span class="hljs-string">'in'</span>:
- token.precidence = <span class="hljs-number">20</span>;
- token.associativity = Twig.expression.operator.leftToRight;
- <span class="hljs-keyword">break</span>;
-
- <span class="hljs-keyword">case</span> <span class="hljs-string">','</span>:
- token.precidence = <span class="hljs-number">18</span>;
- token.associativity = Twig.expression.operator.leftToRight;
- <span class="hljs-keyword">break</span>;</pre></div></div>
-
- </li>
-
-
- <li id="section-296">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-296">&#182;</a>
- </div>
- <p>Ternary</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">case</span> <span class="hljs-string">'?'</span>:
- <span class="hljs-keyword">case</span> <span class="hljs-string">':'</span>:
- token.precidence = <span class="hljs-number">16</span>;
- token.associativity = Twig.expression.operator.rightToLeft;
- <span class="hljs-keyword">break</span>;
-
- <span class="hljs-keyword">case</span> <span class="hljs-string">'or'</span>:
- token.precidence = <span class="hljs-number">14</span>;
- token.associativity = Twig.expression.operator.leftToRight;
- <span class="hljs-keyword">break</span>;
-
- <span class="hljs-keyword">case</span> <span class="hljs-string">'and'</span>:
- token.precidence = <span class="hljs-number">13</span>;
- token.associativity = Twig.expression.operator.leftToRight;
- <span class="hljs-keyword">break</span>;
-
- <span class="hljs-keyword">case</span> <span class="hljs-string">'=='</span>:
- <span class="hljs-keyword">case</span> <span class="hljs-string">'!='</span>:
- token.precidence = <span class="hljs-number">9</span>;
- token.associativity = Twig.expression.operator.leftToRight;
- <span class="hljs-keyword">break</span>;
-
- <span class="hljs-keyword">case</span> <span class="hljs-string">'&lt;'</span>:
- <span class="hljs-keyword">case</span> <span class="hljs-string">'&lt;='</span>:
- <span class="hljs-keyword">case</span> <span class="hljs-string">'&gt;'</span>:
- <span class="hljs-keyword">case</span> <span class="hljs-string">'&gt;='</span>:
- token.precidence = <span class="hljs-number">8</span>;
- token.associativity = Twig.expression.operator.leftToRight;
- <span class="hljs-keyword">break</span>;
-
-
- <span class="hljs-keyword">case</span> <span class="hljs-string">'~'</span>: <span class="hljs-comment">// String concatination</span>
- <span class="hljs-keyword">case</span> <span class="hljs-string">'+'</span>:
- <span class="hljs-keyword">case</span> <span class="hljs-string">'-'</span>:
- token.precidence = <span class="hljs-number">6</span>;
- token.associativity = Twig.expression.operator.leftToRight;
- <span class="hljs-keyword">break</span>;
-
- <span class="hljs-keyword">case</span> <span class="hljs-string">'//'</span>:
- <span class="hljs-keyword">case</span> <span class="hljs-string">'**'</span>:
- <span class="hljs-keyword">case</span> <span class="hljs-string">'*'</span>:
- <span class="hljs-keyword">case</span> <span class="hljs-string">'/'</span>:
- <span class="hljs-keyword">case</span> <span class="hljs-string">'%'</span>:
- token.precidence = <span class="hljs-number">5</span>;
- token.associativity = Twig.expression.operator.leftToRight;
- <span class="hljs-keyword">break</span>;
-
- <span class="hljs-keyword">case</span> <span class="hljs-string">'not'</span>:
- token.precidence = <span class="hljs-number">3</span>;
- token.associativity = Twig.expression.operator.rightToLeft;
- <span class="hljs-keyword">break</span>;
-
- <span class="hljs-keyword">default</span>:
- <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> Twig.Error(operator + <span class="hljs-string">" is an unknown operator."</span>);
- }
- token.operator = operator;
- <span class="hljs-keyword">return</span> token;
- };
-
- <span class="hljs-comment">/**
- * Handle operations on the RPN stack.
- *
- * Returns the updated stack.
- */</span>
- Twig.expression.operator.parse = <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">operator, stack</span>) </span>{
- Twig.log.trace(<span class="hljs-string">"Twig.expression.operator.parse: "</span>, <span class="hljs-string">"Handling "</span>, operator);
- <span class="hljs-keyword">var</span> a, b, c;
- <span class="hljs-keyword">switch</span> (operator) {
- <span class="hljs-keyword">case</span> <span class="hljs-string">':'</span>:</pre></div></div>
-
- </li>
-
-
- <li id="section-297">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-297">&#182;</a>
- </div>
- <p>Ignore</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">break</span>;
-
- <span class="hljs-keyword">case</span> <span class="hljs-string">'?'</span>:
- c = stack.pop(); <span class="hljs-comment">// false expr</span>
- b = stack.pop(); <span class="hljs-comment">// true expr</span>
- a = stack.pop(); <span class="hljs-comment">// conditional</span>
- <span class="hljs-keyword">if</span> (a) {
- stack.push(b);
- } <span class="hljs-keyword">else</span> {
- stack.push(c);
- }
- <span class="hljs-keyword">break</span>;
-
- <span class="hljs-keyword">case</span> <span class="hljs-string">'+'</span>:
- b = <span class="hljs-built_in">parseFloat</span>(stack.pop());
- a = <span class="hljs-built_in">parseFloat</span>(stack.pop());
- stack.push(a + b);
- <span class="hljs-keyword">break</span>;
-
- <span class="hljs-keyword">case</span> <span class="hljs-string">'-'</span>:
- b = <span class="hljs-built_in">parseFloat</span>(stack.pop());
- a = <span class="hljs-built_in">parseFloat</span>(stack.pop());
- stack.push(a - b);
- <span class="hljs-keyword">break</span>;
-
- <span class="hljs-keyword">case</span> <span class="hljs-string">'*'</span>:
- b = <span class="hljs-built_in">parseFloat</span>(stack.pop());
- a = <span class="hljs-built_in">parseFloat</span>(stack.pop());
- stack.push(a * b);
- <span class="hljs-keyword">break</span>;
-
- <span class="hljs-keyword">case</span> <span class="hljs-string">'/'</span>:
- b = <span class="hljs-built_in">parseFloat</span>(stack.pop());
- a = <span class="hljs-built_in">parseFloat</span>(stack.pop());
- stack.push(a / b);
- <span class="hljs-keyword">break</span>;
-
- <span class="hljs-keyword">case</span> <span class="hljs-string">'//'</span>:
- b = <span class="hljs-built_in">parseFloat</span>(stack.pop());
- a = <span class="hljs-built_in">parseFloat</span>(stack.pop());
- stack.push(<span class="hljs-built_in">parseInt</span>(a / b));
- <span class="hljs-keyword">break</span>;
-
- <span class="hljs-keyword">case</span> <span class="hljs-string">'%'</span>:
- b = <span class="hljs-built_in">parseFloat</span>(stack.pop());
- a = <span class="hljs-built_in">parseFloat</span>(stack.pop());
- stack.push(a % b);
- <span class="hljs-keyword">break</span>;
-
- <span class="hljs-keyword">case</span> <span class="hljs-string">'~'</span>:
- b = stack.pop();
- a = stack.pop();
- stack.push( (a != <span class="hljs-literal">null</span> ? a.toString() : <span class="hljs-string">""</span>)
- + (b != <span class="hljs-literal">null</span> ? b.toString() : <span class="hljs-string">""</span>) );
- <span class="hljs-keyword">break</span>;
-
- <span class="hljs-keyword">case</span> <span class="hljs-string">'not'</span>:
- <span class="hljs-keyword">case</span> <span class="hljs-string">'!'</span>:
- stack.push(!stack.pop());
- <span class="hljs-keyword">break</span>;
-
- <span class="hljs-keyword">case</span> <span class="hljs-string">'&lt;'</span>:
- b = stack.pop();
- a = stack.pop();
- stack.push(a &lt; b);
- <span class="hljs-keyword">break</span>;
-
- <span class="hljs-keyword">case</span> <span class="hljs-string">'&lt;='</span>:
- b = stack.pop();
- a = stack.pop();
- stack.push(a &lt;= b);
- <span class="hljs-keyword">break</span>;
-
- <span class="hljs-keyword">case</span> <span class="hljs-string">'&gt;'</span>:
- b = stack.pop();
- a = stack.pop();
- stack.push(a &gt; b);
- <span class="hljs-keyword">break</span>;
-
- <span class="hljs-keyword">case</span> <span class="hljs-string">'&gt;='</span>:
- b = stack.pop();
- a = stack.pop();
- stack.push(a &gt;= b);
- <span class="hljs-keyword">break</span>;
-
- <span class="hljs-keyword">case</span> <span class="hljs-string">'==='</span>:
- b = stack.pop();
- a = stack.pop();
- stack.push(a === b);
- <span class="hljs-keyword">break</span>;
-
- <span class="hljs-keyword">case</span> <span class="hljs-string">'=='</span>:
- b = stack.pop();
- a = stack.pop();
- stack.push(a == b);
- <span class="hljs-keyword">break</span>;
-
- <span class="hljs-keyword">case</span> <span class="hljs-string">'!=='</span>:
- b = stack.pop();
- a = stack.pop();
- stack.push(a !== b);
- <span class="hljs-keyword">break</span>;
-
- <span class="hljs-keyword">case</span> <span class="hljs-string">'!='</span>:
- b = stack.pop();
- a = stack.pop();
- stack.push(a != b);
- <span class="hljs-keyword">break</span>;
-
- <span class="hljs-keyword">case</span> <span class="hljs-string">'or'</span>:
- b = stack.pop();
- a = stack.pop();
- stack.push(a || b);
- <span class="hljs-keyword">break</span>;
-
- <span class="hljs-keyword">case</span> <span class="hljs-string">'and'</span>:
- b = stack.pop();
- a = stack.pop();
- stack.push(a &amp;&amp; b);
- <span class="hljs-keyword">break</span>;
-
- <span class="hljs-keyword">case</span> <span class="hljs-string">'**'</span>:
- b = stack.pop();
- a = stack.pop();
- stack.push(<span class="hljs-built_in">Math</span>.pow(a, b));
- <span class="hljs-keyword">break</span>;
-
-
- <span class="hljs-keyword">case</span> <span class="hljs-string">'not in'</span>:
- b = stack.pop();
- a = stack.pop();
- stack.push( !containment(a, b) );
- <span class="hljs-keyword">break</span>;
-
- <span class="hljs-keyword">case</span> <span class="hljs-string">'in'</span>:
- b = stack.pop();
- a = stack.pop();
- stack.push( containment(a, b) );
- <span class="hljs-keyword">break</span>;
-
- <span class="hljs-keyword">case</span> <span class="hljs-string">'..'</span>:
- b = stack.pop();
- a = stack.pop();
- stack.push( Twig.functions.range(a, b) );
- <span class="hljs-keyword">break</span>;
-
- <span class="hljs-keyword">default</span>:
- <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> Twig.Error(operator + <span class="hljs-string">" is an unknown operator."</span>);
- }
- };
-
- <span class="hljs-keyword">return</span> Twig;
-
-})( Twig || { } );</pre></div></div>
-
- </li>
-
-
- <li id="section-298">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-298">&#182;</a>
- </div>
- <pre><code>Twig.js
-Available under the BSD <span class="hljs-number">2</span>-Clause License
-https:<span class="hljs-comment">//github.com/justjohn/twig.js</span>
-</code></pre>
- </div>
-
- </li>
-
-
- <li id="section-299">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-299">&#182;</a>
- </div>
- <h2 id="twig-filters-js">twig.filters.js</h2>
-<p>This file handles parsing filters.</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre><span class="hljs-keyword">var</span> Twig = (<span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">Twig</span>) </span>{</pre></div></div>
-
- </li>
-
-
- <li id="section-300">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-300">&#182;</a>
- </div>
- <p>Determine object type</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">is</span>(<span class="hljs-params">type, obj</span>) </span>{
- <span class="hljs-keyword">var</span> clas = <span class="hljs-built_in">Object</span>.prototype.toString.call(obj).slice(<span class="hljs-number">8</span>, <span class="hljs-number">-1</span>);
- <span class="hljs-keyword">return</span> obj !== <span class="hljs-literal">undefined</span> &amp;&amp; obj !== <span class="hljs-literal">null</span> &amp;&amp; clas === type;
- }
-
- Twig.filters = {</pre></div></div>
-
- </li>
-
-
- <li id="section-301">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-301">&#182;</a>
- </div>
- <p>String Filters</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> upper: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">value</span>) </span>{
- <span class="hljs-keyword">if</span> ( <span class="hljs-keyword">typeof</span> value !== <span class="hljs-string">"string"</span> ) {
- <span class="hljs-keyword">return</span> value;
- }
-
- <span class="hljs-keyword">return</span> value.toUpperCase();
- },
- lower: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">value</span>) </span>{
- <span class="hljs-keyword">if</span> ( <span class="hljs-keyword">typeof</span> value !== <span class="hljs-string">"string"</span> ) {
- <span class="hljs-keyword">return</span> value;
- }
-
- <span class="hljs-keyword">return</span> value.toLowerCase();
- },
- capitalize: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">value</span>) </span>{
- <span class="hljs-keyword">if</span> ( <span class="hljs-keyword">typeof</span> value !== <span class="hljs-string">"string"</span> ) {
- <span class="hljs-keyword">return</span> value;
- }
-
- <span class="hljs-keyword">return</span> value.substr(<span class="hljs-number">0</span>, <span class="hljs-number">1</span>).toUpperCase() + value.toLowerCase().substr(<span class="hljs-number">1</span>);
- },
- title: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">value</span>) </span>{
- <span class="hljs-keyword">if</span> ( <span class="hljs-keyword">typeof</span> value !== <span class="hljs-string">"string"</span> ) {
- <span class="hljs-keyword">return</span> value;
- }
-
- <span class="hljs-keyword">return</span> value.toLowerCase().replace( <span class="hljs-regexp">/(^|\s)([a-z])/g</span> , <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">m, p1, p2</span>)</span>{
- <span class="hljs-keyword">return</span> p1 + p2.toUpperCase();
- });
- },
- length: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">value</span>) </span>{
- <span class="hljs-keyword">if</span> (Twig.lib.is(<span class="hljs-string">"Array"</span>, value) || <span class="hljs-keyword">typeof</span> value === <span class="hljs-string">"string"</span>) {
- <span class="hljs-keyword">return</span> value.length;
- } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (Twig.lib.is(<span class="hljs-string">"Object"</span>, value)) {
- <span class="hljs-keyword">if</span> (value._keys === <span class="hljs-literal">undefined</span>) {
- <span class="hljs-keyword">return</span> <span class="hljs-built_in">Object</span>.keys(value).length;
- } <span class="hljs-keyword">else</span> {
- <span class="hljs-keyword">return</span> value._keys.length;
- }
- } <span class="hljs-keyword">else</span> {
- <span class="hljs-keyword">return</span> <span class="hljs-number">0</span>;
- }
- },</pre></div></div>
-
- </li>
-
-
- <li id="section-302">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-302">&#182;</a>
- </div>
- <p>Array/Object Filters</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> reverse: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">value</span>) </span>{
- <span class="hljs-keyword">if</span> (is(<span class="hljs-string">"Array"</span>, value)) {
- <span class="hljs-keyword">return</span> value.reverse();
- } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (is(<span class="hljs-string">"String"</span>, value)) {
- <span class="hljs-keyword">return</span> value.split(<span class="hljs-string">""</span>).reverse().join(<span class="hljs-string">""</span>);
- } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (is(<span class="hljs-string">"Object"</span>, value)) {
- <span class="hljs-keyword">var</span> keys = value._keys || <span class="hljs-built_in">Object</span>.keys(value).reverse();
- value._keys = keys;
- <span class="hljs-keyword">return</span> value;
- }
- },
- sort: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">value</span>) </span>{
- <span class="hljs-keyword">if</span> (is(<span class="hljs-string">"Array"</span>, value)) {
- <span class="hljs-keyword">return</span> value.sort();
- } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (is(<span class="hljs-string">'Object'</span>, value)) {</pre></div></div>
-
- </li>
-
-
- <li id="section-303">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-303">&#182;</a>
- </div>
- <p>Sorting objects isn’t obvious since the order of
-returned keys isn’t guaranteed in JavaScript.
-Because of this we use a “hidden” key called _keys to
-store the keys in the order we want to return them.</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre>
- <span class="hljs-keyword">delete</span> value._keys;
- <span class="hljs-keyword">var</span> keys = <span class="hljs-built_in">Object</span>.keys(value),
- sorted_keys = keys.sort(<span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">a, b</span>) </span>{
- <span class="hljs-keyword">var</span> a1, a2;</pre></div></div>
-
- </li>
-
-
- <li id="section-304">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-304">&#182;</a>
- </div>
- <p>if a and b are comparable, we’re fine :-)</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span>((value[a] &gt; value[b]) == !(value[a] &lt;= value[b])) {
- <span class="hljs-keyword">return</span> value[a] &gt; value[b] ? <span class="hljs-number">1</span> :
- value[a] &lt; value[b] ? <span class="hljs-number">-1</span> :
- <span class="hljs-number">0</span>;
- }</pre></div></div>
-
- </li>
-
-
- <li id="section-305">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-305">&#182;</a>
- </div>
- <p>if a and b can be parsed as numbers, we can compare
-their numeric value</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span>(!<span class="hljs-built_in">isNaN</span>(a1 = <span class="hljs-built_in">parseFloat</span>(value[a])) &amp;&amp;
- !<span class="hljs-built_in">isNaN</span>(b1 = <span class="hljs-built_in">parseFloat</span>(value[b]))) {
- <span class="hljs-keyword">return</span> a1 &gt; b1 ? <span class="hljs-number">1</span> :
- a1 &lt; b1 ? <span class="hljs-number">-1</span> :
- <span class="hljs-number">0</span>;
- }</pre></div></div>
-
- </li>
-
-
- <li id="section-306">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-306">&#182;</a>
- </div>
- <p>if one of the values is a string, we convert the
-other value to string as well</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span>(<span class="hljs-keyword">typeof</span> value[a] == <span class="hljs-string">'string'</span>) {
- <span class="hljs-keyword">return</span> value[a] &gt; value[b].toString() ? <span class="hljs-number">1</span> :
- value[a] &lt; value[b].toString() ? <span class="hljs-number">-1</span> :
- <span class="hljs-number">0</span>;
- }
- <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span>(<span class="hljs-keyword">typeof</span> value[b] == <span class="hljs-string">'string'</span>) {
- <span class="hljs-keyword">return</span> value[a].toString() &gt; value[b] ? <span class="hljs-number">1</span> :
- value[a].toString() &lt; value[b] ? <span class="hljs-number">-1</span> :
- <span class="hljs-number">0</span>;
- }</pre></div></div>
-
- </li>
-
-
- <li id="section-307">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-307">&#182;</a>
- </div>
- <p>everything failed - return ‘null’ as sign, that
-the values are not comparable</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">else</span> {
- <span class="hljs-keyword">return</span> <span class="hljs-literal">null</span>;
- }
- });
- value._keys = sorted_keys;
- <span class="hljs-keyword">return</span> value;
- }
- },
- keys: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">value</span>) </span>{
- <span class="hljs-keyword">if</span> (value === <span class="hljs-literal">undefined</span> || value === <span class="hljs-literal">null</span>){
- <span class="hljs-keyword">return</span>;
- }
-
- <span class="hljs-keyword">var</span> keyset = value._keys || <span class="hljs-built_in">Object</span>.keys(value),
- output = [];
-
- Twig.forEach(keyset, <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">key</span>) </span>{
- <span class="hljs-keyword">if</span> (key === <span class="hljs-string">"_keys"</span>) <span class="hljs-keyword">return</span>; <span class="hljs-comment">// Ignore the _keys property</span>
- <span class="hljs-keyword">if</span> (value.hasOwnProperty(key)) {
- output.push(key);
- }
- });
- <span class="hljs-keyword">return</span> output;
- },
- url_encode: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">value</span>) </span>{
- <span class="hljs-keyword">if</span> (value === <span class="hljs-literal">undefined</span> || value === <span class="hljs-literal">null</span>){
- <span class="hljs-keyword">return</span>;
- }
-
- <span class="hljs-keyword">var</span> result = <span class="hljs-built_in">encodeURIComponent</span>(value);
- result = result.replace(<span class="hljs-string">"'"</span>, <span class="hljs-string">"%27"</span>);
- <span class="hljs-keyword">return</span> result;
- },
- join: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">value, params</span>) </span>{
- <span class="hljs-keyword">if</span> (value === <span class="hljs-literal">undefined</span> || value === <span class="hljs-literal">null</span>){
- <span class="hljs-keyword">return</span>;
- }
-
- <span class="hljs-keyword">var</span> join_str = <span class="hljs-string">""</span>,
- output = [],
- keyset = <span class="hljs-literal">null</span>;
-
- <span class="hljs-keyword">if</span> (params &amp;&amp; params[<span class="hljs-number">0</span>]) {
- join_str = params[<span class="hljs-number">0</span>];
- }
- <span class="hljs-keyword">if</span> (is(<span class="hljs-string">"Array"</span>, value)) {
- output = value;
- } <span class="hljs-keyword">else</span> {
- keyset = value._keys || <span class="hljs-built_in">Object</span>.keys(value);
- Twig.forEach(keyset, <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">key</span>) </span>{
- <span class="hljs-keyword">if</span> (key === <span class="hljs-string">"_keys"</span>) <span class="hljs-keyword">return</span>; <span class="hljs-comment">// Ignore the _keys property</span>
- <span class="hljs-keyword">if</span> (value.hasOwnProperty(key)) {
- output.push(value[key]);
- }
- });
- }
- <span class="hljs-keyword">return</span> output.join(join_str);
- },
- <span class="hljs-string">"default"</span>: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">value, params</span>) </span>{
- <span class="hljs-keyword">if</span> (params !== <span class="hljs-literal">undefined</span> &amp;&amp; params.length &gt; <span class="hljs-number">1</span>) {
- <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> Twig.Error(<span class="hljs-string">"default filter expects one argument"</span>);
- }
- <span class="hljs-keyword">if</span> (value === <span class="hljs-literal">undefined</span> || value === <span class="hljs-literal">null</span> || value === <span class="hljs-string">''</span> ) {
- <span class="hljs-keyword">if</span> (params === <span class="hljs-literal">undefined</span>) {
- <span class="hljs-keyword">return</span> <span class="hljs-string">''</span>;
- }
-
- <span class="hljs-keyword">return</span> params[<span class="hljs-number">0</span>];
- } <span class="hljs-keyword">else</span> {
- <span class="hljs-keyword">return</span> value;
- }
- },
- json_encode: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">value</span>) </span>{
- <span class="hljs-keyword">if</span>(value === <span class="hljs-literal">undefined</span> || value === <span class="hljs-literal">null</span>) {
- <span class="hljs-keyword">return</span> <span class="hljs-string">"null"</span>;
- }
- <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> ((<span class="hljs-keyword">typeof</span> value == <span class="hljs-string">'object'</span>) &amp;&amp; (is(<span class="hljs-string">"Array"</span>, value))) {
- output = [];
-
- Twig.forEach(value, <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">v</span>) </span>{
- output.push(Twig.filters.json_encode(v));
- });
-
- <span class="hljs-keyword">return</span> <span class="hljs-string">"["</span> + output.join(<span class="hljs-string">","</span>) + <span class="hljs-string">"]"</span>;
- }
- <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (<span class="hljs-keyword">typeof</span> value == <span class="hljs-string">'object'</span>) {
- <span class="hljs-keyword">var</span> keyset = value._keys || <span class="hljs-built_in">Object</span>.keys(value),
- output = [];
-
- Twig.forEach(keyset, <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">key</span>) </span>{
- output.push(<span class="hljs-built_in">JSON</span>.stringify(key) + <span class="hljs-string">":"</span> + Twig.filters.json_encode(value[key]));
- });
-
- <span class="hljs-keyword">return</span> <span class="hljs-string">"{"</span> + output.join(<span class="hljs-string">","</span>) + <span class="hljs-string">"}"</span>;
- }
- <span class="hljs-keyword">else</span> {
- <span class="hljs-keyword">return</span> <span class="hljs-built_in">JSON</span>.stringify(value);
- }
- },
- merge: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">value, params</span>) </span>{
- <span class="hljs-keyword">var</span> obj = [],
- arr_index = <span class="hljs-number">0</span>,
- keyset = [];</pre></div></div>
-
- </li>
-
-
- <li id="section-308">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-308">&#182;</a>
- </div>
- <p>Check to see if all the objects being merged are arrays</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> (!is(<span class="hljs-string">"Array"</span>, value)) {</pre></div></div>
-
- </li>
-
-
- <li id="section-309">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-309">&#182;</a>
- </div>
- <p>Create obj as an Object</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> obj = { };
- } <span class="hljs-keyword">else</span> {
- Twig.forEach(params, <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">param</span>) </span>{
- <span class="hljs-keyword">if</span> (!is(<span class="hljs-string">"Array"</span>, param)) {
- obj = { };
- }
- });
- }
- <span class="hljs-keyword">if</span> (!is(<span class="hljs-string">"Array"</span>, obj)) {
- obj._keys = [];
- }
-
- <span class="hljs-keyword">if</span> (is(<span class="hljs-string">"Array"</span>, value)) {
- Twig.forEach(value, <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">val</span>) </span>{
- <span class="hljs-keyword">if</span> (obj._keys) obj._keys.push(arr_index);
- obj[arr_index] = val;
- arr_index++;
- });
- } <span class="hljs-keyword">else</span> {
- keyset = value._keys || <span class="hljs-built_in">Object</span>.keys(value);
- Twig.forEach(keyset, <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">key</span>) </span>{
- obj[key] = value[key];
- obj._keys.push(key);</pre></div></div>
-
- </li>
-
-
- <li id="section-310">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-310">&#182;</a>
- </div>
- <p>Handle edge case where a number index in an object is greater than
- the array counter. In such a case, the array counter is increased
- one past the index.</p>
-<p>Example {{ [“a”, “b”]|merge({“4”:”value”}, [“c”, “d”])
-Without this, d would have an index of “4” and overwrite the value
- of “value”</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">var</span> int_key = <span class="hljs-built_in">parseInt</span>(key, <span class="hljs-number">10</span>);
- <span class="hljs-keyword">if</span> (!<span class="hljs-built_in">isNaN</span>(int_key) &amp;&amp; int_key &gt;= arr_index) {
- arr_index = int_key + <span class="hljs-number">1</span>;
- }
- });
- }</pre></div></div>
-
- </li>
-
-
- <li id="section-311">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-311">&#182;</a>
- </div>
- <p>mixin the merge arrays</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> Twig.forEach(params, <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">param</span>) </span>{
- <span class="hljs-keyword">if</span> (is(<span class="hljs-string">"Array"</span>, param)) {
- Twig.forEach(param, <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">val</span>) </span>{
- <span class="hljs-keyword">if</span> (obj._keys) obj._keys.push(arr_index);
- obj[arr_index] = val;
- arr_index++;
- });
- } <span class="hljs-keyword">else</span> {
- keyset = param._keys || <span class="hljs-built_in">Object</span>.keys(param);
- Twig.forEach(keyset, <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">key</span>) </span>{
- <span class="hljs-keyword">if</span> (!obj[key]) obj._keys.push(key);
- obj[key] = param[key];
-
- <span class="hljs-keyword">var</span> int_key = <span class="hljs-built_in">parseInt</span>(key, <span class="hljs-number">10</span>);
- <span class="hljs-keyword">if</span> (!<span class="hljs-built_in">isNaN</span>(int_key) &amp;&amp; int_key &gt;= arr_index) {
- arr_index = int_key + <span class="hljs-number">1</span>;
- }
- });
- }
- });
- <span class="hljs-keyword">if</span> (params.length === <span class="hljs-number">0</span>) {
- <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> Twig.Error(<span class="hljs-string">"Filter merge expects at least one parameter"</span>);
- }
-
- <span class="hljs-keyword">return</span> obj;
- },
- date: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">value, params</span>) </span>{
- <span class="hljs-keyword">var</span> date = Twig.functions.date(value);
- <span class="hljs-keyword">var</span> format = params &amp;&amp; params.length ? params[<span class="hljs-number">0</span>] : <span class="hljs-string">'F j, Y H:i'</span>;
- <span class="hljs-keyword">return</span> Twig.lib.formatDate(date, format);
- },
-
- date_modify: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">value, params</span>) </span>{
- <span class="hljs-keyword">if</span> (value === <span class="hljs-literal">undefined</span> || value === <span class="hljs-literal">null</span>) {
- <span class="hljs-keyword">return</span>;
- }
- <span class="hljs-keyword">if</span> (params === <span class="hljs-literal">undefined</span> || params.length !== <span class="hljs-number">1</span>) {
- <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> Twig.Error(<span class="hljs-string">"date_modify filter expects 1 argument"</span>);
- }
-
- <span class="hljs-keyword">var</span> modifyText = params[<span class="hljs-number">0</span>], time;
-
- <span class="hljs-keyword">if</span> (Twig.lib.is(<span class="hljs-string">"Date"</span>, value)) {
- time = Twig.lib.strtotime(modifyText, value.getTime() / <span class="hljs-number">1000</span>);
- }
- <span class="hljs-keyword">if</span> (Twig.lib.is(<span class="hljs-string">"String"</span>, value)) {
- time = Twig.lib.strtotime(modifyText, Twig.lib.strtotime(value));
- }
- <span class="hljs-keyword">if</span> (Twig.lib.is(<span class="hljs-string">"Number"</span>, value)) {
- time = Twig.lib.strtotime(modifyText, value);
- }
-
- <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Date</span>(time * <span class="hljs-number">1000</span>);
- },
-
- replace: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">value, params</span>) </span>{
- <span class="hljs-keyword">if</span> (value === <span class="hljs-literal">undefined</span>||value === <span class="hljs-literal">null</span>){
- <span class="hljs-keyword">return</span>;
- }
-
- <span class="hljs-keyword">var</span> pairs = params[<span class="hljs-number">0</span>],
- tag;
- <span class="hljs-keyword">for</span> (tag <span class="hljs-keyword">in</span> pairs) {
- <span class="hljs-keyword">if</span> (pairs.hasOwnProperty(tag) &amp;&amp; tag !== <span class="hljs-string">"_keys"</span>) {
- value = Twig.lib.replaceAll(value, tag, pairs[tag]);
- }
- }
- <span class="hljs-keyword">return</span> value;
- },
-
- format: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">value, params</span>) </span>{
- <span class="hljs-keyword">if</span> (value === <span class="hljs-literal">undefined</span> || value === <span class="hljs-literal">null</span>){
- <span class="hljs-keyword">return</span>;
- }
-
- <span class="hljs-keyword">return</span> Twig.lib.vsprintf(value, params);
- },
-
- striptags: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">value</span>) </span>{
- <span class="hljs-keyword">if</span> (value === <span class="hljs-literal">undefined</span> || value === <span class="hljs-literal">null</span>){
- <span class="hljs-keyword">return</span>;
- }
-
- <span class="hljs-keyword">return</span> Twig.lib.strip_tags(value);
- },
-
- <span class="hljs-built_in">escape</span>: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">value, params</span>) </span>{
- <span class="hljs-keyword">if</span> (value === <span class="hljs-literal">undefined</span>|| value === <span class="hljs-literal">null</span>){
- <span class="hljs-keyword">return</span>;
- }
-
- <span class="hljs-keyword">var</span> strategy = <span class="hljs-string">"html"</span>;
- <span class="hljs-keyword">if</span>(params &amp;&amp; params.length &amp;&amp; params[<span class="hljs-number">0</span>] !== <span class="hljs-literal">true</span>)
- strategy = params[<span class="hljs-number">0</span>];
-
- <span class="hljs-keyword">if</span>(strategy == <span class="hljs-string">"html"</span>) {
- <span class="hljs-keyword">var</span> raw_value = value.toString().replace(<span class="hljs-regexp">/&amp;/g</span>, <span class="hljs-string">"&amp;amp;"</span>)
- .replace(<span class="hljs-regexp">/&lt;/g</span>, <span class="hljs-string">"&amp;lt;"</span>)
- .replace(<span class="hljs-regexp">/&gt;/g</span>, <span class="hljs-string">"&amp;gt;"</span>)
- .replace(<span class="hljs-regexp">/"/g</span>, <span class="hljs-string">"&amp;quot;"</span>)
- .replace(<span class="hljs-regexp">/'/g</span>, <span class="hljs-string">"&amp;#039;"</span>);
- <span class="hljs-keyword">return</span> Twig.Markup(raw_value, <span class="hljs-string">'html'</span>);
- } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span>(strategy == <span class="hljs-string">"js"</span>) {
- <span class="hljs-keyword">var</span> raw_value = value.toString();
- <span class="hljs-keyword">var</span> result = <span class="hljs-string">""</span>;
-
- <span class="hljs-keyword">for</span>(<span class="hljs-keyword">var</span> i = <span class="hljs-number">0</span>; i &lt; raw_value.length; i++) {
- <span class="hljs-keyword">if</span>(raw_value[i].match(<span class="hljs-regexp">/^[a-zA-Z0-9,\._]$/</span>))
- result += raw_value[i];
- <span class="hljs-keyword">else</span> {
- <span class="hljs-keyword">var</span> char_code = raw_value.charCodeAt(i);
-
- <span class="hljs-keyword">if</span>(char_code &lt; <span class="hljs-number">0x80</span>)
- result += <span class="hljs-string">"\\x"</span> + char_code.toString(<span class="hljs-number">16</span>).toUpperCase();
- <span class="hljs-keyword">else</span>
- result += Twig.lib.sprintf(<span class="hljs-string">"\\u%04s"</span>, char_code.toString(<span class="hljs-number">16</span>).toUpperCase());
- }
- }
-
- <span class="hljs-keyword">return</span> Twig.Markup(result, <span class="hljs-string">'js'</span>);
- } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span>(strategy == <span class="hljs-string">"css"</span>) {
- <span class="hljs-keyword">var</span> raw_value = value.toString();
- <span class="hljs-keyword">var</span> result = <span class="hljs-string">""</span>;
-
- <span class="hljs-keyword">for</span>(<span class="hljs-keyword">var</span> i = <span class="hljs-number">0</span>; i &lt; raw_value.length; i++) {
- <span class="hljs-keyword">if</span>(raw_value[i].match(<span class="hljs-regexp">/^[a-zA-Z0-9]$/</span>))
- result += raw_value[i];
- <span class="hljs-keyword">else</span> {
- <span class="hljs-keyword">var</span> char_code = raw_value.charCodeAt(i);
- result += <span class="hljs-string">"\\"</span> + char_code.toString(<span class="hljs-number">16</span>).toUpperCase() + <span class="hljs-string">" "</span>;
- }
- }
-
- <span class="hljs-keyword">return</span> Twig.Markup(result, <span class="hljs-string">'css'</span>);
- } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span>(strategy == <span class="hljs-string">"url"</span>) {
- <span class="hljs-keyword">var</span> result = Twig.filters.url_encode(value);
- <span class="hljs-keyword">return</span> Twig.Markup(result, <span class="hljs-string">'url'</span>);
- } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span>(strategy == <span class="hljs-string">"html_attr"</span>) {
- <span class="hljs-keyword">var</span> raw_value = value.toString();
- <span class="hljs-keyword">var</span> result = <span class="hljs-string">""</span>;
-
- <span class="hljs-keyword">for</span>(<span class="hljs-keyword">var</span> i = <span class="hljs-number">0</span>; i &lt; raw_value.length; i++) {
- <span class="hljs-keyword">if</span>(raw_value[i].match(<span class="hljs-regexp">/^[a-zA-Z0-9,\.\-_]$/</span>))
- result += raw_value[i];
- <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span>(raw_value[i].match(<span class="hljs-regexp">/^[&amp;&lt;&gt;"]$/</span>))
- result += raw_value[i].replace(<span class="hljs-regexp">/&amp;/g</span>, <span class="hljs-string">"&amp;amp;"</span>)
- .replace(<span class="hljs-regexp">/&lt;/g</span>, <span class="hljs-string">"&amp;lt;"</span>)
- .replace(<span class="hljs-regexp">/&gt;/g</span>, <span class="hljs-string">"&amp;gt;"</span>)
- .replace(<span class="hljs-regexp">/"/g</span>, <span class="hljs-string">"&amp;quot;"</span>);
- <span class="hljs-keyword">else</span> {
- <span class="hljs-keyword">var</span> char_code = raw_value.charCodeAt(i);</pre></div></div>
-
- </li>
-
-
- <li id="section-312">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-312">&#182;</a>
- </div>
- <p>The following replaces characters undefined in HTML with
-the hex entity for the Unicode replacement character.</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span>(char_code &lt;= <span class="hljs-number">0x1f</span> &amp;&amp; char_code != <span class="hljs-number">0x09</span> &amp;&amp; char_code != <span class="hljs-number">0x0a</span> &amp;&amp; char_code != <span class="hljs-number">0x0d</span>)
- result += <span class="hljs-string">"&amp;#xFFFD;"</span>;
- <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span>(char_code &lt; <span class="hljs-number">0x80</span>)
- result += Twig.lib.sprintf(<span class="hljs-string">"&amp;#x%02s;"</span>, char_code.toString(<span class="hljs-number">16</span>).toUpperCase());
- <span class="hljs-keyword">else</span>
- result += Twig.lib.sprintf(<span class="hljs-string">"&amp;#x%04s;"</span>, char_code.toString(<span class="hljs-number">16</span>).toUpperCase());
- }
- }
-
- <span class="hljs-keyword">return</span> Twig.Markup(result, <span class="hljs-string">'html_attr'</span>);
- } <span class="hljs-keyword">else</span> {
- <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> Twig.Error(<span class="hljs-string">"escape strategy unsupported"</span>);
- }
- },
-
- <span class="hljs-comment">/* Alias of escape */</span>
- <span class="hljs-string">"e"</span>: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">value, params</span>) </span>{
- <span class="hljs-keyword">return</span> Twig.filters.escape(value, params);
- },
-
- nl2br: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">value</span>) </span>{
- <span class="hljs-keyword">if</span> (value === <span class="hljs-literal">undefined</span> || value === <span class="hljs-literal">null</span>){
- <span class="hljs-keyword">return</span>;
- }
- <span class="hljs-keyword">var</span> linebreak_tag = <span class="hljs-string">"BACKSLASH_n_replace"</span>,
- br = <span class="hljs-string">"&lt;br /&gt;"</span> + linebreak_tag;
-
- value = Twig.filters.escape(value)
- .replace(<span class="hljs-regexp">/\r\n/g</span>, br)
- .replace(<span class="hljs-regexp">/\r/g</span>, br)
- .replace(<span class="hljs-regexp">/\n/g</span>, br);
-
- value = Twig.lib.replaceAll(value, linebreak_tag, <span class="hljs-string">"\n"</span>);
-
- <span class="hljs-keyword">return</span> Twig.Markup(value);
- },
-
- <span class="hljs-comment">/**
- * Adapted from: http://phpjs.org/functions/number_format:481
- */</span>
- number_format: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">value, params</span>) </span>{
- <span class="hljs-keyword">var</span> number = value,
- decimals = (params &amp;&amp; params[<span class="hljs-number">0</span>]) ? params[<span class="hljs-number">0</span>] : <span class="hljs-literal">undefined</span>,
- dec = (params &amp;&amp; params[<span class="hljs-number">1</span>] !== <span class="hljs-literal">undefined</span>) ? params[<span class="hljs-number">1</span>] : <span class="hljs-string">"."</span>,
- sep = (params &amp;&amp; params[<span class="hljs-number">2</span>] !== <span class="hljs-literal">undefined</span>) ? params[<span class="hljs-number">2</span>] : <span class="hljs-string">","</span>;
-
- number = (number + <span class="hljs-string">''</span>).replace(<span class="hljs-regexp">/[^0-9+\-Ee.]/g</span>, <span class="hljs-string">''</span>);
- <span class="hljs-keyword">var</span> n = !<span class="hljs-built_in">isFinite</span>(+number) ? <span class="hljs-number">0</span> : +number,
- prec = !<span class="hljs-built_in">isFinite</span>(+decimals) ? <span class="hljs-number">0</span> : <span class="hljs-built_in">Math</span>.abs(decimals),
- s = <span class="hljs-string">''</span>,
- toFixedFix = <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">n, prec</span>) </span>{
- <span class="hljs-keyword">var</span> k = <span class="hljs-built_in">Math</span>.pow(<span class="hljs-number">10</span>, prec);
- <span class="hljs-keyword">return</span> <span class="hljs-string">''</span> + <span class="hljs-built_in">Math</span>.round(n * k) / k;
- };</pre></div></div>
-
- </li>
-
-
- <li id="section-313">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-313">&#182;</a>
- </div>
- <p>Fix for IE parseFloat(0.55).toFixed(0) = 0;</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> s = (prec ? toFixedFix(n, prec) : <span class="hljs-string">''</span> + <span class="hljs-built_in">Math</span>.round(n)).split(<span class="hljs-string">'.'</span>);
- <span class="hljs-keyword">if</span> (s[<span class="hljs-number">0</span>].length &gt; <span class="hljs-number">3</span>) {
- s[<span class="hljs-number">0</span>] = s[<span class="hljs-number">0</span>].replace(<span class="hljs-regexp">/\B(?=(?:\d{3})+(?!\d))/g</span>, sep);
- }
- <span class="hljs-keyword">if</span> ((s[<span class="hljs-number">1</span>] || <span class="hljs-string">''</span>).length &lt; prec) {
- s[<span class="hljs-number">1</span>] = s[<span class="hljs-number">1</span>] || <span class="hljs-string">''</span>;
- s[<span class="hljs-number">1</span>] += <span class="hljs-keyword">new</span> <span class="hljs-built_in">Array</span>(prec - s[<span class="hljs-number">1</span>].length + <span class="hljs-number">1</span>).join(<span class="hljs-string">'0'</span>);
- }
- <span class="hljs-keyword">return</span> s.join(dec);
- },
-
- trim: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">value, params</span>) </span>{
- <span class="hljs-keyword">if</span> (value === <span class="hljs-literal">undefined</span>|| value === <span class="hljs-literal">null</span>){
- <span class="hljs-keyword">return</span>;
- }
-
- <span class="hljs-keyword">var</span> str = Twig.filters.escape( <span class="hljs-string">''</span> + value ),
- whitespace;
- <span class="hljs-keyword">if</span> ( params &amp;&amp; params[<span class="hljs-number">0</span>] ) {
- whitespace = <span class="hljs-string">''</span> + params[<span class="hljs-number">0</span>];
- } <span class="hljs-keyword">else</span> {
- whitespace = <span class="hljs-string">' \n\r\t\f\x0b\xa0\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u200b\u2028\u2029\u3000'</span>;
- }
- <span class="hljs-keyword">for</span> (<span class="hljs-keyword">var</span> i = <span class="hljs-number">0</span>; i &lt; str.length; i++) {
- <span class="hljs-keyword">if</span> (whitespace.indexOf(str.charAt(i)) === <span class="hljs-number">-1</span>) {
- str = str.substring(i);
- <span class="hljs-keyword">break</span>;
- }
- }
- <span class="hljs-keyword">for</span> (i = str.length - <span class="hljs-number">1</span>; i &gt;= <span class="hljs-number">0</span>; i--) {
- <span class="hljs-keyword">if</span> (whitespace.indexOf(str.charAt(i)) === <span class="hljs-number">-1</span>) {
- str = str.substring(<span class="hljs-number">0</span>, i + <span class="hljs-number">1</span>);
- <span class="hljs-keyword">break</span>;
- }
- }
- <span class="hljs-keyword">return</span> whitespace.indexOf(str.charAt(<span class="hljs-number">0</span>)) === <span class="hljs-number">-1</span> ? str : <span class="hljs-string">''</span>;
- },
-
- truncate: <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">value, params</span>) </span>{
- <span class="hljs-keyword">var</span> length = <span class="hljs-number">30</span>,
- preserve = <span class="hljs-literal">false</span>,
- separator = <span class="hljs-string">'...'</span>;
-
- value = value + <span class="hljs-string">''</span>;
- <span class="hljs-keyword">if</span> (params) {
- <span class="hljs-keyword">if</span> (params[<span class="hljs-number">0</span>]) {
- length = params[<span class="hljs-number">0</span>];
- }
- <span class="hljs-keyword">if</span> (params[<span class="hljs-number">1</span>]) {
- preserve = params[<span class="hljs-number">1</span>];
- }
- <span class="hljs-keyword">if</span> (params[<span class="hljs-number">2</span>]) {
- separator = params[<span class="hljs-number">2</span>];
- }
- }
-
- <span class="hljs-keyword">if</span> (value.length &gt; length) {
-
- <span class="hljs-keyword">if</span> (preserve) {
- length = value.indexOf(<span class="hljs-string">' '</span>, length);
- <span class="hljs-keyword">if</span> (length === <span class="hljs-number">-1</span>) {
- <span class="hljs-keyword">return</span> value;
- }
- }
-
- value = value.substr(<span class="hljs-number">0</span>, length) + separator;
- }
-
- <span class="hljs-keyword">return</span> value;
- },
-
- slice: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">value, params</span>) </span>{
- <span class="hljs-keyword">if</span> (value === <span class="hljs-literal">undefined</span> || value === <span class="hljs-literal">null</span>) {
- <span class="hljs-keyword">return</span>;
- }
- <span class="hljs-keyword">if</span> (params === <span class="hljs-literal">undefined</span> || params.length &lt; <span class="hljs-number">1</span>) {
- <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> Twig.Error(<span class="hljs-string">"slice filter expects at least 1 argument"</span>);
- }</pre></div></div>
-
- </li>
-
-
- <li id="section-314">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-314">&#182;</a>
- </div>
- <p>default to start of string</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">var</span> start = params[<span class="hljs-number">0</span>] || <span class="hljs-number">0</span>;</pre></div></div>
-
- </li>
-
-
- <li id="section-315">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-315">&#182;</a>
- </div>
- <p>default to length of string</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">var</span> length = params.length &gt; <span class="hljs-number">1</span> ? params[<span class="hljs-number">1</span>] : value.length;</pre></div></div>
-
- </li>
-
-
- <li id="section-316">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-316">&#182;</a>
- </div>
- <p>handle negative start values</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">var</span> startIndex = start &gt;= <span class="hljs-number">0</span> ? start : <span class="hljs-built_in">Math</span>.max( value.length + start, <span class="hljs-number">0</span> );
-
- <span class="hljs-keyword">if</span> (Twig.lib.is(<span class="hljs-string">"Array"</span>, value)) {
- <span class="hljs-keyword">var</span> output = [];
- <span class="hljs-keyword">for</span> (<span class="hljs-keyword">var</span> i = startIndex; i &lt; startIndex + length &amp;&amp; i &lt; value.length; i++) {
- output.push(value[i]);
- }
- <span class="hljs-keyword">return</span> output;
- } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (Twig.lib.is(<span class="hljs-string">"String"</span>, value)) {
- <span class="hljs-keyword">return</span> value.substr(startIndex, length);
- } <span class="hljs-keyword">else</span> {
- <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> Twig.Error(<span class="hljs-string">"slice filter expects value to be an array or string"</span>);
- }
- },
-
- abs: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">value</span>) </span>{
- <span class="hljs-keyword">if</span> (value === <span class="hljs-literal">undefined</span> || value === <span class="hljs-literal">null</span>) {
- <span class="hljs-keyword">return</span>;
- }
-
- <span class="hljs-keyword">return</span> <span class="hljs-built_in">Math</span>.abs(value);
- },
-
- first: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">value</span>) </span>{
- <span class="hljs-keyword">if</span> (is(<span class="hljs-string">"Array"</span>, value)) {
- <span class="hljs-keyword">return</span> value[<span class="hljs-number">0</span>];
- } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (is(<span class="hljs-string">"Object"</span>, value)) {
- <span class="hljs-keyword">if</span> (<span class="hljs-string">'_keys'</span> <span class="hljs-keyword">in</span> value) {
- <span class="hljs-keyword">return</span> value[value._keys[<span class="hljs-number">0</span>]];
- }
- } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> ( <span class="hljs-keyword">typeof</span> value === <span class="hljs-string">"string"</span> ) {
- <span class="hljs-keyword">return</span> value.substr(<span class="hljs-number">0</span>, <span class="hljs-number">1</span>);
- }
-
- <span class="hljs-keyword">return</span>;
- },
-
- split: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">value, params</span>) </span>{
- <span class="hljs-keyword">if</span> (value === <span class="hljs-literal">undefined</span> || value === <span class="hljs-literal">null</span>) {
- <span class="hljs-keyword">return</span>;
- }
- <span class="hljs-keyword">if</span> (params === <span class="hljs-literal">undefined</span> || params.length &lt; <span class="hljs-number">1</span> || params.length &gt; <span class="hljs-number">2</span>) {
- <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> Twig.Error(<span class="hljs-string">"split filter expects 1 or 2 argument"</span>);
- }
- <span class="hljs-keyword">if</span> (Twig.lib.is(<span class="hljs-string">"String"</span>, value)) {
- <span class="hljs-keyword">var</span> delimiter = params[<span class="hljs-number">0</span>],
- limit = params[<span class="hljs-number">1</span>],
- split = value.split(delimiter);
-
- <span class="hljs-keyword">if</span> (limit === <span class="hljs-literal">undefined</span>) {
-
- <span class="hljs-keyword">return</span> split;
-
- } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (limit &lt; <span class="hljs-number">0</span>) {
-
- <span class="hljs-keyword">return</span> value.split(delimiter, split.length + limit);
-
- } <span class="hljs-keyword">else</span> {
-
- <span class="hljs-keyword">var</span> limitedSplit = [];
-
- <span class="hljs-keyword">if</span> (delimiter == <span class="hljs-string">''</span>) {</pre></div></div>
-
- </li>
-
-
- <li id="section-317">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-317">&#182;</a>
- </div>
- <p>empty delimiter
-“aabbcc”|split(‘’, 2)
- -&gt; [‘aa’, ‘bb’, ‘cc’]</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre>
- <span class="hljs-keyword">while</span>(split.length &gt; <span class="hljs-number">0</span>) {
- <span class="hljs-keyword">var</span> temp = <span class="hljs-string">""</span>;
- <span class="hljs-keyword">for</span> (<span class="hljs-keyword">var</span> i=<span class="hljs-number">0</span>; i&lt;limit &amp;&amp; split.length &gt; <span class="hljs-number">0</span>; i++) {
- temp += split.shift();
- }
- limitedSplit.push(temp);
- }
-
- } <span class="hljs-keyword">else</span> {</pre></div></div>
-
- </li>
-
-
- <li id="section-318">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-318">&#182;</a>
- </div>
- <p>non-empty delimiter
-“one,two,three,four,five”|split(‘,’, 3)
- -&gt; [‘one’, ‘two’, ‘three,four,five’]</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre>
- <span class="hljs-keyword">for</span> (<span class="hljs-keyword">var</span> i=<span class="hljs-number">0</span>; i&lt;limit<span class="hljs-number">-1</span> &amp;&amp; split.length &gt; <span class="hljs-number">0</span>; i++) {
- limitedSplit.push(split.shift());
- }
-
- <span class="hljs-keyword">if</span> (split.length &gt; <span class="hljs-number">0</span>) {
- limitedSplit.push(split.join(delimiter));
- }
- }
-
- <span class="hljs-keyword">return</span> limitedSplit;
- }
-
- } <span class="hljs-keyword">else</span> {
- <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> Twig.Error(<span class="hljs-string">"split filter expects value to be a string"</span>);
- }
- },
- last: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">value</span>) </span>{
- <span class="hljs-keyword">if</span> (Twig.lib.is(<span class="hljs-string">'Object'</span>, value)) {
- <span class="hljs-keyword">var</span> keys;
-
- <span class="hljs-keyword">if</span> (value._keys === <span class="hljs-literal">undefined</span>) {
- keys = <span class="hljs-built_in">Object</span>.keys(value);
- } <span class="hljs-keyword">else</span> {
- keys = value._keys;
- }
-
- <span class="hljs-keyword">return</span> value[keys[keys.length - <span class="hljs-number">1</span>]];
- }</pre></div></div>
-
- </li>
-
-
- <li id="section-319">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-319">&#182;</a>
- </div>
- <p>string|array</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">return</span> value[value.length - <span class="hljs-number">1</span>];
- },
- raw: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">value</span>) </span>{
- <span class="hljs-keyword">return</span> Twig.Markup(value);
- },
- batch: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">items, params</span>) </span>{
- <span class="hljs-keyword">var</span> size = params.shift(),
- fill = params.shift(),
- result,
- last,
- missing;
-
- <span class="hljs-keyword">if</span> (!Twig.lib.is(<span class="hljs-string">"Array"</span>, items)) {
- <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> Twig.Error(<span class="hljs-string">"batch filter expects items to be an array"</span>);
- }
-
- <span class="hljs-keyword">if</span> (!Twig.lib.is(<span class="hljs-string">"Number"</span>, size)) {
- <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> Twig.Error(<span class="hljs-string">"batch filter expects size to be a number"</span>);
- }
-
- size = <span class="hljs-built_in">Math</span>.ceil(size);
-
- result = Twig.lib.chunkArray(items, size);
-
- <span class="hljs-keyword">if</span> (fill &amp;&amp; items.length % size != <span class="hljs-number">0</span>) {
- last = result.pop();
- missing = size - last.length;
-
- <span class="hljs-keyword">while</span> (missing--) {
- last.push(fill);
- }
-
- result.push(last);
- }
-
- <span class="hljs-keyword">return</span> result;
- },
- round: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">value, params</span>) </span>{
- params = params || [];
-
- <span class="hljs-keyword">var</span> precision = params.length &gt; <span class="hljs-number">0</span> ? params[<span class="hljs-number">0</span>] : <span class="hljs-number">0</span>,
- method = params.length &gt; <span class="hljs-number">1</span> ? params[<span class="hljs-number">1</span>] : <span class="hljs-string">"common"</span>;
-
- value = <span class="hljs-built_in">parseFloat</span>(value);
-
- <span class="hljs-keyword">if</span>(precision &amp;&amp; !Twig.lib.is(<span class="hljs-string">"Number"</span>, precision)) {
- <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> Twig.Error(<span class="hljs-string">"round filter expects precision to be a number"</span>);
- }
-
- <span class="hljs-keyword">if</span> (method === <span class="hljs-string">"common"</span>) {
- <span class="hljs-keyword">return</span> Twig.lib.round(value, precision);
- }
-
- <span class="hljs-keyword">if</span>(!Twig.lib.is(<span class="hljs-string">"Function"</span>, <span class="hljs-built_in">Math</span>[method])) {
- <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> Twig.Error(<span class="hljs-string">"round filter expects method to be 'floor', 'ceil', or 'common'"</span>);
- }
-
- <span class="hljs-keyword">return</span> <span class="hljs-built_in">Math</span>[method](value * <span class="hljs-built_in">Math</span>.pow(<span class="hljs-number">10</span>, precision)) / <span class="hljs-built_in">Math</span>.pow(<span class="hljs-number">10</span>, precision);
- }
- };
-
- Twig.filter = <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">filter, value, params</span>) </span>{
- <span class="hljs-keyword">if</span> (!Twig.filters[filter]) {
- <span class="hljs-keyword">throw</span> <span class="hljs-string">"Unable to find filter "</span> + filter;
- }
- <span class="hljs-keyword">return</span> Twig.filters[filter].apply(<span class="hljs-keyword">this</span>, [value, params]);
- };
-
- Twig.filter.extend = <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">filter, definition</span>) </span>{
- Twig.filters[filter] = definition;
- };
-
- <span class="hljs-keyword">return</span> Twig;
-
-})(Twig || { });</pre></div></div>
-
- </li>
-
-
- <li id="section-320">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-320">&#182;</a>
- </div>
- <pre><code>Twig.js
- <span class="hljs-number">2012</span> Hadrien Lanneau
-Available under the BSD <span class="hljs-number">2</span>-Clause License
-https:<span class="hljs-comment">//github.com/justjohn/twig.js</span>
-</code></pre>
- </div>
-
- </li>
-
-
- <li id="section-321">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-321">&#182;</a>
- </div>
- <h2 id="twig-functions-js">twig.functions.js</h2>
-<p>This file handles parsing filters.</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre><span class="hljs-keyword">var</span> Twig = (<span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">Twig</span>) </span>{
- <span class="hljs-comment">/**
- * @constant
- * @type {string}
- */</span>
- <span class="hljs-keyword">var</span> TEMPLATE_NOT_FOUND_MESSAGE = <span class="hljs-string">'Template "{name}" is not defined.'</span>;</pre></div></div>
-
- </li>
-
-
- <li id="section-322">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-322">&#182;</a>
- </div>
- <p>Determine object type</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">is</span>(<span class="hljs-params">type, obj</span>) </span>{
- <span class="hljs-keyword">var</span> clas = <span class="hljs-built_in">Object</span>.prototype.toString.call(obj).slice(<span class="hljs-number">8</span>, <span class="hljs-number">-1</span>);
- <span class="hljs-keyword">return</span> obj !== <span class="hljs-literal">undefined</span> &amp;&amp; obj !== <span class="hljs-literal">null</span> &amp;&amp; clas === type;
- }
-
- Twig.functions = {</pre></div></div>
-
- </li>
-
-
- <li id="section-323">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-323">&#182;</a>
- </div>
- <p> attribute, block, constant, date, dump, parent, random,.</p>
-
- </div>
-
- </li>
-
-
- <li id="section-324">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-324">&#182;</a>
- </div>
- <p>Range function from <a href="http://phpjs.org/functions/range:499">http://phpjs.org/functions/range:499</a>
-Used under an MIT License</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> range: <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">low, high, step</span>) </span>{</pre></div></div>
-
- </li>
-
-
- <li id="section-325">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-325">&#182;</a>
- </div>
- <p><a href="http://kevin.vanzonneveld.net">http://kevin.vanzonneveld.net</a></p>
-<ul>
-<li>original by: Waldo Malqui Silva</li>
-<li>example 1: range ( 0, 12 );</li>
-<li>returns 1: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]</li>
-<li>example 2: range( 0, 100, 10 );</li>
-<li>returns 2: [0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100]</li>
-<li>example 3: range( ‘a’, ‘i’ );</li>
-<li>returns 3: [‘a’, ‘b’, ‘c’, ‘d’, ‘e’, ‘f’, ‘g’, ‘h’, ‘i’]</li>
-<li>example 4: range( ‘c’, ‘a’ );</li>
-<li>returns 4: [‘c’, ‘b’, ‘a’]</li>
-</ul>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">var</span> matrix = [];
- <span class="hljs-keyword">var</span> inival, endval, plus;
- <span class="hljs-keyword">var</span> walker = step || <span class="hljs-number">1</span>;
- <span class="hljs-keyword">var</span> chars = <span class="hljs-literal">false</span>;
-
- <span class="hljs-keyword">if</span> (!<span class="hljs-built_in">isNaN</span>(low) &amp;&amp; !<span class="hljs-built_in">isNaN</span>(high)) {
- inival = <span class="hljs-built_in">parseInt</span>(low, <span class="hljs-number">10</span>);
- endval = <span class="hljs-built_in">parseInt</span>(high, <span class="hljs-number">10</span>);
- } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (<span class="hljs-built_in">isNaN</span>(low) &amp;&amp; <span class="hljs-built_in">isNaN</span>(high)) {
- chars = <span class="hljs-literal">true</span>;
- inival = low.charCodeAt(<span class="hljs-number">0</span>);
- endval = high.charCodeAt(<span class="hljs-number">0</span>);
- } <span class="hljs-keyword">else</span> {
- inival = (<span class="hljs-built_in">isNaN</span>(low) ? <span class="hljs-number">0</span> : low);
- endval = (<span class="hljs-built_in">isNaN</span>(high) ? <span class="hljs-number">0</span> : high);
- }
-
- plus = ((inival &gt; endval) ? <span class="hljs-literal">false</span> : <span class="hljs-literal">true</span>);
- <span class="hljs-keyword">if</span> (plus) {
- <span class="hljs-keyword">while</span> (inival &lt;= endval) {
- matrix.push(((chars) ? <span class="hljs-built_in">String</span>.fromCharCode(inival) : inival));
- inival += walker;
- }
- } <span class="hljs-keyword">else</span> {
- <span class="hljs-keyword">while</span> (inival &gt;= endval) {
- matrix.push(((chars) ? <span class="hljs-built_in">String</span>.fromCharCode(inival) : inival));
- inival -= walker;
- }
- }
-
- <span class="hljs-keyword">return</span> matrix;
- },
- cycle: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">arr, i</span>) </span>{
- <span class="hljs-keyword">var</span> pos = i % arr.length;
- <span class="hljs-keyword">return</span> arr[pos];
- },
- dump: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) </span>{
- <span class="hljs-keyword">var</span> EOL = <span class="hljs-string">'\n'</span>,
- indentChar = <span class="hljs-string">' '</span>,
- indentTimes = <span class="hljs-number">0</span>,
- out = <span class="hljs-string">''</span>,
- args = <span class="hljs-built_in">Array</span>.prototype.slice.call(<span class="hljs-built_in">arguments</span>),
- indent = <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">times</span>) </span>{
- <span class="hljs-keyword">var</span> ind = <span class="hljs-string">''</span>;
- <span class="hljs-keyword">while</span> (times &gt; <span class="hljs-number">0</span>) {
- times--;
- ind += indentChar;
- }
- <span class="hljs-keyword">return</span> ind;
- },
- displayVar = <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">variable</span>) </span>{
- out += indent(indentTimes);
- <span class="hljs-keyword">if</span> (<span class="hljs-keyword">typeof</span>(variable) === <span class="hljs-string">'object'</span>) {
- dumpVar(variable);
- } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (<span class="hljs-keyword">typeof</span>(variable) === <span class="hljs-string">'function'</span>) {
- out += <span class="hljs-string">'function()'</span> + EOL;
- } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (<span class="hljs-keyword">typeof</span>(variable) === <span class="hljs-string">'string'</span>) {
- out += <span class="hljs-string">'string('</span> + variable.length + <span class="hljs-string">') "'</span> + variable + <span class="hljs-string">'"'</span> + EOL;
- } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (<span class="hljs-keyword">typeof</span>(variable) === <span class="hljs-string">'number'</span>) {
- out += <span class="hljs-string">'number('</span> + variable + <span class="hljs-string">')'</span> + EOL;
- } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (<span class="hljs-keyword">typeof</span>(variable) === <span class="hljs-string">'boolean'</span>) {
- out += <span class="hljs-string">'bool('</span> + variable + <span class="hljs-string">')'</span> + EOL;
- }
- },
- dumpVar = <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">variable</span>) </span>{
- <span class="hljs-keyword">var</span> i;
- <span class="hljs-keyword">if</span> (variable === <span class="hljs-literal">null</span>) {
- out += <span class="hljs-string">'NULL'</span> + EOL;
- } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (variable === <span class="hljs-literal">undefined</span>) {
- out += <span class="hljs-string">'undefined'</span> + EOL;
- } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (<span class="hljs-keyword">typeof</span> variable === <span class="hljs-string">'object'</span>) {
- out += indent(indentTimes) + <span class="hljs-keyword">typeof</span>(variable);
- indentTimes++;
- out += <span class="hljs-string">'('</span> + (<span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">obj</span>) </span>{
- <span class="hljs-keyword">var</span> size = <span class="hljs-number">0</span>, key;
- <span class="hljs-keyword">for</span> (key <span class="hljs-keyword">in</span> obj) {
- <span class="hljs-keyword">if</span> (obj.hasOwnProperty(key)) {
- size++;
- }
- }
- <span class="hljs-keyword">return</span> size;
- })(variable) + <span class="hljs-string">') {'</span> + EOL;
- <span class="hljs-keyword">for</span> (i <span class="hljs-keyword">in</span> variable) {
- out += indent(indentTimes) + <span class="hljs-string">'['</span> + i + <span class="hljs-string">']=&gt; '</span> + EOL;
- displayVar(variable[i]);
- }
- indentTimes--;
- out += indent(indentTimes) + <span class="hljs-string">'}'</span> + EOL;
- } <span class="hljs-keyword">else</span> {
- displayVar(variable);
- }
- };</pre></div></div>
-
- </li>
-
-
- <li id="section-326">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-326">&#182;</a>
- </div>
- <p>handle no argument case by dumping the entire render context</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> (args.length == <span class="hljs-number">0</span>) args.push(<span class="hljs-keyword">this</span>.context);
-
- Twig.forEach(args, <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">variable</span>) </span>{
- dumpVar(variable);
- });
-
- <span class="hljs-keyword">return</span> out;
- },
- date: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">date, time</span>) </span>{
- <span class="hljs-keyword">var</span> dateObj;
- <span class="hljs-keyword">if</span> (date === <span class="hljs-literal">undefined</span>) {
- dateObj = <span class="hljs-keyword">new</span> <span class="hljs-built_in">Date</span>();
- } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (Twig.lib.is(<span class="hljs-string">"Date"</span>, date)) {
- dateObj = date;
- } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (Twig.lib.is(<span class="hljs-string">"String"</span>, date)) {
- <span class="hljs-keyword">if</span> (date.match(<span class="hljs-regexp">/^[0-9]+$/</span>)) {
- dateObj = <span class="hljs-keyword">new</span> <span class="hljs-built_in">Date</span>(date * <span class="hljs-number">1000</span>);
- }
- <span class="hljs-keyword">else</span> {
- dateObj = <span class="hljs-keyword">new</span> <span class="hljs-built_in">Date</span>(Twig.lib.strtotime(date) * <span class="hljs-number">1000</span>);
- }
- } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (Twig.lib.is(<span class="hljs-string">"Number"</span>, date)) {</pre></div></div>
-
- </li>
-
-
- <li id="section-327">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-327">&#182;</a>
- </div>
- <p>timestamp</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> dateObj = <span class="hljs-keyword">new</span> <span class="hljs-built_in">Date</span>(date * <span class="hljs-number">1000</span>);
- } <span class="hljs-keyword">else</span> {
- <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> Twig.Error(<span class="hljs-string">"Unable to parse date "</span> + date);
- }
- <span class="hljs-keyword">return</span> dateObj;
- },
- block: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">block</span>) </span>{
- <span class="hljs-keyword">if</span> (<span class="hljs-keyword">this</span>.originalBlockTokens[block]) {
- <span class="hljs-keyword">return</span> Twig.logic.parse.apply(<span class="hljs-keyword">this</span>, [<span class="hljs-keyword">this</span>.originalBlockTokens[block], <span class="hljs-keyword">this</span>.context]).output;
- } <span class="hljs-keyword">else</span> {
- <span class="hljs-keyword">return</span> <span class="hljs-keyword">this</span>.blocks[block];
- }
- },
- parent: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) </span>{</pre></div></div>
-
- </li>
-
-
- <li id="section-328">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-328">&#182;</a>
- </div>
- <p>Add a placeholder</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">return</span> Twig.placeholders.parent;
- },
- attribute: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">object, method, params</span>) </span>{
- <span class="hljs-keyword">if</span> (Twig.lib.is(<span class="hljs-string">'Object'</span>, object)) {
- <span class="hljs-keyword">if</span> (object.hasOwnProperty(method)) {
- <span class="hljs-keyword">if</span> (<span class="hljs-keyword">typeof</span> object[method] === <span class="hljs-string">"function"</span>) {
- <span class="hljs-keyword">return</span> object[method].apply(<span class="hljs-literal">undefined</span>, params);
- }
- <span class="hljs-keyword">else</span> {
- <span class="hljs-keyword">return</span> object[method];
- }
- }
- }</pre></div></div>
-
- </li>
-
-
- <li id="section-329">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-329">&#182;</a>
- </div>
- <p>Array will return element 0-index</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">return</span> object[method] || <span class="hljs-literal">undefined</span>;
- },
- max: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">values</span>) </span>{
- <span class="hljs-keyword">if</span>(Twig.lib.is(<span class="hljs-string">"Object"</span>, values)) {
- <span class="hljs-keyword">delete</span> values[<span class="hljs-string">"_keys"</span>];
- <span class="hljs-keyword">return</span> Twig.lib.max(values);
- }
-
- <span class="hljs-keyword">return</span> Twig.lib.max.apply(<span class="hljs-literal">null</span>, <span class="hljs-built_in">arguments</span>);
- },
- min: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">values</span>) </span>{
- <span class="hljs-keyword">if</span>(Twig.lib.is(<span class="hljs-string">"Object"</span>, values)) {
- <span class="hljs-keyword">delete</span> values[<span class="hljs-string">"_keys"</span>];
- <span class="hljs-keyword">return</span> Twig.lib.min(values);
- }
-
- <span class="hljs-keyword">return</span> Twig.lib.min.apply(<span class="hljs-literal">null</span>, <span class="hljs-built_in">arguments</span>);
- },
- template_from_string: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">template</span>) </span>{
- <span class="hljs-keyword">if</span> (template === <span class="hljs-literal">undefined</span>) {
- template = <span class="hljs-string">''</span>;
- }
- <span class="hljs-keyword">return</span> Twig.Templates.parsers.twig({
- options: <span class="hljs-keyword">this</span>.options,
- data: template
- });
- },
- random: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">value</span>) </span>{
- <span class="hljs-keyword">var</span> LIMIT_INT31 = <span class="hljs-number">0x80000000</span>;
-
- <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">getRandomNumber</span>(<span class="hljs-params">n</span>) </span>{
- <span class="hljs-keyword">var</span> random = <span class="hljs-built_in">Math</span>.floor(<span class="hljs-built_in">Math</span>.random() * LIMIT_INT31);
- <span class="hljs-keyword">var</span> limits = [<span class="hljs-number">0</span>, n];
- <span class="hljs-keyword">var</span> min = <span class="hljs-built_in">Math</span>.min.apply(<span class="hljs-literal">null</span>, limits),
- max = <span class="hljs-built_in">Math</span>.max.apply(<span class="hljs-literal">null</span>, limits);
- <span class="hljs-keyword">return</span> min + <span class="hljs-built_in">Math</span>.floor((max - min + <span class="hljs-number">1</span>) * random / LIMIT_INT31);
- }
-
- <span class="hljs-keyword">if</span>(Twig.lib.is(<span class="hljs-string">"Number"</span>, value)) {
- <span class="hljs-keyword">return</span> getRandomNumber(value);
- }
-
- <span class="hljs-keyword">if</span>(Twig.lib.is(<span class="hljs-string">"String"</span>, value)) {
- <span class="hljs-keyword">return</span> value.charAt(getRandomNumber(value.length<span class="hljs-number">-1</span>));
- }
-
- <span class="hljs-keyword">if</span>(Twig.lib.is(<span class="hljs-string">"Array"</span>, value)) {
- <span class="hljs-keyword">return</span> value[getRandomNumber(value.length<span class="hljs-number">-1</span>)];
- }
-
- <span class="hljs-keyword">if</span>(Twig.lib.is(<span class="hljs-string">"Object"</span>, value)) {
- <span class="hljs-keyword">var</span> keys = <span class="hljs-built_in">Object</span>.keys(value);
- <span class="hljs-keyword">return</span> value[keys[getRandomNumber(keys.length<span class="hljs-number">-1</span>)]];
- }
-
- <span class="hljs-keyword">return</span> getRandomNumber(LIMIT_INT31<span class="hljs-number">-1</span>);
- },
-
- <span class="hljs-comment">/**
- * Returns the content of a template without rendering it
- * @param {string} name
- * @param {boolean} [ignore_missing=false]
- * @returns {string}
- */</span>
- source: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">name, ignore_missing</span>) </span>{
- <span class="hljs-keyword">var</span> templateSource;
- <span class="hljs-keyword">var</span> templateFound = <span class="hljs-literal">false</span>;
- <span class="hljs-keyword">var</span> isNodeEnvironment = <span class="hljs-keyword">typeof</span> <span class="hljs-built_in">module</span> !== <span class="hljs-string">'undefined'</span> &amp;&amp; <span class="hljs-keyword">typeof</span> <span class="hljs-built_in">module</span>.exports !== <span class="hljs-string">'undefined'</span> &amp;&amp; <span class="hljs-keyword">typeof</span> <span class="hljs-built_in">window</span> === <span class="hljs-string">'undefined'</span>;
- <span class="hljs-keyword">var</span> loader;
- <span class="hljs-keyword">var</span> path;</pre></div></div>
-
- </li>
-
-
- <li id="section-330">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-330">&#182;</a>
- </div>
- <p>if we are running in a node.js environment, set the loader to ‘fs’ and ensure the
-path is relative to the CWD of the running script
-else, set the loader to ‘ajax’ and set the path to the value of name</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> (isNodeEnvironment) {
- loader = <span class="hljs-string">'fs'</span>;
- path = __dirname + <span class="hljs-string">'/'</span> + name;
- } <span class="hljs-keyword">else</span> {
- loader = <span class="hljs-string">'ajax'</span>;
- path = name;
- }</pre></div></div>
-
- </li>
-
-
- <li id="section-331">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-331">&#182;</a>
- </div>
- <p>build the params object</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">var</span> params = {
- id: name,
- path: path,
- method: loader,
- parser: <span class="hljs-string">'source'</span>,
- <span class="hljs-keyword">async</span>: <span class="hljs-literal">false</span>,
- fetchTemplateSource: <span class="hljs-literal">true</span>
- };</pre></div></div>
-
- </li>
-
-
- <li id="section-332">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-332">&#182;</a>
- </div>
- <p>default ignore_missing to false</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> (<span class="hljs-keyword">typeof</span> ignore_missing === <span class="hljs-string">'undefined'</span>) {
- ignore_missing = <span class="hljs-literal">false</span>;
- }</pre></div></div>
-
- </li>
-
-
- <li id="section-333">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-333">&#182;</a>
- </div>
- <p>try to load the remote template</p>
-<p>on exception, log it</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">try</span> {
- templateSource = Twig.Templates.loadRemote(name, params);</pre></div></div>
-
- </li>
-
-
- <li id="section-334">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-334">&#182;</a>
- </div>
- <p>if the template is undefined or null, set the template to an empty string and do NOT flip the
-boolean indicating we found the template</p>
-<p>else, all is good! flip the boolean indicating we found the template</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> (<span class="hljs-keyword">typeof</span> templateSource === <span class="hljs-string">'undefined'</span> || templateSource === <span class="hljs-literal">null</span>) {
- templateSource = <span class="hljs-string">''</span>;
- } <span class="hljs-keyword">else</span> {
- templateFound = <span class="hljs-literal">true</span>;
- }
- } <span class="hljs-keyword">catch</span> (e) {
- Twig.log.debug(<span class="hljs-string">'Twig.functions.source: '</span>, <span class="hljs-string">'Problem loading template '</span>, e);
- }</pre></div></div>
-
- </li>
-
-
- <li id="section-335">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-335">&#182;</a>
- </div>
- <p>if the template was NOT found AND we are not ignoring missing templates, return the same message
-that is returned by the PHP implementation of the twig source() function</p>
-<p>else, return the template source</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> (!templateFound &amp;&amp; !ignore_missing) {
- <span class="hljs-keyword">return</span> TEMPLATE_NOT_FOUND_MESSAGE.replace(<span class="hljs-string">'{name}'</span>, name);
- } <span class="hljs-keyword">else</span> {
- <span class="hljs-keyword">return</span> templateSource;
- }
- }
- };
-
- Twig._function = <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">_function, value, params</span>) </span>{
- <span class="hljs-keyword">if</span> (!Twig.functions[_function]) {
- <span class="hljs-keyword">throw</span> <span class="hljs-string">"Unable to find function "</span> + _function;
- }
- <span class="hljs-keyword">return</span> Twig.functions[_function](value, params);
- };
-
- Twig._function.extend = <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">_function, definition</span>) </span>{
- Twig.functions[_function] = definition;
- };
-
- <span class="hljs-keyword">return</span> Twig;
-
-})(Twig || { });</pre></div></div>
-
- </li>
-
-
- <li id="section-336">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-336">&#182;</a>
- </div>
- <pre><code>Twig.js
-Available under the BSD <span class="hljs-number">2</span>-Clause License
-https:<span class="hljs-comment">//github.com/justjohn/twig.js</span>
-</code></pre>
- </div>
-
- </li>
-
-
- <li id="section-337">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-337">&#182;</a>
- </div>
- <h2 id="twig-path-js">twig.path.js</h2>
-<p>This file handles path parsing</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre><span class="hljs-keyword">var</span> Twig = (<span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">Twig</span>) </span>{
-<span class="hljs-meta"> "use strict"</span>;
-
- <span class="hljs-comment">/**
- * Namespace for path handling.
- */</span>
- Twig.path = {};
-
- <span class="hljs-comment">/**
- * Generate the canonical version of a url based on the given base path and file path and in
- * the previously registered namespaces.
- *
- * @param {string} template The Twig Template
- * @param {string} file The file path, may be relative and may contain namespaces.
- *
- * @return {string} The canonical version of the path
- */</span>
- Twig.path.parsePath = <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">template, file</span>) </span>{
- <span class="hljs-keyword">var</span> namespaces = <span class="hljs-literal">null</span>,
- file = file || <span class="hljs-string">""</span>;
-
- <span class="hljs-keyword">if</span> (<span class="hljs-keyword">typeof</span> template === <span class="hljs-string">'object'</span> &amp;&amp; <span class="hljs-keyword">typeof</span> template.options === <span class="hljs-string">'object'</span>) {
- namespaces = template.options.namespaces;
- }
-
- <span class="hljs-keyword">if</span> (<span class="hljs-keyword">typeof</span> namespaces === <span class="hljs-string">'object'</span> &amp;&amp; (file.indexOf(<span class="hljs-string">'::'</span>) &gt; <span class="hljs-number">0</span>) || file.indexOf(<span class="hljs-string">'@'</span>) &gt;= <span class="hljs-number">0</span>){
- <span class="hljs-keyword">for</span> (<span class="hljs-keyword">var</span> k <span class="hljs-keyword">in</span> namespaces){
- <span class="hljs-keyword">if</span> (namespaces.hasOwnProperty(k)) {
- file = file.replace(k + <span class="hljs-string">'::'</span>, namespaces[k]);
- file = file.replace(<span class="hljs-string">'@'</span> + k, namespaces[k]);
- }
- }
-
- <span class="hljs-keyword">return</span> file;
- }
-
- <span class="hljs-keyword">return</span> Twig.path.relativePath(template, file);
- };
-
- <span class="hljs-comment">/**
- * Generate the relative canonical version of a url based on the given base path and file path.
- *
- * @param {Twig.Template} template The Twig.Template.
- * @param {string} file The file path, relative to the base path.
- *
- * @return {string} The canonical version of the path.
- */</span>
- Twig.path.relativePath = <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">template, file</span>) </span>{
- <span class="hljs-keyword">var</span> base,
- base_path,
- sep_chr = <span class="hljs-string">"/"</span>,
- new_path = [],
- file = file || <span class="hljs-string">""</span>,
- val;
-
- <span class="hljs-keyword">if</span> (template.url) {
- <span class="hljs-keyword">if</span> (<span class="hljs-keyword">typeof</span> template.base !== <span class="hljs-string">'undefined'</span>) {
- base = template.base + ((template.base.charAt(template.base.length<span class="hljs-number">-1</span>) === <span class="hljs-string">'/'</span>) ? <span class="hljs-string">''</span> : <span class="hljs-string">'/'</span>);
- } <span class="hljs-keyword">else</span> {
- base = template.url;
- }
- } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (template.path) {</pre></div></div>
-
- </li>
-
-
- <li id="section-338">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-338">&#182;</a>
- </div>
- <p>Get the system-specific path separator</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">var</span> path = <span class="hljs-built_in">require</span>(<span class="hljs-string">"path"</span>),
- sep = path.sep || sep_chr,
- relative = <span class="hljs-keyword">new</span> <span class="hljs-built_in">RegExp</span>(<span class="hljs-string">"^\\.{1,2}"</span> + sep.replace(<span class="hljs-string">"\\"</span>, <span class="hljs-string">"\\\\"</span>));
- file = file.replace(<span class="hljs-regexp">/\//g</span>, sep);
-
- <span class="hljs-keyword">if</span> (template.base !== <span class="hljs-literal">undefined</span> &amp;&amp; file.match(relative) == <span class="hljs-literal">null</span>) {
- file = file.replace(template.base, <span class="hljs-string">''</span>);
- base = template.base + sep;
- } <span class="hljs-keyword">else</span> {
- base = path.normalize(template.path);
- }
-
- base = base.replace(sep+sep, sep);
- sep_chr = sep;
- } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> ((template.name || template.id) &amp;&amp; template.method &amp;&amp; template.method !== <span class="hljs-string">'fs'</span> &amp;&amp; template.method !== <span class="hljs-string">'ajax'</span>) {</pre></div></div>
-
- </li>
-
-
- <li id="section-339">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-339">&#182;</a>
- </div>
- <p>Custom registered loader</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> base = template.base || template.name || template.id;
- } <span class="hljs-keyword">else</span> {
- <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> Twig.Error(<span class="hljs-string">"Cannot extend an inline template."</span>);
- }
-
- base_path = base.split(sep_chr);</pre></div></div>
-
- </li>
-
-
- <li id="section-340">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-340">&#182;</a>
- </div>
- <p>Remove file from url</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> base_path.pop();
- base_path = base_path.concat(file.split(sep_chr));
-
- <span class="hljs-keyword">while</span> (base_path.length &gt; <span class="hljs-number">0</span>) {
- val = base_path.shift();
- <span class="hljs-keyword">if</span> (val == <span class="hljs-string">"."</span>) {</pre></div></div>
-
- </li>
-
-
- <li id="section-341">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-341">&#182;</a>
- </div>
- <p>Ignore</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (val == <span class="hljs-string">".."</span> &amp;&amp; new_path.length &gt; <span class="hljs-number">0</span> &amp;&amp; new_path[new_path.length<span class="hljs-number">-1</span>] != <span class="hljs-string">".."</span>) {
- new_path.pop();
- } <span class="hljs-keyword">else</span> {
- new_path.push(val);
- }
- }
-
- <span class="hljs-keyword">return</span> new_path.join(sep_chr);
- };
-
- <span class="hljs-keyword">return</span> Twig;
-}) (Twig || { });</pre></div></div>
-
- </li>
-
-
- <li id="section-342">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-342">&#182;</a>
- </div>
- <pre><code>Twig.js
-Available under the BSD <span class="hljs-number">2</span>-Clause License
-https:<span class="hljs-comment">//github.com/justjohn/twig.js</span>
-</code></pre>
- </div>
-
- </li>
-
-
- <li id="section-343">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-343">&#182;</a>
- </div>
- <h2 id="twig-tests-js">twig.tests.js</h2>
-<p>This file handles expression tests. (is empty, is not defined, etc…)</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre><span class="hljs-keyword">var</span> Twig = (<span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">Twig</span>) </span>{
-<span class="hljs-meta"> "use strict"</span>;
- Twig.tests = {
- empty: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">value</span>) </span>{
- <span class="hljs-keyword">if</span> (value === <span class="hljs-literal">null</span> || value === <span class="hljs-literal">undefined</span>) <span class="hljs-keyword">return</span> <span class="hljs-literal">true</span>;</pre></div></div>
-
- </li>
-
-
- <li id="section-344">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-344">&#182;</a>
- </div>
- <p>Handler numbers</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> (<span class="hljs-keyword">typeof</span> value === <span class="hljs-string">"number"</span>) <span class="hljs-keyword">return</span> <span class="hljs-literal">false</span>; <span class="hljs-comment">// numbers are never "empty"</span></pre></div></div>
-
- </li>
-
-
- <li id="section-345">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-345">&#182;</a>
- </div>
- <p>Handle strings and arrays</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> (value.length &amp;&amp; value.length &gt; <span class="hljs-number">0</span>) <span class="hljs-keyword">return</span> <span class="hljs-literal">false</span>;</pre></div></div>
-
- </li>
-
-
- <li id="section-346">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-346">&#182;</a>
- </div>
- <p>Handle objects</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">for</span> (<span class="hljs-keyword">var</span> key <span class="hljs-keyword">in</span> value) {
- <span class="hljs-keyword">if</span> (value.hasOwnProperty(key)) <span class="hljs-keyword">return</span> <span class="hljs-literal">false</span>;
- }
- <span class="hljs-keyword">return</span> <span class="hljs-literal">true</span>;
- },
- odd: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">value</span>) </span>{
- <span class="hljs-keyword">return</span> value % <span class="hljs-number">2</span> === <span class="hljs-number">1</span>;
- },
- even: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">value</span>) </span>{
- <span class="hljs-keyword">return</span> value % <span class="hljs-number">2</span> === <span class="hljs-number">0</span>;
- },
- divisibleby: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">value, params</span>) </span>{
- <span class="hljs-keyword">return</span> value % params[<span class="hljs-number">0</span>] === <span class="hljs-number">0</span>;
- },
- defined: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">value</span>) </span>{
- <span class="hljs-keyword">return</span> value !== <span class="hljs-literal">undefined</span>;
- },
- none: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">value</span>) </span>{
- <span class="hljs-keyword">return</span> value === <span class="hljs-literal">null</span>;
- },
- <span class="hljs-string">'null'</span>: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">value</span>) </span>{
- <span class="hljs-keyword">return</span> <span class="hljs-keyword">this</span>.none(value); <span class="hljs-comment">// Alias of none</span>
- },
- sameas: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">value, params</span>) </span>{
- <span class="hljs-keyword">return</span> value === params[<span class="hljs-number">0</span>];
- },
- iterable: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">value</span>) </span>{
- <span class="hljs-keyword">return</span> value &amp;&amp; (Twig.lib.is(<span class="hljs-string">"Array"</span>, value) || Twig.lib.is(<span class="hljs-string">"Object"</span>, value));
- }
- <span class="hljs-comment">/*
- constant ?
- */</span>
- };
-
- Twig.test = <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">test, value, params</span>) </span>{
- <span class="hljs-keyword">if</span> (!Twig.tests[test]) {
- <span class="hljs-keyword">throw</span> <span class="hljs-string">"Test "</span> + test + <span class="hljs-string">" is not defined."</span>;
- }
- <span class="hljs-keyword">return</span> Twig.tests[test](value, params);
- };
-
- Twig.test.extend = <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">test, definition</span>) </span>{
- Twig.tests[test] = definition;
- };
-
- <span class="hljs-keyword">return</span> Twig;
-})( Twig || { } );</pre></div></div>
-
- </li>
-
-
- <li id="section-347">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-347">&#182;</a>
- </div>
- <pre><code>Twig.js
-Available under the BSD <span class="hljs-number">2</span>-Clause License
-https:<span class="hljs-comment">//github.com/justjohn/twig.js</span>
-</code></pre>
- </div>
-
- </li>
-
-
- <li id="section-348">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-348">&#182;</a>
- </div>
- <h2 id="twig-exports-js">twig.exports.js</h2>
-<p>This file provides extension points and other hooks into the twig functionality.</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre>
-<span class="hljs-keyword">var</span> Twig = (<span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">Twig</span>) </span>{
-<span class="hljs-meta"> "use strict"</span>;
- Twig.exports = {
- VERSION: Twig.VERSION
- };
-
- <span class="hljs-comment">/**
- * Create and compile a twig.js template.
- *
- * @param {Object} param Paramteres for creating a Twig template.
- *
- * @return {Twig.Template} A Twig template ready for rendering.
- */</span>
- Twig.exports.twig = <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">twig</span>(<span class="hljs-params">params</span>) </span>{
-<span class="hljs-meta"> 'use strict'</span>;
- <span class="hljs-keyword">var</span> id = params.id,
- options = {
- strict_variables: params.strict_variables || <span class="hljs-literal">false</span>,</pre></div></div>
-
- </li>
-
-
- <li id="section-349">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-349">&#182;</a>
- </div>
- <p>TODO: turn autoscape on in the next major version</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> autoescape: params.autoescape != <span class="hljs-literal">null</span> &amp;&amp; params.autoescape || <span class="hljs-literal">false</span>,
- allowInlineIncludes: params.allowInlineIncludes || <span class="hljs-literal">false</span>,
- rethrow: params.rethrow || <span class="hljs-literal">false</span>,
- namespaces: params.namespaces
- };
-
- <span class="hljs-keyword">if</span> (Twig.cache &amp;&amp; id) {
- Twig.validateId(id);
- }
-
- <span class="hljs-keyword">if</span> (params.debug !== <span class="hljs-literal">undefined</span>) {
- Twig.debug = params.debug;
- }
- <span class="hljs-keyword">if</span> (params.trace !== <span class="hljs-literal">undefined</span>) {
- Twig.trace = params.trace;
- }
-
- <span class="hljs-keyword">if</span> (params.data !== <span class="hljs-literal">undefined</span>) {
- <span class="hljs-keyword">return</span> Twig.Templates.parsers.twig({
- data: params.data,
- path: params.hasOwnProperty(<span class="hljs-string">'path'</span>) ? params.path : <span class="hljs-literal">undefined</span>,
- <span class="hljs-built_in">module</span>: params.module,
- id: id,
- options: options
- });
-
- } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (params.ref !== <span class="hljs-literal">undefined</span>) {
- <span class="hljs-keyword">if</span> (params.id !== <span class="hljs-literal">undefined</span>) {
- <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> Twig.Error(<span class="hljs-string">"Both ref and id cannot be set on a twig.js template."</span>);
- }
- <span class="hljs-keyword">return</span> Twig.Templates.load(params.ref);
-
- } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (params.method !== <span class="hljs-literal">undefined</span>) {
- <span class="hljs-keyword">if</span> (!Twig.Templates.isRegisteredLoader(params.method)) {
- <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> Twig.Error(<span class="hljs-string">'Loader for "'</span> + params.method + <span class="hljs-string">'" is not defined.'</span>);
- }
- <span class="hljs-keyword">return</span> Twig.Templates.loadRemote(params.name || params.href || params.path || id || <span class="hljs-literal">undefined</span>, {
- id: id,
- method: params.method,
- parser: params.parser || <span class="hljs-string">'twig'</span>,
- base: params.base,
- <span class="hljs-built_in">module</span>: params.module,
- precompiled: params.precompiled,
- <span class="hljs-keyword">async</span>: params.async,
- options: options
-
- }, params.load, params.error);
-
- } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (params.href !== <span class="hljs-literal">undefined</span>) {
- <span class="hljs-keyword">return</span> Twig.Templates.loadRemote(params.href, {
- id: id,
- method: <span class="hljs-string">'ajax'</span>,
- parser: params.parser || <span class="hljs-string">'twig'</span>,
- base: params.base,
- <span class="hljs-built_in">module</span>: params.module,
- precompiled: params.precompiled,
- <span class="hljs-keyword">async</span>: params.async,
- options: options
-
- }, params.load, params.error);
-
- } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (params.path !== <span class="hljs-literal">undefined</span>) {
- <span class="hljs-keyword">return</span> Twig.Templates.loadRemote(params.path, {
- id: id,
- method: <span class="hljs-string">'fs'</span>,
- parser: params.parser || <span class="hljs-string">'twig'</span>,
- base: params.base,
- <span class="hljs-built_in">module</span>: params.module,
- precompiled: params.precompiled,
- <span class="hljs-keyword">async</span>: params.async,
- options: options
-
- }, params.load, params.error);
- }
- };</pre></div></div>
-
- </li>
-
-
- <li id="section-350">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-350">&#182;</a>
- </div>
- <p>Extend Twig with a new filter.</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> Twig.exports.extendFilter = <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">filter, definition</span>) </span>{
- Twig.filter.extend(filter, definition);
- };</pre></div></div>
-
- </li>
-
-
- <li id="section-351">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-351">&#182;</a>
- </div>
- <p>Extend Twig with a new function.</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> Twig.exports.extendFunction = <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">fn, definition</span>) </span>{
- Twig._function.extend(fn, definition);
- };</pre></div></div>
-
- </li>
-
-
- <li id="section-352">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-352">&#182;</a>
- </div>
- <p>Extend Twig with a new test.</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> Twig.exports.extendTest = <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">test, definition</span>) </span>{
- Twig.test.extend(test, definition);
- };</pre></div></div>
-
- </li>
-
-
- <li id="section-353">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-353">&#182;</a>
- </div>
- <p>Extend Twig with a new definition.</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> Twig.exports.extendTag = <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">definition</span>) </span>{
- Twig.logic.extend(definition);
- };</pre></div></div>
-
- </li>
-
-
- <li id="section-354">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-354">&#182;</a>
- </div>
- <p>Provide an environment for extending Twig core.
-Calls fn with the internal Twig object.</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> Twig.exports.extend = <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">fn</span>) </span>{
- fn(Twig);
- };
-
-
- <span class="hljs-comment">/**
- * Provide an extension for use with express 2.
- *
- * @param {string} markup The template markup.
- * @param {array} options The express options.
- *
- * @return {string} The rendered template.
- */</span>
- Twig.exports.compile = <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">markup, options</span>) </span>{
- <span class="hljs-keyword">var</span> id = options.filename,
- path = options.filename,
- template;</pre></div></div>
-
- </li>
-
-
- <li id="section-355">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-355">&#182;</a>
- </div>
- <p>Try to load the template from the cache</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> template = <span class="hljs-keyword">new</span> Twig.Template({
- data: markup,
- path: path,
- id: id,
- options: options.settings[<span class="hljs-string">'twig options'</span>]
- }); <span class="hljs-comment">// Twig.Templates.load(id) ||</span>
-
- <span class="hljs-keyword">return</span> <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">context</span>) </span>{
- <span class="hljs-keyword">return</span> template.render(context);
- };
- };
-
- <span class="hljs-comment">/**
- * Provide an extension for use with express 3.
- *
- * @param {string} path The location of the template file on disk.
- * @param {Object|Function} The options or callback.
- * @param {Function} fn callback.
- *
- * @throws Twig.Error
- */</span>
- Twig.exports.renderFile = <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">path, options, fn</span>) </span>{</pre></div></div>
-
- </li>
-
-
- <li id="section-356">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-356">&#182;</a>
- </div>
- <p>handle callback in options</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> (<span class="hljs-keyword">typeof</span> options === <span class="hljs-string">'function'</span>) {
- fn = options;
- options = {};
- }
-
- options = options || {};
-
- <span class="hljs-keyword">var</span> settings = options.settings || {};
-
- <span class="hljs-keyword">var</span> params = {
- path: path,
- base: settings.views,
- load: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">template</span>) </span>{</pre></div></div>
-
- </li>
-
-
- <li id="section-357">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-357">&#182;</a>
- </div>
- <p>render and return template</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> fn(<span class="hljs-literal">null</span>, template.render(options));
- }
- };</pre></div></div>
-
- </li>
-
-
- <li id="section-358">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-358">&#182;</a>
- </div>
- <p>mixin any options provided to the express app.</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">var</span> view_options = settings[<span class="hljs-string">'twig options'</span>];
-
- <span class="hljs-keyword">if</span> (view_options) {
- <span class="hljs-keyword">for</span> (<span class="hljs-keyword">var</span> option <span class="hljs-keyword">in</span> view_options) {
- <span class="hljs-keyword">if</span> (view_options.hasOwnProperty(option)) {
- params[option] = view_options[option];
- }
- }
- }
-
- Twig.exports.twig(params);
- };</pre></div></div>
-
- </li>
-
-
- <li id="section-359">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-359">&#182;</a>
- </div>
- <p>Express 3 handler</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> Twig.exports.__express = Twig.exports.renderFile;
-
- <span class="hljs-comment">/**
- * Shoud Twig.js cache templates.
- * Disable during development to see changes to templates without
- * reloading, and disable in production to improve performance.
- *
- * @param {boolean} cache
- */</span>
- Twig.exports.cache = <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">cache</span>) </span>{
- Twig.cache = cache;
- };</pre></div></div>
-
- </li>
-
-
- <li id="section-360">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-360">&#182;</a>
- </div>
- <p>We need to export the path module so we can effectively test it</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> Twig.exports.path = Twig.path;
-
- <span class="hljs-keyword">return</span> Twig;
-}) (Twig || { });</pre></div></div>
-
- </li>
-
-
- <li id="section-361">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-361">&#182;</a>
- </div>
- <pre><code>Twig.js
-Available under the BSD <span class="hljs-number">2</span>-Clause License
-https:<span class="hljs-comment">//github.com/justjohn/twig.js</span>
-</code></pre>
- </div>
-
- </li>
-
-
- <li id="section-362">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-362">&#182;</a>
- </div>
- <h2 id="twig-compiler-js">twig.compiler.js</h2>
-<p>This file handles compiling templates into JS</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre><span class="hljs-keyword">var</span> Twig = (<span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">Twig</span>) </span>{
- <span class="hljs-comment">/**
- * Namespace for compilation.
- */</span>
- Twig.compiler = {
- <span class="hljs-built_in">module</span>: {}
- };</pre></div></div>
-
- </li>
-
-
- <li id="section-363">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-363">&#182;</a>
- </div>
- <p>Compile a Twig Template to output.</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> Twig.compiler.compile = <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">template, options</span>) </span>{</pre></div></div>
-
- </li>
-
-
- <li id="section-364">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-364">&#182;</a>
- </div>
- <p>Get tokens</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">var</span> tokens = <span class="hljs-built_in">JSON</span>.stringify(template.tokens)
- , id = template.id
- , output;
-
- <span class="hljs-keyword">if</span> (options.module) {
- <span class="hljs-keyword">if</span> (Twig.compiler.module[options.module] === <span class="hljs-literal">undefined</span>) {
- <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> Twig.Error(<span class="hljs-string">"Unable to find module type "</span> + options.module);
- }
- output = Twig.compiler.module[options.module](id, tokens, options.twig);
- } <span class="hljs-keyword">else</span> {
- output = Twig.compiler.wrap(id, tokens);
- }
- <span class="hljs-keyword">return</span> output;
- };
-
- Twig.compiler.module = {
- amd: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">id, tokens, pathToTwig</span>) </span>{
- <span class="hljs-keyword">return</span> <span class="hljs-string">'define(["'</span> + pathToTwig + <span class="hljs-string">'"], function (Twig) {\n\tvar twig, templates;\ntwig = Twig.twig;\ntemplates = '</span> + Twig.compiler.wrap(id, tokens) + <span class="hljs-string">'\n\treturn templates;\n});'</span>;
- }
- , node: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">id, tokens</span>) </span>{
- <span class="hljs-keyword">return</span> <span class="hljs-string">'var twig = require("twig").twig;\n'</span>
- + <span class="hljs-string">'exports.template = '</span> + Twig.compiler.wrap(id, tokens)
- }
- , cjs2: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">id, tokens, pathToTwig</span>) </span>{
- <span class="hljs-keyword">return</span> <span class="hljs-string">'module.declare([{ twig: "'</span> + pathToTwig + <span class="hljs-string">'" }], function (require, exports, module) {\n'</span>
- + <span class="hljs-string">'\tvar twig = require("twig").twig;\n'</span>
- + <span class="hljs-string">'\texports.template = '</span> + Twig.compiler.wrap(id, tokens)
- + <span class="hljs-string">'\n});'</span>
- }
- };
-
- Twig.compiler.wrap = <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">id, tokens</span>) </span>{
- <span class="hljs-keyword">return</span> <span class="hljs-string">'twig({id:"'</span>+id.replace(<span class="hljs-string">'"'</span>, <span class="hljs-string">'\\"'</span>)+<span class="hljs-string">'", data:'</span>+tokens+<span class="hljs-string">', precompiled: true});\n'</span>;
- };
-
- <span class="hljs-keyword">return</span> Twig;
-})(Twig || {});</pre></div></div>
-
- </li>
-
-
- <li id="section-365">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-365">&#182;</a>
- </div>
- <pre><code>Twig.js
-Available under the BSD <span class="hljs-number">2</span>-Clause License
-https:<span class="hljs-comment">//github.com/justjohn/twig.js</span>
-</code></pre>
- </div>
-
- </li>
-
-
- <li id="section-366">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-366">&#182;</a>
- </div>
- <h2 id="twig-module-js">twig.module.js</h2>
-<p>Provide a CommonJS/AMD/Node module export.</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre>
-<span class="hljs-keyword">if</span> (<span class="hljs-keyword">typeof</span> <span class="hljs-built_in">module</span> !== <span class="hljs-string">'undefined'</span> &amp;&amp; <span class="hljs-built_in">module</span>.declare) {</pre></div></div>
-
- </li>
-
-
- <li id="section-367">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-367">&#182;</a>
- </div>
- <p>Provide a CommonJS Modules/2.0 draft 8 module</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> <span class="hljs-built_in">module</span>.declare([], <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">require, exports, module</span>) </span>{</pre></div></div>
-
- </li>
-
-
- <li id="section-368">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-368">&#182;</a>
- </div>
- <p>Add exports from the Twig exports</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> <span class="hljs-keyword">for</span> (key <span class="hljs-keyword">in</span> Twig.exports) {
- <span class="hljs-keyword">if</span> (Twig.exports.hasOwnProperty(key)) {
- exports[key] = Twig.exports[key];
- }
- }
- });
-} <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (<span class="hljs-keyword">typeof</span> define == <span class="hljs-string">'function'</span> &amp;&amp; define.amd) {
- define(<span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) </span>{
- <span class="hljs-keyword">return</span> Twig.exports;
- });
-} <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (<span class="hljs-keyword">typeof</span> <span class="hljs-built_in">module</span> !== <span class="hljs-string">'undefined'</span> &amp;&amp; <span class="hljs-built_in">module</span>.exports) {</pre></div></div>
-
- </li>
-
-
- <li id="section-369">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-369">&#182;</a>
- </div>
- <p>Provide a CommonJS Modules/1.1 module</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> <span class="hljs-built_in">module</span>.exports = Twig.exports;
-} <span class="hljs-keyword">else</span> {</pre></div></div>
-
- </li>
-
-
- <li id="section-370">
- <div class="annotation">
-
- <div class="pilwrap ">
- <a class="pilcrow" href="#section-370">&#182;</a>
- </div>
- <p>Export for browser use</p>
-
- </div>
-
- <div class="content"><div class='highlight'><pre> <span class="hljs-built_in">window</span>.twig = Twig.exports.twig;
- <span class="hljs-built_in">window</span>.Twig = Twig.exports;
-}</pre></div></div>
-
- </li>
-
- </ul>
- </div>
-</body>
-</html>