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

时间:2013-08-13 08:03:06

标签: bash web makefile io-redirection pandoc

简介

我开始使用Pandoc markdown为我的个人网站生成静态XHTML。 我设法使用Pandoc $(NAME)参数自动插入了几个引用.md文件-B的链接(参见下面的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>")

3 个答案:

答案 0 :(得分:1)

如何在模板中使用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)

答案 1 :(得分:1)

您可以将整个文件读入变量,然后使用$(NAME)替换所有$(subst)次出现。

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>

答案 2 :(得分:1)

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

尽管如此,loentar提议的解决方案不能与pandoc一起使用,原因如下:

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

    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>