summaryrefslogtreecommitdiffstats
path: root/common/text/position.go
diff options
context:
space:
mode:
authorBjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com>2018-11-01 11:28:30 +0100
committerBjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com>2018-11-01 21:06:35 +0100
commit1d18eb0574a57c3e9f468659d076a666a3dd76f2 (patch)
tree8536aa6e8e2fc496b3b2d7b66a2e5f0110e625a6 /common/text/position.go
parent33a7b36fd42ee31dd79115ec6639bed24247332f (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.go99
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"))
+}