crowbook_intl/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//! # Known limitations and bugs
107//!
108//! * Currently, `crowbook-intl` doesn't handle correctly raw string literals in `lformat!`
109//! (they won't be translated correctly).
110//! * Multiple calls to the same string, but formatted differently (e.g. using a backslash
111//! before a newline to separate a string on multiple lines) will also cause problems.
112//!
113//! # Warning
114//!
115//! In case the complexity of the operation didn't discourage you, I should warn you
116//! that this library is highly experimental at this time.
117//!
118//! # License
119//!
120//! This is free software, published under the [Mozilla Public License,
121//! version 2.0](https://www.mozilla.org/en-US/MPL/2.0/).
122
123
124extern crate regex;
125#[macro_use] extern crate lazy_static;
126extern crate walkdir;
127
128mod common;
129mod macrogen;
130mod lang;
131mod error;
132mod localizer;
133mod message;
134mod extractor;
135
136pub use error::{Result, Error};
137pub use localizer::Localizer;
138pub use extractor::Extractor;