NAME

Mojo::PrettyTidy::Manual - User guide for Mojo::PrettyTidy and mojo-prettytidy

OVERVIEW

Mojo::PrettyTidy is a conservative formatter for Mojolicious Embedded Perl templates, especially .html.ep files.

The project favors safe, predictable cleanup over aggressive rewriting. It is intended to make real-world Mojolicious templates easier to inspect and maintain without changing template behavior.

The command-line tool, mojo-prettytidy, provides editor-friendly access to the formatter in a style similar to perltidy.

SCOPE

Mojo::PrettyTidy formats Mojolicious Embedded Perl template source, especially .html.ep files that are intended to be rendered by a Mojolicious application.

It is not a general-purpose HTML formatter, browser-source formatter, or post-rendered HTML cleanup tool. It is not intended for HTML downloaded from a browser's "View Source", saved web pages, scraper output, or other already-rendered documents.

You can try that if you really want to and good luck with that, but it is outside the supported use case. So, I don't want to hear about your miserable experience for having done so. That monkey is simply not a member of this circus.

QUICK START

Format a single file and print the result to standard output:

mojo-prettytidy file.html.ep

Check whether a file would change:

mojo-prettytidy --check file.html.ep

Show a diff:

mojo-prettytidy --diff file.html.ep

Rewrite a file in place:

mojo-prettytidy --write file.html.ep

Rewrite a file in place and keep a backup:

mojo-prettytidy --write --backup file.html.ep

Read from standard input:

mojo-prettytidy --stdin < file.html.ep

Write to a specific output file:

mojo-prettytidy --output parsed.file.html.ep file.html.ep

Process multiple files with a generated filename prefix:

mojo-prettytidy file1.html.ep file2.html.ep --prefix pt.

Process a directory non-recursively:

mojo-prettytidy templates --prefix pt. --outdir parsed

MODULE SYNOPSIS

use Mojo::PrettyTidy;

my $pt = Mojo::PrettyTidy->new(
  indent_width => 2,
  tab_width    => 2,
  columns      => 80,
  attributes   => 1,
  javascript   => 1,
);

my $output = $pt->tidy($input);

if ( !$pt->check($input) ) {
  print "changes would be made\n";
}

COMMAND SYNOPSIS

mojo-prettytidy [options] file.html.ep
mojo-prettytidy [options] file1.html.ep file2.html.ep
mojo-prettytidy [options] templates
mojo-prettytidy --stdin < file.html.ep

FORMATTING POLICY

Mojo::PrettyTidy is intentionally conservative.

It aims to:

  • preserve Mojolicious template semantics

  • normalize whitespace safely

  • improve readability of mixed HTML, Embedded Perl, JavaScript, and CSS

  • keep text payloads intact unless a specific structural rule applies

  • avoid wrapping arbitrary prose, Perl expressions, JavaScript, or quoted payloads

  • prefer structural expansion over generic hard wrapping

It is not intended to be a full HTML parser, JavaScript parser, or prose reformatter.

CURRENT BEHAVIOR

Current versions perform conservative cleanup including:

  • normalizing line endings to LF

  • removing trailing horizontal whitespace

  • ensuring exactly one trailing newline at end of file

  • applying conservative indentation to safe HTML structure

  • indenting plain text lines inside safe HTML structure

  • preserving Embedded Perl structure conservatively

  • indenting HTML lines containing Embedded Perl markers conservatively

  • indenting Embedded Perl control lines locally inside surrounding HTML blocks

  • handling single-line and multiline HTML comments conservatively

  • treating script and style blocks as protected regions

  • handling multiline opening tags conservatively

  • formatting selected HTML attributes conservatively

  • handling inline style="..." attributes conservatively when --columns is enabled

ATTRIBUTE FORMATTING

Attribute formatting is enabled by default.

The formatter groups supported tags by behavior rather than by strict HTML taxonomy:

  • container-like tags

    Tags whose opening attributes can be formatted while their body is handled by normal structure rules. Examples include form, select, div, main, picture, svg, and tr.

  • solo tags

    Tags with no body handling. Examples include input, img, source, and path.

  • paired tags

    Tags with an opening tag, body, and closing tag that can be expanded safely. Examples include button and a.

Attribute continuation lines are indented more deeply than nested child content so that attributes do not visually collide with child elements.

Quoted attribute values containing HTML-like fragments are protected from early tag-splitting rules. For example, tooltip content such as:

data-bs-title="<b>Regex:</b><code><%= $regex %></code>"

is treated as an attribute value, not as real template structure.

COLUMN-AWARE FORMATTING

--columns, also available as --cols or -c, sets a target width for conservative width-aware formatting. The default is 80. Use --no-columns or --no-cols to disable column-aware formatting.

Column-aware formatting is not a generic hard-wrap engine.

The first supported behavior is conservative formatting of long style="..." attributes. Style declarations are split only on CSS declaration boundaries, using semicolons as legal break points. The formatter packs declarations into lines near the configured column target while preserving declaration order.

The formatter intentionally does not wrap arbitrary quoted values such as:

  • SVG path d="..." data

  • href="..."

  • src="..."

  • srcset="..."

  • data-*="..." payloads

  • event handlers such as onclick="..."

  • Embedded Perl expressions

  • prose or text payloads

TEXT PAYLOADS

Text payloads are treated carefully because source whitespace can affect rendered output.

Paragraph-like text payload blocks should preserve their inline content, including inline tags such as a, b, i, and inline code, unless a specific structural rule applies.

The formatter avoids treating prose as a generic wrapping target. Editor or terminal line wrapping is preferred for long prose until an explicit safe rule is added.

EMBEDDED PERL FORMATTING

Mojo::PrettyTidy uses perltidy for Embedded Perl/code regions where possible. If $HOME/.perltidyrc exists, it is passed to perltidy, so your normal Perl indentation preferences are inherited.

PrettyTidy still overrides a small number of perltidy settings where needed for template formatting. In particular, it sets a very large line length (-l=9999) so perltidy does not make wrapping decisions. Width-aware template expansion is handled by PrettyTidy itself, for example through --cols.

PrettyTidy also runs perltidy through standard input/output in quiet mode and currently uses -nbbc to avoid introducing blank lines before comments.

JAVASCRIPT HANDLING

Mojo::PrettyTidy contains a conservative JavaScript handler for inline script blocks in Mojolicious .html.ep templates.

The goal is not for Mojo::PrettyTidy itself to become a JavaScript formatter. Instead, JavaScript is treated as a language island inside the template.

The handler attempts to:

  1. detect inline script ... /script blocks

  2. separate the script block cleanly from surrounding EP/HTML

  3. format the JavaScript body with JavaScript::Beautifier

  4. repair a small set of known modern-JavaScript token splits

  5. verify that known dangerous munges did not survive

  6. reinsert the script body into the template

External scripts such as:

<script src="/app.js"></script>

are not JavaScript-formatted because there is no inline body to format.

JavaScript::Beautifier

Mojo::PrettyTidy currently uses JavaScript::Beautifier. This keeps the implementation Perl-native and avoids requiring Node, npm, npx, node_modules, or editor-specific PATH setup.

The beautifier is called with the configured indentation width, so JavaScript indentation follows the formatter's indentation size.

Modern JavaScript caveat

JavaScript::Beautifier is older than many modern JavaScript syntax forms. Some modern tokens may be split incorrectly by the beautifier. For example, arrow functions may be transformed incorrectly:

() => {

into:

() = > {

The formatter currently detects and repairs a small set of known token splits, including:

  • =>

  • ?.

  • ??

  • ??=

  • ||=

  • &&=

If known JavaScript munging is detected after attempted repair, the original JavaScript body is left unchanged and a warning is emitted.

JavaScript warning comment

When the formatter accepts a changed JavaScript body, it injects a visible comment inside the script block warning that the block was reformatted and can be rerun with JavaScript formatting disabled.

If JavaScript formatting fails or is rejected as unsafe, the original body is kept and no reformatting warning comment is injected.

COMMAND-LINE OPTIONS

--attributes, --attrib, -a

Enable attribute formatting. This is enabled by default.

Use --no-attributes or --no-attrib to disable attribute formatting.

--backup

When used with --write, create a backup of the original file before rewriting it.

--backup-ext

When used with --write --backup, choose the backup suffix. The default is .bak.

--check

Exit with status 0 if the input file is already tidy, or 1 if changes would be made.

This option requires a single input file.

--columns, --cols, -c

Set the target column width for conservative width-aware formatting. The default is 80.

Use --no-columns or --no-cols to disable column-aware formatting.

--config

Load default options from the specified JSON config file.

If --config is not given, mojo-prettytidy will look for a default

configuration file and load the first one found:

  • $HOME/.mojo-prettytidy.json

  • ./.mojo-prettytidy.json

Command-line options override config values.

The installer should create $HOME/.mojo-prettytidy.json from the

shipped default config when no user config already exists.

--diff

Print a minimal unified-style diff showing what would change. Exit with status 0 if no changes would occur or 1 if differences are found.

This option requires a single input file.

--help, -h

Show brief help.

--javascript, --js, -j

Enable JavaScript formatting. This is enabled by default.

Use --no-javascript or --no-js to disable JavaScript formatting.

--man

Show full documentation.

--output, -o

Write the tidied result to the specified output file instead of standard output.

This option cannot be combined with --write, --check, or --diff. It is intended for single-input use. =head2 --outdir

When writing multiple outputs, place generated files in the specified directory.

--perl / --no-perl

Enable or disable perltidy formatting for Embedded Perl/code regions. Enabled by default. When disabled, PrettyTidy still applies its template, HTML, attribute, JavaScript, and column-handling passes as configured, but it does not run perltidy over Embedded Perl regions.

--prefix, --pre

When writing multiple outputs, prefix generated filenames with the specified string.

--show-options, -V, -VV

Show effective option values after config and command-line processing.

-V shows active or behavior-changing options. -VV shows all effective options, including defaults.

Intended for development use.

--stdin

Read template input from standard input and write formatted output to standard output. This is useful when piping data to mojo-prettytidy from an editor, shell command, or another program.

--version, -v

Print the program version and exit.

--write, -w

Rewrite input files in place.

CONFIG FILE

Config files use JSON object syntax. Supported keys may include:

  • attributes

  • columns

  • indent_width

  • javascript

  • outdir

  • perl

  • prefix

  • tab_width

Example:

{
  "attributes": 1,
  "columns": 80,
  "javascript": 1,
  "prefix": "pt.",
  "outdir": "share/samples/testing"
}

Command-line options override config values.

INPUT AND OUTPUT MODES

Positional inputs may be files or directories.

When a positional input is a directory, mojo-prettytidy scans it non-recursively and processes matching .html.ep files.

When multiple files are processed, use one of:

  • --write

    Rewrite each file in place.

  • --prefix

    Write sibling output files with prefixed names.

  • --outdir

    Write generated files to the specified output directory.

--output is intended for single-file output to a specific file.

--write cannot be combined with --output, --prefix, or --outdir.

--check and --diff require a single input file.

Multiple inputs require --write, --prefix, or --outdir.

EDITOR USAGE

The tool is designed to work cleanly as an editor-invoked command, similar in spirit to perltidy.

Typical patterns:

bin/mojo-prettytidy %filename

or:

bin/mojo-prettytidy --stdin

For non-destructive inspection of generated output, --output, --prefix, and --outdir are often more useful than --diff.

Editor integration

Mojo::PrettyTidy includes an optional Kate External Tool helper:

kate-tool --install

This writes a Kate External Tools configuration for running mojo-prettytidy against the current document, when the document is saved.

Other editor integrations are encouraged. If you use another editor, please consider contributing a small installer/helper for that editor. Good candidates include Vim, Neovim, VS Code, BBEdit, Sublime Text, and any editor that can run an external formatter command.

The formatter itself is editor-agnostic; editor helpers are convenience wrappers around the mojo-prettytidy command.

EXIT STATUS

  • 0

    Success, or no changes needed in --check or --diff mode.

  • 1

    Changes would be made in --check mode, or differences were found in --diff mode.

  • 2

    Command-line usage error.

DESIGN NOTES

Mojo::PrettyTidy favors local readability over aggressive transformation.

It is intentionally conservative around:

  • Embedded Perl control flow

  • mixed HTML and Embedded Perl lines

  • script and style blocks

  • multiline inline attributes

  • multiline opening tags

  • quoted attribute values

  • text payloads

DEVELOPMENT STATUS

The project is in active development but is already useful for real-world inspection and iterative cleanup.

The current implementation is developed on Perl 5.40. It may work with lower Perl versions, but that is not currently guaranteed or tested.

INSTALLATION

Development install from the repository:

perl Makefile.PL
make
make test
make install

PROJECT HOME

https://github.com/Harryb382003/PrettyTidy

AUTHOR

Harry Bennett

LICENSE

Same terms as Perl itself.