diff --git a/TODO.md b/TODO.md index 4109d76..b889f4c 100644 --- a/TODO.md +++ b/TODO.md @@ -6,7 +6,10 @@ * Inform tag type (% or <) in result * Handle other kinds of quotes * Handle escaping quote characters -* Handle escaping the shortcode itself like \{{% foo %}} (check with hugo docs) -* Report errors on mismatched {{% foo >}} +* Handle escaping the shortcode itself like `\{{% foo %}}` (check with hugo docs) +* Report errors on mismatched `{{% foo >}}` +* Add self-closing shortcodes `{{< foo />}}` + (also, how TF do they work?) +* Add inline shortcodes `{{< time.inline >}}{{ now }}{{< /time.inline >}}` * ~~Detect mismatched start/end like {{% foo >}}~~ diff --git a/shortcodes.rl b/shortcodes.rl index 496a7da..a11ba58 100644 --- a/shortcodes.rl +++ b/shortcodes.rl @@ -43,10 +43,10 @@ arg = ((argname '=')? (value|qvalue)); - start_p = '{{%'; + start_p = ('{{%'); end_p = '%}}'; - start_b = '{{<'; + start_b = ('{{<'); end_b = '>}}'; content = spc name (sep arg)* spc; @@ -73,8 +73,10 @@ closing_shortcode = (start spc '/' name spc end) > { - // Starting a shortcode, close data (if previous shortcode is opening) - // If it's closing, then previous text can't be data. + // Starting a "closing" shortcode ( {{ /foo }}), + // close data (if previous shortcode is opening) + // If previous shortcode was closing, then previous + // text can't be data. if (sc_list[c_sc-1].matching == 0) { sc_list[c_sc-1].data.start = data_mark-start; sc_list[c_sc-1].data.len = p-data_mark-1; diff --git a/tests.c b/tests.c index a80b3d1..e8f3875 100755 --- a/tests.c +++ b/tests.c @@ -46,6 +46,30 @@ Ensure(parse, mismatched_brackets) assert_that(result[0].name.len, is_equal_to(0)); } +Ensure(parse, mismatched_brackets_inside_data_are_ok) +{ + char *input = "foobar {{% sc %}} >}}blah {{% /sc %}} "; + result = parse(input); + // 1 shortcode + assert_that(result[1].name.len, is_equal_to(0)); + chunk_s(input, result[0].whole); + assert_that(s.s, is_equal_to_string("{{% sc %}} >}}blah {{% /sc %}}")); + chunk_s(input, result[0].data); + assert_that(s.s, is_equal_to_string(" >}}blah ")); +} + +Ensure(parse, mismatched_brackets_in_qval_are_ok) +{ + char *input = "foobar {{% sc \">}}blah\" %}} {{% /sc %}}"; + result = parse(input); + // 1 shortcode + assert_that(result[1].name.len, is_equal_to(0)); + chunk_s(input, result[0].whole); + assert_that(s.s, is_equal_to_string("{{% sc \">}}blah\" %}} {{% /sc %}}")); + chunk_s(input, result[0].argvals[0]); + assert_that(s.s, is_equal_to_string(">}}blah")); +} + Ensure(parse, inner_spaces_optional) { char *input = "foobar {{% shortcode%}}blah"; @@ -166,18 +190,31 @@ Ensure(parse, shortcode_args) assert_that(s.s, is_equal_to_string("v2")); } +Ensure(parse, escaped_shortcode) +{ + char *input = "foobar \\{{% shortcode %}}"; + result = parse(input); + // No shortcodes + assert_that(result[0].name.len, is_equal_to(0)); +} + int main(int argc, char **argv) { str_init(&s); TestSuite *suite = create_test_suite(); add_test_with_context(suite, parse, empty_string); - add_test_with_context(suite, parse, mismatched_brackets); add_test_with_context(suite, parse, simple_shortcode); + add_test_with_context(suite, parse, mismatched_brackets); + add_test_with_context(suite, parse, mismatched_brackets_inside_data_are_ok); + add_test_with_context(suite, parse, mismatched_brackets_in_qval_are_ok); add_test_with_context(suite, parse, name_can_be_path); add_test_with_context(suite, parse, inner_spaces_optional); add_test_with_context(suite, parse, multiple_shortcodes); add_test_with_context(suite, parse, matching_shortcode); add_test_with_context(suite, parse, shortcode_args); + + // Bugs + // add_test_with_context(suite, parse, escaped_shortcode); return run_test_suite(suite, create_text_reporter()); }