summaryrefslogtreecommitdiff
path: root/packages/backend
diff options
context:
space:
mode:
authordakkar <dakkar@thenautilus.net>2025-01-19 11:15:01 +0000
committerdakkar <dakkar@thenautilus.net>2025-01-19 11:16:00 +0000
commit408e2f824a686defd3ea96cc5782b6b59779b7b9 (patch)
treefc7e11cb8421b1ac0577eabb745510745b8d7a22 /packages/backend
parentpick lints (diff)
downloadsharkey-408e2f824a686defd3ea96cc5782b6b59779b7b9.tar.gz
sharkey-408e2f824a686defd3ea96cc5782b6b59779b7b9.tar.bz2
sharkey-408e2f824a686defd3ea96cc5782b6b59779b7b9.zip
format ruby for masto api
Diffstat (limited to 'packages/backend')
-rw-r--r--packages/backend/src/core/MfmService.ts68
-rw-r--r--packages/backend/test/unit/MfmService.ts38
2 files changed, 100 insertions, 6 deletions
diff --git a/packages/backend/src/core/MfmService.ts b/packages/backend/src/core/MfmService.ts
index bc624daaee..dc47e38562 100644
--- a/packages/backend/src/core/MfmService.ts
+++ b/packages/backend/src/core/MfmService.ts
@@ -409,7 +409,9 @@ export class MfmService {
}
}
- case 'group': { // this is mostly a hack for `ruby`
+ // hack for ruby, should never be needed because we should
+ // never send this out to other instances
+ case 'group': {
const el = doc.createElement('span');
appendChildren(node.children, el);
return el;
@@ -593,11 +595,65 @@ export class MfmService {
},
async fn(node) {
- const el = doc.createElement('span');
- el.textContent = '*';
- await appendChildren(node.children, el);
- el.textContent += '*';
- return el;
+ switch (node.props.name) {
+ case 'group': { // hack for ruby
+ const el = doc.createElement('span');
+ await appendChildren(node.children, el);
+ return el;
+ }
+ case 'ruby': {
+ if (node.children.length === 1) {
+ const child = node.children[0];
+ const text = child.type === 'text' ? child.props.text : '';
+ const rubyEl = doc.createElement('ruby');
+ const rtEl = doc.createElement('rt');
+
+ const rpStartEl = doc.createElement('rp');
+ rpStartEl.appendChild(doc.createTextNode('('));
+ const rpEndEl = doc.createElement('rp');
+ rpEndEl.appendChild(doc.createTextNode(')'));
+
+ rubyEl.appendChild(doc.createTextNode(text.split(' ')[0]));
+ rtEl.appendChild(doc.createTextNode(text.split(' ')[1]));
+ rubyEl.appendChild(rpStartEl);
+ rubyEl.appendChild(rtEl);
+ rubyEl.appendChild(rpEndEl);
+ return rubyEl;
+ } else {
+ const rt = node.children.at(-1);
+
+ if (!rt) {
+ const el = doc.createElement('span');
+ await appendChildren(node.children, el);
+ return el;
+ }
+
+ const text = rt.type === 'text' ? rt.props.text : '';
+ const rubyEl = doc.createElement('ruby');
+ const rtEl = doc.createElement('rt');
+
+ const rpStartEl = doc.createElement('rp');
+ rpStartEl.appendChild(doc.createTextNode('('));
+ const rpEndEl = doc.createElement('rp');
+ rpEndEl.appendChild(doc.createTextNode(')'));
+
+ await appendChildren(node.children.slice(0, node.children.length - 1), rubyEl);
+ rtEl.appendChild(doc.createTextNode(text.trim()));
+ rubyEl.appendChild(rpStartEl);
+ rubyEl.appendChild(rtEl);
+ rubyEl.appendChild(rpEndEl);
+ return rubyEl;
+ }
+ }
+
+ default: {
+ const el = doc.createElement('span');
+ el.textContent = '*';
+ await appendChildren(node.children, el);
+ el.textContent += '*';
+ return el;
+ }
+ }
},
blockCode(node) {
diff --git a/packages/backend/test/unit/MfmService.ts b/packages/backend/test/unit/MfmService.ts
index 93ce0672dc..5c3ffba422 100644
--- a/packages/backend/test/unit/MfmService.ts
+++ b/packages/backend/test/unit/MfmService.ts
@@ -47,12 +47,50 @@ describe('MfmService', () => {
});
test('ruby', () => {
+ const input = '$[ruby some text ignore me]';
+ const output = '<p><ruby>some<rp>(</rp><rt>text</rt><rp>)</rp></ruby></p>';
+ assert.equal(mfmService.toHtml(mfm.parse(input)), output);
+ });
+
+ test('ruby2', () => {
+ const input = '$[ruby *some text* ignore me]';
+ const output = '<p><ruby><i>some text</i><rp>(</rp><rt>ignore me</rt><rp>)</rp></ruby></p>';
+ assert.equal(mfmService.toHtml(mfm.parse(input)), output);
+ });
+
+ test('ruby 3', () => {
const input = '$[ruby $[group *some* text] ignore me]';
const output = '<p><ruby><span><i>some</i> text</span><rp>(</rp><rt>ignore me</rt><rp>)</rp></ruby></p>';
assert.equal(mfmService.toHtml(mfm.parse(input)), output);
});
});
+ describe('toMastoApiHtml', () => {
+ test('br', async () => {
+ const input = 'foo\nbar\nbaz';
+ const output = '<p><span>foo<br>bar<br>baz</span></p>';
+ assert.equal(await mfmService.toMastoApiHtml(mfm.parse(input)), output);
+ });
+
+ test('br alt', async () => {
+ const input = 'foo\r\nbar\rbaz';
+ const output = '<p><span>foo<br>bar<br>baz</span></p>';
+ assert.equal(await mfmService.toMastoApiHtml(mfm.parse(input)), output);
+ });
+
+ test('escape', async () => {
+ const input = '```\n<p>Hello, world!</p>\n```';
+ const output = '<p><pre><code>&lt;p&gt;Hello, world!&lt;/p&gt;</code></pre></p>';
+ assert.equal(await mfmService.toMastoApiHtml(mfm.parse(input)), output);
+ });
+
+ test('ruby', async () => {
+ const input = '$[ruby $[group *some* text] ignore me]';
+ const output = '<p><ruby><span><span>*some*</span><span> text</span></span><rp>(</rp><rt>ignore me</rt><rp>)</rp></ruby></p>';
+ assert.equal(await mfmService.toMastoApiHtml(mfm.parse(input)), output);
+ });
+ });
+
describe('fromHtml', () => {
test('p', () => {
assert.deepStrictEqual(mfmService.fromHtml('<p>a</p><p>b</p>'), 'a\n\nb');