From b42d9db4325fa1259ddcb23db151f122bfe4cd4b Mon Sep 17 00:00:00 2001
From: fr33domlover <fr33domlover@rel4tion.org>
Date: Wed, 13 Apr 2016 06:55:39 +0000
Subject: [PATCH] Split source file rendering into separate module

---
 src/Vervis/Handler/Repo.hs   | 25 ++---------------
 src/Vervis/Render.hs         | 54 ++++++++++++++++++++++++++++++++++++
 templates/repo/source.hamlet |  7 ++---
 vervis.cabal                 |  2 ++
 4 files changed, 61 insertions(+), 27 deletions(-)
 create mode 100644 src/Vervis/Render.hs

diff --git a/src/Vervis/Handler/Repo.hs b/src/Vervis/Handler/Repo.hs
index 975b301..95c0505 100644
--- a/src/Vervis/Handler/Repo.hs
+++ b/src/Vervis/Handler/Repo.hs
@@ -58,8 +58,6 @@ import Database.Esqueleto
 import Data.Hourglass (timeConvert)
 import System.Directory (createDirectoryIfMissing)
 import System.Hourglass (dateCurrent)
-import Text.Highlighter (lexerFromFilename, runLexer, Lexer (lName))
-import Text.Highlighter.Formatters.Html (format)
 
 import qualified Data.DList as D
 import qualified Data.Set as S (member)
@@ -71,6 +69,7 @@ import Vervis.Foundation
 import Vervis.Git (timeAgo')
 import Vervis.Path
 import Vervis.Model
+import Vervis.Render
 import Vervis.Settings
 import Vervis.Style
 
@@ -169,26 +168,8 @@ getRepoSource repository user repo ref dir = do
                     , toText $ toBytes name
                     )
             display <- case view of
-                    Left b ->
-                        let lbs = blobGetContent b
-                            bs = toStrict lbs
-                        in  Left <$>
-                            case lexerFromFilename $ unpack $ last dir of
-                                Nothing    -> return $ Left $ toTextL lbs
-                                Just lexer ->
-                                    case runLexer lexer bs of
-                                        Left err -> do
-                                            $logWarn $ mconcat
-                                                [ "Failed to highlight "
-                                                , ref
-                                                , " :: "
-                                                , intercalate "/" dir
-                                                , " with lexer "
-                                                , pack $ lName lexer
-                                                ]
-                                            return $ Left $ toTextL lbs
-                                        Right tokens ->
-                                            return $ Right $ format True tokens
+                    Left b -> return $ Left $
+                        renderSource (unpack $ last dir) (blobGetContent b)
                     Right v -> return $ Right $ map mkrow v
             let parent = if null dir then [] else init dir
                 dirs = zip parent (tail $ inits parent)
diff --git a/src/Vervis/Render.hs b/src/Vervis/Render.hs
new file mode 100644
index 0000000..9127324
--- /dev/null
+++ b/src/Vervis/Render.hs
@@ -0,0 +1,54 @@
+{- This file is part of Vervis.
+ -
+ - Written in 2016 by fr33domlover <fr33domlover@riseup.net>.
+ -
+ - ♡ Copying is an act of love. Please copy, reuse and share.
+ -
+ - The author(s) have dedicated all copyright and related and neighboring
+ - rights to this software to the public domain worldwide. This software is
+ - distributed without any warranty.
+ -
+ - You should have received a copy of the CC0 Public Domain Dedication along
+ - with this software. If not, see
+ - <http://creativecommons.org/publicdomain/zero/1.0/>.
+ -}
+
+-- | Tools for rendering repository file contents and other source files.
+module Vervis.Render
+    ( renderSource
+    )
+where
+
+import Prelude
+
+import Control.Monad.Logger (logWarn)
+import Data.ByteString.Lazy (ByteString, toStrict)
+import Data.Text (pack)
+import Data.Text.Encoding.Error (lenientDecode)
+import Data.Text.Lazy.Encoding (decodeUtf8With)
+import Text.Highlighter (lexerFromFilename, runLexer, Lexer (lName))
+import Text.Highlighter.Formatters.Html (format)
+import Yesod.Core.Widget (whamlet, toWidget)
+
+import Vervis.Foundation (Widget)
+
+renderSource :: FilePath -> ByteString -> Widget
+renderSource name content =
+    let raw =
+            [whamlet|
+              <pre>
+                <code>#{decodeUtf8With lenientDecode content}
+            |]
+    in  case lexerFromFilename name of
+            Nothing    -> raw
+            Just lexer ->
+                case runLexer lexer $ toStrict content of
+                    Left err -> do
+                        $logWarn $ mconcat
+                            [ "Failed to highlight "
+                            , pack name
+                            , " with lexer "
+                            , pack $ lName lexer
+                            ]
+                        raw
+                    Right tokens -> toWidget $ format True tokens
diff --git a/templates/repo/source.hamlet b/templates/repo/source.hamlet
index 409ecb1..0916410 100644
--- a/templates/repo/source.hamlet
+++ b/templates/repo/source.hamlet
@@ -39,11 +39,8 @@ $forall (piece, piecePath) <- dirs
   <span>/
 <h2>#{title}
 $case display
-  $of Left (Left plain)
-    <pre>
-      <code>#{plain}
-  $of Left (Right highlighted)
-    #{highlighted}
+  $of Left source
+    ^{source}
   $of Right rows
     <table>
       <tr>
diff --git a/vervis.cabal b/vervis.cabal
index d062155..7cd528a 100644
--- a/vervis.cabal
+++ b/vervis.cabal
@@ -53,6 +53,8 @@ library
                        Vervis.Import
                        Vervis.Import.NoFoundation
                        Vervis.Model
+                       Vervis.Readme
+                       Vervis.Render
                        Vervis.Settings
                        Vervis.Settings.StaticFiles
                        Vervis.Handler.Common