Refactor modules into contexts (#78)
* [WIP] break out a few contexts, start refactoring fast index modules * [WIP] more contexts, this time around slow indexing and downloads * [WIP] got all tests passing * [WIP] Added moduledocs * Built a genserver to rename old jobs on boot * Added a module naming check; moved things around * Fixed specs
This commit is contained in:
@@ -0,0 +1,52 @@
|
||||
defmodule Pinchflat.Downloading.OutputPath.Base do
|
||||
@moduledoc """
|
||||
A base module for parsing rendered strings, designed as a macro to be used
|
||||
in other modules. See https://elixirforum.com/t/help-to-parse-a-template-with-nimbleparsec/47980
|
||||
|
||||
NOTE: if the needs here get any more complicated, look into using a Liquid
|
||||
template parser. No need to reinvent the wheel any more than I already have.
|
||||
|
||||
NOTE: this is effectively tested by the `Pinchflat.Downloading.OutputPath.Parser`'s tests
|
||||
"""
|
||||
|
||||
defmacro __using__(_opts) do
|
||||
quote location: :keep do
|
||||
import NimbleParsec
|
||||
|
||||
opening_tag = string("{{")
|
||||
closing_tag = string("}}")
|
||||
optional_whitespaces = ascii_string(~c[ \t\n\r], min: 0)
|
||||
|
||||
# Capture everything up to the opening object
|
||||
text =
|
||||
lookahead_not(opening_tag)
|
||||
# ... as long as it's a character
|
||||
|> utf8_char([])
|
||||
# ... and there's at least one character
|
||||
|> times(min: 1)
|
||||
# ... and then convert it to a string
|
||||
|> reduce({List, :to_string, []})
|
||||
# ... finally bag it and tag it
|
||||
|> unwrap_and_tag(:text)
|
||||
|
||||
identifier =
|
||||
utf8_string([?a..?z, ?A..?Z, ?_, ?0..?9], min: 1)
|
||||
|> reduce({Enum, :join, []})
|
||||
|> unwrap_and_tag(:identifier)
|
||||
|
||||
defparsecp(:expression, identifier)
|
||||
|
||||
# when spotting interpolation, ignore the opening tag and any whitespace
|
||||
interpolation =
|
||||
ignore(concat(opening_tag, optional_whitespaces))
|
||||
# ... then parse the expression (identifier)
|
||||
|> parsec(:expression)
|
||||
# ... then ignore any whitespace and the closing tags after the expression
|
||||
|> ignore(concat(optional_whitespaces, closing_tag))
|
||||
# ... once again we bag it and tag it
|
||||
|> unwrap_and_tag(:interpolation)
|
||||
|
||||
defparsec(:do_parse, choice([interpolation, text]) |> repeat() |> eos())
|
||||
end
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user