Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding 'each .. of' syntax #3179

Merged
merged 5 commits into from Sep 16, 2019
Merged

Adding 'each .. of' syntax #3179

merged 5 commits into from Sep 16, 2019

Conversation

@maxrumsey
Copy link
Contributor

@maxrumsey maxrumsey commented Sep 11, 2019

This PR adds support for iterating over maps and other iterable objects with the JS syntax each var of map. This example patches issue #3170. The syntax each var of map and for var of map has been introduced, but each and for can be used interchangeably, like with the original each syntax.

All tests run and pass, but I haven't added any tests except for a small fix to recognise the eachOf function is the pug-lexer.

Example Code

JS

var pug = require('pug');

var map = new Map([['foo', 'bar'], ['a', 'b']]);

var html = pug.renderFile('code.pug', { some_iterable: map });

console.log(html);

Pug

h1 Pug iteration test file
each el of some_iterable
     p= el[0]
     p= el[1]

Output

<h1>Pug iteration test file</h1><p>foo</p><p>bar</p><p>a</p><p>b</p>
Copy link
Member

@ForbesLindesay ForbesLindesay left a comment

This looks like a good start. I've made a few comments that I hope are helpful.

packages/pug-parser/index.js Outdated Show resolved Hide resolved
packages/pug-lexer/index.js Outdated Show resolved Hide resolved
packages/pug-walk/index.js Outdated Show resolved Hide resolved
+ '// iterate ' + each.obj + '\n'
+ ';(function(){\n'
+ ' var $$obj = ' + each.obj + ';\n'
+ ' if (\'number\' == typeof $$obj.length) {');

This comment has been minimized.

@ForbesLindesay

ForbesLindesay Sep 12, 2019
Member

This will need to use the for (const ... of ...) { js syntax and not refer to length at all as in general iteration objects are not referenced by indexing. We'll need to decide how/if we want to handle the key. One option would be to assume value, key means de-structure as [value, key]. I think it might be better to offer:

each x of foo

and

each [x, y] of foo

rather than supporting:

each x, y of foo

That way, if we wanted to, we'd have a clear path towards supporting more destructuring in the future.

This comment has been minimized.

@maxrumsey

maxrumsey Sep 13, 2019
Author Contributor

I've changed it so you can have

each [key, value] of map

as well as

each keyValPair of map
@maxrumsey
Copy link
Contributor Author

@maxrumsey maxrumsey commented Sep 13, 2019

@ForbesLindesay I've removed all 'else' syntax, and have added the ability to do

each [key, val] of map

Anything else? :)

@maxrumsey maxrumsey requested a review from ForbesLindesay Sep 15, 2019
Copy link
Member

@ForbesLindesay ForbesLindesay left a comment

This is looking loads closer.

packages/pug-lexer/index.js Outdated Show resolved Hide resolved
packages/pug-code-gen/index.js Outdated Show resolved Hide resolved
packages/pug-code-gen/index.js Outdated Show resolved Hide resolved
packages/pug-code-gen/index.js Outdated Show resolved Hide resolved
packages/pug-code-gen/index.js Outdated Show resolved Hide resolved
@maxrumsey
Copy link
Contributor Author

@maxrumsey maxrumsey commented Sep 16, 2019

@ForbesLindesay I've updated the parser as well as the code-gen library. Anything else needing a change?

@maxrumsey maxrumsey requested a review from ForbesLindesay Sep 16, 2019
Copy link
Member

@ForbesLindesay ForbesLindesay left a comment

I think this is probably the last few comments.

packages/pug-lexer/index.js Outdated Show resolved Hide resolved
packages/pug-lexer/index.js Outdated Show resolved Hide resolved
packages/pug-parser/index.js Outdated Show resolved Hide resolved
packages/pug-code-gen/index.js Outdated Show resolved Hide resolved
@maxrumsey
Copy link
Contributor Author

@maxrumsey maxrumsey commented Sep 16, 2019

@ForbesLindesay That's awesome to hear. Anything else that could be fixed up? :)

@maxrumsey maxrumsey requested a review from ForbesLindesay Sep 16, 2019
Copy link
Member

@ForbesLindesay ForbesLindesay left a comment

This looks great. Would you mind following up with a couple of tests cases (in a separate PR)?

You can see https://github.com/pugjs/pug/tree/master/packages/pug/test/extends-not-top-level for a test that covers the error handling - i.e. you can test things like each foo, bar] of bing and https://github.com/pugjs/pug/tree/master/packages/pug/test/shadowed-block gives you an example of testing a successful render. It would be good to have tests for Array, Set and Map.

@ForbesLindesay ForbesLindesay merged commit 8aed002 into pugjs:master Sep 16, 2019
1 check passed
1 check passed
continuous-integration/travis-ci/pr The Travis CI build passed
Details
@ForbesLindesay
Copy link
Member

@ForbesLindesay ForbesLindesay commented Sep 16, 2019

This is now merged and will go in the next release.

@maxrumsey
Copy link
Contributor Author

@maxrumsey maxrumsey commented Sep 17, 2019

That's awesome to hear. Thanks for the help with getting me started. I'll post the PR now.

@nmggithub
Copy link

@nmggithub nmggithub commented Mar 28, 2020

This is now merged and will go in the next release.

Is it available now?

@rollingversions
Copy link

@rollingversions rollingversions bot commented May 24, 2020

pug (2.0.4 → 2.1.0)

New Features

  • Support each ... of ... loops

    each value of iterable
      li= value

    This requires an environment that supports the for (const val of iterable) syntax in JS. You can iterate over Maps, Sets etc. as well as arrays. There is also some destructuring of map keys:

    - const map = new Map([['a', 'x'], ['b', 'y']]);
    each [key, value] of map
      li
        strong= key
        = value

pug-code-gen (2.0.2 → 2.1.0)

New Features

  • Support EachOf nodes

pug-lexer (4.1.0 → 5.0.0)

Breaking Changes

  • Support each ... of ...

    The pug lexer can now output a new token type: eachOf

pug-parser (5.0.1 → 6.0.0)

Breaking Changes

  • Support eachOf tokens and output EachOf nodes

pug-walk (1.1.8 → 1.2.0)

New Features

  • Support EachOf tokens

Packages With No Changes

The following packages have no user facing changes, so won't be released:

  • pug-attrs
  • pug-error
  • pug-filters
  • pug-linker
  • pug-load
  • pug-runtime
  • pug-strip-comments

Edit changelogs

This was referenced Mar 14, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Linked issues

Successfully merging this pull request may close these issues.

None yet

3 participants