Jinja multiple rendering streams - stream

Is there any way within a jinja template to render simultaneously to multiple streams?
Lets say I want to render a (printable) quiz, with first all the questions, then all the answers at the end. Each type of question (multiple choice, matching, missing word) is a different template.
Obviously I can take two passes and have question and answer in separate templates. But I would like to do this in one pass, so as to keep the templates well organised, and also to make the python calling code more regular, without a special case to handle this situation).
What I would like to have something like multiple 'streams', similar to blocks, but which which accumulate the output of multiple templates. Obviously the below is fantasy but is there another way within jinja to do this?
{% streams x, y %} {# define twp streams x and y #}
{% stream x %}
aaaa
{% endstream %}
{% stream y %}
bbbb
{% endstream %}
{% stream x %}
cccc
{% endstream %}
{% stream y %}
dddd
{% endstream %}
{{ x }} {# renders aaaacccc #}
{{ y }} {# renders bbbbdddd #}

Rendering to multiple streams is not possible. A simple solution would be to call the template twice, with a question boolean argument, and use if expressions to switch between question and answer code:
{% if questions %}
aaaa
{% else %}
bbbb
{% endif %}
{% if questions %}
cccc
{% else %}
dddd
{% endif %}
Then you call the template:
questions_html = template.render(questions=True)
answers_html = template.render(questions=False)

Related

How to use Latex in dev.to editor?

I wonder is there some way I could render math formulas in dev.to editor to show as mathematical equations in my articles?
It seems that Dev.to supports Katex for mathematical formulas.
From dev.to documents:
KaTeX Embed
Place your mathematical expression within a KaTeX liquid block, as follows:
{% katex %} c = \pm\sqrt{a^2 + b^2} {% endkatex %}
To render KaTeX inline add the "inline" option:
{% katex inline %} c = \pm\sqrt{a^2 + b^2} {% endkatex %}
Info taken also for dev.to github issues.

Jinja2 if value less than zero

I am using Python and Jinja2 to generate a LaTeX table. The following code produces the bottom row of the table:
<snip>
\hline
\BLOCK{for col1, col2, col3, col4, col5, col6 in shareCompSum}
\VAR{col1} & \VAR{col2} & \VAR{col3}\euro & \VAR{col4}\euro & \VAR{col5}\euro & \VAR{col6}\euro \\
\BLOCK{endfor}
\hline
<snip>
The corresponding LaTeX-output is as follows:
\hline
Profit/Loss & & -174.040\euro & -9.040\euro & -723.20\euro & -733.28\euro \\
\hline
For columns 3 to 6, I would like the text color to be changed to red if the value of variable col3 is negative, and normal black if positive.
I am trying to write a statement along the following lines:
{% if col3 < 0 %} \textcolor{red}{\VAR{col3}\euro}
{% else %} \VAR{col3}\euro {% endif %}
It seems that Jinja does evaluate the if condition, but as a string-test rather than on numbers.
How can I perform the evaluation of float/numbers in Jinja?
The variable col3 appears as a string. You can set it to float via the following syntax:
{% if col3|float < 0.0 %} \textcolor{red}{\VAR{col3}\euro}
{% else %} \VAR{col3}\euro {% endif %}
The above Jinja code will typeset the variable col3 in red if negative, and black when larger than or equal to zero

Can the antlr4 parser see matching opening and closing text pattern?

I'm matching user-defined HTML-template tags that look like this (simplified):
{% label %} ... {% endlabel %}
The "label" is an alphanumeric value that a user can define himself, e.g.:
{% mytag %}<div>...</div>{% endmytag %}
Is there a way to tell the parser that the LABEL start tag text has to match with the ENDLABEL end tag text? In other words, I want this to be invalid:
{% mytag %}<div>...</div>{% endnotmatchingtag %}
My lexer looks like this:
LABEL : ALPHA (ALPHA|DIGIT|UNDERSCORE)* ;
fragment UNDERSCORE: '_' ;
fragment ALPHA: [a-zA-Z] ;
fragment DIGIT: [0-9] ;
END : 'end'
ENDLABEL : END LABEL
TAGSTART : '{%'
TAGEND : '%}'
WS : [ \t\r\n]+ -> skip ;
And the parser rule looks similar to this:
customtag: TAGSTART LABEL TAGEND block TAGSTART ENDLABEL TAGEND;
(and a block matches text or other tags recursively)
Right now I'm checking for a match in the listener, but I was hoping I could do it in the parser. Is there any way to ensure that ENDLABEL is equal to 'end' + LABEL at the parser level in Antlr4?
... and is it possible to do it if I weren't prepending 'end' in the lexer?
Create two additional lexer rules
EndTag : TAGSTART ENDLABEL TAGEND;
StartTag : TAGSTART LABEL TAGEND;
Make sure that the token ENDLABEL is not subsumed by LABEL (yet LABEL matches the same text, but is preferred because it is first in the grammar!)
Use the new tokens in your grammar, similar as you did:
taggedElement : StartTag othernodes EndTag;
and insert a semantic predicate
taggedElement : StartTag othernodes EndTag {matches($StartTag.text,$EndTag.text)};
where matches is true if the tags are matching.
A parser deals with syntax at the grammar level. What you are requesting can not be expressed in a Context Free Grammar (CFG), which suggests to me that you are not capable of solving this at the parser level.
In your schenario, I would create a visitor which enforces your semantics.
ANTLR 4 can generate abstract and base visitors for you, which you can then extend.

Use Regexp to replace optional match between charaters

I'm trying to replace the html entity for a blank space with an actual space between occurrences of {{ and }}
Example example
"this is a gap {{ for user in users }}" =>
"this is a gap {{ for user in users }}"
I've found answers similar which had led me to write something like this (which doesn't work)
.gsub(/(?<=\{\{).*( ?).*(?=\}\})/,' ')
Any help with such a regex would be appreciated thanks!
You can do this with a complex regular expression I agree, but I find it simpler to use nested substitution. First use gsub to find the bracketed substrings and then use another to replace the entity.
string = 'this is a gap {{ for user in users }}'
result = string.gsub(/{{.*?}}/){ |s| s.gsub(/ /, ' ') }
# => "this is a gap {{ for user in users }}"
Single call to gsub using \K and \G
It's a bit tricky, but in Ruby 2.0+, we can do it with a compact regex thanks to the \K and \G tokens. Use this regex and replace with a space:
[^{}]*\K(?:{{|\G).*?\K (?=[^{]*})
See demo.
In Ruby:
result = subject.gsub(/[^{}]*\K(?:{{|\G).*?\K (?=[^{]*})/, ' ')
Explanation
[^{}]* matches any chars that are not braces
\K tells the engine to drop what was just matched
(?:{{|\G) either matches the opening curlies or asserts that we are positioned after the last match
.*?\K lazily matches chars (and drops them), up to...
Our match!
which, as the lookakead (?=[^{]*}) asserts, must be followed by any chars that are not an opening brace before meeting a closing brace

Increment value in locomotivecms liquid markup

I wouldn't have come here if I hadn't tried many different approaches...
Obviously collections of objects do have a field size/length, but the components don't have an index. I want something like this:
{% for product in contents.products %}
<h3>Produkt {{ product.index + 1 }}</h3>
<p>{{ product.price | concat: ' €' }}</p>
{% endfor %}
I have tried the following as documented here:
http://www.omniref.com/ruby/gems/locomotivecms-liquid/classes/Liquid::Increment
{% increment variable %}
Doesn't work. I have to work in the backend editor which complains about bad syntax. Unknown tag increment. Could I be working with an old version? Unfortunately I can't check it.
I also tried assigning a value to 0 before the for loop:
{% assign x = 0 %}
And then manually increment it by 1:
{% assign x = x + 1 %}
There must be way! I mean this is basic programming. Has anybody found a way around this?
Thanks!
You can do increment in Locomotive CMS this way:
{% assign counter = 0 %}
{% capture counter %}{{ counter | plus: 1 }}{% endcapture %}

Resources