Skip to content

Commit

Permalink
🧪 labsite: Add Next Button to Labs (#424)
Browse files Browse the repository at this point in the history
Update `.htmlf` generation from `.md` in `build-tools/labsite-gen/main.go`:

Generate `<button class="next-btn">Next</button>` from markdown paragraphs
only containing marker `[Next]`. Use the next button as additional
`<deatils>....</details>` end marker in Markdown, in addition to
Heading and ThematicBreak.

Add JS and CSS to align with design.

Rework contents to better flow and fit with Next button concept.

Remove Bouncing Ball example from `if` lab listing (too much).

This merges the following commits:
* labsite: Remove bounce sample from lab listing
* labsite: Add tooling for Next button
* labsite: Update JS and CSS for Next button
* labsite: Update contents to align with Next button (1/2)
* labsite: Update contents to align with Next button (2/2)

     build-tools/labsite-gen/main.go               |  49 +++++++-
     build-tools/labsite-gen/main_test.go          |  78 +++++++++++++
     frontend/lab/css/overrides.css                |  64 +++++++----
     frontend/lab/samples/ifs/alpha.htmlf          |  17 ++-
     frontend/lab/samples/ifs/alpha.md             |  22 +++-
     frontend/lab/samples/ifs/bounce.htmlf         |   3 +-
     frontend/lab/samples/ifs/bounce.md            |   4 +-
     frontend/lab/samples/ifs/chat.evy             |   3 +-
     frontend/lab/samples/ifs/chat.htmlf           |  68 ++++++------
     frontend/lab/samples/ifs/chat.md              |  47 +++++---
     frontend/lab/samples/ifs/pi.htmlf             |  99 ++++++++---------
     frontend/lab/samples/ifs/pi.md                |  64 +++++------
     frontend/lab/samples/ifs/pulse.htmlf          |  82 ++++++++------
     frontend/lab/samples/ifs/pulse.md             |  85 ++++++++------
     frontend/lab/samples/ifs/stars.htmlf          |  42 ++++---
     frontend/lab/samples/ifs/stars.md             |  50 ++++++---
     frontend/lab/samples/ifs/welcome-ifs.htmlf    |   2 +-
     frontend/lab/samples/ifs/welcome-ifs.md       |   2 +-
     frontend/lab/samples/intro/circles.htmlf      |  21 +++-
     frontend/lab/samples/intro/circles.md         |  27 +++--
     frontend/lab/samples/intro/coords.htmlf       |   4 +-
     frontend/lab/samples/intro/coords.md          |   4 +-
     .../lab/samples/intro/img/1-jumpy-circle.gif  | Bin 0 -> 25386 bytes
     frontend/lab/samples/intro/loop.htmlf         |  20 ++--
     frontend/lab/samples/intro/loop.md            |  23 ++--
     frontend/lab/samples/intro/move.htmlf         | 105 ++++++++++++------
     frontend/lab/samples/intro/move.md            |  94 +++++++++++-----
     frontend/lab/samples/intro/var.htmlf          |  15 ++-
     frontend/lab/samples/intro/var.md             |  20 +++-
     .../lab/samples/loops/gradient-show.htmlf     |   4 +-
     frontend/lab/samples/loops/gradient-show.md   |   4 +-
     frontend/lab/samples/loops/gradient.htmlf     |  29 +++--
     frontend/lab/samples/loops/gradient.md        |  39 +++++--
     frontend/lab/samples/loops/hsl.htmlf          |   4 +-
     frontend/lab/samples/loops/hsl.md             |   4 +-
     frontend/lab/samples/loops/lines.htmlf        |   4 +-
     frontend/lab/samples/loops/lines.md           |   4 +-
     frontend/lab/samples/loops/sequence.htmlf     |  80 ++++++-------
     frontend/lab/samples/loops/sequence.md        |  37 +++---
     frontend/lab/samples/loops/target-show.htmlf  |   2 +-
     frontend/lab/samples/loops/target-show.md     |   2 +-
     frontend/lab/samples/loops/target.htmlf       |  15 ++-
     frontend/lab/samples/loops/target.md          |  20 +++-
     frontend/lab/samples/samples.json             |   2 +-
     frontend/play/index.js                        |  61 +++++++---
     45 files changed, 940 insertions(+), 485 deletions(-)

Pull-request: #424
  • Loading branch information
juliaogris committed Aug 26, 2024
2 parents 204e259 + 767af33 commit 16f9213
Show file tree
Hide file tree
Showing 45 changed files with 940 additions and 485 deletions.
49 changes: 44 additions & 5 deletions build-tools/labsite-gen/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,12 @@ import (
"rsc.io/markdown"
)

const marker = "[>]"
const (
detailsMarker = "[>]"
nextButtonMarker = "[Next]"
)

var nextButton = newNextButton()

func main() {
if len(os.Args) != 3 {
Expand All @@ -34,6 +39,7 @@ func run(mdFile, htmlfFile string) error {
return err
}
doc := parse(string(md))
replaceNextButton(doc)
doc.Blocks = collapse(doc.Blocks)
html := markdown.ToHTML(doc)

Expand All @@ -45,6 +51,29 @@ func parse(md string) *markdown.Document {
return p.Parse(md)
}

func replaceNextButton(doc *markdown.Document) {
for i, block := range doc.Blocks {
if isNextButton(block) {
doc.Blocks[i] = nextButton
}
}
}

func isNextButton(block markdown.Block) bool {
paragraph, ok := block.(*markdown.Paragraph)
if !ok {
return false
}
if len(paragraph.Text.Inline) != 1 {
return false
}
plain, ok := paragraph.Text.Inline[0].(*markdown.Plain)
if !ok {
return false
}
return plain.Text == nextButtonMarker
}

func collapse(blocks []markdown.Block) []markdown.Block {
var result []markdown.Block
for idx := 0; idx < len(blocks); {
Expand Down Expand Up @@ -75,19 +104,22 @@ func isCollapsible(block markdown.Block) bool {
return false
}
plain, ok := heading.Text.Inline[0].(*markdown.Plain)
return ok && strings.HasPrefix(plain.Text, marker)
return ok && strings.HasPrefix(plain.Text, detailsMarker)
}

func deleteCollapseMarker(heading *markdown.Heading) {
// assumes isCollapsible returned true
plain := heading.Text.Inline[0].(*markdown.Plain)
s := strings.TrimPrefix(plain.Text, marker)
s := strings.TrimPrefix(plain.Text, detailsMarker)
s = strings.TrimLeftFunc(s, unicode.IsSpace)
plain.Text = s
}

func findEndIdx(level, start int, blocks []markdown.Block) int {
for i := start; i < len(blocks); i++ {
if blocks[i] == nextButton {
return i
}
if _, ok := blocks[i].(*markdown.ThematicBreak); ok {
return i
}
Expand All @@ -110,8 +142,15 @@ func toDetailsHTML(heading *markdown.Heading, blocks []markdown.Block) *markdown
buf.WriteString(markdown.ToHTML(block))
}
buf.WriteString("</details>")
doc := parse(buf.String())
return doc.Blocks[0].(*markdown.HTMLBlock)
htmlBlock := &markdown.HTMLBlock{
Text: strings.Split(buf.String(), "\n"),
}
return htmlBlock
}

func newNextButton() *markdown.Paragraph {
doc := parse(`<button class="next-btn">Next</button>`)
return doc.Blocks[0].(*markdown.Paragraph)
}

func isThematicBreak(blocks []markdown.Block, idx int) bool {
Expand Down
78 changes: 78 additions & 0 deletions build-tools/labsite-gen/main_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,26 @@ anybody here?`,
<summary>goodbye</summary>
</details>
</details>
`[1:],
}, {
name: "codeblocks",
in: `
# [>] hallo
` + "```evy" + `
print 1
print 2
` + "```" + `
`,
want: `
<details>
<summary>hallo</summary>
<pre><code class="language-evy">print 1
print 2
</code></pre>
</details>
`[1:],
},
}
Expand All @@ -78,3 +98,61 @@ func TestCollapse(t *testing.T) {
})
}
}

var nextButtonTests = []struct {
name string
in string
wantMD string
wantHTML string
}{
{
name: "no marker",
in: "hallo",
wantMD: "hallo\n",
wantHTML: "<p>hallo</p>\n",
},
{
name: "single button",
in: `[Next]`,
wantMD: `<button class="next-btn">Next</button>` + "\n",
wantHTML: `<p><button class="next-btn">Next</button></p>` + "\n",
},
{
name: "multiple buttons",
in: `# Heading
[Next]
paragraph
[Next]`,
wantMD: `
# Heading
<button class="next-btn">Next</button>
paragraph
<button class="next-btn">Next</button>
`[1:],
wantHTML: `
<h1>Heading</h1>
<p><button class="next-btn">Next</button></p>
<p>paragraph</p>
<p><button class="next-btn">Next</button></p>
`[1:],
},
}

func TestReplaceNextButton(t *testing.T) {
for _, tt := range nextButtonTests {
t.Run(tt.name, func(t *testing.T) {
p := markdown.Parser{}
doc := p.Parse(tt.in)
replaceNextButton(doc)
gotMD := markdown.Format(doc)
assert.Equal(t, tt.wantMD, gotMD)
gotHTML := markdown.ToHTML(doc)
assert.Equal(t, tt.wantHTML, gotHTML)
})
}
}
64 changes: 45 additions & 19 deletions frontend/lab/css/overrides.css
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@
--notes-max-width: min(25vw, calc(20rem + 32px));
--editor-max-width: calc(36rem + 16px);
}
html {
scroll-behavior: smooth;
}

.max-width-wrapper:not(:has(.main > .hidden)) {
max-width: calc(var(--editor-max-width) + var(--notes-max-width) + var(--canvas-size) + 64px);
Expand All @@ -22,6 +25,7 @@
overflow-y: auto;
height: 100%;
padding: 8px 16px var(--editor-padding-bottom) 16px;
scroll-behavior: smooth;
}

@media (min-width: 768px) {
Expand All @@ -40,34 +44,28 @@
margin-bottom: 16px;
font-size: 1.5rem;
}
.notes :is(h2, h3, h4, summary) {
.notes :is(h2, h3) {
color: var(--color);
font-size: 1rem;
font-weight: 400;
font-weight: 600;
margin-top: 16px;
margin-bottom: 12px;
}
.notes h2 {
font-weight: 600;
.notes h3 {
font-size: 0.875rem;
}

.notes details {
margin-top: 16px;
margin-bottom: 12px;
}
.notes summary {
.notes details pre {
margin: 0;
cursor: pointer;
font-weight: 600;
color: var(--color-slightly-dimmed);
font-size: 0.875rem;
}
.notes summary + p {
margin-top: 12px;
.notes details[open] > summary + * {
margin-top: 8px;
}
.notes p + details {
margin-top: -8px;
margin-bottom: 20px;
.notes details[open] {
margin-bottom: 16px;
}

.notes h4 {
Expand Down Expand Up @@ -124,7 +122,7 @@

.notes code {
padding: 0.25em;
font-size: 0.85rem;
font-size: 0.875em;
background-color: var(--background-inline-code);
border-radius: 4px;
color: var(--color);
Expand All @@ -135,6 +133,7 @@
color: var(--color);
background: none;
margin-bottom: 24px;
pointer-events: none;
}

.notes img {
Expand Down Expand Up @@ -191,7 +190,31 @@
border: 1px solid var(--border-color);
border-radius: 6px;
}

.notes summary {
list-style: none;
display: block;
}
summary::-webkit-details-marker {
display: none;
}
.notes summary,
.notes .next-btn {
background: none;
border: 1px solid var(--color-accent-hover);
color: var(--color-accent-hover);
border-radius: 10px;
padding: 4px;
min-width: 100px;
margin-left: auto;
margin-right: 0;
display: block;
width: fit-content;
text-align: center;
font-size: 1rem;
}
.next-btn.hidden {
display: none;
}
@media (max-width: 767px) {
.notes {
display: none;
Expand All @@ -203,10 +226,13 @@
}

@media (hover: hover) {
.notes summary {
.notes summary,
.notes .next-btn {
&:hover,
&:hover code {
color: var(--color-accent);
color: hsl(201deg 100% 78%);
border-color: hsl(201deg 100% 78%);
cursor: pointer;
}
}
}
17 changes: 11 additions & 6 deletions frontend/lab/samples/ifs/alpha.htmlf
Original file line number Diff line number Diff line change
@@ -1,13 +1,18 @@
<h1>🌈 Transparent Colors</h1>
<p>⭐ <strong>Read</strong> and <strong>Run</strong> the code. Does it make sense to you?</p>
<p>⭐ <strong>Complete it</strong> to create the following drawing:</p>
<h2>⭐ Intro</h2>
<p><strong>Read</strong> the code. What do you think will happen when you run it?</p>
<p><strong>Run</strong> the code. Was it what you expected?</p>
<p><button class="next-btn">Next</button></p>
<h2>⭐ Add a Yellow Rectangle</h2>
<p>Complete the code to create the following drawing:</p>
<p>
<img src="samples/ifs/img/red-dot-two-squares.svg" alt="simple drawing of circles and squares" />
</p>
<p><button class="next-btn">Next</button></p>
<h2>⭐ Tweak the Alpha</h2>
<p>
⭐ <strong>Modify the Alpha</strong> parameter to the
<a href="/docs/builtins.html#hsl"><code>hsl</code></a> function to make the bottom quadrant grey,
like so:
Tweak the Alpha parameter to the <a href="/docs/builtins.html#hsl"><code>hsl</code></a> function,
its fourth parameter, to make the bottom left quadrant grey:
</p>
<p>
<img
Expand All @@ -16,7 +21,7 @@
/>
</p>
<details>
<summary>Understanding Alpha 📖</summary>
<summary>Docs</summary>
<p>
In the interactive <a href="/docs/builtins.html#hsl"><code>hsl</code></a> function
<a href="#hsl">color explorer</a> we learned how hsl takes three values: hue, saturation,
Expand Down
22 changes: 17 additions & 5 deletions frontend/lab/samples/ifs/alpha.md
Original file line number Diff line number Diff line change
@@ -1,17 +1,29 @@
# 🌈 Transparent Colors

**Read** and **Run** the code. Does it make sense to you?
## ⭐ Intro

**Complete it** to create the following drawing:
**Read** the code. What do you think will happen when you run it?

**Run** the code. Was it what you expected?

[Next]

## ⭐ Add a Yellow Rectangle

Complete the code to create the following drawing:

![simple drawing of circles and squares](samples/ifs/img/red-dot-two-squares.svg)

**Modify the Alpha** parameter to the [`hsl`] function to make the bottom
quadrant grey, like so:
[Next]

## ⭐ Tweak the Alpha

Tweak the Alpha parameter to the [`hsl`] function, its fourth parameter, to make
the bottom left quadrant grey:

![simple drawing of circles and squares](samples/ifs/img/red-dot-two-squares-alpha.svg)

## [>] Understanding Alpha 📖
## [>] Docs

In the interactive [`hsl`] function [color explorer](#hsl) we learned how hsl
takes three values: hue, saturation, lightness values to create a color.
Expand Down
3 changes: 2 additions & 1 deletion frontend/lab/samples/ifs/bounce.htmlf
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
<p>
Check out the <a href="#bounce-show">bouncing ball page 🏓📺</a> or observe the animation below.
</p>
<h2>Demo</h2>
<details>
<summary>Animation demo</summary>
<p><img src="samples/ifs/img/bounce.gif" alt="small centered circle" /></p>
Expand All @@ -26,7 +27,7 @@
<a href="#pulse">Pulse challenge</a>.
</p>
<details>
<summary>Code hint 🧚</summary>
<summary>Hint</summary>
<p>Inside the loop body add:</p>
<pre><code class="language-evy">x = x + inc
if x &lt; 10 or x &gt; 90
Expand Down
Loading

0 comments on commit 16f9213

Please sign in to comment.