kyoh86 / madao

MIT License
0 stars 0 forks source link

設計 #1

Open kyoh86 opened 2 years ago

kyoh86 commented 2 years ago

リファクタリングとはなにか

Markdown 文書群におけるリファクタリングとはどのような操作か

どの操作も、

  1. テキストを移動する
  2. 関連ドキュメント群の中で、カットしたテキストへのリンクを付け替える
  3. (必要であれば)元の文書から新しい文書へのリンクを付ける

基本的にはこれだ。

例外として文書の削除があり、これは 3. がない。

kyoh86 commented 2 years ago

操作の内容

意図はすべてテキストの移動であることに変わりない。 移動元と移動先が指定できて、移動先はない場合(削除の場合)がある。

"位置" とは?

位置にはいろんな方式があるがどういうのが良いだろう?

いくつか特殊な位置については注意が必要そう

kyoh86 commented 2 years ago

移動するテキストの中にもリンクがあり得るのだった。そこも移動に伴った書換がいる。

kyoh86 commented 2 years ago

位置の指定には省略が許されるならば、下手な記法でごまかさないほうがいい。 つまり例えば、

filename:line:column

みたいな形で指定できるとすると、

が同じ形になってしまう。 ファイル名に「使えない文字」がない以上、cli引数でファイル名と他の何かを結合するのは無防備すぎる。

kyoh86 commented 2 years ago

位置の指定を行単位に限ると、とたんにいろいろな課題が解決する気がする。 挿入位置前後の改行は、とか、ASTの構造の中で切り出すときは、とか。

kyoh86 commented 2 years ago

懸念

ディレクトリにファイルが多いと、リンクの移動でものすごい探索が発生する。 なんかいい方法無いかな。

サーバーを立てて持たせるのは、インメモリに相当量のキャッシュを持たせないと役に立たなくてきつそう。 ファイル名と時刻、内容のハッシュをキーにしてキャッシュDBを作ったほうが良いかも。

kyoh86 commented 2 years ago

性能的な問題は、起きたら考えよう。まずはミニマムで実装

kyoh86 commented 2 years ago

コマンド体系

$ madao mv [options...] <source> [<destination>]
$ madao move [options...] <source> [<destination>]

$ madao mv SOURCE dest.md:9
kyoh86 commented 2 years ago
source               = entire lines of file
                     | head lines of file
                     | tail lines of file
                     | middle lines of file ;

destination          = tail of file | a line of file

entire lines of file = filename ;
head lines of file   = filename , ":" , "~" , end line ;
tail lines of file   = filename , ":" , start line , "~" ;
middle lines of file = filename , ":" start line , "~" , end line ;

tail of file         = filename ;
a line of file       = filename , ":" , line ;

start line           = positive ;
end line             = line ;
line                 = positive | negative ;

digit sequence       = digit | digit sequence , digit ;
negative             = "-" , positive ;
positive             = digit excluding zero | digit excluding zero , digit sequence ;

digit excluding zero = "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9" ;
digit                = "0" | digit excluding zero ;

filename             = ? all characters ?

これだと曖昧になる(xxx.md:1 という名前のファイルの全行、みたいな指定はできない)が、 エッジケースなので無視する。

kyoh86 commented 2 years ago

goのgoldmarkはダメそう。変更したASTをMarkdownとして書き出せない。

kyoh86 commented 2 years ago

blackberry.v2も駄目。メンテが2年近く止まってる。

結局remark + denoか、pandoc filterで作るのが良さそう。

kyoh86 commented 2 years ago

denoでremarkを使うのは難しそう。

$ deno run ./src/main.ts
Check file:///home/kyoh86/Projects/github.com/kyoh86/madao/src/main.ts
error: TS2300 [ERROR]: Duplicate identifier 'BufferEncoding'.
type BufferEncoding = "ascii" | "utf8" | "utf-8" | "utf16le" | "ucs2" | "ucs-2" | "base64" | "latin1" | "binary" | "hex";
     ~~~~~~~~~~~~~~
    at https://cdn.esm.sh/v78/node.ns.d.ts:7:6

    'BufferEncoding' was also declared here.
            type BufferEncoding = 'ascii' | 'utf8' | 'utf-8' | 'utf16le' | 'ucs2' | 'ucs-2' | 'base64' | 'base64url' | 'latin1' | 'binary' | 'hex';
                 ~~~~~~~~~~~~~~
        at https://cdn.esm.sh/v78/@types/node/buffer.d.ts:171:14

TS2300 [ERROR]: Duplicate identifier 'WithImplicitCoercion'.
type WithImplicitCoercion<T> = T | { valueOf(): T };
     ~~~~~~~~~~~~~~~~~~~~
    at https://cdn.esm.sh/v78/node.ns.d.ts:9:6

    'WithImplicitCoercion' was also declared here.
            type WithImplicitCoercion<T> =
                 ~~~~~~~~~~~~~~~~~~~~
        at https://cdn.esm.sh/v78/@types/node/buffer.d.ts:172:14

TS2300 [ERROR]: Duplicate identifier 'Buffer'.
declare class Buffer extends Uint8Array {
              ~~~~~~
    at https://cdn.esm.sh/v78/node.ns.d.ts:16:15

    'Buffer' was also declared here.
            interface Buffer extends Uint8Array {
                      ~~~~~~
        at https://cdn.esm.sh/v78/@types/node/buffer.d.ts:532:19    and here.
            var Buffer: BufferConstructor;
                ~~~~~~
        at https://cdn.esm.sh/v78/@types/node/buffer.d.ts:2196:13

TS2661 [ERROR]: Cannot export 'Buffer'. Only local declarations can be exported from a module.
    export { Buffer };
             ~~~~~~
    at https://cdn.esm.sh/v78/@types/node/buffer.d.ts:98:14

TS2300 [ERROR]: Duplicate identifier 'BufferEncoding'.
        type BufferEncoding = 'ascii' | 'utf8' | 'utf-8' | 'utf16le' | 'ucs2' | 'ucs-2' | 'base64' | 'base64url' | 'latin1' | 'binary' | 'hex';
             ~~~~~~~~~~~~~~
    at https://cdn.esm.sh/v78/@types/node/buffer.d.ts:171:14

    'BufferEncoding' was also declared here.
    type BufferEncoding = "ascii" | "utf8" | "utf-8" | "utf16le" | "ucs2" | "ucs-2" | "base64" | "latin1" | "binary" | "hex";
         ~~~~~~~~~~~~~~
        at https://cdn.esm.sh/v78/node.ns.d.ts:7:6

TS2300 [ERROR]: Duplicate identifier 'WithImplicitCoercion'.
        type WithImplicitCoercion<T> =
             ~~~~~~~~~~~~~~~~~~~~
    at https://cdn.esm.sh/v78/@types/node/buffer.d.ts:172:14

    'WithImplicitCoercion' was also declared here.
    type WithImplicitCoercion<T> = T | { valueOf(): T };
         ~~~~~~~~~~~~~~~~~~~~
        at https://cdn.esm.sh/v78/node.ns.d.ts:9:6

TS2300 [ERROR]: Duplicate identifier 'Buffer'.
        interface Buffer extends Uint8Array {
                  ~~~~~~
    at https://cdn.esm.sh/v78/@types/node/buffer.d.ts:532:19

    'Buffer' was also declared here.
    declare class Buffer extends Uint8Array {
                  ~~~~~~
        at https://cdn.esm.sh/v78/node.ns.d.ts:16:15

TS2300 [ERROR]: Duplicate identifier 'Buffer'.
        var Buffer: BufferConstructor;
            ~~~~~~
    at https://cdn.esm.sh/v78/@types/node/buffer.d.ts:2196:13

    'Buffer' was also declared here.
    declare class Buffer extends Uint8Array {
                  ~~~~~~
        at https://cdn.esm.sh/v78/node.ns.d.ts:16:15

TS2694 [ERROR]: Namespace '__' has no exported member 'Root'.
  import('https://cdn.esm.sh/v78/@types/mdast@3.0.10/index.d.ts').Root,
                                                                  ~~~~
    at https://cdn.esm.sh/v78/remark@14.0.2/index.d.ts:2:67

TS2694 [ERROR]: Namespace '__' has no exported member 'Root'.
  import('https://cdn.esm.sh/v78/@types/mdast@3.0.10/index.d.ts').Root,
                                                                  ~~~~
    at https://cdn.esm.sh/v78/remark@14.0.2/index.d.ts:3:67

TS2694 [ERROR]: Namespace '__' has no exported member 'Root'.
  import('https://cdn.esm.sh/v78/@types/mdast@3.0.10/index.d.ts').Root,
                                                                  ~~~~
    at https://cdn.esm.sh/v78/remark@14.0.2/index.d.ts:4:67

Found 11 errors.
kyoh86 commented 2 years ago

pandocのlua filterを作るのが筋良いんだけど、luaはなぁ。 pandocの組み込みluaのバージョンと、環境のLUA_PATHで指定されてるバージョンが一致しないと、undefined symbolが発生しがち。

pandoc 2.17.1.1 を使ってるけど、今は lua 5.3らしい。

eval "$(luarocs --lua-version=5.3 path)"

してやる必要がある

kyoh86 commented 2 years ago

流れはわかった。

sourceの切り出し

指定された場所の内容を切り出す。 ファイル全体の場合はファイルを削除する。

partial-sourceと呼ぶ。

linkの変更を検出する

を別々に使うので

を別々に持ったほうが良さそう

partial-sourceの中のIDを抽出

collect-link.luaを作って次のコマンドに標準出力でpartial-sourceを食わせると、IDのリストが得られる。

local collection = {}

local function collect(elem)
    if not elem.identifier then
        return
    end
    collection[elem.identifier] = true
end

local function dump()
    for id, _ in pairs(collection) do
        print(id)
    end
end

return {
    setmetatable(collection, {
        __index = function()
            return collect
        end,
    }),
    {
        Pandoc = function()
            dump()
            return pandoc.Pandoc({}, {})
        end,
    },
}

得られたIDのリストを以降partial-source-idsと呼ぶ。

partial-sourceの中のリンクを加工

他のドキュメントから、sourceへのリンクを置換する

destに書き込む

partial-sourceをdestに書き込む。DONE