Skip to content

Commit e5b1131

Browse files
committed
Prepare for interactive guides
1 parent 67a2fca commit e5b1131

File tree

3 files changed

+96
-18
lines changed

3 files changed

+96
-18
lines changed

tiny-doc/src/docs/asciidoc/docinfo-header.html

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -260,6 +260,26 @@
260260
color: #ff0080;
261261
}
262262

263+
/* Static code block + "Try it" button (matches API fn-card pattern) */
264+
.fn-card__try-btn { margin-left: auto; }
265+
.fn-card__filename {
266+
color: #888;
267+
font-size: .8rem;
268+
font-family: 'Source Code Pro', monospace;
269+
}
270+
.fn-card__code {
271+
padding: 20px 24px;
272+
background: #f8f9fa;
273+
border: 1px solid #e0e0e0;
274+
border-top: none;
275+
border-radius: 0 0 10px 10px;
276+
font-family: 'Source Code Pro', monospace;
277+
font-size: .88rem;
278+
line-height: 1.7;
279+
color: #333;
280+
}
281+
.fn-card__code pre { margin: 0; white-space: pre-wrap; }
282+
263283
/* Status bar: reload progress indicator */
264284
.tiny-status-bar {
265285
width: calc(100%);

tiny-doc/src/docs/asciidoc/tiny-tutorial.adoc

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,20 @@ function _init()
3737
end
3838
```
3939

40-
== Step 2: Update the Game State
40+
== Step 2: Draw the Game
41+
In the `_draw()` callback, we'll draw the paddles and the ball using the `shape.rectf()` and `shape.circlef()` functions.
42+
43+
```lua
44+
function _draw()
45+
-- Draw game
46+
gfx.cls()
47+
shape.rectf(player1_pos.x, player1_pos.y, paddle_width, paddle_height, 7)
48+
shape.rectf(player2_pos.x, player2_pos.y, paddle_width, paddle_height, 7)
49+
shape.circlef(ball_pos.x, ball_pos.y, ball_radius, 7)
50+
end
51+
```
52+
53+
== Step 3: Update the Game State
4154
In the `_update()` callback, we'll update the game state by moving the paddles and the ball. We'll also check for collisions between the ball and the paddles, and update the ball's velocity accordingly.
4255

4356
```lua
@@ -83,18 +96,7 @@ function _update()
8396
end
8497
```
8598

86-
== Step 3: Draw the Game
87-
In the `_draw()` callback, we'll draw the paddles and the ball using the `shape.rectf()` and `shape.circlef()` functions.
8899

89-
```lua
90-
function _draw()
91-
-- Draw game
92-
gfx.cls()
93-
shape.rectf(player1_pos.x, player1_pos.y, paddle_width, paddle_height, 7)
94-
shape.rectf(player2_pos.x, player2_pos.y, paddle_width, paddle_height, 7)
95-
shape.circlef(ball_pos.x, ball_pos.y, ball_radius, 7)
96-
end
97-
```
98100

99101
And that's it! With these three steps, you should have a basic Pong game up and running in Lua. Feel free to experiment with the game state, update function, and drawing function to customize the game to your liking.
100102

tiny-web-editor/src/jsMain/kotlin/Main.kt

Lines changed: 62 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -83,28 +83,69 @@ private fun setupDocMode(
8383
val spritePath = game.getAttribute("sprite")
8484
val levelPath = game.getAttribute("level")
8585

86+
// Check if the fn-card structure already exists (e.g. API page from fn-card.peb).
87+
// If not, create the toolbar + static code block + "Try it" button dynamically.
88+
val hasFnCard = game.parentElement?.classList?.contains("fn-card__example") == true
89+
var codeBlock: Element? = null
90+
91+
if (!hasFnCard) {
92+
val toolbar = document.createElement("div") {
93+
setAttribute("class", "tiny-toolbar")
94+
}
95+
game.after(toolbar)
96+
97+
toolbar.appendChild(
98+
document.createElement("span") {
99+
setAttribute("class", "fn-card__filename")
100+
textContent = "example.lua"
101+
},
102+
)
103+
104+
val tryButton = document.createElement("a") {
105+
setAttribute("class", "fn-card__try-btn tiny-button")
106+
innerHTML = """<i data-lucide="play"></i> Try it"""
107+
}
108+
toolbar.appendChild(tryButton)
109+
110+
codeBlock = document.createElement("div") {
111+
setAttribute("class", "fn-card__code")
112+
val pre = document.createElement("pre")
113+
pre.innerHTML = highlightStatic(code)
114+
appendChild(pre)
115+
}
116+
toolbar.after(codeBlock)
117+
118+
tryButton.addEventListener("click", {
119+
game.dispatchEvent(Event("play"))
120+
})
121+
122+
js("if (typeof lucide !== 'undefined') { lucide.createIcons(); }")
123+
}
124+
86125
val container = document.createElement("div").apply {
87126
setAttribute("class", "tiny-container")
88127
asDynamic().style.display = "none"
89128
}
90-
game.after(container)
129+
(codeBlock ?: game).after(container)
91130

92131
val codeToUse = decodedCode ?: "-- Update the code to update the game!\n$code"
93132

94133
var started = false
95-
game.addEventListener("play", {
134+
135+
fun startGame() {
96136
if (!started) {
137+
codeBlock?.asDynamic()?.style?.display = "none"
97138
container.asDynamic().style.display = ""
98139
createGame(container, index, codeToUse, spritePath, levelPath, rootPath)
99140
started = true
100141
}
101-
})
142+
}
143+
144+
game.addEventListener("play", { startGame() })
102145

103146
// There is a user code. Let's unfold the game.
104147
if (savedCode != null) {
105-
container.asDynamic().style.display = ""
106-
createGame(container, index, codeToUse, spritePath, levelPath, rootPath)
107-
started = true
148+
startGame()
108149
}
109150
}
110151

@@ -268,6 +309,21 @@ fun setCaret(
268309
return position
269310
}
270311

312+
/**
313+
* Highlight Lua code for static display (no line wrapping in divs).
314+
* Same highlighting rules as [highlight] but suited for a <pre> block.
315+
*/
316+
fun highlightStatic(content: String): String {
317+
return content
318+
.replace(Regex("(\".*?\")"), "<strong class=\"code_string\">$1</strong>")
319+
.replace(Regex("--(.*)"), """<em class="code_comment">--$1</em>""")
320+
.replace(
321+
Regex("\\b(if|else|elif|end|while|for|in|of|continue|break|return|function|local|do)\\b"),
322+
"""<strong class="code_keyword">$1</strong>""",
323+
)
324+
.replace(Regex("\\b(\\d+)"), "<em class=\"code_number\">$1</em>")
325+
}
326+
271327
/**
272328
* Highlight the code with HTML tags.
273329
*

0 commit comments

Comments
 (0)