summaryrefslogtreecommitdiffstats
path: root/vendor/github.com/mattermost/mattermost-server/utils/markdown/markdown.go
diff options
context:
space:
mode:
authorDuco van Amstel <helcaraxan@gmail.com>2018-11-18 17:55:05 +0000
committerWim <wim@42.be>2018-11-25 21:21:04 +0100
commit09875fe1603307080f3a4172985c5dca3bd9912d (patch)
treea23220772f6f6597d509ca71b2df3480a77b8076 /vendor/github.com/mattermost/mattermost-server/utils/markdown/markdown.go
parentf716b8fc0ff90f47b61e218ef34019b38bd70e0d (diff)
downloadmatterbridge-msglm-09875fe1603307080f3a4172985c5dca3bd9912d.tar.gz
matterbridge-msglm-09875fe1603307080f3a4172985c5dca3bd9912d.tar.bz2
matterbridge-msglm-09875fe1603307080f3a4172985c5dca3bd9912d.zip
Update direct dependencies where possible
Diffstat (limited to 'vendor/github.com/mattermost/mattermost-server/utils/markdown/markdown.go')
-rw-r--r--vendor/github.com/mattermost/mattermost-server/utils/markdown/markdown.go148
1 files changed, 148 insertions, 0 deletions
diff --git a/vendor/github.com/mattermost/mattermost-server/utils/markdown/markdown.go b/vendor/github.com/mattermost/mattermost-server/utils/markdown/markdown.go
new file mode 100644
index 00000000..57b10f3f
--- /dev/null
+++ b/vendor/github.com/mattermost/mattermost-server/utils/markdown/markdown.go
@@ -0,0 +1,148 @@
+// Copyright (c) 2017-present Mattermost, Inc. All Rights Reserved.
+// See License.txt for license information.
+
+// This package implements a parser for the subset of the CommonMark spec necessary for us to do
+// server-side processing. It is not a full implementation and lacks many features. But it is
+// complete enough to efficiently and accurately allow us to do what we need to like rewrite image
+// URLs for proxying.
+package markdown
+
+import (
+ "strings"
+)
+
+func isEscapable(c rune) bool {
+ return c > ' ' && (c < '0' || (c > '9' && (c < 'A' || (c > 'Z' && (c < 'a' || (c > 'z' && c <= '~'))))))
+}
+
+func isEscapableByte(c byte) bool {
+ return isEscapable(rune(c))
+}
+
+func isWhitespace(c rune) bool {
+ switch c {
+ case ' ', '\t', '\n', '\u000b', '\u000c', '\r':
+ return true
+ default:
+ return false
+ }
+}
+
+func isWhitespaceByte(c byte) bool {
+ return isWhitespace(rune(c))
+}
+
+func isNumeric(c rune) bool {
+ return c >= '0' && c <= '9'
+}
+
+func isNumericByte(c byte) bool {
+ return isNumeric(rune(c))
+}
+
+func isHex(c rune) bool {
+ return isNumeric(c) || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F')
+}
+
+func isHexByte(c byte) bool {
+ return isHex(rune(c))
+}
+
+func isAlphanumeric(c rune) bool {
+ return isNumeric(c) || (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')
+}
+
+func isAlphanumericByte(c byte) bool {
+ return isAlphanumeric(rune(c))
+}
+
+func nextNonWhitespace(markdown string, position int) int {
+ for offset, c := range []byte(markdown[position:]) {
+ if !isWhitespaceByte(c) {
+ return position + offset
+ }
+ }
+ return len(markdown)
+}
+
+func nextLine(markdown string, position int) (linePosition int, skippedNonWhitespace bool) {
+ for i := position; i < len(markdown); i++ {
+ c := markdown[i]
+ if c == '\r' {
+ if i+1 < len(markdown) && markdown[i+1] == '\n' {
+ return i + 2, skippedNonWhitespace
+ }
+ return i + 1, skippedNonWhitespace
+ } else if c == '\n' {
+ return i + 1, skippedNonWhitespace
+ } else if !isWhitespaceByte(c) {
+ skippedNonWhitespace = true
+ }
+ }
+ return len(markdown), skippedNonWhitespace
+}
+
+func countIndentation(markdown string, r Range) (spaces, bytes int) {
+ for i := r.Position; i < r.End; i++ {
+ if markdown[i] == ' ' {
+ spaces++
+ bytes++
+ } else if markdown[i] == '\t' {
+ spaces += 4
+ bytes++
+ } else {
+ break
+ }
+ }
+ return
+}
+
+func trimLeftSpace(markdown string, r Range) Range {
+ s := markdown[r.Position:r.End]
+ trimmed := strings.TrimLeftFunc(s, isWhitespace)
+ return Range{r.Position, r.End - (len(s) - len(trimmed))}
+}
+
+func trimRightSpace(markdown string, r Range) Range {
+ s := markdown[r.Position:r.End]
+ trimmed := strings.TrimRightFunc(s, isWhitespace)
+ return Range{r.Position, r.End - (len(s) - len(trimmed))}
+}
+
+func relativeToAbsolutePosition(ranges []Range, position int) int {
+ rem := position
+ for _, r := range ranges {
+ l := r.End - r.Position
+ if rem < l {
+ return r.Position + rem
+ }
+ rem -= l
+ }
+ if len(ranges) == 0 {
+ return 0
+ }
+ return ranges[len(ranges)-1].End
+}
+
+func trimBytesFromRanges(ranges []Range, bytes int) (result []Range) {
+ rem := bytes
+ for _, r := range ranges {
+ if rem == 0 {
+ result = append(result, r)
+ continue
+ }
+ l := r.End - r.Position
+ if rem < l {
+ result = append(result, Range{r.Position + rem, r.End})
+ rem = 0
+ continue
+ }
+ rem -= l
+ }
+ return
+}
+
+func Parse(markdown string) (*Document, []*ReferenceDefinition) {
+ lines := ParseLines(markdown)
+ return ParseBlocks(markdown, lines)
+}