Adam S.
Adam S.

Reputation: 193

How to Use html <ruby> tags in Swift 4 for Japanese Characters

I need to use html tags for Japanese characters in Swift.

I've been using the following string extension below:

extension String{
func convertHtml() -> NSAttributedString{
    guard let data = data(using: .utf8) else { return NSAttributedString() }
    do{
        return try NSAttributedString(data: data, options: [.documentType: NSAttributedString.DocumentType.html, .characterEncoding: String.Encoding.utf8.rawValue], documentAttributes: nil)
    }catch{
        return NSAttributedString()
    }
}

And then testing it out with a textView as follows:

textView.attributedText = "<!DOCTYPE html><html><body>これは<ruby>日<rt>に</rt>本<rt>ほん</rt>語<rt>ご</rt></ruby>です。</body></html>".convertHtml()

This is how it should actually look:

これは<ruby>日<rt>に</rt>本<rt>ほん</rt>語<rt>ご</rt></ruby>です。

But it ends up looking like this. It doesn't line up properly, and there is a strange line break after every single use of the ruby tag.

enter image description here

Is there something I'm doing wrong here, and a way to fix this?

Thank you!

Upvotes: 2

Views: 1511

Answers (2)

MysticWhiteDragon
MysticWhiteDragon

Reputation: 71

Here's an easy way which I use.

<html>
<head>
<meta charset="UTF-8">
<title></title>
<style>
fg:before {
	content: attr(t);
	display: block;
    font-size: 50%;
    text-align: start;
	line-height: 1.5;
}

fg {
	display: inline-block;
	text-indent: 0px;
	line-height: normal;
    -webkit-text-emphasis: none;
	text-align: center;
	line-height: 1;
}
</style>
</head>
<body>
<fg t="わたし">私</fg>はケンです。<br><br>
</body>
</html>

See if that might work. It works fine for me in all the browsers I tested.

Upvotes: 0

Jamie Birch
Jamie Birch

Reputation: 6112

The whole line of Japanese text should be enclosed in <ruby> tags. This is because the <ruby> element sets up its own inline context, yet its sub-elements such as <rb>, <rt>, <rp>, and <rtc> also set up their own contexts like 'block' that only really make sense when the whole line is enclosed in a <ruby> element.

<!DOCTYPE html>
<html>
    <head>
        <!-- In case you'd like to try opening this page in desktop Safari! -->
        <meta charset="UTF-8">
    </head>
    <body>
        <ruby>
            <rb>これ</rb><rt></rt>
            <rb>は</rb><rt></rt>
            <rb>日</rb><rt>に</rt>
            <rb>本</rb><rt>ほん</rt>
            <rb>語</rb><rt>ご</rt>
            <rb>です</rb><rt></rt>
            <rb>。</rb><rt></rt>
        </ruby>
        <span>But this <em>isn't</em> Japanese.</span>
    </body>
</html>

I find it's best to be explicit about every <ruby> sub-element, and to also pair every <rb> (ruby base text) with a corresponding <rt> (ruby transcription). Sure, it looks more redundant and less clean, but it's a lot more semantic and you can be sure it's going to look the same in all browsers.

Edit showing that HTML is valid

Below, I provide a screenshot of it working. Here's how I invoked it:

let webView: WKWebView = WKWebView(frame: self.view.frame, configuration: WKWebViewConfiguration())

webView.loadHTMLString(
    "<!DOCTYPE html><html><head><!-- In case you'd like to try opening this page in desktop Safari! --><meta charset=\"UTF-8\"></head><body><ruby><rb>これ</rb><rt></rt><rb>は</rb><rt></rt><rb>日</rb><rt>に</rt><rb>本</rb><rt>ほん</rt><rb>語</rb><rt>ご</rt><rb>です</rb><rt></rt><rb>。</rb><rt></rt></ruby><span>But this <em>isn't</em> Japanese.</span></body></html>",
    baseURL: nil
)

Evidence

If you copy-paste that as-is, do you have any more luck?

Digression

Seems like UITextView interprets all ruby nodes as having a block context. I would therefore argue that either UITextView/NSAttributedString has not fully implemented the HTML5 specification, or it has bugs, or there is some further configuration to be done. Either way, the easiest way to display this ruby text correctly would be to use a true WKWebView (although I understand this has its own tradeoffs like lack of text-to-speech support, and visibly increased time taken to render).

Upvotes: 2

Related Questions