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

SourceRange.prettyRange: escape sourceName #92

Open
wants to merge 2 commits 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
26 changes: 25 additions & 1 deletion commonmark/benchmark/benchmark.hs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
{-# LANGUAGE CPP #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE FlexibleContexts #-}
import Test.Tasty.Bench
import Data.Text (Text)
import Data.Functor.Identity -- base >= 4.8
Expand All @@ -19,6 +21,8 @@ main = do
]
, bgroup "pathological"
(map toPathBench pathtests)
, bgroup "name impact"
(map (toNameImpactBench sample) nameImpactTests)
]

toPathBench :: (String, Int -> T.Text) -> Benchmark
Expand Down Expand Up @@ -88,11 +92,31 @@ pathtests =
("a" <> T.replicate num "<!A "))
]

toNameImpactBench :: Text -> (String, String) -> Benchmark
toNameImpactBench sample (testName, name) =
let benchArgs n = (show n, take (50 * n) (cycle name), sample)
in bgroup testName
(map (benchCommonmark' @SourceRange defaultSyntaxSpec . benchArgs)
[1, 5, 10, 20])

nameImpactTests :: [(String, String)]
nameImpactTests =
[ ("no special characters", "the quick brown fox jumps over the lazy dog")
, ("special characters", "\\-:-as;df-:d:%%-:\\;;;\\-:%%-:---:-sdf-:sa-\\;")
]

benchCommonmark :: SyntaxSpec Identity (Html ()) (Html ())
-> (String, Text)
-> Benchmark
benchCommonmark spec (name, contents) =
bench name $
benchCommonmark' spec (name, name, contents)

benchCommonmark' :: Rangeable (Html a)
=> SyntaxSpec Identity (Html a) (Html a)
-> (String, String, Text)
-> Benchmark
benchCommonmark' spec (testName, name, contents) =
bench testName $
nf (either (error . show) renderHtml
. runIdentity . parseCommonmarkWith spec . tokenize name)
contents
Expand Down
15 changes: 13 additions & 2 deletions commonmark/src/Commonmark/Types.hs
Original file line number Diff line number Diff line change
Expand Up @@ -126,19 +126,30 @@ prettyRange (SourceRange xs) = go "" xs
go _ [] = ""
go curname ((p1,p2):rest)
= (if sourceName p1 /= curname
then sourceName p1 ++ "@"
then escapeSourceName (sourceName p1) ++ "@"
else "") ++
show (sourceLine p1) ++ ":" ++
show (sourceColumn p1) ++ "-" ++
(if sourceName p2 /= sourceName p1
then sourceName p2 ++ "@"
then escapeSourceName (sourceName p2) ++ "@"
else "") ++
show (sourceLine p2) ++
":" ++ show (sourceColumn p2) ++
if null rest
then ""
else ";" ++ go (sourceName p2) rest

-- if the source name contains special characters it can lead to ambiguity when
-- a filename exactly matches a fragment of syntax of the range
escapeSourceName :: String -> String
escapeSourceName = concatMap escapeChar
where
escapeChar '-' = "%2D"
escapeChar '%' = "%25"
escapeChar ':' = "%3A"
escapeChar ';' = "%3B"
escapeChar x = [x]

type Attribute = (Text, Text)

type Attributes = [Attribute]
Expand Down