This commit is contained in:
Roberto Alsina 2023-07-14 12:08:11 -03:00
parent df2c0c147a
commit 817eea895a
4 changed files with 48 additions and 12 deletions

View File

@ -1,5 +1,7 @@
# Shortcodes # Shortcodes
## What it is
This is a parser for the shortcode spec as explained in the Hugo docs This is a parser for the shortcode spec as explained in the Hugo docs
and used in Hugo and Nikola. Approximately. and used in Hugo and Nikola. Approximately.
@ -9,14 +11,50 @@ It probably won't be 100% identical, but I'll try to make it
as close as practical. as close as practical.
* Implemented in Ragel + C for performance * Implemented in Ragel + C for performance
* Allocates no memory, because all strings are references to * Allocates no memory, because all strings are references to
pieces of input. pieces of input.
What works: ## What works
* Detect shortcodes with names * Detect shortcodes with names
* Standalone and matched shortcodes * Standalone and matched shortcodes
* Capture data between tags in matched shortcodes * Capture data between tags in matched shortcodes
* Capture arguments with and without names * Capture arguments with and without names
* Capture values with and without quotes (with details, see TODO above) * Capture values with and without quotes (with details, see [TODO](TODO.md))
## Building
You need [Ragel](http://www.colm.net/open-source/ragel/) and a C compiler.
Ragel is used to generate `shortcodes.c` out of `shortcodes.rl`.
As a convenience there is a generated `shortcodes.c` in the repo,
Then:
```shell
cd src && make
```
To run tests:
```shell
crystal spec
```
## Installation
1. Add the dependency to your `shard.yml`:
```yaml
dependencies:
cr-discount:
github: ralsina/shortcodes
```
2. Run `shards install`
## Usage
```crystal
require "shortcodes"
```

View File

@ -4,9 +4,9 @@ describe "Shortcodes" do
# TODO: Write tests # TODO: Write tests
it "works" do it "works" do
result = Shortcodes.parse("foo{{% bar %}}baz{{% /bar %}}qux"); result = Shortcodes.parse("foo{{% bar %}}baz{{% /bar %}}qux")
p! result.sccount; result.sccount.should eq 1
p! result.shortcodes[0].matching; result.shortcodes[0].matching.should eq 1
end end
end end
@ -237,4 +237,4 @@ end
# // result = parse(input); # // result = parse(input);
# // // No shortcodes # // // No shortcodes
# // assert_that(result.sc[0].name.len, is_equal_to(0)); # // assert_that(result.sc[0].name.len, is_equal_to(0));
# // } # // }

View File

@ -1,4 +1,3 @@
CC=gcc
shortcodes.c: shortcodes.rl shortcodes.c: shortcodes.rl
ragel -G2 shortcodes.rl -o shortcodes.c ragel -G2 shortcodes.rl -o shortcodes.c
clean: clean:

View File

@ -1,13 +1,12 @@
@[Link(ldflags: "#{__DIR__}/shortcodes.o")] @[Link(ldflags: "#{__DIR__}/shortcodes.o")]
lib Shortcodes lib Shortcodes
struct Chunk struct Chunk
start : UInt32 start : UInt32
len : UInt32 len : UInt32
end end
struct ScError struct ScError
position: UInt32 position : UInt32
code : UInt32 code : UInt32
end end
@ -28,5 +27,5 @@ lib Shortcodes
errcount : UInt32 errcount : UInt32
end end
fun parse(input : Pointer(LibC::Char)) : ScResult; fun parse(input : Pointer(LibC::Char)) : ScResult
end end