arashm/PoParser

View on GitHub
README.md

Summary

Maintainability
Test Coverage
# PoParser

![Build Status](https://github.com/arashm/poparser/workflows/Ruby/badge.svg?branch=master)
[![Coverage Status](https://coveralls.io/repos/github/arashm/PoParser/badge.svg)](https://coveralls.io/github/arashm/PoParser)
[![Code Climate](https://codeclimate.com/github/arashm/PoParser.png)](https://codeclimate.com/github/arashm/PoParser)
[![Gem Version](https://badge.fury.io/rb/PoParser.svg)](http://badge.fury.io/rb/PoParser)

A Ruby PO file parser, editor and generator. PO files are translation files generated by GNU/Gettext tool. This GEM is compatible with [GNU PO file specification](https://www.gnu.org/software/gettext/manual/html_node/PO-Files.html). report misbehaviours and bugs to the [issue tracker](https://github.com/arashm/PoParser/issues).

## Installation

Add this line to your application's Gemfile:

    gem 'PoParser'

And then execute:

    $ bundle install

Or globally install it:

    $ gem install PoParser

## Usage

Working with the GEM is pretty easy:

```ruby
require 'poparser'

content = File.read('example.po')
po = PoParser.parse(content)
# => <PoParser::Po, Translated: 68.1% Untranslated: 20.4% Fuzzy: 11.5%>

# Or you could pass a file path:

path = Pathname.new('example.po')
po = PoParser.parse_file(path)
# => <PoParser::Po, Translated: 68.1% Untranslated: 20.4% Fuzzy: 11.5%>
```

The `parse` method returns a `PO` object which contains all `Entries`:

```ruby
# get all entries
po.entries # or .all alias

# including cached/obsolete entries (started with "#~")
# more info: https://www.gnu.org/software/gettext/manual/html_node/Obsolete-Entries.html
po.entries(true)

# get all fuzzy entries
po.fuzzy

# get all untranslated entries
po.untranslated

# get all translated entries
po.translated

# get all cached/obsolete entries
po.cached # or .obsolete alias

# returns a hash representation of the PO file
po.to_h

# returns a string representation of the PO file
po.to_s
```

You can add a new entry to the PO file:

```ruby
new_entry = {
              translator_comment: 'comment',
              reference: 'reference comment',
              msgid: 'untranslated',
              msgstr: 'translated string'
            }

po.add(new_entry)

# There's also an alias for add `<<`
po << new_entry
```

You can pass an array of hashes to `new_entry` and it will be added to `PO` file.

Similarly you can add plural strings:

```ruby
new_entry = {
              translator_comment: 'comment',
              reference: 'reference comment',
              msgid_plural: 'untranslated',
              'msgstr[0]': 'translated string',
              'msgstr[1]': 'translated string'
            }

```

_Note_: currently `PoParser` won't warn you if you add a `msgstr[0]` without `msgid_plural`, any `msgid` at all or even if the index numbers in `msgstr[0]` are not in any logical order.

### Entry

Each entry can have following properties (for more information see [GNU PO file specification](https://www.gnu.org/software/gettext/manual/html_node/PO-Files.html)):

```
translator_comment
reference
extracted_comment
flag
previous_msgctxt
previous_msgid
previous_msgid_plural
cached # obsolete entries
msgid
msgid_plural
msgstr
msgctxt
```

#### Working with entries

The `PO` object contains many `Entry` objects. Number of methods are available to check state of an `Entry`:

```ruby
entry = po.entries[1]

entry.untranslated? # or .incomplete? alias
#=> false
entry.translated? # or .complete? alias
#=> true
entry.fuzzy?
#=> true
entry.plural?
#=> false
entry.cached? # or .obsolete?
#=> false
```

You can get or edit each property of the `Entry`:

```ruby
entry.msgid.to_s
#=> "This is an msgid that needs to get translated"
entry.translate("This entry is translated") # or `msgstr=` alias
entry.msgstr.to_s
#=> "This entry is translated"
```

Note that msgstr for plural entries are returned as Array:

```ruby
if entry.plural?
  entry.msgstr.each do |msgstr|
    msgstr.to_s
    #=> This is one of the plural translations
  end
end
```

You can mark an entry as fuzzy:

```ruby
entry.flag_as_fuzzy
entry.fuzzy?
#=> true
```

It's possible to get Hash and String representation of the `Entry`:

```ruby
entry.to_h
entry.to_s
```

To remove an entry from the PO, use `PO#delete`

```ruby
po.delete(entry)
```

### Searching

`PO` is an `Enumerable`. All exciting methods from `Enumerable` are available in `PO`. The `PO` yields `Entry`.

```ruby
po.find_all do |entry|
  entry.msgid.str.match(/some text/i)
end
```

There is a helper method that does the same:

```ruby
po.search_in(:msgstr, 'some string to search')
```

This method returns an array of matched entries.

### Saving

You can simply save the PO file using the `PO` object:

```ruby
po.save_file
```

If you want to save as the file in diffrent location change the `path`:

```ruby
po.path
#=> example.po
po.path = 'example2.po'
po.save_file
```

## Header

The first entry of every PO file is reserved for header which represent license and general information about translators and the po file itself. For more information visit the [GNU website](https://www.gnu.org/software/gettext/manual/html_node/Header-Entry.html#Header-Entry).

Get header with `header`!:

```ruby
po.header
```

You can get and set following variables from `header`:

```
  pot_creation_date
  po_revision_date
  project_id
  report_to
  report_msgid_bugs_to
  last_translator
  team
  language
  charset
  encoding
  plural_forms
```

## To-Do

* Streaming support
* Update header after changing/saving po
* add `before_save` and `after_save` callbacks

## Authors

[Arash Mousavi](https://github.com/arashm)

### [Contributors](https://github.com/arashm/PoParser/contributors)
 - [Dennis-Florian Herr](https://github.com/dfherr)
 - [Roland Gropmair](https://github.com/roland9)

License: [MIT](https://github.com/arashm/PoParser/blob/master/LICENSE.txt)

## Contributing

1. Fork it ( http://github.com/arashm/poparser/fork )
2. Create your feature branch (`git checkout -b my-new-feature`)
3. Commit your changes (`git commit -am 'Add some feature'`)
4. Push to the branch (`git push origin my-new-feature`)
5. Create new Pull Request