Repository: pugjs/pug Branch: master Commit: c323ed3e630b Files: 912 Total size: 2.7 MB Directory structure: gitextract_f46w__89/ ├── .editorconfig ├── .gitattributes ├── .github/ │ ├── FUNDING.yml │ ├── ISSUE_TEMPLATE.md │ └── workflows/ │ ├── rollingversions.yml │ └── test.yml ├── .gitignore ├── .prettierrc.js ├── README.md ├── SECURITY.md ├── package.json ├── packages/ │ ├── pug/ │ │ ├── History.md │ │ ├── LICENSE │ │ ├── README.md │ │ ├── examples/ │ │ │ ├── README.md │ │ │ ├── attributes.js │ │ │ ├── attributes.pug │ │ │ ├── code.js │ │ │ ├── code.pug │ │ │ ├── dynamicscript.js │ │ │ ├── dynamicscript.pug │ │ │ ├── each.js │ │ │ ├── each.pug │ │ │ ├── extend-layout.pug │ │ │ ├── extend.js │ │ │ ├── extend.pug │ │ │ ├── form.js │ │ │ ├── form.pug │ │ │ ├── includes/ │ │ │ │ ├── foot.pug │ │ │ │ ├── head.pug │ │ │ │ ├── scripts.pug │ │ │ │ └── style.css │ │ │ ├── includes.js │ │ │ ├── includes.pug │ │ │ ├── layout-debug.js │ │ │ ├── layout.js │ │ │ ├── layout.pug │ │ │ ├── mixins/ │ │ │ │ ├── dialog.pug │ │ │ │ └── profile.pug │ │ │ ├── mixins.js │ │ │ ├── mixins.pug │ │ │ ├── pet.pug │ │ │ ├── rss.js │ │ │ ├── rss.pug │ │ │ ├── text.js │ │ │ ├── text.pug │ │ │ ├── whitespace.js │ │ │ └── whitespace.pug │ │ ├── lib/ │ │ │ └── index.js │ │ ├── package.json │ │ ├── register.js │ │ ├── support/ │ │ │ └── benchmark.js │ │ └── test/ │ │ ├── README.md │ │ ├── __snapshots__/ │ │ │ └── pug.test.js.snap │ │ ├── anti-cases/ │ │ │ ├── attrs.unescaped.pug │ │ │ ├── case-when.pug │ │ │ ├── case-without-with.pug │ │ │ ├── else-condition.pug │ │ │ ├── else-without-if.pug │ │ │ ├── inlining-a-mixin-after-a-tag.pug │ │ │ ├── key-char-ending-badly.pug │ │ │ ├── key-ending-badly.pug │ │ │ ├── mismatched-inline-tag.pug │ │ │ ├── mixin-args-syntax-error.pug │ │ │ ├── mixins-blocks-with-bodies.pug │ │ │ ├── multiple-non-nested-tags-on-a-line.pug │ │ │ ├── non-existant-filter.pug │ │ │ ├── non-mixin-block.pug │ │ │ ├── open-brace-in-attributes.pug │ │ │ ├── readme.md │ │ │ ├── self-closing-tag-with-block.pug │ │ │ ├── self-closing-tag-with-body.pug │ │ │ ├── self-closing-tag-with-code.pug │ │ │ ├── tabs-and-spaces.pug │ │ │ ├── unclosed-interpolated-call.pug │ │ │ ├── unclosed-interpolated-tag.pug │ │ │ └── unclosed-interpolation.pug │ │ ├── browser/ │ │ │ ├── index.html │ │ │ └── index.pug │ │ ├── cases/ │ │ │ ├── attrs-data.html │ │ │ ├── attrs-data.pug │ │ │ ├── attrs.colon.html │ │ │ ├── attrs.colon.pug │ │ │ ├── attrs.html │ │ │ ├── attrs.js.html │ │ │ ├── attrs.js.pug │ │ │ ├── attrs.pug │ │ │ ├── attrs.unescaped.html │ │ │ ├── attrs.unescaped.pug │ │ │ ├── auxiliary/ │ │ │ │ ├── 1794-extends.pug │ │ │ │ ├── 1794-include.pug │ │ │ │ ├── blocks-in-blocks-layout.pug │ │ │ │ ├── dialog.pug │ │ │ │ ├── empty-block.pug │ │ │ │ ├── escapes.html │ │ │ │ ├── extends-empty-block-1.pug │ │ │ │ ├── extends-empty-block-2.pug │ │ │ │ ├── extends-from-root.pug │ │ │ │ ├── extends-relative.pug │ │ │ │ ├── filter-in-include.pug │ │ │ │ ├── includable.js │ │ │ │ ├── include-from-root.pug │ │ │ │ ├── inheritance.extend.mixin.block.pug │ │ │ │ ├── inheritance.extend.recursive-grand-grandparent.pug │ │ │ │ ├── inheritance.extend.recursive-grandparent.pug │ │ │ │ ├── inheritance.extend.recursive-parent.pug │ │ │ │ ├── layout.include.pug │ │ │ │ ├── layout.pug │ │ │ │ ├── mixin-at-end-of-file.pug │ │ │ │ ├── mixins.pug │ │ │ │ ├── pet.pug │ │ │ │ ├── smile.html │ │ │ │ ├── window.pug │ │ │ │ └── yield-nested.pug │ │ │ ├── basic.html │ │ │ ├── basic.pug │ │ │ ├── blanks.html │ │ │ ├── blanks.pug │ │ │ ├── block-code.html │ │ │ ├── block-code.pug │ │ │ ├── block-expansion.html │ │ │ ├── block-expansion.pug │ │ │ ├── block-expansion.shorthands.html │ │ │ ├── block-expansion.shorthands.pug │ │ │ ├── blockquote.html │ │ │ ├── blockquote.pug │ │ │ ├── blocks-in-blocks.html │ │ │ ├── blocks-in-blocks.pug │ │ │ ├── blocks-in-if.html │ │ │ ├── blocks-in-if.pug │ │ │ ├── case-blocks.html │ │ │ ├── case-blocks.pug │ │ │ ├── case.html │ │ │ ├── case.pug │ │ │ ├── classes-empty.html │ │ │ ├── classes-empty.pug │ │ │ ├── classes.html │ │ │ ├── classes.pug │ │ │ ├── code.conditionals.html │ │ │ ├── code.conditionals.pug │ │ │ ├── code.escape.html │ │ │ ├── code.escape.pug │ │ │ ├── code.html │ │ │ ├── code.iteration.html │ │ │ ├── code.iteration.pug │ │ │ ├── code.pug │ │ │ ├── comments-in-case.html │ │ │ ├── comments-in-case.pug │ │ │ ├── comments.html │ │ │ ├── comments.pug │ │ │ ├── comments.source.html │ │ │ ├── comments.source.pug │ │ │ ├── doctype.custom.html │ │ │ ├── doctype.custom.pug │ │ │ ├── doctype.default.html │ │ │ ├── doctype.default.pug │ │ │ ├── doctype.keyword.html │ │ │ ├── doctype.keyword.pug │ │ │ ├── each.else.html │ │ │ ├── each.else.pug │ │ │ ├── escape-chars.html │ │ │ ├── escape-chars.pug │ │ │ ├── escape-test.html │ │ │ ├── escape-test.pug │ │ │ ├── escaping-class-attribute.html │ │ │ ├── escaping-class-attribute.pug │ │ │ ├── filter-in-include.html │ │ │ ├── filter-in-include.pug │ │ │ ├── filters-empty.html │ │ │ ├── filters-empty.pug │ │ │ ├── filters.coffeescript.html │ │ │ ├── filters.coffeescript.pug │ │ │ ├── filters.custom.html │ │ │ ├── filters.custom.pug │ │ │ ├── filters.include.custom.html │ │ │ ├── filters.include.custom.pug │ │ │ ├── filters.include.html │ │ │ ├── filters.include.pug │ │ │ ├── filters.inline.html │ │ │ ├── filters.inline.pug │ │ │ ├── filters.less.html │ │ │ ├── filters.less.pug │ │ │ ├── filters.markdown.html │ │ │ ├── filters.markdown.pug │ │ │ ├── filters.nested.html │ │ │ ├── filters.nested.pug │ │ │ ├── filters.stylus.html │ │ │ ├── filters.stylus.pug │ │ │ ├── html.html │ │ │ ├── html.pug │ │ │ ├── html5.html │ │ │ ├── html5.pug │ │ │ ├── include-extends-from-root.html │ │ │ ├── include-extends-from-root.pug │ │ │ ├── include-extends-of-common-template.html │ │ │ ├── include-extends-of-common-template.pug │ │ │ ├── include-extends-relative.html │ │ │ ├── include-extends-relative.pug │ │ │ ├── include-filter-coffee.coffee │ │ │ ├── include-only-text-body.html │ │ │ ├── include-only-text-body.pug │ │ │ ├── include-only-text.html │ │ │ ├── include-only-text.pug │ │ │ ├── include-with-text-head.html │ │ │ ├── include-with-text-head.pug │ │ │ ├── include-with-text.html │ │ │ ├── include-with-text.pug │ │ │ ├── include.script.html │ │ │ ├── include.script.pug │ │ │ ├── include.yield.nested.html │ │ │ ├── include.yield.nested.pug │ │ │ ├── includes-with-ext-js.html │ │ │ ├── includes-with-ext-js.pug │ │ │ ├── includes.html │ │ │ ├── includes.pug │ │ │ ├── inheritance.alert-dialog.html │ │ │ ├── inheritance.alert-dialog.pug │ │ │ ├── inheritance.defaults.html │ │ │ ├── inheritance.defaults.pug │ │ │ ├── inheritance.extend.html │ │ │ ├── inheritance.extend.include.html │ │ │ ├── inheritance.extend.include.pug │ │ │ ├── inheritance.extend.mixins.block.html │ │ │ ├── inheritance.extend.mixins.block.pug │ │ │ ├── inheritance.extend.mixins.html │ │ │ ├── inheritance.extend.mixins.pug │ │ │ ├── inheritance.extend.pug │ │ │ ├── inheritance.extend.recursive.html │ │ │ ├── inheritance.extend.recursive.pug │ │ │ ├── inheritance.extend.whitespace.html │ │ │ ├── inheritance.extend.whitespace.pug │ │ │ ├── inheritance.html │ │ │ ├── inheritance.pug │ │ │ ├── inline-tag.html │ │ │ ├── inline-tag.pug │ │ │ ├── intepolated-elements.html │ │ │ ├── intepolated-elements.pug │ │ │ ├── interpolated-mixin.html │ │ │ ├── interpolated-mixin.pug │ │ │ ├── interpolation.escape.html │ │ │ ├── interpolation.escape.pug │ │ │ ├── javascript-new-lines.js │ │ │ ├── layout.append.html │ │ │ ├── layout.append.pug │ │ │ ├── layout.append.without-block.html │ │ │ ├── layout.append.without-block.pug │ │ │ ├── layout.multi.append.prepend.block.html │ │ │ ├── layout.multi.append.prepend.block.pug │ │ │ ├── layout.prepend.html │ │ │ ├── layout.prepend.pug │ │ │ ├── layout.prepend.without-block.html │ │ │ ├── layout.prepend.without-block.pug │ │ │ ├── mixin-at-end-of-file.html │ │ │ ├── mixin-at-end-of-file.pug │ │ │ ├── mixin-block-with-space.html │ │ │ ├── mixin-block-with-space.pug │ │ │ ├── mixin-hoist.html │ │ │ ├── mixin-hoist.pug │ │ │ ├── mixin-via-include.html │ │ │ ├── mixin-via-include.pug │ │ │ ├── mixin.attrs.html │ │ │ ├── mixin.attrs.pug │ │ │ ├── mixin.block-tag-behaviour.html │ │ │ ├── mixin.block-tag-behaviour.pug │ │ │ ├── mixin.blocks.html │ │ │ ├── mixin.blocks.pug │ │ │ ├── mixin.merge.html │ │ │ ├── mixin.merge.pug │ │ │ ├── mixins-unused.html │ │ │ ├── mixins-unused.pug │ │ │ ├── mixins.html │ │ │ ├── mixins.pug │ │ │ ├── mixins.rest-args.html │ │ │ ├── mixins.rest-args.pug │ │ │ ├── namespaces.html │ │ │ ├── namespaces.pug │ │ │ ├── nesting.html │ │ │ ├── nesting.pug │ │ │ ├── pipeless-comments.html │ │ │ ├── pipeless-comments.pug │ │ │ ├── pipeless-filters.html │ │ │ ├── pipeless-filters.pug │ │ │ ├── pipeless-tag.html │ │ │ ├── pipeless-tag.pug │ │ │ ├── pre.html │ │ │ ├── pre.pug │ │ │ ├── quotes.html │ │ │ ├── quotes.pug │ │ │ ├── regression.1794.html │ │ │ ├── regression.1794.pug │ │ │ ├── regression.784.html │ │ │ ├── regression.784.pug │ │ │ ├── script.whitespace.html │ │ │ ├── script.whitespace.pug │ │ │ ├── scripts.html │ │ │ ├── scripts.non-js.html │ │ │ ├── scripts.non-js.pug │ │ │ ├── scripts.pug │ │ │ ├── self-closing-html.html │ │ │ ├── self-closing-html.pug │ │ │ ├── single-period.html │ │ │ ├── single-period.pug │ │ │ ├── some-included.styl │ │ │ ├── some.md │ │ │ ├── some.styl │ │ │ ├── source.html │ │ │ ├── source.pug │ │ │ ├── styles.html │ │ │ ├── styles.pug │ │ │ ├── tag.interpolation.html │ │ │ ├── tag.interpolation.pug │ │ │ ├── tags.self-closing.html │ │ │ ├── tags.self-closing.pug │ │ │ ├── template.html │ │ │ ├── template.pug │ │ │ ├── text-block.html │ │ │ ├── text-block.pug │ │ │ ├── text.html │ │ │ ├── text.pug │ │ │ ├── utf8bom.html │ │ │ ├── utf8bom.pug │ │ │ ├── vars.html │ │ │ ├── vars.pug │ │ │ ├── while.html │ │ │ ├── while.pug │ │ │ ├── xml.html │ │ │ ├── xml.pug │ │ │ ├── yield-before-conditional-head.html │ │ │ ├── yield-before-conditional-head.pug │ │ │ ├── yield-before-conditional.html │ │ │ ├── yield-before-conditional.pug │ │ │ ├── yield-head.html │ │ │ ├── yield-head.pug │ │ │ ├── yield-title-head.html │ │ │ ├── yield-title-head.pug │ │ │ ├── yield-title.html │ │ │ ├── yield-title.pug │ │ │ ├── yield.html │ │ │ └── yield.pug │ │ ├── cases-es2015/ │ │ │ ├── attr.html │ │ │ └── attr.pug │ │ ├── dependencies/ │ │ │ ├── dependency1.pug │ │ │ ├── dependency2.pug │ │ │ ├── dependency3.pug │ │ │ ├── extends1.pug │ │ │ ├── extends2.pug │ │ │ ├── include1.pug │ │ │ └── include2.pug │ │ ├── duplicate-block/ │ │ │ ├── __snapshots__/ │ │ │ │ └── index.test.js.snap │ │ │ ├── index.pug │ │ │ ├── index.test.js │ │ │ └── layout-with-duplicate-block.pug │ │ ├── eachOf/ │ │ │ ├── __snapshots__/ │ │ │ │ └── index.test.js.snap │ │ │ ├── error/ │ │ │ │ ├── left-side.pug │ │ │ │ ├── no-brackets.pug │ │ │ │ ├── one-val.pug │ │ │ │ └── right-side.pug │ │ │ ├── index.test.js │ │ │ └── passing/ │ │ │ ├── brackets.pug │ │ │ └── no-brackets.pug │ │ ├── error.reporting.test.js │ │ ├── examples.test.js │ │ ├── extends-not-top-level/ │ │ │ ├── default.pug │ │ │ ├── duplicate.pug │ │ │ ├── index.pug │ │ │ └── index.test.js │ │ ├── fixtures/ │ │ │ ├── append/ │ │ │ │ ├── app-layout.pug │ │ │ │ ├── layout.pug │ │ │ │ ├── page.html │ │ │ │ └── page.pug │ │ │ ├── append-without-block/ │ │ │ │ ├── app-layout.pug │ │ │ │ ├── layout.pug │ │ │ │ └── page.pug │ │ │ ├── compile.with.include.locals.error.pug │ │ │ ├── compile.with.include.syntax.error.pug │ │ │ ├── compile.with.layout.locals.error.pug │ │ │ ├── compile.with.layout.syntax.error.pug │ │ │ ├── compile.with.layout.with.include.locals.error.pug │ │ │ ├── compile.with.layout.with.include.syntax.error.pug │ │ │ ├── element-with-multiple-attributes.pug │ │ │ ├── include.locals.error.pug │ │ │ ├── include.syntax.error.pug │ │ │ ├── invalid-block-in-extends.pug │ │ │ ├── issue-1593/ │ │ │ │ ├── include-layout.pug │ │ │ │ ├── include.pug │ │ │ │ ├── index.pug │ │ │ │ └── layout.pug │ │ │ ├── layout.locals.error.pug │ │ │ ├── layout.pug │ │ │ ├── layout.syntax.error.pug │ │ │ ├── layout.with.runtime.error.pug │ │ │ ├── mixin-include.pug │ │ │ ├── mixin.error.pug │ │ │ ├── multi-append-prepend-block/ │ │ │ │ ├── redefine.pug │ │ │ │ └── root.pug │ │ │ ├── perf.pug │ │ │ ├── prepend/ │ │ │ │ ├── app-layout.pug │ │ │ │ ├── layout.pug │ │ │ │ ├── page.html │ │ │ │ └── page.pug │ │ │ ├── prepend-without-block/ │ │ │ │ ├── app-layout.pug │ │ │ │ ├── layout.pug │ │ │ │ ├── page.html │ │ │ │ └── page.pug │ │ │ ├── runtime.error.pug │ │ │ ├── runtime.layout.error.pug │ │ │ ├── runtime.with.mixin.error.pug │ │ │ └── scripts.pug │ │ ├── markdown-it/ │ │ │ ├── comment.md │ │ │ ├── index.test.js │ │ │ ├── layout-markdown-include.pug │ │ │ └── layout-markdown-inline.pug │ │ ├── plugins.test.js │ │ ├── pug.test.js │ │ ├── regression-2436/ │ │ │ ├── __snapshots__/ │ │ │ │ └── index.test.js.snap │ │ │ ├── index.test.js │ │ │ ├── issue1.pug │ │ │ ├── issue2.pug │ │ │ ├── layout.pug │ │ │ ├── other1.pug │ │ │ ├── other2.pug │ │ │ └── other_layout.pug │ │ ├── run-es2015.test.js │ │ ├── run-syntax-errors.test.js │ │ ├── run-utils.js │ │ ├── run.test.js │ │ └── shadowed-block/ │ │ ├── __snapshots__/ │ │ │ └── index.test.js.snap │ │ ├── base.pug │ │ ├── index.pug │ │ ├── index.test.js │ │ └── layout.pug │ ├── pug-attrs/ │ │ ├── LICENSE │ │ ├── README.md │ │ ├── index.js │ │ ├── package.json │ │ └── test/ │ │ └── index.test.js │ ├── pug-code-gen/ │ │ ├── HISTORY.md │ │ ├── LICENSE │ │ ├── README.md │ │ ├── index.js │ │ └── package.json │ ├── pug-error/ │ │ ├── LICENSE │ │ ├── README.md │ │ ├── package.json │ │ ├── src/ │ │ │ └── index.ts │ │ ├── test/ │ │ │ └── index.test.js │ │ └── tsconfig.json │ ├── pug-filters/ │ │ ├── CHANGELOG.md │ │ ├── LICENSE │ │ ├── README.md │ │ ├── index.js │ │ ├── lib/ │ │ │ ├── handle-filters.js │ │ │ └── run-filter.js │ │ ├── package.json │ │ └── test/ │ │ ├── __snapshots__/ │ │ │ ├── filter-aliases.test.js.snap │ │ │ ├── index.test.js.snap │ │ │ └── per-filter-options-applied-to-nested-filters.test.js.snap │ │ ├── cases/ │ │ │ ├── filters-empty.input.json │ │ │ ├── filters.cdata.input.json │ │ │ ├── filters.coffeescript.input.json │ │ │ ├── filters.custom.input.json │ │ │ ├── filters.include.custom.input.json │ │ │ ├── filters.include.custom.pug │ │ │ ├── filters.include.input.json │ │ │ ├── filters.inline.input.json │ │ │ ├── filters.less.input.json │ │ │ ├── filters.markdown.input.json │ │ │ ├── filters.nested.input.json │ │ │ ├── filters.stylus.input.json │ │ │ ├── include-filter-coffee.coffee │ │ │ └── some.md │ │ ├── custom-filters.js │ │ ├── errors/ │ │ │ └── dynamic-option.input.json │ │ ├── errors-src/ │ │ │ └── dynamic-option.jade │ │ ├── filter-aliases.test.js │ │ ├── index.test.js │ │ └── per-filter-options-applied-to-nested-filters.test.js │ ├── pug-lexer/ │ │ ├── History.md │ │ ├── LICENSE │ │ ├── README.md │ │ ├── index.d.ts │ │ ├── index.js │ │ ├── package.json │ │ └── test/ │ │ ├── __snapshots__/ │ │ │ └── index.test.js.snap │ │ ├── cases/ │ │ │ ├── attr-es2015.pug │ │ │ ├── attrs-data.pug │ │ │ ├── attrs.js.pug │ │ │ ├── attrs.pug │ │ │ ├── attrs.unescaped.pug │ │ │ ├── basic.pug │ │ │ ├── blanks.pug │ │ │ ├── block-code.pug │ │ │ ├── block-expansion.pug │ │ │ ├── block-expansion.shorthands.pug │ │ │ ├── blockquote.pug │ │ │ ├── blocks-in-blocks.pug │ │ │ ├── blocks-in-if.pug │ │ │ ├── case-blocks.pug │ │ │ ├── case.pug │ │ │ ├── classes-empty.pug │ │ │ ├── classes.pug │ │ │ ├── code.conditionals.pug │ │ │ ├── code.escape.pug │ │ │ ├── code.iteration.pug │ │ │ ├── code.pug │ │ │ ├── comments-in-case.pug │ │ │ ├── comments.pug │ │ │ ├── comments.source.pug │ │ │ ├── doctype.custom.pug │ │ │ ├── doctype.default.pug │ │ │ ├── doctype.keyword.pug │ │ │ ├── each.else.pug │ │ │ ├── escape-chars.pug │ │ │ ├── escape-test.pug │ │ │ ├── escaping-class-attribute.pug │ │ │ ├── filter-in-include.pug │ │ │ ├── filters-empty.pug │ │ │ ├── filters.coffeescript.pug │ │ │ ├── filters.custom.pug │ │ │ ├── filters.include.custom.pug │ │ │ ├── filters.include.pug │ │ │ ├── filters.inline.pug │ │ │ ├── filters.less.pug │ │ │ ├── filters.markdown.pug │ │ │ ├── filters.nested.pug │ │ │ ├── filters.stylus.pug │ │ │ ├── filters.verbatim.pug │ │ │ ├── html.pug │ │ │ ├── html5.pug │ │ │ ├── include-extends-from-root.pug │ │ │ ├── include-extends-of-common-template.pug │ │ │ ├── include-extends-relative.pug │ │ │ ├── include-only-text-body.pug │ │ │ ├── include-only-text.pug │ │ │ ├── include-with-text-head.pug │ │ │ ├── include-with-text.pug │ │ │ ├── include.script.pug │ │ │ ├── include.yield.nested.pug │ │ │ ├── includes-with-ext-js.pug │ │ │ ├── includes.pug │ │ │ ├── inheritance.alert-dialog.pug │ │ │ ├── inheritance.defaults.pug │ │ │ ├── inheritance.extend.include.pug │ │ │ ├── inheritance.extend.mixins.block.pug │ │ │ ├── inheritance.extend.mixins.pug │ │ │ ├── inheritance.extend.pug │ │ │ ├── inheritance.extend.recursive.pug │ │ │ ├── inheritance.extend.whitespace.pug │ │ │ ├── inheritance.pug │ │ │ ├── inline-block-comment.pug │ │ │ ├── inline-tag.pug │ │ │ ├── intepolated-elements.pug │ │ │ ├── interpolated-mixin.pug │ │ │ ├── interpolation.escape.pug │ │ │ ├── javascript-new-lines.js │ │ │ ├── layout.append.pug │ │ │ ├── layout.append.without-block.pug │ │ │ ├── layout.multi.append.prepend.block.pug │ │ │ ├── layout.prepend.pug │ │ │ ├── layout.prepend.without-block.pug │ │ │ ├── mixin-at-end-of-file.pug │ │ │ ├── mixin-block-with-space.pug │ │ │ ├── mixin-hoist.pug │ │ │ ├── mixin-via-include.pug │ │ │ ├── mixin.attrs.pug │ │ │ ├── mixin.block-tag-behaviour.pug │ │ │ ├── mixin.blocks.pug │ │ │ ├── mixin.merge.pug │ │ │ ├── mixins-unused.pug │ │ │ ├── mixins.pug │ │ │ ├── mixins.rest-args.pug │ │ │ ├── namespaces.pug │ │ │ ├── nesting.pug │ │ │ ├── pipeless-comments.pug │ │ │ ├── pipeless-filters.pug │ │ │ ├── pipeless-tag.pug │ │ │ ├── pre.pug │ │ │ ├── quotes.pug │ │ │ ├── regression.1794.pug │ │ │ ├── regression.784.pug │ │ │ ├── script.whitespace.pug │ │ │ ├── scripts.non-js.pug │ │ │ ├── scripts.pug │ │ │ ├── self-closing-html.pug │ │ │ ├── single-period.pug │ │ │ ├── source.pug │ │ │ ├── styles.pug │ │ │ ├── tag-blocks.pug │ │ │ ├── tag.interpolation.pug │ │ │ ├── tags.self-closing.pug │ │ │ ├── template.pug │ │ │ ├── text-block.pug │ │ │ ├── text.pug │ │ │ ├── utf8bom.pug │ │ │ ├── vars.pug │ │ │ ├── while.pug │ │ │ ├── xml.pug │ │ │ ├── yield-before-conditional-head.pug │ │ │ ├── yield-before-conditional.pug │ │ │ ├── yield-head.pug │ │ │ ├── yield-title-head.pug │ │ │ ├── yield-title.pug │ │ │ └── yield.pug │ │ ├── check-lexer-functions.test.js │ │ ├── errors/ │ │ │ ├── attribute-invalid-expression.pug │ │ │ ├── case-with-invalid-expression.pug │ │ │ ├── case-with-no-expression.pug │ │ │ ├── default-with-expression.pug │ │ │ ├── else-with-condition.pug │ │ │ ├── extends-no-path.pug │ │ │ ├── include-filter-no-path-2.pug │ │ │ ├── include-filter-no-path.pug │ │ │ ├── include-filter-no-space.pug │ │ │ ├── include-no-path.pug │ │ │ ├── inconsistent-indentation.pug │ │ │ ├── interpolated-call.pug │ │ │ ├── invalid-class-name-1.pug │ │ │ ├── invalid-class-name-2.pug │ │ │ ├── invalid-class-name-3.pug │ │ │ ├── invalid-id.pug │ │ │ ├── malformed-each.pug │ │ │ ├── malformed-extend.pug │ │ │ ├── malformed-include.pug │ │ │ ├── mismatched-inline-tag.pug │ │ │ ├── mismatched-tag-interpolation.pug │ │ │ ├── multi-line-interpolation.pug │ │ │ ├── old-prefixed-each.pug │ │ │ ├── open-interpolation.pug │ │ │ ├── when-with-no-expression.pug │ │ │ └── while-with-no-expression.pug │ │ └── index.test.js │ ├── pug-linker/ │ │ ├── HISTORY.md │ │ ├── LICENSE │ │ ├── README.md │ │ ├── index.js │ │ ├── package.json │ │ └── test/ │ │ ├── __snapshots__/ │ │ │ └── index.test.js.snap │ │ ├── cases/ │ │ │ ├── include-extends-from-root.input.json │ │ │ ├── include-extends-of-common-template.input.json │ │ │ ├── include-extends-relative.input.json │ │ │ ├── include-filter-stylus.input.json │ │ │ ├── include-filter.input.json │ │ │ ├── include-only-text-body.input.json │ │ │ ├── include-only-text.input.json │ │ │ ├── include-with-text-head.input.json │ │ │ ├── include-with-text.input.json │ │ │ ├── include.script.input.json │ │ │ ├── include.yield.nested.input.json │ │ │ ├── includes-with-ext-js.input.json │ │ │ ├── includes.input.json │ │ │ ├── layout.append.input.json │ │ │ ├── layout.append.without-block.input.json │ │ │ ├── layout.multi.append.prepend.block.input.json │ │ │ ├── layout.prepend.input.json │ │ │ └── layout.prepend.without-block.input.json │ │ ├── cases-src/ │ │ │ ├── auxiliary/ │ │ │ │ ├── 1794-extends.pug │ │ │ │ ├── 1794-include.pug │ │ │ │ ├── blocks-in-blocks-layout.pug │ │ │ │ ├── dialog.pug │ │ │ │ ├── empty-block.pug │ │ │ │ ├── escapes.html │ │ │ │ ├── extends-empty-block-1.pug │ │ │ │ ├── extends-empty-block-2.pug │ │ │ │ ├── extends-from-root.pug │ │ │ │ ├── extends-relative.pug │ │ │ │ ├── filter-in-include.pug │ │ │ │ ├── includable.js │ │ │ │ ├── include-from-root.pug │ │ │ │ ├── inheritance.extend.mixin.block.pug │ │ │ │ ├── inheritance.extend.recursive-grand-grandparent.pug │ │ │ │ ├── inheritance.extend.recursive-grandparent.pug │ │ │ │ ├── inheritance.extend.recursive-parent.pug │ │ │ │ ├── layout.include.pug │ │ │ │ ├── layout.pug │ │ │ │ ├── mixin-at-end-of-file.pug │ │ │ │ ├── mixins.pug │ │ │ │ ├── pet.pug │ │ │ │ ├── smile.html │ │ │ │ ├── window.pug │ │ │ │ └── yield-nested.pug │ │ │ ├── include-extends-from-root.pug │ │ │ ├── include-extends-of-common-template.pug │ │ │ ├── include-extends-relative.pug │ │ │ ├── include-filter-coffee.coffee │ │ │ ├── include-filter-stylus.pug │ │ │ ├── include-filter.pug │ │ │ ├── include-only-text-body.pug │ │ │ ├── include-only-text.pug │ │ │ ├── include-with-text-head.pug │ │ │ ├── include-with-text.pug │ │ │ ├── include.script.pug │ │ │ ├── include.yield.nested.pug │ │ │ ├── includes-with-ext-js.pug │ │ │ ├── includes.pug │ │ │ ├── javascript-new-lines.js │ │ │ ├── layout.append.pug │ │ │ ├── layout.append.without-block.pug │ │ │ ├── layout.multi.append.prepend.block.pug │ │ │ ├── layout.prepend.pug │ │ │ ├── layout.prepend.without-block.pug │ │ │ ├── some-included.styl │ │ │ ├── some.md │ │ │ └── some.styl │ │ ├── errors/ │ │ │ ├── child-with-tags.input.json │ │ │ ├── extends-not-first.input.json │ │ │ └── unexpected-block.input.json │ │ ├── errors-src/ │ │ │ ├── child-with-tags.pug │ │ │ ├── extends-not-first.pug │ │ │ └── unexpected-block.pug │ │ ├── fixtures/ │ │ │ ├── append/ │ │ │ │ ├── app-layout.pug │ │ │ │ ├── layout.pug │ │ │ │ ├── page.html │ │ │ │ └── page.pug │ │ │ ├── append-without-block/ │ │ │ │ ├── app-layout.pug │ │ │ │ ├── layout.pug │ │ │ │ └── page.pug │ │ │ ├── empty.pug │ │ │ ├── layout.pug │ │ │ ├── mixins.pug │ │ │ ├── multi-append-prepend-block/ │ │ │ │ ├── redefine.pug │ │ │ │ └── root.pug │ │ │ ├── prepend/ │ │ │ │ ├── app-layout.pug │ │ │ │ ├── layout.pug │ │ │ │ ├── page.html │ │ │ │ └── page.pug │ │ │ └── prepend-without-block/ │ │ │ ├── app-layout.pug │ │ │ ├── layout.pug │ │ │ ├── page.html │ │ │ └── page.pug │ │ ├── index.test.js │ │ ├── special-cases/ │ │ │ ├── extending-empty.input.json │ │ │ ├── extending-include.input.json │ │ │ └── root-mixin.input.json │ │ └── special-cases-src/ │ │ ├── extending-empty.pug │ │ ├── extending-include.pug │ │ └── root-mixin.pug │ ├── pug-load/ │ │ ├── HISTORY.md │ │ ├── LICENSE │ │ ├── README.md │ │ ├── index.js │ │ ├── package.json │ │ └── test/ │ │ ├── __snapshots__/ │ │ │ └── index.test.js.snap │ │ ├── bar.pug │ │ ├── bing.pug │ │ ├── foo.pug │ │ ├── index.test.js │ │ └── script.js │ ├── pug-parser/ │ │ ├── HISTORY.md │ │ ├── LICENSE │ │ ├── README.md │ │ ├── index.js │ │ ├── lib/ │ │ │ └── inline-tags.js │ │ ├── package.json │ │ └── test/ │ │ ├── __snapshots__/ │ │ │ ├── index.test.js.snap │ │ │ └── no-unnecessary-blocks.test.js.snap │ │ ├── cases/ │ │ │ ├── attr-es2015.tokens.json │ │ │ ├── attrs-data.tokens.json │ │ │ ├── attrs.js.tokens.json │ │ │ ├── attrs.tokens.json │ │ │ ├── attrs.unescaped.tokens.json │ │ │ ├── basic.tokens.json │ │ │ ├── blanks.tokens.json │ │ │ ├── block-code.tokens.json │ │ │ ├── block-expansion.shorthands.tokens.json │ │ │ ├── block-expansion.tokens.json │ │ │ ├── blockquote.tokens.json │ │ │ ├── blocks-in-blocks.tokens.json │ │ │ ├── blocks-in-if.tokens.json │ │ │ ├── case-blocks.tokens.json │ │ │ ├── case.tokens.json │ │ │ ├── classes-empty.tokens.json │ │ │ ├── classes.tokens.json │ │ │ ├── code.conditionals.tokens.json │ │ │ ├── code.escape.tokens.json │ │ │ ├── code.iteration.tokens.json │ │ │ ├── code.tokens.json │ │ │ ├── comments-in-case.tokens.json │ │ │ ├── comments.source.tokens.json │ │ │ ├── comments.tokens.json │ │ │ ├── doctype.custom.tokens.json │ │ │ ├── doctype.default.tokens.json │ │ │ ├── doctype.keyword.tokens.json │ │ │ ├── each.else.tokens.json │ │ │ ├── escape-chars.tokens.json │ │ │ ├── escape-test.tokens.json │ │ │ ├── escaping-class-attribute.tokens.json │ │ │ ├── filter-in-include.tokens.json │ │ │ ├── filters-empty.tokens.json │ │ │ ├── filters.coffeescript.tokens.json │ │ │ ├── filters.custom.tokens.json │ │ │ ├── filters.include.custom.tokens.json │ │ │ ├── filters.include.tokens.json │ │ │ ├── filters.inline.tokens.json │ │ │ ├── filters.less.tokens.json │ │ │ ├── filters.markdown.tokens.json │ │ │ ├── filters.nested.tokens.json │ │ │ ├── filters.stylus.tokens.json │ │ │ ├── filters.verbatim.tokens.json │ │ │ ├── html.tokens.json │ │ │ ├── html5.tokens.json │ │ │ ├── include-extends-from-root.tokens.json │ │ │ ├── include-extends-of-common-template.tokens.json │ │ │ ├── include-extends-relative.tokens.json │ │ │ ├── include-only-text-body.tokens.json │ │ │ ├── include-only-text.tokens.json │ │ │ ├── include-with-text-head.tokens.json │ │ │ ├── include-with-text.tokens.json │ │ │ ├── include.script.tokens.json │ │ │ ├── include.yield.nested.tokens.json │ │ │ ├── includes-with-ext-js.tokens.json │ │ │ ├── includes.tokens.json │ │ │ ├── inheritance.alert-dialog.tokens.json │ │ │ ├── inheritance.defaults.tokens.json │ │ │ ├── inheritance.extend.include.tokens.json │ │ │ ├── inheritance.extend.mixins.block.tokens.json │ │ │ ├── inheritance.extend.mixins.tokens.json │ │ │ ├── inheritance.extend.recursive.tokens.json │ │ │ ├── inheritance.extend.tokens.json │ │ │ ├── inheritance.extend.whitespace.tokens.json │ │ │ ├── inheritance.tokens.json │ │ │ ├── inline-block-comment.tokens.json │ │ │ ├── inline-tag.tokens.json │ │ │ ├── intepolated-elements.tokens.json │ │ │ ├── interpolated-mixin.tokens.json │ │ │ ├── interpolation.escape.tokens.json │ │ │ ├── layout.append.tokens.json │ │ │ ├── layout.append.without-block.tokens.json │ │ │ ├── layout.multi.append.prepend.block.tokens.json │ │ │ ├── layout.prepend.tokens.json │ │ │ ├── layout.prepend.without-block.tokens.json │ │ │ ├── mixin-at-end-of-file.tokens.json │ │ │ ├── mixin-block-with-space.tokens.json │ │ │ ├── mixin-hoist.tokens.json │ │ │ ├── mixin-via-include.tokens.json │ │ │ ├── mixin.attrs.tokens.json │ │ │ ├── mixin.block-tag-behaviour.tokens.json │ │ │ ├── mixin.blocks.tokens.json │ │ │ ├── mixin.merge.tokens.json │ │ │ ├── mixins-unused.tokens.json │ │ │ ├── mixins.rest-args.tokens.json │ │ │ ├── mixins.tokens.json │ │ │ ├── namespaces.tokens.json │ │ │ ├── nesting.tokens.json │ │ │ ├── pipeless-comments.tokens.json │ │ │ ├── pipeless-filters.tokens.json │ │ │ ├── pipeless-tag.tokens.json │ │ │ ├── pre.tokens.json │ │ │ ├── quotes.tokens.json │ │ │ ├── regression.1794.tokens.json │ │ │ ├── regression.784.tokens.json │ │ │ ├── script.whitespace.tokens.json │ │ │ ├── scripts.non-js.tokens.json │ │ │ ├── scripts.tokens.json │ │ │ ├── self-closing-html.tokens.json │ │ │ ├── single-period.tokens.json │ │ │ ├── source.tokens.json │ │ │ ├── styles.tokens.json │ │ │ ├── tag-blocks.tokens.json │ │ │ ├── tag.interpolation.tokens.json │ │ │ ├── tags.self-closing.tokens.json │ │ │ ├── template.tokens.json │ │ │ ├── text-block.tokens.json │ │ │ ├── text.tokens.json │ │ │ ├── utf8bom.tokens.json │ │ │ ├── vars.tokens.json │ │ │ ├── while.tokens.json │ │ │ ├── xml.tokens.json │ │ │ ├── yield-before-conditional-head.tokens.json │ │ │ ├── yield-before-conditional.tokens.json │ │ │ ├── yield-head.tokens.json │ │ │ ├── yield-title-head.tokens.json │ │ │ ├── yield-title.tokens.json │ │ │ └── yield.tokens.json │ │ ├── index.test.js │ │ └── no-unnecessary-blocks.test.js │ ├── pug-runtime/ │ │ ├── .gitignore │ │ ├── CHANGELOG.md │ │ ├── LICENSE │ │ ├── README.md │ │ ├── build.js │ │ ├── index.js │ │ ├── package.json │ │ ├── prepublish.js │ │ ├── test/ │ │ │ └── index.test.js │ │ └── wrap.js │ ├── pug-strip-comments/ │ │ ├── CHANGELOG.md │ │ ├── LICENSE │ │ ├── LICENSE.md │ │ ├── README.md │ │ ├── index.js │ │ ├── package.json │ │ └── test/ │ │ ├── __snapshots__/ │ │ │ └── index.test.js.snap │ │ ├── cases/ │ │ │ ├── comments-in-case.input.json │ │ │ ├── comments.input.json │ │ │ └── comments.source.input.json │ │ ├── errors/ │ │ │ ├── comment-in-comment.input.json │ │ │ ├── end.input.json │ │ │ └── startstart.input.json │ │ └── index.test.js │ └── pug-walk/ │ ├── .gitignore │ ├── .travis.yml │ ├── HISTORY.md │ ├── LICENSE │ ├── README.md │ ├── index.js │ ├── package.json │ └── test/ │ └── index.test.js ├── scripts/ │ ├── buffer-serializer.js │ ├── filename-serializer.js │ ├── prebuild.js │ └── prettier-javascript-serializer.js └── tsconfig.json ================================================ FILE CONTENTS ================================================ ================================================ FILE: .editorconfig ================================================ root = true [*] charset = utf-8 indent_style = space indent_size = 2 tab_width = 2 end_of_line = lf insert_final_newline = true trim_trailing_whitespace = true ================================================ FILE: .gitattributes ================================================ * text=auto eol=lf ================================================ FILE: .github/FUNDING.yml ================================================ # These are supported funding model platforms github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2] patreon: # Replace with a single Patreon username open_collective: pug ko_fi: # Replace with a single Ko-fi username tidelift: npm/pug community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry liberapay: # Replace with a single Liberapay username issuehunt: # Replace with a single IssueHunt username otechie: # Replace with a single Otechie username custom: # Replace with a single custom sponsorship URL ================================================ FILE: .github/ISSUE_TEMPLATE.md ================================================ **Pug Version:** your version number here **Node Version:** your version number here ## Input JavaScript Values ```js pug.renderFile('input.pug', { whatIsIt: 'language', }); ``` ## Input Pug ```pug h1 I Love Pug p It's a great #{whatIsIt} ``` ## Expected HTML ```html

I Love Pug

It's a great language

``` ## Actual HTML ```html

I Love Pug

It's a great language

``` ## Additional Comments ================================================ FILE: .github/workflows/rollingversions.yml ================================================ name: Release on: push: branches: - master repository_dispatch: types: [rollingversions_publish_approved] jobs: test: runs-on: ubuntu-latest strategy: matrix: node-version: [10.x, 12.x, 14.x] steps: - uses: actions/checkout@v2 - name: Use Node.js ${{ matrix.node-version }} uses: actions/setup-node@v1 with: node-version: ${{ matrix.node-version }} - run: yarn install --frozen-lockfile - run: yarn prettier:check - run: yarn test publish-canary: runs-on: ubuntu-latest if: ${{ github.event_name == 'push' }} needs: test steps: - uses: actions/checkout@v2 - uses: actions/setup-node@v1 with: node-version: 24.x registry-url: 'https://registry.npmjs.org' - run: yarn install --frozen-lockfile - run: yarn build - run: npx rollingversions publish --canary $GITHUB_RUN_NUMBER env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} publish: runs-on: ubuntu-latest if: ${{ github.event_name == 'repository_dispatch' }} needs: test steps: - uses: actions/checkout@v2 - uses: actions/setup-node@v1 with: node-version: 24.x registry-url: 'https://registry.npmjs.org' - run: yarn install --frozen-lockfile - run: yarn build - run: npx rollingversions publish env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} permissions: id-token: write contents: write ================================================ FILE: .github/workflows/test.yml ================================================ name: Test on: pull_request: branches: - master jobs: test: runs-on: ubuntu-latest strategy: matrix: node-version: [10.x, 12.x, 14.x] steps: - uses: actions/checkout@v2 - name: Use Node.js ${{ matrix.node-version }} uses: actions/setup-node@v1 with: node-version: ${{ matrix.node-version }} - run: yarn install --frozen-lockfile - run: yarn prettier:check - run: yarn test ================================================ FILE: .gitignore ================================================ .DS_Store .idea .vscode testing node_modules lib-cov coverage cov-pt* *.seed *.log *.csv *.dat *.out *.patch *.pid *.gz **/test/output* **/test/temp .release.json package-lock.json scripts/tsconfig.json packages/pug-error/lib ================================================ FILE: .prettierrc.js ================================================ module.exports = { bracketSpacing: false, singleQuote: true, trailingComma: 'all', overrides: [ { files: '*.js', options: { parser: 'babel', trailingComma: 'es5', }, }, ], }; ================================================ FILE: README.md ================================================ # Pug Full documentation is at [pugjs.org](https://pugjs.org/) Pug is a high-performance template engine heavily influenced by [Haml](http://haml.info/) and implemented with JavaScript for [Node.js](http://nodejs.org) and browsers. For bug reports, feature requests and questions, [open an issue](https://github.com/pugjs/pug/issues/new). For discussion join the [chat room](https://gitter.im/pugjs/pug). You can test drive Pug online [here](https://pugjs.org/). [Professionally supported pug is now available](https://tidelift.com/subscription/pkg/npm-pug?utm_source=npm-pug&utm_medium=referral&utm_campaign=readme) [![Build Status](https://img.shields.io/github/workflow/status/pugjs/pug/Test/master?style=for-the-badge)](https://github.com/pugjs/pug/actions?query=workflow%3ATest+branch%3Amaster) [![Rolling Versions](https://img.shields.io/badge/Rolling%20Versions-Enabled-brightgreen?style=for-the-badge)](https://rollingversions.com/pugjs/pug) [![NPM version](https://img.shields.io/npm/v/pug?style=for-the-badge)](https://www.npmjs.com/package/pug) [![Join Gitter Chat](https://img.shields.io/badge/gitter-join%20chat%20%E2%86%92-brightgreen.svg?style=for-the-badge)](https://gitter.im/pugjs/pug?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) ## Packages Package Name | Version -------------|-------- pug | [![NPM version](https://img.shields.io/npm/v/pug?style=for-the-badge)](https://www.npmjs.com/package/pug) pug-attrs | [![NPM version](https://img.shields.io/npm/v/pug-attrs?style=for-the-badge)](https://www.npmjs.com/package/pug-attrs) pug-code-gen | [![NPM version](https://img.shields.io/npm/v/pug-code-gen?style=for-the-badge)](https://www.npmjs.com/package/pug-code-gen) pug-error | [![NPM version](https://img.shields.io/npm/v/pug-error?style=for-the-badge)](https://www.npmjs.com/package/pug-error) pug-filters | [![NPM version](https://img.shields.io/npm/v/pug-filters?style=for-the-badge)](https://www.npmjs.com/package/pug-filters) pug-lexer | [![NPM version](https://img.shields.io/npm/v/pug-lexer?style=for-the-badge)](https://www.npmjs.com/package/pug-lexer) pug-linker | [![NPM version](https://img.shields.io/npm/v/pug-linker?style=for-the-badge)](https://www.npmjs.com/package/pug-linker) pug-load | [![NPM version](https://img.shields.io/npm/v/pug-load?style=for-the-badge)](https://www.npmjs.com/package/pug-load) pug-parser | [![NPM version](https://img.shields.io/npm/v/pug-parser?style=for-the-badge)](https://www.npmjs.com/package/pug-parser) pug-runtime | [![NPM version](https://img.shields.io/npm/v/pug-runtime?style=for-the-badge)](https://www.npmjs.com/package/pug-runtime) pug-strip-comments | [![NPM version](https://img.shields.io/npm/v/pug-strip-comments?style=for-the-badge)](https://www.npmjs.com/package/pug-strip-comments) pug-walk | [![NPM version](https://img.shields.io/npm/v/pug-walk?style=for-the-badge)](https://www.npmjs.com/package/pug-walk) ## Rename from "Jade" This project was formerly known as "Jade". However, it was revealed to us that "Jade" is a registered trademark; as a result, a rename was needed. After some discussion among the maintainers, **"Pug"** was chosen as the new name for this project. As of version 2, "pug" is the official package name. If your package or app currently uses `jade`, don't worry: we have secured permissions to continue to occupy that package name, although all new versions will be released under `pug`. Before the renaming, work had already begun on “Jade 2.0.0”. Therefore, the rename to Pug coincided with the major version bump. As a result, upgrading from Jade to Pug will be the same process as upgrading any other package with a major version bump. The syntax of Pug has several differences, deprecations, and removals compared to its predecessor. These differences are documented in [#2305](https://github.com/pugjs/pug/issues/2305). The website and documentation for Pug are still being updated. But if you are new to Pug, you should get started with the new syntax and install the Pug package from npm. ## Installation ### Package To use Pug in your own JavaScript projects: ```bash $ npm install pug ``` ### Command Line After installing the latest version of [Node.js](http://nodejs.org), install with: ```bash $ npm install pug-cli -g ``` and run with ```bash $ pug --help ``` ## Syntax Pug is a clean, whitespace sensitive syntax for writing HTML. Here is a simple example: ```pug doctype html html(lang="en") head title= pageTitle script(type='text/javascript'). if (foo) bar(1 + 5); body h1 Pug - node template engine #container.col if youAreUsingPug p You are amazing else p Get on it! p. Pug is a terse and simple templating language with a strong focus on performance and powerful features. ``` Pug transforms the above to: ```html Pug

Pug - node template engine

You are amazing

Pug is a terse and simple templating language with a strong focus on performance and powerful features.

``` ## API For full API, see [pugjs.org/api/reference.html](https://pugjs.org/api/reference.html) ```js var pug = require('pug'); // compile var fn = pug.compile('string of pug', options); var html = fn(locals); // render var html = pug.render('string of pug', merge(options, locals)); // renderFile var html = pug.renderFile('filename.pug', merge(options, locals)); ``` ### Options - `filename` Used in exceptions, and required when using includes - `compileDebug` When `false` no debug instrumentation is compiled - `pretty` Add pretty-indentation whitespace to output _(`false` by default)_ ## Browser Support The latest version of pug can be [downloaded for the browser in standalone form](https://pugjs.org/js/pug.js). It only supports the very latest browsers, though, and is a large file. It is recommended that you pre-compile your pug templates to JavaScript. To compile a template for use on the client using the command line, do: ```bash $ pug --client --no-debug filename.pug ``` which will produce `filename.js` containing the compiled template. ## Tutorials - cssdeck interactive [Pug syntax tutorial](http://cssdeck.com/labs/learning-the-jade-templating-engine-syntax) - cssdeck interactive [Pug logic tutorial](http://cssdeck.com/labs/jade-templating-tutorial-codecast-part-2) - [Pug について。](https://gist.github.com/japboy/5402844) (A Japanese Tutorial) ## Implementations in other languages ### Ports in other languages Ports to other languages, with very close syntax: - [PHP](https://github.com/pug-php/pug) - [Java](https://github.com/neuland/jade4j) - [Python](https://github.com/kakulukia/pypugjs) - [Ruby](https://github.com/yivo/pug-ruby) - [C# (ASP.NET Core)](https://github.com/AspNetMonsters/pugzor) - [RPG/ILE](https://github.com/WorksOfLiam/apug) ### Equivalents in other languages Templates engines for other languages with a different syntax, but a similar philosophy: - [Scaml for Scala](https://scalate.github.io/scalate/documentation/scaml-reference.html) - [Slim for Ruby](https://github.com/slim-template/slim) (should not be confused with Slim PHP framework) - [HAML for Ruby](http://haml.info) ### Framework implementations/adapters Embedded view engines for frameworks: - [Laravel](https://github.com/BKWLD/laravel-pug) - [Symfony](https://github.com/pug-php/pug-symfony) - [Phalcon](https://github.com/pug-php/pug-phalcon) - [CodeIgniter](https://github.com/pug-php/ci-pug-engine) - [Yii 2](https://github.com/pug-php/pug-yii2) - [Slim 3](https://github.com/pug-php/pug-slim) - [Silex (implementation example)](https://gist.github.com/kylekatarnls/ba13e4361ab14f4ff5d2a5775eb0cc10) - [Lumen](https://github.com/BKWLD/laravel-pug#use-in-lumen) - [Rails](https://github.com/yivo/pug-rails) ### CMS plugins - [WordPress](https://github.com/welaika/wordless) ## Additional Resources - [Emacs Mode](https://github.com/brianc/jade-mode) - [Vim Syntax](https://github.com/digitaltoad/vim-pug) - [TextMate Bundle](http://github.com/miksago/jade-tmbundle) - [Coda/SubEtha syntax Mode](https://github.com/aaronmccall/jade.mode) - [html2pug](https://github.com/donpark/html2jade) converter - [pug2php](https://github.com/SE7ENSKY/jade2php) converter - [Pug Server](https://github.com/ctrlaltdev/pug-server) Ideal for building local prototypes apart from any application - [cache-pug-templates](https://github.com/ladjs/cache-pug-templates) Cache Pug templates for [Lad](https://github.com/ladjs/lad)/[Koa](https://github.com/koajs/koa)/[Express](https://github.com/expressjs/express)/[Connect](https://github.com/senchalabs/connect) with [Redis](https://redis.io) - [Prettier Plugin](https://github.com/prettier/plugin-pug) ## Backers Support us with a monthly donation and help us continue our activities. [[Become a backer](https://opencollective.com/pug#backer)] ## Sponsors Become a sponsor and get your logo on our README on GitHub with a link to your site. [[Become a sponsor](https://opencollective.com/pug#sponsor)] ## License MIT ================================================ FILE: SECURITY.md ================================================ # Security Policy ## Supported Versions | Version | Supported | | -------- | ------------------ | | ^3.0.1 | :white_check_mark: | | <3.0.1 | :x: | ## Reporting a Vulnerability To report a security vulnerability, please use the [Tidelift security contact](https://tidelift.com/security). Tidelift will coordinate the fix and disclosure. ================================================ FILE: package.json ================================================ { "name": "pug-monorepo", "private": true, "@rollingversions/ignore": true, "workspaces": [ "packages/*" ], "devDependencies": { "coveralls": "3.0.9", "jest": "^26.0.1", "prettier": "1.19.1", "typescript": "^4.1.2", "wsrun": "^5.2.0" }, "repository": { "type": "git", "url": "https://github.com/pugjs/pug.git" }, "scripts": { "prettier:check": "prettier --ignore-path .gitignore --list-different './**/*.js'", "format": "prettier --ignore-path .gitignore --write './**/*.js'", "build": "node scripts/prebuild && wsrun --stages --exclude-missing --fast-exit --collect-logs build && tsc --build scripts", "pretest": "yarn build", "test": "jest", "coverage": "jest --coverage", "coveralls": "jest --coverage --coverageReporters=text-lcov | coveralls", "watch": "jest --watch" }, "jest": { "testEnvironment": "node", "snapshotSerializers": [ "./scripts/filename-serializer.js", "./scripts/prettier-javascript-serializer.js", "./scripts/buffer-serializer.js" ] }, "license": "MIT" } ================================================ FILE: packages/pug/History.md ================================================ 1.11.0 / 2015-06-12 ================== * Added block code support ([@alephyud](https://github.com/alephyud)) * Improved runtime performance of mixins significantly ([Andreas Lubbe](https://github.com/alubbe)) * Improved runtime performance of pug's string escaping ([Andreas Lubbe](https://github.com/alubbe)) and ([@ForbesLindesay](http://www.forbeslindesay.co.uk/)) * Better line number counting for pipeless text ([@alephyud](https://github.com/alephyud)) 1.10.0 / 2015-05-25 ================== * Now supports jstransformers, which allows improved handling of embedded languages such as Coffee-Script, and deprecated Transformers support in filters - to be removed in 2.0.0 ([@ForbesLindesay](http://www.forbeslindesay.co.uk/)) * CLI: added a flag to keep directory hierarchy when a directory is specified - this behavior will be the default in 2.0.0 ([@TimothyGu](https://github.com/TimothyGu)) * disabled 'compileDebug' flag by default when used with express in production mode ([Andreas Lubbe](https://github.com/alubbe)) * Fixed a memory leak on modern versions of Chrome as well as node 0.12 and iojs ([Andreas Lubbe](https://github.com/alubbe)) * update website ([@GarthDB](https://github.com/GarthDB)) 1.9.2 / 2015-01-18 ================== * Do not ignore some parser errors for mismatched parenthesis ([@TimothyGu](https://github.com/TimothyGu)) * Warn for `:` that is not followed by a space ([@ForbesLindesay](http://www.forbeslindesay.co.uk/)) * Fix #1794 (a bizzare bug with a certain combination of inheritance, mixins and &attributes) ([@ForbesLindesay](http://www.forbeslindesay.co.uk/)) * Add `compileClientWithDependenciesTracked` ([@ForbesLindesay](http://www.forbeslindesay.co.uk/)) * Support comments in `case` blocks ([@ForbesLindesay](http://www.forbeslindesay.co.uk/)) * Fix blocks in nested mixins ([@ForbesLindesay](http://www.forbeslindesay.co.uk/)) * Lots more documentation ([@enlore](https://github.com/enlore)) * Fix watching in CLI ([@pavel](https://github.com/pavel)) 1.9.1 / 2015-01-17 ================== * Clean up path/fs functions in CLI as we no longer support node@0.6 ([@TimothyGu](https://github.com/TimothyGu)) * Update commander ([@TimothyGu](https://github.com/TimothyGu)) * Document `cache` and `parser` options ([@TimothyGu](https://github.com/TimothyGu)) * Fix bug in 1.9.0 where we read the file if cache was enabled, even if a string was provided ([@TimothyGu](https://github.com/TimothyGu)) * Fix year in changelog ([@tomByrer](https://github.com/tomByrer)) 1.9.0 / 2015-01-13 ================== * Fix `--watch` sometimes dying when there were file-system errors ([@ForbesLindesay](http://www.forbeslindesay.co.uk/)) * Fix `--watch` by using `fs.watchFile` correctly ([@TimothyGu](https://github.com/TimothyGu)) * Fix errors with using the CLI to compile from stdin * Better looking badges ([@TimothyGu](https://github.com/TimothyGu)) * Added `--extension` to CLI([@nicocedron](https://github.com/nicocedron) and [@TimothyGu](https://github.com/TimothyGu)) * Refactor and improve internal cache handling ([@TimothyGu](https://github.com/TimothyGu)) * Loads more tests ([@TimothyGu](https://github.com/TimothyGu)) 1.8.2 / 2014-12-16 ================== * Use `-` as the default filename when using stdin on CLI ([@TimothyGu](https://github.com/TimothyGu)) * Prevent some compiler errors being silenced ([@ForbesLindesay](http://www.forbeslindesay.co.uk/)) * Remove use of non-standard `string.trimLeft()` ([@ForbesLindesay](http://www.forbeslindesay.co.uk/)) * Fix bug in CLI when no name was provided for child template ([@ForbesLindesay](http://www.forbeslindesay.co.uk/)) * Remove dependency on monocle (hopefully fixing installation on 0.8) ([@ForbesLindesay](http://www.forbeslindesay.co.uk/)) * Add gitter chat room ([@ForbesLindesay](http://www.forbeslindesay.co.uk/)) 1.8.1 / 2014-11-30 ================== * Fix corner case when the pretty option was passed a non-string truthy value ([@TimothyGu](https://github.com/TimothyGu)) * Warn when `lexer` is given as an option ([@TimothyGu](https://github.com/TimothyGu)) * Update dependencies ([@TimothyGu](https://github.com/TimothyGu)) 1.8.0 / 2014-11-28 ================== * Fix empty text-only block ([@rlidwka](https://github.com/rlidwka)) * Warn about future change to ISO 8601 style dates ([@TimothyGu](https://github.com/TimothyGu) and [@ForbesLindesay](http://www.forbeslindesay.co.uk/)) * Add warnings when data-attributes contain ampersands ([@TimothyGu](https://github.com/TimothyGu)) * Allow custom pretty indentation ([@bfred-it](https://github.com/bfred-it)) * Add support for an object in the style attribute ([@ForbesLindesay](http://www.forbeslindesay.co.uk/)) * Add support for an object in the class attribute ([@ForbesLindesay](http://www.forbeslindesay.co.uk/)) * Ignore fs module in browser builds ([@sokra](https://github.com/sokra)) * Update dependencies ([@hildjj](https://github.com/hildjj)) * Check mixin arguments are valid JavaScript expressions ([@ForbesLindesay](http://www.forbeslindesay.co.uk/)) * Remove symlink ([@slang800](https://github.com/slang800)) 1.7.0 / 2014-09-17 ================== * Add Doctype option on command line ([@ForbesLindesay](http://www.forbeslindesay.co.uk/)) * Support ES6 style rest args in mixins ([@ForbesLindesay](http://www.forbeslindesay.co.uk/)) * Fix support for unicode newlines (\u2028, \u2029) ([@rlidwka](https://github.com/rlidwka)) * Expose `globals` option from the `with` module ([@sokra](https://github.com/sokra)) * Lots of new documentation ([@ForbesLindesay](http://www.forbeslindesay.co.uk/)) 1.6.0 / 2014-08-31 ================== * Allow optional white space after `+` when calling a mixin ([@char101](https://github.com/char101)) * Use void-elements module to replace internal self-closing list ([@hemanth](https://github.com/hemanth)) * Fix a warning that eroniously warned for un-used blocks if in an extending template from an include (Reported by [@Dissimulazione](https://github.com/Dissimulazione)) * Fix mixins not working at end of file ([@ForbesLindesay](http://www.forbeslindesay.co.uk/)) * Fix error reporting when mixin block was followed by blank lines ([@ForbesLindesay](http://www.forbeslindesay.co.uk/)) 1.5.0 / 2014-07-23 ================== * Added compileFile API ([@ForbesLindesay](http://www.forbeslindesay.co.uk/)) * Fix line number in un-used blocks warning ([@ForbesLindesay](http://www.forbeslindesay.co.uk/)) * Fix a warning that eroniously warned for un-used blocks if they were under another block (Reported by [@pesho](https://github.com/pesho)) 1.4.2 / 2014-07-16 ================== * Fix a warning that eroniously warned for un-used blocks if they were under a "Code" element (Reported by [@narirou](https://github.com/narirou)) 1.4.1 / 2014-07-16 ================== * Fix an error that sometimes resulted in 'unexpected token "pipless-text"' being erroniously thrown (Reported by [@Artazor](https://github.com/Artazor) and [@thenitai](https://github.com/thenitai)) 1.4.0 / 2014-07-15 ================== * Fix CLI so it keeps watching when errors occur ([@AndrewTsao](https://github.com/AndrewTsao)) * Support custom names for client side templates ([@ForbesLindesay](http://www.forbeslindesay.co.uk/) and [@dscape](https://github.com/dscape)) * Allow whitepsace other than "space" before attributes passed to mixins (N.B. there is a small chance this could be a breaking change for you) ([@regular](https://github.com/regular)) * Track dependencies so file watchers can be more clever ([@ForbesLindesay](http://www.forbeslindesay.co.uk/) and [@sdether](https://github.com/sdether)) * Allow passing options to filtered includes ([@ForbesLindesay](http://www.forbeslindesay.co.uk/)) * Fix bugs with indentation in filters ([@ForbesLindesay](http://www.forbeslindesay.co.uk/) and [@lackac](https://github.com/lackac)) * Warn on block names that are never used ([@ForbesLindesay](http://www.forbeslindesay.co.uk/)) 1.3.1 / 2014-04-04 ================== * Fix error with tags in xml that are self-closing in html ([@ForbesLindesay](http://www.forbeslindesay.co.uk/)) * Fix error message for inline tags with content ([@hiddentao](https://github.com/hiddentao)) 1.3.0 / 2014-03-02 ================== * Fix a bug where sometimes mixins were removed by an optimisation even though they were being called ([@ForbesLindesay](http://www.forbeslindesay.co.uk/), reported by [@leider](https://github.com/leider)) * Updated with to support automatically detecting when a value is "global" and removed redundant `options.globals` option ([@ForbesLindesay](http://www.forbeslindesay.co.uk/)) * Improve warnings for tags with multiple attributes ([@ForbesLindesay](http://www.forbeslindesay.co.uk/)) * Deprecate (with a warning) `node.clone`, `block.replace`, `attrs.removeAttribute`, `attrs.getAttribute` - these are all internal APIs for the AST ([@ForbesLindesay](http://www.forbeslindesay.co.uk/)) 1.2.0 / 2014-02-26 ================== * Use variables instead of properties of pug, improving performance and reliability with nested templates ([@ForbesLindesay](http://www.forbeslindesay.co.uk/)) * Support compiling templates from stdin via a user typing ([@yorkie](https://github.com/yorkie)) * Lazily add mixins ([@ForbesLindesay](http://www.forbeslindesay.co.uk/)) * Fix case fall-through ([@ForbesLindesay](http://www.forbeslindesay.co.uk/)) * Earlier errors for `when` without `case` and `else` without `if` ([@ForbesLindesay](http://www.forbeslindesay.co.uk/)) * Allow `if`/`else` etc. to not have a block. * Remove lib-cov legacy to make browserify work better ([@silver83](https://github.com/silver83)) * Add and improve test coverage using istanbul ([@ForbesLindesay](http://www.forbeslindesay.co.uk/)) 1.1.5 / 2014-01-19 ================== * Add filename to and fix line numbers for missing space before text warning (@ijin82) * Fix filenames for some error reporting in extends/includes (@doublerebel) * Fix a corner case where a mixin was called with `&attributes` but no other attributes and a block that was supposed to be fixed in 1.1.4 ([@ForbesLindesay](http://www.forbeslindesay.co.uk/)) 1.1.4 / 2014-01-09 ================== * Fix a corner case where a mixin was called with `&attributes` but no other attributes and a block ([@ForbesLindesay](http://www.forbeslindesay.co.uk/)) 1.1.3 / 2014-01-09 ================== * Fix failure of npm prepublish not running 1.1.2 / 2014-01-09 ================== * Fix same interaction of `&attributes` with `false` `null` or `undefined` but combined with dynamic attributes ([@ForbesLindesay](http://www.forbeslindesay.co.uk/)) 1.1.1 / 2014-01-09 ================== * Fix a bug when `&attributes` is combined with static attributes that evaluate to `false` or `null` or `undefined` ([@ForbesLindesay](http://www.forbeslindesay.co.uk/)) 1.1.0 / 2014-01-07 ================== * Fix class merging to work as documented ([@ForbesLindesay](http://www.forbeslindesay.co.uk/)) * Throw an error when the same attribute is duplicated multiple times ([@ForbesLindesay](http://www.forbeslindesay.co.uk/)) * Move more errors into the parser/lexer so they have more info about line numbers ([@ForbesLindesay](http://www.forbeslindesay.co.uk/)) * Support mixin blocks at the end of files ([@ForbesLindesay](http://www.forbeslindesay.co.uk/)) 1.0.2 / 2013-12-31 ================== * Fix a bug when `&attributes` is combined with dynamic attributes ([@ForbesLindesay](http://www.forbeslindesay.co.uk/)) 1.0.1 / 2013-12-29 ================== * Allow self closing tags to contian whitespace ([@ForbesLindesay](http://www.forbeslindesay.co.uk/)) * Allow tags to have a single white space after them ([@ForbesLindesay](http://www.forbeslindesay.co.uk/)) * Support text bodies of tags that begin with `//` rather than treating them as comments ([@ForbesLindesay](http://www.forbeslindesay.co.uk/)) 1.0.0 / 2013-12-22 ================== * No longer support node@0.8 ([@ForbesLindesay](http://www.forbeslindesay.co.uk/)) * Fix error reporting in layouts & includes ([@ForbesLindesay](http://www.forbeslindesay.co.uk/)) * Allow a list of 'globals' to be passed as an array at compile time & don't automatically expose all globals ([@ForbesLindesay](http://www.forbeslindesay.co.uk/)) * Escape apostrophes in data attributes (@qualiabyte) * Fix mixin/block interaction ([@ForbesLindesay](http://www.forbeslindesay.co.uk/) & [@paulyoung](https://github.com/paulyoung)) * Ignore trailing space after mixin declaration ([@ForbesLindesay](http://www.forbeslindesay.co.uk/)) * Make literal `.` work as expected ([@ForbesLindesay](http://www.forbeslindesay.co.uk/)) * Remove implicit text only for script/style ([@ForbesLindesay](http://www.forbeslindesay.co.uk/)) * Stop parsing comments and remove support for conditional comments ([@ForbesLindesay](http://www.forbeslindesay.co.uk/)) * Make filtering includes explicit ([@ForbesLindesay](http://www.forbeslindesay.co.uk/)) * Remove special assignment syntax ([@ForbesLindesay](http://www.forbeslindesay.co.uk/)) * Remove `!!!` shortcut for `doctype` ([@ForbesLindesay](http://www.forbeslindesay.co.uk/)) * Remove `5` shorcut for `html` doctype ([@ForbesLindesay](http://www.forbeslindesay.co.uk/)) * Remove `colons` option from the distant past ([@ForbesLindesay](http://www.forbeslindesay.co.uk/)) * Add a sepatate `compileClient` and `compileFileClient` to replace the `client` option ([@ForbesLindesay](http://www.forbeslindesay.co.uk/)) * Remove polyfills for supporting old browsers ([@ForbesLindesay](http://www.forbeslindesay.co.uk/)) * Allow interpolation for mixin names ([@jeromew](https://github.com/jeromew) * Use `node.type` instead of `node.constructor.name` so it can be minified ([@ForbesLindesay](http://www.forbeslindesay.co.uk/)) * Allow hyphens in filter names ([@ForbesLindesay](http://www.forbeslindesay.co.uk/)) * Throw an error if a self closing tag has content ([@ForbesLindesay](http://www.forbeslindesay.co.uk/)) * Support inline tags ([@ForbesLindesay](http://www.forbeslindesay.co.uk/)) * Replace `attributes` magic attribute with `&attributes(attributes)` ([@ForbesLindesay](http://www.forbeslindesay.co.uk/)) * Remove automatic tag wrapping for filters, you can just put the tags in yourself now ([@ForbesLindesay](http://www.forbeslindesay.co.uk/)) * Remove whitespace from tags nested inside pre tags ([@markdalgleish](http://markdalgleish.com)) 0.35.0 / 2013-08-21 =================== * Add support for space separated attributes (thanks to [@ForbesLindesay](http://www.forbeslindesay.co.uk/)) * Add earlier errors for invalid JavaScript expressions (thanks to [@ForbesLindesay](http://www.forbeslindesay.co.uk/)) * Fix parsing files with UTF8 BOMs when they are includes or parent/layout templates (thanks to [@kiinoo](https://github.com/kiinoo)) 0.34.1 / 2013-07-26 =================== * fix render file not working when called with callback (reported by [@xieren58](https://github.com/xieren58)) 0.34.0 / 2013-07-26 =================== * callbacks only called once for async methods even if they throw (reported by [@davidcornu](https://github.com/davidcornu)) * HTML comments are pretty printed better (thanks to [@eddiemonge](https://github.com/eddiemonge)) * callbacks are optional and leaving them out results in synchronous operation (thanks to [@ForbesLindesay](http://www.forbeslindesay.co.uk/)) * empty filter nodes are now permitted (thanks to [@coderanger](https://github.com/coderanger)) * overhaul website and documentation (thanks to [@ForbesLindesay](http://www.forbeslindesay.co.uk/)), much more of this to come. 0.33.0 / 2013-07-12 =================== * Hugely more powerful error reporting (especially with `compileDebug` set explicitly to `true`) * Add a warning for tags with multiple attributes * be strict about requiring newlines after tags to fix some odd corner cases * fix escaping of class to allow it to be unescaped (thanks to [@christiangenco](https://github.com/christiangenco)) 0.32.0 / 2013-06-28 =================== * remove `pug.version` and fix `pug --version` * add file name and line number to deprecation warnings * use constantinople for better constant detection * update `with` for a massive performance upgrade at compile time 0.31.2 / 2013-06-07 =================== * fix overzealous deprecation warnings 0.31.1 / 2013-05-31 =================== * fix line endings for executable command * fix `locals` variable being undefined * fix an obscure bug that could occur if multiple mixins interact badly (see [substack/lexical-scope#13](https://github.com/substack/lexical-scope/issues/13)) 0.31.0 / 2013-05-30 ================== * deprecate implicit text-only `script` and `style` tags * make `with` at compile time using `lexical-scope` * add `options.parser` that behaves exactly like `options.compiler` * add "component.json" for component (runtime) support * removed `hasOwnProperty` check in each loops * removed .min files from the repository (people can just generate these themselves) * use browserify to compile client side libraries * fix buggy block extending should now be fixed * fix preserve case of custom doctypes * fix regexps in attributes sometimes not being accepted * fix allow `$` sign in each loop variable names * fix mixins with buffered code on the same line * fix separate class names by ` ` rather than `,` (was sometimes incorrect) 0.30.0 / 2013-04-25 ================== * add support for 'include' and 'extends' to use paths relative to basedir * fix accidental calling of functions in iteration block. Closes #986 * fix: skip rethrow on client * fix each/else prefixed with `-` * fix multi-block prepend/append * swap -o and -O, set -o to --out 0.29.0 / 2013-04-16 ================== * add "monocle" for watcher that actually works... * fix interpolation in blocks of text * fix attribute interpolation * move filters to an external library * fix JavaScript escaping corner cases 0.28.2 / 2013-03-04 ================== * wtf coffeescript is not a dep 0.28.1 / 2013-01-10 ================== * add passing of filename to include filters * fix wrong new lines for include filters 0.28.0 / 2013-01-08 ================== * add .css and .js "filters". re #438 * add include filters. Closes #283 * fix "class:" within attribute escaping * removing ast filters * things I can't read: * 反馈地址 * 样式 * 联系 * 初稿,翻译完 * 接受大鸟的建议 * 头晕,翻译一点点 * 到过滤器翻译完毕 * 翻译一部分 * 中文翻译单独放 * 特性部分 * 再翻 * 翻译一点点 0.27.7 / 2012-11-05 ================== * fix each/else clause for enumerated objects * fix #764 (incorrect line number for error messages) * fix double-escaping of interpolated js slashes. Closes #784 0.27.6 / 2012-10-05 ================== * Included templates can not override blocks of their parent. Closes #699 0.27.5 / 2012-09-24 ================== * fix attr interpolation escaping. Closes #771 0.27.4 / 2012-09-18 ================== * fix include yields. Closes #770 0.27.3 / 2012-09-18 ================== * fix escaping of interpolation. Closes #769 * loosen "mkdirp" version restriction [TooTallNate] 0.27.2 / 2012-08-07 ================== * Revert "fixing string interpolation escaping #731", problems reported 0.27.1 / 2012-08-06 ================== * fix attribute interpolation escaping #731 * fix string interpolation escaping #731 0.27.0 / 2012-07-26 ================== * added ability to pass in json file to `--obj` * add preliminary `each` `else` support. Closes #716 * fix doctype bug overlooked in #712 * fix stripping of utf-8 BOMs 0.26.3 / 2012-06-25 ================== * Update version of commander that supports node v0.8. 0.26.2 / 2012-06-22 ================== * Added --options alias of --obj * Added reserved word conflict prevention in Google's Closure Compiler * Added tag interpolation. Closes #657 * Allow the compiled client to use it's own pug util functions [3rd-Eden] * Fixed `attrs()` escape bug [caseywebdev] 0.26.1 / 2012-05-27 ================== * Changed default doctype to __html5__ * Performance: statically compile attrs when possible [chowey] * Fixed some class attribute merging cases * Fixed so `block` doesn't consume `blockquotes` tag [chowey] * Fixed backslashes in text nodes [chowey] * Fixed / in text. Closes #638 0.26.0 / 2012-05-04 ================== * Added package.json __component__ support * Added explicit self-closing tag support. Closes #605 * Added `block` statement * Added mixin tag-like behaviour [chowey] * Fixed mixins with extends [chowey] 0.25.0 / 2012-04-18 ================== * Added preliminary mixin block support. Closes #310 * Fixed whitespace handling in various situations [chowey] * Fixed indentation in various situations [chowey] 0.24.0 / 2012-04-12 ================== * Fixed unescaped attribute compilation * Fixed pretty-printing of text-only tags (__Warning__: this may affect rendering) [chowey] 0.23.0 / 2012-04-11 ================== * Added data-attr json stringification support. Closes #572 * Added unescaped attr support. Closes #198 * Fixed #1070, reverted mixin function statements * Fixed pug.1 typo 0.22.1 / 2012-04-04 ================== * Fixed source tags. now self-closing. Closes #308 * Fixed: escape backslashes in coffeescript filter 0.22.0 / 2012-03-22 ================== * Added pug manpage (`man pug` after installation for docs) * Added `-D, --no-debug` to pug(1) * Added `-p, --pretty` to pug(1) * Added `-c, --client` option to pug(1) * Fixed `-o { client: true }` with stdin * Fixed: skip blank lines in lexer (unless within pipeless text). Closes #399 0.21.0 / 2012-03-10 ================== * Added new input/output test suite using Mocha's string diffing * Added alias `extend` -> `extends`. Closes #527 [guillermo] * Fixed include escapes. Closes #513 * Fixed block-expansion with .foo and #foo short-hands. Closes #498 0.20.3 / 2012-02-16 ================== * Changed: pass `.filename` to filters only 0.20.2 / 2012-02-16 ================== * Fixed `:stylus` import capabilities, pass .filename 0.20.1 / 2012-02-02 ================== * Fixed Block#includeBlock() with textOnly blocks 0.20.0 / 2011-12-28 ================== * Added a browser example * Added `yield` for block `include`s * Changed: replaced internal `__` var with `__pug` [chrisleishman] * Fixed two globals. Closes #433 0.19.0 / 2011-12-02 ================== * Added block `append` / `prepend` support. Closes #355 * Added link in readme to pug-mode for Emacs * Added link to python implementation 0.18.0 / 2011-11-21 ================== * Changed: only ['script', 'style'] are text-only. Closes #398' 0.17.0 / 2011-11-10 ================== * pug.renderFile() is back! (for express 3.x) * Fixed `Object.keys()` failover bug 0.16.4 / 2011-10-24 ================== * Fixed a test due to reserved keyword * Fixed: commander 0.1.x dep for 0.5.x 0.16.3 / 2011-10-24 ================== * Added: allow leading space for conditional comments * Added quick implementation of a switch statement * Fixed parens in mixin args. Closes #380 * Fixed: include files with a .pug extension as pug files 0.16.2 / 2011-09-30 ================== * Fixed include regression. Closes #354 0.16.1 / 2011-09-29 ================== * Fixed unexpected `else` bug when compileDebug: false * Fixed attr state issue for balancing pairs. Closes #353 0.16.0 / 2011-09-26 ================== * Added `include` block support. Closes #303 * Added template inheritance via `block` and `extends`. Closes #242 * Added 'type="text/css"' to the style tags generated by filters. * Added 'uglifyjs' as an explicit devDependency. * Added -p, --path flag to pug(1) * Added support for any arbitrary doctype * Added `pug.render(str[,options], fn)` back * Added first-class `while` support * Added first-class assignment support * Fixed runtime.js `Array.isArray()` polyfill. Closes #345 * Fixed: set .filename option in pug(1) when passing filenames * Fixed `Object.keys()` polyfill typo. Closes #331 * Fixed `include` error context * Renamed magic "index" to "$index". Closes #350 0.15.4 / 2011-09-05 ================== * Fixed script template html. Closes #316 * Revert "Fixed script() tag with trailing ".". Closes #314" 0.15.3 / 2011-08-30 ================== * Added Makefile example. Closes #312 * Fixed script() tag with trailing ".". Closes #314 0.15.2 / 2011-08-26 ================== * Fixed new conditional boundaries. Closes #307 0.15.1 / 2011-08-26 ================== * Fixed pug(1) support due to `res.render()` removal * Removed --watch support (use a makefile + watch...) 0.15.0 / 2011-08-26 ================== * Added `client` option to reference runtime helpers * Added `Array.isArray()` for runtime.js as well * Added `Object.keys()` for the client-side runtime * Added first-class `if`, `unless`, `else` and `else if` support * Added first-class `each` / `for` support * Added `make benchmark` for continuous-bench * Removed `inline` option, SS helpers are no longer inlined either * Removed `Parser#debug()` * Removed `pug.render()` and `pug.renderFile()` * Fixed runtime.js `escape()` bug causing window.escape to be used * Fixed a bunch of tests 0.14.2 / 2011-08-16 ================== * Added `include` support for non-pug files * Fixed code indentation when followed by newline(s). Closes #295 [reported by masylum] 0.14.1 / 2011-08-14 ================== * Added `colons` option for everyone stuck with ":". Closes #231 * Optimization: consecutive lines are merged in compiled js 0.14.0 / 2011-08-08 ================== * Added array iteration with index example. Closes #276 * Added _runtime.js_ * Added `compileDebug` option to enable lineno instrumentation * Added `inline` option to disable inlining of helpers (for client-side) 0.13.0 / 2011-07-13 ================== * Added `mixin` support * Added `include` support * Added array support for the class attribute 0.12.4 / 2011-06-23 ================== * Fixed filter indentation bug. Closes #243 0.12.3 / 2011-06-21 ================== * Fixed empty strings support. Closes #223 * Fixed conditional comments documentation. Closes #245 0.12.2 / 2011-06-16 ================== * Fixed `make test` * Fixed block comments 0.12.1 / 2011-06-04 ================== * Fixed attribute interpolation with double quotes. Fixes #232 [topaxi] 0.12.0 / 2011-06-03 ================== * Added `doctype` as alias of `!!!` * Added; doctype value is now case-insensitive * Added attribute interpolation support * Fixed; retain original indentation spaces in text blocks 0.11.1 / 2011-06-01 ================== * Fixed text block indentation [Laszlo Bacsi] * Changed; utilizing devDependencies * Fixed try/catch issue with renderFile(). Closes #227 * Removed attribute ":" support, use "=" (option for ':' coming soon) 0.11.0 / 2011-05-14 ================== * Added `self` object to avoid poor `with(){}` performance [masylum] * Added `doctype` option [Jeremy Larkin] 0.10.7 / 2011-05-04 ================== * expose Parser 0.10.6 / 2011-04-29 ================== * Fixed CS `Object.keys()` [reported by robholland] 0.10.5 / 2011-04-26 ================== * Added error context after the lineno * Added; indicate failing lineno with ">" * Added `Object.keys()` for the client-side * Fixed attr strings when containing the opposite quote. Closes 207 * Fixed attr issue with js expressions within strings * Fixed single-quote filter escape bug. Closes #196 0.10.4 / 2011-04-05 ================== * Added `html` doctype, same as "5" * Fixed `pre`, no longer text-only 0.10.3 / 2011-03-30 ================== * Fixed support for quoted attribute keys ex `rss("xmlns:atom"="atom")` 0.10.2 / 2011-03-30 ================== * Fixed pipeless text bug with missing outdent 0.10.1 / 2011-03-28 ================== * Fixed `support/compile.js` to exclude browser js in node * Fixes for IE [Patrick Pfeiffer] 0.10.0 / 2011-03-25 ================== * Added AST-filter support back in the form of `[attrs]<:>` 0.9.3 / 2011-03-24 ================== * Added `Block#unshift(node)` * Added `pug.js` for the client-side to the repo * Added `pug.min.js` for the client-side to the repo * Removed need for pipes in filters. Closes #185 Note that this _will_ break filters used to manipulate the AST, until we have a different syntax for doing so. 0.9.2 / 2011-03-23 ================== * Added pug `--version` * Removed `${}` interpolation support, use `#{}` 0.9.1 / 2011-03-16 ================== * Fixed invalid `.map()` call due to recent changes 0.9.0 / 2011-03-16 ================== * Added client-side browser support via `make pug.js` and `make pug.min.js`. 0.8.9 / 2011-03-15 ================== * Fixed preservation of newlines in text blocks 0.8.8 / 2011-03-14 ================== * Fixed pug(1) stdio 0.8.7 / 2011-03-14 ================== * Added `mkdirs()` to pug(1) * Added pug(1) stdio support * Added new features to pug(1), `--watch`, recursive compilation etc [khingebjerg] * Fixed pipe-less text newlines * Removed pug(1) `--pipe` flag 0.8.6 / 2011-03-11 ================== * Fixed parenthesized expressions in attrs. Closes #170 * Changed; default interpolation values `== null` to ''. Closes #167 0.8.5 / 2011-03-09 ================== * Added pipe-less text support with immediate ".". Closes #157 * Fixed object support in attrs * Fixed array support for attrs 0.8.4 / 2011-03-08 ================== * Fixed issue with expressions being evaluated several times. closes #162 0.8.2 / 2011-03-07 ================== * Added markdown, discount, and markdown-js support to `:markdown`. Closes #160 * Removed `:discount` 0.8.1 / 2011-03-04 ================== * Added `pre` pipe-less text support (and auto-escaping) 0.8.0 / 2011-03-04 ================== * Added block-expansion support. Closes #74 * Added support for multi-line attrs without commas. Closes #65 0.7.1 / 2011-03-04 ================== * Fixed `script()` etc pipe-less text with attrs 0.7.0 / 2011-03-04 ================== * Removed `:javascript` filter (it doesn't really do anything special, use `script` tags) * Added pipe-less text support. Tags that only accept text nodes (`script`, `textarea`, etc) do not require `|`. * Added `:text` filter for ad-hoc pipe-less * Added flexible indentation. Tabs, arbitrary number of spaces etc * Added conditional-comment support. Closes #146 * Added block comment support * Added rss example * Added `:stylus` filter * Added `:discount` filter * Fixed; auto-detect xml and do not self-close tags. Closes #147 * Fixed whitespace issue. Closes #118 * Fixed attrs. `,`, `=`, and `:` within attr value strings are valid Closes #133 * Fixed; only output "" when code == null. Ex: `span.name= user.name` when undefined or null will not output "undefined". Closes #130 * Fixed; throw on unexpected token instead of hanging 0.6.3 / 2011-02-02 ================== * Added `each` support for Array-like objects [guillermo] 0.6.2 / 2011-02-02 ================== * Added CSRF example, showing how you can transparently add inputs to a form * Added link to vim-pug * Fixed self-closing col support [guillermo] * Fixed exception when getAttribute or removeAttribute run into removed attributes [Naitik Shah] 0.6.0 / 2010-12-19 ================== * Added unescaped interpolation variant `!{code}`. Closes #124 * Changed; escape interpolated code by default `#{code}` 0.5.7 / 2010-12-08 ================== * Fixed; hyphen in get `tag()` 0.5.6 / 2010-11-24 ================== * Added `exports.compile(str, options)` * Renamed internal `_` to `__`, since `_()` is commonly used for translation 0.5.5 / 2010-10-30 ================== * Add _coffeescript_ filter [Michael Hampton] * Added link to _slim_; a ruby implementation * Fixed quoted attributes issue. * Fixed attribute issue with over greedy regexp. Previously "p(foo=(((('bar')))))= ((('baz')))" would __fail__ for example since the regexp would lookahead to far. Now we simply pair the delimiters. 0.5.4 / 2010-10-18 ================== * Adding newline when using tag code when preceding text * Assume newline in tag text when preceding text * Changed; retain leading text whitespace * Fixed code block support to prevent multiple buffer openings [Jake Luer] * Fixed nested filter support 0.5.3 / 2010-10-06 ================== * Fixed bug when tags with code also have a block [reported by chrisirhc] 0.5.2 / 2010-10-05 ================== * Added; Text introduces newlines to mimic the grammar. Whitespace handling is a little tricky with this sort of grammar. Pug will now mimic the written grammar, meaning that text blocks using the "|" margin character will introduce a literal newline, where as immediate tag text (ex "a(href='#') Link") will not. This may not be ideal, but it makes more sense than what Pug was previously doing. * Added `Tag#text` to disambiguate between immediate / block text * Removed _pretty_ option (was kinda useless in the state it was in) * Reverted ignoring of newlines. Closes #92. * Fixed; `Parser#parse()` ignoring newlines 0.5.1 / 2010-10-04 ================== * Added many examples * Added; compiler api is now public * Added; filters can accept / manipulate the parse tree * Added filter attribute support. Closes #79 * Added LL(*) capabilities * Performance; wrapping code blocks in {} instead of `(function(){}).call(this)` * Performance; Optimized attribute buffering * Fixed trailing newlines in blocks 0.5.0 / 2010-09-11 ================== * __Major__ refactor. Logic now separated into lexer/parser/compiler for future extensibility. * Added _pretty_ option * Added parse tree output for _debug_ option * Added new examples * Removed _context_ option, use _scope_ 0.4.1 / 2010-09-09 ================== * Added support for arbitrary indentation for single-line comments. Closes #71 * Only strip first space in text (ex '| foo' will buffer ' foo') 0.4.0 / 2010-08-30 ================== * Added tab naive support (tabs are converted to a single indent, aka two spaces). Closes #24 * Added unbuffered comment support. Closes #62 * Added hyphen support for tag names, ex: "fb:foo-bar" * Fixed bug with single quotes in comments. Closes #61 * Fixed comment whitespace issue, previously padding. Closes #55 0.3.0 / 2010-08-04 ================== * Added single line comment support. Closes #25 * Removed CDATA from _:javascript_ filter. Closes #47 * Removed _sys_ local * Fixed code following tag 0.2.4 / 2010-08-02 ================== * Added Buffer support to `render()` * Fixed filter text block exception reporting * Fixed tag exception reporting 0.2.3 / 2010-07-27 ================== * Fixed newlines before block * Fixed; tag text allowing arbitrary trailing whitespace 0.2.2 / 2010-07-16 ================== * Added support for `pug.renderFile()` to utilize primed cache * Added link to [textmate bundle](http://github.com/miksago/pug-tmbundle) * Fixed filter issue with single quotes * Fixed hyphenated attr bug * Fixed interpolation single quotes. Closes #28 * Fixed issue with comma in attrs 0.2.1 / 2010-07-09 ================== * Added support for node-discount and markdown-js depending on which is available. * Added support for tags to have blocks _and_ text. this kinda fucks with arbitrary whitespace unfortunately, but also fixes trailing spaces after tags _with_ blocks. * Caching generated functions. Closes #46 0.2.0 / 2010-07-08 ================== * Added `- each` support for readable iteration * Added [markdown-js](http://github.com/evilstreak/markdown-js) support (no compilation required) * Removed node-discount support 0.1.0 / 2010-07-05 ================== * Added `${}` support for interpolation. Closes #45 * Added support for quoted attr keys: `label("for": 'something')` is allowed (_although not required_) [Guillermo] * Added `:less` filter [jakeluer] 0.0.2 / 2010-07-03 ================== * Added `context` as synonym for `scope` option [Guillermo] * Fixed attr splitting: `div(style:"color: red")` is now allowed * Fixed issue with `(` and `)` within attrs: `a(class: (a ? 'a' : 'b'))` is now allowed * Fixed issue with leading / trailing spaces in attrs: `a( href="#" )` is now allowed [Guillermo] ================================================ FILE: packages/pug/LICENSE ================================================ (The MIT License) Copyright (c) 2009-2014 TJ Holowaychuk 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. ================================================ FILE: packages/pug/README.md ================================================ # Pug Full documentation is at [pugjs.org](https://pugjs.org/) Pug is a high performance template engine heavily influenced by [Haml](http://haml.info/) and implemented with JavaScript for [Node.js](http://nodejs.org) and browsers. For bug reports, feature requests and questions, [open an issue](https://github.com/pugjs/pug/issues/new). For discussion join the [chat room](https://gitter.im/pugjs/pug). You can test drive Pug online [here](https://pugjs.org/). [![Build Status](https://img.shields.io/travis/pugjs/pug/master.svg?style=flat)](https://travis-ci.org/pugjs/pug) [![Coverage Status](https://img.shields.io/coveralls/pugjs/pug/master.svg?style=flat)](https://coveralls.io/r/pugjs/pug?branch=master) [![Dependency Status](https://david-dm.org/pugjs/pug/status.svg?path=packages/pug)](https://david-dm.org/pugjs/pug?path=packages/pug) [![DevDependencies Status](https://david-dm.org/pugjs/pug/dev-status.svg?path=packages/pug)](https://david-dm.org/pugjs/pug?path=packages/pug&type=dev) [![NPM version](https://img.shields.io/npm/v/pug.svg?style=flat)](https://www.npmjs.com/package/pug) [![Join Gitter Chat](https://img.shields.io/badge/gitter-join%20chat%20%E2%86%92-brightgreen.svg?style=flat)](https://gitter.im/pugjs/pug?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) ## Rename from "Jade" This project was formerly known as "Jade." However, it has been revealed to us that "Jade" is a registered trademark, and as a result a rename is needed. After some discussion among the maintainers, **"Pug"** has been chosen as the new name for this project. The next major version will carry "pug" as the package name. If your package or app currently uses `jade`, don't worry: we have secured permissions to continue to occupy that package name, although all new versions will be released under `pug`. Before the renaming, we had already begun working on an incompatible Jade 2.0.0. We have then made it so that this new major version bump will coincide with the rename to Pug. Therefore, upgrading from Jade to Pug will be the same process as upgrading any other package with a major version bump. Currently, Pug 2.0.0 is still under beta stage, and there are several syntactic differences we have deprecated and removed. Such differences are documented at [#2305](https://github.com/pugjs/pug/issues/2305). The website and documentation for Pug are still being updated, but if you are new to Pug, you should get started with the new syntax and install the Pug package on npm. ## Installation ### Package via npm: ```bash $ npm install pug ``` ### Command Line After installing the latest version of [Node.js](http://nodejs.org/), install with: ```bash $ npm install pug-cli -g ``` and run with ```bash $ pug --help ``` ## Syntax Pug is a clean, whitespace sensitive syntax for writing html. Here is a simple example: ```pug doctype html html(lang="en") head title= pageTitle script(type='text/javascript'). if (foo) bar(1 + 5) body h1 Pug - node template engine #container.col if youAreUsingPug p You are amazing else p Get on it! p. Pug is a terse and simple templating language with a strong focus on performance and powerful features. ``` becomes ```html Pug

Pug - node template engine

You are amazing

Pug is a terse and simple templating language with a strong focus on performance and powerful features.

``` ## API For full API, see [pugjs.org/api/reference.html](https://pugjs.org/api/reference.html) ```js var pug = require('pug'); // compile var fn = pug.compile('string of pug', options); var html = fn(locals); // render var html = pug.render('string of pug', merge(options, locals)); // renderFile var html = pug.renderFile('filename.pug', merge(options, locals)); ``` ### Options - `filename` Used in exceptions, and required when using includes - `compileDebug` When `false` no debug instrumentation is compiled - `pretty` Add pretty-indentation whitespace to output _(false by default)_ ## Browser Support The latest version of pug can be download for the browser in standalone form from [here](https://pugjs.org/js/pug.js). It only supports the very latest browsers though, and is a large file. It is recommended that you pre-compile your pug templates to JavaScript. To compile a template for use on the client using the command line, do: ```bash $ pug --client --no-debug filename.pug ``` which will produce `filename.js` containing the compiled template. ## Additional Resources Tutorials: - cssdeck interactive [Pug syntax tutorial](http://cssdeck.com/labs/learning-the-jade-templating-engine-syntax) - cssdeck interactive [Pug logic tutorial](http://cssdeck.com/labs/jade-templating-tutorial-codecast-part-2) - [Pug について。](https://gist.github.com/japboy/5402844) (A Japanese Tutorial) Implementations in other languages: - [Larpug - Pug for Laravel](https://github.com/acidjazz/larpug) - [php](https://github.com/pug-php/pug) - [scala](https://scalate.github.io/scalate/documentation/scaml-reference.html) - [ruby](https://github.com/slim-template/slim) - [python](https://github.com/SyrusAkbary/pyjade) - [java](https://github.com/neuland/jade4j) Other: - [Emacs Mode](https://github.com/brianc/jade-mode) - [Vim Syntax](https://github.com/digitaltoad/vim-pug) - [TextMate Bundle](http://github.com/miksago/jade-tmbundle) - [Coda/SubEtha syntax Mode](https://github.com/aaronmccall/jade.mode) - [html2pug](https://github.com/donpark/html2jade) converter - [pug2php](https://github.com/SE7ENSKY/jade2php) converter - [Pug Server](https://github.com/ded/jade-server) Ideal for building local prototypes apart from any application - [pug-ruby](https://github.com/yivo/pug-ruby) gem: Allows to invoke Pug and Jade from Ruby - [pug-rails](https://github.com/yivo/pug-rails) gem: Integrates Pug and Jade into your Rails application ## License MIT ================================================ FILE: packages/pug/examples/README.md ================================================ The examples in this directory can be run simply by something like. node attributes.js You can also open `browser.html` in a browser. ================================================ FILE: packages/pug/examples/attributes.js ================================================ /** * Module dependencies. */ var pug = require('../'), path = __dirname + '/attributes.pug', str = require('fs').readFileSync(path, 'utf8'), fn = pug.compile(str, {filename: path, pretty: true}); console.log(fn({name: 'tj'})); ================================================ FILE: packages/pug/examples/attributes.pug ================================================ div#id.left.container(class='user user-' + name) h1.title= name form //- unbuffered comment :) // An example of attributes. input(type='text' name='user[name]' value=name) input(checked, type='checkbox', name='user[blocked]') input(type='submit', value='Update') ================================================ FILE: packages/pug/examples/code.js ================================================ /** * Module dependencies. */ var pug = require('../'), path = __dirname + '/code.pug', str = require('fs').readFileSync(path, 'utf8'), fn = pug.compile(str, {filename: path, pretty: true}); var users = { tj: {age: 23, email: 'tj@vision-media.ca', isA: 'human'}, tobi: {age: 1, email: 'tobi@is-amazing.com', isA: 'ferret'}, }; console.log(fn({users: users})); ================================================ FILE: packages/pug/examples/code.pug ================================================ - var title = "Things" - var subtitle = ["Really", "long", "list", "of", "words"] h1= title h2= subtitle.join(" ") ul#users each user, name in users // expands to if (user.isA == 'ferret') if user.isA == 'ferret' li(class='user-' + name) #{name} is just a ferret else li(class='user-' + name) #{name} #{user.email} ================================================ FILE: packages/pug/examples/dynamicscript.js ================================================ /** * Module dependencies. */ var pug = require('../'); var locals = { users: { tj: {age: 23, email: 'tj@vision-media.ca', isA: 'human'}, tobi: {age: 1, email: 'tobi@is-amazing.com', isA: 'ferret'}, }, }; var fn = pug.compileFile(__dirname + '/dynamicscript.pug'); console.log(fn(locals)); ================================================ FILE: packages/pug/examples/dynamicscript.pug ================================================ html head title Dynamic Inline JavaScript script. var users = !{JSON.stringify(users).replace(/<\//g, "<\\/")} ================================================ FILE: packages/pug/examples/each.js ================================================ /** * Module dependencies. */ var pug = require('../'), path = __dirname + '/each.pug', str = require('fs').readFileSync(path, 'utf8'), fn = pug.compile(str, {filename: path, pretty: true}); var users = { tj: {age: 23, email: 'tj@vision-media.ca', isA: 'human'}, tobi: {age: 1, email: 'tobi@is-amazing.com', isA: 'ferret'}, }; console.log(fn({users: users})); ================================================ FILE: packages/pug/examples/each.pug ================================================ ul#users each user, name in users li(class='user-' + name) #{name} #{user.email} ================================================ FILE: packages/pug/examples/extend-layout.pug ================================================ html head h1 My Site - #{title} block scripts script(src='/jquery.js') body block content block foot #footer p some footer content ================================================ FILE: packages/pug/examples/extend.js ================================================ /** * Module dependencies. */ var pug = require('../'), path = __dirname + '/extend.pug', str = require('fs').readFileSync(path, 'utf8'), fn = pug.compile(str, {filename: path, pretty: true}); var tobi = {name: 'tobi', age: 2}; var loki = {name: 'loki', age: 1}; var jane = {name: 'jane', age: 5}; console.log( fn({ title: 'pets', pets: [tobi, loki, jane], }) ); ================================================ FILE: packages/pug/examples/extend.pug ================================================ extends extend-layout.pug block scripts script(src='/jquery.js') script(src='/pets.js') block content h1= title each pet in pets include pet.pug ================================================ FILE: packages/pug/examples/form.js ================================================ /** * Module dependencies. */ var pug = require('../'), path = __dirname + '/form.pug', str = require('fs').readFileSync(path, 'utf8'), fn = pug.compile(str, {filename: path, pretty: true}); var user = { name: 'TJ', email: 'tj@vision-media.ca', city: 'Victoria', province: 'BC', }; console.log(fn({user: user})); ================================================ FILE: packages/pug/examples/form.pug ================================================ form(method="post") fieldset legend General p label(for="user[name]") Username: input(type="text", name="user[name]", value=user.name) p label(for="user[email]") Email: input(type="text", name="user[email]", value=user.email) .tip. Enter a valid email address such as tj@vision-media.ca. fieldset legend Location p label(for="user[city]") City: input(type="text", name="user[city]", value=user.city) p select(name="user[province]") option(value="") -- Select Province -- option(value="AB") Alberta option(value="BC") British Columbia option(value="SK") Saskatchewan option(value="MB") Manitoba option(value="ON") Ontario option(value="QC") Quebec p.buttons input(type="submit", value="Save") ================================================ FILE: packages/pug/examples/includes/foot.pug ================================================ #footer p Copyright (c) foobar ================================================ FILE: packages/pug/examples/includes/head.pug ================================================ head title My Site // including other pug works include scripts.pug // including .html, .css, etc works include style.css ================================================ FILE: packages/pug/examples/includes/scripts.pug ================================================ script(src='/javascripts/jquery.js') script(src='/javascripts/app.js') ================================================ FILE: packages/pug/examples/includes/style.css ================================================ ================================================ FILE: packages/pug/examples/includes.js ================================================ /** * Module dependencies. */ var pug = require('../'), path = __dirname + '/includes.pug', str = require('fs').readFileSync(path, 'utf8'), fn = pug.compile(str, {filename: path, pretty: true}); console.log(fn()); ================================================ FILE: packages/pug/examples/includes.pug ================================================ html include includes/head.pug body h1 My Site p Welcome to my super lame site. include includes/foot.pug ================================================ FILE: packages/pug/examples/layout-debug.js ================================================ /** * Module dependencies. */ var pug = require('../'); pug.renderFile(__dirname + '/layout.pug', {debug: true}, function(err, html) { if (err) throw err; console.log(html); }); ================================================ FILE: packages/pug/examples/layout.js ================================================ /** * Module dependencies. */ var pug = require('../'), path = __dirname + '/layout.pug', str = require('fs').readFileSync(path, 'utf8'), fn = pug.compile(str, {filename: path, pretty: true}); console.log(fn()); ================================================ FILE: packages/pug/examples/layout.pug ================================================ doctype html html(lang="en") head title Example script. if (foo) { bar(); } body h1 Pug - node template engine #container :markdown-it Pug is a _high performance_ template engine for [node](http://nodejs.org), inspired by [haml](http://haml-lang.com/), and written by [TJ Holowaychuk](http://github.com/visionmedia). ================================================ FILE: packages/pug/examples/mixins/dialog.pug ================================================ mixin dialog .dialog h1 Whoop p stuff mixin dialog-title(title) .dialog h1= title p stuff mixin dialog-title-desc(title, desc) .dialog h1= title p= desc ================================================ FILE: packages/pug/examples/mixins/profile.pug ================================================ mixin pets(pets) ul.pets each pet in pets li= pet mixin profile(user) .user h2= user.name +pets(user.pets) ================================================ FILE: packages/pug/examples/mixins.js ================================================ /** * Module dependencies. */ var pug = require('../'), path = __dirname + '/mixins.pug', str = require('fs').readFileSync(path, 'utf8'), fn = pug.compile(str, {filename: path, pretty: true}); var user = { name: 'tj', pets: ['tobi', 'loki', 'jane', 'manny'], }; console.log(fn({user: user})); ================================================ FILE: packages/pug/examples/mixins.pug ================================================ include mixins/dialog.pug include mixins/profile.pug .one +dialog .two +dialog-title('Whoop') .three +dialog-title-desc('Whoop', 'Just a mixin') #profile +profile(user) ================================================ FILE: packages/pug/examples/pet.pug ================================================ .pet h2= pet.name p #{pet.name} is #{pet.age} year(s) old. ================================================ FILE: packages/pug/examples/rss.js ================================================ /** * Module dependencies. */ var pug = require('../'), path = __dirname + '/rss.pug', str = require('fs').readFileSync(path, 'utf8'), fn = pug.compile(str, {filename: path, pretty: true}); var items = []; items.push({ title: 'Example', description: 'Something', link: 'http://google.com', }); items.push({ title: 'LearnBoost', description: 'Cool', link: 'http://learnboost.com', }); items.push({ title: 'Express', description: 'Cool', link: 'http://expressjs.com', }); console.log(fn({items: items})); ================================================ FILE: packages/pug/examples/rss.pug ================================================ doctype xml rss(version='2.0') channel title RSS Title description Some description here link http://google.com lastBuildDate Mon, 06 Sep 2010 00:01:00 +0000 pubDate Mon, 06 Sep 2009 16:45:00 +0000 each item in items item title= item.title description= item.description link= item.link ================================================ FILE: packages/pug/examples/text.js ================================================ /** * Module dependencies. */ var pug = require('../'), path = __dirname + '/text.pug', str = require('fs').readFileSync(path, 'utf8'), fn = pug.compile(str, {filename: path, pretty: true}); console.log(fn({name: 'tj', email: 'tj@vision-media.ca'})); ================================================ FILE: packages/pug/examples/text.pug ================================================ | An example of an a(href='#') inline | link. form label Username: input(type='text', name='user[name]') p | Just an example of some text usage. | You can have inline html, | as well as strong tags | . | Interpolation is also supported. The | username is currently "#{name}". label Email: input(type='text', name='user[email]') p | Email is currently em= email | . // alternatively, if we plan on having only // text or inline-html, we can use a trailing // "." to let pug know we want to omit pipes label Username: input(type='text') p. Just an example, like before however now we can omit those annoying pipes!. Wahoo. ================================================ FILE: packages/pug/examples/whitespace.js ================================================ /** * Module dependencies. */ var pug = require('../'), path = __dirname + '/whitespace.pug', str = require('fs').readFileSync(path, 'utf8'), fn = pug.compile(str, {filename: path, pretty: true}); console.log(fn()); ================================================ FILE: packages/pug/examples/whitespace.pug ================================================ - var js = '' doctype html html head title= "Some " + "JavaScript" != js body ================================================ FILE: packages/pug/lib/index.js ================================================ 'use strict'; /*! * Pug * Copyright(c) 2010 TJ Holowaychuk * MIT Licensed */ /** * Module dependencies. */ var fs = require('fs'); var path = require('path'); var lex = require('pug-lexer'); var stripComments = require('pug-strip-comments'); var parse = require('pug-parser'); var load = require('pug-load'); var filters = require('pug-filters'); var link = require('pug-linker'); var generateCode = require('pug-code-gen'); var runtime = require('pug-runtime'); var runtimeWrap = require('pug-runtime/wrap'); /** * Name for detection */ exports.name = 'Pug'; /** * Pug runtime helpers. */ exports.runtime = runtime; /** * Template function cache. */ exports.cache = {}; function applyPlugins(value, options, plugins, name) { return plugins.reduce(function(value, plugin) { return plugin[name] ? plugin[name](value, options) : value; }, value); } function findReplacementFunc(plugins, name) { var eligiblePlugins = plugins.filter(function(plugin) { return plugin[name]; }); if (eligiblePlugins.length > 1) { throw new Error('Two or more plugins all implement ' + name + ' method.'); } else if (eligiblePlugins.length) { return eligiblePlugins[0][name].bind(eligiblePlugins[0]); } return null; } /** * Object for global custom filters. Note that you can also just pass a `filters` * option to any other method. */ exports.filters = {}; /** * Compile the given `str` of pug and return a function body. * * @param {String} str * @param {Object} options * @return {Object} * @api private */ function compileBody(str, options) { var debug_sources = {}; debug_sources[options.filename] = str; var dependencies = []; var plugins = options.plugins || []; var ast = load.string(str, { filename: options.filename, basedir: options.basedir, lex: function(str, options) { var lexOptions = {}; Object.keys(options).forEach(function(key) { lexOptions[key] = options[key]; }); lexOptions.plugins = plugins .filter(function(plugin) { return !!plugin.lex; }) .map(function(plugin) { return plugin.lex; }); var contents = applyPlugins( str, {filename: options.filename}, plugins, 'preLex' ); return applyPlugins( lex(contents, lexOptions), options, plugins, 'postLex' ); }, parse: function(tokens, options) { tokens = tokens.map(function(token) { if (token.type === 'path' && path.extname(token.val) === '') { return { type: 'path', loc: token.loc, val: token.val + '.pug', }; } return token; }); tokens = stripComments(tokens, options); tokens = applyPlugins(tokens, options, plugins, 'preParse'); var parseOptions = {}; Object.keys(options).forEach(function(key) { parseOptions[key] = options[key]; }); parseOptions.plugins = plugins .filter(function(plugin) { return !!plugin.parse; }) .map(function(plugin) { return plugin.parse; }); return applyPlugins( applyPlugins( parse(tokens, parseOptions), options, plugins, 'postParse' ), options, plugins, 'preLoad' ); }, resolve: function(filename, source, loadOptions) { var replacementFunc = findReplacementFunc(plugins, 'resolve'); if (replacementFunc) { return replacementFunc(filename, source, options); } return load.resolve(filename, source, loadOptions); }, read: function(filename, loadOptions) { dependencies.push(filename); var contents; var replacementFunc = findReplacementFunc(plugins, 'read'); if (replacementFunc) { contents = replacementFunc(filename, options); } else { contents = load.read(filename, loadOptions); } debug_sources[filename] = Buffer.isBuffer(contents) ? contents.toString('utf8') : contents; return contents; }, }); ast = applyPlugins(ast, options, plugins, 'postLoad'); ast = applyPlugins(ast, options, plugins, 'preFilters'); var filtersSet = {}; Object.keys(exports.filters).forEach(function(key) { filtersSet[key] = exports.filters[key]; }); if (options.filters) { Object.keys(options.filters).forEach(function(key) { filtersSet[key] = options.filters[key]; }); } ast = filters.handleFilters( ast, filtersSet, options.filterOptions, options.filterAliases ); ast = applyPlugins(ast, options, plugins, 'postFilters'); ast = applyPlugins(ast, options, plugins, 'preLink'); ast = link(ast); ast = applyPlugins(ast, options, plugins, 'postLink'); // Compile ast = applyPlugins(ast, options, plugins, 'preCodeGen'); var js = (findReplacementFunc(plugins, 'generateCode') || generateCode)(ast, { pretty: options.pretty, compileDebug: options.compileDebug, doctype: options.doctype, inlineRuntimeFunctions: options.inlineRuntimeFunctions, globals: options.globals, self: options.self, includeSources: options.includeSources ? debug_sources : false, templateName: options.templateName, }); js = applyPlugins(js, options, plugins, 'postCodeGen'); // Debug compiler if (options.debug) { console.error( '\nCompiled Function:\n\n\u001b[90m%s\u001b[0m', js.replace(/^/gm, ' ') ); } return {body: js, dependencies: dependencies}; } /** * Get the template from a string or a file, either compiled on-the-fly or * read from cache (if enabled), and cache the template if needed. * * If `str` is not set, the file specified in `options.filename` will be read. * * If `options.cache` is true, this function reads the file from * `options.filename` so it must be set prior to calling this function. * * @param {Object} options * @param {String=} str * @return {Function} * @api private */ function handleTemplateCache(options, str) { var key = options.filename; if (options.cache && exports.cache[key]) { return exports.cache[key]; } else { if (str === undefined) str = fs.readFileSync(options.filename, 'utf8'); var templ = exports.compile(str, options); if (options.cache) exports.cache[key] = templ; return templ; } } /** * Compile a `Function` representation of the given pug `str`. * * Options: * * - `compileDebug` when `false` debugging code is stripped from the compiled template, when it is explicitly `true`, the source code is included in the compiled template for better accuracy. * - `filename` used to improve errors when `compileDebug` is not `false` and to resolve imports/extends * * @param {String} str * @param {Options} options * @return {Function} * @api public */ exports.compile = function(str, options) { var options = options || {}; str = String(str); var parsed = compileBody(str, { compileDebug: options.compileDebug !== false, filename: options.filename, basedir: options.basedir, pretty: options.pretty, doctype: options.doctype, inlineRuntimeFunctions: options.inlineRuntimeFunctions, globals: options.globals, self: options.self, includeSources: options.compileDebug === true, debug: options.debug, templateName: 'template', filters: options.filters, filterOptions: options.filterOptions, filterAliases: options.filterAliases, plugins: options.plugins, }); var res = options.inlineRuntimeFunctions ? new Function('', parsed.body + ';return template;')() : runtimeWrap(parsed.body); res.dependencies = parsed.dependencies; return res; }; /** * Compile a JavaScript source representation of the given pug `str`. * * Options: * * - `compileDebug` When it is `true`, the source code is included in * the compiled template for better error messages. * - `filename` used to improve errors when `compileDebug` is not `true` and to resolve imports/extends * - `name` the name of the resulting function (defaults to "template") * - `module` when it is explicitly `true`, the source code include export module syntax * * @param {String} str * @param {Options} options * @return {Object} * @api public */ exports.compileClientWithDependenciesTracked = function(str, options) { var options = options || {}; str = String(str); var parsed = compileBody(str, { compileDebug: options.compileDebug, filename: options.filename, basedir: options.basedir, pretty: options.pretty, doctype: options.doctype, inlineRuntimeFunctions: options.inlineRuntimeFunctions !== false, globals: options.globals, self: options.self, includeSources: options.compileDebug, debug: options.debug, templateName: options.name || 'template', filters: options.filters, filterOptions: options.filterOptions, filterAliases: options.filterAliases, plugins: options.plugins, }); var body = parsed.body; if (options.module) { if (options.inlineRuntimeFunctions === false) { body = 'var pug = require("pug-runtime");' + body; } body += ' module.exports = ' + (options.name || 'template') + ';'; } return {body: body, dependencies: parsed.dependencies}; }; /** * Compile a JavaScript source representation of the given pug `str`. * * Options: * * - `compileDebug` When it is `true`, the source code is included in * the compiled template for better error messages. * - `filename` used to improve errors when `compileDebug` is not `true` and to resolve imports/extends * - `name` the name of the resulting function (defaults to "template") * * @param {String} str * @param {Options} options * @return {String} * @api public */ exports.compileClient = function(str, options) { return exports.compileClientWithDependenciesTracked(str, options).body; }; /** * Compile a `Function` representation of the given pug file. * * Options: * * - `compileDebug` when `false` debugging code is stripped from the compiled template, when it is explicitly `true`, the source code is included in the compiled template for better accuracy. * * @param {String} path * @param {Options} options * @return {Function} * @api public */ exports.compileFile = function(path, options) { options = options || {}; options.filename = path; return handleTemplateCache(options); }; /** * Render the given `str` of pug. * * Options: * * - `cache` enable template caching * - `filename` filename required for `include` / `extends` and caching * * @param {String} str * @param {Object|Function} options or fn * @param {Function|undefined} fn * @returns {String} * @api public */ exports.render = function(str, options, fn) { // support callback API if ('function' == typeof options) { (fn = options), (options = undefined); } if (typeof fn === 'function') { var res; try { res = exports.render(str, options); } catch (ex) { return fn(ex); } return fn(null, res); } options = options || {}; // cache requires .filename if (options.cache && !options.filename) { throw new Error('the "filename" option is required for caching'); } return handleTemplateCache(options, str)(options); }; /** * Render a Pug file at the given `path`. * * @param {String} path * @param {Object|Function} options or callback * @param {Function|undefined} fn * @returns {String} * @api public */ exports.renderFile = function(path, options, fn) { // support callback API if ('function' == typeof options) { (fn = options), (options = undefined); } if (typeof fn === 'function') { var res; try { res = exports.renderFile(path, options); } catch (ex) { return fn(ex); } return fn(null, res); } options = options || {}; options.filename = path; return handleTemplateCache(options)(options); }; /** * Compile a Pug file at the given `path` for use on the client. * * @param {String} path * @param {Object} options * @returns {String} * @api public */ exports.compileFileClient = function(path, options) { var key = path + ':client'; options = options || {}; options.filename = path; if (options.cache && exports.cache[key]) { return exports.cache[key]; } var str = fs.readFileSync(options.filename, 'utf8'); var out = exports.compileClient(str, options); if (options.cache) exports.cache[key] = out; return out; }; /** * Express support. */ exports.__express = function(path, options, fn) { if ( options.compileDebug == undefined && process.env.NODE_ENV === 'production' ) { options.compileDebug = false; } exports.renderFile(path, options, fn); }; ================================================ FILE: packages/pug/package.json ================================================ { "name": "pug", "description": "A clean, whitespace-sensitive template language for writing HTML", "keywords": [ "html", "jade", "pug", "template" ], "version": "2.0.4", "author": "TJ Holowaychuk ", "maintainers": [ "Forbes Lindesay ", "Matthias Le Brun ", "Joshua Appelman ", "Jonathan Ong ", "Alex Kocharin ", "Hemanth ", "Timothy Gu ", "Andreas Lubbe " ], "license": "MIT", "repository": { "type": "git", "url": "https://github.com/pugjs/pug/tree/master/packages/pug" }, "main": "lib", "dependencies": { "pug-code-gen": "^2.0.2", "pug-filters": "^3.1.1", "pug-lexer": "^4.1.0", "pug-linker": "^3.0.6", "pug-load": "^2.0.12", "pug-parser": "^5.0.1", "pug-runtime": "^2.0.5", "pug-strip-comments": "^1.0.4" }, "devDependencies": { "jstransformer-cdata": "^1.0.0", "jstransformer-coffee-script": "^1.0.0", "jstransformer-less": "^2.1.0", "jstransformer-markdown-it": "^2.0.0", "jstransformer-stylus": "^1.0.0", "jstransformer-uglify-js": "^1.1.1", "jstransformer-verbatim": "^1.0.0", "mkdirp": "^0.5.1", "rimraf": "^3.0.2", "uglify-js": "github:mishoo/UglifyJS2#1c15d0db456ce32f1b9b507aad97e5ee5c8285f7" }, "files": [ "lib/index.js", "register.js" ], "browser": { "fs": false }, "homepage": "https://pugjs.org" } ================================================ FILE: packages/pug/register.js ================================================ var pug = require('./'); var resolvedPug = JSON.stringify(require.resolve('./')); function compileTemplate(module, filename) { var template = pug.compileFileClient(filename, { inlineRuntimeFunctions: false, }); var body = 'var pug = require(' + resolvedPug + ').runtime;\n\n' + 'module.exports = ' + template + ';'; module._compile(body, filename); } if (require.extensions) { require.extensions['.pug'] = compileTemplate; } ================================================ FILE: packages/pug/support/benchmark.js ================================================ /** * Module dependencies. */ var uubench = require('uubench'), pug = require('../'); var suite = new uubench.Suite({ min: 200, result: function(name, stats) { var persec = 1000 / stats.elapsed, ops = stats.iterations * persec; console.log('%s: %d', name, ops | 0); }, }); function setup(self) { var suffix = self ? ' (self)' : '', options = {self: self}; var str = 'html\n body\n h1 Title', fn = pug.compile(str, options); suite.bench('tiny' + suffix, function(next) { fn(); next(); }); str = '\ html\n\ body\n\ h1 Title\n\ ul#menu\n\ li: a(href="#") Home\n\ li: a(href="#") About Us\n\ li: a(href="#") Store\n\ li: a(href="#") FAQ\n\ li: a(href="#") Contact\n\ '; var fn2 = pug.compile(str, options); suite.bench('small' + suffix, function(next) { fn2(); next(); }); str = '\ html\n\ body\n\ h1 #{title}\n\ ul#menu\n\ - each link in links\r\n\ li: a(href="#")= link\r\n\ '; if (self) { str = '\ html\n\ body\n\ h1 #{self.title}\n\ ul#menu\n\ - each link in self.links\r\n\ li: a(href="#")= link\r\n\ '; } var fn3 = pug.compile(str, options); suite.bench('small locals' + suffix, function(next) { fn3({ title: 'Title', links: ['Home', 'About Us', 'Store', 'FAQ', 'Contact'], }); next(); }); str = '\ html\n\ body\n\ h1 Title\n\ ul#menu\n\ li: a(href="#") Home\n\ li: a(href="#") About Us\n\ li: a(href="#") Store\n\ li: a(href="#") FAQ\n\ li: a(href="#") Contact\n\ '; str = Array(30).join(str); var fn4 = pug.compile(str, options); suite.bench('medium' + suffix, function(next) { fn4(); next(); }); str = '\ html\n\ body\n\ h1 Title\n\ ul#menu\n\ li: a(href="#") Home\n\ li: a(href="#") About Us\n\ li: a(href="#") Store\n\ li: a(href="#") FAQ\n\ li: a(href="#") Contact\n\ '; str = Array(100).join(str); var fn5 = pug.compile(str, options); suite.bench('large' + suffix, function(next) { fn5(); next(); }); } setup(); setup(true); suite.run(); ================================================ FILE: packages/pug/test/README.md ================================================ # Running Tests To run tests (with node.js installed) you must complete 2 steps. ## 1 Install dependencies ``` npm install ``` ## 2 Run tests ``` npm test ``` ================================================ FILE: packages/pug/test/__snapshots__/pug.test.js.snap ================================================ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`pug .compileClient() should support module syntax in pug.compileClient(str, options) when inlineRuntimeFunctions it false 1`] = ` "var pug = require(\\"pug-runtime\\"); function template(locals) { var pug_html = \\"\\", pug_mixins = {}, pug_interp; var pug_debug_filename, pug_debug_line; try { var self = locals || {}; pug_debug_line = 1; pug_html = pug_html + '\\\\u003Cdiv class=\\"bar\\"\\\\u003E'; pug_debug_line = 1; pug_html = pug_html + pug.escape(null == (pug_interp = self.foo) ? \\"\\" : pug_interp) + \\"\\\\u003C\\\\u002Fdiv\\\\u003E\\"; } catch (err) { pug.rethrow(err, pug_debug_filename, pug_debug_line); } return pug_html; } module.exports = template; " `; exports[`pug .compileClient() should support module syntax in pug.compileClient(str, options) when inlineRuntimeFunctions it true 1`] = ` "function pug_escape(e) { var a = \\"\\" + e, t = pug_match_html.exec(a); if (!t) return e; var r, c, n, s = \\"\\"; for (r = t.index, c = 0; r < a.length; r++) { switch (a.charCodeAt(r)) { case 34: n = \\""\\"; break; case 38: n = \\"&\\"; break; case 60: n = \\"<\\"; break; case 62: n = \\">\\"; break; default: continue; } c !== r && (s += a.substring(c, r)), (c = r + 1), (s += n); } return c !== r ? s + a.substring(c, r) : s; } var pug_match_html = /[\\"&<>]/; function pug_rethrow(e, n, r, t) { if (!(e instanceof Error)) throw e; if (!((\\"undefined\\" == typeof window && n) || t)) throw ((e.message += \\" on line \\" + r), e); var o, a, i, s; try { (t = t || require(\\"fs\\").readFileSync(n, { encoding: \\"utf8\\" })), (o = 3), (a = t.split(\\"\\\\n\\")), (i = Math.max(r - o, 0)), (s = Math.min(a.length, r + o)); } catch (t) { return ( (e.message += \\" - could not read from \\" + n + \\" (\\" + t.message + \\")\\"), void pug_rethrow(e, null, r) ); } (o = a .slice(i, s) .map(function(e, n) { var t = n + i + 1; return (t == r ? \\" > \\" : \\" \\") + t + \\"| \\" + e; }) .join(\\"\\\\n\\")), (e.path = n); try { e.message = (n || \\"Pug\\") + \\":\\" + r + \\"\\\\n\\" + o + \\"\\\\n\\\\n\\" + e.message; } catch (e) {} throw e; } function template(locals) { var pug_html = \\"\\", pug_mixins = {}, pug_interp; var pug_debug_filename, pug_debug_line; try { var self = locals || {}; pug_debug_line = 1; pug_html = pug_html + '\\\\u003Cdiv class=\\"bar\\"\\\\u003E'; pug_debug_line = 1; pug_html = pug_html + pug_escape(null == (pug_interp = self.foo) ? \\"\\" : pug_interp) + \\"\\\\u003C\\\\u002Fdiv\\\\u003E\\"; } catch (err) { pug_rethrow(err, pug_debug_filename, pug_debug_line); } return pug_html; } module.exports = template; " `; ================================================ FILE: packages/pug/test/anti-cases/attrs.unescaped.pug ================================================ script(type='text/x-template') #user(id!='user-<%= user.id %>') h1 <%= user.title %> ================================================ FILE: packages/pug/test/anti-cases/case-when.pug ================================================ when 5 .foo when 6 .bar ================================================ FILE: packages/pug/test/anti-cases/case-without-with.pug ================================================ case foo .div ================================================ FILE: packages/pug/test/anti-cases/else-condition.pug ================================================ if foo div else bar article ================================================ FILE: packages/pug/test/anti-cases/else-without-if.pug ================================================ else .foo ================================================ FILE: packages/pug/test/anti-cases/inlining-a-mixin-after-a-tag.pug ================================================ foo()+bar() ================================================ FILE: packages/pug/test/anti-cases/key-char-ending-badly.pug ================================================ div("foo"abc) ================================================ FILE: packages/pug/test/anti-cases/key-ending-badly.pug ================================================ div(foo!~abc) ================================================ FILE: packages/pug/test/anti-cases/mismatched-inline-tag.pug ================================================ //- #1871 p #[strong a} ================================================ FILE: packages/pug/test/anti-cases/mixin-args-syntax-error.pug ================================================ mixin foo(a, b) +foo('a'b'b') ================================================ FILE: packages/pug/test/anti-cases/mixins-blocks-with-bodies.pug ================================================ mixin foo block bar ================================================ FILE: packages/pug/test/anti-cases/multiple-non-nested-tags-on-a-line.pug ================================================ foo()bar ================================================ FILE: packages/pug/test/anti-cases/non-existant-filter.pug ================================================ :not-a-valid-filter foo bar ================================================ FILE: packages/pug/test/anti-cases/non-mixin-block.pug ================================================ div block ================================================ FILE: packages/pug/test/anti-cases/open-brace-in-attributes.pug ================================================ div(title=[) ================================================ FILE: packages/pug/test/anti-cases/readme.md ================================================ This folder collects examples of files that are not valid `pug`, but were at some point accepted by the parser without throwing an error. The tests ensure that all these cases now throw some form of error message (hopefully a helpful one). ================================================ FILE: packages/pug/test/anti-cases/self-closing-tag-with-block.pug ================================================ input | Inputs cannot have content ================================================ FILE: packages/pug/test/anti-cases/self-closing-tag-with-body.pug ================================================ input Input's can't have content ================================================ FILE: packages/pug/test/anti-cases/self-closing-tag-with-code.pug ================================================ input= 'Inputs cannot have code' ================================================ FILE: packages/pug/test/anti-cases/tabs-and-spaces.pug ================================================ div div article ================================================ FILE: packages/pug/test/anti-cases/unclosed-interpolated-call.pug ================================================ +#{myMixin ================================================ FILE: packages/pug/test/anti-cases/unclosed-interpolated-tag.pug ================================================ mixin item block +item( Contact ================================================ FILE: packages/pug/test/anti-cases/unclosed-interpolation.pug ================================================ #{myMixin ================================================ FILE: packages/pug/test/browser/index.html ================================================
================================================ FILE: packages/pug/test/browser/index.pug ================================================ !!! 5 html head body textarea#input(placeholder='write pug here', style='width: 100%; min-height: 400px;'). p author != myName pre(style='background: #ECECEC;width: 100%; min-height: 400px;') code#output script(src='../../pug.js') script. var input = document.getElementById('input'); var output = document.getElementById('output'); setInterval(function () { pug.render(input.value, {myName: 'Forbes Lindesay', pretty: true}, function (err, res) { if (err) throw err; output.textContent = res; }) }, 500) ================================================ FILE: packages/pug/test/cases/attrs-data.html ================================================ ================================================ FILE: packages/pug/test/cases/attrs-data.pug ================================================ - var user = { name: 'tobi' } foo(data-user=user) foo(data-items=[1,2,3]) foo(data-username='tobi') foo(data-escaped={message: "Let's rock!"}) foo(data-ampersand={message: "a quote: " this & that"}) foo(data-epoc=new Date(0)) ================================================ FILE: packages/pug/test/cases/attrs.colon.html ================================================
Click Me! ================================================ FILE: packages/pug/test/cases/attrs.colon.pug ================================================ //- Tests for using a colon-prefexed attribute (typical when using short-cut for Vue.js `v-bind`) div(:my-var="model") span(v-for="item in items" :key="item.id" :value="item.name") span( v-for="item in items" :key="item.id" :value="item.name" ) a(:link="goHere" value="static" :my-value="dynamic" @click="onClick()" :another="more") Click Me! ================================================ FILE: packages/pug/test/cases/attrs.html ================================================ contactsave contactsave
================================================ FILE: packages/pug/test/cases/attrs.js.html ================================================
================================================ FILE: packages/pug/test/cases/attrs.js.pug ================================================ - var id = 5 - function answer() { return 42; } a(href='/user/' + id, class='button') a(href = '/user/' + id, class = 'button') meta(key='answer', value=answer()) a(class = ['class1', 'class2']) a.tag-class(class = ['class1', 'class2']) a(href='/user/' + id class='button') a(href = '/user/' + id class = 'button') meta(key='answer' value=answer()) a(class = ['class1', 'class2']) a.tag-class(class = ['class1', 'class2']) div(id=id)&attributes({foo: 'bar'}) - var bar = null div(foo=null bar=bar)&attributes({baz: 'baz'}) ================================================ FILE: packages/pug/test/cases/attrs.pug ================================================ a(href='/contact') contact a(href='/save').button save a(foo, bar, baz) a(foo='foo, bar, baz', bar=1) a(foo='((foo))', bar= (1) ? 1 : 0 ) select option(value='foo', selected) Foo option(selected, value='bar') Bar a(foo="class:") input(pattern='\\S+') a(href='/contact') contact a(href='/save').button save a(foo bar baz) a(foo='foo, bar, baz' bar=1) a(foo='((foo))' bar= (1) ? 1 : 0 ) select option(value='foo' selected) Foo option(selected value='bar') Bar a(foo="class:") input(pattern='\\S+') foo(terse="true") foo(date=new Date(0)) foo(abc ,def) foo(abc, def) foo(abc, def) foo(abc ,def) foo(abc def) foo(abc def) - var attrs = {foo: 'bar', bar: ''} div&attributes(attrs) a(foo='foo' "bar"="bar") a(foo='foo' 'bar'='bar') ================================================ FILE: packages/pug/test/cases/attrs.unescaped.html ================================================ ================================================ FILE: packages/pug/test/cases/attrs.unescaped.pug ================================================ script(type='text/x-template') div(id!='user-<%= user.id %>') h1 <%= user.title %> ================================================ FILE: packages/pug/test/cases/auxiliary/1794-extends.pug ================================================ block content ================================================ FILE: packages/pug/test/cases/auxiliary/1794-include.pug ================================================ mixin test() .test&attributes(attributes) +test() ================================================ FILE: packages/pug/test/cases/auxiliary/blocks-in-blocks-layout.pug ================================================ doctype html html head title Default title body block body .container block content ================================================ FILE: packages/pug/test/cases/auxiliary/dialog.pug ================================================ extends window.pug block window-content .dialog block content ================================================ FILE: packages/pug/test/cases/auxiliary/empty-block.pug ================================================ block test ================================================ FILE: packages/pug/test/cases/auxiliary/escapes.html ================================================ ================================================ FILE: packages/pug/test/cases/auxiliary/extends-empty-block-1.pug ================================================ extends empty-block.pug block test div test1 ================================================ FILE: packages/pug/test/cases/auxiliary/extends-empty-block-2.pug ================================================ extends empty-block.pug block test div test2 ================================================ FILE: packages/pug/test/cases/auxiliary/extends-from-root.pug ================================================ extends /auxiliary/layout.pug block content include /auxiliary/include-from-root.pug ================================================ FILE: packages/pug/test/cases/auxiliary/extends-relative.pug ================================================ extends ../../cases/auxiliary/layout block content include ../../cases/auxiliary/include-from-root ================================================ FILE: packages/pug/test/cases/auxiliary/filter-in-include.pug ================================================ html head style(type="text/css") :less @pad: 15px; body { padding: @pad; } ================================================ FILE: packages/pug/test/cases/auxiliary/includable.js ================================================ var STRING_SUBSTITUTIONS = { // table of character substitutions '\t': '\\t', '\r': '\\r', '\n': '\\n', '"': '\\"', '\\': '\\\\', }; ================================================ FILE: packages/pug/test/cases/auxiliary/include-from-root.pug ================================================ h1 hello ================================================ FILE: packages/pug/test/cases/auxiliary/inheritance.extend.mixin.block.pug ================================================ mixin article() article block html head title My Application block head body +article block content ================================================ FILE: packages/pug/test/cases/auxiliary/inheritance.extend.recursive-grand-grandparent.pug ================================================ h1 grand-grandparent block grand-grandparent ================================================ FILE: packages/pug/test/cases/auxiliary/inheritance.extend.recursive-grandparent.pug ================================================ extends inheritance.extend.recursive-grand-grandparent.pug block grand-grandparent h2 grandparent block grandparent ================================================ FILE: packages/pug/test/cases/auxiliary/inheritance.extend.recursive-parent.pug ================================================ extends inheritance.extend.recursive-grandparent.pug block grandparent h3 parent block parent ================================================ FILE: packages/pug/test/cases/auxiliary/layout.include.pug ================================================ html head title My Application block head body block content include window.pug ================================================ FILE: packages/pug/test/cases/auxiliary/layout.pug ================================================ html head title My Application block head body block content ================================================ FILE: packages/pug/test/cases/auxiliary/mixin-at-end-of-file.pug ================================================ mixin slide section.slide block ================================================ FILE: packages/pug/test/cases/auxiliary/mixins.pug ================================================ mixin foo() p bar ================================================ FILE: packages/pug/test/cases/auxiliary/pet.pug ================================================ .pet h1 {{name}} p {{name}} is a {{species}} that is {{age}} old ================================================ FILE: packages/pug/test/cases/auxiliary/smile.html ================================================

:)

================================================ FILE: packages/pug/test/cases/auxiliary/window.pug ================================================ .window a(href='#').close Close block window-content ================================================ FILE: packages/pug/test/cases/auxiliary/yield-nested.pug ================================================ html head title body h1 Page #content #content-wrapper yield #footer stuff ================================================ FILE: packages/pug/test/cases/basic.html ================================================

Title

================================================ FILE: packages/pug/test/cases/basic.pug ================================================ html body h1 Title ================================================ FILE: packages/pug/test/cases/blanks.html ================================================
  • foo
  • bar
  • baz
================================================ FILE: packages/pug/test/cases/blanks.pug ================================================ ul li foo li bar li baz ================================================ FILE: packages/pug/test/cases/block-code.html ================================================
  • Uno
  • Dos
  • Tres
  • Cuatro
  • Cinco
  • Seis
  • ================================================ FILE: packages/pug/test/cases/block-code.pug ================================================ - list = ["uno", "dos", "tres", "cuatro", "cinco", "seis"]; //- Without a block, the element is accepted and no code is generated - each item in list - string = item.charAt(0) .toUpperCase() + item.slice(1); li= string ================================================ FILE: packages/pug/test/cases/block-expansion.html ================================================

    baz

    ================================================ FILE: packages/pug/test/cases/block-expansion.pug ================================================ ul li: a(href='#') foo li: a(href='#') bar p baz ================================================ FILE: packages/pug/test/cases/block-expansion.shorthands.html ================================================
    • baz
    ================================================ FILE: packages/pug/test/cases/block-expansion.shorthands.pug ================================================ ul li.list-item: .foo: #bar baz ================================================ FILE: packages/pug/test/cases/blockquote.html ================================================
    Try to define yourself by what you do, and you’ll burnout every time. You are. That is enough. I rest in that.
    from @thefray at 1:43pm on May 10
    ================================================ FILE: packages/pug/test/cases/blockquote.pug ================================================ figure blockquote | Try to define yourself by what you do, and you’ll burnout every time. You are. That is enough. I rest in that. figcaption from @thefray at 1:43pm on May 10 ================================================ FILE: packages/pug/test/cases/blocks-in-blocks.html ================================================ Default title

    Page 2

    ================================================ FILE: packages/pug/test/cases/blocks-in-blocks.pug ================================================ extends ./auxiliary/blocks-in-blocks-layout.pug block body h1 Page 2 ================================================ FILE: packages/pug/test/cases/blocks-in-if.html ================================================

    ajax contents

    ================================================ FILE: packages/pug/test/cases/blocks-in-if.pug ================================================ //- see https://github.com/pugjs/pug/issues/1589 -var ajax = true -if( ajax ) //- return only contents if ajax requests block contents p ajax contents -else //- return all html doctype html html head meta( charset='utf8' ) title sample body block contents p all contetns ================================================ FILE: packages/pug/test/cases/case-blocks.html ================================================

    you have a friend

    ================================================ FILE: packages/pug/test/cases/case-blocks.pug ================================================ html body - var friends = 1 case friends when 0 p you have no friends when 1 p you have a friend default p you have #{friends} friends ================================================ FILE: packages/pug/test/cases/case.html ================================================

    you have a friend

    you have very few friends

    Friend is a string

    ================================================ FILE: packages/pug/test/cases/case.pug ================================================ html body - var friends = 1 case friends when 0: p you have no friends when 1: p you have a friend default: p you have #{friends} friends - var friends = 0 case friends when 0 when 1 p you have very few friends default p you have #{friends} friends - var friend = 'Tim:G' case friend when 'Tim:G': p Friend is a string when {tim: 'g'}: p Friend is an object ================================================ FILE: packages/pug/test/cases/classes-empty.html ================================================ ================================================ FILE: packages/pug/test/cases/classes-empty.pug ================================================ a(class='') a(class=null) a(class=undefined) ================================================ FILE: packages/pug/test/cases/classes.html ================================================ ================================================ FILE: packages/pug/test/cases/classes.pug ================================================ a(class=['foo', 'bar', 'baz']) a.foo(class='bar').baz a.foo-bar_baz a(class={foo: true, bar: false, baz: true}) ================================================ FILE: packages/pug/test/cases/code.conditionals.html ================================================

    foo

    foo

    foo

    bar

    baz

    bar

    yay

    ================================================ FILE: packages/pug/test/cases/code.conditionals.pug ================================================ - if (true) p foo - else p bar - if (true) { p foo - } else { p bar - } if true p foo p bar p baz else p bar unless true p foo else p bar if 'nested' if 'works' p yay //- allow empty blocks if false else .bar if true .bar else .bing if false .bing else if false .bar else .foo ================================================ FILE: packages/pug/test/cases/code.escape.html ================================================

    <script>

    ================================================ FILE: packages/pug/test/cases/escape-chars.pug ================================================ script. var re = /\d+/; ================================================ FILE: packages/pug/test/cases/escape-test.html ================================================ escape-test ================================================ FILE: packages/pug/test/cases/escape-test.pug ================================================ doctype html html head title escape-test body textarea - var txt = '' | #{txt} ================================================ FILE: packages/pug/test/cases/escaping-class-attribute.html ================================================ ================================================ FILE: packages/pug/test/cases/escaping-class-attribute.pug ================================================ foo(attr="<%= bar %>") foo(class="<%= bar %>") foo(attr!="<%= bar %>") foo(class!="<%= bar %>") foo(class!="<%= bar %> lol rofl") foo(class!="<%= bar %> lol rofl <%= lmao %>") ================================================ FILE: packages/pug/test/cases/filter-in-include.html ================================================ ================================================ FILE: packages/pug/test/cases/filter-in-include.pug ================================================ include ./auxiliary/filter-in-include.pug ================================================ FILE: packages/pug/test/cases/filters-empty.html ================================================ ================================================ FILE: packages/pug/test/cases/filters-empty.pug ================================================ - var users = [{ name: 'tobi', age: 2 }] fb:users for user in users fb:user(age=user.age) :cdata ================================================ FILE: packages/pug/test/cases/filters.coffeescript.html ================================================ ================================================ FILE: packages/pug/test/cases/filters.coffeescript.pug ================================================ script(type='text/javascript') :coffee-script regexp = /\n/ :coffee-script(minify=true) math = square: (value) -> value * value ================================================ FILE: packages/pug/test/cases/filters.custom.html ================================================ BEGINLine 1 Line 2 Line 4END ================================================ FILE: packages/pug/test/cases/filters.custom.pug ================================================ html body :custom(opt='val' num=2) Line 1 Line 2 Line 4 ================================================ FILE: packages/pug/test/cases/filters.include.custom.html ================================================

    BEGINhtml
      body
        pre
          include:custom(opt='val' num=2) filters.include.custom.pug
    END
    ================================================ FILE: packages/pug/test/cases/filters.include.custom.pug ================================================ html body pre include:custom(opt='val' num=2) filters.include.custom.pug ================================================ FILE: packages/pug/test/cases/filters.include.html ================================================

    Just some markdown tests.

    With new line.

    ================================================ FILE: packages/pug/test/cases/filters.include.pug ================================================ html body include:markdown-it some.md script include:coffee-script(minify=true) include-filter-coffee.coffee script include:coffee-script(minify=false) include-filter-coffee.coffee ================================================ FILE: packages/pug/test/cases/filters.inline.html ================================================

    before after

    ================================================ FILE: packages/pug/test/cases/filters.inline.pug ================================================ p before #[:cdata inside] after ================================================ FILE: packages/pug/test/cases/filters.less.html ================================================ ================================================ FILE: packages/pug/test/cases/filters.less.pug ================================================ html head style(type="text/css") :less @pad: 15px; body { padding: @pad; } ================================================ FILE: packages/pug/test/cases/filters.markdown.html ================================================

    This is some awesome markdown whoop.

    ================================================ FILE: packages/pug/test/cases/filters.markdown.pug ================================================ html body :markdown This is _some_ awesome **markdown** whoop. ================================================ FILE: packages/pug/test/cases/filters.nested.html ================================================ ================================================ FILE: packages/pug/test/cases/filters.nested.pug ================================================ script :cdata:uglify-js (function() { console.log('test') })() script :cdata:uglify-js:coffee-script (-> console.log 'test' )() ================================================ FILE: packages/pug/test/cases/filters.stylus.html ================================================ ================================================ FILE: packages/pug/test/cases/filters.stylus.pug ================================================ html head style(type="text/css") :stylus body padding: 50px body ================================================ FILE: packages/pug/test/cases/html.html ================================================
    • foo
    • bar
    • baz

    You can embed html as well.

    Even as the body of a block expansion.

    ================================================ FILE: packages/pug/test/cases/html.pug ================================================ - var version = 1449104952939
    • foo
    • bar
    • baz
    p You can embed html as well. p: Even as the body of a block expansion. ================================================ FILE: packages/pug/test/cases/html5.html ================================================ ================================================ FILE: packages/pug/test/cases/html5.pug ================================================ doctype html input(type='checkbox', checked) input(type='checkbox', checked=true) input(type='checkbox', checked=false) ================================================ FILE: packages/pug/test/cases/include-extends-from-root.html ================================================ My Application

    hello

    ================================================ FILE: packages/pug/test/cases/include-extends-from-root.pug ================================================ include /auxiliary/extends-from-root.pug ================================================ FILE: packages/pug/test/cases/include-extends-of-common-template.html ================================================
    test1
    test2
    ================================================ FILE: packages/pug/test/cases/include-extends-of-common-template.pug ================================================ include auxiliary/extends-empty-block-1.pug include auxiliary/extends-empty-block-2.pug ================================================ FILE: packages/pug/test/cases/include-extends-relative.html ================================================ My Application

    hello

    ================================================ FILE: packages/pug/test/cases/include-extends-relative.pug ================================================ include ../cases/auxiliary/extends-relative.pug ================================================ FILE: packages/pug/test/cases/include-filter-coffee.coffee ================================================ math = square: (value) -> value * value ================================================ FILE: packages/pug/test/cases/include-only-text-body.html ================================================ The message is "" ================================================ FILE: packages/pug/test/cases/include-only-text-body.pug ================================================ | The message is " yield | " ================================================ FILE: packages/pug/test/cases/include-only-text.html ================================================

    The message is "hello world"

    ================================================ FILE: packages/pug/test/cases/include-only-text.pug ================================================ html body p include include-only-text-body.pug em hello world ================================================ FILE: packages/pug/test/cases/include-with-text-head.html ================================================ ================================================ FILE: packages/pug/test/cases/include-with-text-head.pug ================================================ head script(type='text/javascript'). alert('hello world'); ================================================ FILE: packages/pug/test/cases/include-with-text.html ================================================ ================================================ FILE: packages/pug/test/cases/include-with-text.pug ================================================ html include include-with-text-head.pug script(src='/caustic.js') script(src='/app.js') ================================================ FILE: packages/pug/test/cases/include.script.html ================================================ ================================================ FILE: packages/pug/test/cases/include.script.pug ================================================ script#pet-template(type='text/x-template') include auxiliary/pet.pug ================================================ FILE: packages/pug/test/cases/include.yield.nested.html ================================================

    Page

    some content

    and some more

    ================================================ FILE: packages/pug/test/cases/include.yield.nested.pug ================================================ include auxiliary/yield-nested.pug p some content p and some more ================================================ FILE: packages/pug/test/cases/includes-with-ext-js.html ================================================
    var x = '\n here is some \n new lined text';
    
    ================================================ FILE: packages/pug/test/cases/includes-with-ext-js.pug ================================================ pre code include javascript-new-lines.js ================================================ FILE: packages/pug/test/cases/includes.html ================================================

    bar

    :)

    ================================================ FILE: packages/pug/test/cases/includes.pug ================================================ include auxiliary/mixins.pug +foo body include auxiliary/smile.html include auxiliary/escapes.html script(type="text/javascript") include:verbatim auxiliary/includable.js ================================================ FILE: packages/pug/test/cases/inheritance.alert-dialog.html ================================================
    Close

    Alert!

    I'm an alert!

    ================================================ FILE: packages/pug/test/cases/inheritance.alert-dialog.pug ================================================ extends auxiliary/dialog.pug block content h1 Alert! p I'm an alert! ================================================ FILE: packages/pug/test/cases/inheritance.defaults.html ================================================ ================================================ FILE: packages/pug/test/cases/inheritance.defaults.pug ================================================ html head block head script(src='jquery.js') script(src='keymaster.js') script(src='caustic.js') ================================================ FILE: packages/pug/test/cases/inheritance.extend.html ================================================ My Application

    Page

    Some content

    ================================================ FILE: packages/pug/test/cases/inheritance.extend.include.html ================================================ My Application

    Page

    Some content

    Close

    Awesome

    Now we can extend included blocks!

    ================================================ FILE: packages/pug/test/cases/inheritance.extend.include.pug ================================================ extend auxiliary/layout.include.pug block head script(src='jquery.js') block content h2 Page p Some content block window-content h2 Awesome p Now we can extend included blocks! ================================================ FILE: packages/pug/test/cases/inheritance.extend.mixins.block.html ================================================ My Application

    Hello World!

    ================================================ FILE: packages/pug/test/cases/inheritance.extend.mixins.block.pug ================================================ extend auxiliary/inheritance.extend.mixin.block.pug block content p Hello World! ================================================ FILE: packages/pug/test/cases/inheritance.extend.mixins.html ================================================ My Application

    The meaning of life

    Foo bar baz!

    ================================================ FILE: packages/pug/test/cases/inheritance.extend.mixins.pug ================================================ extend auxiliary/layout.pug mixin article(title) if title h1= title block block content +article("The meaning of life") p Foo bar baz! ================================================ FILE: packages/pug/test/cases/inheritance.extend.pug ================================================ extend auxiliary/layout.pug block head script(src='jquery.js') block content h2 Page p Some content ================================================ FILE: packages/pug/test/cases/inheritance.extend.recursive.html ================================================

    grand-grandparent

    grandparent

    parent

    child

    ================================================ FILE: packages/pug/test/cases/inheritance.extend.recursive.pug ================================================ extends /auxiliary/inheritance.extend.recursive-parent.pug block parent h4 child ================================================ FILE: packages/pug/test/cases/inheritance.extend.whitespace.html ================================================ My Application

    Page

    Some content

    ================================================ FILE: packages/pug/test/cases/inheritance.extend.whitespace.pug ================================================ extend auxiliary/layout.pug block head script(src='jquery.js') block content h2 Page p Some content ================================================ FILE: packages/pug/test/cases/inheritance.html ================================================ My Application

    Page

    Some content

    ================================================ FILE: packages/pug/test/cases/inheritance.pug ================================================ extends auxiliary/layout.pug block head script(src='jquery.js') block content h2 Page p Some content ================================================ FILE: packages/pug/test/cases/inline-tag.html ================================================

    bing foo bong

    bing foo [foo] bong

    bing foo [foo] bong

    #[strong escaped] #[escaped

    ================================================ FILE: packages/pug/test/cases/inline-tag.pug ================================================ p bing #[strong foo] bong p. bing #[strong foo] #[strong= '[foo]'] #[- var foo = 'foo]'] bong p | bing | #[strong foo] | #[strong= '[foo]'] | #[- var foo = 'foo]'] | bong p. \#[strong escaped] \#[#[strong escaped] ================================================ FILE: packages/pug/test/cases/intepolated-elements.html ================================================

    with inline link

    Some text

    Some text with inline link

    ================================================ FILE: packages/pug/test/cases/intepolated-elements.pug ================================================ p #[a.rho(href='#', class='rho--modifier') with inline link] p Some text #[a.rho(href='#', class='rho--modifier')] p Some text #[a.rho(href='#', class='rho--modifier') with inline link] ================================================ FILE: packages/pug/test/cases/interpolated-mixin.html ================================================

    This also works http://www.bing.com so hurrah for Pug

    ================================================ FILE: packages/pug/test/cases/interpolated-mixin.pug ================================================ mixin linkit(url) a(href=url)= url p This also works #[+linkit('http://www.bing.com')] so hurrah for Pug ================================================ FILE: packages/pug/test/cases/interpolation.escape.html ================================================ some #{text} here My ID is {42} ================================================ FILE: packages/pug/test/cases/interpolation.escape.pug ================================================ - var id = 42; foo | some | \#{text} | here | My ID #{"is {" + id + "}"} ================================================ FILE: packages/pug/test/cases/javascript-new-lines.js ================================================ var x = '\n here is some \n new lined text'; ================================================ FILE: packages/pug/test/cases/layout.append.html ================================================ ================================================ FILE: packages/pug/test/cases/layout.append.pug ================================================ extends ../fixtures/append/app-layout.pug block append head script(src='foo.js') script(src='bar.js') ================================================ FILE: packages/pug/test/cases/layout.append.without-block.html ================================================ ================================================ FILE: packages/pug/test/cases/layout.append.without-block.pug ================================================ extends ../fixtures/append-without-block/app-layout.pug append head script(src='foo.js') script(src='bar.js') ================================================ FILE: packages/pug/test/cases/layout.multi.append.prepend.block.html ================================================

    Last prepend must appear at top

    Something prepended to content

    Defined content

    Something appended to content

    Last append must be most last

    ================================================ FILE: packages/pug/test/cases/layout.multi.append.prepend.block.pug ================================================ extends ../fixtures/multi-append-prepend-block/redefine.pug append content p.first.append Something appended to content prepend content p.first.prepend Something prepended to content append content p.last.append Last append must be most last prepend content p.last.prepend Last prepend must appear at top append head script(src='jquery.js') prepend head script(src='foo.js') ================================================ FILE: packages/pug/test/cases/layout.prepend.html ================================================ ================================================ FILE: packages/pug/test/cases/layout.prepend.pug ================================================ extends ../fixtures/prepend/app-layout.pug block prepend head script(src='foo.js') script(src='bar.js') ================================================ FILE: packages/pug/test/cases/layout.prepend.without-block.html ================================================ ================================================ FILE: packages/pug/test/cases/layout.prepend.without-block.pug ================================================ extends ../fixtures/prepend-without-block/app-layout.pug prepend head script(src='foo.js') script(src='bar.js') ================================================ FILE: packages/pug/test/cases/mixin-at-end-of-file.html ================================================

    some awesome content

    ================================================ FILE: packages/pug/test/cases/mixin-at-end-of-file.pug ================================================ include ./auxiliary/mixin-at-end-of-file.pug +slide() p some awesome content ================================================ FILE: packages/pug/test/cases/mixin-block-with-space.html ================================================
    This text should appear
    ================================================ FILE: packages/pug/test/cases/mixin-block-with-space.pug ================================================ mixin m(id) div block +m() | This text should appear ================================================ FILE: packages/pug/test/cases/mixin-hoist.html ================================================

    Pug

    ================================================ FILE: packages/pug/test/cases/mixin-hoist.pug ================================================ mixin foo() h1= title html body +foo ================================================ FILE: packages/pug/test/cases/mixin-via-include.html ================================================

    bar

    ================================================ FILE: packages/pug/test/cases/mixin-via-include.pug ================================================ //- regression test for https://github.com/pugjs/pug/issues/1435 include ../fixtures/mixin-include.pug +bang ================================================ FILE: packages/pug/test/cases/mixin.attrs.html ================================================
    Hello World

    Section 1

    Some important content.

    Section 2

    Even more important content.

    Section 3

    Last content.

    Some final words.

    work

    1

    2

    3

    4

    ================================================ FILE: packages/pug/test/cases/mixin.attrs.pug ================================================ mixin centered(title) div.centered(id=attributes.id) - if (title) h1(class=attributes.class)= title block - if (attributes.href) .footer a(href=attributes.href) Back mixin main(title) div.stretch +centered(title).highlight&attributes(attributes) block mixin bottom div.bottom&attributes(attributes) block body +centered#First Hello World +centered('Section 1')#Second p Some important content. +centered('Section 2')#Third.foo(href='menu.html', class='bar') p Even more important content. +main('Section 3')(href='#') p Last content. +bottom.foo(class='bar', name='end', id='Last', data-attr='baz') p Some final words. +bottom(class=['class1', 'class2']) mixin foo div.thing(attr1='foo', attr2='bar')&attributes(attributes) - var val = '' - var classes = ['foo', 'bar'] +foo(attr3='baz' data-foo=val data-bar!=val class=classes).thunk //- Regression test for #1424 mixin work_filmstrip_item(work) div&attributes(attributes)= work +work_filmstrip_item('work')("data-profile"='profile', "data-creator-name"='name') mixin my-mixin(arg1, arg2, arg3, arg4) p= arg1 p= arg2 p= arg3 p= arg4 +foo( attr3="qux" class="baz" ) +my-mixin( '1', '2', '3', '4' ) ================================================ FILE: packages/pug/test/cases/mixin.block-tag-behaviour.html ================================================

    Foo

    I'm article foo

    Something

    I'm a much longer text-only article, but you can still inline html tags in me if you want.

    ================================================ FILE: packages/pug/test/cases/mixin.block-tag-behaviour.pug ================================================ mixin article(name) section.article h1= name block html body +article('Foo'): p I'm article foo mixin article(name) section.article h1= name p block html body +article('Something'). I'm a much longer text-only article, but you can still inline html tags in me if you want. ================================================ FILE: packages/pug/test/cases/mixin.blocks.html ================================================

    one

    two

    three

    123
    ================================================ FILE: packages/pug/test/cases/mixin.blocks.pug ================================================ mixin form(method, action) form(method=method, action=action) - var csrf_token_from_somewhere = 'hey' input(type='hidden', name='_csrf', value=csrf_token_from_somewhere) block html body +form('GET', '/search') input(type='text', name='query', placeholder='Search') input(type='submit', value='Search') html body +form('POST', '/search') input(type='text', name='query', placeholder='Search') input(type='submit', value='Search') html body +form('POST', '/search') mixin bar() #bar block mixin foo() #foo +bar block +foo p one p two p three mixin baz #baz block +baz()= '123' ================================================ FILE: packages/pug/test/cases/mixin.merge.html ================================================

    One

    Two

    Three

    Four

    One

    Two

    Three

    Four

    One

    Two

    Three

    Four

    One

    Two

    Three

    Four

    One

    Two

    Three

    Four

    One

    Two

    Three

    Four

    One

    Two

    Three

    Four

    One

    Two

    Three

    Four

    ================================================ FILE: packages/pug/test/cases/mixin.merge.pug ================================================ mixin foo p.bar&attributes(attributes) One p.baz.quux&attributes(attributes) Two p&attributes(attributes) Three p.bar&attributes(attributes)(class="baz") Four body +foo.hello +foo#world +foo.hello#world +foo.hello.world +foo(class="hello") +foo.hello(class="world") +foo +foo&attributes({class: "hello"}) ================================================ FILE: packages/pug/test/cases/mixins-unused.html ================================================ ================================================ FILE: packages/pug/test/cases/mixins-unused.pug ================================================ mixin never-called .wtf This isn't something we ever want to output body ================================================ FILE: packages/pug/test/cases/mixins.html ================================================

    Tobi

    This

    is regular, javascript

    • foo
    • bar
    • baz
    • foo
    • bar
    • baz
    This is interpolated
    ================================================ FILE: packages/pug/test/cases/mixins.pug ================================================ mixin comment(title, str) .comment h2= title p.body= str mixin comment (title, str) .comment h2= title p.body= str #user h1 Tobi .comments +comment('This', (('is regular, javascript'))) mixin list ul li foo li bar li baz body +list() + list() mixin foobar(str) div#interpolation= str + 'interpolated' - var suffix = "bar" +#{'foo' + suffix}('This is ') ================================================ FILE: packages/pug/test/cases/mixins.rest-args.html ================================================
    • 1
    • 2
    • 3
    • 4
    ================================================ FILE: packages/pug/test/cases/mixins.rest-args.pug ================================================ mixin list(tag, ...items) #{tag} each item in items li= item +list('ul', 1, 2, 3, 4) ================================================ FILE: packages/pug/test/cases/namespaces.html ================================================ Something ================================================ FILE: packages/pug/test/cases/namespaces.pug ================================================ fb:user:role Something foo(fb:foo='bar') ================================================ FILE: packages/pug/test/cases/nesting.html ================================================
    • a
    • b
      • c
      • d
    • e
    ================================================ FILE: packages/pug/test/cases/nesting.pug ================================================ ul li a li b li ul li c li d li e ================================================ FILE: packages/pug/test/cases/pipeless-comments.html ================================================ ================================================ FILE: packages/pug/test/cases/pipeless-comments.pug ================================================ // .foo .bar .hey ================================================ FILE: packages/pug/test/cases/pipeless-filters.html ================================================
    code sample
    

    Heading

    ================================================ FILE: packages/pug/test/cases/pipeless-filters.pug ================================================ :markdown-it code sample # Heading ================================================ FILE: packages/pug/test/cases/pipeless-tag.html ================================================
      what
    is going on
    ================================================ FILE: packages/pug/test/cases/pipeless-tag.pug ================================================ pre. what is #{'going'} #[| #{'on'}] ================================================ FILE: packages/pug/test/cases/pre.html ================================================
    foo
    bar
    baz
    
    foo
    bar
    baz
    ================================================ FILE: packages/pug/test/cases/pre.pug ================================================ pre. foo bar baz pre code. foo bar baz ================================================ FILE: packages/pug/test/cases/quotes.html ================================================

    "foo"

    'foo'

    ================================================ FILE: packages/pug/test/cases/quotes.pug ================================================ p "foo" p 'foo' ================================================ FILE: packages/pug/test/cases/regression.1794.html ================================================
    ================================================ FILE: packages/pug/test/cases/regression.1794.pug ================================================ extends ./auxiliary/1794-extends.pug block content include ./auxiliary/1794-include.pug ================================================ FILE: packages/pug/test/cases/regression.784.html ================================================
    google.com
    ================================================ FILE: packages/pug/test/cases/regression.784.pug ================================================ - var url = 'http://www.google.com' .url #{url.replace('http://', '').replace(/^www\./, '')} ================================================ FILE: packages/pug/test/cases/script.whitespace.html ================================================ ================================================ FILE: packages/pug/test/cases/script.whitespace.pug ================================================ script. if (foo) { bar(); } ================================================ FILE: packages/pug/test/cases/scripts.html ================================================
    ================================================ FILE: packages/pug/test/cases/scripts.non-js.html ================================================ ================================================ FILE: packages/pug/test/cases/scripts.non-js.pug ================================================ script#user-template(type='text/template') #user h1 <%= user.name %> p <%= user.description %> script#user-template(type='text/template'). if (foo) { bar(); } ================================================ FILE: packages/pug/test/cases/scripts.pug ================================================ script. if (foo) { bar(); } script!= 'foo()' script foo() script div ================================================ FILE: packages/pug/test/cases/self-closing-html.html ================================================
    ================================================ FILE: packages/pug/test/cases/self-closing-html.pug ================================================ doctype html html body br/ ================================================ FILE: packages/pug/test/cases/single-period.html ================================================ . ================================================ FILE: packages/pug/test/cases/single-period.pug ================================================ span . ================================================ FILE: packages/pug/test/cases/some-included.styl ================================================ body padding 10px ================================================ FILE: packages/pug/test/cases/some.md ================================================ Just _some_ markdown **tests**. With new line. ================================================ FILE: packages/pug/test/cases/some.styl ================================================ @import "some-included" ================================================ FILE: packages/pug/test/cases/source.html ================================================ ================================================ FILE: packages/pug/test/cases/source.pug ================================================ html audio(preload='auto', autobuffer, controls) source(src='foo') source(src='bar') ================================================ FILE: packages/pug/test/cases/styles.html ================================================
    ================================================ FILE: packages/pug/test/cases/styles.pug ================================================ html head style. body { padding: 50px; } body div(style='color:red;background:green') div(style={color: 'red', background: 'green'}) div&attributes({style: 'color:red;background:green'}) div&attributes({style: {color: 'red', background: 'green'}}) mixin div() div&attributes(attributes) +div(style='color:red;background:green') +div(style={color: 'red', background: 'green'}) - var bg = 'green'; div(style={color: 'red', background: bg}) div&attributes({style: {color: 'red', background: bg}}) +div(style={color: 'red', background: bg}) ================================================ FILE: packages/pug/test/cases/tag.interpolation.html ================================================

    value

    value

    here ================================================ FILE: packages/pug/test/cases/tag.interpolation.pug ================================================ - var tag = 'p' - var foo = 'bar' #{tag} value #{tag}(foo='bar') value #{foo ? 'a' : 'li'}(something) here mixin item(icon) li if attributes.href a&attributes(attributes) img.icon(src=icon) block else span&attributes(attributes) img.icon(src=icon) block ul +item('contact') Contact +item(href='/contact') Contact ================================================ FILE: packages/pug/test/cases/tags.self-closing.html ================================================ / / / / ================================================ FILE: packages/pug/test/cases/tags.self-closing.pug ================================================ body foo foo(bar='baz') foo/ foo(bar='baz')/ foo / foo(bar='baz') / #{'foo'}/ #{'foo'}(bar='baz')/ #{'foo'} / #{'foo'}(bar='baz') / //- can have a single space after them img //- can have lots of white space after them img #{ 'foo' }/ ================================================ FILE: packages/pug/test/cases/template.html ================================================ ================================================ FILE: packages/pug/test/cases/template.pug ================================================ script(type='text/x-template') article h2 {{title}} p {{description}} script(type='text/x-template'). article h2 {{title}} p {{description}} ================================================ FILE: packages/pug/test/cases/text-block.html ================================================ ================================================ FILE: packages/pug/test/cases/text-block.pug ================================================ label Username: input(type='text', name='user[name]') label Password: input(type='text', name='user[pass]') ================================================ FILE: packages/pug/test/cases/text.html ================================================

    foo bar baz

    foo bar baz

    foo bar baz
    foo
      bar
        baz
    .
    foo
      bar
        baz
    .
    
    foo bar baz . ================================================ FILE: packages/pug/test/cases/text.pug ================================================ option(value='') -- (selected) -- p p. p | foo | bar | | | baz p. foo bar baz . . foo bar baz pre | foo | bar | baz | . pre. foo bar baz . . foo bar baz . ================================================ FILE: packages/pug/test/cases/utf8bom.html ================================================

    "foo"

    ================================================ FILE: packages/pug/test/cases/utf8bom.pug ================================================ p "foo" ================================================ FILE: packages/pug/test/cases/vars.html ================================================ ================================================ FILE: packages/pug/test/cases/vars.pug ================================================ - var foo = 'bar' - var list = [1,2,3] a(class=list, id=foo) ================================================ FILE: packages/pug/test/cases/while.html ================================================
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    ================================================ FILE: packages/pug/test/cases/while.pug ================================================ - var x = 1; ul while x < 10 - x++; li= x ================================================ FILE: packages/pug/test/cases/xml.html ================================================ http://google.com ================================================ FILE: packages/pug/test/cases/xml.pug ================================================ doctype xml category(term='some term')/ link http://google.com ================================================ FILE: packages/pug/test/cases/yield-before-conditional-head.html ================================================ ================================================ FILE: packages/pug/test/cases/yield-before-conditional-head.pug ================================================ head script(src='/jquery.js') yield if false script(src='/jquery.ui.js') ================================================ FILE: packages/pug/test/cases/yield-before-conditional.html ================================================ ================================================ FILE: packages/pug/test/cases/yield-before-conditional.pug ================================================ html body include yield-before-conditional-head.pug script(src='/caustic.js') script(src='/app.js') ================================================ FILE: packages/pug/test/cases/yield-head.html ================================================ ================================================ FILE: packages/pug/test/cases/yield-head.pug ================================================ head script(src='/jquery.js') yield script(src='/jquery.ui.js') ================================================ FILE: packages/pug/test/cases/yield-title-head.html ================================================ ================================================ FILE: packages/pug/test/cases/yield-title-head.pug ================================================ head title yield script(src='/jquery.js') script(src='/jquery.ui.js') ================================================ FILE: packages/pug/test/cases/yield-title.html ================================================ My Title ================================================ FILE: packages/pug/test/cases/yield-title.pug ================================================ html body include yield-title-head.pug | My Title ================================================ FILE: packages/pug/test/cases/yield.html ================================================ ================================================ FILE: packages/pug/test/cases/yield.pug ================================================ html body include yield-head.pug script(src='/caustic.js') script(src='/app.js') ================================================ FILE: packages/pug/test/cases-es2015/attr.html ================================================
    ================================================ FILE: packages/pug/test/cases-es2015/attr.pug ================================================ - var avatar = '219b77f9d21de75e81851b6b886057c7' div.avatar-div(style=`background-image: url(https://www.gravatar.com/avatar/${avatar})`) ================================================ FILE: packages/pug/test/dependencies/dependency1.pug ================================================ strong dependency1 ================================================ FILE: packages/pug/test/dependencies/dependency2.pug ================================================ include dependency3.pug ================================================ FILE: packages/pug/test/dependencies/dependency3.pug ================================================ strong dependency3 ================================================ FILE: packages/pug/test/dependencies/extends1.pug ================================================ extends dependency1.pug ================================================ FILE: packages/pug/test/dependencies/extends2.pug ================================================ extends dependency2.pug ================================================ FILE: packages/pug/test/dependencies/include1.pug ================================================ include dependency1.pug ================================================ FILE: packages/pug/test/dependencies/include2.pug ================================================ include dependency2.pug ================================================ FILE: packages/pug/test/duplicate-block/__snapshots__/index.test.js.snap ================================================ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`layout with duplicate block 1`] = `"
    Hello World
    "`; exports[`layout with duplicate block 2`] = `"
    Hello World
    "`; ================================================ FILE: packages/pug/test/duplicate-block/index.pug ================================================ extends ./layout-with-duplicate-block.pug block content div Hello World ================================================ FILE: packages/pug/test/duplicate-block/index.test.js ================================================ const pug = require('../../'); test('layout with duplicate block', () => { const outputWithAjax = pug.renderFile(__dirname + '/index.pug', {ajax: true}); const outputWithoutAjax = pug.renderFile(__dirname + '/index.pug', { ajax: false, }); expect(outputWithAjax).toMatchSnapshot(); expect(outputWithoutAjax).toMatchSnapshot(); }); ================================================ FILE: packages/pug/test/duplicate-block/layout-with-duplicate-block.pug ================================================ if ajax block content else doctype html html head body block content ================================================ FILE: packages/pug/test/eachOf/__snapshots__/index.test.js.snap ================================================ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`Proper Usage Brackets 1`] = `"
  • a
  • b
  • foo
  • bar
  • "`; exports[`Proper Usage No Brackets 1`] = `"
  • a
  • b
  • foo
  • bar
  • "`; ================================================ FILE: packages/pug/test/eachOf/error/left-side.pug ================================================ each [key, val of users li= key li= val ================================================ FILE: packages/pug/test/eachOf/error/no-brackets.pug ================================================ each key, val of users li= key li= val ================================================ FILE: packages/pug/test/eachOf/error/one-val.pug ================================================ each [key] of users li= key li= val ================================================ FILE: packages/pug/test/eachOf/error/right-side.pug ================================================ each key, val] of users li= key li= val ================================================ FILE: packages/pug/test/eachOf/index.test.js ================================================ const pug = require('../../'); describe('Inproper Usage', () => { test('Only left-side bracket', () => { expect(() => pug.compileFile(__dirname + '/error/left-side.pug')).toThrow( 'The value variable for each must either be a valid identifier (e.g. `item`) or a pair of identifiers in square brackets (e.g. `[key, value]`).' ); }); test('Only right-side bracket', () => { expect(() => pug.compileFile(__dirname + '/error/right-side.pug')).toThrow( 'The value variable for each must either be a valid identifier (e.g. `item`) or a pair of identifiers in square brackets (e.g. `[key, value]`).' ); }); test('Only one value inside brackets', () => { expect(() => pug.compileFile(__dirname + '/error/one-val.pug')).toThrow( 'The value variable for each must either be a valid identifier (e.g. `item`) or a pair of identifiers in square brackets (e.g. `[key, value]`).' ); }); test('No brackets', () => { expect(() => pug.compileFile(__dirname + '/error/no-brackets.pug')).toThrow( 'The value variable for each must either be a valid identifier (e.g. `item`) or a pair of identifiers in square brackets (e.g. `[key, value]`).' ); }); }); describe('Proper Usage', () => { test('Brackets', () => { const html = pug.renderFile(__dirname + '/passing/brackets.pug', { users: new Map([ ['a', 'b'], ['foo', 'bar'], ]), }); expect(html).toMatchSnapshot(); }); test('No Brackets', () => { const html = pug.renderFile(__dirname + '/passing/no-brackets.pug', { users: new Map([ ['a', 'b'], ['foo', 'bar'], ]), }); expect(html).toMatchSnapshot(); }); }); ================================================ FILE: packages/pug/test/eachOf/passing/brackets.pug ================================================ each [key, val] of users li= key li= val ================================================ FILE: packages/pug/test/eachOf/passing/no-brackets.pug ================================================ each data of users li= data[0] li= data[1] ================================================ FILE: packages/pug/test/error.reporting.test.js ================================================ /** * Module dependencies. */ var pug = require('../'); var assert = require('assert'); var fs = require('fs'); // Shortcut function getError(str, options) { try { pug.render(str, options); } catch (ex) { return ex; } throw new Error('Input was supposed to result in an error.'); } function getFileError(name, options) { try { pug.renderFile(name, options); } catch (ex) { return ex; } throw new Error('Input was supposed to result in an error.'); } describe('error reporting', function() { describe('compile time errors', function() { describe('with no filename', function() { it('includes detail of where the error was thrown', function() { var err = getError('foo('); expect(err.message).toMatch(/Pug:1/); expect(err.message).toMatch(/foo\(/); }); }); describe('with a filename', function() { it('includes detail of where the error was thrown including the filename', function() { var err = getError('foo(', {filename: 'test.pug'}); expect(err.message).toMatch(/test\.pug:1/); expect(err.message).toMatch(/foo\(/); }); }); describe('with a layout without block declaration (syntax)', function() { it('includes detail of where the error was thrown including the filename', function() { var err = getFileError( __dirname + '/fixtures/compile.with.layout.syntax.error.pug', {} ); expect(err.message).toMatch(/[\\\/]layout.syntax.error.pug:2/); expect(err.message).toMatch(/foo\(/); }); }); describe('with a layout without block declaration (locals)', function() { it('includes detail of where the error was thrown including the filename', function() { var err = getFileError( __dirname + '/fixtures/compile.with.layout.locals.error.pug', {} ); expect(err.message).toMatch(/[\\\/]layout.locals.error.pug:2/); expect(err.message).toMatch(/is not a function/); }); }); describe('with a include (syntax)', function() { it('includes detail of where the error was thrown including the filename', function() { var err = getFileError( __dirname + '/fixtures/compile.with.include.syntax.error.pug', {} ); expect(err.message).toMatch(/[\\\/]include.syntax.error.pug:2/); expect(err.message).toMatch(/foo\(/); }); }); describe('with a include (locals)', function() { it('includes detail of where the error was thrown including the filename', function() { var err = getFileError( __dirname + '/fixtures/compile.with.include.locals.error.pug', {} ); expect(err.message).toMatch(/[\\\/]include.locals.error.pug:2/); expect(err.message).toMatch(/foo\(/); }); it('handles compileDebug option properly', function() { var err = getFileError( __dirname + '/fixtures/compile.with.include.locals.error.pug', { compileDebug: true, } ); expect(err.message).toMatch(/[\\\/]include.locals.error.pug:2/); expect(err.message).toMatch(/foo is not a function/); }); }); describe('with a layout (without block) with an include (syntax)', function() { it('includes detail of where the error was thrown including the filename', function() { var err = getFileError( __dirname + '/fixtures/compile.with.layout.with.include.syntax.error.pug', {} ); expect(err.message).toMatch(/[\\\/]include.syntax.error.pug:2/); expect(err.message).toMatch(/foo\(/); }); }); describe('with a layout (without block) with an include (locals)', function() { it('includes detail of where the error was thrown including the filename', function() { var err = getFileError( __dirname + '/fixtures/compile.with.layout.with.include.locals.error.pug', {} ); expect(err.message).toMatch(/[\\\/]include.locals.error.pug:2/); expect(err.message).toMatch(/foo\(/); }); }); describe('block that is never actually used', function() { it('includes detail of where the error was thrown including the filename', function() { var err = getFileError( __dirname + '/fixtures/invalid-block-in-extends.pug', {} ); expect(err.message).toMatch(/invalid-block-in-extends.pug:6/); expect(err.message).toMatch(/content/); }); }); describe('Unexpected character', function() { it('includes details of where the error was thrown', function() { var err = getError('ul?', {}); expect(err.message).toMatch(/unexpected text \"\?\"/); }); }); describe('Include filtered', function() { it('includes details of where the error was thrown', function() { var err = getError('include:verbatim()!', {}); assert(err.message.indexOf('unexpected text "!"') !== -1); var err = getError('include:verbatim ', {}); assert(err.message.indexOf('missing path for include') !== -1); }); }); describe('mixin block followed by a lot of blank lines', function() { it('reports the correct line number', function() { var err = getError('mixin test\n block\n\ndiv()Test'); var line = /Pug\:(\d+)/.exec(err.message); assert(line, 'Line number must be included in error message'); assert( line[1] === '4', 'The error should be reported on line 4, not line ' + line[1] ); }); }); }); describe('runtime errors', function() { describe('with no filename and `compileDebug` left undefined', function() { it('just reports the line number', function() { var sentinel = new Error('sentinel'); var err = getError('-foo()', { foo: function() { throw sentinel; }, }); expect(err.message).toMatch(/on line 1/); }); }); describe('with no filename and `compileDebug` set to `true`', function() { it('includes detail of where the error was thrown', function() { var sentinel = new Error('sentinel'); var err = getError('-foo()', { foo: function() { throw sentinel; }, compileDebug: true, }); expect(err.message).toMatch(/Pug:1/); expect(err.message).toMatch(/-foo\(\)/); }); }); describe('with a filename that does not correspond to a real file and `compileDebug` left undefined', function() { it('just reports the line number', function() { var sentinel = new Error('sentinel'); var err = getError('-foo()', { foo: function() { throw sentinel; }, filename: 'fake.pug', }); expect(err.message).toMatch(/on line 1/); }); }); describe('with a filename that corresponds to a real file and `compileDebug` left undefined', function() { it('includes detail of where the error was thrown including the filename', function() { var sentinel = new Error('sentinel'); var path = __dirname + '/fixtures/runtime.error.pug'; var err = getError(fs.readFileSync(path, 'utf8'), { foo: function() { throw sentinel; }, filename: path, }); expect(err.message).toMatch(/fixtures[\\\/]runtime\.error\.pug:1/); expect(err.message).toMatch(/-foo\(\)/); }); }); describe('in a mixin', function() { it('includes detail of where the error was thrown including the filename', function() { var err = getFileError( __dirname + '/fixtures/runtime.with.mixin.error.pug', {} ); expect(err.message).toMatch(/mixin.error.pug:2/); expect(err.message).toMatch(/Cannot read property 'length' of null/); }); }); describe('in a layout', function() { it('includes detail of where the error was thrown including the filename', function() { var err = getFileError( __dirname + '/fixtures/runtime.layout.error.pug', {} ); expect(err.message).toMatch(/layout.with.runtime.error.pug:3/); expect(err.message).toMatch( /Cannot read property 'length' of undefined/ ); }); }); }); describe('deprecated features', function() { it('warns about element-with-multiple-attributes', function() { var consoleWarn = console.warn; var log = ''; console.warn = function(str) { log += str; }; var res = pug.renderFile( __dirname + '/fixtures/element-with-multiple-attributes.pug' ); console.warn = consoleWarn; expect(log).toMatch(/element-with-multiple-attributes.pug, line 1:/); expect(log).toMatch( /You should not have pug tags with multiple attributes/ ); expect(res).toBe('
    '); }); }); describe("if you throw something that isn't an error", function() { it('just rethrows without modification', function() { var err = getError('- throw "foo"'); expect(err).toBe('foo'); }); }); describe('import without a filename for a basedir', function() { it('throws an error', function() { var err = getError('include foo.pug'); expect(err.message).toMatch(/the "filename" option is required to use/); var err = getError('include /foo.pug'); expect(err.message).toMatch(/the "basedir" option is required to use/); }); }); }); ================================================ FILE: packages/pug/test/examples.test.js ================================================ 'use strict'; var fs = require('fs'); var pug = require('../'); describe('examples', function() { fs.readdirSync(__dirname + '/../examples').forEach(function(example) { if (/\.js$/.test(example)) { it(example + ' does not throw any error', function() { var log = console.log; var err = console.error; console.log = function() {}; console.error = function() {}; try { require('../examples/' + example); } finally { console.log = log; console.error = err; } }); } }); }); ================================================ FILE: packages/pug/test/extends-not-top-level/default.pug ================================================ body block content ================================================ FILE: packages/pug/test/extends-not-top-level/duplicate.pug ================================================ extends default extends default ================================================ FILE: packages/pug/test/extends-not-top-level/index.pug ================================================ mixin content if bar extends default block content block else block +content h1 Hello! ================================================ FILE: packages/pug/test/extends-not-top-level/index.test.js ================================================ const pug = require('../../'); // regression test for #2404 test('extends not top level should throw an error', () => { expect(() => pug.compileFile(__dirname + '/index.pug')).toThrow( 'Declaration of template inheritance ("extends") should be the first thing in the file. There can only be one extends statement per file.' ); }); test('duplicate extends should throw an error', () => { expect(() => pug.compileFile(__dirname + '/duplicate.pug')).toThrow( 'Declaration of template inheritance ("extends") should be the first thing in the file. There can only be one extends statement per file.' ); }); ================================================ FILE: packages/pug/test/fixtures/append/app-layout.pug ================================================ extends layout block append head script(src='app.js') ================================================ FILE: packages/pug/test/fixtures/append/layout.pug ================================================ html block head script(src='vendor/jquery.js') script(src='vendor/caustic.js') body block body ================================================ FILE: packages/pug/test/fixtures/append/page.html ================================================ ================================================ FILE: packages/pug/test/fixtures/append/page.pug ================================================ extends app-layout block append head script(src='foo.js') script(src='bar.js') ================================================ FILE: packages/pug/test/fixtures/append-without-block/app-layout.pug ================================================ extends layout.pug append head script(src='app.js') ================================================ FILE: packages/pug/test/fixtures/append-without-block/layout.pug ================================================ html block head script(src='vendor/jquery.js') script(src='vendor/caustic.js') body block body ================================================ FILE: packages/pug/test/fixtures/append-without-block/page.pug ================================================ extends app-layout.pug append head script(src='foo.js') script(src='bar.js') ================================================ FILE: packages/pug/test/fixtures/compile.with.include.locals.error.pug ================================================ include include.locals.error.pug ================================================ FILE: packages/pug/test/fixtures/compile.with.include.syntax.error.pug ================================================ include include.syntax.error.pug ================================================ FILE: packages/pug/test/fixtures/compile.with.layout.locals.error.pug ================================================ extends layout.locals.error.pug ================================================ FILE: packages/pug/test/fixtures/compile.with.layout.syntax.error.pug ================================================ extends layout.syntax.error.pug ================================================ FILE: packages/pug/test/fixtures/compile.with.layout.with.include.locals.error.pug ================================================ extends compile.with.include.locals.error.pug ================================================ FILE: packages/pug/test/fixtures/compile.with.layout.with.include.syntax.error.pug ================================================ extends compile.with.include.syntax.error.pug ================================================ FILE: packages/pug/test/fixtures/element-with-multiple-attributes.pug ================================================ div(attr='val')(foo='bar') ================================================ FILE: packages/pug/test/fixtures/include.locals.error.pug ================================================ = foo() ================================================ FILE: packages/pug/test/fixtures/include.syntax.error.pug ================================================ = foo( ================================================ FILE: packages/pug/test/fixtures/invalid-block-in-extends.pug ================================================ extends ./layout.pug block title title My Article block contents // oops, that's not a block ================================================ FILE: packages/pug/test/fixtures/issue-1593/include-layout.pug ================================================ .included-layout block include-body ================================================ FILE: packages/pug/test/fixtures/issue-1593/include.pug ================================================ extends ./include-layout.pug block include-body .include-body ================================================ FILE: packages/pug/test/fixtures/issue-1593/index.pug ================================================ extends ./layout.pug block body-a .body-a block body-b .body-b include ./include.pug ================================================ FILE: packages/pug/test/fixtures/issue-1593/layout.pug ================================================ .layout-body block body-a block body-b ================================================ FILE: packages/pug/test/fixtures/layout.locals.error.pug ================================================ = foo() ================================================ FILE: packages/pug/test/fixtures/layout.pug ================================================ doctype html html head block title body block body ================================================ FILE: packages/pug/test/fixtures/layout.syntax.error.pug ================================================ = foo( ================================================ FILE: packages/pug/test/fixtures/layout.with.runtime.error.pug ================================================ html body = foo.length block content ================================================ FILE: packages/pug/test/fixtures/mixin-include.pug ================================================ mixin bang +foo mixin foo p bar ================================================ FILE: packages/pug/test/fixtures/mixin.error.pug ================================================ mixin mixin-with-error(foo) - foo.length ================================================ FILE: packages/pug/test/fixtures/multi-append-prepend-block/redefine.pug ================================================ extends root.pug block content .content | Defined content ================================================ FILE: packages/pug/test/fixtures/multi-append-prepend-block/root.pug ================================================ block content | default content block head script(src='/app.js') ================================================ FILE: packages/pug/test/fixtures/perf.pug ================================================ .data ol.sortable#contents each item in report if (!item.parent) div li.chapter(data-ref= item.id) a(href='/admin/report/detail/' + item.id) = item.name - var chp = item.id ol.sortable each item in report if (item.parent === chp && item.type === 'section') div li.section(data-ref= item.id) a(href='/admin/report/detail/' + item.id) = item.name - var sec = item.id ol.sortable each item in report if (item.parent === sec && item.type === 'page') div li.page(data-ref= item.id) a(href='/admin/report/detail/' + item.id) = item.name - var page = item.id ol.sortable each item in report if (item.parent === page && item.type === 'subpage') div li.subpage(data-ref= item.id) a(href='/admin/report/detail/' + item.id) = item.name ================================================ FILE: packages/pug/test/fixtures/prepend/app-layout.pug ================================================ extends layout.pug block prepend head script(src='app.js') ================================================ FILE: packages/pug/test/fixtures/prepend/layout.pug ================================================ html block head script(src='vendor/jquery.js') script(src='vendor/caustic.js') body block body ================================================ FILE: packages/pug/test/fixtures/prepend/page.html ================================================ ================================================ FILE: packages/pug/test/fixtures/prepend/page.pug ================================================ extends app-layout.pug block prepend head script(src='foo.js') script(src='bar.js') ================================================ FILE: packages/pug/test/fixtures/prepend-without-block/app-layout.pug ================================================ extends layout.pug prepend head script(src='app.js') ================================================ FILE: packages/pug/test/fixtures/prepend-without-block/layout.pug ================================================ html block head script(src='vendor/jquery.js') script(src='vendor/caustic.js') body block body ================================================ FILE: packages/pug/test/fixtures/prepend-without-block/page.html ================================================ ================================================ FILE: packages/pug/test/fixtures/prepend-without-block/page.pug ================================================ extends app-layout.pug prepend head script(src='foo.js') script(src='bar.js') ================================================ FILE: packages/pug/test/fixtures/runtime.error.pug ================================================ -foo() ================================================ FILE: packages/pug/test/fixtures/runtime.layout.error.pug ================================================ extends layout.with.runtime.error.pug block content | some content ================================================ FILE: packages/pug/test/fixtures/runtime.with.mixin.error.pug ================================================ include mixin.error.pug +mixin-with-error(null) ================================================ FILE: packages/pug/test/fixtures/scripts.pug ================================================ script(src='/jquery.js') script(src='/caustic.js') ================================================ FILE: packages/pug/test/markdown-it/comment.md ================================================

    Hello World!

    ================================================ FILE: packages/pug/test/markdown-it/index.test.js ================================================ const pug = require('../../'); test('inline and include markdow-it should match ', () => { const outputMarkdownInline = pug.renderFile( __dirname + '/layout-markdown-inline.pug' ); const outputMarkdownIncludes = pug.renderFile( __dirname + '/layout-markdown-include.pug' ); expect(outputMarkdownIncludes).toEqual(outputMarkdownInline); }); ================================================ FILE: packages/pug/test/markdown-it/layout-markdown-include.pug ================================================ include:markdown-it(html=true) comment.md ================================================ FILE: packages/pug/test/markdown-it/layout-markdown-inline.pug ================================================ :markdown-it(html=true)

    Hello World!

    ================================================ FILE: packages/pug/test/plugins.test.js ================================================ const pug = require('../'); test('#3295 - lexer plugins should be used in tag interpolation', () => { const lex = { advance(lexer) { if ('~' === lexer.input.charAt(0)) { lexer.tokens.push(lexer.tok('text', 'twiddle-dee-dee')); lexer.consume(1); lexer.incrementColumn(1); return true; } }, }; const input = 'p Look at #[~]'; const expected = '

    Look at twiddle-dee-dee

    '; const output = pug.render(input, {plugins: [{lex}]}); expect(output).toEqual(expected); }); ================================================ FILE: packages/pug/test/pug.test.js ================================================ 'use strict'; var assert = require('assert'); var fs = require('fs'); var path = require('path'); var pug = require('../'); var perfTest = fs.readFileSync(__dirname + '/fixtures/perf.pug', 'utf8'); try { fs.mkdirSync(__dirname + '/temp'); } catch (ex) { if (ex.code !== 'EEXIST') { throw ex; } } describe('pug', function() { describe('unit tests with .render()', function() { it('should support doctypes', function() { assert.equal( '', pug.render('doctype xml') ); assert.equal('', pug.render('doctype html')); assert.equal('', pug.render('doctype foo bar baz')); assert.equal('', pug.render('doctype html')); assert.equal('', pug.render('doctype', {doctype: 'html'})); assert.equal( '', pug.render('doctype html', {doctype: 'xml'}) ); assert.equal('', pug.render('html')); assert.equal( '', pug.render('html', {doctype: 'html'}) ); assert.equal( '', pug.render('doctype html PUBLIC "-//W3C//DTD XHTML Basic 1.1//EN') ); }); it('should support Buffers', function() { assert.equal('

    foo

    ', pug.render(Buffer.from('p foo'))); }); it('should support line endings', function() { var src = ['p', 'div', 'img']; var html = ['

    ', '
    ', ''].join(''); assert.equal(html, pug.render(src.join('\n'))); assert.equal(html, pug.render(src.join('\r'))); assert.equal(html, pug.render(src.join('\r\n'))); html = ['

    ', '
    ', ''].join(''); assert.equal(html, pug.render(src.join('\n'), {doctype: 'html'})); assert.equal(html, pug.render(src.join('\r'), {doctype: 'html'})); assert.equal(html, pug.render(src.join('\r\n'), {doctype: 'html'})); }); it('should support single quotes', function() { assert.equal("

    'foo'

    ", pug.render("p 'foo'")); assert.equal("

    'foo'

    ", pug.render("p\n | 'foo'")); assert.equal( '', pug.render("- var path = 'foo';\na(href='/' + path)") ); }); it('should support block-expansion', function() { assert.equal( '
  • foo
  • bar
  • baz
  • ', pug.render('li: a foo\nli: a bar\nli: a baz') ); assert.equal( '
  • foo
  • bar
  • baz
  • ', pug.render('li.first: a foo\nli: a bar\nli: a baz') ); assert.equal( '
    baz
    ', pug.render('.foo: .bar baz') ); }); it('should support tags', function() { var str = ['p', 'div', 'img', 'br/'].join('\n'); var html = ['

    ', '
    ', '', '
    '].join(''); assert.equal(html, pug.render(str), 'Test basic tags'); assert.equal( '', pug.render('fb:foo-bar'), 'Test hyphens' ); assert.equal( '
    ', pug.render('div.something'), 'Test classes' ); assert.equal( '
    ', pug.render('div#something'), 'Test ids' ); assert.equal( '
    ', pug.render('.something'), 'Test stand-alone classes' ); assert.equal( '
    ', pug.render('#something'), 'Test stand-alone ids' ); assert.equal('
    ', pug.render('#foo.bar')); assert.equal('
    ', pug.render('.bar#foo')); assert.equal( '
    ', pug.render('div#foo(class="bar")') ); assert.equal( '
    ', pug.render('div(class="bar")#foo') ); assert.equal( '
    ', pug.render('div(id="bar").foo') ); assert.equal( '
    ', pug.render('div.foo.bar.baz') ); assert.equal( '
    ', pug.render('div(class="foo").bar.baz') ); assert.equal( '
    ', pug.render('div.foo(class="bar").baz') ); assert.equal( '
    ', pug.render('div.foo.bar(class="baz")') ); assert.equal('
    ', pug.render('div.a-b2')); assert.equal('
    ', pug.render('div.a_b2')); assert.equal('', pug.render('fb:user')); assert.equal('', pug.render('fb:user:role')); assert.equal( '', pug.render('colgroup\n col.test') ); }); it('should support nested tags', function() { var str = [ 'ul', ' li a', ' li b', ' li', ' ul', ' li c', ' li d', ' li e', ].join('\n'); var html = [ '
      ', '
    • a
    • ', '
    • b
    • ', '
      • c
      • d
    • ', '
    • e
    • ', '
    ', ].join(''); assert.equal(html, pug.render(str)); var str = ['a(href="#")', ' | foo ', ' | bar ', ' | baz'].join('\n'); assert.equal('foo \nbar \nbaz', pug.render(str)); var str = ['ul', ' li one', ' ul', ' | two', ' li three'].join( '\n' ); var html = [ '
      ', '
    • one
    • ', '
        two', '
      • three
      • ', '
      ', '
    ', ].join(''); assert.equal(html, pug.render(str)); }); it('should support variable length newlines', function() { var str = [ 'ul', ' li a', ' ', ' li b', ' ', ' ', ' li', ' ul', ' li c', '', ' li d', ' li e', ].join('\n'); var html = [ '
      ', '
    • a
    • ', '
    • b
    • ', '
      • c
      • d
    • ', '
    • e
    • ', '
    ', ].join(''); assert.equal(html, pug.render(str)); }); it('should support tab conversion', function() { var str = [ 'ul', '\tli a', '\t', '\tli b', '\t\t', '\t\t\t\t\t\t', '\tli', '\t\tul', '\t\t\tli c', '', '\t\t\tli d', '\tli e', ].join('\n'); var html = [ '
      ', '
    • a
    • ', '
    • b
    • ', '
      • c
      • d
    • ', '
    • e
    • ', '
    ', ].join(''); assert.equal(html, pug.render(str)); }); it('should support newlines', function() { var str = [ 'ul', ' li a', ' ', ' ', '', ' ', ' li b', ' li', ' ', ' ', ' ', ' ul', ' ', ' li c', ' li d', ' li e', ].join('\n'); var html = [ '
      ', '
    • a
    • ', '
    • b
    • ', '
      • c
      • d
    • ', '
    • e
    • ', '
    ', ].join(''); assert.equal(html, pug.render(str)); var str = [ 'html', ' ', ' head', ' != "test"', ' ', ' ', ' ', ' body', ].join('\n'); var html = [ '', '', 'test', '', '', '', ].join(''); assert.equal(html, pug.render(str)); assert.equal( 'something', pug.render('foo\n= "something"\nbar') ); assert.equal( 'somethingelse', pug.render('foo\n= "something"\nbar\n= "else"') ); }); it('should support text', function() { assert.equal('foo\nbar\nbaz', pug.render('| foo\n| bar\n| baz')); assert.equal('foo \nbar \nbaz', pug.render('| foo \n| bar \n| baz')); assert.equal('(hey)', pug.render('| (hey)')); assert.equal('some random text', pug.render('| some random text')); assert.equal(' foo', pug.render('| foo')); assert.equal(' foo ', pug.render('| foo ')); assert.equal(' foo \n bar ', pug.render('| foo \n| bar ')); }); it('should support pipe-less text', function() { assert.equal( '
    ', pug.render('pre\n code\n foo\n\n bar') ); assert.equal('

    foo\n\nbar

    ', pug.render('p.\n foo\n\n bar')); assert.equal( '

    foo\n\n\n\nbar

    ', pug.render('p.\n foo\n\n\n\n bar') ); assert.equal( '

    foo\n bar\nfoo

    ', pug.render('p.\n foo\n bar\n foo') ); assert.equal( '', pug.render('script.\n s.parentNode.insertBefore(g,s)\n') ); assert.equal( '', pug.render('script.\n s.parentNode.insertBefore(g,s)') ); }); it('should support tag text', function() { assert.equal('

    some random text

    ', pug.render('p some random text')); assert.equal( '

    clickGoogle.

    ', pug.render('p\n | click\n a Google\n | .') ); assert.equal('

    (parens)

    ', pug.render('p (parens)')); assert.equal( '

    (parens)

    ', pug.render('p(foo="bar") (parens)') ); assert.equal( '', pug.render('option(value="") -- (optional) foo --') ); }); it('should support tag text block', function() { assert.equal( '

    foo \nbar \nbaz

    ', pug.render('p\n | foo \n | bar \n | baz') ); assert.equal( '', pug.render('label\n | Password:\n input') ); assert.equal( '', pug.render('label Password:\n input') ); }); it('should support tag text interpolation', function() { assert.equal( 'yo, pug is cool', pug.render('| yo, #{name} is cool\n', {name: 'pug'}) ); assert.equal( '

    yo, pug is cool

    ', pug.render('p yo, #{name} is cool', {name: 'pug'}) ); assert.equal( 'yo, pug is cool', pug.render('| yo, #{name || "pug"} is cool', {name: null}) ); assert.equal( "yo, 'pug' is cool", pug.render('| yo, #{name || "\'pug\'"} is cool', {name: null}) ); assert.equal( 'foo <script> bar', pug.render('| foo #{code} bar', {code: '', '', '', ].join(''); assert.equal(html, pug.render(str)); }); it('should support comments', function() { // Regular var str = ['//foo', 'p bar'].join('\n'); var html = ['', '

    bar

    '].join(''); assert.equal(html, pug.render(str)); // Between tags var str = ['p foo', '// bar ', 'p baz'].join('\n'); var html = ['

    foo

    ', '', '

    baz

    '].join(''); assert.equal(html, pug.render(str)); // Quotes var str = "", js = "// script(src: '/js/validate.js') "; assert.equal(str, pug.render(js)); }); it('should support unbuffered comments', function() { var str = ['//- foo', 'p bar'].join('\n'); var html = ['

    bar

    '].join(''); assert.equal(html, pug.render(str)); var str = ['p foo', '//- bar ', 'p baz'].join('\n'); var html = ['

    foo

    ', '

    baz

    '].join(''); assert.equal(html, pug.render(str)); }); it('should support literal html', function() { assert.equal( '', pug.render('') ); }); it('should support code', function() { assert.equal('test', pug.render('!= "test"')); assert.equal('test', pug.render('= "test"')); assert.equal('test', pug.render('- var foo = "test"\n=foo')); assert.equal( 'footestbar', pug.render('- var foo = "test"\n| foo\nem= foo\n| bar') ); assert.equal( 'test

    something

    ', pug.render('!= "test"\nh2 something') ); var str = ['- var foo = "', pug.render(str, {filename: __dirname + '/pug.test.js'}) ); }); it('should not fail on js newlines', function() { assert.equal('

    foo\u2028bar

    ', pug.render('p foo\u2028bar')); assert.equal('

    foo\u2029bar

    ', pug.render('p foo\u2029bar')); }); it('should display error line number correctly up to token level', function() { var str = [ 'p.', ' Lorem ipsum dolor sit amet, consectetur', ' adipisicing elit, sed do eiusmod tempor', ' incididunt ut labore et dolore magna aliqua.', 'p.', ' Ut enim ad minim veniam, quis nostrud', ' exercitation ullamco laboris nisi ut aliquip', ' ex ea commodo consequat.', 'p.', ' Duis aute irure dolor in reprehenderit', ' in voluptate velit esse cillum dolore eu', ' fugiat nulla pariatur.', 'a(href="#" Next', ].join('\n'); var errorLocation = function(str) { try { pug.render(str); } catch (err) { return err.message.split('\n')[0]; } }; assert.equal(errorLocation(str), 'Pug:13:16'); }); }); describe('.compileFile()', function() { it('does not produce warnings for issue-1593', function() { pug.compileFile(__dirname + '/fixtures/issue-1593/index.pug'); }); it('should support caching (pass 1)', function() { fs.writeFileSync(__dirname + '/temp/input-compileFile.pug', '.foo bar'); var fn = pug.compileFile(__dirname + '/temp/input-compileFile.pug', { cache: true, }); var expected = '
    bar
    '; assert(fn() === expected); }); it('should support caching (pass 2)', function() { // Poison the input file fs.writeFileSync( __dirname + '/temp/input-compileFile.pug', '.big fat hen' ); var fn = pug.compileFile(__dirname + '/temp/input-compileFile.pug', { cache: true, }); var expected = '
    bar
    '; assert(fn() === expected); }); }); describe('.render()', function() { it('should support .pug.render(str, fn)', function() { pug.render('p foo bar', function(err, str) { assert.ok(!err); assert.equal('

    foo bar

    ', str); }); }); it('should support .pug.render(str, options, fn)', function() { pug.render('p #{foo}', {foo: 'bar'}, function(err, str) { assert.ok(!err); assert.equal('

    bar

    ', str); }); }); it('should support .pug.render(str, options, fn) cache', function() { pug.render('p bar', {cache: true}, function(err, str) { assert.ok( /the "filename" option is required for caching/.test(err.message) ); }); pug.render('p foo bar', {cache: true, filename: 'test'}, function( err, str ) { assert.ok(!err); assert.equal('

    foo bar

    ', str); }); }); }); describe('.compile()', function() { it('should support .compile()', function() { var fn = pug.compile('p foo'); assert.equal('

    foo

    ', fn()); }); it('should support .compile() locals', function() { var fn = pug.compile('p= foo'); assert.equal('

    bar

    ', fn({foo: 'bar'})); }); it("should support .compile() locals in 'self' hash", function() { var fn = pug.compile('p= self.foo', {self: true}); assert.equal('

    bar

    ', fn({foo: 'bar'})); }); it('should support .compile() no debug', function() { var fn = pug.compile('p foo\np #{bar}', {compileDebug: false}); assert.equal('

    foo

    baz

    ', fn({bar: 'baz'})); }); it('should support .compile() no debug and global helpers', function() { var fn = pug.compile('p foo\np #{bar}', { compileDebug: false, helpers: 'global', }); assert.equal('

    foo

    baz

    ', fn({bar: 'baz'})); }); it('should be reasonably fast', function() { pug.compile(perfTest, {}); }); it('allows trailing space (see #1586)', function() { var res = pug.render('ul \n li An Item'); assert.equal('
    • An Item
    ', res); }); }); describe('.compileClient()', function() { it('should support pug.compileClient(str)', function() { var src = fs.readFileSync(__dirname + '/cases/basic.pug'); var expected = fs .readFileSync(__dirname + '/cases/basic.html', 'utf8') .replace(/\s/g, ''); var fn = pug.compileClient(src); fn = Function('pug', fn.toString() + '\nreturn template;')(pug.runtime); var actual = fn({name: 'foo'}).replace(/\s/g, ''); expect(actual).toBe(expected); }); it('should support pug.compileClient(str, options)', function() { var src = '.bar= self.foo'; var fn = pug.compileClient(src, {self: true}); fn = Function('pug', fn.toString() + '\nreturn template;')(pug.runtime); var actual = fn({foo: 'baz'}); expect(actual).toBe('
    baz
    '); }); it('should support module syntax in pug.compileClient(str, options) when inlineRuntimeFunctions it true', function() { var src = '.bar= self.foo'; var fn = pug.compileClient(src, { self: true, module: true, inlineRuntimeFunctions: true, }); expect(fn).toMatchSnapshot(); fs.writeFileSync( __dirname + '/temp/input-compileModuleFileClient.js', fn ); var fn = require(__dirname + '/temp/input-compileModuleFileClient.js'); expect(fn({foo: 'baz'})).toBe('
    baz
    '); }); it('should support module syntax in pug.compileClient(str, options) when inlineRuntimeFunctions it false', function() { var src = '.bar= self.foo'; var fn = pug.compileClient(src, { self: true, module: true, inlineRuntimeFunctions: false, }); expect(fn).toMatchSnapshot(); fs.writeFileSync( __dirname + '/temp/input-compileModuleFileClient.js', fn ); var fn = require(__dirname + '/temp/input-compileModuleFileClient.js'); expect(fn({foo: 'baz'})).toBe('
    baz
    '); }); }); describe('.renderFile()', function() { it('will synchronously return a string', function() { var expected = fs .readFileSync(__dirname + '/cases/basic.html', 'utf8') .replace(/\s/g, ''); var actual = pug .renderFile(__dirname + '/cases/basic.pug', {name: 'foo'}) .replace(/\s/g, ''); assert(actual === expected); }); it('when given a callback, it calls that rather than returning', function(done) { var expected = fs .readFileSync(__dirname + '/cases/basic.html', 'utf8') .replace(/\s/g, ''); pug.renderFile(__dirname + '/cases/basic.pug', {name: 'foo'}, function( err, actual ) { if (err) return done(err); assert(actual.replace(/\s/g, '') === expected); done(); }); }); it('when given a callback, it calls that rather than returning even if there are no options', function(done) { var expected = fs .readFileSync(__dirname + '/cases/basic.html', 'utf8') .replace(/\s/g, ''); pug.renderFile(__dirname + '/cases/basic.pug', function(err, actual) { if (err) return done(err); assert(actual.replace(/\s/g, '') === expected); done(); }); }); it('when given a callback, it calls that with any errors', function(done) { pug.renderFile(__dirname + '/fixtures/runtime.error.pug', function( err, actual ) { assert.ok(err); done(); }); }); it('should support caching (pass 1)', function(done) { fs.writeFileSync(__dirname + '/temp/input-renderFile.pug', '.foo bar'); pug.renderFile( __dirname + '/temp/input-renderFile.pug', {cache: true}, function(err, actual) { if (err) return done(err); assert.equal('
    bar
    ', actual); done(); } ); }); it('should support caching (pass 2)', function(done) { // Poison the input file fs.writeFileSync( __dirname + '/temp/input-renderFile.pug', '.big fat hen' ); pug.renderFile( __dirname + '/temp/input-renderFile.pug', {cache: true}, function(err, actual) { if (err) return done(err); assert.equal('
    bar
    ', actual); done(); } ); }); }); describe('.compileFileClient(path, options)', function() { it('returns a string form of a function called `template`', function() { var src = pug.compileFileClient(__dirname + '/cases/basic.pug'); var expected = fs .readFileSync(__dirname + '/cases/basic.html', 'utf8') .replace(/\s/g, ''); var fn = Function('pug', src + '\nreturn template;')(pug.runtime); var actual = fn({name: 'foo'}).replace(/\s/g, ''); assert(actual === expected); }); it('accepts the `name` option to rename the resulting function', function() { var src = pug.compileFileClient(__dirname + '/cases/basic.pug', { name: 'myTemplateName', }); var expected = fs .readFileSync(__dirname + '/cases/basic.html', 'utf8') .replace(/\s/g, ''); var fn = Function('pug', src + '\nreturn myTemplateName;')(pug.runtime); var actual = fn({name: 'foo'}).replace(/\s/g, ''); assert(actual === expected); }); it('should support caching (pass 1)', function() { fs.writeFileSync( __dirname + '/temp/input-compileFileClient.pug', '.foo bar' ); var src = pug.compileFileClient( __dirname + '/temp/input-compileFileClient.pug', {name: 'myTemplateName', cache: true} ); var expected = '
    bar
    '; var fn = Function('pug', src + '\nreturn myTemplateName;')(pug.runtime); assert(fn() === expected); }); it('should support caching (pass 2)', function() { // Poison the input file fs.writeFileSync( __dirname + '/temp/input-compileFileClient.pug', '.big fat hen' ); var src = pug.compileFileClient( __dirname + '/temp/input-compileFileClient.pug', {name: 'myTemplateName', cache: true} ); var expected = '
    bar
    '; var fn = Function('pug', src + '\nreturn myTemplateName;')(pug.runtime); assert(fn() === expected); }); }); describe('.runtime', function() { describe('.merge', function() { it('merges two attribute objects, giving precedensce to the second object', function() { assert.deepEqual( pug.runtime.merge({}, {class: ['foo', 'bar'], foo: 'bar'}), {class: ['foo', 'bar'], foo: 'bar'} ); assert.deepEqual( pug.runtime.merge( {class: ['foo'], foo: 'baz'}, {class: ['bar'], foo: 'bar'} ), {class: ['foo', 'bar'], foo: 'bar'} ); assert.deepEqual( pug.runtime.merge({class: ['foo', 'bar'], foo: 'bar'}, {}), {class: ['foo', 'bar'], foo: 'bar'} ); }); }); describe('.attrs', function() { it('Renders the given attributes object', function() { assert.equal(pug.runtime.attrs({}), ''); assert.equal(pug.runtime.attrs({class: []}), ''); assert.equal(pug.runtime.attrs({class: ['foo']}), ' class="foo"'); assert.equal( pug.runtime.attrs({class: ['foo'], id: 'bar'}), ' class="foo" id="bar"' ); }); }); }); describe('filter indentation', function() { it('is maintained', function() { var filters = { indents: function(str) { return str .split(/\n/) .map(function(line) { return line.match(/^ */)[0].length; }) .join(','); }, }; var indents = [ ':indents', ' x', ' x', ' x', ' x', ' x', ' x', ' x', ' x', ' x', ' x', ' x', ' x', ' x', ' x', ' x', ].join('\n'); assert.equal( pug.render(indents, {filters: filters}), '0,1,2,3,0,4,4,3,3,4,2,0,2,0,1' ); }); }); describe('.compile().dependencies', function() { it('should list the filename of the template referenced by extends', function() { var filename = __dirname + '/dependencies/extends1.pug'; var str = fs.readFileSync(filename, 'utf8'); var info = pug.compile(str, {filename: filename}); assert.deepEqual( [path.resolve(__dirname + '/dependencies/dependency1.pug')], info.dependencies ); }); it('should list the filename of the template referenced by an include', function() { var filename = __dirname + '/dependencies/include1.pug'; var str = fs.readFileSync(filename, 'utf8'); var info = pug.compile(str, {filename: filename}); assert.deepEqual( [path.resolve(__dirname + '/dependencies/dependency1.pug')], info.dependencies ); }); it('should list the dependencies of extends dependencies', function() { var filename = __dirname + '/dependencies/extends2.pug'; var str = fs.readFileSync(filename, 'utf8'); var info = pug.compile(str, {filename: filename}); assert.deepEqual( [ path.resolve(__dirname + '/dependencies/dependency2.pug'), path.resolve(__dirname + '/dependencies/dependency3.pug'), ], info.dependencies ); }); it('should list the dependencies of include dependencies', function() { var filename = __dirname + '/dependencies/include2.pug'; var str = fs.readFileSync(filename, 'utf8'); var info = pug.compile(str, {filename: filename}); assert.deepEqual( [ path.resolve(__dirname + '/dependencies/dependency2.pug'), path.resolve(__dirname + '/dependencies/dependency3.pug'), ], info.dependencies ); }); }); describe('.name', function() { it('should have a name attribute', function() { assert.strictEqual(pug.name, 'Pug'); }); }); }); ================================================ FILE: packages/pug/test/regression-2436/__snapshots__/index.test.js.snap ================================================ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`#2436 - block with a same name extends from different layout in nesting 1`] = ` "

    layout

    Main A

    other layout

    Other A

    " `; exports[`#2436 - block with a same name extends from the same layout in nesting 1`] = ` "

    layout

    Main A

    layout

    Other A

    " `; ================================================ FILE: packages/pug/test/regression-2436/index.test.js ================================================ const pug = require('../../'); test('#2436 - block with a same name extends from the same layout in nesting', () => { const output = pug.renderFile(__dirname + '/issue1.pug', {pretty: true}); expect(output).toMatchSnapshot(); }); test('#2436 - block with a same name extends from different layout in nesting', () => { const output = pug.renderFile(__dirname + '/issue2.pug', {pretty: true}); expect(output).toMatchSnapshot(); }); ================================================ FILE: packages/pug/test/regression-2436/issue1.pug ================================================ extends layout.pug block a p Main A block b include other1.pug ================================================ FILE: packages/pug/test/regression-2436/issue2.pug ================================================ extends layout.pug block a p Main A block b include other2.pug ================================================ FILE: packages/pug/test/regression-2436/layout.pug ================================================ h1 layout block a p block in layout block b ================================================ FILE: packages/pug/test/regression-2436/other1.pug ================================================ extends layout.pug block a p Other A ================================================ FILE: packages/pug/test/regression-2436/other2.pug ================================================ extends other_layout.pug block a p Other A ================================================ FILE: packages/pug/test/regression-2436/other_layout.pug ================================================ h1 other layout block a p block in other layout ================================================ FILE: packages/pug/test/run-es2015.test.js ================================================ 'use strict'; const fs = require('fs'); const assert = require('assert'); const mkdirp = require('mkdirp').sync; const runUtils = require('./run-utils'); const pug = require('../'); var cases = runUtils.findCases(__dirname + '/cases'); var es2015 = runUtils.findCases(__dirname + '/cases-es2015'); mkdirp(__dirname + '/output-es2015'); describe('test cases for ECMAScript 2015', function() { try { eval('``'); es2015.forEach(runUtils.testSingle.bind(null, it, '-es2015')); } catch (ex) { es2015.forEach(runUtils.testSingle.bind(null, it.skip, '-es2015')); } }); ================================================ FILE: packages/pug/test/run-syntax-errors.test.js ================================================ const assert = require('assert'); const fs = require('fs'); const runUtils = require('./run-utils'); const pug = require('../'); const anti = runUtils.findCases(__dirname + '/anti-cases'); describe('certain syntax is not allowed and will throw a compile time error', function() { anti.forEach(function(test) { var name = test.replace(/[-.]/g, ' '); it(name, function() { var path = __dirname.replace(/\\/g, '/') + '/anti-cases/' + test + '.pug'; var str = fs.readFileSync(path, 'utf8'); try { var fn = pug.compile(str, { filename: path, pretty: true, basedir: __dirname + '/anti-cases', filters: runUtils.filters, }); } catch (ex) { if (!ex.code) { throw ex; } assert(ex instanceof Error, 'Should throw a real Error'); assert( ex.code.indexOf('PUG:') === 0, 'It should have a code of "PUG:SOMETHING"' ); assert( ex.message.replace(/\\/g, '/').indexOf(path) === 0, 'it should start with the path' ); assert( /:\d+$/m.test(ex.message.replace(/\\/g, '/')), 'it should include a line number.' ); return; } throw new Error(test + ' should have thrown an error'); }); }); }); ================================================ FILE: packages/pug/test/run-utils.js ================================================ var fs = require('fs'); var assert = require('assert'); var pug = require('../'); var uglify = require('uglify-js'); var mkdirp = require('mkdirp').sync; var filters = { custom: function(str, options) { assert(options.opt === 'val'); assert(options.num === 2); return 'BEGIN' + str + 'END'; }, }; // test cases function writeFileSync(filename, data) { try { if (fs.readFileSync(filename, 'utf8') === data.toString('utf8')) { return; } } catch (ex) { if (ex.code !== 'ENOENT') { throw ex; } } fs.writeFileSync(filename, data); } function findCases(dir) { return fs .readdirSync(dir) .filter(function(file) { return ~file.indexOf('.pug'); }) .map(function(file) { return file.replace('.pug', ''); }); } function testSingle(it, suffix, test) { var name = test.replace(/[-.]/g, ' '); it(name, function() { var path = __dirname + '/cases' + suffix + '/' + test + '.pug'; var str = fs.readFileSync(path, 'utf8'); var fn = pug.compile(str, { filename: path, pretty: true, basedir: __dirname + '/cases' + suffix, filters: filters, filterAliases: {markdown: 'markdown-it'}, }); var actual = fn({title: 'Pug'}); writeFileSync( __dirname + '/output' + suffix + '/' + test + '.html', actual ); var html = fs .readFileSync( __dirname + '/cases' + suffix + '/' + test + '.html', 'utf8' ) .trim() .replace(/\r/g, ''); var clientCode = uglify.minify( pug.compileClient(str, { filename: path, pretty: true, compileDebug: false, basedir: __dirname + '/cases' + suffix, filters: filters, filterAliases: {markdown: 'markdown-it'}, }), { output: {beautify: true}, mangle: false, compress: false, fromString: true, } ).code; var clientCodeDebug = uglify.minify( pug.compileClient(str, { filename: path, pretty: true, compileDebug: true, basedir: __dirname + '/cases' + suffix, filters: filters, filterAliases: {markdown: 'markdown-it'}, }), { output: {beautify: true}, mangle: false, compress: false, fromString: true, } ).code; writeFileSync( __dirname + '/output' + suffix + '/' + test + '.js', uglify.minify( pug.compileClient(str, { filename: path, pretty: false, compileDebug: false, basedir: __dirname + '/cases' + suffix, filters: filters, filterAliases: {markdown: 'markdown-it'}, }), { output: {beautify: true}, mangle: false, compress: false, fromString: true, } ).code ); if (/filter/.test(test)) { actual = actual.replace(/\n| /g, ''); html = html.replace(/\n| /g, ''); } if (/mixins-unused/.test(test)) { assert( /never-called/.test(str), 'never-called is in the pug file for mixins-unused' ); assert( !/never-called/.test(clientCode), 'never-called should be removed from the code' ); } expect(actual.trim()).toEqual(html); actual = Function('pug', clientCode + '\nreturn template;')()({ title: 'Pug', }); if (/filter/.test(test)) { actual = actual.replace(/\n| /g, ''); } expect(actual.trim()).toEqual(html); actual = Function('pug', clientCodeDebug + '\nreturn template;')()({ title: 'Pug', }); if (/filter/.test(test)) { actual = actual.replace(/\n| /g, ''); } expect(actual.trim()).toEqual(html); }); } module.exports = { filters, findCases, testSingle, }; ================================================ FILE: packages/pug/test/run.test.js ================================================ 'use strict'; // even and odd tests are arbitrarily split because jest is faster that way const fs = require('fs'); const assert = require('assert'); const mkdirp = require('mkdirp').sync; const runUtils = require('./run-utils'); const pug = require('../'); var cases = runUtils.findCases(__dirname + '/cases'); var es2015 = runUtils.findCases(__dirname + '/cases-es2015'); mkdirp(__dirname + '/output'); describe('test cases', function() { cases.forEach((test, i) => { runUtils.testSingle(it, '', test); }); }); ================================================ FILE: packages/pug/test/shadowed-block/__snapshots__/index.test.js.snap ================================================ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`layout with shadowed block 1`] = `""`; exports[`layout with shadowed block 2`] = `""`; ================================================ FILE: packages/pug/test/shadowed-block/base.pug ================================================ block root // base.pug: root block shadowed // base.pug: shadowed ================================================ FILE: packages/pug/test/shadowed-block/index.pug ================================================ extends ./layout.pug block shadowed // index.pug: shadowed ================================================ FILE: packages/pug/test/shadowed-block/index.test.js ================================================ const pug = require('../../'); test('layout with shadowed block', () => { const outputWithAjax = pug.renderFile(__dirname + '/index.pug', {ajax: true}); const outputWithoutAjax = pug.renderFile(__dirname + '/index.pug', { ajax: false, }); expect(outputWithAjax).toMatchSnapshot(); expect(outputWithoutAjax).toMatchSnapshot(); }); ================================================ FILE: packages/pug/test/shadowed-block/layout.pug ================================================ extends ./base.pug block root // layout.pug: root block shadowed // layout.pug: shadowed ================================================ FILE: packages/pug-attrs/LICENSE ================================================ Copyright (c) 2015 Forbes Lindesay 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. ================================================ FILE: packages/pug-attrs/README.md ================================================ # pug-attrs Generate code for Pug attributes [![Build Status](https://img.shields.io/travis/pugjs/pug-attrs/master.svg)](https://travis-ci.org/pugjs/pug-attrs) [![Dependencies Status](https://david-dm.org/pugjs/pug/status.svg?path=packages/pug-attrs)](https://david-dm.org/pugjs/pug?path=packages/pug-attrs) [![NPM version](https://img.shields.io/npm/v/pug-attrs.svg)](https://www.npmjs.org/package/pug-attrs) ## Installation npm install pug-attrs ## Usage ```js var compileAttrs = require('pug-attrs'); ``` ### `compileAttrs(attrs, options)` Compile `attrs` to a JavaScript string that evaluates to the attributes in the desired format. `options` MUST include the following properties: - `terse`: whether or not to use HTML5-style terse boolean attributes - `runtime`: callback that takes a runtime function name and returns the source code that will evaluate to that function at runtime - `format`: output format; must be `html` or `object` `attrs` is an array of attributes, with each attribute having the form of `{ name, val, mustEscape }`. `val` represents a JavaScript string that evaluates to the value of the attribute, either statically or dynamically. ```js var compileAttrs = require('pug-attrs'); var pugRuntime = require('pug-runtime'); function getBaz () { return 'baz<>'; } var attrs = [ {name: 'foo', val: '"bar"', mustEscape: true }, {name: 'baz', val: 'getBaz()', mustEscape: true }, {name: 'quux', val: true, mustEscape: false} ]; var result, finalResult; // HTML MODE result = compileAttrs(attrs, { terse: true, format: 'html', runtime: function (name) { return 'pugRuntime.' + name; } }); //=> '" foo=\\"bar\\"" + pugRuntime.attr("baz", getBaz(), true, true) + " quux"' finalResult = Function('pugRuntime, getBaz', 'return (' + result + ');' ); finalResult(pugRuntime, getBaz); // => ' foo="bar" baz="baz<>" quux' // OBJECT MODE result = compileAttrs(attrs, { terse: true, format: 'object', runtime: function (name) { return 'pugRuntime.' + name; } }); //=> '{"foo": "bar","baz": pugRuntime.escape(getBaz()),"quux": true}' finalResult = Function('pugRuntime, getBaz', 'return (' + result + ');' ); finalResult(pugRuntime, getBaz); //=> { foo: 'bar', baz: 'baz<>', quux: true } ``` ## License MIT ================================================ FILE: packages/pug-attrs/index.js ================================================ 'use strict'; var assert = require('assert'); var constantinople = require('constantinople'); var runtime = require('pug-runtime'); var stringify = require('js-stringify'); function isConstant(src) { return constantinople(src, {pug: runtime, pug_interp: undefined}); } function toConstant(src) { return constantinople.toConstant(src, {pug: runtime, pug_interp: undefined}); } module.exports = compileAttrs; /** * options: * - terse * - runtime * - format ('html' || 'object') */ function compileAttrs(attrs, options) { assert(Array.isArray(attrs), 'Attrs should be an array'); assert( attrs.every(function(attr) { return ( attr && typeof attr === 'object' && typeof attr.name === 'string' && (typeof attr.val === 'string' || typeof attr.val === 'boolean') && typeof attr.mustEscape === 'boolean' ); }), 'All attributes should be supplied as an object of the form {name, val, mustEscape}' ); assert(options && typeof options === 'object', 'Options should be an object'); assert( typeof options.terse === 'boolean', 'Options.terse should be a boolean' ); assert( typeof options.runtime === 'function', 'Options.runtime should be a function that takes a runtime function name and returns the source code that will evaluate to that function at runtime' ); assert( options.format === 'html' || options.format === 'object', 'Options.format should be "html" or "object"' ); var buf = []; var classes = []; var classEscaping = []; function addAttribute(key, val, mustEscape, buf) { if (isConstant(val)) { if (options.format === 'html') { var str = stringify( runtime.attr(key, toConstant(val), mustEscape, options.terse) ); var last = buf[buf.length - 1]; if (last && last[last.length - 1] === str[0]) { buf[buf.length - 1] = last.substr(0, last.length - 1) + str.substr(1); } else { buf.push(str); } } else { val = toConstant(val); if (mustEscape) { val = runtime.escape(val); } buf.push(stringify(key) + ': ' + stringify(val)); } } else { if (options.format === 'html') { buf.push( options.runtime('attr') + '("' + key + '", ' + val + ', ' + stringify(mustEscape) + ', ' + stringify(options.terse) + ')' ); } else { if (mustEscape) { val = options.runtime('escape') + '(' + val + ')'; } buf.push(stringify(key) + ': ' + val); } } } attrs.forEach(function(attr) { var key = attr.name; var val = attr.val; var mustEscape = attr.mustEscape; if (key === 'class') { classes.push(val); classEscaping.push(mustEscape); } else { if (key === 'style') { if (isConstant(val)) { val = stringify(runtime.style(toConstant(val))); } else { val = options.runtime('style') + '(' + val + ')'; } } addAttribute(key, val, mustEscape, buf); } }); var classesBuf = []; if (classes.length) { if (classes.every(isConstant)) { addAttribute( 'class', stringify(runtime.classes(classes.map(toConstant), classEscaping)), false, classesBuf ); } else { classes = classes.map(function(cls, i) { if (isConstant(cls)) { cls = stringify( classEscaping[i] ? runtime.escape(toConstant(cls)) : toConstant(cls) ); classEscaping[i] = false; } return cls; }); addAttribute( 'class', options.runtime('classes') + '([' + classes.join(',') + '], ' + stringify(classEscaping) + ')', false, classesBuf ); } } buf = classesBuf.concat(buf); if (options.format === 'html') return buf.length ? buf.join('+') : '""'; else return '{' + buf.join(',') + '}'; } ================================================ FILE: packages/pug-attrs/package.json ================================================ { "name": "pug-attrs", "version": "2.0.4", "description": "Generate code for Pug attributes", "keywords": [ "pug" ], "dependencies": { "constantinople": "^4.0.1", "js-stringify": "^1.0.2", "pug-runtime": "^2.0.5" }, "files": [ "index.js" ], "repository": { "type": "git", "url": "https://github.com/pugjs/pug/tree/master/packages/pug-attrs" }, "author": "Forbes Lindesay", "license": "MIT" } ================================================ FILE: packages/pug-attrs/test/index.test.js ================================================ 'use strict'; var assert = require('assert'); var utils = require('util'); var attrs = require('../'); var options; function test(input, expected, locals) { var opts = options; locals = locals || {}; locals.pug = locals.pug || require('pug-runtime'); it( utils.inspect(input).replace(/\n/g, '') + ' => ' + utils.inspect(expected), function() { var src = attrs(input, opts); var localKeys = Object.keys(locals).sort(); var output = Function( localKeys.join(', '), 'return (' + src + ');' ).apply( null, localKeys.map(function(key) { return locals[key]; }) ); if (opts.format === 'html') { expect(output).toBe(expected); } else { expect(output).toEqual(expected); } } ); } function withOptions(opts, fn) { describe('options: ' + utils.inspect(opts), function() { options = opts; fn(); }); } withOptions( { terse: true, format: 'html', runtime: function(name) { return 'pug.' + name; }, }, function() { test([], ''); test([{name: 'foo', val: 'false', mustEscape: true}], ''); test([{name: 'foo', val: 'true', mustEscape: true}], ' foo'); test([{name: 'foo', val: false, mustEscape: true}], ''); test([{name: 'foo', val: true, mustEscape: true}], ' foo'); test([{name: 'foo', val: 'foo', mustEscape: true}], '', {foo: false}); test([{name: 'foo', val: 'foo', mustEscape: true}], ' foo', {foo: true}); test([{name: 'foo', val: '"foo"', mustEscape: true}], ' foo="foo"'); test( [ {name: 'foo', val: '"foo"', mustEscape: true}, {name: 'bar', val: '"bar"', mustEscape: true}, ], ' foo="foo" bar="bar"' ); test([{name: 'foo', val: 'foo', mustEscape: true}], ' foo="fooo"', { foo: 'fooo', }); test( [ {name: 'foo', val: 'foo', mustEscape: true}, {name: 'bar', val: 'bar', mustEscape: true}, ], ' foo="fooo" bar="baro"', {foo: 'fooo', bar: 'baro'} ); test( [{name: 'style', val: '{color: "red"}', mustEscape: true}], ' style="color:red;"' ); test( [{name: 'style', val: '{color: color}', mustEscape: true}], ' style="color:red;"', {color: 'red'} ); test( [ {name: 'class', val: '"foo"', mustEscape: true}, {name: 'class', val: '["bar", "baz"]', mustEscape: true}, ], ' class="foo bar baz"' ); test( [ {name: 'class', val: '{foo: foo}', mustEscape: true}, {name: 'class', val: '["bar", "baz"]', mustEscape: true}, ], ' class="foo bar baz"', {foo: true} ); test( [ {name: 'class', val: '{foo: foo}', mustEscape: true}, {name: 'class', val: '["bar", "baz"]', mustEscape: true}, ], ' class="bar baz"', {foo: false} ); test( [ {name: 'class', val: 'foo', mustEscape: true}, {name: 'class', val: '""', mustEscape: true}, ], ' class="<foo> <str>"', {foo: ''} ); test( [ {name: 'foo', val: '"foo"', mustEscape: true}, {name: 'class', val: '["bar", "baz"]', mustEscape: true}, ], ' class="bar baz" foo="foo"' ); test( [ {name: 'class', val: '["bar", "baz"]', mustEscape: true}, {name: 'foo', val: '"foo"', mustEscape: true}, ], ' class="bar baz" foo="foo"' ); test([{name: 'foo', val: '""', mustEscape: false}], ' foo=""'); test( [{name: 'foo', val: '""', mustEscape: true}], ' foo="<foo>"' ); test([{name: 'foo', val: 'foo', mustEscape: false}], ' foo=""', { foo: '', }); test([{name: 'foo', val: 'foo', mustEscape: true}], ' foo="<foo>"', { foo: '', }); } ); withOptions( { terse: false, format: 'html', runtime: function(name) { return 'pug.' + name; }, }, function() { test([{name: 'foo', val: 'false', mustEscape: true}], ''); test([{name: 'foo', val: 'true', mustEscape: true}], ' foo="foo"'); test([{name: 'foo', val: false, mustEscape: true}], ''); test([{name: 'foo', val: true, mustEscape: true}], ' foo="foo"'); test([{name: 'foo', val: 'foo', mustEscape: true}], '', {foo: false}); test([{name: 'foo', val: 'foo', mustEscape: true}], ' foo="foo"', { foo: true, }); } ); withOptions( { terse: true, format: 'object', runtime: function(name) { return 'pug.' + name; }, }, function() { test([], {}); test([{name: 'foo', val: 'false', mustEscape: true}], {foo: false}); test([{name: 'foo', val: 'true', mustEscape: true}], {foo: true}); test([{name: 'foo', val: false, mustEscape: true}], {foo: false}); test([{name: 'foo', val: true, mustEscape: true}], {foo: true}); test( [{name: 'foo', val: 'foo', mustEscape: true}], {foo: false}, {foo: false} ); test( [{name: 'foo', val: 'foo', mustEscape: true}], {foo: true}, {foo: true} ); test([{name: 'foo', val: '"foo"', mustEscape: true}], {foo: 'foo'}); test( [ {name: 'foo', val: '"foo"', mustEscape: true}, {name: 'bar', val: '"bar"', mustEscape: true}, ], {foo: 'foo', bar: 'bar'} ); test( [{name: 'foo', val: 'foo', mustEscape: true}], {foo: 'fooo'}, {foo: 'fooo'} ); test( [ {name: 'foo', val: 'foo', mustEscape: true}, {name: 'bar', val: 'bar', mustEscape: true}, ], {foo: 'fooo', bar: 'baro'}, {foo: 'fooo', bar: 'baro'} ); test([{name: 'style', val: '{color: "red"}', mustEscape: true}], { style: 'color:red;', }); test( [{name: 'style', val: '{color: color}', mustEscape: true}], {style: 'color:red;'}, {color: 'red'} ); test( [ {name: 'class', val: '"foo"', mustEscape: true}, {name: 'class', val: '["bar", "baz"]', mustEscape: true}, ], {class: 'foo bar baz'} ); test( [ {name: 'class', val: '{foo: foo}', mustEscape: true}, {name: 'class', val: '["bar", "baz"]', mustEscape: true}, ], {class: 'foo bar baz'}, {foo: true} ); test( [ {name: 'class', val: '{foo: foo}', mustEscape: true}, {name: 'class', val: '["bar", "baz"]', mustEscape: true}, ], {class: 'bar baz'}, {foo: false} ); test( [ {name: 'class', val: 'foo', mustEscape: true}, {name: 'class', val: '""', mustEscape: true}, ], {class: '<foo> <str>'}, {foo: ''} ); test( [ {name: 'foo', val: '"foo"', mustEscape: true}, {name: 'class', val: '["bar", "baz"]', mustEscape: true}, ], {class: 'bar baz', foo: 'foo'} ); test( [ {name: 'class', val: '["bar", "baz"]', mustEscape: true}, {name: 'foo', val: '"foo"', mustEscape: true}, ], {class: 'bar baz', foo: 'foo'} ); test([{name: 'foo', val: '""', mustEscape: false}], {foo: ''}); test([{name: 'foo', val: '""', mustEscape: true}], { foo: '<foo>', }); test( [{name: 'foo', val: 'foo', mustEscape: false}], {foo: ''}, {foo: ''} ); test( [{name: 'foo', val: 'foo', mustEscape: true}], {foo: '<foo>'}, {foo: ''} ); } ); withOptions( { terse: false, format: 'object', runtime: function(name) { return 'pug.' + name; }, }, function() { test([{name: 'foo', val: 'false', mustEscape: true}], {foo: false}); test([{name: 'foo', val: 'true', mustEscape: true}], {foo: true}); test([{name: 'foo', val: false, mustEscape: true}], {foo: false}); test([{name: 'foo', val: true, mustEscape: true}], {foo: true}); test( [{name: 'foo', val: 'foo', mustEscape: true}], {foo: false}, {foo: false} ); test( [{name: 'foo', val: 'foo', mustEscape: true}], {foo: true}, {foo: true} ); } ); ================================================ FILE: packages/pug-code-gen/HISTORY.md ================================================ # Change log ## 1.1.0 / 2016-08-23 - Wrap `each` and `for` in IIFE to prevent variable from leaking ## 1.0.1 / 2016-08-10 - Update doctypes to 1.1.0 ## 1.0.0 / 2016-08-10 - First stable release ================================================ FILE: packages/pug-code-gen/LICENSE ================================================ Copyright (c) 2015 Forbes Lindesay 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. ================================================ FILE: packages/pug-code-gen/README.md ================================================ # pug-code-gen Default code-generator for pug. It generates HTML via a JavaScript template function. [![Dependencies Status](https://david-dm.org/pugjs/pug/status.svg?path=packages/pug-code-gen)](https://david-dm.org/pugjs/pug?path=packages/pug-code-gen) [![npm version](https://img.shields.io/npm/v/pug-code-gen.svg)](https://www.npmjs.org/package/pug-code-gen) ## Installation npm install pug-code-gen ## Usage ```js var generateCode = require('pug-code-gen'); ``` ### `generateCode(ast, options)` Generate a JavaScript function string for the given AST. `ast` is a fully expanded AST for Pug, with all inclusion, extends, and filters resolved. `options` may contain the following properties that have the same meaning as the options with the same names in `pug`: - pretty (boolean): default is `false` - compileDebug (boolean): default is `true` - doctype (string): default is `undefined` - inlineRuntimeFunctions (boolean): default is `false` - globals (array of strings): default is `[]` - self (boolean): default is `false` In addition to above, `pug-code-gen` has the following unique options: - includeSources (object): map of filename to source string; used if `compileDebug` is `true`; default is `undefined` - templateName (string): the name of the generated function; default is `'template'` ```js var lex = require('pug-lexer'); var parse = require('pug-parser'); var wrap = require('pug-runtime/wrap'); var generateCode = require('pug-code-gen'); var funcStr = generateCode(parse(lex('p Hello world!')), { compileDebug: false, pretty: true, inlineRuntimeFunctions: false, templateName: 'helloWorld' }); //=> 'function helloWorld(locals) { ... }' var func = wrap(funcStr, 'helloWorld'); func(); //=> '\n

    Hello world!

    ' ``` ### `new generateCode.CodeGenerator(ast, options)` The constructor for the internal class of the code generator. You shouldn't need to use this for most purposes. ## License MIT ================================================ FILE: packages/pug-code-gen/index.js ================================================ 'use strict'; var doctypes = require('doctypes'); var makeError = require('pug-error'); var buildRuntime = require('pug-runtime/build'); var runtime = require('pug-runtime'); var compileAttrs = require('pug-attrs'); var selfClosing = require('void-elements'); var constantinople = require('constantinople'); var stringify = require('js-stringify'); var addWith = require('with'); // This is used to prevent pretty printing inside certain tags var WHITE_SPACE_SENSITIVE_TAGS = { pre: true, textarea: true, }; var INTERNAL_VARIABLES = [ 'pug', 'pug_mixins', 'pug_interp', 'pug_debug_filename', 'pug_debug_line', 'pug_debug_sources', 'pug_html', ]; module.exports = generateCode; module.exports.CodeGenerator = Compiler; function generateCode(ast, options) { return new Compiler(ast, options).compile(); } function isConstant(src) { return constantinople(src, {pug: runtime, pug_interp: undefined}); } function toConstant(src) { return constantinople.toConstant(src, {pug: runtime, pug_interp: undefined}); } function isIdentifier(name) { return /^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(name); } /** * Initialize `Compiler` with the given `node`. * * @param {Node} node * @param {Object} options * @api public */ function Compiler(node, options) { this.options = options = options || {}; this.node = node; this.bufferedConcatenationCount = 0; this.hasCompiledDoctype = false; this.hasCompiledTag = false; this.pp = options.pretty || false; if (this.pp && typeof this.pp !== 'string') { this.pp = ' '; } if (this.pp && !/^\s+$/.test(this.pp)) { throw new Error( 'The pretty parameter should either be a boolean or whitespace only string' ); } if (this.options.templateName && !isIdentifier(this.options.templateName)) { throw new Error( 'The templateName parameter must be a valid JavaScript identifier if specified.' ); } if ( this.options.doctype && (this.options.doctype.includes('<') || this.options.doctype.includes('>')) ) { throw new Error('Doctype can not contain "<" or ">"'); } if (this.options.globals && !this.options.globals.every(isIdentifier)) { throw new Error( 'The globals option must be an array of valid JavaScript identifiers if specified.' ); } this.debug = false !== options.compileDebug; this.indents = 0; this.parentIndents = 0; this.terse = false; this.mixins = {}; this.dynamicMixins = false; this.eachCount = 0; if (options.doctype) this.setDoctype(options.doctype); this.runtimeFunctionsUsed = []; this.inlineRuntimeFunctions = options.inlineRuntimeFunctions || false; if (this.debug && this.inlineRuntimeFunctions) { this.runtimeFunctionsUsed.push('rethrow'); } } /** * Compiler prototype. */ Compiler.prototype = { runtime: function(name) { if (this.inlineRuntimeFunctions) { this.runtimeFunctionsUsed.push(name); return 'pug_' + name; } else { return 'pug.' + name; } }, error: function(message, code, node) { var err = makeError(code, message, { line: node.line, column: node.column, filename: node.filename, }); throw err; }, /** * Compile parse tree to JavaScript. * * @api public */ compile: function() { this.buf = []; if (this.pp) this.buf.push('var pug_indent = [];'); this.lastBufferedIdx = -1; this.visit(this.node); if (!this.dynamicMixins) { // if there are no dynamic mixins we can remove any un-used mixins var mixinNames = Object.keys(this.mixins); for (var i = 0; i < mixinNames.length; i++) { var mixin = this.mixins[mixinNames[i]]; if (!mixin.used) { for (var x = 0; x < mixin.instances.length; x++) { for ( var y = mixin.instances[x].start; y < mixin.instances[x].end; y++ ) { this.buf[y] = ''; } } } } } var js = this.buf.join('\n'); var globals = this.options.globals ? this.options.globals.concat(INTERNAL_VARIABLES) : INTERNAL_VARIABLES; if (this.options.self) { js = 'var self = locals || {};' + js; } else { js = addWith( 'locals || {}', js, globals.concat( this.runtimeFunctionsUsed.map(function(name) { return 'pug_' + name; }) ) ); } if (this.debug) { if (this.options.includeSources) { js = 'var pug_debug_sources = ' + stringify(this.options.includeSources) + ';\n' + js; } js = 'var pug_debug_filename, pug_debug_line;' + 'try {' + js + '} catch (err) {' + (this.inlineRuntimeFunctions ? 'pug_rethrow' : 'pug.rethrow') + '(err, pug_debug_filename, pug_debug_line' + (this.options.includeSources ? ', pug_debug_sources[pug_debug_filename]' : '') + ');' + '}'; } return ( buildRuntime(this.runtimeFunctionsUsed) + 'function ' + (this.options.templateName || 'template') + '(locals) {var pug_html = "", pug_mixins = {}, pug_interp;' + js + ';return pug_html;}' ); }, /** * Sets the default doctype `name`. Sets terse mode to `true` when * html 5 is used, causing self-closing tags to end with ">" vs "/>", * and boolean attributes are not mirrored. * * @param {string} name * @api public */ setDoctype: function(name) { this.doctype = doctypes.hasOwnProperty(name.toLowerCase()) ? doctypes[name.toLowerCase()] : ''; this.terse = this.doctype.toLowerCase() == ''; this.xml = 0 == this.doctype.indexOf(' 1 && !escapePrettyMode && block.nodes[0].type === 'Text' && block.nodes[1].type === 'Text' ) { this.prettyIndent(1, true); } for (var i = 0; i < block.nodes.length; ++i) { // Pretty print text if ( pp && i > 0 && !escapePrettyMode && block.nodes[i].type === 'Text' && block.nodes[i - 1].type === 'Text' && /\n$/.test(block.nodes[i - 1].val) ) { this.prettyIndent(1, false); } this.visit(block.nodes[i], block); } }, /** * Visit a mixin's `block` keyword. * * @param {MixinBlock} block * @api public */ visitMixinBlock: function(block) { if (this.pp) this.buf.push( 'pug_indent.push(' + stringify(Array(this.indents + 1).join(this.pp)) + ');' ); this.buf.push('block && block();'); if (this.pp) this.buf.push('pug_indent.pop();'); }, /** * Visit `doctype`. Sets terse mode to `true` when html 5 * is used, causing self-closing tags to end with ">" vs "/>", * and boolean attributes are not mirrored. * * @param {Doctype} doctype * @api public */ visitDoctype: function(doctype) { if (doctype && (doctype.val || !this.doctype)) { this.setDoctype(doctype.val || 'html'); } if (this.doctype) this.buffer(this.doctype); this.hasCompiledDoctype = true; }, /** * Visit `mixin`, generating a function that * may be called within the template. * * @param {Mixin} mixin * @api public */ visitMixin: function(mixin) { var name = 'pug_mixins['; var args = mixin.args || ''; var block = mixin.block; var attrs = mixin.attrs; var attrsBlocks = this.attributeBlocks(mixin.attributeBlocks); var pp = this.pp; var dynamic = mixin.name[0] === '#'; var key = mixin.name; if (dynamic) this.dynamicMixins = true; name += (dynamic ? mixin.name.substr(2, mixin.name.length - 3) : '"' + mixin.name + '"') + ']'; this.mixins[key] = this.mixins[key] || {used: false, instances: []}; if (mixin.call) { this.mixins[key].used = true; if (pp) this.buf.push( 'pug_indent.push(' + stringify(Array(this.indents + 1).join(pp)) + ');' ); if (block || attrs.length || attrsBlocks.length) { this.buf.push(name + '.call({'); if (block) { this.buf.push('block: function(){'); // Render block with no indents, dynamically added when rendered this.parentIndents++; var _indents = this.indents; this.indents = 0; this.visit(mixin.block, mixin); this.indents = _indents; this.parentIndents--; if (attrs.length || attrsBlocks.length) { this.buf.push('},'); } else { this.buf.push('}'); } } if (attrsBlocks.length) { if (attrs.length) { var val = this.attrs(attrs); attrsBlocks.unshift(val); } if (attrsBlocks.length > 1) { this.buf.push( 'attributes: ' + this.runtime('merge') + '([' + attrsBlocks.join(',') + '])' ); } else { this.buf.push('attributes: ' + attrsBlocks[0]); } } else if (attrs.length) { var val = this.attrs(attrs); this.buf.push('attributes: ' + val); } if (args) { this.buf.push('}, ' + args + ');'); } else { this.buf.push('});'); } } else { this.buf.push(name + '(' + args + ');'); } if (pp) this.buf.push('pug_indent.pop();'); } else { var mixin_start = this.buf.length; args = args ? args.split(',') : []; var rest; if (args.length && /^\.\.\./.test(args[args.length - 1].trim())) { rest = args .pop() .trim() .replace(/^\.\.\./, ''); } // we need use pug_interp here for v8: https://code.google.com/p/v8/issues/detail?id=4165 // once fixed, use this: this.buf.push(name + ' = function(' + args.join(',') + '){'); this.buf.push(name + ' = pug_interp = function(' + args.join(',') + '){'); this.buf.push( 'var block = (this && this.block), attributes = (this && this.attributes) || {};' ); if (rest) { this.buf.push('var ' + rest + ' = [];'); this.buf.push( 'for (pug_interp = ' + args.length + '; pug_interp < arguments.length; pug_interp++) {' ); this.buf.push(' ' + rest + '.push(arguments[pug_interp]);'); this.buf.push('}'); } this.parentIndents++; this.visit(block, mixin); this.parentIndents--; this.buf.push('};'); var mixin_end = this.buf.length; this.mixins[key].instances.push({start: mixin_start, end: mixin_end}); } }, /** * Visit `tag` buffering tag markup, generating * attributes, visiting the `tag`'s code and block. * * @param {Tag} tag * @param {boolean} interpolated * @api public */ visitTag: function(tag, interpolated) { this.indents++; var name = tag.name, pp = this.pp, self = this; function bufferName() { if (interpolated) self.bufferExpression(tag.expr); else self.buffer(name); } if (WHITE_SPACE_SENSITIVE_TAGS[tag.name] === true) this.escapePrettyMode = true; if (!this.hasCompiledTag) { if (!this.hasCompiledDoctype && 'html' == name) { this.visitDoctype(); } this.hasCompiledTag = true; } // pretty print if (pp && !tag.isInline) this.prettyIndent(0, true); if (tag.selfClosing || (!this.xml && selfClosing[tag.name])) { this.buffer('<'); bufferName(); this.visitAttributes( tag.attrs, this.attributeBlocks(tag.attributeBlocks) ); if (this.terse && !tag.selfClosing) { this.buffer('>'); } else { this.buffer('/>'); } // if it is non-empty throw an error if ( tag.code || (tag.block && !(tag.block.type === 'Block' && tag.block.nodes.length === 0) && tag.block.nodes.some(function(tag) { return tag.type !== 'Text' || !/^\s*$/.test(tag.val); })) ) { this.error( name + ' is a self closing element: <' + name + '/> but contains nested content.', 'SELF_CLOSING_CONTENT', tag ); } } else { // Optimize attributes buffering this.buffer('<'); bufferName(); this.visitAttributes( tag.attrs, this.attributeBlocks(tag.attributeBlocks) ); this.buffer('>'); if (tag.code) this.visitCode(tag.code); this.visit(tag.block, tag); // pretty print if ( pp && !tag.isInline && WHITE_SPACE_SENSITIVE_TAGS[tag.name] !== true && !tagCanInline(tag) ) this.prettyIndent(0, true); this.buffer(''); } if (WHITE_SPACE_SENSITIVE_TAGS[tag.name] === true) this.escapePrettyMode = false; this.indents--; }, /** * Visit InterpolatedTag. * * @param {InterpolatedTag} tag * @api public */ visitInterpolatedTag: function(tag) { return this.visitTag(tag, true); }, /** * Visit `text` node. * * @param {Text} text * @api public */ visitText: function(text) { this.buffer(text.val); }, /** * Visit a `comment`, only buffering when the buffer flag is set. * * @param {Comment} comment * @api public */ visitComment: function(comment) { if (!comment.buffer) return; if (this.pp) this.prettyIndent(1, true); this.buffer(''); }, /** * Visit a `YieldBlock`. * * This is necessary since we allow compiling a file with `yield`. * * @param {YieldBlock} block * @api public */ visitYieldBlock: function(block) {}, /** * Visit a `BlockComment`. * * @param {Comment} comment * @api public */ visitBlockComment: function(comment) { if (!comment.buffer) return; if (this.pp) this.prettyIndent(1, true); this.buffer(''); }, /** * Visit `code`, respecting buffer / escape flags. * If the code is followed by a block, wrap it in * a self-calling function. * * @param {Code} code * @api public */ visitCode: function(code) { // Wrap code blocks with {}. // we only wrap unbuffered code blocks ATM // since they are usually flow control // Buffer code if (code.buffer) { var val = code.val.trim(); val = 'null == (pug_interp = ' + val + ') ? "" : pug_interp'; if (code.mustEscape !== false) val = this.runtime('escape') + '(' + val + ')'; this.bufferExpression(val); } else { this.buf.push(code.val); } // Block support if (code.block) { if (!code.buffer) this.buf.push('{'); this.visit(code.block, code); if (!code.buffer) this.buf.push('}'); } }, /** * Visit `Conditional`. * * @param {Conditional} cond * @api public */ visitConditional: function(cond) { var test = cond.test; this.buf.push('if (' + test + ') {'); this.visit(cond.consequent, cond); this.buf.push('}'); if (cond.alternate) { if (cond.alternate.type === 'Conditional') { this.buf.push('else'); this.visitConditional(cond.alternate); } else { this.buf.push('else {'); this.visit(cond.alternate, cond); this.buf.push('}'); } } }, /** * Visit `While`. * * @param {While} loop * @api public */ visitWhile: function(loop) { var test = loop.test; this.buf.push('while (' + test + ') {'); this.visit(loop.block, loop); this.buf.push('}'); }, /** * Visit `each` block. * * @param {Each} each * @api public */ visitEach: function(each) { var indexVarName = each.key || 'pug_index' + this.eachCount; this.eachCount++; this.buf.push( '' + '// iterate ' + each.obj + '\n' + ';(function(){\n' + ' var $$obj = ' + each.obj + ';\n' + " if ('number' == typeof $$obj.length) {" ); if (each.alternate) { this.buf.push(' if ($$obj.length) {'); } this.buf.push( '' + ' for (var ' + indexVarName + ' = 0, $$l = $$obj.length; ' + indexVarName + ' < $$l; ' + indexVarName + '++) {\n' + ' var ' + each.val + ' = $$obj[' + indexVarName + '];' ); this.visit(each.block, each); this.buf.push(' }'); if (each.alternate) { this.buf.push(' } else {'); this.visit(each.alternate, each); this.buf.push(' }'); } this.buf.push( '' + ' } else {\n' + ' var $$l = 0;\n' + ' for (var ' + indexVarName + ' in $$obj) {\n' + ' $$l++;\n' + ' var ' + each.val + ' = $$obj[' + indexVarName + '];' ); this.visit(each.block, each); this.buf.push(' }'); if (each.alternate) { this.buf.push(' if ($$l === 0) {'); this.visit(each.alternate, each); this.buf.push(' }'); } this.buf.push(' }\n}).call(this);\n'); }, visitEachOf: function(each) { this.buf.push( '' + '// iterate ' + each.obj + '\n' + 'for (const ' + each.val + ' of ' + each.obj + ') {\n' ); this.visit(each.block, each); this.buf.push('}\n'); }, /** * Visit `attrs`. * * @param {Array} attrs * @api public */ visitAttributes: function(attrs, attributeBlocks) { if (attributeBlocks.length) { if (attrs.length) { var val = this.attrs(attrs); attributeBlocks.unshift(val); } if (attributeBlocks.length > 1) { this.bufferExpression( this.runtime('attrs') + '(' + this.runtime('merge') + '([' + attributeBlocks.join(',') + ']), ' + stringify(this.terse) + ')' ); } else { this.bufferExpression( this.runtime('attrs') + '(' + attributeBlocks[0] + ', ' + stringify(this.terse) + ')' ); } } else if (attrs.length) { this.attrs(attrs, true); } }, /** * Compile attributes. */ attrs: function(attrs, buffer) { var res = compileAttrs(attrs, { terse: this.terse, format: buffer ? 'html' : 'object', runtime: this.runtime.bind(this), }); if (buffer) { this.bufferExpression(res); } return res; }, /** * Compile attribute blocks. */ attributeBlocks: function(attributeBlocks) { return ( attributeBlocks && attributeBlocks.slice().map(function(attrBlock) { return attrBlock.val; }) ); }, }; function tagCanInline(tag) { function isInline(node) { // Recurse if the node is a block if (node.type === 'Block') return node.nodes.every(isInline); // When there is a YieldBlock here, it is an indication that the file is // expected to be included but is not. If this is the case, the block // must be empty. if (node.type === 'YieldBlock') return true; return (node.type === 'Text' && !/\n/.test(node.val)) || node.isInline; } return tag.block.nodes.every(isInline); } ================================================ FILE: packages/pug-code-gen/package.json ================================================ { "name": "pug-code-gen", "version": "2.0.2", "description": "Default code-generator for pug. It generates HTML via a JavaScript template function.", "keywords": [ "pug" ], "dependencies": { "constantinople": "^4.0.1", "doctypes": "^1.1.0", "js-stringify": "^1.0.2", "pug-attrs": "^2.0.4", "pug-error": "^1.3.3", "pug-runtime": "^2.0.5", "void-elements": "^3.1.0", "with": "^7.0.0" }, "files": [ "index.js" ], "repository": { "type": "git", "url": "https://github.com/pugjs/pug/tree/master/packages/pug-code-gen" }, "author": "Forbes Lindesay", "license": "MIT" } ================================================ FILE: packages/pug-error/LICENSE ================================================ Copyright (c) 2015 Forbes Lindesay 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. ================================================ FILE: packages/pug-error/README.md ================================================ # pug-error Standard error objects for pug. This module is intended for use by the lexer, parser, loader, linker, code-generator and any plugins. [![Build Status](https://img.shields.io/travis/pugjs/pug-error/master.svg)](https://travis-ci.org/pugjs/pug-error) [![Dependencies Status](https://david-dm.org/pugjs/pug/status.svg?path=packages/pug-error)](https://david-dm.org/pugjs/pug?path=packages/pug-error) [![NPM version](https://img.shields.io/npm/v/pug-error.svg)](https://www.npmjs.org/package/pug-error) ## Installation npm install pug-error ## Usage ```js var error = require('pug-error'); ``` ### `error(code, message, options)` Create a Pug error object. `code` is a required unique code for the error type that can be used to pinpoint a certain error. `message` is a human-readable explanation of the error. `options` can contain any of the following properties: - `filename`: the name of the file causing the error - `line`: the offending line - `column`: the offending column - `src`: the Pug source, if available, for pretty-printing the error context The resulting error object is a simple Error object with additional properties given in the arguments. **Caveat:** the `message` argument is stored in `err.msg`, not `err.message`, which is occupied with a better-formatted message. ```js var error = require('pug-error'); var err = error('MY_CODE', 'My message', {line: 3, filename: 'myfile', src: 'foo\nbar\nbaz\nbash\nbing'}); // { code: 'PUG:MY_CODE', // msg: 'My message', // line: 3, // column: undefined, // filename: 'myfile', // src: 'foo\nbar\nbaz\nbash\nbing', // message: 'myfile:3\n 1| foo\n 2| bar\n > 3| baz\n 4| bash\n 5| bing\n\nMy message' } throw err; ``` ## License MIT ================================================ FILE: packages/pug-error/package.json ================================================ { "name": "pug-error", "version": "1.3.3", "description": "Standard error objects for pug", "main": "./lib/index.js", "types": "./lib/index.d.ts", "keywords": [ "pug" ], "files": [ "lib/" ], "repository": { "type": "git", "url": "https://github.com/pugjs/pug/tree/master/packages/pug-error" }, "author": "Forbes Lindesay", "license": "MIT" } ================================================ FILE: packages/pug-error/src/index.ts ================================================ export default function makeError( code: string, message: string, options: {line: number; column: number; filename?: string; src?: string}, ) { const line = options.line; const column = options.column; const filename = options.filename; const src = options.src; let fullMessage; const location = line + (column ? ':' + column : ''); if (src && line >= 1 && line <= src.split('\n').length) { const lines = src.split('\n'); const start = Math.max(line - 3, 0); const end = Math.min(lines.length, line + 3); // Error context const context = lines .slice(start, end) .map(function(text, i) { const curr = i + start + 1; const preamble = (curr == line ? ' > ' : ' ') + curr + '| '; let out = preamble + text; if (curr === line && column > 0) { out += '\n'; out += Array(preamble.length + column).join('-') + '^'; } return out; }) .join('\n'); fullMessage = (filename || 'Pug') + ':' + location + '\n' + context + '\n\n' + message; } else { fullMessage = (filename || 'Pug') + ':' + location + '\n\n' + message; } const err: any = new Error(fullMessage); err.code = 'PUG:' + code; err.msg = message; err.line = line; err.column = column; err.filename = filename; err.src = src; err.toJSON = function() { return { code: this.code, msg: this.msg, line: this.line, column: this.column, filename: this.filename, }; }; return err; } // Make this easier to use from CommonJS module.exports = makeError; module.exports.default = makeError; ================================================ FILE: packages/pug-error/test/index.test.js ================================================ 'use strict'; var error = require('../'); describe('with a source', function() { test('and a filename', function() { var err = error('MY_CODE', 'My message', { line: 3, filename: 'myfile', src: 'foo\nbar\nbaz\nbash\nbing', }); expect(err.message).toBe( 'myfile:3\n 1| foo\n 2| bar\n > 3| baz\n 4| bash\n 5| bing\n\nMy message' ); expect(err.code).toBe('PUG:MY_CODE'); expect(err.msg).toBe('My message'); expect(err.line).toBe(3); expect(err.filename).toBe('myfile'); expect(err.src).toBe('foo\nbar\nbaz\nbash\nbing'); }); test('and no filename', function() { var err = error('MY_CODE', 'My message', { line: 3, src: 'foo\nbar\nbaz\nbash\nbing', }); expect(err.message).toBe( 'Pug:3\n 1| foo\n 2| bar\n > 3| baz\n 4| bash\n 5| bing\n\nMy message' ); expect(err.code).toBe('PUG:MY_CODE'); expect(err.msg).toBe('My message'); expect(err.line).toBe(3); expect(err.filename).toBe(undefined); expect(err.src).toBe('foo\nbar\nbaz\nbash\nbing'); }); }); describe('without source', function() { test('and with a filename', function() { var err = error('MY_CODE', 'My message', {line: 3, filename: 'myfile'}); expect(err.message).toBe('myfile:3\n\nMy message'); expect(err.code).toBe('PUG:MY_CODE'); expect(err.msg).toBe('My message'); expect(err.line).toBe(3); expect(err.filename).toBe('myfile'); expect(err.src).toBe(undefined); }); test('and with no filename', function() { var err = error('MY_CODE', 'My message', {line: 3}); expect(err.message).toBe('Pug:3\n\nMy message'); expect(err.code).toBe('PUG:MY_CODE'); expect(err.msg).toBe('My message'); expect(err.line).toBe(3); expect(err.filename).toBe(undefined); expect(err.src).toBe(undefined); }); }); describe('with column', function() { test('and with a filename', function() { var err = error('MY_CODE', 'My message', { line: 3, column: 2, filename: 'myfile', src: 'foo\nbar\nbaz\nbash\nbing', }); expect(err.message).toBe( 'myfile:3:2\n 1| foo\n 2| bar\n > 3| baz\n--------^\n 4| bash\n 5| bing\n\nMy message' ); expect(err.code).toBe('PUG:MY_CODE'); expect(err.msg).toBe('My message'); expect(err.line).toBe(3); expect(err.filename).toBe('myfile'); expect(err.src).toBe('foo\nbar\nbaz\nbash\nbing'); }); test('and with no filename', function() { var err = error('MY_CODE', 'My message', {line: 3, column: 1}); expect(err.message).toBe('Pug:3:1\n\nMy message'); expect(err.code).toBe('PUG:MY_CODE'); expect(err.msg).toBe('My message'); expect(err.line).toBe(3); expect(err.filename).toBe(undefined); expect(err.src).toBe(undefined); }); }); describe('invalid information', function() { test('negative column', function() { var err = error('MY_CODE', 'My message', { line: 3, column: -1, src: 'foo\nbar\nbaz\nbash\nbing', }); expect(err.message).toBe( 'Pug:3:-1\n 1| foo\n 2| bar\n > 3| baz\n 4| bash\n 5| bing\n\nMy message' ); expect(err.code).toBe('PUG:MY_CODE'); expect(err.msg).toBe('My message'); expect(err.line).toBe(3); expect(err.filename).toBe(undefined); expect(err.src).toBe('foo\nbar\nbaz\nbash\nbing'); }); test('out of range line', function() { check(0); check(6); function check(line) { var err = error('MY_CODE', 'My message', { line: line, src: 'foo\nbar\nbaz\nbash\nbing', }); expect(err.message).toBe('Pug:' + line + '\n\nMy message'); expect(err.code).toBe('PUG:MY_CODE'); expect(err.msg).toBe('My message'); expect(err.line).toBe(line); expect(err.filename).toBe(undefined); expect(err.src).toBe('foo\nbar\nbaz\nbash\nbing'); } }); }); ================================================ FILE: packages/pug-error/tsconfig.json ================================================ { "extends": "../../tsconfig.json", "compilerOptions": { "composite": true, "rootDir": "src", "outDir": "lib", "tsBuildInfoFile": "lib/tsconfig.tsbuildinfo", }, "references": [], } ================================================ FILE: packages/pug-filters/CHANGELOG.md ================================================ # Change log ## 1.2.4 / 2016-08-23 - Update to `pug-walk@1.0.0` ## 1.2.3 / 2016-07-18 - Fix includes using custom filters ## 1.2.2 / 2016-06-06 - Update to `jstransformer@1.0.0` ## 1.2.1 / 2016-04-27 - Apply filters to included files as well ## 1.2.0 / 2016-04-01 - Add support for specifying per-filter options ## 1.1.1 / 2015-12-23 - Update UglifyJS to 2.6.2 - Rename to Pug ## 1.1.0 / 2015-11-14 - Add support for filtered includes ## 1.0.0 / 2015-10-08 - Initial stable release ================================================ FILE: packages/pug-filters/LICENSE ================================================ Copyright (c) 2015 Forbes Lindesay 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. ================================================ FILE: packages/pug-filters/README.md ================================================ # pug-filters Code for processing filters in pug templates [![Build Status](https://img.shields.io/travis/pugjs/pug-filters/master.svg)](https://travis-ci.org/pugjs/pug-filters) [![Dependencies Status](https://david-dm.org/pugjs/pug/status.svg?path=packages/pug-filters)](https://david-dm.org/pugjs/pug?path=packages/pug-filters) [![DevDependencies Status](https://david-dm.org/pugjs/pug/dev-status.svg?path=packages/pug-filters)](https://david-dm.org/pugjs/pug?path=packages/pug-filters&type=dev) [![NPM version](https://img.shields.io/npm/v/pug-filters.svg)](https://www.npmjs.org/package/pug-filters) ## Installation npm install pug-filters ## Usage ``` var filters = require('pug-filters'); ``` ### `filters.handleFilters(ast, filters)` Renders all `Filter` nodes in a Pug AST (`ast`), using user-specified filters (`filters`) or a JSTransformer. ### `filters.runFilter(name, str[, options[, currentDirectory]])` Invokes filter through `jstransformer`. This is internally used in `filters.handleFilters`, and is a lower-level interface exclusively for invoking JSTransformer-based filters. `name` represents the name of the JSTransformer. `str` represents the string to render. `currentDirectory` is used when attempting to `require` the transformer module. `options` may contain the following properties: - `minify` (boolean): whether or not to attempt minifying the result from the transformer. If minification fails, the original result is returned. ## License MIT ================================================ FILE: packages/pug-filters/index.js ================================================ 'use strict'; exports.runFilter = require('./lib/run-filter'); exports.handleFilters = require('./lib/handle-filters'); ================================================ FILE: packages/pug-filters/lib/handle-filters.js ================================================ 'use strict'; var dirname = require('path').dirname; var constantinople = require('constantinople'); var walk = require('pug-walk'); var error = require('pug-error'); var runFilter = require('./run-filter'); module.exports = handleFilters; function handleFilters(ast, filters, options, filterAliases) { options = options || {}; walk( ast, function(node) { var dir = node.filename ? dirname(node.filename) : null; if (node.type === 'Filter') { handleNestedFilters(node, filters, options, filterAliases); var text = getBodyAsText(node); var attrs = getAttributes(node, options); attrs.filename = node.filename; node.type = 'Text'; node.val = filterWithFallback(node, text, attrs); } else if (node.type === 'RawInclude' && node.filters.length) { var firstFilter = node.filters.pop(); var attrs = getAttributes(firstFilter, options); var filename = (attrs.filename = node.file.fullPath); node.type = 'Text'; node.val = filterFileWithFallback( firstFilter, filename, node.file, attrs ); node.filters .slice() .reverse() .forEach(function(filter) { var attrs = getAttributes(filter, options); attrs.filename = filename; node.val = filterWithFallback(filter, node.val, attrs); }); node.filters = undefined; node.file = undefined; } function filterWithFallback(filter, text, attrs, funcName) { try { var filterName = getFilterName(filter); if (filters && filters[filterName]) { return filters[filterName](text, attrs); } else { return runFilter(filterName, text, attrs, dir, funcName); } } catch (ex) { if (ex.code === 'UNKNOWN_FILTER') { throw error(ex.code, ex.message, filter); } throw ex; } } function filterFileWithFallback(filter, filename, file, attrs) { var filterName = getFilterName(filter); if (filters && filters[filterName]) { if (filters[filterName].renderBuffer) { return filters[filterName].renderBuffer(file.raw, attrs); } else { return filters[filterName](file.str, attrs); } } else { return filterWithFallback(filter, filename, attrs, 'renderFile'); } } }, {includeDependencies: true} ); function getFilterName(filter) { var filterName = filter.name; if (filterAliases && filterAliases[filterName]) { filterName = filterAliases[filterName]; if (filterAliases[filterName]) { throw error( 'FILTER_ALISE_CHAIN', 'The filter "' + filter.name + '" is an alias for "' + filterName + '", which is an alias for "' + filterAliases[filterName] + '". Pug does not support chains of filter aliases.', filter ); } } return filterName; } return ast; } function handleNestedFilters(node, filters, options, filterAliases) { if (node.block.nodes[0] && node.block.nodes[0].type === 'Filter') { node.block.nodes[0] = handleFilters( node.block, filters, options, filterAliases ).nodes[0]; } } function getBodyAsText(node) { return node.block.nodes .map(function(node) { return node.val; }) .join(''); } function getAttributes(node, options) { var attrs = {}; node.attrs.forEach(function(attr) { try { attrs[attr.name] = attr.val === true ? true : constantinople.toConstant(attr.val); } catch (ex) { if (/not constant/.test(ex.message)) { throw error( 'FILTER_OPTION_NOT_CONSTANT', ex.message + ' All filters are rendered compile-time so filter options must be constants.', node ); } throw ex; } }); var opts = options[node.name] || {}; Object.keys(opts).forEach(function(opt) { if (!attrs.hasOwnProperty(opt)) { attrs[opt] = opts[opt]; } }); return attrs; } ================================================ FILE: packages/pug-filters/lib/run-filter.js ================================================ 'use strict'; var jstransformer = require('jstransformer'); var resolve = require('resolve'); module.exports = filter; function getMinifyTransformerName(outputFormat) { switch (outputFormat) { case 'js': return 'uglify-js'; case 'css': return 'clean-css'; } } function filter(name, str, options, currentDirectory, funcName) { funcName = funcName || 'render'; var trPath; try { try { trPath = resolve.sync('jstransformer-' + name, { basedir: currentDirectory || process.cwd(), }); } catch (ex) { trPath = require.resolve('jstransformer-' + name); } } catch (ex) { var err = new Error('unknown filter ":' + name + '"'); err.code = 'UNKNOWN_FILTER'; throw err; } var tr = jstransformer(require(trPath)); // TODO: we may want to add a way for people to separately specify "locals" var result = tr[funcName](str, options, options).body; if (options && options.minify) { var minifyTranformer = getMinifyTransformerName(tr.outputFormat); if (minifyTranformer) { try { result = filter(minifyTranformer, result, null, currentDirectory); } catch (ex) { // better to fail to minify than output nothing } } } return result; } ================================================ FILE: packages/pug-filters/package.json ================================================ { "name": "pug-filters", "version": "3.1.1", "description": "Code for processing filters in pug templates", "keywords": [ "pug" ], "dependencies": { "constantinople": "^4.0.1", "jstransformer": "1.0.0", "pug-error": "^1.3.3", "pug-walk": "^1.1.8", "resolve": "^1.15.1" }, "devDependencies": { "jstransformer-cdata": "^1.0.0", "jstransformer-coffee-script": "^1.1.1", "jstransformer-less": "^2.3.0", "jstransformer-markdown-it": "^2.0.0", "jstransformer-stylus": "^1.5.0", "jstransformer-uglify-js": "^1.2.0", "pug-lexer": "^4.1.0", "pug-load": "^2.0.12", "pug-parser": "^5.0.1" }, "files": [ "lib/handle-filters.js", "lib/run-filter.js", "index.js" ], "repository": { "type": "git", "url": "https://github.com/pugjs/pug/tree/master/packages/pug-filters" }, "author": "Forbes Lindesay", "license": "MIT" } ================================================ FILE: packages/pug-filters/test/__snapshots__/filter-aliases.test.js.snap ================================================ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`filters can be aliased 1`] = ` Object { "filename": "/packages/pug-filters/test/filter-aliases.test.js", "line": 0, "nodes": Array [ Object { "attributeBlocks": Array [], "attrs": Array [], "block": Object { "filename": "/packages/pug-filters/test/filter-aliases.test.js", "line": 2, "nodes": Array [ Object { "attrs": Array [], "block": Object { "filename": "/packages/pug-filters/test/filter-aliases.test.js", "line": 3, "nodes": Array [ Object { "attrs": Array [], "block": Object { "filename": "/packages/pug-filters/test/filter-aliases.test.js", "line": 3, "nodes": Array [ Object { "column": 5, "filename": "/packages/pug-filters/test/filter-aliases.test.js", "line": 4, "type": "Text", "val": "function myFunc(foo) {", }, Object { "column": 1, "filename": "/packages/pug-filters/test/filter-aliases.test.js", "line": 5, "type": "Text", "val": " ", }, Object { "column": 5, "filename": "/packages/pug-filters/test/filter-aliases.test.js", "line": 5, "type": "Text", "val": " return foo;", }, Object { "column": 1, "filename": "/packages/pug-filters/test/filter-aliases.test.js", "line": 6, "type": "Text", "val": " ", }, Object { "column": 5, "filename": "/packages/pug-filters/test/filter-aliases.test.js", "line": 6, "type": "Text", "val": "}", }, ], "type": "Block", }, "column": 9, "filename": "/packages/pug-filters/test/filter-aliases.test.js", "line": 3, "name": "minify", "type": "Text", "val": "function myFunc(n) { return n; } ", }, ], "type": "Block", }, "column": 3, "filename": "/packages/pug-filters/test/filter-aliases.test.js", "line": 3, "name": "cdata", "type": "Text", "val": "", }, ], "type": "Block", }, "column": 1, "filename": "/packages/pug-filters/test/filter-aliases.test.js", "isInline": false, "line": 2, "name": "script", "selfClosing": false, "type": "Tag", }, ], "type": "Block", } `; exports[`options are applied before aliases 1`] = ` Object { "filename": "/packages/pug-filters/test/filter-aliases.test.js", "line": 0, "nodes": Array [ Object { "attributeBlocks": Array [], "attrs": Array [], "block": Object { "filename": "/packages/pug-filters/test/filter-aliases.test.js", "line": 2, "nodes": Array [ Object { "attrs": Array [], "block": Object { "filename": "/packages/pug-filters/test/filter-aliases.test.js", "line": 3, "nodes": Array [ Object { "attrs": Array [], "block": Object { "filename": "/packages/pug-filters/test/filter-aliases.test.js", "line": 3, "nodes": Array [ Object { "column": 5, "filename": "/packages/pug-filters/test/filter-aliases.test.js", "line": 4, "type": "Text", "val": "function myFunc(foo) {", }, Object { "column": 1, "filename": "/packages/pug-filters/test/filter-aliases.test.js", "line": 5, "type": "Text", "val": " ", }, Object { "column": 5, "filename": "/packages/pug-filters/test/filter-aliases.test.js", "line": 5, "type": "Text", "val": " return foo;", }, Object { "column": 1, "filename": "/packages/pug-filters/test/filter-aliases.test.js", "line": 6, "type": "Text", "val": " ", }, Object { "column": 5, "filename": "/packages/pug-filters/test/filter-aliases.test.js", "line": 6, "type": "Text", "val": "}", }, ], "type": "Block", }, "column": 9, "filename": "/packages/pug-filters/test/filter-aliases.test.js", "line": 3, "name": "minify", "type": "Text", "val": "function myFunc(n) { return n; } ", }, ], "type": "Block", }, "column": 3, "filename": "/packages/pug-filters/test/filter-aliases.test.js", "line": 3, "name": "cdata", "type": "Text", "val": "", }, Object { "attrs": Array [], "block": Object { "filename": "/packages/pug-filters/test/filter-aliases.test.js", "line": 7, "nodes": Array [ Object { "attrs": Array [], "block": Object { "filename": "/packages/pug-filters/test/filter-aliases.test.js", "line": 7, "nodes": Array [ Object { "column": 5, "filename": "/packages/pug-filters/test/filter-aliases.test.js", "line": 8, "type": "Text", "val": "function myFunc(foo) {", }, Object { "column": 1, "filename": "/packages/pug-filters/test/filter-aliases.test.js", "line": 9, "type": "Text", "val": " ", }, Object { "column": 5, "filename": "/packages/pug-filters/test/filter-aliases.test.js", "line": 9, "type": "Text", "val": " return foo;", }, Object { "column": 1, "filename": "/packages/pug-filters/test/filter-aliases.test.js", "line": 10, "type": "Text", "val": " ", }, Object { "column": 5, "filename": "/packages/pug-filters/test/filter-aliases.test.js", "line": 10, "type": "Text", "val": "}", }, ], "type": "Block", }, "column": 9, "filename": "/packages/pug-filters/test/filter-aliases.test.js", "line": 7, "name": "uglify-js", "type": "Text", "val": "function myFunc(n) { return n; } ", }, ], "type": "Block", }, "column": 3, "filename": "/packages/pug-filters/test/filter-aliases.test.js", "line": 7, "name": "cdata", "type": "Text", "val": "", }, ], "type": "Block", }, "column": 1, "filename": "/packages/pug-filters/test/filter-aliases.test.js", "isInline": false, "line": 2, "name": "script", "selfClosing": false, "type": "Tag", }, ], "type": "Block", } `; exports[`we do not support chains of aliases 1`] = ` Object { "code": "PUG:FILTER_ALISE_CHAIN", "message": "/packages/pug-filters/test/filter-aliases.test.js:3:9 The filter \\"minify-js\\" is an alias for \\"minify\\", which is an alias for \\"uglify-js\\". Pug does not support chains of filter aliases.", } `; ================================================ FILE: packages/pug-filters/test/__snapshots__/index.test.js.snap ================================================ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`cases/filters.cdata.input.json 1`] = ` "{ \\"type\\": \\"Block\\", \\"nodes\\": [ { \\"type\\": \\"Code\\", \\"val\\": \\"users = [{ name: 'tobi', age: 2 }]\\", \\"buffer\\": false, \\"mustEscape\\": false, \\"isInline\\": false, \\"line\\": 2, \\"filename\\": \\"filters.cdata.tokens.json\\" }, { \\"type\\": \\"Tag\\", \\"name\\": \\"fb:users\\", \\"selfClosing\\": false, \\"block\\": { \\"type\\": \\"Block\\", \\"nodes\\": [ { \\"type\\": \\"Each\\", \\"obj\\": \\"users\\", \\"val\\": \\"user\\", \\"block\\": { \\"type\\": \\"Block\\", \\"nodes\\": [ { \\"type\\": \\"Tag\\", \\"name\\": \\"fb:user\\", \\"selfClosing\\": false, \\"block\\": { \\"type\\": \\"Block\\", \\"nodes\\": [ { \\"type\\": \\"Text\\", \\"name\\": \\"cdata\\", \\"block\\": { \\"type\\": \\"Block\\", \\"nodes\\": [ { \\"type\\": \\"Text\\", \\"val\\": \\"#{user.name}\\", \\"line\\": 8 } ] }, \\"attrs\\": [], \\"line\\": 7, \\"filename\\": \\"filters.cdata.tokens.json\\", \\"val\\": \\"\\" } ] }, \\"attrs\\": [ { \\"name\\": \\"age\\", \\"val\\": \\"user.age\\", \\"mustEscape\\": true } ], \\"attributeBlocks\\": [], \\"isInline\\": false, \\"line\\": 6, \\"filename\\": \\"filters.cdata.tokens.json\\" } ], \\"line\\": 6, \\"filename\\": \\"filters.cdata.tokens.json\\" }, \\"line\\": 5, \\"filename\\": \\"filters.cdata.tokens.json\\" } ] }, \\"attrs\\": [], \\"attributeBlocks\\": [], \\"isInline\\": false, \\"line\\": 4, \\"filename\\": \\"filters.cdata.tokens.json\\" } ], \\"line\\": 0, \\"filename\\": \\"filters.cdata.tokens.json\\" }" `; exports[`cases/filters.coffeescript.input.json 1`] = ` "{ \\"type\\": \\"Block\\", \\"nodes\\": [ { \\"type\\": \\"Tag\\", \\"name\\": \\"script\\", \\"selfClosing\\": false, \\"block\\": { \\"type\\": \\"Block\\", \\"nodes\\": [ { \\"type\\": \\"Text\\", \\"name\\": \\"coffee-script\\", \\"block\\": { \\"type\\": \\"Block\\", \\"nodes\\": [ { \\"type\\": \\"Text\\", \\"val\\": \\"regexp = /\\\\\\\\n/\\", \\"line\\": 3 } ], \\"line\\": 2, \\"filename\\": \\"filters.coffeescript.tokens.json\\" }, \\"attrs\\": [], \\"line\\": 2, \\"filename\\": \\"filters.coffeescript.tokens.json\\", \\"val\\": \\"(function() {\\\\n var regexp;\\\\n\\\\n regexp = /\\\\\\\\n/;\\\\n\\\\n}).call(this);\\\\n\\" }, { \\"type\\": \\"Text\\", \\"name\\": \\"coffee-script\\", \\"block\\": { \\"type\\": \\"Block\\", \\"nodes\\": [ { \\"type\\": \\"Text\\", \\"val\\": \\"math =\\", \\"line\\": 5 }, { \\"type\\": \\"Text\\", \\"val\\": \\"\\\\n\\", \\"line\\": 6 }, { \\"type\\": \\"Text\\", \\"val\\": \\" square: (value) -> value * value\\", \\"line\\": 6 } ], \\"line\\": 4, \\"filename\\": \\"filters.coffeescript.tokens.json\\" }, \\"attrs\\": [ { \\"name\\": \\"minify\\", \\"val\\": \\"true\\", \\"mustEscape\\": true } ], \\"line\\": 4, \\"filename\\": \\"filters.coffeescript.tokens.json\\", \\"val\\": \\"(function(){}).call(this);\\" } ], \\"line\\": 1, \\"filename\\": \\"filters.coffeescript.tokens.json\\" }, \\"attrs\\": [ { \\"name\\": \\"type\\", \\"val\\": \\"'text/javascript'\\", \\"mustEscape\\": true } ], \\"attributeBlocks\\": [], \\"isInline\\": false, \\"line\\": 1, \\"filename\\": \\"filters.coffeescript.tokens.json\\" } ], \\"line\\": 0, \\"filename\\": \\"filters.coffeescript.tokens.json\\" }" `; exports[`cases/filters.custom.input.json 1`] = ` "{ \\"type\\": \\"Block\\", \\"nodes\\": [ { \\"type\\": \\"Tag\\", \\"name\\": \\"html\\", \\"selfClosing\\": false, \\"block\\": { \\"type\\": \\"Block\\", \\"nodes\\": [ { \\"type\\": \\"Tag\\", \\"name\\": \\"body\\", \\"selfClosing\\": false, \\"block\\": { \\"type\\": \\"Block\\", \\"nodes\\": [ { \\"type\\": \\"Text\\", \\"name\\": \\"custom\\", \\"block\\": { \\"type\\": \\"Block\\", \\"nodes\\": [ { \\"type\\": \\"Text\\", \\"val\\": \\"Line 1\\", \\"line\\": 4 }, { \\"type\\": \\"Text\\", \\"val\\": \\"\\\\n\\", \\"line\\": 5 }, { \\"type\\": \\"Text\\", \\"val\\": \\"Line 2\\", \\"line\\": 5 }, { \\"type\\": \\"Text\\", \\"val\\": \\"\\\\n\\", \\"line\\": 6 }, { \\"type\\": \\"Text\\", \\"val\\": \\"\\", \\"line\\": 6 }, { \\"type\\": \\"Text\\", \\"val\\": \\"\\\\n\\", \\"line\\": 7 }, { \\"type\\": \\"Text\\", \\"val\\": \\"Line 4\\", \\"line\\": 7 } ], \\"line\\": 3, \\"filename\\": \\"filters.custom.tokens.json\\" }, \\"attrs\\": [ { \\"name\\": \\"opt\\", \\"val\\": \\"'val'\\", \\"mustEscape\\": true }, { \\"name\\": \\"num\\", \\"val\\": \\"2\\", \\"mustEscape\\": true } ], \\"line\\": 3, \\"filename\\": \\"filters.custom.tokens.json\\", \\"val\\": \\"BEGINLine 1\\\\nLine 2\\\\n\\\\nLine 4END\\" } ], \\"line\\": 2, \\"filename\\": \\"filters.custom.tokens.json\\" }, \\"attrs\\": [], \\"attributeBlocks\\": [], \\"isInline\\": false, \\"line\\": 2, \\"filename\\": \\"filters.custom.tokens.json\\" } ], \\"line\\": 1, \\"filename\\": \\"filters.custom.tokens.json\\" }, \\"attrs\\": [], \\"attributeBlocks\\": [], \\"isInline\\": false, \\"line\\": 1, \\"filename\\": \\"filters.custom.tokens.json\\" } ], \\"line\\": 0, \\"filename\\": \\"filters.custom.tokens.json\\" }" `; exports[`cases/filters.include.custom.input.json 1`] = ` "{ \\"type\\": \\"Block\\", \\"nodes\\": [ { \\"type\\": \\"Tag\\", \\"name\\": \\"html\\", \\"selfClosing\\": false, \\"block\\": { \\"type\\": \\"Block\\", \\"nodes\\": [ { \\"type\\": \\"Tag\\", \\"name\\": \\"body\\", \\"selfClosing\\": false, \\"block\\": { \\"type\\": \\"Block\\", \\"nodes\\": [ { \\"type\\": \\"Tag\\", \\"name\\": \\"pre\\", \\"selfClosing\\": false, \\"block\\": { \\"type\\": \\"Block\\", \\"nodes\\": [ { \\"type\\": \\"Text\\", \\"line\\": 4, \\"filename\\": \\"filters.include.custom.tokens.json\\", \\"val\\": \\"BEGINhtml\\\\n body\\\\n pre\\\\n include:custom(opt='val' num=2) filters.include.custom.pug\\\\nEND\\" } ], \\"line\\": 3, \\"filename\\": \\"filters.include.custom.tokens.json\\" }, \\"attrs\\": [], \\"attributeBlocks\\": [], \\"isInline\\": false, \\"line\\": 3, \\"filename\\": \\"filters.include.custom.tokens.json\\" } ], \\"line\\": 2, \\"filename\\": \\"filters.include.custom.tokens.json\\" }, \\"attrs\\": [], \\"attributeBlocks\\": [], \\"isInline\\": false, \\"line\\": 2, \\"filename\\": \\"filters.include.custom.tokens.json\\" } ], \\"line\\": 1, \\"filename\\": \\"filters.include.custom.tokens.json\\" }, \\"attrs\\": [], \\"attributeBlocks\\": [], \\"isInline\\": false, \\"line\\": 1, \\"filename\\": \\"filters.include.custom.tokens.json\\" } ], \\"line\\": 0, \\"filename\\": \\"filters.include.custom.tokens.json\\" }" `; exports[`cases/filters.include.input.json 1`] = ` "{ \\"type\\": \\"Block\\", \\"nodes\\": [ { \\"type\\": \\"Tag\\", \\"name\\": \\"html\\", \\"selfClosing\\": false, \\"block\\": { \\"type\\": \\"Block\\", \\"nodes\\": [ { \\"type\\": \\"Tag\\", \\"name\\": \\"body\\", \\"selfClosing\\": false, \\"block\\": { \\"type\\": \\"Block\\", \\"nodes\\": [ { \\"type\\": \\"Text\\", \\"line\\": 3, \\"filename\\": \\"filters.include.tokens.json\\", \\"val\\": \\"

    Just some markdown tests.

    \\\\n

    With new line.

    \\\\n\\" }, { \\"type\\": \\"Tag\\", \\"name\\": \\"script\\", \\"selfClosing\\": false, \\"block\\": { \\"type\\": \\"Block\\", \\"nodes\\": [ { \\"type\\": \\"Text\\", \\"line\\": 5, \\"filename\\": \\"filters.include.tokens.json\\", \\"val\\": \\"(function(){}).call(this);\\" } ], \\"line\\": 4, \\"filename\\": \\"filters.include.tokens.json\\" }, \\"attrs\\": [], \\"attributeBlocks\\": [], \\"isInline\\": false, \\"line\\": 4, \\"filename\\": \\"filters.include.tokens.json\\" }, { \\"type\\": \\"Tag\\", \\"name\\": \\"script\\", \\"selfClosing\\": false, \\"block\\": { \\"type\\": \\"Block\\", \\"nodes\\": [ { \\"type\\": \\"Text\\", \\"line\\": 7, \\"filename\\": \\"filters.include.tokens.json\\", \\"val\\": \\"\\" } ], \\"line\\": 6, \\"filename\\": \\"filters.include.tokens.json\\" }, \\"attrs\\": [], \\"attributeBlocks\\": [], \\"isInline\\": false, \\"line\\": 6, \\"filename\\": \\"filters.include.tokens.json\\" } ], \\"line\\": 2, \\"filename\\": \\"filters.include.tokens.json\\" }, \\"attrs\\": [], \\"attributeBlocks\\": [], \\"isInline\\": false, \\"line\\": 2, \\"filename\\": \\"filters.include.tokens.json\\" } ], \\"line\\": 1, \\"filename\\": \\"filters.include.tokens.json\\" }, \\"attrs\\": [], \\"attributeBlocks\\": [], \\"isInline\\": false, \\"line\\": 1, \\"filename\\": \\"filters.include.tokens.json\\" } ], \\"line\\": 0, \\"filename\\": \\"filters.include.tokens.json\\" }" `; exports[`cases/filters.inline.input.json 1`] = ` "{ \\"type\\": \\"Block\\", \\"nodes\\": [ { \\"type\\": \\"Tag\\", \\"name\\": \\"p\\", \\"selfClosing\\": false, \\"block\\": { \\"type\\": \\"Block\\", \\"nodes\\": [ { \\"type\\": \\"Text\\", \\"val\\": \\"before \\", \\"line\\": 1, \\"filename\\": \\"filters.inline.tokens.json\\" }, { \\"type\\": \\"Text\\", \\"name\\": \\"cdata\\", \\"block\\": { \\"type\\": \\"Block\\", \\"nodes\\": [ { \\"type\\": \\"Text\\", \\"val\\": \\"inside\\", \\"line\\": 1, \\"filename\\": \\"filters.inline.tokens.json\\" } ], \\"line\\": 1, \\"filename\\": \\"filters.inline.tokens.json\\" }, \\"attrs\\": [], \\"line\\": 1, \\"filename\\": \\"filters.inline.tokens.json\\", \\"val\\": \\"\\" }, { \\"type\\": \\"Text\\", \\"val\\": \\" after\\", \\"line\\": 1, \\"filename\\": \\"filters.inline.tokens.json\\" } ], \\"line\\": 1, \\"filename\\": \\"filters.inline.tokens.json\\" }, \\"attrs\\": [], \\"attributeBlocks\\": [], \\"isInline\\": false, \\"line\\": 1, \\"filename\\": \\"filters.inline.tokens.json\\" } ], \\"line\\": 0, \\"filename\\": \\"filters.inline.tokens.json\\" }" `; exports[`cases/filters.less.input.json 1`] = ` "{ \\"type\\": \\"Block\\", \\"nodes\\": [ { \\"type\\": \\"Tag\\", \\"name\\": \\"html\\", \\"selfClosing\\": false, \\"block\\": { \\"type\\": \\"Block\\", \\"nodes\\": [ { \\"type\\": \\"Tag\\", \\"name\\": \\"head\\", \\"selfClosing\\": false, \\"block\\": { \\"type\\": \\"Block\\", \\"nodes\\": [ { \\"type\\": \\"Tag\\", \\"name\\": \\"style\\", \\"selfClosing\\": false, \\"block\\": { \\"type\\": \\"Block\\", \\"nodes\\": [ { \\"type\\": \\"Text\\", \\"name\\": \\"less\\", \\"block\\": { \\"type\\": \\"Block\\", \\"nodes\\": [ { \\"type\\": \\"Text\\", \\"val\\": \\"@pad: 15px;\\", \\"line\\": 5 }, { \\"type\\": \\"Text\\", \\"val\\": \\"\\\\n\\", \\"line\\": 6 }, { \\"type\\": \\"Text\\", \\"val\\": \\"body {\\", \\"line\\": 6 }, { \\"type\\": \\"Text\\", \\"val\\": \\"\\\\n\\", \\"line\\": 7 }, { \\"type\\": \\"Text\\", \\"val\\": \\" padding: @pad;\\", \\"line\\": 7 }, { \\"type\\": \\"Text\\", \\"val\\": \\"\\\\n\\", \\"line\\": 8 }, { \\"type\\": \\"Text\\", \\"val\\": \\"}\\", \\"line\\": 8 } ], \\"line\\": 4, \\"filename\\": \\"filters.less.tokens.json\\" }, \\"attrs\\": [], \\"line\\": 4, \\"filename\\": \\"filters.less.tokens.json\\", \\"val\\": \\"body {\\\\n padding: 15px;\\\\n}\\\\n\\" } ], \\"line\\": 3, \\"filename\\": \\"filters.less.tokens.json\\" }, \\"attrs\\": [ { \\"name\\": \\"type\\", \\"val\\": \\"\\\\\\"text/css\\\\\\"\\", \\"mustEscape\\": true } ], \\"attributeBlocks\\": [], \\"isInline\\": false, \\"line\\": 3, \\"filename\\": \\"filters.less.tokens.json\\" } ], \\"line\\": 2, \\"filename\\": \\"filters.less.tokens.json\\" }, \\"attrs\\": [], \\"attributeBlocks\\": [], \\"isInline\\": false, \\"line\\": 2, \\"filename\\": \\"filters.less.tokens.json\\" } ], \\"line\\": 1, \\"filename\\": \\"filters.less.tokens.json\\" }, \\"attrs\\": [], \\"attributeBlocks\\": [], \\"isInline\\": false, \\"line\\": 1, \\"filename\\": \\"filters.less.tokens.json\\" } ], \\"line\\": 0, \\"filename\\": \\"filters.less.tokens.json\\" }" `; exports[`cases/filters.markdown.input.json 1`] = ` "{ \\"type\\": \\"Block\\", \\"nodes\\": [ { \\"type\\": \\"Tag\\", \\"name\\": \\"html\\", \\"selfClosing\\": false, \\"block\\": { \\"type\\": \\"Block\\", \\"nodes\\": [ { \\"type\\": \\"Tag\\", \\"name\\": \\"body\\", \\"selfClosing\\": false, \\"block\\": { \\"type\\": \\"Block\\", \\"nodes\\": [ { \\"type\\": \\"Text\\", \\"name\\": \\"markdown-it\\", \\"block\\": { \\"type\\": \\"Block\\", \\"nodes\\": [ { \\"type\\": \\"Text\\", \\"val\\": \\"This is _some_ awesome **markdown**\\", \\"line\\": 4 }, { \\"type\\": \\"Text\\", \\"val\\": \\"\\\\n\\", \\"line\\": 5 }, { \\"type\\": \\"Text\\", \\"val\\": \\"whoop.\\", \\"line\\": 5 } ], \\"line\\": 3, \\"filename\\": \\"filters.markdown.tokens.json\\" }, \\"attrs\\": [], \\"line\\": 3, \\"filename\\": \\"filters.markdown.tokens.json\\", \\"val\\": \\"

    This is some awesome markdown\\\\nwhoop.

    \\\\n\\" } ], \\"line\\": 2, \\"filename\\": \\"filters.markdown.tokens.json\\" }, \\"attrs\\": [], \\"attributeBlocks\\": [], \\"isInline\\": false, \\"line\\": 2, \\"filename\\": \\"filters.markdown.tokens.json\\" } ], \\"line\\": 1, \\"filename\\": \\"filters.markdown.tokens.json\\" }, \\"attrs\\": [], \\"attributeBlocks\\": [], \\"isInline\\": false, \\"line\\": 1, \\"filename\\": \\"filters.markdown.tokens.json\\" } ], \\"line\\": 0, \\"filename\\": \\"filters.markdown.tokens.json\\" }" `; exports[`cases/filters.nested.input.json 1`] = ` "{ \\"type\\": \\"Block\\", \\"nodes\\": [ { \\"type\\": \\"Tag\\", \\"name\\": \\"script\\", \\"selfClosing\\": false, \\"block\\": { \\"type\\": \\"Block\\", \\"nodes\\": [ { \\"type\\": \\"Text\\", \\"name\\": \\"cdata\\", \\"block\\": { \\"type\\": \\"Block\\", \\"nodes\\": [ { \\"type\\": \\"Text\\", \\"name\\": \\"uglify-js\\", \\"block\\": { \\"type\\": \\"Block\\", \\"nodes\\": [ { \\"type\\": \\"Text\\", \\"val\\": \\"(function() {\\", \\"line\\": 3 }, { \\"type\\": \\"Text\\", \\"val\\": \\"\\\\n\\", \\"line\\": 4 }, { \\"type\\": \\"Text\\", \\"val\\": \\" console.log('test')\\", \\"line\\": 4 }, { \\"type\\": \\"Text\\", \\"val\\": \\"\\\\n\\", \\"line\\": 5 }, { \\"type\\": \\"Text\\", \\"val\\": \\"})()\\", \\"line\\": 5 } ], \\"line\\": 2, \\"filename\\": \\"filters.nested.tokens.json\\" }, \\"attrs\\": [], \\"line\\": 2, \\"filename\\": \\"filters.nested.tokens.json\\", \\"val\\": \\"!function(){console.log(\\\\\\"test\\\\\\")}();\\" } ], \\"line\\": 2, \\"filename\\": \\"filters.nested.tokens.json\\" }, \\"attrs\\": [], \\"line\\": 2, \\"filename\\": \\"filters.nested.tokens.json\\", \\"val\\": \\"\\" } ], \\"line\\": 1, \\"filename\\": \\"filters.nested.tokens.json\\" }, \\"attrs\\": [], \\"attributeBlocks\\": [], \\"isInline\\": false, \\"line\\": 1, \\"filename\\": \\"filters.nested.tokens.json\\" }, { \\"type\\": \\"Tag\\", \\"name\\": \\"script\\", \\"selfClosing\\": false, \\"block\\": { \\"type\\": \\"Block\\", \\"nodes\\": [ { \\"type\\": \\"Text\\", \\"name\\": \\"cdata\\", \\"block\\": { \\"type\\": \\"Block\\", \\"nodes\\": [ { \\"type\\": \\"Text\\", \\"name\\": \\"uglify-js\\", \\"block\\": { \\"type\\": \\"Block\\", \\"nodes\\": [ { \\"type\\": \\"Text\\", \\"name\\": \\"coffee-script\\", \\"block\\": { \\"type\\": \\"Block\\", \\"nodes\\": [ { \\"type\\": \\"Text\\", \\"val\\": \\"(->\\", \\"line\\": 8 }, { \\"type\\": \\"Text\\", \\"val\\": \\"\\\\n\\", \\"line\\": 9 }, { \\"type\\": \\"Text\\", \\"val\\": \\" console.log 'test'\\", \\"line\\": 9 }, { \\"type\\": \\"Text\\", \\"val\\": \\"\\\\n\\", \\"line\\": 10 }, { \\"type\\": \\"Text\\", \\"val\\": \\")()\\", \\"line\\": 10 } ], \\"line\\": 7, \\"filename\\": \\"filters.nested.tokens.json\\" }, \\"attrs\\": [], \\"line\\": 7, \\"filename\\": \\"filters.nested.tokens.json\\", \\"val\\": \\"(function() {\\\\n (function() {\\\\n return console.log('test');\\\\n })();\\\\n\\\\n}).call(this);\\\\n\\" } ], \\"line\\": 7, \\"filename\\": \\"filters.nested.tokens.json\\" }, \\"attrs\\": [], \\"line\\": 7, \\"filename\\": \\"filters.nested.tokens.json\\", \\"val\\": \\"(function(){!function(){console.log(\\\\\\"test\\\\\\")}()}).call(this);\\" } ], \\"line\\": 7, \\"filename\\": \\"filters.nested.tokens.json\\" }, \\"attrs\\": [], \\"line\\": 7, \\"filename\\": \\"filters.nested.tokens.json\\", \\"val\\": \\"\\" } ], \\"line\\": 6, \\"filename\\": \\"filters.nested.tokens.json\\" }, \\"attrs\\": [], \\"attributeBlocks\\": [], \\"isInline\\": false, \\"line\\": 6, \\"filename\\": \\"filters.nested.tokens.json\\" } ], \\"line\\": 0, \\"filename\\": \\"filters.nested.tokens.json\\" }" `; exports[`cases/filters.stylus.input.json 1`] = ` "{ \\"type\\": \\"Block\\", \\"nodes\\": [ { \\"type\\": \\"Tag\\", \\"name\\": \\"html\\", \\"selfClosing\\": false, \\"block\\": { \\"type\\": \\"Block\\", \\"nodes\\": [ { \\"type\\": \\"Tag\\", \\"name\\": \\"head\\", \\"selfClosing\\": false, \\"block\\": { \\"type\\": \\"Block\\", \\"nodes\\": [ { \\"type\\": \\"Tag\\", \\"name\\": \\"style\\", \\"selfClosing\\": false, \\"block\\": { \\"type\\": \\"Block\\", \\"nodes\\": [ { \\"type\\": \\"Text\\", \\"name\\": \\"stylus\\", \\"block\\": { \\"type\\": \\"Block\\", \\"nodes\\": [ { \\"type\\": \\"Text\\", \\"val\\": \\"body\\", \\"line\\": 5 }, { \\"type\\": \\"Text\\", \\"val\\": \\"\\\\n\\", \\"line\\": 6 }, { \\"type\\": \\"Text\\", \\"val\\": \\" padding: 50px\\", \\"line\\": 6 } ], \\"line\\": 4, \\"filename\\": \\"filters.stylus.tokens.json\\" }, \\"attrs\\": [], \\"line\\": 4, \\"filename\\": \\"filters.stylus.tokens.json\\", \\"val\\": \\"body {\\\\n padding: 50px;\\\\n}\\\\n\\" } ], \\"line\\": 3, \\"filename\\": \\"filters.stylus.tokens.json\\" }, \\"attrs\\": [ { \\"name\\": \\"type\\", \\"val\\": \\"\\\\\\"text/css\\\\\\"\\", \\"mustEscape\\": true } ], \\"attributeBlocks\\": [], \\"isInline\\": false, \\"line\\": 3, \\"filename\\": \\"filters.stylus.tokens.json\\" } ], \\"line\\": 2, \\"filename\\": \\"filters.stylus.tokens.json\\" }, \\"attrs\\": [], \\"attributeBlocks\\": [], \\"isInline\\": false, \\"line\\": 2, \\"filename\\": \\"filters.stylus.tokens.json\\" }, { \\"type\\": \\"Tag\\", \\"name\\": \\"body\\", \\"selfClosing\\": false, \\"block\\": { \\"type\\": \\"Block\\", \\"nodes\\": [], \\"line\\": 7, \\"filename\\": \\"filters.stylus.tokens.json\\" }, \\"attrs\\": [], \\"attributeBlocks\\": [], \\"isInline\\": false, \\"line\\": 7, \\"filename\\": \\"filters.stylus.tokens.json\\" } ], \\"line\\": 1, \\"filename\\": \\"filters.stylus.tokens.json\\" }, \\"attrs\\": [], \\"attributeBlocks\\": [], \\"isInline\\": false, \\"line\\": 1, \\"filename\\": \\"filters.stylus.tokens.json\\" } ], \\"line\\": 0, \\"filename\\": \\"filters.stylus.tokens.json\\" }" `; exports[`cases/filters-empty.input.json 1`] = ` "{ \\"type\\": \\"Block\\", \\"nodes\\": [ { \\"type\\": \\"Code\\", \\"val\\": \\"var users = [{ name: 'tobi', age: 2 }]\\", \\"buffer\\": false, \\"mustEscape\\": false, \\"isInline\\": false, \\"line\\": 1, \\"filename\\": \\"filters-empty.tokens.json\\" }, { \\"type\\": \\"Tag\\", \\"name\\": \\"fb:users\\", \\"selfClosing\\": false, \\"block\\": { \\"type\\": \\"Block\\", \\"nodes\\": [ { \\"type\\": \\"Each\\", \\"obj\\": \\"users\\", \\"val\\": \\"user\\", \\"key\\": null, \\"block\\": { \\"type\\": \\"Block\\", \\"nodes\\": [ { \\"type\\": \\"Tag\\", \\"name\\": \\"fb:user\\", \\"selfClosing\\": false, \\"block\\": { \\"type\\": \\"Block\\", \\"nodes\\": [ { \\"type\\": \\"Text\\", \\"name\\": \\"cdata\\", \\"block\\": { \\"type\\": \\"Block\\", \\"nodes\\": [], \\"line\\": 6, \\"filename\\": \\"filters-empty.tokens.json\\" }, \\"attrs\\": [], \\"line\\": 6, \\"filename\\": \\"filters-empty.tokens.json\\", \\"val\\": \\"\\" } ], \\"line\\": 5, \\"filename\\": \\"filters-empty.tokens.json\\" }, \\"attrs\\": [ { \\"name\\": \\"age\\", \\"val\\": \\"user.age\\", \\"mustEscape\\": true } ], \\"attributeBlocks\\": [], \\"isInline\\": false, \\"line\\": 5, \\"filename\\": \\"filters-empty.tokens.json\\" } ], \\"line\\": 5, \\"filename\\": \\"filters-empty.tokens.json\\" }, \\"line\\": 4, \\"filename\\": \\"filters-empty.tokens.json\\" } ], \\"line\\": 3, \\"filename\\": \\"filters-empty.tokens.json\\" }, \\"attrs\\": [], \\"attributeBlocks\\": [], \\"isInline\\": false, \\"line\\": 3, \\"filename\\": \\"filters-empty.tokens.json\\" } ], \\"line\\": 0, \\"filename\\": \\"filters-empty.tokens.json\\" }" `; exports[`errors/dynamic-option.input.json 1`] = ` Object { "code": "PUG:FILTER_OPTION_NOT_CONSTANT", "line": 2, "msg": "\\"opt\\" is not constant. All filters are rendered compile-time so filter options must be constants.", } `; ================================================ FILE: packages/pug-filters/test/__snapshots__/per-filter-options-applied-to-nested-filters.test.js.snap ================================================ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`per filter options are applied, even to nested filters 1`] = ` Object { "filename": "/packages/pug-filters/test/per-filter-options-applied-to-nested-filters.test.js", "line": 0, "nodes": Array [ Object { "attributeBlocks": Array [], "attrs": Array [], "block": Object { "filename": "/packages/pug-filters/test/per-filter-options-applied-to-nested-filters.test.js", "line": 2, "nodes": Array [ Object { "attrs": Array [], "block": Object { "filename": "/packages/pug-filters/test/per-filter-options-applied-to-nested-filters.test.js", "line": 3, "nodes": Array [ Object { "attrs": Array [], "block": Object { "filename": "/packages/pug-filters/test/per-filter-options-applied-to-nested-filters.test.js", "line": 3, "nodes": Array [ Object { "column": 5, "filename": "/packages/pug-filters/test/per-filter-options-applied-to-nested-filters.test.js", "line": 4, "type": "Text", "val": "function myFunc(foo) {", }, Object { "column": 1, "filename": "/packages/pug-filters/test/per-filter-options-applied-to-nested-filters.test.js", "line": 5, "type": "Text", "val": " ", }, Object { "column": 5, "filename": "/packages/pug-filters/test/per-filter-options-applied-to-nested-filters.test.js", "line": 5, "type": "Text", "val": " return foo;", }, Object { "column": 1, "filename": "/packages/pug-filters/test/per-filter-options-applied-to-nested-filters.test.js", "line": 6, "type": "Text", "val": " ", }, Object { "column": 5, "filename": "/packages/pug-filters/test/per-filter-options-applied-to-nested-filters.test.js", "line": 6, "type": "Text", "val": "}", }, ], "type": "Block", }, "column": 9, "filename": "/packages/pug-filters/test/per-filter-options-applied-to-nested-filters.test.js", "line": 3, "name": "uglify-js", "type": "Text", "val": "function myFunc(n) { return n; } ", }, ], "type": "Block", }, "column": 3, "filename": "/packages/pug-filters/test/per-filter-options-applied-to-nested-filters.test.js", "line": 3, "name": "cdata", "type": "Text", "val": "", }, ], "type": "Block", }, "column": 1, "filename": "/packages/pug-filters/test/per-filter-options-applied-to-nested-filters.test.js", "isInline": false, "line": 2, "name": "script", "selfClosing": false, "type": "Tag", }, ], "type": "Block", } `; ================================================ FILE: packages/pug-filters/test/cases/filters-empty.input.json ================================================ { "type": "Block", "nodes": [ { "type": "Code", "val": "var users = [{ name: 'tobi', age: 2 }]", "buffer": false, "mustEscape": false, "isInline": false, "line": 1, "filename": "filters-empty.tokens.json" }, { "type": "Tag", "name": "fb:users", "selfClosing": false, "block": { "type": "Block", "nodes": [ { "type": "Each", "obj": "users", "val": "user", "key": null, "block": { "type": "Block", "nodes": [ { "type": "Tag", "name": "fb:user", "selfClosing": false, "block": { "type": "Block", "nodes": [ { "type": "Filter", "name": "cdata", "block": { "type": "Block", "nodes": [], "line": 6, "filename": "filters-empty.tokens.json" }, "attrs": [], "line": 6, "filename": "filters-empty.tokens.json" } ], "line": 5, "filename": "filters-empty.tokens.json" }, "attrs": [ { "name": "age", "val": "user.age", "mustEscape": true } ], "attributeBlocks": [], "isInline": false, "line": 5, "filename": "filters-empty.tokens.json" } ], "line": 5, "filename": "filters-empty.tokens.json" }, "line": 4, "filename": "filters-empty.tokens.json" } ], "line": 3, "filename": "filters-empty.tokens.json" }, "attrs": [], "attributeBlocks": [], "isInline": false, "line": 3, "filename": "filters-empty.tokens.json" } ], "line": 0, "filename": "filters-empty.tokens.json" } ================================================ FILE: packages/pug-filters/test/cases/filters.cdata.input.json ================================================ { "type": "Block", "nodes": [ { "type": "Code", "val": "users = [{ name: 'tobi', age: 2 }]", "buffer": false, "mustEscape": false, "isInline": false, "line": 2, "filename": "filters.cdata.tokens.json" }, { "type": "Tag", "name": "fb:users", "selfClosing": false, "block": { "type": "Block", "nodes": [ { "type": "Each", "obj": "users", "val": "user", "block": { "type": "Block", "nodes": [ { "type": "Tag", "name": "fb:user", "selfClosing": false, "block": { "type": "Block", "nodes": [ { "type": "Filter", "name": "cdata", "block": { "type": "Block", "nodes": [ { "type": "Text", "val": "#{user.name}", "line": 8 } ] }, "attrs": [], "line": 7, "filename": "filters.cdata.tokens.json" } ] }, "attrs": [ { "name": "age", "val": "user.age", "mustEscape": true } ], "attributeBlocks": [], "isInline": false, "line": 6, "filename": "filters.cdata.tokens.json" } ], "line": 6, "filename": "filters.cdata.tokens.json" }, "line": 5, "filename": "filters.cdata.tokens.json" } ] }, "attrs": [], "attributeBlocks": [], "isInline": false, "line": 4, "filename": "filters.cdata.tokens.json" } ], "line": 0, "filename": "filters.cdata.tokens.json" } ================================================ FILE: packages/pug-filters/test/cases/filters.coffeescript.input.json ================================================ { "type": "Block", "nodes": [ { "type": "Tag", "name": "script", "selfClosing": false, "block": { "type": "Block", "nodes": [ { "type": "Filter", "name": "coffee-script", "block": { "type": "Block", "nodes": [ { "type": "Text", "val": "regexp = /\\n/", "line": 3 } ], "line": 2, "filename": "filters.coffeescript.tokens.json" }, "attrs": [], "line": 2, "filename": "filters.coffeescript.tokens.json" }, { "type": "Filter", "name": "coffee-script", "block": { "type": "Block", "nodes": [ { "type": "Text", "val": "math =", "line": 5 }, { "type": "Text", "val": "\n", "line": 6 }, { "type": "Text", "val": " square: (value) -> value * value", "line": 6 } ], "line": 4, "filename": "filters.coffeescript.tokens.json" }, "attrs": [ { "name": "minify", "val": "true", "mustEscape": true } ], "line": 4, "filename": "filters.coffeescript.tokens.json" } ], "line": 1, "filename": "filters.coffeescript.tokens.json" }, "attrs": [ { "name": "type", "val": "'text/javascript'", "mustEscape": true } ], "attributeBlocks": [], "isInline": false, "line": 1, "filename": "filters.coffeescript.tokens.json" } ], "line": 0, "filename": "filters.coffeescript.tokens.json" } ================================================ FILE: packages/pug-filters/test/cases/filters.custom.input.json ================================================ { "type": "Block", "nodes": [ { "type": "Tag", "name": "html", "selfClosing": false, "block": { "type": "Block", "nodes": [ { "type": "Tag", "name": "body", "selfClosing": false, "block": { "type": "Block", "nodes": [ { "type": "Filter", "name": "custom", "block": { "type": "Block", "nodes": [ { "type": "Text", "val": "Line 1", "line": 4 }, { "type": "Text", "val": "\n", "line": 5 }, { "type": "Text", "val": "Line 2", "line": 5 }, { "type": "Text", "val": "\n", "line": 6 }, { "type": "Text", "val": "", "line": 6 }, { "type": "Text", "val": "\n", "line": 7 }, { "type": "Text", "val": "Line 4", "line": 7 } ], "line": 3, "filename": "filters.custom.tokens.json" }, "attrs": [ { "name": "opt", "val": "'val'", "mustEscape": true }, { "name": "num", "val": "2", "mustEscape": true } ], "line": 3, "filename": "filters.custom.tokens.json" } ], "line": 2, "filename": "filters.custom.tokens.json" }, "attrs": [], "attributeBlocks": [], "isInline": false, "line": 2, "filename": "filters.custom.tokens.json" } ], "line": 1, "filename": "filters.custom.tokens.json" }, "attrs": [], "attributeBlocks": [], "isInline": false, "line": 1, "filename": "filters.custom.tokens.json" } ], "line": 0, "filename": "filters.custom.tokens.json" } ================================================ FILE: packages/pug-filters/test/cases/filters.include.custom.input.json ================================================ { "type": "Block", "nodes": [ { "type": "Tag", "name": "html", "selfClosing": false, "block": { "type": "Block", "nodes": [ { "type": "Tag", "name": "body", "selfClosing": false, "block": { "type": "Block", "nodes": [ { "type": "Tag", "name": "pre", "selfClosing": false, "block": { "type": "Block", "nodes": [ { "type": "RawInclude", "file": { "type": "FileReference", "line": 4, "filename": "filters.include.custom.tokens.json", "path": "filters.include.custom.pug", "fullPath": "test/cases/filters.include.custom.pug", "str": "html\n body\n pre\n include:custom(opt='val' num=2) filters.include.custom.pug\n" }, "line": 4, "filename": "filters.include.custom.tokens.json", "filters": [ { "type": "IncludeFilter", "name": "custom", "attrs": [ { "name": "opt", "val": "'val'", "mustEscape": true }, { "name": "num", "val": "2", "mustEscape": true } ], "line": 4, "filename": "filters.include.custom.tokens.json" } ] } ], "line": 3, "filename": "filters.include.custom.tokens.json" }, "attrs": [], "attributeBlocks": [], "isInline": false, "line": 3, "filename": "filters.include.custom.tokens.json" } ], "line": 2, "filename": "filters.include.custom.tokens.json" }, "attrs": [], "attributeBlocks": [], "isInline": false, "line": 2, "filename": "filters.include.custom.tokens.json" } ], "line": 1, "filename": "filters.include.custom.tokens.json" }, "attrs": [], "attributeBlocks": [], "isInline": false, "line": 1, "filename": "filters.include.custom.tokens.json" } ], "line": 0, "filename": "filters.include.custom.tokens.json" } ================================================ FILE: packages/pug-filters/test/cases/filters.include.custom.pug ================================================ html body pre include:custom(opt='val' num=2) filters.include.custom.pug ================================================ FILE: packages/pug-filters/test/cases/filters.include.input.json ================================================ { "type": "Block", "nodes": [ { "type": "Tag", "name": "html", "selfClosing": false, "block": { "type": "Block", "nodes": [ { "type": "Tag", "name": "body", "selfClosing": false, "block": { "type": "Block", "nodes": [ { "type": "RawInclude", "file": { "type": "FileReference", "line": 3, "filename": "filters.include.tokens.json", "path": "some.md", "fullPath": "test/cases/some.md", "str": "Just _some_ markdown **tests**.\n\nWith new line.\n" }, "line": 3, "filename": "filters.include.tokens.json", "filters": [ { "type": "IncludeFilter", "name": "markdown-it", "attrs": [], "line": 3, "filename": "filters.include.tokens.json" } ] }, { "type": "Tag", "name": "script", "selfClosing": false, "block": { "type": "Block", "nodes": [ { "type": "RawInclude", "file": { "type": "FileReference", "line": 5, "filename": "filters.include.tokens.json", "path": "include-filter-coffee.coffee", "fullPath": "test/cases/include-filter-coffee.coffee", "str": "math =\n square: (value) -> value * value\n" }, "line": 5, "filename": "filters.include.tokens.json", "filters": [ { "type": "IncludeFilter", "name": "coffee-script", "attrs": [ { "name": "minify", "val": "true", "mustEscape": true } ], "line": 5, "filename": "filters.include.tokens.json" } ] } ], "line": 4, "filename": "filters.include.tokens.json" }, "attrs": [], "attributeBlocks": [], "isInline": false, "line": 4, "filename": "filters.include.tokens.json" }, { "type": "Tag", "name": "script", "selfClosing": false, "block": { "type": "Block", "nodes": [ { "type": "RawInclude", "file": { "type": "FileReference", "line": 7, "filename": "filters.include.tokens.json", "path": "include-filter-coffee.coffee", "fullPath": "test/cases/include-filter-coffee.coffee", "str": "math =\n square: (value) -> value * value\n" }, "line": 7, "filename": "filters.include.tokens.json", "filters": [ { "type": "IncludeFilter", "name": "cdata", "attrs": [], "line": 7, "filename": "filters.include.tokens.json" }, { "type": "IncludeFilter", "name": "coffee-script", "attrs": [ { "name": "minify", "val": "false", "mustEscape": true } ], "line": 7, "filename": "filters.include.tokens.json" } ] } ], "line": 6, "filename": "filters.include.tokens.json" }, "attrs": [], "attributeBlocks": [], "isInline": false, "line": 6, "filename": "filters.include.tokens.json" } ], "line": 2, "filename": "filters.include.tokens.json" }, "attrs": [], "attributeBlocks": [], "isInline": false, "line": 2, "filename": "filters.include.tokens.json" } ], "line": 1, "filename": "filters.include.tokens.json" }, "attrs": [], "attributeBlocks": [], "isInline": false, "line": 1, "filename": "filters.include.tokens.json" } ], "line": 0, "filename": "filters.include.tokens.json" } ================================================ FILE: packages/pug-filters/test/cases/filters.inline.input.json ================================================ { "type": "Block", "nodes": [ { "type": "Tag", "name": "p", "selfClosing": false, "block": { "type": "Block", "nodes": [ { "type": "Text", "val": "before ", "line": 1, "filename": "filters.inline.tokens.json" }, { "type": "Filter", "name": "cdata", "block": { "type": "Block", "nodes": [ { "type": "Text", "val": "inside", "line": 1, "filename": "filters.inline.tokens.json" } ], "line": 1, "filename": "filters.inline.tokens.json" }, "attrs": [], "line": 1, "filename": "filters.inline.tokens.json" }, { "type": "Text", "val": " after", "line": 1, "filename": "filters.inline.tokens.json" } ], "line": 1, "filename": "filters.inline.tokens.json" }, "attrs": [], "attributeBlocks": [], "isInline": false, "line": 1, "filename": "filters.inline.tokens.json" } ], "line": 0, "filename": "filters.inline.tokens.json" } ================================================ FILE: packages/pug-filters/test/cases/filters.less.input.json ================================================ { "type": "Block", "nodes": [ { "type": "Tag", "name": "html", "selfClosing": false, "block": { "type": "Block", "nodes": [ { "type": "Tag", "name": "head", "selfClosing": false, "block": { "type": "Block", "nodes": [ { "type": "Tag", "name": "style", "selfClosing": false, "block": { "type": "Block", "nodes": [ { "type": "Filter", "name": "less", "block": { "type": "Block", "nodes": [ { "type": "Text", "val": "@pad: 15px;", "line": 5 }, { "type": "Text", "val": "\n", "line": 6 }, { "type": "Text", "val": "body {", "line": 6 }, { "type": "Text", "val": "\n", "line": 7 }, { "type": "Text", "val": " padding: @pad;", "line": 7 }, { "type": "Text", "val": "\n", "line": 8 }, { "type": "Text", "val": "}", "line": 8 } ], "line": 4, "filename": "filters.less.tokens.json" }, "attrs": [], "line": 4, "filename": "filters.less.tokens.json" } ], "line": 3, "filename": "filters.less.tokens.json" }, "attrs": [ { "name": "type", "val": "\"text/css\"", "mustEscape": true } ], "attributeBlocks": [], "isInline": false, "line": 3, "filename": "filters.less.tokens.json" } ], "line": 2, "filename": "filters.less.tokens.json" }, "attrs": [], "attributeBlocks": [], "isInline": false, "line": 2, "filename": "filters.less.tokens.json" } ], "line": 1, "filename": "filters.less.tokens.json" }, "attrs": [], "attributeBlocks": [], "isInline": false, "line": 1, "filename": "filters.less.tokens.json" } ], "line": 0, "filename": "filters.less.tokens.json" } ================================================ FILE: packages/pug-filters/test/cases/filters.markdown.input.json ================================================ { "type": "Block", "nodes": [ { "type": "Tag", "name": "html", "selfClosing": false, "block": { "type": "Block", "nodes": [ { "type": "Tag", "name": "body", "selfClosing": false, "block": { "type": "Block", "nodes": [ { "type": "Filter", "name": "markdown-it", "block": { "type": "Block", "nodes": [ { "type": "Text", "val": "This is _some_ awesome **markdown**", "line": 4 }, { "type": "Text", "val": "\n", "line": 5 }, { "type": "Text", "val": "whoop.", "line": 5 } ], "line": 3, "filename": "filters.markdown.tokens.json" }, "attrs": [], "line": 3, "filename": "filters.markdown.tokens.json" } ], "line": 2, "filename": "filters.markdown.tokens.json" }, "attrs": [], "attributeBlocks": [], "isInline": false, "line": 2, "filename": "filters.markdown.tokens.json" } ], "line": 1, "filename": "filters.markdown.tokens.json" }, "attrs": [], "attributeBlocks": [], "isInline": false, "line": 1, "filename": "filters.markdown.tokens.json" } ], "line": 0, "filename": "filters.markdown.tokens.json" } ================================================ FILE: packages/pug-filters/test/cases/filters.nested.input.json ================================================ { "type": "Block", "nodes": [ { "type": "Tag", "name": "script", "selfClosing": false, "block": { "type": "Block", "nodes": [ { "type": "Filter", "name": "cdata", "block": { "type": "Block", "nodes": [ { "type": "Filter", "name": "uglify-js", "block": { "type": "Block", "nodes": [ { "type": "Text", "val": "(function() {", "line": 3 }, { "type": "Text", "val": "\n", "line": 4 }, { "type": "Text", "val": " console.log('test')", "line": 4 }, { "type": "Text", "val": "\n", "line": 5 }, { "type": "Text", "val": "})()", "line": 5 } ], "line": 2, "filename": "filters.nested.tokens.json" }, "attrs": [], "line": 2, "filename": "filters.nested.tokens.json" } ], "line": 2, "filename": "filters.nested.tokens.json" }, "attrs": [], "line": 2, "filename": "filters.nested.tokens.json" } ], "line": 1, "filename": "filters.nested.tokens.json" }, "attrs": [], "attributeBlocks": [], "isInline": false, "line": 1, "filename": "filters.nested.tokens.json" }, { "type": "Tag", "name": "script", "selfClosing": false, "block": { "type": "Block", "nodes": [ { "type": "Filter", "name": "cdata", "block": { "type": "Block", "nodes": [ { "type": "Filter", "name": "uglify-js", "block": { "type": "Block", "nodes": [ { "type": "Filter", "name": "coffee-script", "block": { "type": "Block", "nodes": [ { "type": "Text", "val": "(->", "line": 8 }, { "type": "Text", "val": "\n", "line": 9 }, { "type": "Text", "val": " console.log 'test'", "line": 9 }, { "type": "Text", "val": "\n", "line": 10 }, { "type": "Text", "val": ")()", "line": 10 } ], "line": 7, "filename": "filters.nested.tokens.json" }, "attrs": [], "line": 7, "filename": "filters.nested.tokens.json" } ], "line": 7, "filename": "filters.nested.tokens.json" }, "attrs": [], "line": 7, "filename": "filters.nested.tokens.json" } ], "line": 7, "filename": "filters.nested.tokens.json" }, "attrs": [], "line": 7, "filename": "filters.nested.tokens.json" } ], "line": 6, "filename": "filters.nested.tokens.json" }, "attrs": [], "attributeBlocks": [], "isInline": false, "line": 6, "filename": "filters.nested.tokens.json" } ], "line": 0, "filename": "filters.nested.tokens.json" } ================================================ FILE: packages/pug-filters/test/cases/filters.stylus.input.json ================================================ { "type": "Block", "nodes": [ { "type": "Tag", "name": "html", "selfClosing": false, "block": { "type": "Block", "nodes": [ { "type": "Tag", "name": "head", "selfClosing": false, "block": { "type": "Block", "nodes": [ { "type": "Tag", "name": "style", "selfClosing": false, "block": { "type": "Block", "nodes": [ { "type": "Filter", "name": "stylus", "block": { "type": "Block", "nodes": [ { "type": "Text", "val": "body", "line": 5 }, { "type": "Text", "val": "\n", "line": 6 }, { "type": "Text", "val": " padding: 50px", "line": 6 } ], "line": 4, "filename": "filters.stylus.tokens.json" }, "attrs": [], "line": 4, "filename": "filters.stylus.tokens.json" } ], "line": 3, "filename": "filters.stylus.tokens.json" }, "attrs": [ { "name": "type", "val": "\"text/css\"", "mustEscape": true } ], "attributeBlocks": [], "isInline": false, "line": 3, "filename": "filters.stylus.tokens.json" } ], "line": 2, "filename": "filters.stylus.tokens.json" }, "attrs": [], "attributeBlocks": [], "isInline": false, "line": 2, "filename": "filters.stylus.tokens.json" }, { "type": "Tag", "name": "body", "selfClosing": false, "block": { "type": "Block", "nodes": [], "line": 7, "filename": "filters.stylus.tokens.json" }, "attrs": [], "attributeBlocks": [], "isInline": false, "line": 7, "filename": "filters.stylus.tokens.json" } ], "line": 1, "filename": "filters.stylus.tokens.json" }, "attrs": [], "attributeBlocks": [], "isInline": false, "line": 1, "filename": "filters.stylus.tokens.json" } ], "line": 0, "filename": "filters.stylus.tokens.json" } ================================================ FILE: packages/pug-filters/test/cases/include-filter-coffee.coffee ================================================ math = square: (value) -> value * value ================================================ FILE: packages/pug-filters/test/cases/some.md ================================================ Just _some_ markdown **tests**. With new line. ================================================ FILE: packages/pug-filters/test/custom-filters.js ================================================ var assert = require('assert'); module.exports = { custom: function(str, options) { expect(options.opt).toBe('val'); expect(options.num).toBe(2); return 'BEGIN' + str + 'END'; }, }; ================================================ FILE: packages/pug-filters/test/errors/dynamic-option.input.json ================================================ { "type": "Block", "nodes": [ { "type": "Code", "val": "var opt = 'a'", "buffer": false, "escape": false, "isInline": false, "line": 1 }, { "type": "Filter", "name": "cdata", "block": { "type": "Block", "nodes": [ { "type": "Text", "val": "hey", "line": 3 } ], "line": 2 }, "attrs": [ { "name": "option", "val": "opt", "escaped": true } ], "line": 2 } ], "line": 0 } ================================================ FILE: packages/pug-filters/test/errors-src/dynamic-option.jade ================================================ - var opt = 'a' :cdata(option=opt) hey ================================================ FILE: packages/pug-filters/test/filter-aliases.test.js ================================================ const lex = require('pug-lexer'); const parse = require('pug-parser'); const handleFilters = require('../').handleFilters; const customFilters = {}; test('filters can be aliased', () => { const source = ` script :cdata:minify function myFunc(foo) { return foo; } `; const ast = parse(lex(source, {filename: __filename}), { filename: __filename, src: source, }); const options = {}; const aliases = { minify: 'uglify-js', }; const output = handleFilters(ast, customFilters, options, aliases); expect(output).toMatchSnapshot(); }); test('we do not support chains of aliases', () => { const source = ` script :cdata:minify-js function myFunc(foo) { return foo; } `; const ast = parse(lex(source, {filename: __filename}), { filename: __filename, src: source, }); const options = {}; const aliases = { 'minify-js': 'minify', minify: 'uglify-js', }; try { const output = handleFilters(ast, customFilters, options, aliases); } catch (ex) { expect({ code: ex.code, message: ex.message, }).toMatchSnapshot(); return; } throw new Error('Expected an exception'); }); test('options are applied before aliases', () => { const source = ` script :cdata:minify function myFunc(foo) { return foo; } :cdata:uglify-js function myFunc(foo) { return foo; } `; const ast = parse(lex(source, {filename: __filename}), { filename: __filename, src: source, }); const options = { minify: {output: {beautify: true}}, }; const aliases = { minify: 'uglify-js', }; const output = handleFilters(ast, customFilters, options, aliases); expect(output).toMatchSnapshot(); }); ================================================ FILE: packages/pug-filters/test/index.test.js ================================================ 'use strict'; var fs = require('fs'); var assert = require('assert'); var handleFilters = require('../').handleFilters; var customFilters = require('./custom-filters.js'); process.chdir(__dirname + '/../'); var testCases; testCases = fs.readdirSync(__dirname + '/cases').filter(function(name) { return /\.input\.json$/.test(name); }); // testCases.forEach(function(filename) { function read(path) { return fs.readFileSync(__dirname + '/cases/' + path, 'utf8'); } test('cases/' + filename, function() { var actualAst = JSON.stringify( handleFilters(JSON.parse(read(filename)), customFilters), null, ' ' ); expect(actualAst).toMatchSnapshot(); }); }); testCases = fs.readdirSync(__dirname + '/errors').filter(function(name) { return /\.input\.json$/.test(name); }); testCases.forEach(function(filename) { function read(path) { return fs.readFileSync(__dirname + '/errors/' + path, 'utf8'); } test('errors/' + filename, function() { var actual; try { handleFilters(JSON.parse(read(filename)), customFilters); throw new Error('Expected ' + filename + ' to throw an exception.'); } catch (ex) { if (!ex || !ex.code || ex.code.indexOf('PUG:') !== 0) throw ex; actual = { msg: ex.msg, code: ex.code, line: ex.line, }; } expect(actual).toMatchSnapshot(); }); }); ================================================ FILE: packages/pug-filters/test/per-filter-options-applied-to-nested-filters.test.js ================================================ const lex = require('pug-lexer'); const parse = require('pug-parser'); const handleFilters = require('../').handleFilters; const customFilters = {}; test('per filter options are applied, even to nested filters', () => { const source = ` script :cdata:uglify-js function myFunc(foo) { return foo; } `; const ast = parse(lex(source, {filename: __filename}), { filename: __filename, src: source, }); const options = { 'uglify-js': {output: {beautify: true}}, }; const output = handleFilters(ast, customFilters, options); expect(output).toMatchSnapshot(); // TODO: render with `options.filterOptions['uglify-js']` }); ================================================ FILE: packages/pug-lexer/History.md ================================================ 2.3.0 / 2016-09-11 ================== * Update is-expression to 3.0.0 2.2.2 / 2016-09-07 ================== * Support non-standard class names that start with two hyphens in class literals, most notably used in Bemto 2.2.1 / 2016-08-29 ================== * Fix semantics of `isExpression` plugin 2.2.0 / 2016-08-26 ================== * Allow customizing `isExpression` 2.1.0 / 2016-08-22 ================== * Allow attributes that start with a colon 2.0.3 / 2016-08-07 ================== * Allow `when` expressions with colons * Fix incorrect location of some errors 2.0.2 / 2016-06-02 ================== * Fix incorrect location of some invalid expressions in an attribute. 2.0.1 / 2016-05-31 ================== * Update README for `filename` option 2.0.0 / 2016-05-14 ================== * Take the `filename` as an option rather than special casing it. This means that lex only takes 2 arguments rather than 3 * Add support for an inline comment after a block. This means block names can no longer contain `//` * Add type checking on arguments 1.2.0 / 2016-05-14 ================== * Throw a more helpful error if someone attempts to use the old `- each foo in bar` syntax (it should not have the `- ` prefix) * Add Error reporting for invalid case expressions 1.0.1 / 2016-04-18 ================== * Update dependencies - Update to `is-expression@2` which allows ES2015-style template strings by default. 1.0.0 / 2015-12-23 ================== * First stable release ================================================ FILE: packages/pug-lexer/LICENSE ================================================ Copyright (c) 2014 Forbes Lindesay 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. ================================================ FILE: packages/pug-lexer/README.md ================================================ # pug-lexer The pug lexer. This module is responsible for taking a string and converting it into an array of tokens. [![Build Status](https://img.shields.io/travis/pugjs/pug-lexer/master.svg)](https://travis-ci.org/pugjs/pug-lexer) [![Dependencies Status](https://david-dm.org/pugjs/pug/status.svg?path=packages/pug-lexer)](https://david-dm.org/pugjs/pug?path=packages/pug-lexer) [![DevDependencies Status](https://david-dm.org/pugjs/pug/dev-status.svg?path=packages/pug-lexer)](https://david-dm.org/pugjs/pug?path=packages/pug-lexer&type=dev) [![NPM version](https://img.shields.io/npm/v/pug-lexer.svg)](https://www.npmjs.org/package/pug-lexer) [![Coverage Status](https://img.shields.io/codecov/c/github/pugjs/pug-lexer.svg)](https://codecov.io/gh/pugjs/pug-lexer) ## Installation npm install pug-lexer ## Usage ```js var lex = require('pug-lexer'); ``` ### `lex(str, options)` Convert Pug string to an array of tokens. `options` can contain the following properties: - `filename` (string): The name of the Pug file; it is used in error handling if provided. - `plugins` (array): An array of plugins, in the order they should be applied. ```js console.log(JSON.stringify(lex('div(data-foo="bar")', {filename: 'my-file.pug'}), null, ' ')) ``` ```json [ { "type": "tag", "line": 1, "val": "div", "selfClosing": false }, { "type": "attrs", "line": 1, "attrs": [ { "name": "data-foo", "val": "\"bar\"", "escaped": true } ] }, { "type": "eos", "line": 1 } ] ``` ### `new lex.Lexer(str, options)` Constructor for a Lexer class. This is not meant to be used directly unless you know what you are doing. `options` may contain the following properties: - `filename` (string): The name of the Pug file; it is used in error handling if provided. - `interpolated` (boolean): if the Lexer is created as a child lexer for inline tag interpolation (e.g. `#[p Hello]`). Defaults to `false`. - `startingLine` (integer): the real line number of the first line in the input. It is also used for inline tag interpolation. Defaults to `1`. - `plugins` (array): An array of plugins, in the order they should be applied. ## License MIT ================================================ FILE: packages/pug-lexer/index.d.ts ================================================ declare module 'pug-lexer' { namespace lex { export interface Loc { start: {line: number; column: number}; end: {line: number; column: number}; } export type LexTokenType = | ':' | '&attributes' | 'attribute' | 'block' | 'blockcode' | 'call' | 'case' | 'class' | 'code' | 'comment' | 'default' | 'doctype' | 'dot' | 'each' | 'eachOf' | 'else-if' | 'else' | 'end-attributes' | 'end-pipeless-text' | 'end-pug-interpolation' | 'eos' | 'extends' | 'filter' | 'id' | 'if' | 'include' | 'indent' | 'interpolated-code' | 'interpolation' | 'mixin-block' | 'mixin' | 'newline' | 'outdent' | 'path' | 'slash' | 'start-attributes' | 'start-pipeless-text' | 'start-pug-interpolation' | 'tag' | 'text-html' | 'text' | 'when' | 'while' | 'yield'; export interface LexToken { type: Type; loc: Loc; } export interface TagToken extends LexToken<'tag'> { val: string; } export type StartAttributesToken = LexToken<'start-attributes'>; export interface AttributeToken extends LexToken<'attribute'> { name: string; val: string | boolean; mustEscape: boolean; } export type EndAttributesToken = LexToken<'end-attributes'>; export interface IndentToken extends LexToken<'indent'> { val: number; } export interface ClassToken extends LexToken<'class'> { val: string; } export type OutdentToken = LexToken<'outdent'>; export type EosToken = LexToken<'eos'>; export interface CommentToken extends LexToken<'comment'> { val: string; buffer: boolean; } export type NewlineToken = LexToken<'newline'>; export interface TextToken extends LexToken<'text'> { val: string; } export interface InterpolatedCodeToken extends LexToken<'interpolated-code'> { mustEscape: boolean; buffer: boolean; val: string; } export interface CodeToken extends LexToken<'code'> { val: string; mustEscape: boolean; buffer: boolean; } export interface IdToken extends LexToken<'id'> { val: string; } export type StartPipelessTextToken = LexToken<'start-pipeless-text'>; export type EndPipelessTextToken = LexToken<'end-pipeless-text'>; export interface DoctypeToken extends LexToken<'doctype'> { val: string; } export type DotToken = LexToken<'dot'>; export interface BlockToken extends LexToken<'block'> { val: string; mode: 'replace' | 'prepend' | 'append'; } export type ExtendsToken = LexToken<'extends'>; export interface PathToken extends LexToken<'path'> { val: string; } export type StartPugInterpolationToken = LexToken< 'start-pug-interpolation' >; export type EndPugInterpolationToken = LexToken<'end-pug-interpolation'>; export interface InterpolationToken extends LexToken<'interpolation'> { val: string; } export type IncludeToken = LexToken<'include'>; export interface FilterToken extends LexToken<'filter'> { val: string; } export interface CallToken extends LexToken<'call'> { val: string; args: string; } export interface MixinToken extends LexToken<'mixin'> { val: string; args: string | null; } export interface IfToken extends LexToken<'if'> { val: string; } export type MixinBlockToken = LexToken<'mixin-block'>; export interface ElseToken extends LexToken<'else'> { val: string; } export interface AndAttributesToken extends LexToken<'&attributes'> { val: string; } export interface TextHtmlToken extends LexToken<'text-html'> { val: string; } export interface EachToken extends LexToken<'each'> { val: string; key: string | null; code: string; } export interface EachOfToken extends LexToken<'eachOf'> { val: string; value: string; code: string; } export interface WhileToken extends LexToken<'while'> { val: string; } export interface CaseToken extends LexToken<'case'> { val: string; } export interface WhenToken extends LexToken<'when'> { val: string; } export type ColonToken = LexToken<':'>; export type DefaultToken = LexToken<'default'>; export interface ElseIfToken extends LexToken<'else-if'> { val: string; } export type BlockcodeToken = LexToken<'blockcode'>; export type YieldToken = LexToken<'yield'>; export type SlashToken = LexToken<'slash'>; export type Token = | AndAttributesToken | AttributeToken | BlockcodeToken | BlockToken | CallToken | CaseToken | ClassToken | CodeToken | ColonToken | CommentToken | DefaultToken | DoctypeToken | DotToken | EachToken | EachOfToken | ElseIfToken | ElseToken | EndAttributesToken | EndPipelessTextToken | EndPugInterpolationToken | EosToken | ExtendsToken | FilterToken | IdToken | IfToken | IncludeToken | IndentToken | InterpolatedCodeToken | InterpolationToken | MixinBlockToken | MixinToken | NewlineToken | OutdentToken | PathToken | SlashToken | StartAttributesToken | StartPipelessTextToken | StartPugInterpolationToken | TagToken | TextHtmlToken | TextToken | WhenToken | WhileToken | YieldToken; export type LexerFunction = (type: string, exp?: any) => boolean; export interface LexerOptions { filename: string; interpolated?: boolean; startingLine?: number; startingColumn?: number; plugins?: LexerFunction[]; } export class Lexer { input: string; originalInput: string; filename?: string; interpolated: boolean; lineno: number; colno: number; plugins: LexerFunction[]; indentStack: number[]; indentRe: RegExp | null; interpolationAllowed: boolean; whitespaceRe: RegExp; tokens: Token[]; ended: boolean; constructor(str: string, options?: LexerOptions); error(code: string, message: string): never; assert(value: any, message: string): void; isExpression(exp: string): boolean; assertExpression(exp: string, noThrow?: boolean): boolean; assertNestingCorrect(exp: string): void; private tok( type: Type, val?: any, ): LexToken; private tokEnd( tok: LexToken, ): LexToken; private incrementLine(increment: number): void; private incrementColumn(increment: number): void; private consume(len: number): void; private scan( regexp: RegExp, type: Type, ): LexToken | undefined; private scanEndOfLine( regexp: RegExp, type: Type, ): LexToken | undefined; private bracketExpression(skip?: number): number; scanIndentation(): RegExpExecArray | null; eos(): true | undefined; blank(): true | undefined; comment(): true | undefined; interpolation(): true | undefined; tag(): true | undefined; filter(): true | undefined; doctype(): true | undefined; id(): true | undefined; className(): true | undefined; endInterpolation(): true | undefined; addText( type: LexTokenType, value: string, prefix?: string, escaped?: number, ): void; text(): true | undefined; textHtml(): true | undefined; dot(): true | undefined; extends(): true | undefined; prepend(): true | undefined; append(): true | undefined; block(): true | undefined; mixinBlock(): true | undefined; yield(): true | undefined; include(): true | undefined; path(): true | undefined; case(): true | undefined; when(): true | undefined; default(): true | undefined; call(): true | undefined; mixin(): true | undefined; conditional(): true | undefined; while(): true | undefined; each(): true | undefined; eachOf(): true | undefined; code(): true | undefined; blockCode(): true | undefined; attribute(): string; attributeValue( str: string, ): {val?: string; mustEscape?: boolean; remainingSource: string}; attrs(): true | undefined; attributesBlock(): true | undefined; indent(): true | NewlineToken | undefined; pipelessText(indents?: number): boolean | undefined; slash(): true | undefined; colon(): true | undefined; fail(): never; callLexerFunction(func: string): boolean; private advance(): boolean; getTokens(): Token[]; } } function lex(str: string, options?: lex.LexerOptions): lex.Token[]; export = lex; } ================================================ FILE: packages/pug-lexer/index.js ================================================ 'use strict'; var assert = require('assert'); var isExpression = require('is-expression'); var characterParser = require('character-parser'); var error = require('pug-error'); module.exports = lex; module.exports.Lexer = Lexer; function lex(str, options) { var lexer = new Lexer(str, options); return JSON.parse(JSON.stringify(lexer.getTokens())); } /** * Initialize `Lexer` with the given `str`. * * @param {String} str * @param {String} filename * @api private */ function Lexer(str, options) { options = options || {}; if (typeof str !== 'string') { throw new Error( 'Expected source code to be a string but got "' + typeof str + '"' ); } if (typeof options !== 'object') { throw new Error( 'Expected "options" to be an object but got "' + typeof options + '"' ); } //Strip any UTF-8 BOM off of the start of `str`, if it exists. str = str.replace(/^\uFEFF/, ''); this.input = str.replace(/\r\n|\r/g, '\n'); this.originalInput = this.input; this.filename = options.filename; this.interpolated = options.interpolated || false; this.lineno = options.startingLine || 1; this.colno = options.startingColumn || 1; this.plugins = options.plugins || []; this.indentStack = [0]; this.indentRe = null; // If #{}, !{} or #[] syntax is allowed when adding text this.interpolationAllowed = true; this.whitespaceRe = /[ \n\t]/; this.tokens = []; this.ended = false; } /** * Lexer prototype. */ Lexer.prototype = { constructor: Lexer, error: function(code, message) { var err = error(code, message, { line: this.lineno, column: this.colno, filename: this.filename, src: this.originalInput, }); throw err; }, assert: function(value, message) { if (!value) this.error('ASSERT_FAILED', message); }, isExpression: function(exp) { return isExpression(exp, { throw: true, }); }, assertExpression: function(exp, noThrow) { //this verifies that a JavaScript expression is valid try { this.callLexerFunction('isExpression', exp); return true; } catch (ex) { if (noThrow) return false; // not coming from acorn if (!ex.loc) throw ex; this.incrementLine(ex.loc.line - 1); this.incrementColumn(ex.loc.column); var msg = 'Syntax Error: ' + ex.message.replace(/ \([0-9]+:[0-9]+\)$/, ''); this.error('SYNTAX_ERROR', msg); } }, assertNestingCorrect: function(exp) { //this verifies that code is properly nested, but allows //invalid JavaScript such as the contents of `attributes` var res = characterParser.default(exp); if (res.isNesting()) { this.error( 'INCORRECT_NESTING', 'Nesting must match on expression `' + exp + '`' ); } }, /** * Construct a token with the given `type` and `val`. * * @param {String} type * @param {String} val * @return {Object} * @api private */ tok: function(type, val) { var res = { type: type, loc: { start: { line: this.lineno, column: this.colno, }, filename: this.filename, }, }; if (val !== undefined) res.val = val; return res; }, /** * Set the token's `loc.end` value. * * @param {Object} tok * @returns {Object} * @api private */ tokEnd: function(tok) { tok.loc.end = { line: this.lineno, column: this.colno, }; return tok; }, /** * Increment `this.lineno` and reset `this.colno`. * * @param {Number} increment * @api private */ incrementLine: function(increment) { this.lineno += increment; if (increment) this.colno = 1; }, /** * Increment `this.colno`. * * @param {Number} increment * @api private */ incrementColumn: function(increment) { this.colno += increment; }, /** * Consume the given `len` of input. * * @param {Number} len * @api private */ consume: function(len) { this.input = this.input.substr(len); }, /** * Scan for `type` with the given `regexp`. * * @param {String} type * @param {RegExp} regexp * @return {Object} * @api private */ scan: function(regexp, type) { var captures; if ((captures = regexp.exec(this.input))) { var len = captures[0].length; var val = captures[1]; var diff = len - (val ? val.length : 0); var tok = this.tok(type, val); this.consume(len); this.incrementColumn(diff); return tok; } }, scanEndOfLine: function(regexp, type) { var captures; if ((captures = regexp.exec(this.input))) { var whitespaceLength = 0; var whitespace; var tok; if ((whitespace = /^([ ]+)([^ ]*)/.exec(captures[0]))) { whitespaceLength = whitespace[1].length; this.incrementColumn(whitespaceLength); } var newInput = this.input.substr(captures[0].length); if (newInput[0] === ':') { this.input = newInput; tok = this.tok(type, captures[1]); this.incrementColumn(captures[0].length - whitespaceLength); return tok; } if (/^[ \t]*(\n|$)/.test(newInput)) { this.input = newInput.substr(/^[ \t]*/.exec(newInput)[0].length); tok = this.tok(type, captures[1]); this.incrementColumn(captures[0].length - whitespaceLength); return tok; } } }, /** * Return the indexOf `(` or `{` or `[` / `)` or `}` or `]` delimiters. * * Make sure that when calling this function, colno is at the character * immediately before the beginning. * * @return {Number} * @api private */ bracketExpression: function(skip) { skip = skip || 0; var start = this.input[skip]; assert( start === '(' || start === '{' || start === '[', 'The start character should be "(", "{" or "["' ); var end = {'(': ')', '{': '}', '[': ']'}[start]; var range; try { range = characterParser.parseUntil(this.input, end, {start: skip + 1}); } catch (ex) { if (ex.index !== undefined) { var idx = ex.index; // starting from this.input[skip] var tmp = this.input.substr(skip).indexOf('\n'); // starting from this.input[0] var nextNewline = tmp + skip; var ptr = 0; while (idx > nextNewline && tmp !== -1) { this.incrementLine(1); idx -= nextNewline + 1; ptr += nextNewline + 1; tmp = nextNewline = this.input.substr(ptr).indexOf('\n'); } this.incrementColumn(idx); } if (ex.code === 'CHARACTER_PARSER:END_OF_STRING_REACHED') { this.error( 'NO_END_BRACKET', 'The end of the string reached with no closing bracket ' + end + ' found.' ); } else if (ex.code === 'CHARACTER_PARSER:MISMATCHED_BRACKET') { this.error('BRACKET_MISMATCH', ex.message); } throw ex; } return range; }, scanIndentation: function() { var captures, re; // established regexp if (this.indentRe) { captures = this.indentRe.exec(this.input); // determine regexp } else { // tabs re = /^\n(\t*) */; captures = re.exec(this.input); // spaces if (captures && !captures[1].length) { re = /^\n( *)/; captures = re.exec(this.input); } // established if (captures && captures[1].length) this.indentRe = re; } return captures; }, /** * end-of-source. */ eos: function() { if (this.input.length) return; if (this.interpolated) { this.error( 'NO_END_BRACKET', 'End of line was reached with no closing bracket for interpolation.' ); } for (var i = 0; this.indentStack[i]; i++) { this.tokens.push(this.tokEnd(this.tok('outdent'))); } this.tokens.push(this.tokEnd(this.tok('eos'))); this.ended = true; return true; }, /** * Blank line. */ blank: function() { var captures; if ((captures = /^\n[ \t]*\n/.exec(this.input))) { this.consume(captures[0].length - 1); this.incrementLine(1); return true; } }, /** * Comment. */ comment: function() { var captures; if ((captures = /^\/\/(-)?([^\n]*)/.exec(this.input))) { this.consume(captures[0].length); var tok = this.tok('comment', captures[2]); tok.buffer = '-' != captures[1]; this.interpolationAllowed = tok.buffer; this.tokens.push(tok); this.incrementColumn(captures[0].length); this.tokEnd(tok); this.callLexerFunction('pipelessText'); return true; } }, /** * Interpolated tag. */ interpolation: function() { if (/^#\{/.test(this.input)) { var match = this.bracketExpression(1); this.consume(match.end + 1); var tok = this.tok('interpolation', match.src); this.tokens.push(tok); this.incrementColumn(2); // '#{' this.assertExpression(match.src); var splitted = match.src.split('\n'); var lines = splitted.length - 1; this.incrementLine(lines); this.incrementColumn(splitted[lines].length + 1); // + 1 → '}' this.tokEnd(tok); return true; } }, /** * Tag. */ tag: function() { var captures; if ((captures = /^(\w(?:[-:\w]*\w)?)/.exec(this.input))) { var tok, name = captures[1], len = captures[0].length; this.consume(len); tok = this.tok('tag', name); this.tokens.push(tok); this.incrementColumn(len); this.tokEnd(tok); return true; } }, /** * Filter. */ filter: function(opts) { var tok = this.scan(/^:([\w\-]+)/, 'filter'); var inInclude = opts && opts.inInclude; if (tok) { this.tokens.push(tok); this.incrementColumn(tok.val.length); this.tokEnd(tok); this.callLexerFunction('attrs'); if (!inInclude) { this.interpolationAllowed = false; this.callLexerFunction('pipelessText'); } return true; } }, /** * Doctype. */ doctype: function() { var node = this.scanEndOfLine(/^doctype *([^\n]*)/, 'doctype'); if (node) { this.tokens.push(this.tokEnd(node)); return true; } }, /** * Id. */ id: function() { var tok = this.scan(/^#([\w-]+)/, 'id'); if (tok) { this.tokens.push(tok); this.incrementColumn(tok.val.length); this.tokEnd(tok); return true; } if (/^#/.test(this.input)) { this.error( 'INVALID_ID', '"' + /.[^ \t\(\#\.\:]*/.exec(this.input.substr(1))[0] + '" is not a valid ID.' ); } }, /** * Class. */ className: function() { var tok = this.scan(/^\.([_a-z0-9\-]*[_a-z][_a-z0-9\-]*)/i, 'class'); if (tok) { this.tokens.push(tok); this.incrementColumn(tok.val.length); this.tokEnd(tok); return true; } if (/^\.[_a-z0-9\-]+/i.test(this.input)) { this.error( 'INVALID_CLASS_NAME', 'Class names must contain at least one letter or underscore.' ); } if (/^\./.test(this.input)) { this.error( 'INVALID_CLASS_NAME', '"' + /.[^ \t\(\#\.\:]*/.exec(this.input.substr(1))[0] + '" is not a valid class name. Class names can only contain "_", "-", a-z and 0-9, and must contain at least one of "_", or a-z' ); } }, /** * Text. */ endInterpolation: function() { if (this.interpolated && this.input[0] === ']') { this.input = this.input.substr(1); this.ended = true; return true; } }, addText: function(type, value, prefix, escaped) { var tok; if (value + prefix === '') return; prefix = prefix || ''; escaped = escaped || 0; var indexOfEnd = this.interpolated ? value.indexOf(']') : -1; var indexOfStart = this.interpolationAllowed ? value.indexOf('#[') : -1; var indexOfEscaped = this.interpolationAllowed ? value.indexOf('\\#[') : -1; var matchOfStringInterp = /(\\)?([#!]){((?:.|\n)*)$/.exec(value); var indexOfStringInterp = this.interpolationAllowed && matchOfStringInterp ? matchOfStringInterp.index : Infinity; if (indexOfEnd === -1) indexOfEnd = Infinity; if (indexOfStart === -1) indexOfStart = Infinity; if (indexOfEscaped === -1) indexOfEscaped = Infinity; if ( indexOfEscaped !== Infinity && indexOfEscaped < indexOfEnd && indexOfEscaped < indexOfStart && indexOfEscaped < indexOfStringInterp ) { prefix = prefix + value.substring(0, indexOfEscaped) + '#['; return this.addText( type, value.substring(indexOfEscaped + 3), prefix, escaped + 1 ); } if ( indexOfStart !== Infinity && indexOfStart < indexOfEnd && indexOfStart < indexOfEscaped && indexOfStart < indexOfStringInterp ) { tok = this.tok(type, prefix + value.substring(0, indexOfStart)); this.incrementColumn(prefix.length + indexOfStart + escaped); this.tokens.push(this.tokEnd(tok)); tok = this.tok('start-pug-interpolation'); this.incrementColumn(2); this.tokens.push(this.tokEnd(tok)); var child = new this.constructor(value.substr(indexOfStart + 2), { filename: this.filename, interpolated: true, startingLine: this.lineno, startingColumn: this.colno, plugins: this.plugins, }); var interpolated; try { interpolated = child.getTokens(); } catch (ex) { if (ex.code && /^PUG:/.test(ex.code)) { this.colno = ex.column; this.error(ex.code.substr(4), ex.msg); } throw ex; } this.colno = child.colno; this.tokens = this.tokens.concat(interpolated); tok = this.tok('end-pug-interpolation'); this.incrementColumn(1); this.tokens.push(this.tokEnd(tok)); this.addText(type, child.input); return; } if ( indexOfEnd !== Infinity && indexOfEnd < indexOfStart && indexOfEnd < indexOfEscaped && indexOfEnd < indexOfStringInterp ) { if (prefix + value.substring(0, indexOfEnd)) { this.addText(type, value.substring(0, indexOfEnd), prefix); } this.ended = true; this.input = value.substr(value.indexOf(']') + 1) + this.input; return; } if (indexOfStringInterp !== Infinity) { if (matchOfStringInterp[1]) { prefix = prefix + value.substring(0, indexOfStringInterp) + matchOfStringInterp[2] + '{'; return this.addText( type, value.substring(indexOfStringInterp + 3), prefix, escaped + 1 ); } var before = value.substr(0, indexOfStringInterp); if (prefix || before) { before = prefix + before; tok = this.tok(type, before); this.incrementColumn(before.length + escaped); this.tokens.push(this.tokEnd(tok)); } var rest = matchOfStringInterp[3]; var range; tok = this.tok('interpolated-code'); this.incrementColumn(2); try { range = characterParser.parseUntil(rest, '}'); } catch (ex) { if (ex.index !== undefined) { this.incrementColumn(ex.index); } if (ex.code === 'CHARACTER_PARSER:END_OF_STRING_REACHED') { this.error( 'NO_END_BRACKET', 'End of line was reached with no closing bracket for interpolation.' ); } else if (ex.code === 'CHARACTER_PARSER:MISMATCHED_BRACKET') { this.error('BRACKET_MISMATCH', ex.message); } else { throw ex; } } tok.mustEscape = matchOfStringInterp[2] === '#'; tok.buffer = true; tok.val = range.src; this.assertExpression(range.src); if (range.end + 1 < rest.length) { rest = rest.substr(range.end + 1); this.incrementColumn(range.end + 1); this.tokens.push(this.tokEnd(tok)); this.addText(type, rest); } else { this.incrementColumn(rest.length); this.tokens.push(this.tokEnd(tok)); } return; } value = prefix + value; tok = this.tok(type, value); this.incrementColumn(value.length + escaped); this.tokens.push(this.tokEnd(tok)); }, text: function() { var tok = this.scan(/^(?:\| ?| )([^\n]+)/, 'text') || this.scan(/^( )/, 'text') || this.scan(/^\|( ?)/, 'text'); if (tok) { this.addText('text', tok.val); return true; } }, textHtml: function() { var tok = this.scan(/^(<[^\n]*)/, 'text-html'); if (tok) { this.addText('text-html', tok.val); return true; } }, /** * Dot. */ dot: function() { var tok; if ((tok = this.scanEndOfLine(/^\./, 'dot'))) { this.tokens.push(this.tokEnd(tok)); this.callLexerFunction('pipelessText'); return true; } }, /** * Extends. */ extends: function() { var tok = this.scan(/^extends?(?= |$|\n)/, 'extends'); if (tok) { this.tokens.push(this.tokEnd(tok)); if (!this.callLexerFunction('path')) { this.error('NO_EXTENDS_PATH', 'missing path for extends'); } return true; } if (this.scan(/^extends?\b/)) { this.error('MALFORMED_EXTENDS', 'malformed extends'); } }, /** * Block prepend. */ prepend: function() { var captures; if ((captures = /^(?:block +)?prepend +([^\n]+)/.exec(this.input))) { var name = captures[1].trim(); var comment = ''; if (name.indexOf('//') !== -1) { comment = '//' + name .split('//') .slice(1) .join('//'); name = name.split('//')[0].trim(); } if (!name) return; var tok = this.tok('block', name); var len = captures[0].length - comment.length; while (this.whitespaceRe.test(this.input.charAt(len - 1))) len--; this.incrementColumn(len); tok.mode = 'prepend'; this.tokens.push(this.tokEnd(tok)); this.consume(captures[0].length - comment.length); this.incrementColumn(captures[0].length - comment.length - len); return true; } }, /** * Block append. */ append: function() { var captures; if ((captures = /^(?:block +)?append +([^\n]+)/.exec(this.input))) { var name = captures[1].trim(); var comment = ''; if (name.indexOf('//') !== -1) { comment = '//' + name .split('//') .slice(1) .join('//'); name = name.split('//')[0].trim(); } if (!name) return; var tok = this.tok('block', name); var len = captures[0].length - comment.length; while (this.whitespaceRe.test(this.input.charAt(len - 1))) len--; this.incrementColumn(len); tok.mode = 'append'; this.tokens.push(this.tokEnd(tok)); this.consume(captures[0].length - comment.length); this.incrementColumn(captures[0].length - comment.length - len); return true; } }, /** * Block. */ block: function() { var captures; if ((captures = /^block +([^\n]+)/.exec(this.input))) { var name = captures[1].trim(); var comment = ''; if (name.indexOf('//') !== -1) { comment = '//' + name .split('//') .slice(1) .join('//'); name = name.split('//')[0].trim(); } if (!name) return; var tok = this.tok('block', name); var len = captures[0].length - comment.length; while (this.whitespaceRe.test(this.input.charAt(len - 1))) len--; this.incrementColumn(len); tok.mode = 'replace'; this.tokens.push(this.tokEnd(tok)); this.consume(captures[0].length - comment.length); this.incrementColumn(captures[0].length - comment.length - len); return true; } }, /** * Mixin Block. */ mixinBlock: function() { var tok; if ((tok = this.scanEndOfLine(/^block/, 'mixin-block'))) { this.tokens.push(this.tokEnd(tok)); return true; } }, /** * Yield. */ yield: function() { var tok = this.scanEndOfLine(/^yield/, 'yield'); if (tok) { this.tokens.push(this.tokEnd(tok)); return true; } }, /** * Include. */ include: function() { var tok = this.scan(/^include(?=:| |$|\n)/, 'include'); if (tok) { this.tokens.push(this.tokEnd(tok)); while (this.callLexerFunction('filter', {inInclude: true})); if (!this.callLexerFunction('path')) { if (/^[^ \n]+/.test(this.input)) { // if there is more text this.fail(); } else { // if not this.error('NO_INCLUDE_PATH', 'missing path for include'); } } return true; } if (this.scan(/^include\b/)) { this.error('MALFORMED_INCLUDE', 'malformed include'); } }, /** * Path */ path: function() { var tok = this.scanEndOfLine(/^ ([^\n]+)/, 'path'); if (tok && (tok.val = tok.val.trim())) { this.tokens.push(this.tokEnd(tok)); return true; } }, /** * Case. */ case: function() { var tok = this.scanEndOfLine(/^case +([^\n]+)/, 'case'); if (tok) { this.incrementColumn(-tok.val.length); this.assertExpression(tok.val); this.incrementColumn(tok.val.length); this.tokens.push(this.tokEnd(tok)); return true; } if (this.scan(/^case\b/)) { this.error('NO_CASE_EXPRESSION', 'missing expression for case'); } }, /** * When. */ when: function() { var tok = this.scanEndOfLine(/^when +([^:\n]+)/, 'when'); if (tok) { var parser = characterParser.default(tok.val); while (parser.isNesting() || parser.isString()) { var rest = /:([^:\n]+)/.exec(this.input); if (!rest) break; tok.val += rest[0]; this.consume(rest[0].length); this.incrementColumn(rest[0].length); parser = characterParser.default(tok.val); } this.incrementColumn(-tok.val.length); this.assertExpression(tok.val); this.incrementColumn(tok.val.length); this.tokens.push(this.tokEnd(tok)); return true; } if (this.scan(/^when\b/)) { this.error('NO_WHEN_EXPRESSION', 'missing expression for when'); } }, /** * Default. */ default: function() { var tok = this.scanEndOfLine(/^default/, 'default'); if (tok) { this.tokens.push(this.tokEnd(tok)); return true; } if (this.scan(/^default\b/)) { this.error( 'DEFAULT_WITH_EXPRESSION', 'default should not have an expression' ); } }, /** * Call mixin. */ call: function() { var tok, captures, increment; if ((captures = /^\+(\s*)(([-\w]+)|(#\{))/.exec(this.input))) { // try to consume simple or interpolated call if (captures[3]) { // simple call increment = captures[0].length; this.consume(increment); tok = this.tok('call', captures[3]); } else { // interpolated call var match = this.bracketExpression(2 + captures[1].length); increment = match.end + 1; this.consume(increment); this.assertExpression(match.src); tok = this.tok('call', '#{' + match.src + '}'); } this.incrementColumn(increment); tok.args = null; // Check for args (not attributes) if ((captures = /^ *\(/.exec(this.input))) { var range = this.bracketExpression(captures[0].length - 1); if (!/^\s*[-\w]+ *=/.test(range.src)) { // not attributes this.incrementColumn(1); this.consume(range.end + 1); tok.args = range.src; this.assertExpression('[' + tok.args + ']'); for (var i = 0; i <= tok.args.length; i++) { if (tok.args[i] === '\n') { this.incrementLine(1); } else { this.incrementColumn(1); } } } } this.tokens.push(this.tokEnd(tok)); return true; } }, /** * Mixin. */ mixin: function() { var captures; if ((captures = /^mixin +([-\w]+)(?: *\((.*)\))? */.exec(this.input))) { this.consume(captures[0].length); var tok = this.tok('mixin', captures[1]); tok.args = captures[2] || null; this.incrementColumn(captures[0].length); this.tokens.push(this.tokEnd(tok)); return true; } }, /** * Conditional. */ conditional: function() { var captures; if ((captures = /^(if|unless|else if|else)\b([^\n]*)/.exec(this.input))) { this.consume(captures[0].length); var type = captures[1].replace(/ /g, '-'); var js = captures[2] && captures[2].trim(); // type can be "if", "else-if" and "else" var tok = this.tok(type, js); this.incrementColumn(captures[0].length - js.length); switch (type) { case 'if': case 'else-if': this.assertExpression(js); break; case 'unless': this.assertExpression(js); tok.val = '!(' + js + ')'; tok.type = 'if'; break; case 'else': if (js) { this.error( 'ELSE_CONDITION', '`else` cannot have a condition, perhaps you meant `else if`' ); } break; } this.incrementColumn(js.length); this.tokens.push(this.tokEnd(tok)); return true; } }, /** * While. */ while: function() { var captures, tok; if ((captures = /^while +([^\n]+)/.exec(this.input))) { this.consume(captures[0].length); this.assertExpression(captures[1]); tok = this.tok('while', captures[1]); this.incrementColumn(captures[0].length); this.tokens.push(this.tokEnd(tok)); return true; } if (this.scan(/^while\b/)) { this.error('NO_WHILE_EXPRESSION', 'missing expression for while'); } }, /** * Each. */ each: function() { var captures; if ( (captures = /^(?:each|for) +([a-zA-Z_$][\w$]*)(?: *, *([a-zA-Z_$][\w$]*))? * in *([^\n]+)/.exec( this.input )) ) { this.consume(captures[0].length); var tok = this.tok('each', captures[1]); tok.key = captures[2] || null; this.incrementColumn(captures[0].length - captures[3].length); this.assertExpression(captures[3]); tok.code = captures[3]; this.incrementColumn(captures[3].length); this.tokens.push(this.tokEnd(tok)); return true; } const name = /^each\b/.exec(this.input) ? 'each' : 'for'; if (this.scan(/^(?:each|for)\b/)) { this.error( 'MALFORMED_EACH', 'This `' + name + '` has a syntax error. `' + name + '` statements should be of the form: `' + name + ' VARIABLE_NAME of JS_EXPRESSION`' ); } if ( (captures = /^- *(?:each|for) +([a-zA-Z_$][\w$]*)(?: *, *([a-zA-Z_$][\w$]*))? +in +([^\n]+)/.exec( this.input )) ) { this.error( 'MALFORMED_EACH', 'Pug each and for should no longer be prefixed with a dash ("-"). They are pug keywords and not part of JavaScript.' ); } }, /** * EachOf. */ eachOf: function() { var captures; if ((captures = /^(?:each|for) (.*?) of *([^\n]+)/.exec(this.input))) { this.consume(captures[0].length); var tok = this.tok('eachOf', captures[1]); tok.value = captures[1]; this.incrementColumn(captures[0].length - captures[2].length); this.assertExpression(captures[2]); tok.code = captures[2]; this.incrementColumn(captures[2].length); this.tokens.push(this.tokEnd(tok)); if ( !( /^[a-zA-Z_$][\w$]*$/.test(tok.value.trim()) || /^\[ *[a-zA-Z_$][\w$]* *\, *[a-zA-Z_$][\w$]* *\]$/.test( tok.value.trim() ) ) ) { this.error( 'MALFORMED_EACH_OF_LVAL', 'The value variable for each must either be a valid identifier (e.g. `item`) or a pair of identifiers in square brackets (e.g. `[key, value]`).' ); } return true; } if ( (captures = /^- *(?:each|for) +([a-zA-Z_$][\w$]*)(?: *, *([a-zA-Z_$][\w$]*))? +of +([^\n]+)/.exec( this.input )) ) { this.error( 'MALFORMED_EACH', 'Pug each and for should not be prefixed with a dash ("-"). They are pug keywords and not part of JavaScript.' ); } }, /** * Code. */ code: function() { var captures; if ((captures = /^(!?=|-)[ \t]*([^\n]+)/.exec(this.input))) { var flags = captures[1]; var code = captures[2]; var shortened = 0; if (this.interpolated) { var parsed; try { parsed = characterParser.parseUntil(code, ']'); } catch (err) { if (err.index !== undefined) { this.incrementColumn(captures[0].length - code.length + err.index); } if (err.code === 'CHARACTER_PARSER:END_OF_STRING_REACHED') { this.error( 'NO_END_BRACKET', 'End of line was reached with no closing bracket for interpolation.' ); } else if (err.code === 'CHARACTER_PARSER:MISMATCHED_BRACKET') { this.error('BRACKET_MISMATCH', err.message); } else { throw err; } } shortened = code.length - parsed.end; code = parsed.src; } var consumed = captures[0].length - shortened; this.consume(consumed); var tok = this.tok('code', code); tok.mustEscape = flags.charAt(0) === '='; tok.buffer = flags.charAt(0) === '=' || flags.charAt(1) === '='; // p #[!= abc] hey // ^ original colno // -------------- captures[0] // -------- captures[2] // ------ captures[0] - captures[2] // ^ after colno // = abc // ^ original colno // ------- captures[0] // --- captures[2] // ---- captures[0] - captures[2] // ^ after colno this.incrementColumn(captures[0].length - captures[2].length); if (tok.buffer) this.assertExpression(code); this.tokens.push(tok); // p #[!= abc] hey // ^ original colno // ----- shortened // --- code // ^ after colno // = abc // ^ original colno // shortened // --- code // ^ after colno this.incrementColumn(code.length); this.tokEnd(tok); return true; } }, /** * Block code. */ blockCode: function() { var tok; if ((tok = this.scanEndOfLine(/^-/, 'blockcode'))) { this.tokens.push(this.tokEnd(tok)); this.interpolationAllowed = false; this.callLexerFunction('pipelessText'); return true; } }, /** * Attribute Name. */ attribute: function(str) { var quote = ''; var quoteRe = /['"]/; var key = ''; var i; // consume all whitespace before the key for (i = 0; i < str.length; i++) { if (!this.whitespaceRe.test(str[i])) break; if (str[i] === '\n') { this.incrementLine(1); } else { this.incrementColumn(1); } } if (i === str.length) { return ''; } var tok = this.tok('attribute'); // quote? if (quoteRe.test(str[i])) { quote = str[i]; this.incrementColumn(1); i++; } // start looping through the key for (; i < str.length; i++) { if (quote) { if (str[i] === quote) { this.incrementColumn(1); i++; break; } } else { if ( this.whitespaceRe.test(str[i]) || str[i] === '!' || str[i] === '=' || str[i] === ',' ) { break; } } key += str[i]; if (str[i] === '\n') { this.incrementLine(1); } else { this.incrementColumn(1); } } tok.name = key; var valueResponse = this.attributeValue(str.substr(i)); if (valueResponse.val) { tok.val = valueResponse.val; tok.mustEscape = valueResponse.mustEscape; } else { // was a boolean attribute (ex: `input(disabled)`) tok.val = true; tok.mustEscape = true; } str = valueResponse.remainingSource; this.tokens.push(this.tokEnd(tok)); for (i = 0; i < str.length; i++) { if (!this.whitespaceRe.test(str[i])) { break; } if (str[i] === '\n') { this.incrementLine(1); } else { this.incrementColumn(1); } } if (str[i] === ',') { this.incrementColumn(1); i++; } return str.substr(i); }, /** * Attribute Value. */ attributeValue: function(str) { var quoteRe = /['"]/; var val = ''; var done, i, x; var escapeAttr = true; var state = characterParser.defaultState(); var col = this.colno; var line = this.lineno; // consume all whitespace before the equals sign for (i = 0; i < str.length; i++) { if (!this.whitespaceRe.test(str[i])) break; if (str[i] === '\n') { line++; col = 1; } else { col++; } } if (i === str.length) { return {remainingSource: str}; } if (str[i] === '!') { escapeAttr = false; col++; i++; if (str[i] !== '=') this.error( 'INVALID_KEY_CHARACTER', 'Unexpected character ' + str[i] + ' expected `=`' ); } if (str[i] !== '=') { // check for anti-pattern `div("foo"bar)` if (i === 0 && str && !this.whitespaceRe.test(str[0]) && str[0] !== ',') { this.error( 'INVALID_KEY_CHARACTER', 'Unexpected character ' + str[0] + ' expected `=`' ); } else { return {remainingSource: str}; } } this.lineno = line; this.colno = col + 1; i++; // consume all whitespace before the value for (; i < str.length; i++) { if (!this.whitespaceRe.test(str[i])) break; if (str[i] === '\n') { this.incrementLine(1); } else { this.incrementColumn(1); } } line = this.lineno; col = this.colno; // start looping through the value for (; i < str.length; i++) { // if the character is in a string or in parentheses/brackets/braces if (!(state.isNesting() || state.isString())) { if (this.whitespaceRe.test(str[i])) { done = false; // find the first non-whitespace character for (x = i; x < str.length; x++) { if (!this.whitespaceRe.test(str[x])) { // if it is a JavaScript punctuator, then assume that it is // a part of the value const isNotPunctuator = !characterParser.isPunctuator(str[x]); const isQuote = quoteRe.test(str[x]); const isColon = str[x] === ':'; const isSpreadOperator = str[x] + str[x + 1] + str[x + 2] === '...'; if ( (isNotPunctuator || isQuote || isColon || isSpreadOperator) && this.assertExpression(val, true) ) { done = true; } break; } } // if everything else is whitespace, return now so last attribute // does not include trailing whitespace if (done || x === str.length) { break; } } // if there's no whitespace and the character is not ',', the // attribute did not end. if (str[i] === ',' && this.assertExpression(val, true)) { break; } } state = characterParser.parseChar(str[i], state); val += str[i]; if (str[i] === '\n') { line++; col = 1; } else { col++; } } this.assertExpression(val); this.lineno = line; this.colno = col; return {val: val, mustEscape: escapeAttr, remainingSource: str.substr(i)}; }, /** * Attributes. */ attrs: function() { var tok; if ('(' == this.input.charAt(0)) { tok = this.tok('start-attributes'); var index = this.bracketExpression().end; var str = this.input.substr(1, index - 1); this.incrementColumn(1); this.tokens.push(this.tokEnd(tok)); this.assertNestingCorrect(str); this.consume(index + 1); while (str) { str = this.attribute(str); } tok = this.tok('end-attributes'); this.incrementColumn(1); this.tokens.push(this.tokEnd(tok)); return true; } }, /** * &attributes block */ attributesBlock: function() { if (/^&attributes\b/.test(this.input)) { var consumed = 11; this.consume(consumed); var tok = this.tok('&attributes'); this.incrementColumn(consumed); var args = this.bracketExpression(); consumed = args.end + 1; this.consume(consumed); tok.val = args.src; this.incrementColumn(consumed); this.tokens.push(this.tokEnd(tok)); return true; } }, /** * Indent | Outdent | Newline. */ indent: function() { var captures = this.scanIndentation(); var tok; if (captures) { var indents = captures[1].length; this.incrementLine(1); this.consume(indents + 1); if (' ' == this.input[0] || '\t' == this.input[0]) { this.error( 'INVALID_INDENTATION', 'Invalid indentation, you can use tabs or spaces but not both' ); } // blank line if ('\n' == this.input[0]) { this.interpolationAllowed = true; return this.tokEnd(this.tok('newline')); } // outdent if (indents < this.indentStack[0]) { var outdent_count = 0; while (this.indentStack[0] > indents) { if (this.indentStack[1] < indents) { this.error( 'INCONSISTENT_INDENTATION', 'Inconsistent indentation. Expecting either ' + this.indentStack[1] + ' or ' + this.indentStack[0] + ' spaces/tabs.' ); } outdent_count++; this.indentStack.shift(); } while (outdent_count--) { this.colno = 1; tok = this.tok('outdent'); this.colno = this.indentStack[0] + 1; this.tokens.push(this.tokEnd(tok)); } // indent } else if (indents && indents != this.indentStack[0]) { tok = this.tok('indent', indents); this.colno = 1 + indents; this.tokens.push(this.tokEnd(tok)); this.indentStack.unshift(indents); // newline } else { tok = this.tok('newline'); this.colno = 1 + Math.min(this.indentStack[0] || 0, indents); this.tokens.push(this.tokEnd(tok)); } this.interpolationAllowed = true; return true; } }, pipelessText: function pipelessText(indents) { while (this.callLexerFunction('blank')); var captures = this.scanIndentation(); indents = indents || (captures && captures[1].length); if (indents > this.indentStack[0]) { this.tokens.push(this.tokEnd(this.tok('start-pipeless-text'))); var tokens = []; var token_indent = []; var isMatch; // Index in this.input. Can't use this.consume because we might need to // retry lexing the block. var stringPtr = 0; do { // text has `\n` as a prefix var i = this.input.substr(stringPtr + 1).indexOf('\n'); if (-1 == i) i = this.input.length - stringPtr - 1; var str = this.input.substr(stringPtr + 1, i); var lineCaptures = this.indentRe.exec('\n' + str); var lineIndents = lineCaptures && lineCaptures[1].length; isMatch = lineIndents >= indents; token_indent.push(isMatch); isMatch = isMatch || !str.trim(); if (isMatch) { // consume test along with `\n` prefix if match stringPtr += str.length + 1; tokens.push(str.substr(indents)); } else if (lineIndents > this.indentStack[0]) { // line is indented less than the first line but is still indented // need to retry lexing the text block this.tokens.pop(); return pipelessText.call(this, lineCaptures[1].length); } } while (this.input.length - stringPtr && isMatch); this.consume(stringPtr); while (this.input.length === 0 && tokens[tokens.length - 1] === '') tokens.pop(); tokens.forEach( function(token, i) { var tok; this.incrementLine(1); if (i !== 0) tok = this.tok('newline'); if (token_indent[i]) this.incrementColumn(indents); if (tok) this.tokens.push(this.tokEnd(tok)); this.addText('text', token); }.bind(this) ); this.tokens.push(this.tokEnd(this.tok('end-pipeless-text'))); return true; } }, /** * Slash. */ slash: function() { var tok = this.scan(/^\//, 'slash'); if (tok) { this.tokens.push(this.tokEnd(tok)); return true; } }, /** * ':' */ colon: function() { var tok = this.scan(/^: +/, ':'); if (tok) { this.tokens.push(this.tokEnd(tok)); return true; } }, fail: function() { this.error( 'UNEXPECTED_TEXT', 'unexpected text "' + this.input.substr(0, 5) + '"' ); }, callLexerFunction: function(func) { var rest = []; for (var i = 1; i < arguments.length; i++) { rest.push(arguments[i]); } var pluginArgs = [this].concat(rest); for (var i = 0; i < this.plugins.length; i++) { var plugin = this.plugins[i]; if (plugin[func] && plugin[func].apply(plugin, pluginArgs)) { return true; } } return this[func].apply(this, rest); }, /** * Move to the next token * * @api private */ advance: function() { return ( this.callLexerFunction('blank') || this.callLexerFunction('eos') || this.callLexerFunction('endInterpolation') || this.callLexerFunction('yield') || this.callLexerFunction('doctype') || this.callLexerFunction('interpolation') || this.callLexerFunction('case') || this.callLexerFunction('when') || this.callLexerFunction('default') || this.callLexerFunction('extends') || this.callLexerFunction('append') || this.callLexerFunction('prepend') || this.callLexerFunction('block') || this.callLexerFunction('mixinBlock') || this.callLexerFunction('include') || this.callLexerFunction('mixin') || this.callLexerFunction('call') || this.callLexerFunction('conditional') || this.callLexerFunction('eachOf') || this.callLexerFunction('each') || this.callLexerFunction('while') || this.callLexerFunction('tag') || this.callLexerFunction('filter') || this.callLexerFunction('blockCode') || this.callLexerFunction('code') || this.callLexerFunction('id') || this.callLexerFunction('dot') || this.callLexerFunction('className') || this.callLexerFunction('attrs') || this.callLexerFunction('attributesBlock') || this.callLexerFunction('indent') || this.callLexerFunction('text') || this.callLexerFunction('textHtml') || this.callLexerFunction('comment') || this.callLexerFunction('slash') || this.callLexerFunction('colon') || this.fail() ); }, /** * Return an array of tokens for the current file * * @returns {Array.} * @api public */ getTokens: function() { while (!this.ended) { this.callLexerFunction('advance'); } return this.tokens; }, }; ================================================ FILE: packages/pug-lexer/package.json ================================================ { "name": "pug-lexer", "version": "4.1.0", "description": "The pug lexer (takes a string and converts it to an array of tokens)", "keywords": [ "pug" ], "dependencies": { "character-parser": "^4.0.0", "is-expression": "^4.0.0", "pug-error": "^1.3.3" }, "devDependencies": { "acorn": "^7.1.1", "acorn-walk": "^7.1.1" }, "files": [ "index.js", "index.d.ts" ], "repository": { "type": "git", "url": "https://github.com/pugjs/pug/tree/master/packages/pug-lexer" }, "author": "ForbesLindesay", "license": "MIT" } ================================================ FILE: packages/pug-lexer/test/__snapshots__/index.test.js.snap ================================================ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`attr-es2015.pug 1`] = ` Array [ Object { "buffer": false, "loc": Object { "end": Object { "column": 50, "line": 1, }, "filename": "/packages/pug-lexer/test/cases/attr-es2015.pug", "start": Object { "column": 1, "line": 1, }, }, "mustEscape": false, "type": "code", "val": "var avatar = '219b77f9d21de75e81851b6b886057c7'", }, Object { "loc": Object { "end": Object { "column": 1, "line": 3, }, "filename": "/packages/pug-lexer/test/cases/attr-es2015.pug", "start": Object { "column": 1, "line": 3, }, }, "type": "newline", }, Object { "loc": Object { "end": Object { "column": 4, "line": 3, }, "filename": "/packages/pug-lexer/test/cases/attr-es2015.pug", "start": Object { "column": 1, "line": 3, }, }, "type": "tag", "val": "div", }, Object { "loc": Object { "end": Object { "column": 15, "line": 3, }, "filename": "/packages/pug-lexer/test/cases/attr-es2015.pug", "start": Object { "column": 4, "line": 3, }, }, "type": "class", "val": "avatar-div", }, Object { "loc": Object { "end": Object { "column": 16, "line": 3, }, "filename": "/packages/pug-lexer/test/cases/attr-es2015.pug", "start": Object { "column": 15, "line": 3, }, }, "type": "start-attributes", }, Object { "loc": Object { "end": Object { "column": 88, "line": 3, }, "filename": "/packages/pug-lexer/test/cases/attr-es2015.pug", "start": Object { "column": 16, "line": 3, }, }, "mustEscape": true, "name": "style", "type": "attribute", "val": "\`background-image: url(https://www.gravatar.com/avatar/\${avatar})\`", }, Object { "loc": Object { "end": Object { "column": 89, "line": 3, }, "filename": "/packages/pug-lexer/test/cases/attr-es2015.pug", "start": Object { "column": 88, "line": 3, }, }, "type": "end-attributes", }, Object { "loc": Object { "end": Object { "column": 1, "line": 4, }, "filename": "/packages/pug-lexer/test/cases/attr-es2015.pug", "start": Object { "column": 1, "line": 4, }, }, "type": "newline", }, Object { "loc": Object { "end": Object { "column": 1, "line": 4, }, "filename": "/packages/pug-lexer/test/cases/attr-es2015.pug", "start": Object { "column": 1, "line": 4, }, }, "type": "eos", }, ] `; exports[`attribute-invalid-expression.pug 1`] = ` Object { "code": "PUG:SYNTAX_ERROR", "column": 5, "line": 2, "msg": "Syntax Error: Unterminated string constant", } `; exports[`attrs.js.pug 1`] = ` Array [ Object { "buffer": false, "loc": Object { "end": Object { "column": 13, "line": 1, }, "filename": "/packages/pug-lexer/test/cases/attrs.js.pug", "start": Object { "column": 1, "line": 1, }, }, "mustEscape": false, "type": "code", "val": "var id = 5", }, Object { "loc": Object { "end": Object { "column": 1, "line": 2, }, "filename": "/packages/pug-lexer/test/cases/attrs.js.pug", "start": Object { "column": 1, "line": 2, }, }, "type": "newline", }, Object { "buffer": false, "loc": Object { "end": Object { "column": 35, "line": 2, }, "filename": "/packages/pug-lexer/test/cases/attrs.js.pug", "start": Object { "column": 1, "line": 2, }, }, "mustEscape": false, "type": "code", "val": "function answer() { return 42; } ", }, Object { "loc": Object { "end": Object { "column": 1, "line": 3, }, "filename": "/packages/pug-lexer/test/cases/attrs.js.pug", "start": Object { "column": 1, "line": 3, }, }, "type": "newline", }, Object { "loc": Object { "end": Object { "column": 2, "line": 3, }, "filename": "/packages/pug-lexer/test/cases/attrs.js.pug", "start": Object { "column": 1, "line": 3, }, }, "type": "tag", "val": "a", }, Object { "loc": Object { "end": Object { "column": 3, "line": 3, }, "filename": "/packages/pug-lexer/test/cases/attrs.js.pug", "start": Object { "column": 2, "line": 3, }, }, "type": "start-attributes", }, Object { "loc": Object { "end": Object { "column": 21, "line": 3, }, "filename": "/packages/pug-lexer/test/cases/attrs.js.pug", "start": Object { "column": 3, "line": 3, }, }, "mustEscape": true, "name": "href", "type": "attribute", "val": "'/user/' + id", }, Object { "loc": Object { "end": Object { "column": 37, "line": 3, }, "filename": "/packages/pug-lexer/test/cases/attrs.js.pug", "start": Object { "column": 23, "line": 3, }, }, "mustEscape": true, "name": "class", "type": "attribute", "val": "'button'", }, Object { "loc": Object { "end": Object { "column": 38, "line": 3, }, "filename": "/packages/pug-lexer/test/cases/attrs.js.pug", "start": Object { "column": 37, "line": 3, }, }, "type": "end-attributes", }, Object { "loc": Object { "end": Object { "column": 1, "line": 4, }, "filename": "/packages/pug-lexer/test/cases/attrs.js.pug", "start": Object { "column": 1, "line": 4, }, }, "type": "newline", }, Object { "loc": Object { "end": Object { "column": 2, "line": 4, }, "filename": "/packages/pug-lexer/test/cases/attrs.js.pug", "start": Object { "column": 1, "line": 4, }, }, "type": "tag", "val": "a", }, Object { "loc": Object { "end": Object { "column": 3, "line": 4, }, "filename": "/packages/pug-lexer/test/cases/attrs.js.pug", "start": Object { "column": 2, "line": 4, }, }, "type": "start-attributes", }, Object { "loc": Object { "end": Object { "column": 25, "line": 4, }, "filename": "/packages/pug-lexer/test/cases/attrs.js.pug", "start": Object { "column": 3, "line": 4, }, }, "mustEscape": true, "name": "href", "type": "attribute", "val": "'/user/' + id", }, Object { "loc": Object { "end": Object { "column": 45, "line": 4, }, "filename": "/packages/pug-lexer/test/cases/attrs.js.pug", "start": Object { "column": 27, "line": 4, }, }, "mustEscape": true, "name": "class", "type": "attribute", "val": "'button'", }, Object { "loc": Object { "end": Object { "column": 46, "line": 4, }, "filename": "/packages/pug-lexer/test/cases/attrs.js.pug", "start": Object { "column": 45, "line": 4, }, }, "type": "end-attributes", }, Object { "loc": Object { "end": Object { "column": 1, "line": 5, }, "filename": "/packages/pug-lexer/test/cases/attrs.js.pug", "start": Object { "column": 1, "line": 5, }, }, "type": "newline", }, Object { "loc": Object { "end": Object { "column": 5, "line": 5, }, "filename": "/packages/pug-lexer/test/cases/attrs.js.pug", "start": Object { "column": 1, "line": 5, }, }, "type": "tag", "val": "meta", }, Object { "loc": Object { "end": Object { "column": 6, "line": 5, }, "filename": "/packages/pug-lexer/test/cases/attrs.js.pug", "start": Object { "column": 5, "line": 5, }, }, "type": "start-attributes", }, Object { "loc": Object { "end": Object { "column": 18, "line": 5, }, "filename": "/packages/pug-lexer/test/cases/attrs.js.pug", "start": Object { "column": 6, "line": 5, }, }, "mustEscape": true, "name": "key", "type": "attribute", "val": "'answer'", }, Object { "loc": Object { "end": Object { "column": 34, "line": 5, }, "filename": "/packages/pug-lexer/test/cases/attrs.js.pug", "start": Object { "column": 20, "line": 5, }, }, "mustEscape": true, "name": "value", "type": "attribute", "val": "answer()", }, Object { "loc": Object { "end": Object { "column": 35, "line": 5, }, "filename": "/packages/pug-lexer/test/cases/attrs.js.pug", "start": Object { "column": 34, "line": 5, }, }, "type": "end-attributes", }, Object { "loc": Object { "end": Object { "column": 1, "line": 6, }, "filename": "/packages/pug-lexer/test/cases/attrs.js.pug", "start": Object { "column": 1, "line": 6, }, }, "type": "newline", }, Object { "loc": Object { "end": Object { "column": 2, "line": 6, }, "filename": "/packages/pug-lexer/test/cases/attrs.js.pug", "start": Object { "column": 1, "line": 6, }, }, "type": "tag", "val": "a", }, Object { "loc": Object { "end": Object { "column": 3, "line": 6, }, "filename": "/packages/pug-lexer/test/cases/attrs.js.pug", "start": Object { "column": 2, "line": 6, }, }, "type": "start-attributes", }, Object { "loc": Object { "end": Object { "column": 31, "line": 6, }, "filename": "/packages/pug-lexer/test/cases/attrs.js.pug", "start": Object { "column": 3, "line": 6, }, }, "mustEscape": true, "name": "class", "type": "attribute", "val": "['class1', 'class2']", }, Object { "loc": Object { "end": Object { "column": 32, "line": 6, }, "filename": "/packages/pug-lexer/test/cases/attrs.js.pug", "start": Object { "column": 31, "line": 6, }, }, "type": "end-attributes", }, Object { "loc": Object { "end": Object { "column": 1, "line": 7, }, "filename": "/packages/pug-lexer/test/cases/attrs.js.pug", "start": Object { "column": 1, "line": 7, }, }, "type": "newline", }, Object { "loc": Object { "end": Object { "column": 2, "line": 7, }, "filename": "/packages/pug-lexer/test/cases/attrs.js.pug", "start": Object { "column": 1, "line": 7, }, }, "type": "tag", "val": "a", }, Object { "loc": Object { "end": Object { "column": 12, "line": 7, }, "filename": "/packages/pug-lexer/test/cases/attrs.js.pug", "start": Object { "column": 2, "line": 7, }, }, "type": "class", "val": "tag-class", }, Object { "loc": Object { "end": Object { "column": 13, "line": 7, }, "filename": "/packages/pug-lexer/test/cases/attrs.js.pug", "start": Object { "column": 12, "line": 7, }, }, "type": "start-attributes", }, Object { "loc": Object { "end": Object { "column": 41, "line": 7, }, "filename": "/packages/pug-lexer/test/cases/attrs.js.pug", "start": Object { "column": 13, "line": 7, }, }, "mustEscape": true, "name": "class", "type": "attribute", "val": "['class1', 'class2']", }, Object { "loc": Object { "end": Object { "column": 42, "line": 7, }, "filename": "/packages/pug-lexer/test/cases/attrs.js.pug", "start": Object { "column": 41, "line": 7, }, }, "type": "end-attributes", }, Object { "loc": Object { "end": Object { "column": 1, "line": 9, }, "filename": "/packages/pug-lexer/test/cases/attrs.js.pug", "start": Object { "column": 1, "line": 9, }, }, "type": "newline", }, Object { "loc": Object { "end": Object { "column": 2, "line": 9, }, "filename": "/packages/pug-lexer/test/cases/attrs.js.pug", "start": Object { "column": 1, "line": 9, }, }, "type": "tag", "val": "a", }, Object { "loc": Object { "end": Object { "column": 3, "line": 9, }, "filename": "/packages/pug-lexer/test/cases/attrs.js.pug", "start": Object { "column": 2, "line": 9, }, }, "type": "start-attributes", }, Object { "loc": Object { "end": Object { "column": 21, "line": 9, }, "filename": "/packages/pug-lexer/test/cases/attrs.js.pug", "start": Object { "column": 3, "line": 9, }, }, "mustEscape": true, "name": "href", "type": "attribute", "val": "'/user/' + id", }, Object { "loc": Object { "end": Object { "column": 36, "line": 9, }, "filename": "/packages/pug-lexer/test/cases/attrs.js.pug", "start": Object { "column": 22, "line": 9, }, }, "mustEscape": true, "name": "class", "type": "attribute", "val": "'button'", }, Object { "loc": Object { "end": Object { "column": 37, "line": 9, }, "filename": "/packages/pug-lexer/test/cases/attrs.js.pug", "start": Object { "column": 36, "line": 9, }, }, "type": "end-attributes", }, Object { "loc": Object { "end": Object { "column": 1, "line": 10, }, "filename": "/packages/pug-lexer/test/cases/attrs.js.pug", "start": Object { "column": 1, "line": 10, }, }, "type": "newline", }, Object { "loc": Object { "end": Object { "column": 2, "line": 10, }, "filename": "/packages/pug-lexer/test/cases/attrs.js.pug", "start": Object { "column": 1, "line": 10, }, }, "type": "tag", "val": "a", }, Object { "loc": Object { "end": Object { "column": 3, "line": 10, }, "filename": "/packages/pug-lexer/test/cases/attrs.js.pug", "start": Object { "column": 2, "line": 10, }, }, "type": "start-attributes", }, Object { "loc": Object { "end": Object { "column": 25, "line": 10, }, "filename": "/packages/pug-lexer/test/cases/attrs.js.pug", "start": Object { "column": 3, "line": 10, }, }, "mustEscape": true, "name": "href", "type": "attribute", "val": "'/user/' + id", }, Object { "loc": Object { "end": Object { "column": 44, "line": 10, }, "filename": "/packages/pug-lexer/test/cases/attrs.js.pug", "start": Object { "column": 26, "line": 10, }, }, "mustEscape": true, "name": "class", "type": "attribute", "val": "'button'", }, Object { "loc": Object { "end": Object { "column": 45, "line": 10, }, "filename": "/packages/pug-lexer/test/cases/attrs.js.pug", "start": Object { "column": 44, "line": 10, }, }, "type": "end-attributes", }, Object { "loc": Object { "end": Object { "column": 1, "line": 11, }, "filename": "/packages/pug-lexer/test/cases/attrs.js.pug", "start": Object { "column": 1, "line": 11, }, }, "type": "newline", }, Object { "loc": Object { "end": Object { "column": 5, "line": 11, }, "filename": "/packages/pug-lexer/test/cases/attrs.js.pug", "start": Object { "column": 1, "line": 11, }, }, "type": "tag", "val": "meta", }, Object { "loc": Object { "end": Object { "column": 6, "line": 11, }, "filename": "/packages/pug-lexer/test/cases/attrs.js.pug", "start": Object { "column": 5, "line": 11, }, }, "type": "start-attributes", }, Object { "loc": Object { "end": Object { "column": 18, "line": 11, }, "filename": "/packages/pug-lexer/test/cases/attrs.js.pug", "start": Object { "column": 6, "line": 11, }, }, "mustEscape": true, "name": "key", "type": "attribute", "val": "'answer'", }, Object { "loc": Object { "end": Object { "column": 33, "line": 11, }, "filename": "/packages/pug-lexer/test/cases/attrs.js.pug", "start": Object { "column": 19, "line": 11, }, }, "mustEscape": true, "name": "value", "type": "attribute", "val": "answer()", }, Object { "loc": Object { "end": Object { "column": 34, "line": 11, }, "filename": "/packages/pug-lexer/test/cases/attrs.js.pug", "start": Object { "column": 33, "line": 11, }, }, "type": "end-attributes", }, Object { "loc": Object { "end": Object { "column": 1, "line": 12, }, "filename": "/packages/pug-lexer/test/cases/attrs.js.pug", "start": Object { "column": 1, "line": 12, }, }, "type": "newline", }, Object { "loc": Object { "end": Object { "column": 2, "line": 12, }, "filename": "/packages/pug-lexer/test/cases/attrs.js.pug", "start": Object { "column": 1, "line": 12, }, }, "type": "tag", "val": "a", }, Object { "loc": Object { "end": Object { "column": 3, "line": 12, }, "filename": "/packages/pug-lexer/test/cases/attrs.js.pug", "start": Object { "column": 2, "line": 12, }, }, "type": "start-attributes", }, Object { "loc": Object { "end": Object { "column": 31, "line": 12, }, "filename": "/packages/pug-lexer/test/cases/attrs.js.pug", "start": Object { "column": 3, "line": 12, }, }, "mustEscape": true, "name": "class", "type": "attribute", "val": "['class1', 'class2']", }, Object { "loc": Object { "end": Object { "column": 32, "line": 12, }, "filename": "/packages/pug-lexer/test/cases/attrs.js.pug", "start": Object { "column": 31, "line": 12, }, }, "type": "end-attributes", }, Object { "loc": Object { "end": Object { "column": 1, "line": 13, }, "filename": "/packages/pug-lexer/test/cases/attrs.js.pug", "start": Object { "column": 1, "line": 13, }, }, "type": "newline", }, Object { "loc": Object { "end": Object { "column": 2, "line": 13, }, "filename": "/packages/pug-lexer/test/cases/attrs.js.pug", "start": Object { "column": 1, "line": 13, }, }, "type": "tag", "val": "a", }, Object { "loc": Object { "end": Object { "column": 12, "line": 13, }, "filename": "/packages/pug-lexer/test/cases/attrs.js.pug", "start": Object { "column": 2, "line": 13, }, }, "type": "class", "val": "tag-class", }, Object { "loc": Object { "end": Object { "column": 13, "line": 13, }, "filename": "/packages/pug-lexer/test/cases/attrs.js.pug", "start": Object { "column": 12, "line": 13, }, }, "type": "start-attributes", }, Object { "loc": Object { "end": Object { "column": 41, "line": 13, }, "filename": "/packages/pug-lexer/test/cases/attrs.js.pug", "start": Object { "column": 13, "line": 13, }, }, "mustEscape": true, "name": "class", "type": "attribute", "val": "['class1', 'class2']", }, Object { "loc": Object { "end": Object { "column": 42, "line": 13, }, "filename": "/packages/pug-lexer/test/cases/attrs.js.pug", "start": Object { "column": 41, "line": 13, }, }, "type": "end-attributes", }, Object { "loc": Object { "end": Object { "column": 1, "line": 15, }, "filename": "/packages/pug-lexer/test/cases/attrs.js.pug", "start": Object { "column": 1, "line": 15, }, }, "type": "newline", }, Object { "loc": Object { "end": Object { "column": 4, "line": 15, }, "filename": "/packages/pug-lexer/test/cases/attrs.js.pug", "start": Object { "column": 1, "line": 15, }, }, "type": "tag", "val": "div", }, Object { "loc": Object { "end": Object { "column": 5, "line": 15, }, "filename": "/packages/pug-lexer/test/cases/attrs.js.pug", "start": Object { "column": 4, "line": 15, }, }, "type": "start-attributes", }, Object { "loc": Object { "end": Object { "column": 10, "line": 15, }, "filename": "/packages/pug-lexer/test/cases/attrs.js.pug", "start": Object { "column": 5, "line": 15, }, }, "mustEscape": true, "name": "id", "type": "attribute", "val": "id", }, Object { "loc": Object { "end": Object { "column": 11, "line": 15, }, "filename": "/packages/pug-lexer/test/cases/attrs.js.pug", "start": Object { "column": 10, "line": 15, }, }, "type": "end-attributes", }, Object { "loc": Object { "end": Object { "column": 36, "line": 15, }, "filename": "/packages/pug-lexer/test/cases/attrs.js.pug", "start": Object { "column": 11, "line": 15, }, }, "type": "&attributes", "val": "{foo: 'bar'}", }, Object { "loc": Object { "end": Object { "column": 1, "line": 16, }, "filename": "/packages/pug-lexer/test/cases/attrs.js.pug", "start": Object { "column": 1, "line": 16, }, }, "type": "newline", }, Object { "buffer": false, "loc": Object { "end": Object { "column": 17, "line": 16, }, "filename": "/packages/pug-lexer/test/cases/attrs.js.pug", "start": Object { "column": 1, "line": 16, }, }, "mustEscape": false, "type": "code", "val": "var bar = null", }, Object { "loc": Object { "end": Object { "column": 1, "line": 17, }, "filename": "/packages/pug-lexer/test/cases/attrs.js.pug", "start": Object { "column": 1, "line": 17, }, }, "type": "newline", }, Object { "loc": Object { "end": Object { "column": 4, "line": 17, }, "filename": "/packages/pug-lexer/test/cases/attrs.js.pug", "start": Object { "column": 1, "line": 17, }, }, "type": "tag", "val": "div", }, Object { "loc": Object { "end": Object { "column": 5, "line": 17, }, "filename": "/packages/pug-lexer/test/cases/attrs.js.pug", "start": Object { "column": 4, "line": 17, }, }, "type": "start-attributes", }, Object { "loc": Object { "end": Object { "column": 13, "line": 17, }, "filename": "/packages/pug-lexer/test/cases/attrs.js.pug", "start": Object { "column": 5, "line": 17, }, }, "mustEscape": true, "name": "foo", "type": "attribute", "val": "null", }, Object { "loc": Object { "end": Object { "column": 21, "line": 17, }, "filename": "/packages/pug-lexer/test/cases/attrs.js.pug", "start": Object { "column": 14, "line": 17, }, }, "mustEscape": true, "name": "bar", "type": "attribute", "val": "bar", }, Object { "loc": Object { "end": Object { "column": 22, "line": 17, }, "filename": "/packages/pug-lexer/test/cases/attrs.js.pug", "start": Object { "column": 21, "line": 17, }, }, "type": "end-attributes", }, Object { "loc": Object { "end": Object { "column": 47, "line": 17, }, "filename": "/packages/pug-lexer/test/cases/attrs.js.pug", "start": Object { "column": 22, "line": 17, }, }, "type": "&attributes", "val": "{baz: 'baz'}", }, Object { "loc": Object { "end": Object { "column": 1, "line": 19, }, "filename": "/packages/pug-lexer/test/cases/attrs.js.pug", "start": Object { "column": 1, "line": 19, }, }, "type": "newline", }, Object { "loc": Object { "end": Object { "column": 4, "line": 19, }, "filename": "/packages/pug-lexer/test/cases/attrs.js.pug", "start": Object { "column": 1, "line": 19, }, }, "type": "tag", "val": "div", }, Object { "loc": Object { "end": Object { "column": 5, "line": 19, }, "filename": "/packages/pug-lexer/test/cases/attrs.js.pug", "start": Object { "column": 4, "line": 19, }, }, "type": "start-attributes", }, Object { "loc": Object { "end": Object { "column": 14, "line": 19, }, "filename": "/packages/pug-lexer/test/cases/attrs.js.pug", "start": Object { "column": 5, "line": 19, }, }, "mustEscape": true, "name": "...object", "type": "attribute", "val": true, }, Object { "loc": Object { "end": Object { "column": 15, "line": 19, }, "filename": "/packages/pug-lexer/test/cases/attrs.js.pug", "start": Object { "column": 14, "line": 19, }, }, "type": "end-attributes", }, Object { "loc": Object { "end": Object { "column": 1, "line": 20, }, "filename": "/packages/pug-lexer/test/cases/attrs.js.pug", "start": Object { "column": 1, "line": 20, }, }, "type": "newline", }, Object { "loc": Object { "end": Object { "column": 4, "line": 20, }, "filename": "/packages/pug-lexer/test/cases/attrs.js.pug", "start": Object { "column": 1, "line": 20, }, }, "type": "tag", "val": "div", }, Object { "loc": Object { "end": Object { "column": 5, "line": 20, }, "filename": "/packages/pug-lexer/test/cases/attrs.js.pug", "start": Object { "column": 4, "line": 20, }, }, "type": "start-attributes", }, Object { "loc": Object { "end": Object { "column": 14, "line": 20, }, "filename": "/packages/pug-lexer/test/cases/attrs.js.pug", "start": Object { "column": 5, "line": 20, }, }, "mustEscape": true, "name": "...object", "type": "attribute", "val": true, }, Object { "loc": Object { "end": Object { "column": 28, "line": 20, }, "filename": "/packages/pug-lexer/test/cases/attrs.js.pug", "start": Object { "column": 15, "line": 20, }, }, "mustEscape": true, "name": "after", "type": "attribute", "val": "\\"after\\"", }, Object { "loc": Object { "end": Object { "column": 29, "line": 20, }, "filename": "/packages/pug-lexer/test/cases/attrs.js.pug", "start": Object { "column": 28, "line": 20, }, }, "type": "end-attributes", }, Object { "loc": Object { "end": Object { "column": 1, "line": 21, }, "filename": "/packages/pug-lexer/test/cases/attrs.js.pug", "start": Object { "column": 1, "line": 21, }, }, "type": "newline", }, Object { "loc": Object { "end": Object { "column": 4, "line": 21, }, "filename": "/packages/pug-lexer/test/cases/attrs.js.pug", "start": Object { "column": 1, "line": 21, }, }, "type": "tag", "val": "div", }, Object { "loc": Object { "end": Object { "column": 5, "line": 21, }, "filename": "/packages/pug-lexer/test/cases/attrs.js.pug", "start": Object { "column": 4, "line": 21, }, }, "type": "start-attributes", }, Object { "loc": Object { "end": Object { "column": 20, "line": 21, }, "filename": "/packages/pug-lexer/test/cases/attrs.js.pug", "start": Object { "column": 5, "line": 21, }, }, "mustEscape": true, "name": "before", "type": "attribute", "val": "\\"before\\"", }, Object { "loc": Object { "end": Object { "column": 30, "line": 21, }, "filename": "/packages/pug-lexer/test/cases/attrs.js.pug", "start": Object { "column": 21, "line": 21, }, }, "mustEscape": true, "name": "...object", "type": "attribute", "val": true, }, Object { "loc": Object { "end": Object { "column": 31, "line": 21, }, "filename": "/packages/pug-lexer/test/cases/attrs.js.pug", "start": Object { "column": 30, "line": 21, }, }, "type": "end-attributes", }, Object { "loc": Object { "end": Object { "column": 1, "line": 22, }, "filename": "/packages/pug-lexer/test/cases/attrs.js.pug", "start": Object { "column": 1, "line": 22, }, }, "type": "newline", }, Object { "loc": Object { "end": Object { "column": 4, "line": 22, }, "filename": "/packages/pug-lexer/test/cases/attrs.js.pug", "start": Object { "column": 1, "line": 22, }, }, "type": "tag", "val": "div", }, Object { "loc": Object { "end": Object { "column": 5, "line": 22, }, "filename": "/packages/pug-lexer/test/cases/attrs.js.pug", "start": Object { "column": 4, "line": 22, }, }, "type": "start-attributes", }, Object { "loc": Object { "end": Object { "column": 20, "line": 22, }, "filename": "/packages/pug-lexer/test/cases/attrs.js.pug", "start": Object { "column": 5, "line": 22, }, }, "mustEscape": true, "name": "before", "type": "attribute", "val": "\\"before\\"", }, Object { "loc": Object { "end": Object { "column": 30, "line": 22, }, "filename": "/packages/pug-lexer/test/cases/attrs.js.pug", "start": Object { "column": 21, "line": 22, }, }, "mustEscape": true, "name": "...object", "type": "attribute", "val": true, }, Object { "loc": Object { "end": Object { "column": 44, "line": 22, }, "filename": "/packages/pug-lexer/test/cases/attrs.js.pug", "start": Object { "column": 31, "line": 22, }, }, "mustEscape": true, "name": "after", "type": "attribute", "val": "\\"after\\"", }, Object { "loc": Object { "end": Object { "column": 45, "line": 22, }, "filename": "/packages/pug-lexer/test/cases/attrs.js.pug", "start": Object { "column": 44, "line": 22, }, }, "type": "end-attributes", }, Object { "loc": Object { "end": Object { "column": 1, "line": 23, }, "filename": "/packages/pug-lexer/test/cases/attrs.js.pug", "start": Object { "column": 1, "line": 23, }, }, "type": "newline", }, Object { "loc": Object { "end": Object { "column": 1, "line": 23, }, "filename": "/packages/pug-lexer/test/cases/attrs.js.pug", "start": Object { "column": 1, "line": 23, }, }, "type": "eos", }, ] `; exports[`attrs.pug 1`] = ` Array [ Object { "loc": Object { "end": Object { "column": 2, "line": 1, }, "filename": "/packages/pug-lexer/test/cases/attrs.pug", "start": Object { "column": 1, "line": 1, }, }, "type": "tag", "val": "a", }, Object { "loc": Object { "end": Object { "column": 3, "line": 1, }, "filename": "/packages/pug-lexer/test/cases/attrs.pug", "start": Object { "column": 2, "line": 1, }, }, "type": "start-attributes", }, Object { "loc": Object { "end": Object { "column": 18, "line": 1, }, "filename": "/packages/pug-lexer/test/cases/attrs.pug", "start": Object { "column": 3, "line": 1, }, }, "mustEscape": true, "name": "href", "type": "attribute", "val": "'/contact'", }, Object { "loc": Object { "end": Object { "column": 19, "line": 1, }, "filename": "/packages/pug-lexer/test/cases/attrs.pug", "start": Object { "column": 18, "line": 1, }, }, "type": "end-attributes", }, Object { "loc": Object { "end": Object { "column": 27, "line": 1, }, "filename": "/packages/pug-lexer/test/cases/attrs.pug", "start": Object { "column": 20, "line": 1, }, }, "type": "text", "val": "contact", }, Object { "loc": Object { "end": Object { "column": 1, "line": 2, }, "filename": "/packages/pug-lexer/test/cases/attrs.pug", "start": Object { "column": 1, "line": 2, }, }, "type": "newline", }, Object { "loc": Object { "end": Object { "column": 2, "line": 2, }, "filename": "/packages/pug-lexer/test/cases/attrs.pug", "start": Object { "column": 1, "line": 2, }, }, "type": "tag", "val": "a", }, Object { "loc": Object { "end": Object { "column": 3, "line": 2, }, "filename": "/packages/pug-lexer/test/cases/attrs.pug", "start": Object { "column": 2, "line": 2, }, }, "type": "start-attributes", }, Object { "loc": Object { "end": Object { "column": 15, "line": 2, }, "filename": "/packages/pug-lexer/test/cases/attrs.pug", "start": Object { "column": 3, "line": 2, }, }, "mustEscape": true, "name": "href", "type": "attribute", "val": "'/save'", }, Object { "loc": Object { "end": Object { "column": 16, "line": 2, }, "filename": "/packages/pug-lexer/test/cases/attrs.pug", "start": Object { "column": 15, "line": 2, }, }, "type": "end-attributes", }, Object { "loc": Object { "end": Object { "column": 23, "line": 2, }, "filename": "/packages/pug-lexer/test/cases/attrs.pug", "start": Object { "column": 16, "line": 2, }, }, "type": "class", "val": "button", }, Object { "loc": Object { "end": Object { "column": 28, "line": 2, }, "filename": "/packages/pug-lexer/test/cases/attrs.pug", "start": Object { "column": 24, "line": 2, }, }, "type": "text", "val": "save", }, Object { "loc": Object { "end": Object { "column": 1, "line": 3, }, "filename": "/packages/pug-lexer/test/cases/attrs.pug", "start": Object { "column": 1, "line": 3, }, }, "type": "newline", }, Object { "loc": Object { "end": Object { "column": 2, "line": 3, }, "filename": "/packages/pug-lexer/test/cases/attrs.pug", "start": Object { "column": 1, "line": 3, }, }, "type": "tag", "val": "a", }, Object { "loc": Object { "end": Object { "column": 3, "line": 3, }, "filename": "/packages/pug-lexer/test/cases/attrs.pug", "start": Object { "column": 2, "line": 3, }, }, "type": "start-attributes", }, Object { "loc": Object { "end": Object { "column": 6, "line": 3, }, "filename": "/packages/pug-lexer/test/cases/attrs.pug", "start": Object { "column": 3, "line": 3, }, }, "mustEscape": true, "name": "foo", "type": "attribute", "val": true, }, Object { "loc": Object { "end": Object { "column": 11, "line": 3, }, "filename": "/packages/pug-lexer/test/cases/attrs.pug", "start": Object { "column": 8, "line": 3, }, }, "mustEscape": true, "name": "bar", "type": "attribute", "val": true, }, Object { "loc": Object { "end": Object { "column": 16, "line": 3, }, "filename": "/packages/pug-lexer/test/cases/attrs.pug", "start": Object { "column": 13, "line": 3, }, }, "mustEscape": true, "name": "baz", "type": "attribute", "val": true, }, Object { "loc": Object { "end": Object { "column": 17, "line": 3, }, "filename": "/packages/pug-lexer/test/cases/attrs.pug", "start": Object { "column": 16, "line": 3, }, }, "type": "end-attributes", }, Object { "loc": Object { "end": Object { "column": 1, "line": 4, }, "filename": "/packages/pug-lexer/test/cases/attrs.pug", "start": Object { "column": 1, "line": 4, }, }, "type": "newline", }, Object { "loc": Object { "end": Object { "column": 2, "line": 4, }, "filename": "/packages/pug-lexer/test/cases/attrs.pug", "start": Object { "column": 1, "line": 4, }, }, "type": "tag", "val": "a", }, Object { "loc": Object { "end": Object { "column": 3, "line": 4, }, "filename": "/packages/pug-lexer/test/cases/attrs.pug", "start": Object { "column": 2, "line": 4, }, }, "type": "start-attributes", }, Object { "loc": Object { "end": Object { "column": 22, "line": 4, }, "filename": "/packages/pug-lexer/test/cases/attrs.pug", "start": Object { "column": 3, "line": 4, }, }, "mustEscape": true, "name": "foo", "type": "attribute", "val": "'foo, bar, baz'", }, Object { "loc": Object { "end": Object { "column": 29, "line": 4, }, "filename": "/packages/pug-lexer/test/cases/attrs.pug", "start": Object { "column": 24, "line": 4, }, }, "mustEscape": true, "name": "bar", "type": "attribute", "val": "1", }, Object { "loc": Object { "end": Object { "column": 30, "line": 4, }, "filename": "/packages/pug-lexer/test/cases/attrs.pug", "start": Object { "column": 29, "line": 4, }, }, "type": "end-attributes", }, Object { "loc": Object { "end": Object { "column": 1, "line": 5, }, "filename": "/packages/pug-lexer/test/cases/attrs.pug", "start": Object { "column": 1, "line": 5, }, }, "type": "newline", }, Object { "loc": Object { "end": Object { "column": 2, "line": 5, }, "filename": "/packages/pug-lexer/test/cases/attrs.pug", "start": Object { "column": 1, "line": 5, }, }, "type": "tag", "val": "a", }, Object { "loc": Object { "end": Object { "column": 3, "line": 5, }, "filename": "/packages/pug-lexer/test/cases/attrs.pug", "start": Object { "column": 2, "line": 5, }, }, "type": "start-attributes", }, Object { "loc": Object { "end": Object { "column": 16, "line": 5, }, "filename": "/packages/pug-lexer/test/cases/attrs.pug", "start": Object { "column": 3, "line": 5, }, }, "mustEscape": true, "name": "foo", "type": "attribute", "val": "'((foo))'", }, Object { "loc": Object { "end": Object { "column": 34, "line": 5, }, "filename": "/packages/pug-lexer/test/cases/attrs.pug", "start": Object { "column": 18, "line": 5, }, }, "mustEscape": true, "name": "bar", "type": "attribute", "val": "(1) ? 1 : 0", }, Object { "loc": Object { "end": Object { "column": 36, "line": 5, }, "filename": "/packages/pug-lexer/test/cases/attrs.pug", "start": Object { "column": 35, "line": 5, }, }, "type": "end-attributes", }, Object { "loc": Object { "end": Object { "column": 1, "line": 6, }, "filename": "/packages/pug-lexer/test/cases/attrs.pug", "start": Object { "column": 1, "line": 6, }, }, "type": "newline", }, Object { "loc": Object { "end": Object { "column": 7, "line": 6, }, "filename": "/packages/pug-lexer/test/cases/attrs.pug", "start": Object { "column": 1, "line": 6, }, }, "type": "tag", "val": "select", }, Object { "loc": Object { "end": Object { "column": 3, "line": 7, }, "filename": "/packages/pug-lexer/test/cases/attrs.pug", "start": Object { "column": 1, "line": 7, }, }, "type": "indent", "val": 2, }, Object { "loc": Object { "end": Object { "column": 9, "line": 7, }, "filename": "/packages/pug-lexer/test/cases/attrs.pug", "start": Object { "column": 3, "line": 7, }, }, "type": "tag", "val": "option", }, Object { "loc": Object { "end": Object { "column": 10, "line": 7, }, "filename": "/packages/pug-lexer/test/cases/attrs.pug", "start": Object { "column": 9, "line": 7, }, }, "type": "start-attributes", }, Object { "loc": Object { "end": Object { "column": 21, "line": 7, }, "filename": "/packages/pug-lexer/test/cases/attrs.pug", "start": Object { "column": 10, "line": 7, }, }, "mustEscape": true, "name": "value", "type": "attribute", "val": "'foo'", }, Object { "loc": Object { "end": Object { "column": 31, "line": 7, }, "filename": "/packages/pug-lexer/test/cases/attrs.pug", "start": Object { "column": 23, "line": 7, }, }, "mustEscape": true, "name": "selected", "type": "attribute", "val": true, }, Object { "loc": Object { "end": Object { "column": 32, "line": 7, }, "filename": "/packages/pug-lexer/test/cases/attrs.pug", "start": Object { "column": 31, "line": 7, }, }, "type": "end-attributes", }, Object { "loc": Object { "end": Object { "column": 36, "line": 7, }, "filename": "/packages/pug-lexer/test/cases/attrs.pug", "start": Object { "column": 33, "line": 7, }, }, "type": "text", "val": "Foo", }, Object { "loc": Object { "end": Object { "column": 3, "line": 8, }, "filename": "/packages/pug-lexer/test/cases/attrs.pug", "start": Object { "column": 1, "line": 8, }, }, "type": "newline", }, Object { "loc": Object { "end": Object { "column": 9, "line": 8, }, "filename": "/packages/pug-lexer/test/cases/attrs.pug", "start": Object { "column": 3, "line": 8, }, }, "type": "tag", "val": "option", }, Object { "loc": Object { "end": Object { "column": 10, "line": 8, }, "filename": "/packages/pug-lexer/test/cases/attrs.pug", "start": Object { "column": 9, "line": 8, }, }, "type": "start-attributes", }, Object { "loc": Object { "end": Object { "column": 18, "line": 8, }, "filename": "/packages/pug-lexer/test/cases/attrs.pug", "start": Object { "column": 10, "line": 8, }, }, "mustEscape": true, "name": "selected", "type": "attribute", "val": true, }, Object { "loc": Object { "end": Object { "column": 31, "line": 8, }, "filename": "/packages/pug-lexer/test/cases/attrs.pug", "start": Object { "column": 20, "line": 8, }, }, "mustEscape": true, "name": "value", "type": "attribute", "val": "'bar'", }, Object { "loc": Object { "end": Object { "column": 32, "line": 8, }, "filename": "/packages/pug-lexer/test/cases/attrs.pug", "start": Object { "column": 31, "line": 8, }, }, "type": "end-attributes", }, Object { "loc": Object { "end": Object { "column": 36, "line": 8, }, "filename": "/packages/pug-lexer/test/cases/attrs.pug", "start": Object { "column": 33, "line": 8, }, }, "type": "text", "val": "Bar", }, Object { "loc": Object { "end": Object { "column": 1, "line": 9, }, "filename": "/packages/pug-lexer/test/cases/attrs.pug", "start": Object { "column": 1, "line": 9, }, }, "type": "outdent", }, Object { "loc": Object { "end": Object { "column": 2, "line": 9, }, "filename": "/packages/pug-lexer/test/cases/attrs.pug", "start": Object { "column": 1, "line": 9, }, }, "type": "tag", "val": "a", }, Object { "loc": Object { "end": Object { "column": 3, "line": 9, }, "filename": "/packages/pug-lexer/test/cases/attrs.pug", "start": Object { "column": 2, "line": 9, }, }, "type": "start-attributes", }, Object { "loc": Object { "end": Object { "column": 15, "line": 9, }, "filename": "/packages/pug-lexer/test/cases/attrs.pug", "start": Object { "column": 3, "line": 9, }, }, "mustEscape": true, "name": "foo", "type": "attribute", "val": "\\"class:\\"", }, Object { "loc": Object { "end": Object { "column": 16, "line": 9, }, "filename": "/packages/pug-lexer/test/cases/attrs.pug", "start": Object { "column": 15, "line": 9, }, }, "type": "end-attributes", }, Object { "loc": Object { "end": Object { "column": 1, "line": 10, }, "filename": "/packages/pug-lexer/test/cases/attrs.pug", "start": Object { "column": 1, "line": 10, }, }, "type": "newline", }, Object { "loc": Object { "end": Object { "column": 6, "line": 10, }, "filename": "/packages/pug-lexer/test/cases/attrs.pug", "start": Object { "column": 1, "line": 10, }, }, "type": "tag", "val": "input", }, Object { "loc": Object { "end": Object { "column": 7, "line": 10, }, "filename": "/packages/pug-lexer/test/cases/attrs.pug", "start": Object { "column": 6, "line": 10, }, }, "type": "start-attributes", }, Object { "loc": Object { "end": Object { "column": 21, "line": 10, }, "filename": "/packages/pug-lexer/test/cases/attrs.pug", "start": Object { "column": 7, "line": 10, }, }, "mustEscape": true, "name": "pattern", "type": "attribute", "val": "'\\\\\\\\S+'", }, Object { "loc": Object { "end": Object { "column": 22, "line": 10, }, "filename": "/packages/pug-lexer/test/cases/attrs.pug", "start": Object { "column": 21, "line": 10, }, }, "type": "end-attributes", }, Object { "loc": Object { "end": Object { "column": 1, "line": 12, }, "filename": "/packages/pug-lexer/test/cases/attrs.pug", "start": Object { "column": 1, "line": 12, }, }, "type": "newline", }, Object { "loc": Object { "end": Object { "column": 2, "line": 12, }, "filename": "/packages/pug-lexer/test/cases/attrs.pug", "start": Object { "column": 1, "line": 12, }, }, "type": "tag", "val": "a", }, Object { "loc": Object { "end": Object { "column": 3, "line": 12, }, "filename": "/packages/pug-lexer/test/cases/attrs.pug", "start": Object { "column": 2, "line": 12, }, }, "type": "start-attributes", }, Object { "loc": Object { "end": Object { "column": 18, "line": 12, }, "filename": "/packages/pug-lexer/test/cases/attrs.pug", "start": Object { "column": 3, "line": 12, }, }, "mustEscape": true, "name": "href", "type": "attribute", "val": "'/contact'", }, Object { "loc": Object { "end": Object { "column": 19, "line": 12, }, "filename": "/packages/pug-lexer/test/cases/attrs.pug", "start": Object { "column": 18, "line": 12, }, }, "type": "end-attributes", }, Object { "loc": Object { "end": Object { "column": 27, "line": 12, }, "filename": "/packages/pug-lexer/test/cases/attrs.pug", "start": Object { "column": 20, "line": 12, }, }, "type": "text", "val": "contact", }, Object { "loc": Object { "end": Object { "column": 1, "line": 13, }, "filename": "/packages/pug-lexer/test/cases/attrs.pug", "start": Object { "column": 1, "line": 13, }, }, "type": "newline", }, Object { "loc": Object { "end": Object { "column": 2, "line": 13, }, "filename": "/packages/pug-lexer/test/cases/attrs.pug", "start": Object { "column": 1, "line": 13, }, }, "type": "tag", "val": "a", }, Object { "loc": Object { "end": Object { "column": 3, "line": 13, }, "filename": "/packages/pug-lexer/test/cases/attrs.pug", "start": Object { "column": 2, "line": 13, }, }, "type": "start-attributes", }, Object { "loc": Object { "end": Object { "column": 15, "line": 13, }, "filename": "/packages/pug-lexer/test/cases/attrs.pug", "start": Object { "column": 3, "line": 13, }, }, "mustEscape": true, "name": "href", "type": "attribute", "val": "'/save'", }, Object { "loc": Object { "end": Object { "column": 16, "line": 13, }, "filename": "/packages/pug-lexer/test/cases/attrs.pug", "start": Object { "column": 15, "line": 13, }, }, "type": "end-attributes", }, Object { "loc": Object { "end": Object { "column": 23, "line": 13, }, "filename": "/packages/pug-lexer/test/cases/attrs.pug", "start": Object { "column": 16, "line": 13, }, }, "type": "class", "val": "button", }, Object { "loc": Object { "end": Object { "column": 28, "line": 13, }, "filename": "/packages/pug-lexer/test/cases/attrs.pug", "start": Object { "column": 24, "line": 13, }, }, "type": "text", "val": "save", }, Object { "loc": Object { "end": Object { "column": 1, "line": 14, }, "filename": "/packages/pug-lexer/test/cases/attrs.pug", "start": Object { "column": 1, "line": 14, }, }, "type": "newline", }, Object { "loc": Object { "end": Object { "column": 2, "line": 14, }, "filename": "/packages/pug-lexer/test/cases/attrs.pug", "start": Object { "column": 1, "line": 14, }, }, "type": "tag", "val": "a", }, Object { "loc": Object { "end": Object { "column": 3, "line": 14, }, "filename": "/packages/pug-lexer/test/cases/attrs.pug", "start": Object { "column": 2, "line": 14, }, }, "type": "start-attributes", }, Object { "loc": Object { "end": Object { "column": 6, "line": 14, }, "filename": "/packages/pug-lexer/test/cases/attrs.pug", "start": Object { "column": 3, "line": 14, }, }, "mustEscape": true, "name": "foo", "type": "attribute", "val": true, }, Object { "loc": Object { "end": Object { "column": 10, "line": 14, }, "filename": "/packages/pug-lexer/test/cases/attrs.pug", "start": Object { "column": 7, "line": 14, }, }, "mustEscape": true, "name": "bar", "type": "attribute", "val": true, }, Object { "loc": Object { "end": Object { "column": 14, "line": 14, }, "filename": "/packages/pug-lexer/test/cases/attrs.pug", "start": Object { "column": 11, "line": 14, }, }, "mustEscape": true, "name": "baz", "type": "attribute", "val": true, }, Object { "loc": Object { "end": Object { "column": 15, "line": 14, }, "filename": "/packages/pug-lexer/test/cases/attrs.pug", "start": Object { "column": 14, "line": 14, }, }, "type": "end-attributes", }, Object { "loc": Object { "end": Object { "column": 1, "line": 15, }, "filename": "/packages/pug-lexer/test/cases/attrs.pug", "start": Object { "column": 1, "line": 15, }, }, "type": "newline", }, Object { "loc": Object { "end": Object { "column": 2, "line": 15, }, "filename": "/packages/pug-lexer/test/cases/attrs.pug", "start": Object { "column": 1, "line": 15, }, }, "type": "tag", "val": "a", }, Object { "loc": Object { "end": Object { "column": 3, "line": 15, }, "filename": "/packages/pug-lexer/test/cases/attrs.pug", "start": Object { "column": 2, "line": 15, }, }, "type": "start-attributes", }, Object { "loc": Object { "end": Object { "column": 22, "line": 15, }, "filename": "/packages/pug-lexer/test/cases/attrs.pug", "start": Object { "column": 3, "line": 15, }, }, "mustEscape": true, "name": "foo", "type": "attribute", "val": "'foo, bar, baz'", }, Object { "loc": Object { "end": Object { "column": 28, "line": 15, }, "filename": "/packages/pug-lexer/test/cases/attrs.pug", "start": Object { "column": 23, "line": 15, }, }, "mustEscape": true, "name": "bar", "type": "attribute", "val": "1", }, Object { "loc": Object { "end": Object { "column": 29, "line": 15, }, "filename": "/packages/pug-lexer/test/cases/attrs.pug", "start": Object { "column": 28, "line": 15, }, }, "type": "end-attributes", }, Object { "loc": Object { "end": Object { "column": 1, "line": 16, }, "filename": "/packages/pug-lexer/test/cases/attrs.pug", "start": Object { "column": 1, "line": 16, }, }, "type": "newline", }, Object { "loc": Object { "end": Object { "column": 2, "line": 16, }, "filename": "/packages/pug-lexer/test/cases/attrs.pug", "start": Object { "column": 1, "line": 16, }, }, "type": "tag", "val": "a", }, Object { "loc": Object { "end": Object { "column": 3, "line": 16, }, "filename": "/packages/pug-lexer/test/cases/attrs.pug", "start": Object { "column": 2, "line": 16, }, }, "type": "start-attributes", }, Object { "loc": Object { "end": Object { "column": 16, "line": 16, }, "filename": "/packages/pug-lexer/test/cases/attrs.pug", "start": Object { "column": 3, "line": 16, }, }, "mustEscape": true, "name": "foo", "type": "attribute", "val": "'((foo))'", }, Object { "loc": Object { "end": Object { "column": 33, "line": 16, }, "filename": "/packages/pug-lexer/test/cases/attrs.pug", "start": Object { "column": 17, "line": 16, }, }, "mustEscape": true, "name": "bar", "type": "attribute", "val": "(1) ? 1 : 0", }, Object { "loc": Object { "end": Object { "column": 35, "line": 16, }, "filename": "/packages/pug-lexer/test/cases/attrs.pug", "start": Object { "column": 34, "line": 16, }, }, "type": "end-attributes", }, Object { "loc": Object { "end": Object { "column": 1, "line": 17, }, "filename": "/packages/pug-lexer/test/cases/attrs.pug", "start": Object { "column": 1, "line": 17, }, }, "type": "newline", }, Object { "loc": Object { "end": Object { "column": 7, "line": 17, }, "filename": "/packages/pug-lexer/test/cases/attrs.pug", "start": Object { "column": 1, "line": 17, }, }, "type": "tag", "val": "select", }, Object { "loc": Object { "end": Object { "column": 3, "line": 18, }, "filename": "/packages/pug-lexer/test/cases/attrs.pug", "start": Object { "column": 1, "line": 18, }, }, "type": "indent", "val": 2, }, Object { "loc": Object { "end": Object { "column": 9, "line": 18, }, "filename": "/packages/pug-lexer/test/cases/attrs.pug", "start": Object { "column": 3, "line": 18, }, }, "type": "tag", "val": "option", }, Object { "loc": Object { "end": Object { "column": 10, "line": 18, }, "filename": "/packages/pug-lexer/test/cases/attrs.pug", "start": Object { "column": 9, "line": 18, }, }, "type": "start-attributes", }, Object { "loc": Object { "end": Object { "column": 21, "line": 18, }, "filename": "/packages/pug-lexer/test/cases/attrs.pug", "start": Object { "column": 10, "line": 18, }, }, "mustEscape": true, "name": "value", "type": "attribute", "val": "'foo'", }, Object { "loc": Object { "end": Object { "column": 30, "line": 18, }, "filename": "/packages/pug-lexer/test/cases/attrs.pug", "start": Object { "column": 22, "line": 18, }, }, "mustEscape": true, "name": "selected", "type": "attribute", "val": true, }, Object { "loc": Object { "end": Object { "column": 31, "line": 18, }, "filename": "/packages/pug-lexer/test/cases/attrs.pug", "start": Object { "column": 30, "line": 18, }, }, "type": "end-attributes", }, Object { "loc": Object { "end": Object { "column": 35, "line": 18, }, "filename": "/packages/pug-lexer/test/cases/attrs.pug", "start": Object { "column": 32, "line": 18, }, }, "type": "text", "val": "Foo", }, Object { "loc": Object { "end": Object { "column": 3, "line": 19, }, "filename": "/packages/pug-lexer/test/cases/attrs.pug", "start": Object { "column": 1, "line": 19, }, }, "type": "newline", }, Object { "loc": Object { "end": Object { "column": 9, "line": 19, }, "filename": "/packages/pug-lexer/test/cases/attrs.pug", "start": Object { "column": 3, "line": 19, }, }, "type": "tag", "val": "option", }, Object { "loc": Object { "end": Object { "column": 10, "line": 19, }, "filename": "/packages/pug-lexer/test/cases/attrs.pug", "start": Object { "column": 9, "line": 19, }, }, "type": "start-attributes", }, Object { "loc": Object { "end": Object { "column": 18, "line": 19, }, "filename": "/packages/pug-lexer/test/cases/attrs.pug", "start": Object { "column": 10, "line": 19, }, }, "mustEscape": true, "name": "selected", "type": "attribute", "val": true, }, Object { "loc": Object { "end": Object { "column": 30, "line": 19, }, "filename": "/packages/pug-lexer/test/cases/attrs.pug", "start": Object { "column": 19, "line": 19, }, }, "mustEscape": true, "name": "value", "type": "attribute", "val": "'bar'", }, Object { "loc": Object { "end": Object { "column": 31, "line": 19, }, "filename": "/packages/pug-lexer/test/cases/attrs.pug", "start": Object { "column": 30, "line": 19, }, }, "type": "end-attributes", }, Object { "loc": Object { "end": Object { "column": 35, "line": 19, }, "filename": "/packages/pug-lexer/test/cases/attrs.pug", "start": Object { "column": 32, "line": 19, }, }, "type": "text", "val": "Bar", }, Object { "loc": Object { "end": Object { "column": 1, "line": 20, }, "filename": "/packages/pug-lexer/test/cases/attrs.pug", "start": Object { "column": 1, "line": 20, }, }, "type": "outdent", }, Object { "loc": Object { "end": Object { "column": 2, "line": 20, }, "filename": "/packages/pug-lexer/test/cases/attrs.pug", "start": Object { "column": 1, "line": 20, }, }, "type": "tag", "val": "a", }, Object { "loc": Object { "end": Object { "column": 3, "line": 20, }, "filename": "/packages/pug-lexer/test/cases/attrs.pug", "start": Object { "column": 2, "line": 20, }, }, "type": "start-attributes", }, Object { "loc": Object { "end": Object { "column": 15, "line": 20, }, "filename": "/packages/pug-lexer/test/cases/attrs.pug", "start": Object { "column": 3, "line": 20, }, }, "mustEscape": true, "name": "foo", "type": "attribute", "val": "\\"class:\\"", }, Object { "loc": Object { "end": Object { "column": 16, "line": 20, }, "filename": "/packages/pug-lexer/test/cases/attrs.pug", "start": Object { "column": 15, "line": 20, }, }, "type": "end-attributes", }, Object { "loc": Object { "end": Object { "column": 1, "line": 21, }, "filename": "/packages/pug-lexer/test/cases/attrs.pug", "start": Object { "column": 1, "line": 21, }, }, "type": "newline", }, Object { "loc": Object { "end": Object { "column": 6, "line": 21, }, "filename": "/packages/pug-lexer/test/cases/attrs.pug", "start": Object { "column": 1, "line": 21, }, }, "type": "tag", "val": "input", }, Object { "loc": Object { "end": Object { "column": 7, "line": 21, }, "filename": "/packages/pug-lexer/test/cases/attrs.pug", "start": Object { "column": 6, "line": 21, }, }, "type": "start-attributes", }, Object { "loc": Object { "end": Object { "column": 21, "line": 21, }, "filename": "/packages/pug-lexer/test/cases/attrs.pug", "start": Object { "column": 7, "line": 21, }, }, "mustEscape": true, "name": "pattern", "type": "attribute", "val": "'\\\\\\\\S+'", }, Object { "loc": Object { "end": Object { "column": 22, "line": 21, }, "filename": "/packages/pug-lexer/test/cases/attrs.pug", "start": Object { "column": 21, "line": 21, }, }, "type": "end-attributes", }, Object { "loc": Object { "end": Object { "column": 1, "line": 22, }, "filename": "/packages/pug-lexer/test/cases/attrs.pug", "start": Object { "column": 1, "line": 22, }, }, "type": "newline", }, Object { "loc": Object { "end": Object { "column": 4, "line": 22, }, "filename": "/packages/pug-lexer/test/cases/attrs.pug", "start": Object { "column": 1, "line": 22, }, }, "type": "tag", "val": "foo", }, Object { "loc": Object { "end": Object { "column": 5, "line": 22, }, "filename": "/packages/pug-lexer/test/cases/attrs.pug", "start": Object { "column": 4, "line": 22, }, }, "type": "start-attributes", }, Object { "loc": Object { "end": Object { "column": 17, "line": 22, }, "filename": "/packages/pug-lexer/test/cases/attrs.pug", "start": Object { "column": 5, "line": 22, }, }, "mustEscape": true, "name": "terse", "type": "attribute", "val": "\\"true\\"", }, Object { "loc": Object { "end": Object { "column": 18, "line": 22, }, "filename": "/packages/pug-lexer/test/cases/attrs.pug", "start": Object { "column": 17, "line": 22, }, }, "type": "end-attributes", }, Object { "loc": Object { "end": Object { "column": 1, "line": 23, }, "filename": "/packages/pug-lexer/test/cases/attrs.pug", "start": Object { "column": 1, "line": 23, }, }, "type": "newline", }, Object { "loc": Object { "end": Object { "column": 4, "line": 23, }, "filename": "/packages/pug-lexer/test/cases/attrs.pug", "start": Object { "column": 1, "line": 23, }, }, "type": "tag", "val": "foo", }, Object { "loc": Object { "end": Object { "column": 5, "line": 23, }, "filename": "/packages/pug-lexer/test/cases/attrs.pug", "start": Object { "column": 4, "line": 23, }, }, "type": "start-attributes", }, Object { "loc": Object { "end": Object { "column": 21, "line": 23, }, "filename": "/packages/pug-lexer/test/cases/attrs.pug", "start": Object { "column": 5, "line": 23, }, }, "mustEscape": true, "name": "date", "type": "attribute", "val": "new Date(0)", }, Object { "loc": Object { "end": Object { "column": 22, "line": 23, }, "filename": "/packages/pug-lexer/test/cases/attrs.pug", "start": Object { "column": 21, "line": 23, }, }, "type": "end-attributes", }, Object { "loc": Object { "end": Object { "column": 1, "line": 25, }, "filename": "/packages/pug-lexer/test/cases/attrs.pug", "start": Object { "column": 1, "line": 25, }, }, "type": "newline", }, Object { "loc": Object { "end": Object { "column": 4, "line": 25, }, "filename": "/packages/pug-lexer/test/cases/attrs.pug", "start": Object { "column": 1, "line": 25, }, }, "type": "tag", "val": "foo", }, Object { "loc": Object { "end": Object { "column": 5, "line": 25, }, "filename": "/packages/pug-lexer/test/cases/attrs.pug", "start": Object { "column": 4, "line": 25, }, }, "type": "start-attributes", }, Object { "loc": Object { "end": Object { "column": 8, "line": 25, }, "filename": "/packages/pug-lexer/test/cases/attrs.pug", "start": Object { "column": 5, "line": 25, }, }, "mustEscape": true, "name": "abc", "type": "attribute", "val": true, }, Object { "loc": Object { "end": Object { "column": 8, "line": 26, }, "filename": "/packages/pug-lexer/test/cases/attrs.pug", "start": Object { "column": 5, "line": 26, }, }, "mustEscape": true, "name": "def", "type": "attribute", "val": true, }, Object { "loc": Object { "end": Object { "column": 9, "line": 26, }, "filename": "/packages/pug-lexer/test/cases/attrs.pug", "start": Object { "column": 8, "line": 26, }, }, "type": "end-attributes", }, Object { "loc": Object { "end": Object { "column": 1, "line": 27, }, "filename": "/packages/pug-lexer/test/cases/attrs.pug", "start": Object { "column": 1, "line": 27, }, }, "type": "newline", }, Object { "loc": Object { "end": Object { "column": 4, "line": 27, }, "filename": "/packages/pug-lexer/test/cases/attrs.pug", "start": Object { "column": 1, "line": 27, }, }, "type": "tag", "val": "foo", }, Object { "loc": Object { "end": Object { "column": 5, "line": 27, }, "filename": "/packages/pug-lexer/test/cases/attrs.pug", "start": Object { "column": 4, "line": 27, }, }, "type": "start-attributes", }, Object { "loc": Object { "end": Object { "column": 8, "line": 27, }, "filename": "/packages/pug-lexer/test/cases/attrs.pug", "start": Object { "column": 5, "line": 27, }, }, "mustEscape": true, "name": "abc", "type": "attribute", "val": true, }, Object { "loc": Object { "end": Object { "column": 8, "line": 28, }, "filename": "/packages/pug-lexer/test/cases/attrs.pug", "start": Object { "column": 5, "line": 28, }, }, "mustEscape": true, "name": "def", "type": "attribute", "val": true, }, Object { "loc": Object { "end": Object { "column": 9, "line": 28, }, "filename": "/packages/pug-lexer/test/cases/attrs.pug", "start": Object { "column": 8, "line": 28, }, }, "type": "end-attributes", }, Object { "loc": Object { "end": Object { "column": 1, "line": 29, }, "filename": "/packages/pug-lexer/test/cases/attrs.pug", "start": Object { "column": 1, "line": 29, }, }, "type": "newline", }, Object { "loc": Object { "end": Object { "column": 4, "line": 29, }, "filename": "/packages/pug-lexer/test/cases/attrs.pug", "start": Object { "column": 1, "line": 29, }, }, "type": "tag", "val": "foo", }, Object { "loc": Object { "end": Object { "column": 5, "line": 29, }, "filename": "/packages/pug-lexer/test/cases/attrs.pug", "start": Object { "column": 4, "line": 29, }, }, "type": "start-attributes", }, Object { "loc": Object { "end": Object { "column": 8, "line": 29, }, "filename": "/packages/pug-lexer/test/cases/attrs.pug", "start": Object { "column": 5, "line": 29, }, }, "mustEscape": true, "name": "abc", "type": "attribute", "val": true, }, Object { "loc": Object { "end": Object { "column": 6, "line": 30, }, "filename": "/packages/pug-lexer/test/cases/attrs.pug", "start": Object { "column": 3, "line": 30, }, }, "mustEscape": true, "name": "def", "type": "attribute", "val": true, }, Object { "loc": Object { "end": Object { "column": 7, "line": 30, }, "filename": "/packages/pug-lexer/test/cases/attrs.pug", "start": Object { "column": 6, "line": 30, }, }, "type": "end-attributes", }, Object { "loc": Object { "end": Object { "column": 1, "line": 31, }, "filename": "/packages/pug-lexer/test/cases/attrs.pug", "start": Object { "column": 1, "line": 31, }, }, "type": "newline", }, Object { "loc": Object { "end": Object { "column": 4, "line": 31, }, "filename": "/packages/pug-lexer/test/cases/attrs.pug", "start": Object { "column": 1, "line": 31, }, }, "type": "tag", "val": "foo", }, Object { "loc": Object { "end": Object { "column": 5, "line": 31, }, "filename": "/packages/pug-lexer/test/cases/attrs.pug", "start": Object { "column": 4, "line": 31, }, }, "type": "start-attributes", }, Object { "loc": Object { "end": Object { "column": 8, "line": 31, }, "filename": "/packages/pug-lexer/test/cases/attrs.pug", "start": Object { "column": 5, "line": 31, }, }, "mustEscape": true, "name": "abc", "type": "attribute", "val": true, }, Object { "loc": Object { "end": Object { "column": 7, "line": 32, }, "filename": "/packages/pug-lexer/test/cases/attrs.pug", "start": Object { "column": 4, "line": 32, }, }, "mustEscape": true, "name": "def", "type": "attribute", "val": true, }, Object { "loc": Object { "end": Object { "column": 8, "line": 32, }, "filename": "/packages/pug-lexer/test/cases/attrs.pug", "start": Object { "column": 7, "line": 32, }, }, "type": "end-attributes", }, Object { "loc": Object { "end": Object { "column": 1, "line": 33, }, "filename": "/packages/pug-lexer/test/cases/attrs.pug", "start": Object { "column": 1, "line": 33, }, }, "type": "newline", }, Object { "loc": Object { "end": Object { "column": 4, "line": 33, }, "filename": "/packages/pug-lexer/test/cases/attrs.pug", "start": Object { "column": 1, "line": 33, }, }, "type": "tag", "val": "foo", }, Object { "loc": Object { "end": Object { "column": 5, "line": 33, }, "filename": "/packages/pug-lexer/test/cases/attrs.pug", "start": Object { "column": 4, "line": 33, }, }, "type": "start-attributes", }, Object { "loc": Object { "end": Object { "column": 8, "line": 33, }, "filename": "/packages/pug-lexer/test/cases/attrs.pug", "start": Object { "column": 5, "line": 33, }, }, "mustEscape": true, "name": "abc", "type": "attribute", "val": true, }, Object { "loc": Object { "end": Object { "column": 6, "line": 34, }, "filename": "/packages/pug-lexer/test/cases/attrs.pug", "start": Object { "column": 3, "line": 34, }, }, "mustEscape": true, "name": "def", "type": "attribute", "val": true, }, Object { "loc": Object { "end": Object { "column": 7, "line": 34, }, "filename": "/packages/pug-lexer/test/cases/attrs.pug", "start": Object { "column": 6, "line": 34, }, }, "type": "end-attributes", }, Object { "loc": Object { "end": Object { "column": 1, "line": 35, }, "filename": "/packages/pug-lexer/test/cases/attrs.pug", "start": Object { "column": 1, "line": 35, }, }, "type": "newline", }, Object { "loc": Object { "end": Object { "column": 4, "line": 35, }, "filename": "/packages/pug-lexer/test/cases/attrs.pug", "start": Object { "column": 1, "line": 35, }, }, "type": "tag", "val": "foo", }, Object { "loc": Object { "end": Object { "column": 5, "line": 35, }, "filename": "/packages/pug-lexer/test/cases/attrs.pug", "start": Object { "column": 4, "line": 35, }, }, "type": "start-attributes", }, Object { "loc": Object { "end": Object { "column": 8, "line": 35, }, "filename": "/packages/pug-lexer/test/cases/attrs.pug", "start": Object { "column": 5, "line": 35, }, }, "mustEscape": true, "name": "abc", "type": "attribute", "val": true, }, Object { "loc": Object { "end": Object { "column": 8, "line": 36, }, "filename": "/packages/pug-lexer/test/cases/attrs.pug", "start": Object { "column": 5, "line": 36, }, }, "mustEscape": true, "name": "def", "type": "attribute", "val": true, }, Object { "loc": Object { "end": Object { "column": 9, "line": 36, }, "filename": "/packages/pug-lexer/test/cases/attrs.pug", "start": Object { "column": 8, "line": 36, }, }, "type": "end-attributes", }, Object { "loc": Object { "end": Object { "column": 1, "line": 38, }, "filename": "/packages/pug-lexer/test/cases/attrs.pug", "start": Object { "column": 1, "line": 38, }, }, "type": "newline", }, Object { "buffer": false, "loc": Object { "end": Object { "column": 41, "line": 38, }, "filename": "/packages/pug-lexer/test/cases/attrs.pug", "start": Object { "column": 1, "line": 38, }, }, "mustEscape": false, "type": "code", "val": "var attrs = {foo: 'bar', bar: ''}", }, Object { "loc": Object { "end": Object { "column": 1, "line": 40, }, "filename": "/packages/pug-lexer/test/cases/attrs.pug", "start": Object { "column": 1, "line": 40, }, }, "type": "newline", }, Object { "loc": Object { "end": Object { "column": 4, "line": 40, }, "filename": "/packages/pug-lexer/test/cases/attrs.pug", "start": Object { "column": 1, "line": 40, }, }, "type": "tag", "val": "div", }, Object { "loc": Object { "end": Object { "column": 22, "line": 40, }, "filename": "/packages/pug-lexer/test/cases/attrs.pug", "start": Object { "column": 4, "line": 40, }, }, "type": "&attributes", "val": "attrs", }, Object { "loc": Object { "end": Object { "column": 1, "line": 42, }, "filename": "/packages/pug-lexer/test/cases/attrs.pug", "start": Object { "column": 1, "line": 42, }, }, "type": "newline", }, Object { "loc": Object { "end": Object { "column": 2, "line": 42, }, "filename": "/packages/pug-lexer/test/cases/attrs.pug", "start": Object { "column": 1, "line": 42, }, }, "type": "tag", "val": "a", }, Object { "loc": Object { "end": Object { "column": 3, "line": 42, }, "filename": "/packages/pug-lexer/test/cases/attrs.pug", "start": Object { "column": 2, "line": 42, }, }, "type": "start-attributes", }, Object { "loc": Object { "end": Object { "column": 12, "line": 42, }, "filename": "/packages/pug-lexer/test/cases/attrs.pug", "start": Object { "column": 3, "line": 42, }, }, "mustEscape": true, "name": "foo", "type": "attribute", "val": "'foo'", }, Object { "loc": Object { "end": Object { "column": 24, "line": 42, }, "filename": "/packages/pug-lexer/test/cases/attrs.pug", "start": Object { "column": 13, "line": 42, }, }, "mustEscape": true, "name": "bar", "type": "attribute", "val": "\\"bar\\"", }, Object { "loc": Object { "end": Object { "column": 25, "line": 42, }, "filename": "/packages/pug-lexer/test/cases/attrs.pug", "start": Object { "column": 24, "line": 42, }, }, "type": "end-attributes", }, Object { "loc": Object { "end": Object { "column": 1, "line": 43, }, "filename": "/packages/pug-lexer/test/cases/attrs.pug", "start": Object { "column": 1, "line": 43, }, }, "type": "newline", }, Object { "loc": Object { "end": Object { "column": 2, "line": 43, }, "filename": "/packages/pug-lexer/test/cases/attrs.pug", "start": Object { "column": 1, "line": 43, }, }, "type": "tag", "val": "a", }, Object { "loc": Object { "end": Object { "column": 3, "line": 43, }, "filename": "/packages/pug-lexer/test/cases/attrs.pug", "start": Object { "column": 2, "line": 43, }, }, "type": "start-attributes", }, Object { "loc": Object { "end": Object { "column": 12, "line": 43, }, "filename": "/packages/pug-lexer/test/cases/attrs.pug", "start": Object { "column": 3, "line": 43, }, }, "mustEscape": true, "name": "foo", "type": "attribute", "val": "'foo'", }, Object { "loc": Object { "end": Object { "column": 24, "line": 43, }, "filename": "/packages/pug-lexer/test/cases/attrs.pug", "start": Object { "column": 13, "line": 43, }, }, "mustEscape": true, "name": "bar", "type": "attribute", "val": "'bar'", }, Object { "loc": Object { "end": Object { "column": 25, "line": 43, }, "filename": "/packages/pug-lexer/test/cases/attrs.pug", "start": Object { "column": 24, "line": 43, }, }, "type": "end-attributes", }, Object { "loc": Object { "end": Object { "column": 1, "line": 44, }, "filename": "/packages/pug-lexer/test/cases/attrs.pug", "start": Object { "column": 1, "line": 44, }, }, "type": "newline", }, Object { "loc": Object { "end": Object { "column": 1, "line": 44, }, "filename": "/packages/pug-lexer/test/cases/attrs.pug", "start": Object { "column": 1, "line": 44, }, }, "type": "eos", }, ] `; exports[`attrs.unescaped.pug 1`] = ` Array [ Object { "loc": Object { "end": Object { "column": 7, "line": 1, }, "filename": "/packages/pug-lexer/test/cases/attrs.unescaped.pug", "start": Object { "column": 1, "line": 1, }, }, "type": "tag", "val": "script", }, Object { "loc": Object { "end": Object { "column": 8, "line": 1, }, "filename": "/packages/pug-lexer/test/cases/attrs.unescaped.pug", "start": Object { "column": 7, "line": 1, }, }, "type": "start-attributes", }, Object { "loc": Object { "end": Object { "column": 30, "line": 1, }, "filename": "/packages/pug-lexer/test/cases/attrs.unescaped.pug", "start": Object { "column": 8, "line": 1, }, }, "mustEscape": true, "name": "type", "type": "attribute", "val": "'text/x-template'", }, Object { "loc": Object { "end": Object { "column": 31, "line": 1, }, "filename": "/packages/pug-lexer/test/cases/attrs.unescaped.pug", "start": Object { "column": 30, "line": 1, }, }, "type": "end-attributes", }, Object { "loc": Object { "end": Object { "column": 3, "line": 2, }, "filename": "/packages/pug-lexer/test/cases/attrs.unescaped.pug", "start": Object { "column": 1, "line": 2, }, }, "type": "indent", "val": 2, }, Object { "loc": Object { "end": Object { "column": 6, "line": 2, }, "filename": "/packages/pug-lexer/test/cases/attrs.unescaped.pug", "start": Object { "column": 3, "line": 2, }, }, "type": "tag", "val": "div", }, Object { "loc": Object { "end": Object { "column": 7, "line": 2, }, "filename": "/packages/pug-lexer/test/cases/attrs.unescaped.pug", "start": Object { "column": 6, "line": 2, }, }, "type": "start-attributes", }, Object { "loc": Object { "end": Object { "column": 32, "line": 2, }, "filename": "/packages/pug-lexer/test/cases/attrs.unescaped.pug", "start": Object { "column": 7, "line": 2, }, }, "mustEscape": false, "name": "id", "type": "attribute", "val": "'user-<%= user.id %>'", }, Object { "loc": Object { "end": Object { "column": 33, "line": 2, }, "filename": "/packages/pug-lexer/test/cases/attrs.unescaped.pug", "start": Object { "column": 32, "line": 2, }, }, "type": "end-attributes", }, Object { "loc": Object { "end": Object { "column": 5, "line": 3, }, "filename": "/packages/pug-lexer/test/cases/attrs.unescaped.pug", "start": Object { "column": 1, "line": 3, }, }, "type": "indent", "val": 4, }, Object { "loc": Object { "end": Object { "column": 7, "line": 3, }, "filename": "/packages/pug-lexer/test/cases/attrs.unescaped.pug", "start": Object { "column": 5, "line": 3, }, }, "type": "tag", "val": "h1", }, Object { "loc": Object { "end": Object { "column": 25, "line": 3, }, "filename": "/packages/pug-lexer/test/cases/attrs.unescaped.pug", "start": Object { "column": 8, "line": 3, }, }, "type": "text", "val": "<%= user.title %>", }, Object { "loc": Object { "end": Object { "column": 25, "line": 3, }, "filename": "/packages/pug-lexer/test/cases/attrs.unescaped.pug", "start": Object { "column": 25, "line": 3, }, }, "type": "outdent", }, Object { "loc": Object { "end": Object { "column": 25, "line": 3, }, "filename": "/packages/pug-lexer/test/cases/attrs.unescaped.pug", "start": Object { "column": 25, "line": 3, }, }, "type": "outdent", }, Object { "loc": Object { "end": Object { "column": 25, "line": 3, }, "filename": "/packages/pug-lexer/test/cases/attrs.unescaped.pug", "start": Object { "column": 25, "line": 3, }, }, "type": "eos", }, ] `; exports[`attrs-data.pug 1`] = ` Array [ Object { "buffer": false, "loc": Object { "end": Object { "column": 30, "line": 1, }, "filename": "/packages/pug-lexer/test/cases/attrs-data.pug", "start": Object { "column": 1, "line": 1, }, }, "mustEscape": false, "type": "code", "val": "var user = { name: 'tobi' }", }, Object { "loc": Object { "end": Object { "column": 1, "line": 2, }, "filename": "/packages/pug-lexer/test/cases/attrs-data.pug", "start": Object { "column": 1, "line": 2, }, }, "type": "newline", }, Object { "loc": Object { "end": Object { "column": 4, "line": 2, }, "filename": "/packages/pug-lexer/test/cases/attrs-data.pug", "start": Object { "column": 1, "line": 2, }, }, "type": "tag", "val": "foo", }, Object { "loc": Object { "end": Object { "column": 5, "line": 2, }, "filename": "/packages/pug-lexer/test/cases/attrs-data.pug", "start": Object { "column": 4, "line": 2, }, }, "type": "start-attributes", }, Object { "loc": Object { "end": Object { "column": 19, "line": 2, }, "filename": "/packages/pug-lexer/test/cases/attrs-data.pug", "start": Object { "column": 5, "line": 2, }, }, "mustEscape": true, "name": "data-user", "type": "attribute", "val": "user", }, Object { "loc": Object { "end": Object { "column": 20, "line": 2, }, "filename": "/packages/pug-lexer/test/cases/attrs-data.pug", "start": Object { "column": 19, "line": 2, }, }, "type": "end-attributes", }, Object { "loc": Object { "end": Object { "column": 1, "line": 3, }, "filename": "/packages/pug-lexer/test/cases/attrs-data.pug", "start": Object { "column": 1, "line": 3, }, }, "type": "newline", }, Object { "loc": Object { "end": Object { "column": 4, "line": 3, }, "filename": "/packages/pug-lexer/test/cases/attrs-data.pug", "start": Object { "column": 1, "line": 3, }, }, "type": "tag", "val": "foo", }, Object { "loc": Object { "end": Object { "column": 5, "line": 3, }, "filename": "/packages/pug-lexer/test/cases/attrs-data.pug", "start": Object { "column": 4, "line": 3, }, }, "type": "start-attributes", }, Object { "loc": Object { "end": Object { "column": 23, "line": 3, }, "filename": "/packages/pug-lexer/test/cases/attrs-data.pug", "start": Object { "column": 5, "line": 3, }, }, "mustEscape": true, "name": "data-items", "type": "attribute", "val": "[1,2,3]", }, Object { "loc": Object { "end": Object { "column": 24, "line": 3, }, "filename": "/packages/pug-lexer/test/cases/attrs-data.pug", "start": Object { "column": 23, "line": 3, }, }, "type": "end-attributes", }, Object { "loc": Object { "end": Object { "column": 1, "line": 4, }, "filename": "/packages/pug-lexer/test/cases/attrs-data.pug", "start": Object { "column": 1, "line": 4, }, }, "type": "newline", }, Object { "loc": Object { "end": Object { "column": 4, "line": 4, }, "filename": "/packages/pug-lexer/test/cases/attrs-data.pug", "start": Object { "column": 1, "line": 4, }, }, "type": "tag", "val": "foo", }, Object { "loc": Object { "end": Object { "column": 5, "line": 4, }, "filename": "/packages/pug-lexer/test/cases/attrs-data.pug", "start": Object { "column": 4, "line": 4, }, }, "type": "start-attributes", }, Object { "loc": Object { "end": Object { "column": 25, "line": 4, }, "filename": "/packages/pug-lexer/test/cases/attrs-data.pug", "start": Object { "column": 5, "line": 4, }, }, "mustEscape": true, "name": "data-username", "type": "attribute", "val": "'tobi'", }, Object { "loc": Object { "end": Object { "column": 26, "line": 4, }, "filename": "/packages/pug-lexer/test/cases/attrs-data.pug", "start": Object { "column": 25, "line": 4, }, }, "type": "end-attributes", }, Object { "loc": Object { "end": Object { "column": 1, "line": 5, }, "filename": "/packages/pug-lexer/test/cases/attrs-data.pug", "start": Object { "column": 1, "line": 5, }, }, "type": "newline", }, Object { "loc": Object { "end": Object { "column": 4, "line": 5, }, "filename": "/packages/pug-lexer/test/cases/attrs-data.pug", "start": Object { "column": 1, "line": 5, }, }, "type": "tag", "val": "foo", }, Object { "loc": Object { "end": Object { "column": 5, "line": 5, }, "filename": "/packages/pug-lexer/test/cases/attrs-data.pug", "start": Object { "column": 4, "line": 5, }, }, "type": "start-attributes", }, Object { "loc": Object { "end": Object { "column": 42, "line": 5, }, "filename": "/packages/pug-lexer/test/cases/attrs-data.pug", "start": Object { "column": 5, "line": 5, }, }, "mustEscape": true, "name": "data-escaped", "type": "attribute", "val": "{message: \\"Let's rock!\\"}", }, Object { "loc": Object { "end": Object { "column": 43, "line": 5, }, "filename": "/packages/pug-lexer/test/cases/attrs-data.pug", "start": Object { "column": 42, "line": 5, }, }, "type": "end-attributes", }, Object { "loc": Object { "end": Object { "column": 1, "line": 6, }, "filename": "/packages/pug-lexer/test/cases/attrs-data.pug", "start": Object { "column": 1, "line": 6, }, }, "type": "newline", }, Object { "loc": Object { "end": Object { "column": 4, "line": 6, }, "filename": "/packages/pug-lexer/test/cases/attrs-data.pug", "start": Object { "column": 1, "line": 6, }, }, "type": "tag", "val": "foo", }, Object { "loc": Object { "end": Object { "column": 5, "line": 6, }, "filename": "/packages/pug-lexer/test/cases/attrs-data.pug", "start": Object { "column": 4, "line": 6, }, }, "type": "start-attributes", }, Object { "loc": Object { "end": Object { "column": 60, "line": 6, }, "filename": "/packages/pug-lexer/test/cases/attrs-data.pug", "start": Object { "column": 5, "line": 6, }, }, "mustEscape": true, "name": "data-ampersand", "type": "attribute", "val": "{message: \\"a quote: " this & that\\"}", }, Object { "loc": Object { "end": Object { "column": 61, "line": 6, }, "filename": "/packages/pug-lexer/test/cases/attrs-data.pug", "start": Object { "column": 60, "line": 6, }, }, "type": "end-attributes", }, Object { "loc": Object { "end": Object { "column": 1, "line": 7, }, "filename": "/packages/pug-lexer/test/cases/attrs-data.pug", "start": Object { "column": 1, "line": 7, }, }, "type": "newline", }, Object { "loc": Object { "end": Object { "column": 4, "line": 7, }, "filename": "/packages/pug-lexer/test/cases/attrs-data.pug", "start": Object { "column": 1, "line": 7, }, }, "type": "tag", "val": "foo", }, Object { "loc": Object { "end": Object { "column": 5, "line": 7, }, "filename": "/packages/pug-lexer/test/cases/attrs-data.pug", "start": Object { "column": 4, "line": 7, }, }, "type": "start-attributes", }, Object { "loc": Object { "end": Object { "column": 26, "line": 7, }, "filename": "/packages/pug-lexer/test/cases/attrs-data.pug", "start": Object { "column": 5, "line": 7, }, }, "mustEscape": true, "name": "data-epoc", "type": "attribute", "val": "new Date(0)", }, Object { "loc": Object { "end": Object { "column": 27, "line": 7, }, "filename": "/packages/pug-lexer/test/cases/attrs-data.pug", "start": Object { "column": 26, "line": 7, }, }, "type": "end-attributes", }, Object { "loc": Object { "end": Object { "column": 1, "line": 8, }, "filename": "/packages/pug-lexer/test/cases/attrs-data.pug", "start": Object { "column": 1, "line": 8, }, }, "type": "newline", }, Object { "loc": Object { "end": Object { "column": 1, "line": 8, }, "filename": "/packages/pug-lexer/test/cases/attrs-data.pug", "start": Object { "column": 1, "line": 8, }, }, "type": "eos", }, ] `; exports[`basic.pug 1`] = ` Array [ Object { "loc": Object { "end": Object { "column": 5, "line": 1, }, "filename": "/packages/pug-lexer/test/cases/basic.pug", "start": Object { "column": 1, "line": 1, }, }, "type": "tag", "val": "html", }, Object { "loc": Object { "end": Object { "column": 3, "line": 2, }, "filename": "/packages/pug-lexer/test/cases/basic.pug", "start": Object { "column": 1, "line": 2, }, }, "type": "indent", "val": 2, }, Object { "loc": Object { "end": Object { "column": 7, "line": 2, }, "filename": "/packages/pug-lexer/test/cases/basic.pug", "start": Object { "column": 3, "line": 2, }, }, "type": "tag", "val": "body", }, Object { "loc": Object { "end": Object { "column": 5, "line": 3, }, "filename": "/packages/pug-lexer/test/cases/basic.pug", "start": Object { "column": 1, "line": 3, }, }, "type": "indent", "val": 4, }, Object { "loc": Object { "end": Object { "column": 7, "line": 3, }, "filename": "/packages/pug-lexer/test/cases/basic.pug", "start": Object { "column": 5, "line": 3, }, }, "type": "tag", "val": "h1", }, Object { "loc": Object { "end": Object { "column": 13, "line": 3, }, "filename": "/packages/pug-lexer/test/cases/basic.pug", "start": Object { "column": 8, "line": 3, }, }, "type": "text", "val": "Title", }, Object { "loc": Object { "end": Object { "column": 13, "line": 3, }, "filename": "/packages/pug-lexer/test/cases/basic.pug", "start": Object { "column": 13, "line": 3, }, }, "type": "outdent", }, Object { "loc": Object { "end": Object { "column": 13, "line": 3, }, "filename": "/packages/pug-lexer/test/cases/basic.pug", "start": Object { "column": 13, "line": 3, }, }, "type": "outdent", }, Object { "loc": Object { "end": Object { "column": 13, "line": 3, }, "filename": "/packages/pug-lexer/test/cases/basic.pug", "start": Object { "column": 13, "line": 3, }, }, "type": "eos", }, ] `; exports[`blanks.pug 1`] = ` Array [ Object { "loc": Object { "end": Object { "column": 1, "line": 3, }, "filename": "/packages/pug-lexer/test/cases/blanks.pug", "start": Object { "column": 1, "line": 3, }, }, "type": "newline", }, Object { "loc": Object { "end": Object { "column": 3, "line": 3, }, "filename": "/packages/pug-lexer/test/cases/blanks.pug", "start": Object { "column": 1, "line": 3, }, }, "type": "tag", "val": "ul", }, Object { "loc": Object { "end": Object { "column": 3, "line": 4, }, "filename": "/packages/pug-lexer/test/cases/blanks.pug", "start": Object { "column": 1, "line": 4, }, }, "type": "indent", "val": 2, }, Object { "loc": Object { "end": Object { "column": 5, "line": 4, }, "filename": "/packages/pug-lexer/test/cases/blanks.pug", "start": Object { "column": 3, "line": 4, }, }, "type": "tag", "val": "li", }, Object { "loc": Object { "end": Object { "column": 9, "line": 4, }, "filename": "/packages/pug-lexer/test/cases/blanks.pug", "start": Object { "column": 6, "line": 4, }, }, "type": "text", "val": "foo", }, Object { "loc": Object { "end": Object { "column": 3, "line": 6, }, "filename": "/packages/pug-lexer/test/cases/blanks.pug", "start": Object { "column": 1, "line": 6, }, }, "type": "newline", }, Object { "loc": Object { "end": Object { "column": 5, "line": 6, }, "filename": "/packages/pug-lexer/test/cases/blanks.pug", "start": Object { "column": 3, "line": 6, }, }, "type": "tag", "val": "li", }, Object { "loc": Object { "end": Object { "column": 9, "line": 6, }, "filename": "/packages/pug-lexer/test/cases/blanks.pug", "start": Object { "column": 6, "line": 6, }, }, "type": "text", "val": "bar", }, Object { "loc": Object { "end": Object { "column": 3, "line": 8, }, "filename": "/packages/pug-lexer/test/cases/blanks.pug", "start": Object { "column": 1, "line": 8, }, }, "type": "newline", }, Object { "loc": Object { "end": Object { "column": 5, "line": 8, }, "filename": "/packages/pug-lexer/test/cases/blanks.pug", "start": Object { "column": 3, "line": 8, }, }, "type": "tag", "val": "li", }, Object { "loc": Object { "end": Object { "column": 9, "line": 8, }, "filename": "/packages/pug-lexer/test/cases/blanks.pug", "start": Object { "column": 6, "line": 8, }, }, "type": "text", "val": "baz", }, Object { "loc": Object { "end": Object { "column": 1, "line": 9, }, "filename": "/packages/pug-lexer/test/cases/blanks.pug", "start": Object { "column": 1, "line": 9, }, }, "type": "outdent", }, Object { "loc": Object { "end": Object { "column": 1, "line": 9, }, "filename": "/packages/pug-lexer/test/cases/blanks.pug", "start": Object { "column": 1, "line": 9, }, }, "type": "eos", }, ] `; exports[`block-code.pug 1`] = ` Array [ Object { "loc": Object { "end": Object { "column": 2, "line": 1, }, "filename": "/packages/pug-lexer/test/cases/block-code.pug", "start": Object { "column": 1, "line": 1, }, }, "type": "blockcode", }, Object { "loc": Object { "end": Object { "column": 2, "line": 1, }, "filename": "/packages/pug-lexer/test/cases/block-code.pug", "start": Object { "column": 2, "line": 1, }, }, "type": "start-pipeless-text", }, Object { "loc": Object { "end": Object { "column": 32, "line": 2, }, "filename": "/packages/pug-lexer/test/cases/block-code.pug", "start": Object { "column": 3, "line": 2, }, }, "type": "text", "val": "list = [\\"uno\\", \\"dos\\", \\"tres\\",", }, Object { "loc": Object { "end": Object { "column": 3, "line": 3, }, "filename": "/packages/pug-lexer/test/cases/block-code.pug", "start": Object { "column": 1, "line": 3, }, }, "type": "newline", }, Object { "loc": Object { "end": Object { "column": 38, "line": 3, }, "filename": "/packages/pug-lexer/test/cases/block-code.pug", "start": Object { "column": 3, "line": 3, }, }, "type": "text", "val": " \\"cuatro\\", \\"cinco\\", \\"seis\\"];", }, Object { "loc": Object { "end": Object { "column": 38, "line": 3, }, "filename": "/packages/pug-lexer/test/cases/block-code.pug", "start": Object { "column": 38, "line": 3, }, }, "type": "end-pipeless-text", }, Object { "loc": Object { "end": Object { "column": 1, "line": 4, }, "filename": "/packages/pug-lexer/test/cases/block-code.pug", "start": Object { "column": 1, "line": 4, }, }, "type": "newline", }, Object { "buffer": false, "loc": Object { "end": Object { "column": 70, "line": 4, }, "filename": "/packages/pug-lexer/test/cases/block-code.pug", "start": Object { "column": 1, "line": 4, }, }, "type": "comment", "val": " Without a block, the element is accepted and no code is generated", }, Object { "loc": Object { "end": Object { "column": 1, "line": 5, }, "filename": "/packages/pug-lexer/test/cases/block-code.pug", "start": Object { "column": 1, "line": 5, }, }, "type": "newline", }, Object { "loc": Object { "end": Object { "column": 2, "line": 5, }, "filename": "/packages/pug-lexer/test/cases/block-code.pug", "start": Object { "column": 1, "line": 5, }, }, "type": "blockcode", }, Object { "loc": Object { "end": Object { "column": 1, "line": 6, }, "filename": "/packages/pug-lexer/test/cases/block-code.pug", "start": Object { "column": 1, "line": 6, }, }, "type": "newline", }, Object { "code": "list", "key": null, "loc": Object { "end": Object { "column": 18, "line": 6, }, "filename": "/packages/pug-lexer/test/cases/block-code.pug", "start": Object { "column": 1, "line": 6, }, }, "type": "each", "val": "item", }, Object { "loc": Object { "end": Object { "column": 3, "line": 7, }, "filename": "/packages/pug-lexer/test/cases/block-code.pug", "start": Object { "column": 1, "line": 7, }, }, "type": "indent", "val": 2, }, Object { "loc": Object { "end": Object { "column": 4, "line": 7, }, "filename": "/packages/pug-lexer/test/cases/block-code.pug", "start": Object { "column": 3, "line": 7, }, }, "type": "blockcode", }, Object { "loc": Object { "end": Object { "column": 4, "line": 7, }, "filename": "/packages/pug-lexer/test/cases/block-code.pug", "start": Object { "column": 4, "line": 7, }, }, "type": "start-pipeless-text", }, Object { "loc": Object { "end": Object { "column": 28, "line": 8, }, "filename": "/packages/pug-lexer/test/cases/block-code.pug", "start": Object { "column": 5, "line": 8, }, }, "type": "text", "val": "string = item.charAt(0)", }, Object { "loc": Object { "end": Object { "column": 5, "line": 9, }, "filename": "/packages/pug-lexer/test/cases/block-code.pug", "start": Object { "column": 1, "line": 9, }, }, "type": "newline", }, Object { "loc": Object { "end": Object { "column": 5, "line": 9, }, "filename": "/packages/pug-lexer/test/cases/block-code.pug", "start": Object { "column": 5, "line": 9, }, }, "type": "text", "val": "", }, Object { "loc": Object { "end": Object { "column": 5, "line": 10, }, "filename": "/packages/pug-lexer/test/cases/block-code.pug", "start": Object { "column": 1, "line": 10, }, }, "type": "newline", }, Object { "loc": Object { "end": Object { "column": 23, "line": 10, }, "filename": "/packages/pug-lexer/test/cases/block-code.pug", "start": Object { "column": 5, "line": 10, }, }, "type": "text", "val": " .toUpperCase() +", }, Object { "loc": Object { "end": Object { "column": 5, "line": 11, }, "filename": "/packages/pug-lexer/test/cases/block-code.pug", "start": Object { "column": 1, "line": 11, }, }, "type": "newline", }, Object { "loc": Object { "end": Object { "column": 19, "line": 11, }, "filename": "/packages/pug-lexer/test/cases/block-code.pug", "start": Object { "column": 5, "line": 11, }, }, "type": "text", "val": "item.slice(1);", }, Object { "loc": Object { "end": Object { "column": 19, "line": 11, }, "filename": "/packages/pug-lexer/test/cases/block-code.pug", "start": Object { "column": 19, "line": 11, }, }, "type": "end-pipeless-text", }, Object { "loc": Object { "end": Object { "column": 3, "line": 12, }, "filename": "/packages/pug-lexer/test/cases/block-code.pug", "start": Object { "column": 1, "line": 12, }, }, "type": "newline", }, Object { "loc": Object { "end": Object { "column": 5, "line": 12, }, "filename": "/packages/pug-lexer/test/cases/block-code.pug", "start": Object { "column": 3, "line": 12, }, }, "type": "tag", "val": "li", }, Object { "buffer": true, "loc": Object { "end": Object { "column": 13, "line": 12, }, "filename": "/packages/pug-lexer/test/cases/block-code.pug", "start": Object { "column": 5, "line": 12, }, }, "mustEscape": true, "type": "code", "val": "string", }, Object { "loc": Object { "end": Object { "column": 1, "line": 13, }, "filename": "/packages/pug-lexer/test/cases/block-code.pug", "start": Object { "column": 1, "line": 13, }, }, "type": "outdent", }, Object { "loc": Object { "end": Object { "column": 1, "line": 13, }, "filename": "/packages/pug-lexer/test/cases/block-code.pug", "start": Object { "column": 1, "line": 13, }, }, "type": "eos", }, ] `; exports[`block-expansion.pug 1`] = ` Array [ Object { "loc": Object { "end": Object { "column": 3, "line": 1, }, "filename": "/packages/pug-lexer/test/cases/block-expansion.pug", "start": Object { "column": 1, "line": 1, }, }, "type": "tag", "val": "ul", }, Object { "loc": Object { "end": Object { "column": 3, "line": 2, }, "filename": "/packages/pug-lexer/test/cases/block-expansion.pug", "start": Object { "column": 1, "line": 2, }, }, "type": "indent", "val": 2, }, Object { "loc": Object { "end": Object { "column": 5, "line": 2, }, "filename": "/packages/pug-lexer/test/cases/block-expansion.pug", "start": Object { "column": 3, "line": 2, }, }, "type": "tag", "val": "li", }, Object { "loc": Object { "end": Object { "column": 7, "line": 2, }, "filename": "/packages/pug-lexer/test/cases/block-expansion.pug", "start": Object { "column": 5, "line": 2, }, }, "type": ":", }, Object { "loc": Object { "end": Object { "column": 8, "line": 2, }, "filename": "/packages/pug-lexer/test/cases/block-expansion.pug", "start": Object { "column": 7, "line": 2, }, }, "type": "tag", "val": "a", }, Object { "loc": Object { "end": Object { "column": 9, "line": 2, }, "filename": "/packages/pug-lexer/test/cases/block-expansion.pug", "start": Object { "column": 8, "line": 2, }, }, "type": "start-attributes", }, Object { "loc": Object { "end": Object { "column": 17, "line": 2, }, "filename": "/packages/pug-lexer/test/cases/block-expansion.pug", "start": Object { "column": 9, "line": 2, }, }, "mustEscape": true, "name": "href", "type": "attribute", "val": "'#'", }, Object { "loc": Object { "end": Object { "column": 18, "line": 2, }, "filename": "/packages/pug-lexer/test/cases/block-expansion.pug", "start": Object { "column": 17, "line": 2, }, }, "type": "end-attributes", }, Object { "loc": Object { "end": Object { "column": 22, "line": 2, }, "filename": "/packages/pug-lexer/test/cases/block-expansion.pug", "start": Object { "column": 19, "line": 2, }, }, "type": "text", "val": "foo", }, Object { "loc": Object { "end": Object { "column": 3, "line": 3, }, "filename": "/packages/pug-lexer/test/cases/block-expansion.pug", "start": Object { "column": 1, "line": 3, }, }, "type": "newline", }, Object { "loc": Object { "end": Object { "column": 5, "line": 3, }, "filename": "/packages/pug-lexer/test/cases/block-expansion.pug", "start": Object { "column": 3, "line": 3, }, }, "type": "tag", "val": "li", }, Object { "loc": Object { "end": Object { "column": 7, "line": 3, }, "filename": "/packages/pug-lexer/test/cases/block-expansion.pug", "start": Object { "column": 5, "line": 3, }, }, "type": ":", }, Object { "loc": Object { "end": Object { "column": 8, "line": 3, }, "filename": "/packages/pug-lexer/test/cases/block-expansion.pug", "start": Object { "column": 7, "line": 3, }, }, "type": "tag", "val": "a", }, Object { "loc": Object { "end": Object { "column": 9, "line": 3, }, "filename": "/packages/pug-lexer/test/cases/block-expansion.pug", "start": Object { "column": 8, "line": 3, }, }, "type": "start-attributes", }, Object { "loc": Object { "end": Object { "column": 17, "line": 3, }, "filename": "/packages/pug-lexer/test/cases/block-expansion.pug", "start": Object { "column": 9, "line": 3, }, }, "mustEscape": true, "name": "href", "type": "attribute", "val": "'#'", }, Object { "loc": Object { "end": Object { "column": 18, "line": 3, }, "filename": "/packages/pug-lexer/test/cases/block-expansion.pug", "start": Object { "column": 17, "line": 3, }, }, "type": "end-attributes", }, Object { "loc": Object { "end": Object { "column": 22, "line": 3, }, "filename": "/packages/pug-lexer/test/cases/block-expansion.pug", "start": Object { "column": 19, "line": 3, }, }, "type": "text", "val": "bar", }, Object { "loc": Object { "end": Object { "column": 1, "line": 5, }, "filename": "/packages/pug-lexer/test/cases/block-expansion.pug", "start": Object { "column": 1, "line": 5, }, }, "type": "outdent", }, Object { "loc": Object { "end": Object { "column": 2, "line": 5, }, "filename": "/packages/pug-lexer/test/cases/block-expansion.pug", "start": Object { "column": 1, "line": 5, }, }, "type": "tag", "val": "p", }, Object { "loc": Object { "end": Object { "column": 6, "line": 5, }, "filename": "/packages/pug-lexer/test/cases/block-expansion.pug", "start": Object { "column": 3, "line": 5, }, }, "type": "text", "val": "baz", }, Object { "loc": Object { "end": Object { "column": 6, "line": 5, }, "filename": "/packages/pug-lexer/test/cases/block-expansion.pug", "start": Object { "column": 6, "line": 5, }, }, "type": "eos", }, ] `; exports[`block-expansion.shorthands.pug 1`] = ` Array [ Object { "loc": Object { "end": Object { "column": 3, "line": 1, }, "filename": "/packages/pug-lexer/test/cases/block-expansion.shorthands.pug", "start": Object { "column": 1, "line": 1, }, }, "type": "tag", "val": "ul", }, Object { "loc": Object { "end": Object { "column": 3, "line": 2, }, "filename": "/packages/pug-lexer/test/cases/block-expansion.shorthands.pug", "start": Object { "column": 1, "line": 2, }, }, "type": "indent", "val": 2, }, Object { "loc": Object { "end": Object { "column": 5, "line": 2, }, "filename": "/packages/pug-lexer/test/cases/block-expansion.shorthands.pug", "start": Object { "column": 3, "line": 2, }, }, "type": "tag", "val": "li", }, Object { "loc": Object { "end": Object { "column": 15, "line": 2, }, "filename": "/packages/pug-lexer/test/cases/block-expansion.shorthands.pug", "start": Object { "column": 5, "line": 2, }, }, "type": "class", "val": "list-item", }, Object { "loc": Object { "end": Object { "column": 17, "line": 2, }, "filename": "/packages/pug-lexer/test/cases/block-expansion.shorthands.pug", "start": Object { "column": 15, "line": 2, }, }, "type": ":", }, Object { "loc": Object { "end": Object { "column": 21, "line": 2, }, "filename": "/packages/pug-lexer/test/cases/block-expansion.shorthands.pug", "start": Object { "column": 17, "line": 2, }, }, "type": "class", "val": "foo", }, Object { "loc": Object { "end": Object { "column": 23, "line": 2, }, "filename": "/packages/pug-lexer/test/cases/block-expansion.shorthands.pug", "start": Object { "column": 21, "line": 2, }, }, "type": ":", }, Object { "loc": Object { "end": Object { "column": 27, "line": 2, }, "filename": "/packages/pug-lexer/test/cases/block-expansion.shorthands.pug", "start": Object { "column": 23, "line": 2, }, }, "type": "id", "val": "bar", }, Object { "loc": Object { "end": Object { "column": 31, "line": 2, }, "filename": "/packages/pug-lexer/test/cases/block-expansion.shorthands.pug", "start": Object { "column": 28, "line": 2, }, }, "type": "text", "val": "baz", }, Object { "loc": Object { "end": Object { "column": 31, "line": 2, }, "filename": "/packages/pug-lexer/test/cases/block-expansion.shorthands.pug", "start": Object { "column": 31, "line": 2, }, }, "type": "outdent", }, Object { "loc": Object { "end": Object { "column": 31, "line": 2, }, "filename": "/packages/pug-lexer/test/cases/block-expansion.shorthands.pug", "start": Object { "column": 31, "line": 2, }, }, "type": "eos", }, ] `; exports[`blockquote.pug 1`] = ` Array [ Object { "loc": Object { "end": Object { "column": 7, "line": 1, }, "filename": "/packages/pug-lexer/test/cases/blockquote.pug", "start": Object { "column": 1, "line": 1, }, }, "type": "tag", "val": "figure", }, Object { "loc": Object { "end": Object { "column": 3, "line": 2, }, "filename": "/packages/pug-lexer/test/cases/blockquote.pug", "start": Object { "column": 1, "line": 2, }, }, "type": "indent", "val": 2, }, Object { "loc": Object { "end": Object { "column": 13, "line": 2, }, "filename": "/packages/pug-lexer/test/cases/blockquote.pug", "start": Object { "column": 3, "line": 2, }, }, "type": "tag", "val": "blockquote", }, Object { "loc": Object { "end": Object { "column": 5, "line": 3, }, "filename": "/packages/pug-lexer/test/cases/blockquote.pug", "start": Object { "column": 1, "line": 3, }, }, "type": "indent", "val": 4, }, Object { "loc": Object { "end": Object { "column": 123, "line": 3, }, "filename": "/packages/pug-lexer/test/cases/blockquote.pug", "start": Object { "column": 7, "line": 3, }, }, "type": "text", "val": "Try to define yourself by what you do, and you’ll burnout every time. You are. That is enough. I rest in that.", }, Object { "loc": Object { "end": Object { "column": 3, "line": 4, }, "filename": "/packages/pug-lexer/test/cases/blockquote.pug", "start": Object { "column": 1, "line": 4, }, }, "type": "outdent", }, Object { "loc": Object { "end": Object { "column": 13, "line": 4, }, "filename": "/packages/pug-lexer/test/cases/blockquote.pug", "start": Object { "column": 3, "line": 4, }, }, "type": "tag", "val": "figcaption", }, Object { "loc": Object { "end": Object { "column": 47, "line": 4, }, "filename": "/packages/pug-lexer/test/cases/blockquote.pug", "start": Object { "column": 14, "line": 4, }, }, "type": "text", "val": "from @thefray at 1:43pm on May 10", }, Object { "loc": Object { "end": Object { "column": 47, "line": 4, }, "filename": "/packages/pug-lexer/test/cases/blockquote.pug", "start": Object { "column": 47, "line": 4, }, }, "type": "outdent", }, Object { "loc": Object { "end": Object { "column": 47, "line": 4, }, "filename": "/packages/pug-lexer/test/cases/blockquote.pug", "start": Object { "column": 47, "line": 4, }, }, "type": "eos", }, ] `; exports[`blocks-in-blocks.pug 1`] = ` Array [ Object { "loc": Object { "end": Object { "column": 8, "line": 1, }, "filename": "/packages/pug-lexer/test/cases/blocks-in-blocks.pug", "start": Object { "column": 1, "line": 1, }, }, "type": "extends", }, Object { "loc": Object { "end": Object { "column": 48, "line": 1, }, "filename": "/packages/pug-lexer/test/cases/blocks-in-blocks.pug", "start": Object { "column": 9, "line": 1, }, }, "type": "path", "val": "./auxiliary/blocks-in-blocks-layout.pug", }, Object { "loc": Object { "end": Object { "column": 1, "line": 3, }, "filename": "/packages/pug-lexer/test/cases/blocks-in-blocks.pug", "start": Object { "column": 1, "line": 3, }, }, "type": "newline", }, Object { "loc": Object { "end": Object { "column": 11, "line": 3, }, "filename": "/packages/pug-lexer/test/cases/blocks-in-blocks.pug", "start": Object { "column": 1, "line": 3, }, }, "mode": "replace", "type": "block", "val": "body", }, Object { "loc": Object { "end": Object { "column": 3, "line": 4, }, "filename": "/packages/pug-lexer/test/cases/blocks-in-blocks.pug", "start": Object { "column": 1, "line": 4, }, }, "type": "indent", "val": 2, }, Object { "loc": Object { "end": Object { "column": 5, "line": 4, }, "filename": "/packages/pug-lexer/test/cases/blocks-in-blocks.pug", "start": Object { "column": 3, "line": 4, }, }, "type": "tag", "val": "h1", }, Object { "loc": Object { "end": Object { "column": 12, "line": 4, }, "filename": "/packages/pug-lexer/test/cases/blocks-in-blocks.pug", "start": Object { "column": 6, "line": 4, }, }, "type": "text", "val": "Page 2", }, Object { "loc": Object { "end": Object { "column": 1, "line": 5, }, "filename": "/packages/pug-lexer/test/cases/blocks-in-blocks.pug", "start": Object { "column": 1, "line": 5, }, }, "type": "outdent", }, Object { "loc": Object { "end": Object { "column": 1, "line": 5, }, "filename": "/packages/pug-lexer/test/cases/blocks-in-blocks.pug", "start": Object { "column": 1, "line": 5, }, }, "type": "eos", }, ] `; exports[`blocks-in-if.pug 1`] = ` Array [ Object { "buffer": false, "loc": Object { "end": Object { "column": 49, "line": 1, }, "filename": "/packages/pug-lexer/test/cases/blocks-in-if.pug", "start": Object { "column": 1, "line": 1, }, }, "type": "comment", "val": " see https://github.com/pugjs/pug/issues/1589", }, Object { "loc": Object { "end": Object { "column": 1, "line": 3, }, "filename": "/packages/pug-lexer/test/cases/blocks-in-if.pug", "start": Object { "column": 1, "line": 3, }, }, "type": "newline", }, Object { "buffer": false, "loc": Object { "end": Object { "column": 17, "line": 3, }, "filename": "/packages/pug-lexer/test/cases/blocks-in-if.pug", "start": Object { "column": 1, "line": 3, }, }, "mustEscape": false, "type": "code", "val": "var ajax = true", }, Object { "loc": Object { "end": Object { "column": 1, "line": 5, }, "filename": "/packages/pug-lexer/test/cases/blocks-in-if.pug", "start": Object { "column": 1, "line": 5, }, }, "type": "newline", }, Object { "buffer": false, "loc": Object { "end": Object { "column": 12, "line": 5, }, "filename": "/packages/pug-lexer/test/cases/blocks-in-if.pug", "start": Object { "column": 1, "line": 5, }, }, "mustEscape": false, "type": "code", "val": "if( ajax )", }, Object { "loc": Object { "end": Object { "column": 5, "line": 6, }, "filename": "/packages/pug-lexer/test/cases/blocks-in-if.pug", "start": Object { "column": 1, "line": 6, }, }, "type": "indent", "val": 4, }, Object { "buffer": false, "loc": Object { "end": Object { "column": 46, "line": 6, }, "filename": "/packages/pug-lexer/test/cases/blocks-in-if.pug", "start": Object { "column": 5, "line": 6, }, }, "type": "comment", "val": " return only contents if ajax requests", }, Object { "loc": Object { "end": Object { "column": 5, "line": 7, }, "filename": "/packages/pug-lexer/test/cases/blocks-in-if.pug", "start": Object { "column": 1, "line": 7, }, }, "type": "newline", }, Object { "loc": Object { "end": Object { "column": 19, "line": 7, }, "filename": "/packages/pug-lexer/test/cases/blocks-in-if.pug", "start": Object { "column": 5, "line": 7, }, }, "mode": "replace", "type": "block", "val": "contents", }, Object { "loc": Object { "end": Object { "column": 9, "line": 8, }, "filename": "/packages/pug-lexer/test/cases/blocks-in-if.pug", "start": Object { "column": 1, "line": 8, }, }, "type": "indent", "val": 8, }, Object { "loc": Object { "end": Object { "column": 10, "line": 8, }, "filename": "/packages/pug-lexer/test/cases/blocks-in-if.pug", "start": Object { "column": 9, "line": 8, }, }, "type": "tag", "val": "p", }, Object { "loc": Object { "end": Object { "column": 24, "line": 8, }, "filename": "/packages/pug-lexer/test/cases/blocks-in-if.pug", "start": Object { "column": 11, "line": 8, }, }, "type": "text", "val": "ajax contents", }, Object { "loc": Object { "end": Object { "column": 1, "line": 10, }, "filename": "/packages/pug-lexer/test/cases/blocks-in-if.pug", "start": Object { "column": 1, "line": 10, }, }, "type": "outdent", }, Object { "loc": Object { "end": Object { "column": 1, "line": 10, }, "filename": "/packages/pug-lexer/test/cases/blocks-in-if.pug", "start": Object { "column": 1, "line": 10, }, }, "type": "outdent", }, Object { "buffer": false, "loc": Object { "end": Object { "column": 6, "line": 10, }, "filename": "/packages/pug-lexer/test/cases/blocks-in-if.pug", "start": Object { "column": 1, "line": 10, }, }, "mustEscape": false, "type": "code", "val": "else", }, Object { "loc": Object { "end": Object { "column": 5, "line": 11, }, "filename": "/packages/pug-lexer/test/cases/blocks-in-if.pug", "start": Object { "column": 1, "line": 11, }, }, "type": "indent", "val": 4, }, Object { "buffer": false, "loc": Object { "end": Object { "column": 24, "line": 11, }, "filename": "/packages/pug-lexer/test/cases/blocks-in-if.pug", "start": Object { "column": 5, "line": 11, }, }, "type": "comment", "val": " return all html", }, Object { "loc": Object { "end": Object { "column": 5, "line": 12, }, "filename": "/packages/pug-lexer/test/cases/blocks-in-if.pug", "start": Object { "column": 1, "line": 12, }, }, "type": "newline", }, Object { "loc": Object { "end": Object { "column": 17, "line": 12, }, "filename": "/packages/pug-lexer/test/cases/blocks-in-if.pug", "start": Object { "column": 5, "line": 12, }, }, "type": "doctype", "val": "html", }, Object { "loc": Object { "end": Object { "column": 5, "line": 13, }, "filename": "/packages/pug-lexer/test/cases/blocks-in-if.pug", "start": Object { "column": 1, "line": 13, }, }, "type": "newline", }, Object { "loc": Object { "end": Object { "column": 9, "line": 13, }, "filename": "/packages/pug-lexer/test/cases/blocks-in-if.pug", "start": Object { "column": 5, "line": 13, }, }, "type": "tag", "val": "html", }, Object { "loc": Object { "end": Object { "column": 9, "line": 14, }, "filename": "/packages/pug-lexer/test/cases/blocks-in-if.pug", "start": Object { "column": 1, "line": 14, }, }, "type": "indent", "val": 8, }, Object { "loc": Object { "end": Object { "column": 13, "line": 14, }, "filename": "/packages/pug-lexer/test/cases/blocks-in-if.pug", "start": Object { "column": 9, "line": 14, }, }, "type": "tag", "val": "head", }, Object { "loc": Object { "end": Object { "column": 13, "line": 15, }, "filename": "/packages/pug-lexer/test/cases/blocks-in-if.pug", "start": Object { "column": 1, "line": 15, }, }, "type": "indent", "val": 12, }, Object { "loc": Object { "end": Object { "column": 17, "line": 15, }, "filename": "/packages/pug-lexer/test/cases/blocks-in-if.pug", "start": Object { "column": 13, "line": 15, }, }, "type": "tag", "val": "meta", }, Object { "loc": Object { "end": Object { "column": 18, "line": 15, }, "filename": "/packages/pug-lexer/test/cases/blocks-in-if.pug", "start": Object { "column": 17, "line": 15, }, }, "type": "start-attributes", }, Object { "loc": Object { "end": Object { "column": 33, "line": 15, }, "filename": "/packages/pug-lexer/test/cases/blocks-in-if.pug", "start": Object { "column": 19, "line": 15, }, }, "mustEscape": true, "name": "charset", "type": "attribute", "val": "'utf8'", }, Object { "loc": Object { "end": Object { "column": 35, "line": 15, }, "filename": "/packages/pug-lexer/test/cases/blocks-in-if.pug", "start": Object { "column": 34, "line": 15, }, }, "type": "end-attributes", }, Object { "loc": Object { "end": Object { "column": 13, "line": 16, }, "filename": "/packages/pug-lexer/test/cases/blocks-in-if.pug", "start": Object { "column": 1, "line": 16, }, }, "type": "newline", }, Object { "loc": Object { "end": Object { "column": 18, "line": 16, }, "filename": "/packages/pug-lexer/test/cases/blocks-in-if.pug", "start": Object { "column": 13, "line": 16, }, }, "type": "tag", "val": "title", }, Object { "loc": Object { "end": Object { "column": 25, "line": 16, }, "filename": "/packages/pug-lexer/test/cases/blocks-in-if.pug", "start": Object { "column": 19, "line": 16, }, }, "type": "text", "val": "sample", }, Object { "loc": Object { "end": Object { "column": 13, "line": 17, }, "filename": "/packages/pug-lexer/test/cases/blocks-in-if.pug", "start": Object { "column": 1, "line": 17, }, }, "type": "newline", }, Object { "loc": Object { "end": Object { "column": 17, "line": 17, }, "filename": "/packages/pug-lexer/test/cases/blocks-in-if.pug", "start": Object { "column": 13, "line": 17, }, }, "type": "tag", "val": "body", }, Object { "loc": Object { "end": Object { "column": 17, "line": 18, }, "filename": "/packages/pug-lexer/test/cases/blocks-in-if.pug", "start": Object { "column": 1, "line": 18, }, }, "type": "indent", "val": 16, }, Object { "loc": Object { "end": Object { "column": 31, "line": 18, }, "filename": "/packages/pug-lexer/test/cases/blocks-in-if.pug", "start": Object { "column": 17, "line": 18, }, }, "mode": "replace", "type": "block", "val": "contents", }, Object { "loc": Object { "end": Object { "column": 21, "line": 19, }, "filename": "/packages/pug-lexer/test/cases/blocks-in-if.pug", "start": Object { "column": 1, "line": 19, }, }, "type": "indent", "val": 20, }, Object { "loc": Object { "end": Object { "column": 22, "line": 19, }, "filename": "/packages/pug-lexer/test/cases/blocks-in-if.pug", "start": Object { "column": 21, "line": 19, }, }, "type": "tag", "val": "p", }, Object { "loc": Object { "end": Object { "column": 35, "line": 19, }, "filename": "/packages/pug-lexer/test/cases/blocks-in-if.pug", "start": Object { "column": 23, "line": 19, }, }, "type": "text", "val": "all contetns", }, Object { "loc": Object { "end": Object { "column": 1, "line": 20, }, "filename": "/packages/pug-lexer/test/cases/blocks-in-if.pug", "start": Object { "column": 1, "line": 20, }, }, "type": "outdent", }, Object { "loc": Object { "end": Object { "column": 1, "line": 20, }, "filename": "/packages/pug-lexer/test/cases/blocks-in-if.pug", "start": Object { "column": 1, "line": 20, }, }, "type": "outdent", }, Object { "loc": Object { "end": Object { "column": 1, "line": 20, }, "filename": "/packages/pug-lexer/test/cases/blocks-in-if.pug", "start": Object { "column": 1, "line": 20, }, }, "type": "outdent", }, Object { "loc": Object { "end": Object { "column": 1, "line": 20, }, "filename": "/packages/pug-lexer/test/cases/blocks-in-if.pug", "start": Object { "column": 1, "line": 20, }, }, "type": "outdent", }, Object { "loc": Object { "end": Object { "column": 1, "line": 20, }, "filename": "/packages/pug-lexer/test/cases/blocks-in-if.pug", "start": Object { "column": 1, "line": 20, }, }, "type": "outdent", }, Object { "loc": Object { "end": Object { "column": 1, "line": 20, }, "filename": "/packages/pug-lexer/test/cases/blocks-in-if.pug", "start": Object { "column": 1, "line": 20, }, }, "type": "eos", }, ] `; exports[`case.pug 1`] = ` Array [ Object { "loc": Object { "end": Object { "column": 5, "line": 1, }, "filename": "/packages/pug-lexer/test/cases/case.pug", "start": Object { "column": 1, "line": 1, }, }, "type": "tag", "val": "html", }, Object { "loc": Object { "end": Object { "column": 3, "line": 2, }, "filename": "/packages/pug-lexer/test/cases/case.pug", "start": Object { "column": 1, "line": 2, }, }, "type": "indent", "val": 2, }, Object { "loc": Object { "end": Object { "column": 7, "line": 2, }, "filename": "/packages/pug-lexer/test/cases/case.pug", "start": Object { "column": 3, "line": 2, }, }, "type": "tag", "val": "body", }, Object { "loc": Object { "end": Object { "column": 5, "line": 3, }, "filename": "/packages/pug-lexer/test/cases/case.pug", "start": Object { "column": 1, "line": 3, }, }, "type": "indent", "val": 4, }, Object { "buffer": false, "loc": Object { "end": Object { "column": 22, "line": 3, }, "filename": "/packages/pug-lexer/test/cases/case.pug", "start": Object { "column": 5, "line": 3, }, }, "mustEscape": false, "type": "code", "val": "var friends = 1", }, Object { "loc": Object { "end": Object { "column": 5, "line": 4, }, "filename": "/packages/pug-lexer/test/cases/case.pug", "start": Object { "column": 1, "line": 4, }, }, "type": "newline", }, Object { "loc": Object { "end": Object { "column": 17, "line": 4, }, "filename": "/packages/pug-lexer/test/cases/case.pug", "start": Object { "column": 5, "line": 4, }, }, "type": "case", "val": "friends", }, Object { "loc": Object { "end": Object { "column": 7, "line": 5, }, "filename": "/packages/pug-lexer/test/cases/case.pug", "start": Object { "column": 1, "line": 5, }, }, "type": "indent", "val": 6, }, Object { "loc": Object { "end": Object { "column": 13, "line": 5, }, "filename": "/packages/pug-lexer/test/cases/case.pug", "start": Object { "column": 7, "line": 5, }, }, "type": "when", "val": "0", }, Object { "loc": Object { "end": Object { "column": 15, "line": 5, }, "filename": "/packages/pug-lexer/test/cases/case.pug", "start": Object { "column": 13, "line": 5, }, }, "type": ":", }, Object { "loc": Object { "end": Object { "column": 16, "line": 5, }, "filename": "/packages/pug-lexer/test/cases/case.pug", "start": Object { "column": 15, "line": 5, }, }, "type": "tag", "val": "p", }, Object { "loc": Object { "end": Object { "column": 36, "line": 5, }, "filename": "/packages/pug-lexer/test/cases/case.pug", "start": Object { "column": 17, "line": 5, }, }, "type": "text", "val": "you have no friends", }, Object { "loc": Object { "end": Object { "column": 7, "line": 6, }, "filename": "/packages/pug-lexer/test/cases/case.pug", "start": Object { "column": 1, "line": 6, }, }, "type": "newline", }, Object { "loc": Object { "end": Object { "column": 13, "line": 6, }, "filename": "/packages/pug-lexer/test/cases/case.pug", "start": Object { "column": 7, "line": 6, }, }, "type": "when", "val": "1", }, Object { "loc": Object { "end": Object { "column": 15, "line": 6, }, "filename": "/packages/pug-lexer/test/cases/case.pug", "start": Object { "column": 13, "line": 6, }, }, "type": ":", }, Object { "loc": Object { "end": Object { "column": 16, "line": 6, }, "filename": "/packages/pug-lexer/test/cases/case.pug", "start": Object { "column": 15, "line": 6, }, }, "type": "tag", "val": "p", }, Object { "loc": Object { "end": Object { "column": 34, "line": 6, }, "filename": "/packages/pug-lexer/test/cases/case.pug", "start": Object { "column": 17, "line": 6, }, }, "type": "text", "val": "you have a friend", }, Object { "loc": Object { "end": Object { "column": 7, "line": 7, }, "filename": "/packages/pug-lexer/test/cases/case.pug", "start": Object { "column": 1, "line": 7, }, }, "type": "newline", }, Object { "loc": Object { "end": Object { "column": 14, "line": 7, }, "filename": "/packages/pug-lexer/test/cases/case.pug", "start": Object { "column": 7, "line": 7, }, }, "type": "default", }, Object { "loc": Object { "end": Object { "column": 16, "line": 7, }, "filename": "/packages/pug-lexer/test/cases/case.pug", "start": Object { "column": 14, "line": 7, }, }, "type": ":", }, Object { "loc": Object { "end": Object { "column": 17, "line": 7, }, "filename": "/packages/pug-lexer/test/cases/case.pug", "start": Object { "column": 16, "line": 7, }, }, "type": "tag", "val": "p", }, Object { "loc": Object { "end": Object { "column": 27, "line": 7, }, "filename": "/packages/pug-lexer/test/cases/case.pug", "start": Object { "column": 18, "line": 7, }, }, "type": "text", "val": "you have ", }, Object { "buffer": true, "loc": Object { "end": Object { "column": 37, "line": 7, }, "filename": "/packages/pug-lexer/test/cases/case.pug", "start": Object { "column": 27, "line": 7, }, }, "mustEscape": true, "type": "interpolated-code", "val": "friends", }, Object { "loc": Object { "end": Object { "column": 45, "line": 7, }, "filename": "/packages/pug-lexer/test/cases/case.pug", "start": Object { "column": 37, "line": 7, }, }, "type": "text", "val": " friends", }, Object { "loc": Object { "end": Object { "column": 5, "line": 8, }, "filename": "/packages/pug-lexer/test/cases/case.pug", "start": Object { "column": 1, "line": 8, }, }, "type": "outdent", }, Object { "buffer": false, "loc": Object { "end": Object { "column": 22, "line": 8, }, "filename": "/packages/pug-lexer/test/cases/case.pug", "start": Object { "column": 5, "line": 8, }, }, "mustEscape": false, "type": "code", "val": "var friends = 0", }, Object { "loc": Object { "end": Object { "column": 5, "line": 9, }, "filename": "/packages/pug-lexer/test/cases/case.pug", "start": Object { "column": 1, "line": 9, }, }, "type": "newline", }, Object { "loc": Object { "end": Object { "column": 17, "line": 9, }, "filename": "/packages/pug-lexer/test/cases/case.pug", "start": Object { "column": 5, "line": 9, }, }, "type": "case", "val": "friends", }, Object { "loc": Object { "end": Object { "column": 7, "line": 10, }, "filename": "/packages/pug-lexer/test/cases/case.pug", "start": Object { "column": 1, "line": 10, }, }, "type": "indent", "val": 6, }, Object { "loc": Object { "end": Object { "column": 13, "line": 10, }, "filename": "/packages/pug-lexer/test/cases/case.pug", "start": Object { "column": 7, "line": 10, }, }, "type": "when", "val": "0", }, Object { "loc": Object { "end": Object { "column": 7, "line": 11, }, "filename": "/packages/pug-lexer/test/cases/case.pug", "start": Object { "column": 1, "line": 11, }, }, "type": "newline", }, Object { "loc": Object { "end": Object { "column": 13, "line": 11, }, "filename": "/packages/pug-lexer/test/cases/case.pug", "start": Object { "column": 7, "line": 11, }, }, "type": "when", "val": "1", }, Object { "loc": Object { "end": Object { "column": 9, "line": 12, }, "filename": "/packages/pug-lexer/test/cases/case.pug", "start": Object { "column": 1, "line": 12, }, }, "type": "indent", "val": 8, }, Object { "loc": Object { "end": Object { "column": 10, "line": 12, }, "filename": "/packages/pug-lexer/test/cases/case.pug", "start": Object { "column": 9, "line": 12, }, }, "type": "tag", "val": "p", }, Object { "loc": Object { "end": Object { "column": 36, "line": 12, }, "filename": "/packages/pug-lexer/test/cases/case.pug", "start": Object { "column": 11, "line": 12, }, }, "type": "text", "val": "you have very few friends", }, Object { "loc": Object { "end": Object { "column": 7, "line": 13, }, "filename": "/packages/pug-lexer/test/cases/case.pug", "start": Object { "column": 1, "line": 13, }, }, "type": "outdent", }, Object { "loc": Object { "end": Object { "column": 14, "line": 13, }, "filename": "/packages/pug-lexer/test/cases/case.pug", "start": Object { "column": 7, "line": 13, }, }, "type": "default", }, Object { "loc": Object { "end": Object { "column": 9, "line": 14, }, "filename": "/packages/pug-lexer/test/cases/case.pug", "start": Object { "column": 1, "line": 14, }, }, "type": "indent", "val": 8, }, Object { "loc": Object { "end": Object { "column": 10, "line": 14, }, "filename": "/packages/pug-lexer/test/cases/case.pug", "start": Object { "column": 9, "line": 14, }, }, "type": "tag", "val": "p", }, Object { "loc": Object { "end": Object { "column": 20, "line": 14, }, "filename": "/packages/pug-lexer/test/cases/case.pug", "start": Object { "column": 11, "line": 14, }, }, "type": "text", "val": "you have ", }, Object { "buffer": true, "loc": Object { "end": Object { "column": 30, "line": 14, }, "filename": "/packages/pug-lexer/test/cases/case.pug", "start": Object { "column": 20, "line": 14, }, }, "mustEscape": true, "type": "interpolated-code", "val": "friends", }, Object { "loc": Object { "end": Object { "column": 38, "line": 14, }, "filename": "/packages/pug-lexer/test/cases/case.pug", "start": Object { "column": 30, "line": 14, }, }, "type": "text", "val": " friends", }, Object { "loc": Object { "end": Object { "column": 5, "line": 16, }, "filename": "/packages/pug-lexer/test/cases/case.pug", "start": Object { "column": 1, "line": 16, }, }, "type": "outdent", }, Object { "loc": Object { "end": Object { "column": 5, "line": 16, }, "filename": "/packages/pug-lexer/test/cases/case.pug", "start": Object { "column": 1, "line": 16, }, }, "type": "outdent", }, Object { "buffer": false, "loc": Object { "end": Object { "column": 27, "line": 16, }, "filename": "/packages/pug-lexer/test/cases/case.pug", "start": Object { "column": 5, "line": 16, }, }, "mustEscape": false, "type": "code", "val": "var friend = 'Tim:G'", }, Object { "loc": Object { "end": Object { "column": 5, "line": 17, }, "filename": "/packages/pug-lexer/test/cases/case.pug", "start": Object { "column": 1, "line": 17, }, }, "type": "newline", }, Object { "loc": Object { "end": Object { "column": 16, "line": 17, }, "filename": "/packages/pug-lexer/test/cases/case.pug", "start": Object { "column": 5, "line": 17, }, }, "type": "case", "val": "friend", }, Object { "loc": Object { "end": Object { "column": 7, "line": 18, }, "filename": "/packages/pug-lexer/test/cases/case.pug", "start": Object { "column": 1, "line": 18, }, }, "type": "indent", "val": 6, }, Object { "loc": Object { "end": Object { "column": 19, "line": 18, }, "filename": "/packages/pug-lexer/test/cases/case.pug", "start": Object { "column": 7, "line": 18, }, }, "type": "when", "val": "'Tim:G'", }, Object { "loc": Object { "end": Object { "column": 24, "line": 18, }, "filename": "/packages/pug-lexer/test/cases/case.pug", "start": Object { "column": 19, "line": 18, }, }, "type": ":", }, Object { "loc": Object { "end": Object { "column": 25, "line": 18, }, "filename": "/packages/pug-lexer/test/cases/case.pug", "start": Object { "column": 24, "line": 18, }, }, "type": "tag", "val": "p", }, Object { "loc": Object { "end": Object { "column": 44, "line": 18, }, "filename": "/packages/pug-lexer/test/cases/case.pug", "start": Object { "column": 26, "line": 18, }, }, "type": "text", "val": "Friend is a string", }, Object { "loc": Object { "end": Object { "column": 7, "line": 19, }, "filename": "/packages/pug-lexer/test/cases/case.pug", "start": Object { "column": 1, "line": 19, }, }, "type": "newline", }, Object { "loc": Object { "end": Object { "column": 22, "line": 19, }, "filename": "/packages/pug-lexer/test/cases/case.pug", "start": Object { "column": 7, "line": 19, }, }, "type": "when", "val": "{tim: 'g'}", }, Object { "loc": Object { "end": Object { "column": 24, "line": 19, }, "filename": "/packages/pug-lexer/test/cases/case.pug", "start": Object { "column": 22, "line": 19, }, }, "type": ":", }, Object { "loc": Object { "end": Object { "column": 25, "line": 19, }, "filename": "/packages/pug-lexer/test/cases/case.pug", "start": Object { "column": 24, "line": 19, }, }, "type": "tag", "val": "p", }, Object { "loc": Object { "end": Object { "column": 45, "line": 19, }, "filename": "/packages/pug-lexer/test/cases/case.pug", "start": Object { "column": 26, "line": 19, }, }, "type": "text", "val": "Friend is an object", }, Object { "loc": Object { "end": Object { "column": 1, "line": 20, }, "filename": "/packages/pug-lexer/test/cases/case.pug", "start": Object { "column": 1, "line": 20, }, }, "type": "outdent", }, Object { "loc": Object { "end": Object { "column": 1, "line": 20, }, "filename": "/packages/pug-lexer/test/cases/case.pug", "start": Object { "column": 1, "line": 20, }, }, "type": "outdent", }, Object { "loc": Object { "end": Object { "column": 1, "line": 20, }, "filename": "/packages/pug-lexer/test/cases/case.pug", "start": Object { "column": 1, "line": 20, }, }, "type": "outdent", }, Object { "loc": Object { "end": Object { "column": 1, "line": 20, }, "filename": "/packages/pug-lexer/test/cases/case.pug", "start": Object { "column": 1, "line": 20, }, }, "type": "eos", }, ] `; exports[`case-blocks.pug 1`] = ` Array [ Object { "loc": Object { "end": Object { "column": 5, "line": 1, }, "filename": "/packages/pug-lexer/test/cases/case-blocks.pug", "start": Object { "column": 1, "line": 1, }, }, "type": "tag", "val": "html", }, Object { "loc": Object { "end": Object { "column": 3, "line": 2, }, "filename": "/packages/pug-lexer/test/cases/case-blocks.pug", "start": Object { "column": 1, "line": 2, }, }, "type": "indent", "val": 2, }, Object { "loc": Object { "end": Object { "column": 7, "line": 2, }, "filename": "/packages/pug-lexer/test/cases/case-blocks.pug", "start": Object { "column": 3, "line": 2, }, }, "type": "tag", "val": "body", }, Object { "loc": Object { "end": Object { "column": 5, "line": 3, }, "filename": "/packages/pug-lexer/test/cases/case-blocks.pug", "start": Object { "column": 1, "line": 3, }, }, "type": "indent", "val": 4, }, Object { "buffer": false, "loc": Object { "end": Object { "column": 22, "line": 3, }, "filename": "/packages/pug-lexer/test/cases/case-blocks.pug", "start": Object { "column": 5, "line": 3, }, }, "mustEscape": false, "type": "code", "val": "var friends = 1", }, Object { "loc": Object { "end": Object { "column": 5, "line": 4, }, "filename": "/packages/pug-lexer/test/cases/case-blocks.pug", "start": Object { "column": 1, "line": 4, }, }, "type": "newline", }, Object { "loc": Object { "end": Object { "column": 17, "line": 4, }, "filename": "/packages/pug-lexer/test/cases/case-blocks.pug", "start": Object { "column": 5, "line": 4, }, }, "type": "case", "val": "friends", }, Object { "loc": Object { "end": Object { "column": 7, "line": 5, }, "filename": "/packages/pug-lexer/test/cases/case-blocks.pug", "start": Object { "column": 1, "line": 5, }, }, "type": "indent", "val": 6, }, Object { "loc": Object { "end": Object { "column": 13, "line": 5, }, "filename": "/packages/pug-lexer/test/cases/case-blocks.pug", "start": Object { "column": 7, "line": 5, }, }, "type": "when", "val": "0", }, Object { "loc": Object { "end": Object { "column": 9, "line": 6, }, "filename": "/packages/pug-lexer/test/cases/case-blocks.pug", "start": Object { "column": 1, "line": 6, }, }, "type": "indent", "val": 8, }, Object { "loc": Object { "end": Object { "column": 10, "line": 6, }, "filename": "/packages/pug-lexer/test/cases/case-blocks.pug", "start": Object { "column": 9, "line": 6, }, }, "type": "tag", "val": "p", }, Object { "loc": Object { "end": Object { "column": 30, "line": 6, }, "filename": "/packages/pug-lexer/test/cases/case-blocks.pug", "start": Object { "column": 11, "line": 6, }, }, "type": "text", "val": "you have no friends", }, Object { "loc": Object { "end": Object { "column": 7, "line": 7, }, "filename": "/packages/pug-lexer/test/cases/case-blocks.pug", "start": Object { "column": 1, "line": 7, }, }, "type": "outdent", }, Object { "loc": Object { "end": Object { "column": 13, "line": 7, }, "filename": "/packages/pug-lexer/test/cases/case-blocks.pug", "start": Object { "column": 7, "line": 7, }, }, "type": "when", "val": "1", }, Object { "loc": Object { "end": Object { "column": 9, "line": 8, }, "filename": "/packages/pug-lexer/test/cases/case-blocks.pug", "start": Object { "column": 1, "line": 8, }, }, "type": "indent", "val": 8, }, Object { "loc": Object { "end": Object { "column": 10, "line": 8, }, "filename": "/packages/pug-lexer/test/cases/case-blocks.pug", "start": Object { "column": 9, "line": 8, }, }, "type": "tag", "val": "p", }, Object { "loc": Object { "end": Object { "column": 28, "line": 8, }, "filename": "/packages/pug-lexer/test/cases/case-blocks.pug", "start": Object { "column": 11, "line": 8, }, }, "type": "text", "val": "you have a friend", }, Object { "loc": Object { "end": Object { "column": 7, "line": 9, }, "filename": "/packages/pug-lexer/test/cases/case-blocks.pug", "start": Object { "column": 1, "line": 9, }, }, "type": "outdent", }, Object { "loc": Object { "end": Object { "column": 14, "line": 9, }, "filename": "/packages/pug-lexer/test/cases/case-blocks.pug", "start": Object { "column": 7, "line": 9, }, }, "type": "default", }, Object { "loc": Object { "end": Object { "column": 9, "line": 10, }, "filename": "/packages/pug-lexer/test/cases/case-blocks.pug", "start": Object { "column": 1, "line": 10, }, }, "type": "indent", "val": 8, }, Object { "loc": Object { "end": Object { "column": 10, "line": 10, }, "filename": "/packages/pug-lexer/test/cases/case-blocks.pug", "start": Object { "column": 9, "line": 10, }, }, "type": "tag", "val": "p", }, Object { "loc": Object { "end": Object { "column": 20, "line": 10, }, "filename": "/packages/pug-lexer/test/cases/case-blocks.pug", "start": Object { "column": 11, "line": 10, }, }, "type": "text", "val": "you have ", }, Object { "buffer": true, "loc": Object { "end": Object { "column": 30, "line": 10, }, "filename": "/packages/pug-lexer/test/cases/case-blocks.pug", "start": Object { "column": 20, "line": 10, }, }, "mustEscape": true, "type": "interpolated-code", "val": "friends", }, Object { "loc": Object { "end": Object { "column": 38, "line": 10, }, "filename": "/packages/pug-lexer/test/cases/case-blocks.pug", "start": Object { "column": 30, "line": 10, }, }, "type": "text", "val": " friends", }, Object { "loc": Object { "end": Object { "column": 38, "line": 10, }, "filename": "/packages/pug-lexer/test/cases/case-blocks.pug", "start": Object { "column": 38, "line": 10, }, }, "type": "outdent", }, Object { "loc": Object { "end": Object { "column": 38, "line": 10, }, "filename": "/packages/pug-lexer/test/cases/case-blocks.pug", "start": Object { "column": 38, "line": 10, }, }, "type": "outdent", }, Object { "loc": Object { "end": Object { "column": 38, "line": 10, }, "filename": "/packages/pug-lexer/test/cases/case-blocks.pug", "start": Object { "column": 38, "line": 10, }, }, "type": "outdent", }, Object { "loc": Object { "end": Object { "column": 38, "line": 10, }, "filename": "/packages/pug-lexer/test/cases/case-blocks.pug", "start": Object { "column": 38, "line": 10, }, }, "type": "outdent", }, Object { "loc": Object { "end": Object { "column": 38, "line": 10, }, "filename": "/packages/pug-lexer/test/cases/case-blocks.pug", "start": Object { "column": 38, "line": 10, }, }, "type": "eos", }, ] `; exports[`case-with-invalid-expression.pug 1`] = ` Object { "code": "PUG:SYNTAX_ERROR", "column": 22, "line": 1, "msg": "Syntax Error: Unexpected token", } `; exports[`case-with-no-expression.pug 1`] = ` Object { "code": "PUG:NO_CASE_EXPRESSION", "column": 5, "line": 1, "msg": "missing expression for case", } `; exports[`classes.pug 1`] = ` Array [ Object { "loc": Object { "end": Object { "column": 2, "line": 1, }, "filename": "/packages/pug-lexer/test/cases/classes.pug", "start": Object { "column": 1, "line": 1, }, }, "type": "tag", "val": "a", }, Object { "loc": Object { "end": Object { "column": 3, "line": 1, }, "filename": "/packages/pug-lexer/test/cases/classes.pug", "start": Object { "column": 2, "line": 1, }, }, "type": "start-attributes", }, Object { "loc": Object { "end": Object { "column": 30, "line": 1, }, "filename": "/packages/pug-lexer/test/cases/classes.pug", "start": Object { "column": 3, "line": 1, }, }, "mustEscape": true, "name": "class", "type": "attribute", "val": "['foo', 'bar', 'baz']", }, Object { "loc": Object { "end": Object { "column": 31, "line": 1, }, "filename": "/packages/pug-lexer/test/cases/classes.pug", "start": Object { "column": 30, "line": 1, }, }, "type": "end-attributes", }, Object { "loc": Object { "end": Object { "column": 1, "line": 5, }, "filename": "/packages/pug-lexer/test/cases/classes.pug", "start": Object { "column": 1, "line": 5, }, }, "type": "newline", }, Object { "loc": Object { "end": Object { "column": 2, "line": 5, }, "filename": "/packages/pug-lexer/test/cases/classes.pug", "start": Object { "column": 1, "line": 5, }, }, "type": "tag", "val": "a", }, Object { "loc": Object { "end": Object { "column": 6, "line": 5, }, "filename": "/packages/pug-lexer/test/cases/classes.pug", "start": Object { "column": 2, "line": 5, }, }, "type": "class", "val": "foo", }, Object { "loc": Object { "end": Object { "column": 7, "line": 5, }, "filename": "/packages/pug-lexer/test/cases/classes.pug", "start": Object { "column": 6, "line": 5, }, }, "type": "start-attributes", }, Object { "loc": Object { "end": Object { "column": 18, "line": 5, }, "filename": "/packages/pug-lexer/test/cases/classes.pug", "start": Object { "column": 7, "line": 5, }, }, "mustEscape": true, "name": "class", "type": "attribute", "val": "'bar'", }, Object { "loc": Object { "end": Object { "column": 19, "line": 5, }, "filename": "/packages/pug-lexer/test/cases/classes.pug", "start": Object { "column": 18, "line": 5, }, }, "type": "end-attributes", }, Object { "loc": Object { "end": Object { "column": 23, "line": 5, }, "filename": "/packages/pug-lexer/test/cases/classes.pug", "start": Object { "column": 19, "line": 5, }, }, "type": "class", "val": "baz", }, Object { "loc": Object { "end": Object { "column": 1, "line": 9, }, "filename": "/packages/pug-lexer/test/cases/classes.pug", "start": Object { "column": 1, "line": 9, }, }, "type": "newline", }, Object { "loc": Object { "end": Object { "column": 2, "line": 9, }, "filename": "/packages/pug-lexer/test/cases/classes.pug", "start": Object { "column": 1, "line": 9, }, }, "type": "tag", "val": "a", }, Object { "loc": Object { "end": Object { "column": 14, "line": 9, }, "filename": "/packages/pug-lexer/test/cases/classes.pug", "start": Object { "column": 2, "line": 9, }, }, "type": "class", "val": "foo-bar_baz", }, Object { "loc": Object { "end": Object { "column": 1, "line": 11, }, "filename": "/packages/pug-lexer/test/cases/classes.pug", "start": Object { "column": 1, "line": 11, }, }, "type": "newline", }, Object { "loc": Object { "end": Object { "column": 2, "line": 11, }, "filename": "/packages/pug-lexer/test/cases/classes.pug", "start": Object { "column": 1, "line": 11, }, }, "type": "tag", "val": "a", }, Object { "loc": Object { "end": Object { "column": 3, "line": 11, }, "filename": "/packages/pug-lexer/test/cases/classes.pug", "start": Object { "column": 2, "line": 11, }, }, "type": "start-attributes", }, Object { "loc": Object { "end": Object { "column": 43, "line": 11, }, "filename": "/packages/pug-lexer/test/cases/classes.pug", "start": Object { "column": 3, "line": 11, }, }, "mustEscape": true, "name": "class", "type": "attribute", "val": "{foo: true, bar: false, baz: true}", }, Object { "loc": Object { "end": Object { "column": 44, "line": 11, }, "filename": "/packages/pug-lexer/test/cases/classes.pug", "start": Object { "column": 43, "line": 11, }, }, "type": "end-attributes", }, Object { "loc": Object { "end": Object { "column": 1, "line": 13, }, "filename": "/packages/pug-lexer/test/cases/classes.pug", "start": Object { "column": 1, "line": 13, }, }, "type": "newline", }, Object { "loc": Object { "end": Object { "column": 2, "line": 13, }, "filename": "/packages/pug-lexer/test/cases/classes.pug", "start": Object { "column": 1, "line": 13, }, }, "type": "tag", "val": "a", }, Object { "loc": Object { "end": Object { "column": 7, "line": 13, }, "filename": "/packages/pug-lexer/test/cases/classes.pug", "start": Object { "column": 2, "line": 13, }, }, "type": "class", "val": "-foo", }, Object { "loc": Object { "end": Object { "column": 1, "line": 14, }, "filename": "/packages/pug-lexer/test/cases/classes.pug", "start": Object { "column": 1, "line": 14, }, }, "type": "newline", }, Object { "loc": Object { "end": Object { "column": 2, "line": 14, }, "filename": "/packages/pug-lexer/test/cases/classes.pug", "start": Object { "column": 1, "line": 14, }, }, "type": "tag", "val": "a", }, Object { "loc": Object { "end": Object { "column": 7, "line": 14, }, "filename": "/packages/pug-lexer/test/cases/classes.pug", "start": Object { "column": 2, "line": 14, }, }, "type": "class", "val": "3foo", }, Object { "loc": Object { "end": Object { "column": 1, "line": 15, }, "filename": "/packages/pug-lexer/test/cases/classes.pug", "start": Object { "column": 1, "line": 15, }, }, "type": "newline", }, Object { "loc": Object { "end": Object { "column": 1, "line": 15, }, "filename": "/packages/pug-lexer/test/cases/classes.pug", "start": Object { "column": 1, "line": 15, }, }, "type": "eos", }, ] `; exports[`classes-empty.pug 1`] = ` Array [ Object { "loc": Object { "end": Object { "column": 2, "line": 1, }, "filename": "/packages/pug-lexer/test/cases/classes-empty.pug", "start": Object { "column": 1, "line": 1, }, }, "type": "tag", "val": "a", }, Object { "loc": Object { "end": Object { "column": 3, "line": 1, }, "filename": "/packages/pug-lexer/test/cases/classes-empty.pug", "start": Object { "column": 2, "line": 1, }, }, "type": "start-attributes", }, Object { "loc": Object { "end": Object { "column": 11, "line": 1, }, "filename": "/packages/pug-lexer/test/cases/classes-empty.pug", "start": Object { "column": 3, "line": 1, }, }, "mustEscape": true, "name": "class", "type": "attribute", "val": "''", }, Object { "loc": Object { "end": Object { "column": 12, "line": 1, }, "filename": "/packages/pug-lexer/test/cases/classes-empty.pug", "start": Object { "column": 11, "line": 1, }, }, "type": "end-attributes", }, Object { "loc": Object { "end": Object { "column": 1, "line": 2, }, "filename": "/packages/pug-lexer/test/cases/classes-empty.pug", "start": Object { "column": 1, "line": 2, }, }, "type": "newline", }, Object { "loc": Object { "end": Object { "column": 2, "line": 2, }, "filename": "/packages/pug-lexer/test/cases/classes-empty.pug", "start": Object { "column": 1, "line": 2, }, }, "type": "tag", "val": "a", }, Object { "loc": Object { "end": Object { "column": 3, "line": 2, }, "filename": "/packages/pug-lexer/test/cases/classes-empty.pug", "start": Object { "column": 2, "line": 2, }, }, "type": "start-attributes", }, Object { "loc": Object { "end": Object { "column": 13, "line": 2, }, "filename": "/packages/pug-lexer/test/cases/classes-empty.pug", "start": Object { "column": 3, "line": 2, }, }, "mustEscape": true, "name": "class", "type": "attribute", "val": "null", }, Object { "loc": Object { "end": Object { "column": 14, "line": 2, }, "filename": "/packages/pug-lexer/test/cases/classes-empty.pug", "start": Object { "column": 13, "line": 2, }, }, "type": "end-attributes", }, Object { "loc": Object { "end": Object { "column": 1, "line": 3, }, "filename": "/packages/pug-lexer/test/cases/classes-empty.pug", "start": Object { "column": 1, "line": 3, }, }, "type": "newline", }, Object { "loc": Object { "end": Object { "column": 2, "line": 3, }, "filename": "/packages/pug-lexer/test/cases/classes-empty.pug", "start": Object { "column": 1, "line": 3, }, }, "type": "tag", "val": "a", }, Object { "loc": Object { "end": Object { "column": 3, "line": 3, }, "filename": "/packages/pug-lexer/test/cases/classes-empty.pug", "start": Object { "column": 2, "line": 3, }, }, "type": "start-attributes", }, Object { "loc": Object { "end": Object { "column": 18, "line": 3, }, "filename": "/packages/pug-lexer/test/cases/classes-empty.pug", "start": Object { "column": 3, "line": 3, }, }, "mustEscape": true, "name": "class", "type": "attribute", "val": "undefined", }, Object { "loc": Object { "end": Object { "column": 19, "line": 3, }, "filename": "/packages/pug-lexer/test/cases/classes-empty.pug", "start": Object { "column": 18, "line": 3, }, }, "type": "end-attributes", }, Object { "loc": Object { "end": Object { "column": 19, "line": 3, }, "filename": "/packages/pug-lexer/test/cases/classes-empty.pug", "start": Object { "column": 19, "line": 3, }, }, "type": "eos", }, ] `; exports[`code.conditionals.pug 1`] = ` Array [ Object { "loc": Object { "end": Object { "column": 1, "line": 2, }, "filename": "/packages/pug-lexer/test/cases/code.conditionals.pug", "start": Object { "column": 1, "line": 2, }, }, "type": "newline", }, Object { "buffer": false, "loc": Object { "end": Object { "column": 12, "line": 2, }, "filename": "/packages/pug-lexer/test/cases/code.conditionals.pug", "start": Object { "column": 1, "line": 2, }, }, "mustEscape": false, "type": "code", "val": "if (true)", }, Object { "loc": Object { "end": Object { "column": 3, "line": 3, }, "filename": "/packages/pug-lexer/test/cases/code.conditionals.pug", "start": Object { "column": 1, "line": 3, }, }, "type": "indent", "val": 2, }, Object { "loc": Object { "end": Object { "column": 4, "line": 3, }, "filename": "/packages/pug-lexer/test/cases/code.conditionals.pug", "start": Object { "column": 3, "line": 3, }, }, "type": "tag", "val": "p", }, Object { "loc": Object { "end": Object { "column": 8, "line": 3, }, "filename": "/packages/pug-lexer/test/cases/code.conditionals.pug", "start": Object { "column": 5, "line": 3, }, }, "type": "text", "val": "foo", }, Object { "loc": Object { "end": Object { "column": 1, "line": 4, }, "filename": "/packages/pug-lexer/test/cases/code.conditionals.pug", "start": Object { "column": 1, "line": 4, }, }, "type": "outdent", }, Object { "buffer": false, "loc": Object { "end": Object { "column": 7, "line": 4, }, "filename": "/packages/pug-lexer/test/cases/code.conditionals.pug", "start": Object { "column": 1, "line": 4, }, }, "mustEscape": false, "type": "code", "val": "else", }, Object { "loc": Object { "end": Object { "column": 3, "line": 5, }, "filename": "/packages/pug-lexer/test/cases/code.conditionals.pug", "start": Object { "column": 1, "line": 5, }, }, "type": "indent", "val": 2, }, Object { "loc": Object { "end": Object { "column": 4, "line": 5, }, "filename": "/packages/pug-lexer/test/cases/code.conditionals.pug", "start": Object { "column": 3, "line": 5, }, }, "type": "tag", "val": "p", }, Object { "loc": Object { "end": Object { "column": 8, "line": 5, }, "filename": "/packages/pug-lexer/test/cases/code.conditionals.pug", "start": Object { "column": 5, "line": 5, }, }, "type": "text", "val": "bar", }, Object { "loc": Object { "end": Object { "column": 1, "line": 7, }, "filename": "/packages/pug-lexer/test/cases/code.conditionals.pug", "start": Object { "column": 1, "line": 7, }, }, "type": "outdent", }, Object { "buffer": false, "loc": Object { "end": Object { "column": 14, "line": 7, }, "filename": "/packages/pug-lexer/test/cases/code.conditionals.pug", "start": Object { "column": 1, "line": 7, }, }, "mustEscape": false, "type": "code", "val": "if (true) {", }, Object { "loc": Object { "end": Object { "column": 3, "line": 8, }, "filename": "/packages/pug-lexer/test/cases/code.conditionals.pug", "start": Object { "column": 1, "line": 8, }, }, "type": "indent", "val": 2, }, Object { "loc": Object { "end": Object { "column": 4, "line": 8, }, "filename": "/packages/pug-lexer/test/cases/code.conditionals.pug", "start": Object { "column": 3, "line": 8, }, }, "type": "tag", "val": "p", }, Object { "loc": Object { "end": Object { "column": 8, "line": 8, }, "filename": "/packages/pug-lexer/test/cases/code.conditionals.pug", "start": Object { "column": 5, "line": 8, }, }, "type": "text", "val": "foo", }, Object { "loc": Object { "end": Object { "column": 1, "line": 9, }, "filename": "/packages/pug-lexer/test/cases/code.conditionals.pug", "start": Object { "column": 1, "line": 9, }, }, "type": "outdent", }, Object { "buffer": false, "loc": Object { "end": Object { "column": 11, "line": 9, }, "filename": "/packages/pug-lexer/test/cases/code.conditionals.pug", "start": Object { "column": 1, "line": 9, }, }, "mustEscape": false, "type": "code", "val": "} else {", }, Object { "loc": Object { "end": Object { "column": 3, "line": 10, }, "filename": "/packages/pug-lexer/test/cases/code.conditionals.pug", "start": Object { "column": 1, "line": 10, }, }, "type": "indent", "val": 2, }, Object { "loc": Object { "end": Object { "column": 4, "line": 10, }, "filename": "/packages/pug-lexer/test/cases/code.conditionals.pug", "start": Object { "column": 3, "line": 10, }, }, "type": "tag", "val": "p", }, Object { "loc": Object { "end": Object { "column": 8, "line": 10, }, "filename": "/packages/pug-lexer/test/cases/code.conditionals.pug", "start": Object { "column": 5, "line": 10, }, }, "type": "text", "val": "bar", }, Object { "loc": Object { "end": Object { "column": 1, "line": 11, }, "filename": "/packages/pug-lexer/test/cases/code.conditionals.pug", "start": Object { "column": 1, "line": 11, }, }, "type": "outdent", }, Object { "buffer": false, "loc": Object { "end": Object { "column": 4, "line": 11, }, "filename": "/packages/pug-lexer/test/cases/code.conditionals.pug", "start": Object { "column": 1, "line": 11, }, }, "mustEscape": false, "type": "code", "val": "}", }, Object { "loc": Object { "end": Object { "column": 1, "line": 13, }, "filename": "/packages/pug-lexer/test/cases/code.conditionals.pug", "start": Object { "column": 1, "line": 13, }, }, "type": "newline", }, Object { "loc": Object { "end": Object { "column": 8, "line": 13, }, "filename": "/packages/pug-lexer/test/cases/code.conditionals.pug", "start": Object { "column": 1, "line": 13, }, }, "type": "if", "val": "true", }, Object { "loc": Object { "end": Object { "column": 3, "line": 14, }, "filename": "/packages/pug-lexer/test/cases/code.conditionals.pug", "start": Object { "column": 1, "line": 14, }, }, "type": "indent", "val": 2, }, Object { "loc": Object { "end": Object { "column": 4, "line": 14, }, "filename": "/packages/pug-lexer/test/cases/code.conditionals.pug", "start": Object { "column": 3, "line": 14, }, }, "type": "tag", "val": "p", }, Object { "loc": Object { "end": Object { "column": 8, "line": 14, }, "filename": "/packages/pug-lexer/test/cases/code.conditionals.pug", "start": Object { "column": 5, "line": 14, }, }, "type": "text", "val": "foo", }, Object { "loc": Object { "end": Object { "column": 3, "line": 15, }, "filename": "/packages/pug-lexer/test/cases/code.conditionals.pug", "start": Object { "column": 1, "line": 15, }, }, "type": "newline", }, Object { "loc": Object { "end": Object { "column": 4, "line": 15, }, "filename": "/packages/pug-lexer/test/cases/code.conditionals.pug", "start": Object { "column": 3, "line": 15, }, }, "type": "tag", "val": "p", }, Object { "loc": Object { "end": Object { "column": 8, "line": 15, }, "filename": "/packages/pug-lexer/test/cases/code.conditionals.pug", "start": Object { "column": 5, "line": 15, }, }, "type": "text", "val": "bar", }, Object { "loc": Object { "end": Object { "column": 3, "line": 16, }, "filename": "/packages/pug-lexer/test/cases/code.conditionals.pug", "start": Object { "column": 1, "line": 16, }, }, "type": "newline", }, Object { "loc": Object { "end": Object { "column": 4, "line": 16, }, "filename": "/packages/pug-lexer/test/cases/code.conditionals.pug", "start": Object { "column": 3, "line": 16, }, }, "type": "tag", "val": "p", }, Object { "loc": Object { "end": Object { "column": 8, "line": 16, }, "filename": "/packages/pug-lexer/test/cases/code.conditionals.pug", "start": Object { "column": 5, "line": 16, }, }, "type": "text", "val": "baz", }, Object { "loc": Object { "end": Object { "column": 1, "line": 17, }, "filename": "/packages/pug-lexer/test/cases/code.conditionals.pug", "start": Object { "column": 1, "line": 17, }, }, "type": "outdent", }, Object { "loc": Object { "end": Object { "column": 5, "line": 17, }, "filename": "/packages/pug-lexer/test/cases/code.conditionals.pug", "start": Object { "column": 1, "line": 17, }, }, "type": "else", "val": "", }, Object { "loc": Object { "end": Object { "column": 3, "line": 18, }, "filename": "/packages/pug-lexer/test/cases/code.conditionals.pug", "start": Object { "column": 1, "line": 18, }, }, "type": "indent", "val": 2, }, Object { "loc": Object { "end": Object { "column": 4, "line": 18, }, "filename": "/packages/pug-lexer/test/cases/code.conditionals.pug", "start": Object { "column": 3, "line": 18, }, }, "type": "tag", "val": "p", }, Object { "loc": Object { "end": Object { "column": 8, "line": 18, }, "filename": "/packages/pug-lexer/test/cases/code.conditionals.pug", "start": Object { "column": 5, "line": 18, }, }, "type": "text", "val": "bar", }, Object { "loc": Object { "end": Object { "column": 1, "line": 20, }, "filename": "/packages/pug-lexer/test/cases/code.conditionals.pug", "start": Object { "column": 1, "line": 20, }, }, "type": "outdent", }, Object { "loc": Object { "end": Object { "column": 12, "line": 20, }, "filename": "/packages/pug-lexer/test/cases/code.conditionals.pug", "start": Object { "column": 1, "line": 20, }, }, "type": "if", "val": "!(true)", }, Object { "loc": Object { "end": Object { "column": 3, "line": 21, }, "filename": "/packages/pug-lexer/test/cases/code.conditionals.pug", "start": Object { "column": 1, "line": 21, }, }, "type": "indent", "val": 2, }, Object { "loc": Object { "end": Object { "column": 4, "line": 21, }, "filename": "/packages/pug-lexer/test/cases/code.conditionals.pug", "start": Object { "column": 3, "line": 21, }, }, "type": "tag", "val": "p", }, Object { "loc": Object { "end": Object { "column": 8, "line": 21, }, "filename": "/packages/pug-lexer/test/cases/code.conditionals.pug", "start": Object { "column": 5, "line": 21, }, }, "type": "text", "val": "foo", }, Object { "loc": Object { "end": Object { "column": 1, "line": 22, }, "filename": "/packages/pug-lexer/test/cases/code.conditionals.pug", "start": Object { "column": 1, "line": 22, }, }, "type": "outdent", }, Object { "loc": Object { "end": Object { "column": 5, "line": 22, }, "filename": "/packages/pug-lexer/test/cases/code.conditionals.pug", "start": Object { "column": 1, "line": 22, }, }, "type": "else", "val": "", }, Object { "loc": Object { "end": Object { "column": 3, "line": 23, }, "filename": "/packages/pug-lexer/test/cases/code.conditionals.pug", "start": Object { "column": 1, "line": 23, }, }, "type": "indent", "val": 2, }, Object { "loc": Object { "end": Object { "column": 4, "line": 23, }, "filename": "/packages/pug-lexer/test/cases/code.conditionals.pug", "start": Object { "column": 3, "line": 23, }, }, "type": "tag", "val": "p", }, Object { "loc": Object { "end": Object { "column": 8, "line": 23, }, "filename": "/packages/pug-lexer/test/cases/code.conditionals.pug", "start": Object { "column": 5, "line": 23, }, }, "type": "text", "val": "bar", }, Object { "loc": Object { "end": Object { "column": 1, "line": 25, }, "filename": "/packages/pug-lexer/test/cases/code.conditionals.pug", "start": Object { "column": 1, "line": 25, }, }, "type": "outdent", }, Object { "loc": Object { "end": Object { "column": 12, "line": 25, }, "filename": "/packages/pug-lexer/test/cases/code.conditionals.pug", "start": Object { "column": 1, "line": 25, }, }, "type": "if", "val": "'nested'", }, Object { "loc": Object { "end": Object { "column": 3, "line": 26, }, "filename": "/packages/pug-lexer/test/cases/code.conditionals.pug", "start": Object { "column": 1, "line": 26, }, }, "type": "indent", "val": 2, }, Object { "loc": Object { "end": Object { "column": 13, "line": 26, }, "filename": "/packages/pug-lexer/test/cases/code.conditionals.pug", "start": Object { "column": 3, "line": 26, }, }, "type": "if", "val": "'works'", }, Object { "loc": Object { "end": Object { "column": 5, "line": 27, }, "filename": "/packages/pug-lexer/test/cases/code.conditionals.pug", "start": Object { "column": 1, "line": 27, }, }, "type": "indent", "val": 4, }, Object { "loc": Object { "end": Object { "column": 6, "line": 27, }, "filename": "/packages/pug-lexer/test/cases/code.conditionals.pug", "start": Object { "column": 5, "line": 27, }, }, "type": "tag", "val": "p", }, Object { "loc": Object { "end": Object { "column": 10, "line": 27, }, "filename": "/packages/pug-lexer/test/cases/code.conditionals.pug", "start": Object { "column": 7, "line": 27, }, }, "type": "text", "val": "yay", }, Object { "loc": Object { "end": Object { "column": 1, "line": 29, }, "filename": "/packages/pug-lexer/test/cases/code.conditionals.pug", "start": Object { "column": 1, "line": 29, }, }, "type": "outdent", }, Object { "loc": Object { "end": Object { "column": 1, "line": 29, }, "filename": "/packages/pug-lexer/test/cases/code.conditionals.pug", "start": Object { "column": 1, "line": 29, }, }, "type": "outdent", }, Object { "buffer": false, "loc": Object { "end": Object { "column": 23, "line": 29, }, "filename": "/packages/pug-lexer/test/cases/code.conditionals.pug", "start": Object { "column": 1, "line": 29, }, }, "type": "comment", "val": " allow empty blocks", }, Object { "loc": Object { "end": Object { "column": 1, "line": 30, }, "filename": "/packages/pug-lexer/test/cases/code.conditionals.pug", "start": Object { "column": 1, "line": 30, }, }, "type": "newline", }, Object { "loc": Object { "end": Object { "column": 9, "line": 30, }, "filename": "/packages/pug-lexer/test/cases/code.conditionals.pug", "start": Object { "column": 1, "line": 30, }, }, "type": "if", "val": "false", }, Object { "loc": Object { "end": Object { "column": 1, "line": 31, }, "filename": "/packages/pug-lexer/test/cases/code.conditionals.pug", "start": Object { "column": 1, "line": 31, }, }, "type": "newline", }, Object { "loc": Object { "end": Object { "column": 5, "line": 31, }, "filename": "/packages/pug-lexer/test/cases/code.conditionals.pug", "start": Object { "column": 1, "line": 31, }, }, "type": "else", "val": "", }, Object { "loc": Object { "end": Object { "column": 3, "line": 32, }, "filename": "/packages/pug-lexer/test/cases/code.conditionals.pug", "start": Object { "column": 1, "line": 32, }, }, "type": "indent", "val": 2, }, Object { "loc": Object { "end": Object { "column": 7, "line": 32, }, "filename": "/packages/pug-lexer/test/cases/code.conditionals.pug", "start": Object { "column": 3, "line": 32, }, }, "type": "class", "val": "bar", }, Object { "loc": Object { "end": Object { "column": 1, "line": 33, }, "filename": "/packages/pug-lexer/test/cases/code.conditionals.pug", "start": Object { "column": 1, "line": 33, }, }, "type": "outdent", }, Object { "loc": Object { "end": Object { "column": 8, "line": 33, }, "filename": "/packages/pug-lexer/test/cases/code.conditionals.pug", "start": Object { "column": 1, "line": 33, }, }, "type": "if", "val": "true", }, Object { "loc": Object { "end": Object { "column": 3, "line": 34, }, "filename": "/packages/pug-lexer/test/cases/code.conditionals.pug", "start": Object { "column": 1, "line": 34, }, }, "type": "indent", "val": 2, }, Object { "loc": Object { "end": Object { "column": 7, "line": 34, }, "filename": "/packages/pug-lexer/test/cases/code.conditionals.pug", "start": Object { "column": 3, "line": 34, }, }, "type": "class", "val": "bar", }, Object { "loc": Object { "end": Object { "column": 1, "line": 35, }, "filename": "/packages/pug-lexer/test/cases/code.conditionals.pug", "start": Object { "column": 1, "line": 35, }, }, "type": "outdent", }, Object { "loc": Object { "end": Object { "column": 5, "line": 35, }, "filename": "/packages/pug-lexer/test/cases/code.conditionals.pug", "start": Object { "column": 1, "line": 35, }, }, "type": "else", "val": "", }, Object { "loc": Object { "end": Object { "column": 1, "line": 36, }, "filename": "/packages/pug-lexer/test/cases/code.conditionals.pug", "start": Object { "column": 1, "line": 36, }, }, "type": "newline", }, Object { "loc": Object { "end": Object { "column": 6, "line": 36, }, "filename": "/packages/pug-lexer/test/cases/code.conditionals.pug", "start": Object { "column": 1, "line": 36, }, }, "type": "class", "val": "bing", }, Object { "loc": Object { "end": Object { "column": 1, "line": 38, }, "filename": "/packages/pug-lexer/test/cases/code.conditionals.pug", "start": Object { "column": 1, "line": 38, }, }, "type": "newline", }, Object { "loc": Object { "end": Object { "column": 9, "line": 38, }, "filename": "/packages/pug-lexer/test/cases/code.conditionals.pug", "start": Object { "column": 1, "line": 38, }, }, "type": "if", "val": "false", }, Object { "loc": Object { "end": Object { "column": 3, "line": 39, }, "filename": "/packages/pug-lexer/test/cases/code.conditionals.pug", "start": Object { "column": 1, "line": 39, }, }, "type": "indent", "val": 2, }, Object { "loc": Object { "end": Object { "column": 8, "line": 39, }, "filename": "/packages/pug-lexer/test/cases/code.conditionals.pug", "start": Object { "column": 3, "line": 39, }, }, "type": "class", "val": "bing", }, Object { "loc": Object { "end": Object { "column": 1, "line": 40, }, "filename": "/packages/pug-lexer/test/cases/code.conditionals.pug", "start": Object { "column": 1, "line": 40, }, }, "type": "outdent", }, Object { "loc": Object { "end": Object { "column": 14, "line": 40, }, "filename": "/packages/pug-lexer/test/cases/code.conditionals.pug", "start": Object { "column": 1, "line": 40, }, }, "type": "else-if", "val": "false", }, Object { "loc": Object { "end": Object { "column": 3, "line": 41, }, "filename": "/packages/pug-lexer/test/cases/code.conditionals.pug", "start": Object { "column": 1, "line": 41, }, }, "type": "indent", "val": 2, }, Object { "loc": Object { "end": Object { "column": 7, "line": 41, }, "filename": "/packages/pug-lexer/test/cases/code.conditionals.pug", "start": Object { "column": 3, "line": 41, }, }, "type": "class", "val": "bar", }, Object { "loc": Object { "end": Object { "column": 1, "line": 42, }, "filename": "/packages/pug-lexer/test/cases/code.conditionals.pug", "start": Object { "column": 1, "line": 42, }, }, "type": "outdent", }, Object { "loc": Object { "end": Object { "column": 5, "line": 42, }, "filename": "/packages/pug-lexer/test/cases/code.conditionals.pug", "start": Object { "column": 1, "line": 42, }, }, "type": "else", "val": "", }, Object { "loc": Object { "end": Object { "column": 3, "line": 43, }, "filename": "/packages/pug-lexer/test/cases/code.conditionals.pug", "start": Object { "column": 1, "line": 43, }, }, "type": "indent", "val": 2, }, Object { "loc": Object { "end": Object { "column": 7, "line": 43, }, "filename": "/packages/pug-lexer/test/cases/code.conditionals.pug", "start": Object { "column": 3, "line": 43, }, }, "type": "class", "val": "foo", }, Object { "loc": Object { "end": Object { "column": 7, "line": 43, }, "filename": "/packages/pug-lexer/test/cases/code.conditionals.pug", "start": Object { "column": 7, "line": 43, }, }, "type": "outdent", }, Object { "loc": Object { "end": Object { "column": 7, "line": 43, }, "filename": "/packages/pug-lexer/test/cases/code.conditionals.pug", "start": Object { "column": 7, "line": 43, }, }, "type": "eos", }, ] `; exports[`code.escape.pug 1`] = ` Array [ Object { "loc": Object { "end": Object { "column": 2, "line": 1, }, "filename": "/packages/pug-lexer/test/cases/code.escape.pug", "start": Object { "column": 1, "line": 1, }, }, "type": "tag", "val": "p", }, Object { "buffer": true, "loc": Object { "end": Object { "column": 14, "line": 1, }, "filename": "/packages/pug-lexer/test/cases/code.escape.pug", "start": Object { "column": 2, "line": 1, }, }, "mustEscape": true, "type": "code", "val": "' ", }, Object { "attributeBlocks": Array [], "attrs": Array [ Object { "mustEscape": true, "name": "type", "val": "\\"text/javascript\\"", }, ], "block": Object { "filename": "includes.pug", "line": 9, "nodes": Array [ Object { "type": "Text", "val": "var STRING_SUBSTITUTIONS = { // table of character substitutions '\\\\t': '\\\\\\\\t', '\\\\r': '\\\\\\\\r', '\\\\n': '\\\\\\\\n', '\\"' : '\\\\\\\\\\"', '\\\\\\\\': '\\\\\\\\\\\\\\\\' };", }, ], "type": "Block", }, "filename": "includes.pug", "isInline": false, "line": 9, "name": "script", "selfClosing": false, "type": "Tag", }, ], "type": "Block", }, "filename": "includes.pug", "isInline": false, "line": 6, "name": "body", "selfClosing": false, "type": "Tag", }, ], "type": "Block", } `; exports[`cases from pug includes-with-ext-js.input.json 1`] = ` Object { "declaredBlocks": Object {}, "filename": "includes-with-ext-js.pug", "line": 0, "nodes": Array [ Object { "attributeBlocks": Array [], "attrs": Array [], "block": Object { "filename": "includes-with-ext-js.pug", "line": 1, "nodes": Array [ Object { "attributeBlocks": Array [], "attrs": Array [], "block": Object { "filename": "includes-with-ext-js.pug", "line": 2, "nodes": Array [ Object { "type": "Text", "val": "var x = \\"\\\\n here is some \\\\n new lined text\\"; ", }, ], "type": "Block", }, "filename": "includes-with-ext-js.pug", "isInline": true, "line": 2, "name": "code", "selfClosing": false, "type": "Tag", }, ], "type": "Block", }, "filename": "includes-with-ext-js.pug", "isInline": false, "line": 1, "name": "pre", "selfClosing": false, "type": "Tag", }, ], "type": "Block", } `; exports[`cases from pug layout.append.input.json 1`] = ` Object { "declaredBlocks": Object { "body": Array [ Object { "filename": "../fixtures/append/layout.pug", "line": 7, "mode": "replace", "name": "body", "nodes": Array [], "type": "NamedBlock", }, ], "head": Array [ Object { "filename": "../fixtures/append/layout.pug", "line": 3, "mode": "replace", "name": "head", "nodes": Array [ Object { "attributeBlocks": Array [], "attrs": Array [ Object { "mustEscape": true, "name": "src", "val": "'vendor/jquery.js'", }, ], "block": Object { "filename": "../fixtures/append/layout.pug", "line": 4, "nodes": Array [], "type": "Block", }, "filename": "../fixtures/append/layout.pug", "isInline": false, "line": 4, "name": "script", "selfClosing": false, "type": "Tag", }, Object { "attributeBlocks": Array [], "attrs": Array [ Object { "mustEscape": true, "name": "src", "val": "'vendor/caustic.js'", }, ], "block": Object { "filename": "../fixtures/append/layout.pug", "line": 5, "nodes": Array [], "type": "Block", }, "filename": "../fixtures/append/layout.pug", "isInline": false, "line": 5, "name": "script", "selfClosing": false, "type": "Tag", }, Object { "attributeBlocks": Array [], "attrs": Array [ Object { "mustEscape": true, "name": "src", "val": "'app.js'", }, ], "block": Object { "filename": "../fixtures/append/app-layout.pug", "line": 5, "nodes": Array [], "type": "Block", }, "filename": "../fixtures/append/app-layout.pug", "isInline": false, "line": 5, "name": "script", "selfClosing": false, "type": "Tag", }, Object { "attributeBlocks": Array [], "attrs": Array [ Object { "mustEscape": true, "name": "src", "val": "'foo.js'", }, ], "block": Object { "filename": "layout.append.pug", "line": 5, "nodes": Array [], "type": "Block", }, "filename": "layout.append.pug", "isInline": false, "line": 5, "name": "script", "selfClosing": false, "type": "Tag", }, Object { "attributeBlocks": Array [], "attrs": Array [ Object { "mustEscape": true, "name": "src", "val": "'bar.js'", }, ], "block": Object { "filename": "layout.append.pug", "line": 6, "nodes": Array [], "type": "Block", }, "filename": "layout.append.pug", "isInline": false, "line": 6, "name": "script", "selfClosing": false, "type": "Tag", }, ], "type": "NamedBlock", }, ], }, "filename": "../fixtures/append/layout.pug", "hasExtends": true, "line": 0, "nodes": Array [ Object { "attributeBlocks": Array [], "attrs": Array [], "block": Object { "filename": "../fixtures/append/layout.pug", "line": 2, "nodes": Array [ Object { "filename": "../fixtures/append/layout.pug", "line": 3, "mode": "replace", "name": "head", "nodes": Array [ Object { "attributeBlocks": Array [], "attrs": Array [ Object { "mustEscape": true, "name": "src", "val": "'vendor/jquery.js'", }, ], "block": Object { "filename": "../fixtures/append/layout.pug", "line": 4, "nodes": Array [], "type": "Block", }, "filename": "../fixtures/append/layout.pug", "isInline": false, "line": 4, "name": "script", "selfClosing": false, "type": "Tag", }, Object { "attributeBlocks": Array [], "attrs": Array [ Object { "mustEscape": true, "name": "src", "val": "'vendor/caustic.js'", }, ], "block": Object { "filename": "../fixtures/append/layout.pug", "line": 5, "nodes": Array [], "type": "Block", }, "filename": "../fixtures/append/layout.pug", "isInline": false, "line": 5, "name": "script", "selfClosing": false, "type": "Tag", }, Object { "attributeBlocks": Array [], "attrs": Array [ Object { "mustEscape": true, "name": "src", "val": "'app.js'", }, ], "block": Object { "filename": "../fixtures/append/app-layout.pug", "line": 5, "nodes": Array [], "type": "Block", }, "filename": "../fixtures/append/app-layout.pug", "isInline": false, "line": 5, "name": "script", "selfClosing": false, "type": "Tag", }, Object { "attributeBlocks": Array [], "attrs": Array [ Object { "mustEscape": true, "name": "src", "val": "'foo.js'", }, ], "block": Object { "filename": "layout.append.pug", "line": 5, "nodes": Array [], "type": "Block", }, "filename": "layout.append.pug", "isInline": false, "line": 5, "name": "script", "selfClosing": false, "type": "Tag", }, Object { "attributeBlocks": Array [], "attrs": Array [ Object { "mustEscape": true, "name": "src", "val": "'bar.js'", }, ], "block": Object { "filename": "layout.append.pug", "line": 6, "nodes": Array [], "type": "Block", }, "filename": "layout.append.pug", "isInline": false, "line": 6, "name": "script", "selfClosing": false, "type": "Tag", }, ], "type": "NamedBlock", }, Object { "attributeBlocks": Array [], "attrs": Array [], "block": Object { "filename": "../fixtures/append/layout.pug", "line": 6, "nodes": Array [ Object { "filename": "../fixtures/append/layout.pug", "line": 7, "mode": "replace", "name": "body", "nodes": Array [], "type": "NamedBlock", }, ], "type": "Block", }, "filename": "../fixtures/append/layout.pug", "isInline": false, "line": 6, "name": "body", "selfClosing": false, "type": "Tag", }, ], "type": "Block", }, "filename": "../fixtures/append/layout.pug", "isInline": false, "line": 2, "name": "html", "selfClosing": false, "type": "Tag", }, ], "type": "Block", } `; exports[`cases from pug layout.append.without-block.input.json 1`] = ` Object { "declaredBlocks": Object { "body": Array [ Object { "filename": "../fixtures/append-without-block/layout.pug", "line": 7, "mode": "replace", "name": "body", "nodes": Array [], "type": "NamedBlock", }, ], "head": Array [ Object { "filename": "../fixtures/append-without-block/layout.pug", "line": 3, "mode": "replace", "name": "head", "nodes": Array [ Object { "attributeBlocks": Array [], "attrs": Array [ Object { "mustEscape": true, "name": "src", "val": "'vendor/jquery.js'", }, ], "block": Object { "filename": "../fixtures/append-without-block/layout.pug", "line": 4, "nodes": Array [], "type": "Block", }, "filename": "../fixtures/append-without-block/layout.pug", "isInline": false, "line": 4, "name": "script", "selfClosing": false, "type": "Tag", }, Object { "attributeBlocks": Array [], "attrs": Array [ Object { "mustEscape": true, "name": "src", "val": "'vendor/caustic.js'", }, ], "block": Object { "filename": "../fixtures/append-without-block/layout.pug", "line": 5, "nodes": Array [], "type": "Block", }, "filename": "../fixtures/append-without-block/layout.pug", "isInline": false, "line": 5, "name": "script", "selfClosing": false, "type": "Tag", }, Object { "attributeBlocks": Array [], "attrs": Array [ Object { "mustEscape": true, "name": "src", "val": "'app.js'", }, ], "block": Object { "filename": "../fixtures/append-without-block/app-layout.pug", "line": 5, "nodes": Array [], "type": "Block", }, "filename": "../fixtures/append-without-block/app-layout.pug", "isInline": false, "line": 5, "name": "script", "selfClosing": false, "type": "Tag", }, Object { "attributeBlocks": Array [], "attrs": Array [ Object { "mustEscape": true, "name": "src", "val": "'foo.js'", }, ], "block": Object { "filename": "layout.append.without-block.pug", "line": 5, "nodes": Array [], "type": "Block", }, "filename": "layout.append.without-block.pug", "isInline": false, "line": 5, "name": "script", "selfClosing": false, "type": "Tag", }, Object { "attributeBlocks": Array [], "attrs": Array [ Object { "mustEscape": true, "name": "src", "val": "'bar.js'", }, ], "block": Object { "filename": "layout.append.without-block.pug", "line": 6, "nodes": Array [], "type": "Block", }, "filename": "layout.append.without-block.pug", "isInline": false, "line": 6, "name": "script", "selfClosing": false, "type": "Tag", }, ], "type": "NamedBlock", }, ], }, "filename": "../fixtures/append-without-block/layout.pug", "hasExtends": true, "line": 0, "nodes": Array [ Object { "attributeBlocks": Array [], "attrs": Array [], "block": Object { "filename": "../fixtures/append-without-block/layout.pug", "line": 2, "nodes": Array [ Object { "filename": "../fixtures/append-without-block/layout.pug", "line": 3, "mode": "replace", "name": "head", "nodes": Array [ Object { "attributeBlocks": Array [], "attrs": Array [ Object { "mustEscape": true, "name": "src", "val": "'vendor/jquery.js'", }, ], "block": Object { "filename": "../fixtures/append-without-block/layout.pug", "line": 4, "nodes": Array [], "type": "Block", }, "filename": "../fixtures/append-without-block/layout.pug", "isInline": false, "line": 4, "name": "script", "selfClosing": false, "type": "Tag", }, Object { "attributeBlocks": Array [], "attrs": Array [ Object { "mustEscape": true, "name": "src", "val": "'vendor/caustic.js'", }, ], "block": Object { "filename": "../fixtures/append-without-block/layout.pug", "line": 5, "nodes": Array [], "type": "Block", }, "filename": "../fixtures/append-without-block/layout.pug", "isInline": false, "line": 5, "name": "script", "selfClosing": false, "type": "Tag", }, Object { "attributeBlocks": Array [], "attrs": Array [ Object { "mustEscape": true, "name": "src", "val": "'app.js'", }, ], "block": Object { "filename": "../fixtures/append-without-block/app-layout.pug", "line": 5, "nodes": Array [], "type": "Block", }, "filename": "../fixtures/append-without-block/app-layout.pug", "isInline": false, "line": 5, "name": "script", "selfClosing": false, "type": "Tag", }, Object { "attributeBlocks": Array [], "attrs": Array [ Object { "mustEscape": true, "name": "src", "val": "'foo.js'", }, ], "block": Object { "filename": "layout.append.without-block.pug", "line": 5, "nodes": Array [], "type": "Block", }, "filename": "layout.append.without-block.pug", "isInline": false, "line": 5, "name": "script", "selfClosing": false, "type": "Tag", }, Object { "attributeBlocks": Array [], "attrs": Array [ Object { "mustEscape": true, "name": "src", "val": "'bar.js'", }, ], "block": Object { "filename": "layout.append.without-block.pug", "line": 6, "nodes": Array [], "type": "Block", }, "filename": "layout.append.without-block.pug", "isInline": false, "line": 6, "name": "script", "selfClosing": false, "type": "Tag", }, ], "type": "NamedBlock", }, Object { "attributeBlocks": Array [], "attrs": Array [], "block": Object { "filename": "../fixtures/append-without-block/layout.pug", "line": 6, "nodes": Array [ Object { "filename": "../fixtures/append-without-block/layout.pug", "line": 7, "mode": "replace", "name": "body", "nodes": Array [], "type": "NamedBlock", }, ], "type": "Block", }, "filename": "../fixtures/append-without-block/layout.pug", "isInline": false, "line": 6, "name": "body", "selfClosing": false, "type": "Tag", }, ], "type": "Block", }, "filename": "../fixtures/append-without-block/layout.pug", "isInline": false, "line": 2, "name": "html", "selfClosing": false, "type": "Tag", }, ], "type": "Block", } `; exports[`cases from pug layout.multi.append.prepend.block.input.json 1`] = ` Object { "declaredBlocks": Object { "content": Array [ Object { "filename": "../fixtures/multi-append-prepend-block/redefine.pug", "line": 3, "mode": "replace", "name": "content", "nodes": Array [ Object { "attributeBlocks": Array [], "attrs": Array [ Object { "mustEscape": false, "name": "class", "val": "'last'", }, Object { "mustEscape": false, "name": "class", "val": "'prepend'", }, ], "block": Object { "filename": "layout.multi.append.prepend.block.pug", "line": 13, "nodes": Array [ Object { "filename": "layout.multi.append.prepend.block.pug", "line": 13, "type": "Text", "val": "Last prepend must appear at top", }, ], "type": "Block", }, "filename": "layout.multi.append.prepend.block.pug", "isInline": false, "line": 13, "name": "p", "selfClosing": false, "type": "Tag", }, Object { "attributeBlocks": Array [], "attrs": Array [ Object { "mustEscape": false, "name": "class", "val": "'first'", }, Object { "mustEscape": false, "name": "class", "val": "'prepend'", }, ], "block": Object { "filename": "layout.multi.append.prepend.block.pug", "line": 7, "nodes": Array [ Object { "filename": "layout.multi.append.prepend.block.pug", "line": 7, "type": "Text", "val": "Something prepended to content", }, ], "type": "Block", }, "filename": "layout.multi.append.prepend.block.pug", "isInline": false, "line": 7, "name": "p", "selfClosing": false, "type": "Tag", }, Object { "attributeBlocks": Array [], "attrs": Array [ Object { "mustEscape": false, "name": "class", "val": "'content'", }, ], "block": Object { "filename": "../fixtures/multi-append-prepend-block/redefine.pug", "line": 4, "nodes": Array [ Object { "filename": "../fixtures/multi-append-prepend-block/redefine.pug", "line": 5, "type": "Text", "val": "Defined content", }, ], "type": "Block", }, "filename": "../fixtures/multi-append-prepend-block/redefine.pug", "isInline": false, "line": 4, "name": "div", "selfClosing": false, "type": "Tag", }, Object { "attributeBlocks": Array [], "attrs": Array [ Object { "mustEscape": false, "name": "class", "val": "'first'", }, Object { "mustEscape": false, "name": "class", "val": "'append'", }, ], "block": Object { "filename": "layout.multi.append.prepend.block.pug", "line": 4, "nodes": Array [ Object { "filename": "layout.multi.append.prepend.block.pug", "line": 4, "type": "Text", "val": "Something appended to content", }, ], "type": "Block", }, "filename": "layout.multi.append.prepend.block.pug", "isInline": false, "line": 4, "name": "p", "selfClosing": false, "type": "Tag", }, Object { "attributeBlocks": Array [], "attrs": Array [ Object { "mustEscape": false, "name": "class", "val": "'last'", }, Object { "mustEscape": false, "name": "class", "val": "'append'", }, ], "block": Object { "filename": "layout.multi.append.prepend.block.pug", "line": 10, "nodes": Array [ Object { "filename": "layout.multi.append.prepend.block.pug", "line": 10, "type": "Text", "val": "Last append must be most last", }, ], "type": "Block", }, "filename": "layout.multi.append.prepend.block.pug", "isInline": false, "line": 10, "name": "p", "selfClosing": false, "type": "Tag", }, ], "parents": Array [ Object { "filename": "../fixtures/multi-append-prepend-block/root.pug", "line": 1, "mode": "replace", "name": "content", "nodes": Array [ Object { "attributeBlocks": Array [], "attrs": Array [ Object { "mustEscape": false, "name": "class", "val": "'last'", }, Object { "mustEscape": false, "name": "class", "val": "'prepend'", }, ], "block": Object { "filename": "layout.multi.append.prepend.block.pug", "line": 13, "nodes": Array [ Object { "filename": "layout.multi.append.prepend.block.pug", "line": 13, "type": "Text", "val": "Last prepend must appear at top", }, ], "type": "Block", }, "filename": "layout.multi.append.prepend.block.pug", "isInline": false, "line": 13, "name": "p", "selfClosing": false, "type": "Tag", }, Object { "attributeBlocks": Array [], "attrs": Array [ Object { "mustEscape": false, "name": "class", "val": "'first'", }, Object { "mustEscape": false, "name": "class", "val": "'prepend'", }, ], "block": Object { "filename": "layout.multi.append.prepend.block.pug", "line": 7, "nodes": Array [ Object { "filename": "layout.multi.append.prepend.block.pug", "line": 7, "type": "Text", "val": "Something prepended to content", }, ], "type": "Block", }, "filename": "layout.multi.append.prepend.block.pug", "isInline": false, "line": 7, "name": "p", "selfClosing": false, "type": "Tag", }, Object { "attributeBlocks": Array [], "attrs": Array [ Object { "mustEscape": false, "name": "class", "val": "'content'", }, ], "block": Object { "filename": "../fixtures/multi-append-prepend-block/redefine.pug", "line": 4, "nodes": Array [ Object { "filename": "../fixtures/multi-append-prepend-block/redefine.pug", "line": 5, "type": "Text", "val": "Defined content", }, ], "type": "Block", }, "filename": "../fixtures/multi-append-prepend-block/redefine.pug", "isInline": false, "line": 4, "name": "div", "selfClosing": false, "type": "Tag", }, Object { "attributeBlocks": Array [], "attrs": Array [ Object { "mustEscape": false, "name": "class", "val": "'first'", }, Object { "mustEscape": false, "name": "class", "val": "'append'", }, ], "block": Object { "filename": "layout.multi.append.prepend.block.pug", "line": 4, "nodes": Array [ Object { "filename": "layout.multi.append.prepend.block.pug", "line": 4, "type": "Text", "val": "Something appended to content", }, ], "type": "Block", }, "filename": "layout.multi.append.prepend.block.pug", "isInline": false, "line": 4, "name": "p", "selfClosing": false, "type": "Tag", }, Object { "attributeBlocks": Array [], "attrs": Array [ Object { "mustEscape": false, "name": "class", "val": "'last'", }, Object { "mustEscape": false, "name": "class", "val": "'append'", }, ], "block": Object { "filename": "layout.multi.append.prepend.block.pug", "line": 10, "nodes": Array [ Object { "filename": "layout.multi.append.prepend.block.pug", "line": 10, "type": "Text", "val": "Last append must be most last", }, ], "type": "Block", }, "filename": "layout.multi.append.prepend.block.pug", "isInline": false, "line": 10, "name": "p", "selfClosing": false, "type": "Tag", }, ], "type": "NamedBlock", }, ], "type": "NamedBlock", }, ], "head": Array [ Object { "filename": "../fixtures/multi-append-prepend-block/root.pug", "line": 4, "mode": "replace", "name": "head", "nodes": Array [ Object { "attributeBlocks": Array [], "attrs": Array [ Object { "mustEscape": true, "name": "src", "val": "'foo.js'", }, ], "block": Object { "filename": "layout.multi.append.prepend.block.pug", "line": 19, "nodes": Array [], "type": "Block", }, "filename": "layout.multi.append.prepend.block.pug", "isInline": false, "line": 19, "name": "script", "selfClosing": false, "type": "Tag", }, Object { "attributeBlocks": Array [], "attrs": Array [ Object { "mustEscape": true, "name": "src", "val": "'/app.js'", }, ], "block": Object { "filename": "../fixtures/multi-append-prepend-block/root.pug", "line": 5, "nodes": Array [], "type": "Block", }, "filename": "../fixtures/multi-append-prepend-block/root.pug", "isInline": false, "line": 5, "name": "script", "selfClosing": false, "type": "Tag", }, Object { "attributeBlocks": Array [], "attrs": Array [ Object { "mustEscape": true, "name": "src", "val": "'jquery.js'", }, ], "block": Object { "filename": "layout.multi.append.prepend.block.pug", "line": 16, "nodes": Array [], "type": "Block", }, "filename": "layout.multi.append.prepend.block.pug", "isInline": false, "line": 16, "name": "script", "selfClosing": false, "type": "Tag", }, ], "type": "NamedBlock", }, ], }, "filename": "../fixtures/multi-append-prepend-block/root.pug", "hasExtends": true, "line": 0, "nodes": Array [ Object { "filename": "../fixtures/multi-append-prepend-block/root.pug", "line": 1, "mode": "replace", "name": "content", "nodes": Array [ Object { "attributeBlocks": Array [], "attrs": Array [ Object { "mustEscape": false, "name": "class", "val": "'last'", }, Object { "mustEscape": false, "name": "class", "val": "'prepend'", }, ], "block": Object { "filename": "layout.multi.append.prepend.block.pug", "line": 13, "nodes": Array [ Object { "filename": "layout.multi.append.prepend.block.pug", "line": 13, "type": "Text", "val": "Last prepend must appear at top", }, ], "type": "Block", }, "filename": "layout.multi.append.prepend.block.pug", "isInline": false, "line": 13, "name": "p", "selfClosing": false, "type": "Tag", }, Object { "attributeBlocks": Array [], "attrs": Array [ Object { "mustEscape": false, "name": "class", "val": "'first'", }, Object { "mustEscape": false, "name": "class", "val": "'prepend'", }, ], "block": Object { "filename": "layout.multi.append.prepend.block.pug", "line": 7, "nodes": Array [ Object { "filename": "layout.multi.append.prepend.block.pug", "line": 7, "type": "Text", "val": "Something prepended to content", }, ], "type": "Block", }, "filename": "layout.multi.append.prepend.block.pug", "isInline": false, "line": 7, "name": "p", "selfClosing": false, "type": "Tag", }, Object { "attributeBlocks": Array [], "attrs": Array [ Object { "mustEscape": false, "name": "class", "val": "'content'", }, ], "block": Object { "filename": "../fixtures/multi-append-prepend-block/redefine.pug", "line": 4, "nodes": Array [ Object { "filename": "../fixtures/multi-append-prepend-block/redefine.pug", "line": 5, "type": "Text", "val": "Defined content", }, ], "type": "Block", }, "filename": "../fixtures/multi-append-prepend-block/redefine.pug", "isInline": false, "line": 4, "name": "div", "selfClosing": false, "type": "Tag", }, Object { "attributeBlocks": Array [], "attrs": Array [ Object { "mustEscape": false, "name": "class", "val": "'first'", }, Object { "mustEscape": false, "name": "class", "val": "'append'", }, ], "block": Object { "filename": "layout.multi.append.prepend.block.pug", "line": 4, "nodes": Array [ Object { "filename": "layout.multi.append.prepend.block.pug", "line": 4, "type": "Text", "val": "Something appended to content", }, ], "type": "Block", }, "filename": "layout.multi.append.prepend.block.pug", "isInline": false, "line": 4, "name": "p", "selfClosing": false, "type": "Tag", }, Object { "attributeBlocks": Array [], "attrs": Array [ Object { "mustEscape": false, "name": "class", "val": "'last'", }, Object { "mustEscape": false, "name": "class", "val": "'append'", }, ], "block": Object { "filename": "layout.multi.append.prepend.block.pug", "line": 10, "nodes": Array [ Object { "filename": "layout.multi.append.prepend.block.pug", "line": 10, "type": "Text", "val": "Last append must be most last", }, ], "type": "Block", }, "filename": "layout.multi.append.prepend.block.pug", "isInline": false, "line": 10, "name": "p", "selfClosing": false, "type": "Tag", }, ], "type": "NamedBlock", }, Object { "filename": "../fixtures/multi-append-prepend-block/root.pug", "line": 4, "mode": "replace", "name": "head", "nodes": Array [ Object { "attributeBlocks": Array [], "attrs": Array [ Object { "mustEscape": true, "name": "src", "val": "'foo.js'", }, ], "block": Object { "filename": "layout.multi.append.prepend.block.pug", "line": 19, "nodes": Array [], "type": "Block", }, "filename": "layout.multi.append.prepend.block.pug", "isInline": false, "line": 19, "name": "script", "selfClosing": false, "type": "Tag", }, Object { "attributeBlocks": Array [], "attrs": Array [ Object { "mustEscape": true, "name": "src", "val": "'/app.js'", }, ], "block": Object { "filename": "../fixtures/multi-append-prepend-block/root.pug", "line": 5, "nodes": Array [], "type": "Block", }, "filename": "../fixtures/multi-append-prepend-block/root.pug", "isInline": false, "line": 5, "name": "script", "selfClosing": false, "type": "Tag", }, Object { "attributeBlocks": Array [], "attrs": Array [ Object { "mustEscape": true, "name": "src", "val": "'jquery.js'", }, ], "block": Object { "filename": "layout.multi.append.prepend.block.pug", "line": 16, "nodes": Array [], "type": "Block", }, "filename": "layout.multi.append.prepend.block.pug", "isInline": false, "line": 16, "name": "script", "selfClosing": false, "type": "Tag", }, ], "type": "NamedBlock", }, ], "type": "Block", } `; exports[`cases from pug layout.prepend.input.json 1`] = ` Object { "declaredBlocks": Object { "body": Array [ Object { "filename": "../fixtures/prepend/layout.pug", "line": 7, "mode": "replace", "name": "body", "nodes": Array [], "type": "NamedBlock", }, ], "head": Array [ Object { "filename": "../fixtures/prepend/layout.pug", "line": 3, "mode": "replace", "name": "head", "nodes": Array [ Object { "attributeBlocks": Array [], "attrs": Array [ Object { "mustEscape": true, "name": "src", "val": "'foo.js'", }, ], "block": Object { "filename": "layout.prepend.pug", "line": 5, "nodes": Array [], "type": "Block", }, "filename": "layout.prepend.pug", "isInline": false, "line": 5, "name": "script", "selfClosing": false, "type": "Tag", }, Object { "attributeBlocks": Array [], "attrs": Array [ Object { "mustEscape": true, "name": "src", "val": "'bar.js'", }, ], "block": Object { "filename": "layout.prepend.pug", "line": 6, "nodes": Array [], "type": "Block", }, "filename": "layout.prepend.pug", "isInline": false, "line": 6, "name": "script", "selfClosing": false, "type": "Tag", }, Object { "attributeBlocks": Array [], "attrs": Array [ Object { "mustEscape": true, "name": "src", "val": "'app.js'", }, ], "block": Object { "filename": "../fixtures/prepend/app-layout.pug", "line": 5, "nodes": Array [], "type": "Block", }, "filename": "../fixtures/prepend/app-layout.pug", "isInline": false, "line": 5, "name": "script", "selfClosing": false, "type": "Tag", }, Object { "attributeBlocks": Array [], "attrs": Array [ Object { "mustEscape": true, "name": "src", "val": "'vendor/jquery.js'", }, ], "block": Object { "filename": "../fixtures/prepend/layout.pug", "line": 4, "nodes": Array [], "type": "Block", }, "filename": "../fixtures/prepend/layout.pug", "isInline": false, "line": 4, "name": "script", "selfClosing": false, "type": "Tag", }, Object { "attributeBlocks": Array [], "attrs": Array [ Object { "mustEscape": true, "name": "src", "val": "'vendor/caustic.js'", }, ], "block": Object { "filename": "../fixtures/prepend/layout.pug", "line": 5, "nodes": Array [], "type": "Block", }, "filename": "../fixtures/prepend/layout.pug", "isInline": false, "line": 5, "name": "script", "selfClosing": false, "type": "Tag", }, ], "type": "NamedBlock", }, ], }, "filename": "../fixtures/prepend/layout.pug", "hasExtends": true, "line": 0, "nodes": Array [ Object { "attributeBlocks": Array [], "attrs": Array [], "block": Object { "filename": "../fixtures/prepend/layout.pug", "line": 2, "nodes": Array [ Object { "filename": "../fixtures/prepend/layout.pug", "line": 3, "mode": "replace", "name": "head", "nodes": Array [ Object { "attributeBlocks": Array [], "attrs": Array [ Object { "mustEscape": true, "name": "src", "val": "'foo.js'", }, ], "block": Object { "filename": "layout.prepend.pug", "line": 5, "nodes": Array [], "type": "Block", }, "filename": "layout.prepend.pug", "isInline": false, "line": 5, "name": "script", "selfClosing": false, "type": "Tag", }, Object { "attributeBlocks": Array [], "attrs": Array [ Object { "mustEscape": true, "name": "src", "val": "'bar.js'", }, ], "block": Object { "filename": "layout.prepend.pug", "line": 6, "nodes": Array [], "type": "Block", }, "filename": "layout.prepend.pug", "isInline": false, "line": 6, "name": "script", "selfClosing": false, "type": "Tag", }, Object { "attributeBlocks": Array [], "attrs": Array [ Object { "mustEscape": true, "name": "src", "val": "'app.js'", }, ], "block": Object { "filename": "../fixtures/prepend/app-layout.pug", "line": 5, "nodes": Array [], "type": "Block", }, "filename": "../fixtures/prepend/app-layout.pug", "isInline": false, "line": 5, "name": "script", "selfClosing": false, "type": "Tag", }, Object { "attributeBlocks": Array [], "attrs": Array [ Object { "mustEscape": true, "name": "src", "val": "'vendor/jquery.js'", }, ], "block": Object { "filename": "../fixtures/prepend/layout.pug", "line": 4, "nodes": Array [], "type": "Block", }, "filename": "../fixtures/prepend/layout.pug", "isInline": false, "line": 4, "name": "script", "selfClosing": false, "type": "Tag", }, Object { "attributeBlocks": Array [], "attrs": Array [ Object { "mustEscape": true, "name": "src", "val": "'vendor/caustic.js'", }, ], "block": Object { "filename": "../fixtures/prepend/layout.pug", "line": 5, "nodes": Array [], "type": "Block", }, "filename": "../fixtures/prepend/layout.pug", "isInline": false, "line": 5, "name": "script", "selfClosing": false, "type": "Tag", }, ], "type": "NamedBlock", }, Object { "attributeBlocks": Array [], "attrs": Array [], "block": Object { "filename": "../fixtures/prepend/layout.pug", "line": 6, "nodes": Array [ Object { "filename": "../fixtures/prepend/layout.pug", "line": 7, "mode": "replace", "name": "body", "nodes": Array [], "type": "NamedBlock", }, ], "type": "Block", }, "filename": "../fixtures/prepend/layout.pug", "isInline": false, "line": 6, "name": "body", "selfClosing": false, "type": "Tag", }, ], "type": "Block", }, "filename": "../fixtures/prepend/layout.pug", "isInline": false, "line": 2, "name": "html", "selfClosing": false, "type": "Tag", }, ], "type": "Block", } `; exports[`cases from pug layout.prepend.without-block.input.json 1`] = ` Object { "declaredBlocks": Object { "body": Array [ Object { "filename": "../fixtures/prepend-without-block/layout.pug", "line": 7, "mode": "replace", "name": "body", "nodes": Array [], "type": "NamedBlock", }, ], "head": Array [ Object { "filename": "../fixtures/prepend-without-block/layout.pug", "line": 3, "mode": "replace", "name": "head", "nodes": Array [ Object { "attributeBlocks": Array [], "attrs": Array [ Object { "mustEscape": true, "name": "src", "val": "'foo.js'", }, ], "block": Object { "filename": "layout.prepend.without-block.pug", "line": 5, "nodes": Array [], "type": "Block", }, "filename": "layout.prepend.without-block.pug", "isInline": false, "line": 5, "name": "script", "selfClosing": false, "type": "Tag", }, Object { "attributeBlocks": Array [], "attrs": Array [ Object { "mustEscape": true, "name": "src", "val": "'bar.js'", }, ], "block": Object { "filename": "layout.prepend.without-block.pug", "line": 6, "nodes": Array [], "type": "Block", }, "filename": "layout.prepend.without-block.pug", "isInline": false, "line": 6, "name": "script", "selfClosing": false, "type": "Tag", }, Object { "attributeBlocks": Array [], "attrs": Array [ Object { "mustEscape": true, "name": "src", "val": "'app.js'", }, ], "block": Object { "filename": "../fixtures/prepend-without-block/app-layout.pug", "line": 5, "nodes": Array [], "type": "Block", }, "filename": "../fixtures/prepend-without-block/app-layout.pug", "isInline": false, "line": 5, "name": "script", "selfClosing": false, "type": "Tag", }, Object { "attributeBlocks": Array [], "attrs": Array [ Object { "mustEscape": true, "name": "src", "val": "'vendor/jquery.js'", }, ], "block": Object { "filename": "../fixtures/prepend-without-block/layout.pug", "line": 4, "nodes": Array [], "type": "Block", }, "filename": "../fixtures/prepend-without-block/layout.pug", "isInline": false, "line": 4, "name": "script", "selfClosing": false, "type": "Tag", }, Object { "attributeBlocks": Array [], "attrs": Array [ Object { "mustEscape": true, "name": "src", "val": "'vendor/caustic.js'", }, ], "block": Object { "filename": "../fixtures/prepend-without-block/layout.pug", "line": 5, "nodes": Array [], "type": "Block", }, "filename": "../fixtures/prepend-without-block/layout.pug", "isInline": false, "line": 5, "name": "script", "selfClosing": false, "type": "Tag", }, ], "type": "NamedBlock", }, ], }, "filename": "../fixtures/prepend-without-block/layout.pug", "hasExtends": true, "line": 0, "nodes": Array [ Object { "attributeBlocks": Array [], "attrs": Array [], "block": Object { "filename": "../fixtures/prepend-without-block/layout.pug", "line": 2, "nodes": Array [ Object { "filename": "../fixtures/prepend-without-block/layout.pug", "line": 3, "mode": "replace", "name": "head", "nodes": Array [ Object { "attributeBlocks": Array [], "attrs": Array [ Object { "mustEscape": true, "name": "src", "val": "'foo.js'", }, ], "block": Object { "filename": "layout.prepend.without-block.pug", "line": 5, "nodes": Array [], "type": "Block", }, "filename": "layout.prepend.without-block.pug", "isInline": false, "line": 5, "name": "script", "selfClosing": false, "type": "Tag", }, Object { "attributeBlocks": Array [], "attrs": Array [ Object { "mustEscape": true, "name": "src", "val": "'bar.js'", }, ], "block": Object { "filename": "layout.prepend.without-block.pug", "line": 6, "nodes": Array [], "type": "Block", }, "filename": "layout.prepend.without-block.pug", "isInline": false, "line": 6, "name": "script", "selfClosing": false, "type": "Tag", }, Object { "attributeBlocks": Array [], "attrs": Array [ Object { "mustEscape": true, "name": "src", "val": "'app.js'", }, ], "block": Object { "filename": "../fixtures/prepend-without-block/app-layout.pug", "line": 5, "nodes": Array [], "type": "Block", }, "filename": "../fixtures/prepend-without-block/app-layout.pug", "isInline": false, "line": 5, "name": "script", "selfClosing": false, "type": "Tag", }, Object { "attributeBlocks": Array [], "attrs": Array [ Object { "mustEscape": true, "name": "src", "val": "'vendor/jquery.js'", }, ], "block": Object { "filename": "../fixtures/prepend-without-block/layout.pug", "line": 4, "nodes": Array [], "type": "Block", }, "filename": "../fixtures/prepend-without-block/layout.pug", "isInline": false, "line": 4, "name": "script", "selfClosing": false, "type": "Tag", }, Object { "attributeBlocks": Array [], "attrs": Array [ Object { "mustEscape": true, "name": "src", "val": "'vendor/caustic.js'", }, ], "block": Object { "filename": "../fixtures/prepend-without-block/layout.pug", "line": 5, "nodes": Array [], "type": "Block", }, "filename": "../fixtures/prepend-without-block/layout.pug", "isInline": false, "line": 5, "name": "script", "selfClosing": false, "type": "Tag", }, ], "type": "NamedBlock", }, Object { "attributeBlocks": Array [], "attrs": Array [], "block": Object { "filename": "../fixtures/prepend-without-block/layout.pug", "line": 6, "nodes": Array [ Object { "filename": "../fixtures/prepend-without-block/layout.pug", "line": 7, "mode": "replace", "name": "body", "nodes": Array [], "type": "NamedBlock", }, ], "type": "Block", }, "filename": "../fixtures/prepend-without-block/layout.pug", "isInline": false, "line": 6, "name": "body", "selfClosing": false, "type": "Tag", }, ], "type": "Block", }, "filename": "../fixtures/prepend-without-block/layout.pug", "isInline": false, "line": 2, "name": "html", "selfClosing": false, "type": "Tag", }, ], "type": "Block", } `; exports[`error handling child-with-tags.input.json 1`] = ` Object { "code": "PUG:UNEXPECTED_NODES_IN_EXTENDING_ROOT", "line": 6, "msg": "Only named blocks and mixins can appear at the top level of an extending template", } `; exports[`error handling extends-not-first.input.json 1`] = ` Object { "code": "PUG:EXTENDS_NOT_FIRST", "line": 4, "msg": "Declaration of template inheritance (\\"extends\\") should be the first thing in the file. There can only be one extends statement per file.", } `; exports[`error handling unexpected-block.input.json 1`] = ` Object { "code": "PUG:UNEXPECTED_BLOCK", "line": 3, "msg": "Unexpected block foo", } `; exports[`special cases extending-empty.input.json 1`] = ` Object { "declaredBlocks": Object {}, "filename": "../fixtures/empty.pug", "hasExtends": true, "line": 0, "nodes": Array [], "type": "Block", } `; exports[`special cases extending-include.input.json 1`] = ` Object { "declaredBlocks": Object { "body": Array [ Object { "filename": "extending-include.pug", "line": 4, "mode": "replace", "name": "body", "nodes": Array [ Object { "args": "'myimg.png'", "attributeBlocks": Array [], "attrs": Array [ Object { "mustEscape": false, "name": "class", "val": "'with-border'", }, Object { "mustEscape": true, "name": "alt", "val": "\\"My image\\"", }, ], "block": null, "call": true, "filename": "extending-include.pug", "line": 5, "name": "image", "type": "Mixin", }, ], "parents": Array [ Object { "filename": "../fixtures/layout.pug", "line": 8, "mode": "replace", "name": "body", "nodes": Array [ Object { "args": "'myimg.png'", "attributeBlocks": Array [], "attrs": Array [ Object { "mustEscape": false, "name": "class", "val": "'with-border'", }, Object { "mustEscape": true, "name": "alt", "val": "\\"My image\\"", }, ], "block": null, "call": true, "filename": "extending-include.pug", "line": 5, "name": "image", "type": "Mixin", }, ], "type": "NamedBlock", }, ], "type": "NamedBlock", }, ], "head": Array [ Object { "filename": "../fixtures/layout.pug", "line": 5, "mode": "replace", "name": "head", "nodes": Array [ Object { "filename": "../fixtures/layout.pug", "isHtml": true, "line": 6, "type": "Text", "val": "Hello world!", }, ], "type": "NamedBlock", }, ], }, "filename": "../fixtures/layout.pug", "hasExtends": true, "line": 0, "nodes": Array [ Object { "args": "src", "block": Object { "filename": "../fixtures/mixins.pug", "line": 2, "nodes": Array [ Object { "attributeBlocks": Array [ "attributes", ], "attrs": Array [ Object { "mustEscape": true, "name": "cl-src", "val": "src", }, ], "block": Object { "filename": "../fixtures/mixins.pug", "line": 2, "nodes": Array [], "type": "Block", }, "filename": "../fixtures/mixins.pug", "isInline": true, "line": 2, "name": "img", "selfClosing": false, "type": "Tag", }, ], "type": "Block", }, "call": false, "filename": "../fixtures/mixins.pug", "line": 1, "name": "image", "type": "Mixin", }, Object { "filename": "../fixtures/layout.pug", "line": 1, "type": "Doctype", "val": "", }, Object { "attributeBlocks": Array [], "attrs": Array [], "block": Object { "filename": "../fixtures/layout.pug", "line": 3, "nodes": Array [ Object { "attributeBlocks": Array [], "attrs": Array [], "block": Object { "filename": "../fixtures/layout.pug", "line": 4, "nodes": Array [ Object { "filename": "../fixtures/layout.pug", "line": 5, "mode": "replace", "name": "head", "nodes": Array [ Object { "filename": "../fixtures/layout.pug", "isHtml": true, "line": 6, "type": "Text", "val": "Hello world!", }, ], "type": "NamedBlock", }, ], "type": "Block", }, "filename": "../fixtures/layout.pug", "isInline": false, "line": 4, "name": "head", "selfClosing": false, "type": "Tag", }, Object { "attributeBlocks": Array [], "attrs": Array [], "block": Object { "filename": "../fixtures/layout.pug", "line": 7, "nodes": Array [ Object { "filename": "../fixtures/layout.pug", "line": 8, "mode": "replace", "name": "body", "nodes": Array [ Object { "args": "'myimg.png'", "attributeBlocks": Array [], "attrs": Array [ Object { "mustEscape": false, "name": "class", "val": "'with-border'", }, Object { "mustEscape": true, "name": "alt", "val": "\\"My image\\"", }, ], "block": null, "call": true, "filename": "extending-include.pug", "line": 5, "name": "image", "type": "Mixin", }, ], "type": "NamedBlock", }, ], "type": "Block", }, "filename": "../fixtures/layout.pug", "isInline": false, "line": 7, "name": "body", "selfClosing": false, "type": "Tag", }, ], "type": "Block", }, "filename": "../fixtures/layout.pug", "isInline": false, "line": 3, "name": "html", "selfClosing": false, "type": "Tag", }, ], "type": "Block", } `; exports[`special cases root-mixin.input.json 1`] = ` Object { "declaredBlocks": Object { "body": Array [ Object { "filename": "root-mixin.pug", "line": 6, "mode": "replace", "name": "body", "nodes": Array [ Object { "attributeBlocks": Array [], "attrs": Array [], "block": Object { "filename": "root-mixin.pug", "line": 7, "nodes": Array [ Object { "filename": "root-mixin.pug", "line": 7, "type": "Text", "val": "Before", }, ], "type": "Block", }, "filename": "root-mixin.pug", "isInline": false, "line": 7, "name": "p", "selfClosing": false, "type": "Tag", }, Object { "args": null, "attributeBlocks": Array [], "attrs": Array [], "block": null, "call": true, "filename": "root-mixin.pug", "line": 8, "name": "myMixin", "type": "Mixin", }, Object { "attributeBlocks": Array [], "attrs": Array [], "block": Object { "filename": "root-mixin.pug", "line": 9, "nodes": Array [ Object { "filename": "root-mixin.pug", "line": 9, "type": "Text", "val": "After", }, ], "type": "Block", }, "filename": "root-mixin.pug", "isInline": false, "line": 9, "name": "p", "selfClosing": false, "type": "Tag", }, ], "parents": Array [ Object { "filename": "../fixtures/layout.pug", "line": 8, "mode": "replace", "name": "body", "nodes": Array [ Object { "attributeBlocks": Array [], "attrs": Array [], "block": Object { "filename": "root-mixin.pug", "line": 7, "nodes": Array [ Object { "filename": "root-mixin.pug", "line": 7, "type": "Text", "val": "Before", }, ], "type": "Block", }, "filename": "root-mixin.pug", "isInline": false, "line": 7, "name": "p", "selfClosing": false, "type": "Tag", }, Object { "args": null, "attributeBlocks": Array [], "attrs": Array [], "block": null, "call": true, "filename": "root-mixin.pug", "line": 8, "name": "myMixin", "type": "Mixin", }, Object { "attributeBlocks": Array [], "attrs": Array [], "block": Object { "filename": "root-mixin.pug", "line": 9, "nodes": Array [ Object { "filename": "root-mixin.pug", "line": 9, "type": "Text", "val": "After", }, ], "type": "Block", }, "filename": "root-mixin.pug", "isInline": false, "line": 9, "name": "p", "selfClosing": false, "type": "Tag", }, ], "type": "NamedBlock", }, ], "type": "NamedBlock", }, ], "head": Array [ Object { "filename": "../fixtures/layout.pug", "line": 5, "mode": "replace", "name": "head", "nodes": Array [ Object { "filename": "../fixtures/layout.pug", "isHtml": true, "line": 6, "type": "Text", "val": "Hello world!", }, ], "type": "NamedBlock", }, ], }, "filename": "../fixtures/layout.pug", "hasExtends": true, "line": 0, "nodes": Array [ Object { "args": null, "block": Object { "filename": "root-mixin.pug", "line": 4, "nodes": Array [ Object { "attributeBlocks": Array [], "attrs": Array [], "block": Object { "filename": "root-mixin.pug", "line": 4, "nodes": Array [ Object { "filename": "root-mixin.pug", "line": 4, "type": "Text", "val": "Hello world", }, ], "type": "Block", }, "filename": "root-mixin.pug", "isInline": false, "line": 4, "name": "p", "selfClosing": false, "type": "Tag", }, ], "type": "Block", }, "call": false, "filename": "root-mixin.pug", "line": 3, "name": "myMixin", "type": "Mixin", }, Object { "filename": "../fixtures/layout.pug", "line": 1, "type": "Doctype", "val": "", }, Object { "attributeBlocks": Array [], "attrs": Array [], "block": Object { "filename": "../fixtures/layout.pug", "line": 3, "nodes": Array [ Object { "attributeBlocks": Array [], "attrs": Array [], "block": Object { "filename": "../fixtures/layout.pug", "line": 4, "nodes": Array [ Object { "filename": "../fixtures/layout.pug", "line": 5, "mode": "replace", "name": "head", "nodes": Array [ Object { "filename": "../fixtures/layout.pug", "isHtml": true, "line": 6, "type": "Text", "val": "Hello world!", }, ], "type": "NamedBlock", }, ], "type": "Block", }, "filename": "../fixtures/layout.pug", "isInline": false, "line": 4, "name": "head", "selfClosing": false, "type": "Tag", }, Object { "attributeBlocks": Array [], "attrs": Array [], "block": Object { "filename": "../fixtures/layout.pug", "line": 7, "nodes": Array [ Object { "filename": "../fixtures/layout.pug", "line": 8, "mode": "replace", "name": "body", "nodes": Array [ Object { "attributeBlocks": Array [], "attrs": Array [], "block": Object { "filename": "root-mixin.pug", "line": 7, "nodes": Array [ Object { "filename": "root-mixin.pug", "line": 7, "type": "Text", "val": "Before", }, ], "type": "Block", }, "filename": "root-mixin.pug", "isInline": false, "line": 7, "name": "p", "selfClosing": false, "type": "Tag", }, Object { "args": null, "attributeBlocks": Array [], "attrs": Array [], "block": null, "call": true, "filename": "root-mixin.pug", "line": 8, "name": "myMixin", "type": "Mixin", }, Object { "attributeBlocks": Array [], "attrs": Array [], "block": Object { "filename": "root-mixin.pug", "line": 9, "nodes": Array [ Object { "filename": "root-mixin.pug", "line": 9, "type": "Text", "val": "After", }, ], "type": "Block", }, "filename": "root-mixin.pug", "isInline": false, "line": 9, "name": "p", "selfClosing": false, "type": "Tag", }, ], "type": "NamedBlock", }, ], "type": "Block", }, "filename": "../fixtures/layout.pug", "isInline": false, "line": 7, "name": "body", "selfClosing": false, "type": "Tag", }, ], "type": "Block", }, "filename": "../fixtures/layout.pug", "isInline": false, "line": 3, "name": "html", "selfClosing": false, "type": "Tag", }, ], "type": "Block", } `; ================================================ FILE: packages/pug-linker/test/cases/include-extends-from-root.input.json ================================================ { "type": "Block", "nodes": [ { "type": "Include", "file": { "type": "FileReference", "line": 1, "filename": "include-extends-from-root.pug", "path": "/auxiliary/extends-from-root.pug", "fullPath": "auxiliary/extends-from-root.pug", "str": "extends /auxiliary/layout.pug\n\nblock content\n include /auxiliary/include-from-root.pug\n", "ast": { "type": "Block", "nodes": [ { "type": "Extends", "file": { "type": "FileReference", "path": "/auxiliary/layout.pug", "line": 1, "filename": "auxiliary/extends-from-root.pug", "fullPath": "auxiliary/layout.pug", "str": "html\n head\n title My Application\n block head\n body\n block content", "ast": { "type": "Block", "nodes": [ { "type": "Tag", "name": "html", "selfClosing": false, "block": { "type": "Block", "nodes": [ { "type": "Tag", "name": "head", "selfClosing": false, "block": { "type": "Block", "nodes": [ { "type": "Tag", "name": "title", "selfClosing": false, "block": { "type": "Block", "nodes": [ { "type": "Text", "val": "My Application", "line": 3, "filename": "auxiliary/layout.pug" } ], "line": 3, "filename": "auxiliary/layout.pug" }, "attrs": [], "attributeBlocks": [], "isInline": false, "line": 3, "filename": "auxiliary/layout.pug" }, { "type": "NamedBlock", "nodes": [], "line": 4, "filename": "auxiliary/layout.pug", "name": "head", "mode": "replace" } ], "line": 2, "filename": "auxiliary/layout.pug" }, "attrs": [], "attributeBlocks": [], "isInline": false, "line": 2, "filename": "auxiliary/layout.pug" }, { "type": "Tag", "name": "body", "selfClosing": false, "block": { "type": "Block", "nodes": [ { "type": "NamedBlock", "nodes": [], "line": 6, "filename": "auxiliary/layout.pug", "name": "content", "mode": "replace" } ], "line": 5, "filename": "auxiliary/layout.pug" }, "attrs": [], "attributeBlocks": [], "isInline": false, "line": 5, "filename": "auxiliary/layout.pug" } ], "line": 1, "filename": "auxiliary/layout.pug" }, "attrs": [], "attributeBlocks": [], "isInline": false, "line": 1, "filename": "auxiliary/layout.pug" } ], "line": 0, "filename": "auxiliary/layout.pug" } }, "line": 1, "filename": "auxiliary/extends-from-root.pug" }, { "type": "NamedBlock", "nodes": [ { "type": "Include", "file": { "type": "FileReference", "line": 4, "filename": "auxiliary/extends-from-root.pug", "path": "/auxiliary/include-from-root.pug", "fullPath": "auxiliary/include-from-root.pug", "str": "h1 hello", "ast": { "type": "Block", "nodes": [ { "type": "Tag", "name": "h1", "selfClosing": false, "block": { "type": "Block", "nodes": [ { "type": "Text", "val": "hello", "line": 1, "filename": "auxiliary/include-from-root.pug" } ], "line": 1, "filename": "auxiliary/include-from-root.pug" }, "attrs": [], "attributeBlocks": [], "isInline": false, "line": 1, "filename": "auxiliary/include-from-root.pug" } ], "line": 0, "filename": "auxiliary/include-from-root.pug" } }, "line": 4, "filename": "auxiliary/extends-from-root.pug", "block": { "type": "Block", "nodes": [], "line": 4, "filename": "auxiliary/extends-from-root.pug" } } ], "line": 3, "filename": "auxiliary/extends-from-root.pug", "name": "content", "mode": "replace" } ], "line": 0, "filename": "auxiliary/extends-from-root.pug" } }, "line": 1, "filename": "include-extends-from-root.pug", "block": { "type": "Block", "nodes": [], "line": 1, "filename": "include-extends-from-root.pug" } } ], "line": 0, "filename": "include-extends-from-root.pug" } ================================================ FILE: packages/pug-linker/test/cases/include-extends-of-common-template.input.json ================================================ { "type": "Block", "nodes": [ { "type": "Include", "file": { "type": "FileReference", "line": 1, "filename": "include-extends-of-common-template.pug", "path": "auxiliary/extends-empty-block-1.pug", "fullPath": "auxiliary/extends-empty-block-1.pug", "str": "extends empty-block.pug\n\nblock test\n div test1\n\n", "ast": { "type": "Block", "nodes": [ { "type": "Extends", "file": { "type": "FileReference", "path": "empty-block.pug", "line": 1, "filename": "auxiliary/extends-empty-block-1.pug", "fullPath": "auxiliary/empty-block.pug", "str": "block test\n\n", "ast": { "type": "Block", "nodes": [ { "type": "NamedBlock", "nodes": [], "line": 1, "filename": "auxiliary/empty-block.pug", "name": "test", "mode": "replace" } ], "line": 0, "filename": "auxiliary/empty-block.pug" } }, "line": 1, "filename": "auxiliary/extends-empty-block-1.pug" }, { "type": "NamedBlock", "nodes": [ { "type": "Tag", "name": "div", "selfClosing": false, "block": { "type": "Block", "nodes": [ { "type": "Text", "val": "test1", "line": 4, "filename": "auxiliary/extends-empty-block-1.pug" } ], "line": 4, "filename": "auxiliary/extends-empty-block-1.pug" }, "attrs": [], "attributeBlocks": [], "isInline": false, "line": 4, "filename": "auxiliary/extends-empty-block-1.pug" } ], "line": 3, "filename": "auxiliary/extends-empty-block-1.pug", "name": "test", "mode": "replace" } ], "line": 0, "filename": "auxiliary/extends-empty-block-1.pug" } }, "line": 1, "filename": "include-extends-of-common-template.pug", "block": { "type": "Block", "nodes": [], "line": 1, "filename": "include-extends-of-common-template.pug" } }, { "type": "Include", "file": { "type": "FileReference", "line": 2, "filename": "include-extends-of-common-template.pug", "path": "auxiliary/extends-empty-block-2.pug", "fullPath": "auxiliary/extends-empty-block-2.pug", "str": "extends empty-block.pug\n\nblock test\n div test2\n\n", "ast": { "type": "Block", "nodes": [ { "type": "Extends", "file": { "type": "FileReference", "path": "empty-block.pug", "line": 1, "filename": "auxiliary/extends-empty-block-2.pug", "fullPath": "auxiliary/empty-block.pug", "str": "block test\n\n", "ast": { "type": "Block", "nodes": [ { "type": "NamedBlock", "nodes": [], "line": 1, "filename": "auxiliary/empty-block.pug", "name": "test", "mode": "replace" } ], "line": 0, "filename": "auxiliary/empty-block.pug" } }, "line": 1, "filename": "auxiliary/extends-empty-block-2.pug" }, { "type": "NamedBlock", "nodes": [ { "type": "Tag", "name": "div", "selfClosing": false, "block": { "type": "Block", "nodes": [ { "type": "Text", "val": "test2", "line": 4, "filename": "auxiliary/extends-empty-block-2.pug" } ], "line": 4, "filename": "auxiliary/extends-empty-block-2.pug" }, "attrs": [], "attributeBlocks": [], "isInline": false, "line": 4, "filename": "auxiliary/extends-empty-block-2.pug" } ], "line": 3, "filename": "auxiliary/extends-empty-block-2.pug", "name": "test", "mode": "replace" } ], "line": 0, "filename": "auxiliary/extends-empty-block-2.pug" } }, "line": 2, "filename": "include-extends-of-common-template.pug", "block": { "type": "Block", "nodes": [], "line": 2, "filename": "include-extends-of-common-template.pug" } } ], "line": 0, "filename": "include-extends-of-common-template.pug" } ================================================ FILE: packages/pug-linker/test/cases/include-extends-relative.input.json ================================================ { "type": "Block", "nodes": [ { "type": "Include", "file": { "type": "FileReference", "line": 1, "filename": "include-extends-relative.pug", "path": "../cases-src/auxiliary/extends-relative.pug", "fullPath": "../cases-src/auxiliary/extends-relative.pug", "str": "extends ../../cases-src/auxiliary/layout\n\nblock content\n include ../../cases-src/auxiliary/include-from-root\n", "ast": { "type": "Block", "nodes": [ { "type": "Extends", "file": { "type": "FileReference", "path": "../../cases-src/auxiliary/layout", "line": 1, "filename": "../cases-src/auxiliary/extends-relative.pug", "fullPath": "../cases-src/auxiliary/layout.pug", "str": "html\n head\n title My Application\n block head\n body\n block content", "ast": { "type": "Block", "nodes": [ { "type": "Tag", "name": "html", "selfClosing": false, "block": { "type": "Block", "nodes": [ { "type": "Tag", "name": "head", "selfClosing": false, "block": { "type": "Block", "nodes": [ { "type": "Tag", "name": "title", "selfClosing": false, "block": { "type": "Block", "nodes": [ { "type": "Text", "val": "My Application", "line": 3, "filename": "../cases-src/auxiliary/layout.pug" } ], "line": 3, "filename": "../cases-src/auxiliary/layout.pug" }, "attrs": [], "attributeBlocks": [], "isInline": false, "line": 3, "filename": "../cases-src/auxiliary/layout.pug" }, { "type": "NamedBlock", "nodes": [], "line": 4, "filename": "../cases-src/auxiliary/layout.pug", "name": "head", "mode": "replace" } ], "line": 2, "filename": "../cases-src/auxiliary/layout.pug" }, "attrs": [], "attributeBlocks": [], "isInline": false, "line": 2, "filename": "../cases-src/auxiliary/layout.pug" }, { "type": "Tag", "name": "body", "selfClosing": false, "block": { "type": "Block", "nodes": [ { "type": "NamedBlock", "nodes": [], "line": 6, "filename": "../cases-src/auxiliary/layout.pug", "name": "content", "mode": "replace" } ], "line": 5, "filename": "../cases-src/auxiliary/layout.pug" }, "attrs": [], "attributeBlocks": [], "isInline": false, "line": 5, "filename": "../cases-src/auxiliary/layout.pug" } ], "line": 1, "filename": "../cases-src/auxiliary/layout.pug" }, "attrs": [], "attributeBlocks": [], "isInline": false, "line": 1, "filename": "../cases-src/auxiliary/layout.pug" } ], "line": 0, "filename": "../cases-src/auxiliary/layout.pug" } }, "line": 1, "filename": "../cases-src/auxiliary/extends-relative.pug" }, { "type": "NamedBlock", "nodes": [ { "type": "RawInclude", "file": { "type": "FileReference", "line": 4, "filename": "../cases-src/auxiliary/extends-relative.pug", "path": "../../cases-src/auxiliary/include-from-root", "fullPath": "../cases-src/auxiliary/include-from-root.pug", "str": "h1 hello" }, "line": 4, "filename": "../cases-src/auxiliary/extends-relative.pug", "filters": [] } ], "line": 3, "filename": "../cases-src/auxiliary/extends-relative.pug", "name": "content", "mode": "replace" } ], "line": 0, "filename": "../cases-src/auxiliary/extends-relative.pug" } }, "line": 1, "filename": "include-extends-relative.pug", "block": { "type": "Block", "nodes": [], "line": 1, "filename": "include-extends-relative.pug" } } ], "line": 0, "filename": "include-extends-relative.pug" } ================================================ FILE: packages/pug-linker/test/cases/include-filter-stylus.input.json ================================================ { "type": "Block", "nodes": [ { "type": "Tag", "name": "style", "selfClosing": false, "block": { "type": "Block", "nodes": [ { "type": "RawInclude", "file": { "type": "FileReference", "line": 2, "filename": "include-filter-stylus.pug", "path": "some.styl", "fullPath": "some.styl", "str": "@import \"some-included\"\n" }, "line": 2, "filename": "include-filter-stylus.pug", "filters": [ { "type": "IncludeFilter", "name": "stylus", "attrs": [], "line": 2, "filename": "include-filter-stylus.pug" } ] } ], "line": 1, "filename": "include-filter-stylus.pug" }, "attrs": [ { "name": "type", "val": "\"text/css\"", "mustEscape": true } ], "attributeBlocks": [], "isInline": false, "line": 1, "filename": "include-filter-stylus.pug" } ], "line": 0, "filename": "include-filter-stylus.pug" } ================================================ FILE: packages/pug-linker/test/cases/include-filter.input.json ================================================ { "type": "Block", "nodes": [ { "type": "Tag", "name": "html", "selfClosing": false, "block": { "type": "Block", "nodes": [ { "type": "Tag", "name": "body", "selfClosing": false, "block": { "type": "Block", "nodes": [ { "type": "RawInclude", "file": { "type": "FileReference", "line": 3, "filename": "include-filter.pug", "path": "some.md", "fullPath": "some.md", "str": "Just _some_ markdown **tests**.\n\nWith new line.\n" }, "line": 3, "filename": "include-filter.pug", "filters": [ { "type": "IncludeFilter", "name": "markdown-it", "attrs": [], "line": 3, "filename": "include-filter.pug" } ] }, { "type": "Tag", "name": "script", "selfClosing": false, "block": { "type": "Block", "nodes": [ { "type": "RawInclude", "file": { "type": "FileReference", "line": 5, "filename": "include-filter.pug", "path": "include-filter-coffee.coffee", "fullPath": "include-filter-coffee.coffee", "str": "math =\n square: (value) -> value * value\n" }, "line": 5, "filename": "include-filter.pug", "filters": [ { "type": "IncludeFilter", "name": "coffee-script", "attrs": [ { "name": "minify", "val": "true", "mustEscape": true } ], "line": 5, "filename": "include-filter.pug" } ] } ], "line": 4, "filename": "include-filter.pug" }, "attrs": [], "attributeBlocks": [], "isInline": false, "line": 4, "filename": "include-filter.pug" }, { "type": "Tag", "name": "script", "selfClosing": false, "block": { "type": "Block", "nodes": [ { "type": "RawInclude", "file": { "type": "FileReference", "line": 7, "filename": "include-filter.pug", "path": "include-filter-coffee.coffee", "fullPath": "include-filter-coffee.coffee", "str": "math =\n square: (value) -> value * value\n" }, "line": 7, "filename": "include-filter.pug", "filters": [ { "type": "IncludeFilter", "name": "coffee-script", "attrs": [ { "name": "minify", "val": "false", "mustEscape": true } ], "line": 7, "filename": "include-filter.pug" } ] } ], "line": 6, "filename": "include-filter.pug" }, "attrs": [], "attributeBlocks": [], "isInline": false, "line": 6, "filename": "include-filter.pug" } ], "line": 2, "filename": "include-filter.pug" }, "attrs": [], "attributeBlocks": [], "isInline": false, "line": 2, "filename": "include-filter.pug" } ], "line": 1, "filename": "include-filter.pug" }, "attrs": [], "attributeBlocks": [], "isInline": false, "line": 1, "filename": "include-filter.pug" } ], "line": 0, "filename": "include-filter.pug" } ================================================ FILE: packages/pug-linker/test/cases/include-only-text-body.input.json ================================================ { "type": "Block", "nodes": [ { "type": "Text", "val": "The message is \"", "line": 1, "filename": "include-only-text-body.pug" }, { "type": "YieldBlock", "line": 2, "filename": "include-only-text-body.pug" }, { "type": "Text", "val": "\"", "line": 3, "filename": "include-only-text-body.pug" } ], "line": 0, "filename": "include-only-text-body.pug" } ================================================ FILE: packages/pug-linker/test/cases/include-only-text.input.json ================================================ { "type": "Block", "nodes": [ { "type": "Tag", "name": "html", "selfClosing": false, "block": { "type": "Block", "nodes": [ { "type": "Tag", "name": "body", "selfClosing": false, "block": { "type": "Block", "nodes": [ { "type": "Tag", "name": "p", "selfClosing": false, "block": { "type": "Block", "nodes": [ { "type": "Include", "file": { "type": "FileReference", "line": 4, "filename": "include-only-text.pug", "path": "include-only-text-body.pug", "fullPath": "include-only-text-body.pug", "str": "| The message is \"\nyield\n| \"\n", "ast": { "type": "Block", "nodes": [ { "type": "Text", "val": "The message is \"", "line": 1, "filename": "include-only-text-body.pug" }, { "type": "YieldBlock", "line": 2, "filename": "include-only-text-body.pug" }, { "type": "Text", "val": "\"", "line": 3, "filename": "include-only-text-body.pug" } ], "line": 0, "filename": "include-only-text-body.pug" } }, "line": 4, "filename": "include-only-text.pug", "block": { "type": "Block", "nodes": [ { "type": "Tag", "name": "em", "selfClosing": false, "block": { "type": "Block", "nodes": [ { "type": "Text", "val": "hello world", "line": 5, "filename": "include-only-text.pug" } ], "line": 5, "filename": "include-only-text.pug" }, "attrs": [], "attributeBlocks": [], "isInline": true, "line": 5, "filename": "include-only-text.pug" } ], "line": 5, "filename": "include-only-text.pug" } } ], "line": 3, "filename": "include-only-text.pug" }, "attrs": [], "attributeBlocks": [], "isInline": false, "line": 3, "filename": "include-only-text.pug" } ], "line": 2, "filename": "include-only-text.pug" }, "attrs": [], "attributeBlocks": [], "isInline": false, "line": 2, "filename": "include-only-text.pug" } ], "line": 1, "filename": "include-only-text.pug" }, "attrs": [], "attributeBlocks": [], "isInline": false, "line": 1, "filename": "include-only-text.pug" } ], "line": 0, "filename": "include-only-text.pug" } ================================================ FILE: packages/pug-linker/test/cases/include-with-text-head.input.json ================================================ { "type": "Block", "nodes": [ { "type": "Tag", "name": "head", "selfClosing": false, "block": { "type": "Block", "nodes": [ { "type": "Tag", "name": "script", "selfClosing": false, "block": { "type": "Block", "nodes": [ { "type": "Text", "val": "alert('hello world');", "line": 3 } ], "line": 2, "filename": "include-with-text-head.pug" }, "attrs": [ { "name": "type", "val": "'text/javascript'", "mustEscape": true } ], "attributeBlocks": [], "isInline": false, "line": 2, "filename": "include-with-text-head.pug", "textOnly": true } ], "line": 1, "filename": "include-with-text-head.pug" }, "attrs": [], "attributeBlocks": [], "isInline": false, "line": 1, "filename": "include-with-text-head.pug" } ], "line": 0, "filename": "include-with-text-head.pug" } ================================================ FILE: packages/pug-linker/test/cases/include-with-text.input.json ================================================ { "type": "Block", "nodes": [ { "type": "Tag", "name": "html", "selfClosing": false, "block": { "type": "Block", "nodes": [ { "type": "Include", "file": { "type": "FileReference", "line": 2, "filename": "include-with-text.pug", "path": "include-with-text-head.pug", "fullPath": "include-with-text-head.pug", "str": "head\n script(type='text/javascript').\n alert('hello world');\n", "ast": { "type": "Block", "nodes": [ { "type": "Tag", "name": "head", "selfClosing": false, "block": { "type": "Block", "nodes": [ { "type": "Tag", "name": "script", "selfClosing": false, "block": { "type": "Block", "nodes": [ { "type": "Text", "val": "alert('hello world');", "line": 3 } ], "line": 2, "filename": "include-with-text-head.pug" }, "attrs": [ { "name": "type", "val": "'text/javascript'", "mustEscape": true } ], "attributeBlocks": [], "isInline": false, "line": 2, "filename": "include-with-text-head.pug", "textOnly": true } ], "line": 1, "filename": "include-with-text-head.pug" }, "attrs": [], "attributeBlocks": [], "isInline": false, "line": 1, "filename": "include-with-text-head.pug" } ], "line": 0, "filename": "include-with-text-head.pug" } }, "line": 2, "filename": "include-with-text.pug", "block": { "type": "Block", "nodes": [ { "type": "Tag", "name": "script", "selfClosing": false, "block": { "type": "Block", "nodes": [], "line": 3, "filename": "include-with-text.pug" }, "attrs": [ { "name": "src", "val": "'/caustic.js'", "mustEscape": true } ], "attributeBlocks": [], "isInline": false, "line": 3, "filename": "include-with-text.pug" }, { "type": "Tag", "name": "script", "selfClosing": false, "block": { "type": "Block", "nodes": [], "line": 4, "filename": "include-with-text.pug" }, "attrs": [ { "name": "src", "val": "'/app.js'", "mustEscape": true } ], "attributeBlocks": [], "isInline": false, "line": 4, "filename": "include-with-text.pug" } ], "line": 3, "filename": "include-with-text.pug" } } ], "line": 1, "filename": "include-with-text.pug" }, "attrs": [], "attributeBlocks": [], "isInline": false, "line": 1, "filename": "include-with-text.pug" } ], "line": 0, "filename": "include-with-text.pug" } ================================================ FILE: packages/pug-linker/test/cases/include.script.input.json ================================================ { "type": "Block", "nodes": [ { "type": "Tag", "name": "script", "selfClosing": false, "block": { "type": "Block", "nodes": [ { "type": "Include", "file": { "type": "FileReference", "line": 2, "filename": "include.script.pug", "path": "auxiliary/pet.pug", "fullPath": "auxiliary/pet.pug", "str": ".pet\n h1 {{name}}\n p {{name}} is a {{species}} that is {{age}} old", "ast": { "type": "Block", "nodes": [ { "type": "Tag", "name": "div", "selfClosing": false, "block": { "type": "Block", "nodes": [ { "type": "Tag", "name": "h1", "selfClosing": false, "block": { "type": "Block", "nodes": [ { "type": "Text", "val": "{{name}}", "line": 2, "filename": "auxiliary/pet.pug" } ], "line": 2, "filename": "auxiliary/pet.pug" }, "attrs": [], "attributeBlocks": [], "isInline": false, "line": 2, "filename": "auxiliary/pet.pug" }, { "type": "Tag", "name": "p", "selfClosing": false, "block": { "type": "Block", "nodes": [ { "type": "Text", "val": "{{name}} is a {{species}} that is {{age}} old", "line": 3, "filename": "auxiliary/pet.pug" } ], "line": 3, "filename": "auxiliary/pet.pug" }, "attrs": [], "attributeBlocks": [], "isInline": false, "line": 3, "filename": "auxiliary/pet.pug" } ], "line": 1, "filename": "auxiliary/pet.pug" }, "attrs": [ { "name": "class", "val": "'pet'", "mustEscape": false } ], "attributeBlocks": [], "isInline": false, "line": 1, "filename": "auxiliary/pet.pug" } ], "line": 0, "filename": "auxiliary/pet.pug" } }, "line": 2, "filename": "include.script.pug", "block": { "type": "Block", "nodes": [], "line": 2, "filename": "include.script.pug" } } ], "line": 1, "filename": "include.script.pug" }, "attrs": [ { "name": "id", "val": "'pet-template'", "mustEscape": false }, { "name": "type", "val": "'text/x-template'", "mustEscape": true } ], "attributeBlocks": [], "isInline": false, "line": 1, "filename": "include.script.pug" } ], "line": 0, "filename": "include.script.pug" } ================================================ FILE: packages/pug-linker/test/cases/include.yield.nested.input.json ================================================ { "type": "Block", "nodes": [ { "type": "Include", "file": { "type": "FileReference", "line": 2, "filename": "include.yield.nested.pug", "path": "auxiliary/yield-nested.pug", "fullPath": "auxiliary/yield-nested.pug", "str": "html\n head\n title\n body\n h1 Page\n #content\n #content-wrapper\n yield\n #footer\n stuff", "ast": { "type": "Block", "nodes": [ { "type": "Tag", "name": "html", "selfClosing": false, "block": { "type": "Block", "nodes": [ { "type": "Tag", "name": "head", "selfClosing": false, "block": { "type": "Block", "nodes": [ { "type": "Tag", "name": "title", "selfClosing": false, "block": { "type": "Block", "nodes": [], "line": 3, "filename": "auxiliary/yield-nested.pug" }, "attrs": [], "attributeBlocks": [], "isInline": false, "line": 3, "filename": "auxiliary/yield-nested.pug" } ], "line": 2, "filename": "auxiliary/yield-nested.pug" }, "attrs": [], "attributeBlocks": [], "isInline": false, "line": 2, "filename": "auxiliary/yield-nested.pug" }, { "type": "Tag", "name": "body", "selfClosing": false, "block": { "type": "Block", "nodes": [ { "type": "Tag", "name": "h1", "selfClosing": false, "block": { "type": "Block", "nodes": [ { "type": "Text", "val": "Page", "line": 5, "filename": "auxiliary/yield-nested.pug" } ], "line": 5, "filename": "auxiliary/yield-nested.pug" }, "attrs": [], "attributeBlocks": [], "isInline": false, "line": 5, "filename": "auxiliary/yield-nested.pug" }, { "type": "Tag", "name": "div", "selfClosing": false, "block": { "type": "Block", "nodes": [ { "type": "Tag", "name": "div", "selfClosing": false, "block": { "type": "Block", "nodes": [ { "type": "YieldBlock", "line": 8, "filename": "auxiliary/yield-nested.pug" } ], "line": 7, "filename": "auxiliary/yield-nested.pug" }, "attrs": [ { "name": "id", "val": "'content-wrapper'", "mustEscape": false } ], "attributeBlocks": [], "isInline": false, "line": 7, "filename": "auxiliary/yield-nested.pug" } ], "line": 6, "filename": "auxiliary/yield-nested.pug" }, "attrs": [ { "name": "id", "val": "'content'", "mustEscape": false } ], "attributeBlocks": [], "isInline": false, "line": 6, "filename": "auxiliary/yield-nested.pug" }, { "type": "Tag", "name": "div", "selfClosing": false, "block": { "type": "Block", "nodes": [ { "type": "Tag", "name": "stuff", "selfClosing": false, "block": { "type": "Block", "nodes": [], "line": 10, "filename": "auxiliary/yield-nested.pug" }, "attrs": [], "attributeBlocks": [], "isInline": false, "line": 10, "filename": "auxiliary/yield-nested.pug" } ], "line": 9, "filename": "auxiliary/yield-nested.pug" }, "attrs": [ { "name": "id", "val": "'footer'", "mustEscape": false } ], "attributeBlocks": [], "isInline": false, "line": 9, "filename": "auxiliary/yield-nested.pug" } ], "line": 4, "filename": "auxiliary/yield-nested.pug" }, "attrs": [], "attributeBlocks": [], "isInline": false, "line": 4, "filename": "auxiliary/yield-nested.pug" } ], "line": 1, "filename": "auxiliary/yield-nested.pug" }, "attrs": [], "attributeBlocks": [], "isInline": false, "line": 1, "filename": "auxiliary/yield-nested.pug" } ], "line": 0, "filename": "auxiliary/yield-nested.pug" } }, "line": 2, "filename": "include.yield.nested.pug", "block": { "type": "Block", "nodes": [ { "type": "Tag", "name": "p", "selfClosing": false, "block": { "type": "Block", "nodes": [ { "type": "Text", "val": "some content", "line": 3, "filename": "include.yield.nested.pug" } ], "line": 3, "filename": "include.yield.nested.pug" }, "attrs": [], "attributeBlocks": [], "isInline": false, "line": 3, "filename": "include.yield.nested.pug" }, { "type": "Tag", "name": "p", "selfClosing": false, "block": { "type": "Block", "nodes": [ { "type": "Text", "val": "and some more", "line": 4, "filename": "include.yield.nested.pug" } ], "line": 4, "filename": "include.yield.nested.pug" }, "attrs": [], "attributeBlocks": [], "isInline": false, "line": 4, "filename": "include.yield.nested.pug" } ], "line": 3, "filename": "include.yield.nested.pug" } } ], "line": 0, "filename": "include.yield.nested.pug" } ================================================ FILE: packages/pug-linker/test/cases/includes-with-ext-js.input.json ================================================ { "type": "Block", "nodes": [ { "type": "Tag", "name": "pre", "selfClosing": false, "block": { "type": "Block", "nodes": [ { "type": "Tag", "name": "code", "selfClosing": false, "block": { "type": "Block", "nodes": [ { "type": "RawInclude", "file": { "type": "FileReference", "line": 3, "filename": "includes-with-ext-js.pug", "path": "javascript-new-lines.js", "fullPath": "javascript-new-lines.js", "str": "var x = \"\\n here is some \\n new lined text\";\n" }, "line": 3, "filename": "includes-with-ext-js.pug", "filters": [] } ], "line": 2, "filename": "includes-with-ext-js.pug" }, "attrs": [], "attributeBlocks": [], "isInline": true, "line": 2, "filename": "includes-with-ext-js.pug" } ], "line": 1, "filename": "includes-with-ext-js.pug" }, "attrs": [], "attributeBlocks": [], "isInline": false, "line": 1, "filename": "includes-with-ext-js.pug" } ], "line": 0, "filename": "includes-with-ext-js.pug" } ================================================ FILE: packages/pug-linker/test/cases/includes.input.json ================================================ { "type": "Block", "nodes": [ { "type": "Include", "file": { "type": "FileReference", "line": 2, "filename": "includes.pug", "path": "auxiliary/mixins.pug", "fullPath": "auxiliary/mixins.pug", "str": "\nmixin foo()\n p bar", "ast": { "type": "Block", "nodes": [ { "type": "Mixin", "name": "foo", "args": null, "block": { "type": "Block", "nodes": [ { "type": "Tag", "name": "p", "selfClosing": false, "block": { "type": "Block", "nodes": [ { "type": "Text", "val": "bar", "line": 3, "filename": "auxiliary/mixins.pug" } ], "line": 3, "filename": "auxiliary/mixins.pug" }, "attrs": [], "attributeBlocks": [], "isInline": false, "line": 3, "filename": "auxiliary/mixins.pug" } ], "line": 3, "filename": "auxiliary/mixins.pug" }, "call": false, "line": 2, "filename": "auxiliary/mixins.pug" } ], "line": 0, "filename": "auxiliary/mixins.pug" } }, "line": 2, "filename": "includes.pug", "block": { "type": "Block", "nodes": [], "line": 2, "filename": "includes.pug" } }, { "type": "Mixin", "name": "foo", "args": null, "block": null, "call": true, "attrs": [], "attributeBlocks": [], "line": 4, "filename": "includes.pug" }, { "type": "Tag", "name": "body", "selfClosing": false, "block": { "type": "Block", "nodes": [ { "type": "RawInclude", "file": { "type": "FileReference", "line": 7, "filename": "includes.pug", "path": "auxiliary/smile.html", "fullPath": "auxiliary/smile.html", "str": "

    :)

    \n" }, "line": 7, "filename": "includes.pug", "filters": [] }, { "type": "RawInclude", "file": { "type": "FileReference", "line": 8, "filename": "includes.pug", "path": "auxiliary/escapes.html", "fullPath": "auxiliary/escapes.html", "str": "\n" }, "line": 8, "filename": "includes.pug", "filters": [] }, { "type": "Tag", "name": "script", "selfClosing": false, "block": { "type": "Block", "nodes": [ { "type": "RawInclude", "file": { "type": "FileReference", "line": 10, "filename": "includes.pug", "path": "auxiliary/includable.js", "fullPath": "auxiliary/includable.js", "str": "var STRING_SUBSTITUTIONS = { // table of character substitutions\n '\\t': '\\\\t',\n '\\r': '\\\\r',\n '\\n': '\\\\n',\n '\"' : '\\\\\"',\n '\\\\': '\\\\\\\\'\n};" }, "line": 10, "filename": "includes.pug", "filters": [ { "type": "IncludeFilter", "name": "verbatim", "attrs": [], "line": 10, "filename": "includes.pug" } ] } ], "line": 9, "filename": "includes.pug" }, "attrs": [ { "name": "type", "val": "\"text/javascript\"", "mustEscape": true } ], "attributeBlocks": [], "isInline": false, "line": 9, "filename": "includes.pug" } ], "line": 6, "filename": "includes.pug" }, "attrs": [], "attributeBlocks": [], "isInline": false, "line": 6, "filename": "includes.pug" } ], "line": 0, "filename": "includes.pug" } ================================================ FILE: packages/pug-linker/test/cases/layout.append.input.json ================================================ { "type": "Block", "nodes": [ { "type": "Extends", "file": { "type": "FileReference", "path": "../fixtures/append/app-layout.pug", "line": 2, "filename": "layout.append.pug", "fullPath": "../fixtures/append/app-layout.pug", "str": "\nextends layout\n\nblock append head\n script(src='app.js')", "ast": { "type": "Block", "nodes": [ { "type": "Extends", "file": { "type": "FileReference", "path": "layout", "line": 2, "filename": "../fixtures/append/app-layout.pug", "fullPath": "../fixtures/append/layout.pug", "str": "\nhtml\n block head\n script(src='vendor/jquery.js')\n script(src='vendor/caustic.js')\n body\n block body", "ast": { "type": "Block", "nodes": [ { "type": "Tag", "name": "html", "selfClosing": false, "block": { "type": "Block", "nodes": [ { "type": "NamedBlock", "nodes": [ { "type": "Tag", "name": "script", "selfClosing": false, "block": { "type": "Block", "nodes": [], "line": 4, "filename": "../fixtures/append/layout.pug" }, "attrs": [ { "name": "src", "val": "'vendor/jquery.js'", "mustEscape": true } ], "attributeBlocks": [], "isInline": false, "line": 4, "filename": "../fixtures/append/layout.pug" }, { "type": "Tag", "name": "script", "selfClosing": false, "block": { "type": "Block", "nodes": [], "line": 5, "filename": "../fixtures/append/layout.pug" }, "attrs": [ { "name": "src", "val": "'vendor/caustic.js'", "mustEscape": true } ], "attributeBlocks": [], "isInline": false, "line": 5, "filename": "../fixtures/append/layout.pug" } ], "line": 3, "filename": "../fixtures/append/layout.pug", "name": "head", "mode": "replace" }, { "type": "Tag", "name": "body", "selfClosing": false, "block": { "type": "Block", "nodes": [ { "type": "NamedBlock", "nodes": [], "line": 7, "filename": "../fixtures/append/layout.pug", "name": "body", "mode": "replace" } ], "line": 6, "filename": "../fixtures/append/layout.pug" }, "attrs": [], "attributeBlocks": [], "isInline": false, "line": 6, "filename": "../fixtures/append/layout.pug" } ], "line": 2, "filename": "../fixtures/append/layout.pug" }, "attrs": [], "attributeBlocks": [], "isInline": false, "line": 2, "filename": "../fixtures/append/layout.pug" } ], "line": 0, "filename": "../fixtures/append/layout.pug" } }, "line": 2, "filename": "../fixtures/append/app-layout.pug" }, { "type": "NamedBlock", "nodes": [ { "type": "Tag", "name": "script", "selfClosing": false, "block": { "type": "Block", "nodes": [], "line": 5, "filename": "../fixtures/append/app-layout.pug" }, "attrs": [ { "name": "src", "val": "'app.js'", "mustEscape": true } ], "attributeBlocks": [], "isInline": false, "line": 5, "filename": "../fixtures/append/app-layout.pug" } ], "line": 4, "filename": "../fixtures/append/app-layout.pug", "name": "head", "mode": "append" } ], "line": 0, "filename": "../fixtures/append/app-layout.pug" } }, "line": 2, "filename": "layout.append.pug" }, { "type": "NamedBlock", "nodes": [ { "type": "Tag", "name": "script", "selfClosing": false, "block": { "type": "Block", "nodes": [], "line": 5, "filename": "layout.append.pug" }, "attrs": [ { "name": "src", "val": "'foo.js'", "mustEscape": true } ], "attributeBlocks": [], "isInline": false, "line": 5, "filename": "layout.append.pug" }, { "type": "Tag", "name": "script", "selfClosing": false, "block": { "type": "Block", "nodes": [], "line": 6, "filename": "layout.append.pug" }, "attrs": [ { "name": "src", "val": "'bar.js'", "mustEscape": true } ], "attributeBlocks": [], "isInline": false, "line": 6, "filename": "layout.append.pug" } ], "line": 4, "filename": "layout.append.pug", "name": "head", "mode": "append" } ], "line": 0, "filename": "layout.append.pug" } ================================================ FILE: packages/pug-linker/test/cases/layout.append.without-block.input.json ================================================ { "type": "Block", "nodes": [ { "type": "Extends", "file": { "type": "FileReference", "path": "../fixtures/append-without-block/app-layout.pug", "line": 2, "filename": "layout.append.without-block.pug", "fullPath": "../fixtures/append-without-block/app-layout.pug", "str": "\nextends layout.pug\n\nappend head\n script(src='app.js')\n", "ast": { "type": "Block", "nodes": [ { "type": "Extends", "file": { "type": "FileReference", "path": "layout.pug", "line": 2, "filename": "../fixtures/append-without-block/app-layout.pug", "fullPath": "../fixtures/append-without-block/layout.pug", "str": "\nhtml\n block head\n script(src='vendor/jquery.js')\n script(src='vendor/caustic.js')\n body\n block body", "ast": { "type": "Block", "nodes": [ { "type": "Tag", "name": "html", "selfClosing": false, "block": { "type": "Block", "nodes": [ { "type": "NamedBlock", "nodes": [ { "type": "Tag", "name": "script", "selfClosing": false, "block": { "type": "Block", "nodes": [], "line": 4, "filename": "../fixtures/append-without-block/layout.pug" }, "attrs": [ { "name": "src", "val": "'vendor/jquery.js'", "mustEscape": true } ], "attributeBlocks": [], "isInline": false, "line": 4, "filename": "../fixtures/append-without-block/layout.pug" }, { "type": "Tag", "name": "script", "selfClosing": false, "block": { "type": "Block", "nodes": [], "line": 5, "filename": "../fixtures/append-without-block/layout.pug" }, "attrs": [ { "name": "src", "val": "'vendor/caustic.js'", "mustEscape": true } ], "attributeBlocks": [], "isInline": false, "line": 5, "filename": "../fixtures/append-without-block/layout.pug" } ], "line": 3, "filename": "../fixtures/append-without-block/layout.pug", "name": "head", "mode": "replace" }, { "type": "Tag", "name": "body", "selfClosing": false, "block": { "type": "Block", "nodes": [ { "type": "NamedBlock", "nodes": [], "line": 7, "filename": "../fixtures/append-without-block/layout.pug", "name": "body", "mode": "replace" } ], "line": 6, "filename": "../fixtures/append-without-block/layout.pug" }, "attrs": [], "attributeBlocks": [], "isInline": false, "line": 6, "filename": "../fixtures/append-without-block/layout.pug" } ], "line": 2, "filename": "../fixtures/append-without-block/layout.pug" }, "attrs": [], "attributeBlocks": [], "isInline": false, "line": 2, "filename": "../fixtures/append-without-block/layout.pug" } ], "line": 0, "filename": "../fixtures/append-without-block/layout.pug" } }, "line": 2, "filename": "../fixtures/append-without-block/app-layout.pug" }, { "type": "NamedBlock", "nodes": [ { "type": "Tag", "name": "script", "selfClosing": false, "block": { "type": "Block", "nodes": [], "line": 5, "filename": "../fixtures/append-without-block/app-layout.pug" }, "attrs": [ { "name": "src", "val": "'app.js'", "mustEscape": true } ], "attributeBlocks": [], "isInline": false, "line": 5, "filename": "../fixtures/append-without-block/app-layout.pug" } ], "line": 4, "filename": "../fixtures/append-without-block/app-layout.pug", "name": "head", "mode": "append" } ], "line": 0, "filename": "../fixtures/append-without-block/app-layout.pug" } }, "line": 2, "filename": "layout.append.without-block.pug" }, { "type": "NamedBlock", "nodes": [ { "type": "Tag", "name": "script", "selfClosing": false, "block": { "type": "Block", "nodes": [], "line": 5, "filename": "layout.append.without-block.pug" }, "attrs": [ { "name": "src", "val": "'foo.js'", "mustEscape": true } ], "attributeBlocks": [], "isInline": false, "line": 5, "filename": "layout.append.without-block.pug" }, { "type": "Tag", "name": "script", "selfClosing": false, "block": { "type": "Block", "nodes": [], "line": 6, "filename": "layout.append.without-block.pug" }, "attrs": [ { "name": "src", "val": "'bar.js'", "mustEscape": true } ], "attributeBlocks": [], "isInline": false, "line": 6, "filename": "layout.append.without-block.pug" } ], "line": 4, "filename": "layout.append.without-block.pug", "name": "head", "mode": "append" } ], "line": 0, "filename": "layout.append.without-block.pug" } ================================================ FILE: packages/pug-linker/test/cases/layout.multi.append.prepend.block.input.json ================================================ { "type": "Block", "nodes": [ { "type": "Extends", "file": { "type": "FileReference", "path": "../fixtures/multi-append-prepend-block/redefine.pug", "line": 1, "filename": "layout.multi.append.prepend.block.pug", "fullPath": "../fixtures/multi-append-prepend-block/redefine.pug", "str": "extends root.pug\n\nblock content\n\t.content\n\t\t| Defined content\n", "ast": { "type": "Block", "nodes": [ { "type": "Extends", "file": { "type": "FileReference", "path": "root.pug", "line": 1, "filename": "../fixtures/multi-append-prepend-block/redefine.pug", "fullPath": "../fixtures/multi-append-prepend-block/root.pug", "str": "block content\n\t| default content\n\nblock head\n\tscript(src='/app.js')", "ast": { "type": "Block", "nodes": [ { "type": "NamedBlock", "nodes": [ { "type": "Text", "val": "default content", "line": 2, "filename": "../fixtures/multi-append-prepend-block/root.pug" } ], "line": 1, "filename": "../fixtures/multi-append-prepend-block/root.pug", "name": "content", "mode": "replace" }, { "type": "NamedBlock", "nodes": [ { "type": "Tag", "name": "script", "selfClosing": false, "block": { "type": "Block", "nodes": [], "line": 5, "filename": "../fixtures/multi-append-prepend-block/root.pug" }, "attrs": [ { "name": "src", "val": "'/app.js'", "mustEscape": true } ], "attributeBlocks": [], "isInline": false, "line": 5, "filename": "../fixtures/multi-append-prepend-block/root.pug" } ], "line": 4, "filename": "../fixtures/multi-append-prepend-block/root.pug", "name": "head", "mode": "replace" } ], "line": 0, "filename": "../fixtures/multi-append-prepend-block/root.pug" } }, "line": 1, "filename": "../fixtures/multi-append-prepend-block/redefine.pug" }, { "type": "NamedBlock", "nodes": [ { "type": "Tag", "name": "div", "selfClosing": false, "block": { "type": "Block", "nodes": [ { "type": "Text", "val": "Defined content", "line": 5, "filename": "../fixtures/multi-append-prepend-block/redefine.pug" } ], "line": 4, "filename": "../fixtures/multi-append-prepend-block/redefine.pug" }, "attrs": [ { "name": "class", "val": "'content'", "mustEscape": false } ], "attributeBlocks": [], "isInline": false, "line": 4, "filename": "../fixtures/multi-append-prepend-block/redefine.pug" } ], "line": 3, "filename": "../fixtures/multi-append-prepend-block/redefine.pug", "name": "content", "mode": "replace" } ], "line": 0, "filename": "../fixtures/multi-append-prepend-block/redefine.pug" } }, "line": 1, "filename": "layout.multi.append.prepend.block.pug" }, { "type": "NamedBlock", "nodes": [ { "type": "Tag", "name": "p", "selfClosing": false, "block": { "type": "Block", "nodes": [ { "type": "Text", "val": "Something appended to content", "line": 4, "filename": "layout.multi.append.prepend.block.pug" } ], "line": 4, "filename": "layout.multi.append.prepend.block.pug" }, "attrs": [ { "name": "class", "val": "'first'", "mustEscape": false }, { "name": "class", "val": "'append'", "mustEscape": false } ], "attributeBlocks": [], "isInline": false, "line": 4, "filename": "layout.multi.append.prepend.block.pug" } ], "line": 3, "filename": "layout.multi.append.prepend.block.pug", "name": "content", "mode": "append" }, { "type": "NamedBlock", "nodes": [ { "type": "Tag", "name": "p", "selfClosing": false, "block": { "type": "Block", "nodes": [ { "type": "Text", "val": "Something prepended to content", "line": 7, "filename": "layout.multi.append.prepend.block.pug" } ], "line": 7, "filename": "layout.multi.append.prepend.block.pug" }, "attrs": [ { "name": "class", "val": "'first'", "mustEscape": false }, { "name": "class", "val": "'prepend'", "mustEscape": false } ], "attributeBlocks": [], "isInline": false, "line": 7, "filename": "layout.multi.append.prepend.block.pug" } ], "line": 6, "filename": "layout.multi.append.prepend.block.pug", "name": "content", "mode": "prepend" }, { "type": "NamedBlock", "nodes": [ { "type": "Tag", "name": "p", "selfClosing": false, "block": { "type": "Block", "nodes": [ { "type": "Text", "val": "Last append must be most last", "line": 10, "filename": "layout.multi.append.prepend.block.pug" } ], "line": 10, "filename": "layout.multi.append.prepend.block.pug" }, "attrs": [ { "name": "class", "val": "'last'", "mustEscape": false }, { "name": "class", "val": "'append'", "mustEscape": false } ], "attributeBlocks": [], "isInline": false, "line": 10, "filename": "layout.multi.append.prepend.block.pug" } ], "line": 9, "filename": "layout.multi.append.prepend.block.pug", "name": "content", "mode": "append" }, { "type": "NamedBlock", "nodes": [ { "type": "Tag", "name": "p", "selfClosing": false, "block": { "type": "Block", "nodes": [ { "type": "Text", "val": "Last prepend must appear at top", "line": 13, "filename": "layout.multi.append.prepend.block.pug" } ], "line": 13, "filename": "layout.multi.append.prepend.block.pug" }, "attrs": [ { "name": "class", "val": "'last'", "mustEscape": false }, { "name": "class", "val": "'prepend'", "mustEscape": false } ], "attributeBlocks": [], "isInline": false, "line": 13, "filename": "layout.multi.append.prepend.block.pug" } ], "line": 12, "filename": "layout.multi.append.prepend.block.pug", "name": "content", "mode": "prepend" }, { "type": "NamedBlock", "nodes": [ { "type": "Tag", "name": "script", "selfClosing": false, "block": { "type": "Block", "nodes": [], "line": 16, "filename": "layout.multi.append.prepend.block.pug" }, "attrs": [ { "name": "src", "val": "'jquery.js'", "mustEscape": true } ], "attributeBlocks": [], "isInline": false, "line": 16, "filename": "layout.multi.append.prepend.block.pug" } ], "line": 15, "filename": "layout.multi.append.prepend.block.pug", "name": "head", "mode": "append" }, { "type": "NamedBlock", "nodes": [ { "type": "Tag", "name": "script", "selfClosing": false, "block": { "type": "Block", "nodes": [], "line": 19, "filename": "layout.multi.append.prepend.block.pug" }, "attrs": [ { "name": "src", "val": "'foo.js'", "mustEscape": true } ], "attributeBlocks": [], "isInline": false, "line": 19, "filename": "layout.multi.append.prepend.block.pug" } ], "line": 18, "filename": "layout.multi.append.prepend.block.pug", "name": "head", "mode": "prepend" } ], "line": 0, "filename": "layout.multi.append.prepend.block.pug" } ================================================ FILE: packages/pug-linker/test/cases/layout.prepend.input.json ================================================ { "type": "Block", "nodes": [ { "type": "Extends", "file": { "type": "FileReference", "path": "../fixtures/prepend/app-layout.pug", "line": 2, "filename": "layout.prepend.pug", "fullPath": "../fixtures/prepend/app-layout.pug", "str": "\nextends layout.pug\n\nblock prepend head\n script(src='app.js')\n", "ast": { "type": "Block", "nodes": [ { "type": "Extends", "file": { "type": "FileReference", "path": "layout.pug", "line": 2, "filename": "../fixtures/prepend/app-layout.pug", "fullPath": "../fixtures/prepend/layout.pug", "str": "\nhtml\n block head\n script(src='vendor/jquery.js')\n script(src='vendor/caustic.js')\n body\n block body", "ast": { "type": "Block", "nodes": [ { "type": "Tag", "name": "html", "selfClosing": false, "block": { "type": "Block", "nodes": [ { "type": "NamedBlock", "nodes": [ { "type": "Tag", "name": "script", "selfClosing": false, "block": { "type": "Block", "nodes": [], "line": 4, "filename": "../fixtures/prepend/layout.pug" }, "attrs": [ { "name": "src", "val": "'vendor/jquery.js'", "mustEscape": true } ], "attributeBlocks": [], "isInline": false, "line": 4, "filename": "../fixtures/prepend/layout.pug" }, { "type": "Tag", "name": "script", "selfClosing": false, "block": { "type": "Block", "nodes": [], "line": 5, "filename": "../fixtures/prepend/layout.pug" }, "attrs": [ { "name": "src", "val": "'vendor/caustic.js'", "mustEscape": true } ], "attributeBlocks": [], "isInline": false, "line": 5, "filename": "../fixtures/prepend/layout.pug" } ], "line": 3, "filename": "../fixtures/prepend/layout.pug", "name": "head", "mode": "replace" }, { "type": "Tag", "name": "body", "selfClosing": false, "block": { "type": "Block", "nodes": [ { "type": "NamedBlock", "nodes": [], "line": 7, "filename": "../fixtures/prepend/layout.pug", "name": "body", "mode": "replace" } ], "line": 6, "filename": "../fixtures/prepend/layout.pug" }, "attrs": [], "attributeBlocks": [], "isInline": false, "line": 6, "filename": "../fixtures/prepend/layout.pug" } ], "line": 2, "filename": "../fixtures/prepend/layout.pug" }, "attrs": [], "attributeBlocks": [], "isInline": false, "line": 2, "filename": "../fixtures/prepend/layout.pug" } ], "line": 0, "filename": "../fixtures/prepend/layout.pug" } }, "line": 2, "filename": "../fixtures/prepend/app-layout.pug" }, { "type": "NamedBlock", "nodes": [ { "type": "Tag", "name": "script", "selfClosing": false, "block": { "type": "Block", "nodes": [], "line": 5, "filename": "../fixtures/prepend/app-layout.pug" }, "attrs": [ { "name": "src", "val": "'app.js'", "mustEscape": true } ], "attributeBlocks": [], "isInline": false, "line": 5, "filename": "../fixtures/prepend/app-layout.pug" } ], "line": 4, "filename": "../fixtures/prepend/app-layout.pug", "name": "head", "mode": "prepend" } ], "line": 0, "filename": "../fixtures/prepend/app-layout.pug" } }, "line": 2, "filename": "layout.prepend.pug" }, { "type": "NamedBlock", "nodes": [ { "type": "Tag", "name": "script", "selfClosing": false, "block": { "type": "Block", "nodes": [], "line": 5, "filename": "layout.prepend.pug" }, "attrs": [ { "name": "src", "val": "'foo.js'", "mustEscape": true } ], "attributeBlocks": [], "isInline": false, "line": 5, "filename": "layout.prepend.pug" }, { "type": "Tag", "name": "script", "selfClosing": false, "block": { "type": "Block", "nodes": [], "line": 6, "filename": "layout.prepend.pug" }, "attrs": [ { "name": "src", "val": "'bar.js'", "mustEscape": true } ], "attributeBlocks": [], "isInline": false, "line": 6, "filename": "layout.prepend.pug" } ], "line": 4, "filename": "layout.prepend.pug", "name": "head", "mode": "prepend" } ], "line": 0, "filename": "layout.prepend.pug" } ================================================ FILE: packages/pug-linker/test/cases/layout.prepend.without-block.input.json ================================================ { "type": "Block", "nodes": [ { "type": "Extends", "file": { "type": "FileReference", "path": "../fixtures/prepend-without-block/app-layout.pug", "line": 2, "filename": "layout.prepend.without-block.pug", "fullPath": "../fixtures/prepend-without-block/app-layout.pug", "str": "\nextends layout.pug\n\nprepend head\n script(src='app.js')\n", "ast": { "type": "Block", "nodes": [ { "type": "Extends", "file": { "type": "FileReference", "path": "layout.pug", "line": 2, "filename": "../fixtures/prepend-without-block/app-layout.pug", "fullPath": "../fixtures/prepend-without-block/layout.pug", "str": "\nhtml\n block head\n script(src='vendor/jquery.js')\n script(src='vendor/caustic.js')\n body\n block body", "ast": { "type": "Block", "nodes": [ { "type": "Tag", "name": "html", "selfClosing": false, "block": { "type": "Block", "nodes": [ { "type": "NamedBlock", "nodes": [ { "type": "Tag", "name": "script", "selfClosing": false, "block": { "type": "Block", "nodes": [], "line": 4, "filename": "../fixtures/prepend-without-block/layout.pug" }, "attrs": [ { "name": "src", "val": "'vendor/jquery.js'", "mustEscape": true } ], "attributeBlocks": [], "isInline": false, "line": 4, "filename": "../fixtures/prepend-without-block/layout.pug" }, { "type": "Tag", "name": "script", "selfClosing": false, "block": { "type": "Block", "nodes": [], "line": 5, "filename": "../fixtures/prepend-without-block/layout.pug" }, "attrs": [ { "name": "src", "val": "'vendor/caustic.js'", "mustEscape": true } ], "attributeBlocks": [], "isInline": false, "line": 5, "filename": "../fixtures/prepend-without-block/layout.pug" } ], "line": 3, "filename": "../fixtures/prepend-without-block/layout.pug", "name": "head", "mode": "replace" }, { "type": "Tag", "name": "body", "selfClosing": false, "block": { "type": "Block", "nodes": [ { "type": "NamedBlock", "nodes": [], "line": 7, "filename": "../fixtures/prepend-without-block/layout.pug", "name": "body", "mode": "replace" } ], "line": 6, "filename": "../fixtures/prepend-without-block/layout.pug" }, "attrs": [], "attributeBlocks": [], "isInline": false, "line": 6, "filename": "../fixtures/prepend-without-block/layout.pug" } ], "line": 2, "filename": "../fixtures/prepend-without-block/layout.pug" }, "attrs": [], "attributeBlocks": [], "isInline": false, "line": 2, "filename": "../fixtures/prepend-without-block/layout.pug" } ], "line": 0, "filename": "../fixtures/prepend-without-block/layout.pug" } }, "line": 2, "filename": "../fixtures/prepend-without-block/app-layout.pug" }, { "type": "NamedBlock", "nodes": [ { "type": "Tag", "name": "script", "selfClosing": false, "block": { "type": "Block", "nodes": [], "line": 5, "filename": "../fixtures/prepend-without-block/app-layout.pug" }, "attrs": [ { "name": "src", "val": "'app.js'", "mustEscape": true } ], "attributeBlocks": [], "isInline": false, "line": 5, "filename": "../fixtures/prepend-without-block/app-layout.pug" } ], "line": 4, "filename": "../fixtures/prepend-without-block/app-layout.pug", "name": "head", "mode": "prepend" } ], "line": 0, "filename": "../fixtures/prepend-without-block/app-layout.pug" } }, "line": 2, "filename": "layout.prepend.without-block.pug" }, { "type": "NamedBlock", "nodes": [ { "type": "Tag", "name": "script", "selfClosing": false, "block": { "type": "Block", "nodes": [], "line": 5, "filename": "layout.prepend.without-block.pug" }, "attrs": [ { "name": "src", "val": "'foo.js'", "mustEscape": true } ], "attributeBlocks": [], "isInline": false, "line": 5, "filename": "layout.prepend.without-block.pug" }, { "type": "Tag", "name": "script", "selfClosing": false, "block": { "type": "Block", "nodes": [], "line": 6, "filename": "layout.prepend.without-block.pug" }, "attrs": [ { "name": "src", "val": "'bar.js'", "mustEscape": true } ], "attributeBlocks": [], "isInline": false, "line": 6, "filename": "layout.prepend.without-block.pug" } ], "line": 4, "filename": "layout.prepend.without-block.pug", "name": "head", "mode": "prepend" } ], "line": 0, "filename": "layout.prepend.without-block.pug" } ================================================ FILE: packages/pug-linker/test/cases-src/auxiliary/1794-extends.pug ================================================ block content ================================================ FILE: packages/pug-linker/test/cases-src/auxiliary/1794-include.pug ================================================ mixin test() .test&attributes(attributes) +test() ================================================ FILE: packages/pug-linker/test/cases-src/auxiliary/blocks-in-blocks-layout.pug ================================================ doctype html html head title Default title body block body .container block content ================================================ FILE: packages/pug-linker/test/cases-src/auxiliary/dialog.pug ================================================ extends window.pug block window-content .dialog block content ================================================ FILE: packages/pug-linker/test/cases-src/auxiliary/empty-block.pug ================================================ block test ================================================ FILE: packages/pug-linker/test/cases-src/auxiliary/escapes.html ================================================ ================================================ FILE: packages/pug-linker/test/cases-src/auxiliary/extends-empty-block-1.pug ================================================ extends empty-block.pug block test div test1 ================================================ FILE: packages/pug-linker/test/cases-src/auxiliary/extends-empty-block-2.pug ================================================ extends empty-block.pug block test div test2 ================================================ FILE: packages/pug-linker/test/cases-src/auxiliary/extends-from-root.pug ================================================ extends /auxiliary/layout.pug block content include /auxiliary/include-from-root.pug ================================================ FILE: packages/pug-linker/test/cases-src/auxiliary/extends-relative.pug ================================================ extends ../../cases-src/auxiliary/layout block content include ../../cases-src/auxiliary/include-from-root ================================================ FILE: packages/pug-linker/test/cases-src/auxiliary/filter-in-include.pug ================================================ html head style(type="text/css") :less @pad: 15px; body { padding: @pad; } ================================================ FILE: packages/pug-linker/test/cases-src/auxiliary/includable.js ================================================ var STRING_SUBSTITUTIONS = { // table of character substitutions '\t': '\\t', '\r': '\\r', '\n': '\\n', '"': '\\"', '\\': '\\\\', }; ================================================ FILE: packages/pug-linker/test/cases-src/auxiliary/include-from-root.pug ================================================ h1 hello ================================================ FILE: packages/pug-linker/test/cases-src/auxiliary/inheritance.extend.mixin.block.pug ================================================ mixin article() article block html head title My Application block head body +article block content ================================================ FILE: packages/pug-linker/test/cases-src/auxiliary/inheritance.extend.recursive-grand-grandparent.pug ================================================ h1 grand-grandparent block grand-grandparent ================================================ FILE: packages/pug-linker/test/cases-src/auxiliary/inheritance.extend.recursive-grandparent.pug ================================================ extends inheritance.extend.recursive-grand-grandparent.pug block grand-grandparent h2 grandparent block grandparent ================================================ FILE: packages/pug-linker/test/cases-src/auxiliary/inheritance.extend.recursive-parent.pug ================================================ extends inheritance.extend.recursive-grandparent.pug block grandparent h3 parent block parent ================================================ FILE: packages/pug-linker/test/cases-src/auxiliary/layout.include.pug ================================================ html head title My Application block head body block content include window.pug ================================================ FILE: packages/pug-linker/test/cases-src/auxiliary/layout.pug ================================================ html head title My Application block head body block content ================================================ FILE: packages/pug-linker/test/cases-src/auxiliary/mixin-at-end-of-file.pug ================================================ mixin slide section.slide block ================================================ FILE: packages/pug-linker/test/cases-src/auxiliary/mixins.pug ================================================ mixin foo() p bar ================================================ FILE: packages/pug-linker/test/cases-src/auxiliary/pet.pug ================================================ .pet h1 {{name}} p {{name}} is a {{species}} that is {{age}} old ================================================ FILE: packages/pug-linker/test/cases-src/auxiliary/smile.html ================================================

    :)

    ================================================ FILE: packages/pug-linker/test/cases-src/auxiliary/window.pug ================================================ .window a(href='#').close Close block window-content ================================================ FILE: packages/pug-linker/test/cases-src/auxiliary/yield-nested.pug ================================================ html head title body h1 Page #content #content-wrapper yield #footer stuff ================================================ FILE: packages/pug-linker/test/cases-src/include-extends-from-root.pug ================================================ include /auxiliary/extends-from-root.pug ================================================ FILE: packages/pug-linker/test/cases-src/include-extends-of-common-template.pug ================================================ include auxiliary/extends-empty-block-1.pug include auxiliary/extends-empty-block-2.pug ================================================ FILE: packages/pug-linker/test/cases-src/include-extends-relative.pug ================================================ include ../cases-src/auxiliary/extends-relative.pug ================================================ FILE: packages/pug-linker/test/cases-src/include-filter-coffee.coffee ================================================ math = square: (value) -> value * value ================================================ FILE: packages/pug-linker/test/cases-src/include-filter-stylus.pug ================================================ style(type="text/css") include:stylus some.styl ================================================ FILE: packages/pug-linker/test/cases-src/include-filter.pug ================================================ html body include:markdown-it some.md script include:coffee-script(minify=true) include-filter-coffee.coffee script include:coffee-script(minify=false) include-filter-coffee.coffee ================================================ FILE: packages/pug-linker/test/cases-src/include-only-text-body.pug ================================================ | The message is " yield | " ================================================ FILE: packages/pug-linker/test/cases-src/include-only-text.pug ================================================ html body p include include-only-text-body.pug em hello world ================================================ FILE: packages/pug-linker/test/cases-src/include-with-text-head.pug ================================================ head script(type='text/javascript'). alert('hello world'); ================================================ FILE: packages/pug-linker/test/cases-src/include-with-text.pug ================================================ html include include-with-text-head.pug script(src='/caustic.js') script(src='/app.js') ================================================ FILE: packages/pug-linker/test/cases-src/include.script.pug ================================================ script#pet-template(type='text/x-template') include auxiliary/pet.pug ================================================ FILE: packages/pug-linker/test/cases-src/include.yield.nested.pug ================================================ include auxiliary/yield-nested.pug p some content p and some more ================================================ FILE: packages/pug-linker/test/cases-src/includes-with-ext-js.pug ================================================ pre code include javascript-new-lines.js ================================================ FILE: packages/pug-linker/test/cases-src/includes.pug ================================================ include auxiliary/mixins.pug +foo body include auxiliary/smile.html include auxiliary/escapes.html script(type="text/javascript") include:verbatim auxiliary/includable.js ================================================ FILE: packages/pug-linker/test/cases-src/javascript-new-lines.js ================================================ var x = '\n here is some \n new lined text'; ================================================ FILE: packages/pug-linker/test/cases-src/layout.append.pug ================================================ extends ../fixtures/append/app-layout.pug block append head script(src='foo.js') script(src='bar.js') ================================================ FILE: packages/pug-linker/test/cases-src/layout.append.without-block.pug ================================================ extends ../fixtures/append-without-block/app-layout.pug append head script(src='foo.js') script(src='bar.js') ================================================ FILE: packages/pug-linker/test/cases-src/layout.multi.append.prepend.block.pug ================================================ extends ../fixtures/multi-append-prepend-block/redefine.pug append content p.first.append Something appended to content prepend content p.first.prepend Something prepended to content append content p.last.append Last append must be most last prepend content p.last.prepend Last prepend must appear at top append head script(src='jquery.js') prepend head script(src='foo.js') ================================================ FILE: packages/pug-linker/test/cases-src/layout.prepend.pug ================================================ extends ../fixtures/prepend/app-layout.pug block prepend head script(src='foo.js') script(src='bar.js') ================================================ FILE: packages/pug-linker/test/cases-src/layout.prepend.without-block.pug ================================================ extends ../fixtures/prepend-without-block/app-layout.pug prepend head script(src='foo.js') script(src='bar.js') ================================================ FILE: packages/pug-linker/test/cases-src/some-included.styl ================================================ body padding 10px ================================================ FILE: packages/pug-linker/test/cases-src/some.md ================================================ Just _some_ markdown **tests**. With new line. ================================================ FILE: packages/pug-linker/test/cases-src/some.styl ================================================ @import "some-included" ================================================ FILE: packages/pug-linker/test/errors/child-with-tags.input.json ================================================ { "type": "Block", "nodes": [ { "type": "Extends", "file": { "type": "FileReference", "path": "../fixtures/layout", "line": 1, "filename": "child-with-tags.pug", "fullPath": "../fixtures/layout.pug", "str": "doctype\n\nhtml\n head\n block head\n Hello world!\n body\n block body\n", "ast": { "type": "Block", "nodes": [ { "type": "Doctype", "val": "", "line": 1, "filename": "../fixtures/layout.pug" }, { "type": "Tag", "name": "html", "selfClosing": false, "block": { "type": "Block", "nodes": [ { "type": "Tag", "name": "head", "selfClosing": false, "block": { "type": "Block", "nodes": [ { "type": "NamedBlock", "nodes": [ { "type": "Text", "val": "Hello world!", "filename": "../fixtures/layout.pug", "line": 6, "isHtml": true } ], "line": 5, "filename": "../fixtures/layout.pug", "name": "head", "mode": "replace" } ], "line": 4, "filename": "../fixtures/layout.pug" }, "attrs": [], "attributeBlocks": [], "isInline": false, "line": 4, "filename": "../fixtures/layout.pug" }, { "type": "Tag", "name": "body", "selfClosing": false, "block": { "type": "Block", "nodes": [ { "type": "NamedBlock", "nodes": [], "line": 8, "filename": "../fixtures/layout.pug", "name": "body", "mode": "replace" } ], "line": 7, "filename": "../fixtures/layout.pug" }, "attrs": [], "attributeBlocks": [], "isInline": false, "line": 7, "filename": "../fixtures/layout.pug" } ], "line": 3, "filename": "../fixtures/layout.pug" }, "attrs": [], "attributeBlocks": [], "isInline": false, "line": 3, "filename": "../fixtures/layout.pug" } ], "line": 0, "filename": "../fixtures/layout.pug" } }, "line": 1, "filename": "child-with-tags.pug" }, { "type": "NamedBlock", "nodes": [ { "type": "Tag", "name": "p", "selfClosing": false, "block": { "type": "Block", "nodes": [ { "type": "Text", "val": "Hello world!", "line": 4, "filename": "child-with-tags.pug" } ], "line": 4, "filename": "child-with-tags.pug" }, "attrs": [], "attributeBlocks": [], "isInline": false, "line": 4, "filename": "child-with-tags.pug" } ], "line": 3, "filename": "child-with-tags.pug", "name": "body", "mode": "replace" }, { "type": "Tag", "name": "p", "selfClosing": false, "block": { "type": "Block", "nodes": [ { "type": "Text", "val": "BAD!!!", "line": 6, "filename": "child-with-tags.pug" } ], "line": 6, "filename": "child-with-tags.pug" }, "attrs": [], "attributeBlocks": [], "isInline": false, "line": 6, "filename": "child-with-tags.pug" } ], "line": 0, "filename": "child-with-tags.pug" } ================================================ FILE: packages/pug-linker/test/errors/extends-not-first.input.json ================================================ { "type": "Block", "nodes": [ { "type": "NamedBlock", "nodes": [ { "type": "Tag", "name": "p", "selfClosing": false, "block": { "type": "Block", "nodes": [ { "type": "Text", "val": "Hey", "line": 2, "filename": "extends-not-first.pug" } ], "line": 2, "filename": "extends-not-first.pug" }, "attrs": [], "attributeBlocks": [], "isInline": false, "line": 2, "filename": "extends-not-first.pug" } ], "line": 1, "filename": "extends-not-first.pug", "name": "body", "mode": "replace" }, { "type": "Extends", "file": { "type": "FileReference", "path": "../fixtures/layout", "line": 4, "filename": "extends-not-first.pug", "fullPath": "../fixtures/layout.pug", "str": "doctype\n\nhtml\n head\n block head\n Hello world!\n body\n block body\n", "ast": { "type": "Block", "nodes": [ { "type": "Doctype", "val": "", "line": 1, "filename": "../fixtures/layout.pug" }, { "type": "Tag", "name": "html", "selfClosing": false, "block": { "type": "Block", "nodes": [ { "type": "Tag", "name": "head", "selfClosing": false, "block": { "type": "Block", "nodes": [ { "type": "NamedBlock", "nodes": [ { "type": "Text", "val": "Hello world!", "filename": "../fixtures/layout.pug", "line": 6, "isHtml": true } ], "line": 5, "filename": "../fixtures/layout.pug", "name": "head", "mode": "replace" } ], "line": 4, "filename": "../fixtures/layout.pug" }, "attrs": [], "attributeBlocks": [], "isInline": false, "line": 4, "filename": "../fixtures/layout.pug" }, { "type": "Tag", "name": "body", "selfClosing": false, "block": { "type": "Block", "nodes": [ { "type": "NamedBlock", "nodes": [], "line": 8, "filename": "../fixtures/layout.pug", "name": "body", "mode": "replace" } ], "line": 7, "filename": "../fixtures/layout.pug" }, "attrs": [], "attributeBlocks": [], "isInline": false, "line": 7, "filename": "../fixtures/layout.pug" } ], "line": 3, "filename": "../fixtures/layout.pug" }, "attrs": [], "attributeBlocks": [], "isInline": false, "line": 3, "filename": "../fixtures/layout.pug" } ], "line": 0, "filename": "../fixtures/layout.pug" } }, "line": 4, "filename": "extends-not-first.pug" } ], "line": 0, "filename": "extends-not-first.pug" } ================================================ FILE: packages/pug-linker/test/errors/unexpected-block.input.json ================================================ { "type": "Block", "nodes": [ { "type": "Extends", "file": { "type": "FileReference", "path": "../fixtures/empty.pug", "line": 1, "filename": "unexpected-block.pug", "fullPath": "../fixtures/empty.pug", "str": "", "ast": { "type": "Block", "nodes": [], "line": 0, "filename": "../fixtures/empty.pug" } }, "line": 1, "filename": "unexpected-block.pug" }, { "type": "NamedBlock", "nodes": [ { "type": "Tag", "name": "div", "selfClosing": false, "block": { "type": "Block", "nodes": [ { "type": "Text", "val": "Hello World", "line": 4, "filename": "unexpected-block.pug" } ], "line": 4, "filename": "unexpected-block.pug" }, "attrs": [], "attributeBlocks": [], "isInline": false, "line": 4, "filename": "unexpected-block.pug" } ], "line": 3, "filename": "unexpected-block.pug", "name": "foo", "mode": "replace" } ], "line": 0, "filename": "unexpected-block.pug" } ================================================ FILE: packages/pug-linker/test/errors-src/child-with-tags.pug ================================================ extend ../fixtures/layout block body p Hello world! p BAD!!! ================================================ FILE: packages/pug-linker/test/errors-src/extends-not-first.pug ================================================ block body p Hey extends ../fixtures/layout ================================================ FILE: packages/pug-linker/test/errors-src/unexpected-block.pug ================================================ extends ../fixtures/empty.pug block foo div Hello World ================================================ FILE: packages/pug-linker/test/fixtures/append/app-layout.pug ================================================ extends layout block append head script(src='app.js') ================================================ FILE: packages/pug-linker/test/fixtures/append/layout.pug ================================================ html block head script(src='vendor/jquery.js') script(src='vendor/caustic.js') body block body ================================================ FILE: packages/pug-linker/test/fixtures/append/page.html ================================================ ================================================ FILE: packages/pug-linker/test/fixtures/append/page.pug ================================================ extends app-layout block append head script(src='foo.js') script(src='bar.js') ================================================ FILE: packages/pug-linker/test/fixtures/append-without-block/app-layout.pug ================================================ extends layout.pug append head script(src='app.js') ================================================ FILE: packages/pug-linker/test/fixtures/append-without-block/layout.pug ================================================ html block head script(src='vendor/jquery.js') script(src='vendor/caustic.js') body block body ================================================ FILE: packages/pug-linker/test/fixtures/append-without-block/page.pug ================================================ extends app-layout.pug append head script(src='foo.js') script(src='bar.js') ================================================ FILE: packages/pug-linker/test/fixtures/empty.pug ================================================ ================================================ FILE: packages/pug-linker/test/fixtures/layout.pug ================================================ doctype html head block head Hello world! body block body ================================================ FILE: packages/pug-linker/test/fixtures/mixins.pug ================================================ mixin image(src) img(cl-src=src)&attributes(attributes) ================================================ FILE: packages/pug-linker/test/fixtures/multi-append-prepend-block/redefine.pug ================================================ extends root.pug block content .content | Defined content ================================================ FILE: packages/pug-linker/test/fixtures/multi-append-prepend-block/root.pug ================================================ block content | default content block head script(src='/app.js') ================================================ FILE: packages/pug-linker/test/fixtures/prepend/app-layout.pug ================================================ extends layout.pug block prepend head script(src='app.js') ================================================ FILE: packages/pug-linker/test/fixtures/prepend/layout.pug ================================================ html block head script(src='vendor/jquery.js') script(src='vendor/caustic.js') body block body ================================================ FILE: packages/pug-linker/test/fixtures/prepend/page.html ================================================ ================================================ FILE: packages/pug-linker/test/fixtures/prepend/page.pug ================================================ extends app-layout.pug block prepend head script(src='foo.js') script(src='bar.js') ================================================ FILE: packages/pug-linker/test/fixtures/prepend-without-block/app-layout.pug ================================================ extends layout.pug prepend head script(src='app.js') ================================================ FILE: packages/pug-linker/test/fixtures/prepend-without-block/layout.pug ================================================ html block head script(src='vendor/jquery.js') script(src='vendor/caustic.js') body block body ================================================ FILE: packages/pug-linker/test/fixtures/prepend-without-block/page.html ================================================ ================================================ FILE: packages/pug-linker/test/fixtures/prepend-without-block/page.pug ================================================ extends app-layout.pug prepend head script(src='foo.js') script(src='bar.js') ================================================ FILE: packages/pug-linker/test/index.test.js ================================================ var assert = require('assert'); var fs = require('fs'); var link = require('../'); function testDir(dir) { fs.readdirSync(dir).forEach(function(name) { if (!/\.input\.json$/.test(name)) return; test(name, function() { var actual = link(JSON.parse(fs.readFileSync(dir + '/' + name, 'utf8'))); expect(actual).toMatchSnapshot(); }); }); } function testDirError(dir) { fs.readdirSync(dir).forEach(function(name) { if (!/\.input\.json$/.test(name)) return; test(name, function() { var input = JSON.parse(fs.readFileSync(dir + '/' + name, 'utf8')); var err; try { link(input); } catch (ex) { err = { msg: ex.msg, code: ex.code, line: ex.line, }; } if (!err) throw new Error('Expected error'); expect(err).toMatchSnapshot(); }); }); } describe('cases from pug', function() { testDir(__dirname + '/cases'); }); describe('special cases', function() { testDir(__dirname + '/special-cases'); }); describe('error handling', function() { testDirError(__dirname + '/errors'); }); ================================================ FILE: packages/pug-linker/test/special-cases/extending-empty.input.json ================================================ { "type": "Block", "nodes": [ { "type": "Extends", "file": { "type": "FileReference", "path": "../fixtures/empty.pug", "line": 1, "filename": "extending-empty.pug", "fullPath": "../fixtures/empty.pug", "str": "", "ast": { "type": "Block", "nodes": [], "line": 0, "filename": "../fixtures/empty.pug" } }, "line": 1, "filename": "extending-empty.pug" } ], "line": 0, "filename": "extending-empty.pug" } ================================================ FILE: packages/pug-linker/test/special-cases/extending-include.input.json ================================================ { "type": "Block", "nodes": [ { "type": "Extends", "file": { "type": "FileReference", "path": "../fixtures/layout.pug", "line": 1, "filename": "extending-include.pug", "fullPath": "../fixtures/layout.pug", "str": "doctype\n\nhtml\n head\n block head\n Hello world!\n body\n block body\n", "ast": { "type": "Block", "nodes": [ { "type": "Doctype", "val": "", "line": 1, "filename": "../fixtures/layout.pug" }, { "type": "Tag", "name": "html", "selfClosing": false, "block": { "type": "Block", "nodes": [ { "type": "Tag", "name": "head", "selfClosing": false, "block": { "type": "Block", "nodes": [ { "type": "NamedBlock", "nodes": [ { "type": "Text", "val": "Hello world!", "filename": "../fixtures/layout.pug", "line": 6, "isHtml": true } ], "line": 5, "filename": "../fixtures/layout.pug", "name": "head", "mode": "replace" } ], "line": 4, "filename": "../fixtures/layout.pug" }, "attrs": [], "attributeBlocks": [], "isInline": false, "line": 4, "filename": "../fixtures/layout.pug" }, { "type": "Tag", "name": "body", "selfClosing": false, "block": { "type": "Block", "nodes": [ { "type": "NamedBlock", "nodes": [], "line": 8, "filename": "../fixtures/layout.pug", "name": "body", "mode": "replace" } ], "line": 7, "filename": "../fixtures/layout.pug" }, "attrs": [], "attributeBlocks": [], "isInline": false, "line": 7, "filename": "../fixtures/layout.pug" } ], "line": 3, "filename": "../fixtures/layout.pug" }, "attrs": [], "attributeBlocks": [], "isInline": false, "line": 3, "filename": "../fixtures/layout.pug" } ], "line": 0, "filename": "../fixtures/layout.pug" } }, "line": 1, "filename": "extending-include.pug" }, { "type": "Include", "file": { "type": "FileReference", "line": 2, "filename": "extending-include.pug", "path": "../fixtures/mixins.pug", "fullPath": "../fixtures/mixins.pug", "str": "mixin image(src)\n img(cl-src=src)&attributes(attributes)\n", "ast": { "type": "Block", "nodes": [ { "type": "Mixin", "name": "image", "args": "src", "block": { "type": "Block", "nodes": [ { "type": "Tag", "name": "img", "selfClosing": false, "block": { "type": "Block", "nodes": [], "line": 2, "filename": "../fixtures/mixins.pug" }, "attrs": [ { "name": "cl-src", "val": "src", "mustEscape": true } ], "attributeBlocks": [ "attributes" ], "isInline": true, "line": 2, "filename": "../fixtures/mixins.pug" } ], "line": 2, "filename": "../fixtures/mixins.pug" }, "call": false, "line": 1, "filename": "../fixtures/mixins.pug" } ], "line": 0, "filename": "../fixtures/mixins.pug" } }, "line": 2, "filename": "extending-include.pug", "block": { "type": "Block", "nodes": [], "line": 2, "filename": "extending-include.pug" } }, { "type": "NamedBlock", "nodes": [ { "type": "Mixin", "name": "image", "args": "'myimg.png'", "block": null, "call": true, "attrs": [ { "name": "class", "val": "'with-border'", "mustEscape": false }, { "name": "alt", "val": "\"My image\"", "mustEscape": true } ], "attributeBlocks": [], "line": 5, "filename": "extending-include.pug" } ], "line": 4, "filename": "extending-include.pug", "name": "body", "mode": "replace" } ], "line": 0, "filename": "extending-include.pug" } ================================================ FILE: packages/pug-linker/test/special-cases/root-mixin.input.json ================================================ { "type": "Block", "nodes": [ { "type": "Extends", "file": { "type": "FileReference", "path": "../fixtures/layout.pug", "line": 1, "filename": "root-mixin.pug", "fullPath": "../fixtures/layout.pug", "str": "doctype\n\nhtml\n head\n block head\n Hello world!\n body\n block body\n", "ast": { "type": "Block", "nodes": [ { "type": "Doctype", "val": "", "line": 1, "filename": "../fixtures/layout.pug" }, { "type": "Tag", "name": "html", "selfClosing": false, "block": { "type": "Block", "nodes": [ { "type": "Tag", "name": "head", "selfClosing": false, "block": { "type": "Block", "nodes": [ { "type": "NamedBlock", "nodes": [ { "type": "Text", "val": "Hello world!", "filename": "../fixtures/layout.pug", "line": 6, "isHtml": true } ], "line": 5, "filename": "../fixtures/layout.pug", "name": "head", "mode": "replace" } ], "line": 4, "filename": "../fixtures/layout.pug" }, "attrs": [], "attributeBlocks": [], "isInline": false, "line": 4, "filename": "../fixtures/layout.pug" }, { "type": "Tag", "name": "body", "selfClosing": false, "block": { "type": "Block", "nodes": [ { "type": "NamedBlock", "nodes": [], "line": 8, "filename": "../fixtures/layout.pug", "name": "body", "mode": "replace" } ], "line": 7, "filename": "../fixtures/layout.pug" }, "attrs": [], "attributeBlocks": [], "isInline": false, "line": 7, "filename": "../fixtures/layout.pug" } ], "line": 3, "filename": "../fixtures/layout.pug" }, "attrs": [], "attributeBlocks": [], "isInline": false, "line": 3, "filename": "../fixtures/layout.pug" } ], "line": 0, "filename": "../fixtures/layout.pug" } }, "line": 1, "filename": "root-mixin.pug" }, { "type": "Mixin", "name": "myMixin", "args": null, "block": { "type": "Block", "nodes": [ { "type": "Tag", "name": "p", "selfClosing": false, "block": { "type": "Block", "nodes": [ { "type": "Text", "val": "Hello world", "line": 4, "filename": "root-mixin.pug" } ], "line": 4, "filename": "root-mixin.pug" }, "attrs": [], "attributeBlocks": [], "isInline": false, "line": 4, "filename": "root-mixin.pug" } ], "line": 4, "filename": "root-mixin.pug" }, "call": false, "line": 3, "filename": "root-mixin.pug" }, { "type": "NamedBlock", "nodes": [ { "type": "Tag", "name": "p", "selfClosing": false, "block": { "type": "Block", "nodes": [ { "type": "Text", "val": "Before", "line": 7, "filename": "root-mixin.pug" } ], "line": 7, "filename": "root-mixin.pug" }, "attrs": [], "attributeBlocks": [], "isInline": false, "line": 7, "filename": "root-mixin.pug" }, { "type": "Mixin", "name": "myMixin", "args": null, "block": null, "call": true, "attrs": [], "attributeBlocks": [], "line": 8, "filename": "root-mixin.pug" }, { "type": "Tag", "name": "p", "selfClosing": false, "block": { "type": "Block", "nodes": [ { "type": "Text", "val": "After", "line": 9, "filename": "root-mixin.pug" } ], "line": 9, "filename": "root-mixin.pug" }, "attrs": [], "attributeBlocks": [], "isInline": false, "line": 9, "filename": "root-mixin.pug" } ], "line": 6, "filename": "root-mixin.pug", "name": "body", "mode": "replace" } ], "line": 0, "filename": "root-mixin.pug" } ================================================ FILE: packages/pug-linker/test/special-cases-src/extending-empty.pug ================================================ extend ../fixtures/empty.pug ================================================ FILE: packages/pug-linker/test/special-cases-src/extending-include.pug ================================================ extend ../fixtures/layout.pug include ../fixtures/mixins.pug block body +image('myimg.png').with-border(alt="My image") ================================================ FILE: packages/pug-linker/test/special-cases-src/root-mixin.pug ================================================ extend ../fixtures/layout.pug mixin myMixin p Hello world block body p Before +myMixin p After ================================================ FILE: packages/pug-load/HISTORY.md ================================================ 2.0.3 / 2016-08-24 ================== * Do not pollute the user's `options` object 2.0.2 / 2016-08-23 ================== * Only publish the module itself 2.0.1 / 2016-08-23 ================== * Update to pug-walk@^1.0.0 2.0.0 / 2016-05-14 ================== * Make filename part of the options - updates to the 2.x.y APIs for lexer and parser ================================================ FILE: packages/pug-load/LICENSE ================================================ Copyright (c) 2015 Forbes Lindesay 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. ================================================ FILE: packages/pug-load/README.md ================================================ # pug-load The pug loader is responsible for loading the depenendencies of a given pug file. It adds `fullPath` and `str` properties to every `Include` and `Extends` node. It also adds an `ast` property to any `Include` nodes that are loading pug and any `Extends` nodes. It then recursively loads the dependencies of any of those included files. [![Build Status](https://img.shields.io/travis/pugjs/pug-load/master.svg)](https://travis-ci.org/pugjs/pug-load) [![Dependencies Status](https://david-dm.org/pugjs/pug/status.svg?path=packages/pug-load)](https://david-dm.org/pugjs/pug?path=packages/pug-load) [![DevDependencies Status](https://david-dm.org/pugjs/pug/dev-status.svg?path=packages/pug-load)](https://david-dm.org/pugjs/pug?path=packages/pug-load&type=dev) [![NPM version](https://img.shields.io/npm/v/pug-load.svg)](https://www.npmjs.org/package/pug-load) [![Coverage Status](https://img.shields.io/codecov/c/github/pugjs/pug-load.svg)](https://codecov.io/gh/pugjs/pug-load) ## Installation npm install pug-load ## Usage ```js var load = require('pug-load'); ``` ### `load(ast, options)` ### `load.string(str, filename, options)` ### `load.file(filename, options)` Loads all dependencies of the Pug AST. `load.string` and `load.file` are syntactic sugar that parses the string or file instead of you doing it yourself. `options` may contain the following properties: - `lex` (function): **(required)** the lexer used - `parse` (function): **(required)** the parser used - `resolve` (function): a function used to override `load.resolve`. Defaults to `load.resolve`. - `read` (function): a function used to override `load.read`. Defaults to `load.read`. - `basedir` (string): the base directory of absolute inclusion. This is **required** when absolute inclusion (file name starts with `'/'`) is used. Defaults to undefined. The `options` object is passed to `load.resolve` and `load.read`, or equivalently `options.resolve` and `options.read`. ### `load.resolve(filename, source, options)` Callback used by `pug-load` to resolve the full path of an included or extended file given the path of the source file. `filename` is the included file. `source` is the name of the parent file that includes `filename`. This function is not meant to be called from outside of `pug-load`, but rather for you to override. ### `load.read(filename, options)` Callback used by `pug-load` to return the contents of a file. `filename` is the file to read. This function is not meant to be called from outside of `pug-load`, but rather for you to override. ### `load.validateOptions(options)` Callback used `pug-load` to ensure the options object is valid. If your overridden `load.resolve` or `load.read` uses a different `options` scheme, you will need to override this function as well. This function is not meant to be called from outside of `pug-load`, but rather for you to override. ### Example ```js var fs = require('fs'); var lex = require('pug-lexer'); var parse = require('pug-parser'); var load = require('pug-load'); // you can do everything very manually var str = fs.readFileSync('bar.pug', 'utf8'); var ast = load(parse(lex(str, 'bar.pug'), 'bar.pug'), { lex: lex, parse: parse, resolve: function (filename, source, options) { console.log('"' + filename + '" file requested from "' + source + '".'); return load.resolve(filename, source, options); } }); // or you can do all that in just two steps var str = fs.readFileSync('bar.pug', 'utf8'); var ast = load.string(str, 'bar.pug', { lex: lex, parse: parse, resolve: function (filename, source, options) { console.log('"' + filename + '" file requested from "' + source + '".'); return load.resolve(filename, source, options); } }); // or you can do all that in only one step var ast = load.file('bar.pug', { lex: lex, parse: parse, resolve: function (filename, source, options) { console.log('"' + filename + '" file requested from "' + source + '".'); return load.resolve(filename, source, options); } }); ``` ## License MIT ================================================ FILE: packages/pug-load/index.js ================================================ 'use strict'; var fs = require('fs'); var path = require('path'); var walk = require('pug-walk'); var assign = require('object-assign'); module.exports = load; function load(ast, options) { options = getOptions(options); // clone the ast ast = JSON.parse(JSON.stringify(ast)); return walk(ast, function(node) { if (node.str === undefined) { if ( node.type === 'Include' || node.type === 'RawInclude' || node.type === 'Extends' ) { var file = node.file; if (file.type !== 'FileReference') { throw new Error('Expected file.type to be "FileReference"'); } var path, str, raw; try { path = options.resolve(file.path, file.filename, options); file.fullPath = path; raw = options.read(path, options); str = raw.toString('utf8'); } catch (ex) { ex.message += '\n at ' + node.filename + ' line ' + node.line; throw ex; } file.str = str; file.raw = raw; if (node.type === 'Extends' || node.type === 'Include') { file.ast = load.string( str, assign({}, options, { filename: path, }) ); } } } }); } load.string = function loadString(src, options) { options = assign(getOptions(options), { src: src, }); var tokens = options.lex(src, options); var ast = options.parse(tokens, options); return load(ast, options); }; load.file = function loadFile(filename, options) { options = assign(getOptions(options), { filename: filename, }); var str = options.read(filename).toString('utf8'); return load.string(str, options); }; load.resolve = function resolve(filename, source, options) { filename = filename.trim(); if (filename[0] !== '/' && !source) throw new Error( 'the "filename" option is required to use includes and extends with "relative" paths' ); if (filename[0] === '/' && !options.basedir) throw new Error( 'the "basedir" option is required to use includes and extends with "absolute" paths' ); filename = path.join( filename[0] === '/' ? options.basedir : path.dirname(source.trim()), filename ); return filename; }; load.read = function read(filename, options) { return fs.readFileSync(filename); }; load.validateOptions = function validateOptions(options) { /* istanbul ignore if */ if (typeof options !== 'object') { throw new TypeError('options must be an object'); } /* istanbul ignore if */ if (typeof options.lex !== 'function') { throw new TypeError('options.lex must be a function'); } /* istanbul ignore if */ if (typeof options.parse !== 'function') { throw new TypeError('options.parse must be a function'); } /* istanbul ignore if */ if (options.resolve && typeof options.resolve !== 'function') { throw new TypeError('options.resolve must be a function'); } /* istanbul ignore if */ if (options.read && typeof options.read !== 'function') { throw new TypeError('options.read must be a function'); } }; function getOptions(options) { load.validateOptions(options); return assign( { resolve: load.resolve, read: load.read, }, options ); } ================================================ FILE: packages/pug-load/package.json ================================================ { "name": "pug-load", "version": "2.0.12", "description": "The Pug loader is responsible for loading the depenendencies of a given Pug file.", "keywords": [ "pug" ], "dependencies": { "object-assign": "^4.1.1", "pug-walk": "^1.1.8" }, "devDependencies": { "pug-lexer": "^4.1.0", "pug-parser": "^5.0.1" }, "files": [ "index.js" ], "repository": { "type": "git", "url": "https://github.com/pugjs/pug/tree/master/packages/pug-load" }, "author": "ForbesLindesay", "license": "MIT" } ================================================ FILE: packages/pug-load/test/__snapshots__/index.test.js.snap ================================================ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`pug-load 1`] = ` Object { "filename": "/foo.pug", "line": 0, "nodes": Array [ Object { "column": 1, "file": Object { "ast": Object { "filename": "/bar.pug", "line": 0, "nodes": Array [ Object { "column": 1, "filename": "/bar.pug", "line": 1, "mode": "replace", "name": "bing", "nodes": Array [], "type": "NamedBlock", }, ], "type": "Block", }, "column": 9, "filename": "/foo.pug", "fullPath": "/bar.pug", "line": 1, "path": "bar.pug", "raw": Object { "hash": "538bf7d4b81ef364b1f2e9d42c11f156", "size": 11, "type": "Buffer", }, "str": "block bing ", "type": "FileReference", }, "filename": "/foo.pug", "line": 1, "type": "Extends", }, Object { "column": 1, "filename": "/foo.pug", "line": 3, "mode": "replace", "name": "bing", "nodes": Array [ Object { "block": Object { "filename": "/foo.pug", "line": 4, "nodes": Array [], "type": "Block", }, "column": 3, "file": Object { "ast": Object { "filename": "/bing.pug", "line": 0, "nodes": Array [ Object { "attributeBlocks": Array [], "attrs": Array [ Object { "column": 1, "filename": "/packages/pug-load/test/bing.pug", "line": 1, "mustEscape": false, "name": "class", "val": "'bing'", }, ], "block": Object { "filename": "/bing.pug", "line": 1, "nodes": Array [ Object { "column": 7, "filename": "/bing.pug", "line": 1, "type": "Text", "val": "bong", }, ], "type": "Block", }, "column": 1, "filename": "/bing.pug", "isInline": false, "line": 1, "name": "div", "selfClosing": false, "type": "Tag", }, ], "type": "Block", }, "column": 11, "filename": "/foo.pug", "fullPath": "/bing.pug", "line": 4, "path": "bing.pug", "raw": Object { "hash": "58ecbe086e7a045084cbddac849a2563", "size": 11, "type": "Buffer", }, "str": ".bing bong ", "type": "FileReference", }, "filename": "/foo.pug", "line": 4, "type": "Include", }, Object { "attributeBlocks": Array [], "attrs": Array [], "block": Object { "filename": "/foo.pug", "line": 5, "nodes": Array [ Object { "column": 5, "file": Object { "column": 13, "filename": "/foo.pug", "fullPath": "/script.js", "line": 6, "path": "script.js", "raw": Object { "hash": "86d4f8e34165faeb09f10255121078f8", "size": 32, "type": "Buffer", }, "str": "document.write('hello world!'); ", "type": "FileReference", }, "filename": "/foo.pug", "filters": Array [], "line": 6, "type": "RawInclude", }, ], "type": "Block", }, "column": 3, "filename": "/foo.pug", "isInline": false, "line": 5, "name": "script", "selfClosing": false, "type": "Tag", }, ], "type": "NamedBlock", }, ], "type": "Block", } `; ================================================ FILE: packages/pug-load/test/bar.pug ================================================ block bing ================================================ FILE: packages/pug-load/test/bing.pug ================================================ .bing bong ================================================ FILE: packages/pug-load/test/foo.pug ================================================ extends bar.pug block bing include bing.pug script include script.js ================================================ FILE: packages/pug-load/test/index.test.js ================================================ 'use strict'; var fs = require('fs'); var path = require('path'); var assert = require('assert'); var walk = require('pug-walk'); var lex = require('pug-lexer'); var parse = require('pug-parser'); var load = require('../'); test('pug-load', () => { var filename = __dirname + '/foo.pug'; var ast = load.file(filename, { lex: lex, parse: parse, }); ast = walk( ast, function(node) { if (node.filename) node.filename = '/' + path.basename(node.filename); if (node.fullPath) node.fullPath = '/' + path.basename(node.fullPath); }, {includeDependencies: true} ); expect(ast).toMatchSnapshot(); }); ================================================ FILE: packages/pug-load/test/script.js ================================================ document.write('hello world!'); ================================================ FILE: packages/pug-parser/HISTORY.md ================================================ 2.0.1 / 2016-06-01 ================== * Add a brief API introduction to README 2.0.0 / 2016-05-14 ================== * Take the `filename` as an option rather than special casing it. This means that parse only takes 2 arguments rather than 3 * Add type checking on arguments * Treat the legacy `.jade` extension as `.pug` rather than a raw include ================================================ FILE: packages/pug-parser/LICENSE ================================================ Copyright (c) 2014 Forbes Lindesay 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. ================================================ FILE: packages/pug-parser/README.md ================================================ # pug-parser The pug parser (takes an array of tokens and converts it to an abstract syntax tree) [![Build Status](https://img.shields.io/travis/pugjs/pug-parser/master.svg)](https://travis-ci.org/pugjs/pug-parser) [![Dependencies Status](https://david-dm.org/pugjs/pug/status.svg?path=packages/pug-parser)](https://david-dm.org/pugjs/pug?path=packages/pug-parser) [![DevDependencies Status](https://david-dm.org/pugjs/pug/dev-status.svg?path=packages/pug-parser)](https://david-dm.org/pugjs/pug?path=packages/pug-parser&type=dev) [![NPM version](https://img.shields.io/npm/v/pug-parser.svg)](https://www.npmjs.org/package/pug-parser) ## Installation npm install pug-parser ## Usage ```js var parse = require('pug-parser'); ``` ### `parse(tokens, options)` Convert Pug tokens to an abstract syntax tree (AST). `options` can contain the following properties: - `filename` (string): The name of the Pug file; it is included in the produced AST nodes and error handling, if provided. - `plugins` (array): An array of plugins, in the order they should be applied. - `src` (string): The source of the Pug file; it is used in error handling if provided. ```js var lex = require('pug-lexer'); var filename = 'my-file.pug'; var src = 'div(data-foo="bar")'; var tokens = lex(src, {filename}); var ast = parse(tokens, {filename, src}); console.log(JSON.stringify(ast, null, ' ')) ``` ```json { "type": "Block", "nodes": [ { "type": "Tag", "name": "div", "selfClosing": false, "block": { "type": "Block", "nodes": [], "line": 1, "filename": "my-file.pug" }, "attrs": [ { "name": "data-foo", "val": "\"bar\"", "line": 1, "column": 5, "filename": "my-file.pug", "mustEscape": true } ], "attributeBlocks": [], "isInline": false, "line": 1, "column": 1, "filename": "my-file.pug" } ], "line": 0, "filename": "my-file.pug" } ``` ### `new parse.Parser(tokens, options)` Constructor for a Parser class. This is not meant to be used directly unless you know what you are doing. `options` may contain the following properties: - `filename` (string): The name of the Pug file; it is included in the produced AST nodes and error handling, if provided. - `plugins` (array): An array of plugins, in the order they should be applied. - `src` (string): The source of the Pug file; it is used in error handling if provided. ## License MIT ================================================ FILE: packages/pug-parser/index.js ================================================ 'use strict'; var assert = require('assert'); var TokenStream = require('token-stream'); var error = require('pug-error'); var inlineTags = require('./lib/inline-tags'); module.exports = parse; module.exports.Parser = Parser; function parse(tokens, options) { var parser = new Parser(tokens, options); var ast = parser.parse(); return JSON.parse(JSON.stringify(ast)); } /** * Initialize `Parser` with the given input `str` and `filename`. * * @param {String} str * @param {String} filename * @param {Object} options * @api public */ function Parser(tokens, options) { options = options || {}; if (!Array.isArray(tokens)) { throw new Error( 'Expected tokens to be an Array but got "' + typeof tokens + '"' ); } if (typeof options !== 'object') { throw new Error( 'Expected "options" to be an object but got "' + typeof options + '"' ); } this.tokens = new TokenStream(tokens); this.filename = options.filename; this.src = options.src; this.inMixin = 0; this.plugins = options.plugins || []; } /** * Parser prototype. */ Parser.prototype = { /** * Save original constructor */ constructor: Parser, error: function(code, message, token) { var err = error(code, message, { line: token.loc.start.line, column: token.loc.start.column, filename: this.filename, src: this.src, }); throw err; }, /** * Return the next token object. * * @return {Object} * @api private */ advance: function() { return this.tokens.advance(); }, /** * Single token lookahead. * * @return {Object} * @api private */ peek: function() { return this.tokens.peek(); }, /** * `n` token lookahead. * * @param {Number} n * @return {Object} * @api private */ lookahead: function(n) { return this.tokens.lookahead(n); }, /** * Parse input returning a string of js for evaluation. * * @return {String} * @api public */ parse: function() { var block = this.emptyBlock(0); while ('eos' != this.peek().type) { if ('newline' == this.peek().type) { this.advance(); } else if ('text-html' == this.peek().type) { block.nodes = block.nodes.concat(this.parseTextHtml()); } else { var expr = this.parseExpr(); if (expr) { if (expr.type === 'Block') { block.nodes = block.nodes.concat(expr.nodes); } else { block.nodes.push(expr); } } } } return block; }, /** * Expect the given type, or throw an exception. * * @param {String} type * @api private */ expect: function(type) { if (this.peek().type === type) { return this.advance(); } else { this.error( 'INVALID_TOKEN', 'expected "' + type + '", but got "' + this.peek().type + '"', this.peek() ); } }, /** * Accept the given `type`. * * @param {String} type * @api private */ accept: function(type) { if (this.peek().type === type) { return this.advance(); } }, initBlock: function(line, nodes) { /* istanbul ignore if */ if ((line | 0) !== line) throw new Error('`line` is not an integer'); /* istanbul ignore if */ if (!Array.isArray(nodes)) throw new Error('`nodes` is not an array'); return { type: 'Block', nodes: nodes, line: line, filename: this.filename, }; }, emptyBlock: function(line) { return this.initBlock(line, []); }, runPlugin: function(context, tok) { var rest = [this]; for (var i = 2; i < arguments.length; i++) { rest.push(arguments[i]); } var pluginContext; for (var i = 0; i < this.plugins.length; i++) { var plugin = this.plugins[i]; if (plugin[context] && plugin[context][tok.type]) { if (pluginContext) throw new Error( 'Multiple plugin handlers found for context ' + JSON.stringify(context) + ', token type ' + JSON.stringify(tok.type) ); pluginContext = plugin[context]; } } if (pluginContext) return pluginContext[tok.type].apply(pluginContext, rest); }, /** * tag * | doctype * | mixin * | include * | filter * | comment * | text * | text-html * | dot * | each * | code * | yield * | id * | class * | interpolation */ parseExpr: function() { switch (this.peek().type) { case 'tag': return this.parseTag(); case 'mixin': return this.parseMixin(); case 'block': return this.parseBlock(); case 'mixin-block': return this.parseMixinBlock(); case 'case': return this.parseCase(); case 'extends': return this.parseExtends(); case 'include': return this.parseInclude(); case 'doctype': return this.parseDoctype(); case 'filter': return this.parseFilter(); case 'comment': return this.parseComment(); case 'text': case 'interpolated-code': case 'start-pug-interpolation': return this.parseText({block: true}); case 'text-html': return this.initBlock(this.peek().loc.start.line, this.parseTextHtml()); case 'dot': return this.parseDot(); case 'each': return this.parseEach(); case 'eachOf': return this.parseEachOf(); case 'code': return this.parseCode(); case 'blockcode': return this.parseBlockCode(); case 'if': return this.parseConditional(); case 'while': return this.parseWhile(); case 'call': return this.parseCall(); case 'interpolation': return this.parseInterpolation(); case 'yield': return this.parseYield(); case 'id': case 'class': if (!this.peek().loc.start) debugger; this.tokens.defer({ type: 'tag', val: 'div', loc: this.peek().loc, filename: this.filename, }); return this.parseExpr(); default: var pluginResult = this.runPlugin('expressionTokens', this.peek()); if (pluginResult) return pluginResult; this.error( 'INVALID_TOKEN', 'unexpected token "' + this.peek().type + '"', this.peek() ); } }, parseDot: function() { this.advance(); return this.parseTextBlock(); }, /** * Text */ parseText: function(options) { var tags = []; var lineno = this.peek().loc.start.line; var nextTok = this.peek(); loop: while (true) { switch (nextTok.type) { case 'text': var tok = this.advance(); tags.push({ type: 'Text', val: tok.val, line: tok.loc.start.line, column: tok.loc.start.column, filename: this.filename, }); break; case 'interpolated-code': var tok = this.advance(); tags.push({ type: 'Code', val: tok.val, buffer: tok.buffer, mustEscape: tok.mustEscape !== false, isInline: true, line: tok.loc.start.line, column: tok.loc.start.column, filename: this.filename, }); break; case 'newline': if (!options || !options.block) break loop; var tok = this.advance(); var nextType = this.peek().type; if (nextType === 'text' || nextType === 'interpolated-code') { tags.push({ type: 'Text', val: '\n', line: tok.loc.start.line, column: tok.loc.start.column, filename: this.filename, }); } break; case 'start-pug-interpolation': this.advance(); tags.push(this.parseExpr()); this.expect('end-pug-interpolation'); break; default: var pluginResult = this.runPlugin('textTokens', nextTok, tags); if (pluginResult) break; break loop; } nextTok = this.peek(); } if (tags.length === 1) return tags[0]; else return this.initBlock(lineno, tags); }, parseTextHtml: function() { var nodes = []; var currentNode = null; loop: while (true) { switch (this.peek().type) { case 'text-html': var text = this.advance(); if (!currentNode) { currentNode = { type: 'Text', val: text.val, filename: this.filename, line: text.loc.start.line, column: text.loc.start.column, isHtml: true, }; nodes.push(currentNode); } else { currentNode.val += '\n' + text.val; } break; case 'indent': var block = this.block(); block.nodes.forEach(function(node) { if (node.isHtml) { if (!currentNode) { currentNode = node; nodes.push(currentNode); } else { currentNode.val += '\n' + node.val; } } else { currentNode = null; nodes.push(node); } }); break; case 'code': currentNode = null; nodes.push(this.parseCode(true)); break; case 'newline': this.advance(); break; default: break loop; } } return nodes; }, /** * ':' expr * | block */ parseBlockExpansion: function() { var tok = this.accept(':'); if (tok) { var expr = this.parseExpr(); return expr.type === 'Block' ? expr : this.initBlock(tok.loc.start.line, [expr]); } else { return this.block(); } }, /** * case */ parseCase: function() { var tok = this.expect('case'); var node = { type: 'Case', expr: tok.val, line: tok.loc.start.line, column: tok.loc.start.column, filename: this.filename, }; var block = this.emptyBlock(tok.loc.start.line + 1); this.expect('indent'); while ('outdent' != this.peek().type) { switch (this.peek().type) { case 'comment': case 'newline': this.advance(); break; case 'when': block.nodes.push(this.parseWhen()); break; case 'default': block.nodes.push(this.parseDefault()); break; default: var pluginResult = this.runPlugin('caseTokens', this.peek(), block); if (pluginResult) break; this.error( 'INVALID_TOKEN', 'Unexpected token "' + this.peek().type + '", expected "when", "default" or "newline"', this.peek() ); } } this.expect('outdent'); node.block = block; return node; }, /** * when */ parseWhen: function() { var tok = this.expect('when'); if (this.peek().type !== 'newline') { return { type: 'When', expr: tok.val, block: this.parseBlockExpansion(), debug: false, line: tok.loc.start.line, column: tok.loc.start.column, filename: this.filename, }; } else { return { type: 'When', expr: tok.val, debug: false, line: tok.loc.start.line, column: tok.loc.start.column, filename: this.filename, }; } }, /** * default */ parseDefault: function() { var tok = this.expect('default'); return { type: 'When', expr: 'default', block: this.parseBlockExpansion(), debug: false, line: tok.loc.start.line, column: tok.loc.start.column, filename: this.filename, }; }, /** * code */ parseCode: function(noBlock) { var tok = this.expect('code'); assert( typeof tok.mustEscape === 'boolean', 'Please update to the newest version of pug-lexer.' ); var node = { type: 'Code', val: tok.val, buffer: tok.buffer, mustEscape: tok.mustEscape !== false, isInline: !!noBlock, line: tok.loc.start.line, column: tok.loc.start.column, filename: this.filename, }; // todo: why is this here? It seems like a hacky workaround if (node.val.match(/^ *else/)) node.debug = false; if (noBlock) return node; var block; // handle block block = 'indent' == this.peek().type; if (block) { if (tok.buffer) { this.error( 'BLOCK_IN_BUFFERED_CODE', 'Buffered code cannot have a block attached to it', this.peek() ); } node.block = this.block(); } return node; }, parseConditional: function() { var tok = this.expect('if'); var node = { type: 'Conditional', test: tok.val, consequent: this.emptyBlock(tok.loc.start.line), alternate: null, line: tok.loc.start.line, column: tok.loc.start.column, filename: this.filename, }; // handle block if ('indent' == this.peek().type) { node.consequent = this.block(); } var currentNode = node; while (true) { if (this.peek().type === 'newline') { this.expect('newline'); } else if (this.peek().type === 'else-if') { tok = this.expect('else-if'); currentNode = currentNode.alternate = { type: 'Conditional', test: tok.val, consequent: this.emptyBlock(tok.loc.start.line), alternate: null, line: tok.loc.start.line, column: tok.loc.start.column, filename: this.filename, }; if ('indent' == this.peek().type) { currentNode.consequent = this.block(); } } else if (this.peek().type === 'else') { this.expect('else'); if (this.peek().type === 'indent') { currentNode.alternate = this.block(); } break; } else { break; } } return node; }, parseWhile: function() { var tok = this.expect('while'); var node = { type: 'While', test: tok.val, line: tok.loc.start.line, column: tok.loc.start.column, filename: this.filename, }; // handle block if ('indent' == this.peek().type) { node.block = this.block(); } else { node.block = this.emptyBlock(tok.loc.start.line); } return node; }, /** * block code */ parseBlockCode: function() { var tok = this.expect('blockcode'); var line = tok.loc.start.line; var column = tok.loc.start.column; var body = this.peek(); var text = ''; if (body.type === 'start-pipeless-text') { this.advance(); while (this.peek().type !== 'end-pipeless-text') { tok = this.advance(); switch (tok.type) { case 'text': text += tok.val; break; case 'newline': text += '\n'; break; default: var pluginResult = this.runPlugin('blockCodeTokens', tok, tok); if (pluginResult) { text += pluginResult; break; } this.error( 'INVALID_TOKEN', 'Unexpected token type: ' + tok.type, tok ); } } this.advance(); } return { type: 'Code', val: text, buffer: false, mustEscape: false, isInline: false, line: line, column: column, filename: this.filename, }; }, /** * comment */ parseComment: function() { var tok = this.expect('comment'); var block; if ((block = this.parseTextBlock())) { return { type: 'BlockComment', val: tok.val, block: block, buffer: tok.buffer, line: tok.loc.start.line, column: tok.loc.start.column, filename: this.filename, }; } else { return { type: 'Comment', val: tok.val, buffer: tok.buffer, line: tok.loc.start.line, column: tok.loc.start.column, filename: this.filename, }; } }, /** * doctype */ parseDoctype: function() { var tok = this.expect('doctype'); return { type: 'Doctype', val: tok.val, line: tok.loc.start.line, column: tok.loc.start.column, filename: this.filename, }; }, parseIncludeFilter: function() { var tok = this.expect('filter'); var attrs = []; if (this.peek().type === 'start-attributes') { attrs = this.attrs(); } return { type: 'IncludeFilter', name: tok.val, attrs: attrs, line: tok.loc.start.line, column: tok.loc.start.column, filename: this.filename, }; }, /** * filter attrs? text-block */ parseFilter: function() { var tok = this.expect('filter'); var block, attrs = []; if (this.peek().type === 'start-attributes') { attrs = this.attrs(); } if (this.peek().type === 'text') { var textToken = this.advance(); block = this.initBlock(textToken.loc.start.line, [ { type: 'Text', val: textToken.val, line: textToken.loc.start.line, column: textToken.loc.start.column, filename: this.filename, }, ]); } else if (this.peek().type === 'filter') { block = this.initBlock(tok.loc.start.line, [this.parseFilter()]); } else { block = this.parseTextBlock() || this.emptyBlock(tok.loc.start.line); } return { type: 'Filter', name: tok.val, block: block, attrs: attrs, line: tok.loc.start.line, column: tok.loc.start.column, filename: this.filename, }; }, /** * each block */ parseEach: function() { var tok = this.expect('each'); var node = { type: 'Each', obj: tok.code, val: tok.val, key: tok.key, block: this.block(), line: tok.loc.start.line, column: tok.loc.start.column, filename: this.filename, }; if (this.peek().type == 'else') { this.advance(); node.alternate = this.block(); } return node; }, parseEachOf: function() { var tok = this.expect('eachOf'); var node = { type: 'EachOf', obj: tok.code, val: tok.val, block: this.block(), line: tok.loc.start.line, column: tok.loc.start.column, filename: this.filename, }; return node; }, /** * 'extends' name */ parseExtends: function() { var tok = this.expect('extends'); var path = this.expect('path'); return { type: 'Extends', file: { type: 'FileReference', path: path.val.trim(), line: path.loc.start.line, column: path.loc.start.column, filename: this.filename, }, line: tok.loc.start.line, column: tok.loc.start.column, filename: this.filename, }; }, /** * 'block' name block */ parseBlock: function() { var tok = this.expect('block'); var node = 'indent' == this.peek().type ? this.block() : this.emptyBlock(tok.loc.start.line); node.type = 'NamedBlock'; node.name = tok.val.trim(); node.mode = tok.mode; node.line = tok.loc.start.line; node.column = tok.loc.start.column; return node; }, parseMixinBlock: function() { var tok = this.expect('mixin-block'); if (!this.inMixin) { this.error( 'BLOCK_OUTISDE_MIXIN', 'Anonymous blocks are not allowed unless they are part of a mixin.', tok ); } return { type: 'MixinBlock', line: tok.loc.start.line, column: tok.loc.start.column, filename: this.filename, }; }, parseYield: function() { var tok = this.expect('yield'); return { type: 'YieldBlock', line: tok.loc.start.line, column: tok.loc.start.column, filename: this.filename, }; }, /** * include block? */ parseInclude: function() { var tok = this.expect('include'); var node = { type: 'Include', file: { type: 'FileReference', filename: this.filename, }, line: tok.loc.start.line, column: tok.loc.start.column, filename: this.filename, }; var filters = []; while (this.peek().type === 'filter') { filters.push(this.parseIncludeFilter()); } var path = this.expect('path'); node.file.path = path.val.trim(); node.file.line = path.loc.start.line; node.file.column = path.loc.start.column; if ( (/\.jade$/.test(node.file.path) || /\.pug$/.test(node.file.path)) && !filters.length ) { node.block = 'indent' == this.peek().type ? this.block() : this.emptyBlock(tok.loc.start.line); if (/\.jade$/.test(node.file.path)) { console.warn( this.filename + ', line ' + tok.loc.start.line + ':\nThe .jade extension is deprecated, use .pug for "' + node.file.path + '".' ); } } else { node.type = 'RawInclude'; node.filters = filters; if (this.peek().type === 'indent') { this.error( 'RAW_INCLUDE_BLOCK', 'Raw inclusion cannot contain a block', this.peek() ); } } return node; }, /** * call ident block */ parseCall: function() { var tok = this.expect('call'); var name = tok.val; var args = tok.args; var mixin = { type: 'Mixin', name: name, args: args, block: this.emptyBlock(tok.loc.start.line), call: true, attrs: [], attributeBlocks: [], line: tok.loc.start.line, column: tok.loc.start.column, filename: this.filename, }; this.tag(mixin); if (mixin.code) { mixin.block.nodes.push(mixin.code); delete mixin.code; } if (mixin.block.nodes.length === 0) mixin.block = null; return mixin; }, /** * mixin block */ parseMixin: function() { var tok = this.expect('mixin'); var name = tok.val; var args = tok.args; if ('indent' == this.peek().type) { this.inMixin++; var mixin = { type: 'Mixin', name: name, args: args, block: this.block(), call: false, line: tok.loc.start.line, column: tok.loc.start.column, filename: this.filename, }; this.inMixin--; return mixin; } else { this.error( 'MIXIN_WITHOUT_BODY', 'Mixin ' + name + ' declared without body', tok ); } }, /** * indent (text | newline)* outdent */ parseTextBlock: function() { var tok = this.accept('start-pipeless-text'); if (!tok) return; var block = this.emptyBlock(tok.loc.start.line); while (this.peek().type !== 'end-pipeless-text') { var tok = this.advance(); switch (tok.type) { case 'text': block.nodes.push({ type: 'Text', val: tok.val, line: tok.loc.start.line, column: tok.loc.start.column, filename: this.filename, }); break; case 'newline': block.nodes.push({ type: 'Text', val: '\n', line: tok.loc.start.line, column: tok.loc.start.column, filename: this.filename, }); break; case 'start-pug-interpolation': block.nodes.push(this.parseExpr()); this.expect('end-pug-interpolation'); break; case 'interpolated-code': block.nodes.push({ type: 'Code', val: tok.val, buffer: tok.buffer, mustEscape: tok.mustEscape !== false, isInline: true, line: tok.loc.start.line, column: tok.loc.start.column, filename: this.filename, }); break; default: var pluginResult = this.runPlugin('textBlockTokens', tok, block, tok); if (pluginResult) break; this.error( 'INVALID_TOKEN', 'Unexpected token type: ' + tok.type, tok ); } } this.advance(); return block; }, /** * indent expr* outdent */ block: function() { var tok = this.expect('indent'); var block = this.emptyBlock(tok.loc.start.line); while ('outdent' != this.peek().type) { if ('newline' == this.peek().type) { this.advance(); } else if ('text-html' == this.peek().type) { block.nodes = block.nodes.concat(this.parseTextHtml()); } else { var expr = this.parseExpr(); if (expr.type === 'Block') { block.nodes = block.nodes.concat(expr.nodes); } else { block.nodes.push(expr); } } } this.expect('outdent'); return block; }, /** * interpolation (attrs | class | id)* (text | code | ':')? newline* block? */ parseInterpolation: function() { var tok = this.advance(); var tag = { type: 'InterpolatedTag', expr: tok.val, selfClosing: false, block: this.emptyBlock(tok.loc.start.line), attrs: [], attributeBlocks: [], isInline: false, line: tok.loc.start.line, column: tok.loc.start.column, filename: this.filename, }; return this.tag(tag, {selfClosingAllowed: true}); }, /** * tag (attrs | class | id)* (text | code | ':')? newline* block? */ parseTag: function() { var tok = this.advance(); var tag = { type: 'Tag', name: tok.val, selfClosing: false, block: this.emptyBlock(tok.loc.start.line), attrs: [], attributeBlocks: [], isInline: inlineTags.indexOf(tok.val) !== -1, line: tok.loc.start.line, column: tok.loc.start.column, filename: this.filename, }; return this.tag(tag, {selfClosingAllowed: true}); }, /** * Parse tag. */ tag: function(tag, options) { var seenAttrs = false; var attributeNames = []; var selfClosingAllowed = options && options.selfClosingAllowed; // (attrs | class | id)* out: while (true) { switch (this.peek().type) { case 'id': case 'class': var tok = this.advance(); if (tok.type === 'id') { if (attributeNames.indexOf('id') !== -1) { this.error( 'DUPLICATE_ID', 'Duplicate attribute "id" is not allowed.', tok ); } attributeNames.push('id'); } tag.attrs.push({ name: tok.type, val: "'" + tok.val + "'", line: tok.loc.start.line, column: tok.loc.start.column, filename: this.filename, mustEscape: false, }); continue; case 'start-attributes': if (seenAttrs) { console.warn( this.filename + ', line ' + this.peek().loc.start.line + ':\nYou should not have pug tags with multiple attributes.' ); } seenAttrs = true; tag.attrs = tag.attrs.concat(this.attrs(attributeNames)); continue; case '&attributes': var tok = this.advance(); tag.attributeBlocks.push({ type: 'AttributeBlock', val: tok.val, line: tok.loc.start.line, column: tok.loc.start.column, filename: this.filename, }); break; default: var pluginResult = this.runPlugin( 'tagAttributeTokens', this.peek(), tag, attributeNames ); if (pluginResult) break; break out; } } // check immediate '.' if ('dot' == this.peek().type) { tag.textOnly = true; this.advance(); } // (text | code | ':')? switch (this.peek().type) { case 'text': case 'interpolated-code': var text = this.parseText(); if (text.type === 'Block') { tag.block.nodes.push.apply(tag.block.nodes, text.nodes); } else { tag.block.nodes.push(text); } break; case 'code': tag.block.nodes.push(this.parseCode(true)); break; case ':': this.advance(); var expr = this.parseExpr(); tag.block = expr.type === 'Block' ? expr : this.initBlock(tag.line, [expr]); break; case 'newline': case 'indent': case 'outdent': case 'eos': case 'start-pipeless-text': case 'end-pug-interpolation': break; case 'slash': if (selfClosingAllowed) { this.advance(); tag.selfClosing = true; break; } default: var pluginResult = this.runPlugin( 'tagTokens', this.peek(), tag, options ); if (pluginResult) break; this.error( 'INVALID_TOKEN', 'Unexpected token `' + this.peek().type + '` expected `text`, `interpolated-code`, `code`, `:`' + (selfClosingAllowed ? ', `slash`' : '') + ', `newline` or `eos`', this.peek() ); } // newline* while ('newline' == this.peek().type) this.advance(); // block? if (tag.textOnly) { tag.block = this.parseTextBlock() || this.emptyBlock(tag.line); } else if ('indent' == this.peek().type) { var block = this.block(); for (var i = 0, len = block.nodes.length; i < len; ++i) { tag.block.nodes.push(block.nodes[i]); } } return tag; }, attrs: function(attributeNames) { this.expect('start-attributes'); var attrs = []; var tok = this.advance(); while (tok.type === 'attribute') { if (tok.name !== 'class' && attributeNames) { if (attributeNames.indexOf(tok.name) !== -1) { this.error( 'DUPLICATE_ATTRIBUTE', 'Duplicate attribute "' + tok.name + '" is not allowed.', tok ); } attributeNames.push(tok.name); } attrs.push({ name: tok.name, val: tok.val, line: tok.loc.start.line, column: tok.loc.start.column, filename: this.filename, mustEscape: tok.mustEscape !== false, }); tok = this.advance(); } this.tokens.defer(tok); this.expect('end-attributes'); return attrs; }, }; ================================================ FILE: packages/pug-parser/lib/inline-tags.js ================================================ 'use strict'; module.exports = [ 'a', 'abbr', 'acronym', 'b', 'br', 'code', 'em', 'font', 'i', 'img', 'ins', 'kbd', 'map', 'samp', 'small', 'span', 'strong', 'sub', 'sup', ]; ================================================ FILE: packages/pug-parser/package.json ================================================ { "name": "pug-parser", "version": "5.0.1", "description": "The pug parser (takes an array of tokens and converts it to an abstract syntax tree)", "keywords": [ "pug" ], "dependencies": { "pug-error": "^1.3.3", "token-stream": "1.0.0" }, "devDependencies": {}, "files": [ "lib/inline-tags.js", "index.js" ], "repository": { "type": "git", "url": "https://github.com/pugjs/pug/tree/master/packages/pug-parser" }, "author": "ForbesLindesay", "license": "MIT" } ================================================ FILE: packages/pug-parser/test/__snapshots__/index.test.js.snap ================================================ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`attr-es2015.tokens.json 1`] = ` Object { "filename": "attr-es2015.tokens.json", "line": 0, "nodes": Array [ Object { "buffer": false, "column": 1, "filename": "attr-es2015.tokens.json", "isInline": false, "line": 1, "mustEscape": false, "type": "Code", "val": "var avatar = '219b77f9d21de75e81851b6b886057c7'", }, Object { "attributeBlocks": Array [], "attrs": Array [ Object { "column": 4, "filename": "attr-es2015.tokens.json", "line": 3, "mustEscape": false, "name": "class", "val": "'avatar-div'", }, Object { "column": 16, "filename": "attr-es2015.tokens.json", "line": 3, "mustEscape": true, "name": "style", "val": "\`background-image: url(https://www.gravatar.com/avatar/\${avatar})\`", }, ], "block": Object { "filename": "attr-es2015.tokens.json", "line": 3, "nodes": Array [], "type": "Block", }, "column": 1, "filename": "attr-es2015.tokens.json", "isInline": false, "line": 3, "name": "div", "selfClosing": false, "type": "Tag", }, ], "type": "Block", } `; exports[`attrs.js.tokens.json 1`] = ` Object { "filename": "attrs.js.tokens.json", "line": 0, "nodes": Array [ Object { "buffer": false, "column": 1, "filename": "attrs.js.tokens.json", "isInline": false, "line": 1, "mustEscape": false, "type": "Code", "val": "var id = 5", }, Object { "buffer": false, "column": 1, "filename": "attrs.js.tokens.json", "isInline": false, "line": 2, "mustEscape": false, "type": "Code", "val": "function answer() { return 42; } ", }, Object { "attributeBlocks": Array [], "attrs": Array [ Object { "column": 3, "filename": "attrs.js.tokens.json", "line": 3, "mustEscape": true, "name": "href", "val": "'/user/' + id", }, Object { "column": 23, "filename": "attrs.js.tokens.json", "line": 3, "mustEscape": true, "name": "class", "val": "'button'", }, ], "block": Object { "filename": "attrs.js.tokens.json", "line": 3, "nodes": Array [], "type": "Block", }, "column": 1, "filename": "attrs.js.tokens.json", "isInline": true, "line": 3, "name": "a", "selfClosing": false, "type": "Tag", }, Object { "attributeBlocks": Array [], "attrs": Array [ Object { "column": 3, "filename": "attrs.js.tokens.json", "line": 4, "mustEscape": true, "name": "href", "val": "'/user/' + id", }, Object { "column": 27, "filename": "attrs.js.tokens.json", "line": 4, "mustEscape": true, "name": "class", "val": "'button'", }, ], "block": Object { "filename": "attrs.js.tokens.json", "line": 4, "nodes": Array [], "type": "Block", }, "column": 1, "filename": "attrs.js.tokens.json", "isInline": true, "line": 4, "name": "a", "selfClosing": false, "type": "Tag", }, Object { "attributeBlocks": Array [], "attrs": Array [ Object { "column": 6, "filename": "attrs.js.tokens.json", "line": 5, "mustEscape": true, "name": "key", "val": "'answer'", }, Object { "column": 20, "filename": "attrs.js.tokens.json", "line": 5, "mustEscape": true, "name": "value", "val": "answer()", }, ], "block": Object { "filename": "attrs.js.tokens.json", "line": 5, "nodes": Array [], "type": "Block", }, "column": 1, "filename": "attrs.js.tokens.json", "isInline": false, "line": 5, "name": "meta", "selfClosing": false, "type": "Tag", }, Object { "attributeBlocks": Array [], "attrs": Array [ Object { "column": 3, "filename": "attrs.js.tokens.json", "line": 6, "mustEscape": true, "name": "class", "val": "['class1', 'class2']", }, ], "block": Object { "filename": "attrs.js.tokens.json", "line": 6, "nodes": Array [], "type": "Block", }, "column": 1, "filename": "attrs.js.tokens.json", "isInline": true, "line": 6, "name": "a", "selfClosing": false, "type": "Tag", }, Object { "attributeBlocks": Array [], "attrs": Array [ Object { "column": 2, "filename": "attrs.js.tokens.json", "line": 7, "mustEscape": false, "name": "class", "val": "'tag-class'", }, Object { "column": 13, "filename": "attrs.js.tokens.json", "line": 7, "mustEscape": true, "name": "class", "val": "['class1', 'class2']", }, ], "block": Object { "filename": "attrs.js.tokens.json", "line": 7, "nodes": Array [], "type": "Block", }, "column": 1, "filename": "attrs.js.tokens.json", "isInline": true, "line": 7, "name": "a", "selfClosing": false, "type": "Tag", }, Object { "attributeBlocks": Array [], "attrs": Array [ Object { "column": 3, "filename": "attrs.js.tokens.json", "line": 9, "mustEscape": true, "name": "href", "val": "'/user/' + id", }, Object { "column": 22, "filename": "attrs.js.tokens.json", "line": 9, "mustEscape": true, "name": "class", "val": "'button'", }, ], "block": Object { "filename": "attrs.js.tokens.json", "line": 9, "nodes": Array [], "type": "Block", }, "column": 1, "filename": "attrs.js.tokens.json", "isInline": true, "line": 9, "name": "a", "selfClosing": false, "type": "Tag", }, Object { "attributeBlocks": Array [], "attrs": Array [ Object { "column": 3, "filename": "attrs.js.tokens.json", "line": 10, "mustEscape": true, "name": "href", "val": "'/user/' + id", }, Object { "column": 26, "filename": "attrs.js.tokens.json", "line": 10, "mustEscape": true, "name": "class", "val": "'button'", }, ], "block": Object { "filename": "attrs.js.tokens.json", "line": 10, "nodes": Array [], "type": "Block", }, "column": 1, "filename": "attrs.js.tokens.json", "isInline": true, "line": 10, "name": "a", "selfClosing": false, "type": "Tag", }, Object { "attributeBlocks": Array [], "attrs": Array [ Object { "column": 6, "filename": "attrs.js.tokens.json", "line": 11, "mustEscape": true, "name": "key", "val": "'answer'", }, Object { "column": 19, "filename": "attrs.js.tokens.json", "line": 11, "mustEscape": true, "name": "value", "val": "answer()", }, ], "block": Object { "filename": "attrs.js.tokens.json", "line": 11, "nodes": Array [], "type": "Block", }, "column": 1, "filename": "attrs.js.tokens.json", "isInline": false, "line": 11, "name": "meta", "selfClosing": false, "type": "Tag", }, Object { "attributeBlocks": Array [], "attrs": Array [ Object { "column": 3, "filename": "attrs.js.tokens.json", "line": 12, "mustEscape": true, "name": "class", "val": "['class1', 'class2']", }, ], "block": Object { "filename": "attrs.js.tokens.json", "line": 12, "nodes": Array [], "type": "Block", }, "column": 1, "filename": "attrs.js.tokens.json", "isInline": true, "line": 12, "name": "a", "selfClosing": false, "type": "Tag", }, Object { "attributeBlocks": Array [], "attrs": Array [ Object { "column": 2, "filename": "attrs.js.tokens.json", "line": 13, "mustEscape": false, "name": "class", "val": "'tag-class'", }, Object { "column": 13, "filename": "attrs.js.tokens.json", "line": 13, "mustEscape": true, "name": "class", "val": "['class1', 'class2']", }, ], "block": Object { "filename": "attrs.js.tokens.json", "line": 13, "nodes": Array [], "type": "Block", }, "column": 1, "filename": "attrs.js.tokens.json", "isInline": true, "line": 13, "name": "a", "selfClosing": false, "type": "Tag", }, Object { "attributeBlocks": Array [ Object { "column": 11, "filename": "attrs.js.tokens.json", "line": 15, "type": "AttributeBlock", "val": "{foo: 'bar'}", }, ], "attrs": Array [ Object { "column": 5, "filename": "attrs.js.tokens.json", "line": 15, "mustEscape": true, "name": "id", "val": "id", }, ], "block": Object { "filename": "attrs.js.tokens.json", "line": 15, "nodes": Array [], "type": "Block", }, "column": 1, "filename": "attrs.js.tokens.json", "isInline": false, "line": 15, "name": "div", "selfClosing": false, "type": "Tag", }, Object { "buffer": false, "column": 1, "filename": "attrs.js.tokens.json", "isInline": false, "line": 16, "mustEscape": false, "type": "Code", "val": "var bar = null", }, Object { "attributeBlocks": Array [ Object { "column": 22, "filename": "attrs.js.tokens.json", "line": 17, "type": "AttributeBlock", "val": "{baz: 'baz'}", }, ], "attrs": Array [ Object { "column": 5, "filename": "attrs.js.tokens.json", "line": 17, "mustEscape": true, "name": "foo", "val": "null", }, Object { "column": 14, "filename": "attrs.js.tokens.json", "line": 17, "mustEscape": true, "name": "bar", "val": "bar", }, ], "block": Object { "filename": "attrs.js.tokens.json", "line": 17, "nodes": Array [], "type": "Block", }, "column": 1, "filename": "attrs.js.tokens.json", "isInline": false, "line": 17, "name": "div", "selfClosing": false, "type": "Tag", }, ], "type": "Block", } `; exports[`attrs.tokens.json 1`] = ` Object { "filename": "attrs.tokens.json", "line": 0, "nodes": Array [ Object { "attributeBlocks": Array [], "attrs": Array [ Object { "column": 3, "filename": "attrs.tokens.json", "line": 1, "mustEscape": true, "name": "href", "val": "'/contact'", }, ], "block": Object { "filename": "attrs.tokens.json", "line": 1, "nodes": Array [ Object { "column": 20, "filename": "attrs.tokens.json", "line": 1, "type": "Text", "val": "contact", }, ], "type": "Block", }, "column": 1, "filename": "attrs.tokens.json", "isInline": true, "line": 1, "name": "a", "selfClosing": false, "type": "Tag", }, Object { "attributeBlocks": Array [], "attrs": Array [ Object { "column": 3, "filename": "attrs.tokens.json", "line": 2, "mustEscape": true, "name": "href", "val": "'/save'", }, Object { "column": 16, "filename": "attrs.tokens.json", "line": 2, "mustEscape": false, "name": "class", "val": "'button'", }, ], "block": Object { "filename": "attrs.tokens.json", "line": 2, "nodes": Array [ Object { "column": 24, "filename": "attrs.tokens.json", "line": 2, "type": "Text", "val": "save", }, ], "type": "Block", }, "column": 1, "filename": "attrs.tokens.json", "isInline": true, "line": 2, "name": "a", "selfClosing": false, "type": "Tag", }, Object { "attributeBlocks": Array [], "attrs": Array [ Object { "column": 3, "filename": "attrs.tokens.json", "line": 3, "mustEscape": true, "name": "foo", "val": true, }, Object { "column": 8, "filename": "attrs.tokens.json", "line": 3, "mustEscape": true, "name": "bar", "val": true, }, Object { "column": 13, "filename": "attrs.tokens.json", "line": 3, "mustEscape": true, "name": "baz", "val": true, }, ], "block": Object { "filename": "attrs.tokens.json", "line": 3, "nodes": Array [], "type": "Block", }, "column": 1, "filename": "attrs.tokens.json", "isInline": true, "line": 3, "name": "a", "selfClosing": false, "type": "Tag", }, Object { "attributeBlocks": Array [], "attrs": Array [ Object { "column": 3, "filename": "attrs.tokens.json", "line": 4, "mustEscape": true, "name": "foo", "val": "'foo, bar, baz'", }, Object { "column": 24, "filename": "attrs.tokens.json", "line": 4, "mustEscape": true, "name": "bar", "val": "1", }, ], "block": Object { "filename": "attrs.tokens.json", "line": 4, "nodes": Array [], "type": "Block", }, "column": 1, "filename": "attrs.tokens.json", "isInline": true, "line": 4, "name": "a", "selfClosing": false, "type": "Tag", }, Object { "attributeBlocks": Array [], "attrs": Array [ Object { "column": 3, "filename": "attrs.tokens.json", "line": 5, "mustEscape": true, "name": "foo", "val": "'((foo))'", }, Object { "column": 18, "filename": "attrs.tokens.json", "line": 5, "mustEscape": true, "name": "bar", "val": "(1) ? 1 : 0", }, ], "block": Object { "filename": "attrs.tokens.json", "line": 5, "nodes": Array [], "type": "Block", }, "column": 1, "filename": "attrs.tokens.json", "isInline": true, "line": 5, "name": "a", "selfClosing": false, "type": "Tag", }, Object { "attributeBlocks": Array [], "attrs": Array [], "block": Object { "filename": "attrs.tokens.json", "line": 6, "nodes": Array [ Object { "attributeBlocks": Array [], "attrs": Array [ Object { "column": 10, "filename": "attrs.tokens.json", "line": 7, "mustEscape": true, "name": "value", "val": "'foo'", }, Object { "column": 23, "filename": "attrs.tokens.json", "line": 7, "mustEscape": true, "name": "selected", "val": true, }, ], "block": Object { "filename": "attrs.tokens.json", "line": 7, "nodes": Array [ Object { "column": 33, "filename": "attrs.tokens.json", "line": 7, "type": "Text", "val": "Foo", }, ], "type": "Block", }, "column": 3, "filename": "attrs.tokens.json", "isInline": false, "line": 7, "name": "option", "selfClosing": false, "type": "Tag", }, Object { "attributeBlocks": Array [], "attrs": Array [ Object { "column": 10, "filename": "attrs.tokens.json", "line": 8, "mustEscape": true, "name": "selected", "val": true, }, Object { "column": 20, "filename": "attrs.tokens.json", "line": 8, "mustEscape": true, "name": "value", "val": "'bar'", }, ], "block": Object { "filename": "attrs.tokens.json", "line": 8, "nodes": Array [ Object { "column": 33, "filename": "attrs.tokens.json", "line": 8, "type": "Text", "val": "Bar", }, ], "type": "Block", }, "column": 3, "filename": "attrs.tokens.json", "isInline": false, "line": 8, "name": "option", "selfClosing": false, "type": "Tag", }, ], "type": "Block", }, "column": 1, "filename": "attrs.tokens.json", "isInline": false, "line": 6, "name": "select", "selfClosing": false, "type": "Tag", }, Object { "attributeBlocks": Array [], "attrs": Array [ Object { "column": 3, "filename": "attrs.tokens.json", "line": 9, "mustEscape": true, "name": "foo", "val": "\\"class:\\"", }, ], "block": Object { "filename": "attrs.tokens.json", "line": 9, "nodes": Array [], "type": "Block", }, "column": 1, "filename": "attrs.tokens.json", "isInline": true, "line": 9, "name": "a", "selfClosing": false, "type": "Tag", }, Object { "attributeBlocks": Array [], "attrs": Array [ Object { "column": 7, "filename": "attrs.tokens.json", "line": 10, "mustEscape": true, "name": "pattern", "val": "'\\\\\\\\S+'", }, ], "block": Object { "filename": "attrs.tokens.json", "line": 10, "nodes": Array [], "type": "Block", }, "column": 1, "filename": "attrs.tokens.json", "isInline": false, "line": 10, "name": "input", "selfClosing": false, "type": "Tag", }, Object { "attributeBlocks": Array [], "attrs": Array [ Object { "column": 3, "filename": "attrs.tokens.json", "line": 12, "mustEscape": true, "name": "href", "val": "'/contact'", }, ], "block": Object { "filename": "attrs.tokens.json", "line": 12, "nodes": Array [ Object { "column": 20, "filename": "attrs.tokens.json", "line": 12, "type": "Text", "val": "contact", }, ], "type": "Block", }, "column": 1, "filename": "attrs.tokens.json", "isInline": true, "line": 12, "name": "a", "selfClosing": false, "type": "Tag", }, Object { "attributeBlocks": Array [], "attrs": Array [ Object { "column": 3, "filename": "attrs.tokens.json", "line": 13, "mustEscape": true, "name": "href", "val": "'/save'", }, Object { "column": 16, "filename": "attrs.tokens.json", "line": 13, "mustEscape": false, "name": "class", "val": "'button'", }, ], "block": Object { "filename": "attrs.tokens.json", "line": 13, "nodes": Array [ Object { "column": 24, "filename": "attrs.tokens.json", "line": 13, "type": "Text", "val": "save", }, ], "type": "Block", }, "column": 1, "filename": "attrs.tokens.json", "isInline": true, "line": 13, "name": "a", "selfClosing": false, "type": "Tag", }, Object { "attributeBlocks": Array [], "attrs": Array [ Object { "column": 3, "filename": "attrs.tokens.json", "line": 14, "mustEscape": true, "name": "foo", "val": true, }, Object { "column": 7, "filename": "attrs.tokens.json", "line": 14, "mustEscape": true, "name": "bar", "val": true, }, Object { "column": 11, "filename": "attrs.tokens.json", "line": 14, "mustEscape": true, "name": "baz", "val": true, }, ], "block": Object { "filename": "attrs.tokens.json", "line": 14, "nodes": Array [], "type": "Block", }, "column": 1, "filename": "attrs.tokens.json", "isInline": true, "line": 14, "name": "a", "selfClosing": false, "type": "Tag", }, Object { "attributeBlocks": Array [], "attrs": Array [ Object { "column": 3, "filename": "attrs.tokens.json", "line": 15, "mustEscape": true, "name": "foo", "val": "'foo, bar, baz'", }, Object { "column": 23, "filename": "attrs.tokens.json", "line": 15, "mustEscape": true, "name": "bar", "val": "1", }, ], "block": Object { "filename": "attrs.tokens.json", "line": 15, "nodes": Array [], "type": "Block", }, "column": 1, "filename": "attrs.tokens.json", "isInline": true, "line": 15, "name": "a", "selfClosing": false, "type": "Tag", }, Object { "attributeBlocks": Array [], "attrs": Array [ Object { "column": 3, "filename": "attrs.tokens.json", "line": 16, "mustEscape": true, "name": "foo", "val": "'((foo))'", }, Object { "column": 17, "filename": "attrs.tokens.json", "line": 16, "mustEscape": true, "name": "bar", "val": "(1) ? 1 : 0", }, ], "block": Object { "filename": "attrs.tokens.json", "line": 16, "nodes": Array [], "type": "Block", }, "column": 1, "filename": "attrs.tokens.json", "isInline": true, "line": 16, "name": "a", "selfClosing": false, "type": "Tag", }, Object { "attributeBlocks": Array [], "attrs": Array [], "block": Object { "filename": "attrs.tokens.json", "line": 17, "nodes": Array [ Object { "attributeBlocks": Array [], "attrs": Array [ Object { "column": 10, "filename": "attrs.tokens.json", "line": 18, "mustEscape": true, "name": "value", "val": "'foo'", }, Object { "column": 22, "filename": "attrs.tokens.json", "line": 18, "mustEscape": true, "name": "selected", "val": true, }, ], "block": Object { "filename": "attrs.tokens.json", "line": 18, "nodes": Array [ Object { "column": 32, "filename": "attrs.tokens.json", "line": 18, "type": "Text", "val": "Foo", }, ], "type": "Block", }, "column": 3, "filename": "attrs.tokens.json", "isInline": false, "line": 18, "name": "option", "selfClosing": false, "type": "Tag", }, Object { "attributeBlocks": Array [], "attrs": Array [ Object { "column": 10, "filename": "attrs.tokens.json", "line": 19, "mustEscape": true, "name": "selected", "val": true, }, Object { "column": 19, "filename": "attrs.tokens.json", "line": 19, "mustEscape": true, "name": "value", "val": "'bar'", }, ], "block": Object { "filename": "attrs.tokens.json", "line": 19, "nodes": Array [ Object { "column": 32, "filename": "attrs.tokens.json", "line": 19, "type": "Text", "val": "Bar", }, ], "type": "Block", }, "column": 3, "filename": "attrs.tokens.json", "isInline": false, "line": 19, "name": "option", "selfClosing": false, "type": "Tag", }, ], "type": "Block", }, "column": 1, "filename": "attrs.tokens.json", "isInline": false, "line": 17, "name": "select", "selfClosing": false, "type": "Tag", }, Object { "attributeBlocks": Array [], "attrs": Array [ Object { "column": 3, "filename": "attrs.tokens.json", "line": 20, "mustEscape": true, "name": "foo", "val": "\\"class:\\"", }, ], "block": Object { "filename": "attrs.tokens.json", "line": 20, "nodes": Array [], "type": "Block", }, "column": 1, "filename": "attrs.tokens.json", "isInline": true, "line": 20, "name": "a", "selfClosing": false, "type": "Tag", }, Object { "attributeBlocks": Array [], "attrs": Array [ Object { "column": 7, "filename": "attrs.tokens.json", "line": 21, "mustEscape": true, "name": "pattern", "val": "'\\\\\\\\S+'", }, ], "block": Object { "filename": "attrs.tokens.json", "line": 21, "nodes": Array [], "type": "Block", }, "column": 1, "filename": "attrs.tokens.json", "isInline": false, "line": 21, "name": "input", "selfClosing": false, "type": "Tag", }, Object { "attributeBlocks": Array [], "attrs": Array [ Object { "column": 5, "filename": "attrs.tokens.json", "line": 22, "mustEscape": true, "name": "terse", "val": "\\"true\\"", }, ], "block": Object { "filename": "attrs.tokens.json", "line": 22, "nodes": Array [], "type": "Block", }, "column": 1, "filename": "attrs.tokens.json", "isInline": false, "line": 22, "name": "foo", "selfClosing": false, "type": "Tag", }, Object { "attributeBlocks": Array [], "attrs": Array [ Object { "column": 5, "filename": "attrs.tokens.json", "line": 23, "mustEscape": true, "name": "date", "val": "new Date(0)", }, ], "block": Object { "filename": "attrs.tokens.json", "line": 23, "nodes": Array [], "type": "Block", }, "column": 1, "filename": "attrs.tokens.json", "isInline": false, "line": 23, "name": "foo", "selfClosing": false, "type": "Tag", }, Object { "attributeBlocks": Array [], "attrs": Array [ Object { "column": 5, "filename": "attrs.tokens.json", "line": 25, "mustEscape": true, "name": "abc", "val": true, }, Object { "column": 5, "filename": "attrs.tokens.json", "line": 26, "mustEscape": true, "name": "def", "val": true, }, ], "block": Object { "filename": "attrs.tokens.json", "line": 25, "nodes": Array [], "type": "Block", }, "column": 1, "filename": "attrs.tokens.json", "isInline": false, "line": 25, "name": "foo", "selfClosing": false, "type": "Tag", }, Object { "attributeBlocks": Array [], "attrs": Array [ Object { "column": 5, "filename": "attrs.tokens.json", "line": 27, "mustEscape": true, "name": "abc", "val": true, }, Object { "column": 5, "filename": "attrs.tokens.json", "line": 28, "mustEscape": true, "name": "def", "val": true, }, ], "block": Object { "filename": "attrs.tokens.json", "line": 27, "nodes": Array [], "type": "Block", }, "column": 1, "filename": "attrs.tokens.json", "isInline": false, "line": 27, "name": "foo", "selfClosing": false, "type": "Tag", }, Object { "attributeBlocks": Array [], "attrs": Array [ Object { "column": 5, "filename": "attrs.tokens.json", "line": 29, "mustEscape": true, "name": "abc", "val": true, }, Object { "column": 3, "filename": "attrs.tokens.json", "line": 30, "mustEscape": true, "name": "def", "val": true, }, ], "block": Object { "filename": "attrs.tokens.json", "line": 29, "nodes": Array [], "type": "Block", }, "column": 1, "filename": "attrs.tokens.json", "isInline": false, "line": 29, "name": "foo", "selfClosing": false, "type": "Tag", }, Object { "attributeBlocks": Array [], "attrs": Array [ Object { "column": 5, "filename": "attrs.tokens.json", "line": 31, "mustEscape": true, "name": "abc", "val": true, }, Object { "column": 4, "filename": "attrs.tokens.json", "line": 32, "mustEscape": true, "name": "def", "val": true, }, ], "block": Object { "filename": "attrs.tokens.json", "line": 31, "nodes": Array [], "type": "Block", }, "column": 1, "filename": "attrs.tokens.json", "isInline": false, "line": 31, "name": "foo", "selfClosing": false, "type": "Tag", }, Object { "attributeBlocks": Array [], "attrs": Array [ Object { "column": 5, "filename": "attrs.tokens.json", "line": 33, "mustEscape": true, "name": "abc", "val": true, }, Object { "column": 3, "filename": "attrs.tokens.json", "line": 34, "mustEscape": true, "name": "def", "val": true, }, ], "block": Object { "filename": "attrs.tokens.json", "line": 33, "nodes": Array [], "type": "Block", }, "column": 1, "filename": "attrs.tokens.json", "isInline": false, "line": 33, "name": "foo", "selfClosing": false, "type": "Tag", }, Object { "attributeBlocks": Array [], "attrs": Array [ Object { "column": 5, "filename": "attrs.tokens.json", "line": 35, "mustEscape": true, "name": "abc", "val": true, }, Object { "column": 5, "filename": "attrs.tokens.json", "line": 36, "mustEscape": true, "name": "def", "val": true, }, ], "block": Object { "filename": "attrs.tokens.json", "line": 35, "nodes": Array [], "type": "Block", }, "column": 1, "filename": "attrs.tokens.json", "isInline": false, "line": 35, "name": "foo", "selfClosing": false, "type": "Tag", }, Object { "buffer": false, "column": 1, "filename": "attrs.tokens.json", "isInline": false, "line": 38, "mustEscape": false, "type": "Code", "val": "var attrs = {foo: 'bar', bar: ''}", }, Object { "attributeBlocks": Array [ Object { "column": 4, "filename": "attrs.tokens.json", "line": 40, "type": "AttributeBlock", "val": "attrs", }, ], "attrs": Array [], "block": Object { "filename": "attrs.tokens.json", "line": 40, "nodes": Array [], "type": "Block", }, "column": 1, "filename": "attrs.tokens.json", "isInline": false, "line": 40, "name": "div", "selfClosing": false, "type": "Tag", }, Object { "attributeBlocks": Array [], "attrs": Array [ Object { "column": 3, "filename": "attrs.tokens.json", "line": 42, "mustEscape": true, "name": "foo", "val": "'foo'", }, Object { "column": 13, "filename": "attrs.tokens.json", "line": 42, "mustEscape": true, "name": "bar", "val": "\\"bar\\"", }, ], "block": Object { "filename": "attrs.tokens.json", "line": 42, "nodes": Array [], "type": "Block", }, "column": 1, "filename": "attrs.tokens.json", "isInline": true, "line": 42, "name": "a", "selfClosing": false, "type": "Tag", }, Object { "attributeBlocks": Array [], "attrs": Array [ Object { "column": 3, "filename": "attrs.tokens.json", "line": 43, "mustEscape": true, "name": "foo", "val": "'foo'", }, Object { "column": 13, "filename": "attrs.tokens.json", "line": 43, "mustEscape": true, "name": "bar", "val": "'bar'", }, ], "block": Object { "filename": "attrs.tokens.json", "line": 43, "nodes": Array [], "type": "Block", }, "column": 1, "filename": "attrs.tokens.json", "isInline": true, "line": 43, "name": "a", "selfClosing": false, "type": "Tag", }, ], "type": "Block", } `; exports[`attrs.unescaped.tokens.json 1`] = ` Object { "filename": "attrs.unescaped.tokens.json", "line": 0, "nodes": Array [ Object { "attributeBlocks": Array [], "attrs": Array [ Object { "column": 8, "filename": "attrs.unescaped.tokens.json", "line": 1, "mustEscape": true, "name": "type", "val": "'text/x-template'", }, ], "block": Object { "filename": "attrs.unescaped.tokens.json", "line": 1, "nodes": Array [ Object { "attributeBlocks": Array [], "attrs": Array [ Object { "column": 7, "filename": "attrs.unescaped.tokens.json", "line": 2, "mustEscape": false, "name": "id", "val": "'user-<%= user.id %>'", }, ], "block": Object { "filename": "attrs.unescaped.tokens.json", "line": 2, "nodes": Array [ Object { "attributeBlocks": Array [], "attrs": Array [], "block": Object { "filename": "attrs.unescaped.tokens.json", "line": 3, "nodes": Array [ Object { "column": 8, "filename": "attrs.unescaped.tokens.json", "line": 3, "type": "Text", "val": "<%= user.title %>", }, ], "type": "Block", }, "column": 5, "filename": "attrs.unescaped.tokens.json", "isInline": false, "line": 3, "name": "h1", "selfClosing": false, "type": "Tag", }, ], "type": "Block", }, "column": 3, "filename": "attrs.unescaped.tokens.json", "isInline": false, "line": 2, "name": "div", "selfClosing": false, "type": "Tag", }, ], "type": "Block", }, "column": 1, "filename": "attrs.unescaped.tokens.json", "isInline": false, "line": 1, "name": "script", "selfClosing": false, "type": "Tag", }, ], "type": "Block", } `; exports[`attrs-data.tokens.json 1`] = ` Object { "filename": "attrs-data.tokens.json", "line": 0, "nodes": Array [ Object { "buffer": false, "column": 1, "filename": "attrs-data.tokens.json", "isInline": false, "line": 1, "mustEscape": false, "type": "Code", "val": "var user = { name: 'tobi' }", }, Object { "attributeBlocks": Array [], "attrs": Array [ Object { "column": 5, "filename": "attrs-data.tokens.json", "line": 2, "mustEscape": true, "name": "data-user", "val": "user", }, ], "block": Object { "filename": "attrs-data.tokens.json", "line": 2, "nodes": Array [], "type": "Block", }, "column": 1, "filename": "attrs-data.tokens.json", "isInline": false, "line": 2, "name": "foo", "selfClosing": false, "type": "Tag", }, Object { "attributeBlocks": Array [], "attrs": Array [ Object { "column": 5, "filename": "attrs-data.tokens.json", "line": 3, "mustEscape": true, "name": "data-items", "val": "[1,2,3]", }, ], "block": Object { "filename": "attrs-data.tokens.json", "line": 3, "nodes": Array [], "type": "Block", }, "column": 1, "filename": "attrs-data.tokens.json", "isInline": false, "line": 3, "name": "foo", "selfClosing": false, "type": "Tag", }, Object { "attributeBlocks": Array [], "attrs": Array [ Object { "column": 5, "filename": "attrs-data.tokens.json", "line": 4, "mustEscape": true, "name": "data-username", "val": "'tobi'", }, ], "block": Object { "filename": "attrs-data.tokens.json", "line": 4, "nodes": Array [], "type": "Block", }, "column": 1, "filename": "attrs-data.tokens.json", "isInline": false, "line": 4, "name": "foo", "selfClosing": false, "type": "Tag", }, Object { "attributeBlocks": Array [], "attrs": Array [ Object { "column": 5, "filename": "attrs-data.tokens.json", "line": 5, "mustEscape": true, "name": "data-escaped", "val": "{message: \\"Let's rock!\\"}", }, ], "block": Object { "filename": "attrs-data.tokens.json", "line": 5, "nodes": Array [], "type": "Block", }, "column": 1, "filename": "attrs-data.tokens.json", "isInline": false, "line": 5, "name": "foo", "selfClosing": false, "type": "Tag", }, Object { "attributeBlocks": Array [], "attrs": Array [ Object { "column": 5, "filename": "attrs-data.tokens.json", "line": 6, "mustEscape": true, "name": "data-ampersand", "val": "{message: \\"a quote: " this & that\\"}", }, ], "block": Object { "filename": "attrs-data.tokens.json", "line": 6, "nodes": Array [], "type": "Block", }, "column": 1, "filename": "attrs-data.tokens.json", "isInline": false, "line": 6, "name": "foo", "selfClosing": false, "type": "Tag", }, Object { "attributeBlocks": Array [], "attrs": Array [ Object { "column": 5, "filename": "attrs-data.tokens.json", "line": 7, "mustEscape": true, "name": "data-epoc", "val": "new Date(0)", }, ], "block": Object { "filename": "attrs-data.tokens.json", "line": 7, "nodes": Array [], "type": "Block", }, "column": 1, "filename": "attrs-data.tokens.json", "isInline": false, "line": 7, "name": "foo", "selfClosing": false, "type": "Tag", }, ], "type": "Block", } `; exports[`basic.tokens.json 1`] = ` Object { "filename": "basic.tokens.json", "line": 0, "nodes": Array [ Object { "attributeBlocks": Array [], "attrs": Array [], "block": Object { "filename": "basic.tokens.json", "line": 1, "nodes": Array [ Object { "attributeBlocks": Array [], "attrs": Array [], "block": Object { "filename": "basic.tokens.json", "line": 2, "nodes": Array [ Object { "attributeBlocks": Array [], "attrs": Array [], "block": Object { "filename": "basic.tokens.json", "line": 3, "nodes": Array [ Object { "column": 8, "filename": "basic.tokens.json", "line": 3, "type": "Text", "val": "Title", }, ], "type": "Block", }, "column": 5, "filename": "basic.tokens.json", "isInline": false, "line": 3, "name": "h1", "selfClosing": false, "type": "Tag", }, ], "type": "Block", }, "column": 3, "filename": "basic.tokens.json", "isInline": false, "line": 2, "name": "body", "selfClosing": false, "type": "Tag", }, ], "type": "Block", }, "column": 1, "filename": "basic.tokens.json", "isInline": false, "line": 1, "name": "html", "selfClosing": false, "type": "Tag", }, ], "type": "Block", } `; exports[`blanks.tokens.json 1`] = ` Object { "filename": "blanks.tokens.json", "line": 0, "nodes": Array [ Object { "attributeBlocks": Array [], "attrs": Array [], "block": Object { "filename": "blanks.tokens.json", "line": 3, "nodes": Array [ Object { "attributeBlocks": Array [], "attrs": Array [], "block": Object { "filename": "blanks.tokens.json", "line": 4, "nodes": Array [ Object { "column": 6, "filename": "blanks.tokens.json", "line": 4, "type": "Text", "val": "foo", }, ], "type": "Block", }, "column": 3, "filename": "blanks.tokens.json", "isInline": false, "line": 4, "name": "li", "selfClosing": false, "type": "Tag", }, Object { "attributeBlocks": Array [], "attrs": Array [], "block": Object { "filename": "blanks.tokens.json", "line": 6, "nodes": Array [ Object { "column": 6, "filename": "blanks.tokens.json", "line": 6, "type": "Text", "val": "bar", }, ], "type": "Block", }, "column": 3, "filename": "blanks.tokens.json", "isInline": false, "line": 6, "name": "li", "selfClosing": false, "type": "Tag", }, Object { "attributeBlocks": Array [], "attrs": Array [], "block": Object { "filename": "blanks.tokens.json", "line": 8, "nodes": Array [ Object { "column": 6, "filename": "blanks.tokens.json", "line": 8, "type": "Text", "val": "baz", }, ], "type": "Block", }, "column": 3, "filename": "blanks.tokens.json", "isInline": false, "line": 8, "name": "li", "selfClosing": false, "type": "Tag", }, ], "type": "Block", }, "column": 1, "filename": "blanks.tokens.json", "isInline": false, "line": 3, "name": "ul", "selfClosing": false, "type": "Tag", }, ], "type": "Block", } `; exports[`block-code.tokens.json 1`] = ` Object { "filename": "block-code.tokens.json", "line": 0, "nodes": Array [ Object { "buffer": false, "column": 1, "filename": "block-code.tokens.json", "isInline": false, "line": 1, "mustEscape": false, "type": "Code", "val": "list = [\\"uno\\", \\"dos\\", \\"tres\\", \\"cuatro\\", \\"cinco\\", \\"seis\\"];", }, Object { "buffer": false, "column": 1, "filename": "block-code.tokens.json", "line": 4, "type": "Comment", "val": " Without a block, the element is accepted and no code is generated", }, Object { "buffer": false, "column": 1, "filename": "block-code.tokens.json", "isInline": false, "line": 5, "mustEscape": false, "type": "Code", "val": "", }, Object { "block": Object { "filename": "block-code.tokens.json", "line": 7, "nodes": Array [ Object { "buffer": false, "column": 3, "filename": "block-code.tokens.json", "isInline": false, "line": 7, "mustEscape": false, "type": "Code", "val": "string = item.charAt(0) .toUpperCase() + item.slice(1);", }, Object { "attributeBlocks": Array [], "attrs": Array [], "block": Object { "filename": "block-code.tokens.json", "line": 12, "nodes": Array [ Object { "buffer": true, "column": 5, "filename": "block-code.tokens.json", "isInline": true, "line": 12, "mustEscape": true, "type": "Code", "val": "string", }, ], "type": "Block", }, "column": 3, "filename": "block-code.tokens.json", "isInline": false, "line": 12, "name": "li", "selfClosing": false, "type": "Tag", }, ], "type": "Block", }, "column": 1, "filename": "block-code.tokens.json", "key": null, "line": 6, "obj": "list", "type": "Each", "val": "item", }, ], "type": "Block", } `; exports[`block-expansion.shorthands.tokens.json 1`] = ` Object { "filename": "block-expansion.shorthands.tokens.json", "line": 0, "nodes": Array [ Object { "attributeBlocks": Array [], "attrs": Array [], "block": Object { "filename": "block-expansion.shorthands.tokens.json", "line": 1, "nodes": Array [ Object { "attributeBlocks": Array [], "attrs": Array [ Object { "column": 5, "filename": "block-expansion.shorthands.tokens.json", "line": 2, "mustEscape": false, "name": "class", "val": "'list-item'", }, ], "block": Object { "filename": "block-expansion.shorthands.tokens.json", "line": 2, "nodes": Array [ Object { "attributeBlocks": Array [], "attrs": Array [ Object { "column": 17, "filename": "block-expansion.shorthands.tokens.json", "line": 2, "mustEscape": false, "name": "class", "val": "'foo'", }, ], "block": Object { "filename": "block-expansion.shorthands.tokens.json", "line": 2, "nodes": Array [ Object { "attributeBlocks": Array [], "attrs": Array [ Object { "column": 23, "filename": "block-expansion.shorthands.tokens.json", "line": 2, "mustEscape": false, "name": "id", "val": "'bar'", }, ], "block": Object { "filename": "block-expansion.shorthands.tokens.json", "line": 2, "nodes": Array [ Object { "column": 28, "filename": "block-expansion.shorthands.tokens.json", "line": 2, "type": "Text", "val": "baz", }, ], "type": "Block", }, "column": 23, "filename": "block-expansion.shorthands.tokens.json", "isInline": false, "line": 2, "name": "div", "selfClosing": false, "type": "Tag", }, ], "type": "Block", }, "column": 17, "filename": "block-expansion.shorthands.tokens.json", "isInline": false, "line": 2, "name": "div", "selfClosing": false, "type": "Tag", }, ], "type": "Block", }, "column": 3, "filename": "block-expansion.shorthands.tokens.json", "isInline": false, "line": 2, "name": "li", "selfClosing": false, "type": "Tag", }, ], "type": "Block", }, "column": 1, "filename": "block-expansion.shorthands.tokens.json", "isInline": false, "line": 1, "name": "ul", "selfClosing": false, "type": "Tag", }, ], "type": "Block", } `; exports[`block-expansion.tokens.json 1`] = ` Object { "filename": "block-expansion.tokens.json", "line": 0, "nodes": Array [ Object { "attributeBlocks": Array [], "attrs": Array [], "block": Object { "filename": "block-expansion.tokens.json", "line": 1, "nodes": Array [ Object { "attributeBlocks": Array [], "attrs": Array [], "block": Object { "filename": "block-expansion.tokens.json", "line": 2, "nodes": Array [ Object { "attributeBlocks": Array [], "attrs": Array [ Object { "column": 9, "filename": "block-expansion.tokens.json", "line": 2, "mustEscape": true, "name": "href", "val": "'#'", }, ], "block": Object { "filename": "block-expansion.tokens.json", "line": 2, "nodes": Array [ Object { "column": 19, "filename": "block-expansion.tokens.json", "line": 2, "type": "Text", "val": "foo", }, ], "type": "Block", }, "column": 7, "filename": "block-expansion.tokens.json", "isInline": true, "line": 2, "name": "a", "selfClosing": false, "type": "Tag", }, ], "type": "Block", }, "column": 3, "filename": "block-expansion.tokens.json", "isInline": false, "line": 2, "name": "li", "selfClosing": false, "type": "Tag", }, Object { "attributeBlocks": Array [], "attrs": Array [], "block": Object { "filename": "block-expansion.tokens.json", "line": 3, "nodes": Array [ Object { "attributeBlocks": Array [], "attrs": Array [ Object { "column": 9, "filename": "block-expansion.tokens.json", "line": 3, "mustEscape": true, "name": "href", "val": "'#'", }, ], "block": Object { "filename": "block-expansion.tokens.json", "line": 3, "nodes": Array [ Object { "column": 19, "filename": "block-expansion.tokens.json", "line": 3, "type": "Text", "val": "bar", }, ], "type": "Block", }, "column": 7, "filename": "block-expansion.tokens.json", "isInline": true, "line": 3, "name": "a", "selfClosing": false, "type": "Tag", }, ], "type": "Block", }, "column": 3, "filename": "block-expansion.tokens.json", "isInline": false, "line": 3, "name": "li", "selfClosing": false, "type": "Tag", }, ], "type": "Block", }, "column": 1, "filename": "block-expansion.tokens.json", "isInline": false, "line": 1, "name": "ul", "selfClosing": false, "type": "Tag", }, Object { "attributeBlocks": Array [], "attrs": Array [], "block": Object { "filename": "block-expansion.tokens.json", "line": 5, "nodes": Array [ Object { "column": 3, "filename": "block-expansion.tokens.json", "line": 5, "type": "Text", "val": "baz", }, ], "type": "Block", }, "column": 1, "filename": "block-expansion.tokens.json", "isInline": false, "line": 5, "name": "p", "selfClosing": false, "type": "Tag", }, ], "type": "Block", } `; exports[`blockquote.tokens.json 1`] = ` Object { "filename": "blockquote.tokens.json", "line": 0, "nodes": Array [ Object { "attributeBlocks": Array [], "attrs": Array [], "block": Object { "filename": "blockquote.tokens.json", "line": 1, "nodes": Array [ Object { "attributeBlocks": Array [], "attrs": Array [], "block": Object { "filename": "blockquote.tokens.json", "line": 2, "nodes": Array [ Object { "column": 7, "filename": "blockquote.tokens.json", "line": 3, "type": "Text", "val": "Try to define yourself by what you do, and you’ll burnout every time. You are. That is enough. I rest in that.", }, ], "type": "Block", }, "column": 3, "filename": "blockquote.tokens.json", "isInline": false, "line": 2, "name": "blockquote", "selfClosing": false, "type": "Tag", }, Object { "attributeBlocks": Array [], "attrs": Array [], "block": Object { "filename": "blockquote.tokens.json", "line": 4, "nodes": Array [ Object { "column": 14, "filename": "blockquote.tokens.json", "line": 4, "type": "Text", "val": "from @thefray at 1:43pm on May 10", }, ], "type": "Block", }, "column": 3, "filename": "blockquote.tokens.json", "isInline": false, "line": 4, "name": "figcaption", "selfClosing": false, "type": "Tag", }, ], "type": "Block", }, "column": 1, "filename": "blockquote.tokens.json", "isInline": false, "line": 1, "name": "figure", "selfClosing": false, "type": "Tag", }, ], "type": "Block", } `; exports[`blocks-in-blocks.tokens.json 1`] = ` Object { "filename": "blocks-in-blocks.tokens.json", "line": 0, "nodes": Array [ Object { "column": 1, "file": Object { "column": 9, "filename": "blocks-in-blocks.tokens.json", "line": 1, "path": "./auxiliary/blocks-in-blocks-layout.pug", "type": "FileReference", }, "filename": "blocks-in-blocks.tokens.json", "line": 1, "type": "Extends", }, Object { "column": 1, "filename": "blocks-in-blocks.tokens.json", "line": 3, "mode": "replace", "name": "body", "nodes": Array [ Object { "attributeBlocks": Array [], "attrs": Array [], "block": Object { "filename": "blocks-in-blocks.tokens.json", "line": 4, "nodes": Array [ Object { "column": 6, "filename": "blocks-in-blocks.tokens.json", "line": 4, "type": "Text", "val": "Page 2", }, ], "type": "Block", }, "column": 3, "filename": "blocks-in-blocks.tokens.json", "isInline": false, "line": 4, "name": "h1", "selfClosing": false, "type": "Tag", }, ], "type": "NamedBlock", }, ], "type": "Block", } `; exports[`blocks-in-if.tokens.json 1`] = ` Object { "filename": "blocks-in-if.tokens.json", "line": 0, "nodes": Array [ Object { "buffer": false, "column": 1, "filename": "blocks-in-if.tokens.json", "line": 1, "type": "Comment", "val": " see https://github.com/pugjs/pug/issues/1589", }, Object { "buffer": false, "column": 1, "filename": "blocks-in-if.tokens.json", "isInline": false, "line": 3, "mustEscape": false, "type": "Code", "val": "var ajax = true", }, Object { "block": Object { "filename": "blocks-in-if.tokens.json", "line": 6, "nodes": Array [ Object { "buffer": false, "column": 5, "filename": "blocks-in-if.tokens.json", "line": 6, "type": "Comment", "val": " return only contents if ajax requests", }, Object { "column": 5, "filename": "blocks-in-if.tokens.json", "line": 7, "mode": "replace", "name": "contents", "nodes": Array [ Object { "attributeBlocks": Array [], "attrs": Array [], "block": Object { "filename": "blocks-in-if.tokens.json", "line": 8, "nodes": Array [ Object { "column": 11, "filename": "blocks-in-if.tokens.json", "line": 8, "type": "Text", "val": "ajax contents", }, ], "type": "Block", }, "column": 9, "filename": "blocks-in-if.tokens.json", "isInline": false, "line": 8, "name": "p", "selfClosing": false, "type": "Tag", }, ], "type": "NamedBlock", }, ], "type": "Block", }, "buffer": false, "column": 1, "filename": "blocks-in-if.tokens.json", "isInline": false, "line": 5, "mustEscape": false, "type": "Code", "val": "if( ajax )", }, Object { "block": Object { "filename": "blocks-in-if.tokens.json", "line": 11, "nodes": Array [ Object { "buffer": false, "column": 5, "filename": "blocks-in-if.tokens.json", "line": 11, "type": "Comment", "val": " return all html", }, Object { "column": 5, "filename": "blocks-in-if.tokens.json", "line": 12, "type": "Doctype", "val": "html", }, Object { "attributeBlocks": Array [], "attrs": Array [], "block": Object { "filename": "blocks-in-if.tokens.json", "line": 13, "nodes": Array [ Object { "attributeBlocks": Array [], "attrs": Array [], "block": Object { "filename": "blocks-in-if.tokens.json", "line": 14, "nodes": Array [ Object { "attributeBlocks": Array [], "attrs": Array [ Object { "column": 19, "filename": "blocks-in-if.tokens.json", "line": 15, "mustEscape": true, "name": "charset", "val": "'utf8'", }, ], "block": Object { "filename": "blocks-in-if.tokens.json", "line": 15, "nodes": Array [], "type": "Block", }, "column": 13, "filename": "blocks-in-if.tokens.json", "isInline": false, "line": 15, "name": "meta", "selfClosing": false, "type": "Tag", }, Object { "attributeBlocks": Array [], "attrs": Array [], "block": Object { "filename": "blocks-in-if.tokens.json", "line": 16, "nodes": Array [ Object { "column": 19, "filename": "blocks-in-if.tokens.json", "line": 16, "type": "Text", "val": "sample", }, ], "type": "Block", }, "column": 13, "filename": "blocks-in-if.tokens.json", "isInline": false, "line": 16, "name": "title", "selfClosing": false, "type": "Tag", }, Object { "attributeBlocks": Array [], "attrs": Array [], "block": Object { "filename": "blocks-in-if.tokens.json", "line": 17, "nodes": Array [ Object { "column": 17, "filename": "blocks-in-if.tokens.json", "line": 18, "mode": "replace", "name": "contents", "nodes": Array [ Object { "attributeBlocks": Array [], "attrs": Array [], "block": Object { "filename": "blocks-in-if.tokens.json", "line": 19, "nodes": Array [ Object { "column": 23, "filename": "blocks-in-if.tokens.json", "line": 19, "type": "Text", "val": "all contetns", }, ], "type": "Block", }, "column": 21, "filename": "blocks-in-if.tokens.json", "isInline": false, "line": 19, "name": "p", "selfClosing": false, "type": "Tag", }, ], "type": "NamedBlock", }, ], "type": "Block", }, "column": 13, "filename": "blocks-in-if.tokens.json", "isInline": false, "line": 17, "name": "body", "selfClosing": false, "type": "Tag", }, ], "type": "Block", }, "column": 9, "filename": "blocks-in-if.tokens.json", "isInline": false, "line": 14, "name": "head", "selfClosing": false, "type": "Tag", }, ], "type": "Block", }, "column": 5, "filename": "blocks-in-if.tokens.json", "isInline": false, "line": 13, "name": "html", "selfClosing": false, "type": "Tag", }, ], "type": "Block", }, "buffer": false, "column": 1, "debug": false, "filename": "blocks-in-if.tokens.json", "isInline": false, "line": 10, "mustEscape": false, "type": "Code", "val": "else", }, ], "type": "Block", } `; exports[`case.tokens.json 1`] = ` Object { "filename": "case.tokens.json", "line": 0, "nodes": Array [ Object { "attributeBlocks": Array [], "attrs": Array [], "block": Object { "filename": "case.tokens.json", "line": 1, "nodes": Array [ Object { "attributeBlocks": Array [], "attrs": Array [], "block": Object { "filename": "case.tokens.json", "line": 2, "nodes": Array [ Object { "buffer": false, "column": 5, "filename": "case.tokens.json", "isInline": false, "line": 3, "mustEscape": false, "type": "Code", "val": "var friends = 1", }, Object { "block": Object { "filename": "case.tokens.json", "line": 5, "nodes": Array [ Object { "block": Object { "filename": "case.tokens.json", "line": 5, "nodes": Array [ Object { "attributeBlocks": Array [], "attrs": Array [], "block": Object { "filename": "case.tokens.json", "line": 5, "nodes": Array [ Object { "column": 17, "filename": "case.tokens.json", "line": 5, "type": "Text", "val": "you have no friends", }, ], "type": "Block", }, "column": 15, "filename": "case.tokens.json", "isInline": false, "line": 5, "name": "p", "selfClosing": false, "type": "Tag", }, ], "type": "Block", }, "column": 7, "debug": false, "expr": "0", "filename": "case.tokens.json", "line": 5, "type": "When", }, Object { "block": Object { "filename": "case.tokens.json", "line": 6, "nodes": Array [ Object { "attributeBlocks": Array [], "attrs": Array [], "block": Object { "filename": "case.tokens.json", "line": 6, "nodes": Array [ Object { "column": 17, "filename": "case.tokens.json", "line": 6, "type": "Text", "val": "you have a friend", }, ], "type": "Block", }, "column": 15, "filename": "case.tokens.json", "isInline": false, "line": 6, "name": "p", "selfClosing": false, "type": "Tag", }, ], "type": "Block", }, "column": 7, "debug": false, "expr": "1", "filename": "case.tokens.json", "line": 6, "type": "When", }, Object { "block": Object { "filename": "case.tokens.json", "line": 7, "nodes": Array [ Object { "attributeBlocks": Array [], "attrs": Array [], "block": Object { "filename": "case.tokens.json", "line": 7, "nodes": Array [ Object { "column": 18, "filename": "case.tokens.json", "line": 7, "type": "Text", "val": "you have ", }, Object { "buffer": true, "column": 27, "filename": "case.tokens.json", "isInline": true, "line": 7, "mustEscape": true, "type": "Code", "val": "friends", }, Object { "column": 37, "filename": "case.tokens.json", "line": 7, "type": "Text", "val": " friends", }, ], "type": "Block", }, "column": 16, "filename": "case.tokens.json", "isInline": false, "line": 7, "name": "p", "selfClosing": false, "type": "Tag", }, ], "type": "Block", }, "column": 7, "debug": false, "expr": "default", "filename": "case.tokens.json", "line": 7, "type": "When", }, ], "type": "Block", }, "column": 5, "expr": "friends", "filename": "case.tokens.json", "line": 4, "type": "Case", }, Object { "buffer": false, "column": 5, "filename": "case.tokens.json", "isInline": false, "line": 8, "mustEscape": false, "type": "Code", "val": "var friends = 0", }, Object { "block": Object { "filename": "case.tokens.json", "line": 10, "nodes": Array [ Object { "column": 7, "debug": false, "expr": "0", "filename": "case.tokens.json", "line": 10, "type": "When", }, Object { "block": Object { "filename": "case.tokens.json", "line": 12, "nodes": Array [ Object { "attributeBlocks": Array [], "attrs": Array [], "block": Object { "filename": "case.tokens.json", "line": 12, "nodes": Array [ Object { "column": 11, "filename": "case.tokens.json", "line": 12, "type": "Text", "val": "you have very few friends", }, ], "type": "Block", }, "column": 9, "filename": "case.tokens.json", "isInline": false, "line": 12, "name": "p", "selfClosing": false, "type": "Tag", }, ], "type": "Block", }, "column": 7, "debug": false, "expr": "1", "filename": "case.tokens.json", "line": 11, "type": "When", }, Object { "block": Object { "filename": "case.tokens.json", "line": 14, "nodes": Array [ Object { "attributeBlocks": Array [], "attrs": Array [], "block": Object { "filename": "case.tokens.json", "line": 14, "nodes": Array [ Object { "column": 11, "filename": "case.tokens.json", "line": 14, "type": "Text", "val": "you have ", }, Object { "buffer": true, "column": 20, "filename": "case.tokens.json", "isInline": true, "line": 14, "mustEscape": true, "type": "Code", "val": "friends", }, Object { "column": 30, "filename": "case.tokens.json", "line": 14, "type": "Text", "val": " friends", }, ], "type": "Block", }, "column": 9, "filename": "case.tokens.json", "isInline": false, "line": 14, "name": "p", "selfClosing": false, "type": "Tag", }, ], "type": "Block", }, "column": 7, "debug": false, "expr": "default", "filename": "case.tokens.json", "line": 13, "type": "When", }, ], "type": "Block", }, "column": 5, "expr": "friends", "filename": "case.tokens.json", "line": 9, "type": "Case", }, Object { "buffer": false, "column": 5, "filename": "case.tokens.json", "isInline": false, "line": 16, "mustEscape": false, "type": "Code", "val": "var friend = 'Tim:G'", }, Object { "block": Object { "filename": "case.tokens.json", "line": 18, "nodes": Array [ Object { "block": Object { "filename": "case.tokens.json", "line": 18, "nodes": Array [ Object { "attributeBlocks": Array [], "attrs": Array [], "block": Object { "filename": "case.tokens.json", "line": 18, "nodes": Array [ Object { "column": 26, "filename": "case.tokens.json", "line": 18, "type": "Text", "val": "Friend is a string", }, ], "type": "Block", }, "column": 24, "filename": "case.tokens.json", "isInline": false, "line": 18, "name": "p", "selfClosing": false, "type": "Tag", }, ], "type": "Block", }, "column": 7, "debug": false, "expr": "'Tim:G'", "filename": "case.tokens.json", "line": 18, "type": "When", }, Object { "block": Object { "filename": "case.tokens.json", "line": 19, "nodes": Array [ Object { "attributeBlocks": Array [], "attrs": Array [], "block": Object { "filename": "case.tokens.json", "line": 19, "nodes": Array [ Object { "column": 26, "filename": "case.tokens.json", "line": 19, "type": "Text", "val": "Friend is an object", }, ], "type": "Block", }, "column": 24, "filename": "case.tokens.json", "isInline": false, "line": 19, "name": "p", "selfClosing": false, "type": "Tag", }, ], "type": "Block", }, "column": 7, "debug": false, "expr": "{tim: 'g'}", "filename": "case.tokens.json", "line": 19, "type": "When", }, ], "type": "Block", }, "column": 5, "expr": "friend", "filename": "case.tokens.json", "line": 17, "type": "Case", }, ], "type": "Block", }, "column": 3, "filename": "case.tokens.json", "isInline": false, "line": 2, "name": "body", "selfClosing": false, "type": "Tag", }, ], "type": "Block", }, "column": 1, "filename": "case.tokens.json", "isInline": false, "line": 1, "name": "html", "selfClosing": false, "type": "Tag", }, ], "type": "Block", } `; exports[`case-blocks.tokens.json 1`] = ` Object { "filename": "case-blocks.tokens.json", "line": 0, "nodes": Array [ Object { "attributeBlocks": Array [], "attrs": Array [], "block": Object { "filename": "case-blocks.tokens.json", "line": 1, "nodes": Array [ Object { "attributeBlocks": Array [], "attrs": Array [], "block": Object { "filename": "case-blocks.tokens.json", "line": 2, "nodes": Array [ Object { "buffer": false, "column": 5, "filename": "case-blocks.tokens.json", "isInline": false, "line": 3, "mustEscape": false, "type": "Code", "val": "var friends = 1", }, Object { "block": Object { "filename": "case-blocks.tokens.json", "line": 5, "nodes": Array [ Object { "block": Object { "filename": "case-blocks.tokens.json", "line": 6, "nodes": Array [ Object { "attributeBlocks": Array [], "attrs": Array [], "block": Object { "filename": "case-blocks.tokens.json", "line": 6, "nodes": Array [ Object { "column": 11, "filename": "case-blocks.tokens.json", "line": 6, "type": "Text", "val": "you have no friends", }, ], "type": "Block", }, "column": 9, "filename": "case-blocks.tokens.json", "isInline": false, "line": 6, "name": "p", "selfClosing": false, "type": "Tag", }, ], "type": "Block", }, "column": 7, "debug": false, "expr": "0", "filename": "case-blocks.tokens.json", "line": 5, "type": "When", }, Object { "block": Object { "filename": "case-blocks.tokens.json", "line": 8, "nodes": Array [ Object { "attributeBlocks": Array [], "attrs": Array [], "block": Object { "filename": "case-blocks.tokens.json", "line": 8, "nodes": Array [ Object { "column": 11, "filename": "case-blocks.tokens.json", "line": 8, "type": "Text", "val": "you have a friend", }, ], "type": "Block", }, "column": 9, "filename": "case-blocks.tokens.json", "isInline": false, "line": 8, "name": "p", "selfClosing": false, "type": "Tag", }, ], "type": "Block", }, "column": 7, "debug": false, "expr": "1", "filename": "case-blocks.tokens.json", "line": 7, "type": "When", }, Object { "block": Object { "filename": "case-blocks.tokens.json", "line": 10, "nodes": Array [ Object { "attributeBlocks": Array [], "attrs": Array [], "block": Object { "filename": "case-blocks.tokens.json", "line": 10, "nodes": Array [ Object { "column": 11, "filename": "case-blocks.tokens.json", "line": 10, "type": "Text", "val": "you have ", }, Object { "buffer": true, "column": 20, "filename": "case-blocks.tokens.json", "isInline": true, "line": 10, "mustEscape": true, "type": "Code", "val": "friends", }, Object { "column": 30, "filename": "case-blocks.tokens.json", "line": 10, "type": "Text", "val": " friends", }, ], "type": "Block", }, "column": 9, "filename": "case-blocks.tokens.json", "isInline": false, "line": 10, "name": "p", "selfClosing": false, "type": "Tag", }, ], "type": "Block", }, "column": 7, "debug": false, "expr": "default", "filename": "case-blocks.tokens.json", "line": 9, "type": "When", }, ], "type": "Block", }, "column": 5, "expr": "friends", "filename": "case-blocks.tokens.json", "line": 4, "type": "Case", }, ], "type": "Block", }, "column": 3, "filename": "case-blocks.tokens.json", "isInline": false, "line": 2, "name": "body", "selfClosing": false, "type": "Tag", }, ], "type": "Block", }, "column": 1, "filename": "case-blocks.tokens.json", "isInline": false, "line": 1, "name": "html", "selfClosing": false, "type": "Tag", }, ], "type": "Block", } `; exports[`classes.tokens.json 1`] = ` Object { "filename": "classes.tokens.json", "line": 0, "nodes": Array [ Object { "attributeBlocks": Array [], "attrs": Array [ Object { "column": 3, "filename": "classes.tokens.json", "line": 1, "mustEscape": true, "name": "class", "val": "['foo', 'bar', 'baz']", }, ], "block": Object { "filename": "classes.tokens.json", "line": 1, "nodes": Array [], "type": "Block", }, "column": 1, "filename": "classes.tokens.json", "isInline": true, "line": 1, "name": "a", "selfClosing": false, "type": "Tag", }, Object { "attributeBlocks": Array [], "attrs": Array [ Object { "column": 2, "filename": "classes.tokens.json", "line": 5, "mustEscape": false, "name": "class", "val": "'foo'", }, Object { "column": 7, "filename": "classes.tokens.json", "line": 5, "mustEscape": true, "name": "class", "val": "'bar'", }, Object { "column": 19, "filename": "classes.tokens.json", "line": 5, "mustEscape": false, "name": "class", "val": "'baz'", }, ], "block": Object { "filename": "classes.tokens.json", "line": 5, "nodes": Array [], "type": "Block", }, "column": 1, "filename": "classes.tokens.json", "isInline": true, "line": 5, "name": "a", "selfClosing": false, "type": "Tag", }, Object { "attributeBlocks": Array [], "attrs": Array [ Object { "column": 2, "filename": "classes.tokens.json", "line": 9, "mustEscape": false, "name": "class", "val": "'foo-bar_baz'", }, ], "block": Object { "filename": "classes.tokens.json", "line": 9, "nodes": Array [], "type": "Block", }, "column": 1, "filename": "classes.tokens.json", "isInline": true, "line": 9, "name": "a", "selfClosing": false, "type": "Tag", }, Object { "attributeBlocks": Array [], "attrs": Array [ Object { "column": 3, "filename": "classes.tokens.json", "line": 11, "mustEscape": true, "name": "class", "val": "{foo: true, bar: false, baz: true}", }, ], "block": Object { "filename": "classes.tokens.json", "line": 11, "nodes": Array [], "type": "Block", }, "column": 1, "filename": "classes.tokens.json", "isInline": true, "line": 11, "name": "a", "selfClosing": false, "type": "Tag", }, Object { "attributeBlocks": Array [], "attrs": Array [ Object { "column": 2, "filename": "classes.tokens.json", "line": 13, "mustEscape": false, "name": "class", "val": "'-foo'", }, ], "block": Object { "filename": "classes.tokens.json", "line": 13, "nodes": Array [], "type": "Block", }, "column": 1, "filename": "classes.tokens.json", "isInline": true, "line": 13, "name": "a", "selfClosing": false, "type": "Tag", }, Object { "attributeBlocks": Array [], "attrs": Array [ Object { "column": 2, "filename": "classes.tokens.json", "line": 14, "mustEscape": false, "name": "class", "val": "'3foo'", }, ], "block": Object { "filename": "classes.tokens.json", "line": 14, "nodes": Array [], "type": "Block", }, "column": 1, "filename": "classes.tokens.json", "isInline": true, "line": 14, "name": "a", "selfClosing": false, "type": "Tag", }, ], "type": "Block", } `; exports[`classes-empty.tokens.json 1`] = ` Object { "filename": "classes-empty.tokens.json", "line": 0, "nodes": Array [ Object { "attributeBlocks": Array [], "attrs": Array [ Object { "column": 3, "filename": "classes-empty.tokens.json", "line": 1, "mustEscape": true, "name": "class", "val": "''", }, ], "block": Object { "filename": "classes-empty.tokens.json", "line": 1, "nodes": Array [], "type": "Block", }, "column": 1, "filename": "classes-empty.tokens.json", "isInline": true, "line": 1, "name": "a", "selfClosing": false, "type": "Tag", }, Object { "attributeBlocks": Array [], "attrs": Array [ Object { "column": 3, "filename": "classes-empty.tokens.json", "line": 2, "mustEscape": true, "name": "class", "val": "null", }, ], "block": Object { "filename": "classes-empty.tokens.json", "line": 2, "nodes": Array [], "type": "Block", }, "column": 1, "filename": "classes-empty.tokens.json", "isInline": true, "line": 2, "name": "a", "selfClosing": false, "type": "Tag", }, Object { "attributeBlocks": Array [], "attrs": Array [ Object { "column": 3, "filename": "classes-empty.tokens.json", "line": 3, "mustEscape": true, "name": "class", "val": "undefined", }, ], "block": Object { "filename": "classes-empty.tokens.json", "line": 3, "nodes": Array [], "type": "Block", }, "column": 1, "filename": "classes-empty.tokens.json", "isInline": true, "line": 3, "name": "a", "selfClosing": false, "type": "Tag", }, ], "type": "Block", } `; exports[`code.conditionals.tokens.json 1`] = ` Object { "filename": "code.conditionals.tokens.json", "line": 0, "nodes": Array [ Object { "block": Object { "filename": "code.conditionals.tokens.json", "line": 3, "nodes": Array [ Object { "attributeBlocks": Array [], "attrs": Array [], "block": Object { "filename": "code.conditionals.tokens.json", "line": 3, "nodes": Array [ Object { "column": 5, "filename": "code.conditionals.tokens.json", "line": 3, "type": "Text", "val": "foo", }, ], "type": "Block", }, "column": 3, "filename": "code.conditionals.tokens.json", "isInline": false, "line": 3, "name": "p", "selfClosing": false, "type": "Tag", }, ], "type": "Block", }, "buffer": false, "column": 1, "filename": "code.conditionals.tokens.json", "isInline": false, "line": 2, "mustEscape": false, "type": "Code", "val": "if (true)", }, Object { "block": Object { "filename": "code.conditionals.tokens.json", "line": 5, "nodes": Array [ Object { "attributeBlocks": Array [], "attrs": Array [], "block": Object { "filename": "code.conditionals.tokens.json", "line": 5, "nodes": Array [ Object { "column": 5, "filename": "code.conditionals.tokens.json", "line": 5, "type": "Text", "val": "bar", }, ], "type": "Block", }, "column": 3, "filename": "code.conditionals.tokens.json", "isInline": false, "line": 5, "name": "p", "selfClosing": false, "type": "Tag", }, ], "type": "Block", }, "buffer": false, "column": 1, "debug": false, "filename": "code.conditionals.tokens.json", "isInline": false, "line": 4, "mustEscape": false, "type": "Code", "val": "else", }, Object { "block": Object { "filename": "code.conditionals.tokens.json", "line": 8, "nodes": Array [ Object { "attributeBlocks": Array [], "attrs": Array [], "block": Object { "filename": "code.conditionals.tokens.json", "line": 8, "nodes": Array [ Object { "column": 5, "filename": "code.conditionals.tokens.json", "line": 8, "type": "Text", "val": "foo", }, ], "type": "Block", }, "column": 3, "filename": "code.conditionals.tokens.json", "isInline": false, "line": 8, "name": "p", "selfClosing": false, "type": "Tag", }, ], "type": "Block", }, "buffer": false, "column": 1, "filename": "code.conditionals.tokens.json", "isInline": false, "line": 7, "mustEscape": false, "type": "Code", "val": "if (true) {", }, Object { "block": Object { "filename": "code.conditionals.tokens.json", "line": 10, "nodes": Array [ Object { "attributeBlocks": Array [], "attrs": Array [], "block": Object { "filename": "code.conditionals.tokens.json", "line": 10, "nodes": Array [ Object { "column": 5, "filename": "code.conditionals.tokens.json", "line": 10, "type": "Text", "val": "bar", }, ], "type": "Block", }, "column": 3, "filename": "code.conditionals.tokens.json", "isInline": false, "line": 10, "name": "p", "selfClosing": false, "type": "Tag", }, ], "type": "Block", }, "buffer": false, "column": 1, "filename": "code.conditionals.tokens.json", "isInline": false, "line": 9, "mustEscape": false, "type": "Code", "val": "} else {", }, Object { "buffer": false, "column": 1, "filename": "code.conditionals.tokens.json", "isInline": false, "line": 11, "mustEscape": false, "type": "Code", "val": "}", }, Object { "alternate": Object { "filename": "code.conditionals.tokens.json", "line": 18, "nodes": Array [ Object { "attributeBlocks": Array [], "attrs": Array [], "block": Object { "filename": "code.conditionals.tokens.json", "line": 18, "nodes": Array [ Object { "column": 5, "filename": "code.conditionals.tokens.json", "line": 18, "type": "Text", "val": "bar", }, ], "type": "Block", }, "column": 3, "filename": "code.conditionals.tokens.json", "isInline": false, "line": 18, "name": "p", "selfClosing": false, "type": "Tag", }, ], "type": "Block", }, "column": 1, "consequent": Object { "filename": "code.conditionals.tokens.json", "line": 14, "nodes": Array [ Object { "attributeBlocks": Array [], "attrs": Array [], "block": Object { "filename": "code.conditionals.tokens.json", "line": 14, "nodes": Array [ Object { "column": 5, "filename": "code.conditionals.tokens.json", "line": 14, "type": "Text", "val": "foo", }, ], "type": "Block", }, "column": 3, "filename": "code.conditionals.tokens.json", "isInline": false, "line": 14, "name": "p", "selfClosing": false, "type": "Tag", }, Object { "attributeBlocks": Array [], "attrs": Array [], "block": Object { "filename": "code.conditionals.tokens.json", "line": 15, "nodes": Array [ Object { "column": 5, "filename": "code.conditionals.tokens.json", "line": 15, "type": "Text", "val": "bar", }, ], "type": "Block", }, "column": 3, "filename": "code.conditionals.tokens.json", "isInline": false, "line": 15, "name": "p", "selfClosing": false, "type": "Tag", }, Object { "attributeBlocks": Array [], "attrs": Array [], "block": Object { "filename": "code.conditionals.tokens.json", "line": 16, "nodes": Array [ Object { "column": 5, "filename": "code.conditionals.tokens.json", "line": 16, "type": "Text", "val": "baz", }, ], "type": "Block", }, "column": 3, "filename": "code.conditionals.tokens.json", "isInline": false, "line": 16, "name": "p", "selfClosing": false, "type": "Tag", }, ], "type": "Block", }, "filename": "code.conditionals.tokens.json", "line": 13, "test": "true", "type": "Conditional", }, Object { "alternate": Object { "filename": "code.conditionals.tokens.json", "line": 23, "nodes": Array [ Object { "attributeBlocks": Array [], "attrs": Array [], "block": Object { "filename": "code.conditionals.tokens.json", "line": 23, "nodes": Array [ Object { "column": 5, "filename": "code.conditionals.tokens.json", "line": 23, "type": "Text", "val": "bar", }, ], "type": "Block", }, "column": 3, "filename": "code.conditionals.tokens.json", "isInline": false, "line": 23, "name": "p", "selfClosing": false, "type": "Tag", }, ], "type": "Block", }, "column": 1, "consequent": Object { "filename": "code.conditionals.tokens.json", "line": 21, "nodes": Array [ Object { "attributeBlocks": Array [], "attrs": Array [], "block": Object { "filename": "code.conditionals.tokens.json", "line": 21, "nodes": Array [ Object { "column": 5, "filename": "code.conditionals.tokens.json", "line": 21, "type": "Text", "val": "foo", }, ], "type": "Block", }, "column": 3, "filename": "code.conditionals.tokens.json", "isInline": false, "line": 21, "name": "p", "selfClosing": false, "type": "Tag", }, ], "type": "Block", }, "filename": "code.conditionals.tokens.json", "line": 20, "test": "!(true)", "type": "Conditional", }, Object { "alternate": null, "column": 1, "consequent": Object { "filename": "code.conditionals.tokens.json", "line": 26, "nodes": Array [ Object { "alternate": null, "column": 3, "consequent": Object { "filename": "code.conditionals.tokens.json", "line": 27, "nodes": Array [ Object { "attributeBlocks": Array [], "attrs": Array [], "block": Object { "filename": "code.conditionals.tokens.json", "line": 27, "nodes": Array [ Object { "column": 7, "filename": "code.conditionals.tokens.json", "line": 27, "type": "Text", "val": "yay", }, ], "type": "Block", }, "column": 5, "filename": "code.conditionals.tokens.json", "isInline": false, "line": 27, "name": "p", "selfClosing": false, "type": "Tag", }, ], "type": "Block", }, "filename": "code.conditionals.tokens.json", "line": 26, "test": "'works'", "type": "Conditional", }, ], "type": "Block", }, "filename": "code.conditionals.tokens.json", "line": 25, "test": "'nested'", "type": "Conditional", }, Object { "buffer": false, "column": 1, "filename": "code.conditionals.tokens.json", "line": 29, "type": "Comment", "val": " allow empty blocks", }, Object { "alternate": Object { "filename": "code.conditionals.tokens.json", "line": 32, "nodes": Array [ Object { "attributeBlocks": Array [], "attrs": Array [ Object { "column": 3, "filename": "code.conditionals.tokens.json", "line": 32, "mustEscape": false, "name": "class", "val": "'bar'", }, ], "block": Object { "filename": "code.conditionals.tokens.json", "line": 32, "nodes": Array [], "type": "Block", }, "column": 3, "filename": "code.conditionals.tokens.json", "isInline": false, "line": 32, "name": "div", "selfClosing": false, "type": "Tag", }, ], "type": "Block", }, "column": 1, "consequent": Object { "filename": "code.conditionals.tokens.json", "line": 30, "nodes": Array [], "type": "Block", }, "filename": "code.conditionals.tokens.json", "line": 30, "test": "false", "type": "Conditional", }, Object { "alternate": null, "column": 1, "consequent": Object { "filename": "code.conditionals.tokens.json", "line": 34, "nodes": Array [ Object { "attributeBlocks": Array [], "attrs": Array [ Object { "column": 3, "filename": "code.conditionals.tokens.json", "line": 34, "mustEscape": false, "name": "class", "val": "'bar'", }, ], "block": Object { "filename": "code.conditionals.tokens.json", "line": 34, "nodes": Array [], "type": "Block", }, "column": 3, "filename": "code.conditionals.tokens.json", "isInline": false, "line": 34, "name": "div", "selfClosing": false, "type": "Tag", }, ], "type": "Block", }, "filename": "code.conditionals.tokens.json", "line": 33, "test": "true", "type": "Conditional", }, Object { "attributeBlocks": Array [], "attrs": Array [ Object { "column": 1, "filename": "code.conditionals.tokens.json", "line": 36, "mustEscape": false, "name": "class", "val": "'bing'", }, ], "block": Object { "filename": "code.conditionals.tokens.json", "line": 36, "nodes": Array [], "type": "Block", }, "column": 1, "filename": "code.conditionals.tokens.json", "isInline": false, "line": 36, "name": "div", "selfClosing": false, "type": "Tag", }, Object { "alternate": Object { "alternate": Object { "filename": "code.conditionals.tokens.json", "line": 43, "nodes": Array [ Object { "attributeBlocks": Array [], "attrs": Array [ Object { "column": 3, "filename": "code.conditionals.tokens.json", "line": 43, "mustEscape": false, "name": "class", "val": "'foo'", }, ], "block": Object { "filename": "code.conditionals.tokens.json", "line": 43, "nodes": Array [], "type": "Block", }, "column": 3, "filename": "code.conditionals.tokens.json", "isInline": false, "line": 43, "name": "div", "selfClosing": false, "type": "Tag", }, ], "type": "Block", }, "column": 1, "consequent": Object { "filename": "code.conditionals.tokens.json", "line": 41, "nodes": Array [ Object { "attributeBlocks": Array [], "attrs": Array [ Object { "column": 3, "filename": "code.conditionals.tokens.json", "line": 41, "mustEscape": false, "name": "class", "val": "'bar'", }, ], "block": Object { "filename": "code.conditionals.tokens.json", "line": 41, "nodes": Array [], "type": "Block", }, "column": 3, "filename": "code.conditionals.tokens.json", "isInline": false, "line": 41, "name": "div", "selfClosing": false, "type": "Tag", }, ], "type": "Block", }, "filename": "code.conditionals.tokens.json", "line": 40, "test": "false", "type": "Conditional", }, "column": 1, "consequent": Object { "filename": "code.conditionals.tokens.json", "line": 39, "nodes": Array [ Object { "attributeBlocks": Array [], "attrs": Array [ Object { "column": 3, "filename": "code.conditionals.tokens.json", "line": 39, "mustEscape": false, "name": "class", "val": "'bing'", }, ], "block": Object { "filename": "code.conditionals.tokens.json", "line": 39, "nodes": Array [], "type": "Block", }, "column": 3, "filename": "code.conditionals.tokens.json", "isInline": false, "line": 39, "name": "div", "selfClosing": false, "type": "Tag", }, ], "type": "Block", }, "filename": "code.conditionals.tokens.json", "line": 38, "test": "false", "type": "Conditional", }, ], "type": "Block", } `; exports[`code.escape.tokens.json 1`] = ` Object { "filename": "code.escape.tokens.json", "line": 0, "nodes": Array [ Object { "attributeBlocks": Array [], "attrs": Array [], "block": Object { "filename": "code.escape.tokens.json", "line": 1, "nodes": Array [ Object { "buffer": true, "column": 2, "filename": "code.escape.tokens.json", "isInline": true, "line": 1, "mustEscape": true, "type": "Code", "val": "'