@@ -2310,6 +2310,7 @@ these types:
23102310- Planning keywords (=DEADLINE=, =SCHEDULED=, =CLOSED=)
23112311- Orgfile special keywords (=#+TITLE=, =#+BEGIN_SRC=, =#+ARCHIVE=, etc.)
23122312- Hyperlinks (=* - headlines=, =# - headlines with CUSTOM_ID property=, =headlines matching title=)
2313+ - Citation keys (inside =[cite:...]= blocks after =@=)
23132314
23142315Autocompletion is context aware, which means that for example
23152316tags autocompletion will kick in only when cursor is at the end of
@@ -2539,6 +2540,159 @@ require('orgmode').setup({
25392540})
25402541#+end_src
25412542
2543+ *** Citations
2544+ :PROPERTIES:
2545+ :CUSTOM_ID: citations
2546+ :END:
2547+ Orgmode supports [[https://orgmode.org/manual/Citation-handling.html][Org 9.5 citations]] using the =[cite:@key]= syntax.
2548+ For example:
2549+
2550+ #+begin_src org
2551+ See [cite:@smith2020] for details, or [cite/t:@jones2021;@doe2022] for a
2552+ textual citation.
2553+ #+end_src
2554+
2555+ The citation key under the cursor can be followed to its bibliography entry
2556+ using the same =org_open_at_point= mapping (=<Leader>oo= by default) that is
2557+ used for hyperlinks.
2558+
2559+ Citation key autocompletion is provided via the standard =omnifunc= (triggered
2560+ by =<C-x><C-o>= in insert mode). Completion is active inside any =[cite:...]=
2561+ or =[cite/style:...]=, after the =@= character.
2562+
2563+ **** Bibliography files
2564+ :PROPERTIES:
2565+ :CUSTOM_ID: citations-bibliography-files
2566+ :END:
2567+ The built-in BibTeX source reads citation keys from =.bib= files. Two
2568+ discovery mechanisms are available (both can be used simultaneously):
2569+
2570+ ***** Global bibliography
2571+ :PROPERTIES:
2572+ :CUSTOM_ID: org_cite_global_bibliography
2573+ :END:
2574+ Set =citations.org_cite_global_bibliography= to a path or list of paths that
2575+ are always searched, regardless of which file is open:
2576+
2577+ #+begin_src lua
2578+ require('orgmode').setup({
2579+ citations = {
2580+ org_cite_global_bibliography = {
2581+ '~/references/global.bib',
2582+ '~/references/books.bib',
2583+ },
2584+ },
2585+ })
2586+ #+end_src
2587+
2588+ A single string is also accepted:
2589+
2590+ #+begin_src lua
2591+ require('orgmode').setup({
2592+ citations = {
2593+ org_cite_global_bibliography = '~/references/global.bib',
2594+ },
2595+ })
2596+ #+end_src
2597+
2598+ ***** File-local bibliography
2599+ :PROPERTIES:
2600+ :CUSTOM_ID: citations-file-local-bibliography
2601+ :END:
2602+ Any =.org= file can declare its own bibliography with one or more
2603+ =#+bibliography:= directives. Paths are resolved relative to the org file:
2604+
2605+ #+begin_src org
2606+ #+bibliography: refs.bib
2607+ #+bibliography: /absolute/path/to/extra.bib
2608+
2609+ * Introduction
2610+ See [cite:@smith2020] for background.
2611+ #+end_src
2612+
2613+ **** Custom citation sources
2614+ :PROPERTIES:
2615+ :CUSTOM_ID: citations-custom-sources
2616+ :END:
2617+ Additional citation sources can be registered via =citations.sources=. Each
2618+ source is a table (or object) that implements the =OrgCitationSource=
2619+ interface:
2620+
2621+ - =get_name()= (required) — return a unique name string for the source.
2622+ - =get_items()= (required) — return a list of =OrgCitationItem= tables.
2623+ Each item must have a =key= field, and may optionally have =label= and
2624+ =description= fields used in completion menus.
2625+ - =follow(key)= (optional) — navigate to the entry for =key=; return =true=
2626+ if handled, =false= to fall through to the next source.
2627+
2628+ #+begin_src lua
2629+ require('orgmode').setup({
2630+ citations = {
2631+ sources = {
2632+ {
2633+ get_name = function() return 'my_source' end,
2634+ get_items = function()
2635+ return {
2636+ { key = 'smith2020', description = 'Smith et al. 2020' },
2637+ { key = 'jones2021' },
2638+ }
2639+ end,
2640+ follow = function(self, key)
2641+ vim.notify('Citation: ' .. key)
2642+ return true
2643+ end,
2644+ },
2645+ },
2646+ },
2647+ })
2648+ #+end_src
2649+
2650+ ***** Example: Zotero Local API
2651+ :PROPERTIES:
2652+ :CUSTOM_ID: citations-zotero-local-api
2653+ :END:
2654+ [[https://www.zotero.org][Zotero]] exposes a local HTTP API on =http://localhost:23119= (requires the
2655+ Zotero desktop application to be running). The example below defines a
2656+ custom source that queries the local API for all library items and exposes
2657+ their citation keys for completion.
2658+ #+begin_src lua
2659+ local ZoteroSource = {}
2660+
2661+ function ZoteroSource:get_name()
2662+ return 'zotero'
2663+ end
2664+
2665+ function ZoteroSource:get_items()
2666+ -- Replace 0 with your numeric Zotero user ID if needed.
2667+ local url = 'http://localhost:23119/api/users/0/items?format=json'
2668+ local ok, result = pcall(vim.fn.system, { 'curl', '-s', url })
2669+ if not ok or vim.v.shell_error ~= 0 then
2670+ return {}
2671+ end
2672+ local data = vim.json.decode(result or '') or {}
2673+ local items = {}
2674+ for _, entry in ipairs(data) do
2675+ local d = entry.data or {}
2676+ if d.citationKey then
2677+ local creators = d.creators or {}
2678+ local author = (creators[1] or {}).lastName or ''
2679+ local year = (d.date or ''):match('%d%d%d%d') or ''
2680+ table.insert(items, {
2681+ key = d.citationKey,
2682+ description = author .. year .. ' ' .. (d.title or ''),
2683+ })
2684+ end
2685+ end
2686+ return items
2687+ end
2688+
2689+ require('orgmode').setup({
2690+ citations = {
2691+ sources = { ZoteroSource },
2692+ },
2693+ })
2694+ #+end_src
2695+
25422696*** Notifications
25432697:PROPERTIES:
25442698:CUSTOM_ID: notifications
0 commit comments