diff --git a/COPYING b/COPYING index bb0fd87..dd8b95f 100644 --- a/COPYING +++ b/COPYING @@ -1,5 +1,5 @@ Copyright 2018 Prodrive Technologies B.V. -Copyright 2018 Google LLC +Copyright 2018-2019 Google LLC Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/README.md b/README.md index 660e3c0..ab0aaba 100644 --- a/README.md +++ b/README.md @@ -35,16 +35,18 @@ You can then add directives along these lines to your `BUILD.bazel` files: load("@bazel_pandoc//:pandoc.bzl", "pandoc") pandoc( - name = "foo", - src = "foo.md", - from_format = "markdown", - to_format = "latex", + name = "foo", # required + src = "foo.md", # required + from_format = "markdown", # optional, inferred from src extension by default + to_format = "latex", # optional, inferred from output extension by default + output = "awesome_doc.tex", # optional, derived from name and to_format by default ) ``` -In the example above, an output file called `foo.tex` will be created in -the `bazel-bin` directory. The `to_format` field is used to -automatically derive a file extension of the output file. +In the example above, an output file called `awesome_doc.tex` will be created +in the `bazel-bin` directory. + +At least one of the `to_format` or `output` attributes must be provided. # Platform support diff --git a/pandoc.bzl b/pandoc.bzl index 4b3baa4..d36a2a1 100644 --- a/pandoc.bzl +++ b/pandoc.bzl @@ -51,44 +51,56 @@ PANDOC_EXTENSIONS = { def _pandoc_impl(ctx): toolchain = ctx.toolchains["@bazel_pandoc//:pandoc_toolchain_type"] + cli_args = [] + cli_args.extend(ctx.attr.options) + if ctx.attr.from_format: + cli_args.extend(["--from", ctx.attr.from_format]) + if ctx.attr.to_format: + cli_args.extend(["--to", ctx.attr.to_format]) + cli_args.extend(["-o", ctx.outputs.output.path]) + cli_args.extend([ctx.file.src.path]) ctx.actions.run( mnemonic = "Pandoc", executable = toolchain.pandoc.files.to_list()[0].path, - arguments = ctx.attr.options + [ - "--from", - ctx.attr.from_format, - "--to", - ctx.attr.to_format, - "-o", - ctx.outputs.out.path, - ctx.files.src[0].path, - ], + arguments = cli_args, inputs = depset( direct = ctx.files.src, transitive = [toolchain.pandoc.files], ), - outputs = [ctx.outputs.out], + outputs = [ctx.outputs.output], ) _pandoc = rule( attrs = { - "extension": attr.string(), "from_format": attr.string(), "options": attr.string_list(), - "src": attr.label(allow_files = True), + "src": attr.label(allow_single_file = True, mandatory = True), "to_format": attr.string(), + "output": attr.output(mandatory = True), }, - outputs = {"out": "%{name}.%{extension}"}, toolchains = ["@bazel_pandoc//:pandoc_toolchain_type"], implementation = _pandoc_impl, ) -def pandoc(**kwargs): - # Derive extension of the output file based on the desired format. - # Use the generic .xml syntax for XML-based formats and .txt for - # ones with no commonly used extension. - to_format = kwargs["to_format"] - if to_format not in PANDOC_EXTENSIONS: - fail("Unknown output format: " + to_format) +def _check_format(format, attr_name): + if format not in PANDOC_EXTENSIONS: + fail("Unknown `%{attr}` format: %{format}".fmt(attr = attr_name, format = format)) + return format + +def _infer_output(name, to_format): + """Derives output file based on the desired format. - _pandoc(extension = PANDOC_EXTENSIONS[to_format], **kwargs) + Use the generic .xml syntax for XML-based formats and .txt for + ones with no commonly used extension. + """ + to_format = _check_format(to_format, "to_format") + ext = PANDOC_EXTENSIONS[to_format] + return name + "." + ext + +def pandoc(**kwargs): + if "output" not in kwargs: + if "to_format" not in kwargs: + fail("One of `output` or `to_format` attributes must be provided") + to_format = _check_format(kwargs["to_format"], "to_format") + kwargs["output"] = _infer_output(kwargs["name"], to_format) + _pandoc(**kwargs) diff --git a/sample/BUILD.bazel b/sample/BUILD.bazel index a9a873c..14af1a8 100644 --- a/sample/BUILD.bazel +++ b/sample/BUILD.bazel @@ -1,10 +1,17 @@ load("//:pandoc.bzl", "PANDOC_EXTENSIONS", "pandoc") # Conversion of README to various formats for testing. - [pandoc( name = "readme_" + fmt, src = "//:README.md", from_format = "markdown", to_format = fmt, ) for fmt in PANDOC_EXTENSIONS.keys()] + +# You can also specify the output, the format is then inferred from the extension, +# and the rule name is not used. +pandoc( + name = "gen_html_page", + src = "//:README.md", + output = "index.html", +) diff --git a/sample/README.md b/sample/README.md index 47c90f0..5eb669d 100644 --- a/sample/README.md +++ b/sample/README.md @@ -3,6 +3,9 @@ Once you have set up your workspace, you can generate the [README](../README.md) in a multitude of formats. + +## Target defined with `to_format` + For instance: ```sh @@ -11,7 +14,57 @@ bazel build @bazel_pandoc//sample:readme_html bazel build @bazel_pandoc//sample:readme_epub ``` -You can also produce the README in all formats know to the rule: +These targets are defined (actually with a _for loop_) with + +```python +pandoc( + name = "readme_plain", + src = "//:README.md", + from_format = "markdown", + to_format = "plain", +) +pandoc( + name = "readme_html", + src = "//:README.md", + from_format = "markdown", + to_format = "html", +) +pandoc( + name = "readme_epub", + src = "//:README.md", + from_format = "markdown", + to_format = "epub", +) +``` + +You notice that the output file is derived from the rule name: +- bazel-bin/sample/readme_plain.txt +- bazel-bin/sample/readme_html.html +- bazel-bin/sample/readme_epub.epub + +NB: `from_format` is optional and inferred from the file extension by default. + + +## Target defined with `output` + +It's also possible to specify the output + +```python +pandoc( + name = "gen_html_page", + src = "//:README.md", + output = "index.html", +) + +``` +As a result, +```sh +bazel build //sample:gen_html_page +``` +produces an HTML document in: +- bazel-bin/sample/index.html + +Finally can also produce the README in all formats know to the rule: ```sh bazel build @bazel_pandoc//sample/...