Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
日本語でもいい感じに改行したい!! / Split Japanese sentence for...
Search
Trickart
September 18, 2021
Technology
3
3.3k
日本語でもいい感じに改行したい!! / Split Japanese sentence for UILabel and SwiftUI Text
iOSDC2021発表資料
Trickart
September 18, 2021
Tweet
Share
More Decks by Trickart
See All by Trickart
External Accessory入門
trickart
0
570
Other Decks in Technology
See All in Technology
【re:Invent 2024 アプデ】 Prompt Routing の紹介
champ
0
140
組織に自動テストを書く文化を根付かせる戦略(2024冬版) / Building Automated Test Culture 2024 Winter Edition
twada
PRO
13
3.6k
複雑性の高いオブジェクト編集に向き合う: プラガブルなReactフォーム設計
righttouch
PRO
0
110
サービスでLLMを採用したばっかりに振り回され続けたこの一年のあれやこれや
segavvy
2
390
PHPからGoへのマイグレーション for DMMアフィリエイト
yabakokobayashi
1
170
KnowledgeBaseDocuments APIでベクトルインデックス管理を自動化する
iidaxs
1
260
[Ruby] Develop a Morse Code Learning Gem & Beep from Strings
oguressive
1
150
サーバレスアプリ開発者向けアップデートをキャッチアップしてきた #AWSreInvent #regrowth_fuk
drumnistnakano
0
190
kargoの魅力について伝える
magisystem0408
0
200
ずっと昔に Star をつけたはずの思い出せない GitHub リポジトリを見つけたい!
rokuosan
0
150
非機能品質を作り込むための実践アーキテクチャ
knih
3
950
Storage Browser for Amazon S3
miu_crescent
1
140
Featured
See All Featured
Done Done
chrislema
181
16k
Evolution of real-time – Irina Nazarova, EuRuKo, 2024
irinanazarova
5
440
Building a Scalable Design System with Sketch
lauravandoore
460
33k
Distributed Sagas: A Protocol for Coordinating Microservices
caitiem20
330
21k
Typedesign – Prime Four
hannesfritz
40
2.4k
Producing Creativity
orderedlist
PRO
341
39k
What’s in a name? Adding method to the madness
productmarketing
PRO
22
3.2k
The Cost Of JavaScript in 2023
addyosmani
45
7k
The World Runs on Bad Software
bkeepers
PRO
65
11k
GitHub's CSS Performance
jonrohan
1030
460k
Refactoring Trust on Your Teams (GOTO; Chicago 2020)
rmw
32
2.7k
Code Reviewing Like a Champion
maltzj
520
39k
Transcript
日本語でもいい感じに改 行したい!! trickart(@trickart4121)
みなさん
こういった 経験ありませんか?
レイアウトはこんな感じでいいか!
一応初代SEでも確認しておくか…
よいしょ…ん…?
あっ…!!
None
変なところで改行されてし まっている!! 😇
幅に合わせて縮めるやつでいいじゃん - adjustFontSizeToFitWidthをtrueにする - これで解決!!
None
お品書き - 一行表示じゃダメなケースについて - UILabelの改行制御(NSLineBreakMode) - 制御文字について(WORD JOINER) - 形態素解析
- 改行制御ツールの実装 - パッケージング - おまけ
一行表示では良くないときある… - フォントサイズを縮めたくないことも… - ユーザー層的にフォントは大きくしておきたい場合 - めちゃ長テキストで米粒サイズになってしまう場合 - etc…
あらかじめ改行しておけば…? 「iOSDC/2021/開催中」とした
あらかじめ改行しておけば…? 12 Pro Maxでは改行されすぎてる感じがしてしまう… そもそもあらかじめやっておけない場合もある
どうすれば…😇
UILabelって こういうとこいい感じに やってくれないの…?
もちろんやってくれます!
英語なら!!
NSLineBreakMode - Viewの幅より長かったときどうするか? - そのままクリップする(byClipping) - はみ出す文字の前で改行する(byCharWapping) - はみ出す単語の前で改行する(byWordWrapping) -
etc…
でも日本語だと .byWordWrappingでも…
😇
つまり 「Word」扱いされてない ってコト…?
そんなときは… WORD JOINER!!
WORD JOINERとは? - 制御文字の一種 - 幅がゼロの文字で、挿入した箇所は改行されなくなる - Unicodeのコードポイントは2060 →これを単語内にたくさん挿入すればいいはず
実験 - WORD JOINERを入れる・入れないで比較
実験 - WORD JOINERを入れる・入れないで比較 🎉
これで 改行させない方法は わかった。
じゃあ逆に どこで改行させれば…?
手作業は…
こんなときは… 形態素解析!!
形態素解析とは 文法的な情報の注記の無い自然言語のテキストデータ(文)から、対象言語の文法や、辞書と呼ばれる単語 の品詞等の情報にもとづき、形態素(Morpheme, おおまかにいえば、言語で意味を持つ最小単位)の列に分 割し、それぞれの形態素の品詞等を判別する作業である。 by 形態素解析 – Wikipedia →単語の分割と品詞判別ができる!!
OSSな形態素解析エンジン - ChaSen - JUMAN - MeCab ←今回はこれを使います
MeCabとは - 工藤拓氏によって開発された形態素解析エンジン - C++製でC言語、Java、Python、Rubyからも利用可能 - BSD/GPL/LGPLのトリプルライセンス - macOSやiOSでも利用されている -
Homebrewで簡単にインストールできる
MeCabとは
MeCabをSwiftからどう使う? - MeCabはC++製 - 今の所Swiftから直接C++ライブラリを使うことはできない →Objective-C++を使えばOK!! MeCabのC APIとSwiftのC Interopを使う案についてはおまけに
Objective-C++とは? - Objective-C++はObjective-CとC++を合体させた言語 - 拡張子は.mm - Objective-C++からC++のクラスを扱える - Swift →
Objective-C++ → C++
Objective-C++とは? Objective-C++ C言語 オブジェクト指向 Objective-C C++
全体像 MeCab (C++) ツール (Swift) ラッパー (Objective-C++)
ラッパーを書く - Objective-C++でただひたすら書く - 構造体とかStringをSwift向けに変換したりする - MeCabはchar *を返すのでNSStringに変換
- やっぱりSwift Packageとして使いたい - ラッパーだけでなくMeCab自身や辞書データもSwift Packageにする 書いたラッパーをSwift Packageにする
- C++なのにSwift Package? - Swift PackageはC/C++/Objective-C/Objective-C++の コードをパッケージング出来る - 1ターゲットにSwiftとObjective-Cを同居させたりすること はできない
MeCab as a Swift Package
- ビルド設定はPackage.swiftで行う - defineはcSettingsのdefine MeCab as a Swift Package
- コンパイラに渡す設定はPackage.swiftで行う - ライブラリのリンクはlinkerSettingsのlinkedLibrary - iOSにもiconvはあるので安心 MeCab as a Swift
Package
- Objective-C/SwiftからC/C++のライブラリを使うためには module.modulemapが必要 MeCab as a Swift Package
- 辞書データをSwift Packageにするには? - Swift 5.3からSwift PackageにBundleを追加することが出来 るようになった →辞書データだけBundleしたパッケージを作る MeCabIPAdic
as a Swift Package
- Swift PackageにファイルをBundleするにはresourcesで copyすればOK MeCabIPAdic as a Swift Package
これでSwiftから MeCabが使える!! \\٩( 'ω' ) و//
実装する - 単語に分割したら単語中の文字の間にWORD JOINERを 入れる 青いそら → 青い/そら → 青¥u{2060}い/そ¥u{2060}ら
つなぐ単語 - すべての単語を分割してしまうと見栄えが良くない - すきとおっ/た (動詞/助動詞) - 夏/で/も (名詞/助詞/助詞) -
句読点や括弧閉 (禁則処理) →これらは前の単語と結合してしまう
実装する
あらかじめLocalizable.strings - あらかじめWORD JOINERを仕込んでおきたい - MeCabIPAdicがデカいので同梱したくない… - Localizable.stringsを出力するCLIコマンド - $
muscat in.strings out.strings
完成!! - 名前はMuscatといいます - https://github.com/trickart/muscat
今度こそ
補足1 NLTaggerは? - AppleはNLTaggerというクラスを提供している - NLTaggerではだめなのか? - 英語だと単語分割・品詞判別できる - 日本語だと品詞が全部「OtherWord」になってしまう
- 品詞がないと助詞の連結などができないためボツ MeCabを選んだのはぶっちゃけMeCabしか知らなかったから
補足2 SwiftUIは? - SwiftUIにはlineBreakModeとかないけど使えるの? - 特に何も指定してないけど使えます!!
補足3 辞書データについて - MuscatではMeCabIPAdicを使用 - 辞書は差し替えようと思えば差し替えられるため mecab-ipadic-NEologdを使ったりすることも可能
補足4 muscat CLIの実装について - 引数やオプションの処理はswift-argument-parserを使用 - Property Wrapperでスッキリしてるのでおすすめ - Localizable.stringsはPropertyListDecoderで読み込める
- ただ普通に[String:String]でデコードするとDictionaryは 順番を保証しないので順番が不定になってしまう - swift-collectionsのOrderedDictionaryを使えば…?
補足5 先行事例について - 作ったあとに先行事例について調べたらあった - GoogleのBudou 🍇 - Python製のツールで形態素解析して単語の区切に HTMLのspanタグを挿入するツール
- よく考えたら昔Googleのブログで見たかも… - Muscatの名前はBudouにあやかってつけました
補足6 MeCab C APIとSwift C Interop - MeCabはC++製だがC言語向けのAPIがある - SwiftはC言語の関数を使用できる
- Objective-C++使わなくてもいいのでは…? - 試したところXcodeでデバッグ実行したらメモリリーク警告 が発生 - 実装が悪いかもしれないが、原因が特定できなかった 為断念した - 将来追加されるであろうSwift C++ Interopに期待
ご清聴ありがとうございました 参考資料 MeCab: Yet Another Part-of-Speech and Morphological Analyzer Bundling
Resources with a Swift Package | Apple Developer Documentation C++ライブラリをiOSプロジェクトに追加する方法について - Zenn