Skip to content

Commit

Permalink
Adds support for multiple languages
Browse files Browse the repository at this point in the history
  • Loading branch information
niklasmohrin committed Aug 10, 2020
1 parent 0b277c7 commit 68f9fca
Show file tree
Hide file tree
Showing 2 changed files with 81 additions and 34 deletions.
55 changes: 34 additions & 21 deletions src/cache.rs
Original file line number Diff line number Diff line change
Expand Up @@ -140,38 +140,51 @@ impl Cache {
}
}

/// Check for pages for a given platform in one of the given languages.
fn find_page_for_platform(
&self,
name: &str,
cache_dir: &PathBuf,
platform: &str,
language_dirs: &[String],
) -> Option<PathBuf> {
language_dirs
.iter()
.map(|lang_dir| cache_dir.join(lang_dir).join(platform).join(name))
.find(|path| path.exists() && path.is_file())
}

/// Search for a page and return the path to it.
pub fn find_page(&self, name: &str) -> Option<PathBuf> {
// Build page file name
pub fn find_page(&self, name: &str, languages: &[String]) -> Option<PathBuf> {
let page_filename = format!("{}.md", name);

// Get platform dir
let platforms_dir = match Self::get_cache_dir() {
Ok(cache_dir) => cache_dir.join("tldr-master").join("pages"),
let cache_dir = match Self::get_cache_dir() {
Ok(cache_dir) => cache_dir.join("tldr-master"),
_ => return None,
};

// Determine platform
let platform = self.get_platform_dir();
let lang_dirs: Vec<String> = languages
.iter()
.map(|lang| {
if lang == "en" {
String::from("pages")
} else {
format!("pages.{}", lang)
}
})
.collect();

// Search for the page in the platform specific directory
if let Some(pf) = platform {
let path = platforms_dir.join(&pf).join(&page_filename);
if path.exists() && path.is_file() {
return Some(path);
// Try to find a platform specific path first.
if let Some(pf) = self.get_platform_dir() {
let pf_path = self.find_page_for_platform(&page_filename, &cache_dir, pf, &lang_dirs);
if pf_path.is_some() {
return pf_path;
}
}

// If platform is not supported or if platform specific page does not exist,
// look up the page in the "common" directory.
let path = platforms_dir.join("common").join(&page_filename);

// Return it if it exists, otherwise give up and return `None`
if path.exists() && path.is_file() {
Some(path)
} else {
None
}
// Did not find platform specific results, fall back to "common"
self.find_page_for_platform(&page_filename, &cache_dir, "common", &lang_dirs)
}

/// Return the available pages.
Expand Down
60 changes: 47 additions & 13 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,18 +57,19 @@ Usage:
Options:
-h --help Show this screen
-v --version Show version information
-l --list List all commands in the cache
-f --render <file> Render a specific markdown file
-o --os <type> Override the operating system [linux, osx, sunos, windows]
-u --update Update the local cache
-c --clear-cache Clear the local cache
-p --pager Use a pager to page output
-m --markdown Display the raw markdown instead of rendering it
-q --quiet Suppress informational messages
--config-path Show config file path
--seed-config Create a basic config
-h --help Show this screen
-v --version Show version information
-l --list List all commands in the cache
-f --render <file> Render a specific markdown file
-o --os <type> Override the operating system [linux, osx, sunos, windows]
-L --language <lang> Override the language settings
-u --update Update the local cache
-c --clear-cache Clear the local cache
-p --pager Use a pager to page output
-m --markdown Display the raw markdown instead of rendering it
-q --quiet Suppress informational messages
--config-path Show config file path
--seed-config Create a basic config
Examples:
Expand Down Expand Up @@ -103,6 +104,7 @@ struct Args {
flag_config_path: bool,
flag_seed_config: bool,
flag_markdown: bool,
flag_language: Option<String>,
}

/// Print page by path
Expand Down Expand Up @@ -376,6 +378,38 @@ fn main() {
process::exit(0);
}

// Language list according to
// https://github.com/tldr-pages/tldr/blob/master/CLIENT-SPECIFICATION.md#language
let languages = if let Some(ref lang) = args.flag_language {
// Language overwritten by console argument
vec![lang.clone()]
} else if let Ok(lang) = std::env::var("LANG") {
let locales = std::env::var("LANGUAGE").unwrap_or_default();
let mut locales: Vec<&str> = locales.split(':').collect();
// According to the client specification, these should be appended
locales.push(&lang[..]);
locales.push("en");

let mut lang_list = Vec::new();
for locale in locales.iter() {
if locale.len() >= 5 && locale.chars().nth(2) == Some('_') {
// Language with county code
lang_list.push(&locale[..5]);
}
if locale.len() >= 2 {
// Language code
lang_list.push(&locale[..2]);
}
}

lang_list.dedup();
lang_list.iter().map(|&s| String::from(s)).collect()
} else {
// Even if the LANGUAGES environment variable is set,
// the specification wants to only look for English pages.
vec!["en".into()]
};

// Show command from cache
if let Some(ref command) = args.arg_command {
let command = command.join("-");
Expand All @@ -386,7 +420,7 @@ fn main() {
}

// Search for command in cache
if let Some(path) = cache.find_page(&command) {
if let Some(path) = cache.find_page(&command, &languages) {
if let Err(msg) = print_page(&path, args.flag_markdown, &config) {
eprintln!("{}", msg);
process::exit(1);
Expand Down

0 comments on commit 68f9fca

Please sign in to comment.