From d018fe58aa91eb702b098df659f23f9a981f4368 Mon Sep 17 00:00:00 2001 From: "Hong Minhee (洪 民憙)" Date: Tue, 14 Jan 2025 22:06:39 +0900 Subject: fix(backend): Let MfmService.fromHtml accept ruby (#15117) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This fix makes `MfmService.fromHtml()` method accept `` tags and translate it to MFM's ruby characters syntax (`$[ruby ...]`). このパッチは`MfmService.fromHtml()`メソッドが``タグをMFMの 読み仮名(ルビ)文法に翻訳する様に修正します。 --- packages/backend/src/core/MfmService.ts | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) (limited to 'packages/backend/src/core/MfmService.ts') diff --git a/packages/backend/src/core/MfmService.ts b/packages/backend/src/core/MfmService.ts index 8061622340..bf06d4457e 100644 --- a/packages/backend/src/core/MfmService.ts +++ b/packages/backend/src/core/MfmService.ts @@ -171,6 +171,39 @@ export class MfmService { break; } + case 'ruby': { + let ruby: [string, string][] = []; + for (const child of node.childNodes) { + if (child.nodeName === 'rp') { + continue; + } + if (treeAdapter.isTextNode(child) && !/\s|\[|\]/.test(child.value)) { + ruby.push([child.value, '']); + continue; + } + if (child.nodeName === 'rt' && ruby.length > 0) { + const rt = getText(child); + if (/\s|\[|\]/.test(rt)) { + // If any space is included in rt, it is treated as a normal text + ruby = []; + appendChildren(node.childNodes); + break; + } else { + ruby.at(-1)![1] = rt; + continue; + } + } + // If any other element is included in ruby, it is treated as a normal text + ruby = []; + appendChildren(node.childNodes); + break; + } + for (const [base, rt] of ruby) { + text += `$[ruby ${base} ${rt}]`; + } + break; + } + // block code (
)
 				case 'pre': {
 					if (node.childNodes.length === 1 && node.childNodes[0].nodeName === 'code') {
-- 
cgit v1.2.3-freya


From d426e2a7ef5fae1f93769d2e53cfef248146f447 Mon Sep 17 00:00:00 2001
From: dakkar 
Date: Fri, 7 Feb 2025 18:20:36 +0000
Subject: fix our ruby/group hack

---
 packages/backend/src/core/MfmService.ts  | 17 +++++++++++++----
 packages/backend/test/unit/MfmService.ts | 10 +++++-----
 2 files changed, 18 insertions(+), 9 deletions(-)

(limited to 'packages/backend/src/core/MfmService.ts')

diff --git a/packages/backend/src/core/MfmService.ts b/packages/backend/src/core/MfmService.ts
index 2095ebca98..99adad3018 100644
--- a/packages/backend/src/core/MfmService.ts
+++ b/packages/backend/src/core/MfmService.ts
@@ -179,7 +179,8 @@ export class MfmService {
 					break;
 				}
 
-				case 'ruby': {
+					// this is here only to catch upstream changes!
+				case 'ruby--': {
 					let ruby: [string, string][] = [];
 					for (const child of node.childNodes) {
 						if (child.nodeName === 'rp') {
@@ -310,16 +311,24 @@ export class MfmService {
 								continue;
 							}
 							if (child.nodeName === 'rt') {
-								text += '$[ruby $[group ';
+								// the only case in which we don't need a `$[group ]`
+								// is when both sides of the ruby are simple words
+								const needsGroup = nonRtNodes.length > 1 ||
+									/\s|\[|\]/.test(getText(nonRtNodes[0])) ||
+									/\s|\[|\]/.test(getText(child)) ;
+								text += '$[ruby ';
+								if (needsGroup) text += '$[group ';
 								appendChildren(nonRtNodes);
-								text += '] ';
+								if (needsGroup) text += ']';
+								text += ' ';
 								analyze(child);
-								text += '] ';
+								text += ']';
 								nonRtNodes = [];
 								continue;
 							}
 							nonRtNodes.push(child);
 						}
+						appendChildren(nonRtNodes);
 					}
 					break;
 				}
diff --git a/packages/backend/test/unit/MfmService.ts b/packages/backend/test/unit/MfmService.ts
index d263aafa0f..e54c006a4f 100644
--- a/packages/backend/test/unit/MfmService.ts
+++ b/packages/backend/test/unit/MfmService.ts
@@ -158,16 +158,16 @@ describe('MfmService', () => {
 		});
 
 		test('ruby with spaces', () => {
-			assert.deepStrictEqual(mfmService.fromHtml('

a Miss key(ミスキー) b c

'), 'a Miss key(ミスキー) b c'); - assert.deepStrictEqual(mfmService.fromHtml('

a Misskey(ミス キー) b c

'), 'a Misskey(ミス キー) b c'); + assert.deepStrictEqual(mfmService.fromHtml('

a Miss key(ミスキー) b c

'), 'a $[ruby $[group Miss key] ミスキー] b c'); + assert.deepStrictEqual(mfmService.fromHtml('

a Misskey(ミス キー) b c

'), 'a $[ruby $[group Misskey] ミス キー] b c'); assert.deepStrictEqual( mfmService.fromHtml('

a Misskey(ミスキー)Misskey(ミス キー)Misskey(ミスキー) b

'), - 'a Misskey(ミスキー)Misskey(ミス キー)Misskey(ミスキー) b' + 'a $[ruby Misskey ミスキー]$[ruby $[group Misskey] ミス キー]$[ruby Misskey ミスキー] b' ); }); test('ruby with other inline tags', () => { - assert.deepStrictEqual(mfmService.fromHtml('

a Misskey(ミスキー) b c

'), 'a **Misskey**(ミスキー) b c'); + assert.deepStrictEqual(mfmService.fromHtml('

a Misskey(ミスキー) b c

'), 'a $[ruby **Misskey** ミスキー] b c'); }); test('mention', () => { @@ -181,7 +181,7 @@ describe('MfmService', () => { test('ruby', () => { assert.deepStrictEqual( mfmService.fromHtml(' some text (ignore me) and more'), - '$[ruby $[group some text ] ignore me] $[ruby $[group and ] more]' + '$[ruby $[group some text ] ignore me]$[ruby $[group and ] more]' ); }); }); -- cgit v1.2.3-freya From 09128ef399c8fc4f40c688617869bfbb4c3d526e Mon Sep 17 00:00:00 2001 From: dakkar Date: Fri, 7 Feb 2025 18:33:24 +0000 Subject: pick lints --- packages/backend/src/core/MfmService.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'packages/backend/src/core/MfmService.ts') diff --git a/packages/backend/src/core/MfmService.ts b/packages/backend/src/core/MfmService.ts index 99adad3018..6c2f673217 100644 --- a/packages/backend/src/core/MfmService.ts +++ b/packages/backend/src/core/MfmService.ts @@ -315,7 +315,7 @@ export class MfmService { // is when both sides of the ruby are simple words const needsGroup = nonRtNodes.length > 1 || /\s|\[|\]/.test(getText(nonRtNodes[0])) || - /\s|\[|\]/.test(getText(child)) ; + /\s|\[|\]/.test(getText(child)); text += '$[ruby '; if (needsGroup) text += '$[group '; appendChildren(nonRtNodes); -- cgit v1.2.3-freya