mirror of
				https://codeberg.org/yeentown/barkey.git
				synced 2025-11-04 07:24:13 +00:00 
			
		
		
		
	handle more complex ruby from/to html - fixes #605
this is not exactly great, but it should be "good enough" note that the new `group` function should not escape in the wild, as we don't document it and only use it internally I tried using `$[scale foo bar]` instead of `$[group foo bar]`, but that would be rendered as `<i>foo bar</i>` when sent over the network to non-misskey instances, and we don't want that
This commit is contained in:
		
							parent
							
								
									42d8279610
								
							
						
					
					
						commit
						01a5300be8
					
				
					 3 changed files with 84 additions and 0 deletions
				
			
		| 
						 | 
				
			
			@ -230,6 +230,67 @@ export class MfmService {
 | 
			
		|||
					break;
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				case 'rp': break
 | 
			
		||||
				case 'rt': {
 | 
			
		||||
					appendChildren(node.childNodes);
 | 
			
		||||
					break;
 | 
			
		||||
				}
 | 
			
		||||
				case 'ruby': {
 | 
			
		||||
					if (node.childNodes) {
 | 
			
		||||
						/*
 | 
			
		||||
							we get:
 | 
			
		||||
							```
 | 
			
		||||
							<ruby>
 | 
			
		||||
							some text <rp>(</rp> <rt>annotation</rt> <rp>)</rp>
 | 
			
		||||
							more text <rt>more annotation<rt>
 | 
			
		||||
							</ruby>
 | 
			
		||||
							```
 | 
			
		||||
 | 
			
		||||
							and we want to produce:
 | 
			
		||||
							```
 | 
			
		||||
							$[ruby $[group some text] annotation]
 | 
			
		||||
							$[ruby $[group more text] more annotation]
 | 
			
		||||
							```
 | 
			
		||||
 | 
			
		||||
							that `group` is a hack, because when the `ruby` render
 | 
			
		||||
							sees just text inside the `$[ruby]`, it splits on
 | 
			
		||||
							whitespace, considers the first "word" to be the main
 | 
			
		||||
							content, and the rest the annotation
 | 
			
		||||
 | 
			
		||||
							with that `group`, we force it to consider the whole
 | 
			
		||||
							group as the main content
 | 
			
		||||
 | 
			
		||||
							(note that the `rp` are to be ignored, they only exist
 | 
			
		||||
							for browsers who don't understand ruby)
 | 
			
		||||
						*/
 | 
			
		||||
						let nonRtNodes=[];
 | 
			
		||||
						// scan children, ignore `rp`, split on `rt`
 | 
			
		||||
						for (const child of node.childNodes) {
 | 
			
		||||
							if (treeAdapter.isTextNode(child)) {
 | 
			
		||||
								nonRtNodes.push(child);
 | 
			
		||||
								continue;
 | 
			
		||||
							}
 | 
			
		||||
							if (!treeAdapter.isElementNode(child)) {
 | 
			
		||||
								continue;
 | 
			
		||||
							}
 | 
			
		||||
							if (child.nodeName == 'rp') {
 | 
			
		||||
								continue;
 | 
			
		||||
							}
 | 
			
		||||
							if (child.nodeName == 'rt') {
 | 
			
		||||
								text += '$[ruby $[group ';
 | 
			
		||||
								appendChildren(nonRtNodes);
 | 
			
		||||
								text += '] ';
 | 
			
		||||
								analyze(child);
 | 
			
		||||
								text += '] ';
 | 
			
		||||
								nonRtNodes=[];
 | 
			
		||||
								continue;
 | 
			
		||||
							}
 | 
			
		||||
							nonRtNodes.push(child);
 | 
			
		||||
						}
 | 
			
		||||
					}
 | 
			
		||||
					break;
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				default:	// includes inline elements
 | 
			
		||||
				{
 | 
			
		||||
					appendChildren(node.childNodes);
 | 
			
		||||
| 
						 | 
				
			
			@ -348,6 +409,12 @@ export class MfmService {
 | 
			
		|||
						}
 | 
			
		||||
					}
 | 
			
		||||
 | 
			
		||||
					case 'group': { // this is mostly a hack for `ruby`
 | 
			
		||||
						const el = doc.createElement('span');
 | 
			
		||||
						appendChildren(node.children, el);
 | 
			
		||||
						return el;
 | 
			
		||||
					}
 | 
			
		||||
 | 
			
		||||
					default: {
 | 
			
		||||
						return fnDefault(node);
 | 
			
		||||
					}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -45,6 +45,12 @@ describe('MfmService', () => {
 | 
			
		|||
			const output = '<p><pre><code><p>Hello, world!</p></code></pre></p>';
 | 
			
		||||
			assert.equal(mfmService.toHtml(mfm.parse(input)), output);
 | 
			
		||||
		});
 | 
			
		||||
 | 
			
		||||
		test('ruby', () => {
 | 
			
		||||
			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('fromHtml', () => {
 | 
			
		||||
| 
						 | 
				
			
			@ -115,5 +121,12 @@ describe('MfmService', () => {
 | 
			
		|||
		test('hashtag', () => {
 | 
			
		||||
			assert.deepStrictEqual(mfmService.fromHtml('<p>a <a href="https://example.com/tags/a">#a</a> d</p>', ['#a']), 'a #a d');
 | 
			
		||||
		});
 | 
			
		||||
 | 
			
		||||
		test('ruby', () => {
 | 
			
		||||
			assert.deepStrictEqual(
 | 
			
		||||
				mfmService.fromHtml('<ruby> <i>some</i> text <rp>(</rp><rt>ignore me</rt><rp>)</rp> and <rt>more</rt></ruby>'),
 | 
			
		||||
				'$[ruby $[group  <i>some</i> text ] ignore me] $[ruby $[group  and ] more]'
 | 
			
		||||
			);
 | 
			
		||||
		});
 | 
			
		||||
	});
 | 
			
		||||
});
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -358,6 +358,10 @@ export default function (props: MfmProps, { emit }: { emit: SetupContext<MfmEven
 | 
			
		|||
							return h('ruby', {}, [...genEl(token.children.slice(0, token.children.length - 1), scale), h('rt', text.trim())]);
 | 
			
		||||
						}
 | 
			
		||||
					}
 | 
			
		||||
					case 'group': { // this is mostly a hack for the insides of `ruby`
 | 
			
		||||
						style = '';
 | 
			
		||||
						break;
 | 
			
		||||
					}
 | 
			
		||||
					case 'unixtime': {
 | 
			
		||||
						const child = token.children[0];
 | 
			
		||||
						const unixtime = parseInt(child.type === 'text' ? child.props.text : '');
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		
		Reference in a new issue