From 658ab1ba98971370b741a0a4cc5fba4da107ce29 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mikl=C3=B3s=20T=C3=B3th?= <tothmiklostibor@gmail.com> Date: Sun, 9 May 2021 23:09:49 +0200 Subject: [PATCH] flatten all the things --- plab/flatten/flatten.go | 15 ++++++- plab/flatten/flattenable.go | 4 +- plab/flatten/function.go | 88 +++++++++++++++++++++++++------------ plab/flatten/input.go | 55 +++++++++++++++++++++++ plab/helpers/unescape.go | 6 +++ 5 files changed, 137 insertions(+), 31 deletions(-) create mode 100644 plab/flatten/input.go diff --git a/plab/flatten/flatten.go b/plab/flatten/flatten.go index 7f4e616..af95aa8 100644 --- a/plab/flatten/flatten.go +++ b/plab/flatten/flatten.go @@ -3,6 +3,8 @@ package flatten import ( "fmt" "git.sch.bme.hu/insert-epic-projlab-team-name-here/tooling/plab/helpers" + "io/ioutil" + "os" ) var Flatten = helpers.Subcommand{ @@ -26,7 +28,18 @@ var Flatten = helpers.Subcommand{ 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", } diff --git a/plab/flatten/flattenable.go b/plab/flatten/flattenable.go index b84178b..090c552 100644 --- a/plab/flatten/flattenable.go +++ b/plab/flatten/flattenable.go @@ -1,5 +1,7 @@ package flatten type flattenable interface { - Flatten() string + Name() string + Inline(args ...string) string + ArgNum() int } diff --git a/plab/flatten/function.go b/plab/flatten/function.go index 2bc8052..e04e120 100644 --- a/plab/flatten/function.go +++ b/plab/flatten/function.go @@ -2,8 +2,8 @@ package flatten import ( "bytes" - "errors" "fmt" + "git.sch.bme.hu/insert-epic-projlab-team-name-here/tooling/plab/helpers" "io/ioutil" "regexp" "strconv" @@ -11,15 +11,25 @@ import ( ) type FunctionImplementation struct { - Name string - Body string - ArgNum int + flattenable + name string + 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) { for _, f := range funcs { 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 { return "", e } @@ -29,44 +39,65 @@ func InlineAllFuncs(str string) (string, error) { nameStart := i[0] 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]) + prevStop = nameStart args := make([]string, 0) - for i := 0; i < fi.ArgNum; i++ { + argStop := argsStart + for i := 0; i < f.ArgNum(); i++ { depth := 0 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 + } + } + 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 + return str, nil } func (f *FunctionImplementation) Inline(args ...string) string { const canary = "🙂🙃🙂" str := "{" - str = f.Body + str += f.body str = strings.ReplaceAll(str, `\#`, canary) 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 += "}" + var e error + str, e = InlineAllFuncs(str) + if e != nil { + panic(e) + } return str } -var funcs = make([]FunctionImplementation, 0) +var funcs = []flattenable{ + &Input, +} var cmdRegex = regexp.MustCompile(`\\newcommand{`) @@ -82,10 +113,10 @@ func ParseFile(filename string) error { for _, i := range idx { nameStart := i[1] - nameStop := strings.Index(str[nameStart:], "}")+nameStart + nameStop := strings.Index(str[nameStart:], "}") + nameStart name := str[nameStart:nameStop] - bodystart := strings.Index(str[nameStop:], "{")+nameStop+1 + bodystart := strings.Index(str[nameStop:], "{") + nameStop + 1 var depth = 0 var bodyend = 0 for i, r := range str[bodystart:] { @@ -121,14 +152,13 @@ func ParseFile(filename string) error { } fi := FunctionImplementation{ - Name: name, - Body: body, - ArgNum: argNum, + name: name, + body: body, + argNum: argNum, } - funcs = append(funcs, fi) + funcs = append(funcs, &fi) } return nil } - diff --git a/plab/flatten/input.go b/plab/flatten/input.go new file mode 100644 index 0000000..e903222 --- /dev/null +++ b/plab/flatten/input.go @@ -0,0 +1,55 @@ +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{} diff --git a/plab/helpers/unescape.go b/plab/helpers/unescape.go index 0e8fc62..b4f3ff7 100644 --- a/plab/helpers/unescape.go +++ b/plab/helpers/unescape.go @@ -7,3 +7,9 @@ func Unescape(s string) string { _ = json.Unmarshal([]byte(s), &ret) return ret } + +func Escape(s string) string { + ret, _ := json.Marshal(s) + ret = ret[1 : len(ret)-1] + return string(ret) +} -- GitLab