update 1 arg tr strings in rslib

This commit is contained in:
Damien Elmes 2021-03-27 10:39:53 +10:00
parent d5e5722dc8
commit 698ae855d3
10 changed files with 75 additions and 141 deletions

View File

@ -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"]):

View File

@ -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<FluentValue<'a>>";
format!("{}: {}", var.name.to_snake_case(), kind)
})
.collect();

View File

@ -57,8 +57,7 @@ pub(super) fn progress_to_proto(progress: Option<Progress>, 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<Progress>, 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],

View File

@ -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()
}
}

View File

@ -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()
}
}

View File

@ -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!("<pre>`{}`</pre>", text.replace('`', "'")).into(),
SearchErrorKind::InvalidPropOperator(ctx) => {
i18n.search_invalid_prop_operator(ctx.as_str()).into()
}
SearchErrorKind::Regex(text) => {
format!("<pre>`{}`</pre>", 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(),

View File

@ -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');
}
}

View File

@ -79,10 +79,7 @@ impl Collection {
write!(
buf,
"<div><b>{}</b></div><ol>",
self.i18n.trn(
TR::EmptyCardsForNoteType,
tr_args!["notetype"=>nt.name.clone()],
)
self.i18n.empty_cards_for_note_type(nt.name.clone())
)
.unwrap();

View File

@ -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,

View File

@ -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!(
"<div>{}<br><a href='{}'>{}</a></div>",
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()
))