diff options
author | Karl Berry <karl@freefriends.org> | 2009-06-23 00:14:43 +0000 |
---|---|---|
committer | Karl Berry <karl@freefriends.org> | 2009-06-23 00:14:43 +0000 |
commit | b3e52d29b04fed8c4f0a8695fbca2b113a36d4ad (patch) | |
tree | ec05ec4e73895011aa3a6e0e8ab038684e03baf9 /Master/texmf-dist/source/luatex | |
parent | aca03c9b6823255ebc3b94d81160eb3c6d85e80d (diff) |
new luatex package luamplib
git-svn-id: svn://tug.org/texlive/trunk@13901 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/texmf-dist/source/luatex')
-rw-r--r-- | Master/texmf-dist/source/luatex/luamplib/Makefile | 87 | ||||
-rw-r--r-- | Master/texmf-dist/source/luatex/luamplib/luamplib.dtx | 914 |
2 files changed, 1001 insertions, 0 deletions
diff --git a/Master/texmf-dist/source/luatex/luamplib/Makefile b/Master/texmf-dist/source/luatex/luamplib/Makefile new file mode 100644 index 00000000000..dd8a8eb40e7 --- /dev/null +++ b/Master/texmf-dist/source/luatex/luamplib/Makefile @@ -0,0 +1,87 @@ +# Makefile for luamplib + +NAME = luamplib +DOC = $(NAME).pdf +DTX = $(NAME).dtx + +# Files grouped by generation mode +COMPILED = $(DOC) +UNPACKED = luamplib-createmem.lua luamplib.lua luamplib.sty +SOURCE = $(DTX) README Makefile +GENERATED = $(COMPILED) $(UNPACKED) + +# Files grouped by installation location +RUNFILES = $(UNPACKED) +DOCFILES = $(DOC) README +SRCFILES = $(DTX) Makefile + +# The following definitions should be equivalent +# ALL_FILES = $(RUNFILES) $(DOCFILES) $(SRCFILES) +ALL_FILES = $(GENERATED) $(SOURCE) + +# Installation locations +FORMAT = luatex +RUNDIR = $(TEXMF)/tex/$(FORMAT)/$(NAME) +DOCDIR = $(TEXMF)/doc/$(FORMAT)/$(NAME) +SRCDIR = $(TEXMF)/source/$(FORMAT)/$(NAME) +TEXMF = ./texmf + +CTAN_ZIP = $(NAME).zip +TDS_ZIP = $(NAME).tds.zip +ZIPS = $(CTAN_ZIP) $(TDS_ZIP) + +DO_TEX = tex --interaction=batchmode $< >/dev/null +DO_PDFLATEX = pdflatex --interaction=batchmode $< >/dev/null + +all: $(GENERATED) +doc: $(COMPILED) +unpack: $(UNPACKED) +ctan: $(CTAN_ZIP) +tds: $(TDS_ZIP) +world: all ctan + +$(COMPILED): $(DTX) + $(DO_PDFLATEX) + $(DO_PDFLATEX) + +$(UNPACKED): $(DTX) + $(DO_TEX) + +$(CTAN_ZIP): $(SOURCE) $(COMPILED) $(TDS_ZIP) + @echo "Making $@ for CTAN upload." + @$(RM) -- $@ + @zip -9 $@ $^ >/dev/null + +define run-install +@mkdir -p $(RUNDIR) && cp $(RUNFILES) $(RUNDIR) +@mkdir -p $(DOCDIR) && cp $(DOCFILES) $(DOCDIR) +@mkdir -p $(SRCDIR) && cp $(SRCFILES) $(SRCDIR) +endef + +$(TDS_ZIP): TEXMF=./tmp-texmf +$(TDS_ZIP): $(ALL_FILES) + @echo "Making TDS-ready archive $@." + @$(RM) -- $@ + $(run-install) + @cd $(TEXMF) && zip -9 ../$@ -r . >/dev/null + @$(RM) -r -- $(TEXMF) + +.PHONY: install manifest clean mrproper + +install: $(ALL_FILES) + @echo "Installing in '$(TEXMF)'." + $(run-install) + +manifest: + @echo "Source files:" + @for f in $(SOURCE); do echo $$f; done + @echo "" + @echo "Derived files:" + @for f in $(GENERATED); do echo $$f; done + +clean: + @$(RM) -- *.log *.aux *.toc *.idx *.ind *.ilg + +mrproper: clean + @$(RM) -- $(GENERATED) $(ZIPS) + diff --git a/Master/texmf-dist/source/luatex/luamplib/luamplib.dtx b/Master/texmf-dist/source/luatex/luamplib/luamplib.dtx new file mode 100644 index 00000000000..70cb5399117 --- /dev/null +++ b/Master/texmf-dist/source/luatex/luamplib/luamplib.dtx @@ -0,0 +1,914 @@ +% \iffalse meta-comment +% +% Copyright (C) 2008-2009 by Hans Hagen, Taco Hoekwater and Elie Roux +% <elie.roux@telecom-bretagne.eu>. +% +% This work is under the CC0 license. +% +% This Current Maintainer of this work is Elie Roux. +% +% This work consists of the main source file luamplib.dtx +% and the derived files +% luamplib.sty, luamplib.lua, luamplib-createmem.lua and luamplib.pdf. +% +% +% Unpacking: +% tex luamplib.dtx +% +% Documentation: +% pdflatex luamplib.dtx +% +% The class ltxdoc loads the configuration file ltxdoc.cfg +% if available. Here you can specify further options, e.g. +% use A4 as paper format: +% \PassOptionsToClass{a4paper}{article} +% +% +%<*ignore> +\begingroup + \def\x{LaTeX2e}% +\expandafter\endgroup +\ifcase 0\ifx\install y1\fi\expandafter + \ifx\csname processbatchFile\endcsname\relax\else1\fi + \ifx\fmtname\x\else 1\fi\relax +\else\csname fi\endcsname +%</ignore> +%<*install> +\input docstrip.tex +\Msg{************************************************************************} +\Msg{* Installation} +\Msg{* Package: luamplib 2009/03/09 v1.01 metapost package for LuaTeX with luamplib.} +\Msg{************************************************************************} + +\keepsilent +\askforoverwritefalse + +\let\MetaPrefix\relax + +\preamble +This is a generated file. + +Copyright (C) 2008-2009 by Hans Hagen, Taco Hoekwater and Elie Roux +<elie.roux@telecom-bretagne.eu>. + +This work is under the CC0 license. + +This Current Maintainer of this work is Elie Roux. + +This work consists of the main source file luamplib.dtx +and the derived files + luamplib.sty, luamplib.lua, luamplib-createmem.lua and luamplib.pdf. + +\endpreamble + +\let\MetaPrefix\DoubleperCent + +\generate{% + \usedir{tex/luatex/mplib}% + \file{luamplib.sty}{\from{luamplib.dtx}{package}}% +} + +% The following hacks are to generate a lua file with lua comments starting by -- instead of %% + +\def\MetaPrefix{-- } + +\def\luapostamble{% + \MetaPrefix^^J% + \MetaPrefix\space End of File `\outFileName'.% +} + +\def\currentpostamble{\luapostamble}% + +\generate{% + \usedir{tex/luatex/mplib}% + \file{luamplib.lua}{\from{luamplib.dtx}{lua}}% + \file{luamplib-createmem.lua}{\from{luamplib.dtx}{gen-lua}}% +} + +\obeyspaces +\Msg{************************************************************************} +\Msg{*} +\Msg{* To finish the installation you have to move the following} +\Msg{* files into a directory searched by TeX:} +\Msg{*} +\Msg{* luamplib.sty luamplib.lua} +\Msg{*} +\Msg{* Happy TeXing!} +\Msg{*} +\Msg{************************************************************************} + +\endbatchfile +%</install> +%<*ignore> +\fi +%</ignore> +%<*driver> +\NeedsTeXFormat{LaTeX2e} +\ProvidesFile{luamplib.drv}% + [2009/03/09 v1.01 mplib package for LuaTeX.]% +\documentclass{ltxdoc} +\begin{document} + \DocInput{luamplib.dtx}% +\end{document} +%</driver> +% \fi +% +% \CheckSum{2} +% +% \CharacterTable +% {Upper-case \A\B\C\D\E\F\G\H\I\J\K\L\M\N\O\P\Q\R\S\T\U\V\W\X\Y\Z +% Lower-case \a\b\c\d\e\f\g\h\i\j\k\l\m\n\o\p\q\r\s\t\u\v\w\x\y\z +% Digits \0\1\2\3\4\5\6\7\8\9 +% Exclamation \! Double quote \" Hash (number) \# +% Dollar \$ Percent \% Ampersand \& +% Acute accent \' Left paren \( Right paren \) +% Asterisk \* Plus \+ Comma \, +% Minus \- Point \. Solidus \/ +% Colon \: Semicolon \; Less than \< +% Equals \= Greater than \> Question mark \? +% Commercial at \@ Left bracket \[ Backslash \\ +% Right bracket \] Circumflex \^ Underscore \_ +% Grave accent \` Left brace \{ Vertical bar \| +% Right brace \} Tilde \~} +% +% \title{The \textsf{luamplib} package} +% \date{2009/03/09 v1.01} +% \author{Hans Hagen, Taco Hoekwater and Elie Roux \\ \texttt{elie.roux@telecom-bretagne.eu}} +% +% \maketitle +% +% \begin{abstract} +% Package to have metapost code typeset directly in a document with Lua\TeX . +% \end{abstract} +% +% \section{Documentation} +% +% This packages aims at providing a simple way to typeset directly metapost code in a document with Lua\TeX . Lua\TeX\ is built with the lua \texttt{mplib} library, that runs metapost code. This package is basically a wrapper (in Lua) for the Lua \texttt{mplib} functions and some \TeX\ functions to have the output of the \texttt{mplib} functions in the pdf. +% +% The package need to be in PDF mode in order to output something, as PDF specials are not supported by the DVI format and tools. +% +% The metapost figures are put in a \TeX\ \texttt{hbox} with dimensions adjusted to the metapost code. +% +% The code is from the \texttt{supp-mpl.lua} and \texttt{supp-mpl.tex} files from Con\TeX t, they have been adapted to \LaTeX\ and Plain by Elie Roux. The changes are: +% +% \begin{itemize} +% \item a \LaTeX\ environment +% \item all \TeX\ macros start by \texttt{mplib} +% \item use of the luatextra printing and module functions +% \end{itemize} +% +% Using this package is easy: in Plain, type your metapost code between the macros \texttt{mplibcode} and \texttt{endmplibcode}, and in \LaTeX\ in the \texttt{mplibcode} environment. +% +% In order to use metapost, some \texttt{.mem} files are needed. These files must be generated with the same version of \texttt{mplib} as the version of Lua\TeX . These files names can be changed, they are by default \texttt{luatex-plain.mem} and \texttt{luatex-mpfun.mem}. If this package is to be included in a distribution, some values may have to be changed in the file \texttt{luamplib.lua}, see comments. +% +% +% If your distribution does not provide valid \texttt{.mem} files (\TeX Live 2009 will be the first), you'll have to generate and install them by hand, with the script \texttt{luamplib-createmem.lua} included in this package. +% +% \section{Files} +% +% This package contains three files: +% \begin{itemize} +% \item \texttt{luamplib.lua} containing the lua code that calls mplib +% \item \texttt{luamplib.sty} containing the macros for \LaTeX\ and Plain +% \item \texttt{create-mem.lua}, a standalone mem generation script +% \end{itemize} +% +% \iffalse +%<*lua> +% \fi +% +% \subsection{\texttt{luamplib.lua}} +% +% First the \texttt{luamplib} module is registered as a Lua\TeX\ module, with some informations. Here we can't name it \texttt{mplib}, as the name is already taken. +% +% \begin{macrocode} + +luamplib = { } + +luamplib.module = { + name = "luamplib", + version = 1.01, + date = "2009/03/09", + description = "Lua functions to typeset Metapost directly with MPLib.", + author = "Hans Hagen, Taco Hoekwater & Elie Roux", + copyright = "ConTeXt Development Team & Elie Roux", + license = "CC0", +} + +luatextra.provides_module(luamplib.module) + +% \end{macrocode} +% This module is a stripped down version of libraries that are used +% by Con\TeX t. +% \begin{macrocode} + +local format, concat, abs = string.format, table.concat, math.abs + +% \end{macrocode} +% +% The \texttt{mem} file and the format name are hardcoded, and they can be set with \TeX\ if it's useful. The \TeX\ distributions should change these values if necessary. +% +% \begin{macrocode} + +luamplib.currentformat = "plain" +luamplib.currentmem = "luatex-plain.mem" + +local currentformat = luamplib.currentformat +local currentmem = luamplib.currentmem + +function luamplib.setformat (name) + luamplib.currentformat = name +end + +function luamplib.setmemfile(name) + luamplib.currentmem = name +end + +% \end{macrocode} +% +% We use the \texttt{kpse} library unless a finder is already defined. To find the .mem files with kpse, we have to set the \texttt{engine} environment variable to \texttt{metapost}. +% +% \begin{macrocode} + +luamplib.finder = luamplib.finder or function(name, mode, ftype) + if mode == "w" then + return name + else + local result + if ftype == 'mem' then + local envsave = os.getenv('engine') + os.setenv('engine', 'metapost') + result = kpse.find_file(name,ftype) + os.setenv('engine', envsave) + else + result = kpse.find_file(name,ftype) + end + return result + end +end + +function luamplib.info (...) + luatextra.module_info('luamplib', format(...)) +end + +function luamplib.log (...) + luatextra.module_log('luamplib', format(...)) +end + +function luamplib.term (...) + luatextra.module_term('luamplib', format(...)) +end + +function luamplib.warning (...) + luatextra.module_warning('luamplib', format(...)) +end + +function luamplib.error (...) + luatextra.module_error('luamplib', format(...)) +end + +% \end{macrocode} +% +% This is a small hack for \LaTeX . In \LaTeX\ we read the metapost code line by line, but it needs to be passed entirely to \texttt{luamplib.process}, so we simply add the lines in \texttt{luamplib.data} and at the end we call \texttt{luamplib.process} on \texttt{luamplib.data}. +% +% \begin{macrocode} + +luamplib.data = "" + +function luamplib.resetdata() + luamplib.data = "" +end + +function luamplib.addline(line) + luamplib.data = luamplib.data .. '\n' .. line +end + +function luamplib.processlines() + luamplib.process(luamplib.data) + luamplib.resetdata() +end + + + +% \end{macrocode} +% +% +% \begin{macro}{luamplib.load} +% +% This function is the one loading the metapost format we want. It uses the \texttt{luamplib.currentformat} and \texttt{luamplib.currentmem} to determine the format and the mem file to use. +% +% The rest of this module is not documented. More info can be found in the +% Lua\TeX\ manual, articles in user group journals and the files that +% ship with Con\TeX t. +% +% \begin{macrocode} + +function luamplib.load() + local mpx = mplib.new { + ini_version = false, + mem_name = currentmem, + find_file = luamplib.finder + } + if mpx then + luamplib.log("using mem file %s", luamplib.finder(currentmem, 'r', 'mem')) + return mpx, nil + else + return nil, { status = 99, error = "out of memory or invalid format" } + end +end + +% \end{macrocode} +% +% \end{macro} +% +% \begin{macrocode} + +function luamplib.report(result) + if not result then + luamplib.error("no result object") + elseif result.status > 0 then + local t, e, l, f = result.term, result.error, result.log + if l then + luamplib.log(l) + end + if t then + luamplib.term(t) + end + if e then + if result.status == 1 then + luamplib.warning(e) + else + luamplib.error(e) + end + end + if not t and not e and not l then + if result.status == 1 then + luamplib.warning("unknown error, no error, terminal or log messages, maybe missing beginfig/endfig") + else + luamplib.error("unknown error, no error, terminal or log messages, maybe missing beginfig/endfig") + end + end + else + return true + end + return false +end + +function luamplib.process(data) + local converted, result = false, {} + local mpx = luamplib.load() + if mpx and data then + local result = mpx:execute(data) + if luamplib.report(result) then + if result.fig then + converted = luamplib.convert(result) + else + luamplib.warning("no figure output") + end + end + else + luamplib.error("Mem file unloadable. Maybe generated with a different version of mplib?") + end + return converted, result +end + +local function getobjects(result,figure,f) + return figure:objects() +end + +function luamplib.convert(result, flusher) + luamplib.flush(result, flusher) + return true -- done +end + +local function pdf_startfigure(n,llx,lly,urx,ury) + tex.sprint(format("\\mplibstarttoPDF{%s}{%s}{%s}{%s}",llx,lly,urx,ury)) +end + +local function pdf_stopfigure() + tex.sprint("\\mplibstoptoPDF") +end + +function pdf_literalcode(fmt,...) -- table + tex.sprint(format("\\mplibtoPDF{%s}",format(fmt,...))) +end + +function pdf_textfigure(font,size,text,width,height,depth) + text = text:gsub(".","\\hbox{%1}") -- kerning happens in metapost + tex.sprint(format("\\mplibtextext{%s}{%s}{%s}{%s}{%s}",font,size,text,0,-( 7200/ 7227)/65536*depth)) +end + +local bend_tolerance = 131/65536 + +local rx, sx, sy, ry, tx, ty, divider = 1, 0, 0, 1, 0, 0, 1 + +local function pen_characteristics(object) + if luamplib.pen_info then + local t = luamplib.pen_info(object) + rx, ry, sx, sy, tx, ty = t.rx, t.ry, t.sx, t.sy, t.tx, t.ty + divider = sx*sy - rx*ry + return not (sx==1 and rx==0 and ry==0 and sy==1 and tx==0 and ty==0), t.width + else + rx, sx, sy, ry, tx, ty, divider = 1, 0, 0, 1, 0, 0, 1 + return false, 1 + end +end + +local function concat(px, py) -- no tx, ty here + return (sy*px-ry*py)/divider,(sx*py-rx*px)/divider +end + +local function curved(ith,pth) + local d = pth.left_x - ith.right_x + if abs(ith.right_x - ith.x_coord - d) <= bend_tolerance and abs(pth.x_coord - pth.left_x - d) <= bend_tolerance then + d = pth.left_y - ith.right_y + if abs(ith.right_y - ith.y_coord - d) <= bend_tolerance and abs(pth.y_coord - pth.left_y - d) <= bend_tolerance then + return false + end + end + return true +end + +local function flushnormalpath(path,open) + local pth, ith + for i=1,#path do + pth = path[i] + if not ith then + pdf_literalcode("%f %f m",pth.x_coord,pth.y_coord) + elseif curved(ith,pth) then + pdf_literalcode("%f %f %f %f %f %f c",ith.right_x,ith.right_y,pth.left_x,pth.left_y,pth.x_coord,pth.y_coord) + else + pdf_literalcode("%f %f l",pth.x_coord,pth.y_coord) + end + ith = pth + end + if not open then + local one = path[1] + if curved(pth,one) then + pdf_literalcode("%f %f %f %f %f %f c",pth.right_x,pth.right_y,one.left_x,one.left_y,one.x_coord,one.y_coord ) + else + pdf_literalcode("%f %f l",one.x_coord,one.y_coord) + end + elseif #path == 1 then + -- special case .. draw point + local one = path[1] + pdf_literalcode("%f %f l",one.x_coord,one.y_coord) + end + return t +end + +local function flushconcatpath(path,open) + pdf_literalcode("%f %f %f %f %f %f cm", sx, rx, ry, sy, tx ,ty) + local pth, ith + for i=1,#path do + pth = path[i] + if not ith then + pdf_literalcode("%f %f m",concat(pth.x_coord,pth.y_coord)) + elseif curved(ith,pth) then + local a, b = concat(ith.right_x,ith.right_y) + local c, d = concat(pth.left_x,pth.left_y) + pdf_literalcode("%f %f %f %f %f %f c",a,b,c,d,concat(pth.x_coord, pth.y_coord)) + else + pdf_literalcode("%f %f l",concat(pth.x_coord, pth.y_coord)) + end + ith = pth + end + if not open then + local one = path[1] + if curved(pth,one) then + local a, b = concat(pth.right_x,pth.right_y) + local c, d = concat(one.left_x,one.left_y) + pdf_literalcode("%f %f %f %f %f %f c",a,b,c,d,concat(one.x_coord, one.y_coord)) + else + pdf_literalcode("%f %f l",concat(one.x_coord,one.y_coord)) + end + elseif #path == 1 then + -- special case .. draw point + local one = path[1] + pdf_literalcode("%f %f l",concat(one.x_coord,one.y_coord)) + end + return t +end + +% \end{macrocode} +% +% Support for specials in DVI has been removed. +% +% \begin{macrocode} + +function luamplib.flush(result,flusher) + if result then + local figures = result.fig + if figures then + for f=1, #figures do + luamplib.info("flushing figure %s",f) + local figure = figures[f] + local objects = getobjects(result,figure,f) + local fignum = tonumber((figure:filename()):match("([%d]+)$") or figure:charcode() or 0) + local miterlimit, linecap, linejoin, dashed = -1, -1, -1, false + local bbox = figure:boundingbox() + local llx, lly, urx, ury = bbox[1], bbox[2], bbox[3], bbox[4] -- faster than unpack + if urx < llx then + -- invalid + pdf_startfigure(fignum,0,0,0,0) + pdf_stopfigure() + else + pdf_startfigure(fignum,llx,lly,urx,ury) + pdf_literalcode("q") + if objects then + for o=1,#objects do + local object = objects[o] + local objecttype = object.type + if objecttype == "start_bounds" or objecttype == "stop_bounds" then + -- skip + elseif objecttype == "start_clip" then + pdf_literalcode("q") + flushnormalpath(object.path,t,false) + pdf_literalcode("W n") + elseif objecttype == "stop_clip" then + pdf_literalcode("Q") + miterlimit, linecap, linejoin, dashed = -1, -1, -1, false + elseif objecttype == "special" then + -- not supported + elseif objecttype == "text" then + local ot = object.transform -- 3,4,5,6,1,2 + pdf_literalcode("q %f %f %f %f %f %f cm",ot[3],ot[4],ot[5],ot[6],ot[1],ot[2]) + pdf_textfigure(object.font,object.dsize,object.text,object.width,object.height,object.depth) + pdf_literalcode("Q") + else + local cs = object.color + if cs and #cs > 0 then + pdf_literalcode(luamplib.colorconverter(cs)) + end + local ml = object.miterlimit + if ml and ml ~= miterlimit then + miterlimit = ml + pdf_literalcode("%f M",ml) + end + local lj = object.linejoin + if lj and lj ~= linejoin then + linejoin = lj + pdf_literalcode("%i j",lj) + end + local lc = object.linecap + if lc and lc ~= linecap then + linecap = lc + pdf_literalcode("%i J",lc) + end + local dl = object.dash + if dl then + local d = format("[%s] %i d",concat(dl.dashes or {}," "),dl.offset) + if d ~= dashed then + dashed = d + pdf_literalcode(dashed) + end + elseif dashed then + pdf_literalcode("[] 0 d") + dashed = false + end + local path = object.path + local transformed, penwidth = false, 1 + local open = path and path[1].left_type and path[#path].right_type + local pen = object.pen + if pen then + if pen.type == 'elliptical' then + transformed, penwidth = pen_characteristics(object) -- boolean, value + pdf_literalcode("%f w",penwidth) + if objecttype == 'fill' then + objecttype = 'both' + end + else -- calculated by mplib itself + objecttype = 'fill' + end + end + if transformed then + pdf_literalcode("q") + end + if path then + if transformed then + flushconcatpath(path,open) + else + flushnormalpath(path,open) + end + if objecttype == "fill" then + pdf_literalcode("h f") + elseif objecttype == "outline" then + pdf_literalcode((open and "S") or "h S") + elseif objecttype == "both" then + pdf_literalcode("h B") + end + end + if transformed then + pdf_literalcode("Q") + end + local path = object.htap + if path then + if transformed then + pdf_literalcode("q") + end + if transformed then + flushconcatpath(path,open) + else + flushnormalpath(path,open) + end + if objecttype == "fill" then + pdf_literalcode("h f") + elseif objecttype == "outline" then + pdf_literalcode((open and "S") or "h S") + elseif objecttype == "both" then + pdf_literalcode("h B") + end + if transformed then + pdf_literalcode("Q") + end + end + if cr then + pdf_literalcode(cr) + end + end + end + end + pdf_literalcode("Q") + pdf_stopfigure() + end + end + end + end +end + +function luamplib.colorconverter(cr) + local n = #cr + if n == 4 then + local c, m, y, k = cr[1], cr[2], cr[3], cr[4] + return format("%.3f %.3f %.3f %.3f k %.3f %.3f %.3f %.3f K",c,m,y,k,c,m,y,k), "0 g 0 G" + elseif n == 3 then + local r, g, b = cr[1], cr[2], cr[3] + return format("%.3f %.3f %.3f rg %.3f %.3f %.3f RG",r,g,b,r,g,b), "0 g 0 G" + else + local s = cr[1] + return format("%.3f g %.3f G",s,s), "0 g 0 G" + end +end +% \end{macrocode} +% +% \iffalse +%</lua> +% \fi +% +% \subsection{\texttt{luamplib.sty}} +% +% \iffalse +%<*package> +% \fi +% +% +% First we need to load fancyvrb, to define the environment mplibcode. +% +% \begin{macrocode} + +\expandafter\ifx\csname ProvidesPackage\endcsname\relax + \input luatextra.sty +\else + \NeedsTeXFormat{LaTeX2e} + \ProvidesPackage{luamplib} + [2009/03/09 v1.01 mplib package for LuaTeX.] + \RequirePackage{luatextra} + \RequirePackage{fancyvrb} +\fi + +% \end{macrocode} +% Loading of lua code. +% \begin{macrocode} + +\luaUseModule{luamplib} + +% \end{macrocode} +% +% +% +% There are (basically) two formats for metapost: \emph{plain} and \emph{mpfun}. The corresponding \texttt{.mem} files are (at least will be) \texttt{luatex-plain.mem} and \texttt{luatex-mpfun.mem} in \TeX Live. With these functions you can set the format and the mem files that will be used by this package. Warning: the package never generates the mem files, you have to do it by hand, with \texttt{create-mem.lua}. +% +% \begin{macrocode} + +\def\mplibsetformat#1{\directlua0{luamplib.setformat([[#1]])}} + +\def\mplibsetmemfile#1{\directlua0{luamplib.setmemfile([[#1]])}} + +% \end{macrocode} +% +% +% MPLib only works in PDF mode, we don't do anything if we are in DVI mode, and we output a warning. +% +% \begin{macrocode} + +\ifnum\pdfoutput>0 + \let\mplibtoPDF\pdfliteral +\else + %\def\MPLIBtoPDF#1{\special{pdf:literal direct #1}} % not ok yet + \def\mplibtoPDF#1{} + \expandafter\ifx\csname PackageWarning\endcsname\relax + \write16{} + \write16{Warning: MPLib only works in PDF mode, no figure will be output.} + \write16{} + \else + \PackageWarning{mplib}{MPLib only works in PDF mode, no figure will be output.} + \fi +\fi + +% \end{macrocode} +% +% The Plain-specific stuff. +% +% \begin{macrocode} + +\expandafter\ifx\csname ProvidesPackage\endcsname\relax + +\def\mplibsetupcatcodes{ + \catcode`\{=12 \catcode`\}=12 \catcode`\#=12 \catcode`\^=12 \catcode`\~=12 + \catcode`\_=12 \catcode`\%=12 \catcode`\&=12 \catcode`\$=12 +} + +\def\mplibcode{% + \bgroup % + \mplibsetupcatcodes % + \mplibdocode % +} + +\long\def\mplibdocode#1\endmplibcode{% + \egroup % + \mplibprocess{#1}% +} + +\long\def\mplibprocess#1{% + \luadirect{luamplib.process([[#1]])}% +} + +\else + +% \end{macrocode} +% The \LaTeX-specific parts. First a Hack for the catcodes in \LaTeX . +% \begin{macrocode} + +\makeatletter +\begingroup +\catcode`\,=13 +\catcode`\-=13 +\gdef\FV@hack{% + \def,{\string,}% + \def-{\string-}% +} +\endgroup + +% \end{macrocode} +% In \LaTeX\ (it's not the case in plain\TeX ), we get the metapost code line by line, here is the function handling a line. +% \begin{macrocode} + +\newcommand\mplibaddlines[1]{% + \begingroup % + \FV@hack % + \def\FV@ProcessLine##1{% + \luadirect{luamplib.addline([[##1]])}% + }% + \csname FV@SV@#1\endcsname % + \endgroup % +} + +\makeatother + +% \end{macrocode} +% The \LaTeX\ environment is a modified \texttt{verbatim} environment. +% \begin{macrocode} + +\newenvironment{mplibcode}{% + \VerbatimEnvironment % + \begin{SaveVerbatim}{memoire}% +}{% + \end{SaveVerbatim}% + \mplibaddlines{memoire}% + \luadirect{luamplib.processlines()}% +} + +\fi + +% \end{macrocode} +% We use a dedicated scratchbox. +% \begin{macrocode} + +\ifx\mplibscratchbox\undefined \newbox\mplibscratchbox \fi + +% \end{macrocode} +% We encapsulate the litterals. +% \begin{macrocode} + +\def\mplibstarttoPDF#1#2#3#4{ + \hbox\bgroup + \xdef\MPllx{#1}\xdef\MPlly{#2}% + \xdef\MPurx{#3}\xdef\MPury{#4}% + \xdef\MPwidth{\the\dimexpr#3bp-#1bp\relax}% + \xdef\MPheight{\the\dimexpr#4bp-#2bp\relax}% + \parskip0pt% + \leftskip0pt% + \parindent0pt% + \everypar{}% + \setbox\mplibscratchbox\vbox\bgroup + \noindent +} + +\def\mplibstoptoPDF{% + \egroup % + \setbox\mplibscratchbox\hbox % + {\hskip-\MPllx bp% + \raise-\MPlly bp% + \box\mplibscratchbox}% + \setbox\mplibscratchbox\vbox to \MPheight + {\vfill + \hsize\MPwidth + \wd\mplibscratchbox0pt% + \ht\mplibscratchbox0pt% + \dp\mplibscratchbox0pt% + \box\mplibscratchbox}% + \wd\mplibscratchbox\MPwidth + \ht\mplibscratchbox\MPheight + \box\mplibscratchbox + \egroup +} + +% \end{macrocode} +% Text items have a special handler. +% \begin{macrocode} + +\def\mplibtextext#1#2#3#4#5{% + \begingroup + \setbox\mplibscratchbox\hbox + {\font\temp=#1 at #2bp% + \temp + #3}% + \setbox\mplibscratchbox\hbox + {\hskip#4 bp% + \raise#5 bp% + \box\mplibscratchbox}% + \wd\mplibscratchbox0pt% + \ht\mplibscratchbox0pt% + \dp\mplibscratchbox0pt% + \box\mplibscratchbox + \endgroup +} + +% \end{macrocode} +% +% \iffalse +%</package> +% \fi +% +% \subsection{\texttt{luamplib-createmem.lua}} +% +% Finally a small standalone file to call with \texttt{texlua} that generates \texttt{luatex-plain.mem} in the current directory. To generate other formats in other names, simply change the last line. After the \texttt{mem} generation, you'll have to install it in a directory searchable by \TeX . +% +% \iffalse +%<*gen-lua> +% \fi +% \begin{macrocode} + +kpse.set_program_name("kpsewhich") + +function finder (name, mode, ftype) + if mode == "w" then + return name + else + local result = kpse.find_file(name,ftype) + return result + end +end + +local preamble = [[ +input %s ; dump ; +]] + +% \end{macrocode} +% \begin{macro}{makeformat} +% +% \begin{macrocode} + +makeformat = function (name, mem_name) + local mpx = mplib.new { + ini_version = true, + find_file = finder, + job_name = mem_name, + } + if mpx then + local result + result = mpx:execute(string.format(preamble,name)) + print(string.format("dumping format %s in %s", name, mem_name)) + mpx:finish() + end +end + +makeformat("plain", "luatex-plain.mem") + +% \end{macrocode} +% \end{macro} +% \iffalse +%</gen-lua> +% \fi +% \Finale +\endinput |