func processColorTemplates(colorTemplateRegexp *regexp.Regexp, buf []byte) []byte { // We really want ReplaceAllSubmatchFunc, i.e.: https://github.com/golang/go/issues/5690 // Instead we call FindSubmatch on each match, which means that backtracking may not be // used in custom Regexps (matches must also match on themselves without context). colorTemplateReplacer := func(token []byte) []byte { tmp2 := []byte{} groups := colorTemplateRegexp.FindSubmatch(token) var ansiActive ActiveAnsiCodes for _, codeBytes := range bytes.Split(groups[1], bytesComma) { colorCode, ok := ansiColorCodes[string(codeBytes)] if !ok { // Don't modify the text if we don't recognize any of the codes return groups[0] } for _, code := range colorCode.GetAnsiCodes() { ansiActive.add(code) tmp2 = append(tmp2, ansiEscapeBytes(code)...) } } if len(groups[2]) > 0 { tmp2 = append(tmp2, groups[3]...) tmp2 = append(tmp2, ansiActive.getResetBytes()...) } return tmp2 } return colorTemplateRegexp.ReplaceAllFunc(buf, colorTemplateReplacer) }
func _builtinGlobal_encodeURI(call FunctionCall, characterRegexp *regexp.Regexp) Value { value := []byte(toString(call.Argument(0))) value = characterRegexp.ReplaceAllFunc(value, func(target []byte) []byte { // Probably a better way of doing this if target[0] == ' ' { return []byte("%20") } return []byte(url.QueryEscape(string(target))) }) return toValue(string(value)) }
func _builtinGlobal_encodeURI(call FunctionCall, escape *regexp.Regexp) Value { value := call.Argument(0) var input []uint16 switch vl := value.value.(type) { case []uint16: input = vl default: input = utf16.Encode([]rune(toString(value))) } if len(input) == 0 { return toValue("") } output := []byte{} length := len(input) encode := make([]byte, 4) for index := 0; index < length; { value := input[index] decode := utf16.Decode(input[index : index+1]) if value >= 0xDC00 && value <= 0xDFFF { panic(newURIError("URI malformed")) } if value >= 0xD800 && value <= 0xDBFF { index += 1 if index >= length { panic(newURIError("URI malformed")) } // input = ..., value, value1, ... value = value value1 := input[index] if value1 < 0xDC00 || value1 > 0xDFFF { panic(newURIError("URI malformed")) } decode = []rune{((rune(value) - 0xD800) * 0x400) + (rune(value1) - 0xDC00) + 0x10000} } index += 1 size := utf8.EncodeRune(encode, decode[0]) encode := encode[0:size] output = append(output, encode...) } { value := escape.ReplaceAllFunc(output, func(target []byte) []byte { // Probably a better way of doing this if target[0] == ' ' { return []byte("%20") } return []byte(url.QueryEscape(string(target))) }) return toValue(string(value)) } }
// Replace prefixed shortcode tokens (HUGOSHORTCODE-1, HUGOSHORTCODE-2) with the real content. // wrapped = true means that the token has been wrapped in {@{@/@}@} func replaceShortcodeTokens(source []byte, prefix string, wrapped bool, replacements map[string]string) (b []byte, err error) { var re *regexp.Regexp if wrapped { re, err = regexp.Compile(`\{@\{@` + regexp.QuoteMeta(prefix) + `-\d+@\}@\}`) if err != nil { return nil, err } } else { re, err = regexp.Compile(regexp.QuoteMeta(prefix) + `-(\d+)`) if err != nil { return nil, err } } // use panic/recover for reporting if an unknown defer func() { if r := recover(); r != nil { var ok bool b = nil err, ok = r.(error) if !ok { err = fmt.Errorf("unexpected panic during replaceShortcodeTokens: %v", r) } } }() b = re.ReplaceAllFunc(source, func(m []byte) []byte { key := string(m) if val, ok := replacements[key]; ok { return []byte(val) } else { panic(fmt.Errorf("unknown shortcode token %q", key)) } }) return b, err }
// As above, but further uses exp to parse the non-preformatted sections. func replaceNonPreformattedRegexp(input []byte, exp *regexp.Regexp, replace func([]byte) []byte) []byte { return replaceNonPreformatted(input, func(in []byte) []byte { return exp.ReplaceAllFunc(in, replace) }) }