在Pandoc makefile中,Bash文件重定向而不是字符串解释



简介

我开始使用Pandocmarkdown为我的个人网站生成静态XHTML。我设法使用Pandoc-B参数自动插入了几个引用.md文件的$(NAME)的链接(请参见下面的makefile)。这个Pandoc-B参数实际上是为了包含一个文件名而设计的,所以除了shell解释之外,我还必须使用echo命令的输出重定向。

问题

Pandoc-B自变量太长,无法在makefile中轻松维护。我想将XHTML字符串移回一个单独的文件,同时保留Bash字符串的解释。cat命令不会执行此操作,因为它不是Bash的一部分。

SHELL := /bin/bash
NAME  = $(basename $(wildcard *.md))
all: index.html
html: index.html
index.html: $(NAME).md
pandoc $< -S -o $@ 
-B <(echo "<div id="PDF"><ul><li><a href="$(NAME).a4.pdf">A4 PDF</a></li><li><a href="$(NAME).letter.pdf">Letter PDF</a></li></ul></div><div id="source"><ul><li><a href="../$(NAME).bib">BibTeX references</a></li><li><a href="$(NAME).md">Pandoc MarkDown</a></li><li><a href="makefile">makefile</a></li></ul></div>")

如何将sed与模板一起使用?例如,这是文件,单词模板是{__NAME__}:

<div id="PDF"><ul><li><a href="{__NAME__}.a4.pdf">A4 PDF</a></li><li><a href="{__NAME__}.letter.pdf">Letter PDF</a></li></ul></div><div id="source"><ul><li><a href="../{__NAME__}.bib">BibTeX references</a></li><li><a href="{__NAME__}.md">Pandoc MarkDown</a></li><li><a href="makefile">makefile</a></li></ul></div>

你可以用sed来代替它们:

pandoc $< -S -o $@ 
-B <(sed -e "s|{__NAME__}|$(NAME)|g" file.txt)

您可以将整个文件读取到变量中,然后使用$(subst)替换所有出现的$(NAME)

SHELL := /bin/bash
NAME  := $(basename $(wildcard *.md))
TEMPLATE := $(shell cat template.html)
all: index.html
html: index.html
index.html: $(NAME).md
    pandoc $< -S -o $@ -B <<< "$(subst $$(NAME),$(NAME),$(TEMPLATE))"

或者,如果您想解析模板文件中的所有变量,请按如下方式替换最后一个文件:

pandoc $< -S -o $@ -B <<< "$(eval RESULT:=$(TEMPLATE))$(RESULT)"

template.html:

<div id="PDF"><ul><li><a href="$(NAME).a4.pdf">A4 PDF</a></li><li><a href="$(NAME).letter.pdf">Letter PDF</a></li></ul></div><div id="source"><ul><li><a href="../$(NAME).bib">BibTeX references</a></li><li><a href="$(NAME).md">Pandoc MarkDown</a></li><li><a href="makefile">makefile</a></li></ul></div>

我开始欣赏loentar的编辑答案,因为它比sed解决方案更通用。loentar提出的解决方案不仅可以解释模板文件中的$(NAME)变量,还可以解释其他各种Bash变量和命令。

尽管如此,loentar提出的解决方案不适用于pandoc,原因如下:

  1. Bash命令<<<创建一个here字符串,而参数-B-A需要文件。<(echo string)纠正了这个问题
  2. 另一个问题是,Bash将展开before.htmlafter.html模板文件中的所有双引号,从而生成一个未经验证的XHTML文件。为了解决这个问题,sed 's/"/\"/g'在Bash解释之前用反斜杠转义所有双引号

因此,一个行之有效的解决方案是:

SHELL := /bin/bash
NAME  := $(basename $(wildcard *.md))
BEFORE := $(shell sed 's/"/\"/g' before.html)
AFTER := $(shell sed 's/"/\"/g' after.html)
all: index.html
html: index.html
index.html: $(NAME).md
    pandoc $< -S -o $@ 
    -B <(echo "$(eval RESULT:=$(BEFORE))$(RESULT)") 
    -A <(echo "$(eval RESULT:=$(AFTER))$(RESULT)")

before.html为例:

<div id="PDF">
    <img src="../../images/pdf.png" alt="PDF" width="34" />
    <ul>
        <li><a href="$(NAME).a4.pdf">A4 PDF</a></li>
        <li><a href="$(NAME).letter.pdf">Letter PDF</a></li>
    </ul>
</div>
<div id="source">
    <ul>
        <li><a href="../$(NAME).bib">BibTeX references</a></li>
        <li><a href="$(NAME).md">Pandoc MarkDown</a></li>
        <li><a href="makefile">makefile</a></li>
    </ul>
</div>
</div>

最新更新