|
| 1 | +=begin pod |
| 2 | + |
| 3 | +=head1 NAME |
| 4 | + |
| 5 | +POFile - manipulating data in gettext PO files |
| 6 | + |
| 7 | +=head1 SYNOPSIS |
| 8 | + |
| 9 | +=begin code :lang<raku> |
| 10 | + |
| 11 | +use POFile; |
| 12 | +my $po = POFile.load('foo.po'); |
| 13 | + |
| 14 | +say $po.obsolete-messages; # list of obsolete messages |
| 15 | +say $po[0]; # POFile::Entry object at 0 index |
| 16 | +say $po{'Splash text'}; # POFile::Entry object with msgid C<Splash textC< |
| 17 | +for @$po -> $item { |
| 18 | + say $item.reference; # 'finddialog.cpp:38' |
| 19 | + say $item.msgstr; # msgstr value |
| 20 | + $item.msgstr = update($item.msgstr); # Do some update |
| 21 | +} |
| 22 | +$po.save('foo-updated.po'); |
| 23 | + |
| 24 | +=end code |
| 25 | + |
| 26 | +=head1 DESCRIPTION |
| 27 | + |
| 28 | +The C<.po> file as a whole is represented by the C<POFile> class, |
| 29 | +which holds a C<POFile::Entry> object per entry in the PO file. |
| 30 | + |
| 31 | +=head2 POFile::Entry |
| 32 | + |
| 33 | +The C<POFile::Entry> class represents a single record in PO file, |
| 34 | +and has its fields as attributes: C<msgid>, C<msgid-plural>, |
| 35 | +C<msgstr>, C<msgctxt>, C<reference> (reference comment), |
| 36 | +C<extracted> (extracted comment), C<comment> (translator comment), |
| 37 | +C<format-style>, C<fuzzy-msgid>, C<fuzzy-msgctxt>. All these |
| 38 | +attributes are set read/write. |
| 39 | + |
| 40 | +You can create a single C<POFile::Entry> object from a C<Str> |
| 41 | +using the C<POFile::Entry.parse($str)> method. |
| 42 | + |
| 43 | +The C<msgid> and C<msgstr> accessors always provided unquoted |
| 44 | +values; the methods C<msgid-quoted> and C<msgstr-quoted> are present |
| 45 | +to provide access to the quoted messages. |
| 46 | + |
| 47 | +The value of C<msgstr> attribute might be either C<Str> or C<Array>, |
| 48 | +and is based on value of C<msgid-plural> attribute: |
| 49 | + |
| 50 | +=begin code :lang<raku> |
| 51 | + |
| 52 | +with $po.msgid-plural { |
| 53 | + say $po.msgid; # Singular form |
| 54 | + say $_; # Plural form |
| 55 | + for $po.msgstr -> $form { |
| 56 | + say $form; # Every plural form of end language |
| 57 | + } |
| 58 | +} |
| 59 | + |
| 60 | +=end code |
| 61 | + |
| 62 | +You can serialize an entry with C<Str> method or its C<~> shortcut: |
| 63 | + |
| 64 | +=begin code :lang<raku> |
| 65 | + |
| 66 | +my $po-entry = $po[1]; # Get second entry |
| 67 | +say ~$po-entry; # Serialized 1 |
| 68 | +say $po-entry.Str; # Serialized 2 |
| 69 | + |
| 70 | +=end code |
| 71 | + |
| 72 | +Note that B<no line wrapping> is done by the module. |
| 73 | + |
| 74 | +=head2 POFile |
| 75 | + |
| 76 | +C<POFile> provides access to C<POFile::Entry> objects using either |
| 77 | +index (position in original file) or key (msgid value). |
| 78 | + |
| 79 | +It must be noted that this module provides hash-like access by msgid, |
| 80 | +which might B<not> be unique. Please consider that I<only array access> |
| 81 | +is stable in this case. Use hash access you know I<for sure> there |
| 82 | +are no items with the same C<msgid>, yet different C<msgctxt>. |
| 83 | + |
| 84 | +The C<POFile> object also contains all obsolete messages, which cani |
| 85 | +be accessed using C<obsolete-messages> attribute. |
| 86 | + |
| 87 | +You can create from scratch a new C<POFile> object and populate it with |
| 88 | +entries, as well as delete entries by id or by key: |
| 89 | + |
| 90 | +=begin code :lang<raku> |
| 91 | + |
| 92 | +my $po = POFile.new; |
| 93 | +@$po.push(POFile::Entry.parse(...)); |
| 94 | +@$po.push(POFile::Entry.parse(...)); |
| 95 | +$po[0]:delete; |
| 96 | +$po{'my msgid'}:delete; |
| 97 | + |
| 98 | +=end code |
| 99 | + |
| 100 | +As well as C<POFile::Entry>, you can serialize a C<POFile> object |
| 101 | +calling C<Str> method on it. |
| 102 | + |
| 103 | +=head2 Escaping |
| 104 | + |
| 105 | +Additionally, two routines are available to escape and unescape |
| 106 | +strings accordingly to rules described for PO format. |
| 107 | + |
| 108 | +=begin code :lang<raku> |
| 109 | + |
| 110 | +use POFile :quoting; |
| 111 | + |
| 112 | +say po-unquote(「\t\"\\\n」); # 「\t"\\n」 <- unquoting |
| 113 | +say po-quote(「\t"\\n\」); # 「\t\"\\\n\\」 <- quoting |
| 114 | + |
| 115 | +=end code |
| 116 | + |
| 117 | +=head1 AUTHORS |
| 118 | + |
| 119 | +=item Alexander Kiryuhin |
| 120 | +=item Jonathan Worthington |
| 121 | + |
| 122 | +Source can be located at: https://github.com/raku-community-modules/POFile . |
| 123 | +Comments and Pull Requests are welcome. |
| 124 | + |
| 125 | +=head1 COPYRIGHT AND LICENSE |
| 126 | + |
| 127 | +Copyright 2018 - 2020 Edument AB |
| 128 | + |
| 129 | +Copyright 2024, 2025 The Raku Community |
| 130 | + |
| 131 | +This library is free software; you can redistribute it and/or modify it under the Artistic License 2.0. |
| 132 | + |
| 133 | +=end pod |
| 134 | + |
| 135 | +# vim: expandtab shiftwidth=4 |
0 commit comments