github.com/graemephi/kahugo@v0.62.3-0.20211121071557-d78c0423784d/tpl/tplimpl/shortcodes.go (about)

     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 tplimpl
    15  
    16  import (
    17  	"strings"
    18  
    19  	"github.com/gohugoio/hugo/tpl"
    20  )
    21  
    22  // Currently lang, outFormat, suffix
    23  const numTemplateVariants = 3
    24  
    25  type shortcodeVariant struct {
    26  
    27  	// The possible variants: lang, outFormat, suffix
    28  	// gtag
    29  	// gtag.html
    30  	// gtag.no.html
    31  	// gtag.no.amp.html
    32  	// A slice of length numTemplateVariants.
    33  	variants []string
    34  
    35  	ts *templateState
    36  }
    37  
    38  type shortcodeTemplates struct {
    39  	variants []shortcodeVariant
    40  }
    41  
    42  func (s *shortcodeTemplates) indexOf(variants []string) int {
    43  L:
    44  	for i, v1 := range s.variants {
    45  		for i, v2 := range v1.variants {
    46  			if v2 != variants[i] {
    47  				continue L
    48  			}
    49  		}
    50  		return i
    51  	}
    52  	return -1
    53  }
    54  
    55  func (s *shortcodeTemplates) fromVariants(variants tpl.TemplateVariants) (shortcodeVariant, bool) {
    56  	return s.fromVariantsSlice([]string{
    57  		variants.Language,
    58  		strings.ToLower(variants.OutputFormat.Name),
    59  		variants.OutputFormat.MediaType.FirstSuffix.Suffix,
    60  	})
    61  }
    62  
    63  func (s *shortcodeTemplates) fromVariantsSlice(variants []string) (shortcodeVariant, bool) {
    64  	var (
    65  		bestMatch       shortcodeVariant
    66  		bestMatchWeight int
    67  	)
    68  
    69  	for _, variant := range s.variants {
    70  		w := s.compareVariants(variants, variant.variants)
    71  		if bestMatchWeight == 0 || w > bestMatchWeight {
    72  			bestMatch = variant
    73  			bestMatchWeight = w
    74  		}
    75  	}
    76  
    77  	return bestMatch, true
    78  }
    79  
    80  // calculate a weight for two string slices of same length.
    81  // higher value means "better match".
    82  func (s *shortcodeTemplates) compareVariants(a, b []string) int {
    83  	weight := 0
    84  	k := len(a)
    85  	for i, av := range a {
    86  		bv := b[i]
    87  		if av == bv {
    88  			// Add more weight to the left side (language...).
    89  			weight = weight + k - i
    90  		} else {
    91  			weight--
    92  		}
    93  	}
    94  	return weight
    95  }
    96  
    97  func templateVariants(name string) []string {
    98  	_, variants := templateNameAndVariants(name)
    99  	return variants
   100  }
   101  
   102  func templateNameAndVariants(name string) (string, []string) {
   103  	variants := make([]string, numTemplateVariants)
   104  
   105  	parts := strings.Split(name, ".")
   106  
   107  	if len(parts) <= 1 {
   108  		// No variants.
   109  		return name, variants
   110  	}
   111  
   112  	name = parts[0]
   113  	parts = parts[1:]
   114  	lp := len(parts)
   115  	start := len(variants) - lp
   116  
   117  	for i, j := start, 0; i < len(variants); i, j = i+1, j+1 {
   118  		variants[i] = parts[j]
   119  	}
   120  
   121  	if lp > 1 && lp < len(variants) {
   122  		for i := lp - 1; i > 0; i-- {
   123  			variants[i-1] = variants[i]
   124  		}
   125  	}
   126  
   127  	if lp == 1 {
   128  		// Suffix only. Duplicate it into the output format field to
   129  		// make HTML win over AMP.
   130  		variants[len(variants)-2] = variants[len(variants)-1]
   131  	}
   132  
   133  	return name, variants
   134  }
   135  
   136  func resolveTemplateType(name string) templateType {
   137  	if isShortcode(name) {
   138  		return templateShortcode
   139  	}
   140  
   141  	if strings.Contains(name, "partials/") {
   142  		return templatePartial
   143  	}
   144  
   145  	return templateUndefined
   146  }
   147  
   148  func isShortcode(name string) bool {
   149  	return strings.Contains(name, shortcodesPathPrefix)
   150  }
   151  
   152  func isInternal(name string) bool {
   153  	return strings.HasPrefix(name, internalPathPrefix)
   154  }