@@ -75,6 +75,7 @@ module Text.Pandoc.Parsing ( (>>~),
7575 SubstTable,
7676 Key (..),
7777 toKey,
78+ registerHeader,
7879 smartPunctuation,
7980 withQuoteContext,
8081 singleQuoteStart,
@@ -151,6 +152,7 @@ where
151152import Text.Pandoc.Definition
152153import Text.Pandoc.Options
153154import Text.Pandoc.Builder (Blocks, Inlines, rawBlock, HasMeta(..))
155+import qualified Text.Pandoc.Builder as B
154156import Text.Pandoc.XML (fromEntities)
155157import qualified Text.Pandoc.UTF8 as UTF8 (putStrLn)
156158import Text.Parsec
@@ -162,11 +164,13 @@ import Text.Pandoc.Shared
162164import qualified Data.Map as M
163165import Text.TeXMath.Macros (applyMacros, Macro, parseMacroDefinitions)
164166import Text.Pandoc.Compat.TagSoupEntity ( lookupEntity )
167+import Text.Pandoc.Asciify (toAsciiChar)
165168import Data.Default
166169import qualified Data.Set as Set
167170import Control.Monad.Reader
168171import Control.Applicative ((*>), (<*), (<$), liftA2)
169172import Data.Monoid
173+import Data.Maybe (catMaybes)
170174
171175type Parser t s = Parsec t s
172176
@@ -886,6 +890,34 @@ type KeyTable = M.Map Key Target
886890
887891type SubstTable = M.Map Key Inlines
888892
893+-- | Add header to the list of headers in state, together
894+-- with its associated identifier. If the identifier is null
895+-- and the auto_identifers extension is set, generate a new
896+-- unique identifier, and update the list of identifiers
897+-- in state.
898+registerHeader :: Attr -> Inlines -> Parser s ParserState Attr
899+registerHeader (ident,classes,kvs) header' = do
900+ ids <- stateIdentifiers `fmap` getState
901+ exts <- getOption readerExtensions
902+ let insert' = M.insertWith (\_new old -> old)
903+ if null ident && Ext_auto_identifiers `Set.member` exts
904+ then do
905+ let id' = uniqueIdent (B.toList header') ids
906+ let id'' = if Ext_ascii_identifiers `Set.member` exts
907+ then catMaybes $ map toAsciiChar id'
908+ else id'
909+ updateState $ \st -> st{
910+ stateIdentifiers = if id' == id''
911+ then id' : ids
912+ else id' : id'' : ids,
913+ stateHeaders = insert' header' id' $ stateHeaders st }
914+ return (id'',classes,kvs)
915+ else do
916+ unless (null ident) $
917+ updateState $ \st -> st{
918+ stateHeaders = insert' header' ident $ stateHeaders st }
919+ return (ident,classes,kvs)
920+
889921-- | Fail unless we're in "smart typography" mode.
890922failUnlessSmart :: Parser [tok] ParserState ()
891923failUnlessSmart = getOption readerSmart >>= guard