yesod-markdown (empty) → 0.0
raw patch · 5 files changed
+236/−0 lines, 5 filesdep +basedep +bytestringdep +containerssetup-changed
Dependencies added: base, bytestring, containers, pandoc, utf8-string, xss-sanitize, yesod
Files
- LICENSE +30/−0
- Setup.hs +2/−0
- Yesod/Markdown.hs +99/−0
- Yesod/Markdown/Macros.hs +64/−0
- yesod-markdown.cabal +41/−0
+ LICENSE view
@@ -0,0 +1,30 @@+Copyright (c) 2010, Alexander Dunlap.++All rights reserved.++Redistribution and use in source and binary forms, with or without+modification, are permitted provided that the following conditions are met:++ * Redistributions of source code must retain the above copyright+ notice, this list of conditions and the following disclaimer.++ * Redistributions in binary form must reproduce the above+ copyright notice, this list of conditions and the following+ disclaimer in the documentation and/or other materials provided+ with the distribution.++ * Neither the name of Alexander Dunlap nor the names of other+ contributors may be used to endorse or promote products derived+ from this software without specific prior written permission.++THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ Setup.hs view
@@ -0,0 +1,2 @@+import Distribution.Simple+main = defaultMain
+ Yesod/Markdown.hs view
@@ -0,0 +1,99 @@+{-# LANGUAGE GeneralizedNewtypeDeriving, CPP, QuasiQuotes, TypeFamilies, FlexibleInstances,+ MultiParamTypeClasses #-}+-- | This module provides functions for using Markdown with Yesod. An example pipeline could be+--+-- > (writePandoc defaultWriterOptions <$>) . localLinks . parseMarkdown defaultParserState+module Yesod.Markdown+ ( Markdown (..)+ , parseMarkdown+ , localLinks+ , writePandoc+ , writePandocTrusted+ -- * Option sets+ , yesodDefaultWriterOptions+ , yesodDefaultParserState+ , yesodDefaultParserStateTrusted+ )+ where++import Yesod+import Data.Monoid+import Data.String+import Yesod.Form.Core+import Text.Pandoc+import Text.Pandoc.Shared+import Text.HTML.SanitizeXSS+import Control.Applicative+import Data.Map ( Map )+import qualified Data.Map as Map+import qualified Data.ByteString.Char8 as B++newtype Markdown = Markdown String+ deriving (Eq, Ord, Show, Read, PersistField, IsString, Monoid)++instance ToFormField Markdown y where+ toFormField = markdownField++instance ToFormField (Maybe Markdown) y where+ toFormField = maybeMarkdownField++markdownField :: (IsForm f, FormType f ~ Markdown)+ => FormFieldSettings -> Maybe Markdown -> f+markdownField = requiredFieldHelper markdownFieldProfile++maybeMarkdownField :: FormFieldSettings -> FormletField sub y (Maybe Markdown)+maybeMarkdownField = optionalFieldHelper markdownFieldProfile++markdownFieldProfile :: FieldProfile sub y Markdown+markdownFieldProfile = FieldProfile+ { fpParse = Right . Markdown+ , fpRender = \(Markdown m) -> m+ , fpWidget = \theId name val _isReq -> addHamlet+#if GHC7+ [hamlet|+#else+ [$hamlet|+#endif+%textarea.markdown#$theId$!name=$name$ $val$+|]+ }++-- | Write untrusted 'Pandoc' to 'Html'. Calls 'sanitizeBalance' from xss-sanitize.+writePandoc :: WriterOptions -> Pandoc -> Html+writePandoc wo = preEscapedString . sanitizeBalance . writeHtmlString wo++-- | Write trusted 'Pandoc' to 'Html'. Does not sanitize or balance tags.+writePandocTrusted :: WriterOptions -> Pandoc -> Html+writePandocTrusted wo = preEscapedString . writeHtmlString wo++-- | Read in 'Markdown' to an intermediate 'Pandoc' type.+parseMarkdown :: ParserState -> Markdown -> Pandoc+parseMarkdown ro (Markdown m) = readMarkdown ro m++-- | Convert local (in-site) links. This function works on all link URLs that start with the two-character+-- prefix @~:@. It normalizes the links and replaces the @~:@ with the @approot@ value for the site.+localLinks :: Yesod master => Pandoc -> GHandler sub master Pandoc+localLinks p = (\y -> processWith (links y) p) <$> getYesod where+ links y (Link x ('~':':':l,n)) = Link x (joinPath y (approot y) (links' y (B.pack l)) [],n)+ links _ x = x+ links' y l = case splitPath y l of+ Left corrected -> links' y corrected+ Right xs -> xs++-- | A set of default Pandoc writer options good for Yesod websites. Enables Javascript-based email obfuscation,+-- eliminates div tags around sections, and disables text wrapping.+yesodDefaultWriterOptions :: WriterOptions+yesodDefaultWriterOptions = defaultWriterOptions+ { writerEmailObfuscation = JavascriptObfuscation+ , writerSectionDivs = False+ , writerWrapText = False+ }++-- | A set of default Pandoc reader options good for Yesod websites /where the data input is trusted/. Enables raw+-- HTML.+yesodDefaultParserStateTrusted :: ParserState+yesodDefaultParserStateTrusted = yesodDefaultParserState { stateParseRaw = True }++-- | A set of default Pandoc reader options good for Yesod websites. Enables smart parsing.+yesodDefaultParserState :: ParserState+yesodDefaultParserState = defaultParserState { stateSmart = True }
+ Yesod/Markdown/Macros.hs view
@@ -0,0 +1,64 @@+{-# LANGUAGE ViewPatterns #-}+-- | Macros allow users to access more advanced functionality from within Markdown syntax. There are two types+-- of macros, block and inline, which allow substitution of 'Block' and 'Inline' data, respectively. Macros+-- are called in a very similar fashion to shell programs: the argument string is split on whitespace. The+-- first word is the name of the macro, and the remaining words are the arguments. Option-parsing libraries+-- may be useful for interpreting the arguments.+--+-- Note: using 'blockMacros' and 'inlineMacros' at the same time with the same magic string and can lead to behavior+-- that depends on the order in which they are called, if any of the macro names are the same for block and inline+-- macros. However, if none of the macro names are the same, unrecognized macro names will be ignored by the pass+-- that doesn't recognize them, leaving them available to be recognized by the other pass.++module Yesod.Markdown.Macros+ where++import Text.Pandoc+import Yesod+import Control.Applicative+import Data.Map ( Map )+import qualified Data.Map as Map+import qualified Data.ByteString.Lazy.UTF8 as U++-- | Convert block-level macros. Block-level macros are signalled by a first-level header containing a piece of+-- inline code starting with a client-specified magic string. For example, if the magic string is @??@, a macro+-- can be called by+--+-- > #`??MACRO_NAME MACRO_ARGS`+--+-- where @MACRO_NAME@ is the identifying name of the macro and @MACRO_ARGS@ is a space-separated list of arguments.+blockMacros+ :: Yesod master+ => String -- ^ Magic string to introduce the macro+ -> Map String ([String] -> GHandler sub master Block) -- ^ Lookup table from macro names to macro functions+ -> Pandoc+ -> GHandler sub master Pandoc+blockMacros magic table p = processWithM blockMacros' p where+ blockMacros' (Header 1 [Code (splitAt (length magic) -> (magic',words -> ((flip Map.lookup table -> Just f):xs)))])+ | magic == magic' = f xs+ blockMacros' b = return b++-- | Convert block-level macros. Inline-level macros are signalled by a piece of inline code starting with a+-- client-specified magic string. For example, if the magic string is @??@, a macro can be called by+--+-- > `??MACRO_NAME MACRO_ARGS`+--+-- where @MACRO_NAME@ is the identifying name of the macro and @MACRO_ARGS@ is a space-separated list of arguments.+inlineMacros+ :: Yesod master+ => String -- ^ Magic string to introduce the macro+ -> Map String ([String] -> GHandler sub master Inline) -- ^ Lookup table from macro names to macro functions+ -> Pandoc+ -> GHandler sub master Pandoc+inlineMacros magic table p = processWithM inlineMacros' p where+ inlineMacros' (Code (splitAt (length magic) -> (magic',words -> ((flip Map.lookup table -> Just f):xs))))+ | magic == magic' = f xs+ inlineMacros' b = return b++-- | Convert a 'Hamlet' value to a 'Block'.+hamletToBlock :: Hamlet (Route master) -> GHandler sub master Block+hamletToBlock x = RawHtml . U.toString . renderHtml . x <$> getUrlRenderParams++-- | Convert a 'Hamlet' value to an 'Inline'.+hamletToInline :: Hamlet (Route master) -> GHandler sub master Inline+hamletToInline x = HtmlInline . U.toString . renderHtml . x <$> getUrlRenderParams
+ yesod-markdown.cabal view
@@ -0,0 +1,41 @@+-- yesod-markdown.cabal auto-generated by cabal init. For additional+-- options, see+-- http://www.haskell.org/cabal/release/cabal-latest/doc/users-guide/authors.html#pkg-descr.+Name: yesod-markdown+Version: 0.0+Synopsis: Markdown processing for Yesod sites using Pandoc+Description: Process Markdown in Yesod sites.+License: BSD3+License-file: LICENSE+Author: Alexander Dunlap+Maintainer: alexander.dunlap@gmail.com+Copyright: (c) 2010 Alexander Dunlap+Category: Web, Yesod+Build-type: Simple+Stability: Alpha+-- Extra files to be distributed with the package, such as examples or+-- a README.+-- Extra-source-files: ++-- Constraint on the version of Cabal needed to build this package.+Cabal-version: >=1.6++flag ghc7++Library+ if flag(ghc7)+ build-depends: base >= 4.3 && < 5+ cpp-options: -DGHC7+ else+ build-depends: base >= 4 && < 4.3+ Exposed-modules: Yesod.Markdown, Yesod.Markdown.Macros+ Build-depends: yesod+ , pandoc+ , containers+ , xss-sanitize+ , bytestring+ , utf8-string++source-repository head+ type: git+ location: git://github.com/ajdunlap/yesod-markdown.git