~reesmichael1/chantpointer

ref: 0ba42d0dff660f88ca66c3b97a6fed56d37721a4 chantpointer/parser.go -rw-r--r-- 2.1 KiB View raw
0ba42d0dMichael Rees Use .ssh/config as secret 1 year, 5 months ago
                                                                                
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
package main

import (
	"regexp"
	"strings"
)

var re = regexp.MustCompile(`\((.*?)\)`)

const (
	// FIRST signals to the parser that it is looking
	// for a line in the first part of the verse
	FIRST = iota
	// SECOND signals to the parser that it is looking
	// for a line in the second part of the verse
	SECOND
)

// ProcessLine takes a line and returns a "processed" version
// (i.e., one that uses the TeX commands instead of the user inputted ones)
func ProcessLine(line string) string {
	// Escape LaTeX reserved characters
	line = strings.Replace(line, "#", `\#`, -1)
	line = strings.Replace(line, "$", `\$`, -1)
	line = strings.Replace(line, "%", `\%`, -1)
	line = strings.Replace(line, "{", `\{`, -1)
	line = strings.Replace(line, "}", `\}`, -1)
	line = strings.Replace(line, "~", `\~`, -1)
	// Format interline breaks
	line = strings.Replace(line, `\\`, `\breaklongline{} `, -1)
	// Format brackets over words
	line = re.ReplaceAllString(line, `\bracket{${1}}`)
	// Smallcap "Lord"
	line = strings.Replace(line, "Lord", `\textsc{Lord}`, -1)
	line = strings.Replace(line, "LORD", `\textsc{Lord}`, -1)
	return line
}

// ParseInput converts the raw input string into a collection of verses while also
// changing the user input formatting strings into the TeX-sanctioned commands
func ParseInput(input string) (verses []Verse) {
	lines := strings.Split(input, "\n")

	v := Verse{}
	parity := FIRST

	if len(lines) == 1 {
		if strings.HasPrefix(lines[0], "^") {
			return []Verse{
				Verse{
					FirstPart: ProcessLine(lines[0][1:]),
					IsSecond:  true,
				},
			}
		}
		return []Verse{
			Verse{
				FirstPart: ProcessLine(lines[0]),
			},
		}
	}

	for _, l := range lines {
		// Empty lines are used to separate verses
		if strings.TrimSpace(l) == "" {
			parity = FIRST
			continue
		}
		line := ProcessLine(l)
		if strings.HasPrefix(line, "^") {
			v.IsSecond = true
			line = line[1:]
		}

		if parity == FIRST {
			v.FirstPart = line
			parity = SECOND
		} else if parity == SECOND {
			v.SecondPart = line
			verses = append(verses, v)
			parity = FIRST
			v = Verse{}
		}
	}

	return verses
}