Skip to content
Snippets Groups Projects
Verified Commit 658ab1ba authored by Tóth Miklós Tibor's avatar Tóth Miklós Tibor :shrug:
Browse files

flatten all the things

parent 9e562ab1
No related branches found
No related tags found
No related merge requests found
Pipeline #7926 passed
...@@ -3,6 +3,8 @@ package flatten ...@@ -3,6 +3,8 @@ package flatten
import ( import (
"fmt" "fmt"
"git.sch.bme.hu/insert-epic-projlab-team-name-here/tooling/plab/helpers" "git.sch.bme.hu/insert-epic-projlab-team-name-here/tooling/plab/helpers"
"io/ioutil"
"os"
) )
var Flatten = helpers.Subcommand{ var Flatten = helpers.Subcommand{
...@@ -26,7 +28,18 @@ var Flatten = helpers.Subcommand{ ...@@ -26,7 +28,18 @@ var Flatten = helpers.Subcommand{
panic(e) panic(e)
} }
} }
fmt.Println("flattened") b, e := ioutil.ReadFile(entry)
if e != nil {
panic(e)
}
o, e := InlineAllFuncs(string(b))
if e != nil {
panic(e)
}
e = ioutil.WriteFile(out, []byte(o), os.ModePerm)
if e != nil {
panic(e)
}
}, },
Help: "flaten a .tex file", Help: "flaten a .tex file",
} }
package flatten package flatten
type flattenable interface { type flattenable interface {
Flatten() string Name() string
Inline(args ...string) string
ArgNum() int
} }
...@@ -2,8 +2,8 @@ package flatten ...@@ -2,8 +2,8 @@ package flatten
import ( import (
"bytes" "bytes"
"errors"
"fmt" "fmt"
"git.sch.bme.hu/insert-epic-projlab-team-name-here/tooling/plab/helpers"
"io/ioutil" "io/ioutil"
"regexp" "regexp"
"strconv" "strconv"
...@@ -11,15 +11,25 @@ import ( ...@@ -11,15 +11,25 @@ import (
) )
type FunctionImplementation struct { type FunctionImplementation struct {
Name string flattenable
Body string name string
ArgNum int body string
argNum int
}
func (f *FunctionImplementation) Name() string {
return f.name
}
func (f *FunctionImplementation) ArgNum() int {
return f.argNum
} }
func InlineAllFuncs(str string) (string, error) { func InlineAllFuncs(str string) (string, error) {
for _, f := range funcs { for _, f := range funcs {
var soFar bytes.Buffer var soFar bytes.Buffer
tmpRegexp, e := regexp.Compile(fmt.Sprintf(`\\%s`, f.Name)) rx := helpers.Escape(f.Name()) + "{"
tmpRegexp, e := regexp.Compile(rx)
if e != nil { if e != nil {
return "", e return "", e
} }
...@@ -29,44 +39,65 @@ func InlineAllFuncs(str string) (string, error) { ...@@ -29,44 +39,65 @@ func InlineAllFuncs(str string) (string, error) {
nameStart := i[0] nameStart := i[0]
argsStart := i[1] argsStart := i[1]
name := str[nameStart:argsStart]
var fi *FunctionImplementation = nil
for fidx, f := range funcs {
if f.Name == name {
fi = &funcs[fidx]
}
}
if fi == nil {
continue
}
soFar.WriteString(str[prevStop:nameStart]) soFar.WriteString(str[prevStop:nameStart])
prevStop = nameStart
args := make([]string, 0) args := make([]string, 0)
for i := 0; i < fi.ArgNum; i++ { argStop := argsStart
for i := 0; i < f.ArgNum(); i++ {
depth := 0 depth := 0
var arg string var arg string
for for i, c := range str[argStop:] {
switch c {
case '{':
depth++
case '}':
depth--
default:
arg += string(c)
} }
if depth < 0 {
argStop += i
break
} }
} }
return str args = append(args, arg)
argStop++
}
inlined := f.Inline(args...)
soFar.WriteString("\n")
soFar.WriteString(inlined)
soFar.WriteString("\n")
prevStop = argStop
}
soFar.WriteString(str[prevStop:])
str = soFar.String()
}
return str, nil
} }
func (f *FunctionImplementation) Inline(args ...string) string { func (f *FunctionImplementation) Inline(args ...string) string {
const canary = "🙂🙃🙂" const canary = "🙂🙃🙂"
str := "{" str := "{"
str = f.Body str += f.body
str = strings.ReplaceAll(str, `\#`, canary) str = strings.ReplaceAll(str, `\#`, canary)
for i, a := range args { for i, a := range args {
str = strings.ReplaceAll(str, fmt.Sprintf("#%d", i), a) str = strings.ReplaceAll(str, fmt.Sprintf("#%d", i+1), a)
} }
str = strings.ReplaceAll(str, canary, `\#`) str = strings.ReplaceAll(str, canary, `\#`)
str += "}" str += "}"
var e error
str, e = InlineAllFuncs(str)
if e != nil {
panic(e)
}
return str return str
} }
var funcs = make([]FunctionImplementation, 0) var funcs = []flattenable{
&Input,
}
var cmdRegex = regexp.MustCompile(`\\newcommand{`) var cmdRegex = regexp.MustCompile(`\\newcommand{`)
...@@ -121,14 +152,13 @@ func ParseFile(filename string) error { ...@@ -121,14 +152,13 @@ func ParseFile(filename string) error {
} }
fi := FunctionImplementation{ fi := FunctionImplementation{
Name: name, name: name,
Body: body, body: body,
ArgNum: argNum, argNum: argNum,
} }
funcs = append(funcs, fi) funcs = append(funcs, &fi)
} }
return nil return nil
} }
package flatten
import (
"bytes"
"fmt"
"git.sch.bme.hu/insert-epic-projlab-team-name-here/tooling/plab/helpers"
"io"
"io/ioutil"
"os"
"os/exec"
)
type input struct {
flattenable
}
func (i *input) Inline(args ...string) string {
arg := args[0]
if arg[0] == '|' {
cmd := exec.Command("sh", "-c", helpers.Unescape(arg[1:]))
out, e := cmd.Output()
if e != nil {
_, _ = fmt.Fprint(os.Stderr, "error running command:", helpers.Unescape(arg[1:]), "\n")
var stde bytes.Buffer
rd, er := cmd.StderrPipe()
if er == nil {
_, _ = io.Copy(&stde, rd)
_, _ = fmt.Fprint(os.Stderr, stde.String(), "\n")
}
panic(e)
}
return string(out)
} else {
by, e := ioutil.ReadFile(arg)
if e != nil {
panic(e)
}
in, e := InlineAllFuncs(string(by))
if e != nil {
panic(e)
}
return in
}
}
func (i *input) Name() string {
return "\\input"
}
func (i *input) ArgNum() int {
return 1
}
var Input = input{}
...@@ -7,3 +7,9 @@ func Unescape(s string) string { ...@@ -7,3 +7,9 @@ func Unescape(s string) string {
_ = json.Unmarshal([]byte(s), &ret) _ = json.Unmarshal([]byte(s), &ret)
return ret return ret
} }
func Escape(s string) string {
ret, _ := json.Marshal(s)
ret = ret[1 : len(ret)-1]
return string(ret)
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment