1if not modules then modules = { } end modules ['mtx-metapost'] = {
2 version = 0.100,
3 comment = "companion to mtxrun.lua",
4 author = "Taco Hoekwater & Hans Hagen",
5 copyright = "ConTeXt Development Team",
6 license = "see context related readme files"
7}
8
9
10
11local helpinfo = [[
12<?xml version="1.0"?>
13<application>
14 <metadata>
15 <entry name="name">mtx-metapost</entry>
16 <entry name="detail">MetaPost to PDF processor</entry>
17 <entry name="version">0.10</entry>
18 </metadata>
19 <flags>
20 <category name="basic">
21 <subcategory>
22 <flag name="rawmp"><short>raw metapost run</short></flag>
23 <flag name="metafun"><short>use metafun instead of plain</short></flag>
24 <flag name="latex"><short>force <ref name="tex=latex"/></short></flag>
25 <flag name="texexec"><short>force texexec usage (mkii)</short></flag>
26 <flag name="split"><short>split single result file into pages</short></flag>
27 </subcategory>
28 </category>
29 </flags>
30 <examples>
31 <category>
32 <title>Examples</title>
33 <subcategory>
34 <example><command>mtxrun --script metapost yourfile.mp</command></example>
35 <example><command>mtxrun --script metapost --split yourfile.mp</command></example>
36 <example><command>mtxrun --script metapost yourfile.123 myfile.mps</command></example>
37 </subcategory>
38 </category>
39 </examples>
40 <comments>
41 <comment>other usage resembles mptopdf.pl</comment>
42 </comments>
43</application>
44]]
45
46local application = logs.application {
47 name = "mtx-metapost",
48 banner = "MetaPost to PDF processor 0.10",
49 helpinfo = helpinfo,
50}
51
52local report = application.report
53
54scripts = scripts or { }
55scripts.mptopdf = scripts.mptopdf or { }
56scripts.mptopdf.aux = scripts.mptopdf.aux or { }
57
58local format, find, gsub = string.format, string.find, string.gsub
59
60local function assumes_latex(filename)
61 local d = io.loaddata(filename) or ""
62 return find(d,"\\documentstyle") or find(d,"\\documentclass") or find(d,"\\begin{document}")
63end
64
65local basemaps = "original-base.map,original-ams-base.map,original-ams-euler.map,original-public-lm.map"
66
67local wrapper = "\\starttext\n%s\n%s\\stoptext"
68local loadmap = "\\loadmapfile[%s]\n"
69local template = "\\startTEXpage\n\\convertMPtoPDF{%s}{1}{1}\n\\stopTEXpage"
70local texified = "\\starttext\n%s\n\\stoptext"
71local splitter = "\\startTEXpage\\externalfigure[%s][page=%s]\\stopTEXpage"
72local tempname = "mptopdf-temp.tex"
73
74local function do_mapfiles(mapfiles)
75 local maps = { }
76 for i=1,#mapfiles do
77 local mapfile = mapfiles[i]
78 application.report("using map file %a",mapfile)
79 maps[i] = format(loadmap,mapfile)
80 end
81 return table.concat(maps)
82end
83
84local function do_convert(filename,mapfiles)
85 if find(filename,".%d+$") or find(filename,"%.mps$") then
86 local body = format(template,filename)
87 local maps = do_mapfiles(mapfiles)
88 io.savedata(tempname,format(wrapper,maps,body))
89 local resultname = format("%s-%s.pdf",file.nameonly(filename),file.suffix(filename))
90 local result = os.execute(format([[context --once --batch --purge --result=%s "%s"]],resultname,tempname))
91 return lfs.isfile(resultname) and resultname
92 end
93end
94
95local function do_split(filename,numbers,mapfiles)
96 local name = file.nameonly(filename)
97 local maps = do_mapfiles(mapfiles)
98 for i=1,#numbers do
99 local body = format(splitter,file.addsuffix(name,"pdf"),i)
100 io.savedata(tempname,format(wrapper,maps,body))
101 local resultname = format("%s-%s.pdf",name,numbers[i])
102 local result = os.execute(format([[context --once --batch --purge --result=%s "%s"]],resultname,tempname))
103 end
104end
105
106local function do_texify(str)
107
108
109
110 local numbers = { }
111 str = "\\startMPinclusions\n".. str .. "\n\\stopMPinclusions"
112 str = gsub(str,"beginfig%s*%(%s*(.-)%s*%)%s*;%s*",function(s)
113 numbers[#numbers+1] = tonumber(s) or 0
114 return "\n\\stopMPinclusions\n\\startMPpage\n"
115 end)
116 str = gsub(str,"%s*endfig%s*;%s*","\n\\stopMPpage\n\\startMPinclusions\n")
117 str = gsub(str,"\\startMPinclusions%s*\\stopMPinclusions","")
118 str = gsub(str,"[\n\r]+","\n")
119 return format(texified,str), numbers
120end
121
122local function do_convert_all(filename,mapfiles)
123 local results = dir.glob(file.nameonly(filename) .. ".*")
124 local report = { }
125 for i=1,#results do
126 local filename = results[i]
127 local resultname = do_convert(filename,mapfiles)
128 if resultname then
129 report[#report+1] = { filename, resultname }
130 end
131 end
132 if #report > 0 then
133 report("number of converted files: %i", #report)
134 report()
135 for i=1,#report do
136 local r = report[i]
137 report("%s => %s", r[1], r[2])
138 end
139 else
140 report("no files are converted for '%s'",filename)
141 end
142end
143
144local function do_convert_one(filename,mapfiles)
145 local resultname = do_convert(filename,mapfiles)
146 if resultname then
147 report("%s => %s", filename,resultname)
148 else
149 report("no result for '%s'",filename)
150 end
151end
152
153function scripts.mptopdf.convertall()
154 local rawmp = environment.arguments.rawmp or false
155 local metafun = environment.arguments.metafun or false
156 local latex = environment.arguments.latex or false
157 local pattern = environment.arguments.pattern or false
158 local split = environment.arguments.split or false
159 local files = pattern and dir.glob(file.nameonly(filename)) or environment.files
160 local mapfiles = utilities.parsers.settings_to_array(environment.arguments.mapfiles or basemaps)
161 if #files > 0 then
162 for i=1,#files do
163 local filename = files[i]
164 if file.suffix(filename) == "mp" then
165 local command, convert, texdata, numbers
166 if rawmp then
167 if metafun then
168 command, convert = format("mpost --progname=mpost --mem=metafun %s",filename), true
169 else
170 command, convert = format("mpost --mem=mpost %s",filename), true
171 end
172 else
173 if latex or assumes_latex(filename) then
174 command, convert = format("mpost --mem=mpost --tex=latex %s",filename), true
175 elseif texexec then
176 command, convert = format("texexec --mptex %s",filename), true
177 else
178 texdata, numbers = do_texify(io.loaddata(filename) or "")
179 io.savedata(tempname,texdata)
180 command, convert = format("context --result=%s --purge --once %s",file.nameonly(filename),tempname), false
181 end
182 end
183 report("running: %s",command)
184 local done = os.execute(command)
185 if done then
186 if convert then
187 do_convert_all(filename,mapfiles)
188 elseif split then
189 do_split(filename,numbers,mapfiles)
190
191 end
192 else
193 report("error while processing mp file '%s'", filename)
194 end
195 else
196 do_convert_one(filename,mapfiles)
197 end
198 end
199 else
200 report("no files match to process")
201 end
202end
203
204if environment.argument("exporthelp") then
205 application.export(environment.argument("exporthelp"),environment.files[1])
206elseif environment.files[1] then
207 scripts.mptopdf.convertall()
208else
209 if not environment.argument("help") then
210 report("provide MP output file (or pattern)")
211 report()
212 end
213 application.help()
214end
215 |