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

Allow iteration on a string #620

Merged
merged 1 commit into from
Jun 14, 2021
Merged

Allow iteration on a string #620

merged 1 commit into from
Jun 14, 2021

Conversation

Stepland
Copy link
Contributor

@Stepland Stepland commented Apr 2, 2021

I wanted to add some silly per-character rainbow text for my own blog with this style
image

I managed to do so with split but it feels hacky

{%- macro rainbow(text) -%}
{%- set color_index = 0 -%}
{%- set text_length = text | length -%}
{%- set text_array = text | split(pat="") | slice(start=1, end=-1) -%}
{%- for i in range(end=text_length) -%}
    {%- set char = text_array | nth(n=i) -%}
    {%- if char != " " -%}
        <span class="color-{{ color_index % 6 }}">{{ char }}</span>
        {%- set_global color_index = color_index + 1 -%}
    {%- else %} {% endif -%}
{%- endfor -%}
{%- endmacro input -%}

Adding the ability to iterate on characters with a filter reduces it to

{%- macro rainbow(text) -%}
{%- set color_index = 0 -%}
{%- for char in text | chars -%}
    {%- if char != " " -%}
        <span class="color-{{ color_index % 6 }}">{{ char }}</span>
        {%- set_global color_index = color_index + 1 -%}
    {%- else %} {% endif -%}
{%- endfor -%}
{%- endmacro input -%}

I feel like tera not allowing strings to be iterated on directly was intentional so I chose to implement it as a filter. Using filters also allows for other ways of iterating on a string to be implemented, even though I can't think of another useful way to iterate on a string right now.

@Stepland Stepland changed the title Add chars filter Add chars filter to iterate on characters of a string Apr 3, 2021
@Keats
Copy link
Owner

Keats commented Apr 5, 2021

I feel like tera not allowing strings to be iterated on directly was intentional

Not really, more like an oversight. If it works in Jinja2, it should work here as well in this case.

@Keats
Copy link
Owner

Keats commented May 16, 2021

@Stepland are you interested in implementing iteration on strings?

@Stepland
Copy link
Contributor Author

I'll try !

@Stepland
Copy link
Contributor Author

Stepland commented May 16, 2021

I first tried repurposing ForLoopValues::Array for this but I couldn't figure out how to make it work without turning current_value() into a big mess, so instead I made a new enum variant

Copy link
Owner

@Keats Keats left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM but can you add some tests?

@Keats
Copy link
Owner

Keats commented May 17, 2021

Actually wait, using .chars will not work as expected. You want to make the unic-segment non optional and use that (see the truncate filter for an example).
See https://doc.rust-lang.org/std/primitive.char.html#representation for details

@Stepland
Copy link
Contributor Author

Nice catch !

I added only one test. I think it is enough to check that string iteration gives back grapheme clusters and not something else like codepoints. I feel like adding more tests would just result in testing unic-segment by proxy.

Make unic-segment required
@Stepland Stepland changed the title Add chars filter to iterate on characters of a string Allow iteration on a string May 18, 2021
@Stepland Stepland requested a review from Keats May 23, 2021 10:15
@Keats
Copy link
Owner

Keats commented May 23, 2021

Thanks, I'll merge/release it next week!

@Keats
Copy link
Owner

Keats commented Jun 14, 2021

I should stop giving time estimates haha
Thanks, I'll release it now

@Keats Keats merged commit b133f8e into Keats:master Jun 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
Development

Successfully merging this pull request may close these issues.

2 participants