diff --git a/scripts/docs-i18n/doc_chunked_raw.go b/scripts/docs-i18n/doc_chunked_raw.go index 3d5f56284ea0..574486bcab13 100644 --- a/scripts/docs-i18n/doc_chunked_raw.go +++ b/scripts/docs-i18n/doc_chunked_raw.go @@ -164,6 +164,7 @@ func translateDocBlockGroup(ctx context.Context, translator docsTranslator, chun translated = normalizeMaskedListMarkerSpacing(source, translated, listPlaceholders) translated = escapeUnexpectedListItemBodyMarkers(source, translated, listPlaceholders) translated = escapeUnexpectedMarkdownListMarkers(translated, listPlaceholders) + translated = unwrapUnexpectedInlineCodeSpans(source, translated) if validationErr := validateDocChunkTranslation(source, translated); validationErr == nil { log.Printf("docs-i18n: chunk done %s out_bytes=%d", chunkID, len(translated)) return translated, nil @@ -217,6 +218,7 @@ func translateDocLeafBlock(ctx context.Context, translator docsTranslator, chunk translated = normalizeMaskedListMarkerSpacing(source, translated, listPlaceholders) translated = escapeUnexpectedListItemBodyMarkers(source, translated, listPlaceholders) translated = escapeUnexpectedMarkdownListMarkers(translated, listPlaceholders) + translated = unwrapUnexpectedInlineCodeSpans(source, translated) if validationErr := validateDocChunkTranslation(source, translated); validationErr != nil { return "", validationErr } diff --git a/scripts/docs-i18n/doc_mode_test.go b/scripts/docs-i18n/doc_mode_test.go index 72fe808a2d53..355135d1e966 100644 --- a/scripts/docs-i18n/doc_mode_test.go +++ b/scripts/docs-i18n/doc_mode_test.go @@ -891,6 +891,30 @@ func TestValidateDocChunkTranslationAcceptsReorderedInlineCode(t *testing.T) { } } +func TestUnwrapUnexpectedInlineCodeSpans(t *testing.T) { + t.Parallel() + + source := "Use labels in ordinary prose.\n" + translated := "Verwende `Bezeichnungen` in `normalem Text`.\n" + want := "Verwende Bezeichnungen in normalem Text.\n" + if got := unwrapUnexpectedInlineCodeSpans(source, translated); got != want { + t.Fatalf("unexpected inline-code repair:\n%s\nwant:\n%s", got, want) + } + if err := validateDocChunkTranslation(source, want); err != nil { + t.Fatalf("expected repaired translation to validate: %v", err) + } +} + +func TestUnwrapUnexpectedInlineCodeSpansPreservesSourceCodeContract(t *testing.T) { + t.Parallel() + + source := "Use `--source`.\n" + translated := "Verwende `--target`.\n" + if got := unwrapUnexpectedInlineCodeSpans(source, translated); got != translated { + t.Fatalf("expected source inline-code contract to remain untouched: %q", got) + } +} + func TestMaskMarkdownDocSyntaxPreservesCanonicalNestedBackticks(t *testing.T) { t.Parallel() diff --git a/scripts/docs-i18n/markdown_segments.go b/scripts/docs-i18n/markdown_segments.go index f5eea18b6c3a..3348ba8b6e2f 100644 --- a/scripts/docs-i18n/markdown_segments.go +++ b/scripts/docs-i18n/markdown_segments.go @@ -203,6 +203,29 @@ func extractMarkdownInlineCodeValues(body string) []string { return values } +func unwrapUnexpectedInlineCodeSpans(source, translated string) string { + if len(extractMarkdownInlineCodeValues(source)) != 0 || len(extractMarkdownInlineCodeValues(translated)) == 0 { + return translated + } + fenced := append(markdownFencedCodeRanges(translated), markdownClosedLiteralFenceByteRanges(translated)...) + ranges := markdownBlockBacktickRanges(translated) + for index := len(ranges) - 1; index >= 0; index-- { + span := ranges[index] + if rangeOverlapsAny(span, fenced) { + continue + } + runLength := 0 + for span[0]+runLength < span[1] && translated[span[0]+runLength] == '`' { + runLength++ + } + if runLength == 0 || span[1]-runLength < span[0]+runLength { + continue + } + translated = translated[:span[0]] + translated[span[0]+runLength:span[1]-runLength] + translated[span[1]:] + } + return translated +} + func extractMarkdownFencedLiteralValues(body string) ([]string, []string, []string) { placeholders := []string{} directiveTokens := []string{}