hugo

Fork of github.com/gohugoio/hugo with reverse pagination support

git clone git://git.shimmy1996.com/hugo.git

page__content.go (3449B)

    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 hugolib
   15 
   16 import (
   17 	"fmt"
   18 
   19 	"github.com/gohugoio/hugo/output"
   20 	"github.com/gohugoio/hugo/parser/pageparser"
   21 )
   22 
   23 var (
   24 	internalSummaryDividerBase      = "HUGOMORE42"
   25 	internalSummaryDividerBaseBytes = []byte(internalSummaryDividerBase)
   26 	internalSummaryDividerPre       = []byte("\n\n" + internalSummaryDividerBase + "\n\n")
   27 )
   28 
   29 // The content related items on a Page.
   30 type pageContent struct {
   31 	selfLayout string
   32 	truncated  bool
   33 
   34 	cmap *pageContentMap
   35 
   36 	source rawPageContent
   37 }
   38 
   39 // returns the content to be processed by Goldmark or similar.
   40 func (p pageContent) contentToRender(parsed pageparser.Result, pm *pageContentMap, renderedShortcodes map[string]string) []byte {
   41 	source := parsed.Input()
   42 
   43 	c := make([]byte, 0, len(source)+(len(source)/10))
   44 
   45 	for _, it := range pm.items {
   46 		switch v := it.(type) {
   47 		case pageparser.Item:
   48 			c = append(c, source[v.Pos:v.Pos+len(v.Val)]...)
   49 		case pageContentReplacement:
   50 			c = append(c, v.val...)
   51 		case *shortcode:
   52 			if !v.insertPlaceholder() {
   53 				// Insert the rendered shortcode.
   54 				renderedShortcode, found := renderedShortcodes[v.placeholder]
   55 				if !found {
   56 					// This should never happen.
   57 					panic(fmt.Sprintf("rendered shortcode %q not found", v.placeholder))
   58 				}
   59 
   60 				c = append(c, []byte(renderedShortcode)...)
   61 
   62 			} else {
   63 				// Insert the placeholder so we can insert the content after
   64 				// markdown processing.
   65 				c = append(c, []byte(v.placeholder)...)
   66 			}
   67 		default:
   68 			panic(fmt.Sprintf("unknown item type %T", it))
   69 		}
   70 	}
   71 
   72 	return c
   73 }
   74 
   75 func (p pageContent) selfLayoutForOutput(f output.Format) string {
   76 	if p.selfLayout == "" {
   77 		return ""
   78 	}
   79 	return p.selfLayout + f.Name
   80 }
   81 
   82 type rawPageContent struct {
   83 	hasSummaryDivider bool
   84 
   85 	// The AST of the parsed page. Contains information about:
   86 	// shortcodes, front matter, summary indicators.
   87 	parsed pageparser.Result
   88 
   89 	// Returns the position in bytes after any front matter.
   90 	posMainContent int
   91 
   92 	// These are set if we're able to determine this from the source.
   93 	posSummaryEnd int
   94 	posBodyStart  int
   95 }
   96 
   97 type pageContentReplacement struct {
   98 	val []byte
   99 
  100 	source pageparser.Item
  101 }
  102 
  103 type pageContentMap struct {
  104 
  105 	// If not, we can skip any pre-rendering of shortcodes.
  106 	hasMarkdownShortcode bool
  107 
  108 	// Indicates whether we must do placeholder replacements.
  109 	hasNonMarkdownShortcode bool
  110 
  111 	//  *shortcode, pageContentReplacement or pageparser.Item
  112 	items []any
  113 }
  114 
  115 func (p *pageContentMap) AddBytes(item pageparser.Item) {
  116 	p.items = append(p.items, item)
  117 }
  118 
  119 func (p *pageContentMap) AddReplacement(val []byte, source pageparser.Item) {
  120 	p.items = append(p.items, pageContentReplacement{val: val, source: source})
  121 }
  122 
  123 func (p *pageContentMap) AddShortcode(s *shortcode) {
  124 	p.items = append(p.items, s)
  125 	if s.insertPlaceholder() {
  126 		p.hasNonMarkdownShortcode = true
  127 	} else {
  128 		p.hasMarkdownShortcode = true
  129 	}
  130 }