ntg-context - mailing list for ConTeXt users
 help / color / mirror / Atom feed
From: Max Chernoff <mseven@telus.net>
To: hdanielhixson@gmail.com
Cc: ntg-context@ntg.nl
Subject: [NTG-context] Re: Cite-proc Lua - Following up
Date: Wed, 12 Jun 2024 04:56:04 -0600	[thread overview]
Message-ID: <57507d1609bc8a927ebfd9b159f85c18f1881981.camel@telus.net> (raw)
In-Reply-To: <171810588944.1996.17716317259045887131@cgl.ntg.nl>

Hi,

On Tue, 2024-06-11 at 11:38 +0000, hdanielhixson@gmail.com wrote:
> There is a LaTeX package called citation-style-language, backed by
> some software called citeproc-lua. The github page for the software is
> here: https://github.com/zepinglee/citeproc-lua

> I'm just wondering if there is more news about its potential
> integration with Context.

A *very* quick and hacky implementation. First, clone the repository
plus all its submodules, then apply two small patches for Lua 5.5
compatibility:

    diff --git a/citeproc/citeproc-latex-core.lua b/citeproc/citeproc-latex-core.lua
    index 3057c5d..95c917a 100644
    --- a/citeproc/citeproc-latex-core.lua
    +++ b/citeproc/citeproc-latex-core.lua
    @@ -260,6 +260,7 @@ end
     local function parse_latex_seq(s)
       local t = {}
       for item in string.gmatch(s, "(%b{})") do
    +    local item = item
         item = string.sub(item, 2, -2)
         table.insert(t, item)
       end

    diff --git a/luaxml-mod-xml.lua b/luaxml-mod-xml.lua
    index d40b761..bf09830 100644
    --- a/luaxml-mod-xml.lua
    +++ b/luaxml-mod-xml.lua
    @@ -524,6 +524,7 @@ local function getAttributes(k,v)
       level = level or 0
       local spaces = string.rep(' ', level*2)
       for k,v in pairs(tb) do
    +    local k = k
         if type(v) ~= "table" then
           local ct = k
           if type(k)=="number" then

Then, install all the files somewhere where ConTeXt can find them. The
following layout seems to work:

    $ tree -a $TEXMFHOME
    /home/max/Projects/citeproc-lua/texmf/
    ├── scripts
    │   ├── citation-style-language -> ../../citeproc/
    │   └── lua-uca -> ../../submodules/lua-uca/src/lua-uca/
    └── tex
        ├── generic
        │   └── unicode-data -> ../../../submodules/unicode-data/
        ├── latex
        │   └── citation-style-language -> ../../../latex/
        └── luatex
            ├── lua-uni-algos -> ../../../submodules/lua-uni-algos/
            └── luaxml -> ../../../submodules/luaxml/

    12 directories, 0 files

Finally, make a new file somewhere in the "examples/" folder with the
following contents:

    \startluacode
        package.loaded.unicode = { utf8 = string }
        package.loaded.lualibs = {}
        kpse.find_file = function(name)
            local path = resolvers.findfile(name)
            if path == "" then
                path = nil
            end
            return path
        end

        local saved_require = require
        function require(name)
            return saved_require(name:gsub("^[^%.]+%.", ""))
        end

        require("util-jsn")

        local output = require("citeproc-output")
        local ConTeXtWriter = output.LatexWriter

        ConTeXtWriter.markups = {
            ["bibstart"] = [[\startitemize]],
            ["bibend"] = [[\stopitemize]],
            ["@font-style/normal"] = [[\normal{%s}]],
            ["@font-style/italic"] = [[\italic{%s}]],
            ["@font-style/oblique"] = [[\slanted{%s}]],
            ["@font-variant/normal"] = "[[\normal{%s}]]",
            ["@font-variant/small-caps"] = [[{\sc %s}]],
            ["@font-weight/normal"] = "[[\normal{%s}]]",
            ["@font-weight/bold"] = [[\bold{%s}]],
            ["@font-weight/light"] = "[[\normal{%s}]]",
            ["@text-decoration/none"] = false,
            ["@text-decoration/underline"] = [[\underline{%s}]],
            ["@vertical-align/sup"] = [[\high{%s}]],
            ["@vertical-align/sub"] = [[\low{%s}]],
            ["@vertical-align/baseline"] = false,
            ["@cite/entry"] = false,
            ["@bibliography/entry"] = [[\item %s]] .. "\n"
        }

        function ConTeXtWriter:write_escaped(str, context)
            return string.formatters["%!tex!"](str)
        end

        function ConTeXtWriter:write_link(inline, context)
            if inline.href == inline.value then
                -- URL
                return string.format([[\hyphenatedurl{%s}]], inline.value)
            elseif context.engine.opt.wrap_url_and_doi then
                return string.format([=[\goto{\hyphenatedurl{%s}}[url(%s)]]=], inline.href, self:write_escaped(inline.value, context))
            else
                return self:write_escaped(inline.value, context)
            end
        end

        local engine
        interfaces.implement {
            name = "cslinit",
            public = true,
            arguments = "2 strings",
            actions = function(style_name, bib_file)
                local citeproc = require("citeproc")
                local latex_core = require("citeproc-latex-core")
                local citeproc_sys = latex_core.make_citeproc_sys { bib_file }
                local style = latex_core.read_file(style_name .. ".csl")
                engine = citeproc.new(citeproc_sys, style)
                engine.output_format = ConTeXtWriter
            end
        }

        interfaces.implement {
            name = "cslcite",
            public = true,
            arguments = "string",
            actions = function(key)
                context(engine:makeCitationCluster { { id = key } })
            end
        }

        interfaces.implement {
            name = "cslbibliography",
            public = true,
            actions = function()
                local params, items = table.unpack(engine:makeBibliography())
                context(params.bibstart)
                for _, item in ipairs(items) do
                    context(item)
                end
                context(params.bibend)
            end
        }
    \stopluacode

    \cslinit{apa}{example.json}

    \starttext
        A \cslcite{ITEM-1} B \cslcite{ITEM-2} C \cslcite{ITEM-3} D \cslcite{ITEM-4}.

        \cslbibliography
    \stoptext

I've only tested this with the exact example from the README, so it will
probably break for anything even slightly more complex. Improving this
is left as an exercise for the reader :)

Thanks,
-- Max
___________________________________________________________________________________
If your question is of interest to others as well, please add an entry to the Wiki!

maillist : ntg-context@ntg.nl / https://mailman.ntg.nl/mailman3/lists/ntg-context.ntg.nl
webpage  : https://www.pragma-ade.nl / https://context.aanhet.net (mirror)
archive  : https://github.com/contextgarden/context
wiki     : https://wiki.contextgarden.net
___________________________________________________________________________________

      reply	other threads:[~2024-06-12 10:59 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-06-11 11:38 [NTG-context] " hdanielhixson
2024-06-12 10:56 ` Max Chernoff [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=57507d1609bc8a927ebfd9b159f85c18f1881981.camel@telus.net \
    --to=mseven@telus.net \
    --cc=hdanielhixson@gmail.com \
    --cc=ntg-context@ntg.nl \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).