úÎ!ù>íË      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~€‚ƒ„…†‡ˆ‰Š‹Œ‘’“”•–—˜™š›œŸ ¡¢£¤¥¦§¨©ª« ¬ ­ ® ¯ ° ± ² ³ ´ µ ¶ · ¸ ¹ º » ¼ ½ ¾ ¿ À Á Â Ã Ä Å Æ Ç È É Ê Safe]›pencilPencil's tokens for content. pencil Pencil's Page AST.pencilConvert Tokens to PNode AST.,transform [TokText "hello", TokText "world"][PText "hello",PText "world"]!transform [TokIf "title", TokEnd][PIf "title" []]Ctransform [TokIf "title", TokText "hello", TokText "world", TokEnd]+[PIf "title" [PText "hello",PText "world"]] 6${if(title)} ${for(posts)} world ${end} ${end}Jtransform [TokIf "title", TokFor "posts", TokText "world", TokEnd, TokEnd],[PIf "title" [PFor "posts" [PText "world"]]] Šbegin now ${if(title)} hello world ${if(body)} ${body} ${someothervar} wahh ${end} final thing ${end} the lastlineôtransform [TokText "begin", TokText "now", TokIf "title", TokText "hello", TokText "world", TokIf "body", TokVar "body", TokVar "someothervar", TokText "wahh", TokEnd, TokText "final", TokText "thing", TokEnd, TokText "the", TokText "lastline"]¸[PText "begin",PText "now",PIf "title" [PText "hello",PText "world",PIf "body" [PVar "body",PVar "someothervar",PText "wahh"],PText "final",PText "thing"],PText "the",PText "lastline"] ><!--PREAMBLE foo: bar do: - re - me --> Hello world ${foo}\transform [TokPreamble "foo: bar\ndo:\n - re\n -me", TokText "Hello world ", TokVar "foo"]J[PPreamble "foo: bar\ndo:\n - re\n -me",PText "Hello world ",PVar "foo"]pencil‰Converts Tokens, which is just the raw list of parsed tokens, into PNodes which are the tree-structure expressions (i.e. if/for nesting)ÿÌThis function works by using a stack to keep track of where we are for nested expressions such as if and for statements. When a token that starts a nesting is found (like a TokIf), a "meta" expression (PMetaIf) is pushed into the stack. When we finally see an end token (TokEnd), we pop all the expressions off the stack until the first meta tag (e.g PMetaIf) is reached. All the expressions popped off are now known to be nested inside that if statement.penciljPop nodes until we hit a If/For statement. Return pair (constructor found, nodes popped, remaining stack)pencil Helper for .pencilRender nodes as string.pencilRender node as string.pencilRender tokens.pencil Render token.pencil Parse text.pencilParse everything.5parse parseEverything "" "Hello ${man} and ${woman}."PRight [TokText "Hello ",TokVar "man",TokText " and ",TokVar "woman",TokText "."]Jparse parseEverything "" "Hello ${man} and ${if(woman)} text here ${end}."lRight [TokText "Hello ",TokVar "man",TokText " and ",TokIf "woman",TokText " text here ",TokEnd,TokText "."]Fparse parseEverything "" "Hi ${for(people)} ${name}, ${end} everyone!"hRight [TokText "Hi ",TokFor "people",TokText " ",TokVar "name",TokText ", ",TokEnd,TokText " everyone!"]yparse parseEverything "" "${realvar} $.get(javascript) $$ $$$ $} $( $45.50 $$escape $${escape2} wonderful life! ${truth}"“Right [TokVar "realvar",TokText " $.get(javascript) $$ $$$ $} $( $45.50 $$escape ",TokText "${",TokText "escape2} wonderful life! ",TokVar "truth"]dparse parseEverything "" "<!--PREAMBLE \n foo: bar\ndo:\n - re\n -me\n -->waffle house ${lyfe}"bRight [TokPreamble " \n foo: bar\ndo:\n - re\n -me\n ",TokText "waffle house ",TokVar "lyfe"]qparse parseEverything "" "YO ${foo} <!--PREAMBLE \n ${foo}: bar\ndo:\n - re\n -me\n -->waffle house ${lyfe}"ŒRight [TokText "YO ",TokVar "foo",TokText " ",TokPreamble " \n ${foo}: bar\ndo:\n - re\n -me\n ",TokText "waffle house ",TokVar "lyfe"]kThis is a degenerate case that we will just allow (for now) to go sideways: >>> parse parseEverything "" " bthis ${var never closes /b ${realvar}" Right [TokText " bthis ",TokVar "var never closes /b ${realvar"]pencilParse variables.pencilParse preamble. pencilParse the start of a PREAMBLE.!pencilParse partial commands.9parse parsePartial "" "${partial(\"my/file/name.html\")}"&Right (TokPartial "my/file/name.html")"pencilParse escape sequence "$${""parse parseEscape "" "$${example}"Right (TokText "${")#pencilParse boring, boring text.*parse parseContent "" "hello ${ffwe} you!"Right (TokText "hello ")2parse parseContent "" "hello $.get() $ $( $$ you!",Right (TokText "hello $.get() $ $( $$ you!")ÜBecause of our first parser to grab a character that is not a $, we can't grab strings that start with a $, even if it's text. It's a bug, just deal with it for now. >>> isLeft $ parse parseContent "" "$$$ what" True*isLeft $ parse parseContent "" "${name}!!"True$pencilParse for loop declaration.!parse parseFor "" "${for(posts)}"Right (TokFor "posts")Iparse parseFor "" "${for(variable name with spaces technically allowed)}">Right (TokFor "variable name with spaces technically allowed")%isLeft $ parse parseFor "" "${for()}"True'isLeft $ parse parseFor "" "${for foo}"True%pencilParse if directive.&pencil!General parse template functions.'pencilParse end keyword.parse parseEnd "" "${end}" Right TokEnd%isLeft $ parse parseEnd "" "${enddd}"True(pencilZA hack to capture strings that "almost" are templates. I couldn't figure out another way.)pencilmany1Till p end will parse one or more p until @end.From Qhttps://hackage.haskell.org/package/pandoc-1.10.0.4/docs/Text-Pandoc-Parsing.html*pencil)Find the preamble content from the given PNodes.+pencilReturns True if the PNode is a  PPreamble.,pencilGets the content of the  PPreamble.+   !"#$%&'()*+,+    !"#$%&'()*+,None}“ 1pencil Environment map of variables to 2s.2pencil2Represents the data types found in an environment.This includes at least     types, plus other useful ones.:pencilConverts an Aeson   to a Pencil 2.;pencil]Accepted format is ISO 8601 (YYYY-MM-DD), optionally with an appended "THH:MM:SS". Examples: 2010-01-302010-01-30T09:08:00<pencil Helper for Ë= using ISO 8601. YYYY-MM-DDTHH:MM:SS and YYYY-MM-DD formats. [https://hackage.haskell.org/package/time-1.9/docs/Data-Time-Format.html#v:iso8601DateFormat=pencil&Gets the nodes from the env, from the  this.nodes; variable. Returns empty list if this variable is missing.>pencilUFind preamble node, and load as an Env. If no preamble is found, return a blank Env.?pencil#Converts an Aeson Object to an Env.@pencilConvert known Aeson   into a Pencil 2X, and insert into the env. If there is no conversion possible, the env is not modified.Apencil1Gets the rendered content from the env, from the  this.contentR variable. Returns empty is the variable is missing (e.g. has not been rendered).BpencilIRenders environment value for human consumption. This is the default one.Cpencil A version of B that renders 2 acceptable for an RSS feed.)Dates are rendered in the RFC 822 format. Everything else defaults to the B implementation.!You'll probably want to also use  to render an RSS feed.DpencilRFC 822 date format.Helps to pass  'https://validator.w3.org/feed/check.cgi.Same as  Vhttps://hackage.haskell.org/package/time/docs/Data-Time-Format.html#v:rfc822DateFormata but no padding for the day section, so that single-digit days only has one space preceeding it.ZAlso changed to spit out the offset timezone (+0000) because the default was spitting out UTCh which is not valid RFC 822. Weird, since the defaultTimeLocal source and docs show that it won't use UTC: Whttps://hackage.haskell.org/package/time/docs/Data-Time-Format.html#v:defaultTimeLocale129876543:;<=>?@ABCD298765431:;<=>?@ABCDNone7÷KGpencil9Class for types that has a final file path for rendering.<This allows file-path-changing methods to be re-used across [, V and P types.Jpencil?Enum for file types that can be parsed and converted by Pencil.PpencilResource is used to copy static binary files to the destination, and to load and render files that just needs conversion without template directives or structures.‚This is how Pencil handles files like images, compiled JavaScript, or text files that require only a straight-forward conversion.Use  ,   and   to build a Resource from a file.In the example below,  robots.txt and everything in the images/# directory will be rendered as-is. Epassthrough "robots.txt" >>= render passthrough "images/" >>= render Rpencil+in and out file paths (can be dir or files)Spencil·An inner element in the Structure. Either a singular Page, or a collection of Pages. The Text element is the variable name that the inner page's content is injected as. Defaults to "body".VpencilA  Structure is a list of [1s, defining a nesting order. Think of them like  -https://en.wikipedia.org/wiki/Matryoshka_dollRussian nesting dollsT. The first element defines the outer-most container, and subsequent elements are inside the previous element.You commonly use  Structure|s to insert a page containing content (e.g. a blog post) into a container (e.g. a layout shared across all your web pages).Build structures using  ,   and  . layout <- load "layout.html" index <- load "index.markdown" about <- load "about.markdown" render (layout <|| index) render (layout <|| about) YIn the example above we load a layout page, which defines the outer HTML structure like  <html></html>D. We then "push" the index page and the about page into the layout.When we   layout <|| indexd, the contents of the index (and about) page is injected into the layout page through the variable ${body}. So  layout.html must use ${body} somewhere in its own body.úStructures also control the closure of variables. Variables defined in a page are accessible both by pages above and below. This allows inner pages to define variables like the blog post title, which may be used in the outer page to, say, set the <title> tag.OIn this way, structures allows efficient page reuse. See the private function 2 to learn more about how structures are evaluated.The Default File Path Rule$. When a structure is rendered, the lastr non-collection page in the structure is used as the destination file path. You can select a different page via c.The  :https://elbenshira.com/pencil/guides/pages-and-structures/Pages and Structures, guide also describes structures in detail.%Note that structures differ from the ${partial(...)}ø directive, which has no such variable closures. The partial directive is much simpler think of them as copy-and-pasting snippets from one file to another. A partial has the same environment as the context in which the partial directive appears.Zpencil…True if the file path should no longer be changed. This happens when a page with `useFilePath = True` was pushed into the structure.[pencilThe Page% is an important data type in Pencil.9Source files like Markdown and HTML are loaded (e.g. via  ) as a Page@. A page contains the contents of the file, their un-evaluated  /https://elbenshira.com/pencil/guides/templates/template directives (e.g. ${body}I), the variables defined in the preamble, and the destination file path. The contents may be in its converted form.  - will convert Markdown to HTML, for example. Pages can be combined together into a V), or inserted into the environment (see  Q). But at the end of the day, even a structure is converted back into a page on  m. This is because it is the page that is finally rendered into an actual web page when you run your program.^pencil The rendered output path of this page. Defaults to the input file path. This file path is used to generate the self URL that is injected into the environment._pencilNWhether or not this Page's URL should be used as the final URL in the render.`pencil=Whether or not XML/HTML tags should be escaped when rendered.apencilGets the Env of a [.bpencilSets the Env of a [.cpencil Sets this [ as the designated final Ì.'This is useful when you are building a V+ but don't want the file path of the last [= in the structure to be the destination file path on render.The  :https://elbenshira.com/pencil/guides/pages-and-structures/Pages and Structures! guide describes this in detail. ·a <- load "a.html" b <- load "b.html" c <- load "c.html" -- Rendered file path is "c.html" render $ a <|| b <| c -- Rendered file path is "b.html" render $ a <|| useFilePath b <| c dpencil Sets this [& to render with escaped XML/HTML tags.CThis is useful when you are building an RSS feed, and you need the contents+ of each item in the feed to HTML-escaped. Srss <- load "rss.xml" item1 <- load "item1.html" render $ rss <|| escapeXml item1 epencilA Í of file extensions (e.g. markdown) to J.K:  html, htmL:  markdown, mdM: cssN:  sass, scssfpencil Mapping of J/ to the final converted format. Only contains Js that Pencil will convert.L: htmlN: cssgpencil Converts a J[ into its converted webpage extension, if Pencil would convert it (e.g. Markdown to HTML).toExtension Markdown Just "html"hpencil"Takes a file path and returns the J, defaulting to O$ if it's not a supported extension.ipencil<Returns True if the file path is a directory. Examples: foobar Examples of not directories: foo, foobar, foo/bar.bazjpencil(Replaces the file path's extension with .html. rename toHtml <$>   "about.htm" kpencilConverts a file path into a directory name, dropping the extension. Pages with a directory as its file path is rendered as an index file in that directory. For example, pages/about.html is transformed into  pages/about/, which upon  & results in the destination file path pages/about/index.html: toDir "pages/about.html" Load and render as  pages/about/:  render $ n toDir <$>   "pages/about.html" lpencil(Replaces the file path's extension with .css. rename toCss <$>   "style.sass" mpencil<Converts file path into the expected extensions. This means  .markdown become .html, .sass becomes .css, and so forth. See f for conversion table.npencilTransforms the file path. 2about <- load "about.htm" render $ struct (rename j about) opencilsSets the target file path to the specified file path. If the given file path is a directory, the file name set to  index.html=. If the file path is a file name, then the file is renamed.Move stuff/about.html to about/blah.html on render: 8about <- to "about/blah.html" <$> load "stuff/about.htm"%Convert the destination file path to about/index.html: <about <- to "about/" <$> load "stuff/about.htm" render about Equivalent to the above example: :about <- load "stuff/about.htm" render $ to "about/" aboutppencilTMoves the target file path to the specified file path. Behaves similar to the UNIX mvŒ command: if the given file path is a directory, the file name is kept the same. If the file path is a file name, then the file is renamed.Move assets/style.css to stylesheets/style.css: /move "stylesheets/" <$> load "assets/style.css"Move assets/style.css to stylesheets/base.css. 7move "stylesheets/base.css" <$> load "assets/style.css"qpencilInternal implemenation for p and o.£Moves the target file path to the specified FilePath. If the given FilePath is a directory, the file name is kept the same. If the FilePath is a file name, then  fromFileName is used as the file name.rpencilÎ instance of FileType.+GHIJMNLKOPRQSUTVWZYX[\`_^]abcdefghijklmnopq+[\`_^]abcdVWZYXSUTPRQJMNLKOefghijklmnopqGHINonefzpencil The main Config* needed to build your website. Your app's Config is passed into the   monad transformer.Use ƒJ as a starting point, along with the config-modification helpers such as ….ƒpencil This default Config( gives you everything you need to start.Default values:  Config { | = "site/" , } = "out/" , ~ = HashMap.empty ,  = B , €+ = Text.Sass.Options.defaultSassOptions , : = Text.Pandoc.def { Text.Pandoc.readerExtensions = Ï Ğ ( "markdown") } , ‚| = Text.Pandoc.def { Text.Pandoc.writerHighlightStyle = Just Text.Pandoc.Highlighting.monochrome } , 'configDisplayValue = B } Ext_tex_math_dollars³ is disabled because it messes with parsing template variable directives. If you want TeX math, the better option is drop in a JavaScript library like KaTeX (https://katex.org).„pencil8Gets the source directory of your web page source files.…pencil8Sets the source directory of your web page source files.†pencil5Gets the output directory of your rendered web pages.‡pencil5Sets the output directory of your rendered web pages.ˆpencilGets environment of the Config, which is what the  PencilApp] monad transformer uses. This is where variables are set for rendering template directives.‰pencil;Sets the current environment. You may also want to look at   if you want to  " things in a modified environment.ŠpencilUpdates the Env inside the z.‹pencil Gets the Ñ for rendering Sass/Scss files.Œpencil Sets the Ñ for rendering Sass/Scss files.pencil Gets the  7 for reading files that use Pandoc. Supported formats:Markdown6Open a GitHub issue if you'd like to see more options!pencil Sets the  C. For example, you may want to enable some Pandoc extensions like Ò: ,setPandocReaderOptions (Text.Pandoc.def { !"9 = extensionsFromList [Ext_literate_haskell] }) config pencil Gets the #% for rendering files that use Pandoc.pencil Sets the #.‘pencilGets the function that renders 2 to text.’pencilSets the function that renders 2Y to text. Overwrite this with your own function if you would like to change how certain 2s are rendered (e.g. 6). 6myRender :: Value -> T.Text myRender (VDateTime dt) = Ó $ $% $& "%e %B %Y" dt myRender t = B) t ... setDisplayValue myRender config $In the above example, we change the  VDateTime rendering to show 25 December 2017". Leave everything else unchanged.z{|}~€‚ƒ„…†‡ˆ‰Š‹Œ‘’z{|}~€‚ƒ„…†‡ˆ‰Š‘’‹ŒNone2T ”pencilPKnown Pencil errors that we know how to either recover from or quit gracefully.•pencil%Failed to read a file as a text file.–pencilDFile not found. We may or may not know the file we were looking for.—pencilKThe collection in the structure was not the last element in the structure.˜pencil†A collection cannot be the first element in the structure (it's useless there, as nothing can reference the pages in the collection).™pencil=The primary monad transformer stack for a Pencil application.This unrolls to: 5PencilApp a = Config -> IO (Except PencilException a)The ExceptTª monad allows us to catch "checked" exceptions; errors that we know how to handle, in PencilException. Note that Unknown "unchecked" exceptions can still go through IO.špencil Converts the IOError to a known ”.How to test errors: Limport Control.Exception import qualified Data.Text.IO as TIO (e -> print ('( (e :: IOError)) >> return "") )* (TIO.readFile "foo") ›pencilmReturns true if the IOError is an invalid byte sequence error. This suggests that the file is a binary file.œpencil3Returns true if the IOError is due to missing file.pencilAPrint the list of Strings, one line at a time, prefixed with "-". ”˜—–•™š›œ ™”˜—–•š›œNoneAğŸpencilInserts Value into the given Env. pencil-Modifies a variable in the given environment.¡pencil Merges two Env)s together, biased towards the left-hand Env on duplicates.¢pencilInserts text into the given Env. ?env <- asks getEnv insertText "title" "My Awesome Website" env £pencil[Runs the computation with the given environment. This is useful when you want to render a + or , with a modified environment.  withEnv (¢ "newvar" "newval" env) (  page) Alternatively, use ,, which is re-exported in the Pencil module.¤pencilReturns true if the given Value is a VArray that contains the given text.¥pencilJDefines an ordering for possibly-missing Value. Nothings are ordered last.¦pencilSort by newest first.ŸpencilEnvironment variable name.pencilValue to insert.pencilEnvironment to modify. pencilEnvironment variable name.¢pencilEnvironment variable name.pencilText to insert.pencilEnvironment to modify.23456789BCŸ ¡¢£¤¥¦23456789£Ÿ¢ ¡BC¤¦¥NoneJ§pencilTEvaluate the nodes in the given environment. Note that it returns an IO because of ${partial(..)}' calls that requires us to load a file.¨pencil/Loads and parses the given file path. Converts L files to HTML, compiles N2 files into CSS, and leaves everything else alone.©pencil|Loads the given file as a text file. Throws an exception into the ExceptT monad transformer if the file is not a text file.ªpencil2Converts Markdown to HTML using the given options.§¨©ª§¨©ª None=>?ÈZ«pencil‹To render something is to create the output web pages, evaluating template directives into their final form using the current environment.¬pencilRenders a as web page(s).­pencil^Lists files in given directory. The file paths returned is prefixed with the given directory.Ôpencil­ helper.Õpencil5Applies the environment variables on the given pages.The Vy is expected to be ordered by inner-most content first (such that the final, HTML structure layout is last in the list).vThe returned Page contains the fully-applied environment and the nodes of the fully rendered page in this.nodes. The  `this.url`> variable is set to the Page in the Structure that specified cY; if no Page specified this, then it defaults to the URL of the first (inner-most) Page.ÿ Variable application. The outer environment's variables are applied down into the inner environments. Once it hits the lowest environment, that page is rendered (and has access to all variables defined in the parent). The page's rendered content is now set as the ${body}f variable in the environment. The parent page now gets rendered with this new environment, and so on.RAs an example, there is the common scenario where we have a default layout (e.g.  default.html=), with the full HTML structure, but no body. It has only a ${body}ÿ4 template variable inside. This is the parent layout. There is a child layout, the partial called "blog-post.html", which has HTML for rendering a blog post, like usage of ${postTitle} and ${postDate}. Inside this, there is another child layout, the blog post content itself, which defines the variables  postTitle and postDate-, and may renderer parent variables such as  websiteTitle. ÿ¤+--------------+ | | <--- default.html | | Defines websiteTitle | +---------+ | | | |<+----- blog-post.html | | +-----+ | | Renders ${postTitle}, ${postDate} | | | | | | | | | | | | | | | |<+-+----- blog-article-content.markdown | | | | | | Renders ${websiteTitle} | | +-----+ | | Defines postTitle, postDate | +---------+ | +--------------+ÿIn this case, we want to accumulate the environment variables, starting from default.html, to blog-post.html, and blog-article-content.markdown variables. Combine all of that, then render the blog post content. This content is then injected into the parent's environment as a ${body}+ variable, for use in blog-post.html. Now that4 content is injected into the parent environment's ${body}A variable, which is then used to render the full-blown HTML page.ÖpencilApply list of Pages and convert to Page.[It's simpler to implement if NonEmpty is ordered outer-structure first (e.g. HTML layout).×pencilŸApplies the Page by merging the given env with the Page's env, evaluating the nodes with the combined env, and generating a new env for the Page, containing this.url,  this.nodes and  this.content in the env.Øpencil+Render nodes. XML/HTML tags are escaped if escpXml is True.Ùpencil"Escape XML tags in the given Text.®pencil$Sorts pages by an ordering function.¯pencil7Filters pages by a variable's value in the environment.°pencilŠGiven a variable (whose value is assumed to be an array of VText) and list of pages, groups the pages by the VText found in the variable.zFor example, say each Page has a variable "tags" that is a list of tags. The first Page has a "tags" variable that is an VArray [VText "a"]8, and the second Page has a "tags" variable that is an VArray [VText "a", VText "b"]#. The final output would be a map 1fromList [("a", [page1, page2]), ("b", [page2])].Úpencil“Copy file from source to output dir. If both the input and output file paths are directories, recursively copy the contents from one to the other.±pencilLoads a file as a Pš. Use this for binary files (e.g. images) and for files without template directives that may still need conversion (e.g. Markdown to HTML, SASS to CSS).Generally, you can just use ¸ instead of this method.QLoads and renders the image as-is. Underneath the hood this is just a file copy: ,loadResource "images/profile.jpg" >>= renderLoads and renders to  about.html: (loadResource "about.markdown" >>= render²pencil!Loads file in given directory as Ps.Generally, you can just use ¸ instead of this method.Load everything inside the assets/B folder, renaming converted files as expected (e.g. SCSS to CSS): !loadResources True True "assets/"³pencilƒLoads file as a pass-through. There is no content conversion, and template directives are ignored. In essence this is a file copy. opassthrough "robots.txt" >>= render render (move "images/profile.jpg" <$> passthrough "images/myProfile.jpg") ´pencilìLoads a file as a page, rendering the file (as determined by the file extension) into the proper output format (e.g. Markdown rendered to HTML, SCSS to CSS). Parses the template directives and preamble variables into its environment. This loads index.markdown' with the destination file path set to  index.html: load "index.markdown"?Because this is already an HTML file, the file path is kept as  about.html: load "about.html"Using n and k$, the destination file path becomes pages/about/index.html: ¬ $ n k! <$> load "pages/about.markdown" µpencilLike ´!, loads a file as a page. Unlike ´f, the source file path is used as the destination file path (i.e. the extension name is not changed).¶pencil A version of ´ for directories. \layout <- load "layout.html" tutorials <- loadDir False "tutorials/" render $ fmap ((layout ¹) . n k ) tutorials ·pencilwA version of load' for directories. Loads the files in the specified directory as pages. Keeps the original file path. [tutorials <- loadDir' False "tutorials/" render $ fmap ((layout <||) . rename toDir) pages Ûpencil8Internal implemenation for loading directories to pgaes.¸pencilÿLoads and renders file, converting content if it's convertible (e.g. Markdown to HTML). The final file path is the "default conversion", if Pencil knows how to convert the file (e.g. .markdown to .html). Otherwise, the same file name is kept (e.g. .txt).Load  style.sass , convert to CSS, and render as  style.css: loadAndRender "style.sass"+Load, convert and render everything in the assets/G folder. Binary files are copied as-is without any further processing: loadAndRender "assets/"Üpencil4Returns True if the given Node is a collection node.İpencilGet the node's name.¹pencil;Creates a new structure from two pages. Pronounced "smash". Vlayout <- load "layout.html" index <- load "index.markdown" render (layout <|| index) ºpencilPushes Page into  Structure. Pronounced "push". •layout <- load "layout.html" blogLayout <- load "blog-layout.html" blogPost <- load "myblogpost.markdown" render (layout <|| blogLayout <| blogPost) »pencilPushes Node into the  Structure#. Usually used in conjunction with ¼. 3blogLayout <- load "blog-layout.html" blogPosts <-  -@ "posts/" render (struct blogLayout <<| coll "posts" blogPosts) ¼pencilCreates a collection S#. Usually used in conjunction with ».½pencil Converts a Page into a  Structure". This is a "singleton" structure.¾pencilYInserts pages into the environment. The pages are evaluated and applied before insertion.  posts <-  - "blog/" env <- asks ˆ' env' <- insertPages "posts" posts env ­pencil Recursive if True.ØpencilXML/HTML tags escaped if True.®pencilEnvironment variable name.pencilƒOrdering function to compare Value against. If the variable is not in the Env, the Page will be placed at the bottom of the order.¯pencil6If true, include pages without the specified variable.pencilEnvironment variable name.°pencilEnvironment variable name.²pencil Recursive if True.pencil'Handle as pass-throughs (file copy) if True.¶pencil0If True, recursively load files in the directory·pencilRecursive if trueÛpencilRecursive if true¾pencilEnvironment variable name.pencilPage s to insert.pencilEnvironment to modify.(GIHJPV[abcdghjklmnop«¬­®¯°±²³´µ¶·¸¹º»¼½¾([´µ¶·¸nopcdab¯®°¾V½¹º»¼P³±²«¬­mjlkJhgGIH NoneÌ`ÃpencilRun the Pencil app.+Note that this can throw a fatal exception.ŞpencilTGiven a file path, look at all file paths and find the one that seems most similar.™Ã™Ã NoneëÄpencil(Like, you know, a hashtag. Wraps a text.ÅpencilCLoads the given directory as a series of blog posts, sorted by the date, preamble environment variable. Posts with  draft: true are filtered out. posts <- loadPosts "blog/" Æpencil"Rewrites file path for blog posts. HpostUrl "/blog/2011-01-01-post-title.html" -- "/blog/1-post-title.html/"ÇpencilGiven that the current Page has a  postTitle5 in the environment, inject the post title into the title= environment variable, prefixed with the given title prefix."This is useful for generating the <title>${title}</title> tags in your container layout.(For example, if the page's preamble has  postTitle: "The Meaning of Life"(, then the snippet below will insert a title variable with the value +"The Meaning of Life - My Awesome Website": &injectTitle "My Awesome Website" post Èpencil Finds all the tags from the given pages, and generates a page for each tag found. Each tag page has a variable "posts" containing all pages that have the tag. Helper of É! defaulting to the variable name posts$, and the tag index page file path blog/tags/my-tag-name/.  tagPages <- buildTagPages pages ÉpencilBuild the tag index pages.Given blog post Pages with tags# variables in its PREAMBLE, builds Page/s that contain in its environment the list of PageYs that were tagged with that particular tag. Returns a map of tag of the tag index page. {tagPages <- buildTagPagesWith "tag-list.html" "posts" (\tag _ -> "blog/tags/" ++ ./! tag ++ "/") posts Êpencil*Injects the tag map (usually generated by È or É.) into the page's environment as the variable tags, which is an VEnvList.Çpencil Title prefixÉpencil'Partial to load for the Tag index pagespencil`Variable name inserted into Tag index pages for the list of Pages tagged with the specified tagpencil-Function to generate the URL of the tag pagesÄÅÆÇÈÉÊÅÆÇÄÈÉÊNoneë€^23456789BCGIHJPV[abcdghjklmnopz{|}~€‚ƒ„…†‡ˆ‰Š‹Œ‘’™Ÿ ¡¢£¤¥¦«¬­®¯°±²³´µ¶·¸¹º»¼½¾ÃÄÅÆÇÈÉÊß012013456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~€‚ƒ„„…,,†‡ˆ++‰Š‹Œ‘’“”•–—˜™š›œŸ ¡¢£¤¥¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏĞÑÒ Ó  Ô Õ Ö ×     Ø Ù Ú Û   Ü İ   Ş ß à á â ã - ä å æ ç èéêëì'íîïğñòóôõôö÷øùôúû.ü ı  ş ÿ       #pencil-1.0.0-9xnPWpo5eBiD165KWEZJT9Pencil Pencil.ParserPencil.Env.InternalPencil.Content.Internal Pencil.ConfigPencil.App.Internal Pencil.EnvPencil.Content.NodesPencil.Content Pencil.App Pencil.BlogDataAesonData.Aeson.TypesValue escapeXml passthrough loadResource loadResourcesstruct<||<|renderapplyload insertPages PencilAppText.Pandoc.ExtensionsgetDefaultExtensionswithEnv Text.Pandoc ReaderOptionsText.Pandoc.OptionsreaderExtensions WriterOptionsTF formatTimedefaultTimeLocaleGHC.IOioe_descriptionControl.ExceptionhandlePage Structure loadPosts Data.Textunpack mtl-2.2.2Control.Monad.Reader.ClassaskslocalTokenTokTextTokVarTokForTokIf TokPartial TokPreambleTokEndPNodePTextPVarPForPIfPPartial PPreamblePMetaIfPMetaForPMetaEnd transformastpopNodes popNodes_ renderNodes renderNode renderTokens renderToken parseTextparseEverythingparseVar parsePreambleparsePreambleStart parsePartial parseEscape parseContentparseForparseIf parseFunctionparseEnd parseFakeVar many1TillfindPreambleText isPreamble preambleText $fShowPNode $fEqPNode $fShowToken $fEqTokenEnvVNullVTextVBool VDateTimeVArrayVEnvListVNodestoValue toDateTime parseIso8601getNodesfindEnv aesonToEnvmaybeInsertIntoEnv getContenttoText toTextRssrfc822DateFormat $fEqValue $fShowValue HasFilePath getFilePath setFilePathFileTypeHtmlMarkdownCssSassOtherResourceSingle PassthroughNodeNodesstructureNodesstructureFilePathstructureFilePathFrozenpageEnv pageFilePathpageUseFilePath pageEscapeXml getPageEnv setPageEnv useFilePath fileTypeMap extensionMap toExtensionfileTypeisDirtoHtmltoDirtoCss toExpectedrenametomovemove'$fHashableFileType$fHasFilePathStructure$fHasFilePathResource$fHasFilePathPage$fEqPage $fShowPage $fEqFileType$fGenericFileTypeConfigconfigSourceDirconfigOutputDir configEnvconfigDisplayValueconfigSassOptionsconfigPandocReaderOptionsconfigPandocWriterOptions defaultConfig getSourceDir setSourceDir getOutputDir setOutputDirgetEnvsetEnv updateEnvgetSassOptionssetSassOptionsgetPandocReaderOptionssetPandocReaderOptionsgetPandocWriterOptionssetPandocWriterOptionsgetDisplayValuesetDisplayValue$fDefaultConfigPencilException NotTextFile FileNotFoundCollectionNotLastInStructureCollectionFirstInStructuretoPencilExceptionisInvalidByteSequence isNoSuchFile printAsList$fShowPencilExceptioninsertadjustmerge insertTextarrayContainsText maybeOrdering dateOrdering evalNodesparseAndConvertTextFiles loadTextFilereadMarkdownWriteHtmlRenderlistDir sortByVar filterByVargroupByElementsload'loadDirloadDir' loadAndRender<<|coll $fRender[] $fRenderPage$fRenderStructure$fRenderResourcerunTagpostUrl injectTitle buildTagPagesbuildTagPagesWith injectTags time-1.8.0.2Data.Time.Format.Parse parseTimeMbaseFilePath4unordered-containers-0.2.10.0-LgoTL3wbBEY5bZIDJiyxW4Data.HashMap.BaseHashMap'hashable-1.2.7.0-2SI038axTEd7AEZJ275kpiData.Hashable.ClassHashable"pandoc-2.7.2-9B2LzTQVlBI1df9j0MZiZdisableExtensionExt_tex_math_dollars!hsass-0.8.0-xM2jy3rknGFDeKlycjjzcText.Sass.Options SassOptionsExt_literate_haskell text-1.2.3.1packlistDir_apply_ applyPage nodesToText escapeForXmlcopyFile loadDirWithisCollnodeNamemostSimilarFiles