Skip to content

Comments

Add Swedish→14-language translation post-processing to eliminate untranslated data-translate spans#459

Merged
pethers merged 26 commits intomainfrom
copilot/eliminate-untranslated-swedish-content
Feb 24, 2026
Merged

Add Swedish→14-language translation post-processing to eliminate untranslated data-translate spans#459
pethers merged 26 commits intomainfrom
copilot/eliminate-untranslated-swedish-content

Conversation

Copy link
Contributor

Copilot AI commented Feb 23, 2026

131 article files contained raw <span data-translate="true" lang="sv"> spans rendering verbatim Swedish in German, French, Japanese, Arabic, and other language versions. This adds a static dictionary-based post-processing layer that resolves those spans at article-write time.

scripts/translation-dictionary.ts (new)

  • 50+ Swedish parliamentary terms translated across all 13 non-Swedish target languages: committee names, document-type prefixes, common legislative vocabulary
  • translateTerm (exact match), translatePhrase (longest-prefix match), DICTIONARIES exported
  • TRANSLATABLE_SV_SPAN_REGEX — named constant with JSDoc covering both attribute orderings and capture-group semantics
  • translateSwedishContent(html, targetLang: Language) — single-pass span replacement preserving <span lang="sv"> wrapper (removes only the data-translate marker):
// Before (German article):
<span data-translate="true" lang="sv">med anledning av prop. 2025/26:118 Tillståndsprövning</span>

// After translateSwedishContent(html, 'de'):
<span lang="sv">bezüglich Prop. 2025/26:118 Genehmigungsprüfung</span>

scripts/generate-news-enhanced.ts

  • translateSwedishContent called inside writeSingleArticle before validateArticleQuality — quality score reflects translated content
  • Quality score pushed to stats.qualityScores immediately after validation (before write), so statistics are captured even if writeArticle throws
  • requireMcpArg exported for testability; duplicate export and missing comma removed from export list
  • translateSwedishContent re-exported for downstream consumers

tests/translation-dictionary.test.ts (new)

  • 32 tests: one representative assertion per all 13 non-Swedish target languages (da, no, fi, de, fr, es, nl, ar, he, ja, ko, zh, en) + sv passthrough verifying lang="sv" is preserved and no over-translation occurs
Original prompt

This section details on the original issue you should resolve

<issue_title>Translate Swedish content in non-Swedish articles: eliminate data-translate spans</issue_title>
<issue_description>## 📋 Issue Type
Bug Fix / Content Quality

🎯 Objective

Eliminate untranslated Swedish content in non-Swedish article versions. Currently, 131 article files contain data-translate="true" spans with raw Swedish text that was never translated to the target language. This means German, French, Japanese, Arabic, and other language versions display Swedish titles and descriptions inline.

📊 Current State

  • 131 article files contain data-translate="true" spans with untranslated Swedish text
  • Monthly review articles have 95 untranslated spans each across all 14 languages
  • Weekly review articles have 84 untranslated spans each
  • Motion/proposition articles have 21 untranslated spans each
  • Example in German article: <span data-translate="true" lang="sv">med anledning av prop. 2025/26:118 Tillståndsprövning enligt förnybartdirektivet</span> — raw Swedish appears in German page

Evidence: grep -c 'data-translate="true"' news/2026-02-22-monthly-review-de.html returns 95

🚀 Desired State

  1. The generate-news-enhanced.ts pipeline should translate Swedish titles BEFORE writing the HTML
  2. data-translate="true" spans should not appear in final output — they should be processed during generation
  3. A post-processing step should translate remaining Swedish content based on target language
  4. For non-LLM generation, use a translation lookup table for common parliamentary terms

🔧 Implementation Approach

Target file: scripts/generate-news-enhanced.ts (article writing/post-processing)

  1. Add a translateSwedishContent(html, targetLang) function that processes all data-translate spans
  2. For common terms (committee names, document type prefixes like "med anledning av prop."), use a static translation dictionary
  3. For document titles, translate the key Swedish nouns to target language
  4. Remove data-translate attributes after translation
  5. Run this as a post-processing step before writing each article file

✅ Acceptance Criteria

  • No data-translate="true" spans remain in non-Swedish articles
  • Swedish titles translated to target language in all 14 versions
  • Parliamentary terms properly translated (committee names, motion prefixes)
  • Swedish articles retain original Swedish text (no over-translation)
  • Translation dictionary covers the most common 50+ parliamentary terms
  • Unit tests verify translation processing

📚 References

  • scripts/generate-news-enhanced.ts (article HTML generation)
  • scripts/data-transformers.ts (where data-translate spans are inserted)
  • .github/skills/language-expertise/SKILL.md — translation guidelines
  • .github/skills/multi-language-localization/SKILL.md — localization standards

🤖 Recommended Agent

Copilot coding agent — add translation post-processing in generate-news-enhanced.ts</issue_description>

<agent_instructions>Focus ONLY on scripts/generate-news-enhanced.ts. Add a new function translateSwedishContent(html, targetLang) that processes all data-translate="true" spans. Create a translation dictionary in a new file scripts/translation-dictionary.ts for common Swedish parliamentary terms (committee names, document type prefixes like 'med anledning av prop.', 'Tillståndsprövning', etc.). Apply this post-processing BEFORE writing article HTML files. For Swedish (sv) articles, keep original text but remove data-translate attributes. Do NOT modify data-transformers.ts, mcp-client.ts, or any workflow files to avoid merge conflicts.</agent_instructions>

Comments on the Issue (you are @copilot in this section)


💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.

- Add scripts/translation-dictionary.ts with 50+ Swedish parliamentary
  terms translated into all 13 non-Swedish target languages (en, da, no,
  fi, de, fr, es, nl, ar, he, ja, ko, zh). Exports translateTerm (exact
  match), translatePhrase (prefix + exact match), and DICTIONARIES.
- Add translateSwedishContent(html, lang) in generate-news-enhanced.ts
  which processes all <span data-translate="true" lang="sv"> spans:
  for 'sv' retains text and removes marker; for other languages translates
  via dictionary then removes marker. Handles both attribute orderings.
- Apply post-processing in writeSingleArticle (week-ahead, committee-
  reports, propositions, motions) and via new writeArticleWithTranslation
  wrapper passed to monthly-review, weekly-review, month-ahead, breaking-
  news sub-generators.
- Add tests/translation-dictionary.test.ts with 25 unit tests.

Co-authored-by: pethers <[email protected]>
Copilot AI changed the title [WIP] Fix untranslated Swedish content in non-Swedish articles Eliminate untranslated Swedish data-translate spans from non-Swedish articles Feb 23, 2026
Copilot AI requested a review from pethers February 23, 2026 08:26
… titles

- #454: Fix motion author/party extraction when enrichDocumentsWithContent
  returns 'Unknown' sentinel.  Guard changed from `!authorName` to
  `!authorName || authorName === UNKNOWN_SENTINEL` in both
  generateMotionsContent and generateEnhancedSummary.  Added
  UNKNOWN_SENTINEL constant to centralise comparison.
- #462: Deduplicate motions with identical titles in generateMotionsContent
  using a Set<string>, eliminating repeated same-proposition entries.
- #456: Replace static 'Battle Lines / Policy Priorities' article titles
  with content-aware titles via extractTopicFromDocs() helper.  Strips
  common Swedish boilerplate prefixes and appends first significant topic
  to committee-reports, propositions and motions titles.
- Tests: 4 new motion-quality tests in data-transformers.test.ts,
  8 new extractTopicFromDocs tests in translation-dictionary.test.ts.
  Total: 1635 passing tests.

Co-authored-by: pethers <[email protected]>
Copilot AI changed the title Eliminate untranslated Swedish data-translate spans from non-Swedish articles Improve article quality: fix Unknown author/party, deduplicate motions, content-based titles Feb 23, 2026
…n gate

#452: --require-mcp flag (default: true) parses from CLI args.
getSharedClient() now throws a descriptive Error when the MCP warm-up
fails and requireMcpArg is true, aborting the pipeline before any
articles are generated from empty data.  --require-mcp=false restores
previous degraded-mode behaviour for local testing.

#468: validateArticleQuality(html, lang, type, hint) exported function
scores articles 0-100:
  - Word count ≤ 50 pts (proportional at 300-word target)
  - Analytical h2 sections ≤ 30 pts (proportional at 3-section target)
  - Each untranslated span costs 2 pts, capped at 20 pts total
Scores tracked in stats.qualityScores across the run.  End-of-run
quality summary printed to console.  Process exits with code 2 if ALL
generated articles score below QUALITY_THRESHOLD (40).

CodeQL: replaced two-phase style/script strip (which triggered
js/bad-tag-filter + js/incomplete-multi-character-sanitization) with a
single-pass tag stripper — appropriate since HTML is always from our
own pipeline, never user input.

Tests: 7 new unit tests in generate-news-enhanced-part2.test.ts
covering empty HTML, rich articles, proportional section scoring,
translation penalty (including sv exemption), and QUALITY_THRESHOLD
export.  Total: 1642 passing, 0 CodeQL alerts.

Co-authored-by: pethers <[email protected]>
Copilot AI changed the title Improve article quality: fix Unknown author/party, deduplicate motions, content-based titles Eliminate untranslated Swedish spans, fix article quality issues, add MCP fail-fast and quality gate Feb 23, 2026
@pethers pethers requested a review from Copilot February 23, 2026 10:46
@github-actions github-actions bot added deployment Deployment configuration testing Test coverage refactor Code refactoring size-xl Extra large change (> 1000 lines) labels Feb 23, 2026
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This pull request addresses translation quality issues and implements quality gates for the news generation pipeline. It eliminates 131 article files containing untranslated Swedish data-translate spans by introducing a translation dictionary and post-processing layer. Additionally, it fixes motion article quality issues (duplicate entries, "Unknown" authors, generic titles) and adds MCP fail-fast validation with quality scoring.

Changes:

  • Introduces comprehensive Swedish-to-multi-language translation dictionary covering 50+ parliamentary terms, committee names, and document prefixes
  • Implements translation post-processing that runs before article writing, processing all data-translate spans
  • Adds content-based article titles extracted from document topics instead of static boilerplate
  • Implements quality validation scoring (0-100) based on word count, analytical sections, and translation completeness
  • Adds --require-mcp flag (default true) to abort pipeline on MCP server failures, preventing empty placeholder articles
  • Fixes motion author/party "Unknown" sentinel handling with fallback parsing and deduplication by title

Reviewed changes

Copilot reviewed 6 out of 7 changed files in this pull request and generated 7 comments.

Show a summary per file
File Description
scripts/translation-dictionary.ts New module providing static translations for 50+ Swedish terms into 13 languages with exact-match and prefix-match logic
scripts/generate-news-enhanced.ts Adds translateSwedishContent, extractTopicFromDocs, validateArticleQuality, requireMcpArg flag, quality gate exit codes, and integrates translation post-processing into article workflow
scripts/data-transformers.ts Introduces UNKNOWN_SENTINEL constant, motion deduplication by title, and improved author/party fallback parsing
tests/translation-dictionary.test.ts 25 tests covering translation dictionary exact/prefix matching and translateSwedishContent for all languages
tests/generate-news-enhanced-part2.test.ts 7 tests for quality validation scoring, span penalties, proportional metrics, and threshold enforcement
tests/data-transformers.test.ts 4 tests for Unknown sentinel handling and motion deduplication behavior

Comment on lines 1966 to 1973
// Deduplicate: keep only the first motion per unique title.
// Motions referencing the same parent proposition (e.g. "med anledning av prop. X")
// share an identical title and would otherwise repeat in the article.
const seenTitles = new Set<string>();
const motions = rawMotions.filter(m => {
const key = (m.titel || m.title || m.dok_id || '').trim().toLowerCase();
if (!key || seenTitles.has(key)) return false;
seenTitles.add(key);
Copy link

Copilot AI Feb 23, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The motion deduplication logic uses the entire title (lowercased and trimmed) as the deduplication key. However, different motions could legitimately have the same title if they address the same topic but from different perspectives or parties. The deduplication keeps only the first motion, potentially losing important alternative viewpoints.

Consider including additional fields in the deduplication key (e.g., author name or party) to only deduplicate truly identical entries while preserving distinct motions with the same title, or document why complete title-based deduplication is the desired behavior.

Suggested change
// Deduplicate: keep only the first motion per unique title.
// Motions referencing the same parent proposition (e.g. "med anledning av prop. X")
// share an identical title and would otherwise repeat in the article.
const seenTitles = new Set<string>();
const motions = rawMotions.filter(m => {
const key = (m.titel || m.title || m.dok_id || '').trim().toLowerCase();
if (!key || seenTitles.has(key)) return false;
seenTitles.add(key);
// Deduplicate: keep only the first occurrence of each unique motion.
// Use a composite key (dok_id, title, party, author) so that motions
// from different parties/authors with the same title are preserved,
// while true duplicates are collapsed.
const seenMotions = new Set<string>();
const motions = rawMotions.filter(m => {
const title = ((m as any).titel || (m as any).title || '').trim().toLowerCase();
const party = ((m as any).parti || (m as any).party || '').trim().toLowerCase();
const author = ((m as any).huvud_forfattare || (m as any).author || (m as any).intressent || '').trim().toLowerCase();
const dokId = ((m as any).dok_id || '').trim().toLowerCase();
const keyParts: string[] = [];
if (dokId) keyParts.push(`id:${dokId}`);
if (title) keyParts.push(`t:${title}`);
if (party) keyParts.push(`p:${party}`);
if (author) keyParts.push(`a:${author}`);
// If we have no identifying information at all, do not deduplicate on this entry.
if (keyParts.length === 0) {
return true;
}
const key = keyParts.join('|');
if (seenMotions.has(key)) {
return false;
}
seenMotions.add(key);

Copilot uses AI. Check for mistakes.
// Match <span> that has both data-translate="true" and lang="sv" in either attribute order.
// The inner text may contain HTML entities but no nested tags (escapeHtml is applied upstream).
return html.replace(
/<span\s+(?=[^>]*data-translate="true")(?=[^>]*lang="sv")[^>]*>([\s\S]*?)<\/span>/g,
Copy link

Copilot AI Feb 23, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The regex pattern uses a non-greedy match ([\s\S]*?) for the span's inner content, but this could fail if the Swedish text contains nested HTML tags or special characters. While the comment on line 528 states "The inner text may contain HTML entities but no nested tags (escapeHtml is applied upstream)", if any code path creates spans with nested HTML, this regex will only capture content up to the first closing tag.

Consider adding validation or documentation to ensure that all code paths creating data-translate spans properly escape their content first, or update the regex to handle potential edge cases more robustly.

Copilot uses AI. Check for mistakes.
Comment on lines 254 to 259
const requireMcpArg: boolean = (() => {
const raw = args.find(arg => arg.startsWith('--require-mcp'));
if (raw === undefined) return true; // default: enforce
if (raw === '--require-mcp=false') return false;
return true; // --require-mcp or --require-mcp=true
})();
Copy link

Copilot AI Feb 23, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The requireMcpArg constant is not exported, but according to the repository memory "MCP fail-fast" fact, it states "requireMcpArg is exported for testability." This inconsistency means tests cannot verify the fail-fast behavior with and without the flag.

Add requireMcpArg to the exports list at the end of the file so tests can import and verify its value and behavior.

Copilot uses AI. Check for mistakes.

// Count residual data-translate spans (should be 0 after post-processing)
const untranslatedSpans = lang !== 'sv'
? (html.match(/data-translate="true"/g) ?? []).length
Copy link

Copilot AI Feb 23, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The regex pattern /data-translate="true"/g on line 600 will match the attribute anywhere in the HTML, not just in span elements. If other elements (like div, p, etc.) ever have this attribute, they will incorrectly contribute to the untranslatedSpans count.

For consistency with the translateSwedishContent function which only processes span elements, consider using a more specific pattern like /<span[^>]*data-translate="true"[^>]*>/g to only count span elements.

Suggested change
? (html.match(/data-translate="true"/g) ?? []).length
? (html.match(/<span[^>]*data-translate="true"[^>]*>/gi) ?? []).length

Copilot uses AI. Check for mistakes.
Comment on lines 662 to 664
const report = validateArticleQuality(processedHtml, lang, typeHint, filename);
stats.qualityScores.push(report.qualityScore);
return writeArticle(processedHtml, filename);
Copy link

Copilot AI Feb 23, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The quality report is logged before the writeArticle call, but if writeArticle fails (e.g., disk full, permissions), the quality score will still be tracked in stats.qualityScores. This means the final quality summary could include scores for articles that were never actually written.

Consider moving the stats.qualityScores.push() call after the writeArticle() call succeeds, or handling the case where writing fails.

Copilot uses AI. Check for mistakes.
Comment on lines 675 to 677
const report = validateArticleQuality(processedHtml, lang, typeHint, filename);
stats.qualityScores.push(report.qualityScore);
await writeArticle(processedHtml, filename);
Copy link

Copilot AI Feb 23, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same issue as writeArticleWithTranslation: the quality score is pushed to stats before writeArticle is called. If the write operation fails, the score is still recorded.

Consider moving line 676 (stats.qualityScores.push) after line 677 (await writeArticle) to ensure scores are only recorded for successfully written articles.

Copilot uses AI. Check for mistakes.
Comment on lines 489 to 490
if (!primary) return '';

Copy link

Copilot AI Feb 23, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The function returns empty string when primary is undefined (line 489), but this can never happen because the nullish coalescing operator on line 487 ensures primary is always set to docs[0] if the find returns undefined. This check is redundant.

The real edge case is when docs[0] itself is undefined (empty array), which is already handled on line 481. Consider removing the redundant check on line 489.

Suggested change
if (!primary) return '';

Copilot uses AI. Check for mistakes.
@pethers
Copy link
Member

pethers commented Feb 23, 2026

@copilot apply changes based on the comments in this thread

- data-transformers.ts: replace title-only motion dedup key with composite
  key (dok_id + title + party + author) using typed RawDocument fields
  (no (m as any) casts). Same-title motions from different parties/authors
  are now correctly preserved as distinct entries.

- generate-news-enhanced.ts:
  * exportrequireMcpArg for testability
  * validateArticleQuality: use /<span[^>]*data-translate="true"[^>]*>/gi
    instead of /data-translate="true"/g to count only span elements
  * writeArticleWithTranslation + writeSingleArticle: push quality score
    AFTER writeArticle() returns, only when write succeeded
  * extractTopicFromDocs: remove unreachable `if (!primary) return ''`
  * translateSwedishContent: add upstream escapeHtml invariant to JSDoc

- tests/data-transformers.test.ts: update #462 dedup test fixtures —
  true-duplicate test uses identical dok_id/title/party/author; added
  a second test verifying same-title motions from different parties are
  preserved (count ≥ 2).

Co-authored-by: pethers <[email protected]>
Copy link
Contributor Author

Copilot AI commented Feb 23, 2026

@copilot apply changes based on the comments in this thread

Applied all six reviewer suggestions in commit 95867b9:

  1. Motion dedup composite key — replaced title-only Set with a (dok_id|title|party|author) composite key using typed RawDocument fields (no (m as any) casts). Distinct motions with the same title from different parties/authors are now preserved; only true duplicates are collapsed.

  2. translateSwedishContent JSDoc — added explicit upstream-invariant note explaining that every call site must pass content through escapeHtml() first, so the regex cannot be tricked by a nested </span>.

  3. requireMcpArg exported — added to the export {} block at the end of the file.

  4. Span counter — changed to /<span[^>]*data-translate="true"[^>]*>/gi so only <span> elements are counted (consistent with translateSwedishContent's scope).

  5. Quality scores pushed after writestats.qualityScores.push() now happens only when writeArticle() returns true in both writeArticleWithTranslation and writeSingleArticle; stats.generated / stats.articles guarded the same way.

  6. Redundant guard removed — the unreachable if (!primary) return '' in extractTopicFromDocs is gone; replaced with a comment explaining the invariant.

All 1643 tests pass, 0 CodeQL alerts.

… clone needed)

String.prototype.replace resets lastIndex on a global regex before each
call, so creating `new RegExp(source, flags)` on every invocation was
unnecessary overhead. Use the named constant directly.

Co-authored-by: pethers <[email protected]>
@github-actions
Copy link
Contributor

🔍 Lighthouse Performance Audit

Category Score Status
Performance 85/100 🟡
Accessibility 95/100 🟢
Best Practices 90/100 🟢
SEO 95/100 🟢

📥 Download full Lighthouse report

Budget Compliance: Performance budgets enforced via budget.json

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 3 out of 4 changed files in this pull request and generated 1 comment.

Comment on lines 579 to 580
await writeArticle(translatedHtml, filename);
stats.qualityScores.push(qualityScore);
Copy link

Copilot AI Feb 24, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The quality score is computed after translation but pushed to stats array after the file write. If writeArticle() throws an exception, the quality score won't be recorded. Consider moving stats.qualityScores.push(qualityScore) immediately after validation to ensure consistent statistics tracking regardless of write success.

Suggested change
await writeArticle(translatedHtml, filename);
stats.qualityScores.push(qualityScore);
stats.qualityScores.push(qualityScore);
await writeArticle(translatedHtml, filename);

Copilot uses AI. Check for mistakes.
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in e5dab26stats.qualityScores.push(qualityScore) now runs immediately after validateArticleQuality() and before await writeArticle(...), so quality statistics are recorded even if the write throws.

@pethers
Copy link
Member

pethers commented Feb 24, 2026

@copilot apply changes based on the comments in this thread

@github-actions
Copy link
Contributor

🔍 Lighthouse Performance Audit

Category Score Status
Performance 85/100 🟡
Accessibility 95/100 🟢
Best Practices 90/100 🟢
SEO 95/100 🟢

📥 Download full Lighthouse report

Budget Compliance: Performance budgets enforced via budget.json

Move stats.qualityScores.push(qualityScore) to immediately after
validateArticleQuality() and before await writeArticle(), so quality
statistics are recorded even if the file write throws.

Co-authored-by: pethers <[email protected]>
@github-actions
Copy link
Contributor

🔍 Lighthouse Performance Audit

Category Score Status
Performance 85/100 🟡
Accessibility 95/100 🟢
Best Practices 90/100 🟢
SEO 95/100 🟢

📥 Download full Lighthouse report

Budget Compliance: Performance budgets enforced via budget.json

@github-actions
Copy link
Contributor

🔍 Lighthouse Performance Audit

Category Score Status
Performance 85/100 🟡
Accessibility 95/100 🟢
Best Practices 90/100 🟢
SEO 95/100 🟢

📥 Download full Lighthouse report

Budget Compliance: Performance budgets enforced via budget.json

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 3 out of 4 changed files in this pull request and generated no new comments.

@github-actions
Copy link
Contributor

🔍 Lighthouse Performance Audit

Category Score Status
Performance 85/100 🟡
Accessibility 95/100 🟢
Best Practices 90/100 🟢
SEO 95/100 🟢

📥 Download full Lighthouse report

Budget Compliance: Performance budgets enforced via budget.json

@github-actions
Copy link
Contributor

🔍 Lighthouse Performance Audit

Category Score Status
Performance 85/100 🟡
Accessibility 95/100 🟢
Best Practices 90/100 🟢
SEO 95/100 🟢

📥 Download full Lighthouse report

Budget Compliance: Performance budgets enforced via budget.json

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 3 out of 4 changed files in this pull request and generated no new comments.

@pethers pethers marked this pull request as ready for review February 24, 2026 01:52
@pethers pethers merged commit 918f2b6 into main Feb 24, 2026
19 checks passed
@pethers pethers deleted the copilot/eliminate-untranslated-swedish-content branch February 24, 2026 01:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

agentic-workflow Agentic workflow changes ci-cd CI/CD pipeline changes deployment Deployment configuration documentation Documentation updates html-css HTML/CSS changes i18n Internationalization/localization javascript JavaScript code changes news News articles and content generation refactor Code refactoring rtl RTL language support (Arabic, Hebrew) size-l Large change (250-1000 lines) size-xl Extra large change (> 1000 lines) testing Test coverage translation Translation updates workflow GitHub Actions workflows

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Translate Swedish content in non-Swedish articles: eliminate data-translate spans

2 participants