diff --git a/vscode-slashdown/.vscodeignore b/vscode-slashdown/.vscodeignore new file mode 100644 index 0000000..f5f69a8 --- /dev/null +++ b/vscode-slashdown/.vscodeignore @@ -0,0 +1,10 @@ +.vscode/** +.vscode-test/** +.gitignore +.yarnrc +vsc-extension-quickstart.md +**/node_modules/** +**/*.map +**/.eslintrc.json +**/*.ts +!**/*.d.ts diff --git a/vscode-slashdown/CHANGELOG.md b/vscode-slashdown/CHANGELOG.md new file mode 100644 index 0000000..54de423 --- /dev/null +++ b/vscode-slashdown/CHANGELOG.md @@ -0,0 +1,23 @@ +# Change Log + +All notable changes to the "slashdown" extension will be documented in this file. + +## [0.1.0] - 2025-11-15 + +### Added +- Initial release of Slashdown syntax highlighting +- Tag syntax highlighting (`/tagname`) +- ID highlighting (`#id-name`) +- Class highlighting (`.class-name`) +- Attribute highlighting (`key="value"` and boolean attributes) +- Inline text content highlighting (`= text`) +- Comment support (`//`) +- Code fence support with language-specific syntax highlighting +- Full markdown syntax support: + - Headings (h1-h6) + - Bold and italic text + - Inline code + - Links + - Ordered and unordered lists +- Language configuration for auto-closing pairs and comment toggling +- Folding support for tag blocks diff --git a/vscode-slashdown/README.md b/vscode-slashdown/README.md new file mode 100644 index 0000000..84c7b58 --- /dev/null +++ b/vscode-slashdown/README.md @@ -0,0 +1,160 @@ +# Slashdown for Visual Studio Code + +Syntax highlighting for Slashdown - "For when MDX is too much, but Markdown is too little." + +## Features + +This extension provides comprehensive syntax highlighting for Slashdown files, including: + +- **Tag syntax**: `/tagname` with proper highlighting for HTML-like tags +- **IDs**: `#id-name` highlighting +- **Classes**: `.class-name` highlighting +- **Attributes**: Support for both `key="value"` and boolean attributes +- **Text content**: `= inline text` syntax +- **Comments**: `//` line comments +- **Code fences**: Triple backtick code blocks with language-specific syntax highlighting +- **Markdown**: Full markdown support including: + - Headings (h1-h6) + - Bold and italic text + - Inline code + - Links + - Lists (ordered and unordered) + +## Usage + +Create a file with a `.sd` or `.slashdown` extension and start writing Slashdown: + +```slashdown +/header .flex.justify-between + # Slashdown + [Get it](#) + +/ul .grid.grid-cols-3 + + /li + ### Easy to read + - lots of space + + /li + ### Fast to write + - type, type, type + + /li + ### You already know it + - Just markdown with extra oomph +``` + +## Slashdown Syntax Overview + +### Tags +Start a tag with `/` followed by the tag name: +```slashdown +/div +/header +/button +``` + +Use `/` alone as shorthand for `div`: +```slashdown +/ #container .wrapper +``` + +### IDs and Classes +Add IDs with `#` and classes with `.`: +```slashdown +/header #main-header .flex.justify-between +``` + +### Attributes +Add attributes on the same line or on following lines: +```slashdown +/button = Click me + hx-post="/api/roll" + hx-trigger="click" + class="bg-blue-500" + disabled +``` + +### Text Content +Use `=` for inline text content: +```slashdown +/h1 = Hello World +/p = This is a paragraph +``` + +### Markdown +Regular markdown works anywhere: +```slashdown +/article + # Main Heading + + This is a paragraph with **bold** and *italic* text. + + - List item 1 + - List item 2 +``` + +### Code Fences +Triple backticks work as expected: +````slashdown +/div + Here's some code: + + ```javascript + console.log('Hello, world!'); + ``` +```` + +### Comments +Use `//` for line comments: +```slashdown +// This is a comment +/div + // This is also a comment + # Not a comment +``` + +## Installation + +### From VSIX +1. Download the `.vsix` file from the releases +2. Open VSCode +3. Go to Extensions (Ctrl+Shift+X) +4. Click the "..." menu at the top +5. Select "Install from VSIX..." +6. Choose the downloaded `.vsix` file + +### From Source +1. Clone this repository +2. Run `npm install -g @vscode/vsce` if you don't have it +3. Run `vsce package` in the extension directory +4. Install the generated `.vsix` file as described above + +## Requirements + +- Visual Studio Code 1.75.0 or higher + +## Known Issues + +None at this time. Please report issues on the [GitHub repository](https://github.com/nickisnoble/slashdown). + +## Release Notes + +### 0.1.0 + +Initial release of Slashdown syntax highlighting: +- Tag syntax highlighting +- ID and class highlighting +- Attribute highlighting +- Inline text content +- Markdown support +- Code fence support with language-specific highlighting +- Comment support + +## About Slashdown + +Slashdown is a markup language that combines the simplicity of Markdown with HTML-like tag syntax. Learn more at [github.com/nickisnoble/slashdown](https://github.com/nickisnoble/slashdown). + +## License + +MIT diff --git a/vscode-slashdown/example.sd b/vscode-slashdown/example.sd new file mode 100644 index 0000000..08dea1d --- /dev/null +++ b/vscode-slashdown/example.sd @@ -0,0 +1,77 @@ +// This is a comment +// Example Slashdown file to test syntax highlighting + +/header .flex.justify-between #main-header + # Slashdown Syntax Example + [Get it on GitHub](https://github.com/nickisnoble/slashdown) + +/ .container + /section #introduction + ## What is Slashdown? + + Slashdown combines **Markdown** with *HTML-like* tags for more structured documents. + + - Easy to read + - Fast to write + - Powerful and flexible + + /section #examples + ## Examples + + ### Basic Tag + /div = This is a div with inline text + + ### Tag with Classes and IDs + / #hero .bg-blue-500.text-white.p-4 + # Welcome! + Click the button below to get started. + + /button = Get Started + class="bg-white text-blue-500 px-4 py-2 rounded" + onclick="handleClick()" + + ### HTMX Example + / #roll-result + /button = Roll Dice + hx-post="/api/roll?sides=6" + hx-trigger="click" + hx-target="#roll-result" + class="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded" + + ### Code Fence + Here's some JavaScript code: + + ```javascript + function greet(name) { + console.log(`Hello, ${name}!`); + } + + greet('World'); + ``` + + And some HTML: + + ```html +
+

Hello World

+
+ ``` + + /section #markdown-support + ## Full Markdown Support + + You can use all standard markdown features: + + 1. Ordered lists + 2. With multiple items + 3. Like this + + **Bold text**, *italic text*, and `inline code`. + + > Blockquotes work too! + + [Links are supported](https://example.com) + +/footer .mt-8.text-center + Made with ❤️ in Slashdown + /a href="https://miniware.team?ref=slashdown" target="_blank" = by Miniware diff --git a/vscode-slashdown/language-configuration.json b/vscode-slashdown/language-configuration.json new file mode 100644 index 0000000..7ea60ec --- /dev/null +++ b/vscode-slashdown/language-configuration.json @@ -0,0 +1,38 @@ +{ + "comments": { + "lineComment": "//" + }, + "brackets": [ + ["[", "]"], + ["(", ")"], + ["{", "}"] + ], + "autoClosingPairs": [ + { "open": "[", "close": "]" }, + { "open": "(", "close": ")" }, + { "open": "{", "close": "}" }, + { "open": "\"", "close": "\"" }, + { "open": "'", "close": "'" }, + { "open": "`", "close": "`" } + ], + "surroundingPairs": [ + ["[", "]"], + ["(", ")"], + ["{", "}"], + ["\"", "\""], + ["'", "'"], + ["`", "`"], + ["*", "*"], + ["_", "_"] + ], + "folding": { + "markers": { + "start": "^\\s*/", + "end": "^\\s*$" + } + }, + "indentationRules": { + "increaseIndentPattern": "^\\s*/.*$", + "decreaseIndentPattern": "^\\s*$" + } +} diff --git a/vscode-slashdown/package.json b/vscode-slashdown/package.json new file mode 100644 index 0000000..d467aea --- /dev/null +++ b/vscode-slashdown/package.json @@ -0,0 +1,52 @@ +{ + "name": "slashdown", + "displayName": "Slashdown", + "description": "Syntax highlighting for Slashdown - Markdown with HTML-like tags", + "version": "0.1.0", + "publisher": "slashdown", + "icon": "icon.png", + "engines": { + "vscode": "^1.75.0" + }, + "categories": [ + "Programming Languages" + ], + "keywords": [ + "slashdown", + "markdown", + "markup", + "syntax highlighting" + ], + "repository": { + "type": "git", + "url": "https://github.com/nickisnoble/slashdown" + }, + "contributes": { + "languages": [ + { + "id": "slashdown", + "aliases": [ + "Slashdown", + "slashdown", + "sd" + ], + "extensions": [ + ".sd", + ".slashdown" + ], + "configuration": "./language-configuration.json", + "icon": { + "light": "./icon.png", + "dark": "./icon.png" + } + } + ], + "grammars": [ + { + "language": "slashdown", + "scopeName": "text.slashdown", + "path": "./syntaxes/slashdown.tmLanguage.json" + } + ] + } +} diff --git a/vscode-slashdown/syntaxes/slashdown.tmLanguage.json b/vscode-slashdown/syntaxes/slashdown.tmLanguage.json new file mode 100644 index 0000000..d018eaf --- /dev/null +++ b/vscode-slashdown/syntaxes/slashdown.tmLanguage.json @@ -0,0 +1,342 @@ +{ + "$schema": "https://raw.githubusercontent.com/martinring/tmlanguage/master/tmlanguage.json", + "name": "Slashdown", + "scopeName": "text.slashdown", + "patterns": [ + { + "include": "#comment" + }, + { + "include": "#tag-line" + }, + { + "include": "#code-fence" + }, + { + "include": "#markdown-content" + } + ], + "repository": { + "comment": { + "name": "comment.line.double-slash.slashdown", + "match": "^\\s*//.*$" + }, + "tag-line": { + "name": "meta.tag.slashdown", + "begin": "^(\\s*)(/)([\\w-]*)", + "beginCaptures": { + "2": { + "name": "punctuation.definition.tag.begin.slashdown" + }, + "3": { + "name": "entity.name.tag.slashdown" + } + }, + "end": "$", + "patterns": [ + { + "include": "#tag-id" + }, + { + "include": "#tag-class" + }, + { + "include": "#tag-attribute" + }, + { + "include": "#tag-text" + } + ] + }, + "tag-id": { + "name": "meta.tag.id.slashdown", + "match": "#([\\w-]+)", + "captures": { + "0": { + "name": "entity.other.attribute-name.id.slashdown" + }, + "1": { + "name": "string.unquoted.id.slashdown" + } + } + }, + "tag-class": { + "name": "meta.tag.class.slashdown", + "match": "\\.([\\w-]+)", + "captures": { + "0": { + "name": "entity.other.attribute-name.class.slashdown" + }, + "1": { + "name": "string.unquoted.class.slashdown" + } + } + }, + "tag-attribute": { + "patterns": [ + { + "name": "meta.tag.attribute.with-value.slashdown", + "match": "([\\w-]+)(=)(\"[^\"]*\")", + "captures": { + "1": { + "name": "entity.other.attribute-name.slashdown" + }, + "2": { + "name": "punctuation.separator.key-value.slashdown" + }, + "3": { + "name": "string.quoted.double.slashdown" + } + } + }, + { + "name": "meta.tag.attribute.without-value.slashdown", + "match": "\\b([\\w-]+)\\b(?!\\s*=)", + "captures": { + "1": { + "name": "entity.other.attribute-name.slashdown" + } + } + } + ] + }, + "tag-text": { + "name": "meta.tag.text.slashdown", + "match": "=\\s+(.+)$", + "captures": { + "0": { + "name": "meta.embedded.text.slashdown" + }, + "1": { + "name": "string.unquoted.slashdown" + } + } + }, + "code-fence": { + "name": "markup.fenced_code.block.slashdown", + "begin": "^\\s*(`{3})(\\w+)?\\s*$", + "beginCaptures": { + "1": { + "name": "punctuation.definition.markdown.code-fence.begin.slashdown" + }, + "2": { + "name": "fenced_code.block.language.slashdown" + } + }, + "end": "^\\s*(`{3})\\s*$", + "endCaptures": { + "1": { + "name": "punctuation.definition.markdown.code-fence.end.slashdown" + } + }, + "patterns": [ + { + "begin": "(?<=```javascript|```js)", + "end": "(?=```)", + "name": "source.js.embedded.slashdown", + "patterns": [ + { + "include": "source.js" + } + ] + }, + { + "begin": "(?<=```typescript|```ts)", + "end": "(?=```)", + "name": "source.ts.embedded.slashdown", + "patterns": [ + { + "include": "source.ts" + } + ] + }, + { + "begin": "(?<=```python|```py)", + "end": "(?=```)", + "name": "source.python.embedded.slashdown", + "patterns": [ + { + "include": "source.python" + } + ] + }, + { + "begin": "(?<=```json)", + "end": "(?=```)", + "name": "source.json.embedded.slashdown", + "patterns": [ + { + "include": "source.json" + } + ] + }, + { + "begin": "(?<=```html)", + "end": "(?=```)", + "name": "text.html.embedded.slashdown", + "patterns": [ + { + "include": "text.html.basic" + } + ] + }, + { + "begin": "(?<=```css)", + "end": "(?=```)", + "name": "source.css.embedded.slashdown", + "patterns": [ + { + "include": "source.css" + } + ] + }, + { + "name": "markup.raw.block.slashdown", + "match": ".+" + } + ] + }, + "markdown-content": { + "patterns": [ + { + "name": "markup.heading.1.slashdown", + "match": "^\\s*(#{1})\\s+(.+)$", + "captures": { + "1": { + "name": "punctuation.definition.heading.slashdown" + }, + "2": { + "name": "entity.name.section.slashdown" + } + } + }, + { + "name": "markup.heading.2.slashdown", + "match": "^\\s*(#{2})\\s+(.+)$", + "captures": { + "1": { + "name": "punctuation.definition.heading.slashdown" + }, + "2": { + "name": "entity.name.section.slashdown" + } + } + }, + { + "name": "markup.heading.3.slashdown", + "match": "^\\s*(#{3})\\s+(.+)$", + "captures": { + "1": { + "name": "punctuation.definition.heading.slashdown" + }, + "2": { + "name": "entity.name.section.slashdown" + } + } + }, + { + "name": "markup.heading.4.slashdown", + "match": "^\\s*(#{4})\\s+(.+)$", + "captures": { + "1": { + "name": "punctuation.definition.heading.slashdown" + }, + "2": { + "name": "entity.name.section.slashdown" + } + } + }, + { + "name": "markup.heading.5.slashdown", + "match": "^\\s*(#{5})\\s+(.+)$", + "captures": { + "1": { + "name": "punctuation.definition.heading.slashdown" + }, + "2": { + "name": "entity.name.section.slashdown" + } + } + }, + { + "name": "markup.heading.6.slashdown", + "match": "^\\s*(#{6})\\s+(.+)$", + "captures": { + "1": { + "name": "punctuation.definition.heading.slashdown" + }, + "2": { + "name": "entity.name.section.slashdown" + } + } + }, + { + "name": "markup.bold.slashdown", + "match": "(\\*\\*|__)(?=\\S)(.+?)(?<=\\S)\\1", + "captures": { + "1": { + "name": "punctuation.definition.bold.slashdown" + }, + "2": { + "name": "markup.bold.slashdown" + } + } + }, + { + "name": "markup.italic.slashdown", + "match": "(\\*|_)(?=\\S)(.+?)(?<=\\S)\\1", + "captures": { + "1": { + "name": "punctuation.definition.italic.slashdown" + }, + "2": { + "name": "markup.italic.slashdown" + } + } + }, + { + "name": "markup.inline.raw.slashdown", + "match": "(`+)(?!`)(.+?)(?