Skip to content

Commit

Permalink
Keep Inline HTML tags in the translated text group while ignoring blo…
Browse files Browse the repository at this point in the history
…ck level HTML tags (#195)

* Keep Inline HTML tags in the translated text group while ignoring block level HTML tags

* rewrite the matches!() macro into a proper match while handling Html|InlineHtml events.
  • Loading branch information
michael-kerscher authored May 22, 2024
1 parent 3836fb3 commit 2168b9c
Show file tree
Hide file tree
Showing 3 changed files with 126 additions and 18 deletions.
18 changes: 18 additions & 0 deletions i18n-helpers/src/gettext.rs
Original file line number Diff line number Diff line change
Expand Up @@ -244,6 +244,24 @@ mod tests {
);
}

#[test]
fn test_translate_inline_html() {
let catalog = create_catalog(&[("foo <b>bar</b> baz", "FOO <b>BAR</b> BAZ")]);
assert_eq!(
translate("foo <b>bar</b> baz", &catalog),
"FOO <b>BAR</b> BAZ"
);
}

#[test]
fn test_translate_block_html() {
let catalog = create_catalog(&[("foo", "FOO"), ("bar", "BAR")]);
assert_eq!(
translate("<div>\n\nfoo\n\n</div><div>\n\nbar\n\n</div>", &catalog),
"<div>\n\nFOO\n\n</div><div>\n\nBAR\n\n</div>"
);
}

#[test]
fn test_translate_table() {
let catalog = create_catalog(&[
Expand Down
98 changes: 80 additions & 18 deletions i18n-helpers/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -368,14 +368,32 @@ pub fn group_events<'a>(events: &'a [(usize, Event<'a>)]) -> Vec<Group<'a>> {

ctx.comments.push(comment);
}
// Otherwise, treat as a skipping group.
_ => {
if let State::Translate(_) = state {
let mut next_groups;
(next_groups, ctx) = state.into_groups(idx, events, ctx);
groups.append(&mut next_groups);

state = State::Skip(idx);
match event {
Event::Html(_) => {
// Otherwise, treat as a skipping group if this is a block level Html tag
if let State::Translate(_) = state {
let mut next_groups;
(next_groups, ctx) = state.into_groups(idx, events, ctx);
groups.append(&mut next_groups);

state = State::Skip(idx);
}
}
Event::InlineHtml(_) =>
// If we're currently skipping, then a new
// translatable group starts here.
{
if let State::Skip(_) = state {
let mut next_groups;
(next_groups, ctx) = state.into_groups(idx, events, ctx);
groups.append(&mut next_groups);

state = State::Translate(idx);
}
}
// this code is inside a match of Event::{Html|InlineHtml}, other types are not possible
_ => unreachable!(),
}
}
}
Expand Down Expand Up @@ -964,13 +982,21 @@ mod tests {
}

#[test]
fn extract_messages_empty_html() {
assert_extract_messages("<span></span>", &[]);
fn extract_messages_keep_empty_inline_html() {
// Keep inline html tags
assert_extract_messages("<span></span>", &[(1, "<span></span>")]);
}

#[test]
fn extract_messages_whitespace_only() {
assert_extract_messages("<span> </span>", &[]);
fn extract_messages_keep_whitespace_inline_html() {
// span is an inline html tag so even whitespace is kept as is
assert_extract_messages("<span> </span>", &[(1, "<span> </span>")]);
}

#[test]
fn extract_messages_ignore_whitespace_only_block_html() {
// Whitespace in block level html tags is ignored
assert_extract_messages("<p> </p>", &[]);
}

#[test]
Expand Down Expand Up @@ -1028,13 +1054,36 @@ mod tests {

#[test]
fn extract_messages_inline_html() {
// HTML tags are skipped, but text inside is extracted:
// Inline HTML tag is kept as is in the translation.
assert_extract_messages(
"Hi <script>alert('there');</script>",
&[
(1, "Hi "), //
(1, "alert('there');"),
],
"Hi from <span dir=\"ltr\">Rust</div>",
&[(1, "Hi from <span dir=\"ltr\">Rust</div>")],
);
}

#[test]
fn extract_messages_block_html() {
// block level HTML tag is skipped, but text inside is extracted.
assert_extract_messages(
"<div class=\"warning\">\n\
\n\
Beware of the dog!\n\
\n\
</div>",
&[(3, "Beware of the dog!")],
);
}

#[test]
fn extract_messages_mixed_html() {
// block level HTML tag is skipped, but text inside is extracted with inline html as is.
assert_extract_messages(
"<div>\n\
\n\
Hi from <span dir=\"ltr\">Rust</span>\n\
\n\
</div>",
&[(3, "Hi from <span dir=\"ltr\">Rust</span>")],
);
}

Expand Down Expand Up @@ -1481,7 +1530,20 @@ But *this* should!
}

#[test]
fn extract_messages_inline_skips() {
fn extract_messages_block_html_skip() {
// The comment is a block level html tag.
assert_extract_messages(
"<!-- mdbook-xgettext:skip -->\n\
This is ignored\n\
\n\
but this is not",
&[(4, "but this is not")],
);
}

#[test]
fn extract_messages_inline_html_skips() {
// The comment is an inline html tag.
assert_extract_messages(
"
this should be translated <!-- mdbook-xgettext:skip --> but not this.
Expand Down
28 changes: 28 additions & 0 deletions i18n-helpers/src/normalize.rs
Original file line number Diff line number Diff line change
Expand Up @@ -460,6 +460,34 @@ mod tests {
);
}

#[test]
fn test_normalize_inline_html() {
// Inline tags are kept as is.
let catalog = create_catalog(&[("foo <span>bar</span>", "FOO <span>BAR</span>")]);
assert_normalized_messages_eq(
catalog,
&[exact("foo <span>bar</span>", "FOO <span>BAR</span>")],
);
}

#[test]
fn test_normalize_block_html() {
// Block level tags are not translated.
let catalog = create_catalog(&[(
"<div class=\"warning\">\n\
\n\
foo\n\
\n\
</div>",
"<div class=\"warning\">\n\
\n\
FOO\n\
\n\
</div>",
)]);
assert_normalized_messages_eq(catalog, &[exact("foo", "FOO")]);
}

#[test]
fn test_normalize_disappearing_html() {
// Normalizing "<b>" results in no messages.
Expand Down

0 comments on commit 2168b9c

Please sign in to comment.