lualatex / luamplib

generic TeX package - including MetaPost code in LuaTeX documents
http://ctan.org/pkg/luamplib
14 stars 11 forks source link

Named MetaPost instances #99

Closed jemmybutton closed 2 years ago

jemmybutton commented 2 years ago

In some cases it may be useful to have several named MetaPost instances which can be referred to independently from LaTeX (similar to what ConTeXt offers). As far as I understand, currently, this can't be achieved using luamplib? The interface could look something like:

\begin[instance_name]{mplibcode}
...
\end{mplibcode}

(see also this) My naïve attempt at implementing a minimal workaround does seem to work ok:

local function process_mplibcode_alt (data, instanceName)
  legacy_mplibcode_reset()

  local everymplib    = texgettoks'everymplibtoks'    or ''
  local everyendmplib = texgettoks'everyendmplibtoks' or ''
  data = format("\n%s\n%s\n%s\n",everymplib, data, everyendmplib)
  data = data:gsub("\r","\n")

  data = data:gsub("\\mpcolor%s+(.-%b{})","mplibcolor(\"%1\")")
  data = data:gsub("\\mpdim%s+(%b{})", "mplibdimen(\"%1\")")
  data = data:gsub("\\mpdim%s+(\\%a+)","mplibdimen(\"%1\")")

  data = data:gsub(btex_etex, function(str)
    return format("btex %s etex ", -- space
      luamplib.verbatiminput and str or protect_expansion(str))
  end)
  data = data:gsub(verbatimtex_etex, function(str)
    return format("verbatimtex %s etex;", -- semicolon
      luamplib.verbatiminput and str or protect_expansion(str))
  end)

  if not luamplib.verbatiminput then
    data = data:gsub("\".-\"", protect_expansion)

    data = data:gsub("\\%%", "\0PerCent\0")
    data = data:gsub("%%.-\n","")
    data = data:gsub("%zPerCent%z", "\\%%")

    run_tex_code(format("\\mplibtmptoks\\expanded{{%s}}",data))
    data = texgettoks"mplibtmptoks"
    data = data:gsub("##", "#")
    data = data:gsub("\".-\"", unprotect_expansion)
    data = data:gsub(btex_etex, function(str)
      return format("btex %s etex", unprotect_expansion(str))
    end)
    data = data:gsub(verbatimtex_etex, function(str)
      return format("verbatimtex %s etex", unprotect_expansion(str))
    end)
  end

  process_alt(data, instanceName)
end
...
local function process_alt (data, instanceName)
  local standalone = not luamplib.codeinherit
  local currfmt = instanceName or currentformat .. (luamplib.numbersystem or "scaled")
    .. tostring(luamplib.textextlabel) .. tostring(luamplib.legacy_verbatimtex)
  local mpx = mplibinstances[currfmt]
  if mpx and standalone then
    mpx:finish()
  end
  if standalone or not mpx then
    mpx = luamplibload(currentformat)
    mplibinstances[currfmt] = mpx
  end
  return process_indeed(mpx, data)
end
\directlua{luamplib.codeinherit = true}
\directlua{luamplib.process_mplibcode_alt([===[beginfig(1);a := 1cm;draw fullcircle scaled a;endfig;]===],"instance_a")}
\directlua{luamplib.process_mplibcode_alt([===[beginfig(1);a := 2cm;draw fullcircle scaled a;endfig;]===],"instance_b")}
\directlua{luamplib.process_mplibcode_alt([===[beginfig(1);draw unitsquare scaled a;endfig;]===],"instance_a")}
\directlua{luamplib.process_mplibcode_alt([===[beginfig(1);draw unitsquare scaled a;endfig;]===],"instance_b")}

image

But I'm sure it may break something elsewhere.

jemmybutton commented 2 years ago

I modified .sty and .lua files to work as described: luamplib_with_named_instances.zip

The following:

\mplibcodeinherit{enable}

\begin{mplibcode} % no instance name
beginfig(1);
a := 1/2cm;
draw fullcircle scaled a;
endfig;
\end{mplibcode}

\begin{mplibcode}[instance_one]
beginfig(1);
a := 1cm;
draw fullcircle scaled a;
endfig;
\end{mplibcode}

\begin{mplibcode}[instance_two]
beginfig(1);
a := 2cm;
draw fullcircle scaled a;
endfig;
\end{mplibcode}

\begin{mplibcode} % no instance name
beginfig(1);
draw unitsquare scaled a;
endfig;
\end{mplibcode}

\begin{mplibcode}[instance_one]
beginfig(1);
draw unitsquare scaled a;
endfig;
\end{mplibcode}

\begin{mplibcode}[instance_two]
beginfig(1);
draw unitsquare scaled a;
endfig;
\end{mplibcode}

produces this: image

I didn't test it thoroughly though.

dohyunkim commented 2 years ago

Thanks for the suggestion. Would you please make a PR?

jemmybutton commented 2 years ago

@dohyunkim Sure! Done.

dohyunkim commented 2 years ago

Thank you so much. A new version based on your contribution has just been sent to CTAN.