convert.go (2609B)
1 // Copyright 2019 The Hugo Authors. All rights reserved.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 // http://www.apache.org/licenses/LICENSE-2.0
7 //
8 // Unless required by applicable law or agreed to in writing, software
9 // distributed under the License is distributed on an "AS IS" BASIS,
10 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11 // See the License for the specific language governing permissions and
12 // limitations under the License.
13
14 // Package pandoc converts content to HTML using Pandoc as an external helper.
15 package pandoc
16
17 import (
18 "github.com/gohugoio/hugo/common/hexec"
19 "github.com/gohugoio/hugo/htesting"
20 "github.com/gohugoio/hugo/identity"
21 "github.com/gohugoio/hugo/markup/internal"
22
23 "github.com/gohugoio/hugo/markup/converter"
24 )
25
26 // Provider is the package entry point.
27 var Provider converter.ProviderProvider = provider{}
28
29 type provider struct {
30 }
31
32 func (p provider) New(cfg converter.ProviderConfig) (converter.Provider, error) {
33 return converter.NewProvider("pandoc", func(ctx converter.DocumentContext) (converter.Converter, error) {
34 return &pandocConverter{
35 ctx: ctx,
36 cfg: cfg,
37 }, nil
38 }), nil
39 }
40
41 type pandocConverter struct {
42 ctx converter.DocumentContext
43 cfg converter.ProviderConfig
44 }
45
46 func (c *pandocConverter) Convert(ctx converter.RenderContext) (converter.Result, error) {
47 b, err := c.getPandocContent(ctx.Src, c.ctx)
48 if err != nil {
49 return nil, err
50 }
51 return converter.Bytes(b), nil
52 }
53
54 func (c *pandocConverter) Supports(feature identity.Identity) bool {
55 return false
56 }
57
58 // getPandocContent calls pandoc as an external helper to convert pandoc markdown to HTML.
59 func (c *pandocConverter) getPandocContent(src []byte, ctx converter.DocumentContext) ([]byte, error) {
60 logger := c.cfg.Logger
61 binaryName := getPandocBinaryName()
62 if binaryName == "" {
63 logger.Println("pandoc not found in $PATH: Please install.\n",
64 " Leaving pandoc content unrendered.")
65 return src, nil
66 }
67 args := []string{"--mathjax"}
68 return internal.ExternallyRenderContent(c.cfg, ctx, src, binaryName, args)
69 }
70
71 const pandocBinary = "pandoc"
72
73 func getPandocBinaryName() string {
74 if hexec.InPath(pandocBinary) {
75 return pandocBinary
76 }
77 return ""
78 }
79
80 // Supports returns whether Pandoc is installed on this computer.
81 func Supports() bool {
82 hasBin := getPandocBinaryName() != ""
83 if htesting.SupportsAll() {
84 if !hasBin {
85 panic("pandoc not installed")
86 }
87 return true
88 }
89 return hasBin
90 }