ruderich.org/simon/gswgf@v0.2.3/layout.go (about)

     1  // Layouts for converted source files
     2  
     3  // Copyright (C) 2019-2020  Simon Ruderich
     4  //
     5  // This program is free software: you can redistribute it and/or modify
     6  // it under the terms of the GNU Affero General Public License as published by
     7  // the Free Software Foundation, either version 3 of the License, or
     8  // (at your option) any later version.
     9  //
    10  // This program is distributed in the hope that it will be useful,
    11  // but WITHOUT ANY WARRANTY; without even the implied warranty of
    12  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    13  // GNU Affero General Public License for more details.
    14  //
    15  // You should have received a copy of the GNU Affero General Public License
    16  // along with this program.  If not, see <https://www.gnu.org/licenses/>.
    17  
    18  package gswgf
    19  
    20  import (
    21  	"regexp"
    22  
    23  	"github.com/pkg/errors"
    24  )
    25  
    26  // A Layout controls the path used as layout file. This file uses Go
    27  // templating to embed the converted source file and produce the final output.
    28  //
    29  // If no layout matches the default Layout sets Path to "layout.html".
    30  type Layout struct {
    31  	// Path to template file
    32  	Path string
    33  }
    34  
    35  // A PathLayout sets the Layout for a path having a given extension (Ext, uses
    36  // filepath.Ext() but treats ".filename" as having no extension; multiple
    37  // extensions, e.g. ".tar.gz" are not supported), matching a shell glob (Glob,
    38  // uses filepath.Match()) or matching a regular expression (Regexp). Only one
    39  // of Ext/Glob/Regexp can be set.
    40  type PathLayout struct {
    41  	Ext    string
    42  	Glob   string
    43  	Regexp *regexp.Regexp
    44  
    45  	Layout Layout
    46  }
    47  
    48  // DefaultPathActions returns the built-in PathLayouts.
    49  //
    50  // The default is empty which causes "layouts.html" to be used for all files.
    51  var DefaultPathLayouts = []PathLayout{}
    52  
    53  func layoutForPath(cfg *Config, path string) (Layout, error) {
    54  	// Default layout
    55  	layout := Layout{
    56  		Path: "layout.html",
    57  	}
    58  
    59  	// Find any overrides for this path
    60  	for _, x := range cfg.PathLayouts {
    61  		ok, err := pathMatches(path, x)
    62  		if err != nil {
    63  			return Layout{}, err
    64  		}
    65  		if ok {
    66  			layout = x.Layout
    67  			break
    68  		}
    69  	}
    70  
    71  	// User hook
    72  	if cfg.LayoutSelectionHook == nil {
    73  		return layout, nil
    74  	}
    75  	layout, err := cfg.LayoutSelectionHook(path, layout)
    76  	if err != nil {
    77  		return Layout{}, errors.Wrapf(err, "LayoutHook")
    78  	}
    79  	return layout, nil
    80  }
    81  
    82  func (pl PathLayout) ext() string {
    83  	return pl.Ext
    84  }
    85  func (pl PathLayout) glob() string {
    86  	return pl.Glob
    87  }
    88  func (pl PathLayout) regexp() *regexp.Regexp {
    89  	return pl.Regexp
    90  }