Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[API change] Add a Ref inline element and Reference type #81

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions src/Text/Pandoc/Arbitrary.hs
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ instance Arbitrary Inlines where
flattenInline (SmallCaps ils) = ils
flattenInline (Quoted _ ils) = ils
flattenInline (Cite _ ils) = ils
flattenInline (Ref _ _ _ ils) = ils
flattenInline Code{} = []
flattenInline Space = []
flattenInline SoftBreak = []
Expand Down Expand Up @@ -125,6 +126,9 @@ instance Arbitrary Inline where
shrink (Quoted qtype ils) = Quoted qtype <$> shrinkInlineList ils
shrink (Cite cits ils) = (Cite cits <$> shrinkInlineList ils)
++ (flip Cite ils <$> shrink cits)
shrink (Ref attr rt refs ils) = [Ref attr rt refs ils' | ils' <- shrinkInlineList ils]
++ [Ref attr rt refs' ils | refs' <- shrink refs]
++ [Ref attr' rt refs ils | attr' <- shrinkAttr attr]
shrink (Code attr s) = (Code attr <$> shrinkText s)
++ (flip Code s <$> shrinkAttr attr)
shrink Space = []
Expand Down Expand Up @@ -173,6 +177,7 @@ arbInline n = frequency $ [ (60, Str <$> realString)
, (10, Link <$> arbAttr <*> arbInlines (n-1) <*> ((,) <$> realString <*> realString))
, (10, Image <$> arbAttr <*> arbInlines (n-1) <*> ((,) <$> realString <*> realString))
, (2, Cite <$> arbitrary <*> arbInlines 1)
, (2, Ref <$> arbAttr <*> arbitrary <*> arbitrary <*> arbInlines 1)
, (2, Note <$> resize 3 (listOf1 $ arbBlock (n-1)))
]

Expand Down Expand Up @@ -301,6 +306,22 @@ instance Arbitrary Citation where
<*> arbitrary
<*> arbitrary

instance Arbitrary ReferenceMode where
arbitrary
= arbitraryBoundedEnum

instance Arbitrary RefType where
arbitrary
= arbitraryBoundedEnum

instance Arbitrary Reference where
arbitrary
= Reference <$> fmap T.pack (listOf $ elements $ ['a'..'z'] ++ ['0'..'9'] ++ ['_'])
<*> arbInlines 1
<*> arbInlines 1
<*> arbitrary
<*> arbitrary

instance Arbitrary Row where
arbitrary = resize 3 $ arbRow 2
shrink (Row attr body)
Expand Down
8 changes: 8 additions & 0 deletions src/Text/Pandoc/Builder.hs
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,8 @@ module Text.Pandoc.Builder ( module Text.Pandoc.Definition
, singleQuoted
, doubleQuoted
, cite
, ref
, refWith
, codeWith
, code
, space
Expand Down Expand Up @@ -380,6 +382,12 @@ quoted qt = singleton . Quoted qt . toList
cite :: [Citation] -> Inlines -> Inlines
cite cts = singleton . Cite cts . toList

ref :: RefType -> [Reference] -> Inlines -> Inlines
ref = refWith nullAttr

refWith :: Attr -> RefType -> [Reference] -> Inlines -> Inlines
refWith a rt rfs = singleton . Ref a rt rfs . toList

-- | Inline code with attributes.
codeWith :: Attr -> Text -> Inlines
codeWith attrs = singleton . Code attrs
Expand Down
33 changes: 33 additions & 0 deletions src/Text/Pandoc/Definition.hs
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,9 @@ module Text.Pandoc.Definition ( Pandoc(..)
, MathType(..)
, Citation(..)
, CitationMode(..)
, Reference(..)
, ReferenceMode(..)
, RefType(..)
, pandocTypesVersion
) where

Expand Down Expand Up @@ -327,6 +330,7 @@ data Inline
| SmallCaps [Inline] -- ^ Small caps text (list of inlines)
| Quoted QuoteType [Inline] -- ^ Quoted text (list of inlines)
| Cite [Citation] [Inline] -- ^ Citation (list of inlines)
| Ref Attr RefType [Reference] [Inline] -- ^ Reference (list of inlines)
| Code Attr Text -- ^ Inline code (literal)
| Space -- ^ Inter-word space
| SoftBreak -- ^ Soft line break
Expand Down Expand Up @@ -354,6 +358,29 @@ instance Ord Citation where
data CitationMode = AuthorInText | SuppressAuthor | NormalCitation
deriving (Show, Eq, Ord, Read, Typeable, Data, Generic)

data Reference = Reference
{ referenceId :: Text
, referencePrefix :: [Inline]
, referenceSuffix :: [Inline]
, referenceMode :: ReferenceMode
, referenceHash :: Int
} deriving (Show, Eq, Read, Typeable, Data, Generic)

instance Ord Reference where
compare = comparing referenceHash

data ReferenceMode
= UpperCasePrefix
| LowerCasePrefix
| SuppressPrefix
| NormalReference
deriving (Show, Eq, Read, Enum, Bounded, Typeable, Data, Generic)

data RefType
= NumberRef
| PageRef
| RefTypeDefault
deriving (Show, Eq, Ord, Read, Enum, Bounded, Typeable, Data, Generic)

-- ToJSON/FromJSON instances. Some are defined by hand so that we have
-- more control over the format.
Expand All @@ -366,6 +393,9 @@ $(let jsonOpts = defaultOptions
[ ''MetaValue
, ''CitationMode
, ''Citation
, ''ReferenceMode
, ''RefType
, ''Reference
, ''QuoteType
, ''MathType
, ''ListNumberStyle
Expand Down Expand Up @@ -422,6 +452,7 @@ instance ToJSON Pandoc where
instance NFData MetaValue
instance NFData Meta
instance NFData Citation
instance NFData Reference
instance NFData Alignment
instance NFData RowSpan
instance NFData ColSpan
Expand All @@ -435,6 +466,8 @@ instance NFData Inline
instance NFData MathType
instance NFData Format
instance NFData CitationMode
instance NFData ReferenceMode
instance NFData RefType
instance NFData QuoteType
instance NFData ListNumberDelim
instance NFData ListNumberStyle
Expand Down
45 changes: 43 additions & 2 deletions src/Text/Pandoc/Walk.hs
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ module Text.Pandoc.Walk
, queryTableFoot
, queryCell
, queryCitation
, queryReference
, queryInline
, queryMetaValue
, queryPandoc
Expand All @@ -107,6 +108,7 @@ module Text.Pandoc.Walk
, walkTableFootM
, walkCellM
, walkCitationM
, walkReferenceM
, walkInlineM
, walkMetaValueM
, walkPandocM
Expand Down Expand Up @@ -388,12 +390,31 @@ instance Walkable [Block] Citation where
walkM = walkCitationM
query = queryCitation

--
-- Walk Reference
--
instance Walkable Inline Reference where
walkM = walkReferenceM
query = queryReference

instance Walkable [Inline] Reference where
walkM = walkReferenceM
query = queryReference

instance Walkable Block Reference where
walkM = walkReferenceM
query = queryReference

instance Walkable [Block] Reference where
walkM = walkReferenceM
query = queryReference

-- | Helper method to walk to elements nested below @'Inline'@ nodes.
--
-- When walking an inline with this function, only the contents of the traversed
-- inline element may change. The element itself, i.e. its constructor, cannot
-- be changed.
walkInlineM :: (Walkable a Citation, Walkable a [Block],
walkInlineM :: (Walkable a Citation, Walkable a Reference, Walkable a [Block],
Walkable a [Inline], Monad m, Applicative m, Functor m)
=> (a -> m a) -> Inline -> m Inline
walkInlineM _ (Str xs) = return (Str xs)
Expand All @@ -410,6 +431,7 @@ walkInlineM f (Image atr xs t) = Image atr <$> walkM f xs <*> pure t
walkInlineM f (Note bs) = Note <$> walkM f bs
walkInlineM f (Span attr xs) = Span attr <$> walkM f xs
walkInlineM f (Cite cs xs) = Cite <$> walkM f cs <*> walkM f xs
walkInlineM f (Ref a rt cs xs) = Ref a rt <$> walkM f cs <*> walkM f xs
walkInlineM _ LineBreak = return LineBreak
walkInlineM _ SoftBreak = return SoftBreak
walkInlineM _ Space = return Space
Expand All @@ -420,7 +442,7 @@ walkInlineM _ x@RawInline {} = return x
-- | Perform a query on elements nested below an @'Inline'@ element by
-- querying nested lists of @Inline@s, @Block@s, or @Citation@s.
queryInline :: (Walkable a Citation, Walkable a [Block],
Walkable a [Inline], Monoid c)
Walkable a Reference, Walkable a [Inline], Monoid c)
=> (a -> c) -> Inline -> c
queryInline _ (Str _) = mempty
queryInline f (Emph xs) = query f xs
Expand All @@ -432,6 +454,7 @@ queryInline f (Superscript xs)= query f xs
queryInline f (SmallCaps xs) = query f xs
queryInline f (Quoted _ xs) = query f xs
queryInline f (Cite cs xs) = query f cs <> query f xs
queryInline f (Ref _ _ cs xs) = query f cs <> query f xs
queryInline _ (Code _ _) = mempty
queryInline _ Space = mempty
queryInline _ SoftBreak = mempty
Expand Down Expand Up @@ -544,6 +567,24 @@ queryCitation :: (Walkable a [Inline], Monoid c)
=> (a -> c) -> Citation -> c
queryCitation f (Citation _ pref suff _ _ _) = query f pref <> query f suff

-- | Helper method to walk to elements nested below @'Reference'@ nodes.
--
-- The non-inline contents of a reference will remain unchanged during traversal.
-- Only the inline contents, viz. the reference's prefix and postfix, will be
-- traversed further and can thus be changed during this operation.
walkReferenceM :: (Walkable a [Inline], Monad m, Applicative m, Functor m)
=> (a -> m a) -> Reference -> m Reference
walkReferenceM f (Reference id' pref suff mode hash) =
do pref' <- walkM f pref
suff' <- walkM f suff
return $ Reference id' pref' suff' mode hash

-- | Perform a query on elements nested below a @'Reference'@ element by
-- querying the prefix and postfix @Inline@ lists.
queryReference :: (Walkable a [Inline], Monoid c)
=> (a -> c) -> Reference -> c
queryReference f (Reference _ pref suff _ _) = query f pref <> query f suff

-- | Helper method to walk the elements nested below @'Row'@ nodes. The
-- @'Attr'@ component is not changed by this operation.
walkRowM :: (Walkable a Cell, Monad m)
Expand Down
43 changes: 43 additions & 0 deletions test/test-pandoc-types.hs
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,37 @@ t_citation = ( Citation { citationId = "jameson:unconscious",
, [s|{"citationId":"jameson:unconscious","citationPrefix":[{"t":"Str","c":"cf"}],"citationSuffix":[{"t":"Space"},{"t":"Str","c":"123"}],"citationMode":{"t":"NormalCitation"},"citationNoteNum":0,"citationHash":0}|]
)

t_uppercaseprefix :: (ReferenceMode, ByteString)
t_uppercaseprefix = (UpperCasePrefix, [s|{"t":"UpperCasePrefix"}|])

t_lowercaseprefix :: (ReferenceMode, ByteString)
t_lowercaseprefix = (LowerCasePrefix, [s|{"t":"LowerCasePrefix"}|])

t_suppressprefix :: (ReferenceMode, ByteString)
t_suppressprefix = (SuppressPrefix, [s|{"t":"SuppressPrefix"}|])

t_normalreference :: (ReferenceMode, ByteString)
t_normalreference = (NormalReference, [s|{"t":"NormalReference"}|])

t_numberref :: (RefType, ByteString)
t_numberref = (NumberRef, [s|{"t":"NumberRef"}|])

t_pageref :: (RefType, ByteString)
t_pageref = (PageRef, [s|{"t":"PageRef"}|])

t_reftypedefault :: (RefType, ByteString)
t_reftypedefault = (RefTypeDefault, [s|{"t":"RefTypeDefault"}|])

t_reference :: (Reference, ByteString)
t_reference
= ( Reference { referenceId = "fig:demonstration"
, referencePrefix = [Str "cf"]
, referenceSuffix = [Space,Str "123"]
, referenceMode = NormalReference
, referenceHash = 0 }
, [s|{"referenceId":"fig:demonstration","referencePrefix":[{"t":"Str","c":"cf"}],"referenceSuffix":[{"t":"Space"},{"t":"Str","c":"123"}],"referenceMode":{"t":"NormalReference"},"referenceHash":0}|]
)

t_displaymath :: (MathType, ByteString)
t_displaymath = ( DisplayMath, [s|{"t":"DisplayMath"}|])

Expand Down Expand Up @@ -678,6 +709,18 @@ tests =
, testEncodeDecode "NormalCitation" t_normalcitation
]
, testEncodeDecode "Citation" t_citation
, testGroup "ReferenceMode"
[ testEncodeDecode "UpperCasePrefix" t_uppercaseprefix
, testEncodeDecode "LowerCasePrefix" t_lowercaseprefix
, testEncodeDecode "SuppressPrefix" t_suppressprefix
, testEncodeDecode "NormalReference" t_normalreference
]
, testGroup "RefType"
[ testEncodeDecode "NumberRef" t_numberref
, testEncodeDecode "PageRef" t_pageref
, testEncodeDecode "RefTypeDefault" t_reftypedefault
]
, testEncodeDecode "Reference" t_reference
, testGroup "MathType"
[ testEncodeDecode "DisplayMath" t_displaymath
, testEncodeDecode "InlineMath" t_inlinemath
Expand Down