# tree-sitter-pgn
## Overview
Chess Portable Game Notation (PGN) grammar for [tree-sitter](https://github.com/tree-sitter/tree-sitter).
## Used in
* [Emacs pygn-mode](https://github.com/dwcoates/pygn-mode)
## Highlighting Example
<a href="/doc/images/pgn_syntax_highlight.png">
<img src="/doc/images/pgn_syntax_highlight.png" width=500/>
</a>
## Python Example
```python
import more_itertools
from tree_sitter import Language, Parser
import tree_sitter_pgn as ts_pgn
PGN_LANGUAGE = Language(ts_pgn.language())
parser = Parser(PGN_LANGUAGE)
query = PGN_LANGUAGE.query(
'''
(series_of_games
game: (game) @game)
(movetext
san_move: (san_move) @san_move)
(movetext
lan_move: (lan_move) @lan_move)
''')
with open('input_file.pgn', 'rb') as file:
tree = parser.parse(file.read())
matches = query.captures(tree.root_node)
merged_nodes = [
*matches.get('game', []),
*matches.get('san_move', []),
*matches.get('lan_move', []),
]
merged_nodes = sorted(merged_nodes, key=lambda elt: elt.start_byte)
for game in more_itertools.split_before(merged_nodes, lambda node: node.type == 'game'):
main_line = []
for node in game:
if node.type in ['san_move', 'lan_move'] and node.text is not None:
main_line.append(node.text.decode().strip())
continue
print(' '.join(main_line))
```
## References
* [PGN specification](http://www.saremba.de/chessgml/standards/pgn/pgn-complete.htm)
* [Commonly-used extensions](https://www.enpassant.dk/chess/palview/enhancedpgn.htm)
* [Commonly-used annotation glyphs](https://en.wikipedia.org/wiki/Numeric_Annotation_Glyphs)
Raw data
{
"_id": null,
"home_page": null,
"name": "tree-sitter-pgn",
"maintainer": null,
"docs_url": null,
"requires_python": ">=3.8",
"maintainer_email": null,
"keywords": "incremental, parsing, tree-sitter, PGN, chess",
"author": null,
"author_email": null,
"download_url": "https://files.pythonhosted.org/packages/60/e7/0218c37a75ba50895b9e2977a8e6b03c3431a6c5c5012ceb1ae48de3e8d1/tree_sitter_pgn-1.1.4.tar.gz",
"platform": null,
"description": "# tree-sitter-pgn\n\n## Overview\n\nChess Portable Game Notation (PGN) grammar for [tree-sitter](https://github.com/tree-sitter/tree-sitter).\n\n## Used in\n\n * [Emacs pygn-mode](https://github.com/dwcoates/pygn-mode)\n\n## Highlighting Example\n\n<a href=\"/doc/images/pgn_syntax_highlight.png\">\n <img src=\"/doc/images/pgn_syntax_highlight.png\" width=500/>\n</a>\n\n## Python Example\n\n```python\nimport more_itertools\nfrom tree_sitter import Language, Parser\nimport tree_sitter_pgn as ts_pgn\n\nPGN_LANGUAGE = Language(ts_pgn.language())\nparser = Parser(PGN_LANGUAGE)\n\nquery = PGN_LANGUAGE.query(\n '''\n (series_of_games\n game: (game) @game)\n\n (movetext\n san_move: (san_move) @san_move)\n\n (movetext\n lan_move: (lan_move) @lan_move)\n ''')\n\nwith open('input_file.pgn', 'rb') as file:\n tree = parser.parse(file.read())\n\nmatches = query.captures(tree.root_node)\n\nmerged_nodes = [\n *matches.get('game', []),\n *matches.get('san_move', []),\n *matches.get('lan_move', []),\n]\nmerged_nodes = sorted(merged_nodes, key=lambda elt: elt.start_byte)\n\nfor game in more_itertools.split_before(merged_nodes, lambda node: node.type == 'game'):\n main_line = []\n for node in game:\n if node.type in ['san_move', 'lan_move'] and node.text is not None:\n main_line.append(node.text.decode().strip())\n continue\n print(' '.join(main_line))\n```\n\n## References\n\n * [PGN specification](http://www.saremba.de/chessgml/standards/pgn/pgn-complete.htm)\n * [Commonly-used extensions](https://www.enpassant.dk/chess/palview/enhancedpgn.htm)\n * [Commonly-used annotation glyphs](https://en.wikipedia.org/wiki/Numeric_Annotation_Glyphs)\n",
"bugtrack_url": null,
"license": "BSD",
"summary": "PGN grammar for tree-sitter",
"version": "1.1.4",
"project_urls": {
"Homepage": "https://github.com/rolandwalker/tree-sitter-pgn"
},
"split_keywords": [
"incremental",
" parsing",
" tree-sitter",
" pgn",
" chess"
],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "4645f9836487fec85e25adb0f221eac1733012471707398d7a5f04f35480c1df",
"md5": "d331b835c91d2b0af06039a449a1dcf2",
"sha256": "1d8bf764ec12d476a01782b29d000d774a451707997c62aa3c4814363d8d28ae"
},
"downloads": -1,
"filename": "tree_sitter_pgn-1.1.4-cp38-abi3-macosx_10_9_x86_64.whl",
"has_sig": false,
"md5_digest": "d331b835c91d2b0af06039a449a1dcf2",
"packagetype": "bdist_wheel",
"python_version": "cp38",
"requires_python": ">=3.8",
"size": 74946,
"upload_time": "2024-09-19T15:08:45",
"upload_time_iso_8601": "2024-09-19T15:08:45.669117Z",
"url": "https://files.pythonhosted.org/packages/46/45/f9836487fec85e25adb0f221eac1733012471707398d7a5f04f35480c1df/tree_sitter_pgn-1.1.4-cp38-abi3-macosx_10_9_x86_64.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "5c2f7d9001ed9296024a5cdd0fced96c98c43c85f742eede3f6a94240f55bb91",
"md5": "3e5940832fe67799656b391282f306d8",
"sha256": "dda6c454a2ffc7c4efebfa8df826b037d42438b96299a947aaaade0917154593"
},
"downloads": -1,
"filename": "tree_sitter_pgn-1.1.4-cp38-abi3-macosx_11_0_arm64.whl",
"has_sig": false,
"md5_digest": "3e5940832fe67799656b391282f306d8",
"packagetype": "bdist_wheel",
"python_version": "cp38",
"requires_python": ">=3.8",
"size": 77626,
"upload_time": "2024-09-19T15:08:47",
"upload_time_iso_8601": "2024-09-19T15:08:47.385696Z",
"url": "https://files.pythonhosted.org/packages/5c/2f/7d9001ed9296024a5cdd0fced96c98c43c85f742eede3f6a94240f55bb91/tree_sitter_pgn-1.1.4-cp38-abi3-macosx_11_0_arm64.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "25fb9f01e27160d96dc132f7a2e86e3f2a604dea0b6873cc1f9833fc6d98ab28",
"md5": "edb954da32b949044586f66bdd3257bb",
"sha256": "c78cba994fd18afff8fe9b804a667c2747acbbe4c417537cee72148dd29c678a"
},
"downloads": -1,
"filename": "tree_sitter_pgn-1.1.4-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl",
"has_sig": false,
"md5_digest": "edb954da32b949044586f66bdd3257bb",
"packagetype": "bdist_wheel",
"python_version": "cp38",
"requires_python": ">=3.8",
"size": 145007,
"upload_time": "2024-09-19T15:08:48",
"upload_time_iso_8601": "2024-09-19T15:08:48.350052Z",
"url": "https://files.pythonhosted.org/packages/25/fb/9f01e27160d96dc132f7a2e86e3f2a604dea0b6873cc1f9833fc6d98ab28/tree_sitter_pgn-1.1.4-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "318cc2b8041273d6eca639252665f9a4edbdce21300e413f866eb02519426fcb",
"md5": "677169b169506f9eea6bb67b6483bd1f",
"sha256": "a390fd2fa8752af3227273b7e4c8acebdadab3b8565e37b8ad38fd9e7c7eb027"
},
"downloads": -1,
"filename": "tree_sitter_pgn-1.1.4-cp38-abi3-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl",
"has_sig": false,
"md5_digest": "677169b169506f9eea6bb67b6483bd1f",
"packagetype": "bdist_wheel",
"python_version": "cp38",
"requires_python": ">=3.8",
"size": 99655,
"upload_time": "2024-09-19T15:08:49",
"upload_time_iso_8601": "2024-09-19T15:08:49.603388Z",
"url": "https://files.pythonhosted.org/packages/31/8c/c2b8041273d6eca639252665f9a4edbdce21300e413f866eb02519426fcb/tree_sitter_pgn-1.1.4-cp38-abi3-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "3e1d3555207a26c70005e9cfac5155ee6bc027f166789943a161b5ba3729afde",
"md5": "e8ca5c37ba9de5dc41216e75e8b31f43",
"sha256": "c9a4131c325d8a7b36e812b2bf2d7633299a9394e5918a0642eea4100eff5fee"
},
"downloads": -1,
"filename": "tree_sitter_pgn-1.1.4-cp38-abi3-musllinux_1_2_aarch64.whl",
"has_sig": false,
"md5_digest": "e8ca5c37ba9de5dc41216e75e8b31f43",
"packagetype": "bdist_wheel",
"python_version": "cp38",
"requires_python": ">=3.8",
"size": 87641,
"upload_time": "2024-09-19T15:08:50",
"upload_time_iso_8601": "2024-09-19T15:08:50.570742Z",
"url": "https://files.pythonhosted.org/packages/3e/1d/3555207a26c70005e9cfac5155ee6bc027f166789943a161b5ba3729afde/tree_sitter_pgn-1.1.4-cp38-abi3-musllinux_1_2_aarch64.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "37b4faf33cc9c269ad9722abc1fa2379c690e31333337f833cb5456c27aed248",
"md5": "1abf5c77d2fd7279bbda156d16dcbe6d",
"sha256": "e9c8cb9f9e0a27004ff32dbcfe23a2d7809dd3dd3e5a115c5a1f424e260012e7"
},
"downloads": -1,
"filename": "tree_sitter_pgn-1.1.4-cp38-abi3-musllinux_1_2_x86_64.whl",
"has_sig": false,
"md5_digest": "1abf5c77d2fd7279bbda156d16dcbe6d",
"packagetype": "bdist_wheel",
"python_version": "cp38",
"requires_python": ">=3.8",
"size": 90478,
"upload_time": "2024-09-19T15:08:51",
"upload_time_iso_8601": "2024-09-19T15:08:51.847396Z",
"url": "https://files.pythonhosted.org/packages/37/b4/faf33cc9c269ad9722abc1fa2379c690e31333337f833cb5456c27aed248/tree_sitter_pgn-1.1.4-cp38-abi3-musllinux_1_2_x86_64.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "60e70218c37a75ba50895b9e2977a8e6b03c3431a6c5c5012ceb1ae48de3e8d1",
"md5": "c4b85953bdc73b084fb258675b931eff",
"sha256": "913e1a3da536a39144da008b6703bb34dd30904b6929aa38def88c3423e85f2b"
},
"downloads": -1,
"filename": "tree_sitter_pgn-1.1.4.tar.gz",
"has_sig": false,
"md5_digest": "c4b85953bdc73b084fb258675b931eff",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.8",
"size": 60568,
"upload_time": "2024-09-19T15:08:52",
"upload_time_iso_8601": "2024-09-19T15:08:52.698844Z",
"url": "https://files.pythonhosted.org/packages/60/e7/0218c37a75ba50895b9e2977a8e6b03c3431a6c5c5012ceb1ae48de3e8d1/tree_sitter_pgn-1.1.4.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2024-09-19 15:08:52",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "rolandwalker",
"github_project": "tree-sitter-pgn",
"travis_ci": false,
"coveralls": false,
"github_actions": true,
"lcname": "tree-sitter-pgn"
}