diff options
author | Bjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com> | 2018-11-01 11:28:30 +0100 |
---|---|---|
committer | Bjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com> | 2018-11-01 21:06:35 +0100 |
commit | 1d18eb0574a57c3e9f468659d076a666a3dd76f2 (patch) | |
tree | 8536aa6e8e2fc496b3b2d7b66a2e5f0110e625a6 /common/text/position.go | |
parent | 33a7b36fd42ee31dd79115ec6639bed24247332f (diff) |
Add file (line/col) info to ref/relref errors
See #5371
Diffstat (limited to 'common/text/position.go')
-rw-r--r-- | common/text/position.go | 99 |
1 files changed, 99 insertions, 0 deletions
diff --git a/common/text/position.go b/common/text/position.go new file mode 100644 index 000000000..0c43c5ae7 --- /dev/null +++ b/common/text/position.go @@ -0,0 +1,99 @@ +// Copyright 2018 The Hugo Authors. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package text + +import ( + "fmt" + "os" + "strings" + + "github.com/gohugoio/hugo/common/terminal" +) + +// Positioner represents a thing that knows its position in a text file or stream, +// typically an error. +type Positioner interface { + Position() Position +} + +// Position holds a source position in a text file or stream. +type Position struct { + Filename string // filename, if any + Offset int // byte offset, starting at 0. It's set to -1 if not provided. + LineNumber int // line number, starting at 1 + ColumnNumber int // column number, starting at 1 (character count per line) +} + +func (pos Position) String() string { + if pos.Filename == "" { + pos.Filename = "<stream>" + } + return positionStringFormatfunc(pos) +} + +// IsValid returns true if line number is > 0. +func (pos Position) IsValid() bool { + return pos.LineNumber > 0 +} + +var positionStringFormatfunc func(p Position) string + +func createPositionStringFormatter(formatStr string) func(p Position) string { + + if formatStr == "" { + formatStr = "\":file::line::col\"" + } + + var identifiers = []string{":file", ":line", ":col"} + var identifiersFound []string + + for i := range formatStr { + for _, id := range identifiers { + if strings.HasPrefix(formatStr[i:], id) { + identifiersFound = append(identifiersFound, id) + } + } + } + + replacer := strings.NewReplacer(":file", "%s", ":line", "%d", ":col", "%d") + format := replacer.Replace(formatStr) + + f := func(pos Position) string { + args := make([]interface{}, len(identifiersFound)) + for i, id := range identifiersFound { + switch id { + case ":file": + args[i] = pos.Filename + case ":line": + args[i] = pos.LineNumber + case ":col": + args[i] = pos.ColumnNumber + } + } + + msg := fmt.Sprintf(format, args...) + + if terminal.IsTerminal(os.Stdout) { + return terminal.Notice(msg) + } + + return msg + } + + return f +} + +func init() { + positionStringFormatfunc = createPositionStringFormatter(os.Getenv("HUGO_FILE_LOG_FORMAT")) +} |