From 698ae855d36eafe57bb93938cae68a70b910c90d Mon Sep 17 00:00:00 2001 From: Damien Elmes Date: Sat, 27 Mar 2021 10:39:53 +1000 Subject: [PATCH] update 1 arg tr strings in rslib --- pylib/tools/rewrite_tr.py | 15 ++++++--- rslib/i18n/build/write_strings.rs | 28 +++++++--------- rslib/src/backend/progress.rs | 5 ++- rslib/src/browser_rows.rs | 13 +++----- rslib/src/dbcheck.rs | 54 +++++++------------------------ rslib/src/err.rs | 40 +++++++++-------------- rslib/src/media/check.rs | 34 ++++++------------- rslib/src/notetype/emptycards.rs | 5 +-- rslib/src/stats/card.rs | 7 ++-- rslib/src/template.rs | 15 +++------ 10 files changed, 75 insertions(+), 141 deletions(-) diff --git a/pylib/tools/rewrite_tr.py b/pylib/tools/rewrite_tr.py index 1c088b2fd..0a36ba25f 100644 --- a/pylib/tools/rewrite_tr.py +++ b/pylib/tools/rewrite_tr.py @@ -9,13 +9,20 @@ from re import Match import stringcase -TR_REF = re.compile(r"\.tr\(\s*TR::([^,) ]+)\)") +TR_REF = re.compile(r'\.trn\(\s*TR::([^,) ]+),\s+tr_(?:strs|args)!\[((?:"[A-z0-9_]+"\s*=>[^=]+?)+)]\s*,?\s*\)') +TR_ARG_INNER = re.compile(r'"([A-z0-9_]+)"\s*=>(?!=>)+,?\s*') +# eg "count"=>output.trash_count, "megs"=>megs +def rewrite_tr_args(args: str) -> str: + return TR_ARG_INNER.sub("", args) def repl(m: Match) -> str: name = stringcase.snakecase(m.group(1)) - # args = m.group(2) - return f".{name}()" + args = rewrite_tr_args(m.group(2)) + #print(m.group(0)) + #print(f".{name}({args})") + #print(args) + return f".{name}({args})" def update_py(path: str) -> None: @@ -24,7 +31,7 @@ def update_py(path: str) -> None: if buf != buf2: open(path, "w").writelines(buf2) print("updated", path) - # print(buf2) + # print(buf2) for dirpath, dirnames, fnames in os.walk(os.environ["BUILD_WORKSPACE_DIRECTORY"]): diff --git a/rslib/i18n/build/write_strings.rs b/rslib/i18n/build/write_strings.rs index 6c862fdf7..c89cf54d4 100644 --- a/rslib/i18n/build/write_strings.rs +++ b/rslib/i18n/build/write_strings.rs @@ -7,7 +7,7 @@ use inflections::Inflect; use std::{fmt::Write, fs, path::PathBuf}; use crate::{ - extract::{Module, Translation, VariableKind}, + extract::{Module, Translation}, gather::{TranslationsByFile, TranslationsByLang}, }; @@ -34,6 +34,7 @@ fn write_methods(modules: &[Module], buf: &mut String) { r#" use crate::I18n; use crate::tr_args; +use fluent::FluentValue; use std::borrow::Cow; impl I18n { @@ -46,18 +47,12 @@ impl I18n { let doc = translation.text.replace("\n", " "); let in_args; let out_args; - let outtype; - let trailer; if translation.variables.is_empty() { in_args = "".to_string(); out_args = ", None".to_string(); - outtype = "Cow<'a, str>"; - trailer = ""; } else { in_args = build_in_args(translation); out_args = build_out_args(translation); - outtype = "String"; - trailer = ".to_string()"; } writeln!( @@ -65,16 +60,14 @@ impl I18n { r#" /// {doc} #[inline] - pub fn {func}<'a>(&'a self{in_args}) -> {outtype} {{ - self.tr_("{key}"{out_args}){trailer} + pub fn {func}<'a>(&'a self{in_args}) -> Cow<'a, str> {{ + self.tr_("{key}"{out_args}) }}"#, func = func, key = key, doc = doc, - outtype = outtype, in_args = in_args, out_args = out_args, - trailer = trailer, ) .unwrap(); } @@ -103,12 +96,13 @@ fn build_in_args(translation: &Translation) -> String { .variables .iter() .map(|var| { - let kind = match var.kind { - VariableKind::Int => "i64", - VariableKind::Float => "f64", - VariableKind::String => "&str", - VariableKind::Any => "&str", - }; + // let kind = match var.kind { + // VariableKind::Int => "i64", + // VariableKind::Float => "f64", + // VariableKind::String => "&str", + // VariableKind::Any => "&str", + // }; + let kind = "impl Into>"; format!("{}: {}", var.name.to_snake_case(), kind) }) .collect(); diff --git a/rslib/src/backend/progress.rs b/rslib/src/backend/progress.rs index 095994ee0..7b3544712 100644 --- a/rslib/src/backend/progress.rs +++ b/rslib/src/backend/progress.rs @@ -57,8 +57,7 @@ pub(super) fn progress_to_proto(progress: Option, i18n: &I18n) -> pb:: match progress { Progress::MediaSync(p) => pb::progress::Value::MediaSync(media_sync_progress(p, i18n)), Progress::MediaCheck(n) => { - let s = i18n.trn(TR::MediaCheckChecked, tr_args!["count"=>n]); - pb::progress::Value::MediaCheck(s) + pb::progress::Value::MediaCheck(i18n.media_check_checked(n).into()) } Progress::FullSync(p) => pb::progress::Value::FullSync(pb::progress::FullSync { transferred: p.transferred_bytes as u32, @@ -119,7 +118,7 @@ pub(super) fn progress_to_proto(progress: Option, i18n: &I18n) -> pb:: fn media_sync_progress(p: MediaSyncProgress, i18n: &I18n) -> pb::progress::MediaSync { pb::progress::MediaSync { - checked: i18n.trn(TR::SyncMediaCheckedCount, tr_args!["count"=>p.checked]), + checked: i18n.sync_media_checked_count(p.checked).into(), added: i18n.trn( TR::SyncMediaAddedCount, tr_args!["up"=>p.uploaded_files,"down"=>p.downloaded_files], diff --git a/rslib/src/browser_rows.rs b/rslib/src/browser_rows.rs index 14e5bbb37..83d59d09d 100644 --- a/rslib/src/browser_rows.rs +++ b/rslib/src/browser_rows.rs @@ -6,7 +6,7 @@ use std::sync::Arc; use itertools::Itertools; use crate::err::{AnkiError, Result}; -use crate::i18n::{tr_args, I18n, TR}; +use crate::i18n::I18n; use crate::{ card::{Card, CardID, CardQueue, CardType}, collection::Collection, @@ -236,12 +236,9 @@ impl<'a> RowContext<'a> { fn card_due_str(&mut self) -> String { let due = if self.card.original_deck_id != DeckID(0) { - self.i18n.browsing_filtered().into() + self.i18n.browsing_filtered() } else if self.card.queue == CardQueue::New || self.card.ctype == CardType::New { - self.i18n.trn( - TR::StatisticsDueForNewCard, - tr_args!["number"=>self.card.due], - ) + self.i18n.statistics_due_for_new_card(self.card.due) } else { let date = if self.card.queue == CardQueue::Learn { TimestampSecs(self.card.due as i64) @@ -254,12 +251,12 @@ impl<'a> RowContext<'a> { } else { return "".into(); }; - date.date_string() + date.date_string().into() }; if (self.card.queue as i8) < 0 { format!("({})", due) } else { - due + due.into() } } diff --git a/rslib/src/dbcheck.rs b/rslib/src/dbcheck.rs index fd537ef2e..a0dabe07e 100644 --- a/rslib/src/dbcheck.rs +++ b/rslib/src/dbcheck.rs @@ -5,7 +5,7 @@ use crate::{ collection::Collection, config::SchedulerVersion, err::{AnkiError, DBErrorKind, Result}, - i18n::{tr_args, I18n, TR}, + i18n::I18n, notetype::{ all_stock_notetypes, AlreadyGeneratedCardInfo, CardGenContext, NoteType, NoteTypeID, NoteTypeKind, @@ -45,68 +45,38 @@ impl CheckDatabaseOutput { let mut probs = Vec::new(); if self.notetypes_recovered > 0 { - probs.push(i18n.trn( - TR::DatabaseCheckNotetypesRecovered, - tr_args!["count"=>self.revlog_properties_invalid], - )); + probs.push(i18n.database_check_notetypes_recovered()); } if self.card_position_too_high > 0 { - probs.push(i18n.trn( - TR::DatabaseCheckNewCardHighDue, - tr_args!["count"=>self.card_position_too_high], - )); + probs.push(i18n.database_check_new_card_high_due(self.card_position_too_high)); } if self.card_properties_invalid > 0 { - probs.push(i18n.trn( - TR::DatabaseCheckCardProperties, - tr_args!["count"=>self.card_properties_invalid], - )); + probs.push(i18n.database_check_card_properties(self.card_properties_invalid)); } if self.cards_missing_note > 0 { - probs.push(i18n.trn( - TR::DatabaseCheckCardMissingNote, - tr_args!["count"=>self.cards_missing_note], - )); + probs.push(i18n.database_check_card_missing_note(self.cards_missing_note)); } if self.decks_missing > 0 { - probs.push(i18n.trn( - TR::DatabaseCheckMissingDecks, - tr_args!["count"=>self.decks_missing], - )); + probs.push(i18n.database_check_missing_decks(self.decks_missing)); } if self.field_count_mismatch > 0 { - probs.push(i18n.trn( - TR::DatabaseCheckFieldCount, - tr_args!["count"=>self.field_count_mismatch], - )); + probs.push(i18n.database_check_field_count(self.field_count_mismatch)); } if self.card_ords_duplicated > 0 { - probs.push(i18n.trn( - TR::DatabaseCheckDuplicateCardOrds, - tr_args!["count"=>self.card_ords_duplicated], - )); + probs.push(i18n.database_check_duplicate_card_ords(self.card_ords_duplicated)); } if self.templates_missing > 0 { - probs.push(i18n.trn( - TR::DatabaseCheckMissingTemplates, - tr_args!["count"=>self.templates_missing], - )); + probs.push(i18n.database_check_missing_templates(self.templates_missing)); } if self.revlog_properties_invalid > 0 { - probs.push(i18n.trn( - TR::DatabaseCheckRevlogProperties, - tr_args!["count"=>self.revlog_properties_invalid], - )); + probs.push(i18n.database_check_revlog_properties(self.revlog_properties_invalid)); } if self.invalid_utf8 > 0 { - probs.push(i18n.trn( - TR::DatabaseCheckNotesWithInvalidUtf8, - tr_args!["count"=>self.invalid_utf8], - )); + probs.push(i18n.database_check_notes_with_invalid_utf8(self.invalid_utf8)); } - probs + probs.into_iter().map(Into::into).collect() } } diff --git a/rslib/src/err.rs b/rslib/src/err.rs index c22ab7ea1..aaee2faca 100644 --- a/rslib/src/err.rs +++ b/rslib/src/err.rs @@ -1,7 +1,7 @@ // Copyright: Ankitects Pty Ltd and contributors // License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html -use crate::i18n::{tr_args, tr_strs, I18n, TR}; +use crate::i18n::I18n; pub use failure::{Error, Fail}; use nom::error::{ErrorKind as NomErrorKind, ParseError as NomParseError}; use reqwest::StatusCode; @@ -113,17 +113,16 @@ impl AnkiError { NetworkErrorKind::ProxyAuth => i18n.network_proxy_auth(), NetworkErrorKind::Other => i18n.network_other(), }; - let details = i18n.trn(TR::NetworkDetails, tr_strs!["details"=>info]); + let details = i18n.network_details(info.as_str()); format!("{}\n\n{}", summary, details) } AnkiError::TemplateError { info } => { // already localized info.into() } - AnkiError::TemplateSaveError { ordinal } => i18n.trn( - TR::CardTemplatesInvalidTemplateNumber, - tr_args!["number"=>ordinal+1], - ), + AnkiError::TemplateSaveError { ordinal } => i18n + .card_templates_invalid_template_number(ordinal + 1) + .into(), AnkiError::DBError { info, kind } => match kind { DBErrorKind::Corrupt => info.clone(), DBErrorKind::Locked => "Anki already open, or media currently syncing.".into(), @@ -139,12 +138,9 @@ impl AnkiError { SearchErrorKind::EmptyQuote => i18n.search_empty_quote(), SearchErrorKind::UnclosedQuote => i18n.search_unclosed_quote(), SearchErrorKind::MissingKey => i18n.search_missing_key(), - SearchErrorKind::UnknownEscape(ctx) => i18n - .trn( - TR::SearchUnknownEscape, - tr_strs!["val"=>(ctx.replace('`', "'"))], - ) - .into(), + SearchErrorKind::UnknownEscape(ctx) => { + i18n.search_unknown_escape(ctx.replace('`', "'")).into() + } SearchErrorKind::InvalidState(state) => i18n .trn( TR::SearchInvalidArgument, @@ -158,10 +154,12 @@ impl AnkiError { tr_strs!("term" => "prop:", "argument" => prop.replace('`', "'")), ) .into(), - SearchErrorKind::InvalidPropOperator(ctx) => i18n - .trn(TR::SearchInvalidPropOperator, tr_strs!["val"=>(ctx)]) - .into(), - SearchErrorKind::Regex(text) => format!("
`{}`
", text.replace('`', "'")).into(), + SearchErrorKind::InvalidPropOperator(ctx) => { + i18n.search_invalid_prop_operator(ctx.as_str()).into() + } + SearchErrorKind::Regex(text) => { + format!("
`{}`
", text.replace('`', "'")).into() + } SearchErrorKind::Other(Some(info)) => info.into(), SearchErrorKind::Other(None) => i18n.search_invalid_other(), SearchErrorKind::InvalidNumber { provided, context } => i18n @@ -195,19 +193,13 @@ impl AnkiError { ) .into(), }; - i18n.trn( - TR::SearchInvalidSearch, - tr_args!("reason" => reason.into_owned()), - ) + i18n.search_invalid_search(reason).into() } AnkiError::InvalidInput { info } => { if info.is_empty() { i18n.errors_invalid_input_empty().into() } else { - i18n.trn( - TR::ErrorsInvalidInputDetails, - tr_args!("details" => info.to_owned()), - ) + i18n.errors_invalid_input_details(info.as_str()).into() } } AnkiError::ParseNumError => i18n.errors_parse_number_fail().into(), diff --git a/rslib/src/media/check.rs b/rslib/src/media/check.rs index 6eaea648e..f6235bf8e 100644 --- a/rslib/src/media/check.rs +++ b/rslib/src/media/check.rs @@ -3,7 +3,6 @@ use crate::collection::Collection; use crate::err::{AnkiError, DBErrorKind, Result}; -use crate::i18n::{tr_args, tr_strs, TR}; use crate::latex::extract_latex_expanding_clozes; use crate::log::debug; use crate::media::database::MediaDatabaseContext; @@ -102,37 +101,22 @@ where buf.push('\n'); } - buf += &i.trn( - TR::MediaCheckMissingCount, - tr_args!["count"=>output.missing.len()], - ); + buf += &i.media_check_missing_count(output.missing.len()); buf.push('\n'); - buf += &i.trn( - TR::MediaCheckUnusedCount, - tr_args!["count"=>output.unused.len()], - ); + buf += &i.media_check_unused_count(output.unused.len()); buf.push('\n'); if !output.renamed.is_empty() { - buf += &i.trn( - TR::MediaCheckRenamedCount, - tr_args!["count"=>output.renamed.len()], - ); + buf += &i.media_check_renamed_count(output.renamed.len()); buf.push('\n'); } if !output.oversize.is_empty() { - buf += &i.trn( - TR::MediaCheckOversizeCount, - tr_args!["count"=>output.oversize.len()], - ); + buf += &i.media_check_oversize_count(output.oversize.len()); buf.push('\n'); } if !output.dirs.is_empty() { - buf += &i.trn( - TR::MediaCheckSubfolderCount, - tr_args!["count"=>output.dirs.len()], - ); + buf += &i.media_check_subfolder_count(output.dirs.len()); buf.push('\n'); } @@ -153,7 +137,7 @@ where buf += &i.media_check_oversize_header(); buf.push('\n'); for fname in &output.oversize { - buf += &i.trn(TR::MediaCheckOversizeFile, tr_strs!["filename"=>fname]); + buf += &i.media_check_oversize_file(fname.as_str()); buf.push('\n'); } buf.push('\n') @@ -164,7 +148,7 @@ where buf += &i.media_check_subfolder_header(); buf.push('\n'); for fname in &output.dirs { - buf += &i.trn(TR::MediaCheckSubfolderFile, tr_strs!["filename"=>fname]); + buf += &i.media_check_subfolder_file(fname.as_str()); buf.push('\n'); } buf.push('\n') @@ -175,7 +159,7 @@ where buf += &i.media_check_missing_header(); buf.push('\n'); for fname in &output.missing { - buf += &i.trn(TR::MediaCheckMissingFile, tr_strs!["filename"=>fname]); + buf += &i.media_check_missing_file(fname.as_str()); buf.push('\n'); } buf.push('\n') @@ -186,7 +170,7 @@ where buf += &i.media_check_unused_header(); buf.push('\n'); for fname in &output.unused { - buf += &i.trn(TR::MediaCheckUnusedFile, tr_strs!["filename"=>fname]); + buf += &i.media_check_unused_file(fname.as_str()); buf.push('\n'); } } diff --git a/rslib/src/notetype/emptycards.rs b/rslib/src/notetype/emptycards.rs index a49f478dd..af3b47818 100644 --- a/rslib/src/notetype/emptycards.rs +++ b/rslib/src/notetype/emptycards.rs @@ -79,10 +79,7 @@ impl Collection { write!( buf, "
{}
    ", - self.i18n.trn( - TR::EmptyCardsForNoteType, - tr_args!["notetype"=>nt.name.clone()], - ) + self.i18n.empty_cards_for_note_type(nt.name.clone()) ) .unwrap(); diff --git a/rslib/src/stats/card.rs b/rslib/src/stats/card.rs index 8a8950756..a31c5ba4f 100644 --- a/rslib/src/stats/card.rs +++ b/rslib/src/stats/card.rs @@ -241,10 +241,9 @@ fn revlog_to_text(e: RevlogEntry, i18n: &I18n) -> RevlogText { } else { "".to_string() }; - let taken_secs = i18n.trn( - TR::StatisticsSecondsTaken, - tr_args!["seconds"=>(e.taken_millis / 1000) as i32], - ); + let taken_secs = i18n + .statistics_seconds_taken((e.taken_millis / 1000) as i32) + .into(); RevlogText { time, diff --git a/rslib/src/template.rs b/rslib/src/template.rs index 28f1f8741..f5404889c 100644 --- a/rslib/src/template.rs +++ b/rslib/src/template.rs @@ -2,7 +2,7 @@ // License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html use crate::err::{AnkiError, Result, TemplateError}; -use crate::i18n::{tr_args, tr_strs, I18n, TR}; +use crate::i18n::{tr_strs, I18n, TR}; use crate::{cloze::add_cloze_numbers_in_string, template_filters::apply_filters}; use lazy_static::lazy_static; use nom::branch::alt; @@ -267,11 +267,9 @@ fn localized_template_error(i18n: &I18n, err: TemplateError) -> String { TemplateError::NoClosingBrackets(tag) => i18n.trn( TR::CardTemplateRenderingNoClosingBrackets, tr_strs!("tag"=>tag, "missing"=>"}}"), - ), - TemplateError::ConditionalNotClosed(tag) => i18n.trn( - TR::CardTemplateRenderingConditionalNotClosed, - tr_strs!("missing"=>format!("{{{{/{}}}}}", tag)), - ), + TemplateError::ConditionalNotClosed(tag) => i18n + .card_template_rendering_conditional_not_closed(format!("{{{{/{}}}}}", tag)) + .into(), TemplateError::ConditionalNotOpen { closed, currently_open, @@ -561,10 +559,7 @@ pub fn render_card( let empty_message = if is_cloze && cloze_is_empty(field_map, card_ord) { Some(format!( "
    {}
    {}
    ", - i18n.trn( - TR::CardTemplateRenderingMissingCloze, - tr_args!["number"=>card_ord+1] - ), + i18n.card_template_rendering_missing_cloze(card_ord + 1), TEMPLATE_BLANK_CLOZE_LINK, i18n.card_template_rendering_more_info() ))