blog/content/posts/2024-11-17/index.md

78 lines
2.9 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

---
author: usbharu
draft: false
categories:
- 技術
date: 2024-11-17T20:26:23+09:00
tags:
- Kotlin
- KMP
- Markdown
keywords:
- Kotlin
- Markdown
- KMP
title: Kotlin MultiplatformなMarkdownパーサを作った
relpermalink: posts/2024-11-17/
url: posts/2024-11-17/
decription: Kotlin MultiplatformなMarkdownパーサを作った
---
なんとなくパーサを作って遊びたくなったので作り始めたら意外と楽しくて、夢中で作ってました。制作期間は5日ぐらいです。パーサコンビネータを使わずにパーサを書くこと自体がかなり久しぶりだったのでウンコード量産しました。気が向いたら改善したいです。
[markdown-kt](https://github.com/usbharu/markdown-kt)
## markdown-kt
全部で1000行程度で、Lexerはテーブルと参照以外の基本的な構文に対応しています。パーサは打ち消し線、HTML、コードブロック、チェックボックスが未対応です。コード生成部分は作ってないのでパースできるだけ、いつかHTML生成とかもやってみたい
せっかく作るならなんか特徴入れたいなと思って、全角記号に対応したLexerにしてみました。
![全角半角両方書かれたLexer](lexer.png)
雑に全角対応してあります。
### Kotlinのwhenについて
Kotlinは`when`を使うことで複数のor条件を簡単に書くことができますが、今回は使えなかったので普通に`||`演算子使っています。
```kotlin
val foo: String
fun isBar(string:String): Boolean{
return string == "bar"
}
when(foo){
"hoge", "fuga" -> TODO() //複数の条件を簡単に書くことができる
isBlank() -> TODO() //error 書けない
isBar(foo) -> TODO() //error 書けない
}
when{
foo == "hoge" || foo == "fuga" -> TODO() //書ける
foo.isBlank() -> TODO() //書ける
isBar(foo) -> TODO() //書ける
}
```
あとはRustみたいに書けるようになったら便利だなぁと思いながら書いていました。
```kotlin
val foo: String
val flagA: Boolean
when(foo,flagA){
("hoge",false) -> TODO()
("hoge",true) -> TODO()
}
```
### while
どうやら今回whileとdo-whileを合計28回使っているようです。というかdo-whileを実際に書く事があるとは思わなかった
ラベル付きwhileも何回か登場していて、まともにコードを書いていたら使わないであろう構文を何度か使えて楽しかったです。リと勢いで実装したのでかなりウンコードなので、1週間後の自分はもう読めないと思います。
### その他
MisskeyのMFMをパースしようとしたときに身に着けた無駄な知識が意外と役に立ったので、今度はRustで実装するとか、MFMのパース再チャレンジとかしたいなと思いました。あとはトークンとかASTに行番号とかを持たせてエラー表示とかをやってみたい