Compare commits
2 commits
59b1d6c116
...
35013b0676
| Author | SHA1 | Date | |
|---|---|---|---|
| 35013b0676 | |||
| 07dd66ed07 |
3 changed files with 97 additions and 4 deletions
63
README.md
63
README.md
|
|
@ -0,0 +1,63 @@
|
|||
# YAMD
|
||||
|
||||
Indentation-based markup language that compiles to HTML via Ruby codegen.
|
||||
|
||||
## Syntax
|
||||
|
||||
Structure is defined by indentation (tabs). Lines at a given indent level belong to the enclosing directive.
|
||||
|
||||
### Directives (line-start only)
|
||||
|
||||
| Syntax | Description |
|
||||
|--------|-------------|
|
||||
| `#% <ruby code>` | Metadata / Ruby statement. e.g. `#% meta "date", "2025 01 01"` |
|
||||
| `#! <expr>` | Block wrapper. Evaluates `expr` as a Ruby method call, content is passed as a block. e.g. `#! tag('h1')` |
|
||||
| `#$ <expr>` | Raw block. Like `#!` but inner lines are passed as a raw string (no YAMD parsing). Used for code blocks. e.g. `#$ code` |
|
||||
| `#. ` | List item. Must appear inside a `#! list(...)` block |
|
||||
|
||||
### Inline constructs
|
||||
|
||||
| Syntax | Description |
|
||||
|--------|-------------|
|
||||
| `` #`...` `` | Inline code |
|
||||
| `#{expr}` | Ruby expression interpolation (result converted to string) |
|
||||
| `#(expr)` | Inline math (AsciiMath, rendered to MathML) |
|
||||
| `#name(args)` | Method call. e.g. `#link("url")` |
|
||||
| `#name(args)#{ content }#` | Method call with content block. e.g. `#link("url")#{ click here }#` |
|
||||
| `##` | Escaped literal `#` |
|
||||
| `}#` | Closes a `#{` content block |
|
||||
|
||||
### Comments
|
||||
|
||||
Lines matching `#` followed by nothing or a space (i.e. `#` or `# ...`) are comments and are skipped.
|
||||
|
||||
### Available renderer methods
|
||||
|
||||
These are defined by `HTMLRenderer` in `exe/yamd`:
|
||||
|
||||
| Method | Usage |
|
||||
|--------|-------|
|
||||
| `tag(name, **attrs)` | HTML element. `#! tag('h2')` |
|
||||
| `list(numbering)` | List. numbering: `"-"` (ul), `"1"`, `"a"`, `"A"`, `"i"`, `"I"` (ol). Dot-separated for nested: `"-.1"` |
|
||||
| `link(url)` | Anchor tag. `#link("https://example.com")#{ text }#` |
|
||||
| `code(lang: Lang::DEFAULT)` | Code block (used via `#$`). Optional `lang:` for highlighting rules |
|
||||
| `meta(name, value)` | HTML `<meta>` tag. Used via `#%` |
|
||||
| `inline_code(text)` | Inline `<code>`. Used via `` #`...` `` |
|
||||
| `inline_math(text)` | AsciiMath to MathML. Used via `#(...)` |
|
||||
|
||||
### Example
|
||||
|
||||
```
|
||||
#% meta "date", "2025 01 01"
|
||||
|
||||
#! tag('h1')
|
||||
Title
|
||||
|
||||
Paragraph text with #`inline code` and #link("https://example.com")#{ a link }#.
|
||||
|
||||
#! list('-')
|
||||
#. First item
|
||||
#. Second item with sub-content
|
||||
#$ code
|
||||
x = 1
|
||||
```
|
||||
23
exe/yamd
23
exe/yamd
|
|
@ -91,6 +91,23 @@ class HTMLRenderer < YAMD::Renderer
|
|||
}
|
||||
end
|
||||
|
||||
def single_tag(name, **attrs)
|
||||
@buf << "<#{name}"
|
||||
attrs.each { |k, v|
|
||||
@buf << " "
|
||||
if k.kind_of? Symbol
|
||||
k = k.to_s
|
||||
end
|
||||
@buf << k
|
||||
@buf << "=" << v.dump
|
||||
}
|
||||
@buf << "/>"
|
||||
end
|
||||
|
||||
def meta(name, value)
|
||||
single_tag('meta', name: name, content: value)
|
||||
end
|
||||
|
||||
def tag(name, **attrs)
|
||||
@buf << "<#{name}"
|
||||
attrs.each { |k, v|
|
||||
|
|
@ -110,16 +127,16 @@ class HTMLRenderer < YAMD::Renderer
|
|||
tag('a', href: to, &blk)
|
||||
end
|
||||
|
||||
def code(&blk)
|
||||
def code(lang: YAMD::Code::Lang::DEFAULT, &blk)
|
||||
tag('pre', class: "language-any") {
|
||||
tag('code', class: "language-any") {
|
||||
@buf << YAMD::Code::highlight(blk.())
|
||||
@buf << YAMD::Code::highlight(blk.(), lang)
|
||||
}
|
||||
}
|
||||
end
|
||||
|
||||
def inline_code(text)
|
||||
tag('code') {
|
||||
tag('code', class: "code-inline") {
|
||||
@buf << YAMD::Code::highlight(text)
|
||||
}
|
||||
end
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ module YAMD::Code
|
|||
DEFAULT = {
|
||||
/\b(?:[A-Z][a-zA-Z\-_0-9]*)\b*/ => 'type',
|
||||
/#(\s|$)[^\n]*/ => 'comment',
|
||||
/\b(?:open|final|class|fn|let|var|if|else|while|loop|return|namespace|new)\b/ => 'kw',
|
||||
/\b(?:open|final|class|struct|enum|fn|let|var|if|else|while|loop|return|namespace|new)\b/ => 'kw',
|
||||
/\b(?:def|import|from)\b/ => 'kw',
|
||||
/\b(?:null|undefined|true|false|this|self)\b/i => 'const',
|
||||
/\b(?:__[a-zA-Z0-9_]+__)\b/i => 'const',
|
||||
|
|
@ -30,6 +30,19 @@ module YAMD::Code
|
|||
/"(?:\\.|[^\\"])*"/ => 'str',
|
||||
/'(?:\\.|[^\\'])*'/ => 'str',
|
||||
}
|
||||
|
||||
GD_SCRIPT = {
|
||||
/\b(?:[A-Z_]+[A-Z_0-9]*)\b/ => 'const',
|
||||
/\b(?:[A-Z][a-zA-Z\-_0-9]*)\b*/ => 'type',
|
||||
/#(\s|$)[^\n]*/ => 'comment',
|
||||
/\b(?:class|struct|enum|var|func|const|if|else|while|return)\b/ => 'kw',
|
||||
/\b(?:class_name|extends)\b/ => 'kw',
|
||||
/\b(?:null|true|false|self)\b/i => 'const',
|
||||
/[:,;()\[\]{}<>]/ => 'punct',
|
||||
/0|(0x[0-9a-fA-F]+)|([1-9][0-9]*(\.[0-9]+)?)/ => 'number',
|
||||
/"(?:\\.|[^\\"])*"/ => 'str',
|
||||
/'(?:\\.|[^\\'])*'/ => 'str',
|
||||
}
|
||||
end
|
||||
|
||||
def self.highlight(txt, highlights=Lang::DEFAULT)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue