├── .github └── workflows │ └── go.yml ├── .gitignore ├── CONTRIBUTING.md ├── COPYING ├── README.md ├── _talks └── GolangUK2017 │ ├── README.md │ ├── background.png │ ├── context.go │ ├── decorated.go │ ├── describe.go │ ├── elf_dump.go │ ├── empty.go │ ├── filler.png │ ├── filtering.go │ ├── fprint_table.html │ ├── functions.go │ ├── go_list.html │ ├── head_tail.go │ ├── if.go │ ├── index.go │ ├── loops.go │ ├── macho_dump.go │ ├── promote.go │ ├── qanda.html │ ├── rows_cols.go │ ├── select.go │ ├── sorting.go │ ├── table.go │ ├── table_fmt.go │ ├── table_templ.go │ ├── table_templ_hl.go │ ├── templates.slide │ ├── title.html │ ├── tojson.go │ ├── undecorated.go │ └── unexported.go ├── defaults.go ├── example_test.go ├── examples ├── csv │ └── csv.go ├── elf_dump │ ├── README.md │ └── elf_dump.go └── tmplex │ └── tmplex.go ├── funcs.go ├── go.mod ├── tfortools.go ├── tfortools_test.go └── usage.go /.github/workflows/go.yml: -------------------------------------------------------------------------------- 1 | name: Go 2 | 3 | on: 4 | push: 5 | branches: [ master ] 6 | pull_request: 7 | branches: [ master ] 8 | 9 | jobs: 10 | 11 | build: 12 | runs-on: ubuntu-latest 13 | steps: 14 | - uses: actions/checkout@v2 15 | 16 | - name: Set up Go 17 | uses: actions/setup-go@v2 18 | with: 19 | go-version: 1.16 20 | 21 | - name: Build 22 | run: go build -v ./... 23 | 24 | - name: Test 25 | run: go test -v ./... 26 | 27 | - name: Install golang-ci-lint 28 | run: curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $(go env GOPATH)/bin v1.40.1 29 | 30 | - name: golang-ci-lint 31 | run: golangci-lint run --tests --disable-all --enable=misspell --enable=vet --enable=ineffassign --enable=gofmt --enable=gocyclo --enable=revive --enable=errcheck --enable=deadcode ./... 32 | 33 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *~ 2 | tfortools 3 | examples/tmplex/tmplex 4 | examples/csv/csv 5 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing to Templates for Tools 2 | 3 | Templates for Tools is an open source project licensed under the [Apache v2 License] (https://opensource.org/licenses/Apache-2.0) 4 | 5 | ## Coding Style 6 | 7 | Templates for Tools follows the standard formatting recommendations and language idioms set out 8 | in [Effective Go](https://golang.org/doc/effective_go.html) and in the 9 | [Go Code Review Comments wiki](https://github.com/golang/go/wiki/CodeReviewComments). 10 | 11 | ## Certificate of Origin 12 | 13 | In order to get a clear contribution chain of trust we use the [signed-off-by language] (https://01.org/community/signed-process) 14 | used by the Linux kernel project. 15 | 16 | ## Patch format 17 | 18 | Beside the signed-off-by footer, we expect each patch to comply with the following format: 19 | 20 | ``` 21 | Change summary 22 | 23 | More detailed explanation of your changes: Why and how. 24 | Wrap it to 72 characters. 25 | See [here] (http://chris.beams.io/posts/git-commit/) 26 | for some more good advices. 27 | 28 | Fixes #NUMBER (or URL to the issue) 29 | 30 | Signed-off-by: 31 | ``` 32 | 33 | For example: 34 | 35 | ``` 36 | Fix poorly named identifiers 37 | 38 | One identifier, fnname, in func.go was poorly named. It has been renamed 39 | to fnName. Another identifier retval was not needed and has been removed 40 | entirely. 41 | 42 | Fixes #1 43 | 44 | Signed-off-by: Mark Ryan 45 | ``` 46 | 47 | ## Pull requests 48 | 49 | We accept github pull requests. 50 | 51 | ## Quality Controls 52 | 53 | We request you give quality assurance some consideration by: 54 | 55 | * Adding go unit tests for changes where it makes sense. 56 | * Enabling [Travis CI](https://travis-ci.org/intel/tfortools) on your github fork of Templates for Tools to get continuous integration feedback on your dev/test branches. 57 | 58 | ## Issue tracking 59 | 60 | If you find a bug please [open a github issue](https://github.com/intel/tfortools/issues/new). 61 | -------------------------------------------------------------------------------- /COPYING: -------------------------------------------------------------------------------- 1 | 2 | Apache License 3 | Version 2.0, January 2004 4 | http://www.apache.org/licenses/ 5 | 6 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 7 | 8 | 1. Definitions. 9 | 10 | "License" shall mean the terms and conditions for use, reproduction, 11 | and distribution as defined by Sections 1 through 9 of this document. 12 | 13 | "Licensor" shall mean the copyright owner or entity authorized by 14 | the copyright owner that is granting the License. 15 | 16 | "Legal Entity" shall mean the union of the acting entity and all 17 | other entities that control, are controlled by, or are under common 18 | control with that entity. For the purposes of this definition, 19 | "control" means (i) the power, direct or indirect, to cause the 20 | direction or management of such entity, whether by contract or 21 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 22 | outstanding shares, or (iii) beneficial ownership of such entity. 23 | 24 | "You" (or "Your") shall mean an individual or Legal Entity 25 | exercising permissions granted by this License. 26 | 27 | "Source" form shall mean the preferred form for making modifications, 28 | including but not limited to software source code, documentation 29 | source, and configuration files. 30 | 31 | "Object" form shall mean any form resulting from mechanical 32 | transformation or translation of a Source form, including but 33 | not limited to compiled object code, generated documentation, 34 | and conversions to other media types. 35 | 36 | "Work" shall mean the work of authorship, whether in Source or 37 | Object form, made available under the License, as indicated by a 38 | copyright notice that is included in or attached to the work 39 | (an example is provided in the Appendix below). 40 | 41 | "Derivative Works" shall mean any work, whether in Source or Object 42 | form, that is based on (or derived from) the Work and for which the 43 | editorial revisions, annotations, elaborations, or other modifications 44 | represent, as a whole, an original work of authorship. For the purposes 45 | of this License, Derivative Works shall not include works that remain 46 | separable from, or merely link (or bind by name) to the interfaces of, 47 | the Work and Derivative Works thereof. 48 | 49 | "Contribution" shall mean any work of authorship, including 50 | the original version of the Work and any modifications or additions 51 | to that Work or Derivative Works thereof, that is intentionally 52 | submitted to Licensor for inclusion in the Work by the copyright owner 53 | or by an individual or Legal Entity authorized to submit on behalf of 54 | the copyright owner. For the purposes of this definition, "submitted" 55 | means any form of electronic, verbal, or written communication sent 56 | to the Licensor or its representatives, including but not limited to 57 | communication on electronic mailing lists, source code control systems, 58 | and issue tracking systems that are managed by, or on behalf of, the 59 | Licensor for the purpose of discussing and improving the Work, but 60 | excluding communication that is conspicuously marked or otherwise 61 | designated in writing by the copyright owner as "Not a Contribution." 62 | 63 | "Contributor" shall mean Licensor and any individual or Legal Entity 64 | on behalf of whom a Contribution has been received by Licensor and 65 | subsequently incorporated within the Work. 66 | 67 | 2. Grant of Copyright License. Subject to the terms and conditions of 68 | this License, each Contributor hereby grants to You a perpetual, 69 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 70 | copyright license to reproduce, prepare Derivative Works of, 71 | publicly display, publicly perform, sublicense, and distribute the 72 | Work and such Derivative Works in Source or Object form. 73 | 74 | 3. Grant of Patent License. Subject to the terms and conditions of 75 | this License, each Contributor hereby grants to You a perpetual, 76 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 77 | (except as stated in this section) patent license to make, have made, 78 | use, offer to sell, sell, import, and otherwise transfer the Work, 79 | where such license applies only to those patent claims licensable 80 | by such Contributor that are necessarily infringed by their 81 | Contribution(s) alone or by combination of their Contribution(s) 82 | with the Work to which such Contribution(s) was submitted. If You 83 | institute patent litigation against any entity (including a 84 | cross-claim or counterclaim in a lawsuit) alleging that the Work 85 | or a Contribution incorporated within the Work constitutes direct 86 | or contributory patent infringement, then any patent licenses 87 | granted to You under this License for that Work shall terminate 88 | as of the date such litigation is filed. 89 | 90 | 4. Redistribution. You may reproduce and distribute copies of the 91 | Work or Derivative Works thereof in any medium, with or without 92 | modifications, and in Source or Object form, provided that You 93 | meet the following conditions: 94 | 95 | (a) You must give any other recipients of the Work or 96 | Derivative Works a copy of this License; and 97 | 98 | (b) You must cause any modified files to carry prominent notices 99 | stating that You changed the files; and 100 | 101 | (c) You must retain, in the Source form of any Derivative Works 102 | that You distribute, all copyright, patent, trademark, and 103 | attribution notices from the Source form of the Work, 104 | excluding those notices that do not pertain to any part of 105 | the Derivative Works; and 106 | 107 | (d) If the Work includes a "NOTICE" text file as part of its 108 | distribution, then any Derivative Works that You distribute must 109 | include a readable copy of the attribution notices contained 110 | within such NOTICE file, excluding those notices that do not 111 | pertain to any part of the Derivative Works, in at least one 112 | of the following places: within a NOTICE text file distributed 113 | as part of the Derivative Works; within the Source form or 114 | documentation, if provided along with the Derivative Works; or, 115 | within a display generated by the Derivative Works, if and 116 | wherever such third-party notices normally appear. The contents 117 | of the NOTICE file are for informational purposes only and 118 | do not modify the License. You may add Your own attribution 119 | notices within Derivative Works that You distribute, alongside 120 | or as an addendum to the NOTICE text from the Work, provided 121 | that such additional attribution notices cannot be construed 122 | as modifying the License. 123 | 124 | You may add Your own copyright statement to Your modifications and 125 | may provide additional or different license terms and conditions 126 | for use, reproduction, or distribution of Your modifications, or 127 | for any such Derivative Works as a whole, provided Your use, 128 | reproduction, and distribution of the Work otherwise complies with 129 | the conditions stated in this License. 130 | 131 | 5. Submission of Contributions. Unless You explicitly state otherwise, 132 | any Contribution intentionally submitted for inclusion in the Work 133 | by You to the Licensor shall be under the terms and conditions of 134 | this License, without any additional terms or conditions. 135 | Notwithstanding the above, nothing herein shall supersede or modify 136 | the terms of any separate license agreement you may have executed 137 | with Licensor regarding such Contributions. 138 | 139 | 6. Trademarks. This License does not grant permission to use the trade 140 | names, trademarks, service marks, or product names of the Licensor, 141 | except as required for reasonable and customary use in describing the 142 | origin of the Work and reproducing the content of the NOTICE file. 143 | 144 | 7. Disclaimer of Warranty. Unless required by applicable law or 145 | agreed to in writing, Licensor provides the Work (and each 146 | Contributor provides its Contributions) on an "AS IS" BASIS, 147 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 148 | implied, including, without limitation, any warranties or conditions 149 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 150 | PARTICULAR PURPOSE. You are solely responsible for determining the 151 | appropriateness of using or redistributing the Work and assume any 152 | risks associated with Your exercise of permissions under this License. 153 | 154 | 8. Limitation of Liability. In no event and under no legal theory, 155 | whether in tort (including negligence), contract, or otherwise, 156 | unless required by applicable law (such as deliberate and grossly 157 | negligent acts) or agreed to in writing, shall any Contributor be 158 | liable to You for damages, including any direct, indirect, special, 159 | incidental, or consequential damages of any character arising as a 160 | result of this License or out of the use or inability to use the 161 | Work (including but not limited to damages for loss of goodwill, 162 | work stoppage, computer failure or malfunction, or any and all 163 | other commercial damages or losses), even if such Contributor 164 | has been advised of the possibility of such damages. 165 | 166 | 9. Accepting Warranty or Additional Liability. While redistributing 167 | the Work or Derivative Works thereof, You may choose to offer, 168 | and charge a fee for, acceptance of support, warranty, indemnity, 169 | or other liability obligations and/or rights consistent with this 170 | License. However, in accepting such obligations, You may act only 171 | on Your own behalf and on Your sole responsibility, not on behalf 172 | of any other Contributor, and only if You agree to indemnify, 173 | defend, and hold each Contributor harmless for any liability 174 | incurred by, or claims asserted against, such Contributor by reason 175 | of your accepting any such warranty or additional liability. 176 | 177 | END OF TERMS AND CONDITIONS 178 | 179 | APPENDIX: How to apply the Apache License to your work. 180 | 181 | To apply the Apache License to your work, attach the following 182 | boilerplate notice, with the fields enclosed by brackets "[]" 183 | replaced with your own identifying information. (Don't include 184 | the brackets!) The text should be enclosed in the appropriate 185 | comment syntax for the file format. We also recommend that a 186 | file or class name and description of purpose be included on the 187 | same "printed page" as the copyright notice for easier 188 | identification within third-party archives. 189 | 190 | Copyright [yyyy] [name of copyright owner] 191 | 192 | Licensed under the Apache License, Version 2.0 (the "License"); 193 | you may not use this file except in compliance with the License. 194 | You may obtain a copy of the License at 195 | 196 | http://www.apache.org/licenses/LICENSE-2.0 197 | 198 | Unless required by applicable law or agreed to in writing, software 199 | distributed under the License is distributed on an "AS IS" BASIS, 200 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 201 | See the License for the specific language governing permissions and 202 | limitations under the License. 203 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Templates for Tools 2 | 3 | [![Go Report Card](https://goreportcard.com/badge/github.com/intel/tfortools)](https://goreportcard.com/report/github.com/intel/tfortools) 4 | [![GoDoc](https://godoc.org/github.com/intel/tfortools?status.svg)](https://godoc.org/github.com/intel/tfortools) 5 | 6 | Package tfortools provides a set of functions that are designed to 7 | make it easier for developers to add template based scripting to their 8 | command line tools. 9 | 10 | Command line tools written in Go often allow users to specify a template 11 | script to tailor the output of the tool to their specific needs. This can be 12 | useful both when visually inspecting the data and also when invoking command 13 | line tools in scripts. The best example of this is go list which allows users 14 | to pass a template script to extract interesting information about Go 15 | packages. For example, 16 | 17 | ``` 18 | go list -f '{{range .Imports}}{{println .}}{{end}}' 19 | ``` 20 | 21 | prints all the imports of the current package. 22 | 23 | The aim of this package is to make it easier for developers to add template 24 | scripting support to their tools and easier for users of these tools to 25 | extract the information they need. It does this by augmenting the 26 | templating language provided by the standard library package text/template in 27 | two ways: 28 | 29 | 1. It auto generates descriptions of the data structures passed as 30 | input to a template script for use in help messages. This ensures 31 | that help usage information is always up to date with the source code. 32 | 33 | 2. It provides a suite of convenience functions to make it easy for 34 | script writers to extract the data they need. There are functions for 35 | sorting, selecting rows and columns and generating nicely formatted 36 | tables. 37 | 38 | For example, if a program passed a slice of structs containing stock 39 | data to a template script, we could use the following script to extract 40 | the names of the 3 stocks with the highest trade volume. 41 | 42 | ``` 43 | {{table (cols (head (sort . "Volume" "dsc") 3) "Name" "Volume")}} 44 | ``` 45 | 46 | The output might look something like this: 47 | 48 | ``` 49 | Name Volume 50 | Happy Enterprises 6395624278 51 | Big Company 7500000 52 | Medium Company 300122 53 | ``` 54 | 55 | The functions head, sort, tables and col are provided by this package. 56 | -------------------------------------------------------------------------------- /_talks/GolangUK2017/README.md: -------------------------------------------------------------------------------- 1 | # Command Line Scripting with Templates 2 | 3 | Here are the slides for the "Command Line Scripting with Templates" talk given at 4 | GolangUK 2017 in London. A video of the talk is available on 5 | [YouTube](https://www.youtube.com/watch?v=UMbicEbSIjc). 6 | 7 | The slides are written using [Go's present tool](https://godoc.org/golang.org/x/tools/cmd/present). 8 | To view them you need to first install present. This can be done as follows. 9 | 10 | 1. Download and install Go (https://golang.org/dl/) 11 | 2. Ensure ``` `go env GOPATH` ``` is in your PATH 12 | 3. go get github.com/intel/tfortools 13 | 4. go get golang.org/x/tools/cmd/present 14 | 5. cd to this directory 15 | 6. present 16 | 17 | You should see a URL on the terminal window. Paste this into your browser. Click on the first link, template.slides 18 | -------------------------------------------------------------------------------- /_talks/GolangUK2017/background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intel/tfortools/f29b131673ea15dcd767ea61f36b225e14225991/_talks/GolangUK2017/background.png -------------------------------------------------------------------------------- /_talks/GolangUK2017/context.go: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) 2017 Intel Corporation 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // 16 | 17 | package main 18 | 19 | import "text/template" 20 | import "os" 21 | 22 | 23 | type address struct { 24 | House string 25 | Street string 26 | PostCode string 27 | Country string 28 | } 29 | 30 | type person struct { 31 | FirstName string 32 | FamilyName string 33 | Address address 34 | PhoneNumbers []string 35 | } 36 | 37 | func main() { 38 | source := 39 | //START OMIT 40 | `{{ "Who's this guy and where does he live" }} 41 | {{.FirstName}} 42 | {{with .Address -}} 43 | The {{ .Country }} is where {{$.FirstName}} lives. {{/* . refers to Address instance */}} 44 | {{end}}` 45 | 46 | p := person{ FirstName: "Markus", Address : address{Country: "UK"}} 47 | //END OMIT 48 | tmpl := template.Must(template.New("table").Parse(source)) 49 | err := tmpl.Execute(os.Stdout, p) 50 | if err != nil { 51 | panic(err) 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /_talks/GolangUK2017/decorated.go: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) 2017 Intel Corporation 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // 16 | 17 | package main 18 | 19 | import ( 20 | "fmt" 21 | "time" 22 | 23 | "github.com/intel/tfortools" 24 | ) 25 | 26 | //STRUCT OMIT 27 | type stock struct { 28 | Ticker string 29 | Name string 30 | LastTrade time.Time 31 | Current float64 32 | High float64 33 | Low float64 34 | Volume int 35 | } 36 | 37 | var fictionalStocks = []stock{ 38 | {"BCOM.L", "Big Company", time.Date(2017, time.March, 17, 11, 01, 00, 00, time.UTC), 120.23, 150.00, 119.00, 7500000}, 39 | //STRUCT OMIT 40 | 41 | {"SMAL.L", "Small Company", time.Date(2017, time.March, 17, 10, 59, 00, 00, time.UTC), 1.06, 1.06, 1.10, 750}, 42 | {"MEDI.L", "Medium Company", time.Date(2017, time.March, 17, 12, 23, 00, 00, time.UTC), 77.00, 75.11, 81.12, 300122}, 43 | {"PICO.L", "Tiny Corp", time.Date(2017, time.March, 16, 16, 01, 00, 00, time.UTC), 0.59, 0.57, 0.63, 155}, 44 | {"HENT.L", "Happy Enterprises", time.Date(2017, time.March, 17, 9, 45, 00, 00, time.UTC), 756.11, 600.00, 10000, 6395624278}, 45 | {"LONL.L", "Lonely Systems", time.Date(2017, time.March, 17, 13, 45, 00, 00, time.UTC), 1245.00, 1200.00, 1245.00, 19003}, 46 | } 47 | 48 | func main() { 49 | //START OMIT 50 | fmt.Print(tfortools.GenerateUsageDecorated("f", fictionalStocks, nil)) 51 | //END OMIT 52 | } 53 | -------------------------------------------------------------------------------- /_talks/GolangUK2017/describe.go: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) 2017 Intel Corporation 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // 16 | 17 | package main 18 | 19 | import ( 20 | "os" 21 | "time" 22 | 23 | "github.com/intel/tfortools" 24 | ) 25 | 26 | type stock struct { 27 | Ticker string 28 | Name string 29 | LastTrade time.Time 30 | Current float64 31 | High float64 32 | Low float64 33 | Volume int 34 | } 35 | 36 | var fictionalStocks = []stock{ 37 | {"BCOM.L", "Big Company", time.Now(), 120.23, 150.00, 119.00, 7500000}, 38 | {"SMAL.L", "Small Company", time.Date(2017, time.March, 17, 10, 59, 00, 00, time.UTC), 1.06, 1.06, 1.10, 750}, 39 | {"MEDI.L", "Medium Company", time.Date(2017, time.March, 17, 12, 23, 00, 00, time.UTC), 77.00, 75.11, 81.12, 300122}, 40 | {"PICO.L", "Tiny Corp", time.Date(2017, time.March, 16, 16, 01, 00, 00, time.UTC), 0.59, 0.57, 0.63, 155}, 41 | {"HENT.L", "Happy Enterprises", time.Date(2017, time.March, 17, 9, 45, 00, 00, time.UTC), 756.11, 600.00, 10000, 6395624278}, 42 | {"LONL.L", "Lonely Systems", time.Date(2017, time.March, 17, 13, 45, 00, 00, time.UTC), 1245.00, 1200.00, 1245.00, 19003}, 43 | } 44 | 45 | func main() { 46 | //START OMIT 47 | const script = `{{ describe . }}` // HL 48 | 49 | err := tfortools.OutputToTemplate(os.Stdout, "describe", script, fictionalStocks, nil) 50 | //END OMIT 51 | if err != nil { 52 | panic(err) 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /_talks/GolangUK2017/elf_dump.go: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) 2017 Intel Corporation 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // 16 | 17 | package main 18 | 19 | import "os" 20 | 21 | //START OMIT 22 | import "debug/elf" 23 | import "github.com/intel/tfortools" 24 | 25 | func main() { 26 | if len(os.Args) != 3 { 27 | panic("Usage: elf_dump script file") 28 | } 29 | 30 | f, err := os.Open(os.Args[2]) 31 | if err != nil { 32 | panic(err) 33 | } 34 | defer func() { _ = f.Close() }() 35 | ef, err := elf.NewFile(f) 36 | if err != nil { 37 | panic(err) 38 | } 39 | 40 | err = tfortools.OutputToTemplate(os.Stdout, "elf_dump", os.Args[1], ef, nil) 41 | if err != nil { 42 | panic(err) 43 | } 44 | } 45 | 46 | //END OMIT 47 | -------------------------------------------------------------------------------- /_talks/GolangUK2017/empty.go: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) 2017 Intel Corporation 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // 16 | 17 | package main 18 | 19 | import ( 20 | "os" 21 | "time" 22 | 23 | "github.com/intel/tfortools" 24 | ) 25 | 26 | type stock struct { 27 | Ticker string 28 | Name string 29 | LastTrade time.Time 30 | Current float64 31 | High float64 32 | Low float64 33 | Volume int 34 | } 35 | 36 | //START OMIT 37 | var fictionalStocks = []interface{}{ // HL 38 | stock{"BCOM.L", "Big Company", time.Now(), 120.23, 150.00, 119.00, 7500000}, 39 | } 40 | 41 | func main() { 42 | const script = `{{ describe . }}` // HL 43 | err := tfortools.OutputToTemplate(os.Stdout, "filter", script, fictionalStocks, nil) 44 | //END OMIT 45 | if err != nil { 46 | panic(err) 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /_talks/GolangUK2017/filler.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intel/tfortools/f29b131673ea15dcd767ea61f36b225e14225991/_talks/GolangUK2017/filler.png -------------------------------------------------------------------------------- /_talks/GolangUK2017/filtering.go: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) 2017 Intel Corporation 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // 16 | 17 | package main 18 | 19 | import ( 20 | "os" 21 | "time" 22 | 23 | "github.com/intel/tfortools" 24 | ) 25 | 26 | type stock struct { 27 | Ticker string 28 | Name string 29 | LastTrade time.Time 30 | Current float64 31 | High float64 32 | Low float64 33 | Volume int 34 | } 35 | 36 | var fictionalStocks = []stock{ 37 | {"BCOM.L", "Big Company", time.Now(), 120.23, 150.00, 119.00, 7500000}, 38 | {"SMAL.L", "Small Company", time.Date(2017, time.March, 17, 10, 59, 00, 00, time.UTC), 1.06, 1.06, 1.10, 750}, 39 | {"MEDI.L", "Medium Company", time.Date(2017, time.March, 17, 12, 23, 00, 00, time.UTC), 77.00, 75.11, 81.12, 300122}, 40 | {"PICO.L", "Tiny Corp", time.Date(2017, time.March, 16, 16, 01, 00, 00, time.UTC), 0.59, 0.57, 0.63, 155}, 41 | {"HENT.L", "Happy Enterprises", time.Date(2017, time.March, 17, 9, 45, 00, 00, time.UTC), 756.11, 600.00, 10000, 6395624278}, 42 | {"LONL.L", "Lonely Systems", time.Date(2017, time.March, 17, 13, 45, 00, 00, time.UTC), 1245.00, 1200.00, 1245.00, 19003}, 43 | } 44 | 45 | func main() { 46 | //START OMIT 47 | const script = `{{ table (filterContains . "Name" "Company") }}` // HL 48 | 49 | err := tfortools.OutputToTemplate(os.Stdout, "filter", script, fictionalStocks, nil) 50 | //END OMIT 51 | if err != nil { 52 | panic(err) 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /_talks/GolangUK2017/fprint_table.html: -------------------------------------------------------------------------------- 1 |
2 | 3 |
 func fprintTable(w io.Writer, db []person) error {
 4 |     const header = `<html>
 5 |   <head>
 6 |     <title>Important Contacts</title>
 7 |   </head>
 8 |   <body>
 9 |     <table border=1 style="width:100%%">
10 |       <tr><th>Name</th><th>Address</th><th>First Number</th><th>Second Number</th></tr>
11 | `
12 |     if _, err := fmt.Fprintf(w, header); err != nil {
13 |         return err
14 |     }
15 |     for _, p := range db {
16 |         if _, err := fmt.Fprintf(w, "      <tr><td>%s %s</td>", p.FirstName, p.FamilyName); err != nil {
17 |             return err
18 |         }
19 |         if _, err := fmt.Fprintf(w, "<td>%s %s</td>", p.Address.House, p.Address.Street); err != nil {
20 |             return err
21 |         }
22 |         for _, num := range p.PhoneNumbers {
23 |             if _, err := fmt.Fprintf(w, "<td>%s</td>", num); err != nil {
24 |                 return err
25 |             }
26 |         }
27 |         if _, err := fmt.Fprintf(w, "</tr>\n"); err != nil {
28 |             return err
29 |         }
30 |     }
31 |     if _, err := fmt.Fprintf(w, "    </table>\n  </body>\n</html>\n"); err != nil {
32 |         return err
33 |     }
34 |     return nil
35 | }
36 | 
37 | 38 |
39 | -------------------------------------------------------------------------------- /_talks/GolangUK2017/functions.go: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) 2017 Intel Corporation 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // 16 | 17 | package main 18 | 19 | import "os" 20 | import "strings" 21 | import "text/template" 22 | 23 | type address struct { 24 | House string 25 | Street string 26 | PostCode string 27 | Country string 28 | } 29 | 30 | type person struct { 31 | FirstName string 32 | FamilyName string 33 | Address address 34 | PhoneNumbers []string 35 | } 36 | 37 | func main() { 38 | source := 39 | //START OMIT 40 | `{{.FirstName}} 41 | {{trim .FirstName}} 42 | {{trim .FirstName | title}} 43 | ` 44 | 45 | p := person{ FirstName : " shamrock "} 46 | funcMap := template.FuncMap{ 47 | "title": strings.Title, 48 | "trim": strings.TrimSpace, 49 | } 50 | tmpl := template.Must(template.New("table").Funcs(funcMap).Parse(source)) // HL 51 | err := tmpl.Execute(os.Stdout, p) 52 | //END OMIT 53 | if err != nil { 54 | panic(err) 55 | } 56 | } 57 | 58 | -------------------------------------------------------------------------------- /_talks/GolangUK2017/go_list.html: -------------------------------------------------------------------------------- 1 |
 2 | 
 3 | 
 4 | 
 5 | 
 6 | 
 7 | 
 8 | 
 9 | 
10 | 
11 |   
12 |          go list
13 | 
14 | -------------------------------------------------------------------------------- /_talks/GolangUK2017/head_tail.go: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) 2017 Intel Corporation 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // 16 | 17 | package main 18 | 19 | import ( 20 | "os" 21 | "time" 22 | 23 | "github.com/intel/tfortools" 24 | ) 25 | 26 | type stock struct { 27 | Ticker string 28 | Name string 29 | LastTrade time.Time 30 | Current float64 31 | High float64 32 | Low float64 33 | Volume int 34 | } 35 | 36 | var fictionalStocks = []stock{ 37 | {"BCOM.L", "Big Company", time.Now(), 120.23, 150.00, 119.00, 7500000}, 38 | {"SMAL.L", "Small Company", time.Date(2017, time.March, 17, 10, 59, 00, 00, time.UTC), 1.06, 1.06, 1.10, 750}, 39 | {"MEDI.L", "Medium Company", time.Date(2017, time.March, 17, 12, 23, 00, 00, time.UTC), 77.00, 75.11, 81.12, 300122}, 40 | {"PICO.L", "Tiny Corp", time.Date(2017, time.March, 16, 16, 01, 00, 00, time.UTC), 0.59, 0.57, 0.63, 155}, 41 | {"HENT.L", "Happy Enterprises", time.Date(2017, time.March, 17, 9, 45, 00, 00, time.UTC), 756.11, 600.00, 10000, 6395624278}, 42 | {"LONL.L", "Lonely Systems", time.Date(2017, time.March, 17, 13, 45, 00, 00, time.UTC), 1245.00, 1200.00, 1245.00, 19003}, 43 | } 44 | 45 | func main() { 46 | //START OMIT 47 | const script = `{{ table (head .) }}` // HL 48 | 49 | err := tfortools.OutputToTemplate(os.Stdout, "head_tail", script, fictionalStocks, nil) 50 | //END OMIT 51 | if err != nil { 52 | panic(err) 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /_talks/GolangUK2017/if.go: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) 2017 Intel Corporation 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // 16 | 17 | package main 18 | 19 | import "text/template" 20 | import "os" 21 | 22 | type address struct { 23 | House string 24 | Street string 25 | PostCode string 26 | Country string 27 | } 28 | 29 | type person struct { 30 | FirstName string 31 | FamilyName string 32 | Address address 33 | PhoneNumbers []string 34 | } 35 | 36 | func main() { 37 | source := 38 | //START OMIT 39 | `{ 40 | "phone_numbers" : [ 41 | {{- range $i, $val := .PhoneNumbers -}} 42 | {{if ne $i 0 }},{{end -}} // HL 43 | "{{$val}}" 44 | {{- end}}] 45 | } 46 | ` 47 | p := person{PhoneNumbers: []string{"11111111111", "2222222222"}} 48 | //END OMIT 49 | tmpl := template.Must(template.New("table").Parse(source)) 50 | err := tmpl.Execute(os.Stdout, p) 51 | if err != nil { 52 | panic(err) 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /_talks/GolangUK2017/index.go: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) 2017 Intel Corporation 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // 16 | 17 | package main 18 | 19 | import "text/template" 20 | import "os" 21 | 22 | type address struct { 23 | House string 24 | Street string 25 | PostCode string 26 | Country string 27 | } 28 | 29 | type person struct { 30 | FirstName string 31 | FamilyName string 32 | Address address 33 | PhoneNumbers []string 34 | } 35 | 36 | func main() { 37 | source := 38 | //START OMIT 39 | `{{index .PhoneNumbers 1}} {{index .PhoneNumbers 0}}` 40 | 41 | p := person{PhoneNumbers: []string{"11111111111", "2222222222"}} 42 | //END OMIT 43 | tmpl := template.Must(template.New("table").Parse(source)) 44 | err := tmpl.Execute(os.Stdout, p) 45 | if err != nil { 46 | panic(err) 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /_talks/GolangUK2017/loops.go: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) 2017 Intel Corporation 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // 16 | 17 | package main 18 | 19 | import "text/template" 20 | import "os" 21 | 22 | 23 | type address struct { 24 | House string 25 | Street string 26 | PostCode string 27 | Country string 28 | } 29 | 30 | type person struct { 31 | FirstName string 32 | FamilyName string 33 | Address address 34 | PhoneNumbers []string 35 | } 36 | 37 | func main() { 38 | source := 39 | //START OMIT 40 | `{{range .PhoneNumbers -}} 41 | {{.}} {{/* . refers to a slice element */}} 42 | {{end}}` 43 | 44 | p := person{ PhoneNumbers : []string{"11111111111", "2222222222"}} 45 | //END OMIT 46 | tmpl := template.Must(template.New("table").Parse(source)) 47 | err := tmpl.Execute(os.Stdout, p) 48 | if err != nil { 49 | panic(err) 50 | } 51 | } 52 | 53 | -------------------------------------------------------------------------------- /_talks/GolangUK2017/macho_dump.go: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) 2017 Intel Corporation 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // 16 | 17 | package main 18 | 19 | import ( 20 | "debug/macho" 21 | "os" 22 | 23 | "github.com/intel/tfortools" 24 | ) //START OMIT 25 | 26 | func main() { 27 | if len(os.Args) != 3 { 28 | panic("Usage: elf_dump script file") 29 | } 30 | 31 | f, err := os.Open(os.Args[2]) 32 | if err != nil { 33 | panic(err) 34 | } 35 | defer func() { _ = f.Close() }() 36 | ef, err := macho.NewFile(f) 37 | if err != nil { 38 | panic(err) 39 | } 40 | 41 | err = tfortools.OutputToTemplate(os.Stdout, "elf_dump", os.Args[1], ef, nil) 42 | if err != nil { 43 | panic(err) 44 | } 45 | } 46 | 47 | //END OMIT 48 | -------------------------------------------------------------------------------- /_talks/GolangUK2017/promote.go: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) 2017 Intel Corporation 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // 16 | 17 | package main 18 | 19 | import ( 20 | "os" 21 | "time" 22 | 23 | "github.com/intel/tfortools" 24 | ) 25 | 26 | type stock struct { 27 | Ticker string 28 | Name string 29 | LastTrade time.Time 30 | Current float64 31 | High float64 32 | Low float64 33 | Volume int 34 | } 35 | 36 | var fictionalStocks = []stock{ 37 | {"BCOM.L", "Big Company", time.Now(), 120.23, 150.00, 119.00, 7500000}, 38 | {"SMAL.L", "Small Company", time.Date(2017, time.March, 17, 10, 59, 00, 00, time.UTC), 1.06, 1.06, 1.10, 750}, 39 | {"MEDI.L", "Medium Company", time.Date(2017, time.March, 17, 12, 23, 00, 00, time.UTC), 77.00, 75.11, 81.12, 300122}, 40 | {"PICO.L", "Tiny Corp", time.Date(2017, time.March, 16, 16, 01, 00, 00, time.UTC), 0.59, 0.57, 0.63, 155}, 41 | {"HENT.L", "Happy Enterprises", time.Date(2017, time.March, 17, 9, 45, 00, 00, time.UTC), 756.11, 600.00, 10000, 6395624278}, 42 | {"LONL.L", "Lonely Systems", time.Date(2017, time.March, 17, 13, 45, 00, 00, time.UTC), 1245.00, 1200.00, 1245.00, 19003}, 43 | } 44 | 45 | func main() { 46 | //START OMIT 47 | const script = `{{ tojson (promote . "Name")}}` // HL 48 | 49 | err := tfortools.OutputToTemplate(os.Stdout, "promote", script, fictionalStocks, nil) 50 | //END OMIT 51 | if err != nil { 52 | panic(err) 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /_talks/GolangUK2017/qanda.html: -------------------------------------------------------------------------------- 1 |
 2 | 
 3 | 
 4 | 
 5 | 
 6 | 
 7 | 
 8 | 
 9 | 
10 | 
11 |   
12 |            Q & A
13 | 
14 | -------------------------------------------------------------------------------- /_talks/GolangUK2017/rows_cols.go: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) 2017 Intel Corporation 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // 16 | 17 | package main 18 | 19 | import ( 20 | "os" 21 | "time" 22 | 23 | "github.com/intel/tfortools" 24 | ) 25 | 26 | type stock struct { 27 | Ticker string 28 | Name string 29 | LastTrade time.Time 30 | Current float64 31 | High float64 32 | Low float64 33 | Volume int 34 | } 35 | 36 | var fictionalStocks = []stock{ 37 | {"BCOM.L", "Big Company", time.Now(), 120.23, 150.00, 119.00, 7500000}, 38 | {"SMAL.L", "Small Company", time.Date(2017, time.March, 17, 10, 59, 00, 00, time.UTC), 1.06, 1.06, 1.10, 750}, 39 | {"MEDI.L", "Medium Company", time.Date(2017, time.March, 17, 12, 23, 00, 00, time.UTC), 77.00, 75.11, 81.12, 300122}, 40 | {"PICO.L", "Tiny Corp", time.Date(2017, time.March, 16, 16, 01, 00, 00, time.UTC), 0.59, 0.57, 0.63, 155}, 41 | {"HENT.L", "Happy Enterprises", time.Date(2017, time.March, 17, 9, 45, 00, 00, time.UTC), 756.11, 600.00, 10000, 6395624278}, 42 | {"LONL.L", "Lonely Systems", time.Date(2017, time.March, 17, 13, 45, 00, 00, time.UTC), 1245.00, 1200.00, 1245.00, 19003}, 43 | } 44 | 45 | func main() { 46 | //START OMIT 47 | const script = `{{ table (rows . 1 3 5) }}` // HL 48 | 49 | err := tfortools.OutputToTemplate(os.Stdout, "rows_cols", script, fictionalStocks, nil) 50 | //END OMIT 51 | if err != nil { 52 | panic(err) 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /_talks/GolangUK2017/select.go: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) 2017 Intel Corporation 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // 16 | 17 | package main 18 | 19 | import ( 20 | "os" 21 | "time" 22 | 23 | "github.com/intel/tfortools" 24 | ) 25 | 26 | type stock struct { 27 | Ticker string 28 | Name string 29 | LastTrade time.Time 30 | Current float64 31 | High float64 32 | Low float64 33 | Volume int 34 | } 35 | 36 | var fictionalStocks = []stock{ 37 | {"BCOM.L", "Big Company", time.Now(), 120.23, 150.00, 119.00, 7500000}, 38 | {"SMAL.L", "Small Company", time.Date(2017, time.March, 17, 10, 59, 00, 00, time.UTC), 1.06, 1.06, 1.10, 750}, 39 | {"MEDI.L", "Medium Company", time.Date(2017, time.March, 17, 12, 23, 00, 00, time.UTC), 77.00, 75.11, 81.12, 300122}, 40 | {"PICO.L", "Tiny Corp", time.Date(2017, time.March, 16, 16, 01, 00, 00, time.UTC), 0.59, 0.57, 0.63, 155}, 41 | {"HENT.L", "Happy Enterprises", time.Date(2017, time.March, 17, 9, 45, 00, 00, time.UTC), 756.11, 600.00, 10000, 6395624278}, 42 | {"LONL.L", "Lonely Systems", time.Date(2017, time.March, 17, 13, 45, 00, 00, time.UTC), 1245.00, 1200.00, 1245.00, 19003}, 43 | } 44 | 45 | func main() { 46 | //START OMIT 47 | const script = `{{ select . "Ticker" }}` // HL 48 | 49 | err := tfortools.OutputToTemplate(os.Stdout, "filter", script, fictionalStocks, nil) 50 | //END OMIT 51 | if err != nil { 52 | panic(err) 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /_talks/GolangUK2017/sorting.go: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) 2017 Intel Corporation 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // 16 | 17 | package main 18 | 19 | import ( 20 | "os" 21 | "time" 22 | 23 | "github.com/intel/tfortools" 24 | ) 25 | 26 | type stock struct { 27 | Ticker string 28 | Name string 29 | LastTrade time.Time 30 | Current float64 31 | High float64 32 | Low float64 33 | Volume int 34 | } 35 | 36 | var fictionalStocks = []stock{ 37 | {"BCOM.L", "Big Company", time.Now(), 120.23, 150.00, 119.00, 7500000}, 38 | {"SMAL.L", "Small Company", time.Date(2017, time.March, 17, 10, 59, 00, 00, time.UTC), 1.06, 1.06, 1.10, 750}, 39 | {"MEDI.L", "Medium Company", time.Date(2017, time.March, 17, 12, 23, 00, 00, time.UTC), 77.00, 75.11, 81.12, 300122}, 40 | {"PICO.L", "Tiny Corp", time.Date(2017, time.March, 16, 16, 01, 00, 00, time.UTC), 0.59, 0.57, 0.63, 155}, 41 | {"HENT.L", "Happy Enterprises", time.Date(2017, time.March, 17, 9, 45, 00, 00, time.UTC), 756.11, 600.00, 10000, 6395624278}, 42 | {"LONL.L", "Lonely Systems", time.Date(2017, time.March, 17, 13, 45, 00, 00, time.UTC), 1245.00, 1200.00, 1245.00, 19003}, 43 | } 44 | 45 | func main() { 46 | //START OMIT 47 | const script = `{{ table (sort . "Name") }}` // HL 48 | 49 | err := tfortools.OutputToTemplate(os.Stdout, "filter", script, fictionalStocks, nil) 50 | //END OMIT 51 | if err != nil { 52 | panic(err) 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /_talks/GolangUK2017/table.go: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) 2017 Intel Corporation 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // 16 | 17 | package main 18 | 19 | import ( 20 | "os" 21 | "time" 22 | 23 | "github.com/intel/tfortools" 24 | ) 25 | 26 | type stock struct { 27 | Ticker string 28 | Name string 29 | LastTrade time.Time 30 | Current float64 31 | High float64 32 | Low float64 33 | Volume int 34 | } 35 | 36 | var fictionalStocks = []stock{ 37 | {"BCOM.L", "Big Company", time.Now(), 120.23, 150.00, 119.00, 7500000}, 38 | {"SMAL.L", "Small Company", time.Date(2017, time.March, 17, 10, 59, 00, 00, time.UTC), 1.06, 1.06, 1.10, 750}, 39 | {"MEDI.L", "Medium Company", time.Date(2017, time.March, 17, 12, 23, 00, 00, time.UTC), 77.00, 75.11, 81.12, 300122}, 40 | {"PICO.L", "Tiny Corp", time.Date(2017, time.March, 16, 16, 01, 00, 00, time.UTC), 0.59, 0.57, 0.63, 155}, 41 | {"HENT.L", "Happy Enterprises", time.Date(2017, time.March, 17, 9, 45, 00, 00, time.UTC), 756.11, 600.00, 10000, 6395624278}, 42 | {"LONL.L", "Lonely Systems", time.Date(2017, time.March, 17, 13, 45, 00, 00, time.UTC), 1245.00, 1200.00, 1245.00, 19003}, 43 | } 44 | 45 | func main() { 46 | //START OMIT 47 | const script = `{{ table .}}` // HL 48 | 49 | err := tfortools.OutputToTemplate(os.Stdout, "filter", script, fictionalStocks, nil) 50 | //END OMIT 51 | if err != nil { 52 | panic(err) 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /_talks/GolangUK2017/table_fmt.go: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) 2017 Intel Corporation 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // 16 | 17 | package main 18 | 19 | import ( 20 | "fmt" 21 | "io" 22 | "os" 23 | ) 24 | 25 | //START OMIT 26 | type address struct { 27 | House, Street, PostCode, Country string 28 | } 29 | 30 | type person struct { 31 | FirstName, FamilyName string 32 | Address address 33 | PhoneNumbers [2]string 34 | } 35 | 36 | var db = []person{ 37 | {"John", "Doe", address{"19", "Nowhere", "BP9", "UK"}, [2]string{"12121212121", "214345677"}}, 38 | {"Jane", "Doe", address{"1900", "Somewhere", "SK12", "UK"}, [2]string{"987654331", "172846281"}}, 39 | {"Joe", "Bloggs", address{"1900", "Zig Zig", "W10", "UK"}, 40 | [2]string{``}}, 41 | //END OMIT 42 | } 43 | 44 | //FPRINTSTART OMIT 45 | func fprintTable(w io.Writer, db []person) error { 46 | const header = ` 47 | 48 | Important Contacts 49 | 50 | 51 | 52 | 53 | ` 54 | if _, err := fmt.Fprintf(w, header); err != nil { 55 | return err 56 | } 57 | for _, p := range db { 58 | if _, err := fmt.Fprintf(w, " ", p.FirstName, p.FamilyName); err != nil { 59 | return err 60 | } 61 | if _, err := fmt.Fprintf(w, "", p.Address.House, p.Address.Street); err != nil { 62 | return err 63 | } 64 | for _, num := range p.PhoneNumbers { 65 | if _, err := fmt.Fprintf(w, "", num); err != nil { 66 | return err 67 | } 68 | } 69 | if _, err := fmt.Fprintf(w, "\n"); err != nil { 70 | return err 71 | } 72 | } 73 | if _, err := fmt.Fprintf(w, "
NameAddressFirst NumberSecond Number
%s %s%s %s%s
\n \n\n"); err != nil { 74 | return err 75 | } 76 | 77 | return nil 78 | } 79 | 80 | //FPRINTEND OMIT 81 | 82 | //START1 OMIT 83 | func main() { 84 | if err := fprintTable(os.Stdout, db); err != nil { 85 | panic(err) 86 | } 87 | } 88 | 89 | //END1 OMIT 90 | -------------------------------------------------------------------------------- /_talks/GolangUK2017/table_templ.go: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) 2017 Intel Corporation 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // 16 | 17 | package main 18 | 19 | import ( 20 | "html/template" 21 | "io" 22 | "os" 23 | ) 24 | 25 | //START OMIT 26 | type address struct { 27 | House string 28 | Street string 29 | PostCode string 30 | Country string 31 | } 32 | 33 | type person struct { 34 | FirstName string 35 | FamilyName string 36 | Address address 37 | PhoneNumbers [2]string 38 | } 39 | 40 | var db = []person{ 41 | {"John", "Doe", address{"19", "Nowhere", "BP9", "UK"}, [2]string{"12121212121", "214345677"}}, 42 | {"Jane", "Doe", address{"1900", "Somwhere", "SK12", "UK"}, [2]string{"987654331"}}, 43 | //... 44 | //END OMIT 45 | {"Joe", "Bloggs", address{"1900", "Zig Zig", "W10", "UK"}, [2]string{``}}, 46 | } 47 | 48 | //TEMPLATESTART OMIT 49 | func templateTable(w io.Writer, db []person) error { 50 | const source = ` 51 | 52 | Important Contacts 53 | 54 | 55 | 56 | 57 | {{- range .}} 58 | 59 | {{- range .PhoneNumbers}}{{end}} 60 | {{- end}} 61 |
NameAddressFirst NumberSecond Number
{{.FirstName}} {{.FamilyName}}{{.Address.House}} {{.Address.Street}}{{.}}
62 | 63 | ` 64 | 65 | tmpl := template.Must(template.New("table").Parse(source)) 66 | return tmpl.Execute(w, db) 67 | } 68 | 69 | //TEMPLATEEND OMIT 70 | 71 | //START1 OMIT 72 | func main() { 73 | if err := templateTable(os.Stdout, db); err != nil { 74 | panic(err) 75 | } 76 | } 77 | 78 | //END1 OMIT 79 | -------------------------------------------------------------------------------- /_talks/GolangUK2017/table_templ_hl.go: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) 2017 Intel Corporation 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // 16 | 17 | package main 18 | 19 | import ( 20 | "html/template" 21 | "io" 22 | "os" 23 | ) 24 | 25 | //START OMIT 26 | type address struct { 27 | House string 28 | Street string 29 | PostCode string 30 | Country string 31 | } 32 | 33 | type person struct { 34 | FirstName string 35 | FamilyName string 36 | Address address 37 | PhoneNumbers [2]string 38 | } 39 | 40 | var db = []person{ 41 | {"John", "Doe", address{"19", "Nowhere", "BP9", "UK"}, [2]string{"12121212121", "214345677"}}, 42 | {"Jane", "Doe", address{"1900", "Somwhere", "SK12", "UK"}, [2]string{"987654331"}}, 43 | //... 44 | //END OMIT 45 | {"Joe", "Bloggs", address{"1900", "Zig Zig", "W10", "UK"}, [2]string{``}}, 46 | } 47 | 48 | //TEMPLATESTART OMIT 49 | func templateTable(w io.Writer, db []person) error { 50 | const source = ` 51 | 52 | Important Contacts 53 | 54 | 55 | 56 | 57 | {{- range .}} // HL 58 | // HL 59 | {{- range .PhoneNumbers}}{{end}} // HL 60 | {{- end}} // HL 61 |
NameAddressFirst NumberSecond Number
{{.FirstName}} {{.FamilyName}}{{.Address.House}} {{.Address.Street}}{{.}}
62 | 63 | ` 64 | 65 | tmpl := template.Must(template.New("table").Parse(source)) 66 | return tmpl.Execute(w, db) 67 | } 68 | 69 | //TEMPLATEEND OMIT 70 | 71 | //START1 OMIT 72 | func main() { 73 | if err := templateTable(os.Stdout, db); err != nil { 74 | panic(err) 75 | } 76 | } 77 | 78 | //END1 OMIT 79 | -------------------------------------------------------------------------------- /_talks/GolangUK2017/templates.slide: -------------------------------------------------------------------------------- 1 | Command Line Scripting with Templates 2 | 3 | 18th August 2017 4 | 5 | Mark Ryan 6 | Software Engineer OTC London 7 | mark.d.ryan@intel.com 8 | 9 | * 10 | 11 | .html title.html 12 | 13 | .background filler.png 14 | 15 | * An Example 16 | 17 | .code table_fmt.go /START OMIT/,/END OMIT/ 18 | 19 | .play table_fmt.go /START1 OMIT/,/END1 OMIT/ 20 | 21 | .background background.png 22 | 23 | 24 | * Generate HTML with Go code 25 | 26 | .html fprint_table.html 27 | 28 | .background background.png 29 | 30 | 31 | * Generate HTML with a Go Template 32 | 33 | .play table_templ_hl.go /TEMPLATESTART OMIT/,/TEMPLATEEND OMIT/ 34 | 35 | .background background.png 36 | 37 | 38 | * Template Primer 39 | 40 | Pipelines and Context 41 | 42 | .play -edit context.go /START OMIT/,/END OMIT/ 43 | 44 | .background background.png 45 | 46 | Loops 47 | 48 | .play -edit loops.go /START OMIT/,/END OMIT/ 49 | 50 | .background background.png 51 | 52 | 53 | * Template Fun Facts 54 | 55 | There are two template packages 56 | 57 | .link https://golang.org/pkg/text/template/ 58 | 59 | .link https://golang.org/pkg/html/template/ 60 | 61 | Fields operated on by templates need to be exported 62 | 63 | .play -edit unexported.go /START OMIT/,/END OMIT/ 64 | 65 | .background background.png 66 | 67 | 68 | * Template Primer 2 69 | 70 | If statements 71 | 72 | .play -edit if.go /START OMIT/,/END OMIT/ 73 | 74 | Indexing maps and slices 75 | 76 | .play -edit index.go /START OMIT/,/END OMIT/ 77 | 78 | .background background.png 79 | 80 | * Template Primer 3 81 | 82 | Functions 83 | 84 | .play -edit functions.go /START OMIT/,/END OMIT/ 85 | 86 | .background background.png 87 | 88 | * 89 | 90 | .html go_list.html 91 | 92 | .background filler.png 93 | 94 | * Scripting issues 95 | 96 | - Keeping help up to date is a nightmare 97 | .link https://github.com/golang/go/blob/master/src/cmd/go/internal/list/list.go#L25 list.go 98 | - Extracting information is either too hard or just not possible 99 | {{range $i, $v := .Deps}}{{if lt $i 3}}{{println .}}{{end}}{{end}} 100 | - Converting to JSON is a pain 101 | - Cannot count elements that match a query 102 | - Cannot output the last element of a collection 103 | - Cannot sort the output 104 | - Pretty printing the output is also a pain 105 | 106 | * Templates for Tools 107 | 108 | Package to facilitate command line scripting with templates 109 | .link https://github.com/intel/tfortools https://github.com/intel/tfortools 110 | 111 | The package provides 112 | 113 | - Automatic generation of help messages 114 | - Filtering 115 | - Sorting 116 | - Data extraction 117 | - Conversion of selected parts of the data to JSON 118 | - Pretty printing of data 119 | 120 | .background background.png 121 | 122 | * Help Messages 123 | 124 | .code undecorated.go /STRUCT OMIT/,/STRUCT OMIT/ 125 | 126 | Undecorated help 127 | 128 | .play -edit undecorated.go /START OMIT/,/END OMIT/ 129 | 130 | Decorated help 131 | 132 | .play -edit decorated.go /START OMIT/,/END OMIT/ 133 | 134 | .background background.png 135 | 136 | 137 | * Formatting 138 | 139 | Table 140 | 141 | .play -edit table.go /START OMIT/,/END OMIT/ 142 | 143 | Select 144 | 145 | .play -edit select.go /START OMIT/,/END OMIT/ 146 | 147 | Sort 148 | 149 | .play -edit sorting.go /START OMIT/,/END OMIT/ 150 | 151 | .background background.png 152 | 153 | * Extracting 154 | 155 | Filter 156 | 157 | .play -edit filtering.go /START OMIT/,/END OMIT/ 158 | 159 | Head and Tail 160 | 161 | .play -edit head_tail.go /START OMIT/,/END OMIT/ 162 | 163 | Row and Cols 164 | 165 | .play -edit rows_cols.go /START OMIT/,/END OMIT/ 166 | 167 | .background background.png 168 | 169 | * More Formatting 170 | 171 | ToJson 172 | 173 | .play -edit tojson.go /START OMIT/,/END OMIT/ 174 | 175 | Describe 176 | 177 | .play -edit describe.go /START OMIT/,/END OMIT/ 178 | 179 | Promote 180 | 181 | .play -edit promote.go /START OMIT/,/END OMIT/ 182 | 183 | .background background.png 184 | 185 | * ELF Dump 186 | 187 | .code elf_dump.go /START OMIT/,/END OMIT/ 188 | 189 | * Guidelines 190 | 191 | - Allow users to tailor the output of your tools 192 | - Always document types passed to template scripts 193 | - These types constitute a public API 194 | - Apply templates to entire collections rather than elements of collections 195 | - Avoid interface{} in your public types 196 | 197 | .play -edit empty.go /START OMIT/,/END OMIT/ 198 | 199 | .background background.png 200 | 201 | * 202 | 203 | .html qanda.html 204 | 205 | .background filler.png 206 | 207 | -------------------------------------------------------------------------------- /_talks/GolangUK2017/title.html: -------------------------------------------------------------------------------- 1 |
 2 | 
 3 | 
 4 | 
 5 |   Command Line Scripting
 6 | 
 7 |   
 8 |   with Templates
 9 | 
10 | 
11 |   
12 | 
13 | 14 |
15 | 
16 | 
17 |   
18 |   
19 |      18th August 2017
20 | 
21 |   
22 |      Mark Ryan
23 |   
24 |      Software Engineer OTC London
25 |   
26 |      mark.d.ryan@intel.com
27 |            
28 | 
29 | -------------------------------------------------------------------------------- /_talks/GolangUK2017/tojson.go: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) 2017 Intel Corporation 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // 16 | 17 | package main 18 | 19 | import ( 20 | "os" 21 | "time" 22 | 23 | "github.com/intel/tfortools" 24 | ) 25 | 26 | type stock struct { 27 | Ticker string 28 | Name string 29 | LastTrade time.Time 30 | Current float64 31 | High float64 32 | Low float64 33 | Volume int 34 | } 35 | 36 | var fictionalStocks = []stock{ 37 | {"BCOM.L", "Big Company", time.Now(), 120.23, 150.00, 119.00, 7500000}, 38 | {"SMAL.L", "Small Company", time.Date(2017, time.March, 17, 10, 59, 00, 00, time.UTC), 1.06, 1.06, 1.10, 750}, 39 | {"MEDI.L", "Medium Company", time.Date(2017, time.March, 17, 12, 23, 00, 00, time.UTC), 77.00, 75.11, 81.12, 300122}, 40 | {"PICO.L", "Tiny Corp", time.Date(2017, time.March, 16, 16, 01, 00, 00, time.UTC), 0.59, 0.57, 0.63, 155}, 41 | {"HENT.L", "Happy Enterprises", time.Date(2017, time.March, 17, 9, 45, 00, 00, time.UTC), 756.11, 600.00, 10000, 6395624278}, 42 | {"LONL.L", "Lonely Systems", time.Date(2017, time.March, 17, 13, 45, 00, 00, time.UTC), 1245.00, 1200.00, 1245.00, 19003}, 43 | } 44 | 45 | func main() { 46 | //START OMIT 47 | const script = `{{ tojson . }}` // HL 48 | 49 | err := tfortools.OutputToTemplate(os.Stdout, "tojson", script, fictionalStocks, nil) 50 | //END OMIT 51 | if err != nil { 52 | panic(err) 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /_talks/GolangUK2017/undecorated.go: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) 2017 Intel Corporation 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // 16 | 17 | package main 18 | 19 | import ( 20 | "fmt" 21 | "time" 22 | 23 | "github.com/intel/tfortools" 24 | ) 25 | 26 | //STRUCT OMIT 27 | type stock struct { 28 | Ticker string 29 | Name string 30 | LastTrade time.Time 31 | Current float64 32 | High float64 33 | Low float64 34 | Volume int 35 | } 36 | var fictionalStocks = []stock{ 37 | {"BCOM.L", "Big Company", time.Now(), 120.23, 150.00, 119.00, 7500000}, 38 | // ... 39 | //STRUCT OMIT 40 | 41 | {"SMAL.L", "Small Company", time.Date(2017, time.March, 17, 10, 59, 00, 00, time.UTC), 1.06, 1.06, 1.10, 750}, 42 | {"MEDI.L", "Medium Company", time.Date(2017, time.March, 17, 12, 23, 00, 00, time.UTC), 77.00, 75.11, 81.12, 300122}, 43 | {"PICO.L", "Tiny Corp", time.Date(2017, time.March, 16, 16, 01, 00, 00, time.UTC), 0.59, 0.57, 0.63, 155}, 44 | {"HENT.L", "Happy Enterprises", time.Date(2017, time.March, 17, 9, 45, 00, 00, time.UTC), 756.11, 600.00, 10000, 6395624278}, 45 | {"LONL.L", "Lonely Systems", time.Date(2017, time.March, 17, 13, 45, 00, 00, time.UTC), 1245.00, 1200.00, 1245.00, 19003}, 46 | } 47 | 48 | func main() { 49 | //START OMIT 50 | fmt.Print(tfortools.GenerateUsageUndecorated(fictionalStocks)) 51 | //END OMIT 52 | } 53 | -------------------------------------------------------------------------------- /_talks/GolangUK2017/unexported.go: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) 2017 Intel Corporation 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // 16 | 17 | package main 18 | 19 | import "os" 20 | import "text/template" 21 | 22 | //START OMIT 23 | var test = struct { 24 | name string 25 | }{ 26 | "Markus", 27 | } 28 | 29 | func main() { 30 | const source = "{{.name}}" 31 | tmpl := template.Must(template.New("table").Parse(source)) 32 | tmpl.Execute(os.Stdout, test) 33 | } 34 | 35 | //END OMIT 36 | -------------------------------------------------------------------------------- /defaults.go: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) 2017 Intel Corporation 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // 16 | 17 | package tfortools 18 | 19 | import "text/template" 20 | 21 | var funcMap = template.FuncMap{ 22 | "filter": filterByField, 23 | "filterContains": filterByContains, 24 | "filterHasPrefix": filterByHasPrefix, 25 | "filterHasSuffix": filterByHasSuffix, 26 | "filterFolded": filterByFolded, 27 | "filterRegexp": filterByRegexp, 28 | "tojson": toJSON, 29 | "tocsv": toCSV, 30 | "select": selectField, 31 | "selectalt": selectFieldAlt, 32 | "table": table, 33 | "tablealt": tableAlt, 34 | "tablex": tablex, 35 | "tablexalt": tablexAlt, 36 | "htable": htable, 37 | "htablealt": htableAlt, 38 | "htablex": htablex, 39 | "htablexalt": htablexAlt, 40 | "cols": cols, 41 | "sort": sortSlice, 42 | "rows": rows, 43 | "head": head, 44 | "tail": tail, 45 | "describe": describe, 46 | "promote": promote, 47 | "sliceof": sliceof, 48 | "totable": toTable, 49 | } 50 | 51 | var funcHelpSlice = []funcHelpInfo{ 52 | {"filter", helpFilter, helpFilterIndex}, 53 | {"filterContains", helpFilterContains, helpFilterContainsIndex}, 54 | {"filterHasPrefix", helpFilterHasPrefix, helpFilterHasPrefixIndex}, 55 | {"filterHasSuffix", helpFilterHasSuffix, helpFilterHasSuffixIndex}, 56 | {"filterFolded", helpFilterFolded, helpFilterFoldedIndex}, 57 | {"filterRegexp", helpFilterRegexp, helpFilterRegexpIndex}, 58 | {"tojson", helpToJSON, helpToJSONIndex}, 59 | {"tocsv", helpToCSV, helpToCSVIndex}, 60 | {"select", helpSelect, helpSelectIndex}, 61 | {"selectalt", helpSelectAlt, helpSelectAltIndex}, 62 | {"table", helpTable, helpTableIndex}, 63 | {"tablealt", helpTableAlt, helpTableAltIndex}, 64 | {"tablex", helpTableX, helpTableXIndex}, 65 | {"tablexalt", helpTableXAlt, helpTableXAltIndex}, 66 | {"htable", helpHTable, helpHTableIndex}, 67 | {"htablealt", helpHTableAlt, helpHTableAltIndex}, 68 | {"htablex", helpHTableX, helpHTableXIndex}, 69 | {"htablexalt", helpHTableXAlt, helpHTableXAltIndex}, 70 | {"cols", helpCols, helpColsIndex}, 71 | {"sort", helpSort, helpSortIndex}, 72 | {"rows", helpRows, helpRowsIndex}, 73 | {"head", helpHead, helpHeadIndex}, 74 | {"tail", helpTail, helpTailIndex}, 75 | {"describe", helpDescribe, helpDescribeIndex}, 76 | {"promote", helpPromote, helpPromoteIndex}, 77 | {"sliceof", helpSliceof, helpSliceofIndex}, 78 | {"totable", helpToTable, helpToTableIndex}, 79 | } 80 | 81 | func getFuncMap(cfg *Config) template.FuncMap { 82 | if cfg == nil { 83 | return funcMap 84 | } 85 | 86 | return cfg.funcMap 87 | } 88 | 89 | func getHelpers(cfg *Config) []funcHelpInfo { 90 | if cfg == nil { 91 | return funcHelpSlice 92 | } 93 | 94 | return cfg.funcHelp 95 | } 96 | -------------------------------------------------------------------------------- /example_test.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2017 Intel Corporation 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package tfortools 16 | 17 | import ( 18 | "bufio" 19 | "bytes" 20 | "fmt" 21 | "os" 22 | "strings" 23 | ) 24 | 25 | func ExampleGenerateUsageDecorated() { 26 | cfg := NewConfig(OptCols) 27 | help := GenerateUsageDecorated("-f", []struct{ X, Y int }{}, cfg) 28 | fmt.Println(help) 29 | // output: 30 | // The template passed to the --f option operates on a 31 | // 32 | // []struct { 33 | // X int 34 | // Y int 35 | // } 36 | // 37 | // Some new functions have been added to Go's template language 38 | // 39 | // - 'cols' can be used to extract certain columns from a table consisting of a 40 | // slice or array of structs. It returns a new slice of structs which contain 41 | // only the fields requested by the caller. For example, given a slice of structs 42 | // 43 | // {{cols . "Name" "Address"}} 44 | // 45 | // returns a new slice of structs, each element of which is a structure with only 46 | // two fields, 'Name' and 'Address'. 47 | } 48 | 49 | func ExampleGenerateUsageUndecorated() { 50 | i := struct { 51 | X int `tfortools:"This is an int"` 52 | Y string `json:"omitempty" tfortools:"This is a string"` 53 | hidden float64 54 | Invalid chan int 55 | }{} 56 | help := GenerateUsageUndecorated(i) 57 | fmt.Println(help) 58 | // output: 59 | // struct { 60 | // X int // This is an int 61 | // Y string `json:"omitempty"` // This is a string 62 | // } 63 | } 64 | 65 | func ExampleTemplateFunctionNames() { 66 | cfg := NewConfig(OptCols, OptRows) 67 | err := cfg.AddCustomFn(strings.TrimSpace, "trim", 68 | "- trim trims leading and trailing whitespace from string") 69 | if err != nil { 70 | panic(err) 71 | } 72 | for _, fn := range TemplateFunctionNames(cfg) { 73 | fmt.Println(fn) 74 | } 75 | // output: 76 | // cols 77 | // rows 78 | // trim 79 | } 80 | 81 | func ExampleTemplateFunctionHelpSingle() { 82 | cfg := NewConfig(OptCols, OptRows) 83 | err := cfg.AddCustomFn(strings.TrimSpace, "trim", 84 | "- trim trims leading and trailing whitespace from string") 85 | if err != nil { 86 | panic(err) 87 | } 88 | help, err := TemplateFunctionHelpSingle("cols", cfg) 89 | if err != nil { 90 | panic(err) 91 | } 92 | fmt.Println(help) 93 | 94 | help, err = TemplateFunctionHelpSingle("trim", cfg) 95 | if err != nil { 96 | panic(err) 97 | } 98 | fmt.Println(help) 99 | // output: 100 | // - 'cols' can be used to extract certain columns from a table consisting of a 101 | // slice or array of structs. It returns a new slice of structs which contain 102 | // only the fields requested by the caller. For example, given a slice of structs 103 | // 104 | // {{cols . "Name" "Address"}} 105 | // 106 | // returns a new slice of structs, each element of which is a structure with only 107 | // two fields, 'Name' and 'Address'. 108 | // 109 | // - trim trims leading and trailing whitespace from string 110 | } 111 | 112 | func ExampleOutputToTemplate() { 113 | data := []struct{ FirstName, MiddleName, Surname string }{ 114 | {"Marcus", "Tullius", "Cicero"}, 115 | {"Gaius", "Julius", "Caesar"}, 116 | {"Marcus", "Licinius", "Crassus"}, 117 | } 118 | 119 | // print the surname of the person whose middlename is lexographically smallest. 120 | script := `{{select (head (sort . "MiddleName")) "Surname"}}` 121 | if err := OutputToTemplate(os.Stdout, "names", script, data, nil); err != nil { 122 | panic(err) 123 | } 124 | // output: 125 | // Caesar 126 | } 127 | 128 | func ExampleOptFilter() { 129 | data := []struct{ FirstName, MiddleName, Surname string }{ 130 | {"Marcus", "Tullius", "Cicero"}, 131 | {"Gaius", "Julius", "Caesar"}, 132 | {"Marcus", "Licinius", "Crassus"}, 133 | } 134 | 135 | // Print the surname of all people whose first name is Marcus 136 | script := `{{range (filter . "FirstName" "Marcus")}}{{println .Surname}}{{end}}` 137 | if err := OutputToTemplate(os.Stdout, "names", script, data, nil); err != nil { 138 | panic(err) 139 | } 140 | // output: 141 | // Cicero 142 | // Crassus 143 | } 144 | 145 | func ExampleOptFilterContains() { 146 | data := []struct{ FirstName, MiddleName, Surname string }{ 147 | {"Marcus", "Tullius", "Cicero"}, 148 | {"Gaius", "Julius", "Caesar"}, 149 | {"Marcus", "Licinius", "Crassus"}, 150 | } 151 | 152 | // Count the number of people whose middle name contains a 'ul' 153 | script := `{{len (filterContains . "MiddleName" "ul")}}` 154 | if err := OutputToTemplate(os.Stdout, "names", script, data, nil); err != nil { 155 | panic(err) 156 | } 157 | // output: 158 | // 2 159 | } 160 | 161 | func ExampleOptFilterHasPrefix() { 162 | data := []struct{ FirstName, MiddleName, Surname string }{ 163 | {"Marcus", "Tullius", "Cicero"}, 164 | {"Gaius", "Julius", "Caesar"}, 165 | {"Marcus", "Licinius", "Crassus"}, 166 | } 167 | 168 | // Print all the surnames that start with 'Ci' 169 | script := `{{select (filterHasPrefix . "Surname" "Ci") "Surname"}}` 170 | if err := OutputToTemplate(os.Stdout, "names", script, data, nil); err != nil { 171 | panic(err) 172 | } 173 | // output: 174 | // Cicero 175 | } 176 | 177 | func ExampleOptFilterHasSuffix() { 178 | data := []struct{ FirstName, MiddleName, Surname string }{ 179 | {"Marcus", "Tullius", "Cicero"}, 180 | {"Gaius", "Julius", "Caesar"}, 181 | {"Marcus", "Licinius", "Crassus"}, 182 | } 183 | 184 | // Print all the surnames that end with 'us' 185 | script := `{{select (filterHasSuffix . "Surname" "us") "Surname"}}` 186 | if err := OutputToTemplate(os.Stdout, "names", script, data, nil); err != nil { 187 | panic(err) 188 | } 189 | // output: 190 | // Crassus 191 | } 192 | 193 | func ExampleOptFilterFolded() { 194 | data := []struct{ FirstName, MiddleName, Surname string }{ 195 | {"Marcus", "Tullius", "Cicero"}, 196 | {"Gaius", "Julius", "Caesar"}, 197 | {"Marcus", "Licinius", "Crassus"}, 198 | } 199 | 200 | // Output the first and surnames of all people whose first name is marcus 201 | script := `{{range (filterFolded . "FirstName" "marcus")}}{{println .FirstName .Surname}}{{end}}` 202 | if err := OutputToTemplate(os.Stdout, "names", script, data, nil); err != nil { 203 | panic(err) 204 | } 205 | // output: 206 | // Marcus Cicero 207 | // Marcus Crassus 208 | } 209 | 210 | func ExampleOptFilterRegexp() { 211 | data := []struct{ FirstName, MiddleName, Surname string }{ 212 | {"Marcus", "Tullius", "Cicero"}, 213 | {"Gaius", "Julius", "Caesar"}, 214 | {"Marcus", "Licinius", "Crassus"}, 215 | } 216 | 217 | // Output the first and last names of all people whose middle name ends in 'ius' and whose 218 | // second letter is 'u' 219 | script := `{{range (filterRegexp . "MiddleName" "^.u.*ius$")}}{{println .FirstName .Surname}}{{end}}` 220 | if err := OutputToTemplate(os.Stdout, "names", script, data, nil); err != nil { 221 | panic(err) 222 | } 223 | // output: 224 | // Marcus Cicero 225 | // Gaius Caesar 226 | } 227 | 228 | func ExampleOptToJSON() { 229 | data := []struct { 230 | Name string 231 | AgeAtDeath int 232 | Battles []string 233 | }{ 234 | {"Caesar", 55, []string{"Battle of Alesia", "Battle of Dyrrhachium", "Battle of the Nile"}}, 235 | {"Alexander", 32, []string{"Battle of Issus", "Battle of Gaugamela", "Battle of the Hydaspes"}}, 236 | } 237 | 238 | script := `{{tojson .}}` 239 | if err := OutputToTemplate(os.Stdout, "names", script, data, nil); err != nil { 240 | panic(err) 241 | } 242 | // output: 243 | // [ 244 | // { 245 | // "Name": "Caesar", 246 | // "AgeAtDeath": 55, 247 | // "Battles": [ 248 | // "Battle of Alesia", 249 | // "Battle of Dyrrhachium", 250 | // "Battle of the Nile" 251 | // ] 252 | // }, 253 | // { 254 | // "Name": "Alexander", 255 | // "AgeAtDeath": 32, 256 | // "Battles": [ 257 | // "Battle of Issus", 258 | // "Battle of Gaugamela", 259 | // "Battle of the Hydaspes" 260 | // ] 261 | // } 262 | // ] 263 | } 264 | 265 | func ExampleOptTableX() { 266 | data := []struct{ FirstName, MiddleName, Surname string }{ 267 | {"Marcus", "Tullius", "Cicero"}, 268 | {"Gaius", "Julius", "Caesar"}, 269 | {"Marcus", "Licinius", "Crassus"}, 270 | } 271 | 272 | // Output the names of people in a nicely formatted table 273 | script := `{{tablex . 12 8 0}}` 274 | var b bytes.Buffer 275 | if err := OutputToTemplate(&b, "names", script, data, nil); err != nil { 276 | panic(err) 277 | } 278 | 279 | // Normally you would pass os.Stdout directly into OutputToTemplate. Here 280 | // we're outputting the result of the running the script to a buffer. We need 281 | // to do this so we can remove the whitespace at the end of each line of the 282 | // table. The test fails with the newline present as go tests implementation 283 | // of output: for examples, trims spaces. 284 | 285 | scanner := bufio.NewScanner(&b) 286 | for scanner.Scan() { 287 | fmt.Println(strings.TrimSpace(scanner.Text())) 288 | } 289 | // output: 290 | // FirstName MiddleName Surname 291 | // Marcus Tullius Cicero 292 | // Gaius Julius Caesar 293 | // Marcus Licinius Crassus 294 | } 295 | 296 | func ExampleOptTableXAlt() { 297 | data := []struct { 298 | FirstName string 299 | Mask uint32 300 | }{ 301 | {"Marcus", 255}, 302 | {"Gaius", 10}, 303 | {"Marcus", 6}, 304 | } 305 | 306 | script := `{{tablexalt . 12 8 0}}` 307 | var b bytes.Buffer 308 | if err := OutputToTemplate(&b, "names", script, data, nil); err != nil { 309 | panic(err) 310 | } 311 | 312 | scanner := bufio.NewScanner(&b) 313 | for scanner.Scan() { 314 | fmt.Println(strings.TrimSpace(scanner.Text())) 315 | } 316 | // output: 317 | // FirstName Mask 318 | // "Marcus" 0xff 319 | // "Gaius" 0xa 320 | // "Marcus" 0x6 321 | } 322 | 323 | func ExampleOptHTableX() { 324 | data := []struct{ FirstName, MiddleName, Surname string }{ 325 | {"Marcus", "Tullius", "Cicero"}, 326 | {"Gaius", "Julius", "Caesar"}, 327 | {"Marcus", "Licinius", "Crassus"}, 328 | } 329 | 330 | // Output the names of people in a series of nicely formatted tables 331 | script := `{{htablex . 12 8 0}}` 332 | var b bytes.Buffer 333 | if err := OutputToTemplate(&b, "names", script, data, nil); err != nil { 334 | panic(err) 335 | } 336 | 337 | scanner := bufio.NewScanner(&b) 338 | for scanner.Scan() { 339 | fmt.Println(strings.TrimSpace(scanner.Text())) 340 | } 341 | // output: 342 | // FirstName: Marcus 343 | // MiddleName: Tullius 344 | // Surname: Cicero 345 | // 346 | // FirstName: Gaius 347 | // MiddleName: Julius 348 | // Surname: Caesar 349 | // 350 | // FirstName: Marcus 351 | // MiddleName: Licinius 352 | // Surname: Crassus 353 | } 354 | 355 | func ExampleOptHTableXAlt() { 356 | data := []struct { 357 | FirstName string 358 | Mask uint32 359 | }{ 360 | {"Marcus", 255}, 361 | {"Gaius", 10}, 362 | {"Marcus", 6}, 363 | } 364 | 365 | script := `{{htablexalt . 12 8 0}}` 366 | var b bytes.Buffer 367 | if err := OutputToTemplate(&b, "names", script, data, nil); err != nil { 368 | panic(err) 369 | } 370 | 371 | scanner := bufio.NewScanner(&b) 372 | for scanner.Scan() { 373 | fmt.Println(strings.TrimSpace(scanner.Text())) 374 | } 375 | 376 | // output: 377 | // FirstName: "Marcus" 378 | // Mask: 0xff 379 | // 380 | // FirstName: "Gaius" 381 | // Mask: 0xa 382 | // 383 | // FirstName: "Marcus" 384 | // Mask: 0x6 385 | } 386 | 387 | func ExampleOptCols() { 388 | data := []struct{ FirstName, MiddleName, Surname string }{ 389 | {"Marcus", "Tullius", "Cicero"}, 390 | {"Gaius", "Julius", "Caesar"}, 391 | {"Marcus", "Licinius", "Crassus"}, 392 | } 393 | 394 | // Output the first and last names of people in a nicely formatted table 395 | script := `{{tablex (cols . "FirstName" "Surname") 12 8 0}}` 396 | var b bytes.Buffer 397 | if err := OutputToTemplate(&b, "names", script, data, nil); err != nil { 398 | panic(err) 399 | } 400 | 401 | // Normally you would pass os.Stdout directly into OutputToTemplate. Here 402 | // we're outputting the result of the running the script to a buffer. We need 403 | // to do this so we can remove the whitespace at the end of each line of the 404 | // table. The test fails with the newline present as go tests implementation 405 | // of output: for examples, trims spaces. 406 | 407 | scanner := bufio.NewScanner(&b) 408 | for scanner.Scan() { 409 | fmt.Println(strings.TrimSpace(scanner.Text())) 410 | } 411 | // output: 412 | // FirstName Surname 413 | // Marcus Cicero 414 | // Gaius Caesar 415 | // Marcus Crassus 416 | } 417 | 418 | func ExampleOptSort() { 419 | data := []struct{ FirstName, MiddleName, Surname string }{ 420 | {"Marcus", "Tullius", "Cicero"}, 421 | {"Gaius", "Julius", "Caesar"}, 422 | {"Marcus", "Licinius", "Crassus"}, 423 | } 424 | 425 | // Output the names of people sorted by their Surnames 426 | script := `{{tablex (sort . "Surname") 12 8 0}}` 427 | var b bytes.Buffer 428 | if err := OutputToTemplate(&b, "names", script, data, nil); err != nil { 429 | panic(err) 430 | } 431 | 432 | // Normally you would pass os.Stdout directly into OutputToTemplate. Here 433 | // we're outputting the result of the running the script to a buffer. We need 434 | // to do this so we can remove the whitespace at the end of each line of the 435 | // table. The test fails with the newline present as go tests implementation 436 | // of output: for examples, trims spaces. 437 | 438 | scanner := bufio.NewScanner(&b) 439 | for scanner.Scan() { 440 | fmt.Println(strings.TrimSpace(scanner.Text())) 441 | } 442 | // output: 443 | // FirstName MiddleName Surname 444 | // Gaius Julius Caesar 445 | // Marcus Tullius Cicero 446 | // Marcus Licinius Crassus 447 | } 448 | 449 | func ExampleOptRows() { 450 | data := []struct{ FirstName, MiddleName, Surname string }{ 451 | {"Marcus", "Tullius", "Cicero"}, 452 | {"Gaius", "Julius", "Caesar"}, 453 | {"Marcus", "Licinius", "Crassus"}, 454 | } 455 | 456 | // Print the surname of the first and third people in the database 457 | script := `{{range (rows . 0 2)}}{{println .Surname}}{{end}}` 458 | if err := OutputToTemplate(os.Stdout, "names", script, data, nil); err != nil { 459 | panic(err) 460 | } 461 | // output: 462 | // Cicero 463 | // Crassus 464 | } 465 | 466 | func ExampleOptHead() { 467 | data := []struct{ FirstName, MiddleName, Surname string }{ 468 | {"Marcus", "Tullius", "Cicero"}, 469 | {"Gaius", "Julius", "Caesar"}, 470 | {"Marcus", "Licinius", "Crassus"}, 471 | } 472 | 473 | // Print the surname of the first person in the database 474 | script := `{{range (head .)}}{{println .Surname}}{{end}}` 475 | if err := OutputToTemplate(os.Stdout, "names", script, data, nil); err != nil { 476 | panic(err) 477 | } 478 | // output: 479 | // Cicero 480 | } 481 | 482 | func ExampleOptTail() { 483 | data := []struct{ FirstName, MiddleName, Surname string }{ 484 | {"Marcus", "Tullius", "Cicero"}, 485 | {"Gaius", "Julius", "Caesar"}, 486 | {"Marcus", "Licinius", "Crassus"}, 487 | } 488 | 489 | // Print the surname of the first person in the database 490 | script := `{{range (tail .)}}{{println .Surname}}{{end}}` 491 | if err := OutputToTemplate(os.Stdout, "names", script, data, nil); err != nil { 492 | panic(err) 493 | } 494 | // output: 495 | // Crassus 496 | } 497 | 498 | func ExampleOptDescribe() { 499 | data := []struct{ FirstName, MiddleName, Surname string }{} 500 | 501 | // Describe the type of data 502 | script := `{{describe .}}` 503 | if err := OutputToTemplate(os.Stdout, "names", script, data, nil); err != nil { 504 | panic(err) 505 | } 506 | // output: 507 | // []struct { 508 | // FirstName string 509 | // MiddleName string 510 | // Surname string 511 | // } 512 | } 513 | 514 | func ExampleOptPromote() { 515 | type cred struct { 516 | Name string 517 | Password string 518 | } 519 | 520 | type u struct { 521 | Credentials cred 522 | } 523 | 524 | data := []struct { 525 | Uninteresting int 526 | User u 527 | }{ 528 | {0, u{cred{"Marcus", "1234"}}}, 529 | {0, u{cred{"Gaius", "0000"}}}, 530 | } 531 | 532 | // Create a new []cred containing the credentials embedded within data, 533 | // iterate through this new slice printing out the names and passwords. 534 | // The cred instances rooted at "User.Credentials" in the data object 535 | // are promoted to the top level in the new slice. 536 | script := `{{range (promote . "User.Credentials")}}{{printf "%s %s\n" .Name .Password}}{{end}}` 537 | if err := OutputToTemplate(os.Stdout, "names", script, data, nil); err != nil { 538 | panic(err) 539 | } 540 | // output: 541 | // Marcus 1234 542 | // Gaius 0000 543 | } 544 | 545 | func ExampleOptSliceof() { 546 | script := `{{index (sliceof .) 0}}` 547 | if err := OutputToTemplate(os.Stdout, "names", script, 1, nil); err != nil { 548 | panic(err) 549 | } 550 | // output: 551 | // 1 552 | } 553 | 554 | func ExampleOptToTable() { 555 | data := [][]string{ 556 | {"Message", "Code", "Occurrence"}, 557 | {"Too many GOSUBs", "37", "0.1"}, 558 | {"Too many REPEATs", "44", "0.15"}, 559 | } 560 | script := `{{with (totable .)}}{{select . "Message"}}{{select . "Code"}}{{select . "Occurrence"}}{{end}}` 561 | if err := OutputToTemplate(os.Stdout, "errors", script, data, nil); err != nil { 562 | panic(err) 563 | } 564 | // output: 565 | // Too many GOSUBs 566 | // Too many REPEATs 567 | // 37 568 | // 44 569 | // 0.1 570 | // 0.15 571 | } 572 | 573 | func ExampleOptSelectAlt() { 574 | data := []struct{ Integer uint32 }{{255}} 575 | script := `{{selectalt . "Integer"}}` 576 | if err := OutputToTemplate(os.Stdout, "names", script, data, nil); err != nil { 577 | panic(err) 578 | } 579 | // output: 580 | // 0xff 581 | } 582 | 583 | func ExampleConfig_AddCustomFn() { 584 | nums := []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10} 585 | cfg := NewConfig(OptAllFns) 586 | err := cfg.AddCustomFn(func(n []int) int { 587 | sum := 0 588 | for _, num := range n { 589 | sum += num 590 | } 591 | return sum 592 | }, "sum", "- sum \"Returns\" the sum of a slice of integers") 593 | if err != nil { 594 | panic(err) 595 | } 596 | 597 | // Print the sum of a slice of numbers 598 | script := `{{println (sum .)}}` 599 | if err = OutputToTemplate(os.Stdout, "sums", script, nums, cfg); err != nil { 600 | panic(err) 601 | } 602 | // output: 603 | // 55 604 | } 605 | -------------------------------------------------------------------------------- /examples/csv/csv.go: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) 2017 Intel Corporation 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // 16 | 17 | package main 18 | 19 | import ( 20 | "encoding/csv" 21 | "flag" 22 | "fmt" 23 | "os" 24 | 25 | "github.com/intel/tfortools" 26 | ) 27 | 28 | var code string 29 | 30 | func init() { 31 | flag.Usage = func() { 32 | fmt.Fprintf(os.Stderr, "Usage: %s [-f template] file\n", os.Args[0]) 33 | flag.PrintDefaults() 34 | fmt.Fprintln(os.Stderr) 35 | fmt.Fprintln(os.Stderr, tfortools.GenerateUsageUndecorated([][]string{})) 36 | } 37 | flag.StringVar(&code, "f", "{{table (totable .)}}", "string containing the template code to execute") 38 | } 39 | 40 | func applyTemplate(path string) error { 41 | f, err := os.Open(path) 42 | if err != nil { 43 | return fmt.Errorf("Unable to open %s : %v", path, err) 44 | } 45 | defer func() { 46 | _ = f.Close() 47 | }() 48 | data, err := csv.NewReader(f).ReadAll() 49 | if err != nil { 50 | return fmt.Errorf("Unable to read %s : %v", path, err) 51 | } 52 | return tfortools.OutputToTemplate(os.Stdout, "csv", code, data, nil) 53 | } 54 | 55 | func main() { 56 | flag.Parse() 57 | 58 | if len(flag.Args()) != 1 { 59 | flag.Usage() 60 | os.Exit(1) 61 | } 62 | 63 | if err := applyTemplate(flag.Args()[0]); err != nil { 64 | fmt.Fprintln(os.Stderr, err.Error()) 65 | os.Exit(1) 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /examples/elf_dump/README.md: -------------------------------------------------------------------------------- 1 | # ELF Parsing leveraging templates 2 | 3 | By default 4 | 5 | elf_dump just dumps the Program Headers and the Section Headers as well the symbol table 6 | 7 | However what makes this interesting the ability to use templates to do interesting stuff 8 | 9 | An few examples 10 | 11 | You can filter the symbol table to extract information in different ways 12 | 13 | ``` 14 | elf_dump -f '{{tablealt (head (promote .Sections "SectionHeader") 3)}}' curl 15 | ``` 16 | 17 | ``` 18 | elf_dump -f '{{range (head .ImportedSymbols 3)}}{{println .}}{{end}}' curl 19 | ``` 20 | 21 | ``` 22 | elf_dump -f '{{range .DynamicSymbols}}{{println .}}{{end}}' curl 23 | ``` 24 | -------------------------------------------------------------------------------- /examples/elf_dump/elf_dump.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "debug/elf" 5 | "flag" 6 | "fmt" 7 | "os" 8 | 9 | "github.com/intel/tfortools" 10 | ) 11 | 12 | var code string //The format string 13 | 14 | func init() { 15 | 16 | flag.Usage = func() { 17 | fmt.Fprintf(os.Stderr, "Usage: %s [-f