crowbook_localize/
lib.rs

1// This Source Code Form is subject to the terms of the Mozilla Public
2// License, v. 2.0. If a copy of the MPL was not distributed with
3// this file, You can obtain one at https://mozilla.org/MPL/2.0/.
4
5//! A library to localize strings, translating them according to runtime options.
6//!
7//! Basically, this library allows your project to generate a `lformat!` macro, that behaves
8//! similarly to `format!`, except the message string (the first argument) might get translated
9//! (if you can find the appropriate string for the language).
10//!
11//! # Usage
12//!
13//! First, you'll need to add the following to your `Cargo.toml` file:
14//!
15//! ```toml
16//! build = "build.rs"
17//! 
18//! [build-dependencies]
19//! crowbook-intl = "0.1.0"
20//!
21//! [dependencies]
22//! crowbook-intl-runtime = "0.1.0"
23//! ```
24//!
25//! You'll then need to create the `build.rs` file, which can look like this:
26//!
27//! ```rust,ignore
28//! extern crate crowbook_intl;
29//! use crowbook_intl::{Localizer, Extractor};
30//! 
31//! fn main() {
32//!     // Generate a `lang/default.pot` containing strings used to call `lformat!`
33//!     let mut extractor = Extractor::new();
34//!     extractor.add_messages_from_dir(concat!(env!("CARGO_MANIFEST_DIR"), "/src")).unwrap();
35//!     extractor.write_pot_file(concat!(env!("CARGO_MANIFEST_DIR"), "/lang/default.pot")).unwrap();
36//!
37//!     // Generate the `localize_macros.rs` file
38//!     let mut localizer = Localizer::new(&extractor);
39//!     // Use env::var instead of env! to avoid problems when cross-compiling
40//!     let dest_path = Path::new(&env::var("OUT_DIR").unwrap())
41//!        .join("localize_macros.rs");
42//!     localizer.write_macro_file(dest_path).unwrap();
43//! }
44//! ```
45//!
46//! This will create a `localize_macros.rs` at build time somewhere in `OUT_DIR`, containing the `lformat!` macro.
47//! To actually use this macro, you have to create a `src/localize_macros.rs` file that includes it:
48//!
49//! ```rust,ignore
50//! include!(concat!(env!("OUT_DIR"), "/localize_macros.rs"));
51//! ```
52//!
53//! //! To use it, the last step is to modify your `src/lib/lib.rs` file:
54//!
55//! ```rust,ignore
56//! extern crate crowbook_intl_runtime;
57//! #[macro_use] mod localize_macros;
58//! ```
59//!
60//! Once this is done, you can start replacing your calls to `format!` with calls to `lformat!`.
61//!
62//! In order to get translation, you'll need to actually translate the strings in separate
63//! files, and set your `build.rs` to load them.
64//!
65//! E.g., if you have the following code:
66//!
67//! ```rust,ignore
68//! println!("{}", lformat!("Hello, world!"));
69//! ```
70//!
71//! and you want it translated in french, you'll have to create a `lang/fr.po` file
72//! from the `lang/default.pot` file containing:
73//!
74//! ```text
75//! msgid "Hello, world!";
76//! msgstr "Bonjour le monde !";
77//! ```
78//!
79//! And load it in your `build.rs` file:
80//!
81//! ```rust,ignore
82//! let mut localizer = Localizer::new();
83//! localizer.add_lang("fr", include_str!(concat!(env!("CARGO_MANIFEST_DIR"), "/lang/fr.mp"))).unwrap();
84//! (...)
85//! ```
86//!
87//! Once *this* is done, you can use the `localize_macros::set_lang` function
88//! to switch the language at runtime:
89//!
90//! ```rust,ignore
91//! use crowbook_intl_runtime::set_lang;
92//! set_lang("en");
93//! println!("{}", lformat!("Hello, world!")); // prints "Hello, world!"
94//! set_lang("fr");
95//! println!("{}", lformat!("Hello, world!")); // prints "Bonjour le monde !"
96//! ```
97//!
98//! # Updating your translation
99//!
100//! When you add new strings that need to be translated (by more calls to `lformat!`),
101//! or when you change the content of existing strings, you can use [Gettext's `msgmerge` and `msgcmp`](https://www.gnu.org/software/gettext/manual/html_node/msgmerge-Invocation.html)
102//! commands to update your translation. While it is not guaranteed that the formats are
103//! strictly identical, it should work. (That is, it is a bug if it doesn't; but at this
104//! stage, this library is absolutely not guaranteed to be bug-free.)
105//!
106//! # Warning
107//!
108//! In case the complexity of the operation didn't discourage you, I should warn you
109//! that this library is highly experimental at this time.
110
111
112extern crate regex;
113#[macro_use] extern crate lazy_static;
114extern crate walkdir;
115
116mod common;
117mod macrogen;
118mod lang;
119mod error;
120mod localizer;
121mod message;
122mod extractor;
123
124pub use error::{Result, Error};
125pub use localizer::Localizer;
126pub use extractor::Extractor;