Scrapbox to Markdown コードブロック
- コードブロック
- 全然動かんw
- コードの始めも終わりも動いてない
- 始めはそもそも実装入ってない
- 終わりは実装入れてるけど「今週前半の俺、これ何がしたいん?」状態
- step2で終端を入れて、step3で各行(つまり
code:xxx
to```xxx
)をする
- コードの始めも終わりも動いてない
- step2で終端入れる
- Scrapbox to Markdown 文法変換の設計やら実装やらの★1
- ★1
- リストやテーブルの場合、add \n で良い
- コードブロックの場合、add
```
- リストorテーブルかコードブロックかを判別する手段がない
- state userにフラグがもう一つ要るなぁ
- is_left_just_now() が「たった今ブロックから抜けました」を調べるやつ
- ここに「たった今 "コード" ブロックから抜けました」も追加すればいい
- フラグ更新戦略
- if in block
- 更新しない
- if not in block
- code blockに入ったら更新する
- code blockから出たら更新する
- それ以外は更新しない
- if in block
- code blockに入ってるかどうかはstateが持っている
- おお、すげえ:sta:
- ok、入った
- step3で開始入れる
- まだ遠いのー
- なんで?
def _update_case_of_not_in_block(self, line, cur_indentdepth):
……
raise RuntimeError('Invalid start of block.') # ★これ入れてみたら普通に入りやがった
- ...
- ...
- いや、入るか
- blockじゃないときに専用記法があったらcodeblockやtableblockにするぞって話なだけで
- おかしいな
- codeblock中の行が全部 is not in blockと判定されている
- なんで
- テストコードではちゃんと動いてるんですけど
- i==15とかi=17とか
- いや、入るか
- コードブロック開始後に(なぜか入ってる)空行のせいでモードが戻されてる?
- Scrapbox to Markdown 文法変換の設計やら実装やらの話
- table:patterns
- ...
curlineのインデント数 | prevlineのインデント数 | どう解釈すべき? | 備考 |
---|---|---|---|
…… | |||
1 | 0 | add \n | リスト or ブロックがはじまた |
- ...
- ...
- 始まりの前に空行入れてるけど
- コードブロックの場合は入れちゃいけないんだ
- done
- ...
- あと少し
- 要するに「本来nインデントであるはずの行」からインデントを外す処理をどこでやるか
- step1とstep2は違うから、step3かそのメタしかない
- step3はutilなのでlineしか受け付けないはず(自分がコードブロックの中にいるとかどうとかは関知しない)
- よってメタで処理するしかない
- あ、でもstep3ではinblockstate使ってメタな処理してるw
- :train:設計軽いとこういうほころびがでてくるよねー。。。
- ほころびがでないような設計するってのは中々に難しい
- 中学からのプログラミング経験で言えば、ここは才能が絡む部分だと思う
- 圧倒的な地頭でクソースでも御するタイプと
- 世の中には変数名をa,a1,x,x1みたいにつけるプログラマーもいる(って話聞いたことある)
- 何らかの才能で芸術的にシンプルでほころびのない設計をやってしまうタイプ
- 圧倒的な地頭でクソースでも御するタイプと
- 俺は凡人なので愚直に対応していくしかない
- せめてテストコードでホワイトボックス的に品質担保するくらいよ
# コードブロックの中身
if is_in_block and state.is_in_code_block():
# ただし code:xxx の開始行も in code block 判定なので
# 置換処理もここでやるしかない.
#
# パフォーマンスがダメそうなら, 開始行を in code block 判定にしない等の追加処理が必要か.
newline = re.sub(RE_CODE_BLOCK_START, '```\\2', newline)
#
# ★ここでインデントを解除する処理を書く
return newline
- ...
- あああああ、これ厄介だな
- 機械的にインデント殺しちゃダメ
- コードブロックの始まりが持つインデント数nを使って、nだけ除外してやらねばならない
- あああああ、これ厄介だな
たとえば
list1
list2
```py
for _ in range(4):
print('4回繰り返すじぇー')
コード終わり
- ...
- ...
- これを変換するとこうなる
- ...
たとえば
- list1
- list2
```python
for _ in range(4):
print('4回繰り返すじぇー') # ここのインデントまで殺しちゃいけない
-
...★このダミーリスト部分はまだ実装できてないが。。。
- コード終わり ```
-
...
- 正規表現だとどうなる?
- cur_indentdepth回のスペースをキャプチャして殺したいんですけど
r'( ){3}'
これで3回- ここにcur_indentdepthを差し込む
r'( ){{}}'.format(cur_indentdepth)
?- でもformat使うと
{}
自体が特別な意味もっちゃって、正規表現のn回指定が使えない
- でもformat使うと
- ……愚直に文字列処理するか
- ああ、待って、だめ
- cur_indentdepthじゃなくて、コードブロック開始時のインデント深さが必要
- this_codeblock_indentdepthみたいなの
- indentdepth_of_startプロパティある
- done
- cur_indentdepthじゃなくて、コードブロック開始時のインデント深さが必要
- 正規表現だとどうなる?
- あと少し(意外と長い)
- 言語名の統一と
- ahkのHotStringのとき(たぶん
:
ついててコードブロック判定になってしまってる)の謎のインデント
- 言語名統一
newline = re.sub(RE_CODE_BLOCK_START, '```\\2', newline)
- これの延長線やな
```
でsplitして1番目の要素取り出して、あとは愚直に条件分岐するしかないか- パターン
- js
- javascript
- JavaScriptやJSなど大文字小文字
- hoge.jsなど拡張子
- 全部対応するのは明らかにしんどいので、どっかから流用するべき
- markdown、というよりGFMがどうしているかも見るべき
- 拡張子をそのまま書いて処理はできるので、少なくとも xxxx.ext は ext をそのまま使えばいい
- あとは言語名だけ書かれてるパターン
- いくつか例出してみるか
- js
code:ここの仕様
以前どこかで見た気がする- なにかのライブラリ使ってるんだよな、たしか
- Scrapboxのコードハイライトはhighlight.jsを使っている
- と思ったけど、よく考えたらGitHub側も多分同じようなの使ってるよな
- つまり、scrapboxが対応している言語名指定の語彙≒GitHubの語彙とみなせるのでは?
- そやな
- 自力実装なんてしたくないし、そうしよう
- まとめ
code:xxx
は```xxx
にするcode:xxx.ext
は```ext
にする
- 正規表現だけでは無理くない?
- できた!
- ahkのHotStringのとき(たぶん
:
ついててコードブロック判定になってしまってる?)の謎のインデント- あああああああああああああわかった
- json parserでnormalize scbしてるせいだ
- Scrapboxのjsonにはタブとスペース両方交じるので全部スペースにしている
- が、これだとコードブロック内のタブインデントも全部スペースになってしまう
- どうすっかな
- 案は2つ
- スペースのままで通す
- 僕はスペース派なので!
- が、これだとタブ派の人達が使えなくなっちゃうね。。。
- json parse時、コードブロックについてはnormalizeしない
- というかscrapboxで通常ほ本文もタブとスペースが混ざってるの、なんか理由がある気がしてきた
- shokaiさん達のエンジニアがあえてタブとスペースを混在させるやりづらさを放置するとは思えない
- 何か理由があるんだ?
- スペースのままで通す
- 今はプロトで早く形にしたいので、スペースのまま押し通しますん:sta: