misohena / el-igo

Emacs Go Game(SGF) Editor
53 stars 3 forks source link

`#+begin_igo` vs. `#+begin_src sgf`. #2

Open RNAer opened 3 months ago

RNAer commented 3 months ago

@misohena , thank you for developing this fantastic Go package for integration with Org-mode. I'm curious about your decision to use a special #+begin_igo block instead of a new language #+begin_src sgf. Could you share the considerations behind this choice? Is it challenge to implement all the modes it currently has? For a new language, :tangle could be nice feature to have.

Additionally, do you have any future plans for the development of this package?

misohena commented 3 months ago

(Translated by Google Translate) The reason for using "#+begin_igo" instead of "#+begin_src sgf" is probably because of the following (although it was a long time ago so I don't remember the details):

In the general use of source code blocks in org-mode, I think that the result of evaluating the source code is often an image (dot, mermaid, plantuml, R, gnuplot, etc.). So it seems good that the evaluation result of an SGF language should be an image of the game board represented by the SGF (preferably the image can be manipulated interactively in Emacs and HTML). In other words, the game board should be displayed after "#+RESULTS:".

For example, suppose you want to write a document explaining the SGF format. In that case, wouldn't you want to display and export the SGF text and the resulting game board side by side?

The following SGF shows black and white players placing stones at the star positions.

#+name: sgf-example1
#+begin_src sgf
(;FF[4]GM[1]SZ[9];B[fd];W[df])
#+end_src sgf

The result is:

#+RESULTS: sgf-example1
(Display the game board here)

In this case, we should not replace the source code block with the game board because the text of the SGF language is important. Of course, it's good to be able to edit in a temporary board view by explicit commands.

But I wanted to take notes to study the life and death problems of Go, so I didn't want to see the SGF text.

But at the same time, I'm also a developer, so I might introduce the SGF language on my blog (written in org-mode).

I think the solution would probably be something like this:

This is much more complicated and difficult than what I want for the time being, so I went with "#+begin_igo".

If these problems can be solved, I think source code blocks in the SGF language would be good.

At the moment I have no plans to make any changes to el-igo.

I hope it translates well into English.

(Original Message) 「#+begin_src sgf」ではなく「#+begin_igo」にした理由ですが、次のようなことを考慮したのだと思います(かなり前のことになるので詳しくは覚えていませんが)。

org-modeの一般的なソースコードブロックの使い方では、ソースコードを評価した結果が画像になるものが多いと思います(dot、mermaid、plantuml、R、gnuplot等々)。なのでSGF言語の評価結果はそのSGFが示す盤面画像になっているのが良さそうに思えます(その画像はEmacs上とHTML上でインタラクティブに操作できるのが望ましいでしょう)。つまり、「#+RESULTS:」の後に盤面を表示すべきということになります。

例えばSGF形式についての解説文書を書きたいとします。その場合、SGFのテキストとその結果である盤面を並べて表示・エクスポートしたくならないでしょうか。

次のSGFは黒と白が星の位置に石を置いたところです。

#+name: sgf-example1
#+begin_src sgf
(;FF[4]GM[1]SZ[9];B[fd];W[df])
#+end_src sgf

結果は次のようになります:

#+RESULTS: sgf-example1
(ここに盤面を表示)

この場合、ソースコードブロックを盤面に置き換えるべきではありません。SGF言語のテキストが重要だからです。もちろん明示的なコマンドによって一時的に盤面ビューで編集が出来るのは良いことです。

しかし私は囲碁の死活問題の勉強のためのノートを取りたかったので、SGFテキストは見たくありませんでした。

しかし同時に私は開発者でもあるので、SGF言語をブログ(org-modeで書いている)で紹介する可能性があります。

おそらく解決方法は次のようになるのではないかと思います:

これはさしあたって私が欲しいものよりも大分複雑で大変なので、「#+begin_igo」にしたというわけです。

この辺りの問題が解決できるなら、SGF言語のソースコードブロックも良いと思います。

今のところ私の方でel-igoに手を加える予定はありません。

うまく英語に翻訳できていると良いのですが。

misohena commented 3 months ago

(Translated by Google Translate) It might be a good idea to display the source code block as an inline board only when "#+begin_src sgf :exports results" is specified. When it is set to other (none, code, both), the SGF code text needs to be readable, so the inline board is not displayed by default (only when #+RESULTS: is specified, the results are displayed as an inline board).

(Original Message) 「#+begin_src sgf :exports results」の時だけそのソースコードブロックをインライン盤面として表示してしまうというのは良いかもしれません。その他(none、code、bothの時はSGFのコードテキストが読める必要があるので、デフォルトではインライン盤面にはしないというわけです(#+RESULTS:があるときのみその結果部分をインライン盤面として表示する)。

RNAer commented 3 months ago

Thanks for the explanation! I was thinking of something like below (can hard code :wrap igo as a default header argument so users wouldn't have to type it out each time). This approach could offer two advantages:

  1. Users could easily tangle the SGF file. It would be a nice feature if one want to use el-igo to manage a SGF library.
  2. SGF and board image can both be displayed at the same time. If users manually edit the SGF code, the SVG image update can be seen together with SGF change.

All the issues should not be a problem (e.g. reporting errors on non-Go game SGF evaluation; export can be set to skip code or evaluation results). However, I'm not sure if it’s feasible to retain all the functionality of your current implementation with this approach. Would it be possible to sync changes made on the game board image back to the SGF code block?


#+begin_src sgf :tangle /file/path.sgf :wrap igo
(;FF[4]GM[1]SZ[9]AB[cb][eb:ec][fd:gd][he][gf]AW[ea][fb][fc:hc][hd]PL[B];B[id];W[ic];B[hb];W[ha])
#+end_src

#+results:
#+begin_igo
Description of Image
#+end_igo

misohena commented 3 months ago

(Translated by Google Translate)

Would it be possible to sync changes made on the game board image back to the SGF code block?

It would be possible. Currently, a igo-editor object overlays a region, hiding the text underneath and showing the game board image instead. When GUI editing is performed, the igo-editor-update-on-modified function is called, so it would be a good idea to customize the behavior at that time. You can force it to extend with advice, or you can add a hook to notify the igo-editor object of edit changes. Next, igo-org.el uses this mechanism to define org-mode-specific processing when GUI editing is performed. Under org-mode, when the igo-editor object is GUI-edited, and if it is under "#+RESULTS:", find the corresponding source code block and rewrite its contents.

However, I feel uncomfortable with the operation method of editing the game board image displayed in the result section and changing the source code block above it. In other languages, you can directly change the text in the result section, but this does not change the source code. This is because there is a sense that the results are merely rewritten by the evaluation of the source code (org-babel-execute-src-block). If I want to edit the SGF in the source code block with the GUI, I would like there to be a board image in that location. I don't think there's any need to see the SGF text while editing in the GUI.

Of course, if you are not bound by preconceptions, one way may be to reflect the editing results of the evaluation results in the code block.

(I feel like some of the translations are questionable. I hope it doesn't seem unpleasant.)

(Original Message)

Would it be possible to sync changes made on the game board image back to the SGF code block?

可能ではあるでしょう。現在igo-editorオブジェクトは一つのリージョンをオーバーレイで覆い、その下のテキストを隠して代わりに盤面画像を表示するようになっています。GUIによる編集が行われたらigo-editor-update-on-modified関数が呼ばれるので、まずはその時の動作をカスタマイズ出来るようにすると良いでしょう。adviceで無理矢理拡張することも出来ますし、igo-editorオブジェクトに編集による変更を通知するためのフックを追加しても良いでしょう。次にigo-org.elではその仕組みを利用して、GUI編集が行われたときのorg-mode独自の処理を定義します。org-mode下、かつ、igo-editorオブジェクトがGUI編集されたとき、かつ、それが「#+RESULTS:」の下にある場合は、対応するソースコードブロックを見つけ出し、その内容を書き替えます。

ただし、私は結果部分に表示されている盤面画像を編集してその上にあるソースコードブロックが変更されるという操作方法には違和感を覚えます。他の言語でも結果部分のテキストを直接変更できますが、それによってソースコードが変更されたりはしません。結果はあくまでソースコードの評価(org-babel-execute-src-block)によって書き替えられるだけという感覚があるためです。ソースコードブロック内のSGFをGUIで編集したいのならその場所に盤面画像があってほしいです。GUI編集中にSGFテキストを見る必要は無いと思うので。

もちろんその既成概念に囚われないのであれば、評価結果の編集結果をコードブロックに反映させるのも一つの方法かもしれません。

(一部翻訳が怪しいところがある気がします。不愉快に思われなければ良いのですが。)

RNAer commented 3 months ago

Thanks. You are right about #+results - it is not a good idea to change the sgf code by clicking on the board in the results. it is a wrong logic flow direction. It should be a direct overlay on the code block. In terms of evaluation, I don't worry about what the sgf evaluation means. org-mode code block already has some special meaning block types like begin_src org or begin_src conff. I think it is fine to do similarly. And then one can use the org-mode block handling code instead of maintaining custom-made code after switching to sgf code block.

would you mind if I continue the development from where you have left off? I may change some design like #+begin_src sgf.

misohena commented 3 months ago

(Translated) As you say, the meaning of "evaluation" in org-babel is ambiguous. When I created ob-html, I wondered what the evaluation result of html was. The behavior of org language is actually useful. I think it's fine as long as it outputs a result that is convenient for us.

would you mind if I continue the development from where you have left off? I may change some design like #+begin_src sgf.

That's fine.

If it were me, I would add igo-org-babel.el (ob-sgf.el? ob-sgf-igo.el? You could consider making it a separate package) and write org-babel-execute:sgf (:sgf-igo? :igo?) etc. in it. As I wrote before, if you use sgf, you have to take into account games other than Go.

It seems that the code to overlay "#+begin_src sgf" actually already exists (I had completely forgotten about it!). In the igo-org-hook-fontify-block function in igo-org.el, there is a place that says ;;(advice-add #'org-src-font-lock-fontify-block :around #'igo-org--fontify-src-block-advice). Enabling this will make the code blocks overlays, but currently it will unconditionally make all sgf code blocks overlays, which is bad as we discussed earlier.

(Original) おっしゃるとおりorg-babelの「評価」の意味は曖昧ですよね。私はob-htmlを作ったときにhtmlの評価結果とは何かで悩んだことがあります。org言語の動作は実際便利ですよね。私たちにとって都合の良い結果を出力をすれば良いのだと思います。

would you mind if I continue the development from where you have left off? I may change some design like #+begin_src sgf.

良いですよ。

私だったらigo-org-babel.el (ob-sgf.el? ob-sgf-igo.el? 別パッケージにすることも考えられる)を追加してその中に org-babel-execute:sgf (:sgf-igo? :igo?) 等の関数を書くと思います。sgfにすると囲碁以外のゲームの場合を考慮しなければならないのは前に書いたとおりですね。

「#+begin_src sgf」をオーバーレイにするコードは実は既に存在しているみたいです(すっかり忘れていました!)。igo-org.el内の igo-org-hook-fontify-block 関数に ;;(advice-add #'org-src-font-lock-fontify-block :around #'igo-org--fontify-src-block-advice) と書かれている場所があります。これを有効にすると、コードブロックがオーバーレイになります。しかし今のところ全てのsgfコードブロックを無条件でオーバーレイにしようとしてしまいます。この動作が良くないのは前に話したとおりですね。

RNAer commented 2 months ago

I have a question regarding the cool undo tracking system you implemented. I noticed that it reverts both the SGF string and the game state to a previous state. However, I'm struggling to understand exactly how it works. Does the Emacs undo command first revert the SGF string and then synchronize the game state with it? How does the Emacs undo command trigger the game state undo process? Could you explain the logic and implementation behind this system? I’d really appreciate your insights. Thank you!

misohena commented 2 months ago

(Translated) That may indeed be a confusing point. I had forgotten about it too, and I was surprised when I looked it up just now.

In conclusion, the reflection of text to the board is triggered by the fontify process in font-lock-mode. In org-mode, it is the igo-org-fontify-block function, and in igo-sgf-mode, it is the igo-sgf-mode-fontify function. If you execute M-x font-lock-mode in org-mode, you will see that undo is no longer reflected. "Adjusting the appearance of the text" is the job of font-lock-mode, and the idea seems to be that the go board image is included in that "appearance". When igo-editor is in text mode, it does not create an image, and if there is an error in the SGF, it will highlight that part.

I think it would be possible to use modification-hooks (https://www.gnu.org/software/emacs/manual/html_node/elisp/Overlay-Properties.html#index-modification_002dhooks-_0028overlay-property_0029 ), but I may have thought that it would be simpler to consolidate the process of reflecting text to the board in fontify. After writing the fontify process, I may have realized that undo was also possible.

(Original) そこは確かに分かりづらいところかもしれません。私も忘れていて、今調べてみて驚きました。

結論から書くと、テキストから碁盤への反映はfont-lock-modeのfontifyの処理がトリガーになっています。org-modeではigo-org-fontify-block関数、igo-sgf-modeではigo-sgf-mode-fontify関数です。org-modeでM-x font-lock-mode を実行すれば、アンドゥが反映されなくなることが分かります。「テキストの見た目を整える」というのはfont-lock-modeの仕事であり、碁盤画像もその「見た目」に含まれるという考え方をしているのでしょう。igo-editorがテキストモードの時は画像にしませんし、もしSGFにエラーが含まれていた時はその部分をハイライトするようにもなっています。

modification-hooks(https://www.gnu.org/software/emacs/manual/html_node/elisp/Overlay-Properties.html#index-modification_002dhooks-_0028overlay-property_0029 )を使う方法も考えられると思うのですが、テキストから盤面へ反映する処理はfontifyにまとめた方がシンプルだと考えたのかもしれません。fontify処理を書いた後、偶然アンドゥも出来ていることに気がついた気がします。

RNAer commented 2 months ago

cool. overlay's modification-hooks is also a good idea. Ok, after the SGF text change triggered the fontify process and your igo-editor-update function, how did you make sure to move the game state to the right state? Did you move thru the game tree to the right move number by tracking which move number was before SGF text change?

misohena commented 2 months ago

(Translated) I think it's best to read the igo-editor-update function and the igo-editor-update-model function that is called from it to find out more about this. I thought that any board state not written in the SGF would be lost, but now that I've read it, it doesn't seem to be the case. It seems to do a minimum amount of restoration processing. There is a part where the path from the root of the game tree to the current position is obtained and then traced in the new game tree. So if the entire game tree is drastically changed by replacement or something, it may move to an unexpected board state.

(Original) その辺りのことは igo-editor-update関数とそれから呼ばれる igo-editor-update-model関数を読んでいただくのが一番だと思います。私はSGFに書いていない盤面状態は失われると思っていたのですが、今読んでみるとそうではないようですね。最低限の復元処理はしているようです。ゲーム木のルートから現在の位置までの経路を取得し、新しいゲーム木でそれを辿っている箇所があります。なのでゲーム木全体が置換などで大幅に変わると見当外れの盤面状態に移動してしまう可能性があります。