diff --git a/.changeset/eleven-otters-smoke.md b/.changeset/eleven-otters-smoke.md new file mode 100644 index 000000000..7219c16a1 --- /dev/null +++ b/.changeset/eleven-otters-smoke.md @@ -0,0 +1,5 @@ +--- +"lingo.dev": patch +--- + +split images into sections diff --git a/.changeset/violet-bulldogs-train.md b/.changeset/violet-bulldogs-train.md new file mode 100644 index 000000000..d8a892cd3 --- /dev/null +++ b/.changeset/violet-bulldogs-train.md @@ -0,0 +1,5 @@ +--- +"lingo.dev": patch +--- + +dates in mdx diff --git a/.prettierrc b/.prettierrc deleted file mode 100644 index 963354f23..000000000 --- a/.prettierrc +++ /dev/null @@ -1,3 +0,0 @@ -{ - "printWidth": 120 -} diff --git a/packages/cli/.prettierrc b/packages/cli/.prettierrc deleted file mode 100644 index 29f26b486..000000000 --- a/packages/cli/.prettierrc +++ /dev/null @@ -1,17 +0,0 @@ -{ - "tabWidth": 2, - "useTabs": false, - "trailingComma": "all", - "semi": true, - "printWidth": 80, - "endOfLine": "auto", - "proseWrap": "always", - "overrides": [ - { - "files": ["*.mdx"], - "options": { - "trailingComma": "none" - } - } - ] -} diff --git a/packages/cli/demo/mdx/de.mdx b/packages/cli/demo/mdx/de.mdx new file mode 100644 index 000000000..e69de29bb diff --git a/packages/cli/i18n.json b/packages/cli/i18n.json index 7c7711cbc..f2ecb3542 100644 --- a/packages/cli/i18n.json +++ b/packages/cli/i18n.json @@ -2,13 +2,8 @@ "version": 1.6, "locale": { "source": "en", - "targets": ["es"] - }, - "buckets": { - "mdx": { - "lockedKeys": ["meta/slug", "meta/category"], - "include": ["demo/mdx/[locale].mdx"] - } + "targets": ["de"] }, + "main": {}, "$schema": "https://lingo.dev/schema/i18n.json" } diff --git a/packages/cli/i18n.lock b/packages/cli/i18n.lock index f7e889a76..e69de29bb 100644 --- a/packages/cli/i18n.lock +++ b/packages/cli/i18n.lock @@ -1,32 +0,0 @@ -version: 1 -checksums: - 77624f597c2092ea61483d71313398c3: - meta/title: 0a2cc2035f59644733615dd8675b3618 - meta/summary: dd9c3e74401afb579e4668b11f11f2ab - meta/author: 5cc899158b9a4b8e2a6abaf26c498786 - content/0: 4dfc7a0ee6a9dc089d8a76ad27d38754 - content/1: 133929451ee05c91d68b75a15bfe6596 - content/2: c89b46f8b2f582e06111a6c96b82e8bf - content/3: 417995a6cdfb7ab127e5431b5b5ef720 - content/4: aa9c76dbf759c838e8bd62ae85825e52 - content/5: 5704f51f430cbaa8d6452b38c91ea485 - content/6: 8db8789e2a220825c9df6c3706bb8389 - content/7: 6278ebdd79f1ea718aabeb8e40b5f999 - content/8: 37ad0f04abb0e32b88e3bd6b79bb7110 - content/9: f3103fdf8e9bd164be82af6c84e17b81 - content/10: f030df31e8f24b9890bc9b7d7d387a69 - content/11: da348e7e947e0d6054f2b177abc6060b - content/12: 83e15bc1599d243ca5efee3bb6da3152 - content/13: 3c176fdcdcc855b44cb42da632312e73 - content/14: cecd264ec97755c0100c8bc7d5b0bd70 - content/15: 426e9e0abc16c001e04cfb03c9611a6b - content/16: a42f584c463c26a44c5c6d0f6cb8ace0 - content/17: e54125a6e2a6fea17309a2c8949e2490 - content/18: 79ef1a72bb4e09c347e3a0afae68c18d - content/19: 3feea98e670a946eefdd2fc48d7b99b5 - content/20: 51adf33450cab2ef392e93147386647c - content/21: 66ba09daf8e0ae94effa4b98f19ded22 - content/22: fed9e643c4a407e5fa118690285a85ed - content/23: 5975348444539ca25e20d05e53b87105 - content/24: 7f019348c6dd5d97e746f32741241c55 - content/25: 5678250e0f9cff6a5b71f42ff222bd2d diff --git a/packages/cli/src/cli/loaders/index.spec.ts b/packages/cli/src/cli/loaders/index.spec.ts index a8b2d9e83..7a9f8d093 100644 --- a/packages/cli/src/cli/loaders/index.spec.ts +++ b/packages/cli/src/cli/loaders/index.spec.ts @@ -294,7 +294,7 @@ describe("bucket loaders", () => { }); it("should save html data", async () => { - const input = ` + const input = dedent`
- Este es un párrafo con un - enlace - y - - texto en negrita y - texto en cursiva - -
- - + const expectedOutput = dedent` + +Este es un párrafo con un enlace y texto en negrita y texto en cursiva +
+ + `.trim(); mockFileOperations(input); @@ -437,7 +427,14 @@ describe("bucket loaders", () => { const input = { messages: ["foo", "bar"] }; const payload = { "messages/0": "foo", "messages/1": "bar" }; - const expectedOutput = `{\n "messages\": [\"foo\", \"bar\"]\n}`; + const expectedOutput = dedent` + { + "messages": [ + "foo", + "bar" + ] + } + `.trim(); mockFileOperations(JSON.stringify(input)); @@ -907,7 +904,7 @@ Another paragraph with **bold** and *italic* text.`; "md-section-0": "# Heading 1", "md-section-1": "This is a paragraph.", "md-section-2": "## Heading 2", - "md-section-3": "Another paragraph with **bold** and _italic_ text.", + "md-section-3": "Another paragraph with **bold** and *italic* text.", }; mockFileOperations(input); diff --git a/packages/cli/src/cli/loaders/index.ts b/packages/cli/src/cli/loaders/index.ts index 7ba7bfde7..9b95ea085 100644 --- a/packages/cli/src/cli/loaders/index.ts +++ b/packages/cli/src/cli/loaders/index.ts @@ -1,4 +1,5 @@ import Z from "zod"; +import jsdom from "jsdom"; import { bucketTypeSchema } from "@lingo.dev/_spec"; import { composeLoaders } from "./_utils"; import createJsonLoader from "./json"; diff --git a/packages/cli/src/cli/loaders/mdx2/code-placeholder.spec.ts b/packages/cli/src/cli/loaders/mdx2/code-placeholder.spec.ts index 211c5b62f..3f3eb71cf 100644 --- a/packages/cli/src/cli/loaders/mdx2/code-placeholder.spec.ts +++ b/packages/cli/src/cli/loaders/mdx2/code-placeholder.spec.ts @@ -267,6 +267,50 @@ describe("MDX Code Placeholder Loader", () => { expect(pushed).toBe(md); }); + it("round-trips an image block with surrounding blank lines unchanged", async () => { + const md = dedent` + Text above. + +  + + Text below. + `; + + const pulled = await loader.pull("en", md); + const pushed = await loader.push("es", pulled); + expect(pushed).toBe(md); + }); + + it("round-trips and adds blank lines around an image block when missing", async () => { + const md = dedent` + Text above. +  + Text below. + `; + + const expected = dedent` + Text above. + +  + + Text below. + `; + + const pulled = await loader.pull("en", md); + const pushed = await loader.push("es", pulled); + expect(pushed).toBe(expected); + }); + + it("keeps image inside blockquote as-is", async () => { + const md = dedent` + >  + `; + + const pulled = await loader.pull("en", md); + const pushed = await loader.push("es", pulled); + expect(pushed).toBe(md); + }); + it("leaves incomplete fences untouched", async () => { const md = "```js\nno close"; const pulled = await loader.pull("en", md); @@ -275,6 +319,87 @@ describe("MDX Code Placeholder Loader", () => { const pushed = await loader.push("es", pulled); expect(pushed).toBe(md); }); + + // Edge cases for image spacing + + it("adds blank line after image when only before exists", async () => { + const md = dedent` + Before. + +  + After. + `; + + const expected = dedent` + Before. + +  + + After. + `; + + const pulled = await loader.pull("en", md); + const pushed = await loader.push("es", pulled); + expect(pushed).toBe(expected); + }); + + it("adds blank line before image when only after exists", async () => { + const md = dedent` + Before. +  + + After. + `; + + const expected = dedent` + Before. + +  + + After. + `; + + const pulled = await loader.pull("en", md); + const pushed = await loader.push("es", pulled); + expect(pushed).toBe(expected); + }); + + it("inserts spacing between consecutive images", async () => { + const md = dedent` +  +  + `; + + const expected = dedent` +  + +  + `; + + const pulled = await loader.pull("en", md); + const pushed = await loader.push("es", pulled); + expect(pushed).toBe(expected); + }); + + it("handles image inside JSX component - adds blank lines", async () => { + const md = dedent` +