{"id":23741288,"url":"https://github.com/arne314/typstar","last_synced_at":"2025-09-04T15:33:07.669Z","repository":{"id":261113246,"uuid":"882107972","full_name":"arne314/typstar","owner":"arne314","description":"Neovim plugin for efficient note taking in typst","archived":false,"fork":false,"pushed_at":"2024-12-30T22:49:50.000Z","size":231,"stargazers_count":2,"open_issues_count":0,"forks_count":1,"subscribers_count":1,"default_branch":"main","last_synced_at":"2024-12-30T23:25:53.251Z","etag":null,"topics":["anki","excalidraw","nvim-plugin","treesitter","typst"],"latest_commit_sha":null,"homepage":"","language":"Lua","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/arne314.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-11-01T22:51:51.000Z","updated_at":"2024-12-29T13:27:29.000Z","dependencies_parsed_at":"2024-12-02T22:22:14.586Z","dependency_job_id":"c35e82ed-8651-4e08-ae7b-bcc8eccfe14e","html_url":"https://github.com/arne314/typstar","commit_stats":null,"previous_names":["arne314/typstar"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/arne314%2Ftypstar","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/arne314%2Ftypstar/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/arne314%2Ftypstar/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/arne314%2Ftypstar/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/arne314","download_url":"https://codeload.github.com/arne314/typstar/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":231971535,"owners_count":18454018,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["anki","excalidraw","nvim-plugin","treesitter","typst"],"created_at":"2024-12-31T10:19:17.973Z","updated_at":"2025-09-04T15:33:07.653Z","avatar_url":"https://github.com/arne314.png","language":"Lua","funding_links":[],"categories":["Integrations \u0026 Tools"],"sub_categories":["Editor Integrations"],"readme":"# Typstar\nNeovim plugin for efficient (mathematical) note taking in Typst\n\n## Features\n- Powerful autosnippets using [LuaSnip](https://github.com/L3MON4D3/LuaSnip/) and [Tree-sitter](https://tree-sitter.github.io/) (inspired by [fastex.nvim](https://github.com/lentilus/fastex.nvim))\n- Easy insertion of drawings using [Obsidian Excalidraw](https://github.com/zsviczian/obsidian-excalidraw-plugin) or [Rnote](https://github.com/flxzt/rnote)\n- Export of [Anki](https://apps.ankiweb.net/) flashcards \\[No Neovim required\\]\n\n## Usage\n\n### Snippets\nUse `:TypstarToggleSnippets` to toggle all snippets at any time.\nTo efficiently navigate insert nodes and avoid overlapping ones,\nuse `:TypstarSmartJump` and `:TypstarSmartJumpBack`.\nAvailable snippets can mostly be intuitively derived from [here](././lua/typstar/snippets), they include:\n\nUniversal snippets:\n- Alphanumeric characters: `:\u003cchar\u003e` \u0026#8594; `$\u003cchar\u003e$ ` in markup (e.g. `:X` \u0026#8594; `$X$ `, `:5` \u0026#8594; `$5$ `)\n- Greek letters: `;\u003clatin\u003e` \u0026#8594; `\u003cgreek\u003e` in math and `$\u003cgreek\u003e$ ` in markup (e.g. `;a` \u0026#8594; `alpha`/`$alpha$ `)\n- Common indices (numbers and letters `i-n`): `\u003cletter\u003e\u003cindex\u003e ` \u0026#8594; `\u003cletter\u003e_\u003cindex\u003e ` in math and `$\u003cletter\u003e$ \u003cindex\u003e ` \u0026#8594; `$\u003cletter\u003e_\u003cindex\u003e$ ` in markup (e.g `A314 ` \u0026#8594; `A_314 `, `$alpha$ n ` \u0026#8594; `$alpha_n$ `)\n\nYou can find a complete map of latin to greek letters including reasons for the less intuitive ones [here](./lua/typstar/snippets/letters.lua).\nNote that some greek letters have multiple latin ones mapped to them.\n\nMarkup snippets:\n- Begin inline math with `ll` and multiline math with `dm`\n- [Markup shorthands](./lua/typstar/snippets/markup.lua) (e.g. `HIG` \u0026#8594; `#highlight[\u003ccursor\u003e]`, `IMP` \u0026#8594; `$==\u003e$ `)\n- [ctheorems shorthands](./lua/typstar/snippets/markup.lua) (e.g. `tem` \u0026#8594; empty theorem, `exa` \u0026#8594; empty example)\n- [Flashcards](#anki): `fla` and `flA`\n- All above snippets support visual mode via the [selection key](#installation)\n\nMath snippets:\n- [Many shorthands](./lua/typstar/snippets/math.lua) for mathematical expressions\n- Series of numbered letters: `\u003cletter\u003e ot\u003coptional last index\u003e ` \u0026#8594; `\u003cletter\u003e_1, \u003cletter\u003e_2, ... ` (e.g. `a ot ` \u0026#8594; `a_1, a_2, ... `, `a ot4 ` \u0026#8594; `a_1, a_2, a_3, a_4 `, `alpha otk ` \u0026#8594; `alpha_1, alpha_2, ..., alpha_k `)\n- Wrapping of any mathematical expression (see [operations](./lua/typstar/snippets/visual.lua), works nested, multiline and in visual mode via the [selection key](#installation)): `\u003cexpression\u003e\u003coperation\u003e` \u0026#8594; `\u003coperation\u003e(\u003cexpression\u003e)` (e.g. `(a^2+b^2)rt` \u0026#8594; `sqrt(a^2+b^2)`, `lambdatd` \u0026#8594; `tilde(lambda)`, `(1+1)sQ` \u0026#8594; `[1+1]`, `(1+1)sq` \u0026#8594; `[(1+1)]`)\n- Simple functions: `fo\u003cvalue\u003e ` \u0026#8594; `f(\u003cvalue\u003e) ` (e.g. `fox ` \u0026#8594; `f(x) `, `ao5 ` \u0026#8594; `a(5) `)\n- Matrices: `\u003csize\u003ema` and `\u003csize\u003elma` (e.g. `23ma` \u0026#8594; 2x3 matrix)\n\nNote that you can [customize](#custom-snippets) (enable, disable and modify) every snippet.\n\n### Excalidraw/Rnote\n- Use `:TypstarInsertExcalidraw`/`:TypstarInsertRnote` to\n  create a new drawing using the [configured](#configuration) template,\n  insert a figure displaying it and open it in Obsidian/Rnote.\n- To open an inserted drawing in Obsidian/Rnote,\n  simply run `:TypstarOpenDrawing` (or `:TypstarOpenExcalidraw`/`:TypstarOpenRnote` if you are using the same file extension for both)\n  while your cursor is on a line referencing the drawing.\n\n### Anki\nUse the `flA` snippet to create a new flashcard\n```typst\n#flashcard(0, \"My first flashcard\")[\n  Typst is awesome $a^2+b^2=c^2$\n]\n```\nor the `fla` snippet to add a more complex front\n```typst\n#flashcard(0)[I love Typst $pi$][\n  This is the back of my second flashcard\n]\n```\n\nTo render the flashcard in your document as well add some code like this\n```typst\n#let flashcard(id, front, back) = {\n  strong(front)\n  [\\ ]\n  back\n}\n```\n\n- Add a comment like `// ANKI: MY::DECK` to your document to set a deck used for all flashcards after this comment (You can use multiple decks per file)\n- Add a file named `.anki` containing a deck name to define a default deck on a directory base\n- Add a file named `.anki.typ` to define a preamble on a directory base. You can find the default preamble [here](./src/anki/typst_compiler.py).\n- Tip: Despite the use of SVGs you can still search your flashcards in Anki as the typst source is added into an invisible html paragraph\n\n#### Neovim\n- Use `:TypstarAnkiScan` to scan the current nvim working directory and compile all flashcards in its context, unchanged files will be ignored\n- Use `:TypstarAnkiForce` to force compilation of all flashcards in the current working directory even if the files haven't changed since the last scan (e.g. on preamble change)\n- Use `:TypstarAnkiForceCurrent` to force compilation of all flashcards in the file currently edited\n- Use `:TypstarAnkiReimport` to also add flashcards that have already been asigned an id but are not currently\npresent in Anki\n- Use `:TypstarAnkiForceReimport` and `:TypstarAnkiForceCurrentReimport` to combine features accordingly\n\n#### Standalone\n- Run `typstar-anki --help` to show the available options\n\n\n## Installation\nInstall the plugin in Neovim (see [Nix instructions](#in-a-nix-flake-optional)) and run the plugin setup.\n```lua\nrequire('typstar').setup({ -- depending on your neovim plugin system\n   -- your typstar config goes here\n})\n```\n\n\u003cdetails\u003e\n\u003csummary\u003eExample lazy.nvim config\u003c/summary\u003e\n\n```lua\n{\n    \"arne314/typstar\",\n    dependencies = {\n        \"L3MON4D3/LuaSnip\",\n    },\n    ft = { \"typst\" },\n    keys = {\n        {\n            \"\u003cM-t\u003e\",\n            \"\u003cCmd\u003eTypstarToggleSnippets\u003cCR\u003e\",\n            mode = { \"n\", \"i\" },\n        },\n        {\n            \"\u003cM-j\u003e\",\n            \"\u003cCmd\u003eTypstarSmartJump\u003cCR\u003e\",\n            mode = { \"s\", \"i\" },\n        },\n        {\n            \"\u003cM-k\u003e\",\n            \"\u003cCmd\u003eTypstarSmartJumpBack\u003cCR\u003e\",\n            mode = { \"s\", \"i\" },\n        },\n    },\n    config = function()\n        local typstar = require(\"typstar\")\n        typstar.setup({\n            -- your typstar configuration\n            add_undo_breakpoints = true,\n        })\n    end,\n},\n{\n    \"L3MON4D3/LuaSnip\",\n    version = \"v2.*\",\n    build = \"make install_jsregexp\",\n    config = function()\n        local luasnip = require(\"luasnip\")\n        luasnip.config.setup({\n            enable_autosnippets = true,\n            store_selection_keys = \"\u003cTab\u003e\",\n        })\n    end,\n},\n{\n    \"nvim-treesitter/nvim-treesitter\",\n    build = \":TSUpdate\",\n    lazy = false,\n    config = function()\n        local configs = require(\"nvim-treesitter.configs\")\n        configs.setup({\n            ensure_installed = { \"typst\" },\n        })\n    end,\n},\n```\n\u003c/details\u003e\n\n### Snippets\n1. Install [LuaSnip](https://github.com/L3MON4D3/LuaSnip/), set `enable_autosnippets = true` and set a visual mode selection key (e.g. `store_selection_keys = '\u003cTab\u003e'`) in the configuration\n2. Install [jsregexp](https://github.com/kmarius/jsregexp) as described [here](https://github.com/L3MON4D3/LuaSnip/blob/master/DOC.md#transformations) (You will see a warning on startup if jsregexp isn't installed properly)\n3. Install [nvim-treesitter](https://github.com/nvim-treesitter/nvim-treesitter) and run `:TSInstall typst`\n4. Make sure you haven't remapped `\u003cC-g\u003e`. Otherwise set `add_undo_breakpoints = false` in the [config](#configuration)\n5. Optional: Setup [ctheorems](https://typst.app/universe/package/ctheorems/) with names like [here](./lua/typstar/snippets/markup.lua)\n\n### Excalidraw\n1. Install [Obsidian](https://obsidian.md/) and create a vault in your typst note taking directory\n2. Install the [obsidian-excalidraw-plugin](https://github.com/zsviczian/obsidian-excalidraw-plugin) and enable `Auto-export SVG` (in plugin settings at `Embedding Excalidraw into your Notes and Exporting \u003e Export Settings \u003e Auto-export Settings`)\n3. Have the `xdg-open` command working or set a different command at `uriOpenCommand` in the [config](#configuration)\n4. If you encounter issues with the file creation of drawings, try cloning the repo into `~/typstar` or setting the `typstarRoot` config accordingly; feel free to open an issue\n\n### Rnote\n1. Install [Rnote](https://github.com/flxzt/rnote?tab=readme-ov-file#installation); I recommend not using flatpak as that might cause issues with file permissions.\n2. Make sure `rnote-cli` is available in your `PATH` or set a different command at `exportCommand` in the [config](#configuration)\n3. Have the `xdg-open` command working with Rnote files or set a different command at `uriOpenCommand` in the [config](#configuration)\n4. See comment 4 above at Excalidraw\n\n### Anki\n0. Typst version `0.12.0` or higher is required\n1. Install [Anki](https://apps.ankiweb.net/#download)\n2. Install [Anki-Connect](https://ankiweb.net/shared/info/2055492159) and make sure `http://localhost` is added to `webCorsOriginList` in the Add-on config (should be added by default)\n3. Install the typstar python package (I recommend using [pipx](https://github.com/pypa/pipx) via `pipx install git+https://github.com/arne314/typstar`, you will need to have python build tools and clang installed) \\[Note: this may take a while\\]\n4. Make sure the `typstar-anki` command is available in your `PATH` or modify the `typstarAnkiCmd` option in the [config](#configuration)\n\n### In a Nix Flake (optional)\nYou can add typstar to your `nix-flake` like so\n```nix\n# `flake.nix`\ninputs = {\n  # ... other inputs\n  typstar = {\n    url = \"github:arne314/typstar\";\n    flake = false;\n  };\n}\n```\nNow you can use `typstar` in any package-set\n```nix\nwith pkgs; [\n  # ... other packges\n  (pkgs.vimUtils.buildVimPlugin {\n     name = \"typstar\";\n     src = inputs.typstar; \n     buildInputs = [\n        vimPlugins.luasnip \n        vimPlugins.nvim-treesitter-parsers.typst\n     ];\n  })\n]\n```\n\n## Configuration\nConfiguration options can be intuitively derived from the table [here](./lua/typstar/config.lua).\n\n### Excalidraw/Rnote templates\nThe `templatePath` option expects a table that maps file patterns to template locations.\nTo for example have a specific template for lectures, you could configure it like this\n```Lua\ntemplatePath = {\n    { 'lectures/.*%.excalidraw%.md$', '~/Templates/lecture_excalidraw.excalidraw.md' }, -- path contains \"lectures\"\n    { '%.excalidraw%.md$', '~/Templates/default_excalidraw.excalidraw.md' }, -- fallback\n},\n```\n\n### Custom snippets\nThe [config](#configuration) allows you to\n- disable all snippets via `snippets.enable = false`\n- only include specific modules from the snippets folder via e.g. `snippets.modules = { 'letters' }`\n- exclude specific triggers via e.g. `snippets.exclude = { 'dx', 'ddx' }`\n- disable different behaviors of snippets from the `visual` module\n    - visual selection via e.g. `snippets.visual_disable = { 'br' }`\n    - normal snippets (`abs` \u0026#8594; `abs(1+1)`) via e.g. `snippets.visual_disable_normal = { 'abs' }`\n    - postfix snippets (`xabs` \u0026#8594; `abs(x)`) via e.g. `snippets.visual_disable_postfix = { 'abs' }`\n\nFor further customization you can make use of the provided wrappers from within your [LuaSnip](https://github.com/L3MON4D3/LuaSnip/) config.\nLet's say you prefer the short `=\u003e` arrow over the long `==\u003e` one and would like to change the `ip` trigger to `imp`.\nYour `typstar` config could look like\n```lua\nrequire('typstar').setup({\n    snippets = {\n        exclude = { 'ip' },\n    },\n})\n```\nwhile your LuaSnip `typst.lua` could look like this (`\u003c` and `\u003e` require escaping as `\u003c\u003e` [introduces a new node](https://github.com/L3MON4D3/LuaSnip/blob/master/DOC.md#fmt))\n```lua\nlocal tp = require('typstar.autosnippets')\nlocal snip = tp.snip\nlocal math = tp.in_math\nlocal markup = tp.in_markup\n\nreturn {\n    -- add a new snippet (the old one is excluded via the config)\n    snip('imp', '=\u003e\u003e ', {}, math),\n\n    -- override existing triggers by setting a high priority\n    snip('ib', '\u003c\u003c= ', {}, math, 2000),\n    snip('iff', '\u003c\u003c=\u003e\u003e ', {}, math, 2000),\n\n    -- setup markup snippets accordingly\n    snip('IMP', '$=\u003e\u003e$ ', {}, markup, 2000),\n    snip('IFF', '$\u003c\u003c=\u003e\u003e$ ', {}, markup, 2000),\n}\n```\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Farne314%2Ftypstar","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Farne314%2Ftypstar","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Farne314%2Ftypstar/lists"}