Skip to content

Commit

Permalink
chore(i18n): add dynamic translations
Browse files Browse the repository at this point in the history
  • Loading branch information
j-mendez committed Oct 11, 2023
1 parent e20f657 commit 1a696c9
Show file tree
Hide file tree
Showing 7 changed files with 38 additions and 80 deletions.
11 changes: 3 additions & 8 deletions accessibility-rs/src/engine/audit/wcag.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use crate::engine::issue::Issue;
use crate::engine::rules::wcag_rule_map::RULES_A;
use crate::i18n::locales::{get_message, Langs};
use crate::i18n::locales::{get_message_i18n, Langs};
use crate::Auditor;

/// baseline for all rules
Expand Down Expand Up @@ -32,9 +32,9 @@ impl WCAG3AA {
if !valid {
// get locales prior or from document
let message = if !message.is_empty() {
message
message.into()
} else {
get_message(&rule.rule_id, &section, &Langs::En.as_str())
get_message_i18n(&rule, &section, &Langs::En.as_str())
};

let issue = Issue::new(
Expand All @@ -52,11 +52,6 @@ impl WCAG3AA {
);
issues.push(issue);
}

println!(
"RULE {:?} {:?} {:?} Valid: {:?}",
rule.rule_id, rule.criteria, section, valid
);
}
}
_ => (),
Expand Down
4 changes: 2 additions & 2 deletions accessibility-rs/src/engine/issue.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ pub struct Issue {
/// the typecode of the issue 0,1,2
pub type_code: u8,
/// the message of the issue
pub message: &'static str,
pub message: String,
/// the type of runner
pub runner: &'static str,
/// extra details for the runner
Expand All @@ -52,7 +52,7 @@ pub struct Issue {
impl Issue {
/// create a new issue
pub fn new(
message: &'static str,
message: String,
context: &str,
code: &str,
issue_type: &'static str,
Expand Down
1 change: 1 addition & 0 deletions accessibility-rs/src/engine/rules/rule.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ impl Validation {
}

/// the rule validation method that should be performed.
#[derive(Debug)]
pub struct Rule {
/// the message id of the rule to point to the locale
pub rule_id: Techniques,
Expand Down
22 changes: 22 additions & 0 deletions accessibility-rs/src/engine/rules/wcag_base.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ impl Criteria {
}

/// wcag principle to follow
#[derive(Debug)]
pub enum Principle {
/// Provide text alternatives for any non-text content so that it can be changed into other forms people need, such as large print, braille, speech, symbols or simpler language.
Perceivable,
Expand All @@ -33,6 +34,7 @@ pub enum Principle {
}

impl Principle {
/// the principle to string code
pub fn as_str(&self) -> &'static str {
match self {
Principle::Perceivable => "Principle1",
Expand All @@ -41,9 +43,19 @@ impl Principle {
Principle::Robust => "Principle4",
}
}
/// the principle index
pub fn as_index(&self) -> &'static str {
match self {
Principle::Perceivable => "1",
Principle::Operable => "2",
Principle::Understandable => "3",
Principle::Robust => "4",
}
}
}

/// wcag principle to follow
#[derive(Debug)]
pub enum Guideline {
/// Provide ways to help users navigate, find content, and determine where they are.
Navigable,
Expand All @@ -56,6 +68,7 @@ pub enum Guideline {
}

impl Guideline {
/// the guideline to string code
pub fn as_str(&self) -> &'static str {
match self {
Guideline::EnoughTime => "Guideline2_2",
Expand All @@ -64,4 +77,13 @@ impl Guideline {
Guideline::Predictable => "Guideline3_2",
}
}
/// the principle index
pub fn as_index(&self) -> &'static str {
match self {
Guideline::EnoughTime => "2_2",
Guideline::Navigable => "2_4",
Guideline::Readable => "3_1",
Guideline::Predictable => "3_2",
}
}
}
2 changes: 1 addition & 1 deletion accessibility-rs/src/engine/rules/wcag_rule_map.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ lazy_static! {
Rule::new(Techniques::H25, Criteria::Error, Principle::Operable, Guideline::Navigable, |_rule, nodes| {
Validation::new_issue(!nodes.is_empty(), "1.NoTitleEl")
}),
Rule::new(Techniques::H25, Criteria::Error, Principle::Understandable, Guideline::Predictable, |_rule, nodes| {
Rule::new(Techniques::H25, Criteria::Error, Principle::Operable, Guideline::Navigable, |_rule, nodes| {
Validation::new_issue(nodes.is_empty() || nodes[0].0.html().is_empty(), "1.EmptyTitle")
}),
])),
Expand Down
74 changes: 7 additions & 67 deletions accessibility-rs/src/i18n/locales.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
use crate::engine::rules::ids::Techniques;
use std::collections::BTreeMap;
use crate::engine::rules::rule::Rule;

type M = &'static str;

Expand Down Expand Up @@ -64,74 +63,15 @@ impl Langs {
}
}

/// the context of the issue
impl Messages {
/// create a new message
pub fn new(en: M, es: M, de: M, ja: M) -> Messages {
Messages {
en,
es,
de,
ja,
pt_pt: &"",
pt_br: &"",
zh_cn: &"",
zh_tw: &"",
hi: &"",
}
}
}

/// parse message translation
pub fn get_message(rule_id: &Techniques, section: &str, lang: &str) -> &'static str {
let rule_id = rule_id.as_str();
let message = if section.is_empty() {
LOCALES.get(&rule_id)
} else {
LOCALES.get([rule_id, section].join(".").as_str())
};

match message {
Some(m) => match lang {
"en" => m.en,
"es" => m.es,
_ => Default::default(),
},
_ => Default::default(),
}
}

/// get message config type
pub fn get_message_i18n(rule_id: &Techniques, section: &str, lang: &str) -> String {
let rule_id = rule_id.as_str();
pub fn get_message_i18n(rule: &Rule, section: &str, lang: &str) -> String {
let base = [rule.guideline.as_index(), rule.principle.as_index()].join("_") + "_";
let message = if section.is_empty() {
rule_id.to_string()
[rule.rule_id.as_str()].join(".").to_string()
} else {
[rule_id, section].join(".").to_string()
[rule.rule_id.as_str(), section].join(".").to_string()
};
let message = [base.as_str(), message.as_str()].join("").to_string();

message
}

lazy_static! {
/// message for an issue
pub static ref LOCALES: BTreeMap<&'static str, Messages> = {
BTreeMap::from([
(Techniques::H25.pairs()[0], Messages::new(
"A title should be provided for the document, using a non-empty title element in the head section.",
"Se debe proporcionar un título para el documento, utilizando un elemento de título no vacío en la sección head.",
"",
"head セクションの空でない title 要素を使って、文書にタイトルをつけるべきです。"
)),
(Techniques::H25.pairs()[1], Messages::new(&"The title element in the head section should be non-empty.", "", "", "")),
(Techniques::H32.pairs()[0], Messages::new(&r###"Form does not contain a submit button (input type="submit", input type="image", or button type="submit")."###, "", "", "")),
(Techniques::H64.pairs()[0], Messages::new(&"Iframe element requires a non-empty title attribute that identifies the frame.", "", "", "")),
(Techniques::H57.pairs()[0], Messages::new(&"The html element should have a lang or xml:lang attribute which describes the language of the document.", "", "", "")),
(Techniques::H57.pairs()[1], Messages::new(&"The language specified in the lang attribute of the document element does not appear to be well-formed.", "", "", "")),
(Techniques::H57.pairs()[2], Messages::new(&"The language specified in the xml:lang attribute of the document element does not appear to be well-formed.", "", "", "")),
(Techniques::F40.pairs()[0], Messages::new(&"Meta refresh tag used to redirect to another page, with a time limit that is not zero. Users cannot control this time limit.", "", "", "")),
(Techniques::F41.pairs()[0], Messages::new(&"Meta refresh tag used to refresh the current page. Users cannot control the time limit for this refresh.", "", "", "")),
(Techniques::F47.pairs()[0], Messages::new(&"Blink elements cannot satisfy the requirement that blinking information can be stopped within five seconds.", "", "", "")),
])
};
t!(&message, lang = lang)
}
4 changes: 2 additions & 2 deletions accessibility-rs/tests/unit/meta.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,12 @@ use crate::mocks::mock;

#[test]
/// missing title element
fn _audit_missing_headers() {
fn _audit_missing_title() {
let audit = accessibility_rs::audit(&AuditConfig::basic(mock::MOCK_WEBSITE_HTML));
let mut valid = true;

for x in &audit {
if x.code == "WCAGAAA.Principle3.Guideline3_2.H25" {
if x.code == "WCAGAAA.Principle2.Guideline2_4.H25" {
valid = false;
break;
}
Expand Down

0 comments on commit 1a696c9

Please sign in to comment.