-
Notifications
You must be signed in to change notification settings - Fork 32
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
Force a specific mode using {# fmt:mode #}
#116
Conversation
Without the `-t` / `--tabwidth` argument, DjHTML no longer defaults to | ||
a tabwidth of 4 but instead guesses the correct tabwidth. | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This was removed because it's hardly "new" anymore. I replaced it with a representative example of DjHTML's output at the top of this file.
|
||
```jinja | ||
{% block extra_css %} | ||
{# fmt:css #} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't understand, when would the fmt:css
end in this example? Doesn't this need some sort of endfmt:css
? Or perhaps fmt:auto
to go back to whatever fmt:on
does?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
when would the fmt:css end in this example?
Until one of the following strings is encountered:
{# fmt:html #}
{# fmt:js #}
</style>
You should know that the tokenizer of DjHTML is pretty dumb. It processes the input file line by line, token by token, and switches to different modes when it encounters certain tokens. For example, when the token <script>
is encountered in DjHTML
mode, it switches to DjJS
mode. Each mode is an instance of its class, and the previous mode instance is stored as self.return_mode
. Each mode normally only looks at the contents of the token it's currently processing, although there are some look-ahead assertions in a few places. It never looks back.
Therefore, a reasonable implementation of a potential {# fmt:auto #}
would be to return to the mode it came from, which is technically not "auto-detecting" the appropriate mode at all, but simply deterministically unstacking the order of modes. {# fmt:previous #}
would be more correct.
However, if you want to switch to a different mode you could also just specify the mode explicitly, which is better than implicitly. Here's how I would imagine the the original bug reporter using these new tags:
{% block style %}
{# fmt:css %}
{{ block.super }}
.somemorecss {
somemoreproperty: somemorevalue;
}
{% endblock %}
{% block content %}
{# fmt:html #}
<main>
<article>...</article>
</main>
{% endblock %}
That the indenter remains in DjCSS
mode until it encounters a different {# fmt #}
tag is kinda weird, though. For example, if you switch the above two blocks around, indentation will fail as it will remain in DjCSS
mode indefinitely. It may also lead to other problems that I have not foreseen.
I'm open to other suggestions on how to implement mode switches, and even to other suggestions on how to solve OP's problem 🙏
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How about reverting to the previous formatter on endblock
if a format was explicitly requested for a block? So you can think of the fmt:css
as an "attribute" of the django block.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For this specific use case, that would work. However, there are plenty more use cases for overriding modes, for example:
<a onclick="
{# fmt:js #}
var links = document.querySelectorAll('a');
for (var i = 0; i < links.length; i++) {
links[i].click();
}
">
{# fmt:html #}
Click me!
</a>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Then you really need something that ends it explicitly I think. endfmt:html
perhaps? As a bonus, you could then perhaps try checking that each explicit fmt:xxx
call has a matching endfmt:xxx
call, although that would likely make keeping track of the callstack complex 🤔
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The above example does illustrate the need for a {# fmt:auto #}
, though, because when inside a HTML element using {# fmt:html #}
will have unpredictable results at best. I'll see what I can do.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I cannot solve this:
<div>
<blockquote cite="#103"
x-data="
{# fmt:js #}
function() {
foo();
}
{# fmt:auto #}
"
class="foo"
/>
<blockquote
cite="#110"
style="{# fmt:css #}
font-family: Arial,
Helvetica;
{# fmt:auto #}"
/>
</div>
This makes me arrive at the same conclusion that I arrived at earlier in #103:
The
{# fmt:<mode> #}
option seems like a good idea though, so I experimented a bit with it. The problem is that it's hard to "exit" this mode again without running into inconsistencies.
So, I have decided to decline this PR.
Impossible. |
Closes #110