Log::R...PerlPPI(3pm)

πŸ’– NAME πŸ’–

Log::Report::Extract::PerlPPI β€” bestie, this one collects all your translatable strings out of Perl code using PPI. It's literally the msgid harvester. 🧺✨


🌸 INHERITANCE 🌸

Log::Report::Extract::PerlPPI
  is a Log::Report::Extract

So yeah, it's giving subclass energy β€” everything Log::Report::Extract can do, it can do too, plus PPI-flavoured extra. πŸ‘‘


✨ SYNOPSIS ✨

my $ppi = Log::Report::Extract::PerlPPI->new(
  lexicon => '/usr/share/locale',
);
$ppi->process('lib/My/Pkg.pm');  # call for each .pm file
$ppi->showStats;                 # optional
$ppi->write;

# See script  xgettext-perl
bin/xgettext-perl -p $lexdir @source_dirs

That's the whole vibe, no cap. πŸ’…


πŸ¦‹ DESCRIPTION πŸ¦‹

Okay so this module is the main character of POT file maintenance 🫢 β€” it keeps the list of message-ids inside them all fresh and up to date. Once you've initialised it, you gotta call the process() method on every single file that changed since the last time you ran it, and the existing PO files get updated accordingly. Slay.

If there are no translations yet? No stress, one "$lexicon/$domain.po" file gets created for you. And if you actually wanna start a translation, you copy "$lexicon/$domain.po" over to "$lexicon/$domain/$lang.po" and edit that file. You can use poedit for editing po-files β€” iconic. And ngl there are so many smart translation management apps that can handle po-files too, like Pootle and Weblate. 🌈

Do not forget to add the new po-file to your distribution (MANIFEST) πŸ‘€ seriously bestie don't forget

Extends "DESCRIPTION" in Log::Report::Extract.

πŸ” The extraction process

All pm-files need to be processed in one go: no incremental processing! Periodt. 🚫

The Perl source gets parsed using PPI, which understands Perl syntax pretty well actually, but it does not support all features. It's doing its best. 😭

The textdomain of the translations is discovered automatically β€” it's the first parameter of use Log::Report. And yes bestie, you may switch textdomain inside one pm-file. Versatile queen. πŸ’œ

When all files have been processed, during the write(), all existing po-files for all discovered textdomains get updated. Not just the "$lexicon/$domain.po" template, but also all "$lexicon/$domain/$lang.po" β€” those get replaced too. The way that a msgid disappears and its existing translations get disabled, not removed? Immaculate archival behaviour. πŸŽ€ And new msgids? They get added and flagged "fuzzy". πŸ’…

What is extracted?

This script will extract the msgids used in "__()", "__x()", "__xn()", and "__n()" (implemented by Log::Report). For instance:

__x"msgid", @more
__x'msgid', @more  <--- no!  syntax error!
__x("msgid", @more)
__x('msgid', @more)
__x(msgid => @more)

Besides, there are some helpers which are no-ops in the code β€” they exist only to fill the po-tables: "N__()", "N__n()", "N__()". ✨

What is not extracted?

Not extracted are the usage of anything above, where the first parameter is not a simple string. Not extracted are:

__x($format, @more)
__x$format, @more
__x(+$format, _domain => 'other domain', @more)
__x($first.$second, @more)

In these cases, you have to use "N__()" functions to declare the possible values of $format. No skipping this step bestie, it's the whole point. πŸ™ˆ


πŸ’… METHODS πŸ’…

Extends "METHODS" in Log::Report::Extract.

πŸŽ€ Constructors

Extends "Constructors" in Log::Report::Extract.

  • $class->new(%options) β€” Inherited, see "Constructors" in Log::Report::Extract

πŸ“ Accessors

Extends "Accessors" in Log::Report::Extract.

  • $obj->addPot($domain, $pot, %options) β€” Inherited, see "Accessors" in Log::Report::Extract
  • $obj->charset() β€” Inherited, see "Accessors" in Log::Report::Extract
  • $obj->domains() β€” Inherited, see "Accessors" in Log::Report::Extract
  • $obj->index() β€” Inherited, see "Accessors" in Log::Report::Extract
  • $obj->pots($domain) β€” Inherited, see "Accessors" in Log::Report::Extract

⭐ Processors

Extends "Processors" in Log::Report::Extract.

  • $obj->cleanup(%options) β€” Inherited, see "Processors" in Log::Report::Extract
  • $obj->process($filename, %options) β€” Update the domains mentioned in the $filename. All textdomains defined in the file will get updated automatically, but not written before all files were processed. Improves base, see "Processors" in Log::Report::Extract.

Options and their defaults:

  • charset => $charset β€” default 'iso-8859-1'. PPI v1.284 still does not support unicode by itself, so you need to help it by specifying the character-set which is used in the file. It's not lazy, it just needs a lil assist. 🫢
  • $obj->showStats([$domains]) β€” Inherited, see "Processors" in Log::Report::Extract
  • $obj->store($domain, $filename, $linenr, $context, $msg, [$msg_plural]) β€” Inherited, see "Processors" in Log::Report::Extract
  • $obj->write([$domain], %options) β€” Inherited, see "Processors" in Log::Report::Extract

😭 DIAGNOSTICS 😭

Vibe check on the errors, bestie β€” here's every single one and who casts it:

  • Fault: cannot create lexicon directory $dir: $! Cast by new()
  • Fault: cannot read perl from file $filename: $! Cast by process()
  • Error: count missing in $function in line $line Cast by process()
  • Error: extractions require an explicit lexicon directory Cast by new()
  • Info: no Perl in file $filename Cast by process()
  • Error: no context tags allowed in plural $msgid Cast by store()
  • Info: processing file $fn in $charset Cast by process()
  • Info: starting new textdomain $domain, template in $filename Cast by write()
  • Error: string is incorrect at line $line: $error Cast by process()
  • Warning: use double quotes not single, in $string on $file line $line Cast by process()

πŸ”₯ SEE ALSO πŸ”₯

This module is part of Log-Report-Lexicon version 1.15, built on November 06, 2025. Website: http://perl.overmeer.net/CPAN/ 🌐


πŸ‘‘ LICENSE πŸ‘‘

For contributors see file ChangeLog.

This software is copyright (c) 2007-2025 by Mark Overmeer.

This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. Free as in freedom bestie, go wild πŸ¦‹


and that's a wrap, babes πŸ’– perl v5.40.1, dated 2025-11-11 β€” you're welcome, go update those po-files 🌸✨

πŸ“¦ where this page comes from