• Stars
    star
    576
  • Rank 77,502 (Top 2 %)
  • Language
    Python
  • License
    GNU General Publi...
  • Created over 3 years ago
  • Updated about 1 month ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Django/Jinja template indenter

DjHTML

A pure-Python Django/Jinja template indenter without dependencies.

DjHTML indents mixed HTML/CSS/JavaScript templates that contain Django or Jinja template tags. It works similar to other code-formatting tools such as Black and interoperates nicely with pre-commit.

DjHTML is an indenter and not a formatter: it will only add/remove whitespace at the beginning of lines. It will not insert newlines or other characters. The goal is to correctly indent already well-structured templates, not to fix broken ones.

New! Multi-line HTML elements

As of version 3, DjHTML indents multi-line HTML elements and multi-line attribute values like this:

<blockquote cite="Guido Van Rossum"
            style="font-style: italic;
                   {% if dark_mode %}
                       background: black;
                   {% endif %}
                  ">
    Don't you hate code that's not properly indented?
</blockquote>

New! Multi-line CSS indentation

Multi-line CSS values are now continued at the same indentation level:

<style>
    @font-face {
        font-family: Helvetica;
        src: {% for format, filename in licensed_fonts %}
                 url('{% static filename %}') format('{{ format }}'),
             {% endfor %}
             url('Arial.woff2') format('woff2'),
             url('Arial.woff') format('woff');
    }
</style>

New! Improved JavaScript indentation

Many new JavaScript indention rules have been added, such as the indentation of method chaining:

<script>
    window.fetch('/test.html')
        .then((html) => {
            document.body.innerHTML = html;
            {% block extra_statements %}
            {% endblock %}
        });
</script>

New! Tabwidth guessing

Without the -t / --tabwidth argument, DjHTML no longer defaults to a tabwidth of 4 but instead guesses the correct tabwidth.

Installation

DjHTML requires Python 3.8 or higher and is compatible with all operating systems supported by Python. Install DjHTML with the following command:

$ pip install djhtml

Note that Windows still uses legacy code pages instead of UTF-8. It is highly advised to set the environment variable PYTHONUTF8 to 1 with the setx command:

C:\> setx /m PYTHONUTF8 1

Usage

After installation you can indent templates using the djhtml command:

$ djhtml template.html
reindented template.html
1 template has been reindented.

You can also run djhtml . to indent all HTML files beneath the current directory.

An exit status of 0 means that everything went well, regardless of whether any files were changed. When the option -c / --check is used, the exit status is 1 when one or more files would have changed, but no changes are actually made. All available options are given by djthml -h / djthml --help.

fmt:off and fmt:on

You can exclude specific lines from being processed with the {# fmt:off #} and {# fmt:on #} operators:

{# fmt:off #}
   ,-._|\
  /     .\
  \_,--._/
{# fmt:on #}

Contents inside <pre> ... </pre>, <!-- ... --->, /* ... */, and {% comment %} ... {% endcomment %} tags are also ignored (depending on the current mode).

Modes

The indenter operates in one of three different modes:

  • DjHTML mode: the default mode. Invoked by using the djhtml command or the pre-commit hook.

  • DjCSS mode. Will be entered when a <style> tag is encountered in DjHTML mode. It can also be invoked directly with the command djcss.

  • DjJS mode. Will be entered when a <script> tag is encountered in DjHTML mode. It can also be invoked directly with the command djjs.

pre-commit configuration

A great way to use DjHTML is as a pre-commit hook, so all your HTML, CSS and JavaScript files will automatically be indented upon every commit.

First, install pre-commit:

$ pip install pre-commit
$ pre-commit install

Then, add the following to your .pre-commit-config.yaml:

repos:
  - repo: https://github.com/rtts/djhtml
    rev: 'main'  # replace with the latest tag on GitHub
    hooks:
      - id: djhtml
      - id: djcss
      - id: djjs

Now run pre-commit autoupdate to automatically replace main with the latest tag on GitHub, as recommended by pre-commit.

If you want to override a command-line option, for example to change the default tabwidth, you change the entry point of these hooks:

    hooks:
      - id: djhtml
        # Use a tabwidth of 2 for HTML files
        entry: djhtml --tabwidth 2
      - id: djcss
      - id: djjs

If you want to limit the files these hooks operate on, you can use pre-commit mechanisms for filtering. For example:

    hooks:
      - id: djhtml
        # Indent only HTML files in template directories
        files: .*/templates/.*\.html$
      - id: djcss
        # Run this hook only on SCSS files (CSS and SCSS is the default)
        types: [scss]
      - id: djjs
        # Exclude JavaScript files in vendor directories
        exclude: .*/vendor/.*

Now when you run git commit you will see something like the following output:

$ git commit

DjHTML...................................................................Failed
- hook id: djhtml
- files were modified by this hook

reindented template.html
1 template has been reindented.

To inspect the changes that were made, use git diff. If you are happy with the changes, you can commit them normally. If you are not happy, please do the following:

  1. Run SKIP=djhtml git commit to commit anyway, skipping the djhtml hook.

  2. Consider opening an issue with the relevant part of the input file that was incorrectly formatted, and an example of how it should have been formatted.

Your feedback for improving DjHTML is very welcome!

Development

First of all, clone this repository:

$ git clone https://github.com/rtts/djhtml
$ cd djhtml

Then, create a Python virtualenv and activate it:

$ python -m venv ~/.virtualenvs/djhtml
$ . ~/.virtualenvs/djhtml/bin/activate

Then, install the package in development mode including the dev dependencies, and install the pre-commit hooks:

$ python -m pip install -e '.[dev]'
$ pre-commit install --install-hooks

You can run the unittests with:

$ python -m unittest

Or use nox to test all supported Python interpreters:

$ nox

Finally, to get a little insight into the tokenization step of the indenting algorithm, you can run DjHTML with the -d / --debug argument. You will see a Python representation of the tokens that are created.

More Repositories

1

debian

A complete, minimalist Debian setup for power users
Shell
144
star
2

ialauncher

Play all of the Internet Archive’s MS-DOS games offline!
Python
77
star
3

win311

VM with Windows 3.11 and a working internet connection
Shell
54
star
4

certify

Create self-signed certificates with the "subjectAltName" extension
Shell
33
star
5

photog

The static photography website generator used by Super Formosa Photography
JavaScript
26
star
6

photog-perl

Photography Website Generator
JavaScript
24
star
7

django-pandocfield

An advanced Markdown field for Django that supports LaTeX formulas
Python
9
star
8

fftok

Convert long, horizontal videos to short, vertical videos
Shell
8
star
9

win95

VM with Windows 95 and a working internet connection
Shell
8
star
10

win98

VM with Windows 98 and a working internet connection
Shell
7
star
11

django-tidy

Tidy up your Django!
Python
6
star
12

autodidact

A content management system for self-learning activities
Java
4
star
13

django-simplecms

Simple Django CMS
Python
3
star
14

cchess

Console chess frontend for UCI-compliant chess engines
Haskell
3
star
15

bps

A web application by Tilburg University for teaching statistics
Java
2
star
16

wikical

Fill a calendar with Wikepedia information
Perl
2
star
17

technicmocs

A social news website about Lego Technic models
Python
1
star
18

paragraph

Outlining text editor for writing well-structured text
HTML
1
star
19

dyad

Peer-to-peer Android communication
Java
1
star
20

maestro

A simple content management system
Perl
1
star
21

lego

Lego Technic Creations published on jj.created.today
POV-Ray SDL
1
star
22

ij

Inter-Jection provides interjections, catchphrases, and general expressions of enthusiasm
Haskell
1
star
23

RegexRhyme

Dutch words that end with a given regular expression
Shell
1
star