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
590
Other Decks in Technology
See All in Technology
例外処理を理解して、設計段階からエラーを「見つけやすく」「起こりにくく」する
kajitack
12
3.1k
トレードオフスライダーにおける品質について考えてみた
suzuki_tada
3
150
“自分”を大切に、フラットに。キャリアチェンジしてからの一年 三ヶ月で見えたもの。
maimyyym
0
250
ハンズオンで学ぶ Databricks - Databricksにおけるデータエンジニアリング
taka_aki
1
2.1k
もし今からGraphQLを採用するなら
kazukihayase
7
3.2k
論文紹介 ”Long-Context LLMs Meet RAG: Overcoming Challenges for Long Inputs in RAG” @GDG Tokyo
shukob
0
260
スクラムマスターの活動と組織からの期待のズレへの対応 / Dealing with the gap between Scrum Master activities and organizational expectations
pauli
2
1k
DevSecOps入門:Security Development Lifecycleによる開発プロセスのセキュリティ強化
yuriemori
0
220
GitLab SelfManagedをCodePipelineのソースに設定する/SetGitLabSelfManagedtoCodePipeline
norihiroishiyama
1
110
[SRE kaigi 2025] ガバメントクラウドに向けた開発と変化するSRE組織のあり方 / Development for Government Cloud and the Evolving Role of SRE Teams
kazeburo
4
1.7k
20250129 Findy_テスト高活用化
dshirae
0
190
ObservabilityCON on the Road Tokyoの見どころ
hamadakoji
0
150
Featured
See All Featured
CSS Pre-Processors: Stylus, Less & Sass
bermonpainter
356
29k
Testing 201, or: Great Expectations
jmmastey
41
7.2k
Raft: Consensus for Rubyists
vanstee
137
6.7k
Refactoring Trust on Your Teams (GOTO; Chicago 2020)
rmw
33
2.8k
Building Flexible Design Systems
yeseniaperezcruz
328
38k
A Philosophy of Restraint
colly
203
16k
A Modern Web Designer's Workflow
chriscoyier
693
190k
Producing Creativity
orderedlist
PRO
343
39k
No one is an island. Learnings from fostering a developers community.
thoeni
19
3.1k
Creating an realtime collaboration tool: Agile Flush - .NET Oxford
marcduiker
27
1.9k
Building Your Own Lightsaber
phodgson
104
6.2k
GraphQLの誤解/rethinking-graphql
sonatard
68
10k
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