diff --git a/changes.txt b/changes.txt
--- a/changes.txt
+++ b/changes.txt
@@ -1,8 +1,18 @@
+0.1.2.0
+-------
+
+- Released Wed 24 Jun 2015 03:46:07 CEST
+- added ``-f compiler`` option to make output emacs parseable
+  (requested by Henning Thielemann).
+- fixed contiguous single-line/block-comment bug (reported by
+  Henning Thielemann).
+
 0.1.1.3
 -------
 
 - Released Mon 15 Jun 2015 23:29:49 CEST
-- fixmes and xxx issues now get a free [fixme]/[xxx] tag
+- fixmes and xxx issues now get a free [fixme]/[xxx] tag (requested
+  by qptain nemo).
 
 0.1.1.2
 -------
diff --git a/doc/usr/page.rst b/doc/usr/page.rst
--- a/doc/usr/page.rst
+++ b/doc/usr/page.rst
@@ -73,7 +73,7 @@
 
   lentil .
 
-This should output a basic list of issues.
+This should output a basic list of issues:
 
 ::
 
@@ -190,14 +190,18 @@
    <p><br/></p>
 
 
-Output options
+Format options
 --------------
 
-You can change the ``-f TYPE`` option to change the output format. You
-can choose the default format ``pretty``, export issues to CSV format
-using ``-f csv`` or pick ``tagpop``. Tagpop lists tags by their popularity
-(reverse order) and is useful to see a summary of the open issues:
+The ``-f TYPE`` option modifies the output format, with ``pretty`` being
+the default.
 
+``-f csv`` export issues to CSV (RFC 4180).
+
+
+``-f tagpop``, lists tags by their popularity (reverse order),
+useful to get a summary of open issues:
+
 ::
 
   lentil . -x test/test-files/ -f tagpop
@@ -212,9 +216,20 @@
        1  [urgency:3]
        1  [design]
 
+``-f comp`` displays issues in a format similar to the one emitted
+by compilers (GCC, GHC, etc.):
 
-``--output VERSION`` is used to output the report to a file instead of stdout.
+::
 
+  alpha.hs:4:
+     add prompt before getline, or the user might complain! [interface]
+
+  alpha.hs:11:
+     add a type signature to replace [lint]
+
+This is useful because it is recognised by editors like EMACS,
+which can turn them into active links to the relevant file/position.
+
 .. raw:: html
 
    <p><br/></p>
@@ -223,6 +238,10 @@
 Other options
 -------------
 
-``-v`` outputs the program version, ``--help`` displays cheatsheet option
-help.
+``--output FILE`` is used to output the report to a file instead of stdout.
+
+``-v`` outputs the program version.
+
+``--help`` displays cheatsheet option help.
+
 
diff --git a/issues.txt b/issues.txt
--- a/issues.txt
+++ b/issues.txt
@@ -1,3 +1,9 @@
+changes.txt
+    14  issues now get a free [xxx] [fixme]
+    33  something <-- is valid now) - more languages available (c++, java,
+        javascript, python, ruby) - fixed end-of-file bug and double quote
+        string literal
+ 
 doc/dev/issues.txt
     10  from String to Text? [feature:advanced]
     11  colorise output on regexps? [feature:advanced]
@@ -9,64 +15,68 @@
     17  symlinks? [feature:intermediate]
     18  check --output pretty, there are trailing white spaces [bug] [u:1]
     19  test con 7.6.3 [feature:basic] [test]
-    20  todo/fixmes in different sections [request] [u:3]
-    21  linux kernel, lentil si inceppa su dei caratteri [bug]
-    22  da cabal a hpack [u:1] [feature:advanced]
-    23  ad oggi veramente lento [u:2] [refactor]
-    24  list 'ok' tags somehow? put them in doc? [doc] [design]
-    25  sm: issue numbers is valuable [design] [request]
-    26  sm: have a way to link to discussion/history of issue [design]
+    20  linux kernel, lentil si inceppa su dei caratteri [bug]
+    21  da cabal a hpack [u:1] [feature:advanced]
+    22  ad oggi veramente lento [u:2] [refactor]
+    23  sm: issue numbers is valuable [design] [request]
+    24  sm: have a way to link to discussion/history of issue [design]
         [request]
-    27  sm: 1. lentil autogenerates numbers where missing adding tags, 2.
+    25  sm: 1. lentil autogenerates numbers where missing adding tags, 2.
         creates an associated numbered file in .issues/, displays
         associated notes written in those files is asked, 3. even update
         them when there is a source change. (4) these files could be
         webserved when they want something linkable. Vedi comments in
         doc/dev/issues.txt [design] [request]
-    33  chickpea, lentil's brother. Two commands, add number to numberless
+    31  chickpea, lentil's brother. Two commands, add number to numberless
         tag (#1212 or something), create a mini db with those issues, which
         automatically updated and you can even write stuff in there. O
         maybe you can even add lentil, chickpea and quinoa. Vedi more in
         doc/dev/issues.txt [design]
+    37  make it lazy in ouputting todos [refactor]
+    38  way to 'group' (section) output by tag [feature:advanced]
  
+doc/dev/sm.txt
+    13  issue from something like
+    15  take the dog out for a walk [refactor]
+    19  #301 take the dog out for a walk [refactor]
+    25  referring to this, and another part editable freely.
+ 
 src/Lentil/Args.hs
     23  disambiguation optparse-applicative [feature:intermediate]
     24  help as lentil PATH [ PATH... ] [ OPTIONS ] [feature:intermediate]
     89  uncomment and implement sorting [feature:intermediate]
+   100  sort parsing? [feature:intermediate]
  
 src/Lentil/File.hs
-    49  combine funziona su windows? [feature:intermediate]
+    51  combine funziona su windows? [feature:intermediate]
  
 src/Lentil/Parse/Issue.hs
-    26  eliminate lookahead? fai il parser davvero da bottom up senza sub
-        parsing [lint] [refactor]
-    28  e che fare quando il todo segue un * come nei commenti lunghi c?
+    23  e che fare quando il todo segue un * come nei commenti lunghi c?
         [design]
-    56  add this to (ciString ancillaries?) [refactor]
-    67  add blankline to ancillaries? [lint]
-   110  allow tags in before description? [doc] [design]
-   141  rimuovi tutti gli eof, oramai non servono [refactor]
-   165  partial pattern! [refactor] [lint]
-   180  deduplicate runparsource [lint] [refactor]
+    63  add this to (ciString ancillaries?) [refactor]
+   111  usa spaces non ' ' [fixme]
+   154  specifica meglio [fixme]
  
-src/Lentil/Parse/Source.hs
-    41  ++ "\n" is inefficient [lint] [refactor]
-    62  fallo diventare string così non impazzisci nelle altre parti
-        [refactor]
-    83  lint program parser [lint]
-    87  manyTill1 broken? occhio che al primon on chiama ed! [test]
-   102  ugly parens [lint] [refactor]
-   116  add langparsers che sia estensibile e leggibile a compilazione
-        [u:3]
-   155  ugly hack to allow tODOs to be parseable even in first line. This
-        is coupled with another hack in parser `issue` (another module).
-        [refactor] [lint] [duct]
+src/Lentil/Parse/Run.hs
+    31  a function String -> [Issue]
  
-src/Lentil/Print.hs
-    43  colours are bad for unix philosophy, remove them? hlint manages to
-        get a colorised output when ran alone but not when piped to less,
-        how? [design]
+src/Lentil/Parse/Syntaxes.hs
+    19  add langparsers che sia estensibile e leggibile a compilazione
+        [u:2] [feature:intermediate]
+    35  multiline signature? [lint]
+    36  tag at the beginning too? [design]
  
+src/Main.hs
+    35  add doc to use less -r when piping hIsTerminalDevice stdout [doc]
+ 
 test/Lentil/ArgsSpec.hs
     12  can't test lOpts, need to make a runner and a validator on the
         output from io [test]
+ 
+test/Tests.hs
+     3 
+   http://hackage.haskell.org/package/nanospec-0.2.1/docs/Test-Hspec.html
+   use this? [refactor]
+     6 
+   http://hackage.haskell.org/package/mockery-0.3.0/docs/Test-Mockery-Directory.html
+   instead of folder use this? [refactor]
diff --git a/lentil.cabal b/lentil.cabal
--- a/lentil.cabal
+++ b/lentil.cabal
@@ -1,5 +1,5 @@
 name:                lentil
-version:             0.1.1.3
+version:             0.1.2.0
 synopsis:            frugal issue tracker
 description:         minumum effort, cohesive issue tracker based on
                      ubiquitous @TODO@s and @FIXME@s conventions.
@@ -41,7 +41,8 @@
                        ansi-wl-pprint >= 0.6 && < 0.7, csv >= 0.1 && < 0.2
   other-modules:       Lentil.Types, Lentil.Args, Lentil.File, Lentil.Print,
                        Lentil.Query, Lentil.Export, Lentil.Parse.Source,
-                       Lentil.Parse.Issue
+                       Lentil.Parse.Issue Lentil.Parse.Syntaxes,
+                       Lentil.Parse.Run
   hs-source-dirs:      src
   default-language:    Haskell2010
 
@@ -58,10 +59,12 @@
                        csv >= 0.1 && < 0.2
   other-modules:       Lentil.Types, Lentil.Args, Lentil.File, Lentil.Print,
                        Lentil.Query, Lentil.Export, Lentil.Parse.Source,
-                       Lentil.Parse.Issue,
+                       Lentil.Parse.Issue, Lentil.Parse.Syntaxes,
+                       Lentil.Parse.Run,
                        Lentil.ArgsSpec, Lentil.ExportSpec, Lentil.FileSpec,
                        Lentil.PrintSpec, Lentil.Parse.SourceSpec,
-                       Lentil.Parse.IssueSpec, Lentil.QuerySpec
+                       Lentil.Parse.IssueSpec, Lentil.QuerySpec,
+                       Lentil.TypeSpec, Lentil.Parse.RunSpec
   type:                exitcode-stdio-1.0
 
 source-repository head
diff --git a/src/Lentil/Args.hs b/src/Lentil/Args.hs
--- a/src/Lentil/Args.hs
+++ b/src/Lentil/Args.hs
@@ -63,7 +63,7 @@
                     ( short 'f'      <>
                       metavar "TYPE" <>
                       value Pretty   <>
-                      help "output format (pretty, tagpop, csv)" )
+                      help "output format (pretty, tagpop, csv, comp)" )
     where
           parseFormat :: String -> ReadM Format
           parseFormat s = let asl = map forTup (enumFrom minBound)
diff --git a/src/Lentil/Export.hs b/src/Lentil/Export.hs
--- a/src/Lentil/Export.hs
+++ b/src/Lentil/Export.hs
@@ -12,6 +12,7 @@
 import Text.CSV
 import Lentil.Types
 
+import qualified Data.List as L
 
 ---------------
 -- FUNCTIONS --
@@ -20,14 +21,28 @@
 issues2CSV :: [Issue] -> String
 issues2CSV is = printCSV (firstLine : map i2r is)
     where firstLine = ["Filepath", "Row", "Description", "Tags"]
-          i2r i     = [iFile i, show (iRow i),
+          i2r i     = [(prettyFP . iFile) i, show (iRow i),
                        iDesc i, tags2String (iTags i)]
 
 
+-- compiler-like (gcc/ghc) warnings, parseable by emacs
+issues2Compiler :: [Issue] -> String
+issues2Compiler is = L.intercalate "\n" (map i2c is)
+    where i2c i = (prettyFP . iFile) i ++ ":" ++ show (iRow i) ++ ":\n" ++
+                  "   " ++ iDesc i ++ " " ++
+                  tags2StringPretty (iTags i) ++ "\n"
+
+
 -----------------
 -- ANCILLARIES --
 -----------------
 
+-- tag1 tag2 etc
 tags2String :: [Tag] -> String
 tags2String ts = unwords (map tagString ts)
+
+-- [tag1] [tag2] etc.
+tags2StringPretty :: [Tag] -> String
+tags2StringPretty ts = L.intercalate " " .
+                       map ((openDel:) . (++[closeDel]) . tagString) $ ts
 
diff --git a/src/Lentil/File.hs b/src/Lentil/File.hs
--- a/src/Lentil/File.hs
+++ b/src/Lentil/File.hs
@@ -11,7 +11,7 @@
 module Lentil.File where
 
 import Lentil.Types
-import Lentil.Parse.Issue
+import Lentil.Parse.Run
 
 import System.FilePath
 import System.FilePath.Find
@@ -42,7 +42,9 @@
 findClause :: [FilePath] -> [FilePath] -> FindClause Bool
 findClause i x = let ic     = mconcat $ map fp2fc i
                      xc     = mconcat $ map fp2fc x
-                 in fmap getAny ic &&? (not <$> fmap getAny xc)
+                 in fileType ==? RegularFile &&?
+                    fmap getAny ic           &&?
+                    (not <$> fmap getAny xc)
     where
           fp2fc :: FilePath -> FindClause Any
           fp2fc f = Any . L.isPrefixOf (combine "." f) <$> filePath
diff --git a/src/Lentil/Parse/Issue.hs b/src/Lentil/Parse/Issue.hs
--- a/src/Lentil/Parse/Issue.hs
+++ b/src/Lentil/Parse/Issue.hs
@@ -10,32 +10,25 @@
 module Lentil.Parse.Issue where
 
 import Lentil.Types
-import Lentil.Parse.Source (commentParser)
 
 import Text.Parsec
-import qualified Text.Parsec.Pos as P
 
 import Control.Applicative hiding ( (<|>), optional, many )
 
 import qualified Data.Char as C
-import qualified Data.List as L
-import qualified Data.Either as E
-import qualified System.IO as I
 
+import Prelude -- 7.8 hack
 
--- TODO: eliminate lookahead? fai il parser davvero da bottom up senza sub
---       parsing [lint] [refactor] ?
--- TODO: e che fare quando il todo segue un * come nei commenti lunghi c? [design]
 
+-- TODO: e che fare quando il todo segue un * come nei commenti
+--       lunghi c? [design]
 
+
 -----------
 -- TYPES --
 -----------
 
-type ParIssue a = Parsec String ParState a
-
--- file we are parsing
-data ParState = ParState { psPath    :: FilePath }
+type ParIssue a = Parsec String () a
 
 -- issue flagword
 data FlagWord = Todo | Fixme | Xxx deriving (Show, Enum, Eq)
@@ -78,7 +71,6 @@
 htmlify :: String -> String
 htmlify cs = unwords . words $ cs
 
--- todo add blankline to ancillaries? [lint]
 -- a blank line of text (even at eof)
 blankline :: ParIssue ()
 blankline = char '\n' *> (() <$ char '\n' <|> eof)
@@ -114,8 +106,7 @@
 
 -- optional ws + flagwords (case unsensitive) + optional ':' ++ optional1 ws
 incipit :: ParIssue FlagWord
-incipit = char '\n' *> spaces >>
-          fwpar               >>= \fw ->
+incipit = fwpar               >>= \fw ->
           optional (char ':') >>
           many1 (char ' ')    >> -- fixme usa spaces non ' '
           return fw
@@ -126,9 +117,7 @@
           fwpar = choice (map ciString flagWords) >>=
                   return . s2fw
 
--- TODO: allow tags in before description? [doc] [design]
 
-
 ------------
 -- ISSUES --
 ------------
@@ -140,7 +129,7 @@
 -- another TODO).
 issue :: ParIssue Issue
 issue = (mkIssue <$> incipit
-                 <*> fmap psPath getState
+                 <*> fmap sourceName getPosition
                  <*> (fmap sourceLine getPosition)
                  <*> freeText
                  <*> option [] (try tags))
@@ -148,7 +137,6 @@
     where
           mkIssue fw fp ln ds tgs = Issue fp ln ds (addTag fw tgs)
 
-          -- todo incipit should return FlagWord, not a string [refactor]
           addTag Todo tgs = tgs
           addTag fw   tgs = (Tag $ fw2s fw) : tgs
 
@@ -159,50 +147,18 @@
 freeText :: ParIssue Description
 freeText = fmap htmlify (manyTill anyChar end) <?> "free text"
     where vp p      = try . parsecMap (const ()) $ p
+          nlInc     = char '\n' *> spaces >> incipit
           end       = lookAhead $ choice [vp (spaces *> tag),
                                           vp blankline,
-                                          vp incipit]
-
-    -- todo rimuovi tutti gli eof, oramai non servono [refactor]
+                                          vp nlInc,
+                                          vp eof] -- fixme specifica meglio
 
 tags :: ParIssue [Tag]
 tags = many1 (try $ spaces *> tag) <?> "tags"
 
 
-
-
 -- parses a number of issues from a given line-of-text
 issues :: ParIssue [Issue]
-issues = getPosition >>= \p -> -- horrible hack, search for [duct] for expl-
-         setPosition (setSourceLine p 0) >> -- anation
-         many (try $ manyTill anyChar (lookAhead $ try incipit) *> issue)
+issues = many (try $ manyTill anyChar (lookAhead $ try incipit) *> issue)
          <?> "issues"
-
-
-----------
--- FILE --
-----------
-
--- main function with wich to parse issues; errors on stderr
-issueFinder :: [FilePath] -> IO [Issue]
-issueFinder fps = mapM commentParser fps >>= \content ->
-
-                  -- todo partial pattern! [refactor] [lint]
-                  let ass = zip fps content
-                      con' = map (\(a, Just b) -> (a,b)) .
-                             filter ((/= Nothing) . snd) $ ass in
-                  mapM pf con' >>= \iss ->
-
-                  return (concat iss)
-    where
-          pf (fp,cs) = case runParSource issues fp cs of
-                         Left l  -> perr (fp ++ " : issue parsing error " ++
-                                          show l) >> return []
-                         Right r -> return r
-
-          perr cs = I.hPutStrLn I.stderr cs
-
--- todo deduplicate runparsource [lint] [refactor]
-runParSource :: ParIssue a -> FilePath -> String -> Either ParseError a
-runParSource p fp cs = runParser p (ParState fp) fp cs
 
diff --git a/src/Lentil/Parse/Run.hs b/src/Lentil/Parse/Run.hs
new file mode 100644
--- /dev/null
+++ b/src/Lentil/Parse/Run.hs
@@ -0,0 +1,77 @@
+-----------------------------------------------------------------------------
+-- |
+-- Module      :  Lentil.Parse.Run
+-- Copyright   :  © 2015 Francesco Ariis
+-- License     :  GPLv3 (see the LICENSE file)
+--
+-- Parsing functions interface
+-----------------------------------------------------------------------------
+
+
+module Lentil.Parse.Run where
+
+import Lentil.Types
+import Lentil.Parse.Issue
+import Lentil.Parse.Source
+import Lentil.Parse.Syntaxes
+
+import Text.Parsec
+
+import qualified System.IO as I
+import qualified System.Directory as D
+
+import Prelude -- 7.8 hack
+
+
+
+-- main function with wich to parse issues; errors on stderr
+issueFinder :: [FilePath] -> IO [Issue]
+issueFinder fps = fmap concat (mapM fileParser fps)
+
+-- todo a function String -> [Issue] (w/o IO) [debug] [refactor]
+
+-----------------
+-- ANCILLARIES --
+-----------------
+
+-- errors to stderr
+fileParser :: FilePath -> IO [Issue]
+fileParser fp = D.doesFileExist fp >>= \fb ->
+
+                -- file exists
+                if fb == False
+                  then perr (fp ++ " : no such file") >> return []
+                  else
+
+                -- parser exists
+                case langParser fp of
+                  Nothing -> return [] -- no error just empy list
+                  Just p  -> readFile fp                >>=
+                             runParIO p fp              >>=
+                             parIssues fp . comms2Tuple
+
+
+-- generic parsing --
+
+runParIO :: Parsec String () [a] -> FilePath -> String -> IO [a]
+runParIO p fp t = case runParser p () fp t of
+                    Left l  -> perr (fp ++ " : parse error " ++
+                                     show l) >> return []
+                    Right r -> return r
+
+-- output errors
+perr :: String -> IO ()
+perr cs  = I.hPutStrLn I.stderr cs
+
+
+-- issue parsing --
+
+parIssues :: FilePath -> [Comment] -> IO [Issue]
+parIssues fp cs = concat <$> mapM (parIssue fp) cs
+
+parIssue :: FilePath -> Comment -> IO [Issue]
+parIssue fp (r, t) = runParIO (setRow r >> issues) fp t
+
+setRow :: Row -> ParIssue ()
+setRow r = getPosition >>= setPosition . flip setSourceLine r
+
diff --git a/src/Lentil/Parse/Source.hs b/src/Lentil/Parse/Source.hs
--- a/src/Lentil/Parse/Source.hs
+++ b/src/Lentil/Parse/Source.hs
@@ -10,21 +10,23 @@
 
 module Lentil.Parse.Source where
 
+import Lentil.Types
+
 import Text.Parsec hiding (Line)
 
-import qualified Data.Char as C
-import qualified System.Directory as D
-import qualified System.IO as I
-import qualified System.FilePath as SF
+import qualified Data.Char  as C
+import qualified Data.Maybe as M
+import qualified Data.List as L
 
 import Control.Applicative hiding (many, (<|>))
 
+import Prelude -- 7.8 hack
+
 -----------
 -- TYPES --
 -----------
 
--- our parsers goal is simple: from a source file, only the comments and
--- newlines
+-- from source to comment strings
 type ParSource a = Parsec String () a
 
 data ParSyntax = ParSyntax { psLineComms  :: [String],
@@ -34,19 +36,43 @@
                  deriving (Show)
 
 
-------------
--- BLOCKS --
-------------
+-----------------
+-- ANCILLARIES --
+-----------------
 
--- TODO: ++ "\n" is inefficient [lint] [refactor]
-lineComment :: String -> ParSource String
-lineComment s = string s *> fmap (++ "\n") (manyTill anyChar newline)
+-- like many1 for manyTill
+manyTill1 :: ParSource a -> ParSource b -> ParSource [a]
+manyTill1 p ed = (:) <$> p <*> manyTill p ed
+
+
+--------------
+-- COMMENTS --
+--------------
+
+data CommentString = SingleLine Row String  -- sans newline
+                   | MultiLine Row String
+                   deriving (Show, Eq)
+
+-- parses stuff like "-- comment"
+lineComment :: String -> ParSource CommentString
+lineComment s = SingleLine                 <$>
+                (string s *> getRow)       <*>
+                (manyTill anyChar newline)
                 <?> "line comment"
 
-blockComment :: (String, String) -> ParSource String
-blockComment (i, e) = string i *> manyTill anyChar (try $ string e)
+blockComment :: (String, String) -> ParSource CommentString
+blockComment (i, e) = MultiLine                         <$>
+                      (string i *> getRow)              <*>
+                      manyTill anyChar (try $ string e)
                       <?> "block comment"
 
+getRow :: ParSource Row
+getRow = fmap sourceLine getPosition
+
+------------------
+-- OTHER BLOCKS --
+------------------
+
 -- quoted strings, escaped by \, by mauke^
 litString :: Char -> ParSource String
 litString ic = q *> many ((char '\\' *> anyChar) <|> noneOf no) <* q
@@ -59,8 +85,6 @@
 litChar ic = q *> ((char '\\' *> anyChar) <|> anyChar) <* q
              <?> "char string sign"
     where q = char ic
-    -- TODO: fallo diventare string così non impazzisci nelle altre parti
-    --       [refactor]
 
 -- a program is instructions to the computer. Ends when you meet
 -- a well formed element from above (linecomm, blockcom, stringlit,
@@ -70,109 +94,75 @@
              <?> "program"
     where
           -- endp :: [ParSource String]
-          endp  = lookAhead $ choice $ map try $ map string posts ++ [lchars]
+          endp  = lookAhead . choice . map try $ map string posts ++ [lchars]
 
-          -- every unambiguous symbol (init comments, listring char)
-          posts  = psLineComms ps ++ map fst (psBlockComms ps) ++
-                   map (:[]) (psStringLits ps)
+          -- every "post" symbol (init comments, listring char)
+          posts  = psLineComms ps              ++ -- line
+                   map fst (psBlockComms ps)   ++ -- block
+                   map (:[]) (psStringLits ps)    -- lit string
 
           -- ambiguous symbols (pall'aaa'foo is valid haskell identifier,
           -- so it should stay here
           lchars = "" <$ choice (map litChar (psCharLits ps))
 
-          -- TODO: lint program parser [lint]
 
-
--- occhio che il primo carattere non è controllato da ED
--- TODO: manyTill1 broken? occhio che al primon on chiama ed! [test]
-manyTill1 :: ParSource a -> ParSource b -> ParSource [a]
-manyTill1 p ed = (:) <$> p <*> manyTill p ed
-
-
 ------------
 -- SOURCE --
 ------------
 
 -- given a set of lineparsers / blockparsers
-source :: ParSyntax -> ParSource String
-source ps@(ParSyntax lc bc sl cl) =
-                choice (map (try . lineComment) lc) -- line comment
-            <|> choice (map (try . blockComment) bc) -- block comment
-            <|> choice (map (onlynl . try . litString) sl)
-            <|> ("" <$ choice (map (try . litChar) cl)) -- todo ugly parens [lint] [refactor]
-            <|> onlynl (program ps)
-            <?> "source file"
-    where onlynl a = fmap (filter (== '\n')) a
+sourcePart :: ParSyntax -> ParSource (Maybe CommentString)
+sourcePart ps@(ParSyntax lc bc sl cl) = choice [plc, pbc, psl, pcl, ppr]
+            <?> "source file part"
+    where
+          ct = choice . map try
 
-sources :: ParSyntax -> ParSource String
-sources ps =   fmap concat (many1 (source ps))
-           <|> ("" <$ eof)
+          plc = Just <$> (ct . map lineComment  $ lc)  -- line comlm
+          pbc = Just <$> (ct . map blockComment $ bc)  -- block comm
+          psl = Nothing <$ (choice . map try . map litString $ sl) -- str lit
+          pcl = Nothing <$ (ct . map litChar $ cl)                 -- char lit
+          ppr = Nothing <$ program ps                              -- program
 
+-- ps: syntax to sever comment from the rest
+source :: ParSyntax -> ParSource [CommentString]
+source ps = fmap M.catMaybes (many1 (sourcePart ps)) <|> ([] <$ eof)
+         <?> "source file"
 
---------------
--- SYNTAXES --
---------------
 
--- TODO: add langparsers che sia estensibile e leggibile
---       a compilazione [u:3]
-
-langParser :: String -> Maybe (ParSource String)
-langParser fp | ext `elem` [".hs", ".lhs"]         = Just haskell
-              | ext `elem` [".c", ".h"]            = Just c
-              | ext `elem` [".cpp", ".hpp"]        = Just c -- C++
-              | ext `elem` [".java"]               = Just c -- Java
-              | ext `elem` [".js"]                 = Just javascript
-              | ext `elem` [".py"]                 = Just python
-              | ext `elem` [".rb"]                 = Just ruby
-              | ext `elem` [".pas", ".pp", ".inc"] = Just pascal
-              | ext `elem` [".txt"]                = Just text
-              | otherwise                          = Nothing
-    where ext = SF.takeExtension fp
+-------------
+-- CONVERT --
+-------------
 
-haskell, c, pascal, text :: ParSource String
-haskell    = sources $ ParSyntax ["--"] [("{-", "-}")] ['"']  ['\'']
-c          = sources $ ParSyntax ["//"] [("/*", "*/")] ['"']  ['\'']
-javascript = sources $ ParSyntax ["//"] [("/*", "*/")] ['"', '\''] []
-pascal     = sources $ ParSyntax ["//"] [("{",  "}" ),
-                                         ("(*", "*)")] ['\''] []
-python     = sources $ ParSyntax ["#"]  [("\"\"\"",
-                                          "\"\"\"")]   ['"', '\''] []
-ruby       = sources $ ParSyntax ["#"] [("=begin",
-                                         "=end")]      ['"', '\''] []
-text       = many anyChar
+type Comment = (Row, String)
 
 
--------------
--- PARSERS --
--------------
+comms2Tuple :: [CommentString] -> [Comment]
+comms2Tuple [] = []
+comms2Tuple (c:cs) | isSl c    = let (a,z) = span isSl (c:cs)
+                                 in groupLineComms a ++ comms2Tuple z
+                   | otherwise = comment2Tuple c : comms2Tuple cs
+    where
+          isSl (SingleLine _ _) = True
+          isSl _                = False
 
+-- use it on Line comments **only**!
+groupLineComms :: [CommentString] -> [Comment]
+groupLineComms cs = let cs'         = map comment2Tuple cs
+                        f (r, s) i  = (r, s, r-i)
 
-commentParser :: FilePath -> IO (Maybe String)
-commentParser fp = case langParser fp of
-                     Nothing -> return Nothing
-                     Just p  -> fileParser fp p >>=
-                                return . Just . ('\n':)
-                                -- TODO: ugly hack to allow tODOs to be
-                                -- parseable even in first line. This is
-                                -- coupled with another hack in parser
-                                -- `issue` (another module). [refactor]
-                                -- [lint] [duct]
+                        zipped      = zipWith f cs' (enumFrom 1)
+                        grouped     = L.groupBy threeEq zipped
 
+                    in map (flatComm . map back) grouped
 
--- errors to stderr
-fileParser :: FilePath -> ParSource String -> IO String
-fileParser fp p = rfe fp >>= \cs ->
-                  case runParSource p fp cs of
-                      Left l  -> perr (fp ++ " : parse error " ++ show l) >>
-                                 return []
-                      Right r -> return r
-    where rfe :: FilePath -> IO String
-          rfe _ = D.doesFileExist fp >>= \fb ->
-                  if fb then readFile fp
-                        else perr (fp ++ " : no such file") >> return ""
+    where
+          threeEq (_, _, x) (_, _, y) = x == y
 
-          perr cs = I.hPutStrLn I.stderr cs
+          back (a, b, _) = (a, b)
+          flatComm cs'   = (fst . head $ cs',
+                            unlines . map snd $ cs')
 
-runParSource :: ParSource a -> FilePath -> String -> Either ParseError a
-runParSource p fp cs = runParser p () fp cs
+comment2Tuple :: CommentString -> Comment
+comment2Tuple (SingleLine r t) = (r, t)
+comment2Tuple (MultiLine  r t) = (r, t)
 
diff --git a/src/Lentil/Parse/Syntaxes.hs b/src/Lentil/Parse/Syntaxes.hs
new file mode 100644
--- /dev/null
+++ b/src/Lentil/Parse/Syntaxes.hs
@@ -0,0 +1,48 @@
+-----------------------------------------------------------------------------
+-- |
+-- Module      :  Lentil.Parse.Syntaxes
+-- Copyright   :  © 2015 Francesco Ariis
+-- License     :  GPLv3 (see the LICENSE file)
+--
+-- Languages descriptors
+-----------------------------------------------------------------------------
+
+
+module Lentil.Parse.Syntaxes where
+
+import Lentil.Parse.Source
+import Text.Parsec
+
+import qualified System.FilePath as SF
+
+
+-- TODO: add langparsers che sia estensibile e leggibile
+--       a compilazione [u:2] [feature:intermediate]
+
+langParser :: String -> Maybe (ParSource [CommentString])
+langParser fp | ext `elem` [".hs", ".lhs"]         = Just haskell
+              | ext `elem` [".c", ".h"]            = Just c
+              | ext `elem` [".cpp", ".hpp"]        = Just c -- C++
+              | ext `elem` [".java"]               = Just c -- Java
+              | ext `elem` [".js"]                 = Just javascript
+              | ext `elem` [".py"]                 = Just python
+              | ext `elem` [".rb"]                 = Just ruby
+              | ext `elem` [".pas", ".pp", ".inc"] = Just pascal
+              | ext `elem` [".txt"]                = Just text
+              | otherwise                          = Nothing
+    where ext = SF.takeExtension fp
+
+-- todo multiline signature? [lint]
+-- todo tag at the beginning too? [design]
+haskell, c, javascript, pascal, python, ruby, text :: ParSource [CommentString]
+haskell    = source $ ParSyntax ["--"] [("{-", "-}")] ['"']  ['\'']
+c          = source $ ParSyntax ["//"] [("/*", "*/")] ['"']  ['\'']
+javascript = source $ ParSyntax ["//"] [("/*", "*/")] ['"', '\''] []
+pascal     = source $ ParSyntax ["//"] [("{",  "}" ),
+                                        ("(*", "*)")] ['\''] []
+python     = source $ ParSyntax ["#"]  [("\"\"\"",
+                                         "\"\"\"")]   ['"', '\''] []
+ruby       = source $ ParSyntax ["#"] [("=begin",
+                                         "=end")]      ['"', '\''] []
+text       = (:[]) . MultiLine 1 <$> many anyChar
+
diff --git a/src/Lentil/Print.hs b/src/Lentil/Print.hs
--- a/src/Lentil/Print.hs
+++ b/src/Lentil/Print.hs
@@ -40,9 +40,6 @@
 -- PRETTY PRINT --
 ------------------
 
--- TODO: colours are bad for unix philosophy, remove them? hlint
---       manages to get a colorised output when ran alone but not when
---       piped to less, how? [design]
 data TagCol = Red | Blue deriving (Eq)
 ppTag :: TagCol -> Tag -> Doc
 ppTag c t = col (char openDel) <> string (tagString t) <>
@@ -63,7 +60,7 @@
 
 
 ppFile :: Int -> [Issue] -> Doc
-ppFile ind is = text (drop 2 $ iFile (head is)) PP.<$>
+ppFile ind is = text (prettyFP $ iFile (head is)) PP.<$>
                 vsep (map (ppIssue ind) is)
 
 ppIssues :: Bool -> [Issue] -> String
diff --git a/src/Lentil/Types.hs b/src/Lentil/Types.hs
--- a/src/Lentil/Types.hs
+++ b/src/Lentil/Types.hs
@@ -10,7 +10,9 @@
 module Lentil.Types where
 
 
+import qualified Data.List as L
 
+
 data Issue = Issue { iFile   :: FilePath,
                      iRow    :: Row,
                      iDesc   :: Description,
@@ -24,12 +26,18 @@
 type Row = Int
 
 -- output format
-data Format = TagPop | Pretty | Csv
+data Format = TagPop | Pretty | Csv | Comp
             deriving (Show, Eq, Enum, Bounded)
+    -- comp: as gcc/ghc would output warnings
 
 
 -- tag delimiters
 openDel, closeDel :: Char
 openDel  = '['
 closeDel = ']'
+
+-- eliminate "./" at the beginning of fp if present
+prettyFP :: String -> String
+prettyFP fp | L.isPrefixOf "./" fp = drop 2 fp
+            | otherwise            = fp
 
diff --git a/src/Main.hs b/src/Main.hs
--- a/src/Main.hs
+++ b/src/Main.hs
@@ -8,7 +8,8 @@
 import Options.Applicative
 
 import qualified Data.Maybe as M
-import Data.Monoid
+import Data.Monoid -- 7.8
+import qualified System.IO as I
 
 
 main :: IO ()
@@ -27,26 +28,34 @@
                                    short 'v'      <>
                                    help "show version and copyright info" )
     where
-          versionCopy = "\nlentil - a frugal issue tracker, version 0.1.1.3\n\
+          versionCopy = "lentil - a frugal issue tracker, version 0.1.2.0\n\
                         \(C) 2015 Francesco Ariis - http://www.ariis.it\n\
                         \released under the GNU General Public License 3\n"
 
+-- todo add doc to use less -r when piping hIsTerminalDevice stdout [doc]
 
 runLentil :: LOptions -> IO ()
 runLentil lo = uncurry findIssues (loInExcl lo) >>= \is -> -- grab issues
                let fil = filterAnd (loFilters lo) is       -- filtered
-                   ord = chainSorts fil (loSort lo) in     -- ordered
+                   ord = chainSorts fil (loSort lo)        -- ordered
 
-               case loOutFile lo of
+                   -- which function to use to output stuff (file/term)
+                   outFunction :: String -> IO ()
+                   outFunction = case loOutFile lo of
+                                   Nothing -> putStrLn
+                                   Just fp -> writeFile fp
 
-                 -- std output
-                 Nothing -> case loFormat lo of
-                              Csv    -> putStrLn (issues2CSV is)
-                              Pretty -> putStrLn (ppIssues True ord)
-                              TagPop -> putStrLn (ppPopularity True is)
+                   -- col or not?
+                   bCol :: Bool
+                   bCol = if loOutFile lo == Nothing
+                            then True
+                            else False
 
-                 Just fp -> case loFormat lo of
-                              Csv    -> writeFile fp (issues2CSV is)
-                              Pretty -> writeFile fp (ppIssues False ord)
-                              TagPop -> writeFile fp (ppPopularity False is)
+               in
+
+               case loFormat lo of
+                 Pretty -> outFunction (ppIssues bCol ord)
+                 TagPop -> outFunction (ppPopularity bCol fil)
+                 Csv    -> outFunction (issues2CSV fil)
+                 Comp   -> outFunction (issues2Compiler fil)
 
diff --git a/test/Lentil/ExportSpec.hs b/test/Lentil/ExportSpec.hs
--- a/test/Lentil/ExportSpec.hs
+++ b/test/Lentil/ExportSpec.hs
@@ -8,7 +8,7 @@
 
 
 is :: [Issue]
-is = [Issue "file" 1 "da" [Tag "a", Tag "c"],
+is = [Issue "./file" 1 "da" [Tag "a", Tag "c"],
       Issue "file" 2 "db" [Tag "e:f"]]
 
 csv :: String
@@ -16,6 +16,13 @@
       \\"file\",\"1\",\"da\",\"a c\"\n\
       \\"file\",\"2\",\"db\",\"e:f\""
 
+cmp :: String
+cmp = unlines $
+        ["file:1:",
+         "   da [a] [c]",
+         "",
+         "file:2:",
+         "   db [e:f]"]
 
 main :: IO ()
 main = hspec spec
@@ -23,7 +30,19 @@
 spec :: Spec
 spec = do
 
+  describe "tags2String" $ do
+    it "converts tags to plain string, intercalated by ' '" $
+      tags2String [Tag "a", Tag "b"] `shouldBe` "a b"
+
+  describe "tags2StringPretty" $ do
+    it "converts tags to string, with open/close delimiters" $
+      tags2StringPretty [Tag "a", Tag "b"] `shouldBe` "[a] [b]"
+
   describe "issues2CSV" $ do
     it "exports issues to CSV" $
       issues2CSV is `shouldBe` csv
+
+  describe "issues2Compiler" $ do
+    it "exports issues to compiler-like output format" $
+      issues2Compiler is `shouldBe` cmp
 
diff --git a/test/Lentil/Parse/IssueSpec.hs b/test/Lentil/Parse/IssueSpec.hs
--- a/test/Lentil/Parse/IssueSpec.hs
+++ b/test/Lentil/Parse/IssueSpec.hs
@@ -3,18 +3,19 @@
 import Test.Hspec
 import Text.Parsec ( runParser )
 import Text.Parsec.Char
-import Text.Parsec.Combinator
 import Control.Applicative
 
 import Lentil.Types
 import Lentil.Parse.Issue
 
+import Prelude -- 7.8 hack
+
 -- Parsing tests
 
 -- simple parser (choosable if we are at begin of line or else)
 sp :: ParIssue a -> String -> Maybe a
 sp p cs = either (const Nothing) Just
-                    (runParser p (ParState fp) fp cs)
+                    (runParser p () fp cs)
     where fp = "<f>"
 
 
@@ -56,23 +57,21 @@
 
   describe "incipit" $ do
     it "parses the initial section of an issue, returns nothing" $
-       do sp incipit "\nTODO: "  `shouldBe` Just Todo
-          sp incipit "\nFIXME: "  `shouldBe` Just Fixme
-          sp incipit "\nXXX: "  `shouldBe` Just Xxx
+       do sp incipit "TODO: "  `shouldBe` Just Todo
+          sp incipit "FIXME: "  `shouldBe` Just Fixme
+          sp incipit "XXX: "  `shouldBe` Just Xxx
     it "doesn't work without previous newline" $
-      sp incipit "\nTODO:some"  `shouldBe` Nothing
+      sp incipit "TODO:some"  `shouldBe` Nothing
     it "doesn't work if you don't add a space after :" $
-      sp incipit "\nTODO:some"  `shouldBe` Nothing
+      sp incipit "TODO:some"  `shouldBe` Nothing
     it "does allow you to omit the :" $
-      sp incipit "\nxxx some"  `shouldBe` Just Xxx
+      sp incipit "xxx some"  `shouldBe` Just Xxx
     it "is case unsensitive in flag-word" $
-      sp incipit "\ntOdO some"  `shouldBe` Just Todo
-    it "allows whitespace before the todo" $
-      sp incipit "\n   fixme some"  `shouldBe` Just Fixme
-    it "doesn't allow anything else before flag-words" $
-      sp incipit "\nso fixme someday"  `shouldBe` Nothing
+      sp incipit "tOdO some"  `shouldBe` Just Todo
+    it "doesn't allow anything before flag-words" $
+      sp incipit "so fixme someday"  `shouldBe` Nothing
     it "fails if we are not at the beginning of line" $
-      sp incipit "\nso fixme someday"  `shouldBe` Nothing
+      sp incipit "so fixme someday"  `shouldBe` Nothing
 
   describe "tags" $ do
     it "parses a series of tags, sep by whitespace" $
@@ -102,40 +101,39 @@
 
   describe "issue" $ do
     it "parses an issue" $
-      sp issue "\n fixMe this is it [t] [f:w]"
-         `shouldBe` (Just $ Issue "<f>" 2 "this is it"
-                                  [Tag "fixme", Tag "t", Tag "f:w"])
-    it "fails if were are not at beginning of a line" $
       sp issue "fixMe this is it [t] [f:w]"
-         `shouldBe` Nothing
+         `shouldBe` (Just $ Issue "<f>" 1 "this is it"
+                                  [Tag "fixme", Tag "t", Tag "f:w"])
     it "parses tagless/fieldless issues too" $
-      sp issue "\nTODO: this is it\n"
-         `shouldBe` (Just $ Issue "<f>" 2 "this is it" [])
+      sp issue "TODO: this is it\n"
+         `shouldBe` (Just $ Issue "<f>" 1 "this is it" [])
+    it "parses an issue not ended by \\n" $
+      sp issue "todo block1 "
+         `shouldBe` (Just $ Issue "<f>" 1 "block1" [])
     it "doesn't display the eventual \n at eof" $
-      sp issue "\nTOdO: this is it\n"
-         `shouldBe` (Just $ Issue "<f>" 2 "this is it" [])
+      sp issue "TOdO: this is it\n"
+         `shouldBe` (Just $ Issue "<f>" 1 "this is it" [])
     it "doesn't accept a lone (naked) todo" $
-      sp issue "\ntodo\n"
+      sp issue "todo\n"
          `shouldBe` Nothing
     it "issues declared with fixme get a free [fixme] tag" $
-      sp issue "\nfixme blah\n"
-         `shouldBe` (Just $ Issue "<f>" 2 "blah" [Tag "fixme"])
+      sp issue "fixme blah\n"
+         `shouldBe` (Just $ Issue "<f>" 1 "blah" [Tag "fixme"])
 
   describe "issues" $ do
     it "parses multiple issues" $
-      sp issues "\nTODO: this is it [f:w]\n TODO: hey [t]"
+      sp issues "TODO: this is it [f:w]\n TODO: hey [t]"
          `shouldBe` Just [Issue "<f>" 1 "this is it" [Tag "f:w"],
                           Issue "<f>" 2 "hey" [Tag "t"]]
-    it "don't parse multiple issues if on the same line" $
-      sp issues "\nTODO: this is it [f:w] TODO: hey [t]"
-         `shouldBe` Just [Issue "<f>" 1 "this is it" [Tag "f:w"]]
-
-  describe "issueFinder" $ do
-    it "reads a file (code or txt) for issues" $
-      let fp = "test/test-files/lang-comm/test.txt" in
-      issueFinder [fp] >>= \i ->
-      i `shouldBe` [Issue fp 1 "palla" [],
-                    Issue fp 3 "beta"  [Tag "fixme"],
-                    Issue fp 4 "gamma" [Tag "xxx"],
-                    Issue fp 6 "qqq"   [Tag "fixme", Tag "bug"]]
+    it "parse multiple issues if on the same line" $
+      sp issues "TODO: this is it [f:w] TODO: hey [t]"
+         `shouldBe` Just [Issue "<f>" 1 "this is it" [Tag "f:w"],
+                          Issue "<f>" 1 "hey" [Tag "t"]]
+    it "don't parse multiple issues on the same line if not ended by tags" $
+      sp issues "TODO: this is it todo hey [t]"
+         `shouldBe` Just [Issue "<f>" 1 "this is it todo hey" [Tag "t"]]
+    it "parses two issues, tagless, if the second starts on nl" $
+      sp issues "TODO: this is it \n  todo hey [t]"
+         `shouldBe` Just [Issue "<f>" 1 "this is it" [],
+                          Issue "<f>" 2 "hey" [Tag "t"]]
 
diff --git a/test/Lentil/Parse/RunSpec.hs b/test/Lentil/Parse/RunSpec.hs
new file mode 100644
--- /dev/null
+++ b/test/Lentil/Parse/RunSpec.hs
@@ -0,0 +1,70 @@
+module Lentil.Parse.RunSpec where
+
+import Test.Hspec
+import Text.Parsec ( runParser )
+
+import Lentil.Types
+import Lentil.Parse.Run
+import Lentil.Parse.Source
+
+import Prelude -- 7.8 hack
+
+-- Parsing tests
+
+-- simple parser (choosable if we are at begin of line or else)
+sp :: ParSource a -> String -> Maybe a
+sp p cs = either (const Nothing) Just
+                    (runParser p () fp cs)
+    where fp = "<f>"
+
+
+main :: IO ()
+main = hspec spec
+
+
+
+spec :: Spec
+spec = do
+
+  describe "commentParser - specific" $ do
+    it "doesn't parse contiguous line/block as a single issue" $
+        fileParser "test/test-files/specific/contiguous.c"
+            `shouldReturn` [Issue "test/test-files/specific/contiguous.c" 1
+                                  "issue1" []]
+
+  let spt fp = [Issue fp 1 "single comment" [],
+                Issue fp 3 "single2" [],
+                Issue fp 8 "block1"  [],
+                Issue fp 9 "block2" [Tag "tog"]]
+  describe "commentParser - languages" $ do
+    it "parses a plain text source" $
+        fileParser "test/test-files/lang-comm/text.txt"
+            `shouldReturn` spt "test/test-files/lang-comm/text.txt"
+    it "parses a haskell source" $
+        fileParser "test/test-files/lang-comm/haskell.hs"
+            `shouldReturn` spt "test/test-files/lang-comm/haskell.hs"
+    it "parses a C source" $
+        fileParser "test/test-files/lang-comm/clang.c"
+            `shouldReturn` spt "test/test-files/lang-comm/clang.c"
+    it "parses a Pascal source" $
+        fileParser "test/test-files/lang-comm/pascal.pas"
+            `shouldReturn` spt "test/test-files/lang-comm/pascal.pas"
+    it "parses a javascript source" $
+        fileParser "test/test-files/lang-comm/javascript.js"
+            `shouldReturn` spt "test/test-files/lang-comm/javascript.js"
+    it "parses a python source" $
+        fileParser "test/test-files/lang-comm/python.py"
+            `shouldReturn` spt "test/test-files/lang-comm/python.py"
+    it "parses a ruby source" $
+        fileParser "test/test-files/lang-comm/ruby.rb"
+            `shouldReturn` spt "test/test-files/lang-comm/ruby.rb"
+
+  describe "issueFinder" $ do
+    it "reads a file (code or txt) for issues" $
+      let fp = "test/test-files/lang-comm/test.txt" in
+      issueFinder [fp] >>= \i ->
+      i `shouldBe` [Issue fp 1 "palla" [],
+                    Issue fp 3 "beta"  [Tag "fixme"],
+                    Issue fp 4 "gamma" [Tag "xxx"],
+                    Issue fp 6 "qqq"   [Tag "fixme", Tag "bug"]]
+
diff --git a/test/Lentil/Parse/SourceSpec.hs b/test/Lentil/Parse/SourceSpec.hs
--- a/test/Lentil/Parse/SourceSpec.hs
+++ b/test/Lentil/Parse/SourceSpec.hs
@@ -4,10 +4,12 @@
 import Text.Parsec (runParser)
 import Text.Parsec.Char
 import Text.Parsec.Combinator
-import Control.Applicative
 
+import Lentil.Types
 import Lentil.Parse.Source
 
+import Prelude -- 7.8 hack
+
 -- Parsing tests
 
 -- simple parser
@@ -16,7 +18,12 @@
                  (runParser p () fp cs)
     where fp = "<f>"
 
+-- short comment constructors
+sl, ml :: Row -> String -> CommentString
+sl r t = SingleLine r t
+ml r t = MultiLine r t
 
+
 main :: IO ()
 main = hspec spec
 
@@ -32,17 +39,20 @@
       (sp (manyTill1 anyChar newline) "\n",
        sp (manyTill  anyChar newline) "\n") `shouldBe` (Nothing,
                                                         Just "")
+    it "has the same behaviour as manyTill on 1 char w/o end char" $
+      sp (manyTill1 anyChar newline) "f" `shouldBe`
+      sp (manyTill anyChar newline) "f"
 
   describe "lineComment" $ do
     it "parses a line comment" $
-      sp (lineComment "//") "// Test\n" `shouldBe` Just " Test\n"
+      sp (lineComment "//") "// Test\n" `shouldBe` Just (sl 1 " Test")
     it "fails without trailing \\n" $
       sp (lineComment "//") "// Test"   `shouldBe` Nothing
 
   describe "blockComment" $ do
     it "parses a block comment" $
       sp (blockComment ("/*","*/")) "/* Test\n2 */" `shouldBe`
-         Just " Test\n2 "
+         Just (ml 1 " Test\n2 ")
 
   describe "litString" $ do
     it "parses code string" $
@@ -76,43 +86,33 @@
   let rbs = ParSyntax ["#"] [] ['"', '\'']  []
   describe "source" $ do
     it "parses one piece of source (line-comment)" $
-      sp (source hss) "-- hey\n my " `shouldBe`  Just " hey\n"
+      sp (source hss) "-- hey\n my " `shouldBe` Just [sl 1 " hey"]
     it "parses one piece of source (block-comment)" $
-      sp (source hss) "{-hey-}\n my " `shouldBe`  Just "hey"
+      sp (source hss) "{-hey-}\n my " `shouldBe` Just [ml 1 "hey"]
     it "parses one piece of source (string-literal)" $
-      sp (source hss) "\"hey\"" `shouldBe`  Just ""
+      sp (source hss) "\"hey\"" `shouldBe` Just []
     it "parses a string for language with ' and \" available" $
-      sp (source rbs) "\"he#y\"" `shouldBe`  Just ""
+      sp (source rbs) "\"he#y\"" `shouldBe` Just []
     it "parses one piece of source (char-literal)" $
-      sp (source hss) "\'h\'" `shouldBe`  Just ""
+      sp (source hss) "\'h\'" `shouldBe` Just []
     it "parses one piece of source (program instructions)" $
-      sp (source hss) "prime'" `shouldBe`  Just ""
-
-  describe "sources" $ do
+      sp (source hss) "prime'" `shouldBe` Just []
     it "should not choke on en empty file" $
-      sp (sources hss) "" `shouldBe`  Just ""
+      sp (source hss) "" `shouldBe`  Just []
 
-  describe "commentParser" $ do
-    beforeAll (readFile "test/test-files/lang-comm/out.blocks") $ do
-      it "parses a haskell source" (\a ->
-        commentParser "test/test-files/lang-comm/haskell.hs" >>= \s ->
-        s `shouldBe` Just a)
-      it "parses a C source" (\a ->
-        commentParser "test/test-files/lang-comm/clang.c" >>= \s ->
-        s `shouldBe` Just a)
-      it "parses a Pascal source" (\a ->
-        commentParser "test/test-files/lang-comm/pascal.pas" >>= \s ->
-        s `shouldBe` Just a)
-      it "parses a plain text source" (\a ->
-        commentParser "test/test-files/lang-comm/text.txt" >>= \s ->
-        s `shouldBe` Just a)
-      it "parses a javascript source" (\a ->
-        commentParser "test/test-files/lang-comm/javascript.js" >>= \s ->
-        s `shouldBe` Just a)
-      it "parses a python source" (\a ->
-        commentParser "test/test-files/lang-comm/python.py" >>= \s ->
-        s `shouldBe` Just a)
-      it "parses a ruby source" (\a ->
-        commentParser "test/test-files/lang-comm/ruby.rb" >>= \s ->
-        s `shouldBe` Just a)
+  describe "groupLineComms" $ do
+    it "groups line comments" $
+      groupLineComms [SingleLine 1 "a",
+                      SingleLine 2 "b",
+                      SingleLine 4 "c"] `shouldBe` [(1, "a\nb\n"),
+                                                    (4, "c\n"   )]
+
+  describe "comms2Tuple" $ do
+    it "groups comments" $
+      comms2Tuple [SingleLine 1 "a",
+                   SingleLine 2 "b",
+                   MultiLine  5 "c",
+                   SingleLine 6 "d"] `shouldBe` [(1, "a\nb\n"),
+                                                 (5, "c"     ),
+                                                 (6, "d\n"   )]
 
diff --git a/test/Lentil/TypeSpec.hs b/test/Lentil/TypeSpec.hs
new file mode 100644
--- /dev/null
+++ b/test/Lentil/TypeSpec.hs
@@ -0,0 +1,20 @@
+module Lentil.TypeSpec where
+
+import Test.Hspec
+
+import Lentil.Types
+
+-- File tests
+
+main :: IO ()
+main = hspec spec
+
+spec :: Spec
+spec = do
+
+  describe "prettyFP" $ do
+    it "eliminates ./ from beginning of fp, if present" $
+      prettyFP "./file" `shouldBe` "file"
+    it "doesn't change fp is ./ is not there at begin-of-fp" $
+      prettyFP "./file" `shouldBe` "file"
+
diff --git a/test/test-files/lang-comm/clang.c b/test/test-files/lang-comm/clang.c
--- a/test/test-files/lang-comm/clang.c
+++ b/test/test-files/lang-comm/clang.c
@@ -1,11 +1,12 @@
-// single
+// todo single
 // comment
+// Todo: single2
 
 var c = "st/*ring"; // string
+char letter = 'c' // char
 
-/* block
-   comment */
+/* TODO: block1 */
+/* TODO: block2 [tog] */
 
-char letter = 'c' // char
 
 //  end
diff --git a/test/test-files/lang-comm/haskell.hs b/test/test-files/lang-comm/haskell.hs
--- a/test/test-files/lang-comm/haskell.hs
+++ b/test/test-files/lang-comm/haskell.hs
@@ -1,11 +1,9 @@
--- single
+-- TODO: single
 -- comment
+-- todo single2
 
 someOther = "  \"  " -- string
-
-{- block
-   comment -}
-
 char' = '\n' -- char
 
---  end
+{- todo block1 -}
+{- todo block2 [tog] -}
diff --git a/test/test-files/lang-comm/javascript.js b/test/test-files/lang-comm/javascript.js
--- a/test/test-files/lang-comm/javascript.js
+++ b/test/test-files/lang-comm/javascript.js
@@ -1,11 +1,12 @@
-// single
+// todo single
 // comment
+// Todo: single2
 
 var c = "st/*ring"; // string
-
-/* block
-   comment */
-
 var letter = 'c' // char
+
+/* todo block1 */
+          /* todo block2 [tog]
+          */
 
 //  end
diff --git a/test/test-files/lang-comm/pascal.pas b/test/test-files/lang-comm/pascal.pas
--- a/test/test-files/lang-comm/pascal.pas
+++ b/test/test-files/lang-comm/pascal.pas
@@ -1,11 +1,11 @@
-// single
+// todo single
 // comment
+// Todo: single2
 
 qqq := 'Afla' // string
-
-{ block}
-(*   comment *)
-
 c := '"' // char
+
+{ TODO: block1 }
+(*   todo block2 [tog] *)
 
 //  end
diff --git a/test/test-files/lang-comm/python.py b/test/test-files/lang-comm/python.py
--- a/test/test-files/lang-comm/python.py
+++ b/test/test-files/lang-comm/python.py
@@ -1,11 +1,11 @@
-# single
+# TODO: single
 # comment
+# todo single2
 
 c = "st/*ring" # string
-
-""" block
-   comment """
-
 letter = 'c' # char
+
+""" todo block1
+   TODO: block2 [tog] """
 
 #  end
diff --git a/test/test-files/lang-comm/ruby.rb b/test/test-files/lang-comm/ruby.rb
--- a/test/test-files/lang-comm/ruby.rb
+++ b/test/test-files/lang-comm/ruby.rb
@@ -1,11 +1,11 @@
-# single
+# TODO: single
 # comment
+# todo single2
 
 puts "str#ing" # string
-
-=begin block
-   comment =end
-
 a = [1, 'hi', 3.14, 1, 2, [4, 5]] # char
+
+=begin todo block1
+   todo block2 [tog] =end
 
 #  end
diff --git a/test/test-files/lang-comm/text.txt b/test/test-files/lang-comm/text.txt
--- a/test/test-files/lang-comm/text.txt
+++ b/test/test-files/lang-comm/text.txt
@@ -1,11 +1,9 @@
- single
- comment
+todo single
+comment
+TODO single2
 
  string
 
- block
-   comment 
 
- char
-
-  end
+   todo block1
+       todo  block2 [tog]
