# Twine [![Continuous Integration by CircleCI](https://circleci.com/gh/teespring/twine.svg?style=shield)](https://circleci.com/gh/teespring/twine) Twine is a command line tool for managing your strings and their translations. These are all stored in a master text file and then Twine uses this file to import and export localization files in a variety of types, including iOS and Mac OS X `.strings` files, Android `.xml` files, gettext `.po` files, and [jquery-localize][jquerylocalize] `.json` files. This allows individuals and companies to easily share translations across multiple projects, as well as export localization files in any format the user wants. ## Install Twine is most easily installed as a Gem. $ gem install twine ## Twine File Format Twine stores everything in a single file, the Twine data file. The format of this file is a slight variant of the [Git][git] config file format, which itself is based on the old [Windows INI file][INI] format. The entire file is broken up into sections, which are created by placing the section name between two pairs of square brackets. Sections are optional, but they are the recommended way of grouping your definitions into smaller, more manageable chunks. Each grouping section contains N definitions. These definitions start with the key placed within a single pair of square brackets. It then contains a number of key-value pairs, including a comment, a comma-separated list of tags and all of the translations. ### Placeholders Twine supports [`printf` style placeholders][printf] with one peculiarity: `@` is used for strings instead of `s`. This is because Twine started out as a tool for iOS and OS X projects. ### Tags Tags are used by Twine as a way to only work with a subset of your definitions at any given point in time. Each definition can be assigned zero or more tags which are separated by commas. Tags are optional, though highly recommended. You can get a list of all definitions currently missing tags by executing the [`validate-twine-file`](#validate-twine-file) command with the `--pedantic` option. When generating a localization file, you can specify which definitions should be included using the `--tags` option. Provide a comma separated list of tags to match all definitions that contain any of the tags (`--tags tag1,tag2` matches all definitions tagged with `tag1` _or_ `tag2`). Provide multiple `--tags` options to match defintions containing all specified tags (`--tags tag1 --tags tag2` matches all definitions tagged with `tag1` _and_ `tag2`). You can match definitions _not_ containing a tag by prefixing the tag with a tilde (`--tags ~tag1` matches all definitions _not_ tagged with `tag1`). All three options are combinable. ### Whitespace Whitepace in this file is mostly ignored. If you absolutely need to put spaces at the beginning or end of your translated string, you can wrap the entire string in a pair of `` ` `` characters. If your actual string needs to start *and* end with a grave accent, you can wrap it in another pair of `` ` `` characters. See the example, below. ### References If you want a definition to inherit the values of another definition, you can use a reference. Any property not specified for a definition will be taken from the reference. ### Example ```ini [[General]] [yes] en = Yes es = Sí fr = Oui ja = はい [no] en = No fr = Non ja = いいえ [[Errors]] [path_not_found_error] en = The file '%@' could not be found. tags = app1,app6 comment = An error describing when a path on the filesystem could not be found. [network_unavailable_error] en = The network is currently unavailable. tags = app1 comment = An error describing when the device can not connect to the internet. [dismiss_error] ref = yes en = Dismiss [[Escaping Example]] [list_item_separator] en = `, ` tags = mytag comment = A string that should be placed between multiple items in a list. For example: Red, Green, Blue [grave_accent_quoted_string] en = ``%@`` tags = myothertag comment = This string will evaluate to `%@`. ``` ## Supported Output Formats Twine currently supports the following output formats: * [iOS and OS X String Resources][applestrings] (format: apple) * [Android String Resources][androidstrings] (format: android) * Supports [basic styling][androidstyling] with \, \, \ and \ links. These tags will *not* be escaped. Use [`getText()`](https://developer.android.com/reference/android/content/res/Resources.html#getText(int)) to read these strings. Also tags inside `/dev/null; then twine generate-localization-file twine.txt ./src/main/res/values/generated_strings.xml; fi' exec { executable "sh" args '-c', script } } ``` Now every time you build your app the localization files are generated from the Twine file. ## User Interface * [Twine TextMate 2 Bundle](https://github.com/mobiata/twine.tmbundle) — This [TextMate 2](https://github.com/textmate/textmate) bundle will make it easier for you to work with Twine files. In particular, it lets you use code folding to easily collapse and expand both definitions and sections. ## Extending Twine If there's a format Twine does not yet support and you're keen to change that, check out the [documentation](documentation/formatters.md). ## Contributors Many thanks to all of the contributors to the Twine project, including: * [Blake Watters](https://github.com/blakewatters) * [bootstraponline](https://github.com/bootstraponline) * [Ishitoya Kentaro](https://github.com/kent013) * [Joseph Earl](https://github.com/JosephEarl) * [Kevin Everets](https://github.com/keverets) * [Kevin Wood](https://github.com/kwood) * [Mohammad Hejazi](https://github.com/MohammadHejazi) * [Robert Guo](http://www.robertguo.me/) * [Sebastian Ludwig](https://github.com/sebastianludwig) * [Sergey Pisarchik](https://github.com/SergeyPisarchik) * [Shai Shamir](https://github.com/pichirichi) [rubyzip]: http://rubygems.org/gems/rubyzip [git]: http://git-scm.org/ [INI]: http://en.wikipedia.org/wiki/INI_file [applestrings]: http://developer.apple.com/documentation/Cocoa/Conceptual/LoadingResources/Strings/Strings.html [androidstrings]: http://developer.android.com/guide/topics/resources/string-resource.html [androidstyling]: http://developer.android.com/guide/topics/resources/string-resource.html#FormattingAndStyling [gettextpo]: http://www.gnu.org/savannah-checkouts/gnu/gettext/manual/html_node/PO-Files.html [jquerylocalize]: https://github.com/coderifous/jquery-localize [djangopo]: https://docs.djangoproject.com/en/dev/topics/i18n/translation/ [tizen]: https://developer.tizen.org/documentation/articles/localization [flash]: http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/mx/resources/IResourceManager.html#getString() [printf]: https://en.wikipedia.org/wiki/Printf_format_string