> [!tldr] A collection of [[Plaintext]] [[Pattern]]s with usually carry [[Ontology, Semantics, and Syntax|semantic]] meaning. [[Plain Text Weaknesses]] exist. For one, [[Things not Strings|a string is a string is a string]]. However, by convention you can make strings mean more. You can encode: - [[#Markdown Syntax]] - [[#Data Encoding]] - [[#YAML Blocks]] - [[#Inline Properties]] - [[#Rapid Logging Sigils]] - [[#URI s]] - [[#ASCII Art]] - [[#HTML]] > [!note] > This note is about *what **small things** can you put into a plaintext (or Markdown) document to do special things?* > It was born in support of my [[A Digital Asset Management System Design|Digital Asset Management System]] for Asset references. ## [[Markdown]] Syntax Plaintext can carry formatting information via markdown syntax. Including [[Extended Markdown Syntax]]. ```markdown - this is a bullet - this is an indented bullet **this is bold** *this is italic* - [ ] this is an undone task - [x] this is a done task [This is a link](https://example.com) --- 👆 that is a horizontal rule ``` Note: every example in this file is encapsulated in standard markdown code fences. ### Specific Sub-flavors ```markdown [[Wikilinks]] ``` ## Data Encoding Plaintext strings can be used to represent data. Most file formats I work with are just [[UTF-8]]-encoded files that fit a particular syntax. [[XML]], [[JSON]], [[YAML]], [[CSV]], etc. ```csv date, name, note 2026-08-05, Plaintext Magic Strings, This note here! 2026-08-05, Obsidian URIs, a note I also just touched. ``` ```json { name: "Aaron", height: 80 } ``` ```yaml name: Aaron height: 80 ``` ### YAML Blocks This is sort of the crux of what I was hoping to achieve with this note. If you're looking at a Markdown file, you can assume that triple dashes are horizontal rules. But a pair of horizontal rules sandwiching some [[YAML]] at the top of a file is [[Frontmatter]]. ```markdown --- status: draft --- This is the core essence of this note. ``` ### Inline Properties There is no "official" way to do this. There are, however, some examples of prior art which seem to be converging on a common `key:: value` syntax. This is used by [[Dataview Plug-in]] and [[Logseq]]. ```markdown - This is a block example:: this property is a piece of metadata about the block above id:: abc123 - This is a subblock, not a piece of metadata. Its here to show that not every block would need proerties. - This subblock has some inline properties. example:: this example property is on the subblock right above it ``` ## Rapid Logging Sigils If you follow Ryder Carrol's[[Bullet Journaling|Bullet Journal]] [[Rapid Logging]] approach, a [[Sigil]] can carry meaning. He does it with a pen & pencil, but it works digitally as well. ```plaintext - this is a thought = this is a feeling [ ] this is a task ! this is important ``` ## [[URI]]s This is the heavy-hitter in terms of plaintext magic strings. URIs can do anything, really. [[Obsidian URIs]] are a thing, as are [[Shortcuts App]] URIs and file URIs. You **can** register your own URI handler, but it requires creating & installing your own app. ```plaintext file://Users/aaron/Documents/example.md obsidian://new?vault=Notes&name=my%20new%20note shortcuts://run-shortcut?name=URITEST&input=Hello%20World ``` ## [[ASCII Art]] Shout out to [[Character Encoding|ASCII]] art. It's not really a "magic string", but it is an example of a thing you can insert into plaintext that has a specific and different interpretation than "read these characters at face value". ```plaintext __ ____ ___ __ __ __ ____ ____ / _\ / ___) / __)( )( ) / _\ ( _ \(_ _) / \\___ \( (__ )( )( / \ ) / )( \_/\_/(____/ \___)(__)(__) \_/\_/(__\_) (__) ``` ```plaintext .--------------------. | | | ASCII ART IS FUN | | ------------------ | '--------------------' ``` ## [[HTML]] Because [[Markdown]] is a superset of [[HTML]], you could insert full [[Single HTML File App]]s into documents. <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Tiny HTML Snake</title> <style> body { background-color: #222; color: #fff; font-family: 'Courier New', Courier, monospace; display: flex; flex-direction: column; align-items: center; justify-content: center; height: 100vh; margin: 0; } h1 { margin-bottom: 10px; } canvas { border: 4px solid #555; background-color: #111; box-shadow: 0 0 20px rgba(0,0,0,0.5); } #score-board { font-size: 24px; margin-top: 15px; } </style> </head> <body> <p>🐍 SNAKE</p> <canvas id="gameCanvas" width="400" height="400"></canvas> <div id="score-board">Score: <span id="score">0</span></div> <script> const canvas = document.getElementById("gameCanvas"); const ctx = canvas.getContext("2d"); const scoreElement = document.getElementById("score"); // Grid and game variables const gridSize = 20; const tileCount = canvas.width / gridSize; let snake = [{x: 10, y: 10}]; let food = {x: 15, y: 15}; let dx = gridSize; let dy = 0; let score = 0; let changingDirection = false; let gameInterval; // Start game loop main(); function main() { gameInterval = setInterval(function onTick() { changingDirection = false; clearCanvas(); drawFood(); moveSnake(); drawSnake(); checkGameOver(); }, 100); } // Clear the canvas every frame function clearCanvas() { ctx.fillStyle = "#111"; ctx.fillRect(0, 0, canvas.width, canvas.height); } // Draw the snake function drawSnake() { snake.forEach(part => { ctx.fillStyle = "#00FF00"; ctx.strokeStyle = "#111"; ctx.fillRect(part.x, part.y, gridSize, gridSize); ctx.strokeRect(part.x, part.y, gridSize, gridSize); }); } // Move the snake forward function moveSnake() { const head = {x: snake[0].x + dx, y: snake[0].y + dy}; snake.unshift(head); // Check if snake ate the food const hasEatenFood = snake[0].x === food.x && snake[0].y === food.y; if (hasEatenFood) { score += 10; scoreElement.innerText = score; generateFood(); } else { snake.pop(); } } // Generate food in a random position function generateFood() { food.x = Math.floor(Math.random() * tileCount) * gridSize; food.y = Math.floor(Math.random() * tileCount) * gridSize; // Ensure food doesn't spawn on the snake snake.forEach(function hasSnakeEatenFood(part) { const hasEaten = part.x === food.x && part.y === food.y; if (hasEaten) generateFood(); }); } // Draw food on the canvas function drawFood() { ctx.fillStyle = "#FF0000"; ctx.fillRect(food.x, food.y, gridSize, gridSize); } // Check for collisions function checkGameOver() { // Tail collision for (let i = 4; i < snake.length; i++) { if (snake[i].x === snake[0].x && snake[i].y === snake[0].y) return endGame(); } // Wall collision const hitLeftWall = snake[0].x < 0; const hitRightWall = snake[0].x >= canvas.width; const hitToptWall = snake[0].y < 0; const hitBottomWall = snake[0].y >= canvas.height; if (hitLeftWall || hitRightWall || hitToptWall || hitBottomWall) { endGame(); } } function endGame() { clearInterval(gameInterval); alert("Game Over! Final Score: " + score); // Reset game snake = [{x: 10, y: 10}]; dx = gridSize; dy = 0; score = 0; scoreElement.innerText = score; generateFood(); main(); } // Handle keyboard controls document.addEventListener("keydown", changeDirection); function changeDirection(event) { const LEFT_KEY = 37; const UP_KEY = 38; const RIGHT_KEY = 39; const DOWN_KEY = 40; if (changingDirection) return; const goingUp = dy === -gridSize; const goingDown = dy === gridSize; const goingRight = dx === gridSize; const goingLeft = dx === -gridSize; if (event.keyCode === LEFT_KEY && !goingRight) { dx = -gridSize; dy = 0; changingDirection = true; } if (event.keyCode === UP_KEY && !goingDown) { dx = 0; dy = -gridSize; changingDirection = true; } if (event.keyCode === RIGHT_KEY && !goingLeft) { dx = gridSize; dy = 0; changingDirection = true; } if (event.keyCode === DOWN_KEY && !goingUp) { dx = 0; dy = gridSize; changingDirection = true; } } </script> </body> </html> Probably don't, though. # More ## Source - self