It displays the Go board and edits the game record (SGF format) in Emacs.
- Emacs 27.1-30.06
- Org-mode 9.7.5
- Put code inside init path. Then:
(with-eval-after-load "org" (require 'igo-org) (igo-org-setup))
- Use
use-package
(use-package igo-org :after org :vc (:url https://github.com/rnaer/el-igo) :config (igo-org-setup))
Insert igo special block in a org-mode file:
#+begin_igo
#+end_igo
Inside the block, you can create or edit SGF file for a Go game.
special header args can be used following #+begin_igo
.
For example, the following will display the step number on the stones when the block is boarded (e.g., when the org file is opened).
#+begin_igo :move-number t
(;FF[4]GM[1]SZ[9];B[fd];W[df];B[ff];W[dd])
#+end_igo
Valid options include:
header args | meaning | value |
---|---|---|
:status-bar | Status bar display state | Hidden when nil or no |
:move-number | Display state of step number | Hidden when nil or no |
:branch-text | Display state of branch text (A, B, …) | Hidden when nil or no |
:editable | Editable | Not editable if nil or no |
:read-only | Editing prohibited (opposite of :editable) | Editing possible when nil or no |
:path | The board (node) to display initially | The path to reach the board (see below) |
:display | Display method when exporting | Value indicating the display method (see below) |
:grid-interval | Grid interval | Number of pixels (default is igo-board-view-grid-interval-default) |
Or you can set the default value of an option in the file by writing in the file. (Note: Currently, you need to reopen the file when you change it.)
Example:
#+IGO_BLOCK_DEFAULTS: :grid-interval 24 :move-number t
The :path option specifies the initial board (game tree node) to display.
A path (a route to a board state) is a sequence of the following elements, and the final board state is selected by tracing the board states specified by each element in order from the initial board state (route).
Number | The state after the current state specified by the number (if there are intermediate branches, select the first branch (A)) (if there are no intermediate branches, select the final state) |
-number | The previous board state specified by the number from the current board state (if not specified, the first board state) |
Two letters of the alphabet | Consider it as SGF coordinates, and place it at that location. The board state closest to the current board state (breadth-first search) |
One capital alphabet character | The first branch destination (A:0, B:1, …) after the current board state is specified, and the board state immediately after that branch |
_ (underscore) | The first board state with a branch after the current board state (the last board state if there are no branches) |
example:
- 0 : First board
- 12: The 12th move from the beginning
- cd : First move to 3 of 4
- cc/fc: The first move to the upper left triple (cc), followed by the first move to the two spaces (fc)
- cc/2 : 2nd move after the first move
- A/B/A: The board with the branches selected in the order A, B, A.
- _ : First branch (if not, the final board state)
- _/-1: One before the first branch (if there is none, the final board state)
Add the following code to your emacs config:
(autoload 'igo-sgf-mode "igo-sgf-mode")
(add-to-list 'auto-mode-alist '("\\.sgf$" . igo-sgf-mode))
When you open an SGF file, the board will automatically be displayed.
Note: SGF files can also represent other games besides Go, such as Othello, chess, backgammon, etc. If you handle them, you need to make sure that igo-sgf-mode
is not started when the GM property is not 1 (not yet implemented).
If you enclose any SGF text in a region and then run M-x igo-edit-region, that region will become an editor.
Both igo-sgf-mode.el
and igo-org.el
are implemented using igo-editor.el
. igo-sgf-mode.el
automatically converts the entire buffer into an editor, while igo-org.el
automatically converts the region between #+begin_igo
and #+end_igo
into an editor.
The editor has the following main modes:
- Text mode
- Fixed mode (remains text even if the error is gone)
- Auto-recovery mode (automatically switches to graphical mode when no errors are detected)
Operation | Description | Function |
---|---|---|
C-c q | Quit editor | igo-editor-quit |
C-c g | Switch to graphical mode | igo-editor-graphical-mode |
C-c i | Initialize board | igo-editor-init-board |
Operation | Description | Function |
---|---|---|
C-c g | Go to text mode | igo-editor-text-mode |
C-x c-q | Toggle editable state | igo-editor-toggle-editable |
a, |< button click | Go to the beginning | igo-editor-first-node |
e, >| button click | Go to the end (as far as you can reach with default selection) | igo-editor-last-node |
b, < button click | Previous | igo-editor-previous-node |
f, > button click | Next (if default selection is available) | igo-editor-next-node |
M-b | Previous fork | igo-editor-previous-fork |
M-f | Next fork | igo-editor-next-fork |
n | Select the next board state from the branch and display it | igo-editor-select-next-node |
Q | Move mode | igo-editor-move-mode |
F | Free edit mode | igo-editor-free-edit-mode |
M | Mark edit mode | igo-editor-mark-edit-mode |
s s | Toggle status bar display | igo-editor-toggle-status-bar |
s n | Toggle step number display | igo-editor-toggle-move-number |
s b | Toggle the display of next move | igo-editor-toggle-branch-text |
c | Edit comment | igo-editor-edit-comment |
N | Edit step number | igo-editor-edit-move-number |
g | Edit game info | igo-editor-edit-game-info |
x i | SVG image output of the board surface | igo-editor-export-image |
C-c i | Initialize board | igo-editor-init-board |
Operation | Description | Function |
---|---|---|
P, click Pass button | Pass | igo-editor-pass |
p | put stone | igo-editor-put-stone |
Click on the board | Place a stone | igo-editor-move-mode-board-click |
Right click on Pass button | Display menu for “Pass” | igo-editor-pass-click-r |
Right-click on the board | Display menu for intersections (stones and empty points) | igo-editor-move-mode-board-click-r |
\dollar | Make current node root | igo-editor-make-current-node-root |
(Currently, it can only be used on the first board)
Operation | Description | Function |
---|---|---|
Click Quit button | Switch to move mode | igo-editor-move-mode |
p | Set intersection point to selected state | igo-editor-free-edit-put |
Click on the board | Select the intersection | igo-editor-free-edit-board-down |
B, Click Black button | Select black stone | igo-editor-free-edit-black |
W, White button click | Select white stone | igo-editor-free-edit-white |
E, Click Empty button | Select empty point | igo-editor-free-edit-empty |
T, Click Turn button | Reverse next turn | igo-editor-free-edit-toggle-turn |
Operation | Description | Function |
---|---|---|
Click Quit button | Switch to move mode | igo-editor-move-mode |
p | Set intersection point as selected | igo-editor-mark-edit-put |
Click on the board | Mark the intersection as selected | igo-editor-mark-edit-board-down |
X, X button click | Select with ╳ mark | igo-editor-mark-edit-cross |
Click O, O button | Select with ○ mark | igo-editor-mark-edit-circle |
Click S, SQ button | Select with □ mark | igo-editor-mark-edit-square |
Click T, TR button | Select with △ mark | igo-editor-mark-edit-triangle |
E, Click Text button | Select with text | igo-editor-mark-edit-text |
D, click Del button | Delete the select node | igo-editor-mark-edit-del |
If you go back and hit a different place, a branch will be created automatically. The editor keeps track of all the branches in a tree structure.
Branches are displayed with an alphabet starting with A on the board just before the branch.
Left-click on the alphabet that indicates a branching point to proceed to that branch.
The “Next” button will proceed to the last selected branch, but you must explicitly select it if it is not already selected.
If you want to delete a branch or change the (alphabetical) order of the branches, right-click on the alphabet. A pop-up menu will appear with options for what to do with the branch.
PROPERTIES:
If you have embedded a game record in an org-mode document, you will probably want the game board to be displayed in the exported document. Here we explain how to output the game board when exporting to HTML.
The standard HTML backend outputs special blocks enclosed in div tags. Since #+begin_igo
to #+end_igo
are also special blocks, when output in HTML they are output in the form <div class="igo"><p>
SGF text </p></div>
.
If you want to display it in the shape of a board, it is a good idea to convert it all at once using JavaScript when the page has finished loading.
For example, if you want to use my JavaScript Go board, download igo.js, igo_view.js, and igo.css from misohena/js_igo: JavaScript Go Game Board and do the following.
#+HTML_HEAD: <script src="igo.js"></script>
#+HTML_HEAD: <script src="igo_view.js"></script>
#+HTML_HEAD: <link rel="stylesheet" href="igo.css" />
#+HTML_HEAD: <script>window.addEventListener("load", ev=>{ for(elem of document.querySelectorAll("div.igo")){ let sgf = elem.textContent; while(elem.hasChildNodes() ){elem.removeChild(elem.firstChild);} new igo.GameView(elem, sgf, {"showBranchText": true, "showLastMoveMark": true, "showComment": true, "path":1000}); }} );</script>
They just got two stars from each other.
#+begin_igo
(;FF[4]GM[1]SZ[9];B[fd];W[df];B[ff];W[dd])
#+end_igo
There is also a way to change the output (conversion result) of the igo special block itself.
To change the output of igo special blocks, you need to customize the org-mode exporter. There are three ways to do this:
- Modify an existing HTML backend
- Define a new backend that is derived from the HTML backend
- Overwrite buffer local variables
The easiest way to do this is to modify an existing HTML backend, so once you’ve set it up you don’t have to configure it for each file, and you can export as you normally would.
Add the following code to your emacs config:
(with-eval-after-load "ox-html"
(require 'igo-org-export-html)
(igo-org-modify-html-backend))
Then, immediately after the org-mode HTML backend is loaded, it is rewritten to handle the igo special blocks (the #+begin_igo
to #+end_igo
parts) specially.
By default, it outputs HTML that uses my own JavaScript Go board, so download igo.js, igo_view.js, and igo.css from misohena/js_igo: JavaScript Go Game Board and place them in the same location as the html.
Now just export it as HTML as you normally would.
If for some reason you don’t want to modify the HTML backend directly, you can define a new custom backend.
The following code will register a backend named igo-html.
(require 'igo-org-export-html)
(igo-org-define-html-backend t)
Specifying t
as an argument to igo-org-define-html-backend
will add an item to the menu.
After bringing up the export menu with Cc Ce
, you can specify this backend by pressing g.
You can change the conversion process by setting buffer-local variables for each file without customizing the backend.
To use this method, add the following code to your org-mode document:
#+begin_src emacs-lisp :exports results :results none
(require 'igo-org-export-html)
(igo-org-set-html-filters-local)
#+end_src
Specifying :exports results
causes the source block to be evaluated each time an export is made, and specifying :results none
suppresses the output of the results.
Then export it as HTML as usual.
By default, org-mode will ask you whether you want to evaluate the source block every time you export, so enter yes.
This sets a conversion filter in the buffer local variable, which converts the igo special blocks in a special way.
When converting using igo-org-export-html.el the following options are available:
Option | Meaning | Default Value |
---|---|---|
#+IGO_JS_PATH: <path-to-directory> | Path to the directory containing the script | Value of igo-org-js-path (./) |
#+IGO_JS_TEMPLATE: <header-template> | Text template to insert into HTML HEAD (when display is js) | Value of igo-org-js-template |
#+IGO_LAZY_JS_TEMPLATE: <block-template> | Template for text to insert into igo special blocks (when display is lazy-js) | Value of igo-org-lazy-js-template |
#+IGO_HEADER_TEMPLATE: <header-template> | Template of text to insert into HTML HEAD (when display is custom) | Value of igo-org-header-template |
#+IGO_BLOCK_TEMPLATE: <block-template> | Template for text to insert into igo special blocks (when display is custom) | Value of igo-org-block-template |
#+IGO_ENABLE: <boolean> | Whether to convert igo special blocks | t |
#+IGO_DISPLAY: <display-type> | How to convert igo special blocks | js |
You can suppress all conversions in the file by specifying #+IGO_ENABLE: nil
.
#+IGO_DISPLAY:
can be one of the following:
<display-type> | Display method |
---|---|
none | Hidden |
noconv | Do not convert (remain SGF text) |
js | JavaScript Goboard by js_igo |
lazy-js | JavaScript Go board by js_igo (lazy loading type, does not insert scripts in <head></head>) |
svg | Embed SVG image |
custom | Use #+IGO_HEADER_TEMPLATE: and #+IGO_BLOCK_TEMPLATE: |
The display method can also be specified for each block in the form #+begin_igo :display <display-type>
.
example:
#+IGO_JS_PATH: ./js_igo/
#+IGO_DISPLAY: svg
#+begin_igo :move-number t :path A/A/B
....Omitted (SVG view)...
#+end_igo
#+begin_igo :read-only t :move-number t :path 5 :display js
....Omitted (displayed by js_igo)...
#+end_igo
Depending on the display method, you can specify a template string.
The optional <header-template> is a template for the text to be inserted into the HTML HEAD element. If a block with the display method js exists, the template specified by the #+IGO_JS_TEMPLATE:
option will be used. If a block with the display method custom exists, the template specified by the #+IGO_HEADER_TEMPLATE:
option will also be used.
The following syntax can be used within <header-template>.
% <var-name> % | Replace with |
---|---|
%PATH% | #+IGO_JS_PATH: option value |
The optional <block-template> is the template for the text to be inserted into the igo special block. For blocks with lazy-js display style, the template specified by the #+IGO_LAZY_JS_TEMPLATE:
option will be used. For blocks with custom display style, the template specified by the #+IGO_BLOCK_TEMPLATE:
option will be used.
The following syntax can be used within <header-template>.
% <var-name> % | Replace with |
---|---|
%PATH% | #+IGO_JS_PATH: option value |
%SGF% | SGF text |
%OPT_JSON% | Options for js_igo |
%SVG% | SVG version of the board |
You can also escape some characters within the text by specifying one of the following after the %:
Notation | Character to replace | Character to replace |
---|---|---|
%HTML_<var-name>% | & < > | & < > |
%ATTR_<var-name>% | & < > ” | & < > ” |
%LITERAL_<var-name>% | \ ” line break <!– <script </script | \ " \n <\!– <\script <\/script |
In other words, use %ATTR_ when writing inside an HTML attribute, %HTML_ when writing inside the HTML content, and %LITERAL_ when writing inside a JavaScript string literal. For example, if you want to convert an SGF into a JavaScript string and parse it, write it as follows: parseSGF("%LITERAL_SGF%")
.