我正在使用Makefile和GNU make来创建基于源Markdown文件的各种文档输出目标。
这包括使用latex
或pdflatex
创建DVI文件。使用EPS或PS格式以外的图像会导致错误。
我可以在源markdown文件中搜索和替换图像名称,并且已经这样做了。
我想要做的是为images/
子目录中的所有图像文件创建一个makefile规则,并运行convert
来创建这些文件的eps版本。
所以:
images/myimage1.png
images/myimage2.jpeg
保留,但已创建其他版本:
images/myimage1.eps
images/myimage2.eps
(是的,我必须跟踪其他地方没有名称冲突。)
要运行的命令类似于:
convert -format eps images/myimage1.png images/myimage1.eps
我想在任何非EPS图片文件上运行:gif,jpg,jpeg,png,bmp等。这些将在Makefile中明确列出。
它有效(模数为其他错误),虽然它有点长,如果扩展 Imagemagick支持的完整193种图形格式将是...... unweildy。
我的目标是建立DVI,所以我展示了相关的目标
dvi: docfs-Manifesto.dvi
latex: docfs-Manifesto.tex
epsimg.md: docfs-Manifesto.md
docfs-Manifesto.tex: docfs-Manifesto-epsimg.md all-img
pandoc -s --from=markdown --to=latex -o docfs-Manifesto.tex docfs-Manifesto-epsimg.md
docfs-Manifesto-epsimg.md: docfs-Manifesto.md
./img-ref-to-eps.sed docfs-Manifesto.md > docfs-Manifesto-epsimg.md
docfs-Manifesto.dvi: latex
pdflatex -output-format dvi -halt-on-error docfs-Manifesto.tex 2>pdflatex.log
MG_DIR=images
EPS_DIR=images-eps
# We can handle any of about 193 formats Imagemagick will read, but
# let's start with some basics
# ... Source formats
SRC_GIF = $(wildcard $(IMG_DIR)/*.gif)
SRC_JPG = $(wildcard $(IMG_DIR)/*.jpg)
# ... Destination formats
EPS_GIF = $(patsubst $(IMG_DIR)/%.gif,$(EPS_DIR)/%.eps,$(SRC_GIF))
EPS_JPG = $(patsubst $(IMG_DIR)/%.jpg,$(EPS_DIR)/%.eps,$(SRC_JPG))
# And the actual conversions. This ... could be shorter?
all-img: $(EPS_DIR) $(EPS_GIF) $(EPS_JPG)
@echo "Done"
$(EPS_DIR) :
mkdir $(EPS_DIR)
$(EPS_DIR)/%.eps : $(IMG_DIR)/%.gif
convert -format eps $< $@
$(EPS_DIR)/%.eps : $(IMG_DIR)/%.jpg
convert -format eps $< $@
(我认为这是所有相关规则)
它成功了,因为它失败了一个图像我的转换脚本 没能转换。
但这不是Make的错。
我们得到了它! 77行代码减少到17行(包括空格)。
IMG_DIR=images
EPS_DIR=images-eps
# We can handle any of about 193 formats Imagemagick will read, but
# let's start with some basics
# Thanks @kebs: https://stackoverflow.com/a/47857821/9105048
IMG_EXT=bmp dot gif jpg jpeg png raw tiff xcf pnm ppm ps
# ... Source formats
IMG_FILES = $(wildcard $(IMG_DIR)/*)
# Rename files s/./_/ so: img1.gif => img1_gif Then add extension
IMG_FILES2 = $(subst .,_,$(IMG_FILES))
EPS_FILES = $(patsubst $(IMG_DIR)/%,$(EPS_DIR)/%.eps,$(IMG_FILES2))
all-img: $(EPS_DIR) $(EPS_FILES)
@echo "all-img: done"
$(EPS_DIR) :
mkdir $(EPS_DIR)
$(foreach \
prereq, \
$(IMG_EXT), \
$(eval $(EPS_DIR)/%_$(prereq).eps: $(IMG_SRC)/%.$(prereq); convert -format eps $$< $$@) \
)
当前输出(make clean
之后):
$ make all-img
convert -format eps images/browser-of-a-scientist.jpg images-eps/browser-of-a-scientist_jpg.eps
convert -format eps images/nukewaste.jpg images-eps/nukewaste_jpg.eps
convert -format eps images/standards.png images-eps/standards_png.eps
$ ls images-eps/
browser-of-a-scientist_jpg.eps standards_png.eps
nukewaste_jpg.eps
答案 0 :(得分:1)
尝试这样的事情:
SRC_DIR=images
SRC_FILES1 = $(wildcard $(SRC_DIR)/*.png)
SRC_FILES2 = $(wildcard $(SRC_DIR)/*.jpeg)
DEST_FILES1 = $(patsubst $(SRC_DIR)/%.png,$(SRC_DIR)/%.eps,$(SRC_FILES1))
DEST_FILES2 = $(patsubst $(SRC_DIR)/%.jpeg,$(SRC_DIR)/%.eps,$(SRC_FILES2))
all: $(DEST_FILES1) $(DEST_FILES2)
@echo "Done"
$(SRC_DIR)/%.eps : $(SRC_DIR)/%.png
convert -format eps $< $@
$(SRC_DIR)/%.eps : $(SRC_DIR)/%.jpeg
convert -format eps $< $@
但是,如果您同时拥有image1.png
和image1.jpeg
,则会失败。
要处理其他图像类型,您需要复制其他图像类型的规则和变量。但我认为如果你在另一个文件夹中构建eps文件可以避免这种情况(推荐使用BTW,它被称为“out of source”版本,主要的想法是你不要在同一个文件夹中混合源文件和构建文件)。如果你这样做,我认为你可以设法只有一个变量和构建规则。
编辑好的,我想我有一个解决方案可以简化所有这些:
首先,定义一个包含所有所需文件类型的变量(读取:扩展名):
EXT=gif png jpg jpeg
然后,构建一个包含所有图像的变量(假设此处只有图像,这是请求的):
SRC_FILES = $(wildcard $(SRC_DIR)/*)
然后我们需要构建包含所有输入文件的相应目标变量,但扩展名为.eps。我们无法直接使用patsubst
,因为它无法继续使用倍数扩展。所以我们需要一个技巧:将img1.gif
替换为img1_gif
,然后添加.eps扩展名。这分两步完成:
首先,在输入文件中将.
替换为_
:
DEST1 = $(subst .,_,$(SRC_FILES))
其次,添加.eps扩展名(假设输出文件夹为out
):
DEST2 = $(patsubst $(SRC_DIR)/%,out/%.eps,$(DEST1))
好的,现在我们完成了:
all: $(DEST2)
@echo "Done"
嗯,不太好。最后一招是:使用foreach
函数自动生成EXT
变量所需的所有食谱:
$(foreach \
prereq, \
$(EXT), \
$(eval out/%_$(prereq).eps: $(SRC_DIR)/%.$(prereq); convert -format eps $$< $$@) \
)
这会在prereq
EXT
中显示所有值,并调用eval
函数生成配方。