doc/tutorial/basics: order files

Change-Id: I1d681ba69e37324be0e58b138784c61372c41c8c
Reviewed-on: https://cue-review.googlesource.com/c/cue/+/3541
Reviewed-by: Marcel van Lohuizen <mpvl@golang.org>
diff --git a/doc/tutorial/basics/operators.txt b/doc/tutorial/basics/expressions/10_operators.txt
similarity index 100%
rename from doc/tutorial/basics/operators.txt
rename to doc/tutorial/basics/expressions/10_operators.txt
diff --git a/doc/tutorial/basics/interpolation.txt b/doc/tutorial/basics/expressions/20_interpolation.txt
similarity index 100%
rename from doc/tutorial/basics/interpolation.txt
rename to doc/tutorial/basics/expressions/20_interpolation.txt
diff --git a/doc/tutorial/basics/interpolfield.txt b/doc/tutorial/basics/expressions/25_interpolfield.txt
similarity index 100%
rename from doc/tutorial/basics/interpolfield.txt
rename to doc/tutorial/basics/expressions/25_interpolfield.txt
diff --git a/doc/tutorial/basics/listcomp.txt b/doc/tutorial/basics/expressions/40_listcomp.txt
similarity index 100%
rename from doc/tutorial/basics/listcomp.txt
rename to doc/tutorial/basics/expressions/40_listcomp.txt
diff --git a/doc/tutorial/basics/fieldcomp.txt b/doc/tutorial/basics/expressions/50_fieldcomp.txt
similarity index 100%
rename from doc/tutorial/basics/fieldcomp.txt
rename to doc/tutorial/basics/expressions/50_fieldcomp.txt
diff --git a/doc/tutorial/basics/conditional.txt b/doc/tutorial/basics/expressions/55_conditional.txt
similarity index 100%
rename from doc/tutorial/basics/conditional.txt
rename to doc/tutorial/basics/expressions/55_conditional.txt
diff --git a/doc/tutorial/basics/regexp.txt b/doc/tutorial/basics/expressions/70_regexp.txt
similarity index 100%
rename from doc/tutorial/basics/regexp.txt
rename to doc/tutorial/basics/expressions/70_regexp.txt
diff --git a/doc/tutorial/basics/coalesce.txt b/doc/tutorial/basics/expressions/80_coalesce.txt
similarity index 100%
rename from doc/tutorial/basics/coalesce.txt
rename to doc/tutorial/basics/expressions/80_coalesce.txt
diff --git a/doc/tutorial/basics/expressions/_index.md b/doc/tutorial/basics/expressions/_index.md
new file mode 100644
index 0000000..11e3143
--- /dev/null
+++ b/doc/tutorial/basics/expressions/_index.md
@@ -0,0 +1,5 @@
++++
+title = "Expressions"
+weight = 2600
+description = ""
++++
\ No newline at end of file
diff --git a/doc/tutorial/basics/gen.go b/doc/tutorial/basics/gen.go
new file mode 100644
index 0000000..8f3666e
--- /dev/null
+++ b/doc/tutorial/basics/gen.go
@@ -0,0 +1,181 @@
+// Copyright 2019 CUE Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// +build ignore
+
+// gen generates Hugo files from the given current script files.
+package main
+
+import (
+	"fmt"
+	"log"
+	"os"
+	"path/filepath"
+	"regexp"
+	"strconv"
+	"strings"
+	"text/template"
+
+	"github.com/rogpeppe/testscript/txtar"
+)
+
+func main() {
+	log.SetFlags(log.Lshortfile)
+	index := ""
+	filepath.Walk(".", func(path string, info os.FileInfo, err error) error {
+		if x, ok := chapter[path]; ok {
+			index = x
+		}
+		if !strings.HasSuffix(path, ".txt") ||
+			filepath.Base(path) == "out.txt" {
+			return nil
+		}
+		generate(path, index)
+		return nil
+	})
+}
+
+var chapter = map[string]string{
+	"intro":       "0",
+	"types":       "2",
+	"references":  "4",
+	"expressions": "6",
+	"packages":    "8",
+}
+
+type Page struct {
+	FrontMatter string
+	Weight      int
+	Body        string
+	Command     string
+	Inputs      []File
+	Out         File
+}
+
+type File struct {
+	Name string
+	Data string
+	Type string
+}
+
+var hugoPage = template.Must(template.New("page").Delims("[[", "]]").Parse(`+++
+[[ .FrontMatter ]]
+weight = [[ .Weight ]]
+layout = "tutorial"
++++
+[[.Body -]]
+[[- if .Inputs ]]
+<a id="td-block-padding" class="td-offset-anchor"></a>
+<section class="row td-box td-box--white td-box--gradient td-box--height-auto">
+<div class="col-lg-6 mr-0">
+[[ range .Inputs -]]
+<i>[[ .Name ]]</i>
+<p>
+{{< highlight go >}}
+[[ .Data -]]
+{{< /highlight >}}
+<br>
+[[end -]]
+</div>
+
+<div class="col-lg-6 ml-0">
+[[- if .Out.Data -]]
+<i>$ [[ .Command ]]</i>
+<p>
+{{< highlight go >}}
+[[ .Out.Data -]]
+{{< /highlight >}}
+[[end -]]
+</div>
+</section>
+[[- end -]]
+`))
+
+func generate(filename, index string) {
+	a, err := txtar.ParseFile(filename)
+	if err != nil {
+		log.Fatal(err)
+	}
+
+	re := regexp.MustCompile(`(\d+)_`)
+	for _, m := range re.FindAllStringSubmatch(filename, 2) {
+		index += m[1]
+	}
+	weight, err := strconv.Atoi(index)
+	if err != nil {
+		log.Fatal(err)
+	}
+	filename = re.ReplaceAllLiteralString(filename, "")
+	filename = filename[:len(filename)-len(".txt")] + ".md"
+	filename = filepath.Join("tour", filename)
+	fmt.Println(index, filename)
+
+	comments := strings.Split(string(a.Comment), "\n")[0]
+	comments = strings.TrimLeft(comments, "! ")
+	page := &Page{
+		Command: comments,
+		Weight:  2000 + weight,
+	}
+
+	for _, f := range a.Files {
+		data := string(f.Data)
+		file := File{Name: f.Name, Data: data}
+
+		switch s := f.Name; {
+		case s == "frontmatter.toml":
+			page.FrontMatter = strings.TrimSpace(data)
+
+		case strings.HasSuffix(s, ".md"):
+			page.Body = data
+
+		case strings.HasSuffix(s, ".cue"):
+			file.Type = "cue"
+			page.Inputs = append(page.Inputs, file)
+
+		case strings.HasSuffix(s, ".json"):
+			file.Type = "json"
+			page.Inputs = append(page.Inputs, file)
+
+		case strings.HasSuffix(s, ".yaml"):
+			file.Type = "yaml"
+			page.Inputs = append(page.Inputs, file)
+
+		case strings.HasSuffix(s, "stdout-cue"):
+			file.Type = "cue"
+			page.Out = file
+
+		case strings.HasSuffix(s, "stdout-json"):
+			file.Type = "json"
+			page.Out = file
+
+		case strings.HasSuffix(s, "stderr"):
+			page.Out = file
+
+		default:
+			log.Fatalf("unknown file type %q", s)
+		}
+	}
+
+	_ = os.MkdirAll(filepath.Dir(filename), 0755)
+
+	w, err := os.Create(filename)
+	if err != nil {
+		log.Fatal(err)
+	}
+	defer w.Close()
+
+	if err = hugoPage.Execute(w, page); err != nil {
+		log.Fatal(err)
+	}
+}
diff --git a/doc/tutorial/basics/instances.txt b/doc/tutorial/basics/instances.txt
deleted file mode 100644
index 2fe7df2..0000000
--- a/doc/tutorial/basics/instances.txt
+++ /dev/null
@@ -1,4 +0,0 @@
--- frontmatter.toml --
-title = "Modules"
-description = ""
-
diff --git a/doc/tutorial/basics/fieldname.txt b/doc/tutorial/basics/intro/10_fieldname.txt
similarity index 100%
rename from doc/tutorial/basics/fieldname.txt
rename to doc/tutorial/basics/intro/10_fieldname.txt
diff --git a/doc/tutorial/basics/commas.txt b/doc/tutorial/basics/intro/20_commas.txt
similarity index 100%
rename from doc/tutorial/basics/commas.txt
rename to doc/tutorial/basics/intro/20_commas.txt
diff --git a/doc/tutorial/basics/commaslists.txt b/doc/tutorial/basics/intro/25_commaslists.txt
similarity index 100%
rename from doc/tutorial/basics/commaslists.txt
rename to doc/tutorial/basics/intro/25_commaslists.txt
diff --git a/doc/tutorial/basics/curly.txt b/doc/tutorial/basics/intro/30_curly.txt
similarity index 100%
rename from doc/tutorial/basics/curly.txt
rename to doc/tutorial/basics/intro/30_curly.txt
diff --git a/doc/tutorial/basics/fold.txt b/doc/tutorial/basics/intro/40_fold.txt
similarity index 100%
rename from doc/tutorial/basics/fold.txt
rename to doc/tutorial/basics/intro/40_fold.txt
diff --git a/doc/tutorial/basics/foldany.txt b/doc/tutorial/basics/intro/45_foldany.txt
similarity index 100%
rename from doc/tutorial/basics/foldany.txt
rename to doc/tutorial/basics/intro/45_foldany.txt
diff --git a/doc/tutorial/basics/comments.txt b/doc/tutorial/basics/intro/50_comments.txt
similarity index 100%
rename from doc/tutorial/basics/comments.txt
rename to doc/tutorial/basics/intro/50_comments.txt
diff --git a/doc/tutorial/basics/numberlit.txt b/doc/tutorial/basics/intro/60_numberlit.txt
similarity index 100%
rename from doc/tutorial/basics/numberlit.txt
rename to doc/tutorial/basics/intro/60_numberlit.txt
diff --git a/doc/tutorial/basics/stringlit.txt b/doc/tutorial/basics/intro/70_stringlit.txt
similarity index 100%
rename from doc/tutorial/basics/stringlit.txt
rename to doc/tutorial/basics/intro/70_stringlit.txt
diff --git a/doc/tutorial/basics/stringraw.txt b/doc/tutorial/basics/intro/75_stringraw.txt
similarity index 100%
rename from doc/tutorial/basics/stringraw.txt
rename to doc/tutorial/basics/intro/75_stringraw.txt
diff --git a/doc/tutorial/basics/bytes.txt b/doc/tutorial/basics/intro/80_bytes.txt
similarity index 100%
rename from doc/tutorial/basics/bytes.txt
rename to doc/tutorial/basics/intro/80_bytes.txt
diff --git a/doc/tutorial/basics/intro/_index.md b/doc/tutorial/basics/intro/_index.md
new file mode 100644
index 0000000..3edfac3
--- /dev/null
+++ b/doc/tutorial/basics/intro/_index.md
@@ -0,0 +1,5 @@
++++
+title = "Introduction"
+weight = 2000
+description = ""
++++
\ No newline at end of file
diff --git a/doc/tutorial/basics/json.txt b/doc/tutorial/basics/json.txt
deleted file mode 100644
index ba5d6df..0000000
--- a/doc/tutorial/basics/json.txt
+++ /dev/null
@@ -1,4 +0,0 @@
--- frontmatter.toml --
-title = "JSON sugar and other Goodness"
-description = ""
-
diff --git a/doc/tutorial/basics/packages.txt b/doc/tutorial/basics/packages/10_packages.txt
similarity index 100%
rename from doc/tutorial/basics/packages.txt
rename to doc/tutorial/basics/packages/10_packages.txt
diff --git a/doc/tutorial/basics/imports.txt b/doc/tutorial/basics/packages/30_imports.txt
similarity index 100%
rename from doc/tutorial/basics/imports.txt
rename to doc/tutorial/basics/packages/30_imports.txt
diff --git a/doc/tutorial/basics/packages/_index.md b/doc/tutorial/basics/packages/_index.md
new file mode 100644
index 0000000..879be44
--- /dev/null
+++ b/doc/tutorial/basics/packages/_index.md
@@ -0,0 +1,5 @@
++++
+title = "Modules, Packages, and Instances"
+weight = 2800
+description = ""
++++
\ No newline at end of file
diff --git a/doc/tutorial/basics/scopes.txt b/doc/tutorial/basics/references/10_scopes.txt
similarity index 100%
rename from doc/tutorial/basics/scopes.txt
rename to doc/tutorial/basics/references/10_scopes.txt
diff --git a/doc/tutorial/basics/aliases.txt b/doc/tutorial/basics/references/30_aliases.txt
similarity index 100%
rename from doc/tutorial/basics/aliases.txt
rename to doc/tutorial/basics/references/30_aliases.txt
diff --git a/doc/tutorial/basics/emit.txt b/doc/tutorial/basics/references/50_emit.txt
similarity index 100%
rename from doc/tutorial/basics/emit.txt
rename to doc/tutorial/basics/references/50_emit.txt
diff --git a/doc/tutorial/basics/cycle.txt b/doc/tutorial/basics/references/80_cycle.txt
similarity index 100%
rename from doc/tutorial/basics/cycle.txt
rename to doc/tutorial/basics/references/80_cycle.txt
diff --git a/doc/tutorial/basics/cycleref.txt b/doc/tutorial/basics/references/85_cycleref.txt
similarity index 100%
rename from doc/tutorial/basics/cycleref.txt
rename to doc/tutorial/basics/references/85_cycleref.txt
diff --git a/doc/tutorial/basics/hidden.txt b/doc/tutorial/basics/references/99_hidden.txt
similarity index 97%
rename from doc/tutorial/basics/hidden.txt
rename to doc/tutorial/basics/references/99_hidden.txt
index 520cf97..aabdc29 100644
--- a/doc/tutorial/basics/hidden.txt
+++ b/doc/tutorial/basics/references/99_hidden.txt
@@ -4,6 +4,7 @@
 -- frontmatter.toml --
 title = "Hidden Fields"
 description = ""
+draft = true
 
 -- text.md --
 A non-quoted field name that starts with an underscore (`_`) is not
diff --git a/doc/tutorial/basics/references/_index.md b/doc/tutorial/basics/references/_index.md
new file mode 100644
index 0000000..7a3bdd6
--- /dev/null
+++ b/doc/tutorial/basics/references/_index.md
@@ -0,0 +1,5 @@
++++
+title = "References and Visibility"
+weight = 2400
+description = ""
++++
\ No newline at end of file
diff --git a/doc/tutorial/basics/script_test.go b/doc/tutorial/basics/script_test.go
index 4523fb1..92e2179 100644
--- a/doc/tutorial/basics/script_test.go
+++ b/doc/tutorial/basics/script_test.go
@@ -3,6 +3,7 @@
 import (
 	"flag"
 	"os"
+	"path/filepath"
 	"testing"
 
 	"cuelang.org/go/cmd/cue/cmd"
@@ -12,9 +13,15 @@
 var update = flag.Bool("update", false, "update the test files")
 
 func TestScript(t *testing.T) {
-	testscript.Run(t, testscript.Params{
-		Dir:           "",
-		UpdateScripts: *update,
+	filepath.Walk(".", func(path string, info os.FileInfo, err error) error {
+		if !info.IsDir() {
+			return nil
+		}
+		testscript.Run(t, testscript.Params{
+			Dir:           path,
+			UpdateScripts: *update,
+		})
+		return nil
 	})
 }
 
diff --git a/doc/tutorial/basics/tut_test.go b/doc/tutorial/basics/tut_test.go
deleted file mode 100644
index c69326d..0000000
--- a/doc/tutorial/basics/tut_test.go
+++ /dev/null
@@ -1,123 +0,0 @@
-// Copyright 2019 CUE Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package basics
-
-import (
-	"fmt"
-	"io/ioutil"
-	"os"
-	"path/filepath"
-	"strings"
-	"testing"
-
-	"cuelang.org/go/internal/cuetest"
-	"github.com/rogpeppe/testscript/txtar"
-)
-
-func TestTutorial(t *testing.T) {
-	t.Skip()
-
-	err := filepath.Walk(".", func(path string, f os.FileInfo, err error) error {
-		if strings.HasSuffix(path, ".md") && !strings.Contains(path, "/") {
-			t.Run(path, func(t *testing.T) { simulateFile(t, path) })
-		}
-		return nil
-	})
-	if err != nil {
-		t.Fatal(err)
-	}
-}
-
-func simulateFile(t *testing.T, path string) {
-	b, err := ioutil.ReadFile(path)
-	if err != nil {
-		t.Fatalf("failed to open file %q: %v", path, err)
-	}
-
-	if path == "Readme.md" {
-		return
-	}
-
-	archive := &txtar.Archive{}
-
-	addFile := func(filename string, body string) {
-		archive.Files = append(archive.Files, txtar.File{
-			Name: filename,
-			Data: []byte(strings.TrimSpace(body) + "\n\n"),
-		})
-	}
-
-	var (
-		baseName = path[:len(path)-len(".md")]
-		txtFile  = baseName + ".txt"
-	)
-
-	defer func() {
-		err = ioutil.WriteFile(txtFile, txtar.Format(archive), 0644)
-	}()
-
-	c := cuetest.NewChunker(t, b)
-
-	c.Find("\n")
-	c.Next("_", "_")
-	section := c.Text()
-	sub := strings.ToLower(strings.Fields(section)[0])
-	sub = strings.TrimRight(sub, ",")
-
-	c.Next("# ", "\n")
-	addFile("frontmatter.toml", fmt.Sprintf(`title = %q
-description = ""
-`, c.Text()))
-
-	for i := 0; c.Find("<!-- CUE editor -->"); i++ {
-		if i == 0 {
-			addFile("text.md", c.Text())
-		}
-		if !c.Next("_", "_") {
-			continue
-		}
-		filename := strings.TrimRight(c.Text(), ":")
-
-		if !c.Next("```", "```") {
-			t.Fatalf("No body for filename %q in file %q", filename, path)
-		}
-		addFile(filename, c.Text())
-	}
-
-	if !c.Find("<!-- result -->") {
-		return
-	}
-
-	if !c.Next("`$ ", "`") {
-		t.Fatalf("No command for result section in file %q", path)
-	}
-	archive.Comment = []byte(c.Text())
-	archive.Comment = append(archive.Comment, `
-cmp stdout expect-stdout-cue
-
-`...)
-
-	if !c.Next("```", "```") {
-		return
-	}
-	gold := c.Text()
-	if p := strings.Index(gold, "\n"); p > 0 {
-		gold = gold[p+1:]
-	}
-
-	gold = strings.TrimSpace(gold) + "\n"
-	// TODO: manually adjust file type and stderr.
-	addFile("expect-stdout-cue", gold)
-}
diff --git a/doc/tutorial/basics/bottom.txt b/doc/tutorial/basics/types/20_bottom.txt
similarity index 100%
rename from doc/tutorial/basics/bottom.txt
rename to doc/tutorial/basics/types/20_bottom.txt
diff --git a/doc/tutorial/basics/duplicates.txt b/doc/tutorial/basics/types/20_duplicates.txt
similarity index 100%
rename from doc/tutorial/basics/duplicates.txt
rename to doc/tutorial/basics/types/20_duplicates.txt
diff --git a/doc/tutorial/basics/selectors.txt b/doc/tutorial/basics/types/20_selectors.txt
similarity index 100%
rename from doc/tutorial/basics/selectors.txt
rename to doc/tutorial/basics/types/20_selectors.txt
diff --git a/doc/tutorial/basics/types.txt b/doc/tutorial/basics/types/30_types.txt
similarity index 100%
rename from doc/tutorial/basics/types.txt
rename to doc/tutorial/basics/types/30_types.txt
diff --git a/doc/tutorial/basics/numbers.txt b/doc/tutorial/basics/types/40_numbers.txt
similarity index 100%
rename from doc/tutorial/basics/numbers.txt
rename to doc/tutorial/basics/types/40_numbers.txt
diff --git a/doc/tutorial/basics/unification.txt b/doc/tutorial/basics/types/40_unification.txt
similarity index 100%
rename from doc/tutorial/basics/unification.txt
rename to doc/tutorial/basics/types/40_unification.txt
diff --git a/doc/tutorial/basics/disjunctions.txt b/doc/tutorial/basics/types/50_disjunctions.txt
similarity index 69%
rename from doc/tutorial/basics/disjunctions.txt
rename to doc/tutorial/basics/types/50_disjunctions.txt
index b6b85c6..81a7eda 100644
--- a/doc/tutorial/basics/disjunctions.txt
+++ b/doc/tutorial/basics/types/50_disjunctions.txt
@@ -1,3 +1,6 @@
+cue eval disjunctions.cue
+cmp stdout expect-stdout-cue
+
 -- frontmatter.toml --
 title = "Disjunctions"
 description = ""
@@ -23,3 +26,14 @@
     protocol: "udp"
 }
 
+-- expect-stdout-cue --
+conn: {
+    address:  string
+    port:     int
+    protocol: "tcp" | "udp"
+}
+lossy: {
+    address:  "1.2.3.4"
+    port:     8888
+    protocol: "udp"
+}
diff --git a/doc/tutorial/basics/defaults.txt b/doc/tutorial/basics/types/55_defaults.txt
similarity index 100%
rename from doc/tutorial/basics/defaults.txt
rename to doc/tutorial/basics/types/55_defaults.txt
diff --git a/doc/tutorial/basics/sumstruct.txt b/doc/tutorial/basics/types/55_sumstruct.txt
similarity index 99%
rename from doc/tutorial/basics/sumstruct.txt
rename to doc/tutorial/basics/types/55_sumstruct.txt
index 5ec64e6..29f8a9a 100644
--- a/doc/tutorial/basics/sumstruct.txt
+++ b/doc/tutorial/basics/types/55_sumstruct.txt
@@ -23,4 +23,3 @@
     level: -1 | 2 | 3
     hasExit: false
 }
-
diff --git a/doc/tutorial/basics/ranges.txt b/doc/tutorial/basics/types/70_bounds.txt
similarity index 100%
rename from doc/tutorial/basics/ranges.txt
rename to doc/tutorial/basics/types/70_bounds.txt
diff --git a/doc/tutorial/basics/rangedef.txt b/doc/tutorial/basics/types/75_rangedef.txt
similarity index 100%
rename from doc/tutorial/basics/rangedef.txt
rename to doc/tutorial/basics/types/75_rangedef.txt
diff --git a/doc/tutorial/basics/lists.txt b/doc/tutorial/basics/types/80_lists.txt
similarity index 100%
rename from doc/tutorial/basics/lists.txt
rename to doc/tutorial/basics/types/80_lists.txt
diff --git a/doc/tutorial/basics/templates.txt b/doc/tutorial/basics/types/90_templates.txt
similarity index 100%
rename from doc/tutorial/basics/templates.txt
rename to doc/tutorial/basics/types/90_templates.txt
diff --git a/doc/tutorial/basics/types/_index.md b/doc/tutorial/basics/types/_index.md
new file mode 100644
index 0000000..7e813fc
--- /dev/null
+++ b/doc/tutorial/basics/types/_index.md
@@ -0,0 +1,5 @@
++++
+title = "Types ~~and~~ are Values"
+weight = 2200
+description = ""
++++
\ No newline at end of file