Perl Formatter

Perl hides curly braces inside s{}{}, qw{}, hash slices and heredoc bodies, so a brace counter mis-indents the second half of most scripts. This page lexes first. Regex bodies, POD, heredocs and __DATA__ pass through untouched. Indent is rebuilt from the braces perl itself would see.

Indent
Else
Load
Pasted PerlEditable
ReindentedRead only

Paste Perl on the left.

Most online perl formatter pages count { and } with a regular expression. Perl is the worst possible language for a counter. A substitution written as s{^\s+}{} holds four braces and opens no block. A word list written as qw{ host path bytes } holds two more. A heredoc body often holds a JSON template full of them. One log parser is enough to push the counter two levels off, and every line after the mistake lands in the wrong column.

The engine on this page reads the paste the way perl reads a source file. Quote-like operators (q, qq, qw, qr, m, s, tr, y) are consumed with their own delimiters, including paired and nested ones. Heredoc bodies are read to their terminator. POD is skipped from a column-zero =head1 down to =cut. Only the braces left over decide indent.

How seven typical lines are read before indent is rebuilt
Pasted lineWhat the lexer decided
$path =~ s{\?.*$}{};One substitution token. Zero braces counted.
my @cols = qw{ host path bytes };One word list. Zero braces counted.
push @{ $hits{$path} }, $host;A dereference plus a hash subscript. Two open, two close, same line, net zero.
print <<"EOM";Heredoc opener. The body down to EOM is copied byte for byte.
=head1 NAME at column zeroPOD begins. Nothing is touched until the line after =cut.
__END__ on its own lineEverything below is copied as pasted, POD or plain text.
} elsif ($mode eq "lookup") {Block close, then a new block. Split onto two lines unless the Cuddle switch is on.

Four spaces and an uncuddled else come from perlstyle

The defaults are not a preference of this site. perldoc perlstyle, the style document shipped with every Perl install since 5.x, asks for a four column indent, the opening curly on the same line as the keyword, space around most operators, no space before a semicolon, and an uncuddled else. perltidy with no .perltidyrc produces the same shape. Paste a script indented with two spaces or with tabs and the output comes back at four unless you switch the strip.

The Cuddle switch is the equivalent of perltidy -ce. Off, }else{ becomes a } on one line and else { on the next. On, a lone } followed by an else or elsif line is pulled back onto one line. Neither rewrite changes what the script does. Pick whichever the rest of the file already uses. A single cuddled else in an uncuddled module is the kind of diff a reviewer bounces without reading the logic.

Two space Perl exists. Teams who arrived from Ruby or JavaScript write it, and a few large codebases from the mod_perl era settled on it. Tabs survive in cron scripts written by sysadmins in 2006 and never opened since. Both are legal. Match the file in front of you, not the document.

What passes through untouched

A heredoc body is a string. Reindenting <<"EOM" to line up with the surrounding sub changes the mail header the script sends, so the body stays exactly as pasted. The squiggly form <<~EOM strips common leading whitespace at runtime and would tolerate a reindent. This page still leaves the body alone. The rule is one rule for both forms, applied the same way every time.

format blocks are picture lines. The @<<<< and @>>>> fields are positioned by column, so a single added space shifts a report. Everything from format NAME = down to the lone . line is copied through. Comments keep their text. String and regex bodies keep their whitespace. __DATA__ and __END__ sections are appended to the output unchanged, which matters when a script reads its own config from <DATA>.

Inside a statement, the rewrites are narrow. Leading whitespace is rebuilt from brace depth. A line starting with ||, ., or, => or a ternary ? is treated as a continuation and indented one level past its statement. Spaces are put around binary operators and after commas. sub name{ gains a space before the brace. Runs of blank lines collapse to one. Trailing whitespace is dropped. Identifier names, quoting style, parenthesis choices and statement order are never changed.

The readout below the editors

After each run the cells under the panes report what the lexer found. Braces shows opened against closed once strings, regexes and POD are out of the way. When the two numbers differ, the warning line names the first unmatched line, and every indent below it is a guess. Fix the source on the left before you copy. Subs counts named sub declarations, a quick check the paste is a whole module and not a fragment.

use strict and use warnings report present or missing. The page reads use v5.12 or later as strict and use v5.36 or later as warnings too, since those pragmas are implied. Nothing is inserted. Adding use strict to a script from 2004 stops the run at the first undeclared global, and the person who pasted the script into a browser is rarely the person who wants to fix forty of them right now. The readout is there to tell you the state of the file, not to change it behind your back.

POD lines kept, heredocs kept and __DATA__ confirm the verbatim regions were recognised. A module with documentation and a zero in the POD cell means the =head1 was not at column zero, which is also why perldoc would ignore it.

perltidy is the tool for the repository

This page is for a paste. A script from a ticket, a subroutine from a chat window, a CGI file recovered from a backup. A repository with more than one Perl file wants perltidy installed and a .perltidyrc committed, so every file lands on the same rules from the same command and nobody opens a browser.

# .perltidyrc -i=4 # indent width -l=100 # line length -nce # uncuddled else, the perlstyle default -b # write in place, keep a .bak -bext='/' # delete the .bak when the run succeeds
perltidy -pro=.perltidyrc lib/Toolexe/Mailer.pm perltidy -b -i=4 bin/*.pl

Several perltidy jobs are outside this page on purpose. Long statements are not broken at a column limit, so a 190 character printf stays 190 characters. Nothing is vertically aligned, so a hash with => arrows at four different columns keeps them there. -pbp, the Perl Best Practices profile, changes parenthesis style and quoting and is not attempted. Pastes over 2 MB are refused rather than formatted, because two Ace editors holding a 2 MB file lock the tab before indent finishes. A whole lib/ tree belongs in perltidy on disk.

Where the lexer still guesses

Perl is famous for being hard to parse without running. A few constructions are read on a heuristic here, and each is worth knowing before you trust the brace count on a strange file.

The regex itself is a separate job. When the pattern in a =~ line is the thing you are unsure about, paste the pattern and a few sample rows into the regex tester and watch the captures. Porting a script to Python and want the target side indented too? The Python formatter applies PEP 8 spacing. The Ruby formatter and PHP formatter cover the two languages Perl teams most often migrate to. A clipboard whose language you have not named yet belongs on the universal code formatter. A JSON dump written by JSON::PP with no Perl around it belongs on the JSON beautifier.

Questions from the readout

Uploads, else placement, heredocs, and why perltidy on disk still prints something different.

Is the script uploaded anywhere?

No. The lexer and the printer are JavaScript inside this tab. A CGI script holding database credentials or a mailer with api.toolexe.com keys never leaves the machine. Closing the tab drops both panes.

Why did else move onto its own line?

perlstyle and the perltidy default both ask for an uncuddled else, so } and else { sit on separate lines. Turn on the Cuddle switch in the strip to keep } else { on one line, the same result as perltidy -ce. The choice is cosmetic. Match the rest of the file.

Will the heredoc body be reindented with the code around it?

No. The body between the opener and the terminator is a string, and changing its leading whitespace changes what the script prints or mails. The opener line is indented with its statement. The body, including a squiggly <<~ body, is copied exactly as pasted.

The readout says use strict is missing but the script runs fine. Is the page wrong?

The readout reports what the file declares. A script without use strict runs, it only skips the compile-time checks. use v5.12 or later is counted as strict and use v5.36 or later as warnings, because those versions imply the pragmas. Nothing is inserted either way.

Why does perltidy give a different result on the same file?

perltidy breaks long lines at a column limit, aligns => arrows and = signs vertically, and applies dozens of options from .perltidyrc. This page rebuilds indent and operator spacing only. Both agree on brace depth and on where else goes. For a committed file, run perltidy. For a paste, this is enough.

Does it handle .pm modules, .cgi files and .t tests?

Yes. The extension is irrelevant. package statements, POD between subs, a 1; at the end, Test::More calls and __DATA__ sections are all read. A .t file full of is() and ok() calls formats the same way as a script.

The braces cell shows 14 / 13. What now?

One block never closed. The warning line under the panes names the line where the still-open brace was opened. Everything indented below it is a guess. Add the missing } on the left, run Format again, and copy once the two numbers match.

How big a file will the page take?

Up to 2 MB. Past 2 MB the paste is refused rather than formatted, because two editors holding the file plus the token list freeze the tab. A whole lib/ tree belongs in perltidy on disk, not in a browser.