github.com/kovansky/hugo@v0.92.3-0.20220224232819-63076e4ff19f/tpl/transform/transform.go (about)

     1  // Copyright 2017 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 transform provides template functions for transforming content.
    15  package transform
    16  
    17  import (
    18  	"html"
    19  	"html/template"
    20  
    21  	"github.com/gohugoio/hugo/cache/namedmemcache"
    22  	"github.com/gohugoio/hugo/common/herrors"
    23  	"github.com/gohugoio/hugo/markup/converter/hooks"
    24  	"github.com/gohugoio/hugo/markup/highlight"
    25  
    26  	"github.com/gohugoio/hugo/deps"
    27  	"github.com/gohugoio/hugo/helpers"
    28  	"github.com/spf13/cast"
    29  )
    30  
    31  // New returns a new instance of the transform-namespaced template functions.
    32  func New(deps *deps.Deps) *Namespace {
    33  	cache := namedmemcache.New()
    34  	deps.BuildStartListeners.Add(
    35  		func() {
    36  			cache.Clear()
    37  		})
    38  
    39  	return &Namespace{
    40  		cache: cache,
    41  		deps:  deps,
    42  	}
    43  }
    44  
    45  // Namespace provides template functions for the "transform" namespace.
    46  type Namespace struct {
    47  	cache *namedmemcache.Cache
    48  	deps  *deps.Deps
    49  }
    50  
    51  // Emojify returns a copy of s with all emoji codes replaced with actual emojis.
    52  //
    53  // See http://www.emoji-cheat-sheet.com/
    54  func (ns *Namespace) Emojify(s interface{}) (template.HTML, error) {
    55  	ss, err := cast.ToStringE(s)
    56  	if err != nil {
    57  		return "", err
    58  	}
    59  
    60  	return template.HTML(helpers.Emojify([]byte(ss))), nil
    61  }
    62  
    63  // Highlight returns a copy of s as an HTML string with syntax
    64  // highlighting applied.
    65  func (ns *Namespace) Highlight(s interface{}, lang string, opts ...interface{}) (template.HTML, error) {
    66  	ss, err := cast.ToStringE(s)
    67  	if err != nil {
    68  		return "", err
    69  	}
    70  
    71  	var optsv interface{}
    72  	if len(opts) > 0 {
    73  		optsv = opts[0]
    74  	}
    75  
    76  	hl := ns.deps.ContentSpec.Converters.GetHighlighter()
    77  	highlighted, _ := hl.Highlight(ss, lang, optsv)
    78  	return template.HTML(highlighted), nil
    79  }
    80  
    81  // HighlightCodeBlock highlights a code block on the form received in the codeblock render hooks.
    82  func (ns *Namespace) HighlightCodeBlock(ctx hooks.CodeblockContext, opts ...interface{}) (highlight.HightlightResult, error) {
    83  	var optsv interface{}
    84  	if len(opts) > 0 {
    85  		optsv = opts[0]
    86  	}
    87  
    88  	hl := ns.deps.ContentSpec.Converters.GetHighlighter()
    89  
    90  	return hl.HighlightCodeBlock(ctx, optsv)
    91  }
    92  
    93  // HTMLEscape returns a copy of s with reserved HTML characters escaped.
    94  func (ns *Namespace) HTMLEscape(s interface{}) (string, error) {
    95  	ss, err := cast.ToStringE(s)
    96  	if err != nil {
    97  		return "", err
    98  	}
    99  
   100  	return html.EscapeString(ss), nil
   101  }
   102  
   103  // HTMLUnescape returns a copy of with HTML escape requences converted to plain
   104  // text.
   105  func (ns *Namespace) HTMLUnescape(s interface{}) (string, error) {
   106  	ss, err := cast.ToStringE(s)
   107  	if err != nil {
   108  		return "", err
   109  	}
   110  
   111  	return html.UnescapeString(ss), nil
   112  }
   113  
   114  // Markdownify renders a given input from Markdown to HTML.
   115  func (ns *Namespace) Markdownify(s interface{}) (template.HTML, error) {
   116  	defer herrors.Recover()
   117  	ss, err := cast.ToStringE(s)
   118  	if err != nil {
   119  		return "", err
   120  	}
   121  
   122  	home := ns.deps.Site.Home()
   123  	if home == nil {
   124  		panic("home must not be nil")
   125  	}
   126  	sss, err := home.RenderString(ss)
   127  
   128  	// Strip if this is a short inline type of text.
   129  	bb := ns.deps.ContentSpec.TrimShortHTML([]byte(sss))
   130  
   131  	return helpers.BytesToHTML(bb), nil
   132  }
   133  
   134  // Plainify returns a copy of s with all HTML tags removed.
   135  func (ns *Namespace) Plainify(s interface{}) (string, error) {
   136  	ss, err := cast.ToStringE(s)
   137  	if err != nil {
   138  		return "", err
   139  	}
   140  
   141  	return helpers.StripHTML(ss), nil
   142  }
   143  
   144  func (ns *Namespace) Reset() {
   145  	ns.cache.Clear()
   146  }