2
{-# OPTIONS -Wwarn -w #-}
3
-- The above warning supression flag is a temporary kludge.
4
-- While working on this module you are encouraged to remove it and fix
5
-- any warnings in the module. See
6
-- http://hackage.haskell.org/trac/ghc/wiki/Commentary/CodingStyle#Warnings
9
module Haddock.Parse where
12
import Haddock.Types (Doc(..), Example(Example))
16
import Data.Char (isSpace)
17
import Data.Maybe (fromMaybe)
18
import Data.List (stripPrefix)
25
%token '/' { (TokSpecial '/',_) }
26
'@' { (TokSpecial '@',_) }
27
'[' { (TokDefStart,_) }
29
DQUO { (TokSpecial '\"',_) }
32
ANAME { (TokAName $$,_) }
33
'/../' { (TokEmphasis $$,_) }
35
'(n)' { (TokNumber,_) }
36
'>..' { (TokBirdTrack $$,_) }
37
PROMPT { (TokExamplePrompt $$,_) }
38
RESULT { (TokExampleResult $$,_) }
39
EXP { (TokExampleExpression $$,_) }
40
IDENT { (TokIdent $$,_) }
42
STRING { (TokString $$,_) }
51
doc :: { Doc RdrName }
52
: apara PARA doc { docAppend $1 $3 }
55
| {- empty -} { DocEmpty }
57
apara :: { Doc RdrName }
58
: ulpara { DocUnorderedList [$1] }
59
| olpara { DocOrderedList [$1] }
60
| defpara { DocDefList [$1] }
63
ulpara :: { Doc RdrName }
66
olpara :: { Doc RdrName }
69
defpara :: { (Doc RdrName, Doc RdrName) }
70
: '[' seq ']' seq { ($2, $4) }
72
para :: { Doc RdrName }
73
: seq { docParagraph $1 }
74
| codepara { DocCodeBlock $1 }
75
| examples { DocExamples $1 }
77
codepara :: { Doc RdrName }
78
: '>..' codepara { docAppend (DocString $1) $2 }
79
| '>..' { DocString $1 }
81
examples :: { [Example] }
82
: example examples { $1 : $2 }
85
example :: { Example }
86
: PROMPT EXP result { makeExample $1 $2 (lines $3) }
87
| PROMPT EXP { makeExample $1 $2 [] }
90
: RESULT result { $1 ++ $2 }
93
seq :: { Doc RdrName }
94
: elem seq { docAppend $1 $2 }
97
elem :: { Doc RdrName }
99
| '@' seq1 '@' { DocMonospaced $2 }
101
seq1 :: { Doc RdrName }
102
: PARA seq1 { docAppend (DocString "\n") $2 }
103
| elem1 seq1 { docAppend $1 $2 }
106
elem1 :: { Doc RdrName }
107
: STRING { DocString $1 }
108
| '/../' { DocEmphasis (DocString $1) }
111
| ANAME { DocAName $1 }
112
| IDENT { DocIdentifier $1 }
113
| DQUO strings DQUO { DocModule $2 }
115
strings :: { String }
117
| STRING strings { $1 ++ $2 }
120
happyError :: [LToken] -> Maybe a
121
happyError toks = Nothing
123
-- | Create an 'Example', stripping superfluous characters as appropriate
124
makeExample :: String -> String -> [String] -> Example
125
makeExample prompt expression result =
127
(strip expression) -- we do not care about leading and trailing
128
-- whitespace in expressions, so drop them
131
-- drop trailing whitespace from the prompt, remember the prefix
132
(prefix, _) = span isSpace prompt
133
-- drop, if possible, the exact same sequence of whitespace characters
134
-- from each result line
135
result' = map (tryStripPrefix prefix) result
137
tryStripPrefix xs ys = fromMaybe ys $ stripPrefix xs ys
139
-- | Remove all leading and trailing whitespace
140
strip :: String -> String
141
strip = dropWhile isSpace . reverse . dropWhile isSpace . reverse