packagemainimport("regexp""strings")varre=regexp.MustCompile(`\((.*?)\)`)const(// FIRST signals to the parser that it is looking// for a line in the first part of the verseFIRST=iota// SECOND signals to the parser that it is looking// for a line in the second part of the verseSECOND)// ProcessLine takes a line and returns a "processed" version// (i.e., one that uses the TeX commands instead of the user inputted ones)funcProcessLine(linestring)string{// Escape LaTeX reserved charactersline=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 breaksline=strings.Replace(line,`\\`,`\breaklongline{} `,-1)// Format brackets over wordsline=re.ReplaceAllString(line,`\bracket{${1}}`)// Smallcap "Lord"line=strings.Replace(line,"Lord",`\textsc{Lord}`,-1)line=strings.Replace(line,"LORD",`\textsc{Lord}`,-1)returnline}// ParseInput converts the raw input string into a collection of verses while also// changing the user input formatting strings into the TeX-sanctioned commandsfuncParseInput(inputstring)(verses[]Verse){lines:=strings.Split(input,"\n")v:=Verse{}parity:=FIRSTiflen(lines)==1{ifstrings.HasPrefix(lines[0],"^"){return[]Verse{Verse{FirstPart:ProcessLine(lines[0][1:]),IsSecond:true,},}}return[]Verse{Verse{FirstPart:ProcessLine(lines[0]),},}}for_,l:=rangelines{// Empty lines are used to separate versesifstrings.TrimSpace(l)==""{parity=FIRSTcontinue}line:=ProcessLine(l)ifstrings.HasPrefix(line,"^"){v.IsSecond=trueline=line[1:]}ifparity==FIRST{v.FirstPart=lineparity=SECOND}elseifparity==SECOND{v.SecondPart=lineverses=append(verses,v)parity=FIRSTv=Verse{}}}returnverses}